summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 02:23:56 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 02:23:56 +0000
commit9620f76a210d9d8c1aaff25e99d6dc513f87e6e9 (patch)
treeceecc90fb95780872c35da764c5163f38e4727c4
parentInitial commit. (diff)
downloadsudo-9620f76a210d9d8c1aaff25e99d6dc513f87e6e9.tar.xz
sudo-9620f76a210d9d8c1aaff25e99d6dc513f87e6e9.zip
Adding upstream version 1.8.27.upstream/1.8.27upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--ABOUT-NLS1406
-rw-r--r--ChangeLog54001
-rw-r--r--INSTALL937
-rw-r--r--INSTALL.configure365
-rw-r--r--MANIFEST801
-rw-r--r--Makefile.in402
-rw-r--r--NEWS2644
-rw-r--r--README80
-rw-r--r--README.LDAP205
-rw-r--r--aclocal.m4139
-rwxr-xr-xautogen.sh20
-rw-r--r--config.guess1462
-rw-r--r--config.h.in1303
-rw-r--r--config.sub1827
-rwxr-xr-xconfigure29294
-rw-r--r--configure.ac4659
-rw-r--r--doc/CONTRIBUTORS230
-rw-r--r--doc/HISTORY76
-rw-r--r--doc/LICENSE236
-rw-r--r--doc/Makefile.in395
-rw-r--r--doc/TROUBLESHOOTING282
-rw-r--r--doc/UPGRADE463
-rw-r--r--doc/cvtsudoers.cat282
-rw-r--r--doc/cvtsudoers.man.in511
-rw-r--r--doc/cvtsudoers.mdoc.in437
-rwxr-xr-xdoc/fixman.sh37
-rw-r--r--doc/fixmdoc.sed5
-rw-r--r--doc/schema.ActiveDirectory255
-rw-r--r--doc/schema.OpenLDAP78
-rw-r--r--doc/schema.iPlanet12
-rw-r--r--doc/schema.olcSudo79
-rw-r--r--doc/sudo.cat741
-rw-r--r--doc/sudo.conf.cat434
-rw-r--r--doc/sudo.conf.man.in752
-rw-r--r--doc/sudo.conf.mdoc.in687
-rw-r--r--doc/sudo.man.in1431
-rw-r--r--doc/sudo.man.in.sed76
-rw-r--r--doc/sudo.mdoc.in1320
-rw-r--r--doc/sudo_plugin.cat1683
-rw-r--r--doc/sudo_plugin.man.in2986
-rw-r--r--doc/sudo_plugin.mdoc.in2625
-rw-r--r--doc/sudoers.cat2931
-rw-r--r--doc/sudoers.ldap.cat1033
-rw-r--r--doc/sudoers.ldap.man.in1712
-rw-r--r--doc/sudoers.ldap.mdoc.in1567
-rw-r--r--doc/sudoers.man.in5831
-rw-r--r--doc/sudoers.man.in.sed116
-rw-r--r--doc/sudoers.mdoc.in5398
-rw-r--r--doc/sudoers_timestamp.cat201
-rw-r--r--doc/sudoers_timestamp.man.in310
-rw-r--r--doc/sudoers_timestamp.mdoc.in288
-rw-r--r--doc/sudoreplay.cat303
-rw-r--r--doc/sudoreplay.man.in486
-rw-r--r--doc/sudoreplay.mdoc.in431
-rw-r--r--doc/visudo.cat226
-rw-r--r--doc/visudo.man.in465
-rw-r--r--doc/visudo.mdoc.in447
-rw-r--r--examples/Makefile.in100
-rw-r--r--examples/pam.conf30
-rw-r--r--examples/sudo.conf72
-rw-r--r--examples/sudoers133
-rw-r--r--examples/syslog.conf26
-rw-r--r--include/Makefile.in96
-rw-r--r--include/compat/charclass.h39
-rw-r--r--include/compat/endian.h72
-rw-r--r--include/compat/fnmatch.h32
-rw-r--r--include/compat/getaddrinfo.h83
-rw-r--r--include/compat/getopt.h81
-rw-r--r--include/compat/glob.h76
-rw-r--r--include/compat/nss_dbdefs.h106
-rw-r--r--include/compat/sha2.h98
-rw-r--r--include/compat/stdbool.h44
-rw-r--r--include/sudo_compat.h531
-rw-r--r--include/sudo_conf.h85
-rw-r--r--include/sudo_debug.h297
-rw-r--r--include/sudo_digest.h44
-rw-r--r--include/sudo_dso.h55
-rw-r--r--include/sudo_event.h193
-rw-r--r--include/sudo_fatal.h205
-rw-r--r--include/sudo_gettext.h75
-rw-r--r--include/sudo_lbuf.h53
-rw-r--r--include/sudo_plugin.h201
-rw-r--r--include/sudo_queue.h821
-rw-r--r--include/sudo_rand.h50
-rw-r--r--include/sudo_util.h275
-rw-r--r--indent.pro36
-rw-r--r--init.d/aix.sh.in25
-rw-r--r--init.d/hpux.sh.in27
-rw-r--r--init.d/sudo.conf.in6
-rwxr-xr-xinstall-sh239
-rw-r--r--lib/util/Makefile.in1120
-rw-r--r--lib/util/aix.c291
-rw-r--r--lib/util/arc4random.c217
-rw-r--r--lib/util/arc4random.h107
-rw-r--r--lib/util/arc4random_uniform.c75
-rw-r--r--lib/util/chacha_private.h222
-rw-r--r--lib/util/closefrom.c131
-rw-r--r--lib/util/digest.c173
-rw-r--r--lib/util/digest_gcrypt.c153
-rw-r--r--lib/util/digest_openssl.c163
-rw-r--r--lib/util/event.c798
-rw-r--r--lib/util/event_poll.c211
-rw-r--r--lib/util/event_select.c261
-rw-r--r--lib/util/fatal.c338
-rw-r--r--lib/util/fnmatch.c502
-rw-r--r--lib/util/getaddrinfo.c412
-rw-r--r--lib/util/getcwd.c248
-rw-r--r--lib/util/getentropy.c605
-rw-r--r--lib/util/getgrouplist.c517
-rw-r--r--lib/util/gethostname.c59
-rw-r--r--lib/util/getline.c101
-rw-r--r--lib/util/getopt_long.c629
-rw-r--r--lib/util/gettime.c227
-rw-r--r--lib/util/gidlist.c90
-rw-r--r--lib/util/glob.c958
-rw-r--r--lib/util/inet_ntop.c229
-rw-r--r--lib/util/inet_pton.c254
-rw-r--r--lib/util/isblank.c37
-rw-r--r--lib/util/key_val.c62
-rw-r--r--lib/util/lbuf.c329
-rw-r--r--lib/util/locking.c121
-rw-r--r--lib/util/memrchr.c49
-rw-r--r--lib/util/memset_s.c76
-rw-r--r--lib/util/mksiglist.c58
-rw-r--r--lib/util/mksiglist.h174
-rw-r--r--lib/util/mksigname.c58
-rw-r--r--lib/util/mksigname.h175
-rw-r--r--lib/util/mktemp.c129
-rw-r--r--lib/util/nanosleep.c63
-rw-r--r--lib/util/parseln.c136
-rw-r--r--lib/util/pipe2.c64
-rw-r--r--lib/util/progname.c91
-rw-r--r--lib/util/pw_dup.c105
-rw-r--r--lib/util/reallocarray.c56
-rw-r--r--lib/util/regress/atofoo/atofoo_test.c183
-rw-r--r--lib/util/regress/fnmatch/fnm_test.c85
-rw-r--r--lib/util/regress/fnmatch/fnm_test.in6
-rw-r--r--lib/util/regress/getgrouplist/getgrouplist_test.c104
-rw-r--r--lib/util/regress/glob/files47
-rw-r--r--lib/util/regress/glob/globtest.c216
-rw-r--r--lib/util/regress/glob/globtest.in64
-rw-r--r--lib/util/regress/mktemp/mktemp_test.c196
-rw-r--r--lib/util/regress/parse_gids/parse_gids_test.c114
-rw-r--r--lib/util/regress/progname/progname_test.c65
-rw-r--r--lib/util/regress/strsplit/strsplit_test.c111
-rw-r--r--lib/util/regress/sudo_conf/conf_test.c102
-rw-r--r--lib/util/regress/sudo_conf/test1.in73
-rw-r--r--lib/util/regress/sudo_conf/test1.out.ok7
-rw-r--r--lib/util/regress/sudo_conf/test2.in0
-rw-r--r--lib/util/regress/sudo_conf/test2.out.ok3
-rw-r--r--lib/util/regress/sudo_conf/test3.in2
-rw-r--r--lib/util/regress/sudo_conf/test3.out.ok5
-rw-r--r--lib/util/regress/sudo_conf/test4.err.ok1
-rw-r--r--lib/util/regress/sudo_conf/test4.in1
-rw-r--r--lib/util/regress/sudo_conf/test4.out.ok3
-rw-r--r--lib/util/regress/sudo_conf/test5.err.ok1
-rw-r--r--lib/util/regress/sudo_conf/test5.in1
-rw-r--r--lib/util/regress/sudo_conf/test5.out.ok3
-rw-r--r--lib/util/regress/sudo_conf/test6.in1
-rw-r--r--lib/util/regress/sudo_conf/test6.out.ok3
-rw-r--r--lib/util/regress/sudo_conf/test7.in4
-rw-r--r--lib/util/regress/sudo_conf/test7.out.ok7
-rw-r--r--lib/util/regress/sudo_parseln/parseln_test.c58
-rw-r--r--lib/util/regress/sudo_parseln/test1.in72
-rw-r--r--lib/util/regress/sudo_parseln/test1.out.ok72
-rw-r--r--lib/util/regress/sudo_parseln/test2.in8
-rw-r--r--lib/util/regress/sudo_parseln/test2.out.ok3
-rw-r--r--lib/util/regress/sudo_parseln/test3.in1
-rw-r--r--lib/util/regress/sudo_parseln/test3.out.ok1
-rw-r--r--lib/util/regress/sudo_parseln/test4.in4
-rw-r--r--lib/util/regress/sudo_parseln/test4.out.ok2
-rw-r--r--lib/util/regress/sudo_parseln/test5.in1
-rw-r--r--lib/util/regress/sudo_parseln/test5.out.ok0
-rw-r--r--lib/util/regress/sudo_parseln/test6.in3
-rw-r--r--lib/util/regress/sudo_parseln/test6.out.ok2
-rw-r--r--lib/util/regress/tailq/hltq_test.c199
-rw-r--r--lib/util/regress/vsyslog/vsyslog_test.c131
-rw-r--r--lib/util/secure_path.c86
-rw-r--r--lib/util/setgroups.c52
-rw-r--r--lib/util/sha2.c522
-rw-r--r--lib/util/sig2str.c76
-rw-r--r--lib/util/siglist.in56
-rw-r--r--lib/util/snprintf.c1592
-rw-r--r--lib/util/strlcat.c68
-rw-r--r--lib/util/strlcpy.c62
-rw-r--r--lib/util/strndup.c56
-rw-r--r--lib/util/strnlen.c43
-rw-r--r--lib/util/strsignal.c55
-rw-r--r--lib/util/strsplit.c78
-rw-r--r--lib/util/strtobool.c82
-rw-r--r--lib/util/strtoid.c176
-rw-r--r--lib/util/strtomode.c67
-rw-r--r--lib/util/strtonum.c198
-rw-r--r--lib/util/sudo_conf.c658
-rw-r--r--lib/util/sudo_debug.c877
-rw-r--r--lib/util/sudo_dso.c325
-rw-r--r--lib/util/term.c304
-rw-r--r--lib/util/ttyname_dev.c316
-rw-r--r--lib/util/ttysize.c71
-rw-r--r--lib/util/util.exp.in119
-rw-r--r--lib/util/utimens.c200
-rw-r--r--lib/util/vsyslog.c82
-rw-r--r--lib/zlib/Makefile.in209
-rw-r--r--lib/zlib/adler32.c186
-rw-r--r--lib/zlib/compress.c86
-rw-r--r--lib/zlib/crc32.c442
-rw-r--r--lib/zlib/crc32.h441
-rw-r--r--lib/zlib/deflate.c2165
-rw-r--r--lib/zlib/deflate.h349
-rw-r--r--lib/zlib/gzclose.c25
-rw-r--r--lib/zlib/gzguts.h218
-rw-r--r--lib/zlib/gzlib.c637
-rw-r--r--lib/zlib/gzread.c654
-rw-r--r--lib/zlib/gzwrite.c665
-rw-r--r--lib/zlib/infback.c640
-rw-r--r--lib/zlib/inffast.c323
-rw-r--r--lib/zlib/inffast.h11
-rw-r--r--lib/zlib/inffixed.h94
-rw-r--r--lib/zlib/inflate.c1561
-rw-r--r--lib/zlib/inflate.h125
-rw-r--r--lib/zlib/inftrees.c304
-rw-r--r--lib/zlib/inftrees.h62
-rw-r--r--lib/zlib/trees.c1203
-rw-r--r--lib/zlib/trees.h128
-rw-r--r--lib/zlib/uncompr.c93
-rw-r--r--lib/zlib/zconf.h.in556
-rw-r--r--lib/zlib/zlib.exp85
-rw-r--r--lib/zlib/zlib.h1912
-rw-r--r--lib/zlib/zutil.c325
-rw-r--r--lib/zlib/zutil.h271
-rwxr-xr-xlog2cl.pl102
-rw-r--r--ltmain.sh11167
-rw-r--r--m4/ax_append_flag.m471
-rw-r--r--m4/ax_check_compile_flag.m472
-rw-r--r--m4/ax_check_link_flag.m471
-rw-r--r--m4/ax_func_getaddrinfo.m470
-rw-r--r--m4/ax_func_snprintf.m482
-rw-r--r--m4/libtool.m48444
-rw-r--r--m4/ltoptions.m4437
-rw-r--r--m4/ltsugar.m4124
-rw-r--r--m4/ltversion.m423
-rw-r--r--m4/lt~obsolete.m499
-rw-r--r--m4/sudo.m4496
-rwxr-xr-xmkdep.pl283
-rwxr-xr-xmkinstalldirs84
-rwxr-xr-xmkpkg407
-rw-r--r--pathnames.h.in208
-rw-r--r--plugins/group_file/Makefile.in212
-rw-r--r--plugins/group_file/getgrent.c183
-rw-r--r--plugins/group_file/group_file.c132
-rw-r--r--plugins/group_file/group_file.exp1
-rw-r--r--plugins/group_file/plugin_test.c217
-rw-r--r--plugins/sample/Makefile.in199
-rw-r--r--plugins/sample/README23
-rw-r--r--plugins/sample/sample_plugin.c500
-rw-r--r--plugins/sample/sample_plugin.exp2
-rw-r--r--plugins/sudoers/Makefile.in2559
-rw-r--r--plugins/sudoers/alias.c381
-rw-r--r--plugins/sudoers/audit.c102
-rw-r--r--plugins/sudoers/auth/API135
-rw-r--r--plugins/sudoers/auth/afs.c83
-rw-r--r--plugins/sudoers/auth/aix_auth.c193
-rw-r--r--plugins/sudoers/auth/bsdauth.c205
-rw-r--r--plugins/sudoers/auth/dce.c196
-rw-r--r--plugins/sudoers/auth/fwtk.c154
-rw-r--r--plugins/sudoers/auth/kerb5.c335
-rw-r--r--plugins/sudoers/auth/pam.c616
-rw-r--r--plugins/sudoers/auth/passwd.c113
-rw-r--r--plugins/sudoers/auth/rfc1938.c142
-rw-r--r--plugins/sudoers/auth/secureware.c116
-rw-r--r--plugins/sudoers/auth/securid5.c232
-rw-r--r--plugins/sudoers/auth/sia.c156
-rw-r--r--plugins/sudoers/auth/sudo_auth.c483
-rw-r--r--plugins/sudoers/auth/sudo_auth.h102
-rw-r--r--plugins/sudoers/base64.c129
-rw-r--r--plugins/sudoers/boottime.c175
-rw-r--r--plugins/sudoers/bsm_audit.c285
-rw-r--r--plugins/sudoers/bsm_audit.h24
-rw-r--r--plugins/sudoers/check.c333
-rw-r--r--plugins/sudoers/check.h87
-rw-r--r--plugins/sudoers/cvtsudoers.c1334
-rw-r--r--plugins/sudoers/cvtsudoers.h98
-rw-r--r--plugins/sudoers/cvtsudoers_json.c1161
-rw-r--r--plugins/sudoers/cvtsudoers_ldif.c665
-rw-r--r--plugins/sudoers/cvtsudoers_pwutil.c480
-rw-r--r--plugins/sudoers/def_data.c499
-rw-r--r--plugins/sudoers/def_data.h241
-rw-r--r--plugins/sudoers/def_data.in359
-rw-r--r--plugins/sudoers/defaults.c1132
-rw-r--r--plugins/sudoers/defaults.h138
-rw-r--r--plugins/sudoers/digestname.c56
-rw-r--r--plugins/sudoers/editor.c179
-rw-r--r--plugins/sudoers/env.c1389
-rw-r--r--plugins/sudoers/env_pattern.c97
-rw-r--r--plugins/sudoers/file.c156
-rw-r--r--plugins/sudoers/filedigest.c102
-rw-r--r--plugins/sudoers/find_path.c173
-rw-r--r--plugins/sudoers/fmtsudoers.c477
-rw-r--r--plugins/sudoers/gc.c151
-rw-r--r--plugins/sudoers/gentime.c161
-rw-r--r--plugins/sudoers/getdate.c1582
-rw-r--r--plugins/sudoers/getdate.y939
-rw-r--r--plugins/sudoers/getspwuid.c142
-rw-r--r--plugins/sudoers/gmtoff.c75
-rw-r--r--plugins/sudoers/goodpath.c68
-rw-r--r--plugins/sudoers/gram.c2300
-rw-r--r--plugins/sudoers/gram.h63
-rw-r--r--plugins/sudoers/gram.y1327
-rw-r--r--plugins/sudoers/group_plugin.c232
-rw-r--r--plugins/sudoers/hexchar.c102
-rw-r--r--plugins/sudoers/ins_2001.h33
-rw-r--r--plugins/sudoers/ins_classic.h37
-rw-r--r--plugins/sudoers/ins_csops.h39
-rw-r--r--plugins/sudoers/ins_goons.h48
-rw-r--r--plugins/sudoers/ins_python.h37
-rw-r--r--plugins/sudoers/insults.h67
-rw-r--r--plugins/sudoers/interfaces.c142
-rw-r--r--plugins/sudoers/interfaces.h55
-rw-r--r--plugins/sudoers/iolog.c1292
-rw-r--r--plugins/sudoers/iolog.h86
-rw-r--r--plugins/sudoers/iolog_files.h47
-rw-r--r--plugins/sudoers/iolog_path.c287
-rw-r--r--plugins/sudoers/iolog_util.c387
-rw-r--r--plugins/sudoers/ldap.c2050
-rw-r--r--plugins/sudoers/ldap_conf.c934
-rw-r--r--plugins/sudoers/ldap_util.c581
-rw-r--r--plugins/sudoers/linux_audit.c111
-rw-r--r--plugins/sudoers/linux_audit.h22
-rw-r--r--plugins/sudoers/locale.c156
-rw-r--r--plugins/sudoers/logging.c1044
-rw-r--r--plugins/sudoers/logging.h83
-rw-r--r--plugins/sudoers/logwrap.c80
-rw-r--r--plugins/sudoers/match.c1281
-rw-r--r--plugins/sudoers/match_addr.c211
-rwxr-xr-xplugins/sudoers/mkdefaults164
-rw-r--r--plugins/sudoers/mkdir_parents.c93
-rw-r--r--plugins/sudoers/parse.c864
-rw-r--r--plugins/sudoers/parse.h365
-rw-r--r--plugins/sudoers/parse_ldif.c774
-rw-r--r--plugins/sudoers/po/README14
-rw-r--r--plugins/sudoers/po/ca.mobin0 -> 43748 bytes
-rw-r--r--plugins/sudoers/po/ca.po2081
-rw-r--r--plugins/sudoers/po/cs.mobin0 -> 49130 bytes
-rw-r--r--plugins/sudoers/po/cs.po2412
-rw-r--r--plugins/sudoers/po/da.mobin0 -> 46545 bytes
-rw-r--r--plugins/sudoers/po/da.po2344
-rw-r--r--plugins/sudoers/po/de.mobin0 -> 51907 bytes
-rw-r--r--plugins/sudoers/po/de.po2357
-rw-r--r--plugins/sudoers/po/el.mobin0 -> 51050 bytes
-rw-r--r--plugins/sudoers/po/el.po1718
-rw-r--r--plugins/sudoers/po/eo.mobin0 -> 46893 bytes
-rw-r--r--plugins/sudoers/po/eo.po2347
-rw-r--r--plugins/sudoers/po/eu.mobin0 -> 6445 bytes
-rw-r--r--plugins/sudoers/po/eu.po1679
-rw-r--r--plugins/sudoers/po/fi.mobin0 -> 45911 bytes
-rw-r--r--plugins/sudoers/po/fi.po2361
-rw-r--r--plugins/sudoers/po/fr.mobin0 -> 44799 bytes
-rw-r--r--plugins/sudoers/po/fr.po2048
-rw-r--r--plugins/sudoers/po/fur.mobin0 -> 9526 bytes
-rw-r--r--plugins/sudoers/po/fur.po2119
-rw-r--r--plugins/sudoers/po/hr.mobin0 -> 49993 bytes
-rw-r--r--plugins/sudoers/po/hr.po2518
-rw-r--r--plugins/sudoers/po/hu.mobin0 -> 26114 bytes
-rw-r--r--plugins/sudoers/po/hu.po2152
-rw-r--r--plugins/sudoers/po/it.mobin0 -> 49417 bytes
-rw-r--r--plugins/sudoers/po/it.po2345
-rw-r--r--plugins/sudoers/po/ja.mobin0 -> 56302 bytes
-rw-r--r--plugins/sudoers/po/ja.po2525
-rw-r--r--plugins/sudoers/po/ko.mobin0 -> 45799 bytes
-rw-r--r--plugins/sudoers/po/ko.po2122
-rw-r--r--plugins/sudoers/po/lt.mobin0 -> 2035 bytes
-rw-r--r--plugins/sudoers/po/lt.po1682
-rw-r--r--plugins/sudoers/po/nb.mobin0 -> 48349 bytes
-rw-r--r--plugins/sudoers/po/nb.po2404
-rw-r--r--plugins/sudoers/po/nl.mobin0 -> 39137 bytes
-rw-r--r--plugins/sudoers/po/nl.po2282
-rw-r--r--plugins/sudoers/po/pl.mobin0 -> 50114 bytes
-rw-r--r--plugins/sudoers/po/pl.po2346
-rw-r--r--plugins/sudoers/po/pt.mobin0 -> 48637 bytes
-rw-r--r--plugins/sudoers/po/pt.po2347
-rw-r--r--plugins/sudoers/po/pt_BR.mobin0 -> 50337 bytes
-rw-r--r--plugins/sudoers/po/pt_BR.po2485
-rw-r--r--plugins/sudoers/po/ru.mobin0 -> 11596 bytes
-rw-r--r--plugins/sudoers/po/ru.po1868
-rw-r--r--plugins/sudoers/po/sk.mobin0 -> 4968 bytes
-rw-r--r--plugins/sudoers/po/sk.po1892
-rw-r--r--plugins/sudoers/po/sl.mobin0 -> 36454 bytes
-rw-r--r--plugins/sudoers/po/sl.po1758
-rw-r--r--plugins/sudoers/po/sr.mobin0 -> 57820 bytes
-rw-r--r--plugins/sudoers/po/sr.po2172
-rw-r--r--plugins/sudoers/po/sudoers.pot2296
-rw-r--r--plugins/sudoers/po/sv.mobin0 -> 48105 bytes
-rw-r--r--plugins/sudoers/po/sv.po2475
-rw-r--r--plugins/sudoers/po/tr.mobin0 -> 14020 bytes
-rw-r--r--plugins/sudoers/po/tr.po1721
-rw-r--r--plugins/sudoers/po/uk.mobin0 -> 67174 bytes
-rw-r--r--plugins/sudoers/po/uk.po2347
-rw-r--r--plugins/sudoers/po/vi.mobin0 -> 54737 bytes
-rw-r--r--plugins/sudoers/po/vi.po2502
-rw-r--r--plugins/sudoers/po/zh_CN.mobin0 -> 44917 bytes
-rw-r--r--plugins/sudoers/po/zh_CN.po2549
-rw-r--r--plugins/sudoers/policy.c997
-rw-r--r--plugins/sudoers/prompt.c168
-rw-r--r--plugins/sudoers/pwutil.c1107
-rw-r--r--plugins/sudoers/pwutil.h75
-rw-r--r--plugins/sudoers/pwutil_impl.c414
-rw-r--r--plugins/sudoers/rcstr.c111
-rw-r--r--plugins/sudoers/redblack.c479
-rw-r--r--plugins/sudoers/redblack.h58
-rw-r--r--plugins/sudoers/regress/check_symbols/check_symbols.c103
-rw-r--r--plugins/sudoers/regress/cvtsudoers/sudoers126
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/sudoers.defs19
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test1.out.ok14
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test1.sh9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test10.out.ok1
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test10.sh9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test11.out.ok7
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test11.sh7
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test12.out.ok8
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test12.sh7
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test13.out.ok7
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test13.sh7
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test14.out.ok7
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test14.sh7
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test15.out.ok1
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test15.sh9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test16.out.ok1
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test16.sh9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test17.out.ok1
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test17.sh9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test18.out.ok1
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test18.sh9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test19.out.ok11
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test19.sh7
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test2.out.ok10
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test2.sh9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test20.conf6
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test20.out.ok1
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test20.sh12
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test21.conf8
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test21.out.ok24
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test21.sh13
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test22.out.ok31
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test22.sh72
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test23.out.ok20
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test23.sh8
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test24.out.ok89
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test24.sh8
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test25.out.ok31
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test25.sh52
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test26.out.ok3
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test26.sh41
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test27.out.ok16
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test27.sh11
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test28.out.ok10
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test28.sh73
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test29.out.ok4
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test29.sh60
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test3.out.ok7
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test3.sh9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test30.out.ok26
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test30.sh14
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test31.conf9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test31.out.ok24
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test31.sh13
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test32.out.ok120
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test32.sh21
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test33.out.ok7
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test33.sh61
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test4.out.ok5
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test4.sh9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test5.out.ok6
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test5.sh9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test6.out.ok1
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test6.sh9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test7.out.ok2
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test7.sh9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test8.out.ok1
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test8.sh9
-rw-r--r--plugins/sudoers/regress/cvtsudoers/test9.out.ok1
-rwxr-xr-xplugins/sudoers/regress/cvtsudoers/test9.sh9
-rw-r--r--plugins/sudoers/regress/env_match/check_env_pattern.c82
-rw-r--r--plugins/sudoers/regress/env_match/data22
-rw-r--r--plugins/sudoers/regress/iolog_path/check_iolog_path.c215
-rw-r--r--plugins/sudoers/regress/iolog_path/data96
-rw-r--r--plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c412
-rw-r--r--plugins/sudoers/regress/iolog_util/check_iolog_util.c151
-rw-r--r--plugins/sudoers/regress/logging/check_wrap.c108
-rw-r--r--plugins/sudoers/regress/logging/check_wrap.in4
-rw-r--r--plugins/sudoers/regress/logging/check_wrap.out.ok175
-rw-r--r--plugins/sudoers/regress/parser/check_addr.c145
-rw-r--r--plugins/sudoers/regress/parser/check_addr.in13
-rw-r--r--plugins/sudoers/regress/parser/check_base64.c123
-rw-r--r--plugins/sudoers/regress/parser/check_digest.c140
-rw-r--r--plugins/sudoers/regress/parser/check_digest.out.ok36
-rw-r--r--plugins/sudoers/regress/parser/check_fill.c194
-rw-r--r--plugins/sudoers/regress/parser/check_gentime.c87
-rw-r--r--plugins/sudoers/regress/parser/check_hexchar.c90
-rw-r--r--plugins/sudoers/regress/starttime/check_starttime.c117
-rw-r--r--plugins/sudoers/regress/sudoers/test1.in12
-rw-r--r--plugins/sudoers/regress/sudoers/test1.json.ok154
-rw-r--r--plugins/sudoers/regress/sudoers/test1.ldif.ok88
-rw-r--r--plugins/sudoers/regress/sudoers/test1.ldif2sudo.ok13
-rw-r--r--plugins/sudoers/regress/sudoers/test1.out.ok6
-rw-r--r--plugins/sudoers/regress/sudoers/test1.toke.ok8
-rw-r--r--plugins/sudoers/regress/sudoers/test10.in1
-rw-r--r--plugins/sudoers/regress/sudoers/test10.json.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test10.ldif.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test10.out.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test10.toke.ok1
-rw-r--r--plugins/sudoers/regress/sudoers/test11.in1
-rw-r--r--plugins/sudoers/regress/sudoers/test11.json.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test11.ldif.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test11.out.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test11.toke.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test12.in1
-rw-r--r--plugins/sudoers/regress/sudoers/test12.json.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test12.ldif.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test12.out.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test12.toke.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test13.in1
-rw-r--r--plugins/sudoers/regress/sudoers/test13.json.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test13.ldif.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test13.out.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test13.toke.ok1
-rw-r--r--plugins/sudoers/regress/sudoers/test14.in4
-rw-r--r--plugins/sudoers/regress/sudoers/test14.json.ok38
-rw-r--r--plugins/sudoers/regress/sudoers/test14.ldif.ok11
-rw-r--r--plugins/sudoers/regress/sudoers/test14.ldif2sudo.ok5
-rw-r--r--plugins/sudoers/regress/sudoers/test14.out.ok6
-rw-r--r--plugins/sudoers/regress/sudoers/test14.toke.ok4
-rw-r--r--plugins/sudoers/regress/sudoers/test15.in2
-rw-r--r--plugins/sudoers/regress/sudoers/test15.json.ok19
-rw-r--r--plugins/sudoers/regress/sudoers/test15.ldif.ok9
-rw-r--r--plugins/sudoers/regress/sudoers/test15.ldif2sudo.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test15.out.ok3
-rw-r--r--plugins/sudoers/regress/sudoers/test15.toke.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test16.in3
-rw-r--r--plugins/sudoers/regress/sudoers/test16.json.ok24
-rw-r--r--plugins/sudoers/regress/sudoers/test16.ldif.ok9
-rw-r--r--plugins/sudoers/regress/sudoers/test16.ldif2sudo.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test16.out.ok5
-rw-r--r--plugins/sudoers/regress/sudoers/test16.toke.ok3
-rw-r--r--plugins/sudoers/regress/sudoers/test17.in13
-rw-r--r--plugins/sudoers/regress/sudoers/test17.json.ok180
-rw-r--r--plugins/sudoers/regress/sudoers/test17.ldif.ok104
-rw-r--r--plugins/sudoers/regress/sudoers/test17.ldif2sudo.ok29
-rw-r--r--plugins/sudoers/regress/sudoers/test17.out.ok13
-rw-r--r--plugins/sudoers/regress/sudoers/test17.toke.ok11
-rw-r--r--plugins/sudoers/regress/sudoers/test18.in8
-rw-r--r--plugins/sudoers/regress/sudoers/test18.json.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test18.ldif.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test18.out.ok4
-rw-r--r--plugins/sudoers/regress/sudoers/test18.toke.ok10
-rw-r--r--plugins/sudoers/regress/sudoers/test19.in12
-rw-r--r--plugins/sudoers/regress/sudoers/test19.json.ok187
-rw-r--r--plugins/sudoers/regress/sudoers/test19.ldif.ok103
-rw-r--r--plugins/sudoers/regress/sudoers/test19.ldif2sudo.ok30
-rw-r--r--plugins/sudoers/regress/sudoers/test19.out.ok12
-rw-r--r--plugins/sudoers/regress/sudoers/test19.toke.ok12
-rw-r--r--plugins/sudoers/regress/sudoers/test2.in60
-rw-r--r--plugins/sudoers/regress/sudoers/test2.json.ok403
-rw-r--r--plugins/sudoers/regress/sudoers/test2.ldif.ok157
-rw-r--r--plugins/sudoers/regress/sudoers/test2.ldif2sudo.ok38
-rw-r--r--plugins/sudoers/regress/sudoers/test2.out.ok42
-rw-r--r--plugins/sudoers/regress/sudoers/test2.toke.ok60
-rw-r--r--plugins/sudoers/regress/sudoers/test20.in26
-rw-r--r--plugins/sudoers/regress/sudoers/test20.json.ok114
-rw-r--r--plugins/sudoers/regress/sudoers/test20.ldif.ok28
-rw-r--r--plugins/sudoers/regress/sudoers/test20.ldif2sudo.ok22
-rw-r--r--plugins/sudoers/regress/sudoers/test20.out.ok24
-rw-r--r--plugins/sudoers/regress/sudoers/test20.toke.ok26
-rw-r--r--plugins/sudoers/regress/sudoers/test21.in36
-rw-r--r--plugins/sudoers/regress/sudoers/test21.json.ok169
-rw-r--r--plugins/sudoers/regress/sudoers/test21.ldif.ok39
-rw-r--r--plugins/sudoers/regress/sudoers/test21.ldif2sudo.ok33
-rw-r--r--plugins/sudoers/regress/sudoers/test21.out.ok35
-rw-r--r--plugins/sudoers/regress/sudoers/test21.toke.ok36
-rw-r--r--plugins/sudoers/regress/sudoers/test22.in6
-rw-r--r--plugins/sudoers/regress/sudoers/test22.json.ok88
-rw-r--r--plugins/sudoers/regress/sudoers/test22.ldif.ok40
-rw-r--r--plugins/sudoers/regress/sudoers/test22.ldif2sudo.ok11
-rw-r--r--plugins/sudoers/regress/sudoers/test22.out.ok6
-rw-r--r--plugins/sudoers/regress/sudoers/test22.sudo.ok7
-rw-r--r--plugins/sudoers/regress/sudoers/test22.toke.ok6
-rw-r--r--plugins/sudoers/regress/sudoers/test3.in6
-rw-r--r--plugins/sudoers/regress/sudoers/test3.json.ok45
-rw-r--r--plugins/sudoers/regress/sudoers/test3.ldif.ok12
-rw-r--r--plugins/sudoers/regress/sudoers/test3.ldif2sudo.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test3.out.ok8
-rw-r--r--plugins/sudoers/regress/sudoers/test3.toke.ok6
-rw-r--r--plugins/sudoers/regress/sudoers/test4.in7
-rw-r--r--plugins/sudoers/regress/sudoers/test4.json.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test4.ldif.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test4.out.ok4
-rw-r--r--plugins/sudoers/regress/sudoers/test4.toke.ok5
-rw-r--r--plugins/sudoers/regress/sudoers/test5.in3
-rw-r--r--plugins/sudoers/regress/sudoers/test5.json.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test5.ldif.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test5.out.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test5.toke.ok3
-rw-r--r--plugins/sudoers/regress/sudoers/test6.in15
-rw-r--r--plugins/sudoers/regress/sudoers/test6.json.ok158
-rw-r--r--plugins/sudoers/regress/sudoers/test6.ldif.ok70
-rw-r--r--plugins/sudoers/regress/sudoers/test6.ldif2sudo.ok5
-rw-r--r--plugins/sudoers/regress/sudoers/test6.out.ok13
-rw-r--r--plugins/sudoers/regress/sudoers/test6.toke.ok15
-rw-r--r--plugins/sudoers/regress/sudoers/test7.in7
-rw-r--r--plugins/sudoers/regress/sudoers/test7.json.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test7.ldif.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test7.out.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test7.toke.ok7
-rw-r--r--plugins/sudoers/regress/sudoers/test8.in8
-rw-r--r--plugins/sudoers/regress/sudoers/test8.json.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test8.ldif.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test8.out.ok5
-rw-r--r--plugins/sudoers/regress/sudoers/test8.toke.ok7
-rw-r--r--plugins/sudoers/regress/sudoers/test9.in0
-rw-r--r--plugins/sudoers/regress/sudoers/test9.json.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test9.ldif.ok0
-rw-r--r--plugins/sudoers/regress/sudoers/test9.out.ok2
-rw-r--r--plugins/sudoers/regress/sudoers/test9.toke.ok0
-rw-r--r--plugins/sudoers/regress/testsudoers/group15
-rw-r--r--plugins/sudoers/regress/testsudoers/test1.out.ok8
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test1.sh13
-rw-r--r--plugins/sudoers/regress/testsudoers/test2.inc1
-rw-r--r--plugins/sudoers/regress/testsudoers/test2.out.ok10
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test2.sh13
-rw-r--r--plugins/sudoers/regress/testsudoers/test3.d/root1
-rw-r--r--plugins/sudoers/regress/testsudoers/test3.out.ok10
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test3.sh13
-rw-r--r--plugins/sudoers/regress/testsudoers/test4.out.ok6
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test4.sh14
-rw-r--r--plugins/sudoers/regress/testsudoers/test5.out.ok12
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test5.sh32
-rw-r--r--plugins/sudoers/regress/testsudoers/test6.out.ok10
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test6.sh11
-rw-r--r--plugins/sudoers/regress/testsudoers/test7.out.ok10
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test7.sh11
-rw-r--r--plugins/sudoers/regress/visudo/test1.out.ok1
-rwxr-xr-xplugins/sudoers/regress/visudo/test1.sh12
-rw-r--r--plugins/sudoers/regress/visudo/test10.out.ok1
-rwxr-xr-xplugins/sudoers/regress/visudo/test10.sh11
-rw-r--r--plugins/sudoers/regress/visudo/test2.err.ok1
-rw-r--r--plugins/sudoers/regress/visudo/test2.out.ok0
-rwxr-xr-xplugins/sudoers/regress/visudo/test2.sh15
-rw-r--r--plugins/sudoers/regress/visudo/test3.err.ok2
-rw-r--r--plugins/sudoers/regress/visudo/test3.out.ok1
-rwxr-xr-xplugins/sudoers/regress/visudo/test3.sh35
-rw-r--r--plugins/sudoers/regress/visudo/test4.out.ok1
-rwxr-xr-xplugins/sudoers/regress/visudo/test4.sh14
-rw-r--r--plugins/sudoers/regress/visudo/test5.out.ok1
-rwxr-xr-xplugins/sudoers/regress/visudo/test5.sh8
-rw-r--r--plugins/sudoers/regress/visudo/test6.out.ok1
-rwxr-xr-xplugins/sudoers/regress/visudo/test6.sh25
-rw-r--r--plugins/sudoers/regress/visudo/test7.out.ok1
-rwxr-xr-xplugins/sudoers/regress/visudo/test7.sh29
-rw-r--r--plugins/sudoers/regress/visudo/test8.err.ok1
-rw-r--r--plugins/sudoers/regress/visudo/test8.out.ok1
-rwxr-xr-xplugins/sudoers/regress/visudo/test8.sh30
-rw-r--r--plugins/sudoers/regress/visudo/test9.out.ok1
-rwxr-xr-xplugins/sudoers/regress/visudo/test9.sh12
-rw-r--r--plugins/sudoers/set_perms.c1710
-rw-r--r--plugins/sudoers/solaris_audit.c134
-rw-r--r--plugins/sudoers/solaris_audit.h23
-rw-r--r--plugins/sudoers/sssd.c790
-rw-r--r--plugins/sudoers/starttime.c307
-rw-r--r--plugins/sudoers/strlist.c97
-rw-r--r--plugins/sudoers/strlist.h38
-rw-r--r--plugins/sudoers/stubs.c115
-rw-r--r--plugins/sudoers/sudo_ldap.h30
-rw-r--r--plugins/sudoers/sudo_ldap_conf.h129
-rw-r--r--plugins/sudoers/sudo_nss.c271
-rw-r--r--plugins/sudoers/sudo_nss.h44
-rw-r--r--plugins/sudoers/sudo_printf.c60
-rw-r--r--plugins/sudoers/sudoers.c1281
-rw-r--r--plugins/sudoers/sudoers.exp6
-rw-r--r--plugins/sudoers/sudoers.h428
-rw-r--r--plugins/sudoers/sudoers.in97
-rw-r--r--plugins/sudoers/sudoers_debug.c162
-rw-r--r--plugins/sudoers/sudoers_debug.h46
-rw-r--r--plugins/sudoers/sudoers_version.h75
-rw-r--r--plugins/sudoers/sudoreplay.c1641
-rw-r--r--plugins/sudoers/testsudoers.c608
-rw-r--r--plugins/sudoers/timeout.c114
-rw-r--r--plugins/sudoers/timestamp.c1075
-rw-r--r--plugins/sudoers/timestr.c51
-rw-r--r--plugins/sudoers/toke.c4665
-rw-r--r--plugins/sudoers/toke.h39
-rw-r--r--plugins/sudoers/toke.l1161
-rw-r--r--plugins/sudoers/toke_util.c193
-rw-r--r--plugins/sudoers/tsdump.c316
-rw-r--r--plugins/sudoers/tsgetgrpw.c413
-rw-r--r--plugins/sudoers/tsgetgrpw.h72
-rw-r--r--plugins/sudoers/visudo.c1300
-rw-r--r--plugins/system_group/Makefile.in204
-rw-r--r--plugins/system_group/system_group.c157
-rw-r--r--plugins/system_group/system_group.exp1
-rw-r--r--po/README14
-rw-r--r--po/ast.mobin0 -> 19664 bytes
-rw-r--r--po/ast.po928
-rw-r--r--po/ca.mobin0 -> 19183 bytes
-rw-r--r--po/ca.po896
-rw-r--r--po/cs.mobin0 -> 19346 bytes
-rw-r--r--po/cs.po977
-rw-r--r--po/da.mobin0 -> 18394 bytes
-rw-r--r--po/da.po898
-rw-r--r--po/de.mobin0 -> 19908 bytes
-rw-r--r--po/de.po881
-rw-r--r--po/eo.mobin0 -> 18439 bytes
-rw-r--r--po/eo.po953
-rw-r--r--po/es.mobin0 -> 19231 bytes
-rw-r--r--po/es.po950
-rw-r--r--po/eu.mobin0 -> 6812 bytes
-rw-r--r--po/eu.po742
-rw-r--r--po/fi.mobin0 -> 19870 bytes
-rw-r--r--po/fi.po962
-rw-r--r--po/fr.mobin0 -> 20512 bytes
-rw-r--r--po/fr.po978
-rw-r--r--po/fur.mobin0 -> 18376 bytes
-rw-r--r--po/fur.po873
-rw-r--r--po/gl.mobin0 -> 17653 bytes
-rw-r--r--po/gl.po898
-rw-r--r--po/hr.mobin0 -> 19504 bytes
-rw-r--r--po/hr.po1001
-rw-r--r--po/hu.mobin0 -> 20167 bytes
-rw-r--r--po/hu.po883
-rw-r--r--po/it.mobin0 -> 19967 bytes
-rw-r--r--po/it.po939
-rw-r--r--po/ja.mobin0 -> 22906 bytes
-rw-r--r--po/ja.po996
-rw-r--r--po/ko.mobin0 -> 20165 bytes
-rw-r--r--po/ko.po877
-rw-r--r--po/nb.mobin0 -> 19332 bytes
-rw-r--r--po/nb.po973
-rw-r--r--po/nl.mobin0 -> 17756 bytes
-rw-r--r--po/nl.po856
-rw-r--r--po/nn.mobin0 -> 3058 bytes
-rw-r--r--po/nn.po934
-rw-r--r--po/pl.mobin0 -> 19896 bytes
-rw-r--r--po/pl.po924
-rw-r--r--po/pt.mobin0 -> 19367 bytes
-rw-r--r--po/pt.po933
-rw-r--r--po/pt_BR.mobin0 -> 20037 bytes
-rw-r--r--po/pt_BR.po988
-rw-r--r--po/ru.mobin0 -> 24561 bytes
-rw-r--r--po/ru.po923
-rw-r--r--po/sk.mobin0 -> 15536 bytes
-rw-r--r--po/sk.po858
-rw-r--r--po/sl.mobin0 -> 16504 bytes
-rw-r--r--po/sl.po810
-rw-r--r--po/sr.mobin0 -> 24607 bytes
-rw-r--r--po/sr.po923
-rw-r--r--po/sudo.pot924
-rw-r--r--po/sv.mobin0 -> 19080 bytes
-rw-r--r--po/sv.po974
-rw-r--r--po/tr.mobin0 -> 19231 bytes
-rw-r--r--po/tr.po988
-rw-r--r--po/uk.mobin0 -> 26643 bytes
-rw-r--r--po/uk.po926
-rw-r--r--po/vi.mobin0 -> 22016 bytes
-rw-r--r--po/vi.po1006
-rw-r--r--po/zh_CN.mobin0 -> 17614 bytes
-rw-r--r--po/zh_CN.po1003
-rw-r--r--po/zh_TW.mobin0 -> 18739 bytes
-rw-r--r--po/zh_TW.po886
-rwxr-xr-xpp8415
-rw-r--r--src/Makefile.in718
-rw-r--r--src/conversation.c166
-rw-r--r--src/env_hooks.c297
-rw-r--r--src/exec.c480
-rw-r--r--src/exec_common.c219
-rw-r--r--src/exec_monitor.c719
-rw-r--r--src/exec_nopty.c573
-rw-r--r--src/exec_pty.c1813
-rw-r--r--src/get_pty.c195
-rw-r--r--src/hooks.c251
-rw-r--r--src/load_plugins.c369
-rw-r--r--src/net_ifs.c371
-rw-r--r--src/openbsd.c45
-rw-r--r--src/parse_args.c774
-rw-r--r--src/preload.c74
-rw-r--r--src/preserve_fds.c222
-rw-r--r--src/regress/noexec/check_noexec.c203
-rw-r--r--src/regress/ttyname/check_ttyname.c85
-rw-r--r--src/selinux.c460
-rw-r--r--src/sesh.c268
-rw-r--r--src/signal.c193
-rw-r--r--src/solaris.c122
-rw-r--r--src/sudo.c1450
-rw-r--r--src/sudo.h279
-rw-r--r--src/sudo_edit.c1101
-rw-r--r--src/sudo_exec.h111
-rw-r--r--src/sudo_noexec.c261
-rw-r--r--src/sudo_plugin_int.h117
-rw-r--r--src/sudo_usage.h.in36
-rw-r--r--src/tcsetpgrp_nobg.c78
-rw-r--r--src/tgetpass.c446
-rw-r--r--src/ttyname.c336
-rw-r--r--src/utmp.c389
-rw-r--r--sudo.pp531
801 files changed, 383106 insertions, 0 deletions
diff --git a/ABOUT-NLS b/ABOUT-NLS
new file mode 100644
index 0000000..82047a2
--- /dev/null
+++ b/ABOUT-NLS
@@ -0,0 +1,1406 @@
+1 Notes on the Free Translation Project
+***************************************
+
+Free software is going international! The Free Translation Project is a
+way to get maintainers of free software, translators, and users all
+together, so that free software will gradually become able to speak many
+languages. A few packages already provide translations for their
+messages.
+
+ If you found this 'ABOUT-NLS' file inside a distribution, you may
+assume that the distributed package does use GNU 'gettext' internally,
+itself available at your nearest GNU archive site. But you do _not_
+need to install GNU 'gettext' prior to configuring, installing or using
+this package with messages translated.
+
+ Installers will find here some useful hints. These notes also
+explain how users should proceed for getting the programs to use the
+available translations. They tell how people wanting to contribute and
+work on translations can contact the appropriate team.
+
+1.1 INSTALL Matters
+===================
+
+Some packages are "localizable" when properly installed; the programs
+they contain can be made to speak your own native language. Most such
+packages use GNU 'gettext'. Other packages have their own ways to
+internationalization, predating GNU 'gettext'.
+
+ By default, this package will be installed to allow translation of
+messages. It will automatically detect whether the system already
+provides the GNU 'gettext' functions. Installers may use special
+options at configuration time for changing the default behaviour. The
+command:
+
+ ./configure --disable-nls
+
+will _totally_ disable translation of messages.
+
+ When you already have GNU 'gettext' installed on your system and run
+configure without an option for your new package, 'configure' will
+probably detect the previously built and installed 'libintl' library and
+will decide to use it. If not, you may have to to use the
+'--enable-nls[=location]' option to tell 'configure' where to look for it.
+
+ Internationalized packages usually have many 'po/LL.po' files, where
+LL gives an ISO 639 two-letter code identifying the language. Unless
+translations have been forbidden at 'configure' time by using the
+'--disable-nls' switch, all available translations are installed
+together with the package. However, the environment variable 'LINGUAS'
+may be set, prior to configuration, to limit the installed set.
+'LINGUAS' should then contain a space separated list of two-letter
+codes, stating which languages are allowed.
+
+1.2 Using This Package
+======================
+
+As a user, if your language has been installed for this package, you
+only have to set the 'LANG' environment variable to the appropriate
+'LL_CC' combination. If you happen to have the 'LC_ALL' or some other
+'LC_xxx' environment variables set, you should unset them before setting
+'LANG', otherwise the setting of 'LANG' will not have the desired
+effect. Here 'LL' is an ISO 639 two-letter language code, and 'CC' is
+an ISO 3166 two-letter country code. For example, let's suppose that
+you speak German and live in Germany. At the shell prompt, merely
+execute 'setenv LANG de_DE' (in 'csh'), 'export LANG; LANG=de_DE' (in
+'sh') or 'export LANG=de_DE' (in 'bash'). This can be done from your
+'.login' or '.profile' file, once and for all.
+
+ You might think that the country code specification is redundant.
+But in fact, some languages have dialects in different countries. For
+example, 'de_AT' is used for Austria, and 'pt_BR' for Brazil. The
+country code serves to distinguish the dialects.
+
+ The locale naming convention of 'LL_CC', with 'LL' denoting the
+language and 'CC' denoting the country, is the one use on systems based
+on GNU libc. On other systems, some variations of this scheme are used,
+such as 'LL' or 'LL_CC.ENCODING'. You can get the list of locales
+supported by your system for your language by running the command
+'locale -a | grep '^LL''.
+
+ Not all programs have translations for all languages. By default, an
+English message is shown in place of a nonexistent translation. If you
+understand other languages, you can set up a priority list of languages.
+This is done through a different environment variable, called
+'LANGUAGE'. GNU 'gettext' gives preference to 'LANGUAGE' over 'LANG'
+for the purpose of message handling, but you still need to have 'LANG'
+set to the primary language; this is required by other parts of the
+system libraries. For example, some Swedish users who would rather read
+translations in German than English for when Swedish is not available,
+set 'LANGUAGE' to 'sv:de' while leaving 'LANG' to 'sv_SE'.
+
+ Special advice for Norwegian users: The language code for Norwegian
+bokma*l changed from 'no' to 'nb' recently (in 2003). During the
+transition period, while some message catalogs for this language are
+installed under 'nb' and some older ones under 'no', it's recommended
+for Norwegian users to set 'LANGUAGE' to 'nb:no' so that both newer and
+older translations are used.
+
+ In the 'LANGUAGE' environment variable, but not in the 'LANG'
+environment variable, 'LL_CC' combinations can be abbreviated as 'LL' to
+denote the language's main dialect. For example, 'de' is equivalent to
+'de_DE' (German as spoken in Germany), and 'pt' to 'pt_PT' (Portuguese
+as spoken in Portugal) in this context.
+
+1.3 Translating Teams
+=====================
+
+For the Free Translation Project to be a success, we need interested
+people who like their own language and write it well, and who are also
+able to synergize with other translators speaking the same language.
+Each translation team has its own mailing list. The up-to-date list of
+teams can be found at the Free Translation Project's homepage,
+'http://translationproject.org/', in the "Teams" area.
+
+ If you'd like to volunteer to _work_ at translating messages, you
+should become a member of the translating team for your own language.
+The subscribing address is _not_ the same as the list itself, it has
+'-request' appended. For example, speakers of Swedish can send a
+message to 'sv-request@li.org', having this message body:
+
+ subscribe
+
+ Keep in mind that team members are expected to participate _actively_
+in translations, or at solving translational difficulties, rather than
+merely lurking around. If your team does not exist yet and you want to
+start one, or if you are unsure about what to do or how to get started,
+please write to 'coordinator@translationproject.org' to reach the
+coordinator for all translator teams.
+
+ The English team is special. It works at improving and uniformizing
+the terminology in use. Proven linguistic skills are praised more than
+programming skills, here.
+
+1.4 Available Packages
+======================
+
+Languages are not equally supported in all packages. The following
+matrix shows the current state of internationalization, as of Jun 2014.
+The matrix shows, in regard of each package, for which languages PO
+files have been submitted to translation coordination, with a
+translation percentage of at least 50%.
+
+ Ready PO files af am an ar as ast az be bg bn bn_IN bs ca crh cs
+ +---------------------------------------------------+
+ a2ps | [] [] [] |
+ aegis | |
+ anubis | |
+ aspell | [] [] [] |
+ bash | [] [] [] |
+ bfd | |
+ binutils | [] |
+ bison | |
+ bison-runtime | [] |
+ buzztrax | [] |
+ ccd2cue | |
+ ccide | |
+ cflow | |
+ clisp | |
+ coreutils | [] [] |
+ cpio | |
+ cppi | |
+ cpplib | [] |
+ cryptsetup | [] |
+ datamash | |
+ denemo | [] [] |
+ dfarc | [] |
+ dialog | [] [] [] |
+ dico | |
+ diffutils | [] |
+ dink | [] |
+ direvent | |
+ doodle | [] |
+ dos2unix | |
+ dos2unix-man | |
+ e2fsprogs | [] [] |
+ enscript | [] |
+ exif | [] |
+ fetchmail | [] [] |
+ findutils | [] |
+ flex | [] |
+ freedink | [] [] |
+ fusionforge | |
+ gas | |
+ gawk | [] |
+ gcal | [] |
+ gcc | |
+ gdbm | |
+ gettext-examples | [] [] [] [] [] |
+ gettext-runtime | [] [] [] |
+ gettext-tools | [] [] |
+ gip | [] [] |
+ gjay | |
+ glunarclock | [] [] [] |
+ gnubiff | [] |
+ gnubik | [] |
+ gnucash | () () [] |
+ gnuchess | |
+ gnulib | [] |
+ gnunet | |
+ gnunet-gtk | |
+ gold | |
+ gphoto2 | [] |
+ gprof | [] |
+ gpsdrive | |
+ gramadoir | |
+ grep | [] [] |
+ grub | [] |
+ gsasl | |
+ gss | |
+ gst-plugins-bad | [] |
+ gst-plugins-base | [] [] [] |
+ gst-plugins-good | [] [] [] |
+ gst-plugins-ugly | [] [] [] |
+ gstreamer | [] [] [] [] |
+ gtick | [] |
+ gtkam | [] [] |
+ gtkorphan | [] [] |
+ gtkspell | [] [] [] [] [] |
+ guix | |
+ guix-packages | |
+ gutenprint | [] |
+ hello | [] |
+ help2man | |
+ help2man-texi | |
+ hylafax | |
+ idutils | |
+ iso_15924 | [] |
+ iso_3166 | [] [] [] [] [] [] [] [] [] [] |
+ iso_3166_2 | |
+ iso_4217 | [] |
+ iso_639 | [] [] [] [] [] [] [] [] [] |
+ iso_639_3 | [] [] |
+ iso_639_5 | |
+ jwhois | |
+ kbd | [] |
+ klavaro | [] [] [] [] [] |
+ latrine | |
+ ld | [] |
+ leafpad | [] [] [] [] |
+ libc | [] [] [] |
+ libexif | () |
+ libextractor | |
+ libgnutls | [] |
+ libgpg-error | [] |
+ libgphoto2 | [] |
+ libgphoto2_port | [] |
+ libgsasl | |
+ libiconv | [] [] |
+ libidn | [] |
+ liferea | [] [] [] [] |
+ lilypond | [] [] |
+ lordsawar | [] |
+ lprng | |
+ lynx | [] [] |
+ m4 | [] |
+ mailfromd | |
+ mailutils | |
+ make | [] |
+ man-db | [] [] |
+ man-db-manpages | |
+ midi-instruments | [] [] [] |
+ minicom | [] |
+ mkisofs | [] |
+ myserver | [] |
+ nano | [] [] [] |
+ opcodes | |
+ parted | [] |
+ pies | |
+ popt | [] |
+ procps-ng | |
+ procps-ng-man | |
+ psmisc | [] |
+ pspp | [] |
+ pushover | [] |
+ pwdutils | |
+ pyspread | |
+ radius | [] |
+ recode | [] [] [] |
+ recutils | |
+ rpm | |
+ rush | |
+ sarg | |
+ sed | [] [] [] |
+ sharutils | [] |
+ shishi | |
+ skribilo | |
+ solfege | [] |
+ solfege-manual | |
+ spotmachine | |
+ sudo | [] [] |
+ sudoers | [] [] |
+ sysstat | [] |
+ tar | [] [] [] |
+ texinfo | [] [] |
+ texinfo_document | [] |
+ tigervnc | [] |
+ tin | |
+ tin-man | |
+ tracgoogleappsa... | |
+ trader | |
+ util-linux | [] |
+ ve | |
+ vice | |
+ vmm | |
+ vorbis-tools | [] |
+ wastesedge | |
+ wcd | |
+ wcd-man | |
+ wdiff | [] [] |
+ wget | [] [] |
+ wyslij-po | |
+ xboard | |
+ xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] |
+ xkeyboard-config | [] [] [] |
+ +---------------------------------------------------+
+ af am an ar as ast az be bg bn bn_IN bs ca crh cs
+ 4 0 2 4 3 11 0 8 24 3 3 1 55 4 76
+
+ da de el en en_GB en_ZA eo es et eu fa fi fr
+ +--------------------------------------------------+
+ a2ps | [] [] [] [] [] [] [] [] [] |
+ aegis | [] [] [] [] |
+ anubis | [] [] [] [] [] |
+ aspell | [] [] [] [] [] [] [] |
+ bash | [] [] [] [] [] |
+ bfd | [] [] [] [] |
+ binutils | [] [] [] |
+ bison | [] [] [] [] [] [] [] [] |
+ bison-runtime | [] [] [] [] [] [] [] [] |
+ buzztrax | [] [] [] [] |
+ ccd2cue | [] [] [] |
+ ccide | [] [] [] [] [] [] |
+ cflow | [] [] [] [] [] |
+ clisp | [] [] [] [] [] |
+ coreutils | [] [] [] [] [] |
+ cpio | [] [] [] [] [] |
+ cppi | [] [] [] [] [] |
+ cpplib | [] [] [] [] [] [] |
+ cryptsetup | [] [] [] [] [] |
+ datamash | [] [] [] [] |
+ denemo | |
+ dfarc | [] [] [] [] [] [] |
+ dialog | [] [] [] [] [] [] [] [] [] |
+ dico | [] [] [] [] |
+ diffutils | [] [] [] [] [] [] |
+ dink | [] [] [] [] [] [] |
+ direvent | [] [] [] [] |
+ doodle | [] [] [] [] |
+ dos2unix | [] [] [] [] [] |
+ dos2unix-man | [] [] [] |
+ e2fsprogs | [] [] [] [] [] |
+ enscript | [] [] [] [] [] [] |
+ exif | [] [] [] [] [] [] |
+ fetchmail | [] () [] [] [] [] [] |
+ findutils | [] [] [] [] [] [] [] [] |
+ flex | [] [] [] [] [] [] |
+ freedink | [] [] [] [] [] [] [] [] |
+ fusionforge | [] [] [] |
+ gas | [] [] [] |
+ gawk | [] [] [] [] [] |
+ gcal | [] [] [] [] |
+ gcc | [] [] |
+ gdbm | [] [] [] [] [] |
+ gettext-examples | [] [] [] [] [] [] [] |
+ gettext-runtime | [] [] [] [] [] [] |
+ gettext-tools | [] [] [] [] [] |
+ gip | [] [] [] [] [] [] [] |
+ gjay | [] [] [] [] |
+ glunarclock | [] [] [] [] [] |
+ gnubiff | () [] [] () |
+ gnubik | [] [] [] [] [] |
+ gnucash | [] () () () () () () |
+ gnuchess | [] [] [] [] |
+ gnulib | [] [] [] [] [] [] [] |
+ gnunet | [] |
+ gnunet-gtk | [] |
+ gold | [] [] [] |
+ gphoto2 | [] () [] [] |
+ gprof | [] [] [] [] [] [] |
+ gpsdrive | [] [] [] [] |
+ gramadoir | [] [] [] [] [] |
+ grep | [] [] [] [] [] [] [] |
+ grub | [] [] [] [] [] |
+ gsasl | [] [] [] [] [] |
+ gss | [] [] [] [] [] |
+ gst-plugins-bad | [] [] |
+ gst-plugins-base | [] [] [] [] [] [] |
+ gst-plugins-good | [] [] [] [] [] [] [] |
+ gst-plugins-ugly | [] [] [] [] [] [] [] [] |
+ gstreamer | [] [] [] [] [] [] [] |
+ gtick | [] () [] [] [] |
+ gtkam | [] () [] [] [] [] |
+ gtkorphan | [] [] [] [] [] |
+ gtkspell | [] [] [] [] [] [] [] [] |
+ guix | [] [] [] |
+ guix-packages | |
+ gutenprint | [] [] [] [] |
+ hello | [] [] [] [] [] [] [] [] |
+ help2man | [] [] [] [] [] [] [] |
+ help2man-texi | [] [] [] |
+ hylafax | [] [] |
+ idutils | [] [] [] [] [] |
+ iso_15924 | [] () [] [] () [] () |
+ iso_3166 | [] () [] [] [] [] () [] () |
+ iso_3166_2 | [] () () () |
+ iso_4217 | [] () [] [] [] () [] () |
+ iso_639 | [] () [] [] () [] () |
+ iso_639_3 | () () () |
+ iso_639_5 | () () () |
+ jwhois | [] [] [] [] [] |
+ kbd | [] [] [] [] [] [] |
+ klavaro | [] [] [] [] [] [] [] |
+ latrine | [] () [] [] |
+ ld | [] [] [] [] |
+ leafpad | [] [] [] [] [] [] [] [] |
+ libc | [] [] [] [] [] |
+ libexif | [] [] () [] [] |
+ libextractor | [] |
+ libgnutls | [] [] [] [] |
+ libgpg-error | [] [] [] |
+ libgphoto2 | [] () [] |
+ libgphoto2_port | [] () [] [] [] [] |
+ libgsasl | [] [] [] [] [] |
+ libiconv | [] [] [] [] [] [] [] |
+ libidn | [] [] [] [] [] |
+ liferea | [] () [] [] [] [] [] |
+ lilypond | [] [] [] [] [] [] |
+ lordsawar | [] [] |
+ lprng | |
+ lynx | [] [] [] [] [] [] |
+ m4 | [] [] [] [] [] [] |
+ mailfromd | [] |
+ mailutils | [] [] [] [] |
+ make | [] [] [] [] [] |
+ man-db | [] [] [] [] |
+ man-db-manpages | [] [] |
+ midi-instruments | [] [] [] [] [] [] [] [] [] |
+ minicom | [] [] [] [] [] |
+ mkisofs | [] [] [] |
+ myserver | [] [] [] [] |
+ nano | [] [] [] [] [] [] [] |
+ opcodes | [] [] [] [] [] |
+ parted | [] [] [] |
+ pies | [] |
+ popt | [] [] [] [] [] [] |
+ procps-ng | [] [] |
+ procps-ng-man | [] [] |
+ psmisc | [] [] [] [] [] [] [] |
+ pspp | [] [] [] |
+ pushover | () [] [] [] |
+ pwdutils | [] [] [] |
+ pyspread | [] [] |
+ radius | [] [] |
+ recode | [] [] [] [] [] [] [] |
+ recutils | [] [] [] [] |
+ rpm | [] [] [] [] [] |
+ rush | [] [] [] |
+ sarg | [] [] |
+ sed | [] [] [] [] [] [] [] [] |
+ sharutils | [] [] [] [] |
+ shishi | [] [] [] |
+ skribilo | [] [] |
+ solfege | [] [] [] [] [] [] [] [] |
+ solfege-manual | [] [] [] [] [] |
+ spotmachine | [] [] [] [] |
+ sudo | [] [] [] [] [] [] |
+ sudoers | [] [] [] [] [] [] |
+ sysstat | [] [] [] [] [] [] |
+ tar | [] [] [] [] [] [] [] |
+ texinfo | [] [] [] [] [] |
+ texinfo_document | [] [] [] [] |
+ tigervnc | [] [] [] [] [] [] |
+ tin | [] [] [] [] |
+ tin-man | [] |
+ tracgoogleappsa... | [] [] [] [] [] |
+ trader | [] [] [] [] [] [] |
+ util-linux | [] [] [] [] |
+ ve | [] [] [] [] [] |
+ vice | () () () |
+ vmm | [] [] |
+ vorbis-tools | [] [] [] [] |
+ wastesedge | [] () |
+ wcd | [] [] [] [] |
+ wcd-man | [] |
+ wdiff | [] [] [] [] [] [] [] |
+ wget | [] [] [] [] [] [] |
+ wyslij-po | [] [] [] [] |
+ xboard | [] [] [] [] |
+ xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] |
+ xkeyboard-config | [] [] [] [] [] [] [] |
+ +--------------------------------------------------+
+ da de el en en_GB en_ZA eo es et eu fa fi fr
+ 123 134 32 1 6 0 97 97 23 14 4 106 139
+
+ ga gd gl gu he hi hr hu hy ia id is it ja ka kk
+ +-------------------------------------------------+
+ a2ps | [] [] [] [] |
+ aegis | [] |
+ anubis | [] [] [] [] |
+ aspell | [] [] [] [] [] |
+ bash | [] [] [] [] |
+ bfd | [] [] |
+ binutils | [] [] [] |
+ bison | [] |
+ bison-runtime | [] [] [] [] [] [] [] [] |
+ buzztrax | |
+ ccd2cue | [] |
+ ccide | [] [] |
+ cflow | [] [] [] |
+ clisp | |
+ coreutils | [] [] [] |
+ cpio | [] [] [] [] [] [] |
+ cppi | [] [] [] [] [] |
+ cpplib | [] [] |
+ cryptsetup | [] |
+ datamash | |
+ denemo | [] |
+ dfarc | [] [] [] |
+ dialog | [] [] [] [] [] [] [] [] [] [] |
+ dico | |
+ diffutils | [] [] [] [] |
+ dink | [] |
+ direvent | [] |
+ doodle | [] [] |
+ dos2unix | [] [] |
+ dos2unix-man | |
+ e2fsprogs | [] |
+ enscript | [] [] [] |
+ exif | [] [] [] [] [] [] |
+ fetchmail | [] [] [] |
+ findutils | [] [] [] [] [] [] [] |
+ flex | [] |
+ freedink | [] [] [] [] |
+ fusionforge | |
+ gas | [] |
+ gawk | [] () [] |
+ gcal | |
+ gcc | |
+ gdbm | |
+ gettext-examples | [] [] [] [] [] [] [] |
+ gettext-runtime | [] [] [] [] [] [] [] |
+ gettext-tools | [] [] [] |
+ gip | [] [] [] [] [] [] |
+ gjay | [] |
+ glunarclock | [] [] [] [] [] [] |
+ gnubiff | [] [] () |
+ gnubik | [] [] [] |
+ gnucash | () () () () () [] |
+ gnuchess | |
+ gnulib | [] [] [] [] [] |
+ gnunet | |
+ gnunet-gtk | |
+ gold | [] [] |
+ gphoto2 | [] [] [] [] |
+ gprof | [] [] [] [] |
+ gpsdrive | [] [] [] [] |
+ gramadoir | [] [] [] |
+ grep | [] [] [] [] [] [] [] |
+ grub | [] [] [] |
+ gsasl | [] [] [] [] [] |
+ gss | [] [] [] [] [] |
+ gst-plugins-bad | [] |
+ gst-plugins-base | [] [] [] [] |
+ gst-plugins-good | [] [] [] [] [] [] |
+ gst-plugins-ugly | [] [] [] [] [] [] |
+ gstreamer | [] [] [] [] [] |
+ gtick | [] [] [] [] [] |
+ gtkam | [] [] [] [] [] |
+ gtkorphan | [] [] [] [] |
+ gtkspell | [] [] [] [] [] [] [] [] [] [] |
+ guix | [] |
+ guix-packages | |
+ gutenprint | [] [] [] |
+ hello | [] [] [] [] [] |
+ help2man | [] [] [] |
+ help2man-texi | |
+ hylafax | [] |
+ idutils | [] [] |
+ iso_15924 | [] [] [] [] [] [] |
+ iso_3166 | [] [] [] [] [] [] [] [] [] [] [] [] [] |
+ iso_3166_2 | [] [] |
+ iso_4217 | [] [] [] [] [] [] |
+ iso_639 | [] [] [] [] [] [] [] [] [] |
+ iso_639_3 | [] [] |
+ iso_639_5 | |
+ jwhois | [] [] [] [] |
+ kbd | [] [] [] |
+ klavaro | [] [] [] [] |
+ latrine | [] |
+ ld | [] [] [] [] |
+ leafpad | [] [] [] [] [] [] [] () |
+ libc | [] [] [] [] [] |
+ libexif | [] |
+ libextractor | |
+ libgnutls | [] |
+ libgpg-error | [] [] [] |
+ libgphoto2 | [] [] |
+ libgphoto2_port | [] [] |
+ libgsasl | [] [] [] [] |
+ libiconv | [] [] [] [] [] [] [] |
+ libidn | [] [] [] [] |
+ liferea | [] [] [] [] [] |
+ lilypond | [] |
+ lordsawar | |
+ lprng | [] |
+ lynx | [] [] [] [] |
+ m4 | [] [] [] [] [] |
+ mailfromd | |
+ mailutils | |
+ make | [] [] [] [] |
+ man-db | [] [] |
+ man-db-manpages | [] [] |
+ midi-instruments | [] [] [] [] [] [] [] [] [] |
+ minicom | [] [] [] |
+ mkisofs | [] [] |
+ myserver | [] |
+ nano | [] [] [] [] [] |
+ opcodes | [] [] [] |
+ parted | [] [] [] [] |
+ pies | |
+ popt | [] [] [] [] [] [] [] [] [] [] |
+ procps-ng | |
+ procps-ng-man | |
+ psmisc | [] [] [] [] |
+ pspp | [] [] |
+ pushover | [] |
+ pwdutils | [] |
+ pyspread | |
+ radius | [] |
+ recode | [] [] [] [] [] [] [] |
+ recutils | |
+ rpm | [] |
+ rush | [] |
+ sarg | |
+ sed | [] [] [] [] [] [] [] |
+ sharutils | |
+ shishi | |
+ skribilo | [] |
+ solfege | [] [] |
+ solfege-manual | |
+ spotmachine | |
+ sudo | [] [] [] [] |
+ sudoers | [] [] [] |
+ sysstat | [] [] [] |
+ tar | [] [] [] [] [] [] |
+ texinfo | [] [] [] |
+ texinfo_document | [] [] |
+ tigervnc | |
+ tin | |
+ tin-man | |
+ tracgoogleappsa... | [] [] [] [] |
+ trader | [] [] |
+ util-linux | [] |
+ ve | [] |
+ vice | () () |
+ vmm | |
+ vorbis-tools | [] [] |
+ wastesedge | () |
+ wcd | |
+ wcd-man | |
+ wdiff | [] [] [] |
+ wget | [] [] [] [] |
+ wyslij-po | [] [] [] |
+ xboard | |
+ xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] [] [] [] [] |
+ xkeyboard-config | [] [] [] [] [] |
+ +-------------------------------------------------+
+ ga gd gl gu he hi hr hu hy ia id is it ja ka kk
+ 36 2 49 4 8 2 54 75 2 6 84 11 89 60 0 3
+
+ kn ko ku ky lg lt lv mk ml mn mr ms mt nb ne nl
+ +--------------------------------------------------+
+ a2ps | [] [] |
+ aegis | [] |
+ anubis | [] [] [] |
+ aspell | [] [] |
+ bash | [] [] |
+ bfd | |
+ binutils | |
+ bison | [] |
+ bison-runtime | [] [] [] [] [] [] |
+ buzztrax | |
+ ccd2cue | |
+ ccide | [] [] |
+ cflow | [] |
+ clisp | [] |
+ coreutils | [] [] |
+ cpio | [] |
+ cppi | |
+ cpplib | [] |
+ cryptsetup | [] |
+ datamash | [] [] |
+ denemo | |
+ dfarc | [] [] |
+ dialog | [] [] [] [] [] [] |
+ dico | |
+ diffutils | [] [] [] |
+ dink | [] |
+ direvent | [] |
+ doodle | [] |
+ dos2unix | [] [] |
+ dos2unix-man | [] |
+ e2fsprogs | [] |
+ enscript | [] |
+ exif | [] [] |
+ fetchmail | [] |
+ findutils | [] [] |
+ flex | [] |
+ freedink | [] [] |
+ fusionforge | |
+ gas | |
+ gawk | [] |
+ gcal | |
+ gcc | |
+ gdbm | |
+ gettext-examples | [] [] [] [] [] [] |
+ gettext-runtime | [] [] |
+ gettext-tools | [] |
+ gip | [] [] [] |
+ gjay | |
+ glunarclock | [] [] |
+ gnubiff | [] |
+ gnubik | [] [] |
+ gnucash | () () () () () () () [] |
+ gnuchess | [] [] |
+ gnulib | [] |
+ gnunet | |
+ gnunet-gtk | |
+ gold | |
+ gphoto2 | [] |
+ gprof | [] [] |
+ gpsdrive | [] |
+ gramadoir | [] |
+ grep | [] [] |
+ grub | [] [] [] |
+ gsasl | [] |
+ gss | |
+ gst-plugins-bad | [] |
+ gst-plugins-base | [] [] [] |
+ gst-plugins-good | [] [] [] [] |
+ gst-plugins-ugly | [] [] [] [] [] |
+ gstreamer | [] [] |
+ gtick | [] |
+ gtkam | [] [] |
+ gtkorphan | [] [] |
+ gtkspell | [] [] [] [] [] [] [] |
+ guix | |
+ guix-packages | |
+ gutenprint | [] |
+ hello | [] [] [] |
+ help2man | [] |
+ help2man-texi | |
+ hylafax | [] |
+ idutils | [] |
+ iso_15924 | () [] [] |
+ iso_3166 | [] [] [] () [] [] [] [] [] [] |
+ iso_3166_2 | () [] |
+ iso_4217 | () [] [] [] |
+ iso_639 | [] [] () [] [] [] [] |
+ iso_639_3 | [] () [] |
+ iso_639_5 | () |
+ jwhois | [] [] |
+ kbd | [] |
+ klavaro | [] [] |
+ latrine | |
+ ld | |
+ leafpad | [] [] [] [] [] |
+ libc | [] [] |
+ libexif | [] |
+ libextractor | [] |
+ libgnutls | [] [] |
+ libgpg-error | [] |
+ libgphoto2 | [] |
+ libgphoto2_port | [] |
+ libgsasl | [] |
+ libiconv | [] [] |
+ libidn | [] |
+ liferea | [] [] [] |
+ lilypond | |
+ lordsawar | |
+ lprng | |
+ lynx | [] |
+ m4 | [] |
+ mailfromd | |
+ mailutils | |
+ make | [] [] |
+ man-db | [] |
+ man-db-manpages | [] |
+ midi-instruments | [] [] [] [] [] [] [] |
+ minicom | [] |
+ mkisofs | [] |
+ myserver | |
+ nano | [] [] [] |
+ opcodes | [] |
+ parted | [] |
+ pies | |
+ popt | [] [] [] [] [] |
+ procps-ng | |
+ procps-ng-man | |
+ psmisc | [] |
+ pspp | [] [] |
+ pushover | |
+ pwdutils | [] |
+ pyspread | |
+ radius | [] |
+ recode | [] [] |
+ recutils | [] |
+ rpm | [] |
+ rush | [] |
+ sarg | |
+ sed | [] [] |
+ sharutils | [] |
+ shishi | |
+ skribilo | |
+ solfege | [] [] |
+ solfege-manual | [] |
+ spotmachine | [] |
+ sudo | [] [] |
+ sudoers | [] [] |
+ sysstat | [] [] |
+ tar | [] [] [] |
+ texinfo | [] |
+ texinfo_document | [] |
+ tigervnc | [] |
+ tin | |
+ tin-man | |
+ tracgoogleappsa... | [] [] [] |
+ trader | [] |
+ util-linux | [] |
+ ve | [] |
+ vice | [] |
+ vmm | [] |
+ vorbis-tools | [] |
+ wastesedge | [] |
+ wcd | [] |
+ wcd-man | [] |
+ wdiff | [] |
+ wget | [] [] |
+ wyslij-po | [] |
+ xboard | [] |
+ xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] [] |
+ xkeyboard-config | [] [] [] |
+ +--------------------------------------------------+
+ kn ko ku ky lg lt lv mk ml mn mr ms mt nb ne nl
+ 5 11 4 6 0 13 24 3 3 3 4 12 2 40 1 126
+
+ nn or os pa pl ps pt pt_BR ro ru rw sk sl sq sr
+ +--------------------------------------------------+
+ a2ps | [] [] [] [] [] [] [] |
+ aegis | [] [] |
+ anubis | [] [] [] |
+ aspell | [] [] [] [] [] [] [] |
+ bash | [] [] [] [] [] |
+ bfd | [] |
+ binutils | [] [] |
+ bison | [] [] [] |
+ bison-runtime | [] [] [] [] [] [] [] [] |
+ buzztrax | |
+ ccd2cue | [] |
+ ccide | [] [] [] |
+ cflow | [] [] |
+ clisp | [] |
+ coreutils | [] [] [] [] |
+ cpio | [] [] [] |
+ cppi | [] [] [] |
+ cpplib | [] [] [] |
+ cryptsetup | [] [] |
+ datamash | [] [] |
+ denemo | |
+ dfarc | [] [] [] |
+ dialog | [] [] [] [] [] [] [] |
+ dico | [] |
+ diffutils | [] [] |
+ dink | |
+ direvent | [] [] |
+ doodle | [] [] |
+ dos2unix | [] [] [] [] |
+ dos2unix-man | [] [] |
+ e2fsprogs | [] |
+ enscript | [] [] [] [] [] [] |
+ exif | [] [] [] [] [] [] |
+ fetchmail | [] [] [] |
+ findutils | [] [] [] [] [] |
+ flex | [] [] [] [] [] |
+ freedink | [] [] [] [] [] |
+ fusionforge | |
+ gas | |
+ gawk | [] |
+ gcal | |
+ gcc | |
+ gdbm | [] [] [] |
+ gettext-examples | [] [] [] [] [] [] [] [] |
+ gettext-runtime | [] [] [] [] [] [] [] [] [] |
+ gettext-tools | [] [] [] [] [] [] [] |
+ gip | [] [] [] [] [] |
+ gjay | [] |
+ glunarclock | [] [] [] [] [] [] |
+ gnubiff | [] |
+ gnubik | [] [] [] [] |
+ gnucash | () () () () [] |
+ gnuchess | [] [] |
+ gnulib | [] [] [] [] [] |
+ gnunet | |
+ gnunet-gtk | |
+ gold | |
+ gphoto2 | [] [] [] [] [] |
+ gprof | [] [] [] [] |
+ gpsdrive | [] |
+ gramadoir | [] [] |
+ grep | [] [] [] [] [] [] |
+ grub | [] [] [] [] [] |
+ gsasl | [] [] [] |
+ gss | [] [] [] [] |
+ gst-plugins-bad | [] [] [] [] |
+ gst-plugins-base | [] [] [] [] [] [] |
+ gst-plugins-good | [] [] [] [] [] [] [] |
+ gst-plugins-ugly | [] [] [] [] [] [] [] |
+ gstreamer | [] [] [] [] [] [] [] |
+ gtick | [] [] [] [] [] |
+ gtkam | [] [] [] [] [] [] |
+ gtkorphan | [] [] [] [] |
+ gtkspell | [] [] [] [] [] [] [] [] [] |
+ guix | |
+ guix-packages | |
+ gutenprint | [] |
+ hello | [] [] [] [] [] [] |
+ help2man | [] [] [] [] |
+ help2man-texi | [] |
+ hylafax | |
+ idutils | [] [] [] |
+ iso_15924 | [] () [] [] [] [] |
+ iso_3166 | [] [] [] [] () [] [] [] [] [] [] [] [] |
+ iso_3166_2 | [] () [] |
+ iso_4217 | [] [] () [] [] [] [] [] |
+ iso_639 | [] [] [] () [] [] [] [] [] [] |
+ iso_639_3 | [] () |
+ iso_639_5 | () [] |
+ jwhois | [] [] [] [] |
+ kbd | [] [] |
+ klavaro | [] [] [] [] [] |
+ latrine | [] |
+ ld | |
+ leafpad | [] [] [] [] [] [] [] [] [] |
+ libc | [] [] [] |
+ libexif | [] () [] |
+ libextractor | [] |
+ libgnutls | [] |
+ libgpg-error | [] [] [] |
+ libgphoto2 | [] |
+ libgphoto2_port | [] [] [] [] [] |
+ libgsasl | [] [] [] [] |
+ libiconv | [] [] [] [] [] |
+ libidn | [] [] [] |
+ liferea | [] [] [] [] () [] [] |
+ lilypond | |
+ lordsawar | |
+ lprng | [] |
+ lynx | [] [] |
+ m4 | [] [] [] [] [] |
+ mailfromd | [] |
+ mailutils | [] |
+ make | [] [] [] |
+ man-db | [] [] [] |
+ man-db-manpages | [] [] [] |
+ midi-instruments | [] [] [] [] [] [] [] [] |
+ minicom | [] [] [] [] |
+ mkisofs | [] [] [] |
+ myserver | [] [] |
+ nano | [] [] [] [] [] [] |
+ opcodes | |
+ parted | [] [] [] [] [] [] |
+ pies | [] |
+ popt | [] [] [] [] [] [] |
+ procps-ng | [] |
+ procps-ng-man | [] |
+ psmisc | [] [] [] [] |
+ pspp | [] [] |
+ pushover | |
+ pwdutils | [] |
+ pyspread | [] [] |
+ radius | [] [] |
+ recode | [] [] [] [] [] [] [] [] |
+ recutils | [] |
+ rpm | [] |
+ rush | [] [] [] |
+ sarg | [] [] |
+ sed | [] [] [] [] [] [] [] [] |
+ sharutils | [] [] [] |
+ shishi | [] [] |
+ skribilo | |
+ solfege | [] [] [] |
+ solfege-manual | [] [] |
+ spotmachine | [] [] |
+ sudo | [] [] [] [] [] |
+ sudoers | [] [] [] [] |
+ sysstat | [] [] [] [] [] |
+ tar | [] [] [] [] [] |
+ texinfo | [] [] [] |
+ texinfo_document | [] [] |
+ tigervnc | |
+ tin | [] |
+ tin-man | |
+ tracgoogleappsa... | [] [] [] [] |
+ trader | [] |
+ util-linux | [] [] |
+ ve | [] [] [] |
+ vice | |
+ vmm | |
+ vorbis-tools | [] [] [] |
+ wastesedge | |
+ wcd | |
+ wcd-man | |
+ wdiff | [] [] [] [] [] |
+ wget | [] [] [] [] [] |
+ wyslij-po | [] [] [] [] |
+ xboard | [] [] |
+ xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] [] [] [] |
+ xkeyboard-config | [] [] [] [] |
+ +--------------------------------------------------+
+ nn or os pa pl ps pt pt_BR ro ru rw sk sl sq sr
+ 7 3 1 6 117 1 12 84 33 82 3 37 45 7 98
+
+ sv sw ta te tg th tr uk ur vi wa wo zh_CN zh_HK
+ +---------------------------------------------------+
+ a2ps | [] [] [] [] [] |
+ aegis | [] |
+ anubis | [] [] [] [] |
+ aspell | [] [] [] [] |
+ bash | [] [] [] [] [] |
+ bfd | [] [] |
+ binutils | [] [] [] |
+ bison | [] [] [] [] |
+ bison-runtime | [] [] [] [] [] [] |
+ buzztrax | [] [] [] |
+ ccd2cue | [] [] |
+ ccide | [] [] [] |
+ cflow | [] [] [] [] |
+ clisp | |
+ coreutils | [] [] [] [] |
+ cpio | [] [] [] [] [] |
+ cppi | [] [] [] |
+ cpplib | [] [] [] [] [] |
+ cryptsetup | [] [] [] |
+ datamash | [] [] [] |
+ denemo | |
+ dfarc | [] |
+ dialog | [] [] [] [] [] [] |
+ dico | [] |
+ diffutils | [] [] [] [] [] |
+ dink | |
+ direvent | [] [] |
+ doodle | [] [] |
+ dos2unix | [] [] [] |
+ dos2unix-man | [] [] |
+ e2fsprogs | [] [] [] [] |
+ enscript | [] [] [] [] |
+ exif | [] [] [] [] [] |
+ fetchmail | [] [] [] [] |
+ findutils | [] [] [] [] [] |
+ flex | [] [] [] |
+ freedink | [] [] |
+ fusionforge | |
+ gas | [] |
+ gawk | [] [] |
+ gcal | [] [] |
+ gcc | [] [] |
+ gdbm | [] [] |
+ gettext-examples | [] [] [] [] [] [] |
+ gettext-runtime | [] [] [] [] [] [] |
+ gettext-tools | [] [] [] [] [] |
+ gip | [] [] [] [] |
+ gjay | [] [] |
+ glunarclock | [] [] [] [] |
+ gnubiff | [] [] |
+ gnubik | [] [] [] |
+ gnucash | () () () () [] |
+ gnuchess | [] [] |
+ gnulib | [] [] [] [] |
+ gnunet | |
+ gnunet-gtk | |
+ gold | [] [] |
+ gphoto2 | [] [] [] [] |
+ gprof | [] [] [] [] |
+ gpsdrive | [] [] [] |
+ gramadoir | [] [] [] |
+ grep | [] [] [] [] [] |
+ grub | [] [] [] [] |
+ gsasl | [] [] [] [] |
+ gss | [] [] [] |
+ gst-plugins-bad | [] [] [] [] |
+ gst-plugins-base | [] [] [] [] [] |
+ gst-plugins-good | [] [] [] [] [] |
+ gst-plugins-ugly | [] [] [] [] [] |
+ gstreamer | [] [] [] [] [] |
+ gtick | [] [] [] |
+ gtkam | [] [] [] [] |
+ gtkorphan | [] [] [] |
+ gtkspell | [] [] [] [] [] [] [] [] |
+ guix | [] |
+ guix-packages | |
+ gutenprint | [] [] [] |
+ hello | [] [] [] [] [] |
+ help2man | [] [] [] |
+ help2man-texi | [] |
+ hylafax | [] |
+ idutils | [] [] [] |
+ iso_15924 | [] () [] [] () [] |
+ iso_3166 | [] [] () [] [] () [] [] [] |
+ iso_3166_2 | () [] [] () [] |
+ iso_4217 | [] () [] [] () [] [] |
+ iso_639 | [] [] [] () [] [] () [] [] [] |
+ iso_639_3 | [] () [] [] () |
+ iso_639_5 | () [] () |
+ jwhois | [] [] [] [] |
+ kbd | [] [] [] |
+ klavaro | [] [] [] [] [] [] |
+ latrine | [] [] |
+ ld | [] [] [] [] [] |
+ leafpad | [] [] [] [] [] [] |
+ libc | [] [] [] [] [] |
+ libexif | [] () |
+ libextractor | [] [] |
+ libgnutls | [] [] [] [] |
+ libgpg-error | [] [] [] [] |
+ libgphoto2 | [] [] |
+ libgphoto2_port | [] [] [] [] |
+ libgsasl | [] [] [] [] |
+ libiconv | [] [] [] [] [] |
+ libidn | () [] [] [] |
+ liferea | [] [] [] [] [] |
+ lilypond | [] |
+ lordsawar | |
+ lprng | [] |
+ lynx | [] [] [] [] |
+ m4 | [] [] [] |
+ mailfromd | [] [] |
+ mailutils | [] |
+ make | [] [] [] |
+ man-db | [] [] |
+ man-db-manpages | [] |
+ midi-instruments | [] [] [] [] [] [] |
+ minicom | [] [] |
+ mkisofs | [] [] [] |
+ myserver | [] |
+ nano | [] [] [] [] |
+ opcodes | [] [] |
+ parted | [] [] [] [] [] |
+ pies | [] [] |
+ popt | [] [] [] [] [] [] [] |
+ procps-ng | [] [] |
+ procps-ng-man | [] |
+ psmisc | [] [] [] |
+ pspp | [] [] [] |
+ pushover | [] |
+ pwdutils | [] [] |
+ pyspread | [] |
+ radius | [] [] |
+ recode | [] [] [] [] |
+ recutils | [] [] [] |
+ rpm | [] [] [] [] |
+ rush | [] [] |
+ sarg | |
+ sed | [] [] [] [] [] |
+ sharutils | [] [] [] |
+ shishi | [] |
+ skribilo | |
+ solfege | [] [] [] |
+ solfege-manual | [] |
+ spotmachine | [] [] |
+ sudo | [] [] [] [] |
+ sudoers | [] [] [] |
+ sysstat | [] [] [] [] |
+ tar | [] [] [] [] [] |
+ texinfo | [] [] [] |
+ texinfo_document | [] |
+ tigervnc | [] [] |
+ tin | [] |
+ tin-man | |
+ tracgoogleappsa... | [] [] [] [] [] |
+ trader | [] |
+ util-linux | [] [] [] |
+ ve | [] [] [] [] |
+ vice | () () |
+ vmm | |
+ vorbis-tools | [] [] |
+ wastesedge | |
+ wcd | [] [] |
+ wcd-man | [] |
+ wdiff | [] [] [] |
+ wget | [] [] [] |
+ wyslij-po | [] [] |
+ xboard | [] |
+ xdg-user-dirs | [] [] [] [] [] [] [] [] [] |
+ xkeyboard-config | [] [] [] [] |
+ +---------------------------------------------------+
+ sv sw ta te tg th tr uk ur vi wa wo zh_CN zh_HK
+ 87 1 4 3 0 14 52 114 1 130 7 1 88 7
+
+ zh_TW
+ +-------+
+ a2ps | | 30
+ aegis | | 9
+ anubis | | 19
+ aspell | | 28
+ bash | [] | 25
+ bfd | | 9
+ binutils | | 12
+ bison | [] | 18
+ bison-runtime | [] | 38
+ buzztrax | | 8
+ ccd2cue | | 7
+ ccide | | 16
+ cflow | | 15
+ clisp | | 10
+ coreutils | | 20
+ cpio | [] | 21
+ cppi | | 16
+ cpplib | [] | 19
+ cryptsetup | | 13
+ datamash | | 11
+ denemo | | 3
+ dfarc | | 16
+ dialog | [] | 42
+ dico | | 6
+ diffutils | | 21
+ dink | | 9
+ direvent | | 10
+ doodle | | 12
+ dos2unix | [] | 17
+ dos2unix-man | | 8
+ e2fsprogs | | 14
+ enscript | | 21
+ exif | | 26
+ fetchmail | | 19
+ findutils | | 28
+ flex | [] | 18
+ freedink | | 23
+ fusionforge | | 3
+ gas | | 5
+ gawk | | 12
+ gcal | | 7
+ gcc | | 4
+ gdbm | | 10
+ gettext-examples | [] | 40
+ gettext-runtime | [] | 34
+ gettext-tools | [] | 24
+ gip | [] | 28
+ gjay | | 8
+ glunarclock | [] | 27
+ gnubiff | | 9
+ gnubik | | 18
+ gnucash | () | 6
+ gnuchess | | 10
+ gnulib | | 23
+ gnunet | | 1
+ gnunet-gtk | | 1
+ gold | | 7
+ gphoto2 | [] | 19
+ gprof | | 21
+ gpsdrive | | 13
+ gramadoir | | 14
+ grep | [] | 30
+ grub | | 21
+ gsasl | [] | 19
+ gss | | 17
+ gst-plugins-bad | | 13
+ gst-plugins-base | | 27
+ gst-plugins-good | | 32
+ gst-plugins-ugly | | 34
+ gstreamer | [] | 31
+ gtick | | 19
+ gtkam | | 24
+ gtkorphan | | 20
+ gtkspell | [] | 48
+ guix | | 5
+ guix-packages | | 0
+ gutenprint | | 13
+ hello | [] | 29
+ help2man | | 18
+ help2man-texi | | 5
+ hylafax | | 5
+ idutils | | 14
+ iso_15924 | [] | 23
+ iso_3166 | [] | 58
+ iso_3166_2 | | 9
+ iso_4217 | [] | 28
+ iso_639 | [] | 46
+ iso_639_3 | | 10
+ iso_639_5 | | 2
+ jwhois | [] | 20
+ kbd | | 16
+ klavaro | | 29
+ latrine | | 7
+ ld | [] | 15
+ leafpad | [] | 40
+ libc | [] | 24
+ libexif | | 9
+ libextractor | | 5
+ libgnutls | | 13
+ libgpg-error | | 15
+ libgphoto2 | | 9
+ libgphoto2_port | [] | 19
+ libgsasl | | 18
+ libiconv | [] | 29
+ libidn | | 17
+ liferea | | 29
+ lilypond | | 10
+ lordsawar | | 3
+ lprng | | 3
+ lynx | | 19
+ m4 | [] | 22
+ mailfromd | | 4
+ mailutils | | 6
+ make | | 18
+ man-db | | 14
+ man-db-manpages | | 9
+ midi-instruments | [] | 43
+ minicom | [] | 17
+ mkisofs | | 13
+ myserver | | 9
+ nano | [] | 29
+ opcodes | | 11
+ parted | [] | 21
+ pies | | 4
+ popt | [] | 36
+ procps-ng | | 5
+ procps-ng-man | | 4
+ psmisc | [] | 21
+ pspp | | 13
+ pushover | | 6
+ pwdutils | | 8
+ pyspread | | 5
+ radius | | 9
+ recode | | 31
+ recutils | | 9
+ rpm | [] | 13
+ rush | | 10
+ sarg | | 4
+ sed | [] | 34
+ sharutils | | 12
+ shishi | | 6
+ skribilo | | 3
+ solfege | | 19
+ solfege-manual | | 9
+ spotmachine | | 9
+ sudo | | 23
+ sudoers | | 20
+ sysstat | | 21
+ tar | [] | 30
+ texinfo | | 17
+ texinfo_document | | 11
+ tigervnc | | 10
+ tin | [] | 7
+ tin-man | | 1
+ tracgoogleappsa... | [] | 22
+ trader | | 11
+ util-linux | | 12
+ ve | | 14
+ vice | | 1
+ vmm | | 3
+ vorbis-tools | | 13
+ wastesedge | | 2
+ wcd | | 7
+ wcd-man | | 3
+ wdiff | [] | 22
+ wget | | 22
+ wyslij-po | | 14
+ xboard | | 8
+ xdg-user-dirs | [] | 68
+ xkeyboard-config | [] | 27
+ +-------+
+ 90 teams zh_TW
+ 170 domains 44 2805
+
+ Some counters in the preceding matrix are higher than the number of
+visible blocks let us expect. This is because a few extra PO files are
+used for implementing regional variants of languages, or language
+dialects.
+
+ For a PO file in the matrix above to be effective, the package to
+which it applies should also have been internationalized and distributed
+as such by its maintainer. There might be an observable lag between the
+mere existence a PO file and its wide availability in a distribution.
+
+ If Jun 2014 seems to be old, you may fetch a more recent copy of this
+'ABOUT-NLS' file on most GNU archive sites. The most up-to-date matrix
+with full percentage details can be found at
+'http://translationproject.org/extra/matrix.html'.
+
+1.5 Using 'gettext' in new packages
+===================================
+
+If you are writing a freely available program and want to
+internationalize it you are welcome to use GNU 'gettext' in your
+package. Of course you have to respect the GNU Lesser General Public
+License which covers the use of the GNU 'gettext' library. This means
+in particular that even non-free programs can use 'libintl' as a shared
+library, whereas only free software can use 'libintl' as a static
+library or use modified versions of 'libintl'.
+
+ Once the sources are changed appropriately and the setup can handle
+the use of 'gettext' the only thing missing are the translations. The
+Free Translation Project is also available for packages which are not
+developed inside the GNU project. Therefore the information given above
+applies also for every other Free Software Project. Contact 'coordinator@translationproject.org'
+to make the '.pot' files available to the translation teams.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..b7744ea
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,54001 @@
+2019-01-07 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS:
+ The AIX nofiles hard limit fix and bug #867 will make 1.8.27.
+ [a8b4710ff907]
+
+ * plugins/sudoers/auth/pam.c:
+ Use PAM_SILENT to prevent pam_lastlog from printing last login
+ information on RedHat except when explicitly running a shell.
+ Adapted from a patch from Nir Soffer. Bug #867
+ [b8b5d3445a3c]
+
+ * lib/util/aix.c:
+ Fix the default nofiles and stack hard limits. The table of default
+ hard limits in /etc/security/limits was out of date with respect to
+ the current documentation. The default hard limit for nofiles should
+ be unlimited, not 8196. The default hard limit for stack should be
+ 4194304 blocks (which fits in an unsigned long on 32-bit platforms).
+ [68c8c05a0b9b]
+
+2019-01-03 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [3000c62ed0ba]
+
+ * NEWS:
+ Final updates for sudo 1.8.27.
+ [40d6ecb1f739]
+
+ * src/exec_pty.c:
+ Update copyright year
+ [adc9f4046585]
+
+ * doc/LICENSE:
+ Update for 2019
+ [ccbbad25d7c7]
+
+2019-01-02 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * src/exec_pty.c:
+ Fix setting of utmp entry when running command in a pty. Regression
+ introduced in sudo 1.8.22.
+ [cf81f3fa1f3a]
+
+2018-12-24 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/sudoers.c:
+ Use debug_return_int not debug_return_bool in resolve_host
+ [490241e14e68]
+
+ * NEWS, configure, configure.ac:
+ sudo 1.8.27
+ [f59a4a391a44]
+
+ * doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in,
+ plugins/sudoers/visudo.c:
+ Allow the sudoers file to be specified without the -f option. Bug
+ #864
+ [eb3d4c4461ba]
+
+2018-12-20 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ The iolog_dir section is below the maxseq section, not above.
+ [35534e4f23d9]
+
+2018-12-12 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po, po/ja.mo,
+ po/ja.po:
+ Updated translations from translationproject.org
+ [270660da2de4]
+
+2018-12-11 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/sudoreplay.c:
+ Add -n and -R options to help; reported by Radovan Sroka
+ [683df32eb950]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in:
+ Add missing description of padding option and missing argument to
+ -c.
+ [c762020f1694]
+
+ * plugins/sudoers/cvtsudoers.c:
+ The -c option was missing from the help info; from Radovan Sroka
+ [aa36d5c05b0b]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in:
+ Fix some typos; reported by Radovan Sroka
+ [d6137224dd47]
+
+2018-12-08 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/auth/pam.c:
+ In sudo_pam_approval(), for the exempt case, only overwrite pam
+ status when the passwd is expired or needs to be updated.
+ [2c2d1ed1bb7e]
+
+2018-12-07 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/auth/pam.c:
+ The fix for bug #843 was incomplete and caused pam_end() to be
+ called early. sudo_pam_approval() must not set the global pam status
+ to an error value if it returns AUTH_SUCCESS. Otherwise,
+ sudo_pam_cleanup() will call pam_end() before
+ sudo_pam_begin_session(). This resulted in a NULL PAM handle being
+ used in sudo_pam_begin_session().
+ [656aa910fbaf]
+
+2018-12-05 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * src/exec.c:
+ Don't run the command in a pty if no I/O plugins are logging
+ anything. That way an I/O plugin that doesn't actually log anything
+ won't cause the command to be run in a pty.
+ [ef83f35c9cb0]
+
+2018-11-29 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * .hgignore:
+ Update ignore patterns to match doc changes.
+ [7438cdacc0e1]
+
+ * doc/fixmdoc.sed:
+ fix mode fixmdoc.sed
+ [d74c0b7c5932]
+
+2018-11-27 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/Makefile.in, doc/sudo.conf.man.in, doc/sudo.man.in,
+ doc/sudoers.ldap.man.in, doc/sudoers.man.in,
+ doc/sudoers_timestamp.man.in, doc/sudoreplay.man.in,
+ doc/visudo.man.in:
+ Fix section in the .TH line of *.man.in file. The substitution for
+ @mansectsu@ and @mansectform@ was broken. No longer need to strip
+ out OpenBSD from the header line.
+ [cb02c8496b21]
+
+ * doc/sudoers.man.in.sed:
+ Add sudoers.man.in.sed, missed from previous commit.
+ [a2113a52e6a7]
+
+ * doc/CONTRIBUTORS:
+ Add Guillem Jover
+ [db7a39f9726a]
+
+ * NEWS:
+ recent changes
+ [0c07a0cdf2ff]
+
+ * MANIFEST, doc/Makefile.in, doc/fixman.sh, doc/fixmdoc.sed,
+ doc/fixmdoc.sh, doc/sudo.cat, doc/sudo.man.in, doc/sudo.man.in.sed,
+ doc/sudo.mdoc.in, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in:
+ Use roff conditionals in the manuals instead of post-processing. We
+ still need to process the resulting .man.in files to add back the
+ conditionals but this should be easier to debug as the changes are
+ visible in the .in file. Some minor postprocessing is still used to
+ make the manuals HP-UX friendly and to change "0 seconds" ->
+ unlimited after substitution.
+ [44316d271ab8]
+
+2018-11-24 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in:
+ Sudo plugin manual updates and clarification from Guillem Jover:
+ - Add missing return information for show_version().
+ - Fix prototypes for several function pointers.
+ - Update SUDO_API_VERSION_MINOR.
+ - Add missing references to log_suspend() and change_winsize().
+ - Add missing "array.".
+ - Clarify that argc can be zero on sudo -V.
+ - Clarify size requirements for conversation array arguments.
+ - Clarify timeout zero value for struct sudo_conv_message.
+ - Clarify initial and final state of reply in struct sudo_conv_reply.
+ [1241cff4dd51]
+
+ * doc/fixmdoc.sh, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Revert changes to give arguments to the .Bx macro. This is intended
+ for things like .Bx 4.3 to generate "4.3BSD" so the argument ends up
+ before the BSD, not after. Just go back to using "BSD
+ authentication" and "BSD login classes" so fixmdoc.sh can operate
+ correctly. Bug #861
+ [c58965343318]
+
+2018-11-23 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/fixmdoc.sh, doc/sudo.mdoc.in, doc/sudoers.mdoc.in:
+ Update fixmdoc.sh to match the BSD -> .Bx changes in the manuals.
+ Bug #861
+ [7ddfb74781a1]
+
+2018-11-18 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * config.h.in, configure, configure.ac, m4/sudo.m4, src/utmp.c:
+ Add support for utmps as found in HP-UX.
+ [f55312948139]
+
+2018-11-14 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * config.h.in, configure, configure.ac, include/sudo_util.h,
+ lib/util/utimens.c:
+ Support st_nmtime in struct stat as found in HP-UX.
+ [0854b34cd2ea]
+
+ * lib/util/closefrom.c:
+ If fcntl fails, fall back to the /proc implementation.
+ [59a03e0d3148]
+
+2018-11-12 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS:
+ Mention schema.olcSudo
+ [320adcd29a61]
+
+2018-11-09 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ Mention schema.olcSudo here too.
+ [a19dff54603b]
+
+ * MANIFEST, README.LDAP, doc/CONTRIBUTORS, doc/schema.OpenLDAP,
+ doc/schema.olcSudo:
+ OpenLDAP schema file for Sudo in on-line configuration (OLC) format.
+ From Frederic Pasteleurs.
+ [1fcfa9f307a2]
+
+ * po/ast.mo, po/ast.po:
+ Updated translations from translationproject.org
+ [70f0ec8c721c]
+
+2018-11-08 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * lib/util/closefrom.c:
+ Only use closefrom_fallback() if no better method exists. The
+ previous logic was too fragile.
+ [2510928e291f]
+
+2018-11-07 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/hr.mo, plugins/sudoers/po/hr.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/sv.mo, plugins/sudoers/po/sv.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po, po/cs.mo,
+ po/cs.po, po/fr.mo, po/fr.po, po/hr.mo, po/hr.po, po/it.mo,
+ po/it.po, po/nb.mo, po/nb.po, po/pl.mo, po/pl.po, po/pt_BR.mo,
+ po/pt_BR.po, po/sv.mo, po/sv.po, po/tr.mo, po/tr.po, po/uk.mo,
+ po/uk.po, po/vi.mo, po/vi.po, po/zh_CN.mo, po/zh_CN.po:
+ Updated translations from translationproject.org
+ [898154804015]
+
+ * MANIFEST, NEWS, doc/CONTRIBUTORS, plugins/sudoers/po/pt.mo,
+ plugins/sudoers/po/pt.po, po/pt.mo, po/pt.po:
+ Portuguese translation for sudo and sudoers from
+ translationproject.org.
+ [4c49e5cf8936]
+
+2018-11-05 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS, configure, configure.ac, include/sudo_fatal.h,
+ lib/util/Makefile.in, lib/util/fatal.c, lib/util/util.exp.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/logging.c,
+ plugins/sudoers/logging.h, plugins/sudoers/sudoers.c:
+ Add sudo_gai_fatal, sudo_gai_vfatal, sudo_gai_vwarn, sudo_gai_warn
+ and gai_log_warning that use gai_strerror() instead of strerror().
+ [9c37c5db3293]
+
+2018-10-31 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/match.c:
+ Fix memory leak in runaslist_matches().
+ [f1366ad50eb3]
+
+2018-10-29 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS:
+ typo
+ [fc8aa243672a]
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [f333405eb06c]
+
+ * NEWS:
+ More updates for 1.8.26
+ [1941961b232f]
+
+2018-10-28 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * MANIFEST, doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, plugins/sudoers/ldap_util.c,
+ plugins/sudoers/regress/cvtsudoers/test33.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test33.sh:
+ Add support for negated sudoRunAsUser and sudoRunAsGroup entries.
+ [d0368336d92b]
+
+2018-10-27 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document that the target user's groups may be specified via the -g
+ option.
+ [67b7643e3bcb]
+
+ * plugins/sudoers/tsgetgrpw.c:
+ Include getpwent() version of sudo_getgrouplist2_v1() from
+ getgrouplist.c
+ [60aa493504d1]
+
+ * MANIFEST, plugins/sudoers/regress/testsudoers/group,
+ plugins/sudoers/regress/testsudoers/test1.sh:
+ Use a testsudoers group file with known contents instead of the
+ system one.
+ [7a4499c92acd]
+
+ * plugins/sudoers/match.c, plugins/sudoers/parse.h,
+ plugins/sudoers/set_perms.c:
+ Allow the group set by "sudo -g" to be any of the target user's
+ groups. Previously, this was only allowed if the group matched the
+ target user's primary group ID (from the passwd database entry). The
+ sudoers policy will now allow the group if it is one of the target
+ user's supplemental groups as well.
+ [c43fedc19a01]
+
+2018-10-26 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * lib/util/regress/getgrouplist/getgrouplist_test.c:
+ Skip sudo_getgrouplist2() check on systems with getgrouplist_2().
+ sudo_getgrouplist2() is just a wrapper on such systems and this
+ avoids a test failure on macOS where a user is automatically a
+ member of certain groups.
+ [26ba0c363b80]
+
+ * lib/util/util.exp.in:
+ Add missing exported symbol sudo_term_eof
+ [2d8e0438eba4]
+
+ * plugins/sudoers/ldap_conf.c:
+ Add missing #ifdef LDAP_OPT_X_TLS_REQUIRE_CERT Fixes problems
+ building on older LDAP sdks.
+ [1effb0f19867]
+
+ * MANIFEST:
+ add getgrouplist_test.c
+ [ca5bae341846]
+
+ * lib/util/regress/getgrouplist/getgrouplist_test.c:
+ Check the user's primary gid from the passwd file too.
+ [60ba98074d75]
+
+ * .hgignore:
+ ignore prologue
+ [589222ec2717]
+
+ * lib/util/aix.c, lib/util/arc4random.c,
+ lib/util/arc4random_uniform.c, lib/util/closefrom.c,
+ lib/util/digest.c, lib/util/digest_gcrypt.c,
+ lib/util/digest_openssl.c, lib/util/event.c, lib/util/event_poll.c,
+ lib/util/event_select.c, lib/util/fatal.c, lib/util/fnmatch.c,
+ lib/util/getentropy.c, lib/util/getgrouplist.c,
+ lib/util/gethostname.c, lib/util/getline.c, lib/util/getopt_long.c,
+ lib/util/gettime.c, lib/util/gidlist.c, lib/util/isblank.c,
+ lib/util/key_val.c, lib/util/lbuf.c, lib/util/locking.c,
+ lib/util/memrchr.c, lib/util/memset_s.c, lib/util/mksiglist.c,
+ lib/util/mksigname.c, lib/util/mktemp.c, lib/util/nanosleep.c,
+ lib/util/parseln.c, lib/util/pipe2.c, lib/util/progname.c,
+ lib/util/pw_dup.c, lib/util/reallocarray.c,
+ lib/util/regress/atofoo/atofoo_test.c,
+ lib/util/regress/getgrouplist/getgrouplist_test.c,
+ lib/util/regress/parse_gids/parse_gids_test.c,
+ lib/util/regress/progname/progname_test.c,
+ lib/util/regress/strsplit/strsplit_test.c,
+ lib/util/regress/sudo_conf/conf_test.c,
+ lib/util/regress/sudo_parseln/parseln_test.c,
+ lib/util/regress/tailq/hltq_test.c,
+ lib/util/regress/vsyslog/vsyslog_test.c, lib/util/secure_path.c,
+ lib/util/setgroups.c, lib/util/sha2.c, lib/util/sig2str.c,
+ lib/util/strlcat.c, lib/util/strlcpy.c, lib/util/strndup.c,
+ lib/util/strnlen.c, lib/util/strsignal.c, lib/util/strsplit.c,
+ lib/util/strtobool.c, lib/util/strtoid.c, lib/util/strtomode.c,
+ lib/util/strtonum.c, lib/util/sudo_conf.c, lib/util/sudo_debug.c,
+ lib/util/sudo_dso.c, lib/util/term.c, lib/util/ttyname_dev.c,
+ lib/util/ttysize.c, lib/util/utimens.c, lib/util/vsyslog.c,
+ plugins/group_file/getgrent.c, plugins/group_file/group_file.c,
+ plugins/group_file/plugin_test.c, plugins/sample/sample_plugin.c,
+ plugins/sudoers/Makefile.in, plugins/sudoers/alias.c,
+ plugins/sudoers/audit.c, plugins/sudoers/auth/afs.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/dce.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/base64.c, plugins/sudoers/boottime.c,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/check.c,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers_json.c,
+ plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/cvtsudoers_pwutil.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/digestname.c, plugins/sudoers/editor.c,
+ plugins/sudoers/env.c, plugins/sudoers/env_pattern.c,
+ plugins/sudoers/file.c, plugins/sudoers/filedigest.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/fmtsudoers.c,
+ plugins/sudoers/gc.c, plugins/sudoers/gentime.c,
+ plugins/sudoers/getdate.c, plugins/sudoers/getspwuid.c,
+ plugins/sudoers/gmtoff.c, plugins/sudoers/goodpath.c,
+ plugins/sudoers/gram.c, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/hexchar.c, plugins/sudoers/interfaces.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/iolog_util.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/ldap_conf.c, plugins/sudoers/ldap_util.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/locale.c,
+ plugins/sudoers/logging.c, plugins/sudoers/logwrap.c,
+ plugins/sudoers/match.c, plugins/sudoers/match_addr.c,
+ plugins/sudoers/mkdir_parents.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse_ldif.c, plugins/sudoers/policy.c,
+ plugins/sudoers/prompt.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/pwutil_impl.c, plugins/sudoers/rcstr.c,
+ plugins/sudoers/redblack.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/env_match/check_env_pattern.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c,
+ plugins/sudoers/regress/iolog_util/check_iolog_util.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/regress/parser/check_base64.c,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/regress/parser/check_gentime.c,
+ plugins/sudoers/regress/parser/check_hexchar.c,
+ plugins/sudoers/regress/starttime/check_starttime.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/solaris_audit.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/starttime.c,
+ plugins/sudoers/strlist.c, plugins/sudoers/stubs.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudo_printf.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers_debug.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/timeout.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/timestr.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke_util.c, plugins/sudoers/tsdump.c,
+ plugins/sudoers/tsgetgrpw.c, plugins/sudoers/visudo.c,
+ plugins/system_group/system_group.c, src/conversation.c,
+ src/env_hooks.c, src/exec.c, src/exec_common.c, src/exec_monitor.c,
+ src/exec_nopty.c, src/exec_pty.c, src/get_pty.c, src/hooks.c,
+ src/load_plugins.c, src/net_ifs.c, src/openbsd.c, src/parse_args.c,
+ src/preload.c, src/preserve_fds.c,
+ src/regress/noexec/check_noexec.c,
+ src/regress/ttyname/check_ttyname.c, src/selinux.c, src/sesh.c,
+ src/signal.c, src/solaris.c, src/sudo.c, src/sudo_edit.c,
+ src/sudo_noexec.c, src/tcsetpgrp_nobg.c, src/tgetpass.c,
+ src/ttyname.c, src/utmp.c:
+ Convert PVS-Studio comment to ANSI C.
+ [31f2aefe6d9b]
+
+ * Makefile.in, doc/Makefile.in, doc/cvtsudoers.man.in,
+ doc/cvtsudoers.mdoc.in, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in,
+ doc/sudo.man.in, doc/sudo.mdoc.in, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ doc/sudoers_timestamp.man.in, doc/sudoers_timestamp.mdoc.in,
+ doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in, doc/visudo.man.in,
+ doc/visudo.mdoc.in, examples/Makefile.in, include/Makefile.in,
+ include/sudo_lbuf.h, lib/util/Makefile.in, lib/util/digest.c,
+ lib/util/digest_gcrypt.c, lib/util/digest_openssl.c,
+ lib/util/lbuf.c, lib/util/setgroups.c, lib/util/ttysize.c,
+ lib/zlib/Makefile.in, plugins/group_file/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/sudoers/alias.c, plugins/sudoers/auth/dce.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/base64.c,
+ plugins/sudoers/file.c, plugins/sudoers/filedigest.c,
+ plugins/sudoers/gentime.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/match.c,
+ plugins/sudoers/match_addr.c, plugins/sudoers/parse.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/timeout.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, plugins/sudoers/tsdump.c,
+ plugins/system_group/Makefile.in, src/Makefile.in, src/sesh.c,
+ src/sudo_usage.h.in:
+ Fix some mangled text in the license block.
+ [86b88fbda4b4]
+
+ * lib/util/Makefile.in,
+ lib/util/regress/getgrouplist/getgrouplist_test.c,
+ lib/util/regress/parse_gids/parse_gids_test.c:
+ Add regress test for sudo_getgrouplist2(). This test assumes all the
+ groups in root's group list can be resolved by group ID.
+ [48564f85b7ed]
+
+2018-10-25 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS:
+ More changes in 1.8.26
+ [fe81e3e4b653]
+
+ * MANIFEST, doc/cvtsudoers.cat, doc/cvtsudoers.man.in,
+ doc/cvtsudoers.mdoc.in, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/cvtsudoers.h, plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/regress/cvtsudoers/test31.conf,
+ plugins/sudoers/regress/cvtsudoers/test31.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test31.sh,
+ plugins/sudoers/regress/cvtsudoers/test32.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test32.sh:
+ Add padding option to cvtsudoers. Bug #856
+ [6e31b0e37ba1]
+
+ * lib/util/getgrouplist.c:
+ Remove an errant grset++ in the AIX version of sudo_getgrouplist2().
+ Bug #857
+ [03b19227cab2]
+
+2018-10-22 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * lib/util/Makefile.in, plugins/group_file/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in, src/Makefile.in:
+ Pass --sourcetree-root to pvs-studio and don't check sudo_noexec.c.
+ Since we don't auto-generate dependencies for sudo_noexec.c we can't
+ easily check it from outside the source tree. This is not a problem
+ as it just contains stub functions.
+ [3cf842d30e45]
+
+ * MANIFEST, doc/CONTRIBUTORS, po/ast.mo, po/ast.po:
+ Asturian translation for sudo from translationproject.org
+ [dc0b31fa013c]
+
+2018-10-21 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * lib/util/gettime.c:
+ Add support for CLOCK_MONOTONIC_RAW and CLOCK_UPTIME_RAW, present on
+ macOS.
+ [5f34c8de0707]
+
+ * INSTALL, configure, configure.ac:
+ Add --enable-pvs-studio configure option to create PVS-Studio.cfg.
+ [772e86227c11]
+
+ * .hgignore, Makefile.in, doc/Makefile.in, examples/Makefile.in,
+ include/Makefile.in, lib/util/Makefile.in, lib/zlib/Makefile.in,
+ mkdep.pl, plugins/group_file/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in, src/Makefile.in:
+ Add pvs-studio target and associated production rules.
+ [3dbcef5ac205]
+
+ * lib/util/aix.c, lib/util/arc4random.c,
+ lib/util/arc4random_uniform.c, lib/util/closefrom.c,
+ lib/util/digest.c, lib/util/digest_gcrypt.c,
+ lib/util/digest_openssl.c, lib/util/event.c, lib/util/event_poll.c,
+ lib/util/event_select.c, lib/util/fatal.c, lib/util/fnmatch.c,
+ lib/util/getentropy.c, lib/util/getgrouplist.c,
+ lib/util/gethostname.c, lib/util/getline.c, lib/util/getopt_long.c,
+ lib/util/gettime.c, lib/util/gidlist.c, lib/util/isblank.c,
+ lib/util/key_val.c, lib/util/lbuf.c, lib/util/locking.c,
+ lib/util/memrchr.c, lib/util/memset_s.c, lib/util/mksiglist.c,
+ lib/util/mksigname.c, lib/util/mktemp.c, lib/util/nanosleep.c,
+ lib/util/parseln.c, lib/util/pipe2.c, lib/util/progname.c,
+ lib/util/pw_dup.c, lib/util/reallocarray.c,
+ lib/util/regress/atofoo/atofoo_test.c,
+ lib/util/regress/parse_gids/parse_gids_test.c,
+ lib/util/regress/progname/progname_test.c,
+ lib/util/regress/strsplit/strsplit_test.c,
+ lib/util/regress/sudo_conf/conf_test.c,
+ lib/util/regress/sudo_parseln/parseln_test.c,
+ lib/util/regress/tailq/hltq_test.c,
+ lib/util/regress/vsyslog/vsyslog_test.c, lib/util/secure_path.c,
+ lib/util/setgroups.c, lib/util/sha2.c, lib/util/sig2str.c,
+ lib/util/strlcat.c, lib/util/strlcpy.c, lib/util/strndup.c,
+ lib/util/strnlen.c, lib/util/strsignal.c, lib/util/strsplit.c,
+ lib/util/strtobool.c, lib/util/strtoid.c, lib/util/strtomode.c,
+ lib/util/strtonum.c, lib/util/sudo_conf.c, lib/util/sudo_debug.c,
+ lib/util/sudo_dso.c, lib/util/term.c, lib/util/ttyname_dev.c,
+ lib/util/ttysize.c, lib/util/utimens.c, lib/util/vsyslog.c,
+ plugins/group_file/getgrent.c, plugins/group_file/group_file.c,
+ plugins/group_file/plugin_test.c, plugins/sample/sample_plugin.c,
+ plugins/sudoers/alias.c, plugins/sudoers/audit.c,
+ plugins/sudoers/auth/afs.c, plugins/sudoers/auth/aix_auth.c,
+ plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/dce.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/passwd.c,
+ plugins/sudoers/auth/rfc1938.c, plugins/sudoers/auth/secureware.c,
+ plugins/sudoers/auth/securid5.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/base64.c,
+ plugins/sudoers/boottime.c, plugins/sudoers/bsm_audit.c,
+ plugins/sudoers/check.c, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/cvtsudoers_json.c,
+ plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/cvtsudoers_pwutil.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/digestname.c, plugins/sudoers/editor.c,
+ plugins/sudoers/env.c, plugins/sudoers/env_pattern.c,
+ plugins/sudoers/file.c, plugins/sudoers/filedigest.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/fmtsudoers.c,
+ plugins/sudoers/gc.c, plugins/sudoers/gentime.c,
+ plugins/sudoers/getdate.c, plugins/sudoers/getspwuid.c,
+ plugins/sudoers/gmtoff.c, plugins/sudoers/goodpath.c,
+ plugins/sudoers/gram.c, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/hexchar.c, plugins/sudoers/interfaces.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/iolog_util.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/ldap_conf.c, plugins/sudoers/ldap_util.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/locale.c,
+ plugins/sudoers/logging.c, plugins/sudoers/logwrap.c,
+ plugins/sudoers/match.c, plugins/sudoers/match_addr.c,
+ plugins/sudoers/mkdir_parents.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse_ldif.c, plugins/sudoers/policy.c,
+ plugins/sudoers/prompt.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/pwutil_impl.c, plugins/sudoers/rcstr.c,
+ plugins/sudoers/redblack.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/env_match/check_env_pattern.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c,
+ plugins/sudoers/regress/iolog_util/check_iolog_util.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/regress/parser/check_base64.c,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/regress/parser/check_gentime.c,
+ plugins/sudoers/regress/parser/check_hexchar.c,
+ plugins/sudoers/regress/starttime/check_starttime.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/solaris_audit.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/starttime.c,
+ plugins/sudoers/strlist.c, plugins/sudoers/stubs.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudo_printf.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers_debug.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/timeout.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/timestr.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke_util.c, plugins/sudoers/tsdump.c,
+ plugins/sudoers/tsgetgrpw.c, plugins/sudoers/visudo.c,
+ plugins/system_group/system_group.c, src/conversation.c,
+ src/env_hooks.c, src/exec.c, src/exec_common.c, src/exec_monitor.c,
+ src/exec_nopty.c, src/exec_pty.c, src/get_pty.c, src/hooks.c,
+ src/load_plugins.c, src/net_ifs.c, src/openbsd.c, src/parse_args.c,
+ src/preload.c, src/preserve_fds.c,
+ src/regress/noexec/check_noexec.c,
+ src/regress/ttyname/check_ttyname.c, src/selinux.c, src/sesh.c,
+ src/signal.c, src/solaris.c, src/sudo.c, src/sudo_edit.c,
+ src/sudo_noexec.c, src/tcsetpgrp_nobg.c, src/tgetpass.c,
+ src/ttyname.c, src/utmp.c:
+ Add comments in .c files so PVS-Studio will check them.
+ [b42b6dcb48a6]
+
+2018-10-20 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/iolog_util.c:
+ Simplify range checks. No need to check for ERANGE in the cases
+ where we also check that the value is <= INT_MAX. Found by PVS-
+ Studio.
+ [45810a8437b6]
+
+2018-10-19 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * lib/util/key_val.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/toke_util.c,
+ src/preserve_fds.c:
+ Avoid some PVS-Studio false positives.
+ [e4d8ce94fda7]
+
+ * src/sudo.c:
+ Remove some calls to sudo_fatalx(); just propagate the error return.
+ [bc9eefbf0cdf]
+
+ * src/sesh.c:
+ No need to check if fd_dst is -1 in sudoedit mode. Failure to open
+ the destination sudoedit file is fatal so there's no need to check
+ that fd_dst != -1 later on. Found by PVS-Studio.
+ [5530586ace16]
+
+ * plugins/sudoers/timestamp.c:
+ In timestamp_open() no need to free cookie on error, it is NULL.
+ Found by PVS-Studio.
+ [becfe97c72f8]
+
+2018-10-18 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/ldap_util.c:
+ Fix a memory leak on malloc() error in sudo_ldap_role_to_priv().
+ Coverity CID 188804
+ [1bea56670410]
+
+ * plugins/sudoers/parse_ldif.c:
+ Move the allocation of role to be immediately before in_role is set.
+ This makes it clear that when in_role == true, role is non-NULL.
+ Also remove two dead stores.
+ [790d90c578c8]
+
+ * plugins/sudoers/parse_ldif.c:
+ Fix trimming of non-escaped trailing space in
+ ldif_parse_attribute(). Found by PVS-Studio.
+ [37fded3c77a4]
+
+ * plugins/sudoers/match.c:
+ Simplify the logic surrounding sudoers_args in command_args_match().
+ We only need to check that sudoers_args is non-NULL once. Found by
+ PVS-Studio.
+ [93c967145e82]
+
+ * plugins/sudoers/ldap.c:
+ If sudo_ldap_get_values_len() fails goto cleanup instead of oom.
+ This is not strictly necessary as there's not anything to cleanup in
+ this case but it is more consistent with the code that follows.
+ [d0d8b8b8dca8]
+
+ * plugins/sudoers/policy.c:
+ Fix handling of timeout values in sudoers. When passing the timeout
+ back to the front end, ignore the user-specified timeout if it is
+ not set (initialized to 0). Otherwise, sudo would choose a zero
+ user-specified timeout over the sudoers-specified timeout (non-
+ zero).
+ [6b08b3b918b7]
+
+2018-10-17 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers_pwutil.c:
+ Fix cut & pastos in cvtsudoers_make_gritem()
+ [bd901c0394ba]
+
+ * plugins/sudoers/regress/sudoers/test17.ldif2sudo.ok:
+ Fix expected test output now that command_timeout is parsed
+ correctly in LDIF.
+ [ba6cfd26330e]
+
+ * lib/util/event.c, lib/util/event_poll.c, lib/util/event_select.c:
+ tv_nsec can never be negative after timespecsub. Found by PVS Studio
+ [ecfb93c9463c]
+
+2018-10-16 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/sudoers.c:
+ Avoid potentially undefined behavior. Found by PVS Studio.
+ [ae76c69e0d6f]
+
+ * plugins/sudoers/ldap_util.c:
+ sudo_ldap_parse_option() never returns '=' as the operator. When
+ parsing command_timeout, role, type, privs and limitprivs, check
+ that val is non-NULL instead. Found by PVS Studio.
+ [10f8cff7cce7]
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/toke.c:
+ Fix up #line entries that reference lex.sudoers.c.
+ [c724cef37b66]
+
+2018-10-13 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/iolog.h, plugins/sudoers/iolog_util.c:
+ Fix workaround for broken sudo 1.8.7 timing files.
+ [78ef3625c650]
+
+ * plugins/sudoers/parse_ldif.c:
+ Fix memory leak when reusing the runas list. We need to free the
+ member list itself as well as its contents.
+ [62fb86a5c83f]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Some DIAGNOSTICS updates: Update error message for when the user's
+ uid does not exist in passwd. Remove "This error indicates" and some
+ other cosmetic cleanups.
+ [c73841e03014]
+
+ * src/sudo.c:
+ If the user's passwd entry cannot be resolved via the uid, use the
+ same error message as visudo.
+ [ce596b32dfbb]
+
+2018-10-12 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Add a DIAGNOSTICS section with an explanation of the more non-
+ trivial error messages.
+ [775419794f7d]
+
+ * plugins/sudoers/sudoreplay.c, src/exec_monitor.c, src/exec_nopty.c,
+ src/exec_pty.c:
+ Replace sudo_fatal(NULL) with an "unable to allocate memory" message
+ that includes the function name.
+ [26e19bcc0ce8]
+
+2018-10-09 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in, src/tgetpass.c:
+ Make EOF handling while reading the password prompt more like
+ getpass(3). We now return the password as long as at least one
+ character has been read. Previously, EOF at the password prompt was
+ treated as if nothing was entered.
+ [fc2ed4a87e6f]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in:
+ regen
+ [2aee8680abc3]
+
+ * src/tgetpass.c:
+ Print a warning for password read issues. Issues include: timeout at
+ the password prompt, read error while reading the password, and EOF
+ reading the password.
+ [df1dcebe9ffa]
+
+2018-10-08 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * lib/util/term.c, src/tgetpass.c:
+ Handle EOF on password input when pwfedback is enabled.
+ [4958978fc967]
+
+2018-10-07 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudoers.ldap.mdoc.in:
+ Fix remaining instances of "e.g." without a trailing ','.
+ [8cbf11c04b3c]
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.man.in, doc/sudo_plugin.mdoc.in, doc/sudoers.cat,
+ doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ doc/sudoers_timestamp.cat, doc/sudoers_timestamp.man.in,
+ doc/sudoers_timestamp.mdoc.in:
+ Use mdoc macros for BSD systems. All manuals now pass "make lint"
+ [7f23209a5e1c]
+
+ * doc/Makefile.in:
+ Use -Wstyle with -Tlint since sudo is not part of the base system.
+ This avoids "referenced manual not found" and "operating system
+ explicitly specified" warnings.
+ [e417e972a88a]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in:
+ Document log_suspend() and fix the description of the
+ change_winsize() return value.
+ [be02b0fb26a9]
+
+2018-10-06 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in, doc/sudoers_timestamp.cat,
+ doc/sudoers_timestamp.man.in, doc/sudoers_timestamp.mdoc.in,
+ doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in,
+ doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in:
+ Fix problems found by igor. Bug #854
+ [4ddcb625f3b7]
+
+ * doc/Makefile.in:
+ Sort DOCS and DEVDOCS and remove extra sudoers entry (it was listed
+ twice).
+ [abb2baac9373]
+
+ * doc/Makefile.in:
+ Add igor target to run igor(1) on the manuals.
+ [64be7fb868b3]
+
+2018-10-05 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in,
+ plugins/sudoers/sudoreplay.c:
+ Add new -S option to sleep while the command was suspended. The
+ default behavior is now to not consider the time the command was
+ suspended as part of the normal inter-event delay.
+ [bb30f7b28126]
+
+ * MANIFEST, include/sudo_plugin.h, plugins/sudoers/Makefile.in,
+ plugins/sudoers/iolog.c, plugins/sudoers/iolog.h,
+ plugins/sudoers/iolog_event.h, plugins/sudoers/iolog_files.h,
+ plugins/sudoers/iolog_util.c, plugins/sudoers/iolog_util.h,
+ plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c,
+ plugins/sudoers/regress/iolog_util/check_iolog_util.c,
+ plugins/sudoers/sudoreplay.c, src/exec_pty.c:
+ Add a suspend event type to the I/O log to log suspend/resume of the
+ command so we can skip that delay during replay.
+ [8091d1835a31]
+
+ * src/exec_pty.c, src/sudo.c, src/sudo.h:
+ Initialize the pty rows/cols based on the values we stored in
+ user_details. This fixes a minor issue where we would send an extra
+ window size change event the first time the command was suspended.
+ [b2ae9be4d1d6]
+
+2018-09-27 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, plugins/sudoers/ldap_conf.c,
+ plugins/sudoers/sudo_ldap_conf.h:
+ Add support for OpenLDAP's TLS_REQCERT setting in ldap.conf.
+ [f07a14ae05cb]
+
+2018-09-24 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * include/sudo_util.h, plugins/sudoers/defaults.c,
+ plugins/sudoers/iolog_util.c,
+ plugins/sudoers/regress/starttime/check_starttime.c:
+ Move definition of TIME_T_MAX to sudo_util.h
+ [469c36d44950]
+
+ * NEWS, doc/UPGRADE:
+ Changes in 1.8.26 (so far).
+ [5c73b0d8c676]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/env.c:
+ Treat LOGIN, LOGNAME and USER specially. If one is preserved or
+ deleted we want to preserve or delete all of them.
+ [ea1782686195]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, plugins/sudoers/env.c,
+ plugins/sudoers/logging.c, plugins/sudoers/regress/visudo/test6.sh:
+ Remove special handling of the USERNAME environment variable. It
+ used to be set on old versions of Fedora but that hasn't been the
+ case for some time. It's worth noting that ssh doesn't set USERNAME
+ either.
+ [5141bebd99c4]
+
+ * configure, configure.ac:
+ sudo 1.8.26
+ [cfe8d540328e]
+
+2018-09-22 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * src/sudo.c:
+ Remove unused system_maxgroups argument from fill_group_list().
+ [debc4ca9d35f]
+
+ * lib/util/getgrouplist.c:
+ Pass getgrouplist() NGROUPS_MAX+1, not NGROUPS_MAX so we have room
+ for the primary gid.
+ [fccf07f2e8cf]
+
+2018-09-20 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers_json.c:
+ In print_member_json_int() eliminate the need_newline variable and
+ just move the non-alias expansion printing bits into the else
+ clause, including the newline and comma printing.
+ [b40224fc6090]
+
+ * MANIFEST, plugins/sudoers/regress/cvtsudoers/test30.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test30.sh:
+ Add regress test for bug #853
+ [31544afc6013]
+
+ * plugins/sudoers/cvtsudoers_json.c:
+ When expanding an alias in print_member_json_int() avoid printing an
+ extra comma at the end of the entry. Bug #853.
+ [e73e09f8569a]
+
+2018-09-12 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/CONTRIBUTORS:
+ Add Kan Sasaki
+ [ff277fb5b0c9]
+
+ * NEWS, configure, configure.ac:
+ sudo 1.8.25p1
+ [c4f0a69e6356]
+
+ * lib/util/event_poll.c:
+ Fix a crash in the event system's poll() backend introduced with
+ support for nanosecond timers. Only affects systems without ppoll().
+ Bug #851
+ [54e561b11a0f]
+
+2018-09-02 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [04afa00445ef]
+
+2018-08-31 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c:
+ Allow for some clock drift due to ntpd, etc.
+ [2d72989fe7b1]
+
+ * plugins/sudoers/visudo.c:
+ If sudo_lock_file() fails for a reason other than the file already
+ being locked, give the user a chance to edit anyway.
+ [e5a963ecc083]
+
+2018-08-30 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/regress/cvtsudoers/test28.sh:
+ Quick sort is not a stable sort; use distinct sudoOrder values so
+ the output is predictable.
+ [46ebc1169c0c]
+
+ * lib/util/regress/atofoo/atofoo_test.c,
+ lib/util/regress/parse_gids/parse_gids_test.c,
+ plugins/sudoers/ldap.c,
+ plugins/sudoers/regress/parser/check_base64.c:
+ Fix warnings on OpenIndiana (Illumos)
+ [1b45d303b338]
+
+ * plugins/sudoers/ldap.c:
+ Correct ldap_to_sudoers() return value.
+ [16b0d144b196]
+
+ * NEWS:
+ Bug #849
+ [3e05bad00a44]
+
+ * plugins/sudoers/sssd.c:
+ The sssd backend used to take the first match, assuming that entries
+ were sorted in descending order by sudoOrder. That allowed it to
+ avoid iterating over the entire list of rules. Now that we convert
+ to a sudoers parse tree, we need to convert rules in ascending
+ order, not descending. The simplest way to accomplish this is to
+ simply iterate over the rules from last to first, reversing the sort
+ order. Bug #849
+ [63627909bb10]
+
+ * MANIFEST, plugins/sudoers/regress/cvtsudoers/test28.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test28.sh,
+ plugins/sudoers/regress/cvtsudoers/test29.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test29.sh:
+ Add some more ldif -> sudoers tests to verify sudoOrder.
+ [f41358fbd066]
+
+ * plugins/sudoers/ldap.c:
+ For conversion to a sudoers parse tree, ldap_entry_compare() now
+ needs to sort in ascending order, not descending. Bug #849
+ [9f23126cded8]
+
+2018-08-29 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers.c:
+ No need to set input_file for stdin in parse_ldif(); noted by clang
+ analyzer.
+ [c852e1c92dd2]
+
+ * plugins/sudoers/iolog_util.c:
+ Use TIME_T_MAX when parsing the I/O log file timestamp and disallow
+ negative times.
+ [bfb17118e584]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/iolog_util.c,
+ plugins/sudoers/iolog_util.h,
+ plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c,
+ plugins/sudoers/regress/iolog_util/check_iolog_util.c,
+ plugins/sudoers/sudoreplay.c:
+ When parsing an I/O log timing line, store the result in a timespec,
+ not a double. The speed factor (for scaling the delay) in sudoreplay
+ is still a double but we only need to adjust the delay if the factor
+ is something other than 1.0.
+ [39077129d1f9]
+
+ * plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c:
+ Fix memory leak in test.
+ [94fb9f39dfee]
+
+ * doc/cvtsudoers.cat, doc/sudo.cat, doc/sudo.conf.cat,
+ doc/sudo_plugin.cat, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers_timestamp.cat, doc/sudoreplay.cat, doc/visudo.cat:
+ regen
+ [f2850c2f733a]
+
+2018-08-28 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/env.c:
+ Update conversion of DID_* to KEPT_* to match the new values of
+ DID_* and KEPT_*.
+ [6ce1bc30a4d1]
+
+ * NEWS, plugins/sudoers/env.c:
+ Set the LOGIN environment variable on AIX like we do LOGNAME.
+ [e6afb82d918c]
+
+2018-08-27 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * config.h.in, configure, configure.ac, m4/sudo.m4,
+ plugins/sudoers/bsm_audit.c:
+ Add a test for the 4-argument au_close() function found in Solaris
+ 11 instead of assuming it is present if __sun is defined. Fixes a
+ compilation error on OpenIndiana and older Solaris versions.
+ [4a4f91e28bbc]
+
+ * doc/CONTRIBUTORS:
+ Add Miguel Sanders and Scott Cheloha
+ [14aca7309a0a]
+
+ * NEWS:
+ testsudoers changes
+ [f008d473c933]
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/testsudoers.c:
+ Add ldif support to testsudoers
+ [321f11b7badd]
+
+2018-08-26 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/cvtsudoers.h, plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/parse.h, plugins/sudoers/parse_ldif.c:
+ Move ldif -> sudoers conversion code into parse_ldif.c
+ [497d55799d5b]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/cvtsudoers.h, plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/cvtsudoers_pwutil.c, plugins/sudoers/strlist.c,
+ plugins/sudoers/strlist.h:
+ Move string list functions to their own file.
+ [a15902cde4eb]
+
+ * lib/util/Makefile.in:
+ sync
+ [9b1f98d4335f]
+
+2018-08-25 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * include/sudo_event.h, lib/util/event.c, lib/util/util.exp.in:
+ Backward ABI compatibility for even functions that use a timeval.
+ [01d9e617a923]
+
+ * lib/util/event.c, lib/util/event_poll.c, lib/util/event_select.c:
+ Use a monotonic timer for the event subsystem.
+ [acf30905a275]
+
+ * config.h.in, configure, configure.ac, include/sudo_event.h,
+ lib/util/event.c, lib/util/event_poll.c, lib/util/event_select.c,
+ plugins/sudoers/iolog_util.h, plugins/sudoers/sudoers.h,
+ plugins/sudoers/sudoreplay.c:
+ Use struct timespec, not struct timeval in the event subsystem. Use
+ ppoll() or pselect() if avaialble which use timespec.
+ [b1bfccec8b13]
+
+2018-08-24 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * .hgignore:
+ sync
+ [193fd33e9864]
+
+ * plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers.h,
+ plugins/sudoers/cvtsudoers_json.c,
+ plugins/sudoers/cvtsudoers_ldif.c:
+ Eliminate most use of parsed_sudoers in cvtsudoers
+ [0d0504f61e3e]
+
+ * plugins/sudoers/alias.c, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/cvtsudoers_json.c, plugins/sudoers/parse.h,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ Make alias_apply() take 3 arguments, the first being a pointer to
+ the struct sudoers_parse_tree.
+ [7802295c07fa]
+
+2018-08-23 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c:
+ Handle systems where root's gid is not 0.
+ [1fc92bad715a]
+
+ * plugins/sudoers/iolog_util.c, plugins/sudoers/iolog_util.h:
+ Add missing files from last commit.
+ [a155e07bb191]
+
+ * .hgignore, MANIFEST, plugins/sudoers/Makefile.in,
+ plugins/sudoers/po/sudoers.pot,
+ plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c,
+ plugins/sudoers/sudoreplay.c:
+ Add regress test for I/O log plugin endpoints
+ [bf9fbe5ff2a6]
+
+ * plugins/sudoers/iolog.c:
+ We cannot reuse last_time for the I/O log info file now that it is a
+ monotonic timer. Just call time(3) in write_info_log() directly.
+ [f2e1de732a91]
+
+ * src/exec_pty.c:
+ Move the loop to free the monitor_messages list into
+ free_exec_closure_pty()
+ [d6edc1a94e7e]
+
+ * po/sudo.pot:
+ regen
+ [6467f05a2fd0]
+
+2018-08-22 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * lib/util/getentropy.c:
+ Fix typo in last commit.
+ [38f3450b57fb]
+
+ * config.h.in, configure, configure.ac, lib/util/getentropy.c:
+ Do not assume all Linux has linux/random.h. Add missing
+ sys/syscall.h include
+ [8460f258e1af]
+
+ * plugins/sudoers/policy.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/visudo.c, src/sudo_edit.c:
+ Cast uid/gid to unsigned int before printing.
+ [37fcab8b4f97]
+
+ * include/sudo_compat.h:
+ Only include stdarg.h if we need it.
+ [c266d34454ba]
+
+ * plugins/sudoers/cvtsudoers_pwutil.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/pwutil_impl.c,
+ plugins/sudoers/rcstr.c, plugins/sudoers/timestamp.c,
+ src/sudo_noexec.c:
+ Include stddef.h for offsetof() definition.
+ [15d13ae1ba46]
+
+ * plugins/sudoers/bsm_audit.c, plugins/sudoers/timestamp.c:
+ fix compiler warnings on Solaris 11
+ [6c92c438a38e]
+
+ * lib/util/getentropy.c:
+ Fix setting of errno when gotdata() fails.
+ [4fab71fa575f]
+
+ * NEWS:
+ Bugs 846 and 847
+ [a0ba7ad24812]
+
+ * include/sudo_compat.h:
+ We still need to include string.h for AIX (and possibly others) when
+ we are not using the system memset_r() function and rsize_t is
+ defined by the system headers.
+ [e1f8f7537209]
+
+ * configure, configure.ac, include/sudo_compat.h, mkpkg:
+ Add --enable-package-build to give configure a hint that we are
+ building a package. This can be used to avoid relying on libc
+ functions that may not be present in all libc versions for a
+ particular system. For instance, AIX 7.1 may or may not have
+ memset_s() and getline() present.
+ [7e843bed8435]
+
+ * include/sudo_compat.h:
+ AIX defines rsize_t in string.h, not stddef.h for use by the
+ memset_s() prototype. We use our own memset_s() on AIX since it is
+ not available on all BOS levels which makes package building
+ problematic.
+ [3724b47eadd8]
+
+2018-08-21 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/defaults.c:
+ Fix printing of T_TIMESPEC values.
+ [8775c17229a4]
+
+ * plugins/sudoers/iolog.c:
+ Remove unused struct script_buf
+ [fd27f67123b3]
+
+2018-08-20 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS:
+ Document when the I/O log timing file entry bug was introduced.
+ [09a75d80487e]
+
+ * NEWS:
+ sync
+ [95fd54c61719]
+
+ * config.h.in, configure, configure.ac, lib/util/gettime.c:
+ HP-UX doesn't suport CLOCK_MONOTONIC but we can use gethrtime()
+ instead.
+ [3ec7d99444c0]
+
+ * src/exec_monitor.c, src/exec_pty.c:
+ Close the pty slave in the parent so that when the command and
+ monitor exit, the pty gets recycled without our having to close it
+ directly.
+ [fec53753cf52]
+
+ * lib/util/term.c, src/exec_monitor.c, src/exec_pty.c, src/sudo.h:
+ Move updating of the window size to the monitor process. This will
+ allow us to close the slave in the main sudo process in the future
+ so only the command and monitor have it open.
+ [07108a1c2edc]
+
+ * configure, configure.ac:
+ sudo 1.8.25
+ [4938ba570787]
+
+ * plugins/sudoers/regress/sudoers/test19.ldif2sudo.ok:
+ Fix test output for bug #845
+ [ee6f2d615bd8]
+
+ * plugins/sudoers/ldap_util.c:
+ Fix pasto when converting sudoNotAfter; from Miguel Sanders Bug #845
+ [69638cd6da60]
+
+2018-08-19 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/iolog.c:
+ Use a monotonic timer that only runs while not suspended for the
+ iolog timing values and write nsec-precision entries.
+ [7f37f0b24ce7]
+
+ * aclocal.m4, config.h.in, configure, configure.ac,
+ include/sudo_util.h, lib/util/gettime.c, lib/util/util.exp.in:
+ Add sudo_gettime_uptime() to measure time while not sleeping.
+ [a128e7d51740]
+
+2018-08-18 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * mkpkg:
+ Detect number of CPUs on AIX.
+ [2b7c62b42da2]
+
+ * plugins/sudoers/iolog.c:
+ Fix I/O log timing file on systems without a C99-compatible
+ snprintf(). On those systems we use our own snprintf() that doesn't
+ support floating point. We don't actually need floating point in
+ this case since the we can print seconds and microseconds without
+ using it.
+ [4ea419ac5bee]
+
+ * NEWS:
+ Fix for Bug #844
+ [51cfeb79669c]
+
+ * src/sudo_edit.c:
+ Handle the case where O_PATH or O_SEARCH is defined but O_DIRECTORY
+ is not. In theory, O_DIRECTORY is redundant when O_SEARCH is
+ specified but it is legal for O_EXEC and O_SEARCH to have the same
+ value. Bug #844
+ [fb75d75c7249]
+
+2018-08-17 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS:
+ sync
+ [2be1b619a06a]
+
+ * plugins/sudoers/starttime.c:
+ Fix get_starttime() on HP-UX.
+ [329a4ad9f4ef]
+
+ * src/net_ifs.c:
+ Avoid a compilation problem on HP-UX 11.31 with gcc and
+ machine/sys/getppdp.h
+ [b861e894271b]
+
+ * mkpkg:
+ Detect number of CPUs on HP-UX. Use MAKE environment variable if
+ set.
+ [c95ab5d6d392]
+
+2018-08-16 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/Makefile.in:
+ Add CHECK_SYMBOLS_LDFLAGS to check_symbols target. Non-ELF HP-UX
+ executables don't support SHLIB_PATH or LD_LIBRARY_PATH unless ld is
+ passed the +s flag. This lets the check_symbols test pass on systems
+ where the ldap libraries aren't installed in the standard location.
+ [c2d6d3248fa4]
+
+2018-08-15 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/Makefile.in:
+ For the lint target, don't stop after the first manual that fails
+ lint.
+ [8a80d8e7b540]
+
+ * plugins/sudoers/timestamp.c:
+ Add debugging info so we can tell why a timestamp record doesn't
+ match.
+ [99ede76f9835]
+
+2018-08-13 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS:
+ typo
+ [8a5a11b921ea]
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po, po/da.mo,
+ po/da.po:
+ sync with translationproject.org
+ [19f7eba39013]
+
+2018-08-08 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS:
+ sync
+ [1448675b44aa]
+
+2018-08-11 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/iolog.c:
+ Fix the return value of sudoers_io_change_winsize() on success.
+ Otherwise, we only log a single window size change.
+ [d6cdab99f6f9]
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po:
+ sync with translationproject.org
+ [4109b52f393f]
+
+2018-08-07 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Fix ambiguity when talking about Aliases. We can't use User_Alias in
+ the grammar as both the definition of the Alias as well as its name.
+ This adds {User,Runas,Host,Cmnd}_Alias_Spec to help differentiate
+ between the name of the alias and its definition. Bug #834
+ [06678d12306f]
+
+ * doc/cvtsudoers.cat, doc/sudoreplay.cat:
+ regen
+ [d7237381675a]
+
+ * Makefile.in:
+ Warn if unable to run xgettext or msgfmt.
+ [d0cbba35cd49]
+
+2018-08-06 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/hr.mo,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/ja.mo,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pt_BR.mo,
+ plugins/sudoers/po/sv.mo, plugins/sudoers/po/uk.mo,
+ plugins/sudoers/po/vi.mo:
+ sync with translationproject.org
+ [d1deb5cb5eb3]
+
+2018-08-05 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/fmtsudoers.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/ldap_util.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/policy.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Refactor code to convert defaults to tags and do conversion on
+ output for "sudo -l".
+
+ Remove the short_list (was long_list) global in favor of a verbose
+ argument.
+ [eae1e1e814e0]
+
+2018-08-04 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/policy.c:
+ Assign short_list true, not 1 now that it is a boolean.
+ [10354cd29439]
+
+ * plugins/sudoers/fmtsudoers.c:
+ fix typo
+ [ad7e93f375ba]
+
+2018-08-03 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/rcstr.c:
+ Fix a warning on FreeBSD which has a fancier __containerof
+ implementation.
+ [b5106a524232]
+
+ * plugins/sudoers/po/de.po, plugins/sudoers/po/hr.po,
+ plugins/sudoers/po/it.po, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/pl.po, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/sv.po, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.po:
+ sync with translationproject.org
+ [ae5353cbeac4]
+
+2018-08-02 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * aclocal.m4, autogen.sh, config.h.in, configure:
+ Regen with aclocal 1.15.1.
+ [22c02e451333]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/parse.c,
+ plugins/sudoers/policy.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ For ldap/sssd, include defaults in the generate privilege unless we
+ are listing in short mode (in which case we convert them to tags if
+ possible). Fixes a problem where sudoOptions were not being applied
+ to the command.
+ [b21267488971]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/parse.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ update_defaults() needs to be able to take a defaults_list for the
+ ldap/sssd backends which support per-role defaults.
+ [ddbb07881a46]
+
+2018-07-31 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [29c5a09aaeaf]
+
+2018-07-30 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS:
+ Update
+ [045b535f84b9]
+
+2018-07-26 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/alias.c, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/cvtsudoers_json.c,
+ plugins/sudoers/cvtsudoers_ldif.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/defaults.h, plugins/sudoers/file.c,
+ plugins/sudoers/fmtsudoers.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/ldap.c,
+ plugins/sudoers/match.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudo_nss.h, plugins/sudoers/sudoers.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ o Move userspecs, defaults and aliases into a new struct
+ sudoers_parse_tree. o The parse tree is now passed to the alias,
+ match and defaults functions. o The nss API has been changed so that
+ the nss parse() function returns a pointer to a struct
+ sudoers_parse_tree which will be filled in by the getdefs() and
+ query() functions.
+ [bddb4676ad0e]
+
+ * lib/util/getgrouplist.c:
+ Don't need to preallocate 4 x NGROUP_MAX on AIX or BSD/Linux. For
+ BSD/Linux, getgrouplist(3) will tell us the number of groups if we
+ don't have enough. For AIX, we can count the entries in the group
+ set before allocating the group vector.
+ [c278fd947af4]
+
+ * plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/auth/sudo_auth.h,
+ plugins/sudoers/check.c, plugins/sudoers/sudoers.h:
+ Ignore PAM_NEW_AUTHTOK_REQD and PAM_AUTHTOK_EXPIRED errors from
+ pam_acct_mgmt() if authentication is disabled for the user. Bug #843
+ [1dc39794cf0d]
+
+2018-07-23 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * src/exec_pty.c:
+ Work around a bug on AIX where closing the pty slave causes the main
+ sudo process to lose its controlling tty (which was *not* the pty
+ slave).
+ [649a25b7f864]
+
+ * src/sudo.c:
+ Add missing aix_restoreauthdb() call to match the aix_setauthdb()
+ added in b8a011be9af7. Fixes issues on AIX where local users/groups
+ may not be resolved when some NIS/AD/LDAP is used for users.
+ [16e196a7a337]
+
+ * lib/util/getgrouplist.c:
+ Linux getgrouplist(3) returns the number of groups on success
+ instead of 0 like BSD.
+ [599a89afa4f5]
+
+2018-07-20 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * mkdep.pl, plugins/sudoers/Makefile.in:
+ When both a .o and .lo file was used in a Makefile, we used to make
+ the .o depend on the .lo. Unfortunately, this creates a race
+ condition for parallel make since libtool is not atomic (it creates
+ a .o and then renames it when building PIC objects for shared libs).
+
+ We always link with libtool so the only reason to prefer the .o over
+ the .lo file is to avoid mixing .o and .lo in the dependencies.
+ That's not a good enough reason so change mkdep.pl to warn when both
+ a .o and .lo are referenced in a Makefile and do nothing else.
+
+ Bug #842
+ [a8d94e6aed9f]
+
+2018-07-15 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/ldap.c:
+ Avoid duplicate free when netgroup_base is invalid.
+ [5ce39dff77ba]
+
+2018-07-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/arc4random.h:
+ Use madvise(2) with MADV_WIPEONFORK if available.
+ [a11461409569]
+
+2018-07-01 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po, po/eo.mo,
+ po/eo.po:
+ sync with translationproject.org
+ [01bcfe7b30e5]
+
+ * NEWS:
+ Update.
+ [f5e0b1f909bb]
+
+2018-06-25 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ sync with schema.OpenLDAP
+ [d83420d8228d]
+
+ * doc/schema.OpenLDAP:
+ RFC 2849 specifies whitespace as the space character only so replace
+ tabs with spaces. Bug #840
+ [e9d5de6365ba]
+
+ * doc/schema.OpenLDAP:
+ Fix typo; bug #839
+ [dee2dad738de]
+
+2018-06-16 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in:
+ Should no longer need to set max_groups.
+ [459119b11265]
+
+2018-06-15 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers_pwutil.c, plugins/sudoers/pwutil_impl.c,
+ src/sudo.c:
+ Use new sudo_getgrouplist2() function instead of getgrouplist().
+ [8e88b6d3ea6f]
+
+ * configure, configure.ac, include/sudo_compat.h, include/sudo_util.h,
+ lib/util/Makefile.in, lib/util/getgrouplist.c, lib/util/util.exp.in:
+ Add sudo_getgrouplist2() to dynamically allocate the group vector.
+ This allows us to avoid repeatedly calling getgrouplist() with a
+ statically sized vector on macOS, Solaris, HP-UX, and AIX.
+ [55480e2ec7c2]
+
+ * src/conversation.c:
+ Fix fd leak introduced by SUDO_CONV_PREFER_TTY commit. Coverity CID
+ 186605.
+ [fb6eb518bc4c]
+
+2018-06-13 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.man.in, doc/sudo_plugin.mdoc.in, doc/sudoers.cat,
+ doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ doc/sudoers_timestamp.cat, doc/sudoers_timestamp.man.in,
+ doc/sudoers_timestamp.mdoc.in, doc/visudo.cat, doc/visudo.man.in,
+ doc/visudo.mdoc.in:
+ Fix some issues pointed out by mandoc -Tlint
+ [7ace981c7334]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, include/sudo_plugin.h, src/conversation.c:
+ Add SUDO_CONV_PREFER_TTY flag for conversation function to tell sudo
+ to try writing to /dev/tty first. Can be used in conjunction with
+ SUDO_CONV_INFO_MSG and SUDO_CONV_ERROR_MSG.
+ [a1e9420a7c5e]
+
+2018-06-08 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/LICENSE:
+ Update for arc4random.c, arc4random_uniform.c and getentropy.c
+ [168db3c8d590]
+
+2018-06-05 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * src/regress/noexec/check_noexec.c:
+ FreeBSD wordexp() returns WRDE_SYNTAX if it can't write to the shell
+ process. Since we've prevented execve() from succeeding this is the
+ error we get back from wordexp() on FreeBSD.
+ [2a7a73de30cf]
+
+2018-06-04 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/starttime.c:
+ Fix conversion of usec to nsec; from Scott Cheloha
+ [26fa756ea623]
+
+2018-06-01 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * include/sudo_plugin.h:
+ Fix typo.
+ [504256dc4ccc]
+
+2018-05-29 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ The getdefs() function now get called multiple times so use the
+ cached data if present.
+ [042be7ccab3c]
+
+ * plugins/sudoers/sssd.c, plugins/sudoers/sudoers.c:
+ Return an empty defaults list, not NULL if there is no global
+ sudoers defaults entry in sss.
+ [8e16de465ee2]
+
+ * plugins/sudoers/file.c:
+ Fix memory leak of handle pointer on close.
+ [e4eb30e611d4]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Remove a needless copy when parsing options.
+ [60fe50b736a9]
+
+ * plugins/sudoers/file.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/parse.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudo_nss.h,
+ plugins/sudoers/sudoers.c:
+ Move cached userspecs and defaults into the handle object.
+ [37e4df73907d]
+
+2018-05-28 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Quiet a clang analyzer warning. It should not be possible for
+ pop_include() to be called when YY_CURRENT_BUFFER is NULL.
+ [148d79e5a44e]
+
+ * plugins/sudoers/file.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/sssd.c:
+ Reorder things to avoid the need to declare static functions.
+ [8f27e69fa9cb]
+
+2018-05-24 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * lib/util/Makefile.in, lib/util/mktemp.c,
+ plugins/sudoers/Makefile.in, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/insults.h:
+ Use arc4random for mkstemp() and insults.
+ [b8c7447756f2]
+
+ * MANIFEST, config.h.in, configure, configure.ac, include/sudo_rand.h,
+ lib/util/Makefile.in, lib/util/arc4random.c, lib/util/arc4random.h,
+ lib/util/arc4random_uniform.c, lib/util/chacha_private.h,
+ lib/util/getentropy.c, lib/util/util.exp.in, mkdep.pl:
+ Import arc4random() from libressl. This takes an all-in-one approach
+ instead of the one-file-per-OS approach that libressl takes. The
+ fallback code does not have as many OS-specific bits as libressl.
+ [310d65e466bd]
+
+ * MANIFEST, configure, configure.ac, include/sudo_digest.h,
+ lib/util/Makefile.in, lib/util/digest.c, lib/util/digest_gcrypt.c,
+ lib/util/digest_openssl.c, lib/util/util.exp.in, mkdep.pl,
+ plugins/sudoers/Makefile.in, plugins/sudoers/digestname.c,
+ plugins/sudoers/filedigest.c, plugins/sudoers/filedigest_gcrypt.c,
+ plugins/sudoers/filedigest_openssl.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.h, plugins/sudoers/gram.y,
+ plugins/sudoers/ldap_util.c, plugins/sudoers/match.c,
+ plugins/sudoers/parse.h,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/sudo_ldap.h, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l:
+ Move digest code into libutil
+ [c53cf5c508eb]
+
+2018-05-20 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * MANIFEST, plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/regress/cvtsudoers/test25.sh,
+ plugins/sudoers/regress/cvtsudoers/test26.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test26.sh,
+ plugins/sudoers/regress/cvtsudoers/test27.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test27.sh:
+ Check for invalid bas64 attributes.
+ [4218d11c8205]
+
+ * plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/regress/parser/check_base64.c:
+ Fix pointer sign warnings.
+ [5ee724e3956e]
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ Add missing variable declaration for SELinux and Solaris.
+ [c8084f0508e5]
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ Handle empty string and treat it as safe.
+ [8029b97d8f4a]
+
+ * MANIFEST, plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/regress/cvtsudoers/test26.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test26.sh:
+ Add support for base64-encoding non-safe strings in LDIF output.
+ [b9fd1795f4ee]
+
+2018-05-19 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/base64.c, plugins/sudoers/parse.h,
+ plugins/sudoers/regress/parser/check_base64.c:
+ Add base64_encode() by Jon Mayo.
+ [a893ec3dc667]
+
+2018-05-18 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * MANIFEST, plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/regress/cvtsudoers/test25.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test25.sh:
+ Add support for parsing base64-encoded attributes
+ [262dd9a526de]
+
+2018-05-17 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/regress/sudoers/test2.ldif.ok:
+ rfc2253 says we need to escape " and leading and trailing space.
+ [1c0105a5eb1b]
+
+ * configure, configure.ac:
+ Define ZLIB_CONST so we get the const version of the API.
+ [71a629d0eb4b]
+
+2018-05-16 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/parse.c:
+ Fix logic inversion when handing the authenticate Defaults option
+ for "sudo -l" and "sudo -v" in long list mode.
+ [f8157d4c4f03]
+
+ * plugins/sudoers/sssd.c:
+ Set handle->pw before sss_to_sudoers() since sss_check_user() uses
+ it. Coverity CID 185651
+ [fa646e569352]
+
+ * plugins/sudoers/ldap_util.c:
+ Fix memory leak on error, CID 185602
+ [31c1ab085985]
+
+ * plugins/sudoers/ldap.c:
+ Some ldap_get_values_len -> sudo_ldap_get_values_len that were
+ missed before.
+ [d7f1877531be]
+
+ * plugins/sudoers/ldap_util.c:
+ When building up the cmndspec, add the actual command member last.
+ This simplifies the logic regarding the SETENV tag and alsomakes
+ "out of memory" cleanup simpler.
+ [d704f3b09ac1]
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ Fix format string mismatch, sudo_order is unsigned.
+ [ecc398e45b0a]
+
+ * plugins/sudoers/pwutil.c:
+ Add cppcheck annotation to suppress memory leak false positive.
+ [d4a0ae57c372]
+
+ * plugins/sudoers/ldap_util.c:
+ Sudo "ALL" implies the SETENV tag.
+ [7abc653b4d39]
+
+ * src/parse_args.c:
+ Only set MODE_PRESERVE_ENV when preserving the entire environment.
+ Fixes a problem introduced in 1.8.23 where "sudo -i" could not be
+ used in conjunction with --preserve-env=VARIABLE. Bug #835
+ [8ea75ca8fbd2]
+
+2018-05-15 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/file.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/ldap.c,
+ plugins/sudoers/parse.h, plugins/sudoers/sssd.c:
+ Add free_userspecs() and free_default() and use them instead of
+ looping over the lists and calling free_userspec() and
+ free_default().
+ [797221539242]
+
+ * configure, configure.ac:
+ Depending on the bos level, AIX 6.1 may or may not include
+ getline/getdelim and AIX 7.1 may or may not include memset_s. Since
+ we need to build packages that will work on all AIX 6.1 and 7.1
+ machines, use our getline() and memset_s emulation.
+ [f5c427076b2c]
+
+2018-05-14 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/ldap_util.c:
+ Do not leak struct sudo_command when the command is ALL. Coverity
+ CID 185602.
+ [d71ca4bc06bc]
+
+ * NEWS, configure, configure.ac:
+ Sudo 1.8.24
+ [7df3df9a3907]
+
+ * plugins/sudoers/sssd.c:
+ Improve comments about why we need to do a user check and how it
+ related to netgroups.
+ [605234ed0935]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Add checks for ldap/sss functions failing due to memory allocation
+ errors.
+ [0dfeb0d8ecf5]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Let the main sudoers lookup code check the host name. We still check
+ the user name so it is possible to use a single userspec but this
+ may change in the future.
+ [a74699b90213]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/defaults.c,
+ plugins/sudoers/defaults.h, plugins/sudoers/file.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/ldap_util.c,
+ plugins/sudoers/parse.c, plugins/sudoers/parse.h,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudo_ldap.h,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudo_nss.h,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ Simplify the nss interface such that each sudoers provider fills in
+ a per-nss list of userspecs and defaults instead of using separate
+ lookup and list functions. This makes it possible to have a single
+ implementation of the code for sudoers lookup and listing.
+ [50de9302de01]
+
+ * plugins/sudoers/alias.c, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/cvtsudoers_json.c,
+ plugins/sudoers/cvtsudoers_ldif.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/filedigest.c, plugins/sudoers/filedigest_gcrypt.c,
+ plugins/sudoers/filedigest_openssl.c, plugins/sudoers/fmtsudoers.c,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/ldap.c, plugins/sudoers/ldap_conf.c,
+ plugins/sudoers/ldap_util.c, plugins/sudoers/match.c,
+ plugins/sudoers/parse.c, plugins/sudoers/policy.c,
+ plugins/sudoers/regress/parser/check_addr.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, plugins/sudoers/visudo.c:
+ Include parse.h in sudoers.h since it will soon be required.
+ [196abb590d96]
+
+ * plugins/sudoers/ldap_util.c:
+ Parse "ALL" as a command correctly.
+ [d969e7dfdbbc]
+
+2018-05-11 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/match.c:
+ Add debug warning if lseek() fails (should not be possible).
+ [d568dc923c7d]
+
+ * plugins/sudoers/match.c:
+ Fix swapped args of lseek() when rewinding. This didn't cause a
+ problem because the value of SEEK_SET is 0.
+ [142591a3f333]
+
+2018-05-10 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/regress/parser/check_hexchar.c:
+ Fix a format-truncation warning in newer gcc by avoiding using %0x
+ and %0X in the test. We are formatting a single byte so just do it
+ one nybble at a time.
+ [7c594a63598f]
+
+ * configure:
+ Regen with autoconf git commit
+ e17a30e987d7ee695fb4294a82d987ec3dc9b974 AC_HEADER_MAJOR: port to
+ glibc 2.25
+ [9fe77765c768]
+
+2018-05-03 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ No need to explicitly free role on EOF, it will be freed after the
+ loop is done.
+ [8d08c06b7622]
+
+ * plugins/sudoers/policy.c:
+ Garbage collect the command argv, envp and info vectors since they
+ are not available at policy close time.
+ [de22290a8ec5]
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ Plug memory leaks on parse error or when an LDIF entry doesn't match
+ the dn filter.
+ [4f48e740eed1]
+
+ * plugins/sudoers/cvtsudoers.c:
+ Rename variables now that the string list functions are not ldap-
+ specific.
+ [640497f70551]
+
+2018-04-30 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS:
+ Fix typo
+ [6466295ba962]
+
+2018-04-29 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * configure, configure.ac:
+ fix version
+ [bfed601130b5]
+
+ * NEWS:
+ sync
+ [1c382f2aff27]
+
+ * configure, configure.ac, plugins/sudoers/po/zh_CN.mo,
+ plugins/sudoers/po/zh_CN.po, po/zh_CN.mo, po/zh_CN.po:
+ sync with translationproject.org
+ [ec28ff5acbd6]
+
+2018-04-25 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/match.c:
+ O_EXEC for fexecve() not O_SEARCH.
+ [a156d8b38f31]
+
+ * doc/TROUBLESHOOTING:
+ Document how to suppress the last login message on Solaris.
+ [2926b670aca4]
+
+2018-04-24 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers_json.c:
+ Fix compilation error with older Sun Studio compilers.
+ [0f735611642d]
+
+ * NEWS:
+ Update Bug #831 decription.
+ [d5e6a2a807b8]
+
+ * MANIFEST, doc/CONTRIBUTORS, po/zh_TW.mo, po/zh_TW.po:
+ Add Chinese(Taiwan) translation for sudo.
+ [5a4ba6769cca]
+
+ * plugins/sudoers/match.c:
+ Move the check for /dev/fd/N until *after* the digest has been
+ checked. We still need to be able to check the digest even if there
+ is no /dev/fd/N or fexecve().
+ [e0e086b4e764]
+
+2018-04-23 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/match.c:
+ Rewind the fd after calling sudo_filedigest(). Otherwise, when
+ running a script via fexecve(), the interpreter may get EOF when
+ reading /dev/fd/N. This only appears to affect BSD systems with
+ fdescfs. Bug #831.
+ [d79f5125cc73]
+
+ * plugins/sudoers/match.c:
+ In open_cmnd(), return true, not false, if we the /dev/fd/N pathname
+ is not present. We don't want to fail a match because of this.
+ [72c4b499c019]
+
+ * NEWS:
+ Bug #831.
+ [700646725f45]
+
+ * plugins/sudoers/match.c:
+ We can only use fexecve() on a script if /dev/fd/N exists. Some
+ systems, such as FreeBSD, don't have /dev/fd mounted by default. Bug
+ #831
+ [30f7c5d64104]
+
+2018-04-22 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/ca.mo, plugins/sudoers/po/ca.po,
+ plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/el.mo, plugins/sudoers/po/el.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/eu.mo, plugins/sudoers/po/eu.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/fr.mo, plugins/sudoers/po/fr.po,
+ plugins/sudoers/po/fur.mo, plugins/sudoers/po/fur.po,
+ plugins/sudoers/po/hu.mo, plugins/sudoers/po/hu.po,
+ plugins/sudoers/po/ko.mo, plugins/sudoers/po/ko.po,
+ plugins/sudoers/po/lt.mo, plugins/sudoers/po/lt.po,
+ plugins/sudoers/po/nl.mo, plugins/sudoers/po/nl.po,
+ plugins/sudoers/po/ru.mo, plugins/sudoers/po/ru.po,
+ plugins/sudoers/po/sk.mo, plugins/sudoers/po/sk.po,
+ plugins/sudoers/po/sl.mo, plugins/sudoers/po/sl.po,
+ plugins/sudoers/po/sr.mo, plugins/sudoers/po/sr.po,
+ plugins/sudoers/po/tr.mo, plugins/sudoers/po/tr.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po, po/ca.mo,
+ po/ca.po, po/da.mo, po/da.po, po/de.mo, po/de.po, po/eo.mo,
+ po/eo.po, po/es.mo, po/es.po, po/eu.mo, po/eu.po, po/fi.mo,
+ po/fi.po, po/fur.mo, po/fur.po, po/gl.mo, po/gl.po, po/hu.mo,
+ po/hu.po, po/ko.mo, po/ko.po, po/nl.mo, po/nl.po, po/nn.mo,
+ po/nn.po, po/ru.mo, po/ru.po, po/sk.mo, po/sk.po, po/sl.mo,
+ po/sl.po, po/sr.mo, po/sr.po, po/vi.mo, po/vi.po, po/zh_CN.mo,
+ po/zh_CN.po:
+ sync with translationproject.org
+ [a786a841f30a]
+
+2018-04-21 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/ca.mo, plugins/sudoers/po/ca.po,
+ plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/el.mo, plugins/sudoers/po/el.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/eu.mo, plugins/sudoers/po/eu.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/fr.mo, plugins/sudoers/po/fr.po,
+ plugins/sudoers/po/fur.mo, plugins/sudoers/po/fur.po,
+ plugins/sudoers/po/hu.mo, plugins/sudoers/po/hu.po,
+ plugins/sudoers/po/ko.mo, plugins/sudoers/po/ko.po,
+ plugins/sudoers/po/lt.mo, plugins/sudoers/po/lt.po,
+ plugins/sudoers/po/nl.mo, plugins/sudoers/po/nl.po,
+ plugins/sudoers/po/ru.mo, plugins/sudoers/po/ru.po,
+ plugins/sudoers/po/sk.mo, plugins/sudoers/po/sk.po,
+ plugins/sudoers/po/sl.mo, plugins/sudoers/po/sl.po,
+ plugins/sudoers/po/sr.mo, plugins/sudoers/po/sr.po,
+ plugins/sudoers/po/tr.mo, plugins/sudoers/po/tr.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po, po/ca.mo,
+ po/ca.po, po/da.mo, po/da.po, po/de.mo, po/de.po, po/eo.mo,
+ po/eo.po, po/es.mo, po/es.po, po/eu.mo, po/eu.po, po/fi.mo,
+ po/fi.po, po/fur.mo, po/fur.po, po/gl.mo, po/gl.po, po/hu.mo,
+ po/hu.po, po/ko.mo, po/ko.po, po/nl.mo, po/nl.po, po/nn.mo,
+ po/nn.po, po/ru.mo, po/ru.po, po/sk.mo, po/sk.po, po/sl.mo,
+ po/sl.po, po/sr.mo, po/sr.po, po/vi.mo, po/vi.po, po/zh_CN.mo,
+ po/zh_CN.po:
+ sync with translationproject.org
+ [268a65ce44cb]
+
+ * MANIFEST, plugins/sudoers/regress/cvtsudoers/test23.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test23.sh,
+ plugins/sudoers/regress/cvtsudoers/test24.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test24.sh:
+ Add tests for round-tripping cvtsudoers, sudoers -> LDIF -> sudoers
+ and LDIF -> sudoers -> LDIF.
+ [370d4ba4dbb8]
+
+2018-04-19 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * MANIFEST, plugins/sudoers/regress/cvtsudoers/test22.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test22.sh:
+ Test the -b option when converting from LDIF.
+ [4d65c7c2ed01]
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ Fix the -b option when converting from LDIF.
+ [f3c1e4dbd61e]
+
+2018-04-18 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po, po/it.mo,
+ po/it.po:
+ sync with translationproject.org
+ [1953956c60fe]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.ldap.mdoc.in,
+ doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in:
+ Fix some more typos.
+ [87fde92a1fa4]
+
+ * doc/Makefile.in:
+ mandoc now preserves the copyright notice, no need to do it
+ ourselves
+ [2c3f6841941a]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Describe the special handling of LOGNAME, USER and USERNAME. Fix
+ typos reported by aspell.
+ [e89bd28f4530]
+
+ * src/load_plugins.c:
+ Fix a memory leak on the error path.
+ [db5a4678e0e4]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document that the editor setting is also used by sudoedit.
+ [2ae14439efd7]
+
+2018-04-17 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * src/load_plugins.c, src/sudo.c, src/sudo_plugin_int.h:
+ Plug memory leak when an I/O plugin is specified in sudo.conf but
+ the I/O plugin is not configured.
+ [5b5086d7152a]
+
+ * INSTALL, MANIFEST, NEWS, config.h.in, configure, configure.ac,
+ plugins/sudoers/Makefile.in, plugins/sudoers/ins_python.h,
+ plugins/sudoers/insults.h:
+ Monty Python insults from Philip Hudson
+ [8330cfc5ea19]
+
+2018-04-15 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in:
+ add examples
+ [830ff26a0dbc]
+
+ * doc/sudo.conf.man.in, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.man.in, doc/sudo_plugin.mdoc.in,
+ doc/sudoers.ldap.man.in, doc/sudoers.man.in,
+ doc/sudoers_timestamp.man.in, doc/sudoreplay.man.in,
+ doc/visudo.man.in:
+ Update copyright year and regen man pages.
+ [6385891ebaa3]
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/hr.mo, plugins/sudoers/po/hr.po,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/sv.mo, plugins/sudoers/po/sv.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po, po/cs.mo,
+ po/cs.po, po/fr.mo, po/fr.po, po/hr.mo, po/hr.po, po/ja.mo,
+ po/ja.po, po/nb.mo, po/nb.po, po/pl.mo, po/pl.po, po/pt_BR.mo,
+ po/pt_BR.po, po/sv.mo, po/sv.po, po/tr.mo, po/tr.po, po/uk.mo,
+ po/uk.po:
+ sync with translationproject.org
+ [3495b17becb0]
+
+ * MANIFEST, examples/sudoers, plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/cvtsudoers/sudoers,
+ plugins/sudoers/regress/cvtsudoers/sudoers.defs,
+ plugins/sudoers/regress/cvtsudoers/test1.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test1.sh,
+ plugins/sudoers/regress/cvtsudoers/test10.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test10.sh,
+ plugins/sudoers/regress/cvtsudoers/test11.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test11.sh,
+ plugins/sudoers/regress/cvtsudoers/test12.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test12.sh,
+ plugins/sudoers/regress/cvtsudoers/test13.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test13.sh,
+ plugins/sudoers/regress/cvtsudoers/test14.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test14.sh,
+ plugins/sudoers/regress/cvtsudoers/test15.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test15.sh,
+ plugins/sudoers/regress/cvtsudoers/test16.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test16.sh,
+ plugins/sudoers/regress/cvtsudoers/test17.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test17.sh,
+ plugins/sudoers/regress/cvtsudoers/test18.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test18.sh,
+ plugins/sudoers/regress/cvtsudoers/test19.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test19.sh,
+ plugins/sudoers/regress/cvtsudoers/test2.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test2.sh,
+ plugins/sudoers/regress/cvtsudoers/test20.conf,
+ plugins/sudoers/regress/cvtsudoers/test20.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test20.sh,
+ plugins/sudoers/regress/cvtsudoers/test21.conf,
+ plugins/sudoers/regress/cvtsudoers/test21.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test21.sh,
+ plugins/sudoers/regress/cvtsudoers/test3.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test3.sh,
+ plugins/sudoers/regress/cvtsudoers/test4.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test4.sh,
+ plugins/sudoers/regress/cvtsudoers/test5.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test5.sh,
+ plugins/sudoers/regress/cvtsudoers/test6.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test6.sh,
+ plugins/sudoers/regress/cvtsudoers/test7.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test7.sh,
+ plugins/sudoers/regress/cvtsudoers/test8.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test8.sh,
+ plugins/sudoers/regress/cvtsudoers/test9.out.ok,
+ plugins/sudoers/regress/cvtsudoers/test9.sh:
+ cvtsudoers regress tests
+ [72fd218b5036]
+
+ * plugins/sudoers/cvtsudoers.c, plugins/sudoers/match.c:
+ Prune alias contents when pruning and expanding aliases. This abuses
+ the userlist_matches_filter() and hostlist_matches_filter()
+ functions. A better approach would be to call the correct function
+ from user_matches() and host_matches().
+ [0ae5f351b09f]
+
+2018-04-14 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in:
+ Fix typo
+ [e572c36919b7]
+
+ * plugins/sudoers/cvtsudoers.c:
+ Fix cut & pasto that prevented "-d command" from working.
+ [6e4ff7f23d0a]
+
+2018-04-13 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y:
+ Fix a user after free crash as well as a memory leak when filtering
+ Defaults.
+ [9bdd404ae6a4]
+
+2018-04-12 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in:
+ Document that a User_Alias or Host_Alias may be used in the match
+ filter.
+ [49b9306a6a6d]
+
+ * plugins/sudoers/fmtsudoers.c:
+ Don't always expand aliases when formatting a host-based Defaults
+ line. This was missed when expand_aliases support was added.
+ [ef12a033306c]
+
+ * plugins/sudoers/cvtsudoers.c:
+ Allow host and user aliases to be specified in match filters.
+ [6bc8c0da4578]
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ Update copyright year.
+ [e9c2eb23def1]
+
+2018-04-10 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/hr.mo, plugins/sudoers/po/hr.po,
+ plugins/sudoers/po/hu.mo, plugins/sudoers/po/hu.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/sv.mo, plugins/sudoers/po/sv.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po, po/da.mo,
+ po/da.po, po/hr.mo, po/hr.po, po/hu.mo, po/hu.po, po/pt_BR.mo,
+ po/pt_BR.po, po/tr.mo, po/tr.po:
+ sync with translationproject.org
+ [4a0811073374]
+
+2018-04-09 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/alias.c, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/parse.h:
+ When the -d option is used, remove aliases used by the non-converted
+ Defaults settings if the aliases are not also referenced by
+ userspecs.
+ [d07c4254b3dd]
+
+2018-04-05 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [9a4d88b2a965]
+
+ * NEWS:
+ update
+ [6ef9dde8fc9a]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in:
+ Mention -p and -M options in the description of -m.
+ [b20abfd14164]
+
+2018-04-04 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * src/sudo_edit.c:
+ Check sudoedit temporary directory for writability before using it.
+ [1e29ade3f4b2]
+
+ * plugins/sudoers/regress/starttime/check_starttime.c:
+ Use btime in /proc/stat to determine system start time instead of
+ /proc/uptime. Fixes the process start time test when run from a
+ container where /proc/uptime is the uptime of the container but the
+ process start time is relative to the host system boot time. Bug
+ #829
+ [65ba61e55011]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers.h,
+ plugins/sudoers/match.c, plugins/sudoers/parse.h:
+ Add option to prune non-matching entries from cvtsudoers output with
+ -m option is used.
+ [9a69ba35389d]
+
+2018-04-02 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers.h:
+ Allow defaults types and suppression list to be specified in the
+ config file.
+ [62dd7a96ac9b]
+
+ * plugins/sudoers/alias.c, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/parse.h, plugins/sudoers/visudo.c:
+ Refactor common alias code out of cvtsudoers and visudo and into
+ alias.c.
+ [b3ba3e6f24d2]
+
+2018-03-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/cvtsudoers.c:
+ Avoid NULL deref in an error path. CID 183467
+ [38ea56670f18]
+
+ * plugins/sudoers/cvtsudoers.c:
+ No need to initialize the last pointer passed to strtok_r(). This
+ was originally added to appease newer gcc but no longer seems to be
+ required. CID 183466, CID 183468, CID 183469
+ [b0a9b90603e1]
+
+ * plugins/sudoers/cvtsudoers_json.c:
+ Avoid false positive NULL dereference by uses value.u.string instead
+ of name as the former is guaranteed not to be NULL. Fixes CID
+ 183465.
+ [c896d10f5626]
+
+2018-03-29 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [8a88e162fd0b]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ Add a section on convertion from file-based sudoers.
+ [033c797b229d]
+
+2018-03-28 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/cvtsudoers.c:
+ Add support for "cvtsudoers -d all"
+ [62e748b70105]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers.h:
+ Add -d option to control what type of Defaults entries are
+ converted.
+ [b723f0dae5c7]
+
+2018-03-27 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * src/exec_pty.c:
+ In pty_close() we still need to check whether the pty master and
+ slave fds are open before closing them. When no tty is present but
+ we are I/O logging pty_close() will be called when there is no
+ actual pty in use.
+ [59201fb78427]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/sudo.conf.cat,
+ doc/sudoers_timestamp.cat, doc/visudo.cat:
+ regen
+ [186f3b58daf5]
+
+2018-03-26 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * .hgignore:
+ ignore *.ldif2sudo regress output
+ [8d57e8a0013f]
+
+ * src/exec_pty.c:
+ In pty_close() there is no need to remove events associated with the
+ pty slave as there are none. We also don't need to check for the pty
+ fds being -1 since they are not closed elsewhere and pty_close() is
+ only called if pty_setup() succeeds.
+ [585a47fb5a8b]
+
+2018-03-25 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/Makefile.in, doc/cvtsudoers.mdoc.in:
+ Move cvtsudoers to section 1.
+ [69adcb2d24ff]
+
+ * src/exec_pty.c:
+ In pty_close() close the slave and remove any events associated with
+ it. Fixes a potential hang when performing the final flush on non-
+ BSD systems.
+ [40159d852c2d]
+
+2018-03-23 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/ldap_util.c:
+ Fix typo in strcmp(), we are comparing var not val.
+ [07ccd7bae4f6]
+
+ * MANIFEST:
+ sync
+ [7960511e39dd]
+
+ * NEWS:
+ sync
+ [c655e7111ce9]
+
+2018-03-22 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [ff7b545844fb]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers.h,
+ plugins/sudoers/cvtsudoers_pwutil.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/sudoers.h:
+ Add -M option to cvtsudoers to force the use of the local passwd and
+ group databases when matching.
+ [ea58e2765a40]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers.h,
+ plugins/sudoers/cvtsudoers_json.c,
+ plugins/sudoers/cvtsudoers_ldif.c:
+ Add cvtsudoers command line option to suppress certain parts of the
+ security policy. Can be used to suppress displaying of Defaults
+ entries, aliases or privileges.
+ [b243efa695e6]
+
+2018-03-21 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/regress/parser/check_gentime.c:
+ Silence a false positive from the clang static analyzer.
+ [bfde0594783e]
+
+ * plugins/sudoers/cvtsudoers.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/parse.h:
+ Silence a false positive from the clang static analyzer.
+ [5257e321158d]
+
+ * plugins/sudoers/cvtsudoers.c:
+ Fix memory leak on error path.
+ [1a13732abfd5]
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [c139b8bed3c1]
+
+ * plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers.h,
+ plugins/sudoers/cvtsudoers_ldif.c:
+ Move cvtsudoers string functions into cvtsudoers.c
+ [4b5b799e7abc]
+
+ * plugins/sudoers/Makefile.in:
+ regen
+ [6ecb37e35c9f]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/alias.c,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers.h,
+ plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/cvtsudoers_pwutil.c, plugins/sudoers/parse.h:
+ Initial support filtering by user, group and host in cvtsudoers.
+ Currently forces alias expansion when a filter is applied and the
+ entire matching user or host list is printed, even the non-matching
+ entries. This effectively allows you to grep sudoers by user, group
+ and host.
+ [0adbf8d38eb4]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/parse.h:
+ Add free_default() to free a struct defaults pointer so we have a
+ single place where we free the defaults. A pointer to the previous
+ Default's binding may be passed in to avoid freeing an already free
+ binding.
+ [9d9ef007ee88]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.ldap.mdoc.in,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Decrease bullet width to 1n.
+ [e6f3776fd72e]
+
+2018-03-17 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * src/sudo.c:
+ Add aix_setauthdb() before the initial getpwuid() call.
+ [b8a011be9af7]
+
+2018-03-10 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers_ldif.c, plugins/sudoers/fmtsudoers.c,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/parse.h:
+ fix compilation on Solaris
+ [e31019b5f545]
+
+2018-03-08 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in,
+ plugins/sudoers/sudoreplay.c:
+ Make "sudoreplay -m 0" skip the pauses entirely.
+ [d9a7fc9f5720]
+
+ * doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in:
+ Document that a negative value for -m will elmininate the pauses.
+ [a025e96abb47]
+
+2018-03-06 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/testsudoers.c:
+ Update copyright date, remove unneeded include and add a few
+ comments.
+ [ac1bccd631e5]
+
+ * plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/sudoers/test1.out.ok,
+ plugins/sudoers/regress/sudoers/test10.out.ok,
+ plugins/sudoers/regress/sudoers/test11.out.ok,
+ plugins/sudoers/regress/sudoers/test12.out.ok,
+ plugins/sudoers/regress/sudoers/test13.out.ok,
+ plugins/sudoers/regress/sudoers/test14.out.ok,
+ plugins/sudoers/regress/sudoers/test15.out.ok,
+ plugins/sudoers/regress/sudoers/test16.out.ok,
+ plugins/sudoers/regress/sudoers/test17.out.ok,
+ plugins/sudoers/regress/sudoers/test18.out.ok,
+ plugins/sudoers/regress/sudoers/test19.out.ok,
+ plugins/sudoers/regress/sudoers/test2.out.ok,
+ plugins/sudoers/regress/sudoers/test20.out.ok,
+ plugins/sudoers/regress/sudoers/test21.out.ok,
+ plugins/sudoers/regress/sudoers/test22.out.ok,
+ plugins/sudoers/regress/sudoers/test3.out.ok,
+ plugins/sudoers/regress/sudoers/test4.out.ok,
+ plugins/sudoers/regress/sudoers/test5.out.ok,
+ plugins/sudoers/regress/sudoers/test6.out.ok,
+ plugins/sudoers/regress/sudoers/test7.out.ok,
+ plugins/sudoers/regress/sudoers/test8.out.ok,
+ plugins/sudoers/regress/sudoers/test9.out.ok,
+ plugins/sudoers/testsudoers.c:
+ Use fmtsudoers functions in testsudoers.
+ [be27df4a5291]
+
+ * MANIFEST, plugins/sudoers/regress/sudoers/test22.in,
+ plugins/sudoers/regress/sudoers/test22.json.ok,
+ plugins/sudoers/regress/sudoers/test22.ldif.ok,
+ plugins/sudoers/regress/sudoers/test22.ldif2sudo.ok,
+ plugins/sudoers/regress/sudoers/test22.out.ok,
+ plugins/sudoers/regress/sudoers/test22.sudo.ok,
+ plugins/sudoers/regress/sudoers/test22.toke.ok:
+ Add test for empty runas user list.
+ [5598cf4c3329]
+
+ * plugins/sudoers/testsudoers.c:
+ Don't print an empty user list as ALL.
+ [806ee09f854d]
+
+ * plugins/sudoers/fmtsudoers.c, plugins/sudoers/parse.h:
+ In sudoers_format_userspecs make the separator optional and silence
+ a printf format warning.
+ [62c576cbec4b]
+
+ * plugins/sudoers/starttime.c:
+ Use correct defines when checking for sysctl kinfo_proc support.
+ [6017e45d14b9]
+
+ * plugins/sudoers/cvtsudoers_json.c:
+ Fix crash when converting sudoers entry with a runas list that is
+ present but empty.
+ [ff6b9ef53c6b]
+
+2018-03-05 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * config.h.in, configure, configure.ac, plugins/sudoers/starttime.c,
+ plugins/sudoers/sudoers.c, src/regress/ttyname/check_ttyname.c,
+ src/tgetpass.c, src/ttyname.c:
+ Less confusing sysctl checks for kinfo_proc.
+ [553f6b3f9c3b]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/defaults.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/match.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/sssd.c:
+ Add case_insensitive_group and case_insensitive_user sudoers
+ options, which are enabled by default.
+ [bd74d8b7fe83]
+
+2018-03-04 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/fmtsudoers.c:
+ Kill dead store found by clang-analyzer.
+ [af2021d3d396]
+
+2018-03-02 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * MANIFEST, plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/sudoers/test1.ldif2sudo.ok,
+ plugins/sudoers/regress/sudoers/test14.ldif2sudo.ok,
+ plugins/sudoers/regress/sudoers/test15.ldif2sudo.ok,
+ plugins/sudoers/regress/sudoers/test16.ldif2sudo.ok,
+ plugins/sudoers/regress/sudoers/test17.ldif2sudo.ok,
+ plugins/sudoers/regress/sudoers/test19.ldif2sudo.ok,
+ plugins/sudoers/regress/sudoers/test2.ldif2sudo.ok,
+ plugins/sudoers/regress/sudoers/test20.ldif2sudo.ok,
+ plugins/sudoers/regress/sudoers/test21.ldif2sudo.ok,
+ plugins/sudoers/regress/sudoers/test3.ldif2sudo.ok,
+ plugins/sudoers/regress/sudoers/test6.ldif2sudo.ok:
+ Add tests for round-tripping sudoers -> ldif -> sudoers
+ [72e3e73fb612]
+
+2018-03-04 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/cvtsudoers_ldif.c, plugins/sudoers/fmtsudoers.c,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/ldap.c, plugins/sudoers/ldap_util.c,
+ plugins/sudoers/parse.h,
+ plugins/sudoers/regress/sudoers/test2.ldif.ok,
+ plugins/sudoers/regress/sudoers/test3.ldif.ok,
+ plugins/sudoers/regress/sudoers/test6.ldif.ok,
+ plugins/sudoers/sssd.c:
+ Initial support for adding comments that will be emitted when
+ sudoers is formatted. Currently adds a comment for the source
+ sudoRole when converting from ldif -> sudoers.
+ [bf2e7f48f452]
+
+ * lib/util/lbuf.c, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/fmtsudoers.c, plugins/sudoers/parse.h:
+ Special case comment lines in lbufs.
+ [10d6d229ffae]
+
+2018-03-03 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers.c, plugins/sudoers/fmtsudoers.c,
+ plugins/sudoers/parse.h:
+ When formatting as sudoers, flush the lbuf after each userspec.
+ [060266dd440c]
+
+2018-03-04 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ Handle escaped commas when skipping over the cn.
+ [61aed7ff5e1c]
+
+2018-03-02 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ Add missing sudoOrder support to parse_ldif().
+ [8c5e9f22f0da]
+
+ * plugins/sudoers/ldap_util.c:
+ Add missing support for converting LOG_INPUT/LOG_OUTPUT tags and
+ expand support for NOMAIL tags.
+ [2820c8333381]
+
+ * plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/regress/sudoers/test2.ldif.ok,
+ plugins/sudoers/regress/sudoers/test3.ldif.ok,
+ plugins/sudoers/regress/sudoers/test6.ldif.ok:
+ Don't emit an empty sudoRole for global defaults if there are none.
+ [2a69dccb7071]
+
+ * plugins/sudoers/ldap_util.c:
+ Avoid changing the order of non-negated hosts and commands. We still
+ put negated hosts/commands at the end of the list.
+ [e1aea92dd6dc]
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ Handle parsing boolean options that have no explicit value.
+ [b5d597faa23d]
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ Refactor the code that actually converts the role to sudoers format
+ into role_to_sudoers() now that it is more involved than just
+ calling sudo_ldap_role_to_priv().
+ [b876171ff96e]
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ When merging two privileges, use the runas lists of the previous
+ privilege when possible. Otherwise, the generated sudoers line will
+ include a runas list for commands that is not necessary.
+ [337b49451947]
+
+2018-03-01 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/match.c:
+ Use a case-insensitive comparison when matching user and group names
+ in sudoers with the passwd or group database. This can be necessary
+ when users and groups are stored in AD or LDAP.
+ [bfccb8acc3e9]
+
+ * plugins/sudoers/Makefile.in:
+ Fix clean target for *.sudo regress files
+ [6f52a4aef93a]
+
+ * .hgignore:
+ ignore more binaries
+ [9adf244d0e9e]
+
+ * plugins/sudoers/cvtsudoers.c:
+ Fix use of uninitialized variable (conf) if sudoers_debug_register()
+ happens to fail.
+ [0ef1765f14f4]
+
+2018-02-28 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ Split conversion code out of parse_ldif() and into
+ ldif_to_sudoers().
+ [27c8b7001735]
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ Quiet a clang analyzer warning.
+ [21102c27dcce]
+
+ * MANIFEST, configure, configure.ac, mkdep.pl,
+ plugins/sudoers/Makefile.in, plugins/sudoers/ldap_common.c,
+ plugins/sudoers/ldap_util.c:
+ rename ldap_common.c -> ldap_util.c
+ [3093bdbb8a9b]
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ When converting from ldif to sudoers, sudoRole objects with the same
+ user if possible. If both user and host are the same, merge into a
+ single privilege. This makes it possible to convert a sudoers entry
+ like:
+
+ aaron shanty = NOEXEC: /usr/bin/vi, /usr/bin/more, EXEC: /bin/sh
+
+ to ldif and then back to sudoers as a single line. Currently, the
+ ldif entries to be merged must have the same or adjacent sudoOrder
+ attributes.
+ [74e5cef2e849]
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ plug memory leaks
+ [a5268668c397]
+
+ * src/parse_args.c:
+ Restore line to set MODE_PRESERVE_ENV in flags when the -E command
+ line option is used. The caller doesn't check MODE_PRESERVE_ENV
+ these days but parse_args uses it to detect usage errors when -E is
+ used along with a mutually excusive option. Problem found by Yuriy
+ Vostrikov.
+ [b511e35d9be4]
+
+2018-02-26 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Add missing close parenthesis in "Including other files from within
+ sudoers" section. Bug #824
+ [3335cb2ce29f]
+
+2018-02-25 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/ldap_common.c:
+ When converting from LDAP to sudoers, put negated hosts and commands
+ at the end of the list. Since LDAP doesn't guarantee attribute order
+ we need to make sure negated entries always override non- negated
+ ones.
+ [0ebff259c521]
+
+2018-02-24 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers.c:
+ We may need the hostname to resolve %h escapes in include files.
+ [3e57710762d3]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers_ldif.c:
+ Setting a sudoOrder start point of 0 will disable creation of
+ sudoOrder attributes in the resulting LDIF output.
+ [4107f61b431b]
+
+ * plugins/sudoers/cvtsudoers.c:
+ Don't need to fill in struct sudo_user since we don't do matching.
+ [cdc876d298b5]
+
+ * MANIFEST, doc/cvtsudoers.cat, doc/cvtsudoers.man.in,
+ doc/cvtsudoers.mdoc.in, pathnames.h.in, plugins/sudoers/Makefile.in,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers.h,
+ plugins/sudoers/cvtsudoers_json.c,
+ plugins/sudoers/cvtsudoers_ldif.c:
+ Add support for setting default options in a config file. In
+ addition to expand_aliases, input_format and output_format, both the
+ initial sudoOrder and the increment when updating sudoOrder for
+ subsequent sudoRole objects can be specified. Command line options
+ have also been added for the start order and increment.
+ [d3121c039ddf]
+
+2018-02-22 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS:
+ cvtsudoers can now read LDIF
+ [99b7ed30c754]
+
+ * doc/UPGRADE:
+ Fix a typo.
+ [87f635970a5d]
+
+ * plugins/sudoers/fmtsudoers.c:
+ Deal with user_name not being set in cvtsudoers.
+ [421bb1dbff57]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/cvtsudoers_json.c,
+ plugins/sudoers/cvtsudoers_ldif.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/ldap_common.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudo_ldap.h:
+ Initial support for parsing sudoers LDIF files in cvtsudoers. This
+ makes it possible to convert from LDAP sudoers to a traditional
+ sudoers file. Semantic differences between file sudoers and LDAP
+ sudoers mean that LDIF -> sudoers is not completely equivalent.
+ [ddf513e2778f]
+
+2018-02-21 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/regress/sudoers/test14.ldif.ok:
+ Fix LDIF conversion of commands with an associated digest.
+ [590ab0cb58e4]
+
+ * plugins/sudoers/ldap_common.c:
+ In array_to_member_list() use the correct type for netgroups and
+ user groups.
+ [359947d19131]
+
+ * plugins/sudoers/fmtsudoers.c:
+ Prepend digest to command if present. Fix printing of group IDs and
+ non-unix groups.
+ [5f9834b4bcbc]
+
+ * plugins/sudoers/cvtsudoers_json.c:
+ Fix gcc false positive for uninitialized variable
+ [d250b862c1ed]
+
+2018-02-20 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * pp:
+ Update Polypkg to the latest version from git.
+ [204ebffb502f]
+
+ * config.h.in, configure, configure.ac, src/sudo.c:
+ Use setpassent() and setgroupent() on systems that support it to
+ keep the passwd and group database open. Sudo does a lot of passwd
+ and group lookups so it can be beneficial to just leave the file
+ open.
+ [3d2d5bca9670]
+
+2018-02-19 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers_json.c,
+ plugins/sudoers/cvtsudoers_ldif.c, plugins/sudoers/fmtsudoers.c:
+ Add option to cvtsudoers to expand aliases in the output.
+ [1af56459fd7d]
+
+ * plugins/sudoers/cvtsudoers_json.c,
+ plugins/sudoers/regress/sudoers/test1.json.ok,
+ plugins/sudoers/regress/sudoers/test14.json.ok,
+ plugins/sudoers/regress/sudoers/test15.json.ok,
+ plugins/sudoers/regress/sudoers/test16.json.ok,
+ plugins/sudoers/regress/sudoers/test17.json.ok,
+ plugins/sudoers/regress/sudoers/test19.json.ok,
+ plugins/sudoers/regress/sudoers/test2.json.ok,
+ plugins/sudoers/regress/sudoers/test6.json.ok:
+ Fix conversion of "ALL" in the JSON output format, which was being
+ printed as an alias.
+ [3f7869688820]
+
+ * INSTALL, configure, configure.ac:
+ Clarify that --with-rundir and --with-vardir take sudo-specific
+ directory, e.g. /var/run/sudo and not just /var/run. Bug #823
+ [e1913085e544]
+
+ * src/exec_pty.c:
+ In pty_cleanup() we need to call sudo_term_restore() even if no I/O
+ plugins are present as long as /dev/tty exists. Fixes the use_pty
+ case with no I/O plugins.
+ [82fecef72998]
+
+ * include/sudo_event.h, lib/util/event.c, lib/util/util.exp.in,
+ plugins/sudoers/sudoreplay.c, src/exec_monitor.c, src/exec_nopty.c,
+ src/exec_pty.c:
+ Add sudo_ev_dispatch(), a wrapper for ev_loop() with no flags.
+ Similar the dispatch function in libevent.
+ [61e588fd50d0]
+
+ * INSTALL, configure, configure.ac, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, m4/sudo.m4:
+ Use /run in preference to /var/run if it exists. Bug #822
+ [ec2febe6f8a3]
+
+2018-02-14 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS:
+ mention common sudoers formatting changes
+ [b32825ca3e2f]
+
+2018-02-11 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * MANIFEST, configure, configure.ac, mkdep.pl,
+ plugins/sudoers/Makefile.in, plugins/sudoers/ldap.c,
+ plugins/sudoers/ldap_conf.c, plugins/sudoers/sudo_ldap.h,
+ plugins/sudoers/sudo_ldap_conf.h:
+ Move LDAP configuration bits into ldap_conf.c
+ [1673e3c7855a]
+
+2018-02-10 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/ldap_common.c:
+ No longer need to include stddef.h
+ [a10a13dc73c7]
+
+ * plugins/sudoers/iolog.c:
+ Remove dead store, found by cppcheck.
+ [744e99ffc82e]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/ldap_common.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudo_ldap.h:
+ simplify iterator
+ [944fd546ec98]
+
+ * plugins/sudoers/mkdir_parents.c:
+ Silence a false positive from cppcheck.
+ [f94421968d8e]
+
+ * plugins/sudoers/tsdump.c:
+ Cast version to int when printing. Avoids a cppcheck warning.
+ [3312bec4f1e3]
+
+2018-02-09 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/ldap_common.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudo_ldap.h:
+ Use an iterator instead of fragile pointer arithmetic to iterate
+ over value arrays in sudo_ldap_role_to_priv().
+ [61752c5f3427]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/fmtsudoers.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/parse.c, plugins/sudoers/parse.h,
+ plugins/sudoers/sssd.c:
+ Move sudoers formatting code into fmtsudoers.
+ [ff25291c99f4]
+
+ * plugins/sudoers/cvtsudoers.c, plugins/sudoers/parse.c:
+ Clean up some XXX in parse.c
+ [19854e7d8ac7]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/sssd.c:
+ Rename sudo_file_append_default() -> sudo_lbuf_append_default() and
+ use it for ldap and sssd too.
+ [dae22810f2dd]
+
+ * MANIFEST, configure, configure.ac, mkdep.pl,
+ plugins/sudoers/Makefile.in, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/ldap.c,
+ plugins/sudoers/ldap_common.c, plugins/sudoers/parse.h,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudo_ldap.h:
+ Move common bits of ldap to sudoers conversion into ldap_common.c
+ and use it in sssd.c.
+ [5cca03f64b77]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/ldap.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h:
+ Convert ldap results into a sudoers userspec so we can use the "sudo
+ -l" output functions in parse.c.
+ [1422e10dc274]
+
+2018-02-08 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * sudo.pp:
+ Don't mark sudoers.dist volatile, it only gets used on systems that
+ don't have the concept of volatile files.
+ [c47fd17e62e3]
+
+2018-02-05 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/parse.h:
+ Refactor member freeing code into free_member(). Refactor userspec
+ freeing code into free_userspec().
+ [ccc95e8b9f69]
+
+ * plugins/sudoers/cvtsudoers.c:
+ Fix compilation with glibc where stdout is not constant.
+ [97a0302c29c8]
+
+2018-02-04 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/ldap.c:
+ For "sudo -l", if a word includes spaces, print it in double quotes.
+ Also escape spaces in the command path. This matches the sudoers
+ quoting rules.
+ [04ace6decf3a]
+
+2018-02-03 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/ldap.c:
+ Display sudoNotBefore and sudoNotAfter in "sudo -l"
+ [ef7de4c8aa9e]
+
+ * plugins/sudoers/parse.c:
+ For "sudo -l", if a word includes spaces, print it in double quotes.
+ Also escape spaces in the command path. This matches the sudoers
+ quoting rules.
+ [fa12a254657c]
+
+ * plugins/sudoers/cvtsudoers.c:
+ Add back printing of negation operator ('!') when printing a word
+ with spaces in it.
+ [c69706a91817]
+
+ * plugins/sudoers/Makefile.in:
+ Use visudo to validate "cvtsudoers -f sudoers" output.
+ [06bae7204926]
+
+ * plugins/sudoers/regress/sudoers/test21.in,
+ plugins/sudoers/regress/sudoers/test21.json.ok,
+ plugins/sudoers/regress/sudoers/test21.ldif.ok,
+ plugins/sudoers/regress/sudoers/test21.out.ok,
+ plugins/sudoers/regress/sudoers/test21.toke.ok:
+ Remove syslog_goodpri and syslog_badpri without a value that causes
+ visudo to report an error.
+ [c1f696e49f49]
+
+ * plugins/sudoers/cvtsudoers.c:
+ When outputting sudoers, if a word includes spaces, print it in
+ double quotes. Also escape spaces in the command path.
+ [d040c1a21277]
+
+2018-02-02 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/alias.c, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/parse.h, plugins/sudoers/visudo.c:
+ Add sudoers output format to cvtsudoers. In the future this may be
+ used with filters to emit a partial sudoers file instead of a full
+ one.
+ [533d2c389213]
+
+ * plugins/sudoers/parse.c:
+ When printing a member name, quote sudoers special characters unless
+ it is a UID/GID, in which case we print the '#' unquoted.
+ [e4e8154c4fe9]
+
+ * plugins/sudoers/parse.c, plugins/sudoers/parse.h:
+ Move SUDOERS_QUOTED define to parse.h
+ [a813ec4acb5f]
+
+2018-01-30 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/timestamp.c:
+ Remove extraneous break statement and fix some whitespace.
+ [39df566c33e3]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ The max timeout for kernel time stamps is 60 minutes, not 3600
+ minutes.
+ [95be88c4f106]
+
+2018-01-29 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/testsudoers.c:
+ Check the return value of sudoers_debug_register(). Coverity CID
+ 182574
+ [fb5449acdafd]
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ Fix memory leak, su->count is now 0 when it is unused, not 1.
+ Covertity CID 182573
+ [77019ded8f84]
+
+ * plugins/sudoers/cvtsudoers_ldif.c:
+ Quiet a clang analyzer false positive.
+ [ef04f7069df4]
+
+ * plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/regress/sudoers/test2.ldif.ok,
+ plugins/sudoers/regress/sudoers/test6.ldif.ok:
+ Quote special characters when creating the cn as per RFC2253
+ [e49ff28c1fd7]
+
+ * NEWS, configure, configure.ac, doc/UPGRADE:
+ Sudo 1.8.23
+ [e364ed057d1d]
+
+ * doc/LICENSE:
+ Remove the C-style comment charactes from the getopt_long.c and
+ inet_pton.c license text as it was inconsistent with the rest of the
+ file and messed up the html formatting.
+ [a26679d2d0a7]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/sudoers2ldif,
+ sudo.pp:
+ Remove sudoers2ldif, it has been replaced by cvtsudoers.
+ [7563cc3768c2]
+
+2018-01-28 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers_ldif.c:
+ Add -b option to specify the base dn.
+ [7cd4c46c33bf]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in:
+ Document limitations of LDIF conversion.
+ [e8c84362f084]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/cvtsudoers.c:
+ Switch the default output format to LDIF
+ [a677c7b72a90]
+
+ * plugins/sudoers/visudo.c:
+ Execute cvtsudoers if the user runs "visudo -x" but also emit a
+ warning.
+ [53ec45a847d2]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/stubs.c,
+ plugins/sudoers/visudo.c:
+ Revert 04ec05108b2b, change the default input source back to stdin.
+ [df8d94f1bab4]
+
+ * MANIFEST, plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/sudoers/test1.ldif.ok,
+ plugins/sudoers/regress/sudoers/test10.ldif.ok,
+ plugins/sudoers/regress/sudoers/test11.ldif.ok,
+ plugins/sudoers/regress/sudoers/test12.ldif.ok,
+ plugins/sudoers/regress/sudoers/test13.ldif.ok,
+ plugins/sudoers/regress/sudoers/test14.ldif.ok,
+ plugins/sudoers/regress/sudoers/test15.ldif.ok,
+ plugins/sudoers/regress/sudoers/test16.ldif.ok,
+ plugins/sudoers/regress/sudoers/test17.ldif.ok,
+ plugins/sudoers/regress/sudoers/test18.ldif.ok,
+ plugins/sudoers/regress/sudoers/test19.ldif.ok,
+ plugins/sudoers/regress/sudoers/test2.ldif.ok,
+ plugins/sudoers/regress/sudoers/test20.ldif.ok,
+ plugins/sudoers/regress/sudoers/test21.ldif.ok,
+ plugins/sudoers/regress/sudoers/test3.ldif.ok,
+ plugins/sudoers/regress/sudoers/test4.ldif.ok,
+ plugins/sudoers/regress/sudoers/test5.ldif.ok,
+ plugins/sudoers/regress/sudoers/test6.ldif.ok,
+ plugins/sudoers/regress/sudoers/test7.ldif.ok,
+ plugins/sudoers/regress/sudoers/test8.ldif.ok,
+ plugins/sudoers/regress/sudoers/test9.ldif.ok:
+ Add LDIF conversion to sudoers tests
+ [997b79da8874]
+
+ * plugins/sudoers/cvtsudoers_json.c,
+ plugins/sudoers/cvtsudoers_ldif.c,
+ plugins/sudoers/regress/sudoers/test19.json.ok:
+ Add notbefore and notafter support to the backends.
+ [be50db300eda]
+
+2018-01-27 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * README.LDAP:
+ cvtsudoers instead of sudoers2ldif
+ [3909ea2c29c1]
+
+ * MANIFEST, doc/cvtsudoers.cat, doc/cvtsudoers.man.in,
+ doc/cvtsudoers.mdoc.in, plugins/sudoers/Makefile.in,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers_ldif.c:
+ Add ldif backend to cvtsudoers, to replace sudoers2ldif
+ [f0e039c63488]
+
+ * plugins/sudoers/Makefile.in:
+ fix make check
+ [2cbedce72e3a]
+
+2018-01-26 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers_json.c:
+ Parse sudoers in the front end, not the back end.
+ [30d4e40ed69a]
+
+ * doc/Makefile.in:
+ install the cvtsudoers manual
+ [243d319fed1c]
+
+ * doc/cvtsudoers.cat, doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/stubs.c,
+ plugins/sudoers/visudo.c:
+ Use the built-in sudoers file location as the default sudoers file
+ for cvtsudoers and move parse_sudoers_options() to stubs.c since it
+ is shared between visudo.c and cvtsudoers.c.
+ [04ec05108b2b]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/cvtsudoers.c,
+ plugins/sudoers/stubs.c, plugins/sudoers/visudo.c:
+ Move common stub functions required by the parser out of visudo.c
+ and cvtsudoers.c and into stubs.c.
+ [a324cbde55a3]
+
+ * plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers_json.c:
+ Rename export_sudoers() to convert_sudoers_json() and move the check
+ for the same input and output file to the front-end.
+ [7c83c21ea479]
+
+ * sudo.pp:
+ add cvtsudoers
+ [e8ba851cafb4]
+
+ * MANIFEST, doc/Makefile.in, doc/cvtsudoers.cat,
+ doc/cvtsudoers.man.in, doc/cvtsudoers.mdoc.in, doc/visudo.cat,
+ doc/visudo.man.in, doc/visudo.mdoc.in, plugins/sudoers/Makefile.in,
+ plugins/sudoers/cvtsudoers.c, plugins/sudoers/cvtsudoers_json.c,
+ plugins/sudoers/visudo.c, plugins/sudoers/visudo_json.c:
+ Move sudoers JSON conversion to cvtsudoers which will eventually
+ output to other formats too.
+ [e64a50657a88]
+
+ * plugins/sudoers/defaults.c:
+ Convert from time in minutes to timespec directly instead of
+ converting to double via strtod(). This makes it easier to catch
+ overflow.
+ [0d6ab7c21a15]
+
+2018-01-24 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ document that kernel tty timestamps don't support negative timeouts
+ [4ff726cf2010]
+
+2018-01-23 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/timestamp.c:
+ Fall back to ppid time stamps if timestamp_type == kernel and no tty
+ is present. This is consistent with timestamp_type == tty.
+ [26c527166a0c]
+
+ * plugins/sudoers/timestamp.c:
+ Do not call the TIOCSETVERAUTH ioctl with a negative number of
+ seconds. Also cap the max number of seconds at 3600 to avoid getting
+ EINVAL from TIOCSETVERAUTH.
+ [371744874743]
+
+2018-01-22 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/defaults.c:
+ Better conversion from double to nanoseconds.
+ [2f54790801c8]
+
+ * plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/securid5.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/auth/sudo_auth.h,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/defaults.c,
+ plugins/sudoers/defaults.h, plugins/sudoers/mkdefaults,
+ plugins/sudoers/timestamp.c:
+ Store passwd_timeout and timestamp_timeout as a struct timespec
+ instead of as a float. Remove timeout argument to auth_getpass() as
+ it was never used.
+ [c4a3c60d0284]
+
+2018-01-21 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/mkdefaults:
+ Don't rely on perl being installed in /usr/local/bin
+ [e3274f56df43]
+
+2018-01-17 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * config.h.in, configure, configure.ac, lib/util/gettime.c,
+ lib/util/mktemp.c, lib/util/nanosleep.c, lib/util/utimens.c,
+ plugins/sudoers/boottime.c, plugins/sudoers/check.c,
+ plugins/sudoers/getdate.c, plugins/sudoers/getdate.y,
+ plugins/sudoers/group_plugin.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/visudo.c, src/net_ifs.c, src/sesh.c, src/sudo.c,
+ src/sudo_edit.c, src/utmp.c:
+ Remove use of AC_HEADER_TIME, only obsolete platforms actually need
+ this. Also stop removing sys/time.h unless the source file uses
+ struct timeval.
+ [a744b8a07685]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y:
+ Remove duplicate options %type
+ [3ea3c3d477bf]
+
+2018-01-16 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/auth/API, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/auth/sudo_auth.h, plugins/sudoers/check.c,
+ plugins/sudoers/sudoers.h:
+ Add an approval function to the sudo auth API which is run after the
+ user's password has been verified. The approval function is run even
+ if no password is required. This is currently only used for PAM (use
+ pam_acct_mgmt) and BSD auth (auth_approval).
+ [cab448ac8633]
+
+2018-01-15 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/tsdump.c:
+ treat uid as unsigned in error message
+ [2672d4ca3479]
+
+ * MANIFEST, plugins/sudoers/po/fur.mo:
+ Add missing plugins/sudoers/po/fur.mo file to repo.
+ [cfa503d7fcd4]
+
+ * NEWS:
+ Mention new sudoers_timestamp manual.
+ [f96ad00c4ba4]
+
+2018-01-12 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * .hgignore:
+ ignore tsdump
+ [39306d37c846]
+
+ * plugins/sudoers/tsdump.c:
+ Convert from mono time to real time before displaying time stamps.
+ [12f9e1f5e8e5]
+
+2018-01-11 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/solaris_audit.c:
+ Use PATH_MAX, not MAXPATHLEN.
+ [d3c7466aad1d]
+
+ * MANIFEST, config.h.in, configure, configure.ac, include/sudo_util.h,
+ lib/util/Makefile.in, lib/util/ttyname_dev.c, lib/util/util.exp.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/check.h,
+ plugins/sudoers/tsdump.c, src/ttyname.c:
+ Add tsdump, a simple utility to dump a timestamp file. To build, run
+ "make tsdump" in the plugins/sudoers directory (it is not built by
+ default). In order to map the tty device number to a name,
+ sudo_ttyname_dev() has been moved into libsudo_util.
+ [b79ae30fe6a4]
+
+2018-01-04 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po, po/uk.mo,
+ po/uk.po:
+ sync with translationproject.org
+ [71140a551c60]
+
+ * doc/LICENSE:
+ Welcome to 2018
+ [3ddea360d414]
+
+2017-12-28 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/fur.po, plugins/sudoers/po/nb.mo,
+ plugins/sudoers/po/nb.po, plugins/sudoers/po/zh_CN.mo,
+ plugins/sudoers/po/zh_CN.po:
+ sync with translationproject.org
+ [fbd54c7f59f1]
+
+2017-12-22 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/logging.c:
+ Silence a clang analyzer false positive.
+ [bfcdfe2c1376]
+
+ * doc/Makefile.in:
+ Remove extra $(srcdir)/sudoreplay.man.in target added by mistake.
+ [7e83806cc17e]
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/hr.mo, plugins/sudoers/po/hr.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/nl.mo, plugins/sudoers/po/nl.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/sv.mo, plugins/sudoers/po/sv.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po, po/ja.mo,
+ po/ja.po:
+ sync with translationproject.org
+ [27cf5abeeb1a]
+
+ * plugins/sudoers/timestamp.c:
+ Use a tty lock even for kernel time stamps so we can avoid
+ simultaneous password prompts.
+ [90a55098176b]
+
+ * NEWS:
+ visudo changes
+ [06c99aab6f7a]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in,
+ plugins/sudoers/editor.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/visudo.c:
+ Also honor SUDO_EDITOR in visudo. Previously is was only used by
+ sudoedit.
+ [9bccc7171a53]
+
+2017-12-21 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/sudoers.c:
+ Stop looking for an editor as soon as we find one. A similar fix was
+ made to visudo some time ago.
+ [c6c5d968612a]
+
+ * doc/sudoers_timestamp.cat, doc/sudoers_timestamp.man.in,
+ doc/sudoers_timestamp.mdoc.in:
+ The session ID was added in 1.8.6p7 to prevent a user in another
+ session from re-using the time stamp file. Other minor cleanups.
+ [f733f7ea97a7]
+
+ * plugins/sudoers/check.h:
+ "time stamp" not "timestamp"
+ [af0f2d8b6d52]
+
+2017-12-20 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS, doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/timestamp.c:
+ Add "kernel" as a possible value of timestamp_type. Currently only
+ supported on OpenBSD.
+ [ca1a2a03e37d]
+
+ * MANIFEST, doc/Makefile.in, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in, doc/sudoers_timestamp.cat,
+ doc/sudoers_timestamp.man.in, doc/sudoers_timestamp.mdoc.in,
+ plugins/sudoers/check.h:
+ Document the sudoers time stamp file format.
+ [d3470da8fde9]
+
+2017-12-19 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/regress/starttime/check_starttime.c:
+ Verify start time of the current process, allowing for some clock
+ drift. For Linux, process start time is relative to boot time, not
+ wallclock time.
+ [4928645eaa1c]
+
+2017-12-18 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * NEWS:
+ sync
+ [aeffb7f82e10]
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [8be51858eec1]
+
+ * MANIFEST, plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/starttime/check_starttime.c:
+ Trivial test for process start time. We don't try to check the
+ resulting timespec as it differs by platform. On most it is
+ wallclock time, on others it is relative to boot time (Linux).
+ [e74cf3bd4c87]
+
+ * lib/util/Makefile.in:
+ regen
+ [6de26735d666]
+
+2017-12-17 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/starttime.c:
+ Support start time on macOS and 4.4BSD
+ [81f2eebc7edb]
+
+2017-12-16 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/regress/env_match/check_env_pattern.c:
+ Include sys/types.h for mode_t used in sudoers.h.
+ [bdff1606f111]
+
+ * plugins/sudoers/starttime.c:
+ Fix compilation error on FreeBSD
+ [2c4962a7812c]
+
+ * plugins/sudoers/starttime.c:
+ Fix debug_decl(), it should be SUDOERS_DEBUG_UTIL Add debugging for
+ the successful case For Linux, don't NUL out *ep before parsing with
+ strtoull().
+ * * * Add missing debug info for the System V /proc version.
+ [2394c6d9375d]
+
+ * MANIFEST, doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/check.h,
+ plugins/sudoers/starttime.c, plugins/sudoers/timestamp.c:
+ In the timestamp record, include the start time of the terminal
+ session leader for tty-based timestamps or the start time of the
+ parent process for ppid-based timestamps. Idea from Duncan
+ Overbruck.
+ [f0964b4cf4ac]
+
+2017-12-15 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/timestamp.c:
+ If the lock record doesn't match the expected record size we need to
+ seek to the end of the record as we otherwise may have gone too far
+ (or not far enough). Fixes interop problems when the time stamp
+ record changes size.
+ [e8e4c3815db5]
+
+2017-12-12 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * src/exec_pty.c:
+ No need for a loop around the recv() now that we don't have to worry
+ about EINTR. CID 180697
+ [7cb966d69bc6]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Try to be clearer about sudo's exit value when the -l option is
+ used.
+ [efbddaa576a7]
+
+ * NEWS:
+ sync
+ [99fc4b347250]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, plugins/sudoers/ldap.c,
+ plugins/sudoers/sssd.c:
+ An empty RunAsUser means run as the invoking user, similar to how
+ the sudoers files works.
+ [576172386594]
+
+ * doc/sudoers.cat, doc/sudoers.man.in:
+ regen
+ [9b6d0064f410]
+
+2017-12-11 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/logging.c:
+ Add authfail_message sudoers option to allow the user to override
+ the default message of %d incorrect password attempt(s).
+ [f11e9d64a6da]
+
+ * plugins/sudoers/policy.c, src/parse_args.c:
+ Allow the plugin to determine whether or not an empty timeout is
+ allowed. For sudoers, an error will be returned for an empty
+ timeout.
+ [26511c049fb1]
+
+ * plugins/sudoers/timeout.c:
+ Return an error for an empty timeout string. Just use strtol() for
+ syntax checking instead of scanning with strspn().
+ [1fa1b712fbcc]
+
+ * src/parse_args.c, src/sudo_edit.c:
+ Change some _() into U_() since they are used for warn/fatal. We
+ always want to issue warnings in the user's locale.
+ [684331aee66e]
+
+ * Makefile.in:
+ update my email address
+ [b4ec26be6203]
+
+2017-12-10 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * log2cl.pl:
+ Don't print mercurial branch info for merges.
+ [489881774e52]
+
+ * log2cl.pl:
+ Use log size instead of using a separator between the log entry and
+ the file names.
+ [620c231f789b]
+
+ * src/parse_args.c:
+ Print usage and return an error when an empty argument is given for
+ all command line arguments other than -p and -E. Bug #817
+ [143be1bc8316]
+
+ * plugins/sudoers/policy.c:
+ Better input validation of settings passed by the sudo front-end.
+ Instead of ignoring an empty setting, throw an error.
+ [93cc4f4761f3]
+
+ * log2cl.pl:
+ Treat a blank line in a commit message as a line break. There
+ doesn't appear to be a way to make perl's format use a blank field
+ but at least the line break happens now.
+ [fbc3ff819341]
+
+2017-12-09 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * MANIFEST, Makefile.in, log2cl.pl:
+ Add script to generate ChangeLog from git log output.
+ [e8bfbd1ae6ef]
+
+2017-12-08 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/logging.c,
+ plugins/sudoers/logging.h:
+ Don't include syslog.h from logging.h, just include it in the two .c
+ files it is actually needed.
+ [9ffc5ca9eb49]
+
+2017-12-06 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in:
+ Document that in check mode, visudo does not check the owner/mode on
+ files specified with the -f flag.
+ [f5d86019e4c7]
+
+2017-12-03 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * Makefile.in, configure.ac, doc/HISTORY, doc/LICENSE,
+ doc/Makefile.in, doc/fixman.sh, doc/fixmdoc.sh,
+ doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in, doc/sudo.man.in,
+ doc/sudo.mdoc.in, doc/sudo_plugin.man.in, doc/sudo_plugin.mdoc.in,
+ doc/sudoers.ldap.man.in, doc/sudoers.ldap.mdoc.in,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, doc/sudoreplay.man.in,
+ doc/sudoreplay.mdoc.in, doc/visudo.man.in, doc/visudo.mdoc.in,
+ examples/Makefile.in, include/Makefile.in,
+ include/compat/charclass.h, include/compat/endian.h,
+ include/compat/fnmatch.h, include/compat/nss_dbdefs.h,
+ include/compat/sha2.h, include/sudo_compat.h, include/sudo_conf.h,
+ include/sudo_debug.h, include/sudo_dso.h, include/sudo_event.h,
+ include/sudo_fatal.h, include/sudo_gettext.h, include/sudo_lbuf.h,
+ include/sudo_plugin.h, include/sudo_util.h, lib/util/Makefile.in,
+ lib/util/aix.c, lib/util/closefrom.c, lib/util/event.c,
+ lib/util/event_poll.c, lib/util/event_select.c, lib/util/fatal.c,
+ lib/util/getgrouplist.c, lib/util/gethostname.c, lib/util/getline.c,
+ lib/util/getopt_long.c, lib/util/gettime.c, lib/util/gidlist.c,
+ lib/util/glob.c, lib/util/isblank.c, lib/util/key_val.c,
+ lib/util/lbuf.c, lib/util/locking.c, lib/util/memrchr.c,
+ lib/util/memset_s.c, lib/util/mksiglist.c, lib/util/mksigname.c,
+ lib/util/mktemp.c, lib/util/nanosleep.c, lib/util/parseln.c,
+ lib/util/pipe2.c, lib/util/progname.c, lib/util/pw_dup.c,
+ lib/util/regress/atofoo/atofoo_test.c,
+ lib/util/regress/fnmatch/fnm_test.c,
+ lib/util/regress/glob/globtest.c,
+ lib/util/regress/parse_gids/parse_gids_test.c,
+ lib/util/regress/progname/progname_test.c,
+ lib/util/regress/strsplit/strsplit_test.c,
+ lib/util/regress/sudo_conf/conf_test.c,
+ lib/util/regress/sudo_parseln/parseln_test.c,
+ lib/util/regress/tailq/hltq_test.c,
+ lib/util/regress/vsyslog/vsyslog_test.c, lib/util/secure_path.c,
+ lib/util/setgroups.c, lib/util/sha2.c, lib/util/sig2str.c,
+ lib/util/snprintf.c, lib/util/strlcat.c, lib/util/strlcpy.c,
+ lib/util/strndup.c, lib/util/strnlen.c, lib/util/strsignal.c,
+ lib/util/strsplit.c, lib/util/strtobool.c, lib/util/strtoid.c,
+ lib/util/strtomode.c, lib/util/strtonum.c, lib/util/sudo_conf.c,
+ lib/util/sudo_debug.c, lib/util/sudo_dso.c, lib/util/term.c,
+ lib/util/ttysize.c, lib/util/utimens.c, lib/util/vsyslog.c,
+ lib/zlib/Makefile.in, m4/sudo.m4, mkdep.pl, mkpkg, pathnames.h.in,
+ plugins/group_file/Makefile.in, plugins/group_file/getgrent.c,
+ plugins/group_file/group_file.c, plugins/group_file/plugin_test.c,
+ plugins/sample/Makefile.in, plugins/sample/sample_plugin.c,
+ plugins/sudoers/Makefile.in, plugins/sudoers/alias.c,
+ plugins/sudoers/audit.c, plugins/sudoers/auth/afs.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/dce.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/auth/sudo_auth.h, plugins/sudoers/base64.c,
+ plugins/sudoers/boottime.c, plugins/sudoers/bsm_audit.c,
+ plugins/sudoers/bsm_audit.h, plugins/sudoers/check.c,
+ plugins/sudoers/check.h, plugins/sudoers/defaults.c,
+ plugins/sudoers/defaults.h, plugins/sudoers/digestname.c,
+ plugins/sudoers/editor.c, plugins/sudoers/env.c,
+ plugins/sudoers/env_pattern.c, plugins/sudoers/filedigest.c,
+ plugins/sudoers/filedigest_gcrypt.c,
+ plugins/sudoers/filedigest_openssl.c, plugins/sudoers/find_path.c,
+ plugins/sudoers/gc.c, plugins/sudoers/gentime.c,
+ plugins/sudoers/getspwuid.c, plugins/sudoers/gmtoff.c,
+ plugins/sudoers/goodpath.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/hexchar.c, plugins/sudoers/ins_2001.h,
+ plugins/sudoers/ins_classic.h, plugins/sudoers/ins_csops.h,
+ plugins/sudoers/ins_goons.h, plugins/sudoers/insults.h,
+ plugins/sudoers/interfaces.c, plugins/sudoers/interfaces.h,
+ plugins/sudoers/iolog.c, plugins/sudoers/iolog.h,
+ plugins/sudoers/iolog_path.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/linux_audit.h,
+ plugins/sudoers/locale.c, plugins/sudoers/logging.c,
+ plugins/sudoers/logging.h, plugins/sudoers/logwrap.c,
+ plugins/sudoers/match.c, plugins/sudoers/match_addr.c,
+ plugins/sudoers/mkdir_parents.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/po/sudoers.pot,
+ plugins/sudoers/policy.c, plugins/sudoers/prompt.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/pwutil.h,
+ plugins/sudoers/pwutil_impl.c, plugins/sudoers/rcstr.c,
+ plugins/sudoers/redblack.c, plugins/sudoers/redblack.h,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/env_match/check_env_pattern.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/regress/parser/check_base64.c,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/regress/parser/check_gentime.c,
+ plugins/sudoers/regress/parser/check_hexchar.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudo_nss.h,
+ plugins/sudoers/sudo_printf.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoers2ldif,
+ plugins/sudoers/sudoers_debug.c, plugins/sudoers/sudoers_debug.h,
+ plugins/sudoers/sudoers_version.h, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/timeout.c,
+ plugins/sudoers/timestamp.c, plugins/sudoers/timestr.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.h,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c,
+ plugins/sudoers/tsgetgrpw.c, plugins/sudoers/tsgetgrpw.h,
+ plugins/sudoers/visudo.c, plugins/sudoers/visudo_json.c,
+ plugins/system_group/Makefile.in,
+ plugins/system_group/system_group.c, po/sudo.pot, src/Makefile.in,
+ src/conversation.c, src/env_hooks.c, src/exec.c, src/exec_common.c,
+ src/exec_monitor.c, src/exec_nopty.c, src/exec_pty.c, src/get_pty.c,
+ src/hooks.c, src/load_plugins.c, src/net_ifs.c, src/openbsd.c,
+ src/parse_args.c, src/preload.c, src/preserve_fds.c,
+ src/regress/noexec/check_noexec.c,
+ src/regress/ttyname/check_ttyname.c, src/selinux.c, src/sesh.c,
+ src/signal.c, src/solaris.c, src/sudo.c, src/sudo.h,
+ src/sudo_edit.c, src/sudo_exec.h, src/sudo_noexec.c,
+ src/sudo_plugin_int.h, src/sudo_usage.h.in, src/tcsetpgrp_nobg.c,
+ src/tgetpass.c, src/ttyname.c, src/utmp.c, sudo.pp:
+ update my email to Todd.Miller@sudo.ws
+ [96110003e904]
+
+2017-12-02 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/sudoreplay.c:
+ Add missing carriage return before prompt when replay is done.
+ [cf4b8bfcb3dd]
+
+ * src/exec_pty.c:
+ Track window size changes that happen while sudo is suspended
+ [cae06f75bde9]
+
+2017-12-01 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [26ae754b8416]
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo_plugin.cat,
+ doc/sudoers.cat, doc/sudoers.ldap.cat, doc/sudoreplay.cat,
+ doc/visudo.cat:
+ regen for sudo 1.8.22
+ [596d82da0158]
+
+ * NEWS, configure, configure.ac:
+ Sudo 1.8.22
+ [6b32c2f5d020]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Background processes started by the command will no longer receive
+ SIGHUP.
+ [47bcc3ae4362]
+
+ * src/exec_monitor.c:
+ When the command completes, make the monitor the foreground process
+ group before informing the main sudo process of the command's exit
+ status. This will prevent processes started by the command (which
+ runs in a different process group) from receiving SIGHUP since the
+ kernel sends SIGHUP to the foreground process group associated with
+ the terminal session. The monitor has a SIGHUP handler installed so
+ the signal is effectively ignored.
+ [9e163efe4afb]
+
+ * src/sudo.c:
+ Add debug printfs around group list retrieval.
+ [5f307b00153b]
+
+2017-11-30 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * src/exec_pty.c:
+ Move call to sudo_ev_loopcontinue() into schedule_signal() itself.
+ We always want to prioritize signal forwarding.
+ [4b25dc24038b]
+
+ * src/exec_monitor.c, src/exec_nopty.c, src/exec_pty.c:
+ Don't loop over read/write, recv/send or tcgetpgrp/tcsetpgrp trying
+ to handle EINTR. We now use SA_RESTART with signals so this is not
+ needed and is potentially dangerous if it is possible to receive
+ SIGTTIN or SIGTTOU (which it currently is not).
+ [ba6885b57891]
+
+2017-11-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Better describe things when a command is run in a pty.
+ [0f34fc342ab5]
+
+2017-11-29 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * src/exec_monitor.c, src/signal.c:
+ Sprinkle some extra debugging printfs
+ [bf33574bc603]
+
+ * src/exec_pty.c:
+ Handle receipt of SIGTTIN/SIGTTOU when reading/writing from/to the
+ tty. We can't use a signal event for these since that would restart
+ the system call after the signal was handled and the callback would
+ not get a chance to run. Fixes running a command in the background
+ that write to the tty when the TOSTOP terminal flag is set.
+ [5ac68f05249a]
+
+ * src/exec_pty.c:
+ We don't need to be the foreground process to be able to write to
+ the terminal in most cases. If the background process tries to
+ modify the terminal flags it will receive SIGTTOU which is relayed
+ to the sudo front-end. This currently mishandles terminals with the
+ TOSTOP local flag set.
+ [3fc25570d482]
+
+2017-11-28 Todd C. Miller <Todd.Miller@sudo.ws>
+
+ * plugins/sudoers/sssd.c:
+ Avoid a double free when ipa_hostname is set in sssd.conf and it is
+ an unqualified host name. From Daniel Kopecek.
+
+ Also move the "unable to allocate memory" warning into
+ get_ipa_hostname() itself to make it easier to see where the
+ allocation failed in the debug log.
+ [14dacdea3319]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/policy.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/pwutil.h,
+ plugins/sudoers/pwutil_impl.c, plugins/sudoers/set_perms.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ When running a command as the invoking user we cannot use the gid
+ list from the front-end since it may not correspond to the user's
+ aux group vector as defined by the group database.
+ [b456101fe509]
+
+ * lib/util/regress/fnmatch/fnm_test.c,
+ lib/util/regress/glob/globtest.c,
+ plugins/sudoers/regress/env_match/check_env_pattern.c,
+ plugins/sudoers/regress/parser/check_base64.c,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/regress/parser/check_gentime.c,
+ plugins/sudoers/regress/parser/check_hexchar.c:
+ Add missing initprogname() calls.
+ [ad4f8d236d89]
+
+2017-11-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Plug some memory leaks on error, some found by the clang static
+ analyzer.
+ [62844cc145b6]
+
+2017-11-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/parse.c:
+ Avoid calling cmnd_matches() in list/verify mode if we already have
+ a match.
+ [5bddfc911065]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/parse.c,
+ plugins/sudoers/sssd.c:
+ In list (-l) or verify (-v) mode, if we have a match but
+ authentication is required, clear FLAG_NOPASSWD so that when
+ listpw/verifypw is set to "all" and there are multiple sudoers
+ sources a password will be required unless none of the entries in
+ all sources require authentication. From Radovan Sroka of RedHat
+ [edac7222600a]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ When checking the results for "sudo -l" and "sudo -v", keep checking
+ even after we get a match since the value of doauth may depend on
+ evaluating all the results. From Radovan Sroka of RedHat.
+ [ae0704445bd4]
+
+2017-11-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ If passwd_tries is less than 1, check_user() will always return
+ false (since the user didn't authenticate). The normal reason for
+ this is an authentication error but in this case no authentication
+ was tries so no warning message has been displayed to the user. If
+ the user wasn't given a chance to authenticate, set inform_user to
+ true when calling log_denial() from sudoers_policy_main().
+
+ An alternate approach would be for check_user() to return true in
+ this case but seems more confusing.
+ [c8be95b46e9d]
+
+2017-10-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/TROUBLESHOOTING:
+ Document bash shell alias issue with "sudo -i".
+ [8affa5376277]
+
+2017-10-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/policy.c:
+ Return an error if the sudo front end doesn't set the user name,
+ user ID, group ID or host name. Bug #807
+ [03e281d93fff]
+
+ * lib/util/gethostname.c:
+ Treat an empty hostname as a failure and return NULL.
+ [fafb3a3083cb]
+
+2017-10-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers2ldif:
+ Add support for #include and #includedir from Natale Vinto.
+ [926deea0d506]
+
+2017-10-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS:
+ Minor corrections from Tae Wong
+ [dbc5ee98ffa6]
+
+2017-10-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Add a warning that for "sudo -i command" and "sudo -s command" the
+ shell is not run in interactive mode which may change its behavior.
+ [76c19db05a1e]
+
+2017-09-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_compat.h, src/exec_pty.c:
+ Fix stair-stepped output when the output of a sudo command is piped
+ to another command and use_pty is set.
+ [e91e3f12d2d4]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ env_keep and env_check are also taken into account with "sudo -i".
+ Bug #806
+ [5f5568c6fdd9]
+
+2017-09-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, config.h.in, configure, configure.ac,
+ plugins/sudoers/ins_classic.h:
+ Make PC insults the default and add new configure option, enable-
+ offensive-insults, to enable the offensive insults.
+ [eb264d342601]
+
+2017-09-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS:
+ Add missing translators from recent updates and one name change.
+ [20828c25ad92]
+
+2017-09-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/po/fur.po, plugins/sudoers/po/hr.mo,
+ plugins/sudoers/po/hr.po, plugins/sudoers/po/sv.mo,
+ plugins/sudoers/po/sv.po, po/hr.mo, po/hr.po, po/sv.mo, po/sv.po:
+ sync with translationproject.org
+ * * * sync with translationproject.org
+ [24bb066fa19f]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ More accurately describe the use_pty option now that its behavior
+ has changed with respect to interposition with a pipe. Also describe
+ some caveats with log_input.
+ [a87056499931]
+
+ * doc/UPGRADE:
+ Document changes in use_pty behavior when no terminal is present.
+ [a4b978693178]
+
+ * src/exec_pty.c:
+ Set ec->cmnd_pid to the correct value when receiving the command's
+ process ID from the monitor.
+ [a624309ba848]
+
+ * src/exec.c, src/exec_nopty.c, src/exec_pty.c, src/sudo_exec.h:
+ If /dev/tty is not available and no I/O logging plugins are
+ configured, fall back on exec_nopty() even if the policy plugin
+ requested a pty. We never allocate a pty when sudo is not run from a
+ terminal anyway.
+ [c9b9c6c4e0ad]
+
+ * src/exec_pty.c:
+ Do not set utmp_user if we did not actually allocate a pty.
+ [aa8e0fdea32b]
+
+2017-09-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.ac:
+ sudo 1.8.21p2
+ [94d18888e7c4]
+
+ * src/exec.c:
+ sudo_terminated() should not return true when SIGCHLD is pending.
+ Bug #801
+ [57f636b6489f]
+
+ * src/tgetpass.c:
+ Set SIGCHLD handler to SIG_DFL before forking the askpass command
+ and restore after. Otherwise, SIGCHLD will end up in the list of
+ pending signals and sudo_execute() will not execute the command.
+ [c171eeabdc72]
+
+ * lib/util/event.c:
+ The read and write sides of signal_pipe[] were swapped, resulting in
+ EBADF reading from and writing to the signal pipe on Linux and
+ probably others. On systems with bidirectional pipes this was not an
+ issue.
+ [7668f93e6544]
+
+2017-09-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/pam.c:
+ Fix a logic error in 96651906de42 which prevented sudo from using
+ the PAM-supplied prompt. Bug #799
+ [6ee5cc13af69]
+
+2017-09-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.ac:
+ Sudo 1.8.21p1
+ [7e6bf56cb06c]
+
+ * mkpkg:
+ The Fedora sudo package uses /etc/ldap.conf not /etc/sudo-ldap.conf.
+ [7b4e6f50e138]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ The fix for matching when no sudoRunAsUser is present in a sudoRole
+ was incomplete. If no -g option was specified on the command line
+ but sudoRunAsGroup is present in a sudoRole, we need to treat the
+ group match as failed instead of missing.
+ [3aaeeebd924c]
+
+ * plugins/sudoers/check.c, plugins/sudoers/defaults.c:
+ Sprinkle a few more debugging printfs.
+ [f7a40f9985cf]
+
+ * plugins/sudoers/sudoreplay.c:
+ Fix replaying sessions that contain input logs. When the inter-
+ record timeout expires we need to read the next record if there is
+ nothing to output.
+ [443b329ddc60]
+
+ * doc/visudo.cat:
+ regen
+ [7ace4ac32116]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Fix typo (Auguest vs. August). From David Pocock.
+ [98a792ff1c90]
+
+2017-08-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudo_nss.c:
+ Go back to returning true from display_privs() on non-error. This
+ results in "sudo -U otheruser -l" exiting with a status of 0 even
+ when otheruser is not allowed to run commands. This is appropriate
+ since the "sudo -l" command was successful. This does not change the
+ exit value when otheruser runs "sudo -l" themselves, the exit status
+ will be 1 since that user is not allowed to run commands. Requested
+ by Radovan Sroka.
+ [055b78015fcb]
+
+ * plugins/sudoers/ldap.c:
+ Fix the pass2 ldap query string when no search filter is defined.
+ Due to the addition of "(sudoUser=*)" to the query we always need
+ the AND operator, even if no search filter is present.
+ [631243487d27]
+
+2017-08-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_nopty.c:
+ Don't forward SIGINFO to the child when it is send by the kernel
+ (not another user process). This is consistent with the handling of
+ other keyboard-generated signals such as SIGINT, SIGQUIT and
+ SIGTSTP. Bug #796
+ [29603b0a4315]
+
+2017-08-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Fix path to LICENSE and NEWS files that get used in the installer.
+ Previously, the installed versions were used instead of the ones in
+ the destdir.
+ [689a5806f2de]
+
+2017-08-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po, po/fi.mo,
+ po/fi.po:
+ sync with translationproject.org
+ [32a0f3bbba31]
+
+2017-08-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * po/es.mo, po/es.po:
+ sync with translationproject.org
+ [bfa5659d66f2]
+
+2017-08-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po, po/it.mo,
+ po/it.po:
+ sync with translationproject.org
+ [05cd6ff68a4b]
+
+2017-08-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Preserving environment variables on the command line was bug #279
+ [46f2c7931a84]
+
+2017-08-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, NEWS, doc/CONTRIBUTORS, po/fur.mo, po/fur.po:
+ Add Friulian translation for sudo from Fabio Tomat via
+ translationproject.org
+ [77fdb76e83c8]
+
+2017-08-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/ko.mo, plugins/sudoers/po/ko.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/sr.mo, plugins/sudoers/po/sr.po,
+ plugins/sudoers/po/sv.mo, plugins/sudoers/po/sv.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po, po/cs.mo,
+ po/cs.po, po/fr.mo, po/fr.po, po/ko.mo, po/ko.po, po/nb.mo,
+ po/nb.po, po/pl.mo, po/pl.po, po/pt_BR.mo, po/pt_BR.po, po/sr.mo,
+ po/sr.po, po/sv.mo, po/sv.po, po/vi.mo, po/vi.po, po/zh_CN.mo,
+ po/zh_CN.po:
+ sync with translationproject.org
+ [0f18e2f30ff5]
+
+2017-08-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ In the Runas example that uses "boulder" make it clear that
+ "boulder" is a host name.
+ [6bca59aa5579]
+
+2017-08-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [9bb78048656f]
+
+ * NEWS, doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in,
+ src/parse_args.c:
+ Allow the user to specify a list of environment variables to
+ preserve. This adds an option paramter to the --preserve-env option,
+ a comma-separated list of variable names.
+ [a6bc511a2e81]
+
+2017-08-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, NEWS, config.h.in, configure, configure.ac,
+ doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/defaults.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/timestamp.c:
+ Replace tty_tickets option with timestamp_type which can be global,
+ ppid or tty. Defaults to tty (no change in behavior). Some users
+ want the ppid behavior.
+ [426161a2e06f]
+
+ * lib/util/Makefile.in, plugins/sudoers/Makefile.in:
+ regen
+ [b396e70a4a8b]
+
+ * plugins/sudoers/sudoers.c:
+ Don't send email about an unresolvable host name if fqdn is enabled
+ and the user specified the run host via the -h flag.
+ [59d7a8743943]
+
+2017-07-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ fix playback of stdout/stderr without embedded carriage returns
+ [f1a5b47be2db]
+
+2017-07-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Avoid unused variable warning when sasl is not used.
+ [3010fd3c5a7f]
+
+ * INSTALL, configure, configure.ac:
+ Add support for --enable-sasl and --disable-sasl to make it possible
+ to enable/disable support for LDAP with SASL authentication. Sudo
+ compiles in support for SASL authentiation by default if the
+ ldap_sasl_interactive_bind_s() function is detected. Bug #788
+ [cf94d407d576]
+
+ * NEWS:
+ List the correct pattern ("*=()*") in the env_delete description.
+ Use pseudo-tty instead of pseudo terminal for consistency.
+ [f2df0baea2f0]
+
+2017-07-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/closefrom.c:
+ Include pathnames.h for /dev/fd on FreeBSD and Mac OS X.
+ [b190dc607277]
+
+ * NEWS:
+ update for 1.8.21
+ [a3a38f6cba66]
+
+ * src/exec_pty.c:
+ No need to call sudo_ev_del() before sudo_ev_free(); sudo_ev_free()
+ will delete the event from its base before freeing it.
+ [ebf3dedcba5c]
+
+ * src/exec_pty.c:
+ Terminate the command if an I/O log function returns 0 or -1. This
+ was mistakenly removed by 25b7fd056614 in Sudo 1.8.18 with the
+ removal of the ignore_iolog_errors variable.
+ [e1dd18d95815]
+
+ * plugins/sudoers/sudoreplay.c:
+ Quiet a coverity false positive.
+ [b7a9c9e35fd0]
+
+ * plugins/sudoers/sudoreplay.c:
+ Change to a single event loop in sudoreplay and use signal events.
+ [7320de46cf48]
+
+2017-07-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in:
+ start new sentences on a new line
+ [ae35ab253de5]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Clarify how the variable prompt options interact with each other and
+ PAM.
+ [342b936c4aaa]
+
+ * plugins/sudoers/sudoers.c:
+ Don't set passprompt_override when SUDO_PROMPT is present. This
+ effectively reverts ed77d255f383.
+
+ We treat the SUDO_PROMPT environment variable similar to passprompt
+ in sudoers: it will only override a PAM prompt if the PAM prompt is
+ either "Password:" or "username's Password:".
+ [6dad2bd126d1]
+
+2017-07-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/logging.c:
+ Add syslog_pid sudoers option to log sudo's process ID when logging
+ via syslog. This is disabled by default to match historic behavior.
+ [f4dc29b0052c]
+
+ * plugins/sudoers/auth/pam.c:
+ When deciding which prompt to use (PAM's or sudo's) treat the PAM
+ prompt "username's Password:" as equivalent to "Password:". Some PAM
+ modules (on AIX at least) use this prompt.
+ [96651906de42]
+
+ * plugins/sudoers/def_data.c, plugins/sudoers/def_data.in:
+ Add missing argument to a few of the defaults strings in the "sudo
+ -V" output.
+ [44546c4b87c3]
+
+ * plugins/sudoers/policy.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/visudo.c:
+ When examining environment variables or variables passed in from the
+ front-end, ignore variables with no value specified.
+ [8537a7fc6190]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Document that "-p prompt" overrides SUDO_PROMPT.
+ [d2e6b518d00d]
+
+ * plugins/sudoers/sudoers.c:
+ Enable passprompt_override by default if SUDO_PROMPT is present in
+ the environment. This is consistent with how "sudo -p prompt" is
+ handled.
+ [ed77d255f383]
+
+2017-07-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ When reading a single character via a switch() use "default: instead
+ of "case 1:" to quiet a coverity warning.
+ [ddcfc40159e4]
+
+ * plugins/sudoers/sudoreplay.c:
+ Initialize ch in getsize_cb() in case we are called with the wrong
+ initial state.
+ [a31431c59e14]
+
+ * plugins/sudoers/sudoreplay.c:
+ remove unused variable
+ [488054411049]
+
+ * plugins/sudoers/visudo.c:
+ Call install_sudoers() even when doedit is false. If a file in a
+ #includedir has a syntax error it will still have been edited and we
+ need to install the edited temp file.
+ [ab833e2d1791]
+
+ * plugins/sudoers/visudo.c:
+ Reparse sudoers if a new #include file was added. Otherwise the new
+ file will not get its syntax checked. Bug #791
+ [e584dc8bf306]
+
+2017-07-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ don't restore the cursor when setting terminal size, we don't want
+ the cursor to move
+ [9cbcb3372bcd]
+
+ * plugins/sudoers/sudoreplay.c:
+ Read the xterm terminal size using an event so we can easily time
+ out if needed.
+ [634524476741]
+
+ * lib/util/event.c, src/exec_nopty.c, src/exec_pty.c:
+ If we free the default base in sudo_ev_base_free(), reset the
+ default base to NULL.
+ [2a8f7938618b]
+
+2017-07-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_event.h, lib/util/event.c, lib/util/util.exp.in,
+ src/exec_monitor.c, src/exec_nopty.c, src/exec_pty.c:
+ Add the ability to set a default event base, to be used by plugins
+ which don't have access to the event base.
+ [dc159ea98b25]
+
+ * doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in,
+ plugins/sudoers/sudoreplay.c:
+ Allow sudoreplay to adjust the window size on xterm-like terminals.
+ [3358b1a9f01c]
+
+2017-07-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/sudoreplay.c:
+ Log window size change events in the sudoers I/O plugin. Let
+ sudoreplay parse a timing file with window change events (currently
+ ignored).
+ [a67f4627dfa7]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, include/sudo_plugin.h, src/exec_pty.c:
+ Pass window size change events to the plugin.
+ [529b5c9d16a4]
+
+ * lib/util/term.c:
+ Clear input, output, control and local flags before copying them
+ from the source terminal. Otherwise, flags that are disabled in the
+ source terminal may still be enabled in the destination.
+ [ead41242b820]
+
+ * Makefile.in, doc/Makefile.in, examples/Makefile.in,
+ include/Makefile.in, lib/util/Makefile.in, lib/zlib/Makefile.in,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/system_group/Makefile.in,
+ src/Makefile.in:
+ Remove pointless subshells in targets that simply change the
+ directory and execute a command. The command is already run in a
+ shell so there is no need to execute a subshell in this case.
+ [e57639cb2f97]
+
+2017-07-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo.c:
+ Store the debug instance ID for I/O plugins too. Now iolog_open() is
+ consistent with policy_open().
+ [519abb3c09d0]
+
+2017-06-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/event.c:
+ Move the bits to fill in the new event base to sudo_ev_base_init(),
+ which is not currently exported.
+ [9be46693bed1]
+
+2017-06-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.ac, lib/util/mktemp.c:
+ Use getentropy() in mkstemp/mkdtemp replacement.
+ [8d8e45266858]
+
+ * configure, configure.ac, lib/util/closefrom.c, lib/util/mktemp.c,
+ pathnames.h.in, src/exec_pty.c, src/get_pty.c, src/ttyname.c:
+ Use _PATH_DEV consistently
+ [ca10a91539e0]
+
+2017-06-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/term.c:
+ When copying terminal settings from one tty to another only copy a
+ subset of the flags. Sudo now copies the same set of flags that
+ OpenSSH uses, which should be safe.
+ [2f12bc7a87d1]
+
+ * src/exec_monitor.c, src/exec_nopty.c:
+ Add debug warning when we have wait status but don't overwrite the
+ existing cstat.
+ [5ae8f8e75104]
+
+ * src/exec_monitor.c:
+ Better handling of SIGCONT from in command in the monitor. It is
+ useful to know when the command continued but we don't want to
+ inform the parent or store the wait status in this case. Fixes a
+ hang after multiple suspends on Linux.
+ [9cdbbb7ff3dd]
+
+2017-06-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/parse.h:
+ avoid padding in struct cmndspec
+ [2529551a9c2d]
+
+2017-06-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudoers.cat, doc/sudoers.ldap.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in:
+ Fix the man section of sudo_plugin in cross-references.
+ [f964de570403]
+
+2017-06-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo_edit.c:
+ Don't treat an unchanged file as an error. From Xin Li.
+ [503e04f7856e]
+
+ * src/sudo_edit.c:
+ sudo_edit() must return a wait status but if there is an error, or
+ even if no changes were made to the file, it was returning 1 instead
+ which would be interpreted as the command having received SIGHUP.
+ Use the W_EXITCODE() to construct a proper wait status in the error
+ case too.
+ [62515bd6c64c]
+
+2017-06-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/ttyname.c:
+ Avoid sign extension when assigning the value of tty_nr in
+ /proc/self/stat on Linux. It is an unsigned int value that is
+ printed as a signed int but dev_t is unsigned long long. We need to
+ cast to unsigned int before assigning to a dev_t.
+ [c198d1317560]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/env.c:
+ Instead of hard-coding a check for bash functions in
+ env_should_delete(), use a "*=()* " pattern in
+ initial_badenv_table[] to match them instead. This allows the user
+ to remove the check via env_delete.
+ [90c4dfd1d3a3]
+
+2017-06-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL.configure, configure.ac, doc/sudo_plugin.cat,
+ doc/sudo_plugin.man.in, doc/sudo_plugin.mdoc.in, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, mkpkg, sudo.pp:
+ Mac OS X -> macOS
+ [08f793d1f496]
+
+ * doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in:
+ devsearch is ignored on BSD, macOS and Solaris
+ [b041a1d64eda]
+
+2017-05-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Sudo 1.8.20p2
+ [39f199a38383]
+
+ * src/ttyname.c:
+ A command name may also contain newline characters so read
+ /proc/self/stat until EOF. It is not legal for /proc/self/stat to
+ contain embedded NUL bytes so treat the file as corrupt if we see
+ any. With help from Qualys.
+
+ This is not exploitable due to the /dev traversal changes in sudo
+ 1.8.20p1 (thanks Solar!).
+ [9ad60fe663e5]
+
+2017-05-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/ttyname.c:
+ Use /proc/self consistently on Linux. As far as I know, only AIX
+ doesn't support /proc/self.
+ [ef737b5d4ed8]
+
+ * INSTALL, configure, configure.ac, doc/sudo.conf.cat,
+ doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in, include/sudo_conf.h,
+ lib/util/sudo_conf.c, lib/util/util.exp.in, pathnames.h.in,
+ src/ttyname.c:
+ Add a new "devsearch" Path setting to sudo.conf for configuring the
+ /dev paths to traverse instead of hard-coding a list in ttyname.c
+ The default value can be set at configure time.
+ [7ab1be502dc3]
+
+ * src/selinux.c:
+ After opening a tty device, fstat() and error out if it is not a
+ character device.
+ [e03cfa98f2b6]
+
+2017-05-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure:
+ Sudo 1.8.20p1
+ [c34da84ae8e4]
+
+ * src/ttyname.c:
+ Fix for CVE-2017-1000367, parsing of /proc/pid/stat on Linux when
+ the process name contains spaces. Since the user has control over
+ the command name this could be used by a user with sudo access to
+ overwrite an arbitrary file. Thanks to Qualys for investigating and
+ reporting this bug.
+
+ Also stop performing a breadth-first traversal of /dev when looking
+ for the device. Only the directories specified in search_devs[] are
+ checked.
+ [b5460cbbb11b]
+
+2017-05-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/event_select.c:
+ Fix potential memory leak on reallocarray() error. Coverity CID
+ 169639
+ [c303e6eecc78]
+
+ * plugins/sudoers/bsm_audit.c:
+ Only fall back to deprecated getaudit() on FreeBSD. Fixes compiler
+ warnings on macOS.
+ [18f4699e417c]
+
+ * mkpkg:
+ Use clang on macOS if present
+ [a963454d1b9e]
+
+ * sudo.pp:
+ fix paths to LICENSE and NEWS files for macOS packages
+ [47103614311b]
+
+2017-05-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_monitor.c, src/exec_nopty.c, src/exec_pty.c:
+ To avoid overwriting existing command status, check for CMD_INVALID
+ instead of CMD_ERRNO or CMD_WSTATUS.
+ [5fec1fa81482]
+
+ * plugins/sudoers/regress/env_match/data:
+ Add some patterns that could result in exponential run time for
+ poorly written '*' matching.
+ [98f4d085c919]
+
+2017-05-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/ttysize.c, src/exec_pty.c:
+ On HP-UX 11.0, sys/ioctl.h is not sufficient to make struct winsize
+ visisble, we need termios.h too.
+ [211510123ad6]
+
+ * lib/util/ttysize.c:
+ Always used TIOCGWINSZ.
+ [82e679b8cd00]
+
+ * src/exec.c, src/sudo.c, src/sudo.h:
+ Move exec_setup(), unlimit_nproc() and restore_nproc() from sudo.c
+ to exec.c.
+ [9127e50cf4ec]
+
+ * src/sudo_edit.c:
+ No need to include selinux.h here.
+ [8bb07a8f4203]
+
+ * plugins/sudoers/regress/env_match/check_env_pattern.c:
+ Fix compilation error on macOS
+ [bc5e5c3d44f2]
+
+2017-05-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/ldap.c:
+ Avoid a clang analyzer false positive.
+ [9f4f915a2e28]
+
+ * Makefile.in:
+ Add cov-build and cov-submit targets for checking with coverity.
+ [bf88b4439c7b]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/mkdir_parents.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/visudo.c:
+ Use debug logging instead of ignore_result() where possible.
+ [9c9fde5b52cc]
+
+ * config.h.in, configure, configure.ac, include/sudo_compat.h,
+ lib/util/term.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/visudo.c, src/exec_monitor.c, src/exec_nopty.c,
+ src/exec_pty.c, src/signal.c, src/sudo.c, src/tcsetpgrp_nobg.c,
+ src/tgetpass.c:
+ Remove use of non-standard sigaction_t
+ [81a57af4c7a9]
+
+ * include/sudo_compat.h, plugins/sudoers/timestamp.c,
+ src/tcsetpgrp_nobg.c, src/tgetpass.c:
+ Remove use of the non-standard SA_INTERRUPT
+ [3ec05ffb0dcb]
+
+ * configure, configure.ac:
+ sudo 1.8.21
+ [76aa5455903e]
+
+ * MANIFEST, doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/env.c,
+ plugins/sudoers/env_pattern.c,
+ plugins/sudoers/regress/env_match/check_env_pattern.c,
+ plugins/sudoers/regress/env_match/data, plugins/sudoers/sudoers.h:
+ Add support for multiple '*' in env_keep, env_check and env_delete
+ entries.
+ [b55270a8ecc4]
+
+ * src/signal.c:
+ Add SIGCHLD to the list of signals we install sudo_handler() for.
+ Otherwise, it is possible for the command to exit before the SIGCHLD
+ handler is installed. POSIX says that signals that are ignored by
+ default are still ignored even if the signal mask would block them.
+ We need to have a handler installed for SIGCHLD before the fork().
+ [a26f04459c37]
+
+ * lib/util/event.c:
+ Activate the sigevents inside the signal pipe callback itself and
+ call signal_pipe_cb() directly if the backend returns EINTR and the
+ signal_caught flag is set. This has the side effect of processing
+ signal events in the current pass of the event loop instead of the
+ next one.
+ [d94e202b8e57]
+
+ * src/exec.c, src/exec_monitor.c, src/exec_nopty.c, src/exec_pty.c,
+ src/signal.c, src/sudo.h, src/sudo_exec.h:
+ Use SUDO_EV_SIGNAL and SUDO_EV_SIGINFO instead of managing the
+ signal_pipe explicitly.
+ [841e2ca6a4a6]
+
+ * include/sudo_event.h, lib/util/event.c:
+ Handle the possibility of the siginfo parameter in sa_sigaction
+ handler being NULL.
+ [0835ca553426]
+
+ * include/sudo_event.h, lib/util/event.c:
+ Add support for signal events in sudo's event subsystem
+ [0d48fab2dec8]
+
+ * plugins/sudoers/sudoreplay.c:
+ Restore the error message for sudo_ev_add() failure.
+ [267305606577]
+
+ * include/sudo_queue.h:
+ Add workaround for clang static analyzer being confused by
+ LIST_REMOVE and TAILQ_REMOVE.
+ [ff8d278e8526]
+
+2017-05-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ Fix "make check" when openssl or gcrypt is used. Bug #787
+ [7968686742e2]
+
+2017-05-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ Only display string version of errno if sudo_ev_add() fails for now
+ [24244a02c93f]
+
+2017-05-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ update
+ [8e3359235e24]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Be clear that #includedir diverts control to the files in the
+ specified directory and, when parsing of those files is complete,
+ returns control to the original file. Bug #775
+ [f68769f15356]
+
+2017-05-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sr.mo, plugins/sudoers/po/sr.po, po/sr.mo,
+ po/sr.po:
+ sync with translationproject.org
+ [4552eaf8fabf]
+
+2017-05-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ update
+ [53d1c9424816]
+
+ * src/exec_monitor.c:
+ Fix a hang introduced in the last commit. Don't close the pty slave
+ until after we have the controlling tty.
+ [c9c19beb60ed]
+
+ * src/exec_monitor.c, src/exec_pty.c:
+ If any of std{in,out,err} are not hooked up to a tty only interpose
+ ourselves with a pipe if the plugin will actually log the data. This
+ avoids a problem with non-interactive commands where no tty is
+ present where sudo will consume stdin even when log_input is not
+ enabled in sudoers.
+ [a79edafdd307]
+
+ * NEWS:
+ update
+ [144ff056cd01]
+
+ * doc/TROUBLESHOOTING:
+ Update based on information from Michael Felt.
+ [7ea34380ba1d]
+
+2017-05-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ In check_input() when switch()ing on the return value of read(), use
+ the default label instead of 1 for the success case. It is only
+ reading a single byte so the two are equivalent but it reads better
+ using default.
+ [860682b86af5]
+
+ * plugins/sudoers/sudoreplay.c:
+ Check sudo_ev_add() return value. Coverity CID 168362
+ [b69779d3801f]
+
+ * plugins/sudoers/iolog.c:
+ Add io_open() wrapper for open(2) that retries with PERM_IOLOG if
+ open(2) fails with EACCES. Use io_open() instead of duplicate copies
+ of the same fallback code.
+ [09f7992f681b]
+
+ * plugins/sudoers/iolog.c:
+ Don't retry the open() if set_perms() fails.
+ [0808a9157037]
+
+ * plugins/sudoers/iolog.c:
+ Fix typo (fd2 vs. fd) caught by coverity, CID 168359.
+ [f68df770e06f]
+
+ * po/hu.mo, po/hu.po:
+ sync with translationproject.org
+ [ebef76dc27be]
+
+2017-05-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ Warn people not to use --enable-asan in production.
+ [ecb5c1143ef4]
+
+ * configure, configure.ac, src/Makefile.in:
+ Move the invocation of check_noexec into the main "check" target but
+ only run it if not cross compiling and whe CHECK_NOEXEC is not
+ empty.
+ [cba8fd3337c2]
+
+ * src/Makefile.in:
+ Move @CHECK_NOEXEC@ to TEST_PROGS so it gets cleaned up properly.
+ [efaa9c44e749]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Move syslog_maxlen to the "Integers" section. Move syslog_goodpri
+ and syslog_badpri to the "Strings at can be used in a boolean
+ context" section.
+ [342dfe9dd37c]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Fix a pasto that resulted in an extra (empty) syslog_goodpri list
+ entry.
+ [eb0563c5b8dc]
+
+ * MANIFEST, plugins/sudoers/regress/sudoers/test20.in,
+ plugins/sudoers/regress/sudoers/test20.json.ok,
+ plugins/sudoers/regress/sudoers/test20.out.ok,
+ plugins/sudoers/regress/sudoers/test20.toke.ok,
+ plugins/sudoers/regress/sudoers/test21.in,
+ plugins/sudoers/regress/sudoers/test21.json.ok,
+ plugins/sudoers/regress/sudoers/test21.out.ok,
+ plugins/sudoers/regress/sudoers/test21.toke.ok:
+ Add tests for parsing tuples and syslog options.
+ [86f3da23b4df]
+
+ * plugins/sudoers/defaults.c:
+ Allow the syslog Defaults option to be used in a "true" boolean
+ context and use the compiled in default log facility in this case.
+ [4fab25217602]
+
+ * plugins/sudoers/defaults.c:
+ Allow a tuple to be set to boolean true. Regression introduced by
+ refactor of set_default_entry() in sudo 1.8.18.
+ [9b38728deb27]
+
+2017-05-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/TROUBLESHOOTING:
+ Replace the list of "dangerous" environment variables and explain
+ how sudo handles the environment instead.
+ [966cf87d1bed]
+
+2017-04-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/glob.c:
+ Fix exponential behavior in glob() with respect to multiple '*'. See
+ https://research.swtch.com/glob Adapted from https://perl5.git.perl.
+ org/perl.git/commit/33252c318625f3c6c89b816ee88481940e3e6f95
+ [3d187b0fb764]
+
+ * src/exec_pty.c:
+ We no longer need to write to the tty if the command was killed by a
+ signal. Sudo will terminate itself with the same signal the command
+ died from. Unfortunately, we lose the "core dumped" bit since sudo
+ itself will not dump core, but there doesn't appear to be a way
+ around that.
+ [1be331e0c4d4]
+
+2017-04-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo.c:
+ On Linux, if the command we ran dumped core, set PR_SET_DUMPABLE to
+ 0. This will prevent sudo itself from dumping core in this case.
+ [cf5a5793ebf4]
+
+ * INSTALL:
+ Update path to sudo_noexec.so
+ [14e995667c8b]
+
+ * src/sudo.c:
+ If the command terminated due to a signal, sudo will send that same
+ signal to itself so the parent shell knows the command died from a
+ signal. However, we don't want sudo itself to dump core.
+ [8d823e6ec41e]
+
+2017-04-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ sync
+ [1704e6005b07]
+
+ * src/sudo.c:
+ The fix for Bug #722 contained a typo/thinko that resulted in the
+ exit status being 0 when a command was killed by a signal other than
+ SIGINT. This fixes the signal handler setup so sudo will terminate
+ with the same signal as the command. Bug #784.
+ [50b988d0c97f]
+
+ * sudo.pp:
+ Better check for /etc/rc.d/rc2.d/S90sudo on AIX
+ [93de5e34a6a3]
+
+ * src/Makefile.in:
+ Don't install the rc.d link when installing to a DESTDIR. DESTDIR is
+ generally only set when installing to a temporary directory for
+ packaging in which case the link should be made in a post-install
+ script.
+ [4200ef757b56]
+
+ * plugins/sudoers/Makefile.in, sudo.pp:
+ In "make install", install sample sudoers file as /etc/sudoers.dist
+ and copy it to /etc/sudoers if there is no existing /etc/sudoers.
+ Packages either contain /etc/sudoers (RPM and Debian) or
+ /etc/sudoers.dist (everything else).
+ [40f8e5806d71]
+
+ * Makefile.in, mkdep.pl:
+ Allow "make dist" and "make depend" to work for out of tree builds.
+ [7b7ba3f38abb]
+
+2017-04-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/zlib/Makefile.in:
+ Add missing $(srcdir) prefix to shlib_exp definition.
+ [c63e8e73507e]
+
+2017-04-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_compat.h:
+ Fix typo in killpg macro.
+ [f7392d21c915]
+
+ * include/sudo_compat.h:
+ Fix the killpg macro for systems without killpg() in libc.
+ [ba0c5162bc4a]
+
+2017-04-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Use the standard idiom for popping all entries from a tail queue.
+ The llvm checker gets confused by TAILQ_REMOVE and generate use-
+ after-free false positives.
+ [a88cacd23f09]
+
+ * src/exec_monitor.c, src/exec_nopty.c:
+ rewrite errpipe callbacks
+ [5c75729cea19]
+
+ * src/exec_monitor.c, src/exec_nopty.c:
+ use pipe2() with O_CLOEXEC instead of pipe() + fcntl() and
+ FD_CLOEXEC
+ [c8c9cc31c43a]
+
+ * src/exec_pty.c:
+ init io_pipe[][] to -1, not 0
+ [71012940a8f1]
+
+2017-04-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sssd.c:
+ In sudo_sss_check_user() it is not possible for handle to be NULL.
+ [de41ba76a4ce]
+
+ * plugins/sudoers/sssd.c:
+ Fix a use after free when the fqdn sudoOption is set and no hostname
+ value is present in sssd.conf.
+ [716a7c502cc0]
+
+ * src/sudo.c:
+ Avoid unused variable when getgrouplist_2() is available. It would
+ be nicer to just provide getgrouplist_2() (or the equivalent) and
+ avoid the ugly #ifdefs.
+ [2c7ac21feb5f]
+
+ * plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po, po/nb.mo,
+ po/nb.po:
+ sync with translationproject.org
+ [e91a983f9de6]
+
+2017-04-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ regen
+ [790d9a05f585]
+
+2017-04-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/ttyname.c:
+ In sudo_ttyname_scan() if dir is the empty string, set errno to
+ ENOENT before returning.
+ [f531ea6e489e]
+
+2017-04-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Try to make it clear that when match_group_by_gid is enabled, groups
+ in sudoers are looked up by group name instead of group ID. This
+ doesn't usually cause problems, but if there are conflicting group
+ entries (for example, from a local /etc/group file and an LDAP or AD
+ group database), whether the group is resolved by name or ID can be
+ used to work around conflicts.
+ [fe3bfca4fcce]
+
+2017-04-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po, po/ja.mo,
+ po/ja.po:
+ sync with translationproject.org
+ [94d36c45e345]
+
+ * plugins/sudoers/regress/parser/check_digest.c:
+ plug memory leak in check_digest
+ [40aab9e6e365]
+
+ * src/exec.c:
+ Check return value of dispatch_pending_signals() in case we received
+ SIGINT or SIGQUIT before executing the command.
+ [218758d1560d]
+
+2017-03-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ back out unintentional change to the version number
+ [799b396c1c69]
+
+2017-03-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/hr.mo, plugins/sudoers/po/hr.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po, po/cs.mo,
+ po/cs.po, po/da.mo, po/da.po, po/de.mo, po/de.po, po/fr.mo,
+ po/fr.po, po/hr.mo, po/hr.po, po/it.mo, po/it.po, po/pl.mo,
+ po/pl.po, po/pt_BR.mo, po/pt_BR.po, po/tr.mo, po/tr.po, po/uk.mo,
+ po/uk.po, po/vi.mo, po/vi.po, po/zh_CN.mo, po/zh_CN.po:
+ sync with translationproject.org
+ [04c4a3ec233d]
+
+2017-03-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac, plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/regress/parser/check_digest.out.ok:
+ Make check_digest test sudo_filedigest() itself instead of the
+ underlying SHA2 functions. That way we can test it regardless of
+ whether we use sudo's SHA2 functions or a library version.
+ [9834b37f1fb0]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document that commands matched by "sudo ALL" are not affected by
+ fdexec.
+ [7cc3b770a2ff]
+
+2017-03-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Update for 1.8.20
+ [14a09000c1dc]
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen for restricted_env_file
+ [81290b370c95]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Mention that iolog_user is useful for NFS.
+ [9c8f9dfdebf0]
+
+2017-03-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Only retry mkdir or create with PERM_IOLOG if errno is EACCES. Also
+ always use PERM_IOLOG for mkdtemp() since we cannot retry if it
+ fails. Since we are guaranteed to create a new directory there's no
+ real need to try w/o PERM_IOLOG in this case.
+ [c3c67d78e46a]
+
+2017-03-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Add fallback to PERM_IOLOG when making the final componenet of
+ iolog_dir.
+ [72924e4c8f5d]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/env.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Add restricted_env_file which is like env_file but subject to the
+ same restrictions as the user's own environment.
+ [ec887cc57a8b]
+
+ * plugins/sudoers/iolog.c:
+ quiet a warning on older zlib
+ [bcd3cac968a2]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/timestamp.c:
+ cast mode_t to unsigned int when printing with %o
+ [f9ca9ead134e]
+
+2017-03-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [f62e81f74d10]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/mkdir_parents.c,
+ plugins/sudoers/timestamp.c:
+ Set umask temporarily when creating files instead of changing the
+ mode after the fact. This is slightly less error prone.
+ [a9b4cf336b73]
+
+ * plugins/sudoers/iolog.c:
+ remove now-useless variable
+ [9a36b2449ac4]
+
+ * plugins/sudoers/mkdir_parents.c:
+ Don't set owner/mode on directories that already exist, only on
+ newly-created ones.
+ [2b616be0e165]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/mkdir_parents.c:
+ Explicitly set the file mode of I/O log files so the mode is not
+ affected by the invoking user's umask.
+ [ec7d5dd47b6b]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/iolog.c, plugins/sudoers/mkdir_parents.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/timestamp.c:
+ Add PERM_IOLOG so we can create I/O log files on an NFS-mounted
+ filesystem where root is remapped to an unprivileged user.
+ [01804a971cd5]
+
+ * plugins/sudoers/mkdir_parents.c:
+ Restore the '/' in the path before returning if we encounter an
+ error.
+ [bb12cfce16fd]
+
+2017-03-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/timestamp.c:
+ When creating the timestamp directory, use the group of the
+ timestamp owner instead of inheriting the group of the parent
+ directory.
+ [7a4a10cafe08]
+
+2017-03-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sssd.c:
+ zero out nss->handle after it has been freed to make sure we cannot
+ free it twice
+ [00d5340b7541]
+
+2017-03-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/iolog.c:
+ Add iolog_flush option.
+ [96baa17409cf]
+
+2017-03-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/iolog.c:
+ Don't allow the user to specify an I/O log file mode that sudo can't
+ read or write to. I/O logs must always be readable and writable by
+ the owner.
+ [b32e2ef04905]
+
+2017-03-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo_plugin.cat,
+ doc/sudoers.cat, doc/sudoers.ldap.cat, doc/sudoreplay.cat,
+ doc/visudo.cat:
+ Regenerate the cat pages with newer mandoc which formats double
+ quotes as "foo" instead of ``foo''.
+ [5f14e527ae05]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Make it clear that I/O logs will be complete even if the command run
+ by sudo is terminated by a signal. The I/O log buffering just
+ prevents the logs from being displayed in real-time as the command
+ is running.
+ [072fd419ac1e]
+
+2017-03-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c, src/exec_monitor.c, src/signal.c, src/sudo.h:
+ Replace pipe_nonblock() with pipe2()
+ [c106b62d7835]
+
+ * MANIFEST, config.h.in, configure, configure.ac,
+ include/sudo_compat.h, lib/util/Makefile.in, lib/util/pipe2.c,
+ mkdep.pl:
+ Emulate pipe2() on systems without it.
+ [5a183dd380f0]
+
+2017-03-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/kerb5.c:
+ Fix declaration of sudo_krb5_verify() in the case where
+ krb5_verify_user() is not present. Bug #777
+ [eafd4e2d7c7f]
+
+ * plugins/sudoers/rcstr.c:
+ Use HAVE_STDBOOL_H to detect systems w/o stdbool.h. Bug #778
+ [dbac86777429]
+
+2017-03-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [2fc489ddc143]
+
+ * src/exec_monitor.c, src/exec_nopty.c, src/exec_pty.c:
+ Move SIGCHLD handling into handle_sigchld() functions and move the
+ remaining bits of dispatch_signal() into signal_pipe_cb()
+ [b120f5cfa8cc]
+
+2017-03-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/utmp.c:
+ e_termination should be set to the value of WTERMSIG not WEXITSTATUS
+ [95f37078ae8f]
+
+2017-03-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, src/Makefile.in, src/exec_nopty.c, src/sudo.h,
+ src/tcsetpgrp_nobg.c:
+ Add tcsetpgrp_nobg() which acts like tcsetpgrp() but returns -1 for
+ a background process. This is safer than blocking SIGTTOU which
+ would cause tcsetpgrp() to succeed in the background.
+ [7ab75c47b8bf]
+
+2017-03-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_nopty.c:
+ Prevent sudo from receiving SIGTTOU when it tries to restore the
+ controlling terminal. There appears to be a race with the shell
+ (bash) which we may lose.
+ [aab018fb9940]
+
+2017-03-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/timestamp.c, src/exec_monitor.c:
+ Add some casts to quiet gcc warnings on Solaris and remove a now-
+ useless debug printf.
+ [16c862eab0ce]
+
+ * src/exec_pty.c:
+ change debug info when suspending sudo
+ [f5c5ee07f8e3]
+
+ * MANIFEST, src/Makefile.in, src/exec.c, src/exec_monitor.c,
+ src/exec_nopty.c, src/exec_pty.c, src/sudo_exec.h:
+ Reorganize the command execution code to separate out the pty and
+ non-pty code paths into their own event loops. The non-pty exec code
+ is now contained in exec_nopty.c and the pty exec code is split
+ between exec_pty.c (parent process) and exec_monitor.c (session
+ leader). This results in a small bit of duplicated code but improves
+ readability. Some of the duplicated code will fall out in future
+ changes to the event subsystem (the signal pipe).
+ [fe239d2a3cbd]
+
+2017-02-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/ttysize.c, src/exec_pty.c:
+ Remove support for the TIOCGSIZE ioctl. Systems that use this rather
+ than TIOCGWINSZ are too old for sudo to build on anyway.
+ [0179b16c70f9]
+
+2017-02-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c, src/exec_pty.c:
+ Set the child pid to -1 after we've waited for it and take care to
+ avoid killing pid -1. This makes it a bit more explicit and removes
+ the need for a separate variable to track the child's status. Sudo
+ already stops processing signals after it receives SIGCHLD so it is
+ not vulnerable to CVE-2017-2616.
+ [1123704858ae]
+
+2017-02-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in:
+ Update the description of strict mode to current reality. Aliases
+ haven't needed to be defined before they are used since sudo 1.7.
+ [9dc4ce4ec538]
+
+ * doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in,
+ plugins/sudoers/regress/visudo/test2.err.ok,
+ plugins/sudoers/regress/visudo/test3.err.ok,
+ plugins/sudoers/visudo.c:
+ Go back to using a Warning/Error prefix in the message printed to
+ stderr for alias problems. Requested by Tomas Sykora.
+ [ad4dc6e34222]
+
+2017-02-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/filedigest.c, plugins/sudoers/filedigest_openssl.c:
+ fix copyright years
+ [b9f013f95bb2]
+
+2017-02-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, MANIFEST, configure, configure.ac, mkdep.pl,
+ plugins/sudoers/Makefile.in, plugins/sudoers/filedigest_gcrypt.c:
+ Add support for using the message digest functions in libgcrypt
+ instead of sudo's own SHA2 implementation.
+ [0259467c38dd]
+
+ * INSTALL, MANIFEST, configure, configure.ac, mkdep.pl,
+ plugins/sudoers/Makefile.in, plugins/sudoers/filedigest_openssl.c:
+ Add support for using the message digest functions in OpenSSL
+ instead of sudo's own SHA2 implementation.
+ [d77639c97e43]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/digestname.c,
+ plugins/sudoers/filedigest.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/match.c, plugins/sudoers/parse.h,
+ plugins/sudoers/sssd.c, plugins/sudoers/visudo_json.c:
+ Move the file digest code out of match.c and into filedigest.c.
+ Inspired by RedHat changes that used libgcrypt. Also add
+ digest_type_to_name() to map a sudo digest type (int) to a name
+ (string) and use it.
+ [9213d8c94b8f]
+
+ * plugins/sudoers/gmtoff.c:
+ Check for gmtime() or localtime() returning NULL and just use a zero
+ offset in that case. Should not be possible.
+ [ed210dd8bf46]
+
+2017-02-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers2ldif:
+ Add support for ROLE, TYPE, PRIVS, LIMITPRIVS, TIMEOUT, NOTBEFORE
+ and NOTAFTER.
+ [d0310b017c78]
+
+ * config.h.in, configure, configure.ac, plugins/sudoers/timestr.c:
+ strftime() was in C89 so use it unconditionally.
+ [87bf66aa18fd]
+
+ * MANIFEST, config.h.in, configure, configure.ac, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, include/sudo_debug.h,
+ lib/util/sudo_debug.c, lib/util/util.exp.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/gentime.c,
+ plugins/sudoers/gmtoff.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.h, plugins/sudoers/gram.y,
+ plugins/sudoers/parse.c, plugins/sudoers/parse.h,
+ plugins/sudoers/regress/parser/check_gentime.c,
+ plugins/sudoers/regress/sudoers/test19.in,
+ plugins/sudoers/regress/sudoers/test19.json.ok,
+ plugins/sudoers/regress/sudoers/test19.out.ok,
+ plugins/sudoers/regress/sudoers/test19.toke.ok,
+ plugins/sudoers/regress/visudo/test10.out.ok,
+ plugins/sudoers/regress/visudo/test10.sh,
+ plugins/sudoers/sudoers_version.h, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Add NOTBEFORE and NOTAFTER command options similar to what is
+ already available in LDAP.
+ [3ba0f9567f83]
+
+2017-02-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [f2876eadc1f5]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, include/sudo_plugin.h:
+ Bump version to 1.11 for timeout entry in settings[]
+ [7b288e4bab93]
+
+ * doc/sudo.conf.cat, doc/sudo_plugin.cat, doc/sudoers.ldap.cat,
+ doc/sudoreplay.cat, doc/visudo.cat:
+ regen
+ [8c059a57d367]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in,
+ plugins/sudoers/policy.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, src/parse_args.c, src/sudo_usage.h.in:
+ Add a command line option to specify the command timeout, as long as
+ sudoers does not specify a shorter time limit.
+ [a8ef7f923d0a]
+
+2017-02-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y:
+ Better error message when the timeout value does not parse.
+ [2360fb093e3e]
+
+ * plugins/sudoers/timeout.c:
+ set errno to ERANGE not EOVERFLOW on range error
+ [9654e1acab0d]
+
+2017-02-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ regen
+ [46a124dd72aa]
+
+ * plugins/sudoers/Makefile.in:
+ Only inhibit ASAN leak detector for tests that result in a parse
+ error. The parser cannot currently clean up completely on error.
+ [b2f82dcd2545]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y:
+ Plug some memory leaks found by ASAN.
+ [08189098a5b6]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ List SELinux role/type for "sudo -l" with LDAP and SSSd backends.
+ Also fix printing of the timeout.
+ [740723a49ab5]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y:
+ Only inherit SELinux role/type and Solaris privilege sets if the
+ command does not include any. Previously, a command with only a role
+ would inherit a type from the previous command which is not what was
+ intended.
+ [171a3ad972e7]
+
+ * doc/fixman.sh, doc/fixmdoc.sh, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in, plugins/sudoers/gram.c, plugins/sudoers/gram.h,
+ plugins/sudoers/gram.y, plugins/sudoers/parse.h:
+ Split out tags again so they must precede the command and not allow
+ them to be mixed in with options.
+ [e7e7d60316cc]
+
+ * MANIFEST, doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in,
+ plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.h,
+ plugins/sudoers/gram.y, plugins/sudoers/ldap.c,
+ plugins/sudoers/mkdefaults, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/policy.c,
+ plugins/sudoers/regress/sudoers/test17.in,
+ plugins/sudoers/regress/sudoers/test17.json.ok,
+ plugins/sudoers/regress/sudoers/test17.out.ok,
+ plugins/sudoers/regress/sudoers/test17.toke.ok,
+ plugins/sudoers/regress/sudoers/test18.in,
+ plugins/sudoers/regress/sudoers/test18.json.ok,
+ plugins/sudoers/regress/sudoers/test18.out.ok,
+ plugins/sudoers/regress/sudoers/test18.toke.ok,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/timeout.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/visudo_json.c:
+ Add support for command timeouts in sudoers. After the timeout, the
+ command will be terminated.
+ [a36a748e9324]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.h,
+ plugins/sudoers/gram.y, plugins/sudoers/parse.h:
+ Merge command tags, SELinux type/role and Solaris privs settings
+ into "command options". This relaxes the order of things so tags and
+ other options can be interspersed.
+ [0970fd78cbe8]
+
+ * plugins/sudoers/rcstr.c:
+ supress cppcheck memory leak false positive
+ [e0caf2275a44]
+
+ * lib/util/strtoid.c:
+ fix typo that prevented compilation on FreeBSD
+ [27866f6a2b5e]
+
+2017-02-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/Makefile.in:
+ Link vsyslog.lo directly into vsyslog_test to make sure the syslog()
+ stub gets called. Otherwise, the real syslog will get called via
+ libutil on AIX.
+ [693bc8411a98]
+
+ * lib/util/regress/vsyslog/vsyslog_test.c:
+ Fix final test with a format > 2048 bytes. Keep track of tests run
+ in the syslog() stub so we can detect if the stub is not being
+ called.
+ [d10d784446c1]
+
+ * lib/zlib/deflate.c:
+ avoid redefining the MIN macro
+ [45b7b0ba0f01]
+
+ * plugins/sudoers/parse.h, plugins/sudoers/timestr.c:
+ Include parse.h in timestr.c which is where function prototype
+ lives.
+ [3ec9ec84a84c]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Fix for including a sudoers file that begins with the letter 'i'.
+ The hack to determine whether we are parsing an include or
+ includedir is no longer safe now that relative include paths are
+ permitted. Bug #776.
+ [4d9691a43867]
+
+2017-02-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/def_data.c, plugins/sudoers/def_data.in:
+ Display the value of syslog_maxlen in sudo -V output.
+ [0841ad36531c]
+
+2017-02-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/defaults.c:
+ Add ignore_unknown_defaults flag to ignore unknown Defaults entries
+ in sudoers instead of producing a warning.
+ [a7fdb44677dd]
+
+2017-01-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/match.c:
+ Always set the close-on-exec bit on the fd used to generate the
+ digest (i.e. the command to run) on systems that lack fexecve(2).
+ That way we don't need to explicitly close it using #ifdefs.
+ [f840a22fac1c]
+
+ * plugins/sudoers/po/ca.mo, plugins/sudoers/po/ca.po,
+ plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/sr.mo, plugins/sudoers/po/sr.po,
+ plugins/sudoers/po/sv.mo, plugins/sudoers/po/sv.po, po/ca.mo,
+ po/ca.po, po/eo.mo, po/eo.po, po/sv.mo, po/sv.po:
+ sync with translationproject.org
+ [57e877674892]
+
+ * NEWS:
+ first updates for 1.8.20
+ [118208688b08]
+
+ * configure, configure.ac:
+ sudo 1.8.20
+ [6cba125ea903]
+
+2017-01-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/LICENSE, lib/zlib/adler32.c, lib/zlib/compress.c,
+ lib/zlib/crc32.c, lib/zlib/deflate.c, lib/zlib/deflate.h,
+ lib/zlib/gzguts.h, lib/zlib/gzlib.c, lib/zlib/gzread.c,
+ lib/zlib/gzwrite.c, lib/zlib/infback.c, lib/zlib/inffast.c,
+ lib/zlib/inflate.c, lib/zlib/inflate.h, lib/zlib/inftrees.c,
+ lib/zlib/trees.c, lib/zlib/uncompr.c, lib/zlib/zconf.h.in,
+ lib/zlib/zlib.exp, lib/zlib/zlib.h, lib/zlib/zutil.c,
+ lib/zlib/zutil.h:
+ update zlib to version 1.2.11
+ [75a563663083]
+
+2017-01-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/match.c:
+ Fix fdexec=never when a digest is present.
+ [49d3ab5baad0]
+
+2017-01-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/defaults.c,
+ plugins/sudoers/match.c:
+ Add new fdexec sudoers setting to allow choose whether execve() or
+ fexecve() is used.
+ [6a7623aa9a64]
+
+ * src/exec.c, src/exec_pty.c:
+ Close execfd in parent processes where it is not needed.
+ [f44e334d43e2]
+
+2017-01-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/match.c:
+ Add support for digest matching when the command is a glob-style
+ pattern or a directory. For example:
+
+ millert ALL = sha224:TmUvLkp3a2txliSC2X6CiK42626qdKsH72m/PQ== /bin/
+ millert ALL = sha224:TmUvLkp3a2txliSC2X6CiK42626qdKsH72m/PQ== /bin/*
+
+ would only match /bin/ls (assuming the digest matches).
+
+ Previously, only explicit path matches checked the digest.
+ [d4f6822ba9bb]
+
+2017-01-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, plugins/sudoers/ldap.c:
+ Add support for SASL_MECH in ldap.conf; Bug #764
+ [d057bb7f2ddc]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Fix documentation bug, the contents of env_file have never been
+ subject to env_keep or env_check. However, variables are only added
+ if they have not already been preserved.
+ [4483b1b44709]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ examples/sudoers:
+ Safer example for rule that can change non-root passwords. GNU
+ getopts allows options to follow arguments so we need to be able to
+ deny things like "passwd root -q". From Paul "Joey" Clark. Bug #772
+ [c809f1372811]
+
+2017-01-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Don't overwrite the return value of ldap_sasl_interactive_bind_s()
+ by the subsequent call to sudo_set_krb5_ccache_name(). From Paul
+ Zirnik of SUSE.
+ [448baff2b586]
+
+ * plugins/sudoers/env.c:
+ In sudo_unsetenv_nodebug(), decrement envp.env_len after removing
+ the variable. From Paul Zirnik of SUSE.
+ [3d87a008671c]
+
+2017-01-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/Makefile.in:
+ only run vsyslog_test if it exists
+ [5323dfcfb009]
+
+ * MANIFEST, configure, configure.ac, lib/util/Makefile.in,
+ lib/util/regress/vsyslog/vsyslog_test.c:
+ Add regress for vsyslog replacement.
+ [1f767b8f5940]
+
+2017-01-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Define HAVE_NANOSLEEP if we find nanosleep in librt
+ [ec8d949bf411]
+
+ * configure, configure.ac:
+ sudo_nanosleep not nanosleep in util.exp.in
+ [18a3bca78962]
+
+ * configure, configure.ac:
+ add nanosleep to util.exp.in if needed
+ [6ac2e9266d67]
+
+ * NEWS, configure, configure.ac:
+ sudo 1.8.19p2
+ [9c15593a007a]
+
+ * lib/util/vsyslog.c:
+ Double the size of new_fmt[] and remove an extraneous break in the
+ %m handling that was leftover from an earlier edit.
+ [fcb28dc9cd4e]
+
+ * lib/util/vsyslog.c:
+ Fix typo, want vsnprintf not snprintf.
+ [2717f2125ecd]
+
+ * plugins/sudoers/logging.c:
+ move va_start() in mysyslog()
+ [b58ec40bbfc3]
+
+ * plugins/sudoers/sudoers.c:
+ Only treat failure of expand_iolog_path() as fatal if
+ ignore_iolog_errors is not set.
+ [1ba009311cf7]
+
+2017-01-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, config.h.in, configure, configure.ac,
+ include/sudo_compat.h, lib/util/Makefile.in, lib/util/nanosleep.c,
+ mkdep.pl, src/exec_pty.c:
+ When waiting for the parent to grant us the tty, use nanosleep
+ instead of spinning to avoid hogging the CPU.
+ [76335b380d7c]
+
+ * src/sudo.c:
+ Use ROOT_UID instead of 0
+ [5ed03a4e0b0b]
+
+2017-01-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ regen
+ [99b26e2c523d]
+
+2017-01-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/interfaces.c,
+ plugins/sudoers/regress/visudo/test9.out.ok,
+ plugins/sudoers/regress/visudo/test9.sh, plugins/sudoers/visudo.c:
+ Fix crash in visudo introduced in sudo 1.8.9 when an IP address or
+ network is used in a host-based Defaults entry. Bug #766
+ [ff9001f126b5]
+
+2017-01-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac, doc/LICENSE:
+ Avoid using the system strnlen/strndup on AIX < 6. Even if configure
+ correctly detects it is working on the build machine, the sudo
+ package may be run on a system with an old libc were it is broken.
+ [28d148db0aaa]
+
+2016-12-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.ac:
+ sudo 1.8.19p1
+ [7bfd43fa5caf]
+
+ * plugins/sudoers/defaults.c:
+ Fix logic bug when matching syslog priority and facility.
+ [576cc9eb850f]
+
+ * doc/HISTORY:
+ Dell spun off Quest so simplify the history by just talking about
+ Quest and not Dell.
+ [a66120495435]
+
+2016-12-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/LICENSE:
+ Fix copyright year
+ [3122e55195a6]
+
+ * NEWS:
+ typo
+ [ffe9e84928b6]
+
+2016-12-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_compat.h:
+ HAVE_DECL_GETGROUPLIST_2 is always defined if HAVE_GETGROUPLIST_2
+ is, we need to check its value, not whether it is defined.
+ [849eb3113149]
+
+2016-12-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/ko.mo, plugins/sudoers/po/ko.po:
+ sync with translationproject.org
+ [abf5d356a33b]
+
+2016-12-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/sr.mo, plugins/sudoers/po/sr.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po, po/sr.mo,
+ po/sr.po:
+ sync with translationproject.org
+ [fec672d5a4c7]
+
+ * config.h.in, configure.ac, include/sudo_compat.h,
+ plugins/sudoers/pwutil_impl.c, src/sudo.c:
+ Use getgrouplist_2() on macOS if available.
+ [3bf58af56d18]
+
+2016-12-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [3f4d52230317]
+
+ * plugins/sudoers/interfaces.c:
+ In set_interfaces() treat a parse error as fatal.
+ [7d0048108b1d]
+
+2016-12-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/regress/atofoo/atofoo_test.c:
+ Fix a clang warning on macOS
+ [58e9d192e907]
+
+2016-12-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/ko.mo, plugins/sudoers/po/ko.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po, po/ko.mo,
+ po/ko.po, po/vi.mo, po/vi.po:
+ sync with translationproject.org
+ [99cce0f5fddc]
+
+ * NEWS:
+ update for 1.8.19b2
+ [18cfc9b8b8e7]
+
+ * plugins/sudoers/timestamp.c:
+ Ignore a boot time that is in the future, which can happen when the
+ clock is corrected down after boot. Otherwise, the timestamp file
+ will be unlinked each time sudo is run and a password is always
+ required.
+ [dd3b2b7ae709]
+
+2016-11-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.in,
+ plugins/sudoers/defaults.c, plugins/sudoers/logging.c:
+ Allow syslog priority to be negated or set to "none" to disable
+ logging successes or failures.
+ [624eddac4ab1]
+
+ * doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in,
+ plugins/sudoers/sudoreplay.c:
+ Allow stdin and ttyin to be displayed too. The only one that is
+ really useful in sudoreplay is stdin when input is from a pipe.
+ [5aa8b3a90c84]
+
+ * src/regress/noexec/check_noexec.c:
+ Solaris 10 wordexp() returns 127 on execve() failure like popen()
+ does.
+ [f927c50dda17]
+
+ * config.h.in, configure, configure.ac, include/sudo_debug.h,
+ lib/util/regress/atofoo/atofoo_test.c, lib/util/strtoid.c,
+ lib/util/sudo_debug.c, lib/util/util.exp.in:
+ id_t is 64-bits on FreeBSD so use strtoll() there. Fixes the strtoid
+ regress.
+ [448a9857e89f]
+
+2016-11-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ fix typo
+ [92ea657a87f5]
+
+ * plugins/sudoers/sudoers.c:
+ Fix the "all" setting for verifypw and listpw; nopass would never be
+ true even if all the user's entries had the NOPASSWD tag. Regression
+ introduce in sudo 1.8.17. Bug #762
+ [c672e3ebfbe2]
+
+2016-11-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/ca.mo, plugins/sudoers/po/cs.mo,
+ plugins/sudoers/po/cs.po, plugins/sudoers/po/da.mo,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/el.mo, plugins/sudoers/po/eo.mo,
+ plugins/sudoers/po/eu.mo, plugins/sudoers/po/fi.mo,
+ plugins/sudoers/po/fr.mo, plugins/sudoers/po/hr.mo,
+ plugins/sudoers/po/hr.po, plugins/sudoers/po/hu.mo,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/ko.mo, plugins/sudoers/po/ko.po,
+ plugins/sudoers/po/lt.mo, plugins/sudoers/po/nb.mo,
+ plugins/sudoers/po/nb.po, plugins/sudoers/po/nl.mo,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/ru.mo, plugins/sudoers/po/sk.mo,
+ plugins/sudoers/po/sl.mo, plugins/sudoers/po/sr.mo,
+ plugins/sudoers/po/tr.mo, plugins/sudoers/po/uk.mo,
+ plugins/sudoers/po/uk.po, plugins/sudoers/po/zh_CN.mo,
+ plugins/sudoers/po/zh_CN.po, po/cs.mo, po/cs.po, po/de.mo, po/de.po,
+ po/es.mo, po/es.po, po/fr.mo, po/fr.po, po/hr.mo, po/hr.po,
+ po/it.mo, po/it.po, po/ja.mo, po/ja.po, po/ko.mo, po/ko.po,
+ po/nb.mo, po/nb.po, po/pl.mo, po/pl.po, po/pt_BR.mo, po/pt_BR.po,
+ po/tr.mo, po/tr.po, po/uk.mo, po/uk.po, po/zh_CN.mo, po/zh_CN.po:
+ sync with translationproject.org
+ [8a4ab570d132]
+
+2016-11-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c, src/openbsd.c:
+ Just use malloc_options "S" on OpenBSD instead of "AFGJPR".
+ [2851cd2da1c7]
+
+2016-11-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ Update year in license
+ [e370bf3d1035]
+
+2016-11-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [d524f0306467]
+
+ * doc/sudo.conf.cat, doc/sudoers.ldap.cat, doc/sudoreplay.cat:
+ regen
+ [185328ea20c3]
+
+ * include/sudo_debug.h, lib/util/sudo_debug.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoers_debug.c,
+ plugins/sudoers/visudo.c, src/sudo.c:
+ Add SUDO_DEBUG_INSTANCE_ERROR return value for sudo_debug_register()
+ and check for it in places where we check the return value of
+ sudo_debug_register().
+ [d1e74c5f21a6]
+
+2016-11-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ update for 1.8.19
+ [b248866c511d]
+
+2016-11-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.ac, plugins/sudoers/getspwuid.c:
+ Add support for getpwnam_shadow() on OpenBSD
+ [4db7ed374c33]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, plugins/sudoers/policy.c, src/sudo.c:
+ Add umask to user_info passed in from the front end to the plugin.
+ [4a4eee52a717]
+
+ * plugins/sudoers/auth/rfc1938.c:
+ Fix sign compare warning.
+ [8732d632cbff]
+
+ * MANIFEST, aclocal.m4, configure, configure.ac, m4/ax_append_flag.m4,
+ m4/sudo.m4:
+ Use AX_APPEND_FLAG instead of SUDO_APPEND_CPPFLAGS and direct
+ modification of LDFLAGS.
+ [c1464dcd45e0]
+
+ * MANIFEST, configure, configure.ac, plugins/sudoers/aixcrypt.exp:
+ Remove aixcrypt.exp, it was a remnant of the 90's crypto wars where
+ crypt() was not exported.
+ [785d57666d41]
+
+ * doc/TROUBLESHOOTING:
+ Remove obsolete solaris issue with snprintf
+ [3ce6cc899026]
+
+ * INSTALL:
+ SunOS 4.x is no longer supported
+ [2239eb30ff2c]
+
+2016-11-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/regress/sudo_conf/test1.in, lib/util/sudo_conf.c:
+ Plug memory leak when a particular Path is set more than once.
+ [debc97dac01d]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Add sudo_ldap_is_negated() and sudo_ldap_is_negated() functions and
+ use them to parse negated entries instead of doing it manually.
+ [12010b64afe5]
+
+ * plugins/sudoers/ldap.c:
+ Fix printing of sudoedit_follow in "sudo -l"
+ [2094a8f880c4]
+
+ * plugins/sudoers/sssd.c:
+ For "sudo -l" print sudoOption sudoedit_follow as FOLLOW.
+ [9c860b1fa721]
+
+ * config.h.in, configure, configure.ac, include/sudo_conf.h,
+ lib/util/regress/sudo_conf/conf_test.c,
+ lib/util/regress/sudo_conf/test1.out.ok, lib/util/sudo_conf.c,
+ lib/util/util.exp.in, plugins/sudoers/policy.c, src/exec_common.c,
+ src/load_plugins.c, src/parse_args.c:
+ Always define _PATH_SUDO_NOEXEC, _PATH_SUDO_SESH,
+ _PATH_SUDO_PLUGIN_DIR, even if only defined to NULL. This means the
+ accessors can always be present.
+
+ Use RTLD_PRELOAD_VAR instead of _PATH_SUDO_NOEXEC to tell when
+ noexec is available.
+
+ Add ENABLE_SUDO_PLUGIN_API and use it instead of
+ _PATH_SUDO_PLUGIN_DIR to tell when the plugin API is available.
+
+ Add sudo_conf_clear_paths() to clear the path values so the regress
+ tests are not affected by compile-time settings.
+ [2b05e4a143d9]
+
+ * plugins/sudoers/ldap.c:
+ Use readline() in sudo_ldap_read_secret()
+ [3f0506e5cbe3]
+
+2016-11-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/sudo_conf.c:
+ Get rid of struct sudo_conf_paths and just use #defined index values
+ to access the path values. Make all accessors available even when
+ the feature is not enabled.
+ [58d1ec6170a8]
+
+ * configure, configure.ac, lib/util/Makefile.in, lib/zlib/Makefile.in,
+ mkdep.pl, plugins/group_file/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in, src/Makefile.in:
+ Add ASAN_CFLAGS and ASAN_LDFLAGS and use -Wc prefix in ASAN_LDFLAGS
+ to prevent libtool from strippign them out. Avoid using ASAN flags
+ when building sudo_noexec.so.
+ [9644dd92e586]
+
+2016-11-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Disable noexec for HP-UX 10.x which probably doesn't support
+ LD_PRELOAD
+ [d87bc5ea4688]
+
+ * config.h.in, configure, configure.ac, plugins/sudoers/getspwuid.c:
+ Remove SunOS 4 support, it is not modern enough to run sudo.
+ [b6e15f8360b6]
+
+ * config.h.in, configure, configure.ac, plugins/sudoers/getspwuid.c:
+ Remove HP-UX 9 support, it is not modern enough for sudo.
+ [226dda48c1e1]
+
+ * config.h.in, configure, configure.ac, plugins/sudoers/auth/passwd.c,
+ plugins/sudoers/getspwuid.c:
+ Remove Ultrix support, modern sudo can't run on Ultrix anyway.
+ [95a11ef29a2b]
+
+ * MANIFEST, configure, configure.ac, lib/util/sudo_conf.c,
+ src/Makefile.in, src/exec_common.c,
+ src/regress/noexec/check_noexec.c, src/sudo_exec.h:
+ Add regress for noexec functionality
+ [2cadd8e04677]
+
+ * src/Makefile.in:
+ Unbreak sudo_noexec on macOS where shared libraries and dynamic
+ modules are different. We still want to install sudo_noexec.so
+ without the "lib" prefix so some hackery is required.
+ [93d7b69491a1]
+
+ * configure, configure.ac:
+ Don't enable noexec for AIX 5.0-5.2, we need 5.3 and above.
+ [92cad0180239]
+
+2016-11-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/Makefile.in:
+ Need to link sudo_noexec.so with -ldl for dlsym() on some platforms.
+ Otherwise, the wordexp(3) wrapper will fail due to an undefined
+ symbol. Bug #761
+ [120a317ce25b]
+
+ * plugins/sudoers/visudo.c:
+ In strict mode, go to the file/line with an undefined aliases or
+ aliases cycle directly.
+ [b4f51b79bd9e]
+
+2016-11-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in,
+ plugins/sudoers/alias.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/parse.h,
+ plugins/sudoers/regress/visudo/test2.err.ok,
+ plugins/sudoers/regress/visudo/test3.err.ok,
+ plugins/sudoers/visudo.c:
+ Store the file/lineno for alias and userspec entries so we can
+ provide that info if there is an error.
+ [7deb4e41ca7b]
+
+2016-11-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/rcstr.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/visudo.c,
+ plugins/sudoers/visudo_json.c:
+ Add simple reference-counted string allocator and use it for passing
+ around references to the sudoers path. This lets us avoid making
+ copies of the sudoers path for the errorfile as well as each
+ Defaults entry.
+ [afcff7b5b647]
+
+ * lib/util/sha2.c:
+ Cast len from size_t to uint64_t before bit shifting since we are
+ adding to count which is also uint64_t. Quiets a PVS-Studio warning.
+ [167210670b30]
+
+2016-11-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/regress/visudo/test7.out.ok,
+ plugins/sudoers/regress/visudo/test7.sh,
+ plugins/sudoers/regress/visudo/test8.err.ok,
+ plugins/sudoers/regress/visudo/test8.out.ok,
+ plugins/sudoers/regress/visudo/test8.sh:
+ Add checks for sudoers_locale early Defaults
+ [582c08c9418c]
+
+2016-11-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/ldap.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h,
+ plugins/sudoers/regress/parser/check_fill.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c,
+ plugins/sudoers/visudo_json.c:
+ Go back to parsing Defaults entries in update_defaults instead of as
+ sudoers is read. Otherwise, we cannot properly support early
+ defaults like sudoers_locale.
+ [ff1328a86b97]
+
+2016-11-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/parse_args.c, src/sudo.c, src/sudo.h:
+ Add the argument vector allocated for -s and -i mode to the garbage
+ collector list. Avoids an ASAN warning on exit when the -s or -i
+ flags are used.
+ [652691a5216b]
+
+2016-11-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ add missing sudo_pw_delref/sudo_gr_delref to plug memory leak
+ [c4ba4c26e0c1]
+
+ * mkpkg:
+ Use expr instead of POSIX sh numerical expression to avoid a syntax
+ error on older shells.
+ [638383bb40d5]
+
+2016-11-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, include/sudo_plugin.h:
+ Bump plugin minor version to 10 for sudo_mode, sudo_group and
+ sudo_user.
+ [0c65dc1f2874]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Fix a bug in host matching where a negated sudoHost entry would
+ prevent other sudoHosts following it from matching.
+ [40cbd5790106]
+
+ * plugins/sudoers/defaults.c:
+ Zero out sd_un before calling parse_default() so we don't try to
+ free stack garbage in the ldap/sssd backends.
+ [6b64a8e3a19d]
+
+2016-11-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Use "ret", not "rc" for the function return value.
+ [fdfe637adee6]
+
+ * include/sudo_compat.h, lib/util/strtomode.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/goodpath.c,
+ plugins/sudoers/logging.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/visudo.c, src/sesh.c, src/sudo.c, src/sudo_edit.c:
+ Use sys/stat.h defines instead of bare octal values.
+ [215c80e09830]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in, plugins/sudoers/iolog.c,
+ plugins/sudoers/policy.c:
+ Pass iolog mode, group and user from policy plugin to I/O log
+ plugin.
+ [1ed4967771c8]
+
+2016-11-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/ldap.c, plugins/sudoers/parse.h,
+ plugins/sudoers/regress/parser/check_fill.c, plugins/sudoers/sssd.c:
+ Instead of parsing sudoers Defaults twice, parse once while reading
+ sudoers and then just set the parsed value in update_defaults().
+ [370d51681c6e]
+
+ * plugins/sudoers/defaults.c:
+ Use "struct defaults *d" instead of "struct defaults *def"
+ throughout for consistency and to avoid confusino with "struct
+ def_values *def". Use "str" not "var" for the string argument to
+ convert and store in sd_un for the store_* functions.
+ [5cc3efc609df]
+
+ * plugins/sudoers/parse.c:
+ In display_bound_defaults() rename dtype arg -> deftype.
+ [b3323960e1db]
+
+2016-11-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/regress/sudo_conf/test4.err.ok,
+ lib/util/regress/sudo_conf/test5.err.ok,
+ plugins/sudoers/regress/visudo/test2.err.ok,
+ plugins/sudoers/regress/visudo/test3.err.ok:
+ Update error output to match quoting changes.
+ [27bbf5004d1e]
+
+ * plugins/sudoers/defaults.c:
+ Avoid passing in a struct sudo_defs_types pointer to the store
+ functions. Pass in a pointer to the union to fill instead.
+ [ea956d00aae3]
+
+ * plugins/sudoers/defaults.h:
+ no longer need struct defaults forward referebce
+ [21e34ca85de5]
+
+2016-11-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/sudo_conf.c, plugins/sudoers/alias.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/logging.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/visudo.c,
+ plugins/sudoers/visudo_json.c, src/load_plugins.c:
+ Use "double quotes" in messages instead of a combination of the
+ accent (grave) mark and apostrophe.
+ [10dee3ecf3e1]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Add file:linenumber prefix to all Defaults warnings so we can see
+ them when running sudo too. For LDAP/SSSD we print the sudoRole
+ instead of the file name and omit the line number.
+ [5c6b95cd3792]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Use sudoedit in examples instead of "sudo vi"
+ [6008c208682c]
+
+2016-11-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/parse.c, plugins/sudoers/parse.h,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c,
+ plugins/sudoers/visudo_json.c:
+ Only treat an unknown Defaults entry as a parse error in visudo, not
+ in sudo itself.
+ [8d8aa7ac5a32]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/visudo.c:
+ Instead of checking Defaults values after the fact, check them at
+ sudoers parse time. This makes it possible to display the file and
+ line number with the problem and for visudo to go right to the
+ error.
+ [ac66bd690d05]
+
+ * plugins/sudoers/alias.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/parse.h:
+ Refactor freeing of a member_list into free_members().
+ [d29daa01bb9c]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y:
+ add_defaults() now calls sudoerserror() itself instead of the caller
+ assuming any error means out of member.
+ [a25e51321e0b]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/mkdir_parents.c:
+ s/rval/ret/g -- old habits die hard
+ [fa55d08b233a]
+
+2016-10-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Remove inaccurate XXX comment, sudo_file_parse() sends mail on parse
+ error.
+ [052b0e112839]
+
+ * plugins/sudoers/visudo.c:
+ The fix for Bug #408 broke editing of files in an include dir that
+ have a syntax error. Normally, visudo does not edit those files, but
+ if a syntax error is detected in one, the user gets a chance to fix
+ it.
+ [6b00f9bfff31]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/sudoers.h, plugins/sudoers/visudo.c,
+ plugins/sudoers/visudo_json.c:
+ Make a copy of the current sudoers path when assigning errorfile.
+ Fixes a potential use after free in visudo when there is an error in
+ one of the include files.
+ [eb6db5d15b61]
+
+ * plugins/sudoers/sudoers_debug.c:
+ sudoers_debug_register() was not setting the active debug instance
+ to sudoers_debug_instance when called from the I/O log plugin. This
+ is because it relied on sudo_debug_register to do that but
+ sudoers_debug_parse_flags() doesn't set debug_files[]
+ sudoers_debug_instance is already set (we can only init sudoers
+ debug once).
+
+ To work around this, just make sudoers_debug_instance the active
+ debug instance in sudoers_debug_register() when it is already set.
+ [71b0221c8c28]
+
+ * src/load_plugins.c:
+ Fix pasto when setting I/O plugin debug files
+ [03c3aab22e65]
+
+ * plugins/sudoers/iolog.c:
+ use cp instead of *cur when comparing against plugin_path
+ [f2dfe69549f5]
+
+2016-10-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/mkdir_parents.c:
+ In sudo_mkdir_parents() inherit the gid of / instead of using gid 0
+ for the first component.
+ [5f2bf33bccb5]
+
+ * plugins/sudoers/iolog.c:
+ We want to inherit the gid from the parent directory when not
+ setting permissions on intermerdiate directories.
+ [845f5a20b5fa]
+
+2016-10-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/iolog.c,
+ plugins/sudoers/mkdir_parents.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/timestamp.c:
+ Move io_mkdir_parents() to its own file and use it in ts_mkdirs().
+ [c1d55f588a60]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/defaults.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Make the I/O log file/dir permissions and owner configurable.
+ [e7a74f3dfa56]
+
+ * lib/util/Makefile.in, mkdep.pl:
+ Add vsyslog.lo
+ [18362a9ae32e]
+
+ * configure, configure.ac:
+ sudo 1.8.19
+ [97743604e6e3]
+
+2016-10-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/defaults.c:
+ Don't try to syntax check an unrecognized Defaults value in visudo.
+ [e4972655b5d3]
+
+2016-10-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Create I/O log files with the same gid as the parent directory.
+ [0da5824e006d]
+
+ * plugins/sudoers/ldap.c:
+ Check for sudo_ldap_result_last_search() returning NULL. This can't
+ happen in practice because we always call
+ sudo_ldap_result_add_search() first which guarantees there is a
+ result to be found. Quiets a PVS-Studio warning.
+ [4f6074f40fbc]
+
+ * src/exec_pty.c:
+ Quiet a PVS-Studio warning about the spin loop when waiting for the
+ parent to assign us the terminal pgrp.
+ [d063a283477b]
+
+ * plugins/sudoers/env.c:
+ Fix incorrect strncmp() lengths. The check for USERNAME was only
+ looking at the first 5 characters (copy and paste error). The check
+ for SUDO_PS1 was not checking the trailing '=' character (off by one
+ error). Found by PVS-Studio.
+ [297380eb6940]
+
+ * plugins/sudoers/env.c:
+ When checking for old-style bash functions in the environment, check
+ for values starting with "() " (note the trailing space) rather than
+ "()". Bash will only treat the value as a function if the space
+ after "()" is present. The trailing space was already present in the
+ compare string but when it was added, the length passed to strncmp()
+ was not updated from 3 to 4. Found by PVS-Studio. No security
+ impact.
+ [7e35f39d356b]
+
+ * plugins/sudoers/set_perms.c:
+ Add some missing casts from uid_t/gid_t to int when printing uid/gid
+ values. We print these as signed so a value of -1 (no change) is
+ obvious. Quiets PVS-Studio warnings.
+ [9773e5b166e1]
+
+ * plugins/sudoers/timestamp.c:
+ def_timestamp_timeout is a double so compare against 0.0 not 0 to
+ avoid making it appear to be an integer type.
+ [8675db470ab7]
+
+ * plugins/sudoers/defaults.c:
+ When checking syslog facility or priority, move the string compare
+ into the body of the loop and return if it matches. If we finish the
+ loop it means we didn't find a match. This makes the code a little
+ bit more readable.
+ [d1df1649a01e]
+
+ * lib/util/strlcpy.c, lib/util/strnlen.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/env.c, plugins/sudoers/logging.c,
+ plugins/sudoers/visudo_json.c, src/env_hooks.c, src/exec_pty.c:
+ Replace bare ";" in the body of for() loops with "continue;" for
+ improved readability.
+ [92eff8dbe5f8]
+
+2016-10-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.guess, config.sub:
+ Update from http://git.savannah.gnu.org/gitweb/?p=config.git
+ [86e6144dfdd7]
+
+ * config.guess, config.sub, configure, ltmain.sh, m4/libtool.m4,
+ m4/ltoptions.m4, m4/ltsugar.m4, m4/ltversion.m4, m4/lt~obsolete.m4:
+ Update to libtool 2.4.6
+ [8d85d9e8687b]
+
+2016-10-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/vsyslog.c:
+ Use a static buffer if possible.
+ [758ce6478994]
+
+ * MANIFEST, configure, configure.ac, include/sudo_compat.h,
+ lib/util/vsyslog.c, plugins/sudoers/logging.c:
+ add vsyslog() for systems without it.
+ [c6457f333252]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ There are now 14 tag values, not 10. Don't bother mentioning the
+ number since it keeps increasing. Bug #759
+ [17e4c900dc12]
+
+2016-10-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.ac, plugins/sudoers/logging.c:
+ Use vsyslog() if available.
+ [ea9b7a51eaec]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/defaults.c,
+ plugins/sudoers/logging.c:
+ Add syslog_maxlen to control the max size of syslog messages.
+ [5f9872d2073f]
+
+2016-10-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/tgetpass.c:
+ Don't generate SIGTOU when restoring the terminal modes. It doen't
+ make sense to suspend the process only to restore the terminal
+ settings since in this case the shell has already taken ownership of
+ the tty.
+ [981c26f3fc8f]
+
+ * plugins/sudoers/sudoreplay.c, src/exec_pty.c, src/tgetpass.c:
+ The flush parameter of sudo_term_restore() is bool, not int.
+ [c2597f1881f3]
+
+2016-10-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in:
+ Add wordexp() to the list of functions wrapped by sudo_noexec.so.
+ [2e847ce3f02f]
+
+2016-10-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo_noexec.c:
+ Need RTLD_NEXT for wordexp() on dlopen() systems. It is missing on
+ AIX 5.1 at least.
+ [167a518d8129]
+
+ * src/sudo_noexec.c:
+ add missing guard around wordexp()
+ [7b8357b0a358]
+
+ * NEWS:
+ expand on 1.8.18p1 changes
+ [f560e06ad584]
+
+2016-10-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.ac:
+ sudo 1.8.18p1
+ [a36e17d1c5db]
+
+ * config.h.in, configure, configure.ac, src/sudo_noexec.c:
+ Fix configure check for seccomp filter on Linux
+ [5d88d7cda853]
+
+2016-10-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.ac, src/sudo_noexec.c:
+ Use a seccomp filter on Linux to disable execve(2) and execveat(2).
+ This still relies on LD_PRELOAD to work so it has the same issues as
+ the existing mether with respect to running 32-bit binaries on a
+ 64-bit kernel.
+ [59d76bdc0f0c]
+
+ * src/Makefile.in:
+ regen
+ [9e313cb0900b]
+
+ * plugins/sudoers/Makefile.in:
+ regen
+ [5ca77049e5cd]
+
+2016-10-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4, config.h.in, configure, configure.ac, src/sudo_noexec.c:
+ Wrap wordexp(3) in sudo_noexec.
+ [e7d09243e51b]
+
+2016-09-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ Clean .json files created by "make check"
+ [d214117fbda1]
+
+2016-09-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * po/ca.mo, po/da.mo, po/eo.mo, po/es.mo, po/eu.mo, po/fi.mo,
+ po/gl.mo, po/hr.mo, po/hu.mo, po/ko.mo, po/nl.mo, po/ru.mo,
+ po/sk.mo, po/sl.mo, po/sr.mo, po/tr.mo:
+ recompile .po files
+ [3d91cbf75744]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Fix matching when no sudoRunAsUser is present in a sudoRole. If only
+ a sudoRunAsGroup is present, match on the invoking user if the -g
+ option was specified and the group matched. If no sudoRunAsGroup is
+ present and the -g option was specified, allow it if it matches the
+ passwd gid of the runas user. This matches the behavior of the
+ sudoers backend.
+ [e1a52c34da5e]
+
+ * plugins/sudoers/match.c:
+ runas_pw can no longer be NULL
+ [020c6ddcae11]
+
+2016-09-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ RunAsGroup without RunAsUser issues
+ [52d1547c9d3a]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ user_matched and group_matched must be type int, not bool
+ [204d8de97a05]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/match.c,
+ plugins/sudoers/parse.h, plugins/sudoers/sssd.c:
+ Use RUNAS_USER_SPECIFIED and RUNAS_GROUP_SPECIFIED when deciding
+ whether to check runas user/group instead of checking runas_pw or
+ runas_gr.
+ [d17f223e8313]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ When matching against runas_default use userpw_matches() instead of
+ just strcasecmp().
+ [ce70077c5861]
+
+ * plugins/sudoers/testsudoers.c:
+ Set RUNAS_USER_SPECIFIED when -u is specified and/or
+ RUNAS_GROUP_SPECIFIED when -g is specified.
+ [fa7a1035a058]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Fix printing of the default runas user when a RunAsGroup is
+ specified but no RunAsUser is present.
+ [c05dabd194a1]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Only match against runas_default if both sudoRunAsUser and
+ sudoRunAsGroup are missing.
+ [019084f428b2]
+
+ * plugins/sudoers/match.c:
+ runas_pw can no longer be NULL here
+ [e73dcebafa15]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/match.c,
+ plugins/sudoers/parse.h, plugins/sudoers/sssd.c:
+ Update check for whether or not the runas user was set in the ldap
+ and sssd backends to match the sudoers file backend. Introduces the
+ runas_user_set() macro to improve readability. Previously, runas_pw
+ was set late, now it is set before checking sudoers.
+ [d8280d8a96c9]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ Document that negated sudoHosts are only supported by 1.8.18 and
+ higher.
+ [f56824fe61bc]
+
+ * plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/testsudoers/test4.sh,
+ plugins/sudoers/regress/testsudoers/test5.sh:
+ Disable Address Sanitizer leak detection for tests which generate
+ parse errors. The parser leaks a bit on error.
+ [4b0ddb11df3a]
+
+ * plugins/sudoers/sssd.c:
+ Fix underflow in get_ipa_hostname() when trimming trailing
+ whitespace.
+ [875f2f5cd363]
+
+2016-09-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Document negated sudoHost entries.
+ [41d9853f89f7]
+
+ * plugins/sudoers/sssd.c:
+ Support negated sudoHost entries.
+ [7c25f9111633]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ Document negated sudoHost entries.
+ [6c8444c6bc6c]
+
+ * plugins/sudoers/ldap.c:
+ Support negated sudoHost entries.
+ [1899906b8ef4]
+
+2016-09-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/match.c:
+ Don't check the username when matching a host netgroup unless
+ def_netgroup_tuple is enabled.
+ [238c8064542f]
+
+ * plugins/sudoers/match.c:
+ Move valid domain name check into a new valid_domain() function. Fix
+ memory leak if getdomainname(2) fails and avoid using heap garbage
+ for the domain name matching in this case.
+ [946f2441c90a]
+
+2016-09-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po, po/it.mo,
+ po/it.po:
+ sync with translationproject.org
+ [40eab0801eae]
+
+2016-09-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Add back line mistakenly removed in 0cf2a9351740
+ [8622c83c1474]
+
+ * plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po, po/nb.mo,
+ po/nb.po:
+ sync with translationproject.org
+ [f180826bb77b]
+
+2016-09-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Bug #757
+ [de67bc9e26f8]
+
+ * plugins/sudoers/sudoers.c:
+ Fix typo that broke short host name matching when the fqdn flag is
+ enabled. Bug #757
+ [605c03afc80f]
+
+2016-09-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_debug.h, lib/util/aix.c, lib/util/fnmatch.c,
+ lib/util/getgrouplist.c, lib/util/secure_path.c,
+ lib/util/setgroups.c, lib/util/strtoid.c, lib/util/sudo_conf.c,
+ lib/util/sudo_debug.c, plugins/sample/sample_plugin.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/check.c,
+ plugins/sudoers/env.c, plugins/sudoers/goodpath.c,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/interfaces.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/logging.c,
+ plugins/sudoers/match.c, plugins/sudoers/parse.c,
+ plugins/sudoers/policy.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/timestamp.c, plugins/sudoers/visudo.c,
+ plugins/sudoers/visudo_json.c, src/env_hooks.c, src/exec.c,
+ src/exec_pty.c, src/get_pty.c, src/hooks.c, src/load_plugins.c,
+ src/regress/ttyname/check_ttyname.c, src/selinux.c, src/signal.c,
+ src/sudo.c, src/sudo_edit.c, src/tgetpass.c, src/ttyname.c,
+ src/utmp.c:
+ Be consistent with the naming of the variable used to store the
+ function return value. Previously, some code used "rval", some used
+ "ret". This standardizes on "ret" and uses "rc" for temporary return
+ codes.
+ [017866310d24]
+
+2016-09-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/ca.po, plugins/sudoers/po/cs.mo,
+ plugins/sudoers/po/cs.po, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/el.po, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/eu.po, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/fr.po, plugins/sudoers/po/hr.po,
+ plugins/sudoers/po/hu.po, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/ko.po, plugins/sudoers/po/lt.po,
+ plugins/sudoers/po/nb.po, plugins/sudoers/po/nl.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/ru.po, plugins/sudoers/po/sk.po,
+ plugins/sudoers/po/sl.po, plugins/sudoers/po/sr.po,
+ plugins/sudoers/po/sv.mo, plugins/sudoers/po/sv.po,
+ plugins/sudoers/po/tr.po, plugins/sudoers/po/uk.mo,
+ plugins/sudoers/po/uk.po, plugins/sudoers/po/vi.mo,
+ plugins/sudoers/po/vi.po, plugins/sudoers/po/zh_CN.mo,
+ plugins/sudoers/po/zh_CN.po, po/ca.po, po/cs.mo, po/cs.po, po/da.po,
+ po/de.mo, po/de.po, po/eo.po, po/es.po, po/eu.po, po/fi.po,
+ po/fr.mo, po/fr.po, po/gl.po, po/hr.po, po/hu.po, po/it.po,
+ po/ja.mo, po/ja.po, po/ko.po, po/nb.po, po/nl.po, po/pl.mo,
+ po/pl.po, po/pt_BR.mo, po/pt_BR.po, po/ru.po, po/sk.po, po/sl.po,
+ po/sr.po, po/sv.mo, po/sv.po, po/tr.po, po/uk.mo, po/uk.po,
+ po/vi.mo, po/vi.po, po/zh_CN.mo, po/zh_CN.po:
+ sync with translationproject.org
+ [6312962695df]
+
+ * MANIFEST, NEWS, doc/CONTRIBUTORS, po/nn.mo, po/nn.po:
+ Norwegian Nynorsk translation of sudo from translationproject.org
+ [05203a266265]
+
+ * NEWS:
+ Fix for Bug #756
+ [89ff21579216]
+
+2016-09-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ In sudoers_main() avoid setting rval prematurely. Prevents a crash
+ when auditing fails after successfully authenticating. Bug #756
+ [d17a06bce04c]
+
+ * plugins/sudoers/defaults.c:
+ Apply match_group_by_gid early.
+ [1259c7fd66ca]
+
+2016-09-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ update
+ [292a9e21474e]
+
+ * src/ttyname.c:
+ Don't disable large file support for Linux, just SVR4-style /proc.
+ Otherwise, stat(2) may fail on Linux when running a 32-bit sudo on a
+ 64-bit machine. Bug #755
+ [09450ce8b8a8]
+
+2016-09-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_util.h:
+ Make sudo_parseln() flags hex to make it more obvious that they are
+ bit flags.
+ [b912a078047e]
+
+ * plugins/sudoers/env.c:
+ Don't try to support line continuation in /etc/environment.
+ [d7e30e821c0e]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, plugins/sudoers/ldap.c:
+ No line continuation support in ldap.conf.
+ [211caaba2395]
+
+ * include/sudo_util.h, lib/util/parseln.c:
+ Add flag to sudo_parseln() to disable line continuation support.
+ [d2820247fc07]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ A comment character ('#') is only special at the beginning of the
+ line.
+ [b3b67b7e4fc0]
+
+ * include/sudo_util.h, lib/util/parseln.c,
+ lib/util/regress/sudo_parseln/parseln_test.c, lib/util/sudo_conf.c,
+ lib/util/util.exp.in, plugins/sudoers/env.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/sudo_nss.c:
+ Add a flags option to sudo_parseln() and a flag to only mach
+ comments at the beginning of the line. Use the flag when parsing
+ ldap.conf.
+ [40c560fc9a10]
+
+ * src/sudo.c:
+ If get_process_ttyname() fails for errno != ENOENT, just warn
+ instead of making it a fatal error. Bug #755
+ [1a028b861801]
+
+2016-08-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/mkdefaults:
+ use strict
+ [681281bc0f6d]
+
+ * plugins/sudoers/def_data.h, plugins/sudoers/mkdefaults:
+ Define def_foo in terms of the I_FOO index instead of a bare number.
+ [abb119f84ae6]
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/hr.mo, plugins/sudoers/po/hr.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po:
+ sync with translationproject.org
+ [d339717f8692]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Mention that match_group_by_gid has no effect when sudoers is stored
+ in LDAP.
+ [5eb6ae45c699]
+
+ * include/sudo_compat.h, src/sudo.c:
+ Use W_EXITCODE to construct the wait status if sudo could not
+ execute the command. Fixes the sudo exit value for exec(3) failure.
+ [95eae2d60292]
+
+ * src/exec.c:
+ fix brace style
+ [54448c10b6b5]
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [794b06ba727b]
+
+ * src/sudo.c:
+ It is possible for get_user_info() to fail for reasons other than
+ ENOMEM so print the warning message there rather than in main().
+ [8c24df8d6b78]
+
+2016-08-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ match_group_by_gid is only available in sudo 1.8.18 and above
+ [dd237eb540d0]
+
+ * doc/UPGRADE:
+ Mention match_group_by_gid
+ [417f27e9059a]
+
+ * NEWS, doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document match_group_by_gid
+ [2234997acb8d]
+
+ * plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/pwutil.c:
+ Add match_group_by_gid Defaults option to allow sites with slow
+ group lookups and a small number of groups in sudoers to match
+ groups by group ID instead of by group name.
+ [20714580da96]
+
+2016-08-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Mention "sudo -l command" bug fix.
+ [cb8ade186880]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Fix "sudo -l command" in the LDAP and SSS backends when the command
+ is not allowed.
+ [631038350b2a]
+
+2016-08-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/defaults.c:
+ Use sudo_strsplit() instead of doing the equivalent manually.
+ [9eb6d1cc78bd]
+
+2016-08-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Move SIGPIPE bug fix to 1.8.18 where it belongs
+ [52509fd0100e]
+
+ * plugins/sudoers/defaults.c:
+ Fix memset size typo in previous commit.
+ [e00299f7c50f]
+
+ * plugins/sudoers/regress/visudo/test6.out.ok,
+ plugins/sudoers/regress/visudo/test6.sh:
+ Add regress for check_defaults() use-after-free bug.
+ [0b362678ca10]
+
+ * MANIFEST, plugins/sudoers/defaults.c:
+ Fix use-after-free in check_defaults(), reported by Radovan Sroka of
+ RedHat.
+ [ab3a4227c12f]
+
+2016-08-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ SIGPIPE bug fix
+ [24c9a12f7e59]
+
+ * src/signal.c:
+ Now that we ignore SIGPIPE in sudo we need to restore it at exec
+ time. Problem reported by Radovan Sroka of RedHat.
+ [3cfa7e3510ff]
+
+2016-08-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ Fix appending to make_opts
+ [abe28b6b7663]
+
+ * NEWS:
+ Add Bug #753 and fix reference to Bug #752.
+ [e8c959e1cd6c]
+
+2016-08-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/sr.mo, plugins/sudoers/po/sr.po, po/da.mo,
+ po/da.po, po/pt_BR.mo, po/pt_BR.po:
+ sync with translationproject.org
+ [219c3f0aeee7]
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen pot files
+ [d0c56a4ff553]
+
+2016-08-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Update with logging changes.
+ [f41beca23b99]
+
+ * plugins/sudoers/logging.c:
+ Avoid duplicate warnings when we cannot write to the log file. Also
+ send the warning in mail if possible.
+ [9b8509cff137]
+
+ * plugins/sudoers/iolog.c, src/exec_pty.c, src/sudo.c, src/sudo.h:
+ Move the ignoring of I/O log plugin errors into the I/O log plugin
+ itself.
+ [25b7fd056614]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/defaults.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.c, src/exec_pty.c, src/sudo.c, src/sudo.h:
+ Make the behavior when we cannot write to a log or audit file
+ configurable. File log failures are ignored by default for
+ consistency with syslog. Audit errors are ignored by default to
+ allow the admin to fix the issue. I/O log file errors are still
+ fatal by default since if I/O logging is activated it is usually to
+ have an audit trail. Bug #751
+ [dbd085e7c736]
+
+2016-08-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/logging.c:
+ Make sure we print an error message to stderr (and not just send
+ mail) if do_logfile() fails. Bug #751
+ [7884a23a0cdc]
+
+2016-08-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/pwutil.c:
+ Separate out the supplemental group ID checks from the supplemental
+ group name checks in user_in_group(). We now call sudo_get_gidlist()
+ only when the group name in sudoers begins with a '#' (which is
+ seldom used).
+ [80534785d8b7]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/policy.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/pwutil.h,
+ plugins/sudoers/pwutil_impl.c, plugins/sudoers/set_perms.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Cache the user's group IDs and group names separately and only
+ resolve group IDs -> names when needed. If the sudoers file doesn't
+ contain groups we will no longer try to resolve all the user's group
+ IDs to names, which can be expensive on some systems.
+ [8ce3564e896e]
+
+2016-08-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/defaults.c:
+ Remove the "op" parameter from all the store_foo() functions except
+ store_list() where it is actually needed. For the others, a NULL
+ value indicates the setting was negated. This unconfuses static
+ analyzers (and perhaps humans too).
+ [fca031b57f15]
+
+ * plugins/sudoers/defaults.c:
+ Flags always have a NULL value. Regression introduced by refactor of
+ set_default_entry().
+ [71fe4fad097b]
+
+ * plugins/sudoers/defaults.c:
+ Set rc to true when setting a flag Defaults value.
+ [cf016b6aedd4]
+
+ * src/utmp.c:
+ suppress a cppcheck false positive
+ [0d44aa7cf05c]
+
+ * plugins/sudoers/defaults.c:
+ Refactor the error parts of set_default_entry() so the switch() is
+ mostly just calls to store_foo() functions. Avoids a lot of
+ duplicated error checking and silences a cppcheck false positive.
+ [1112b894007c]
+
+ * plugins/sudoers/defaults.c:
+ In set_default_entry() check for unsupported Defaults type.
+ [beb1ae20179f]
+
+ * lib/util/aix.c:
+ Add missing break in switch that sets the max limit for
+ RLIMIT_NOFILE. Found by cppcheck.
+ [39b1979b1b92]
+
+ * plugins/sudoers/defaults.c:
+ Check sudoers_initlocale return value and treat as oom. Coverity CID
+ 141832
+ [b1cad9d6c49d]
+
+2016-08-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/match.c, plugins/sudoers/parse.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/testsudoers.c:
+ Set runas_pw early and adjust runaslist_matches() to deal. Since we
+ now set runas_default early there is no need to call update_defaults
+ with SETDEF_RUNAS after sudoers has been parsed.
+ [35e0b08219a8]
+
+2016-08-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/defaults.c, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/testsudoers.c:
+ Load sudoers group plugin via an early callback.
+ [0fc4382cd6e4]
+
+ * sudo.pp:
+ System Integrity Protection on Mac OS X won't allow us to write
+ directly to /etc or /var. We must install in /private/{etc,var}
+ instead.
+ [831c78241e78]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document that fqdn, runas_default and sudoers_locale are parsed
+ early.
+ [beb4868c449e]
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo_plugin.cat,
+ doc/sudoers.cat, doc/sudoers.ldap.cat, doc/sudoreplay.cat,
+ doc/visudo.cat:
+ Regen for 1.8.18
+ [eb4feabb8fee]
+
+2016-08-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/defaults.h, plugins/sudoers/ldap.c,
+ plugins/sudoers/sssd.c:
+ Avoid passing around struct defaults when it is not needed. As a
+ result, we no longer need to include gram.h in the LDAP and SSSD
+ backends.
+ [14d0bfdc8bd2]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Instead of deferring setting early defaults until we have traversed
+ the entire defaults list, just defer running the callbacks.
+ Otherwise, if the last early default setting we see has a bad value
+ we won't set any defaults of that type even if there was an earlier
+ one that was valid.
+ [552863e5a097]
+
+ * plugins/sudoers/defaults.c:
+ Run callbacks once in set_default_entry() instead of each of the
+ store_foo() functions.
+ [b92b51c67845]
+
+2016-08-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ Use /proc/cpuinfo on Linux instead of running lscpu
+ [450ea436dbe4]
+
+ * mkpkg:
+ If using GNU make on a multi-cpu system, use the -j flag to run make
+ jobs in parallel, up to the number of cpus/cores.
+ [7a6670de96dc]
+
+2016-07-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo.c:
+ Only check SUDO_USER if euid is 0
+ [f42d00c94817]
+
+2016-07-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo.c:
+ Initialize sudo_user based on the SUDO_USER environment variable if
+ present. This allows things like :Defaults:username editor=foo" to
+ work when visudo is run via sudo.
+ [a526d6f74198]
+
+2016-07-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Add function name in "command resumed" debug message
+ [e209f199a79f]
+
+ * src/exec_pty.c:
+ If waitpid() returns 0 or -1, display a warning, this should never
+ happen. Add a check for unhandled wait status (also should never
+ happen).
+ [983a0b79b527]
+
+ * plugins/sudoers/defaults.c:
+ Flag settings have a NULL value so we can't use that to test whether
+ an entry in struct early_default is set or not. Add a "set" member
+ and use that instead.
+ [68a7c0de9b0e]
+
+2016-07-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Explicitly check for a continued process with waitpid(2). Otherwise,
+ waitpid() will return 0 when the command is resumed after being
+ suspended, which we were treating the same as -1. Fixes suspend and
+ resume on Linux and probably others.
+ [54a464b116ad]
+
+ * plugins/sudoers/defaults.c:
+ Fix --with-fqdn, the value should be NULL since it is a flag.
+ [95bc8b82911e]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Add support for early defaults to the ldap and sssd backends.
+ [3a034360c177]
+
+2016-07-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo_edit.c:
+ Repair symlink check in sudo_edit_openat_nofollow() on systems
+ without O_NOFOLLOW, it must be done relative to dfd. Previously the
+ lstat() would always fail, possibly leading to a false positive.
+ Also add an early symlink check like in sudo_edit() while here.
+ [f72901c7f7cc]
+
+ * src/sudo_edit.c:
+ On systems that lack the O_NOFOLLOW open(2) flag, check in
+ sudo_edit_open() whether the path to be opened is symlink before
+ opening it. This is racey but we detect losing the last post-open
+ and it is better to fail early if possible. When editing a link to a
+ non-existent file, a zero-length file will be left behind but it is
+ too dangerous to try and remove it after the fact. Bug #753
+ [dac04f305262]
+
+ * src/sudo_edit.c:
+ Update debug_decl for sudo_edit_openat_nofollow() Remove unused
+ variables when O_NOFOLLOW is not present.
+ [8dc0afb1de58]
+
+2016-07-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/visudo.c:
+ Split set_default_entry() out of set_default() so we can call it
+ from check_defaults() to validate the defaults value. In visudo,
+ suppress warnings from update_defaults() and rely on
+ check_defaults() to provide warnings.
+ [7d9b50f42d0b]
+
+ * plugins/sudoers/defaults.c:
+ Split binding match code out of default_type_matches() into
+ default_binding_matches(). We can now use default_type_matches() in
+ check_defaults().
+ [c158768b12c5]
+
+ * plugins/sudoers/visudo.c:
+ Pass quiet flag to init_parser() and update_defaults() when doing
+ first parse of sudoers.
+ [3af76c1a0d84]
+
+2016-07-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/ldap.c, plugins/sudoers/parse.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ Update defaults in visudo after sudoers has been edited so we pick
+ up locale changes. The init_defaults() function will now re-init the
+ sudoers locale.
+ [ceb099392289]
+
+2016-07-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/testsudoers.c:
+ Set sudoers locale before calling sudoersparse(). We don't need to
+ restore the user's locale since warnings are displayed in the user's
+ locale anyway.
+ [c44a38a496d1]
+
+ * plugins/sudoers/visudo.c:
+ Set the locale to the sudoers locale when parsing and restore the
+ user's locale afterward. Also set the warn/fatal locale helper
+ function so warning messages during a sudoers parse are displayed in
+ the user's own locale.
+ [a0b2cdb69d43]
+
+ * plugins/sudoers/logging.h:
+ Add forward decl of union sudo_defs_val to silence a gcc warning.
+ [9e717510f132]
+
+ * plugins/sudoers/sudoers.c:
+ Set the warn/fatal locale helper function in sudoers_policy_init()
+ so warning messages during sudoers loading are displayed in the
+ user's own locale.
+ [b6c7bab1ca80]
+
+ * plugins/sudoers/locale.c, plugins/sudoers/logging.h,
+ plugins/sudoers/sudoers.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c:
+ Move sudoers locale callback function to locale.c and user it in
+ visudo and testsudoers.
+ [7c4e9a71e252]
+
+ * plugins/sudoers/sudoers.c:
+ In cb_sudoers_locale() actually set the locale in addition to
+ storing its name. Otherwise, it won't take effect until sudoers
+ lookup time.
+ [ceb446c2168b]
+
+ * plugins/sudoers/defaults.c:
+ Fix regression that would cause early defaults entries to be set
+ multiple times.
+ [5f5cd02d5f0f]
+
+ * NEWS, configure, configure.ac:
+ sudo 1.8.18
+ [7c778904c39b]
+
+2016-07-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/sudoers.c:
+ Only set early defaults once, regardless of how many times the
+ variable is set in sudoers. This avoids running an early callback
+ more than once. For example, we don't want to call cb_fqdn() if sudo
+ is compiled with FQDN set but sudoers has "Defaults !fqdn".
+ [0c5d80939ea2]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h:
+ Make strings const in functions that set defaults as they are not
+ modified.
+ [d01f22ab1902]
+
+ * plugins/sudoers/sudoers.c:
+ In cb_fqdn() just return if the fqdn flag is set to false.
+ [0cb3d78aa944]
+
+2016-07-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/defaults.c:
+ Implement callbacks for defaults flags (T_FLAG).
+ [936adcc98800]
+
+ * plugins/sudoers/sudoers.c:
+ add debug_decl for cb_runas_default and cb_sudoers_locale
+ [4667b1e14172]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/sudoers.c:
+ Convert fqdn to a callback and add it to the list of early defaults.
+ [df863787cf5e]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/iolog.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/testsudoers.c:
+ Change defaults callbacks to take a union sudo_defs_val * instead of
+ a char *.
+ [c7730fa19e46]
+
+ * plugins/sudoers/defaults.c:
+ When updating defaults, process certain values fist since they can
+ influence how other defaults are parsed. Currently, runas_default
+ and sudoers_locale are processed early.
+ [32062737a1ae]
+
+2016-07-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/toke_util.c:
+ Fix typo introduced in last commit to fix fill_args() overflow
+ check.
+ [535d13b81c5d]
+
+ * plugins/sudoers/toke_util.c:
+ Fix underflow checl in fill_args().
+ [2c6852e65ad6]
+
+ * plugins/sudoers/toke_util.c:
+ Make sure we account for the trailing NUL when computing arg_size in
+ fill_args(). Bug #752
+ [c73c1ea4b230]
+
+ * plugins/sudoers/toke_util.c:
+ Make arg_size and arg_len unsigned since we do bitwise operations on
+ them.
+ [0a551c7a5e67]
+
+2016-07-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/Makefile.in, lib/zlib/Makefile.in,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/system_group/Makefile.in,
+ src/Makefile.in:
+ Only remove backup files as part of "make uninstall" when
+ INSTALL_BACKUP is set.
+ [c2541d2de89c]
+
+ * configure, configure.ac, lib/util/Makefile.in, lib/zlib/Makefile.in,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/system_group/Makefile.in,
+ src/Makefile.in:
+ Only keep backups of installed files on HP-UX where you cannot
+ unlink a shared library that is in use.
+ [8763a1d0d515]
+
+2016-07-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Ignore a missing or insecure #includedir, it is not a fatal error.
+ [8a82818c9f0d]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Make sure we always call sudoerserror() on error in
+ read_dir_files(), otherwise sudo will not treat it as a fatal error.
+ [1a38da425ca0]
+
+2016-06-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Set the sudoers locale before opening the sudoers file. Previously
+ the sudoers locale was used when evaluating sudoers but not during
+ the inital parse. Bug #748
+ [c8deb0da75b4]
+
+ * plugins/sudoers/locale.c:
+ Add debugging
+ [5fbe2f109b92]
+
+ * plugins/sudoers/Makefile.in:
+ Don't link test programs with the sudoers-specific locale code if we
+ don't need to.
+ [41224154534e]
+
+ * plugins/sudoers/Makefile.in:
+ sudoreplay does not need to link with the sudoers-specific locale
+ code.
+ [348638a68f69]
+
+2016-06-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y:
+ new_digest was prototyped as static but not explicitly declared
+ static.
+ [52949a024acb]
+
+ * configure, configure.ac:
+ Some versions of HP-UX 11.11 do not expose struct sockaddr_ext if
+ _XOPEN_SOURCE_EXTENDED is defined. Only define
+ _XOPEN_SOURCE_EXTENDED if we can still compile net/if.h.
+ [0189ff7daa63]
+
+ * plugins/sudoers/Makefile.in:
+ Some versions of HP-UX make will ignore suffix rules if they are
+ empty.
+ [cffeee232752]
+
+2016-06-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Don't skip debug printfs in handle_sigchld() just because execve()
+ returned an error.
+ [0cf2a9351740]
+
+ * include/compat/charclass.h, include/sudo_compat.h, lib/util/aix.c,
+ lib/util/getaddrinfo.c, lib/util/sudo_debug.c,
+ plugins/sudoers/insults.h,
+ plugins/sudoers/regress/parser/check_base64.c,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/sudoers_debug.c:
+ Add definition of nitems for those without it and use it throughout.
+ [4b30c8834fdd]
+
+2016-06-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Update copyright year.
+ [638c964e44fd]
+
+ * NEWS, configure, configure.ac:
+ Sudo 1.8.17p1
+ [bc30a172370c]
+
+ * src/sudo.c, src/sudo.h:
+ Set user groups in exec_setup() if they were not already set by
+ policy_init_session(). Bug #749
+ [3bf16489800c]
+
+2016-06-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in:
+ Point the reader to the sudoers manual for the list of supported
+ arguments after the plugin path.
+ [40cbfa5deeb1]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ forgot to update date in last commit
+ [3872a46e229b]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ Fix typo; cn=default should be cn=defaults
+ [06e097667465]
+
+2016-06-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/Makefile.in, lib/zlib/Makefile.in,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/system_group/Makefile.in,
+ src/Makefile.in:
+ Fold lines at 80 characters for the clean: target
+ [651623231cd8]
+
+ * lib/util/Makefile.in:
+ Remove mksiglist, siglist.c, mksigname, signame.c as part of
+ "distclean"
+ [ed7f58685633]
+
+2016-06-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po:
+ sync with translationproject.org
+ [a3bb8c15ef3d]
+
+ * plugins/sudoers/sssd.c:
+ LDAP sudoers doesn't support negated users, groups or netgroups.
+ [d6585245c24d]
+
+2016-06-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Bug #746
+ [e0bba3ae78c2]
+
+ * plugins/sudoers/match.c:
+ When matching paths with glob(3), check returned matches against
+ user_cmnd first if it is fully-qualified. This avoids a lot of
+ needless stat(2) calls and avoids a mismatch between safe_cmnd and
+ argv[0] if there are multiple matches with the same inode/dev due to
+ links. Bug #746.
+ [29bdba0cf2eb]
+
+ * NEWS:
+ Add execve failure in pty bug fix.
+ [941672cc6793]
+
+ * plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po:
+ sync with translationproject.org
+ [a4f789cedecc]
+
+ * src/exec_pty.c:
+ In handle_sigchld() fix the return value when we've already received
+ an exec error. We don't want to overwrite the error status but we do
+ need to indicate that the command is no longer running. Fixes as
+ hang on execve(2) error when running in a pty.
+ [797bed2c39a7]
+
+ * src/exec.c, src/exec_common.c:
+ Move sudo_debug_execve() call into sudo_execve().
+ [ab2ea3459a7c]
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/hr.mo, plugins/sudoers/po/hr.po,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/sv.mo, plugins/sudoers/po/sv.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po, po/sr.mo,
+ po/sr.po, po/sv.mo, po/sv.po:
+ sync with translationproject.org
+ [046ba9a0fca8]
+
+2016-06-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ update for 1.8.17 final
+ [a2f02775aba5]
+
+ * lib/util/aix.c:
+ Fix setting of hard stack limit when stack_hard is not specified in
+ /etc/security/limits. When 64-bit resource limits are supported we
+ can use the default value of 8388608 512-byte blocks directly. We
+ should only resort to using RLIM_SAVED_MAX for 32-bit resource
+ limits.
+ [cc4933fc41bd]
+
+2016-06-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [4ab85a46cf63]
+
+2016-06-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sssd.c:
+ Ignore empty ipa_hostname
+ [9421ade7b47f]
+
+ * plugins/sudoers/sssd.c:
+ Better martching of ipa_hostname in sssd.conf
+ [abd53491cb4b]
+
+2016-06-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, configure, configure.ac, pathnames.h.in,
+ plugins/sudoers/sssd.c:
+ Use the value of ipa_hostname from /etc/sssd/sssd.conf if present
+ instead of the system hostname.
+ [3f5cffcd8432]
+
+2016-06-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sssd.c:
+ When matching host, short-circuit the loop when we get a match. Only
+ check username as part of the netgroup when netgroup_tuple is
+ enabled.
+ [2eab4070dcf7]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Avoid using !strcmp()
+ [f976b3d973e0]
+
+2016-06-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sssd.c:
+ SSSD doesn't handle netgroups, we have to ensure they are correctly
+ filtered in sudo. The rules may contain mixed sudoUser specification
+ so we have to check not only for netgroup membership but also for
+ user and group matches. Adapted from a patch from Daniel Kopecek.
+ [50d8d88bcc28]
+
+2016-06-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/pam.c:
+ Return PAM_CONV_ERR from the conversation function if getpass
+ returns NULL or the user pressed ^C.
+ [bec7e2ec26ff]
+
+ * plugins/sudoers/base64.c:
+ Make base64 decoding table-driven.
+ [2d001c111552]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Back out cfa26b99228f, it was already fixed differently. Caught by
+ regress checks.
+ [0584f80e9951]
+
+2016-05-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Allow double-quoted groups and netgroups to be part of a Defaults
+ spec. From Daniel Kopecek.
+ [cfa26b99228f]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ The sudoers.ldap manual is installed in section 4 or 5, not 1m or 8.
+ Also fix the section for ldap.conf cross-references.
+ [eb1c0a2b84a1]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ Fix copy pasta, "sudoNotAfter" not "sudoNotBefore". Add missing word
+ "order" in a sentence describing sudoOrder.
+ [653cb783f89b]
+
+ * plugins/sudoers/sssd.c:
+ For sudo -ll (long list) print the SSSD role just like we do for the
+ LDAP backend. Adapted from sudo-1.8.6p3-sssdrulenames.patch
+ [46f962b1f3ef]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Setting timestamp_timeout less than zero only lasts until the next
+ reboot. Adapted from a RedHat patch.
+ [f8ce1dfebfe9]
+
+ * po/it.mo, po/it.po, po/nb.mo, po/nb.po:
+ sync with translationproject.org
+ [31b55426358b]
+
+2016-05-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/conversation.c:
+ fputs() is now specified as returning non-negative on success, not
+ explicitly zero. Fixes a failure on glibc.
+ [55f8a25d4af4]
+
+ * src/conversation.c:
+ Don't try to dereference replies[] if it is a NULL pointer.
+ [c4fdd838f2f5]
+
+ * plugins/sudoers/policy.c:
+ sudo_version should be unsigned
+ [7719d425c65a]
+
+ * plugins/sudoers/po/ca.mo, plugins/sudoers/po/ca.po,
+ plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/hr.mo, plugins/sudoers/po/hr.po,
+ plugins/sudoers/po/sv.mo, plugins/sudoers/po/sv.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po, po/ca.mo,
+ po/ca.po, po/cs.mo, po/cs.po, po/da.mo, po/da.po, po/de.mo,
+ po/de.po, po/fr.mo, po/fr.po, po/hr.mo, po/hr.po, po/ja.mo,
+ po/ja.po, po/pl.mo, po/pl.po, po/sk.mo, po/sk.po, po/sv.mo,
+ po/sv.po, po/uk.mo, po/uk.po, po/vi.mo, po/vi.po, po/zh_CN.mo,
+ po/zh_CN.po:
+ sync with translationproject.org
+ [e40cdc972d19]
+
+ * MANIFEST, NEWS, doc/CONTRIBUTORS, plugins/sudoers/po/ko.mo,
+ plugins/sudoers/po/ko.po, po/ko.mo, po/ko.po:
+ Korean translation for sudo and sudoers from translationproject.org.
+ [188ffbed5bf2]
+
+ * NEWS, plugins/sudoers/auth/pam.c:
+ Ignore PAM_SESSION_ERR from pam_open_session() since this can
+ apparently happen on systems using Solaris-derived PAM. Other errors
+ from pam_open_session() are treated as fatal. This avoids the
+ "policy plugin failed session initialization" error message seen on
+ some systems.
+ [0f7f3e7ead21]
+
+2016-05-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, src/exec_pty.c:
+ Don't read from stdin when flushing final buffers in blocking mode.
+ Reading from the pipe can block too if the other end is not closed.
+ [a651f913a1ef]
+
+2016-05-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Mention visudo -x change.
+ [2fd35df055b2]
+
+ * plugins/sudoers/regress/sudoers/test1.json.ok,
+ plugins/sudoers/regress/sudoers/test14.json.ok,
+ plugins/sudoers/regress/sudoers/test15.json.ok,
+ plugins/sudoers/regress/sudoers/test16.json.ok,
+ plugins/sudoers/regress/sudoers/test2.json.ok,
+ plugins/sudoers/visudo_json.c:
+ There's no need to escape forward slashes in JSON output. While it
+ is legal to escape a forward slash, it is not required.
+ [044710f516a9]
+
+ * doc/UPGRADE:
+ Document that in 1.8.12 sudo started being able to check the NIS
+ domain on Solaris.
+ [bced94478c0e]
+
+2016-05-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Better description of the I/O logging pipe issue.
+ [6eee2f8a1fae]
+
+ * src/exec_pty.c:
+ In del_io_events(), avoid reading from the pty master in blocking
+ mode. We now do two passes, one with SUDO_EVLOOP_NONBLOCK and
+ another that could block if stdin is a pipe. This ensures we consume
+ the pipe until EOF.
+ [564ae2b4c305]
+
+ * lib/util/event.c:
+ Improve debug info in sudo_ev_add() and sudo_ev_del()
+ [ca839439ff22]
+
+ * src/exec_pty.c:
+ In pty_close(), call del_io_events with the SUDO_EVLOOP_ONCE flag so
+ the event loop will exit after a single run through. Otherwise, we
+ may hang at exit on non-BSD systems.
+ [e6c38d5a341b]
+
+2016-05-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * po/sudo.pot:
+ regen
+ [18a4570be506]
+
+2016-05-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Bump I/O buffer size to 64K. We don't use PIPE_BUF or _PC_PIPE_BUF
+ for this because that corresponds to the value for atomic pipe
+ writes. The actual pipe buffer is much larger on modern systems and
+ 64K is what BSD and Linux support for large pipe buffers.
+ [3b5d995966ef]
+
+ * NEWS:
+ I/O logging bug fix
+ [934d755ac12c]
+
+ * src/exec_pty.c:
+ Don't use SUDO_EVLOOP_NONBLOCK when flushing buffers at pty close
+ time, only when the user suspends sudo. Fixes a problem where all
+ buffers might not get flushed at exit when logging I/O. Reproducible
+ via "sudo tar cf - foo | (cd /tmp && sudo tar xf -)" on OpenBSD.
+ [bbe0e18739ec]
+
+2016-05-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo_json.c:
+ Don't try to fflush(export_fp) or ferror(export_fp) if export_fp is
+ NULL, which can happen on the error path.
+ [ccfb4dd260fa]
+
+ * plugins/sudoers/sudoers.c, src/exec.c, src/exec_pty.c, src/sudo.c,
+ src/tgetpass.c:
+ O_NOCTTY has no effect when opening /dev/tty as the open can only
+ succeed if there is already a controlling tty.
+ [9ca106c499b2]
+
+ * src/sudo.c:
+ Do not need to open /dev/tty with O_NONBLOCK, it doesn't block on
+ first open like a physical terminal. By definition, if you have a
+ controlling tty, the first open (which might block) has already
+ occurred.
+ [15a5f006836a]
+
+ * src/selinux.c:
+ Use O_NOCTTY when opening a tty.
+ [5f9fd6458be4]
+
+ * src/Makefile.in:
+ regen
+ [105ef4533724]
+
+ * plugins/sudoers/auth/sudo_auth.c:
+ No need to set pass to NULL after freeing at the end of the loop it
+ since it is already set to NULL each time through the loop.
+ [2657b0b4260d]
+
+2016-05-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ SELinux fixes in 1.8.17.
+ [f743cf0d9c62]
+
+ * plugins/sudoers/logging.h, plugins/sudoers/logwrap.c:
+ Check fprintf() return value in writeln_wrap() and return the number
+ of characters actually written, or -1 on error.
+ [4739e0f58fa3]
+
+ * src/conversation.c:
+ Check fputs() return value.
+ [e85778cbe0e3]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Do not write directly to stdout/stderr, use sudo_printf which calls
+ the conversation function.
+ [e86d5ed4dca7]
+
+ * plugins/sudoers/auth/dce.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/securid5.c:
+ Do not write directly to stdout/stderr, use sudo_printf which calls
+ the conversation function.
+ [002a30fdb4e0]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/visudo_json.c:
+ Use ferror() after fflush() to check the error status of the stdio
+ stream we wrote to.
+ [fa1db13fe9ac]
+
+2016-05-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/parse.c:
+ printf() returns < 0 on error, not explicitly -1
+ [2a2385b941de]
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo_plugin.cat,
+ doc/sudoers.ldap.cat, doc/sudoreplay.cat, doc/visudo.cat:
+ Regen for 1.8.17
+ [e24b0f944000]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document that you need to preserve EDITOR and/or VISUAL for
+ env_editor to be useful.
+ [ef0ce8917307]
+
+ * src/selinux.c:
+ Fix last commit, now that argc is not reset we need to explicitly
+ start the copy from argv[1]. From Daniel Kopecek
+ [f52403ef587a]
+
+2016-05-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/selinux.c:
+ cosmetic change to warning string
+ [a2893e3f9b70]
+
+ * plugins/sudoers/auth/pam.c:
+ Avoid adding an extraneous warning string to sudoers.pot.
+ [6b07043b48f7]
+
+ * lib/util/snprintf.c:
+ Use EOVERFLOW, not ENOMEM for overflow conditions. For snprintf()
+ and vsnprintf(), POSIX says we should return -1 and set errno to
+ EOVERFLOW if the size param is > INT_MAX; also zero out the string
+ in this case (not mandated by POSIX) for safety.
+ [294720fc981a]
+
+2016-05-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/pam.c:
+ Now that pam_open_session() failure is fatal we should print and log
+ an error from it. Bug #744
+ [0e98a92ef910]
+
+ * src/selinux.c:
+ Repair SELinux support, broken by 397722cdd7ec. From Daniel Kopecek.
+ [1246583c7c1f]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ Remove sudo_mkpwcache() and sudo_mkgrcache(). We now create the
+ caches as needed on demand. Also remove calls to sudo_freepwcache()
+ and sudo_freegrcache() that are immediately followed by execve(),
+ they are not needed.
+ [60448afe813d]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/logging.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c:
+ Eliminate use of setpwent()/endpwent() and setgrent()/endgrent().
+ Sudo never iterates over the passwd or group file. Rename
+ sudo_set{pw,gr}ent() -> sudo_mk{pw,gr}cache() and use
+ sudo_free{pw,gr}cache() instead of sudo_end{pw,gr}ent().
+ [66e6f5e7b51b]
+
+2016-05-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/parse.h:
+ Remove unnecessary NULL checks in the RUNAS_CHANGED macro. The only
+ place where the pointers could be NULL is in visudo_json.c but we
+ already check for "next" being NULL there. Quiets a cppcheck
+ warning.
+ [a0d84832c154]
+
+2016-05-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ In replay_session() free iov at the end of the function (if needed)
+ instead of after processing each line from the timing file. Coverity
+ CID 104843.
+ [5112f514af87]
+
+ * plugins/sudoers/sudoreplay.c:
+ Add io_log_read() and io_log_gets() to hide differences between
+ gzread/fread and gzgets/fgets. Check for premature EOF and error
+ from io_log_read(). Also sanity check the index in the timing file.
+ Coverity CID 104630.
+ [6a3b9932f567]
+
+ * src/exec_pty.c:
+ Break up io_callback() into read_callback() and write_callback() to
+ make it clear that we can't get an event with both read and write
+ set.
+ [cd3a1e182dd4]
+
+2016-05-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ In io_callback() make sure we clear SUDO_EV_READ if we close the fd.
+ It should not be possible for SUDO_EV_READ to be set when revent is
+ non-NULL but this makes static analyzers happier. Coverity CID
+ 104124.
+ [7acc249fa098]
+
+ * plugins/sudoers/ldap.c:
+ In sudo_krb5_copy_cc_file() move the close(ofd) to the done: label
+ so we only have to cleanup in one place. Coverity CID 104577.
+ [0f189e70c59d]
+
+ * plugins/sudoers/ldap.c:
+ Fix memory leak in sudo_netgroup_lookup() in the non-error case.
+ Coverity CID 104572, 104573, 104574, 104575.
+ [7f9fb7a360b7]
+
+ * plugins/sudoers/ldap.c:
+ Fix fd leak in sudo_krb5_copy_cc_file() if restore_perms() fails.
+ Coverity CID 104571.
+ [d9434cdfb73c]
+
+ * plugins/sudoers/sudoreplay.c:
+ Free the events and event base before returning from
+ replay_session(). Coverity CID 104116, 104117.
+ [321216089e4a]
+
+ * src/sudo_edit.c:
+ In sudo_edit_create_tfiles(), fix fd leak if sudo_edit_mktemp()
+ fails. Coverity CID 104114.
+ [713de09ff956]
+
+ * src/sudo_edit.c:
+ Fix fd leak in sudo_edit_open_nonwritable() if dir_is_writable()
+ returns an error. Coverity CID 104113.
+ [314a57004f00]
+
+ * src/sudo_edit.c:
+ Fix memory leak of sesh_args in selinux_edit_copy_tfiles(). Coverity
+ CID 104112.
+ [ac7f0cbd07c9]
+
+ * plugins/sudoers/visudo.c:
+ Fix memory leak in get_editor() if resolve_editor() fails with an
+ error. Coverity CID 104107.
+ [e355b1f45bcb]
+
+ * src/sudo.c:
+ Fix memory leak on error if sudo_new_key_val() fails. Coverity CID
+ 104103.
+ [c2ee1557aef2]
+
+ * plugins/sudoers/visudo.c:
+ Ignore the return value of the initial sudoersparse(), before we
+ have actually edited any files. Coverity CID 104078.
+ [184d9c6aec65]
+
+ * src/exec.c:
+ Ignore the result of send() on exec error, if it fails the other end
+ of the pipe is gone and we are headed for exit. Coverity CID 104066.
+ [cdcd7dfcbca1]
+
+ * plugins/sudoers/toke_util.c:
+ In fill_args() clean up properly if there is an internal overflow
+ (which should not be possible). Coverity CID 104569.
+ [0bc710e91ec4]
+
+ * plugins/sudoers/gc.c:
+ Fix logic inversion in sudoers_gc_remove(), currently unused.
+ Coverity CID 104568
+ [e29df8da11ea]
+
+2016-05-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ In io_mkdirs(), change the order from stat then mkdir, to mkdir then
+ stat. This more closely matches what "mkdir -p" does. Coverity CID
+ 104120.
+ [e462528ff7ea]
+
+ * plugins/sudoers/timestamp.c:
+ In ts_mkdirs(), change the order from stat then mkdir, to mkdir then
+ stat. This more closely matches what "mkdir -p" does. Coverity CID
+ 104119.
+ [c0c0e2662883]
+
+ * plugins/sudoers/sudoers.c:
+ Newer versions of Ubuntu have switched from using the "admin" group
+ to the "sudo" group to align with Debian.
+ create_admin_success_flag() now accepts either one.
+ https://bugs.launchpad.net/ubuntu/+source/sudo/+bug/1387347
+ [17b4d725dac4]
+
+ * plugins/sudoers/timestamp.c:
+ Cast off_t printed via printf(3) instead of assuming it is long
+ long.
+ [b1d398f4a8dc]
+
+ * plugins/sudoers/sudoers.c:
+ Instead of using stat(2) to see if the admin flag file exists and
+ creating it if not, just try to create the file and treat EEXIST as
+ a non-error. Coverity CID 104121.
+ [bd58b0a35a3c]
+
+ * MANIFEST, plugins/sample/README:
+ README file for the sample plugin that tells the user how to build,
+ install and enable it.
+ [8d7096ce78cc]
+
+ * plugins/sample/sample_plugin.c:
+ Fix compilation error and export sample_policy struct. From Michael
+ Evans
+ [5280c1576e7f]
+
+ * NEWS:
+ Update for 1.8.17
+ [979688a5ef13]
+
+ * configure, configure.ac:
+ Sudo 1.8.17
+ [09311b2e9697]
+
+ * plugins/sudoers/logging.c:
+ Check return value of restore_perms() in vlog_warning(). Coverity
+ CID 104079.
+ [86555dd0942d]
+
+ * plugins/sudoers/editor.c:
+ Fix memory leaks in resolve_editor() in the error path. Coverity CID
+ 104109, 104110
+ [6ac3f7e3ada9]
+
+ * plugins/sudoers/policy.c:
+ Fix memory leak of gid_list in sudoers_policy_exec_setup() in the
+ error path. Coverity CID 104111.
+ [eac1e9489367]
+
+ * plugins/sudoers/logging.c:
+ Fix fd leak in do_logfile() if we fail to lock the log file.
+ Coverity CID 104115.
+ [164a693207a8]
+
+ * plugins/sudoers/sssd.c:
+ Fix memory leak of sss_result in sudo_sss_lookup() Coverity CID
+ 104106
+ [7dcee1e6d76f]
+
+ * plugins/sudoers/iolog.c:
+ Fix fd leak in open_io_fd() if gzdopen/fdopen fails. Coverity CID
+ 104105
+ [c4c2848c1167]
+
+ * plugins/sudoers/iolog.c:
+ Fix fd leak in io_nextid() in error path. Coverity CID 104104
+ [8920cdaab5bd]
+
+2016-05-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/timestamp.c:
+ Check lseek() return value. Coverity CID 104061.
+ [bf3bb4c80cfc]
+
+ * plugins/sudoers/timestamp.c:
+ Ignore ts_write() return value when disabling an entry with a bogus
+ timestamp. We ignore the timestamp entry even it doesn't succeed.
+ Coverity CID 104062.
+ [5e5925ebbc75]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/match.c,
+ plugins/sudoers/tsgetgrpw.c, src/exec.c, src/exec_pty.c, src/sudo.c:
+ Cast the return value of fcntl() to void when setting FD_CLOEXEC.
+ Coverity CID 104063, 104064, 104069, 104070, 104071, 104072, 104073,
+ 104074
+ [48720d2f6658]
+
+ * plugins/group_file/getgrent.c:
+ Cast the return value of fcntl() to void when setting FD_CLOEXEC.
+ Coverity CID 104075, 104076, 104077.
+ [7fe1d9f97321]
+
+ * plugins/sudoers/env.c:
+ Avoid a false positive. Coverity CID 104056.
+ [0256978219a6]
+
+ * plugins/sudoers/visudo_json.c:
+ Avoid calling fclose(NULL) on error in export_sudoers(). Coverity
+ CID 104091.
+ [2f73d86ab929]
+
+ * plugins/sudoers/toke_util.c:
+ In fill_args(), check for "arg_size == 0" instead of
+ "sudoerslval.command.args == NULL" since the latter leads Coverity
+ to imply that sudoerslval.command.args could be NULL later on.
+ Coverity CID 104093.
+ [bab505438881]
+
+ * plugins/sudoers/sudoers.c:
+ Avoid calling fclose(NULL) if the sudoers file is not secure and
+ restore_perms() fails. Coverity CID 104090.
+ [150db126c221]
+
+2016-05-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/toke.h, plugins/sudoers/toke_util.c:
+ In fill_args(), replace loop that increments arg_size() with a
+ simple add and mask. Should prevent a false positive from Coverity
+ CID 104094.
+ [411c7e398286]
+
+ * plugins/sudoers/sudoreplay.c:
+ In parse_expr(), move the "bad" label after the "default" case in
+ the switch(), not before it. This seemed to confuse Covertity,
+ resulting in a false positive, CID 104095.
+ [4371f26995fb]
+
+ * doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in:
+ For "sudoreplay -l", not all predicates may be shortened to a single
+ character. Both 'c' and 't' have more than one possibility.
+ [29a5a9a313e2]
+
+ * src/exec.c, src/exec_pty.c, src/sudo.c:
+ pid_t is defined by POSIX as a signed integer type so we don't need
+ a cast when comparing to -1.
+ [98f0a86260a0]
+
+ * src/exec.c:
+ In dispatch_signal() for stopped processes check for tcgetpgrp()
+ returning -1. Also change checks from "saved_pgrp != -1" to "fd !=
+ -1". Coverity CID 104098.
+ [42ac4ad85900]
+
+ * src/selinux.c:
+ In relabel_tty() always jump to bad: on error, regardless of the
+ value of se_state.enforcing. On error, return -1 if enforcing, else
+ 0. Coverity CID 104099.
+ [db1a54d718f1]
+
+ * config.h.in, configure.ac:
+ Define NO_LEAKS when sudo is built with Coverity.
+ [f4209b9ade8c]
+
+ * src/exec_pty.c:
+ In io_callback() if we write the complete buffer and find that there
+ is no associated reader just return as there is nothing else to be
+ done. In practice is it not possible for SUDO_EV_READ to be set if
+ revent is NULL but an early return is harmless and possibly easier
+ to understand. Coverity CID 104124.
+ [3b3eb45b701e]
+
+ * src/sudo_edit.c:
+ Handle read() returning -1 when creating temporary files. Coverity
+ CID 104100
+ [e82af51e4f48]
+
+ * plugins/sudoers/policy.c:
+ Fix cut and paste error when checking cols for 0. Coverity CID
+ 104081
+ [22a3b7d9bce1]
+
+ * plugins/sudoers/pwutil.c:
+ Use a single debug message for cache hit or store to avoid another
+ situation where they get out of sync. Bug #743
+ [4cf484e9b016]
+
+ * plugins/sudoers/pwutil.c:
+ Sync the "cache hit" debug messages with the "cached" debug
+ messages. This fixes a bug where we could dereference a NULL pointer
+ when we look up a negative cached entry which is stored as a NULL
+ passwd or group struct pointer. Bug #743.
+ [1d13341d53ec]
+
+2016-04-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Remove the check for __sprintf_chk when checking for
+ _FORTIFY_SOURCE, Some implementations are purely header-file based.
+ As long as we can link a test program using sprintf() when
+ _FORTIFY_SOURCE=2 it should be safe to use.
+ [910af8ba4666]
+
+ * config.h.in, configure, configure.ac:
+ Remove configure checks for dev_t, id_t, ino_t, ptrdiff_t, size_t
+ and ssize_t. These have been specified by either ANSI C or POSIX for
+ long enough that if the system doesn't support them, it is unlikely
+ to be able to compile sudo anyway.
+ [c9fd433cfe27]
+
+ * src/sudo.c:
+ Do group setup in policy_init_session() before calling out to the
+ plugin. This makes it possible for the pam_group module to change
+ the group in pam_setcred(). It's a bit bogus since pam_setcred() is
+ documented as not changing the group or user ID, but pam_group is
+ shipped with stock Linux-PAM so we need to support it.
+ [814cda602541]
+
+2016-04-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/logging.c:
+ Add missing newline when logging to a file (not syslog) and
+ loglinelen is set to a non-positive number. Bug #742
+ [ef0a5428a574]
+
+2016-04-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ style fix; fork_cmnd should start on a new line
+ [e8211fe0f8d7]
+
+2016-04-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, plugins/sudoers/ldap.c,
+ plugins/sudoers/logging.c, src/signal.c, src/sudo.c, src/tgetpass.c:
+ Ignore SIGPIPE for the duration of sudo and not just in a few select
+ places. We have no control over what nss, PAM modules or sudo
+ plugins might do so ignoring SIGPIPE is safest.
+ [7c919101b8ec]
+
+ * src/selinux.c:
+ Use string_to_security_class() instead of pulling SECCLASS_CHR_FILE
+ from flask.h. Avoids a warning with new SELinux includes.
+ [24f357b419c4]
+
+2016-04-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/parse.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ When determining whether or not "sudo -l" or "sudo -b" should prompt
+ for a password, take all sudoers sources into account. In other
+ words, if both file and ldap sudoers sources are in use, "sudo -v"
+ will now require that all entries in both sources be have NOPASSWD
+ (file) or !authenticate (ldap) in the entries.
+ [51e2a5ecacc6]
+
+2016-03-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/sudo_auth.h:
+ If the auth_type setting in /etc/security/login.cfg is set to
+ PAM_AUTH but pam_start() fails, fall back to use AIX authentication.
+ Skip the auth_type check if sudo is not compiled with PAM support.
+ [cdbe432c465c]
+
+2016-03-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in:
+ The header for sudo.conf(5) should be SUDO.CONF(5) not SUDO(5).
+ [d3afd5bd550f]
+
+2016-03-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/policy.c:
+ hook_version and hook_type are unsigned so use 0, not -1 in the
+ final (empty) entry. Quiets a warning on Solaris Studio 12.2.
+ [4947de8e35b7]
+
+2016-03-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, config.h.in, configure, configure.ac,
+ plugins/sudoers/auth/pam.c:
+ Work around an ambiguity in the PAM spec with respect to the
+ conversation function. It is not clear whether the "struct
+ pam_message **msg" is an array of pointers or a pointer to an array.
+ Linux-PAM and OpenPAM use an array of pointers while Solaris/HP-
+ UX/AIX uses a pointer to an array. Bug #726.
+ [d2b926e2f7d6]
+
+2016-03-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/sr.mo, plugins/sudoers/po/sr.po, po/eo.mo,
+ po/eo.po, po/it.mo, po/it.po, po/ja.mo, po/ja.po, po/ru.mo,
+ po/ru.po, po/sr.mo, po/sr.po:
+ sync with translationproject.org
+ [271c6738213d]
+
+2016-02-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Bug #738
+ [9e7974480cdc]
+
+2016-02-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po, po/nb.mo,
+ po/nb.po:
+ sync with translationproject.org
+ [6aa32f6e5240]
+
+ * lib/util/regress/fnmatch/fnm_test.in:
+ Better test for negated character classes.
+ [635e3c17bca1]
+
+ * lib/util/regress/fnmatch/fnm_test.in:
+ Add test for negated character class
+ [0d813e098864]
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po, po/cs.mo,
+ po/cs.po, po/de.mo, po/de.po, po/fr.mo, po/fr.po, po/pl.mo,
+ po/pl.po, po/pt_BR.mo, po/pt_BR.po, po/uk.mo, po/uk.po, po/vi.mo,
+ po/vi.po, po/zh_CN.mo, po/zh_CN.po:
+ sync with translationproject.org
+ [9398ffdc7719]
+
+ * NEWS:
+ sync
+ [a27a7d40491e]
+
+ * lib/util/fnmatch.c:
+ Fix negation of character classes.
+ [aed07c013a41]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Fix the check for whether a user is allowed to lists another user's
+ privileges. The "matched" variable is not boolean, it can also have
+ the value UNSPEC so we need to check explicitly for true. Bug #738
+ [e8ed706fda03]
+
+ * plugins/sudoers/auth/pam.c:
+ Log the number of PAM messages in the conversation function at debug
+ level.
+ [3f16eea5875f]
+
+2016-02-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Don't check for posix_spawn() or posix_spawnp() if we were unable to
+ find spawn.h. This should only be a problem on systems with broken
+ headers. Bug #730
+ [5e5b0646dca4]
+
+2016-02-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ update for 1.8.16
+ [bad5e6534f39]
+
+ * doc/CONTRIBUTORS, plugins/sudoers/sudoers2ldif:
+ Fix documented bug with duplicate role names and turn on perl
+ warnings. Based on a diff from Aaron Peschel
+ [344a1c1f5c93]
+
+2016-02-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/aix.c:
+ Add declaration of getauthdb() for AIX 5.1
+ [f758960bcfd6]
+
+2016-02-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [e61e1241f15f]
+
+ * plugins/sudoers/po/fr.mo, plugins/sudoers/po/fr.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po:
+ sync with translationproject.org
+ [2f3dea24199b]
+
+ * INSTALL:
+ Add a note that --with-solaris-audit is only for Solaris 11 and
+ above. Bug #737
+ [6722331c2830]
+
+2016-02-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Remove last remnants of the deprecated --with-stow option.
+ [8616d6de7ecd]
+
+ * src/Makefile.in:
+ src/load_plugins.c needs _PATH_SUDO_CONF so allow it to be
+ overridden via the Makefile like other consumers of _PATH_SUDO_CONF.
+ Bug #735
+ [10148ef883ec]
+
+2016-02-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac, include/sudo_util.h, lib/util/aix.c,
+ lib/util/getgrouplist.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/pwutil.h, plugins/sudoers/pwutil_impl.c,
+ plugins/sudoers/set_perms.c, src/sudo.c:
+ Add an administrative domain to the passwd/group cache key for AIX
+ which can have different name <-> ID mappings depending on whether
+ the database is local, LDAP, etc.
+ [5319c11aefe9]
+
+ * mkpkg, sudo.pp:
+ Fedora dropped "core" from the name some time ago so just match on
+ f[0-9] for the rpm distro name provided by pp. Since the version
+ numbers of Fedora and RHEL are so different switch to defining
+ variables to indicate which features should be enabled. Works for
+ Fedora 23.
+ [4ec50b352293]
+
+2016-01-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg, sudo.pp:
+ Treat fedora core like centos/rhel for package building.
+ [0dfc607d07a1]
+
+2016-01-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/parser/check_fill.c:
+ Plug some memory leaks in the tests.
+ [ce76ba538867]
+
+ * plugins/sudoers/toke_util.c:
+ If realloc of sudoerslval.command.args fails, reset
+ sudoerslval.command.args as well as arg_len and arg_size after
+ freeing sudoerslval.command.args.
+ [6481bad56e6a]
+
+ * src/exec_pty.c:
+ When freeing the iobs after pty tear-down, also free the associated
+ event structures. Quiets a memory leak warnings from address
+ sanitizer and valgrind.
+ [f19c689a2ded]
+
+2016-01-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ iolog_compress should be bool, not int
+ [b437123a242b]
+
+ * plugins/sudoers/visudo.c:
+ Quiet address sanitizer leak detector.
+ [b7ce672331f6]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/env.c,
+ plugins/sudoers/gc.c, plugins/sudoers/sudoers.h:
+ Simple garbage collection (really a to-be-freed list) for the
+ sudoers plugin. Almost identical to what sudo.c uses. Currenly only
+ the environment strings are collected at exit time which is enough
+ to quiet address sanitizer's leak detector.
+ [47f32e047b1a]
+
+ * src/sudo.c:
+ Rename gc_cleanup to gc_run and remove I/O plugins from the plugin
+ list when freeing them.
+ [ea640f0b46f9]
+
+ * src/sudo.c:
+ Free up the garbage via an atexit() handler instead of requiring a
+ call to gc_exit.
+ [cc9c96d88595]
+
+ * src/sudo_edit.c:
+ Plug a memory leak in sudo_edit.
+ [cab9a13a669b]
+
+2016-01-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ mention --enable-asan
+ [ee2bc0f60c8b]
+
+ * plugins/sudoers/auth/sudo_auth.c:
+ Try to deconfuse static analyzers a bit.
+ [7e728c76f5df]
+
+ * plugins/sudoers/sssd.c:
+ Avoid possible NULL deref found by clang analyzer.
+ [8bb3cbfe0446]
+
+ * config.h.in, configure, configure.ac:
+ Add --enable-asan configure flag to enable address sanitizer
+ [8aae250fb68e]
+
+ * src/sudo.c, src/sudo_plugin_int.h, src/ttyname.c:
+ Add support for garbage collecting info passed to the plugin before
+ exit to appease address sanitizer's leak detector (and valgrind's
+ leak checker). We can't free these sooner since the plugin may be
+ using the memory. For plugin API 2.0 it should be make clear that
+ the plugin must make a copy of the data in the arrays passed in to
+ the plugin's open() function. Only enabled if NO_LEAKS is defined.
+ [8458bcb165d8]
+
+ * plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/securid5.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c:
+ auth_getpass() returns a dynamically allocated copy of the plaintext
+ password which needs to be freed after checking (and clearing) it.
+ [28d2c83c3ac4]
+
+ * src/sudo.c:
+ Remove sudo_fatalx() calls from format_plugin_settings().
+ [96a18a3ccc49]
+
+ * plugins/sudoers/sssd.c:
+ fn_free_result() (aka sss_sudo_free_result() in sss_sudo.c) handles
+ a NULL poiner so there's no need to check before calling it. Add
+ missing initialization of sss_sudo_result to NULL in
+ sudo_sss_setdefs().
+ [fa1c8eaed6ac]
+
+ * plugins/sudoers/sssd.c:
+ Add missing return when user is not found in sudo_sss_result_get().
+ Previously we fell through to the default case which just logged a
+ debug message and returned so this just avoids the extra (generic)
+ debug message.
+ [68c2201f3a85]
+
+2016-01-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/gettime.c:
+ Fix a warning on AIX.
+ [4ebc19a143ff]
+
+ * src/sudo.c:
+ Pass updated user_env_out, not envp, to the I/O open function.
+ [f02e6f32f189]
+
+ * src/sudo.c:
+ Pass updated argv/envp to the I/O open function like the plugin API
+ documents.
+ [ff9f4fae5cf3]
+
+2016-01-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Add check for I/O log file handle being NULL. This could only happen
+ if the front-end calls iolog_open with argc == 0 but actually runs a
+ command.
+ [5113a3c04494]
+
+2016-01-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/pwutil.c:
+ Additional debugging for pwutil functions.
+ [908b83c3acbb]
+
+ * config.h.in, configure, configure.ac, lib/util/aix.c:
+ When calling setauthdb(), save the old registry value so we can
+ restore it properly. Previously we were setting the registry to
+ unrestricted instead of actually restoring it.
+ [5a2921412663]
+
+ * plugins/sudoers/sudoers.c:
+ Use SUDOERS_DEBUG_UTIL not SUDO_DEBUG_UTIL in the plugin.
+ [79b012777e71]
+
+2016-01-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/sudo_debug.c:
+ When parsing debug entries, don't make a lower value override a
+ higher one. For example, for "pcomm@debug,all@warn" the "all@warn"
+ should not set pcomm to "warn" when it is already at "debug".
+ [031037a56e51]
+
+2016-01-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/policy.c:
+ Set sudoedit_checkdir=false in command_details when it is disabled
+ in sudoers.
+ [811dd43b29f5]
+
+ * include/sudo_compat.h, lib/util/strtobool.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/sssd.c, src/sudo_edit.c:
+ Update copyright year
+ [5ec484920763]
+
+ * src/sudo_edit.c:
+ If the user runs "sudoedit /" we will receive ENOENT from openat(2)
+ and sudoedit will try to create a file with the null string. If path
+ is empty, open the cwd instead so sudoedit can give a sensible error
+ message.
+ [fc39d5804f1f]
+
+ * lib/util/strtobool.c:
+ Log an error for invalid boolean strings.
+ [004afa5e05c5]
+
+ * src/sudo.c:
+ Fix off by one error in new SET_FLAG macro.
+ [5bdce4edf8b9]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document the race with sudoedit_checkdir in 1.8.15.
+ [cb7aed3367e9]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in:
+ Document sudoedit_checkdir
+ [89f2452272ad]
+
+2016-01-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo_edit.c:
+ There are no systems that support O_SEARCH/O_PATH that do not also
+ support O_DIRECTORY so simplify the definition of DIR_OPEN_FLAGS a
+ bit.
+ [a48f11ea53b3]
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [8ae4d883ac59]
+
+ * NEWS, doc/UPGRADE:
+ Add 1.8.16 changes
+ [8d3a3f5cdf59]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, plugins/sudoers/defaults.c,
+ src/sudo.c:
+ Make sudoedit_checkdir the default and update the documentation
+ accordingly.
+ [84bbc1b73411]
+
+ * src/sudo.c:
+ Add a SET_FLAG macro to simplify parsing command details boolean
+ flags. Previously, flags were only set and never cleared even if the
+ boolean value was false. This was not a problem as there were no
+ default flags for the plugin to enable. That will change in the
+ future.
+ [75f24ca13f41]
+
+2016-01-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo_edit.c:
+ Need to be root when switching to a different user.
+ [06d5f010b607]
+
+ * src/sudo_edit.c:
+ Use O_SEARCH on systems without O_PATH if present. It can be used
+ for a similar purpose.
+ [3f559a389bf9]
+
+ * config.h.in, configure, configure.ac, src/sudo_edit.c:
+ Use faccessat(2) for directory writability instead of doing the
+ checks manually where possible. This also allows us to remove the
+ #ifdef __linux__ bits since we no longer use fstat(2) on Linux with
+ an O_PATH fd.
+ [fe50d0c1f1b9]
+
+2016-01-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Add "I/O LOG FILES" section to the manual and move many of the
+ details from the log_input and log_output descriptions to it.
+ [a604903f5ae3]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Use "Nm sudoers" when talking about the plugin and "Em sudoers" when
+ talking about the sudoers file.
+ [727a68b02de7]
+
+2016-01-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/zlib/zlib.exp:
+ Remove gzopen_w which is only defined on Windows.
+ [a73236903e7b]
+
+ * config.h.in, configure, configure.ac, include/sudo_compat.h:
+ Work around the buggy pread(2) on 32-bit HP-UX 11.00 by using
+ pread64() on that platform.
+ [31c4be934115]
+
+2016-01-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/defaults.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/match.c,
+ plugins/sudoers/parse.c, plugins/sudoers/parse.h,
+ plugins/sudoers/sssd.c, plugins/sudoers/testsudoers.c:
+ Add support for matching the entire netgroup tuple (user, host,
+ domain).
+ [9f694ba7c86d]
+
+ * plugins/sudoers/ldap.c:
+ Use asprintf() to generate the netgroup filter instead of using lots
+ of concatenation.
+ [f8290c040aea]
+
+ * lib/util/util.exp.in:
+ Add missing sudo_debug_exit_ssize_t_v1 symbol.
+ [9407fb25dfa4]
+
+2016-01-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ In sudo_netgroup_lookup() only build up the search filter once
+ instead of once per netgroup_base.
+ [a03440237078]
+
+ * plugins/sudoers/ldap.c:
+ It is safe to pass ldap_msgfree() a NULL pointer.
+ [abc2eaddbf83]
+
+ * plugins/sudoers/ldap.c:
+ On overflow, warn before freeing anything.
+ [2e3bcfa4a8f9]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Use user_runhost and user_srunhost instead of user_host and
+ user_shost. Fixes "sudo -l -h other_host" for LDAP and sssd.
+ [e1abfdc82242]
+
+ * plugins/sudoers/match.c:
+ Silence warning in digest_matches() on systems with no fexecve(2).
+ [0cd3cc8fa195]
+
+ * plugins/sudoers/sssd.c:
+ Fix free() of invalid pointer introduced in the commit that stripped
+ whitespace between a '!' and the name in a sudoOption.
+ [4d2c1761c752]
+
+ * plugins/sudoers/ldap.c:
+ Fix free() of invalid pointer introduced in the commit that stripped
+ whitespace between a '!' and the name in a sudoOption.
+ [14391603a9e5]
+
+ * src/sudo_edit.c:
+ Add missing dfd argument to the version of
+ sudo_edit_openat_nofollow() for systems without O_NOFOLLOW.
+ [574e4a840879]
+
+ * plugins/sudoers/def_data.c, plugins/sudoers/def_data.in:
+ Update description of sudoedit_checkdir. Reported by Sander Bos.
+ [ee44e7255096]
+
+ * src/sudo_edit.c:
+ No need to check whether the fd we opened is really a directory in
+ sudo_edit_open_nonwritable() since if not, the openat() will fail
+ with ENOTDIR anyway.
+ [b41c5b289f35]
+
+2016-01-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS, doc/UPGRADE, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in, include/sudo_compat.h, src/sudo_edit.c:
+ Rewritten sudoedit_checkdir support that checks all the dirs in the
+ path and refuses to follow symlinks in writable directories. This is
+ a better fix for CVE-2015-5602. Adapted from a diff by Ben
+ Hutchings. Bug #707
+ [c2e36a80a279]
+
+2016-01-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/po/ca.mo, plugins/sudoers/po/ca.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/fr.mo, plugins/sudoers/po/fr.po,
+ plugins/sudoers/po/sr.mo, plugins/sudoers/po/sr.po, po/ca.mo,
+ po/ca.po, po/fi.mo, po/fi.po, po/hu.mo, po/hu.po, po/sr.mo,
+ po/sr.po:
+ sync with translationproject.org
+ [94ffd6b18431]
+
+ * configure, configure.ac, doc/sudo_plugin.cat,
+ doc/sudo_plugin.man.in, doc/sudo_plugin.mdoc.in, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, include/sudo_plugin.h,
+ plugins/sudoers/match.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.h, src/exec.c, src/exec_common.c,
+ src/selinux.c, src/sesh.c, src/sudo.c, src/sudo.h, src/sudo_exec.h:
+ Add support for using fexecve() if supported on commands that are
+ checksummed.
+ [397722cdd7ec]
+
+2015-12-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo_edit.c:
+ Call openat() with the basename not the full path. From Ben
+ Hutchings.
+ [33272418bb10]
+
+2015-12-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/group_plugin.c, plugins/sudoers/policy.c:
+ Fix compilation with --disable-shared
+ [84c084618676]
+
+2015-12-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_common.c:
+ Check for existing dso in LD_PRELOAD and only add it if it is not
+ already present.
+ [15042e8999f7]
+
+2015-12-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Clarify when SIGINT and SIGQUIT are relayed by sudo to the command.
+ [8efed5784393]
+
+ * plugins/sudoers/group_plugin.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.h, src/load_plugins.c:
+ Actually use the plugin_dir Path setting in sudo.conf.
+ [bccc548127a2]
+
+ * lib/util/sudo_conf.c:
+ The Path setting for the plugin directory is "plugin_dir" not
+ "plugin".
+ [07c2677bbce5]
+
+ * doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in,
+ lib/util/sudo_conf.c, src/exec_common.c:
+ Allow sudo.conf Path settings to disable path names (by setting the
+ value of NULL).
+ [81a44e011a40]
+
+2015-12-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/selinux.c, src/sudo.h:
+ Change noexec flag in selinux_execve() from int to bool.
+ [7cb872aac155]
+
+ * src/exec_common.c, src/sudo_exec.h:
+ Refactor code to set LD_PRELOAD (or the equivalent) in the
+ environment into a preload_dso() function. Also avoid allocating a
+ new copy of the environment array if the size of the array does not
+ change.
+ [72194b0b51f7]
+
+ * configure, configure.ac:
+ Add missing square brackets in configure option descriptions.
+ [6e25685c6349]
+
+2015-12-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document the names of the I/O log files and mention buffering.
+ Document that I/O logs are in gzip format by default.
+ [474838e7b365]
+
+2015-12-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/env.c:
+ Add BASHOPTS to initial_badenv_table[]; from Stephane Chazelas
+ [f206a9089a69]
+
+2015-12-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ When parsing sudoOptions that include an operator (!, +, +=, -=)
+ strip out any whitespace on either side of the operator.
+ [62041b5888e5]
+
+2015-12-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers2ldif:
+ Strip whitespace around '!', '=', '+=' and '-=' in Defaults entries.
+ [dcc9d15b0f3c]
+
+2015-12-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document the race condition between the digest check and command
+ execution.
+ [24a3d9215c64]
+
+2015-12-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ When checking the query results, don't set user_matches in the
+ netgroup pass unless sudo_ldap_check_non_unix_group() returns true.
+ This was preventing the mail_no_user sudoOption from being
+ effective.
+ [31004144421b]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ In list mode, we always want to clear FLAG_NO_USER and FLAG_NO_HOST
+ regardless of whether or not there was an actual match. Otherwise,
+ warning mail may be sent which is not what we want in list mode.
+ This is consistent with what the sudoers file backend does.
+ [2809338a7b21]
+
+2015-11-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/toke.h, plugins/sudoers/toke_util.c:
+ Use size_t for length parameters in the fill functions used by the
+ lexer.
+ [0428c9067182]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Use yy_size_t for digest_len since newer flex uses yy_size_t for
+ yyleng. Old flex uses int for yyleng so we need to use a cast to
+ avoid a sign compare warning.
+ [4a3dc6fb8f99]
+
+2015-11-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, README, configure, configure.ac,
+ plugins/sudoers/regress/sudoers/test1.in, sudo.pp:
+ Use https in sudo.ws urls
+ [04e5177022d3]
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.ldap.mdoc.in,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in, doc/visudo.cat,
+ doc/visudo.man.in, doc/visudo.mdoc.in:
+ Use https in urls.
+ [855b05943b2d]
+
+ * configure, configure.ac:
+ sudo 1.8.16
+ [b745f7031aeb]
+
+ * plugins/sudoers/env.c:
+ When preserving variables from the invoking user's environment, if
+ there are duplicates only keep the first instance.
+ [d4dfb05db5d7]
+
+2015-11-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_debug.h, lib/util/parseln.c, lib/util/sudo_debug.c,
+ plugins/sudoers/timestamp.c:
+ Add debug_return_ssize_t
+ [d491ed281726]
+
+ * plugins/sudoers/timestamp.c:
+ Avoid compilation error on Solaris 10 with Stun Studio 12. Bug #727
+ [facd8ff1ee6c]
+
+2015-10-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po, po/da.mo,
+ po/da.po:
+ sync with translationproject.org
+ [6711d740d3d0]
+
+ * NEWS:
+ Mention ssp configure fix.
+ [92d64fd724cc]
+
+2015-10-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/nl.mo, plugins/sudoers/po/nl.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po, po/cs.mo,
+ po/cs.po, po/de.mo, po/de.po, po/fr.mo, po/fr.po, po/it.mo,
+ po/it.po, po/ja.mo, po/ja.po, po/nb.mo, po/nb.po, po/pl.mo,
+ po/pl.po, po/pt_BR.mo, po/pt_BR.po, po/uk.mo, po/uk.po, po/vi.mo,
+ po/vi.po, po/zh_CN.mo, po/zh_CN.po:
+ sync with translationproject.org
+ [9c8eb0062d8c]
+
+ * configure, configure.ac:
+ Don't use CPPFLAGS for the -fstack-protector check. Otherwise on
+ systems with _FORTIFY_SOURCE support we'll get an error due to the
+ lack of optimization flags. Bug #725
+ [1a9f8571a82d]
+
+ * configure, configure.ac:
+ When checking for stack protector support we need to actually link
+ the test program.
+ [ab4f94aac7de]
+
+2015-10-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Preserve LDFLAGS when checking for stack protector as they may
+ include rpath settings to allow the stack protector lib to be found.
+ Avoid using existing CFLAGS since we don't want the compiler to
+ optimize away the stack variable.
+ [e6bc59225c06]
+
+ * configure, configure.ac:
+ Better configure test for -fstack-protector. Some gcc installations
+ may be missing the ssp library even though the compiler supports it.
+ [4ade5d1249f4]
+
+2015-10-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo_edit.c:
+ Set errno to EISDIR instead of ENOTDIR if directory is writable
+ since ENOTDIR can be a legitimate errno. This avoids a bogus
+ "directory is writable" error in that case.
+ [97ee37d905ce]
+
+ * mkpkg:
+ Fix the check for whether to include 32-bit arch in Mac OS X
+ packages.
+ [a76654512f6b]
+
+2015-10-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [58277a8f418b]
+
+ * NEWS, src/sudo_edit.c:
+ When creating a new file, sudoedit will now check that the file's
+ parent directory exists before running the editor.
+ [65bc45510fb2]
+
+ * NEWS, doc/UPGRADE, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in,
+ plugins/sudoers/match.c:
+ Add always_query_group_plugin
+ [7e9060d4c13a]
+
+2015-10-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ABOUT-NLS, MANIFEST:
+ Add ABOUT-NLS from GNU gettext.
+ [971c168c065a]
+
+ * NEWS, config.h.in, configure, configure.ac, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in,
+ plugins/sudoers/policy.c, plugins/sudoers/sudoers_version.h,
+ src/sudo.c, src/sudo.h, src/sudo_edit.c:
+ Add directory writability checks for sudoedit.
+ [f5349d059a98]
+
+2015-10-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Latest.
+ [9aae49302c60]
+
+ * src/conversation.c:
+ Ignore the SUDO_CONV_PROMPT_ECHO_OK flag when echo is enabled. This
+ was preventing a match of SUDO_CONV_PROMPT_ECHO_ON which resulted in
+ a masked password instead of an echoed one.
+ [53f6a78d79e3]
+
+ * plugins/sudoers/auth/bsdauth.c:
+ Repair challenge/response prompting for BSD authentication which got
+ broken while it was converted to use the conversation function.
+ [2d0b0cec5e4f]
+
+ * plugins/sudoers/auth/sia.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/auth/sudo_auth.h:
+ Use the auth_getpass (and the plugin conversation fuction) for Tru64
+ SIA. This prevents sudo from sleeping while holding the tty ticket
+ lock.
+ [9221eec812cf]
+
+ * NEWS, doc/UPGRADE, plugins/sudoers/env.c:
+ For env_reset, SHELL should be set based on the target user, not the
+ invoking user unless preserved via env_keep.
+ [b77adbc08c91]
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po:
+ sync with translationproject.org
+ [adb927ad5e86]
+
+2015-10-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Hungarian and Slovak translations
+ [d3b6acece125]
+
+ * MANIFEST, doc/CONTRIBUTORS, plugins/sudoers/po/hu.mo,
+ plugins/sudoers/po/hu.po, plugins/sudoers/po/sk.mo,
+ plugins/sudoers/po/sk.po, po/sk.mo, po/sk.po:
+ Add new Slovak and Hungarian translations from
+ translationproject.org
+ [132ec9b7a927]
+
+2015-10-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo_edit.c:
+ Remove S_ISREG check from sudo_edit_open(), it is already done in
+ the caller.
+ [9fff8c0bb1f7]
+
+ * src/sudo_edit.c:
+ Open sudoedit files with O_NONBLOCK and fail if they are not regular
+ files.
+ [56b01164869c]
+
+ * plugins/sudoers/logging.c, plugins/sudoers/visudo.c, src/tgetpass.c:
+ It is possible for WIFSTOPPED to be true even if waitpid() is not
+ given WUNTRACED if the child is ptraced. Don't exit the waitpid()
+ loop if WIFSTOPPED is true, just in case.
+ [a2cab04a03da]
+
+2015-09-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/de.mo,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/it.mo,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/nb.mo,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pt_BR.mo,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/vi.mo,
+ plugins/sudoers/po/zh_CN.mo, po/cs.mo, po/de.mo, po/fi.mo, po/fr.mo,
+ po/gl.mo, po/it.mo, po/ja.mo, po/nb.mo, po/pl.mo, po/pt_BR.mo,
+ po/uk.mo, po/vi.mo, po/zh_CN.mo:
+ rebuild .mo files
+ [676362ed6061]
+
+ * plugins/sudoers/po/pt_BR.po, po/pt_BR.po:
+ sync with translationproject.org
+ [be932694e600]
+
+2015-09-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.ac, src/sudo_noexec.c:
+ There's no point in trying to interpose protected versions of the
+ exec family of functions. Many modern C libraries use hidden symbols
+ for the functions and syscalls defined in libc such that they cannot
+ be overridden inside libc itself. We have to just wrap all the exec
+ variants plus system and popen.
+ [30aa4bd6c15b]
+
+ * doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in:
+ List all the functions wrapped by sudo_noexec.so.
+ [57a9db56f4e0]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ The section is now called "EXEC and NOEXEC" and it is above, not
+ below.
+ [9b0a2537f65d]
+
+ * src/sudo_noexec.c:
+ Also wrap popen(3).
+ [a826cd7787e9]
+
+ * src/sudo_noexec.c:
+ Also interpose system(3). On glibc systems you cannot interpose the
+ syscalls used internally by libc.
+ [58a5c06b5257]
+
+ * src/conversation.c:
+ Set active debug instance to sudo_debug_instance() during the
+ conversation function.
+ [22fb750d92a9]
+
+2015-09-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ LOGNAME and USERNAME are set the same way as USER
+ [54f170cf2536]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Document behavior when the command dies from a signal in EXIT
+ STATUS.
+ [3c93d682e5e6]
+
+2015-09-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Bug #722
+ [5cca49bb0e02]
+
+ * src/sudo.c:
+ When the command sudo is running is killed by a signal, sudo will
+ now send itself the same signal with the default signal handler
+ instead of exiting. The bash shell appears to ignore some signals,
+ e.g. SIGINT, unless the command is killed by that signal. This makes
+ the behavior of commands run under sudo the same as without sudo
+ when bash is the shell. Bug #722
+ [153f016db8f1]
+
+2015-09-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Adjust set_logname description to new behavior when any of LOGNAME,
+ USER or USERNAME are preserved.
+ [89009c2dcf38]
+
+ * NEWS, plugins/sudoers/env.c:
+ If some, but not all, of the LOGNAME, USER or USERNAME environment
+ variables have been preserved from the invoking user's environment,
+ sudo will now use the preserved value to set the remaining variables
+ instead of using the runas user. This ensures that if, for example,
+ only LOGNAME is present in the env_keep list, that sudo will not set
+ USER and USERNAME to the runas user.
+ [54a60fe72b9a]
+
+2015-09-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/pam.c:
+ Fix passing of the callback pointer to the conversation function.
+ This was preventing the on_suspend and on_resume functions from
+ being called on PAM systems.
+ [611246ded4ff]
+
+ * include/sudo_plugin.h:
+ Explicitly mark large hex constants unsigned.
+ [5b67b0090814]
+
+ * plugins/sudoers/timestamp.c:
+ Cast sizeof(entry) to off_t before making it a negative offset for
+ lseek(). Fixes "sudo -k" on Solaris and probably others.
+ [ed5d312f6baa]
+
+2015-09-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Add explicit mention of sudo's netgroup semantics since they differ
+ from most other netgroup consumers.
+ [0e9030f8cf56]
+
+ * plugins/sudoers/po/fi.po, po/fi.po:
+ sync with translationproject.org
+ [f9236f25a616]
+
+ * plugins/sudoers/check.c:
+ Fix potential double free of the cookie when sudo is suspended at
+ the password prompt.
+ [cbecb3136155]
+
+2015-09-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/cs.po, plugins/sudoers/po/zh_CN.po, po/cs.po,
+ po/zh_CN.po:
+ sync with translationproject.org
+ [21138f16a3a6]
+
+2015-09-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/de.po, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/ja.po, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/pl.po, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.po, po/de.po, po/fr.po, po/gl.po, po/it.po,
+ po/ja.po, po/nb.po, po/pl.po, po/uk.po, po/vi.po:
+ sync with translationproject.org
+ [2d9f3e4c3ccf]
+
+ * NEWS:
+ Bug #719
+ [cfa393164a0f]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ SIGHUP is now relayed to the command. Bug #719
+ [8db7c492c52a]
+
+ * src/exec.c:
+ When a terminal device is closed, SIGHUP is sent to the controlling
+ process associated with that terminal. It is not sent to the entire
+ process group so sudo needs to relay SIGHUP to the command when it
+ is not being run in a new pty. Bug #719
+ [b408a792f31a]
+
+ * NEWS:
+ Mention visudo bug in 1.8.14
+ [0fec829807fd]
+
+ * plugins/sudoers/visudo.c:
+ We reserved two slots at the end of the editor argv for the line
+ number and the file name. However, resolve_editor() adds "--" before
+ the file names so the +line_number is interpreted as a file name,
+ not a line number so we need to overwrite the "--" as well.
+ [ff107430ee4b]
+
+2015-09-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.ac, lib/util/sig2str.c,
+ lib/util/strsignal.c:
+ Remove checks for __sys_siglist and __sys_signame. They are internal
+ to libc and there are no known systems that export those symbols
+ that do not already export the single underbar or no- underbar
+ versions.
+ [2b3efe0a91f2]
+
+ * plugins/sudoers/po/ru.mo, plugins/sudoers/po/ru.po, po/es.mo,
+ po/es.po:
+ Sync with translationproject.org
+ [feb5eb934a9e]
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [947e8320c557]
+
+2015-09-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/tgetpass.c:
+ Restore old signal handlers before tty settings. That way SIGTTOU is
+ at its original value if sudo_term_restore() should fail.
+ [69d2cc6c0702]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in:
+ Document what happens when the on_suspend/on_resume callbacks return
+ an error.
+ [d8c9dcf7a926]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, include/sudo_plugin.h,
+ plugins/group_file/group_file.c, plugins/group_file/plugin_test.c,
+ plugins/sudoers/group_plugin.c, plugins/sudoers/policy.c,
+ plugins/system_group/system_group.c, src/hooks.c:
+ No need to have version macros for hooks, callbacks and the sudoers
+ group plugin. We can just use the main sudo API macros. The sudoers
+ group plugin macros are preserved for source compatibility but are
+ not documented.
+ [8c52bb83f991]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Properly escape the backslash before a comma in an example so the
+ example rule is parsable by visudo.
+ [6745d38e9876]
+
+ * src/tgetpass.c:
+ Ignore callbacks if major version doesn't match.
+ [f852e6ebff01]
+
+ * MANIFEST, config.h.in, configure, configure.ac,
+ include/compat/timespec.h, lib/util/Makefile.in, lib/util/gettime.c,
+ lib/util/utimens.c, plugins/sudoers/Makefile.in,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/visudo.c, src/Makefile.in, src/sudo_edit.c:
+ Remove include/compat/timespec.h. Systems old enough to lack struct
+ timespec are too old to build a modern sudo.
+ [37812e10a449]
+
+ * NEWS:
+ Bug #713
+ [8a7245d76799]
+
+ * src/exec.c:
+ Fill in cstat if exec_setup() fails. Previously it was only filled
+ in for an execve() failure. Fixes an unkillable sudo process when
+ exec_setup() fails and I/O logging is enabled.
+ [ff1d39d9e505]
+
+ * src/sudo.c:
+ Fix running commands as non-root when neither setresuid() not
+ setreuid() are available. At this point we are already root so
+ setuid() must succeed. Bug #713
+ [34754ad586c7]
+
+ * src/sudo.c:
+ Cast uid_t to unsigned int when printing as %u
+ [669e2d5244a6]
+
+ * doc/UPGRADE:
+ Mention time stamp file locking changes, fix some spelling.
+ [c4563ea85e3a]
+
+ * NEWS:
+ Update with latest changes.
+ [2cbd50e7c158]
+
+2015-09-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c:
+ Avoid touching the time stamp directory for "sudo -k command"
+ [391d20c17775]
+
+ * plugins/sudoers/timestamp.c:
+ Bring back the check for time stamp files that predate the boot
+ time. Instead of truncating we now unlink the file since another
+ process may be sleeping on the lock.
+ [9cdf7468d0f2]
+
+ * config.h.in, configure, configure.ac, plugins/sudoers/iolog.c,
+ plugins/sudoers/timestamp.c:
+ Use pread(2) and pwrite(2) where possible.
+ [86cd3f6bab9e]
+
+ * src/exec_pty.c:
+ sudo_term_* already restart themselve for all but SIGTTOU so we
+ don't need to use our own restart loops.
+ [113924cd05c0]
+
+ * lib/util/locking.c:
+ Set errno to EINVAL if sudo_lock_* is called with a bad type.
+ [cfba014f1c1a]
+
+ * plugins/sudoers/timestamp.c:
+ Adjust new locking to work when tty_tickets is disabled. We need to
+ use per-tty/ppid locking to gain exclusive access to the tty for the
+ password prompt but use a separate (short term) lock that is shared
+ among all sudo processes for the user.
+ [d6d7a0bb6bd0]
+
+ * plugins/sudoers/timestamp.c:
+ Allow the time stamp lock to be interrupted by signals.
+ [aa5017f86210]
+
+ * lib/util/term.c, plugins/sudoers/check.c,
+ plugins/sudoers/sudoreplay.c, src/tgetpass.c:
+ Implement suspend/resume callbacks for the conversation function. If
+ suspended, close the timestamp file (dropping all locks). On resume,
+ lock the record before reading the password.
+
+ For this to work properly we need to be able to run th callback when
+ tsetattr() suspends us, not just when the user does. To accomplish
+ this the term_* functions now return EINTR if SIGTTOU would be
+ generated. The caller now has to restart the term_* function (and
+ send itself SIGTTOU) instead of it being done automatically.
+ [572374035897]
+
+ * config.h.in, configure, configure.ac, include/sudo_util.h,
+ lib/util/locking.c, lib/util/util.exp.in, plugins/sudoers/check.c,
+ plugins/sudoers/check.h, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/timestamp.c:
+ Lock individual records in the timestamp file instead of the entire
+ file. This will make it possible for multiple sudo processes using
+ the same tty to serialize their timestamp lookups.
+ [f4ad82e36d90]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, include/sudo_fatal.h,
+ include/sudo_plugin.h, lib/util/fatal.c, plugins/sudoers/auth/afs.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/dce.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/auth/sudo_auth.h, plugins/sudoers/check.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoers.h,
+ src/conversation.c, src/sudo.c, src/sudo.h, src/sudo_plugin_int.h,
+ src/tgetpass.c:
+ Add a struct sudo_conv_callback that contains on_suspend and
+ on_resume function pointer args plus a closure pointer and at it to
+ the conversation function.
+ [5608cb4c18f2]
+
+2015-09-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, include/sudo_plugin.h:
+ Make hook_version and hook_type unsigned.
+ [77cb84793f07]
+
+2015-09-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/base64.c, plugins/sudoers/match.c,
+ plugins/sudoers/regress/parser/check_base64.c:
+ When decoding base64, avoid using '=' in the decoded temporary array
+ as a sentinel as it can legitimately be present. Instead, just use
+ the count of bytes stored in the temp array to determine which bytes
+ to fold into the destination.
+ [6abef15d3954]
+
+2015-08-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, plugins/sudoers/sudoers.c, plugins/sudoers/visudo.c:
+ When parsing def_editor, break out of the loop when we find the
+ first valid editor. Bug #714
+ [c7508ed075c2]
+
+2015-08-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo.c:
+ The condition for adding a missing newline at the end of sudoers was
+ never reached. Keep track of the last character and write a newline
+ character if when copying to the temp file. Found by Radovan Sroka.
+ [86c20e7fc6bd]
+
+ * plugins/sudoers/sudoers.c, plugins/sudoers/visudo.c:
+ Remove extraneous while() from botched do {} while() loop conversion
+ to use sudo_strsplit. Noticed by Radovan Sroka.
+ [cd2d25510129]
+
+2015-08-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/pam.c, plugins/sudoers/auth/sudo_auth.c:
+ In sudo_pam_begin_session() and sudo_pam_end_session() return
+ AUTH_FATAL on error, not AUTH_FAILURE. In sudo_auth_begin_session()
+ treat anything other than AUTH_SUCCESS as a fatal error.
+ [3ad7296390f2]
+
+ * doc/CONTRIBUTORS, src/exec.c, src/exec_pty.c:
+ Linux sets si_pid in struct siginfo to 0 when the process that sent
+ the signal is in a different container since the PID namespaces in
+ different conatiners are separate. Avoid looking up the process
+ group by id when si_pid is 0 since getpgid(0) returns the process
+ group of the current process. Since sudo ignores signals sent by
+ processes in its own process group, this had the effect of ignoring
+ signals sent from other containers. From Maarten de Vries
+ [6d3f43b95a1f]
+
+ * plugins/sudoers/auth/pam.c:
+ Sprinkle some debugging.
+ [f5a94a3a1192]
+
+2015-08-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.man.in, doc/sudo.mdoc.in:
+ Document that sudo uses the real uid to map from uid to passwd file
+ user name.
+ [04f6709675cc]
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, doc/sudo.man.in, doc/sudo.mdoc.in:
+ disable_coredump can be set to no on modern OSes without security
+ consequences.
+ [ebe6d5bb2274]
+
+2015-08-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Emphasis on the never.
+ [39ca000281c7]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Explicitly tell people not to grant sudoedit to directories the user
+ can write to. While sudoedit will no longer open symbolic links,
+ hard links are still an issue.
+ [26e0afae9bae]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Add warning about writable directories and sudo/sudoedit.
+ [701ff725af42]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Emphasize that wildcards are not regexps. Bug #692
+ [1e071810c4cb]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Emphasize that wildcards in command line arguments are dangerous.
+ Document the failings of the passwd example on GNU systems. Bug #691
+ [54d793aea6b2]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Escape the colons in [[:alpha:]] as required by sudoers.
+ [ad875dd5ca64]
+
+ * po/sudo.pot, src/sudo_edit.c:
+ Change warning when user tries to sudoedit a symbolic link.
+ [b8f44e834c2f]
+
+2015-08-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [5abaa0eeab86]
+
+ * doc/sudo.conf.cat, doc/sudoers.ldap.cat, doc/sudoreplay.cat,
+ doc/visudo.cat:
+ regen
+ [43e6b445734c]
+
+ * doc/UPGRADE, doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in, include/sudo_compat.h, include/sudo_plugin.h,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.h, plugins/sudoers/gram.y,
+ plugins/sudoers/ldap.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/policy.c,
+ plugins/sudoers/regress/sudoers/test1.in,
+ plugins/sudoers/regress/sudoers/test1.json.ok,
+ plugins/sudoers/regress/sudoers/test1.out.ok,
+ plugins/sudoers/regress/sudoers/test1.toke.ok,
+ plugins/sudoers/sudoers_version.h, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/visudo_json.c, src/sesh.c, src/sudo.c, src/sudo.h,
+ src/sudo_edit.c:
+ Do not follow symbolic links in sudoedit by default. This behavior
+ can be controlled by the sudoedit_follow Defaults flag as well as
+ the FOLLOW/NOFOLLOW tags.
+ [9636fd256325]
+
+ * NEWS, aclocal.m4, configure, configure.ac:
+ Sudo 1.8.15
+ [bf18da363b06]
+
+ * MANIFEST:
+ add .json regress files to MANIFEST
+ [03ddb3a9671b]
+
+ * plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/sudoers/test1.json.ok,
+ plugins/sudoers/regress/sudoers/test10.json.ok,
+ plugins/sudoers/regress/sudoers/test11.json.ok,
+ plugins/sudoers/regress/sudoers/test12.json.ok,
+ plugins/sudoers/regress/sudoers/test13.json.ok,
+ plugins/sudoers/regress/sudoers/test14.json.ok,
+ plugins/sudoers/regress/sudoers/test15.json.ok,
+ plugins/sudoers/regress/sudoers/test16.json.ok,
+ plugins/sudoers/regress/sudoers/test2.json.ok,
+ plugins/sudoers/regress/sudoers/test3.json.ok,
+ plugins/sudoers/regress/sudoers/test4.json.ok,
+ plugins/sudoers/regress/sudoers/test5.json.ok,
+ plugins/sudoers/regress/sudoers/test6.json.ok,
+ plugins/sudoers/regress/sudoers/test7.json.ok,
+ plugins/sudoers/regress/sudoers/test8.json.ok,
+ plugins/sudoers/regress/sudoers/test9.json.ok:
+ Check JSON output of sudoers test files too.
+ [3d8517812b80]
+
+2015-08-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Move comment to match moved code.
+ [7a30f06462a8]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ maxseq is an int not a string
+ [bffd97d22064]
+
+2015-08-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/preserve_fds.c:
+ Include sys/types.h for id_t. Bug #711
+ [fda95d9ca1e9]
+
+2015-07-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/fnmatch.c:
+ Avoid a potential out of bounds read found by enh while fuzzing with
+ address sanitizer enabled.
+ [52d6b9916593]
+
+2015-07-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ Set sssd lib location to /usr/lib64 on 64-bit RHEL/Centos. Bug #710
+ [428421925a20]
+
+2015-07-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS:
+ Add Jakub Wilk
+ [78bfdf2e441b]
+
+2015-07-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS, src/Makefile.in:
+ The init.d files are generated from a .in file so we need to install
+ from top_builddir not top_srcdir. From Ross Burton. Bug #708
+ [df1e7a0d3182]
+
+2015-07-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/term.c:
+ Replace two "return 0" with debug_return_bool(false).
+ [49f8fb3dcd36]
+
+ * src/ttyname.c:
+ fix typo in previous commit
+ [094488696f2c]
+
+ * NEWS, configure, configure.ac:
+ Sudo 1.8.14p3
+ [0079c43d8247]
+
+2015-07-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/ttyname.c:
+ Fix errno value from get_process_ttyname() when no tty is present.
+ [ff7b12bb0638]
+
+ * src/ttyname.c:
+ On AIX, only convert the tty device number from dev64_t to dev32_t
+ if dev_t is 32-bits.
+ [0e728a1eb07a]
+
+2015-07-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.ac:
+ Sudo 1.8.14p2
+ [55fe56b28c7b]
+
+ * plugins/sudoers/timestamp.c:
+ Fix creation of the timestamp file; bug #704
+ [1ff77fd5cc8f]
+
+2015-07-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/regress/ttyname/check_ttyname.c, src/sudo.c, src/sudo.h,
+ src/ttyname.c:
+ Avoid needless memory allocation when resolving the tty name.
+ [c58cce92d5e0]
+
+2015-07-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.ac:
+ Sudo 1.8.14p1
+ [973705806759]
+
+ * plugins/sudoers/sssd.c:
+ Fix typo in sudo_sss_attrcpy() that caused a memory allocation
+ error.
+ [0fa324a7bb56]
+
+2015-07-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/ja.mo, plugins/sudoers/po/uk.mo,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/zh_CN.mo:
+ rebuild
+ [e4c7cda46475]
+
+2015-07-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/lbuf.c, plugins/sudoers/env.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/interfaces.c,
+ plugins/sudoers/match.c, plugins/sudoers/pwutil_impl.c,
+ plugins/sudoers/redblack.c, src/hooks.c, src/net_ifs.c, src/sudo.c:
+ Add some debugging printfs when malloc fails and we don't have an
+ explicit call to sudo_warnx().
+ [07aebb5839c3]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c:
+ Add missing warnings for memory allocation failure. Add function
+ name to memory allocation warnings.
+ [4f6027786a28]
+
+ * lib/util/parseln.c:
+ Return -1 if realloc() fails.
+ [707632291eac]
+
+ * lib/util/event.c, lib/util/event_poll.c, lib/util/event_select.c:
+ Add line number to debug log for memory allocation errors.
+ [f4f3debdfcc5]
+
+ * plugins/sudoers/auth/pam.c:
+ Add warning if calloc() fails. Add debugging for other unexpected
+ errors.
+ [a1e0945237d8]
+
+ * plugins/sudoers/ldap.c:
+ Add missing check for calloc(3) return value.
+ [37fe3ca78e8e]
+
+2015-07-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document that the values printed by "sudo -V" are affected by
+ Defaults settings in sudoers.
+ [80ec2572861b]
+
+2015-07-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/group_plugin.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/sssd.c, src/load_plugins.c:
+ Avoid calling dlerror() multiple times since it clear the error
+ status after printing the error. Problem caused by
+ sudo_warn/sudo_fatal being macros...
+ [c0fd3b0fb9c3]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Attempt to clarify the conditions under which MAIL and HOME are set
+ to the target user.
+ [ebd269bebe64]
+
+2015-07-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ Better checks for the libaudit package for Debian and error out if
+ we can't figure it out.
+ [225c1bfcb629]
+
+ * mkpkg:
+ Fix linux_audit setting on non-multiarch Debian.
+ [0a38e9d158f4]
+
+ * sudo.pp:
+ Fix typo that broke the linux_audit dependency on Debian.
+ [0917bd45acf1]
+
+ * NEWS:
+ Mention /proc/stat btime fix.
+ [754050a340e2]
+
+ * config.h.in, configure, configure.ac, lib/util/getaddrinfo.c,
+ plugins/sudoers/interfaces.c, plugins/sudoers/match_addr.c,
+ src/net_ifs.c:
+ Solaris 2.6 has the prototypes for inet_pton() and inet_ntop() in
+ resolv.h.
+ [dc0f62743845]
+
+ * plugins/sudoers/boottime.c:
+ Sprinkle debugging for boottime.
+ [dfb45c763179]
+
+ * mkpkg:
+ The old Solaris /bin/sh doesn't support POSIX $( .. ) syntax, use
+ backquotes instead.
+ [c9e33ffef2b1]
+
+2015-07-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg, sudo.pp:
+ Only use --with-sssd-lib on Debian/Ubuntu w/ multipackage. Use dpkg-
+ query to determine the name of the audit package for proper
+ dependencies.
+ [e9669389aa2f]
+
+ * mkpkg, plugins/sudoers/sudoers.in, sudo.pp:
+ Update Debian/Ubuntu packages to be more like the vendor ones. One
+ notable exception is that sudo.ws packages use /var/run, not
+ /var/lib for timestamp files.
+ [0f4c49a3768e]
+
+ * plugins/sudoers/boottime.c:
+ Strip newline from /proc/stat btime line to avoid a strtonum()
+ failure. From Jakub Wilk.
+ [8a04f85a070f]
+
+ * src/exec_pty.c:
+ In io_callback() service writes before reads. That way, if both
+ SUDO_EV_READ and SUDO_EV_WRITE are set and read() returns 0 (EOF) we
+ don't close the fd before the write() is performed.
+
+ If the write() returns EPIPE, ENXIO, EIO or EBADF, clear
+ SUDO_EV_READ before we close the fd to avoid calling read() on a
+ closed fd.
+ [167548fd8af2]
+
+2015-07-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/regress/sudo_conf/conf_test.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c, src/sesh.c, src/sudo.c:
+ Check sudo_conf_read() return value and exit on fatal error (a
+ warning was already printed by sudo_conf_read()).
+ [d05797f4f197]
+
+ * NEWS:
+ Mention double-quoted sudoOption value support.
+ [55684a73f097]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Add support for parsing quoted strings in a sudoOption just like
+ sudoers Defaults settings.
+ [fe8291414179]
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po, po/da.mo,
+ po/da.po:
+ Sync with translationproject.org
+ [1c15d1a3dbdd]
+
+2015-07-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ Update year.
+ [6ca660e4a957]
+
+ * plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po, po/de.mo,
+ po/de.po, po/nb.mo, po/nb.po:
+ Sync with translationproject.org
+ [d7ede74dcb19]
+
+ * src/sudo.c:
+ Fix utmp setup broken by commit be0ca60facf8
+ [cd8a06f57f2b]
+
+2015-07-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/ja.po, plugins/sudoers/po/pl.mo,
+ plugins/sudoers/po/pl.po, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.po, plugins/sudoers/po/zh_CN.po, po/cs.mo,
+ po/cs.po, po/fr.mo, po/fr.po, po/it.mo, po/it.po, po/pl.mo,
+ po/pl.po:
+ Sync with translationproject.org
+ [aa473519e66d]
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [8f8aa321f043]
+
+ * plugins/sudoers/logging.c:
+ Fix typo in error message.
+ [220832711826]
+
+2015-07-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Bug #702 is the AIX timespec issue.
+ [c597a312e816]
+
+ * config.h.in, configure, configure.ac, lib/util/closefrom.c,
+ lib/util/getcwd.c, lib/util/glob.c, plugins/sudoers/match.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, src/ttyname.c:
+ We require POSIX so no need to conditionally include dirent.h. Add a
+ check for d_namlen and use the result in the NAMLEN macro.
+ [2728194cb6cf]
+
+ * lib/util/event.c, lib/util/event_poll.c, lib/util/event_select.c,
+ lib/util/getcwd.c, lib/util/gettime.c, lib/util/glob.c,
+ lib/util/lbuf.c, lib/util/locking.c, lib/util/mktemp.c,
+ lib/util/parseln.c, lib/util/secure_path.c, lib/util/setgroups.c,
+ lib/util/sudo_conf.c, lib/util/sudo_debug.c, lib/util/ttysize.c,
+ plugins/group_file/group_file.c, plugins/sample/sample_plugin.c,
+ plugins/sudoers/alias.c, plugins/sudoers/auth/afs.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/dce.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/check.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/editor.c, plugins/sudoers/env.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/getspwuid.c,
+ plugins/sudoers/goodpath.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/interfaces.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/logging.c,
+ plugins/sudoers/match.c, plugins/sudoers/match_addr.c,
+ plugins/sudoers/parse.c, plugins/sudoers/policy.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/pwutil_impl.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers_debug.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, plugins/sudoers/visudo.c,
+ plugins/sudoers/visudo_json.c, plugins/system_group/system_group.c,
+ src/conversation.c, src/exec.c, src/exec_common.c, src/exec_pty.c,
+ src/get_pty.c, src/hooks.c, src/load_plugins.c, src/net_ifs.c,
+ src/openbsd.c, src/parse_args.c, src/preserve_fds.c, src/signal.c,
+ src/solaris.c, src/sudo.c, src/sudo_edit.c, src/sudo_noexec.c,
+ src/tgetpass.c, src/ttyname.c, src/utmp.c:
+ There's no need to conditionalize the #include <unistd.h>, we
+ require a POSIX system.
+ [79389c527c08]
+
+ * include/sudo_compat.h:
+ Remove some compatibilty defines that should no longer be needed.
+ [e9136646d1c6]
+
+2015-06-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Final changes in 1.8.14
+ [3a5cd4f2875a]
+
+ * include/sudo_compat.h:
+ Need to include stddef.h to get rsize_t on Mac OS X for
+ sudo_memset_s() prototype.
+ [9615efed4a9a]
+
+ * lib/util/regress/parse_gids/parse_gids_test.c,
+ lib/util/regress/strsplit/strsplit_test.c:
+ Add missing exit value.
+ [484202b53893]
+
+ * lib/util/regress/mktemp/mktemp_test.c:
+ Add missing fcntl.h include.
+ [020fe6252d96]
+
+ * configure, configure.ac:
+ Do check for inet_pton before inet_ntop since we may need to record
+ dependent libraries for inet_pton when linking our getaddrinfo
+ replacement.
+ [fde03eefd88d]
+
+ * include/sudo_debug.h, lib/util/sudo_debug.c:
+ Fix build on compilers w/o __func__ or __FUNCTION__
+ [196d75416cd5]
+
+ * lib/util/util.exp.in:
+ Remove sudo_evasprintf_v1, missed during alloc.c removal.
+ [7d0ac7e5909d]
+
+ * lib/util/snprintf.c:
+ Add missing fcntl.h include.
+ [23b886deb879]
+
+ * config.h.in, configure, configure.ac:
+ Add check for inline support.
+ [061dab0e411c]
+
+2015-06-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/LICENSE:
+ Add reallocarray.c license.
+ [b4b4d46309f3]
+
+2015-06-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS:
+ Fix entry for Joel Pelaez Jorge.
+ [386434049903]
+
+2015-06-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_lbuf.h, lib/util/lbuf.c, lib/util/util.exp.in,
+ plugins/sudoers/ldap.c, plugins/sudoers/parse.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudo_nss.c:
+ Add an error flag to the lbuf struct to simplify error checking.
+ Callers of the lbuf functions now check the error flag to tell if a
+ memory allocation error ocurred.
+ [bc44b0fbc03b]
+
+ * plugins/sudoers/parse.c, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudo_nss.h, plugins/sudoers/sudoers.h:
+ display_privs() and display_cmnd() may need to return -1 on error.
+ [b6d8826900bb]
+
+2015-06-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Return -1, not 0 from sudoers when there is an error (as opposed to
+ a policy denial).
+ [5d197fe29e0e]
+
+ * plugins/sudoers/check.c, plugins/sudoers/check.h,
+ plugins/sudoers/ldap.c, plugins/sudoers/logging.c,
+ plugins/sudoers/parse.c, plugins/sudoers/policy.c,
+ plugins/sudoers/prompt.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/timestamp.c:
+ Check restore_perms() return value in all cases, pushing the return
+ value back up the call stack.
+ [c9beeed2b614]
+
+ * doc/CONTRIBUTORS:
+ Add Joel Pelaez Jorge
+ [55387b44d6e9]
+
+ * plugins/sudoers/auth/pam.c:
+ When checking whether the PAM prompt matches "Password:", also check
+ for the untranslated version. The PAM module might not be using the
+ localized string even though it exists. From Joel Pelaez Jorge.
+ Fixes Bug #701
+ [d87f6f2ccb42]
+
+2015-06-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Silence clang analyzer warning on glibc systems where the first
+ argument to qsort() is marked as non-NULL. Also change some counters
+ from into to unsigned int and two flags from int to bool.
+ [09e400445ca2]
+
+2015-06-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ Silence clang analyzer warning on glibc systems where the first
+ argument to qsort() is marked as non-NULL.
+ [34fa7256f1e2]
+
+ * include/sudo_compat.h, include/sudo_debug.h, include/sudo_util.h,
+ src/preserve_fds.c:
+ Use our own bitmap macros instead of borrowing the ones from select.
+ [51ef403511d9]
+
+ * src/ttyname.c:
+ Quiet clang analyzer false positive.
+ [9ebecd6b6b29]
+
+ * src/sesh.c:
+ Fix uninitialized variables warnings in error case when src file
+ cannot be opened. At least one of these is a false positive.
+ [98b417c1307a]
+
+ * lib/util/sudo_debug.c:
+ Must call round_nfds() with fd+1 since it takes a count not the fd
+ number. In other words, the lowest value is 1, not 0.
+ [cc175cba5371]
+
+2015-06-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/getline.c, plugins/sudoers/toke_util.c:
+ It's safe to rely on C89 semantics for realloc(NULL, size).
+ [b633582413ac]
+
+ * plugins/sudoers/env.c:
+ malloc() sets errno to ENOMEM on failure so we don't need to set it
+ explicitly.
+ [09cb5ceaaec3]
+
+ * include/sudo_compat.h:
+ No longer need __malloc_like
+ [a41b69f256f6]
+
+ * lib/util/util.exp.in:
+ Remove symbols from the now-removed alloc.c.
+ [da0753d85d20]
+
+ * include/sudo_compat.h, lib/util/aix.c, lib/util/closefrom.c,
+ lib/util/event.c, lib/util/event_poll.c, lib/util/event_select.c,
+ lib/util/getaddrinfo.c, lib/util/getcwd.c, lib/util/getgrouplist.c,
+ lib/util/gethostname.c, lib/util/getline.c, lib/util/getopt_long.c,
+ lib/util/gettime.c, lib/util/gidlist.c, lib/util/glob.c,
+ lib/util/key_val.c, lib/util/lbuf.c, lib/util/locking.c,
+ lib/util/mksiglist.c, lib/util/mksigname.c, lib/util/parseln.c,
+ lib/util/progname.c, lib/util/pw_dup.c, lib/util/reallocarray.c,
+ lib/util/regress/atofoo/atofoo_test.c,
+ lib/util/regress/parse_gids/parse_gids_test.c,
+ lib/util/regress/progname/progname_test.c,
+ lib/util/regress/strsplit/strsplit_test.c,
+ lib/util/regress/sudo_conf/conf_test.c,
+ lib/util/regress/sudo_parseln/parseln_test.c, lib/util/setgroups.c,
+ lib/util/sha2.c, lib/util/sig2str.c, lib/util/snprintf.c,
+ lib/util/strndup.c, lib/util/strsplit.c, lib/util/strtobool.c,
+ lib/util/strtoid.c, lib/util/strtomode.c, lib/util/strtonum.c,
+ lib/util/sudo_conf.c, lib/util/sudo_debug.c, lib/util/sudo_dso.c,
+ lib/util/term.c, lib/util/ttysize.c, plugins/group_file/getgrent.c,
+ plugins/group_file/group_file.c, plugins/group_file/plugin_test.c,
+ plugins/sample/sample_plugin.c, plugins/sudoers/alias.c,
+ plugins/sudoers/audit.c, plugins/sudoers/auth/afs.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/dce.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/base64.c, plugins/sudoers/boottime.c,
+ plugins/sudoers/check.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/editor.c, plugins/sudoers/env.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/getdate.c,
+ plugins/sudoers/getdate.y, plugins/sudoers/getspwuid.c,
+ plugins/sudoers/group_plugin.c, plugins/sudoers/interfaces.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/locale.c,
+ plugins/sudoers/logging.c, plugins/sudoers/logwrap.c,
+ plugins/sudoers/match.c, plugins/sudoers/match_addr.c,
+ plugins/sudoers/parse.c, plugins/sudoers/policy.c,
+ plugins/sudoers/prompt.c, plugins/sudoers/pwutil_impl.c,
+ plugins/sudoers/redblack.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/regress/parser/check_base64.c,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/regress/parser/check_hexchar.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudo_printf.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers_debug.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/timestamp.c, plugins/sudoers/timestr.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, plugins/sudoers/tsgetgrpw.c,
+ plugins/sudoers/visudo.c, plugins/sudoers/visudo_json.c,
+ plugins/system_group/system_group.c, src/conversation.c,
+ src/env_hooks.c, src/exec.c, src/exec_common.c, src/exec_pty.c,
+ src/get_pty.c, src/hooks.c, src/load_plugins.c, src/net_ifs.c,
+ src/openbsd.c, src/parse_args.c, src/preserve_fds.c,
+ src/regress/ttyname/check_ttyname.c, src/selinux.c, src/signal.c,
+ src/solaris.c, src/sudo.c, src/sudo_edit.c, src/tgetpass.c,
+ src/ttyname.c, src/utmp.c:
+ Only include stddef.h where it is needed.
+ [ce597fb7ffb9]
+
+2015-06-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [cad83b927f4e]
+
+ * lib/util/sudo_conf.c, plugins/sudoers/locale.c:
+ Better handling of setlocale() returning NULL.
+ [7cd4fcdb528c]
+
+ * lib/util/aix.c, lib/util/gidlist.c, lib/util/sudo_conf.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/editor.c,
+ plugins/sudoers/env.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/linux_audit.c,
+ plugins/sudoers/logging.c, plugins/sudoers/match.c,
+ plugins/sudoers/parse.c, plugins/sudoers/policy.c,
+ plugins/sudoers/prompt.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers_debug.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c, src/conversation.c, src/exec.c,
+ src/exec_common.c, src/exec_pty.c, src/load_plugins.c,
+ src/parse_args.c, src/preserve_fds.c, src/selinux.c, src/sesh.c,
+ src/sudo.c, src/sudo_edit.c:
+ Add function name to "unable to allocate memory" warnings.
+ [98c07e26a13e]
+
+ * configure, configure.ac, include/sudo_compat.h, lib/util/aix.c,
+ lib/util/closefrom.c, lib/util/event.c, lib/util/event_poll.c,
+ lib/util/event_select.c, lib/util/getaddrinfo.c, lib/util/getcwd.c,
+ lib/util/getgrouplist.c, lib/util/gethostname.c, lib/util/getline.c,
+ lib/util/getopt_long.c, lib/util/gettime.c, lib/util/gidlist.c,
+ lib/util/glob.c, lib/util/key_val.c, lib/util/lbuf.c,
+ lib/util/locking.c, lib/util/mksiglist.c, lib/util/mksigname.c,
+ lib/util/parseln.c, lib/util/progname.c, lib/util/pw_dup.c,
+ lib/util/reallocarray.c, lib/util/regress/atofoo/atofoo_test.c,
+ lib/util/regress/parse_gids/parse_gids_test.c,
+ lib/util/regress/progname/progname_test.c,
+ lib/util/regress/strsplit/strsplit_test.c,
+ lib/util/regress/sudo_conf/conf_test.c,
+ lib/util/regress/sudo_parseln/parseln_test.c,
+ lib/util/regress/tailq/hltq_test.c, lib/util/setgroups.c,
+ lib/util/sha2.c, lib/util/sig2str.c, lib/util/snprintf.c,
+ lib/util/strndup.c, lib/util/strsplit.c, lib/util/strtobool.c,
+ lib/util/strtoid.c, lib/util/strtomode.c, lib/util/strtonum.c,
+ lib/util/sudo_conf.c, lib/util/sudo_debug.c, lib/util/sudo_dso.c,
+ lib/util/term.c, lib/util/ttysize.c, plugins/group_file/getgrent.c,
+ plugins/group_file/group_file.c, plugins/sample/sample_plugin.c,
+ plugins/sudoers/alias.c, plugins/sudoers/audit.c,
+ plugins/sudoers/auth/afs.c, plugins/sudoers/auth/aix_auth.c,
+ plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/dce.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/passwd.c,
+ plugins/sudoers/auth/rfc1938.c, plugins/sudoers/auth/secureware.c,
+ plugins/sudoers/auth/securid5.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/base64.c,
+ plugins/sudoers/boottime.c, plugins/sudoers/check.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/editor.c,
+ plugins/sudoers/env.c, plugins/sudoers/find_path.c,
+ plugins/sudoers/getdate.c, plugins/sudoers/getdate.y,
+ plugins/sudoers/getspwuid.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/interfaces.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/iolog_path.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/locale.c,
+ plugins/sudoers/logging.c, plugins/sudoers/logwrap.c,
+ plugins/sudoers/match.c, plugins/sudoers/match_addr.c,
+ plugins/sudoers/parse.c, plugins/sudoers/policy.c,
+ plugins/sudoers/prompt.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/pwutil_impl.c, plugins/sudoers/redblack.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/regress/parser/check_base64.c,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/regress/parser/check_hexchar.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudo_printf.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers_debug.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/timestamp.c, plugins/sudoers/timestr.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, plugins/sudoers/tsgetgrpw.c,
+ plugins/sudoers/visudo.c, plugins/sudoers/visudo_json.c,
+ plugins/system_group/system_group.c, src/conversation.c,
+ src/env_hooks.c, src/exec.c, src/exec_common.c, src/exec_pty.c,
+ src/get_pty.c, src/hooks.c, src/load_plugins.c, src/net_ifs.c,
+ src/openbsd.c, src/parse_args.c, src/preserve_fds.c,
+ src/regress/ttyname/check_ttyname.c, src/signal.c, src/solaris.c,
+ src/sudo.c, src/sudo_edit.c, src/tgetpass.c, src/ttyname.c,
+ src/utmp.c:
+ We require ANSI C so stop using the obsolete STDC_HEADERS.
+ [35a5a680e5fe]
+
+ * config.h.in, configure, configure.ac:
+ Add back _REENTRANT define on HP-UX to expose strtok_r on some
+ versions. We may need to define it on other systems too.
+ [12c36f12eed2]
+
+ * lib/util/getgrouplist.c, lib/util/regress/glob/globtest.c,
+ lib/util/sudo_debug.c, plugins/group_file/getgrent.c,
+ plugins/group_file/plugin_test.c, plugins/sample/sample_plugin.c,
+ plugins/sudoers/group_plugin.c, plugins/sudoers/interfaces.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/logging.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/tsgetgrpw.c:
+ Use strtok_r() instead of strtok()
+ [6b8e3c253dcf]
+
+ * configure, configure.ac:
+ Fix check for strnlen() when cross-compiling.
+ [e501c508891a]
+
+ * plugins/sudoers/interfaces.c:
+ Use sudo_strsplit() in dump_interfaces.
+ [b76ee2f47f37]
+
+2015-06-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/inet_pton.c, lib/util/key_val.c, lib/util/lbuf.c,
+ lib/util/locking.c, lib/util/parseln.c,
+ lib/util/regress/parse_gids/parse_gids_test.c,
+ lib/util/regress/progname/progname_test.c,
+ lib/util/regress/strsplit/strsplit_test.c,
+ lib/util/regress/sudo_conf/conf_test.c,
+ lib/util/regress/sudo_parseln/parseln_test.c,
+ lib/util/regress/tailq/hltq_test.c, lib/util/sha2.c,
+ lib/util/snprintf.c, lib/util/strtobool.c, lib/util/term.c,
+ plugins/group_file/getgrent.c, plugins/group_file/group_file.c,
+ plugins/sample/sample_plugin.c, plugins/sudoers/boottime.c,
+ plugins/sudoers/editor.c, plugins/sudoers/getdate.c,
+ plugins/sudoers/getdate.y, plugins/sudoers/interfaces.c,
+ plugins/sudoers/iolog_path.c, plugins/sudoers/policy.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/pwutil_impl.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_base64.c,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/regress/parser/check_hexchar.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/tsgetgrpw.c, plugins/system_group/system_group.c,
+ src/conversation.c, src/exec_pty.c, src/net_ifs.c, src/openbsd.c,
+ src/preserve_fds.c, src/regress/ttyname/check_ttyname.c,
+ src/solaris.c, src/sudo.c, src/tgetpass.c, src/ttyname.c,
+ src/utmp.c:
+ Remove obsolete memory.h include.
+ [0c1351d614a9]
+
+ * config.h.in, configure, configure.ac, lib/util/getcwd.c,
+ lib/util/gethostname.c, lib/util/glob.c, lib/util/locking.c,
+ lib/util/parseln.c, lib/util/pw_dup.c, lib/util/reallocarray.c,
+ lib/util/snprintf.c, lib/util/strndup.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c,
+ src/env_hooks.c:
+ Remove support for the obsolete malloc.h header.
+ [2a118de27d4e]
+
+ * config.h.in, configure, configure.ac, plugins/sudoers/defaults.c,
+ plugins/sudoers/logging.c:
+ Remove BROKEN_SYSLOG define which was for obsolete versions of HP-
+ UX. Remove last remnants of 4.2BSD syslog support.
+ [e234515f515d]
+
+ * lib/util/sudo_conf.c:
+ Use sudo_strsplit() instead of doing the equivalent manually.
+ [220f2e4a0e68]
+
+ * lib/util/regress/strsplit/strsplit_test.c:
+ Test strsplit behavior with an empty string.
+ [62ae80dcee4a]
+
+ * lib/util/Makefile.in, lib/zlib/Makefile.in,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/system_group/Makefile.in,
+ src/Makefile.in:
+ Allow "make LIBTOOL=/path/to/libtool" to work properly.
+ [f9e5f7109107]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/editor.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/goodpath.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/visudo.c:
+ Use a common function for resolviong the user's editor in sudoedit
+ and visudo. The find_path() function now returns a dynamically
+ allocated path instead of using a static string.
+ [97fe58966144]
+
+ * config.h.in, configure, configure.ac, lib/util/Makefile.in,
+ lib/zlib/Makefile.in, plugins/group_file/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in, src/Makefile.in:
+ Replace use of OSDEFS with config.h defines. Rename DEFS in
+ Makefile.in to CPPDEFS and include in CPPFLAGS. Bring back
+ _BSD_SOURCE as a config.h define. Remove obsolescent _REENTRANT
+ define.
+ [0d76a12adca8]
+
+2015-06-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, include/sudo_alloc.h, lib/util/Makefile.in,
+ lib/util/alloc.c:
+ Remove now-unused sudo_alloc.h and alloc.c
+ [0fe70085c75c]
+
+ * plugins/sudoers/Makefile.in, src/Makefile.in, src/conversation.c,
+ src/env_hooks.c, src/exec.c, src/exec_common.c, src/exec_pty.c,
+ src/hooks.c, src/load_plugins.c, src/net_ifs.c, src/parse_args.c,
+ src/preserve_fds.c, src/regress/ttyname/check_ttyname.c,
+ src/selinux.c, src/sesh.c, src/sudo.c, src/sudo.h, src/sudo_edit.c,
+ src/ttyname.c:
+ Avoid using exiting allocators in the front end.
+ [be0ca60facf8]
+
+ * include/sudo_conf.h, include/sudo_lbuf.h, lib/util/Makefile.in,
+ lib/util/aix.c, lib/util/gidlist.c, lib/util/lbuf.c,
+ lib/util/sudo_conf.c, lib/util/sudo_debug.c:
+ Use non-exiting allocators in libsudo_util.
+ [d9b7cf17b9b4]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/logging.c:
+ Remove asprintf() return value warnings.
+ [fe25ce11f96a]
+
+ * config.h.in, configure, configure.ac:
+ Use AC_FUNC_STRNLEN to check for broken strnlen() on AIX. This
+ requires that we use AC_USE_SYSTEM_EXTENSIONS so remove things from
+ OSDEFS that are enabled by AC_USE_SYSTEM_EXTENSIONS.
+ [1f64269cab6e]
+
+ * plugins/sudoers/ldap.c:
+ Remove extraneous semicolons in CHECK_* macros.
+ [ef99aa3c9d70]
+
+ * plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c:
+ Remove remaining SUDO_MAIN remnants.
+ [1c077699f444]
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/alias.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/check.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/defaults.h, plugins/sudoers/env.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/getspwuid.c,
+ plugins/sudoers/group_plugin.c, plugins/sudoers/interfaces.c,
+ plugins/sudoers/interfaces.h, plugins/sudoers/iolog.c,
+ plugins/sudoers/iolog_path.c, plugins/sudoers/linux_audit.c,
+ plugins/sudoers/locale.c, plugins/sudoers/logging.h,
+ plugins/sudoers/match.c, plugins/sudoers/parse.c,
+ plugins/sudoers/policy.c, plugins/sudoers/prompt.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/sudoers_debug.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ Use non-exiting allocatings in the sudoers plugin.
+ [a5668cb9c516]
+
+2015-06-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sssd.c:
+ Use non-exiting allocators in the sudoers SSSD backend.
+ [dba29b55ac0b]
+
+ * plugins/sudoers/ldap.c:
+ Use non-exiting allocators in the sudoers LDAP backend.
+ [37bfa441345a]
+
+ * lib/util/Makefile.in:
+ regen dependencies
+ [5be6eb005946]
+
+2015-06-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, lib/util/Makefile.in, mkdep.pl:
+ Add missing dependency info for reallocarray.lo in
+ lib/util/Makefile.in and regen configure to match last configure.ac
+ change.
+ [da1fc49b53dc]
+
+ * plugins/sudoers/ldap.c:
+ Use \28 and \29 instead of \( and \) in the ldap query as per RFC
+ 2254. Fixes netgroup queries on AIX. From Steven Soulen.
+ [33267d6243aa]
+
+2015-06-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/glob.c:
+ Move pattern length check until after we have initialized the glob_t
+ so we can call globfree() even on error. From Frank Denis.
+ [a246f9054395]
+
+2015-06-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c, src/sudo.c:
+ We need to unlimit RLIMIT_NPROC in sudoers as well as the sudo front
+ end since set_perms() and restore_perms change the read uid and may
+ fail with EAGAIN on Linux kernels prior to 3.1.
+ [e6a03c31f4e5]
+
+2015-06-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Fix underlining of "root" in -u option descriptions. Bug #699
+ [b3afe47d9798]
+
+ * doc/UPGRADE, src/load_plugins.c:
+ Remove support for converting plugin.so -> plugin.sl on HP-UX when
+ plugin.so can not be found. This was a temporary hack for using an
+ older (pre 1.8.7) sudoers plugin with a newer sudo front-end.
+ [561e2ce444ed]
+
+2015-06-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/event.c, lib/util/event_select.c:
+ Add debugging output on memory alloc failure. Add missing checks in
+ event_select.c for reallocarray() failure.
+ [0853c7bcbeaa]
+
+ * lib/util/event_poll.c:
+ Use non-exiting allocators.
+ [5ed0e276b551]
+
+2015-06-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/logging.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Bring back VALIDATE_ERROR which will be used in the case of memory
+ allocation errors.
+ [784c885db95c]
+
+2015-06-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/snprintf.c:
+ If asprintf() or vasprintf() fail, set the dest pointer to NULL like
+ BSD and Solaris do. This appears to be the direction glibc is going
+ as well.
+ [92fb2283dc9a]
+
+2015-05-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/env.c:
+ Use a stack buffer for the validate_env_vars() error message.
+ [69df3a0cbc2b]
+
+2015-05-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/fatal.c:
+ Fix typo/thinko in static buffer conversion; use vsnprintf() not
+ snprintf()
+ [9d42fb3a94f6]
+
+ * plugins/sudoers/ldap.c:
+ Fix old gcc2 variadic macro support.
+ [fd951ed8865e]
+
+ * plugins/sudoers/visudo.c:
+ Restore old behavior where visudo prevents you from making the main
+ sudoers file zero length.
+ [b03ef908120f]
+
+ * plugins/sudoers/logging.c, plugins/sudoers/logging.h,
+ plugins/sudoers/sudoers.c:
+ Non-exiting allocators for log functions. If log_allowed() fails the
+ user may not run the command. We don't try to return early for
+ log_failure(), log_auth_failure() or log_denial() as we would not
+ run the command in that case.
+ [40c3d0dd75bc]
+
+ * plugins/sudoers/alias.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c:
+ Use non-exiting allocators in the parser (much of it already did).
+ [f14222e5ad1b]
+
+ * lib/util/aix.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/pwutil_impl.c:
+ Use non-existing allocators in the passwd/group cache functions.
+ [86bbe840f348]
+
+ * MANIFEST, configure.ac, lib/util/alloc.c, lib/util/reallocarray.c:
+ Add standalone reallocarray.c from OpenBSD instead of rolling our
+ own.
+ [36ec5840729e]
+
+ * plugins/sudoers/alias.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/iolog.c,
+ plugins/sudoers/parse.h, plugins/sudoers/pwutil.c,
+ plugins/sudoers/redblack.c, plugins/sudoers/redblack.h,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ Use non-exiting allocators in the redblack tree and fix the fallout.
+ Also switch to non-exiting allocators in affected code blocks.
+ [bca56cf769cb]
+
+ * plugins/sudoers/alias.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/parse.h:
+ The error string returned by alias_add should be const.
+ [b378188a0a8f]
+
+ * plugins/sudoers/policy.c:
+ Fix typo, efree vs. free.
+ [9146ba7473ca]
+
+ * plugins/sudoers/policy.c, src/exec_common.c, src/sudo.c:
+ Add a few missing sudo_new_key_val() return value checks. Also use
+ non-exiting allocators for consistency.
+ [2ae76a679052]
+
+2015-05-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, lib/util/Makefile.in,
+ lib/util/regress/parse_gids/parse_gids_test.c,
+ lib/util/regress/strsplit/strsplit_test.c:
+ Add unit tests for strsplit and parse_gid_list.
+ [e08c5ff7b5f0]
+
+ * MANIFEST, include/sudo_util.h, lib/util/Makefile.in,
+ lib/util/strsplit.c, lib/util/util.exp.in,
+ plugins/sudoers/sudoers.c:
+ Add sudo_strsplit(), similar to strtok_r() but non-destructive and
+ operates on non-C strings (requires a length parameter).
+ [45fb50775249]
+
+2015-05-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/sia.c:
+ Use reallocarray() instead of sudo_emallocarray() and return an
+ error on allocation failure.
+ [fee12ac1e0c8]
+
+ * plugins/sudoers/auth/kerb5.c:
+ In our krb5_get_init_creds_opt_alloc() replacement use malloc()
+ instead of sudo_emalloc() and return KRB5_CC_NOMEM on allocation
+ failure. Only old versions of Kerberos V will need this.
+ [95ac6c5b7b60]
+
+ * lib/util/event.c, lib/util/event_select.c:
+ Use non-exiting allocators.
+ [91bbc657901d]
+
+2015-05-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/fatal.c:
+ Use a static buffer for sudo_warn/sudo_fatal messages where
+ possible.
+ [6e1d6ecc022d]
+
+ * include/sudo_compat.h:
+ Fix sudo_strnlen() prototype.
+ [1367bd9227b3]
+
+ * MANIFEST, config.h.in, configure, configure.ac,
+ include/sudo_compat.h, lib/util/Makefile.in, lib/util/strndup.c,
+ mkdep.pl:
+ Add strndup() for those without it. As strndup.c uses strnlen(), use
+ our own if it is missing.
+ [cf904a9c68f7]
+
+ * lib/util/strnlen.c:
+ Add missing sudo_ prefix and include sudo_compat.h.
+ [d5e5dfc3fd20]
+
+ * MANIFEST, config.h.in, configure, configure.ac,
+ include/sudo_compat.h, lib/util/strnlen.c:
+ Add strnlen() replacement needed for glob.c. Only used if no glob()
+ and no strnlen().
+ [bb6b7c4549b1]
+
+2015-05-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/logging.h, plugins/sudoers/sudoers.h:
+ Get rid of SUDO_MAIN. Modern compilers don't warn about mixing
+ extern and auto declarations unless they conflict.
+ [a273b73bca6d]
+
+ * config.h.in, configure.ac, include/compat/endian.h,
+ include/compat/fnmatch.h, include/compat/getaddrinfo.h,
+ include/compat/getopt.h, include/compat/glob.h,
+ include/compat/nss_dbdefs.h, include/compat/sha2.h,
+ include/compat/stdbool.h, include/compat/timespec.h,
+ include/sudo_alloc.h, include/sudo_compat.h, include/sudo_conf.h,
+ include/sudo_debug.h, include/sudo_dso.h, include/sudo_event.h,
+ include/sudo_fatal.h, include/sudo_gettext.h, include/sudo_lbuf.h,
+ include/sudo_plugin.h, include/sudo_queue.h, include/sudo_util.h,
+ lib/util/fatal.c, plugins/sudoers/bsm_audit.h,
+ plugins/sudoers/check.h, plugins/sudoers/defaults.h,
+ plugins/sudoers/ins_2001.h, plugins/sudoers/ins_classic.h,
+ plugins/sudoers/ins_csops.h, plugins/sudoers/ins_goons.h,
+ plugins/sudoers/insults.h, plugins/sudoers/interfaces.h,
+ plugins/sudoers/iolog.h, plugins/sudoers/linux_audit.h,
+ plugins/sudoers/logging.h, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/pwutil.h,
+ plugins/sudoers/redblack.c, plugins/sudoers/redblack.h,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/solaris_audit.h, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudo_nss.h, plugins/sudoers/sudo_printf.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/sudoers_debug.h, plugins/sudoers/sudoers_version.h,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.h, plugins/sudoers/toke.l,
+ plugins/sudoers/visudo.c, src/net_ifs.c, src/sudo.h,
+ src/sudo_exec.h, src/sudo_plugin_int.h, src/sudo_usage.h.in:
+ Avoid using a leading underbar in defines as they are reserved in
+ ISO C.
+ [a442d88c6490]
+
+ * Makefile.in, doc/Makefile.in, examples/Makefile.in,
+ include/Makefile.in, lib/util/Makefile.in, lib/zlib/Makefile.in,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/auth/afs.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/dce.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/rfc1938.c, plugins/sudoers/auth/secureware.c,
+ plugins/sudoers/auth/securid5.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/linux_audit.c,
+ plugins/sudoers/solaris_audit.c, plugins/sudoers/sssd.c,
+ plugins/system_group/Makefile.in, src/Makefile.in, src/selinux.c:
+ Add target for "make splint". A few files need extra guards to avoid
+ errors on systems where they would not otherwise be compiled. No
+ warnings from splint.
+ [64fc04debc58]
+
+2015-05-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.ac, src/sudo.c:
+ There should be no need to check for tzset() as it is POSIX.
+ [50825eb75c97]
+
+ * configure, configure.ac:
+ Add sudo_reallocarrary to util.exp.in if reallocarray is not found.
+ [32588e00bb33]
+
+2015-05-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ NLS now works on Mac OS X properly.
+ [1485c9e51b04]
+
+ * configure, configure.ac, src/Makefile.in:
+ Force flat namespace on darwin to make the getenv() hooking work as
+ it does on ELF.
+ [0837cc3559ce]
+
+2015-05-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/alloc.c, lib/util/snprintf.c,
+ plugins/sample/sample_plugin.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/redblack.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/toke_util.c:
+ No need to cast malloc() return value.
+ [09c7236d3e1a]
+
+ * lib/util/getcwd.c, lib/util/getline.c, lib/util/glob.c,
+ plugins/sudoers/env.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l:
+ Use reallocarray where possible.
+ [2b5957a38baa]
+
+ * config.h.in, configure, configure.ac, include/sudo_compat.h,
+ lib/util/alloc.c:
+ Add reallocarray() for those without it.
+ [3ac5a4abe077]
+
+2015-05-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ The getenv() hook still doesn't work on Mac OS X.
+ [d9297b9ff54c]
+
+2015-05-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_fatal.h, lib/util/fatal.c:
+ In sudo_warn_gettext_v1() call dgettext() not gettext() to make sure
+ the domain is set correctly. The sudoers plugin uses its own text
+ domain.
+ [f7ce0100ff5c]
+
+2015-05-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/Makefile.in:
+ man pages should explicitly depend on config.status since it is used
+ to substitute in variables/settings.
+ [bebe8e19d767]
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo_plugin.cat,
+ doc/sudoers.cat, doc/sudoers.ldap.cat, doc/sudoers.man.in,
+ doc/sudoreplay.cat, doc/visudo.cat:
+ regen
+ [2e613d7bb477]
+
+ * NEWS, configure, configure.ac:
+ Sudo 1.8.14
+ [66e33bc0d18e]
+
+ * INSTALL, MANIFEST, aclocal.m4, config.h.in, configure, configure.ac,
+ include/sudo_fatal.h, lib/util/Makefile.in, lib/util/fatal.c,
+ lib/util/locale_weak.c, lib/util/util.exp.in,
+ m4/ax_sys_weak_alias.m4, mkdep.pl, plugins/sudoers/Makefile.in,
+ plugins/sudoers/locale.c, plugins/sudoers/logging.h,
+ plugins/sudoers/sudoers.c, src/Makefile.in, src/locale_stub.c:
+ Instead of trying to make weak functions work on all platforms, just
+ use a registration function for a plugin-specific setlocale
+ function. The sudoers version just wraps sudoers_setlocale().
+ [0eef64f41cdf]
+
+ * src/parse_args.c:
+ Fix indentation of -a flag help line.
+ [a2ed556b6454]
+
+ * include/sudo_compat.h:
+ Fix compilation when HAVE_DECL_SIG2STR_MAX is not defined.
+ [31aa465affaa]
+
+ * doc/Makefile.in:
+ Add lint target to run "mandoc -Tlint" over the manuals.
+ [63ed14d91adc]
+
+2015-05-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_compat.h:
+ HAVE_DECL_SIG2STR_MAX is always defined so use a
+ !HAVE_DECL_SIG2STR_MAX check instead of #ifndef.
+ [65cc03302d39]
+
+2015-05-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/tgetpass.c:
+ Sync tty_present() with sudoers version.
+ [040c05e68627]
+
+ * src/load_plugins.c:
+ sudo_check_plugin() returns bool.
+ [15b2851bfb90]
+
+ * plugins/sudoers/match.c:
+ In usergr_matches() matched should be bool but we have to take care
+ to handle group_plugin_query() returning a value other than 0/1.
+ [c120901f71c7]
+
+ * plugins/sudoers/ldap.c:
+ sudo_ldap_check_non_unix_group() returns bool, not int.
+ [d12e9242454f]
+
+ * plugins/sudoers/logging.c:
+ Convert two debug_return_int to debug_return_bool.
+ [594d0fc8efda]
+
+ * include/sudo_debug.h, lib/util/sudo_debug.c,
+ plugins/sudoers/auth/dce.c, plugins/sudoers/check.c,
+ plugins/sudoers/env.c, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/match.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.c, src/sudo.c:
+ Previously, debug_return_bool was the same as debug_return_int
+ except that it logged true/false for 1/0. However, this appears to
+ trigger a bug in some compilers. To avoid this, debug_return_bool
+ now uses bool, not int. Callers that were passing it an int have
+ been converted to use debug_return_int instead.
+ [ca142b5a9433]
+
+ * src/get_pty.c, src/sudo.h:
+ get_pty() should return bool
+ [2c72c8d3603b]
+
+ * src/sudo.h, src/tgetpass.c:
+ Make tty_present static to tgetpass.c
+ [bb73a2cc8754]
+
+ * config.h.in, configure, configure.ac, include/sudo_compat.h:
+ Add configure check for SIG2STR_MAX, which may be missing on
+ UnixWare.
+ [e9dcac23c639]
+
+ * m4/ax_sys_weak_alias.m4:
+ Need to quote $GCC as it may include arguments. From Tim Rice.
+ [9ed8a3be94bf]
+
+ * MANIFEST:
+ Add missing m4/ax_sys_weak_alias.m4
+ [269a8d5bfb49]
+
+2015-04-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ There's no point in building i386 binaries for Mac OS X 10.7 and
+ higher.
+ [e8876ea36d14]
+
+2015-04-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/fr.mo, plugins/sudoers/po/fr.po, po/ja.mo,
+ po/ja.po:
+ Sync with translationproject.org
+ [414c51286530]
+
+2015-04-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/bsm_audit.c:
+ Only fall back on AUE_DARWIN_sudo if au_preselect() fails.
+ [aea2f3a60b46]
+
+2015-04-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/bsm_audit.c:
+ Work around a problem on Mac OS X 10.10 which defines AUE_sudo but
+ where au_preselect() only accepts AUE_DARWIN_sudo (the old value).
+ [b5d32d6453d1]
+
+2015-04-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/env_hooks.c:
+ Don't use dlsym() to find the libc getenv() since this may allocate
+ memory on some systems (glibc) which leads to a hang if malloc()
+ calls getenv() (jemalloc).
+ [441846664820]
+
+ * src/sudo.c:
+ Defer conversation initialization until right before plugins are
+ initialized.
+ [83db53d4945c]
+
+ * include/sudo_debug.h, src/sudo.c:
+ Split variable declaration out of debug_decl into debug_decl_vars()
+ so we can use it in main() when we know sudo_debug_enter() cannot
+ succeed.
+ [6931948a57f8]
+
+2015-04-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c, plugins/sudoers/testsudoers.c:
+ When creating a passwd struct from a uid that is not in the passwd
+ database, set pw_gid to the user's gid instead of whatever the user
+ specified via the -g flag (or 0 if no -g).
+ [4154970432df]
+
+2015-04-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Add some ldap_err2string() debugging when the LDAP search fails.
+ Adapted from a diff from Steven Soulen.
+ [e08d38481041]
+
+2015-04-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/sr.mo, plugins/sudoers/po/sr.po, po/sr.mo,
+ po/sr.po:
+ Sync with translationproject.org
+ [cbf24072ad07]
+
+2015-04-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS:
+ Add David Michael and Andrey Klyachkin.
+ [e153a9b46e1f]
+
+ * sudo.pp:
+ Sync tmpfiles.d/sudo.conf with init.d/sudo.conf.in
+ [9e3945c1fe6e]
+
+ * include/sudo_util.h:
+ Avoid struct assignment when stashing mtime since AIX at least uses
+ a struct st_timespec that differs from struct timespec. From Andrey
+ Klyachkin.
+ [e267ea5b019e]
+
+2015-04-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Work around a bug in pp that caused a warning when exampledir is a
+ subdir of docdir.
+ [d81db98f215f]
+
+ * plugins/sudoers/solaris_audit.c:
+ Add sys/types.h
+ [e0794f05e95c]
+
+ * lib/util/getopt_long.c, lib/util/mksiglist.c, lib/util/mksigname.c,
+ lib/util/regress/fnmatch/fnm_test.c,
+ lib/util/regress/glob/globtest.c, lib/util/sha2.c,
+ plugins/sudoers/regress/parser/check_base64.c,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/regress/parser/check_hexchar.c:
+ Include sys/types.h instead of unistd.h to get uid_t and gid_t. Add
+ missing include of sys/types.h to a few places.
+ [86eb67f3c41a]
+
+2015-04-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ Remove unintended commit
+ [2eeeb74b9174]
+
+ * init.d/sudo.conf.in:
+ Add tmpfiles.d/sudo.conf template.
+ [ead9bb7b5328]
+
+2015-04-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * .hgignore, INSTALL, MANIFEST, Makefile.in, configure, configure.ac,
+ mkpkg, src/Makefile.in, sudo.pp:
+ Create template tmpfiles.d/sudo.conf for installation instead of
+ creating one via echo commands in the Makefile.
+
+ Add --enable-tmpfiles.d configure option to enable/disable use of
+ tmpfiles.d and override the default directory.
+
+ Use --disable-tmpfiles.d in mkpkg so we no longer need to ignore
+ tmpfiles.d/sudo.conf in sudo.pp.
+ [930983f88927]
+
+2015-04-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, Makefile.in, configure, configure.ac, doc/sudoers.mdoc.in,
+ examples/Makefile.in, mkpkg, sudo.pp:
+ Make exampledir configurable and default to
+ DATAROOTDIR/examples/sudo on BSD systems.
+ [4c1271298712]
+
+2015-04-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Fix setting of pp_rpm_version when there is no patchlevel present.
+ Also tighten up the regexp for pp_rpm_release.
+ [d6a89aafd99d]
+
+2015-04-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/Makefile.in, sudo.pp:
+ Install /usr/lib/tmpfiles.d/sudo.conf on systems with systemd but do
+ not package it. For packages we create /usr/lib/tmpfiles.d/sudo.conf
+ as needed in the postinstall script.
+ [522666bc079f]
+
+2015-03-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.ldap.mdoc.in,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in, doc/visudo.cat,
+ doc/visudo.man.in, doc/visudo.mdoc.in:
+ Fix "mandoc -Tlint" warnings. Sync AUTHORS section in man pages.
+ Regenerate all man pages.
+ [34e4149bb225]
+
+ * lib/util/Makefile.in, plugins/sudoers/Makefile.in, src/Makefile.in:
+ Make libsudo_util depend on libintl instead of requiring users of
+ libsudo_util to link with libintl directly. Bug #690
+ [f2508d1a21ee]
+
+2015-03-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/logging.c:
+ Use saved errno in vlog_warning() before calling
+ sudo_vwarn_nodebug(). Fixes the error message printed if set_perms()
+ fails.
+ [68bd7297137e]
+
+2015-03-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Update for 1.8.13 final.
+ [4c03db3a740f]
+
+2015-03-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/env.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ For sudoedit, run the editor with the user's original environment as
+ per the documentation (and as in sudo 1.7.x). Bug #688
+ [a5081c8f6950]
+
+ * plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po, po/fr.mo,
+ po/fr.po:
+ Sync with translationproject.org
+ [0b820c5ecb0c]
+
+2015-03-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/term.c:
+ Update function names in debug_decl.
+ [b83f153b2f43]
+
+ * lib/util/term.c:
+ Use TCSAFLUSH instead of TCSANOW in sudo_term_copy(). Be consistent
+ with where we put TCSASOFT in the action flags.
+ [6ffeec3aa184]
+
+2015-03-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po, po/da.mo,
+ po/da.po, po/fi.mo, po/fi.po, po/zh_CN.mo, po/zh_CN.po:
+ Sync with translationproject.org
+ [0d20f88c0a83]
+
+2015-03-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/sha2.c:
+ Include unistd.h since sudo_compat.h uses gid_t.
+ [da491d83e5dc]
+
+2015-03-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, configure, configure.ac:
+ Add --disable-weak-symbols option to disable use of weak symbols in
+ libsudo_util.
+ [3edf2bccb4d8]
+
+ * configure:
+ regen
+ [ff1abfcd2b61]
+
+ * m4/ax_sys_weak_alias.m4:
+ When checking for weak aliases, check the gcc attribute format last
+ since some C compilers just ignore unsupported attributes.
+ [e172cbbfa615]
+
+ * sudo.pp:
+ Update copyright year.
+ [67bcd24c6477]
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po, po/cs.mo,
+ po/cs.po, po/de.mo, po/de.po, po/eo.mo, po/eo.po, po/it.mo,
+ po/it.po, po/nb.mo, po/nb.po, po/pl.mo, po/pl.po, po/pt_BR.mo,
+ po/pt_BR.po, po/uk.mo, po/uk.po, po/vi.mo, po/vi.po:
+ Sync with translationproject.org
+ [ceb62f98364c]
+
+ * configure, configure.ac, include/compat/sha2.h:
+ Fix symbol name collision with systems that have their own sha2
+ implementation. This can result in PAM using the wrong sha2
+ implementation on Solaris systems configured to use SHA512 for
+ passwords.
+ [3a25c4896804]
+
+ * src/Makefile.in:
+ Use SSP_LDFLAGS when linking sudo_noexec.la
+ [6187b17fad90]
+
+2015-03-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, config.h.in, configure, configure.ac,
+ include/compat/utime.h, lib/util/Makefile.in, lib/util/utimens.c:
+ Remove compat/utime.h, it was only useful for ancient systems that
+ are no longer capable of compiling sudo.
+ [94e4f02868db]
+
+2015-03-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac, lib/util/Makefile.in:
+ Link libsudo_util with -lrt on systems where clock_gettime is in
+ -lrt.
+ [44a9a0d0af69]
+
+ * NEWS:
+ Update.
+ [811c8d7090c0]
+
+ * lib/util/strlcat.c, lib/util/strlcpy.c:
+ Update OpenBSD CVS Ids
+ [933788497ee4]
+
+ * lib/util/strlcat.c:
+ Make comment match code.
+ [b1b68810929d]
+
+ * lib/util/utimens.c:
+ Fix compilation error on systems without futimes().
+ [4d55a58ea12e]
+
+ * MANIFEST, config.h.in, configure, configure.ac,
+ include/sudo_compat.h, include/sudo_util.h, lib/util/Makefile.in,
+ lib/util/gettime.c, lib/util/util.exp.in, lib/util/utimens.c,
+ lib/util/utimes.c, mkdep.pl, plugins/sudoers/Makefile.in,
+ plugins/sudoers/boottime.c, plugins/sudoers/gettime.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/timestamp.c,
+ plugins/sudoers/visudo.c, src/Makefile.in, src/sesh.c,
+ src/sudo_edit.c:
+ Use futimens() and utimensat() instead of futimes() and utimes().
+ [8400f91466d8]
+
+ * plugins/sudoers/visudo.c:
+ Fix compiler warning on systems where mode_t is not unsigned int,
+ such as 32-bit Solaris.
+ [1eeeea1c203d]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Fix logic for verifypw/listpw all in sudoers LDAP and sssd.
+ [5bc60a34a477]
+
+ * src/tgetpass.c:
+ Fix cut & pasto that prevented the SIGPIPE handler from being
+ restored before returning from tgetpass(). From mancha
+ [230b0a86876e]
+
+2015-02-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sesh.c, src/sudo_edit.c:
+ Our utimes() emulation support futime() too.
+ [439851535285]
+
+2015-02-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [40aa9164563f]
+
+ * plugins/sudoers/testsudoers.c:
+ Define YYDEBUG to 0 if not already defined so we can protect use of
+ sudoersdebug with "#if YYDEBUG" like the generated parser does. From
+ David Michael.
+ [394e1c237aac]
+
+2015-02-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document that Aliases may not be redefined and that "sudo -f
+ /etc/sudo.d/foo" will not catch the redefinition.
+ [3bff3b5f7eb1]
+
+ * sudo.pp:
+ Only create /usr/lib/tmpfiles.d/sudo.conf if
+ /usr/lib/tmpfiles.d/systemd.conf also exists. Some other package may
+ have created /usr/lib/tmpfiles.d even though it is not used.
+ [cf013d95b7d7]
+
+ * plugins/sudoers/Makefile.in:
+ regen
+ [4dde632c35cd]
+
+ * sudo.pp:
+ Clear the ts dir instead of just making sure it exists.
+ [c49b6e3e2360]
+
+ * configure, configure.ac:
+ Only substiture init.d scripts that we are going to use.
+ [301f16bd04c5]
+
+2015-02-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in, sudo.pp:
+ Create /usr/lib/tmpfiles.d/sudo.conf when systemd is used.
+ [532dc61e7bb7]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/visudo.c, src/sudo_edit.c,
+ src/utmp.c:
+ Check the return value of gettimeofday(), even though it should
+ never fail.
+ [747715d8a11c]
+
+2015-02-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, configure, configure.ac, include/sudo_compat.h,
+ lib/util/Makefile.in, lib/util/clock_gettime.c, mkdep.pl,
+ plugins/sudoers/Makefile.in, plugins/sudoers/gettime.c,
+ plugins/sudoers/po/sudoers.pot, plugins/sudoers/sudoers.h,
+ plugins/sudoers/timestamp.c:
+ We cannot (easily) use clock_gettime(CLOCK_MONOTONIC) directly as it
+ may be present but not implemented. Add sudo_gettime_real() and
+ sudo_gettime_mono() functions to get the real and monotonic times
+ respectively. Now sudo_gettime_mono() checks the value of
+ sysconf(_SC_MONOTONIC_CLOCK) before calling
+ clock_gettime(CLOCK_MONOTONIC) and falls back on sudo_gettime_real()
+ as needed. The Mach version of sudo_gettime_mono() uses
+ mach_absolute_time().
+
+ This should fix problems with timestamp files on systems where the
+ CLOCK_MONOTONIC is defined but not actually implemented.
+ [cd04a21af4c5]
+
+ * include/sudo_compat.h, plugins/sudoers/timestamp.c:
+ Check clock_gettime() return value and warn if it fails. Currently,
+ the timestamp will be ignored if clock_gettime() fails.
+ [3658154638da]
+
+2015-02-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/sudo_debug.c:
+ Plug memory leak when debug file cannot be opened. Use %zu printf
+ format now that our snprintf support it.
+ [a168a002cd19]
+
+ * plugins/sudoers/auth/pam.c:
+ Pam conversation function changes: o use PAM_BUF_ERR as the return
+ value when calloc() fails. o sanity check the value of num_msg o
+ remove the workaround for old Apple PAM o PAM_AUTH_ERR is not a
+ valid PAM conversation function return value
+
+ If getpass_error is set after a call to pam_verify (usually because
+ the user pressed ^C), return AUTH_INTR immediately instead of
+ checking the pam_verify return value.
+ [8d378f40fe1f]
+
+ * INSTALL, NEWS, configure, configure.ac,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/auth/sudo_auth.h:
+ On AIX use the value of auth_type in /etc/security/login.cfg to
+ determine whether to use LAM or PAM unless the user specified the
+ --with-pam or --with-aixauth configure flags.
+ [cb314c1ed5f8]
+
+ * lib/util/parseln.c:
+ Fix cast.
+ [4f56047e2bc4]
+
+2015-02-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.ac, lib/util/snprintf.c:
+ Update snprintf.c from OpenBSD. The floating point and wide
+ character code has been retained but is not compiled by default.
+ [6801a77398fc]
+
+2015-02-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/sudoers/test1.in,
+ plugins/sudoers/regress/sudoers/test1.out.ok,
+ plugins/sudoers/regress/sudoers/test1.toke.ok:
+ Update the regression test that check that all tags are parsed.
+ [d0f9af2f9d45]
+
+ * MANIFEST, configure, configure.ac, lib/util/Makefile.in,
+ lib/util/mktemp.c, lib/util/regress/mktemp/mktemp_test.c, mkdep.pl:
+ Add regress for mkdtemp and mkstemps from OpenBSD
+ [18714ae9bffd]
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [b77490dd9b33]
+
+ * plugins/sudoers/po/nl.mo, plugins/sudoers/po/nl.po, po/tr.mo,
+ po/tr.po:
+ Sync with translationproject.org
+ [b2946065653d]
+
+ * config.h.in, configure.ac:
+ Correct SECURE_PATH comment.
+ [3fd6132d5dba]
+
+ * NEWS, configure, configure.ac:
+ Sudo 1.8.13
+ [32c1183b0666]
+
+2015-02-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, config.h.in, configure, configure.ac,
+ include/sudo_compat.h, include/sudo_util.h, lib/util/Makefile.in,
+ lib/util/gethostname.c, lib/util/util.exp.in,
+ plugins/sudoers/match.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c, src/sudo.c:
+ Avoid using HOST_NAME_MAX directly and use
+ sysconf(_SC_HOST_NAME_MAX) instead.
+ [97036b819d58]
+
+ * plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/secureware.c:
+ Historically, crypt() returned the empty string on error, which
+ ensured that crypt("", "") would return "", which supported matcing
+ empty encrypted passwords with no additional code. Some modern
+ versions of crypt() (such as glibc) return NULL on error so we need
+ an explicit test to match an empty plaintext password and an empty
+ encrypted password.
+ [b88eb9da5e57]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Sort tags lexically in the sudoers manual
+ [66716c0b7a13]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.h,
+ plugins/sudoers/gram.y, plugins/sudoers/ldap.c,
+ plugins/sudoers/parse.c, plugins/sudoers/parse.h,
+ plugins/sudoers/regress/sudoers/test1.out.ok,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudoers_version.h,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/visudo_json.c:
+ Add support for MAIL and NOMAIL command tags to toggle mail sending
+ behavior on a per-command (or Cmnd_Alias) basis.
+ [04f30a064c25]
+
+2015-02-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/logging.c:
+ Add mail_all_cmnds to always mail when a user runs a command (or
+ tries to) including sudoedit. The mail_always flag goes back to its
+ old semantic of always mailing when sudo is run.
+ [edc904502061]
+
+2015-02-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/getline.c, plugins/group_file/getgrent.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/tsgetgrpw.c:
+ All modern systems should have LINE_MAX.
+ [117322b6d86c]
+
+ * config.h.in, configure, configure.ac, include/sudo_compat.h,
+ lib/util/closefrom.c, lib/util/setgroups.c,
+ plugins/sudoers/pwutil_impl.c, src/sudo.c:
+ Almost no systems actually define OPEN_MAX since it is dynamic on
+ modern OSes. If sysconf(_SC_OPEN_MAX) ever fails, fall back on
+ _POSIX_OPEN_MAX instead. We can assume modern systems have
+ sysconf(). Also remove checks for strrchr() and strtoll() for which
+ the HAVE_* defines are no longer used.
+ [c3058a6cca86]
+
+ * Makefile.in, sudo.pp:
+ Don't need to pass exampledir to polypkg now that it is just under
+ docdir.
+ [9f24f0184a78]
+
+2015-02-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Fix packaging of the example dir.
+ [4c7cbc3fc190]
+
+ * lib/util/mktemp.c:
+ Fix mkstemps() extension handling. Sudoedit will now preserve the
+ extension properly when the system libc lacks mkstemps().
+ [b86f54331972]
+
+2015-02-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, aclocal.m4, config.h.in, configure, configure.ac,
+ lib/util/Makefile.in, lib/util/locale_weak.c,
+ m4/ax_sys_weak_alias.m4, mkdep.pl, src/Makefile.in,
+ src/locale_stub.c:
+ Use weak symbols for sudo_warn_gettext() and sudo_warn_strerror() so
+ distros using "-Wl,--no-undefined" in LDFLAGS don't run into
+ problems.
+ [708418615aae]
+
+ * lib/util/mksiglist.c, lib/util/mksigname.c:
+ Include unistd.h in siglist.c and signame.c to get gid_t which is
+ used by sudo_compat.h. Bug #686
+ [0ab6450a96ec]
+
+2015-02-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Minor change in description of TZ path handling.
+ [579b02f0dbe0]
+
+ * Makefile.in, examples/Makefile.in:
+ Move example dir under the doc dir to conform to Debian guidelines.
+ Bug #682.
+ [494d9a0484b6]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document that a leading ':' is skipped when checking TZ for a fully-
+ qualified path name.
+ [91859f613b88]
+
+2015-02-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Typo.
+ [b9257ea66116]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Fix typos.
+ [ac1467f71ac0]
+
+ * plugins/sample/sample_plugin.c:
+ Fix compilation on systems w/o __dso_public
+ [b773ef9127fa]
+
+2015-02-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, plugins/sudoers/po/ru.mo, plugins/sudoers/po/ru.po:
+ Russian translation for sudoers from translationproject.org.
+ [8a7fc2e00072]
+
+2015-02-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, doc/CONTRIBUTORS, plugins/sudoers/po/ru.mo,
+ plugins/sudoers/po/ru.po:
+ Russian translation for sudoers from translationproject.org.
+ [1d5869e4d4af]
+
+ * config.h.in, configure, configure.ac, include/sudo_compat.h:
+ Add check for getresuid() declaration, which may be missing on HP-
+ UX. When checking for getdomainname() prototype, look in netdb.h
+ too.
+ [0ba583590b17]
+
+ * INSTALL, NEWS, configure, configure.ac, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, m4/sudo.m4, pathnames.h.in,
+ plugins/sudoers/env.c:
+ Sanity check the TZ environment variable by special casing it in
+ env_check. The --with-tzdir configure option can be used to specify
+ the zoneinfo directory if configure doesn't find it.
+ [650ac6938b59]
+
+ * NEWS:
+ Mention crash fixes.
+ [f759c993e172]
+
+ * src/parse_args.c:
+ Bail with usage() early if argc <= 0.
+ [aaba56c9a797]
+
+2015-02-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/pwutil.c:
+ Remove extraneous casts of node->data (which is void *).
+ [950749570a00]
+
+ * doc/CONTRIBUTORS:
+ Add Stephane Chazelas
+ [a6c7becabee7]
+
+ * plugins/sudoers/pwutil.c:
+ Fix a potential crash when getpwnam() of the running user fails and
+ we don't replace the negative cached entry with a faked up one. From
+ Stephane Chazelas
+ [9088f041bbad]
+
+ * src/parse_args.c, src/sudo.c:
+ Don't assume argv[0] is set without first checking argc.
+ [aabdc9d0ba26]
+
+ * plugins/sudoers/set_perms.c:
+ Handle sudo_get_grlist() returning NULL which can happen if
+ getgrouplist() fails even after allocating the appropriate amount of
+ memory. From Stephane Chazelas
+ [25747a0ead7c]
+
+ * lib/util/progname.c:
+ Call setprogname("sudo") if getprogname() returns NULL or the empty
+ string.
+ [45438f7227b1]
+
+ * config.h.in, configure, configure.ac:
+ Remove configure checks for strrchr() and strtoll() for which the
+ HAVE_* defines are no longer used.
+ [f04216435aba]
+
+ * config.h.in, configure, configure.ac, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in,
+ plugins/sudoers/sudoreplay.c:
+ Require POSIX regular expression support for sudoreplay.
+ [1486747cd470]
+
+ * plugins/sudoers/policy.c:
+ The plugin no longer needs to call initprogname() now that it links
+ with the same libsudo_util as sudo.
+ [78b65a352ac5]
+
+ * config.h.in, configure, configure.ac, include/sudo_compat.h:
+ Check whether getdomainname(), innetgr(), setresuid() and
+ setresgid() are declared and add prototypes in sudo_compat.h as
+ needed.
+ [03aa144afce4]
+
+2015-02-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Add /usr/local/share/examples/ directory to parentdirs so it is
+ explicitly added to the package.
+ [ef1aa52b0aad]
+
+2015-02-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/logging.c:
+ Don't send mail about pseudo-command failure unless it is an
+ authentication failure.
+ [deddcfc1f2ab]
+
+2015-02-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/da.mo, po/da.mo:
+ Sync with translationproject.org
+ [943986acd31c]
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/nl.mo, plugins/sudoers/po/nl.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po, po/nl.mo,
+ po/nl.po:
+ Sync with translationproject.org
+ [4977ac967bdd]
+
+2015-02-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/getdate.c, plugins/sudoers/gram.c:
+ Regen with yacc skeleton that the clang analyzer doesn't complain
+ about.
+ [e15991fd4ab1]
+
+ * configure, configure.ac, lib/util/alloc.c, lib/util/glob.c,
+ plugins/sudoers/env.c, plugins/sudoers/getdate.c,
+ plugins/sudoers/getdate.y, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y:
+ Use stdint.h to get SIZE_MAX as inttypes.h on some pre-C99 HP-UX
+ systems doesn't include stdint.h itself.
+ [9fbd35811743]
+
+ * configure, configure.ac:
+ SIZE_MAX may be in limits.h on pre-C99 compilers.
+ [d3b554f7e0e5]
+
+ * config.h.in, configure, configure.ac, lib/util/aix.c:
+ Add missing prototypes for usrinfo() and setauthdb() for AIX.
+ [aa4b205296cf]
+
+ * config.h.in, configure, configure.ac, plugins/sudoers/match.c:
+ Solaris uses sysinfo(SI_SRPC_DOMAIN) instead of getdomainname() to
+ get the host's NIS domain.
+ [9234c62a1469]
+
+2015-02-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Remove AC_PROG_GCC_TRADITIONAL and add AC_PROG_CC_STDC since we need
+ C99.
+ [005775f5662b]
+
+ * plugins/sudoers/match.c:
+ Actually use the check for prior initialization in
+ sudo_getdomainname().
+ [06368385ad0d]
+
+ * configure, configure.ac:
+ We need to add OSDEFS to CFLAGS to expose LLONG_MAX et al on glibc
+ when not explicitly asking for c99.
+ [ae9435631600]
+
+ * configure, configure.ac:
+ Fix check for SIZE_MAX, which should be in stdint.h not limits.h.
+ [47bf0ab7dfca]
+
+ * lib/util/glob.c:
+ Need to include inttypes.h for SIZE_MAX
+ [a11f42f40294]
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [d35b24f95ef8]
+
+2015-02-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_debug.h, lib/util/aix.c, lib/util/event.c,
+ lib/util/event_poll.c, lib/util/event_select.c, lib/util/gidlist.c,
+ lib/util/key_val.c, lib/util/lbuf.c, lib/util/locking.c,
+ lib/util/parseln.c, lib/util/secure_path.c, lib/util/setgroups.c,
+ lib/util/strtobool.c, lib/util/strtoid.c, lib/util/strtomode.c,
+ lib/util/sudo_conf.c, lib/util/sudo_debug.c, lib/util/term.c,
+ lib/util/ttysize.c, lib/util/util.exp.in, plugins/sudoers/alias.c,
+ plugins/sudoers/audit.c, plugins/sudoers/auth/afs.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/dce.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/base64.c, plugins/sudoers/boottime.c,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/check.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/env.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/getspwuid.c,
+ plugins/sudoers/goodpath.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/hexchar.c, plugins/sudoers/interfaces.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/linux_audit.c,
+ plugins/sudoers/logging.c, plugins/sudoers/logwrap.c,
+ plugins/sudoers/match.c, plugins/sudoers/match_addr.c,
+ plugins/sudoers/parse.c, plugins/sudoers/policy.c,
+ plugins/sudoers/prompt.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/pwutil_impl.c, plugins/sudoers/redblack.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoers_debug.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/timestamp.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c,
+ plugins/sudoers/visudo.c, plugins/sudoers/visudo_json.c, src/exec.c,
+ src/exec_common.c, src/exec_pty.c, src/get_pty.c, src/hooks.c,
+ src/load_plugins.c, src/net_ifs.c, src/parse_args.c,
+ src/preserve_fds.c, src/selinux.c, src/sesh.c, src/signal.c,
+ src/solaris.c, src/sudo.c, src/sudo_edit.c, src/tgetpass.c,
+ src/ttyname.c, src/utmp.c:
+ Go back to a 2 args debug_decl and just use the "default" instance,
+ now renamed "active".
+ [7130b7478355]
+
+2015-01-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/LICENSE:
+ Update copyright year.
+ [e1dad7b195e4]
+
+2015-01-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, plugins/sudoers/ldap.c,
+ plugins/sudoers/match.c, plugins/sudoers/parse.h:
+ When querying LDAP netgroups, use the NIS domain if it is sent but
+ also match nisNetgroupTriple entries that have no domain.
+ [5a0fa3ac26f7]
+
+ * plugins/sudoers/sudoreplay.c:
+ Avoid setting the tty to non-blocking mode so "sudoreplay | cat"
+ (for example) works as expected. We only read a single byte from the
+ keyboard and only when interactive anyway so this should be fine.
+ [9615a932545b]
+
+ * lib/zlib/Makefile.in, plugins/sudoers/Makefile.in:
+ regen
+ [f19c6e000850]
+
+ * plugins/sudoers/sudoreplay.c:
+ Avoid a cppcheck warning about undefined behavior (using the address
+ of a stack buffer - 1) and fix a memory leak of the iov when doing
+ nl->crnl conversion.
+ [e26f9008c2e4]
+
+ * doc/CONTRIBUTORS:
+ Add Steven Soulen
+ [17a47303d5fe]
+
+ * plugins/sudoers/sudoreplay.c:
+ Fix handling of partial writes from writev() which can occur with
+ large output buffers.
+ [1065dbeaa13d]
+
+2015-01-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, plugins/sudoers/ldap.c:
+ Add support for querying netgroups directly via LDAP since there is
+ no other way to look up all the netgroups for a user (unlike regular
+ groups). This introduces netgroup_base and netgroup_search_filter
+ options to ldap.conf. Based on a diff from Steven Soulen.
+ [7e3d55983e71]
+
+2015-01-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ Sort ldap.conf options.
+ [264608124698]
+
+2015-01-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Add macros to ease the checking of strlcpy, strlcat and
+ sudo_ldap_value_cat return values.
+ [e9122413d4fa]
+
+2015-01-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/logging.c, plugins/sudoers/parse.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Rename VALIDATE_OK -> VALIDATE_SUCCESS Rename VALIDATE_NOT_OK ->
+ VALIDATE_FAILURE
+ [4379cac9f75d]
+
+ * plugins/sudoers/logging.c, plugins/sudoers/sudoers.h:
+ Remove now-unused VALIDATE_ERROR define.
+ [569d4936b761]
+
+ * plugins/sudoers/logging.c:
+ should_mail() now returns bool.
+ [0316d1fb08c3]
+
+ * lib/util/sudo_debug.c:
+ If sudo_debug_register() fails return
+ SUDO_DEBUG_INSTANCE_INITIALIZER, not -1. Otherwise we could end up
+ setting the instance to -1 which is invalid.
+ [032bb1db6db5]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Fix typo.
+ [014be972780c]
+
+ * doc/Makefile.in:
+ Use "mandoc -Tascii" to generate .cat pages to avoid locale-specific
+ characters.
+ [0ec42d8924fc]
+
+2015-01-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, m4/sudo.m4:
+ Use AC_PATH_PROG to find programs instead of checking the path
+ manually.
+ [2b5d9893a7a7]
+
+2015-01-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/strlcat.c, lib/util/strlcpy.c:
+ Sync with OpenBSD version
+ [22c073c42a9e]
+
+2015-01-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Use AC_CHECK_HEADERS_ONCE and AC_CHECK_FUNCS_ONCE where possible and
+ quote the first args in AC_CHECK_FUNCS calls.
+ [84aa40ab410a]
+
+ * config.h.in, configure, configure.ac, include/sudo_compat.h:
+ Avoid inadvertantly defining things like PATH_MAX simply because the
+ source file doesn't include limits.h.
+ [d2e7c4093f55]
+
+2015-01-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, ltmain.sh, m4/libtool.m4, m4/ltoptions.m4,
+ m4/ltversion.m4:
+ Update to libtool 2.4.4 + HP-UX patches
+ [859b7378bc37]
+
+ * src/ttyname.c:
+ Document why we need sys/param.h.
+ [f21a4d7122f0]
+
+ * configure, m4/sudo.m4:
+ Don't need sys/param.h.
+ [6aa24ecfc9d4]
+
+ * lib/util/closefrom.c:
+ Don't appear to need sys/param.h for pstat_getproc() on HP-UX even
+ though the man page lists it.
+ [47d75f3db288]
+
+ * lib/util/inet_ntop.c, lib/util/inet_pton.c:
+ Should not need sys/param.h here.
+ [5c83cebcd75f]
+
+2014-12-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/match_addr.c:
+ Use standard CIDR -> netmask conversion and disallow 0-bit CIDRs.
+ [d30313d726eb]
+
+2014-12-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README.LDAP:
+ Update link to gq LDAP editor, now on sourceforge.
+ [706dadea1abb]
+
+2014-12-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/compat/glob.h, lib/util/glob.c:
+ Add support for GLOB_LIMIT from OpenBSD (not currently used) and
+ also a limit on the max recursion depth for glob().
+ [6f9e26b88612]
+
+ * lib/util/glob.c:
+ Quiet compiler sign compare warning.
+ [c4f35c02122c]
+
+2014-12-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ fnmatch fix
+ [07542b07ac67]
+
+ * lib/util/fnmatch.c:
+ Remove artificial limit on length of pattern and string. It is
+ possible to use fnmatch() on things other than paths (such as
+ arguments) so a limit of PATH_MAX does not make sense. Fixes a bug
+ where rules would fail to match if the length of the arguments were
+ larger than PATH_MAX (usually 1024).
+ [942770c20422]
+
+2014-12-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.ldap.mdoc.in,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in, doc/visudo.cat,
+ doc/visudo.man.in, doc/visudo.mdoc.in:
+ Remove the extra /sudo in sudo.ws urls
+ [0b804e3a1008]
+
+2014-11-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.ldap.mdoc.in,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in, doc/visudo.cat,
+ doc/visudo.man.in, doc/visudo.mdoc.in:
+ Reference bugzilla.sudo.ws
+ [7dc11bbe6f13]
+
+2014-11-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ sync
+ [da17d5a611ce]
+
+2014-11-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y:
+ Require that a digest be specified with a real command, not an alias
+ or pseudo-command. Found via a crash by afl.
+ [55f6166cab63]
+
+ * NEWS:
+ sync
+ [4b31247735c4]
+
+ * MANIFEST, doc/CONTRIBUTORS, plugins/sudoers/po/fr.mo,
+ plugins/sudoers/po/fr.po:
+ French translation for sudoers from translationproject.org.
+ [5c592350c4b0]
+
+2014-11-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c, src/exec_pty.c, src/tgetpass.c:
+ Defer registration of the SIGCHLD handler until just before we exec
+ the command. Fixes a problem where pam_gnome_keyring installs its
+ own SIGCHLD handler and may not restore the original one. As a
+ result, we now have to explicitly wait for the askpass helper to
+ finish. Bug #657
+ [f499500fef71]
+
+2014-11-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ Mention sssd support in the sudoers.ldap manual and cross-reference
+ sssd-sudo(5).
+ [32f84fbf210c]
+
+2014-11-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS:
+ Reorder an entry.
+ [5d15735294f1]
+
+2014-11-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, lib/util/Makefile.in, plugins/group_file/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in, src/Makefile.in:
+ Prevent cppcheck from getting confused by our compat definition of
+ the va_copy macro for pre-C99.
+ [61d94525be2e]
+
+2014-11-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog_path.c:
+ Fix potential NULL pointer deref found by cppcheck.
+ [668967e031e0]
+
+ * plugins/sudoers/alias.c:
+ Quiet a cppcheck false positive.
+ [35a16ae4660c]
+
+ * lib/util/sudo_debug.c:
+ If there are multiple outputs, ap will be re-used so make a copy and
+ operate on it instead.
+ [f4f19df43c93]
+
+ * src/hooks.c:
+ Fix typo in hook return value check.
+ [b12839dc6e78]
+
+ * NEWS:
+ Mention visudo use of sudoers plugin args to set default sudoers
+ file name and owner/mode.
+ [7f2733b53431]
+
+ * NEWS:
+ Mention fix for bug #678
+ [7f7a6d8b985b]
+
+2014-11-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po, po/cs.mo,
+ po/cs.po, po/da.mo, po/da.po, po/de.mo, po/de.po, po/eo.mo,
+ po/eo.po, po/fi.mo, po/fi.po, po/it.mo, po/it.po, po/nb.mo,
+ po/nb.po, po/pl.mo, po/pl.po, po/pt_BR.mo, po/pt_BR.po, po/ru.mo,
+ po/ru.po, po/uk.mo, po/uk.po, po/vi.mo, po/vi.po, po/zh_CN.mo,
+ po/zh_CN.po:
+ Sync with translationproject.org
+ [e51055fdffe1]
+
+2014-11-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ In set_fqdn() we neeed to set user_runhost/user_srunhost at the same
+ time we set user_host/user_shost since that is what
+ hostlist_matches() uses. Bug #678
+ [4f75b01d4884]
+
+2014-11-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/hooks.c:
+ Do not call sudo_warnx() on invalid value from the env hook
+ functions as the printf() family may call getenv() for locale
+ reasons.
+ [547fc25acb7c]
+
+ * doc/sudo.conf.mdoc.in, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.man.in, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in, doc/sudoreplay.mdoc.in, doc/visudo.cat,
+ doc/visudo.man.in, doc/visudo.mdoc.in:
+ No need to keep specifying ".Nm foo" since the Nm macro remembers
+ the argument it was first called with and uses it if none is
+ specified. Also fix a few minor formatting errors and regen bulleted
+ lists in the .man.in files.
+ [d2669e94add4]
+
+ * doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in:
+ Add sudo.conf to SEE ALSO and rename section on sudo.conf
+ [d4cc8ad2c2b4]
+
+ * doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in:
+ Mention sudo.conf use for debugging
+ [9393fb061bcd]
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo_plugin.cat,
+ doc/sudoers.cat, doc/sudoers.ldap.cat, doc/sudoers.man.in,
+ doc/sudoreplay.cat:
+ regen
+ [1d34d21b2136]
+
+ * doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in:
+ Document sudo.conf usage now that visudo will parse the sudoers
+ arguments.
+ [78a413c019a9]
+
+2014-11-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo.c:
+ Use sudoers.so args from sudo.conf to set sudoers_file, sudoers_uid,
+ sudoers_gid, and sudoers_mode in visudo.
+ [1c7408b5ff7e]
+
+ * plugins/sudoers/visudo.c:
+ Use sudoers_file, sudoers_uid, sudoers_gid, and sudoers_mode symbols
+ from toke.l instead of the upper case defines.
+ [21ba15518c7d]
+
+ * lib/util/Makefile.in, lib/zlib/Makefile.in,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/system_group/Makefile.in:
+ Use SSP_LDFLAGS when creating shared objects.
+ [2428de97d2c2]
+
+ * lib/util/Makefile.in:
+ We only build .lo (not .o) files for libsudo_util
+ [2c1e0475cddc]
+
+2014-11-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ sync
+ [aab14a9942e0]
+
+2014-11-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c, src/exec_pty.c:
+ Make sure that SIGCHLD is not treated as a user-generated signal in
+ which case it could be ignored. Bug #676
+ [a4caaaaa47a8]
+
+2014-10-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, ltmain.sh, m4/libtool.m4, m4/ltoptions.m4, m4/ltsugar.m4,
+ m4/ltversion.m4, m4/lt~obsolete.m4:
+ Update to libtool 2.4.3 + HP-UX patches
+ [9ddfd96f3bea]
+
+2014-10-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.ac, lib/util/mktemp.c:
+ Use arc4random() for mkstemp/mkdtemp if available. If not, try to
+ seed from /dev/urandom before falling back to the gettimeofday seed.
+ [7a7096ab82c9]
+
+2014-10-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac, include/sudo_compat.h, lib/util/mktemp.c:
+ If a system lacks mkdtemp() or mkstemps(), use our own mkdtemp() and
+ mkstemps(). Previously we only exposed the missing one but since the
+ guts are the same we might as well use them.
+ [12d4ac64462f]
+
+2014-10-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/sudo_debug.c:
+ Use a static buffer for sudo_debug_execve2() if possible.
+ [abf1fd5891ab]
+
+2014-10-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/env_hooks.c:
+ Mark the putenv(), setenv() and unsetenv() symbols as global, not
+ hidden. Fixes a mismatch where a plugin (or its loaded dso) would
+ call setenv() to set a variables but be unable to find it later with
+ getenv().
+ [96127ac4bbb3]
+
+2014-10-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Fix install-nls target from builddir.
+ [da63bc37f6c5]
+
+ * Makefile.in:
+ Fix dependency on sudo.pp, it needs to relative to srcdir.
+ [c76088da98e8]
+
+ * src/sesh.c:
+ Adapt to new debug subsystem registration.
+ [8e13b349b44b]
+
+2014-10-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/zlib/Makefile.in, lib/zlib/zlib.exp:
+ Add missing zlib.exp file and common LT_LDFLAGS Makefile.in.
+ [0bc0092d3e03]
+
+ * lib/util/sudo_conf.c:
+ Fix path settings broken in rev 9731.
+ [2b33916eb287]
+
+ * MANIFEST, lib/util/regress/sudo_conf/test4.err.ok:
+ Adjust regress test now that boolean settings display an error for
+ invalid input.
+ [73a7365f492e]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoers_debug.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ Add sudoers_debug_deregister() and use it instead of calling
+ sudo_debug_deregister() directly.
+ [819b0e08196e]
+
+ * configure, configure.ac, lib/util/Makefile.in, lib/zlib/Makefile.in,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/system_group/Makefile.in:
+ Use AC_PROG_AWK
+ [945cf6deb18d]
+
+ * NEWS:
+ Mention shared zlib.
+ [094bdada1106]
+
+ * MANIFEST:
+ Add lib/zlib/zlib.exp
+ [7b5011e3eea9]
+
+ * INSTALL, configure, configure.ac, lib/zlib/Makefile.in,
+ lib/zlib/zconf.h.in:
+ Add support for installing a shared zlib
+ [6875ab6ca44f]
+
+ * lib/util/Makefile.in:
+ fix comment typo
+ [35c3dda27eec]
+
+ * configure, configure.ac, lib/zlib/Makefile.in:
+ Newer zlib uses HAVE_HIDDEN to turn on symbol hiding so we don't
+ need to disable it with NO_VIS.
+ [b3eee86f015f]
+
+ * po/sudo.pot:
+ regen
+ [687bc1ea88ac]
+
+ * configure.ac, include/sudo_debug.h, lib/util/sudo_debug.c,
+ lib/util/util.exp.in:
+ Version the symbols for sudo_debug.c now that the API is stable.
+ [873850a062a8]
+
+2014-10-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/sudo_conf.c:
+ Go back to parsing sudo.conf in place for settings and paths and
+ improve debugging info for unsupported entries and parse errors.
+ [264e1f7d6551]
+
+ * include/sudo_conf.h, lib/util/regress/sudo_conf/conf_test.c,
+ lib/util/sudo_conf.c, lib/util/util.exp.in,
+ plugins/sudoers/sudoers_debug.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c,
+ src/load_plugins.c, src/sudo.c, src/sudo_plugin_int.h:
+ Add a flag argument to sudo_conf_read() so we can decide which bits
+ get parsed. This lets us parse Debug statements first and init the
+ debug subsystem early.
+ [56dbf1e671de]
+
+2014-10-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/zlib/gzguts.h:
+ Include stdio.h after zlib.h, not before. We need the large file
+ defines to come first.
+ [b42b53d10252]
+
+ * doc/LICENSE, lib/zlib/compress.c, lib/zlib/crc32.c,
+ lib/zlib/crc32.h, lib/zlib/deflate.c, lib/zlib/deflate.h,
+ lib/zlib/gzguts.h, lib/zlib/gzlib.c, lib/zlib/gzread.c,
+ lib/zlib/gzwrite.c, lib/zlib/infback.c, lib/zlib/inffast.c,
+ lib/zlib/inflate.c, lib/zlib/inftrees.c, lib/zlib/trees.c,
+ lib/zlib/uncompr.c, lib/zlib/zconf.h.in, lib/zlib/zlib.h,
+ lib/zlib/zutil.c, lib/zlib/zutil.h:
+ Update zlib to version 1.2.8
+ [f95280e0448d]
+
+ * configure, configure.ac:
+ Don't add -Wold-style-definition to CFLAGS as it causes problems
+ with 3rd party libraries such as zlib.
+ [1d7613d1c177]
+
+ * src/load_plugins.c:
+ Free up plugin info structs after converting to plugin containers.
+ [1168e873d778]
+
+ * INSTALL, MANIFEST, Makefile.in, configure, configure.ac,
+ doc/Makefile.in, doc/TROUBLESHOOTING, doc/UPGRADE, doc/sample.pam,
+ doc/sample.sudo.conf, doc/sample.sudoers, doc/sample.syslog.conf,
+ examples/Makefile.in, examples/pam.conf, examples/sudo.conf,
+ examples/sudoers, examples/syslog.conf, sudo.pp:
+ Move sample.* files to a sudo examples dir
+ [b53e3df56c66]
+
+ * sudo.pp:
+ Fix a packaging problem with the sudoedit man page link on Debian.
+ [8ad77a37048e]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/policy.c:
+ Initialize the debug subsystem in sudoers early. Currently this
+ means iterating over the settings list twice.
+ [93b12ea08405]
+
+ * lib/util/sudo_debug.c:
+ No need to convert sudoedit -> sudo in sudo_debug_get_instance() as
+ we store the actual program name and only do the sudoedit -> sudo
+ conversion when reading the sudo.conf file. Fixes debugging when
+ invoked as sudoedit.
+ [535c01d83b14]
+
+ * lib/util/sudo_conf.c, lib/util/sudo_debug.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/policy.c, src/exec_pty.c,
+ src/load_plugins.c, src/sudo.c, src/sudo_plugin_int.h:
+ In the plugin registers with the debug framework at open time, the
+ sudo front-end will now set the default debug instance appropriately
+ before calling into the plugin. This means the plugin no longer
+ needs to do the sudo_debug_set_default_instance() dance.
+ [10dd45a7884f]
+
+ * Makefile.in:
+ Remove duplicate -U__NBBY in CPPCHECK_OPTS
+ [ad518cb36279]
+
+2014-10-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ Older shells don't support unset.
+ [8762e40871ab]
+
+ * configure, configure.ac, include/sudo_compat.h,
+ lib/util/inet_ntop.c, src/net_ifs.c:
+ Fix inet_ntop() replacement on older systems without it. We only
+ expose the prototype for net_ifs.c due to the use of socklen_t.
+ [18b95ca378ab]
+
+ * lib/util/sudo_debug.c:
+ Dynamically allocate debug_fds bitmap and realloc as needed.
+ [e858199414f6]
+
+ * Makefile.in, include/sudo_debug.h, lib/util/Makefile.in,
+ lib/util/sudo_debug.c, plugins/group_file/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/sudoers/sudoers_debug.c, plugins/sudoers/sudoers_debug.h,
+ plugins/system_group/Makefile.in, src/Makefile.in, src/exec.c:
+ Use generic bitmap macros instead of select-style fd_set.
+ [c382edc413be]
+
+ * lib/util/sudo_debug.c:
+ Replace sudo_debug_num_instances with sudo_debug_max_instance
+ [12625fd174a4]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/policy.c:
+ Don't call into the debug subsystem after we've deregistered the
+ plugin's instance.
+ [fca7279d2f40]
+
+ * lib/util/sudo_debug.c:
+ Only fill in subsystem_ids[] for the instance if the caller passed
+ in an array for it. If the caller only wants the default subsystems
+ we don't actually need ids[].
+ [07939da6d3a5]
+
+ * lib/util/Makefile.in:
+ Link with -ldl if needed when built with --disable-shared-libutil/
+ [542eeffaf57d]
+
+ * src/regress/ttyname/check_ttyname.c:
+ Fix includes order.
+ [ddd58edba5af]
+
+ * lib/util/util.exp.in:
+ Remove extra newline mistakenly introduced in rev 9682.
+ [36a40e308bbc]
+
+ * plugins/sudoers/Makefile.in:
+ Fix typo in unset.
+ [2c5fbe4c9a54]
+
+ * plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c, src/sesh.c:
+ Set debug instance for standalone programs.
+ [306225438408]
+
+ * plugins/sudoers/bsm_audit.c, plugins/sudoers/linux_audit.c,
+ src/net_ifs.c:
+ Fix compilation issues, fallout from the debug changes.
+ [aff5bb3d0322]
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ regen
+ [bbb69f299d1f]
+
+ * configure, configure.ac:
+ Sudo 1.8.12
+ [8d9b15c1de44]
+
+ * NEWS:
+ Update with debug system changes and revent bug fixes.
+ [44133de1dee2]
+
+ * include/sudo_debug.h, lib/util/sudo_conf.c, lib/util/sudo_debug.c,
+ plugins/sudoers/sudoers_debug.c, plugins/sudoers/sudoers_debug.h:
+ When registering with the debug subsystem, the caller now passes in
+ an arrary of ints that gets filled in with the subsytem IDs to be
+ used in debug_decl.
+ [80e80ba194f7]
+
+ * plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ sudoers_debug_instance is now included in libparsesudoers so we
+ don't need to declare it here.
+ [a56f79e6fcf8]
+
+2014-10-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, include/sudo_debug.h, lib/util/sudo_debug.c,
+ lib/util/ttysize.c, plugins/sudoers/Makefile.in,
+ plugins/sudoers/alias.c, plugins/sudoers/audit.c,
+ plugins/sudoers/auth/afs.c, plugins/sudoers/auth/aix_auth.c,
+ plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/dce.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/passwd.c,
+ plugins/sudoers/auth/rfc1938.c, plugins/sudoers/auth/secureware.c,
+ plugins/sudoers/auth/securid5.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/base64.c,
+ plugins/sudoers/boottime.c, plugins/sudoers/bsm_audit.c,
+ plugins/sudoers/check.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/env.c, plugins/sudoers/find_path.c,
+ plugins/sudoers/getspwuid.c, plugins/sudoers/goodpath.c,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/group_plugin.c, plugins/sudoers/hexchar.c,
+ plugins/sudoers/interfaces.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/iolog_path.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/logging.c,
+ plugins/sudoers/logwrap.c, plugins/sudoers/match.c,
+ plugins/sudoers/match_addr.c, plugins/sudoers/parse.c,
+ plugins/sudoers/policy.c, plugins/sudoers/prompt.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/pwutil_impl.c,
+ plugins/sudoers/redblack.c, plugins/sudoers/set_perms.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/sudoers_debug.c, plugins/sudoers/sudoers_debug.h,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, plugins/sudoers/visudo.c,
+ plugins/sudoers/visudo_json.c:
+ The sudoers plugin now defines its own list of debugging subsystem
+ names and defines.
+ [e85d0375e059]
+
+ * MANIFEST, include/sudo_debug.h, lib/util/aix.c, lib/util/event.c,
+ lib/util/event_poll.c, lib/util/event_select.c, lib/util/gidlist.c,
+ lib/util/key_val.c, lib/util/lbuf.c, lib/util/locking.c,
+ lib/util/parseln.c, lib/util/secure_path.c, lib/util/setgroups.c,
+ lib/util/strtobool.c, lib/util/strtoid.c, lib/util/strtomode.c,
+ lib/util/sudo_conf.c, lib/util/sudo_debug.c, lib/util/term.c,
+ lib/util/ttysize.c, lib/util/util.exp.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/alias.c,
+ plugins/sudoers/audit.c, plugins/sudoers/auth/afs.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/dce.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/base64.c, plugins/sudoers/boottime.c,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/check.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/env.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/getspwuid.c,
+ plugins/sudoers/goodpath.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/hexchar.c, plugins/sudoers/interfaces.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/linux_audit.c,
+ plugins/sudoers/logging.c, plugins/sudoers/logwrap.c,
+ plugins/sudoers/match.c, plugins/sudoers/match_addr.c,
+ plugins/sudoers/parse.c, plugins/sudoers/policy.c,
+ plugins/sudoers/prompt.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/pwutil_impl.c, plugins/sudoers/redblack.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoers_debug.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/timestamp.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c,
+ plugins/sudoers/visudo.c, plugins/sudoers/visudo_json.c,
+ src/Makefile.in, src/exec.c, src/exec_common.c, src/exec_pty.c,
+ src/get_pty.c, src/hooks.c, src/load_plugins.c, src/net_ifs.c,
+ src/parse_args.c, src/preserve_fds.c,
+ src/regress/ttyname/check_ttyname.c, src/selinux.c, src/sesh.c,
+ src/signal.c, src/solaris.c, src/sudo.c, src/sudo.h,
+ src/sudo_edit.c, src/tgetpass.c, src/ttyname.c, src/utmp.c:
+ Add support for multiple Debug lines per program. Callers may
+ register arbitrary debug facilities or use built-in defaults. We now
+ use separate Debug statements for plugins and programs.
+ [5e553cbbfbb1]
+
+ * MANIFEST, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, include/sudo_conf.h, include/sudo_debug.h,
+ lib/util/Makefile.in, lib/util/regress/sudo_conf/conf_test.c,
+ lib/util/regress/sudo_conf/test7.in,
+ lib/util/regress/sudo_conf/test7.out.ok, lib/util/sudo_conf.c,
+ lib/util/sudo_debug.c, lib/util/util.exp.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/solaris_audit.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudoers.h, src/hooks.c,
+ src/load_plugins.c, src/parse_args.c, src/sudo.c,
+ src/sudo_plugin_int.h:
+ Change how sudo.conf is parsed. We now do a quick parse and then set
+ the values after the entire file has been parsed. This lets us init
+ the debug system earlier. Plugin-specific debug flags are now stored
+ in struct plugin_info and struct plugin_container and passed to the
+ plugin via one or more debug_flags settings.
+ [62fb1102e1e2]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, include/sudo_plugin.h, src/load_plugins.c,
+ src/sudo.c, src/sudo_plugin_int.h:
+ Pass plugin path in the settings array.
+ [45bc2d087115]
+
+ * src/parse_args.c, src/sudo.c, src/sudo.h:
+ Return settings from parse_args as struct sudo_settings and format
+ for the plugin at plugin open time. This will allow for additional,
+ plugin-specific settings to be added to the array.
+ [167929871b94]
+
+ * plugins/sudoers/parse.c:
+ Remove an unneeded NULL check to quiet a cppcheck warning.
+ [64cb92122658]
+
+2014-10-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ Set locale to C for visudo and testsudoers regression tests. Bug
+ #672
+ [adf7997a0a65]
+
+2014-10-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/linux_audit.c:
+ Fix logic bug. We only want to return -1 from linux_audit_open()
+ when audit_open() fails and errno is not one of EINVAL,
+ EPROTONOSUPPORT, or EAFNOSUPPORT. For those errno values, we return
+ AUDIT_NOT_CONFIGURED which is not a fatal error. Bug #671
+ [6f0d8f1c7648]
+
+2014-10-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Add back fix for Bug #663
+ [a3dfc76ee776]
+
+2014-10-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ The older style bash function exporting is not used by post-
+ shellshock versions of bash.
+ [223efe328e86]
+
+ * plugins/sudoers/env.c:
+ Apple uses a different variant of the BASH_FUNC prefix for bash
+ functions.
+ [ea13c8c2a716]
+
+2014-10-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Remove change that is part of 1.8.12 not 1.8.11p1
+ [8fdad4c4f314]
+
+ * NEWS, configure, configure.ac:
+ Update for sudo 1.8.11p1
+ [80e9898f7c04]
+
+ * src/regress/ttyname/check_ttyname.c:
+ Only check stdin for the tty and avoid the check entirely if we
+ don't have a way to get the tty from the kernel. Bug #643
+ [deb799e16416]
+
+ * lib/util/sudo_debug.c:
+ Make a copy of ap in sudo_debug_vprintf2() in case the static buffer
+ is not big enough and we need to call vasprintf().
+ [a5d32b9d63be]
+
+ * src/sudo.c:
+ Avoid comparing new cwd with old one if getcwd() failed. Bug #670
+ [e99093578ca7]
+
+ * plugins/sudoers/env.c:
+ Fix debugging printout output for env_should_keep()
+ [a9e7ea4b6751]
+
+2014-10-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, include/Makefile.in:
+ Use INSTALL_OWNER instead of -O/-G flags so we can work with the
+ autotools install-sh too. Bug #669
+ [a5f87f6a52b7]
+
+ * plugins/sudoers/policy.c, plugins/sudoers/sudoers.c:
+ Move sudo_printf to policy.c to match sudo_conv.
+ [f2d6065c3daf]
+
+2014-10-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, include/sudo_fatal.h, lib/util/Makefile.in,
+ lib/util/fatal.c, lib/util/sudo_printf.c, lib/util/util.exp.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/sudo_printf.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ src/conversation.c, src/sudo.c, src/sudo_plugin_int.h:
+ Add sudo_warn_set_conversation() to specify a conversation function
+ to use for warn/fatal. If no conversation function is specified, the
+ standard error will be used. We now only need sudo_printf() for
+ things that use the parser.
+ [d6049e53e3e3]
+
+2014-10-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Use correct names when referring to subsections in the sudoers
+ manual.
+ [7a016916f0ab]
+
+2014-10-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, config.h.in, configure, configure.ac,
+ lib/util/inet_ntop.c, src/net_ifs.c:
+ Use inet_ntop() instead of inet_ntoa() and include a version for
+ systems that are missing it.
+ [1a1a70dba9c0]
+
+2014-10-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Fix detection of functions in network libs like -lsocket, -lnsl and
+ -linet when we have already added those libs to NET_LIBS. Fixes a
+ problem where inet_pton() was not detected on Solaris.
+ [27e10183649e]
+
+ * NEWS:
+ Mention --disable-shared-libutil fix.
+ [7efe70688237]
+
+ * src/Makefile.in:
+ Always use --tag=disable-static to avoid installing a static
+ sudo_noexec.
+ [5d7d58879f99]
+
+ * configure, configure.ac, lib/util/Makefile.in,
+ plugins/sudoers/Makefile.in:
+ Instead of building libutil statically for --disable-shared-libutil,
+ just treat it as a convenience library. Do the same with sudoers for
+ --enable-static-sudoers. Fixes link errors on Solaris among others
+ when --disable-shared-libutil is used.
+ [c5357fe78ab7]
+
+ * configure, configure.ac, lib/util/Makefile.in,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/system_group/Makefile.in:
+ Remove LT_LDMAP and LT_LDOPT and just use LT_LDEXPORTS for the
+ compiler-specific option to restrict symbol exporting.
+ [09e8dab6f528]
+
+ * src/preload.c:
+ Include sys/types.h to get gid_t, etc used in sudo_compat.h. Fixes a
+ build issue on Solaris.
+ [b8917967df41]
+
+2014-09-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/regress/ttyname/check_ttyname.c:
+ Fix cust & pasto in error message when there is a mismatch between
+ the sudo and libc ttys. From Diego Elio Petteno'. Bug #643
+ [87d5f1a49535]
+
+2014-09-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/env.c:
+ Add BASH_FUNC_* to environment blacklist for newer-style bash
+ functions.
+ [b6e66c4a782e]
+
+ * Makefile.in:
+ Pull additional password prompts out of mkpkg instead of hard-coding
+ them.
+ [d2a6da883b34]
+
+ * NEWS:
+ Add post-1.8.11 changes
+ [11169ace8fa4]
+
+ * Makefile.in, configure.ac, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/po/sudoers.pot:
+ Add a space after "Password:" in default password prompt so it is
+ easier to read when pwfeedback is enabled.
+ [a7750d845b5b]
+
+ * plugins/sudoers/auth/sudo_auth.c:
+ Simplify how we count the password tries
+ [71b9f2021561]
+
+ * plugins/sudoers/auth/sia.c, plugins/sudoers/auth/sudo_auth.c:
+ Block SIGINT and SIGQUIT while verifying passwords so that
+ authentication modules that use sleep() are not interrupted. If the
+ user interrupted authentication, exit the loop.
+ [1cfafd7fcb13]
+
+ * configure, configure.ac:
+ Remove Convex support; it is not modern enough to run sudo 1.8.
+ [c3bdfbb2ee11]
+
+ * configure, configure.ac:
+ Only check for -lshadow if we haven't already found getspnam() in
+ libc. Rather than treat this specially, just add -lshadow as another
+ place to search in addition to -lgen.
+ [fdf06757f25d]
+
+2014-09-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/sudo_auth.c:
+ If all authentication methods fail init/setup, fail with an error.
+ [4cd0481bf05e]
+
+ * plugins/sudoers/auth/sudo_auth.c:
+ Move pass_warn() so that it is defined before it is called().
+ [6ea697e89fef]
+
+2014-09-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pp:
+ Remove duplicate Requires: line in generated rpm spec file.
+ [335703b110c7]
+
+ * pp:
+ In pp_files_expand() set _target to be empty. Fixes a problem with
+ Solaris sh where simply using typeset doesn't causes the variable to
+ be treated as local so we can inadvertantly inherit a value from a
+ previous call.
+ [f3cecca3c7b0]
+
+2014-09-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Fix version for release.
+ [39f6a2e9a098]
+
+2014-09-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac, pathnames.h.in:
+ Only redefine _PATH_BSHELL on AIX if we included paths.h.
+ [2dd4e808f69f]
+
+ * NEWS:
+ Bug 661
+ [7f2b278086b2]
+
+ * pathnames.h.in, src/exec_common.c, src/sudo.c:
+ On AIX, _PATH_BSHELL is /usr/bin/bsh but we want to use /usr/bin/sh
+ (which is usually ksh). This makes sudo's behavior when executing a
+ shell without the #! magic number match execvp() on AIX.
+ [2b438ff99991]
+
+ * pathnames.h.in:
+ Whitespace changes.
+ [107f66ecfa54]
+
+ * configure, m4/sudo.m4:
+ Prefer /usr/bin/sh to /bin/sh to match modern systems.
+ [9e2ccb5b239f]
+
+ * NEWS, lib/util/Makefile.in:
+ Don't use SSP_CFLAGS or PIE_CFLAGS when building mksiglist/mksigname
+ as they are built with the host compiler which may be different when
+ cross-compiling. From Gustavo Zacarias. Bug 662.
+ [f1a6d58c0baa]
+
+2014-09-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/sr.mo, plugins/sudoers/po/sr.po, po/cs.mo,
+ po/cs.po, po/de.mo, po/de.po, po/eo.mo, po/eo.po, po/fi.mo,
+ po/fi.po, po/nb.mo, po/nb.po, po/pl.mo, po/pl.po, po/pt_BR.mo,
+ po/pt_BR.po, po/ru.mo, po/ru.po, po/sr.mo, po/sr.po, po/uk.mo,
+ po/uk.po, po/vi.mo, po/vi.po, po/zh_CN.mo, po/zh_CN.po:
+ Sync with translationproject.org
+ [588c41d2eab5]
+
+2014-09-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudo_nss.c:
+ Make sure we can't insert an nss entry in the list that has already
+ been used before.
+ [b5fab945991b]
+
+ * plugins/sudoers/visudo_json.c:
+ Use correct gettext macro with sudo_warnx()
+ [0a532986b016]
+
+ * NEWS:
+ Make nsswitch.conf bug fix description more accurrate. It affects
+ the "files" nsswitch source too.
+ [a29cce3a3ee9]
+
+ * NEWS:
+ Mention nsswitch.conf duplicate entry fix.
+ [f8a45b59a577]
+
+2014-09-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/parse.c, plugins/sudoers/sudoers.h:
+ Make sudoers file nsswitch functions static to parse.c since they
+ are self-contained.
+ [cf22385d0659]
+
+ * plugins/sudoers/sudo_nss.c:
+ Fix infinite loop when mulitple sudoers entries are present in
+ nsswitch.conf. From Daniel Kopecek.
+ [e773e0eee736]
+
+2014-09-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Fix for bug #660
+ [e25192ad79cc]
+
+ * src/get_pty.c:
+ Fix compilation on systems without openpty(), _getpty() or
+ grantpt(). From Vasilyy Balyasnyy
+ [897280412e3e]
+
+2014-09-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/conversation.c:
+ Remove remaining use of SUDO_CONV_DEBUG_MSG.
+ [4ee756b687ea]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, include/sudo_plugin.h:
+ SUDO_CONV_DEBUG_MSG is no longer supported.
+ [7bf46cf06578]
+
+ * doc/sudo.conf.cat, doc/sudoers.cat:
+ regen
+ [5bff0d4d3956]
+
+ * include/sudo_debug.h, lib/util/sudo_debug.c, lib/util/sudo_printf.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/policy.c:
+ There is no longer a reason for the plugin to init the debug
+ subsystem itself. It will always be initialized by the front-end if
+ needed.
+ [970dd80a9e3c]
+
+ * include/sudo_alloc.h, include/sudo_compat.h, include/sudo_fatal.h:
+ Add function arg names to prototypes where missing.
+ [e78dc4c48521]
+
+ * lib/util/alloc.c:
+ Remove obsolete definition of SIZE_T which is now handled by
+ sudo_compat.h and rename the format arg to fmt in
+ sudo_evasprintf_v1() for consistency with sudo_easprintf_v1().
+ [72c0fc5e5114]
+
+ * src/parse_args.c:
+ If we were invoked with any name ending in "edit", treat as
+ sudoedit.
+ [d307572f08bc]
+
+2014-09-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * po/sudo.pot:
+ regen
+ [31c115ffbba8]
+
+ * src/exec.c, src/exec_pty.c, src/signal.c:
+ Check return value of sigaction(), even though it should never fail.
+ [75c578e6a07c]
+
+2014-09-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/Makefile.in, src/Makefile.in:
+ regen
+ [2fcb390e8e89]
+
+ * MANIFEST, plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/parser/check_hexchar.c:
+ Add hexchar unit test
+ [de65e0ded4a2]
+
+ * plugins/sudoers/regress/parser/check_addr.c:
+ Avoid division by zero if there was no test data.
+ [de3324077ba0]
+
+2014-09-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/event.c:
+ Remove confusing comment.
+ [ee1765a06b94]
+
+ * lib/util/sudo_debug.c:
+ Use a stack buffer for the debug message when possible, most are
+ small.
+ [945fb94a7aaf]
+
+2014-09-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/ca.mo, plugins/sudoers/po/ca.po, po/ca.mo,
+ po/ca.po:
+ Sync with translationproject.org
+ [661d536a7599]
+
+2014-08-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ Convert a debug printf to a user-visible warning.
+ [c3866eaea3ec]
+
+ * include/sudo_fatal.h, include/sudo_util.h, lib/util/fatal.c:
+ Move sudo_printf extern to sudo_util.h
+ [50275ef999e9]
+
+ * include/sudo_fatal.h, include/sudo_lbuf.h, lib/util/fatal.c,
+ lib/util/lbuf.c:
+ Some versions of the HP C Compiler don't export functions that take
+ function pointers as arguments unless a typedef is used.
+ [97cc0525dbd7]
+
+ * include/sudo_lbuf.h:
+ Work around a bug in the HP C compiler.
+ [5c902aefeba6]
+
+ * lib/util/lbuf.c:
+ Don't need sudo_fatal.h
+ [bccfe4df4794]
+
+2014-08-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * po/da.mo, po/da.po:
+ Sync with translationproject.org
+ [7910e3fc0f3e]
+
+ * src/exec.c:
+ Remove signal_event from evbase before calling sudo_ev_loopexit()
+ when the command has exited or been killed. It is possible that we
+ could receive another signal on the pipe if they are delivered out
+ of order.
+ [b8ed1c9482b4]
+
+2014-08-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Treat EOF on signal pipe (which should never happen) as ECONNRESET.
+ [eb57e9047a2c]
+
+ * include/sudo_event.h, lib/util/event.c, src/exec_pty.c:
+ Don't allow sudo_ev_loopcont() to override sudo_ev_loopexit()
+ [b6b53eacbc61]
+
+ * include/sudo_event.h, lib/util/event.c, lib/util/event_poll.c,
+ lib/util/event_select.c:
+ Add some internal convenience functions.
+ [b01063d82347]
+
+2014-08-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Fix osrelease sed expression. It wasn't matching distros with a
+ single digit version such as sles9.
+ [44f3e9b7e6c0]
+
+ * plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po, po/cs.mo,
+ po/cs.po, po/de.mo, po/de.po, po/eo.mo, po/eo.po, po/fi.mo,
+ po/fi.po, po/it.mo, po/it.po, po/nb.mo, po/nb.po, po/pl.mo,
+ po/pl.po, po/pt_BR.mo, po/pt_BR.po, po/ru.mo, po/ru.po, po/uk.mo,
+ po/uk.po, po/vi.mo, po/vi.po, po/zh_CN.mo, po/zh_CN.po:
+ Sync with translationproject.org
+ [5b2c6063db75]
+
+ * plugins/sudoers/iolog.c:
+ Return -1 from logging functions if we get a write error.
+ [a3ae43d54101]
+
+ * NEWS:
+ Mention I/O plugin changes.
+ [0bd2e99fe87a]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, include/sudo_plugin.h, src/exec_pty.c:
+ Change behavior when plugin I/O logging function returns 0 or -1.
+ For -1 (error) return, we now kill the command and disable the I/O
+ logging function that returned the error. For a 0 (reject) return,
+ we no longer display the rejected output to the user's terminal. The
+ plugin API revision is now 1.6.
+ [27bb504860f3]
+
+ * doc/sudoers.cat:
+ regen to fix version.
+ [641ea29b7dd3]
+
+ * plugins/sample/sample_plugin.c:
+ Add trivial dirty word check to the sample output logging function.
+ [a14494b87b4d]
+
+2014-08-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Update for 1.8.11b2
+ [72ac1f26ba78]
+
+ * src/sudo_edit.c:
+ Fix restoration of effective uid/gid in command_details. This masked
+ the effects an unset (really zero) egid. Bug 656
+ [b75eed459386]
+
+ * src/sudo.c:
+ Set runas egid to the same value as runas gid if egid not specified
+ by the plugin. Only affects new files created by sudoedit. Bug #656
+ [f2daabba4912]
+
+ * src/sudo_edit.c:
+ Don't leak temp fd in sudo_edit_copy_tfiles(). Fix fd leak in error
+ path in sudo_edit_copy_tfiles().
+ [465d6a79b5cf]
+
+2014-08-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ fix typo
+ [a4659abcbc1d]
+
+ * src/signal.c:
+ We write an unsigned char, not an int, to the signal pipe.
+ [fae4217be608]
+
+2014-08-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo_edit.c:
+ Sprinkle some debugging around uid/gid setting in sudoedit.
+ [15e4a337f0b0]
+
+ * src/sesh.c, src/sudo.c, src/sudo.h, src/sudo_edit.c,
+ src/sudo_exec.h:
+ Make sudoedit work with SELinux RBAC. Adapted from RedHat patches
+ (Daniel Kopecek) but made to behave a bit more like the non-SELinux
+ bits.
+ [8f3f7969220f]
+
+ * src/sudo_edit.c:
+ Refactor code that copies temp files into separate functions.
+ [b1057f4bee87]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in:
+ Fix typo, .em should be .Em
+ [ec28aa3bdd6a]
+
+2014-08-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sesh.c:
+ Add missing call to initprogname().
+ [71040679765f]
+
+ * lib/util/sudo_debug.c, lib/util/sudo_printf.c:
+ Don't recurse infinitely until we blow the stack when the debug file
+ can't be opened in the front-end. The conversation-type debug mode
+ will be removed in the future.
+ [38cd1a6343c2]
+
+2014-08-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Only use the first two digits of the version number. Fixes a problem
+ on RHEL 7 which has version numbers like 7.0.1406
+ [272727fd57fb]
+
+ * plugins/sudoers/linux_audit.c:
+ Fix return value when kernel has no audit support.
+ [7ca1c9857058]
+
+ * lib/util/progname.c:
+ remove unused label
+ [4179ea1ffa3a]
+
+2014-08-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4, autogen.sh:
+ Update to automake 1.14 (no code changes).
+ [5e04db4f7c5d]
+
+2014-08-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document the interaction between sudoers environment handling and
+ the pam_env module.
+ [bd56868f078c]
+
+ * plugins/sudoers/env.c:
+ Don't allow pam_env to overwrite existing variables when env_reset
+ is disabled unless the variables match the black list and would
+ normally be removed. It may just be better to never overwrite when
+ env_reset is disabled.
+ [e0ae88fce535]
+
+2014-08-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ Update year range to include 2014
+ [6b3b5f3fa791]
+
+2014-08-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/Makefile.in:
+ Remove regress .err files in distclean target.
+ [d66a4f1db130]
+
+ * lib/util/Makefile.in, plugins/group_file/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in:
+ Remove generated files for linker as part of distclean.
+ [5d1bf6c32c6b]
+
+ * .hgignore:
+ Ignore .out and .err files in lib/util regress
+ [9f4d91e77c0f]
+
+ * NEWS:
+ Add additional 1.8.11 changes and fix typos.
+ [7980e2abb6ea]
+
+ * configure, configure.ac, plugins/sudoers/Makefile.in:
+ Avoid building/running the check_symbols test program unless we are
+ building a shared sudoers plugin.
+ [a6bde1a12111]
+
+ * plugins/sudoers/Makefile.in, src/Makefile.in:
+ Remove two instances of -no-fast-install that were missed before.
+ [8a2c89cdf252]
+
+ * INSTALL, NEWS, configure, configure.ac, lib/util/Makefile.in:
+ Add --disable-shared-libutil configure option. It may only be used
+ in conjunction with the --enable-static-sudoers option.
+ [e19c71464399]
+
+2014-08-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/Makefile.in:
+ Remove noop man.sed files Use full path instead of $@.in when
+ calling config.status with --file=-
+ [53c69928427e]
+
+ * src/preserve_fds.c:
+ Fix "sudo -C" when we have internal fds to preserve from
+ closefrom().
+ [942db66345ea]
+
+2014-08-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/env.c:
+ Add explicit support for matching the full environment string
+ (name=value). Bash functions may now be preserved for full matches,
+ but not for name-only matches.
+ [f4d816e11f66]
+
+2014-08-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * .hgignore:
+ Ignore lib/util/util.exp
+ [e08306ca6a6d]
+
+2014-07-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Fix exporting of asprintf/vasprintf symbols.
+ [5ff59bdeb501]
+
+ * configure, configure.ac:
+ Don't export getaddrinfo symbols if we found the function in a
+ library.
+ [3bf4a5d3cfdb]
+
+ * src/sudo_edit.c:
+ It is now sudo_efree() not efree(). Don't try to free a pointer to
+ garbage on error.
+ [51a1ddaa220d]
+
+ * plugins/sudoers/po/sudoers.pot, po/sudo.pot:
+ Regen .pot files
+ [8c46fe51d32e]
+
+2014-07-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo_edit.c:
+ Plug memory leak, even though we are headed for exit.
+ [e2b28ddffabe]
+
+ * configure, configure.ac, lib/util/Makefile.in,
+ plugins/sudoers/Makefile.in:
+ If getaddrinfo() is missing libsudoutil may need to pull in
+ networking libraries.
+ [4d6724d54927]
+
+ * MANIFEST, configure, configure.ac, include/sudo_compat.h,
+ lib/util/Makefile.in, lib/util/util.exp, lib/util/util.exp.in,
+ m4/sudo.m4:
+ Only include functions in util.exp that are actually in the library.
+ Fixes a problem on Solaris where undefined functions that are listed
+ as exported in the map file result in a link error. Also make sure
+ we use our glob.c if the system is missing glob().
+ [3121ad215f1e]
+
+ * configure, configure.ac:
+ Make sure shadow libs don't end up in LIBS, only SUDOERS_LIBS (and
+ SUDO_LIBS if set_auth_parameters() or initprivs() are present.
+ [fb084b157c76]
+
+ * configure.ac:
+ No need to AC_SUBST HAVE_BSM_AUDIT and HAVE_SOLARIS_AUDIT
+ [5d73ccf3a7b9]
+
+2014-07-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c, src/exec_pty.c, src/sudo_exec.h:
+ Attempt to handle systems with SA_SIGINFO but that lack SI_USER.
+ [0c8b09861ad5]
+
+ * config.h.in, configure, configure.ac, include/sudo_compat.h:
+ Replace use of HAVE_GETCWD with PREFER_PORTABLE_GETCWD. It is safe
+ to assume getcwd() exists, we just need to handle broken ones.
+ [e897223a8f38]
+
+ * config.h.in, configure, configure.ac, plugins/sudoers/Makefile.in:
+ Add check for inet_ntoa() since it may live in libnsl. Make getcwd()
+ replacement private to the SunOS 4 section.
+ [8e2cd0fdd6cd]
+
+ * plugins/sudoers/match.c:
+ Avoid mixing declarations and code for non-C99 compilers.
+ [1fa5cf2356fd]
+
+ * include/sudo_debug.h:
+ For C89, use "const char __func__[]" instead of "const char
+ *__func__".
+ [c4e9f9d6691b]
+
+ * plugins/sudoers/match.c:
+ Fix compilation on systems w/o netgroups.
+ [57deb66ef8ff]
+
+2014-07-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/preserve_fds.c:
+ Back out old workaround for sudoedit hang when debugging was
+ enabled.
+ [f547bf80c436]
+
+ * src/sudo_edit.c:
+ Don't memcpy() the preserved_fds TAILQ as the pointers into the head
+ will be wrong. All we need to do is save the old command details and
+ restore them after calling run_command(). Fixes a hang with sudoedit
+ when debugging is enabled.
+ [84ff8e1f490a]
+
+2014-07-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo.c:
+ The default policy close function should only print an error message
+ if the error_code is non-zero.
+ [2032c9e33e3f]
+
+ * src/preserve_fds.c:
+ If there the preserved fds list is empty, add a new element with
+ TAILQ_INSERT_HEAD instead of TAILQ_INSERT_TAIL to avoid an infinite
+ loop on AIX, Solaris and possibly others when debug mode is active.
+ [63cefe22c515]
+
+ * lib/util/progname.c:
+ Remove support for getting program name via /proc as pr_fname is
+ usually filled in after symbolic links have been processed, even on
+ Solaris.
+ [0460c613753c]
+
+ * lib/util/Makefile.in:
+ Use shlib_enable instead of soext when determining whether to
+ install the library.
+ [d46640a7733c]
+
+ * lib/util/regress/atofoo/atofoo_test.c:
+ Avoid potential division by zero
+ [6411d276a138]
+
+ * lib/util/Makefile.in:
+ Don't link progname test with libsudo_util, just link in progname.lo
+ directly since that is all we need. Avoid a linker issue on darwin.
+ [ee6210ee5cc0]
+
+ * lib/util/progname.c:
+ Remove pstat_getproc() path as pst_ucomm on HP-UX will return the
+ target of a symbolic link and not the name of the link itself. Avoid
+ using pr_fname on AIX for the same reason. Bug 654
+ [36aced8e3714]
+
+ * MANIFEST, lib/util/Makefile.in,
+ lib/util/regress/progname/progname_test.c:
+ Add test for getprogname() and symbolic links; bug 654
+ [fbbe9faeda46]
+
+2014-07-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in:
+ Document tracing
+ [cfd7f14d596d]
+
+2014-07-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lib/util/util.exp:
+ sudo_term_{erase,kill} are regular symbols not functions.
+ [3454a9c1328b]
+
+2014-07-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Fix NULL deref if base64_decode returns -1.
+ [d03e207b1bb8]
+
+ * MANIFEST, include/missing.h, include/sudo_compat.h,
+ lib/util/Makefile.in, lib/util/aix.c, lib/util/alloc.c,
+ lib/util/clock_gettime.c, lib/util/closefrom.c, lib/util/event.c,
+ lib/util/event_poll.c, lib/util/event_select.c, lib/util/fatal.c,
+ lib/util/fnmatch.c, lib/util/getaddrinfo.c, lib/util/getcwd.c,
+ lib/util/getgrouplist.c, lib/util/getline.c, lib/util/getopt_long.c,
+ lib/util/gidlist.c, lib/util/glob.c, lib/util/inet_pton.c,
+ lib/util/isblank.c, lib/util/key_val.c, lib/util/lbuf.c,
+ lib/util/locking.c, lib/util/memrchr.c, lib/util/memset_s.c,
+ lib/util/mksiglist.c, lib/util/mksigname.c, lib/util/mktemp.c,
+ lib/util/parseln.c, lib/util/progname.c, lib/util/pw_dup.c,
+ lib/util/regress/atofoo/atofoo_test.c,
+ lib/util/regress/fnmatch/fnm_test.c,
+ lib/util/regress/glob/globtest.c,
+ lib/util/regress/sudo_conf/conf_test.c,
+ lib/util/regress/sudo_parseln/parseln_test.c,
+ lib/util/regress/tailq/hltq_test.c, lib/util/secure_path.c,
+ lib/util/setgroups.c, lib/util/sha2.c, lib/util/sig2str.c,
+ lib/util/snprintf.c, lib/util/strlcat.c, lib/util/strlcpy.c,
+ lib/util/strsignal.c, lib/util/strtobool.c, lib/util/strtoid.c,
+ lib/util/strtomode.c, lib/util/strtonum.c, lib/util/sudo_conf.c,
+ lib/util/sudo_debug.c, lib/util/sudo_dso.c, lib/util/sudo_printf.c,
+ lib/util/term.c, lib/util/ttysize.c, lib/util/utimes.c,
+ plugins/group_file/Makefile.in, plugins/group_file/getgrent.c,
+ plugins/group_file/group_file.c, plugins/sample/Makefile.in,
+ plugins/sample/sample_plugin.c, plugins/sudoers/Makefile.in,
+ plugins/sudoers/audit.c, plugins/sudoers/base64.c,
+ plugins/sudoers/boottime.c, plugins/sudoers/bsm_audit.c,
+ plugins/sudoers/getdate.c, plugins/sudoers/getdate.y,
+ plugins/sudoers/hexchar.c, plugins/sudoers/linux_audit.c,
+ plugins/sudoers/locale.c, plugins/sudoers/redblack.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_base64.c,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/timestr.c, plugins/system_group/Makefile.in,
+ plugins/system_group/system_group.c, src/Makefile.in,
+ src/locale_stub.c, src/net_ifs.c, src/preload.c,
+ src/regress/ttyname/check_ttyname.c, src/sesh.c, src/sudo.h,
+ src/sudo_noexec.c:
+ Rename missing.h -> sudo_compat.h
+ [ddcc945a0f87]
+
+ * MANIFEST, include/secure_path.h, include/sudo_util.h,
+ lib/util/Makefile.in, lib/util/secure_path.c, lib/util/sudo_conf.c,
+ plugins/sudoers/Makefile.in, plugins/sudoers/sudoers.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Merge secure_path.h -> sudo_util.h
+ [0385dfbf2e2d]
+
+ * include/secure_path.h, include/sudo_alloc.h, include/sudo_conf.h,
+ include/sudo_dso.h, include/sudo_event.h, include/sudo_fatal.h,
+ include/sudo_lbuf.h, include/sudo_util.h, lib/util/aix.c,
+ lib/util/alloc.c, lib/util/event.c, lib/util/fatal.c,
+ lib/util/gidlist.c, lib/util/key_val.c, lib/util/lbuf.c,
+ lib/util/locking.c, lib/util/parseln.c, lib/util/secure_path.c,
+ lib/util/setgroups.c, lib/util/strtobool.c, lib/util/strtoid.c,
+ lib/util/strtomode.c, lib/util/sudo_conf.c, lib/util/sudo_dso.c,
+ lib/util/term.c, lib/util/ttysize.c, lib/util/util.exp,
+ plugins/sudoers/locale.c, src/locale_stub.c:
+ Version the functions in libsudo_util
+ [c6d6eba95bb4]
+
+2014-07-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/gettext.h, include/sudo_gettext.h, lib/util/Makefile.in,
+ lib/util/aix.c, lib/util/alloc.c, lib/util/fatal.c,
+ lib/util/gidlist.c, lib/util/strsignal.c, lib/util/strtoid.c,
+ lib/util/strtomode.c, lib/util/strtonum.c, lib/util/sudo_conf.c,
+ lib/util/sudo_debug.c, plugins/sudoers/Makefile.in,
+ plugins/sudoers/audit.c, plugins/sudoers/bsm_audit.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/locale.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoreplay.c,
+ src/Makefile.in, src/locale_stub.c, src/net_ifs.c, src/sesh.c,
+ src/sudo.h:
+ Rename gettext.h -> sudo_gettext.h
+ [7f6b44473b8f]
+
+ * include/fatal.h, include/sudo_fatal.h, lib/util/Makefile.in,
+ lib/util/aix.c, lib/util/alloc.c, lib/util/event.c,
+ lib/util/event_poll.c, lib/util/event_select.c, lib/util/fatal.c,
+ lib/util/getopt_long.c, lib/util/gidlist.c, lib/util/lbuf.c,
+ lib/util/regress/atofoo/atofoo_test.c,
+ lib/util/regress/tailq/hltq_test.c, lib/util/sudo_conf.c,
+ lib/util/sudo_debug.c, plugins/sudoers/Makefile.in,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/linux_audit.c,
+ plugins/sudoers/locale.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoreplay.c,
+ src/Makefile.in, src/locale_stub.c, src/net_ifs.c,
+ src/regress/ttyname/check_ttyname.c, src/sesh.c, src/sudo.h:
+ Rename fatal.h -> sudo_fatal.h
+ [bef3401dbb24]
+
+ * include/queue.h, include/sudo_conf.h, include/sudo_event.h,
+ include/sudo_queue.h, lib/util/Makefile.in, lib/util/fatal.c,
+ lib/util/regress/tailq/hltq_test.c, plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoreplay.c,
+ src/Makefile.in, src/hooks.c:
+ Rename queue.h -> sudo_queue.h to avoid collisions with the system
+ version.
+ [473614fdde5a]
+
+ * include/sudo_debug.h, lib/util/sudo_debug.c:
+ Conver sudo_debug_write() to a macro
+ [0f110f27a23c]
+
+2014-07-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/fixman.sh, doc/fixmdoc.sh:
+ Fix man page post-processing; it was deleting more than intended.
+ [716af03dcfb7]
+
+2014-07-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/Makefile.in:
+ Remove double $(srcdir) when running sed scripts.
+ [16add67ae550]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ "an EXEC tag" not "a EXEC tag"
+ [9ac1b8e322f9]
+
+ * doc/sudoers.cat:
+ Document that I/O logging is not enabled by default.
+ [08fca95dd5a4]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document that exec_background is off by default.
+ [87fe5defff58]
+
+2014-07-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sesh.c:
+ Error out if sesh is run as a login shell but the shell it needs to
+ run has no slash. This shouldn't happen in practice.
+ [10ff502888ee]
+
+ * MANIFEST, include/compat/mksiglist.h, include/compat/mksigname.h,
+ lib/util/Makefile.in, lib/util/mksiglist.c, lib/util/mksiglist.h,
+ lib/util/mksigname.c, lib/util/mksigname.h:
+ Move mksiglist.h and mksigname.h to lib/util where they belong.
+ [d01046c69060]
+
+ * config.h.in, configure, configure.ac, include/missing.h,
+ lib/util/progname.c, lib/util/util.exp, plugins/sudoers/Makefile.in:
+ Avoid passing -no-fast-install to libtool as this results in the
+ build dir being left in the library path of the installed
+ executable. Instead, we remove the "lt-" prefix from the program
+ name in initprogname() so that the regress test output is unaffected
+ by libtool's binary wrapper.
+ [75d1563e95b4]
+
+ * sudo.pp:
+ Fix syntax error with some shells.
+ [91e8da7702c5]
+
+2014-07-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Force libtool to use runtime linking on AIX so that it installs the
+ plugins as .so files and not .a files.
+ [ae66488bd9ca]
+
+ * plugins/sudoers/ldap.c:
+ Be sure to NUL-terminate the decoded secret when converting from
+ base64.
+ [b3dc463c8882]
+
+ * plugins/sudoers/ldap.c:
+ Fix a pointer signednes warning calling base64_decode().
+ [74f7354867a3]
+
+ * lib/util/getgrouplist.c:
+ Use sudo_strtoid() now that it is located in the same library.
+ [4868532e2d65]
+
+ * lib/util/strtoid.c:
+ Skip leading space (ala strtol) so that we can pick up the sign even
+ if it is not the first character of the string.
+ [148ee633c6a4]
+
+2014-07-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ For sudoedit, audit the actual editor being run, not just the
+ sudoedit command.
+ [59a5b0ad36af]
+
+ * src/selinux.c:
+ Audit failed user role changes. RedHat bz #665131
+ [cf9777687124]
+
+ * plugins/sudoers/Makefile.in:
+ Avoid running check_symbols for static sudoers
+ [71b13bada1ce]
+
+ * plugins/sudoers/regress/visudo/test3.err.ok,
+ plugins/sudoers/regress/visudo/test3.sh:
+ Adapt to unused alias changes.
+ [4b58e36c3d8f]
+
+ * doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in,
+ plugins/sudoers/visudo.c:
+ An unused alias is not really an error, even in strict mode. RedHat
+ bz #604297
+ [f10b3b7ec5a6]
+
+ * src/sesh.c:
+ When running a login shell via sesh, make new argv[0] -shell, not
+ /path/to-shell. RedHat bz #1065418
+ [414cb512f102]
+
+2014-07-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ The RHEL sudo package allows users in group wheel to run sudo.
+ [9f22020a57cf]
+
+ * Makefile.in, sudo.pp:
+ Avoid packaging parent directories when they are system directories.
+ Currently we just skip this when prefix is /usr
+ [93ccede545cd]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Fix typo: sudo.d -> sudoers.d. From RedHat bz #726634
+ [1c99a4fd9c7d]
+
+ * mkpkg:
+ RHEL 6 and above use /etc/sudo-ldap.conf not /etc/ldap.conf
+ [ce3216e4390a]
+
+ * pp:
+ For rpm, do not specify a mode in %attr for symbolic links. Avoids
+ the warning "Explicit %attr() mode not applicaple to symlink"
+ [3f5a80ed5081]
+
+2014-07-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_alloc.h, lib/util/aix.c, lib/util/event.c,
+ lib/util/event_poll.c, lib/util/event_select.c, lib/util/fatal.c,
+ lib/util/lbuf.c, lib/util/sudo_conf.c, plugins/sudoers/alias.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/passwd.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/check.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/env.c, plugins/sudoers/find_path.c,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/group_plugin.c, plugins/sudoers/interfaces.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/linux_audit.c,
+ plugins/sudoers/locale.c, plugins/sudoers/logging.c,
+ plugins/sudoers/match.c, plugins/sudoers/policy.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/pwutil_impl.c,
+ plugins/sudoers/redblack.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, plugins/sudoers/visudo.c, src/exec.c,
+ src/exec_common.c, src/exec_pty.c, src/hooks.c, src/load_plugins.c,
+ src/net_ifs.c, src/preserve_fds.c,
+ src/regress/ttyname/check_ttyname.c, src/selinux.c, src/sudo.c,
+ src/ttyname.c:
+ efree -> sudo_efree for consistency
+ [7dfd16fbb6cf]
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo_plugin.cat,
+ doc/sudoers.cat, doc/sudoreplay.cat, doc/visudo.cat:
+ regen
+ [a1d38600d34c]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, plugins/sudoers/ldap.c:
+ Add support for base64 secrets in ldap.conf and ldap.secret. Based
+ on an idea from anthony AT rlost DOT com
+ [4999b78f8b6d]
+
+2014-07-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ Don't use the HP compiler in preference to gcc. Some versions have
+ trouble compiling lbuf.c.
+ [322daf03ab6f]
+
+2014-07-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac, plugins/group_file/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in, src/Makefile.in:
+ Remove @SOEXT@ and @SHLIB_EXT@ now that we use libtool to install
+ shared objects. Instead, use the new @SHLIB_ENABLE@ that is set to
+ the value of $enable_dlopen. For sudo_noexec.so there is nothing
+ special to do since the install-noexec target is only called when
+ noexec is enabled by configure.
+ [4447190f212b]
+
+ * configure, configure.ac:
+ Make dynamic shared objects non-writable on HP-UX. Using writable
+ DSOs can substantially increase the load time.
+ [8715aff11063]
+
+ * include/fatal.h, lib/util/fatal.c, lib/util/util.exp,
+ plugins/sudoers/locale.c, src/locale_stub.c:
+ Add sudo_warn_strerror() that wraps strerror() with calls to
+ setlocale() in sudoers so we always get the error string in the
+ user's locale. Also change _warning() to take the error number as a
+ parameter instead of examining errno.
+ [cc38a8389a7b]
+
+2014-07-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, lib/util/Makefile.in, plugins/group_file/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in, src/Makefile.in:
+ Avoid a cppcheck warning when NSIG is not defined.
+ [f8e5e92bab60]
+
+ * include/missing.h:
+ Fix typos in utimes/futimes macros.
+ [10f022d933c2]
+
+2014-07-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [e351d905c0c9]
+
+ * configure.ac:
+ Fix sudo when --disable-shared configure option was specified.
+ [07899f6b43f0]
+
+2014-06-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac, lib/util/Makefile.in,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/system_group/Makefile.in,
+ src/Makefile.in:
+ Use libtool to install/uninstall the plugins and sudo_noexec.
+ [18ae09c53f2e]
+
+2014-07-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, m4/libtool.m4:
+ Do not set an internal name for HP-UX modules, only archives. This
+ works around a problem with some versions of HP-UX ld where setting
+ an internal name that doesn't end in .sl causes link errors.
+ [9a049adb22aa]
+
+ * plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/system_group/Makefile.in:
+ Never build build static versions of other plugins.
+ [52123c4c17bc]
+
+ * lib/util/Makefile.in:
+ Don't build a static libsudo_util.a unless we are linking sudoers
+ statically.
+ [9c3327977dff]
+
+2014-06-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, ltmain.sh, m4/libtool.m4:
+ Fix my typos in the HP-UX libtool patch
+ [6e70066d86bb]
+
+2014-06-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Mention Solaris audit.
+ [d90efa19ca16]
+
+ * INSTALL, MANIFEST, config.h.in, configure, configure.ac, mkdep.pl,
+ plugins/sudoers/Makefile.in, plugins/sudoers/audit.c,
+ plugins/sudoers/solaris_audit.c, plugins/sudoers/solaris_audit.h:
+ Add Solaris audit support; from Gary Winiger at Oracle.
+ [6f68a27e53f5]
+
+ * MANIFEST:
+ Sync MANIFEST with file name changes.
+ [d9958df5f9da]
+
+ * plugins/sudoers/toke.c:
+ regen
+ [ad82b20093c3]
+
+ * include/sudo_util.h, lib/util/Makefile.in, lib/util/atobool.c,
+ lib/util/atoid.c, lib/util/atomode.c, lib/util/getgrouplist.c,
+ lib/util/gidlist.c, lib/util/regress/atofoo/atofoo_test.c,
+ lib/util/strtobool.c, lib/util/strtoid.c, lib/util/strtomode.c,
+ lib/util/sudo_conf.c, lib/util/util.exp,
+ plugins/group_file/getgrent.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/match.c, plugins/sudoers/policy.c,
+ plugins/sudoers/pwutil.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/tsgetgrpw.c, plugins/sudoers/visudo_json.c,
+ plugins/system_group/system_group.c, src/sudo.c:
+ atobool -> sudo_strtobool atoid-> sudo_strtoid atomode ->
+ sudo_strtomode
+ [aefe6f09f4a4]
+
+ * lib/util/alloc.c, lib/util/event_select.c:
+ Fix regexp damage when renaming erecalloc() -> sudo_erecalloc()
+ [d772a34032cc]
+
+ * src/sudo_edit.c:
+ Handle systems like AIX that lack a way to set the modification time
+ on open fds.
+ [b93c0a55c21b]
+
+ * MANIFEST:
+ update MANIFEST for alloc.h -> sudo_alloc.h change
+ [ce240c682554]
+
+ * include/alloc.h, include/sudo_alloc.h, lib/util/Makefile.in,
+ lib/util/aix.c, lib/util/alloc.c, lib/util/event.c,
+ lib/util/event_poll.c, lib/util/event_select.c, lib/util/fatal.c,
+ lib/util/gidlist.c, lib/util/lbuf.c, lib/util/sudo_conf.c,
+ lib/util/sudo_debug.c, lib/util/util.exp,
+ plugins/sudoers/Makefile.in, plugins/sudoers/alias.c,
+ plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/env.c, plugins/sudoers/find_path.c,
+ plugins/sudoers/getspwuid.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/interfaces.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/iolog_path.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/locale.c,
+ plugins/sudoers/logging.c, plugins/sudoers/match.c,
+ plugins/sudoers/parse.c, plugins/sudoers/policy.c,
+ plugins/sudoers/prompt.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/pwutil_impl.c, plugins/sudoers/redblack.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c,
+ src/Makefile.in, src/conversation.c, src/env_hooks.c, src/exec.c,
+ src/exec_common.c, src/exec_pty.c, src/hooks.c, src/load_plugins.c,
+ src/net_ifs.c, src/parse_args.c, src/preserve_fds.c,
+ src/regress/ttyname/check_ttyname.c, src/selinux.c, src/sesh.c,
+ src/sudo.c, src/sudo.h, src/sudo_edit.c, src/ttyname.c:
+ Add sudo_ prefix to alloc.c functions and rename alloc.h ->
+ sudo_alloc.h
+ [3a19f5391442]
+
+ * lib/util/fatal.c:
+ Remove extra sudo_ prefix from vfatalxnodebug and vfatalx_nodebug.
+ [819ad8075005]
+
+ * MANIFEST, include/fileops.h, include/sudo_util.h,
+ lib/util/Makefile.in, lib/util/fileops.c, lib/util/locking.c,
+ lib/util/parseln.c, lib/util/regress/sudo_parseln/parseln_test.c,
+ lib/util/sudo_conf.c, plugins/sudoers/Makefile.in,
+ plugins/sudoers/sudoers.h, src/Makefile.in, src/sudo.h:
+ Split fileops.c into parseln.c and locking.c
+ [361ea81e88d9]
+
+ * include/fatal.h, include/gettext.h, lib/util/aix.c,
+ lib/util/alloc.c, lib/util/fatal.c, lib/util/getopt_long.c,
+ lib/util/gidlist.c, lib/util/regress/atofoo/atofoo_test.c,
+ lib/util/regress/tailq/hltq_test.c, lib/util/sudo_conf.c,
+ lib/util/util.exp, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/rfc1938.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/env.c, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/locale.c,
+ plugins/sudoers/logging.c, plugins/sudoers/match.c,
+ plugins/sudoers/policy.c, plugins/sudoers/prompt.c,
+ plugins/sudoers/pwutil.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, plugins/sudoers/visudo.c,
+ plugins/sudoers/visudo_json.c, src/exec.c, src/exec_common.c,
+ src/exec_pty.c, src/hooks.c, src/load_plugins.c, src/locale_stub.c,
+ src/net_ifs.c, src/parse_args.c, src/selinux.c, src/sesh.c,
+ src/signal.c, src/solaris.c, src/sudo.c, src/sudo_edit.c,
+ src/tgetpass.c, src/ttyname.c, src/utmp.c:
+ Rename warning/fatal -> sudo_warn/sudo_fatal to avoid namespace
+ pollution in libsudo_util.so.
+ [4eb69f501113]
+
+2014-06-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_util.h, lib/util/term.c, lib/util/ttysize.c,
+ lib/util/util.exp, plugins/sudoers/sudoreplay.c, src/exec_pty.c,
+ src/sudo.c, src/tgetpass.c:
+ Reduce name space pollution in libsudo_util.so
+ [215e4413529a]
+
+ * src/solaris.c:
+ Use sudo_dso_load() from libsudo_util.so instead of dlopen() since
+ we no longer link sudo directly with libdl.so.
+ [fe6942873c2d]
+
+ * MANIFEST, Makefile.in, include/lbuf.h, include/sudo_lbuf.h,
+ lib/util/Makefile.in, lib/util/lbuf.c, lib/util/util.exp,
+ plugins/sudoers/Makefile.in, plugins/sudoers/ldap.c,
+ plugins/sudoers/parse.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudo_nss.h,
+ plugins/sudoers/sudoers.h, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, src/Makefile.in, src/parse_args.c:
+ Don't pollute the namespace with lbuf struct and functions
+ [7859e3c22fb9]
+
+ * include/sudo_util.h, lib/util/gidlist.c, lib/util/util.exp,
+ plugins/sudoers/policy.c, src/sudo.c:
+ Rename parse_gid_list -> sudo_parse_gids to avoid namespace
+ pollution.
+ [d88f3cab97e1]
+
+ * MANIFEST, include/sudo_util.h, lib/util/Makefile.in,
+ lib/util/fmt_string.c, lib/util/key_val.c, lib/util/util.exp,
+ plugins/sample/sample_plugin.c, plugins/sudoers/policy.c,
+ src/Makefile.in, src/exec_common.c, src/parse_args.c, src/sudo.c:
+ Rename fmt_string -> sudo_new_key_val to better describe its
+ function.
+ [f9061e319cc3]
+
+ * include/fileops.h, lib/util/fileops.c, lib/util/util.exp,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/logging.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/visudo.c, src/sudo_edit.c:
+ Remove touch() from fileops.c and just call utimes/futimes directly.
+ Rename lock_file -> sudo_lock_file to avoid namespace pollution
+ [ec08128b6900]
+
+ * NEWS, configure, configure.ac:
+ Sudo 1.8.11
+ [5fb775825aab]
+
+ * include/fatal.h, lib/util/fatal.c, lib/util/util.exp,
+ plugins/sudoers/iolog.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.c:
+ Remove use of setjmp/longjmp in the sudoers plugin. We no longer
+ call fatal() except in the malloc wrappers and due to libsudo_util
+ there is now a single copy of fatal/fatalx.
+ [109407210f9c]
+
+ * MANIFEST, Makefile.in, doc/Makefile.in, include/alloc.h,
+ include/compat/fnmatch.h, include/compat/getaddrinfo.h,
+ include/compat/getopt.h, include/compat/glob.h,
+ include/compat/sha2.h, include/fatal.h, include/fileops.h,
+ include/lbuf.h, include/missing.h, include/secure_path.h,
+ include/sudo_conf.h, include/sudo_debug.h, include/sudo_dso.h,
+ include/sudo_event.h, include/sudo_util.h, install-sh,
+ lib/util/Makefile.in, lib/util/fatal.c, lib/util/getaddrinfo.c,
+ lib/util/pw_dup.c, lib/util/regress/fnmatch/fnm_test.c,
+ lib/util/sudo_dso.c, lib/util/sudo_printf.c, lib/util/term.c,
+ lib/util/util.exp, plugins/group_file/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/sudoers/match.c,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/visudo.c,
+ plugins/system_group/Makefile.in, src/Makefile.in, src/parse_args.c,
+ src/preload.c:
+ Add exported libsudo_util functions to util.exp and mark in headers
+ using __dso_public.
+ [18faff6ab915]
+
+ * config.h.in, configure, configure.ac, include/compat/fnmatch.h,
+ include/compat/getaddrinfo.h, include/compat/getopt.h,
+ include/compat/glob.h, include/missing.h, lib/util/clock_gettime.c,
+ lib/util/closefrom.c, lib/util/fnmatch.c, lib/util/getaddrinfo.c,
+ lib/util/getcwd.c, lib/util/getgrouplist.c, lib/util/getline.c,
+ lib/util/getopt_long.c, lib/util/glob.c, lib/util/inet_pton.c,
+ lib/util/memrchr.c, lib/util/memset_s.c, lib/util/mktemp.c,
+ lib/util/pw_dup.c, lib/util/sig2str.c, lib/util/snprintf.c,
+ lib/util/strlcat.c, lib/util/strlcpy.c, lib/util/strsignal.c,
+ lib/util/strtonum.c, lib/util/utimes.c:
+ Prefix all libc replacements with sudo_ and #define the real name to
+ the sudo_ version. That way we don't pollute the libc namespace.
+ [5cf7101479b8]
+
+ * .hgignore, MANIFEST, Makefile.in, common/Makefile.in, common/aix.c,
+ common/alloc.c, common/atobool.c, common/atoid.c, common/atomode.c,
+ common/event.c, common/event_poll.c, common/event_select.c,
+ common/fatal.c, common/fileops.c, common/fmt_string.c,
+ common/gidlist.c, common/lbuf.c, common/progname.c,
+ common/regress/atofoo/atofoo_test.c,
+ common/regress/sudo_conf/conf_test.c,
+ common/regress/sudo_conf/test1.in,
+ common/regress/sudo_conf/test1.out.ok,
+ common/regress/sudo_conf/test2.in,
+ common/regress/sudo_conf/test2.out.ok,
+ common/regress/sudo_conf/test3.in,
+ common/regress/sudo_conf/test3.out.ok,
+ common/regress/sudo_conf/test4.in,
+ common/regress/sudo_conf/test4.out.ok,
+ common/regress/sudo_conf/test5.err.ok,
+ common/regress/sudo_conf/test5.in,
+ common/regress/sudo_conf/test5.out.ok,
+ common/regress/sudo_conf/test6.in,
+ common/regress/sudo_conf/test6.out.ok,
+ common/regress/sudo_parseln/parseln_test.c,
+ common/regress/sudo_parseln/test1.in,
+ common/regress/sudo_parseln/test1.out.ok,
+ common/regress/sudo_parseln/test2.in,
+ common/regress/sudo_parseln/test2.out.ok,
+ common/regress/sudo_parseln/test3.in,
+ common/regress/sudo_parseln/test3.out.ok,
+ common/regress/sudo_parseln/test4.in,
+ common/regress/sudo_parseln/test4.out.ok,
+ common/regress/sudo_parseln/test5.in,
+ common/regress/sudo_parseln/test5.out.ok,
+ common/regress/sudo_parseln/test6.in,
+ common/regress/sudo_parseln/test6.out.ok,
+ common/regress/tailq/hltq_test.c, common/secure_path.c,
+ common/setgroups.c, common/sudo_conf.c, common/sudo_debug.c,
+ common/sudo_dso.c, common/sudo_printf.c, common/term.c,
+ common/ttysize.c, compat/Makefile.in, compat/charclass.h,
+ compat/clock_gettime.c, compat/closefrom.c, compat/endian.h,
+ compat/fnmatch.c, compat/fnmatch.h, compat/getaddrinfo.c,
+ compat/getaddrinfo.h, compat/getcwd.c, compat/getgrouplist.c,
+ compat/getline.c, compat/getopt.h, compat/getopt_long.c,
+ compat/glob.c, compat/glob.h, compat/inet_pton.c, compat/isblank.c,
+ compat/memrchr.c, compat/memset_s.c, compat/mksiglist.c,
+ compat/mksiglist.h, compat/mksigname.c, compat/mksigname.h,
+ compat/mktemp.c, compat/nss_dbdefs.h, compat/pw_dup.c,
+ compat/regress/fnmatch/fnm_test.c,
+ compat/regress/fnmatch/fnm_test.in, compat/regress/glob/files,
+ compat/regress/glob/globtest.c, compat/regress/glob/globtest.in,
+ compat/sha2.c, compat/sha2.h, compat/sig2str.c, compat/siglist.in,
+ compat/snprintf.c, compat/stdbool.h, compat/strlcat.c,
+ compat/strlcpy.c, compat/strsignal.c, compat/strtonum.c,
+ compat/timespec.h, compat/utime.h, compat/utimes.c, configure,
+ configure.ac, include/compat/charclass.h, include/compat/endian.h,
+ include/compat/fnmatch.h, include/compat/getaddrinfo.h,
+ include/compat/getopt.h, include/compat/glob.h,
+ include/compat/mksiglist.h, include/compat/mksigname.h,
+ include/compat/nss_dbdefs.h, include/compat/sha2.h,
+ include/compat/stdbool.h, include/compat/timespec.h,
+ include/compat/utime.h, lib/util/Makefile.in, lib/util/aix.c,
+ lib/util/alloc.c, lib/util/atobool.c, lib/util/atoid.c,
+ lib/util/atomode.c, lib/util/clock_gettime.c, lib/util/closefrom.c,
+ lib/util/event.c, lib/util/event_poll.c, lib/util/event_select.c,
+ lib/util/fatal.c, lib/util/fileops.c, lib/util/fmt_string.c,
+ lib/util/fnmatch.c, lib/util/getaddrinfo.c, lib/util/getcwd.c,
+ lib/util/getgrouplist.c, lib/util/getline.c, lib/util/getopt_long.c,
+ lib/util/gidlist.c, lib/util/glob.c, lib/util/inet_pton.c,
+ lib/util/isblank.c, lib/util/lbuf.c, lib/util/memrchr.c,
+ lib/util/memset_s.c, lib/util/mksiglist.c, lib/util/mksigname.c,
+ lib/util/mktemp.c, lib/util/progname.c, lib/util/pw_dup.c,
+ lib/util/regress/atofoo/atofoo_test.c,
+ lib/util/regress/fnmatch/fnm_test.c,
+ lib/util/regress/fnmatch/fnm_test.in, lib/util/regress/glob/files,
+ lib/util/regress/glob/globtest.c, lib/util/regress/glob/globtest.in,
+ lib/util/regress/sudo_conf/conf_test.c,
+ lib/util/regress/sudo_conf/test1.in,
+ lib/util/regress/sudo_conf/test1.out.ok,
+ lib/util/regress/sudo_conf/test2.in,
+ lib/util/regress/sudo_conf/test2.out.ok,
+ lib/util/regress/sudo_conf/test3.in,
+ lib/util/regress/sudo_conf/test3.out.ok,
+ lib/util/regress/sudo_conf/test4.in,
+ lib/util/regress/sudo_conf/test4.out.ok,
+ lib/util/regress/sudo_conf/test5.err.ok,
+ lib/util/regress/sudo_conf/test5.in,
+ lib/util/regress/sudo_conf/test5.out.ok,
+ lib/util/regress/sudo_conf/test6.in,
+ lib/util/regress/sudo_conf/test6.out.ok,
+ lib/util/regress/sudo_parseln/parseln_test.c,
+ lib/util/regress/sudo_parseln/test1.in,
+ lib/util/regress/sudo_parseln/test1.out.ok,
+ lib/util/regress/sudo_parseln/test2.in,
+ lib/util/regress/sudo_parseln/test2.out.ok,
+ lib/util/regress/sudo_parseln/test3.in,
+ lib/util/regress/sudo_parseln/test3.out.ok,
+ lib/util/regress/sudo_parseln/test4.in,
+ lib/util/regress/sudo_parseln/test4.out.ok,
+ lib/util/regress/sudo_parseln/test5.in,
+ lib/util/regress/sudo_parseln/test5.out.ok,
+ lib/util/regress/sudo_parseln/test6.in,
+ lib/util/regress/sudo_parseln/test6.out.ok,
+ lib/util/regress/tailq/hltq_test.c, lib/util/secure_path.c,
+ lib/util/setgroups.c, lib/util/sha2.c, lib/util/sig2str.c,
+ lib/util/siglist.in, lib/util/snprintf.c, lib/util/strlcat.c,
+ lib/util/strlcpy.c, lib/util/strsignal.c, lib/util/strtonum.c,
+ lib/util/sudo_conf.c, lib/util/sudo_debug.c, lib/util/sudo_dso.c,
+ lib/util/sudo_printf.c, lib/util/term.c, lib/util/ttysize.c,
+ lib/util/utimes.c, lib/zlib/Makefile.in, lib/zlib/adler32.c,
+ lib/zlib/compress.c, lib/zlib/crc32.c, lib/zlib/crc32.h,
+ lib/zlib/deflate.c, lib/zlib/deflate.h, lib/zlib/gzclose.c,
+ lib/zlib/gzguts.h, lib/zlib/gzlib.c, lib/zlib/gzread.c,
+ lib/zlib/gzwrite.c, lib/zlib/infback.c, lib/zlib/inffast.c,
+ lib/zlib/inffast.h, lib/zlib/inffixed.h, lib/zlib/inflate.c,
+ lib/zlib/inflate.h, lib/zlib/inftrees.c, lib/zlib/inftrees.h,
+ lib/zlib/trees.c, lib/zlib/trees.h, lib/zlib/uncompr.c,
+ lib/zlib/zconf.h.in, lib/zlib/zlib.h, lib/zlib/zutil.c,
+ lib/zlib/zutil.h, plugins/group_file/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in, po/README, po/ca.mo, po/ca.po,
+ po/cs.mo, po/cs.po, po/da.mo, po/da.po, po/de.mo, po/de.po,
+ po/eo.mo, po/eo.po, po/es.mo, po/es.po, po/eu.mo, po/eu.po,
+ po/fi.mo, po/fi.po, po/fr.mo, po/fr.po, po/gl.mo, po/gl.po,
+ po/hr.mo, po/hr.po, po/it.mo, po/it.po, po/ja.mo, po/ja.po,
+ po/nb.mo, po/nb.po, po/nl.mo, po/nl.po, po/pl.mo, po/pl.po,
+ po/pt_BR.mo, po/pt_BR.po, po/ru.mo, po/ru.po, po/sl.mo, po/sl.po,
+ po/sr.mo, po/sr.po, po/sudo.pot, po/sv.mo, po/sv.po, po/tr.mo,
+ po/tr.po, po/uk.mo, po/uk.po, po/vi.mo, po/vi.po, po/zh_CN.mo,
+ po/zh_CN.po, src/Makefile.in, src/po/README, src/po/ca.mo,
+ src/po/ca.po, src/po/cs.mo, src/po/cs.po, src/po/da.mo,
+ src/po/da.po, src/po/de.mo, src/po/de.po, src/po/eo.mo,
+ src/po/eo.po, src/po/es.mo, src/po/es.po, src/po/eu.mo,
+ src/po/eu.po, src/po/fi.mo, src/po/fi.po, src/po/fr.mo,
+ src/po/fr.po, src/po/gl.mo, src/po/gl.po, src/po/hr.mo,
+ src/po/hr.po, src/po/it.mo, src/po/it.po, src/po/ja.mo,
+ src/po/ja.po, src/po/nb.mo, src/po/nb.po, src/po/nl.mo,
+ src/po/nl.po, src/po/pl.mo, src/po/pl.po, src/po/pt_BR.mo,
+ src/po/pt_BR.po, src/po/ru.mo, src/po/ru.po, src/po/sl.mo,
+ src/po/sl.po, src/po/sr.mo, src/po/sr.po, src/po/sudo.pot,
+ src/po/sv.mo, src/po/sv.po, src/po/tr.mo, src/po/tr.po,
+ src/po/uk.mo, src/po/uk.po, src/po/vi.mo, src/po/vi.po,
+ src/po/zh_CN.mo, src/po/zh_CN.po, zlib/Makefile.in, zlib/adler32.c,
+ zlib/compress.c, zlib/crc32.c, zlib/crc32.h, zlib/deflate.c,
+ zlib/deflate.h, zlib/gzclose.c, zlib/gzguts.h, zlib/gzlib.c,
+ zlib/gzread.c, zlib/gzwrite.c, zlib/infback.c, zlib/inffast.c,
+ zlib/inffast.h, zlib/inffixed.h, zlib/inflate.c, zlib/inflate.h,
+ zlib/inftrees.c, zlib/inftrees.h, zlib/trees.c, zlib/trees.h,
+ zlib/uncompr.c, zlib/zconf.h.in, zlib/zlib.h, zlib/zutil.c,
+ zlib/zutil.h:
+ Top level directory reorg Move src/po -> po Combine common and
+ compat -> lib/util Move zlib -> lib/zlib
+ [d699ccb60e7e]
+
+ * configure, ltmain.sh, m4/libtool.m4:
+ libtool patches for HP-UX to support DESTDIR
+ [9df98a9582bd]
+
+ * pp:
+ Update polypkg from trunk.
+ [4dc362248196]
+
+ * plugins/sudoers/sssd.c, plugins/sudoers/sudo_nss.c:
+ Fix sssd compiler warnings and fix the sha2 digest support.
+ [2975b030b298]
+
+2014-06-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Don't call gss_krb5_ccache_name() with a NULL pointer when restoring
+ the old credential cache file name. This can happen if there was no
+ old name returned by gss_krb5_ccache_name(). Fixes a crash on
+ kerberized LDAP on some platforms.
+ [4090029e463e]
+
+2014-06-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, doc/CONTRIBUTORS, plugins/sudoers/po/el.mo,
+ plugins/sudoers/po/el.po:
+ Add Greek PO file for sudoers from translationproject.org
+ [6c0cc2def911]
+
+2014-05-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c, src/exec_pty.c:
+ Ignore signals sent by the command's process group, not just the
+ command itself. If we cannot determine the process group ID of the
+ sender (as it may no longer exist), just check the process ID.
+ [7ffa2eefd3c0]
+
+2014-05-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ In handler_user_only() only forward the signal if it was not
+ generated by the command. This should fix a problem with programs
+ that catch SIGTSTP, perform cleanup, and then re-send the signal to
+ their process group (of which sudo is the leader).
+ [d590c899e194]
+
+ * src/exec.c, src/exec_pty.c, src/signal.c:
+ Handle EINTR from write(2) when writing to pipes and socket pairs.
+ [d26a40d21d7a]
+
+2014-05-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/po/nb.mo, plugins/sudoers/po/nb.po:
+ Norwegian Bokmaal translation for sudoers from
+ translationproject.com
+ [92e4aea46c1e]
+
+2014-05-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, doc/CONTRIBUTORS, src/po/nb.mo, src/po/nb.po:
+ Norwegian Bokmaal translation for sudo from translationproject.com
+ [3497f74028fe]
+
+2014-05-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in,
+ plugins/sudoers/visudo.c:
+ Try to be clearer about which are the input and output files in
+ export mode.
+ [66167511a410]
+
+ * plugins/sudoers/visudo_json.c:
+ In -x mode, require that the input and output files be different.
+ This won't currently catch collisions between the output file and an
+ include file.
+ [0c19b82a75e7]
+
+ * plugins/sudoers/bsm_audit.h, plugins/sudoers/linux_audit.h:
+ BSM and Linux audit do not yet use the argc function argument.
+ [3291695d1dfb]
+
+ * plugins/sudoers/audit.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/bsm_audit.c,
+ plugins/sudoers/bsm_audit.h, plugins/sudoers/linux_audit.h,
+ plugins/sudoers/logging.c, plugins/sudoers/logging.h,
+ plugins/sudoers/sudoers.c:
+ Pass argc to audit functions too. Will be needed for Solaris audit
+ support.
+ [d2114897a44e]
+
+2014-05-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/fatal.c, include/fatal.h, plugins/sudoers/policy.c:
+ Do not allow the same callback function to be registered more that
+ once in fatal_callback_register(). Add fatal_callback_deregister()
+ to deregister a callback.
+ [eff74fb9d274]
+
+ * MANIFEST, plugins/sudoers/regress/sudoers/test15.in,
+ plugins/sudoers/regress/sudoers/test15.out.ok,
+ plugins/sudoers/regress/sudoers/test15.toke.ok,
+ plugins/sudoers/regress/sudoers/test16.in,
+ plugins/sudoers/regress/sudoers/test16.out.ok,
+ plugins/sudoers/regress/sudoers/test16.toke.ok:
+ Add trivial sudoedit parsing tests.
+ [291ba6f4d6fd]
+
+ * MANIFEST, plugins/sudoers/po/ca.mo, plugins/sudoers/po/ca.po:
+ Catalan translation for sudoers from translationproject.org.
+ [b102f8cfeed1]
+
+2014-05-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po,
+ src/po/ca.mo, src/po/ca.po, src/po/gl.mo, src/po/gl.po:
+ Sync with translationproject.org
+ [62e5b4842834]
+
+2014-05-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ lockf() is broken on the Hurd -- use flock instead Bug #647
+ [7b8935a0c8b9]
+
+ * plugins/sudoers/visudo.c:
+ Don't try to install the temporary sudoers file if we didn't edit
+ it. By default, visudo does not edit files in a #includedir. Fixes a
+ NULL pointer defef on GNU hurd; Bug #647
+ [3a677c4773e5]
+
+2014-05-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/regress/ttyname/check_ttyname.c:
+ When comparing tty names, resolve the tty for fds 0-3 and compare
+ each one instead of just using the first that resolves.
+ [c37946b280a5]
+
+ * compat/getgrouplist.c, configure, configure.ac:
+ Solaris 8 doesn't export _nss_initf_group() so we need to provide
+ out own for getgrouplist().
+ [d494b39e9376]
+
+2014-05-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/getgrouplist.c, plugins/group_file/group_file.c,
+ plugins/system_group/system_group.c:
+ deal with NULL gr_mem here too
+ [0db43ed71001]
+
+ * NEWS, configure, configure.ac:
+ Sudo 1.8.10p3
+ [3f415a180023]
+
+2014-05-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/check.c,
+ plugins/sudoers/env.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/logging.c, plugins/sudoers/logging.h,
+ plugins/sudoers/parse.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/timestamp.c:
+ Rename log_warning flags and only send mail if SLOG_SEND_MAIL is set
+ instead of mailing by default like we used to.
+ [5b3882833aa1]
+
+ * plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/check.c,
+ plugins/sudoers/env.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/logging.c, plugins/sudoers/logging.h,
+ plugins/sudoers/parse.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/timestamp.c:
+ Add log_warningx
+ [feef646cb8b1]
+
+ * src/exec_pty.c:
+ Add debugging info for when we delete I/O events that still have
+ buffered data in them.
+ [7f17992cdf22]
+
+ * common/event.c:
+ Fix non-blocking mode. We only want to exit the event loop when
+ poll() or select() returns 0 and there are no active events. This
+ fixes a problem on some systems where the last buffer was not being
+ written when the command exited.
+ [deb6b1a7b241]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Change return value of switch_dir() to an int so we can distinguish
+ between an error and an empty dir in push_includedir().
+ [d0462b84782e]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Move code to fill in the list of dirs out of switch_dir and into its
+ own function. Quiets a false positive from cppcheck which got
+ confused due to variable reuse.
+ [6d6296f46255]
+
+ * plugins/sudoers/audit.c:
+ Avoid unused variable warning if auditing is not supported.
+ [5e6fd2ffe039]
+
+2014-05-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ Fix library order when linking binaries.
+ [3fec51f98ae1]
+
+ * plugins/sudoers/getdate.c, plugins/sudoers/getdate.y:
+ Include limits.h and inttypes.h for SIZE_MAX define.
+ [41f8be660384]
+
+ * include/missing.h, plugins/sudoers/env.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y:
+ Move SIZE_MAX compat define into missing.h where it belongs.
+ [1bb108cf9df3]
+
+2014-04-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/logging.c,
+ plugins/sudoers/logging.h, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.c:
+ Remove now-unused log_fatal()
+ [53478df3bb1e]
+
+ * plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/env.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Eliminate calls to fatal()/fatalx()/log_fatal() in env.c and just
+ pass back a return value.
+ [d7f2be8f2740]
+
+2014-04-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/boottime.c, plugins/sudoers/sudoers.h:
+ Make get_boottime() return bool.
+ [9ff15a995d01]
+
+ * doc/CONTRIBUTORS, plugins/sudoers/boottime.c:
+ Fix fd leak on Linux when determing boot time. This is usually
+ masked by the closefrom() call in sudo. From Jamie Anderson. Bug
+ #645
+ [0b4c430e8b88]
+
+2014-04-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/audit.c:
+ Handle the (currently impossible) case where both BSM and Linux
+ auditing are supported. Pacifies cppcheck.
+ [899cd6b5e487]
+
+ * plugins/sudoers/iolog.c:
+ Don't call ferror() on a closed stream, just check the return value
+ of fclose() instead. Found by cppcheck.
+ [e843f3c8f5d8]
+
+2014-04-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS, plugins/sudoers/auth/pam.c:
+ Use calloc() instead of malloc(n * s) followed by memset(). From
+ Jean-Philippe Ouellet.
+ [f416cebd3d8e]
+
+ * plugins/sudoers/sudoers.c:
+ Format string safety in error path.
+ [956fd6dbba80]
+
+ * common/alloc.c, common/event_poll.c, common/gidlist.c,
+ common/sudo_conf.c, include/alloc.h, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/env.c, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/pwutil_impl.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/visudo.c,
+ src/env_hooks.c, src/exec_common.c, src/parse_args.c, src/selinux.c,
+ src/sudo.c, src/sudo_edit.c, src/ttyname.c:
+ Rename emalloc2() -> emallocarray() and erealloc3() ->
+ ereallocarray().
+ [db3941093c68]
+
+ * compat/Makefile.in, mkdep.pl, plugins/sudoers/Makefile.in:
+ Add missing rule for building sha2.lo when not supported by libc or
+ libmd.
+ [70a16e10ddcd]
+
+2014-04-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.in:
+ Disable I/O logging for halt and poweroff in addition to reboot in
+ commented out example.
+ [40a7f11686ce]
+
+ * doc/CONTRIBUTORS, plugins/sudoers/auth/pam.c:
+ Use PAM_REINITIALIZE_CRED instead of PAM_ESTABLISH_CRED when
+ changing the user. This is the correct flag to use with a program
+ that changes the uid like su or sudo and fixes a role problem on
+ Solaris. From Gary Winiger; Bug #642
+ [ec23c3bf41bb]
+
+ * plugins/sudoers/defaults.c:
+ pam_setcred should default to true; from Gary Winiger Bug #642
+ [23e6628ec546]
+
+2014-04-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/logging.c,
+ plugins/sudoers/parse.c, plugins/sudoers/policy.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/timestamp.c:
+ Make set_perms() and restore_perms() return an error instead of
+ calling exit() on failure.
+ [b1a1a36abdb4]
+
+ * plugins/sudoers/sudoers.c:
+ Eliminate calls to fatal() in sudoers.c and just pass back a return
+ value.
+ [e4d87a036f6d]
+
+ * plugins/sudoers/logging.c:
+ Elimate calls to fatal() in the logging code.
+ [9847acdf7066]
+
+2014-04-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/regress/atofoo/atofoo_test.c:
+ Quiet a compiler warning on Solaris.
+ [3b9827834800]
+
+ * MANIFEST, common/Makefile.in, compat/Makefile.in, compat/sha2.c,
+ compat/sha2.h, config.h.in, configure, configure.ac, m4/sudo.m4,
+ plugins/sudoers/Makefile.in, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.h, plugins/sudoers/gram.y,
+ plugins/sudoers/match.c,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/regress/sudoers/test14.toke.ok,
+ plugins/sudoers/sha2.c, plugins/sudoers/sha2.h,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Move the sha2 code into libreplace and add configure checks for
+ SHA224Update in libc and libmd. Solaris uses "void *" where we use
+ "unsigned char *" so we need a check for that too. Solaris sha2.h
+ defines SHA224, SHA256, SHA384, and SHA512 so rename those tokens.
+ Adapted from changes from Vladimir Marek in bug #641.
+ [cd02732f0704]
+
+ * MANIFEST, plugins/sudoers/match.c,
+ plugins/sudoers/regress/testsudoers/test6.out.ok,
+ plugins/sudoers/regress/testsudoers/test6.sh,
+ plugins/sudoers/regress/testsudoers/test7.out.ok,
+ plugins/sudoers/regress/testsudoers/test7.sh:
+ Fix matching of uids and gids broken in sudo 1.8.9.
+ [315eff4add59]
+
+ * plugins/sudoers/testsudoers.c:
+ Fix -P option in usage()
+ [50753b6222b7]
+
+2014-04-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c, plugins/sudoers/prompt.c,
+ plugins/sudoers/set_perms.c:
+ Remove a few more unnecessary uses of fatal().
+ [8cfb205831dc]
+
+ * plugins/sudoers/auth/sudo_auth.c:
+ Use log_warning() not log_fatal() for the "Invalid authentication
+ methods compiled into sudo" message. We return -1 on error anyway.
+ [c8da5cf74348]
+
+ * plugins/sudoers/policy.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Return MODE_ERROR from sudoers_policy_deserialize_info() instead of
+ calling fatalx().
+ [6faefdd188f2]
+
+ * common/gidlist.c, src/sudo.c:
+ parse_gid_list() now returns -1 on error instead of calling
+ fatalx().
+ [ccf19c4a0d5b]
+
+2014-04-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ Forward SIGINFO to running command if supported. If the command is
+ being run in the background (or exec_background is set in sudoers),
+ it is the sudo process, not the actual command, that receives the
+ ^T.
+ [d2b020bdf0d5]
+
+ * plugins/sudoers/defaults.h, plugins/sudoers/iolog.c,
+ plugins/sudoers/iolog_path.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/testsudoers.c:
+ Remove calls to log_fatal() in I/O log functions and just pass an
+ error back to the caller.
+ [e89593d9dc35]
+
+2014-04-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/alloc.c, plugins/sudoers/env.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/policy.c,
+ plugins/sudoers/prompt.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/testsudoers.c:
+ Make "internal error, %s overflow" arguments consistent, using
+ __func__ where possible (when debugging is allowed).
+ [84e2c40d101b]
+
+2014-03-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/toke_util.c, src/net_ifs.c:
+ Use common printf format when warning of buffer overflow prevention.
+ [8b0d732b0eae]
+
+ * Makefile.in:
+ Remove init.d/*.sh in distclean
+ [99cd1eaf4684]
+
+ * .hgignore:
+ Correctly ignore init.d/*.sh
+ [04aabe1893e5]
+
+ * plugins/sudoers/ldap.c:
+ Remove remaining calls to fatalx(); just pass the error to the
+ caller.
+ [a8bcf903d84b]
+
+2014-03-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/pwutil.c, plugins/sudoers/sudoers.h:
+ Make a password/group cache collision a warning rather than fatal.
+ This should not be possible in practice and we can safely return the
+ new (potentially duplicate) item as it will be freed by the caller.
+ Make sudo_set_grlist() return an error on failure instead of calling
+ fatalx().
+ [5e8d3006862d]
+
+ * plugins/sudoers/timestamp.c:
+ Use log_warning() instead of log_fatal() if the ticket or lecture
+ path is too long and just return an error. This can only happen from
+ a misconfiguration so just ignoring the ticket/lecture file is safe.
+ [864c5de8345b]
+
+ * plugins/sudoers/find_path.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ In find_path(), return NOT_FOUND_ERROR instead of calling fatal() if
+ the path is too long. Remove an extraneous check against PATH_MAX in
+ set_cmnd() since find_path() already contains such a check.
+ [183106753690]
+
+ * plugins/sudoers/sudoers.h:
+ Remove unused MODE_LISTDEFS define and correct a comment.
+ [fb47e59ce5fe]
+
+ * plugins/sudoers/hexchar.c, plugins/sudoers/match.c,
+ plugins/sudoers/toke_util.c:
+ Make hexchar() return -1 on invalid input instead of calling
+ fatalx(). Callers used to check that the string was hex before
+ calling hexchar(). Now callers must check for a -1 return value
+ instead.
+ [1be217c71ce7]
+
+ * plugins/sudoers/audit.c, plugins/sudoers/bsm_audit.c,
+ plugins/sudoers/bsm_audit.h, plugins/sudoers/linux_audit.c,
+ plugins/sudoers/logging.h, plugins/sudoers/sudoers.c:
+ Propagate errors in audit code to caller instead of using fatal().
+ If we fail to audit an otherwise successful command, return an error
+ from the policy. For Linux audit, sudo may be compiled with audit
+ support but auditing may not be setup, so we don't consider that an
+ error.
+ [9a5753bfcb95]
+
+ * plugins/sudoers/boottime.c:
+ Remove unused variable on Linux.
+ [f63d7b86797d]
+
+ * plugins/sudoers/timestamp.c:
+ Fix warning on systems where mode_t is not unsigned int (Solaris).
+ [acd1457c23ec]
+
+2014-03-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/env.c, plugins/sudoers/sudoers.c:
+ Audit path too long errror. Add comments about non-audit events and
+ placeholders for future audit hooks.
+ [434ee47c83dc]
+
+2014-02-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/API, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/auth/sudo_auth.h:
+ Remove unused FLAG_USER auth flag. We have no auth methods that
+ require that authentication be run as the invoking user.
+ [4a9a9f557cb1]
+
+2014-03-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/net_ifs.c:
+ Fix aliasing warning in old-style interface probe code.
+ [1d6ce6f46da1]
+
+ * plugins/sudoers/set_perms.c:
+ Fix some sign comparision warnings.
+ [20c6068db104]
+
+ * common/aix.c, common/gidlist.c, compat/getgrouplist.c,
+ include/sudo_util.h, src/sudo.c:
+ Don't call fatal/fatalx in common/*.c
+ [ebf5e55a1ec1]
+
+2014-03-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c, plugins/sudoers/prompt.c,
+ plugins/sudoers/sudoers.h:
+ Fix expansion of %p in the prompt for "sudo -l" when rootpw, runaspw
+ or targetpw is set. Bug #639
+ [dff0208d1194]
+
+2014-03-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.ac:
+ Sudo 1.8.10p2
+ [774ebec63b41]
+
+ * plugins/sudoers/timestamp.c:
+ Don't write an empty timestamp record when timestamp_timeout is
+ zero. If we find an empty record in the timestamp file, overwrite it
+ with a good one, truncating the file as needed.
+ [9c226d81b660]
+
+2014-03-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in:
+ Fix typos in description of the -x option. Bug #637
+ [6ff2bfaaf99d]
+
+2014-03-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.ac:
+ Sudo 1.8.10p1
+ [33828a3385ad]
+
+ * plugins/sudoers/timestamp.c:
+ Fix typo/thinko that prevented "Defaults !tty_tickets" from working.
+ [f65cc29dbcc7]
+
+ * plugins/sudoers/parse.c:
+ Fix "sudo -l command" output when the matching command is negated.
+ Bug #636
+ [b4a92803f733]
+
+2014-03-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/Makefile.in, common/regress/atofoo/atofoo_test.c,
+ common/regress/sudo_conf/test5.err.ok,
+ common/regress/tailq/hltq_test.c:
+ The atofoo_test and hltq_test tests now display their own test error
+ rate. Display pass/fail count separately for sudo_conf and
+ sudo_parseln tests. Check stderr output for the sudo_conf test.
+ [5c814709ac70]
+
+ * src/Makefile.in:
+ Don't run the check_ttyname test if cross compiling.
+ [874ecc1c3db0]
+
+ * plugins/sudoers/Makefile.in:
+ CWD no longer used.
+ [13b2f3c4269b]
+
+ * plugins/sudoers/Makefile.in:
+ Fix diff of toke and err output files in "make check"
+ [485cdf3c75e7]
+
+2014-03-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/po/de.mo, src/po/de.po:
+ sync with translationproject.org
+ [d246c72a2350]
+
+2014-03-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Check whether ber.h is needed before ldap.h even if we are not using
+ any ber functions. Needed for older versions of nss ldap.
+ [c2310324dc34]
+
+ * plugins/sudoers/sssd.c:
+ Fix compiler warning in debug code.
+ [8ee4cb6cafad]
+
+ * MANIFEST, NEWS, doc/CONTRIBUTORS, src/po/ca.mo, src/po/ca.po:
+ Catalan translation for sudo from translationproject.org.
+ [d6af7d06ee36]
+
+2014-03-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Document negation fix in JSON output.
+ [37a85423ae49]
+
+2014-03-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo_json.c:
+ Fix handling of '!' operator when converting sudoers. We now add a
+ "negated" boolean flag to objects that have the '!' operator.
+ [071926c10280]
+
+2014-03-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, NEWS, plugins/sudoers/po/cs.mo, plugins/sudoers/po/cs.po:
+ Czech translation for sudoers from translationproject.org
+ [c0aae297f7c1]
+
+2014-02-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Try -libmldap before -lldap in case there is no link from
+ libibmldap.so to libldap.so. Since IBM ldap is installed under /opt
+ we should only be able to reach it if --with-ldap was given an
+ explicit path.
+
+ Only check for ber_set_option() if LBER_OPT_DEBUG_LEVEL is defined.
+ [89d50c29d737]
+
+2014-02-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/set_perms.c:
+ Fix typo in setreuid() PERM_ROOT error message.
+ [533415f53165]
+
+ * mkpkg:
+ No longer need to disable setresuid() on debian.
+ [96ba687c35f0]
+
+2014-02-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/timestamp.c:
+ Fix conversion of timestamp_timeout from double to struct timeval.
+ Also quiet a printf format warning on 32-bit systems.
+ [59d1f3094dda]
+
+2014-02-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, NEWS, plugins/sudoers/po/sr.mo, plugins/sudoers/po/sr.po:
+ Serbian translation for sudoers from translationproject.org.
+ [7134b386d658]
+
+2014-02-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS:
+ Add Ingo Schwarze
+ [114cdf286987]
+
+ * NEWS, plugins/sudoers/visudo_json.c:
+ When exporting sudoers in JSON format, use the same type of Options
+ object for both Defaults and Cmnd_Specs.
+ [caa57043e197]
+
+2014-02-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/inet_pton.c:
+ Silence cppcheck false positive.
+ [b2781c42a80f]
+
+ * plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po:
+ sync with translationproject.org
+ [baba43a6d682]
+
+ * NEWS, doc/UPGRADE:
+ Mention init.d scripts on AIX and HP-UX Mention sudoers group
+ mismatch fix
+ [0259cb1f7cae]
+
+ * INSTALL:
+ Talk about clearing files at boot time, not reboot time since it
+ happens when the system comes up, not down.
+ [e8e480bc34fd]
+
+ * plugins/sudoers/sudoers.c:
+ We also need to open the sudoers file as root if there is a GID
+ mismatch.
+ [2fb2ba6fc4e6]
+
+ * sudo.pp:
+ Install /etc/rc.d/init.d/sudo and /etc/rc.d/rc2.d/S90sudo for AIX
+ rpm packages.
+ [4aca1d318599]
+
+2014-02-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/Makefile.in:
+ Remove init.d file and link in uninstall target.
+ [249a9f105cdd]
+
+ * configure, configure.ac, sudo.pp:
+ Fix INIT_DIR for real this time.
+ [5444eb1afbc5]
+
+ * configure, configure.ac, sudo.pp:
+ Use correct init.d dir on HP-UX. Fix pp warnings from rc.d and
+ init.d dirs.
+ [809b54ef95f8]
+
+ * .hgignore, MANIFEST, configure, configure.ac, init.d/aix.sh.in,
+ init.d/hpux.sh.in, src/Makefile.in, sudo.pp:
+ First cut add installing an init.d file for HP-UX and AIX to remove
+ old sudo timestamp files at boot time.
+ [ec6d35c62d88]
+
+2014-02-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Use .Ar macro instead of "file ..." Use ".Cm -" instead of ".Li -"
+ for the default login class. From Ingo Schwarze.
+ [f13ea603760e]
+
+ * doc/sudo.conf.mdoc.in, doc/sudo.mdoc.in, doc/sudo_plugin.mdoc.in,
+ doc/sudoers.ldap.mdoc.in, doc/sudoers.mdoc.in,
+ doc/sudoreplay.mdoc.in, doc/visudo.mdoc.in:
+ Remove some extraneous markup; from Ingo Schwarze
+ * No need to explicitly end a macro with No before | because | counts
+ as middle punctuation and falls out of the macro, anyway.
+ * No need to explicitly re-open in-line macros after | because |
+ counts as middle punctuation and the macros resume afterwards,
+ anyway.
+ * Simplify the mnemonic remarks regarding the option letters, no need
+ for manual font and spacing control with No and Ns.
+ * Trim Ns No to just Ns, it already implies No.
+ [cc63d66c6655]
+
+ * doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Move zerowidth space in :alpha: after the colon for consistency.
+ [799f6656c6e8]
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.man.in, doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudoers.cat, doc/sudoers.ldap.man.in, doc/sudoers.man.in,
+ doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/visudo.cat,
+ doc/visudo.man.in:
+ regen
+ [14d682732b6f]
+
+ * doc/sudo.mdoc.in, doc/sudoreplay.mdoc.in, doc/visudo.mdoc.in:
+ Remove extraneous keeps in SYNOPSIS now that mandoc does implied
+ keeps when converting from mdoc to man.
+ [0f48fc289f29]
+
+ * doc/sudoers.mdoc.in:
+ Properly escape the : in :alpha:
+ [e41d4533a55f]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Replace some uses of .Sy with .Ar, .Ev and .Pa as appropriate. From
+ Jan Stary.
+ [90ec488905de]
+
+2014-02-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo_json.c:
+ Fix indentation of Defaults entries. The initial indent should be
+ outside the loop iterating over the entries.
+ [dc493c888fb2]
+
+2014-02-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po:
+ sync with translationproject.org
+ [fc517bc0908e]
+
+ * common/aix.c, common/alloc.c, common/atoid.c, common/atomode.c,
+ common/fatal.c, common/gidlist.c, common/sudo_conf.c,
+ common/sudo_debug.c, compat/strsignal.c, compat/strtonum.c,
+ plugins/sudoers/audit.c, plugins/sudoers/bsm_audit.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/locale.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/visudo.c, plugins/sudoers/visudo_json.c,
+ src/locale_stub.c, src/net_ifs.c, src/sesh.c, src/sudo.h:
+ We must include gettext.h before missing.h as it includes system
+ headers. Also add missing DEFAULT_TEXT_DOMAIN defines in sudoers
+ audit code that does not include sudoers.h.
+ [3ac4aa43ce40]
+
+ * common/sudo_dso.c:
+ When emulating DSO_NEXT with shl_get() we need to skip the program's
+ handle. This used to be documented as being index -2 but now it
+ seems to be index 0. As this is not guaranteed we need to look up
+ the real handle value for PROG_HANDLE and skip it when interating
+ through all the DSOs. Fixes infinite recursion on HP-UX in the
+ getenv() replacement.
+ [ade1b3045232]
+
+ * src/env_hooks.c:
+ Export getenv() so it is visible to shared objects we link with.
+ [1ac08446a3a7]
+
+2014-02-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/regress/atofoo/atofoo_test.c,
+ common/regress/sudo_conf/conf_test.c,
+ common/regress/sudo_parseln/parseln_test.c,
+ common/regress/tailq/hltq_test.c,
+ plugins/sudoers/regress/parser/check_fill.c:
+ Add some initprogname() calls to the test programs.
+ [e4320585a88b]
+
+2014-02-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [038d066a866d]
+
+ * doc/UPGRADE:
+ Mention that there is now a default LDAP search filter.
+ [6351da3f8377]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ Minor word choice change.
+ [7e59ab3eb453]
+
+ * NEWS, doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/defaults.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/match.c:
+ Add use_netgroups sudoers option. For LDAP-based sudoers, netgroup
+ support requires an expensive substring match on the server. If
+ netgroups are not needed, this option can be disabled to reduce the
+ load on the LDAP server.
+ [e6bd6c103390]
+
+2014-02-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Update copyright year.
+ [1299eed430a5]
+
+ * NEWS:
+ Mention LDAP changes.
+ [512b1e363587]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, plugins/sudoers/ldap.c:
+ Use a default LDAP search filter of (objectClass=sudoRole). When
+ constructing the netgroup query, add (sudoUser=*) to the query so we
+ don't fall below the 3 character OpenLDAP substring threshold.
+ Otherwise the index for sudoUser will never be used for that query.
+ Pointed out by Michael Stroeder.
+ [54856973af41]
+
+ * plugins/sudoers/timestamp.c:
+ Don't warn about an insecure lecture dir twice. Display warnings in
+ the user's locale.
+ [2c56b8b6d6f9]
+
+2014-02-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Mention the fix for ^Z at the password prompt when sudo was started
+ in the background.
+ [352d52ad1f7d]
+
+ * common/term.c, src/exec_pty.c:
+ In term_restore(), only restores the terminal if we are in the
+ foregroup process group. Instead of calling tcgetpgrp(), which is
+ racy, we set a temporary handler for SIGTTOU and check whether it
+ was received after a failed call to tcsetattr().
+ [94979d51daa2]
+
+ * MANIFEST, compat/getaddrinfo.c, compat/inet_pton.c, config.h.in,
+ configure, configure.ac, doc/LICENSE, include/missing.h, mkdep.pl,
+ plugins/sudoers/interfaces.c, plugins/sudoers/match_addr.c:
+ Use inet_pton() instead of inet_aton() and include a version from
+ BIND for those without it.
+ [fe61a27c76d3]
+
+ * common/regress/atofoo/atofoo_test.c:
+ Quiet a gcc warning.
+ [f197821892ea]
+
+ * compat/getaddrinfo.c:
+ Need to include limits.h for USHRT_MAX.
+ [d1d8bd9a0e01]
+
+2014-02-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/term.c, include/sudo_util.h:
+ Use bool for function return values instead of 1 or 0.
+ [99e357c0800b]
+
+ * configure, configure.ac:
+ Warn the user if the rundir needs to be cleared in the rc files.
+ Neither AIX not HP-UX clear /var/run (if it even exists).
+ [6cdbf57a2f9e]
+
+ * NEWS:
+ Update for sudo 1.8.9p5
+ [efb737c32615]
+
+ * src/preserve_fds.c:
+ When the closefrom limit is greater than any of the preserved fds,
+ the pfds list will be non-empty but lastfd will be -1 triggering an
+ ecalloc(0) assertion. Instead, test for lastfd being -1 and make
+ sure we always update it, even if dup() fails. Also restore initial
+ value of lowfd after we are done relocating. Fixes bug #633
+ [a11206a31f28]
+
+ * common/term.c:
+ Document function return values.
+ [267bc85f6fbb]
+
+2014-02-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ term_restore() now restarts itself so we don't need to do it
+ ourselves.
+ [a17e885d0b0a]
+
+ * common/term.c:
+ syscall restarting is broken on Mac OS X when interrupted by a tty
+ signal so restart tcsetattr() by hand. For details, see.
+ http://openradar.appspot.com/radar?id=6402578615107584
+ [3997b2a0577e]
+
+ * MANIFEST, common/Makefile.in, common/regress/atofoo/atofoo_test.c:
+ Add regress for atobool(), atoid() and atomode()
+ [e1cbdf86d6e2]
+
+ * plugins/sudoers/Makefile.in:
+ Add back boottime.lo
+ [0b7ddc31e13e]
+
+ * INSTALL:
+ Mention that rundir and vardir may be the same and what to do if
+ they are.
+ [301df9a31d43]
+
+ * MANIFEST, doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/boottime.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/timestamp.c:
+ Bring back boot time checking code and zero out time stamp files
+ that predate the boot time. This should help systems w/o /var/run
+ where the admin has setup rc.d to clear the timestamp directory.
+ [e09389a8b1ca]
+
+ * configure, configure.ac:
+ Check libraries for inet_pton() if not in libc.
+ [9f9bd83895e8]
+
+2014-02-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Fix clock_gettime() detection when it lives in librt. Some systems
+ have inet_aton() in libresolv (older Solaris).
+ [e5f7c8bc9a81]
+
+ * sudo.pp:
+ Avoid duplicate directories if vardir and rundir are the same.
+ [c5df5ebc191b]
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [740b2cc42fea]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Elaborate on time stamp error message causes.
+ [2838fea2e21a]
+
+2014-02-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Remove the time stamp dir and its contents when uninstalling. We
+ currently leave the lecture status files installed until there is a
+ better way to detect upgrades.
+ [61532b7113ff]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Update time stamp error messages and regen.
+ [edf570c98cd5]
+
+ * plugins/sudoers/timestamp.c:
+ Restore warning when sudoers is unable to update the time stamp
+ file.
+ [86648a771250]
+
+ * INSTALL, Makefile.in, configure, configure.ac, doc/sudoers.mdoc.in,
+ m4/sudo.m4, plugins/sudoers/Makefile.in, sudo.pp:
+ Replace --with-timedir and --with-lecture_dir with --with-rundir and
+ --with-vardir which are the parent directories of the time stamp and
+ lecture dirs. These directories need to be searchable by non-root so
+ that the timestampowner setting can function.
+ [5c38d77a2d0c]
+
+ * plugins/sudoers/timestamp.c:
+ Fix use of timestampowner in the new time stamp world order. Parent
+ directories for timestampdir and lecture_dir are now created with
+ the execute bit set so that we can traverse them as non-root.
+ [9ff6f07c0a5d]
+
+2014-01-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in:
+ Regen Makefiles.
+ [59542bcdb222]
+
+ * common/sudo_debug.c, config.h.in, include/sudo_util.h,
+ plugins/sample/sample_plugin.c:
+ Move ctim_get and mtim_get to sudo_util.h
+ [d565391f5491]
+
+ * plugins/sudoers/timestamp.c:
+ sprinkle some debug printfs and add function header comments
+ [1842d9b8170d]
+
+ * plugins/sudoers/timestamp.c:
+ Properly handle the case where /var/run/sudo/ts doesn't exist.
+ [895f3ad6ad60]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ fix typo
+ [50041ebb6ce6]
+
+ * NEWS:
+ Mention "sudo -K" change.
+ [e99bd7657aae]
+
+ * doc/UPGRADE:
+ Upgrade info for 1.8.10
+ [0867718b9af5]
+
+2014-01-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/timestamp.c:
+ Warn on ftruncate failure().
+ [d2081876da25]
+
+ * plugins/sudoers/timestamp.c:
+ Fix checking of lecture status.
+ [e12d78234d17]
+
+ * mkpkg:
+ Do not override timedir on Debian.
+ [283fa2e69a0a]
+
+ * common/event.c, common/event_select.c, include/missing.h,
+ plugins/sudoers/iolog.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/visudo.c, src/sudo_edit.c:
+ Use sudo_timeval macros and remove compat macros from missing.h
+ [1de76d8b811e]
+
+ * INSTALL, MANIFEST, NEWS, compat/Makefile.in, compat/clock_gettime.c,
+ config.h.in, configure, configure.ac, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, include/missing.h,
+ include/sudo_util.h, m4/sudo.m4, mkdep.pl, pathnames.h.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/boottime.c,
+ plugins/sudoers/check.h, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in,
+ plugins/sudoers/defaults.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/timestamp.c, src/Makefile.in:
+ Switch to new time stamp file format. Each user now has a single
+ file which may contain multiple records when per-tty time stamps are
+ in use (the default). The time stamps use a monotonic timer where
+ available and are once again stored in /var/run/sudo. The lecture
+ status is now stored separately from the time stamps in a different
+ directory.
+ [7e16eb37bacc]
+
+2014-01-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/check.c:
+ When listing a user's privileges, always prompt the user for their
+ own password, regardless of the value of target_pw, root_pw or
+ runas_pw.
+ [73a13ccc7933]
+
+2014-01-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/atomode.c:
+ Zero out errstr when there is no error; fixes bug #632
+ [74950ef1a0dc]
+
+2014-01-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac, plugins/sudoers/interfaces.c,
+ plugins/sudoers/match_addr.c:
+ Use inet_aton() instead of inet_addr() as it allows us to
+ distinguish between the address (or mask 255.255.255.255) and an
+ error. In the future we may consider switching to inet_pton() for
+ IPv4 too.
+ [b6b4e4c77e9a]
+
+2014-01-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/missing.h:
+ Fix typo, ULONG_MAX vs. ULLONG_MAX
+ [5d274daa9fb1]
+
+ * plugins/sudoers/sudo_nss.c:
+ Fix typo in the AIX case.
+ [ee531c950fce]
+
+ * plugins/sudoers/sudo_nss.c:
+ Size pointer for sudo_parseln() should be size_t not ssize_t. This
+ was already correct for the nsswitch.conf case.
+ [cfaf895c1db4]
+
+2014-01-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, common/sudo_conf.c, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, include/sudo_conf.h, src/net_ifs.c:
+ It is now possible to disable network interface probing in sudo.conf
+ by changing the value of the probe_interfaces setting.
+ [e9dc28c7db60]
+
+2014-01-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/match_addr.c:
+ If inet_addr() returns INADDR_NONE, return false instead of
+ iterating through the interfaces looking for a match that will never
+ happen.
+ [1559c301caec]
+
+ * configure, configure.ac, src/Makefile.in:
+ Add explicit dependency on sudoers.la to sudo target when sudoers is
+ compiled statically into the sudo binary.
+ [d08cc66e18bd]
+
+2014-01-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/getdate.c, plugins/sudoers/getdate.y,
+ plugins/sudoers/iolog_path.c, plugins/sudoers/logging.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/timestr.c:
+ Do not assume localtime(), gmtime() and ctime() always return non-
+ NULL.
+ [a1b5b67436de]
+
+2014-01-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, common/Makefile.in, compat/Makefile.in,
+ doc/Makefile.in, include/Makefile.in,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/system_group/Makefile.in,
+ src/Makefile.in, zlib/Makefile.in:
+ Update copyright years
+ [37d2aaa92544]
+
+ * plugins/sudoers/visudo_json.c:
+ Eliminate dead store found by clang checker.
+ [86874d5340f1]
+
+ * NEWS, configure, configure.ac:
+ Update for sudo 1.8.9p4
+ [f79ab7c6c1c5]
+
+ * common/sudo_debug.c, include/sudo_debug.h, src/preserve_fds.c:
+ When relocating fds, update the debug fd if it is set so we are
+ guaranteed to get debugging output.
+ [b1deaa472aa6]
+
+2014-01-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ If the event loop exits due to an error and we are not logging I/O,
+ kill the command if still running. Fixes a bug where sudo could exit
+ while the command was still running.
+ [844018ff8a8c]
+
+ * src/preserve_fds.c:
+ When relocating preserved fds, start with the highest ones first to
+ avoid moving fds around more than we have to. Now uses a bitmap to
+ keep track of which fds are being preserved. Fixes a bug where the
+ debugging fd could be relocated to the same fd as the error
+ backchannel temporarily, resulting in debugging output being printed
+ to the backchannel if util@debug was enabled.
+ [55e006dbeaf3]
+
+ * src/preserve_fds.c:
+ When restoring fds traverse list from high -> low, not low -> high
+ to avoid implicitly closing an fd we want to relocate.
+ [6351225f47d7]
+
+ * src/exec.c:
+ If not logging I/O we may get EOF when the command is executed and
+ the other end of the backchannel is closed. Just remove the
+ backchannel event in this case or we will continue to receive the
+ event. Bug #631
+ [a204b69d91f7]
+
+ * src/po/sr.mo, src/po/sr.po:
+ sync with translationproject.org
+ [987087ce4658]
+
+2014-01-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/ttyname.c:
+ Fix strtonum() usage when parsing /proc/self/stat on Linux. Bug #630
+ [3448dffe9701]
+
+ * NEWS, configure, configure.ac:
+ Update for sudo 1.8.9p3
+ [22e5a6f69999]
+
+ * plugins/sudoers/logwrap.c:
+ Remove dead store; found by cppcheck
+ [a59833af3401]
+
+2014-01-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sesh.c:
+ Quiet a cppcheck warning about a negative subscript.
+ [ab98b72f5bdf]
+
+ * src/exec_common.c, src/selinux.c, src/sesh.c, src/sudo_exec.h:
+ Make noexec parameter to sudo_execve() bool.
+ [daa75e4c248a]
+
+ * plugins/sudoers/sudoreplay.c:
+ Quiet a few innocuous cppcheck warnings.
+ [90ffa16d27b1]
+
+ * plugins/sudoers/sssd.c:
+ Handle in_res being NULL for sudo_debug_printf() in
+ sudo_sss_filter_result().
+ [8595cc05d2a8]
+
+ * plugins/sudoers/iolog.c:
+ When writing length to timing file, use %u not %d as it is unsigned.
+ [a7f2fcb6919e]
+
+ * plugins/sudoers/visudo_json.c:
+ Close export_fp in the error path too, but do not close stdout.
+ [5c918718ab45]
+
+ * plugins/sudoers/auth/secureware.c:
+ Move right brace outside #ifdef HAVE_DISPCRYPT; found by cppcheck.
+ [f2619d2eb7a8]
+
+2014-01-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/group_file/plugin_test.c:
+ Make this compile again
+ [f0ff8df475e8]
+
+ * common/term.c:
+ Add suppression line to quiet a bogus (inconclusive) cppcheck
+ warning.
+ [065207271e5d]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Do not leak old istack if realloc fails; found by cppcheck. Also
+ modify yyless() to avoid a harmless cppcheck warning every time it
+ is used.
+ [021077017a23]
+
+ * Makefile.in, common/Makefile.in, compat/Makefile.in,
+ doc/Makefile.in, include/Makefile.in,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/system_group/Makefile.in,
+ src/Makefile.in, zlib/Makefile.in:
+ Add cppcheck target to run cppcheck on all source files.
+ [d207c2ef49a2]
+
+2014-01-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.ac:
+ Update for sudo 1.8.9p2
+ [2e7fe6e371a4]
+
+ * config.h.in, configure, ltmain.sh, m4/libtool.m4, m4/ltoptions.m4,
+ m4/ltsugar.m4, m4/ltversion.m4, m4/lt~obsolete.m4:
+ Update to libtool-2.4.2.418
+ [d1dbed89d733]
+
+ * config.guess, config.sub:
+ Update from http://git.savannah.gnu.org/gitweb/?p=config.git
+ [2b5e32d23be5]
+
+2014-01-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Sudo 1.8.9 also fixes bug #617
+ [cc5c18228719]
+
+2014-01-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ The fix for the hang was already in the 1.8.9 tarballs.
+ [f038ebcc1071]
+
+ * NEWS, configure, configure.ac:
+ Update for sudo 1.8.9p1
+ [732fca0003cf]
+
+ * common/atobool.c, common/event.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/parse.h, src/exec.c, src/preserve_fds.c:
+ Update copyright year.
+ [fdeb5956810e]
+
+ * plugins/sudoers/parse.h:
+ Go back to making the bit fields in struct cmndtag explicitly
+ signed. This fixes a problem on gcc 4.8 (at least) which appears to
+ be treating the value as unsigned by default.
+ [46b9a7bb10ac]
+
+ * common/atobool.c:
+ Use debug_return_int() instead of bare return for debugging support.
+ [c273f822de5f]
+
+2014-01-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/event.c:
+ Fix infinite loop that could be triggered by sudo_ev_loopbreak() and
+ sudo_ev_loopcontinue().
+ [1723561c46b0]
+
+ * NEWS:
+ Update for 1.8.9 final.
+ [d49c14d21410]
+
+2014-01-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Handle a sequence file with no trailing newline.
+ [aa29306e4f6d]
+
+2014-01-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Truncate io log and timing files on open when recycling them. Only
+ an issue when the sequence number wraps around.
+ [01b2dfe15ff0]
+
+ * plugins/sudoers/iolog.c:
+ Repair reading of the iolog sequence number that got broken when
+ adding stricter strtoul() checks.
+ [e0f4a11c3437]
+
+ * src/exec.c:
+ If invoked as sudoedit we can't just exec the command directly since
+ the temporary files need to be updated before sudo exits.
+ [508503be1c4f]
+
+ * src/preserve_fds.c:
+ Fix restoration of the close-on-exec flag when moving a relocated fd
+ back into its original position.
+ [5572f1f8b48a]
+
+2014-01-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Add "see below" to reference "Secure editing" section in "Preventing
+ shell escapes".
+ [b2db990a36b3]
+
+2014-01-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Add initial "Secure editing" section.
+ [0d7a192e0e25]
+
+ * doc/LICENSE:
+ Update copyright year.
+ [4a639d9207a9]
+
+2013-12-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po, src/po/eo.mo,
+ src/po/eo.po, src/po/fi.mo, src/po/fi.po:
+ sync with translationproject.org
+ [5c15a411b10d]
+
+ * plugins/sudoers/policy.c:
+ Make user_cwd and user_tty dynamically allocated even for the
+ "unknown" case.
+ [015454bf97f8]
+
+2013-12-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Use -fstack-protector-strong in preference to -fstack-protector-all
+ or -fstack-protector.
+ [bdd1066eefc4]
+
+ * doc/HISTORY:
+ Dell acquired Quest
+ [3d5b7d27a313]
+
+2013-12-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po, src/po/ru.mo,
+ src/po/ru.po, src/po/vi.mo, src/po/vi.po:
+ sync with translationproject.org
+ [f964671d08ce]
+
+2013-12-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po,
+ src/po/cs.mo, src/po/cs.po, src/po/da.mo, src/po/da.po,
+ src/po/it.mo, src/po/it.po, src/po/pl.mo, src/po/pl.po,
+ src/po/pt_BR.mo, src/po/pt_BR.po, src/po/uk.mo, src/po/uk.po,
+ src/po/zh_CN.mo, src/po/zh_CN.po:
+ sync with translationproject.org
+ [5f5becf5fb7a]
+
+ * doc/sudoers.ldap.cat:
+ regen
+ [77745e6bc0d5]
+
+ * NEWS:
+ Update for recent changes.
+ [365b9084268a]
+
+ * plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c:
+ Fix typo; we want setlocale(LC_ALL, "") since we are setting the
+ locale for the first time.
+ [e2b9660e9d48]
+
+2013-12-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c:
+ Use sudoers_initlocale() in main() startup, not sudoers_setlocal()
+ as the latter assumes we are already in the user's locale which may
+ not be the case. For sudoreplay, we can just use setlocale()
+ directly as there is no sudoers locale.
+ [12235e50dea0]
+
+2013-12-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/preserve_fds.c, src/sudo.c, src/sudo.h:
+ Redo preserve_fds support to remap high fds so we can get the most
+ out of closefrom(). The fds are then restored after closefrom().
+ [7d712ec49db7]
+
+ * plugins/sudoers/Makefile.in:
+ Fix install-plugin when sudoers is compiled statically.
+ [36a8bf3b588d]
+
+2013-12-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/sudo_debug.c, doc/sudo_plugin.cat,
+ doc/sudo_plugin.man.in, doc/sudo_plugin.mdoc.in,
+ include/sudo_debug.h, include/sudo_plugin.h, src/Makefile.in,
+ src/exec.c, src/exec_pty.c, src/preserve_fds.c, src/sudo.c,
+ src/sudo.h, src/sudo_exec.h:
+ Add support for preventing fds from getting clobbered by
+ closefrom().
+ [269f45964ff0]
+
+2013-12-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ regen
+ [b8f458379b5b]
+
+2013-12-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/alloc.c:
+ Need to include limits.h here too.
+ [b53c6edef597]
+
+2013-12-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.ac, plugins/sudoers/parse.h:
+ No need to use __signed.
+ [05f9648d1953]
+
+ * plugins/sudoers/regress/logging/check_wrap.c:
+ Need limits.h here too.
+ [54aac3bbf66a]
+
+ * compat/closefrom.c:
+ Still need limits.h here.
+ [0abc6b2be208]
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [386b47ced07f]
+
+ * compat/closefrom.c:
+ Go back to using /proc/self/fd instead of /proc/$$/fd as only AIX
+ lacks /proc/self and it has F_CLOSEM.
+ [b5735fbcfdce]
+
+2013-12-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo_json.c:
+ Use a switch to map digest type to name instead of an array of
+ strings.
+ [ab17ceb4dd60]
+
+ * compat/closefrom.c:
+ Use /dev/fd in closefrom() on FreeBSD < 8.0 and Mac OS X.
+ [e70df3b3144b]
+
+ * compat/snprintf.c:
+ Remove _MAX and _MIN compat; we rely on missing.h for that. We
+ already require the compiler handle long long so there's no need to
+ use HAVE_LONG_LONG_INT everywhere.
+ [2bda15071439]
+
+ * common/ttysize.c, include/missing.h:
+ Remove _MAX and _MIN defines that any system from the last 20 years
+ should have. Add ULLONG_MAX in case it is missing.
+ [2db0cee4aaa8]
+
+ * doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in,
+ plugins/sudoers/visudo.c, plugins/sudoers/visudo_json.c:
+ Change visudo -x to take a file name argument, which may be '-' to
+ write the exported sudoers file to stdout.
+ [84cb72c3c391]
+
+ * plugins/sudoers/auth/bsdauth.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/parse.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/visudo.c,
+ plugins/sudoers/visudo_json.c, src/regress/ttyname/check_ttyname.c:
+ Move symbol extern defs into sudoers.h
+ [b631a0b57fae]
+
+ * plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/logging/check_wrap.c:
+ Add missing sudo_util.h
+ [ed0edc2e2d0c]
+
+2013-12-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ Warn if the time stamp in the I/O log file does not fit in time_t.
+ Warn if the info line is not well-formed instead of silently
+ ignoring it.
+ [37a050de5be5]
+
+2013-12-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/Makefile.in, plugins/sudoers/Makefile.in, src/Makefile.in:
+ Rename libcommon libsudo_util
+ [df3ffd4229e5]
+
+2013-12-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/Makefile.in, common/aix.c, common/atobool.c,
+ common/atoid.c, common/atomode.c, common/fmt_string.c,
+ common/gidlist.c, common/progname.c, common/setgroups.c,
+ common/sudo_conf.c, common/term.c, common/ttysize.c,
+ include/missing.h, include/sudo_util.h,
+ plugins/group_file/Makefile.in, plugins/group_file/getgrent.c,
+ plugins/sudoers/Makefile.in, plugins/sudoers/sudoers.h,
+ plugins/sudoers/sudoreplay.c, plugins/system_group/Makefile.in,
+ plugins/system_group/system_group.c, src/Makefile.in, src/sudo.h:
+ Move prototypes for functions provided by libcommon that don't have
+ their own header files into sudo_util.h.
+ [43f423a24416]
+
+2013-12-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in,
+ plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/logging.c, plugins/sudoers/logging.h,
+ plugins/sudoers/mkdefaults:
+ Now that we have proper number parsing functions we should store
+ T_UINT defaults values as unsigned int, not int.
+ [67d8c2244f1d]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h:
+ Don't use int where we really mean enum def_tuple. When this code
+ was written it was assumed that we may have multiple tuple types.
+ However, that hasn't happened and probably never will.
+ [8491f970f343]
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ Regen after string parsing changes.
+ [fd6bf79c3286]
+
+ * common/atoid.c, common/atomode.c, compat/strtonum.c, configure,
+ configure.ac, include/missing.h, plugins/sudoers/defaults.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/sudoreplay.c, src/parse_args.c, src/ttyname.c:
+ The OpenBSD strtonum() uses very short error strings that can't be
+ translated usefully. Convert them to longer strings on error. Also
+ use the longer strings for atomode() and atoid().
+ [dace028594da]
+
+2013-12-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/Makefile.in, common/atoid.c, common/atomode.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.h, src/sudo.c, src/sudo.h:
+ Add atomode() function for parsing a file mode.
+ [44e29629aa5e]
+
+ * common/sudo_conf.c, common/ttysize.c, compat/Makefile.in,
+ compat/closefrom.c, compat/getaddrinfo.c, compat/strtonum.c,
+ configure, configure.ac, include/missing.h,
+ plugins/sudoers/boottime.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/match_addr.c, plugins/sudoers/policy.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/sudoreplay.c, plugins/system_group/system_group.c,
+ src/parse_args.c, src/sudo.c, src/ttyname.c:
+ Use strtonum() instead of atoi(), strtol() or strtoul() where
+ possible.
+ [e4a1fc84b893]
+
+ * MANIFEST, compat/Makefile.in, compat/strtonum.c, config.h.in,
+ configure, configure.ac, include/missing.h, mkdep.pl:
+ Add strtonum.c to compat for simpler number parsing.
+ [a4c69b003da0]
+
+2013-12-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_common.c:
+ Fix a warning on Solaris, we need to use debug_return_const_ptr.
+ [932aa94c0cac]
+
+ * plugins/sudoers/Makefile.in:
+ check_symbols needs to link with SUDO_LIBS in order to get -lpthread
+ on HP-UX for libldap (which uses threads). It would be better to
+ have a separate variable for the pthread library but this is no
+ worse than it used to be.
+ [94591b765371]
+
+2013-12-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ add missing comma
+ [7dcbd1c6dd25]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Make -c option description more accurate.
+ [3f305ae6037e]
+
+2013-12-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS, plugins/sudoers/sudoers.c:
+ When checking whether a user may change the login class, just check
+ pw_uid of the runas user, which was passed in to set_loginclass().
+ [aaf736440441]
+
+2013-12-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo_json.c:
+ Use atoid() when parsing user/group IDs and print them as unsigned
+ int.
+ [40c77459a36a]
+
+2013-12-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ Correctly parse 64-bit times in I/O log files.
+ [d053ee75adc3]
+
+ * compat/getgrouplist.c, plugins/group_file/getgrent.c,
+ plugins/sudoers/pwutil.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/testsudoers.c:
+ Use atoid() not atoi() when parsing uids/gids.
+ [491146596626]
+
+ * plugins/sudoers/match.c, plugins/sudoers/match_addr.c,
+ plugins/sudoers/parse.h, plugins/sudoers/pwutil.c,
+ plugins/sudoers/pwutil.h, plugins/sudoers/pwutil_impl.c,
+ plugins/sudoers/sudoers.h:
+ Better match debugging. Sprinkle const in match functions.
+ [4cd8d793f165]
+
+2013-12-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in:
+ Document that plugins can be compiled statically into the sudo
+ binary.
+ [434061cf909f]
+
+2013-12-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sssd.c:
+ sudo_sss_filter_user_netgroup(): fix comment typos, break out of
+ loop early if we match ALL or netgroup.
+ [0691731f4b12]
+
+ * plugins/sudoers/sssd.c:
+ When filtering netgroups, use the passwd struct stashed in the
+ handle, not user_name since we may be listing another users
+ privileges.
+ [f2669cf7b70c]
+
+ * mkpkg:
+ RHEL 6 and above builds sudo with SSSD support
+ [afc3d894851e]
+
+ * plugins/sudoers/sssd.c:
+ Avoid passing NULL domainname to sudo_debug_printf().
+ [b08abe5e6d23]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document sssd debug subsystem.
+ [250c3ab1bcf0]
+
+ * doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in:
+ Document "event" debug subsystem.
+ [85d220b48edc]
+
+ * plugins/sudoers/match.c:
+ Use atoid() instead of atoi() when parsing uids/gids so we get
+ proper range checking.
+ [5c3e2f3f6cb9]
+
+ * plugins/sudoers/sssd.c:
+ Add user netgroup filtering for SSSD. Previously, rules for a
+ netgroup were applied to all even when they did not belong to the
+ specified netgroup. RedHat Bugzilla 880150.
+ [784848b5462c]
+
+ * plugins/sudoers/sssd.c:
+ Fix several issues found by the clang static analyzer; Daniel
+ Kopecek
+ [520261dd7461]
+
+2013-12-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README.LDAP:
+ Mention how to dump sudoers info from LDAP.
+ [a53c93790a30]
+
+ * src/exec_common.c:
+ On Solaris, disabling the proc_exec privilege appears to interfere
+ with DAC file permissions. Adding DAC override permissions to the
+ inheritable set works around this for commands run as root without
+ giving extra permissions to other users. Bug #626
+ [391ad44026c3]
+
+2013-12-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/Makefile.in, common/progname.c, compat/Makefile.in,
+ compat/getprogname.c, configure, configure.ac, include/missing.h,
+ mkdep.pl, plugins/sample/sample_plugin.c, plugins/sudoers/policy.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c, src/parse_args.c,
+ src/regress/ttyname/check_ttyname.c, src/sudo.c:
+ Instead of setprogname(), add initprogname() which gets the program
+ name for getprogname() using /proc or pstat() if possible.
+ [e2d48d81456f]
+
+2013-11-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/ttyname.c:
+ Ignore EOVERFLOW from pstat_getproc(). The HP-UX kernel appears to
+ return this in certain situations but it appears to be harmless at
+ least insofar as retrieving the tty goes.
+ [105bea4e1c20]
+
+ * plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po,
+ src/po/cs.mo, src/po/cs.po, src/po/eo.mo, src/po/eo.po,
+ src/po/fi.mo, src/po/fi.po, src/po/it.mo, src/po/it.po,
+ src/po/pl.mo, src/po/pl.po, src/po/pt_BR.mo, src/po/pt_BR.po,
+ src/po/ru.mo, src/po/ru.po, src/po/uk.mo, src/po/uk.po,
+ src/po/vi.mo, src/po/vi.po, src/po/zh_CN.mo, src/po/zh_CN.po:
+ Sync with translationproject.org
+ [3694d7ad4c9d]
+
+2013-11-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo.c:
+ Add missing newline in help message after export option.
+ [1c0bff0c181e]
+
+2013-11-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac, plugins/sudoers/Makefile.in,
+ src/Makefile.in:
+ Do not add LIBDL to SUDO_LIBS or SUDOERS_LIBS in configure, do it in
+ Makefile.in so we can make it last. Fixes a linking problem on
+ Ubuntu precise.
+ [f8d3bddbe742]
+
+2013-11-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, m4/ax_func_getaddrinfo.m4:
+ Do not rely on NULL being defined for getaddrinfo() test. Fixes the
+ check on HP-UX 11.23.
+ [a5dcf0283693]
+
+2013-11-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ Regen for sudo 1.8.9b1
+ [945f27a7aa1c]
+
+ * src/po/de.mo, src/po/de.po, src/po/sr.mo, src/po/sr.po:
+ Sync with translationproject.org
+ [52abae16ccfa]
+
+2013-11-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, MANIFEST, NEWS, common/Makefile.in, common/sudo_dso.c,
+ compat/Makefile.in, compat/dlfcn.h, compat/dlopen.c, config.h.in,
+ configure, configure.ac, include/sudo_dso.h, mkdep.pl,
+ plugins/sudoers/Makefile.in, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/ldap.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/sssd.c, plugins/system_group/Makefile.in,
+ plugins/system_group/system_group.c, src/Makefile.in,
+ src/env_hooks.c, src/load_plugins.c, src/preload.c, src/sudo.c,
+ src/sudo.h:
+ Add wrapper functions for dlopen() et al so that we can support
+ statically compiling in the sudoers plugin but still allow other
+ plugins to be loaded. The new --enable-static-sudoers configure
+ option will cause the sudoers plugin to be compiled statically into
+ the sudo binary. This does not prevent other plugins from being
+ loaded as per sudo.conf.
+ [9425770e9d2b]
+
+2013-11-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo_json.c:
+ Handle non-unix groups correctly. Get rid of runasuser and
+ runasgroup types and use username and usergroup instead. The fact
+ that the user or group is inside a Runas_List doesn't affect its
+ underlying type.
+ [ea1789258c11]
+
+2013-11-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo_json.c:
+ Simplify Defaults list option object. The name and value strings are
+ superfluous.
+ [5852b0184669]
+
+ * compat/dlopen.c:
+ Back out unintended change.
+ [85156e49e96e]
+
+ * MANIFEST, aclocal.m4, configure, configure.ac,
+ m4/ax_func_getaddrinfo.m4:
+ Add dedicated test for getaddrinfo(). Tru64 UNIX contains two
+ versions of getaddrinfo and we must include netdb.h to get the
+ proper definition.
+ [9882e3e1e8e3]
+
+ * compat/dlopen.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c:
+ Define RTLD_GLOBAL for older systems without it. Bug #621
+ [ed38ac84f1da]
+
+2013-11-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/snprintf.c, include/missing.h:
+ Rename snprintf replacement rpl_snprintf since we may now replace
+ the libc version and #define rpl_snprintf snprintf in missing.h so
+ we get our version when needed. This is consistent with how we
+ replace glob and fnmatch.
+ [309aa17d0dfe]
+
+ * common/Makefile.in, common/regress/sudo_conf/conf_test.c,
+ common/regress/sudo_parseln/parseln_test.c,
+ common/regress/tailq/hltq_test.c, src/Makefile.in:
+ libcommon tests need locale_stub.lo to link.
+ [baae40f36de5]
+
+ * MANIFEST, aclocal.m4, compat/snprintf.c, config.h.in, configure,
+ configure.ac, m4/ax_func_snprintf.m4:
+ Add check for C99 compliant (v)snprintf function.
+ [79e02551543c]
+
+ * compat/sig2str.c, configure, configure.ac:
+ Include unistd.h in sig2str.c for Tru64 as it defines SIGRTMIN and
+ SIGRTMAX in terms of sysconf(), which is prototyped in unistd.h. Bug
+ #621; from Daniel Richard G.
+ [2a59ccb8c966]
+
+ * include/gettext.h, plugins/sudoers/locale.c, src/locale_stub.c:
+ Add definition of U_ for --disable-nsl Don't define warning_gettext
+ if --disable-nsl Bug #621; from Daniel Richard G.
+ [c0054eb89c2b]
+
+2013-11-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo_json.c:
+ When merging Defaults entries we need to check the type of the next
+ entry and not just assume it is the same as the previous one.
+ [e97d9b9cf0d5]
+
+ * plugins/sudoers/visudo_json.c:
+ runasgroups not runasgroup in the Cmnd_Spec.
+ [92ea5dc20e4d]
+
+ * plugins/sudoers/visudo_json.c:
+ Fix some syntax errors and change how lists are handled.
+ [027b8dea44b2]
+
+ * common/sudo_debug.c, config.h.in, configure, configure.ac,
+ include/fatal.h, include/sudo_debug.h:
+ Allow sudo to compile without variadic macro support in cpp.
+ Debugging support will be limited (no file info from warnings.) From
+ Daniel Richard G.; Bug #621
+ [51b8b868cd4b]
+
+ * Makefile.in, common/aix.c, common/fatal.c, common/gidlist.c,
+ common/sudo_conf.c, include/fatal.h, include/gettext.h,
+ include/missing.h, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/rfc1938.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/env.c, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/locale.c,
+ plugins/sudoers/logging.c, plugins/sudoers/match.c,
+ plugins/sudoers/policy.c, plugins/sudoers/prompt.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/set_perms.c,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/timestamp.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c,
+ plugins/sudoers/visudo.c, plugins/sudoers/visudo_json.c, src/exec.c,
+ src/exec_common.c, src/exec_pty.c, src/load_plugins.c,
+ src/locale_stub.c, src/net_ifs.c, src/parse_args.c, src/selinux.c,
+ src/sesh.c, src/signal.c, src/solaris.c, src/sudo.c,
+ src/sudo_edit.c, src/tgetpass.c, src/utmp.c:
+ Add warning_gettext() wrapper function that changes to the user
+ locale, then calls gettext(). Add U_ macro that calls
+ warning_gettext() instead of gettext(). Rename warning2()/error2()
+ back to warning_nodebug()/error_nodebug().
+ [f3bb207db201]
+
+2013-11-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/fileops.c, compat/getaddrinfo.c, compat/mktemp.c,
+ compat/utimes.c, configure.ac, plugins/sudoers/boottime.c,
+ plugins/sudoers/check.c, plugins/sudoers/getdate.c,
+ plugins/sudoers/getdate.y, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/logging.h, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/visudo.c, src/exec.c, src/exec_pty.c, src/preload.c,
+ src/sudo.c, src/sudo_edit.c, src/ttyname.c, src/utmp.c:
+ Fix some #if vs. #ifdef and remove an extraneous semicolon. Bug
+ #624; from Daniel Richard G.
+ [b212e4694018]
+
+ * include/sudo_debug.h, plugins/sudoers/defaults.c,
+ plugins/sudoers/ldap.c, src/exec_common.c:
+ Add debug_return_const_str and debug_return_const_ptr for returning
+ a const string or pointer. Using const for the normal versions
+ produces warnings with the Tru64 compiler.
+ [45018a149cb4]
+
+ * common/event_poll.c, compat/getaddrinfo.c, config.h.in, configure,
+ configure.ac, m4/sudo.m4:
+ Fixes for building under Tru64; from Daniel Richard G. Bug #624
+ [fc4a6cbae1ba]
+
+2013-11-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/logging.c:
+ log_{fatal,warning} now logs to the debug file itself.
+ log_{fatal,warning} now calls warningx2() after setting the locale
+ itself instead of using the wrapper macros. This removes the only
+ use of warningx(ngettext(...)).
+ [930129361e0a]
+
+2013-11-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.ac:
+ Add -Wpointer-arith to --enable-warnings
+ [2043ae306d1b]
+
+ * configure, configure.ac:
+ Fix more instances of #include directives where the '#' was not in
+ column 1. From Daniel Richard G. (bug #622)
+ [75f36f39dcab]
+
+ * MANIFEST, doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/visudo.c,
+ plugins/sudoers/visudo_json.c:
+ Add support to visudo to export sudoers in JSON format.
+ [1697b2b4bfd2]
+
+2013-11-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/parse.h:
+ Remove unused digest field from struct cmndspec, the digest really
+ lives in struct sudo_command.
+ [e9a1e2e112d6]
+
+ * config.h.in, configure:
+ Regen with autoconf 2.69
+ [275f69f98f9e]
+
+ * MANIFEST, Makefile.in, config.h.in, configure.ac, configure.in,
+ doc/Makefile.in:
+ Rename configure.in -> configure.ac
+ [0aeafe425373]
+
+ * MANIFEST, aclocal.m4, autogen.sh, config.h.in, configure,
+ configure.in, ltmain.sh, m4/sudo.m4:
+ From Daniel Richard G. (bug #622) Add an autogen.sh script that
+ rebuilds the autoconf world. Move old aclocal.m4 contents to
+ m4/sudo.m4. New (generayed) aclocal.m4 contains the m4_include
+ directives. Some tests had #include directives where the '#' was not
+ in column 1. Updated obsolete macro usage via autoupdate.
+ [5fe8de5a56df]
+
+2013-11-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo_exec.h:
+ Very old systems (pre XPG 4.2) may not support MSG_WAITALL. The
+ likelihood of receiving a partial message is quite low so this is
+ not a big deal.
+ [900a304f9548]
+
+ * configure, configure.in:
+ HP-UX may require _XOPEN_SOURCE_EXTENDED to be defined for
+ MSG_WAITALL to be visible.
+ [f08b1a00a30a]
+
+ * MANIFEST, plugins/sudoers/regress/visudo/test5.out.ok,
+ plugins/sudoers/regress/visudo/test5.sh:
+ Add regress test for bug #623
+ [8e83cfccaf14]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Cope with a comment on the last line of the file with no newline.
+ Bug #623
+ [f826243bc4e6]
+
+ * compat/getaddrinfo.c:
+ Include arpa/inet.h for HP-UX; from Daniel Richard G.
+ [d4d7a4303bae]
+
+ * doc/Makefile.in:
+ Add missing $(mansrcdir) to visudo.mdoc and visudo.man. From Daniel
+ Richard G.
+ [f664c8d2f961]
+
+2013-11-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/fatal.h:
+ In v{warning,fatal}x?() make a new copy of ap for the debug
+ functions. It is not legal to use ap twice without reinitializing
+ it. Noticed by Daniel Richard G.
+ [6ca8bc48ecb3]
+
+ * include/fatal.h:
+ Remove errant warning_restore_locale() call.
+ [4ef7aecefcbb]
+
+ * include/missing.h, plugins/sudoers/logging.c:
+ Move va_copy compat macro to missing.h
+ [c873e4cc4c8a]
+
+ * common/Makefile.in, compat/Makefile.in, mkdep.pl,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/system_group/Makefile.in,
+ src/Makefile.in, zlib/Makefile.in:
+ Uniquify header dependencies so we don't end up with duplicates when
+ a header file includes other headers. The header dependencies are
+ sorted so the generated order is stable.
+ [95747db2f07a]
+
+ * compat/Makefile.in, configure, configure.in, doc/CONTRIBUTORS,
+ mkdep.pl:
+ Add getaddrinfo.lo to LTLIBOBJS for systems that need it. From
+ Daniel Richard G.
+ [e94ee99a52a9]
+
+ * plugins/sudoers/testsudoers.c:
+ Fix pasto
+ [5262735e78e0]
+
+2013-11-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.mdoc.in:
+ Fix typo.
+ [6b11a4eec6b6]
+
+2013-11-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/getdate.c, plugins/sudoers/gram.c:
+ regen
+ [995ca9f21862]
+
+ * plugins/sudoers/getdate.c, plugins/sudoers/getdate.y,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/toke.c:
+ Fix warnings from -Wold-style-definition
+ [a748c5c7b423]
+
+ * configure, configure.in:
+ Add -Wold-style-definition to --enable-warnings
+ [0484de0deb59]
+
+ * common/event_poll.c:
+ Extra debugging for ready fds.
+ [91fb85cdecbb]
+
+ * common/event_select.c:
+ When deleting an event, check ev->events to determine whether to
+ remove from readfds or writefds instead of blinding removing from
+ both. Also fix highfd adjustment.
+ [7384db65ca9c]
+
+2013-11-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/event_select.c:
+ Only check an fd that is >= 0. Timeout-only events may have a
+ negative fd.
+ [fa0e5cbc3cc2]
+
+2013-11-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/event.c:
+ Don't call sudo_ev_{add,del}_impl() for timeout-only events. This
+ makes it possible to pass sudo_ev_alloc() an fd of -1 for events
+ only use SUDO_EV_TIMEOUT.
+ [6838657a1a2f]
+
+2013-10-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/alloc.c, common/event_select.c, include/sudo_event.h:
+ Make a copy of readfds/writefds before calling select() instead of
+ calculating it each time. Keep track of high fd in the base.
+ [6048b78f2e94]
+
+2013-10-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS:
+ Add Stephen Gelman
+ [0028c7a91a4f]
+
+ * plugins/sudoers/getdate.c, plugins/sudoers/gram.c:
+ Fix sign comparison warning.
+ [914cb36b9ed2]
+
+ * plugins/sudoers/sudoreplay.c:
+ Fix potential NULL dereference in non-interactive mode.
+ [9233428d3f32]
+
+2013-10-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c, src/exec_pty.c:
+ Use MSG_WAITALL when receiving struct command_status over the Unix
+ domain socket since we no longer use datagrams. This should avoid
+ the need to handle incomplete reads, though in theory it is still
+ possible.
+ [28a92888a908]
+
+ * plugins/sudoers/sudoreplay.c:
+ SIGKILL is not catchable
+ [79f82e4cb11d]
+
+ * common/event.c, include/sudo_event.h, plugins/sudoers/sudoreplay.c:
+ Add sudo_ev_get_timeleft() to get the amount of time left before an
+ event times out and use it in sudoreplay.
+ [d5b17ee30fa4]
+
+2013-10-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in,
+ plugins/sudoers/sudoreplay.c:
+ If the user presses <return> or <enter> in sudoreplay, skip to the
+ next event. Useful for skipping past long pauses in the data.
+ [43343f45c94d]
+
+ * common/event.c, common/event_poll.c, common/event_select.c:
+ Fix sudo_ev_scan_impl() return value in event_poll.c. Make sure we
+ clear active flag from unprocessed events if sudo_ev_loopbreak() or
+ sudo_ev_loopcontinue() are used. Remove bogus optimization when the
+ timeout is zero or negative; it could prevent an I/O event from
+ being triggered.
+ [a13603fb3134]
+
+ * plugins/sudoers/sudoreplay.c:
+ Move session replay into its own function.
+ [e323f7729595]
+
+ * common/event.c, common/event_poll.c, common/event_select.c,
+ include/sudo_event.h:
+ Get rid of cur and pending pointers in struct sudo_event_base. We
+ now pop the first event off the active queue instead of using a
+ foreach loop with deferred removal of the event. Add
+ SUDO_EVQ_INSERTED and SUDO_EVQ_TIMEOUTS flags to indicate that the
+ event on the event queue and timeouts queue respectively. No longer
+ need to compare the timeout to {0,0} or compare the event's base
+ pointer to NULL to determine queue membership.
+ [f2b2251fd523]
+
+ * common/event_poll.c:
+ rename sudo_ev_loop_impl() -> sudo_ev_scan_impl()
+ [614faaff04e3]
+
+ * MANIFEST, common/event.c, common/event_poll.c,
+ common/event_select.c, compat/Makefile.in, compat/nanosleep.c,
+ config.h.in, configure, configure.in, include/missing.h,
+ include/sudo_event.h, mkdep.pl, plugins/sudoers/Makefile.in,
+ plugins/sudoers/sudoreplay.c, src/exec.c, src/exec_pty.c:
+ Add support for libevent-style timed events. Adding a timed event is
+ currently O(n). The only consumer of timed events is sudoreplay
+ which only used a singled one so O(n) == O(1) for now. This also
+ allows us to remove the nanosleep compat function as we now use a
+ timeout event instead.
+ [db41c08e92dc]
+
+2013-10-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c, src/exec_pty.c:
+ Now that sudo_ev_base_free() removes all events before freeing we
+ don't need to do this by hand.
+ [b59d43658c5f]
+
+ * common/event.c, common/event_poll.c, common/event_select.c,
+ include/sudo_event.h:
+ Add a list of active events in the base that the back end sets when
+ it calls poll or select. This allows the front end to iterate over
+ the events instead of having that code in both back ends. It will
+ also simplify support for timeout events. Also make sure we can't
+ touch freed memory if a callback frees its own event.
+ [933b99b3f2bc]
+
+ * common/event.c:
+ Remove any existing events before freeing the event base.
+ [2543c6620cf1]
+
+2013-10-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ mon_handler() should be static
+ [b1a62ef65c96]
+
+2013-10-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ If user specified start_tls and ldaps, display a warning and ignore
+ start_tls. There's no reason to make this a fatal error.
+ [bf446dd1e740]
+
+ * src/exec_pty.c:
+ Add missing else when the connection from the monitor to the parent
+ sudo process is broken (due to the parent dying). Prevents a
+ spurious "unexpected reply type on backchannel" warning.
+ [5c44053cef08]
+
+ * src/exec_pty.c:
+ When flushing output we don't care whether we are the foreground
+ process or not, we still need to flush to /dev/tty. If we are in the
+ background, it is OK to get SIGTTOU.
+ [9716892d1fb5]
+
+ * plugins/sudoers/ldap.c:
+ Should not attempt start_tls on an ldaps connection.
+ [9d01d461c52c]
+
+2013-10-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/parser/check_fill.c:
+ Fix sign compare warning.
+ [6130fa8df758]
+
+ * doc/Makefile.in:
+ Eliminate warning about circular dependency from GNU make.
+ [7ed5df762089]
+
+ * plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.c,
+ src/ttyname.c:
+ More sign compare fixes. On Solaris id_t is signed so use uid_t in
+ the set_perms.c ID macro instead.
+ [8166dcc50d0b]
+
+ * common/fileops.c, common/lbuf.c, common/secure_path.c,
+ common/sudo_debug.c, include/secure_path.h,
+ plugins/sudoers/find_path.c, plugins/sudoers/getdate.c,
+ plugins/sudoers/group_plugin.c, plugins/sudoers/interfaces.h,
+ plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/logging.c,
+ plugins/sudoers/match_addr.c, plugins/sudoers/parse.h,
+ plugins/sudoers/policy.c, plugins/sudoers/prompt.c,
+ plugins/sudoers/pwutil_impl.c, plugins/sudoers/set_perms.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, src/load_plugins.c, src/sudo.c,
+ src/ttyname.c:
+ Quiet sign comparision warnings.
+ [e34f45dad10c]
+
+ * configure, configure.in:
+ Add -Wsign-compare to --enable-warnings
+ [d560e274a6ae]
+
+ * plugins/sudoers/ldap.c:
+ Ignore SIGPIPE when connecting to the LDAP server so we can get a
+ proper error message with the IBM LDAP libs. Also return
+ LDAP_SUCCESS instead of 0 from most sudo_ldap_* functions that
+ return an int.
+ [611a4ed9b8ee]
+
+ * plugins/sudoers/regress/parser/check_base64.c,
+ plugins/sudoers/regress/parser/check_digest.c:
+ Quiet compiler warnings.
+ [7d82dcca7126]
+
+2013-10-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ sudo_ldap_parse_uri() should join multiple URIs in the string list
+ together but it was clearing the host entry each time through the
+ loop. Fixes a bug with multiple URI entries in ldap.conf where only
+ the last one was being honored.
+ [83cee19b136d]
+
+ * src/exec_pty.c:
+ Avoid a double free introduced when plugging a memory leak in
+ safe_close(). A new ev_free_by_fd() function is used to remove and
+ free any events sharing the specified fd. This can be used after
+ safe_close() to make sure we don't try to select() on a closed fd.
+ [54f48a281147]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y, src/exec.c:
+ Quiet some llvm check false positives. The common idiom of using
+ TAILQ_FIRST, TAILQ_REMOVE and free in a loop to free each entry in a
+ TAILQ confuses llvm. Use TAILQ_FOREACH_SAFE instead (which is
+ probably faster anyway).
+ [bd1b8c11f416]
+
+ * plugins/sudoers/auth/pam.c:
+ If pam_open_session() fails don't call pam_getenvlist() with a NULL
+ pam handle.
+ [352e0329acba]
+
+ * plugins/sudoers/defaults.c:
+ Fix newly introduced use after frees found by llvm checker.
+ [a81080230f1f]
+
+ * common/event_select.c:
+ Remove an errant list_next() call that should have been removed in
+ the TAILQ conversion.
+ [3bbf8d117ce4]
+
+ * MANIFEST, common/Makefile.in, common/list.c,
+ common/regress/tailq/hltq_test.c, include/list.h, include/queue.h,
+ plugins/sudoers/Makefile.in, plugins/sudoers/alias.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/match.c,
+ plugins/sudoers/parse.c, plugins/sudoers/parse.h,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ Add "headless" tail queues and use them in place of the semi-
+ circular lists in sudoers. Once the headless tail queue is built up
+ it is converted to a normal TAILQ. This removes the last consumer of
+ list.c and list.h so those can now be removed.
+ [5986ba762a24]
+
+ * common/Makefile.in, common/fatal.c, plugins/sudoers/Makefile.in,
+ plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/env.c, plugins/sudoers/interfaces.c,
+ plugins/sudoers/interfaces.h, plugins/sudoers/ldap.c,
+ plugins/sudoers/match_addr.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/visudo.c, src/Makefile.in, src/exec_pty.c,
+ src/hooks.c:
+ Use SLIST and STAILQ macros instead of doing headless singly linked
+ lists manually. As a bonus we now use a tail queue for ldap.c and
+ sudoreplay.c.
+ [c31bc2d99082]
+
+ * MANIFEST, common/Makefile.in, common/event.c, common/event_poll.c,
+ common/event_select.c, common/list.c,
+ common/regress/sudo_conf/conf_test.c, common/sudo_conf.c,
+ doc/LICENSE, include/list.h, include/missing.h, include/queue.h,
+ include/sudo_conf.h, include/sudo_event.h,
+ plugins/sudoers/Makefile.in, plugins/sudoers/ldap.c,
+ plugins/sudoers/parse.c, plugins/sudoers/parse.h,
+ plugins/sudoers/sssd.c, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudo_nss.h, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/visudo.c,
+ src/Makefile.in, src/exec.c, src/exec_pty.c, src/load_plugins.c,
+ src/sudo.c, src/sudo.h, src/sudo_plugin_int.h:
+ Convert sudo to use BSD TAILQ macros instead of home ground tail
+ queue functions. This includes a private queue.h header derived from
+ FreeBSD. It is simpler to just use our own header rather than try to
+ deal with macros that may or may not be present in various queue.h
+ incarnations.
+ [450bce095d7c]
+
+2013-10-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ Fix AND operator broken by changes to fix OR.
+ [a4d3485ee943]
+
+2013-10-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ Fix OR operator.
+ [f5c1c90ee284]
+
+2013-10-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Fix memory leak of I/O buffer events in safe_close().
+ [08cd790cfbba]
+
+2013-10-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/sudo_debug.c:
+ Don't allow the debug subsystem to be initialized twice. Otherwise
+ we can exhuast our stack when built in static mode.
+ [fadacb6a4617]
+
+ * common/event_poll.c:
+ Make sure we do not try to usie index -1 in base->pfds[].
+ [beeb922aba3f]
+
+2013-10-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.in:
+ Bump version to 1.8.9
+ [758dbb464796]
+
+2013-10-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Convert the monitor process to the event subsystem.
+ [c4fe8e2ba53c]
+
+ * src/exec.c, src/exec_pty.c, src/sudo_exec.h:
+ Convert the main sudo event loop to use the event subsystem. Read
+ events for I/O buffers are added before the loop starts. Write
+ events are added on demand as the buffers are filled.
+ [72a603e997e0]
+
+ * INSTALL, MANIFEST, common/Makefile.in, common/event.c,
+ common/event_poll.c, common/event_select.c, common/list.c,
+ common/sudo_debug.c, config.h.in, configure, configure.in,
+ include/list.h, include/sudo_debug.h, include/sudo_event.h,
+ mkdep.pl, plugins/sudoers/Makefile.in, src/Makefile.in,
+ src/exec_pty.c:
+ Simple event subsystem that uses poll() or select(). Basically a
+ simplied subset of libevent2. Currently only fd events are supported
+ (since that's all we need). The poll() backend is used by default,
+ except on Mac OS X where poll() is broken for devices (including
+ /dev/tty and ptys).
+ [8773142b4117]
+
+ * src/exec.c, src/exec_pty.c:
+ Use SOCK_STREAM for socketpair, not SOCK_DGRAM so we get consistent
+ semantics when the other end closes. This should make the conversion
+ to poll() less problematic.
+ [b6a321722a91]
+
+2013-10-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/sudo_debug.c:
+ Fix removal of trailing newlines in a debug message.
+ [6f5ce5ac64e0]
+
+2013-10-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo.c:
+ When checking for unused Runas_Aliases, count those used as part of
+ a Runas Group too. Fixes a false positive warning.
+ [f13271a4a377]
+
+2013-09-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/missing.h:
+ Include stddef.h for rsize_t and errno_t on systems that support it
+ natively.
+ [bc547d47e9c6]
+
+ * MANIFEST:
+ Fix braino.
+ [67b79747312f]
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/de.mo,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/fi.mo,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/pl.mo,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/uk.mo,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/zh_CN.mo:
+ Rebuild message catalog files.
+ [0a9befb0674e]
+
+ * src/po/da.mo, src/po/eo.mo, src/po/fi.mo, src/po/it.mo,
+ src/po/pl.mo, src/po/pt_BR.mo, src/po/ru.mo, src/po/uk.mo,
+ src/po/vi.mo, src/po/zh_CN.mo:
+ Rebuild message catalog files.
+ [25191089ddf2]
+
+ * MANIFEST, NEWS, doc/CONTRIBUTORS, src/po/cs.mo, src/po/cs.po:
+ Czech translation for sudo from translationproject.org.
+ [8bc0ed069ddb]
+
+2013-09-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/da.po, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/eo.po, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/it.po, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.po, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.po, plugins/sudoers/po/zh_CN.po, src/po/da.po,
+ src/po/eo.po, src/po/fi.po, src/po/it.po, src/po/pl.po,
+ src/po/pt_BR.po, src/po/ru.po, src/po/uk.po, src/po/vi.po,
+ src/po/zh_CN.po:
+ Sync with translationproject.org
+ [c16f9bb4579e]
+
+ * NEWS, plugins/sudoers/getdate.c, plugins/sudoers/getdate.y:
+ Change "next" back to 2. In the context of "next Friday" we really
+ do want the friday of the upcoming (not current) week.
+ Unfortunately, this means that things like "next week" and "next
+ year" will match one more than we really want. Fixing this will
+ require some fairly major changes to the grammar.
+ [7f863c930121]
+
+ * doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in:
+ Mention that relative times don't always do what you might expect.
+ [710a9b0dd36f]
+
+2013-09-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS:
+ Add diacritical for Zdenek Behan.
+ [78d333f88e6c]
+
+2013-09-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/regress/ttyname/check_ttyname.c:
+ Do not fail if ttyname() cannot determine the tty but sudo can.
+ Should fix problems with running "make check" under pbuilder.
+ [e6fc06a6c5cf]
+
+ * plugins/sudoers/Makefile.in:
+ Remove extraneous $$CWD; from Bdale Garbee
+ [4d040ddd7446]
+
+2013-09-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, plugins/sudoers/getdate.c, plugins/sudoers/getdate.y:
+ Make "this" and "next" qualifiers work a bit better. There is still
+ room for improvement as "this week" will use the current time
+ instead of the beginning of the week. That's a separate issue
+ though.
+ [e844c02f754a]
+
+2013-09-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/regress/sudo_conf/conf_test.c,
+ common/regress/sudo_parseln/parseln_test.c:
+ Mark main() public to silence a warning on HP-UX.
+ [ac0b869b9842]
+
+2013-09-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, plugins/sudoers/timestamp.c:
+ Be specific that we are talking about the Unix epoch; bug #615
+ [25887775371b]
+
+ * plugins/sudoers/auth/bsdauth.c, plugins/sudoers/po/sudoers.pot,
+ src/po/sudo.pot, src/selinux.c:
+ Do not use "setup" as a verb; bug #614
+ [17c4750aac5f]
+
+ * plugins/sudoers/iolog.c:
+ Fix logic goof when checking open() status.
+ [76ece1445d71]
+
+ * plugins/sudoers/po/nl.mo, plugins/sudoers/po/nl.po, src/po/nl.mo,
+ src/po/nl.po, src/po/ru.mo, src/po/ru.po:
+ Sync with translationproject.org
+ [21351498000f]
+
+ * NEWS, plugins/sudoers/sudoreplay.c:
+ Work around a bug in sudo 1.8.7 timing files where the indexes are
+ off by two.
+ [4aa0cd58af58]
+
+ * MANIFEST, plugins/sudoers/iolog.c, plugins/sudoers/iolog.h,
+ plugins/sudoers/sudoreplay.c:
+ Repair writing of the I/O log file indices broken in sudo 1.8.7.
+ [6a5f867884f5]
+
+2013-08-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Try to improve the PAGERS noexec example a bit.
+ [226f11118daa]
+
+2013-08-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ Document comment character in ldap.conf Clarify what is and is not
+ supported in TLS_KEYPW Mention that gsk8capicmd can be used to
+ create a stash file
+ [fb8f06ab4458]
+
+2013-08-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ New bugs fixed for 1.8.8.
+ [c158df7cd9d2]
+
+ * plugins/sudoers/visudo.c:
+ Fix setting of quiet flag when -q / --quiet is specified. Do not
+ print "sudoers: parsed OK" in quiet mode.
+ [df55acd57ce6]
+
+ * plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po, src/po/fi.mo,
+ src/po/fi.po, src/po/it.mo, src/po/it.po:
+ Updated translations from translationproject.org
+ [e9e8abd23a28]
+
+ * plugins/sudoers/check.c:
+ Don't allow root to change its SELinux role without a password. Bug
+ #611
+ [f8b599acb29d]
+
+2013-08-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Mention new Mac OS X symbol interposition.
+ [98293b7c4e0f]
+
+ * plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po, src/po/eo.mo,
+ src/po/eo.po, src/po/fr.mo, src/po/fr.po:
+ Updated translations from translationproject.org
+ [865be7454354]
+
+ * config.h.in, configure, configure.in, src/sudo_noexec.c:
+ Add configure checks for the exec functions we will dummy out. This
+ is only really needed on Mac OS X when symbol interposition is being
+ performed but won't hurt elsewhere.
+ [49c20cf6bab0]
+
+2013-08-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, src/Makefile.in,
+ src/sudo_noexec.c:
+ Fix installation of sudo_noexec on Mac OS X. Use library symbol
+ interposition on Mac OS X 10.4 and higher so we don't need to set
+ DYLD_FORCE_FLAT_NAMESPACE=1.
+ [a82999dff8e6]
+
+2013-08-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Fix error display from ldap_ssl_client_init(). There are two error
+ codes. The return value can be decoded via ldap_err2string() but the
+ ssl reason code cannot (you have to look it up in a table online).
+ [0267125ce9f0]
+
+2013-08-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ Fix typo in tls_key example for Tivoli
+ [36599f424ac4]
+
+ * src/parse_args.c:
+ Don't escape '$' when running "sudo -i command". Bug #564
+ [17542d52f714]
+
+ * plugins/sudoers/iolog_path.c:
+ Fix typo in comment.
+ [d0510ed5eaba]
+
+ * plugins/sudoers/auth/pam.c:
+ Fix comment.
+ [4e89e0bfd6af]
+
+ * plugins/sudoers/timestr.c, plugins/sudoers/visudo.c:
+ Quiet some gcc -Wformat=2 false positives
+ [28a2014b9822]
+
+2013-08-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/pam.c:
+ Remove now-obsolete arg to env_merge()
+ [ba015cf5d935]
+
+ * plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/pt_BR.mo, plugins/sudoers/po/pt_BR.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po,
+ src/po/pl.mo, src/po/pl.po, src/po/pt_BR.mo, src/po/pt_BR.po,
+ src/po/uk.mo, src/po/uk.po, src/po/vi.mo, src/po/vi.po,
+ src/po/zh_CN.mo, src/po/zh_CN.po:
+ Updated translations from translationproject.org
+ [72b6aeaba505]
+
+ * MANIFEST, NEWS, doc/CONTRIBUTORS, src/po/fr.mo, src/po/fr.po:
+ French translation for sudo from translationproject.org.
+ [a72321771860]
+
+ * plugins/sudoers/logging.h:
+ Add __printflike to audit_failure.
+ [1686b3699d41]
+
+ * include/missing.h:
+ Use __nonnull__ attribute in __printflike.
+ [d123613a1fb6]
+
+2013-08-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/env.c, plugins/sudoers/sudoers.h:
+ When merging the PAM environment, allow environment variables set in
+ PAM to override ones set by sudo as long as they do not match the
+ env_keep or env_check lists.
+ [f3c64967fed7]
+
+ * plugins/sudoers/auth/pam.c:
+ Call pam_getenvlist() after we've opened the session to get the
+ session-specific environment variables.
+ [b413fb9e1c77]
+
+2013-08-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ option not flag
+ [08c31af7b818]
+
+ * compat/getopt_long.c, config.h.in, configure, configure.in:
+ Don't redefine opterr, optind, optopt, optarg in getopt_long.c. Add
+ a check for optreset which is a BSD extension and provide a
+ definition in getopt_long.c if it is not present.
+ [3393e8d83400]
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ regen
+ [f38f65830118]
+
+ * plugins/sudoers/sudoreplay.c, plugins/sudoers/visudo.c:
+ Use lower case for the long option arguments to match the manual.
+ This is inconsistent with GNU but it is better to match the sudo
+ documentation.
+ [8fac2d64f5d2]
+
+ * NEWS:
+ Sudo 1.8.8
+ [105c73752474]
+
+ * src/parse_args.c:
+ Use lower card for the long option arguments to match the manual.
+ This is inconsistent with GNU but it is better to match the sudo
+ documentation.
+ [af243dd39850]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in:
+ Describe how remote command execution can be implemented.
+ [3eba7f93b7f6]
+
+ * doc/sudoers.ldap.cat:
+ Bump version.
+ [0ee7f02f3627]
+
+2013-08-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo.c:
+ Make it a fatal error if the plugin returns invalid or out of range
+ command info.
+ [8a7e56c7584a]
+
+ * plugins/sudoers/policy.c:
+ Use strtol() instead of atoi() and perform error checking of
+ parameters passed from the sudo front-end.
+ [05e05be3c6c4]
+
+ * plugins/sudoers/auth/pam.c:
+ It is not possible for auth to be NULL here.
+ [771500e776e9]
+
+ * plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ Initialize user_runhost and user_srunhost to user_host and
+ user_shost in visudo and testsudoers.
+ [c47cca74e1fc]
+
+ * MANIFEST, common/Makefile.in, common/aix.c, common/alloc.c,
+ common/error.c, common/fatal.c, common/gidlist.c, common/lbuf.c,
+ common/list.c, common/sudo_conf.c, common/sudo_debug.c,
+ compat/Makefile.in, compat/getopt_long.c, include/error.h,
+ include/fatal.h, plugins/sudoers/Makefile.in,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/hexchar.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/locale.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoreplay.c,
+ src/Makefile.in, src/locale_stub.c, src/net_ifs.c,
+ src/regress/ttyname/check_ttyname.c, src/sesh.c, src/sudo.h:
+ Rename error.h -> fatal.h now that there is no error() function.
+ [3a3827f10f04]
+
+ * common/sudo_debug.c, include/sudo_debug.h:
+ Add support to the debug subsystem for zero-length strings. This can
+ happen for things like warning(NULL) or fatal(NULL) where we just
+ want to log the errno string.
+ [3ed739c5cc91]
+
+ * include/error.h:
+ Add __printflike for vfatal, vfatalx, vwarning and vwarningx.
+ [57e65ed595d2]
+
+ * plugins/sudoers/audit.c:
+ Need to include gettext.h for BSM audit.
+ [a87fda2d0123]
+
+ * common/alloc.c, plugins/sudoers/env.c, src/exec_common.c,
+ src/parse_args.c, src/sudo.c:
+ Change some fatalx(NULL) that should be fatal(NULL).
+ [8b1efda9f578]
+
+ * include/error.h, include/missing.h:
+ Use __printf0like for warning() and fatal() since the fmt string may
+ be NULL.
+ [858a890f00ad]
+
+ * compat/pw_dup.c:
+ Quiet a gcc "used uninitialized in this function" false positive.
+ [98f47f89ce60]
+
+ * mkpkg:
+ Enable bsm audit on Mac OS X and Solaris >= 11.
+ [8607488f986c]
+
+ * plugins/sudoers/bsm_audit.c:
+ Fix compilation on Solaris 11.
+ [01aa46298ed7]
+
+ * plugins/sudoers/bsm_audit.c:
+ Add missing missing.h
+ [080de69a55a1]
+
+ * plugins/sudoers/sudoers.c:
+ Move the -C (user_closefrom) check until after set_cmnd() so that
+ closefrom_override can be used in a command-specific Defaults line.
+ Fixes bug #610 from Mengtao Sun.
+ [413565c6ff6b]
+
+2013-08-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ If not using a pty and the child process gets SIGTTOU or SIGTTIN and
+ sudo is the foreground process, make the child the foreground
+ process and continue it.
+ [5ff433443bc4]
+
+ * src/sudo.c:
+ If sudo is not setuid and was not invoked with a full path, look in
+ the user's PATH for the sudo binary to give a better error message.
+ [a740129a38f0]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in,
+ plugins/sudoers/logging.c, plugins/sudoers/match.c,
+ plugins/sudoers/policy.c, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudoers.h:
+ Add limited support for "sudo -l -h other_host". Since group lookups
+ are done on the local host, rules that use group membership may be
+ incorrect if the group database is not synchronized between hosts.
+ [2c8b222a5f7f]
+
+ * src/parse_args.c:
+ Fix parsing of "-h host" when used in conjunction with the -l flag.
+ [62f3d726d52b]
+
+ * configure, configure.in, doc/fixman.sh, doc/fixmdoc.sh,
+ doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in, doc/visudo.cat,
+ doc/visudo.man.in, doc/visudo.mdoc.in, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/visudo.c, src/parse_args.c, src/sudo.c,
+ src/sudo_usage.h.in:
+ Simplify usage messages a bit and make --help output more closely
+ resemble GNU usage wrt long options. Sync usage and man page
+ SYNOPSYS sections and improve long options in the manual pages. Now
+ that we have long options we don't need to give the mnemonic for the
+ single-character options in the description.
+ [17b7e386955a]
+
+2013-08-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/logging.c:
+ Fix setting of mailer argv[0] to basename of mailerpath. No need to
+ strdup() mailerpath as it is not modified.
+ [8843cdd958ee]
+
+ * plugins/sudoers/logging.c:
+ Make sure the mailer exists and is a regular file before trying to
+ exec it.
+ [b73d6214014f]
+
+ * plugins/sudoers/timestamp.c:
+ If tty_tickets are enabled but there is no tty, use a ticket file
+ based on the parent pid.
+ [75408bd61ced]
+
+ * common/sudo_conf.c, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, include/sudo_conf.h, src/parse_args.c:
+ Allow default plugin dir to be configured in sudo.conf.
+ [478883594cc5]
+
+ * doc/CONTRIBUTORS:
+ UTF8 for Ruusamae, Elan; from Tae Wong
+ [02e0c95b4fa6]
+
+2013-08-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/regress/sudo_conf/test5.in,
+ common/regress/sudo_conf/test5.out.ok,
+ common/regress/sudo_conf/test6.in,
+ common/regress/sudo_conf/test6.out.ok, common/sudo_conf.c,
+ doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in,
+ plugins/sudoers/policy.c, plugins/sudoers/pwutil_impl.c, src/sudo.c:
+ Don't allow max_groups to be set to zero, it just complicates things
+ needlessly. Fixes an assertion in visudo when there is a group-
+ based Defaults entry.
+ [d62a8ea32db9]
+
+2013-08-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/Makefile.in, common/gidlist.c,
+ plugins/sudoers/policy.c, plugins/sudoers/sudoers.h, src/sudo.c,
+ src/sudo.h:
+ Refactor code to parse list of gids into its own function that is
+ shared by the sudo front-end and the sudoers module. Make uid/gid
+ parse error be fatal, not just a warning.
+ [da3b2b06605c]
+
+ * common/atoid.c:
+ Add function comment block.
+ [09a324de716f]
+
+ * common/atoid.c:
+ Default text domain is now sudo, not sudoers.
+ [1acb1da6f304]
+
+ * common/Makefile.in:
+ Update dependency for atoid.lo
+ [5e367cd44288]
+
+ * common/atoid.c, plugins/sudoers/iolog.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/tsgetgrpw.c, src/sudo.c,
+ src/sudo.h:
+ Add endpointer and separator args to atoid()
+ [2077e4ed8578]
+
+2013-08-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/getgrouplist.c:
+ Use private version of atoid() to avoid a dependency on libcommon.a
+ (since that already depends on libreplace.a).
+ [7c12d63b0560]
+
+ * doc/CONTRIBUTORS:
+ More UTF8 in names; from Tae Wong
+ [512b263f51c8]
+
+ * compat/getgrouplist.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/tsgetgrpw.c, src/sudo.c, src/sudo.h:
+ Use atoid() in more places.
+ [06f4ae57c707]
+
+ * MANIFEST, common/Makefile.in, common/atoid.c,
+ plugins/sudoers/Makefile.in, plugins/sudoers/atoid.c:
+ Move atoid() to common so it can be used in src and compat too.
+ [095d730701e4]
+
+ * compat/closefrom.c:
+ Avoid a crash on Mac OS X 10.8 (at least) when we close
+ libdispatch's fds out from under it before executing the command.
+ Switch to just setting the close on exec flag instead.
+ [349ebf4987df]
+
+ * doc/CONTRIBUTORS:
+ Convert to last, first for easier sorting and use UTF8 (including a
+ BOM).
+ [8c30d221bd75]
+
+ * plugins/sudoers/atoid.c:
+ Add atoid() function to convert a string to an id_t (uid, gid or
+ pid). We have to be careful to choose() either strtol() or strtoul()
+ depending on whether the string appears to be signed or unsigned.
+ Always using strtoul() is unsafe on 64-bit platforms since the uid
+ might be represented as a negative number and (unsigned long)-1 on a
+ 64-bit system is 0xffffffffffffffff not 0xffffffff. Fixes a problem
+ with uids larger than 0x7fffffff on 32-bit platforms.
+ [5d818e399157]
+
+ * MANIFEST, config.h.in, configure, configure.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.h:
+ Add atoid() function to convert a string to an id_t (uid, gid or
+ pid). We have to be careful to choose() either strtol() or strtoul()
+ depending on whether the string appears to be signed or unsigned.
+ Always using strtoul() is unsafe on 64-bit platforms since the uid
+ might be represented as a negative number and (unsigned long)-1 on a
+ 64-bit system is 0xffffffffffffffff not 0xffffffff. Fixes a problem
+ with uids larger than 0x7fffffff on 32-bit platforms.
+ [cd92246a710f]
+
+ * plugins/sudoers/sudoers.c:
+ Avoid "perm stack underflow" error when logging the unknown uid
+ error.
+ [871514c713b7]
+
+ * plugins/sudoers/set_perms.c:
+ In rewind_perms() there is nothing to do if perm_stack_depth == 0.
+ [98de335f47f0]
+
+2013-08-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in:
+ Add pam_setcred sudoers option to allow the user to control whether
+ pam_setcred() is called on the user's behalf.
+ [4260a8e43073]
+
+ * configure, configure.in, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/defaults.c:
+ Add pam_service and pam_login_service sudoers settings to control
+ the service name passed to pam_start.
+ [5ea0e3588f3a]
+
+ * mkpkg:
+ Newer Xcode places the SDKs under Xcode.app
+ [4b54379d5c45]
+
+2013-08-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/Makefile.in, common/zero_bytes.c,
+ compat/Makefile.in, compat/memset_s.c, config.h.in, configure,
+ configure.in, doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, include/missing.h, include/sudo_plugin.h,
+ mkdep.pl, plugins/sudoers/Makefile.in,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/secureware.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/logging.c, plugins/sudoers/sha2.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/tsgetgrpw.c, plugins/sudoers/visudo.c,
+ src/Makefile.in, src/conversation.c, src/sudo.h, src/sudo_edit.c,
+ src/tgetpass.c:
+ Implement memset_s() and use it instead of zero_bytes(). A new
+ constant, SUDO_CONV_REPL_MAX, is defined by the plugin API as the
+ max conversation reply length. This constant can be used as a max
+ value for memset_s() when clearing passwords filled in by the
+ conversation function.
+ [264ec146028e]
+
+2013-08-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/system_group/Makefile.in:
+ Do not try to install plugins when shared modules are disabled
+ (sudoers already had the check).
+ [3d582c042042]
+
+ * plugins/sudoers/Makefile.in:
+ Update dependencies to take into account compat/getopt.h and
+ compat/dlfcn.h.
+ [301fb31cd121]
+
+ * src/Makefile.in:
+ Update dependencies now that sudo_usage.h is always included from
+ the build dir.
+ [c1ff70ec9515]
+
+2013-07-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Add some warnings and debugging to sasl ccname handling.
+ [467f415861f0]
+
+ * plugins/sudoers/ldap.c:
+ Fix write loop invariant in sudo_krb5_copy_cc_file()
+ [6948cf6e9b9f]
+
+2013-07-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Strip off leading FILE: or WRFILE: prefix before trying to copy the
+ user's credential cache.
+ [56c16feab62f]
+
+2013-07-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo.c:
+ Instead of setting RLIMIT_NPROC to unlimited when sudo initializes,
+ just save RLIMIT_NPROC in exec_setup() before the final setuid() and
+ restore it immediately after. We don't need to modify RLIMIT_NPROC
+ for simple euid changes, just for changing the real (and saved) uids
+ before we exec. This also means we no longer need to worry about
+ _SC_CHILD_MAX returning -1. Bug #565
+ [1372f1909039]
+
+2013-07-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c, src/preload.c:
+ Now that the ldap code runs with the real and effective uid set to
+ 0, it is not possible for the gssapi libs to find the user's krb5
+ credential cache file. To work around this, we make a temporary copy
+ of the user's credential cache specified by KRB5CCNAME (opened with
+ the user's effective uid) and point gssapi to it. To set the
+ credential cache file name, we dynamically look up
+ gss_krb5_ccache_name() and use it if available, otherwise fall back
+ to setting KRB5CCNAME.
+ [8b86c134541a]
+
+2013-07-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.man.in, doc/sudoreplay.cat, doc/sudoreplay.man.in,
+ doc/sudoreplay.mdoc.in, doc/visudo.cat, doc/visudo.man.in,
+ doc/visudo.mdoc.in, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/visudo.c:
+ Long option support for visudo and sudoreplay.
+ [91427968be71]
+
+2013-07-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in, src/Makefile.in,
+ src/parse_args.c, src/sudo.c, src/sudo_usage.h.in:
+ Add support for long options and fix inclusion of sudo_usage.h with
+ modern gcc broken in 8597:1fcb7ba13018.
+ [d13134819944]
+
+ * src/Makefile.in:
+ Add rule to rebuild sudo_usage.h when the .in file changes.
+ [59a32899e251]
+
+ * compat/Makefile.in, mkdep.pl, src/Makefile.in:
+ Add make rules for building getopt_long.c
+ [5f57593b3a8b]
+
+ * src/parse_args.c:
+ Make "-h hostname" work. Optional args in GNU getopt() only work
+ when there is no space between the option flag and the argument.
+ [b8258659cabb]
+
+2013-07-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, compat/getopt.h, compat/getopt_long.c, config.h.in,
+ configure, configure.in, doc/LICENSE, src/parse_args.c:
+ Use getopt_long() so we can make the -h flag take an optional
+ argument. Includes a version for those without it.
+ [d1dd66c8a86b]
+
+2013-07-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Document that the -h option can be used specify a host name for
+ future plugins.
+ [8470c74cf326]
+
+ * include/sudo_plugin.h, src/parse_args.c, src/sudo_usage.h.in:
+ Overload -h option to specify an optional hostname for remote
+ access. This is future-proofing; no policy plugins currently support
+ this.
+ [0e01d8c3c623]
+
+ * configure, configure.in:
+ Bump version to 1.8.8
+ [a1155bfaa28f]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in:
+ Document the remote_host setting (-h host)
+ [c737db906f5d]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ fix "the the"
+ [0025464a3942]
+
+ * src/parse_args.c, src/sudo.c, src/sudo.h:
+ Do not error out if arg to -U option cannot be resolved, that is for
+ the plugin to decide. There is no need for runas_user and
+ runas_group to be global, make them local to parse_args() instead.
+ [fb02a62a72ba]
+
+ * MANIFEST, doc/CONTRIBUTORS, plugins/sudoers/po/pt_BR.mo,
+ plugins/sudoers/po/pt_BR.po, src/po/es.mo, src/po/es.po,
+ src/po/pt_BR.mo, src/po/pt_BR.po:
+ Sync with translationproject.org
+ [e8f4772d918a]
+
+2013-07-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/TROUBLESHOOTING:
+ Remove old bits about sudo setuid problems that should have been
+ cleaned up in changeset 7917:fa4894896d8a. Also update the mode of
+ sudo to 04755 to match current packaging.
+ [1e3904cdc2de]
+
+ * plugins/sudoers/auth/pam.c:
+ Go back to ignoring the return value of pam_setcred() since with
+ stacked PAM auth modules a failure from one module may override
+ PAM_SUCCESS from another. If the first module in the stack fails,
+ the others may be run (and succeed) but an error will be returned.
+ This can cause a spurious warning on systems with non-local users
+ (e.g. pam_ldap or pam_sss) where pam_unix is consulted first.
+ [b6022e26135a]
+
+ * src/net_ifs.c:
+ Remove unused variable.
+ [93dde7d82fde]
+
+ * NEWS:
+ Fix typo
+ [5ef79671c2c7]
+
+2013-07-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sssd.c:
+ Fix pasto; sudo_sss_extract_digest() not sudo_ldap_extract_digest().
+ From Dan Harnett.
+ [4a0af6f12765]
+
+2013-06-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Fix formatting typo; from Eric S. Raymond
+ [058b533ba460]
+
+2013-06-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ Use -gxcoff on aix so dbx can be used to debug sudo.
+ [4950e019ed2d]
+
+2013-06-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in:
+ Fix typo; bug 605
+ [41f7b46a6e51]
+
+2013-06-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/po/da.mo, src/po/eo.mo, src/po/es.mo, src/po/it.mo,
+ src/po/tr.mo:
+ Regen .mo files that were out of date.
+ [9e25a254f9db]
+
+2013-05-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.in:
+ On Solaris 11 and higher, tag binaries for ASLR if supported by the
+ linker.
+ [a2a6cafa3e60]
+
+ * mkpkg:
+ No longer need to disable PIE on Solaris.
+ [cf90019ae67e]
+
+2013-05-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, NEWS, configure, configure.in, doc/TROUBLESHOOTING:
+ Restrict default creation of PIE binaries (-fPIE and -pie) to Linux.
+ OpenBSD also supports PIE but enables it by default so we don't need
+ to do anything. This fixes problems on systems with a version of GNU
+ ld that accepts -pie but where the run-time linker doesn't actually
+ support PIE. Also verify that a trivial PIE binary works unless PIE
+ is explicitly enabled.
+ [3c5f125efeb1]
+
+2013-05-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4, configure, configure.in:
+ Attempt to detect PIE failure on Solaris 10 with GNU as and GNU ld
+ where we can end up crashing due to malloc() failures. Sems OK when
+ Using Sun as and ld.
+ [b8ba412102ab]
+
+ * NEWS:
+ Update with final changes.
+ [78ff6d2ed47a]
+
+2013-05-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Add -fPIE to PIE_LDFLAGS as per gcc manual.
+ [fe900cbb0780]
+
+2013-05-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/Makefile.in, compat/Makefile.in:
+ Add missing $(PIE_LDFLAGS) $(SSP_LDFLAGS) for test programs
+ [f84bc7482b78]
+
+ * MANIFEST, plugins/sudoers/alias.c, plugins/sudoers/match.c,
+ plugins/sudoers/parse.c, plugins/sudoers/parse.h,
+ plugins/sudoers/regress/visudo/test4.out.ok,
+ plugins/sudoers/regress/visudo/test4.sh, plugins/sudoers/visudo.c:
+ Replace sequence number-based cycle detection in visudo with a
+ "used" flag in struct alias. The caller is required to call
+ alias_put() when it is done with the alias. Inspired by a patch from
+ Daniel Kopecek.
+ [0bdbac1b3b39]
+
+2013-05-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Eliminate a few relocations related to sudoers_io.
+ [18e9e2cc3367]
+
+ * plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po:
+ Sync with translationproject.org
+ [f38cc128a2ad]
+
+2013-05-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/ttyname.c:
+ Clarify a comment.
+ [7a045ee06e95]
+
+2013-05-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/ttyname.c:
+ Handle d_type == DT_UNKNOWN when resolving the device to a name and
+ sprinkle some more debugging.
+ [8774133747d9]
+
+2013-05-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/TROUBLESHOOTING:
+ Add message about disabling PIE if sudo gets SIGSEGV.
+ [c786af2a6751]
+
+ * plugins/sudoers/check.h, plugins/sudoers/timestamp.c:
+ No longer store the ctime of a devpts tty. The handling of ctime on
+ devpts in Linux has been changed to conform to POSIX. As a result we
+ can no longer assume that the ctime will stay unchanged throughout
+ the life of the session. We store the session ID in the time stamp
+ file so there is a much smaller chance of the time stamp file being
+ reused by a new login. While here, store the uid/gid in the
+ timestamp file too for good measure.
+ [7028b21f7a9b]
+
+ * configure, configure.in:
+ PIE is broken on FreeBSD/arm
+ [f232c60d6229]
+
+ * mkpkg:
+ Add explicit sendmail path for Linux since we may not have sendmail
+ installed in the build chroot.
+ [1ba2f84f4ff0]
+
+2013-05-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/sudo_debug.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/set_perms.c, src/sudo.c, src/tgetpass.c:
+ Quiet a few -Wunused-result compiler warnings.
+ [ef12afb61423]
+
+2013-04-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Mention what SHA-2 formats are supported.
+ [bf298d0fdf8a]
+
+ * doc/CONTRIBUTORS:
+ List code and translations separately.
+ [826547bc1295]
+
+2013-04-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/po/de.mo, plugins/sudoers/po/de.po,
+ plugins/sudoers/po/tr.mo, plugins/sudoers/po/tr.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po:
+ Sync with translationproject.org
+ [9499a6f438b8]
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [cce449e284a6]
+
+ * Makefile.in:
+ Fix c-format for fatal/fatalx
+ [4ad81d3faaeb]
+
+2013-04-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, plugins/sudoers/iolog.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/visudo.c, src/exec_pty.c, src/sudo.h:
+ Change some error/errorx -> fatal/fatalx in comments and xgettext
+ flags.
+ [9d9b64fa2ec9]
+
+ * NEWS:
+ There is now a Turkish translation of sudoers.
+ [701c5af6aa76]
+
+ * MANIFEST, plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/tr.mo, plugins/sudoers/po/tr.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po:
+ Updated translations from translationproject.org including new
+ Turkish translation.
+ [9cedbb50d90f]
+
+2013-04-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document that sudoers will re-use existing I/O log paths unless they
+ are mktemp-style with trailing X's.
+ [4f43bd13d9e7]
+
+ * NEWS, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.ldap.mdoc.in,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, plugins/sudoers/ldap.c,
+ plugins/sudoers/policy.c, plugins/sudoers/sudoers.h:
+ Allow ldap_conf and ldap_secret to be specified as plugin arguments
+ in sudo.conf
+ [37c6c425b565]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ sudoers_debug is now deprecated in favor of the sudo debugging
+ framework.
+ [1195be1ec254]
+
+ * plugins/sudoers/ldap.c:
+ Replace DPRINTF with DPRINTF1 and DPRINTF2 macros that use
+ SUDO_DEBUG_DIAG and SUDO_DEBUG_INFO respectively for logging to the
+ debug file with the ldap subsystem. The sudoers_debug setting in
+ ldap.conf is still honored for now but will be removed in a future
+ release.
+ [cfa42b4b913e]
+
+2013-04-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers2ldif:
+ Add support for converting sudoers files with SHA-2 command digests.
+ [dc0d03485946]
+
+ * doc/fixman.sh, doc/fixmdoc.sh, mkdep.pl, mkpkg,
+ plugins/sudoers/sudoers2ldif:
+ Add copyright notice to scripts
+ [5e8bd4e6083f]
+
+ * MANIFEST, plugins/sudoers/regress/sudoers/test14.in,
+ plugins/sudoers/regress/sudoers/test14.out.ok,
+ plugins/sudoers/regress/sudoers/test14.toke.ok:
+ Add regress for SHA-2 digests.
+ [0b258c2a2a95]
+
+ * compat/getgrouplist.c:
+ Solaris maps negative gids to GID_NOBODY.
+ [57050e5c750f]
+
+ * plugins/sudoers/visudo.c:
+ Clear up an llvm checker warning which appears to be a false
+ positive and fix an old XXX while I'm at it.
+ [9ee13133e596]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in:
+ Correct last change date
+ [3bc1fa5b0f76]
+
+ * plugins/sudoers/po/sudoers.pot, plugins/sudoers/sudoreplay.c:
+ No need to translate this error message.
+ [4d9941970a26]
+
+ * doc/UPGRADE:
+ Mention .sl vs. .so extension handling on HP-UX Mention group
+ membership changes Fix typos
+ [40ac0efbdb2b]
+
+ * aclocal.m4, common/aix.c, common/alloc.c, common/atobool.c,
+ common/error.c, common/fmt_string.c, common/lbuf.c, common/list.c,
+ common/setgroups.c, common/term.c, common/ttysize.c,
+ compat/Makefile.in, compat/dlopen.c, compat/endian.h,
+ compat/getline.c, compat/getprogname.c, compat/isblank.c,
+ compat/memrchr.c, compat/mksiglist.c, compat/mktemp.c,
+ compat/nanosleep.c, compat/pw_dup.c, compat/sig2str.c,
+ compat/snprintf.c, compat/strlcat.c, compat/strlcpy.c,
+ compat/strsignal.c, compat/utimes.c, doc/Makefile.in,
+ include/Makefile.in, include/alloc.h, include/fileops.h,
+ include/gettext.h, include/lbuf.h, include/missing.h,
+ include/sudo_plugin.h, pathnames.h.in,
+ plugins/group_file/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sample/sample_plugin.c, plugins/sudoers/Makefile.in,
+ plugins/sudoers/alias.c, plugins/sudoers/audit.c,
+ plugins/sudoers/auth/afs.c, plugins/sudoers/auth/aix_auth.c,
+ plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/dce.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/passwd.c,
+ plugins/sudoers/auth/rfc1938.c, plugins/sudoers/auth/secureware.c,
+ plugins/sudoers/auth/securid5.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.h, plugins/sudoers/bsm_audit.c,
+ plugins/sudoers/bsm_audit.h, plugins/sudoers/defaults.c,
+ plugins/sudoers/defaults.h, plugins/sudoers/env.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/getspwuid.c,
+ plugins/sudoers/goodpath.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/interfaces.c, plugins/sudoers/interfaces.h,
+ plugins/sudoers/iolog_path.c, plugins/sudoers/linux_audit.c,
+ plugins/sudoers/linux_audit.h, plugins/sudoers/locale.c,
+ plugins/sudoers/logging.h, plugins/sudoers/match.c,
+ plugins/sudoers/match_addr.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/prompt.c,
+ plugins/sudoers/pwutil.h, plugins/sudoers/redblack.c,
+ plugins/sudoers/redblack.h,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudo_nss.h, plugins/sudoers/sudoers_version.h,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.h, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, plugins/sudoers/tsgetgrpw.c,
+ plugins/sudoers/visudo.c, plugins/system_group/Makefile.in,
+ plugins/system_group/system_group.c, src/Makefile.in,
+ src/conversation.c, src/exec.c, src/exec_common.c, src/get_pty.c,
+ src/net_ifs.c, src/parse_args.c, src/preload.c, src/selinux.c,
+ src/sesh.c, src/signal.c, src/sudo_edit.c, src/sudo_exec.h,
+ src/sudo_noexec.c, src/sudo_plugin_int.h, src/tgetpass.c,
+ src/utmp.c:
+ Update copyright years.
+ [5c6d72661bad]
+
+ * plugins/sudoers/mon_systrace.h:
+ Systrace support was removed long ago.
+ [10a038a2da77]
+
+2013-04-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/regress/sudoers/test10.toke.out.ok,
+ plugins/sudoers/regress/sudoers/test9.toke.out.ok:
+ Remove some files that were mistakenly added.
+ [833502da26de]
+
+ * common/sudo_debug.c, config.h.in, configure, configure.in,
+ plugins/sudoers/boottime.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/logging.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/timestamp.c:
+ Use time(&now) instead of now = time(NULL) when storing the current
+ time in a time_t (better compiler error checking). Better parsing
+ and printing of 64-bit time_t on 32-bit platforms.
+ [c227dc72c04e]
+
+2013-04-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/ttyname.c:
+ Don't check the tty of the parent process. Now that we get the
+ controlling tty device number from the kernel there is no need. If
+ the process has really disassociated from the tty then reporting
+ "unknown" is appropriate.
+ [62fb66e565db]
+
+2013-04-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/error.c:
+ Use EXIT_FAILURE instead of 1 as the fatal() exit value.
+ [ed94c2c5e88a]
+
+ * src/sesh.c:
+ Change remaining errorx -> fatalx
+ [3f6d70e19303]
+
+2013-04-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/pwutil.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Replace sudo_fakepwnamid() with sudo_mkpwent() and don't return an
+ error if the entry already exists in the cache.
+ [94d45970400a]
+
+ * plugins/sudoers/bsm_audit.c, plugins/sudoers/po/sudoers.pot:
+ Change "foo: failed" to just "foo" since we print the string form of
+ errno. Gets rids of some useless translations.
+ [476f37349dbc]
+
+2013-04-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/match.c:
+ Fix pasto in debug_decl
+ [08650186a239]
+
+ * plugins/sudoers/Makefile.in:
+ regen
+ [acf4c34fba2c]
+
+ * plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/logging.c,
+ plugins/sudoers/logging.h, plugins/sudoers/parse.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/timestamp.c:
+ Rename log_error() -> log_warning() for consistency with
+ warning()/fatal()
+ [474ed5a0e335]
+
+ * plugins/sudoers/auth/API:
+ The NO_EXIT flag was removed a while ago.
+ [e0a4be270226]
+
+ * common/aix.c, common/alloc.c, common/error.c, include/error.h,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/env.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/hexchar.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/logging.c,
+ plugins/sudoers/policy.c, plugins/sudoers/prompt.c,
+ plugins/sudoers/pwutil.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/visudo.c, src/exec.c, src/exec_common.c,
+ src/exec_pty.c, src/net_ifs.c, src/parse_args.c, src/selinux.c,
+ src/signal.c, src/sudo.c, src/sudo_edit.c, src/tgetpass.c,
+ src/utmp.c:
+ Rename error/errorx -> fatal/fatalx and remove the exit value as it
+ was always 1.
+ [ea66f58c4da5]
+
+ * NEWS:
+ digests are supported in sudoers ldap too
+ [77d6c25f7653]
+
+ * plugins/sudoers/regress/check_symbols/check_symbols.c:
+ Print test failures to stdout like the final count so the outputis
+ not displayed out of order.
+ [f541b78ecb93]
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/eo.po, plugins/sudoers/po/hr.mo,
+ plugins/sudoers/po/hr.po, plugins/sudoers/po/it.po, src/po/da.mo,
+ src/po/da.po, src/po/eo.po, src/po/hr.mo, src/po/hr.po,
+ src/po/it.po, src/po/tr.po:
+ Sync with translationproject.org
+ [cbd70678b99f]
+
+ * Makefile.in:
+ Check for any uncommitted changes in dist target and add force-dist
+ target that omit check-dist.
+ [78dc3f41e37e]
+
+2013-04-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/regress/ttyname/check_ttyname.c:
+ Fix logic bug when checking tty via ttyname().
+ [279aee076194]
+
+ * compat/endian.h:
+ Fix check for _BIG_ENDIAN and _LITTLE_ENDIAN (Solaris) and
+ __BIG_ENDIAN__ and __LITTLE_ENDIAN__ (HP-UX)
+ [fe35e0b04502]
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [0ddebccd3045]
+
+ * NEWS, doc/sample.sudoers, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.ldap.mdoc.in,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document digest support.
+ [d794c7b9a7bc]
+
+ * MANIFEST, plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/parser/check_base64.c:
+ Simple bas64 decode unit test.
+ [344b0df0fe50]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/base64.c,
+ plugins/sudoers/match.c, plugins/sudoers/parse.h:
+ Move base64_decode into its own source file.
+ [30497e7f88bc]
+
+ * plugins/sudoers/getdate.c, plugins/sudoers/getdate.y:
+ Only check year against 2038 if time_t is 32-bit.
+ [9c1f2e3fc3ba]
+
+2013-04-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/parse.h,
+ plugins/sudoers/sssd.c:
+ Add digest support for sudoers in ldap and sss.
+ [314937b5e59e]
+
+ * INSTALL, configure, configure.in:
+ Error out in configure if the compiler doesn't support "long long".
+ [d3645c1d50d1]
+
+ * plugins/sudoers/match.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l:
+ Include stdint.h or inttypes.h before sha2.h
+ [20ad1c20313d]
+
+ * common/lbuf.c:
+ Simplify lbuf append functions by moving the realloc code into
+ lbuf_expand(). We now expand as needed each time bytes need to be
+ written to the lbuf. Also handle a NULL pointer being passed in for
+ paranoia's sake.
+ [6283ee562ef4]
+
+ * plugins/sudoers/iolog.c:
+ Zero out struct iolog_details early to avoid a potential (though
+ unlikely) dereference of stack garbage if we hit a fatal error
+ before iolog_deserialize_info() is called.
+ [2eeca8be05fb]
+
+2013-04-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Update copyright year.
+ [b843c6a43238]
+
+ * plugins/sudoers/sudoers_version.h:
+ Bump SUDOERS_GRAMMAR_VERSION for new digest support.
+ [188556fb8156]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.h,
+ plugins/sudoers/gram.y, plugins/sudoers/match.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Sanity check digest in parser so visudo can catch errors. Add base64
+ support
+ [b8586d5cc7ed]
+
+ * MANIFEST, compat/endian.h, config.h.in, configure, configure.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/sha2.c:
+ For big endian architectures just use memcpy() instead of BE macros
+ in a loop.
+ [c71a0f4a8a8e]
+
+2013-04-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, config.h.in, configure, configure.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.h, plugins/sudoers/gram.y,
+ plugins/sudoers/hexchar.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/match.c, plugins/sudoers/parse.h,
+ plugins/sudoers/regress/parser/check_digest.c,
+ plugins/sudoers/regress/parser/check_digest.out.ok,
+ plugins/sudoers/sha2.h, plugins/sudoers/sssd.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c:
+ Initial implementation of checksum support in sudoers. Currently
+ supports SHA-224, SHA-256, SHA-384, SHA-512. TODO: checksum format
+ validation in parser and base64 support. checksum support for ldap
+ sudoers
+ [b8f196346eca]
+
+2013-04-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS, plugins/sudoers/sha2.c, plugins/sudoers/sha2.h:
+ SHA-224, SHA-256, SHA-384 and SHA-512. Derived from the public
+ domain SHA-1 and SHA-2 implementations by Steve Reid and Wei Dai
+ respectively.
+ [7511d07c0a83]
+
+2013-04-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Add sudo 1.8.6p8
+ [0666fd0321ae]
+
+ * plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/po/sudoers.pot:
+ Add missing "not" in error message when mixing standalone and non-
+ standalone authentication methods.
+ [7eba4439db73]
+
+ * plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/secureware.c:
+ Check for crypt() returning NULL. Traditionally, crypt() never
+ returned NULL but newer versions of eglibc have a crypt() that does.
+ Bug #598
+ [887b9df243df]
+
+ * plugins/sudoers/auth/pam.c:
+ Better PAM error messages
+ [fd7eda53cdd7]
+
+ * plugins/sudoers/auth/kerb5.c:
+ Better error messages
+ [98142874a2f4]
+
+ * plugins/sudoers/bsm_audit.c:
+ Use same error message for getauid() failure.
+ [07f0d88cb1df]
+
+ * plugins/sudoers/sssd.c:
+ Start warning with a lower case letter for consistency and to match
+ existing translated strings.
+ [b719ac52c9e3]
+
+2013-04-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ Disable PIE on Solaris where it is not really supported.
+ [c36c84cdcc7a]
+
+ * src/ttyname.c:
+ AIX may have a 64-bit pr_ttydev that we need to convert to 32-bit
+ before we try to match it against st_rdev.
+ [5dab449fb962]
+
+ * src/ttyname.c:
+ Break out of the loop if sudo_ttyname_scan() returns non-NULL. Fixes
+ a problem finding the tty name when it is not in /dev/pts.
+ [6c205d087fa0]
+
+ * compat/snprintf.c:
+ Support %lld and %llu
+ [feabfa06c954]
+
+ * .hgignore, MANIFEST, src/Makefile.in,
+ src/regress/ttyname/check_ttyname.c:
+ Add ttyname test.
+ [e987038f8c07]
+
+2013-04-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/sl.mo, plugins/sudoers/po/sl.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po,
+ src/po/de.mo, src/po/de.po, src/po/fi.mo, src/po/fi.po,
+ src/po/pl.mo, src/po/pl.po, src/po/ru.mo, src/po/ru.po,
+ src/po/sl.mo, src/po/sl.po, src/po/uk.mo, src/po/uk.po,
+ src/po/vi.mo, src/po/vi.po, src/po/zh_CN.mo, src/po/zh_CN.po:
+ Sync with translationproject.org
+ [4d7b73b22079]
+
+ * plugins/sudoers/timestamp.c:
+ Log timestampfile to debug file.
+ [e997281146c0]
+
+ * plugins/sudoers/auth/pam.c, plugins/sudoers/po/sudoers.pot:
+ Don't add the "Password: " string we look up in the PAM text domain
+ to the sudoers.pot file.
+ [771b52244abf]
+
+2013-04-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot:
+ Synce with regcomp() error message change.
+ [fc6d3dfb8eb8]
+
+ * plugins/sudoers/sudoreplay.c:
+ Be consistent with error message when regcomp() fails.
+ [de6c69ba04e4]
+
+2013-04-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/testsudoers/test5.out.ok,
+ plugins/sudoers/regress/testsudoers/test5.sh:
+ Use group -1 instead of 1 as the invalid group since the running
+ user might have group 1 as their default group.
+ [71404a9fa75d]
+
+ * plugins/sudoers/Makefile.in:
+ PWD may be a shell builtin, use CWD instead.
+ [c443105c5091]
+
+2013-04-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c:
+ Split up check_user().
+ [ce7cc0767589]
+
+2013-04-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure.in:
+ Cosmetic fixes in the comments.
+ [640abee43c14]
+
+2013-04-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Use AC_LINK_IFELSE instead of AC_TRY_LINK Fix printing of status
+ message for visibility checks when the test fails.
+ [99665477ee55]
+
+ * config.h.in:
+ regen
+ [00c22606719a]
+
+ * configure, configure.in:
+ We no longer use mbr_check_membership() and setrlimit64() is AIX-
+ specific.
+ [43caf685a1f1]
+
+ * Makefile.in:
+ The first (all) target must be by itself or some makes will choose
+ the run the entire target list.
+ [16cf3def49f5]
+
+ * configure, configure.in:
+ Do exec_prefix expansion when enable_shared even if noexec is not
+ enabled.
+ [7ed28cb32d8d]
+
+ * compat/getgrouplist.c:
+ Use free() not efree() since we don't include alloc.h here
+ [1a008737be24]
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ regen
+ [b939f941346f]
+
+ * plugins/sudoers/regress/testsudoers/test2.sh,
+ plugins/sudoers/regress/testsudoers/test3.sh,
+ plugins/sudoers/regress/testsudoers/test5.sh:
+ Pass in expected gid to testsudoers in addition to the uid that
+ matches the test sudoers files.
+ [6a1710e8cac1]
+
+2013-04-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/missing.h:
+ Tru64 5.x does declare innetgr() and getdomainname().
+ [c75598e69c7e]
+
+ * plugins/sudoers/match.c:
+ Fix compilation when getdomainame() is not present.
+ [e831b017a962]
+
+ * config.h.in, configure.in, include/missing.h:
+ Move SET/CLR/ISSET from config.h.in to missing.h
+ [3a3dd29fd7f0]
+
+ * configure, configure.in:
+ Fix getgrouplist() check.
+ [12a2adf60e98]
+
+ * MANIFEST:
+ No more timestamp.h
+ [5677e26afc0f]
+
+ * plugins/sudoers/check.c:
+ Neded sys/time.h for struct timeval in struct sudo_tty_info.
+ [aceaadd8c400]
+
+ * plugins/sudoers/Makefile.in:
+ regen depends
+ [21675a8b67e5]
+
+ * NEWS:
+ Mention libibmldap on HP-UX
+ [75b4e4b22950]
+
+ * NEWS, plugins/sudoers/match.c:
+ Instead of checking the domain name explicitly for "(none)", just
+ check for illegal characters.
+ [ce35dda811db]
+
+ * plugins/sudoers/visudo.c:
+ Only warn once when we are unable to open the sudoers file.
+ [9e27e3aa5b10]
+
+ * plugins/sudoers/sudoers.c:
+ Fall back to opening /dev/tty to determine whether there is a tty if
+ the system doesn't have kernel support for determing the tty.
+ [2775bcf9a9b5]
+
+ * compat/getprogname.c:
+ Update guard to take __progname into account
+ [60eae3f20232]
+
+ * compat/snprintf.c:
+ Some older systems have inttypes.h but not stdint.h
+ [ed1ef160015f]
+
+ * compat/closefrom.c, compat/dlopen.c, compat/fnmatch.c,
+ compat/getaddrinfo.c, compat/getcwd.c, compat/getgrouplist.c,
+ compat/getline.c, compat/getprogname.c, compat/glob.c,
+ compat/isblank.c, compat/memrchr.c, compat/mktemp.c,
+ compat/nanosleep.c, compat/pw_dup.c, compat/sig2str.c,
+ compat/snprintf.c, compat/strlcat.c, compat/strlcpy.c,
+ compat/strsignal.c, compat/utimes.c:
+ Add guards in compat source files. Not really needed since we only
+ include them in the Makefile if they are needed but should not hurt
+ either.
+ [8cbd3b4595b9]
+
+2013-03-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y:
+ Don't include gram.h in gram.y, its contents are already included.
+ Move sudoerserror to the end of gram.y so COMMENT is declared when
+ we need to use it.
+ [7d72ebdd7222]
+
+2013-03-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure.in:
+ Remove some pre-ANSI cruft.
+ [6a95704b2116]
+
+ * plugins/sudoers/match.c:
+ Rename NAME_MATCH -> SUDOERS_NAME_MATCH and avoid pulling in glob.h
+ when it is set.
+ [da40c550ffed]
+
+ * NEWS, plugins/sudoers/iolog_path.c:
+ We still want to recognize %{seq} for the SUDOERS_NO_SEQ case but
+ just leave it as-is.
+ [9a22de140d28]
+
+2013-03-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y:
+ Add missing semicolon in rule.
+ [817d3f1b2a21]
+
+ * plugins/sudoers/sudoers.c:
+ Now that we can determine the terminal even when file descriptors
+ are redirected we can check user_ttypath rather than opening
+ /dev/tty when enforcing requiretty.
+ [56a28bc09041]
+
+ * plugins/sudoers/policy.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Stash umask in struct sudo_user so we don't need to look it up
+ later.
+ [9f85749199dc]
+
+ * plugins/sudoers/sudoers.c:
+ Minor cosmetic change
+ [c373e106ed49]
+
+ * plugins/sudoers/regress/parser/check_addr.c:
+ No longer need to declare interfaces
+ [d7ff7e579557]
+
+ * plugins/sudoers/logging.c:
+ Fix compilation in SUDOERS_NO_SEQ case
+ [9a6db9247534]
+
+ * plugins/sudoers/regress/parser/check_addr.c:
+ No longer need to define sudo_printf
+ [578ad13c3546]
+
+ * plugins/sudoers/check.c, plugins/sudoers/check.h,
+ plugins/sudoers/timestamp.c:
+ Pass auth_pw to the timestamp functions.
+ [f603649177d6]
+
+ * plugins/sudoers/iolog_path.c:
+ Fix SUDOERS_NO_SEQ
+ [17881f9bcd68]
+
+ * plugins/sudoers/locale.c:
+ Don't need all of sudoers.h in here
+ [c518150c6483]
+
+ * plugins/sudoers/sudoers.c:
+ Don't need to include sudoers_version.h here.
+ [8abb31102119]
+
+2013-03-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c:
+ DEFAULT_LECTURE is no longer used.
+ [f565c00a68c1]
+
+ * plugins/sudoers/policy.c, plugins/sudoers/sudoers.c:
+ Move sudo_conv into policy.c
+ [f699aee7136b]
+
+ * plugins/sudoers/pwutil.c:
+ cosmetic fixes
+ [930e60389ca8]
+
+ * plugins/sudoers/match.c:
+ RHEL (and perhaps other Linux distros) use the string "(none)"
+ instead of an empty string when there is no actual NIS-style domain
+ name. Bug #596
+ [11aec11489ac]
+
+ * plugins/sudoers/match.c:
+ Fix return values when NAME_MATCH is defined.
+ [ce030be9ccef]
+
+2013-03-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/pwutil.c, plugins/sudoers/pwutil.h:
+ Update copyright year.
+ [7e4b8d49addd]
+
+ * plugins/sudoers/pwutil.c, plugins/sudoers/pwutil.h,
+ plugins/sudoers/pwutil_impl.c, plugins/sudoers/sudoers.h:
+ Add sudo_set_grlist(), currently unused by the back end.
+ [b37ac1d0e8fc]
+
+ * plugins/sudoers/pwutil.c:
+ Remove unused macros, fix a debug_decl
+ [6136fb4a0d3b]
+
+ * include/missing.h:
+ Tru64 Unix doesn't prototype innetgr() or getdomainname().
+ [585ac1874dfe]
+
+ * include/missing.h:
+ Whitespace fixes
+ [0bb28cd91d97]
+
+ * common/error.c:
+ Don't need to include setjmp.h here, error.h already includes it.
+ [fd05ab00e186]
+
+2013-03-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/Makefile.in, plugins/sudoers/Makefile.in:
+ regen depends
+ [57991f5e16b4]
+
+ * plugins/sudoers/check.h:
+ Rename guard define.
+ [ccf4dba241d6]
+
+ * plugins/sudoers/check.c, plugins/sudoers/check.h,
+ plugins/sudoers/timestamp.c, plugins/sudoers/timestamp.h:
+ Move contents of timestamp.h into check.h.
+ [c139757a9283]
+
+ * plugins/sudoers/sudoers.h:
+ expand_prompt() is now in prompt.c sudo_printf extern is now in
+ error.h
+ [219bd74ca62b]
+
+ * plugins/sudoers/bsm_audit.h, plugins/sudoers/defaults.h,
+ plugins/sudoers/ins_2001.h, plugins/sudoers/ins_classic.h,
+ plugins/sudoers/ins_csops.h, plugins/sudoers/ins_goons.h,
+ plugins/sudoers/insults.h, plugins/sudoers/interfaces.h,
+ plugins/sudoers/linux_audit.h, plugins/sudoers/logging.h,
+ plugins/sudoers/parse.h, plugins/sudoers/pwutil.h,
+ plugins/sudoers/redblack.h, plugins/sudoers/sudo_nss.h,
+ plugins/sudoers/sudoers.h, plugins/sudoers/timestamp.h,
+ plugins/sudoers/toke.h:
+ Change multiple inclusion guards to be _SUDOERS_FOO_H
+ [faace6d55e78]
+
+2013-03-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/po/nl.mo, plugins/sudoers/po/nl.po,
+ src/po/nl.mo, src/po/nl.po, src/po/tr.mo, src/po/tr.po:
+ New Dutch translation for sudo and sudoers New Turkish translation
+ for sudo From translationproject.org
+ [bc918b7b23a4]
+
+2013-03-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in:
+ Fix a typo in a comment and make sure we don't mistakenly include
+ _PATH_SUDO_ASKPASS and _PATH_SUDO_SESH in config.h.in
+ [694d12ac70ec]
+
+2013-03-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ Don't build check_symbols if we are linking sudoers in statically.
+ [f6602723bab7]
+
+ * configure, configure.in:
+ Use $host_os not $host when we only care about the os name and
+ version.
+ [05e4f4fcba06]
+
+ * aclocal.m4, configure, configure.in:
+ Suppress duplicate -L and -I flags.
+ [228f2f581aed]
+
+ * common/Makefile.in, compat/regress/fnmatch/fnm_test.c:
+ Fix regress tests on non-OpenBSD platforms.
+ [9d91bc859c50]
+
+ * configure, configure.in:
+ If we find sasl/sasl.h there's no need to check for sasl.h too
+ [889efaa86012]
+
+ * aclocal.m4, configure, configure.in:
+ Add -R flags at the very end after configure link tests are done
+ since we can only count on libtool to accept -R, the compiler front
+ end may not. Also unify the libldap and libibmldap tests using
+ AC_SEARCH_LIBS and check for -lCsup on HP-UX which is needed by
+ libibmldap (but is not an explicit dependency).
+ [ab1451894351]
+
+2013-03-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Back out changes that broke detection of skey, opie and ldap
+ libraries.
+ [ffa82b8f8641]
+
+ * plugins/sudoers/regress/testsudoers/test1.sh,
+ plugins/sudoers/regress/testsudoers/test2.sh,
+ plugins/sudoers/regress/testsudoers/test3.sh,
+ plugins/sudoers/regress/testsudoers/test4.sh,
+ plugins/sudoers/regress/testsudoers/test5.sh,
+ plugins/sudoers/regress/visudo/test1.sh,
+ plugins/sudoers/regress/visudo/test2.sh,
+ plugins/sudoers/regress/visudo/test3.sh:
+ Add explicit "exit 0" to prevent the check target from ending
+ prematurely.
+ [cca411b492bd]
+
+ * plugins/sudoers/Makefile.in:
+ Fix exit values in check target so we don't have to ignore errors.
+ [cbc429c409e9]
+
+ * plugins/sudoers/Makefile.in:
+ Fail a test if there is unexpected stderr output.
+ [4fc24d536bec]
+
+ * MANIFEST:
+ Fix path to sudo.conf manuals; remove non-existant test2.err.ok
+ [6b8bcd60dd85]
+
+ * src/load_plugins.c:
+ Fix compilation in dynamic mode.
+ [679856fa0774]
+
+ * configure, configure.in:
+ On HP-UX, libibmldap has a hidden dependency on libCsup
+ [22994709d77c]
+
+ * compat/dlopen.c:
+ Pass BIND_VERBOSE to shl_load()
+ [0060b9cfa9ab]
+
+ * configure, configure.in:
+ Only create static helper libs when --disable-shared is specified.
+ [1fcdb1a437e0]
+
+ * src/load_plugins.c:
+ Ubreak static build.
+ [4ac9f96be285]
+
+ * INSTALL, aclocal.m4, configure, configure.in:
+ Replace --with-rpath and --with-blibpath with --disable-rpath. Now
+ that we use libtool for linking we can just use the -R flag and have
+ libtool translate it to the proper linker flag.
+ [09798fad6888]
+
+2013-03-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Bump I/O buffer size 32K
+ [4ef793225309]
+
+2013-03-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in:
+ Document sesh Path setting.
+ [34b0b903b4f8]
+
+ * src/exec.c, src/exec_common.c:
+ Move exec_cmnd to exec.c to fix a compilation issue with sesh.c
+ [06aa1956f38d]
+
+ * common/sudo_conf.c, configure, configure.in, include/sudo_conf.h,
+ src/selinux.c:
+ Make sesh path configurable in sudo.conf
+ [91d331f273b7]
+
+ * configure, configure.in:
+ Use -fno-pie and -nopie if supported when --disable-pie is
+ specified.
+ [777138c04dcc]
+
+2013-03-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Document direct execution of the command if the policy plugin has no
+ close function.
+ [6a14145c6e80]
+
+2013-03-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/pam.c:
+ Only delete creds if we actually established them. Print an error if
+ pam_setcred() fails and we actually authenticated.
+ [1e015314903b]
+
+ * common/Makefile.in, plugins/group_file/Makefile.in:
+ regen
+ [dd8cee2a5e1b]
+
+ * common/alloc.c, include/alloc.h:
+ Convert efree() to a macro that just casts to void * and does
+ free(). If the system free() can't handle free(NULL) this may crash
+ but C89 was a long time ago.
+ [efd0ff9270fb]
+
+ * configure, configure.in:
+ Define _REENTRANT for HP-UX when we add -lpthread to SUDO_LIBS.
+ Fixes a problem with errno sometimes not being set on error on HP-
+ UX.
+ [54b419d58320]
+
+ * common/sudo_debug.c:
+ Fix debug logging from the plugin when there is no error number.
+ This was broken in the big debugging reorg for 1.8.7.
+ [2ea7e145e928]
+
+2013-03-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in, plugins/group_file/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in, src/load_plugins.c:
+ Always install plugins with a .so extension regardless of what
+ extension the system uses for shared libraries. That way the
+ group_plugin sudoers setting can be shared between heterogenous
+ systems.
+ [a7e6ecff6fdf]
+
+ * plugins/sudoers/match.c:
+ Mac OS X has netgroup functions in netdb.h.
+ [243881a974aa]
+
+ * plugins/sudoers/parse.h:
+ Tags in struct cmndtag can be set to IMPLIED as well.
+ [cb6926988cc8]
+
+ * plugins/sudoers/parse.c:
+ Quiet a compiler warning.
+ [14e608c2001d]
+
+ * plugins/sudoers/testsudoers.c:
+ Quiet an llvm checker warning.
+ [2eeb9f3d08f3]
+
+ * plugins/sudoers/parse.c:
+ Quiet gcc -Wuninitialized false positive
+ [643ad987503d]
+
+2013-03-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in:
+ Document group_file and system_group plugins.
+ [b56511e79230]
+
+ * NEWS:
+ Sudo 1.8.7
+ [e95183b8fa27]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Try to clarify that sudoedit in sudoers should not include a leading
+ pathname.
+ [7b2beac92a9c]
+
+ * plugins/sudoers/pwutil_impl.c:
+ Make sure groupname_len is at least 32 just to be on the safe side.
+ It is better to allocate a little extra and not need it than to have
+ to reallocate and start over.
+ [6d3e1ba47de9]
+
+ * include/alloc.h, include/missing.h:
+ Add __malloc_like macro to apply __malloc__ attribute to emalloc,
+ ecalloc and estrdup. It cannot be applied to realloc since that may
+ return the same pointer.
+ [8d70cb81d1f1]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Fix potential double free in an error path.
+ [657573feb6a4]
+
+ * src/exec_pty.c:
+ When running the command in a pty, defer the call to exec_setup()
+ until just before we exec the command. This is consistent with the
+ non-pty path. As a side effect, the monitor process runs as root and
+ not the runas user.
+ [e2a7f8c7ee4c]
+
+2013-03-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/closefrom.c:
+ Update copyright year.
+ [9b652af4dfc0]
+
+2013-03-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/closefrom.c:
+ Use pst_highestfd from pstat_getproc() on HP-UX.
+ [09f3fea46a3d]
+
+2013-02-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, common/Makefile.in, doc/Makefile.in,
+ plugins/sudoers/Makefile.in:
+ Clean up generated test files and other minor housekeeping.
+ [f5f4fdd908e1]
+
+ * plugins/sudoers/iolog.c:
+ Add back gettimeofday() call inadvertantly removed in e1abb9810a83
+ [675cce8401ae]
+
+ * config.h.in, configure, configure.in, src/ttyname.c:
+ Use pstat() on HP-UX to determine the tty device.
+ [2884af22a9df]
+
+ * plugins/sudoers/auth/pam.c:
+ Fix PAM compilation: def_pam_session, not just pam_session.
+ [5417d7acc6ea]
+
+ * doc/fixmdoc.sh:
+ Don't remove the -S option description when trimming out selinux.
+ Bug #592
+ [8a94f2cfa0a0]
+
+2013-02-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Update for Sudo 1.8.6p7
+ [0858a73e9c40]
+
+2013-02-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Document when sudo may exec the command directly instead of forking.
+ [da41951edc28]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in:
+ Document that close and version be NULL for plugin API >= 1.3 and
+ that sudo may execute the command directly if there is no close, or
+ pty or timeout needed.
+ [e5f929ddeaf8]
+
+ * plugins/sudoers/auth/sudo_auth.c:
+ Fix debug_decl for sudo_auth_begin_session and
+ sudo_auth_end_session.
+ [58243392c0df]
+
+ * configure, configure.in, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/defaults.c:
+ Add pam_session sudoers option.
+ [d994465db9f1]
+
+ * plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.h:
+ Dummy out close function if there is no end_session for the auth
+ method and the front-end can handle a NULL close function. Avoids
+ the extra sudo process when we don't actually need it.
+ [74886d5b0fb6]
+
+2013-02-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, aclocal.m4:
+ Add m4/ to paths m4_include parameters so we don't need to use
+ autoconf's -I flag.
+ [4fd86e7a84f3]
+
+ * src/exec.c, src/exec_common.c, src/exec_pty.c, src/sudo_exec.h,
+ src/sudo_plugin_int.h:
+ If the policy plugin does not provide a close function, there is no
+ command timeout and no pty is required, skip the event loop and just
+ exec the command directly.
+ [ad532f107170]
+
+ * src/sudo.c:
+ Do not crash if the plugin close and version functions are not
+ defined. If there is no policy close function, simply print a
+ warning that the command was not found.
+ [c789a9dd54e8]
+
+2013-02-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/parse.c:
+ Fix typos in selinux/solaris privs specific code.
+ [9af3999361b4]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, src/parse_args.c:
+ Pass the default plugin directory to the plugin via the settings
+ list. Could be used by a stacking plugin.
+ [688e771fc145]
+
+ * plugins/sudoers/timestamp.c:
+ Completely ignore time stamp file if it is set to the epoch,
+ regardless of what gettimeofday() returns.
+ [df58842af660]
+
+ * doc/CONTRIBUTORS:
+ Add Nikolai Kondrashov
+ [df59791438f9]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sssd.c:
+ Use userpw_matches() for username matching so #uid works for
+ sudoRunAsUser.
+ [a124062334df]
+
+ * plugins/sudoers/sssd.c:
+ Avoid calling realloc3() with a zero size parameter when all
+ retrieved sssd rules fail. Otherwise we'll get a run-time error due
+ to malloc(0) checking.
+ [84dfcb73ebd7]
+
+ * plugins/sudoers/sssd.c:
+ Do not send error mail if a user is not found in SSSD. Local users
+ can run sudo too. From Nikolai Kondrashov
+ [3d2ae99ee468]
+
+2013-02-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/regress/sudo_conf/test4.in,
+ common/regress/sudo_conf/test4.out.ok:
+ Test setting disable_coredump to illegal value.
+ [3c71c6c49027]
+
+ * common/sudo_conf.c:
+ Fix atobool() usage.
+ [d40c9f4d06b0]
+
+ * common/regress/sudo_conf/conf_test.c:
+ Remove unused variable.
+ [328b524b365b]
+
+ * plugins/sudoers/sudoers.c:
+ Make "sudo -l non_existent_command" warn that non_existent_command
+ doesn't exist, not the "list" pseudo-command.
+ [9dc0388fc4f3]
+
+ * plugins/sudoers/parse.c:
+ Make sudoers file long list output better match the format used by
+ ldap sudoers. Tags are now converted to options and there is a
+ single command per line.
+ [6e6dc3f20d84]
+
+ * doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in,
+ doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Use the correct the sudoers policy symbol names and undo an editor
+ goof committed when adding max_groups to sudo.conf.
+ [2a6f7ddf5cc3]
+
+ * plugins/sudoers/parse.c, plugins/sudoers/sudo_nss.c:
+ For "sudo -l" start a new line if the runas list changes to make the
+ output easier to read.
+ [7dc3d724c924]
+
+2013-02-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/parse.c, plugins/sudoers/sudo_nss.c:
+ For "sudo -l" and "sudo -ll" only print the runas info for
+ subsequent commands in a list if the runas info has changed. If we
+ have new runas info, print out the tags again so as to be less
+ confusing to the user. For "sudo -ll" set the line continuation
+ indent to 8.
+ [b5ec02fe7fc1]
+
+2013-02-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, Makefile.in, configure, configure.in, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/group_file/Makefile.in, plugins/group_file/getgrent.c,
+ plugins/group_file/group_file.c, plugins/group_file/group_file.exp,
+ plugins/group_file/plugin_test.c, plugins/sample_group/Makefile.in,
+ plugins/sample_group/getgrent.c, plugins/sample_group/plugin_test.c,
+ plugins/sample_group/sample_group.c,
+ plugins/sample_group/sample_group.exp:
+ Rename sample_group plugin to group_file. Install group_file and
+ system_group plugins by default.
+ [951b3e446fae]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/iolog.c,
+ plugins/sudoers/policy.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Add maxseq sudoers option to limit the max number of I/O log files.
+ [e1abb9810a83]
+
+2013-02-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Log lines and columns in the iolog file.
+ [03adb6230e05]
+
+2013-02-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/Makefile.in, common/regress/sudo_conf/conf_test.c,
+ common/regress/sudo_conf/test1.in,
+ common/regress/sudo_conf/test1.out.ok,
+ common/regress/sudo_conf/test2.in,
+ common/regress/sudo_conf/test2.out.ok,
+ common/regress/sudo_conf/test3.in,
+ common/regress/sudo_conf/test3.out.ok, common/sudo_conf.c,
+ include/sudo_conf.h, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c, src/sesh.c,
+ src/sudo.c:
+ Add simple regress tests for sudo.conf parsing.
+ [3c36b61bf61c]
+
+ * src/sudo.c:
+ Always display the I/O plugin version as long as its open functions
+ doesn't return an error. Previously it was only displayed if the
+ plugin open returned 1.
+ [4b0277db3f8c]
+
+ * plugins/sudoers/pwutil_impl.c:
+ Use sysconf(_SC_LOGIN_NAME_MAX) to find max username length instead
+ of poking around in struct utmpx.
+ [2c0cc5c42958]
+
+ * plugins/sudoers/pwutil_impl.c, src/parse_args.c, src/sudo.c:
+ #include "sudo_usage.h" not <sudo_usage.h> so we get the one in the
+ build directory and not the src dir when using a separate build
+ directory.
+ [1fcb7ba13018]
+
+2013-02-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/fileops.c:
+ If a line was longer that 0x80000000 the bit hack to round to the
+ next power of two would roll over to zero.
+ [f4f729cf6f0f]
+
+ * plugins/sudoers/policy.c, plugins/sudoers/pwutil_impl.c,
+ plugins/sudoers/sudoers.h, src/sudo.c:
+ Use max_groups in front-end and plugin.
+ [bf1e74166831]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, src/parse_args.c:
+ Pass max_groups to plugin in settings list.
+ [d7d76e8651f4]
+
+ * common/sudo_conf.c, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, include/sudo_conf.h:
+ Add max_groups setting to sudo.conf (currently unused) and remove
+ unused return value from setters.
+ [f6494f71e1f0]
+
+2013-02-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ Reorganize configure options
+ [23475de8039f]
+
+2013-02-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Add Sudo 1.8.6p7
+ [5192fc511cbe]
+
+2013-02-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL.configure:
+ Sync with autoconf 2.68
+ [985e5c8efa4e]
+
+ * INSTALL, README:
+ Remove obsolete OS notes and move build requirements to INSTALL.
+ [bf0dd53ca164]
+
+2013-02-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in:
+ Sort elements of the settings, user_info and command_info lists.
+ [663062ada5b7]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Remove trailing white space
+ [027916a6c8e7]
+
+ * plugins/sudoers/policy.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/timestamp.c, plugins/sudoers/timestamp.h:
+ Store the session ID in the tty ticket file too. A tty may only be
+ in one session at a time so if the session ID doesn't match we
+ ignore the ticket.
+ [4eb2cb8df48b]
+
+2013-02-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c, src/sudo.c:
+ Move tzset() call from sudoers plugin to sudo front end.
+ [3c058dad8772]
+
+ * doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in,
+ doc/sudoers.cat, doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ Mention line continuation
+ [399873f8c805]
+
+ * MANIFEST, common/Makefile.in, common/fileops.c,
+ common/regress/sudo_parseln/parseln_test.c,
+ common/regress/sudo_parseln/test1.in,
+ common/regress/sudo_parseln/test1.out.ok,
+ common/regress/sudo_parseln/test2.in,
+ common/regress/sudo_parseln/test2.out.ok,
+ common/regress/sudo_parseln/test3.in,
+ common/regress/sudo_parseln/test3.out.ok,
+ common/regress/sudo_parseln/test4.in,
+ common/regress/sudo_parseln/test4.out.ok,
+ common/regress/sudo_parseln/test5.in,
+ common/regress/sudo_parseln/test5.out.ok,
+ common/regress/sudo_parseln/test6.in,
+ common/regress/sudo_parseln/test6.out.ok, common/sudo_conf.c,
+ include/fileops.h, plugins/sudoers/env.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/sudo_nss.c:
+ Add line continuation support to sudo_parseln() and make it use
+ getline() instead of fgets() internally.
+ [d02bf3973fc5]
+
+2013-02-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sample/sample_plugin.c:
+ Fix memory leak in error path; found by llvm checker
+ [d090c26a5b00]
+
+ * plugins/sudoers/sudoreplay.c:
+ Remove useless store detected by llvm checker.
+ [12a4db91651a]
+
+ * configure, configure.in, doc/UPGRADE, mkpkg, src/Makefile.in,
+ src/load_plugins.c, sudo.pp:
+ Sudo now stores its libexec files in a "sudo" subdirectory instead
+ of in libexec itself. For backwards compatibility, if the plugin is
+ not found in the default plugin directory, sudo will check the
+ parent directory default directory ends in "/sudo".
+ [5de67de76489]
+
+ * plugins/sample/sample_plugin.c, plugins/sample_group/sample_group.c,
+ plugins/system_group/system_group.c:
+ Add missing __dso_public to plugin structs so they are exported.
+ [dde703577621]
+
+ * doc/sudo.conf.cat, doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in:
+ Mention that sudoers has its own plugins too.
+ [0a6c6203b512]
+
+2013-02-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/visudo.cat, doc/visudo.man.in, doc/visudo.mdoc.in:
+ Correct last change date.
+ [45894291d792]
+
+ * doc/sudo.cat, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in:
+ Remove duplicated sudo.conf info in the sudo, sudoers and
+ sudo_plugin manuals and cross-reference the new sudo.conf manual.
+ [b808ba29cf3a]
+
+ * doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in:
+ Fix typos
+ [0e70964150c6]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in:
+ Fix some typos.
+ [94ae045cfbc6]
+
+ * MANIFEST, doc/Makefile.in, doc/sudo.conf.cat, doc/sudo.conf.man.in,
+ doc/sudo.conf.mdoc.in:
+ Add standalone sudo.conf manual page.
+ [d64d949b700c]
+
+ * doc/sample.sudo.conf:
+ add group_source example
+ [118c1ba1c014]
+
+ * configure, configure.in, doc/sample.sudo.conf, doc/sudo.man.in,
+ doc/sudo.mdoc.in, doc/sudo_plugin.man.in, doc/sudo_plugin.mdoc.in,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Use PLUGINDIR in the manuals and fix a typo in the sample sudo.conf.
+ [f5bd6006dc1c]
+
+ * plugins/sudoers/po/it.mo, plugins/sudoers/po/it.po, src/po/it.mo,
+ src/po/it.po:
+ Sync with translationproject.org
+ [a6f2b9aac371]
+
+2013-02-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/vi.mo, plugins/sudoers/po/vi.po, src/po/fi.mo,
+ src/po/fi.po, src/po/gl.mo, src/po/gl.po, src/po/vi.mo,
+ src/po/vi.po:
+ Sync with translationproject.org
+ [ba546666969d]
+
+2013-02-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/da.po, plugins/sudoers/po/eo.mo,
+ plugins/sudoers/po/eo.po, src/po/da.po, src/po/eo.mo, src/po/eo.po,
+ src/po/es.po, src/po/gl.po:
+ Sync with translationproject.org
+ [cdc454e34c03]
+
+2013-01-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Clarify ttyname changes.
+ [cbf2f80fe582]
+
+ * NEWS:
+ Add 1.8.6p6
+ [3aa591e98b3b]
+
+ * src/ttyname.c:
+ Remove ttyname() fall back code on systems where we can query the
+ kernel for the tty device via /proc or sysctl(). If there is no
+ controlling tty, it is better to just treat the tty as unknown
+ rather than to blindly use what is hooked up to std{in,out,err}.
+ [b2bd3005d2e4]
+
+2013-01-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/sudo_conf.c, include/sudo_conf.h, src/sudo.c:
+ Add group_source setting in sudo.conf to allow the admin to specify
+ how a user's groups are looked up. Legal values are static (just the
+ kernel list from getgroups), dynamic (whatever the group database
+ includes) and adaptive (only use group db if kernel group list is
+ full).
+ [87a5b02e22ad]
+
+ * plugins/sudoers/policy.c:
+ Pass back exec_background to front end if it is enabled in sudoers.
+ [8230e1cd0bbd]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Mention that exec_background is for 1.8.7 and higher only.
+ [fdf0d5a3e182]
+
+2013-01-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST:
+ Add missing test files.
+ [1165389aa5e6]
+
+ * plugins/sudoers/regress/visudo/test3.err.ok,
+ plugins/sudoers/regress/visudo/test3.out.ok,
+ plugins/sudoers/regress/visudo/test3.sh:
+ Add regress test for bug 361
+ [54c7fb61b82d]
+
+ * plugins/sudoers/iolog.c:
+ Add __dso_public to extern declaration of declaration to match
+ actual definition.
+ [4695ded501e6]
+
+ * NEWS:
+ Add 1.8.6p5
+ [b07b28c5c4d7]
+
+2013-01-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/regress/visudo/test2.err.ok,
+ plugins/sudoers/regress/visudo/test2.out.ok,
+ plugins/sudoers/regress/visudo/test2.sh:
+ Add test for visudo cycle check core dump; test case from Daniel
+ Kopecek
+ [41074541147a]
+
+ * plugins/sudoers/visudo.c:
+ Fix potential stack overflow due to infinite recursion in alias
+ cycle detection. From Daniel Kopecek.
+ [d7e018a87434]
+
+ * common/sudo_conf.c, include/sudo_conf.h, src/load_plugins.c:
+ Ignore duplicate entries in sudo.conf and report the line number
+ when there is an error. Warn, don't abort if there is more than one
+ policy plugin.
+ [dfcb5a698f0a]
+
+ * plugins/sudoers/tsgetgrpw.c:
+ Use strtoul() not atoi().
+ [58a52cf9b6b8]
+
+2013-01-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/Makefile.in:
+ regen depends for to add compat/nss_dbdefs.h for getgrouplist.lo
+ [9b44e9d26d16]
+
+ * compat/nss_dbdefs.h:
+ Fix typo that breaks the build on HP-UX.
+ [b9ab6ba23485]
+
+ * MANIFEST, compat/getgrouplist.c, compat/nss_dbdefs.h, config.h.in,
+ configure, configure.in:
+ Use nss_search() to implement getgrouplist() where available. Tested
+ on Solaris and HP-UX. We need to include a compatibility header for
+ HP-UX which uses the Solaris nsswitch implementation but doesn't
+ ship nss_dbdefs.h.
+ [d29dbc4dc06d]
+
+2013-01-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c, src/exec_pty.c, src/signal.c, src/sudo.h:
+ Remove extra flag to sudo_sigaction(). We want to trap the signal
+ regardless of whether or not it is ignored by the underlying command
+ since there's no way to know what signal handlers the command will
+ install. Now we just use sudo_sigaction() to set a flag in
+ saved_signals[] to indicate whether a signal needs to be restored
+ before exec.
+ [c042d52c7192]
+
+2013-01-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/getgrouplist.c, config.h.in, configure, configure.in:
+ Use _getgroupsbymember() on Solaris to get the groups list. Fixes
+ performance problems with the getgroupslist() compat on Solaris
+ systems with network-based group databases.
+ [287d3ae2ce8d]
+
+2013-01-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in:
+ Document signal handler behavior in plugin API 1.3
+ [20dc9d1c105f]
+
+ * MANIFEST, include/sudo_plugin.h, src/Makefile.in, src/exec.c,
+ src/exec_pty.c, src/signal.c, src/sudo.c, src/sudo.h:
+ Move signal code into its own source file and add sudo_sigaction()
+ wrapper that has an extra flag to check the saved_signals list to
+ only install the handler if the signal is not already ignored. Bump
+ plugin API version for the new front-end signal behavior.
+ [5d2f27a1b404]
+
+ * plugins/sudoers/sudoers.c, src/exec.c, src/sudo.c, src/sudo.h,
+ src/sudo_exec.h:
+ Catch SIGINT, SIGQUIT and SIGTSTP in the front end before we execute
+ the command. If we get SIGINT or SIGQUIT, call the plugin close()
+ functions as if the command was interrupted. If we get SIGTSTP,
+ uninstall the handler and deliver SIGTSTP to ourselves.
+ [332baf3a81b7]
+
+ * src/exec.c, src/exec_pty.c:
+ Rename handle_signals() to dispatch_signals(). Block other signals
+ in handler() so we don't have to worry about the write() being
+ interrupted.
+ [666e95c9a0f1]
+
+2013-01-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/tgetpass.c:
+ Rename signal handler to avoid name clash with one in exec.c
+ [8913101a29b6]
+
+2013-01-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo.c:
+ Add missing call to save_signals().
+ [47d075d7326b]
+
+2013-01-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ Fill in the comment block at the top of the .pot files and preserve
+ it when regenerating them.
+ [6449497b76db]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.mdoc.in, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in,
+ plugins/sudoers/sudoers.c, src/exec_pty.c, src/sudo.c, src/sudo.h:
+ Add exec_background option in plugin command info and a sudoers
+ option to match. When set, commands are started in the background
+ and automatically foregrounded as needed. There are issues with some
+ ill-mannered programs (like Linux su) so this is not the default.
+ [c0b32b0938f2]
+
+ * common/Makefile.in:
+ regen
+ [2b2b220e7aea]
+
+ * src/Makefile.in:
+ Add SESH_OBJS variable for sesh object files.
+ [d3e04ae8fd1f]
+
+ * configure.in, doc/LICENSE, plugins/sudoers/redblack.c:
+ Update copyright year.
+ [61a0f0cedb13]
+
+ * src/exec_pty.c:
+ Always resume the command in the foreground if sudo itself is the
+ foreground process. This helps work around poorly behaved programs
+ that catch SIGTTOU/SIGTTIN but suspend themselves with SIGSTOP. At
+ worst, sudo will go into the background but upon resume the command
+ will be runnable. Otherwise, we can get into a situation where the
+ command will immediately suspend itself.
+ [c368ac3eb2e4]
+
+ * configure, configure.in:
+ Use -fstack-protector-all in preference to -fstack-protector where
+ supported.
+ [f930c95ceb51]
+
+2013-01-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Only test for -fstack-protector and -fvisibility=hidden on GNU
+ compatible compilers.
+ [796f4696d863]
+
+2013-01-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Add Sudo 1.8.6p4
+ [8a928de8e717]
+
+ * common/Makefile.in, compat/Makefile.in, configure, configure.in,
+ plugins/sample/Makefile.in, plugins/sample_group/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/system_group/Makefile.in,
+ src/Makefile.in:
+ Break out stack smashing protector options into SSP_CFLAGS and
+ SSP_LDFLAGS so we can use it everywhere (unlike LT_LDFLAGS).
+ [01be114fc9fb]
+
+2013-01-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS, plugins/sudoers/redblack.c:
+ In rbrepair(), make sure we never try to change the color of the
+ sentinel node, which is the first entry, not the root. From Michael
+ King
+ [3fc4dc4004ec]
+
+2012-12-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ No need to restore default signal handler for SIGSTOP as it is not
+ catchable. Attempting to do so is harmless but sigaction() will fail
+ and set errno to EINVAL which makes it looks like there is an error.
+ [be7c0b759e9a]
+
+ * src/exec.c:
+ Print SIGCONT_FG and SIGCONT_BG properly in debug output.
+ [93e59e301c8f]
+
+2012-12-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Disable PIE on FreeBSD/ia64, otherwise sudo will segfault.
+ [9ed48f696595]
+
+2012-12-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/missing.h:
+ Add howmany() macro since some systems have this in sys/param.h
+ which we no longer include.
+ [2c5efaa16c45]
+
+2012-12-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/sudoers/test11.toke.out.ok:
+ Remove errant file.
+ [a91699beffc6]
+
+2012-12-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/regress/parser/check_fill.c:
+ Remove obsolete sudoers_cleanup() stubs.
+ [89153025a2ae]
+
+ * common/alloc.c, common/atobool.c, common/fileops.c,
+ common/fmt_string.c, common/lbuf.c, common/secure_path.c,
+ common/sudo_conf.c, common/sudo_debug.c, common/term.c,
+ compat/closefrom.c, compat/getcwd.c, compat/glob.c,
+ compat/snprintf.c, include/missing.h,
+ plugins/sample/sample_plugin.c, plugins/sample_group/getgrent.c,
+ plugins/sample_group/plugin_test.c,
+ plugins/sample_group/sample_group.c, plugins/sudoers/alias.c,
+ plugins/sudoers/auth/afs.c, plugins/sudoers/auth/aix_auth.c,
+ plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/dce.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/passwd.c,
+ plugins/sudoers/auth/rfc1938.c, plugins/sudoers/auth/secureware.c,
+ plugins/sudoers/auth/securid5.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/boottime.c,
+ plugins/sudoers/check.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/env.c, plugins/sudoers/find_path.c,
+ plugins/sudoers/getspwuid.c, plugins/sudoers/goodpath.c,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/group_plugin.c, plugins/sudoers/interfaces.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/logging.c, plugins/sudoers/match.c,
+ plugins/sudoers/match_addr.c, plugins/sudoers/parse.c,
+ plugins/sudoers/policy.c, plugins/sudoers/prompt.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/pwutil_impl.c,
+ plugins/sudoers/redblack.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/timestamp.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c,
+ plugins/sudoers/tsgetgrpw.c, plugins/sudoers/visudo.c,
+ plugins/system_group/system_group.c, src/conversation.c, src/exec.c,
+ src/exec_common.c, src/exec_pty.c, src/get_pty.c,
+ src/load_plugins.c, src/net_ifs.c, src/parse_args.c, src/sudo.c,
+ src/sudo_edit.c, src/tgetpass.c, src/ttyname.c, src/utmp.c:
+ Don't include <sys/param.h>. We only needed it for MAXPATHLEN,
+ MAXHOSTNAMELEN and the MIN/MAX macros. We now use PATH_MAX and
+ HOST_NAME_MAX throughout without falling back on MAXPATHLEN or
+ MAXHOSTNAMELEN and define our own MIN/MAX macros as needed.
+ [f4807d46f504]
+
+ * include/missing.h, plugins/sudoers/match.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c, src/sudo.c:
+ Use MAX_HOST_NAME+1 (limits.h) instead of MAXHOSTNAMELEN
+ (sys/param.h or netdb.h).
+ [2544f5e306dd]
+
+2012-11-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/logging.c:
+ Move debug_decl() in log_failure() to be after the variable
+ declarations for C89.
+ [f48d2035ab44]
+
+2012-11-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/error.c, include/error.h, plugins/sudoers/iolog.c,
+ plugins/sudoers/logging.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Cannot wrap sigsetjmp() or we end up returning to the wrong place.
+ Use a macro instead.
+ [749ee6acdad8]
+
+2012-11-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/policy.c:
+ Fix return in sudoers_policy_open that should be debug_return.
+ [a78b795b6846]
+
+2012-11-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/ttyname.c:
+ Define sudo_ttyname_dev() for the HAVE_STRUCT_PSINFO_PR_TTYDEV case
+ too.
+ [acfa891c229e]
+
+ * src/solaris.c:
+ Quiet a gcc warning and add comment about needing to keep the handle
+ open.
+ [f954f228960f]
+
+2012-11-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ mention --disable-shared
+ [6954d39e2d0f]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in:
+ Add missing command_info argument in I/O plugin open() prototype.
+ Bug #579
+ [72beb07aba0e]
+
+2012-11-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/gram.c:
+ Regen for proper line numbers.
+ [6cf6e132e764]
+
+ * configure, configure.in:
+ Add locale_stub.o to SUDO_OBJS, not locale_stub.lo.
+ [d604dc8ca38a]
+
+ * common/sudo_printf.c:
+ Include missing.h for __printflike.
+ [a33640600faf]
+
+ * plugins/sudoers/iolog.c:
+ Saner loop invariant in io_mkdirs (cosmetic only).
+ [dc30274afe38]
+
+ * MANIFEST, common/Makefile.in, common/error.c, common/sudo_printf.c,
+ configure, configure.in, include/error.h, mkdep.pl,
+ plugins/sudoers/Makefile.in, plugins/sudoers/locale.c,
+ plugins/sudoers/logging.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/policy.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c,
+ src/Makefile.in, src/error.c, src/exec_pty.c, src/locale_stub.c,
+ src/sesh.c:
+ Move warn/error into common and make static builds work.
+ [4d3f374f4e4c]
+
+ * MANIFEST, common/Makefile.in, common/sudo_debug.c,
+ common/sudo_printf.c, include/error.h, plugins/sudoers/Makefile.in,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/iolog.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/policy.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c,
+ src/Makefile.in, src/conversation.c, src/sesh.c:
+ Move _sudo_printf from src/conversation.c to common/sudo_printf.c.
+ Add sudo_printf function pointer that is initialized to
+ _sudo_printf() instead of requiring a sudo_conv function pointer
+ everywhere. The plugin will reset sudo_printf to point to the
+ version passed in via the plugin open function. Now plugin_error.c
+ can just call sudo_printf in all cases. The sudoers binaries no
+ longer need their own version of sudo_printf.
+ [9b09d3f63790]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/logging.c,
+ plugins/sudoers/plugin_error.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Add plugin_setjmp() wrapper for siglongjmp(error_jmp, 1) so we don't
+ need error_jmp to be extern. Also add plugin_clearjmp() that clears
+ a flag so error()/errorx() knows when to call exit() vs. longjmp().
+ [5a4617148e70]
+
+ * plugins/sudoers/set_perms.c:
+ Let warning() call gettext() for us.
+ [ab8d502ba4ac]
+
+ * include/error.h, plugins/sudoers/plugin_error.c, src/error.c:
+ Do locale swapping in the warning()/error() macros themselves
+ instead of in the underlying functions.
+ [4cd205540e17]
+
+ * common/alloc.c, common/list.c, include/error.h,
+ plugins/sudoers/env.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/visudo.c, src/error.c,
+ src/hooks.c:
+ Rename warning2()/error2() -> warning_nodebug()/error_nodebug().
+ [48346393634d]
+
+ * common/sudo_conf.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/rfc1938.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/linux_audit.c,
+ plugins/sudoers/logging.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/policy.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, plugins/sudoers/visudo.c, src/error.c,
+ src/exec.c, src/exec_common.c, src/exec_pty.c, src/load_plugins.c,
+ src/net_ifs.c, src/parse_args.c, src/selinux.c, src/sesh.c,
+ src/solaris.c, src/sudo.c, src/sudo_edit.c, src/tgetpass.c:
+ Call gettext() on parameters for warning()/warningx() instead of
+ having warning() do it for us.
+ [c71088bc9d3e]
+
+ * Makefile.in, plugins/sudoers/alias.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c:
+ Call gettext() in sudoerserror() in the user's locale and pass the
+ untranslated string to it.
+ [cdbfc231b848]
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/locale.c,
+ plugins/sudoers/logging.h, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ Allow sudoers programs (visudo, sudoreplay, visudo) to use
+ plugin_error.c instead of the error.c from the front-end. This means
+ sudoers_setlocale() needs to be independent of the sudo_user struct
+ and the defaults table. The sudoers locale is now updated via a
+ callback.
+ [e356f5f8cd6a]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/logging.c,
+ plugins/sudoers/plugin_error.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Include setjmp.h in sudoers.h Move error_jmp into plugin_error.c
+ Rename sudoers_plugin_cleanup sudoers_cleanup Make sudoers
+ warning/error functions work when sudo_conv is NULL
+ [7365ee24a779]
+
+ * src/error.c:
+ No need to change locale in front-end warning()/error().
+ [23dc1df7f93b]
+
+ * plugins/sudoers/tsgetgrpw.c:
+ Ignore bad lines in passwd/group file instead if stopping processing
+ when we hit one.
+ [79b790559075]
+
+ * plugins/sudoers/regress/testsudoers/test2.sh,
+ plugins/sudoers/regress/testsudoers/test3.sh,
+ plugins/sudoers/regress/testsudoers/test5.sh:
+ Bash doesn't let you set UID to use MYUID instead.
+ [5be56335f059]
+
+ * plugins/sudoers/visudo.c:
+ Avoid NULL deref for unknown Defaults in strict mode.
+ [545c21c1e7d6]
+
+ * common/sudo_conf.c, common/sudo_debug.c:
+ See DEFAULT_TEXT_DOMAIN
+ [3d723e1d27db]
+
+2012-11-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * .hgignore:
+ Add signame.c and mksigname.
+ [d59bbf423f00]
+
+ * plugins/sudoers/Makefile.in:
+ Fold preinstall into install-plugin and pass the path to the plugin
+ binary to the preinstall command.
+ [2c2205af8bb7]
+
+ * pp:
+ sync with upstream
+ [a4b7336b3256]
+
+ * src/sudo.h:
+ repair spacing
+ [f5c1255ce514]
+
+2012-11-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/sudo_debug.c:
+ Set group on sudo_debug when creating it to gid 0 so systems without
+ BSD group semantics don't get the invoking user's group.
+ [7dda01196554]
+
+ * plugins/sudoers/iolog.c:
+ Rename mkdir_parents() io_mkdirs() and add a flag to specify whether
+ path is a temporary, in which case the final component is created
+ via mkdtemp() instead of mkdir().
+ [79c0c4e7ed58]
+
+ * plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.h:
+ For PERM_ROOT set egid to 0 so log files are not created with the
+ gid of the user.
+ [5b964ea43474]
+
+ * plugins/sudoers/logging.c:
+ Add calls to set_perms(PERM_ROOT) becore logging to a file. We
+ should already be root but since we cache the current permission
+ status it is basically free. That way, if more of sudoers runs as
+ non-root in the future logging will still work correctly.
+ [c591d4973f41]
+
+ * common/sudo_conf.c, config.h.in, configure, configure.in,
+ include/gettext.h, plugins/sudoers/locale.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c,
+ src/error.c, src/exec.c, src/sesh.c, src/sudo.c:
+ #unifdef HAVE_SETLOCALE, it is C89 so no need to check for it.
+ [41f6bb4926f4]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in:
+ Mention that sudo.conf is parsed in the C locale.
+ [f711c416e30c]
+
+ * common/sudo_conf.c:
+ Parse sudo.conf in the "C" locale.
+ [776658f651ea]
+
+ * plugins/sudoers/locale.c, plugins/sudoers/logging.h,
+ plugins/sudoers/sudoers.h:
+ Fix compilation on systems w/o setlocale()
+ [6940d1c1c1ce]
+
+ * doc/TROUBLESHOOTING:
+ Sudo now includes a workaround for the Solaris 11 locale issue.
+ [ab93787a552c]
+
+2012-11-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/gettext.h, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/locale.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c,
+ src/error.c, src/exec.c, src/sesh.c, src/sudo.c, src/sudo.h:
+ Always include locale.h from gettext.h so we no longer need to
+ include locale.h from the .c files.
+ [93d39182ccfa]
+
+ * MANIFEST, config.h.in, configure, configure.in, mkdep.pl,
+ plugins/sudoers/Makefile.in, src/Makefile.in, src/openbsd.c,
+ src/solaris.c, src/sudo.c, src/sudo.h:
+ Add os-specific initialization functions for solaris (workaround
+ setuid locale problem in Solaris 11) and openbsd (set malloc_options
+ if SUDO_DEVEL). Also move set_project() to solaris.c.
+ [1d6581afbaf4]
+
+2012-11-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/find_path.c, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/policy.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/timestamp.c:
+ Avoid strerror() when possible and just rely on warning/error to
+ handle errno in the proper locale.
+ [bf612caae97c]
+
+ * plugins/sudoers/logging.c:
+ Set sudoers locale in log_allowed()
+ [2dd0ac704cae]
+
+ * plugins/sudoers/check.c:
+ Make the sudo lecture translatable.
+ [3cdfc183d72d]
+
+ * Makefile.in:
+ Add the values of badpass_message, passprompt and mailsub to
+ sudoers.pot so they can be translated.
+ [51cbe8adcb94]
+
+ * plugins/sudoers/logging.c:
+ Expand the FMT_FIRST anf FMT_CONTD macros inline so they get picked
+ up by xgettext.
+ [c5b74115caf0]
+
+2012-11-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c, plugins/sudoers/prompt.c,
+ plugins/sudoers/sudoers.h:
+ Make expand_prompt() args const and free the prompt when we are done
+ with it.
+ [995ef8519fe6]
+
+ * plugins/sudoers/policy.c:
+ Fix cut and pasto
+ [e002921c1d15]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/logging.c:
+ Expand def_mailsub in the sudoers locale, not the user's.
+ [a4775f2fb385]
+
+ * plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/check.c,
+ plugins/sudoers/env.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/locale.c, plugins/sudoers/logging.c,
+ plugins/sudoers/logging.h, plugins/sudoers/parse.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/timestamp.c:
+ Call gettext inside log_error et al instead of having the caller do
+ it. This way we can display any messages to the user in their own
+ locale but log in the sudoers local.
+ [286e0444f785]
+
+ * common/sudo_conf.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/rfc1938.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/linux_audit.c,
+ plugins/sudoers/logging.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/policy.c, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/visudo.c, src/error.c, src/exec.c,
+ src/exec_common.c, src/exec_pty.c, src/load_plugins.c,
+ src/net_ifs.c, src/parse_args.c, src/selinux.c, src/sesh.c,
+ src/sudo.c, src/sudo_edit.c, src/tgetpass.c:
+ Display warning/error messages in the user's locale.
+ [00a04165c0cf]
+
+ * plugins/sudoers/audit.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/logging.c, plugins/sudoers/sudoers.c:
+ audit_failure() now calls gettext itself using the sudoers locale.
+ [d77f1d78799a]
+
+ * plugins/sudoers/iolog_path.c, plugins/sudoers/logging.c,
+ plugins/sudoers/sudoers.c:
+ Convert setlocale() to sudoers_setlocale() in the sudoers module.
+ This only converts existing uses, there are more places where we
+ need to sprinkle sudoers_setlocale() calls.
+ [8ee0cbf0d0a9]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/env.c,
+ plugins/sudoers/locale.c, plugins/sudoers/logging.h,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Add simple locale switching to make it easy to switch from the
+ user's locale to the sudoers locale without making excessive
+ setlocale() calls when we don't need to.
+ [5c61582fdeee]
+
+ * common/sudo_debug.c, include/error.h, include/sudo_debug.h,
+ plugins/sudoers/plugin_error.c, src/error.c:
+ Add variants of warn/error and sudo_debug_printf that take a va_list
+ instead of a variable number of args.
+ [00392bdc063c]
+
+ * INSTALL, doc/TROUBLESHOOTING:
+ Document Solaris 11 locale issues and workarounds.
+ [05f7d34af3ae]
+
+ * Makefile.in, configure, configure.in:
+ Solaris gettext() looks in lang.UTF-8, not just lang for UTF-8
+ locales. Make links from localdir/lang -> localdir/lang.UTF-8
+ [5ca9326480e2]
+
+2012-11-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/audit.c, plugins/sudoers/logging.c,
+ plugins/sudoers/logging.h, plugins/sudoers/sudoers.c:
+ Do not inform the user that the command was not permitted by the
+ policy if they do not successfully authenticate. This is a
+ regression introduced in sudo 1.8.6.
+ [c1279df08bfb]
+
+ * plugins/sudoers/Makefile.in:
+ Add preinstall target that runs SUDO_PREINSTALL_CMD. Used to fixup
+ the rpath in HP-UX SOM shared libraries for the LDAP libs.
+ [b07185657b42]
+
+ * src/parse_args.c:
+ The -a option should be #ifdef HAVE_BSD_AUTH_H, not -A.
+ [22c73cbe3ff9]
+
+2012-10-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, configure, configure.in:
+ Allow the user to specify and alternate libtool
+ [c9d6fc9521fd]
+
+2012-10-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS, plugins/sudoers/sudo_nss.c:
+ Allow sudo to be build with sss support without also including ldap
+ support. From Stephane Graber.
+ [b992a80ebea1]
+
+2012-10-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/logging.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/policy.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c:
+ Refactor policy plugin interface code from sudoers.c into policy.c
+ [393e62910b8a]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/sudoers.c:
+ Refactor command_info setting into its own function.
+ [a952b948324c]
+
+ * plugins/sudoers/interfaces.c, plugins/sudoers/interfaces.h,
+ plugins/sudoers/match_addr.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ Make interfaces pointer private to interfaces.c and add
+ get_interfaces() accessor.
+ [b69b9334ed3c]
+
+2012-10-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog_path.c, plugins/sudoers/logging.c,
+ plugins/sudoers/sudoers.h:
+ Make user_cwd const since it is either a string literal or passed in
+ from the front-end.
+ [90751b81e8bc]
+
+ * configure, configure.in:
+ sudo 1.8.7
+ [bf727adb8af0]
+
+ * plugins/sudoers/sudoers.c:
+ Avoid nested strtok() calls.
+ [9d9f22ab52a9]
+
+2012-10-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/check.c,
+ plugins/sudoers/prompt.c, plugins/sudoers/sudoers.h:
+ Move expand_prompt() into its own source file for easier unit
+ testing.
+ [b419b48a436f]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/check.c,
+ plugins/sudoers/check.h, plugins/sudoers/sudoers.h,
+ plugins/sudoers/timestamp.c, plugins/sudoers/timestamp.h:
+ Make check.c independent of the underlying timestamp implementation.
+ [895071bd6065]
+
+ * plugins/sudoers/iolog_path.c:
+ Add SUDOERS_NO_SEQ define to allow ${seq} to be disabled.
+ [8ac38f02dd6d]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Use a list for the possible values of Tag_Spec with a minimal indent
+ to improve readability. In the pod version, these were =head3. Also
+ use .St -p1003.1 instead of just POSIX when talking about glob() and
+ fnmatch().
+ [361a6f7a5c44]
+
+2012-10-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/ttyname.c:
+ sudo_ttyname_dev() is unused if there is no /proc or sysctl().
+ [6598dbf81e16]
+
+ * compat/mksiglist.c, compat/mksigname.c,
+ compat/regress/fnmatch/fnm_test.c, compat/regress/glob/globtest.c,
+ plugins/sample_group/plugin_test.c,
+ plugins/sudoers/regress/check_symbols/check_symbols.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c, src/sesh.c, src/sudo.c:
+ Explicitly mark main() as public in executables to avoid an HP-UX ld
+ warning.
+ [72a40ce218be]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in:
+ Remove grep from SEE ALSO section.
+ [c7cafee1621f]
+
+ * common/alloc.c:
+ If vasprintf() fails, just use the errno it sets instead of assuming
+ ENOMEM.
+ [1be5bfdc0cab]
+
+2012-09-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/TROUBLESHOOTING:
+ Mention HP-UX pam.conf settings.
+ [8b8e745b49fd]
+
+2012-09-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/check.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/timestamp.c,
+ plugins/sudoers/timestamp.h:
+ Split off timestamp functions into their own source file.
+ [d5833332511d]
+
+2012-09-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Mention how !foo is not the same as ALL,!foo
+ [51f8e470757d]
+
+2012-09-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Start commands in the background when I/O logging is enabled. We
+ can't do this on Mac OS X due to a kernel bug in tc[gs]etattr(2)
+ which returns EINTR on signal instead of restarting automatically.
+ [83b1d59146f7]
+
+ * src/exec_pty.c:
+ Handle SIGCONT_FG and SIGCONT_BG when converting signal number to
+ string in deliver_signal().
+ [2cefea7a976e]
+
+2012-09-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Fix running commands that need the terminal in the background when
+ I/O logging is enabled. E.g. "sudo vi &". When the command is
+ foregrounded, it will now resume properly.
+ [0bc13a253429]
+
+ * plugins/sudoers/match.c:
+ Add rudimentary support for name-based matching as a compile-time
+ option. This unsafe when used in conjunction with the '!' operator.
+ [f93bc8e6db15]
+
+2012-09-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/pwutil.c,
+ plugins/sudoers/pwutil.h, plugins/sudoers/pwutil_impl.c:
+ Split out implementation-specific back end code out of pwutil.c into
+ pwutil_impl.c. This will allow the main pwutil code to be used for
+ lookup methods other than getpw* and getgr*.
+ [999c2dde60e4]
+
+2012-09-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.in:
+ sudo 1.8.6p3
+ [97fef3d9ed65]
+
+2012-09-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/fixman.sh:
+ Don't use embedded newline when matching, use \n. This got expanded
+ at some point. Bug #573
+ [6652f834b8f5]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y:
+ Rename yyerror() to sudoerserror() to match yacc prefix changes. Not
+ really needed due to the #defines that yacc makes but it is less
+ confusing this way as the lexer calls sudoerserror().
+ [a0577be6527d]
+
+ * common/alloc.c, plugins/sample_group/plugin_test.c,
+ plugins/sudoers/env.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c,
+ src/exec_common.c, src/parse_args.c, src/sudo.c:
+ No need to translate "unable to allocate memory" when we can just
+ use the system translation via strerror().
+ [377499e5827c]
+
+ * plugins/sudoers/sudoreplay.c:
+ Fall back on lstat(2) if d_type in struct dirent is DT_UNKNOWN. Not
+ all file systems support d_type. Bug #572
+ [8b861c62945f]
+
+ * plugins/sudoers/sudoreplay.c:
+ Avoid calling fclose(NULL) in the error path when we cannot open an
+ I/O log file.
+ [9401d5c4bb05]
+
+2012-09-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.in:
+ Sudo 1.8.6p2
+ [6e32496280f2]
+
+ * src/exec.c:
+ When setting the signal handler for SIGTSTP to the default value in
+ non-I/O log mode, store the old handler value for when we restore it
+ after resume.
+ [242628694e42]
+
+ * plugins/sudoers/env.c:
+ Replace the guts of sudo_setenv_nodebug() with our old setenv.c
+ which supports non-standard BSD and glibc semantics. sudo_setenv()
+ now simply calls sudo_setenv2().
+ [57ffb6c9efaa]
+
+2012-09-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.mdoc.in, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document non-Unix group support in LDAP sudoers.
+ [33c89f3aeee6]
+
+ * plugins/sudoers/ldap.c:
+ Enable non-Unix group support for LDAP sudoers. We now check for
+ non-Unix groups and netgroups with the same query in the second
+ pass. Bug #571
+ [eb98fdff54d9]
+
+2012-09-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.h, plugins/sudoers/parse.c,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.h,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c,
+ plugins/sudoers/visudo.c:
+ Set yacc prefix to "sudoers" to avoid conflicts other yacc parsers.
+ [cb6c0d93215e]
+
+2012-09-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Mention support for SUCCESS=return in /etc/nsswitch.conf
+ [ef1f35aa0863]
+
+ * NEWS, configure, configure.in:
+ sudo 1.8.6p1
+ [73a5e1f004b3]
+
+2012-09-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/env.c:
+ Avoid setting LOGNAME, USER and USERNAME variables twice when
+ set_logname is enabled.
+ [0de4f5fbd1d4]
+
+ * plugins/sudoers/env.c:
+ Fix duplicate detection in sudo_putenv(), do not prune out the
+ variable we just set when overwriting an existing instance. Fixes
+ bug #570
+ [854ee714c831]
+
+ * plugins/sudoers/env.c:
+ Add some debuggging
+ [a25cd3305823]
+
+2012-09-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudo_nss.c:
+ Disable word wrap in list mode when stdout is a pipe to make "sudo
+ -l | grep ..." more useful. Adapted from a diff by Daniel Kopecek.
+ [65ade04511fd]
+
+ * common/lbuf.c:
+ Print a trailing newline in lbuf_print() when there is not enough
+ space to do word wrapping and the lbuf does not end with a newline.
+ [c0200e19cd09]
+
+ * plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoers.c:
+ Add support for [SUCCESS=return] in nsswitch.conf; from Daniel
+ Kopecek
+ [5c480316e3ce]
+
+ * MANIFEST:
+ Add sssd.c
+ [9cadd014ef97]
+
+2012-09-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/fi.mo,
+ plugins/sudoers/po/hr.mo, plugins/sudoers/po/sl.mo,
+ plugins/sudoers/po/uk.mo, src/po/fi.mo, src/po/hr.mo, src/po/it.mo,
+ src/po/ru.mo, src/po/sl.mo, src/po/uk.mo, src/po/vi.mo:
+ regen .po files
+ [62423d4d143d]
+
+ * MANIFEST, plugins/sudoers/po/vi.mo:
+ Add Vietnamese sudoers translation from translationproject.org
+ [33666a605525]
+
+ * NEWS:
+ mention PIE
+ [05032e5304c6]
+
+ * MANIFEST, plugins/sudoers/po/vi.po:
+ Add Vietnamese sudoers translation from translationproject.org
+ [015c2204bae2]
+
+2012-08-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, compat/Makefile.in, mkdep.pl:
+ Add missing signame dependency
+ [e493bfb01929]
+
+ * src/exec.c, src/ttyname.c:
+ Silence compiler warnings.
+ [1c5374b66d9b]
+
+ * MANIFEST, compat/Makefile.in, compat/sig2str.c, compat/strsigname.c,
+ config.h.in, configure, configure.in, include/missing.h, mkdep.pl,
+ src/exec.c, src/exec_pty.c:
+ Replace strsigname() with sig2str(), emulating it as needed.
+ [1e348cca1fa6]
+
+ * config.h.in, configure, configure.in, src/utmp.c:
+ Use fseeko() for legacy utmp handling if available.
+ [b4bbd8d2c0e9]
+
+2012-08-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/strsigname.c, config.h.in, configure, configure.in:
+ Detect sys_sigabbrev[] and use it in place of sys_signame[] if
+ present. For some reason glibc does not declare sys_sigabbrev so we
+ must add an extern definition of our own.
+ [b38f3fbd7078]
+
+ * compat/strsignal.c, compat/strsigname.c:
+ Handle NULL entries in sys_siglist and sys_signame.
+ [a388959d9654]
+
+ * compat/mksiglist.c, compat/mksiglist.h, compat/mksigname.c,
+ compat/mksigname.h, compat/strsignal.c, compat/strsigname.c:
+ Convert my_sys_sig{list,name} -> sudo_sys_sig{list,name}
+ [711e41aba59a]
+
+2012-08-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ sync
+ [5a2522488754]
+
+ * src/exec.c:
+ Pass on SIGTSTP to the command if it was sent by a user process (not
+ the kernel or the terminal) when we are not I/O logging and set the
+ default SIGTSTP handler when we re-send the signal to ourself,
+ restoring our handler after we resume.
+ [4259c47e31c0]
+
+ * src/exec.c:
+ Shells typically change their process group when they start up so
+ that they can implement job control. Most well-behaved shells change
+ the pgrp back to its original value before suspending so we must not
+ try to restore in that case, lest we race with the child upon
+ resume, potentially stopping sudo with SIGTTOU while the command
+ continues to run. Some shells, such as pdksh, just suspend the shell
+ by sending SIGSTOP to themselves without restoring the pgrp. In this
+ case we need to change the pgrp back for them. Should fix bug #568
+ [6ac6751ffd17]
+
+2012-08-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, compat/Makefile.in, compat/mksigname.c,
+ compat/mksigname.h, compat/strsignal.c, compat/strsigname.c,
+ config.h.in, configure, configure.in, include/missing.h, mkdep.pl,
+ src/exec.c, src/exec_pty.c:
+ Use strsigname() to print signal names in the debug output. If the
+ system has no strsigname(), use our own.
+ [0735f18906b9]
+
+2012-08-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/testsudoers/test5.inc,
+ plugins/sudoers/regress/testsudoers/test5.sh:
+ Remove generated file and change path for temporary include file.
+ [4e9fa830c6b5]
+
+ * plugins/sudoers/Makefile.in:
+ When running regress tests, list pass/fail rate for each dir
+ (testsudoers and visudo) instead of the total. Also prevent the
+ result files from clobbering each other by keeping them in the
+ relevant directories.
+ [6aac53baff7d]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Don't print an error message in yyerror() if open_sudoers() fails,
+ we've already printed an error message. Also restore the check for
+ sudoers_warnings in yyerror().
+ [aa6036df5fb2]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.h,
+ plugins/sudoers/toke.l:
+ Avoid printing the >>> parse error <<< message for testsudoers when
+ the -t flag is specified.
+ [76f3433c8992]
+
+2012-08-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/parse.c:
+ Fix NULL deref when an entry has no Runas_Entry
+ [4b14983ff6e7]
+
+ * plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po,
+ src/po/ja.mo, src/po/ja.po, src/po/pl.mo, src/po/pl.po,
+ src/po/zh_CN.mo, src/po/zh_CN.po:
+ sync with translationproject.org
+ [440e9c9b37de]
+
+ * NEWS:
+ sync
+ [3142ba2dce60]
+
+ * plugins/sudoers/check.c:
+ Correct the check_user() comment header.
+ [73da30308fff]
+
+ * plugins/sudoers/auth/sudo_auth.c:
+ Change a log_fatal() into log_error() when no auth methods are
+ configured. The caller already checks the return value.
+ [05f5c39793a7]
+
+ * plugins/sudoers/logging.c:
+ Add missing debug_return
+ [3a76bb7c2fe7]
+
+2012-08-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.ldap.mdoc.in,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Make the capitalization consistent for .Ss and .Sx
+ [5c5735ee4b2f]
+
+ * doc/Makefile.in, doc/fixman.sh, doc/fixmdoc.sh, doc/sudo.cat,
+ doc/sudo.man.in, doc/sudo.mdoc.in:
+ Add COMMAND EXECUTION section that describes how sudo runs the
+ command, the extra sudo processes and signal handling.
+ [dff2d88e984e]
+
+2012-08-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Happy Easter
+ [4b9d697c6b83]
+
+2012-08-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/Makefile.in:
+ Don't echo the awk command when building siglist.in
+ [21daa72921e6]
+
+ * doc/fixman.sh, doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Cosmetic changes.
+ [19259528e9ad]
+
+ * doc/Makefile.in:
+ The HISTORY, LICENSE and CONTRIBUTORS files are not longer
+ generated.
+ [ea6ac9e981e6]
+
+ * MANIFEST, plugins/sudoers/po/da.po, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/hr.po, plugins/sudoers/po/it.mo,
+ plugins/sudoers/po/it.po, plugins/sudoers/po/sl.po,
+ plugins/sudoers/po/uk.po, src/po/de.mo, src/po/de.po, src/po/fi.po,
+ src/po/hr.po, src/po/it.po, src/po/ru.po, src/po/sl.po,
+ src/po/uk.po, src/po/vi.po:
+ Sync with translationproject.org and add Italian sudoers
+ translation.
+ [9276740aea59]
+
+2012-08-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Expand description of fqdn to talk about systems where the hosts
+ file is searched before DNS.
+ [4ee812ca6116]
+
+2012-08-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/Makefile.in:
+ For cat pages there is nothing to make unless DEVEL is set.
+ [fab4a5b68708]
+
+ * configure, configure.in, doc/Makefile.in:
+ Always use mandoc to format cat pages and remove now-extraneous
+ nroff configure tests.
+ [5747f4ed5762]
+
+ * pp:
+ sync polypkg from git
+ [89ddf6ea3e3f]
+
+ * plugins/sudoers/sudoers.c:
+ Use AI_FQDN instead of AI_CANONNAME if available since "canonical"
+ is not always the same as "fully qualified".
+ [7c1d9c098386]
+
+2012-08-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.mdoc.in:
+ Fix some typos. Describe error messages not related to policy
+ permissions.
+ [f5ebf9030d85]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/visudo.c:
+ Add new check_defaults() function to check (but not update) the
+ Defaults entries. Visudo can now use this instead of update_defaults
+ to check all the defaults regardless instead of just the global
+ Defaults entries.
+ [3fa879ce1b65]
+
+2012-08-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Document sudoers log format.
+ [08998a7061ab]
+
+ * NEWS:
+ Update for sudo 1.8.5p3
+ [6e102a5d4e8d]
+
+ * src/load_plugins.c:
+ Add missing check for I/O plugin API version when checking for the
+ presence of I/O plugin hooks.
+ [ef05c7eeaf81]
+
+ * src/hooks.c:
+ Can't call debug code in the process_hooks_xxx functions() since
+ ctime() may look up the timezone via the TZ environment variable.
+ [2179fb26bd8e]
+
+2012-08-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_common.c, src/sesh.c, src/utmp.c:
+ Include signal.h before sudo_exec.h since it uses sigset_t * in the
+ fork_pty prototype.
+ [94fc0d859600]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in, doc/visudo.cat,
+ doc/visudo.man.in, doc/visudo.mdoc.in:
+ Remove OPTIONS section; options now go inside DESCRIPTION
+ [a619fc58a746]
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ regen
+ [44719d80bc06]
+
+ * MANIFEST, NEWS, plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/hr.mo, plugins/sudoers/po/hr.po,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/sl.mo, plugins/sudoers/po/sl.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po,
+ src/po/da.mo, src/po/da.po, src/po/hr.mo, src/po/hr.po,
+ src/po/sl.mo, src/po/sl.po, src/po/vi.mo, src/po/vi.po:
+ Sync with translationproject.org and add new Slovenian translation.
+ [34b4b966bbac]
+
+ * common/alloc.c, plugins/sudoers/check.c, plugins/sudoers/env.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/testsudoers.c:
+ Reduce the number of "internal error, foo overflow" messages that
+ need to be translated.
+ [93ffa2b3d53f]
+
+ * NEWS:
+ Mention HP-UX reboot fix.
+ [1e39b5aa32ac]
+
+ * INSTALL, NEWS, common/sudo_debug.c, configure, configure.in,
+ doc/CONTRIBUTORS, include/sudo_debug.h, mkdep.pl, pathnames.h.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/sssd.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoers.c:
+ Support for using SSSD (http://fedorahosted.org/sssd/) as a sudoers
+ data source. From Daniel Kopecek and Pavel Brezina.
+ [3f85e95d6928]
+
+2012-08-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/sudo_conf.c, src/load_plugins.c:
+ If sudo.conf contains an I/O plugin but no policy plugin, use
+ sudoers for the policy plugin. If a policy plugin is specified
+ without an I/O plugin, only the policy plugin will be loaded.
+ [ea192df2439d]
+
+ * doc/Makefile.in, doc/sudoers.man.in:
+ Do not modify the .Os section when building the .man.in file from
+ .mdoc.in.
+ [a9f9628e147f]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Add a note about wildcards matching multiple words and include an
+ example. Also mention that for sudoedit, a wildcard in command line
+ args does not match a slash.
+ [fcb9fbac14e0]
+
+2012-08-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c, src/sudo_exec.h:
+ Fix a comment, update a variable name in a prototype; all cosmetic.
+ [e89f10cbd6e1]
+
+ * plugins/sudoers/iolog.c:
+ Cast 2nd argument of lseek() to off_t if it is a constant for
+ systems with 64-bit off_t but without a proper lseek() prototype.
+ [d8779da135d0]
+
+ * compat/getline.c, plugins/sudoers/check.c, plugins/sudoers/env.c,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/visudo.c:
+ Fix some warnings from clang checker-267
+ [1e44ef7860b5]
+
+ * plugins/sample/sample_plugin.c:
+ Fix memory leak found by clang checker-267
+ [f8a43617fdfb]
+
+2012-08-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c, src/exec_pty.c, src/sudo.h, src/sudo_exec.h:
+ If we receive a signal from the command we executed, do not forward
+ it back to the command. This fixes a problem with BSD-derived
+ versions of the reboot command which send SIGTERM to all other
+ processes, including the sudo process. Sudo would then deliver
+ SIGTERM to reboot which would die before calling the reboot() system
+ call, effectively leaving the system in single user mode.
+ [4ffab9ab9e98]
+
+2012-08-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/fixman.sh, doc/fixmdoc.sh:
+ Remove section about Solaris 10 on other systems. Add missing
+ sudoers.man.in bit to fixman.sh.
+ [176559199ba7]
+
+2012-08-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in:
+ Expand section on Solaris privileges.
+ [3a1bfa2f1743]
+
+ * NEWS:
+ Expand a bit on the Solaris priv set changes.
+ [bffb78b4a520]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/parse.c, plugins/sudoers/parse.h,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ The second argument to init_parser() is now bool.
+ [fb727a4fb651]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y:
+ Fix printing of parse error message to stderr.
+ [dea6b420b84f]
+
+ * plugins/sudoers/check.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/match.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/testsudoers.c:
+ If a command matches using an empty Runas_List (i.e. Runas_List is
+ present but empty) and the -u option was not specified, set runas_pw
+ to user_pw instead of using runas_default. This is intended to be
+ used in conjunction with the Solaris Privilege Set support for rules
+ that grant privileges without changing the user.
+ [e84a081f3c11]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.mdoc.in,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.h,
+ plugins/sudoers/gram.y, plugins/sudoers/match.c,
+ plugins/sudoers/parse.c, plugins/sudoers/sudoers_version.h:
+ Add support for parsing an empty Runas_List, which only allows the
+ command to be run as the invoking user. This can be used in
+ conjunction with the Solaris Privilege Set support to grant
+ privileges without changing the user.
+ [dc34373792fc]
+
+2012-08-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/fixman.sh:
+ Fix HP-UX, just use ".TH name section" like the vendor manuals.
+ [559738237c92]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Fix compilation on Solaris
+ [2d310302207c]
+
+ * .hgignore, MANIFEST, doc/Makefile.in, doc/fixman.sh, doc/fixmdoc.sh,
+ doc/sudo.man.sh, doc/sudo.mdoc.sh, doc/sudoers.man.sh,
+ doc/sudoers.mdoc.sh:
+ Generate a sed script file when munging *.mdoc or *.man instead of
+ passing sed expressions on the command line. Older seds do not
+ support \n in a replacement so generate and run a sed script
+ instead.
+ [0bcce3f1ca18]
+
+ * doc/Makefile.in, doc/sudo.man.in, doc/sudo_plugin.man.in,
+ doc/sudoers.ldap.man.in, doc/sudoers.man.in, doc/sudoreplay.man.in,
+ doc/visudo.man.in:
+ Use "Sudo VERSION" as the 4th arg to .TH instead of just "VERSION"
+ [fe0f10b63776]
+
+2012-07-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ When checking whether a signal is user-generated, compare si_code
+ against SI_USER instead of <= 0 since on HP-UX, terminal-related
+ signals get a code of 0.
+ [4e9021243343]
+
+ * src/sudo.c:
+ SuSE Enterprise Linux uses RLIMIT_NPROC and _SC_CHILD_MAX
+ interchangably. This causes problems when setting RLIMIT_NPROC to
+ RLIM_INFINITY due to a bug in bash where bash tries to honor the
+ value of _SC_CHILD_MAX but treats a value of -1 as an error, and
+ uses a default value of 32 instead.
+
+ Previously, we just checked RLIMIT_NPROC and, if it was unlimited,
+ restored the previous value of RLIMIT_NPROC. However, that makes it
+ impossible to set nproc to unlimited. We now only restore the nproc
+ resource limit if sysconf(_SC_CHILD_MAX) is negative. In most cases,
+ pam_limits will set RLIMIT_NPROC for us.
+ [cb71cc8d0b08]
+
+2012-07-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Active Directory apparently requires that tenths of a second be
+ present in a date so append .0 to the "now" value in the time
+ filter. Also remove space for the global AND from TIMEFILTER_LENGTH
+ since it was not being used consistently. Buffers of
+ TIMEFILTER_LENGTH now need to account for the terminating NUL byte.
+ [d28619ff6e45]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Fix SELinux build
+ [cc0d1f4e851b]
+
+2012-07-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST:
+ Remove pod versinons of HISTORY, CONTRIBUTORS and LICENSE as they
+ were not being kept in sync.
+ [fc3ad1847cb1]
+
+ * doc/HISTORY, doc/Makefile.in, doc/contributors.pod, doc/history.pod,
+ doc/license.pod:
+ Remove pod versinons of HISTORY, CONTRIBUTORS and LICENSE as they
+ were not being kept in sync.
+ [950363dffe3a]
+
+2012-07-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/logging.c:
+ Fix printing of the permission denied message to standard error when
+ a user is not allowed to run a command. This got broken by the
+ recent logging changes.
+ [b7af63da3ca1]
+
+ * plugins/sudoers/sudoers_version.h:
+ Bump grammar version for Solaris privs.
+ [2a2baf024477]
+
+ * doc/schema.ActiveDirectory:
+ Fix errors introduced when sudoNotBefore, sudoNotAfter and sudoOrder
+ were added. From David Hicks.
+ [3fc432a8edb4]
+
+2012-07-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ Remove lex.yy.c when building toke.c
+ [72bb9e62b289]
+
+ * doc/Makefile.in:
+ Fix building docs in a build dir.
+ [7a6f435af022]
+
+ * doc/sudo.man.pl, doc/sudo.pod, doc/sudo_plugin.pod,
+ doc/sudoers.ldap.pod, doc/sudoers.man.pl, doc/sudoers.pod,
+ doc/sudoreplay.pod, doc/visudo.pod:
+ Remove pod versions of the manual; we now use mdoc.
+ [5c967d2dd5db]
+
+ * MANIFEST, doc/Makefile.in, doc/sudo.man.sh, doc/sudo.mdoc.sh,
+ doc/sudoers.man.sh, doc/sudoers.mdoc.sh:
+ Add post-processing scripts to strip out login class, BSD auth,
+ SELinux and privilege set bits when they are not supported.
+ [d0d51f72f597]
+
+ * NEWS, configure.in, doc/CONTRIBUTORS, doc/Makefile.in,
+ doc/contributors.pod, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.man.pl, doc/sudoers.mdoc.in, doc/sudoers.pod,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.h, plugins/sudoers/gram.y,
+ plugins/sudoers/parse.c, plugins/sudoers/parse.h,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, src/sudo.c, src/sudo.h:
+ Merge in Solaris privilege support by Darren Moffat and John
+ Zolnowsky
+ [3aa0a64f2f5c]
+
+2012-07-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/contributors.pod:
+ Sync with CONTRIBUTORS file
+ [9a0852306ad9]
+
+ * doc/sudo.man.in, doc/sudo_plugin.man.in, doc/sudoers.ldap.man.in,
+ doc/sudoers.man.in, doc/sudoreplay.man.in:
+ Regen .man.in files with my private mandoc.
+ [dc3c9fc449eb]
+
+ * doc/Makefile.in:
+ add MANDOC variable
+ [35527e66afc5]
+
+2012-07-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.man.in, doc/sudo_plugin.man.in, doc/sudoers.ldap.man.in,
+ doc/sudoers.man.in, doc/sudoreplay.man.in, doc/visudo.man.in:
+ Regen .man.in files with hacked mandoc to avoid issues with historic
+ nroff.
+ [d45cfa7d665f]
+
+2012-07-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.mdoc.in, doc/sudoers.mdoc.in:
+ Fix groff warnings.
+ [111d522ca807]
+
+ * doc/Makefile.in:
+ Fix dependencies for .man.in files.
+ [aefeffe1af2b]
+
+ * .hgignore:
+ Add doc/*.mdoc to ignore file
+ [1e4de6ef2ad8]
+
+ * INSTALL, MANIFEST, NEWS, configure, configure.in, doc/Makefile.in,
+ doc/sudo.cat, doc/sudo.man.in, doc/sudo.mdoc.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.mdoc.in, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.ldap.mdoc.in,
+ doc/sudoers.man.in, doc/sudoers.mdoc.in, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/sudoreplay.mdoc.in, doc/visudo.cat,
+ doc/visudo.man.in, doc/visudo.mdoc.in:
+ Build .man.in and .cat files from .mdoc.in files. Add new --with-man
+ and --with-mdoc configure options.
+ [c963fd7e8f80]
+
+2012-07-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.mdoc.in, doc/sudo_plugin.mdoc.in, doc/sudoers.ldap.mdoc.in,
+ doc/sudoers.mdoc.in, doc/sudoreplay.mdoc.in, doc/visudo.mdoc.in:
+ Sudo manuals formatted in mdoc, to replace the pod versions.
+ [e6dca4030451]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod,
+ doc/sudoers.cat, doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.pod, doc/sudoers.man.in, doc/sudoers.pod,
+ doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.pod,
+ doc/visudo.cat, doc/visudo.man.in, doc/visudo.pod:
+ More minor costmetic fixes.
+ [a7287a68385a]
+
+2012-07-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.pod:
+ Minor cosmetic fixes.
+ [9c48bdaf3946]
+
+2012-07-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/logging.c, plugins/sudoers/po/sudoers.pot:
+ Use "a password is required" instead of "password required" when the
+ -n flag is used and we need to read a password.
+ [a3c30fc41648]
+
+2012-07-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Mention logging changes.
+ [8238fd6e02e8]
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [e2cf634ba63b]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod:
+ Document that other mail_* flags have precedence over mail_badpass.
+ [9f4cc9188f40]
+
+ * plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/check.c,
+ plugins/sudoers/logging.c, plugins/sudoers/logging.h,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Move log_denial() calls and logic to log_failure(). Move
+ authentication failure logging to log_auth_failure(). Both of these
+ call audit_failure() for us.
+
+ This subtly changes logging for commands that are denied by sudoers
+ but where the user failed to enter the correct password. Previously,
+ these would be logged as "N incorrect password attempts" but now are
+ logged as "command not allowed". Fixes bug #563
+ [cad35f0b3ad7]
+
+2012-07-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/aix.c:
+ Do not set a resource limit to zero when we are unable to fetch a
+ value from /etc/security/limits.
+ [62bfb0a7895e]
+
+2012-07-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Add "Provides: sudo" to debian sudo-ldap package
+ [beb8afa0beb2]
+
+2012-07-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in, zlib/Makefile.in:
+ Define NO_VIZ for zlib when gcc doesn't support symbol visibility
+ attributes.
+ [9fdcbf526386]
+
+ * configure, configure.in:
+ Use the autoconf cache when checking for symbol export control
+ support.
+ [03c2cce8711f]
+
+ * INSTALL, common/Makefile.in, compat/Makefile.in, configure,
+ configure.in, mkpkg, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in, src/Makefile.in:
+ Add configure check for building PIE executables instead of doing it
+ in mkpkg.
+ [02b5b78ef258]
+
+ * sudo.pp:
+ MacOS pp backend doesn't like modes longer than 4 characters.
+ [01b49022bf01]
+
+2012-07-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Add -Wc,-fstack-protector to LT_LDFLAGS instead of adding
+ -fstack-protector to LDFLAGS so it doesn't get stripped out. Libtool
+ will strip -fstack-protector from the linker flags and we always
+ link with libtool.
+ [0a0a0250ac2b]
+
+2012-06-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo_plugin.cat,
+ doc/sudo_plugin.man.in, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.man.in, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/visudo.cat, doc/visudo.man.in:
+ Regen for sudo 1.8.6
+ [1657ee28b496]
+
+ * NEWS, doc/sudoers.ldap.pod:
+ Document improved Tivoli Directory Server support.
+ [fb411edf4687]
+
+ * config.h.in, configure, configure.in, plugins/sudoers/ldap.c:
+ Add support for ldaps using Tivoli LDAP libraries. Add ldap.conf
+ option to specify Tivoli key db password. Allow TLS ciphers to be
+ configured for Tivoli.
+ [737e17c91e60]
+
+2012-06-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Tivoli Directory Server 6.3 libs always return a (bogus) error when
+ setting LDAP_OPT_CONNECT_TIMEOUT.
+ [504406637c38]
+
+ * NEWS:
+ Update
+ [687a755604e8]
+
+ * plugins/sudoers/ldap.c:
+ Treat LDAP_OPT_CONNECT_TIMEOUT (Tivoli Directory Server 6.3) the
+ same as LDAP_OPT_CONNECT_TIMEOUT (OpenSSH). Don't make failure to a
+ set an ldap option fatal.
+ [17cf93ae3304]
+
+2012-06-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Zero pointers in sudo_user struct after freeing, just in case.
+ [8eff1f80b943]
+
+ * plugins/sudoers/sudoers.c:
+ Free user_gids in close function if it has not already been freed.
+ [cbce28877f37]
+
+ * plugins/sudoers/pwutil.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Defer group ID to name resolution until we actually need it.
+ [463e75b81e89]
+
+ * src/sudo.c:
+ It is safe to read in sudo.conf before calling user_info().
+ [3290b6434e3c]
+
+ * plugins/sudoers/env.c, plugins/sudoers/ldap.c:
+ Use MAX_UID_T_LEN + 1 for uid/gid buffers, not MAX_UID_T_LEN to
+ prevent potential truncation. Bug #562.
+ [29d9fc4e0c4e]
+
+2012-06-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ If installing with installp, error out if there is already an
+ instance of the rpm package installed.
+ [ec24c6faba22]
+
+ * mkpkg:
+ Add --disable-nls for AIX
+ [192ac2f7d65e]
+
+2012-06-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Debian sudo-ldap packages should now depend on libldap-2.4-2, not
+ libldap2.
+ [cbcec71e6b58]
+
+2012-06-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Add Homepage and Bugs to debian control file.
+ [0f19d7d14e66]
+
+2012-06-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ fix typo when setting aix_freeware
+ [2fd6feb50195]
+
+ * common/Makefile.in, compat/Makefile.in, configure, configure.in,
+ doc/Makefile.in, include/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in, src/Makefile.in, zlib/Makefile.in:
+ Don't run regress tests or sudoers sanity check (using the newly-
+ built visudo) when cross compiling. Bug #560
+ [0c4e3f68b2f5]
+
+ * MANIFEST, configure, configure.in, plugins/sample/Makefile.in,
+ plugins/sample/sample_plugin.exp, plugins/sample/sample_plugin.map,
+ plugins/sample/sample_plugin.sym, plugins/sample_group/Makefile.in,
+ plugins/sample_group/sample_group.exp,
+ plugins/sample_group/sample_group.map,
+ plugins/sample_group/sample_group.sym, plugins/sudoers/Makefile.in,
+ plugins/sudoers/sudoers.exp, plugins/sudoers/sudoers.map,
+ plugins/sudoers/sudoers.sym, plugins/system_group/Makefile.in,
+ plugins/system_group/system_group.exp,
+ plugins/system_group/system_group.map,
+ plugins/system_group/system_group.sym:
+ Rename foo.sym -> foo.exp Remove foo.map from the repo and generate
+ it on demand Use a loader option file for HP-UX ld to explicitly
+ export symbols
+ [2402ff5302ab]
+
+ * src/Makefile.in:
+ Remove extraneous backslash
+ [8ca054de138c]
+
+ * plugins/sudoers/regress/check_symbols/check_symbols.c:
+ Don't check for errorx as an exported symbols as it is now a macro.
+ Check for user_in_group() instead.
+ [7b02c8ecd3ea]
+
+2012-06-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Adjust ld map file support to use an anonymous scope to match the
+ updated .map files.
+ [49be44282d9e]
+
+2012-06-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, include/gettext.h:
+ Older versions of Solaris lack ngettext()
+ [028af10dfa5f]
+
+ * configure, configure.in:
+ Move the check for -static-libgcc until after AC_LANG_WERROR has
+ been called and use AX_CHECK_COMPILE_FLAG().
+ [a7b09120e7ff]
+
+ * include/gettext.h:
+ Sudo defines HAVE_SETLOCALE not HAVE_LOCALE_H
+ [3aa2780d4a4e]
+
+ * include/error.h, include/sudo_debug.h:
+ Fix gcc 2.x variant macro support.
+ [8e71c2370997]
+
+ * plugins/sudoers/logging.c, plugins/sudoers/sudoreplay.c:
+ Fix compilation on gcc 2.95 and other compilers that only allow
+ variable declarations at the beginning of a block.
+ [9d80c802bb46]
+
+ * configure, configure.in, plugins/sudoers/Makefile.in:
+ Link check_symbols with SUDO_LIBS to make sure we link with the
+ requisite libraries to successfully dlopen sudoers.so. This is
+ needed on HP-UX where a program dlopen()ing a shared object that
+ uses pthreads must also be linked with pthreads (and HP-UX LDAP uses
+ pthreads).
+ [b8961cd82337]
+
+ * plugins/sudoers/regress/check_symbols/check_symbols.c:
+ Add check for exported local symbols. This will cause a "make check"
+ failure on systems where we don't support symbol hiding.
+ [8aa549389bb1]
+
+ * configure, configure.in:
+ Additional ${foo} -> $(foo) Makefile tweaks.
+ [046bbde18f52]
+
+ * plugins/sample/sample_plugin.map,
+ plugins/sample_group/sample_group.map, plugins/sudoers/sudoers.map,
+ plugins/system_group/system_group.map:
+ No need to provide a name for the scope in the map file since we
+ don't use the it for versioning.
+ [5ed4b997560d]
+
+2012-06-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/check_symbols/check_symbols.c:
+ Add regress test for symbol visibility.
+ [9adddd4e0518]
+
+2012-06-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.in:
+ sudo 1.8.6
+ [57008a7afb77]
+
+ * configure, configure.in, include/missing.h:
+ Add support for controlling symbol visibility using the HP and
+ Solaris C compilers.
+ [46d5b468979e]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/sudoers.h:
+ Use the expanded io log dir when updating the sequence number.
+ Includes a workaround for older versions of sudo where the sequence
+ number was stored in the unexpanded io log dir.
+ [210797dab9a8]
+
+2012-06-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/parse_args.c:
+ Simplify "sudo -s" argv rewriting.
+ [7be143dae7c5]
+
+ * MANIFEST, configure, configure.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in, src/Makefile.in,
+ src/sudo_noexec.map:
+ Don't use a map file for sudo_noexec.so since Solaris ld doesn't
+ allow '*' in the global section. The libtool export flag is now
+ added to LT_LDFLAGS instead of commenting/uncommenting lines.
+ [38fc37a66b04]
+
+2012-06-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, include/missing.h:
+ The visibility attribute was actually added in gcc 3.3.x, not 4.0.
+ Just assume that if -fvisibility=hidden works that the attribute is
+ usable.
+ [d3904d6faf14]
+
+ * plugins/sudoers/check.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/iolog_path.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/match.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoers.map,
+ plugins/sudoers/sudoers.sym, plugins/sudoers/testsudoers.c,
+ plugins/system_group/system_group.c:
+ Export group cache from sudoers.so for system_group.so to use.
+ [16695d207fc5]
+
+ * MANIFEST, configure, configure.in, include/missing.h,
+ plugins/sample/Makefile.in, plugins/sample/sample_plugin.map,
+ plugins/sample_group/Makefile.in,
+ plugins/sample_group/sample_group.map, plugins/sudoers/Makefile.in,
+ plugins/sudoers/iolog.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.map, plugins/system_group/Makefile.in,
+ plugins/system_group/system_group.map, src/sudo_noexec.c,
+ src/sudo_noexec.map:
+ Use gcc's visibility attribute to specify when symbols are visible
+ or hidden, if available. If not available, use an ELF version script
+ if it is supported. If all else fails, fall back to using libtool's
+ -export-symbols.
+ [64e889921727]
+
+2012-06-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Add mode for installed locale files but leave the directories with
+ default mode and owner.
+ [142237dbb31f]
+
+2012-06-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg, sudo.pp:
+ Install AIX packages under /opt/freeware with links in /usr/bin and
+ /usr/sbin. This matches the layout of the sudo package from AIX
+ freeware.
+ [0b79d47bbe01]
+
+ * Makefile.in, configure, configure.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in, src/Makefile.in, sudo.pp:
+ Install shared objects with mode 0644 except on HP-UX which needs
+ the executable bit set.
+ [ae416af0ba6c]
+
+ * Makefile.in, doc/Makefile.in, include/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in:
+ Make installed file modes consistent with the file modes in the sudo
+ package.
+ [307386373289]
+
+2012-06-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.pod:
+ Add "%:" prefix when talking about QAS non-Unix group support.
+ [7cb25f6861f8]
+
+ * pp, sudo.pp:
+ Fix packaging of symbolic links on HP-UX when the link source
+ already exists in the filesystem.
+ [c9bb48031596]
+
+ * mkpkg:
+ Only specify prefix if we are overriding the default value. Fixes
+ the man dir (/usr/local/man vs. /usr/local/share/man).
+ [65351b6c1697]
+
+ * sudo.pp:
+ Fix setting of sudoedit_man variable.
+ [9beed9ae5bba]
+
+ * doc/Makefile.in:
+ Echo the command when linking the sudoedit manual.
+ [6c83b5657b55]
+
+2012-06-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg, sudo.pp:
+ Build .deb packages with selinux support.
+ [3fd9cb1b4526]
+
+2012-06-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Don't list paths for unstripped binaries in the lintial overrides.
+ [4c8e16f1773b]
+
+ * pp:
+ Add support for Installed-Size header in control file, required by
+ newer debian versions.
+ [e97d76234bee]
+
+ * pp:
+ Fix extended description in .deb files.
+ [d35e27ace146]
+
+ * sudo.pp:
+ Add Depends, Replaces and Conflicts headers for .deb packages.
+ [76eb6c4b3278]
+
+2012-06-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudo_nss.c:
+ If there are no privs to print, write the message to the lbuf
+ instead of printing it directly.
+ [ecd56226abb7]
+
+2012-05-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Set -e in %pos and %preun for debian to quiet a lintian warning.
+ [8bb908514df9]
+
+ * doc/Makefile.in, src/Makefile.in, sudo.pp:
+ Install sudoedit and the sudoedit manual as symbolic links, not hard
+ links and package them as such.
+ [f317ff3cf3e7]
+
+ * sudo.pp:
+ Make sudo binary permissions 755 instead of 111 Add lintian
+ overrides file for .deb files.
+ [991cd7d7f0e1]
+
+ * configure, configure.in, doc/Makefile.in, mkpkg:
+ Replace out of date MAN_POSTINSTALL with MANCOMPRESS and
+ MANCOMPRESSEXT which can be used to compress the installed manual
+ pages. Compress the man pages for .deb files to appease lintian.
+ [4e34083b41d2]
+
+ * sudo.pp:
+ Debian fixes:
+ * fix modes to be more in line with what Debian expects
+ * add section
+ * install LICENSE as copyright and ChangeLog as changelog
+ * create stub changelog.debian
+ [7f6c5647f588]
+
+ * pp:
+ Fix find command to properly skip files in the DEBIAN dir when
+ building md5sums.
+ [8918bde941fa]
+
+ * pp, sudo.pp:
+ Use a debian-compliant package maintainer field.
+ [fc51a94170eb]
+
+2012-05-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ No need to loop over atomic_writev(), it guarantees to write all
+ data or return an error.
+
+ Fix handling of stdout/stderr that contains "\r\n" and handle a
+ "\r\n" pair that spans a buffer.
+ [8aaf02d90c45]
+
+2012-05-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Update for sudo 1.8.5p2
+ [d369d4d40a19]
+
+ * plugins/sudoers/sudoreplay.c:
+ Instead of doing extra write()s when replaying stdout, build up a
+ vector for writev() instead. This results in far fewer system calls.
+ [303d866c025c]
+
+2012-05-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/env_hooks.c, src/sudo.h, src/tgetpass.c:
+ Provide unhooked version of getenv() and use it when looking up
+ DISPLAY and SUDO_ASKPASS in the environment.
+ [04dbdccf4a14]
+
+2012-05-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ When replaying a log of stdout or stderr, do newline to carriage
+ return + linefeed conversion. We cannot have termios do this for us
+ since we've disabled output postprocessing (POST) when setting raw
+ mode.
+ [61352a7d996f]
+
+2012-05-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ When checking for -fstack-protector, treat warnings as fatal errors.
+ [4124cd12d511]
+
+2012-05-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Fix test for -z relro
+ [548bdb6f5c4a]
+
+ * MANIFEST:
+ Add m4/ax_check_compile_flag.m4 and m4/ax_check_link_flag.m4
+ [ed063264a2a1]
+
+ * INSTALL, aclocal.m4, configure, configure.in,
+ m4/ax_check_compile_flag.m4, m4/ax_check_link_flag.m4:
+ Build with -fstack-protector and link with -zrelo where supported.
+ Added --disable-hardening option to disable hardening options.
+ [0b6c1a1ceb03]
+
+2012-05-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/testsudoers/test1.sh,
+ plugins/sudoers/regress/testsudoers/test2.sh,
+ plugins/sudoers/regress/testsudoers/test3.sh,
+ plugins/sudoers/regress/testsudoers/test4.out.ok,
+ plugins/sudoers/regress/testsudoers/test4.sh,
+ plugins/sudoers/regress/testsudoers/test5.inc,
+ plugins/sudoers/regress/testsudoers/test5.out.ok,
+ plugins/sudoers/regress/testsudoers/test5.sh,
+ plugins/sudoers/testsudoers.c:
+ Add tests for sudoers mode, owner and group checks.
+ [a7607443aba0]
+
+ * plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.c:
+ If sudoers_mode is group-readable but the actual sudoers file is
+ not, open the file as uid 0, not uid 1. This fixes a problem when
+ sudoers has a more restrictive mode than what sudo expects to find.
+ In older versions, sudo would silently chmod the file to add the
+ group-readable bit.
+ [c056b6003e6f]
+
+ * INSTALL, common/secure_path.c, config.h.in, configure, configure.in:
+ No longer throw an error if sudoers is a symbolic link. Deprecated
+ the --with-stow option as that is now (effectively) the default.
+ [8ce783e54886]
+
+2012-05-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/testsudoers/test2.inc,
+ plugins/sudoers/regress/testsudoers/test2.out.ok,
+ plugins/sudoers/regress/testsudoers/test2.sh,
+ plugins/sudoers/regress/testsudoers/test3.d/root,
+ plugins/sudoers/regress/testsudoers/test3.out.ok,
+ plugins/sudoers/regress/testsudoers/test3.sh:
+ Add basic tests for #include and #includedir
+ [b303e4218951]
+
+ * plugins/sudoers/testsudoers.c:
+ Add -U sudoers_uid option to testsudoers.
+ [3f8ed13501ba]
+
+2012-05-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, configure, configure.in:
+ Update for 1.8.5p1
+ [c33c49bf5b4b]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Fix #includedir; from Mike Frysinger
+ [d4833d4e39a0]
+
+ * plugins/sudoers/check.c:
+ Don't prompt for a password if the user is in the exempt group, is
+ root, or is running the command as themselves even if the -k option
+ was specified. This makes "sudo -k command" consistent with the
+ behavior one would get if the user ran "sudo -k" immediately before
+ running the command.
+ [632b3961df00]
+
+2012-05-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ Fix capitalization
+ [7258aa977caf]
+
+ * mkpkg:
+ Build PIE executable on Mac OS X 10.5 and above.
+ [2a5c7ef92182]
+
+2012-05-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Update for sudo 1.8.4p5
+ [21164f508b68]
+
+ * plugins/sudoers/match_addr.c:
+ Add missing break between AF_INET and AF_INET6 in
+ addr_matches_if_netmask()
+ [672a4793931a]
+
+ * plugins/sudoers/mon_systrace.c:
+ Move systrace monitor code to the attic
+ [d6faf4754e9c]
+
+2012-05-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ The pointer to the siginfo_t struct in a signal handler may be NULL.
+ [41a4ee934b53]
+
+2012-05-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/pwutil.c:
+ Fix an alignment problem on NetBSD systems with a 64-bit time_t and
+ strict alignment. Based on a patch from Martin Husemann.
+ [1e5ba3c18f17]
+
+ * include/missing.h:
+ Add offsetof macro for those without it.
+ [e44cb51d2587]
+
+ * MANIFEST:
+ add system_group plugin
+ [6169793b510c]
+
+2012-05-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/dlopen.c:
+ Implement RTLD_NEXT and fix RTLD_DEFAULT for HP-UX.
+ [85bd03bc5d94]
+
+2012-05-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Mention system_group plugin
+ [05393dd4bdb8]
+
+ * Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/system_group/Makefile.in:
+ update depends
+ [6feb0b824fc4]
+
+ * plugins/system_group/system_group.c:
+ Only call gr_delref() when use sudo's password caching functions.
+ [1103442e21fa]
+
+ * plugins/sample_group/Makefile.in, plugins/system_group/Makefile.in:
+ Add missing dependency on libreplace.la
+ [05bfd9d4657f]
+
+ * compat/dlopen.c:
+ Emulate RTLD_DEFAULT and RTLD_SELF w/ shl_findsym() using NULL and
+ PROG_HANDLE.
+ [2382d0693acc]
+
+ * Makefile.in, configure, configure.in,
+ plugins/system_group/Makefile.in,
+ plugins/system_group/system_group.c,
+ plugins/system_group/system_group.sym:
+ Add group plugin that does lookups by name using the system group
+ database.
+ [2ddbb604112f]
+
+ * plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po, src/po/pl.mo,
+ src/po/pl.po:
+ sync with translationproject.org
+ [4ef05df4226d]
+
+2012-05-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po,
+ src/po/de.mo, src/po/de.po, src/po/eo.mo, src/po/eo.po,
+ src/po/fi.mo, src/po/fi.po, src/po/ja.mo, src/po/ja.po,
+ src/po/ru.mo, src/po/ru.po, src/po/sr.mo, src/po/sr.po,
+ src/po/uk.mo, src/po/uk.po, src/po/vi.mo, src/po/vi.po,
+ src/po/zh_CN.mo, src/po/zh_CN.po:
+ sync with translationproject.org
+ [115c3f828fc5]
+
+2012-05-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Add mode for docdir and use '-' (default) for localedir mode. Fixes
+ a problem on Linux when building in a directory with the setgid bit
+ set.
+ [582279c8bcb1]
+
+2012-04-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pp:
+ Match CentOS 6.0
+ [1e99ef210f98]
+
+2012-04-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Update with recent changes
+ [c5fc220ba696]
+
+ * pp:
+ Fix version check on AIX
+ [d272e39112f4]
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ regen
+ [72b23509465a]
+
+ * plugins/sudoers/ldap.c:
+ Need to call ldapssl_clientauth_init() for start_tls on Mozilla LDAP
+ SDK.
+ [87b685e70b9a]
+
+ * plugins/sudoers/ldap.c:
+ Fix printing of invalid uri
+ [645aa53acdde]
+
+ * plugins/sudoers/auth/pam.c:
+ Pass PAM_SILENT when deleting creds to remove an annoying warning
+ message on Solaris.
+ [1dd0301ef293]
+
+2012-04-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/utmp.c:
+ Fix the setutxent and endutxent compatibility defines (this time
+ correctly) when only setutent and endutent are available.
+ [d136d2867db9]
+
+ * plugins/sudoers/ldap.c:
+ sudo_ldap_set_options_global() should not take an LDAP handle as an
+ argument since the options affect the global settings.
+ [1dc39b9d20f2]
+
+ * mkpkg:
+ Debian sudo has not been built with --with-exempt=sudo since 1.6.8.
+ [c7716291a856]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod,
+ plugins/sudoers/auth/pam.c, src/exec.c, src/exec_pty.c, src/sudo.c,
+ src/sudo.h:
+ Call the policy's init_session() function before we fork the child.
+ That way, the session is created and destroyed in the same process,
+ which is needed by some modules, such as pam_mount.
+ [ece552ba002e]
+
+ * doc/TROUBLESHOOTING:
+ Add entry for SSL LDAP errors on Mozilla SDKs when the cert dir is
+ not specified.
+ [bd293e100b28]
+
+ * plugins/sudoers/auth/pam.c:
+ Delete creds after closing the PAM session.
+ [5158d726d6a5]
+
+ * plugins/sudoers/ldap.c:
+ Provide a more useful error message if using a Mozilla-style LDAP
+ SDK and you forgot to specify TLS_CERT in ldap.conf.
+ [7cb78feb899c]
+
+ * src/exec_pty.c:
+ Add missing initialization of a sigaction structure when I/O
+ logging. Fixes a potential problem when suspending the command.
+ [f4480f2ba816]
+
+ * plugins/sudoers/ldap.c:
+ Split global and per-connection LDAP options into separate arrays.
+ Set global LDAP options before calling ldap_initialize() or
+ ldap_init(). After we have an LDAP handle, set the per-connection
+ options. Fixes a problem with OpenLDAP using the nss crypto backend;
+ bug #342
+ [265c9d2dc12b]
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po,
+ src/po/de.mo, src/po/de.po, src/po/hr.mo, src/po/hr.po,
+ src/po/vi.mo, src/po/vi.po, src/po/zh_CN.mo, src/po/zh_CN.po:
+ sync with translationproject.org
+ [6d7fe44be21e]
+
+2012-04-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo.c, src/sudo.h:
+ Move struct passwd pointer into struct command details.
+ [d6fb1eff2065]
+
+2012-04-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pp:
+ Sync with upstream for Mac OS X (and other) fixes.
+ [c2f4998d01b0]
+
+ * mkpkg:
+ Only built Mac intel universal binary on an intel machine.
+ [0009e0b7e5a8]
+
+ * src/Makefile.in:
+ Do not pass libtool the -static-libtool-libs option when building
+ sudo and sesh. Otherwise, libtool may prefer a static version of an
+ installed library over a dynamic one when linking.
+ [6fbac9adc885]
+
+2012-04-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, NEWS, doc/CONTRIBUTORS, plugins/sudoers/po/hr.mo,
+ plugins/sudoers/po/hr.po, src/po/de.mo, src/po/de.po:
+ Add German translation for sudo Add Croatian translation for sudoers
+ [fa4da1a6530c]
+
+ * plugins/sudoers/iolog.c:
+ typo fix in comment
+ [abd721d1288e]
+
+2012-04-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Update with recent changes
+ [6fa11e8448b9]
+
+ * Makefile.in, plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ Sort xgettext output by file name.
+ [f650841810f0]
+
+ * doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.pod:
+ Clarify what "sudoreplay -l" displays and mention that it is sorted.
+ [84031c117bd6]
+
+ * config.h.in, configure, configure.in, src/ttyname.c:
+ Use AC_HEADER_MAJOR to determine where major/minor are defined.
+ [3c949650a223]
+
+ * config.h.in, configure, configure.in, src/ttyname.c:
+ Include sys/mkdev.h if present instead of sys/sysmacros.h for
+ minor(). This is needed on Solaris (at least) where the makedev
+ macros in sysmacros.h are obsolete and library functions should be
+ used instead.
+ [343928acf81e]
+
+ * mkpkg:
+ When building on Mac OS X, only set SDK_FLAGS if specified osversion
+ doesn't match host.
+ [d84c6efac872]
+
+2012-04-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/ttyname.c:
+ Add back buf and tty variables for _ttyname() case that were
+ inadvertantly removed.
+ [a4a820b22a44]
+
+2012-04-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [5446b12c1250]
+
+ * configure, configure.in:
+ Remove b8 from version number.
+ [5adc4dcec061]
+
+ * src/ttyname.c:
+ remove some XXX
+ [187579a5f593]
+
+ * src/ttyname.c:
+ When looking for a device match, do a breadth-first search instead
+ of depth-first. We already special case /dev/pts/ so chances are
+ good that if it is not a pseudo-tty it is in the base of /dev/. Also
+ avoid a stat(2) when possible if struct dirent has d_type.
+ [0183f8a1b278]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod,
+ src/sudo.c, src/sudo.h:
+ Pass pid, ppid, sid, pgid and tcpgid to plugin in user_info list.
+ [f0574d878491]
+
+ * src/po/eo.mo, src/po/es.mo, src/po/es.po, src/po/fi.mo,
+ src/po/ja.mo, src/po/pl.mo, src/po/ru.mo, src/po/uk.mo,
+ src/po/vi.mo:
+ sync with translationproject.org
+ [4527ea78fbd5]
+
+ * MANIFEST, NEWS, doc/CONTRIBUTORS, src/po/gl.mo, src/po/gl.po,
+ src/po/hr.mo, src/po/hr.po:
+ New Croatian and Galician translations from translationproject.org
+ [ad4bd924b4de]
+
+ * src/ttyname.c:
+ Add depth-first traversal of /dev/ for the /proc case when not
+ /dev/pts/N
+ [499bd3456774]
+
+ * config.h.in, configure, configure.in, plugins/sudoers/sudoreplay.c:
+ If struct dirent has d_type, use it to avoid an extra stat().
+ [741dabbe4bcd]
+
+ * plugins/sudoers/sudoreplay.c:
+ Sort output of "sudoreplay -l"
+ [c0615795bd4b]
+
+2012-04-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ Fix duplicate free introduced in last rev
+ [efdaabe69d75]
+
+2012-04-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/pam.c:
+ Instead of treating ^C from tgetpass() specially, always return
+ AUTH_INTR if tgetpass() returned NULL. Treat PAM_AUTHINFO_UNAVAIL
+ like PAM_AUTH_ERR which Mac OS X returns this when there is no tty.
+ [a3b17298d4d0]
+
+ * config.h.in, configure, configure.in, src/ttyname.c:
+ Rototill code to determine the tty. For Linux, we now look up the
+ tty device in /proc/pid/stat instead of trying to open
+ /proc/pid/fd/[0-2]. The sudo_ttyname_dev() function maps the given
+ device number to a string. On BSD, we can use devname(). On Solaris,
+ _ttyname_dev() does what we want. TODO: write /dev/ traversal code
+ for the generic sudo_ttyname_dev().
+ [6b22be4d09f0]
+
+2012-04-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/ttyname.c:
+ Define PRNODEV for those w/o it.
+ [f17290e64559]
+
+ * config.h.in, configure, configure.in, src/ttyname.c:
+ Check for SVR4-style struct psinfo.pr_ttydev and use that to
+ determine the tty if std{in,out,err} are not ttys.
+ [76ad33a91f4b]
+
+ * src/ttyname.c:
+ Better support for SVR4-style /proc entries where we can't use
+ ttyname() on the /proc/pid/fd/[0-2] entries. We can, however,
+ attempt to map the device number back to the correct pseudo-tty
+ slave device.
+ [4f9f48cc79eb]
+
+ * src/ttyname.c:
+ When trying to determine the tty name, check parent's stderr in
+ addition to its stdin and stdout.
+ [604644056c7d]
+
+ * src/exec_pty.c:
+ Treat a tty read failure like EOF as it usually means the pty has
+ gone away. Handle write() on the tty returning EIO.
+ [16957f4a706f]
+
+ * src/exec.c, src/exec_pty.c:
+ Linux select() may return ENOMEM if there is a kernel resource
+ shortage. Older Solaris select() may return EIO instead of EBADF
+ when the tty goes away. If we get an unhandled select() failure,
+ kill the child and exit cleanly.
+ [d93940a311ab]
+
+ * src/ttyname.c:
+ Open /proc/pid/fd/[0-2] in non-blocking mode just in case we might
+ block in open.
+ [a9f809d09d52]
+
+2012-04-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/set_perms.c:
+ Fix restoration of AIX permissions.
+ [30c717115988]
+
+ * src/parse_args.c:
+ Allow the -k flag to be used along with the -i and -s flags.
+ [0653b17c97f1]
+
+ * plugins/sudoers/sudoreplay.c:
+ Plug memory leak in parse_logfile() in the error path.
+ [9cce86fa833b]
+
+ * plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po,
+ src/po/da.mo, src/po/da.po, src/po/eo.po, src/po/es.po,
+ src/po/fi.po, src/po/it.mo, src/po/it.po, src/po/ja.po,
+ src/po/pl.po, src/po/ru.po, src/po/uk.po, src/po/vi.po,
+ src/po/zh_CN.mo, src/po/zh_CN.po:
+ sync with translationproject.org
+ [14af43d0b170]
+
+2012-04-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/regress/glob/globtest.c, config.h.in, configure,
+ configure.in, plugins/sudoers/match.c:
+ Do not use GLOB_BRACE or GLOB_TILDE flags to glob()--we want the
+ glob() and fnmatch() results to be consistent.
+ [4226750d73c2]
+
+2012-04-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/Makefile.in, common/ttysize.c, src/Makefile.in,
+ src/ttysize.c:
+ Move ttysize.c to common so sudoreplay can use it.
+ [b4a0aa514cd4]
+
+ * plugins/sudoers/sudoreplay.c:
+ If I/O log file includes rows + cols, warn if the user's tty is not
+ big enough.
+ [b980ef89efff]
+
+ * plugins/sudoers/sudoreplay.c:
+ Fix printing of TSID in "sudoreplay -l"
+ [4221e3e108b4]
+
+ * common/sudo_debug.c, include/sudo_debug.h,
+ plugins/sudoers/logging.c, plugins/sudoers/visudo.c, src/exec.c,
+ src/exec_pty.c:
+ Log the process id in the debug file output. Since we don't want to
+ keep calling getpid(), stash the value at init time and when we
+ fork().
+ [2782d30c024d]
+
+ * src/exec_pty.c:
+ Ignore SIGTTIN and SIGTTOU in main sudo process when I/O logging. It
+ is better to receive EIO from read()/write() than to be suspended
+ when we don't expect it. Fixes a problem when our terminal is
+ revoked which can happen when, e.g. our sshd is killed
+ unceremoniously. Also, only change the value of "alive" from true to
+ false, never from false to true. It is possible for us to receive
+ notification of the child having stopped after it is already dead.
+ This does not mean it has risen from the grave.
+ [26c9fe8ce0f9]
+
+ * src/exec_pty.c:
+ Distinguish between signals we received from the parent vs. those
+ delivered explicitly to the monitor process in debugging info.
+ [40716cb180e5]
+
+2012-04-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c:
+ In Solaris 11, /dev/pts under the "dev" filesystem, not "devices".
+ Update tty_is_devpts() to match so we can determine when the tty has
+ been reused.
+ [2689665df027]
+
+ * common/sudo_debug.c, include/error.h, include/sudo_debug.h:
+ Always pass __func__, __FILE__ and __LINE__ in sudo_debug_printf()
+ and use a new flag, SUDO_DEBUG_FILENO to specify when to use it.
+ This allows consumers of sudo_debug_printf() to log that data
+ without having to specify it manually.
+ [7c94c4879208]
+
+ * src/exec_pty.c:
+ Make this compile after last change.
+ [ee09034f3266]
+
+ * src/exec_pty.c:
+ Don't try to restore the terminal if we are not the foreground
+ process. Otherwise, we may be stopped by SIGTTOU when we try to
+ update the terminal settings when cleaning up.
+ [c48b24335456]
+
+ * src/exec.c:
+ If select() return EBADF in the main event loop, one of the ttys
+ must have gone away so perform any I/O we can and close the bad fds.
+ [3bc8678c03ce]
+
+ * common/sudo_debug.c, include/error.h, include/sudo_debug.h,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.h,
+ plugins/sudoers/toke.l:
+ Log warning() at SUDO_DEBUG_WARN not SUDO_DEBUG_ERROR. Log the
+ function, file and line number in the debug log for warning() and
+ error().
+ [894cd131f11d]
+
+2012-04-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/sudo_debug.c, include/error.h, include/sudo_debug.h,
+ src/conversation.c:
+ Add SUDO_DEBUG_ERRNO flag to debug functions so we can log errno.
+ Use this flag when wrapping error() and warning() so the debug
+ output includes the error string.
+ [1e2c67adaf1f]
+
+2012-03-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Update for sudo 1.8.5
+ [7d2b62b823fe]
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen
+ [718ad9de92cd]
+
+ * doc/CONTRIBUTORS:
+ sync
+ [f48013aea641]
+
+ * plugins/sudoers/pwutil.c:
+ Use ecalloc()
+ [fabd23c1f271]
+
+ * src/exec_pty.c:
+ Don't need zero_bytes() after ecalloc()
+ [1a9d95cd10ef]
+
+ * config.h.in, configure, configure.in, src/sudo_noexec.c:
+ Add execvpe(), exect(), posix_spawn() and posix_spawnp() wrappers to
+ sudo_noexec.c.
+ [cbaa1d4b0f8a]
+
+ * src/utmp.c:
+ Fix compat setutxent and endutxent macros for systems with
+ setutent() but not setutxent(). From Gustavo Zacarias
+ [d7ce622fc5f2]
+
+2012-03-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ Add ignore_result definition to AH_BOTTOM
+ [8d4096838a98]
+
+ * common/sudo_debug.c, config.h.in, plugins/sample/sample_plugin.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/visudo.c, src/env_hooks.c,
+ src/exec.c, src/exec_pty.c, src/tgetpass.c:
+ Fix compiler warnings on some platforms and provide a better method
+ of defeating gcc's warn_unused_result attribute.
+ [9a8f804fcc75]
+
+ * configure, configure.in:
+ Fix building the builtin zlib from a build dir. When a zlib dir was
+ specified, prepend its include path instead of appending so we get
+ the right zlib headers.
+ [5f61d591b186]
+
+ * doc/LICENSE, zlib/adler32.c, zlib/crc32.c, zlib/crc32.h,
+ zlib/deflate.c, zlib/deflate.h, zlib/gzguts.h, zlib/gzlib.c,
+ zlib/gzread.c, zlib/gzwrite.c, zlib/infback.c, zlib/inffixed.h,
+ zlib/inflate.c, zlib/inftrees.c, zlib/trees.c, zlib/zconf.h.in,
+ zlib/zlib.h, zlib/zutil.c, zlib/zutil.h:
+ Update zlib to version 1.2.6
+ [173c4bc4d4fc]
+
+2012-03-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/missing.h:
+ g/c __unused which is no longer used
+ [7ef3f23edcd6]
+
+ * src/env_hooks.c:
+ Fix compilation if RTLD_NEXT is not defined.
+ [d5605f468b71]
+
+ * src/po/sr.mo, src/po/sr.po:
+ sync with translationproject.org
+ [27d559f7985d]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudoers.cat,
+ doc/sudoers.man.in:
+ regen
+ [f9f63ce478b6]
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ regen
+ [59035d82d15a]
+
+ * Makefile.in:
+ Ignore Project-Id-Version when comparing pot files.
+ [22feb9ede46b]
+
+ * plugins/sudoers/bsm_audit.c:
+ Use error() instead of log_fatal()
+ [54130bda4b50]
+
+ * plugins/sudoers/env.c:
+ Fix signedness of didvar in env_update_didvar()
+ [77048a80b3e4]
+
+ * plugins/sudoers/iolog.c:
+ Quiet a compiler warning on some platforms.
+ [8fdcaece0400]
+
+ * compat/fnmatch.c:
+ cast ctype(3) function/macro arguments from char to unsigned char to
+ avoid potential negative subscripting.
+ [bdcf7eef21ef]
+
+ * common/setgroups.c:
+ Quiet a warning on systems where the gids array in setgroups() is
+ not prototyped as being const, even though it really is.
+ [fdd758c6302d]
+
+ * src/env_hooks.c:
+ Quiet a compiler warning on systems where the argument to putenv(3)
+ is const.
+ [51bae2193b53]
+
+ * plugins/sudoers/sudoreplay.c:
+ Undo an incorrect int -> bool conversion.
+ [b9a4ce320f14]
+
+ * MANIFEST, NEWS, plugins/sudoers/po/sv.mo, plugins/sudoers/po/sv.po,
+ src/po/sv.mo, src/po/sv.po:
+ Add Swedish sudo and sudoers translations from
+ translationproject.org
+ [f7ce1de9073f]
+
+ * plugins/sudoers/env.c:
+ No need to preserve ODMDIR on AIX now that we always read
+ /etc/environment.
+ [4aa04b2f0125]
+
+2012-03-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.pod, plugins/sudoers/env.c:
+ When initializing the environment for env_reset, start out with the
+ contents of /etc/environment on AIX and login.conf on BSD.
+ [5717bdc321e2]
+
+ * doc/TROUBLESHOOTING, src/sudo.c:
+ If we are not running with an effective uid of 0, try to give the
+ user enough information to debug the problem.
+ [fa4894896d8a]
+
+ * plugins/sudoers/getdate.c, plugins/sudoers/gram.c:
+ Quiet a clang-analyzer false positive.
+ [c4c0c1b9c8b0]
+
+ * src/tgetpass.c:
+ If there is nothing to read from the askpass program, set errno to
+ EINTR. This makes the cancel button behave like the user entered ^C
+ at the password prompt when PAM is used.
+ [594302cb9caf]
+
+ * src/sudo.h, src/tgetpass.c:
+ Fetch the value of "askpass" from the sudo conf struct.
+ [4593ee8f1bd3]
+
+ * common/sudo_conf.c:
+ Fix matching of "Path askpass" and "Path noexec"
+ [4df28d62afb9]
+
+2012-03-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo.c:
+ Quiet a clang-analyzer dead store warning.
+ [dd90bf385a3f]
+
+ * plugins/sudoers/sudoers.c:
+ If the "timestampowner" user cannot be resolved, use ROOT_UID
+ instead of exiting with a fatal error.
+ [8d62aae99715]
+
+ * plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/bsm_audit.c,
+ plugins/sudoers/check.c, plugins/sudoers/env.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/logging.c,
+ plugins/sudoers/logging.h, plugins/sudoers/parse.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.c:
+ Remove the NO_EXIT flag to log_error() and add a log_fatal()
+ function that exits and is marked no_return. Fixes false positives
+ from static analyzers and is easier for humans to read too.
+ [a0fe785c2a3d]
+
+2012-03-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po, src/po/eo.mo,
+ src/po/eo.po:
+ sync with translationproject.org
+ [df5e8777de13]
+
+2012-03-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/po/da.mo, src/po/da.po:
+ sync with translationproject.org
+ [629d99548b78]
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po:
+ sync with translationproject.org
+ [9d122a2860d6]
+
+2012-03-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/po/it.mo, src/po/it.po:
+ sync with translationproject.org
+ [6397593b15cf]
+
+ * common/sudo_conf.c, plugins/sudoers/alias.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/env.c,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/interfaces.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/visudo.c, src/exec.c, src/exec_pty.c, src/hooks.c,
+ src/load_plugins.c:
+ Use ecalloc() when allocating structs.
+ [8b5888868db2]
+
+ * common/alloc.c, include/alloc.h:
+ Add ecalloc() and commented out recalloc(). Use inline strnlen()
+ instead of strlen() in estrndup().
+ [7fb9aa46c1e0]
+
+2012-03-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po,
+ src/po/fi.mo, src/po/fi.po, src/po/ja.mo, src/po/ja.po,
+ src/po/pl.mo, src/po/pl.po, src/po/ru.mo, src/po/ru.po,
+ src/po/uk.mo, src/po/uk.po, src/po/vi.mo, src/po/vi.po,
+ src/po/zh_CN.mo, src/po/zh_CN.po:
+ sync with translationproject.org
+ [45a032c37334]
+
+2012-03-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/set_perms.c:
+ Remove unused label
+ [2660bb0c1313]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Document what changed in each plugin API revision
+ [59b30a6fc4d1]
+
+ * plugins/sudoers/set_perms.c:
+ Remove bogus optimization that could lead to a double free of the
+ group list.
+ [b0bfbd2a83a8]
+
+2012-03-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/TROUBLESHOOTING:
+ Expand AIX /etc/security/privcmds entry.
+ [9f3f072e034e]
+
+ * NEWS:
+ Update for sudo 1.8.5
+ [086049011f25]
+
+ * common/sudo_conf.c, doc/sample.sudo.conf, doc/sudo.cat,
+ doc/sudo.man.in, doc/sudo.pod, doc/sudo_plugin.cat,
+ doc/sudo_plugin.man.in, doc/sudo_plugin.pod, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.pod, include/sudo_conf.h,
+ include/sudo_plugin.h, src/load_plugins.c, src/sudo.c,
+ src/sudo_plugin_int.h:
+ Rename plugin "args" to "options"
+ [f25624951bd2]
+
+ * doc/CONTRIBUTORS:
+ Add Lithuanian and Vietnamese translators
+ [2b4c075b69e3]
+
+ * Makefile.in:
+ Ignore comments when comparing new and old pot files.
+ [f872999347b3]
+
+ * src/Makefile.in:
+ regen
+ [c8193b1b11c7]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in:
+ regen
+ [15e3c17e8a3a]
+
+ * doc/sudo_plugin.pod, include/sudo_plugin.h,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/auth/sudo_auth.h, plugins/sudoers/env.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h, src/hooks.c,
+ src/sudo.c, src/sudo.h:
+ Pass a pointer to user_env in to the init_session policy plugin
+ function so session setup can modify the user environment as needed.
+ For PAM authentication, merge the PAM environment with the user
+ environment at init_session time. We no longer need to swap in the
+ user_env for environ during session init, nor do we need to disable
+ the env hooks at init_session time.
+ [3f5277b359d8]
+
+ * plugins/sample/sample_plugin.c:
+ Add explicit NULL entries for init_session, register_hooks and
+ deregister_hooks with appropriate comments.
+ [727a57978b40]
+
+ * compat/pw_dup.c:
+ Quiet a gcc "used uninitialized in this function" false positive.
+ [f14b68379ce9]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ We should always call warning() with a format string or a string
+ literal. In this case, the argument (path) is not user-controlled.
+ [e9ef51224024]
+
+2012-03-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/selinux.c:
+ Include sudo_exec.h for the sudo_execve() prototype.
+ [769e58065edc]
+
+ * config.h.in, configure, configure.in:
+ Add check for pam_getenvlist()
+ [36bde3f26c60]
+
+ * common/sudo_conf.c:
+ Set args to NULL in default plugin info struct when there is no
+ Plugin line in sudo.conf.
+ [93ec67708f01]
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ regen
+ [a9287677795c]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo_plugin.cat,
+ doc/sudo_plugin.man.in, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.man.in, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/visudo.cat, doc/visudo.man.in:
+ regen
+ [a242769d7962]
+
+ * configure, configure.in:
+ Bump version to 1.8.5
+ [e8618f0c2505]
+
+ * doc/sudo_plugin.pod:
+ Document hooks API
+ [e6ad07d27958]
+
+2012-03-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Make sudoersdir relative to PKG_INSTALL_ROOT for Solaris.
+ [fd72340042d3]
+
+ * include/sudo_plugin.h:
+ Use sudo_hook_fn_t in struct sudo_hook.
+ [938f93112d6e]
+
+ * doc/TROUBLESHOOTING:
+ If cross compiling, --host must include the OS in the tuple. E.g.
+ --host powerpc-unknown-linux
+ [b8c010070c1e]
+
+2012-03-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/parse.c:
+ Fix bogus int -> bool conversion; tags can have a value of -1.
+ [e63d6434a303]
+
+ * plugins/sudoers/env.c:
+ Add env_should_keep() and env_should_delete() wrapper functions to
+ simplify things a bit and hide the fact that matches_env_check() is
+ not bool.
+ [7a03d7a12b50]
+
+ * sudo.pp:
+ Fix application of debian-specific sudoers mods when building
+ packages as non-root.
+ [34bf4c52c425]
+
+ * plugins/sudoers/env.c:
+ matches_env_check() returns int, not boolean
+ [0ad915b8d5cb]
+
+ * src/sudo_edit.c:
+ Fix compilation when seteuid() is not available.
+ [8a722f998000]
+
+ * src/ttyname.c:
+ Simply move the free of ki_proc outside the realloc() loop.
+ [217b786da760]
+
+ * src/ttyname.c:
+ Bring back the erealloc() for the ENOMEM loop and just zero the
+ pointer after we free it.
+ [29a016e45127]
+
+ * src/ttyname.c:
+ Don't try to erealloc() a potentially freed pointer; Mateusz Guzik
+ [266e08844065]
+
+2012-03-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/set_perms.c:
+ Use normal error path if unable to set sudoers gid.
+ [01c816918c99]
+
+ * plugins/sudoers/set_perms.c:
+ Make this work again on systems w/o seteuid().
+ [2e67f7421e97]
+
+2012-03-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/set_perms.c:
+ Fix compilation if no seteuid/setreuid/setresuid available.
+ [d0b3c1f88eb4]
+
+ * plugins/sudoers/set_perms.c:
+ Better error messages, and added debugging throughout. Fixed
+ seteuid() version of set_perms()/restore_perms(). Fixed logic bug in
+ AIX version of restore_perms(). Added checks to avoid changing
+ uid/gid when we don't have to. Never set gid/uid state to -1, use
+ the old value instead.
+ [29188d469b5c]
+
+ * src/exec_pty.c, src/ttyname.c:
+ Fix format string warning on Solaris with gcc 3.4.3.
+ [d1eeb6e1dd0f]
+
+ * src/sudo.c:
+ Always declare environ now that we swap it around unilaterally.
+ [aaa3e92e7d0d]
+
+ * src/Makefile.in:
+ Honor LDFLAGS when linking sesh; from Vita Cizek
+ [498b41438f6e]
+
+ * src/sesh.c:
+ Include alloc.h for estrdup() prototype; from Vita Cizek
+ [93203655a320]
+
+2012-03-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Don't read /etc/environment on Linux when using PAM, PAM should set
+ the environment variables as needed via pam_env.
+ [b1ef62cb2d40]
+
+ * INSTALL:
+ Fix editor goof.
+ [0c3dd3bb8b57]
+
+ * src/hooks.c, src/sudo.c, src/sudo.h:
+ Disable environment hooks after we get user_env back to make sure a
+ plugin can't to modify user_env after we "own" it. This is kind of a
+ hack but we don't want the init_session plugin function to modify
+ user_env.
+ [8e6d119452a5]
+
+ * src/hooks.c, src/sudo.c:
+ Add support for deregistering hooks. If an I/O log plugin fails to
+ initialize, deregister its hooks (if any).
+ [ac00c93900c5]
+
+2012-03-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c, src/sudo.c:
+ Move LOGIN_PATH and LOGIN_SETENV handling to plugin now that we hook
+ setenv.
+ [e75469dd9908]
+
+ * MANIFEST, aclocal.m4, common/sudo_debug.c, compat/Makefile.in,
+ compat/setenv.c, compat/unsetenv.c, config.h.in, configure,
+ configure.in, include/sudo_debug.h, include/sudo_plugin.h, mkdep.pl,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/env.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, src/Makefile.in, src/env_hooks.c,
+ src/hooks.c, src/load_plugins.c, src/sudo.c, src/sudo.h,
+ src/sudo_plugin_int.h:
+ Initial cut at a hooks implementation. The plugin can register hooks
+ for getenv, putenv, setenv and unsetenv. This makes it possible for
+ the plugin to trap changes to the environment made by authentication
+ methods such as PAM or BSD auth so that such changes are reflected
+ in the environment passed back to sudo for execve().
+ [61cffa06f863]
+
+2012-03-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, src/po/vi.mo, src/po/vi.po:
+ Add Vietnamese sudo translation from translationproject.org
+ [96df426790d5]
+
+2012-03-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sample.sudo.conf, doc/sudo.pod, doc/sudo_plugin.pod,
+ doc/sudoers.pod:
+ List sudo_noexec.so not noexec.so in the sample sudo.conf
+ [53844e190ec5]
+
+ * common/sudo_conf.c, doc/sample.sudo.conf, doc/sudo.pod,
+ doc/sudo_plugin.pod, doc/sudoers.pod, include/sudo_conf.h,
+ include/sudo_plugin.h, plugins/sample/sample_plugin.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/toke.l, src/load_plugins.c, src/sudo.c,
+ src/sudo_plugin_int.h:
+ Add support for plugin args at the end of a Plugin line in
+ sudo.conf. Bump the minor number accordingly and update the
+ documentation. A plugin must check the sudo front end's version
+ before using the plugin_args parameter since it is only supported
+ for API version 1.2 and higher.
+ [587f1f819536]
+
+2012-03-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ update depends
+ [6d2da44e11e5]
+
+ * MANIFEST:
+ secure_path.c is in common, not compat
+ [619c4a663dde]
+
+ * configure, configure.in:
+ Add check for variadic macro support in cpp.
+ [756854caf675]
+
+2012-02-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/secure_path.c, common/sudo_conf.c, include/secure_path.h,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Add type param to sudo_secure_path() and add sudo_secure_file() and
+ sudo_secure_dir() wrappers which get by #includedir in sudoers.
+ [2ec2d3d8df04]
+
+2012-02-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/visudo.pod, plugins/sudoers/visudo.c:
+ Check the owner and mode in -c (check) mode unless the -f option is
+ specified. Previously, the owner and mode were checked on the main
+ sudoers file when the -s (strict) option was given, but this was not
+ documented.
+ [b2d6ee1e547a]
+
+ * config.h.in, configure, configure.in, src/ttyname.c:
+ Prefer KERN_PROC2 over KERN_PROC. Fixes compilation on some versions
+ of OpenBSD versions that have KERN_PROC2 but not KERN_PROC.
+ [159f6a50456a]
+
+2012-02-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS:
+ Add Eric Lakin for patch in bug #538
+ [490c29c234c6]
+
+ * src/exec_pty.c:
+ Fix typo in safe_close() made while converting to debug framework
+ that prevented it from actually closing anything.
+ [a66422a62afd]
+
+ * src/exec_pty.c:
+ Add some more debugging.
+ [b5667947dda9]
+
+ * common/Makefile.in, compat/Makefile.in, doc/Makefile.in,
+ include/Makefile.in:
+ We need sysconfdir in compat/Makfile to get the proper sudo.conf
+ path. Add standard prefix and foodir expansion in all Makefiles to
+ avoid this problem in the future.
+ [62b6ce4ecae9]
+
+2012-02-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/po/lt.mo, plugins/sudoers/po/lt.po:
+ New Lithuanian sudoers translation from translationproject.org
+ [10436b649035]
+
+ * plugins/sudoers/po/ja.po:
+ Update from translationproject.org
+ [acb8db5f8ef1]
+
+2012-02-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ When adding gids to the LDAP filter, only add the primary gid once.
+ This is consistent with the space computation/allocation. From Eric
+ Lakin
+ [35d9d99c92c6]
+
+ * doc/TROUBLESHOOTING:
+ Add entry for AIX enhanced RBAC config.
+ [5e10b6f8def7]
+
+ * mkpkg:
+ Target Mac OS X 10.5 when building packages.
+ [06fce9bbebee]
+
+2012-02-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/Makefile.in, common/secure_path.c,
+ common/sudo_conf.c, include/secure_path.h,
+ plugins/sudoers/Makefile.in, plugins/sudoers/sudoers.c:
+ Relax the user/group/mode checks on sudoers files. As long as the
+ file is owned by the right user, not world-writable and not writable
+ by a group other than the one specified at configure time (gid 0 by
+ default), the file is considered OK. Note that visudo will still set
+ the mode to the value specified at configure time.
+ [241174babfcc]
+
+2012-02-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/set_perms.c:
+ Add AIX-specific version of permission setting code to make sure
+ that the saved uid gets restored properly.
+ [9a6f5d22c301]
+
+ * config.h.in, configure, configure.in, src/exec_common.c:
+ Check for LD_PRELOAD variants in configure instead of checkign cpp
+ symbols. In disable_execute(), compute the length of the new envp
+ and allocate it once instead of reallocating on demand. Also append
+ old value of LD_PRELOAD (if any) to the new value.
+ [680266346917]
+
+ * plugins/sudoers/def_data.c, plugins/sudoers/def_data.in:
+ Fix the description of noexec.
+ [6a6d142f3c80]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h:
+ The "op" parameter to set_default() must be int, not bool since it
+ is set to '+' or '-' for list add and subtract.
+ [8da5b137bea2]
+
+ * sudo.pp:
+ Make sure sudoers is writable before calling ed script.
+ [95352ab6336b]
+
+2012-02-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS, doc/contributors.pod:
+ Update contributors. Now includes translators and authors of compat
+ code.
+ [4fb5b616b50a]
+
+2012-02-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/po/sudo.pot:
+ regen
+ [2c86e2c328fe]
+
+ * pp, sudo.pp:
+ Build flat packages, not package bundles, on Mac OS X.
+ [57bda3cd5520]
+
+2012-02-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Move macos section to be with the other OS-specific sections.
+ [51423bb2973a]
+
+ * plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po:
+ Sync with translationproject.org
+ [8ce41cbb8da0]
+
+ * configure, configure.in:
+ Don't permanently add -D_FORTIFY_SOURCE=2 to CPPFLAGS
+ [fa979aa6fe7d]
+
+ * sudo.pp:
+ Add Mac OS X support, printing the latest chunk of the NEWS file and
+ the license text in the installer.
+ [ffeab72387c0]
+
+ * sudo.pp:
+ Add explicit file modes that match those used by "make install"
+ [7eb37242c920]
+
+ * pp:
+ Sync with upstream for Mac OS X fixes.
+ [97cba179041e]
+
+ * plugins/sudoers/Makefile.in, src/Makefile.in:
+ Got back to using "install-sh -M" for files installed as non-
+ readable by owner. This fixes "make install" as non-root for package
+ building.
+ [967804ee77d6]
+
+2012-02-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po,
+ plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po:
+ Sync with translationproject.org
+ [0e53db12039a]
+
+ * Makefile.in, doc/Makefile.in, include/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sample_group/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in:
+ Use -m not -M for install-sh for everything except setuid. Install
+ locale .mo files mode 0444, not 0644. If timedir parent doesn't
+ exist, use default dir mode, not 0700.
+ [8b6f64c92090]
+
+2012-02-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pp:
+ Re-sync with upstream; no longer need a local patch.
+ [97a2c7be5e59]
+
+ * mkpkg:
+ Add support for building Mac OS X packages.
+ [94d49ac223a4]
+
+ * pp:
+ Sync with upstream
+ [1c97654fc841]
+
+ * src/Makefile.in:
+ No longer need to define _PATH_SUDO_CONF here.
+ [2560905b7482]
+
+ * src/exec_common.c:
+ Fix noexec for Mac OS X.
+ [b7a744bca2c0]
+
+2012-02-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/Makefile.in:
+ Move _PATH_SUDO_CONF override to common to match sudo_debug.c
+ [f0788972a63a]
+
+ * plugins/sudoers/set_perms.c:
+ More complete fix for LDR_PRELOAD on AIX. The addition of
+ set_perm(PERM_ROOT) before calling the nss open functions (needed to
+ avoid a GNU TLS bug) also broke LDR_PRELOAD. Setting the effective
+ and then real uid to 0 for PERM_ROOT works around the issue.
+ [5888eda051af]
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ regen
+ [997fe403e219]
+
+ * src/sudo.c:
+ Set real uid to root before calling sudo_edit() or run_command() so
+ that the monitor process is owned by root and not by the user.
+ Otherwise, on AIX at least, the monitor process shows up in ps as
+ belonging to the user (and can be killed by the user).
+ [d4772d7d2fc5]
+
+ * plugins/sudoers/set_perms.c:
+ For PERM_ROOT when using setreuid(), only set the euid to 0 prior to
+ the call to setuid(0) if the current euid is non-zero. This
+ effectively restores the state of things prior to rev 7bfeb629fccb.
+ Fixes a problem on AIX where LDR_PRELOAD was not being honored for
+ the command being executed.
+ [b9b40325b4dc]
+
+ * MANIFEST, compat/pw_dup.c, config.h.in, configure, configure.in,
+ include/missing.h, src/sudo.c:
+ Make a copy of the struct passwd in exec_setup() to make sure
+ nothing in the policy init modifies it.
+ [b721261c921f]
+
+2012-02-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.pod:
+ update copyright
+ [f9d229d1f65e]
+
+ * common/sudo_debug.c, include/sudo_debug.h:
+ g/c now-unused debug subsystems
+ [8f21726e698f]
+
+ * doc/sudo.pod, doc/sudoers.pod:
+ Enumerate the debug subsystems used by sudo and sudoers.
+ [ac4f84293d14]
+
+2012-02-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, common/sudo_conf.c, doc/sample.sudo.conf, doc/sudo.pod,
+ include/sudo_conf.h, src/sudo.c:
+ Normally, sudo disables core dumps while it is running. This
+ behavior can now be modified at run time with a line in sudo.conf
+ like "Set disable_coredumps false"
+ [ad14e0508b0d]
+
+ * NEWS:
+ Mention Spanish translation
+ [600f3205bd6e]
+
+ * common/sudo_debug.c:
+ Make sure we don't try to fall back to using the conversation
+ function for debugging in the main sudo process if we are unable to
+ open the debug file.
+ [ffa329aa908c]
+
+ * MANIFEST, src/po/es.mo, src/po/es.po:
+ Add sudo Spanish translation from translationproject.org
+ [c1906654e740]
+
+2012-02-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Better debug subsystem usage
+ [1a31f115743c]
+
+ * src/sudo.c:
+ Remove duplicate function prototypes
+ [ae04b00532eb]
+
+2012-02-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Error out if user specified --with-pam but we can't find the headers
+ or library. Also throw an error if the headers are present but the
+ library is not and vice versa.
+ [d6bf3e3d0aae]
+
+2012-01-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Fix the sudoers permission check when the expected sudoers mode is
+ owner-writable.
+ [8b0b7e770a22]
+
+2012-01-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Verify that we can link executables built with -D_FORTIFY_SOURCE
+ before using it.
+ [7578215d1a95]
+
+ * src/exec_common.c:
+ Fix potential off-by-one when making a copy of the environment for
+ LD_PRELOAD insertion. Fixes bug #534
+ [cc699cd551b6]
+
+ * configure, configure.in:
+ Add rudimentary check for _FORTIFY_SOURCE support by checking for
+ __sprintf_chk, one of the functions used by gcc to support it.
+ [a992673d2ef8]
+
+ * compat/stdbool.h, config.h.in, configure, configure.in:
+ Use AC_HEADER_STDBOOL instead of checking for stdbool.h ourselves.
+ [8ba1370884b3]
+
+2012-01-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ regen
+ [1e0b38397705]
+
+2012-01-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c, src/sudo.c:
+ The change in 818e82ecbbfc that caused to exit when the monitor dies
+ created a race condition between the monitor exiting and the status
+ being read. All we really want to do is make sure that select()
+ notifies us that there is a status change when the monitor dies
+ unexpectedly so shutdown the socketpair connected to the monitor for
+ writing when it dies. That way we can still read the status that is
+ pending on the socket and select() on Linux will tell us that the fd
+ is ready.
+ [7fb5b30ea48d]
+
+ * MANIFEST, src/Makefile.in, src/exec.c, src/exec_common.c,
+ src/exec_pty.c, src/selinux.c, src/sesh.c, src/sudo.c, src/sudo.h,
+ src/sudo_exec.h:
+ Refactor disable_execute() and my_execve() into exec_common.c for
+ use by sesh.c. This fixes NOEXEC when SELinux is used. Instead of
+ disabling exec in exec_setup(), disable it immediately before
+ executing the command. Adapted from a diff by Arno Schuring.
+ [ec4d8b53db6b]
+
+2012-01-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4, configure, configure.in:
+ Add custom version of AC_CHECK_LIB that uses the extra libs in the
+ cache value name. With this we no longer need to rely on a modified
+ version of autoconf.
+ [1c3b1d482d6c]
+
+2012-01-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Better handling of network functions that need -lsocket -lnsl
+ [cc386342ec2b]
+
+ * src/sudo.c:
+ When setting up the execution environment, set groups before
+ gid/egid like sudo 1.7 did.
+ [928e1c5fa6c1]
+
+ * configure, configure.in:
+ Remove "WARNING: unable to find foo() trying -lsocket -lnsl"
+ [84b23cdf138f]
+
+ * plugins/sudoers/sudoers.c:
+ For "sudo -g" prepend the specified group ID to the beginning of the
+ groups list. This matches BSD convention where the effective gid is
+ the first entry in the group list. This is required on newer FreeBSD
+ where the effective gid is not tracked separately and thus
+ setgroups() changes the egid if this convention is not followed.
+ Fixes bug #532
+ [782d6909108b]
+
+2012-01-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Fix sh warning; use "test" instead of "["
+ [c6ee3407f65e]
+
+ * src/exec.c:
+ When not logging I/O, use a signal handler that only forwards
+ SIGINT, SIGQUIT and SIGHUP when they are user-generated signals.
+ Fixes a race in the non-I/O logging path where the command may
+ receive two keyboard-generated signals; one from the kernel and one
+ from the sudo process.
+ [9638684e786a]
+
+ * src/exec.c:
+ Back out change that put the command in its own pgrp when not
+ logging I/O. It causes problems with pipelines.
+ [4fc9c6e1e770]
+
+2012-01-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/Makefile.in, configure, configure.in:
+ Only run compat regress tests on compat objects we actually build.
+ Fixes "make check" in the compat dir for systems that don't
+ implement character classes in fnmatch() or glob(). Bug #531
+ [a7addc305e83]
+
+2012-01-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po:
+ Update po files from translationproject.org
+ [5ea066af1356]
+
+2012-01-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Include parent directories in case they don't already exist. This
+ fixes a directory permissions problem with the AIX package when the
+ /usr/local directories don't already exist.
+ [a14f783dc827]
+
+ * pp:
+ sync with git version
+ [2f79d0543661]
+
+ * common/Makefile.in, plugins/sudoers/Makefile.in, src/Makefile.in:
+ regen dependencies
+ [24c92ca6c64d]
+
+ * MANIFEST, src/Makefile.in, src/sudo.c, src/sudo.h, src/ttyname.c:
+ Move tty name lookup code to its own file.
+ [58faf072cbf4]
+
+2012-01-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Update with latest sudo 1.8.4 changes.
+ [a4ffe4f42528]
+
+ * config.h.in, configure, configure.in:
+ Remove obsolete template for HAVE_TIMESPEC
+ [75709007c906]
+
+ * src/sudo.c:
+ Add a check for devname() returning a fully-qualified pathname. None
+ of the devname() implementations do this today but you never know
+ when this might change.
+ [16813ace38f9]
+
+2012-01-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo.c:
+ For "visudo -c" also list include files that were checked when
+ everything is OK.
+ [ad6f85b35c9c]
+
+ * src/sudo.c:
+ The device name returned by devname() does not include the /dev/
+ prefix so we need to add it ourselves.
+ [b55285abb7ed]
+
+ * src/sudo.c:
+ Add debug warning if KERN_PROC sysctl fails or devname() can't
+ resolve the tty device to a name.
+ [b5a23916ba3a]
+
+ * common/sudo_debug.c:
+ The result of writev() is never checked so just cast to NULL.
+ [4be4e9b58d5b]
+
+ * plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po:
+ Update Esperanto, Finnish, Polish and Ukrainian translations from
+ translationproject.org.
+ [bb91bc6ad7e9]
+
+2012-01-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, src/sudo.c:
+ Add support for determining tty via sysctl on other BSD variants.
+ [fd15f63f719a]
+
+ * configure, configure.in:
+ Only check for struct kinfo_proc.ki_tdev on systems that support
+ sysctl.
+ [109b3f07a39d]
+
+ * src/sudo.c:
+ For FreeBSD, try the KERN_PROC_PID sysctl() first, falling back on
+ ttyname() of std{in,out,err}.
+ [95969b70bd68]
+
+2012-01-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, src/sudo.c:
+ On newer FreeBSD we can get the parent's tty name via sysctl().
+ [3207290501ee]
+
+ * plugins/sudoers/testsudoers.c:
+ Include locale.h
+ [a602cd0b8c2d]
+
+ * src/sudo.c:
+ Silence a gcc warning.
+ [8c6d0e3cd534]
+
+ * plugins/sudoers/bsm_audit.c:
+ Need to include gettext.h and sudo_debug.h; from John Hein
+ [447912aa7300]
+
+ * plugins/sudoers/iolog.c:
+ Initialize the debug framework from the I/O plugin too.
+ [ce1bf44d96d2]
+
+2012-01-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/testsudoers.c:
+ Enable debugging via sudo.conf.
+ [d85669c749d0]
+
+2012-01-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo.c:
+ Use SUDO_DEBUG_ALIAS for alias checking functions.
+ [fb84af30dc76]
+
+ * configure, configure.in:
+ More complete test for getaddrinfo() that doesn't rely on the
+ network libraries already being added to LIBS.
+ [cbaf2369f4f0]
+
+2012-01-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/aix.c:
+ Add debug support.
+ [def1bdf24485]
+
+ * configure, configure.in:
+ Need -lsocket -lnsl for getaddrinfo(3) on Solaris at least.
+ [a2ea1c2eac61]
+
+ * compat/getaddrinfo.c:
+ Include errno.h and missing.h
+ [7d15e17cc2f2]
+
+ * .hgignore:
+ ignore doc/varsub
+ [417f9fc3231b]
+
+ * configure.in, doc/visudo.pod, plugins/sudoers/Makefile.in,
+ plugins/sudoers/gram.y, plugins/sudoers/match.c,
+ plugins/sudoers/parse.c, plugins/sudoers/testsudoers.c, src/exec.c,
+ src/parse_args.c, src/sudo.c, src/sudo.h:
+ Update copyright year.
+ [5d0ffc7dd567]
+
+ * NEWS:
+ Update for sudo 1.8.4
+ [841e3eff9844]
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ regen pot files
+ [c509cb45b66a]
+
+ * plugins/sudoers/sudoreplay.c:
+ Enable debugging via sudo.conf.
+ [5087aaee8484]
+
+ * plugins/sudoers/visudo.c:
+ Enable debugging via sudo.conf.
+ [04b067c16ed3]
+
+ * plugins/sudoers/visudo.c:
+ Allow "visudo -c" to work when we only have read-only access to the
+ sudoers include files.
+ [d8c6713fe5c1]
+
+ * doc/sudo.pod, doc/visudo.pod:
+ Mention the CONTRIBUTORS file, not HISTORY in AUTHOR section. Add
+ HISTORY section in sudo that points to HISTORY file.
+ [d1f1bcb051c5]
+
+ * doc/sudo.pod, doc/sudo_plugin.pod:
+ Document Debug setting in sudo.conf and debug_flags in plugin.
+ [acfc505aa4a9]
+
+2012-01-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/match.c:
+ Do not include GLOB_MARK in the flags we pass to glob(3). Fixes a
+ bug where a pattern like "/usr/*" include /usr/bin/ in the results,
+ which would be incorrectly be interpreted as if the sudoers file had
+ specified a directory. From Vitezslav Cizek.
+ [0cdb6252188c]
+
+ * INSTALL, config.h.in, configure, configure.in,
+ plugins/sudoers/auth/kerb5.c:
+ Add --enable-kerb5-instance configure option to allow people using
+ Kerberos V authentication to use a custom instance. Adapted from a
+ diff by Michael E Burr.
+ [e83af8bb7aa7]
+
+ * doc/sudo.pod, src/parse_args.c, src/sudo.c, src/sudo.h:
+ Remove -D debug_level option.
+ [cbcd05094347]
+
+ * doc/LICENSE:
+ Update copyright year.
+ [9f43dd7aa852]
+
+2012-01-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/parse.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c:
+ parse_error is now bool, not int
+ [5ea7fb6fda38]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/parse.c:
+ Print a more sensible error if yyparse() returns non-zero but
+ yyerror() was not called.
+ [d44ec88f1183]
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/getdate.c,
+ plugins/sudoers/gram.c:
+ Replace y.tab.c with the correct filename in #line directives.
+ [3c84fcb7e959]
+
+2012-01-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo.c:
+ When trying to determine the tty, fall back on /proc/ppid/fd/{0,1,2}
+ if the main process's fds 0-2 are not hooked up to a tty. Adapted
+ from a diff by Zdenek Behan.
+ [b9dfce12af85]
+
+ * src/exec.c:
+ When not logging I/O, put command in its own pgrp and make that the
+ controlling pgrp if the command is in the foreground. Fixes a race
+ in the non-I/O logging path where the command may receive two
+ keyboard-generated signals; one from the kernel and one from the
+ sudo process.
+ [d0e263ce496c]
+
+2011-12-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo_edit.c:
+ Quiet a bogus gcc warning.
+ [2009669e0608]
+
+ * src/parse_args.c, src/sudo.h:
+ Fix warnings related to sudo.conf accessors.
+ [08ddc29ba50b]
+
+ * common/sudo_conf.c, include/sudo_conf.h:
+ Separate sudo.conf parsing from plugin loading and move the parse
+ functions into the common lib so that visudo, etc. can use them.
+ [f1fc659a8079]
+
+ * MANIFEST, common/Makefile.in, src/Makefile.in, src/load_plugins.c,
+ src/parse_args.c, src/sudo.c, src/sudo_plugin_int.h:
+ Separate sudo.conf parsing from plugin loading and move the parse
+ functions into the common lib so that visudo, etc. can use them.
+ [e1f2cf6bd57a]
+
+ * doc/sudoers.pod, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in,
+ plugins/sudoers/sudoers.c, src/sudo.c:
+ Remove support for noexec_file in sudoers and the plugin API
+ [3e2fd58879b5]
+
+ * plugins/sudoers/sudoers.c:
+ Don't dump interfaces if there are none.
+ [9081bb4d3e9e]
+
+ * plugins/sudoers/def_data.c, plugins/sudoers/def_data.in:
+ Add missing %s printf escape to the group_plugin, iolog_dir and
+ iolog_file descriptions.
+ [7db03f2b737e]
+
+2011-12-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/def_data.c, plugins/sudoers/def_data.in, src/exec.c:
+ Fix typo in visiblepw description; from Joel Pickett
+ [2fb4b26d5c2c]
+
+2011-12-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, configure, configure.in, mkdep.pl,
+ plugins/sudoers/Makefile.in, plugins/sudoers/env.c,
+ plugins/sudoers/login_class.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, src/sudo.c:
+ When running a login shell with a login_class specified, use
+ LOGIN_SETENV instead of rolling our own login.conf setenv support
+ since FreeBSD's login.conf has more than just setenv capabilities.
+ This requires us to swap the plugin-provided envp for the global
+ environ before calling setusercontext() and then stash the resulting
+ environ pointer back into the command details, which is kind of a
+ hack.
+ [ad4f1190143b]
+
+ * plugins/sudoers/Makefile.in:
+ If srcdir is "." just use the basename of the yacc/lex file when
+ generating the C version. This matches the generated files currently
+ in the repo.
+ [0b11c3df87a8]
+
+ * doc/Makefile.in, plugins/sudoers/Makefile.in:
+ Clean up the DEVEL noise
+ [9de2afe457fd]
+
+ * src/exec.c:
+ Handle different Unix domain socket (actually socketpair) semantics
+ in BSD vs. Linux. In BSD if one end of the socketpair goes away
+ select() returns the fd as readable and the read will fail with
+ ECONNRESET. This doesn't appear to happen on Linux so if we notice
+ that the monitor process has died when I/O logging is enabled,
+ behave like the command has exited. This means we log the wait
+ status of the monitor, not the command, but there is nothing else we
+ can do at that point. This should only be an issue if SIGKILL is
+ sent to the monitor process.
+ [818e82ecbbfc]
+
+ * src/exec_pty.c:
+ Catch common signals in the monitor process so they get passed to
+ the command. Fixes a problem when the entire login session is killed
+ when ssh is disconnected or the terminal window is closed.
+ Previously, the monitor would exit and plugin's close method would
+ not be called.
+ [0e4658263138]
+
+ * INSTALL, configure, configure.in:
+ Mention how to configure pam_hpsec on HP-UX to play nicely with
+ sudo.
+ [a7294cd8ce98]
+
+2011-12-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Escape values in the search expression as per RFC 4515.
+ [c2adbc5db92b]
+
+ * doc/Makefile.in, include/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ src/Makefile.in:
+ No need for install target to depend explicitly on install-dirs, the
+ install-foo targets all depend on it.
+ [62a36ed98279]
+
+2011-12-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * .hgignore:
+ ignore src/sesh
+ [463d492f6782]
+
+ * MANIFEST, common/Makefile.in, configure, configure.in, mkdep.pl,
+ plugins/sample/Makefile.in, plugins/sample_group/Makefile.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/env.c,
+ plugins/sudoers/login_class.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, src/Makefile.in:
+ Add support for setenv entries in login.conf. We can't use
+ LOGIN_SETENV since the plugin sets up the envp the command is
+ executed with. Also regen the Makefile.in files while here. Fixes
+ bug #527
+ [088d507926e2]
+
+2011-12-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, aclocal.m4, compat/getaddrinfo.c, compat/getaddrinfo.h,
+ config.h.in, configure, configure.in, plugins/sudoers/sudoers.c,
+ src/net_ifs.c:
+ Add getaddrinfo() for those without it, written by Russ Allbery
+ [4cf9ac831222]
+
+ * doc/Makefile.in:
+ Restore PACKAGE_TARNAME, it is used in docdir
+ [9d65e893edb1]
+
+ * MANIFEST, compat/stdbool.h:
+ SunPro C Compiler also has a _Bool builtin. Also add stdbool.h to
+ the MANIFEST
+ [e67700dc5621]
+
+ * common/atobool.c, common/term.c, src/exec.c:
+ Remove duplicate return statements.
+ [48a20d5215fd]
+
+ * plugins/sudoers/auth/bsdauth.c:
+ Remove inaccurate comment
+ [e7f0265cf657]
+
+ * plugins/sudoers/auth/bsdauth.c, plugins/sudoers/sudoers.c:
+ Fetch the login class for the user we authenticate specifically when
+ using BSD authentication. That user may have a different login class
+ than what we will use to run the command. When setting the login
+ class for the command, use the target user's struct passwd, not the
+ invoking user's. Fixes bug 526
+ [21bf0af892f7]
+
+ * compat/Makefile.in, configure, configure.in, doc/Makefile.in,
+ plugins/sudoers/Makefile.in:
+ Replace @DEV@ prefix with DEVEL variable so we can do "make DEVEL=1"
+ [8ee6e0891f27]
+
+ * plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/regress/parser/check_fill.c:
+ Fix "make check" fallout from the sudo_conv changes in sudo_debug.
+ [b0aaa63c9081]
+
+ * common/fileops.c, common/sudo_debug.c, configure, configure.in,
+ include/fileops.h, plugins/sample/Makefile.in,
+ plugins/sample/sample_plugin.c, plugins/sample_group/Makefile.in,
+ plugins/sample_group/sample_group.c, plugins/sudoers/alias.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/check.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/defaults.h,
+ plugins/sudoers/env.c, plugins/sudoers/find_path.c,
+ plugins/sudoers/goodpath.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/match.c,
+ plugins/sudoers/match_addr.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/pwutil.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.h,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c,
+ plugins/sudoers/visudo.c, src/exec.c, src/exec_pty.c,
+ src/load_plugins.c, src/sudo.c, src/sudo.h, src/sudo_exec.h,
+ src/sudo_plugin_int.h, src/utmp.c:
+ Use stdbool.h instead of rolling our own TRUE/FALSE macros.
+ [dcb0bbc42fc9]
+
+2011-12-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/stdbool.h, config.h.in, configure, configure.in:
+ Add stdbool.h for systems without it.
+ [18bd9dda1dcd]
+
+ * aclocal.m4, config.h.in, configure, configure.in:
+ No longer need SUDO_CHECK_TYPE and SUDO_TYPE_* now that the default
+ includes have unistd.h in them. Add check for socklen_t for upcoming
+ getaddrinfo compat.
+ [d705465bef69]
+
+ * common/fileops.c, compat/nanosleep.c, config.h.in, configure,
+ configure.in, plugins/sudoers/interfaces.c,
+ plugins/sudoers/interfaces.h, plugins/sudoers/match_addr.c,
+ plugins/sudoers/sudoreplay.c, src/net_ifs.c:
+ Use HAVE_STRUCT_TIMESPEC and HAVE_STRUCT_IN6_ADDR instead of
+ HAVE_TIMESPEC and HAVE_IN6_ADDR respectively.
+ [fa187c9bd2be]
+
+ * src/sudo_noexec.c:
+ No longer need to include time.h here as missing.h does not use
+ time_t.
+ [fa3a089bf5b1]
+
+2011-11-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo.c:
+ Fix mode on sudoers as needed when the -f option is not specified.
+ [7a1c40b0dc03]
+
+ * MANIFEST, src/po/sr.mo, src/po/sr.po:
+ Add Serbian translation for sudo from translationproject.org
+ [9a0c25e25cba]
+
+ * common/sudo_debug.c, plugins/sudoers/sudoers.c, src/load_plugins.c,
+ src/parse_args.c:
+ No longer pass debug_file to plugin, plugins must now use
+ CONV_DEBUG_MSG
+ [810cda1abb0b]
+
+ * mkpkg:
+ Build PIE executables for newer Debian and Ubuntu
+ [1c5f25f8904a]
+
+ * common/sudo_debug.c:
+ Include time.h for ctime() prototype.
+ [10090cf3bca1]
+
+2011-11-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/sudo_debug.c, include/sudo_debug.h, src/exec.c,
+ src/exec_pty.c:
+ Do not close error pipe or debug fd via closefrom() as we need them
+ to report an exec error should one occur.
+ [732f6587fafa]
+
+ * doc/sudoers.ldap.pod:
+ Document that a sudoUser may now be a group ID.
+ [2fef46b9d3d3]
+
+ * plugins/sudoers/ldap.c:
+ Add support for permitting access by group ID in addition to group
+ name.
+ [b9450fdf1f69]
+
+ * plugins/sudoers/ldap.c:
+ Older Netscape LDAP SDKs don't prototype ldapssl_set_strength()
+ [d62a1e7cff4f]
+
+ * compat/fnmatch.c, compat/fnmatch.h, doc/LICENSE:
+ Replace UCB fnmatch.c with a non-recursive version written by
+ William A. Rowe Jr.
+ [354d3384adb8]
+
+ * plugins/sudoers/auth/pam.c:
+ Fix typo, return_debug vs. debug_return
+ [1b522efcbb0d]
+
+2011-11-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po:
+ Update Japanese sudoers translation from translationproject.org
+ [ec0f2beaad36]
+
+ * doc/sudoers.pod:
+ Make the env_reset descriptions consistent.
+ [41c056f02688]
+
+2011-11-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Do multiple expansion when expanding paths to the noexec file, sesh
+ and the plugin directory. Adapted from a diff by Mike Frysinger
+ [d7e16c876c66]
+
+ * common/Makefile.in:
+ regen
+ [9d729e09c186]
+
+2011-11-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * .hgignore:
+ Add ignore file; from Mike Frysinger
+ [1fa8d52425f8]
+
+ * mkdep.pl:
+ no longer save old Makefile.in to .old
+ [378dd2395545]
+
+ * plugins/sudoers/Makefile.in, src/Makefile.in:
+ regen
+ [769faf517720]
+
+ * config.guess, config.sub, configure, ltmain.sh, m4/libtool.m4,
+ m4/ltoptions.m4, m4/ltversion.m4:
+ Update to libtool 2.4.2
+ [9dac78d84b4f]
+
+2011-11-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers_version.h:
+ Bump grammar version for #include and #includedir relative path
+ support.
+ [82a4f7cd8f71]
+
+2011-11-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.pod, plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Add support for relative paths in #include and #includedir
+ [4d6e3bd0c24f]
+
+ * plugins/sudoers/Makefile.in:
+ Fix install-plugin when shared objects are unsupported or disabled.
+ [cbdd770a7a1b]
+
+ * plugins/sudoers/goodpath.c:
+ Don't write to sbp if it is NULL
+ [fc438f8e8570]
+
+2011-11-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Remove all sudo/sudoers .mo files on uninstall If LINGUAS is set,
+ only install matching .mo files
+ [c1dc30ab4ebc]
+
+2011-11-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/group_plugin.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/sudoers.c, src/conversation.c:
+ Fix non-dynamic (no dlopen) sudo build.
+ [b0bd3fa925a3]
+
+ * configure, configure.in:
+ Don't error out if the user specified --disable-shared
+ [cf035dd1e5cc]
+
+ * common/sudo_debug.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c,
+ src/conversation.c:
+ Use SUDO_CONV_DEBUG_MSG in the plugin instead of writing directly to
+ the debug file.
+ [640c62f83251]
+
+ * plugins/sudoers/find_path.c, plugins/sudoers/goodpath.c,
+ plugins/sudoers/sudoers.h:
+ Make sudo_goodpath() return value bolean
+ [fea2d59a6e55]
+
+ * INSTALL, MANIFEST, configure, configure.in, mkdep.pl,
+ plugins/sudoers/Makefile.in, plugins/sudoers/auth/securid.c:
+ Remove obsolete securid auth method.
+ [4e54f860214b]
+
+ * plugins/sudoers/auth/afs.c, plugins/sudoers/auth/aix_auth.c,
+ plugins/sudoers/auth/dce.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/auth/sudo_auth.h:
+ Prefix authentication functions with a "sudo_" prefix to avoid
+ namespace problems.
+ [581d74063ea1]
+
+ * INSTALL, MANIFEST, config.h.in, configure, configure.in,
+ doc/TROUBLESHOOTING, mkdep.pl, plugins/sudoers/Makefile.in,
+ plugins/sudoers/auth/kerb4.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/auth/sudo_auth.h, plugins/sudoers/env.c:
+ Remove the old Kerberos IV support
+ [2e4b4a44209d]
+
+2011-11-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c:
+ Don't print garbage at the end of the custom lecture.
+ [44bb788fafaa]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Add lexer tracing as debug@parser
+ [d850f3f9d414]
+
+ * plugins/sudoers/alias.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/defaults.h, plugins/sudoers/gram.c,
+ plugins/sudoers/match.c, plugins/sudoers/parse.c,
+ plugins/sudoers/regress/parser/check_fill.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c,
+ plugins/sudoers/visudo.c:
+ Revert 003bdb078a15. We need to #include <gram.h> not "gram.h" and
+ <def_data.h> and not "def_data.h" when generating the parser in a
+ build dir.
+ [7da701def753]
+
+2011-11-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkdep.pl, plugins/sudoers/Makefile.in:
+ Better devdir support in mkdep.pl
+ [7dcec57bd155]
+
+ * plugins/sudoers/Makefile.in:
+ Add devdir before srcdir in include path and fix up dependecies
+ accordingly.
+ [6e9958eca485]
+
+ * plugins/sudoers/alias.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/defaults.h, plugins/sudoers/match.c,
+ plugins/sudoers/parse.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, plugins/sudoers/visudo.c:
+ #include "gram.h" not <gram.h> and "def_data.h" and not
+ <def_data.h>.
+ [003bdb078a15]
+
+ * sudo.pp:
+ Mark libexec files as optional. If we build without shared object
+ support, libexec is not used.
+ [4bffcf482219]
+
+ * src/load_plugins.c:
+ Change Debug sudo.conf setting to take a program name as the first
+ argument. In the future, this will allow visudo and sudoreplay to
+ use their own Debug entries.
+ [cfb8f7e4867c]
+
+ * src/sudo.c:
+ fix sudo_debug_printf priority
+ [dcb67e965609]
+
+ * plugins/sudoers/sudoers.c:
+ add missing debug_return_int
+ [d88ec450c592]
+
+2011-11-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/sudo_debug.c, include/error.h, include/sudo_debug.h,
+ plugins/sudoers/logging.c, src/exec.c, src/exec_pty.c:
+ Fold SUDO_DEBUG_PROGERR and SUDO_DEBUG_SYSERR into SUDO_DEBUG_ERROR
+ [dcee8efc294f]
+
+ * doc/UPGRADE:
+ Add missing word in HOME security note.
+ [fd844fdcc1ac]
+
+ * plugins/sudoers/testsudoers.c:
+ Prevent "testsudoers -d username" from trying to malloc(0).
+ [839126e56e8c]
+
+2011-11-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/sudoers/test10.in,
+ plugins/sudoers/regress/sudoers/test10.out.ok,
+ plugins/sudoers/regress/sudoers/test10.toke.ok,
+ plugins/sudoers/regress/sudoers/test10.toke.out.ok,
+ plugins/sudoers/regress/sudoers/test11.in,
+ plugins/sudoers/regress/sudoers/test11.out.ok,
+ plugins/sudoers/regress/sudoers/test11.toke.ok,
+ plugins/sudoers/regress/sudoers/test11.toke.out.ok,
+ plugins/sudoers/regress/sudoers/test12.in,
+ plugins/sudoers/regress/sudoers/test12.out.ok,
+ plugins/sudoers/regress/sudoers/test12.toke.ok,
+ plugins/sudoers/regress/sudoers/test13.in,
+ plugins/sudoers/regress/sudoers/test13.out.ok,
+ plugins/sudoers/regress/sudoers/test13.toke.ok,
+ plugins/sudoers/regress/sudoers/test9.in,
+ plugins/sudoers/regress/sudoers/test9.out.ok,
+ plugins/sudoers/regress/sudoers/test9.toke.ok,
+ plugins/sudoers/regress/sudoers/test9.toke.out.ok:
+ Tests for empty sudoers (should parse OK) and syntax errors within a
+ line (should report correct line number) both with and without the
+ trailing newline.
+ [d57c879c4718]
+
+ * plugins/sudoers/regress/sudoers/test4.out.ok,
+ plugins/sudoers/regress/sudoers/test5.out.ok,
+ plugins/sudoers/regress/sudoers/test7.out.ok,
+ plugins/sudoers/regress/sudoers/test8.out.ok,
+ plugins/sudoers/testsudoers.c:
+ Print line number when there is a parser error.
+ [5444ef6ac6dc]
+
+2011-11-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Keep track of the last token returned. On error, if the last token
+ was COMMENT, decrement sudolineno since the error most likely
+ occurred on the preceding line. Previously we always uses
+ sudolineno-1 which will give the wrong line number for errors within
+ a line.
+ [d661a03a64da]
+
+2011-11-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ update with sudo 1.8.3p1 info
+ [0f79ff31f602]
+
+ * plugins/sudoers/sudoers.c:
+ Fix crash when "sudo -g group -i" is run. Fixes bug 521
+ [a3087ae337c4]
+
+2011-10-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo.c:
+ Make alias_remove_recursive() return TRUE/FALSE as its callers
+ expect and remove two unused arguments. Fixes bug 519.
+ [2ee3b2882844]
+
+ * plugins/sudoers/regress/visudo/test1.out.ok,
+ plugins/sudoers/regress/visudo/test1.sh:
+ Add regress test for bugzilla 519
+ [48000ebedf97]
+
+ * plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/regress/parser/check_fill.c:
+ Disable warning/error wrapping in regress tests.
+ [373c589ba561]
+
+2011-10-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Do compile-po as part of sync-po so that the .mo files get rebuild
+ automatically when we sync with translationproject.org
+ [83f3cbfc2f33]
+
+ * plugins/sudoers/Makefile.in:
+ check_addr needs to link with the network libraries on Solaris
+ [322bd70e316e]
+
+ * plugins/sudoers/match.c:
+ When matching a RunasAlias for a runas group, pass the alias in as
+ the group_list, not the user_list. From Daniel Kopecek.
+ [766545edf141]
+
+ * plugins/sudoers/check.c, plugins/sudoers/sudoers.c:
+ We need to init the auth system regardless of whether we need a
+ password since we will be closing the PAM session in the monitor
+ process. Fixes a crash in the monitor on Solaris; bugzilla #518
+ [e82809f86fb3]
+
+2011-10-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ Get rid of done: label. If the child exits we still need to close
+ the pty, update utmp and restore the SELinux tty context.
+ [cc127bf48405]
+
+2011-10-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/Makefile.in, common/atobool.c, common/fileops.c,
+ common/fmt_string.c, common/lbuf.c, common/list.c,
+ common/setgroups.c, common/term.c, plugins/sudoers/Makefile.in,
+ plugins/sudoers/alias.c, plugins/sudoers/audit.c,
+ plugins/sudoers/auth/afs.c, plugins/sudoers/auth/aix_auth.c,
+ plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/dce.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/kerb4.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/securid.c,
+ plugins/sudoers/auth/securid5.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/boottime.c,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/check.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/env.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/getspwuid.c,
+ plugins/sudoers/goodpath.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/interfaces.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/iolog_path.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/logging.c,
+ plugins/sudoers/logwrap.c, plugins/sudoers/match.c,
+ plugins/sudoers/match_addr.c, plugins/sudoers/parse.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/redblack.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.h,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c,
+ src/Makefile.in, src/conversation.c, src/exec.c, src/exec_pty.c,
+ src/get_pty.c, src/load_plugins.c, src/net_ifs.c, src/parse_args.c,
+ src/selinux.c, src/sudo.c, src/sudo.h, src/sudo_edit.c,
+ src/tgetpass.c, src/ttysize.c, src/utmp.c:
+ Add debug_decl/debug_return (almost) everywhere. Remove old
+ sudo_debug() and convert users to sudo_debug_printf().
+ [8f3bbf907b67]
+
+ * common/alloc.c, include/error.h, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c, src/error.c:
+ Wrap error/errorx and warning/warningx functions with debug
+ statements. Disable wrapping for standalone sudoers programs as well
+ as memory allocation functions (to avoid infinite recursion).
+ [562ed7b5ae8d]
+
+ * README, config.h.in, configure, configure.in:
+ Add checks for __func__ and __FUNCTION__ and mention that we now
+ require a cpp that supports variadic macros.
+ [314cfe4c5d23]
+
+ * MANIFEST, common/Makefile.in, common/sudo_debug.c,
+ include/sudo_debug.h, include/sudo_plugin.h, src/conversation.c,
+ src/load_plugins.c, src/parse_args.c, src/sudo.c,
+ src/sudo_plugin_int.h:
+ New debug framework for sudo and plugins using /etc/sudo.conf that
+ also supports function call tracing.
+ [cded741e9f10]
+
+2011-10-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po:
+ Update Japanese sudoers translation from translationproject.org
+ [c24725775e32]
+
+2011-10-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Override and ignore the --disable-static option. Sudo already runs
+ libtool with -tag=disable-static where applicable and we need non-
+ PIC objects to build the executables.
+ [aff1227b853a]
+
+2011-10-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Add sudoedit fix
+ [74655c7ccad1]
+
+ * plugins/sudoers/po/sudoers.pot:
+ regen pot files
+ [28d89a831ed3]
+
+ * plugins/sudoers/env.c:
+ Ignore set_logname (which is now the default) for sudoedit since we
+ want the LOGNAME, USER and USERNAME environment variables to refer
+ to the calling user since that is who the editor runs as. This
+ allows the editor to find the user's startup files. Fixes bugzilla
+ #515
+ [6c5dddf5ff05]
+
+ * plugins/sudoers/pwutil.c:
+ Instead of trying to grow the buffer in make_grlist_item(), simply
+ increase the total length, free the old buffer and allocate a new
+ one. This is less error prone and saves us from having to adjust all
+ the pointers in the buffer. This code path is only taken when there
+ are groups longer than the length of the user field in struct utmp
+ or utmpx, which should be quite rare.
+ [5587dc8cffaf]
+
+ * src/po/it.mo:
+ Add Italian translation for sudo from translationproject.org
+ [1b3dd886e7e3]
+
+ * MANIFEST, NEWS, plugins/sudoers/po/ja.mo, plugins/sudoers/po/ja.po,
+ src/po/ja.mo, src/po/ja.po:
+ Japanese translation for sudo and sudoers from
+ translationproject.org
+ [c06dd866be6e]
+
+2011-10-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ sudoreplay depends on timestr.lo too; from Mike Frysinger
+ [b9e73214b2f1]
+
+2011-10-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot:
+ Regen sudoers pot file.
+ [019588bafdb3]
+
+ * NEWS:
+ Update with latest sudo 1.8.3 news
+ [6868042a88e9]
+
+ * plugins/sudoers/sudoers.c:
+ It appears that LDAP or NSS may modify the euid so we need to be
+ root for the open(). We restore the old perms at the end of
+ sudoers_policy_open().
+ [2da67a5497ef]
+
+ * plugins/sudoers/set_perms.c:
+ Better warning message on setuid() failure for the setreuid()
+ version of set_perms().
+ [07abcfe7bd9a]
+
+2011-09-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c:
+ Delref auth_pw at the end of check_user() instead of getting a ref
+ twice.
+ [cb665f55e6a5]
+
+ * plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/check.c:
+ Make sudo_auth_{init,cleanup} return TRUE on success and check for
+ sudo_auth_init() return value in check_user().
+ [92631c919356]
+
+ * plugins/sudoers/auth/sudo_auth.c:
+ Do not return without restoring permissions.
+ [59ef40b6696a]
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ regen pot files
+ [9f320a340b7c]
+
+ * plugins/sudoers/auth/API, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/kerb4.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/secureware.c,
+ plugins/sudoers/auth/securid.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/auth/sudo_auth.h,
+ plugins/sudoers/check.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Modify the authentication API such that the init and cleanup
+ functions are always called, regardless of whether or not we are
+ going to verify a password. This is needed for proper PAM session
+ support.
+ [19a53f3fb596]
+
+ * compat/Makefile.in, mkdep.pl, plugins/sudoers/Makefile.in:
+ Add missing dependency for getspwuid.lo and regen other depends.
+ [f7f70eae819a]
+
+ * plugins/sudoers/auth/pam.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/auth/sudo_auth.h, plugins/sudoers/sudoers.c:
+ Fix a PAM_USER mismatch in session open/close. We update PAM_USER to
+ the target user immediately before setting resource limits, which is
+ after the monitor process has forked (so it has the old value).
+ Also, if the user did not authenticate, there is no pamh in the
+ monitor so we need to init pam here too. This means we end up
+ calling pam_start() twice, which should be fixed, but at least the
+ session is always properly closed now.
+ [fbc063a2a872]
+
+ * src/utmp.c:
+ Add check for old being NULL in utmp_setid(); from Steven McDonald
+ [e87126442f2e]
+
+2011-09-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/pwutil.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ If the invoking user cannot be resolved by uid fake the struct
+ passwd and store it in the cache so we can delref it on exit.
+ [a27e2f8b9f5e]
+
+2011-09-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Don't error out if the group plugin cannot be loaded, just warn.
+ [0fbfcd381e33]
+
+2011-09-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Quiet a false positive found by several static analysis tools. These
+ tools don't know that log_error() does not return (it longjmps to
+ error_jmp which returns to the sudo front-end).
+ [33d0469df21b]
+
+2011-09-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/po/da.mo, plugins/sudoers/po/eo.mo,
+ plugins/sudoers/po/fi.mo, plugins/sudoers/po/pl.mo,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/zh_CN.mo, src/po/it.po:
+ Add Italian translation for sudo from translationproject.org Regen
+ .mo files
+ [c3c888a82be6]
+
+2011-09-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/TROUBLESHOOTING:
+ Update to current reality and add bit about ssh auth
+ [184a1e7c2eeb]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y:
+ Make "verbose" static; fixes a namespace clash with
+ pam_ssh_agent_auth (and it doesn't need to be extern these days).
+ [cc38d2eb2f4c]
+
+ * config.h.in, configure, configure.in, src/get_pty.c:
+ FreeBSD has libutil.h not util.h
+ [dab4c94b6d4f]
+
+ * configure, configure.in:
+ Define _BSD_SOURCE on FreeBSD, OpenBSD and DragonflyBSD
+ [41c362f0a92a]
+
+2011-09-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/da.po, plugins/sudoers/po/eo.po,
+ plugins/sudoers/po/fi.po, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/uk.po, plugins/sudoers/po/zh_CN.po:
+ Update po files from translationproject.org
+ [1e99e147c7fa]
+
+2011-09-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.ldap.pod, plugins/sudoers/ldap.c:
+ Add support for DEREF in ldap.conf.
+ [3c1937a98547]
+
+ * Makefile.in:
+ install target should depend on ChangeLog too, not just install-doc
+ [1a7c83941175]
+
+ * doc/sudoers.pod:
+ Only iolog_file (not iolog_dir) supports mktemp-style suffixes.
+ [0eca47d60a2c]
+
+ * NEWS:
+ Sync with 1.8 branch for sudo 1.8.2 and 1.8.3 changes.
+ [0501415cc5ff]
+
+ * doc/UPGRADE:
+ Document group lookup change and possible side effects.
+ [585743e1ebf7]
+
+ * configure, configure.in:
+ Fix some square brackets in case statements that needed to be
+ doubled up. While here, use $OSMAJOR when it makes sense.
+ [8973343f4696]
+
+ * plugins/sudoers/pwutil.c:
+ Fix a crash in make_grlist_item() on 64-bit machines with strict
+ alignment.
+ [c89508c73c46]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/defaults.h:
+ Remove list_options() function that is no longer used now that "sudo
+ -L" is gone.
+ [fcc6a776c135]
+
+ * configure, configure.in:
+ Error message if user tries --with-CC
+ [ec5b478f813a]
+
+ * configure, configure.in:
+ Check for -libmldap too when looking for ldap libs, which is the
+ Tivoli Directory Server client library.
+ [bb3007a97206]
+
+2011-09-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/parse.c:
+ Honor NOPASSWD tag for denied commands too.
+ [8dd92656db92]
+
+2011-09-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, configure, configure.in:
+ Remove --with-CC option; it doesn't work correctly now that we use
+ libtool. Users can get the same effect by setting the CC environment
+ variable when running configure.
+ [ec22bd1a55e0]
+
+2011-08-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, plugins/sudoers/visudo.c,
+ src/sudo_edit.c:
+ Assume all modern systems support fstat(2).
+ [6a5a8985f6a0]
+
+2011-08-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/regress/glob/globtest.c, config.h.in, configure,
+ configure.in, include/missing.h, plugins/sudoers/sudoers.h,
+ src/sudo.h, src/sudo_noexec.c:
+ Add configure test for missing errno declaration and only declare it
+ ourselves if it is missing.
+ [456e76c809a2]
+
+ * plugins/sudoers/alias.c:
+ Include errno.h before sudo.h to avoid conflicting with the system
+ definition of errno.
+ [d0b97e392512]
+
+2011-08-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/parser/check_addr.c:
+ Only print individual check status when there is a failure.
+ [2ac704c91441]
+
+ * plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/parser/check_addr.c:
+ Add calls to setprogname() for test programs.
+ [a8d9b420e826]
+
+ * configure, configure.in:
+ Add -Wall and -Werror after all tests so they don't cause failures.
+ [2661188ff3fa]
+
+ * plugins/sudoers/Makefile.in:
+ Actually run check_addr in the check target
+ [0b2778bc86bf]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/match.c,
+ plugins/sudoers/match_addr.c,
+ plugins/sudoers/regress/parser/check_addr.c,
+ plugins/sudoers/regress/parser/check_addr.in:
+ Split out address matching into its own file and add regression
+ tests for it.
+ [12b9a2bf8dba]
+
+2011-08-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/match.c:
+ When matching an address with a netmask in sudoers, AND the mask and
+ addr before checking against the local addresses.
+ [9747bb6d7b1c]
+
+2011-08-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/match.c:
+ Fix netmask matching.
+ [a3c8f8cc1464]
+
+ * plugins/sudoers/visudo.c:
+ Don't assume all editors support the +linenumber command line
+ argument, use a whitelist of known good editors.
+ [21d43a91fd10]
+
+2011-08-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/set_perms.c, plugins/sudoers/visudo.c, src/exec.c,
+ src/exec_pty.c, src/sudo.c:
+ Silence compiler warnings on Solaris with gcc 3.4.3
+ [da620bae6fdb]
+
+ * mkpkg:
+ Fix building on RHEL 3
+ [f3227fb2a252]
+
+ * INSTALL, configure, configure.in:
+ Add --enable-werror configure option.
+ [fec2cdb95543]
+
+ * common/setgroups.c:
+ setgroups() proto lives in grp.h on RHEL4, perhaps others.
+ [de91c0de5a98]
+
+ * configure, configure.in:
+ Use PAM by default on AIX 6 and higher.
+ [e16493208e5f]
+
+2011-08-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/po/eo.mo, plugins/sudoers/po/eo.po,
+ src/po/eo.mo, src/po/eo.po:
+ Add new Esperanto translation from translationproject.org
+ [0d9a59e04c64]
+
+2011-08-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog_path.c:
+ Quiet an innocuous valgrind warning.
+ [0582b6027161]
+
+2011-08-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog_path.c,
+ plugins/sudoers/regress/iolog_path/data:
+ Fix expansion of strftime() escapes in log_dir and add a regress
+ test that exhibited the problem.
+ [a5c7c1c4c589]
+
+ * plugins/sudoers/Makefile.in:
+ Fix "make check" return value.
+ [33b58e175230]
+
+2011-08-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ Regen pot files
+ [063841aac19b]
+
+ * Makefile.in:
+ Fix logic inversion in pot file up to date check.
+ [f6a8ca8654df]
+
+2011-08-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Add caching for gettext() checks.
+ [01b7200f6105]
+
+ * configure, configure.in:
+ Better handling of libintl header and library mismatch.
+ [9a49b1d4db69]
+
+2011-08-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Also check sudoers gid if sudoers is group writable.
+ [23ef96ca0d33]
+
+2011-08-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ If dlopen is present but libtool doesn't find it, error out since it
+ probably means that libtool doesn't support the system.
+ [a9da0a5f7941]
+
+ * mkpkg:
+ configure args on the command line should override builtin defaults.
+ Disable NLS for non-Linux/Solaris unless explicitly enabled.
+ [b2fb05614504]
+
+ * plugins/sudoers/auth/aix_auth.c:
+ Fix loop that calls authenticate(). If there was an error message
+ from authenticate(), display it.
+ [063a0c4f0b9a]
+
+2011-08-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * m4/libtool.m4, m4/ltversion.m4:
+ Update to autoconf 2.68 and libtool 2.4
+ [5a912a6eb67b]
+
+ * config.guess, config.sub, configure, configure.in, ltmain.sh:
+ Update to autoconf 2.68 and libtool 2.4
+ [931ab56aecf6]
+
+ * doc/sudoers.pod:
+ Fix typo; OPT should be OTP
+ [e97bd2e46544]
+
+ * plugins/sudoers/Makefile.in:
+ Rename libsudoers convenience library to libparsesudoers to avoid
+ libtool confusion.
+ [2a89a613f537]
+
+2011-08-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/po/da.mo, plugins/sudoers/po/da.po:
+ Add Danish sudoers translation from translationproject.org
+ [27b96e85eb13]
+
+ * plugins/sudoers/sudoers.c, plugins/sudoers/testsudoers.c:
+ Add dedicated callback function for runas_default sudoers setting
+ that only sets runas_pw if no runas user or group was specified by
+ the user.
+ [b8382d8eea34]
+
+2011-08-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/fi.mo, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po,
+ plugins/sudoers/po/uk.mo, plugins/sudoers/po/uk.po, src/po/ru.mo,
+ src/po/ru.po:
+ Update Finish, Polish, Russian and Ukrainian translations from
+ translationproject.org.
+ [f9339aff664e]
+
+ * plugins/sudoers/defaults.h, plugins/sudoers/sudoers.c,
+ plugins/sudoers/testsudoers.c:
+ Go back to using a callback for runas_default to keep runas_pw in
+ sync. This is needed to make per-entry runas_default settings work
+ with LDAP-based sudoers. Instead of declaring it a callback in
+ def_data.in, sudo and testsudoers poke sudo_defs_table[] which is a
+ bit naughty, but avoids requiring stub functions in visudo and the
+ tests.
+ [9aaefb908415]
+
+2011-08-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Add check for out of date message catalogs when doing "make dist".
+ [e45a29b612f4]
+
+2011-08-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [d6f9ad26774a]
+
+ * configure.in:
+ Make sure compiler supports static-libgcc before using it.
+ [b01bd9566e50]
+
+2011-08-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/Makefile.in:
+ Link libsudo_noexec.la with LDLDFLAGS for -static-libgcc
+ [c99c7ab3edef]
+
+2011-07-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/po/fi.mo, plugins/sudoers/po/pl.mo,
+ plugins/sudoers/po/pl.po, plugins/sudoers/po/uk.mo,
+ plugins/sudoers/po/zh_CN.mo, src/po/ru.mo, src/po/ru.po,
+ src/po/zh_CN.mo:
+ Add new Russian sudo translation from translationproject.org and
+ rebuild the other translation files.
+ [e20015459056]
+
+2011-07-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/fi.po, plugins/sudoers/po/pl.po:
+ Update Finish and Polish translations from translationproject.org
+ [4e3dbba4a1de]
+
+ * plugins/sudoers/sudoers.c, src/parse_args.c, src/sudo.c:
+ Go back to escaping the command args for "sudo -i" and "sudo -s"
+ before calling the plugin. Otherwise, spaces in the command args are
+ not treated properly. The sudoers plugin will unescape non- spaces
+ to make matching easier.
+ [dfa2c4636f33]
+
+2011-07-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/parse.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l:
+ Fix some potential problems found by the clang static analyzer, none
+ serious.
+ [ff64aa74aae6]
+
+ * plugins/sudoers/po/uk.po, plugins/sudoers/po/zh_CN.po,
+ src/po/zh_CN.po:
+ Updated Ukranian and Chinese (simplified) po files from
+ translationproject.org
+ [ec792becb48e]
+
+2011-07-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/pl.po:
+ Updated Polish translation from translationproject.org
+ [a3af53cb649c]
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ Rebuild pot files
+ [c650524c0f0a]
+
+ * plugins/sudoers/audit.c, plugins/sudoers/sudoers.c:
+ Don't try to audit failure if the runas user does not exist. We
+ don't have the user's command at this point so there is nothing to
+ audit. Add a NULL check in audit_success() and audit_failure() just
+ to be on the safe side.
+ [2a0007c2022f]
+
+ * mkpkg:
+ Add -g to CFLAG for PIE builds.
+ [32a0a9693c9c]
+
+2011-07-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/pwutil.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, src/sudo.c:
+ Remove fallback to per-group lookup when matching groups in sudoers.
+ The sudo front-end will now use getgrouplist() to get the user's
+ list of groups if getgroups() fails or returns zero groups so we
+ always have a list of the user's groups. For systems with
+ mbr_check_membership() which support more that NGROUPS_MAX groups
+ (Mac OS X), skip the call to getgroups() and use getgrouplist() so
+ we get all the groups.
+ [51b3ed8c600b]
+
+2011-07-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/setgroups.c:
+ Fix setgroups() fallback code on EINVAL.
+ [2b6faecd56a4]
+
+ * plugins/sudoers/set_perms.c:
+ Fix two PERM_INITIAL cases that were still using user_gids.
+ [9680bab0acc6]
+
+ * MANIFEST:
+ Add Polish sudo message catalog
+ [8bb40c3ba576]
+
+ * plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ user_group is no longer used, remove it
+ [9acede0fe6c5]
+
+2011-07-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/po/pl.mo, plugins/sudoers/po/pl.po:
+ Add Polish translation from translationproject.org
+ [afac5c638573]
+
+ * MANIFEST, common/Makefile.in, common/setgroups.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.h, src/sudo.c,
+ src/sudo.h, src/sudo_edit.c:
+ Add a wrapper for setgroups() that trims off extra groups and
+ retries if setgroups() fails. Also add some missing addrefs for
+ PERM_USER and PERM_FULL_USER.
+ [224dfd8aae5c]
+
+ * MANIFEST, compat/Makefile.in, compat/getgrouplist.c, config.h.in,
+ configure, configure.in, include/missing.h, mkdep.pl,
+ plugins/sudoers/ldap.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h, src/sudo.c:
+ Instead of keeping separate groups and gids arrays, create struct
+ group_info and use it to store both, along with a count for each.
+ Cache group info on a per-user basis using getgrouplist() to get the
+ groups. We no longer need special to special case the user or list
+ user for user_in_group() and thus no longer need to reset the groups
+ list when listing another user.
+ [0ad849a8b2d5]
+
+ * src/preload.c:
+ Don't rely on NULL since we don't include a header for it.
+ [b40937f1890c]
+
+2011-07-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.pod:
+ Fix typo
+ [c1035360e169]
+
+2011-07-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Do not shadow global sudo_mode with a local variable in set_cmnd()
+ [0c72969503ad]
+
+2011-07-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ bash 2.x doesd not support the -l flag and exits with an error if it
+ is specified so use --login instead. This causes an error with bash
+ 1.x (which uses -login instead) but this version is hopefully less
+ used than 2.x.
+ [5c4c296e30e6]
+
+ * src/po/pl.mo, src/po/pl.po:
+ Add Polish translation from translationproject.org
+ [48592dd6edcf]
+
+2011-07-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/set_perms.c:
+ Make error strings translatable.
+ [414c5c484768]
+
+ * mkpkg:
+ Only run configure with --with-pam-login for RHEL 5 and above.
+ [6c16e4de4026]
+
+ * sudo.pp:
+ Fix typo in summary
+ [9ac618c9a749]
+
+2011-07-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/logwrap.c:
+ Add missing logwrap.c
+ [c12a413ecc1d]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/logging.c,
+ plugins/sudoers/logging.h,
+ plugins/sudoers/regress/logging/check_wrap.c,
+ plugins/sudoers/regress/logging/check_wrap.in,
+ plugins/sudoers/regress/logging/check_wrap.out.ok:
+ Split out log file word wrap code into its own file and add unit
+ tests. Fixes an off-by one in the word wrap when the log line length
+ matches loglinelen.
+ [52ed277f6690]
+
+2011-07-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ For SuSE, only use /usr/lib64 as libexec if generating 64-bit
+ binaries.
+ [645ab903cf77]
+
+ * src/load_plugins.c, src/sudo.c:
+ Fix build error when --without-noexec configure option is used.
+ [b994f7b0d8b4]
+
+ * configure, configure.in:
+ Disable noexec for AIX < 5. LDR_PRELOAD is only available in AIX 5.3
+ and above.
+ [c2a6f9b472f3]
+
+2011-07-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Resolve the list of gids passed in from the sudo frontend (the
+ result of getgroups()) to names and store both the group names and
+ ids in the sudo_user struct. When matching groups in the sudoers
+ file, match based on the names in the groups list first and only do
+ a gid-based match when we absolutely have to. By matching on the
+ group name (as it is listed in sudoers) instead of id (which we
+ would have to resolve) we save a lot of group lookups for sudoers
+ files with a lot of groups in them.
+ [8dc19353f148]
+
+2011-06-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Workaround for "sudo -i command" and newer versions of bash which
+ don't go into login mode when -c is specified unless -l is too.
+ [9393762b80f3]
+
+2011-06-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/logging.c:
+ Rewrite logfile word wrapping code to be more straight-forward and
+ actually wrap at the correct place.
+ [f712a0c90f55]
+
+2011-06-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/CONTRIBUTORS, doc/contributors.pod, plugins/sudoers/sudoers.c:
+ Set use_pty=true in command details when use_pty is set in sudoers.
+ From Ludwig Nussel
+ [8d95a163dfc1]
+
+2011-06-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/zh_CN.mo, plugins/sudoers/po/zh_CN.po,
+ src/po/zh_CN.mo, src/po/zh_CN.po:
+ Sync Chinese (simplified) PO files from translationproject.org
+ [acce8eb7be18]
+
+2011-06-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, plugins/sudoers/po/eu.mo, plugins/sudoers/po/fi.mo,
+ plugins/sudoers/po/uk.mo, src/po/da.mo, src/po/da.po, src/po/eu.mo:
+ Add Danish translation from translationproject.org and add missing
+ Basque mo files.
+ [0c22bb21b9c4]
+
+ * Makefile.in, configure, configure.in:
+ No longer need to specify LINGUAS in configure, "make install-nls"
+ now just installs all the .mo files it finds.
+ [fcd45cf04885]
+
+2011-06-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, doc/CONTRIBUTORS, doc/Makefile.in, doc/contributors.pod:
+ Build CONTRIBUTORS from newly-added contributors.pod
+ [8b192f2720f4]
+
+ * doc/CONTRIBUTORS:
+ Rework the wording in the leading paragraph
+ [312044145cdd]
+
+2011-06-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, doc/CONTRIBUTORS:
+ Add a CONTRIBUTORS file with the names of folks who have contributed
+ code or patches to sudo since I started maintaining it (plus the
+ original authors).
+ [b8bdd8b59528]
+
+2011-06-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/env.c:
+ Preserve SHELL variable for "sudo -s". Otherwise we can end up with
+ a situation where the SHELL variable and the actual shell being run
+ do not match.
+ [b8b3974aee3e]
+
+2011-06-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Only enable Solaris project support when setproject() is present in
+ libproject.
+ [49ad7857ab89]
+
+ * sudo.pp:
+ Explicitly set mode and owner of /etc/sudoers instead of relying on
+ "cp -p" to work in the postinstall script. On AIX 6.1 at least the
+ postinstall script runs before the final file permissions are set.
+ [e41ffc0212b2]
+
+2011-06-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.pod, doc/sudoers.pod:
+ Refer the user to the "Command Environment" section in description
+ of sudo's -i option.
+ [263cc3be7eef]
+
+ * doc/sudo.pod:
+ Fix typo
+ [35dfac450f4d]
+
+2011-06-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkdep.pl:
+ If there is no old dependency for an object file, use the MANIFEST
+ to find its source.
+ [d15e3b9899f9]
+
+ * compat/Makefile.in:
+ Remove dependency for getgrouplist.lo as we don't ship that source
+ file.
+ [312a6d5fe6b0]
+
+2011-06-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/getdate.c, plugins/sudoers/getdate.y:
+ Do not declare yyparse() static as the actual function generated by
+ yacc is extern.
+ [9017b79dcf55]
+
+2011-06-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Remove locale files in "make uninstall"
+ [201ff261ecbe]
+
+ * configure.in, plugins/sudoers/po/eu.po, plugins/sudoers/po/fi.po,
+ plugins/sudoers/po/uk.po, src/po/eu.po:
+ Add Basque translation and sync Finish and Ukranian translations.
+ [66d2c78c8a13]
+
+ * configure, configure.in:
+ FreeBSD no longer needs the main sudo binary to link with -lpam now
+ that plug-ins are loaded with RTLD_GLOBAL.
+ [96c710df2457]
+
+ * plugins/sudoers/group_plugin.c, src/load_plugins.c:
+ Load plugins with RTLD_GLOBAL instead of RTLD_LOCAL. This fixes
+ problems with pam modules not having access to symbols provided by
+ libpam on some platforms. Affects FreeBSD and SLES 10 at least.
+ [0d016983ec84]
+
+ * Makefile.in:
+ Move xgettext invocation out of update-po target into update-pot
+ [19a73c6d017c]
+
+2011-06-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+ Regenerate .pot files for 1.8.2rc2
+ [c3037f591dd8]
+
+ * Makefile.in, common/Makefile.in, compat/Makefile.in,
+ doc/Makefile.in, include/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ src/Makefile.in, zlib/Makefile.in:
+ Move nls targets to the top level Makefile so the paths in the pot
+ file are saner
+ [65b9285cd8d9]
+
+ * src/po/fi.mo:
+ Add compiled version of sudo Finish translation
+ [8f2405384ea3]
+
+ * MANIFEST, plugins/sudoers/po/fi.mo, plugins/sudoers/po/uk.mo:
+ Update MANIFEST with .po and .mo files Rebuild sudoers fi and uk .mo
+ files
+ [a165e70fa9ec]
+
+ * configure, configure.in, plugins/sudoers/po/fi.po:
+ Add Finish translation from translationproject.org
+ [4466f8a96ceb]
+
+2011-06-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.pod:
+ The group named by exempt_group should not have a % prefix.
+ [df084d6b32c8]
+
+2011-06-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.pod:
+ Fix typo; "Defaults group_plugin" not "Defaults sudo_plugin"
+ [5113699a3f8b]
+
+2011-05-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c, src/exec_pty.c:
+ Fix compressed io log corruption in background mode by using _exit()
+ instead of exit() to avoid flushing buffers twice.
+
+ Improved background mode support. When not allocating a pty, the
+ command is run in its own process group. This prevents write access
+ to the tty. When running in a pty, stdin is not hooked up and we
+ never read from /dev/tty, which results in similar behavior.
+ [87c15149894c]
+
+ * compat/Makefile.in, mkdep.pl, plugins/sudoers/Makefile.in:
+ Clean up regress files Generate proper dependencies for regress objs
+ in compat
+ [88bfc728c1e7]
+
+ * plugins/sudoers/Makefile.in:
+ Add missing dependency for check_fill.o.
+ [0bd6362e3e17]
+
+2011-05-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, configure, configure.in:
+ Add support for --enable-nls[=location]
+ [b90db44a050f]
+
+2011-05-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/linux_audit.c:
+ Include gettext.h
+ [7f909a6e48cb]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/parse.c:
+ Quiet gcc warnings.
+ [b41a6cdca583]
+
+ * configure, configure.in:
+ Don't install .mo files if gettext was not found.
+ [1397b34cc165]
+
+2011-05-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ Always allocate a pty when running a command in the background but
+ call setsid() after forking to make sure we don't end up with a
+ controlling tty.
+ [b6454ba172e8]
+
+ * plugins/sudoers/iolog.c:
+ Add missing space between command name and the first command line
+ argument.
+ [fe217f0a36d4]
+
+ * plugins/sudoers/sudoreplay.c:
+ Quiet a compiler warning on some platforms.
+ [de9f2849f236]
+
+ * plugins/sudoers/po/README, src/po/README:
+ README file that directs people to translationproject.org
+ [30c0fc323281]
+
+ * plugins/sudoers/po/uk.po, src/po/fi.po:
+ Sync translations with TP
+ [1d7d64559cba]
+
+ * Makefile.in:
+ Add 'sync-po' target to top-level Makefile to rsync the po files
+ from translationproject.org.
+ [20508211aaa3]
+
+ * plugins/sudoers/Makefile.in:
+ install nls files from install target
+ [5fc07b6cab38]
+
+ * Makefile.in, plugins/sudoers/Makefile.in, src/Makefile.in, sudo.pp:
+ Include .mo files in sudo binary packags.
+ [278d4821a916]
+
+ * configure, configure.in, plugins/sudoers/po/zh_CN.mo,
+ plugins/sudoers/po/zh_CN.po, src/po/zh_CN.mo, src/po/zh_CN.po:
+ Add simplified chinese translation
+ [2b33ffc755b9]
+
+2011-05-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in, plugins/sudoers/po/uk.mo,
+ plugins/sudoers/po/uk.po, src/po/uk.mo, src/po/uk.po:
+ Add ukranian translation
+ [2d8102688e93]
+
+ * compat/Makefile.in:
+ refer to siglist.c, not ./siglist.c since not all makes will treat
+ foo and ./foo the same.
+ [6639d293ffba]
+
+ * plugins/sudoers/sudoers.c:
+ Set def_preserve_groups before searching for the command when the -P
+ flag is specified.
+ [0edc7942f875]
+
+ * Makefile.in, compat/Makefile.in, mkdep.pl,
+ plugins/sudoers/Makefile.in:
+ Add dependency for siglist.lo in compat. This is a generated file so
+ "make depend" needs to depend on it.
+ [28d0932f8b50]
+
+ * compat/Makefile.in:
+ More dependency fixes.
+ [aad0d05cd020]
+
+ * compat/Makefile.in:
+ Fix a few dependencies.
+ [eb21aa35a032]
+
+ * plugins/sudoers/Makefile.in, src/Makefile.in:
+ Place compiled mo files in the src dir, not the build dir. When
+ installing compiled mo files, display a status message.
+ [e15634c29cd3]
+
+2011-05-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.ldap.pod, plugins/sudoers/ldap.c:
+ Tivoli Directory Server requires that seconds be present in a
+ timestamp, even though RFC 4517 states that they are optional.
+ [55fe23dd4ef9]
+
+ * plugins/sudoers/sudo_nss.h:
+ Add missing bit of copyright
+ [d2eba3c364ca]
+
+ * doc/visudo.pod:
+ Mention cycle detection warnings
+ [a76bef15ab67]
+
+ * plugins/sudoers/visudo.c:
+ When checking aliases, also check the contents of the alias in case
+ there are problems with an alias that is referenced inside another.
+ Replace the self reference check with real alias cycle detection.
+ [a66c904cf53b]
+
+ * plugins/sudoers/alias.c:
+ Set errno to ELOOP in alias_find() if there is a cycle. Set errno to
+ ENOENT in alias_find() and alias_remove() if the entry could not be
+ found.
+ [b4f0b89e433c]
+
+ * plugins/sudoers/visudo.c:
+ Increment alias_seqno before calls to alias_remove_recursive() to
+ avoid false positives with the alias loop detection. Fixes spurious
+ warnings about unused aliases when they are nested.
+ [a344483b8193]
+
+ * MANIFEST:
+ add mkdep.pl
+ [86b7ed33eab2]
+
+ * plugins/sudoers/Makefile.in:
+ Add dependency on convenience libs to binaries
+ [cd3078b3c997]
+
+ * Makefile.in:
+ mkdep.pl only works when run from the src dir
+ [f35a5e47c944]
+
+ * Makefile.in, common/Makefile.in, compat/Makefile.in, mkdep.pl,
+ plugins/sample/Makefile.in, plugins/sample_group/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in, zlib/Makefile.in:
+ Auto-generate Makefile dependencies with a perl script.
+ [a3e4afcd7975]
+
+2011-05-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/match.c:
+ If the user specifies a runas group via sudo's -g option that
+ matches the runas user's group in the passwd database and that group
+ is not denied in the Runas_Spec, allow it. Thus, if user root's gid
+ in /etc/passwd is 0, then "sudo -u root -g root id" is allow even if
+ no groups are present in the Runas_Spec.
+ [e3f9732dc564]
+
+2011-05-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in, src/Makefile.in:
+ Add dependencies on gettext.h
+ [a3a9dc51f78b]
+
+ * plugins/sudoers/Makefile.in, src/Makefile.in:
+ Fix install-nls target with HP-UX sh when gettext is not present.
+ [0c6b9655cd41]
+
+2011-05-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/po/sudoers.pot,
+ src/Makefile.in, src/po/sudo.pot:
+ regenerate .pot files for lbuf changes
+ [918ded125a0b]
+
+ * configure, configure.in:
+ Add missing "checking" message for gettext when using the cache.
+ [9c21187ad1d2]
+
+ * common/lbuf.c, include/lbuf.h, plugins/sudoers/ldap.c,
+ plugins/sudoers/parse.c, plugins/sudoers/sudo_nss.c,
+ src/parse_args.c:
+ Add primitive format string support to the lbuf code to make
+ translations simpler.
+ [ee71c7ef5299]
+
+ * MANIFEST, plugins/sudoers/Makefile.in,
+ plugins/sudoers/po/sudoers.pot, src/Makefile.in, src/po/sudo.pot:
+ Add message catalog template files for sudo and the sudoers module.
+ [f3f8acb1f014]
+
+ * MANIFEST, common/aix.c, common/alloc.c, compat/strsignal.c,
+ config.h.in, configure.in, doc/Makefile.in, include/gettext.h,
+ plugins/sudoers/iolog.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/visudo.c, src/error.c,
+ src/net_ifs.c, src/sesh.c, src/sudo.c, src/sudo.h:
+ Add gettext.h convenience header. This is similar to but distinct
+ from the one included with the gettext package.
+ [930a0591f73c]
+
+2011-05-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Add checks for nroff -c and -Tascii flags
+ [19ca990b3149]
+
+ * configure, configure.in:
+ Add check for HP bundled C Compiler (which cannot create shared
+ libs)
+ [517716a7072d]
+
+ * plugins/sudoers/sudoreplay.c:
+ Fix C format warnings.
+ [6514326013fa]
+
+ * include/error.h:
+ Add __printflike
+ [e1749a30a406]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/parse.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/visudo.c, src/parse_args.c:
+ Translate help / usage strings.
+ [ee1cc9b1a8bd]
+
+ * plugins/sudoers/Makefile.in, src/Makefile.in:
+ Set --msgid-bugs-address to the bugzilla url
+ [5a0aa250ca21]
+
+ * Makefile.in, common/Makefile.in, compat/Makefile.in, configure,
+ configure.in, doc/Makefile.in, include/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sample_group/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in, zlib/Makefile.in:
+ Add scaffolding to update .po files and install .mo files.
+ [f05f4eed1fe1]
+
+ * doc/license.pod:
+ update copyright year
+ [fa0c62523875]
+
+ * INSTALL, README:
+ No need to include version number at the top of these files.
+ [9f2981325351]
+
+2011-05-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/env.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/visudo.c:
+ Minor warning/error cleanup
+ [9236dc85aeab]
+
+ * config.h.in, configure.in:
+ Emulate ngettext for the non-nls case
+ [13571d63fa36]
+
+ * plugins/sudoers/ldap.c:
+ Do not mark untranslatable strings for translation
+ [735f5d4413fe]
+
+ * plugins/sudoers/check.c:
+ Use ROOT_UID not 0.
+ [09a268db8da4]
+
+ * plugins/sudoers/check.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/logging.c, src/exec.c, src/exec_pty.c,
+ src/load_plugins.c, src/sudo.c, src/sudo_edit.c:
+ Minor warning/error message cleanup
+ [3c7b1a7939b5]
+
+ * plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/logging.c, plugins/sudoers/mon_systrace.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/visudo.c, src/exec.c,
+ src/exec_pty.c, src/net_ifs.c, src/selinux.c:
+ cannot -> "unable to" in warning/error messages
+ [31c3897649e9]
+
+ * plugins/sudoers/check.c, plugins/sudoers/mon_systrace.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/visudo.c, src/exec_pty.c,
+ src/sudo.c, src/utmp.c:
+ can't -> "unable to" in warning/error messages
+ [127b75f15291]
+
+ * configure, configure.in:
+ FreeBSD needs the main sudo executable to link with -lpam when
+ loading dynaic pam modules for some reason.
+ [944522cc9bef]
+
+2011-05-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c, src/exec.c, src/exec_pty.c, src/sudo.c:
+ We don't want to translate debugging messages.
+ [56a1a365815a]
+
+ * configure, configure.in, plugins/sudoers/Makefile.in,
+ plugins/sudoers/iolog.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/visudo.c,
+ src/Makefile.in, src/sesh.c, src/sudo.c:
+ Add calls to bindtextdomain() and textdomain() Currently there are
+ two domains, one for the sudo front-end and one for the sudoers
+ plugin and its associated utilities.
+ [0426138f789e]
+
+ * configure, configure.in:
+ Fix caching of libc gettext check.
+ [942142d2c43a]
+
+ * plugins/sudoers/def_data.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/mkdefaults:
+ Mark defaults descriptions for translation
+ [5b27f018e6cf]
+
+ * NEWS:
+ Update for sudo 1.8.1p2
+ [747c4dee2ca7]
+
+2011-05-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Quiet compiler warning when SELinux is enabled.
+ [1fbf77dda240]
+
+ * plugins/sudoers/plugin_error.c, plugins/sudoers/sudoreplay.c,
+ src/error.c, src/net_ifs.c, src/sesh.c:
+ Add missing includes of libintl.h.
+ [bc1d66316082]
+
+ * plugins/sudoers/auth/pam.c:
+ Fix gettext marker.
+ [a5cf4ed66c66]
+
+ * common/aix.c, common/alloc.c, compat/strsignal.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/sudoers.h, src/sudo.h:
+ Include libint.h where needed.
+ [2b0e5a663c7b]
+
+ * plugins/sudoers/alias.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/securid.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/check.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/env.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/interfaces.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/iolog_path.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/logging.c,
+ plugins/sudoers/parse.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/set_perms.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, plugins/sudoers/visudo.c:
+ Prepare sudoers module messages for translation.
+ [7212ae1909c5]
+
+ * plugins/sudoers/sudoers.c:
+ Only check gid of sudoers file if it is group-readable.
+ [50e3bc0cb242]
+
+ * plugins/sudoers/auth/aix_auth.c:
+ For AIX, keep calling authenticate() until reenter reaches 0.
+ [e240815b74b1]
+
+2011-05-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Cache the status of the initial gettext() check.
+ [32751ebe1704]
+
+ * INSTALL, configure, configure.in:
+ Add --disable-nls flag and improve checks for gettext.
+ [c7e6b17052de]
+
+ * configure, configure.in:
+ When building with gcc on HP-UX, use -march=1.1 to produce portable
+ binaries on a pa-risc2 host. Previously, the +Dportable option was
+ used for the HP-UX C compiler but gcc always produced native
+ binaries.
+ [8f4c749324d7]
+
+2011-05-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/aix.c, common/alloc.c, compat/strsignal.c, src/error.c,
+ src/exec.c, src/exec_pty.c, src/load_plugins.c, src/net_ifs.c,
+ src/parse_args.c, src/selinux.c, src/sesh.c, src/sudo.c,
+ src/sudo_edit.c, src/tgetpass.c, src/utmp.c:
+ Prepare sudo front end messages for translation.
+ [2fc2fabceccb]
+
+2011-05-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, plugins/sudoers/auth/pam.c:
+ Add initial scaffolding to support localization via gettext()
+ [7d47b59fcf95]
+
+ * compat/fnmatch.h, compat/glob.h:
+ Don't let the fnmatch/glob macros expand the function prototype.
+ [a9014aa0288e]
+
+2011-05-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/fnmatch.c, compat/fnmatch.h, compat/glob.c, compat/glob.h:
+ Resolve namespace collisions on HP-UX ia64 and possibly others by
+ adding a rpl_ prefix to our fnmatch and glob replacements and
+ #defining rpl_foo to foo in the header files.
+ [caa9b690a15d]
+
+2011-04-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Split ALL, ROLE and TYPE into their own actions. Since you can only
+ have #ifdefs inside of braces, ROLE and TYPE use a naughty goto in
+ the non-SELinux case. This is safe because the actions are in one
+ big switch() statement.
+ [7473fc2cfa2c]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Fix regexp for matching a CIDR-style IPv4 netmask. From Marc Espie.
+ [9be3480c2865]
+
+2011-04-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/UPGRADE, doc/sudoers.pod:
+ askpass moved from sudoers to sudo.conf in sudo 1.8.0
+ [b2c2956cec4e]
+
+ * doc/sudoers.pod:
+ Remove obsolete warning about runas_default and ordering. Move
+ syslog facility and priority lists into the section where the
+ relevant options are described.
+ [e57b8dc3f779]
+
+2011-04-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/sia.c:
+ Fix SIA support; we no longer have access to the real argc and argv
+ so allocate space for a fake one and use the argv passed to the
+ plugin with "sudo" for argv[0].
+ [1c0552772ad2]
+
+2011-04-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/net_ifs.c:
+ Remove useless realloc when trying to get the buffer size right.
+ [792225380a62]
+
+ * plugins/sudoers/set_perms.c:
+ Be explicit when setting euid to 0 before call to setreuid(0, 0)
+ [7bfeb629fccb]
+
+2011-04-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Need to do checks for krb5_verify_user, krb5_init_secure_context and
+ krb5_get_init_creds_opt_alloc regardless of whether or not
+ krb5-config is present.
+ [9d1b98ece1d3]
+
+2011-04-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/set_perms.c:
+ Work around weird AIX saved uid semantics on setuid() and
+ setreuid(). On AIX, setuid() will only set the saved uid if the euid
+ is already 0.
+ [069fc08150ca]
+
+2011-04-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ update copyright year
+ [1c42d579ba6e]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Treat a missing includedir like an empty one and do not return an
+ error.
+ [92f71d8cbfd4]
+
+2011-04-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pp:
+ Fix ARCH setting in cross-compile Solaris packages.
+ [b0de281cc889]
+
+ * sudo.pp:
+ Fix aix version setting.
+ [98437dbfb085]
+
+ * plugins/sudoers/ldap.c:
+ Remove extraneous parens in LDAP filter when sudoers_search_filter
+ is enabled that causes a search error. From Matthew Thomas.
+ [1d75bf1fc8d9]
+
+2011-04-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/iolog_path/check_iolog_path.c:
+ Correct sizeof() to fix test failure.
+ [fd2f7c0c0572]
+
+ * plugins/sudoers/Makefile.in:
+ "install" target should depend on "install-dirs". Fixes "make -j"
+ problem and closes bz #487. From Chris Coleman.
+ [083902d38edb]
+
+2011-04-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ Add HAVE_RFC1938_SKEYCHALLENGE
+ [a94cb33758a8]
+
+2011-04-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Mention plugin loading and libgcc changes
+ [e11b30b5026a]
+
+ * src/load_plugins.c, src/sudo.c, src/sudo_plugin_int.h:
+ Load plugins after parsing arguments and potentially printing the
+ version. That way, an error loading or initializing a plugin doesn't
+ break "sudo -h" or "sudo -V".
+ [1b76f2b096a2]
+
+ * Makefile.in:
+ When using a sub-shell to invoke the sub-make, exec make instead of
+ running it inside the shell to avoid an extra process.
+ [fd2c04a71fbf]
+
+ * compat/regress/fnmatch/fnm_test.in, compat/regress/glob/globtest.c:
+ Stop testing unspecified behavior in fnmatch Make glob test more
+ portable
+ [229803093725]
+
+ * compat/Makefile.in:
+ No need to add current dir to include path and having it breaks the
+ test programs that expect to get the system glob.h and fnmatch.h
+ [68085f624be4]
+
+ * INSTALL, configure, configure.in:
+ Fix and document --with-plugindir; partially from Diego Elio Petteno
+ [07edc52ea89e]
+
+ * compat/Makefile.in, compat/regress/fnmatch/fnm_test.c,
+ compat/regress/fnmatch/fnm_test.in, compat/regress/glob/globtest.c,
+ compat/regress/glob/globtest.in:
+ Fix fnmatch and glob tests to not use hard-coded flag values in the
+ input file. Link test programs with libreplace so we get our
+ replacement verions as needed.
+ [c2cca448f660]
+
+ * Makefile.in:
+ If make in a subdir fails, fail the target in the upper level
+ Makefile too. Adapted from a patch from Diego Elio Petteno
+ [76fc9a0d96fd]
+
+ * configure, configure.in, plugins/sudoers/auth/rfc1938.c:
+ Add check for NetBSD-style 4-argument skeychallenge() as Gentoo also
+ has this. Adapted from a patch from Diego Elio Petteno
+ [a97279a59b93]
+
+ * plugins/sudoers/Makefile.in:
+ Make SUDOERS_LDFLAGS reference $(LDFLAGS) instead of using @LDFLAGS@
+ directly.
+ [47b884029b3b]
+
+ * configure, configure.in:
+ Fix warnings when -without-skey, --without-opie, --without-kerb4,
+ --without-kerb5 or --without-SecurID were specified.
+ [71ad150f4d24]
+
+ * MANIFEST:
+ Add plugins/sudoers/sudoers_version.h
+ [7423966de440]
+
+ * configure, configure.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in:
+ Back out the --with-libpath addition to SUDOERS_LDFLAGS since that
+ now include LDFLAGS in the sudoers Makefile.in. Add missing settng
+ of @LDFLAGS@ in plugin Makefile.in files.
+ [b835826f889c]
+
+2011-04-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Mention %#gid support in User_List and Runas_List
+ [5a983dff017a]
+
+ * plugins/sudoers/sudoers.c, plugins/sudoers/sudoers_version.h,
+ plugins/sudoers/visudo.c:
+ Keep track of sudoers grammar version and report it in the -V
+ output.
+ [52901a3c0296]
+
+ * plugins/sudoers/sudo_nss.h:
+ Add multiple inclusion guard
+ [50853aed046e]
+
+ * configure, configure.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in:
+ The --with-libpath option now adds to SUDOERS_LDFLAGS as well as
+ LDFLAGS. Remove old -static hack for HP-UX < 9. Add LTLDFLAGS and
+ set it to -Wc,-static-libgcc if not using GNU ld so we don't have a
+ dependency on the shared libgcc in sudoers.so.
+ [66ad8bc5e32d]
+
+ * doc/sudoers.pod:
+ Fix typo; from Petr Uzel
+ [f9a7afd80892]
+
+2011-04-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/testsudoers.c:
+ In dump-only mode, use "root" as the default username instead of
+ "nobody" as the latter may not be available on all systems.
+ [0c48e6414337]
+
+2011-03-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/testsudoers.c:
+ Remove NewArgv/NewArgc, they are no longer needed.
+ [16e18f734c7e]
+
+ * plugins/sudoers/testsudoers.c:
+ Fix setting of user_args
+ [aa29e0d0a54a]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Add '!' token to lex tracing
+ [5227ad266235]
+
+ * plugins/sudoers/regress/testsudoers/test1.sh:
+ Use group bin in test, not wheel as most systems have the bin group
+ but the same is no longer true of wheel.
+ [718802b3b45e]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Avoid using pre or post increment in a parameter to a ctype(3)
+ function as it might be a macro that causes the increment to happen
+ more than once.
+ [78e281152c3a]
+
+2011-03-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Strip off the beta or release candidate version when building AIX
+ packages.
+ [28fe31668559]
+
+ * configure, configure.in:
+ We need to include OSDEFS in CFLAGS when doing the utmp/utmpx
+ structure checks for glibc which only has __e_termination visible
+ when _GNU_SOURCE is *not* defined.
+ [59ae1698911f]
+
+ * common/aix.c:
+ getuserattr(user, ...) will fall back to the "default" entry
+ automatically, there's no need to check "default" manually.
+ [3c7a47a61fdb]
+
+2011-03-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/UPGRADE:
+ Document parser changes.
+ [ec415503308d]
+
+ * Makefile.in, common/Makefile.in, compat/Makefile.in,
+ doc/Makefile.in, include/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ src/Makefile.in, zlib/Makefile.in:
+ If there is an existing sudoers file, only install if it passes a
+ syntax check.
+ [37427c73e8cb]
+
+ * plugins/sudoers/regress/sudoers/test6.out.ok,
+ plugins/sudoers/testsudoers.c:
+ Add runasgroup support to testsudoers
+ [047ea5571f33]
+
+ * plugins/sudoers/Makefile.in:
+ For "make check", keep going even if a test fails.
+ [ce6a0a73c372]
+
+ * plugins/sudoers/testsudoers.c:
+ More useful exit codes:
+ * 0 - parsed OK and command matched.
+ * 1 - parse error
+ * 2 - command not matched
+ * 3 - command denied
+ [1d2ce1361903]
+
+ * doc/sudoers.pod:
+ Document %#gid, and %:#nonunix_gid syntax.
+ [492d4f9696c4]
+
+ * plugins/sudoers/pwutil.c:
+ Add support to user_in_group() for treating group names that begin
+ with a '#' as gids.
+ [20240c94a134]
+
+ * config.h.in, configure, configure.in, src/utmp.c:
+ Add explicit check for struct utmpx.ut_exit.e_termination and struct
+ utmpx.ut_exit.__e_termination. HP-UX uses the latter. Only update
+ ut_exit if we detect one or the other.
+ [b4e8cab777e6]
+
+2011-03-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/toke.c:
+ Add back missing #include of config.h
+ [9ab3897a1b2e]
+
+ * plugins/sudoers/iolog_path.c,
+ plugins/sudoers/regress/iolog_path/data:
+ Avoid a NULL deref on unrecognized escapes. Collapse %% -> % like
+ strftime() does.
+ [93395762cdcd]
+
+ * aclocal.m4:
+ Quote first argument to AC_DEFUN(); from Elan Ruusamae
+ [97f53ad31d77]
+
+2011-03-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST:
+ add new sudoers tests
+ [476af91b3da3]
+
+ * plugins/sudoers/regress/sudoers/test8.in,
+ plugins/sudoers/regress/sudoers/test8.out.ok,
+ plugins/sudoers/regress/sudoers/test8.toke.ok:
+ Add test for a newline in the middle of a string when no line
+ continuation character is used.
+ [de2394bc86ab]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Use bitwise AND instead of modulus to check for length being odd. A
+ newline in the middle of a string is an error unless a line
+ continuation character is used.
+ [bdb1d762a1d5]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Move lexer globals initialization into init_lexer.
+ [1ce62211aadb]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Fix a potential crash when a non-regular file is present in an
+ includedir. Fixes bz #452
+ [1586760c3525]
+
+ * pp:
+ On some Linux systems, "uname -p" contains detailed processor info
+ so check "uname -m" first and then "uname -p" if needed. Recognize
+ PLD Linux.
+ [b8535cb9012e]
+
+2011-03-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/redblack.c:
+ Don't need all sudoers.h here.
+ [8c0929f42dab]
+
+ * src/sudo.c:
+ Print sudo version early, in case policy plugin init fails.
+ [47cddc4358bc]
+
+2011-03-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/sudoers/test4.toke.ok:
+ Update to match change in input.
+ [4a3af8e68790]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Make an empty group or netgroup a syntax error.
+ [66f51ddc2ff6]
+
+ * plugins/sudoers/regress/sudoers/test7.in,
+ plugins/sudoers/regress/sudoers/test7.out.ok,
+ plugins/sudoers/regress/sudoers/test7.toke.ok:
+ An empty group or netgroup should be a syntax error.
+ [bd5bf1e2edce]
+
+ * plugins/sudoers/regress/sudoers/test6.in,
+ plugins/sudoers/regress/sudoers/test6.out.ok,
+ plugins/sudoers/regress/sudoers/test6.toke.ok:
+ Check that uids work in per-user and per-runas Defaults Check that
+ uids and gids work in a Command_Spec
+ [c5e848e6082b]
+
+ * plugins/sudoers/regress/sudoers/test5.in,
+ plugins/sudoers/regress/sudoers/test5.out.ok,
+ plugins/sudoers/regress/sudoers/test5.toke.ok:
+ Test empty string in User_Alias and Command_Spec
+ [3a084d777e03]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Allow a group ID in the User_Spec.
+ [bc2859eb71dc]
+
+2011-03-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Return an error for the empty string when a word is expected. Allow
+ an ID for per-user or per-runas Defaults.
+ [915c259b00ff]
+
+ * plugins/sudoers/testsudoers.c:
+ Fix printing "User_Alias FOO = ALL"
+ [ba58c3d548b3]
+
+2011-03-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/parse_args.c:
+ Better error message about invalid -C argument
+ [c9a8d15bbf5d]
+
+ * NEWS:
+ fix typo
+ [cdcfbafed013]
+
+ * doc/sudoers.pod:
+ Fix placement of equal size ('=') in user specification summary.
+ [5ad7178b230d]
+
+2011-03-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST:
+ update to match sudoers regress
+ [e04db0648717]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Restore ability to define TRACELEXER and have trace output go to
+ stderr.
+ [d9531e4d1b20]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Restore old behavior of setting sawspace = TRUE for command line
+ args when a line continuation character is hit to avoid causing
+ problems for existing sudoers files.
+ [fd930ad25550]
+
+ * plugins/sudoers/regress/sudoers/test4.in,
+ plugins/sudoers/regress/sudoers/test4.out.ok,
+ plugins/sudoers/regress/sudoers/test4.toke.ok:
+ Add test for line continuation and aliases
+ [29ab538ca6bb]
+
+ * plugins/sudoers/Makefile.in:
+ Make test output line up nicely for parse vs. toke
+ [257ef82c1434]
+
+ * plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/sudoers/test1.in,
+ plugins/sudoers/regress/sudoers/test1.out.ok,
+ plugins/sudoers/regress/sudoers/test1.toke.ok,
+ plugins/sudoers/regress/sudoers/test2.in,
+ plugins/sudoers/regress/sudoers/test2.out.ok,
+ plugins/sudoers/regress/sudoers/test2.toke.ok,
+ plugins/sudoers/regress/sudoers/test3.in,
+ plugins/sudoers/regress/sudoers/test3.out.ok,
+ plugins/sudoers/regress/sudoers/test3.toke.ok,
+ plugins/sudoers/regress/testsudoers/test1.ok,
+ plugins/sudoers/regress/testsudoers/test1.out.ok,
+ plugins/sudoers/regress/testsudoers/test1.sh,
+ plugins/sudoers/regress/testsudoers/test2.out,
+ plugins/sudoers/regress/testsudoers/test2.sh,
+ plugins/sudoers/regress/testsudoers/test3.ok,
+ plugins/sudoers/regress/testsudoers/test3.sh,
+ plugins/sudoers/regress/visudo/test1.ok,
+ plugins/sudoers/regress/visudo/test1.sh:
+ Move parser tests to sudoers directory and test the tokenizer output
+ too.
+ [44f529b3cdb6]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ If we match a rule anchored to the beginning of a line after parsing
+ a line continuation character, return an ERROR token. It would be
+ nicer to use REJECT instead but that substantially slows down the
+ lexer.
+ [355478293f8c]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.h,
+ plugins/sudoers/toke.l:
+ Move LEXTRACE macro to toke.h so we can use it in yyerror().
+ [72ee7a06d3ca]
+
+2011-03-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/testsudoers.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l:
+ Make lex tracing settable at run-time in testsudoers via the -t
+ flag. Trace output goes to stderr. Will be used by regress tests to
+ check lexer.
+ [93bd53c413c8]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Allow whitespace after the modifier in a Defaults entry. E.g.
+ "Defaults: username set_home"
+ [9dfcf8dd8a3a]
+
+2011-03-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ Don't set CC when cross-compiling.
+ [4b95b0c04e1c]
+
+ * NEWS:
+ Credit Matthew Thomas for the sudoers_search_filter changes.
+ [a65998ab09f7]
+
+ * MANIFEST:
+ Add the .sym files to the MANIFEST
+ [f599225cc861]
+
+ * NEWS:
+ Update for sudo 1.8.1 beta
+ [71021e854c49]
+
+ * doc/sudo_plugin.pod, plugins/sudoers/sudoers.c, src/parse_args.c:
+ user_shell -> run_shell to avoid confusion with the user's SHELL
+ variable.
+ [dc0ac6dafc21]
+
+ * src/exec_pty.c:
+ Save the controlling tty process group before suspending in pty
+ mode. Previously, we assumed that the child pgrp == child pid (which
+ is usually, but not always, the case).
+ [10b2883b7875]
+
+ * doc/sudoers.ldap.pod, plugins/sudoers/ldap.c:
+ Add support for sudoers_search_filter setting in ldap.conf. This can
+ be used to restrict the set of records returned by the LDAP query.
+ [b0f1b721d102]
+
+2011-03-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Remove the hack to disable -g in CFLAGS unless --with-devel
+ [89822cf84ef4]
+
+ * doc/sudoers.pod:
+ The '@' character does not normally need to be quoted.
+ [7823f5ed829a]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ We normaly transition from GOTDEFS to STARTDEFS on whitespace, but
+ if that whitespace is followed by a comma, we want to treat it as
+ part of a list and not transition.
+ [1ca6943e1824]
+
+ * plugins/sudoers/regress/testsudoers/test3.ok,
+ plugins/sudoers/regress/testsudoers/test3.sh:
+ Add check for whitespace when a User_List is used for a per-user
+ Defaults entry.
+ [91f75e6dd19a]
+
+ * plugins/sudoers/regress/testsudoers/test2.out,
+ plugins/sudoers/regress/testsudoers/test2.sh:
+ Expand quoted name checks to cover recent fixes.
+ [ce4f76bca146]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Fix parsing of double-quoted names in Defaultd and Aliases which was
+ broken in 601d97ea8792.
+ [424b0d6c1dc4]
+
+ * plugins/sudoers/Makefile.in:
+ toke_util.c lives in $(srcdir) not $(devdir)
+ [94866bebee83]
+
+2011-03-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Change trunk version to 1.8.x to distinguish from real 1.8.0.
+ [a9781e61d064]
+
+ * NEWS, doc/UPGRADE:
+ Document major changes in 1.8.1 and add upgrade notes.
+ [f2cf51b0d9ce]
+
+ * plugins/sudoers/match.c:
+ Be careful not to deref user_stat if it is NULL. This cannot
+ currently happen in sudo but might in other programs using the
+ parser.
+ [06a2334dd674]
+
+ * mkpkg:
+ configure will not add -O2 to CFLAGS if it is already defined to add
+ -O2 to the CFLAGS we pass in when PIE is being used.
+ [1ce6481ece59]
+
+ * doc/sudoers.pod:
+ Warn about the dangers of log_input and mention iolog_file and
+ iolog_dir in the log_input and log_output descriptions.
+ [ae854ffb0768]
+
+ * pp:
+ sync with git version
+ [a993e39ce3cb]
+
+ * doc/sudoers.pod:
+ It seems that h comes after i
+ [0f621109220d]
+
+ * doc/sudoers.pod:
+ Move log_input and log_output to their proper, sorted, location.
+ Document set_utmp and utmp_runas.
+ [273b234b9c34]
+
+ * src/exec.c:
+ Save the controlling tty process group before suspending so we can
+ restore it when we resume. Fixes job control problems on Linux
+ caused by the previous attemp to fix resuming a shell when I/O
+ logging not enabled.
+ [f03a660315ee]
+
+ * common/lbuf.c:
+ Fix printing of the remainder after a newline. Fixes "sudo -l"
+ output corruption that could occur in some cases.
+ [25d83fb501fc]
+
+2011-03-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, src/exec_pty.c,
+ src/sudo_exec.h, src/utmp.c:
+ Add support for ut_exit
+ [b574c13f1bba]
+
+ * doc/sudo_plugin.pod, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in,
+ plugins/sudoers/defaults.c, plugins/sudoers/sudoers.c, src/exec.c,
+ src/exec_pty.c, src/sudo.c, src/sudo.h, src/sudo_exec.h, src/utmp.c:
+ Add support for controlling whether utmp is updated and which user
+ is listed in the entry.
+ [44a81632133f]
+
+ * plugins/sudoers/def_data.h, plugins/sudoers/defaults.h,
+ plugins/sudoers/ldap.c, plugins/sudoers/mkdefaults,
+ plugins/sudoers/parse.c:
+ Fix typo; tupple vs. tuple
+ [697744acb710]
+
+ * src/utmp.c:
+ For legacy utmp, strip the /dev/ prefix before trying to determine
+ slot since the ttys file does not include the /dev/ prefix.
+ [7ad5b81ff90c]
+
+ * aclocal.m4, configure, configure.in, pathnames.h.in:
+ Add check for _PATH_UTMP
+ [21e638029bfd]
+
+2011-03-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/iolog_path/check_iolog_path.c:
+ Adapt check_iolog_path to sessid changes
+ [728b5fe2be6f]
+
+ * config.h.in, configure, configure.in, src/Makefile.in,
+ src/exec_pty.c, src/sudo_exec.h, src/utmp.c:
+ Redo utmp handling. If no getutent()/getutxent() is available,
+ assume a ttyslot-based utmp. If getttyent() is available, use that
+ directly instead of ttyslot() so we don't have to do the stdin dup2
+ dance.
+ [18aa455cd140]
+
+2011-03-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, src/Makefile.in, src/exec_pty.c, src/sudo_exec.h,
+ src/utmp.c:
+ Move utmp handling into utmp.c
+ [f6eae6c8e012]
+
+ * common/aix.c, common/alloc.c, common/fileops.c, common/fmt_string.c,
+ common/lbuf.c, common/list.c, compat/isblank.c, compat/memrchr.c,
+ compat/mksiglist.c, compat/nanosleep.c, compat/snprintf.c,
+ compat/strlcat.c, compat/strlcpy.c, compat/strsignal.c,
+ compat/utimes.c, doc/sudo.pod, doc/visudo.pod,
+ include/sudo_plugin.h, plugins/sample/sample_plugin.c,
+ plugins/sample_group/getgrent.c, plugins/sample_group/plugin_test.c,
+ plugins/sudoers/alias.c, plugins/sudoers/auth/afs.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/dce.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/kerb4.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/passwd.c,
+ plugins/sudoers/auth/rfc1938.c, plugins/sudoers/auth/secureware.c,
+ plugins/sudoers/auth/securid.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/boottime.c,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/env.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/goodpath.c,
+ plugins/sudoers/logging.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/redblack.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/timestr.c,
+ plugins/sudoers/tsgetgrpw.c, plugins/sudoers/visudo.c, src/exec.c,
+ src/exec_pty.c, src/get_pty.c, src/parse_args.c, src/sudo.c,
+ src/sudo.h, src/sudo_edit.c, src/sudo_exec.h, src/sudo_noexec.c,
+ src/sudo_plugin_int.h, src/tgetpass.c:
+ Update copyright years.
+ [16aa39f9060a]
+
+ * doc/sudo_plugin.pod, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, src/parse_args.c:
+ Add "user_shell" boolean as a way to indicate to the plugin that the
+ -s flag was given.
+ [fb1ef0897b32]
+
+ * plugins/sudoers/iolog_path.c, plugins/sudoers/logging.c,
+ plugins/sudoers/sudoers.h:
+ Move sessid out of sudo_user.
+ [ba298ddb57f4]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/logging.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Log the TSID even if it is not a simple session ID.
+ [d7cc1b9c513c]
+
+ * doc/sample.sudo.conf, doc/sudo.pod, doc/sudoers.pod:
+ Document noexec in sample.sudo.conf and add back noexec_file section
+ in sudoers with a note that it is deprecated.
+ [4a6e961e494d]
+
+ * plugins/sudoers/set_perms.c:
+ Fix running commands as non-root on systems where setreuid() changes
+ the saved uid based on the effective uid we are changing to.
+ [df0769b71b34]
+
+2011-03-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/defaults.c, src/load_plugins.c, src/sudo.c,
+ src/sudo.h:
+ Move noexec path into sudo.conf now that sudo itself handles noexec.
+ Currently can be configured in sudoers too but is now undocumented
+ and will be removed in a future release.
+ [6fa8befdc110]
+
+ * doc/sudo.pod, doc/sudoers.pod:
+ Document "Path noexec ..." in sudo.conf. No longer document
+ noexec_file in sudoers, it will be removed in a future release.
+ [24eee3a0b3e5]
+
+ * plugins/sudoers/env.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, src/sudo.c, src/sudo.h:
+ Move noexec handling to sudo front-end where it is documented as
+ being.
+ [3ed4f10d7052]
+
+ * config.h.in, configure, configure.in, plugins/sudoers/sudoers.c,
+ src/exec.c, src/exec_pty.c, src/sudo.c, src/sudo.h, src/sudo_edit.c,
+ src/sudo_exec.h:
+ Add support for disabling exec via solaris privileges. Includes
+ preparation for moving noexec support out of sudoers and into front
+ end as documented.
+ [dec843ed553e]
+
+ * plugins/sample/Makefile.in, plugins/sample/sample_plugin.sym,
+ plugins/sample_group/Makefile.in,
+ plugins/sample_group/sample_group.sym, plugins/sudoers/Makefile.in,
+ plugins/sudoers/sudoers.sym:
+ Only export the symbols corresponding to the plugin structs.
+ [8d8d03b0ca54]
+
+ * configure, configure.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in:
+ Install plugins manually instead of using libtool. This works around
+ a problem on AIX where libtool will install a .a file containing the
+ .so file instead of the .so file itself.
+ [796971cfbddb]
+
+ * Makefile.in:
+ Move check into its own rule since some versions of make will run
+ both targets as the default rule.
+ [34d759979176]
+
+ * configure, ltmain.sh, m4/libtool.m4, m4/ltoptions.m4,
+ m4/ltversion.m4, m4/lt~obsolete.m4:
+ Update to libtool 2.2.10
+ [34c130de6af7]
+
+2011-03-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ In handle_signals(), restart the read() on EINTR to make sure we
+ keep up with the signal pipe. Don't return -1 on EAGAIN, it just
+ means we have emptied the pipe.
+ [d5b9c8eb9000]
+
+ * compat/mktemp.c:
+ Reorder functions to quiet a compiler warning.
+ [c9e9a23729f0]
+
+ * mkpkg:
+ Use the Sun Studio C compiler on Solaris if possible
+ [11a86e27891e]
+
+2011-03-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ Fix default setting of osversion variable.
+ [52e49ca1cedd]
+
+ * doc/sudo_plugin.pod:
+ Make two login_class entris consistent.
+ [18ff1fa94a91]
+
+ * config.h.in, configure, configure.in, src/exec.c, src/exec_pty.c,
+ src/sudo_exec.h:
+ Add support for adding a utmp entry when allocating a new pty.
+ Requires the BSD login(3) or SYSV/POSIX getutent()/getutxent().
+ Currently only creates a new entry if the existing tty has a utmp
+ entry.
+ [32db72b81d80]
+
+ * plugins/sudoers/boottime.c:
+ Avoid pulling in headers we don't need on Linux For getutx?id(),
+ call setutx?ent() first and always call endutx?ent().
+ [5dad21e1ee1b]
+
+ * configure, configure.in:
+ Add some more libs to SUDOERS_LIBS instead of relying on them to be
+ pulled in by SUDO_LIBS.
+ [18a7c21c09a7]
+
+ * plugins/sudoers/sudoers.c:
+ Fix return value of "sudo -l command" when command is not allowed,
+ broken in [c7097ea22111]. The default return value is now TRUE and a
+ bad: label is used when permission is denied. Also fixed missing
+ permissions restoration on certain errors. On error()/errorx(), the
+ password and group files are now closed before returning.
+ [4f2d0e869ae5]
+
+2011-03-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.c:
+ Fix passing of login class back to sudo front end.
+ [6f70a784ce48]
+
+ * mkpkg:
+ Add --osversion flag to specify OS instead of running "pp
+ --probeonly"
+ [a8efdccb7bc1]
+
+ * sudo.pp:
+ Fix expr usage w/ GNU expr
+ [48895599ee63]
+
+2011-03-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Fix exit value for validate and list mode.
+ [c7097ea22111]
+
+ * plugins/sudoers/sudoers.c:
+ Fix non-interactive mode with sudoers plugin.
+ [172f29597bd2]
+
+2011-03-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoreplay.pod:
+ sudoreplay can now find IDs other than %{seq} and display the
+ session.
+ [fc3dd3be67e9]
+
+2011-03-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ Add support for replaying sessions when iolog_file is set to
+ something other than %{seq}.
+ [ca3131243874]
+
+ * plugins/sudoers/visudo.c:
+ If we are killed by a signal, display the name of the signal that
+ got us.
+ [994bb76a990e]
+
+ * configure, configure.in:
+ Move libs used for authentication from SUDO_LIBS to SUDOERS_LIBS
+ where they belong.
+ [40f94b936fa4]
+
+ * configure.in:
+ Fix bug in skey/opie check that could cause a shell warning.
+ [83c043072be5]
+
+ * plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ No longer need sudo_getepw() stubs.
+ [bbee15c36912]
+
+2011-03-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudo_nss.c:
+ Fix exit value of "sudo -l command" in sudoers module.
+ [a6541867521b]
+
+2011-03-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/regress/glob/globtest.c:
+ Use fgets() not fgetln() for portability.
+ [df1bb67fb168]
+
+ * sudo.pp:
+ Don't use the beta or release candidate version as the rpm release.
+ [d661ef78021a]
+
+2011-02-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ version 1.8.0
+ [f6530d56f6ae] [SUDO_1_8_0]
+
+ * NEWS:
+ update sudo 1.8 section
+ [f2ee2cf95d18]
+
+2011-02-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/testsudoers/test2.sh:
+ fix test description
+ [cd5730fa9f09]
+
+ * plugins/sudoers/regress/testsudoers/test2.out,
+ plugins/sudoers/regress/testsudoers/test2.sh,
+ plugins/sudoers/regress/visudo/test2.out,
+ plugins/sudoers/regress/visudo/test2.sh:
+ convert test2 to use testsudoers
+ [b5ec3f0b69f1]
+
+ * include/sudo_plugin.h, src/sudo_plugin_int.h:
+ Move struct generic_plugin to sudo_plugin_int.h
+ [6f7bc629329c]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/parse.c, plugins/sudoers/parse.h,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Allow sudoers file name, mode, uid and gid to be specified in the
+ settings list. The sudo front end does not currently set these but
+ may in the future.
+ [22f38a0fda2a]
+
+2011-02-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in, doc/sudo.cat, doc/sudo.man.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudoers.cat,
+ doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in, doc/sudoers.man.in,
+ doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/visudo.cat,
+ doc/visudo.man.in:
+ 1.8.0rc1
+ [5d4588b9c057]
+
+ * doc/sudo.pod, doc/sudoreplay.pod, doc/visudo.pod,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/visudo.c,
+ src/parse_args.c, src/sudo.h:
+ add help text to sudo, visudo and sudoreplay for the -h option
+ [52e7378d8476]
+
+2011-02-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/snprintf.c:
+ avoid using "howmany" for a parameter name since it is a select-
+ related macro
+ [a14d565401a1]
+
+ * doc/sudoers.pod:
+ mention group_plugin when describing nonunix_group
+ [e0d1d0034b17]
+
+ * doc/sudo_plugin.pod:
+ Add missing period at end of sentence
+ [6744d7e9056d]
+
+ * Makefile.in, doc/Makefile.in, include/Makefile.in,
+ plugins/sample/Makefile.in, plugins/sample_group/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in:
+ add localstatedir; closes bug 471
+ [7aefcab85088]
+
+ * config.h.in, configure, configure.in, plugins/sudoers/sudoreplay.c,
+ src/exec.c, src/exec_pty.c:
+ The howmany macro lives in sys/sysmacros.h on SVR5 systems Closes
+ Bug 470
+ [927ed6740f32]
+
+ * configure.in:
+ add missing AH_TEMPLATE for ENV_RESET
+ [16300010c986]
+
+ * src/exec.c:
+ SVR5 systems return non-zero for success on socketpair(), check for
+ -1 instead. Closes Bug 469
+ [4d276494bf8e]
+
+2011-02-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ 1.8.0b5
+ [d611cd5d73d3]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo_plugin.cat,
+ doc/sudo_plugin.man.in, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.man.in, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/visudo.cat, doc/visudo.man.in:
+ regen
+ [85e96eeaed82]
+
+ * doc/sudo.pod:
+ Document that a sudo.conf file with no Pligin lines uses the default
+ sudoers plugins.
+ [88bd52da977f]
+
+ * src/load_plugins.c:
+ If sudo.conf contains no Plugin lines, use the default sudoers
+ policy and I/O plugins.
+ [fd8f4cb811ab]
+
+2011-02-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudo_nss.c:
+ Avoid printing empty "Runas and Command-specific defaults for user"
+ line.
+ [2dd330fe4f8b]
+
+ * common/lbuf.c:
+ Truncate the buffer at buf.len before printing in the non-wordwrap
+ case.
+ [901e9833f80d]
+
+ * common/lbuf.c:
+ Remove extra newline when the tty width is very small or unavailable
+ [245c05506c0e]
+
+2011-02-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/alias.c:
+ Remove unneeded variable.
+ [2c086d30b796]
+
+2011-02-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Prefer getutxid over getutid
+ [3f3322e9c93e]
+
+ * plugins/sudoers/boottime.c:
+ Include utmp.h / utmpx.h before missing.h as apparently including it
+ afterwards causes a compilation problem on GNU Hurd.
+ [a528029ae962]
+
+2011-02-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c, plugins/sudoers/toke_util.c:
+ #include "foo.h", not <foo.h> for local includes.
+ [f65ec693998e]
+
+ * src/parse_args.c:
+ remove bogus XXX
+ [9136c17d53ce]
+
+ * compat/mksiglist.c:
+ Fix typo
+ [1a3bb7b455c9]
+
+ * compat/glob.c, plugins/sudoers/ldap.c, plugins/sudoers/logging.c,
+ plugins/sudoers/match.c:
+ return foo not return(foo)
+ [5c9e0647359a]
+
+2011-02-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ Remove duplicate FD_SET of signal_pipe[0]
+ [3096527d2215]
+
+2011-02-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/mksiglist.c:
+ Use "missing.h" not <missing.h> in generated code.
+ [d8e09cffbe09]
+
+2011-02-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4, configure:
+ fix --with-iologdir=no
+ [a89699cb5f5f]
+
+ * aclocal.m4, configure:
+ fix typo that broke --with-iologdir
+ [91b54eb22403]
+
+2011-02-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in, doc/sudo.cat, doc/sudo.man.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudoers.cat,
+ doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in, doc/sudoers.man.in,
+ doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/visudo.cat,
+ doc/visudo.man.in:
+ Bump version to 1.8.0b4
+ [e2b7f2cdc02e]
+
+ * NEWS:
+ sync
+ [decf5a0a8a33]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod:
+ Attempt to clarify how users and groups interact in Runas_Specs
+ [e6fb3a2dbd77]
+
+ * plugins/sudoers/regress/visudo/test2.out,
+ plugins/sudoers/regress/visudo/test2.sh:
+ Add test for quoted group that contains escaped double quotes
+ [44596c48c629]
+
+ * src/exec.c, src/exec_pty.c:
+ Pass SIGUSR1/SIGUSR2 through to the child.
+ [c3108a827b01]
+
+ * src/exec_pty.c, src/sudo_exec.h:
+ Use special values SIGCONT_FG and SIGCONT_BG instead of SIGUSR1 and
+ SIGUSR2 to indicate whether the child should be continued in the
+ foreground or background.
+ [35ca47cc6785]
+
+ * src/exec.c:
+ Use pid_t not int and check the return value of kill()
+ [36ae7d37d7f9]
+
+2011-02-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Remove obsolete comment
+ [baebef4919f6]
+
+ * src/exec.c:
+ In non-pty mode before continuing the child, make it the foreground
+ pgrp if possible. Fixes resuming a shell.
+ [fef5b1d02ddb]
+
+ * src/exec_pty.c:
+ If we get a signal other than SIGCHLD in the monitor, pass it
+ directly to the child.
+ [b3ecb28163a0]
+
+ * src/exec.c, src/exec_pty.c, src/sudo.h:
+ Save signal state before changing handlers and restore before we
+ execute the command.
+ [faf7475dc4bf]
+
+2011-02-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Use a char array to map a number to a base36 digit.
+ [257576c51f8b]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in, doc/sudoers.ldap.pod:
+ Be clear about what versions of sudo support new LDAP attributes.
+ Fix up some formatting of attribute names. Minor other tweaks.
+ [39f65df71f65]
+
+2011-01-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ match quoted strings the same way whether in a Defaults line or as a
+ user/group/netgroup name. Fixes escaped double quotes in quoted
+ user/group/netgroup names.
+ [601d97ea8792]
+
+ * plugins/sudoers/Makefile.in:
+ 'make check' depends on visudo and testsudoers
+ [127c5a24df8f]
+
+ * plugins/sudoers/sudoers2ldif:
+ Add sudoOrder attribute to each entry Parse LOG_{INPUT,OUTPUT} tags
+ [9029163a58c3]
+
+2011-01-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/UPGRADE:
+ Mention LDAP attribute compatibility status.
+ [2c3595aaec63]
+
+2011-01-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README.LDAP:
+ Mention phpQLAdmin
+ [9304c9064fbe]
+
+ * INSTALL, NEWS, config.h.in, configure, configure.in,
+ doc/sudoers.man.in, doc/sudoers.pod, plugins/sudoers/defaults.c:
+ Add --disable-env-reset configure option.
+ [8a753aa13a46]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod:
+ Document that sudoers_locale also affects logging and email.
+ [998d6ac11277]
+
+ * NEWS, config.h.in, configure, configure.in,
+ plugins/sudoers/logging.c:
+ Do logging and email sending in the locale specified by the
+ "sudoers_locale" setting ("C" by default). Email send by sudo
+ includes MIME headers when the sudoers locale is not "C".
+ [cb7e55408400]
+
+2011-01-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c:
+ Fix indentation
+ [65ae7e92b9e4]
+
+2011-01-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, src/parse_args.c, src/sudo.c:
+ Perform command escaping for "sudo -s" and "sudo -i" after
+ validating sudoers so the sudoers entries don't need to have all the
+ backslashes.
+ [4e168c103f4b]
+
+2011-01-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/logging.c:
+ Prepend "list " to the command logged when "sudo -l command" is used
+ to make it clear that the command was listed, not run.
+ [f392a6056cd6]
+
+ * plugins/sudoers/parse.c:
+ cosmetic change
+ [7c0951dbc2dd]
+
+ * common/aix.c, common/alloc.c, common/fileops.c, common/fmt_string.c,
+ common/list.c, common/term.c, compat/fnmatch.c, compat/getcwd.c,
+ compat/glob.c, compat/isblank.c, compat/memrchr.c, compat/mktemp.c,
+ compat/nanosleep.c, compat/regress/glob/globtest.c,
+ compat/snprintf.c, compat/strlcat.c, compat/strlcpy.c,
+ compat/strsignal.c, compat/utimes.c, plugins/sample/sample_plugin.c,
+ plugins/sample_group/getgrent.c, plugins/sample_group/plugin_test.c,
+ plugins/sudoers/alias.c, plugins/sudoers/auth/afs.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/dce.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/kerb4.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/passwd.c,
+ plugins/sudoers/auth/rfc1938.c, plugins/sudoers/auth/secureware.c,
+ plugins/sudoers/auth/securid.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/bsm_audit.c,
+ plugins/sudoers/check.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/goodpath.c,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/match.c, plugins/sudoers/mon_systrace.c,
+ plugins/sudoers/parse.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/redblack.c, plugins/sudoers/set_perms.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/timestr.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/toke_util.c,
+ plugins/sudoers/tsgetgrpw.c, plugins/sudoers/visudo.c,
+ src/exec_pty.c, src/get_pty.c, src/load_plugins.c, src/parse_args.c,
+ src/sudo_noexec.c, src/tgetpass.c:
+ standardize on "return foo;" rather than "return(foo);" or "return
+ (foo);"
+ [32d76c5aaf8c]
+
+ * plugins/sudoers/sudoers.c:
+ Do not reject sudoers file just because it is root-writable.
+ [0febc579185b]
+
+2011-01-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ sync
+ [1ab03f8278ff]
+
+ * plugins/sudoers/sudo_nss.c:
+ For "sudo -U user -l" if user is not authorized on the host, say so.
+ [289afe6dd15c]
+
+ * plugins/sudoers/ldap.c:
+ In sudo_ldap_lookup(), always do the initial sudoers check as the
+ invoking user. If we are listing another user's privs we will do a
+ separate lookup using list_pw later.
+ [e52bc15de76d]
+
+2011-01-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST:
+ add parser fill tests
+ [4f65140d3515]
+
+ * compat/regress/glob/globtest.c, compat/regress/glob/globtest.in:
+ Don't test features not supported by the bundled glob()
+ [8ec7ace11949]
+
+ * Makefile.in, aclocal.m4, common/Makefile.in, common/term.c,
+ compat/Makefile.in, configure.in, doc/LICENSE, doc/Makefile.in,
+ doc/sudo_plugin.man.in, doc/sudo_plugin.pod,
+ doc/sudoers.ldap.man.in, doc/sudoers.ldap.pod, doc/sudoers.man.in,
+ doc/sudoers.pod, include/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/sudoers/check.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/match.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c, src/Makefile.in, zlib/Makefile.in:
+ Update copyright year to 2011
+ [ac1b45cb1809]
+
+ * plugins/sudoers/sudo_nss.c:
+ When listing, use separate lbufs for the defaults and the privileges
+ and only print something if the number of privileges is non-zero.
+ Fixes extraneous Defaults output for "sudo -U unauthorized_user -l".
+ [d0854d39f8ef]
+
+ * plugins/sudoers/ldap.c:
+ Stash pointer to user group vector in LDAP handle and only reuse the
+ query if it has not changed. We always allocate a new buffer when we
+ reset the group vector so a simple pointer check is sufficient.
+ [88861d4eba69]
+
+ * plugins/sudoers/sudo_nss.c:
+ Check initgroups() return value.
+ [3bdaf58408a7]
+
+ * plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/parser/check_fill.c:
+ Add tests for the fill functions in toke_util.c
+ [bca587ab4956]
+
+2011-01-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/regress/iolog_path/check_iolog_path.c:
+ fix copyright year
+ [e2038cdaf055]
+
+ * NEWS:
+ sync
+ [56ca5d5eaebe]
+
+2011-01-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/term.c:
+ Clear, don't set, OPOST in c_oflag as was intended in 506ad5ae9b4e.
+ [b91f266624ec]
+
+2011-01-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg, sudo.pp:
+ Add Requires line for audit-libs >= 1.4 for RHEL5+
+ [6c02f976171b]
+
+ * pp:
+ sync with git version
+ [d301c32d5865]
+
+2011-01-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod:
+ fix typo
+ [39353f92976f]
+
+2011-01-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Update for sudo 1.7.4p5
+ [b444da76901f]
+
+ * doc/schema.OpenLDAP, doc/schema.iPlanet:
+ Add sudoNotBefore and sudoNotAfter attributes as optional attributes
+ to the sudoRole object class. From Andreas Mueller
+ [dacfad7e7a95]
+
+2011-01-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS:
+ Mention "sudo -g group" password check fix.
+ [1eb8fb14e53b]
+
+ * plugins/sudoers/sudoers.c:
+ Fix "sudo -g" support in the sudoers module.
+ [07d1b0ce530e]
+
+ * plugins/sudoers/check.c:
+ If the user is running sudo as himself but as a different group we
+ need to prompt for a password.
+ [caf1fcc9a117]
+
+2011-01-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * NEWS, config.h.in, configure, configure.in, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.ldap.pod,
+ plugins/sudoers/ldap.c:
+ Add support for TIMEOUT in ldap.conf, mapping to the OpenLDAP
+ LDAP_OPT_TIMEOUT. There is no corresponding option for mozilla-
+ derived LDAP SDKs but we can pass the timeout parameter to
+ ldap_search_ext_s() or ldap_search_st() when possible.
+ [5537049991f7]
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in:
+ regen
+ [5b361c3c4324]
+
+ * NEWS, doc/sudoers.ldap.pod, plugins/sudoers/ldap.c:
+ Add NETWORK_TIMEOUT as an alias for BIND_TIMELIMIT for compatibility
+ with OpenLDAP ldap.conf files.
+ [e97843bd16fb]
+
+ * plugins/sudoers/pwutil.c:
+ If user has no supplementary groups, fall back on checking the group
+ file expliticly.
+ [5223ad4eb690]
+
+2011-01-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/toke.h, plugins/sudoers/toke_util.c:
+ constify
+ [6e132a4cca61]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.h,
+ plugins/sudoers/toke.l:
+ Move fill macro to toke.h
+ [623d430798cf]
+
+ * MANIFEST, plugins/sudoers/Makefile.in, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.h, plugins/sudoers/toke.l,
+ plugins/sudoers/toke_util.c:
+ Split tokenizer utility functions out into toke_util.c
+ [89a97bd51618]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ ANSIfy
+ [ca0eba1dfaa9]
+
+2011-01-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST:
+ sync
+ [a43f94064bb3]
+
+ * plugins/sudoers/Makefile.in:
+ Add visudo tests to check target
+ [8c82fb4ed40f]
+
+ * compat/Makefile.in, compat/regress/fnmatch/fnm_test.c,
+ compat/regress/fnmatch/fnm_test.in, compat/regress/glob/files,
+ compat/regress/glob/globtest.c, compat/regress/glob/globtest.in:
+ Add my regress tests for fnmatch() and glob() from OpenBSD.
+ [6e8c1f211723]
+
+ * plugins/sudoers/regress/testsudoers/test1.sh,
+ plugins/sudoers/regress/visudo/test1.ok,
+ plugins/sudoers/regress/visudo/test1.sh:
+ Add regress test for command tags using visudo -c
+ [18b0ef207c0f]
+
+ * plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/testsudoers/test1.ok,
+ plugins/sudoers/regress/testsudoers/test1.sh:
+ Add support for regress tests using testsudoers
+ [1fa94bd2671b]
+
+ * plugins/sudoers/testsudoers.c:
+ Need to set user_name explicitly due to internal changes made when
+ converting sudoers to a plugin.
+ [1fa54e86a364]
+
+2011-01-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, Makefile.in, common/Makefile.in, compat/Makefile.in,
+ doc/Makefile.in, include/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/sudoers/regress/iolog_path/check_iolog_path.c,
+ plugins/sudoers/regress/iolog_path/data, src/Makefile.in,
+ zlib/Makefile.in:
+ Add regression tests for iolog_path()
+ [afa4b416e559]
+
+ * Makefile.in, common/Makefile.in, compat/Makefile.in,
+ doc/Makefile.in, include/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ src/Makefile.in, zlib/Makefile.in:
+ Add support for "make Makefile" to regenerate Makefile from
+ Makefile.in
+ [98bd2dda3294]
+
+ * plugins/sudoers/iolog_path.c:
+ Quiest a bogus compiler warning.
+ [5ff932a7ad67]
+
+2011-01-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog_path.c:
+ Protect call to setlocale() with HAVE_SETLOCALE
+ [2c29ee3ccc81]
+
+2011-01-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST:
+ mkstemps.c was renamed mktemp.c
+ [ae299c3b1827]
+
+ * NEWS:
+ Update from 1.7 branch
+ [20817d79717b]
+
+ * Makefile.in:
+ Use "mv -f" when regenerating ChangeLog
+ [c163635206c6]
+
+ * plugins/sudoers/match.c:
+ Fix NULL dereference with "sudo -g group" when the sudoers rule has
+ no runas user or group listed. Fixes RedHat bug Bug 667103.
+ [41a6a1243d9e]
+
+2011-01-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Correct the default sudo.conf example
+ [4e791698cad1]
+
+2010-12-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog_path.c:
+ Reset slashp if we allocate a new buffer for strftime()
+ [e491daa4203b]
+
+ * plugins/sudoers/iolog_path.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Add extra out parameter to expand_iolog_path() to allow the caller
+ to split the path into dir and file components if needed.
+ [88346bc5ae39]
+
+2010-12-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ mkdir_iopath() returns size_t now that it uses strlcpy() and not
+ snprintf()
+ [3c4c64d265eb]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c:
+ Trim leading slashes from iolog_file and trailing slashes from
+ iolog_dir
+ [a803b51f8948]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod,
+ plugins/sudoers/iolog.c, plugins/sudoers/iolog_path.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Pass a single I/O log file name in command_details instead of
+ separate dir + file parameters.
+ [d672a3e46e80]
+
+ * plugins/sudoers/sudoreplay.c:
+ change an error() to errorx()
+ [8013dcfdd69d]
+
+ * plugins/sudoers/iolog.c:
+ Add missing cwd line to I/O log info file that got dropped when
+ iolog_deserialize_info() was added
+ [7cf84f208423]
+
+2010-12-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Avoid relying on globals filled in by the sudoers policy module for
+ the sudoers I/O log module. The I/O log open function now pulls the
+ bits it needs out of user_info and command_info.
+ [c02f6951b0cc]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ If no iolog file is specified by the policy plugin, use io_nextid()
+ to determine the next file in the sequence.
+ [faa1130b1020]
+
+2010-12-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Document iolog_compress in command_info
+ [58895c7d12f5]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/sudoers.c:
+ Add support for the iolog_compress variable in command_info.
+ [36f13a2fd1c1]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/sudoers.c:
+ Add sigsetjmp() calls to all plugin entry points just to be safe.
+ [3fa482355bc4]
+
+ * src/sudo.c, src/sudo.h:
+ Don't need iolog variables in struct command_details, they are for
+ the I/O log plugins to handle.
+ [5111579ffd9d]
+
+2010-12-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod:
+ Document use of mkdtemp() for iolog path teplates
+ [5db6101408a9]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo_plugin.cat,
+ doc/sudo_plugin.man.in, doc/sudoers.cat, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/sudoers.man.in, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/visudo.cat, doc/visudo.man.in:
+ regen
+ [1ee11fd6d4eb]
+
+ * doc/sudo_plugin.pod, doc/sudoers.pod:
+ Document iolog_file and supported escape sequences for sudoers.
+ Clarify that iolog_file can contain directories.
+ [da611dedcbdb]
+
+ * compat/Makefile.in, configure, configure.in:
+ Fix building of mkstemps/mkdtemp replacements.
+ [793a5e303122]
+
+ * compat/mkstemps.c, compat/mktemp.c, config.h.in, configure,
+ configure.in, include/missing.h:
+ Provide mkdtemp() for systems without it.
+ [b0527dfa965c]
+
+ * plugins/sudoers/iolog_path.c:
+ Fix typo
+ [277f6c514cba]
+
+ * plugins/sudoers/iolog.c:
+ Only use mkdtemp() if the path ends in at least 6 Xs since otherwise
+ glibc mkdtemp() returns EINVAL.
+ [2e7323b05579]
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in,
+ plugins/sudoers/defaults.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/iolog_path.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Allow sudoers to specify the iolog file in addition to the iolog
+ dir. Add escape sequence support to iolog file and dir: sequence
+ number, user, group, runas_user, runas_group, hostname and command
+ in addition to any escape sequence recognized by strftime(3).
+ [75cd32ee0435]
+
+ * plugins/sudoers/iolog.c:
+ Add missing sigsetjmp() call in I/O plugin open function. Fixes a
+ crash when the I/O plugin calls error(), errorx() or log_error().
+ [1a6718bd817d]
+
+2010-12-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo_plugin.pod, plugins/sudoers/iolog.c,
+ plugins/sudoers/sudoers.c:
+ Give the policy module fine-grained control over what the I/O plugin
+ logs.
+ [d29784fd2a66]
+
+ * common/term.c:
+ Clear OPOST from c_oflag like we used to. Fixes screen-based editors
+ such as vi.
+ [506ad5ae9b4e]
+
+ * doc/sudoers.pod:
+ Clarify umask option description. From Reuben Thomas.
+ [1294ac84222b]
+
+2010-12-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.ldap.pod, plugins/sudoers/ldap.c:
+ Pick last match in LDAP sudoers too
+ [fbfd8e85703b]
+
+ * doc/sudo_plugin.pod:
+ Document iolog_file, iolog_dir and use_pty
+ [26120a59c20e]
+
+ * plugins/sample/sample_plugin.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/sudoers.c:
+ Adapt plugins to version I/O logging ABI 1.1
+ [880dd64bc1e8]
+
+ * src/exec.c, src/sudo.h:
+ Add use_pty command_info flag for policies to indicate that a pty
+ should be allocated even if no I/O logging is performed.
+ [e7b167f8a6e5]
+
+ * src/sudo.c:
+ Add remaining plugin convenience functions
+ [ffeaf96da031]
+
+ * include/sudo_plugin.h, src/sudo.c, src/sudo.h,
+ src/sudo_plugin_int.h:
+ Change I/O log API to pass in command info to the I/O log open
+ function. Add iolog_file and iolog_dir parameters to command info.
+ This allows the policy plugin to specify the I/O log pathname. Add
+ convenience functions for calling plugin functions that handle ABI
+ backwards compatibility.
+ [9b81dce76ce5]
+
+ * compat/dlopen.c:
+ Remove useless cast
+ [7cecce969739]
+
+2010-12-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Bump version to 1.8.0b3
+ [1dc9f040aae0]
+
+2010-12-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ Remove extraneous newline
+ [71c94551eea5]
+
+2010-12-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.pod, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in,
+ plugins/sudoers/defaults.c, plugins/sudoers/iolog.c:
+ Make I/O log dir configurable.
+ [99b576667a38]
+
+ * aclocal.m4, configure, configure.in, doc/sudoers.pod:
+ Rename io_logdir to iolog_dir
+ [0731662acc8d]
+
+2010-12-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pp:
+ Add missing '*' that prevented the generic ELF case from matching.
+ [be77ca26bfb2]
+
+ * pp:
+ If file(1) can't identify the ELF binary type, try readelf(1).
+ [38a18d32a9e3]
+
+2010-11-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/kerb4.c, plugins/sudoers/check.c,
+ plugins/sudoers/env.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/sudoers.c, src/sudo.c:
+ Use %u to print uid/gid, not %lu and adjust casts to match.
+ [03c43b8749cf]
+
+ * doc/sudoers.ldap.pod:
+ Clarify ordering of entries and attributes.
+ [924e2a6bb603]
+
+ * doc/sudoers.ldap.pod:
+ Fix typo and editing goof.
+ [79dc7ccd85a8]
+
+ * doc/schema.ActiveDirectory, doc/schema.OpenLDAP, doc/schema.iPlanet,
+ doc/sudoers.ldap.pod:
+ Merge in ordered LDAP entry support from Andreas Mueller.
+ [ea5885989bad]
+
+ * plugins/sudoers/ldap.c:
+ Make sure we don't dereference a NULL handle.
+ [1a9f9ee15371]
+
+2010-11-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pp:
+ Add support for RHEL 6 file modes that include a trailing dot on
+ files with an SELinux security context
+ [dc09be959547]
+
+2010-11-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo.c:
+ exec_setup() does not need to setuid(0), the Ubuntu issue was in the
+ sudoers module.
+ [d6dd99fc6062]
+
+ * plugins/sudoers/sudoers.c:
+ create_admin_success_flag() should use restore_perms() rather than
+ set_perms() to restore the uid.
+ [eba7a91c1f57]
+
+ * src/sudo.c:
+ In exec_setup() call setuid(0) to make certain the subsequent uid
+ and gid changes will succeed. Fixes a problem on Ubuntu.
+ [c5d32abf0645]
+
+ * src/sudo_edit.c:
+ Error out if we cannot change to root's uid so we catch the failure
+ early.
+ [7a2e7f8f2c80]
+
+2010-11-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.pod:
+ fix typo; from Michael T Hunter
+ [a574a9d0db5b]
+
+ * plugins/sudoers/match.c:
+ In sudoedit mode, assume command line arguments are paths and pass
+ FNM_PATHNAME to fnmatch().
+ [ce0abff8ce9f]
+
+2010-11-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Add workaround for an error in sys/types.h on HP-UX 11.23 when large
+ file support is enabled. Defining _XOPEN_SOURCE_EXTENDED avoids the
+ broken bits of the header file.
+ [e337217f097a]
+
+ * aclocal.m4:
+ Fix SUDO_MAILDIR usage of AC_LANG_PROGRAM
+ [fbbcee28961f]
+
+ * sudo.pp:
+ For Tru64, strip off beta version.
+ [eeccd762df5e]
+
+ * MANIFEST, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/tsgetgrpw.c, plugins/sudoers/tsgetgrpw.h:
+ Avoid conflicts with system definitions in grp.h and pwd.h
+ [b219ffe1da09]
+
+ * zlib/gzguts.h:
+ Include stdio.h after zlib.h, not before. We need the large file
+ defines to come first.
+ [21d6df39790f]
+
+2010-11-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in:
+ regen
+ [3ff8750d0aac]
+
+ * Makefile.in:
+ Don't clean ChangeLog
+ [ab0d30d289d4]
+
+ * plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ Add prototype for cleanup()
+ [75626fd3769a]
+
+2010-11-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/group_plugin.c:
+ Avoid deferencing group_plugin if it is NULL in
+ group_plugin_query(). This should not happen.
+ [4f2933c8da7e]
+
+ * plugins/sudoers/group_plugin.c:
+ group plugin init function return TRUE when successful
+ [198024477030]
+
+2010-11-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Enlarge the array of entry wrappers int blocks of 100 entries to
+ save on allocation time. From Andreas Mueller
+ [375c916bb03b]
+
+ * plugins/sudoers/ldap.c:
+ Add back call to sudo_ldap_timefilter() in sudo_ldap_build_pass2()
+ that was mistakenly dropped.
+ [1555f5bc132d]
+
+2010-11-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/TROUBLESHOOTING:
+ Mention that sudo needs "ar" to build.
+ [65582ace2d09]
+
+ * configure, configure.in:
+ Fail with a more useful error if "ar" is not found.
+ [d1cb83719c17]
+
+2010-11-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Merge in ordered LDAP entry support from Andreas Mueller and add
+ local changes from the 1.7 branch.
+ [bca29e461618]
+
+2010-11-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/schema.ActiveDirectory, doc/schema.OpenLDAP, doc/schema.iPlanet,
+ doc/sudoers.ldap.pod, plugins/sudoers/ldap.c:
+ Add timed entry support from Andreas Mueller.
+ [e18d1df46a8d]
+
+ * plugins/sudoers/group_plugin.c:
+ Don't try to unload if group_plugin is NULL. Don't call dlclose() if
+ group_handle is NULL
+ [de2273da37d5]
+
+ * plugins/sudoers/sudoers.h:
+ It is now plugin_cleanup(), not cleanup()
+ [da62a4e1a78c]
+
+ * plugins/sudoers/logging.c, plugins/sudoers/sudoers.c:
+ Call plugin_cleanup(), not cleanup()
+ [e800ad8b33ad]
+
+2010-11-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Use efree() not free() and remove malloc.h include since we never
+ directly call malloc() or free().
+ [107fffd134bb]
+
+2010-11-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ set PSTAMP for Solaris and move the backend-specific bits to their
+ own %if [xxx] %endif blocks in %set.
+ [a94ebe8920c1]
+
+ * pp:
+ sync with git repo
+ [75ff509696b4]
+
+ * configure, configure.in:
+ Only substitute file zlib files when using the builtin zlib
+ [6c8145b2deb4]
+
+ * common/Makefile.in, compat/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ src/Makefile.in, zlib/Makefile.in:
+ Give up on using VPATH to find sources as it is implemented
+ inconsistenly in different versions of make.
+ [60517c69aaee]
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/getdate.c,
+ plugins/sudoers/gram.c, plugins/sudoers/toke.c:
+ Include config.h before any other includes to make sure we get the
+ right value for _FILE_OFFSET_BITS.
+ [8fb007ca832e]
+
+ * MANIFEST:
+ Add zlib
+ [04a3e23dfaa9]
+
+ * zlib/Makefile.in:
+ Add missing targets
+ [40e45a177168]
+
+ * src/Makefile.in:
+ g/c unused $(GENERATED)
+ [c8758068c1bc]
+
+2010-11-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/group_plugin.c:
+ Zero out group_plugin on unload just to be safe.
+ [0b10f4d101ca]
+
+ * plugins/sudoers/group_plugin.c:
+ Unload group plugin if its init function fails.
+ [6552cdac4b7c]
+
+ * src/sudo.c:
+ Only chdir to cwd if it is different from the current cwd or there
+ is a new root (chroot).
+ [b8203e875e84]
+
+ * configure, configure.in, doc/sudo.cat, doc/sudo.man.in,
+ doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudoers.ldap.cat,
+ doc/sudoers.ldap.man.in, doc/visudo.cat, doc/visudo.man.in:
+ Bump version to 1.8.0b2
+ [6dadeb75a878]
+
+2010-10-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ Better --enable-zlib description
+ [e0da54fa59a6]
+
+ * mkpkg:
+ Use system zlib on Linux Let configure decide on Solaris For all
+ others, use builtin zlib
+ [3d52eddb523c]
+
+ * zlib/zconf.h.in:
+ Add large file support.
+ [bec01215270d]
+
+ * config.h.in:
+ Add large file support.
+ [244e95b034ec]
+
+ * Makefile.in, configure, configure.in, doc/LICENSE, doc/license.pod,
+ zlib/Makefile.in, zlib/adler32.c, zlib/compress.c, zlib/crc32.c,
+ zlib/crc32.h, zlib/deflate.c, zlib/deflate.h, zlib/gzclose.c,
+ zlib/gzguts.h, zlib/gzlib.c, zlib/gzread.c, zlib/gzwrite.c,
+ zlib/infback.c, zlib/inffast.c, zlib/inffast.h, zlib/inffixed.h,
+ zlib/inflate.c, zlib/inflate.h, zlib/inftrees.c, zlib/inftrees.h,
+ zlib/trees.c, zlib/trees.h, zlib/uncompr.c, zlib/zconf.h.in,
+ zlib/zlib.h, zlib/zutil.c, zlib/zutil.h:
+ Add local copy of zlib for systems that lack it.
+ [7542ca465c5a]
+
+2010-10-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ If perform_io() fails, kill the child before exiting so it doesn't
+ complain about connection reset. We can get an I/O error if, for
+ example, and we get EIO reading from stdin.
+ [e59a05fa729f]
+
+2010-10-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c, src/sudo.c:
+ Fix complilation on systems with set_auth_parameters() Sprinkle
+ volatile to quiet warnings from gcc 2.8.0
+ [a34c2b924ba7]
+
+ * compat/dlfcn.h, compat/dlopen.c:
+ Avoid potential namespace issues with dlopen() emulation.
+ [aedfababd6ca]
+
+ * MANIFEST:
+ sync
+ [6afb97e6d308]
+
+ * plugins/sudoers/interfaces.c:
+ Use INADDR_NONE instead of casting -1 to in_addr_t (which may not
+ exist).
+ [ddfca5af1a36]
+
+ * Makefile.in:
+ Mark ChangeLog as PHONY Don't overwrite ChangeLog if we can't run hg
+ [e9d04bfa4505]
+
+ * configure, configure.in:
+ HP-UX 10.20 libc has an incompatible getline
+ [2e7bc202e78d]
+
+ * plugins/sudoers/visudo.c:
+ Quiet an HP-UX compiler warning.
+ [55b9d587ac8c]
+
+ * configure, configure.in:
+ Check for vi even with --with-editor specified; the sample plugin
+ needs it.
+ [94dfc3643f76]
+
+2010-10-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/dlopen.c:
+ Fix remaining syntax errors.
+ [9d729b5b577e]
+
+ * src/Makefile.in:
+ sudo binary depends on the libtool-generated libs
+ [9e6148406adb]
+
+ * plugins/sudoers/group_plugin.c, src/load_plugins.c:
+ Use HAVE_DLOPEN instead of HAVE_DLFCN_H when determining whether to
+ include the local or system dlfcn.h
+ [68cfe4c1089b]
+
+ * pp:
+ Don't use run_as_superuser=false on HP-UX
+ [532242370b09]
+
+ * src/net_ifs.c:
+ Use memset() instead of zero_bytes() since we don't include
+ sudoers.h
+ [a187c18c2472]
+
+ * plugins/sudoers/interfaces.c:
+ Fix pasto; AF_INET not AF_INET6
+ [2d2e9d7dc6f9]
+
+ * compat/dlopen.c:
+ Actually call shl_load()
+ [ed8153b8a3cd]
+
+ * pp:
+ Update from git repo. Debian: version numbers now compliant with
+ policy section 5.6.12 HP-UX: minimal changes needed to work on HP-UX
+ 10.20
+ [ecf2692bceeb]
+
+ * configure, configure.in:
+ Fix dlopen() detection for systems where dlopen() is in a separate
+ library.
+ [fa6b175582b6]
+
+ * plugins/sudoers/auth/pam.c:
+ If pam_acct_mgmt() returns PAM_AUTH_ERR print a (hopefully) more
+ useful message and return AUTH_FATAL so sudo does not keep trying to
+ validate the user.
+ [1be8857e5291]
+
+ * src/preload.c:
+ sudo_preload_table is an array
+ [b7704e72a9da]
+
+ * compat/dlopen.c:
+ Quiet a compiler warning and fix sudo_preload_table external
+ definition.
+ [8234987664cc]
+
+ * compat/dlfcn.h:
+ Fix multiple inclusion guard in dlfcn.h and fix dlerror() prototype.
+ [8bab6a4053cc]
+
+ * plugins/sudoers/group_plugin.c:
+ Make this compile correctly when no dlopen is available.
+ [57643879bd2b]
+
+2010-10-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c:
+ Having a timestamp file defined is no longer indicative of tty
+ tickets being enabled. Check def_tty_tickets directly.
+ [efcc11ad157f]
+
+ * src/exec_pty.c, src/sudo.h, src/ttysize.c:
+ Fix TCGETWINSZ compat.
+ [da3a8b17cf7a]
+
+2010-10-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c, src/ttysize.c:
+ Prefer newer TIOCGWINSZ ioctl to old TIOCGSIZE
+ [926492dd10a6]
+
+2010-10-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c, src/sudo.c:
+ Move set_project() from sudoers module into sudo proper.
+ [beabafac03b4]
+
+ * configure, configure.in:
+ Fix typo and regenerate
+ [4a3caf4234f3]
+
+ * plugins/sudoers/ldap.c:
+ When iterating over returned LDAP entries, keep looking at remaining
+ matches even if we have a positive match. This catches negative
+ matches that may exist in other entries and more closely match the
+ sudoers file behavior.
+ [f47db6e609b0]
+
+ * pp:
+ Add support for multiple package instances on Solaris.
+ [7f2a8b942545]
+
+ * src/exec.c:
+ Add missing signal_pipe[0] to fdsr for the non-pty case.
+ [79d01e11b19c]
+
+ * mkpkg:
+ Add --with-project for Solaris
+ [ffa4c2bb93f7]
+
+ * README:
+ Need ar and ranlib too
+ [5c2f679172ef]
+
+2010-09-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/env.c:
+ Preserve ODMDIR environment variable by default on AIX.
+ [bd47cb1e804f]
+
+2010-09-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, compat/Makefile.in, compat/dlfcn.h, compat/dlopen.c,
+ config.h.in, configure, configure.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ plugins/sudoers/group_plugin.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/sudoers.c, src/Makefile.in, src/load_plugins.c,
+ src/preload.c:
+ Add dlopen() emulation for systems without it. For HP-UX 10, emulate
+ using shl_load(). For others, link sudoers plugin statically and use
+ a lookup table to emulate dlsym().
+ [e92edfb3c642]
+
+2010-09-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/fnmatch.c, compat/glob.c, compat/mksiglist.c,
+ compat/nanosleep.c, compat/utimes.c:
+ When including compat headers, use the compat dir as part of the
+ path so we are sure to get the correct header.
+ [6c2a45da6af5]
+
+2010-09-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/linux_audit.c:
+ Ignore ECONNREFUSED from audit_log_user_command() which will occur
+ if auditd is not running.
+ [d314fe4c8d03]
+
+2010-09-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pp:
+ Sync with git version
+ [1c0357744222]
+
+2010-09-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/fileops.c, plugins/sudoers/defaults.c:
+ Cast isblank argument to unsigned char.
+ [c822dbb3ca54]
+
+2010-09-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, config.h.in, configure, configure.in, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.pod, plugins/sudoers/defaults.c:
+ Implement --with-umask-override configure flag.
+ [863e3047df22]
+
+ * plugins/sudoers/env.c:
+ Take MODE_LOGIN_SHELL into account when initially setting reset_home
+ instead of special-casing it later.
+ [5d6b16480fd6]
+
+ * plugins/sudoers/sudoers.c:
+ In login mode, make a copy of the runas user's pw_shell for
+ NewArgv[0] because 1) we modify it and 2) it will runas_pw gets
+ freed before exec.
+ [1d1ccb568dfa]
+
+ * plugins/sudoers/env.c:
+ Reset HOME for "sudo -i" even if HOME was listed in env_keep.
+ [c1c1c65a2d63]
+
+ * src/sudo.c:
+ Use SIG_SETMASK when resetting signal mask instead of SIG_UNBLOCK.
+ [7443454e5f88]
+
+ * src/sudo.c:
+ Reset signal mask at sudo startup time; we need to be able to rely
+ on normal signal delivery to control the child process.
+ [95800163ff94]
+
+2010-09-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * install-sh:
+ Use sed instead of expr to split a flag from its argument. Fixes a
+ problem with expr interpreting its arguments as a flag when they
+ start with a dash.
+ [736065e14301]
+
+ * common/lbuf.c:
+ Do not need sys/time.h after all
+ [91f6f668ccda]
+
+ * common/lbuf.c:
+ Include sys/time.h for utimes() and struct timeval. No longer need
+ ioctl.h or termios.h
+ [2d75273d3213]
+
+ * compat/snprintf.c:
+ Quiet bogus compiler warnings.
+ [fe252e1968f5]
+
+ * include/missing.h:
+ Declare innetgr() for HP-UX which is missing a declaration. Declare
+ domainname() for HP-UX and Solaris which are missing a declaration.
+ [b37c50751138]
+
+ * plugins/sudoers/bsm_audit.c:
+ Use __sun for consistency with the rest of the sources.
+ [6b086b61ccb6]
+
+ * plugins/sudoers/group_plugin.c:
+ Quiet a bogus compiler warning.
+ [ebc069842c4a]
+
+ * plugins/sudoers/pwutil.c:
+ Don't try to delref a NULL group.
+ [f6ff0838be21]
+
+ * common/alloc.c, common/lbuf.c:
+ Include memory.h on systems that need it.
+ [4e676da81c6f]
+
+2010-09-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ Quiet gcc warnings on glibc systems that use warn_unused_result for
+ write(2).
+ [0532da0b7cf7]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod:
+ sudo_plugin is in section 8; from Ted Percival
+ [b4506a0de87e]
+
+ * plugins/sudoers/Makefile.in:
+ testsudoers depends on libsudoers.la, not sudoreplay
+ [cdb1cc3bf06a]
+
+2010-09-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ Read as many signals on the signal pipe as we can before returning.
+ [b181671da047]
+
+ * src/exec.c, src/exec_pty.c, src/sudo_exec.h:
+ Instead of using a array to store received signals, open a pipe and
+ have the signal handler write the signal number to one end and
+ select() on the other end. This makes it possible to handle signals
+ similar to I/O without race conditions.
+ [ee84d65c16b6]
+
+2010-09-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/visudo.pod, plugins/sudoers/visudo.c:
+ Make "visudo -c -f -" check the standard input.
+ [195a3d2a9a26]
+
+ * doc/sudoers.pod:
+ set_home and always_set_home have an effect if HOME is present in
+ the env_keep list.
+ [159d0b9dc5c8]
+
+ * plugins/sudoers/env.c:
+ Make -H flag work when HOME is listed in env_keep. Also makes
+ "set_home" and "always_set_home" override override HOME in env_keep.
+ [a3e5b966193f]
+
+2010-09-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/interfaces.c,
+ plugins/sudoers/interfaces.h, plugins/sudoers/match.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c, src/net_ifs.c:
+ Convert sudoers plugin to use interface list passed in settings.
+ [87d9b5f4f586]
+
+ * doc/sudo_plugin.pod, src/Makefile.in, src/net_ifs.c,
+ src/parse_args.c, src/sudo.h:
+ Query local network interfaces in the main sudo driver and pass to
+ the plugin as "network_addrs" in the settings list.
+ [7f35bcfe77a7]
+
+ * plugins/sudoers/bsm_audit.c:
+ Solaris BSM audit return EINVAL when auditing is not enabled,
+ whereas OpenBSM returns ENOSYS.
+ [411b980ec58b]
+
+2010-09-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/fnmatch.c:
+ missing.h should come before most local includes
+ [53921a7b8b5b]
+
+ * plugins/sudoers/sudoreplay.c:
+ missing.h should come before most local includes
+ [e9abb0db1aac]
+
+ * plugins/sudoers/sudoers.h:
+ Make local includes consistent; use double quotes for local includes
+ except for generated ones where we use angle brackets.
+ [09de4faa9547]
+
+ * plugins/sudoers/sudoers.c:
+ Always fill in NewArgv for audit code.
+ [7c3aca60519f]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Add missing LOG_INPUT/LOG_OUTPUT support in the lexer.
+ [007cf6560f92]
+
+ * common/alloc.c, common/atobool.c, common/fileops.c,
+ common/fmt_string.c, common/lbuf.c, common/list.c, common/term.c,
+ common/zero_bytes.c, compat/closefrom.c, compat/fnmatch.c,
+ compat/getcwd.c, compat/getgrouplist.c, compat/getline.c,
+ compat/getprogname.c, compat/glob.c, compat/isblank.c,
+ compat/memrchr.c, compat/mksiglist.c, compat/mkstemps.c,
+ compat/nanosleep.c, compat/setenv.c, compat/snprintf.c,
+ compat/strlcat.c, compat/strlcpy.c, compat/strsignal.c,
+ compat/unsetenv.c, compat/utimes.c, include/compat.h,
+ plugins/sample/sample_plugin.c, plugins/sample_group/getgrent.c,
+ plugins/sample_group/plugin_test.c,
+ plugins/sample_group/sample_group.c, plugins/sudoers/audit.c,
+ plugins/sudoers/auth/afs.c, plugins/sudoers/boottime.c,
+ plugins/sudoers/getdate.c, plugins/sudoers/getdate.y,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/match.c,
+ plugins/sudoers/plugin_error.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/timestr.c, src/error.c, src/sesh.c, src/sudo.h,
+ src/sudo_noexec.c, src/ttysize.c:
+ Make local includes consistent; use double quotes for local includes
+ except for generated ones where we use angle brackets. Also g/c
+ unused compat.h.
+ [e57070dc8f04]
+
+2010-09-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/match.c:
+ When matching the runas user and runas group (-u and -g command line
+ options), keep track of runas group and runas user matches
+ separately. Only return a positive match if we have a match for both
+ runas user and runas group (if specified).
+ [815219e04cc8]
+
+2010-09-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.ldap.pod, plugins/sudoers/ldap.c:
+ Add support for multiple URI lines by joining the contents and
+ passing the result to ldap_initialize.
+ [a47cae3b72e8]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/parse.c:
+ Do not return -1 on error from the display functions; the caller
+ expects a return value >= 0.
+ [101456a7dd00]
+
+ * plugins/sudoers/sudoers.c:
+ Do not set both MODE_EDIT and MODE_RUN
+ [8faa36694d54]
+
+2010-09-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/missing.h:
+ Move includes to the top of the file.
+ [a51436798e8c]
+
+2010-08-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ Add missing definition of timedir
+ [458a749c2c5e]
+
+ * compat/fnmatch.c, compat/getprogname.c, compat/isblank.c,
+ compat/mksiglist.c, compat/strsignal.c,
+ plugins/sudoers/plugin_error.c, src/error.c, src/sudo_noexec.c:
+ Add #include of sys/types.h for .c files that include missing.h to
+ be sure that size_t and ssize_t are defined.
+ [08e3132dbf4f]
+
+ * plugins/sudoers/Makefile.in:
+ Install sudoers file from the build dir not hte src dir.
+ [ca89e962dbf4]
+
+2010-08-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/set_perms.c:
+ If runas_pw changes, reset the stashed runas aux group vector.
+ Otherwise, if runas_default is set in a per-command Defaults
+ statement, the command runs with root's aux group vector (i.e. the
+ one that was used when locating the command).
+ [24f9107cedd2]
+
+ * plugins/sudoers/Makefile.in:
+ Add target to generate sudoers file Remove generated sudoers file as
+ part of distclean
+ [fb7422e90f03]
+
+2010-08-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c:
+ When not logging I/O install a handler for SIGCONT and deliver it to
+ the command upon resume. Fixes bugzilla #431
+ [495dce52a5aa]
+
+2010-08-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.h:
+ g/c unused auth_pw extern definition
+ [40eb7477ba17]
+
+ * plugins/sudoers/check.c, plugins/sudoers/sudoers.c:
+ Move get_auth() into check.c where it is actually used.
+ [e31db0ce3a61]
+
+2010-08-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * common/lbuf.c:
+ Convert a remaining puts() and putchar() to use the output function.
+ [d69e363a506b]
+
+ * plugins/sudoers/plugin_error.c:
+ Plug memory leak
+ [68895469ea8d]
+
+2010-08-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/env.c:
+ Set dupcheck to TRUE when setting new HOME value if !env_reset but
+ always_set_home is true. Prevents a duplicate HOME in the
+ environment (old value plus the new one) introduced in f421f8827340.
+ [9ca19183794f]
+
+ * configure, configure.in, plugins/sudoers/sudoers,
+ plugins/sudoers/sudoers.in:
+ Substitute sysconfdir in the installed sudoers file to get the
+ correct path for sudoers.d.
+ [86072b6cd55d]
+
+2010-08-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/get_pty.c:
+ Fix typo that prevented compilation on Irix; Friedrich Haubensak
+ [b48be51b65fc]
+
+2010-08-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/Makefile.in, common/aix.c, common/alloc.c,
+ common/atobool.c, common/fileops.c, common/fmt_string.c,
+ common/lbuf.c, common/list.c, common/term.c, common/zero_bytes.c,
+ compat/Makefile.in, compat/closefrom.c, compat/fnmatch.c,
+ compat/getcwd.c, compat/getgrouplist.c, compat/getline.c,
+ compat/getprogname.c, compat/glob.c, compat/isblank.c,
+ compat/memrchr.c, compat/mksiglist.c, compat/mkstemps.c,
+ compat/nanosleep.c, compat/setenv.c, compat/snprintf.c,
+ compat/strlcat.c, compat/strlcpy.c, compat/strsignal.c,
+ compat/unsetenv.c, compat/utimes.c, include/compat.h,
+ include/missing.h, plugins/sample/sample_plugin.c,
+ plugins/sample_group/getgrent.c,
+ plugins/sample_group/sample_group.c, plugins/sudoers/Makefile.in,
+ plugins/sudoers/audit.c, plugins/sudoers/boottime.c,
+ plugins/sudoers/getdate.c, plugins/sudoers/getdate.y,
+ plugins/sudoers/linux_audit.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/timestr.c, src/Makefile.in, src/error.c, src/sesh.c,
+ src/sudo.h, src/sudo_noexec.c, src/ttysize.c:
+ Merge compat.h and missing.h into missing.h
+ [572909ae9716]
+
+2010-08-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/pam.c:
+ If the user hits ^C while a password is being read, error out before
+ reading any further passwords in the pam conversation function.
+ Otherwise, if multiple PAM auth methods are required, the user will
+ have to hit ^C for each one.
+ [23782631748c]
+
+2010-08-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c:
+ Update comment
+ [a5296cb3a20a]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Document sudo_conv_t function and sudo_printf_t return values.
+ [745c0017814c]
+
+ * src/conversation.c:
+ Make _sudo_printf return the number of characters printed on success
+ like printf(3).
+ [8eeefe8d7e77]
+
+2010-08-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ sudoers.h includes sudo_plugin.h for us
+ [cabe68e07807]
+
+ * common/Makefile.in, common/gettime.c, compat/mkstemps.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/visudo.c, src/sudo.h,
+ src/sudo_edit.c:
+ Use gettimeofday() directly instead of via the gettime() wrapper.
+ [7490426c99ae]
+
+ * common/gettime.c, compat/snprintf.c, compat/strcasecmp.c,
+ compat/strerror.c, config.h.in, configure, configure.in,
+ include/compat.h, include/missing.h, plugins/sudoers/logging.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/visudo.c, src/sudo.c:
+ Remove some obsolete configure tests, ancient Unix systems are no
+ longer supported.
+ [2be6218c3a36]
+
+2010-08-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Set pp_kit_version and strip off patch level
+ [aacfda1b676d]
+
+ * sudo.pp:
+ Better handling of versions with a patchlevel. For rpm and deb, use
+ the patchlevel+1 as the release. For AIX, use the patchlevel as the
+ 4th version number. For the rest, just leave the patchlevel in the
+ version string.
+ [638bd35f2346]
+
+2010-08-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/sudo_auth.c:
+ For non-standalone auth methods, stop reading the password if the
+ user enters ^C at the prompt.
+ [82c2911bb264]
+
+ * configure, configure.in, plugins/sudoers/Makefile.in,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/secureware.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/auth/sudo_auth.h,
+ plugins/sudoers/pwutil.c:
+ No need to look up shadow password unless we are doing password-
+ style authentication. This moves the shadow password lookup to the
+ auth functions that need it.
+ [ba9e3eba2b72]
+
+ * plugins/sudoers/sudoers.c:
+ Retain final passwd/group refs until the policy close() function.
+ Note that this doesn't get called in all cases so putting this in a
+ cleanup function is probably better.
+ [bbe214cb4119]
+
+ * plugins/sudoers/check.c:
+ Fix mismerge
+ [395115f89dd6]
+
+ * plugins/sudoers/check.c:
+ When removing/resetting the timestamp file ignore the tty ticket
+ contents.
+ [b709f5667a0b]
+
+ * plugins/sudoers/sudoers.c:
+ delref sudo_user.pw, runas_pw and runas_gr immediately before we
+ return.
+ [4d67d15dfd3b]
+
+2010-08-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/match.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Reference count cached passwd and group structs. The cache holds one
+ reference itself and another is added by sudo_getgr{gid,nam} and
+ sudo_getpw{uid,nam}. The final ref on the runas and user passwd and
+ group structs are persistent for now.
+ [e544685523c3]
+
+ * doc/UPGRADE:
+ fix typo
+ [e32f2d35e6c9]
+
+2010-08-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c:
+ Do not produce a warning for "sudo -k" if the ticket file does not
+ exist.
+ [1598f6061b75]
+
+ * plugins/sudoers/pwutil.c:
+ Instead of caching struct passwd and struct group in the red-black
+ tree, store a struct cache_item which includes both the key and
+ datum. This allows us to user the actual name that was looked up as
+ the key instead of the contents of struct passwd or struct group.
+ This matters because the name in the database may not match what we
+ looked up, due either to case folding or truncation (historically at
+ 8 characters). Also mark the disabled calls to sudo_freepwcache()
+ and sudo_freegrcache() as broken since we use cached data for things
+ like set_perms() and the logging functions. Fixing this would
+ require making a copy of the structs for user and runas or adding a
+ reference count (better).
+ [225d4a22f60e]
+
+ * plugins/sudoers/Makefile.in:
+ Fix path to mkinstalldirs
+ [b4968379b12d]
+
+ * plugins/sudoers/check.c, plugins/sudoers/logging.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/visudo.c,
+ src/exec_pty.c, src/get_pty.c, src/tgetpass.c:
+ Quiet gcc warnings on glibc systems that use warn_unused_result for
+ write(2) and others.
+ [c99f138960e0]
+
+2010-08-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Add %option noinput
+ [72b9cd49b4f1]
+
+ * aclocal.m4, configure, configure.in:
+ Add cross-compile defaults for remaining AC_TRY_RUN usage. Also add
+ back getgroups() check since AC_FUNC_GETGROUPS defaults to "no" when
+ cross-compiling.
+ [e385c176d0ee]
+
+2010-07-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4, compat/snprintf.c, config.h.in, configure, configure.in:
+ Use AC_CHECK_MEMBER in SUDO_SOCK_SA_LEN Use AC_TYPE_LONG_LONG_INT
+ and AC_CHECK_SIZEOF([long int]) instead of rolling our own.
+ [cf3e60d9c440]
+
+2010-07-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pp:
+ Update to latest version
+ [32f93be33961]
+
+2010-07-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Let pp determine pp_aix_version itself.
+ [7cf0245d84ed]
+
+ * INSTALL, config.h.in, configure, configure.in, mkpkg,
+ plugins/sudoers/sudoers.c:
+ Add support for Ubuntu admin flag file and enable it when building
+ Ubuntu packages.
+ [00e27cff2dfb]
+
+ * plugins/sudoers/sudoers, sudo.pp:
+ Add commented out SuSE-like targetpw settings
+ [4605d47b7413]
+
+ * configure, configure.in:
+ Only try to use +DAportable for non-GCC on hppa
+ [75d0f284ccf7]
+
+ * configure, configure.in:
+ Prevent configure from adding the -g flag unless in devel mode
+ [b1fd3f8d45c0]
+
+2010-07-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Go back to sudo-flavor to match existing packages and only use an
+ underscore for those that need it.
+ [d737069d1e1c]
+
+ * sudo.pp:
+ Use sudo_$flavor instead of sudo-$flavor since that causes the least
+ amount of trouble for the various package managers.
+ [71f547af35fc]
+
+ * mkpkg:
+ Fix handling of the ldap flavor Remove destdir unless --debug was
+ specified Make distclean before running configure if there is a
+ Makefile present
+ [6316f08de7d3]
+
+ * sudo.pp:
+ Add back include file.
+ [195627bf68b8]
+
+ * mkpkg:
+ Pass extra args on to configure on HP-UX, if we don't have the HP C
+ compiler, disable zlib to prevent gcc from finding it in
+ /usr/local/lib.
+ [473efa0e2bac]
+
+ * mkpkg:
+ Use the HP ANSI C compiler on HP-UX if possible
+ [fb249b6b175d]
+
+ * plugins/sudoers/sudoreplay.c:
+ Some getline() implementations (FreeBSD 8.0) do not ignore the
+ length pointer when the line pointer is NULL as they should.
+ [2410a1a3543c]
+
+ * plugins/sudoers/sudoreplay.c:
+ Don't need to check for *cp being non-zero, isdigit() will do that.
+ [7df11ea8a487]
+
+ * plugins/sudoers/sudoreplay.c:
+ Add setlocale() so the command line arguments that use floating
+ point work in different locales. Since sudo now logs the timing data
+ in the C locale we must Parse the seconds in the timing file
+ manually instead of using strtod(). Furthermore, sudo 1.7.3 logged
+ the number of seconds with the user's locale so if the decimal point
+ is not '.' try using the locale-specific version.
+ [4d385765f23b]
+
+ * src/exec.c:
+ Do I/O logging in the C locale so the floating point numbers in the
+ timing file are not locale-dependent.
+ [5961cec044ec]
+
+ * plugins/sudoers/sudoreplay.c:
+ Use errorx() not error() for thingsthat don't set errno.
+ [0fe5e692af84]
+
+2010-07-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pp:
+ Better support for 1.2.3 style versions in Tru64 kits
+ [997c549bb777]
+
+ * sudo.pp:
+ Add Tru64 kit support
+ [e273a954f981]
+
+ * pp:
+ Remove apparently unnecessary use of sudo
+ [be8840d85125]
+
+ * Makefile.in, plugins/sudoers/Makefile.in:
+ Create timedir as part of install-dirs target.
+ [c736bc2fb14f]
+
+ * src/exec_pty.c:
+ Handle ENXIO from read/write which can occur when reading/writing a
+ pty that has gone away.
+ [fa2e8059879f]
+
+ * plugins/sudoers/pwutil.c:
+ sudo_pwdup() was not expanding an empty pw_shell to _PATH_BSHELL
+ [3a045475d5ee]
+
+ * mkpkg:
+ platform is a pp flag not a variable
+ [12eba39a47c1]
+
+ * Makefile.in, mkpkg, sudo.pp:
+ Add simple arg parsing for mkpkg so we can set debug, flavor or
+ platform.
+ [ada839fe252d]
+
+ * pp:
+ Make rpm backend work on AIX 5.x
+ [549a76d11393]
+
+2010-07-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers:
+ Add commented out Defaults entry for log_output
+ [7e67d7588900]
+
+2010-07-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/Makefile.in:
+ Remove sudo docdir completely
+ [dce8e82878ef]
+
+ * doc/sample.sudo.conf:
+ Add sample sudo.conf
+ [aafdba3fc411]
+
+2010-07-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ Add PACKAGE_TARNAME for docdir
+ [930c92b8f8f0]
+
+2010-07-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/Makefile.in:
+ Pass install-sh -b~ here too.
+ [c3f5eb446c38]
+
+ * plugins/sample/Makefile.in, plugins/sample_group/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in:
+ Install binary files with -b~ to make a backup. Fixes "text file
+ busy" error on HP-UX during install.
+ [81f306f54f8c]
+
+ * install-sh:
+ "mv -f" on HP-UX doesn't unlink the destination first so add an
+ explicit rm before moving the temporary into place.
+ [fb719a79582d]
+
+ * configure, configure.in:
+ Some more ${foo} -> $(foo) conversion for consistent Makefiles.
+ [0aa098770074]
+
+ * doc/Makefile.in, plugins/sudoers/Makefile.in:
+ Install sudoers2ldif in the doc dir
+ [33ac3b53d7f5]
+
+2010-07-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pathnames.h.in:
+ Add missing include of maillock.h for Solaris
+ [5a58883be23a]
+
+ * NEWS, configure, configure.in, doc/TROUBLESHOOTING, doc/UPGRADE,
+ doc/sample.syslog.conf, doc/sudoers.cat:
+ Change the default syslog facility from local2 to authpriv (or auth
+ if the operating system doesn't support authpriv).
+ [3b70ba514f49]
+
+ * Makefile.in, sudo.pp:
+ Install sudoers as /etc/sudoers on RPM and debian systems where the
+ package manager will not replace a user-modified configuration file.
+ This fixes upgrades from the vendor sudo packages.
+ [d886b6d60b5b]
+
+ * pp:
+ RPM: use %config(noreplace) instead of %config for volatile This
+ results in the new file being installed with a .rpmnew suffix
+ instead of the file being replaced and the old one renamed with a
+ .rpmsave suffix.
+ [58be2119f8e8]
+
+2010-07-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/mkstemps.c, plugins/sudoers/boottime.c:
+ Include time.h for struct timeval
+ [ddf8b04f0276]
+
+ * src/exec_pty.c:
+ The return value of strsignal() may be const and should be treated
+ as const regardless.
+ [620074ae1e77]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod:
+ Mention that 127.0.0.1 will not match, nor will localhost unless
+ that is the actual host name.
+ [8b574122eb8f]
+
+ * MANIFEST, NEWS, README, WHATSNEW, doc/Makefile.in, doc/UPGRADE:
+ Rename WHATSNEW -> NEWS
+ [d1a2c8c47d89]
+
+ * pp:
+ Updated pp with latest patches
+ [98e16b9b8f62]
+
+ * WHATSNEW:
+ Sync with 1.7.4
+ [65ac4dafeef7]
+
+ * doc/UPGRADE, doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod,
+ plugins/sudoers/sudoers:
+ Add commented out line to add HOME to env_keep and add a warning to
+ the note about the HOME change in UPGRADE.
+ [0d6a775bb6c8]
+
+2010-07-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c:
+ Add LINE_MAX define for those without it.
+ [446d9dbe7859]
+
+ * INSTALL, WHATSNEW, config.h.in, configure, configure.in,
+ doc/UPGRADE, doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod,
+ plugins/sudoers/defaults.c:
+ The tty_tickets option is now on by default.
+ [a01c48206d80]
+
+ * WHATSNEW:
+ Mention that AIX authdb support has been fixed.
+ [87bd7f4eba6a]
+
+ * common/aix.c:
+ setauthdb() only sets the "old" registry if it was set by a previous
+ call to setauthdb(). To restore the original value, passing NULL (or
+ an empty string) to setauthdb() is sufficient.
+ [470da190a254]
+
+2010-07-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * WHATSNEW, doc/UPGRADE, doc/sudo.cat, doc/sudo.man.in, doc/sudo.pod,
+ doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod,
+ plugins/sudoers/env.c:
+ Reset HOME when env_reset is enabled unless it is in env_keep
+ [f421f8827340]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod:
+ The default for set_logname has been "true" for some time now.
+ [f489da5674c3]
+
+ * plugins/sudoers/boottime.c:
+ Add missing include of time.h
+ [624d7014932f]
+
+ * plugins/sudoers/logging.c:
+ Fix check for dup2() return value.
+ [140ea2d50d20]
+
+ * plugins/sudoers/env.c:
+ Add PYTHONUSERBASE to initial_badenv_table
+ [3149aae5b12c]
+
+ * plugins/sudoers/visudo.c:
+ Treat an unknown defaults entry as a parse error.
+ [b3ebad73efb2]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/sudoers.c:
+ Check return value of setdefs() but don't stop setting defaults if
+ we hit an unknown one.
+ [945e752239ab]
+
+ * WHATSNEW, aclocal.m4, config.h.in, configure, configure.in,
+ doc/sudo.cat, doc/sudo.man.in, doc/sudo.pod, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.pod, pathnames.h.in,
+ plugins/sudoers/env.c:
+ If env_reset is enabled, set the MAIL environment variable based on
+ the target user unless MAIL is explicitly preserved in sudoers.
+ [a1b03e2e0e96]
+
+2010-07-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pp:
+ decode debian code names
+ [8741280d9960]
+
+ * WHATSNEW:
+ fix typo
+ [a8a19451110b]
+
+2010-07-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * WHATSNEW:
+ Merge with 1.7.4
+ [9348fa7e15b8]
+
+ * src/sudo.c:
+ Restore RLIMIT_NPROC after the uid switch if it appears that
+ runas_setup() did not do it for us. Fixes a bash script problem on
+ SuSE with RLIMIT_NPROC set to RLIM_INFINITY.
+ [786fb272e5fd]
+
+2010-07-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg, pp, sudo.pp:
+ Restore the dot removal in the os version reported by polypkg. Adapt
+ mkpkg and sudo.pp to the change.
+ [dcafdd53b88f]
+
+2010-07-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ document --with-pam-login
+ [ea93e4c6873c]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod:
+ The tag is NOSETENV, not UNSETENV. From Petr Uzel.
+ [2ac90d8de36e]
+
+2010-07-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pp:
+ Include flavor in solaris package name
+ [e605f6364c9f]
+
+ * mkpkg:
+ Older shells don't support IFS= so set explictly to space, tab,
+ newline.
+ [7773960bc8a0]
+
+ * mkpkg:
+ Use '=' not '==' in test
+ [c99d42bc48e6]
+
+ * mkpkg:
+ Fix typo that prevented debian from matching
+ [84421078fcb7]
+
+ * mkpkg:
+ Add missing prefix setting for debian
+ [6466f23de4aa]
+
+ * sudo.pp:
+ Use tab indents to reduce the chance of problem with <<- Fix the
+ debian %set section, pp does not set pp_deb_distro Uncomment %sudo
+ line in sudoers for debian Uncomment some env_keep lines for RHEL,
+ SLES and debian to more closely match the vendor sudoers files. Add
+ /etc/pam.d to %files Remove the /etc/sudo-ldap.conf symlink on
+ debian for ldap flavor
+ [c5b49feb1a0c]
+
+ * plugins/sudoers/sudoers:
+ Add commented out env_keep entries, sample Aliases and a %sudo line
+ for debian.
+ [387719e52d0f]
+
+ * configure, configure.in:
+ Move zlib check later on in the script to avoid a strange shell
+ problem on SLES11.
+ [1a3153bb1291]
+
+ * configure.in:
+ Remove check for egrep; configure has its own
+ [a3b9d98cb5d2]
+
+2010-07-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg:
+ Enable zlib for linux distros
+ [8fa51a1405a4]
+
+ * mkpkg:
+ Add ldap flavor to default build
+ [97644f5a555f]
+
+ * mkpkg, sudo.pp:
+ Simplify rpm linux distro settings
+ [b9dcf10cdf20]
+
+ * aclocal.m4, configure, configure.in, doc/UPGRADE, doc/sudoers.cat:
+ Move time stamp files from /var/run/sudo to /var/{db,lib,adm}/sudo.
+ [2c549c1acde9]
+
+ * Makefile.in:
+ Fix ChangeLog creation from build dir
+ [3d0c7904f173]
+
+ * plugins/sudoers/sudoers.c:
+ Handle getcwd() failure.
+ [aef7bef87394]
+
+ * doc/Makefile.in, mkpkg, sudo.pp:
+ Add ldap "flavor" for debian, controlled by the SUDO_FLAVOR
+ environment variable.
+ [be6ed611b7a8]
+
+ * sudo.pp:
+ Create sudo group on debian
+ [6ed6c032042e]
+
+ * mkpkg, sudo.pp:
+ Add debian 4/5/6 and use the dot when doing version matches
+ [6bcb664d1f4f]
+
+ * aclocal.m4, configure:
+ Use a loop when searching for mv, sendmail and sh
+ [d5e9369f8d13]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod:
+ Remove spurious "and"; from debian
+ [a21e6f7c5b99]
+
+ * aclocal.m4, configure, configure.in, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.pod, doc/visudo.cat,
+ doc/visudo.man.in, doc/visudo.pod:
+ Substitute the value of EDITOR into the sudoers and visudo manuals.
+ [cd79e587dd7f]
+
+2010-07-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkpkg, pp, sudo.pp:
+ Initial support for debian 4.0
+ [ac6707915fa8]
+
+ * mkpkg:
+ Some platforms need -fPIE instead of -fpie
+ [fd6be19e5bc2]
+
+ * plugins/sudoers/auth/pam.c:
+ Only set PAM_RHOST for Solaris, where it is needed to avoid a bug.
+ On Linux it causes a DNS lookup via libaudit.
+ [1e10105ade5b]
+
+ * MANIFEST:
+ Update MANIFEST to match packaging changes
+ [ef86ee557b5b]
+
+ * sudo.psf:
+ We now use pp to generate HP-UX packages
+ [f7aa8da7844e]
+
+ * INSTALL.binary, plugins/sudoers/Makefile.binary.in:
+ Remove vestiges of old binary package bits.
+ [afffd005452f]
+
+ * INSTALL, Makefile.in, common/Makefile.in, compat/Makefile.in,
+ doc/Makefile.in, include/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ src/Makefile.in:
+ install-man -> install-doc
+ [99b5fa05567c]
+
+ * Makefile.in, doc/Makefile.in, include/Makefile.in, mkpkg,
+ plugins/sudoers/Makefile.in, pp, src/Makefile.in, sudo.pp:
+ Use http://rc.quest.com/topics/polypkg/ for packaging
+ [5ca8eb75b223]
+
+ * install-sh:
+ Just ignore the -c option, it is the default Add support for -d
+ option
+ [a8b6b0a131e8]
+
+2010-07-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pathnames.h.in, plugins/sudoers/env.c, plugins/sudoers/logging.c:
+ Use _PATH_STDPATH instead of _PATH_DEFPATH
+ [137fa911908e]
+
+ * plugins/sudoers/Makefile.in, src/Makefile.in:
+ Do not strip binaries.
+ [20166e287176]
+
+ * INSTALL, configure, configure.in:
+ Add --insults=disabled configure option to allow people to build in
+ insult support but have the insults disabled unless explicitly
+ enabled in sudoers.
+ [523b8c552e90]
+
+ * compat/mkstemps.c:
+ Add prototype for gettime()
+ [275eee40473b]
+
+ * config.h.in, configure, configure.in, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/env.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Add support for a sudo-i pam.d file to be used for "sudo -i".
+ Adapted from a RedHat patch.
+ [06d34f16520b]
+
+2010-07-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/missing.h:
+ Fix mkstemps() prototype
+ [2421841e815b]
+
+ * MANIFEST, compat/Makefile.in, compat/mkstemp.c, compat/mkstemps.c,
+ config.h.in, configure, configure.in, include/missing.h,
+ src/sudo_edit.c:
+ Use mkstemps() instead of mkstemp() in sudoedit. This allows
+ sudoedit to preserve the file extension (if any) which may be used
+ by the editor (like emacs) to choose the editing mode.
+ [d33172d2c086]
+
+2010-07-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in, doc/sudoers.ldap.pod,
+ plugins/sudoers/ldap.c:
+ TLS_CACERT is now an alias for TLS_CACERTFILE. OpenLDAP uses
+ TLS_CACERT, not TLS_CACERTFILE in its ldap.conf. Other LDAP client
+ code, such as nss_ldap, uses TLS_CACERTFILE. Also document why you
+ should avoid disabling TLS_CHECKPEER is possible.
+ [196622436212]
+
+2010-07-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Make sudo_plugin format a bit more like a man page
+ [048d596e32da]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Add suport for negated user/host/command lists in a Defaults entry.
+ E.g. Defaults:!baduser noexec
+ [d41112cf0342]
+
+ * Makefile.in, common/Makefile.in, compat/Makefile.in,
+ doc/Makefile.in, include/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sample_group/Makefile.in, plugins/sudoers/Makefile.in,
+ src/Makefile.in:
+ Add uninstall target
+ [fea66ebf136a]
+
+ * common/Makefile.in, compat/Makefile.in:
+ Remove unused AR, SED and RANLIB variables
+ [2ff9928bfdb3]
+
+ * Makefile.in:
+ Do not install sample plugins
+ [5443b87bd1c3]
+
+2010-07-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, aclocal.m4, compat/setenv.c, compat/unsetenv.c, configure,
+ configure.in, plugins/sudoers/env.c:
+ Now that sudoers is a dynamically loaded module we cannot override
+ the libc environment functions because the symbols may already have
+ been resolved via libc. Remove getenv/putenv/setenv/unsetenv
+ replacements from sudoers and add replacements for setenv/unsetenv
+ for systems that lack them.
+ [3f2b43cb8851]
+
+ * configure, configure.in, plugins/sudoers/Makefile.in:
+ Link testsudoers with -ldl when needed
+ [f79606f9fcd7]
+
+ * plugins/sample_group/plugin_test.c:
+ Remove unused time.h and add limits.h for PATH_MAX
+ [3f5d0074d621]
+
+ * doc/sudoers.ldap.pod:
+ Fix typo.
+ [bc855fd57397]
+
+2010-07-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sample_group/plugin_test.c:
+ Do not depend on strlcpy/strlcat
+ [6e7e2b5af051]
+
+ * plugins/sample_group/plugin_test.c:
+ Standalone test driver for sudoers group plugin.
+ [eb1235fc3b8e]
+
+2010-07-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/group_plugin.c, src/load_plugins.c:
+ Use RTLD_LAZY instead of RTLD_NOW; was using RTLD_NOW as a debugging
+ aid.
+ [2a34e616229b]
+
+ * plugins/sample_group/sample_group.c:
+ Fix style nit in function declarations
+ [ab87c7c76bf9]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod:
+ Document group_plugin syntax.
+ [ed1faf72ddcb]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Document the sudoers group plugin.
+ [f19a62dc8cfc]
+
+ * INSTALL, MANIFEST, Makefile.in, config.h.in, configure,
+ configure.in, doc/LICENSE, doc/license.pod, include/sudo_plugin.h,
+ plugins/sample_group/Makefile.in, plugins/sample_group/getgrent.c,
+ plugins/sample_group/sample_group.c, plugins/sudoers/Makefile.in,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/group_plugin.c,
+ plugins/sudoers/match.c, plugins/sudoers/nonunix.h,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/vasgroups.c, plugins/sudoers/visudo.c, src/sudo.c:
+ Replace built-in non-unix group support with a sudoers group plugin.
+ Include a sample plugin that can read Unix-format group files.
+ [8fc58ce0b1a8]
+
+ * configure, configure.in, src/load_plugins.c:
+ Add a trailing slash to _PATH_SUDO_PLUGIN_DIR to simplify usage.
+ [5c491dddb8ef]
+
+2010-07-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.pod, doc/sudoers.cat,
+ doc/sudoers.man.in, doc/sudoers.pod:
+ Move sudoers-specific bits out of sudo(8) and into sudoers(5)
+ [e8a5a5830cfe]
+
+ * aclocal.m4, configure, configure.in:
+ Substitute @io_logdir@ for the sudoers I/O log directory.
+ [21a75ca7b0ab]
+
+2010-06-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, common/Makefile.in, common/aix.c, common/alloc.c,
+ common/atobool.c, common/fileops.c, common/fmt_string.c,
+ common/lbuf.c, common/term.c, compat/fnmatch.c, compat/getcwd.c,
+ compat/getgrouplist.c, compat/getline.c, compat/glob.c,
+ compat/snprintf.c, config.h.in, configure, configure.in,
+ include/fileops.h, plugins/sample/sample_plugin.c,
+ plugins/sudoers/alias.c, plugins/sudoers/auth/afs.c,
+ plugins/sudoers/auth/aix_auth.c, plugins/sudoers/auth/bsdauth.c,
+ plugins/sudoers/auth/dce.c, plugins/sudoers/auth/fwtk.c,
+ plugins/sudoers/auth/kerb4.c, plugins/sudoers/auth/kerb5.c,
+ plugins/sudoers/auth/pam.c, plugins/sudoers/auth/passwd.c,
+ plugins/sudoers/auth/rfc1938.c, plugins/sudoers/auth/secureware.c,
+ plugins/sudoers/auth/securid.c, plugins/sudoers/auth/securid5.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/boottime.c, plugins/sudoers/check.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/env.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/getdate.c,
+ plugins/sudoers/getdate.y, plugins/sudoers/getspwuid.c,
+ plugins/sudoers/goodpath.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/interfaces.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/logging.c, plugins/sudoers/match.c,
+ plugins/sudoers/parse.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/tsgetgrpw.c, plugins/sudoers/visudo.c,
+ src/Makefile.in, src/aix.c, src/conversation.c, src/exec.c,
+ src/exec_pty.c, src/get_pty.c, src/load_plugins.c, src/parse_args.c,
+ src/sudo.c, src/sudo.h, src/sudo_edit.c, src/tgetpass.c:
+ Set usrinfo for AIX Set adminstrative domain for the process when
+ looking up user's password or group info and when preparing for
+ execve(). Include strings.h even if string.h exists since they may
+ define different things. Fixes warnings on AIX and others.
+ [cf8b93e872c9]
+
+ * Makefile.in:
+ Add a separate all target for AIX make which was using the entire
+ LHS (not just the first entry) of the first target as the implicit
+ target.
+ [a45b980a01ef]
+
+ * plugins/sudoers/env.c:
+ Do not rely on env.env_len when unsetting a variable, just use the
+ NULL terminator.
+ [ca6eb239c829]
+
+ * plugins/sudoers/env.c:
+ In unsetenv() check for NULL or empty name as per POSIX 1003.1-2008
+ [7046ba7caa4e]
+
+2010-06-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/vasgroups.c:
+ Use warningx() instead of log_error() since the latter is not
+ available to visudo or testsudoers. This does mean that they don't
+ end up in syslog.
+ [152b7c50f426]
+
+ * plugins/sudoers/sudoers.c:
+ Defer call to sudo_nonunix_groupcheck_cleanup() until after we have
+ closed the sudoers sources. From Quest sudo.
+ [c1cd573bab94]
+
+ * plugins/sudoers/pwutil.c:
+ Ignore case when matching user/group names in the cache. From Quest
+ sudo.
+ [2aa4ecc7d7f5]
+
+2010-06-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, src/selinux.c:
+ Add check for setkeycreatecon() when --with-selinux is specified.
+ [affae247b4e0]
+
+ * configure, configure.in:
+ Error out if libaudit.h is missing or ununable when --with-linux-
+ audit was specified
+ [d82e743fac04]
+
+ * doc/HISTORY, doc/history.pod:
+ Add =head3 entries, mostly for the html version
+ [ee93112d0308]
+
+2010-06-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/HISTORY, doc/history.pod:
+ Mention when LDAP was incorporate.
+ [2923dc17f79c]
+
+2010-06-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Define _LINUX_SOURCE_COMPAT on AIX for strsignal() prototype, it is
+ not covered by _ALL_SOURCE.
+ [c92fd69809d0]
+
+2010-06-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Add a cast to quiet a compiler warning.
+ [a200e07ee1bc]
+
+ * plugins/sudoers/getdate.c, plugins/sudoers/getdate.y:
+ Quiet a compiler warning.
+ [c9acfc927cea]
+
+ * plugins/sudoers/defaults.c, plugins/sudoers/sudoers.c:
+ Call set_fqdn() after sudoers has parsed instead of inline as a
+ callback.
+ [5f4e5d075f2d]
+
+ * WHATSNEW, plugins/sudoers/sudoers.c:
+ Do not call set_fqdn() until sudoers parses (where is gets run as a
+ callback).
+ [09040fca6d40]
+
+ * WHATSNEW:
+ mention the change in tty ticket behavior when there is no tty
+ [575a1fd98f05]
+
+ * plugins/sudoers/check.c:
+ Do not update tty ticket if there is no tty.
+ [63f9c33ce6a7]
+
+ * doc/LICENSE, doc/license.pod:
+ Update copyright year
+ [0722ab5d404b]
+
+ * doc/Makefile.in:
+ Do not rely on BSD make's $>
+ [936a86398bd9]
+
+ * configure, configure.in:
+ Set timedir to /var/db/sudo for darwin to match Apple sudo's
+ location
+ [d5b9b03096f1]
+
+2010-06-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.h:
+ Add stub declarations for struct stat and struct timeval
+ [f6d90551a4fd]
+
+ * MANIFEST:
+ Remove compat/sigaction.c
+ [d0ed6d9a770e]
+
+ * config.h.in, configure, configure.in, plugins/sudoers/defaults.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/sudoreplay.c:
+ Check for zlib.h in addition to libz.
+ [6e191b4a6065]
+
+ * MANIFEST, src/Makefile.in, src/exec.c, src/exec_pty.c, src/sudo.h,
+ src/sudo_exec.h:
+ Move functions and symbols shared between exec.c and exec_pty.c into
+ sudo_exec.h.
+ [14ae63403544]
+
+ * doc/Makefile.in:
+ Comment out rules to build .man.in and .cat files unless --with-
+ devel
+ [3cf7e5606a85]
+
+ * doc/Makefile.in:
+ Comment out rules to build .man.in and .cat files unless --with-
+ devel
+ [d30495b0e29e]
+
+ * src/parse_args.c:
+ Quote any non-alphanumeric characters other than '_' or '-' when
+ passing a command to be run via the shell for the -s and -i options.
+ [d633f74fe2d9]
+
+ * doc/Makefile.in:
+ Add back .man suffix
+ [6e63b60a2739]
+
+ * INSTALL, MANIFEST, WHATSNEW, config.h.in, configure, configure.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/audit.c,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/linux_audit.c,
+ plugins/sudoers/linux_audit.h, plugins/sudoers/logging.h,
+ src/selinux.c:
+ Add Linux audit support.
+ [5a2f445e0bd4]
+
+2010-06-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Remove an XXX
+ [a170cbe651d1]
+
+ * doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.pod,
+ plugins/sudoers/sudoreplay.c:
+ Add -f (filter) option to sudoreplay to allow certain streams to be
+ replayed and others ignored.
+ [62e51b432ea1]
+
+ * src/load_plugins.c, src/parse_args.c, src/sudo.c, src/sudo.h,
+ src/tgetpass.c:
+ Fix -A flag when askpass is specified in sudo.conf or if sudo
+ doesn't need to read a password.
+ [2e401e4a00e3]
+
+ * src/exec.c, src/exec_pty.c, src/parse_args.c, src/sudo.c,
+ src/sudo.h, src/sudo_edit.c, src/tgetpass.c:
+ Clean up some XXXs
+ [689f0b002d3d]
+
+ * WHATSNEW, doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.ldap.pod, plugins/sudoers/ldap.c:
+ Add support for multiple sudoers_base entries in ldap.conf. From
+ Joachim Henke
+ [e3e4a3c2bd5b]
+
+ * config.h.in, configure, configure.in, plugins/sudoers/logging.c,
+ src/exec_pty.c:
+ remove setsid check, we require a POSIX system
+ [cc73cb9e22c0]
+
+ * plugins/sudoers/logging.c, src/exec_pty.c, src/selinux.c,
+ src/sudo.c, src/tgetpass.c:
+ Check for dup2() failure.
+ [5d46d66794f5]
+
+ * config.h.in, configure, configure.in:
+ Remove dup2() check, it is not optional.
+ [5f1d56de4384]
+
+2010-06-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * WHATSNEW:
+ sync with sudo 1.7.3
+ [88e5c0bd6d59]
+
+ * INSTALL:
+ SunOS does not ship with an ANSI compiler
+ [f13c85c67069]
+
+ * INSTALL:
+ Update OS specific notes. Delete some really ancient ones and move
+ older ones to the end of the list.
+ [59ce592c4c52]
+
+ * README:
+ Sudo can be downloaded from the web site too Mention "OS dependent
+ notes" section in INSTALL
+ [191871538984]
+
+ * src/exec_pty.c, src/selinux.c:
+ Call selinux_restore_tty() as part of cleanup() so it gets called
+ from error()/errorx()
+ [bb017da6b6da]
+
+ * MANIFEST, doc/PORTING:
+ Remove obsolete porting guide
+ [321e35591344]
+
+ * plugins/sudoers/interfaces.h, plugins/sudoers/match.c:
+ Move union sudo_in_addr_un into interfaces.h
+ [b2c8b19ee094]
+
+ * doc/Makefile.in:
+ Remove useless circular dependencies
+ [5682181b59cf]
+
+ * plugins/sudoers/auth/afs.c, plugins/sudoers/auth/aix_auth.c,
+ plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/dce.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/kerb4.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/securid.c,
+ plugins/sudoers/auth/securid5.c, plugins/sudoers/auth/sia.c:
+ Convert to ANSI C function declarations
+ [a4f76927d034]
+
+ * common/alloc.c, common/fileops.c, common/gettime.c, common/list.c,
+ common/zero_bytes.c, compat/charclass.h, compat/closefrom.c,
+ compat/fnmatch.c, compat/glob.c, compat/isblank.c, compat/memrchr.c,
+ compat/mkstemp.c, compat/nanosleep.c, compat/snprintf.c,
+ compat/strcasecmp.c, compat/strerror.c, compat/strlcat.c,
+ compat/strlcpy.c, compat/timespec.h, compat/utime.h,
+ compat/utimes.c, doc/HISTORY, doc/history.pod, doc/license.pod,
+ include/alloc.h, include/error.h, include/lbuf.h, include/list.h,
+ include/missing.h, pathnames.h.in, plugins/sudoers/alias.c,
+ plugins/sudoers/audit.c, plugins/sudoers/auth/sudo_auth.h,
+ plugins/sudoers/boottime.c, plugins/sudoers/bsm_audit.c,
+ plugins/sudoers/bsm_audit.h, plugins/sudoers/defaults.c,
+ plugins/sudoers/defaults.h, plugins/sudoers/find_path.c,
+ plugins/sudoers/getspwuid.c, plugins/sudoers/goodpath.c,
+ plugins/sudoers/gram.y, plugins/sudoers/interfaces.c,
+ plugins/sudoers/interfaces.h, plugins/sudoers/logging.c,
+ plugins/sudoers/logging.h, plugins/sudoers/match.c,
+ plugins/sudoers/parse.h, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/redblack.c,
+ plugins/sudoers/redblack.h, plugins/sudoers/sudo_nss.h,
+ plugins/sudoers/sudoers.h, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/timestr.c,
+ plugins/sudoers/toke.l, plugins/sudoers/visudo.c, src/aix.c,
+ src/conversation.c, src/error.c, src/load_plugins.c,
+ src/parse_args.c, src/sesh.c, src/sudo.h, src/sudo_noexec.c,
+ src/sudo_plugin_int.h, src/sudo_usage.h.in, src/tgetpass.c:
+ Update copyright year
+ [26ac7991f7d8]
+
+ * doc/Makefile.in:
+ Fix commented DEVDOCS when not in devel mode.
+ [e0a97eaf3793]
+
+ * plugins/sudoers/match.c:
+ Quiet a compiler warning.
+ [b2a17ebd5d38]
+
+ * plugins/sudoers/getdate.c, plugins/sudoers/getdate.y:
+ Quiet a compiler warning.
+ [687843bc593d]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/sudoers.h:
+ Make all functions in ldap.c static
+ [b2111e89eeba]
+
+ * doc/schema.ActiveDirectory:
+ Updates from Alain Roy to provide better examples for importing the
+ schema and to fix problems caused by Windows validating attributes
+ which have not yet been added before committing the changes.
+ [69f4c5ccaf89]
+
+2010-06-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in, doc/Makefile.in, doc/sudo.cat,
+ doc/sudo.man.in, doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudoers.cat, doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.man.in, doc/sudoreplay.cat, doc/sudoreplay.man.in,
+ doc/visudo.cat, doc/visudo.man.in:
+ Leave rules to build .man.in and .cat files uncommented but only
+ make them part of the "all" rule in devel mode. Generate .cat files
+ directly from .man.in instead of .man using default values in
+ configure.in
+ [c3054a44f6a5]
+
+ * configure, configure.in:
+ Bump sudo version to 1.8.0b1
+ [8f79c85135e1]
+
+ * configure, configure.in, src/sudo.c, src/sudo_usage.h.in:
+ Print configure args with verbose version information.
+ [1ce690660ed2]
+
+ * TODO, plugins/sudoers/visudo.c:
+ Remove tfd from struct sudoersfile; it is not used. Add prev pointer
+ to struct sudoersfile. Declare list of sudoersfile using TQ_DECLARE.
+ Use tq_append to append sudoers entries to the tail queue.
+ [1743f9a286e4]
+
+2010-06-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * WHATSNEW:
+ Describe tty timestamp improvements
+ [e214e863a313]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ A comment character may not be part of a command line argument
+ unless it is quoted with a backslash. Fixes parsing of: testuser
+ ALL=NOPASSWD: /usr/bin/wl #comment foo bar closes bz #441
+ [ea2e990f85ed]
+
+ * doc/sudoers.pod:
+ Make this read a little bit better when passwd_timeout is 0.
+ [39d362757f31]
+
+ * doc/sudo.man.in, doc/sudo.man.pl, doc/sudo.pod:
+ Attempt to handle a default password prompt timeout of zero more
+ gracefully.
+ [ea47d43acf5b]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ Do not override value of keepopen global, instead restore it to the
+ value we pushed onto the stack when popping.
+ [fe282e5a3402]
+
+ * plugins/sudoers/Makefile.in:
+ Add dependency for utility programs on libreplace and libcommon
+ [2339aba64928]
+
+ * compat/sigaction.c, config.h.in, configure.in, include/compat.h,
+ plugins/sudoers/logging.c, plugins/sudoers/mon_systrace.c,
+ src/exec.c, src/exec_pty.c, src/tgetpass.c:
+ Remove sigaction emulation Use SA_INTERRUPT in sa_flags
+ [7dd61f1bd8d2]
+
+ * MANIFEST, config.h.in, configure, configure.in, include/missing.h:
+ We don't use getgrouplist() at the moment so there's no need to
+ provide a compat version.
+ [1597536fbada]
+
+ * TODO:
+ sync with reality
+ [9e1a874e7885]
+
+ * include/sudo_plugin.h, plugins/sudoers/auth/sudo_auth.c,
+ src/conversation.c, src/sudo.h, src/tgetpass.c:
+ Fix visiblepw sudoers option; the plugin API portion still needs
+ documenting
+ [60b6933ef5e0]
+
+ * src/sudo.c:
+ Print sudo version as well.
+ [987ed459b459]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/sudoers.c:
+ Use sudo_printf for I/O log version Clarify policy plugin version
+ string
+ [5a58b7e8c80b]
+
+ * plugins/sudoers/getdate.c, plugins/sudoers/getdate.y,
+ plugins/sudoers/ldap.c, plugins/sudoers/sudoreplay.c:
+ Silence some compiler warnings
+ [afb1eba90915]
+
+ * src/load_plugins.c, src/tgetpass.c:
+ Store askpass path in a global instead of uses setenv() which many
+ systems lack.
+ [b440bcc0e660]
+
+2010-06-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.pod, doc/sudo_plugin.cat,
+ doc/sudo_plugin.man.in, doc/sudo_plugin.pod,
+ plugins/sudoers/check.c, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in,
+ plugins/sudoers/defaults.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, src/load_plugins.c, src/parse_args.c,
+ src/tgetpass.c:
+ Move askpass path specification from sudoers to sudo.conf.
+ [5507ab867c26]
+
+ * src/exec.c, src/exec_pty.c, src/sudo.c, src/sudo.h:
+ Use a flag bit in struct command_details for selinux instead of a
+ separate field.
+ [c59ca4acded9]
+
+ * src/exec.c, src/exec_pty.c, src/sudo.c, src/sudo.h:
+ Implement background mode. If I/O logging we use pipes instead of a
+ pty.
+ [c07a4b356cbd]
+
+ * compat/mksiglist.c, compat/strsignal.c, include/compat.h,
+ src/exec.c, src/exec_pty.c, src/tgetpass.c:
+ Move compat definition of NSIG to compat.h
+ [ab0385467f25]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.pod, doc/sudo_plugin.cat,
+ doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Mention plugins in the sudo manual and add some missing path
+ substitution in the sudo_plugin manual.
+ [570f831f47a3]
+
+ * src/Makefile.in:
+ Set _PATH_SUDO_CONF based on $(sysconfdir)
+ [fde51869cf07]
+
+ * common/lbuf.c, common/term.c, config.h.in, configure, configure.in,
+ src/exec.c, src/exec_pty.c, src/ttysize.c:
+ Require POSIX termios to build sudo
+ [9ec6b41f3f95]
+
+ * src/tgetpass.c:
+ Ignore SIGPIPE for "sudo -S"
+ [7ad27fde0c06]
+
+ * src/tgetpass.c:
+ Fix uninitialized variable in TGP_ECHO case and print a newline if
+ the user interrupted password input.
+ [ce19204d8dd4]
+
+ * src/tgetpass.c:
+ Make TGP_ECHO override TGP_MASK and don't try to restore the
+ terminal if we didn't modify it.
+ [a7e11abfe7e4]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod,
+ include/sudo_plugin.h, plugins/sudoers/auth/sudo_auth.c,
+ src/conversation.c, src/sudo.h, src/tgetpass.c:
+ Add SUDO_CONV_PROMPT_MASK define which corresponds to the
+ "pwfeedback" sudoers option. Do not disable echo if TGP_ECHO is set.
+ [e0550590cabe]
+
+ * src/exec_pty.c:
+ Use POSIX tcgetpgrp() instead of BSD TIOCGPGRP ioctl
+ [762448182fe3]
+
+2010-06-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec.c, src/exec_pty.c, src/selinux.c, src/sudo.c, src/sudo.h:
+ Add selinux_enabled flag into struct command_details and set it in
+ command_info_to_details(). Return an error from selinux_setup()
+ instead of exiting. Call selinux_setup() from exec_setup().
+ [011bea23a5a0]
+
+2010-06-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/exec_pty.c:
+ Remove commented out copy of old sudo_execve() function.
+ [9c5e21380472]
+
+2010-06-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Fix setting selinux type on command line.
+ [814b20a0b3be]
+
+ * plugins/sudoers/iolog.c:
+ In sudoers_io_close(), skip NULL io_fds[] elements.
+ [4011ff7d4daf]
+
+ * include/compat.h:
+ No longer need NGROUPS_MAX define
+ [cae4c49d7077]
+
+ * compat/nanosleep.c, config.h.in, configure, configure.in,
+ include/compat.h, plugins/sudoers/check.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/visudo.c, src/sudo_edit.c:
+ Replace timerfoo macros with timevalfoo since the timer macros are
+ known to be busted on some systems.
+ [4f97d79f2d41]
+
+ * src/exec_pty.c:
+ Remove duplicate call to selinux_setup().
+ [82bd52764e21]
+
+ * plugins/sudoers/auth/pam.c:
+ If pam_open_session() fails, pass its status to pam_end.
+ [1d8de4cf8ff3]
+
+ * plugins/sudoers/toke.c, plugins/sudoers/toke.l:
+ If a file in a #includedir has improper permissions or owner just
+ skip it. This prevents packages that incorrectly install a file into
+ /etc/sudoers.d from breaking sudo so easily. Syntax errors in
+ #includedir files still result in a parse error (for now).
+ [ade99a4549a4]
+
+ * WHATSNEW, doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/iolog.c:
+ Add use_pty sudoers option to force use of a pty even when not
+ logging I/O.
+ [b280a8972a79]
+
+ * plugins/sudoers/env.c, plugins/sudoers/sudoers.h:
+ Make env_init() void as it never fails.
+ [d3890e55daa7]
+
+ * plugins/sudoers/env.c:
+ No longer use _NSGetEnviron so don't need crt_externs.h
+ [9b4e0e139881]
+
+ * plugins/sudoers/env.c:
+ Remove unused VNULL define
+ [a42cacb263e3]
+
+2010-06-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Add #define for maximum session id
+ [9e18c17a28c2]
+
+ * MANIFEST, src/Makefile.in, src/exec.c, src/exec_pty.c, src/sudo.h:
+ Split exec.c into exec.c and exec_pty.c
+ [d52376327332]
+
+ * MANIFEST:
+ Sync with source file moves.
+ [4a62c6c9e846]
+
+ * src/Makefile.in, src/get_pty.c, src/pty.c:
+ Rename pty.c -> get_pty.c
+ [5696a12bd29b]
+
+2010-06-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Only use I/O input log file if def_log_input is set and output file
+ if def_log_output is set.
+ [d866992f1681]
+
+2010-06-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/strsignal.c:
+ Update copyright year
+ [a96f2593fd4e]
+
+ * src/pty.c:
+ uid -> ttyuid
+ [c3454d74ebcb]
+
+ * plugins/sudoers/sudoers.c:
+ For sudoedit, make a local copy of editor string si become part of
+ argv. If no editor environment variable, split def_editor on ':'
+ since it may be a colon-delimited path.
+ [2ee298506a6e]
+
+ * src/sudo_edit.c:
+ Remove unneeded endpwent()/endgrent()
+ [623f6743d101]
+
+ * doc/Makefile.in:
+ Use value of nroff from configure
+ [b2ce649125ab]
+
+ * src/exec.c:
+ Add missing const to I/O log action function
+ [d764a3955e04]
+
+ * plugins/sudoers/check.c:
+ Update copyright year and fix whitespace
+ [e648c35b16be]
+
+ * configure, configure.in:
+ Fix typo
+ [8e0bdfc47da4]
+
+ * plugins/sudoers/iolog.c:
+ Remove redundant tty signal blocking in log function.
+ [f17f575dabd4]
+
+2010-06-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Place static keyword where it belongs
+ [b01aec7c86b4]
+
+ * plugins/sudoers/logging.c:
+ Always use a printf format string for send_mail()
+ [13b1ada644c9]
+
+ * common/atobool.c, plugins/sudoers/ldap.c:
+ Extend atobool() so we can use it in the LDAP code.
+ [73f8e6807044]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.pod:
+ Sudo now stashes tty ctime for tty_tickets on Solaris too.
+ [e82df13ad3fd]
+
+ * plugins/sudoers/boottime.c:
+ Fix dummy version of get_boottime()
+ [01d69c06013b]
+
+2010-06-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c:
+ Enable tty_is_devpts() support for Solaris with the "devices"
+ filesystem.
+ [237c6b25fa84]
+
+ * src/exec.c:
+ Unbreak the non-io logging case.
+ [4822b9f709fb]
+
+ * src/conversation.c, src/sudo.c, src/sudo_plugin_int.h:
+ Fix symbol name conflict with sudo_printf.
+ [0d44eab0a8f6]
+
+ * plugins/sudoers/auth/pam.c:
+ Fix OpenPAM detection for newer versions.
+ [1b2abed232d8]
+
+ * plugins/sudoers/vasgroups.c:
+ Sync with Quest sudo git repo
+ [f1d98b3cba02]
+
+ * aclocal.m4, configure, configure.in:
+ HP-UX ld uses +b instead or -R or -rpath Fix typo in libvas check
+ Add missing template for ENV_DEBUG Adapted from Quest sudo
+ [695dbd7b28f4]
+
+ * README.LDAP:
+ Fix typos; from Quest Sudo
+ [4eba9da33b8e]
+
+2010-06-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ Add back -I$(top_srcdir); we need it for including compat/foo.h
+ since we cannot rely on "foo.h" being found relative to the source
+ file when the cwd is different.
+ [bbf24695f325]
+
+ * src/exec.c:
+ Fix a bug where we could treat EAGAIN as a permanent error. Also set
+ cstat if perform_io() returns an error.
+ [200475c4326f]
+
+ * common/alloc.c, plugins/sudoers/boottime.c,
+ plugins/sudoers/sudoers.c:
+ Add casts to quiet compiler warnings.
+ [85eb1c336697]
+
+ * plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c:
+ Fix typo in ternary operator usage.
+ [6492ac1450e2]
+
+2010-05-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, configure, configure.in:
+ Add --enable-warnings and fix typo in SUDO_IO_LOGDIR
+ [92121d693b30]
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod,
+ doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.pod:
+ Update docs to match sudoers I/O logging changes
+ [18d651989e49]
+
+ * INSTALL, WHATSNEW, aclocal.m4, configure, configure.in,
+ pathnames.h.in, plugins/sudoers/def_data.c,
+ plugins/sudoers/def_data.h, plugins/sudoers/def_data.in,
+ plugins/sudoers/defaults.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.h, plugins/sudoers/gram.y,
+ plugins/sudoers/iolog.c, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoreplay.c:
+ Break sudoers transcript feature up into log_input and log_output.
+ [db3c1248d2ad]
+
+ * plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/visudo.c:
+ Use setprogname() as needed.
+ [6beee63a4553]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/sudoreplay.c:
+ Adapt sudoreplay to iolog changes.
+ [581f52c05f0f]
+
+2010-05-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c:
+ Log all input and output into separate files and store a number on
+ each timing file line to indicate which file the data is in.
+ [fb460c5273dd]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Make sudoers_io functions static to iolog.c
+ [b2df3cc3eecb]
+
+2010-05-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.pod, src/parse_args.c,
+ src/sudo_usage.h.in:
+ Completely remove the -L flag from the sudo front end.
+ [3d220030b720]
+
+ * plugins/sudoers/sudoreplay.c:
+ Fix EAGAIN handling when writing to stdout.
+ [4766d77cea49]
+
+ * plugins/sudoers/sudoers.c:
+ Eliminate unused variables
+ [83bd711e79c4]
+
+ * plugins/sudoers/sudoers.c, src/exec.c, src/sudo.c:
+ Re-enable cleanup functions in sudoers plugin and sudo driver for
+ error()/errorx().
+ [43093f937dd8]
+
+ * plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/interfaces.c, plugins/sudoers/iolog.c,
+ plugins/sudoers/parse.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c:
+ Use sudo_printf to display verbose version information.
+ [435cc9f8d4a2]
+
+ * common/Makefile.in, compat/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in:
+ Minor Makefile cleanup: fix a typo, change the removal order in the
+ clean targets, and remove a superfluous include path for the sudoers
+ plugin.
+ [6e3b2d6b4437]
+
+ * plugins/sudoers/env.c:
+ Handle duplicate variables in the environment. For unsetenv(), keep
+ looking even after remove the first instance. For sudo_putenv(),
+ check for and remove dupes after we replace an existing value.
+ [c1bbb88d0435]
+
+2010-05-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ Use explicit path to source file instead of $< for files that live
+ in devdir and top_srcdir.
+ [358ab7f6cc64]
+
+ * plugins/sudoers/Makefile.in:
+ Add explicit rules to compile gram.c and toke.c for HP-UX Pevent
+ ending LIBSUDOERS_OBJS with a backslash
+ [481a5c96d47e]
+
+ * plugins/sudoers/Makefile.in, src/Makefile.in:
+ Link libcommon before libreplace since libcommon may use functions
+ only present in libreplace.
+ [1847c496ff5b]
+
+ * common/Makefile.in:
+ Move code common to sudo and the sudoers plugin to a convenience
+ library, libcommon. Removes the need to make links in the sudoers
+ plugin dir and reduces re-compilation of duplicate object files.
+ [4c8986352937]
+
+ * Makefile.in, common/alloc.c, common/atobool.c, common/fileops.c,
+ common/fmt_string.c, common/gettime.c, common/lbuf.c, common/list.c,
+ common/term.c, common/zero_bytes.c, configure, configure.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ src/Makefile.in, src/alloc.c, src/atobool.c, src/fileops.c,
+ src/fmt_string.c, src/gettime.c, src/lbuf.c, src/list.c, src/term.c,
+ src/zero_bytes.c:
+ Move code common to sudo and the sudoers plugin to a convenience
+ library, libcommon. Removes the need to make links in the sudoers
+ plugin dir and reduces re-compilation of duplicate object files.
+ [1d1d98bd55b9]
+
+ * src/exec.c, src/sudo.c, src/sudo.h:
+ Rename script_execve to sudo_execve and rename script_foo in exec.c
+ [a35ec80de96a]
+
+ * MANIFEST, src/Makefile.in, src/exec.c, src/script.c:
+ rename script.c exec.c and fix up the MANIFEST file
+ [36bc3bff9578]
+
+ * src/script.c, src/sudo.c, src/sudo.h:
+ Rename script_setup() to pty_setup() and call from script_execve()
+ directly.
+ [899b0fb2a14d]
+
+ * configure, configure.in:
+ bump version to 1.8.0a2
+ [0b1c1ca9d4e5]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Document init_session
+ [b5324785a406]
+
+ * plugins/sudoers/auth/API, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/auth/sudo_auth.h:
+ Clean up the sudoers auth API a bit and update the docs.
+ [c40fd4cb6e68]
+
+ * include/sudo_plugin.h, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, src/script.c, src/sudo.c:
+ Add init_session function to struct policy_plugin that gets called
+ before the uid/gid/etc changes. A struct passwd pointer is passed
+ in,which may be NULL if the user does not exist in the passwd
+ database.The sudoers module uses init_session to open the pam
+ session as needed.
+ [d71723320ee8]
+
+2010-05-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/pam.c, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/auth/sudo_auth.h, plugins/sudoers/set_perms.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Add open/close session to sudo auth, only used by PAM. This allows
+ us to open (and close) the PAM session from sudoers.
+ [2665e2920d0d]
+
+ * plugins/sudoers/Makefile.in:
+ Add explicit rule to build getdate.o for HP-UX make.
+ [7f049e989956]
+
+ * plugins/sudoers/Makefile.in:
+ Back out most of change 45e406ebdea2. Create dummy .l.c and .y.c
+ rules as an alternate way to prevent HP-UX make (and others) from
+ trying to rebuild the parser in non-dev mode.
+ [f84badad98c5]
+
+ * plugins/sudoers/sudoers.c:
+ Re-enable PATH_MAX check for command
+ [40d8a50da136]
+
+ * Makefile.in:
+ For distclean, clean the main directory last since the subdirs need
+ to be able to run libtool to clean things.
+ [8949a9861634]
+
+ * compat/Makefile.in:
+ Fix generation of mksiglist.h
+ [b7cdc9b36650]
+
+ * src/script.c:
+ Now that we defer sending cstat until the end of script_child() we
+ cannot reuse cstat when reading command status from parent.
+ [25c882643466]
+
+2010-05-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in, doc/sudo.man.in, doc/sudo.man.pl,
+ doc/sudoers.cat, doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in,
+ doc/sudoers.man.in, doc/sudoers.man.pl, doc/sudoreplay.cat,
+ doc/sudoreplay.man.in, doc/visudo.cat, doc/visudo.man.in:
+ Use numeric registers to handle conditionals instead of trying to do
+ it all with text processing.
+ [478079c3fd4b]
+
+ * doc/sudoers.pod:
+ Document per-command SELinux settings
+ [13840d566805]
+
+ * plugins/sudoers/sudoers.c:
+ Repair "sudo -l -U username"
+ [10a0dcdf2ddf]
+
+ * plugins/sudoers/sudoers.c:
+ Set selinux role and type in command details.
+ [8ae6d35a126d]
+
+ * src/script.c, src/selinux.c, src/sudo.h:
+ Rework SELinux support.
+ [83279cc94bf2]
+
+2010-05-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/script.c, src/selinux.c, src/sudo.h:
+ Make SELinux support compile again. Needs more work to be complete.
+ [3d3addebcf82]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ src/parse_args.c, src/script.c, src/selinux.c, src/sudo.c,
+ src/sudo.h:
+ Bring back closefrom settings.
+ [b1c6257d4bbb]
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ If running a command or sudoedit in transcript mode, call
+ io_nextid() before log_allowed() so the session id is logged.
+ [c42f3ae40150]
+
+ * configure, configure.in:
+ Use mandoc(1) if nroff(1) is not present.
+ [daad4bbd04af]
+
+ * doc/Makefile.in:
+ Use the --file argument to config.status instead of setting
+ CONFIG_FILES in the environment.
+ [c89411a8bf70]
+
+ * plugins/sudoers/Makefile.in:
+ We cannot conditionally update gram.h or the dependency ordering
+ gets messed up in devel mode.
+ [c938953231d9]
+
+2010-05-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, compat/Makefile.in, configure, configure.in,
+ doc/Makefile.in, include/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in:
+ Substitute @SHELL@ into Makefiles
+ [36aa6a095335]
+
+ * config.sub:
+ Fix typo
+ [16d294d26b58]
+
+ * config.guess, config.sub, configure, configure.in:
+ Update to autoconf 2.65
+ [4fa6ea8caea3]
+
+ * Makefile.in:
+ Fix libtool target (space vs. tabs)
+ [755cf3892618]
+
+ * config.h.in, plugins/sudoers/logging.h, plugins/sudoers/visudo.c:
+ Remove use of RETSIGTYPE; all modern systems have signal handlers
+ that return void.
+ [42b4e3aee668]
+
+ * Makefile.in, aclocal.m4, acsite.m4, configure, configure.in,
+ ltmain.sh, m4/libtool.m4, m4/ltoptions.m4, m4/ltsugar.m4,
+ m4/ltversion.m4, m4/lt~obsolete.m4, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in:
+ Update to libtool-2.2.6b. I haven't made any local modifications
+ this time, which should be OK since we install sudo_noexec.so by
+ hand now.
+ [6f79ced593bb]
+
+ * compat/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in:
+ Use libtool to clean objects
+ [1581057d6472]
+
+ * include/Makefile.in:
+ Install sudo_plugin.h as part of "make install" and make other
+ install targets callable from the top-level Makefile
+ [aaaeb027d774]
+
+ * configure, configure.in:
+ regen with autoupdate to eliminate AC_TRY_LINK
+ [5d5541c230f5]
+
+ * Makefile.in, compat/Makefile.in, configure, configure.in,
+ doc/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in:
+ Install sudo_plugin.h as part of "make install" and make other
+ install targets callable from the top-level Makefile
+ [b258b8401b1c]
+
+ * plugins/sample/sample_plugin.c:
+ The sample plugin doesn't support being run with no args so return a
+ usage error in this case.
+ [473b3cf965be]
+
+ * plugins/sudoers/iolog.c:
+ Set close on exec flag for descriptors used for I/O logging so they
+ are not present in the command being run.
+ [2c7e8708df76]
+
+ * plugins/sudoers/tsgetgrpw.c:
+ Set close on exec flag in private versions of setpwent() and
+ setgrent().
+ [64fef78cb833]
+
+ * src/script.c:
+ Close the I/O pipes aftering dup2()ing them to std{in,out,err}.
+ Fixes extra fds being present in the command when it is part of a
+ pipeline.
+ [060451617713]
+
+ * plugins/sudoers/sudoers.c:
+ Set user_tty to "unknown" if there is no tty, like sudo 1.7 does (it
+ is used when logging). Note that user_ttypath will still be NULL if
+ there is no tty.
+ [31b69a6ecda7]
+
+ * src/script.c, src/sudo.h:
+ Cosmetic changes: add comments, remove orphaned prototype and make a
+ global static.
+ [f7851af0143e]
+
+2010-05-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/script.c:
+ Move check for maxfd == -1 to flush_output where it belongs.
+ [b826a95b4491]
+
+ * src/script.c:
+ Break out of select loop if all the fds we want to select on are -1.
+ [f5b387024238]
+
+ * src/sudo.c:
+ Avoid possible malloc(0) if plugin returns an empty groups list.
+ [9765a8fe5ce7]
+
+ * src/sudo.c:
+ Add debugging info when calling plugin close function
+ [95a273c7ff66]
+
+ * src/script.c:
+ Avoid closing stdin/stdout/stderr when we are piping output.
+ [330e76423caf]
+
+ * src/script.c:
+ When execve() of the command fails, it is possible to receive
+ SIGCHLD before we've read the error status from the pipe. Re-order
+ things such that we send the final status at the very end and prefer
+ error status over wait status.
+ [b0dcf825244f]
+
+2010-05-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/sudo_auth.c:
+ Fix compilation for non PAM/BSD auth/AIX auth
+ [e382b39d2e4f]
+
+2010-05-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/script.c:
+ Additional checks to make sure we don't close /dev/tty by mistake.
+ When flushing, sleep in select as long as we have buffers that need
+ to be written out.
+ [8139cbd3dd54]
+
+ * src/script.c:
+ Now that we can use pipes for stdin/stdout/stderr there is no longer
+ a need to error out when there is no tty. We just need to make sure
+ we don't try to use the tty fd if it is -1.
+ [666621635d26]
+
+2010-05-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod,
+ include/sudo_plugin.h, plugins/sample/sample_plugin.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/sudoers.h, src/sudo.c:
+ Add argc and argv to I/O logger open function.
+ [0d7faa007d27]
+
+ * doc/sudo_plugin.man.in, doc/sudo_plugin.pod, include/sudo_plugin.h,
+ plugins/sample/sample_plugin.c, plugins/sudoers/sudoers.c,
+ src/parse_args.c, src/sudo.c, src/sudo_edit.c:
+ Remove check_sudoedit function pointer in struct sudo_policy.
+ Instead, sudo will set sudoedit=true in the settings array. The
+ plugin should check for this and modify argv_out as appropriate in
+ check_policy.
+ [c0328e3276b8]
+
+2010-05-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sample/sample_plugin.c, src/sudo.c, src/sudo.h,
+ src/sudo_edit.c:
+ If plugin sets "sudoedit=true" in the command info, enable sudoedit
+ mode even if not invoked as sudoedit. This allows a plugin to enable
+ sudoedit when the user runs an editor.
+ [96d67b99e42e]
+
+2010-05-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ gram.h must not depend on gram.y if we want to avoid unnecessary
+ rebuilding of targets dependent on gram.h when gram.y changes.
+ [9db4b767fdca]
+
+ * plugins/sample/sample_plugin.c:
+ Refactor common bits of check_policy and check_edit
+ [ac4d366a04cf]
+
+ * plugins/sample/sample_plugin.c:
+ Add sudoedit support
+ [a1a6cc4c0cef]
+
+2010-05-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in:
+ Rely more on VPATH; fixes a dependency issue with the parser.
+ [45e406ebdea2]
+
+ * include/compat.h:
+ Fix typo introduced in last commit
+ [3ccb0f853d11]
+
+ * include/compat.h:
+ Emulate seteuid using setreuid() or setresuid() as needed. There are
+ still a few places that call seteuid() directly.
+ [36e8efa3a99d]
+
+ * src/parse_args.c, src/sudo_edit.c:
+ Attempt to fix building on systems that only have setuid.
+ [8e9ba4083318]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Clarify sudoedit a tad.
+ [d39dfaa14ade]
+
+2010-05-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo_edit.c:
+ Fix compilation on HP-UX
+ [f6e47843d139]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Document sudoedit
+ [4cbf5196d993]
+
+ * plugins/sudoers/sudoers.c, src/sudo.c, src/sudo.h, src/sudo_edit.c:
+ Change how we handle the sudoedit argv. We now require that there be
+ a "--" in argv to separate the editor and any command line arguments
+ from the files to be edited.
+ [20623d549a3c]
+
+ * include/sudo_plugin.h, plugins/sample/sample_plugin.c,
+ plugins/sudoers/Makefile.in, plugins/sudoers/gettime.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.c,
+ src/Makefile.in, src/gettime.c, src/parse_args.c, src/sudo.c,
+ src/sudo.h, src/sudo_edit.c:
+ Work in progress support for sudoedit. The actual interface used by
+ the plugin for sudoedit is likely to change.
+ [c31262a31997]
+
+ * plugins/sudoers/find_path.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/visudo.c:
+ Make find_path() a little more generic by not checking def_foo
+ variables inside it. Instead, pass in ignore_dot as a function
+ argument.
+ [9c23101a094d]
+
+ * plugins/sudoers/env.c:
+ Add version of getenv(3) that uses our own environ pointer.
+ [0e3783e63534]
+
+2010-05-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/script.c:
+ Avoid a potential race condition if SIGCHLD is received immediately
+ before we call select().
+ [99adc5ea7f0a]
+
+ * plugins/sudoers/sudoers.c:
+ Call env_init() before we open the sudoers sources as those may call
+ our setenv() replacement.
+ [5f82601f5ab0]
+
+ * plugins/sudoers/env.c:
+ Initialize env_len in env_init()
+ [7ae02b3029b5]
+
+2010-05-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.pod:
+ Document time stamp shortcomings under SECURITY NOTES Use "time
+ stamp" instead of timestamp.
+ [2b86120815b2]
+
+ * doc/Makefile.in:
+ Make sed substitution of mansectsu and mansectform global.
+ [94588632dba0]
+
+ * plugins/sudoers/check.c:
+ If the tty lives on a devpts filesystem, stash the ctime in the tty
+ ticket file, as it is not updated when the tty is written to. This
+ helps us determine when a tty has been reused without the user
+ authenticating again with sudo.
+ [0e62a31bceb0]
+
+ * src/tgetpass.c:
+ Fix pasto in mulitple signal fix and use _NSIG not NSIG since that
+ is what our compat checks set.
+ [df50f0a040c9]
+
+ * configure, configure.in:
+ Add check for whether sudo need to link with -ldl to get dlopen().
+ This is a bit of a hack that will get reworked when libtool is
+ updated.
+ [63bdcf579533]
+
+ * plugins/sudoers/check.c:
+ Fix timestamp removal with -k/-K
+ [6b4639fef973]
+
+ * plugins/sudoers/Makefile.in:
+ audit.c is now private to the sudoers plugin
+ [1974f342ae0b]
+
+ * configure, configure.in:
+ Link with -lpthread on HP-UX since a plugin may be linked with
+ -lpthread and dlopen() will fail if the shared object has a
+ dependency on -lpthread but the main program is not linked with it.
+ [d42139391263]
+
+ * config.h.in, configure, configure.in, plugins/sudoers/set_perms.c:
+ Add separate test for getresuid() since HP-UX has setresuid() but no
+ getresuid().
+ [910fe727a374]
+
+ * doc/Makefile.in:
+ Remove errant backslash
+ [dd5464257c69]
+
+ * src/script.c:
+ Fix SIGPIPE handling. Now that we use may use pipes for stdin/stdout
+ we need to pass any SIGPIPE we receive to the running command.
+ [3f6b1991f4fd]
+
+ * src/script.c:
+ Also start the command in the background if stdin is not a tty.
+ [d93bc33a3740]
+
+2010-05-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoreplay.c, src/script.c, src/sudo.h, src/term.c:
+ No need to use pseudo-cbreak mode now that we use pipes when stdout
+ is not a tty. Instead, check whether stdin is a tty and if not,
+ delay setting the tty to raw mode until the command tries to access
+ it itself (and receives SIGTTIN or SIGTTOU).
+ [e68315cf8c6b]
+
+ * src/tgetpass.c:
+ Use an array for signals received instead of a single variable so we
+ don't lose any when there are multiple different signals.
+ [2ac726dac864]
+
+ * src/tgetpass.c:
+ Do signal setup after turning off echo, not before. If we are using
+ a tty but are not the foreground pgrp this will generate SIGTTOU so
+ we want the default action to be taken (suspend process).
+ [bebb6209c795]
+
+2010-05-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/script.c:
+ Flush the iobufs on suspend or child exit using the same logic as
+ the main event loop.
+ [c627feee1035]
+
+ * src/script.c:
+ Free memory after we are done with it.
+ [8db9b611b45a]
+
+2010-05-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/HISTORY:
+ Quest now sponsors Sudo development
+ [6cc490083bc7]
+
+2010-05-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/Makefile.in:
+ Install sudo_plugin man page.
+ [c253729790b2]
+
+ * src/script.c:
+ Go back to reseting io_buffer offset and length (and now also the
+ EOF handling) in the loop we do the FD_SET, not after we drain the
+ buffer after write() since we don't know what order reads and writes
+ will occur in.
+ [5f38bfa8497f]
+
+ * MANIFEST:
+ audit files moved to sudoers plugin directory
+ [b1ead182428e]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Document plugin_printf and new logging functions.
+ [fe9430b60ab5]
+
+ * src/script.c:
+ Add support for logging stdin when it is not a tty. There is still a
+ bug where "cat | sudo cat" has problems because both cat and sudo
+ are trying to read from the tty.
+ [04c9c59fcfba]
+
+ * include/sudo_plugin.h, plugins/sample/sample_plugin.c,
+ plugins/sudoers/sudoers.c, src/script.c:
+ Add separate I/O logging functions for tty in/out and
+ stdin/stdout/stderr. NOTE: stdin logging does not currently work and
+ is disabled for now.
+ [a36dfd4ca935]
+
+2010-05-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/sudo_plugin.h, plugins/sample/sample_plugin.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/logging.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ src/conversation.c, src/sudo.c, src/sudo_plugin_int.h:
+ Add pointer to a printf like function to plugin open functon. This
+ can be used instead of the conversation function to display info and
+ error messages.
+ [98734eea8ef1]
+
+ * Makefile.in:
+ Stop if make in a subdir fails
+ [228bb3ad2dbc]
+
+ * src/script.c:
+ Only set user's tty to blocking mode when doing the final flush.
+ Flush pipes as well as pty master when the process is done.
+ [20ff67218666]
+
+2010-05-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/ldap.c:
+ Use print_error() when displaying ldap config info in debugging
+ mode.
+ [d142e0cacb22]
+
+ * compat/Makefile.in, compat/strdup.c, compat/strndup.c:
+ No longer need strdup() or strndup() replacements.
+ [df53697174ec]
+
+ * plugins/sudoers/logging.c, plugins/sudoers/plugin_error.c,
+ plugins/sudoers/sudoers.h:
+ Add print_error() function that uses the conversation function to
+ print a variable number of error strings and use it in log_error().
+ [b1fa2861b575]
+
+ * src/script.c, src/sudo.h, src/term.c:
+ Do not need the opost flag to term_copy() now that we use pipes for
+ stdout/stderr when they are not a tty.
+ [f42811f70a19]
+
+ * src/script.c:
+ Use pipes to the sudo process if stdout or stderr is not a tty.
+ Still needs some polishing and a decision as to whether it is
+ desirable to add additonal entry points for logging
+ stdout/stderr/stdin when they are not ttys. That would allow a
+ replay program to keep things separate and to know whether the
+ terminal needs to be in raw mode at replay time.
+ [1a945e0ab2da]
+
+2010-04-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/audit.c,
+ plugins/sudoers/bsm_audit.c, plugins/sudoers/bsm_audit.h,
+ src/audit.c, src/bsm_audit.c, src/bsm_audit.h:
+ Move audit sources into the sudoers plugin dir; the driver does not
+ use them.
+ [50ec36422cd0]
+
+ * compat/getline.c, compat/mksiglist.c, compat/nanosleep.c,
+ compat/strdup.c, compat/strndup.c, plugins/sample/sample_plugin.c,
+ plugins/sudoers/boottime.c, plugins/sudoers/getdate.c,
+ plugins/sudoers/match.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/timestr.c, plugins/sudoers/vasgroups.c, src/alloc.c,
+ src/atobool.c, src/audit.c, src/lbuf.c, src/list.c, src/sesh.c,
+ src/term.c, src/ttysize.c:
+ Use angle brackets when including headers that can only be found
+ when an -I flag is specified. The files in the compat dir could get
+ away with double quotes here but I've converted all the source files
+ to use angle brackets for consistency.
+ [9e30a8fc6d4b]
+
+ * plugins/sudoers/Makefile.in:
+ Add missing -I$(top_srcdir) to CPPFLAGS so includes in the compat
+ dir can be found when building outside the source tree.
+ [1150934b79dd]
+
+ * plugins/sudoers/Makefile.in:
+ Clean up links in distclean
+ [78595028be8b]
+
+ * plugins/sudoers/Makefile.in:
+ Hack around VPATH semantic differences by symlinking files we need
+ from ../../src into the current directory and build those. A better
+ fix would be to either make a .a or .la file with those files in it
+ or simply use a single, flat, Makefile instead of per-subdirs
+ Makefiles.
+ [892c332d3f05]
+
+ * plugins/sudoers/Makefile.in, src/Makefile.in, src/fmt_string.c:
+ fmt_string is used by the sudoers plugin too so do not include
+ sudo.h (which is not really needed here anyway)
+ [231c35e3941f]
+
+ * compat/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in:
+ Fix building with non-BSD versions of make such as GNU make.
+ Requires VPATH support, which should be in any non-neolithic make.
+ [dc174f135919]
+
+ * configure, configure.in, plugins/sudoers/Makefile.in,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/sudoers.c,
+ src/Makefile.in:
+ Re-enable bsm audit. Currently auditing is done within the sudoers
+ plugin itself. If possible, this should really be done in the main
+ driver but we don't presently have the needed data to do that. This
+ will be re-evaluated when Linux audit support is added.
+ [1d05a3236bfe]
+
+ * compat/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in:
+ Remove extraneous $srcdir and use more .c.lo and .c.o rules instead
+ of explicit rules in the dependency.
+ [88f80efd25f0]
+
+ * plugins/sudoers/visudo.c:
+ Fix mismerge; alias_remove_recursive() now returns int
+ [6257a4849641]
+
+2010-04-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/visudo.c:
+ Fix a crash when checking a sudoers file that has aliases that
+ reference themselves. Based on a diff from David Wood.
+ [545d194484a7]
+
+ * src/script.c:
+ Print signal info after restoring the tty mode, not before.
+ [a68618e67435]
+
+ * src/script.c:
+ Defer call to alarm() until after we fork the child. Pass correct
+ pid to terminate_child() If the command exits due to signal, set
+ alive to false like we do when it exits normally. Add missing check
+ for errpipe[0] != -1 before using it in FD_ISSET
+ [22f0a1549391]
+
+2010-04-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/boottime.c:
+ Use 1/0 instead of TRUE/FALSE so we don't need sudoers.h
+ [0e627170c6e8]
+
+2010-04-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/Makefile.in:
+ Simplify dependencies by using .c.o and .c.lo rules.
+ [6abcaef5d1ac]
+
+ * configure, configure.in, plugins/sudoers/Makefile.in,
+ src/Makefile.in:
+ Substitute in @PROGS@ into src/Makefile to add sesh
+ [cc46d3b6208f]
+
+2010-04-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Add back calls to log_denial() if sudoers does not allow the
+ command.
+ [9783316207f0]
+
+ * plugins/sudoers/sudoers.c:
+ Pass in correct pwflag for list and validate.
+ [973dd56d4b81]
+
+ * plugins/sudoers/env.c:
+ Add missing check for NULL in validate_env_vars
+ [1d6eb6957824]
+
+ * src/Makefile.in:
+ Add sudo_noexec.la to "all" target, otherwise it only gets built at
+ install time.
+ [644a9694d2ef]
+
+ * plugins/sudoers/sudoers.c:
+ Only set sudo_user.env_vars if the env_add list is empty.
+ [fccdf6f0e0e2]
+
+ * plugins/sudoers/sudoers.c:
+ Set sudo_user.env_vars so that environment variables specified on
+ the command line get logged correctly.
+ [9b51012c491e]
+
+ * plugins/sudoers/env.c, plugins/sudoers/logging.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Re-enable environment files and setting environment variables on the
+ command line.
+ [5662d5645dbd]
+
+2010-04-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c:
+ Fix typo in last commit (ifndef vs ifdef) Make sure we pass ctime()
+ a pointer to time_t as tv_sec in struct timeval may be long.
+ [4de0c46e788e]
+
+ * plugins/sudoers/check.c:
+ Don't stash ctime in on-disk tty ticket info for now; on many
+ (most?) systems the ctime is updated when the tty is written to.
+ Once I have a better idea of what systems do not update ctime on
+ ttys (and have a way to test for this) the ctime stash will be
+ conditionally re-enabled.
+ [a90eeec0f648]
+
+2010-04-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * MANIFEST, Makefile.in:
+ Add back "dist" target, this time using a MANIFEST file
+ [29277c05499f]
+
+ * Makefile.in:
+ Remove Makefile in distclean target
+ [83d695f4f450]
+
+ * Makefile.in, src/Makefile.in:
+ Update clean and cleandir targets
+ [ad7b2afeb9c1]
+
+ * include/fileops.h, plugins/sudoers/sudoers.h, src/fileops.c,
+ src/sudo.h:
+ Move fileops.c defines and prototypes to filesops.h
+ [4545e9b6892d]
+
+ * plugins/sudoers/check.c:
+ Lock the tty timestamp when writing. We shouldn't have to lock when
+ reading since the file is updated via a single write system call.
+ [0c7276f02696]
+
+2010-04-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/alias.c, plugins/sudoers/check.c,
+ plugins/sudoers/defaults.c, plugins/sudoers/find_path.c,
+ plugins/sudoers/getspwuid.c, plugins/sudoers/gettime.c,
+ plugins/sudoers/goodpath.c, plugins/sudoers/interfaces.c,
+ plugins/sudoers/iolog.c, plugins/sudoers/ldap.c,
+ plugins/sudoers/logging.c, plugins/sudoers/match.c,
+ plugins/sudoers/nonunix.h, plugins/sudoers/parse.c,
+ plugins/sudoers/pwutil.c, plugins/sudoers/redblack.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/timestr.c, plugins/sudoers/tsgetgrpw.c,
+ plugins/sudoers/vasgroups.c, plugins/sudoers/visudo.c:
+ Convert to ANSI C function declarations
+ [9c45def57cf7]
+
+ * plugins/sudoers/sudoers.h:
+ Remove extraneous bits and classify by source file.
+ [e8ea9f109ebb]
+
+ * include/compat.h:
+ Add timercmp macro for systems without it
+ [d3bf87b1d08e]
+
+ * plugins/sudoers/boottime.c, plugins/sudoers/check.c,
+ plugins/sudoers/sudoers.h:
+ get_boottime() now fills in a timeval struct
+ [3573c3f44e11]
+
+ * plugins/sudoers/check.c:
+ Store info from stat(2)ing the tty in the tty ticket when tty
+ tickets are in use. On most systems, this closes the loophole
+ whereby a user can log out of a tty, log back in and still have the
+ timestamp be valid.
+ [53380f9f5242]
+
+ * config.h.in, configure.in:
+ Add timespec2timeval and use it when getting ctime/mtime
+ [4cb7f7caec2c]
+
+2010-04-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/set_perms.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/testsudoers.c:
+ Convert perm setting to push/pop model; still needs some work Use
+ the stashed runas groups instead of using getgrouplist() Reset perms
+ to the initial value on error
+ [09c072ebde8b]
+
+ * config.h.in, configure.in:
+ fix ctim_get and mtim_get macros
+ [58773dc1e360]
+
+ * config.h.in, configure, configure.in, include/compat.h,
+ plugins/sudoers/check.c, plugins/sudoers/gettime.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/visudo.c, src/fileops.c:
+ Use timeval directly instead of converting to timespec when dealing
+ with file times and time of day.
+ [a0ce1ae00a67]
+
+ * plugins/sudoers/Makefile.in:
+ Don't like sudoreplay with libsudoers.la due to a yacc symbol
+ conflict.
+ [f1a59cc63a15]
+
+2010-04-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Darwin >= 9.x has real setreuid(2)
+ [7ec942a64275]
+
+2010-04-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/env.c, plugins/sudoers/sudoers.h:
+ Ansify env.c
+ [f58551bad10a]
+
+ * plugins/sudoers/env.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Remove remaining references to the environ pointer.
+ [96faa530816a]
+
+2010-04-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, plugins/sudoers/env.c:
+ Don't change the environ directly in the sudoers plugin
+ [6db48ed3f7e0]
+
+2010-04-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Fix typo
+ [4aa452b07f8f]
+
+ * plugins/sudoers/alias.c:
+ Fix use after free in error message when a duplicate alias exists.
+ [ce1d2812ee34]
+
+2010-04-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod,
+ src/parse_args.c:
+ Add a "noninteractive" boolean to the settings passed in to the
+ plugin's open function that is set when the user specifies the -n
+ flag.
+ [68f8d9d6d4d0]
+
+ * config.h.in, configure, configure.in, plugins/sudoers/env.c:
+ Add workaround for the lack of the environ pointer on Mac OS X in
+ dlopen()ed modules. Use of environ in the sudoers plugin should
+ ultimately be removed but this will do for the moment.
+ [80c61647434f]
+
+ * plugins/sudoers/visudo.c:
+ Set errorfile to the sudoers path if we set parse_error manually.
+ This prevents a NULL dereference in printf() when checking a sudoers
+ file in strict mode when alias errors are present.
+ [45e249ca99f7]
+
+ * plugins/sudoers/sudoers.c:
+ Main sudo no longer print "unable to execute" on exec failure so do
+ it here.
+ [50aaf62b43b5]
+
+2010-04-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/script.c:
+ Use a pipe to pass back errno to the parent if execve() fails. If we
+ get an error in script_child(), kill the command and exit.
+ [dc3bf870f91b]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod,
+ src/parse_args.c, src/sudo.c:
+ Handle plugin's open function returning -2 (usage error).
+ [aadf900c1de8]
+
+ * src/script.c:
+ If execve() fails, leave it to the plugin to print an error string.
+ [e25748f2d5b9]
+
+ * src/script.c:
+ If execve fails in logging mode, pass the errno directly to the
+ grandparent on the backchannel and exit. The immediate parent will
+ get SIGCHLD and try to report that status but its parent will no
+ longer be listening. It would probably be cleaner to pass this over
+ a pipe in script_child().
+ [cb122acc81a8]
+
+ * plugins/sudoers/sudoers.c:
+ Don't override rval with results of check_user() unless it failed.
+ [46fb7e87ac7d]
+
+2010-04-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod:
+ Fix typo
+ [ccd0b693f3da]
+
+ * src/parse_args.c:
+ NULL-terminate env_add
+ [2c534368a0c3]
+
+2010-04-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo.c:
+ Call the I/O log open function before the I/O version function.
+ [e88bf898990b]
+
+ * plugins/sudoers/iolog.c:
+ Remove io_conv and just use sudo_conv
+ [a280052468eb]
+
+ * plugins/sudoers/set_perms.c:
+ Fix set/restore perms for systems w/o setresuid
+ [4160517f6666]
+
+2010-04-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/check.c, plugins/sudoers/logging.c,
+ plugins/sudoers/parse.c, plugins/sudoers/set_perms.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h:
+ Primitive set/restore permissions. Will be replaced by a push/pop
+ model.
+ [aae102290866]
+
+ * src/script.c:
+ Only need to take action on SIGCHLD in parent if no I/O logger. If
+ there is an I/O logger we will receive ECONNRESET or EPIPE when we
+ try to read from the socketpair.
+ [e1e4560401f6]
+
+2010-04-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/memrchr.c, doc/sudoers.cat, doc/sudoers.man.in,
+ doc/sudoers.pod, plugins/sudoers/find_path.c:
+ Merge fb4d571495fa from the 1.7 branch to trunk.
+ [c8fb424ad4d2]
+
+2010-04-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/script.c:
+ Don't set SA_RESTART when registering SIGALRM handler. Do set
+ SA_RESTART when registering SIGWINCH handler.
+ [173472b76525]
+
+ * doc/Makefile.in:
+ Add dev targets for *.man.in and *.cat that don't specfify the
+ $(srcdir) prefix.
+ [b62f425da2e4]
+
+ * src/script.c:
+ If log_input or log_output returns false, terminate the command.
+ [074f4c0c34a0]
+
+ * src/script.c:
+ Better signal handling. Instead of using a single variable to store
+ the received signal, use an array so we can't lose a signal when
+ multiple are sent. Fix process termination by SIGALRM in non-I/O
+ logger mode. Fix relaying terminal signals to the child in non-I/O
+ logger mode.
+ [7a4723aca99d]
+
+ * src/script.c:
+ Fix a race between when we get the child pid in the parent and when
+ the child process exits. The problem exhibited as a hang after a
+ short-lived process, e.g. "sudo id" when no IO logger was enabled.
+ [80bcc0aca70b]
+
+2010-04-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * doc/sudoers.cat, doc/sudoers.man.in, doc/sudoers.pod:
+ Add a note about the security implications of the fast_glob option.
+ [c37a92ab7c93]
+
+2010-04-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in:
+ Fix up some AC_DEFINE descriptions and regen config.h.in
+ [f4655adc0db3]
+
+2010-04-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/missing.h:
+ No longer check for strdup or strndup for LIBOBJ replacement.
+ [fdc764ee8109]
+
+ * src/script.c:
+ Avoid installing signal handlers that are io-logger specific. Fixes
+ job control when no io logger is enabled.
+ [0853dd0906d4]
+
+ * doc/Makefile.in:
+ Only regen man pages from pod when configured with --with-devel
+ [ab1995f8103d]
+
+2010-04-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile, Makefile.in, configure, configure.in:
+ Top-level Makefile.in. Nothing is currently substituted but this is
+ needed for separate build dirs.
+ [e80873cbd201]
+
+ * compat/Makefile.in, doc/Makefile.in, plugins/sample/Makefile.in,
+ plugins/sudoers/Makefile.in, src/Makefile.in:
+ Fix out-of-tree builds
+ [59a35bef07b8]
+
+ * Merge
+ [386b848047e9]
+
+ * doc/Makefile.in:
+ We always install sudoreplay in 1.8
+ [ce52ba6617c9]
+
+2010-04-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/siglist.in:
+ SIGPOLL is sometimes the same as SIGIO (like on HP-UX)
+ [6d69e1b05faf]
+
+2010-04-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ No need to provide strdup() or strndup(), sudo uses estrdup() and
+ estrndup()
+ [57ec23b72958]
+
+2010-04-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/iolog.c, plugins/sudoers/sudoers.c:
+ Free str after using it in the version method. Use sudo_conv, not
+ io_conv since we don't have the IO conversation function pointer in
+ the I/O version method anymore now that io_open is delayed.
+ [f2ed132adeb0]
+
+2010-04-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/Makefile.in, compat/mksiglist.c, compat/mksiglist.h,
+ compat/siglist.in:
+ Add license to mksiglist.c and note that the bits from pdksh are
+ public domain
+ [d8121a2467e8]
+
+ * compat/Makefile.in:
+ Fix LIBOBJDIR vs. srcdir wrt the siglist bits
+ [164160148421]
+
+ * plugins/sudoers/Makefile.in:
+ Add sudoreplay testsudoers and visudo to clean target
+ [138a17e51c0c]
+
+ * compat/Makefile.in, compat/mksiglist.c, compat/mksiglist.h,
+ compat/siglist.in, compat/strsignal.c, configure, configure.in,
+ include/missing.h, src/script.c:
+ Create our own sys_siglist for systems without it for use by
+ strsignal()
+ [2e5da011ebc3]
+
+ * compat/Makefile.in:
+ Remove duplicate $(LIBOBJDIR)
+ [adf9abc9432f]
+
+2010-04-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c, src/sudo.c, src/sudo_edit.c:
+ Main sudo should not block signals; the plugin should do this in
+ check_policy.
+ [3f3736a7c5ed]
+
+2010-03-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/script.c:
+ Fix a sizeof(ptr) vs. sizeof(*ptr)
+ [aa1bcf5afcce]
+
+ * src/script.c:
+ Unlike most operating systems, HP-UX select() is not interrupted by
+ SIGCHLD when the signal is registered with SA_RESTART. If we clear
+ SA_RESTART when calling sigaction() for SIGCHLD we get the expected
+ behavior and the code in the select() loops already handles EINTR
+ correctly.
+ [9eba0115e35a]
+
+ * compat/getprogname.c:
+ progname should be const
+ [130228f062b7]
+
+ * plugins/sudoers/Makefile.in:
+ Move --tag=disable-static to when we link sudoers.la, not when we
+ install.
+ [ceb5e6c3b78b]
+
+ * src/load_plugins.c:
+ Load the sudoers I/O plugin by default too now that it is hooked up.
+ [ea38befd0742]
+
+2010-03-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/pty.c:
+ It looks like AIX doesn't need to push STREAMS modules for ptys.
+ [22da618ba0a1]
+
+2010-03-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/parse_args.c, src/sudo.c:
+ Delay calling the I/O plugin open function until the policy plugin
+ returns success.
+ [f3297c325b48]
+
+2010-03-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/iolog.c,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Add back io logging (transcript) support. Currently, the open
+ function runs too early and it is not possible to use the io module
+ independently of the policy module.
+ [9bd932f66226]
+
+ * plugins/sudoers/set_perms.c:
+ Comment out dead code; will be removed when set_perms is rewritten.
+ [af7a995284f8]
+
+2010-03-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Fix off by one error when allocating user_groups.
+ [6281fcf9c3bb]
+
+2010-03-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in, plugins/sudoers/Makefile.in:
+ Add REPLAY_LIBS for sudoreplay and add -lrt to it on Solaris.
+ [fbce3e9eda3a]
+
+ * plugins/sudoers/sudoers.c:
+ Fix typo in preserve groups case
+ [1fd72024fb5a]
+
+ * plugins/sudoers/sudoers.c:
+ In command_info it is "runas_groups" not "groups".
+ [5c64dce4f285]
+
+ * src/sudo.c:
+ Fix iteration over runas_groups list.
+ [b3c45a0cd643]
+
+ * configure, configure.in, plugins/sudoers/env.c,
+ plugins/sudoers/match.c, src/script.c:
+ Merge 5177a284b9ff 549f8f7c2463 88f3181692fe from 1.7 branch.
+ [a8108a0776c2]
+
+ * compat/getgrouplist.c:
+ getgrouplist(3) for those without it
+ [4ab4d21e3b16]
+
+ * plugins/sudoers/sudoers.c:
+ Set preserve_groups or groups list in command_info
+ [1266119ad654]
+
+ * src/sudo.c:
+ Fix setting of groups list
+ [e75315e40bd4]
+
+ * config.h.in, configure, configure.in, include/compat.h,
+ include/missing.h:
+ Add checks for getgrset and getgrouplist and use replacement
+ getgrouplist if the system doesn't support it.
+ [a62b8ba50863]
+
+ * src/parse_args.c:
+ Pass in preserve_groups when the -P flag is specified as per the
+ design
+ [7420c5d15474]
+
+ * plugins/sudoers/sudoers.c:
+ Check preserve_groups and ignore_ticket args with atobool instead of
+ assuming they are true if present.
+ [71c905702697]
+
+2010-03-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/error.c,
+ plugins/sudoers/plugin_error.c:
+ Rename plugin-specific error.c to plugin_error.c Wire up visudo,
+ sudoreplay and testsudoers in the build
+ [9d581d5fa4d4]
+
+ * src/Makefile.in, src/term.c:
+ term.c does not needto include sudo.h
+ [f6683cdcd2dd]
+
+ * TODO, doc/sudo_plugin.cat, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.pod:
+ Document the -2 return in the check_policy section too
+ [e9cb4c34bbcf]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ src/parse_args.c, src/sudo.c, src/sudo.h:
+ Fix the -s and -i flags and add support for the "implied_shell"
+ option. If the user does not specify a command, sudo will now pass
+ in the path to the user's shell and set impied_shell=true. The
+ plugin can them either check the command normally or return -2 to
+ cause sudo to print a usage message and exit.
+ [bf889c38f229]
+
+2010-03-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, src/load_plugins.c:
+ Bring back SUDOERS_PLUGIN but add .dylib -> .so conversion for
+ Darwin where libraries end in .dylib but modules end in .so
+ [2c56aaa38e21]
+
+ * plugins/sudoers/parse.c:
+ Better prefix determination now that we can't rely on len==0 to tell
+ the beginning on an entry.
+ [622bf18179e9]
+
+ * plugins/sudoers/ldap.c:
+ display_bound_defaults() stub should return 0, not 1 since it is a
+ count, not a boolean.
+ [0327a6c3d55d]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Document progname in settings
+ [42031d56a2e3]
+
+ * compat/getprogname.c, include/compat.h,
+ plugins/sample/sample_plugin.c, plugins/sudoers/sudoers.c,
+ src/parse_args.c, src/sudo.c:
+ Rewrite compat/getprogname.c and add setprogname(). The progname is
+ now passed to the plugin via the settings array.
+ [25d8663e6006]
+
+ * configure, configure.in, plugins/sudoers/Makefile.in:
+ Fix --with-ldap
+ [b64b633f426d]
+
+ * plugins/sudoers/sudo_nss.c:
+ Add missing whitespace for Runas and Command-specific defaults
+ [65f4ddf5545e]
+
+ * plugins/sudoers/ldap.c, plugins/sudoers/parse.c,
+ plugins/sudoers/sudo_nss.c:
+ Use embedded newlines in lbuf instead of multiple calls to
+ lbuf_print.
+ [eed3af9cc3e1]
+
+ * src/lbuf.c:
+ Add support for embedded newlines.
+ [e11f79b18deb]
+
+2010-03-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/getprogname.c:
+ If system doesn't support getprogname or __programe and we are
+ building a shared object don't bother with Argc/Argv, just return
+ "sudo"
+ [aebde9062be7]
+
+ * config.h.in, configure, configure.in, src/load_plugins.c:
+ Hard-code sudoers.so instead of using SUDOERS_PLUGIN since libtool
+ appears to always install a shared object with the .so suffix.
+ [f9bbd0c0e9d3]
+
+ * compat/Makefile.in, configure, configure.in,
+ plugins/sample/Makefile.in, plugins/sudoers/Makefile.in,
+ src/Makefile.in:
+ Play more nicely with libtool and let it build libreplace (was
+ libmissing) for us.
+ [a4c6ebb2495c]
+
+ * include/missing.h:
+ Include stdarg.h for va_list rather than requiring all consumers of
+ missing.h to include stdarg.h themselves.
+ [37382df948de]
+
+ * include/lbuf.h, plugins/sudoers/auth/sudo_auth.c,
+ plugins/sudoers/check.c, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h, src/lbuf.c,
+ src/parse_args.c:
+ Pass in output function to lbuf_init() instead of writing to stdout.
+ A side effect is that the usage info can now go to stderr as it
+ should.
+ [6d261261a072]
+
+2010-03-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/lbuf.h, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h, src/lbuf.c,
+ src/parse_args.c, src/sudo.c:
+ Use number of tty columns that is passed in user_info instead of
+ getting it directly in the lbuf code.
+ [8a16635c2638]
+
+ * plugins/sudoers/alias.c, plugins/sudoers/auth/dce.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/sia.c, plugins/sudoers/auth/sudo_auth.h,
+ plugins/sudoers/check.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/defaults.h, plugins/sudoers/env.c,
+ plugins/sudoers/getdate.c, plugins/sudoers/getdate.y,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.y,
+ plugins/sudoers/interfaces.h, plugins/sudoers/logging.c,
+ plugins/sudoers/logging.h, plugins/sudoers/match.c,
+ plugins/sudoers/mon_systrace.h, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/pwutil.c,
+ plugins/sudoers/redblack.c, plugins/sudoers/redblack.h,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudo_nss.h,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/sudoreplay.c, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/timestr.c, plugins/sudoers/toke.c,
+ plugins/sudoers/toke.l, plugins/sudoers/tsgetgrpw.c,
+ plugins/sudoers/visudo.c:
+ Kill __P in sudoers
+ [63601e6cb171]
+
+ * config.h.in, configure, configure.in, src/load_plugins.c:
+ Set the sudoers plugin name in configure so we get the extension
+ right.
+ [edad89924cd1]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Document lines/cols in user_info
+ [a808872394f3]
+
+ * src/Makefile.in, src/sudo.c, src/sudo.h, src/ttysize.c:
+ Add tty size to user info
+ [23f3d27e77a7]
+
+ * src/script.c:
+ Use TIOCGSIZE/TIOCSSIZE instead of TIOCGWINSZ/TIOCSWINSZ
+ [a2208dd09051]
+
+2010-03-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c:
+ Kill dead code Add missing sigsetjmp in sudo_policy_invalidate Error
+ out if we fail to lookup the user's name that is passed in
+ [e4e3728ed482]
+
+ * plugins/sudoers/error.c:
+ Pass the error value back via siglongjmp.
+ [667b8ad575ce]
+
+ * plugins/sudoers/check.c:
+ Use conversation function for lecture.
+ [1ab4719f509b]
+
+ * plugins/sudoers/check.c:
+ Don't update ticket file if verify_user returns FALSE.
+ [2bbc46a39a2b]
+
+2010-03-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/sudoers.c, src/sudo.c:
+ Wire up invalidate and validate methods for sudoers
+ [c0630c7bca47]
+
+ * plugins/sudoers/check.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h:
+ Add support for -k flag with a command.
+ [edad239b098b]
+
+ * src/parse_args.c:
+ Allow -k to be specified with a command.
+ [43a45add9974]
+
+ * plugins/sudoers/sudoers.c:
+ Wire up policy_list
+ [27cc35699eca]
+
+ * plugins/sudoers/error.c:
+ Add newline at the end of message and space after the colon in
+ warning message
+ [5a591aa8e744]
+
+ * plugins/sudoers/auth/sudo_auth.c:
+ Add missing newline after pass password warning
+ [337dba3870a7]
+
+ * plugins/sudoers/sudoers.c:
+ Set user_groups and user_ngroups based on user_info
+ [61bee85128c8]
+
+ * plugins/sudoers/error.c:
+ Make this compile
+ [7041c441e1c8]
+
+ * plugins/sudoers/error.c, plugins/sudoers/sudoers.c:
+ Make _warning in error.c use the conversation function and remove
+ commented out warning/warningx in sudoers.c.
+ [7c9b09024b63]
+
+ * plugins/sudoers/logging.c:
+ Use siglongjmp() in log_error for fatal errors
+ [b50e26f1c73f]
+
+ * plugins/sample/Makefile.in, plugins/sudoers/Makefile.in:
+ Quiet a libtool warning
+ [b2331fb006bc]
+
+ * Makefile:
+ Build sudoers plugin
+ [5cdf06e66978]
+
+ * plugins/sudoers/gram.c, plugins/sudoers/gram.y:
+ Use warningx in yyerror() so the conversation function gets used
+ when built as part of sudoers.
+ [85f964215eef]
+
+2010-03-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sudoers/auth/pam.c:
+ Rename sudo_conv to conversation to avoid a namespace conflict.
+ [1ad359d36be9]
+
+ * plugins/sudoers/Makefile.in, plugins/sudoers/alias.c,
+ plugins/sudoers/auth/afs.c, plugins/sudoers/auth/aix_auth.c,
+ plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/dce.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/kerb4.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/securid.c,
+ plugins/sudoers/auth/securid5.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/auth/sudo_auth.h,
+ plugins/sudoers/check.c, plugins/sudoers/defaults.c,
+ plugins/sudoers/env.c, plugins/sudoers/error.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/getspwuid.c,
+ plugins/sudoers/goodpath.c, plugins/sudoers/gram.c,
+ plugins/sudoers/gram.y, plugins/sudoers/interfaces.c,
+ plugins/sudoers/ldap.c, plugins/sudoers/logging.c,
+ plugins/sudoers/match.c, plugins/sudoers/mon_systrace.c,
+ plugins/sudoers/parse.c, plugins/sudoers/pwutil.c,
+ plugins/sudoers/redblack.c, plugins/sudoers/set_perms.c,
+ plugins/sudoers/sudo_nss.c, plugins/sudoers/sudoers.c,
+ plugins/sudoers/sudoers.h, plugins/sudoers/testsudoers.c,
+ plugins/sudoers/toke.c, plugins/sudoers/tsgetgrpw.c,
+ plugins/sudoers/vasgroups.c, plugins/sudoers/visudo.c:
+ Initial bits of sudoers plugin; still needs work.
+ [af2a2c59a952]
+
+ * config.h.in:
+ Add HAVE_STRDUP and HAVE_STRNDUP
+ [50a3c0dd510f]
+
+ * compat/Makefile.in, configure, configure.in:
+ Build libmissing in two flavors (one PIC one non-PIC) and link with
+ the appropriate one.
+ [b62f411a4c18]
+
+ * Makefile, compat/fnmatch.c, compat/glob.c, compat/nanosleep.c,
+ compat/utimes.c, plugins/sample/Makefile.in, src/Makefile.in:
+ Build libmissing in two flavors (one PIC one non-PIC) and link with
+ the appropriate one.
+ [e1e04972b5fe]
+
+2010-03-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * include/missing.h:
+ Add strdup and strndup and fix strsignal
+ [c159babe2896]
+
+2010-03-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat/strdup.c, compat/strndup.c, configure, configure.in,
+ plugins/sample/Makefile.in, src/Makefile.in:
+ Add strdup and strndup to compat
+ [25c9fd399a4d]
+
+ * plugins/sample/sample_plugin.c:
+ Need to include compat.h before missing.h
+ [c94f7aad380f]
+
+ * compat/strsignal.c:
+ Must check HAVE_DECL_SYS_SIGLIST == 1 (not just if defined) since if
+ it doesn't exist configure will set it to 0.
+ [384580566389]
+
+ * compat/glob.c:
+ Fix botched ANSI C coversion of globexp2()
+ [4a344b8cbe49]
+
+ * configure, configure.in:
+ Remove redundant getgroups check
+ [0b16ec210c81]
+
+ * configure, configure.in, src/lbuf.c, src/script.c, src/term.c:
+ Require either termios or termio, no more sgtty.
+ [9b2fa2f17a1c]
+
+ * compat/strsignal.c, config.h.in, configure, configure.in:
+ Change the sys_siglist check to use AC_CHECK_DECLS and also check
+ for _sys_siglist and__sys_siglist
+ [2e078fed2408]
+
+2010-03-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in, src/Makefile.in:
+ Change SUDO_LDFLAGS to SUDOERS_LDFLAGS and add SUDOERS_OBJS. We now
+ use SUDO_OBJS for the main driver as part of OBJS.
+ [9ae4a80a5ade]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Mention in the conversation function section that a newline is not
+ implicit.
+ [04a233b6c491]
+
+ * include/compat.h:
+ Add definition of WCOREDUMP for systems without it. This is known to
+ work on AIX and SunOS 4, but may be incorrect on other systems that
+ lack WCOREDUMP.
+ [c85b3ce6b77d]
+
+2010-03-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sample/sample_plugin.c, src/conversation.c:
+ conversation function no longer puts a newline at the end of info or
+ error messages.
+ [c534cae1ac4a]
+
+2010-03-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/script.c:
+ Use parent process group id instead of parent process id when
+ checking foreground status and suspending parent. Fixes an issue
+ when running commands under /usr/bin/time and others.
+ [564f528c3bb7]
+
+2010-03-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4:
+ transcript option is now --with not --enable
+ [0646fac4cf93]
+
+ * plugins/sample/sample_plugin.c:
+ Add support to -u and -g flags Check fmt_string retval Add timeout
+ for debugging purposes
+ [cfefa4fa60b5]
+
+ * src/script.c, src/sudo.c:
+ Wire up SIGALRM handler Set close on exec flag for child side of the
+ socketpair Fix signal handling when not doing I/O logging
+ [379581ec7272]
+
+ * src/sudo.c:
+ g/c unused SIGCHLD handler
+ [0afa03912dce]
+
+ * src/fmt_string.c, src/parse_args.c, src/sudo.c:
+ Don't use emalloc() in fmt_string(); we want to be able to use it
+ from a plugin.
+ [ade64d368147]
+
+ * include/list.h:
+ tq_remove not list_remove
+ [0e0e1fd5c31c]
+
+ * configure, configure.in:
+ AUTH_OBJS should contain .lo files not .o files.
+ [c64c82c9d5a2]
+
+2010-03-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/parse_args.c:
+ Simplify conversion of command line args to name=value pairs.
+ [75ab127c6a94]
+
+ * plugins/sample/sample_plugin.c:
+ Handle NULL reply from conversation function
+ [6ce09b6cb204]
+
+ * compat/getline.c:
+ Don't depend on emalloc/erealloc
+ [73df09e2109f]
+
+ * plugins/sample/Makefile.in:
+ Use $(OBJS) instead of sample_plugin.lo
+ [2d995db9aa99]
+
+ * plugins/sample/sample_plugin.c:
+ runas_user is in settings not user_info
+ [7ee12068bc57]
+
+ * src/parse_args.c:
+ Fix a mismatch between sudo_settings and settings_pairs that causes
+ some settings to get the wrong values.
+ [b1bc6d81a65f]
+
+2010-03-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/Makefile.in, src/aix.c, src/alloc.c, src/atobool.c, src/error.c,
+ src/fileops.c, src/lbuf.c, src/list.c, src/pty.c, src/sesh.c,
+ src/sudo.c, src/sudo_edit.c, src/term.c, src/zero_bytes.c:
+ Convert to ANSI C
+ [d03b6e4a3b75]
+
+ * src/load_plugins.c:
+ Fix strlcpy() return value check.
+ [7cd66999a374]
+
+ * INSTALL, configure, configure.in:
+ No longer need to substitute in script.o and pty.o; I/O logging
+ support is always built.
+ [45250024c5dc]
+
+2010-02-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/script.c:
+ Add fallback to /bin/sh when execve() fails with ENOEXEC.
+ [7684a15a1352]
+
+ * include/alloc.h, src/alloc.c:
+ Add estrndup()
+ [47621c83bed9]
+
+2010-02-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/script.c, src/sudo.c:
+ Refactor script_execve() a bit so that it can be used in non-script
+ mode. Needs more cleanup.
+ [f09e022d547c]
+
+ * src/sudo.c:
+ Ignore empty entries in command_info list
+ [1eea9a8de21c]
+
+ * include/list.h, src/list.c:
+ Add tq_remove
+ [40908a617cb2]
+
+ * src/conversation.c:
+ Pass timeout to tgetpass()
+ [9e66c918b771]
+
+ * Makefile:
+ Add ChangeLog target
+ [da4a39150838]
+
+ * README, WHATSNEW:
+ Bump version and update things slightly for sudo 1.8.0
+ [4b73cc45e2d4]
+
+ * configure, configure.in:
+ Sudo now requires an ANSI/ISO C compiler
+ [1e51f72e6964]
+
+ * src/alloc.c, src/audit.c, src/error.c, src/lbuf.c,
+ src/sudo_noexec.c:
+ Convert to ANSI C
+ [5cbd315dbde8]
+
+ * include/alloc.h, include/compat.h, include/error.h, include/lbuf.h,
+ include/list.h, include/missing.h:
+ Convert to ANSI C
+ [3f5016ff64f4]
+
+ * compat/charclass.h, compat/closefrom.c, compat/fnmatch.c,
+ compat/fnmatch.h, compat/getcwd.c, compat/getline.c,
+ compat/getprogname.c, compat/glob.c, compat/glob.h,
+ compat/isblank.c, compat/memrchr.c, compat/mkstemp.c,
+ compat/nanosleep.c, compat/sigaction.c, compat/snprintf.c,
+ compat/strcasecmp.c, compat/strerror.c, compat/strlcat.c,
+ compat/strlcpy.c, compat/strsignal.c, compat/utime.h,
+ compat/utimes.c:
+ Convert to ANSI C
+ [0d635c85461c]
+
+2010-02-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/sudo.c, src/tgetpass.c:
+ Make user_details extern so tgetpass can get at the uid and gid. Set
+ uid/gid to user before executing askpass program. Check environment
+ for SUDO_ASKPASS and use that if set. TODO: a way for the policy to
+ set the askpass program itself
+ [d33606396176]
+
+ * src/sudo.c:
+ No longer need sudo_usage.h in sudo.c
+ [063e2946c382]
+
+ * doc/sudo.cat, doc/sudo.man.in, doc/sudo.pod, doc/sudo_plugin.man.in,
+ doc/sudo_plugin.pod, src/Makefile.in, src/parse_args.c,
+ src/sudo_usage.h.in:
+ Document -D level command line flag which maps to the debug_level
+ setting.
+ [61f1e2ab3ac1]
+
+ * doc/sudo_plugin.cat, doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Document debug_level in plugin doc. Still need to document the -D
+ flag in sudo itself.
+ [8c62daea3e9b]
+
+2010-02-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * plugins/sample/sample_plugin.c:
+ include missing,h for vasprintf
+ [92503de49b39]
+
+ * doc/Makefile.in, doc/plugin.pod, doc/sudo_plugin.cat,
+ doc/sudo_plugin.man.in, doc/sudo_plugin.pod:
+ Rename plugin.pod -> sudo_plugin.pod and wire into Makefile
+ [14cfb4775238]
+
+ * plugins/sample/sample_plugin.c:
+ Need to include limits.h
+ [bda7f74343d2]
+
+ * compat/glob.c:
+ No more sudo_getpw*
+ [232e52907634]
+
+ * plugins/sample/Makefile.in, src/Makefile.in:
+ Add missing compat bits
+ [4843dd000e08]
+
+ * compat/closefrom.c, compat/mkstemp.c, plugins/sample/Makefile.in:
+ compat files should not include sudo.h wire up compat in sample
+ plugin
+ [a175b8185e0f]
+
+ * Makefile, configure, configure.in, doc/Makefile.in, src/Makefile.in:
+ Fix up compat dependencies. Fix distclean target in doc/Makefile.in
+ [57e49bc20857]
+
+ * configure, configure.in:
+ Fix typo
+ [333655e3d5fe]
+
+ * plugins/sample/sample_plugin.c:
+ Log input and output to temp files for proof of concept.
+ [ae1dfc34f7d6]
+
+ * Makefile, configure, configure.in, doc/Makefile.in:
+ Add doc Makefile.in and wire it up
+ [6a310443c87d]
+
+ * src/script.c:
+ Handle SIGSTOP in addition to SIGTSTP. Fixes a problem with
+ suspending a shell with the "suspend" builtint.
+ [3d65f182819a]
+
+ * src/script.c:
+ In child, handle parent side of the pipe going away.
+ [a29c14d78cd9]
+
+ * src/script.c:
+ No longer need to check for explicit death of the child (process #2)
+ since if it dies we will get EPIPE from the socketpair. Fix a
+ sizeof() that was causing a spurious error. Convert SCRIPT_DEBUG to
+ sudo_debug.
+ [24c55dd4ff60]
+
+ * src/sudo.c:
+ Make sudo_debug do a single vfprintf() which will result in a single
+ write call on most systems. Avoids problems with interleaved debug
+ printf from different processes. Also remove an extraneous error
+ case since recv() can't return a short read and add some more XXX.
+ [b37a8533ef1e]
+
+2010-02-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * src/script.c:
+ Fix uninitialized variable.
+ [e012a0a30890]
+
+ * src/Makefile.in:
+ Fix sudo install target
+ [1417fa4b4ab9]
+
+ * src/parse_args.c, src/sudo.c, src/sudo.h:
+ Wire up debug_level
+ [144fab289c73]
+
+ * src/Makefile.in:
+ Fix dependencies
+ [5170940af2ce]
+
+ * configure, configure.in:
+ Fix setting of plugin dir
+ [144eda170a72]
+
+ * Makefile:
+ add clean targets
+ [d53f6f6f5c3a]
+
+ * src/atobool.c:
+ Add missing source for sudo front end
+ [42487de9c489]
+
+ * plugins/sample/Makefile.in, plugins/sample/sample_plugin.c:
+ Sample plugin demonstrating the sudo plugin API
+ [f1fd62d7644f]
+
+ * Makefile, configure, configure.in, install-sh, pathnames.h.in,
+ plugins/sudoers/install-sh, src/Makefile.in, src/conversation.c,
+ src/fileops.c, src/fmt_string.c, src/load_plugins.c,
+ src/parse_args.c, src/pty.c, src/script.c, src/sudo.c, src/sudo.h,
+ src/sudo_plugin_int.h, src/sudo_usage.h.in, src/tgetpass.c,
+ sudo_usage.h.in:
+ Modular sudo front-end which loads policy and I/O plugins that do
+ most the actual work. Currently relies on dynamic loading using
+ dlopen(). See doc/plugin.pod for the plugin API.
+ [924f6eb2fbba]
+
+ * doc/plugin.pod, include/sudo_plugin.h:
+ Sudo plugin API
+ [374ccbbd24ae]
+
+ * compat/fnmatch.c, compat/glob.c, compat/nanosleep.c,
+ compat/utimes.c, plugins/sudoers/check.c, plugins/sudoers/gettime.c,
+ plugins/sudoers/match.c, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/visudo.c,
+ src/fileops.c, src/sudo_edit.c:
+ Replace emul/include.h with compat/include.h to match new source
+ tree layout.
+ [7eccd10449a1]
+
+ * src/lbuf.c:
+ Include missing.h for memrchr() proto
+ [03abd63a8a33]
+
+ * HISTORY, LICENSE, Makefile.binary.in, Makefile.in, PORTING,
+ TROUBLESHOOTING, UPGRADE, aix.c, aixcrypt.exp, alias.c, alloc.c,
+ alloc.h, audit.c, auth/API, auth/afs.c, auth/aix_auth.c,
+ auth/bsdauth.c, auth/dce.c, auth/fwtk.c, auth/kerb4.c, auth/kerb5.c,
+ auth/pam.c, auth/passwd.c, auth/rfc1938.c, auth/secureware.c,
+ auth/securid.c, auth/securid5.c, auth/sia.c, auth/sudo_auth.c,
+ auth/sudo_auth.h, boottime.c, bsm_audit.c, bsm_audit.h, check.c,
+ closefrom.c, compat.h, compat/charclass.h, compat/closefrom.c,
+ compat/fnmatch.c, compat/fnmatch.h, compat/getcwd.c,
+ compat/getline.c, compat/getprogname.c, compat/glob.c,
+ compat/glob.h, compat/isblank.c, compat/memrchr.c, compat/mkstemp.c,
+ compat/nanosleep.c, compat/sigaction.c, compat/snprintf.c,
+ compat/strcasecmp.c, compat/strerror.c, compat/strlcat.c,
+ compat/strlcpy.c, compat/strsignal.c, compat/timespec.h,
+ compat/utime.h, compat/utimes.c, def_data.c, def_data.h,
+ def_data.in, defaults.c, defaults.h, doc/HISTORY, doc/LICENSE,
+ doc/PORTING, doc/TROUBLESHOOTING, doc/UPGRADE, doc/history.pod,
+ doc/license.pod, doc/sample.pam, doc/sample.sudoers,
+ doc/sample.syslog.conf, doc/schema.ActiveDirectory,
+ doc/schema.OpenLDAP, doc/schema.iPlanet, doc/sudo.cat,
+ doc/sudo.man.in, doc/sudo.man.pl, doc/sudo.pod, doc/sudoers.cat,
+ doc/sudoers.ldap.cat, doc/sudoers.ldap.man.in, doc/sudoers.ldap.pod,
+ doc/sudoers.man.in, doc/sudoers.man.pl, doc/sudoers.pod,
+ doc/sudoreplay.cat, doc/sudoreplay.man.in, doc/sudoreplay.pod,
+ doc/visudo.cat, doc/visudo.man.in, doc/visudo.pod, emul/charclass.h,
+ emul/fnmatch.h, emul/glob.h, emul/timespec.h, emul/utime.h, env.c,
+ error.c, error.h, fileops.c, find_path.c, fnmatch.c, getcwd.c,
+ getdate.c, getdate.y, getline.c, getprogname.c, getspwuid.c,
+ gettime.c, glob.c, goodpath.c, gram.c, gram.h, gram.y, history.pod,
+ include/alloc.h, include/compat.h, include/error.h, include/lbuf.h,
+ include/list.h, include/missing.h, ins_2001.h, ins_classic.h,
+ ins_csops.h, ins_goons.h, install-sh, insults.h, interfaces.c,
+ interfaces.h, isblank.c, lbuf.c, lbuf.h, ldap.c, license.pod,
+ list.c, list.h, logging.c, logging.h, match.c, memrchr.c, missing.h,
+ mkdefaults, mkstemp.c, mon_systrace.c, mon_systrace.h, nanosleep.c,
+ nonunix.h, parse.c, parse.h, plugins/sudoers/Makefile.binary.in,
+ plugins/sudoers/Makefile.in, plugins/sudoers/aixcrypt.exp,
+ plugins/sudoers/alias.c, plugins/sudoers/auth/API,
+ plugins/sudoers/auth/afs.c, plugins/sudoers/auth/aix_auth.c,
+ plugins/sudoers/auth/bsdauth.c, plugins/sudoers/auth/dce.c,
+ plugins/sudoers/auth/fwtk.c, plugins/sudoers/auth/kerb4.c,
+ plugins/sudoers/auth/kerb5.c, plugins/sudoers/auth/pam.c,
+ plugins/sudoers/auth/passwd.c, plugins/sudoers/auth/rfc1938.c,
+ plugins/sudoers/auth/secureware.c, plugins/sudoers/auth/securid.c,
+ plugins/sudoers/auth/securid5.c, plugins/sudoers/auth/sia.c,
+ plugins/sudoers/auth/sudo_auth.c, plugins/sudoers/auth/sudo_auth.h,
+ plugins/sudoers/boottime.c, plugins/sudoers/check.c,
+ plugins/sudoers/def_data.c, plugins/sudoers/def_data.h,
+ plugins/sudoers/def_data.in, plugins/sudoers/defaults.c,
+ plugins/sudoers/defaults.h, plugins/sudoers/env.c,
+ plugins/sudoers/find_path.c, plugins/sudoers/getdate.c,
+ plugins/sudoers/getdate.y, plugins/sudoers/getspwuid.c,
+ plugins/sudoers/gettime.c, plugins/sudoers/goodpath.c,
+ plugins/sudoers/gram.c, plugins/sudoers/gram.h,
+ plugins/sudoers/gram.y, plugins/sudoers/ins_2001.h,
+ plugins/sudoers/ins_classic.h, plugins/sudoers/ins_csops.h,
+ plugins/sudoers/ins_goons.h, plugins/sudoers/install-sh,
+ plugins/sudoers/insults.h, plugins/sudoers/interfaces.c,
+ plugins/sudoers/interfaces.h, plugins/sudoers/ldap.c,
+ plugins/sudoers/logging.c, plugins/sudoers/logging.h,
+ plugins/sudoers/match.c, plugins/sudoers/mkdefaults,
+ plugins/sudoers/mon_systrace.c, plugins/sudoers/mon_systrace.h,
+ plugins/sudoers/nonunix.h, plugins/sudoers/parse.c,
+ plugins/sudoers/parse.h, plugins/sudoers/pwutil.c,
+ plugins/sudoers/redblack.c, plugins/sudoers/redblack.h,
+ plugins/sudoers/set_perms.c, plugins/sudoers/sudo_nss.c,
+ plugins/sudoers/sudo_nss.h, plugins/sudoers/sudoers,
+ plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h,
+ plugins/sudoers/sudoers2ldif, plugins/sudoers/sudoreplay.c,
+ plugins/sudoers/testsudoers.c, plugins/sudoers/timestr.c,
+ plugins/sudoers/toke.c, plugins/sudoers/toke.l,
+ plugins/sudoers/tsgetgrpw.c, plugins/sudoers/vasgroups.c,
+ plugins/sudoers/visudo.c, pty.c, pwutil.c, redblack.c, redblack.h,
+ sample.pam, sample.sudoers, sample.syslog.conf,
+ schema.ActiveDirectory, schema.OpenLDAP, schema.iPlanet, script.c,
+ selinux.c, sesh.c, set_perms.c, sigaction.c, snprintf.c, src/aix.c,
+ src/alloc.c, src/audit.c, src/bsm_audit.c, src/bsm_audit.h,
+ src/error.c, src/fileops.c, src/lbuf.c, src/list.c, src/pty.c,
+ src/script.c, src/selinux.c, src/sesh.c, src/sudo_edit.c,
+ src/sudo_noexec.c, src/term.c, src/tgetpass.c, src/zero_bytes.c,
+ strcasecmp.c, strerror.c, strlcat.c, strlcpy.c, strsignal.c, sudo.c,
+ sudo.cat, sudo.h, sudo.man.in, sudo.man.pl, sudo.pod, sudo_edit.c,
+ sudo_noexec.c, sudo_nss.c, sudo_nss.h, sudoers, sudoers.cat,
+ sudoers.ldap.cat, sudoers.ldap.man.in, sudoers.ldap.pod,
+ sudoers.man.in, sudoers.man.pl, sudoers.pod, sudoers2ldif,
+ sudoreplay.c, sudoreplay.cat, sudoreplay.man.in, sudoreplay.pod,
+ term.c, testsudoers.c, tgetpass.c, timestr.c, toke.c, toke.l,
+ tsgetgrpw.c, utimes.c, vasgroups.c, visudo.c, visudo.cat,
+ visudo.man.in, visudo.pod, zero_bytes.c:
+ Rework source layout in preparation for modular sudo.
+ [7fc1978c6ad5]
+
+2010-02-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Avoid a duplicate fclose() of the sudoers file.
+ [5dba851088c1]
+
+ * Fix size arg when realloc()ing include stack. From Daniel Kopecek
+ [0a2935061e33]
+
+ * Use setrlimit64(), if available, instead of setrlimit() when setting
+ AIX resource limits since rlim_t is 32bits.
+ [353db89bac61]
+
+ * Fix use after free when sending error messages. From Timo Juhani
+ Lindfors
+ [e50dbd902382]
+
+ * ChangeLog, Makefile.in:
+ Generate the ChangeLog as part of "make dist" instead of having it
+ in the repo.
+ [251b70964673]
+
+2010-01-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.binary.in, Makefile.in, aix.c, alias.c, alloc.c, alloc.h,
+ auth/afs.c, auth/aix_auth.c, auth/bsdauth.c, auth/dce.c,
+ auth/fwtk.c, auth/kerb4.c, auth/kerb5.c, auth/pam.c, auth/passwd.c,
+ auth/rfc1938.c, auth/secureware.c, auth/securid.c, auth/securid5.c,
+ auth/sia.c, auth/sudo_auth.c, auth/sudo_auth.h, check.c,
+ closefrom.c, compat.h, configure.in, defaults.c, defaults.h,
+ emul/charclass.h, emul/timespec.h, env.c, error.c, error.h,
+ fileops.c, find_path.c, getcwd.c, getprogname.c, getspwuid.c,
+ gettime.c, goodpath.c, gram.c, gram.y, ins_2001.h, ins_classic.h,
+ ins_csops.h, ins_goons.h, insults.h, interfaces.c, interfaces.h,
+ isblank.c, lbuf.c, lbuf.h, ldap.c, list.c, list.h, logging.c,
+ logging.h, match.c, memrchr.c, missing.h, mkinstalldirs, mkstemp.c,
+ mon_systrace.c, nanosleep.c, parse.c, parse.h, pathnames.h.in,
+ pty.c, pwutil.c, redblack.c, redblack.h, sample.pam, sample.sudoers,
+ sample.syslog.conf, script.c, selinux.c, sesh.c, set_perms.c,
+ sigaction.c, snprintf.c, strcasecmp.c, strerror.c, strlcat.c,
+ strlcpy.c, strsignal.c, sudo.c, sudo.h, sudo.man.in, sudo.pod,
+ sudo_edit.c, sudo_noexec.c, sudo_nss.c, sudo_nss.h, sudo_usage.h.in,
+ sudoers.ldap.man.in, sudoers.ldap.pod, sudoers.man.in, sudoers.pod,
+ sudoers2ldif, sudoreplay.c, sudoreplay.man.in, sudoreplay.pod,
+ term.c, testsudoers.c, tgetpass.c, timestr.c, toke.c, toke.l,
+ utimes.c, visudo.c, visudo.man.in, visudo.pod, zero_bytes.c:
+ Remove CVS $Sudo$ tags.
+ [de683a8b31f5]
+
+2010-01-18 convert-repo <convert-repo>
+
+ * .hgtags:
+ update tags
+ [9b7aa44ae436]
+
+2009-12-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo_usage.h.in:
+ make this match sudoers SYNOPSIS
+ [c74ba66944c2]
+
+ * lbuf.c, parse.c:
+ Print a newline between Runas and Command-specific defaults in sudo
+ -l.
+ [b5bdfcc9ce4b]
+
+ * term.c:
+ Use SET and CLR macros in term_raw
+ [50ca42609d6c]
+
+ * sudoreplay.c:
+ Set stdin to non-blocking mode early instead of in check_input. Use
+ term_raw instead of term_cbreak since the data we get has already
+ been expanded via OPOST.
+ [51c47e803d62]
+
+2009-12-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c, term.c:
+ Enable/disable all postprocessing instead of just nl->crnl
+ processing since things like tab expansion matter too. However, if
+ stdout is a tty leave postprocessing on in the pty since we run into
+ problems doing it only on the real stdout with .e.g nvi.
+ [62666e309673]
+
+2009-12-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ If tty_tickets is enabled and there is no tty, prompt for a
+ password. Do not lecture user for "sudo -k command" if user has a
+ timestamp.
+ [5880200c5f6b]
+
+ * INSTALL:
+ Document missing options: --with-efence and --with-bsm-audit
+ [d83afcdf9ff3]
+
+ * sudo.cat, sudo.man.in, sudo.pod, sudoers.cat, sudoers.ldap.cat,
+ sudoers.ldap.man.in, sudoers.ldap.pod, sudoers.man.in, sudoers.pod,
+ sudoreplay.cat, sudoreplay.man.in, sudoreplay.pod, visudo.cat,
+ visudo.man.in, visudo.pod:
+ username -> user name groupname -> group name hostname -> host name
+ [10c85646f45d]
+
+ * INSTALL, README.LDAP, sudoers.pod:
+ filename -> file name like the rest of the docs
+ [1ef8ab5a9018]
+
+2009-12-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ Fix printing of entries with multiple host entries on a single line.
+ [226ceaf91d8d]
+
+2009-12-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Mention that targetpw affects the timestamp file name.
+ [a26e22e4f72e]
+
+ * def_data.c, def_data.h, def_data.in, defaults.c, script.c,
+ sudoers.pod:
+ Add compress_transcript option.
+ [6e94f8cb9dfb]
+
+2009-12-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ bump to 1.7.3b2
+ [906d7e347d15]
+
+ * pwutil.c, set_perms.c, sudo.c, sudo_nss.c:
+ Better split of membership vs. traditional group check in
+ user_in_group(). Allow user_ngroups to be < 0 if getgroups() fails.
+ [6ebc55d4716b]
+
+2009-12-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pwutil.c:
+ Fix pasto and add default return value.
+ [7973b5e4599c]
+
+ * check.c, match.c, pwutil.c, sudo.h:
+ refactor group member checking into user_in_group()
+ [48ca8c2eddf8]
+
+ * check.c, config.h.in, configure, configure.in, match.c, sudo.c,
+ sudo.h:
+ Add support for mbr_check_membership() as present in darwin.
+ [5501aed02b9f]
+
+2009-12-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * match.c:
+ Rename label to be accurate
+ [3af17dd960f7]
+
+ * Makefile.in, boottime.c, check.c, config.h.in, configure,
+ configure.in, sudo.h:
+ Treat timestamp files from before we booted as old. Idea from and
+ Apple patch.
+ [5c96e484c05a]
+
+2009-12-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c, sudo.pod, sudo_usage.h.in:
+ Allow the -u flag to be used in conjunction with the -v flag as per
+ older versions of sudo.
+ [591e9fc13c1a]
+
+ * logging.c:
+ fix typo in last commit
+ [4fd0c692dcf0]
+
+2009-12-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ Convert fmt_first and fmt_confd into macros.
+ [32e870158b29]
+
+ * sudoers.pod:
+ timeouts can be floats now
+ [89de639a9679]
+
+ * WHATSNEW, def_data.c, def_data.h, def_data.in, defaults.c,
+ defaults.h, mkdefaults:
+ Add support for floating point timeout values (e.g. 2.5 minutes).
+ [210ffa291733]
+
+2009-12-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod:
+ The -L flag will be removed in sudo 1.7.4
+ [ffd026084333]
+
+2009-12-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoreplay.c:
+ Fix a bug due to order of operators.
+ [938d34464283]
+
+2009-11-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * match.c:
+ cmnd_matches() already deals with negation so _cmndlist_matches()
+ does not need to do so itself. Fixes a bug with negated entries in a
+ Cmnd_List.
+ [71c845f6ce73]
+
+2009-11-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Don't exit() from open_sudoers, just return NULL for all errors.
+ [8cfa832f972a]
+
+ * script.c:
+ Can't rely on the shell sending us SIGCONT when transitioning from
+ backgroup to foreground process.
+ [3c6c5b6cb4b3]
+
+ * toke.c, toke.l:
+ Add missing extern def for parse_error
+ [45b7b59d03b7]
+
+2009-11-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * toke.c, toke.l:
+ Avoid a parse error when #includedir doesn't find any files. Closes
+ bug #375
+ [1ce1b850e9e6]
+
+ * Makefile.in:
+ Include sudo.man.pl and sudoers.man.pl in the distribution tarball.
+ [6a22e32da108]
+
+2009-11-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c:
+ Start command out in foreground mode if stdout is a tty. Works
+ around issues with some curses-based programs that don't handle
+ tcsetattr getting interrupted by a signal. Still allows us to avoid
+ hogging the tty if the command is part of a pipeline.
+ [1c32f2b94769]
+
+ * script.c, sudo.c, sudo.h, sudoreplay.c, term.c, tgetpass.c:
+ Use a socketpair to pass signals from parent to child. Child will
+ now pass command status change info back via the socketpair. This
+ allows the parent to distinguish between signals it has been sent
+ directly and signals the command has received. It also means the
+ parent can once again print the signal notifications to the tty so
+ all writes to the pty master occur in the parent. The command is now
+ always started in background mode with tty signals handled by the
+ parent.
+ [c6790b82986d]
+
+2009-11-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Fix a few typos in the descriptions; from Jeff Makey Only do the
+ check for krb5_get_init_creds_opt_free() taking two arguments if we
+ find krb5_get_init_creds_opt_alloc(). Otherwise we will get a false
+ positive when using our own krb5_get_init_creds_opt_free which takes
+ only a single argument.
+ [845a9ff6f93d]
+
+2009-11-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Remove a spurious comma in the kerb5 bits.
+ [3433eab083db]
+
+ * auth/kerb5.c:
+ Call krb5_get_init_creds_opt_init() in our emulated
+ krb5_get_init_creds_opt_alloc() for MIT kerberos.
+ [7ffb40bf43e9]
+
+2009-11-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ Add HAVE_ZLIB
+ [9297bde61ecc]
+
+ * script.c:
+ Need to ignore SIGTT{IN,OU} in child when running the command in the
+ background. Also some minor cleanup.
+ [dc208d982319]
+
+2009-10-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c:
+ Instead of calling sigsuspend when waiting for SIGUSR[12] from
+ parent, install the signal handlers w/o SA_RESTART and let them
+ interrupt waitpid().
+ [759c7d18203b]
+
+ * script.c:
+ Pass along SIGHUP and SIGTERM from parent to child.
+ [035b0e254568]
+
+ * script.c:
+ Close unused bits of script_fds in processes that don't need them.
+ Restore default SIGCONT handler in child.
+ [e037378ab0c1]
+
+ * script.c:
+ Update foreground/background status in SIGCONT handler in parent
+ process.
+ [3f7f91333264]
+
+2009-10-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c:
+ Defer setting terminal into raw mode until just before we fork() and
+ only do it if sudo is the foreground process. If we get SIGTT{IN,OU}
+ and sudo is already in the foreground be sure to set raw mode before
+ continuing the child.
+ [1102ef40832c]
+
+2009-10-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c:
+ Fix handling of SIGTTOU/SIGTTIN in program being run. We now only
+ give the command the controlling tty if the main sudo process is the
+ foreground process.
+ [cf3a91cb5682]
+
+ * script.c:
+ Don't bother with sudo_waitpid() here for now.
+ [9086de480c2d]
+
+ * script.c:
+ fix non-zlib case
+ [a258bff0f9a6]
+
+2009-10-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c:
+ Remove non-wroking code that crept into rev 1.55
+ [2802dd55cff5]
+
+2009-10-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, configure, configure.in, script.c, sudoreplay.c:
+ First pass at zlib support for transcript data files
+ [5d10260807da]
+
+ * Makefile.in:
+ remove vestiges of ZLDFLAGS
+ [1fa0caf1c0fb]
+
+ * script.c:
+ Add missing variable declaration for when TIOCSCTTY is not defined.
+ Need to include sys/termio.h for TIOCSCTTY on some systems.
+ [ee7f41ac2709]
+
+ * script.c:
+ when resuming command, send SIGCONT to its pgrp not just pid
+ [5cd63c1d565b]
+
+ * selinux.c:
+ remove unused variable
+ [df67df4be228]
+
+ * script.c:
+ include selinux.h for is_selinux_enabled() proto
+ [85ebaa880cc1]
+
+ * script.c:
+ Don't use log_error() in the child process.
+ [def65fe2a433]
+
+ * script.c:
+ Do I/O in parent instead of child since the parent can have both
+ /dev/tty as well as the pty fds open. The child just sets things up
+ and waits for its grandchild and writes the signal description to
+ the pty master if the command was killed by a signal.
+ [95e473208982]
+
+2009-10-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * missing.h, sudo.h:
+ Move two struct forward declarations from sudo.h to missing.h
+ [90ad28294a8c]
+
+ * script.c:
+ Make comment at the top of script_exec() match reality.
+ [c5042d27dbe0]
+
+ * sudo.c:
+ if neither stdin nor stdout is a tty, check stderr
+ [c532ff20c8d8]
+
+ * Makefile.in:
+ Add back dependecy of gram.h on gram.y
+ [c58382b7fcca]
+
+ * script.c:
+ Make transcript mode work as long as we can figure out our tty, even
+ if it is not stdin. We'd like to use /dev/tty but that won't be
+ valid after the setsid().
+ [7b8bba8d99e7]
+
+2009-10-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, pty.c:
+ Add support for IRIX-style dynamic ptys
+ [bedc9bac44c1]
+
+ * Makefile.in, alloc.h, getline.c, sudo.h, sudoreplay.c:
+ Move alloc.c protos into alloc.h
+ [b6a90649617d]
+
+ * missing.h:
+ Move prototypes for missing libc functions to missing.h
+ [dda9ae1ccaf8]
+
+ * Makefile.in, sudo.h, sudoreplay.c:
+ Move prototypes for missing libc functions to missing.h
+ [7483166b577b]
+
+2009-10-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in:
+ Disable transcript support if no tcsetpgrp until we support older
+ BSD-style job control.
+ [27ac1d8163df]
+
+ * configure, configure.in, pty.c, script.c:
+ Break out pty code into pty.c
+ [e85509b25d41]
+
+ * compat.h, config.h.in, configure, configure.in:
+ add killpg macro if no killpg function
+ [3a125f4a51f0]
+
+ * config.h.in, configure, configure.in, script.c:
+ Push ptem and ldterm for STERAMS-based systems when allocating a
+ pty.
+ [36bb39b30ff2]
+
+2009-10-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c:
+ Sprinkle some more O_NOCTTY and call grantpt() before unlockpt()
+ [d94bd5c9bf4e]
+
+ * script.c:
+ Call tcgetpgrp() in the parent, not the child and have the child
+ spin until it is granted. Fixes a race on darwin.
+ [6e8d435339ce]
+
+ * script.c:
+ Only use TIOCNOTTY in the non-setsid case. If no TIOCSCTTY, just
+ reopen slave.
+ [0bdc63c019ca]
+
+2009-10-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c:
+ In script mode, if the command is killed by a signal, print the
+ signal description as well as a core dump notification like the
+ shell does.
+ [9df61738df07]
+
+ * Makefile.in, config.h.in, configure, configure.in, strsignal.c,
+ sudo.h:
+ Add check for strsignal() and a simple implementation if it is not
+ there but sys_siglist is
+ [61421a188ef4]
+
+ * script.c:
+ Add missing WUNTRACED and store the signal that stopped the
+ grandchild in suspended, not signo.
+ [df65042b200e]
+
+ * script.c:
+ g/c unused code
+ [40d8cb5c9203]
+
+ * script.c:
+ Associate the grandchild's pgrp with the tty instead of the child's
+ and just get suspend notifications via SIGCHLD instead of directly.
+ This fixes a hang with programs that try to set terminal attributes
+ and is more consistent with how the shell handles things.
+ [6865abff7e94]
+
+2009-10-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c:
+ Move setpgid() of child into the parent side of the fork() where it
+ belongs.
+ [3defa782777c]
+
+2009-10-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c:
+ fix typo
+ [b6a612b3622c]
+
+ * script.c:
+ Run command in its own pgrp (like the shell does) for easier
+ signalling. No need to relay SIGINT or SIGQUIT to parent, just send
+ to grandchild. Don't want grandchild stopped events in the child
+ (only termination). Flush output after suspending grandchild before
+ signalling parent.
+ [db556bf2176f]
+
+ * script.c:
+ Back out revision 1.34; the problem lies elsewhere.
+ [85f590a03275]
+
+ * script.c:
+ Don't set stdout to blocking mode when flushing remaining output. It
+ can cause us to hang when trying to exit. Need to investigate why.
+ [6f803a3e33ca]
+
+ * script.c:
+ Handle SIGTTOU and remove some debugging.
+ [52d17279053e]
+
+ * term.c:
+ Back out revision 1.10 as the signal that interrupts us may be
+ SIGTTOU or SIGTTIN which the caller must handle.
+ [7e2fa9107975]
+
+ * script.c:
+ Apparently we need to send SIGSTOP to the command as well as ourself
+ when we get SIGTSTP, the kernel doesn't automatically stop the
+ process for us.
+ [1a936e9309c4]
+
+ * script.c:
+ Use an extra process to act as the glue bewteen the sessions
+ associated with the user's controlling tty (what the shell uses) and
+ the tty that sudo is using to do its logging. Basically, this means
+ that if we get, e.g. SIGTSTP from the process sudo is running, we
+ relay the signal to the parent so it's shell can do the job control.
+ [6dd296988060]
+
+ * term.c:
+ Handle getting/setting terminal attributes when the fd is in non-
+ blocking mode.
+ [ae5ae535ea7b]
+
+2009-10-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoreplay.c, sudoreplay.cat, sudoreplay.man.in, sudoreplay.pod:
+ Add support for pausing and changing the speed in interactive mode.
+ [72a2063780a7]
+
+ * script.c:
+ Already define O_NOCTTY in compat.h, don't need it here
+ [b5d80ed3e5ce]
+
+2009-10-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoreplay.c:
+ Add missing protos
+ [c4cb4e7f4d8a]
+
+2009-09-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo_edit.c:
+ Always update the stashed mtime of the temp file instead of using
+ what we have for the original because the time resolution of the
+ filesystem the temporary is on may not match that of the filesystem
+ that holds the original. Should fix bz #371 found by Philippe Levan.
+ [c86ca4bec60c]
+
+ * sudoreplay.c:
+ Use cbreak mode instead of raw mode and add signal handlers to
+ restore the tty on interrupt.
+ [84dd283da41c]
+
+ * script.c, sudo.h, term.c:
+ Retain NL to NLCR conversion on the real tty and skip it on the pty
+ we allocate. That way, if stdout is not a pty there are no extra
+ carriage returns.
+ [32e4f570414e]
+
+ * script.c:
+ Fix log_output(); just pass in a string and a length.
+ [ca980cc0a3fb]
+
+2009-09-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c:
+ do not use errno when complaining out lack of a tty
+ [8f9b8c55ab8e]
+
+2009-09-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, sudoreplay.c, term.c:
+ Instead of messing with line endings, just set terminal to raw mode
+ in sudoreplay.
+ [90943fa87acb]
+
+ * term.c:
+ When copying the terminal attributes to the pty, be sure not to set
+ ONLCR. This prevents extra carriage returns from ending up in the
+ script output file.
+ [e6b5475ac2aa]
+
+ * script.c:
+ Convert a do {} while into a while
+ [e461310d2c77]
+
+ * Makefile.in:
+ Use if then instead of test && when installing binaries that may not
+ exist.
+ [ad4f9490d971]
+
+ * script.c:
+ Add O_NOCTTY when opening a tty device. Explicitly disconnect from
+ old tty before associatng with new one.
+ [0e0ca634b80c]
+
+ * script.c, selinux.c, sudo.c, sudo.h:
+ First cut at refactoring some of the selinux code so it can be used
+ in conjunction with sudo's transcript support.
+ [779b0d8f9d29]
+
+2009-09-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4, configure, configure.in:
+ Fix default case of transcript_enabled being unset.
+ [f8aa96186e6b]
+
+ * script.c, sudoreplay.c:
+ Use _PATH_SUDO_TRANSCRIPT instead of _PATH_SUDO_SESSDIR
+ [2844a7a851fa]
+
+ * INSTALL, Makefile.in, aclocal.m4, configure, configure.in, sudo.c:
+ Hook up --disable-transcript and --enable-transcript=DIR
+ [b3fa7e6b2480]
+
+2009-09-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4, configure, configure.in, pathnames.h.in:
+ _PATH_SUDO_SESSDIR -> _PATH_SUDO_TRANSCRIPT Add --enable-
+ transcript=DIR option to specify the directory
+ [b0bb76d43cda]
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in:
+ regen
+ [c7a8a0a9027c]
+
+ * configure, configure.in, sudoers.man.pl, sudoers.pod:
+ Substitute in default value for secure_path
+ [c8f9ac6dbf93]
+
+ * sudo.pod:
+ Mention that the password must be followed by a newline with the -S
+ option.
+ [2fc589a3ee7e]
+
+2009-09-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c:
+ Go back to dropping out of the select() loop when the process dies;
+ Linux ptys apparently don't behave the same as BSD in regards to
+ select(). No need to flush remaining output to the transcript, only
+ to stdout. Add back code to check the master pty for additional data
+ when we exit the main select loop.
+ [abed9a9cbc6b]
+
+2009-09-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Add getline.o to COMMON_OBJS
+ [04ef7643cbc2]
+
+ * Makefile.in:
+ sudoreplay depends on libsudo.a
+ [142bd0472631]
+
+ * Makefile.in:
+ More pwutil.o into COMMON_OBJS
+ [4a016b933629]
+
+ * pwutil.c, testsudoers.c, tsgetgrpw.c:
+ Remove my_* redirection in pwutil.c for testsudoers and just use the
+ normal libc get{pw,gr}* names.
+ [9b76d637d86b]
+
+ * sudoreplay.cat, sudoreplay.man.in, sudoreplay.pod:
+ More time and date examples
+ [c6ee0175ec56]
+
+ * Makefile.in, configure, configure.in, nanosleep.c, sudoreplay.c:
+ Move nanosleep() emulation into its own file Check librt.a for
+ nanosleep if we don't find it in libc
+ [4da0cc26aad7]
+
+ * Makefile.in, configure, configure.in:
+ Build libsudo with the common bits and link things against that.
+ [2b53bc0b081a]
+
+ * script.c:
+ Fix final flush.
+ [6da287d833da]
+
+ * script.c:
+ Keep reading from the pty master -> log file until read returns <=
+ 0. Do our best to write everything to stdout when flushing any
+ remaining bits.
+ [2a45d4ae280c]
+
+ * sudoreplay.c:
+ Use unbuffered I/O when writing to stdout and make sure we write the
+ entire buffer.
+ [f39ef9844a47]
+
+2009-09-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoreplay.c:
+ Only use max_wait if it is non-zero
+ [f6c10604d2e8]
+
+ * getdate.c, getdate.y, getline.c:
+ Need compat.h here
+ [5d6722e225a0]
+
+ * sudoreplay.c:
+ Fix nanosleep emulation
+ [34e5e5d72a76]
+
+ * script.c:
+ Fix comment after #endif
+ [bd1347718b25]
+
+ * sudoreplay.c:
+ Add protos for missing libc bits
+ [644f496427a2]
+
+ * configure, configure.in:
+ add missing line continuation char
+ [db13c0d402cd]
+
+ * config.h.in, configure, configure.in, getline.c:
+ Implement getline() in terms of fgetln() if we have it.
+ [3ab786eaadc5]
+
+ * sudoreplay.c:
+ Print year when formatting log line
+ [90be669e3443]
+
+ * sudoreplay.pod:
+ Document cwd, attempt to document time/date formats.
+ [6290fb9b65c6]
+
+ * sudoreplay.c:
+ Fix getline return value check.
+ [d696d6657261]
+
+ * Makefile.in, config.h.in, configure, configure.in, getline.c,
+ sudoreplay.c:
+ Use getline() if the system has it, else use provide our own for
+ sudoreplay.
+ [afca1d6fbe5e]
+
+ * script.c:
+ Refactor code to update output and timing files.
+ [361491332b1a]
+
+2009-09-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoreplay.c:
+ Make sudo_getln() behave more like glibc getline.
+ [40c9f2ea29e6]
+
+ * script.c:
+ When flushing remaining output, also update timing file.
+ [5a9a5a627549]
+
+ * sudoreplay.c:
+ Use get_timestr() and make the -l output look like the regular sudo
+ log.
+ [452ba9d436c9]
+
+ * logging.c, sudo.h, timestr.c:
+ Make get_timestr() take a time_t so we can use it properly in
+ sudoreplay.
+ [82e67cc53c9c]
+
+ * script.c:
+ Create session dir earlier now that we update the seq number early.
+ [797fe8d6dc61]
+
+2009-09-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoreplay.c:
+ Use fromdate and todate as the keywords instead of from and to; the
+ short forms will still be accepted.
+ [d14d9b116df4]
+
+ * sudoreplay.c:
+ Fix reading long liensin sudo_getln()
+ [58dadd74118c]
+
+ * script.c, sudoreplay.c:
+ Log the cwd in the script log file. Add sudo_getln() to read
+ arbitrarily long lines.
+ [faceb802ab8f]
+
+ * Makefile.in, logging.c, sudo.h, timestr.c:
+ Move get_timestr() into its own source file so sudoreplay can use
+ it.
+ [99b054bfa20a]
+
+2009-09-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoreplay.c:
+ Add to and from perdicates (date ranges); needs documentation
+ [1d629174dcf4]
+
+2009-09-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, getdate.c, getdate.y:
+ Fix warning and add generated getdate.c
+ [b877a86b5a03]
+
+ * Makefile.in, getdate.y:
+ Add getdate.y to be used for sudoreplay date parsing.
+ [b8e26fbb7a40]
+
+2009-09-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoreplay.c:
+ Check more than just the first character of a predicate
+ [4fe53728adb1]
+
+ * sudoreplay.cat, sudoreplay.man.in, sudoreplay.pod:
+ Add examples, sort predicates
+ [70f8075cbccc]
+
+ * Makefile.in, sudoreplay.c, sudoreplay.cat, sudoreplay.man.in,
+ sudoreplay.pod:
+ Implement search expressions in sudoreplay similar in concept to
+ what find or tcpdump uses. TODO: date ranges
+ [f7ce4fb4cf3a]
+
+2009-09-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c:
+ Remove vhangup as it was hanging up the wrong tty. Should really
+ vhangup in the child after it as set its tty.
+ [2eed9df73010]
+
+ * sudoers.pod:
+ Fix cut at documenting transcript support.
+ [e6c533a5568a]
+
+ * logging.c:
+ ID= -> TSID= for transcript ID
+ [1bf755a35333]
+
+2009-09-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Move fast_glob description to where it belongs in sorted order
+ [5901cfb0d25f]
+
+ * def_data.c, def_data.h, def_data.in, gram.c, gram.h, gram.y,
+ parse.c, parse.h, sudo.c:
+ Rename script -> transcript
+ [e06cf823122c]
+
+2009-09-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat.h:
+ Add timeradd and timersub for those without them
+ [929f8aa06c2b]
+
+ * script.c:
+ Sanity check sessid before using it.
+ [aa8ca5211d43]
+
+ * sudo.c:
+ Only set the session id if we are running a command or editing a
+ file.
+ [7205d717c098]
+
+ * script.c:
+ Actually. qsort is fine since most versions fal back to a cheaper
+ sort when the number of elements to sort is small (like in our
+ case).
+ [d11c7cd352fe]
+
+ * config.h.in, configure, configure.in, script.c:
+ Check for dup2 and use dup instead if we don't have it.
+ [98bd89830f8a]
+
+ * script.c, sudo.c, sudo.h:
+ Move the code to dup2 the script fds to low numbered descriptors
+ into script_duplow() and fix the fd sorting.
+ [9453fdc5fba6]
+
+ * script.c, sudo.c, sudo.h:
+ Move script_setup() back to immediately before we drop privs and
+ call the new script_nextid() in its place, which will set
+ sudo_user.sessid for the logging functions.
+ [8434d0c8ff08]
+
+2009-09-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Install sudoreplay
+ [6acf2cdb4d3f]
+
+ * sudoreplay.c:
+ remove unused variable
+ [2316360bb992]
+
+2009-08-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c, script.c, sudo.c, sudo.h:
+ Log the session ID, if there is one. Currently logs ID=XXXXXX,
+ perhaps should be SESSIONID or SESSID.
+ [53976905b0a6]
+
+ * Makefile.in, configure, configure.in, sudoreplay.cat,
+ sudoreplay.man.in, sudoreplay.pod:
+ Add sudoreplay docs
+ [da4f14f0e64c]
+
+ * sudoreplay.c:
+ add -V (version) flag
+ [b5e743639ee3]
+
+ * sudoreplay.c:
+ Hook up max_wait.
+ [2ec5697a92ba]
+
+ * script.c, sudoreplay.c:
+ Use base36 number for the ID and store script files with paths like
+ /var/log/sudo-session/00/00/00{,.tim,.scr}. This gives us 36^6
+ (2,176,782,336) unique IDs.
+ [6aab019d07aa]
+
+2009-08-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure.in:
+ Add check for regcomp
+ [44c3ebd7ff34]
+
+ * sudoreplay.c:
+ Add support for selecting by pattern and tty when listing.
+ [66189f840c52]
+
+2009-08-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoreplay.c:
+ The beginnings of a list mode.
+ [8d0150b4a52c]
+
+2009-08-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ fix pasto
+ [616b4640b8a8]
+
+ * Makefile.in, config.h.in, configure.in:
+ Add scaffolding for building sudoreplay
+ [a32958505dbe]
+
+ * sudoreplay.c:
+ include error.h first arg to nanotime is const
+ [fe5a7bb31bc5]
+
+ * sudoreplay.c:
+ Initial cut at sudoreplay; replay a sudo session.
+ [f149fba372bd]
+
+2009-08-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * script.c:
+ Fix wait() usage and use correct wait status.
+ [f4745ed7ad05]
+
+ * sudo.c, sudo.h, tgetpass.c:
+ Add protos for term_* to sudo.h
+ [14fe1abd7e7b]
+
+ * script.c:
+ Fix detection of the child process exiting. Since the child is in
+ its own session we should only ever get SIGCHLD for that process but
+ better safe than sorry.
+ [7edfdadd8505]
+
+ * config.h.in:
+ Add UNIX98 pty support.
+ [82f4b53a0e8f]
+
+ * configure, configure.in, script.c:
+ Add UNIX98 pty support.
+ [795b8bb0a3a1]
+
+2009-08-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * term.c:
+ For raw mode, don't bother clearing BRKINT or PARMRK and clear IUCLC
+ if it is defined.
+ [40f8b83baf69]
+
+ * auth/pam.c:
+ Set PAM_RUSER and PAM_RHOST early so they can be used during
+ authentication. Based on a patch from Jamie Beverly.
+ [3d567b453a6a]
+
+ * match.c:
+ Close dir before returning if strlcpy() reports overflow. From
+ Martynas Venckus.
+ [6a82f96473e5]
+
+ * config.h.in, configure, configure.in, script.c:
+ On Linux, the openpty proto libes in pty.h
+ [98643a018d1c]
+
+ * script.c:
+ Call vhangup on exit if the system has it Use setpgrp() if no
+ setsid()
+ [3a9e13149829]
+
+2009-08-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in:
+ Add checks for revoke and vhangup if we don't have openpty
+ [fcb04572e994]
+
+ * script.c:
+ Session logging guts that got forgotten in the previous commit.
+ [c2af08a63ea9]
+
+ * Makefile.in, aclocal.m4, compat.h, config.h.in, configure,
+ configure.in, def_data.c, def_data.h, def_data.in, gram.c, gram.h,
+ gram.y, parse.c, parse.h, pathnames.h.in, sudo.c, sudo.h, term.c,
+ tgetpass.c:
+ First cut at session logging for sudo. Still need to write get_pty()
+ for Unix 98 and old-style BSD ptys. Also needs documentation and
+ general cleanup.
+ [77e3f5e25738]
+
+2009-08-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c, sudo_edit.c:
+ Fix a bug introduced with def_closefrom. The value of def_closefrom
+ already includes the +1.
+ [7291c136300d]
+
+2009-07-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Generate sudo distributions with pax in ustar mode. No longer need
+ to use a temp file or have the source dir name match the version.
+ [9778177a8272]
+
+2009-07-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * toke.c, toke.l:
+ Fix expansion of %h in #include names. Fixes bugzilla 363
+ [6e346879ba24]
+
+2009-07-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkdefaults:
+ If no arg assume def_data.in
+ [c1dd28c0e675]
+
+ * README, WHATSNEW:
+ Update for 1.7.2
+ [f5ad45f69f05] [SUDO_1_7_2]
+
+ * ChangeLog:
+ sync
+ [6283549396ff]
+
+2009-06-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.cat, sudoers.man.in, sudoers.pod:
+ Add missing single quotes around a colon in Runas_Spec definition.
+ From Elias Benali.
+ [ccc6ee4fca83]
+
+2009-06-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.man.in, sudoers.man.in:
+ regen
+ [546e75304ebf]
+
+ * redblack.c:
+ In rbrepair, re-color the root or the first non-block node we find
+ to be black. Re-coloring the root is probably not needed but won't
+ hurt.
+ [34d01ebe241b]
+
+ * sudo.cat, sudoers.cat:
+ regen
+ [bebf5a39f54f]
+
+2009-06-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * redblack.c:
+ When repairing the tree, don't touch the root node.
+ [9841f0d5d789]
+
+2009-06-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * set_perms.c:
+ Protect call to setegid in runas_setup with #ifdef HAVE_SETEUID.
+ Reported by Josef Schmid.
+ [ed044b1eb879]
+
+2009-06-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Document that we accept env_pam-style environment files
+ [e3b545456352]
+
+ * env.c:
+ Adapt to accept pam_env-style /etc/environment which allows shell-
+ style lines such as: export EDITOR="/usr/bin/vi"
+ [752eb75bf007]
+
+ * sudoers.pod:
+ Make it clear that env_delete only works when !env_reset. From Loïc
+ Minier
+ [3bd3f8e351ba]
+
+2009-06-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod, sudoers.pod:
+ Add non-unix group bits, adapted from Quest
+ [8ce427de8dea]
+
+ * Makefile.in:
+ build the .cat page in the current working dir, not the src dir
+ [00e87a307674]
+
+ * env.c:
+ Return EINVAL in setenv() if var is NULL or the empty string to
+ match glibc behavior.
+ [23fd7c247142]
+
+2009-06-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Use AS_HELP_STRING for AC_ARG_WITH and AC_ARG_ENABLE
+ [fedd4a3e2a85]
+
+2009-06-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.ldap.cat,
+ sudoers.ldap.man.in, sudoers.man.in, visudo.cat, visudo.man.in:
+ regen
+ [7b9f461a40b3]
+
+2009-06-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ Document --with-libvas and --with-libvas-rpath
+ [a071e6d96c89]
+
+2009-05-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c, sudoers.ldap.pod:
+ For netscape-derived LDAP SDKs the cert and key paths may be a
+ directory or a file. However, version 5.0 of the SDK only seems to
+ support using a directory. If ldapssl_clientauth_init fails and the
+ cert or key paths look like they could be files, strip off the last
+ path element and try again.
+ [ac4e49d83043]
+
+ * Makefile.in:
+ Add non-Unix group .o to COMMON_OBJS and substitute in path to flex.
+ [4547cc1a335f]
+
+2009-05-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in, match.c, sudo.c, vasgroups.c:
+ Update non-Unix group support from Quest, as reworked by me.
+ [1abafce29dc6]
+
+ * toke.c:
+ regen
+ [01bfca9148b7]
+
+ * toke.l:
+ Add support for escaped hex chars in names, e.g. \x20 for space.
+ [3c7be8e58a39]
+
+2009-05-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * LICENSE, Makefile.in, aclocal.m4, alias.c, auth/aix_auth.c,
+ auth/pam.c, auth/sudo_auth.c, auth/sudo_auth.h, check.c, env.c,
+ fileops.c, glob.c, gram.y, interfaces.c, lbuf.c, ldap.c, logging.c,
+ logging.h, match.c, parse.c, parse.h, pathnames.h.in, pwutil.c,
+ set_perms.c, sudo.c, sudo.h, sudo.pod, sudo_nss.c, sudo_nss.h,
+ sudo_usage.h.in, sudoers.ldap.pod, sudoers.pod, testsudoers.c,
+ tgetpass.c, toke.l, visudo.c:
+ Update copyright years.
+ [e615f676c764]
+
+2009-05-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * interfaces.c, lbuf.c:
+ Minor fixes for Minix-3
+ [898c510d23f9]
+
+2009-05-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * set_perms.c:
+ Handle getgroups() returning 0. Also add missing check for
+ HAVE_GETGROUPS.
+ [d73b958f9ffd]
+
+2009-05-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, config.h.in, configure, configure.in, sudo.c,
+ version.h, visudo.c:
+ Replace version.h with PACKAGE_VERSION set via AC_INIT in configure.
+ [5050579a264d]
+
+2009-05-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * set_perms.c:
+ Remove group setting code in setusercontext case, we will do it
+ ourselves later on in runas_setup. Set the gid after
+ initgroups/setgroups is called, since on Mac OS X it seems to change
+ the egid.
+ [09dc21d8b42d]
+
+2009-05-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * LICENSE, Makefile.in, config.h.in, match.c, nonunix.h, sudo.c,
+ vasgroups.c:
+ Initial bits of non-unix group support using Quest Authentication
+ Services
+ [1eecab0ff27e]
+
+ * toke.c, toke.l:
+ Accept %:foo as a non-Unix group
+ [4c4b5dd899a6]
+
+ * toke.c, toke.l:
+ Allow user/group to be double quoted in the case of non-Unix groups
+ which contain spaces.
+ [47a3d568b7e8]
+
+2009-05-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * match.c:
+ Don't allow the user to specify the default runas user if their
+ sudoers entry only allows them to run as a group.
+ [4d726177227c]
+
+2009-05-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Must call audit_success before we change uids.
+ [04a9e6ce6e55]
+
+ * logging.c, set_perms.c, sudo.h, testsudoers.c:
+ Add option for set_perm to not exit on failure and use this in the
+ logging routines.
+ [833dce7b7f42]
+
+ * parse.c:
+ In -l mode, if the user is only allowed to run as a group, display
+ the user's name, not root's before the allowed group.
+ [ef92ff99d265]
+
+ * sudo.c:
+ Fix -g mode, broken by rev 1.503 which had the side effect of
+ setting the runas user to root unilaterally.
+ [50a2f7df4385]
+
+2009-05-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * fileops.c:
+ When unlocking a file with fcntl, use F_SETLK, not F_SETLKW.
+ [30fbe832dcf3]
+
+ * pwutil.c:
+ Only cache by the method we fetched for pwd and grp lookups.
+ Previously we cached both by namd and id but this can cause problems
+ for entries that share the same id. Also add more info in the error
+ message in case the insert fails (which should now be impossible).
+ [ef95a4f0bab5]
+
+2009-04-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Add a clarification from Nick Sieger
+ [1eadad329561]
+
+2009-04-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ Inline the setting of the environment string.
+ [9515d11c6295]
+
+2009-04-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ setenv(3) in Linux treats a NUL value as the empty string setenv(3)
+ in BSD doesn't return an error if the name has '=' in it, it just
+ treats the '=' as end of string.
+ [941260bf94d2]
+
+2009-04-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * toke.c, toke.l:
+ Not all systems have d_namlen
+ [e377b18d8e2d]
+
+2009-04-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Fix up some pod2html issues.
+ [823a1f10ab60]
+
+2009-04-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * interfaces.c:
+ Check for NULL ifa_addr and ifa_netmask. Adapted from a diff from
+ Quest Software.
+ [73de36653131]
+
+ * sudoers.pod:
+ Ignore files ending in '~' in sudo.d (emacs backup files)
+ [7871fad702db]
+
+ * toke.c, toke.l:
+ Ignore files ending in '~' in sudo.d (emacs backup files)
+ [53fded2a469f]
+
+2009-04-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.cat, sudoers.man.in, sudoers.pod, toke.c, toke.l:
+ For #includedir, ignore any file containing a dot
+ [a7daa1bce6c2]
+
+ * Makefile.in, version.h:
+ Bump version
+ [ef60f14ffc44]
+
+ * gram.c, gram.y, parse.c, parse.h, sudo.c, sudo.h, sudoers.cat,
+ sudoers.man.in, sudoers.pod, testsudoers.c, toke.c, toke.l,
+ visudo.c:
+ Implement #includedir directive. Files in an includedir are not
+ edited by visudo unless they contain a syntax error.
+ [3923d85a6c79]
+
+ * ChangeLog:
+ sync
+ [8741ed61a78b] [SUDO_1_7_1]
+
+ * WHATSNEW:
+ Forgot umask_override
+ [7c86a21a5504]
+
+ * ChangeLog, TODO:
+ sync
+ [57339ca6bccf]
+
+2009-04-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ Rewind stream if we fdopen sudoers since it may not be at the
+ beginning. Set the keepopen flag on already-open files too so the
+ lexer doesn't close them out from under us.
+ [61292d819aff]
+
+ * visudo.c:
+ Print the proper file name when there is a parse error in an include
+ file.
+ [b0e85d4aedde]
+
+2009-04-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * WHATSNEW:
+ Sync
+ [997e5d485ea3]
+
+2009-04-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Fix a warning when --without-ldap is specified.
+ [d91fd9481b30]
+
+2009-04-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * alias.c, parse.h, visudo.c:
+ Store aliases that we remove during check_aliases in a freelist and
+ free them at the end so we don't leak memory.
+ [805e2272f6a3]
+
+2009-03-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ Check aliases in -c mode too.
+ [9199e188d9f2]
+
+ * alias.c, parse.h, visudo.c:
+ Make alias_remove return the alias struct instead of freeing it
+ directly. Fixes a use after free in alias_remove_recursive, the only
+ consumer.
+ [a04b61804800]
+
+ * alias.c, match.c, parse.c, parse.h, visudo.c:
+ Rename find_alias -> alias_find for consistency.
+ [48b0a82924f3]
+
+2009-03-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ When checking for unused aliases, recurse if the alias points to
+ another alias.
+ [2d4d1a7f3a41]
+
+2009-03-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Back out rev 1.105 for now. Real ldapux_client.conf support will be
+ done later after some refactoring.
+ [8ad72e69b277]
+
+2009-03-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Treat ldap_hostport the same as "host" for ldapux.
+ [3281dcc66da8]
+
+ * configure, configure.in:
+ Only check for ldap_sasl_interactive_bind_s if we can find sasl.h.
+ Fixes compilation with ldapux.
+ [ca1ed585ef0e]
+
+2009-03-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * fileops.c:
+ fix char subscript
+ [41e51f080d00]
+
+2009-03-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ remove errant carriage returns
+ [e9e258a31c7b]
+
+ * audit.c, env.c:
+ fix K&R compilation
+ [d182e8920f13]
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.ldap.cat,
+ sudoers.ldap.man.in, sudoers.man.in, visudo.cat, visudo.man.in:
+ regen
+ [791a5cbf04e5]
+
+2009-03-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ Add missing HAVE_BSM_AUDIT
+ [49ad1bb96f04]
+
+ * WHATSNEW:
+ Add 1.7.1 features
+ [f107f1604c61]
+
+ * INSTALL:
+ Mention --with-netsvc
+ [d1e90d147795]
+
+ * sudoers.ldap.pod:
+ Document netsvc.conf support
+ [e78f8abce6af]
+
+ * configure, configure.in, pathnames.h.in, sudo.c, sudo_nss.c,
+ sudo_nss.h:
+ Add support for AIX netsvc.conf (like nsswitch.conf).
+ [1df56a84dee5]
+
+2009-03-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, env.c:
+ Add --enable-env-debug flag to enable environment sanity checks.
+ [128cdd8832e7]
+
+ * sudoers.ldap.pod, sudoers.pod:
+ Work around some pod2html issue.
+ [e733b9609bd2]
+
+2009-03-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ Only sync environ for putenv, setenv, and unsetenv. We need to make
+ sure that sudo_putenv and sudo_setenv only modify env.envp, not
+ environ.
+ [be3ac732243c]
+
+2009-03-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ Really fix UNSETENV_VOID
+ [08ab7e882507]
+
+ * env.c:
+ Fix unsetenv when UNSETENV_VOID
+ [d3038b3f2f15]
+
+ * aclocal.m4, configure:
+ Fix SUDO_FUNC_PUTENV_CONST
+ [de35569c572b]
+
+ * ldap.c:
+ tivoli-based ldap does not have ldapssl_err2string
+ [c63fd90d5e99]
+
+ * configure:
+ regen
+ [f38f1ee828ad]
+
+2009-03-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, ldap.c:
+ Add support for Tivoli-based LDAP start TLS as seen in AIX.
+ Untested.
+ [8f8771829f85]
+
+ * env.c:
+ Add sanity checks for setenv/unsetenv
+ [adbd1d95856b]
+
+ * Makefile.in:
+ Include bsm_audit.h in the tarball
+ [4a4aa02b2c32]
+
+ * Makefile.in, version.h:
+ bump version for sudo 1.7.1
+ [362c71d21595]
+
+ * aclocal.m4, auth/aix_auth.c, config.h.in, configure, configure.in,
+ env.c, ldap.c, sudo.h:
+ Replace sudo_setenv/sudo_unsetenv with calls to setenv/unsetenv and
+ provide our own setenv/unsetenv/putenv that operates on own env
+ pointer. Make sync_env() inline in setenv/unsetenv/putenv functions.
+ [276edcd23032]
+
+2009-02-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Make "sudoedit -h" work as expected
+ [2bcbbb45d389]
+
+ * auth/pam.c:
+ Make sure def_prompt is always defined. This is a workaround for pam
+ configs that prompt for a password in the session but don't have an
+ auth line. A better fix is to expand the sudo prompt earlier and set
+ def_prompt to that when initializing.
+ [ee073c04aec3]
+
+ * sudo.pod:
+ Mention that the helper for -A may be graphical.
+ [b64a940c4082]
+
+ * TROUBLESHOOTING:
+ Document what happens if there is no tty.
+ [313d58a856a5]
+
+ * sudo.c:
+ cosmetic changes
+ [894f5e3b0c3e]
+
+ * term.c:
+ Fix term_restore
+ [6c6315ff14bc]
+
+ * sudo.c:
+ Fix "sudo -k" with no other args
+ [59e94dc419c6]
+
+2009-02-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c, sudo.c, sudo.pod, sudo_usage.h.in:
+ Allow the -k flag to be specified in conjunction with a command or
+ another option that may require authentication.
+ [5960ff20355d]
+
+2009-02-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Remove unneeded AC_CANONICAL_TARGET; from Diego E. 'Flameeyes'
+ [e86ab69c4a57]
+
+ * Makefile.in:
+ Parallel make fix. From Diego E. 'Flameeyes'
+ [1289d7ee27db]
+
+2009-02-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * def_data.c, def_data.h, def_data.in, sudo.c, sudoers.pod:
+ Implement umask_override
+ [8b87a3f7c5aa]
+
+ * toke.c:
+ regen
+ [79d7ca9ac873]
+
+ * sudoers.pod, toke.l, visudo.c:
+ Implement %h escape in sudoers include filenames.
+ [a7f288dd64f0]
+
+ * audit.c:
+ Need to include compat.h
+ [c0dc07ce2f70]
+
+ * Makefile.in, audit.c, bsm_audit.c, bsm_audit.h, logging.h, sudo.c:
+ Make audit_success and audit_failure generic functions in
+ preparation for integrating linux audit support.
+ [7df020a8fd6f]
+
+ * term.c:
+ remove duplicate include
+ [1dfcd01a7e46]
+
+2009-02-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * bsm_audit.c:
+ Add missing include
+ [fb56e08c37ee]
+
+ * sudo.c:
+ May need to update the runas user after parsing command-based
+ defaults.
+ [246f130d7802]
+
+2009-02-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * glob.c:
+ Add missing pair of braces introduced with character class support.
+ [0e2afa2e03e9]
+
+2009-02-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * def_data.c, def_data.h, def_data.in, sudoers.pod, tgetpass.c:
+ Rename pwstars to pwfeedback
+ [a9f85a57ebac]
+
+2009-02-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * bsm_audit.c, bsm_audit.h:
+ Add const to make MacOS happy.
+ [4274432d6627]
+
+ * Makefile.in, auth/sudo_auth.c, bsm_audit.c, bsm_audit.h, configure,
+ configure.in, sudo.c:
+ Add bsm audit support from Christian S.J. Peron
+ [bef61cd8693d]
+
+ * term.c:
+ This is new code, no DARPA notice.
+ [ec6ad09b9c23]
+
+2009-02-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * def_data.c, def_data.h, def_data.in, match.c, sudoers.pod:
+ Rename simple_glob -> fast_glob
+ [68d9ed803cc1]
+
+ * match.c:
+ g/c unused var
+ [693fa0464eb6]
+
+ * def_data.c, def_data.h, def_data.in, match.c, sudoers.pod:
+ Add simple_glob option to use fnmatch() instead of glob(). This is
+ useful when you need to specify patterns that reference network file
+ systems.
+ [77ba634f6949]
+
+ * tgetpass.c:
+ add term_* proto
+ [520f5149d073]
+
+ * sudoers.pod:
+ mention glob()
+ [ddaab8e03c52]
+
+2009-02-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ Delete any pwstars we wrote after the user hits return. That way
+ there is no record on screen as to the user's password length.
+ [fae25cda762b]
+
+2009-02-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * term.c:
+ Move terminal setting bits from tgetpass.c to term.c
+ [03d43325ee99]
+
+ * Makefile.in, def_data.c, def_data.h, def_data.in, sudoers.pod,
+ tgetpass.c:
+ Add pwstars sudoers option that causes sudo to print a star every
+ time the user presses a key.
+ [7aab417e184d]
+
+2009-02-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Fix up F<> brokenness for visudo.man.in and sudoers.ldap.man.in.
+ [64f70e879816]
+
+2009-01-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ For ldap_search_ext_s() the sizelimit param should be 0, not -1, to
+ indicate no limit. From Mark Janssen.
+ [e2c5732d54f5]
+
+2009-01-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * toke.c, toke.l:
+ Comments that begin with #- should not be parsed as uids.
+ [a72a50f12f41]
+
+2009-01-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Do not try to set the close on exec flag if we didn't actually open
+ sudoers.
+ [ece3ca256904]
+
+2008-12-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ChangeLog:
+ regen
+ [e11f0e4c1bdd] [SUDO_1_7_0]
+
+2008-12-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TODO:
+ sync
+ [5b8954462bb3]
+
+2008-12-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c:
+ Return PAM_AUTH_ERR instead of PAM_CONV_ERR if user enters ^C at the
+ password prompt.
+ [8563601cb3de]
+
+ * configure, configure.in:
+ Don't try to build sudo_noexec.so on HP-UX with the bundled compiler
+ as it cannot generate shared objects.
+ [6d4262ef9669]
+
+ * emul/charclass.h, glob.c, lbuf.c, tgetpass.c:
+ K&R compilation fixes
+ [77921678d17c]
+
+ * parse.c:
+ Use tq_foreach_fwd when checking pseudo-commands to make it clear
+ that we are not short-circuiting on last match. When pwcheck is
+ 'all', initialize nopass to TRUE and override it with the first non-
+ TRUE entry.
+ [96b209f4778f]
+
+2008-12-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ Do not short circuit pseudo commands when we get a match since,
+ depending on the settings, we may need to examine all commands for
+ tags.
+ [fdbaf89d6f35]
+
+2008-12-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.cat, sudoers.man.in:
+ regen
+ [1ecce7c1b841]
+
+ * sudoers.pod:
+ hostnames may also contain wildcards
+ [82b76695601c]
+
+ * Makefile.in:
+ remove stamp-* files and linux core files in clean target
+ [22003f091467]
+
+2008-12-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/sudo_auth.h, config.h.in, configure, configure.in:
+ Use HAVE_SIA_SES_INIT instead of HAVE_SIA for Digital UNIX
+ [6905bede8410]
+
+2008-11-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ correctly enable SIA on Digital UNIX
+ [a51881d13995]
+
+ * TODO:
+ checkpoint
+ [af0fe8d94d42]
+
+ * ChangeLog:
+ sync
+ [831f623cf99c]
+
+2008-11-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c, sudo.h, tgetpass.c:
+ Even if neither stdin nor stdout are ttys we may still have /dev/tty
+ available to us.
+ [20f306ba883b]
+
+2008-11-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.cat, sudoers.man.in:
+ regen
+ [76d97c4c318f]
+
+ * sudoers.pod:
+ fix typos; Markus Lude
+ [bff8bc1e2066]
+
+ * ChangeLog:
+ sync
+ [f108552531cd]
+
+ * toke.c:
+ regen
+ [de828413c67e]
+
+ * toke.l:
+ Fix matching of a line that only consists of a comment char
+ [09c953d8d5ca]
+
+2008-11-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c:
+ MacOS pam will retry conversation function if it fails so just treat
+ ^C as an empty password.
+ [d056058930bc]
+
+ * visudo.c:
+ When checking for alias use, also check defaults bindings.
+ [2647f82c7dbd]
+
+ * redblack.c:
+ unused var
+ [b7ff71c17c18]
+
+ * redblack.c:
+ Replace my rbdelete with Emin's version (which actually works ;-)
+ [21b133dd0c72]
+
+2008-11-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * testsudoers.c:
+ malloc debugging
+ [0fb446fa3279]
+
+ * visudo.c:
+ malloc options in devel mode for visudo too
+ [98d06c6afeef]
+
+2008-11-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ fix compilation on non-C99; from Theo
+ [7c304e16c536]
+
+ * visudo.c:
+ fix check_aliases
+ [83f30a3b1765]
+
+ * alias.c:
+ when destroying an alias, free the correct data pointer
+ [6e1a8bd86c01]
+
+ * auth/sudo_auth.h:
+ add proto for aixauth_cleanup; from Dale King
+ [eba94ffc8f63]
+
+2008-11-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in, visudo.cat,
+ visudo.man.in:
+ regen
+ [409fa57fff83]
+
+ * sudo.pod, sudoers.pod, visudo.pod:
+ standardize on the term 'option' for command line options (not flag)
+ [228caefc2e36]
+
+2008-11-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ Add note on configuring HP-UX pam
+ [f7674a581baf]
+
+2008-11-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c, sudo.c:
+ Move tty checks into check_user() so we only do them if we actually
+ need a password.
+ [7d997d7106d6]
+
+ * sudo.c:
+ Don't error out if no tty or askpass unless we actually need to
+ authenticate.
+ [9f23b83ed66c]
+
+2008-11-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ChangeLog:
+ regen
+ [23f9aef32da6]
+
+ * pathnames.h.in, sudo.c:
+ s/overriden/overridden/; from Tobias Stoeckmann
+ [9f7459a8fac5]
+
+2008-11-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * WHATSNEW, visudo.c:
+ check sudoers owner and mode in strict mode
+ [a3468c5ac1c4]
+
+ * gram.c, toke.c:
+ regen
+ [7d6b515a5443]
+
+ * sudo.man.in, sudoers.man.in, visudo.man.in:
+ Update copyright years.
+ [52d340cb8cba]
+
+ * LICENSE, alias.c, alloc.c, auth/afs.c, auth/aix_auth.c,
+ auth/bsdauth.c, auth/fwtk.c, auth/kerb4.c, auth/kerb5.c, auth/pam.c,
+ auth/securid.c, auth/securid5.c, auth/sia.c, auth/sudo_auth.h,
+ closefrom.c, compat.h, defaults.c, defaults.h, env.c, fileops.c,
+ gettime.c, gram.y, ins_csops.h, insults.h, interfaces.c,
+ interfaces.h, lbuf.c, license.pod, list.c, logging.c, logging.h,
+ parse.c, parse.h, pwutil.c, redblack.c, redblack.h, snprintf.c,
+ sudo.c, sudo.pod, sudo_edit.c, sudo_nss.h, sudoers.pod,
+ testsudoers.c, toke.l, tsgetgrpw.c, utimes.c, version.h, visudo.c,
+ visudo.pod, zero_bytes.c:
+ Update copyright years.
+ [b4e6bf2beafa]
+
+ * emul/charclass.h, fnmatch.c, glob.c:
+ add my copyright
+ [28681385014a]
+
+2008-11-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * toke.c, toke.l:
+ The loop in fill_cmnd() was going one byte too far past the end,
+ resulting in a NUL being written immediately after the buffer end.
+ [a5a49d603cd7]
+
+ * UPGRADE, WHATSNEW:
+ add sections on tgetpass changes
+ [2e6929b6a102]
+
+ * tgetpass.c:
+ Treat EOF w/o newline as an error.
+ [aa02b1db9240]
+
+2008-11-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ Fix "sudo -v" when NOPASSWD is set.
+ [f4914711ea80]
+
+ * auth/bsdauth.c, auth/fwtk.c, auth/pam.c, auth/sudo_auth.c,
+ auth/sudo_auth.h:
+ No longer treat an empty password at the prompt as special. To quit
+ out of sudo you now need to hit ^C at the password prompt.
+ [980f760ad419]
+
+ * sudoers.cat, sudoers.man.in:
+ regen
+ [6ca21a2cd869]
+
+ * def_data.c, def_data.h, def_data.in, sudo.c, sudoers.pod:
+ Sudo will now refuse to run if no tty is present unless the new
+ visiblepw sudoers flag is set.
+ [0cc56943252e]
+
+2008-11-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aix.c:
+ just use RLIM_INFINITY for RLIM_SAVED_MAX if RLIM_SAVED_MAX not
+ defined
+ [24fc6f712d5c]
+
+ * aix.c:
+ fix fallback value for RLIM_SAVED_MAX
+ [e09e04e1af89]
+
+ * auth/aix_auth.c, auth/sudo_auth.h:
+ Move clearing of AUTHSTATE into aixauth_cleanup.
+ [e14ae7bd259c]
+
+ * auth/aix_auth.c, env.c:
+ Unset AUTHSTATE after calling authenticate() as it may not be
+ correct for the user we are running the command as.
+ [d14f68f1b0ab]
+
+ * isblank.c:
+ Add isblank() function for systems without it. Needed for POSIX
+ character class matching in fnmatch.c and glob.c.
+ [16cba30b283f]
+
+2008-11-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TROUBLESHOOTING:
+ expound on sudo and cd
+ [8e0fa9033637]
+
+2008-11-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ChangeLog:
+ regen
+ [40cf320a10fc]
+
+ * sudoers.cat, sudoers.man.in:
+ regen
+ [7cac761ae2c6]
+
+ * sudoers.pod:
+ mention defauts parse order
+ [4e2ce86d1394]
+
+2008-11-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, aclocal.m4, compat.h, configure:
+ Add isblank() function for systems without it. Needed for POSIX
+ character class matching in fnmatch.c and glob.c.
+ [a1ab55da8424]
+
+ * Makefile.in:
+ add emul/charclass.h to HDRS
+ [7e8a019dcaa4]
+
+2008-11-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TODO:
+ checkpoint
+ [afeb9bc1baed]
+
+ * defaults.c, parse.c, testsudoers.c, visudo.c:
+ Move update_defaults into defaults.c and call it properly from
+ visudo and testsudoers.
+ [f4dbb369461f]
+
+ * defaults.c, interfaces.c, pwutil.c, sudo.c, sudo_edit.c, tgetpass.c,
+ tsgetgrpw.c:
+ use zero_bytes() instead of memset() for consistency
+ [4cee0465f4a8]
+
+ * logging.c, mon_systrace.c, parse.c, sudo.c, sudo_edit.c, tgetpass.c,
+ visudo.c:
+ Zero out sigaction_t before use in case it has non-standard entries.
+ [120092225459]
+
+ * match.c:
+ quiet gcc
+ [098a1df49b23]
+
+ * match.c:
+ Short circuit glob() checks if basename(pattern) !=
+ basename(command). Refactor code that checks for a command in a
+ directory and use it in the glob case if the resolved pattern ends
+ in a '/'.
+ [3c46fd317acb]
+
+2008-11-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * defaults.h, parse.c, sudo.c, testsudoers.c, visudo.c:
+ Defer setting runas defaults until after runaspw/gr is setup.
+ [12e75ee49c0c]
+
+2008-10-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * match.c, sudo.c, testsudoers.c:
+ Use MAXHOSTNAMELEN+1 when allocating host/domain name since some
+ systems do not include space for the NUL in the size. Also manually
+ NUL-terminate buffer from gethostname() since POSIX is wishy-washy
+ on this.
+ [7266ab3296a3]
+
+2008-10-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c, sudoers.pod:
+ When setting the umask, use the union of the user's umask and the
+ default value set in sudoers so that we never lower the user's umask
+ when running a command.
+ [4e804b004e38]
+
+ * sudo.c:
+ Don't try to read from a zero-length sudoers file. Remove the bogus
+ Solaris work-around for EAGAIN. Since we now use fgetc() it should
+ not be a problem.
+ [bb8e5f68d944]
+
+2008-10-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ In update_defaults() check the return value of user*_matches against
+ ALLOW so we don't inadvertantly match on UNSPEC.
+ [4e422fa1527e]
+
+2008-10-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.ldap.cat,
+ sudoers.ldap.man.in, sudoers.man.in, visudo.cat, visudo.man.in:
+ regen man pages; no more hyphenation
+ [15de4fe2fe01]
+
+ * sudo.c:
+ Don't error out on a zero-length sudoers file. With the advent of
+ #include the user could create a situation where sudo is unusable.
+ [6eb461319fa5]
+
+2008-10-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/kerb5.c, config.h.in, configure, configure.in:
+ Newer heimdal has 2-argument krb5_get_init_creds_opt_free() like MIT
+ krb5. Really old heimdal has no krb5_get_init_creds_opt_alloc() at
+ all. Add configure tests to handle all the cases.
+ [4b554a98470d]
+
+2008-10-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod:
+ resort ENVIRONMENT
+ [f4f20f40653e]
+
+ * sudoers.pod:
+ document sudoers_locale
+ [0bffd2dbe806]
+
+ * sudo.pod, sudo_edit.c:
+ add SUDO_EDITOR variable that sudoedit uses in preference to VISUAL
+ or EDITOR
+ [0ef8cb248cee]
+
+ * toke.c, toke.l:
+ In fill_cmnd(), collapse any escaped sudo-specific characters.
+ Allows character classes to be used in pathnames.
+ [5685244c8e44]
+
+2008-10-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lbuf.c:
+ fix typo in non-C89 function declaration
+ [99a7113b3a05]
+
+ * sudoers.pod:
+ Mention POSIX characters classes now that out fnmatch() and glob()
+ support them.
+ [9c916f1230c3]
+
+ * sample.sudoers, sudoers.pod:
+ Replace [A-z] (which won't match in UTF8) with [A-Za-z] which is
+ locale agnostic.
+ [a60a62bec244]
+
+ * parse.h:
+ use __signed char if we are going to assign a negative value since
+ on Power, char is unsigned by default
+ [2877b319df17]
+
+ * config.h.in, configure, configure.in:
+ Add tests for __signed char and signed char.
+ [5eb874fdf1d4]
+
+ * aix.c:
+ Fix AIX limit setting. getuserattr() returns values in disk blocks
+ rather than bytes. The default hard stack size in newer AIX is
+ RLIM_SAVED_MAX. From Dale King.
+ [3db67415ecc3]
+
+2008-09-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * emul/charclass.h, fnmatch.c, glob.c:
+ Add character class support to included glob(3) and fnmatch(3).
+ [6b5b4ad77899]
+
+2008-09-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * emul/fnmatch.h:
+ Remove UCB advertising clause and some compatibility defines.
+ [2ade7bee74e1]
+
+2008-09-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo_edit.c:
+ Check EDITOR/VISUAL to make sure sudoedit is not re-invoking itself
+ or sudo. This allows one to set EDITOR to sudoedit without getting
+ into an infinite loop of sudoedit running itself until the path gets
+ too big.
+ [aa49ab68f82d]
+
+ * def_data.c, def_data.h, def_data.in, defaults.c, sudo.c:
+ Add sudoers_locale Defaults option to override the default sudoers
+ locale of "C".
+ [0639886a35bf]
+
+2008-09-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Set locale to system default except for during sudoers parse.
+ [016dd2736728]
+
+2008-09-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * match.c:
+ Redo change in 1.34 to use pointer arithmetic.
+ [f9e7b63bb450]
+
+2008-09-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * match.c:
+ Fix a dereference (read) of a freed pointer. Reported by Patrick
+ Williams.
+ [69877b633753]
+
+2008-08-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Set locale to "C" to avoid interpretation issues with character
+ ranges in sudoers. May want to make the locale a sudoers option in
+ the future.
+ [098a95de1746]
+
+2008-08-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ we no longer use setproctitle
+ [c7f20fb747ea]
+
+ * sudo.h:
+ remove #if 1
+ [a368ee6816c6]
+
+ * LICENSE, mkstemp.c:
+ Use my replacement mkstemp() from the mktemp package.
+ [d07c2beb0f9e]
+
+2008-07-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * gram.c:
+ regen with yacc skeleton bug fixed
+ [24784571cbb8]
+
+ * sudoers.pod:
+ Remove duplicate "as root". From Martin Toft.
+ [97241acfee5e]
+
+2008-07-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pwutil.c, sudo.c, sudo.h, testsudoers.c:
+ Flesh out the fake passwd entry used for running commands as a uid
+ not listed in the passwd database. Fixes an issue with some PAM
+ modules.
+ [a6648227f3f2]
+
+2008-07-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Error out in -i mode if the user has no shell. This can happen when
+ running commands as a uid with no password entry.
+ [0c174bef36ff]
+
+2008-06-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * toke.c, toke.l:
+ Better fix for line continuation inside double quotes. Now accepts
+ whitespace between the backslash and the newline like the main
+ lexer.
+ [64efcdf86d31]
+
+2008-06-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * toke.c, toke.l:
+ Fix line continuation in strings. It was only being honored if
+ preceded by whitespace.
+ [96c21271a3e4]
+
+2008-06-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, logging.c:
+ Replace the double fork with a fork + daemonize.
+ [328505441e67]
+
+2008-06-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c, sudo.c:
+ The -i flag should imply env_reset. This got broken in sudo 1.6.9.
+ [3caedfeaec87]
+
+ * logging.c, sudo.c, sudo_edit.c, visudo.c:
+ Change how the mailer is waited for. Instead of having a SIGCHLD
+ handler, use the double fork trick to orphan the child that opens
+ the pipe to sendmail. Fixes a problem running su on some Linux
+ distros.
+ [b59ce60a393d]
+
+2008-06-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Fix configure test for dirfd() on Linux where DIR is opaque.
+ [b8f729cdfecc]
+
+2008-06-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ Get rid of the QNX TCSAFLUSH -> TCSADRAIN hack. If QNX still has
+ this problem we'll need to revisit this again.
+ [c17fee8ad530]
+
+2008-06-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ Ignore SIGPIPE instead of blocking it when piping to the mailer. If
+ we only block the signal it may be delivered later when we unblock.
+ Also, there is no need to block SIGCHLD since we no longer do the
+ double fork. The normal SIGCHLD handler is sufficient.
+ [e94a49e992e5]
+
+2008-06-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Add description for NO_PAM_SESSION, from a redhat patch.
+ [b9e4c939ec09]
+
+2008-06-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man.in, sudo.pod:
+ Fix typos in -i usage
+ [2d7ce5de0235]
+
+2008-05-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Redo the test for dgettext() in a way that hopefully will work
+ around the libintl_dgettext() undefined problem.
+ [d27beb0cf85e]
+
+2008-05-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * schema.ActiveDirectory:
+ change filename in comment
+ [733da4ee9ac5]
+
+2008-05-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, README.LDAP, sudoers.ldap.cat, sudoers.ldap.man.in,
+ sudoers.ldap.pod:
+ Reference schema.ActiveDirectory
+ [d6aec537800e]
+
+2008-05-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * schema.OpenLDAP, schema.iPlanet:
+ Mark sudoRunAs as deprecated.
+ [00c50df807af]
+
+ * schema.ActiveDirectory:
+ add sudoRunAsUser and sudoRunAsGroup
+ [19bcce6f72fb]
+
+ * schema.ActiveDirectory:
+ Active Directory schema by Chantal Paradis and Eric Paquet
+ [06a09c92c6a5]
+
+2008-05-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ remove an XXX that was fixed
+ [b88038062fa2]
+
+ * ChangeLog:
+ sync
+ [8fc27c17270e]
+
+ * parse.c:
+ Initialize tags to UNSPEC instead of def_* in "sudo -l" mode. This
+ fixes a problem where the tag value printed was influenced by
+ defaults set in the first pass through the parser.
+ [588ccd630367]
+
+2008-05-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, sudo.psf:
+ No point in packaging the TODO file
+ [9590248fffe1]
+
+ * ChangeLog:
+ sync
+ [152acf4c6813]
+
+2008-05-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * WHATSNEW, def_data.c, def_data.h, def_data.in, env.c, sudo.c,
+ sudo.h, sudoers.cat, sudoers.man.in, sudoers.pod:
+ Add env_file Defaults option that is similar to /etc/environment on
+ some systems.
+ [1daf53d51e18]
+
+2008-05-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, README, TODO, WHATSNEW, sudo.cat, sudo.man.in,
+ sudoers.cat, sudoers.ldap.cat, sudoers.ldap.man.in, sudoers.man.in,
+ version.h, visudo.cat, visudo.man.in:
+ change version to 1.7.0
+ [d41d126b9bd8]
+
+ * UPGRADE:
+ initial valgrind pass done
+ [c59c3876d8ca]
+
+2008-04-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Fix typo/think in sudo_ldap_read_secret() when storing the secret.
+ [830d246c09b0]
+
+2008-04-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ define LDAPS_PORT if the system headers do not
+ [247b12325701]
+
+2008-04-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * gram.c, gram.y:
+ Fix another memory leak in init_parser().
+ [7bba47deba11]
+
+ * configure, configure.in:
+ There was a missing space before the ldap libs in SUDO_LIBS for some
+ configurations.
+ [7524cfc93759]
+
+ * alias.c, gram.c, gram.y, toke.c, toke.l:
+ Clean up some memory leaks pointed out by valgrind.
+ [a965866ece1a]
+
+2008-04-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ fix "sudo -s" broken by mode/flags breakout
+ [acffe984d408]
+
+ * configure, configure.in:
+ remove duplicate check for dgettext
+ [58145529133c]
+
+2008-04-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aix.c:
+ Fall back to default stanza if no user-specific limit is found.
+ [7b8cb29123ee]
+
+2008-04-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * snprintf.c:
+ include stdint.h if present
+ [f0ec38529306]
+
+ * snprintf.c:
+ Use LLONG_MAX, not the old QUAD_MAX
+ [01041ce508fb]
+
+2008-04-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.ldap.pod:
+ fix cut and pasto
+ [34240fdef5ab]
+
+2008-03-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pwutil.c:
+ Add #ifdef PURITY
+ [ce1b571ad526]
+
+2008-03-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/bsdauth.c:
+ remove useless cast
+ [494f8a862e1d]
+
+2008-03-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ChangeLog:
+ sync
+ [f5c97ffaabcc]
+
+ * TODO:
+ sync
+ [96ff1c44c182]
+
+ * sudo.h:
+ Split MODE_* defines into primary and flags.
+ [c02ee3027cb9]
+
+2008-03-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aix.c:
+ It turns out the logic for getting AIX limits is more convoluted
+ than I realized and differs depending on whether the soft and/or
+ hard limits are defined.
+ [cf8d3f85d395]
+
+2008-03-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, configure, configure.in:
+ Back out AIX-specific change to set the sudo_noexec path to the .a
+ file, we do really want to use the .so file. Since libtool doesn't
+ do that correctly, just install the .so file ourselves in the
+ Makefile.
+ [05c6f33177d9]
+
+ * install-sh:
+ If the file given to install is a path, only use the basename of the
+ file when building the destination path.
+ [695ba4e429ce]
+
+2008-03-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ parse_args() cleanup: Sort command line options in the getopt()
+ switch The -U option requires a parameter Normalize a few ISSET
+ calls Split mode into mode and flags and retire the now-obsolete
+ excl variable
+ [0d156835f861]
+
+ * WHATSNEW, check.c, sudo.c, sudo.cat, sudo.h, sudo.man.in, sudo.pod,
+ sudo_usage.h.in:
+ Add -n (non-interactive) flag.
+ [e3e50400d32d]
+
+ * sudo.c:
+ Move version printing, etc. into a separate function.
+ [18c91b476e2c]
+
+ * sudo.c:
+ Don't try to cleanup nsswitch if it has not been initialized.
+ [aeb1ca1b399d]
+
+2008-03-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ Block SIGPIPE in send_mail() so sudo is not killed by a problem
+ executing the mailer.
+ [f130e7924cca]
+
+2008-03-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ AIX shared libs end in .a, not .so.
+ [a5deb07020d8]
+
+2008-03-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ Preserve HOME by default too. Matches documentation and previous
+ behavior.
+ [c16f17f1047c]
+
+2008-03-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Use getopt() to parse the command line. We need to be able to
+ intersperse env variables and options yet still honor "--"" which
+ complicates things slightly.
+ [60f271ce5c16]
+
+2008-03-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ChangeLog:
+ sync
+ [685e67964eda]
+
+ * acsite.m4, configure, ltmain.sh:
+ update to libtool-1.5.26
+ [4c9a8c3d3b40]
+
+ * config.guess, config.sub:
+ update from libtool-1.5.26 distribution
+ [c6641aef2527]
+
+ * aix.c, sudo.h:
+ attempt to fix compilation errors on AIX
+ [edb13e5b2184]
+
+ * Makefile.in:
+ fix typo in last commit
+ [25ba7f7ceae4]
+
+ * Makefile.in:
+ Add WHATSNEW file to the distribution
+ [213f4115de8f]
+
+ * visudo.c:
+ use warningx instead of fprintf(stderr, ...)
+ [a3494b8ccb19]
+
+ * list.c:
+ add DEBUG to list2tq
+ [115d24a3000c]
+
+ * ChangeLog, TODO:
+ sync
+ [60e6f4d1fac0]
+
+ * WHATSNEW:
+ mention mailfrom
+ [e2498f9e18d6]
+
+ * Makefile.in, aix.c, config.h.in, configure, configure.in,
+ set_perms.c, sudo.h:
+ Add aix_setlimits() to set resource limits on AIX using a
+ combination of getuserattr() and setrlimit(). Currently untested.
+ [9b1441fd89ca]
+
+2008-03-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * def_data.c, def_data.h, def_data.in, logging.c, sudoers.cat,
+ sudoers.man.in, sudoers.pod:
+ Add mailfrom Defaults option that sets the value of the From: field
+ in the warning/error mail. If unset the login name of the invoking
+ user is used.
+ [029b9f05d3d9]
+
+ * defaults.c:
+ store a copy of _PATH_SUDO_ASKPASS in def_askpass that is freeable
+ [a90e407d5e00]
+
+ * gram.c, gram.y:
+ When adding a default, only call list2tq() once to do the list to tq
+ conversion. It is not legal to call list2tq multiple times on the
+ same list since list2tq consumes and modifies the list argument.
+ [fbc25d245c4a]
+
+ * sudoers.ldap.cat, sudoers.ldap.man.in, sudoers.ldap.pod:
+ comment out XXXs for now
+ [595a1d43309d]
+
+ * WHATSNEW:
+ mention askpass
+ [b993e0837c22]
+
+2008-03-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Error out if both -A and -S are specified Error out if -A is
+ specified but no askpass is configured
+ [24f1df2638f6]
+
+ * configure, configure.in:
+ we are not going to ship a sudo-specific askpass
+ [61949e7a3943]
+
+2008-03-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.h:
+ fix definition of TGP_ASKPASS
+ [0447c57ba4c3]
+
+ * def_data.c, def_data.in:
+ make askpass boolean-capable
+ [e0885893a325]
+
+ * INSTALL:
+ document --with-askpass
+ [c76e15ba97cf]
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.ldap.cat,
+ sudoers.man.in, visudo.cat:
+ regen
+ [8d16242980b7]
+
+2008-03-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod, sudo_usage.h.in, sudoers.pod:
+ document -A and askpass
+ [02c07505a78c]
+
+ * auth/sudo_auth.c, check.c, configure, configure.in, def_data.c,
+ def_data.h, def_data.in, defaults.c, pathnames.h.in, sudo.c, sudo.h,
+ sudo_usage.h.in, tgetpass.c:
+ Add support for running a helper program to read the password when
+ no tty is present (or when specified with the -A flag). TODO: docs.
+ [05780f5f71fd]
+
+ * def_data.c, def_data.in:
+ add missing printf format to SELinux role and type strings
+ [2b32774715e7]
+
+2008-02-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, configure, configure.in:
+ Disable use of gss_krb5_ccache_name() by default and add
+ --enable-gss-krb5-ccache-name configure option to enable it. It seems
+ that gss_krb5_ccache_name() doesn't work properly with some
+ combinations of Heimdal and OpenLDAP.
+ [f61ebd3b19bd]
+
+2008-02-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * selinux.c:
+ Ignore setexeccon() failing in permissive mode. Also add a call to
+ setkeycreatecon() (though this is probably insufficient). From Dan
+ Walsh.
+ [52564fc1c069]
+
+ * auth/pam.c:
+ Only set std_prompt for the PAM_PROMPT_* cases. The conversation
+ function may be called for non-password reading purposes so we must
+ be careful not to use def_prompt in cases where it may not be set.
+ [29d88ca575ba]
+
+2008-02-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * selinux.c:
+ Don't free the new tty context, we need to keep it around when we
+ restore the tty context after the command completes
+ [5b4bd39b6ea8]
+
+2008-02-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * selinux.c:
+ s/newrole/sudo/
+ [21b8a96ff8df]
+
+ * sudo.man.pl, sudo.pod:
+ Only put login_cap(3) in SEE ALSO section if we have login.conf
+ support
+ [05250ddff2c0]
+
+2008-02-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.ldap.cat,
+ sudoers.ldap.man.in, sudoers.man.in, visudo.cat, visudo.man.in:
+ regen
+ [301e5c5ccdbe]
+
+ * sudoers.pod:
+ Substitute in comment characters for lines partaining to login.conf,
+ BSD auth and SELinux and only enable them if pertinent.
+ [c1c98fa163ce]
+
+ * sudoers.man.pl:
+ Substitute in comment characters for lines partaining to login.conf,
+ BSD auth and SELinux and only enable them if pertinent.
+ [6c88f30b878a]
+
+ * sudo.pod:
+ Substitute in comment characters for lines partaining to login.conf,
+ BSD auth and SELinux and only enable them if pertinent.
+ [acdbdfd24e1d]
+
+ * sudo.man.pl:
+ Substitute in comment characters for lines partaining to login.conf,
+ BSD auth and SELinux and only enable them if pertinent.
+ [0c56d4750ac3]
+
+ * Makefile.in, configure, configure.in:
+ Substitute in comment characters for lines partaining to login.conf,
+ BSD auth and SELinux and only enable them if pertinent.
+ [9a02bd6a6658]
+
+ * Makefile.in, sudo.pod, sudoers.ldap.pod, sudoers.pod, visudo.pod:
+ Remove the =cut on the first line (above the copyright notice) to
+ quiet pod2man. Also remove the hackery in the FILES section and just
+ deal with the fact that there will a newline between each pathname.
+ [2ac1ab191835]
+
+2008-02-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ run sudo.man.pl when generating sudo.man.in
+ [859727369168]
+
+ * configure, configure.in, sudo.man.pl:
+ comment out SELinux manual bits unless --with-selinux was specified
+ [97ff4212b649]
+
+ * sudoers.pod:
+ document role and type defaults for SELinux
+ [870f303366b3]
+
+ * sudo.c, sudo.cat, sudo.man.in, sudo.pod, sudo_usage.h.in:
+ Document "sudo -ll" and make "sudo -l -l" be equivalent.
+ [3ce6dc429ea3]
+
+2008-02-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Treat k*bsd*-gnu like Linux, not BSD. Fixes compilation problems on
+ Debian GNU/kFreeBSD.
+ [c4efa567a328]
+
+2008-02-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/kerb5.c:
+ Avoid Heimdal'isms introduced in the rev 1.32 rewrite of
+ verify_krb_v5_tgt()
+ [f80538e5a6fa]
+
+ * logging.c, logging.h, sudo.c:
+ Remove dependence on VALIDATE_NOT_OK in logging functions. Split
+ log_auth() into log_allowed() and log_denial() Replace mail_auth()
+ with should_mail() and a call to send_mail()
+ [58aac9997557]
+
+2008-02-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Add debugging so we can tell if the krb5 ccache is accessible
+ [c679322527bb]
+
+ * INSTALL:
+ mention --with-selinux
+ [9efbe0b52194]
+
+2008-02-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [467a834f867c]
+
+ * selinux.c:
+ add Sudo tag
+ [d004ee669bed]
+
+ * sudo.c, sudo.cat, sudo.h, sudo.man.in, sudo.pod, sudo_usage.h.in,
+ sudoers.ldap.cat, sudoers.ldap.man.in, sudoers.ldap.pod,
+ testsudoers.c, toke.c, toke.l:
+ Add support for SELinux RBAC. Sudoers entries may specify a role and
+ type. There are also role and type defaults that may be used. To
+ make sure a transition occurs, when using RBAC commands are executed
+ via the new sesh binary. Based on initial changes from Dan Walsh.
+ [1d4abfe2c004]
+
+ * sesh.c:
+ Add support for SELinux RBAC. Sudoers entries may specify a role and
+ type. There are also role and type defaults that may be used. To
+ make sure a transition occurs, when using RBAC commands are executed
+ via the new sesh binary. Based on initial changes from Dan Walsh.
+ [1e3b395ce049]
+
+ * Makefile.in, config.h.in, configure.in, def_data.c, def_data.h,
+ def_data.in, gram.c, gram.h, gram.y, ldap.c, parse.c, parse.h,
+ pathnames.h.in, selinux.c:
+ Add support for SELinux RBAC. Sudoers entries may specify a role and
+ type. There are also role and type defaults that may be used. To
+ make sure a transition occurs, when using RBAC commands are executed
+ via the new sesh binary. Based on initial changes from Dan Walsh.
+ [6b421948286e]
+
+2008-02-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lbuf.c, ldap.c, parse.c, sudo.c, sudo.h, sudo_nss.c:
+ Add long list (sudo -ll) support for printing verbose LDAP and
+ sudoers file entries. Still need to update manual.
+ [2875be37935c]
+
+2008-02-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c, parse.c, sudo.h, sudo_nss.c, sudo_nss.h:
+ Unify the -l output for file and ldap based sudoers and use lbufs
+ for both. The ldap output does not currently include options that
+ cannot be represented as tags. This will be remedied in a long list
+ output mode to come.
+ [b2e429456596]
+
+2008-01-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * set_perms.c:
+ Use a specific error message for errno == EAGAIN when setuid() et al
+ fails. On Linux systems setuid() will fail with errno set to EAGAIN
+ if changing to the new uid would result in a resource limit
+ violation.
+ [08d0aecd9f03]
+
+ * sudo.c:
+ Unlimit nproc on Linux systems where calling the setuid() family of
+ syscalls causes the nroc resource limit to be checked. The limits
+ will be reset by pam_limits.so when PAM is used. In the non-PAM case
+ the nproc limit will remain unlimited but there doesn't seem to be a
+ way around that other than having sudo parse
+ /etc/security/limits.conf directly.
+ [df024b415a8d]
+
+ * env.c, sudo.c, sudo.pod:
+ Only read /etc/environment on Linux and AIX
+ [90669e2aefdb]
+
+2008-01-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Use SUDO_DEFINE_UNQUOTED instead of AC_DEFINE_UNQUOTED to prevent
+ ldap.conf and ldap.secret paths from going into config.h. Avoid
+ single quotes in variable expansion when using SUDO_DEFINE_UNQUOTED
+ since in some versions of bash they will end up literally in the
+ resulting define.
+ [25390f3ef10a]
+
+2008-01-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README.LDAP:
+ mention --with-nsswitch=no
+ [c509df927263]
+
+ * configure, configure.in:
+ ldap_ssl.h depends on ldap.h being included first
+ [d96d90e9b21f]
+
+ * config.h.in, configure, configure.in, ldap.c:
+ Include ldap_ssl.h if we can find it. Needed for the
+ ldapssl_set_strength defines on HP-UX at least.
+ [9e530470948a]
+
+ * sudoers.ldap.pod:
+ sync
+ [b9d101f4673a]
+
+ * TODO:
+ sync
+ [2ce951b2ecd0]
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.ldap.cat,
+ sudoers.ldap.man.in, sudoers.man.in, visudo.cat, visudo.man.in:
+ regen
+ [b61d793987e0]
+
+ * Makefile.in:
+ Use 78n line length when formatting cat pages.
+ [761bee9d5759]
+
+ * README.LDAP:
+ Remove redundant info that is now in sudoers.ldap.pod
+ [01828dcce59e]
+
+2008-01-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.ldap.cat, sudoers.ldap.man.in, sudoers.ldap.pod:
+ Reorganize the first section a bit. Substitute the proper path for
+ /etc/sudoers.
+ [11ae165e065d]
+
+ * sudoers.ldap.cat, sudoers.ldap.man.in, sudoers.ldap.pod:
+ Substitute values for ldap.conf, ldap.secret and nsswitch.conf Move
+ schema into EXAMPLES
+ [ab6509d1dde7]
+
+ * configure, configure.in:
+ Substitute values for ldap.conf, ldap.secret and nsswitch.conf into
+ sudoers.ldap.man.
+ [6e689972f465]
+
+ * configure, configure.in:
+ substitute for sudoers.ldap.man
+ [5a4a25766dee]
+
+ * Makefile.in:
+ Fix cut & pasto introduced when adding sudoers.ldap man page.
+ [a7b069af8894]
+
+ * sudoers.ldap.cat, sudoers.ldap.man.in, sudoers.ldap.pod:
+ Fill in some of the missing pieces. Still needs some reorganization
+ and editing.
+ [5e7331722166]
+
+2008-01-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, sudoers.ldap.cat, sudoers.ldap.man.in,
+ sudoers.ldap.pod:
+ Beginnings of a sudoers.ldap man page. Currently, much of the
+ information is adapted from README.LDAP.
+ [aad28c8a922d]
+
+2008-01-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pwutil.c:
+ When copying gr_mem we must guarantee that the storage space for
+ gr_mem is properly aligned. The simplest way to do this is to simply
+ store gr_mem directly after struct group. This is not a problem for
+ gr_passwd or gr_name as they are simple strings.
+ [af58fc76f1ed]
+
+ * ldap.c:
+ Fix a typo/thinko in one of the calls to
+ sudo_ldap_check_user_netgroup(). From Marco van Wieringen.
+ [70b2eb8097f5]
+
+2008-01-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, ldap.c:
+ include <mps/ldap_ssl.h> in ldap.c if available
+ [34346206ef16]
+
+2008-01-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * gram.c, gram.y:
+ Make sure we define SIZE_MAX for yacc's skeleton.c
+ [d8a45c7a3c42]
+
+ * tgetpass.c:
+ Use TCSAFLUSH when restoring terminal settings (and echo) to
+ guarantee that any pending output is discarded
+ [549a184479e5]
+
+2008-01-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers:
+ no longer need to specify SETENV when user has sudo ALL
+ [3051b41f8032]
+
+ * testsudoers.c:
+ sync user_args size calculation with sudo.c Add -g group option,
+ renaming old -g to -G Add set_runasgr() and set_runaspw() and use
+ them
+ [0850325180f0]
+
+ * sudo.c, sudo.h:
+ Make set_runaspw static void
+ [5d44d7a340ce]
+
+ * testsudoers.c, visudo.c:
+ g/c set_runaspw stub
+ [79ebb5e2cc38]
+
+ * configure, configure.in:
+ Don't add -llber twice.
+ [4356d302eef4]
+
+2008-01-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ fix typo
+ [249cecc557e9]
+
+2008-01-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * gram.c:
+ regen
+ [2f94ea375b67]
+
+ * configure, configure.in:
+ Fix check that determines whether -llber is required.
+ [6afa99523379]
+
+ * README.LDAP, config.h.in, configure, configure.in, ldap.c:
+ For netscape-based LDAP, use ldapssl_set_strength() to implement the
+ checkpeer ldap.conf option.
+ [16ae24d73795]
+
+ * auth/kerb5.c:
+ Delay krb5_cc_initialize() until we actually need to use the cred
+ cache, which is what krb5_verify_user() does. Better cleanup on
+ failure.
+ [d12e5f1695b8]
+
+2008-01-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/kerb5.c:
+ Rewrite verify_krb_v5_tgt() based on what heimdal's
+ krb5_verify_user() does.
+ [05b5815f86c9]
+
+2008-01-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * gram.c:
+ The U suffix on constants is an ANSI feature
+ [c6dfce3167f1]
+
+ * configure, configure.in:
+ Add check for ber_set_option() in -llber
+ [43d0c0566074]
+
+2008-01-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README.LDAP:
+ default if no nsswitch.conf is files only
+ [c13001d9c998]
+
+2008-01-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README.LDAP:
+ don't tell people to mail aaron about LDAP stuff
+ [8165ec1ef0c6]
+
+ * README.LDAP:
+ timelimit and bind_timelimit
+ [44f74cbed167]
+
+ * ChangeLog:
+ sync
+ [aba1a0ab02bd]
+
+ * ldap.c:
+ Move ldap.secret reading into a separate function.
+ [1948acc9f7a4]
+
+ * check.c:
+ user_runas -> runas_pw
+ [334490fc2bae]
+
+2008-01-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TODO:
+ sync
+ [c7b165cc47c6]
+
+ * check.c, sudo.pod, sudoers.pod:
+ Add and document the %p escape in the password prompt. Based on a
+ patch from Patrick Schoenfeld.
+ [3972d4f31ffa]
+
+ * ldap.c:
+ Check strlcpy() return values.
+ [9b42f3ae8ff1]
+
+ * ldap.c:
+ refactor ldap binding code into sudo_ldap_bind_s()
+ [cb0c66a4d955]
+
+ * README.LDAP:
+ Make it clear that host and uri can take multiple parameters. URI is
+ now supported for more than just openldap nsswitch.conf does't
+ accept "compat"
+ [f610dea656d6]
+
+ * sudo.c:
+ comment cleanup and update (c) year
+ [6cd69c810ca5]
+
+ * parse.c, sudo_nss.c:
+ Move display_privs() and display_cmnd() from parse.c to sudo_nss.c.
+ This should make it possible to build an LDAP-only sudo binary.
+ [61c3f27066a0]
+
+ * ldap.c, parse.c, sudo.c, sudo.h, sudo_nss.h:
+ Improve chaining of multiple sudoers sources by passing in the
+ previous return value to the next in the chain
+ [2c0b722b1b2d]
+
+ * gram.y:
+ Free up parser data structures in sudo_file_close().
+ [2251531d4519]
+
+ * gram.c, parse.c:
+ Free up parser data structures in sudo_file_close().
+ [8371f130f401]
+
+ * ldap.c:
+ Parse uri ourself if no ldap_initialize() is present Use
+ ldap_create() instead of deprecated ldap_init() Use
+ ldap_sasl_bind_s() instead of deprecated ldap_simple_bind_s()
+ [85d3825b1953]
+
+ * config.h.in, configure, configure.in:
+ Add check for ldap_sasl_bind_s() Remove -DLDAP_DEPRECATED from
+ CFLAGS
+ [240524512bc5]
+
+2008-01-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in:
+ add check for ldap_create
+ [3089badd73b8]
+
+2008-01-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, ldap.c:
+ Add sudo_ldap_get_first_rdn() to return the first rdn of an entry's
+ dn using the mechanism appropriate for the LDAP SDK in use. Use
+ ldap_unbind_ext_s() instead of deprecated ldap_unbind_s(). Emulate
+ ldap_unbind_ext_s() and ldap_search_ext_s() for SDK's without them.
+ [6deeca3d00cc]
+
+ * lbuf.c:
+ include unistd.h
+ [8419ed0bae7f]
+
+ * config.h.in, configure.in:
+ fix typo in mtim_getnsec
+ [2d5f21230a60]
+
+2008-01-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in:
+ add check for st__tim in struct stat as used by SCO
+ [587060ea2a89]
+
+ * ldap.c:
+ use ldap_search_ext_s instead of deprecated ldap_search_s
+ [5fc44fe3b44c]
+
+ * Makefile.in, TODO, sudo.cat, sudo.man.in:
+ add sudo_nss.h to HDRS
+ [86f01a70ff29]
+
+ * ldap.c:
+ Replace deprecated ldap_explode_dn() with calls to ldap_str2dn() and
+ ldap_rdn2str().
+ [aa217002cfae]
+
+2008-01-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Use ldap_get_values_len()/ldap_value_free_len() instead of the
+ deprecated ldap_get_values()/ldap_value_free().
+ [e22dceb85e57]
+
+ * ChangeLog:
+ sync
+ [adad27b36107]
+
+ * TODO:
+ sync
+ [c449eb47e0ef]
+
+ * gettime.c, sudo.c:
+ Remove some already fixed XXXs
+ [532788d0e6da]
+
+ * ldap.c:
+ Same return value as non-existent sudoers if LDAP was unable to
+ connect.
+ [5819810e8e4e]
+
+ * sudo.pod:
+ mention /etc/environment
+ [ea8e6102f853]
+
+ * README.LDAP, UPGRADE, WHATSNEW:
+ Update to reflect recent developments.
+ [ed1fb026fe77]
+
+ * sudo.c:
+ Print nsswitch.conf, ldap.conf and ldap.secret paths in -V output.
+ [55b68a58260d]
+
+ * ldap.c:
+ When building up a query don't list groups in the aux group vector
+ that are the same as the passwd file group. On most systems the
+ first gid in the group vector is the same as the passwd entry gid.
+ [4bb51e297e0d]
+
+ * env.c, ldap.c:
+ Define LDAPNOINIT before calling ldap_init(), etc. to disable user
+ ldaprc and system defaults that could affect how LDAP works.
+ [ce5036440db2]
+
+ * INSTALL, configure, configure.in, pathnames.h.in, sudo.c,
+ sudo_nss.c, sudo_nss.h:
+ Rename read_nss -> sudo_read_nss Add --with-nsswitch to allow users
+ to specify nsswitch.conf path or disable it. If --with-nsswitch=no
+ but --with-ldap, order is LDAP, then sudoers. Fix --with-ldap-conf-
+ file and --with-ldap-secret-file
+ [ea5d7704381f]
+
+ * parse.c:
+ Honor def_ignore_local_sudoers
+ [f38e1121fae1]
+
+2007-12-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ no longer need to check def_ignore_local_sudoers here
+ [fce2a72f96fb]
+
+ * parse.c:
+ Refactor group vector resetting into a function and also call it
+ from display_cmnd. Stop after the first sucessful match in
+ display_cmnd. Print a newline between each display_privs method.
+ [981b37b5adff]
+
+ * parse.c:
+ fix double free introduced in rev 1.218
+ [c574b02d8747]
+
+ * ldap.c:
+ belt and suspenders; zero out result after freeing it
+ [7732988d4620]
+
+ * env.c, fileops.c, ldap.c, sudo.h, sudo_nss.c:
+ Refactor line reading into a separate function, sudo_parseln(),
+ which removes comments, leading/trailing whitespace and newlines.
+ May want to rethink the use of sudo_parseln() for /etc/ldap.secret
+ [61d9068f0645]
+
+ * parse.c, sudo.c:
+ Make the inability to read the sudoers file a non-fatal error if
+ there are other sudoers sources available. sudoers_file_lookup now
+ returns "not OK" if sudoers was not present
+ [643babf597a8]
+
+ * ldap.c:
+ make it clear that the global options are from LDAP
+ [9ff950349463]
+
+ * logging.c:
+ allocate proper amount of space for error string
+ [8bebb7d46d19]
+
+ * sudo_nss.c, sudo_nss.h:
+ actual sudo nss code
+ [5bd7d52d7738]
+
+ * ldap.c, parse.c, sudo.c, sudo.h:
+ nss-ify display_privs and display_cmnd.
+ [cccfdd3253f2]
+
+ * defaults.c, parse.c, testsudoers.c, visudo.c:
+ move update_defaults() to parse.c
+ [ace144b958a9]
+
+ * Makefile.in, ldap.c, list.c, parse.c, parse.h, sudo.c, sudo.h:
+ Use nsswitch to hide some sudoers vs. ldap implementation details
+ and reduce the number of #ifdef LDAP TODO: fix display routines and
+ error handling
+ [6225edde89a6]
+
+2007-12-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, README.LDAP, ldap.c, pathnames.h.in, sudo.c, sudo.h:
+ First cut at nsswitch.conf support. Further reorganizaton and
+ related changes are forthcoming.
+ [717f59d0790b]
+
+2007-12-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c, pathnames.h.in, sudo.c, sudo.h:
+ Add support for reading and /etc/environment file. Still needs to be
+ documented and should probably only applies to OSes that have it
+ (AIX and Linux, maybe others).
+ [15d3edae27e4]
+
+ * ldap.c:
+ include limits.h
+ [e19875ef0f82]
+
+2007-12-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * WHATSNEW:
+ reword LDAP SASL
+ [7ec3c4ec31b5]
+
+2007-12-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TODO:
+ sync
+ [87c5a7aea7bf]
+
+ * README.LDAP:
+ Add an example sudoRole, clarify netscape vs. openldap a bit more
+ [6f96c0ca8107]
+
+ * README.LDAP:
+ Be clear on what is OpenLDAP vs. Netscape-derived
+ [a33c8314dec5]
+
+ * config.h.in, configure, configure.in, ldap.c:
+ Use ldapssl_init() for ldaps support instead of trying to do it
+ manually with ldap_init() + ldapssl_install_routines(). Use tls_cert
+ and tls_key for cert7.db and key3.db respectively. Don't print
+ debugging info for options that are not set. Add warning if
+ start_tls specified when not supported.
+ [abb62dc7e4a3]
+
+ * ldap.c:
+ fix compilation on solaris
+ [03d449684e80]
+
+ * Makefile.in:
+ add missing .h and .c files for missing lib objs
+ [8b37825bdfc7]
+
+2007-12-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ fix LDAP_OPT_NETWORK_TIMEOUT setting
+ [226eba89c0ad]
+
+ * ldap.c:
+ fix compilation on Solaris
+ [917d47639eb6]
+
+2007-12-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ fix typo
+ [009d5c81b225]
+
+ * README.LDAP:
+ try to clear up which variables are for OpenLDAP and which are for
+ netscape-derived SDKs
+ [f8d9823ee73c]
+
+ * config.h.in, configure, configure.in, ldap.c:
+ Add support for "ssl on" in both netscape and openldap flavors. Only
+ the OpenLDAP flavor has been tested.
+ [952745829ec5]
+
+ * logging.c, sudo.c, sudo.h:
+ Call cleanup() before exit in log_error() instead of calling
+ sudo_ldap_close() directly. ldap_conn can now be static to sudo.c
+ [da02d1b67a2c]
+
+ * sudo.c:
+ ld -> ldap_conn
+ [01afa6d927cc]
+
+2007-12-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c, sudo.c, sudo.h:
+ Better ldap cleanup.
+ [25b9abe2d617]
+
+ * ldap.c:
+ Distinguish between LDAP conf settings that are connection-specific
+ (which take an ld pointer) and those that are default settings
+ (which do not).
+ [d48dc6c9c3b4]
+
+2007-12-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Improved warnings on error.
+ [c8dce7b4feb4]
+
+ * ldap.c:
+ Make ldap config table driven and set the config *after* we open the
+ connection.
+ [d9698b5a2681]
+
+2007-12-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ fix LDAP_OPT_X_CONNECT_TIMEOUT compat define
+ [598c6df06660]
+
+ * configure, configure.in:
+ some operating systems need to link with -lkrb5support when using
+ krb5
+ [8896365dde9e]
+
+2007-12-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * WHATSNEW:
+ minor update
+ [acfeeb7f4886]
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in:
+ regen
+ [a3c6699674f9]
+
+2007-12-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ChangeLog, TODO:
+ sync
+ [138e99b925ee]
+
+ * ldap.c, schema.OpenLDAP, schema.iPlanet, sudoers2ldif:
+ add -g support for LDAP
+ [8fc27dbe9287]
+
+2007-12-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * WHATSNEW, sudo.c, sudo.pod, sudo_usage.h.in:
+ The -i and -s flags can now take an optional command.
+ [6afec104ee77]
+
+2007-12-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c, def_data.c, def_data.h, def_data.in, sudo.c, sudo.pod,
+ sudoers.pod:
+ Add passprompt_override flag to sudoers that will cause the prompt
+ to be overridden in all cases. This flag is also set when the user
+ specifies the -p flag.
+ [e4c5402131a6]
+
+ * sudo.c:
+ Move setting of login class until after sudoers has been parsed. Set
+ NewArgv[0] for -i after runas_pw has been set.
+ [62a48c8c56fa]
+
+ * configure, configure.in:
+ Move the dgettext check.
+ [5fd8a4712d1c]
+
+2007-12-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c, config.h.in, configure, configure.in:
+ Add basic support for looking up the string "Password: " in the PAM
+ localized text db. This allows us to determine whether the PAM
+ prompt is the default "Password: " one even if it has been
+ localized.
+
+ TODO: concatenate non-std PAM prompts and user-specified sudo
+ prompts.
+ [81c25a415d41]
+
+2007-11-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, config.h.in, configure, configure.in, parse.c,
+ set_perms.c, sudo.c, sudo.h:
+ Use AC_FUNC_GETGROUPS instead of a home-grown attempt that was
+ insufficient.
+ [1cce6ec1a91e]
+
+ * acsite.m4, configure, interfaces.c, memrchr.c:
+ Fix typos; Martynas Venckus
+ [be1233cca11a]
+
+2007-11-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * set_perms.c:
+ Don't assume runas_pw is set; it may not be in the -g case.
+ [aa11bd2193ac]
+
+2007-11-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c, set_perms.c:
+ Set aux group vector for PERM_RUNAS and restore group vector for
+ PERM_ROOT if we previously changed it. Stash the runas group vector
+ so we don't have to call initgroups more than once. Also add no-op
+ check to check_perms.
+ [53837fc755f7]
+
+2007-11-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * WHATSNEW, check.c, def_data.in, defaults.c, gram.c, gram.h, gram.y,
+ ldap.c, logging.c, match.c, mon_systrace.c, parse.c, parse.h,
+ pwutil.c, set_perms.c, sudo.c, sudo.cat, sudo.h, sudo.man.in,
+ sudo.pod, sudo_usage.h.in, sudoers.cat, sudoers.man.in, sudoers.pod,
+ testsudoers.c, visudo.c, visudo.cat, visudo.man.in:
+ Add support for runas groups. This allows the user to run a command
+ with a different effective group. If the -g option is specified
+ without -u the command will be run as the current user (only the
+ group will change). the -g and -u options may be used together.
+ TODO: implement runas group for ldap improve runas group
+ documentation add testsudoers support
+ [9019309df6d0]
+
+ * configure, configure.in:
+ fix setting of mandir
+ [2c60f269399f]
+
+ * sudo.pod, sudoers.pod:
+ document that ALL implies SETENV
+ [bcc8e5b703b9]
+
+ * ldap.c:
+ s/setenv_ok/setenv_implied/g
+ [f005df2c2eea]
+
+ * ldap.c:
+ hostname_matches() returns TRUE on match in sudo 1.7.
+ [c3d4377b6e8b]
+
+ * ldap.c:
+ use strcmp, not strcasecmp when comparing ALL
+ [e486024574a1]
+
+ * ldap.c:
+ Make sudo ALL imply setenv. Note that unlike with file-based sudoers
+ this does affect all the commands in the sudoRole.
+ [bc12f54321d1]
+
+ * gram.c, gram.y, parse.c, parse.h:
+ sudo "ALL" now implies the SETENV tag but, unlike an explicit tag,
+ it is not passed on to other commands in the list.
+ [026e2cb40680]
+
+ * visudo.c:
+ Add missing sudo_setpwent() and sudo_setgrent() calls. Also use
+ sudo_getpwuid() instead of getpwuid().
+ [86f30a8fbd49]
+
+2007-11-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers:
+ Expand on the dangers of not using visudo to edit sudoers.
+ [e434e8057d02]
+
+2007-11-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ Don't quote *?[]! on output since the lexer does not strip off the
+ backslash when reading those in.
+ [561da4a13afa]
+
+2007-11-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * glob.c:
+ expand "u_foo" types to "unsigned foo" to avoid compatibility
+ issues.
+ [b0d7c64d78c3]
+
+2007-11-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ Refactor log line generation in to new_logline().
+ [6a9b9730615d]
+
+2007-10-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TROUBLESHOOTING:
+ fix typo
+ [9e19d4f86e47]
+
+2007-10-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, interfaces.c, interfaces.h,
+ match.c:
+ Add configure check for struct in6_addr instead of relying on
+ AF_INET6 since some systems define AF_INET6 but do not include IPv6
+ support.
+ [e24082c416bd]
+
+2007-10-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Fix block to add -lutil for FreeBSD and NetBSD when logincap is in
+ use.
+ [76a9df4a63be]
+
+2007-10-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ POSIX states that struct timespec be declared in time.h so check
+ there regardless of the value of TIME_WITH_SYS_TIME.
+ [e42c55ec9daf]
+
+2007-10-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ Instead of defining a macro to call the appropriate method for
+ turning on/off echo, just define tc[gs]etattr() and the related
+ defines that use the correct terminal ioctls if needed. Also go back
+ to using TCSAFLUSH instead of TCSADRAIN on all but QNX.
+ [5dfb2379d995]
+
+2007-10-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ g/c @ALLOCA@
+ [e6946c2e3820]
+
+ * configure:
+ regen
+ [9bac7159a138]
+
+ * INSTALL, auth/pam.c, config.h.in, configure.in:
+ Add --disable-pam-session configure option to disable calling
+ pam_{open,close}_session. May work around bugs in some PAM
+ implementations.
+ [273d0fdb4a9d]
+
+2007-10-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ quiet gcc warnings
+ [325565c5a579]
+
+ * tgetpass.c:
+ Avoid printing the prompt if we are already backgrounded. E.g. if
+ the user runs "sudo foo &" from the shell. In this case, the call to
+ tcsetattr() will cause SIGTTOU to be delivered.
+ [db2139a8d8b8]
+
+2007-09-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * def_data.c, def_data.h, def_data.in:
+ Reorder things such that the definition of env_reset come right
+ before the env variable lists.
+ [e0d8e22a581a]
+
+ * parse.h:
+ Shrink type and seqno in struct alias from int to u_short
+ [9425263dd565]
+
+ * alias.c, match.c, parse.c, parse.h:
+ Add a sequence number in the aliases for loop detection. If we find
+ an alias with the seqno already set to the current (global) value we
+ know we've visited it before so ignore it.
+ [301a0548ffff]
+
+2007-09-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TODO, auth/pam.c, sudo.c, sudo.h:
+ PAM wants the full tty path so add user_ttypath which holds the full
+ path to the tty or is NULL if no tty was present.
+ [c7c1dd4b36c8]
+
+ * auth/pam.c:
+ Set PAM_RHOST to work around a bug in Solaris 7 and lower that
+ results in a segv.
+ [3a8865b3a357]
+
+2007-09-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * gram.c:
+ regen
+ [5647be127950]
+
+ * alias.c, defaults.c, gram.y, list.c, list.h, match.c, parse.c,
+ parse.h, testsudoers.c, visudo.c:
+ rename lh_ -> tq_
+ [8f500c542c4a]
+
+2007-09-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * alloc.c:
+ remove some useless casts
+ [409a448b23f5]
+
+ * alloc.c:
+ pull in inttypes.h for SIZE_MAX; we avoid stdint.h since inttypes.h
+ predates the final C99 spec and the standard specifies that it shall
+ include stdint.h anyway
+ [ae478fdef61a]
+
+2007-09-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, alloca.c, configure.in:
+ Since we ship with a pre-generated parser there is no need to ship a
+ bogus alloca implementation.
+ [3f611a7cc0e5]
+
+ * configure:
+ regen
+ [771eccf5269c]
+
+ * configure.in:
+ remove initial setting of CHECKSIA, we require that it be unset if
+ not used
+ [a2e91adc5aa2]
+
+ * Makefile.in:
+ add list.c to SRCS
+ [7db0e56cf5b9]
+
+ * configure:
+ regen
+ [3716ec30172e]
+
+ * configure.in:
+ only do SIA checks on Digital Unix
+ [6a96e1af2597]
+
+2007-09-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.cat, sudoers.man.in:
+ regen
+ [ac1dc29de72b]
+
+ * ChangeLog, TODO:
+ sync
+ [781effce0a2d]
+
+ * auth/kerb5.c:
+ Remove call to krb5_cc_register() as it is not needed for modern
+ kerb5.
+ [351b8b764f16]
+
+ * configure:
+ regen
+ [ac21dbcc9c2c]
+
+ * aclocal.m4, configure.in:
+ New method for setting the default authentication type and avoiding
+ conflicts in auth types.
+ [5fb15be11f78]
+
+ * match.c, parse.c, testsudoers.c:
+ Each entry in a cmndlist now has an associated runaslist so no need
+ to keep track of the most recent non-NULL one.
+ [582e015786b0]
+
+2007-09-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ back out partial ldaps support mistakenly committed
+ [357703e94b2d]
+
+ * ldap.c:
+ Add support for unix groups and netgroups in sudoRunas
+ [2f04eb91c6d0]
+
+2007-09-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo_edit.c:
+ Fix sudoedit of a non-existent file. From Tilo Stritzky.
+ [a5488a03bddd]
+
+2007-09-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [541177376ee1]
+
+ * INSTALL:
+ update --passprompt escape info
+ [6d57db4cd538]
+
+ * configure.in:
+ remove now-bogus comment and update copyright date
+ [6a4af45fa331]
+
+ * configure.in:
+ Fix up use of with_passwd
+ [7c79d8640f77]
+
+ * acsite.m4, config.guess, config.sub, configure.in, ltmain.sh:
+ Update to autoconf-2.61 andf libtool-1.5.24
+ [045259b0b439]
+
+ * Makefile.in:
+ "cmp -s" not just cmp Add @datarootdir@ to quiet autoconf-2.61
+ [f5b6a7afb817]
+
+2007-09-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * gram.c:
+ regen
+ [b5b78e71d2cb]
+
+ * gram.y:
+ move tags and runaslist propagation to be earlier
+ [94f7805f4489]
+
+ * visudo.c:
+ If -f flag given use the permissions of the original file as a
+ template
+ [9303d22bddb0]
+
+ * gram.y:
+ prevent a double free() when re-initing the parser
+ [5b3907c4de5a]
+
+2007-08-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [49a90b19a17d]
+
+ * aclocal.m4, alias.c, alloc.c, auth/API, auth/afs.c, auth/bsdauth.c,
+ auth/kerb4.c, auth/kerb5.c, auth/pam.c, auth/securid.c,
+ auth/securid5.c, auth/sia.c, auth/sudo_auth.h, config.h.in,
+ configure.in, env.c, ldap.c, list.c, list.h, memrchr.c, parse.c,
+ parse.h, pwutil.c, redblack.c, redblack.h, snprintf.c, sudo.c,
+ sudo.h, testsudoers.c, visudo.c, zero_bytes.c:
+ Remove support for compilers that don't support void *
+ [35e1d01ae197]
+
+ * gram.c:
+ regen
+ [70ce412a458a]
+
+ * Makefile.in, alias.c, defaults.c, gram.y, list.c, list.h, match.c,
+ parse.c, parse.h, testsudoers.c, visudo.c:
+ Move list manipulation macros to list.h and create C versions of the
+ more complex ones in list.c. The names have been down-cased so they
+ appear more like normal functions.
+ [9cea0e281148]
+
+ * Makefile.in:
+ Fix cmp command when regenerating parser. Make gram.o the first
+ dependency for all programs so gram.h will be generated before
+ anything that needs it.
+ [429ea065abf1]
+
+ * gram.y, parse.h:
+ Convert NEW_DEFAULT anf NEW_MEMBER into static functions.
+ [2f3433833589]
+
+ * match.c, parse.c, testsudoers.c:
+ Use LH_FOREACH_REV when checking permission and short-circuit on the
+ first non-UNSPEC hit we get for the command. This means that instead
+ of cycling through the all the parsed sudoers entries we start at
+ the end and work backwards and quit after the first positive or
+ negative match.
+ [881474532f3e]
+
+ * gram.c:
+ regen
+ [9152a19d4188]
+
+ * defaults.c, gram.y, parse.c, parse.h, testsudoers.c, visudo.c:
+ Change list head macros to take a pointer, not a struct.
+ [054f1dcce4cc]
+
+ * gram.c:
+ regen
+ [be154aae6235]
+
+ * gram.y:
+ Propagate the runasspec from one command to the next in a cmndspec.
+ [4957b1cb03a3]
+
+2007-08-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * match.c:
+ Replace has_meta() with a macro that calls strpbrk().
+ [a2e58846a542]
+
+ * regen
+ [5a932a5c9451]
+
+ * alias.c, defaults.c, gram.y, match.c, parse.c, parse.h,
+ testsudoers.c, visudo.c:
+ Use a list head struct when storing the semi-circular lists and
+ convert to tail queues in the process. This will allow us to reverse
+ foreach loops more easily and it makes it clearer which functions
+ expect a list as opposed to a single member.
+
+ Add macros for manipulating lists. Some of these should become
+ functions.
+
+ When freeing up a list, just pop off the last item in the queue
+ instead of going from head to tail. This is simpler since we don't
+ have to stash a pointer to the next member, we always just use the
+ last one in the queue until the queue is empty.
+
+ Rename match functions that take a list to have list in the name.
+ Break cmnd_matches() into cmnd_matches() and cmndlist_matches.
+ [7c37b271607a]
+
+ * parse.c:
+ Fix pasto, append "!" not negated (which is an int) for sudo -l
+ output.
+ [93a444c3997f]
+
+ * Makefile.in:
+ Remove the dependency of gram .h on gram.y, the .c dependency is
+ enough. Only move y.tab.h to gram.h if it is different; avoids
+ needless rebuilding.
+ [67bf4ea2a2e5]
+
+2007-08-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Defaults lines may be associated with lists of users, hosts,
+ commands and runas users, not just single entries.
+ [795effacb6be]
+
+2007-08-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Revert the "cmp" portion of the last diff, it doesn't make sense.
+ [26f34bf4e2e3]
+
+ * Makefile.in:
+ Remove *.lo for clean: When generating the parser, only move the
+ generated files into place if they differ from the existing ones.
+ [84673fea371b]
+
+2007-08-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * toke.c, toke.l:
+ Replace IPV6 regexp with a much simpler (readable) one and add an
+ extra check when it matches to make sure we have a valid address.
+ [592e9f690556]
+
+ * match.c:
+ Fix thinko introduced when merging IPV6 support.
+ [da38cd5eb8c7]
+
+2007-08-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * HISTORY, LICENSE:
+ regen
+ [0d7b27b90634]
+
+ * license.pod:
+ add 2007
+ [510e5048ae1a]
+
+ * UPGRADE:
+ mention #uid vs. comment pitfall
+ [4d2861898bcc]
+
+ * acsite.m4:
+ Merge in a patch from the libtool cvs that fixes a problem with the
+ latest autoconf. From Stepan Kasal.
+ [0c279ae7df3e]
+
+ * parse.h:
+ Back out he XOR swap trick, it is slower than a temp variable on
+ modern CPUs.
+ [91c4b024e317]
+
+ * gram.c:
+ regen
+ [cb6d4106fb74]
+
+ * gram.y, parse.h:
+ Convert the tail queue to a semi-circle queue and use the XOR swap
+ trick to swap the prev pointers during append.
+ [8bf4d9fbee58]
+
+2007-08-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.h:
+ remove useless statement
+ [421ec1dd73e6]
+
+ * toke.c, toke.l:
+ Refactor #include parsing into a separate function and return
+ unparsed chars (such as newline or comment) back to the lexer.
+ [64166917aa3d]
+
+2007-08-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * WHATSNEW:
+ mention better uid support
+ [56f510e7f2ec]
+
+ * sudoers.pod:
+ Users may now consist of a uid.
+ [5fd31b2c55ed]
+
+ * gram.c, gram.h, toke.c:
+ regen
+ [599e58af6dc1]
+
+ * parse.c:
+ Use lbuf_append_quoted() for sudo -l output to quote characters that
+ would require quoting in sudoers.
+ [3132d05c990a]
+
+ * lbuf.c, lbuf.h:
+ Add lbuf_append_quoted() which takes a set of characters which
+ should be quoted with a backslash when displayed.
+ [ab09bebb1d65]
+
+ * toke.l:
+ Require that the first character after a comment not be a digit or a
+ dash. This allows us to remove the GOTRUNAS state and treat uid/gids
+ similar to other words. It also means that we can now specify uids
+ in User_Lists and a User_Spec may now contain a uid.
+ [461fe01f8392]
+
+ * gram.y, toke.l:
+ Replace RUNAS token with '(' and ')' tokens to make the runas
+ portion of the grammar more natural.
+ [e0c383b4684d]
+
+ * BUGS:
+ The BUGS file is history
+ [4d9a809585c7]
+
+ * Makefile.in, README:
+ The BUGS file is history
+ [d9500e261172]
+
+2007-08-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * toke.c, toke.l:
+ Allow comments after a RunasAlias as long as the character after the
+ pound sign isn't a digit or a dash.
+ [d7f3bd94eeda]
+
+ * WHATSNEW:
+ Glob support was back-ported to 1.6.9
+ [d1d5cfd46228]
+
+2007-08-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ remove sudo_usage.h in distclean
+ [df05ce9c4127]
+
+ * parse.c:
+ If a Defaults value contains a blank, double-quote the string.
+ [9057a910daad]
+
+ * toke.c, toke.l:
+ Properly deal with Defaults double-quoted strings that span multiple
+ lines using the line continuation char. Previously, the entire
+ thing, including the continuation char, newline, and spaces was
+ stored as-is.
+ [4a4e8eacefe6]
+
+ * sudo.c:
+ Be consistent when using single quotes and backticks.
+ [d010b83a0fa1]
+
+2007-08-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, configure, configure.in, lbuf.c, lbuf.h, parse.c,
+ sudo.c, sudo_usage.h.in:
+ Add new linebuf code to do appends of dynamically allocated strings
+ and word-wrapped output. Currently used for sudo's usage() and sudo
+ -l output. Sudo usage strings are now in sudo_usage.h which is
+ generated at configure time.
+ [4dfd0ee8d961]
+
+2007-08-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c, sudo.c, sudo.h:
+ Fix line wrapping in usage() and use the actual tty width instead of
+ assuming 80.
+ [700eab37c5a6]
+
+2007-08-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * history.pod:
+ some more info
+ [8140112a8ae1]
+
+ * history.pod:
+ Mentioned Chris Jepeway's parser and also the new one that is in
+ sudo 1.7.
+ [2132d00f0597]
+
+2007-08-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod, visudo.pod:
+ For the options list, add flag args where appropriate and increase
+ the indent level so there is room for them.
+ [2b60fb572e12]
+
+2007-08-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ Fix some spacing in "sudo -l" and add a comment about some bogosity
+ in the line wrapping.
+ [b59b056f5ee2]
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in, visudo.cat,
+ visudo.man.in:
+ regen
+ [5fb719f18ebc]
+
+ * INSTALL, Makefile.in, WHATSNEW, config.h.in, configure.in,
+ def_data.c, def_data.h, def_data.in, gram.c, gram.h, gram.y,
+ parse.c, parse.h, pathnames.h.in, sudo.c, sudo.h, sudoers.pod,
+ testsudoers.c, toke.c, toke.l:
+ Remove monitor support until there is a versino of systrace that
+ uses a lookaside buffer (or we have a better mechanism to use).
+ [61ff76878e4a]
+
+ * config.h.in, configure, configure.in, sudo.c:
+ use getaddrinfo() instead of gethostbyname() if it is available
+ [cc33c136aa6a]
+
+2007-08-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c, sudo.c:
+ Deal with OSes where sizeof(gid_t) < sizeof(int).
+ [130a89cbdfba]
+
+ * interfaces.c:
+ repair non-getifaddrs() code after ipv6 integration
+ [7ae7a89e2236]
+
+ * sudo.c:
+ If we can open sudoers but fail to read the first byte, close the
+ file stream before trying again.
+ [6f31272fae7b]
+
+2007-08-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * toke.c:
+ regen
+ [4d7afe0aa6fa]
+
+ * gram.y, interfaces.c, interfaces.h, match.c, sudoers.pod, toke.l:
+ Add IPv6 support; adapted from patches by YOSHIFUJI Hideaki
+ [4e6ff2965a42]
+
+ * sudo.pod, sudoers.pod, visudo.pod:
+ Add some missing markup Update copyright
+ [7e6d3c686b5e]
+
+2007-08-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ fix sudo_noexec extension which got broken in the libtool update
+ [3a5b447df861]
+
+2007-08-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ explicitly specify -Tascii to nroff
+ [45c8da4cbefe]
+
+2007-08-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ remove an ANSI-ism that crept in
+ [29086f87b2ca]
+
+2007-08-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod:
+ Adjust list indents Prevent -- from being turned into an em dash Use
+ a list for the environment instead of a literal paragraph
+ [c3abcd8f76f4]
+
+ * visudo.pod:
+ Use a list for the environment instead of an indented literal
+ paragraph.
+ [0ffcfcb7349f]
+
+ * sudoers.pod:
+ Adjust list indentation
+ [615c89e3123a]
+
+ * license.pod:
+ add =head3
+ [8b2e0d38c0bd]
+
+2007-08-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod:
+ mention that when specifying a uid for the -u option the shell may
+ require that the # be escaped
+ [3e3a17bff150]
+
+2007-08-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * match.c:
+ Fix off by one in group matching.
+ [b529602b7fba]
+
+2007-07-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ Fix typo: PYTHONINSPEC should be PYTHONINSPECT. From David Krause.
+ [ffbf8907c6e7]
+
+2007-07-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Add missing define of HAVE_GSS_KRB5_CCACHE_NAME for the
+ -lgssapi_krb5 case.
+ [2b85a89c2252]
+
+ * aclocal.m4, configure, configure.in:
+ Fix link tests such that new gcc doesn't optimize away the test.
+ [83484ec95cba]
+
+2007-07-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod, sudoers.pod, visudo.pod:
+ add missing over/back
+ [251a12c89b91]
+
+ * sudo.pod, sudoers.pod, visudo.pod:
+ Change FILES section to use =item
+ [60b9efc3a0b2]
+
+ * env.c:
+ Add back allocation of the env struct in rebuild_env but save a copy
+ of the old pointer and free it before returning.
+ [1100cd4fa997]
+
+ * env.c:
+ Don't init the private environment in rebuild_env() since it may
+ have already been done implicitly sudo_setenv/sudo_unsetenv.
+
+ Multiply length by sizeof(char *) in memcpy/memmove when copying the
+ environment so we copy the full thing.
+
+ Add missing set of parens so we deref the right pointer in
+ sudo_unsetenv when searching for a matching variable.
+ [9086a8f756b1]
+
+2007-07-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod, sudoers.pod, visudo.pod:
+ Use file markup for paths in the FILES section
+ [940d99f731f2]
+
+ * sudo.pod, sudoers.pod, visudo.pod:
+ Don't capitalize sudo/visudo
+ [f067a455d44b]
+
+ * sudoers.pod:
+ Sort sudoers options; based on a diff from Igor Sobrado.
+ [a9b9befe85ac]
+
+2007-07-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod, sudoers.pod, visudo.pod:
+ Use 8 and 5 instead of @mansectsu@ and @mansectform@ since the
+ latter confuses pod2man. The Makefile rules for the .man.in file
+ will add @mansectsu@ and @mansectform@ back in after pod2man is done
+ anyway.
+ [b50ea0db727c]
+
+2007-07-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * LICENSE, Makefile.in, license.pod:
+ Move license info to pod format
+ [25bdd82e592b]
+
+ * configure, configure.in, sudoers.pod:
+ Substitute value of path_info into sudoers man page.
+ [9ba661a82798]
+
+ * WHATSNEW:
+ remove features that were back-ported to 1.6.9
+ [e76d756cbe65]
+
+ * sudo.c, sudo.pod, visudo.c, visudo.pod:
+ Sort SYNOPSIS and sync usage. From Igor Sobrado.
+ [4970386c9e54]
+
+ * env.c:
+ Only need sudo_setenv/sudo_unsetenv if we are going to use
+ ldap_sasl_interactive_bind_s() but don't have
+ gss_krb5_ccache_name().
+ [f1a73d8b35c5]
+
+ * ChangeLog:
+ rebuild without branch info
+ [5d5a33494677]
+
+ * Makefile.in:
+ Add ChangeLog target
+ [a702034fdd89]
+
+ * auth/pam.c:
+ Run cleanup code if the user hits ^C at the password prompt.
+ [9cf87768e921]
+
+ * auth/pam.c:
+ Some versions of pam_lastlog have a bug that will cause a crash if
+ PAM_TTY is not set so if there is no tty, set PAM_TTY to the empty
+ string.
+ [5b63f6c88866]
+
+2007-07-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ ChageLog not Changelog
+ [1243d8473ceb]
+
+ * ChangeLog:
+ sync
+ [d887df98c6b0]
+
+ * Makefile.in:
+ CHANGE -> Changelog
+ [917738df30dd]
+
+ * TODO:
+ sync
+ [cd382f7d1948]
+
+2007-07-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, ldap.c:
+ Add configure hooks for gss_krb5_ccache_name() and the gssapi
+ headers.
+ [139606209991]
+
+2007-07-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c, sudo.c:
+ rebuild_env() and insert_env_vars() no longer return environment
+ pointer, they set environ directly.
+
+ No longer need to pass around an envp pointer since we just operate
+ on environ now.
+
+ Add dosync argument to insert_env() that indicates whether it should
+ reset environ when realloc()ing env.envp.
+
+ Use an initial size of 128 for the environment.
+ [4735fd5fddb8]
+
+ * env.c:
+ Split sudo_setenv() into an external version and a version only for
+ use by rebuild_env().
+ [fda7d655adb1]
+
+2007-07-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Add support for using gss_krb5_ccache_name() instead of setting
+ KRB5CCNAME. Also use sudo_unsetenv() in the non-
+ gss_krb5_ccache_name() case if there was no KRB5CCNAME in the
+ original environment. TODO: configure setup for
+ gss_krb5_ccache_name()
+ [fcafa5a49caf]
+
+ * README.LDAP:
+ add krb5_ccname
+ [fceb8f883886]
+
+ * README.LDAP, ldap.c:
+ Add support for sasl_secprops in ldap.conf
+ [1f06f4bf7347]
+
+ * env.c, sudo.h:
+ Add sudo_unsetenv() and refactor private env syncing code into
+ sync_env().
+ [045ecb3fd22b]
+
+ * README.LDAP, ldap.c:
+ The ldap.conf variable is sasl_auth_id not sasl_authid.
+ [a5f98491311b]
+
+2007-07-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c, sudo.c, sudo.h:
+ Add support for krb5_ccname in ldap.conf. If specified, it will
+ override the default value of KRB5CCNAME in the environment for the
+ duration of the call to ldap_sasl_interactive_bind_s().
+ [b08a10c3045b]
+
+ * env.c, sudo.h:
+ Remove format_env() Add sudo_setenv() to replace most format_env() +
+ insert_env() combinations. insert_env() no longer takes a struct
+ environment *
+ [131da52f43f3]
+
+ * ldap.c:
+ Fix use_sasl vs. rootuse_sasl logic.
+ [0c0417b6918c]
+
+ * README.LDAP, config.h.in, configure, configure.in, ldap.c:
+ Add support for SASL auth when connecting to an LDAP server. Adapted
+ from a diff by Tom McLaughlin.
+ [a6285f1356ea]
+
+2007-07-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Only enable AIX or BSD auth if no other exclusive auth method has
+ been chosen. Allows people to e.g., use PAM on AIX without adding
+ --without-aixauth. A better solution is needed to deal with default
+ authentication since if a non-exclusive method is chosen we will
+ still get an error.
+ [83f7afdc0ec3]
+
+2007-07-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * HISTORY, Makefile.in, history.pod:
+ Generate HISTORY from history.pod (which is also used for web pages)
+ [60bcd5164931]
+
+2007-07-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.man.in, sudoers.man.in:
+ regen
+ [63956a366191]
+
+ * sudo.pod:
+ Better explanation of environment handling in the sudo man page.
+ [6c247742f7ee]
+
+ * env.c, sudo.c:
+ Defer setting user-specified env vars until after authentication.
+ [4750b79323ee]
+
+ * env.c:
+ honor def_default_path for PATH set on the command line
+ [6db31d9b6d65]
+
+ * env.c, sudo.c, sudo.pod, sudoers.pod:
+ Allow user to set environment variables on the command line as long
+ as they are allowed by env_keep and env_check. Ie: apply the same
+ restrictions as normal environment variables. TODO: deal with
+ secure_path
+ [26c0da3840cf]
+
+2007-07-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c, sudo_edit.c:
+ Call rebuild_env() in call cases. Pass original envp to sudo_edit().
+ Don't allow -E or env var setting in sudoedit mode. More accurate
+ usage() when called as sudoedit.
+ [a4af20658361]
+
+ * ldap.c:
+ warn -> warning
+ [d87d1192b048]
+
+ * sudo.pod:
+ add -c option to sudoedit synopsis
+ [15b596a7e2db]
+
+ * TODO:
+ udpate to reality
+ [e2f8fde89db1]
+
+ * parse.c:
+ Use ALLOW/DENY instead of TRUE/FALSE when dealing with the return
+ value from {user,host,runas,cmnd}_matches(). Rename *matches
+ variables -> *match. Purely cosmetic.
+ [e54a44c00a88]
+
+ * parse.c:
+ Move setting of FLAG_NO_CHECK into the if(pwflag) block. No change
+ in behavior.
+ [c6272b4f2127]
+
+ * sudoers:
+ add SETENV tag
+ [3a3066bb6788]
+
+2007-07-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ Make pwcheck local to the pwflag block. Use pwcheck even if user
+ didn't match since Defaults options may still apply.
+ [45da9efbbafd]
+
+ * check.c, sudo.c:
+ Do not update timestamp if user not validated by sudoers.
+ [a4a9d4364827]
+
+ * set_perms.c:
+ for PERM_RUNAS, set the egid to the runas user's gid and restore to
+ the user's original in PERM_ROOT
+ [1514bfb32847]
+
+ * logging.c, mon_systrace.c, set_perms.c, sudo.h:
+ PERM_FULL_ROOT is now no different than PERM_ROOT so remove
+ PERM_FULL_ROOT
+ [b9d047a3178c]
+
+ * check.c:
+ don't check timestamp mtime if we are just going to remove it
+ [5d2470bc6cbd]
+
+ * sudoers.pod:
+ Move sudoers defaults parameters into their own section.
+ [54701fbc0ff3]
+
+ * testsudoers.c:
+ Reduce a level of indent by a few placed continue statements.
+ [5d5a9838c8ef]
+
+ * parse.c:
+ Make matching but negated commands/hosts/runas entries override a
+ previous match as expected. Also reduce some levels of indent by a
+ few placed continue statements.
+ [dd59fa4b91a1]
+
+2007-07-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ Print default runas in "sudo -l" if sudoers don't specify one.
+ [07d408c400bd]
+
+ * match.c:
+ Less hacky way of testing whether the domain was set.
+ [a537059776e5]
+
+2007-07-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ Mention pam-devel and openldap-devel for Linux
+ [9e708c54ecc3]
+
+2007-07-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README.LDAP:
+ or vs. are
+ [abe8c0f3a410]
+
+2007-07-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ fix typo in Solaris project support
+ [2ffeb2d80959]
+
+ * HISTORY:
+ update
+ [df162b36f120]
+
+ * sudo.c:
+ Make -- on the command line match the manual page. The implied shell
+ case has been simplified as a result.
+ [cd217a1f6694]
+
+2007-06-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers2ldif:
+ add simplistic support for sudoRunas; note that if a sudoers entry
+ contains multiple Runas users, all will apply to the sudoRole
+ [65b11421f5c8]
+
+ * sudoers2ldif:
+ honor SETENV and NOSETENV tags
+ [2c0d5ba7a09b]
+
+2007-06-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mon_systrace.c:
+ Redo setting of user_args. We now build up a private copy of argv
+ first and then replace the NULs with spaces.
+ [ccbba72ea112]
+
+ * mon_systrace.c:
+ getcwd() returns NULL on failure, not 0 on success
+ [88cd9e66e530]
+
+ * mon_systrace.c:
+ allow chunksiz to reach 1 before erroring out
+ [619d68f14964]
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in, visudo.cat,
+ visudo.man.in:
+ regen
+ [8db512d3caf0]
+
+2007-06-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * def_data.c, def_data.h, def_data.in, env.c, gram.c, gram.h, gram.y,
+ logging.c, parse.c, parse.h, sudo.c, sudo.h, sudo.pod, sudoers.pod,
+ toke.c, toke.l:
+ Add support for setting environment variables on the command line.
+ This is only allowed if the setenv sudoers options is enabled or if
+ the command is prefixed with the SETENV tag.
+ [5744caebd969]
+
+ * README.LDAP:
+ replace Aaron's email address with the sudo-workers list
+ [2ffce5f9afc0]
+
+ * configure:
+ regen
+ [8013dff82c0c]
+
+2007-06-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * schema.OpenLDAP, schema.iPlanet:
+ Break schema out into separate files.
+ [15e598e4c60b]
+
+ * Makefile.in, README.LDAP:
+ Break schema out into separate files.
+ [1a53966ca1fa]
+
+2007-06-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/aix_auth.c:
+ free message if set by authenticate()
+ [849c220c1236]
+
+ * match.c:
+ deal with NULL gr_mem
+ [49e4d74f0bbe]
+
+2007-06-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ regen
+ [fead999ad3e9]
+
+ * configure.in:
+ add template for HAVE_PROJECT_H
+ [e6c42c2eaad1]
+
+ * closefrom.c:
+ include fcntl.h
+ [54d98b382f03]
+
+2007-06-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ mention --with-project
+ [d3ea3baad7c5]
+
+ * config.h.in, configure.in, sudo.c:
+ Add Solaris 10 "project" support. From Michael Brantley.
+ [f14f3c8c6554]
+
+ * sudoers.pod:
+ fix typo
+ [50db81a19787]
+
+ * configure:
+ regen
+ [ea71afd3e564]
+
+ * configure.in:
+ Fix preservation of LDFLAGS in the LDAP case.
+ [40a3a47e8059]
+
+ * memrchr.c:
+ Remove dependecy on NULL
+ [c957ae5e1733]
+
+ * configure:
+ regen
+ [4955ce0c6912]
+
+ * aclocal.m4, configure.in:
+ Can't use the regular autoconf fnmatch() check since we need
+ FNM_CASEFOLD so go back to our custom one.
+ [f10d76237486]
+
+ * env.c:
+ Fix preserving of variables in env_keep.
+ [d040049d6b84]
+
+ * env.c:
+ add XAUTHORIZATION
+ [0d589a5fe015]
+
+ * UPGRADE:
+ expand upon env resetting and mention that it began in 1.6.9 not
+ 1.7.
+ [dba251655c76]
+
+ * sudoers.pod:
+ Update descriptions of env_keep and env_check to match current
+ reality.
+ [dba77357954b]
+
+2007-06-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ Add LINGUAS to initial_checkenv_table. Add COLORS, HOSTNAME,
+ LS_COLORS, MAIL, PS1, PS2, XAUTHORITY to intial_keepenv_table.
+ [eec4632bd190]
+
+ * env.c, logging.c:
+ Treat USERNAME environemnt variable like LOGNAME/USER
+ [09f52dcfd70c]
+
+ * env.c:
+ Don't need to populate keepenv table with the contents of the
+ checkenv table.
+ [527a14afd973]
+
+ * sudo.c:
+ Don't force sudo into the C locale.
+ [8a5bd301ef96]
+
+ * env.c:
+ Make env_check apply when env_reset it true. Environment variables
+ are passed through unless they contain '/' or '%'. There is no need
+ to have a variable in both env_check and env_keep.
+ [840c802721e4]
+
+2007-06-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ Remove an duplicate lock_file() call and add a comment.
+ [5af9dcdf0eb6]
+
+ * UPGRADE:
+ Add sudo 1.6.9 upgrade note.
+ [1585149f2914]
+
+2007-06-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * interfaces.c:
+ Solaris will return EINVAL if the buffer used in SIOCGIFCONF is too
+ small. From Klaus Wagner.
+ [d6899fc44f77]
+
+ * logging.c, sudo.h:
+ Redo the long syslog line splitting based on a patch from Eygene
+ Ryabinkin. Include memrchr() for systems without it.
+ [66a50e8d553a]
+
+ * memrchr.c:
+ Redo the long syslog line splitting based on a patch from Eygene
+ Ryabinkin. Include memrchr() for systems without it.
+ [2f6702b7d41b]
+
+ * Makefile.in, config.h.in, configure, configure.in:
+ Redo the long syslog line splitting based on a patch from Eygene
+ Ryabinkin. Include memrchr() for systems without it.
+ [407a46190921]
+
+ * configure.in:
+ Since we need to be able to convert timespec to timeval for utimes()
+ the last 3 digits in the tv_nsec are not significant. This makes the
+ sudoedit file date comparison work again.
+ [9d0258849fa9]
+
+2007-06-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4, configure, configure.in:
+ Add SUDO_ADD_AUTH macro to deal with adding things to AUTH_OBJS.
+ This deals with exclusive authentication methods in a simple way.
+ [7d70072c0f35]
+
+2007-06-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * LICENSE:
+ mkstemp.c is BSD code too.
+ [29e236d98162]
+
+ * sudo.pod, sudoers.pod, visudo.pod:
+ No commercial support for now.
+ [7c76b3e192dd]
+
+2007-06-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ cleanenv() is no more.
+ [518080514408]
+
+2007-06-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ChangeLog:
+ Display branch info in Changelog
+ [44e3b27427c7]
+
+ * utimes.c:
+ Include config.h early so we have it for TIME_WITH_SYS_TIME
+ [4bf1a00d0703]
+
+ * ChangeLog:
+ Fix Changelog generation and update.
+ [6e960dbcbece]
+
+2007-06-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * closefrom.c:
+ Use /proc/self/fd instead of /proc/$$/fd
+
+ Move old-style fd closing into closefrom_fallback() and call that if
+ /proc/self/fd doesn't exist or the F_CLOSEM fcntl() fails
+ [faa7e4810758]
+
+ * auth/kerb5.c, config.h.in, configure.in:
+ o use krb5_verify_user() if available instead of doing it by hand o
+ use krb5_init_secure_context() if we have it o pass an encryption
+ type of 0 to krb5_kt_read_service_key() instead of
+ ENCTYPE_DES_CBC_MD5 to let kerberos choose.
+ [df7acf72bd7c]
+
+ * env.c:
+ Check TERM and COLORTERM for '%' and '/' characters. From Debian.
+ [f92d05197e40]
+
+ * configure.in:
+ Fix closefrom() substitution in the Makefile
+ [b642b13fcc5c]
+
+ * TROUBLESHOOTING:
+ Mention alternate sudo pronunciation.
+ [7c71dc73409f]
+
+2007-06-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ Remove KRB5_KTNAME from environment. Allow COLORTERM.
+ [70f35a79f780]
+
+ * auth/kerb5.c:
+ If we cannot get a valid service key using the default keytab it is
+ a fatal error. Fixes a bug where sudo could be tricked into allowing
+ access when it should not by a fake KDC. From Thor Lancelot Simon.
+ [a3ae6a47cb23]
+
+2007-05-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4, configure, configure.in:
+ Update long long checks to use AC_CHECK_TYPES and to cache values.
+ [047318eaaeb2]
+
+ * aclocal.m4, configure.in:
+ Use AC_FUNC_FNMATCH instead of a homebrew fnmatch checker. We can't
+ use AC_REPLACE_FNMATCH since that assumes replacing with GNU
+ fnmatch.
+ [80513a1003ea]
+
+2007-05-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Add closefrom() to LIB_OBJS not SUDO_OBJS if it is missing since we
+ need it for visudo now too.
+ [50837c7c2b5e]
+
+2007-04-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Attempt to clarify the bit talking about network numbers w/o
+ netmasks.
+ [211e68c1d034]
+
+ * sudo.pod:
+ Clarify timestamp dir ownership sentence.
+ [9178f132c7f7]
+
+2007-04-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c:
+ Linux PAM now defines __LINUX_PAM__, not __LIBPAM_VERSION. From
+ Dmitry V. Levin.
+ [81fce91667bc]
+
+2007-04-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ -i is also one of the mutually exclusive options to list it in the
+ warning message. Noted by Chris Pepper.
+ [7da73fb248e9]
+
+2007-04-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.pod:
+ The sudoers variable is env_editor, not enveditor. From Jean-
+ Francois Saucier.
+ [2a86ec09a6db]
+
+2007-03-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * redblack.c:
+ I tracked down the original author so credit him and include his
+ license info.
+ [3733553a1bba]
+
+2007-02-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man.in, sudo.pod, sudoers.cat, sudoers.man.in,
+ sudoers.pod:
+ Fix typos; from Jason McIntyre.
+ [1ee4ce2512f2]
+
+ * logging.c:
+ Restore signal mask before calling reapchild(). Fixes a possible
+ race condition that could prevent sudo from properly waiting for the
+ child.
+ [9ee4192385dc]
+
+2007-01-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pwutil.c:
+ Don't declare pw_free() if we are not going to use it.
+ [adb79a4289ca]
+
+ * env.c:
+ Add NOEXEC support for AIX 5.3 which supports LDR_PRELOAD and
+ LDR_PRELOAD64. The 64-bit version is not currently supported. Remove
+ zero_env() prototype as it no longer exists.
+ [b4fe65027fb6]
+
+2006-12-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ Add "Auto-Submitted: auto-generated" line to sudo mail for rfc 3834.
+ [78002ad90f7b]
+
+2006-09-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c:
+ If the user enters ^C at the password prompt, abort instead of
+ trying to authenticate with an empty password (which causes an
+ annoying delay).
+ [da3f27b747c7]
+
+2006-08-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * closefrom.c, config.h.in, configure, configure.in:
+ Add fcntl F_CLOSEM support to closefrom(); adapted from a diff by
+ Darren Tucker.
+ [0331b7780759]
+
+ * pwutil.c:
+ pw_free() is only used by sudo_freepwcache() so ifdef it out too.
+ [0014c0d9eeba]
+
+2006-08-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.guess, config.sub:
+ Update to latest versions from cvs.savannah.gnu.org
+ [aa0143101c20]
+
+2006-07-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pwutil.c, sudo_edit.c:
+ Move password/group cache cleaning out of sudo_end{pw,grp}ent() so
+ we can close the passwd/group files early.
+ [559074bd7eb7]
+
+ * config.h.in, configure, configure.in, set_perms.c:
+ Add seteuid() flavor of set_perms() for systems without setreuid()
+ or setresuid() that have a working seteuid(). Tested on Darwin.
+ [508d8da99189]
+
+2006-07-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mon_systrace.c:
+ systrace_read() returns ssize_t
+ [9f97d1d1a59d]
+
+ * configure, configure.in:
+ Fix typo, -lldap vs. -ldap; from Tim Knox.
+ [a8cc43c3bb2a]
+
+2006-07-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * HISTORY:
+ Fix typo; Matt Ackeret
+ [86964ee3dfbd]
+
+2006-07-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Print sudoers path in -V mode for root.
+ [dc43f2d75bd9]
+
+2006-06-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Do a sub tree search instead of a base search (one level in the tree
+ only) for sudo right objects. This allows system administrators to
+ categorize the rights in a tree to make them easier to manage.
+ [6d2d9abf996e]
+
+2005-12-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod:
+ fix typo
+ [1473413bcbda]
+
+2005-12-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Convert GET_OPT and GET_OPTI to use just 2 args. Add timelimit and
+ bind_timelimit support; adapted from gentoo.
+ [afc816093026]
+
+2005-11-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Support comments that start in the middle of a line
+ [c25df6ee3db8]
+
+ * configure, configure.in:
+ Define LDAP_DEPRECATED until we start using ldap_get_values_len()
+ [ee249bfe230a]
+
+2005-11-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * closefrom.c:
+ Silence gcc -Wsign-compare; djm@openbsd.org
+ [28769ce6418d]
+
+ * error.c, sudo.c, sudo.h, testsudoers.c, visudo.c:
+ cleanup() now takes an int as an arg so it can be used as a signal
+ handler too.
+ [2bb0df34d09c]
+
+ * sudo.c:
+ Make a copy of the shell field in the passwd struct for NewArgv to
+ avoid a use after free situation after sudo_endpwent() is called.
+ [5dcc9ffd362e]
+
+2005-11-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in:
+ Add mkstemp() for those poor souls without it.
+ [5fdd02e863e0]
+
+ * mkstemp.c:
+ Add mkstemp() for those poor souls without it.
+ [c99401207860]
+
+ * Makefile.in:
+ Add mkstemp() for those poor souls without it.
+ [9c1cf2678f24]
+
+2005-11-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ Add PERL5DB to list of environment variables to remove.
+ [7375c27ecf75]
+
+2005-11-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mon_systrace.c, mon_systrace.h:
+ Instead of calling the check function twice with a state cookie use
+ separate check/log functions.
+
+ Check more ioctl() calls for failure.
+
+ systrace_{read,write} now return the number of bytes read/written or
+ -1 on error.
+ [3dc8946d90e9]
+
+ * env.c:
+ Add more environment variables to remove; from gentoo linux Add some
+ comments about what bad env variables go to what (more to do)
+ [6918110a6b82]
+
+2005-11-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c, sudo_edit.c:
+ Move sudo_end{gr,pw}ent() until just before the exec since they free
+ up our cached copy of the passwd structs, including sudo_user and
+ sudo_runas. Fixes a use-after-free bug.
+ [54de3778bad0]
+
+ * visudo.c:
+ Close all fd's before executing editor.
+ [4fcc05e1bec8]
+
+ * sudo.c:
+ Enable malloc debugging on OpenBSD when SUDO_DEVEL is set.
+ [ef0e8ffa5c9f]
+
+ * check.c:
+ Fix fd leak when lecture file option is enabled. From Jerry Brown
+ [ce97f9207cd8]
+
+2005-11-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ Add PERLLIB, PERL5LIB and PERL5OPT to the default list of
+ environment variables to remove. From Charles Morris
+ [c96e1367d1c1]
+
+2005-11-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ add JAVA_TOOL_OPTIONS to initial_badenv_table for java 5
+ [72a6a1571226]
+
+2005-10-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ add PS4 and SHELLOPTS to initial_badenv_table for bash
+ [89dfb3f318f3]
+
+2005-08-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Fix typo; Toby Peterson
+ [b7a3222b23f4]
+
+2005-08-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tsgetgrpw.c:
+ Make return buffers static so they don't get clobbered
+ [13323a39b9f5]
+
+2005-07-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/securid5.c:
+ Fix securid5 authentication, was not checking for ACM_OK. Also add
+ default cases for the two switch()es. Problem noted by ccon at
+ worldbank
+ [14091e418333]
+
+2005-06-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Remove ncat() in favor of just counting bytes and pre-allocating
+ what is needed.
+ [25b8712adb61]
+
+2005-06-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Fix up some comments Add missing fclose() for the rootbinddn case
+ [ae95c8a89711]
+
+ * ldap.c:
+ align struct ldap_config
+ [35d0d64c76f8]
+
+ * ldap.c:
+ use LINE_MAX for max conf file line size
+ [da116cb8853d]
+
+ * pathnames.h.in:
+ add _PATH_LDAP_SECRET
+ [128b04ecfab7]
+
+ * README.LDAP:
+ Mention rootbinddn Give example ou=SUDOers container
+ [852edc69bd1c]
+
+2005-06-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, configure, configure.in, ldap.c:
+ Support rootbinddn in ldap.conf
+ [1615c91522a1]
+
+ * env.c, sudo.pod, sudoers.pod:
+ Preserve DISPLAY environment variable by default.
+ [05f503d5f438]
+
+ * acsite.m4, configure:
+ set need_lib_prefix=no for all cases; this is safe for LD_PRELOAD
+ [18a04dea8d05]
+
+ * acsite.m4, configure:
+ set need_version=no for all cases; this is safe for LD_PRELOAD
+ [b542560e1a73]
+
+ * aclocal.m4:
+ typo
+ [c040df0fcd5a]
+
+ * configure, configure.in:
+ Add dragonfly
+ [f13794618636]
+
+ * auth/pam.c:
+ Fix call to pam_end() when pam_open_session() fails.
+ [0be47cdfdef1]
+
+ * configure:
+ regen
+ [7f5c13b4b800]
+
+ * acsite.m4:
+ rebuild acsite.m4 from libtool 1.9f libtool.m4 ltoptions.m4
+ ltsugar.m4 ltversion.m4
+ [a7ba9fd1a2ab]
+
+ * config.guess, config.sub, ltmain.sh:
+ merge in local changes: config.guess: o better openbsd support
+ config.sub: o hiuxmpp support ltmain.sh o remove requirement that
+ libs must begin with "lib" o don't print a bunch of crap about
+ library installs o don't run ldconfig
+ [f4149f2c720f]
+
+ * config.guess, config.sub, ltmain.sh:
+ libtool 1.9f
+ [82a534e7121f]
+
+ * configure.in:
+ Update with autoupdate and make minor changes for libtool 1.9f
+ [11b5ae5c1428]
+
+2005-06-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ don't call sudo_ldap_display_cmnd if ldap not setup
+ [8bcf6c094ffe]
+
+ * sudo_edit.c, visudo.c:
+ Move declatation of struct timespec to its own include files for
+ systems without it since it needs time_t defined.
+ [b95c333299a0]
+
+ * gettime.c:
+ Move declatation of struct timespec to its own include files for
+ systems without it since it needs time_t defined.
+ [021b4569cc0c]
+
+ * fileops.c:
+ Move declatation of struct timespec to its own include files for
+ systems without it since it needs time_t defined.
+ [dd8573b2ee7d]
+
+ * emul/timespec.h:
+ Move declatation of struct timespec to its own include files for
+ systems without it since it needs time_t defined.
+ [f95137771564]
+
+ * check.c, compat.h:
+ Move declatation of struct timespec to its own include files for
+ systems without it since it needs time_t defined.
+ [2ef2ace8fe85]
+
+ * ldap.c:
+ Don't set safe_cmnd for the "sudo ALL" case.
+ [ad7fa9e07da0]
+
+2005-05-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c:
+ Call pam_open_session() and pam_close_session() to give pam_limits a
+ chance to run. Idea from Karel Zak.
+ [fed46d471350]
+
+2005-04-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c, sudo.c:
+ Add explicit cast from mode_t -> u_int in printf to silence warnings
+ on Solaris
+ [17bb961fe22d]
+
+ * parse.c:
+ include grp.h to silence a warning on Solaris
+ [14386fbab640]
+
+2005-04-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ Fix printing of += and -= defaults.
+ [a667604c56cd]
+
+2005-04-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mon_systrace.c:
+ Sanity check number of syscall args with argsize. Not really needed
+ but a little paranoia never hurts.
+ [6bb455a2c2d6]
+
+ * mon_systrace.c, mon_systrace.h:
+ Don't do pointer arithmetic on void * Use int, not size_t/ssize_t
+ for systrace lengths (since it uses int)
+ [3cafccffcffd]
+
+2005-04-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mon_systrace.c:
+ Add some memsets for paranoia Fix namespace collsion w/ error Check
+ rval of decode_args() and update_env() Remove improper setting of
+ validated variable
+ [3d385158354d]
+
+2005-04-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c, sudo.c, sudo.h:
+ In -l mode, only check local sudoers file if def_ignore_sudoers is
+ not set and call LDAP versions from display_privs() and
+ display_cmnd() instead of directly from main(). Because of this we
+ need to defer closing the ldap connection until after -l processing
+ has ocurred and we must pass in the ldap pointer to display_privs()
+ and display_cmnd().
+ [1dfc2e8c9f2b]
+
+ * ldap.c:
+ Reorganize LDAP code to better match normal sudoers parsing. Instead
+ of storing strings for later printing in -l mode we do another query
+ since the authenticating user and the user being listed may not be
+ the same (the new -U flag). Also add support for "sudo -l command".
+
+ There is still a fair bit if duplicated code that can probably be
+ refactored.
+ [e9568f19bde5]
+
+2005-04-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Replace pass variable with do_netgr for better readability.
+ [1bba841b6e79]
+
+ * ldap.c:
+ use DPRINTF macro
+ [02b159b66bb5]
+
+ * ldap.c:
+ estrdup, not strdup
+ [22cdee7973c1]
+
+2005-04-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ Add macro to test if the tag changed to improve readability.
+ [4e11b4819556]
+
+ * parse.c:
+ Avoid printing defaults header if there are no defaults to print...
+ [41a28627df03]
+
+ * glob.c:
+ Fix a warning on systems without strlcpy().
+ [6814e0f0e4f4]
+
+ * pwutil.c:
+ Use macros where possible for sudo_grdup() like sudo_pwdup().
+ [30f201ff35cd]
+
+2005-04-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * utimes.c:
+ It is possible for tv_usec to hold >= 1000000 usecs so add in
+ tv_usec / 1000000.
+ [794ac4d53a65]
+
+2005-03-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/kerb5.c:
+ The component in krb5_principal_get_comp_string() should be 1, not 0
+ for Heimdal. From Alex Plotnick.
+ [fefa351c5044]
+
+2005-03-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * alias.c, alloc.c, check.c, defaults.c, find_path.c, gram.c, gram.y,
+ interfaces.c, ldap.c, logging.c, match.c, mon_systrace.c, pwutil.c,
+ redblack.c, sudo.c, sudo.h, toke.c, toke.l, visudo.c:
+ Add efree() for consistency with emalloc() et al. Allows us to rely
+ on C89 behavior (free(NULL) is valid) even on K&R.
+ [7876bb80d87c]
+
+ * parse.c, sudo.c:
+ Move initgroups() for -U option into display_privs() so group
+ matching in sudoers works correctly.
+ [b074428ad2ca]
+
+2005-03-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Removed duplicate call to ldap_unbind_s introduced along with
+ sudo_ldap_close.
+ [19acc1c20f7c]
+
+ * parse.c:
+ Add missing space in Defaults printing
+ [95d2935bf6d4]
+
+2005-03-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pwutil.c:
+ Sync sudo_pwdup with OpenBSD changes: use macros for size computaton
+ and string copies.
+ [6b6b241495e5]
+
+2005-03-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pwutil.c:
+ Zero old pw_passwd before replacing with version from shadow file.
+ [3251b349dfe1]
+
+ * configure, configure.in:
+ Only attempt shadow password detection if PAM is not being used Add
+ shadow_* variables to make shadow password detection more generic.
+ [d498a3423ac9]
+
+ * configure.in:
+ Use OSDEFS for os-specific -D_FOO_BAR stuff rather than CPPFLAGS
+ [04d55bbd5e35]
+
+2005-03-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ use a non-breaking space to avoid a double space after e.g.
+ [11cdb54bdf7b]
+
+ * sudo.pod:
+ commna, not colon after e.g.
+ [8d5875ff72e0]
+
+2005-03-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo_noexec.c:
+ Add __ variants of the exec functions. GNU libc at least uses
+ __execve() internally.
+ [d1880473d790]
+
+ * indent.pro:
+ Match reality a bit more.
+ [633e3fa875a7]
+
+ * pwutil.c:
+ Missed piece from rev. 1.6, fix sudo_getpwnam() too.
+ [128f7b21c2ee]
+
+ * pwutil.c:
+ Store shadow password after making a local copy of struct passwd in
+ case normal and shadow routines use the same internal buffer in
+ libc.
+ [f806052a6ffc]
+
+2005-03-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * alloc.c, logging.c:
+ Make varargs usage consistent with the rest of the code.
+ [3d45affc9851]
+
+2005-03-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo_noexec.c:
+ Wrap more of the exec family since on Linux the others do not appear
+ to go through the normal execve() path.
+ [8167769b4e19]
+
+ * visudo.c:
+ make print_unused static like proto says
+ [ecf10e1bae55]
+
+ * glob.c:
+ silence a warning on K&R systems
+ [2e00425f1a5c]
+
+ * alias.c, error.c:
+ make this build in K&R land
+ [156f65f8525a]
+
+ * parse.c:
+ make this build in K&R land
+ [6fc9276889cb]
+
+2005-03-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * toke.c:
+ regen
+ [3b349748cd21]
+
+2005-03-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ return(foo) not return foo optimize _atobool() slightly
+ [11d09d154ed5]
+
+ * ldap.c:
+ Use TRUE/FALSE
+ [53999320d98f]
+
+ * ldap.c:
+ Reformat to match the rest of sudo's code.
+ [1bd0f2afa0e7]
+
+ * sudo.pod:
+ I am the primary author
+ [5d311ecd85c6]
+
+2005-02-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, README, RUNSON:
+ The RUNSON file is toast--it confused too many people and really
+ isn't needed in a configure-oriented world.
+ [96a6ef7bbc08]
+
+ * INSTALL:
+ alternate -> alternative
+ [b65015c5d0a2]
+
+ * tgetpass.c:
+ Use TCSADRAIN instead of TCSAFLUSH since some OSes have issues with
+ TCSAFLUSH.
+ [c66b4763ffdc]
+
+ * toke.l:
+ Allow leading blanks before Defaults and Foo_Alias definitions
+ [2add513d9277]
+
+ * Makefile.in:
+ fix rules to build toke.o and gram.o in devel mode
+ [96cbb414ebd3]
+
+2005-02-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ env_keep overrides set_logname
+ [401877193a15]
+
+ * env.c:
+ Fix disabling set_logname and make env_keep override set_logname.
+ [0906e7a5ed93]
+
+ * compat.h, config.h.in, configure, configure.in:
+ No longer need memmove()
+ [43bdb6efe3f2]
+
+ * env.c, sudo.c:
+ Just clean the environment once. This assumes that any further
+ setenv/putenv will be able to handle the fact that we replaced
+ environ with our own malloc'd copy but all the implementations I've
+ checked do.
+ [11658fe92ba2]
+
+2005-02-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c, sudo.c:
+ In -i mode, base the value of insert_env()'s dupcheck flag on
+ DID_FOO flags. Move checks for $HOME resetting into rebuild_env()
+ [8365b0bd0c71]
+
+2005-02-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c, sudo.c:
+ Move setting of user_path, user_shell, user_prompt and prev_user
+ into init_vars() since user_shell at least is needed there.
+ [37e22dce66e9]
+
+2005-02-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ fix devel builds
+ [9fbb15ef164c]
+
+ * sudo.c:
+ Fix some printf format mismatches on error.
+ [ffc1c3f11740]
+
+ * check.c:
+ Fix some printf format mismatches on error.
+ [7b3b508adf50]
+
+ * configure, gram.c, toke.c:
+ regen
+ [aa76f9d8b02a]
+
+ * Makefile.in, aclocal.m4, alias.c, alloc.c, auth/afs.c,
+ auth/aix_auth.c, auth/bsdauth.c, auth/dce.c, auth/fwtk.c,
+ auth/kerb4.c, auth/kerb5.c, auth/pam.c, auth/passwd.c,
+ auth/rfc1938.c, auth/secureware.c, auth/securid.c, auth/securid5.c,
+ auth/sia.c, auth/sudo_auth.c, auth/sudo_auth.h, check.c,
+ closefrom.c, compat.h, configure.in, defaults.c, defaults.h,
+ emul/utime.h, env.c, error.c, fileops.c, find_path.c, getprogname.c,
+ getspwuid.c, gettime.c, goodpath.c, gram.y, interfaces.c,
+ interfaces.h, ldap.c, logging.c, logging.h, match.c, mon_systrace.c,
+ parse.c, redblack.c, redblack.h, set_perms.c, sigaction.c,
+ snprintf.c, strcasecmp.c, strerror.c, strlcat.c, strlcpy.c, sudo.c,
+ sudo.h, sudo.pod, sudo_edit.c, sudo_noexec.c, sudoers.pod,
+ testsudoers.c, tgetpass.c, toke.l, utimes.c, version.h, visudo.c,
+ visudo.pod, zero_bytes.c:
+ Update copyright years.
+ [0610c3654739]
+
+ * Makefile.binary.in:
+ Update copyright years.
+ [d78ffc9f2e2b]
+
+ * LICENSE:
+ Update copyright years.
+ [f60473bca4b1]
+
+ * BUGS, INSTALL, INSTALL.binary, Makefile.in, README, configure.in:
+ version 1.7
+ [aa977a544ca1]
+
+ * WHATSNEW:
+ What's new in sudo 1.7, based on the 1.7 CHANGES entries.
+ [ecfcf7269c14]
+
+2005-02-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat.h, logging.h, sudo.h:
+ Add __printflike and use it with gcc to warn about printf-like
+ format mismatches
+ [b192ad4a0548]
+
+2005-02-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, ChangeLog:
+ Replaced CHANGES file with ChangeLog generated from cvs logs
+ [d9ace9dab98f]
+
+ * set_perms.c:
+ Use warning/error instead of perror/fatal.
+ [e33259df7738]
+
+ * config.guess:
+ Update OpenBSD section
+ [9d2c23de6801]
+
+ * UPGRADE:
+ Add upgrading noted for 1.7
+ [1fb6b6d6df07]
+
+ * env.c, sudo.c, sudoers.pod:
+ Instead of zeroing out the environment, just prune out entries based
+ on the env_delete and env_check lists. Base building up the new
+ environment on the current environment and the variables we removed
+ initially.
+ [fc192df8fd15]
+
+ * config.h.in, configure, configure.in, sudo.c:
+ Set locale to "C" if locales are supported, just to be safe.
+ [91fbaa98f02e]
+
+ * toke.c, toke.l:
+ Cast argument to ctype functions to unsigned char.
+ [e096b4d65796]
+
+2005-02-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ correct value for DID_USER
+ [b5b05d36ec15]
+
+ * error.c, fnmatch.c, getcwd.c, glob.c, snprintf.c:
+ #include <compat.h> not "compat.h"
+ [7a0ad9a0ccd7]
+
+ * defaults.c:
+ Reset the environment by default.
+ [4ecc6423e0f0]
+
+ * sudo.c:
+ Alloc an extra slot in NewArgv. Removes the need to malloc an new
+ vector if execve() fails.
+ [83dfb6f584a7]
+
+2005-02-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, config.h.in, configure, configure.in, sudo.c:
+ Use execve(2) and wrap the command in sh if we get ENOEXEC.
+ [c0c6af4e2a21]
+
+2005-02-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo_noexec.c:
+ Only include time.h on systems that lack struct timespec which gets
+ defind in compat.h (using time_t).
+ [e373e518b4cb]
+
+ * sudo_noexec.c:
+ Include time.h for time_t in compat.h for systems w/o struct
+ timespec.
+ [a34b5637e458]
+
+ * compat.h, config.h.in, configure, configure.in:
+ use bcopy on systems w/o memmove
+ [f835eafd78c6]
+
+ * compat.h:
+ __attribute__((__unused__)) doesn't work in gcc 2.7.2.1 so limit its
+ use to gcc >= 2.8.
+ [1cb9a4e58566]
+
+ * Makefile.in:
+ Add explicit rule to build sudo_noexec.lo
+ [df1dfcf8dd77]
+
+2005-02-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL.configure, Makefile.in:
+ No longer depend on VPATH; pointed out a bunch of missed
+ dependencies.
+ [601a45d4af6b]
+
+ * TROUBLESHOOTING:
+ Help for PAM when account section is missing
+ [9b8221256756]
+
+ * auth/pam.c:
+ Give user a clue when there is a missing "account" section in the
+ PAM config.
+ [2529625c0495]
+
+ * auth/pam.c:
+ Better error handling.
+ [518c9bda23d8]
+
+ * config.h.in, configure, configure.in:
+ Move _FOO_SOURCE to CPPFLAGS so it takes effect as early as
+ possible. Silences a warning about isblank() on linux.
+ [19c94d7ecdc8]
+
+ * auth/pam.c:
+ Fix typo (missing comma) that caused an incorrect number of args to
+ be passed to log_error().
+ [0099dfec560f]
+
+2005-02-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pwutil.c:
+ Don't try to destroy a tree we didn't create.
+ [d43c4fe03aa4]
+
+2005-01-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * alias.c, alloc.c, auth/afs.c, auth/aix_auth.c, auth/bsdauth.c,
+ auth/dce.c, auth/fwtk.c, auth/kerb4.c, auth/kerb5.c, auth/pam.c,
+ auth/passwd.c, auth/rfc1938.c, auth/secureware.c, auth/securid.c,
+ auth/securid5.c, auth/sia.c, auth/sudo_auth.c, check.c, closefrom.c,
+ compat.h, defaults.c, env.c, error.c, fileops.c, find_path.c,
+ fnmatch.c, getcwd.c, getprogname.c, getspwuid.c, gettime.c,
+ goodpath.c, gram.c, gram.y, interfaces.c, ldap.c, logging.c,
+ match.c, mon_systrace.c, parse.c, pwutil.c, set_perms.c,
+ sigaction.c, snprintf.c, strcasecmp.c, strerror.c, strlcat.c,
+ strlcpy.c, sudo.c, sudo_edit.c, sudo_noexec.c, testsudoers.c,
+ tgetpass.c, toke.c, toke.l, utimes.c, visudo.c, zero_bytes.c:
+ Add __unused to rcsids
+ [ad6b4ac45705]
+
+2005-01-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Fix error message when mixing invalid auth types
+ [68069b3ff5bc]
+
+ * INSTALL:
+ PAM, AIX auth, BSD auth and login_cap are now on by default if the
+ OS supports them.
+ [4e44e9098cf0]
+
+ * auth/sudo_auth.h, config.h.in:
+ s/HAVE_AUTHENTICATE/HAVE_AIXAUTH/g
+ [2d569b43b23e]
+
+ * configure.in:
+ Better checking for conflicting authentication methods Display the
+ authentication methods used at the end of configure Rename --with-
+ authenticate -> --with-aixauth Use --with-aixauth, --with-bsdauth,
+ --with-pam, --with-logincap by default on systems that support them
+ unless disabled. Add OSMAJOR variable that replaces old OSREV; now
+ OSREV has full version number
+ [a21115b6fe9f]
+
+2005-01-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * def_data.c, def_data.in, sudo.c, sudoers.pod:
+ s/-O/-C/
+ [ee73f1b81923]
+
+2005-01-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ Replace: test -n "$FOO" || FOO="bar"
+
+ With: : ${FOO='bar'}
+ [37552d9054fc]
+
+2005-01-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * pwutil.c, testsudoers.c, tsgetgrpw.c:
+ Use function pointers to only call private passwd/group routines
+ when using a nonstandard passwd/group file.
+ [215908681dfb]
+
+2005-01-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ sync
+ [2e55c03f5790]
+
+ * tsgetgrpw.c:
+ Can't use strtok() since it doesn't handle empty fields so add
+ getpwent()/getgrent() functions and call those.
+ [bdaa5b0db70e]
+
+2005-01-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Fix dummied out toke.c and gram.c dependencies.
+ [4b909c8b2ebe]
+
+ * Makefile.in:
+ Rename PARSESRCS -> GENERATED since it is only used in the clean
+ target Add devdir variable and use it to specify the path to parser
+ sources
+ [f27b3f41ca23]
+
+ * configure:
+ regen
+ [22c6435dbd46]
+
+ * configure.in:
+ Add a devdir variables that defaults to $(srcdir) and is set to . if
+ --devel was specified. Allows for proper dependecies building the
+ parser.
+ [a36d694c6d21]
+
+ * testsudoers.c:
+ Add support for custom passwd/group files.
+ [296549ff4b87]
+
+ * Makefile.in:
+ Build private copy of pwutil.o for testsudoers with MYPW defined so
+ it uses our own passwd/group routines.
+ [bafa54ec78ca]
+
+ * visudo.c:
+ Remove sudo_*{pw,gr}* stubs and add sudo_setspent/sudo_endspent
+ stubs instead. We can now just use the caching sudo_*{pw,gr}*
+ functions in pwutil.c Add comment about wanting to call
+ sudo_endpwent/sudo_endgrent in cleanup()
+ [7e59d6b5510d]
+
+ * tsgetgrpw.c:
+ Remove caching; we will just use what is in pwutil.c Use global
+ buffers for passwd/group structs Rename functions from sudo_* to
+ my_*
+ [8c1e068f574c]
+
+ * logging.c, sudo.c:
+ g/c pwcache_init/pwcache_destroy
+ [60a24909b947]
+
+ * sudo.h:
+ Undo last commit and add sudo_setspent and sudo_endspent instead.
+ [bac80db08296]
+
+ * getspwuid.c, pwutil.c:
+ Move all but the shadow stuff from getspwuid.c to pwutil.c and
+ pwcache_get and pwcache_put as they are no longer needed. Also add
+ preprocessor magic to use private versions of the passwd and group
+ routines if MYPW is defined (for use by testsudoers).
+ [a16b8678a426]
+
+ * tsgetgrpw.c:
+ zero out struct passwd/group before filling it in so if there are
+ fields we don't handle they end up as 0.
+ [274cb6a93301]
+
+ * logging.c, sudo.c, sudo.h, testsudoers.c, visudo.c:
+ Adapt to pwutil.c
+ [43ebd04c8b82]
+
+ * Makefile.in:
+ Add tsgetgrpw.c and pwutil.c Rename the *OBJ variables for better
+ readability.
+ [7f88c6061e2d]
+
+ * tsgetgrpw.c:
+ Passwd and group lookup routines for testsudoers that support
+ alternate passwd and group files.
+ [d7803101d34e]
+
+ * getspwuid.c, pwutil.c:
+ Split off pw/gr cache and dup code into its own file. This allows
+ visudo and testsudoers to use the pw/gr cache too.
+ [ef333d3ffedf]
+
+2005-01-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ Print Defaults info in "sudo -l" output and wrap lines based on the
+ terminal width.
+ [e559eae4250e]
+
+2005-01-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * match.c, testsudoers.c, visudo.c:
+ Only check group vector in usergr_matches() if we are matching the
+ invoking or list user. Always check the group members, even if there
+ was a group vector.
+ [d0c7ceb2a041]
+
+2004-12-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * LICENSE, Makefile.in, fnmatch.3:
+ No longer bundle fnmatch.3
+ [72db4a4ff4e1]
+
+ * CHANGES, TODO:
+ checkpoint
+ [e92781bfd99c]
+
+2004-12-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ sort usage
+ [15e3b876ec2c]
+
+ * sudo.pod:
+ Sort command line options
+ [c1fa56584bc4]
+
+ * def_data.c, def_data.h, def_data.in, defaults.c, logging.c, sudo.c,
+ sudo.pod, sudoers.pod:
+ Add closefrom sudoers option to start closing at a point other than
+ 3. Add closefrom_override sudoers option and -C sudo flag to allow
+ the user to specify a different closefrom starting point.
+ [370652b099d1]
+
+ * pathnames.h.in:
+ Add _PATH_DEVNULL for those without it.
+ [0c4c3e0ceb8b]
+
+ * LICENSE:
+ no more UCB strcasecmp
+ [397a6298e07f]
+
+ * strcasecmp.c:
+ replace BSD licensed one with version derived from pdksh
+ [d7cfda8c57a2]
+
+2004-12-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Fix last commit.
+ [7afb9a180532]
+
+ * sudo.c:
+ Make sure stdin, stdout and stderr are open and dup them to
+ /dev/null if not.
+ [590f387068bd]
+
+2004-12-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c, mon_systrace.c, sudo.c, sudo.h:
+ add sudo_ldap_close
+ [4273a36765a7]
+
+ * fileops.c, gettime.c, sudo.c, sudo_edit.c, utimes.c, visudo.c:
+ Use TIME_WITH_SYS_TIME
+ [c32b59bf15fb]
+
+ * config.h.in, configure, configure.in:
+ Add TIME_WITH_SYS_TIME_H
+ [57cb146f451d]
+
+2004-12-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ Add missing braces to avoid DYLD_FORCE_FLAT_NAMESPACE being set
+ unconditionally on darwin. From Toby Peterson.
+ [d69959681c87]
+
+ * getspwuid.c:
+ Check rbinsert() return value. In the case of faked up entries there
+ is usually a negative response cached that we need to overwrite.
+
+ In pwfree() don't try to zero out a NULL pw_passwd pointer.
+ [00b32d1a48c1]
+
+ * mon_systrace.c:
+ Use the double fork trick to avoid the monitor process being waited
+ for by the main program run through sudo.
+ [e0ce556712ff]
+
+2004-11-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Call initgroups() in -U mode so group matches work normally.
+ [2235bea15283]
+
+ * def_data.h, mkdefaults:
+ Don't print a trailing comma for the last entry in enum def_tupple
+ [c43a96bb31df]
+
+2004-11-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.cat, sudoers.man.in, sudoers.pod:
+ Mention values when lecture, listpw and verifypw are used in boolean
+ context.
+ [a0b5c0abaccf]
+
+ * def_data.c, def_data.in:
+ verifypw when used in a boolean TRUE context should be "all", not
+ "any".
+ [2eb076ddd5e2]
+
+2004-11-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * def_data.in, defaults.c:
+ Allow tuples that can be used as booleans to be used as boolean
+ TRUE. In this case the 2nd possible value of the tuple is used for
+ TRUE.
+ [bd99aa77e88b]
+
+2004-11-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Correct the test for 2-parameter timespecsub
+ [d41c9cb26b97]
+
+ * sudo.h:
+ Add strub struct definitions for passwd, timeval and timespec
+ [c4ce5c43d8c5]
+
+ * config.h.in, configure, configure.in, sudo_edit.c, visudo.c:
+ Add check for 2-argument form of timespecsub (FreeBSD and BSD/OS)
+ and fix a typo in the gettimeofday check.
+ [8ac9893057ce]
+
+2004-11-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * match.c, testsudoers.c:
+ Deal with user_stat being NULL as it is for visudo and testsudoers.
+ [3605a6ff64d0]
+
+ * parse.c, sudo.c, sudo.cat, sudo.h, sudo.man.in, sudo.pod:
+ Add -U option to use in conjunction with -l instead of -u. Add
+ support for "sudo -l command" to test a specific command.
+ [99638789d415]
+
+ * gram.c, gram.y, sudo.c:
+ Set safe_cmnd after sudoers_lookup() if it has not been set.
+ Previously it was set by sudo "ALL" in the parser but at that point
+ the fully-qualified pathname has not yet been found.
+ [ac30d98f8225]
+
+2004-11-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c, testsudoers.c:
+ Correctly handle multiple privileges per userspec and runas
+ inheritence.
+ [a98a965181af]
+
+2004-11-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * defaults.c:
+ Zero out sd_un for each entry in sudo_defs_table in init_defaults.
+ [031d3cd4a848]
+
+2004-11-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * toke.c, toke.l:
+ make per-command defaults work with sudoedit
+ [e56fe33db916]
+
+ * ldap.c, parse.c, sudo.c, sudo.h:
+ Remove the FLAG_NOPASS, FLAG_NOEXEC and FLAG_MONITOR flags. Instead,
+ we just set the approriate defaults variable.
+ [756eeecc1d86]
+
+ * sample.sudoers, sudoers.cat, sudoers.man.in, sudoers.pod:
+ Document per-command Defaults.
+ [92a0f84b91c1]
+
+ * defaults.c, defaults.h, gram.c, gram.h, gram.y, mon_systrace.c,
+ sudo.c, testsudoers.c, toke.c, toke.l, visudo.c:
+ Add support for command-specific Defaults entries. E.g.
+ Defaults!/usr/bin/vi noexec
+ [be3d52bf01cf]
+
+ * defaults.c, match.c, parse.c, parse.h, testsudoers.c:
+ Change an occurence of user_matches() -> runas_matches() missed
+ previously runas_matches(), host_matches() and cmnd_matches() only
+ really need to pass in a list of members. user_matches() still needs
+ to pass in a passwd struct because of "sudo -l"
+ [833b22fc6fa0]
+
+ * parse.c:
+ Check def_authenticate, def_noexec and def_monitor when setting
+ return flags. XXX May be better to just set the defaults directly
+ and get rid of those flags.
+ [b6db22b59d69]
+
+ * alias.c, alloc.c, auth/afs.c, auth/aix_auth.c, auth/bsdauth.c,
+ auth/dce.c, auth/fwtk.c, auth/kerb4.c, auth/kerb5.c, auth/pam.c,
+ auth/passwd.c, auth/rfc1938.c, auth/secureware.c, auth/securid.c,
+ auth/securid5.c, auth/sia.c, auth/sudo_auth.c, check.c, closefrom.c,
+ defaults.c, env.c, error.c, fileops.c, find_path.c, fnmatch.c,
+ getcwd.c, getprogname.c, getspwuid.c, gettime.c, glob.c, goodpath.c,
+ gram.c, gram.y, interfaces.c, ldap.c, logging.c, match.c,
+ mon_systrace.c, parse.c, redblack.c, set_perms.c, snprintf.c,
+ strcasecmp.c, strerror.c, strlcat.c, strlcpy.c, sudo.c, sudo_edit.c,
+ sudo_noexec.c, testsudoers.c, tgetpass.c, toke.c, toke.l, utimes.c,
+ visudo.c, zero_bytes.c:
+ Use: #include <config.h> Not: #include "config.h" That way we get
+ the correct config.h when build dir != src dir
+ [97e5670a442b]
+
+ * Makefile.in:
+ Back out part of rev 1.263; fix -I order
+ [197ea01cad5d]
+
+ * toke.c, toke.l:
+ More robust parsing if #include; could be much better still.
+ [31bc3cd8f045]
+
+ * sudo_edit.c, visudo.c:
+ Make arg splitting in visudo and sudoedit consistent.
+ [7bc74485f246]
+
+ * Makefile.in, alias.c, gram.c, gram.y, parse.h:
+ Split alias routines out into their own file.
+ [d90f633cf9ae]
+
+ * error.h:
+ __attribute__ is already defined in compat.h
+ [676ed3fe9203]
+
+ * visudo.c:
+ quit() should not be __noreturn__ as it is non-void on some
+ platforms.
+ [e528c2b6ba10]
+
+ * auth/fwtk.c, auth/rfc1938.c, auth/securid.c, auth/securid5.c:
+ Add local error/warning functions like err/warn but that call an
+ additional cleanup routine in the error case. This means we no
+ longer need to compile a special version of alloc.o for visudo.
+ [e78e8aae882e]
+
+ * parse.h:
+ Clarify comments about the data structures
+ [ae894e266701]
+
+2004-11-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ Add support for VISUAL and EDITOR containing command line args. If
+ env_editor is not set any args in VISUAL and EDITOR are ignored.
+ Arguments are also now supported in def_editor.
+ [ff7303b8e298]
+
+2004-11-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.h:
+ alias_matches() is no more
+ [b59825e28084]
+
+ * CHANGES, TODO:
+ sync
+ [2b8f5f63c1de]
+
+ * Makefile.in:
+ When regenerating the parser, don't replace gram.h unless it has
+ changed.
+ [819949668018]
+
+ * Makefile.in:
+ remove Makefile.binary for distclean
+ [351eec8d00b2]
+
+ * env.c:
+ Preserve KRB5CCNAME in zero_env() and add a paranoia check to make
+ sure we can't overflow new_env.
+ [3284d17b9c6d]
+
+ * sudo_edit.c:
+ paranoia when stripping trailing slashes from tempdir.
+ [012f1aa2b81f]
+
+ * sudo.c:
+ Set user_ngroups to 0 if getgroups() returns an error.
+ [c46d43e9449a]
+
+2004-11-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, sudo.c:
+ Add configure check for getgroups()
+ [5d8a214e2cef]
+
+ * ldap.c:
+ Use supplementary group vector in struct sudo_user.
+ [3d0c463c034d]
+
+ * match.c:
+ Only do string comparisons on the group members if there is no
+ supplemental group list.
+ [be1c8362f7ef]
+
+ * CHANGES, TODO:
+ sync
+ [db188bc5b975]
+
+ * sudo_edit.c:
+ On Digital UNIX _PATH_VAR_TMP doesn't end with a trailing slash so
+ chop off any trailing slashes we see and add an explicit one.
+ [e1b477dafee1]
+
+ * match.c:
+ remove bogus XXX comment
+ [8aecb8a28d40]
+
+ * match.c:
+ Get rid of alias_matches and correctly fall through to the non-alias
+ cases when there is no alias with the specified name.
+ [2cd555246f09]
+
+ * getspwuid.c:
+ Cache non-existent passwd/group entries too.
+ [8de9a467d271]
+
+ * gram.c:
+ regen
+ [9ece18c58f36]
+
+ * getspwuid.c:
+ fix typo
+ [9a7ae371eac1]
+
+ * check.c, getspwuid.c, glob.c, ldap.c, logging.c, match.c,
+ mon_systrace.h, sudo.c, sudo.h, testsudoers.c, visudo.c:
+ Implement group caching and use the passwd and group caches
+ throughout.
+ [f1d8c5015169]
+
+2004-11-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * match.c:
+ Properly negate the return value of alias_matches() when
+ appropriate.
+ [ce59c4ce77ad]
+
+ * match.c:
+ Make hostname_matches() return TRUE for a match, else FALSE like the
+ caller expects.
+ [1dc03902d3a2]
+
+ * Makefile.in:
+ Add missing dependencies on gram.h
+ [4f94bbb1d50c]
+
+ * match.c:
+ Use runas_matches in alias_matches() now that we have it.
+ [284d22e91178]
+
+ * parse.c, parse.h:
+ Expand aliases in "sudo -l" mode
+ [f67a38b79c44]
+
+ * gram.y, match.c:
+ Use ALIAS for the member type when storing an alias instead of
+ HOSTALIAS/RUNASALIAS/CMNDALIAS/USERALIAS since match.c relies on the
+ more generic type. Expand runas_matches instead of calling
+ user_matches() inside of it since user_matches() looks up
+ USERALIASes, not RUNASALIASes.
+ [52004d75232b]
+
+ * CHANGES, getspwuid.c:
+ Paranoia; zero out pw_passwd before freeing passwd entry.
+ [bd1b22638f00]
+
+ * LICENSE, Makefile.in, alloc.c, check.c, config.h.in, configure,
+ configure.in, defaults.c, emul/err.h, env.c, err.c, error.c,
+ error.h, find_path.c, interfaces.c, logging.c, mon_systrace.c,
+ sudo.c, sudo.h, sudo_edit.c, testsudoers.c, visudo.c:
+ Add local error/warning functions like err/warn but that call an
+ additional cleanup routine in the error case. This means we no
+ longer need to compile a special version of alloc.o for visudo.
+ [25000b676cfe]
+
+ * match.c:
+ Use userpw_matches() to compare usernames, not strcmp(), since the
+ latter checks for "#uid".
+ [fcbe4b859f66]
+
+ * getspwuid.c, mon_systrace.c, mon_systrace.h, sudo.c:
+ Cache passwd db entries in 2 reb-black trees; one indexed by uid,
+ the other by user name. The data returned from the cache should be
+ considered read-only and is destroyed by sudo_endpwent().
+ [ee2418ff3f86]
+
+ * match.c:
+ add cast to uid_t
+ [eb6415302d84]
+
+ * gram.y:
+ missing free in alias_destroy
+ [572ecb680ad8]
+
+ * redblack.c:
+ Can't use rbapply() for rbdestroy since the destructor is passed a
+ data pointer, not a node pointer.
+ [11ce713830c0]
+
+ * getspwuid.c, logging.c, sudo.c, sudo.h:
+ Create and use private versions of setpwent() and endpwent() that
+ set/end the shadow password file too.
+ [616bc76d23bf]
+
+ * gram.c, gram.h, gram.y, match.c, parse.h, testsudoers.c, visudo.c:
+ Store aliases in a red-black tree.
+ [ce017d540416]
+
+ * Makefile.in, redblack.c, redblack.h:
+ red-black tree implementation
+ [cd5586e8f48b]
+
+ * visudo.c:
+ Edit all sudoers file if there were unused or undefined aliases and
+ we are in strict mode.
+ [b6d5f5bb7262]
+
+2004-11-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, def_data.c, def_data.h, def_data.in, defaults.c, env.c,
+ find_path.c, sudoers.cat, sudoers.man.in, sudoers.pod, visudo.c:
+ Bring back the "secure_path" Defaults option now that Defaults take
+ effect before the path is searched.
+ [2e52c0e27606]
+
+2004-11-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c, parse.c:
+ A user can always list their own entries, even with -u. Better error
+ message when failing to list another user's entries.
+ [e2e24deb0071]
+
+ * parse.c, sudo.c, sudo.h:
+ The syntax to list another user's entries is now "-u otheruser -l".
+ Only root or users with sudo "ALL" may list other user's entries.
+ [3c0657e8f5fe]
+
+ * sudo.cat, sudo.man.in, sudo.pod:
+ Update env variable info in SECURITY NOTES
+ [299716071024]
+
+ * env.c:
+ strip CDPATH too
+ [9b97643b26f9]
+
+ * env.c:
+ strip exported bash functions from the environment.
+ [9e5090c8284f]
+
+2004-10-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Only reset sudo_user.pw based on SUDO_USER environment variables for
+ real commands and sudoedit. This avoids a confusing message when a
+ user tries "sudo -l" or "sudo -v" and is denied.
+ [3ea6d0053274]
+
+ * gram.c, gram.y, parse.h:
+ Extend LIST_APPEND to deal with appending lists too
+ [d963e42f622f]
+
+2004-10-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ Convert some bitwise AND to ISSET
+ [130dc40d268e]
+
+ * lex.yy.c, toke.c:
+ toke.c replaces lex.yy.c
+ [048858df79e7]
+
+ * CHANGES, TODO:
+ sync
+ [d19e7abf251c]
+
+ * BUGS:
+ new parser fixes most of the outstanding bugs
+ [0891f66e3758]
+
+ * configure:
+ regen
+ [1a3358cc7283]
+
+ * visudo.c:
+ Rework for the new parser. Now checks for unused aliases in sudoers.
+ [ad462ede3094]
+
+ * testsudoers.c:
+ Rewrite for the new parser. Now supports a -d flag (dump) and adds a
+ -h flag (host). It now defaults to the local hostname unless
+ otherwise specified.
+ [1b69685cc601]
+
+ * sudo.h:
+ Add new prototypes. Remove NOMATCH/UNSPEC (now in parse.h)
+ [2e4fb3abfef0]
+
+ * sudo.c:
+ Update for new parse. We now call find_path() *after* we have
+ updated the global defaults based on sudoers. Also adds support for
+ listing other user's privs if you are root.
+ [cf3db9fc3024]
+
+ * mon_systrace.c:
+ Working LDAP support; also remove a now-unneeded rewind().
+ [649ecf1baf6b]
+
+ * logging.c, logging.h:
+ Add NO_STDERR flag.
+ [6cb935af94e0]
+
+ * ldap.c:
+ Split sudo_ldap_check() into three pieces: sudo_ldap_open(),
+ udo_ldap_update_defaults() and sudo_ldap_check(). This allows us to
+ connecto to LDAP, apply the default options, find the command in the
+ user's path, and then check whether the user is allowed to run it.
+ The important thing here is that the default runas user may be
+ specified as a default option and that needs to be set before we
+ search for the command.
+ [fc0426abc6f1]
+
+ * ldap.c:
+ Add casts to unsigned char for isspace() to quiet a gcc warning.
+ [e5358e3df439]
+
+ * defaults.h:
+ Add prototype for update_defaults()
+ [564dac3db74e]
+
+ * defaults.c:
+ Don't warn about line numbers now that we operate on a set of data
+ structures (or LDAP) and not a file.
+ [bcd9ffb9b67c]
+
+ * config.h.in:
+ No long use lsearch()
+ [9d048c587319]
+
+ * Makefile.in:
+ Update for new and changed file names.
+ [6f424a7c4515]
+
+ * LICENSE:
+ no more BSD lsearch.c
+ [463a96d89026]
+
+ * match.c:
+ foo_matches() routines now live in match.c Added user_matches(),
+ runas_matches(), host_matches(), cmnd_matches() and alias_matches()
+ that operate on the parsed sudoers file.
+ [b14da8a0567e]
+
+ * parse.lex, toke.l:
+ Move parse.lex -> toke.l Rename buffer_frob() -> switch_buffer()
+ WORD no longer needs to exclude '@' kill yywrap()
+ [a922294eb7b7]
+
+ * gram.c, gram.h, gram.y, parse.c, parse.h, parse.yacc, sudo.tab.c,
+ sudo.tab.h:
+ Rewritten parser that converts sudoers into a set of data
+ structures. This eliminates ordering issues and makes it possible to
+ apply sudoers Defaults entries before searching for the command.
+ [30d2ec4d203c]
+
+ * configure.in, emul/search.h, lsearch.c:
+ We won't be using lsearch() any longer.
+ [29c4d54bfac0]
+
+ * ldap.c:
+ sudo should not send mail if someone who runs 'sudo -l' has no
+ entry.
+ [6fc27a69fd9c]
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in, visudo.cat,
+ visudo.man.in:
+ regen
+ [8166347917f3]
+
+ * visudo.pod:
+ Update warnings to match new visudo
+ [004c0766798f]
+
+ * sudoers.pod:
+ The new parser doesn't have the old ordering constraints.
+ [ffd43bd08661]
+
+ * sudo.pod:
+ Document that -l now takes an optional username argument
+ [278f9557de8b]
+
+2004-10-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON:
+ AIX 5.2.0.0 works
+ [523acd29d858]
+
+ * ldap.c:
+ If LDAP_OPT_SUCCESS is not defined, use LDAP_SUCCESS instead. Fixes
+ a compilation problem with Solaris 9's native LDAP.
+
+ Set FLAG_MONITOR when needed.
+ [35824ade672d]
+
+2004-10-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mon_systrace.c:
+ Call sudo_goodpath() *after* changing the cwd to match the traced
+ process. Fixes relative paths.
+ [12ee111d0ad7]
+
+2004-10-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * testsudoers.c:
+ Kill set_perms() stub--it is no longer needed.
+ [116ed702935d]
+
+2004-10-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.cat, sudoers.man.in, sudoers.pod:
+ stay_setuid now requires set_reuid() or setresuid()
+ [8511f67e25d5]
+
+ * INSTALL, PORTING, TROUBLESHOOTING, config.h.in, configure,
+ configure.in, set_perms.c, sudo.c, sudo.h:
+ Kill use of POSIX saved uids; they aren't worth bothering with.
+ [b3b1f19f18c1]
+
+2004-10-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * glob.c:
+ remove call to issetugid()
+ [63f2e492c08f]
+
+ * sudoers.cat, sudoers.man.in, sudoers.pod:
+ Remove warning about wildcards. Now that we use glob() the bug is
+ fixed.
+ [b15729d32266]
+
+ * parse.c:
+ Use glob(3) instead of fnmatch(3) for matching pathnames and stat
+ each result that matches the basename of the user's command. This
+ makes "cd /usr/bin ; sudo ./blah" work when sudoers allows
+ /usr/bin/blah. Fixes bug #143.
+ [e31eb6310340]
+
+ * config.h.in, configure, configure.in:
+ Define HAVE_EXTENDED_GLOB for extended glob (GLOB_TILDE and
+ GLOB_BRACE)
+ [677ed6661e17]
+
+ * config.h.in, configure, configure.in:
+ Check for a glob() that supports GLOB_BRACE and GLOB_TILDE
+ [aaa2329dd266]
+
+ * LICENSE:
+ reference glob
+ [bedc9a923423]
+
+ * glob.c:
+ 4.4BSD glob(3) with fixes from OpenBSD and some unneeded extensions
+ removed.
+ [81799451473c]
+
+ * emul/glob.h:
+ 4.4BSD glob(3) with fixes from OpenBSD and some unneeded extensions
+ removed.
+ [0335cf31fb1e]
+
+2004-10-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mon_systrace.c:
+ Just return if STRIOCINJECT or STRIOCREPLACE fail. It probably means
+ we are out of space in the stack gap...
+ [5b02b702021e]
+
+ * CHANGES:
+ sync
+ [be3826273e56]
+
+ * mon_systrace.c:
+ Take a stab at ldap sudoers support here.
+ [9d023695b0de]
+
+ * mon_systrace.c, mon_systrace.h:
+ Detach from tracee on SIGHUP, SIGINT and SIGTERM. Now "sudo reboot"
+ doesn't cause reboot to inadvertanly kill itself.
+ [d4aab2365610]
+
+ * mon_systrace.c:
+ put "monitor" in the proctitle, not "systrace"
+ [9a9025767d86]
+
+ * mon_systrace.c:
+ When modifying the environment, don't replace envp when we can get
+ away with just rewriting pointers in the traced process.
+ [c03622f7a2e2]
+
+ * mon_systrace.c, mon_systrace.h:
+ Add environment updating via STRIOCINJECT (if available).
+ [037291016870]
+
+ * sudoers.cat, sudoers.man.in:
+ regen
+ [869acc511046]
+
+2004-10-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lex.yy.c:
+ regen
+ [4e61a9bd3c97]
+
+ * parse.lex:
+ Fix bug introduced in unput() removal; want yyless(0) not yyless(1)
+ [b70d7bd6e147]
+
+ * mon_systrace.c:
+ Include file is now mon_systrace.h
+ [ead4e36d92ae]
+
+ * Makefile.in, configure, configure.in, def_data.c, def_data.h,
+ def_data.in, lex.yy.c, parse.c, parse.h, parse.lex, parse.yacc,
+ sudo.c, sudo.h, sudo.tab.c, sudo.tab.h, sudoers.pod:
+ No longer call it tracing, it is now "monitoring" which should be
+ more a obvious name to non-hackers.
+ [aa811ded0789]
+
+2004-10-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mon_systrace.c, mon_systrace.h:
+ Fix some XXX
+ [a271072dacc6]
+
+ * mon_systrace.c, mon_systrace.h:
+ No need to include syscall.h, use 1024 as the max # of entries (the
+ max that systrace(4) allows).
+
+ Only need to use SYSTR_POLICY_ASSIGN once
+
+ Change check_syscall() -> find_handler() and have it return the
+ handler instead of just running it. We need this since handler now
+ have two parts: one part that generates and answer and another that
+ gets called after the answer is accepted (to do logging).
+
+ Add some missing check_exec for emul execv
+ [a89d243f0525]
+
+ * sample.pam, sample.sudoers, sample.syslog.conf, sudoers:
+ Add $Sudo$ tags.
+ [6f3fedb0daba]
+
+ * config.h.in:
+ Add missing HAVE_LINUX_SYSTRACE_H
+ [ff75ab7bfc53]
+
+ * Makefile.in:
+ add trace_systrace.o dependency
+ [88a408668ab2]
+
+2004-09-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Also look for systrace.h in /usr/include/linux
+ [98b98b436cf3]
+
+ * mon_systrace.c, mon_systrace.h:
+ Move all struct defs and prototypes into trace_systrace.h and mark
+ all but systace_attach() static.
+ [85511253b570]
+
+ * mon_systrace.c, mon_systrace.h:
+ Add support for tracing emulations. At the moment, all emulations
+ are compiled in. It might make sense to #ifdef them in the future,
+ though this impeeds readability.
+ [87bb50abf277]
+
+ * Makefile.in, configure, configure.in:
+ rename systrace.c -> trace_systrace.c
+ [31cfa4407d93]
+
+ * parse.yacc, sudo.tab.c:
+ Allow this to build with a K&R compiler again
+ [32876af5bb98]
+
+ * TODO:
+ sync
+ [46865bd70f7c]
+
+ * compat.h, sudo.c, visudo.c:
+ Use __attribute__((__noreturn__))
+ [65bbad71fe89]
+
+ * visudo.c:
+ Exit() takes a negative value to indicate it was not called via
+ signal.
+ [b93032ed7b60]
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in, visudo.cat,
+ visudo.man.in:
+ regen
+ [45bcf4661558]
+
+ * Makefile.in, visudo.c:
+ Define Err() and Errx() that are like err() and errx() but call
+ Exit() instead of exit(). Build private copy of alloc.o for visudo
+ that calls Err() and Errx().
+ [c6d02bf42edd]
+
+2004-09-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lex.yy.c, sudo.tab.c:
+ regen
+ [39de7e7c59da]
+
+ * CHANGES:
+ sync
+ [ba481d9ed1aa]
+
+ * visudo.c:
+ Overhaul visudo for editing multiple files: o visudo has been broken
+ out into functions (more work needed here) o each file is now edited
+ before sudoers is re-parsed o if a #include line is added that file
+ will be edited too
+
+ TODO: o cleanup temp files when exiting via err() or errx() o
+ continue breaking things out into separate functions
+ [80c35cf534eb]
+
+ * parse.lex, sudo.c, sudo.h, testsudoers.c, visudo.c:
+ Add keepopen arg to open_sudoers that open_sudoers can use to
+ indicate to the caller that the fd should not be closed when it is
+ done with it. To be used by visudo to keep locked fds from being
+ closed prematurely (and thus losing the lock).
+ [f330fe632470]
+
+ * parse.yacc, sudo.c:
+ Add errorfile global that contains the name of the file that caused
+ the error.
+ [98079c7a37ed]
+
+ * parse.lex:
+ return COMMENT to yacc grammar for a #include line
+ [2024a8de4fa8]
+
+ * parse.lex:
+ Remove us of unput() in favor of yyless() which is cheaper.
+ [c61291902beb]
+
+ * parse.yacc:
+ Allow an empty sudoers file.
+ [62fb111db2e7]
+
+2004-09-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mon_systrace.c:
+ Rewind sudoers_fp now that sudoers_lookup() doesn't do it for us.
+ [9e15869ef597]
+
+ * lex.yy.c, sudo.tab.c:
+ regen
+ [c29bdd43bfad]
+
+ * visudo.c:
+ Do signal setup before calling edit_sudoers(). Don't shadow the
+ "quiet" global.
+ [74252efd09ff]
+
+ * visudo.c:
+ If a sudoers file includes other files, edit those too. Does not yes
+ deal with creating the new includes files itself.
+ [06af7b9c173f]
+
+ * testsudoers.c:
+ init_parser now takes a path
+ [b5ee186eb192]
+
+ * parse.c, parse.h, parse.lex, parse.yacc:
+ More scaffolding for dealing with multiple sudoers files: o
+ init_parser() now takes a path used to populate the sudoers global o
+ the sudoers global is used to print the correct file in yyerror() o
+ when switching to a new sudoers file, perserve old file name and
+ line number
+ [d9be4970b8bd]
+
+ * Makefile.in, pathnames.h.in:
+ Kill _PATH_SUDOERS_TMP; it is not meaningful now that we can have
+ multiple sudoers files.
+ [6ccc4e921c43]
+
+ * parse.c, sudo.c:
+ Rewind sudoers_fp in open_sudoers() instead of sudoers_lookup() so
+ we start at the right file position when reading include files.
+ [91fcb961e7a4]
+
+ * sudoers.pod:
+ document #include
+ [fbb92a25a726]
+
+ * lex.yy.c:
+ regen
+ [50cd7a4c9dff]
+
+ * parse.lex:
+ Add max depth of 128 for the include stack to avoid loops.
+
+ Since yyerror() doesn't stop parsing, pass return values back to
+ yylex and call yyterminate() on error.
+ [e79dbffb729d]
+
+2004-09-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ document tracing
+ [165a467eadd8]
+
+ * sudo.pod:
+ Mention PREVENTING SHELL ESCAPES section of sudoers man page
+ [3217ccecd834]
+
+ * lex.yy.c, sudo.tab.c:
+ regen
+ [fbd58d1d3a76]
+
+ * parse.lex:
+ Add support for #include in sudoers (visudo support TBD)
+ [a78015ca81af]
+
+ * parse.yacc:
+ make yyerror()'s argument const
+ [7d8e168c019a]
+
+ * testsudoers.c, visudo.c:
+ Add open_sudoers() stubs.
+ [087466787198]
+
+ * sudo.c, sudo.h:
+ Rename check_sudoers() open_sudoers() and make it return a FILE *
+ [142fc511fc65]
+
+2004-09-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS, INSTALL, INSTALL.binary, Makefile.in, README, configure.in,
+ version.h:
+ Crank version
+ [1adc3f839480]
+
+ * Makefile.in, sudo.psf:
+ Better HP-UX depot construction
+ [2d952b000e63]
+
+2004-09-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mon_systrace.c:
+ o Made children global so check_exec() can lookup a child. o
+ Replaced uid in struct childinfo with struct passwd * (for runas) o
+ new_child() now takes a parent pid so the runas info can be
+ inherited o Added find_child() to lookup a child by its pid o
+ update_child() now fills in a struct passwd o Converted the big
+ if/else mess in set_policy to a switch o Syscalls that change uid
+ are now "ask" so we get SYSTR_MSG_UGID events
+ [29b9ea3f09a3]
+
+ * getspwuid.c:
+ Add flag to sudo_pwdup that indicates whether or not to lookup the
+ shadow password. Will be used to a struct passwd that has the shadow
+ password already filled in.
+ [e19d43dd7238]
+
+ * mon_systrace.c:
+ add missing increment of addr in read_string()
+ [f9eb0f060cb6]
+
+ * mon_systrace.c:
+ Remove bogus call to update_child() and some cosmetic fixes
+ [701ab0b97fef]
+
+ * mon_systrace.c:
+ Don't leak /dev/systrace fd to tracee Make initialized global for
+ simplicity If STRIOCATTACH returns EBUSY we are already being traced
+ Check for user_args == NULL in setproctitle() call Add missing calls
+ to STRIOCANSWER
+ [1956edf9bc3a]
+
+ * sudo.c:
+ g/c sudo_pwdup proto
+ [b7c4d6249ecb]
+
+ * Makefile.in, sudo.psf:
+ Add target for building a depot file
+ [357019efd99b]
+
+ * mon_systrace.c:
+ trim includes
+ [501534428471]
+
+2004-09-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lex.yy.c, sudo.tab.c, sudo.tab.h:
+ regen
+ [52fd250c6986]
+
+ * INSTALL:
+ document --with-systrace
+ [79623927c94e]
+
+ * config.h.in, configure, configure.in:
+ Add check for setproctitle
+ [1730cf1c26ed]
+
+ * mon_systrace.c:
+ pass struct str_msg_ask in to syscall checker so it can set the
+ error code
+ [1703fd2fdef6]
+
+ * mon_systrace.c:
+ systrace(4) support for sudo. On systems with the systrace(4) kernel
+ facility (OpenBSD, NetBSD, Linux w/ patches) sudo can intercept exec
+ calls and check the exec args against the sudoers file. In other
+ words, sudo can now control subcommands and shell escapes.
+ [928c9217c386]
+
+ * sudo.c, sudo.h:
+ Call systrace_attach() if FLAG_TRACE is set.
+ [014ba9402fa5]
+
+ * parse.c, parse.h, parse.lex, parse.yacc, sudo.h:
+ Add trace Defaults option and TRACE/NOTRACE tags and set FLAG_TRACE
+ [a99904db5e56]
+
+ * parse.c, sudo.c:
+ Don't close sudoers_fp, keep it open and set close on exec flag
+ instead.
+ [43a9fec60bee]
+
+ * def_data.c, def_data.h, def_data.in:
+ Add trace option
+ [5b643b86730a]
+
+ * Makefile.in:
+ Add systrace
+ [47a0519c427c]
+
+ * INSTALL:
+ SunOS /bin/sh blows up with configure
+ [005a23cc5615]
+
+ * configure, configure.in:
+ Include sys/param.h before systrace.h
+ [9345bc8efecf]
+
+ * configure:
+ regen
+ [a8f53fcbb254]
+
+ * pathnames.h.in:
+ _PATH_DEV_SYSTRACE
+ [d2ad1e492a00]
+
+ * configure.in:
+ line up options in --help
+ [fa51f2821d09]
+
+ * config.h.in, configure.in:
+ Add --with-systrace
+ [a264d54bc413]
+
+2004-09-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [a4dad0bcc523]
+
+ * aclocal.m4, configure.in:
+ make this work with autoconf-2.59
+ [c4a92b6a684a]
+
+2004-09-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo_edit.c:
+ Simplify logic around open & stat of files and do sanity on edited
+ file even if we lack fstat (still racable but worth doing).
+ [adda65ade70c]
+
+2004-09-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * HISTORY:
+ Add support url
+ [bf6590fbde9f]
+
+ * Makefile.in:
+ versino 1.6.8p1
+ [b84ebfaf1552] [SUDO_1_6_8p1]
+
+ * CHANGES:
+ more changes for 1.6.8p1
+ [e23a9c0393b6]
+
+ * version.h:
+ 1.6.8p1
+ [872f14504b5f]
+
+ * CHANGES, sudo_edit.c:
+ Add sanity check so we don't try to edit something other than a
+ regular file.
+ [350134ec6d4e]
+
+2004-09-15 Aaron Spangler <aaron777@gmail.com>
+
+ * CHANGES:
+ sync
+ [3091ca9eae00]
+
+ * INSTALL:
+ document --with-ldap-conf-file
+ [0e2cd6b896f1]
+
+2004-09-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, ins_csops.h:
+ political correctness strikes again
+ [428e8bc77f55]
+
+ * RUNSON:
+ sync
+ [27f44bd423dc]
+
+2004-09-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.binary.in, Makefile.in:
+ Install sudoedit man link
+ [19a55234fc1f]
+
+ * INSTALL:
+ Update PAM note and mention where HP-UX users can download gcc
+ binaries.
+ [d37cdbbabfd4]
+
+ * Makefile.in:
+ libtool wants to install stuff from .libs so fake one up for binary
+ installations.
+ [a681bc6fcfba]
+
+ * Makefile.binary.in:
+ rm -f old sudoedit link instead of using ln -f set LIBTOOL correctly
+ [3e0c4b3372cc]
+
+ * Makefile.in:
+ Deal with "uname -m" having slashes in it rm -f old sudoedit link
+ instead of using ln -f
+ [cff33fb97e5b]
+
+ * Makefile.binary, Makefile.binary.in:
+ Makefile.binary -> Makefile.binary.in for config.status substitution
+ Add support for installing noexec bits
+ [37d8bb3483c6]
+
+ * Makefile.in:
+ Copy noexec bits into binary dists too No longer use my old arch
+ script for making binary dists
+ [e7058bab9e33]
+
+ * Makefile.binary:
+ Install sudoedit link.
+ [417d1e101711]
+
+2004-09-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * emul/utime.h:
+ avoid __P so there is no need for compat.h to be included
+ [6d8d1f1abf7d]
+
+ * utimes.c:
+ Don't use HAVE_UTIME_H before including config.h.
+ [013b7bb61181]
+
+2004-09-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat.h:
+ Fix Solatis futimes macro
+ [d4eda2ca0d29]
+
+2004-09-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo_edit.c:
+ Rename ots -> omtim for improved readability.
+ [127ca5bb297c]
+
+2004-09-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo_edit.c:
+ Redo changes in revision 1.7. Don't really need to keep the temp
+ file open; re-opening it with the invoking user's euid is
+ sufficient.
+ [55a883165a95]
+
+ * CHANGES:
+ sync
+ [9015b291170d]
+
+ * sudo.cat, sudo.man.in:
+ regen
+ [c0313f6ed783]
+
+ * sudo.pod:
+ back out revision 1.70; it is no long applicable
+ [b641d503aff6]
+
+ * env.c:
+ Let the loader initialize nep
+ [bec192139b02]
+
+ * config.h.in, configure, configure.in:
+ Removed unneed check for fchown Add check for gettimeofday Move
+ autoheader template stuff into separate AH_TEMPLATE lines
+ [bfc0edbd43f2]
+
+ * check.c, compat.h, fileops.c, sudo.h, sudo_edit.c, visudo.c:
+ Use timespec throughout.
+ [1a178a23b69b]
+
+ * Makefile.in:
+ gettime.[co]
+ [6aeb48a7ab7f]
+
+ * gettime.c:
+ function to return the current time in a struct timespec
+ [bf8eb12cb63f]
+
+ * utimes.c:
+ Not a darpa-sponsored file.
+ [121ce5e2036c]
+
+2004-09-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat.h, config.h.in, configure, configure.in:
+ Add a check for struct timespec and provide it for those without.
+ [42124055030d]
+
+ * config.h.in, configure, configure.in, sudo_edit.c:
+ Add checks for st_mtim and st_mtimespec and add macros for pulling
+ the mtime sec and nsec out of struct stat. These are used in
+ sudo_edit() to better tell whether or not the file has changed.
+ [23debfbb3fab]
+
+ * check.c, fileops.c, sudo.h, sudo_edit.c, visudo.c:
+ Add an extra param to touch() for nsec
+ [56f7a4ba8ddb]
+
+ * sudo_edit.c:
+ Call mkstemp() as the in invoking user so we don't have to chown the
+ file later. Only touch() the temp file if we can do it via the file
+ descriptor. Don't check for modification of the temp file if we lack
+ fstat(). Catch errors read()ing the temp file.
+ [665f52c70836]
+
+ * fileops.c:
+ If path is NULL and fd == -1 return -1.
+ [757a518a824c]
+
+ * sudo_edit.c:
+ closefrom() is overkill, the only extra fds are the ones we opened
+ so just close those in the child.
+ [f361c9d2a1f4]
+
+ * Makefile.in, aclocal.m4, check.c, compat.h, config.h.in, configure,
+ configure.in, fileops.c, sudo.h, sudo_edit.c, utime.c, utimes.c,
+ visudo.c:
+ Use utimes() and futimes() instead of utime() in touch(), emulating
+ as needed. Not all systems are able to support setting the times of
+ an fd so touch() takes both an fd and a file name as arguments.
+ [3d9276f29717]
+
+2004-09-07 Aaron Spangler <aaron777@gmail.com>
+
+ * env.c:
+ Rare SEGV
+ [8995f828782d]
+
+2004-09-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in, visudo.cat,
+ visudo.man.in:
+ regen
+ [b8e9406711c5]
+
+ * sudo.pod, sudoers.pod, visudo.pod:
+ Add SUPPORT section and re-order some of the sections to match the
+ order we use in OpenBSD.
+ [fa37bd917e2c]
+
+2004-09-06 Aaron Spangler <aaron777@gmail.com>
+
+ * env.c:
+ Openldap ~/.ldaprc fix
+ [1a37afe6850f]
+
+2004-09-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod:
+ Talk about how the editor must write its changes to the original
+ file and not just use rename(2).
+ [c55ed91c5ee9]
+
+ * CHANGES:
+ sync
+ [62af26bd37a2]
+
+ * sudo_edit.c:
+ Keep the temp file open instead of re-opening after the editor has
+ exited.
+ [de41eeb6dcf2]
+
+ * sample.pam:
+ Update for current redhat/fedora core.
+ [8cf083077333]
+
+2004-09-03 Aaron Spangler <aaron777@gmail.com>
+
+ * README.LDAP:
+ tls_ examples
+ [ba783d88a034]
+
+2004-09-02 Aaron Spangler <aaron777@gmail.com>
+
+ * ldap.c:
+ config tls_* options
+ [0b0e0797b3b9]
+
+2004-08-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ No need for -lcrypt when using pam.
+ [41fff3a53e68]
+
+2004-08-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [75820aecce2c]
+
+2004-08-27 Aaron Spangler <aaron777@gmail.com>
+
+ * configure.in, ldap.c, pathnames.h.in:
+ Allow --with-ldap-conf-file option to override LDAP_CONF
+ [c9909bc484a5]
+
+ * ldap.c:
+ cleanup debug message
+ [1f6ca4824d8d]
+
+2004-08-26 Aaron Spangler <aaron777@gmail.com>
+
+ * README.LDAP:
+ more config info
+ [f2e7147fd507]
+
+2004-08-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TODO, find_path.c, goodpath.c, parse.c, sudo.c, sudo.h, visudo.c:
+ Add cmnd_base to struct sudo_user and set it in init_vars(). Add
+ cmnd_stat to struct sudo_user and set it in sudo_goodpath(). No
+ longer use gross statics in command_matches(). Also rename some
+ variables for improved clarity.
+ [7169a6c7bea4]
+
+2004-08-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ document HP's crippled compiler deficiency.
+ [c405ea5a8d4c]
+
+ * INSTALL:
+ Fix some thinkos in --with-editor and --with-env-editor
+ descriptions. Noticed by Norihiko Murase.
+ [dd781de1c985]
+
+ * configure, configure.in:
+ --with-noexec takes an optional PATH argument.
+ [8f6ab77f22cc]
+
+ * INSTALL:
+ document --with-noexec
+ [50cb1fc627ce]
+
+2004-08-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON, TODO:
+ sync
+ [f2503bd13373] [SUDO_1_6_8]
+
+ * sudo_edit.c:
+ Better warning message when sudoedit is unable to write to the
+ destination file.
+ [f78c18f2ffa8]
+
+ * sudo.cat, sudo.man.in:
+ regen
+ [7e2bf63d6d9a]
+
+ * sudo.pod:
+ Don't italicize the string "sudoedit"
+ [c691643bd269]
+
+2004-08-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * HISTORY:
+ Mention GratiSoft.
+ [dc53de581b2d]
+
+2004-08-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.tab.c:
+ regen
+ [8ae0484dfc38]
+
+ * parse.yacc:
+ Reset used_runas to FALSE when re-intializing the parser.
+ [b7403f353a02]
+
+2004-08-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.guess:
+ Correct OpenBSD mips support
+ [314fc7afc165]
+
+ * config.guess:
+ Add OpenBSD/mips
+ [ac87d0a773ef]
+
+2004-08-07 Aaron Spangler <aaron777@gmail.com>
+
+ * README.LDAP:
+ More behavior notes
+ [13be1d212b47]
+
+ * README.LDAP:
+ Updates on current behavior
+ [d498a8866d6f]
+
+2004-08-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ =back does not take an indentlevel (makes no difference to formatted
+ files).
+ [9c8523bb382a]
+
+ * sudo.pod:
+ =back does not take an indentlevel (makes no difference to formatted
+ files).
+ [e5f479e24fa8]
+
+ * CHANGES:
+ new
+ [2dbd9aba8b33]
+
+ * sudo.c:
+ Consistency. Use same error for bad -u #uid when targetpw is set as
+ we do when a bad -u username is specified.
+ [922961c4a9d6]
+
+ * TODO:
+ Add checksum idea from Steve Mancini
+ [e6ece1b766ba]
+
+ * sudoers.cat, sudoers.man.in:
+ regen
+ [370d2317829f]
+
+ * sudo.cat, sudo.man.in:
+ regen
+ [f93d41fc38b1]
+
+ * sudo.pod, sudoers.pod:
+ Document the restriction on uids specified via -u when targetpw is
+ set.
+ [878fedb455db]
+
+ * sudo.c:
+ Error out when targetpw is enabled and sudo is run with -u #uid but
+ #uid does not exist in the passwd database. We can't do target
+ authentication when the target is not in passwd!
+ [27c5888c86eb]
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in:
+ regen
+ [ceb65711050c]
+
+ * TODO:
+ Some more todo for the next release.
+ [7b7417be7601]
+
+ * INSTALL:
+ Make it clear that PAM should be used for DCE support when possible.
+ [7502029fd385]
+
+ * sudoers.pod:
+ o Document problems with wildcards and relative paths. o Make the
+ order requirements more prominent. o Change a "set" to "reset" for
+ clarity.
+ [bacdd181b33f]
+
+2004-08-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod:
+ Mention --with-secure-path, not SECURE_PATH.
+ [41283ddde5e1]
+
+2004-08-03 Aaron Spangler <aaron777@gmail.com>
+
+ * ldap.c:
+ reflect changes to parse.c
+ [8880fe9b724d]
+
+2004-08-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.tab.c:
+ regen
+ [a57658ca9177]
+
+ * parse.c, parse.h, testsudoers.c, visudo.c:
+ Don't pass user_cmnd and user_args to command_matches(), just use
+ the globals there. Since we keep state with statics anyway it is
+ misleading to pretend that passing in different cmnd and cmnd_args
+ will work.
+ [0a2544991fd6]
+
+ * parse.yacc:
+ Don't pass user_cmnd and user_args to command_matches(), just use
+ the globals there. Since we keep state with statics anyway it is
+ misleading to pretend that passing in different cmnd and cmnd_args
+ will work.
+ [a4910bf6032b]
+
+ * parse.c:
+ Fix a bug introduced in rev. 1.149. When checking for pseudo-
+ commands check for a '/' anywhere in cmnd, not just the first
+ character.
+ [ce98142f03ca]
+
+2004-07-31 Aaron Spangler <aaron777@gmail.com>
+
+ * sudo.man.in, sudo.pod:
+ Clarification thanks to Olivier Blin <oblin@mandrakesoft.com>
+ [a91800e094b1]
+
+ * sudoers.man.in, sudoers.pod:
+ Add ignore_local_sudoers
+ [741ddcbf7083]
+
+ * README.LDAP:
+ Sun One schema definition by Andreas.Bussjaeger@t-systems.com and
+ janth@moldung.no
+ [742c02e07cd9]
+
+2004-07-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ typo
+ [e7cdefbd7a9a]
+
+2004-07-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ sync
+ [734dafc4a85e]
+
+ * parse.c:
+ Parse sudoers file as PERM_RUNAS not PERM_ROOT and remove a useless
+ PERM_SUDOERS. Restore to PERM_ROOT upon exit of the parse.
+ [151b7f593568]
+
+2004-07-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ PAM change
+ [d8fb6d6a22d0]
+
+2004-07-08 Aaron Spangler <aaron777@gmail.com>
+
+ * ldap.c:
+ Better debugging of ALL command
+ [9db3e84029dc]
+
+2004-07-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ When matching for "sudoedit" in sudoers check both the command the
+ user typed *and* the command that is listed in the sudoers entry.
+ [f36ca1f94095]
+
+2004-07-04 Aaron Spangler <aaron777@gmail.com>
+
+ * ldap.c:
+ Added !command feature
+ [ed539574611b]
+
+2004-06-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c:
+ Use pam_acct_mgmt() to check for disabled accounts; Brian Farrell
+ [2be8e0e8813a]
+
+2004-06-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * LICENSE:
+ License is ISC-style, not BSD-style
+ [ac0589e1dd5d]
+
+ * CHANGES:
+ sync
+ [16058a30f404]
+
+2004-06-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man.in:
+ regen
+ [8820eb9c809b]
+
+ * sudo.pod:
+ o Update some out of date bits to reality o Change the shell promt
+ in examples to bourne-shell style o Clarify some details o Add a
+ CAVEAT about "sudo cd /foo"
+ [b0af373214b6]
+
+ * check.c:
+ Don't ask for a password if invoking user == target user.
+ [dd5c96141132]
+
+ * sudo.c:
+ typo in comment
+ [278d20f9b249]
+
+2004-06-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.cat, sudoers.man.in:
+ regen
+ [9036c6f39eff]
+
+ * sudoers.pod:
+ Expand on NOEXEC a little.
+ [9a13756aebe4]
+
+ * TODO:
+ sync
+ [8d2c1af48de8]
+
+ * visudo.cat, visudo.man.in:
+ regen
+ [3921f01607c8]
+
+ * sudo.tab.c:
+ regen
+ [9338c3d68250]
+
+ * visudo.pod:
+ Add a check in visudo for runas_default being set after it has
+ already been used.
+ [6700358d7ad8]
+
+ * CHANGES, parse.yacc, visudo.c:
+ Add a check in visudo for runas_default being set after it has
+ already been used.
+ [803560986a8a]
+
+ * sudo.tab.c:
+ regen
+ [b60636e2cf63]
+
+ * parse.yacc:
+ Add a MATCHED macro for testing whether foo_matches has been set to
+ TRUE or FALSE. This is more readable than checking for >=0 or < 0.
+ Doesn't change the actual code generated.
+ [f376da8ccdc8]
+
+2004-06-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.cat:
+ regen
+ [6cceb6d6c9bd]
+
+ * sudoers.man.in:
+ regen
+ [5acd12b730b3]
+
+ * sudoers.pod:
+ Correct description of where Defaults specs should go.
+ [6b11ff53d7ad]
+
+ * sudoers:
+ Correct description of where Defaults specs should go.
+ [868db857630d]
+
+ * testsudoers.c, visudo.c:
+ update (c) year
+ [272c8a53604c]
+
+ * logging.h:
+ update (c) year
+ [3cec76d400ce]
+
+ * ldap.c:
+ update (c) year
+ [f264632488a0]
+
+ * find_path.c:
+ update (c) year
+ [40c227af9227]
+
+ * auth/pam.c:
+ update (c) year
+ [87149e0eed50]
+
+ * auth/bsdauth.c, auth/kerb5.c:
+ update (c) year
+ [d72eb434c068]
+
+2004-06-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.tab.c:
+ regen
+ [83408d9e9d2e]
+
+ * auth/bsdauth.c, auth/kerb5.c, auth/pam.c, visudo.c:
+ Remove trailing spaces, no actual code changes.
+ [4c3bf2819293]
+
+ * tgetpass.c:
+ Remove trailing spaces, no actual code changes.
+ [96f6e0a24c26]
+
+ * ldap.c, logging.h, parse.c, parse.yacc, sudo.c, testsudoers.c:
+ Remove trailing spaces, no actual code changes.
+ [c7075d1cbed5]
+
+ * getcwd.c:
+ Remove trailing spaces, no actual code changes.
+ [776cc0374547]
+
+ * find_path.c:
+ Remove trailing spaces, no actual code changes.
+ [7ed7099f3c71]
+
+ * compat.h, defaults.c, env.c:
+ Remove trailing spaces, no actual code changes.
+ [893e83c33795]
+
+ * check.c:
+ Remove trailing spaces, no actual code changes.
+ [f77750f8803b]
+
+ * sudo.tab.c:
+ regen
+ [62e0ed883b31]
+
+ * parse.yacc:
+ Fix a >=0 that should be <0 that was improperly converted when
+ UNSPEC was added.
+ [ad1531a55a49]
+
+ * parse.yacc:
+ Add do {} while(0) around pop macro Set cmnd_matches to UNSPEC, not
+ NOMATCH when resetting it.
+ [ae017a12870a]
+
+ * parse.yacc:
+ Fix pastos introduced in SETNMATCH addition.
+ [6ea1c9d80681]
+
+2004-06-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README.LDAP:
+ Update for configure changes
+ [637a635da287]
+
+ * sudo.tab.c:
+ regen
+ [4753c2788713]
+
+ * sudo.h:
+ Add NOMATCH and UNSPEC defines (-1 and -2 respectively) and use
+ these in parse.yacc. Also in parse.yacc initialize the *_matches
+ vars to UNSPEC and add two macros, SETMATCH and SETNMATCH for use
+ when setting *_matches to a value that may be
+ NOMATCH/UNSPEC/TRUE/FALSE.
+ [2ba622e15a4d]
+
+ * parse.yacc:
+ Add NOMATCH and UNSPEC defines (-1 and -2 respectively) and use
+ these in parse.yacc. Also in parse.yacc initialize the *_matches
+ vars to UNSPEC and add two macros, SETMATCH and SETNMATCH for use
+ when setting *_matches to a value that may be
+ NOMATCH/UNSPEC/TRUE/FALSE.
+ [746b519e41a6]
+
+ * parse.yacc:
+ Initialize runas to -2, not -1 since we need to be able to
+ distinguish between the initialized value and the value of a non-
+ match when passing along the runas value to multiple commands.
+
+ The result of this is that an unmatched runas is now set to -1, not
+ 0. This is required now that parse.c treats a FALSE value for runas
+ as being explicitly denied.
+ [7791ed3621f6]
+
+2004-06-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c, visudo.c:
+ Error out if argc < 1.
+ [ce6b2a9eda3c]
+
+ * getprogname.c:
+ Error out if argc < 1.
+ [c566cce8dc78]
+
+ * configure, configure.in:
+ Add tests for what libs we need to link with for ldap and for
+ whether or not lber.h needs to be explicitly included.
+ [b2e9729cc4e7]
+
+2004-06-03 Aaron Spangler <aaron777@gmail.com>
+
+ * ldap.c:
+ Solaris native LDAP build fix
+ [39929e40eb11]
+
+2004-06-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ldap.c:
+ Set edn to NULL is ldap_get_dn() fails to avoid potential use of an
+ unset variable.
+ [6a4c20a66f98]
+
+ * sudo.h:
+ Add prototype for sudo_ldap_list_matches
+ [443b007a8dab]
+
+ * configure, configure.in:
+ Better check for dirfd macro--we now set HAVE_DIRFD for the macro
+ version too. Added check for dd_fd in `DIR' if no dirfd is found;
+ this is now used to confitionally define the dirfd macro in
+ compat.h.
+ [567656978f7e]
+
+ * config.h.in:
+ Better check for dirfd macro--we now set HAVE_DIRFD for the macro
+ version too. Added check for dd_fd in `DIR' if no dirfd is found;
+ this is now used to confitionally define the dirfd macro in
+ compat.h.
+ [34eace4faec8]
+
+ * compat.h:
+ Better check for dirfd macro--we now set HAVE_DIRFD for the macro
+ version too. Added check for dd_fd in `DIR' if no dirfd is found;
+ this is now used to confitionally define the dirfd macro in
+ compat.h.
+ [8d50ff1bbf2a]
+
+ * closefrom.c:
+ Only check /proc/$$/fd if we have the dirfd function/macro.
+ [15e3ccce7553]
+
+ * compat.h, config.h.in, configure, configure.in:
+ Add a check for a dirfd() function (like Linux) and add a dirfd
+ macro in compat.h if there is no dirfd() function or macro.
+ [1e95756edb50]
+
+ * closefrom.c, getcwd.c:
+ dirfd() is now defined in compat.h as needed.
+ [bb1d79271188]
+
+ * CHANGES:
+ Clarify closefrom() note.
+ [f4e4a5508dda]
+
+ * parse.c:
+ When checking for a command in the directory, only copy the base dir
+ once.
+ [7a3276808b87]
+
+ * closefrom.c:
+ If there is a /proc/$$/fd directory, behave like the Solaris
+ closefrom() and only close the descriptors listed therein.
+ [19de23779e84]
+
+ * alloc.c:
+ compat.h guarantees INT_MAX is defined.
+ [1bf0c79d4606]
+
+ * compat.h:
+ Add definitions of OPEN_MAX and INT_MAX for those without it and
+ remove definition of RLIM_INFINITY (now unused).
+ [f827d1ebf96e]
+
+ * CHANGES, alloc.c, check.c, compat.h, find_path.c, getcwd.c, parse.c,
+ sudo.c, sudo.h, visudo.c:
+ Use PATH_MAX, not MAXPATHLEN since the former is standardized.
+ [59788f211c24]
+
+2004-05-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ sync
+ [d32fa124f1ad]
+
+ * RUNSON:
+ Add some entries that were mailed in a while ago
+ [ff8d5bfec54e]
+
+ * closefrom.c:
+ o sysconf returns a long, not an int. o check for negative return
+ value from sysconf/getdtablesize and use OPEN_MAX in this case. o
+ define OPEN_MAX to 256 for those without it (a fair guess...)
+ [ccf81ae6deb2]
+
+2004-05-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * UPGRADE:
+ Mention change in parse order for RunAs entries.
+ [dc73b0bca617]
+
+ * configure:
+ regen
+ [07cce8e0534e]
+
+2004-05-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, README.LDAP, config.h.in, configure.in:
+ o --with-ldap now takes an optional dir as a parameter o added check
+ for ldap_initialize() and start_tls_s()
+ [2b846c7974c6]
+
+ * README.LDAP:
+ Fix some typos, word choice and formatting issues.
+ [00dc8ca84b10]
+
+2004-05-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ Use SA_INTERRUPT so SunOS works correctly, avoid stdio and just use
+ read/write as it is simpler.
+ [30f5446ee8b0]
+
+ * configure, configure.in:
+ Remove hack overriding cross-compiler check. It should no longer be
+ needed.
+ [22a6cbd88608]
+
+ * compat.h:
+ Remove select() compat bits since we no longer use select().
+ [d7bbf7cd36f5]
+
+ * CHANGES, tgetpass.c:
+ Use alarm() instead of select() for the timeout for systems that
+ don't fully/properly implement select().
+ [d7cc60f15800]
+
+2004-05-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ synbc
+ [132a39788e07]
+
+ * RUNSON:
+ update
+ [61ef508380c6]
+
+ * set_perms.c:
+ Deal with systems that have no way of setting the effective uid such
+ as nsr-tandem-nsk.
+ [306e00e9b5a4]
+
+ * configure, configure.in:
+ Define NO_SAVED_IDS if we don't find seteuid()
+ [8588f18345cf]
+
+ * config.h.in, configure, configure.in:
+ Add back check for setreuid() since NSK doesn't have it.
+ [43127bd703d1]
+
+ * sudoers.cat, sudoers.man.in:
+ regen
+ [af4f4b20e422]
+
+ * CHANGES:
+ sync
+ [29ca3b699c24]
+
+ * BUGS:
+ sync
+ [3593f17f72ed]
+
+ * parse.c:
+ In sudoers_lookup() return VALIDATE_NOT_OK if the runas user was
+ explicitly denied and the command matched. This fixes a long-
+ standing bug and makes: foo machine = (ALL) /usr/bin/blah foo
+ machine = (!bar) /usr/bin/blah
+
+ equivalent to: foo machine = (ALL, !bar) /usr/bin/blah
+ [2f5ee244985a]
+
+ * sudoers.pod:
+ Clarify mail_noperm
+ [3238b2d41989]
+
+2004-05-20 Aaron Spangler <aaron777@gmail.com>
+
+ * Makefile.in:
+ Missing DESTDIR in make install for sudo_noexec.la
+ [91431e821525]
+
+2004-05-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in, visudo.cat,
+ visudo.man.in:
+ regen
+ [cdfde0dcb556]
+
+ * TODO:
+ sync
+ [4799b7d8b62c]
+
+ * sudoers.pod:
+ Remove fastboot/fasthalt (who still remembers these?) and add a
+ minimal sudoedit example.
+ [19d299f233cd]
+
+ * sample.sudoers:
+ Remove fastboot/fasthalt (who still remembers these?) and add a
+ minimal sudoedit example.
+ [b1bca73d6250]
+
+ * UPGRADE, sudo.c, visudo.c:
+ filesystem -> file system
+ [1e1afaf30469]
+
+ * TROUBLESHOOTING:
+ filesystem -> file system
+ [39fb594e9338]
+
+ * CHANGES, INSTALL:
+ filesystem -> file system
+ [85948b608ffe]
+
+ * sudo.pod, sudoers.pod:
+ Fix some minor typos and formatting goofs
+ [e94d243a0b90]
+
+ * lex.yy.c:
+ regen
+ [2eed0ab1f4c4]
+
+ * visudo.pod:
+ remove my email addr
+ [b63262c0389b]
+
+ * sudo.pod, sudoers.pod, visudo.pod:
+ Use @mansectform@ and @mansectsu@ everywhere Make man page
+ references links with L<>
+ [f459f4b9ddb9]
+
+ * parse.lex:
+ Accept quoted globbing characters and pass them verbatim for
+ fnmatch()
+ [8248b86e9380]
+
+ * UPGRADE:
+ Document that /tmp/.odus is gone.
+ [3667b66af5bb]
+
+ * pathnames.h.in:
+ No longer use /tmp/.odus as a possible timestamp dir unless
+ specifically configured to do so. Instead, if no /var/run exists,
+ use /var/adm/sudo or /usr/adm/sudo.
+ [48d94c9f9ad4]
+
+ * configure:
+ No longer use /tmp/.odus as a possible timestamp dir unless
+ specifically configured to do so. Instead, if no /var/run exists,
+ use /var/adm/sudo or /usr/adm/sudo.
+ [058d7b8cf07b]
+
+ * aclocal.m4:
+ No longer use /tmp/.odus as a possible timestamp dir unless
+ specifically configured to do so. Instead, if no /var/run exists,
+ use /var/adm/sudo or /usr/adm/sudo.
+ [cf52c4c2803f]
+
+ * CHANGES:
+ No longer use /tmp/.odus as a possible timestamp dir unless
+ specifically configured to do so. Instead, if no /var/run exists,
+ use /var/adm/sudo or /usr/adm/sudo.
+ [6058c4cefcec]
+
+ * set_perms.c, sudo.c, tgetpass.c, visudo.c:
+ Preliminary changes to support nsr-tandem-nsk. Based on patches from
+ Tom Bates.
+ [2e5f81834383]
+
+ * logging.c:
+ Preliminary changes to support nsr-tandem-nsk. Based on patches from
+ Tom Bates.
+ [934bbe6872b6]
+
+ * check.c, compat.h:
+ Preliminary changes to support nsr-tandem-nsk. Based on patches from
+ Tom Bates.
+ [390b698b5924]
+
+2004-05-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ There was no 1.6.7p6.
+ [8013d2e6b062]
+
+ * BUGS, CHANGES:
+ sync
+ [c38b41f32857]
+
+ * Makefile.in:
+ add missing files to DISTFILES
+ [e6a80ad03039]
+
+ * sudo.cat, sudoers.cat, visudo.cat:
+ regen
+ [027bc9746dd5]
+
+ * sudoers.man.in:
+ regen
+ [f5e85ef686cf]
+
+ * Makefile.in:
+ Fix some line wrap and update (c) year
+ [bad1f46aa1ca]
+
+2004-04-28 Aaron Spangler <aaron777@gmail.com>
+
+ * README.LDAP:
+ Build Note
+ [7a061248249b]
+
+2004-04-07 Aaron Spangler <aaron777@gmail.com>
+
+ * Makefile.in:
+ Fix install-dirs
+ [be0726dd92e7]
+
+2004-04-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.tab.c:
+ regen
+ [3f4f0d1ab8b9]
+
+ * visudo.c:
+ In Exit() when used as a signal handler, emsg is a pointer so
+ sizeof() is wrong so make it a #define instead. Also avoid using a
+ negative exit value. Found by Aaron Campbell
+ [78716a3a3fdc]
+
+2004-03-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Remove bogus sentence about uids in a User_List. Document usernames
+ vs. uid parsing in a Runas_List.
+ [7ca510b5031c]
+
+ * parse.c, parse.h, parse.yacc, sudo.c, testsudoers.c, visudo.c:
+ If the user specified a uid with the -u flag and the uid exists in
+ the passwd file, set runas_user to the name, not the uid.
+
+ When comparing usernames in sudoers, if a name is really a uid
+ (starts with '#') compare it numerically to pw_uid.
+ [8d6935d04673]
+
+2004-03-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/kerb5.c:
+ krb5_mcc_ops should be const; Johnny C. Lam
+ [aa8c753e426e]
+
+2004-02-28 Aaron Spangler <aaron777@gmail.com>
+
+ * CHANGES, config.h.in, ldap.c:
+ Added start_tls support
+ [7ef864c15b69]
+
+2004-02-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Clean up libtool stuff for 'make distclean' and add def_data.c,
+ def_data.h to PARSESRCS.
+ [bf9bb6bb06ab]
+
+2004-02-14 Aaron Spangler <aaron777@gmail.com>
+
+ * strlcat.c, strlcpy.c:
+ Un-Fix last license munge
+ [42654b77ac71]
+
+2004-02-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [e4de6b23a4dc]
+
+ * CHANGES, RUNSON, TODO:
+ checkpoint
+ [94e1ace84d5c]
+
+ * lex.yy.c, sudo.tab.c:
+ regen
+ [8ce784505643]
+
+ * auth/passwd.c, auth/rfc1938.c, auth/secureware.c, auth/securid.c,
+ auth/securid5.c, auth/sia.c, auth/sudo_auth.c, auth/sudo_auth.h,
+ emul/search.h, emul/utime.h:
+ More to a less restrictive, ISC-style license.
+ [a31b20e48003]
+
+ * auth/kerb5.c, auth/pam.c:
+ More to a less restrictive, ISC-style license.
+ [e41f92b41216]
+
+ * auth/dce.c, auth/fwtk.c, auth/kerb4.c:
+ More to a less restrictive, ISC-style license.
+ [87534c164a52]
+
+ * auth/bsdauth.c:
+ More to a less restrictive, ISC-style license.
+ [e21be6594b58]
+
+ * auth/afs.c, auth/aix_auth.c, zero_bytes.c:
+ More to a less restrictive, ISC-style license.
+ [6d234be91c5e]
+
+ * sudoers.man.in, sudoers.pod, testsudoers.c, tgetpass.c, visudo.c,
+ visudo.man.in, visudo.pod:
+ More to a less restrictive, ISC-style license.
+ [b02aea324fd6]
+
+ * sudo_noexec.c:
+ More to a less restrictive, ISC-style license.
+ [a6da7631e0b2]
+
+ * strlcat.c, strlcpy.c, sudo.c, sudo.h, sudo.man.in, sudo.pod,
+ sudo_edit.c:
+ More to a less restrictive, ISC-style license.
+ [71cdcc241e94]
+
+ * sigaction.c, strerror.c:
+ More to a less restrictive, ISC-style license.
+ [4bccdedca58a]
+
+ * ldap.c, logging.c, logging.h, parse.c, parse.h, pathnames.h.in,
+ set_perms.c:
+ More to a less restrictive, ISC-style license.
+ [64d772d70ab3]
+
+ * getspwuid.c, goodpath.c, ins_2001.h, ins_classic.h, ins_csops.h,
+ ins_goons.h, insults.h, interfaces.c, interfaces.h:
+ More to a less restrictive, ISC-style license.
+ [520381c60a54]
+
+ * find_path.c, getprogname.c:
+ More to a less restrictive, ISC-style license.
+ [f605d5eab6f1]
+
+ * fileops.c:
+ More to a less restrictive, ISC-style license.
+ [4129a8b38a67]
+
+ * env.c:
+ More to a less restrictive, ISC-style license.
+ [d5bd859757de]
+
+ * defaults.h:
+ More to a less restrictive, ISC-style license.
+ [008f5d5743f5]
+
+ * LICENSE, Makefile.in, alloc.c, check.c, closefrom.c, compat.h,
+ defaults.c:
+ More to a less restrictive, ISC-style license.
+ [d8d7bfc8a18b]
+
+ * utime.c, version.h:
+ More to a less restrictive, ISC-style license.
+ [e2e038ad8209]
+
+ * parse.lex, parse.yacc:
+ More to a less restrictive, ISC-style license.
+ [2f5942e847a1]
+
+ * Makefile.binary:
+ More to a less restrictive, ISC-style license.
+ [1ed561734535]
+
+2004-02-13 Aaron Spangler <aaron777@gmail.com>
+
+ * sudoers2ldif:
+ Merged in LDAP Support
+ [3994c4d05947]
+
+ * ldap.c, sudo.c, sudo.h:
+ Merged in LDAP Support
+ [547eaa346fcc]
+
+ * def_data.c, def_data.h, def_data.in:
+ Merged in LDAP Support
+ [8fb255280e42]
+
+ * CHANGES, Makefile.in, README.LDAP, config.h.in, configure.in:
+ Merged in LDAP Support
+ [1038092a161e]
+
+2004-02-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.h, sudo_noexec.c:
+ Only do "extern int errno" if errno is not a macro.
+ [b2e02a08be8b]
+
+2004-02-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * set_perms.c:
+ setreuid(0, 0) fails on QNX if the euid is not already 0 so set the
+ euid first, then just call setuid(0) to set the real uid too.
+ [f08546e2e0ee]
+
+ * set_perms.c:
+ Use setresuid() and setreuid() for PERM_RUNAS when appropriate
+ instead of seteuid() which may not exist.
+ [ba508581befb]
+
+2004-02-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * LICENSE:
+ 2004
+ [37425513a342]
+
+ * INSTALL, config.h.in, configure, configure.in, ins_classic.h:
+ Add --with-pc-insults configure option
+ [7daa5294c17b]
+
+ * visudo.man.in:
+ Prefer VISUAL over EDITOR like old vipw did.
+ [996252a4ab65]
+
+2004-02-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.man.in, sudoers.man.in:
+ regen
+ [a247f1c52eb9]
+
+ * sudoers.pod:
+ Add a note that noexec is not a cure-all.
+ [9e7fc535367d]
+
+ * sudoers.pod:
+ Mention that disabling "root_sudo" is pretty pointless.
+ [f38a415afba0]
+
+ * configure, configure.in:
+ Substitute for root_sudo in sudoers.pod
+ [ce483cfc86be]
+
+ * sudo.pod:
+ Add sudoedit to the NAME section
+ [51bc453ec2f6]
+
+ * sudoers.pod:
+ Document that fact that setting ignore_dot in sudoers has no effect
+ due to the fact that find_path() is called *before* sudoers is read.
+ [6808df7e417c]
+
+2004-01-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo_edit.c:
+ Do not require _PATH_USRTMP to be set.
+ [546f3270dd10]
+
+ * BUGS, CHANGES, TODO:
+ sync
+ [4205ddeab781]
+
+ * sudo.man.in:
+ regen
+ [e2143690a88a]
+
+ * sudo.pod:
+ Clarify that when sudo is run by root with the SUDO_USER variable
+ set, the sudoers lookup happens for root and not the SUDO_USER user.
+ [47207bec1bdf]
+
+2004-01-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c, auth/sudo_auth.c, interfaces.c, logging.c, parse.c,
+ set_perms.c, sigaction.c, sudo.c, tgetpass.c:
+ Use the SET, CLR and ISSET macros.
+ [a8b0d7f1e8fd]
+
+ * fnmatch.c:
+ Use the SET, CLR and ISSET macros.
+ [1afbcba22ba6]
+
+ * defaults.c, env.c:
+ Use the SET, CLR and ISSET macros.
+ [2f39431e0a49]
+
+ * interfaces.h:
+ MAIN was replaced with _SUDO_MAIN some time ago.
+ [ea1b38f2ac9d]
+
+ * sudo.c:
+ Don't look at prev_user until after we've parsed sudoers and done
+ the password check. That way, if sudo/sudoedit is run from a root
+ process that was invoked by sudo, we check sudoers for root, not the
+ previous user. This makes sudoedit much more useful and means that
+ for the sudo case, we get correct logging on who actually ran the
+ command.
+ [431dfbf20552]
+
+2004-01-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo_edit.c:
+ Add a comment describing why we need to be notified about our child
+ stopping.
+ [0bec3ce4b49d]
+
+2004-01-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * def_data.c, def_data.in:
+ Update the noexec variable descriptions
+ [9cb7f1aa0e57]
+
+ * sudoers.man.in, sudoers.pod:
+ noexec now replaces more than just execve()
+ [23cbdc0ee95c]
+
+ * sudo_noexec.c:
+ Alas, all the world does not go through execve(2). Many systems
+ still have an execv(2) system call, Linux 2.6 provides fexecve(2)
+ and it is not uncommon for libc to have underscore ('_') versions of
+ the functions to be used internally by the library. Instead of
+ stubbing all these out by hand, define a macro and let it do the
+ work. Extra exec functions pointed out by Reznic Valery.
+ [9fa0cd871b0c]
+
+ * sudo.c, sudo_edit.c:
+ Fix suspending the editor in -e mode. Because we do a fork() first
+ we need to be notified when the child has been stopped and then send
+ that same signal to ourself so the shell can do its job control
+ thing.
+ [773165eb6057]
+
+ * visudo.c:
+ Use WIFEXITED and WEXITSTATUS macros. If there are systems out there
+ that want to run sudo that still don't support these we can try to
+ deal with that later.
+ [6af68e4aff60]
+
+ * lex.yy.c:
+ regen
+ [403435317d5d]
+
+ * sudo.man.in, sudo.pod, sudoers.man.in, sudoers.pod:
+ Document sudo -e / sudoedit
+ [a80f6ea910af]
+
+ * configure, configure.in:
+ fix typo
+ [5020fcdc27f4]
+
+ * config.h.in, configure.in:
+ Add SET/CLR/ISSET
+ [03ff57286e7e]
+
+2004-01-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Allow non-exclusive flags when invoked as sudoedit. Pretty print the
+ long usage() line to not wrap (assumes 80 char display)
+ [3941fa4004bb]
+
+ * Makefile.in, sudo.c:
+ If sudo is invoked as "sudoedit" the -e flag is implied and no other
+ flags are permitted.
+ [929670b01293]
+
+ * sudo.h:
+ Add a new flag, -e, that makes it possible to give users the ability
+ to edit files with the editor of their choice as the invoking user,
+ not the runas user. Temporary files are used for the actual edit and
+ the temp file is copied over the original after the editor is done.
+ [c4051414c1f4]
+
+ * Makefile.in, parse.c, parse.lex, sudo.c, sudo_edit.c:
+ Add a new flag, -e, that makes it possible to give users the ability
+ to edit files with the editor of their choice as the invoking user,
+ not the runas user. Temporary files are used for the actual edit and
+ the temp file is copied over the original after the editor is done.
+ [37ac05c8ac3c]
+
+ * env.c, sudo.c:
+ If real uid == 0 and the SUDO_USER environment variables is set, use
+ that to determine the invoking user's true identity. That way the
+ proper info gets logged by someone who has done "sudo su" but still
+ uses sudo to as root. We can't do this for non-root users since that
+ would open up a security hole, though perhaps it would be acceptable
+ to use getlogin(2) on OSes where this a system call (and doesn't
+ just look in the utmp file).
+ [c2f9198708a1]
+
+ * pathnames.h.in:
+ Add _PATH_TMP, _PATH_VARTMP and _PATH_USRTMP
+ [7d9e5768df93]
+
+ * config.h.in, configure, configure.in:
+ Add check for fchown(2)
+ [a85df18798ed]
+
+2004-01-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Back out portions of the -i commit that set NewArgv[0] in
+ set_runaspw. It is far to late to set NewArgv[0] there and will have
+ no effect anyway as cmnd and safe_cmnd have already been set.
+ [c2d343430c1c]
+
+ * visudo.c, visudo.pod:
+ Prefer VISUAL over EDITOR like old vipw did.
+ [ae32f477cea3]
+
+2004-01-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c, sudo.c:
+ In -i mode always set new environment based on the runas user's
+ passwd entry.
+ [fa653b7887a8]
+
+2004-01-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.man.in, sudo.pod:
+ Document the new -i flag and sync SYNOPSIS section with usage() in
+ sudo.c. Also sort the flags in the OPTIONS section.
+ [6aabc0ffc47e]
+
+ * sudo.c, sudo.h:
+ o Add -i that acts similar to "su -", based on patches from David J.
+ MacKenzie o Sort the flags in the usage message
+ [c0fe7d6beffd]
+
+ * sudoers.man.in, sudoers.pod:
+ Add a missing @runas_default@ substitution.
+ [60516fe2d090]
+
+2004-01-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Change euid to runas user before calling find_path(). Unfortunately,
+ though runas_user can be modified in sudoers we haven't parsed
+ sudoers yet.
+ [f469fdf2e313]
+
+ * sudoers.man.in, sudoers.pod:
+ Add missing defintion of Parameter_List and use single pipes in the
+ Defaults EBNF definition.
+ [f7bed6e909bf]
+
+ * sudo.c:
+ Fix a bug when set_runaspw() is used as a callback. We don't want to
+ reset the contents of runas_pw if the user specified a user via the
+ -u flag.
+
+ Avoid unnecessary passwd lookups in set_authpw(). In most cases we
+ already have the info in runas_pw.
+ [efc35623ba09]
+
+2004-01-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ Add Stan Lee / Uncle Ben quote to the lecture from RedHat
+ [ebd5a76ccd7e]
+
+ * sudo.h:
+ Update sudo_getepw() proto and add one for set_runaspw()
+ [6ed65795c17f]
+
+ * parse.c:
+ If we can't stat the command as root, try as the runas user instead.
+ [ae713fca0e15]
+
+ * testsudoers.c, visudo.c:
+ Add stub set_runaspw() function
+ [42aa37050053]
+
+ * sudo.c:
+ Add set_runaspw() function to fill in runas_pw. This will be used as
+ a callback to update runas_pw when the runas user changes.
+ [e570aa0088d0]
+
+ * env.c, sudo.c:
+ PERM_RUNAS -> PERM_FULL_RUNAS
+ [51eec6f9e89a]
+
+ * set_perms.c, sudo.h:
+ Rename PERM_RUNAS -> PERM_FULL_RUNAS and add a PERM_RUNAS that just
+ changes the euid.
+ [877c6fe4d12c]
+
+ * getspwuid.c:
+ Make sudo_pwdup() act like OpenBSD pw_dup() and allocate memory in
+ one chunk for easy free()ing. Also change it from static to extern.
+ [ab503260a7ec]
+
+ * defaults.c, defaults.h:
+ Add callback support
+ [a61c4ca983fb]
+
+ * mkdefaults:
+ Add a callback field and use it for runas_default
+ [96b69c27df5e]
+
+ * def_data.c, def_data.in:
+ Add a callback field and use it for runas_default
+ [d3e9f06872b8]
+
+2004-01-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/fwtk.c:
+ Add support for chalnecho and display server responses used by fwtk
+ >= 2.0
+ [b1870f7aaf0d]
+
+2004-01-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.man.in, sudoers.pod:
+ ld.so is ld.so.1 on solaris
+ [2bf9a123fa4c]
+
+ * Makefile.in, config.h.in, configure, configure.in, sudo.c, sudo.h:
+ Use closefrom() instead of doing the equivalent inline.
+ [7e3ef6072884]
+
+ * closefrom.c:
+ closefrom(3) for systems w/o it
+ [35caf58bb636]
+
+2004-01-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.man.in:
+ Update from .pod file.
+ [d4c94fc0e0c9]
+
+ * configure, configure.in:
+ Substitute noexec_file for the sudoers man page
+ [203d3376a551]
+
+ * sudo.man.in, sudo.pod:
+ Mention noexec
+ [014375ddbb06]
+
+ * sudoers.man.in, sudoers.pod:
+ Document noexec
+ [49a65d06201f]
+
+ * auth/pam.c, config.h.in, configure.in:
+ Move PAM_CONST macro definition from config.h to pam.c where it
+ belongs. We can't have this in config.h since that gets included too
+ early.
+ [e64748071637]
+
+ * auth/pam.c, config.h.in, configure, configure.in:
+ Some PAM implementations put their headers in /usr/include/pam
+ instead of /usr/include/security.
+ [8cc749e9575c]
+
+ * configure.in:
+ I missed changing the EXEC macro -> EXECV here when I changed this
+ in config.h.in and sudo.c a while ago.
+ [6f5afac7789f]
+
+ * acsite.m4:
+ OpenBSD vax/m88k/hppa don't do shared libs
+ [e4901d958bb7]
+
+ * configure, configure.in:
+ o merge the hpux case entries into a single entry w/ its own sub-
+ case statement. o HP-UX >= 11 support getspnam(), use it in
+ preference to getprpwuid()
+ [0caad428894e]
+
+ * configure, configure.in:
+ eval $shrext so that it expands nicely on MacOS X
+ [40419343eef8]
+
+ * Makefile.in:
+ Don't lie about making a module, it does the wrong thing on mach
+ [7629b28f5688]
+
+ * ltmain.sh:
+ Remove requirement that libs must begin with "lib". They don't when
+ we point directly at the lib using LD_PRELOAD or its equivalent.
+ [d66f3de6ec85]
+
+ * acsite.m4:
+ Disable support for c++, f77 and java. We don't need it, it takes a
+ lot of time, and it hosed our check for shared lib support.
+ [4f5749c52ce4]
+
+ * configure:
+ regen
+ [160865e9d15f]
+
+ * configure.in:
+ Call AC_ENABLE_SHARED and check the status of enable_shared to know
+ when shared libs are available.
+ [42504c1668fc]
+
+ * acsite.m4:
+ Duh, OpenBSD suports shared libs too
+ [8e3cd9417475]
+
+ * config.h.in, configure.in:
+ Only OpenPAM and Linux PAM use const qualifiers.
+ [b2f76476e866]
+
+ * configure, configure.in:
+ o No need to check for sed, libtool config does that for us o move
+ check for --with-noexec until after libtool magic is run so we can
+ use $can_build_shared and $shrext
+ [668c656e89cc]
+
+ * ltmain.sh:
+ Don't print a bunch of crap about library installs since we are not
+ really installing a library.
+ [83fbcad29fe4]
+
+ * env.c:
+ Make format_env() varargs Add noexec support for Darwin, MacOS X,
+ Irix, and Tru64
+ [468885d75d10]
+
+ * acsite.m4, ltconfig, ltmain.sh:
+ Update to libtool 1.5 with local changes: o no ldconfig in the
+ finish step o assume no libprefix or version is needed
+ [4961cffc3797]
+
+ * sudo_noexec.c:
+ Fix compilation under K&R
+ [8b309bf0b1b2]
+
+2004-01-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ checkpoint
+ [3c368badab32]
+
+ * sudo_noexec.c:
+ stub execve() that just returns EACCES; used for noexec
+ functionality
+ [1297acae283a]
+
+ * sudo.tab.h:
+ Regen w/ updated byacc from OpenBSD; fixes a gcc 3.2 issue with
+ generated code.
+ [dcab78c49273]
+
+ * sudo.tab.c:
+ Regen w/ updated byacc from OpenBSD; fixes a gcc 3.2 issue with
+ generated code.
+ [0a61c735eabe]
+
+2004-01-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * def_data.c, def_data.h, def_data.in:
+ Move the environment defaults to the end and shorten a few of the
+ descriptions.
+ [66787b9c612c]
+
+ * configure, configure.in:
+ no shared libs on ultris or convexos
+ [2c5f3c456e32]
+
+ * Makefile.in, configure, configure.in:
+ Build sudo_noexec shared object using libtool; could use some
+ cleanup.
+ [373f483555dd]
+
+ * acsite.m4, ltconfig, ltmain.sh:
+ libtool scaffolding
+ [c903a42e3d90]
+
+ * parse.yacc, sudo.tab.c:
+ Merge the NOPASSWD/PASSWD and NOEXEC/EXEC rules so that order is not
+ important.
+ [c6e8a34639a4]
+
+ * defaults.c, env.c, lex.yy.c, parse.c, parse.h, parse.lex,
+ parse.yacc, pathnames.h.in, sudo.c, sudo.h, sudo.tab.c:
+ update copyright year
+ [a16372ae1711]
+
+ * configure, configure.in, defaults.c, env.c, pathnames.h.in:
+ Add _PATH_SUDO_NOEXEC and corresponding --with-noexec configure
+ option. The default value of noexec_file is set to this.
+ [7d88e1d3c494]
+
+ * def_data.c, def_data.h, def_data.in, env.c, lex.yy.c, parse.c,
+ parse.h, parse.lex, parse.yacc, sudo.c, sudo.h, sudo.tab.c,
+ sudo.tab.h:
+ Add support for preloading a shared object containing a dummy
+ execve() function that just sets error and returns -1. This adds a
+ "noexec_file" option to load the filename as well as a "noexec" flag
+ to enable it unconditionally. There is also a NOEXEC tag that can be
+ attached to specific commands and an EXEC tag to disable it.
+ [c8b6712feb91]
+
+ * mkdefaults:
+ add missing newline to usage statement
+ [e84746618362]
+
+ * config.h.in, sudo.c:
+ Rename EXEC macro -> EXECV
+ [ddaa0c027299]
+
+ * logging.c:
+ Don't truncate usernames to 8 characters in the log message.
+ [f62a20f27075]
+
+ * check.c, sudoers.man.in, sudoers.pod:
+ Update copyright year
+ [ca9964054085]
+
+ * check.c, def_data.c, def_data.h, def_data.in, sudoers.man.in,
+ sudoers.pod:
+ Add a new option, lecture_file, that can be used to point to a
+ custom sudo lecture.
+ [940133231216]
+
+2003-12-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/aix_auth.c, auth/bsdauth.c, auth/fwtk.c, auth/pam.c,
+ auth/sudo_auth.c:
+ Add a zero_bytes() function to do the equivalent of bzero in such a
+ way that will heopfully not be optimized away by sneaky compilers.
+ [161b6d74bfb4]
+
+ * zero_bytes.c:
+ Add a zero_bytes() function to do the equivalent of bzero in such a
+ way that will heopfully not be optimized away by sneaky compilers.
+ [d035abf0af94]
+
+ * Makefile.in, sudo.h:
+ Add a zero_bytes() function to do the equivalent of bzero in such a
+ way that will heopfully not be optimized away by sneaky compilers.
+ [ff136de3e255]
+
+ * err.c:
+ Use #ifdef __STDC__, not #if __STDC__.
+ [6889dd6bc51a]
+
+2003-12-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkdefaults:
+ Always put at least one space between the def_* macro name and its
+ definition.
+ [6b3ad0e6619a]
+
+ * configure, configure.in:
+ Adjust code for --without-lecture to match new values.
+ [062aa788a6b9]
+
+ * visudo.man.in:
+ regen after pasto fix
+ [3deec16906c0]
+
+ * sudoers.man.in, sudoers.pod:
+ Document that "lecture" has changed from a flag to a tuple.
+ [e2c03062b533]
+
+ * check.c, def_data.c, def_data.h, def_data.in, defaults.c,
+ defaults.h, logging.c, mkdefaults, parse.c, sudo.c, sudo.h:
+ Add support for tuples in def_data.in; these are implemented as an
+ enum type. Currently there is only a single tuple enum but in the
+ future we may have one tuple enum per T_TUPLE entry in def_data.in.
+ Currently listpw, verifypw and lecture are tuples. This avoids the
+ need to have two entries (one ival, one str) for pwflags and syslog
+ values.
+
+ lecture is now a tuple with the following values: never, once,
+ always
+
+ We no longer use both an int and string entry for syslog facilities
+ and priorities. Instead, there are logfac2str() and logpri2str()
+ functions that get used when we need to print the string values.
+ [5293f946c836]
+
+ * auth/aix_auth.c, auth/bsdauth.c, auth/fwtk.c, auth/pam.c,
+ auth/rfc1938.c, auth/securid5.c, auth/sia.c, auth/sudo_auth.c,
+ check.c, def_data.h, defaults.c, defaults.h, env.c, find_path.c,
+ logging.c, mkdefaults, parse.c, parse.yacc, set_perms.c, sudo.c,
+ sudo.tab.c, visudo.c:
+ Create def_* macros for each defaults value so we no longer need the
+ def_{flag,ival,str,list,mode} macros (which have been removed). This
+ is a step toward more flexible data types in def_data.in.
+ [009c02934106]
+
+ * TODO:
+ checkpoint
+ [0a99a4bb5d15]
+
+2003-12-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ If we are in -k/-K mode, just spew to stderr. It is not unusual for
+ users to place "sudo -k" in a .logout file which can cause sudo to
+ be run during reboot after the YP/NIS/NIS+/LDAP/etc daemon has died.
+ Previously, this would result in useless mail and logging.
+ [d282e7ed63af]
+
+2003-12-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.pod:
+ fix pasto in VISUAL description
+ [1c6a6148b5f9]
+
+2003-12-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [f44312c63799]
+
+ * CHANGES:
+ checkpoint
+ [0c42e38f78d5]
+
+ * TROUBLESHOOTING:
+ Some OSes (like Solaris) allow export w/ nosuid too
+ [973ce85ffa12]
+
+2003-08-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat.h:
+ We don't use FD_ZERO anymore so just define FD_SET (if not already
+ there).
+ [d1c8c11905cd]
+
+2003-06-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c:
+ Fix a core dump on Solaris by preserving the pam_handle_t we used
+ during authentication for pam_prep_user(). If we didn't authenticate
+ (ie: ticket still valid), we call pam_init() from pam_prep_user().
+ This is something of a hack; it may be better to change the auth API
+ and add an auth_final() function that acts like pam_prep_user().
+ [f787de49b175]
+
+2003-06-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * set_perms.c:
+ Add explicit declaration of printerr variable in function header
+ (was defaulting to int which is OK but oh so K&R :-). From Theo.
+ [492c2358783f]
+
+2003-06-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure.in:
+ s/HAVE_STOW/USE_STOW/
+ [4b99e1824ece]
+
+ * logging.c:
+ Also exit waitpid() loop when pid == 0. Fixes a problem where the
+ sudo process would spin eating up CPU until sendmail finished when
+ it has to send mail.
+ [ec3d5792b9b4]
+
+2003-05-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * fnmatch.c:
+ Remove advertising clause, UCB has disavowed it
+ [43a26bbd6628]
+
+ * fnmatch.3:
+ Remove advertising clause, UCB has disavowed it
+ [3ff24291bcfa]
+
+2003-05-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ Don't assume that getgrnam() calls don't modify contents of struct
+ passwd returned by getpwnam(). On FreeBSD w/ NIS this can happen.
+ Based on a patch from Kirk Webb.
+ [5574c68f60f3]
+
+2003-05-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ missing ;;
+ [22378f2a9d31]
+
+ * configure.in:
+ darwin has a broken setreuid() in at least some versions
+ [d572aed930d2]
+
+ * env.c:
+ Fix an off by one error when reallocating the environment; Kevin Pye
+ [3d98e7cf097a]
+
+2003-04-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Fix User_Spec definition; SEKINE Tatsuo
+ [49b0da65e090]
+
+2003-04-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * HISTORY:
+ More info on the early days from Coggs.
+ [9381ca10b06b]
+
+2003-04-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/kerb5.c:
+ remove errant semicolon that prevented compilation under heimdal
+ [d2f2bb73a598]
+
+2003-04-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * testsudoers.c, tgetpass.c, visudo.c, visudo.man.in, visudo.pod:
+ add DARPA credit on affected files
+ [7020785ee50d]
+
+ * sudoers.pod:
+ add DARPA credit on affected files
+ [83b46318750b]
+
+ * sigaction.c, strerror.c, sudo.c, sudo.h, sudo.man.in, sudo.pod,
+ sudoers.man.in:
+ add DARPA credit on affected files
+ [d8adf1c2ba22]
+
+ * set_perms.c:
+ add DARPA credit on affected files
+ [3d79fdabb582]
+
+ * pathnames.h.in:
+ add DARPA credit on affected files
+ [e334cdda422f]
+
+ * logging.c, parse.c:
+ add DARPA credit on affected files
+ [8f75f822755b]
+
+ * auth/passwd.c, auth/rfc1938.c, auth/secureware.c, auth/securid.c,
+ auth/securid5.c, auth/sia.c, auth/sudo_auth.c, fileops.c,
+ find_path.c, getprogname.c, getspwuid.c, goodpath.c, interfaces.c,
+ interfaces.h:
+ add DARPA credit on affected files
+ [da66e28fb3f5]
+
+ * auth/kerb5.c, auth/pam.c:
+ add DARPA credit on affected files
+ [15da3021b49c]
+
+ * auth/afs.c, auth/aix_auth.c, auth/bsdauth.c, auth/dce.c,
+ auth/fwtk.c, auth/kerb4.c, parse.lex, parse.yacc, utime.c,
+ version.h:
+ add DARPA credit on affected files
+ [868d54cbddea]
+
+ * env.c:
+ add DARPA credit on affected files
+ [90239f51ef0a]
+
+ * defaults.c, defaults.h:
+ add DARPA credit on affected files
+ [6a64205fd1eb]
+
+ * compat.h:
+ add DARPA credit on affected files
+ [316a735783c4]
+
+ * Makefile.in, alloc.c, check.c:
+ add DARPA credit on affected files
+ [cd939e05c810]
+
+ * LICENSE:
+ slightly different wording for the darpa credit
+ [e468909c4a21]
+
+2003-04-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * LICENSE:
+ Add DARPA credit
+ [8eb20e2cd63e]
+
+2003-04-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/kerb5.c:
+ Use krb5_princ_component() instead of krb5_princ_realm() for MIT
+ Kerberos like we did before I messed things up ;-)
+
+ Use krb5_principal_get_comp_string() to do the same thing w/
+ Heimdal. I'm not sure if the component should be 0 or 1 in this
+ case.
+
+ #define ENCTYPE_DES_CBC_MD5 ETYPE_DES_CBC_MD5 for Heimdal since
+ older versions lack ENCTYPE_DES_CBC_MD5. This is gross and there
+ should be a configure check for this I guess.
+ [74919a3933fe]
+
+2003-04-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sample.sudoers:
+ builtin -> built-in; Jason McIntyre
+ [027f2187923e]
+
+ * TROUBLESHOOTING, config.h.in, configure, configure.in:
+ builtin -> built-in; Jason McIntyre
+ [70b81ac48943]
+
+ * sudoers.pod:
+ built in -> built-in; Jason McIntyre
+ [da658ef5138d]
+
+2003-04-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ checkpoint for 1.6.7p3
+ [da85f989fadf]
+
+ * HISTORY:
+ Update info on the early years @ SUNY-Buffalo from Cliff Spencer.
+ Amazingly, sudo source from 1985 is available via groups.google.com
+ [39e0fc85b89f]
+
+ * sudo.c:
+ Don't change rl.rlim_max for RLIMIT_CORE. We need only set
+ rl.rlim_cur to 0 to turn off core dumps. This may be needed for the
+ RLIMIT_CORE restoration on some OSes.
+ [7e2c1a7adfd8]
+
+2003-04-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/kerb5.c:
+ Make this compile on Heimdal and MIT Kerberos 5
+ [44c07d615868]
+
+ * config.h.in, configure, configure.in:
+ Check for heimdal even if we found krb5-config and define
+ HAVE_HEIMDAL.
+ [aba0126f0059]
+
+ * auth/kerb5.c:
+ Replace ETYPE_DES_CBC_MD5 with ENCTYPE_DES_CBC_MD5. The former is no
+ longer defined by MIT kerb5 (though it used to be and indeed remains
+ so in Heimdal).
+ [e5a6c64d7cd5]
+
+2003-04-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkinstalldirs:
+ Remove newer stuff that passes multiple (possibly duplicate)
+ directories to "mkdir -p" since that seems to break on Tru64 Unix at
+ least. This basically brings back what shipped with sudo 1.6.6.
+ [f2a1abd872b3]
+
+2003-04-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/kerb5.c:
+ Correct number of args to krb5_principal_get_realm() and fix an
+ unclosed comment that hid the bug.
+ [0b37f8ce7824]
+
+ * configure:
+ regen
+ [1876cb840fe0]
+
+ * configure.in:
+ ++version
+ [480aff7c048e]
+
+ * README:
+ ++version
+ [488e0bbff613]
+
+ * Makefile.in:
+ ++version
+ [97ef63cedc38]
+
+ * INSTALL.binary:
+ ++version
+ [a506204e77d0]
+
+ * INSTALL:
+ ++version
+ [555aeba5c2bf]
+
+ * CHANGES, version.h:
+ ++version
+ [f66985a64063]
+
+ * BUGS:
+ ++version
+ [ea3573432412]
+
+ * configure.in:
+ use krb5-config to determine Kerberos V details if it exists
+ [7b46bbdaf774]
+
+ * alloc.c, auth/fwtk.c, auth/rfc1938.c, auth/securid.c,
+ auth/securid5.c, auth/sia.c, check.c, compat.h, defaults.c, env.c,
+ find_path.c, interfaces.c, logging.c, parse.c, sudo.c, sudo.h,
+ testsudoers.c, visudo.c:
+ Use warn/err and getprogname() throughout. The main exception is
+ openlog(). Since the admin may be filtering logs based on the
+ program name in the log files, hard code this to "sudo".
+ [9f180d015cfa]
+
+ * Makefile.in:
+ Add getprogname.c and err.c
+ [d411c54a07dc]
+
+ * configure:
+ regen
+ [6d585d391acc]
+
+ * config.h.in, configure.in:
+ Add checks for getprognam(), __progname and err.h
+ [bcbccf61d34a]
+
+ * emul/err.h:
+ For systems withour err/warn functions.
+ [1b33118884d9]
+
+ * err.c:
+ For systems withour err/warn functions.
+ [26721f6b041f]
+
+ * getprogname.c:
+ For systems neither getprogname() nor __progname; uses Argv[0].
+ [841cf42af1eb]
+
+2003-04-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ checkpoint for 1.6.7p1
+ [5bfdaf441dce]
+
+ * sudo.c, testsudoers.c:
+ fix strlcpy() rval check (innocuous)
+ [e05ac7e0d1f3]
+
+ * check.c:
+ oflow detection in expand_prompt() was faulty (false positives). The
+ count was based on strlcat() return value which includes the length
+ of the entire string.
+ [086c5a0acb25]
+
+2003-03-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON, TODO:
+ checkpoint for the sudo 1.6.7 release
+ [096bab4da29a] [SUDO_1_6_7]
+
+ * CHANGES:
+ checkpoint for the sudo 1.6.7 release
+ [87322187ed78]
+
+2003-03-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ g/c unused variable
+ [c57cd4a17765]
+
+ * configure:
+ regen
+ [e7c1f581dfac]
+
+ * configure.in:
+ use man sections 8 and 5 for csops
+ [87de581bda88]
+
+2003-03-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [cb1433a9c7a1]
+
+ * configure.in:
+ Add -lskey or -lopie directly to SUDO_LIBS instead of having
+ AC_CHECK_LIB() add them to LIBS. Fixes visudo linkage.
+ [ac5667978939]
+
+ * configure:
+ regen
+ [638459118a2a]
+
+ * configure.in:
+ Add --with-blibpath for AIX. An alternate libpath may be specified
+ or
+ -blibpath support can be disabled. Also change conifgure such that
+ -blibpath is not specified if no -L libpaths were added to
+ SUDO_LDFLAGS.
+ [c7d17b480cad]
+
+ * aclocal.m4:
+ Add --with-blibpath for AIX. An alternate libpath may be specified
+ or
+ -blibpath support can be disabled. Also change conifgure such that
+ -blibpath is not specified if no -L libpaths were added to
+ SUDO_LDFLAGS.
+ [37022e991575]
+
+ * INSTALL:
+ Add --with-blibpath for AIX. An alternate libpath may be specified
+ or
+ -blibpath support can be disabled. Also change conifgure such that
+ -blibpath is not specified if no -L libpaths were added to
+ SUDO_LDFLAGS.
+ [4b4bbe5bbe1b]
+
+ * configure.in:
+ add AIX blibpath support
+ [16ba788bf086]
+
+ * INSTALL, configure.in:
+ --with-skey and --with-opie now take an option directory argument
+ This obsoletes a --with-csops hack (/tools/cs/skey)
+
+ Also remove the remaining direct uses of "echo"
+ [5b4986a90c03]
+
+2003-03-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ Detect KTH Kerberos IV and deal with it. Also make -lroken optional
+ for KTH Kerberos IV and V.
+ [119f97b48e18]
+
+ * aclocal.m4:
+ Add SUDO_APPEND_LIBPATH function that add -L/path/to/dir (and
+ -R/path/to/dir if $with_rpath) to the specified variable.
+ [e55e49d076ce]
+
+ * INSTALL, configure.in:
+ Add -R/path/to/libs for Solaris and SVR4. There is a new configure
+ option, --with-rpath to control this behavior.
+ [d4730c5399ab]
+
+ * configure.in:
+ for kerb4 put libdes after libkrb on the link line
+ [5c566100eab6]
+
+ * auth/kerb4.c:
+ typo
+ [6541b72b64a3]
+
+ * configure.in:
+ fix kerberos lib check when a path is specified
+ [ae833a914c6f]
+
+ * logging.c:
+ Fix boolean thinko in SIGCHLD reaper and call reapchild after
+ sending mail instead of doing a conditional sudo_waitpid.
+ [86fa9a35df5a]
+
+2003-03-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [e6275cf528ba]
+
+ * configure.in:
+ replace =DIR with [=DIR] where sensible
+ [c39a59173b38]
+
+ * configure.in:
+ o Use AC_MSG_* instead of "echo" o New Kerberos include/lib
+ detection based on openssh's configure.in
+ [5b7a340912df]
+
+ * INSTALL:
+ --with-kerb4 and --with-kerb5 now take an optional argument.
+ [71ed87fc9c64]
+
+2003-03-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/securid.c:
+ Kill remaining strcpy(), the programmer's guide says username is 32
+ bytes.
+ [bdba70fcd08d]
+
+ * auth/kerb4.c:
+ trat uid_t as unsigned long for printf and use snprintf, not sprintf
+ [8072f5f8966d]
+
+ * auth/rfc1938.c:
+ use snprintf
+ [fc0c70c665fe]
+
+2003-03-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/afs.c, auth/aix_auth.c, auth/bsdauth.c, auth/dce.c,
+ auth/fwtk.c, auth/kerb4.c, auth/kerb5.c, auth/pam.c, auth/passwd.c,
+ auth/rfc1938.c, auth/sudo_auth.c:
+ update copyright year
+ [b0a10ccb1d0e]
+
+ * sudo.man.in, sudoers.man.in, visudo.man.in:
+ update copyright year
+ [8fce0034eb51]
+
+ * LICENSE, Makefile.in, aclocal.m4, alloc.c, check.c, compat.h,
+ configure.in, env.c, find_path.c, interfaces.c, logging.c, parse.c,
+ parse.lex, parse.yacc, set_perms.c, sudo.c, sudo.h, sudo.pod,
+ sudoers.pod, testsudoers.c, version.h, visudo.c, visudo.pod:
+ update copyright year
+ [d541e75fe520]
+
+ * check.c, env.c, sudo.c:
+ Cast [ug]ids to unsigned long and printf with %lu
+ [2ede64d3592b]
+
+ * configure:
+ regen
+ [c7c3245bdf3e]
+
+ * configure.in:
+ correct error messages for --with-sudoers-{mode,uid,gid}
+ [77fc15b1c9db]
+
+ * alloc.c:
+ make the malloc(0) error specific to each function to aid tracking
+ down bugs.
+ [a58c34374b4b]
+
+ * alloc.c:
+ deal with platforms where size_t is signed and there is no SIZE_MAX
+ or SIZE_T_MAX
+ [7192abb4ab4e]
+
+ * auth/kerb5.c:
+ Make this compile w/ Heimdal and fix some gcc warnings.
+ [f52f026f31c2]
+
+ * sudo.c:
+ Use stat_sudoers macro so --with-stow can work
+ [c3674735c139]
+
+ * INSTALL, config.h.in, configure, configure.in:
+ Add support for --with-stow based on patches from Robert Uhl
+ [b274cc1dd52c]
+
+ * env.c:
+ fix indentation
+ [110d9f1721b1]
+
+ * configure.in:
+ back out rev 1.352
+ [1eee91c83f11]
+
+ * lex.yy.c:
+ regen
+ [72fba1c9590b]
+
+ * parse.lex:
+ use strlcpy, not strncpy
+ [4faccbaeccef]
+
+ * set_perms.c:
+ Fix typo; check pw_uid, not pw_gid after setusercontext() failure.
+ [33bf0d18fdc1]
+
+ * logging.c:
+ use pid_t
+ [3e0536993d2c]
+
+2003-03-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * strlcat.c, strlcpy.c:
+ Make gcc shutup about unused rcsid
+ [1669a0c74e9e]
+
+ * interfaces.c:
+ Move the n == 0 check for the non-getifaddrs cas
+ [2460be061b2a]
+
+ * auth/rfc1938.c:
+ skeychallenge() on NetBSD take a size parameter
+ [05acc2012801]
+
+ * configure:
+ regen
+ [24bccf4749e8]
+
+ * configure.in:
+ put -ldl after -lpam, not before; fixes static linking on Linux
+ [7f06b7b2b4d8]
+
+ * interfaces.c:
+ Avoid malloc(0) and fix the loop invariant for the getifaddrs()
+ case.
+ [239a55068646]
+
+ * sudo.cat, sudoers.cat, visudo.cat:
+ regen
+ [4a2eed3981ca]
+
+ * sudo.man.in, sudoers.man.in, visudo.man.in:
+ regen
+ [2c96ea2cf930]
+
+ * Makefile.in:
+ Preserve copyright notice from .pod file in .man.in file
+ [519fbd09aebc]
+
+ * visudo.pod:
+ Add sudoers(5) to SEE ALSO
+ [77ecfe3aedf1]
+
+2003-03-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lex.yy.c:
+ regen
+ [6f5751ce0b74]
+
+ * parse.lex:
+ Don't assume libc can realloc() a NULL string. If malloc/realloc
+ fails, make sure we just return; yyerror() is not terminal.
+ [1b8618623708]
+
+ * lex.yy.c:
+ regen
+ [5d31b46191c6]
+
+ * parse.lex:
+ simplify fill_args a little and use strlcpy for paranoia
+ [0ea35a55542b]
+
+ * sudo.tab.c:
+ regen
+ [5a8d508d708b]
+
+ * check.c, env.c, find_path.c, parse.c, parse.yacc, sudo.c,
+ testsudoers.c:
+ Use strlc{at,py} for paranoia's sake and exit on overflow. In all
+ cases the strings were either pre-allocated to the correct size of
+ length checks were done before the copy but a little paranoia can go
+ a long way.
+ [e73d28f1d14e]
+
+ * sudo.h:
+ Add strlc{at,py} protos
+ [748ffc7fc7f4]
+
+ * env.c, interfaces.c:
+ Use erealloc3()
+ [47f2cb46aba8]
+
+ * configure:
+ regen
+ [e7e2fb79f935]
+
+ * alloc.c:
+ Oflow test of nmemb > SIZE_MAX / size is fine (don't need >=). Use
+ memcpy() instead of strcpy() in estrdup() so this is strcpy()-free.
+ [7e0fa4d6fc1d]
+
+ * sudo.c:
+ snprintf() a uid as %lu, not %ld to match the MAX_UID_T_LEN test in
+ configure.
+ [09ea4d3959e9]
+
+ * aclocal.m4:
+ In MAX_UID_T_LEN test cast uid_t to unsigned long, just unsigned.
+ [31b4fdfdb8bf]
+
+2003-03-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Use snprintf() for paranoia
+ [a2659ceb46de]
+
+ * parse.yacc:
+ Use emalloc2 and erealloc3
+ [90a069842401]
+
+ * Makefile.in:
+ strlc{at,py} for those w/o it
+ [bac82dc916ee]
+
+ * strlcat.c, strlcpy.c:
+ stlc{at,py} for those w/o it.
+ [ce7254f5db09]
+
+ * config.h.in, configure, configure.in:
+ Add stlc{at,py} for those w/o it.
+ [00f08219657a]
+
+ * alloc.c, sudo.h:
+ Add erealloc3(), a realloc() version of emalloc2().
+ [c96eaf08bbed]
+
+ * interfaces.c, sudo.c:
+ Use emalloc2() to allocate N things of a certain size.
+ [1e0aba365555]
+
+ * alloc.c, sudo.h:
+ Add emalloc2() -- like calloc() but w/o the bzero and with
+ error/oflow checking.
+ [292150bc4153]
+
+ * alloc.c:
+ Error out on malloc(0); suggested by theo
+ [995279e81326]
+
+2003-03-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ fix a typo; David Krause
+ [f161213a17ab]
+
+2003-03-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod:
+ fix typo
+ [3ae5ad9a351a]
+
+2003-03-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ Remove DYLD_ from the environment for MacOS X; from bbraun
+ [38caad5a3935]
+
+2003-03-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure.in:
+ not not; Anil Madhavapeddy
+ [d4f4f0bfc66b]
+
+2003-01-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod, sudoers.pod, visudo.pod:
+ typos; jmc@openbsd.org
+ [868c0f09bf9e]
+
+2003-01-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ Add some missing ';' rule terminators that bison warns about.
+ [535b0b8dcce5]
+
+ * config.sub:
+ fix typo I introduced in last merge
+ [81db4e4f43fe]
+
+ * configure:
+ regenerate with autoconf 2.57
+ [ca0c1e9564f8]
+
+ * config.h.in:
+ Add missing "$HOME"
+ [209186197ad1]
+
+ * configure.in:
+ Add some more square backets to make autoconf 2.57 happy
+ [b5639c14faf7]
+
+ * config.sub, mkinstalldirs:
+ Updates from autoconf-2.57
+ [36be35eb331b]
+
+ * config.guess:
+ Updates from autoconf-2.57
+ [ea0f8ca622af]
+
+2003-01-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.tab.h:
+ regen
+ [13a65a421567]
+
+ * lex.yy.c, sudo.tab.c:
+ regen
+ [0b529db7cb6d]
+
+ * parse.lex, parse.yacc, sudoers.pod:
+ Add support for Defaults>RunasUser
+ [20d726373175]
+
+2003-01-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ fclose() yyin after each yyparse() is done and use fopen() instead
+ of using freopen().
+ [587f8a2df857]
+
+ * parse.lex:
+ Better fix for sudoers files w/o a newline before EOF. It looks like
+ the issue is that yyrestart() does not reset the start condition to
+ INITIAL which is an issue since we parse sudoers multiple times.
+ [920f8326968a]
+
+2003-01-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.lex:
+ Work around what appears to be a flex bug when dealing with files
+ that lack a final newline before EOF. This adds a rule to match EOF
+ in the non-initial states which resets the state to INITIAL and
+ throws an error.
+ [b94943bb1f81]
+
+ * visudo.c:
+ o The parser needs sudoers to end with a newline but some editors
+ (emacs) may not add one. Check for a missing newline at EOF and add
+ one if needed. o Set quiet flag during initial sudoers parse (to get
+ options) o Move yyrestart() call and always use freopen() to open
+ yyin after initial sudoers parse.
+ [12d12f9b07aa]
+
+2002-12-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * set_perms.c:
+ Fix pasto/thinko in setresgid()/setregid() usage. Want to set
+ effective gid, not real gid, when reading sudoers.
+ [c7d18b810fcd]
+
+ * set_perms.c:
+ don't compile set_perms_posix if we have setreuid or setresuid
+ [b9cea7a81a29]
+
+2002-12-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod, sudoers.pod:
+ document new prompt escapes
+ [2f088076b640]
+
+ * check.c:
+ Add %U and %H escapes and redo prompt rewriting. "%%" now gets
+ collapsed to "%" as was originally intended. This also gets rid of
+ lastchar (does lookahead instead of lookback) which should simplify
+ the logic slightly.
+ [4b707b77b3c7]
+
+2002-12-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ Write the prompt *after* turning off echo to avoid some password
+ characters being echoed on heavily-loaded machines with fast
+ typists.
+ [d38c57775915]
+
+ * config.sub:
+ Add support for mipseb; wiz@danbala.tuwien.ac.at
+ [cfdac87ed5c8]
+
+ * configure.in:
+ Fix IRIX fallout from name changes in man dir/sect Makefile
+ variables. Patch from erici AT motown DOT cc DOT utexas DOT edu
+ [9a7618755c23]
+
+ * auth/pam.c:
+ Keep a local copy of tgetpass_flags so we don't add in TGP_ECHO to
+ the global copy. Problem noted by Peter Pentchev.
+ [d0a3e189cb06]
+
+2002-11-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.tab.c:
+ regen
+ [23b931359087]
+
+ * parse.yacc:
+ Add missing yyerror() calls; YYERROR does not seem to call this for
+ us.
+ [0be7aeb3ac57]
+
+2002-11-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ fix typo in comment; Pedro Bastos
+ [d7406c460e99]
+
+2002-11-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ document --disable-setresuid
+ [fbd03d03a027]
+
+ * auth/aix_auth.c, auth/bsdauth.c, auth/fwtk.c, auth/pam.c,
+ auth/sudo_auth.c:
+ Sprinkle some volatile qualifiers to prevent over-enthusiastic
+ optimizers from removing memset() calls.
+ [5370ac0e6129]
+
+ * logging.c, parse.yacc:
+ minor sign fixes pointed out by gcc -Wsign-compare
+ [db872438337f]
+
+ * set_perms.c, sudo.c, sudo.h:
+ Revamp set_perms. We now use a version based on setresuid() or
+ setreuid() when possible since that allows us to support the
+ stay_setuid option and we always know exactly what the semantics
+ will be (various Linux kernels have broken POSIX saved uid support).
+ [523bc212396c]
+
+ * config.h.in, configure:
+ regen from configure.in
+ [351877ea2624]
+
+ * configure.in:
+ Add checks for setresuid() and a way to disable using it
+ [a5b21653d169]
+
+ * compat.h:
+ No long need to emulate set*[ug]id() via setres[ug]id() or
+ setre[ug]id(). The new set_perms stuff only uses things it knows are
+ there.
+ [47884bd5d1d9]
+
+ * sudo.c:
+ Before exec, restore state of signal handlers to be the same as when
+ we were initialy invoked instead of just reseting to SIG_DFL. Fixes
+ a problem when using sudo with nohup. Based on a patch from Paul
+ Markham.
+ [f8f5a1484faa]
+
+ * sudo.c:
+ o timestamp_uid should be uid_t, not int o clarify error message
+ when sudo is run by root and no_root_sudo is set
+ [19dda0734264]
+
+2002-09-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README:
+ update ftp link for bison
+ [98bc191016e3]
+
+2002-07-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * set_perms.c:
+ Error out if setusercontext() fails and the runas user is not root.
+ [089f9ade4686]
+
+2002-05-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/securid5.c:
+ Fix rcsid
+ [07e9e85dcc2f]
+
+ * configure.in:
+ Fix SecurID API test
+ [5ec201f454a5]
+
+2002-05-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ typo in comment
+ [9d385c9ac533]
+
+ * configure.in:
+ securid5 stuff needs pthreads. Just adding -lpthread is suboptimal
+ but I don't see a better way at the moment.
+ [f89e55cbb313]
+
+ * Makefile.in, auth/securid5.c:
+ SecurID API version 5 support from Michael Stroucken
+ [68500ac7e531]
+
+ * configure.in:
+ Add check for SecurID 5.0 API
+ [1ee242e6de6b]
+
+2002-05-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * strerror.c:
+ We actually do still need config.h to get the 'const' definition for
+ K&R C.
+ [d9c982032d85]
+
+2002-05-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen with autoconf 2.5.3
+ [c71fc086eef5]
+
+ * configure.in:
+ Don't set sysconfdir to '/etc' if the user has specified a --prefix.
+ [d90da1efafd9]
+
+ * configure.in:
+ Some fixes for autoconf 2.53 from Robert Uhl o don't AC_SUBST
+ LIBOBJS o force a 4th arg for AC_CHECK_HEADER() to workaround a bug
+ [dd67afefa90d]
+
+ * env.c, sudo.c, sudo.h:
+ No need for dump_badenv() now that dump_defaults() knows how to dump
+ lists.
+ [6bcda468501d]
+
+ * BUGS, INSTALL, INSTALL.binary, Makefile.in, README, configure.in,
+ version.h:
+ ++version
+ [44e3b8f95f0b]
+
+ * sudoers.pod:
+ document timestampowner
+ [37ebd69e9dd1]
+
+ * check.c:
+ Don't call set_perms() when doing timestamp stuff unless
+ timestamp_uid != 0.
+ [63a63d41d18c]
+
+ * auth/sudo_auth.c, check.c, logging.c, parse.c, set_perms.c, sudo.c,
+ sudo.h, testsudoers.c:
+ g/c second arg to set_perms--it is no longer used
+ [7ac4ce50c612]
+
+2002-05-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c, set_perms.c, sudo.c, sudo.h:
+ Add support for non-root timestamp dirs. This allows the timestamp
+ dir to be shared via NFS (though this is not recommended).
+ [faa83dd2b7fb]
+
+ * def_data.c, def_data.h, def_data.in:
+ Add timestampowner, "Owner of the authentication timestamp dir"
+ [d47640d4c86a]
+
+2002-05-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ Don't try to pre-compute the size of the new envp, just allocate
+ space up front and realloc as needed. Changes to the new env pointer
+ must all be made through insert_env() which now keeps track of
+ spaced used and allocates as needed.
+ [39bc934a9f2c]
+
+2002-04-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [0e12c09bb790]
+
+ * configure.in:
+ Fix two typo/pastos; from jrj@purdue.edu
+ [b718a4bf1181]
+
+2002-04-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL.binary, README:
+ ++version
+ [a1e33027278c] [SUDO_1_6_6]
+
+ * configure, sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in,
+ visudo.cat, visudo.man.in:
+ regen
+ [19eb2be283ef]
+
+ * CHANGES, RUNSON, TODO:
+ Sync with 1.6.6
+ [2ff9a9087f63]
+
+ * check.c:
+ The the loop used to expand %h and %u, the lastchar variable was not
+ being initialized. This means that if the last char in the prompt is
+ '%' and the first char is 'h' or 'u' a extra copy of the host or
+ user name would be copied, for which space had not been allocated.
+ [b2e27197857d]
+
+2002-04-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS, INSTALL, Makefile.in, configure.in, version.h:
+ crank version to 1.6.6
+ [cfd08689e597]
+
+ * auth/afs.c:
+ #undef VOID to get rid of an AFS warning
+ [b40760564dc1]
+
+ * env.c:
+ Use easprintf instead of emalloc + sprintf for some things.
+ [e7bfe2e69a03]
+
+2002-03-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lex.yy.c, sudo.tab.c:
+ regen
+ [35327104383d]
+
+ * parse.c, parse.lex, parse.yacc, testsudoers.c:
+ Remove Chris Jepeway's email address so people don't bug him ;-)
+ [c03410747a69]
+
+2002-03-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Move endpwent() to be after set_perms(PERM_RUNAS, ...) and also call
+ endgrent() at the same time.
+ [28b6097d5d1a]
+
+2002-02-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ Make it clear which configure options take arguments.
+ [38529e7efad0]
+
+2002-01-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat.h:
+ HP-UX 9.x has RLIMIT_* but no RLIM_INFINITY. If there is no
+ RLIM_INFINITY, just pretend it is -1. This works because we only
+ check for RLIM_INFINITY and do not set anything to that value.
+ [53173d34e6eb]
+
+2002-01-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c:
+ Zero and free allocated memory when there is a conversation error.
+ [e342133db579]
+
+ * auth/bsdauth.c:
+ Use sigaction() not signal()
+ [126c2790561f]
+
+ * INSTALL:
+ Mention that some linux kernels have broken POSIX saved ID support
+ [571ef1a893d3]
+
+ * CHANGES:
+ checkpoint for 1.6.5p2
+ [9e9e456f7f43]
+
+ * configure:
+ regen
+ [d53703a46708]
+
+ * configure.in:
+ Add --disable-setreuid flag
+ [3b9f2679cb55]
+
+ * INSTALL:
+ Document new --disable-setreuid option and change description for
+ --disable-saved-ids to match new error message.
+ [14fd3e5f60a5]
+
+ * set_perms.c:
+ fatal() now takes an argument that determines whether or not to call
+ perror().
+ [d826b25e62ff]
+
+ * TROUBLESHOOTING:
+ Update for new error messages from set_perms()
+ [78007c3f76a9]
+
+ * PORTING:
+ Update for new error messages from set_perms()
+ [60c545a6bcff]
+
+2002-01-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c:
+ Make this compile w/o warnings
+ [b90843a29af5]
+
+ * auth/pam.c:
+ Mention that we can't use pam_acct_mgmt()
+ [1dfc5a6e0479]
+
+ * auth/aix_auth.c, auth/bsdauth.c, auth/fwtk.c, auth/pam.c:
+ The user's password was not zeroed after use when AIX
+ authentication, BSD authentication, FWTK or PAM was in use.
+ [b18fff30b1e7]
+
+2002-01-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c:
+ Avoid giving PAM a NULL password response, use the empty string
+ instead. This avoids a log warning when the user hits ^C at the
+ password prompt when PAM is in use.
+ [c3315805e4e4]
+
+ * auth/pam.c:
+ Don't check the return value of pam_setcred(). In Linux-PAM 0.75
+ pam_setcred() returns the last saved return code, not the return
+ code for the setcred module. Because we haven't called
+ pam_authenticate(), this is not set and so pam_setcred() returns
+ PAM_PERM_DENIED.
+ [73db145fa179]
+
+ * Makefile.in:
+ Don't need a '/' between $(DESTDIR) and a directory.
+ [0901ca618176]
+
+ * Makefile.binary:
+ Don't need a '/' between $(DESTDIR) and a directory.
+ [cd7eb6098b87]
+
+2002-01-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [41b12c039282]
+
+ * configure.in:
+ o BSDi also has a bogus setreuid() o Old FreeBSD has a bogus
+ setreuid() o new NetBSD has a real setreuid() o add check for
+ freeifaddrs() if getifaddrs() exists.
+ [a82ee3b01733]
+
+ * config.h.in, interfaces.c:
+ Older BSDi releases lack freeifaddrs() so add a test for that and if
+ it is not present just use free().
+ [6270671ea9d5]
+
+2002-01-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, RUNSON:
+ Checkpoint for 1.6.5p1
+ [26134ecf9b36]
+
+ * auth/passwd.c:
+ Return AUTH_FAILURE in passwd_init() if skeyaccess() denies access
+ to normal passwords, not AUTH_FATAL (which just causes an exit).
+ [785e0f4bc0e2]
+
+ * visudo.c:
+ Don't use memory after it has been freed.
+ [c60492739fdb]
+
+ * auth/passwd.c:
+ skeyaccess() wants a struct passwd * not a char *; Patch from
+ Phillip E. Lobbes
+ [65a1d3806fcd] [SUDO_1_6_5]
+
+ * BUGS:
+ ++version
+ [b2e1825e692e]
+
+ * CHANGES, RUNSON, TODO:
+ checkpoint for sudo 1.6.5
+ [d730945622e7]
+
+2002-01-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [49744c403ac9]
+
+ * INSTALL, INSTALL.binary, Makefile.in, README, configure.in:
+ version 1.6.5
+ [ec30a5f7fc45]
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in, visudo.cat,
+ visudo.man.in:
+ sudo version 1.6.5
+ [458a3bed535d]
+
+ * logging.c:
+ o when invoking the mailer as root use a hard-coded environment that
+ doesn't include any info from the user's environment. Basically
+ paranoia.
+
+ o Add support for the NO_ROOT_MAILER compile-time option and run the
+ mailer as the user and not root if NO_ROOT_MAILER is defined.
+ [4df351ec92ce]
+
+ * set_perms.c, sudo.h:
+ Bring back PERM_FULL_USER
+ [edb6039bb284]
+
+ * configure:
+ regen
+ [3eb2943afa03]
+
+ * version.h:
+ version 1.6.5
+ [044fc9a0c72b]
+
+ * INSTALL, config.h.in, configure.in:
+ Add --disable-root-mailer option to run the mailer as the user and
+ not root.
+ [e9f805397963]
+
+ * CHANGES:
+ checkpoint for 1.6.4p2
+ [b58aae5aa98a]
+
+ * PORTING:
+ Mention the "seteuid(0): Operation not permitted" problem here too
+ just for good measure.
+ [90135b37a691]
+
+2002-01-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c, getspwuid.c, sudo.c:
+ The SHELL environment variable was preserved from the user's
+ environment instead of being reset based on the passwd database when
+ the "env_reset" option was used. Now it is reset as it should be.
+ [300066ef3c71]
+
+ * configure:
+ regen
+ [a47d779e6552]
+
+ * INSTALL, TROUBLESHOOTING, config.h.in, configure.in, set_perms.c,
+ sudo.c:
+ Add a configure option to turn off use of POSIX saved IDs
+ [fb18cc8e94d0]
+
+ * configure:
+ regen
+ [d4f2f20025b6]
+
+ * configure.in:
+ add --with-efence option
+ [45c4f33a8e88]
+
+ * sudo.c:
+ Only OR in MODE_RESET_HOME if MODE_RUN is set. Fixes a problem where
+ "sudo -l" would not work if always_set_home was set.
+ [c3a6de6c4800]
+
+ * lex.yy.c:
+ regen
+ [417424452998]
+
+ * parse.lex:
+ Quoted commas were not being treated correctly in command line
+ arguments.
+ [753415541b37]
+
+ * sudo.c:
+ o Move the call to rebuild_env() until after MODE_RESET_HOME is set.
+ Otherwise, the set_home option has no effect.
+
+ o Fix use of freed memory when the "fqdn" flag is set. This was
+ introduced by the fix for the "segv when gethostbynam() fails" bug.
+ Also, we no longer call set_fqdn() if the "fqdn" flag is not set so
+ there is no need to check the "fqdn" flag in set_fqdn() itself.
+ [4b6a4245c04e]
+
+ * env.c:
+ Add 'continue' statements to optimize the switch statement. From
+ Solar.
+ [a82c76975ae5]
+
+2002-01-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.cat, sudoers.man.in:
+ Regen from new sudoers.pod
+ [6ecc07b3d0e1] [SUDO_1_6_4]
+
+ * sudoers.pod:
+ Add caveat about stay_setuid flag
+ [9d228a7bea1b]
+
+ * sudo.c:
+ If set_perms == set_perms_posix and the stay_setuid flag is not set,
+ set all uids to 0 and use set_perms_fallback().
+ [c4e54d1ec86f]
+
+ * set_perms.c, sudo.h:
+ Remove PERM_FULL_USER (which is no longer used) and add
+ PERM_FULL_ROOT (used when exec'ing the mailer).
+ [15406c522ea2]
+
+ * logging.c:
+ Use set_perms(PERM_FULL_ROOT, 0) before exec'ing the mailer since we
+ never want to run the mailer setuid.
+ [2294853e0666]
+
+2002-01-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man.in, sudo.pod, visudo.cat, visudo.man.in,
+ visudo.pod:
+ Use sudo.ws instead of courtesan.com in URLs
+ [55204002a308]
+
+ * Makefile.binary, Makefile.in:
+ Fix mansect substitution
+ [b7b5cbc3aa91]
+
+ * Makefile.in:
+ Substitute man sections in Makefile.binary
+ [040deb785e56]
+
+ * Makefile.binary:
+ Sync install targets with Makefile.in and substitute in man
+ sections.
+ [77882a275281]
+
+ * INSTALL, INSTALL.binary:
+ version is 1.6.4
+ [0f87aabbcb70]
+
+ * Makefile.in:
+ Repair bindist target
+ [8d43bfe7e2d1]
+
+ * CHANGES:
+ sync for 1.6.4
+ [13ca3d4a0a72]
+
+2002-01-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * install-sh:
+ Fix case where neither whoami nor id are found
+ [424dd270bc47]
+
+2002-01-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * install-sh:
+ If neither whoami nor id exists, just assume we are root.
+ [2d2644e42c53]
+
+ * alloc.c:
+ Add explicit cast to (VOID *) on malloc/realloc. Seems to be needed
+ on AIX which for some reason isn't pulling in the malloc prototype.
+ [231440d2ee3b]
+
+2002-01-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, aclocal.m4, compat.h, parse.c, sudo.c:
+ (c) 2002
+ [700e3b41a68e]
+
+ * CHANGES:
+ checkpoint
+ [33e604bd8d5b]
+
+ * sudo.c:
+ Defer assigning new environment until right before the exec.
+ [f13c49e75c1c]
+
+ * parse.c:
+ kill extra blank line
+ [12ef22e9dae3]
+
+2002-01-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [a6cd2d788f74]
+
+ * configure.in:
+ Use -O not -O2 for m88k-motorola-sysv* since motorola gcc-derived
+ compiler doesn't recognise -O2.
+ [5234aa543692]
+
+ * HISTORY:
+ Clarify origins of Root Group sudo a bit based on info from
+ billp@rootgroup.com
+ [4deef01c4208]
+
+2002-01-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * LICENSE:
+ 2002
+ [6c8e089dbd1a]
+
+ * CHANGES:
+ checkpoint for 1.6.4rc1
+ [3349eb87a49f]
+
+2002-01-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ now generated via autoheader
+ [84657d303cb9]
+
+ * configure:
+ regen
+ [207bfa6a13f6]
+
+ * compat.h:
+ Move in some stuff that was previously in config.h.
+ [e576d8b6480f]
+
+ * aclocal.m4, configure.in:
+ Add info for autoheader.
+ [0549cd5da27c]
+
+2002-01-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ o Add DESTDIR support o Use -M, -O, and -G instead of -m, -o, and -g
+ to facilitate non-root installs
+ [619216038f56]
+
+ * install-sh:
+ Add -M option (like -m but only for root) If we can't find "whoami",
+ use "id" w/ some sed.
+ [b39121c8b792]
+
+ * configure:
+ regen
+ [b39b93ff9804]
+
+ * configure.in:
+ allow user to always override mansectsu and mansectform
+ [0fca5e63bd90]
+
+2001-12-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkinstalldirs:
+ update from autoconf 2.52
+ [07bd75a508c3]
+
+ * config.guess, config.sub:
+ Update from autoconf 2.52
+ [857b90fe31b7]
+
+ * configure:
+ regen with autoconf 2.52
+ [08e7d1ea2aeb]
+
+ * configure.in:
+ o Call AC_PROG_CC_STDC to find out how to run the compiler in ANSI
+ mode o Remove compiler-specific checks for HP-UX now that we use
+ AC_PROG_CC_STDC
+ [d433a70b6208]
+
+ * RUNSON:
+ Checkpoint
+ [babf6d2235d1]
+
+ * auth/pam.c:
+ o Add pam_prep_user function to call pam_setcred() for the target
+ user; on Linux this often sets resource limits. o When calling
+ pam_end(), try to convert the auth->result to a PAM_FOO value. This
+ is a hack--we really need to stash the last PAM_FOO value received
+ and use that instead.
+ [6ad6f340dd2a]
+
+ * set_perms.c, sudo.h:
+ o Add pam_prep_user function to call pam_setcred() for the target
+ user; on Linux this often sets resource limits.
+ [67795421ac82]
+
+ * env.c:
+ Fix off by one error in number of bytes allocated via malloc (does
+ not affected any released version of sudo).
+ [5f5915360111]
+
+2001-12-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lex.yy.c:
+ regen
+ [8208c0277775]
+
+ * parse.lex:
+ Allow '@', '(', ')', ':' in arguments to a defaults variable w/o
+ requiring that they be quoted.
+ [ae59bc8f68dd]
+
+ * sudoers.cat, sudoers.man.in, sudoers.pod:
+ Mention that no double quotes are needed when
+ adding/deleting/assigning a single value to a list.
+ [25efc940a1f0]
+
+ * Makefile.in:
+ Don't rely on mkdefaults being executable, call perl explicitly.
+ [6edc97ba5f1d]
+
+ * sudo.tab.c:
+ regen
+ [49130b2e7e4d]
+
+ * parse.yacc:
+ Remove some XXX that are no longer relevant.
+ [d460ac0d3767]
+
+ * defaults.c:
+ o Roll our own loop instead of using strpbrk() for better
+ grokability o When adding to a list we must malloc() and use
+ memcpy(), not strdup() since we must only copy len bytes from str.
+ [649bef08e1f0]
+
+2001-12-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.tab.c:
+ regen
+ [f0bbf2c38c0e]
+
+ * parse.yacc:
+ typo in comment
+ [2563711ff593]
+
+2001-12-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ checkpoint
+ [a6d8a29fb30e]
+
+ * configure:
+ regen
+ [bdfcaaf3bd13]
+
+ * configure.in:
+ avoid the -g flag unless --with-devel was specified
+ [a976707bef30]
+
+ * Makefile.in:
+ mkdefaults, def_data.in and sigaction.c were missing from the
+ tarball
+ [6917ffbaa412]
+
+ * Makefile.in:
+ def_data.c was missing
+ [87c78b11453d]
+
+2001-12-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ Fix setting of $USER and $LOGNAME in the non-reset_env case. Also
+ allow HOME, SHELL, LOGNAME, and USER to be specified in keep_env
+ [fc8698e6a45e]
+
+ * TODO:
+ Another TODO item
+ [6f251d6cd466]
+
+ * sudoers:
+ Add comment for Default section so folks know where it should go.
+ [7edba626f392]
+
+2001-12-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ Use TCSETAF, not TCSETA to set terminal in termio case
+ [fbd172f6c5d3]
+
+ * sudoers.cat, sudoers.man.in:
+ regen from sudoers.pod
+ [64edd2de816e]
+
+ * sudoers.pod:
+ o Typo, Runas_User_List should be Runas_List o a User_List can not
+ contain a uid o mention that the Defaults section should come after
+ Alias definitions but before the user specifications
+ [54070ba2092b]
+
+2001-12-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.cat, sudoers.man.in:
+ regen
+ [e62d1d97693c]
+
+ * sudoers.pod:
+ Fix listpw and verifypw sections, they were not being formatted
+ properly.
+ [123868c2f3e9]
+
+ * sudoers.cat, sudoers.man.in:
+ regen
+ [f94841f8b374]
+
+ * sudoers.pod:
+ fix typos
+ [f278f1c1184e]
+
+ * configure:
+ regen
+ [d2270049ba9f]
+
+ * config.h.in, configure.in:
+ use AC_SYS_POSIX_TERMIOS instead of rolling our own
+ [c1a13f1354b9]
+
+ * README:
+ Reference sudo.ws not courtesan.com
+ [ca13be67ebd7]
+
+ * PORTING:
+ Add notes on shadow passwords
+ [aa13863f2314]
+
+ * BUGS:
+ In list mode (sudo -l), characters escaped with a backslash are
+ shown verbatim with the backslash.
+ [1a75a2858be2]
+
+ * sudoers:
+ Add simple examples from OpenBSD (Marc Espie)
+ [3ae9a9ae4125]
+
+ * tgetpass.c:
+ Catch SIGTTIN and SIGTTOU too and treat them like SIGTSTP.
+ [f8817699ee10]
+
+ * CHANGES:
+ minor prettyification
+ [f523587929b9]
+
+ * CHANGES:
+ Updated change log
+ [39d9010ee7a8]
+
+ * testsudoers.c:
+ Fix CIDR handling here too.
+ [c91db8344c32]
+
+ * auth/pam.c:
+ Apparently a NULL response is OK
+ [83bae61078d9]
+
+ * TODO:
+ Checkpoint for upcoming beta release
+ [efb95c09df2a]
+
+ * TROUBLESHOOTING:
+ Many people believe that adding a runas spec should obviate the need
+ for the -u flag. It does not.
+ [c698bad85b0e]
+
+ * RUNSON:
+ checkpoint update for upcoming 1.6.4 beta
+ [009e465a0a45]
+
+ * config.h.in:
+ o Add HAVE_STDLIB_H and HAVE_MEMORY_H o Define HAVE_STRINGS_H even
+ if HAVE_STRING_H is defined -- this is safe now
+ [d27c035f4e14]
+
+ * PORTING:
+ Add signals section
+ [2d24c13cb3c8]
+
+ * configure:
+ regen
+ [2b80a939e2ed]
+
+ * configure.in:
+ Fix check for sigaction_t
+ [6fa41c89ab20]
+
+ * sudo.c:
+ XXX - should call find_path() as runas user, not root. Can't do that
+ until the parser changes though.
+ [f0b4f85651bd]
+
+ * sudo.c:
+ If find_path() fails as root, try again as the invoking user (useful
+ for NFS). Idea from Chip Capelik.
+ [e03fa7872692]
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in:
+ Regenerate after pod file changes
+ [48e4bd75ec21]
+
+ * def_data.c, def_data.h, def_data.in, set_perms.c, sudo.c, sudo.h,
+ sudo.pod, sudoers.pod:
+ Add new sudoers option "preserve_groups". Previously sudo would not
+ call initgroups() if the target user was root. Now it always calls
+ initgroups() unless the -P command line option or the
+ "preserve_groups" sudoers option is set. Idea from TJ Saunders.
+ [4f730359f101]
+
+2001-12-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat.h, config.h.in:
+ Use new HAVE_SIGACTION_T define
+ [dfb25f3cae5b]
+
+ * logging.c:
+ Fix compilation on K&C
+ [7355e3275e34]
+
+ * configure:
+ regen
+ [a710584f92f0]
+
+ * configure.in:
+ Add check for sigaction_t -- IRIX already defines this so don't
+ redefine it.
+ [df9c5737f6da]
+
+ * snprintf.c:
+ fix typo
+ [3d782b8134c8]
+
+ * interfaces.c:
+ need stdlib.h here too
+ [c789d8973ab2]
+
+ * configure:
+ regen
+ [44822856bf46]
+
+ * configure.in:
+ Remove redundant checks for string.h, strings.h and unistd.h
+ [933c94f8bbf4]
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in, visudo.cat,
+ visudo.man.in:
+ Regen from pod files
+ [ad18c590f638]
+
+ * BUGS:
+ Update for 1.6.4
+ [26bc88b69d22]
+
+ * configure, lex.yy.c, sudo.tab.c:
+ regen
+ [bef89fd6fa2d]
+
+ * strerror.c:
+ Return EINVAL if errnum > sys_nerr
+ [0512374e6661]
+
+ * auth/sudo_auth.h:
+ o Update copyright year
+ [a877016db6e2]
+
+ * LICENSE, Makefile.binary, Makefile.in, aclocal.m4, compat.h,
+ config.h.in, defaults.h, interfaces.h, pathnames.h.in, sudo.h,
+ sudo.pod:
+ o Update copyright year
+ [e15a1b39039f]
+
+ * configure.in:
+ o Don't define STDC_HEADERS unconditionally for IRIX o Update
+ copyright year
+ [82a8cb819e07]
+
+ * README:
+ update version
+ [d82e523a16b4]
+
+ * auth/afs.c, auth/aix_auth.c, auth/bsdauth.c, auth/dce.c,
+ auth/fwtk.c, auth/kerb4.c, auth/kerb5.c, auth/pam.c, auth/passwd.c,
+ auth/rfc1938.c, auth/secureware.c, auth/securid.c, auth/sia.c,
+ auth/sudo_auth.c, logging.c, parse.c, parse.lex, parse.yacc,
+ set_perms.c, snprintf.c, sudo.c, testsudoers.c, tgetpass.c, utime.c,
+ visudo.c:
+ o Reorder some headers and use STDC_HEADERS define properly o Update
+ copyright year
+ [fe39f76b3795]
+
+ * lsearch.c:
+ o Reorder some headers and use STDC_HEADERS define properly o Update
+ copyright year
+ [764ba3d4fa13]
+
+ * getspwuid.c, goodpath.c, interfaces.c:
+ o Reorder some headers and use STDC_HEADERS define properly o Update
+ copyright year
+ [fb46d46140d4]
+
+ * getcwd.c:
+ o Reorder some headers and use STDC_HEADERS define properly o Update
+ copyright year
+ [b199d70ac7ab]
+
+ * alloc.c, check.c, defaults.c, env.c, fileops.c, find_path.c,
+ fnmatch.c:
+ o Reorder some headers and use STDC_HEADERS define properly o Update
+ copyright year
+ [dab8f192a3ed]
+
+ * configure:
+ regen
+ [156658f25cea]
+
+ * tgetpass.c:
+ flags set in signal handlers should be volatile sig_atomic_t
+ [c22931a5535e]
+
+ * config.h.in, configure.in:
+ Add checks for volatile and sig_atomic_t
+ [b03b3341381d]
+
+ * configure, lex.yy.c:
+ regen
+ [ed9daba88217]
+
+ * def_data.c, def_data.h, def_data.in, defaults.c, env.c, find_path.c,
+ sudo.c, sudoers.pod:
+ Remove "secure_path" Defaults option since it cannot work with the
+ existing parser.
+ [c9e54a0f5971]
+
+ * find_path.c, sudo.c:
+ Unset "secure_path" if user_is_exempt()
+ [fb7544565ae8]
+
+ * env.c, pathnames.h.in:
+ o Remove assumption that PATH and TERM are not listed in env_keep o
+ If no PATH is in the environment use a default value o If TERM is
+ not set in the non-reset case also give it a default value.
+ [c987eb7df268]
+
+ * aclocal.m4, configure.in, defaults.c, pathnames.h.in:
+ _PATH_SENDMAIL -> _PATH_SUDO_SENDMAIL so --without-sendmail works on
+ systems that define in paths.h
+ [51865b0cdebf]
+
+ * auth/passwd.c, auth/sudo_auth.c, auth/sudo_auth.h:
+ Add support for skeyaccess(3) if it is present in libskey.
+ [8add77c7d3e7]
+
+2001-12-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Only need to do 'lc = login_getclass(NULL)' if lc == NULL
+ [5a3d3cbf2c6d]
+
+ * parse.lex:
+ '\\' is a perfectly legal character to have in a command line
+ argument.
+ [c15a466ef00e]
+
+ * sudo.c:
+ o Defer call to set_fqdn() until it is safe to use log_error() o
+ Don't print errno string value if gethostbyname fails, it is not
+ relevant
+ [c0c6bcf08bcb]
+
+ * parse.c:
+ Fix CIDR -> in_addr_t conversion.
+ [2f307ebeb63f]
+
+2001-12-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Remove an extra "User_List" in the User_Spec definition From
+ ybertrand AT snoopymail.com
+ [97bde59ea280]
+
+ * parse.c:
+ Make 'listpw=never' work for users who are not explicitly mentioned
+ in sudoers.
+ [258f0f30a428]
+
+ * sudoers.pod:
+ Remove gratuitous '=' in EBNF grammar; era AT iki.fi
+ [4b0f03872ee1]
+
+ * sudoers.pod:
+ Document new list Defaults type and convert env_keep and env_delete
+ to lists. Document new env_check option.
+ [a07f1f079fe3]
+
+ * lex.yy.c, sudo.tab.c, sudo.tab.h:
+ regen parser
+ [e39ac6c6581b]
+
+ * parse.lex:
+ Don't let '#' appear in a {WORD} and restrict #foo in a Runas spec
+ to #[0-9-]+.
+ [69c5388908f3]
+
+ * configure:
+ regen
+ [0f1877b88cb3]
+
+ * aclocal.m4:
+ Simpler SUDO_FUNC_ISBLANK that uses AC_TRY_LINK
+ [6545503ae361]
+
+ * config.h.in, configure.in:
+ Add check for skeyaccess(3)
+ [6caf69fe6359]
+
+ * visudo.pod:
+ Document new -c, -f, and -q options
+ [13d0203c21d3]
+
+ * visudo.c:
+ o Add -f option (alternate sudoers file) o Convert to use getopt(3)
+ [4c2b664d617d]
+
+ * configure:
+ regen
+ [6d5bd932e7b5]
+
+ * aclocal.m4, config.h.in, configure.in:
+ Add check for isblank and a replacement macro if it doesn't exist.
+ [b524f5e4f953]
+
+2001-12-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ In check-only mode, don't create sudoers if it does not already
+ exist.
+ [c748a2d5acad]
+
+ * parse.yacc:
+ o Add a new token, DEFVAR, to indicate a Defaults variable name o
+ Add support for "+=" and "-=" list operators o replace some 1 and 0
+ with TRUE and FALSE for greater legibility.
+ [554cb174b37e]
+
+ * parse.lex:
+ o Use exclusive start conditions to remove some ambiguity in the
+ lexer. Also reorder some things for clarity. o Add support for "+="
+ and "-=" list operators. o Use the new DEFVAR token to denote a
+ Defaults variable name.
+ [3a2cf8323e26]
+
+ * sudo.h:
+ Prototype init_envtables()
+ [b74916469dab]
+
+ * env.c:
+ o Convert environment handling to use lists instead of strings. This
+ greatly simplifies routines that need to do "foreach" type
+ operations. o Add new init_envtables() function to set env_check and
+ env_delete defaults based on initial_badenv_table and
+ initial_checkenv_table (formerly sudo_badenv_table).
+ [0a8b404658b6]
+
+ * defaults.c, defaults.h:
+ o Add a new LIST type and functions to manipulate it. o This is for
+ use with environment handling variables. o Call new init_envtables()
+ routine inside init_defaults() to initialize the environment lists.
+ [ae73e64f0902]
+
+ * def_data.c, def_data.h, def_data.in:
+ Convert environment options to use the new LIST type and add a new
+ one, env_check that only deletes if the sanity check fails.
+ [3019503936de]
+
+ * testsudoers.c:
+ Add dummy version of init_envtables()
+ [9d9e3ee609d9]
+
+ * parse.yacc:
+ honor quiet mode
+ [8330fba6167c]
+
+ * visudo.c:
+ Add check-only mode
+ [dab411bc8c35]
+
+ * mkdefaults:
+ Fix generation of entries with NULL descriptions.
+ [ea75b9fed02e]
+
+2001-12-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ Use sigaction_t and quiet a gcc warning.
+ [6f67d719c452]
+
+ * sudo.c:
+ Must reset signal handlers before we exec
+ [300418120e1a]
+
+ * auth/aix_auth.c, auth/bsdauth.c, auth/fwtk.c, auth/pam.c,
+ auth/sudo_auth.c:
+ Be carefule now that tgetpass() can return NULL (user hit ^C). PAM
+ version needs testing. Set SIGTSTP to SIG_DFL during password entry
+ so user can suspend us.
+ [00304aa58747]
+
+ * tgetpass.c:
+ Add support for interrupting/suspending tgetpass via keyboard input.
+ If you suspend sudo from the password prompt and resume it will re-
+ prompt you.
+ [4af2b5101d32]
+
+ * sudo.c:
+ Don't block keyboard interrupt signals, just set them to SIG_IGN.
+ [d46d7f67ef6b]
+
+2001-12-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ add back HAVE_SIGACTION
+ [c9c7702c603e]
+
+ * configure:
+ regen
+ [09fe669d337f]
+
+ * config.h.in, configure.in, logging.c, sudo.c, visudo.c:
+ Kill POSIX_SIGNALS define and old signal support now that we emulate
+ POSIX ones Also be sure to correctly initialize struct sigaction.
+ [4bc2a6dbb2be]
+
+ * strerror.c:
+ Don't need config.h or "#ifndef HAVE_STRERROR" wrapper.
+ [1ad64a19f328]
+
+ * compat.h:
+ Add scaffolding for POSIX signal emulation
+ [945861d4c93b]
+
+ * sigaction.c:
+ o Add missing ';' so this compiles o Can't use NULL since we don't
+ include stdio.h
+ [04d0cac7438f]
+
+ * sigaction.c:
+ Emulate sigaction() using sigvec()
+ [d0b54a989875]
+
+2001-11-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Document new behavior of negative values of timestamp_timeout Fix a
+ typo
+ [4c0716570d01]
+
+ * sudo.pod:
+ Add security note about command not being logged after 'sudo su' and
+ friends.
+ [43294851a33c]
+
+ * sudo.pod:
+ Mention that -V prints default values when run as root, including
+ the list of environment variables to clear.
+ [d9e5e550a8c3]
+
+ * Makefile.in:
+ Run pod2man with --quotes=none to avoid stupid quoting of C<>
+ entries.
+ [997b23c35dbe]
+
+2001-11-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/sudo_auth.c, def_data.c, def_data.h, def_data.in, sudoers.pod:
+ Add mail_badpass option Also modify mail_always behavior to also
+ send mail when the password is wrong
+ [838d40ccafce]
+
+ * env.c, sudo.c, sudo.h:
+ Dump default bad env table when 'sudo -V' is run by root.
+ [f67f1b8048b0]
+
+ * sudoers.pod:
+ document env_delete
+ [d74f893663a2]
+
+ * env.c:
+ Add support for '*' in env_keep when not resetting the environment
+ (ie: the normal case).
+ [fd4fb62ea8fd]
+
+ * env.c:
+ Add env_delete variable that lets the user replace/add to the
+ bad_env_table. Allow '*' wildcard in env_keep entries.
+ [aa728bc35e29]
+
+2001-11-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkinstalldirs:
+ Force umask to 022 to guarantee sane directory permissions.
+ [9ab3cfe70569]
+
+2001-11-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ add sudo.tab.h and sudo.tab.c to sudo.tab.o dependency
+ [671010465e6f]
+
+ * mkdefaults:
+ fix breakage in last commit
+ [8318f8851e56]
+
+ * Makefile.in:
+ acsite.m4 -> aclocal.m4
+ [30c146873a01]
+
+ * check.c:
+ fix I_TS_TIMEOUT vs. I_TIMESTAMP_TIMEOUT pasto in previous commit
+ [4dc8b39954da]
+
+ * def_data.c:
+ regenerated from def_data.in
+ [915ea16ce1eb]
+
+ * check.c, defaults.c, defaults.h:
+ Add new T_UINT type that most things use instead of T_INT If
+ timestamp_timeout is < 0 then treat the ticket as never expiring (to
+ be expired manually by the user).
+ [3a3a636a2a5d]
+
+ * def_data.in:
+ change most T_INT -> T_UINT
+ [a2228d2457af]
+
+ * mkdefaults:
+ fix warning when no args
+ [ca70a5394af5]
+
+ * visudo.c:
+ Change 2 Exit() -> exit() Avoid stdio in Exit() and call _exit() if
+ we are a signal handler. We no longer print the signal number but
+ the user can just check the exit value for that.
+ [dc424f631fef]
+
+2001-10-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ when setting up pipes in child process check for case where stdin ==
+ pipe fd 0
+ [518112d76184]
+
+2001-10-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ Ignore editor exit value since XPG4 says vi's exit value is the
+ count of editing errors made (failed searches, etc).
+ [b9d952284865]
+
+2001-10-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [cb3aa586f03b]
+
+ * configure.in:
+ sco now is identified by config.guess as *-sco-*
+ [46664bbdea61]
+
+ * configure.in:
+ Check for getspnam() in -lgen if not in -lc for UnixWare.
+ [0f152ad1ba93]
+
+2001-09-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod, visudo.pod:
+ "upper case" -> "uppercase"
+ [f9151f232326]
+
+ * sudoers.pod:
+ fix typos and grammar; pjanzen@foatdi.harvard.edu
+ [2855d73d0237]
+
+2001-08-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Missing word (specify); krapht@secureops.com
+ [65523eb37a2c]
+
+2001-08-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ If we fail to lookup a login class, apply the default one.
+ [d4869faa6816]
+
+ * logging.c:
+ In log_error() free message, not logline unconditionally, then free
+ logline if it is not the same as message. No function change but
+ this mirrors how they are allocated.
+ [565e5f6cc643]
+
+2001-07-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regenerate
+ [834a48f548a2]
+
+ * configure.in:
+ remove some backslash quotes that are unneeded
+ [50d401d6e2ca]
+
+ * configure.in:
+ o Tweaks to make this work with autoconf-2.50 o Use AC_LIBOBJ
+ instead of changing LIBOBJS directly o Use AC_REPLACE_FUNCS where we
+ can o Use AC_CHECK_FUNCS instead of AC_CHECK_FUNC so we don't have
+ to AC_DEFINE things manually.
+ [f502c5f15f92]
+
+ * config.guess, config.sub:
+ Updated from autoconf-2.50
+ [6140205915ef]
+
+2001-05-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README:
+ Update mailing list section. We use mailman now, not majordomo.
+ [b9a8ca45e6dc]
+
+2001-05-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * getspwuid.c, logging.c, sudo.c:
+ Use setpwent()/endpwent() + all the shadow variants to make sure we
+ don't inadvertantly leak an fd to the child. Apparently Linux's
+ shadow routines leave the fd open even if you don't call setspent().
+ Reported by mike@gistnet.com; different patch used.
+ [d33792ef6c01]
+
+2001-04-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ s/eg./e.g./
+ [bd32a0acaf93]
+
+ * tgetpass.c:
+ select() may return EAGAIN. If so, continue like we do for EINTR.
+ [5f202c943818]
+
+ * logging.c:
+ Fix a non-exploitable buffer overflow in the word splitting code.
+ This should really be rewritten.
+ [4c724363863a]
+
+ * Makefile.in:
+ FAQ link goes away
+ [1d26dd6c8972]
+
+ * INSTALL:
+ Tell people to look in sample.syslog.conf for examples, not FAQ
+ [affcae3f43ca]
+
+ * TROUBLESHOOTING:
+ Update list of env vars that are cleared
+ [234e56f1435a]
+
+ * sudo.c:
+ remove struct env_table decl since that stuff has all moved to env.c
+ [5dd923148777]
+
+2001-04-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * fileops.c:
+ Fix a pasto in flock-style unlocking and include <sys/file.h> for
+ flock on older systems; twetzel@gwdg.de
+ [d5420d9d2861]
+
+ * configure:
+ regen to get NeXT lockf/flock fix
+ [d3ba6ed70e15]
+
+ * configure.in:
+ force NeXT to use flock since lockf is broken
+ [bd5391dca1bb]
+
+2001-03-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ Use stashed user_gid when checking against exempt gid since sudo
+ sets its gid to a a value that makes sudoers readable. Previously if
+ you used gid 0 as the exempt group everyone would be exempt. From
+ Paul Kranenburg <pk@cs.few.eur.nl>
+ [0b140cc3a817]
+
+2001-03-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [cc455408f32b]
+
+ * aclocal.m4:
+ #include stdio.h in SUDO_CHECK_TYPE since IRIX 6 aparently defines
+ some types (such as ssize_t) therein.
+ [b6aee85ca331]
+
+2001-03-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * defaults.c:
+ Fix negation of paths in a boolean context. Problem found by
+ apt@UH.EDU
+ [8aee217a7cdf]
+
+2001-02-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ pasto
+ [ad32b277bf68]
+
+2001-02-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ SA_RESETHAND means the opposite of what I was thinking--oops To
+ block all signals in old-style signals use ~0, not 0xffffffff
+ [6ecdd793590a]
+
+2001-02-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * defaults.c:
+ coerce difference of pointers to int when used in a string length
+ printf format; deraadt@openbsd.org
+ [a9d10f07180d]
+
+2001-01-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ Block all signals in Exit() to avoid a signal race. There is still a
+ tiny window but I'm not going to worry about it.
+ [6661805c0458]
+
+2001-01-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * env.c:
+ glibc uses the LANGUAGE env var so clear that too; Solar Designer
+ [d4ba95628afb]
+
+ * lex.yy.c:
+ Regenerate with a fix to flex.skl that preserves errno from
+ clobbering by isatty().
+ [607eec736e19]
+
+2000-12-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/aix_auth.c, auth/bsdauth.c, auth/fwtk.c, auth/pam.c,
+ auth/sia.c, auth/sudo_auth.c:
+ Some defaults I_ defines got renamed.
+ [ec19b23caaf3]
+
+ * Makefile.in, check.c, def_data.c, def_data.h, def_data.in,
+ defaults.c, defaults.h, env.c, logging.c, mkdefaults, parse.yacc,
+ set_perms.c, sudo.c, sudo.tab.c:
+ Move defaults info into its own files from which we generate .h and
+ .c files. This makes adding or rearranging variables much simpler.
+ [e91b880b5043]
+
+2000-12-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ fix typo in last commit
+ [10a6ee2bae71]
+
+ * compat.h, config.h.in, configure, configure.in:
+ Add check + emulation for setegid (like seteuid).
+ [29492092bd2f]
+
+ * env.c:
+ Make env_keep override badenv_table as documented Fix traversal of
+ badenv_table (broken in last commit)
+ [37c9f0d22673]
+
+ * set_perms.c, sudo.c, sudo.h:
+ Don't try and build saved uid version of set_perms on systems w/o
+ them. Rename set_perms_saved_uid() -> set_perms_posix() Make
+ set_perms_setreuid simply be set_perms_fallback() and simply include
+ the appropriate function at compile time (setreuid() vs. setuid()).
+ [3107333c062c]
+
+ * sudoers.cat, sudoers.man.in, sudoers.pod:
+ PATH is also preserved when env_reset is in effect
+ [90e45c5711ff]
+
+ * CHANGES, Makefile.in, check.c, compat.h, config.h.in, configure,
+ configure.in, defaults.c, defaults.h, env.c, find_path.c,
+ getspwuid.c, set_perms.c, sudo.c, sudo.cat, sudo.h, sudo.man.in,
+ sudo.pod, sudoers.cat, sudoers.man.in, sudoers.pod, testsudoers.c,
+ visudo.c, visudo.cat, visudo.man.in:
+ New Defaults options: o stay_setuid - sudo will remain setuid if
+ system has saved uids or setreuid(2) o env_reset - reset the
+ environment to a sane default o env_keep - preserve environment
+ variables that would otherwise be cleared
+
+ No longer use getenv/putenv/setenv functions--do environment munging
+ by hand. Potentially dangerous environment variables can be cleared
+ only if they contain '/' pr '%' characters to protect buggy
+ programs. Moved environment routines into env.c (new file)
+ [c2f97651db4c]
+
+ * INSTALL:
+ Clear up --without-passwd description
+ [2f336dab6733]
+
+ * putenv.c, sudo_setenv.c:
+ We now build up a new environment from scratch and assign it to
+ "environ".
+ [6ae6152f2238]
+
+2000-12-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod, visudo.pod:
+ Grammatical fixes from Paul Janzen
+ [e03ead2e56f8]
+
+2000-12-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ If there was a syntax error and the user just wants to quit, unlink
+ sudoers if it is zero length.
+ [74ba7921f520]
+
+ * visudo.c:
+ 'Q' means ignore parse error, not 'q'
+ [e8d0e4491fe6]
+
+ * visudo.c:
+ Open sudoers for writing with mode SUDOERS_MODE From Dimitry Andric
+ <dim@xs4all.nl>
+ [b24990a72491]
+
+2000-12-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * set_perms.c:
+ Add missing #ifdef HAVE_LOGIN_CAP_H; ayamura@ayamura.org
+ [41a8db10e076]
+
+2000-12-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.guess, config.sub:
+ Darwin / Mac OS X support from Wilfredo Sanchez <wsanchez@apple.com>
+ [6052da895d2e]
+
+2000-11-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c, visudo.c:
+ Use exit(127), not exit(-1)
+ [9ff0c3eada34]
+
+ * Makefile.in, defaults.c, defaults.h, set_perms.c, sudo.c:
+ Move set_perms() to its own file and use POSIX saved uid or
+ setreuid() if available.
+
+ Added stay_setuid option for systems that have libraries that
+ perform extra paranoia checks in system libraries for setuid
+ programs (ie: anything with issetugid(2)).
+ [28960f842698]
+
+ * sudo.c:
+ strip more bits from the environment and add a facility for
+ stripping things only if they contain '/' or '%' to address printf
+ format string vulnerabilities in other programs.
+ [b98d6375f299]
+
+2000-11-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [7e74e5c91049]
+
+ * configure.in:
+ For NCR, add -lc89 to LIBS, not SUDO_LIBS and cache the existence of
+ strcasecmp().
+ [a418e9e70442]
+
+ * configure:
+ regen
+ [bbff244a52bc]
+
+ * configure.in:
+ Check for strcasecmp(3) in -lc89 for NCR Unix
+ [361c99576681]
+
+2000-11-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ Define HAVE_INNETGR #ifdef HAVE__INNETGR
+ [473cdb92b6db]
+
+ * configure:
+ regen
+ [4e6364a195e0]
+
+ * compat.h, config.h.in, configure.in:
+ Add check for _innetgr(3) since NCR systems have that instead of
+ innetgr(3).
+ [25e6852e7494]
+
+2000-10-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/securid.c:
+ check return value of creadcfg() call sd_close() after sd_auth()
+ store username in sd->username so we don't rely on the USER env
+ variable
+ [d106b4f42722]
+
+2000-10-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ document --with-bsdauth
+ [f1518ecc2ee9]
+
+ * configure:
+ regen
+ [dceb35071ea8]
+
+ * configure.in:
+ --with-bsdauth assumes --with-logincap
+ [4200778083fd]
+
+ * auth/bsdauth.c, auth/fwtk.c:
+ When prompting for a response to a challenge, if the user just hits
+ return then reprompt with echo turned on.
+ [a539b6474a97]
+
+2000-10-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Remove debugging code that should not have been committed, oops.
+ [9862607b77a7]
+
+ * auth/bsdauth.c:
+ Use lower-level routines and get the password ourselves. Checks for
+ a challenge and if there is one echo is not turned off.
+ [2d8fcd166baa]
+
+ * auth/pam.c, auth/sudo_auth.h:
+ minor housekeeping, no real code changes
+ [d0074a277fb4]
+
+2000-10-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Fix a coredump in the logging functions if gethostname(2) fails by
+ deferring the call to log_error() until things are better setup.
+
+ Fix return value of set_loginclass() in non-BSD-auth case.
+
+ Hard-code 'sudo' in the usage message so we can fit more options on
+ a line
+ [d9d1b7579818]
+
+ * logging.c:
+ Fix errant ';' (typo) that broken MSG_ONLY
+ [849b2276a470]
+
+2000-10-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man.in:
+ regen
+ [bb3c8c6704d1]
+
+ * sudo.pod:
+ Document -a flag
+ [e18316cebaac]
+
+ * Makefile.in, auth/bsdauth.c, auth/sudo_auth.h, config.h.in,
+ configure, configure.in, getspwuid.c, sudo.c:
+ Add support for BSD authentication.
+ [f374cfd9ca0d]
+
+2000-10-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Fix typo; from sato@complex.eng.hokudai.ac.jp
+ [3085fee9766e]
+
+2000-10-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ Mention negating umask
+ [c9e410294dae]
+
+ * defaults.c:
+ Allow user to specify umask of 0777 (same as !umask)
+ [bb771daa96fe]
+
+2000-10-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod, visudo.pod:
+ Fix a typo and give a URL for the sudo history.
+ [77f73199aedb]
+
+2000-10-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * defaults.c, sudo.pod:
+ fix typos; pepper@reppep.com
+ [5532c7421340]
+
+2000-09-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c, sudo.h, sudo_setenv.c:
+ sudo_setenv() now exits on memory alloc failure instead of returning
+ -1.
+ [71f1cf18f47b]
+
+2000-09-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Strip out NLSPATH and PATH_LOCALE from the environment for FreeBSD
+ and possibly others.
+ [b69d985b0d22]
+
+ * logging.c:
+ Don't use vsyslog(3) since HP-UX (and others?) lack it. This means
+ that "%m" won't be expanded but we don't use that anyway since the
+ logging routines may splat to stderr as well.
+ [8d37a544d0c0]
+
+ * defaults.c, defaults.h, sudo.c, sudoers.cat, sudoers.man.in,
+ sudoers.pod:
+ Add always_set_home variable
+ [dbcaff646e07]
+
+ * configure, configure.in:
+ Have to hard code default values in help since the defaults are set
+ _after_ the help stuff.
+ [7b5d6d72f55c]
+
+2000-08-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lex.yy.c, parse.lex:
+ Allow special characters (including '#') to be embedded in pathnames
+ if quoted by a '\\'. The quoted chars will be dealt with by
+ fnmatch(). Unfortunately, 'sudo -l' still prints the '\\'.
+ [3ed33cf09977]
+
+2000-08-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * install-sh:
+ Better path searching for programs we need.
+ [60517cb1f0d6]
+
+ * TROUBLESHOOTING:
+ Add section on "C compiler cannot create executables" errors.
+ [e4ada6eaee59]
+
+ * Makefile.binary, Makefile.in, version.h:
+ Crank version
+ [93d1bd5b7f5e]
+
+ * aclocal.m4, configure, configure.in, sudo.cat, sudo.man.in,
+ sudo.pod, sudoers.cat, sudoers.man.in, sudoers.pod, visudo.cat,
+ visudo.man.in, visudo.pod:
+ Substitute values from configure into man pages.
+ [619854c356c1]
+
+2000-08-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c, sudo.c:
+ The listpw and verifypw sudoers options would not take effect
+ because the value of the default was checked *before* sudoers was
+ parsed. Instead of passing in the value of PWCHECK_* to
+ sudoers_lookup(), pass in the arg for def_ival() so the check can be
+ deferred until after sudoers is parsed.
+ [4f596e358f72]
+
+2000-08-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ When writing prompt, no need to write the NUL as well;
+ hag@linnaean.org
+ [fbcdd7b431ee]
+
+2000-06-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * install-sh:
+ When looking for chown, check in /sbin too
+ [657ba6653f8c]
+
+2000-06-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ Remove extraneous call to init_defaults() and set runas_user to NULL
+ betweem parses so init_defaults will reset it each time, thus
+ avoiding a reference to free()d data.
+ [7421fcd692af]
+
+2000-06-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, interfaces.c, interfaces.h, sudo.c:
+ Add support for using getifaddrs() to get the list of ip addr /
+ netmask pairs. Currently IPv4-only.
+ [a35bc4f7306d]
+
+ * visudo.c:
+ Add a missing check for UserEditor == NULL Add missing '+' before
+ line number when invoking editor to fix a syntax error
+ [f0d4635f6082]
+
+2000-05-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Call clean_env very early in main() for paranoia's sake. Idea from
+ Marc Esipovich.
+ [f8d72ebd0115]
+
+2000-05-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.h:
+ Update proto for evasprintf and easprintf
+ [d147d6e58419]
+
+ * alloc.c:
+ Make easprintf() and evasprintf() return an int.
+ [b2ca5d089667]
+
+ * check.c:
+ If the targetpw flag is set, use target username as part of the
+ timestamp path. If tty tickets are in effect cat the tty and the
+ target username with a ':' as the separator.
+ [de11abc693c2]
+
+2000-05-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c:
+ Backout part of last change; setting PAM_USER to the invoking user
+ breaks things like targetpw.
+ [427218a7387f]
+
+ * auth/pam.c:
+ set tty and username via pam_set_item
+ [85d1922dbcc9]
+
+ * auth/sudo_auth.c, check.c, getspwuid.c, sudo.c, sudo.h:
+ Fix root, runas, and target authentication for non-passwd file auth
+ methods.
+ [a14535e7b30c]
+
+2000-04-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man.in, sudo.pod, sudoers.cat, sudoers.man.in,
+ sudoers.pod, visudo.cat, visudo.man.in, visudo.pod:
+ Use B<-Z> not C<-Z> for command line flags in all places. This is
+ more consistent and works around a bug in Pod::Man.
+ [64b5a05f30c5]
+
+ * sudoers.cat, sudoers.man.in, sudoers.pod:
+ Fix an occurence of 'semicolon' that should be 'colon'
+ [4ea5aacae3fb]
+
+2000-04-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Fix --with-badpri help line
+ [3cc40977c043]
+
+2000-04-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * defaults.c, logging.c, sudo.c:
+ Bracket calls to syslog with an openlog() and closelog() since some
+ authentication methods (like PAM) may do their own logging via
+ syslog. Since we don't use syslog much (usually just once per
+ session) this doesn't really incur a performance penalty. It also
+ Fixes a SEGV with pam_kafs.
+ [fe1cc28529f6]
+
+2000-04-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Fix -H flag. runas_homedir is only valid after set_perms(PERM_RUNAS,
+ mode)
+ [ce9b1c6f68a6]
+
+2000-04-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ Clarify the fact that insults are not enabled just by including them
+ in the binary.
+ [d5a31d48320c]
+
+2000-04-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man.in, sudoers.cat, sudoers.man.in, visudo.cat,
+ visudo.man.in:
+ Regenerated with perl 5.6.0 pod2man
+ [21751433768b]
+
+ * Makefile.in:
+ Give date string to pod2man since its default is ugly and it ain't
+ got no alibi.
+ [0080b2f6298f]
+
+ * Makefile.in:
+ Do section substitution on the output of pod2man and remove hack
+ needed for old pod2man.
+ [1ef843d5c78b]
+
+ * sudo.pod, sudoers.pod, visudo.pod:
+ Put back real man sections, we will do the substitution later.
+ [f728c1abad7e]
+
+2000-04-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Don't bother checking for the path to vi if user specified --with-
+ editor
+ [bf698487e0d5]
+
+2000-04-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, visudo.c:
+ Visudo now does its own fork/exec instead of calling system(3).
+ [99bbcd88863b]
+
+ * CHANGES, INSTALL, Makefile.in, sudoers.cat, sudoers.man.in,
+ sudoers.pod, visudo.c:
+ Visudo now checks for the existence of an editor and gives a
+ sensible error if it does not exist.
+
+ The path to the editor for visudo is now a colon-separated list of
+ allowable editors. If the user has $EDITOR set and it matches one of
+ the allowed editors that editor will be used. If not, the first
+ editor in the list that actually exists is used.
+ [cc86eb9f5440]
+
+ * sudo.cat, sudo.man.in, sudo.pod:
+ Clear up confusion wrt sudo's return value.
+ [9385b12d8e79]
+
+2000-03-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Strip sudo and visudo for bindist target
+ [a995ddd79177]
+
+ * sudo.cat, sudo.man.in, sudo.pod, sudoers.cat, sudoers.man.in,
+ sudoers.pod, visudo.cat, visudo.man.in, visudo.pod:
+ Use @mansectsu@ and @mansectform@ in the man page bodies as well.
+ [5eb9e60a726f] [SUDO_1_6_3]
+
+ * visudo.cat, visudo.man.in, visudo.pod:
+ Typo: @sysconf@ -> @sysconfdir@
+ [f07f52fcd099]
+
+ * Makefile.in:
+ 'make dist' should not cause any files to be modified so remove its
+ dependencies.
+ [7f44a2666a9c]
+
+ * CHANGES:
+ Whoops, forgot to add release marker
+ [16c0f16b35b8]
+
+2000-03-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ Final change for 1.6.3 (or so I hope)
+ [473c89da6123]
+
+ * sudo.cat, sudoers.cat, visudo.cat:
+ Use SYSV man sections since BSD systems will have nroff...
+ [0a6bd154324e]
+
+2000-03-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc, sudo.tab.c:
+ When checking to see if the host/user matches in a defaults spec,
+ check against TRUE, not just non-zero since it might be -1.
+ [41f2b7ad3fdd]
+
+ * configure, configure.in:
+ OSF/1 puts file formats in section 4, not 5.
+ [d77c1301afa9]
+
+ * CHANGES, INSTALL, sudo.c:
+ Make login class support work on BSD/OS
+ [e9bbe3c08ade]
+
+ * RUNSON:
+ Update for 1.6.3
+ [c40ce1d76c4d]
+
+ * configure, configure.in:
+ If there is no inet_addr but there *is* an __inet_addr that's ok
+ since inet_addr is probably just a macro then. The better thing to
+ do would be to look for the macro, but this is fine for now.
+ [1b8865ae4d68]
+
+ * configure, configure.in:
+ Don't use shlicc for BSD/OS 4.x
+ [83fbf6dedd2c]
+
+ * Makefile.in, configure, configure.in:
+ *.man lives in cwd, *.cat lives in $(srcdir), add a @mansrcdir@
+ configure variable so we can deal with this. Also, only remove *.man
+ for 'distclean' not 'clean'.
+ [30d56e6de214]
+
+ * sudo.c:
+ set_loginclass() should be static like the proto says
+ [d570a2d55fb8]
+
+2000-03-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * fnmatch.c:
+ Add #ifdef __STDC__ around the rangematch function header to avoid
+ promotion of test to int, thus violating the prototype. Gcc handles
+ this gracefully but more std ANSI compilers will complain.
+ [7d98c3e332b2]
+
+ * emul/fnmatch.h:
+ Pull in newer fnmatch(3) that supports FNM_CASEFOLD
+ [4e1320852f8b]
+
+ * aclocal.m4, configure, fnmatch.3, fnmatch.c:
+ Pull in newer fnmatch(3) that supports FNM_CASEFOLD Check for
+ FNM_CASEFOLD in configure
+ [9ef952bf1896]
+
+ * CHANGES, TODO:
+ update for 1.6.3
+ [e4ba6368a0c5]
+
+ * sudo.tab.c, sudo.tab.h, testsudoers.c, visudo.c:
+ Fully qualified hosts w/ wildcards were not matching the FQHOST
+ token type. There's really no need for a separate token for fully-
+ qualified vs. unqualified anymore so FQHOST is now history and
+ hostname_matches now decides which hostname (short or long) to check
+ based on whether or not the pattern contains a '.'.
+ [fbd2887d9811]
+
+ * parse.h:
+ Fully qualified hosts w/ wildcards were not matching the FQHOST
+ token type. There's really no need for a separate token for fully-
+ qualified vs. unqualified anymore so FQHOST is now history and
+ hostname_matches now decides which hostname (short or long) to check
+ based on whether or not the pattern contains a '.'.
+ [dd7bbe223461]
+
+ * lex.yy.c, parse.c, parse.lex, parse.yacc:
+ Fully qualified hosts w/ wildcards were not matching the FQHOST
+ token type. There's really no need for a separate token for fully-
+ qualified vs. unqualified anymore so FQHOST is now history and
+ hostname_matches now decides which hostname (short or long) to check
+ based on whether or not the pattern contains a '.'.
+ [630d9d205397]
+
+ * parse.c, parse.h, parse.yacc, sudo.tab.c, sudoers.cat,
+ sudoers.man.in, sudoers.pod, testsudoers.c, visudo.c:
+ Add support for wildcards in the hostname.
+ [d8d821ed4238]
+
+ * Makefile.in:
+ Add targets for *.man.in, using config.status to generate *.man from
+ *.man.in
+ [640e50ede485]
+
+ * sudoers.cat, sudoers.man.in, sudoers.pod:
+ Document set_logname option and enbolden refs to sudo and visudo.
+ [9622b3a48707]
+
+ * INSTALL, Makefile.in, aclocal.m4, configure, configure.in, sudo.cat,
+ sudo.man.in, sudo.pod, sudoers.cat, sudoers.man.in, sudoers.pod,
+ visudo.cat, visudo.man.in, visudo.pod:
+ Add FreeBSD login.conf support (untested on BSD/OS) based on a patch
+ from Michael D. Marchionna. configure now does substitution on the
+ man pages, allowing us to fix up the paths and set the section
+ correctly. Based on an idea from Michael D. Marchionna.
+ [463e928a0a2f]
+
+ * auth/passwd.c:
+ Better fix for handling HP-UX aging info.
+ [3950f42d8549]
+
+ * sudo.c:
+ Add support for set_logname run-time default
+ [c6a7cc76b8b4]
+
+ * sudo.man.in, sudoers.man.in, visudo.man.in:
+ configure does substitution on these to produce *.man
+ [b83fc3c1bfc9]
+
+ * sudo.man, sudoers.man, visudo.man:
+ These files now get generated from *.man.in at configure time.
+ [c499061f79e0]
+
+2000-03-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * defaults.c, defaults.h:
+ Add set_logname option so users can turn off setting of LOGNAME/USER
+ environment variables.
+ [6316869180b8]
+
+ * lsearch.c, parse.c, testsudoers.c:
+ kill register
+ [6e104e653748]
+
+2000-03-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/passwd.c:
+ HP-UX adds extra info at the end for password aging so when
+ comparing the result of crypt to pw_passwd we only compare the first
+ len(epass) bytes *unless* the user entered an empty string for a
+ password.
+ [3d24d4e4e889]
+
+ * logging.c:
+ Get rid of grandchild hack, it was causing problems and there is
+ really no need for it. This fixes a bug where we spin eating up CPU
+ when the user runs a long-running process like a shell.
+ [5743b10b1e81]
+
+2000-03-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ User can always specify a login class if he/she is already root.
+ [710d160cef9f]
+
+ * config.h.in, configure, configure.in, defaults.c, defaults.h,
+ sudo.c, sudo.h:
+ FreeBSD login class (login.conf) support.
+ [026b981d6328]
+
+2000-03-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/sudo_auth.c:
+ HAVE_SECUREWARE -> HAVE_GETPRPWNAM; fixes secureware support
+ [9cd4929f1a78]
+
+2000-03-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/passwd.c:
+ Truncate unencrypted password to 8 chars if encrypted password is
+ exactly 13 characters (indicateing standard a DES password). Many
+ versions of crypt() do this for you, but not all (like HP-UX's).
+ [a9d0259cb193]
+
+2000-03-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, RUNSON:
+ Mention that gcc on dynix may have problems
+ [77b97fa5bf1b]
+
+2000-02-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ Link visudo with NET_LIBS since we now call syslog via defaults.c
+ [9e3830b277cc]
+
+ * defaults.c:
+ Use Argv[0] as the first arg to openlog() since visudo uses this
+ too.
+ [e61078f328ec]
+
+2000-02-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Stash coredumpsize resource limit and retsore it before the exec()
+ Otherwise the child ends up with a coredumpsize of 0.
+ [f6a4783835a3]
+
+2000-02-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man, sudo.pod:
+ document -S flag
+ [3ebd805b7142]
+
+ * sudo.c:
+ fix usage string
+ [66b2dfa47fe8]
+
+ * CHANGES, RUNSON, TODO, auth/aix_auth.c, auth/fwtk.c, auth/pam.c,
+ auth/sudo_auth.c, sudo.c, sudo.h, tgetpass.c:
+ Added -S flag (read passwd from stdin) and tgetpass_flags global
+ that holds flags to be passed in to tgetpass(). Change echo_off
+ param to tgetpass() into a flags field. There are currently 2
+ possible flags for tgetpass(): TGP_ECHO and TGP_STDIN. In
+ tgetpass(), abstract the echo set/clear via macros and if (flags &
+ TGP_ECHO) but echo is not set on the terminal, but sure to set it.
+ [a4fcbb712cd0]
+
+ * tgetpass.c:
+ Fixed a bug that caused an infinite loop when the password timeout
+ was disabled.
+ [2be1ffc5a39f]
+
+2000-02-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, defaults.c, defaults.h, getspwuid.c, sudo.c, sudo.h,
+ sudoers.cat, sudoers.man, sudoers.pod, visudo.c:
+ Add rootpw, runaspw, and targetpw options.
+ [2d4563e46df7]
+
+ * CHANGES, defaults.c, sudoers.cat, sudoers.man, sudoers.pod,
+ visudo.c:
+ enveditor -> env_editor
+ [ddc5f856e583]
+
+2000-02-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS, INSTALL, Makefile.in, README, configure, configure.in,
+ sudo.cat, sudo.man, sudoers.cat, sudoers.man, version.h, visudo.cat,
+ visudo.man:
+ crank versino to 1.6.3
+ [a5f7d3e74360]
+
+ * INSTALL, TODO, defaults.c, defaults.h, sudoers.cat, sudoers.man,
+ sudoers.pod, visudo.c:
+ Add 'editor' and 'enveditor' sudoers defaults and make visudo honor
+ them. This means that visudo will now parse the sudoers file
+ *before* it is edited so a bogus sudoers file will cause a warning
+ to go to stderr. Also, visudo checks the variables once--it does not
+ check them after each editor run since that could be confusing.
+ [9f5af18e9212]
+
+2000-02-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON:
+ 1.6.2 -> 1.6.2p1
+ [e25b74f1d1af]
+
+ * check.c, sudo.c, sudo.h:
+ Move user_is_exempt prototype into sudo.h
+ [daf26a6ded8a]
+
+2000-02-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ Fix thinko, some && should have been || in the last commit
+ [4b9b2d487ded]
+
+ * configure, configure.in:
+ Don't initialized Makefile variables to be NULL since the user may
+ want to import variables from their environment.
+ [7be019f4422c]
+
+2000-02-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ typo
+ [38f4d8971f0a]
+
+2000-01-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.tab.c:
+ fix a yacc (skeleton.c) warning
+ [a2da228a937b]
+
+2000-01-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, RUNSON, configure, configure.in:
+ Make pam work on HP-UX 11.0;jaearick@colby.edu
+ [b94de0ff6f42]
+
+ * CHANGES:
+ recent changes; prepare for 1.6.2p1
+ [b291635ea141]
+
+ * find_path.c:
+ Don't apply SECURE_PATH if user is example; jmknoble@pobox.com
+ [4306285c4f6e]
+
+2000-01-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.tab.c:
+ Regen with yacc that has a memory leak plugged.
+ [e26383a04eb7]
+
+ * sudoers.cat, sudoers.man, sudoers.pod:
+ Expanded docs on sudoers 'defaults' options based on INSTALL file
+ info.
+ [54c3d62d6c74]
+
+ * INSTALL:
+ Fix some while lies
+ [d15311782150]
+
+2000-01-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ When making a bindist, link FAQ to TROUBLESHOOTING instead of
+ copying.
+ [2d88a6ac88cf]
+
+ * sudoers.cat, sudoers.man, sudoers.pod:
+ Add netgroup caveat
+ [28d119f466e3] [SUDO_1_6_2]
+
+ * RUNSON:
+ Last minute updates
+ [89fb4ed22d52]
+
+ * TROUBLESHOOTING:
+ PAM entry
+ [a9fd59f39457]
+
+ * auth/pam.c:
+ correct a comment
+ [a29627225ba9]
+
+ * CHANGES, RUNSON:
+ update for 1.6.2
+ [b7f1c40ea732]
+
+ * auth/pam.c:
+ Better detection of PAM errors and fix custom prompts with PAM.
+ Based on patches from "Cloyce D. Spradling" <cloyce@headgear.org>
+ [ff69234b94a5]
+
+2000-01-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * snprintf.c:
+ Cast ULONG_MAX to unsigned long long when comparing to an unsigned
+ long long value.
+ [9d918c3a2ecd]
+
+2000-01-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, config.h.in, configure, configure.in, visudo.c:
+ Fix sudoers locking in visudo. We now lock the sudoers file itself,
+ not the temp file (since locking the temp file can foul up editors).
+ The previous locking scheme didn't work because the fd was closed
+ too early.
+ [de2011bb11ed]
+
+ * config.h.in, configure, configure.in:
+ Don't need test for ftruncate() any more.
+ [e5f71c848104]
+
+ * configure, configure.in:
+ Add a test for the -Aa flag w/ HP-UX's cc. Fixes compilation with
+ the unbundled HP-UX cc.
+ [2c373612c644]
+
+2000-01-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.cat, sudoers.man, sudoers.pod:
+ "a a" -> "a"; Aaron Campbell <aaron@cs.dal.ca>
+ [05360d2c314e]
+
+2000-01-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * LICENSE, Makefile.in, defaults.c, defaults.h, parse.c, parse.h,
+ parse.yacc, sudo.c, sudo.h, sudoers.pod, testsudoers.c, tgetpass.c,
+ version.h, visudo.c:
+ update copyright year on changed files
+ [5792a2a28a4c]
+
+ * RUNSON:
+ updates
+ [edf8f19aa403]
+
+ * CHANGES:
+ aix fix
+ [4d4a243b31e2]
+
+ * INSTALL:
+ Crank version to 1.6.2
+ [bcb5cb411624]
+
+ * configure:
+ Crank version to 1.6.2
+ [32a19f33427f]
+
+ * sudo.c:
+ When using rlimit check for RLIM_INFINITY When computing the value
+ of maxfd, use min(getdtablesize(), RLIMIT_NOFILE)
+ [8c16166802e5]
+
+ * CHANGES:
+ recent changes
+ [09fc7112e44d]
+
+ * BUGS, Makefile.in, README, configure.in, sudo.cat, sudo.man,
+ sudoers.cat, sudoers.man, version.h, visudo.cat, visudo.man:
+ Crank version to 1.6.2
+ [055fa61a7c61]
+
+ * INSTALL, defaults.c, defaults.h, sudo.c, sudo.h, sudoers.pod:
+ Add 'shell_noargs' runtime option back in. We have to defer checking
+ until after the sudoers file has been parsed but since there are now
+ other options that operate that way this one can too. Based on a
+ patch from bguillory@email.com.
+ [231db7a007a6]
+
+ * defaults.c, defaults.h, parse.c, sudo.c, sudo.h:
+ Add "listpw" and "verifypw" options.
+ [190683bac878]
+
+ * sudoers.cat, sudoers.man, sudoers.pod:
+ o Fix some typos/omissions o Add section on verifypw and listpw o
+ Define how NOPASSWD interacts with the -v and -l flags
+ [6feb7350eb79]
+
+2000-01-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ For HP-UX cc, add -Aa to CPPFLAGS. For HP-UX always add
+ -D_HPUX_SOURCE to CPPFLAGS.
+ [06cc35d89dc8]
+
+ * defaults.c, defaults.h:
+ In struct sudo_defs_types, move the union to the end and don't
+ initialize the union member since that only works with an ANSI
+ compiler. We set the value of the union by hand in init_defaults()
+ anyway. This allows sudo to compile on a K&R compiler again.
+ [623487e1fcfa]
+
+2000-01-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c, parse.h, parse.yacc, sudo.tab.c, testsudoers.c, visudo.c:
+ netgr_matches needs to check shost as well as host since they may be
+ different.
+ [3f43ace23d3e]
+
+ * tgetpass.c:
+ End on \r as well as \n
+ [cb7c6e6f4202]
+
+2000-01-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Update statbuf.st_mode based on SUDOERS_MODE when we are chaning
+ from 0400 to whatever SUDOERS_MODE is (converting from the old
+ sudoers mode). Assumes that SUDOERS_MODE is less restrictive than
+ 0400 which should always be the case.
+ [34cd83d49d20]
+
+ * parse.c, parse.yacc, sudo.c, sudo.h, sudo.tab.c:
+ Make treatment of -l and -v sane wrt NOPASSWD flags. Now allow -l
+ w/o a passwd if there is *any* entry for the user on the host with a
+ NOPASSWD flag. For -v, only allow w/o a passwd if *all* entries for
+ the user on the host w/ the specified runas user have the NOPASSWD
+ flag set.
+ [4b3b85697653]
+
+ * Makefile.in:
+ add check target
+ [3d24d34a76fd]
+
+1999-12-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ Treat EOF at whatnow prompt like 'x' instead of looping.
+ [5deffc27114c]
+
+1999-12-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ recent changes
+ [5836a9452568] [SUDO_1_6_1]
+
+1999-12-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure, configure.in, sudo.c:
+ Add check for initgroups() since old SYSV lacks this.
+ [657a6005a569]
+
+ * CHANGES, RUNSON, aclocal.m4, config.h.in, configure, configure.in,
+ parse.c, testsudoers.c:
+ o Kill HAVE_FNMATCH_H o Only define HAVE_FNMATCH if <fnmatch.h>
+ exists.
+ [17d081e917d6]
+
+1999-12-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/sudo_auth.c:
+ Don't allow insults to be enabled if the insults[] array is empty.
+ Otherwise there would be division by zero.
+ [b20c14db6029]
+
+ * insults.h:
+ Don't allow insults to be enabled if the insults[] array is empty.
+ Otherwise there would be division by zero.
+ [028f130204b0]
+
+ * CHANGES, RUNSON:
+ Don't allow insults to be enabled if the insults[] array is empty.
+ Otherwise there would be division by zero.
+ [974f4780254b]
+
+ * insults.h:
+ Don't care about USE_INSULTS #define since the insult stuff may be
+ overridden at runtime.
+ [b873df8b299c]
+
+ * auth/sudo_auth.c:
+ Honor insults flag.
+ [756111640fdc]
+
+ * CHANGES, parse.c:
+ Don't ask the user for a password if the user is not allowed to run
+ the command and the authenticate flag (in sudoers) is false.
+ [cea9fdc09c76]
+
+ * CHANGES, RUNSON, lex.yy.c, parse.lex:
+ o Whenever we get a bare newline we change to the INITIAL state. o
+ Enter GOTRUNAS when we see Runas_Alias
+
+ This allows #uid to work in a RunasAlias.
+ [a475513e7c7a]
+
+1999-12-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, parse.yacc, sudo.tab.c:
+ fix parsing of runas lists: o oprunasuser and runaslist now return a
+ value o in a runasspec, if a runaslist does not return TRUE, set
+ runas_matches to FALSE. Normally, a runaslist only returns FALSE for
+ explicitly denied users. o since runaslist does not modify the stack
+ there is no need for a push/pop in runasalias.
+ [82b305b34a8c]
+
+ * check.c, sudo.c:
+ Don't kill the user's tickets until after sudoers has been parsed
+ since tty_tickets and ticket_dir could be set in sudoers.
+ [f43e25367f3a]
+
+ * BUGS, CHANGES, Makefile.binary, Makefile.in, README, RUNSON,
+ configure, configure.in, sudo.cat, sudo.man, sudoers.cat,
+ sudoers.man, tgetpass.c, version.h, visudo.cat, visudo.man:
+ crank version to 1.6
+ [95f8bdcf9bb2]
+
+ * testsudoers.c:
+ add set_fqdn() stub
+ [bbc81af5b41a]
+
+1999-12-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, defaults.c, defaults.h, sudo.c, sudo.h, sudoers.cat,
+ sudoers.man, sudoers.pod, visudo.c:
+ o Kill shell_noargs option, it cannot work since the command needs
+ to be set before sudoers is parsed. o Fix the "set_home" sudoers
+ option (only worked at compile time). o Fix "fqdn" sudoers option.
+ We now set host/shost via set_fqdn which gets called when the "fqdn"
+ option is set in sudoers. o Move the openlog() to store_syslogfac()
+ so this gets overridden correctly from the sudoers file.
+ [3dca861f0f5d]
+
+ * auth/securid.c:
+ SecurID support should compile now.
+ [a544e5c6ea34]
+
+1999-11-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.man, sudo.pod, sudoers.cat, sudoers.man, visudo.cat,
+ visudo.man, visudo.pod:
+ fix some syntactic goofs
+ [b3451f0d5239]
+
+1999-11-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, sudo.html, sudoers.html, visudo.html:
+ No longer need the .html files as they are generated automatically
+ on the web site.
+ [1b4aa4204584]
+
+ * CHANGES, LICENSE:
+ kill characters that made wml unhappy
+ [b988fbc6da56]
+
+ * HISTORY:
+ typo
+ [a418963f7fce]
+
+1999-11-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README:
+ majordomo@cs.colorado.edu -> majordomo@courtesan.com
+ [5d151e8ffd3b]
+
+ * Makefile.in, configure:
+ Wrap script execution w/ /bin/sh for the benefit of ctm
+ [3a9c4766b2c3]
+
+1999-11-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Make the -s flag be exclusive too. Also reorder the flags in the
+ exclusive usage message so they are alphabetical.
+ [4c7af200db34]
+
+1999-11-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c:
+ make pam errors other than PAM_PERM_DENIED fatal
+ [64bcb3fd2baf]
+
+ * auth/API:
+ fix typo
+ [f3134c88b12e]
+
+ * INSTALL:
+ make it clear that /etc/pam.d/sudo is required on linux
+ [213cc3eaad82]
+
+ * auth/pam.c:
+ fix a warning on redhat and spew an error if pam_authenticate()
+ returns an error other than AUTH_SUCCESS or PAM_PERM_DENIED
+ [7e46dd19da89]
+
+ * sudo.cat, sudo.html, sudo.man, sudo.pod:
+ Be very clear that the password required is the user's not root's
+ [a6da127347e5]
+
+1999-11-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ add sample.syslog.conf to DISTFILES and BINFILES
+ [8661c27c007e]
+
+1999-11-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON:
+ updates from Brian Jackson + some formatting
+ [6d31c6fa63f8]
+
+1999-11-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL.binary, Makefile.binary, README, RUNSON:
+ o One RUNSon update o Changes for automating real binary releases
+ [dd9585f4406c]
+
+ * Makefile.in:
+ Add bindist target
+ [546ed3fa94bb]
+
+1999-11-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TROUBLESHOOTING:
+ talk about run-time options in addition to compile-time options
+ [1eb813ff0a9a] [SUDO_1_6_0]
+
+ * CHANGES:
+ fix typos
+ [65e92bb70a7b]
+
+ * sudo.c:
+ need sys/time.h if HAVE_SETRLIMIT
+ [ce31655a8a60]
+
+ * PORTING, README, RUNSON, sudo.c, sudo.cat, sudo.html, sudo.man,
+ sudo.pod, visudo.cat, visudo.html, visudo.man, visudo.pod:
+ get rid of references to sudo-bugs. Now mention the web site or the
+ sudo@ alias
+ [a9db861fd8c6]
+
+ * sudoers.html:
+ repair pod2html damage
+ [62ece4277f1f]
+
+ * RUNSON, TODO:
+ Update for 1.6 release
+ [98569c57ba2a]
+
+ * sudoers.cat, sudoers.html, sudoers.man, sudoers.pod:
+ Add warning about using ALL in a command context.
+ [6c77685ab280]
+
+1999-11-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ Call yyrestart() on a parse error to reset the lexer state.
+ [1370a27acdb2]
+
+ * lex.yy.c, parse.lex:
+ Don't need YY_FLUSH_BUFFER after all Move yyrestart() into visudo.c
+ since it might not get called in yywrap if we get a parse error (and
+ we only reread the file on error anyway).
+ [37f4b449e28e]
+
+ * lex.yy.c, parse.lex:
+ Call YY_FLUSH_BUFFER macro in yywrap() to clean up any buffers that
+ might still exist. Call yyrestart() instead of using the deprecated
+ YY_NEW_FILE macro.
+ [7d0d873046c6]
+
+ * lex.yy.c, parse.lex:
+ flex doesn't need %N table size declarations
+ [268b020fd60a]
+
+ * sudoers.cat, sudoers.html, sudoers.man, sudoers.pod:
+ Mention what characters need to be escaped in names.
+ [72ccbb6b0f31]
+
+1999-11-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure:
+ regen
+ [65827abb5c7b]
+
+ * INSTALL:
+ clarify Mac OS X entry
+ [8da1549a71f5]
+
+ * RUNSON:
+ update
+ [0cff8df7459f]
+
+ * configure.in:
+ o Use AC_MSG_ERROR throughout o Check syslog configure options for
+ danity
+ [4cb81e642e5c]
+
+1999-11-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * defaults.c:
+ Fix printing of type T_MODE in dump_defaults()
+ [a868bb6f5515]
+
+ * strcasecmp.c:
+ missing sys/types.h
+ [ca694ca325b6]
+
+ * INSTALL:
+ Break out options that may be overridden at run time into their own
+ section. Add a not about Max OS X and correct some lies.
+ [d8bcfd120593]
+
+1999-11-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, config.h.in, configure, configure.in, sudo.c:
+ o Now use getrlimit to find the highest fd when closing all non-std
+ fd's o Turn off core dumps via setrlimit for the sake of paranoia
+ [dd9f651b6def]
+
+ * RUNSON:
+ updates
+ [f581841fe615]
+
+1999-11-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ updates
+ [553baa1d44c7]
+
+ * tgetpass.c:
+ When read()'ing, do a single character at a time to be sure we don't
+ go oast the newline.
+ [907d33f55bb4]
+
+ * sudo.c:
+ For the sudo_root option, check against user_uid, not getuid() since
+ at this point, ruid == euid == 0.
+ [92d5c51939b4]
+
+ * RUNSON:
+ some updates
+ [e3ed0c1f312b]
+
+ * logging.h:
+ Fix compilation problem when --with-logging=file was specified. This
+ means that syslog is now required to build sudo but that should not
+ be a problem. If it is it can be fixed trivially with a configure
+ check for syslog() or syslog.h.
+ [839a4b069190]
+
+ * tgetpass.c:
+ Make this work again for things like "sudo echo hi | more" where the
+ tty gets put into character at a time mode. We read until we read
+ end of line or we run out of space (similar to fgets(3)).
+ [c8f746df2e63]
+
+1999-10-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.cat, sudoers.html, sudoers.man, sudoers.pod:
+ change ital to bold
+ [f860978e530a]
+
+ * RUNSON:
+ update
+ [9bcfbb405568]
+
+1999-10-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * defaults.c:
+ Error out if syslog parameters are given without a value. For Ultrix
+ or 4.2BSD "syslog" is allowed without a value since there are no
+ facilities in the 4.2BSD syslog.
+ [69e7a686f5f0]
+
+1999-10-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * defaults.c:
+ Ignore the syslog facility for systems w/ old syslog like Ultrix.
+ [5c250adbbb84]
+
+ * TROUBLESHOOTING:
+ people with "." early in their path can have problems running sudo
+ from the build dir ;-)
+ [20a1744a24a4]
+
+1999-10-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.html, sudo.man, sudo.pod:
+ Remove -r realm option
+ [127caa537f95]
+
+ * auth/kerb5.c, auth/sudo_auth.c, auth/sudo_auth.h, configure,
+ configure.in, sudo.c:
+ New krb5 code from Frank Cusack <fcusack@iconnet.net>.
+ [7177a3893a62]
+
+ * CHANGES:
+ update to reality
+ [766cfbb512d6]
+
+1999-10-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/fwtk.c:
+ include <auth.h> to get function prototypes.
+ [d6c7c12d09fe]
+
+ * sudo.cat, sudo.html, sudo.man, sudo.pod:
+ document -L flag
+ [dc803e1ce0d7]
+
+1999-10-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ in set_perms(), always call setuid(0) before changing the ruid/euid
+ so we always know it will succeed.
+ [8cced1b862bf]
+
+ * defaults.h:
+ #undef T_FOO to avoid conflicts with system defines (like on
+ ULTRIX).
+ [d9f0aac092b0]
+
+ * TODO, sample.sudoers, sudoers.cat, sudoers.html, sudoers.man,
+ sudoers.pod:
+ Docuement "Defaults" lines in /etc/sudoers. Still needs some
+ fleshing out but this is a start.
+ [521a1e629bbc]
+
+1999-10-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * use strtol, not strtoul since not everyone has not strtoul
+ [988462f093cc]
+
+ * defaults.c:
+ use strtol, not strtoul since not everyone has not strtoul
+ [fce835ce62e3]
+
+ * lex.yy.c, parse.lex:
+ last {WORD} rule should only apply in the INITIAL state
+ [9b57570bfa83]
+
+ * lex.yy.c, parse.lex:
+ o Add support for escaped characters in the WORD macro o Modify
+ fill() to squash escape chars
+ [87572d59e4e0]
+
+ * defaults.c, defaults.h:
+ o Add T_PATH flag to allow simple sanity checks for default values
+ that are supposed to be pathnames. o Fix a duplicate free when
+ visudo finds an error.
+ [bdc6855a6c6d]
+
+1999-10-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * defaults.c, defaults.h, logging.c:
+ mail_if_foo -> mail_foo
+ [cbee9415875d]
+
+1999-10-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat.h, defaults.c, defaults.h, sudo.c, tgetpass.c:
+ o Add requiretty option o Move O_NOCTTY to compat.h
+ [65b8bf0e1795]
+
+ * logging.c:
+ The exit() in log_error() was mistakenly removed in a previous
+ version. Put it back...
+ [9473449130a4]
+
+1999-10-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, TODO, auth/aix_auth.c, auth/fwtk.c, auth/pam.c,
+ auth/rfc1938.c, auth/sia.c, auth/sudo_auth.c, check.c, config.h.in,
+ configure, configure.in, defaults.c, defaults.h, find_path.c,
+ getspwuid.c, logging.c, parse.yacc, sudo.c, sudo.tab.c:
+ o Change defaults stuff to put the value right in the struct. o
+ Implement mailer_flags o Store syslog stuff both in int and string
+ form. Setting the string form magically updates the int version. o
+ Add boolean attribute to strings where it makes sense to say !foo
+ [4698953f9a36]
+
+ * tgetpass.c:
+ add O_NOCTTY when opening /dev/tty just in case
+ [4c6d1d1bb300]
+
+1999-10-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/API:
+ cleanup function no longer takes a status arg
+ [0819edbfe7f8]
+
+ * INSTALL:
+ the the
+ [19aadb65ea28]
+
+1999-09-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TODO, config.h.in, configure, configure.in, logging.c:
+ Use strftime() instead of ctime() if it is available.
+ [fb60ea63b514]
+
+1999-09-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * defaults.c:
+ fix copyright date
+ [4a53b54aa72f]
+
+ * RUNSON:
+ update ReliantUNIX entry
+ [de618a4f67d9]
+
+ * defaults.c, defaults.h, logging.c:
+ add log_year option
+ [251a9e20568a]
+
+ * configure, configure.in:
+ add --without-sendmail to help output
+ [93162f199902]
+
+ * configure, configure.in:
+ enforce an otctal arg for --with-suoders-mode
+ [45e1b04ccad3]
+
+1999-09-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS, INSTALL, Makefile.in, TODO, aclocal.m4, auth/aix_auth.c,
+ auth/fwtk.c, auth/kerb5.c, auth/pam.c, auth/rfc1938.c, auth/sia.c,
+ auth/sudo_auth.c, check.c, config.h.in, configure, configure.in,
+ defaults.c, defaults.h, find_path.c, lex.yy.c, logging.c, parse.h,
+ parse.lex, parse.yacc, sudo.c, sudo.h, sudo.tab.c, sudo.tab.h,
+ testsudoers.c, version.c, visudo.c:
+ Add support for "Defaults" line in sudoers to make configuration
+ variables changable at runtime (and on a global, per-host and per-
+ user basis). Both the names and the internal representation are
+ still subject to change. It was necessary to make sudo_user.runas
+ but a char ** instead of a char * since this value can be changed by
+ a Defaults line. There is a similar (but more complicated) issue
+ with sudo_user.prompt but it is handled differently at the moment.
+
+ Add a "-L" flag to list the name of options with their descriptions.
+ This may only be temporary.
+
+ Move some prototypes to parse.h
+
+ Be much less restrictive on what is allowed for a username.
+ [f71abf7ba80c]
+
+ * sample.syslog.conf:
+ Add more info
+ [e952e6f42d4d]
+
+1999-09-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * LICENSE, fnmatch.3, fnmatch.c, getcwd.c, lsearch.c, snprintf.c,
+ strcasecmp.c:
+ UCB has dropped the advertising clause from their license.
+ [a5602b36a341]
+
+1999-08-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/sudo_auth.h:
+ move dce_verofy proto to correct section
+ [972c815af558]
+
+ * auth/dce.c:
+ remove XXX
+ [820631855be0]
+
+1999-08-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * emul/fnmatch.h:
+ Add fnmatch() prototype
+ [79e84576d92a]
+
+ * fnmatch.c, parse.c, testsudoers.c:
+ Move inclusion of emul/fnmatch.h to be after sudo.h for __P
+ [1182c89fa811]
+
+ * sudo.h:
+ add strcasecmp proto
+ [512d1d8a6a0c]
+
+ * auth/sudo_auth.c:
+ add check for case where there are no auth methods
+ [e4af2b91b43e]
+
+ * configure, configure.in:
+ Define _XOPEN_EXTENDED_SOURCE on AIX and __USE_FIXED_PROTOTYPES__ on
+ SunOS4 w/ gcc
+ [746ce8bcec23]
+
+ * getspwuid.c, lex.yy.c, parse.lex, parse.yacc, sudo.tab.c:
+ include strings.h everywhere we include string.h
+ [6f7d5d437e7b]
+
+ * version.c:
+ nicer output when showing auth methods
+ [0eac4b977f9d]
+
+ * version.c:
+ Add support for SEND_MAIL_WHEN_NO_HOST
+ [9f20a3a3fae6]
+
+ * config.h.in, configure, configure.in:
+ Add _GNU_SOURCE for Linux
+ [c7bd8c511847]
+
+ * lex.yy.c, parse.lex:
+ fix definition of OCTECT
+ [4af30e63244d]
+
+ * configure, configure.in:
+ aix_auth.o not authenticate.o
+ [fe95dfb08df4]
+
+1999-08-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Only block SIGINT, SIGQUIT, SIGTSTP (which can be generated from the
+ keyboard). Since we run with ruid/euid == 0 the user can't really
+ signal us in nasty ways.
+ [a7f6487c0f48]
+
+ * visudo.c:
+ Don't need to worry about catching too many signals since we do
+ locking on the tmp file. If a lockfile is really stale, it will be
+ detected and overwritten.
+ [28983db3e749]
+
+ * INSTALL, Makefile.in:
+ include auth/API in tarball
+ [014991600252]
+
+ * auth/sudo_auth.c:
+ move memset() of plaintext pw outside of verify loop and only do the
+ memset if we are *not* in standalone mode.
+ [66f8e87567e2]
+
+ * auth/sudo_auth.c, auth/sudo_auth.h:
+ DCE is not a standalone method
+ [34963e2d8a1b]
+
+ * sudo.c:
+ fix --enable-noargs-shell
+ [4234062abbb0]
+
+ * snprintf.c:
+ "#ifdef __STDC__" not "#if __STDC__" (I missed one)
+ [c430b80454c6]
+
+ * auth/fwtk.c, auth/sia.c:
+ _cleanup() function returns an int.
+ [d1a1cc071ec1]
+
+ * auth/dce.c:
+ there were still some return(0)'s hanging around, make them
+ AUTH_FAILURE
+ [1002aa1962c3]
+
+ * parse.c:
+ typo in comment
+ [5abc410dbfd2]
+
+ * version.c:
+ add missing semicolon
+ [a262283b52a5]
+
+ * auth/sudo_auth.h:
+ missing backslash
+ [bf89f6bd2900]
+
+1999-08-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, config.h.in, configure, configure.in:
+ Kill _XOPEN_EXTENDED_SOURCE -- causes problems on some OSes
+ [f1a9bca0cf67]
+
+ * Makefile.in:
+ add parse.h to HDRS
+ [a3d054987766]
+
+ * Makefile.in, configure, configure.in:
+ Kill VISUDO_LIBS and VISUDO_LDFLAGS. Add LIBS, NET_LIBS, and
+ LDFLAGS. Common libs go in LIBS, commong ld flags go in LDFLAGS and
+ network libs like -lsocket, -lnsl go in NET_LIBS. This allows
+ testsudoers to build on Solaris and is a bit cleaner in general.
+ [4e6239e97002]
+
+ * UPGRADE:
+ mention ptmp -> sudoers.tmp
+ [ec3baa0fe8a1]
+
+ * config.h.in, configure, configure.in:
+ Define _XOPEN_SOURCE_EXTENDED not _XOPEN_SOURCE
+ [6f93dc7f39f5]
+
+ * RUNSON:
+ add 2 reports
+ [ce0fcc00ee4e]
+
+ * auth/kerb5.c:
+ Minor changes, mostly cosmetic. verify_krb_v5_tgt() changed to
+ return a value more like a system function
+ [0dd56aa21424]
+
+ * auth/dce.c:
+ Add an XXX
+ [58fc8562c212]
+
+ * TODO:
+ more things todo!
+ [5a459d0cf339]
+
+ * sample.sudoers:
+ update based on what is in the man page
+ [1a0477db96fa]
+
+ * parse.yacc, sudo.tab.c:
+ minor change to first line printed in -l mode
+ [69eb57d96952]
+
+ * sudo.cat, sudo.html, sudo.man, sudo.pod:
+ rename "ENVIRONMENT VARIABLES" section to "ENVIRONMENT" to be more
+ standard and add "EXAMPLES" section
+ [7e543335ebe1]
+
+ * visudo.cat, visudo.html, visudo.man, visudo.pod:
+ rename "ENVIRONMENT VARIABLES" section to "ENVIRONMENT" to be more
+ standard
+ [f82d87ed65c2]
+
+ * logging.c, parse.c, sudo.h:
+ add FLAG_NO_CHECK
+ [c7d69176a2d7]
+
+ * lex.yy.c, parse.lex:
+ make an OCTET really be limited to 0-255
+ [6ee568dd6a02]
+
+ * UPGRADE:
+ mention timestamp changes
+ [e44d5302bf60]
+
+ * PORTING:
+ cosmetic cleanup
+ [36fa3a2664dd]
+
+ * sudoers.cat, sudoers.html, sudoers.man, sudoers.pod:
+ new sudoers(8) man page
+ [e674d06283d0]
+
+1999-08-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * version.c:
+ Update comments about syslog name tables
+ [63830a782dcb]
+
+ * CHANGES, LICENSE, Makefile.in, configure, configure.in, parse.yacc,
+ strcasecmp.c, sudo.tab.c:
+ include strcasecmp() for those without it
+ [a0d8e2488bbc]
+
+ * sample.sudoers:
+ Use the : operator some more and fix a typo
+ [18804c70da86]
+
+ * HISTORY:
+ update the history of sudo
+ [9d9b3d5279b3]
+
+ * parse.c, parse.lex, testsudoers.c:
+ CIDR-style netmask support
+ [768644467353]
+
+ * CHANGES:
+ recent changes
+ [a4319e9d07cb]
+
+ * sudo.tab.c, sudo.tab.h:
+ these should be generated with byacc, not bison
+ [f57b9489b752]
+
+ * lex.yy.c:
+ regen
+ [522461f95dfa]
+
+ * parse.h, parse.yacc, sudo.tab.c, sudo.tab.h:
+ In "sudo -l" mode, the type of the stored (expanded) alias was not
+ stored with the contents. This could lead to incorrect output if the
+ sudoers file had different alias types with the same name. Normal
+ parsing (ie: not in '-l' mode) is unaffected.
+ [823fe2bc4b79]
+
+1999-08-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ define _XOPEN_SOURCE to get at crypt() proto on some systems
+ [1b3769b86fb9]
+
+1999-08-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * snprintf.c:
+ fix comment
+ [fc1264df00f7]
+
+ * tgetpass.c:
+ don't need limits.h
+ [f1631829af45]
+
+ * snprintf.c:
+ kill bogus reference to vfprintf
+ [a0b99b25d389]
+
+ * sample.sudoers, sudoers:
+ better examples
+ [b4d87ea64cc8]
+
+ * snprintf.c:
+ Add some const in the K&R defs. This is safe since we define const
+ away if the compiler doesn't grok it.
+ [614d6e83d45e]
+
+ * aclocal.m4, configure:
+ Better test for working long long support. Ultrix compiler supports
+ basic long long but not all operations on them.
+ [5da1508710ed]
+
+ * aclocal.m4, auth/secureware.c, config.h.in, configure, getspwuid.c,
+ snprintf.c, sudo.c:
+ Add check for LONG_IS_QUAD #undef MAXINT before including
+ hpsecurity.h to silence an HP-UX warning Check for U?LONG_LONG_MAX
+ in snprintf.c and use LONG_IS_QUAD
+ [a1f7993367fc]
+
+1999-08-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * LICENSE, aclocal.m4, config.h.in, configure, configure.in,
+ snprintf.c:
+ UCB-derived snprintf + asprintf support. Supports quads if the
+ compiler does. No floating point yet, perhaps later...
+ [0caf05aba945]
+
+1999-08-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/API, auth/sudo_auth.c, auth/sudo_auth.h, check.c, find_path.c,
+ goodpath.c, logging.c, parse.c, sudo.c:
+ Run most of the code as root, not the invoking user. It doesn't
+ really gain us anything to run as the user since an attacker can
+ just have an setuid(0) in their egg. Running as root solves
+ potential problems wrt signalling.
+ [408e530dda01]
+
+ * sudo.tab.c:
+ regen
+ [f8cfb37e37de]
+
+1999-08-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c, sudo.c:
+ Don't wait for child to finish in log_error(), let the signal
+ handler get it if we are still running, else let init reap it for
+ us. The extra time it takes to wait lets the user know that mail is
+ being sent.
+
+ Install SIGCHLD handler in main() and for POSIX signals, block
+ everything
+ *except* SIGCHLD.
+ [d2b6ab0ef3be]
+
+ * INSTALL, config.h.in, configure, configure.in, logging.c, parse.c,
+ parse.yacc, sudo.c, sudo.h:
+ sudoers_lookup() now returns a bitmap instead of an int. This makes
+ it possible to express things like "failed to validate because user
+ not listed for this host". Some thigns that were previously
+ VALIDATE_FOO are now FLAG_FOO. This may change later on.
+
+ Reorganized code in log_auth() and sudo.c to deal with above
+ changes.
+
+ Safer versions of push/pushcp with in the do { ... } while (0) style
+
+ parse.yacc now saves info on the stack to allow parse.c to determine
+ if a user was listed, but not for the host he/she tried to run on.
+
+ Added --with-mail-if-no-host option
+ [63326cb01efc]
+
+1999-08-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc, sudo.h, sudo.tab.c, visudo.c, visudo.cat, visudo.html,
+ visudo.man, visudo.pod:
+ o NewArgv and NewArgc don't need to be externally visible. o If
+ pedantic > 1, it is a parse error. o Add -s (strict) option to
+ visudo which sets pedantic to 2.
+ [5d7d81b55cd5]
+
+ * HISTORY, INSTALL:
+ Just have sudo-bugs contact info in one place
+ [e7f6588ea683]
+
+ * sudo.cat, sudo.html, sudo.man, sudo.pod:
+ Add BUGS section
+ [6607d96ea510]
+
+ * Makefile.in, configure, configure.in:
+ Add testsudoers to default build target if --with-devel Don't clean
+ generated parser files unless "distclean".
+ [5827b769dc57]
+
+ * parse.yacc, sudo.tab.c:
+ In pedantic mode we need to save *all* the aliases, not just those
+ that match, or we get spurious warnings.
+ [24f5b1f0e1de]
+
+ * TROUBLESHOOTING:
+ reference samples.sylog.conf
+ [11841668380a]
+
+1999-08-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sample.syslog.conf:
+ Sample entries for syslog.conf
+ [0f7697d878a1]
+
+ * CHANGES:
+ recent changes
+ [8bca8810c6bd]
+
+ * auth/API, auth/afs.c, auth/aix_auth.c, auth/dce.c, auth/fwtk.c,
+ auth/kerb4.c, auth/kerb5.c, auth/pam.c, auth/passwd.c,
+ auth/rfc1938.c, auth/secureware.c, auth/securid.c, auth/sia.c,
+ auth/sudo_auth.c, auth/sudo_auth.h:
+ In struct sudo_auth, turn need_root and configured into flags and
+ add a flag to specify an auth method is running alone (the only
+ one). Pass auth methods their sudo_auth pointer, not the data
+ pointer. This allows us to get at the flags and tell if we are the
+ only auth method. That, in turn, allows the method to be able to
+ decide what should/should not be a fatal error. Currently only
+ rfc1938 uses it this way, which allows us to kill the OTP_ONLY
+ define and te hackery that went with it. With access to the
+ sudo_auth struct, methods can also get at a string holding their
+ cannonical name (useful in error messages).
+ [b7e320fc6511]
+
+ * INSTALL, Makefile.in, README, config.h.in, configure, configure.in,
+ getspwuid.c, lex.yy.c, parse.lex, parse.yacc, sudo.tab.c,
+ sudo.tab.h:
+ o --with-otp deprecated, use --without-passwd instead o real
+ dependencies in the Makefile o --with-devel option to enable yacc,
+ lex, and -Wall o style -- "foo -> bar" becomes "foo->bar" o ALL goes
+ back to being a token, not a string but don't leak memory o rename
+ hsotspec -> host in parse.yacc
+ [912c45226cb2]
+
+1999-08-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS, CHANGES:
+ recent changes
+ [801fa6e55687]
+
+ * auth/sudo_auth.c, configure, configure.in, interfaces.c, snprintf.c,
+ sudo.c, sudo.h:
+ o Digital UNIX needs to check for *snprintf() before -ldb is added
+ to LIBS since -ldb includes a bogus snprintf(). o Add forward refs
+ for struct mbuf and struct rtentry for Digital UNIX. o Reorder some
+ functions in snprintf.c to fix -Wall o Add missing includes to fix
+ more -Wall
+ [8d207203e126]
+
+ * INSTALL, auth/sudo_auth.c, check.c, config.h.in, configure,
+ configure.in, parse.yacc, sudo.tab.c, testsudoers.c, version.c,
+ visudo.c:
+ o Add a "pedentic" flag to the parser. This makes sudo warn in cases
+ where an alias may be used before it is defined. Only turned on for
+ visudo and testsudoers. o Add --disable-authentication option that
+ makes sudo not require authentication by default. The PASSWD tag can
+ be used to require authentication for an entry. We no longer
+ overload --without-passwd.
+ [f307e09adf98]
+
+ * lex.yy.c, parse.lex:
+ Break 'WORD' regexp def into HOSTNAME and USERNAME. These days a
+ username can contain just about anything so be very permissive. Also
+ drop the unused \. punctuation.
+ [06a50614ff89]
+
+1999-08-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc, sudo.tab.c:
+ o add a 'val' element to aliasinfo struct and move -> parse.h o
+ find_alias() now returns an aliasinfo * instead of boolean o
+ add_alias() now takes a value parameter to store in the
+ aliasinfo.val o The cmnd, hostspec, runasuser, and user rules now
+ return: 1) positive match 0) negative match (due to '!')
+ -1) no match This means setting $$ explicitly in all cases, which I
+ should have done in the first place. It also means that we always
+ store a value that is != -1 and when we see a '!' we can set
+ *_matches to !rv if rv != -1. The upshot of all of this is that '!'
+ now works the way it should in lists and some of the rules are more
+ uniform and sensible.
+ [ad8e73b5d581]
+
+ * Makefile.in:
+ add parse.h dependency
+ [4ccccd464d30]
+
+ * parse.h:
+ kill unused *_matched macros
+ [02cba6dcb732]
+
+ * parse.yacc:
+ Allow a list of users as the first thing in a user spec, not just a
+ single entry. This makes things more uniform, though it does allow
+ you to write user specs that are hard to read.
+ [3c4c91c508ca]
+
+ * sudo.tab.c:
+ parse.yacc
+ [feca81881bb6]
+
+ * configure:
+ regen
+ [6f247010bb3b]
+
+ * configure.in:
+ fix check for crypt() in libufc
+ [82770736f4b0]
+
+1999-08-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README:
+ sudo-users list now exists
+ [4716d2bb0bbf]
+
+ * INSTALL, PORTING, README, TODO, TROUBLESHOOTING:
+ Update to reality.
+ [1eda2d57e42a]
+
+ * CHANGES, Makefile.in, TODO, TROUBLESHOOTING, check.c, compat.h,
+ config.h.in, configure, configure.in, fileops.c, logging.c, sudo.h,
+ version.c, visudo.c:
+ o Move lock_file() and touch() into fileops.c so visudo can use them
+ o Visudo now locks the sudoers temp file instead of bailing when the
+ temp file already exists. This fixes the problem of stale temp files
+ but it does *require* that you not try to put the temp file in a
+ world-writable directory. This shoud not be an issue as the temp
+ file should live in the same dir as sudoers. o Visudo now only
+ installs the temp file as sudoers if it changed.
+ [2517cd06c070]
+
+1999-08-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ add fcntl locking
+ [c304adeaf515]
+
+ * config.h.in, configure, configure.in, logging.c:
+ Lock the log file.
+ [d8652704fbdf]
+
+ * Makefile.in, TROUBLESHOOTING, parse.c, pathnames.h.in, sudo.c,
+ visudo.c, visudo.cat, visudo.html, visudo.man, visudo.pod:
+ o /etc/stmp -> /etc/sudoers.tmp since solaris uses stmp as shadow
+ temp file o _PATH_SUDO_SUDOERS -> _PATH_SUDOERS and _PATH_SUDO_STMP
+ -> _PATH_SUDOERS_TMP
+ [68cad8975807]
+
+1999-08-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, check.c, config.h.in, configure, configure.in, version.c:
+ o Kill *_MESSAGE and replace with NO_LECTURE o Add more things to
+ root sudo -V config reporting
+ [cdd2613a9dcf]
+
+ * configure, configure.in:
+ aix_auth.o not authenticate.o
+ [d972e35f6730]
+
+ * config.h.in:
+ Add --with-goodpri and --with-badpri configure options to specify
+ the syslog priority to use.
+ [2595ae50ab86]
+
+ * INSTALL, configure, configure.in, logging.h:
+ Add --with-goodpri and --with-badpri configure options to specify
+ the syslog priority to use.
+ [8276ee9b2b49]
+
+ * compat.h:
+ kill crufty AIX stuff
+ [a4f35ef9854e]
+
+ * Makefile.in:
+ Sigh, some versions of make (like Solaris's) don't deal with $< like
+ I would expect. Both GNU and BSD makes get this right but... So, we
+ just expand $< inline at the cost of some ugliness.
+ [b1b456f8801f]
+
+ * version.c:
+ If the invoking user is root, sudo will now print configure info in
+ -V mode. Currently just prints logging info, to be expanded later.
+ [392f7ed99267]
+
+ * logging.c, logging.h, sudo.c, sudo.h:
+ o new defines for syslog facility and priority o use new
+ print_version() functino for -V mode
+ [78abc5142985]
+
+ * check.c:
+ Don't need version.c
+ [db9a830ad893]
+
+ * aclocal.m4, config.h.in, configure, configure.in:
+ Add check for syslog facilities and priorities tables in syslog.h
+ [b86213e5fc5c]
+
+ * Makefile.in:
+ o authenticate -> aix_auth o add version.c
+ [44b6b9a8d0f5]
+
+ * auth/sudo_auth.c:
+ Missed a prompt -> user_prompt conversion
+ [e4c60b1f210c]
+
+1999-08-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TODO:
+ sudo should lock its logfile
+ [6d2830b28b07]
+
+ * parse.yacc, sudo.tab.c:
+ o Add '!' correctly when expanding Aliases. o Add shortcut macros
+ for append() to make things more readable. o The separator in
+ append() is now a string instead of a char. o In append(), only
+ prepend the separator if the last char is not a '!'. This is a hack
+ but it greatly simplifies '!' handling. o In -l mode, Runas lists
+ and NOPASSWD/PASSWD tags are now inherited across entries in a list
+ (matches current behavior). o Fix formatting in -l mode such that
+ items in a list are separated by a space. Greatlt improves
+ readability. o Space for name field in struct aliasinfo is now
+ allocated dyanically instead of using a (big) buffer. o In
+ add_alias(), only search the list once (lsearch instead of lfind +
+ lsearch)
+ [51f7e07addb9]
+
+ * lex.yy.c, sudo.tab.c, sudo.tab.h:
+ regen
+ [5c19bb05dc21]
+
+ * configure, configure.in:
+ Solais pam doesn't require anye xtra setup
+ [a25ba03d91d1]
+
+ * parse.yacc:
+ o Simpler '!' support now that the lexer deals with multiple !'s for
+ us. o In the case of opFOO, have FOO give a boolean return value and
+ set foo_matches in opFOO, not FOO. o Treat 'ALL' as a string since
+ it gets fill()'d in parse.lex--fixes a small memory leak. In the
+ long run it may be better to just fix parse.lex and make ALL back
+ into a token. However, having it be a string is useful since it can
+ be easily passed back to the parent rule if we so desire.
+ [b3c64b443018]
+
+ * parse.lex:
+ o Remove some unnecessary backslashes o collapse multiple !'s by
+ using !+ and checking if yyleng is even or odd. this allows us to
+ simplify ! handling in parse.yacc
+ [76330e8da8e3]
+
+ * sudo.c:
+ -u flag was being ignored
+ [e30283207585]
+
+1999-08-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ correct fix
+ [a0e2377dec8f]
+
+ * Makefile.in:
+ work around pod2man stupididy
+ [7c755640b67f]
+
+ * Makefile.in:
+ correct dependencies for .cat
+ [5ed7b0653b68]
+
+ * sudo.cat, sudo.man, visudo.cat, visudo.man:
+ regen
+ [b74510dd6a0a]
+
+ * sudo.pod, visudo.pod:
+ Add copyright Update to reality
+ [188e9b046c15]
+
+ * parse.c, sudo.c, sudo.h:
+ rename validate() to the more descriptive sudoers_lookup()
+ [7a1cb652f379]
+
+ * auth/aix_auth.c:
+ use tgetpass
+ [b8ba5daec40a]
+
+1999-07-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ updates
+ [e61460cdf4a0]
+
+ * HISTORY, INSTALL, Makefile.in, README, RUNSON, TROUBLESHOOTING,
+ configure, configure.in, sudo.c:
+ Sudo, not CU Sudo
+ [9061b3573c0c]
+
+ * LICENSE:
+ add 4th term to license similar to term 5 in the apache license
+ [92712e895afb]
+
+ * emul/search.h, emul/utime.h:
+ add 4th term to license similar to term 5 in the apache license
+ [4f93a8b9396e]
+
+ * auth/afs.c, auth/aix_auth.c, auth/dce.c, auth/fwtk.c, auth/kerb4.c,
+ auth/kerb5.c, auth/pam.c, auth/passwd.c, auth/rfc1938.c,
+ auth/secureware.c, auth/securid.c, auth/sia.c, auth/sudo_auth.c,
+ auth/sudo_auth.h, insults.h, interfaces.c, interfaces.h, lex.yy.c,
+ logging.c, logging.h, parse.c, parse.h, parse.lex, parse.yacc,
+ pathnames.h.in, putenv.c, strerror.c, sudo.c, sudo.h, sudo.tab.c,
+ sudo_setenv.c, testsudoers.c, tgetpass.c, utime.c, version.h,
+ visudo.c:
+ add 4th term to license similar to term 5 in the apache license
+ [afae9f2bf9ec]
+
+ * ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h:
+ add 4th term to license similar to term 5 in the apache license
+ [c389d3fdafac]
+
+ * Makefile.in, alloc.c, check.c, compat.h, config.h.in, find_path.c,
+ getspwuid.c, goodpath.c:
+ add 4th term to license similar to term 5 in the apache license
+ [969e63dbd38e]
+
+ * LICENSE, aclocal.m4, auth/rfc1938.c, check.c, configure.in,
+ insults.h, logging.c, sudo.c, sudo.h:
+ there was a 1995 release too
+ [5963fd89457a]
+
+1999-07-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ updates
+ [254b794f16ab]
+
+ * check.c:
+ Use dirs instead of files for timestamp. This allows tty and non-
+ tty schemes to coexist reasonably. Note, however, that when you
+ update a tty ticket, the mtime on the user dir gets updated as well.
+ [44bfac32f799]
+
+ * configure, configure.in:
+ Fix getprpwnam() checking on SCO. Need to link with "-lprot -lx"
+ when linking test program, not just -lprot. Also add check for
+ getspnam(). The SCO docs indicate that /etc/shadow can be used but
+ this may be a lie.
+ [2ba21d36cc1e]
+
+1999-07-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/API:
+ first cut at auth API description
+ [3d10df021eb8]
+
+1999-07-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/fwtk.c, auth/kerb4.c, auth/kerb5.c, auth/pam.c, auth/rfc1938.c,
+ auth/secureware.c, auth/securid.c, auth/sudo_auth.c,
+ auth/sudo_auth.h:
+ auth API change. There is now an init method that gets run before
+ the main loop. This allows auth routines to differentiate between
+ initialization that happens once vs. setup that needs to run each
+ time through the loop.
+ [76df1c0d3478]
+
+ * auth/kerb5.c, logging.c:
+ use easprintf() and evasprintf()
+ [fd97d96dc12f]
+
+ * alloc.c, sudo.h:
+ add easprintf() and evasprintf(), error checking versions of
+ asprintf() and vasprintf()
+ [f54385de20b7]
+
+ * TODO:
+ remove 2 items. One done, one won't do.
+ [64513b47bc7a]
+
+ * lex.yy.c, sudo.tab.c:
+ regen
+ [4aa299de2752]
+
+ * configure, sudo.cat, sudo.html, sudo.man, sudoers.html, visudo.cat,
+ visudo.html, visudo.man:
+ regen
+ [553c0d1209be]
+
+ * CHANGES:
+ new changes
+ [d7be00b7e36b]
+
+ * sudo.pod:
+ o Document -K flag and update meaning of -k flag. o BSD-style
+ copyright o Document clearing of BIND resolver environment variables
+ o Clarify bit about shared libs o suggest rc files create /tmp/.odus
+ if your OS gives away files
+ [4a4092be1455]
+
+ * visudo.pod:
+ BSD license
+ [ad0bfd0a4630]
+
+ * version.h:
+ BSD-style copyright
+ [ecc6479325be]
+
+ * tgetpass.c:
+ o BSD copyright o no need to block signals, we now do that in main()
+ o cosmetic changes
+ [61958beda7ab]
+
+ * testsudoers.c, visudo.c:
+ o BSD-style copyright o Use "struct sudo_user" instead of old
+ globals. o some cometic cleanup
+ [88c0c6924082]
+
+ * sudo_setenv.c:
+ BSD-style copyright
+ [df20290129a0]
+
+ * sudo.h:
+ o BSD copyright o logging and parser bits moved to their own .h
+ files o new "struct sudo_user" to encapsulate many of the old
+ globals.
+ [50fc86bf25cb]
+
+ * sudo.c:
+ o no longer contains sudo 1.1/1.2 code o BSD copyright o use new
+ logging routines o simplified flow of control o BIND resolver
+ additions to badenv_table
+ [8c53f15bfcb0]
+
+ * strerror.c:
+ BSD-style copyright
+ [7c906c3a82ac]
+
+ * snprintf.c:
+ Now compiles on more K&R compilers
+ [07ab1d3231c7]
+
+ * putenv.c:
+ BSD-style copyright, cosmetic changes
+ [c42371295881]
+
+ * pathnames.h.in:
+ BSD-style copyright
+ [e5c34ebd4cf1]
+
+ * parse.c, parse.h, parse.lex, parse.yacc:
+ BSD-style copyright. Move parser-specific defines and structs into
+ parse.h + other cosmetic changes
+ [d3088efb6228]
+
+ * logging.h:
+ defines for logging routines
+ [13147941c02d]
+
+ * find_path.c, getspwuid.c, goodpath.c, interfaces.c:
+ BSD-style copyright, cosmetic changes
+ [e8205e91a4fa]
+
+ * ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h, insults.h,
+ interfaces.h:
+ BSD-style copyright
+ [b9499da7cdce]
+
+ * configure.in:
+ o tgetpass.c is no longer optional o kill DCE_OBJS, add AUTH_OBJS o
+ kill --disable-tgetpass o add --without-passwd o changes to fill in
+ AUTH_OBJS for new auth api o check for strerror(), v?snprintf() and
+ v?asprintf() o replace --with-AuthSRV with --with-fwtk
+ [9a3f39b9c128]
+
+ * config.h.in:
+ BSD-style copyright. Remove USE_GETPASS and HAVE_UTIME_NULL. Add
+ HAVE_FWTK, HAVE_STRERROR, HAVE_SNPRINTF, HAVE_VSNPRINTF,
+ HAVE_ASPRINTF, HAVE_VASPRINTF, WITHOUT_PASSWD and NO_PASSWD
+ [9a09054db53a]
+
+ * compat.h:
+ BSD-style copyright; Add S_IFLNK and MIN/MAX id they are missing.
+ [25509c566975]
+
+ * alloc.c:
+ BSD-style copyright
+ [4967be892363]
+
+ * TROUBLESHOOTING:
+ no more --with-getpass
+ [afd5b670c196]
+
+ * TODO:
+ Take out things I've done...
+ [375420c8270e]
+
+ * README:
+ Refer to LICENSE
+ [c486c8db30f6]
+
+ * PORTING:
+ --with-getpass no longer exists
+ [db48202df1bb]
+
+ * Makefile.in:
+ BSD-style copyright. Update to reflect reality wrt new files and new
+ auth modules.
+ [61a2ca7940fb]
+
+ * INSTALL:
+ Remove --with-AuthSRV and --disable-tgetpass. Add --with-fwtk and
+ --without-passwd.
+ [64e8f9e1c05e]
+
+ * HISTORY:
+ Update history a bit
+ [df60c0a871b8]
+
+ * COPYING, LICENSE:
+ Now distributed under a BSD-style license
+ [d1a184ccabe1]
+
+ * auth/sudo_auth.c:
+ o BSD-style copyright o Add support for NO_PASSWD/WITHOUT_PASSWD
+ options. o skey/opie replaced by rfc1938 code o new struct sudo_user
+ global
+ [891b57060868]
+
+ * auth/pam.c, auth/sia.c:
+ BSD-style copyright and use new log functions
+ [65c44445ea84]
+
+ * auth/kerb5.c:
+ o BSD-style copyright o Use new log functiongs o Use asprintf() and
+ snprintf() where sensible.
+ [1ff0feaacf95]
+
+ * check.c:
+ Rewrote all the old sudo 1.1/1.2 code. Timestamp handling is now
+ done more reasonably--better sanity checks and tty-based stamps are
+ now done as files in a directory with the same name as the invoking
+ user, eg. /var/run/sudo/millert/ttyp1. It is not currently possible
+ to mix tty and non-tty based ticket schemes but this may change in
+ the future (it requires sudo to use a directory instead of a file in
+ the non-tty case). Also, ``sudo -k'' now sets the ticket back to the
+ epoch and ``sudo -K'' really deletes the file. That way you don't
+ get the lecture again just because you killed your ticket in
+ .logout. BSD-style copyright now.
+ [ec3460f85be8]
+
+ * logging.c:
+ o rewritten logging routines. log_error() now takes printf-style
+ varargs and log_auth() for the return value of validate(). o BSD-
+ style copyright
+ [438292025c4e]
+
+ * auth.c, check_sia.c, dce_pwent.c, secureware.c:
+ superceded by new auth API
+ [412060590da7]
+
+ * auth/kerb4.c:
+ BSD-style copyright
+ [cc4e800833c7]
+
+ * auth/fwtk.c:
+ Use snprintf() where it makes sense and add a BSD-style copyright
+ [1b7502388a74]
+
+ * auth/afs.c, auth/aix_auth.c, auth/dce.c, auth/passwd.c,
+ auth/rfc1938.c, auth/secureware.c, auth/securid.c, auth/sudo_auth.h:
+ BSD-style copyright
+ [42583bedae5c]
+
+ * emul/utime.h, utime.c:
+ BSD-style copyright
+ [3985c90aba47]
+
+ * emul/search.h:
+ this has been rewritten so use my BSD-style copyright
+ [176df1b0de6f]
+
+1999-07-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * snprintf.c:
+ include malloc.h if no stdlib.h
+ [7b123f1d1d03]
+
+ * snprintf.c:
+ KTH snprintf()/asprintf() for systems w/o them
+ [3ca9aefb9d01]
+
+ * strerror.c:
+ strerror() for systems w/o it
+ [7f0bd8a1c1b4]
+
+1999-07-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ stylistic changes
+ [6f99aceb7170]
+
+ * parse.c, parse.lex, parse.yacc:
+ Add contribution info in the main comment
+ [e50cec10acd6]
+
+1999-07-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth/pam.c:
+ remove missed ref to PAM_nullpw
+ [a43e59692cdb]
+
+ * auth/sudo_auth.h:
+ pasto
+ [891ff138ab89]
+
+ * auth/kerb5.c:
+ more or less complete now--still untested
+ [21036732faa0]
+
+ * auth/afs.c, auth/pam.c:
+ don't use user_name macro, it will go away
+ [def7cf727349]
+
+ * auth/opie.c, auth/rfc1938.c, auth/skey.c, auth/sudo_auth.h:
+ combine skey/opie code into rfc1938.c
+ [44d88ca93d3e]
+
+ * auth/dce.c, auth/sudo_auth.h:
+ DCE authentication method; basically unchanged from dce_pwent.c
+ [4d468473dd6f]
+
+ * auth/aix_auth.c, auth/sudo_auth.h:
+ AIX authenticate() support. Could probably be much better
+ [000013321a33]
+
+ * auth/sia.c:
+ Fix an uninitialized variable and some cleanup. Now works (tested)
+ [fd6ad88ff055]
+
+ * auth/sia.c, auth/sudo_auth.h:
+ SIA support for digital unix
+ [5335f3e70eab]
+
+ * auth/pam.c:
+ don't use prompt global, it will go away
+ [fadd22dd6ce4]
+
+ * auth/secureware.c:
+ correct copyright years
+ [6aa07c49f51b]
+
+ * auth/afs.c, auth/fwtk.c, auth/kerb4.c, auth/kerb5.c, auth/opie.c,
+ auth/pam.c, auth/passwd.c, auth/secureware.c, auth/securid.c,
+ auth/skey.c, auth/sudo_auth.c, auth/sudo_auth.h:
+ New authentication API and methods
+ [9debe9b59c79]
+
+1999-07-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.tab.c:
+ regen
+ [84578e82c1a6]
+
+ * parse.yacc:
+ only save an entry if user_matches && host_matches, even if the
+ stack is empty (fix for previous commit)
+ [00984b078d8a]
+
+ * sudo.tab.c:
+ regen
+ [66acf160b4b7]
+
+ * parse.yacc:
+ 1) Always save an entry on the stack if it is empty. This fixes the
+ -l and -v flags that were broken by earlier parser changes.
+
+ 2) In a Runas list, don't negate FALSE -> TRUE since that would make
+ !foo match any time the user specified a runas user (via -u) other
+ than foo.
+ [f322eb54b015]
+
+ * testsudoers.c:
+ interfaces and num_interfaces are now auto, not extern
+ [113add5c6518]
+
+1999-07-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth.c:
+ use a static global to keep stae about empty passwords
+ [bc02e30807d8]
+
+ * check_sia.c:
+ make PASSWORD_NOT_CORRECT logging consistent with other modules
+ [21962549d5fd]
+
+1999-07-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * auth.c:
+ PAM prompt code was wrong, looks like we have to kludge it after
+ all.
+ [91f246155ead]
+
+ * auth.c:
+ In the PAM code, when a user hits return at the first password
+ prompt, exit without a warning just like the normal auth code
+ [918f59bacdb7]
+
+ * configure, configure.in:
+ kludge around cross-compiler false positives
+ [5e5fc8356400]
+
+ * auth.c, check.c, check_sia.c, logging.c, sudo.h, tgetpass.c:
+ New (correct) PAM code Tgetpass now takes an echo flag for use with
+ PAM_PROMPT_ECHO_ON Block SIGINT and SIGTSTP during auth remove a
+ useless umask setting Change error from BAD_ALLOCATION ->
+ BAD_AUTH_INIT (for use with sia/PAM) Some cosmetic changes to auth.c
+ for consistency
+ [e71397f09dd8]
+
+ * sudo.c:
+ Some -Wall and kill some trailing spaces
+ [8229b43d5c4e]
+
+ * configure.in:
+ define -D__EXTENSIONS__ for solaris so we get crypt() proto
+ [7533e4436cab]
+
+1999-06-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON:
+ add Dynix 4.4.4
+ [b69f773efbce]
+
+ * INSTALL, config.h.in, configure, configure.in:
+ for kerberos V < version, fall back on old kerb4 auth code
+ [d685ed3a1d8e]
+
+ * INSTALL:
+ clarify some things
+ [2f5ba2e8e53a]
+
+ * UPGRADE, sudoers.cat, sudoers.man, sudoers.pod:
+ typos
+ [8925a109c093]
+
+1999-06-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ mention why DONT_LEAK_PATH_INFO is not the default
+ [0346260cb4ec]
+
+1999-06-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ Fix open(2) return value checking, was NULL for fopen, should be -1
+ for open
+ [355878bf6d8a]
+
+ * configure:
+ regen
+ [68bf82871862]
+
+ * configure.in:
+ better wording for solaris pam notice
+ [04e88c7a6c42]
+
+ * CHANGES:
+ document recent changes
+ [7c922c5622ef]
+
+ * TROUBLESHOOTING:
+ Update shadow password section
+ [e8448bae7d66]
+
+ * auth.c:
+ move authentication code from check.c to auth.c
+ [e9f6ecae2399]
+
+ * Makefile.in, check.c, sudo.h:
+ move authentication code to auth.c
+ [124cded85f46]
+
+1999-05-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, check.c, check_sia.c, compat.h, find_path.c,
+ getspwuid.c, goodpath.c, interfaces.c, interfaces.h, lex.yy.c,
+ logging.c, parse.c, parse.lex, parse.yacc, secureware.c, sudo.c,
+ sudo.h, sudo.tab.c, sudo_setenv.c, testsudoers.c, tgetpass.c,
+ visudo.c:
+ Move interface-related defines to interfaces.h so we don't have to
+ include <netinet/in.h> everywhere.
+ [e7599d8ea0bf]
+
+1999-05-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, INSTALL, TODO, check.c, compat.h, getspwuid.c, logging.c,
+ parse.yacc, sudo.c, sudo.tab.c, tgetpass.c:
+ o Replace _PASSWD_LEN braindeath with our own SUDO_MAX_PASS. It
+ turns out the old DES crypt does the right thing with passwords
+ longert than 8 characters. o Fix common typo (necesary -> necessary)
+ o Update TODO list
+ [ad75007a6f13]
+
+1999-05-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ set $LOGNAME when we set $USER
+ [391596210fd7]
+
+1999-04-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ add comment about digital unix and interfaces.c warning with gcc
+ [e20f815901cc]
+
+1999-04-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sample.sudoers:
+ use modern paths and give examples for some of the new parser
+ features
+ [e7b2e507c695]
+
+1999-04-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ fix comment
+ [5eb0d005a65f]
+
+ * alloc.c, check.c, check_sia.c, dce_pwent.c, find_path.c,
+ getspwuid.c, goodpath.c, interfaces.c, lex.yy.c, logging.c, parse.c,
+ parse.lex, parse.yacc, putenv.c, secureware.c, sudo.c, sudo.tab.c,
+ sudo_setenv.c, testsudoers.c, tgetpass.c, utime.c, visudo.c:
+ Function names should be flush with the start of the line so they
+ can be found trivially in an editor and with grep
+ [3c400abde574]
+
+ * find_path.c, interfaces.c, lex.yy.c, parse.c, parse.lex, parse.yacc,
+ sudo.c, sudo.tab.c, testsudoers.c, tgetpass.c, visudo.c:
+ free(3) is already void, no need to cast it
+ [6981e1ebda0f]
+
+ * logging.c, sudo.c, sudo.h:
+ catch case where cmnd_safe is not set (this should not be possible)
+ [3e1e3038546c]
+
+ * CHANGES, logging.c, parse.c, parse.yacc, sudo.c, sudo.h, sudo.tab.c,
+ testsudoers.c, visudo.c:
+ Stash the "safe" path (ie: the one listed in sudoers) to the command
+ instead of stashing the struct stat. Should be safer.
+ [aa2883fcf57e]
+
+1999-04-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, Makefile.in, UPGRADE:
+ notes on updating from an earlier release
+ [df9fffa4ab2c]
+
+ * CHANGES:
+ updated
+ [574f5065d15a]
+
+1999-04-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc, sudo.tab.c, sudo.tab.h, sudoers.cat, sudoers.html,
+ sudoers.man, sudoers.pod:
+ You can now specifiy a host list instead of just a host or alias.
+ Ie: user = host1,host2,ALIAS,!host3 my_command now works.
+ [e3942bb78021]
+
+ * testsudoers.c:
+ Quiet -Wall
+ [a3edc8b08c3a]
+
+ * parse.yacc, sudo.tab.c:
+ Move the push from the beginning of cmndspec to the end. This means
+ we no longer have to do a push at the end of privilege, just reset
+ some values.
+ [8ea66e5860c6]
+
+ * sudoers.cat, sudoers.html, sudoers.man, sudoers.pod:
+ runas-lists and NOPASSWD/PASSWD modifiers are now sticky and you can
+ use "!" most everywhere
+ [aadae4d1c9d5]
+
+1999-04-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ modernize paths and update su example based on sample.sudoers one
+ [3f6a37e16c83]
+
+ * sample.sudoers:
+ New runas semantics
+ [756ee92865b7]
+
+ * CHANGES, Makefile.in, alloc.c, config.h.in, configure, configure.in,
+ strdup.c, sudo.h:
+ In estrdup(), do the malloc ourselves so we don't need to rely on
+ the system strdup(3) which may or may not exist. There is now no
+ need to provide strdup() for those w/o it. Also, the prototype for
+ estrdup() was wrong, it returns char * and its param is const.
+ [5f1f984da8e3]
+
+ * getcwd.c:
+ $Sudo tag
+ [e4188a35e68c]
+
+ * check.c:
+ buf should be prompt; Michael Robokoff <mrobo@networkcs.com>
+ [2aec87c86cde]
+
+ * CHANGES, TODO, parse.yacc, sudo.tab.c:
+ It is now possible to use the '!' operator in a runas list as well
+ as in a Cmnd_Alias, Host_Alias and User_Alias.
+ [a4fdaabda990]
+
+ * logging.c, sudo.h:
+ Kill GLOBAL_NO_SPW_ENT (not used) and crank GLOBAL_PROBLEM
+ [73d0376785ae]
+
+ * sudo.h:
+ Definitions of *_matched were wrong--user top, not top-2 as
+ subscript.
+ [5f8350a57362]
+
+ * logging.c, parse.c, parse.yacc, sudo.c, sudo.h, sudo.tab.c:
+ Add VALIDATE_NOT_OK_NOPASS for when user is not allowed to run a
+ command but the NOPASSWD flag was set. Make runasspec, runaslist,
+ runasuser, and nopasswd typeless in parse.yacc Add support for '!'
+ in the runas list Fix double printing of '%' and '+' for groups and
+ netgroups respectively Add *_matched macros (no need for local stack
+ variable). Should only be used directly after a pop (since top must
+ be >= 2).
+ [392b1400c4e6]
+
+ * aclocal.m4, configure.in:
+ Add copyright, somewhat silly
+ [55c2cdd82dca]
+
+1999-04-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS, INSTALL, Makefile.in, README, alloc.c, check.c, check_sia.c,
+ compat.h, config.h.in, configure, configure.in, dce_pwent.c,
+ emul/utime.h, find_path.c, getspwuid.c, goodpath.c, ins_2001.h,
+ ins_classic.h, ins_csops.h, ins_goons.h, insults.h, interfaces.c,
+ lex.yy.c, logging.c, parse.c, parse.lex, parse.yacc, pathnames.h.in,
+ putenv.c, secureware.c, strdup.c, sudo.c, sudo.cat, sudo.h,
+ sudo.man, sudo.tab.c, sudo_setenv.c, sudoers.cat, sudoers.man,
+ testsudoers.c, tgetpass.c, utime.c, version.h, visudo.c, visudo.cat,
+ visudo.man:
+ Crank version to 1.6 and combine copyright statements
+ [0e1c791658ae]
+
+ * sample.sudoers:
+ Use ! not ^ to do negation
+ [1480a0761730]
+
+ * lex.yy.c, sudo.tab.c:
+ regen
+ [89ca5a46684b]
+
+ * parse.lex, parse.yacc:
+ Make runas and NOPASSWD tags persistent across entris in a command
+ list. Add a PASSWD tag to reverse NOPASSWD. When you override a
+ runas or *PASSWD tag the value given becomes the new default for the
+ rest of the command list.
+ [f1bbb4066542]
+
+1999-04-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, RUNSON:
+ update for 1.5.9
+ [a1ae9d4a7d54] [SUDO_1_5_9]
+
+ * visudo.c:
+ Shift return value of system(3) by 8 to get real exit value and if
+ it is not 1 or 0 print the retval along with the error message.
+ [c1ff50d743fb]
+
+1999-03-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ testsudoers needs LIBOBJS too
+ [972571b4e4bf]
+
+ * parse.c, parse.yacc, sudo.tab.c:
+ Fix another parser bug. For a sudoers entry like this: millert
+ ALL=/bin/ls,(daemon) !/bin/ls sudo would not allow millert to run ls
+ as root.
+ [51968e1eb33d]
+
+ * CHANGES:
+ new change
+ [271c6110bb62]
+
+ * parse.yacc, sudo.tab.c:
+ Save entries that match a ! command on the matching stack too
+ [5afb5107116c]
+
+ * sudo.c:
+ Make sudo's usage info better when mutually exclusive args are given
+ and don't rely on argument order to detect this; nick@zeta.org.au
+ [2422753c88fd]
+
+1999-03-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, Makefile.in, RUNSON:
+ updates from CU
+ [b37381e3dafb]
+
+ * Makefile.in:
+ use gzip
+ [94a64e52a166]
+
+ * parse.yacc, sudo.tab.c:
+ Fix off by one error introduced in *alloc changes
+ [95ede581153a]
+
+ * BUGS, CHANGES, INSTALL, Makefile.in, README, alloc.c, check.c,
+ check_sia.c, compat.h, config.h.in, configure, configure.in,
+ dce_pwent.c, emul/utime.h, find_path.c, getspwuid.c, goodpath.c,
+ ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h, insults.h,
+ interfaces.c, lex.yy.c, logging.c, parse.c, parse.lex, parse.yacc,
+ pathnames.h.in, putenv.c, secureware.c, strdup.c, sudo.c, sudo.cat,
+ sudo.h, sudo.man, sudo.tab.c, sudo_setenv.c, sudoers.cat,
+ sudoers.man, testsudoers.c, tgetpass.c, utime.c, version.h,
+ visudo.c, visudo.cat, visudo.html, visudo.man, visudo.pod:
+ ++version
+ [c6d88f024e37]
+
+ * Makefile.in, check.c, find_path.c, getspwuid.c, goodpath.c,
+ interfaces.c, lex.yy.c, logging.c, parse.c, parse.lex, parse.yacc,
+ putenv.c, secureware.c, strdup.c, sudo.c, sudo.h, sudo.tab.c,
+ sudo_setenv.c, testsudoers.c, utime.c, visudo.c:
+ Use emalloc/erealloc/estrdup
+ [44221d97361a]
+
+ * alloc.c:
+ error checking memory allocation routines
+ [5f8c1e7bbc71]
+
+ * parse.yacc, sudo.tab.c:
+ Still not right, this fixes it for real
+ [ad553b6f5339]
+
+ * parse.yacc, sudo.tab.c:
+ Fix for previous commit
+ [4d6f989f9bf2]
+
+ * CHANGES, INSTALL, parse.yacc:
+ Fix a parser bug that was exposed when mixing different runas specs
+ and ! commands. For example: millert ALL=(daemon)
+ /usr/bin/whoami,!/bin/ls would allow millert to run whoami as root
+ as well as daemon when it should just allow daemon. The problem was
+ that comma-separated commands in a list shared the same entry on the
+ matching stack. Now they get their own entry iff there is a full
+ match. It may be better to just make the runas spec persistent
+ across all commands in a list like the user and host entries of the
+ matching stack. However, since that is a fairly major change it
+ should gets its own minor rev increase.
+ [c4b939cdcc8e]
+
+1999-03-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c, config.h.in:
+ Simplify PAM code and fix a PAM-related warning on Linux
+ [2468399523b6]
+
+1999-03-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ updates
+ [29d4a997769c]
+
+ * sample.sudoers:
+ better su entry
+ [76d8285a72ba]
+
+ * configure:
+ regen
+ [b7450cc6975d]
+
+ * check.c, configure.in:
+ new pam code that works on solaris, should work on linux too;
+ aelberg@home.com
+ [84c16c0ff259]
+
+1999-03-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON:
+ more entries
+ [b6bef8660759]
+
+ * config.h.in:
+ only include strings.h if there is no string.h
+ [b66054a32b00]
+
+1999-03-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.guess:
+ Sinix is now being called ReliantUNIX; bjjackso@us.oracle.com
+ [c086d2fe63af]
+
+1999-03-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ shost must be set before log functions are called #ifdef HOST_IN_LOG
+ [d49a7944358f]
+
+1999-03-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, lex.yy.c, parse.lex:
+ Fix a bug wrt quoting characters in command args. Stop processing an
+ arg when you hit a backslash so the quoted-character detection can
+ catch it.
+ [2281438d7f41]
+
+1999-02-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * interfaces.c:
+ include sys/time.h; aparently AIX needs it. ppz@cdu.elektra.ru
+ [31118a9e9916]
+
+1999-02-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ add missing case statement so --without-sendmail works
+ [ca25614f7dd9]
+
+1999-02-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ more
+ [4d70e44f7f93]
+
+1999-02-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ only search for -lsun in irix <= 4.x
+ [e604238317b1]
+
+ * configure, configure.in:
+ back out last configure.in change now that I've hacked autoconf to
+ fix the real problem and add a missing newline
+ [2dabf59a79b5]
+
+ * CHANGES:
+ updated
+ [bb35d526552f]
+
+ * getcwd.c:
+ add def of dirfd() for those without it
+ [95f0173d8441]
+
+ * configure, configure.in:
+ When falling back to checking for socket() when linking with
+ "-lsocket -lnsl" check for main() instead since autoconf has already
+ cached the results of checking for socket() in -lsocket. This is
+ really an autoconf bug as it should use the extra libs as part of
+ the cache variable name.
+ [a845f8b710ad]
+
+ * configure.in:
+ typo
+ [a7d62f62a478]
+
+1999-02-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ fix occurrence of $with_timeout that should be
+ $with_password_timeout; Michael.Neef@neuroinformatik.ruhr-uni-
+ bochum.de
+ [8c4da2cf73d1]
+
+1999-02-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.cat, sudo.html, sudo.man, sudo.pod:
+ fix grammar; espie@openbsd.org
+ [7031d9dfbc3e] [SUDO_1_5_8]
+
+1999-02-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc, sudo.c, testsudoers.c:
+ add cast for strdup in places it does not have it
+ [7ce4478d3b0f]
+
+1999-02-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ define for_BSD_TYPES irix
+ [858337ff4af8]
+
+1999-02-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, sudo.cat, sudo.html, sudo.man, sudo.pod:
+ Make it clear that it is the user's password, not root's, that we
+ want.
+ [ae0f51b35ee4]
+
+ * check.c, sudo.h:
+ If the user enters an empty password and really has no password,
+ accept the empty password they entered. Perviously, they could enter
+ anything
+ *but* an empty password. Also, add GETPASS macro that calls either
+ tgetpass() or getpass() depending on how sudo was configured.
+ Problem noted by jdg@maths.qmw.ac.uk
+ [2fde21ce94c1]
+
+1999-02-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, check.c, check_sia.c, compat.h, config.h.in,
+ dce_pwent.c, emul/utime.h, find_path.c, getspwuid.c, goodpath.c,
+ ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h, insults.h,
+ interfaces.c, logging.c, parse.c, parse.lex, parse.yacc,
+ pathnames.h.in, putenv.c, secureware.c, strdup.c, sudo.c, sudo.h,
+ sudo_setenv.c, testsudoers.c, tgetpass.c, utime.c, version.h,
+ visudo.c:
+ add explicate copyright
+ [d3b4449834a5]
+
+ * CHANGES:
+ mention -lsocket, -lnsl configure changes
+ [9140af4ad8ae]
+
+1999-02-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Don't clobber errno after calling check_sudoers().
+ [59bd581b2654]
+
+1999-02-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ When linking with both -lsocket and -lnsl be sure to do so in that
+ order. Also, when we can't find socket() or inet_addr() and have to
+ try linking with both libs, issue a warning.
+ [0ee547163067]
+
+ * sudo.cat, sudo.man, sudo.pod:
+ clarify bad timestamp and fmt
+ [70e42cf56c75]
+
+1999-01-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, RUNSON:
+ be clear that pam is linux-only and add a RUNSON entry
+ [7fdeab875e0d]
+
+1999-01-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, INSTALL, configure, configure.in:
+ fix and correctly document --with-umask; problem noted by
+ adap@adap.org
+ [11cd0481d63a]
+
+1999-01-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure, configure.in:
+ only use /usr/{man,catman}/local to store man pages if suer didn't
+ override prefix or mandir
+ [781ad2cbe9be]
+
+ * INSTALL, configure, configure.in:
+ fix typo, make --with-SecurID take an arg
+ [026a9b4014fc]
+
+1999-01-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON:
+ updates from users
+ [2286982b31e6]
+
+ * CHANGES, INSTALL, check.c, configure, configure.in:
+ FWTK 'authsrv' support from Kevin Kadow <kadow@MSG.NET>
+ [23aa4e5c6b02]
+
+ * configure, configure.in:
+ better fix for the problem of unresolved symbols in -lnsl or
+ -lsocket
+ [82fe70fc287f]
+
+ * configure, configure.in:
+ when checking for functions in -lnsl and -lsocket link with both of
+ them to avoid unresolved symbols on some weirdo systems
+ [1734a591808e]
+
+1999-01-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS, CHANGES, RUNSON, TODO:
+ old changes that didn't make it into RCS before the RCS->CVS switch
+ [846eb2b8f9aa]
+
+1999-01-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, check.c, check_sia.c, compat.h, config.h.in,
+ configure.in, dce_pwent.c, emul/search.h, emul/utime.h, find_path.c,
+ getspwuid.c, goodpath.c, ins_2001.h, ins_classic.h, ins_csops.h,
+ ins_goons.h, insults.h, interfaces.c, lex.yy.c, logging.c,
+ lsearch.c, parse.c, parse.lex, parse.yacc, pathnames.h.in, putenv.c,
+ secureware.c, strdup.c, sudo.c, sudo.pod, sudo_setenv.c,
+ sudoers.pod, testsudoers.c, tgetpass.c, utime.c, visudo.c,
+ visudo.pod:
+ add sudo tags
+ [962f81eaa5ab]
+
+ * sudo.h:
+ testing Sudo tag
+ [e84cbc521129]
+
+ * version.h:
+ testing Sudo tag
+ [a8c3a3998b88]
+
+ * BUGS, INSTALL, Makefile.in, README, check.c, check_sia.c, compat.h,
+ config.h.in, configure, configure.in, dce_pwent.c, emul/utime.h,
+ find_path.c, getspwuid.c, goodpath.c, ins_2001.h, ins_classic.h,
+ ins_csops.h, ins_goons.h, insults.h, interfaces.c, lex.yy.c,
+ logging.c, parse.c, parse.lex, parse.yacc, pathnames.h.in, putenv.c,
+ secureware.c, strdup.c, sudo.c, sudo.cat, sudo.h, sudo.man,
+ sudo_setenv.c, sudoers.cat, sudoers.man, testsudoers.c, tgetpass.c,
+ utime.c, version.h, visudo.c, visudo.cat, visudo.man:
+ crank version and regen files
+ [23eacf00a1a4]
+
+ * Makefile.in:
+ kill rcs goop in update_version and fix now that version is a const
+ [e6e50bd8d1e1]
+
+ * INSTALL, check.c, config.h.in, configure, configure.in, logging.c,
+ sudo.c, sudo.h, sudo.pod:
+ kerb5 support from fcusack@iconnet.net
+ [8134027986e2]
+
+ * realpath.c, sudo_realpath.c:
+ we no longer use realpath
+ [0f5f64abc646]
+
+ * qualify.c:
+ replaced by find_path.c
+ [9e32a87e09c4]
+
+ * options.h:
+ all options are now configure flags
+ [ee6bd9610102]
+
+ * lex.yy.c:
+ regen
+ [bdbf8a18161f]
+
+ * getwd.c:
+ superceded by getcwd.c
+ [1e54ee0990b4]
+
+ * getpass.c:
+ superceded by tgetpass.c
+ [4e0d1edc30e3]
+
+ * SUPPORTED:
+ superceded by RUNSON
+ [854c5a21cb53]
+
+ * OPTIONS:
+ No longer used now that we have configure options for everything.
+ [9b1ae1c89259]
+
+ * configure:
+ regen based on configure.in
+ [3a4d73936973]
+
+ * sudo.cat, sudo.html, sudo.man, sudoers.cat, sudoers.html,
+ sudoers.man, visudo.cat, visudo.html, visudo.man:
+ regen based on sudo.pod, sudoers.pod, and visudo.pod
+ [c267beb90778]
+
+1998-12-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ fix tty tickets in remove_timestamp (didn't use ':')
+ [fd964a74a32b]
+
+1998-12-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * interfaces.c:
+ close sock when we are done with it
+ [95de0380f8a4]
+
+1998-11-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ never say "error on line -1"
+ [361db1491121]
+
+1998-11-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ check for -lnsl before -lsocket
+ [8e966d6bbcb5]
+
+ * configure.in:
+ quote '[', ']' used in ranges correctly
+ [fa4f9c6ff651]
+
+1998-11-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ add missing NO_ROOT_SUDO noted by drno@tsd.edu
+ [c969f25d1667]
+
+1998-11-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * version.h:
+ 1.5.7
+ [7a22de0bc148]
+
+ * INSTALL:
+ more info for 1.5.7
+ [30ad9e784799]
+
+ * README:
+ update for 1.5.7
+ [cd03a0a27cd2]
+
+ * parse.yacc:
+ make increases of cm_list_size and ga_list_size be similar to
+ increases of stacksize (ie: >= not > in initial compare).
+ [6bd450a896c7]
+
+ * parse.yacc:
+ when we get a syntax error, report it for the previous line since
+ that's generally where the error occurred.
+ [c4ac84058f0b]
+
+1998-11-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in, configure.in, interfaces.c:
+ add back check for sys/sockio.h but only use it if SIOCGIFCONF is
+ not defined
+ [d197f31fd1e4] [SUDO_1_5_7]
+
+ * config.h.in:
+ define BSD_COMP for svr4
+ [87ac1147ff79]
+
+ * check.c, check_sia.c, find_path.c, getcwd.c, getspwuid.c,
+ goodpath.c, interfaces.c, logging.c, lsearch.c, parse.c, parse.lex,
+ parse.yacc, putenv.c, secureware.c, strdup.c, sudo.c, sudo_setenv.c,
+ testsudoers.c, tgetpass.c, utime.c, visudo.c:
+ more -Wall
+ [d98e2d32db2a]
+
+ * configure.in:
+ kill check for sockio,h
+ [4399779014c1]
+
+ * config.h.in:
+ no more HAVE_SYS_SOCKIO_H
+ [67484528e347]
+
+ * check.c, check_sia.c, find_path.c, getcwd.c, getspwuid.c,
+ goodpath.c, interfaces.c, logging.c, lsearch.c, parse.c, parse.lex,
+ parse.yacc, putenv.c, secureware.c, strdup.c, sudo.c, sudo_setenv.c,
+ testsudoers.c, tgetpass.c, utime.c, visudo.c:
+ -Wall
+ [2b7e83976788]
+
+1998-11-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ add missing inform_user()
+ [8689528c6d55]
+
+1998-11-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * find_path.c:
+ return NOT_FOUND if given fully qualified path and it does not exist
+ previously it would perror(ENOENT) which bypasses the option to not
+ leak path info
+ [ccbc3d0130ae]
+
+ * configure.in:
+ for kerb5, check for -lkerb4, fall back on -lkrb for kerb, check for
+ -ldes
+ [c77d3b484ece]
+
+1998-11-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ tty tickets are user:tty now
+ [a53a303a614d]
+
+ * check.c:
+ when using tty tickets make it user:tty not user.tty as a username
+ could have a '.' in it
+ [3160b3f5c890]
+
+1998-11-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ add "ignoring foo found in ." for auth successful case
+ [24257169e0bd]
+
+1998-11-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ add missing printf param
+ [8c905124f777]
+
+1998-11-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, config.h.in, configure.in, find_path.c, sudo.c, sudo.h:
+ go back to printing "command not found" unless --disable-path-info
+ specified. Also, tell user when we ignore '.' in their path and it
+ would have been used but for --with-ignore-dot.
+ [066e118c11e4]
+
+ * check.c, sudo.c:
+ Only one space after a colon, not two, in printf's
+ [38452f4c8007]
+
+1998-11-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod:
+ document setting $USER
+ [80557fe6aede]
+
+ * check.c:
+ fix bugs with prompt expansion
+ [44c4fca5f009]
+
+ * sudo.c:
+ set $USER for root too
+ [4b525e1c6269]
+
+1998-11-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * getspwuid.c:
+ typo
+ [5107446f43e0]
+
+ * configure.in:
+ HP-UX's iscomsec is in -lsec, not libc
+ [03c9f700b795]
+
+ * configure.in:
+ remove some entries in the OS case statement that did nothing
+ [ea96e7e0f624]
+
+ * TROUBLESHOOTING:
+ add "cd" section and flush out syslog section
+ [5107f7363b78]
+
+ * Makefile.in:
+ no more sudo-lex.yy.c
+ [ed50826efbbc]
+
+ * check_sia.c:
+ add custom prompt support
+ [6a285cea10b7]
+
+ * testsudoers.c:
+ kill perror("malloc") since we already have a good error messages
+ pw_ent -> pw for brevity
+ [eee31052921e]
+
+ * sudo.c:
+ kill perror("malloc") since we already have a good error messages
+ pw_ent -> pw for brevity set $USER if -u specified
+ [9f3753461f8a]
+
+ * parse.yacc:
+ kill perror("malloc") since we already have a good error messages
+ [849459088ac3]
+
+ * parse.c:
+ kill perror("malloc") since we already have a good error messages
+ pw_ent -> pw for brevity when checking if %group matches, look up
+ user in password file so that %groups works in a RunAs spec.
+ [0489b4ecc59a]
+
+ * logging.c:
+ kill perror("malloc") since we already have a good error messages
+ [3191a18b3526]
+
+ * check.c, getspwuid.c, interfaces.c:
+ kill perror("malloc") since we already have a good error messages
+ pw_ent -> pw for brevity
+ [7193fdb38cf9]
+
+1998-11-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ the prompt is expanded before tgetpass is called
+ [0f408f508041]
+
+ * sudo.h:
+ tgetpass now has the same args as getpass again
+ [b6778cd9d79f]
+
+ * getspwuid.c:
+ add iscomsec, issecure support
+ [007be7ec7ae7]
+
+ * check.c:
+ we now expand any %h or %u in the prompt before passing to tgetpass
+ [f3db8c9ee387]
+
+ * configure.in:
+ add check for syslog(3) in -lsocket, -lnsl, -linet
+ [5a96f902ce00]
+
+ * config.h.in:
+ add HAVE_ISCOMSEC and HAVE_ISSECURE
+ [f640b0d4cf05]
+
+ * configure.in:
+ add check for iscomsec in HP-UX
+ [b28b249040f0]
+
+ * configure.in:
+ check for issecure if we have getpwanam on SunOS some options are
+ incompatible with DUNIX SIA check for dispcrypt on DUNIX
+ [a49d05d9c913]
+
+1998-10-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ add HAVE_DISPCRYPT
+ [7376d543d8d6]
+
+ * secureware.c:
+ add back support for non-dispcrypt based checking for older DUNIX
+ [977b98e936be]
+
+ * INSTALL:
+ sia changes
+ [c5387c06e30f]
+
+ * configure.in:
+ SIA becomes the default on Digital UNIX now havbe --disable-sia to
+ turn it off...
+ [3b647558ea13]
+
+ * check.c:
+ move local includes after system ones
+ [b2abad4c4aef]
+
+1998-10-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c, check_sia.c, sudo.h:
+ add pass_warn() which prints out INCORRECT_PASSWORD or an insult to
+ stderr
+ [547cbf299661]
+
+ * check_sia.c:
+ fix while loop in sia_attempt_auth() that checks the password. Only
+ the first iteration was working.
+ [1886fd1ac831]
+
+1998-10-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4:
+ don't trust UID_MAX or MAXUID
+ [2aeddb1654d8]
+
+ * configure.in:
+ fix two pastos
+ [c18f0a10b75d]
+
+ * configure.in:
+ fix typo
+ [1eb3190ef12d]
+
+ * getspwuid.c, secureware.c:
+ init crypt_type to INT_MAX since it is legal to be negative in DUNX
+ 5.0
+ [cefbde04822d]
+
+ * configure.in:
+ for secureware on dunix, use -lsecurity -ldb -laud -lm but check for
+ -ldb since DUNX < 4.0 lacks it
+ [e6b11d971068]
+
+1998-10-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c, compat.h, config.h.in, configure.in, getspwuid.c,
+ secureware.c, sudo.c, tgetpass.c:
+ getprpwuid is broken in HP-UX 10.20 at least (it sleeps for 2
+ minutes if the shadow files don't exist).
+ [2f297d095004]
+
+1998-10-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ updated --with-editor blurb
+ [77d8a3ea7328]
+
+ * TROUBLESHOOTING:
+ tell how to put sudoers in a different dir
+ [456cd20eb1d0]
+
+ * configure.in:
+ add missing quotes around $with_editor
+ [22881748ab1b]
+
+ * configure.in:
+ typo in --with-editor bits
+ [ab6964580681]
+
+ * INSTALL:
+ I don't expect it to work on Solaris
+ [1c2fceaaf56e]
+
+ * check.c:
+ add back security/pam_misc.h
+ [6ffd30033c1e]
+
+1998-10-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ remove dunix note since configure checks for this now
+ [e9904512b8e8]
+
+ * configure.in:
+ add check for broken dunix prot.h (4.0 < 4.0D is bad)
+ [8a4c1e6aef3b]
+
+ * getspwuid.c, secureware.c, tgetpass.c:
+ new dunix shadow code, use dispcrypt(3)
+ [1b936bc7268c]
+
+ * config.h.in:
+ add HAVE_INITPRIVS
+ [4369f4c4f914]
+
+ * sudo.c:
+ call initprivs() if we have it for getprpwuid later on
+ [11cf5915d826]
+
+ * Makefile.in:
+ clean pathnames.h too
+ [5f1df3262613]
+
+ * configure.in:
+ quote "Sorry, try again." with [] since it has a comma in it set
+ LIBS when we add stuff to SUDO_LIBS set SECUREWARE when we find
+ getprpwuid() so we can check for bigcrypt, set_auth_parameters, and
+ initprivs later.
+ [e226b0a3f250]
+
+ * INSTALL:
+ update Digital UNIX note about acl.h
+ [80132b71d73a]
+
+ * INSTALL:
+ add --with-sia
+ --without-root-sudo -> --disable-root-sudo some reordering
+ [198386358818]
+
+ * secureware.c:
+ add whitespace
+ [4aadaf1a54b0]
+
+ * Makefile.in, check.c, config.h.in, configure.in, logging.c, sudo.h:
+ add SIA support
+ [fa3ddbb9cc51]
+
+ * check_sia.c:
+ Initial revision
+ [2968551d40e4]
+
+1998-10-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ when checking for -lsocket, -lnsl, and -linet, check for the
+ specific functions we need from them.
+ [8d33e64362a3]
+
+ * config.h.in, sudo.h:
+ move Syslog_* defs into sudo.h
+ [03d1774f25c7]
+
+ * Makefile.in, sudo.h:
+ added check_secureware
+ [e46e3cbb9a97]
+
+ * configure.in:
+ finished adding AC_MSG_CHECKING and AC_MSG_RESULT bits
+ [dbefe1856503]
+
+ * insults.h:
+ don't define CLASSIC_INSULTS and CSOPS_INSULTS if no other sets
+ defined. configure now does that for us
+ [e4520ea0581f]
+
+ * configure.in:
+ move some --with options around change a bunch of echo's to
+ AC_MSG_CHECKING, AC_MSG_RESULT pairs
+ [ffdf6869fdd7]
+
+ * configure.in:
+ change $with_foo-bar -> $with_foo_bar kill extra " that caused a
+ syntax error add some echo verbage
+ [3278c49bf74b]
+
+1998-10-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ moved SecureWare stuff into secureware.c
+ [42d3d3ac35dc]
+
+ * secureware.c:
+ Initial revision
+ [aa7f72a249cf]
+
+ * INSTALL:
+ update url to solaris gcc bins
+ [36a3eb668777]
+
+ * INSTALL:
+ change option formatter and flesh out someentries
+ [6fbd1db4a8ad]
+
+ * TROUBLESHOOTING, sudo.pod, visudo.pod:
+ environmental variable -> environment variable
+ [6f14d708e32d]
+
+ * BUGS:
+ everything is now done via configure
+ [c217858f58ab]
+
+ * README:
+ prev rev was 1.5.6
+ [7b4177103c35]
+
+ * Makefile.in:
+ passing SUDOERS_MODE, SUDOERS_UID, SUDOERS_GID correctly
+ [31c6b0a5e0e2]
+
+ * config.h.in:
+ SUDOERS_MODE, SUDOERS_UID, SUDOERS_GID now come from the Makefile
+ [d406a1ef6d25]
+
+ * Makefile.in:
+ merge OSDEFS and OPTIONS into DEFS get sudoers_uid, sudoers_gid,
+ sudoers_mode from configure
+ [1c509500655a]
+
+ * configure.in:
+ SUDOERS_MODE, SUDOERS_UID, and SUDOERS_GID now get substituted into
+ the Makefile, not config.h
+ [d4482f1492fe]
+
+ * INSTALL:
+ document all --with/--enable options
+ [22d81b312d7f]
+
+1998-10-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * insults.h:
+ options.h is no more
+ [560946a33f7f]
+
+ * config.h.in:
+ assimilated options.h
+ [dd8ce74613c1]
+
+ * configure.in:
+ moved options from options.h to configure
+ [d39662f71b4e]
+
+ * check.c, find_path.c, getspwuid.c, goodpath.c, interfaces.c,
+ logging.c, parse.c, parse.lex, parse.yacc, sudo.c, sudo.pod,
+ sudo_setenv.c, visudo.c:
+ no more options.h
+ [43924bf0858d]
+
+ * INSTALL, Makefile.in, PORTING, TROUBLESHOOTING:
+ remove references to options.h
+ [ef3474295395]
+
+ * dce_pwent.c, interfaces.c, sudo.c:
+ kill sys/time.h
+ [4d833f0034e4]
+
+ * tgetpass.c:
+ if select return < -1 still prompt for pw
+ [e0009e5c93a2]
+
+ * options.h:
+ convert LOGGING, LOGFAC, MAXLOGFILELEN, IGNORE_DOT_PATH into
+ configure options
+ [e60a1e546516]
+
+ * parse.c:
+ FAST_MATCH is no longer an optino
+ [c448dbb3464b]
+
+ * check.c:
+ remove_timestamp() if timestamp is preposterous
+ [70d9a86c6ecd]
+
+ * options.h:
+ convert more options to --with/--enable
+ [34646d9b09dc]
+
+ * INSTALL, aclocal.m4:
+ logfile -> logpath
+ [42de502bc637]
+
+ * configure.in:
+ convert more options into --with and --enable
+ [92d0898c9844]
+
+ * tgetpass.c:
+ catch EINTR in select and restart
+ [f045d2f234d7]
+
+ * logging.c:
+ sys/errno -> errno
+ [7f0c5beab6f2]
+
+1998-09-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ UMASK -> SUDO_UMASK.
+ [48f308661514]
+
+ * check.c, logging.c:
+ time.h, not sys/time.h
+ [91de049c79e4]
+
+1998-09-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ MAILER -> _PATH_SENDMAIL
+ [df65d6896639]
+
+ * INSTALL, configure.in:
+ no more --with-C2, now it is --disable-shadow
+ [18bfcab3b9ab]
+
+ * aclocal.m4, check.c, compat.h, config.h.in, configure.in,
+ getspwuid.c, sudo.c, tgetpass.c:
+ new shadow password scheme. Always include shadow support if the
+ platform supports it and the user did not disable it via configure
+ [2135d93bb4a9]
+
+1998-09-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ --with-getpass -> --{enable,disable}-tgetpass
+ [451b33fdd4c7]
+
+ * Makefile.in:
+ pathnames.h -> pathnames.h.in
+ [b109022eca69]
+
+ * check.c:
+ fix version string
+ [761b25c314ea]
+
+ * check.c:
+ move pam_conv to be static to auth function remove pam_misc.h
+ (solaris doesn't have one)
+ [a682e4da987a]
+
+ * aclocal.m4:
+ _CONFIG_PATH_* -> _PATH_* or _PATH_SUDO_* kill SUDO_PROG_PWD
+ [e6005d0599b5]
+
+ * configure.in:
+ munge pathnames.h.in -> pathnames.h kill SUDO_PROG_PWD
+ [24c0ac2155ef]
+
+ * pathnames.h.in:
+ convert to pathnames.h.in
+ [013bddf7f684]
+
+1998-09-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ fix typo in sysv4 matching case /.
+ [2994c4f88cf5]
+
+1998-09-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ pam stuff needs to run as root, not user, for shadow passwords
+ [d94ff75de503]
+
+1998-09-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS, INSTALL, README, configure.in:
+ updated version
+ [775adc7de7ac]
+
+ * Makefile.in, check.c, compat.h, config.h.in, dce_pwent.c,
+ emul/utime.h, find_path.c, getspwuid.c, goodpath.c, ins_2001.h,
+ ins_classic.h, ins_csops.h, ins_goons.h, insults.h, interfaces.c,
+ logging.c, options.h, parse.c, parse.lex, parse.yacc,
+ pathnames.h.in, putenv.c, strdup.c, sudo.c, sudo.h, sudo_setenv.c,
+ testsudoers.c, tgetpass.c, utime.c, visudo.c:
+ updated version
+ [5ca599fb6b93]
+
+ * check.c:
+ user version.h for long message
+ [47a52ac7e542]
+
+ * check.c:
+ this is version 1.5.6
+ [8451ac79eee2]
+
+1998-09-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ remove errant backslash
+ [0222a8a650ff]
+
+1998-09-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * options.h, parse.yacc, pathnames.h.in:
+ fix version string
+ [fdee73255d64] [SUDO_1_5_6]
+
+ * BUGS, CHANGES, TODO:
+ updtaed for 1.5.6
+ [752443bf7f26]
+
+ * RUNSON:
+ updated for 1.5.6
+ [0f878123fe6a]
+
+1998-09-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * interfaces.c:
+ kill unused localhost_mask var copy if name to ifr_tmp after we zero
+ it
+ [8e89c364cef2]
+
+1998-09-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ Better description of new vs. old sudoers modes fix some typos
+ better description of /usr/ucb/cc gotchas on slowaris
+ [c00b2a6fc1e8]
+
+ * Makefile.in:
+ add sample.pam
+ [ec7f6cc19b00]
+
+ * sudo.c:
+ set NewArgv[0] to user_shell, not basename(user_shell)
+ [1e907cbc9f7b]
+
+1998-09-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README:
+ mention TROUBLESHOOTING more fix some typos
+ [2c2e6907d4a4]
+
+ * configure.in:
+ move --enable/--disable to be after --with
+ [9b30097f76c1]
+
+ * INSTALL:
+ document --enable/--disable
+ [c522362e38a8]
+
+ * INSTALL:
+ document --with-pam
+ [7e38932c78ac]
+
+1998-09-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ Add message for pam users
+ [d224f277e3cd]
+
+ * sample.pam:
+ Initial revision
+ [3a84d7045f54]
+
+ * config.h.in:
+ fix HAVE_PAM
+ [2f0f303ebd88]
+
+ * check.c, config.h.in, configure.in:
+ pam support, from Gary Calvin <GCalvin@kenwoodusa.com>
+ [ea3e0a72d707]
+
+1998-09-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ add HOST_IN_LOG and WRAP_LOG
+ [822c36eeb6a8]
+
+ * logging.c:
+ add WRAP_LOG and HOST_IN_LOG
+ [3cf6052bd27e]
+
+ * configure.in:
+ add --enable-log-host and --enable-log-wrap
+ [c968cc12b353]
+
+ * aclocal.m4:
+ use AC_DEFINE_UNQUOTED for --with-logfile and --with-timedir
+ [915fef7e11a1]
+
+1998-09-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat.h:
+ add howmany macro
+ [9107a057a7c8]
+
+ * tgetpass.c:
+ include sys/param.h to get howmany macro
+ [7e908b5e1f32]
+
+1998-09-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * OPTIONS, options.h, parse.yacc, sudo.c, testsudoers.c, visudo.c:
+ add RUNAS_DEFAULT
+ [1e76398ea3fd]
+
+1998-09-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * fnmatch.c:
+ bring in stdio.h for NULL
+ [69c016610cbb]
+
+ * aclocal.m4:
+ allow /bin/{ksh,bach} and /usr/bin/{ksh,bash} as sh
+ [15ab2972f8d0]
+
+ * sudo.c:
+ use HAVE_SET_AUTH_PARAMETERS
+ [8abfdc8c80f7]
+
+ * config.h.in:
+ add HAVE_SET_AUTH_PARAMETERS
+ [673a5ebd5539]
+
+ * configure.in:
+ add *-*-hiuxmpp* add test for set_auth_parameters() if secureware
+ [a401f5a7469a]
+
+ * config.sub:
+ add support for HI-UX/MPP SR220001 02-03 0 SR2201
+ [cb657b7acaae]
+
+ * interfaces.c:
+ initialize previfname
+ [26a1902f56dc]
+
+ * interfaces.c:
+ Don't use SIOCGIFADDR, we don't need it Use SIOCGIFFLAGS if we have
+ it check ifr_flags against IFF_UP and IFF_LOOPBACK instead of
+ kludging it
+ [fa5c890c313b]
+
+ * configure.in:
+ typo
+ [bff579fbe95c]
+
+ * Makefile.in:
+ don't need special build line for sudo.tab.o
+ [10c0a0a912e4]
+
+ * Makefile.in:
+ don't clean sudo.tab.[ch]
+ [c40d5968efbb]
+
+ * sudo.c:
+ Sudo should prompt for a password before telling the user that a
+ command could not be found.
+ [d718c85a0047]
+
+ * BUGS:
+ for 1.5.6
+ [0cc1fe5b9129]
+
+ * INSTALL, README:
+ no longer require yacc
+ [d9096fc5b8b6]
+
+ * Makefile.in:
+ typo
+ [70feb1aefbd5]
+
+ * Makefile.in:
+ y.tab -> sudo.tab include pre-yacc'd parse.yacc
+ [cc802025fd44]
+
+ * parse.lex:
+ include sudo.tab.h, not y.tab.h don't break out of command args if
+ you get a '='
+ [728ad26dbda5]
+
+ * insults.h:
+ fix version ,
+ [242bbce1b2d4]
+
+ * ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h:
+ fix version
+ [2bb9086fea1e]
+
+ * compat.h:
+ fix version
+ [7e634d498ce6]
+
+ * getcwd.c:
+ getcwd(3) from OpenBSD for those without it.
+ [6c68d0df8f6c]
+
+ * sudo.h:
+ HAVE_GETWD -> HAVE_GETCWD
+ [2ad1e64d60c0]
+
+ * configure.in:
+ pretend sunos doesn't have getcwd(3) since it opens a pipe to
+ getpwd!
+ [677992ba5a6a]
+
+ * parse.c:
+ use NAMLEN() macro
+ [8f5685aa3165]
+
+ * fnmatch.c:
+ remove duplicate include of string.h
+ [6024f3051ac3]
+
+ * configure.in:
+ call SUDO_TYPE_DEV_T and SUDO_TYPE_INO_T
+ [3d82a9c22cc2]
+
+ * aclocal.m4:
+ add SUDO_TYPE_DEV_T and SUDO_TYPE_INO_T
+ [53fbc47282f9]
+
+ * config.h.in:
+ add dev_t and ino_t
+ [5929bb0c7e1a]
+
+1998-07-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ fix OTP_ONLY for opie
+ [7edcfa78f2ec]
+
+1998-06-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * testsudoers.c, tgetpass.c:
+ include stdlib.h for malloc proto
+ [c9f4b99a2fe9]
+
+1998-05-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ make update_version saner
+ [d522f93ee04a]
+
+ * config.h.in:
+ add HAVE_WAITPID, HAVE_WAIT3, and sudo_waitpid()
+ [c9a2d21dc608]
+
+ * configure.in:
+ check for waitpid and wait3 or no waitpid
+ [1f18c3224184]
+
+ * logging.c:
+ used waitpid or wait3 if we have 'em
+ [391c3279ee65]
+
+1998-05-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ fix some fprintf args, ariel@oz.engr.sgi.com (Ariel Faigon)
+ [fbf53b18178f]
+
+1998-04-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ don't need to explicately mention -lsocket -lnsl for sequent
+ [1898dc055352]
+
+1998-04-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ dynix should not link with -linet
+ [278a4b9cfe2a]
+
+1998-04-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ mention that HP-UX doesn't ship with yacc
+ [bde5147198c0]
+
+1998-04-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ ignore kerberos if we can't get the local realm
+ [1e311a091a27]
+
+1998-04-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS, INSTALL, README, configure.in:
+ ++version
+ [499ffc746018]
+
+ * version.h:
+ ++
+ [35ba1ee01bd3]
+
+ * Makefile.in, check.c, config.h.in, dce_pwent.c, emul/utime.h,
+ find_path.c, getcwd.c, getspwuid.c, goodpath.c, interfaces.c,
+ logging.c, parse.c, parse.lex, putenv.c, strdup.c, sudo.c, sudo.h,
+ sudo_setenv.c, testsudoers.c, tgetpass.c, utime.c, visudo.c:
+ updated version
+ [b4990a513f31]
+
+ * check.c, sudo.h:
+ fix version
+ [5710795834e8]
+
+ * getcwd.c:
+ don't use popen/pclose. Do it inline.
+ [29e57b0646a4]
+
+ * lsearch.c:
+ add rcsid
+ [b2b55c39858d]
+
+ * sudo.c:
+ typo
+ [d381ac39ed0f]
+
+ * check.c, compat.h, ins_2001.h, ins_classic.h, ins_csops.h,
+ ins_goons.h, insults.h, options.h, parse.yacc, pathnames.h.in,
+ sudo.h:
+ updated version
+ [462d6e1a2d75]
+
+ * check.c, find_path.c, parse.c, sudo.c, testsudoers.c:
+ MAX* + 1 -> MAX*
+ [2c2eeb78d34f]
+
+ * Makefile.in:
+ getwd.c -> getcwd.c
+ [7d718c32fc02]
+
+ * config.h.in:
+ kill HAVE_GETWD
+ [6ad3d702343f]
+
+ * configure.in:
+ getcwd, not getwd
+ [33e5b9841f58]
+
+ * getcwd.c:
+ use MAX* not MAX* + 1 always run pwd as using getwd() defeats the
+ purpose
+ [24e58d340161]
+
+1998-03-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * OPTIONS, options.h:
+ add STUB_LOAD_INTERFACES
+ [d747cb23ca83]
+
+ * Makefile.in, check.c, compat.h, config.h.in, dce_pwent.c,
+ emul/utime.h, find_path.c, getspwuid.c, getwd.c, goodpath.c,
+ ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h, insults.h,
+ interfaces.c, logging.c, options.h, parse.c, parse.lex, parse.yacc,
+ pathnames.h.in, putenv.c, strdup.c, sudo.c, sudo.h, sudo_setenv.c,
+ testsudoers.c, tgetpass.c, utime.c, visudo.c:
+ updated version
+ [0798229312cc]
+
+ * configure.in:
+ support *-ccur-sysv4 and fix two typos
+ [24a823ad7cc9]
+
+1998-03-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ don't echo about with_logfile and with_timedir
+ [31e4a1e2d9ad]
+
+ * INSTALL:
+ document --with-logfile and --with-timedir
+ [674f811a40e0]
+
+ * aclocal.m4:
+ support --with-logfile and --with-timedir
+ [2fc36b35db12]
+
+ * configure.in:
+ Add --with-logfile and --with-timedir
+ [09045bf07e29]
+
+ * sudo.c:
+ change size computation of NewArgv for UNICOS
+ [b50df07da3a1]
+
+1998-02-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ treate -*-sysv4* like *-*-svr4
+ [471b7ef4dbf2]
+
+1998-02-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ fix spacing for --with-authenticate help
+ [8321cb37c410]
+
+ * Makefile.in, check.c, compat.h, config.h.in, dce_pwent.c,
+ emul/utime.h, find_path.c, getspwuid.c, getwd.c, goodpath.c,
+ ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h, insults.h,
+ interfaces.c, logging.c, options.h, parse.c, parse.lex, parse.yacc,
+ pathnames.h.in, putenv.c, strdup.c, sudo.c, sudo.h, sudo_setenv.c,
+ testsudoers.c, tgetpass.c, utime.c, visudo.c:
+ updated version
+ [dc1ab97312eb]
+
+ * parse.yacc:
+ fix off by one error in push macro
+ [bece59c8c3a9]
+
+1998-02-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ removed bogus alloca hack
+ [a68dd720462d]
+
+ * check.c:
+ added AIX 4.x authenticate() support
+ [12985eb448a0]
+
+ * parse.yacc:
+ include alloca.h if using bison and not gcc and it exists. fixes an
+ alloca problem on hpux 10.x
+ [e3b5c4f26072]
+
+ * INSTALL:
+ mention --with-authenticate
+ [78a1c96820e7]
+
+ * configure.in:
+ added AIX authenticate() support
+ [c983193ec252]
+
+ * config.h.in:
+ add HAVE_AUTHENTICATE
+ [7b0e5f5db5d9]
+
+ * interfaces.c:
+ dynamically size ifconf buffer
+ [10afb0e9b2f9]
+
+ * configure.in:
+ quote '[' and ']'
+ [8fc38a4defad]
+
+ * Makefile.in, check.c, compat.h, config.h.in, dce_pwent.c,
+ emul/utime.h, find_path.c, getspwuid.c, getwd.c, goodpath.c,
+ ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h, insults.h,
+ logging.c, options.h, parse.c, parse.lex, parse.yacc,
+ pathnames.h.in, putenv.c, strdup.c, sudo.c, sudo.h, sudo_setenv.c,
+ testsudoers.c, tgetpass.c, utime.c, visudo.c:
+ updated version
+ [5f66de71ec61]
+
+ * visudo.pod:
+ add ERRORS section
+ [3df3edb73cf6]
+
+1998-02-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TROUBLESHOOTING:
+ add busy stmp file explanation
+ [6c555d469b6f]
+
+1998-02-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ the name of the cached var that signals whether or not you are cross
+ compiling changed. It is now ac_cv_prog_cc_cross
+ [123911c0658c]
+
+1998-02-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ mention glibc 2.07 is fixed wrt lsearch()\.
+ [ded758524582]
+
+1998-02-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sample.sudoers, sudoers.pod:
+ better example of su but not root su
+ [b3199610be21]
+
+1998-02-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, check.c, compat.h, config.h.in, dce_pwent.c,
+ emul/utime.h, find_path.c, getspwuid.c, getwd.c, goodpath.c,
+ ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h, insults.h,
+ interfaces.c, logging.c, options.h, parse.c, parse.lex, parse.yacc,
+ pathnames.h.in, putenv.c, strdup.c, sudo.c, sudo.h, sudo_setenv.c,
+ testsudoers.c, tgetpass.c, utime.c, visudo.c:
+ updated version
+ [46922b84e86b]
+
+ * Makefile.in:
+ correct regexp for updating version
+ [8032728b2a8a]
+
+ * tgetpass.c:
+ remove bogus flush of stderr spew prompt before turning off echo.
+ Seems to fix a weird problem where if sudo complained about a bogus
+ stamp file the user would sometimes not have a chance to enter a
+ password
+ [7aa1493cc141]
+
+ * check.c:
+ fix bogus flush of stderr
+ [6d047871c5e8]
+
+ * sudo.c:
+ close fd's <=2 not <=3 and move that chunk of code up
+ [553e4faac195]
+
+ * configure.in:
+ support hpux1[0-9] not just hpux10
+ [5a34a000ff8a]
+
+1998-01-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ set sudoers_fp to nil after closing
+ [221a8b4bbf34]
+
+1998-01-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.guess, config.sub:
+ updated from autoconf 2.12
+ [6fc86a0fc61b]
+
+ * configure.in:
+ add *-*-svr4 rule
+ [38f0427f7c9d]
+
+1998-01-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ fix select usage for high fd's (dynamically allocate readfds)
+ [c2d1f76e0321]
+
+ * check.c:
+ kill extra whitespace
+ [d784b6c9c514]
+
+ * sudo.c:
+ do an initgroups() before running a command, unless the target user
+ is root.
+ [4ca561287480]
+
+1998-01-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TROUBLESHOOTING:
+ tell people to use tabs, not spaces, in syslog.conf
+ [8ae90a205134]
+
+1998-01-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, config.h.in, dce_pwent.c, emul/utime.h, getwd.c,
+ parse.lex, putenv.c, strdup.c, testsudoers.c, utime.c:
+ updated version
+ [4d855ff5de26]
+
+ * check.c, find_path.c, getspwuid.c, goodpath.c, interfaces.c,
+ logging.c, parse.c, sudo.c, sudo_setenv.c, tgetpass.c, visudo.c:
+ updated version
+ [8e007e178b33]
+
+ * compat.h, ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h,
+ insults.h, options.h, parse.yacc, pathnames.h.in, sudo.h:
+ updated version
+ [9ddea5c8814d]
+
+ * Makefile.in:
+ more tweaks to update_version
+ [047698752855]
+
+ * Makefile.in:
+ fixed up update_version rule
+ [47b6fa34b77f]
+
+ * configure.in:
+ ++version
+ [c1ca664e30b7]
+
+ * Makefile.in:
+ removed supe of check.c
+ [8f340a05296a]
+
+ * INSTALL:
+ ++version I missed
+ [a298e6c17491]
+
+ * RUNSON:
+ updated
+ [a14f6057bc15]
+
+ * BUGS, INSTALL, Makefile.in, README, check.c, compat.h, config.h.in,
+ dce_pwent.c, emul/utime.h, find_path.c, getspwuid.c, getwd.c,
+ goodpath.c, ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h,
+ insults.h, interfaces.c, logging.c, options.h, parse.c, parse.lex,
+ parse.yacc, pathnames.h.in, putenv.c, strdup.c, sudo.c, sudo.h,
+ sudo_setenv.c, testsudoers.c, tgetpass.c, utime.c, version.h,
+ visudo.c:
+ updated version
+ [02231b1a3ab3]
+
+ * CHANGES:
+ updated for 1.5.5
+ [634e5fcaf40b]
+
+ * Makefile.in:
+ add rules to update version stuff in files so I don't need to do it
+ by hand
+ [3620ad60485a]
+
+ * sudo.h:
+ sudoers_fp is now extern
+ [88c6e9b9ea84]
+
+ * sudo.c:
+ in check_sudoers, cache the sudoers file handle in sudoers_fp so we
+ don't have to open it again in the parse. This may help with weird
+ solaris problems where EAGAIN sometime occurrs.
+ [d3c26451ed1d]
+
+ * parse.c:
+ sudoers file open is now done only in check_sudoers() so we just do
+ a rewind() instead of an open. May help people on solaris who were
+ getting EAGAIN.
+ [c8b8c7722fa5]
+
+1998-01-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ mention that newer glibc is fixed
+ [20f06f5d3ef3]
+
+1998-01-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ newer irix uses _RLDN32_* envariables for 32-bit binaries so ignore
+ _RLD* instead of _RLD_*
+ [1e22c588d602]
+
+ * parse.c:
+ typo
+ [d0b7cb85f08a]
+
+ * parse.c:
+ fix that bug for real
+ [5a6eeca6d04b]
+
+ * INSTALL:
+ document Linux's libc6 brokenness.
+ [0246c1aa64ee]
+
+ * parse.yacc:
+ -Wall
+ [d0e452fb1e2d]
+
+ * RUNSON:
+ updated
+ [4949a1bbd0a9] [SUDO_1_5_4]
+
+ * TROUBLESHOOTING:
+ remind people to HUP syslogd
+ [590962faa4f0]
+
+ * Makefile.in:
+ add -O flag to tar
+ [622d02de339d]
+
+ * RUNSON:
+ updated
+ [a72930d6e615]
+
+ * TODO:
+ updated
+ [4a51bd458390]
+
+ * sudo.pod:
+ remove author's email addr. people should mail sudo-bugs
+ [9b6bbdb3a6d9]
+
+ * INSTALL:
+ fix version
+ [246274c6c8af]
+
+ * README, check.c, compat.h, config.h.in, configure.in, dce_pwent.c,
+ find_path.c, getspwuid.c, getwd.c, goodpath.c, ins_2001.h,
+ ins_classic.h, ins_csops.h, ins_goons.h, insults.h, interfaces.c,
+ logging.c, options.h, parse.c, parse.lex, parse.yacc,
+ pathnames.h.in, putenv.c, strdup.c, sudo.c, sudo.h, sudo_setenv.c,
+ testsudoers.c, tgetpass.c, utime.c, version.h, visudo.c:
+ ++version
+ [f532ff4ee766]
+
+ * RUNSON:
+ updated
+ [62d5c71358b5]
+
+ * INSTALL, Makefile.in:
+ ++version
+ [1a7c7628edfc]
+
+ * CHANGES:
+ updated fort 1.5.4
+ [7e4873508c99]
+
+ * check.c:
+ exit(1) if user enters no passwd
+ [f382c0e35e4e]
+
+ * BUGS:
+ ++version
+ [fab6a867ab67]
+
+ * parse.c:
+ commands can start with ./* not just /* -- fixes a serious security
+ hole.
+ [244d2fe35ee3]
+
+1997-12-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ Don't set the tty variable to NULL when we lack a tty, leave it as
+ "unknown".
+ [193b26daba03]
+
+1997-11-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sample.sudoers:
+ fix usage of (username) in conjunction with , and !
+ [7ae68607f68f]
+
+ * visudo.c:
+ catch the case where the user is not in the passwd file
+ [31650258deb0]
+
+ * tgetpass.c:
+ use fileno(input) + 1 instead of getdtablesize() as the nfds arg to
+ select(2)
+ [60ab2d9a9ee8]
+
+ * sudo.c:
+ define tty global to an initial value to avoid dumping core in
+ logging functions when passwd file is unavailable.
+ [77056c7bc908]
+
+ * sudo.c:
+ do the set_perms(PERM_USER, sudo_mode) after we have gotten the
+ passwd entry
+ [1fdb8e579a5a]
+
+ * sudo.pod:
+ talk about problem of ALL
+ [1cd1905c9f6f]
+
+1997-10-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README:
+ new web location
+ [d24dc26f6da5]
+
+ * INSTALL:
+ fdesc bug is fixed in Open/Net BSD
+ [7d4d81b08ac3]
+
+ * HISTORY:
+ updates from Nieusma
+ [3a43769a1b78]
+
+1997-10-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * dce_pwent.c:
+ move compat.h after the system includes
+ [5ea43a5968ac]
+
+1997-08-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ save errno from being clobbered by wait(). From Theo
+ [f2d1c48cd592]
+
+1997-05-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat.h:
+ fix an occurence of setresuid -> setreuid (typo)
+ [394de35c9b1c]
+
+1997-03-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * install-sh:
+ check for path to strip
+ [2b7ef824bd55]
+
+1997-01-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ deal with maxfilelen < 0 case
+ [f0af095178d7]
+
+ * OPTIONS:
+ fixed descriptin
+ [629f60bd4b5f]
+
+1996-12-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ correct error message if mode/owner wrong and not statable by owner
+ but is statable by root.
+ [cb631ce2e85e]
+
+1996-11-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.guess, config.sub:
+ autoconf 2.11
+ [f3cbe59e0756]
+
+1996-11-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, RUNSON, TODO:
+ sudo 1.5.3.
+ [2be3229b8626]
+
+1996-11-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc, sudo.h:
+ command_alias -> generic_alias
+ [c404ca8c510d] [SUDO_1_5_3]
+
+ * sample.sudoers:
+ added Runas_Alias example and fixed syntax errors
+ [c304053f4a8a]
+
+ * OPTIONS, options.h:
+ updated MAILSUBJECT
+ [18d1573fcd2a]
+
+ * logging.c:
+ added %h expansion
+ [a4bff9b284fd]
+
+ * INSTALL, Makefile.in, README, check.c, compat.h, config.h.in,
+ configure.in, dce_pwent.c, find_path.c, getspwuid.c, getwd.c,
+ goodpath.c, ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h,
+ insults.h, interfaces.c, logging.c, options.h, parse.c, parse.lex,
+ parse.yacc, pathnames.h.in, putenv.c, strdup.c, sudo.c, sudo.h,
+ sudo_setenv.c, testsudoers.c, tgetpass.c, utime.c, version.h,
+ visudo.c:
+ ++version
+ [211ff20f956f]
+
+ * BUGS, emul/utime.h:
+ ++version
+ [cde5376579e3]
+
+ * sudoers.pod:
+ document Runas_Alias
+ [b1a58f28fb2c]
+
+ * visudo.pod:
+ q (uid) -> Q
+ [d256649a0e6b]
+
+ * visudo.c:
+ buffer oflow checking q (uit) -> Q if yyparse() fails drop into
+ whatnow
+ [1cb183d15626]
+
+ * parse.yacc:
+ add size params to sprintf
+ [9228f698921f]
+
+ * parse.lex:
+ allow trailing space after '\\' but before '\n'
+ [f51dbbf69fdf]
+
+ * find_path.c:
+ off by one error in path size check
+ [a6d75ccd7632]
+
+ * check.c:
+ sprintf paranoia
+ [3ffb12d198dd]
+
+1996-11-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ fixed more_aliases
+ [aab12f2a50af]
+
+ * visudo.c:
+ now warns if killed by signal ./
+ [310c186a0fd7]
+
+1996-11-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ fix Runas_Alias stuff Alias's in runas list now get expanded (but it
+ is gross)
+ [45590b83120f]
+
+ * sudo.c:
+ Can now deal with SUDOERS_UID == 0 and SUDOERS_MODE == 0400
+ [d53e01c14c58]
+
+ * parse.yacc:
+ add Runas_Alias support change FOO to FOO_ALIAS (ie: USER_ALIAS)
+ [7a4a040aae2d]
+
+ * parse.lex:
+ Add Runas_Alias and simplify a rule.
+ [6f794a769a37]
+
+ * parse.yacc:
+ always store User_Alias's since they can be used inside of a runas
+ list. Sigh. Really need a Runas_Alias instead.
+ [3bab058a873e]
+
+1996-10-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ deal with case where there is no sudoers file
+ [fa38b3bb244d]
+
+1996-10-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TROUBLESHOOTING:
+ added one
+ [e61346d06725]
+
+1996-10-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * HISTORY, testsudoers.c:
+ developement -> development
+ [4df55e293941]
+
+ * INSTALL:
+ added a note
+ [3845fb83dbc0]
+
+ * RUNSON:
+ for 1.5.2
+ [5489b7298942]
+
+ * CHANGES:
+ updated
+ [0741834929e6]
+
+1996-10-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * PORTING:
+ removed seteuid() notes
+ [1010a60f281d] [SUDO_1_5_2]
+
+1996-10-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat.h:
+ better seteuid() emulatino
+ [e807623b662c]
+
+ * configure.in:
+ added check for seteuid
+ [8cf9fabc6f4f]
+
+ * config.h.in:
+ added HAVE_SETEUID
+ [596db46aa828]
+
+1996-10-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ first stab at sequent support
+ [b85a7bfcac76]
+
+ * config.h.in:
+ added HAVE_SYS_SELECT_H
+ [93ecdd042463]
+
+ * compat.h:
+ sequent -> _SEQUENT_
+ [63a38b6da98c]
+
+ * compat.h:
+ added seteuid() macro for DYNIX
+ [695bd63c5ea6]
+
+ * tgetpass.c:
+ _AIX -> HAVE_SYS_SELECT_H
+ [b31221211bc2]
+
+1996-10-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS, INSTALL, Makefile.in, OPTIONS, README, config.h.in, logging.c,
+ parse.c, parse.lex, parse.yacc, putenv.c, strdup.c, sudo_setenv.c,
+ testsudoers.c, tgetpass.c, utime.c, visudo.c:
+ ++version
+ [8052992fd453]
+
+ * check.c, compat.h, dce_pwent.c, emul/utime.h, find_path.c,
+ getspwuid.c, getwd.c, goodpath.c, ins_2001.h, ins_classic.h,
+ ins_csops.h, ins_goons.h, insults.h, interfaces.c, options.h,
+ pathnames.h.in, version.h:
+ ++version
+ [f7ad15e1598a]
+
+ * sudo.pod:
+ added -H and SUDO_PS1
+ [bb965241e30c]
+
+ * configure.in:
+ use SUDO_FUNC_FNMATCH
+ [6a8350d85fb2]
+
+ * aclocal.m4:
+ added SUDO_FUNC_FNMATCH
+ [45b32c91c4ba]
+
+ * sudo.c:
+ added -H flag
+ [11ebc6872fd6]
+
+ * sudo.h:
+ added MODE_RESET_HOME /
+ [67a7f8bcbbd6]
+
+1996-10-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ mention OPIE
+ [5723515d5bbd]
+
+ * options.h:
+ SKEY -> OTP
+ [c1d268130bc4]
+
+ * configure.in:
+ added opie support
+ [123872b41b20]
+
+ * compat.h, config.h.in:
+ added HAVE_OPIE
+ [528c71afc1e5]
+
+ * check.c:
+ added HAVE_OPIE and changed to *_OTP_*
+ [4c62f5db872a]
+
+ * OPTIONS:
+ SKEY -> OTP
+ [bd858e5e9652]
+
+1996-10-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ moved fclose() in skey stuff.
+ [11f7dc8431a6]
+
+1996-10-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * putenv.c:
+ index -> strchr remove unnecesary stuff
+ [af2d05238062]
+
+ * check.c:
+ now call skeychallenge() to get challenge instead of making one up
+ ourselves. this way, we get extra goodies in the prompt.
+ [49b770d98d3a]
+
+1996-09-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ added one
+ [3f5149357e2a] [SUDO_1_5_1]
+
+ * parse.lex:
+ allow logins to start with a number (YUCK!)
+ [7ed7ef324741]
+
+1996-09-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TROUBLESHOOTING:
+ added soalris 2.5 vs 2.4 note
+ [16160a251aae]
+
+ * configure.in:
+ DUNIX doesn't need -lnsl
+ [be924cc322c3]
+
+ * CHANGES:
+ *** empty log message ***
+ [1b2937521981]
+
+ * check.c, compat.h, config.h.in, dce_pwent.c, find_path.c,
+ getspwuid.c, getwd.c, goodpath.c, ins_2001.h, ins_classic.h,
+ ins_csops.h, ins_goons.h, insults.h, interfaces.c, logging.c,
+ options.h, parse.c, parse.lex, parse.yacc, pathnames.h.in, putenv.c,
+ strdup.c, sudo.c, sudo.h, sudo_setenv.c, testsudoers.c, tgetpass.c,
+ utime.c, version.h, visudo.c:
+ courtesan
+ [5f203589bbfe]
+
+ * PORTING, README, RUNSON:
+ courtesan
+ [d72517f4937e]
+
+ * INSTALL, Makefile.in, TROUBLESHOOTING:
+ courtesan
+ [5c007e3c7a71]
+
+ * visudo.pod:
+ *** empty log message ***
+ [37ebe85bd4e1]
+
+ * sudo.pod, visudo.pod:
+ courtesan
+ [37f02e2130ea]
+
+1996-09-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * HISTORY:
+ added courtesan ./
+ [b01435226276]
+
+1996-09-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ added $SUDO_PROMPT support
+ [cb1fa72c093d]
+
+1996-09-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ print long skey challemged to stderr, not stdout
+ [750fc775b3b2]
+
+1996-09-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ updated for 1.5.1
+ [9b615f393057]
+
+ * emul/utime.h:
+ ++version
+ [a94de18deafb]
+
+1996-08-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON:
+ updated for 1.5.1
+ [4092f20ab634]
+
+1996-08-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ use shost, not host for tgetpass
+ [6061c49ff9be]
+
+ * sudo.pod:
+ documented %u and %h
+ [6d2922d29897]
+
+ * OPTIONS:
+ documented %u and %h
+ [1a71da13a864]
+
+ * configure.in:
+ fixed typo
+ [1230dec2b062]
+
+ * INSTALL, Makefile.in, README, check.c, compat.h, config.h.in,
+ dce_pwent.c, find_path.c, getspwuid.c, getwd.c, goodpath.c,
+ ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h, insults.h,
+ interfaces.c, logging.c, options.h, parse.c, parse.lex, parse.yacc,
+ pathnames.h.in, putenv.c, strdup.c, sudo.c, sudo.h, sudo_setenv.c,
+ testsudoers.c, tgetpass.c, utime.c, version.h, visudo.c:
+ ++version
+ [65ce8eabf77a]
+
+ * BUGS:
+ ++version
+ [afecab53aab7]
+
+1996-08-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, configure.in, version.h:
+ ++version
+ [fb3ff940d672]
+
+ * sudo.h:
+ new tgetpass() params
+ [9eccc5b0f8ae]
+
+ * check.c:
+ pass use and host to tgetpass
+ [c56d9d13c401]
+
+ * tgetpass.c:
+ added %u and %h escapes
+ [04ae775d3e5d]
+
+ * OPTIONS, check.c, options.h:
+ added NO_MESSAGE
+ [3927dad19057]
+
+ * configure.in:
+ added cray (unicos) support
+ [1122210c5fb1]
+
+1996-08-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * OPTIONS, options.h, sudo.c:
+ added SHELL_SETS_HOME
+ [0b26909b0929]
+
+1996-08-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ added note about "make install"
+ [7e56ea76d4b4]
+
+ * parse.yacc:
+ changed length/size params from int to size_t
+ [5654e5ceb1b3]
+
+ * OPTIONS:
+ now get CSOPS insults as well by default
+ [297323d0179a]
+
+ * insults.h:
+ use csops insults too by default
+ [07fafc136169]
+
+ * INSTALL, Makefile.in, README, config.h.in, configure.in, version.h:
+ version = 1.5
+ [4b8772b11e3b]
+
+ * sudo.c:
+ added runas_homedir
+ [b0e0d4417a15]
+
+ * TODO:
+ updated for 1.5
+ [66259df825d5]
+
+ * RUNSON:
+ updated for 1.5
+ [e08bc9ebfe95]
+
+ * CHANGES:
+ 1.5 release
+ [8c16942fea41]
+
+ * INSTALL:
+ added "upgrading" notes
+ [210d968964ff]
+
+1996-08-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ now do chmod and chown after edit of temp file and before rename
+ [de174e34faa7] [SUDO_1_5_0]
+
+1996-08-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ ++version added INSTALL.configure
+ [c9e9214f52ae]
+
+ * configure.in, version.h:
+ ++version
+ [5985abed3eb2]
+
+ * TROUBLESHOOTING:
+ *** empty log message ***
+ [d65c540ec52e]
+
+ * parse.yacc:
+ added missing cast
+ [e7247319a7d5]
+
+ * sudo.c:
+ sets $HOME to pw_dir of runas user
+ [d3f7f4d05752]
+
+ * sudo.pod:
+ document $HOME change
+ [854454d458c4]
+
+1996-08-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod:
+ fixed up some wording
+ [b0c8582f2c97]
+
+ * check.c, dce_pwent.c, find_path.c, getspwuid.c, getwd.c, goodpath.c,
+ interfaces.c, logging.c, parse.c, parse.lex, parse.yacc, putenv.c,
+ strdup.c, sudo.c, sudo_setenv.c, testsudoers.c, tgetpass.c, utime.c,
+ visudo.c:
+ ++version
+ [748be723fd8b]
+
+ * compat.h, ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h,
+ insults.h, options.h, pathnames.h.in, sudo.h:
+ ++version
+ [acdf8b1b2a1b]
+
+ * emul/utime.h:
+ ++version
+ [b3f35298ab8d]
+
+ * sudo.h:
+ name nad type changes
+ [db24ab3da141]
+
+ * testsudoers.c:
+ now works with new sudo
+ [379346c42cc2]
+
+ * parse.yacc:
+ fixed some XXX
+ [f5fe4c990052]
+
+ * parse.yacc:
+ some variable name changes + comment headers for functions.
+ [3dc3bd9aa73d]
+
+ * tgetpass.c:
+ added extra paren's to make compilers happy
+ [9e4968a34d56]
+
+ * sudo.c:
+ *** empty log message ***
+ [70c924c1ed69]
+
+ * parse.c:
+ now uses init_parser() if not in sudoers and tries "list" or
+ "validate" scold but don't be nasty.
+ [c0d8fb3f8c9e]
+
+ * TROUBLESHOOTING:
+ now can use upper case login names
+ [c772fffcefe5]
+
+ * visudo.c:
+ now uses init_parser()
+ [b9efae7243fd]
+
+ * INSTALL, README:
+ updated
+ [27dc8283fdc8]
+
+ * PORTING:
+ added info about PASSWORD_TIMEOUT
+ [980e15d892f8]
+
+ * INSTALL.configure:
+ Initial revision
+ [8292e89a08d3]
+
+ * BUGS:
+ fixed a bug ,
+ [c6e46f5624f9]
+
+ * parse.yacc:
+ now dynamically allocates memory for the stacks -- no more
+ overflows!
+ [8615c35b6ad3]
+
+ * sudo.pod:
+ -l now explands command aliases
+ [39f45605935d]
+
+ * parse.yacc:
+ hacks to expand command aliases for `sudo -l'
+ [e4eb752608f9]
+
+ * sudo.c:
+ remove $ENV and $BASH_ENV (dangerous in ksh, posix sh, and bash)
+ [01327ca5084b]
+
+ * sudo.h:
+ added struct command_alias
+ [dd2f32764082]
+
+ * sudo.pod:
+ fixed a bug
+ [e708ff08d2eb]
+
+ * lsearch.c:
+ in compar() key should be first arg
+ [fc14c3fa62ee]
+
+1996-08-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS:
+ fixed some bugs
+ [639dfe425bd5]
+
+ * parse.yacc:
+ can now deal with upcase HOST and USER names
+ [c6aa7bcfb00d]
+
+ * sudo.c:
+ don't yell too loudly at non-sudoers if they do "sudo -l"
+ [4ef146128d89]
+
+ * sudo.pod:
+ fixed thinko
+ [830f2f0f22e7]
+
+ * parse.c:
+ fix comment
+ [d20ce9e17ddc]
+
+1996-08-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c, parse.yacc:
+ added support for new `sudo -l' stuff
+ [7dceaef3c733]
+
+ * sudo.c:
+ now uses list_matches()
+ [293364821b61]
+
+ * sudo.h:
+ added struct sudo_match
+ [b2684179d179]
+
+ * configure.in:
+ now more -lgnumalloc
+ [4f8ae42617d8]
+
+1996-08-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * install-sh:
+ added more paths for chown and whoami
+ [6e685a19426c]
+
+1996-07-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ typo
+ [3adfa01c04bc]
+
+1996-07-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4:
+ fixed DUNIX check for shadow pw
+ [c25324bcd27b]
+
+ * tgetpass.c:
+ now only turn off echo if it is already on. this fixes a race when
+ you use sudo in a pipelin
+ [28388c2de21c]
+
+ * INSTALL:
+ updated
+ [b45ac9366b7e]
+
+ * configure.in:
+ changed "test -z $foo && do_this" to if; then construct
+ [2183c4426bca]
+
+1996-07-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ added missing defines of SHADOW_TYPE
+ [be89ea68a7f3]
+
+1996-07-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ protect AUTH_CRYPT_OLDCRYPT and AUTH_CRYPT_C1CRYPT since they are
+ only in dunix 4.x
+ [1e7c1c677263]
+
+ * getspwuid.c:
+ added AUTH_CRYPT_C1CRYPT support
+ [88d6b0058b20]
+
+ * parse.c:
+ no longer return VALIDATE_NOT_OK if there was a runas that didn't
+ match. Now we can have runas stuff on more than one line.
+ [52b68920d7b7]
+
+ * getspwuid.c, sudo.c, tgetpass.c:
+ use SHADOW_TYPE instead of HAVE_C2_SECURITY
+ [cf401dfcbc06]
+
+ * configure.in:
+ got rid of HAVE_C2_SECURITY SHADOW_TYPE is always defined to
+ something
+ [c7a233c4dd93]
+
+ * config.h.in:
+ removed HAVE_C2_SECURITY added SPW_BSD
+ [8314405e9754]
+
+ * compat.h:
+ use SHADOW_TYPE instead of HAVE_C2_SECURITY
+ [6f94870df17f]
+
+ * check.c:
+ SHADOW_TYPE is always defined so just against its value
+ [72c69a55d02f]
+
+ * aclocal.m4:
+ added SUDO_CHECK_SHADOW_DUNIX
+ [ef025ae9d496]
+
+1996-07-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ * -> ?* in one example added another instance of (runas) and one of
+ NOPASSWD:
+ [d74fe1dcbe7d]
+
+1996-07-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ added back check for config.cache from other host type
+ [0ba87871f585]
+
+ * parse.lex:
+ removed an instance of \"
+ [1e008d3709f6]
+
+ * sample.sudoers:
+ added an example
+ [dbfcf68ee330]
+
+ * sudoers.pod:
+ updated wrt new wildcard matching
+ [193fa44a475b]
+
+ * configure.in:
+ new check for shadow passwords if we don't know anything
+ [67465df7dc9a]
+
+ * aclocal.m4:
+ new SUDO_CHECK_SHADOW_GENERIC
+ [3563b16a41b8]
+
+ * configure.in:
+ added back check for -lsocket (oops)
+ [a80882ee1cb6]
+
+ * configure.in:
+ better (working) check for shadow passwd type if we know to use C2.
+ [3cdd2a59a641]
+
+ * configure.in:
+ now uses AC_CANONICAL_HOST to figure out os type
+ [80db7fe6e704]
+
+ * Makefile.in:
+ added config.{guess,sub}
+ [c6be7e3ca384]
+
+ * aclocal.m4:
+ removed unused stuff to figure out os type
+ [c9a0f3b57123]
+
+ * config.sub:
+ added openbsd
+ [bfc6bfec3668]
+
+ * config.sub:
+ Initial revision
+ [e6e06ce0d17d]
+
+ * config.guess:
+ Initial revision
+ [99dd06f79199]
+
+ * testsudoers.c:
+ don't call fnmatch() with FNM_PATHNAME flag unless it can only be a
+ pathname. need to check against sudoers_args even if user_args is
+ nil
+ [66e6cf77f5d6]
+
+ * parse.c:
+ don't call fnmatch() with FNM_PATHNAME flag unless it can only be a
+ pathname need to check against sudoers_args even if user_args is nil
+ [74374df17311]
+
+1996-07-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ added support for AUTH_CRYPT_OLDCRYPT w/ DUNIX C2
+ [cbb00261c415]
+
+ * testsudoers.c:
+ now takes command line args and uses cmnd_args
+ [f0c2fd35a527]
+
+ * parse.lex:
+ fill_args was adding an extra leading space
+ [692fc999b2e8]
+
+1996-07-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ fixed dummy command_matches()
+ [93d9543db6e2]
+
+ * parse.yacc:
+ fixed prototype
+ [7b0addfbd429]
+
+ * sudo.h:
+ added cmnd_args
+ [8f47c4ae65ef]
+
+ * parse.yacc:
+ now uses flat args string
+ [016e65877da3]
+
+ * parse.c, parse.lex:
+ now uses flat arg string
+ [5b5f2e3f4c09]
+
+ * visudo.c:
+ added cmnd_args def
+ [876867134775]
+
+ * sudo.c:
+ now sets cmnd_args global
+ [e6fee70cb59b]
+
+ * logging.c:
+ cmnd_args is now exported from sudo.[ch]
+ [7a9cd36e356f]
+
+1996-07-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ can't rely on cmnd_matches as much as I thought -- added some $$
+ stuff back in to prevent namespace pollution problems.
+ [3c45fedb5af3]
+
+ * parse.yacc:
+ Simplified parse rules wrt runas and NOPASSWD (more consistent).
+ [e6d838c8a4c7]
+
+1996-07-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.lex:
+ NOPASSWD may now have blanks before the ':' '(' only starts a
+ 'runas' if in the initial state to avoid collision with command args
+ [c5c01172f499]
+
+ * configure.in:
+ added checks for specific shadow passwd schemes
+ [b7e3d1f7b84f]
+
+ * aclocal.m4:
+ added routines to check for specific shadow passwd types
+ [e5e1d19960a6]
+
+1996-07-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ added support for ncr boxen
+ [bea9dc5aae7f]
+
+ * aclocal.m4:
+ added support for detecting ncr boxen
+ [8653a158a924]
+
+1996-07-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ added sinix support
+ [5de2b2173ee1]
+
+1996-07-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TROUBLESHOOTING:
+ added info about "config.cache from other other" error.
+ [845b10198e0b]
+
+ * aclocal.m4:
+ now makes sure you don't have a config.cache file from another OS
+ [4fe32571c021]
+
+ * configure.in:
+ now sets $LIBS when needed to configure links with libs when doing
+ tests hpux10 now uses SPW_SECUREWARE for C2 added check for
+ bigcrypt(3) if SPW_SECUREWARE
+ [2df6b8ca538f]
+
+ * getspwuid.c:
+ fixed typo
+ [fe1cb1d792d6]
+
+ * tgetpass.c:
+ now include stuff for SPW_SECUREWARE to get AUTH_MAX_PASSWD_LENGTH
+ [f71138372c07]
+
+ * getspwuid.c:
+ no more SPW_HPUX10
+ [cfdeb18bc16b]
+
+ * config.h.in:
+ no more SPW_HPUX10 added HAVE_BIGCRYPT
+ [00d296479a61]
+
+ * compat.h:
+ now uses AUTH_MAX_PASSWD_LENGTH if SPW_SECUREWARE
+ [6c6d9e680417]
+
+ * check.c:
+ SPW_SECUREWARE now uses bigcrypt
+ [be71fc66690f]
+
+1996-07-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sample.sudoers:
+ fixed 2 syntax errors
+ [45eee19ef4ac]
+
+ * sudoers:
+ root may now run ALL as ALL
+ [1b54c6b9b212]
+
+1996-07-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * interfaces.c:
+ fixed a typo/thinko that broke BSD's with sa_len
+ [603438360126]
+
+1996-07-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c, configure.in:
+ updated AFS support
+ [e572eb8d177a]
+
+ * TROUBLESHOOTING:
+ added entry about /usr/ucb/cc
+ [025b353aa9d3]
+
+ * INSTALL:
+ prep no longer holds gcc binaries
+ [8b0942958049]
+
+ * INSTALL:
+ updated AFS note
+ [7af6efd5abe4]
+
+ * Makefile.in:
+ added @AFS_LIBS@
+ [97b6fe6ad7d6]
+
+ * compat.h:
+ AFS allows long passwords
+ [5fb17122c302]
+
+ * testsudoers.c:
+ fixed -u user support
+ [b1a0c1648639]
+
+ * parse.c:
+ sudo -v now groks VALIDATE_OK_NOPASS
+ [74fc03fffe7e]
+
+ * parse.yacc:
+ fixed no_passwd vs. runas_matched
+ [549a9b791a6a]
+
+ * TROUBLESHOOTING:
+ took out stuff about NFS-mounting since it is no longer an issue
+ [d95ab7fbbc61]
+
+ * INSTALL:
+ added --with-libraries > --with-libpath --with-incpath
+ [d5d15a7a0f4c]
+
+ * parse.yacc:
+ was setting runas_matches to -1 in wrong place
+ [db2b1deb8d33]
+
+ * check.c:
+ removed usersec.h which is not present in new AFS versions
+ [618b016dd17f]
+
+ * tgetpass.c:
+ now deals with timeout <= 0
+ [ba53a1257255]
+
+ * OPTIONS:
+ updated
+ [75093bd8fdca]
+
+ * configure.in:
+ BSD/OS >= 2.0 now uses shlicc instead of just gcc
+ [ff6dbf7825c2]
+
+ * sudo.c:
+ fixed backwards compatibility with sudo 1.4 sudoers mode for root
+ readable/writable filesystems
+ [2694ed627221]
+
+ * Makefile.in:
+ now gives INSTALL -c flag
+ [63db055a2fd1]
+
+ * parse.yacc:
+ slightly simpler initialization of no_passwd and runas_matches
+ [463a1b5fa323]
+
+ * testsudoers.c:
+ added -u username support
+ [38b072fcd6b3]
+
+ * configure.in:
+ improved --with-libraries support
+ [047dbc5f0af2]
+
+1996-07-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ added --with-incpath, --with-libpath, --with-libraries
+ [20f20d6c718c]
+
+ * parse.yacc:
+ now initializes some fields that weren't getting set to -1 pretty
+ gross -- need a rewrite.
+ [021c160390c6]
+
+1996-06-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * alloca.c:
+ removed emacs'isms
+ [9d4ec2efe057]
+
+ * configure.in:
+ no longer add -lPW to *_LIBS since we include alloca.c
+ [a626d1bbea80]
+
+ * config.h.in:
+ added HAVE_ALLOCA_H
+ [15491e2a6cff]
+
+ * Makefile.in:
+ added alloca.c
+ [0400f25e1fe4]
+
+ * alloca.c:
+ Initial revision
+ [06d033aa4882]
+
+ * configure.in:
+ ++version
+ [f52c0fb98f90]
+
+1996-06-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ now set uid to 1 instead of nobody for PERM_SUDOERS since nobody is
+ not always set to a valid uid.
+ [c2669f77704d]
+
+ * OPTIONS:
+ fixed entry for SUDO_MODE
+ [d7272f6035b8]
+
+ * sudo.c:
+ Fixed NFS-mounted sudoers file under solaris both uid *and* gid were
+ being set to -2. Now beat NFS to the punch and set uid to "nobody"
+ ourselves, preserving group 0 to read sudoers.
+ [b1fbc5dd1e34]
+
+ * parse.c:
+ moved set_perms(PERM_ROOT) to be before yyparse()
+ [7619d8080735]
+
+ * logging.c:
+ fixed a typo
+ [318acc48cde0]
+
+ * configure.in:
+ no longer need AC_PROG_INSTALL
+ [de01b1336dc8]
+
+ * Makefile.in:
+ always use install-sh to avoid install(1)'s that use get{pw,gr}nam
+ [ea2351986406]
+
+ * INSTALL:
+ make clean -> make distclean
+ [704a98e8ba10]
+
+1996-06-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ removed some unnecsary if's
+ [f00db6508132]
+
+ * Makefile.in, version.h:
+ ++version
+ [bdb6740b24c8]
+
+ * parse.c, testsudoers.c:
+ now includes netgroup.h
+ [93f5a06352bc]
+
+ * interfaces.c:
+ removed cats of ioctl to int since they didn't shut up -Wall
+ [83e9f912cd7a]
+
+ * interfaces.c:
+ explicately cast ioctl() to int since it it not always declared
+ [2ff9294e469e]
+
+ * sudo.h:
+ added declarations for yyparse() and yylex()
+ [6071321ab771]
+
+ * parse.yacc:
+ fixed an occurence of '==' -> '='
+ [2c46d2e11d57]
+
+ * config.h.in, configure.in:
+ added check for netgroup.h
+ [73403050f4e3]
+
+ * sudo.c:
+ fixed 2 compiler warnings
+ [680929b0bd97]
+
+ * sudo.c:
+ SHELL_IF_NO_ARGS caused core dump since NewArg[cv] weren't being
+ initialized
+ [18707ecd07c2]
+
+1996-06-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod:
+ fixed a typo
+ [e4b5c12aa130]
+
+1996-06-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ fixed a formatting thingie
+ [c79327b6f19b]
+
+ * parse.c, parse.yacc:
+ fixed -u support with multiple user lists on a line
+ [e4d1066adca2]
+
+ * configure.in:
+ unixware needs -lgen
+ [b5bf9bca63cc]
+
+ * README:
+ updated ftp location
+ [b25a033f7921]
+
+ * sudoers.pod:
+ add net_addr/netmask support
+ [674e83516d1e]
+
+ * sample.sudoers:
+ added net_addr/mask example
+ [774878e89b28]
+
+ * parse.c, parse.lex:
+ added support for net_addr/netmask
+ [e33de27325d8]
+
+1996-06-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ ^ -> !
+ [1a084950d6ef]
+
+1996-06-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON:
+ updated for 1.4.3
+ [c82019025d09]
+
+ * CHANGES:
+ udpated for 1.4.3
+ [ceaa81adb8f0]
+
+ * BUGS, TODO, TROUBLESHOOTING:
+ updated
+ [ff94fae4b853]
+
+ * sample.sudoers:
+ updated with examples of new stuff
+ [99d0b4cb4c9c]
+
+ * INSTALL, README:
+ ++version
+ [b763b80fe836]
+
+ * sudoers.pod:
+ updated wrt -u and NOPASSWD
+ [0b5b722ea0f4]
+
+ * sudo.pod:
+ updated wrt -u and CAVEATS
+ [71d5d53b5d18]
+
+1996-06-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ fixed usage()
+ [114c7d09b550]
+
+ * parse.lex:
+ now use :foo: character classes (makes no diff for generated lexer)
+ [7b0aeb737a02]
+
+1996-06-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ fixed LONG_SKEY_PROMPT stuff
+ [0efe78b4bdda]
+
+1996-06-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ fixed a comment
+ [3d289017104b]
+
+ * lsearch.c:
+ make more like NetBSD one -- now compiles w/o warnings
+ [932206296a54]
+
+ * emul/search.h:
+ fixed decls of lsearch()
+ [c58cf4584c45]
+
+ * config.h.in, configure.in, getspwuid.c:
+ added SPW_HPUX10
+ [d74e5eaa5f17]
+
+ * check.c:
+ hpux 10 uses bigcrypt() if C2
+ [359eb63f4021]
+
+1996-06-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ now always uses fnmatch to match args
+ [a9d91f35256a]
+
+ * tgetpass.c:
+ back to using stdio instead of raw i/o since that caused some
+ problems
+ [e7ce2bc92974]
+
+1996-05-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ now give usage warning if use -l,-v,-k with args
+ [6b48180c4fea]
+
+1996-05-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ NewArgc is now set to 1 for -l, -v, -k
+ [7497cb1416a8]
+
+ * sudo.c:
+ now sets sudoers to correct group if mode is 0400
+ [484c43d99718]
+
+ * install-sh:
+ updated to version used by inn and bind
+ [28683ad8725a]
+
+ * configure.in:
+ now uses -lgnumalloc if it exists
+ [3651ca4415a2]
+
+ * Makefile.in:
+ "make install" now sets uid/gid and mode on sudoers if it exists
+ [1f5216191ae9]
+
+ * sudo.c:
+ rmeoved debugging statements
+ [aeda278e2c26]
+
+ * parse.yacc:
+ added a missing free()
+ [592c9482a159]
+
+ * sudo.c:
+ now uses user_gid instead of getegid (which was wrong anyway) to set
+ SUDO_GID Now sets command line args in SUDO_COMMAND envariabled
+ (logging.c depends on args being in the environment)
+ [9f5328a3b942]
+
+ * logging.c:
+ now uses SUDO_COMMAND envariable to get command args rather than
+ building it up again.
+ [7f8edc5bccb7]
+
+ * parse.c:
+ now uses user_gid
+ [4b9303ae45fe]
+
+ * sudo.c:
+ fixed off by one error in allocation NewArgv
+ [921ea1a4e7c6]
+
+ * parse.c:
+ in sudoers, 'command ""' now means command with no args
+ [a5273648ace2]
+
+ * configure.in:
+ added check for fnmatch(3) and fnmatch.h
+ [258916a7866f]
+
+ * config.h.in:
+ added HAVE_FNMATCH
+ [b9860d361e93]
+
+ * Makefile.in:
+ replaced wildcat.* with fnmatch.*
+ [03ad9ee21a1c]
+
+ * testsudoers.c:
+ now uses fnmatch()
+ [5a7f7de987a9]
+
+1996-05-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ now uses fnmatch() instead of wildmat a trailing star (*) by itself
+ now matches multiple args added support for wildcards in the
+ pathname in sudoers
+ [1f7fb950b868]
+
+1996-05-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * fnmatch.c:
+ now includes compat.h and config.h
+ [090206b95cf8]
+
+ * config.h.in:
+ added HAVE_FNMATCH_H
+ [90eb42150173]
+
+ * configure.in:
+ now checks for alloca() (if needed by bison or dce) and links with
+ -lPW if it contains alloca() and libv and compiler do not.
+ [cfa2b3cef49a]
+
+ * emul/fnmatch.h, fnmatch.3, fnmatch.c:
+ Initial revision
+ [20b1f762a32a]
+
+1996-04-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ now fixes mode on sudoers if set to 0400 to aid in upgrade
+ [d4bdfd521820]
+
+1996-04-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ fixed pod2man usage
+ [5adf2ec77b27]
+
+ * Makefile.in, configure.in, version.h:
+ ++version
+ [b4029de876d0]
+
+ * testsudoers.c, visudo.c:
+ runas_user is now initialized to "root"
+ [8537d97bff39]
+
+ * sudo.h:
+ removed PERM_FULL_ROOT
+ [241f8bbf647f]
+
+ * sudo.c:
+ runas_user defaults to "root" so no more need to PERM_RUNAS
+ [fc0c0dfc72ba]
+
+ * parse.c:
+ will now only running commands as root if there was no runas list
+ (or if root is in the runas list)
+ [40c587666c81]
+
+ * logging.c:
+ now logs "USER=%s"
+ [b733504c87fd]
+
+ * parse.yacc:
+ runas_matches is now set to false if we get a negative match
+ [5495b150b300]
+
+ * parse.lex:
+ make #uid work + some minor cleanup
+ [07851bbce03a]
+
+ * sample.sudoers:
+ added support for NOPASSWD and "runas" from garp@opustel.com /
+ [7a9c67b51fa5]
+
+ * visudo.c:
+ added support for "runas" from garp@opustel.com replaced
+ SUDOERS_OWNER with SUDOERS_UID, SUDOERS_GID added support for
+ SUDOERS_MODE
+ [e714209b9885]
+
+ * testsudoers.c:
+ added support for "runas" from garp@opustel.com
+ [b837f856da10]
+
+ * sudo.h:
+ added support for NO_PASSWD and runas from garp@opustel.com replaced
+ SUDOERS_OWNER with SUDOERS_UID and SUDOERS_GID and added support fro
+ SUDOERS_MODE
+ [cea6f26679b7]
+
+ * sudo.c:
+ added support for NO_PASSWD and runas from garp@opustel.com replaced
+ SUDOERS_OWNER with SUDOERS_UID and SUDOERS_GID and added support fro
+ SUDOERS_MODE
+ [61b5434237c5]
+
+ * parse.yacc:
+ added support for NO_PASSWD and runas from garp@opustel.com
+ [72ebd3056f22]
+
+ * parse.c, parse.lex:
+ added support for NO_PASSWD and runas from garp@opustel.com
+ [fef6dbdd114d]
+
+ * logging.c:
+ added support for SUDOERS_WRONG_MODE and "runas"
+ [e794efc2b443]
+
+ * configure.in:
+ added --with-CC only link with -lshadow on linux (with shadow pw) if
+ libc lacks getspnam()
+ [3ecf4ae21002]
+
+ * OPTIONS, options.h:
+ removed NO_PASSWD since it is not possible to do this in the sudoers
+ file itself. Replaced SUDOERS_OWNER with SUDOERS_UID and
+ SUDOERS_GID. Added SUDOERS_MODE.
+ [2eaa4891ef48]
+
+ * Makefile.in:
+ now uses SUDOERS_UID and SUDOERS_GID
+ [8d615f0fdb2a]
+
+1996-04-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ added --with-CC
+ [a1b8286a81b8]
+
+1996-04-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.lex:
+ added double quote support
+ [a5e4fc7e3a2b]
+
+ * sudoers.pod:
+ documented double quoting
+ [c6ea47969a44]
+
+1996-04-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * mkinstalldirs:
+ Initial revision
+ [dcb86d65ad8f]
+
+ * check.c:
+ fixed some indentation
+ [4d1c5ab8072b]
+
+ * Makefile.in:
+ fixed a typo
+ [0d27eebc7227]
+
+ * Makefile.in:
+ added install-dirs .
+ [f499b99b8be7]
+
+1996-04-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * dce_pwent.c:
+ new version from "Jeff A. Earickson" <jaearick@colby.edu>
+ [422481be5fbd]
+
+1996-04-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ $CSOPS -> $with_csops (whoops, missed one)
+ [b04c6948130e]
+
+ * BUGS:
+ updated
+ [c4d5713e227d]
+
+ * parse.lex:
+ FQHOST now has same constraints as non-FQHOST
+ [e1c3bf2381d1]
+
+ * INSTALL:
+ added note about OS's w/ shadow passwords turned on by default
+ [166257f43be4]
+
+1996-04-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ fixed a typo
+ [e5c3e2e9a359]
+
+ * configure.in:
+ added support for --without-THING sanitized shadow pw situtation by
+ adding support for
+ --without-C2
+ [65dc6bf64cce]
+
+ * tgetpass.c:
+ fixed a typo wrt placement of an end paren
+ [a8780f818231]
+
+ * check.c:
+ was closing an fd that may not have been opened
+ [760271c7bdc9]
+
+1996-03-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * OPTIONS, options.h, sudo.c:
+ added NO_PASSWD
+ [28ff1dc93d7a]
+
+1996-03-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ now always use shadow pw on some arches
+ [069161ccffda]
+
+1996-03-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ added pyramid support
+ [a0eb57a3a531]
+
+ * configure.in:
+ no longer check for C2 if alternate passwd method is used no longer
+ check for some libs twice
+ [2d0c3c902b40]
+
+ * parse.yacc:
+ moved fqdn stuff into parse.lex (FQHOST)
+ [d9c9abd481d8]
+
+ * parse.lex:
+ added FQHOST rules
+ [4a1695acff6d]
+
+ * tgetpass.c:
+ now define TCSASOFT in necesary
+ [3fac2e21c9ab]
+
+ * tgetpass.c:
+ now uses read/write instead of stdio string goop to avoid problems
+ with select(2)
+ [67fd174e518c]
+
+ * OPTIONS, find_path.c, options.h:
+ -DNO_DOT_PATH -> -DIGNORE_DOT_PATH
+ [d05ba5100d28]
+
+1996-03-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ added note about no shadow auto-detect if using alternate auth
+ schemes
+ [b425592232a3]
+
+ * configure.in:
+ don't check for C2 if AFS or DCE (unless they said --with-C2)
+ [61342962171a]
+
+ * testsudoers.c:
+ now groks shost
+ [85dda17303f6]
+
+ * OPTIONS, find_path.c, options.h:
+ added NO_DOT_PATH
+ [c261ca1fb196]
+
+1996-03-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * find_path.c:
+ checkdot now works correctly
+ [3bc4835bb3e9]
+
+1996-03-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ can't have DCE and C2 passwords both...
+ [fb9a8ab7ca66]
+
+1996-03-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc, sudo.c, sudo.h, visudo.c:
+ now uses shost even if not FQDN
+ [87f7498b3a1f]
+
+ * configure.in:
+ now looks for skey in /usr/lib and doesn't require libskey to be in
+ /usr/local/lib just because skey.h is (for my netbsd box :-)
+ [ceb1763e37d2]
+
+ * aclocal.m4, config.h.in, pathnames.h.in:
+ _SUDO_PATH_ -> _CONFIG_PATH_
+ [84d97ad13d75]
+
+ * aclocal.m4, sudo.pod:
+ /var/run/.odus -> /var/run/sudo
+ [922da220b8f5]
+
+ * pathnames.h.in:
+ now uses _SUDO_PATH_TIMEDIR
+ [5ecab0155fdf]
+
+ * OPTIONS:
+ udpated FQDN
+ [361b6f7440c0]
+
+ * aclocal.m4, configure.in:
+ added SUDO_TIMEDIR
+ [368c95c8c950]
+
+ * config.h.in:
+ added _SUDO_PATH_TIMEDIR
+ [3879864d808c]
+
+ * sudo.pod:
+ updated wrt /var/run/sudo
+ [9e14f2a429d3]
+
+ * sudo.c, sudo.h:
+ added support for shost if FQDN
+ [51a3f51a09a1]
+
+ * parse.yacc, visudo.c:
+ now uses shost if FQDN
+ [d19da2e92b42]
+
+ * check.c:
+ Now use skeylookup() instead off skeychallenge()
+ [4c7438bb2ae0]
+
+1996-02-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ mail_argv should not contain ALERTMAIL as it includes "-t"
+ [67ffaaa8f843]
+
+1996-02-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, Makefile.in, README, configure.in, version.h:
+ ++version
+ [e08fd4a809fc]
+
+ * compat.h:
+ added more _PASSWD_LEN stuff -- now uses PASS_MAX too
+ [2f20c3153689]
+
+ * tgetpass.c:
+ now includes limits.h moved _PASSWD_LEN -> compat.h
+ [b1ca3cafdacc]
+
+1996-02-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL, README:
+ ++version
+ [3eacf32803f5]
+
+ * Makefile.in:
+ ++versoin
+ [3b91c317630a]
+
+ * Makefile.in:
+ fixed a typo
+ [3661ac4a7803]
+
+ * configure.in:
+ ++version
+ [60e842973745]
+
+1996-02-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON:
+ updated
+ [def2c3c24195]
+
+ * CHANGES:
+ done for 1.4.1 (I hope)
+ [2ab543769a40]
+
+ * sudoers.pod:
+ added info on wildcards
+ [ce3bd41bc063]
+
+ * sample.sudoers:
+ added wildcard example
+ [762feb0577bd]
+
+ * Makefile.in:
+ now uses *.pod to build *.man and *.cat & *.html
+ [3ec14962028b]
+
+ * configure.in:
+ addedSUDO_PROG_BSHELL !ll
+ [3c80b320bf16]
+
+ * visudo.pod:
+ fixed up some formatting
+ [12166c434526]
+
+ * sudoers.pod:
+ redid section describing sample sudoers stuff
+ [b8065cceec71]
+
+ * sudo.pod:
+ fixed some formatting
+ [aa9a681add0f]
+
+ * getspwuid.c:
+ now treats "" as bourne shell
+ [30194a72ad56]
+
+ * Makefile.in:
+ TESTOBJS nwo includes wildmat.o
+ [86cc6500f84d]
+
+ * testsudoers.c:
+ now works with NewArg[cv]
+ [2f72674ce942]
+
+ * sudo.c:
+ removed an XXX (fixed it in getspwuid.c)
+ [e791ee0d1a68]
+
+ * aclocal.m4:
+ added check for bourne shell
+ [a2fd51676b8a]
+
+ * pathnames.h.in:
+ added _PATH_BSHELL
+ [e7c10011d47b]
+
+ * config.h.in:
+ added _SUDO_PATH_BSHELL
+ [6a1182898de9]
+
+1996-02-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ unixware vi returns 256 instead of 0
+ [234ffc7c6786]
+
+ * INSTALL:
+ added Linux note
+ [5f85efcd2b58]
+
+ * logging.c:
+ fixed up some XXX's. file log format now looks a little more like
+ real syslog(3) format.
+ [6df55707bfc3]
+
+ * README, TROUBLESHOOTING:
+ updated wrt lex/flex
+ [eb787d69156b]
+
+ * Makefile.in:
+ commented out rule to build lex.yy.c from parse.lex since we ship
+ with a pre-flex'd parser
+ [7507e2ce4a95]
+
+ * parse.c, parse.yacc, visudo.c:
+ path_matches -> command_matches
+ [0bd469424f86]
+
+ * logging.c:
+ eliminated some strcat()'s
+ [9878a79bc374]
+
+ * configure.in:
+ no longer checks for lex/flex (now assumes flex)
+ [a086ccc73798]
+
+ * configure.in:
+ now checks for $kerb_dir_candidate/krb.h instead of just
+ kerb_dir_candidate
+ [9133bc3c5208]
+
+1996-02-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ now use a 'hook' expression instead of an iffy one :-)
+ [9560df01b8c0]
+
+1996-02-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ now works with new sudo arg stuff
+ [310a0d43ddad]
+
+ * parse.yacc:
+ fixed dereferencing deadbeef
+ [474ef8a8006b]
+
+ * sudo.c:
+ changed an occurrence of Argv to NewArgv
+ [205b012b7691]
+
+ * parse.lex:
+ took out support for quoted commands since there is no need...
+ [5c5036d353b1]
+
+ * parse.c:
+ fixed a typo in a for() loop
+ [7e8d5283c43b]
+
+ * logging.c:
+ protected against dereferencing rogue pointers
+ [56debd517717]
+
+ * sudo.c:
+ now uses NewArgv amd NewArgc so cmnd_aegs is no longer needed this
+ also allows us to eliminate some kludges in parse_args() and
+ eliminate superfluous code.
+ [5122f66ad150]
+
+ * logging.c:
+ no longer uses cmnd_args, now uses NewArgv instead.
+ [abddd23cf068]
+
+ * sudo.h:
+ added struct sudo_command, NewArgc, and NewArgv removed cmnd_args
+ (no longer used)
+ [78410984fb05]
+
+ * Makefile.in:
+ added wildmat.c to SRCS & SUDOBJS
+ [3800efb41794]
+
+ * parse.yacc:
+ COMMAND is now a struct containing the path and args
+ [5c32822c5b94]
+
+ * parse.lex:
+ replaced append() with fill_cmnd() and fill_args. command args from
+ a sudoers entry are now stored in an arrary for easy matching.
+ [a981d7f4eb0d]
+
+ * parse.c:
+ command line args from sudoers file are now in an array like ones
+ passed in from the command line
+ [1d9e37e84519]
+
+1996-02-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ wildwat stuff now works
+ [49d16488531f]
+
+1996-01-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * version.h:
+ ++version
+ [53e55463ef89]
+
+ * Makefile.in:
+ ++version added wildmat.*
+ [0508297a4711]
+
+1996-01-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.lex:
+ added support for quoted commands (w/ or w/o args)
+ [b9a637155673]
+
+1996-01-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.pod, visudo.pod:
+ cleaned up formatting
+ [4591d4195437]
+
+ * sudo.pod, visudo.pod:
+ Initial revision
+ [7564a8242750]
+
+1996-01-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudoers.pod:
+ looks reasonable, could be mroe readable
+ [a5be2d19d9e0]
+
+ * sudoers.pod:
+ Initial revision
+ [957888be31a6]
+
+1996-01-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON:
+ updated
+ [633743aa924b]
+
+ * OPTIONS:
+ updated NO_ROOT_SUDO entry
+ [f1c15b1dec9e]
+
+1996-01-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON:
+ *** empty log message ***
+ [5b63de579ff7] [SUDO_1_4_0]
+
+ * sudo.c:
+ fixed SECURE_PATH
+ [6002889f606d]
+
+ * RUNSON:
+ udpa`ted for 1.4
+ [6014a8592815]
+
+ * configure.in:
+ AIX aixcrypt.exp now uses $(srcdir)
+ [b0d57674fef4]
+
+ * TROUBLESHOOTING:
+ added entry for anal ansi compilers
+ [4193cec1c6b1]
+
+1996-01-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ added info on libcrypt_i for SCO
+ [575497d56698]
+
+ * TODO:
+ *** empty log message ***
+ [d0aaf67b9913]
+
+ * sample.sudoers:
+ added comments
+ [a7773f7eda8d]
+
+ * TODO:
+ 1.4 release
+ [1dade29e9fd9]
+
+ * CHANGES:
+ ++version
+ [67241be40780]
+
+ * INSTALL, OPTIONS, README, config.h.in, configure.in:
+ ++version
+ [2e0a37897f68]
+
+ * BUGS:
+ ++version and fixed ISC
+ [78963f01a0e3]
+
+ * check.c, compat.h, dce_pwent.c, find_path.c, getspwuid.c, getwd.c,
+ goodpath.c, ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h,
+ insults.h, logging.c, options.h, pathnames.h.in, putenv.c, strdup.c,
+ sudo.c, sudo.h, sudo_setenv.c, testsudoers.c, tgetpass.c, utime.c,
+ visudo.c:
+ ++version
+ [b6227f29b3d9]
+
+ * interfaces.c:
+ added STUB_LOAD_INTERFACES ++version
+ [d8150a3fd577]
+
+ * Makefile.in, emul/utime.h, parse.c, parse.lex, parse.yacc,
+ version.h:
+ ++version
+ [da9e90e69bdc]
+
+ * PORTING:
+ added info about fd_set in tgetpass added info on interfaces.c
+ [a39902febd17]
+
+1996-01-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * dce_pwent.c:
+ added sudo header
+ [fc0f2c48682e]
+
+ * tgetpass.c:
+ fixed a typo
+ [43d40b72ee8f]
+
+ * Makefile.in:
+ tgetpass.o is now only linked in with sudo (not visudo)
+ [7407c5ff11f8]
+
+1996-01-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS, INSTALL, Makefile.in, OPTIONS, README, config.h.in,
+ configure.in:
+ ++version
+ [9b82ad805d6b]
+
+ * emul/utime.h:
+ added copyright notice
+ [4380f16cd075]
+
+ * check.c, compat.h, find_path.c, getspwuid.c, getwd.c, goodpath.c,
+ ins_2001.h, ins_classic.h, ins_csops.h, ins_goons.h, insults.h,
+ interfaces.c, logging.c, options.h, parse.c, parse.lex, parse.yacc,
+ pathnames.h.in, putenv.c, strdup.c, sudo.c, sudo.h, sudo_setenv.c,
+ testsudoers.c, tgetpass.c, utime.c, version.h, visudo.c:
+ ++version
+ [32717fdb5d05]
+
+ * tgetpass.c:
+ minor cleanup and now includes sys/bsdtypes for svr4'ish boxen
+ [326864428da2]
+
+ * configure.in:
+ ISC now gets -lcrypt now check for sys/bsdtypes.h
+ [e064799c054b]
+
+ * config.h.in:
+ added check for sys/bsdtypes.h
+ [9adb9533c363]
+
+1996-01-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ removed debugging stuff (setting freed ptr to NULL)
+ [02fe8eec63a0]
+
+ * TROUBLESHOOTING:
+ added 2 entries
+ [02884e2733e2]
+
+ * Makefile.in:
+ added FAQ
+ [074d8dfcf28d]
+
+ * TROUBLESHOOTING:
+ added section on syslog
+ [e6bc02a22b86]
+
+ * configure.in:
+ added AC_ISC_POSIX for better ISC support
+ [8436b3e12af2]
+
+ * config.h.in:
+ fixed typo
+ [f1b3922babf4]
+
+ * config.h.in:
+ added define for _POSIX_SOURCE
+ [ded6d92b34f9]
+
+1996-01-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ fixed check for lsearch()
+ [75baa5bc28a3]
+
+1995-12-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * interfaces.c:
+ fixed for AIX now deal if num_interfaces == 0 (should not happen)
+ [ae450e859227]
+
+1995-12-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ now only define HAVE_LSEARCH if there is a corresponding search.h
+ [8ce645c5d17f]
+
+ * interfaces.c:
+ works on ISC again
+ [ccac920d424c]
+
+1995-12-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ now define HAVE_LSEARCH if we find lsearch() in libcompat
+ [7343e4313a87]
+
+ * lsearch.c:
+ char * -> const char *
+ [1c0b11c2300a]
+
+ * configure.in:
+ now looks in -lcompat for lsearch()
+ [a1cc1d6fcd09]
+
+ * Makefile.in:
+ remove sudo.core visudo.core for clan target
+ [b523456a85df]
+
+ * aclocal.m4:
+ added UID_MAX support in check for MAX_UID_T_LEN
+ [7ab262b1173f]
+
+ * Makefile.in:
+ fixed another occurence of sudo_getpwuid.*
+ [fb5809c07da2]
+
+ * Makefile.in, getspwuid.c:
+ sudo_getpwuid.c -> getspwuid.c
+ [875f2ef808b4]
+
+ * configure.in:
+ moved the "echo"
+ [ad7b8f966076]
+
+ * BUGS, CHANGES, INSTALL, Makefile.in, OPTIONS, README, check.c,
+ compat.h, config.h.in, configure.in, find_path.c, getspwuid.c,
+ getwd.c, goodpath.c, ins_2001.h, ins_classic.h, ins_csops.h,
+ ins_goons.h, insults.h, interfaces.c, logging.c, options.h, parse.c,
+ parse.lex, parse.yacc, pathnames.h.in, putenv.c, strdup.c, sudo.c,
+ sudo.h, sudo_setenv.c, testsudoers.c, tgetpass.c, utime.c,
+ version.h, visudo.c:
+ ++version
+ [ee57c6410ffa]
+
+ * testsudoers.c:
+ added group support
+ [54d8097df8bd]
+
+ * sample.sudoers:
+ added group entry
+ [50994d31fd49]
+
+ * sudoers.man:
+ documented group support
+ [0a16707f8fed]
+
+ * parse.c, parse.lex, parse.yacc, visudo.c:
+ added group support
+ [427218c879c8]
+
+1995-12-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ tkfile was too short and overflowed the kerberos realm
+ [53823a1ff5af]
+
+1995-12-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ now copy command args directly from Argv
+ [77408278b6fd]
+
+ * sudo.c:
+ replaced code to copy cmnd_args so that is does not use realloc
+ since most realloc()'s really stink
+ [b29a0ff73fb6]
+
+1995-12-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ syslog() fixed in hpux 10.01
+ [2648e6f0cdb0]
+
+1995-12-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ AC_CHECK_LIB() now sets SUDO_LIBS (and VISUDO_LIBS if appropriate)
+ [8f108b8d8711]
+
+ * configure.in:
+ better error if cannot find skey incs or libs
+ [5887662ee9d3]
+
+ * aclocal.m4:
+ now use a temp file for determining max len of uid_t in string form.
+ the old hacky way broke on netbsd
+ [b68f470fa9f8]
+
+ * sudo.c:
+ added set of parens and a space
+ [8a3d4826d022]
+
+1995-12-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * dce_pwent.c:
+ fixes from Jeff Earickson <jaearick@colby.edu> ,
+ [bde0f0b756ec]
+
+ * check.c:
+ modified a comment
+ [e2a97f1afbbe]
+
+ * Makefile.in:
+ fixed up testsudoers target
+ [d39c4e7bb609]
+
+ * configure.in:
+ DCE changes from Jeff Earickson <jaearick@colby.edu> LIBS ->
+ SUDO_LIBS and VISUDO_LIBS LDFLAGS -> SUDO_FDFLAGS and VISUDO_LDFLAGS
+ [da7a1c433828]
+
+ * Makefile.in:
+ LIBS -> SUDO_LIBS , VISUDO_LIBS LDFLAGS -> SUDO_LDFLAGS,
+ VISUDO_LDFLAGS
+ [4b69503e8487]
+
+1995-11-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ fix for C2 on hpux 10 now uses -linet if it exists
+ [8d300112263d]
+
+ * check.c:
+ LONG_SKEY_PROMPT is less of a klusge /
+ [dcc144abaac3]
+
+ * configure.in:
+ fixed typos w/ dce stuff
+ [f7dfd6d4e149]
+
+ * Makefile.in:
+ added dce_pwent.c
+ [79047acdc516]
+
+1995-11-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ amended section on combining authentication mechanisms
+ [dc5138c7c716]
+
+ * PORTING:
+ minor updates for 1.3.6
+ [fe80c13bd994]
+
+ * TROUBLESHOOTING:
+ added 2 more entries
+ [c7201439a0f5]
+
+ * BUGS:
+ updated for 1.3.6
+ [979b414d2a2d]
+
+ * README:
+ overhauled
+ [3af8b60eb594]
+
+ * INSTALL:
+ rewrote for sudo 1.3.6
+ [b16027b9c726]
+
+ * TROUBLESHOOTING:
+ added 3 entries
+ [934c9ee3f153]
+
+1995-11-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * find_path.c, getspwuid.c, sudo.c:
+ added explict casts for strdup since many includes don't prototype
+ it. gag me.
+ [3e19a11f2fcc]
+
+ * sudo.h:
+ removed prototype for sudo_getpwuid() since convex C compiler choked
+ on it.
+ [c3ea74ca67b0]
+
+ * sudo.c:
+ added prototype for sudo_getpwuid()
+ [4a8e3cdc2b98]
+
+ * lsearch.c:
+ now compiles on strict ANSI compilers
+ [3ce5d72d0b08]
+
+ * check.c:
+ added LONG_SKEY_PROMPT support
+ [48a18b8a2332]
+
+ * Makefile.in:
+ added extra $'s for make to eat up, yum.
+ [2995b214e12b]
+
+ * OPTIONS, options.h:
+ added LONG_SKEY_PROMPT
+ [f23ae799b5a4]
+
+1995-11-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ s/key support now works with normal s/key as well as logdaemon
+ [d67573f523bf]
+
+ * OPTIONS, options.h:
+ added SKEY_ONLY
+ [bbf07654e0de]
+
+ * compat.h:
+ set _PASSWD_LEN to 256 for any of KERB4, DCE, SKEY
+ [205895b96a36]
+
+ * INSTALL:
+ added DCE note added more AIX notes
+ [6345403b3522]
+
+ * sudo.c:
+ now include pthread.h for DCE support
+ [6fe02865f679]
+
+ * check.c:
+ dce_pwent() is ok after all .,
+ [d26a8746a55d]
+
+ * logging.c:
+ now uses SYSLOG() macro that equates to either syslog() or
+ syslog_wrapper
+ [42ac4cff8045]
+
+ * dce_pwent.c:
+ minor formatting changes. renamed check() to somthing less generic
+ [71859f217be1]
+
+ * check.c, logging.c, parse.yacc, sudo.c, sudo.h, testsudoers.c,
+ visudo.c:
+ now uses user_pw_ent and simple macros to get at the contents
+ [f4cbf3e7145a]
+
+1995-11-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ simpler dec unix C2 support
+ [86bc8f75250e]
+
+ * getspwuid.c:
+ now sets crypt_type for DEC unix C2
+ [99aeadd18266]
+
+1995-11-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ added csops paths for skey
+ [b8ca672e2117]
+
+ * getspwuid.c:
+ now includes string.h for strdup() prototype
+ [3605259c3620]
+
+ * getspwuid.c:
+ fixed a few typos
+ [46c97e4ea417]
+
+ * check.c:
+ now includes skey.h
+ [11e611ce1b61]
+
+ * getspwuid.c:
+ fixed up comments
+ [223dac56f0c8]
+
+ * check.c:
+ moved a lot of the shadow passwd crap to sudo_getpwuid()
+ [97d8887fb7d3]
+
+ * sudo.c:
+ now uses sudo_pw_ent
+ [d014dadbef48]
+
+ * testsudoers.c:
+ now uses sudo_pw_ent
+ [d92936ed7e34]
+
+ * visudo.c:
+ now sets sudo_pw_ent
+ [ff75cdfcf8b3]
+
+ * getspwuid.c:
+ Initial revision
+ [6deb6df9d7bc]
+
+ * tgetpass.c:
+ moved dce stuff into compat.h
+ [1124284396e7]
+
+ * logging.c, sudo.h:
+ now uses sudo_pw_ent
+ [404ff20a5067]
+
+ * Makefile.in:
+ added sudo_getpwuid.c
+ [6666d0644512]
+
+ * compat.h:
+ added dce support
+ [3c3b36a7ce0e]
+
+ * parse.yacc:
+ now uses sudo_pw_ent
+ [9f5e8d11bd68]
+
+1995-11-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ fixed exempt_group stuff for OS's that don't put base gid in group
+ vector
+ [003f153bd396]
+
+ * check.c:
+ S/Key support now works with sunos4 shadow passwords
+ [1eb64a5efff1]
+
+ * Makefile.in:
+ fixed clean rule
+ [5695a2c62816]
+
+ * config.h.in, configure.in:
+ added DCE support
+ [f53c766c1947]
+
+ * tgetpass.c:
+ DCE & KERB support
+ [904cf436506a]
+
+ * check.c:
+ first stab at dce support
+ [aea5ca07b1e3]
+
+ * dce_pwent.c:
+ now smells like sudo
+ [8b3d609b49cd]
+
+ * dce_pwent.c:
+ Initial revision
+ [b573555f2399]
+
+ * check.c:
+ skey'd sudo now works w/ normal password as well
+ [8d038f9f6e94]
+
+1995-11-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, OPTIONS, check.c, compat.h, config.h.in, find_path.c,
+ getwd.c, goodpath.c, ins_2001.h, ins_classic.h, ins_csops.h,
+ ins_goons.h, insults.h, interfaces.c, logging.c, options.h, parse.c,
+ parse.lex, parse.yacc, pathnames.h.in, putenv.c, strdup.c, sudo.c,
+ sudo.h, sudo_setenv.c, testsudoers.c, tgetpass.c, utime.c,
+ version.h, visudo.c:
+ updated version number
+ [ba7e346d7904]
+
+ * README:
+ updated to reflect version change
+ [1d15cf1d8cc8]
+
+ * configure.in:
+ --with options now line up ++version
+ [08ebf625fbca]
+
+ * sudo.h:
+ removed unecesary S/Key stuff
+ [68188cba90af]
+
+ * configure.in:
+ fixed S/Key support
+ [f6d9cbc36618]
+
+ * Makefile.in:
+ -I stuff now goes in CPPFLAGS
+ [7b8e53c5b046]
+
+ * check.c:
+ fixed SKey support
+ [52c1a5cf4435]
+
+ * README:
+ updated version
+ [bed6498a10bb]
+
+ * OPTIONS:
+ fixed description of EXEMPTGROUP
+ [cfeead55edc2]
+
+ * sudo.c:
+ more people use _RLD_ than just alphas...
+ [6a3c7090a6f6]
+
+ * Makefile.in:
+ replaced $man_prefix with $mandir
+ [dc4b36a550e2]
+
+ * configure.in:
+ fixed a typo
+ [a38a4acddcaf]
+
+ * Makefile.in:
+ now use more GNU'ish dir names
+ [c5498391a520]
+
+ * configure.in:
+ now set *dir correctly (can override from command line)
+ [523ff98fd438]
+
+ * sudo.c:
+ now deal with situations where we getwd() fails
+ [88a9e61dccbb]
+
+1995-11-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ added etc_dir, bin_dir, sbin_dir
+ [75fd08d92842]
+
+ * configure.in:
+ added sbin_dir
+ [3cb318c0d8d1]
+
+ * Makefile.in:
+ now ship a flex-generated lex.yy.c
+ [4d083ed70dce]
+
+ * Makefile.in:
+ now sets _PATH_SUDO_SUDOERS, _PATH_SUDO_STMP, SUDOERS_OWNER
+ [4d51dc9c3780]
+
+ * pathnames.h.in:
+ _PATH_SUDO_SUDOERS & _PATH_SUDO_STMP are now overridden via Makefile
+ [773fd163d52f]
+
+ * options.h:
+ no more error for redefining SUDOERS_OWNER
+ [4ba336644c6a]
+
+ * OPTIONS:
+ expanded SUDOERS_OWNER section
+ [12fae405759e]
+
+1995-11-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ now warn if chown(2) failed
+ [d0d1db6e3a1f]
+
+ * logging.c:
+ better default warning for NO_SUDOERS_FILE
+ [5260b458ac64]
+
+ * sudo.c:
+ added missing set_perms() no more cryptic message if the sudoers
+ file is zero length, now just give a parse error
+ [b81ea724838a]
+
+ * logging.c:
+ better diagnostics if NO_SUDOERS_FILE
+ [877e878663c5]
+
+ * sudo.c:
+ check_sudoers() now catches sudoers files that are not readable (but
+ are stat'able).
+ [fea05663b3de]
+
+1995-11-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ now add -D__STDC__ for convex cc (not gcc)
+ [c80fc53ff51b]
+
+ * configure.in:
+ MAN_PREFIX -> man_prefix now sets prefix and exec_prefix
+ [fe238226a057]
+
+ * Makefile.in:
+ now uses exec_prefix & prefix from configure
+ [f62fca5f56bd]
+
+ * find_path.c, getwd.c, goodpath.c, interfaces.c, logging.c, parse.c,
+ parse.lex, parse.yacc, sudo.c, sudo.h, sudo_setenv.c, tgetpass.c,
+ utime.c, visudo.c:
+ options.h is now <> instead of "" so shadow build trees can have a
+ custom copy of options.h
+ [e6782676099c]
+
+ * check.c:
+ user_is_exempt() is no longer a hack, it now uses getgrnam()
+ [287f8d5356f7]
+
+ * options.h:
+ EXEMPTGROUP is now "sudo"
+ [61487304dbe1]
+
+ * configure.in:
+ MAN_POSTINSTALL now contains a leading space
+ [eaad4ac34012]
+
+ * Makefile.in:
+ removed leading tab if @MAN_POSTINSTALL@ not defined now removes
+ testsudoers in clean:
+ [e01711baceb8]
+
+ * tgetpass.c:
+ includes pwd.h to get _PASSWD_LEN definition
+ [8ec174f263f1]
+
+1995-10-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ unset the KRB_CONF envariable if using kerberos so we don't get
+ spoofed into using a bogus server
+ [2561a0274fca]
+
+1995-09-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ now explicately initialize match[] tp be FALSE
+ [0e45e5c47766]
+
+1995-09-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ removed unused variable now passes -Wall
+ [3452508bc16d]
+
+ * parse.yacc:
+ yyerror and dumpaliases are now void's now passes -Wall
+ [2769dfb51993]
+
+ * parse.lex:
+ added prototype for yyerror
+ [1f3f0c1b4ab4]
+
+ * check.c, logging.c, parse.c:
+ now passes -Wall
+ [eab57e5e81d2]
+
+ * interfaces.c:
+ rmeoved unused cruft now passes -Wall
+ [7a47e1866f4b]
+
+ * Makefile.in:
+ fixed headers that moved to emul dir
+ [e680c1e5049b]
+
+ * logging.c:
+ fixed deref of nil pointer if no args
+ [973b9bea432f]
+
+1995-09-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * OPTIONS:
+ added a caveat to FQDN section
+ [dcf6e2a5fff4]
+
+1995-09-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ more $srcdir support for install targets
+ [f6eac78436dd]
+
+ * find_path.c, interfaces.c, parse.c, parse.lex, parse.yacc, putenv.c,
+ strdup.c, sudo.c, sudo_setenv.c, testsudoers.c, visudo.c:
+ don't include malloc.h if we include stdlib.h
+ [fca2ff307cd8]
+
+ * parse.yacc:
+ local search.h now lives in emul
+ [51c458904424]
+
+ * check.c, utime.c:
+ local utime.h now lives in emul dir
+ [f92fc9e8c8de]
+
+ * lsearch.c:
+ local search.h now lives in emul
+ [579efc407439]
+
+ * Makefile.in:
+ added support for building in other than the sourcedir
+ [2ab53a43f7d4]
+
+1995-09-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * OPTIONS:
+ annotated CSOPS_INSULTS option
+ [9e57d45a0afa]
+
+ * TROUBLESHOOTING:
+ updated shadow passwords blurb
+ [39b785bc7253]
+
+ * sudo.c:
+ if SHELL_IF_NO_ARGS is set, "sudo -- foo" now runs a shell and
+ passes along foo as the arguments
+ [a91077aa8fc5]
+
+1995-09-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.lex:
+ collapsed pathname and dir sections into one -- its now less
+ expensive
+ [89caa03bec25]
+
+ * parse.lex:
+ fixed spacing quoting [,:\\=] now works correctly append() and
+ fill() now take args to make the above work
+ [09d023d9ef3a]
+
+ * sudo.c:
+ fixed a typo that caused commands with no tty on fd 0 but a tty on
+ fd 1 to erroneously have "none" as their tty
+ [07d2c0e7977c]
+
+1995-09-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ timestampfile is now a global static removed decl of timestampfile
+ in remove_timestamp since we can just use the global one
+ [f0cbdc6aab1c]
+
+ * check.c:
+ created touch() to update timestamps added USE_TTY_TICKETS support
+ (bit of a kludge)
+ [cee1dd0318f8]
+
+ * compat.h:
+ added _S_IFDIR and S_ISDIR
+ [b4a51cc9628e]
+
+ * OPTIONS, options.h:
+ added USE_TTY_TICKETS
+ [b4e22f81f25e]
+
+ * parse.yacc:
+ removed const from casts for lsearch() & lfind() to placate irix 4.x
+ C compiler
+ [5003081f76ea]
+
+1995-09-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ now only strip '/dev/' off of a tty if it starts with '/dev/'
+ [7f62bcd24039]
+
+ * pathnames.h.in:
+ added _PATH_DEV
+ [6375f44d1910]
+
+ * configure.in:
+ AC_HAVE_HEADERS -> AC_CHECK_HEADERS now check for tcgetattr only if
+ have termios.h
+ [9c60391235fd]
+
+ * tgetpass.c:
+ fixed incorrect #ifdef termio uses "unsigned short" not int for
+ c_?flag
+ [d032e6a29845]
+
+ * parse.lex, parse.yacc:
+ fixed a spelling error
+ [cad6a944c7b1]
+
+ * Makefile.in:
+ fixed typo
+ [204a65403e7c]
+
+1995-09-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ fixed a comment
+ [268f760e57ad]
+
+ * parse.yacc:
+ added dotcat() to cat 2 strings w/ a dot effeciently now that we
+ dynamically allocate strings they need to be free()'d
+ [ec2e2152f415]
+
+ * parse.lex:
+ dynamically allocates space for strings
+ [d10ac3533d66]
+
+ * sudo.h:
+ no more MAXCOMMANDLENGTH
+ [e2e1219bff8a]
+
+ * sudo.h:
+ added decl of tty
+ [c8ae81303ee5]
+
+ * logging.c, sudo.c:
+ moved tty stuff into sudo.c
+ [e028abefeb07]
+
+1995-09-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ fixed a logic bug. Was denying a command if user gave command line
+ args but there were none in the sudoers file which is wrong.
+ [7489a99b8e8a]
+
+ * sudo.h:
+ MAXCOMMMANDLEN dropped down to 1K
+ [38ef54ba290b]
+
+ * parse.lex:
+ return foo; -> return(foo);
+ [0e8be1b57001]
+
+ * parse.yacc:
+ fixed netgr_matches() prototype
+ [e69f15910464]
+
+ * parse.lex:
+ added support for escaping "termination" characters
+ [8bd4ef50f35c]
+
+ * parse.c:
+ buf is now of size MAXPATHLEN+1 since it never holds command args
+ [2ce4b763058c]
+
+ * sudo.c:
+ fixed comments
+ [0c74a3d2ebb0]
+
+ * goodpath.c:
+ fixed negation problem (doh!)
+ [782814e3a2d1]
+
+ * parse.yacc:
+ fixed 2nd parameter to lfind()
+ [63d7b1623c08]
+
+ * parse.lex:
+ now do bounds checking in fill() and append()
+ [54381b563251]
+
+ * sudo.c:
+ include netdb.h as we should added a missing void cast added
+ SHELL_IF_NO_ARGS support now use realloc() properly. would fail if
+ realloc actually moved the string instead of shrinking it
+ [897ccdec9c06]
+
+ * sample.sudoers:
+ updated with examples of new features
+ [9b3ed00e8aa6]
+
+ * goodpath.c:
+ now set errno to EACCES if not a regular file or not executable
+ [2d069548a5ea]
+
+ * find_path.c:
+ if given a fully-qualified or relative path we now check it with
+ sudo_goodpath() and error out with the appropriate error message if
+ the file does not exist or is not executable
+ [590f89dd8dec]
+
+ * emul/search.h, lsearch.c:
+ now use correct args for lfind
+ [fccdcdbf020e]
+
+ * logging.c:
+ added a comment
+ [fab9f49708ea]
+
+ * insults.h:
+ added in CSOps insults
+ [ad8eb1862adc]
+
+ * ins_csops.h:
+ Initial revision
+ [de5a475ec018]
+
+ * tgetpass.c:
+ added RCS id
+ [c3ffd550a482]
+
+ * sudo.h:
+ increased MAXCOMMANDLENGTH to 8k HAVE_GETCWD -> HAVE_GETWD
+ [aba25c90d08a]
+
+ * OPTIONS:
+ added CLASSIC_INSULTS, CSOPS_INSULTS, SHELL_IF_NO_ARGS
+ [e27bd62e9ccf]
+
+ * sudo.c:
+ fixed -k load_interfaces() now gets called if FQDN is set
+ -p now works with -s
+ [07ca2a34bae8]
+
+ * parse.c:
+ don't try to stat() "pseudo commands" like "validate"
+ [75527045984b]
+
+ * options.h:
+ added CLASSIC_INSULTS added CSOPS_INSULTS added SHELL_IF_NO_ARGS
+ [07b157a0eafd]
+
+ * configure.in:
+ added SecurID support added other insults to --with-csops
+ [6c992ceb244c]
+
+ * config.h.in:
+ added HAVE_SECURID
+ [e734ff617fe8]
+
+ * Makefile.in:
+ added clobber target added ins_csops.h now gets CFLAGS from
+ configure
+ [d1e29c7cec25]
+
+ * aclocal.m4:
+ relaxed SUDO_FULL_VOID
+ [fb4084f27406]
+
+ * visudo.c:
+ function comment blocks are now in same style as rest of code
+ [04a2931354c5]
+
+ * testsudoers.c:
+ added support for command line args in /etc/sudoers
+ [bfe4e1bcc655]
+
+ * sudoers.man:
+ updated to have command args in the sudoers file
+ [1cd34355e9ea]
+
+ * sudo.man:
+ added -s and -- flags added SHELL to ENVIRONMENT VARIABLES section
+ [930b48023b68]
+
+1995-08-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ PATH renamed to COMMAND
+ [4e109a6de3cd]
+
+ * parse.lex:
+ it is now a parse error for directories to have args attached to
+ them
+ [2ab10a146b54]
+
+ * logging.c:
+ now say command args if telling user to buzz off
+ [933de26ded8b]
+
+ * sudo.c:
+ -s no longer indicates end of args sped up loading on cmnd_args in
+ load_cmnd()
+ [eac99a4da862]
+
+ * parse.c:
+ removed an unreachable statement
+ [634302623c49]
+
+ * parse.lex:
+ made more efficient by pulling out the terminators when in GOTCMND
+ state and making them their own rule
+ [80798f1e1166]
+
+1995-08-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.h:
+ removed MAXLOGLEN since it is no longer used
+ [102824196b71]
+
+ * parse.lex:
+ now allows command args
+ [d29dfa1e5254]
+
+ * parse.c:
+ now groks command arguments
+ [6c414cb7f105]
+
+ * logging.c:
+ now sets tty correctly when piped input
+ [de46a30c0406]
+
+ * sudo.c:
+ fixed loading of cmnd_args (was including command name too)
+ [15319a425ea6]
+
+ * logging.c:
+ fixed a core dump due to incorrect if construct
+ [582363c7d7fa]
+
+1995-08-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ only add -lsun is irix < 5 don't look for -lnsl or -lsocket if irix
+ [da591fe9b931]
+
+ * aclocal.m4:
+ fixed check for ISC
+ [52e59f2082a7]
+
+ * sudo.c:
+ now sets cmnd_args used by log_error() and that will be used by the
+ parse to check against command args
+ [c6804389723b]
+
+ * sudo.h:
+ added cmnd_args
+ [4d00446b4a8d]
+
+ * logging.c:
+ now dynamically allocate logline since we can guess at its size
+ [4bed8c8446aa]
+
+1995-08-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ cleaned up a bunch of unnecesary #ifdef's eliminated a buffer remove
+ "register" since the compiler knows more than I do now do a
+ "basename" of the tty
+ [3b1bbf0b3da1]
+
+1995-07-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ ++version
+ [5ce552f9a5f1]
+
+ * sudo.h:
+ added shell extern changed MODE_* to be bit masks to allow for
+ several options together
+ [06f9dc4f400c]
+
+ * sudo.c:
+ added -s (shell) option made MODE_* masks so we can do bitwise & and
+ | to see if multiple flags are set.
+ [01f8143010ad]
+
+ * check.c:
+ added securid support
+ [909e078005fe]
+
+1995-07-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ removed a bunch of unnecesary strncpy()'s and replaced with strcat()
+ [644506b57d61]
+
+1995-07-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, version.h:
+ ++version
+ [3cd6f1fbc3d9]
+
+1995-07-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ fixed free() of an uninitialized pointer (yuck)
+ [8c404ee502ee]
+
+ * testsudoers.c:
+ added netgr_matches
+ [e7c9fa2f774c]
+
+ * parse.c:
+ cleaned up netgr_matches
+ [8108f00b810e]
+
+1995-07-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON:
+ updated for 1.3.4
+ [4741704310a1]
+
+1995-07-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ now installs sudoers.man -- really should clean this up though.
+ [455631d45a1d]
+
+ * Makefile.in:
+ added sudoers.cat and sudoers.man
+ [0bdedd6c7363]
+
+ * sudo.man:
+ pulled out stuff on the sudoers file format into a separate man page
+ [de215d999cb9]
+
+ * sudoers.man:
+ Initial revision
+ [f25eafbb7095]
+
+ * HISTORY:
+ fixed up my email address
+ [254fbf80be74]
+
+ * configure.in:
+ added checks for innetgr and getdomainname
+ [24a99cb7e97e]
+
+ * visudo.c:
+ added dummy netgr_matches function
+ [1841ff2c01da]
+
+ * parse.c:
+ added netgr_matches
+ [ec90db6a97b8]
+
+ * parse.lex, parse.yacc:
+ added NETGROUP support
+ [c9dd93e3bc4b]
+
+ * config.h.in:
+ added HAVE_INNETGR & HAVE_GETDOMAINNAME
+ [14abd494d875]
+
+1995-07-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ rewrote clean_env() that has rm_env() builtin
+ [55cb43818a95]
+
+1995-07-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ now cast uid to long in sprintf
+ [b549eea40aeb]
+
+ * OPTIONS:
+ added _INSULTS suffix to HAL & GOONS end
+ [ed620d0aad30]
+
+ * options.h:
+ added _INSULTS suffix to HAL & GOONS
+ [9f72e9b83afd]
+
+ * ins_2001.h, ins_classic.h, ins_goons.h, insults.h:
+ converted to new scheme of insult "unions" end
+ [2f6d2b412132]
+
+ * sudo.c:
+ now uses MAX_UID_T_LEN
+ [c1df79e0f389]
+
+ * configure.in:
+ added SUDO_UID_T_LEN !l
+ [195f0b9f5f84]
+
+ * config.h.in:
+ added MAX_UID_T_LEN
+ [73f42ae4f14d]
+
+ * check.c:
+ now use MAX_UID_T_LEN
+ [df9c063234cb]
+
+ * aclocal.m4:
+ added check for max len of uid_t fixed sco vs. isc check
+ [d558f36d2223]
+
+1995-07-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ corrected version
+ [828dd1571e86]
+
+ * configure.in:
+ added sco support
+ [af1e2f616638]
+
+ * aclocal.m4:
+ hack to check for sco
+ [549ab99a9a43]
+
+ * interfaces.c:
+ removed #include <net/route.h> since it was hosing some OS's
+ [ac78a7c04005]
+
+1995-07-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * find_path.c:
+ fixed prreadlink() prototype
+ [b380fe1f2b11]
+
+ * check.c:
+ added parens in #if's
+ [e96ade691b82]
+
+ * configure.in:
+ added SPW_ prefix
+ [a302683a1483]
+
+ * sudo.h:
+ moved SPW_* to config.h.in
+ [6b3be70e34cf]
+
+ * sudo.c:
+ added a set of parens
+ [8188d735d695]
+
+ * config.h.in:
+ added SPW_*
+ [5ead6371cf60]
+
+ * sudo.h:
+ added SPW_* reordered error codes
+ [dead25b4ed0a]
+
+ * check.c:
+ moved SPW_* to sudo.h
+ [ca51fb04caf4]
+
+1995-07-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ SPW_AUTH -> SPW_SECUREWARE
+ [6b512b2bc5dc]
+
+ * logging.c:
+ GLOBAL_NO_AUTH_ENT -> GLOBAL_NO_SPW_ENT
+ [defdd0944e2f]
+
+ * configure.in:
+ AUTH -> SECUREWARE
+ [d1f8a17001dd]
+
+ * check.c:
+ SPW_AUTH -> SPW_SECUREWARE
+ [af0e8d8b89b2]
+
+ * check.c:
+ now uses SHADOW_TYPE to make shadow pw support more readable and
+ modular. It's a start...
+ [8c2a59667014]
+
+ * configure.in:
+ added autodetection of shadow passwords
+ [85f81fa54b1b]
+
+ * sudo.c:
+ now uses SHADOW_TYPE define
+ [355e5dc09b07]
+
+ * config.h.in:
+ added SHADOW_TYPE which replaces SUNOS4 & __svr4__ defines
+ [c0c06e83e483]
+
+ * aclocal.m4:
+ added SUDO_CHECK_SHADOW
+ [464301301639]
+
+1995-07-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ define SVR4 for ISC define BROKEN_SYSLOG for hpux took out test for
+ memmove() since we dno longer use it...
+ [8aefa87d7d31]
+
+ * CHANGES:
+ updated
+ [ce97b3fd7182]
+
+ * logging.c:
+ added BROKEN_SYSLOG support
+ [a45c3bca36f6]
+
+ * config.h.in:
+ added BROKEN_SYSLOG
+ [6f6abf0a6268]
+
+ * check.c:
+ now only bitch it timestamp > time_now + 2 * timeout to allow for a
+ machine udpating its time from a server
+ [546bc8d35325]
+
+ * sudo.man:
+ added 2 security notes updated Nieusma's email addr
+ [616756c56977]
+
+ * lsearch.c:
+ changed a memmove() to memcpy() since we don't have to worry about
+ overlapping segments.
+ [30baa478526b]
+
+1995-07-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * interfaces.c:
+ cleanup up the loop when interfaces are groped in so that it is
+ readable
+ [1fa39446bd69]
+
+ * Makefile.in, version.h:
+ ++version
+ [b46bd2b1770f]
+
+1995-07-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ annotated 124-126
+ [b82a2b3ec7ce]
+
+1995-07-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ fixed permissions check on /tmp/.odus
+ [cc2431a65468]
+
+1995-07-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ fixed some comments
+ [8896d09b4fda]
+
+ * check.c:
+ now checks owner & mode of timedir also checks for bogus dates on
+ timestamp file
+ [a0fad5df5b0a]
+
+ * OPTIONS:
+ updated TIMEOUT info
+ [033cc22d9e04]
+
+ * logging.c, sudo.h:
+ added BAD_STAMPDIR and BAD_STAMPFILE
+ [31d9ce691101]
+
+ * compat.h:
+ added definition of S_IRWXU
+ [ff2dab091a9b]
+
+ * CHANGES:
+ updated
+ [a40df90284f1]
+
+1995-07-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * interfaces.c:
+ added #ifdef to make it compile on strange arches
+ [4a127f12afce]
+
+1995-07-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4:
+ fixed check for fulkl void impl.
+ [b6f2a4a361d8]
+
+ * check.c:
+ added mssing "static"
+ [520552f2772b]
+
+ * insults.h:
+ replaced #elif with #else #if constructs for ancient C compilers
+ [39ab2d365b57]
+
+ * INSTALL:
+ updated irix c2 & kerb5 info
+ [ae79b99b4905]
+
+ * configure.in:
+ added shadow pw support for irix
+ [632469d9c528]
+
+1995-07-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS, TODO:
+ updated
+ [2a96bb18ac30]
+
+ * CHANGES:
+ last changes for sudo 1.3.3
+ [c1c0cd1034b8]
+
+ * configure.in:
+ now calls SUDO_SOCK_SA_LEN
+ [14ea78159d45]
+
+ * config.h.in:
+ added HAVE_SA_LEN
+ [cc2a346aa905]
+
+ * aclocal.m4:
+ added SUDO_SOCK_SA_LEN
+ [456a2025644a]
+
+ * interfaces.c:
+ now works with ip implementations that use sa_len in sockaddr
+ [90be6e028077]
+
+ * INSTALL:
+ added note about buggy AIX compiler
+ [c0f6d427e4e4]
+
+ * interfaces.c:
+ now include sys/time.h for AIX
+ [2510858ab38b]
+
+1995-06-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ getcwd -> getwd
+ [66085ebca98e]
+
+ * interfaces.c:
+ now works for ISC and others. yay.
+ [f336d4ffc927]
+
+1995-06-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, version.h:
+ version++
+ [836cffc2078d]
+
+1995-06-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4:
+ fixed test for full void impl
+ [fb004107e7b9]
+
+ * sudo.c:
+ now check to see that st_dev is non-zero before assuming that we are
+ being spoofed
+ [1b0e1c30c506]
+
+1995-06-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4, configure.in:
+ SUDO_FUNC_UTIME_NULL -> AC_FUNC_UTIME_NULL
+ [4953379bfb01]
+
+1995-06-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * aclocal.m4:
+ fixed include file order for SUDO_FUNC_UTIME_POSIX
+ [ff64ab7df44f]
+
+ * logging.c:
+ added cast for ttyname()
+ [444f05f56758]
+
+ * configure.in:
+ fixed typo
+ [de068e748431]
+
+ * check.c:
+ now deal correctly with all known variation of utime() -- yippe
+ [b778a4195a89]
+
+ * configure.in:
+ added SUDO_FUNC_UTIME_POSIX
+ [cf635f2269d6]
+
+ * aclocal.m4:
+ added SUDO_FUNC_UTIME_NULL and SUDO_FUNC_UTIME_POSIX
+ [d79593be4b73]
+
+ * config.h.in:
+ added HAVE_UTIME_POSIX
+ [c67b4ac0dca5]
+
+ * check.c:
+ fixed a typo
+ [b14df5680f59]
+
+ * check.c:
+ no longer assume !HAVE_UTIME_NULL means old BSD utime()
+ [0aeaf4b2f38b]
+
+ * check.c:
+ fixed fascist C compiler warning
+ [c61ddf2f1f93]
+
+ * interfaces.c:
+ now set strioctl.ic_timout in STRSET() now initialize num_interfaces
+ to 0 (just to be anal)
+ [c54cc2ba0052]
+
+1995-06-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.h:
+ increaed MAXLOGLEN by MAXPATHLEN to account for ttyname
+ [74cf585a54fb]
+
+ * logging.c:
+ added tty logging
+ [e27d8dcfbd78]
+
+ * interfaces.c:
+ reworked the ISC code
+ [bcf57ce8ae69]
+
+ * Makefile.in, version.h:
+ updated version
+ [032941c9b94d]
+
+ * check.c:
+ now expect old-style utime(3) if utime() can't take NULL as an arg
+ [018dd4a73030]
+
+ * configure.in:
+ added check for utime.h
+ [0b76e8feb618]
+
+ * config.h.in:
+ added HAVE_UTIME_H
+ [62ee42feda46]
+
+ * Makefile.in:
+ added CPPFLAGS STATIC_FLAGS -> LDFLAGS
+ [fa3201d294e1]
+
+ * configure.in:
+ now search for kerb libs and includes
+ [cc332401e571]
+
+ * check.c:
+ added support for utime(2)'s that can't take a NULL parameter
+ [98797fedf69f]
+
+ * utime.c:
+ moved HAVE_UTIME_NULL stuff to update_timestamp() where t belongs
+ [6ce6d825fb44]
+
+ * configure.in:
+ added utime(s) stuff
+ [a2afb744403e]
+
+ * check.c:
+ now use utime()
+ [48902240a51e]
+
+ * config.h.in:
+ added HAVE_UTIME and HAVE_UTIME_NULL
+ [9a56ab65d4f4]
+
+1995-06-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * utime.c:
+ now use HAVE_UTIME_NULL
+ [e3944de09a92]
+
+ * emul/utime.h, utime.c:
+ Initial revision
+ [a2cbf2ef3427]
+
+ * check.c:
+ need to setuid(0) to make kerb4 stuff work.
+ [c6cfda4039d7]
+
+ * tgetpass.c:
+ no more special case for kerberos
+ [4a5c33145be9]
+
+ * config.h.in:
+ took out setreuid and setresuid stuff added kerb5 stuff (use kerb4
+ emulation)
+ [a607ee43e650]
+
+ * compat.h:
+ no longer need setreuid() emulation now set _PASSWD_LEN to 128 if
+ kerberos
+ [02fb274cc136]
+
+ * check.c:
+ now use private ticket file for kerberos support to avoid trouncing
+ on system one
+ [28d8b6b812c7]
+
+1995-06-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.h:
+ added SPOOF_ATTEMPT & cmnd_st
+ [d3b42a1f4d0d]
+
+ * sudo.c:
+ added anti-spoofing support
+ [ab1e2aa44a57]
+
+ * parse.c:
+ now use global cmnd_st
+ [47018265a1a6]
+
+ * logging.c:
+ added SPOOF_ATTEMPT suypport
+ [7bbe9dd2a021]
+
+ * testsudoers.c, visudo.c:
+ added void casts where appropriate
+ [f191441ba333]
+
+ * parse.yacc:
+ fixed up spacing and added void casts where appropriate
+ [15d886fc809c]
+
+ * sudo.c:
+ fixed problem with "-p prompt" but no args
+ [6fc048261a3e]
+
+1995-06-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.man:
+ added BUGS and annotated -l description
+ [e5c506de2603]
+
+ * sudo.h:
+ validate() now takes a flag
+ [26627becc60a]
+
+ * sudo.c:
+ validate() now takes a flag added -l
+ [a4f7bb97fe54]
+
+ * parse.yacc:
+ added support for -l
+ [e7a9b10b0ad3]
+
+ * parse.c:
+ validate() now takes a flag that says whether or not to check the
+ command
+ [9e1e67f4e281]
+
+1995-06-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ now deals with Argv == 1
+ [0acb637ab635]
+
+ * sudo.man:
+ added -p option
+ [e60382fc0561]
+
+ * sudo.c:
+ added prompt support reworked parse_args()
+ [2f605267ed4a]
+
+ * sudo.h:
+ added prompt
+ [5ab021bdb419]
+
+ * options.h:
+ added PASSPROMPT
+ [614727ff44a2]
+
+ * check.c:
+ now use BUFSIZ as length of kerb password added kpass so pass is
+ always a char * now use prompt global when asking for a password
+ [76be09af784f]
+
+ * tgetpass.c:
+ now use BUFSIZ as _PASSWD_LEN if using kerberos
+ [1e907eed312b]
+
+ * OPTIONS:
+ added PASSPROMPT
+ [ddb2f405ce40]
+
+1995-06-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ only look for -lufc or -lcrypt if crypt() not in libc
+ [9717d315661f]
+
+ * check.c:
+ don't exit on kerb error, just warn if k_errno == KDC_PR_UNKNOWN
+ (unknown user) silently fail
+ [2b48693d4ee9]
+
+ * INSTALL:
+ added kerb4 note
+ [986e393f740c]
+
+ * tgetpass.c:
+ HAVE_KERBEROS -> HAVE_KERB4
+ [e438bfb5e6aa]
+
+ * check.c:
+ removed debugging printf
+ [1cf9f5cbffa5]
+
+ * configure.in:
+ KERBEROS -> KERB4 added checks for setreuid & setresuid
+ [01e9945beb1e]
+
+ * config.h.in:
+ HAVE_KERBEROS -> HAVE_KERB4 added HAVE_SETREUID and HAVE_SETRESUID
+ [0e0bb5b8ac3e]
+
+ * compat.h:
+ added deif of UID_NO_CHANGE & GID_NO_CHANGE added setreuid emulation
+ with setresuid if applic
+ [9dae24c47696]
+
+ * check.c:
+ HAVE_KERBEROS -> HAVE_KERB4 now only do the stupid chown() hack if
+ no setreuid() or a broken one
+ [1fca642bdb8e]
+
+1995-06-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ added kerberos support
+ [da5639b9b8e7]
+
+ * config.h.in:
+ added HAVE_KERBEROS
+ [fcc5be550e65]
+
+ * tgetpass.c:
+ added KERBEROS support (long passwords)
+ [303ba6924dd2]
+
+ * check.c:
+ added kerberos support
+ [e40afe98fc1d]
+
+1995-06-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.h:
+ added MODE_BACKGROUND
+ [9b483c932016]
+
+ * sudo.man:
+ escaped dashes added -b option
+ [62e84f1a7714]
+
+ * sudo.c:
+ added -b option
+ [7e78aaefeb95]
+
+ * check.c:
+ added crypt() for osf/1 3.x enhanced secuiry
+ [e9aa5abdb7d5]
+
+ * configure.in:
+ now check for -lcrypt
+ [5cb9c67e9fa2]
+
+ * interfaces.c:
+ added ENXIO like EADDRNOTAVAIL
+ [74223bb1ba75]
+
+1995-05-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ now emulate getwd(), not getcwd()
+ [3e5439d9a5f4]
+
+ * sudo.c:
+ getcwd() -> getwd()
+ [6392a96a658e]
+
+ * getwd.c:
+ getcwd -> getwd
+ [1b0ab9bae11e]
+
+1995-05-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * ins_2001.h, ins_classic.h, ins_goons.h:
+ Initial revision
+ [86db60d8cf00]
+
+ * insults.h:
+ broke out insults into separate include files
+ [0a01993bd38a]
+
+ * OPTIONS, options.h:
+ added GOONS
+ [e283203c6515]
+
+ * Makefile.in:
+ added ins_2001.h ins_classic.h ins_goons.h
+ [2a39cd6a4cd2]
+
+ * Makefile.in, version.h:
+ ++version
+ [05ebf4f5e41a]
+
+ * visudo.c:
+ moved signal handler setup to setup_signals()
+ [3dd976c04540]
+
+ * sudo.h:
+ added load_interfaces()
+ [af2d473b09e2]
+
+ * sudo.c:
+ moved load_interfaces to interfaces.c
+ [5c8c138e5d4c]
+
+ * parse.yacc:
+ added clearaliases
+ [aeb4ff301daa]
+
+ * OPTIONS, options.h:
+ added FAST_MATCH
+ [f49ea3d1b525]
+
+ * parse.lex:
+ now uses clearaliases variable
+ [a2dda415bf61]
+
+ * interfaces.c:
+ Initial revision
+ [a1990e3f5c69]
+
+ * Makefile.in:
+ added interfaces.[co]
+ [1e8e5984de97]
+
+ * testsudoers.c:
+ now uses ip addrs and netmasks via load_interfaces()
+ [54b8f7a6835e]
+
+ * sudo.c:
+ now remove IFS instead of setting to "sane" value
+ [ce7eec9f115e]
+
+1995-05-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.c:
+ added FAST_MATCH
+ [816d4f5fe81a]
+
+1995-04-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ sudo_goodpath.c-> goodpath.c
+ [a5072c4e1de2]
+
+ * sudo.c:
+ added Andy's new ISC changes
+ [caa6bbee358e]
+
+1995-04-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * OPTIONS:
+ added a sentence to SECURE_PATH info
+ [cad6e1569d15]
+
+ * BUGS:
+ added one
+ [4b35cf699a83]
+
+ * CHANGES:
+ updated
+ [5fded9dc62f0]
+
+ * RUNSON:
+ updated
+ [33cb993cfd39]
+
+1995-04-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * RUNSON:
+ updated for beta3
+ [a05dc6a91995]
+
+ * Makefile.in, version.h:
+ ++version
+ [54aaf3fadc75]
+
+ * aclocal.m4:
+ sendmail is now looked for in /usr/ucblib
+ [231ac1a4662f]
+
+ * sudo.c:
+ fixed indentation
+ [fb137400c8c2]
+
+ * aclocal.m4:
+ fixed a typo
+ [e03f1acc468b]
+
+ * sudo.c:
+ updated ISC mods
+ [070290d4754b]
+
+ * configure.in:
+ added unixware case
+ [e90250bae0d9]
+
+ * check.c:
+ user_is_exempt is no longer hidden
+ [1a341765b8af]
+
+ * RUNSON:
+ updated
+ [a9c4898b26dd]
+
+ * aclocal.m4:
+ isc and riscos changes
+ [98b5d86585d1]
+
+ * OPTIONS:
+ added NOTE about new interaction of EXEMPTGROUP and SECURE_PATH
+ [e1ecc464ce4b]
+
+ * Makefile.in:
+ fixed a typo and added testsudoers stuff
+ [435d60e163dc]
+
+ * testsudoers.c:
+ Initial revision
+ [6ce14a448662]
+
+1995-04-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ applied fixed patch from Chris
+ [cd6144203d13]
+
+1995-04-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ fixed a typo
+ [34f8a54ba041]
+
+ * parse.yacc:
+ added a set of braces for bison
+ [f0e43b938914]
+
+ * parse.yacc:
+ merged in Chris' changes to dekludge the parser.
+ [82d6e373ab1c]
+
+ * logging.c:
+ send_mail() was calling find_path() which is wrong since find_path()
+ stores cmnd in a static var. Anyhow, it doesn't make much sense
+ since MAILER should always be fully qualified
+ [6eae6a0b8098]
+
+1995-04-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sample.sudoers:
+ added User_Alias stuff
+ [aaba8c8e918d]
+
+ * aclocal.m4:
+ SUDO_NEXT now looks for /usr/lib/NextStep/software_version
+ [52bd81f34b32]
+
+ * RUNSON:
+ added DEC UNIX 3.0 w/ gcc
+ [7daf570775b5]
+
+ * visudo.c:
+ Exit was being used in places where exit should be used
+ [6026a89c07ed]
+
+ * sudoers:
+ added "User alias specification"
+ [a487b6e234f8]
+
+ * parse.yacc:
+ fixed probs caused by making nslots and naliases a size_t
+ [0be919384f3f]
+
+ * RUNSON:
+ added KSR, upped rev to 1.3.1b2
+ [ce04ee6faadf]
+
+ * logging.c, parse.yacc:
+ 1024 -> BUFSIZ
+ [cd6dda45fa11]
+
+ * parse.yacc:
+ void * -> VOID * naliases and nslots are now size_t to appease
+ lsearch on 64-bit machines
+ [bf2f807c0dc1]
+
+1995-04-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TODO:
+ did a bunch of things and added a bunch :-)
+ [42afd957b829]
+
+ * PORTING:
+ updated
+ [972f95c85776]
+
+ * visudo.man:
+ closer to BSD manpage style
+ [07ae88f50325]
+
+ * sudo.man:
+ closer to standard BSD man format
+ [372c28dcc135]
+
+ * compat.h, config.h.in, emul/search.h, insults.h, options.h,
+ pathnames.h.in, sudo.h, version.h:
+ added RCS id
+ [c0ec90b81002]
+
+ * sudo.h:
+ removed crufty #defines that are no longer used
+ [35e2b4b477f0]
+
+ * BUGS:
+ fixed a bug
+ [5bb3e1bee85e]
+
+ * sudo.man:
+ updated based on sudo changes
+ [e65de1cae438]
+
+ * parse.yacc:
+ now allow ALL keyword in User_Aliases now allow ALL keyword as well
+ as a NAME or ALIAS
+ [1fb31404dd0f]
+
+ * CHANGES:
+ updated
+ [b24018ac610b]
+
+ * sudo.c:
+ now sets SUDO_COMMAND and SUDO_GID envariables.
+ [e9d791557fb7]
+
+ * aclocal.m4:
+ fixed bug with full void impl check
+ [35715301023c]
+
+ * parse.yacc:
+ fixed User_Alias supoprt
+ [4c30dfbaaa07]
+
+ * parse.yacc:
+ added stubs for User_Alias support
+ [f4afbd247edf]
+
+ * sudo.c:
+ now sets removes # bogus interfaces from num_interfaces
+ [6f077fac9ab1]
+
+ * parse.lex:
+ added User_Alias support
+ [bc7997e5df85]
+
+1995-04-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ removed extraneous TODO
+ [bc87a3b14d6d]
+
+1995-04-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ ntwk_matches -> addr_matches
+ [475044e288b8]
+
+ * parse.yacc:
+ ntwk_matches -> addr_matches
+ [dd1f4093fd2d]
+
+ * parse.c:
+ ntwk_matches -> addr_matches now use inet_addr() not inet_network()
+ (which expects octet boundaries) fixes for OSF (sizeof(int) !=
+ sizeof(long))
+ [acd2f556940f]
+
+ * sudo.c:
+ took out debugging info
+ [044023063eca]
+
+ * aclocal.m4:
+ OS was being set to unknown before non-uname based host checks. This
+ caused no checks to happen since $OS was not zero-length.
+ [335a7267479d]
+
+ * sudo.c:
+ fixed loading of interfaces struct still has debugging info in
+ though
+ [2d1a18998c1e]
+
+ * parse.c:
+ fixed typo
+ [175674a3a9fa]
+
+1995-04-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ ++version
+ [55d191b5daa3]
+
+ * version.h:
+ ++
+ [d7d1f115696a]
+
+ * visudo.c:
+ removed extraneous extern decl of "top
+ [50355621047d]
+
+ * visudo.c:
+ now zeros "top"
+ [4e683210345b]
+
+ * parse.yacc:
+ removed parser_cleanup (no need for it now)
+ [afa59f222b6c]
+
+ * parse.lex:
+ now calls reset_aliases() directly
+ [3a23cbd60fc0]
+
+1995-04-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * OPTIONS:
+ added a sentence to SECURE_PATH description
+ [c5bf75b85af0]
+
+ * parse.c:
+ fixed my stupid bug where I used NAMLEN on something I wanted to
+ just get the name from. argh.
+ [111f460f6540]
+
+1995-04-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * lsearch.c:
+ fixed argument order of memmove() that i hosed when converting from
+ bcopy(). arghh.
+ [2f5336045c8b]
+
+ * Makefile.in:
+ finally fixed DISTFILES line
+ [a1b419e73a63]
+
+ * Makefile.in:
+ tabs -> spaces
+ [280fb03e5764]
+
+ * Makefile.in:
+ added missing files to DISTFILES
+ [991fc1cd2263]
+
+ * Makefile.in:
+ SUPPORTED -> RUNSON
+ [7580e65b05fb]
+
+1995-04-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TODO:
+ updated
+ [fe764a29c1cc]
+
+ * RUNSON:
+ updated for pl5b1 release
+ [aefc35bd2291]
+
+ * BUGS, TODO:
+ updated
+ [8f0ea249b687]
+
+ * check.c:
+ fixed bug where if you hit return at first sudo prompt it would
+ still log as a failure
+ [24539c854692]
+
+ * CHANGES:
+ updated
+ [251cc7b3ede4]
+
+ * aclocal.m4:
+ better test for bogus void * implementation
+ [efe23180cb88]
+
+ * logging.c:
+ added PASSWORDS_NOT_CORRECT
+ [bd12c73f83f7]
+
+ * check.c:
+ added PASSWORDS_NOT_CORRECT stuff]
+ [90de391a979f]
+
+ * sudo.h:
+ added PASSWORDS_NOT_CORRECT
+ [727fbeb76fc5]
+
+ * tgetpass.c:
+ moved pathnames.h
+ [4f910e5a8df7]
+
+ * sudo.c:
+ removed some unused vars and fixed up uid2str
+ [70e92c7f9076]
+
+ * putenv.c:
+ moved compat.h
+ [b271091586f6]
+
+ * getcwd.c, getwd.c:
+ added pathnames.h
+ [6f25218f133f]
+
+1995-03-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ fixed a typo I introduced in the last checkin :-(
+ [62c3af75c4fe]
+
+ * parse.lex:
+ can't have #ifdef's where N is defined so just do this the broken
+ way for AIX
+ [c5648a5594e4]
+
+ * parse.yacc:
+ better hack from Chris (but still a hack)
+ [6b6d8aed93f3]
+
+ * parse.lex:
+ stupid hack for broken aix lex
+ [efc3f9e5280e]
+
+ * tgetpass.c:
+ now includes compat.h 
+ [401822173f77]
+
+ * visudo.c:
+ now includes fcntl.h
+ [63865c2f8ac6]
+
+ * compat.h:
+ added FD_SET and FD_ZERO for 4.2BSD
+ [00c5597c0bb0]
+
+ * parse.yacc:
+ dirty hack to fix parser bug. i don't really like this but it works
+ for now...
+ [5b8bbdc81569]
+
+ * sudo.c:
+ uid2str is now static like the prototype says
+ [f2a97b5cb870]
+
+1995-03-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, SUPPORTED, TODO, TROUBLESHOOTING:
+ updated
+ [6f79c3e92716]
+
+ * RUNSON:
+ Initial revision
+ [12a09ef9e884]
+
+ * sudo.c:
+ check_sudoers now returns an error code and sudo calls inform_user
+ and log_error based on the return value.
+ [340eca188d9a]
+
+ * logging.c, sudo.h:
+ added entries for new errors
+ [6050d8542e1f]
+
+ * parse.c:
+ now set uid to that of SUDOERS_OWNER while parsing sudoers file
+ [3683c42bc9b0]
+
+ * Makefile.in:
+ took out testsudoers 
+ [65317d49db48]
+
+ * sudo.c:
+ now explicately checks that it is setuid root
+ [2fe1be60ef6a]
+
+ * sudo.c:
+ If a user has no passwd entry sudo would segv (writing to a garbage
+ pointer). Now allocate space before writing :-)
+ [d08e7eb5e5ef]
+
+ * configure.in:
+ reordered AC_CHECK_FUNCS
+ [4c82e56c6f4f]
+
+ * config.h.in:
+ fixed memset macro
+ [77ede6b714ab]
+
+ * tgetpass.c, visudo.c:
+ bzero -> memset
+ [1a005bb322c8]
+
+ * logging.c:
+ bzero -> memset when a parse error is logged the line number of the
+ error is now logged too
+ [a42d68047723]
+
+ * INSTALL:
+ added Sunos to blurb about c2 security
+ [af750a1d131e]
+
+ * configure.in:
+ added a SUN4 define for C2 security
+ [6ad5b23a3eb0]
+
+ * config.h.in:
+ bcopy -> memmove bzero -> memset
+ [5494460c8464]
+
+ * lsearch.c:
+ bcopy -> memmove char * -> VOID *
+ [a15f5c316e16]
+
+ * check.c:
+ added support for sunos with C2 security
+ [03fea5bb21e6]
+
+ * OPTIONS, options.h:
+ reordered
+ [1686265af3e1]
+
+ * pathnames.h.in:
+ _PATH_SUDO_LOGFILE now set based on configure
+ [5867b58e4a04]
+
+ * configure.in:
+ added SUDO_LOGFILE and SUDO_TYPE_SIZE_T
+ [1984d9fd1b5c]
+
+ * config.h.in:
+ added _SUDO_PATH_LOGFILE
+ [dd3eebe62580]
+
+ * aclocal.m4:
+ added SUDO_LOGFILE to find where to put sudo.log added
+ SUDO_CHECK_TYPE (just AC_CHECK_TYPE but checks unistd.h too) added
+ SUDO_TYPE_SIZE_T (calls SUDO_CHECK_TYPE)
+ [c589a515a99a]
+
+1995-03-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TROUBLESHOOTING:
+ Initial revision
+ [f42f1baba3a8]
+
+ * sudo.c:
+ now do set_perms(PERM_ROOT) before the getpwuid() in load_global()
+ to work around a problem is trusted hpux shadow passwords. yuck.
+ [ae1f13b54687]
+
+ * parse.yacc:
+ backed out a change in malloc/realloc
+ [ab868db0ad69]
+
+ * parse.yacc:
+ now include stdlib.h
+ [957eef0631eb]
+
+ * visudo.c:
+ now do an freopen() of the stmp file so that yyin will always point
+ to the same thing. This is important for flex since we are doing a
+ YY_NEWFILE
+ [44558922fd3e]
+
+ * parse.yacc:
+ replaced yywrap() with parser_cleanup() since yywrap() needs to be
+ in parse.lex to be able to use YY_NEW_FILE. sigh.
+ [12dd09921074]
+
+ * parse.lex:
+ now have a rule that matches anything that doesn't match an
+ explicite rule. well, you know what i mean (. matches anything not
+ yet matched). However, this means that there is input still queued
+ up so we need to do a YY_NEW_FILE; in yywrap. So, yywrap has moved
+ into parse.lex and it calls parser_cleanup() which is most of the
+ old yywrap() sigh.
+ [7f4042bc48d6]
+
+ * SUPPORTED:
+ no longer used
+ [8f220be4da94]
+
+ * getcwd.c, getwd.c:
+ moved compat.h to be the last include file
+ [9f3a65e2d485]
+
+ * parse.yacc:
+ fixed type of aliascmp() args
+ [1c27eb989bdf]
+
+ * find_path.c:
+ NULL -> '\0'
+ [5c8d8cf1692e]
+
+ * parse.yacc:
+ added casts to lfind and lsearch args for irix
+ [61027ddeecf8]
+
+ * Makefile.in:
+ bsdinstall -> install-sh
+ [61de6612c5a5]
+
+ * INSTALL:
+ added info about make realclean
+ [29c6324d727f]
+
+ * Makefile.in:
+ updated VERSION added dependencies for visudo.cat
+ [09077d7229d4]
+
+ * version.h:
+ -> pl5b1
+ [5d21c7ad1a41]
+
+ * sudo.c:
+ took out -l
+ [fc1478d81b38]
+
+ * Makefile.in:
+ now there is a real visudo.man and visudo.cat
+ [58aeac43a6dd]
+
+ * sudo.man:
+ took out visudo stuff
+ [4a6ac4393343]
+
+ * visudo.man:
+ Initial revision
+ [cba348843db8]
+
+ * parse.c, parse.lex, parse.yacc:
+ updated copyright
+ [ffa16b70944a]
+
+ * README:
+ updated for pl5
+ [a26e423e9e5f]
+
+ * sudo.man:
+ updated Nieusma & Hieb email addresses
+ [f0083e71989d]
+
+ * INSTALL:
+ updated to include options.h and OPTIONS
+ [ee59e2b76c94]
+
+ * CHANGES, TODO:
+ updated
+ [51e011ad5220]
+
+ * BUGS:
+ eliminated bug #1 (yay)
+ [e7e88515494e]
+
+ * configure.in:
+ sunos no longer gets linked statically
+ [2e5b3ff3108f]
+
+1995-03-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.lex:
+ prototype now uses __P()
+ [68ecdcab4c70]
+
+ * parse.lex:
+ make fill() non-ansi
+ [d6509972260b]
+
+ * parse.c:
+ made -v (validate) work
+ [13c9d520638c]
+
+ * logging.c:
+ now gives host
+ [f04859cdba5a]
+
+ * find_path.c:
+ don't check for execute/statable if fq or relative path given
+ [4bbe851f3973]
+
+ * parse.c:
+ added a cast
+ [345c308f72f3]
+
+ * visudo.c:
+ now include ctype.h for islower and tolower macros
+ [582c0aa332d5]
+
+ * goodpath.c:
+ moved _S_IFMT & _S_ISREG to compat.h
+ [828e4ca4e7b4]
+
+ * sudo.c:
+ moved a set of parens
+ [5783474ecf37]
+
+ * strdup.c:
+ now include compat.h
+ [75e2036b94af]
+
+ * emul/search.h:
+ void * -> VOID *
+ [cedcfaf04161]
+
+ * parse.yacc:
+ now cast malloc & realloc return vals added search for HAVE_LSEARCH
+ now use strcmp if no strcasecmp available
+ [d6a42bc3d4ae]
+
+ * lsearch.c:
+ void * -> VOID *
+ [886adc44f607]
+
+ * config.h.in:
+ removed HAVE_FLEX added VOID added HAVE_DIRENT_H, HAVE_SYS_NDIR_H,
+ HAVE_SYS_DIR_H, HAVE_NDIR_H added HAVE_LSEARCH
+ [3b50d7fb4349]
+
+ * compat.h:
+ added _S_IFMT, _S_IFREG, and S_ISREG
+ [73d506c7d53c]
+
+ * aclocal.m4:
+ took out SUDO_PROG_INSTALL 1.x to 2.x changes added echo and results
+ to most SUDO_* macros
+ [8442155f5936]
+
+ * Makefile.in:
+ no more -I.
+ [63462f195bd4]
+
+ * configure.in:
+ various 1.x ro 2.x autoconf changes now check for strcasecmp now use
+ AC_INSTALL_PROG instead of custom one added check for fully woorking
+ void implementation
+ [5ac6b6e6230f]
+
+ * Makefile.in:
+ added lsearch & search.h visudo links into $(LIBOBJS)
+ [bc119cda4598]
+
+ * aclocal.m4:
+ partial 1.x to 2.x changes added SUDO_FULL_VOID
+ [1194d01fa5c5]
+
+ * visudo.c:
+ whatnow_help was prototyped to be static be was not declared as such
+ [0f85489dd426]
+
+ * configure.in:
+ autoconf 2.x changes took out HAVE_FLEX (no longer used) added check
+ for dirent/dir/ndir.h
+ [7408f3854948]
+
+ * parse.c:
+ now use groovy gnu autoconf macro AC_HEADER_DIRENT
+ [e465db9f5dfa]
+
+ * getcwd.c, getwd.c:
+ MAXPATHLEN -> MAXPATHLEN+1
+ [714d87424e21]
+
+ * emul/search.h, lsearch.c:
+ Initial revision
+ [55d79482c535]
+
+1995-03-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ eliminated bison warnings
+ [61ca0a96da22]
+
+ * parse.lex:
+ added missing case
+ [6be0f849747c]
+
+ * visudo.c:
+ now iincludes signal.h
+ [221e0fcc144f]
+
+ * parse.yacc:
+ only clear data structures on a parse error
+ [7b1c0f1a4527]
+
+ * visudo.c:
+ whatnow() now gives help on invalid input
+ [e5a4cd88c587]
+
+ * visudo.c:
+ added a whatnow() function (sort of like mh)
+ [932d9b145f1c]
+
+ * parse.yacc:
+ kill_aliases -> reset_aliases yywrap() now cleans up by calling
+ reset_aliases() and clearing top took reset stuff out of yyerror()
+ since it doesn't beling there (and doesn't work anyway). errorlineno
+ is now initially set to -1 so we can set it to the first error that
+ occurrs (it was getting set to the last)
+ [2f71f95a974c]
+
+ * parse.lex:
+ added a void cast
+ [18ae6042dce4]
+
+ * visudo.c:
+ rewrote from scratch based on 4.3BSD vipw.c
+ [2f6814f18576]
+
+1995-03-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c, sudo.h:
+ removed ocmnd
+ [a31735f41ad4]
+
+ * sudo.h:
+ no more sudo_realpath() and find_path() changed params
+ [8e85c3b39159]
+
+ * sudo.c:
+ find_path() changed since no more realpath()
+ [b25366c7f2ee]
+
+ * parse.yacc:
+ on error, errorlineno is set to the line where the error occurred
+ added kill_aliases() to free the aliases struct now clean up in
+ yyerror() so we can reparse cleanly
+ [2342f578c27a]
+
+ * options.h, parse.c:
+ no more USE_REALPATH
+ [cfc59babeaff]
+
+ * logging.c:
+ changed to use new find_path()
+ [91c7a38e7751]
+
+ * find_path.c:
+ removed all the realpath() stuff
+ [cc21a43a8562]
+
+ * Makefile.in:
+ sudo_realpath.c -> sudo_goodpath.c
+ [03a9b1ddec2f]
+
+ * visudo.c:
+ now works correctly with utk parser
+ [08aa554a0ce8]
+
+ * goodpath.c:
+ Initial revision
+ [1ea607e1ffb2]
+
+ * sudo_realpath.c:
+ eliminated a compiler warning
+ [198bcccc55b6]
+
+ * sudo.c:
+ elinated compiler warning
+ [e2384f9a878b]
+
+ * sudo_realpath.c:
+ added sudo_goodpath()
+ [43878c4cc540]
+
+ * sudo.h:
+ added prototype for sudo_goodpath
+ [23e8627a2265]
+
+ * parse.c:
+ added support for /sys/dir.h
+ [eca897087741]
+
+ * options.h:
+ USE_REALPATH turned off
+ [620ac8b63d85]
+
+ * find_path.c:
+ added calls to sudo_goodpath()
+ [ad170904fbcd]
+
+ * configure.in:
+ added check for dirent.h
+ [7964a8c26855]
+
+ * config.h.in:
+ added HAVE_DIRENT_H
+ [1f785fec7e19]
+
+ * configure.in:
+ added in linux shadow pass stuff 
+ [e585a5785f50]
+
+1995-03-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ added back host, user, cmnd, parse_error
+ [0ec19f3d64f4]
+
+ * visudo.c:
+ added in utk changes plus some minor cosmetic changes
+ [c5c1921c8a58]
+
+ * sudo.c, sudo_realpath.c:
+ added void casts for printf's
+ [9c6ff11c0082]
+
+ * options.h:
+ added a define of USE_REALPATH
+ [db3711c9efc5]
+
+ * configure.in:
+ there is no more visudoers/Makefile
+ [36e1bc1f78d0]
+
+ * Makefile.in:
+ added in utk changes (visudo is now built from the toplevel)
+ [76203d4b345d]
+
+ * find_path.c:
+ added (void) casts to printf's
+ [dd5cb1e060ac]
+
+ * parse.c, parse.lex, parse.yacc, sudo.h, sudo_realpath.c:
+ merged in utk changes
+ [35563307fd8e]
+
+1995-03-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * find_path.c:
+ now check to see that what we are trying to run is a file (or a link
+ to a file, we do a stat(2) so there is no diff)
+ [05889c4bcace]
+
+1995-03-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ updated
+ [3e8047bb26fb]
+
+ * Makefile.in:
+ aclocal.m4 -> acsite.m4 make realclean updated for new autoconf 
+ [0bdbaa7c4c7d]
+
+ * sudo.man:
+ added myself as maintainer
+ [77a9d75aab84]
+
+1995-02-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ changed setegid -> setgid
+ [7f4788d73b6f]
+
+1995-02-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ fixed the test for irix 5.x to skip bad libs
+ [bfef896de013]
+
+ * aclocal.m4:
+ now initialize OS and OSREV
+ [cc302756e440]
+
+1995-01-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ irix5 changes
+ [ac985b23f5f2]
+
+ * configure.in:
+ AC_WITH -> AC_ARG_WITH changes other misc changes for autoconf 2.1
+ compatibility
+ [0cf8c92a06d7]
+
+1995-01-19 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ use YY_NEW_FILE, not yyrestart since OSF flex doesn't do the righ
+ thing wrt yyrestart (grrrr)
+ [18e8eabfbb82]
+
+1995-01-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ added visudoers/compat.h to DISTFILES
+ [db23b574b034]
+
+ * configure.in:
+ fixed an echo
+ [7cbc0462b89d]
+
+ * sudo.c:
+ added ocmnd declaration adjusted for find_path()'s new parameters
+ [d929cd156474]
+
+ * sudo.h:
+ added ocmnd extern adjusted find_path() prototype
+ [e0004daf5d3c]
+
+ * parse.c:
+ cmndcmp() now takes 3 arguments and checks against the qualified as
+ well as the unqualified pathname. more code that should use
+ cmndcmp() but did not, now does
+ [6f70a8c17bee]
+
+ * options.h:
+ added to a comment
+ [7a78680426b2]
+
+ * logging.c:
+ changed to use new find_path() parameter passing
+ [840981d30db4]
+
+ * find_path.c:
+ find_path() now takes 2 copyout parameters (one for the qualified
+ pathname and one for the unqualified pathname). The third parameter
+ may be NULL.
+ [851503b005e9]
+
+ * configure.in:
+ no longer munge pathnames.h
+ [427d8796c5a9]
+
+ * pathnames.h.in:
+ changed _PATH_* to use _SUDO_PATH_* (which are defined in config.h)
+ as a result, pathnames.h does not need to be run through configure
+ and the user can override the configured values easily.
+ [2e378f2ebe88]
+
+ * config.h.in:
+ added _SUDO_PATH_* entries
+ [0857de7cebab]
+
+ * aclocal.m4:
+ _PATH* -> _SUDO_PATH_*
+ [7601193f56cc]
+
+ * Makefile.in:
+ updated DISTFILES and HDRS .o's now depend on config.h
+ [39d8601965cf]
+
+1995-01-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * compat.h:
+ removed extraneous #endif
+ [27d4c5f2ce7e]
+
+ * aclocal.m4:
+ added SUDO_PROG_MV
+ [76dda3bdd816]
+
+ * configure.in:
+ added SUDO_PROG_MV added riscos and isc os types took out
+ -DSHORT_MESSAGE from --with-csops since it is now the default
+ [68c206ad976e]
+
+ * sudo.c:
+ move the include of id.h to compat.h now includes options.h
+ [45a1eaafb3a8]
+
+ * sudo.h:
+ moved compatibility #defines to compat.h
+ [0eee27057698]
+
+ * pathnames.h.in:
+ added _PATH_MV
+ [e830797ab320]
+
+ * config.h.in:
+ move __P to compat.h
+ [188e12e0ba93]
+
+ * getcwd.c, getwd.c, putenv.c:
+ now includes compat.h
+ [c72cb6d73981]
+
+ * compat.h:
+ Initial revision
+ [d4d2f359ae03]
+
+1995-01-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.h:
+ pull user-configurable stuff out and put in options.h
+ [ef929467b070]
+
+1995-01-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.lex, parse.yacc, visudo.c:
+ now includes options.h
+ [e36d7c82add1]
+
+ * check.c, find_path.c, logging.c, parse.c, sudo_realpath.c,
+ sudo_setenv.c:
+ now includes options.h
+ [f186ba03de07]
+
+ * Makefile.in:
+ added visudoers/options.h
+ [e5350c476494]
+
+ * OPTIONS, options.h:
+ Initial revision
+ [9b6b5001e318]
+
+ * Makefile.in:
+ added OPTIONS and options.h
+ [25448341e16a]
+
+ * logging.c:
+ changed #ifdef's to use LOGGING and SLOG_SYSLOG/SLOG_FILE
+ [5dd6385dd1d3]
+
+ * check.c, sudo.h:
+ changed PASSWORD_TIMEOUT to minutes
+ [0ec6aab98738]
+
+1994-12-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ now only do Editor +line_num if line_num != 0
+ [b69f04b5e3c7]
+
+1994-12-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ now use mv if rename(2) fails
+ [83210dca1bab]
+
+ * BUGS:
+ added a visudo bug
+ [d61a806f9aa7]
+
+ * check.c:
+ expanded comment
+ [641f2cba94cb]
+
+1994-11-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ fixed user_is_exempt to return 0 if EXEMPTGROUP is not set
+ [7a11135039a8]
+
+1994-11-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ added mips & isc support
+ [e258dc053119]
+
+ * parse.c:
+ added support for non-root owned sudoers file
+ [fea07e65a0fc]
+
+ * check.c:
+ added exempt group support
+ [928fb4bd9ad5]
+
+ * sudo.h:
+ added set_perms() support added SUDOERS_OWNER so can have non-root
+ own sudoers file added exempt group support added isc support
+ [61c578d31fc1]
+
+ * visudo.c:
+ now copy sudoers to temp file via read/write (not stdio) now chown
+ new sudoers file to SUDOERS_OWNER
+ [a5176c59df70]
+
+1994-11-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ added skey support
+ [35a8d2fabdb7]
+
+ * sudo_realpath.c:
+ be_* -> setperms()
+ [a1631d686e1c]
+
+ * sudo.h:
+ fixed typo added set_perms support added skey support added
+ seteuid()/setegid() emulation for AIX
+ [c0c8d6771406]
+
+ * sudo.c:
+ be_* -> setperms() now check to make sure sudoers file is owned by
+ root nread/write by only root
+ [13ab1e261f1a]
+
+ * logging.c, parse.c:
+ be_* -> setperms()
+ [21499d845c8f]
+
+ * check.c:
+ be_* -> set_perms() added skey support
+ [df51b56871c1]
+
+1994-11-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ ++version
+ [3c1abbe4e43c]
+
+ * version.h:
+ ++
+ [1d2f9b540a95]
+
+1994-10-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ now sets IFS
+ [eabbb41b9f08]
+
+ * insults.h:
+ fixed typo
+ [c7997f19216e]
+
+1994-10-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ added HAVE_SKEY
+ [da948ec4186b]
+
+1994-10-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ updated
+ [f4b55ab007ea]
+
+ * Makefile.in:
+ ++version
+ [0489068b8c95]
+
+ * version.h:
+ ++
+ [d189faedf423]
+
+ * sudo.c:
+ now bail if ARgv[1] > MAXPATHLEN
+ [0cea8ecc9dc2]
+
+ * configure.in:
+ added function check for tcgetattr(3)
+ [e03289b22c2f]
+
+ * config.h.in:
+ only define HAVE_TERMIOS_H if you have tcgetattr(3)
+ [757eab83d1a2]
+
+ * config.h.in:
+ added check for tcgetattr
+ [c5ae92715930]
+
+1994-09-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ updated
+ [cbc419883108]
+
+1994-09-22 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.lex:
+ now only include unistd.h for linux
+ [e9adeab95ef0]
+
+1994-09-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ added visudo.8 generation
+ [d6a3f0f887f8]
+
+ * configure.in:
+ added -Wl,-bI:./aixcrypt.exp to aix flags
+ [72594a21edcf]
+
+1994-09-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS:
+ added one
+ [9993a349e096]
+
+ * CHANGES:
+ updated
+ [297b31ec4cdd]
+
+ * README:
+ added mailing list info
+ [10372f94a2b2]
+
+ * parse.yacc:
+ now use sudolineno instead of yylineno fixed bison warnings
+ [25a83e62057b]
+
+ * configure.in:
+ now use -no_library_replacement for osf don't make a static binary
+ for hpux >= 9.0
+ [1fa7b892f1a3]
+
+ * tgetpass.c:
+ added string.h/strings.h inclusion
+ [71faa98fc0a1]
+
+ * config.h.in:
+ added ssize_t def
+ [406284bd1ac0]
+
+ * parse.lex:
+ added inclusion of string.h/strings.h
+ [6985b1df5d09]
+
+ * aclocal.m4:
+ fixed uname | sed (needed to quote the '[')
+ [4cd2d3415c1a]
+
+ * parse.lex:
+ replaced yylineno with sudolineno fixed bison syntax errors
+ [0bd31a5fab26]
+
+ * visudo.c:
+ changed yylineno to sudolineno since yylineno cannot be counted
+ upon.
+ [38c30104d0ae]
+
+ * TODO:
+ updated
+ [5d4746f1a752]
+
+ * parse.c:
+ added code to support command listings
+ [030172e133fd]
+
+ * sudo.c:
+ added code for -l flag
+ [801dbbc82778]
+
+ * sudo.man:
+ fixed typo added info for -l flag
+ [8916ca945d65]
+
+ * configure.in:
+ AC_SSIZE_T -> SUDO_SSIZE_T
+ [c61f7f47013f]
+
+ * aclocal.m4:
+ added SUDO_SSIZE_T
+ [0ccdb77be84d]
+
+ * sudo.h:
+ added MODE_LIST
+ [9b2bd844c76c]
+
+ * configure.in:
+ added AC_SSIZE_T
+ [35cca208f9b5]
+
+ * find_path.c, sudo_realpath.c:
+ readlink() is now declared as returning ssize~_t
+ [0640a08d1407]
+
+ * configure.in:
+ added -laud for OSF c2
+ [b7539c905efc]
+
+1994-09-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, visudo.c:
+ changed sudo-bugs.cs.colorado.edu -> sudo-bugs@cs.colorado.edu
+ [067fd9bcb5e1]
+
+ * config.h.in, parse.lex, parse.yacc, pathnames.h.in:
+ changed sudo-bugs.cs.colorado.edu -> sudo-bugs@cs.colorado.edu
+ [fc46e7c7110a]
+
+ * check.c, find_path.c, getcwd.c, getwd.c, insults.h, logging.c,
+ parse.c, putenv.c, strdup.c, sudo.c, sudo.h, sudo_realpath.c,
+ sudo_setenv.c, tgetpass.c, version.h:
+ changed sudo-bugs.cs.colorado.edu -> sudo-bugs@cs.colorado.ed
+ [d1d4fbc53a98]
+
+1994-09-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in:
+ ++version
+ [b7066d97633f]
+
+ * version.h:
+ ++
+ [65ec69d88110]
+
+ * logging.c:
+ added host to alertmail messages
+ [d973c19ce777]
+
+ * CHANGES, TODO:
+ udpated
+ [5a65eb16faeb]
+
+ * logging.c:
+ fixed logging problem where mail would not say which user it was
+ [35723edcc5d2]
+
+ * configure.in:
+ added -laud for gcc if osf & c2
+ [18f1e0ae5548]
+
+ * check.c:
+ moved set_auth_parameters to sudo.c
+ [d23112fe01db]
+
+ * sudo.c:
+ added set_auth_parameters for osf
+ [eb70f65214ac]
+
+ * configure.in:
+ cleaned up -static stuff
+ [01e9575f0422]
+
+ * Makefile.in:
+ ++version
+ [7ac3bff5c770]
+
+ * version.h:
+ ++
+ [10a4ff478469]
+
+ * sudo.c:
+ changed setenv() to sudo_setenv()
+ [40a78abb9946]
+
+ * check.c:
+ fixed osf problem
+ [3d69b118efb8]
+
+ * configure.in:
+ added OSF C2 stuff
+ [38cff3ad4093]
+
+ * CHANGES:
+ updated
+ [cd341dd0581a]
+
+ * check.c:
+ added osf auth support & removed some extra spaces
+ [a448cdd81514]
+
+ * INSTALL, SUPPORTED:
+ added osf C2 stuff
+ [f70484796146]
+
+1994-08-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TODO:
+ added 2 suggestions
+ [695fbdbd86e6]
+
+ * Makefile.in:
+ removed README.v1.3.1 and added VERSION stuff
+ [f69403eb04c6]
+
+ * version.h:
+ pl1
+ [21580c0f8cb1]
+
+1994-08-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * version.h:
+ 1.3.1final
+ [630114970298]
+
+ * Makefile.in:
+ added HISTORY
+ [901bff251614]
+
+ * sudo.man:
+ mention HISTPRY file
+ [86dbcfd4326e]
+
+ * sudo.c:
+ use sizeof instead of a constant in 1 place
+ [d819604c68ca]
+
+ * parse.yacc:
+ added unistd.h
+ [6f9500f9fe7e]
+
+ * parse.lex:
+ added unistd.h
+ [468b81a276eb]
+
+ * README:
+ udpated
+ [7e275618923a]
+
+ * HISTORY:
+ Initial revision
+ [5db1b0a3939b]
+
+1994-08-17 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * version.h:
+ ++
+ [7dfbb4a810bb] [SUDO_1_3_1]
+
+ * CHANGES:
+ updated
+ [7820ee610bf8]
+
+ * sudo_setenv.c:
+ added unistd.h include
+ [30cf2b654525]
+
+1994-08-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ added sys/time.h for AIX
+ [199fc8caf3a3]
+
+1994-08-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ added check for -lsocket and sys/sockio.h
+ [f9abfbb31031]
+
+ * config.h.in:
+ took out libshadow check and added in sys/sockio.h check
+ [0c4b0393ac80]
+
+ * sudo.c:
+ now include sockio.h instead of ioctl.h if it exists "sudo -" now
+ gets a better error message
+ [53041bea5483]
+
+ * sample.sudoers:
+ now has a dir and subnet entry
+ [56b820f65438]
+
+1994-08-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ removed if_ether.h
+ [b4f64507493e]
+
+ * TODO:
+ added an item
+ [ea2a1bb6922a]
+
+ * sudo.man:
+ added network and ip addresses to man page
+ [01c85016511f]
+
+ * sudo.c:
+ no error if can't get interfaces or netmask since networking may not
+ be in the kernel.
+ [50b8890e2134]
+
+ * parse.c:
+ nwo check for interfaces == NULL
+ [dc1b3eef0db2]
+
+ * parse.c:
+ fixed a bug that caused directory specs in a Cmnd_Alias to fail if
+ the last entry in the spec failed (ie: it was only looking at the
+ last entry). CLeaned things up by adding the cmndcmp() function--all
+ neat & tidy
+ [007e93578e5e]
+
+ * CHANGES:
+ added one
+ [40e8a2cef497]
+
+1994-08-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ now do two passes to skip bogus interfaces (lo0, etc)
+ [465e30aecaf7]
+
+ * parse.lex, parse.yacc, visudo.c:
+ added include of netinet/in.h
+ [11e3816ed362]
+
+ * logging.c, sudo_realpath.c, sudo_setenv.c:
+ added ninclude of netinet/in.h
+ [daccfa40fe1e]
+
+ * check.c, find_path.c, getcwd.c, getwd.c:
+ added include of netinet/in.h
+ [0222f95e06ad]
+
+ * version.h:
+ ++
+ [d6b0cfa35a38]
+
+ * sudo.h:
+ added interfaces global
+ [ba52fa8ad75e]
+
+ * parse.c:
+ now uses new interfaces global
+ [17473ad5ecba]
+
+ * sudo.c:
+ now ip addresses are gleaned fw/o dns
+ [8828bb2007e0]
+
+1994-08-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ added load_ip_addrs() to load the ip_addrs global var
+ [60c825f04238]
+
+ * parse.c:
+ added hostcmp() to compare hostnames, ip addrs, and network addrs
+ [ab0e40e37537]
+
+ * sudo.h:
+ added ip_addrs def added load_ip_addrs prototype
+ [c41c565d0777]
+
+1994-08-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ updated
+ [2a128dbe9bcb]
+
+ * Makefile.in:
+ removed multiple entries in DISTFILES
+ [2490f4f371e6]
+
+ * visudo.c:
+ ansified the !STDC_HEADERS decls
+ [646ba06d17ae]
+
+ * find_path.c, getcwd.c, getwd.c, putenv.c, strdup.c:
+ don't do malloc decl if gnuc
+ [f1bad1925f98]
+
+ * sudo.c:
+ can't use getopt(3) since it munges args to the command to be run as
+ root don't do malloc decl if gnuc
+ [38e78f6da14e]
+
+ * find_path.c, getcwd.c, getwd.c, putenv.c, strdup.c, sudo.c,
+ sudo_realpath.c, sudo_setenv.c:
+ ansi-fied !STDC_HEADER function prottypes
+ [51d8cad89976]
+
+ * getcwd.c, getwd.c:
+ added missing paren
+ [6a1fae70e27e]
+
+ * Makefile.in:
+ added putenv.c to DISTFILES
+ [a5e4523eabbb]
+
+ * sudo_setenv.c:
+ added params to func decls when STDC_HEADERS is not defined now can
+ count on putenv() being there
+ [fd587796189b]
+
+ * sudo_realpath.c:
+ took out errno decl since sudo.h does it for us fixed up a next cc
+ warning added params to func decls when STDC_HEADERS is not defined
+ [70fa5152ace6]
+
+ * sudo.h:
+ took out environ extern added local declaratio of putenv() if local
+ version is needed
+ [a84bae6c020d]
+
+ * find_path.c, getcwd.c, getwd.c, strdup.c, sudo.c:
+ added params to func decls when STDC_HEADERS is not defined
+ [f406f0e47ac0]
+
+ * config.h.in:
+ added memcpy check check to see that ansi vs bsd macros are ntot
+ already defiend before defining (ie: avoid redefinition)
+ [879ae026e19f]
+
+ * configure.in:
+ removed fluff setenv check plus check w/ replace for putenv if also
+ no setenv
+ [e3c03814ad4b]
+
+ * putenv.c:
+ Initial revision
+ [3cff63e2dc1b]
+
+1994-08-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo_setenv.c:
+ Initial revision
+ [4d637631fa6b]
+
+ * sudo.h:
+ rm'd s realp[ath added sudo_realpath and sudo_setenv
+ [07ba001ff57e]
+
+ * sudo.c:
+ now use sudo_setenvc
+ [fd81e04d5ef0]
+
+ * configure.in:
+ added puteenv and setenv, removed realpath
+ [27bfacfb513b]
+
+ * config.h.in:
+ added putenv & setenv
+ [515f14eaf6e4]
+
+ * Makefile.in:
+ added sudo_setenv
+ [217731a717c5]
+
+ * version.h:
+ ++
+ [eadb346d7129]
+
+1994-08-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ added MAN_POSTINSTALL and /usr/share/catman for irix
+ [2a9496c1bdba]
+
+ * Makefile.in:
+ added MAN_POSTINSTALL
+ [89b0d4695529]
+
+ * CHANGES:
+ added
+ [48c021ba8a70]
+
+ * sudo.man:
+ added SUDO_* plus new options
+ [c0759cff5683]
+
+ * CHANGES:
+ added one
+ [7d44a3922d56]
+
+ * configure.in:
+ took out shadow lib
+ [07cf3de18701]
+
+ * TODO:
+ adde done
+ [a27a578e8afe]
+
+ * visudo.c:
+ now use yyrestart() if flex now reset yylineno to 0
+ [77d67ce0b677]
+
+ * Makefile.in:
+ support for installing a cat page instead of a man page if no nroff
+ [44671c0fc0fa]
+
+ * configure.in:
+ now defines HAVE_FLEX fixed up man stuff so that it looks for nroff
+ to determine whether or not to install a cat or man page
+ [0562d069c135]
+
+ * config.h.in:
+ added HAVE_FLEX
+ [c5490bae39d3]
+
+ * sudo.c:
+ not set ret to MODE_RUN initially
+ [88b4983c195b]
+
+ * find_path.c:
+ made command (and therefor cmnd dynamically allocated)
+ [95b82e32b6de]
+
+ * TODO:
+ did #8
+ [fb6f41308cdf]
+
+ * version.h:
+ ++
+ [14112ecab5ae]
+
+ * sudo_realpath.c:
+ changed bufs from MAXPATHLEN to MAXPATHLEN+1
+ [0ad4f34e55c0]
+
+ * sudo.h:
+ added MODE_ removed validate_only and added remove_timestamp()
+ [dd5f99c57728]
+
+ * sudo.c:
+ usage() now takes an int (exit value) added parse_args() to parse
+ command line arguments moved call to find_path() from load_globals
+ to new function load_cmnd() removed validate_only global -- now use
+ the concept of "modes" added -h and -k options
+ [c3887090b28a]
+
+ * parse.c:
+ no longer use global validate_only now checks for command called
+ "validate" removed check for non-fully qualified commands since that
+ is done by find_path
+ [7d56fbd26369]
+
+ * find_path.c:
+ changed MAXPATHLEN r to MAXPATHLEN+1
+ [a86e8664d971]
+
+ * find_path.c:
+ fixed off by one error with MAXPATHLEN and fixed a comment
+ [58adcef8c981]
+
+ * check.c:
+ check_timestamp no longer runs reminder(), it is implied in the
+ return val added remove_timestamp()
+ [42ab5a77066f]
+
+ * CHANGES:
+ updated
+ [8e69b31df024]
+
+1994-08-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS:
+ fixed on
+ [bc34f1ac4280]
+
+ * sudo_realpath.c:
+ took out old_errno
+ [a168d00a0768]
+
+ * CHANGES:
+ updated
+ [04ba80922df7]
+
+1994-08-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ moved send_mail to after syslog
+ [4d4188087834]
+
+ * sudo.c:
+ now set SUDO_ envariables
+ [e5963f1bd3bb]
+
+1994-08-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * version.h:
+ ++
+ [2a4534845d8c]
+
+ * sudo_realpath.c:
+ now print error if chdir fails
+ [0d75c8973d49]
+
+ * find_path.c:
+ removed an XXX
+ [e2077bcb35aa]
+
+1994-07-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ updated
+ [e30a2b39b41a]
+
+ * configure.in:
+ no more static binaries for aix
+ [77a0beb6bd80]
+
+1994-07-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ fixed typo
+ [ba5e0d391bc4]
+
+ * sudo_realpath.c:
+ took out stuff not needed for sudo now does be_root/be_user itself
+ now uses cwd global
+ [4f6d4641d793]
+
+ * version.h:
+ +=2
+ [97da927b297c]
+
+ * logging.c, sudo.c:
+ be_root/be_user is now down in sudo_realpath()
+ [f331662fa50f]
+
+ * logging.c, sudo.h:
+ now works with 4.2BSD syslog (blech)
+ [98e39d89dd36]
+
+ * find_path.c:
+ now use sudo_realpath()
+ [ab436a8ebd02]
+
+ * config.h.in:
+ took out realpth() stuff since we now use sudo_realpath()
+ [8de5ef9f6044]
+
+ * configure.in:
+ ultrix enhanced sec
+ [815fb7fffcc0]
+
+ * SUPPORTED:
+ added ultrix enhanced sec.
+ [6466766c8062]
+
+ * INSTALL:
+ updated
+ [d681a634297a]
+
+ * check.c:
+ ultrix enhanced security suport
+ [f10c8decbcc2]
+
+ * Makefile.in:
+ added sudo_realpath.c
+ [6b9bcd3be022]
+
+ * CHANGES:
+ updated
+ [2fa8084c1b53]
+
+ * tgetpass.c:
+ increased passwd len to 24 for c2 security
+ [ec64838be62d]
+
+ * BUGS:
+ updated BUGS
+ [ca00d8fec2ce]
+
+1994-07-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ now use user global var
+ [568769719013]
+
+ * configure.in:
+ took out -ls
+ [490a44180d5f]
+
+1994-07-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ added AFS libs
+ [4fb40c8c01ba]
+
+ * sudo.h:
+ user is now a char * added epasswd
+ [27a919fafdfb]
+
+ * sudo.c:
+ added tzset() to load_globals added epasswd (encrypted password)
+ global made user dynamically allocated
+ [b99ef9bdbfce]
+
+ * configure.in:
+ added tzset test
+ [27592dd1214b]
+
+ * config.h.in:
+ added HAVE_TZSET
+ [b13f4213f3d0]
+
+ * check.c:
+ cleaned up encrypted passwd grab somewhat
+ [c8ba9a4db38a]
+
+ * configure.in:
+ fixed AFS typo
+ [2bfcbce237b6]
+
+ * INSTALL:
+ added AFS not
+ [80c67329393c]
+
+ * CHANGES:
+ udpated
+ [2f09ecdd5d31]
+
+ * logging.c:
+ can now log to both syslog & a file
+ [4d5c0932bc01]
+
+ * sudo.h:
+ added BOTH_LOGS
+ [623c539be824]
+
+ * CHANGES:
+ updated
+ [a1c7f5ef3616]
+
+ * configure.in:
+ --with-AFS
+ [28718d8f5daf]
+
+ * config.h.in:
+ added HAVE_AFS
+ [2e32bb4e63e4]
+
+ * check.c:
+ added afs changes
+ [fe4d0ff320a2]
+
+ * sudo.h:
+ removed AFS stuff :-)
+ [a40387e6fa27]
+
+ * tgetpass.c:
+ include sys/select for AIX
+ [f32c5a8f2c84]
+
+ * sudo.h:
+ added AFS
+ [da2ab3dd0348]
+
+ * version.h:
+ ++
+ [452d4dfe25af]
+
+1994-07-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES, SUPPORTED:
+ updated
+ [e7dfe6f23a37]
+
+ * logging.c:
+ can now have MAILER undefined
+ [1d33b98b35e1]
+
+ * INSTALL:
+ new sub-note about MAILER
+ [d35c636a0574]
+
+ * sudo.man:
+ added blurb about password timeout
+ [70c2ee50de20]
+
+ * configure.in:
+ convex c2 changes
+ [367138a6232e]
+
+ * aclocal.m4:
+ took out duplicate define of _CONVEX_SOURCE
+ [647182138450]
+
+ * Makefile.in:
+ added OSDEFS
+ [7fdcd50602d1]
+
+ * config.h.in:
+ added spaces
+ [f2b8a05e48f3]
+
+ * tgetpass.c:
+ added a goto if fgets fails
+ [68a6586d9c45]
+
+ * sudo.h:
+ use __hpux not hpux convex c2 stuff
+ [5c377a8d5f34]
+
+ * sudo.c:
+ use __hpux not hpux
+ [9363bc0f9f9e]
+
+ * logging.c:
+ convex c2 stuff
+ [ea5630975ac4]
+
+ * config.h.in:
+ define ansi-ish cpp os defines if non-ansi are defined for hpux &
+ convex
+ [664f53a5e786]
+
+ * INSTALL:
+ updated to say we support sonvex C2
+ [5f2f8b87013e]
+
+ * check.c:
+ added convex c2 support
+ [9a665d4918fa]
+
+1994-07-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ no more ioctl never returns NULL uses fgets() and select() to
+ timeout
+ [b333e6d63e97]
+
+1994-06-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ things were testing -n "$GCC" instead of -z "$GCC"
+ [059a9b15ede2]
+
+ * tgetpass.c:
+ now works + uses fgets()
+ [353d7ebcb7bb]
+
+1994-06-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ select doesn't seem to recognize a single '\n' as input waiting so
+ we can;t use it, sigh.
+ [f76e3218b835]
+
+1994-06-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * PORTING:
+ updated tgetpass() blurb
+ [95baac736b49]
+
+ * configure.in:
+ added --with-getpass
+ [42ac0bdf58ed]
+
+ * Makefile.in:
+ added tgetpass stuff
+ [e2b38c635663]
+
+ * tgetpass.c:
+ now uses stdio
+ [36af8ff66e35]
+
+ * version.h:
+ ++
+ [4e81c9db19bd]
+
+1994-06-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * PORTING:
+ updated ,.
+ [54f523770a05]
+
+ * config.h.in:
+ added USE_GETPASS && HAVE_C2_SECURITY
+ [86b355cb2953]
+
+ * configure.in:
+ fixed a test aded --with-C2 and --with-tgetpass
+ [abf6181588ef]
+
+ * check.c:
+ added hpux C2 shit
+ [20d4177ffa88]
+
+ * Makefile.in:
+ took out tgetpass.*
+ [cc82fd9984b4]
+
+ * INSTALL:
+ added C2 blurb
+ [1d2bfc35e4b6]
+
+1994-06-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ no termio(s) for ultrix since it is broken
+ [d3e82e835350]
+
+ * check.c:
+ added a space (yeah, anal)
+ [05e4b31ca68c]
+
+ * realpath.c, sudo_realpath.c:
+ fixed it (duh, rtfm)
+ [f13097cb8cb6]
+
+1994-06-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ took out bsd signal stuff for irix
+ [e179cdafc97a]
+
+ * visudo.c:
+ comments in #endif
+ [e3a629190f5e]
+
+ * configure.in:
+ don't define BSD signals for irix
+ [3ce57bffb7f0]
+
+ * TODO:
+ did some...
+ [274241cd0f74]
+
+ * CHANGES:
+ updated
+ [8f29fc755faf]
+
+ * realpath.c, sudo_realpath.c:
+ took out unneeded code by changing where a strings was terminated
+ [b5564d62d30e]
+
+1994-06-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * realpath.c, sudo_realpath.c:
+ fix bug where /dirname would return NULL
+ [b85f470daf26]
+
+ * sudo.h:
+ move __P to config.h
+ [7763c0ff3f28]
+
+ * getcwd.c, getwd.c, realpath.c, sudo_realpath.c:
+ added errno definition
+ [4cc9d2d9782a]
+
+ * config.h.in:
+ added __P
+ [ca06f5aa58f3]
+
+ * config.h.in:
+ added HAVE_FCHDIR
+ [206d714641e0]
+
+ * strdup.c:
+ now include stdio
+ [0d8458da0e1d]
+
+ * realpath.c, sudo_realpath.c:
+ now works if no fchdir
+ [e035911b6722]
+
+ * visudo.c:
+ define SA_RESETHAND to null if not defined
+ [afec03e84342]
+
+ * configure.in:
+ added check & replace
+ [c1a65481441c]
+
+ * configure.in:
+ took out -static for nextstep -- it doesn't work
+ [fa1a1a611743]
+
+1994-06-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ moved #endif to where it belongs
+ [07d3a8972097]
+
+ * SUPPORTED:
+ correction
+ [0c1ecba3e5a3]
+
+ * configure.in:
+ now checks for strdup realpath getcwd bzero
+ [f029a1917515]
+
+ * config.h.in:
+ emulate bzero
+ [d792352e44a3]
+
+ * visudo.c:
+ added posic signals
+ [2ed0005f90fc]
+
+ * tgetpass.c:
+ bzero cast
+ [6d91b1a1526f]
+
+ * logging.c:
+ added posix signals
+ [67ede9c22a05]
+
+ * configure.in:
+ removed BROKEN_GETPASS added new srcs toreplace missing functions
+ [cf44274bb1c8]
+
+ * config.h.in:
+ added posix signal stuff
+ [a3c1c98fe8ef]
+
+ * Makefile.in:
+ added new srcs
+ [b6a079afee47]
+
+ * visudo.c:
+ updated useag
+ [589ed091c44f]
+
+ * tgetpass.c:
+ now uses posix signals
+ [30f74964074f]
+
+ * PORTING:
+ updated sto reflect major changes
+ [bcfc309e017b]
+
+ * CHANGES, TODO:
+ updated
+ [23aacbd54278]
+
+ * tgetpass.c:
+ uses sysconf() if available
+ [a27431c90bab]
+
+ * sudo.h:
+ added PASSWORD_TIMEOUT + prototypes for new functions
+ [d7473c2f77c4]
+
+ * realpath.c, sudo_realpath.c:
+ for those w/o this in libc
+ [1e47aa7a9d46]
+
+ * getcwd.c, getwd.c:
+ Initial revision
+ [c90dea57a84f]
+
+ * find_path.c:
+ rewrote to use realpath(3) - nis now all my code
+ [d2c3bb8fb37d]
+
+ * config.h.in:
+ added HAVE_REALPATH
+ [02c10352a8c7]
+
+ * check.c:
+ now use tgetpass
+ [b5c021fc179f]
+
+ * Makefile.in:
+ added LIBOBJS use tgetpass.c
+ [230a7b3eeaa3]
+
+1994-06-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * tgetpass.c:
+ works now :-)
+ [025e7a3875ba]
+
+ * tgetpass.c:
+ Initial revision
+ [3316ab33b230]
+
+ * pathnames.h.in:
+ added /dev/tty
+ [29242585e53f]
+
+1994-06-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * version.h:
+ incremented
+ [f2e54b48280f]
+
+ * sudo.c:
+ always use getcwd
+ [c6068e8a4029]
+
+ * config.h.in:
+ added check for getwd
+ [ab1e102ad673]
+
+ * configure.in:
+ replace strdup & realpath & getcwd if missing
+ [b0eb14f2a1c3]
+
+ * pathnames.h.in:
+ added _PATH_PWD
+ [309d2388f69a]
+
+ * aclocal.m4:
+ added SUDO_PROG_PWD
+ [e16e85deb96c]
+
+ * strdup.c:
+ Initial revision
+ [810efdc15007]
+
+ * realpath.c, sudo_realpath.c:
+ Initial revision
+ [d85eee438e09]
+
+1994-06-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ quoted quare brackets
+ [d0e7ca111d98]
+
+1994-06-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ no need to strdup() a constant
+ [a8c44712df9a]
+
+ * CHANGES:
+ updated
+ [71364129cca0]
+
+ * sudo.man:
+ added validate
+ [0bb198095a26]
+
+ * sudo.c:
+ added -v to usage
+ [31ea71f11dbb]
+
+ * parse.c, sudo.c, sudo.h:
+ added validate_only stuff
+ [9bcd853d3c90]
+
+1994-05-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ now finds sed
+ [6374bb0d3f28]
+
+ * aclocal.m4:
+ $OSREV is now an int
+ [ace0666d66cf]
+
+1994-05-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ added mtxinu to caser
+ [73a776887b16]
+
+ * sudo.h:
+ added EXEC macro
+ [2e8eb28b710a]
+
+ * sudo.c:
+ now use the EXEC nmacro now only do a gethostbyname() if FQDN is set
+ [56afb4f658d5]
+
+ * logging.c:
+ changed mail_argv[] def now use EXEC() macro
+ [ddcabd28edb1]
+
+ * check.c:
+ took out crypt() definition
+ [0e657724cf5f]
+
+ * version.h:
+ upped the version
+ [62c5d66119fc]
+
+ * configure.in:
+ always look for -lnsl
+ [d7b594f0313b]
+
+ * aclocal.m4:
+ added an echo
+ [1caae3491dc5]
+
+ * sudo.h:
+ SHORT_MESSAGE is now the default
+ [cfce35c3119a]
+
+ * config.h.in:
+ fixed typo
+ [6499a564bf75]
+
+ * configure.in:
+ added missing AC_DEFINE(SVR4) for solaris
+ [feef0b17b94f]
+
+ * sudo.man:
+ documented the -v flag
+ [a6429f2bc2cf]
+
+ * SUPPORTED:
+ updated
+ [088886e79540]
+
+ * check.c:
+ proto-ized crypt()
+ [801e4ff5b121]
+
+ * config.h.in:
+ added LIBSHADOW undef
+ [8df588e9ee2b]
+
+ * configure.in:
+ nwo set OS to be lowercase
+ [561ebed833e4]
+
+1994-05-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ now use SUDO_OSTYPE to set $OS
+ [0e60aee23098]
+
+ * aclocal.m4:
+ now use uname to determine os
+ [99705e58d400]
+
+ * visudo.c:
+ added prototypes & moved sig handler around
+ [1f0bc8d23b51]
+
+ * sudo.h:
+ added prototyppes
+ [be3935a2b163]
+
+ * check.c, logging.c, sudo.c:
+ added prototypes
+ [2079b4605ab8]
+
+ * parse.c:
+ added comment
+ [a34d147d8399]
+
+ * config.h.in:
+ nwo use _BSD_SIGNALS not _BSD_COMPAT
+ [63663195f047]
+
+ * aixcrypt.exp:
+ Initial revision
+ [890aed08357e]
+
+ * Makefile.in:
+ added aixcrypt.exp
+ [1005a183105f]
+
+ * parse.lex, parse.yacc:
+ moved config.h to top of includes
+ [9569c49aa5f3]
+
+1994-05-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * find_path.c:
+ now don't bitch if get EACCESS (treat like EPERM)
+ [dbeffb638de4]
+
+ * visudo.c:
+ added -v flag and usage()
+ [4d44ed60ed75]
+
+ * version.h:
+ fixed a typo
+ [cf3f9347ae41]
+
+ * sudo.c:
+ cast Argv to a const for exec added -v flag
+ [d11b6efc0e45]
+
+ * logging.c:
+ mail_argv is now a const
+ [93bb5d90bb6f]
+
+ * configure.in:
+ only set RETSIGTYPE if it is not set already
+ [c97aac260b77]
+
+ * aclocal.m4:
+ now defines & STDC_HEADERS for Irix
+ [9c2b24ad1fc5]
+
+ * Makefile.in:
+ added version.h
+ [9f79e880229a]
+
+ * insults.h, sudo.h:
+ prevent multiple inclusion
+ [d68c8a9243ce]
+
+ * version.h:
+ Initial revision
+ [dbb39c5ef8d9]
+
+ * parse.lex, parse.yacc:
+ now includes config.h
+ [f117e036a56b]
+
+ * aclocal.m4:
+ now talks about sunos 4.x
+ [c9054aa92d4e]
+
+ * visudo.c:
+ calls to Exit now pass an arg
+ [a92104670551]
+
+1994-05-24 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ signal handler now takes an int argument
+ [26f480c41523]
+
+ * CHANGES:
+ updated
+ [8c166a9d796b]
+
+ * sudo.c:
+ ok, the getcwd() is now *really* done as the user
+ [ab86cf85134a]
+
+ * configure.in:
+ changed AIX STATIC_FLAGS
+ [b9c0a3ba5663]
+
+ * aclocal.m4:
+ solaris now defines SVR4
+ [c3e20cac96f5]
+
+ * sudo.h:
+ added cwd and fixed stupid core dump that makes no sense. sigh.
+ [7a9755436dbb]
+
+ * sudo.c:
+ moved getcwd stuff into load_globals
+ [ec2bc90df1f3]
+
+ * parse.c:
+ took out externs that are in suod.h
+ [93c4b3f856d7]
+
+ * logging.c:
+ moved cwd into load_globals
+ [050de754d228]
+
+ * find_path.c:
+ moved cwd stuff
+ [22f3f3b4c34d]
+
+ * Makefile.in:
+ fixed make distclean & realclean
+ [c9964d89bcef]
+
+ * TODO:
+ updated .,
+ [e513581ef0e3]
+
+ * CHANGES:
+ added solaris changes
+ [505d930daf27]
+
+ * aclocal.m4:
+ added solaris changes, need to rework
+ [33f20fb16c49]
+
+ * configure.in:
+ cleaned up for solaris
+ [2fb8cfa05d0f]
+
+ * logging.c:
+ reinstall reapchild signal handler for non-bsd signals
+ [3d1dc545113d]
+
+ * sudo.h:
+ took out getdtablesize() emulation for HP-UX (no longer needed)
+ [1fc83d170f34]
+
+ * sudo.c:
+ support for HAVE_SYSCONF
+ [50ca2a7a224a]
+
+ * visudo.c:
+ added <fcntl.h> for solaris & reorg'd the includes + minor prettying
+ up /
+ [0a570e826dd4]
+
+ * config.h.in:
+ added HAVE_SYSCONF
+ [2b9a9f3a4e94]
+
+1994-05-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ now tells you what os you are running /.
+ [06c6332a895b]
+
+ * aclocal.m4:
+ took out extra ','
+ [e8c75ce59f4a]
+
+1994-05-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * config.h.in:
+ added _BSD_COMPAT
+ [73c5099806c2]
+
+ * aclocal.m4:
+ fixed for irix5
+ [1047d1f6c0eb]
+
+ * CHANGES:
+ updated
+ [1bc4969fee96]
+
+ * sudo.c:
+ uid seinitialized to -2
+ [8d7812b1878b]
+
+1994-04-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ now removes LIBPATH for AIX
+ [075392eb1dd9]
+
+1994-03-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * configure.in:
+ now uses ufc if it finds it
+ [ab6ce30a5958]
+
+1994-03-12 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.h:
+ no longer define yyval & yylval since yacc does it
+ [09d250aea50a]
+
+ * parse.lex:
+ now defines yylval as extenr
+ [8ec2b88952bc]
+
+ * configure.in:
+ BROKEN_GETPASS is now an OPTION
+ [3714f4bb8312]
+
+ * config.h.in:
+ took out BROKEN_GETPASS
+ [9c4f6aa50137]
+
+ * Makefile.in:
+ took out big comment
+ [4c13cff0e556]
+
+ * README:
+ updated
+ [b8b9902b620d]
+
+ * Makefile.in:
+ took out README.beta
+ [ed2cd861e82b]
+
+ * SUPPORTED:
+ Initial revision
+ [2fffc51e6606]
+
+ * INSTALL:
+ now reference SUPPORTED .,
+ [d112c30be1f2]
+
+ * config.h.in:
+ now check for convex OR __convex__
+ [a0e5701a3069]
+
+ * aclocal.m4:
+ now check for convex or __convex__
+ [5dae2bfbe3bc]
+
+ * Makefile.in:
+ added dist target
+ [400a54de57db]
+
+ * aclocal.m4:
+ use __convex__
+ [58a19470ed0b]
+
+ * find_path.c:
+ now use _S_* stat stuff to be ansi-like
+ [28cce560e048]
+
+ * INSTALL:
+ updated for configure directions
+ [a034ccc7c30a]
+
+ * Makefile.in:
+ distclean now removes config.h and pathnames.h
+ [300f2349b4ab]
+
+ * CHANGES:
+ updated
+ [646f7e9430c1]
+
+ * TODO:
+ fixed typoe
+ [70fd6361b2bc]
+
+ * visudo.c:
+ updated version
+ [cf13d87d789f]
+
+ * Makefile.in:
+ updated version
+ [8c5dacc27a7a]
+
+ * config.h.in, pathnames.h.in:
+ added copyright header
+ [747ce3d3d6b7]
+
+ * check.c, find_path.c, insults.h, logging.c, parse.c, parse.lex,
+ parse.yacc, sudo.c, sudo.h:
+ udpated version
+ [4751c39bad18]
+
+ * visudo.c:
+ udpated to use configure + pathnames.h
+ [d45dff76a1cd]
+
+ * aclocal.m4:
+ updated
+ [f05a367a55be]
+
+ * Makefile.in, config.h.in, configure.in:
+ updated
+ [524778598879]
+
+ * sudo.h:
+ now works with configure
+ [83fc40e533f4]
+
+ * check.c, find_path.c, getpass.c, logging.c, parse.c, sudo.c:
+ updated to work with configure + pathnames.h
+ [cb67fa6ab52d]
+
+ * Makefile.in:
+ added LEXLIB
+ [f43cad4ab0a2]
+
+1994-03-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * COPYING:
+ updated gnu general licence to versio 2
+ [2b0b56112ddc]
+
+ * config.h.in, pathnames.h.in:
+ Initial revision
+ [4b586f39ec2d]
+
+ * sudo.h:
+ changed to work with configure
+ [13f3506ddf16]
+
+1994-03-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * Makefile.in, aclocal.m4, configure.in:
+ Initial revision
+ [a8636ae77371]
+
+ * visudo.c:
+ now uses defines used by configure
+ [de438d118993]
+
+1994-03-01 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * find_path.c:
+ sudo won't bitch about EPERM now, for real
+ [ce26d9ef7e3f]
+
+1994-02-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * logging.c:
+ renamed exec_argv to eliminate a libc name clash with ksros
+ [bcb4350d8411]
+
+ * CHANGES:
+ corrected
+ [dae68d422efd]
+
+ * logging.c, sudo.c, sudo.h:
+ execve -> execv
+ [40cc2c4bdb15]
+
+ * TODO:
+ upated
+ [9275a8b8fc45]
+
+ * PORTING:
+ added 2 mroe items
+ [6cbb5c56993c]
+
+ * CHANGES:
+ updated
+ [73f34f8e571a]
+
+ * sudo.h:
+ added UMASK and mode_t declaration
+ [7c2015e1d171]
+
+ * sudo.c:
+ added UMASK
+ [d37be7523680]
+
+ * logging.c:
+ now opens log file with mode 077
+ [0825cc3ee841]
+
+ * check.c:
+ saved current umask ans restores it
+ [659c1aaae8e8]
+
+ * sudo.h:
+ added MAXLOGFILELEN
+ [34331c7dee90]
+
+ * logging.c:
+ split long log lines. FOr syslog, split into multiple entries, for a
+ log file, indent the extra for readability
+ [72c9e4cdba6e]
+
+1994-02-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ added changes
+ [81196833673d]
+
+ * sudo.h:
+ MAXLOGLEN & MAXSYSLOGLEN are now different (as they should be)
+ [1aa69e903840]
+
+1994-02-25 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TODO:
+ added input from Brett M Hogden <hogden@rge.com>
+ [80f01fc88ce9]
+
+1994-02-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ added rmenv() to remove stuff from environ. can now uses execvp() OR
+ execve() becuase of this.
+ [e7fc2535bd67]
+
+ * logging.c:
+ now uses execvp() OR execve()
+ [56391aa1f99d]
+
+ * sudo.h:
+ added USE_EXECVE
+ [f21f38050b95]
+
+ * sudo.h:
+ added environ
+ [6b805e23c6f6]
+
+ * find_path.c:
+ now ignore EPERM
+ [c8fd7117a1d7]
+
+ * sudo.h:
+ moved some func decls out of sudo.h and into sudo.c as statics /.
+ [5f555c267d27]
+
+ * CHANGES:
+ updated
+ [431f478af320]
+
+ * sudo.h:
+ took out Envp
+ [6f722be7793d]
+
+1994-02-14 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * BUGS:
+ Initial revision
+ [4a8ecf0da95c]
+
+1994-02-10 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ added SECURE_PATH
+ [1c72cb222609]
+
+ * sudo.c, sudo.h:
+ added SECURE_PATH
+ [5bf5357a63c5]
+
+ * sudo.h:
+ added SECURE_PATH
+ [3976a74405ac]
+
+ * INSTALL:
+ added sample.sudoers note
+ [1b395d29aaeb]
+
+ * sudoers:
+ Initial revision
+ [485888d07477]
+
+1994-02-09 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * find_path.c:
+ fixed typo
+ [bfc3cc4d41ca]
+
+ * PORTING:
+ took out SAVED_UID garbage
+ [b7c2d3469661] [SUDO_1_3_0]
+
+ * INSTALL:
+ mentioned HAL
+ [253d6695df90]
+
+ * sudo.h:
+ added HAL line
+ [29ec1a4ac6de]
+
+ * insults.h:
+ added HAL insults
+ [7d7c96d77c74]
+
+ * TODO:
+ updated
+ [aa2ed9790586]
+
+ * logging.c:
+ more verbose error if mailer not found
+ [fca47fd00cb6]
+
+ * check.c:
+ now do getpwent as root for soem shadow password systems (bsdi)
+ [e0339e110d46]
+
+1994-02-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.h:
+ took out SAVED_UID garbade
+ [fcb0e81dcdb5]
+
+ * sudo.c:
+ took out SAVED_UID garbage since it don't work
+ [507e9513e9c2]
+
+1994-02-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * README:
+ updated
+ [d2b6b253dae5]
+
+ * insults.h:
+ added a missing space :-)
+ [8940ea991f87]
+
+ * sudo.c, sudo.h:
+ took out multimax cruft
+ [c2606b365181]
+
+ * INSTALL:
+ minor update
+ [05fb6ee73131]
+
+ * PORTING:
+ finished
+ [c4ac47c84dc5]
+
+ * sudo.c:
+ fixed a typo + indentation
+ [7eab40aae8fa]
+
+1994-02-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.h:
+ took outumoved some defines to the config file ,. ,.
+ [defff05beb52]
+
+ * PORTING:
+ Initial revision
+ [c803e9127959]
+
+ * TODO:
+ did #6
+ [c6fa1c946c31]
+
+ * sudo.h:
+ added HAS_SAVED_UID
+ [6a88a39c0a07]
+
+ * sudo.c:
+ put back AIX cruft
+ [a24d2507ddd4]
+
+1994-02-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ aix changes
+ [1663915f754a]
+
+1994-02-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * CHANGES:
+ updated
+ [a8cc73747cae]
+
+ * check.c, logging.c, parse.c, sudo.c, sudo.h:
+ now is only root when abs necesary
+ [3c9d12c5cdfe]
+
+ * check.c:
+ added missing %s\n
+ [609320b72d89]
+
+1994-01-31 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * install-sh:
+ Initial revision
+ [b5bba140a175]
+
+ * TODO:
+ updated
+ [c9d2eba602af]
+
+ * CHANGES:
+ updated
+ [932f1fc3bb14]
+
+ * sudo.c:
+ now removed _RLD_* for alphas
+ [54a36e648158]
+
+ * INSTALL:
+ updated for new config scheme
+ [61c8ae800444]
+
+ * find_path.c:
+ more verbose eror messages
+ [b4fd123db42d]
+
+1994-01-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * TODO:
+ now have solaris
+ [371002fbf266]
+
+ * sudo.h:
+ define __svr4__ for SOLARIS
+ [0b5cf5ed936d]
+
+ * check.c:
+ added svr4 junk for shadow pws for solaris 2.x
+ [91ed58f21618]
+
+ * check.c, sudo.c:
+ took out setuid(0) and setreuid(udi) garbage. Its not needed since
+ we start out setuid with the correct perms.
+ [07689e782b0b]
+
+ * check.c, sudo.c, sudo.h:
+ now use setreuid()
+ [7d64d685d78e]
+
+1994-01-26 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.man:
+ revised AUTHORS secrtion & added ENV_EDITOR stuff to VARIABLES
+ sectoin
+ [b26967b1e19b]
+
+ * visudo.c:
+ now uses ENV_EDITOR if you want to use the EDITOR envar
+ [a4f8fcb9bd1d]
+
+ * sudo.h:
+ now uses ENV_EDITOR if you want to use the EDITOR envar >> .
+ [028cc55c4328]
+
+1993-12-07 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * INSTALL:
+ rewrote most of this
+ [a6750923f9c9]
+
+ * README:
+ minor update + spell fix
+ [a411717a7249]
+
+ * sudo.h:
+ added all options that are in the Makefile
+ [6db3b3b841b3]
+
+ * getpass.c:
+ now use USE_TERMIO #define for sgi & hpux
+ [b91f89ae6be1]
+
+ * TODO:
+ todo: posix sigs
+ [4548a56eb2ef]
+
+1993-12-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c, find_path.c:
+ always include strings.h
+ [1fc20bda92c0]
+
+ * visudo.c:
+ added STATICEDITOR
+ [0596f820716e]
+
+ * sudo.h:
+ sgi has vi in /usr/bin too
+ [94203b62bfd9]
+
+ * sudo.man:
+ added VISUAL
+ [87c2844c4cac]
+
+1993-12-03 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.h:
+ sue /usr/bin/vi on some systems
+ [e3ad9190f35e]
+
+ * sudo.c:
+ fixed warning (include strings.h)
+ [0b896de4d8a0]
+
+ * sudo.man:
+ added John_Rouillard@dl5000.bc.edu's changes (new features)
+ [f41b4205a8cf]
+
+ * CHANGES:
+ changes from John_Rouillard@dl5000.bc.edu
+ [6bdef8e948d5]
+
+ * visudo.c:
+ added EDITOR envar
+ [5c4bf716de21]
+
+ * check.c, find_path.c, parse.c, sudo.c:
+ added patches from John_Rouillard directory spec uses EDITOR
+ [f62a435f8c41]
+
+1993-12-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * getpass.c:
+ added flush for hpux
+ [07cfdd6a7b55]
+
+1993-11-30 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ no longer assume malloc returns a char *
+ [7480bd2756f3]
+
+ * sudo.c:
+ alpha change to remove LD_-like thing fixed SHLIB_PATH stuff -- now
+ gets removed correctly
+ [8587166c6ac8]
+
+ * sudo.h:
+ added STD_HEADERS macro
+ [480f5a9a516c]
+
+ * sudo.c:
+ now uses STD_HEADERS macor for ansi
+ [c5018806fd59]
+
+ * find_path.c:
+ now uses STD_HEADERS macro
+ [ad821e0788ea]
+
+ * check.c:
+ niceties for C compiler bitches -- no real change
+ [0fc0b1a5fb64]
+
+1993-11-29 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ now doesn't fclose a file never opened.
+ [ee888ec9427d]
+
+1993-11-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.man:
+ added visudo line
+ [698d51c66407]
+
+ * sudo.man:
+ added error stuff added me in there...
+ [d202fd34b906]
+
+ * CHANGES:
+ noted insults
+ [998a22c2230c]
+
+ * INSTALL:
+ added blurb about reading stuff
+ [e71db100798f]
+
+ * sudo.h:
+ added insults
+ [c110431cec56]
+
+ * insults.h:
+ corrected somments and removed newlines
+ [493706fd488c]
+
+ * check.c:
+ now uses insults
+ [6d23cf06a0ef]
+
+ * insults.h:
+ Initial revision
+ [83153c26b4a3]
+
+ * INSTALL:
+ added dec syslog note
+ [555437273237]
+
+ * sample.sudoers:
+ added real stuff in there
+ [53442a7fba78]
+
+ * TODO:
+ added a todo
+ [c630472bd4dc]
+
+ * TODO:
+ added one
+ [806464453284]
+
+1993-11-27 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sample.sudoers:
+ Initial revision
+ [7db0a9f1ca8f]
+
+ * sudo.man:
+ updated with changes
+ [d9bf254c6c08]
+
+ * sudo.man:
+ Initial revision
+ [dd6f11174ac6]
+
+ * indent.pro:
+ Initial revision
+ [dbfbb494fad9]
+
+ * CHANGES, COPYING, INSTALL, README, TODO:
+ Initial revision
+ [6d98f489a079]
+
+ * visudo.c:
+ updated version number and took out jeff's old addr since it is no
+ good
+ [ee47c24818cb]
+
+ * check.c, find_path.c, logging.c, parse.c, parse.lex, parse.yacc,
+ sudo.c, sudo.h:
+ updated version number and took out jeff's email (since it is
+ invalid)
+ [54616458a52e]
+
+1993-10-28 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ added fflush()
+ [145c881f4fb4]
+
+1993-10-23 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * find_path.c:
+ now return NULL instead pfof exiting for nopnn-fatal errors
+ [8bc74f8cb1ae]
+
+1993-10-21 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * check.c:
+ new banner
+ [5387ab2af516]
+
+ * parse.lex:
+ now sudo.h gets included first
+ [2acb01c18e18]
+
+1993-10-18 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.lex:
+ now can use flex
+ [164d3839adf0]
+
+ * sudo.h:
+ linux patch
+ [f1b6b1b1a2ca]
+
+ * sudo.c:
+ hpux 9 fix, removes SHLIB_PATH linux patch
+ [67611dc1737f]
+
+ * check.c:
+ linux diff
+ [c24536682397]
+
+1993-10-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * find_path.c:
+ stat now ignores EINVAL
+ [c7761a5dc642]
+
+1993-10-06 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * find_path.c, sudo.c:
+ now declare strdup as extern
+ [6b7d6f8784b5]
+
+1993-10-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * visudo.c:
+ reformatted with indent + by hand
+ [9d43084e4990]
+
+ * check.c, find_path.c, getpass.c, logging.c, parse.c, sudo.c, sudo.h:
+ used indent to "fix" coding style
+ [489ffacbdc70]
+
+ * find_path.c:
+ now checks '.' or '.' or '' in PATH -- but does it LAST should maybe
+ move the code that does this into the loop body. makes it messier
+ tho. hmmm.
+ [c4d22b48da9a]
+
+1993-09-08 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * find_path.c:
+ redid the fix for non-executable files in an easier to read way plus
+ some minor aethetic changes
+ [84fe337f1426]
+
+ * find_path.c:
+ fixed bug with non-executable tings of same name in path introduced
+ by checkig errno after stat(2).
+ [c2a812cfcbc1]
+
+1993-09-05 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ fixed off by one error
+ [fabb7cee0041]
+
+ * find_path.c:
+ now handles decending below '/' correctly
+ [5d2ddfc0b220]
+
+ * sudo.c:
+ now actually builds Envp instead of munging envp
+ [bdc4b08f6898]
+
+1993-09-04 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * parse.yacc:
+ now includes sys/param.h
+ [efbb494ab4de]
+
+ * visudo.c:
+ now includes sys/param.h
+ [ad6c91d59958]
+
+ * sudo.h:
+ fixed ifndef -> ifdef
+ [7aebe822d863]
+
+ * qualify.c:
+ make more like find_path.c
+ [853b2dab2e03]
+
+ * find_path.c:
+ rewritten by millert
+ [c6a043cc11b3]
+
+ * sudo.h:
+ fixed MAXCOMMANDLENGTH now uses USE_CWD and NEED_STRDUP added info
+ about new defines in the comment
+ [39ffefce3aec]
+
+ * logging.c:
+ now uses USE_CWD
+ [fa0f3b118bb3]
+
+ * sudo.h:
+ added delc for clean_envp() and Envp
+ [a12034e300c2]
+
+ * sudo.c:
+ now rips LD_* env vars out of envp and passed sanitized Envp to exec
+ [d201a218e056]
+
+ * logging.c:
+ now uses execve()
+ [f3e01032cd33]
+
+ * find_path.c:
+ ENOTDIR is ok now too (in case part of the path is bogus)
+ [b5cbbb201bb5]
+
+ * qualify.c:
+ now works correctly (ttaltotal rewrite)
+ [0c25d64a5c68]
+
+ * parse.lex:
+ now includes sys/param.h didn't match trailing / -- fix from
+ rouilj@cs.umb.edu
+ [b6363ba110af]
+
+1993-06-11 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ moved around the #ifndef _AIX
+ [7d4330950c20]
+
+ * check.c, logging.c, parse.c:
+ Initial revision
+ [c101e9572d7f]
+
+1993-03-20 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * qualify.c:
+ Initial revision
+ [5a5f21d0e0bf]
+
+1993-03-13 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * find_path.c:
+ now works if you do sudo bin/test
+ [07835120ce43]
+
+ * find_path.c:
+ works
+ [c3da8b5efa20]
+
+1993-03-02 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.h:
+ Initial revision
+ [28a1caa38b72]
+
+ * visudo.c:
+ Initial revision
+ [0e5cd7c3cdbe]
+
+ * parse.lex, parse.yacc:
+ Initial revision
+ [5f2d0cccb06b]
+
+1993-02-16 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * sudo.c:
+ took out errno.h
+ [7466431a2655]
+
+ * sudo.c:
+ now spews error if exec fails and exits with -1
+ [e5c41ea725c1]
+
+ * sudo.c:
+ Initial revision
+ [8aeabe39a0c2]
+
+ * find_path.c:
+ now only execs files with (an) executable bit set.
+ [0a451f9c0e58]
+
+ * find_path.c:
+ Initial revision
+ [02a534891a35]
+
+1993-02-15 Todd C. Miller <Todd.Miller@courtesan.com>
+
+ * getpass.c:
+ added nice comment
+ [ea8b2aaa9389]
+
+ * getpass.c:
+ now works on sgi's
+ [bf2b7c6d0960]
+
+ * getpass.c:
+ Initial revision
+ [9f4de251c1b5]
+
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..b8f9be6
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,937 @@
+Sudo installation instructions
+==============================
+
+Sudo uses a `configure' script to probe the capabilities and type
+of the system in question. In this release, `configure' takes many
+more options than it did before. Please read this document fully
+before configuring and building sudo. You may also wish to read the
+file INSTALL.configure which explains more about the `configure' script.
+
+System requirements
+===================
+
+To build sudo from the source distribution you need a POSIX-compliant
+operating system (any modern version of BSD, Linux or Unix should work),
+an ANSI/ISO C compiler that supports the "long long" type, variadic
+macros (a C99 feature) as well as the ar, make and ranlib utilities.
+
+If you wish to modify the parser then you will need flex version
+2.5.2 or later and either bison or byacc (sudo comes with a
+pre-generated parser). You'll also have to run configure with the
+--with-devel option or pass DEVEL=1 to make. You can get flex from
+http://flex.sourceforge.net/. You can get GNU bison from
+ftp://ftp.gnu.org/pub/gnu/bison/ or any GNU mirror.
+
+Simple sudo installation
+========================
+
+For most systems and configurations it is possible simply to:
+
+ 0) If you are upgrading from a previous version of sudo
+ please read the info in the UPGRADE file before proceeding.
+
+ 1) Read the `OS dependent notes' section for any particular
+ "gotchas" relating to your operating system.
+
+ 2) `cd' to the source or build directory and type `./configure'
+ to generate a Makefile and config.h file suitable for building
+ sudo. Before you actually run configure you should read the
+ `Available configure options' section to see if there are
+ any special options you may want or need.
+
+ 4) Type `make' to compile sudo. If you are building sudo
+ in a separate build tree (apart from the sudo source) GNU
+ make will probably be required. If `configure' did its job
+ properly (and you have a supported configuration) there won't
+ be any problems. If this doesn't work, take a look at the
+ doc/TROUBLESHOOTING file for tips on what might have gone
+ wrong. Please mail us if you have a fix or if you are unable
+ to come up with a fix (address at EOF).
+
+ 5) Type `make install' (as root) to install sudo, visudo, the
+ man pages, and a skeleton sudoers file. Note that the install
+ will not overwrite an existing sudoers file. You can also
+ install various pieces the package via the install-binaries,
+ install-doc, and install-sudoers make targets.
+
+ 6) Edit the sudoers file with `visudo' as necessary for your
+ site. You will probably want to refer the example sudoers
+ file and sudoers man page included with the sudo package.
+
+ 7) If you want to use syslogd(8) to do the logging, you'll need
+ to update your /etc/syslog.conf file. See the example syslog.conf
+ file included in the distribution for an example.
+
+Available configure options
+===========================
+
+This section describes flags accepted by the sudo's `configure' script.
+Defaults are listed in brackets after the description.
+
+Configuration:
+ --cache-file=FILE
+ Cache test results in FILE
+
+ --config-cache, -C
+ Alias for `--cache-file=config.cache'
+
+ --help, -h
+ Print the usage/help info
+
+ --no-create, -n
+ Do not create output files
+
+ --quiet, --silent, -q
+ Do not print `checking...' messages
+
+ --srcdir=DIR
+ Find the sources in DIR [configure dir or `..']
+
+Directory and file names:
+ --prefix=PREFIX
+ Install architecture-independent files in PREFIX. [/usr/local]
+
+ --exec-prefix=EPREFIX
+ Install architecture-dependent files in EPREFIX.
+ This includes the executables and plugins. [same as PREFIX]
+
+ --bindir=DIR
+ Install `sudo', `sudoedit' and `sudoreplay' in DIR. [EPREFIX/bin]
+
+ --sbindir=DIR
+ Install `visudo' in DIR. [EPREFIX/sbin]
+
+ --libexecdir=DIR
+ Install plugins and helper programs in DIR/sudo [PREFIX/libexec/sudo]
+
+ --sysconfdir=DIR
+ Look for `sudo.conf' and `sudoers' files in DIR. [/etc]
+
+ --includedir=DIR
+ Install sudo_plugin.h include file in DIR [PREFIX/include]
+
+ --datarootdir=DIR
+ Root directory for platform-independent data files [PREFIX/share]
+
+ --localedir=DIR
+ Install sudo and sudoers locale files in DIR [DATAROOTDIR/locale]
+
+ --mandir=DIR
+ Install man pages in DIR [PREFIX/man]
+
+ --docdir=DIR
+ Install other sudo documentation in DIR [DATAROOTDIR/doc/sudo]
+
+ --with-exampledir=DIR
+ Install sudo example files in DIR [DATAROOTDIR/doc/sudo/examples]
+
+ --with-plugindir=DIR
+ The directory that sudo looks in to find the policy and I/O
+ logging plugins. Defaults to the LIBEXEC/sudo.
+
+ --with-rundir=DIR
+ The directory to be used for sudo-specific files that do
+ not survive a system reboot. This is typically where the
+ time stamp directory is located. By default, configure
+ will choose from the following list:
+ /run/sudo /var/run/sudo, /var/db/sudo, /var/lib/sudo,
+ /var/adm/sudo, /usr/adm/sudo
+ This directory should be cleared when the system reboots.
+ On systems that lack /run or /var/run, the default rundir and
+ vardir may be the same. In this case, only the ts directory
+ inside the rundir needs to be cleared at boot time.
+
+ --with-vardir=DIR
+ The directory to be used for sudo-specific files that survive
+ a system reboot. This is typically where the lecture status
+ directory is stored. By default, configure will choose
+ from the following list:
+ /var/db/sudo, /var/lib/sudo, /var/adm/sudo, /usr/adm/sudo
+ This directory should *not* be cleared when the system boots.
+
+ --with-tzdir=DIR
+ The directory to the system's time zone data files. This
+ is only used when sanitizing the TZ environment variable
+ to allow for fully-qualified paths in TZ. By default,
+ configure will look for an existing "zoneinfo" directory
+ in the following locations:
+ /usr/share /usr/share/lib /usr/lib /etc
+ If no zoneinfo directory is found, the TZ variable may not
+ contain a fully-qualified path.
+
+Compilation options:
+ --disable-hardening
+ Disable the use of compiler/linker exploit mitigation options
+ which are enabled by default. This includes compiling with
+ _FORTIFY_SOURCE defined to 2, building with -fstack-protector
+ and linking with -zrelro, where supported.
+
+ --enable-asan
+ Enable the use of AddressSanitizer if supported by the
+ compiler. This can help detect common problems such as
+ buffer overflows and user after free bugs as well as behavior
+ undefined by the C standard. For more information see
+ https://github.com/google/sanitizers/wiki/AddressSanitizer
+ The following compiler flag is used: -fsanitize=address,undefined
+
+ This option should only be used for testing and not in a
+ production environment. Due to AddressSanitizer's unchecked
+ use of environment variables, it is trivial to exploit a
+ setuid root executable such as sudo.
+
+ --enable-pie
+ Build sudo and related programs as as a position independent
+ executables (PIE). This improves the effectiveness of address
+ space layout randomization (ASLR) on systems that support it.
+ Sudo will create PIE binaries by default on Linux systems.
+
+ --disable-pie
+ Disable the creation of position independent executables (PIE),
+ even if the compiler creates PIE binaries by default. This
+ option may be needed on some Linux systems where PIE binaries
+ are not fully supported.
+
+ --disable-poll
+ Use select() instead of poll() in the event loop. By default,
+ sudo will use poll() on systems that support it. Some systems
+ have a broken poll() implementation and need to use select instead.
+ On Mac OS X, select() is always used since its poll() doesn't
+ support devices.
+
+ --disable-rpath
+ By default, configure will use -Rpath in addition to -Lpath
+ when passing library paths to the loader. This option will
+ disable the use of -Rpath.
+
+ --disable-shared
+ Disable dynamic shared object support. By default, sudo
+ is built with a plugin API capable of loading arbitrary
+ policy and I/O logging plugins. If the --disable-shared
+ option is specified, this support is disabled and the default
+ sudoers policy and I/O plugins are embedded in the sudo
+ binary itself. This will also disable the noexec option
+ as it too relies on dynamic shared object support.
+
+ --disable-shared-libutil
+ Disable the use of the dynamic libsudo_util library. By
+ default, sudo, the sudoers plugin and the associated sudo
+ utilities are linked against a shared version of libsudo_util.
+ If the --disable-shared-libutil option is specified, a
+ static version of the libsudo_util library will be used
+ instead. This option may only be used in conjunction with
+ the --enable-static-sudoers option.
+
+ --enable-static-sudoers
+ By default, the sudoers plugin is built and installed as a
+ dynamic shared object. When the --enable-static-sudoers
+ option is specified, the sudoers plugin is compiled directly
+ into the sudo binary. Unlike --disable-shared, this does
+ not prevent other plugins from being used and the noexec
+ option will continue to function.
+
+ --enable-tmpfiles.d=DIR
+ Set the directory to be used when installing the sudo
+ tmpfiles.d file. This is used to create (or clear) the
+ sudo time stamp directory on operating systems that use
+ systemd. If this option is not specified, configure will
+ use the /usr/lib/tmpfiles.d directory if the file
+ /usr/lib/tmpfiles.d/systemd.conf exists.
+
+ --enable-zlib[=location]
+ Enable the use of the zlib compress library when storing
+ I/O log files. If specified, location is the base directory
+ containing the zlib include and lib directories. The special
+ values "system", "builtin", "shared" and "static" can be
+ used to indicate that the system version of zlib should be
+ used or that the version of zlib shipped with sudo should
+ be used instead. If "static" is specified, sudo will
+ statically link the builtin zlib and not install it. If
+ this option is not specified, configure will use the system
+ zlib if it is present, falling back on the sudo version.
+
+ --with-incpath=DIR
+ Adds the specified directory (or directories) to CPPFLAGS
+ so configure and the compiler will look there for include
+ files. Multiple directories may be specified as long as
+ they are space separated.
+ E.g. --with-incpath="/usr/local/include /opt/include"
+
+ --with-libpath=DIR
+ Adds the specified directory (or directories) to LDFLAGS
+ so configure and the compiler will look there for libraries.
+ Multiple directories may be specified as with --with-incpath.
+
+ --with-libraries=LIBRARY
+ Adds the specified library (or libraries) to SUDO_LIBS and
+ and VISUDO_LIBS so sudo will link against them. If the
+ library doesn't start with `-l' or end in `.a' or `.o' a
+ `-l' will be pre-pended to it. Multiple libraries may be
+ specified as long as they are space separated.
+
+ --with-libtool=PATH
+ By default, sudo will use the included version of libtool
+ to build shared libraries. The --with-libtool option can
+ be used to specify a different version of libtool to use.
+ The special values "system" and "builtin" can be used in
+ place of a path to denote the default system libtool (obtained
+ via the user's PATH) and the default libtool that comes
+ with sudo.
+
+Optional features:
+ --disable-root-mailer
+ By default sudo will run the mailer as root when tattling
+ on a user so as to prevent that user from killing the mailer.
+ With this option, sudo will run the mailer as the invoking
+ user which some people consider to be safer.
+
+ --enable-nls[=location]
+ Enable natural language support using the gettext() family
+ of functions. If specified, location is the base directory
+ containing the libintl include and lib directories. If
+ this option is not specified, configure will look for the
+ gettext() family of functions in the standard C library
+ first, then check for a standalone libintl (linking with
+ libiconv as needed).
+
+ --disable-nls
+ Disable natural language support. By default, sudo will
+ use the gettext() family of functions, if available, to
+ implement messages in the invoking user's native language.
+ Note that translations do not exist for all languages.
+
+ --with-ldap[=DIR]
+ Enable LDAP support. If specified, DIR is the base directory
+ containing the LDAP include and lib directories. Please see
+ README.LDAP for more information.
+
+ --with-ldap-conf-file=PATH
+ Path to LDAP configuration file. If specified, sudo reads
+ this file instead of /etc/ldap.conf to locate the LDAP server.
+
+ --with-ldap-secret-file=PATH
+ Path to LDAP secret password file. If specified, sudo uses
+ this file instead of /etc/ldap.secret to read the secret password
+ when rootbinddn is specified in the ldap config file.
+
+ --disable-sasl
+ Disable SASL authentication for LDAP. By default, sudo
+ will compile in support for SASL authentication if the
+ ldap_sasl_interactive_bind_s() function is present in the
+ LDAP libraries.
+
+ --with-logincap
+ This adds support for login classes specified in /etc/login.conf.
+ It is enabled by default on BSD/OS, Darwin, FreeBSD, OpenBSD and
+ NetBSD (where available). By default, a login class is not applied
+ unless the 'use_loginclass' option is defined in sudoers or the user
+ specifies a class on the command line.
+
+ --with-interfaces=no, --without-interfaces
+ This option keeps sudo from trying to glean the ip address
+ from each attached Ethernet interface. It is only useful
+ on a machine where sudo's interface reading support does
+ not work, which may be the case on some SysV-based OS's
+ using STREAMS.
+
+ --with-noexec[=PATH]
+ Enable support for the "noexec" functionality which prevents
+ a dynamically-linked program being run by sudo from executing
+ another program (think shell escapes). Please see the
+ "PREVENTING SHELL ESCAPES" section in the sudoers man page
+ for details. If specified, PATH should be a fully qualified
+ path name, e.g. /usr/local/libexec/sudo/sudo_noexec.so. If PATH
+ is "no", noexec support will not be compiled in. The default
+ is to compile noexec support if libtool supports building
+ shared objects on your OS.
+
+ --with-selinux
+ Enable support for role based access control (RBAC) on
+ systems that support SELinux.
+
+ --with-sssd
+ Enable support for using the System Security Services Daemon
+ (SSSD) as a sudoers data source. For more information on
+ SSD, see http://fedorahosted.org/sssd/
+
+ --with-sssd-conf=PATH
+ Specify the path to the SSSD configuration file, if different
+ from the default value of /etc/sssd/sssd.conf.
+
+ --with-sssd-lib=PATH
+ Specify the path to the SSSD shared library, which is loaded
+ at run-time.
+
+ --enable-offensive-insults
+ Enable potentially offensive sudo insults from the classic
+ version of sudo.
+
+ --enable-pvs-studio
+ Generate a sample PVS-Studio.cfg file based on the compiler and
+ platform type. The "pvs-studio" Makefile target can then be
+ used if PVS-Studio is installed.
+
+Operating system-specific options:
+ --disable-setreuid
+ Disable use of the setreuid() function for operating systems
+ where it is broken. For instance, 4.4BSD has setreuid() that
+ is not fully functional.
+
+ --disable-setresuid
+ Disable use of the setresuid() function for operating systems
+ where it is broken (none currently known).
+
+ --enable-admin-flag
+ Enable the creation of an Ubuntu-style admin flag file
+ the first time sudo is run.
+
+ --enable-devsearch=PATH
+ Set a system-specific search path of directories to look in
+ for device nodes. Sudo uses this when mapping the process's
+ tty device number to a device name. The default value is:
+ /dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev
+
+ --with-bsm-audit
+ Enable support for sudo BSM audit logs on systems that support it.
+ This includes recent versions of FreeBSD, Mac OS X and Solaris.
+
+ --with-linux-audit
+ Enable audit support for Linux systems. Audits attempts
+ to run a command as well as SELinux role changes.
+
+ --with-man
+ Use the "man" macros for manual pages. By default, mdoc versions
+ of the manuals are installed if supported. This can be used to
+ override configure's test for "nroff -mdoc" support.
+
+ --with-mdoc
+ Use the "mdoc" macros for manual pages. By default, mdoc versions
+ of the manuals are installed if supported. This can be used to
+ override configure's test for "nroff -mdoc" support.
+
+ --with-netsvc[=PATH]
+ Path to netsvc.conf or "no" to disable netsvc.conf support.
+ If specified, sudo uses this file instead of /etc/netsvc.conf
+ on AIX systems. If netsvc support is disabled but LDAP is
+ enabled, sudo will check LDAP first, then the sudoers file.
+
+ --with-nsswitch[=PATH]
+ Path to nsswitch.conf or "no" to disable nsswitch support.
+ If specified, sudo uses this file instead of /etc/nsswitch.conf.
+ If nsswitch support is disabled but LDAP is enabled, sudo will
+ check LDAP first, then the sudoers file.
+
+ --with-project
+ Enable support for Solaris project resource limits.
+ This option is only available on Solaris 9 and above.
+
+Authentication options:
+ --with-AFS
+ Enable AFS support with Kerberos authentication. Should work under
+ AFS 3.3. If your AFS doesn't have -laudit you should be able to
+ link without it.
+
+ --with-aixauth
+ Enable support for the AIX general authentication function.
+ This will use the authentication scheme specified for the
+ user on the machine. By default, sudo will use either AIX
+ authentication or PAM depending on the value of the auth_type
+ setting in the /etc/security/login.cfg file.
+
+ --with-bsdauth
+ Enable support for BSD authentication. This is the default
+ for BSD/OS and OpenBSD systems that support it.
+ It is not possible to mix BSD authentication with other
+ authentication methods (and there really should be no need
+ to do so). Note that only the newer BSD authentication API
+ is supported. If you don't have /usr/include/bsd_auth.h
+ then you cannot use this.
+
+ --with-DCE
+ Enable DCE support for systems without PAM. Known to work on
+ HP-UX 9.X, 10.X, and 11.0; other systems may require source
+ code and/or `configure' changes. On systems with PAM support
+ (such as HP-UX 11.0 and higher, Solaris, FreeBSD and Linux), the
+ DCE PAM module (usually libpam_dce) should be used instead.
+
+ --with-fwtk[=DIR]
+ Enable TIS Firewall Toolkit (FWTK) 'authsrv' support. If specified,
+ DIR is the base directory containing the compiled FWTK package
+ (or at least the library and header files).
+
+ --with-kerb5[=DIR]
+ Enable Kerberos V support. If specified, DIR is the base
+ directory containing the Kerberos V include and lib dirs.
+ This uses Kerberos pass phrases for authentication but
+ does not use the Kerberos cookie scheme. Will not work for
+ Kerberos V older than version 1.1.
+
+ --enable-kerb5-instance=string
+ By default, the user name is used as the principal name
+ when authenticating via Kerberos V. If this option is
+ enabled, the specified instance string will be appended to
+ the user name (separated by a slash) when creating the
+ principal name.
+
+ --with-solaris-audit
+ Enable audit support for Solaris 11 and above.
+ For older versions of Solaris, use --with-bsm-audit
+
+ --with-opie[=DIR]
+ Enable NRL OPIE OTP (One Time Password) support. If specified,
+ DIR should contain include and lib directories with opie.h
+ and libopie.a respectively.
+
+ --with-otp-only
+ This option is now just an alias for --without-passwd.
+
+ --with-pam
+ Enable PAM support. This is on by default for Darwin, FreeBSD,
+ Linux, Solaris and HP-UX (version 11 and higher).
+
+ NOTE: on RedHat Linux and Fedora you *must* have an /etc/pam.d/sudo
+ file install. You may either use the example pam.conf file included
+ with sudo or use /etc/pam.d/su as a reference. The pam.conf file
+ included with sudo may or may not work with other Linux distributions.
+ On Solaris and HP-UX 11 systems you should check (and understand)
+ the contents of /etc/pam.conf. Do a "man pam.conf" for more
+ information and consider using the "debug" option, if available,
+ with your PAM libraries in /etc/pam.conf to obtain syslog output
+ for debugging purposes.
+
+ --with-pam-login
+ Enable a specific PAM session when sudo is given the -i option.
+ This changes the PAM service name when sudo is run with the -i
+ option from "sudo" to "sudo-i", allowing for a separate pam
+ configuration for sudo's initial login mode.
+
+ --disable-pam-session
+ Disable sudo's PAM session support. This may be needed on
+ older PAM implementations or on operating systems where
+ opening a PAM session changes the utmp or wtmp files. If
+ PAM session support is disabled, resource limits may not
+ be updated for the command being run.
+
+ --with-passwd=no, --without-passwd
+ This option excludes authentication via the passwd (or
+ shadow) file. It should only be used when another, alternative,
+ authentication scheme is in use.
+
+ --with-SecurID[=DIR]
+ Enable SecurID support. If specified, DIR is directory containing
+ libaceclnt.a, acexport.h, and sdacmvls.h.
+
+ --with-skey[=DIR]
+ Enable S/Key OTP (One Time Password) support. If specified,
+ DIR should contain include and lib directories with skey.h
+ and libskey.a respectively.
+
+ --disable-sia
+ Disable SIA support. This is the "Security Integration
+ Architecture" on Digital UNIX. If you disable SIA sudo will
+ use its own authentication routines.
+
+ --disable-shadow
+ Disable shadow password support. Normally, sudo will compile
+ in shadow password support and use a shadow password if it
+ exists.
+
+ --enable-gss-krb5-ccache-name
+ Use the gss_krb5_ccache_name() function to set the Kerberos
+ V credential cache file name. By default, sudo will use
+ the KRB5CCNAME environment variable to set this. While
+ gss_krb5_ccache_name() provides a better API to do this it
+ is not supported by all Kerberos V and SASL combinations.
+
+ --enable-gcrypt[=DIR]
+ Use GNU crypt's SHA-2 message digest functions instead of the
+ ones bundled with sudo (or in the system's C library).
+ If specified, DIR should contain include and lib directories
+ with gcrypt.h and libgcrypt respectively.
+
+ --enable-openssl[=DIR]
+ Use OpenSSL's SHA-2 message digest functions instead of the
+ ones bundled with sudo (or in the system's C library).
+ If specified, DIR should contain include and lib directories
+ with openssl/sha.h and libcrypto respectively.
+
+Development options:
+ --enable-env-debug
+ Enable debugging of the environment setting functions. This
+ enables extra checks to make sure the environment does not
+ become corrupted.
+
+ --enable-warnings
+ Enable compiler warnings when building sudo with gcc.
+
+ --enable-werror
+ Enable the -Werror compiler option when building sudo with gcc.
+
+ --with-devel
+ Configure development options. This will enable compiler warnings
+ and set up the Makefile to be able to regenerate the sudoers parser
+ as well as the manual pages.
+
+ --with-efence
+ Link with the "electric fence" debugging malloc.
+
+Options that set runtime-changeable default values:
+ --disable-authentication
+ By default, sudo requires the user to authenticate via a
+ password or similar means. This options causes sudo to
+ *not* require authentication. It is possible to turn
+ authentication back on in sudoers via the PASSWD attribute.
+ Sudoers option: !authenticate
+
+ --disable-env-reset
+ Disable environment resetting. This sets the default value
+ of the "env_reset" Defaults option in sudoers to false.
+ Sudoers option: !env_reset
+
+ --disable-path-info
+ Normally, sudo will tell the user when a command could not be found
+ in their $PATH. Some sites may wish to disable this as it could
+ be used to gather information on the location of executables that
+ the normal user does not have access to. The disadvantage is that
+ if the executable is simply not in the user's path, sudo will tell
+ the user that they are not allowed to run it, which can be confusing.
+ Sudoers option: path_info
+
+ --disable-root-sudo
+ Don't let root run sudo. This can be used to prevent people from
+ "chaining" sudo commands to get a root shell by doing something
+ like "sudo sudo /bin/sh".
+ Sudoers option: !root_sudo
+
+ --disable-zlib
+ Disable the use of the zlib compress library when storing
+ I/O log files.
+ Sudoers option: !compress_io
+
+ --enable-log-host
+ Log the hostname in the log file.
+ Sudoers option: log_host
+
+ --enable-noargs-shell
+ If sudo is invoked with no arguments it acts as if the "-s" flag had
+ been given. That is, it runs a shell as root (the shell is determined
+ by the SHELL environment variable, falling back on the shell listed
+ in the invoking user's /etc/passwd entry).
+ Sudoers option: shell_noargs
+
+ --enable-shell-sets-home
+ If sudo is invoked with the "-s" flag the HOME environment variable
+ will be set to the home directory of the target user (which is root
+ unless the "-u" option is used). This option effectively makes the
+ "-s" flag imply "-H".
+ Sudoers option: set_home
+
+ --enable-timestamp-type=TYPE
+ Set the default time stamp record type. The TYPE may be "global"
+ (a single record per user), "ppid" (a single record for process
+ with the same parent process), or "tty" (a separate record for
+ each login session). The default is "tty".
+ Sudoers option: timestamp_type
+
+ --with-all-insults
+ Include all the insult sets listed below. You must either specify
+ --with-insults or enable insults in the sudoers file for this to
+ have any effect.
+
+ --with-askpass=PATH
+ Set PATH as the "askpass" program to use when no tty is
+ available. Typically, this is a graphical password prompter,
+ similar to the one used by ssh. The program must take a
+ prompt as an argument and print the received password to
+ the standard output. This value may overridden at run-time
+ in the sudo.conf file.
+
+ --with-badpass-message="BAD PASSWORD MESSAGE"
+ Message that is displayed if a user enters an incorrect password.
+ The default is "Sorry, try again." unless insults are turned on.
+ Sudoers option: badpass_message
+
+ --with-badpri=PRIORITY
+ Determines which syslog priority to log unauthenticated
+ commands and errors. The following priorities are supported:
+ alert, crit, debug, emerg, err, info, notice, and warning.
+ Sudoers option: syslog_badpri
+
+ --with-classic-insults
+ Uses insults from sudo "classic." If you just specify --with-insults
+ you will get the classic and CSOps insults. This is on by default if
+ --with-insults is given.
+
+ --with-csops-insults
+ Insults the user with an extra set of insults (some quotes, some
+ original) from a sysadmin group at CU (CSOps). You must specify
+ --with-insults as well for this to have any effect. This is on by
+ default if --with-insults is given.
+
+ --with-editor=PATH
+ Specify the default editor path for use by visudo. This may be a
+ single path name or a colon-separated list of editors. In the latter
+ case, visudo will choose the editor that matches the user's VISUAL
+ or EDITOR environment variables or the first editor in the list that
+ exists. The default is the path to vi on your system.
+ Sudoers option: editor
+
+ --with-env-editor
+ Makes visudo consult the VISUAL and EDITOR environment variables before
+ falling back on the default editor list (as specified by --with-editor).
+ Note that this may create a security hole as it allows the user to
+ run any arbitrary command as root without logging. A safer alternative
+ is to use a colon-separated list of editors with the --with-editor
+ option. visudo will then only use the VISUAL or EDITOR variables
+ if they match a value specified via --with-editor.
+ Sudoers option: env_editor
+
+ --with-exempt=GROUP
+ Users in the specified group don't need to enter a password when
+ running sudo. This may be useful for sites that don't want their
+ "core" sysadmins to have to enter a password but where Jr. sysadmins
+ need to. You should probably use NOPASSWD in sudoers instead.
+ Sudoers option: exempt_group
+
+ --with-fqdn
+ Define this if you want to put fully qualified host names in the sudoers
+ file. Ie: instead of myhost you would use myhost.mydomain.edu. You may
+ still use the short form if you wish (and even mix the two). Beware
+ that turning FQDN on requires sudo to make DNS lookups which may make
+ sudo unusable if your DNS is totally hosed. Also note that you must
+ use the host's official name as DNS knows it. That is, you may not use
+ a host alias (CNAME entry) due to performance issues and the fact that
+ there is no way to get all aliases from DNS.
+ Sudoers option: fqdn
+
+ --with-goodpri=PRIORITY
+ Determines which syslog priority to log successfully
+ authenticated commands. The following priorities are
+ supported: alert, crit, debug, emerg, err, info, notice,
+ and warning.
+ Sudoers option: syslog_goodpri
+
+ --with-python-insults
+ Insults the user with lines from "Monty Python's Flying Circus" when an
+ incorrect password is entered. You must either specify --with-insults or
+ enable insults in the sudoers file for this to have any effect.
+
+ --with-goons-insults
+ Insults the user with lines from the "Goon Show" when an incorrect
+ password is entered. You must either specify --with-insults or
+ enable insults in the sudoers file for this to have any effect.
+
+ --with-hal-insults
+ Uses 2001-like insults when an incorrect password is entered.
+ You must either specify --with-insults or enable insults in the
+ sudoers file for this to have any effect.
+
+ --with-ignore-dot
+ If set, sudo will ignore '.' or '' (current dir) in $PATH.
+ The $PATH itself is not modified.
+ Sudoers option: ignore_dot
+
+ --with-insults
+ Define this if you want to be insulted for typing an incorrect password
+ just like the original sudo(8). This is off by default.
+ Sudoers option: insults
+
+ --with-insults=disabled
+ Include support for insults but disable them unless explicitly
+ enabled in sudoers.
+ Sudoers option: !insults
+
+ --with-iologdir[=DIR]
+ By default, sudo stores I/O log files in either /var/log/sudo-io,
+ /var/adm/sudo-io, or /usr/log/sudo-io. If this option is
+ specified, I/O logs will be stored in the indicated directory
+ instead.
+ Sudoers option: iolog_dir
+
+ --with-lecture=no, --without-lecture
+ Don't print the lecture the first time a user runs sudo.
+ Sudoers option: !lecture
+
+ --with-logfac=FACILITY
+ Determines which syslog facility to log to. This requires
+ a 4.3BSD or later version of syslog. You can still set
+ this for ancient syslogs but it will have no effect. The
+ following facilities are supported: authpriv (if your OS
+ supports it), auth, daemon, user, local0, local1, local2,
+ local3, local4, local5, local6, and local7.
+ Sudoers option: syslog
+
+ --with-logging=TYPE
+ How you want to do your logging. You may choose "syslog",
+ "file", or "both". Setting this to "syslog" is nice because
+ you can keep all of your sudo logs in one place (see the
+ example syslog.conf file). The default is "syslog".
+ Sudoers options: syslog and logfile
+
+ --with-loglen=NUMBER
+ Number of characters per line for the file log. This is only used if
+ you are to "file" or "both". This value is used to decide when to wrap
+ lines for nicer log files. The default is 80. Setting this to 0
+ will disable the wrapping.
+ Sudoers options: loglinelen
+
+ --with-logpath=PATH
+ Override the default location of the sudo log file and use
+ "path" instead. By default will use /var/log/sudo.log if
+ there is a /var/log dir, falling back to /var/adm/sudo.log
+ or /usr/adm/sudo.log if not.
+ Sudoers option: logfile
+
+ --with-long-otp-prompt
+ When validating with a One Time Password scheme (S/Key or
+ OPIE), a two-line prompt is used to make it easier to cut
+ and paste the challenge to a local window. It's not as
+ pretty as the default but some people find it more convenient.
+ Sudoers option: long_otp_prompt
+
+ --with-mail-if-no-user=no, --without-mail-if-no-user
+ Normally, sudo will mail to the "alertmail" user if the user invoking
+ sudo is not in the sudoers file. This option disables that behavior.
+ Sudoers option: mail_no_user
+
+ --with-mail-if-no-host
+ Send mail to the "alermail" user if the user exists in the sudoers
+ file, but is not allowed to run commands on the current host.
+ Sudoers option: mail_no_host
+
+ --with-mail-if-noperms
+ Send mail to the "alermail" user if the user is allowed to use sudo but
+ the command they are trying is not listed in their sudoers file entry.
+ Sudoers option: mail_no_perms
+
+ --with-mailsubject="SUBJECT OF MAIL"
+ Subject of the mail sent to the "mailto" user. The token "%h"
+ will expand to the hostname of the machine.
+ Default is "*** SECURITY information for %h ***".
+ Sudoers option: mailsub
+
+ --with-mailto=USER|MAIL_ALIAS
+ User (or mail alias) that mail from sudo is sent to.
+ This should go to a sysadmin at your site. The default is "root".
+ Sudoers option: mailto
+
+ --with-passprompt="PASSWORD PROMPT"
+ Default prompt to use when asking for a password; can be overridden
+ via the -p option and the SUDO_PROMPT environment variable. Supports
+ the "%H", "%h", "%U" and "%u" escapes as documented in the sudo
+ manual page. The default value is "Password:".
+ Sudoers option: passprompt
+
+ --with-password-timeout=NUMBER
+ Number of minutes before the sudo password prompt times out.
+ The default is 5, set this to 0 for no password timeout.
+ Sudoers option: passwd_timeout
+
+ --with-passwd-tries=NUMBER
+ Number of tries a user gets to enter his/her password before sudo logs
+ the failure and exits. The default is 3.
+ Sudoers option: passwd_tries
+
+ --with-runas-default=USER
+ The default user to run commands as if the -u flag is not specified
+ on the command line. This defaults to "root".
+ Sudoers option: runas_default
+
+ --with-secure-path[=PATH]
+ Path used for every command run from sudo(8). If you don't trust the
+ people running sudo to have a sane PATH environment variable you may
+ want to use this. Another use is if you want to have the "root path"
+ be separate from the "user path." You will need to customize the path
+ for your site. NOTE: this is not applied to users in the group
+ specified by --with-exemptgroup. If you do not specify a path,
+ "/bin:/usr/ucb:/usr/bin:/usr/sbin:/sbin:/usr/etc:/etc" is used.
+ Sudoers option: secure_path
+
+ --with-sendmail=PATH
+ Override configure's guess as to the location of sendmail.
+ Sudoers option: mailerpath
+
+ --with-sendmail=no, --without-sendmail
+ Do not use sendmail to mail messages to the "mailto" user.
+ Use only if you don't run sendmail or the equivalent.
+ Sudoers options: !mailerpath or !mailto
+
+ --with-sudoers-mode=MODE
+ File mode for the sudoers file (octal). Note that if you
+ wish to NFS-mount the sudoers file this must be group
+ readable. This value may overridden at run-time in the
+ sudo.conf file. The default mode is 0440.
+
+ --with-sudoers-uid=UID
+ User id that "owns" the sudoers file. Note that this is
+ the numeric id, *not* the symbolic name. This value may
+ overridden at run-time in the sudo.conf file. The default
+ is 0.
+
+ --with-sudoers-gid=GID
+ Group id that "owns" the sudoers file. Note that this is
+ the numeric id, *not* the symbolic name. This value may
+ overridden at run-time in the sudo.conf file. The default
+ is 0.
+
+ --with-timeout=NUMBER
+ Number of minutes that can elapse before sudo will ask for a passwd
+ again. The default is 5, set this to 0 to always prompt for a password.
+ Sudoers option: timestamp_timeout
+
+ --with-umask=MASK
+ Umask to use when running the root command. The default is 0022.
+ Sudoers option: umask
+
+ --with-umask=no, --without-umask
+ Preserves the umask of the user invoking sudo.
+ Sudoers option: !umask
+
+ --with-umask-override
+ Use the umask specified in sudoers even if it is less restrictive
+ than the user's. The default is to use the intersection of the
+ user's umask and the umask specified in sudoers.
+ Sudoers option: umask_override
+
+OS dependent notes
+==================
+
+HP-UX:
+ The default C compiler shipped with HP-UX is not an ANSI compiler.
+ You must use either the HP ANSI C compiler or gcc to build sudo.
+ Binary packages of gcc are available from http://hpux.connect.org.uk/.
+
+ To prevent PAM from overriding the value of umask on HP-UX 11,
+ you will need to add a line like the following to /etc/pam.conf:
+
+ sudo session required libpam_hpsec.so.1 bypass_umask
+
+ If every command run via sudo displays information about the last
+ successful login and the last authentication failure you should
+ make use an /etc/pam.conf line like:
+
+ sudo session required libpam_hpsec.so.1 bypass_umask bypass_last_login
+
+Linux:
+ PAM and LDAP headers are not installed by default on most Linux
+ systems. You will need to install the "pam-dev" package if
+ /usr/include/security/pam_appl.h is not present on your system.
+ If you wish to build with LDAP support you will also need the
+ openldap-devel package.
+
+Mac OS X:
+ The pseudo-tty support in the Mac OS X kernel has bugs related
+ to its handling of the SIGTSTP, SIGTTIN and SIGTTOU signals.
+ It does not restart reads and writes when those signals are
+ delivered. This may cause problems for some commands when I/O
+ logging is enabled. The issue has been reported to Apple and
+ is bug id #7952709.
+
+Solaris:
+ You need to have a C compiler in order to build sudo. Since
+ Solaris does not come with one by default this means that you
+ either need to either install the Solaris Studio compiler suite,
+ available for free from www.oracle.com, or install the GNU C
+ compiler (gcc) which is can be installed via the pkg utility
+ on Solaris 11 and higher and is distributed on the Solaris
+ Companion CD for older Solaris releases. You can also download
+ gcc packages from http://www.opencsw.org/packages/CSWgcc4core/
diff --git a/INSTALL.configure b/INSTALL.configure
new file mode 100644
index 0000000..a1b253c
--- /dev/null
+++ b/INSTALL.configure
@@ -0,0 +1,365 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without warranty of any kind.
+
+Basic Installation
+==================
+
+ Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package. The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package. Some packages provide this
+`INSTALL' file but do not implement all of the features documented
+below. The lack of an optional feature in a given package is not
+necessarily a bug. More recommendations for GNU packages can be found
+in *note Makefile Conventions: (standards)Makefile Conventions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+ The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system.
+
+ Running `configure' might take a while. While running, it prints
+ some messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package, generally using the just-built uninstalled binaries.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation. When installing into a prefix owned by root, it is
+ recommended that the package be configured and built as a regular
+ user, and only the `make install' phase executed with root
+ privileges.
+
+ 5. Optionally, type `make installcheck' to repeat any self-tests, but
+ this time using the binaries in their final installed location.
+ This target does not install anything. Running this target as a
+ regular user, particularly if the prior `make install' required
+ root privileges, verifies that the installation completed
+ correctly.
+
+ 6. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+ 7. Often, you can also type `make uninstall' to remove the installed
+ files again. In practice, not all packages have tested that
+ uninstallation works correctly, even though it is required by the
+ GNU Coding Standards.
+
+ 8. Some packages, particularly those that use Automake, provide `make
+ distcheck', which can by used by developers to test that all other
+ targets like `make install' and `make uninstall' work correctly.
+ This target is generally not run by end users.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you can use GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'. This
+is known as a "VPATH" build.
+
+ With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory. After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+ On macOS 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor. Like
+this:
+
+ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CPP="gcc -E" CXXCPP="g++ -E"
+
+ This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+ By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX', where PREFIX must be an
+absolute file name.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them. In general, the
+default for these options is expressed in terms of `${prefix}', so that
+specifying just `--prefix' will affect all of the other directory
+specifications that were not explicitly provided.
+
+ The most portable way to affect installation locations is to pass the
+correct locations to `configure'; however, many packages provide one or
+both of the following shortcuts of passing variable assignments to the
+`make install' command line to change installation locations without
+having to reconfigure or recompile.
+
+ The first method involves providing an override variable for each
+affected directory. For example, `make install
+prefix=/alternate/directory' will choose an alternate location for all
+directory configuration variables that were expressed in terms of
+`${prefix}'. Any directories that were specified during `configure',
+but not in terms of `${prefix}', must each be overridden at install
+time for the entire installation to be relocated. The approach of
+makefile variable overrides for each directory variable is required by
+the GNU Coding Standards, and ideally causes no recompilation.
+However, some platforms have known limitations with the semantics of
+shared libraries that end up requiring recompilation when using this
+method, particularly noticeable in packages that use GNU Libtool.
+
+ The second method involves providing the `DESTDIR' variable. For
+example, `make install DESTDIR=/alternate/directory' will prepend
+`/alternate/directory' before all installation names. The approach of
+`DESTDIR' overrides is not required by the GNU Coding Standards, and
+does not work on platforms that have drive letters. On the other hand,
+it does better at avoiding recompilation issues, and works well even
+when some directory options were not specified in terms of `${prefix}'
+at `configure' time.
+
+Optional Features
+=================
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+ Some packages offer the ability to configure how verbose the
+execution of `make' will be. For these packages, running `./configure
+--enable-silent-rules' sets the default to minimal output, which can be
+overridden with `make V=1'; while running `./configure
+--disable-silent-rules' sets the default to verbose, which can be
+overridden with `make V=0'.
+
+Particular systems
+==================
+
+ On HP-UX, the default C compiler is not ANSI C compatible. If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+ ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+ On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file. The option `-nodtk' can be used as
+a workaround. If GNU CC is not installed, it is therefore recommended
+to try
+
+ ./configure CC="cc"
+
+and if that doesn't work, try
+
+ ./configure CC="cc -nodtk"
+
+ On Solaris, don't put `/usr/ucb' early in your `PATH'. This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+ On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'. It is recommended to use the following options:
+
+ ./configure --prefix=/boot/common
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on. Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS
+ KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+ Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug. Until the bug is fixed you can use this workaround:
+
+ CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+ Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+ Print a summary of the options unique to this package's
+ `configure', and exit. The `short' variant lists options used
+ only in the top level, while the `recursive' variant lists options
+ also present in any nested packages.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--prefix=DIR'
+ Use DIR as the installation prefix. *note Installation Names::
+ for more details, including other options available for fine-tuning
+ the installation locations.
+
+`--no-create'
+`-n'
+ Run the configure checks, but stop before creating any output
+ files.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
index 0000000..08d7f25
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,801 @@
+ABOUT-NLS
+ChangeLog
+INSTALL
+INSTALL.configure
+MANIFEST
+Makefile.in
+NEWS
+README
+README.LDAP
+aclocal.m4
+autogen.sh
+config.guess
+config.h.in
+config.sub
+configure
+configure.ac
+doc/CONTRIBUTORS
+doc/HISTORY
+doc/LICENSE
+doc/Makefile.in
+doc/TROUBLESHOOTING
+doc/UPGRADE
+doc/cvtsudoers.cat
+doc/cvtsudoers.man.in
+doc/cvtsudoers.mdoc.in
+doc/fixman.sh
+doc/fixmdoc.sed
+doc/schema.ActiveDirectory
+doc/schema.OpenLDAP
+doc/schema.iPlanet
+doc/schema.olcSudo
+doc/sudo.cat
+doc/sudo.conf.cat
+doc/sudo.conf.man.in
+doc/sudo.conf.mdoc.in
+doc/sudo.man.in
+doc/sudo.man.in.sed
+doc/sudo.mdoc.in
+doc/sudo_plugin.cat
+doc/sudo_plugin.man.in
+doc/sudo_plugin.mdoc.in
+doc/sudoers.cat
+doc/sudoers.ldap.cat
+doc/sudoers.ldap.man.in
+doc/sudoers.ldap.mdoc.in
+doc/sudoers.man.in
+doc/sudoers.man.in.sed
+doc/sudoers.mdoc.in
+doc/sudoers_timestamp.cat
+doc/sudoers_timestamp.man.in
+doc/sudoers_timestamp.mdoc.in
+doc/sudoreplay.cat
+doc/sudoreplay.man.in
+doc/sudoreplay.mdoc.in
+doc/visudo.cat
+doc/visudo.man.in
+doc/visudo.mdoc.in
+examples/Makefile.in
+examples/pam.conf
+examples/sudo.conf
+examples/sudoers
+examples/syslog.conf
+include/Makefile.in
+include/compat/charclass.h
+include/compat/endian.h
+include/compat/fnmatch.h
+include/compat/getaddrinfo.h
+include/compat/getopt.h
+include/compat/glob.h
+include/compat/nss_dbdefs.h
+include/compat/sha2.h
+include/compat/stdbool.h
+include/sudo_compat.h
+include/sudo_conf.h
+include/sudo_debug.h
+include/sudo_digest.h
+include/sudo_dso.h
+include/sudo_event.h
+include/sudo_fatal.h
+include/sudo_gettext.h
+include/sudo_lbuf.h
+include/sudo_plugin.h
+include/sudo_queue.h
+include/sudo_rand.h
+include/sudo_util.h
+indent.pro
+init.d/aix.sh.in
+init.d/hpux.sh.in
+init.d/sudo.conf.in
+install-sh
+lib/util/Makefile.in
+lib/util/aix.c
+lib/util/arc4random.c
+lib/util/arc4random.h
+lib/util/arc4random_uniform.c
+lib/util/chacha_private.h
+lib/util/closefrom.c
+lib/util/digest.c
+lib/util/digest_gcrypt.c
+lib/util/digest_openssl.c
+lib/util/event.c
+lib/util/event_poll.c
+lib/util/event_select.c
+lib/util/fatal.c
+lib/util/fnmatch.c
+lib/util/getaddrinfo.c
+lib/util/getcwd.c
+lib/util/getentropy.c
+lib/util/getgrouplist.c
+lib/util/gethostname.c
+lib/util/getline.c
+lib/util/getopt_long.c
+lib/util/gettime.c
+lib/util/gidlist.c
+lib/util/glob.c
+lib/util/inet_ntop.c
+lib/util/inet_pton.c
+lib/util/isblank.c
+lib/util/key_val.c
+lib/util/lbuf.c
+lib/util/locking.c
+lib/util/memrchr.c
+lib/util/memset_s.c
+lib/util/mksiglist.c
+lib/util/mksiglist.h
+lib/util/mksigname.c
+lib/util/mksigname.h
+lib/util/mktemp.c
+lib/util/nanosleep.c
+lib/util/parseln.c
+lib/util/pipe2.c
+lib/util/progname.c
+lib/util/pw_dup.c
+lib/util/reallocarray.c
+lib/util/regress/atofoo/atofoo_test.c
+lib/util/regress/fnmatch/fnm_test.c
+lib/util/regress/fnmatch/fnm_test.in
+lib/util/regress/getgrouplist/getgrouplist_test.c
+lib/util/regress/glob/files
+lib/util/regress/glob/globtest.c
+lib/util/regress/glob/globtest.in
+lib/util/regress/mktemp/mktemp_test.c
+lib/util/regress/parse_gids/parse_gids_test.c
+lib/util/regress/progname/progname_test.c
+lib/util/regress/strsplit/strsplit_test.c
+lib/util/regress/sudo_conf/conf_test.c
+lib/util/regress/sudo_conf/test1.in
+lib/util/regress/sudo_conf/test1.out.ok
+lib/util/regress/sudo_conf/test2.in
+lib/util/regress/sudo_conf/test2.out.ok
+lib/util/regress/sudo_conf/test3.in
+lib/util/regress/sudo_conf/test3.out.ok
+lib/util/regress/sudo_conf/test4.err.ok
+lib/util/regress/sudo_conf/test4.in
+lib/util/regress/sudo_conf/test4.out.ok
+lib/util/regress/sudo_conf/test5.err.ok
+lib/util/regress/sudo_conf/test5.in
+lib/util/regress/sudo_conf/test5.out.ok
+lib/util/regress/sudo_conf/test6.in
+lib/util/regress/sudo_conf/test6.out.ok
+lib/util/regress/sudo_conf/test7.in
+lib/util/regress/sudo_conf/test7.out.ok
+lib/util/regress/sudo_parseln/parseln_test.c
+lib/util/regress/sudo_parseln/test1.in
+lib/util/regress/sudo_parseln/test1.out.ok
+lib/util/regress/sudo_parseln/test2.in
+lib/util/regress/sudo_parseln/test2.out.ok
+lib/util/regress/sudo_parseln/test3.in
+lib/util/regress/sudo_parseln/test3.out.ok
+lib/util/regress/sudo_parseln/test4.in
+lib/util/regress/sudo_parseln/test4.out.ok
+lib/util/regress/sudo_parseln/test5.in
+lib/util/regress/sudo_parseln/test5.out.ok
+lib/util/regress/sudo_parseln/test6.in
+lib/util/regress/sudo_parseln/test6.out.ok
+lib/util/regress/tailq/hltq_test.c
+lib/util/regress/vsyslog/vsyslog_test.c
+lib/util/secure_path.c
+lib/util/setgroups.c
+lib/util/sha2.c
+lib/util/sig2str.c
+lib/util/siglist.in
+lib/util/snprintf.c
+lib/util/strlcat.c
+lib/util/strlcpy.c
+lib/util/strndup.c
+lib/util/strnlen.c
+lib/util/strsignal.c
+lib/util/strsplit.c
+lib/util/strtobool.c
+lib/util/strtoid.c
+lib/util/strtomode.c
+lib/util/strtonum.c
+lib/util/sudo_conf.c
+lib/util/sudo_debug.c
+lib/util/sudo_dso.c
+lib/util/term.c
+lib/util/ttyname_dev.c
+lib/util/ttysize.c
+lib/util/util.exp.in
+lib/util/utimens.c
+lib/util/vsyslog.c
+lib/zlib/Makefile.in
+lib/zlib/adler32.c
+lib/zlib/compress.c
+lib/zlib/crc32.c
+lib/zlib/crc32.h
+lib/zlib/deflate.c
+lib/zlib/deflate.h
+lib/zlib/gzclose.c
+lib/zlib/gzguts.h
+lib/zlib/gzlib.c
+lib/zlib/gzread.c
+lib/zlib/gzwrite.c
+lib/zlib/infback.c
+lib/zlib/inffast.c
+lib/zlib/inffast.h
+lib/zlib/inffixed.h
+lib/zlib/inflate.c
+lib/zlib/inflate.h
+lib/zlib/inftrees.c
+lib/zlib/inftrees.h
+lib/zlib/trees.c
+lib/zlib/trees.h
+lib/zlib/uncompr.c
+lib/zlib/zconf.h.in
+lib/zlib/zlib.exp
+lib/zlib/zlib.h
+lib/zlib/zutil.c
+lib/zlib/zutil.h
+log2cl.pl
+ltmain.sh
+m4/ax_append_flag.m4
+m4/ax_check_compile_flag.m4
+m4/ax_check_link_flag.m4
+m4/ax_func_getaddrinfo.m4
+m4/ax_func_snprintf.m4
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
+m4/sudo.m4
+mkdep.pl
+mkinstalldirs
+mkpkg
+pathnames.h.in
+plugins/group_file/Makefile.in
+plugins/group_file/getgrent.c
+plugins/group_file/group_file.c
+plugins/group_file/group_file.exp
+plugins/group_file/plugin_test.c
+plugins/sample/Makefile.in
+plugins/sample/README
+plugins/sample/sample_plugin.c
+plugins/sample/sample_plugin.exp
+plugins/sudoers/Makefile.in
+plugins/sudoers/alias.c
+plugins/sudoers/audit.c
+plugins/sudoers/auth/API
+plugins/sudoers/auth/afs.c
+plugins/sudoers/auth/aix_auth.c
+plugins/sudoers/auth/bsdauth.c
+plugins/sudoers/auth/dce.c
+plugins/sudoers/auth/fwtk.c
+plugins/sudoers/auth/kerb5.c
+plugins/sudoers/auth/pam.c
+plugins/sudoers/auth/passwd.c
+plugins/sudoers/auth/rfc1938.c
+plugins/sudoers/auth/secureware.c
+plugins/sudoers/auth/securid5.c
+plugins/sudoers/auth/sia.c
+plugins/sudoers/auth/sudo_auth.c
+plugins/sudoers/auth/sudo_auth.h
+plugins/sudoers/base64.c
+plugins/sudoers/boottime.c
+plugins/sudoers/bsm_audit.c
+plugins/sudoers/bsm_audit.h
+plugins/sudoers/check.c
+plugins/sudoers/check.h
+plugins/sudoers/cvtsudoers.c
+plugins/sudoers/cvtsudoers.h
+plugins/sudoers/cvtsudoers_json.c
+plugins/sudoers/cvtsudoers_ldif.c
+plugins/sudoers/cvtsudoers_pwutil.c
+plugins/sudoers/def_data.c
+plugins/sudoers/def_data.h
+plugins/sudoers/def_data.in
+plugins/sudoers/defaults.c
+plugins/sudoers/defaults.h
+plugins/sudoers/digestname.c
+plugins/sudoers/editor.c
+plugins/sudoers/env.c
+plugins/sudoers/env_pattern.c
+plugins/sudoers/file.c
+plugins/sudoers/filedigest.c
+plugins/sudoers/find_path.c
+plugins/sudoers/fmtsudoers.c
+plugins/sudoers/gc.c
+plugins/sudoers/gentime.c
+plugins/sudoers/getdate.c
+plugins/sudoers/getdate.y
+plugins/sudoers/getspwuid.c
+plugins/sudoers/gmtoff.c
+plugins/sudoers/goodpath.c
+plugins/sudoers/gram.c
+plugins/sudoers/gram.h
+plugins/sudoers/gram.y
+plugins/sudoers/group_plugin.c
+plugins/sudoers/hexchar.c
+plugins/sudoers/ins_2001.h
+plugins/sudoers/ins_classic.h
+plugins/sudoers/ins_csops.h
+plugins/sudoers/ins_goons.h
+plugins/sudoers/ins_python.h
+plugins/sudoers/insults.h
+plugins/sudoers/interfaces.c
+plugins/sudoers/interfaces.h
+plugins/sudoers/iolog.c
+plugins/sudoers/iolog.h
+plugins/sudoers/iolog_files.h
+plugins/sudoers/iolog_path.c
+plugins/sudoers/iolog_util.c
+plugins/sudoers/ldap.c
+plugins/sudoers/ldap_conf.c
+plugins/sudoers/ldap_util.c
+plugins/sudoers/linux_audit.c
+plugins/sudoers/linux_audit.h
+plugins/sudoers/locale.c
+plugins/sudoers/logging.c
+plugins/sudoers/logging.h
+plugins/sudoers/logwrap.c
+plugins/sudoers/match.c
+plugins/sudoers/match_addr.c
+plugins/sudoers/mkdefaults
+plugins/sudoers/mkdir_parents.c
+plugins/sudoers/parse.c
+plugins/sudoers/parse.h
+plugins/sudoers/parse_ldif.c
+plugins/sudoers/po/README
+plugins/sudoers/po/ca.mo
+plugins/sudoers/po/ca.po
+plugins/sudoers/po/cs.mo
+plugins/sudoers/po/cs.po
+plugins/sudoers/po/da.mo
+plugins/sudoers/po/da.po
+plugins/sudoers/po/de.mo
+plugins/sudoers/po/de.po
+plugins/sudoers/po/el.mo
+plugins/sudoers/po/el.po
+plugins/sudoers/po/eo.mo
+plugins/sudoers/po/eo.po
+plugins/sudoers/po/eu.mo
+plugins/sudoers/po/eu.po
+plugins/sudoers/po/fi.mo
+plugins/sudoers/po/fi.po
+plugins/sudoers/po/fr.mo
+plugins/sudoers/po/fr.po
+plugins/sudoers/po/fur.mo
+plugins/sudoers/po/fur.po
+plugins/sudoers/po/hr.mo
+plugins/sudoers/po/hr.po
+plugins/sudoers/po/hu.mo
+plugins/sudoers/po/hu.po
+plugins/sudoers/po/it.mo
+plugins/sudoers/po/it.po
+plugins/sudoers/po/ja.mo
+plugins/sudoers/po/ja.po
+plugins/sudoers/po/ko.mo
+plugins/sudoers/po/ko.po
+plugins/sudoers/po/lt.mo
+plugins/sudoers/po/lt.po
+plugins/sudoers/po/nb.mo
+plugins/sudoers/po/nb.po
+plugins/sudoers/po/nl.mo
+plugins/sudoers/po/nl.po
+plugins/sudoers/po/pl.mo
+plugins/sudoers/po/pl.po
+plugins/sudoers/po/pt.mo
+plugins/sudoers/po/pt.po
+plugins/sudoers/po/pt_BR.mo
+plugins/sudoers/po/pt_BR.po
+plugins/sudoers/po/ru.mo
+plugins/sudoers/po/ru.po
+plugins/sudoers/po/sk.mo
+plugins/sudoers/po/sk.po
+plugins/sudoers/po/sl.mo
+plugins/sudoers/po/sl.po
+plugins/sudoers/po/sr.mo
+plugins/sudoers/po/sr.po
+plugins/sudoers/po/sudoers.pot
+plugins/sudoers/po/sv.mo
+plugins/sudoers/po/sv.po
+plugins/sudoers/po/tr.mo
+plugins/sudoers/po/tr.po
+plugins/sudoers/po/uk.mo
+plugins/sudoers/po/uk.po
+plugins/sudoers/po/vi.mo
+plugins/sudoers/po/vi.po
+plugins/sudoers/po/zh_CN.mo
+plugins/sudoers/po/zh_CN.po
+plugins/sudoers/policy.c
+plugins/sudoers/prompt.c
+plugins/sudoers/pwutil.c
+plugins/sudoers/pwutil.h
+plugins/sudoers/pwutil_impl.c
+plugins/sudoers/rcstr.c
+plugins/sudoers/redblack.c
+plugins/sudoers/redblack.h
+plugins/sudoers/regress/check_symbols/check_symbols.c
+plugins/sudoers/regress/cvtsudoers/sudoers
+plugins/sudoers/regress/cvtsudoers/sudoers.defs
+plugins/sudoers/regress/cvtsudoers/test1.out.ok
+plugins/sudoers/regress/cvtsudoers/test1.sh
+plugins/sudoers/regress/cvtsudoers/test10.out.ok
+plugins/sudoers/regress/cvtsudoers/test10.sh
+plugins/sudoers/regress/cvtsudoers/test11.out.ok
+plugins/sudoers/regress/cvtsudoers/test11.sh
+plugins/sudoers/regress/cvtsudoers/test12.out.ok
+plugins/sudoers/regress/cvtsudoers/test12.sh
+plugins/sudoers/regress/cvtsudoers/test13.out.ok
+plugins/sudoers/regress/cvtsudoers/test13.sh
+plugins/sudoers/regress/cvtsudoers/test14.out.ok
+plugins/sudoers/regress/cvtsudoers/test14.sh
+plugins/sudoers/regress/cvtsudoers/test15.out.ok
+plugins/sudoers/regress/cvtsudoers/test15.sh
+plugins/sudoers/regress/cvtsudoers/test16.out.ok
+plugins/sudoers/regress/cvtsudoers/test16.sh
+plugins/sudoers/regress/cvtsudoers/test17.out.ok
+plugins/sudoers/regress/cvtsudoers/test17.sh
+plugins/sudoers/regress/cvtsudoers/test18.out.ok
+plugins/sudoers/regress/cvtsudoers/test18.sh
+plugins/sudoers/regress/cvtsudoers/test19.out.ok
+plugins/sudoers/regress/cvtsudoers/test19.sh
+plugins/sudoers/regress/cvtsudoers/test2.out.ok
+plugins/sudoers/regress/cvtsudoers/test2.sh
+plugins/sudoers/regress/cvtsudoers/test20.conf
+plugins/sudoers/regress/cvtsudoers/test20.out.ok
+plugins/sudoers/regress/cvtsudoers/test20.sh
+plugins/sudoers/regress/cvtsudoers/test21.conf
+plugins/sudoers/regress/cvtsudoers/test21.out.ok
+plugins/sudoers/regress/cvtsudoers/test21.sh
+plugins/sudoers/regress/cvtsudoers/test22.out.ok
+plugins/sudoers/regress/cvtsudoers/test22.sh
+plugins/sudoers/regress/cvtsudoers/test23.out.ok
+plugins/sudoers/regress/cvtsudoers/test23.sh
+plugins/sudoers/regress/cvtsudoers/test24.out.ok
+plugins/sudoers/regress/cvtsudoers/test24.sh
+plugins/sudoers/regress/cvtsudoers/test25.out.ok
+plugins/sudoers/regress/cvtsudoers/test25.sh
+plugins/sudoers/regress/cvtsudoers/test26.out.ok
+plugins/sudoers/regress/cvtsudoers/test26.sh
+plugins/sudoers/regress/cvtsudoers/test27.out.ok
+plugins/sudoers/regress/cvtsudoers/test27.sh
+plugins/sudoers/regress/cvtsudoers/test28.out.ok
+plugins/sudoers/regress/cvtsudoers/test28.sh
+plugins/sudoers/regress/cvtsudoers/test29.out.ok
+plugins/sudoers/regress/cvtsudoers/test29.sh
+plugins/sudoers/regress/cvtsudoers/test3.out.ok
+plugins/sudoers/regress/cvtsudoers/test3.sh
+plugins/sudoers/regress/cvtsudoers/test30.out.ok
+plugins/sudoers/regress/cvtsudoers/test30.sh
+plugins/sudoers/regress/cvtsudoers/test31.conf
+plugins/sudoers/regress/cvtsudoers/test31.out.ok
+plugins/sudoers/regress/cvtsudoers/test31.sh
+plugins/sudoers/regress/cvtsudoers/test32.out.ok
+plugins/sudoers/regress/cvtsudoers/test32.sh
+plugins/sudoers/regress/cvtsudoers/test33.out.ok
+plugins/sudoers/regress/cvtsudoers/test33.sh
+plugins/sudoers/regress/cvtsudoers/test4.out.ok
+plugins/sudoers/regress/cvtsudoers/test4.sh
+plugins/sudoers/regress/cvtsudoers/test5.out.ok
+plugins/sudoers/regress/cvtsudoers/test5.sh
+plugins/sudoers/regress/cvtsudoers/test6.out.ok
+plugins/sudoers/regress/cvtsudoers/test6.sh
+plugins/sudoers/regress/cvtsudoers/test7.out.ok
+plugins/sudoers/regress/cvtsudoers/test7.sh
+plugins/sudoers/regress/cvtsudoers/test8.out.ok
+plugins/sudoers/regress/cvtsudoers/test8.sh
+plugins/sudoers/regress/cvtsudoers/test9.out.ok
+plugins/sudoers/regress/cvtsudoers/test9.sh
+plugins/sudoers/regress/env_match/check_env_pattern.c
+plugins/sudoers/regress/env_match/data
+plugins/sudoers/regress/iolog_path/check_iolog_path.c
+plugins/sudoers/regress/iolog_path/data
+plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c
+plugins/sudoers/regress/iolog_util/check_iolog_util.c
+plugins/sudoers/regress/logging/check_wrap.c
+plugins/sudoers/regress/logging/check_wrap.in
+plugins/sudoers/regress/logging/check_wrap.out.ok
+plugins/sudoers/regress/parser/check_addr.c
+plugins/sudoers/regress/parser/check_addr.in
+plugins/sudoers/regress/parser/check_base64.c
+plugins/sudoers/regress/parser/check_digest.c
+plugins/sudoers/regress/parser/check_digest.out.ok
+plugins/sudoers/regress/parser/check_fill.c
+plugins/sudoers/regress/parser/check_gentime.c
+plugins/sudoers/regress/parser/check_hexchar.c
+plugins/sudoers/regress/starttime/check_starttime.c
+plugins/sudoers/regress/sudoers/test1.in
+plugins/sudoers/regress/sudoers/test1.json.ok
+plugins/sudoers/regress/sudoers/test1.ldif.ok
+plugins/sudoers/regress/sudoers/test1.ldif2sudo.ok
+plugins/sudoers/regress/sudoers/test1.out.ok
+plugins/sudoers/regress/sudoers/test1.toke.ok
+plugins/sudoers/regress/sudoers/test10.in
+plugins/sudoers/regress/sudoers/test10.json.ok
+plugins/sudoers/regress/sudoers/test10.ldif.ok
+plugins/sudoers/regress/sudoers/test10.out.ok
+plugins/sudoers/regress/sudoers/test10.toke.ok
+plugins/sudoers/regress/sudoers/test11.in
+plugins/sudoers/regress/sudoers/test11.json.ok
+plugins/sudoers/regress/sudoers/test11.ldif.ok
+plugins/sudoers/regress/sudoers/test11.out.ok
+plugins/sudoers/regress/sudoers/test11.toke.ok
+plugins/sudoers/regress/sudoers/test12.in
+plugins/sudoers/regress/sudoers/test12.json.ok
+plugins/sudoers/regress/sudoers/test12.ldif.ok
+plugins/sudoers/regress/sudoers/test12.out.ok
+plugins/sudoers/regress/sudoers/test12.toke.ok
+plugins/sudoers/regress/sudoers/test13.in
+plugins/sudoers/regress/sudoers/test13.json.ok
+plugins/sudoers/regress/sudoers/test13.ldif.ok
+plugins/sudoers/regress/sudoers/test13.out.ok
+plugins/sudoers/regress/sudoers/test13.toke.ok
+plugins/sudoers/regress/sudoers/test14.in
+plugins/sudoers/regress/sudoers/test14.json.ok
+plugins/sudoers/regress/sudoers/test14.ldif.ok
+plugins/sudoers/regress/sudoers/test14.ldif2sudo.ok
+plugins/sudoers/regress/sudoers/test14.out.ok
+plugins/sudoers/regress/sudoers/test14.toke.ok
+plugins/sudoers/regress/sudoers/test15.in
+plugins/sudoers/regress/sudoers/test15.json.ok
+plugins/sudoers/regress/sudoers/test15.ldif.ok
+plugins/sudoers/regress/sudoers/test15.ldif2sudo.ok
+plugins/sudoers/regress/sudoers/test15.out.ok
+plugins/sudoers/regress/sudoers/test15.toke.ok
+plugins/sudoers/regress/sudoers/test16.in
+plugins/sudoers/regress/sudoers/test16.json.ok
+plugins/sudoers/regress/sudoers/test16.ldif.ok
+plugins/sudoers/regress/sudoers/test16.ldif2sudo.ok
+plugins/sudoers/regress/sudoers/test16.out.ok
+plugins/sudoers/regress/sudoers/test16.toke.ok
+plugins/sudoers/regress/sudoers/test17.in
+plugins/sudoers/regress/sudoers/test17.json.ok
+plugins/sudoers/regress/sudoers/test17.ldif.ok
+plugins/sudoers/regress/sudoers/test17.ldif2sudo.ok
+plugins/sudoers/regress/sudoers/test17.out.ok
+plugins/sudoers/regress/sudoers/test17.toke.ok
+plugins/sudoers/regress/sudoers/test18.in
+plugins/sudoers/regress/sudoers/test18.json.ok
+plugins/sudoers/regress/sudoers/test18.ldif.ok
+plugins/sudoers/regress/sudoers/test18.out.ok
+plugins/sudoers/regress/sudoers/test18.toke.ok
+plugins/sudoers/regress/sudoers/test19.in
+plugins/sudoers/regress/sudoers/test19.json.ok
+plugins/sudoers/regress/sudoers/test19.ldif.ok
+plugins/sudoers/regress/sudoers/test19.ldif2sudo.ok
+plugins/sudoers/regress/sudoers/test19.out.ok
+plugins/sudoers/regress/sudoers/test19.toke.ok
+plugins/sudoers/regress/sudoers/test2.in
+plugins/sudoers/regress/sudoers/test2.json.ok
+plugins/sudoers/regress/sudoers/test2.ldif.ok
+plugins/sudoers/regress/sudoers/test2.ldif2sudo.ok
+plugins/sudoers/regress/sudoers/test2.out.ok
+plugins/sudoers/regress/sudoers/test2.toke.ok
+plugins/sudoers/regress/sudoers/test20.in
+plugins/sudoers/regress/sudoers/test20.json.ok
+plugins/sudoers/regress/sudoers/test20.ldif.ok
+plugins/sudoers/regress/sudoers/test20.ldif2sudo.ok
+plugins/sudoers/regress/sudoers/test20.out.ok
+plugins/sudoers/regress/sudoers/test20.toke.ok
+plugins/sudoers/regress/sudoers/test21.in
+plugins/sudoers/regress/sudoers/test21.json.ok
+plugins/sudoers/regress/sudoers/test21.ldif.ok
+plugins/sudoers/regress/sudoers/test21.ldif2sudo.ok
+plugins/sudoers/regress/sudoers/test21.out.ok
+plugins/sudoers/regress/sudoers/test21.toke.ok
+plugins/sudoers/regress/sudoers/test22.in
+plugins/sudoers/regress/sudoers/test22.json.ok
+plugins/sudoers/regress/sudoers/test22.ldif.ok
+plugins/sudoers/regress/sudoers/test22.ldif2sudo.ok
+plugins/sudoers/regress/sudoers/test22.out.ok
+plugins/sudoers/regress/sudoers/test22.sudo.ok
+plugins/sudoers/regress/sudoers/test22.toke.ok
+plugins/sudoers/regress/sudoers/test3.in
+plugins/sudoers/regress/sudoers/test3.json.ok
+plugins/sudoers/regress/sudoers/test3.ldif.ok
+plugins/sudoers/regress/sudoers/test3.ldif2sudo.ok
+plugins/sudoers/regress/sudoers/test3.out.ok
+plugins/sudoers/regress/sudoers/test3.toke.ok
+plugins/sudoers/regress/sudoers/test4.in
+plugins/sudoers/regress/sudoers/test4.json.ok
+plugins/sudoers/regress/sudoers/test4.ldif.ok
+plugins/sudoers/regress/sudoers/test4.out.ok
+plugins/sudoers/regress/sudoers/test4.toke.ok
+plugins/sudoers/regress/sudoers/test5.in
+plugins/sudoers/regress/sudoers/test5.json.ok
+plugins/sudoers/regress/sudoers/test5.ldif.ok
+plugins/sudoers/regress/sudoers/test5.out.ok
+plugins/sudoers/regress/sudoers/test5.toke.ok
+plugins/sudoers/regress/sudoers/test6.in
+plugins/sudoers/regress/sudoers/test6.json.ok
+plugins/sudoers/regress/sudoers/test6.ldif.ok
+plugins/sudoers/regress/sudoers/test6.ldif2sudo.ok
+plugins/sudoers/regress/sudoers/test6.out.ok
+plugins/sudoers/regress/sudoers/test6.toke.ok
+plugins/sudoers/regress/sudoers/test7.in
+plugins/sudoers/regress/sudoers/test7.json.ok
+plugins/sudoers/regress/sudoers/test7.ldif.ok
+plugins/sudoers/regress/sudoers/test7.out.ok
+plugins/sudoers/regress/sudoers/test7.toke.ok
+plugins/sudoers/regress/sudoers/test8.in
+plugins/sudoers/regress/sudoers/test8.json.ok
+plugins/sudoers/regress/sudoers/test8.ldif.ok
+plugins/sudoers/regress/sudoers/test8.out.ok
+plugins/sudoers/regress/sudoers/test8.toke.ok
+plugins/sudoers/regress/sudoers/test9.in
+plugins/sudoers/regress/sudoers/test9.json.ok
+plugins/sudoers/regress/sudoers/test9.ldif.ok
+plugins/sudoers/regress/sudoers/test9.out.ok
+plugins/sudoers/regress/sudoers/test9.toke.ok
+plugins/sudoers/regress/testsudoers/group
+plugins/sudoers/regress/testsudoers/test1.out.ok
+plugins/sudoers/regress/testsudoers/test1.sh
+plugins/sudoers/regress/testsudoers/test2.inc
+plugins/sudoers/regress/testsudoers/test2.out.ok
+plugins/sudoers/regress/testsudoers/test2.sh
+plugins/sudoers/regress/testsudoers/test3.d/root
+plugins/sudoers/regress/testsudoers/test3.out.ok
+plugins/sudoers/regress/testsudoers/test3.sh
+plugins/sudoers/regress/testsudoers/test4.out.ok
+plugins/sudoers/regress/testsudoers/test4.sh
+plugins/sudoers/regress/testsudoers/test5.out.ok
+plugins/sudoers/regress/testsudoers/test5.sh
+plugins/sudoers/regress/testsudoers/test6.out.ok
+plugins/sudoers/regress/testsudoers/test6.sh
+plugins/sudoers/regress/testsudoers/test7.out.ok
+plugins/sudoers/regress/testsudoers/test7.sh
+plugins/sudoers/regress/visudo/test1.out.ok
+plugins/sudoers/regress/visudo/test1.sh
+plugins/sudoers/regress/visudo/test10.out.ok
+plugins/sudoers/regress/visudo/test10.sh
+plugins/sudoers/regress/visudo/test2.err.ok
+plugins/sudoers/regress/visudo/test2.out.ok
+plugins/sudoers/regress/visudo/test2.sh
+plugins/sudoers/regress/visudo/test3.err.ok
+plugins/sudoers/regress/visudo/test3.out.ok
+plugins/sudoers/regress/visudo/test3.sh
+plugins/sudoers/regress/visudo/test4.out.ok
+plugins/sudoers/regress/visudo/test4.sh
+plugins/sudoers/regress/visudo/test5.out.ok
+plugins/sudoers/regress/visudo/test5.sh
+plugins/sudoers/regress/visudo/test6.out.ok
+plugins/sudoers/regress/visudo/test6.sh
+plugins/sudoers/regress/visudo/test7.out.ok
+plugins/sudoers/regress/visudo/test7.sh
+plugins/sudoers/regress/visudo/test8.err.ok
+plugins/sudoers/regress/visudo/test8.out.ok
+plugins/sudoers/regress/visudo/test8.sh
+plugins/sudoers/regress/visudo/test9.out.ok
+plugins/sudoers/regress/visudo/test9.sh
+plugins/sudoers/set_perms.c
+plugins/sudoers/solaris_audit.c
+plugins/sudoers/solaris_audit.h
+plugins/sudoers/sssd.c
+plugins/sudoers/starttime.c
+plugins/sudoers/strlist.c
+plugins/sudoers/strlist.h
+plugins/sudoers/stubs.c
+plugins/sudoers/sudo_ldap.h
+plugins/sudoers/sudo_ldap_conf.h
+plugins/sudoers/sudo_nss.c
+plugins/sudoers/sudo_nss.h
+plugins/sudoers/sudo_printf.c
+plugins/sudoers/sudoers.c
+plugins/sudoers/sudoers.exp
+plugins/sudoers/sudoers.h
+plugins/sudoers/sudoers.in
+plugins/sudoers/sudoers_debug.c
+plugins/sudoers/sudoers_debug.h
+plugins/sudoers/sudoers_version.h
+plugins/sudoers/sudoreplay.c
+plugins/sudoers/testsudoers.c
+plugins/sudoers/timeout.c
+plugins/sudoers/timestamp.c
+plugins/sudoers/timestr.c
+plugins/sudoers/toke.c
+plugins/sudoers/toke.h
+plugins/sudoers/toke.l
+plugins/sudoers/toke_util.c
+plugins/sudoers/tsdump.c
+plugins/sudoers/tsgetgrpw.c
+plugins/sudoers/tsgetgrpw.h
+plugins/sudoers/visudo.c
+plugins/system_group/Makefile.in
+plugins/system_group/system_group.c
+plugins/system_group/system_group.exp
+po/README
+po/ast.mo
+po/ast.po
+po/ca.mo
+po/ca.po
+po/cs.mo
+po/cs.po
+po/da.mo
+po/da.po
+po/de.mo
+po/de.po
+po/eo.mo
+po/eo.po
+po/es.mo
+po/es.po
+po/eu.mo
+po/eu.po
+po/fi.mo
+po/fi.po
+po/fr.mo
+po/fr.po
+po/fur.mo
+po/fur.po
+po/gl.mo
+po/gl.po
+po/hr.mo
+po/hr.po
+po/hu.mo
+po/hu.po
+po/it.mo
+po/it.po
+po/ja.mo
+po/ja.po
+po/ko.mo
+po/ko.po
+po/nb.mo
+po/nb.po
+po/nl.mo
+po/nl.po
+po/nn.mo
+po/nn.po
+po/pl.mo
+po/pl.po
+po/pt.mo
+po/pt.po
+po/pt_BR.mo
+po/pt_BR.po
+po/ru.mo
+po/ru.po
+po/sk.mo
+po/sk.po
+po/sl.mo
+po/sl.po
+po/sr.mo
+po/sr.po
+po/sudo.pot
+po/sv.mo
+po/sv.po
+po/tr.mo
+po/tr.po
+po/uk.mo
+po/uk.po
+po/vi.mo
+po/vi.po
+po/zh_CN.mo
+po/zh_CN.po
+po/zh_TW.mo
+po/zh_TW.po
+pp
+src/Makefile.in
+src/conversation.c
+src/env_hooks.c
+src/exec.c
+src/exec_common.c
+src/exec_monitor.c
+src/exec_nopty.c
+src/exec_pty.c
+src/get_pty.c
+src/hooks.c
+src/load_plugins.c
+src/net_ifs.c
+src/openbsd.c
+src/parse_args.c
+src/preload.c
+src/preserve_fds.c
+src/regress/noexec/check_noexec.c
+src/regress/ttyname/check_ttyname.c
+src/selinux.c
+src/sesh.c
+src/signal.c
+src/solaris.c
+src/sudo.c
+src/sudo.h
+src/sudo_edit.c
+src/sudo_exec.h
+src/sudo_noexec.c
+src/sudo_plugin_int.h
+src/sudo_usage.h.in
+src/tcsetpgrp_nobg.c
+src/tgetpass.c
+src/ttyname.c
+src/utmp.c
+sudo.pp
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..4e11e58
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,402 @@
+#
+# Copyright (c) 2010-2015, 2017-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+srcdir = @srcdir@
+devdir = @devdir@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Installation paths for package building
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
+includedir = @includedir@
+datarootdir = @datarootdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+exampledir = @exampledir@
+docdir = @docdir@
+mandir = @mandir@
+rundir = @rundir@
+vardir = @vardir@
+
+# User and group ids the installed files should be "owned" by
+install_uid = 0
+install_gid = 0
+
+# sudoers owner and mode for package building
+sudoersdir = $(sysconfdir)
+sudoers_uid = @SUDOERS_UID@
+sudoers_gid = @SUDOERS_GID@
+sudoers_mode = @SUDOERS_MODE@
+shlib_mode = @SHLIB_MODE@
+
+SUBDIRS = lib/util @ZLIB_SRC@ plugins/group_file plugins/sudoers \
+ plugins/system_group src include doc examples
+
+SAMPLES = plugins/sample
+
+VERSION = @PACKAGE_VERSION@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+
+SHELL = @SHELL@
+
+SED = @SED@
+
+INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
+INSTALL_OWNER = -o $(install_uid) -g $(install_gid)
+
+ECHO_N = @ECHO_N@
+ECHO_C = @ECHO_C@
+
+# Message catalog support
+NLS = @SUDO_NLS@
+POTFILES = po/sudo.pot plugins/sudoers/po/sudoers.pot
+LOCALEDIR_SUFFIX = @LOCALEDIR_SUFFIX@
+MSGFMT = msgfmt
+MSGMERGE = msgmerge
+XGETTEXT = xgettext
+XGETTEXT_OPTS = -F -k_ -kN_ -kU_ --copyright-holder="Todd C. Miller" \
+ "--msgid-bugs-address=https://bugzilla.sudo.ws" \
+ --package-name=@PACKAGE_NAME@ --package-version=$(VERSION) \
+ --flag warning:1:c-format --flag warningx:1:c-format \
+ --flag fatal:1:c-format --flag fatalx:1:c-format \
+ --flag easprintf:3:c-format --flag sudo_lbuf_append:2:c-format \
+ --flag sudo_lbuf_append_quoted:3:c-format --foreign-user
+
+# Default cppcheck options when run from the top-level Makefile
+CPPCHECK_OPTS = -q --force --enable=warning,performance,portability --suppress=constStatement --error-exitcode=1 --inline-suppr -Dva_copy=va_copy -U__cplusplus -UQUAD_MAX -UQUAD_MIN -UUQUAD_MAX -U_POSIX_HOST_NAME_MAX -U_POSIX_PATH_MAX -U__NBBY -DNSIG=64
+
+# Default splint options when run from the top-level Makefile
+SPLINT_OPTS = -D__restrict= -checks
+
+# Default PVS-studio options when run from the top-level Makefile
+PVS_CFG = $(top_srcdir)/PVS-Studio.cfg
+PVS_IGNORE = 'V707,V011,V002,V536'
+PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE)
+
+all: config.status
+ for d in $(SUBDIRS); do \
+ (cd $$d && exec $(MAKE) $@) && continue; \
+ exit $$?; \
+ done
+
+check pre-install: config.status
+ for d in $(SUBDIRS); do \
+ (cd $$d && exec $(MAKE) $@) && continue; \
+ exit $$?; \
+ done
+
+cppcheck: config.status
+ rval=0; \
+ for d in $(SUBDIRS); do \
+ echo checking $$d; \
+ (cd $$d && exec $(MAKE) CPPCHECK_OPTS="$(CPPCHECK_OPTS)" $@) || rval=`expr $$rval + $$?`; \
+ done; \
+ exit $$rval
+
+splint: config.status
+ rval=0; \
+ for d in $(SUBDIRS); do \
+ echo splinting $$d; \
+ (cd $$d && exec $(MAKE) SPLINT_OPTS="$(SPLINT_OPTS)" $@) || rval=`expr $$rval + $$?`; \
+ done; \
+ exit $$rval
+
+cov-build:
+ make clean
+ cov-build --dir cov-int make ${MFLAGS} all
+
+cov-upload:
+ tar zcf cov-int.tgz cov-int
+ curl --form token=$$COVERITY_SUDO_TOKEN \
+ --form email=todd.miller@sudo.ws \
+ --form file=@cov-int.tgz \
+ --form version="$(VERSION)" \
+ https://scan.coverity.com/builds?project=sudo
+
+cov-analyze: cov-upload
+
+pvs-studio: config.status
+ files=; \
+ rval=0; \
+ for d in $(SUBDIRS); do \
+ (cd $$d && exec $(MAKE) PVS_IGNORE="$(PVS_IGNORE)" pvs-log-files) || rval=`expr $$rval + $$?`; \
+ for f in $$d/*.plog; do \
+ if test "$$f" != "$$d/*.plog"; then \
+ files="$$files $$f"; \
+ fi; \
+ done; \
+ done; \
+ if test $$rval -ne 0; then \
+ exit $$rval; \
+ fi; \
+ plog-converter $(PVS_LOG_OPTS) $$files
+
+install-dirs install-binaries install-includes install-plugin: config.status pre-install
+ for d in $(SUBDIRS); do \
+ (cd $$d && exec $(MAKE) "INSTALL_OWNER=$(INSTALL_OWNER)" $@) && continue; \
+ exit $$?; \
+ done
+
+install-doc: config.status ChangeLog
+ for d in $(SUBDIRS); do \
+ (cd $$d && exec $(MAKE) "INSTALL_OWNER=$(INSTALL_OWNER)" $@) && continue; \
+ exit $$?; \
+ done
+
+install: config.status ChangeLog pre-install install-nls
+ for d in $(SUBDIRS); do \
+ (cd $$d && exec $(MAKE) "INSTALL_OWNER=$(INSTALL_OWNER)" $@) && continue; \
+ exit $$?; \
+ done
+
+uninstall: uninstall-nls
+ for d in $(SUBDIRS); do \
+ (cd $$d && exec $(MAKE) $@) && continue; \
+ exit $$?; \
+ done
+
+uninstall-nls:
+ for pot in $(POTFILES); do \
+ domain=`basename $$pot .pot`; \
+ rm -f $(DESTDIR)$(localedir)/*/LC_MESSAGES/$$domain.mo; \
+ done
+
+siglist.c signame.c:
+ cd lib/util && exec $(MAKE) $@
+
+depend: siglist.c signame.c
+ $(top_srcdir)/mkdep.pl --builddir=`pwd` --srcdir=$(top_srcdir) \
+ lib/util/Makefile.in lib/zlib/Makefile.in \
+ plugins/group_file/Makefile.in plugins/sample/Makefile.in \
+ plugins/sudoers/Makefile.in plugins/system_group/Makefile.in \
+ src/Makefile.in && \
+ $(top_builddir)/config.status --file $(top_builddir)/lib/util/Makefile \
+ --file $(top_builddir)/plugins/sample/Makefile \
+ --file $(top_builddir)/plugins/group_file/Makefile \
+ --file $(top_builddir)/plugins/sudoers/Makefile \
+ --file $(top_builddir)/plugins/system_group/Makefile \
+ --file $(top_builddir)/src/Makefile \
+ --file $(top_builddir)/lib/zlib/Makefile
+
+ChangeLog:
+ if test -d $(srcdir)/.hg && cd $(srcdir); then \
+ if hg log --style=changelog -b default > $@.tmp; then \
+ mv -f $@.tmp $@; \
+ else \
+ rm -f $@.tmp; \
+ fi; \
+ elif test -d $(srcdir)/.git && cd $(srcdir); then \
+ $(top_srcdir)/log2cl.pl -b master > $@; \
+ else \
+ echo "ChangeLog data not available" > $@; \
+ fi
+
+config.status:
+ @if [ ! -s config.status ]; then \
+ echo "Please run configure first"; \
+ exit 1; \
+ fi
+
+libtool: $(LIBTOOL_DEPS)
+ $(SHELL) ./config.status --recheck
+
+Makefile: $(srcdir)/Makefile.in
+ ./config.status --file Makefile
+
+sync-po: rsync-po compile-po
+
+rsync-po:
+ rsync -Lrtvz translationproject.org::tp/latest/sudo/ po/
+ rsync -Lrtvz translationproject.org::tp/latest/sudoers/ plugins/sudoers/po/
+
+update-pot:
+ @if $(XGETTEXT) --help >/dev/null 2>&1; then \
+ cd $(top_srcdir); \
+ for pot in $(POTFILES); do \
+ echo "Updating $$pot"; \
+ domain=`basename $$pot .pot`; \
+ case "$$domain" in \
+ sudo) tmpfiles=; cfiles="src/*c lib/*/*c";; \
+ sudoers) \
+ echo "gettext \"syntax error\"" > confstr.sh; \
+ $(SED) -n 's/^.*--with-passprompt=\(.*\)$$/gettext \"\1\"/p' mkpkg | sort -u >> confstr.sh; \
+ $(SED) -n -e 's/^badpass_message="/gettext "/p' \
+ -e 's/^passprompt="/gettext "/p' \
+ -e 's/^mailsub="/gettext "/p' configure.ac \
+ >> confstr.sh; \
+ tmpfiles=confstr.sh; \
+ cfiles="plugins/sudoers/*.c plugins/sudoers/auth/*.c";; \
+ *) echo unknown domain $$domain; continue;; \
+ esac; \
+ $(XGETTEXT) $(XGETTEXT_OPTS) -d$$domain $$cfiles $$tmpfiles -o $$pot.tmp; \
+ test -n "$$tmpfiles" && rm -f $$tmpfiles; \
+ if diff -I'^.POT-Creation-Date' -I'^.Project-Id-Version' -I'^#' $$pot.tmp $$pot >/dev/null; then \
+ rm -f $$pot.tmp; \
+ else \
+ printf '/^#$$/+1,$$d\nw\nq\n' | ed - $$pot; \
+ $(SED) '1,/^#$$/d' $$pot.tmp >> $$pot; \
+ rm -f $$pot.tmp; \
+ fi; \
+ done; \
+ else \
+ echo "Unable to update .pot files: $(XGETTEXT) not found" 1>&2; \
+ fi
+
+update-po: update-pot
+ @if $(MSGFMT) --help >/dev/null 2>&1; then \
+ cd $(top_srcdir); \
+ for pot in $(POTFILES); do \
+ podir=`dirname $$pot`; \
+ for po in $$podir/*.po; do \
+ echo $(ECHO_N) "Updating $$po$(ECHO_C)"; \
+ $(MSGMERGE) --update $$po $$pot; \
+ $(MSGFMT) --output /dev/null --check-format $$po || exit 1; \
+ done; \
+ done; \
+ else \
+ echo "Unable to update .po files: $(MSGFMT) not found" 1>&2; \
+ fi
+
+compile-po:
+ @if $(MSGFMT) --help >/dev/null 2>&1; then \
+ cd $(top_srcdir); \
+ rm -f Makefile.$$$$; \
+ POFILES=""; \
+ for pot in $(POTFILES); do \
+ podir=`dirname $$pot`; \
+ for po in $$podir/*.po; do \
+ POFILES="$$POFILES $$po"; \
+ done; \
+ done; \
+ echo "all: `echo $$POFILES | $(SED) 's/\.po/.mo/g'`" >> Makefile.$$$$; \
+ echo "" >> Makefile.$$$$; \
+ for po in $$POFILES; do \
+ mo=`echo $$po | $(SED) 's/po$$/mo/'`; \
+ echo "$$mo: $$po" >> Makefile.$$$$; \
+ echo " $(MSGFMT) --statistics -c -o $$mo $$po" >> Makefile.$$$$; \
+ done; \
+ $(MAKE) -f Makefile.$$$$; \
+ rm -f Makefile.$$$$; \
+ else \
+ echo "Unable to compile message catalogs: $(MSGFMT) not found" 1>&2; \
+ fi
+
+install-nls:
+ @if test "$(NLS)" = "enabled"; then \
+ for pot in $(POTFILES); do \
+ podir=`dirname $(top_srcdir)/$$pot`; \
+ domain=`basename $$pot .pot`; \
+ SUDO_LINGUAS=$${LINGUAS-"`echo $$podir/*.mo | $(SED) 's:'$$podir'/\([^ ]*\).mo:\1:g'`"}; \
+ echo $(ECHO_N) "Installing $$domain message catalogs:$(ECHO_C)"; \
+ for lang in $$SUDO_LINGUAS; do \
+ test -s $$podir/$$lang.mo || continue; \
+ echo $(ECHO_N) " $$lang$(ECHO_C)"; \
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES; \
+ if test -n "$(LOCALEDIR_SUFFIX)"; then \
+ if test ! -d $(DESTDIR)$(localedir)/$$lang$(LOCALEDIR_SUFFIX); then \
+ ln -s $$lang $(DESTDIR)$(localedir)/$$lang$(LOCALEDIR_SUFFIX); \
+ fi; \
+ fi; \
+ $(INSTALL) $(INSTALL_OWNER) -m 0644 $$podir/$$lang.mo $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$$domain.mo; \
+ done; \
+ echo ""; \
+ done; \
+ fi
+
+check-dist: update-pot compile-po
+ @if test -d $(srcdir)/.hg && cd $(srcdir); then \
+ if test `hg stat -am | wc -l` -ne 0; then \
+ echo "Uncommitted changes" 1>&2; \
+ hg stat -am 1>&2; \
+ exit 1; \
+ fi; \
+ fi
+
+dist: check-dist force-dist
+
+force-dist: ChangeLog $(srcdir)/MANIFEST
+ cd $(top_srcdir) && \
+ pax -w -x ustar -s '/^/$(PACKAGE_TARNAME)-$(VERSION)\//' \
+ -f ../$(PACKAGE_TARNAME)-$(VERSION).tar \
+ `$(SED) 's/[ ].*//' $(srcdir)/MANIFEST` && \
+ gzip -9f ../$(PACKAGE_TARNAME)-$(VERSION).tar && \
+ ls -l ../$(PACKAGE_TARNAME)-$(VERSION).tar.gz
+
+package: $(srcdir)/sudo.pp
+ DESTDIR=`cd $(top_builddir) && pwd`/destdir; rm -rf $$DESTDIR; \
+ $(MAKE) install INSTALL_OWNER= DESTDIR=$$DESTDIR && \
+ $(SHELL) $(srcdir)/pp $(PPFLAGS) \
+ --destdir=$$DESTDIR \
+ $(srcdir)/sudo.pp \
+ prefix=$(prefix) \
+ bindir=$(bindir) \
+ sbindir=$(sbindir) \
+ libexecdir=$(libexecdir) \
+ includedir=$(includedir) \
+ vardir=$(vardir) \
+ rundir=$(rundir) \
+ mandir=$(mandir) \
+ localedir=$(localedir) \
+ docdir=$(docdir) \
+ exampledir=$(exampledir) \
+ sysconfdir=$(sysconfdir) \
+ sudoersdir=$(sudoersdir) \
+ sudoers_uid=$(sudoers_uid) \
+ sudoers_gid=$(sudoers_gid) \
+ sudoers_mode=$(sudoers_mode) \
+ shlib_mode=$(shlib_mode) \
+ version=$(VERSION) $(PPVARS)
+
+clean: config.status
+ for d in $(SUBDIRS) $(SAMPLES); do \
+ (cd $$d && exec $(MAKE) $@); \
+ done
+ -rm -rf cov-int cov-int.tgz
+
+mostlyclean: clean
+
+distclean: config.status
+ for d in $(SUBDIRS) $(SAMPLES); do \
+ (cd $$d && exec $(MAKE) $@); \
+ done
+ -rm -rf autom4te.cache config.cache config.h config.log config.status \
+ init.d/*.sh init.d/sudo.conf libtool Makefile pathnames.h stamp-*
+
+cleandir: distclean
+
+clobber: distclean
+
+realclean: distclean
+
+me:
+
+a:
+
+sandwich:
+ @if test -n "$$SUDO_USER"; then \
+ echo "Okay."; \
+ else \
+ echo "What? Make it yourself!"; \
+ fi
+
+.PHONY: ChangeLog me a sandwhich
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..0c458b7
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,2644 @@
+What's new in Sudo 1.8.27
+
+ * On HP-UX, sudo will now update the utmps file when running a command
+ in a pseudo-tty. Previously, only the utmp and utmpx files were
+ updated.
+
+ * Nanosecond precision file time stamps are now supported in HP-UX.
+
+ * Fixes and clarifications to the sudo plugin documentation.
+
+ * The sudo manuals no longer require extensive post-processing to
+ hide system-specific features. Conditionals in the roff source
+ are now used instead. This fixes corruption of the sudo manual
+ on systems without BSD login classes. Bug #861.
+
+ * If an I/O logging plugin is configured but the plugin does not
+ actually log any I/O, sudo will no longer force the command to
+ be run in a pseudo-tty.
+
+ * The fix for bug #843 in sudo 1.8.24 was incomplete. If the
+ user's password was expired or needed to be updated, but no sudo
+ password was required, the PAM handle was freed too early,
+ resulting in a failure when processing PAM session modules.
+
+ * In visudo, it is now possible to specify the path to sudoers
+ without using the -f option. Bug #864.
+
+ * Fixed a bug introduced in sudo 1.8.22 where the utmp (or utmpx)
+ file would not be updated when a command was run in a pseudo-tty.
+ Bug #865.
+
+ * Sudo now sets the silent flag when opening the PAM session except
+ when running a shell via "sudo -s" or "sudo -i". This prevents
+ the pam_lastlog module from printing the last login information
+ for each sudo command. Bug #867.
+
+ * Fixed the default AIX hard resource limit for the maximum number
+ of files a user may have open. If no hard limit for "nofiles"
+ is explicitly set in /etc/security/limits, the default should
+ be "unlimited". Previously, the default hard limit was 8196.
+
+What's new in Sudo 1.8.26
+
+ * Fixed a bug in cvtsudoers when converting to JSON format when
+ alias expansion is enabled. Bug #853.
+
+ * Sudo no long sets the USERNAME environment variable when running
+ commands. This is a non-standard environment variable that was
+ set on some older Linux systems.
+
+ * Sudo now treats the LOGNAME and USER environment variables (as
+ well as the LOGIN variable on AIX) as a single unit. If one is
+ preserved or removed from the environment using env_keep, env_check
+ or env_delete, so is the other.
+
+ * Added support for OpenLDAP's TLS_REQCERT setting in ldap.conf.
+
+ * Sudo now logs when the command was suspended and resumed in the
+ I/O logs. This information is used by sudoreplay to skip the
+ time suspended when replaying the session unless the new -S flag
+ is used.
+
+ * Fixed documentation problems found by the igor utility. Bug #854.
+
+ * Sudo now prints a warning message when there is an error or end
+ of file while reading the password instead of exiting silently.
+
+ * Fixed a bug in the sudoers LDAP back-end parsing the command_timeout,
+ role, type, privs and limitprivs sudoOptions. This also affected
+ cvtsudoers conversion from LDIF to sudoers or JSON.
+
+ * Fixed a bug that prevented timeout settings in sudoers from
+ functioning unless a timeout was also specified on the command
+ line.
+
+ * Asturian translation for sudo from translationproject.org.
+
+ * When generating LDIF output, cvtsudoers can now be configured
+ to pad the sudoOrder increment such that the start order is used
+ as a prefix. Bug #856.
+
+ * Fixed a bug introduced in sudo 1.8.25 that prevented sudo from
+ properly setting the user's groups on AIX. Bug #857.
+
+ * If the user specifies a group via sudo's -g option that matches
+ any of the target user's groups, it is now allowed even if no
+ groups are present in the Runas_Spec. Previously, it was only
+ allowed if it matched the target user's primary group.
+
+ * The sudoers LDAP back-end now supports negated sudoRunAsUser and
+ sudoRunAsGroup entries.
+
+ * Sudo now provides a proper error message when the "fqdn" sudoers
+ option is set and it is unable to resolve the local host name.
+ Bug #859.
+
+ * Portuguese translation for sudo and sudoers from translationproject.org.
+
+ * Sudo now includes sudoers LDAP schema for the on-line configuration
+ supported by OpenLDAP.
+
+What's new in Sudo 1.8.25p1
+
+ * Fixed a bug introduced in sudo 1.8.25 that caused a crash on
+ systems that have the poll() function but not the ppoll() function.
+ Bug #851.
+
+What's new in Sudo 1.8.25
+
+ * Fixed a bug introduced in sudo 1.8.20 that broke formatting of
+ I/O log timing file entries on systems without a C99-compatible
+ snprintf() function. Our replacement snprintf() doesn't support
+ floating point so we can't use the "%f" format directive.
+
+ * I/O log timing file entries now use a monotonic timer and include
+ nanosecond precision. A monotonic timer that does not increment
+ while the system is sleeping is used where available.
+
+ * Fixed a bug introduced in sudo 1.8.24 where sudoNotAfter in the LDAP
+ backend was not being properly parsed. Bug #845.
+
+ * When sudo runs a command in a pseudo-tty, the slave device is
+ now closed in the main process immediately after starting the
+ monitor process. This removes the need for an AIX-specific
+ workaround that was added in sudo 1.8.24.
+
+ * Added support for monotonic timers on HP-UX.
+
+ * Fixed a bug displaying timeout values the "sudo -V" output.
+ The value displayed was 3600 times the actual value. Bug #846.
+
+ * Fixed a build issue on AIX 7.1 BOS levels that include memset_s()
+ and define rsize_t in string.h. Bug #847.
+
+ * The testsudoers utility now supports querying an LDIF-format
+ policy.
+
+ * Sudo now sets the LOGIN environment variable to the same value as
+ LOGNAME on AIX systems. Bug #848.
+
+ * Fixed a regression introduced in sudo 1.8.24 where the LDAP and
+ SSSD backends evaluated the rules in reverse sudoOrder. Bug #849.
+
+What's new in Sudo 1.8.24
+
+ * The LDAP and SSS back-ends now use the same rule evaluation code
+ as the sudoers file backend. This builds on the work in sudo
+ 1.8.23 where the formatting functions for "sudo -l" output were
+ shared. The handling of negated commands in SSS and LDAP is
+ unchanged.
+
+ * Fixed a regression introduced in 1.8.23 where "sudo -i" could
+ not be used in conjunction with --preserve-env=VARIABLE. Bug #835.
+
+ * cvtsudoers can now parse base64-encoded attributes in LDIF files.
+
+ * Random insults are now more random.
+
+ * Fixed the noexec wordexp(3) test on FreeBSD.
+
+ * Added SUDO_CONV_PREFER_TTY flag for conversation function to
+ tell sudo to try writing to /dev/tty first. Can be used in
+ conjunction with SUDO_CONV_INFO_MSG and SUDO_CONV_ERROR_MSG.
+
+ * Sudo now supports an arbitrary number of groups per user on
+ Solaris. Previously, only the first 64 groups were found.
+ This should remove the need to set "max_groups" in sudo.conf.
+
+ * Fixed typos in the OpenLDAP sudo schema. Bugs #839 and #840.
+
+ * Fixed a race condition when building with parallel make.
+ Bug #842.
+
+ * Fixed a duplicate free when netgroup_base in ldap.conf is set
+ to an invalid value.
+
+ * Fixed a bug introduced in sudo 1.8.23 on AIX that could prevent
+ local users and groups from being resolved properly on systems
+ that have users stored in NIS, LDAP or AD.
+
+ * Added a workaround for an AIX bug exposed by a change in sudo
+ 1.8.23 that prevents the terminal mode from being restored when
+ I/O logging is enabled.
+
+ * On systems using PAM, sudo now ignores the PAM_NEW_AUTHTOK_REQD
+ and PAM_AUTHTOK_EXPIRED errors from PAM account management if
+ authentication is disabled for the user. This fixes a regression
+ introduced in sudo 1.8.23. Bug #843.
+
+ * Fixed an ambiguity in the sudoers manual in the description and
+ definition of User, Runas, Host, and Cmnd Aliases. Bug #834.
+
+ * Fixed a bug that resulted in only the first window size change
+ event being logged.
+
+ * Fixed a bug on HP-UX systems introduced in sudo 1.8.22 that
+ caused sudo to prompt for a password every time when tty-based
+ time stamp files were in use.
+
+ * Fixed a compilation problem on systems that define O_PATH or
+ O_SEARCH in fnctl.h but do not define O_DIRECTORY. Bug #844.
+
+What's new in Sudo 1.8.23
+
+ * PAM account management modules and BSD auth approval modules are
+ now run even when no password is required.
+
+ * For kernel-based time stamps, if no terminal is present, fall
+ back to parent-pid style time stamps.
+
+ * The new cvtsudoers utility replaces both the "sudoers2ldif" script
+ and the "visudo -x" functionality. It can read a file in either
+ sudoers or LDIF format and produce JSON, LDIF or sudoers output.
+ It is also possible to filter the generated output file by user,
+ group or host name.
+
+ * The file, ldap and sss sudoers backends now share a common set
+ of formatting functions for "sudo -l" output, which is also used
+ by the cvtsudoers utility.
+
+ * The /run directory is now used in preference to /var/run if it
+ exists. Bug #822.
+
+ * More accurate descriptions of the --with-rundir and --with-vardir
+ configure options. Bug #823.
+
+ * The setpassent() and setgroupent() functions are now used on systems
+ that support them to keep the passwd and group database open.
+ Sudo performs a lot of passwd and group lookups so it can be
+ beneficial to avoid opening and closing the files each time.
+
+ * The new case_insensitive_user and case_insensitive_group sudoers
+ options can be used to control whether sudo does case-sensitive
+ matching of users and groups in sudoers. Case insensitive
+ matching is now the default.
+
+ * Fixed a bug on some systems where sudo could hang on command
+ exit when I/O logging was enabled. Bug #826.
+
+ * Fixed the build-time process start time test on Linux when the
+ test is run from within a container. Bug #829.
+
+ * When determining which temporary directory to use, sudoedit now
+ checks the directory for writability before using it. Previously,
+ sudoedit only performed an existence check. Bug #827.
+
+ * Sudo now includes an optional set of Monty Python-inspired insults.
+
+ * Fixed the execution of scripts with an associated digest (checksum)
+ in sudoers on FreeBSD systems. FreeBSD does not have a proper
+ /dev/fd directory mounted by default and its fexecve(2) is not
+ fully POSIX compliant when executing scripts. Bug #831.
+
+ * Chinese (Taiwan) translation for sudo from translationproject.org.
+
+What's new in Sudo 1.8.22
+
+ * Commands run in the background from a script run via sudo will
+ no longer receive SIGHUP when the parent exits and I/O logging
+ is enabled. Bug #502
+
+ * A particularly offensive insult is now disabled by default.
+ Bug #804
+
+ * The description of "sudo -i" now correctly documents that
+ the "env_keep" and "env_check" sudoers options are applied to
+ the environment. Bug #806
+
+ * Fixed a crash when the system's host name is not set.
+ Bug #807
+
+ * The sudoers2ldif script now handles #include and #includedir
+ directives.
+
+ * Fixed a bug where sudo would silently exit when the command was
+ not allowed by sudoers and the "passwd_tries" sudoers option
+ was set to a value less than one.
+
+ * Fixed a bug with the "listpw" and "verifypw" sudoers options and
+ multiple sudoers sources. If the option is set to "all", a
+ password should be required unless none of a user's sudoers
+ entries from any source require authentication.
+
+ * Fixed a bug with the "listpw" and "verifypw" sudoers options in
+ the LDAP and SSSD back-ends. If the option is set to "any", and
+ the entry contained multiple rules, only the first matching rule
+ was checked. If an entry contained more than one matching rule
+ and the first rule required authentication but a subsequent rule
+ did not, sudo would prompt for a password when it should not have.
+
+ * When running a command as the invoking user (not root), sudo
+ would execute the command with the same group vector it was
+ started with. Sudo now executes the command with a new group
+ vector based on the group database which is consistent with
+ how su(1) operates.
+
+ * Fixed a double free in the SSSD back-end that could occur when
+ ipa_hostname is present in sssd.conf and is set to an unqualified
+ host name.
+
+ * When I/O logging is enabled, sudo will now write to the terminal
+ even when it is a background process. Previously, sudo would
+ only write to the tty when it was the foreground process when
+ I/O logging was enabled. If the TOSTOP terminal flag is set,
+ sudo will suspend the command (and then itself) with the SIGTTOU
+ signal.
+
+ * A new "authfail_message" sudoers option that overrides the
+ default "N incorrect password attempt(s)".
+
+ * An empty sudoRunAsUser attribute in the LDAP and SSSD backends
+ will now match the invoking user. This is more consistent with
+ how an empty runas user in the sudoers file is treated.
+
+ * Documented that in check mode, visudo does not check the owner/mode
+ on files specified with the -f flag. Bug #809.
+
+ * It is now an error to specify the runas user as an empty string
+ on the command line. Previously, an empty runas user was treated
+ the same as an unspecified runas user. Bug #817.
+
+ * When "timestamp_type" option is set to "tty" and a terminal is
+ present, the time stamp record will now include the start time
+ of the session leader. When the "timestamp_type" option is set
+ to "ppid" or when no terminal is available, the start time of
+ the parent process is used instead. This significantly reduces
+ the likelihood of a time stamp record being re-used when a user
+ logs out and back in again. Bug #818.
+
+ * The sudoers time stamp file format is now documented in the new
+ sudoers_timestamp manual.
+
+ * The "timestamp_type" option now takes a "kernel" value on OpenBSD
+ systems. This causes the tty-based time stamp to be stored in
+ the kernel instead of on the file system. If no tty is present,
+ the time stamp is considered to be invalid.
+
+ * Visudo will now use the SUDO_EDITOR environment variable (if
+ present) in addition to VISUAL and EDITOR.
+
+What's new in Sudo 1.8.21p2
+
+ * Fixed a bug introduced in version 1.8.21 which prevented sudo
+ from using the PAM-supplied prompt. Bug #799
+
+ * Fixed a bug introduced in version 1.8.21 which could result in
+ sudo hanging when running commands that exit quickly. Bug #800
+
+ * Fixed a bug introduced in version 1.8.21 which prevented the
+ command from being run when the password was read via an external
+ program using the askpass interface. Bug #801
+
+What's new in Sudo 1.8.21p1
+
+ * On systems that support both PAM and SIGINFO, the main sudo
+ process will no longer forward SIGINFO to the command if the
+ signal was generated from the keyboard. The command will have
+ already received SIGINFO since it is part of the same process
+ group so there's no need for sudo to forward it. This is
+ consistent with the handling of SIGINT, SIGQUIT and SIGTSTP.
+ Bug #796
+
+ * If SUDOERS_SEARCH_FILTER in ldap.conf does not specify a value,
+ the LDAP search expression used when looking up netgroups and
+ non-Unix groups had a syntax error if a group plugin was not
+ specified.
+
+ * "sudo -U otheruser -l" will now have an exit value of 0 even
+ if "otheruser" has no sudo privileges. The exit value when a
+ user attempts to lists their own privileges or when a command
+ is specified is unchanged.
+
+ * Fixed a regression introduced in sudo 1.8.21 where sudoreplay
+ playback would hang for I/O logs that contain terminal input.
+
+ * Sudo 1.8.18 contained an incomplete fix for the matching of
+ entries in the LDAP and SSSD back-ends when a sudoRunAsGroup is
+ specified but no sudoRunAsUser is present in the sudoRole.
+
+What's new in Sudo 1.8.21
+
+ * The path that sudo uses to search for terminal devices can now
+ be configured via the new "devsearch" Path setting in sudo.conf.
+
+ * It is now possible to preserve bash shell functions in the
+ environment when the "env_reset" sudoers setting is disabled by
+ removing the "*=()*" pattern from the env_delete list.
+
+ * A change made in sudo 1.8.15 inadvertantly caused sudoedit to
+ send itself SIGHUP instead of exiting when the editor returns
+ an error or the file was not modified.
+
+ * Sudoedit now uses an exit code of zero if the file was not
+ actually modified. Previously, sudoedit treated a lack of
+ modifications as an error.
+
+ * When running a command in a pseudo-tty (pty), sudo now copies a
+ subset of the terminal flags to the new pty. Previously, all
+ flags were copied, even those not appropriate for a pty.
+
+ * Fixed a problem with debug logging in the sudoers I/O logging
+ plugin.
+
+ * Window size change events are now logged to the policy plugin.
+ On xterm and compatible terminals, sudoreplay is now capable of
+ resizing the terminal to match the size of the terminal the
+ command was run on. The new -R option can be used to disable
+ terminal resizing.
+
+ * Fixed a bug in visudo where a newly added file was not checked
+ for syntax errors. Bug #791.
+
+ * Fixed a bug in visudo where if a syntax error in an include
+ directory (like /etc/sudoers.d) was detected, the edited version
+ was left as a temporary file instead of being installed.
+
+ * On PAM systems, sudo will now treat "username's Password:" as
+ a standard password prompt. As a result, the SUDO_PROMPT
+ environment variable will now override "username's Password:"
+ as well as the more common "Password:". Previously, the
+ "passprompt_override" Defaults setting would need to be set for
+ SUDO_PROMPT to override a prompt of "username's Password:".
+
+ * A new "syslog_pid" sudoers setting has been added to include
+ sudo's process ID along with the process name when logging via
+ syslog. Bug #792.
+
+ * Fixed a bug introduced in sudo 1.8.18 where a command would
+ not be terminated when the I/O logging plugin returned an error
+ to the sudo front-end.
+
+ * A new "timestamp_type" sudoers setting has been added that replaces
+ the "tty_tickets" option. In addition to tty and global time stamp
+ records, it is now possible to use the parent process ID to restrict
+ the time stamp to commands run by the same process, usually the shell.
+ Bug #793.
+
+ * The --preserve-env command line option has been extended to accept
+ a comma-separated list of environment variables to preserve.
+ Bug #279.
+
+ * Friulian translation for sudo from translationproject.org.
+
+What's new in Sudo 1.8.20p2
+
+ * Fixed a bug parsing /proc/pid/stat on Linux when the process
+ name contains newlines. This is not exploitable due to the /dev
+ traversal changes in sudo 1.8.20p1.
+
+What's new in Sudo 1.8.20p1
+
+ * Fixed "make check" when using OpenSSL or GNU crypt.
+ Bug #787.
+
+ * Fixed CVE-2017-1000367, a bug parsing /proc/pid/stat on Linux
+ when the process name contains spaces. Since the user has control
+ over the command name, this could potentially be used by a user
+ with sudo access to overwrite an arbitrary file on systems with
+ SELinux enabled. Also stop performing a breadth-first traversal
+ of /dev when looking for the device; only a hard-coded list of
+ directories are checked,
+
+What's new in Sudo 1.8.20
+
+ * Added support for SASL_MECH in ldap.conf. Bug #764
+
+ * Added support for digest matching when the command is a glob-style
+ pattern or a directory. Previously, only explicit path matches
+ supported digest checks.
+
+ * New "fdexec" Defaults option to control whether a command
+ is executed by path or by open file descriptor.
+
+ * The embedded copy of zlib has been upgraded to version 1.2.11.
+
+ * Fixed a bug that prevented sudoers include files with a relative
+ path starting with the letter 'i' from being opened. Bug #776.
+
+ * Added support for command timeouts in sudoers. The command will
+ be terminated if the timeout expires.
+
+ * The SELinux role and type are now displayed in the "sudo -l"
+ output for the LDAP and SSSD back-ends, just as they are in the
+ sudoers back-end.
+
+ * A new command line option, -T, can be used to specify a command
+ timeout as long as the user-specified timeout is not longer than
+ the timeout specified in sudoers. This option may only be
+ used when the "user_command_timeouts" flag is enabled in sudoers.
+
+ * Added NOTBEFORE and NOTAFTER command options to the sudoers
+ back-end similar to what is already available in the LDAP back-end.
+
+ * Sudo can now optionally use the SHA2 functions in OpenSSL or GNU
+ crypt instead of the SHA2 implementation bundled with sudo.
+
+ * Fixed a compilation error on systems without the stdbool.h header
+ file. Bug #778.
+
+ * Fixed a compilation error in the standalone Kerberos V authentication
+ module. Bug #777.
+
+ * Added the iolog_flush flag to sudoers which causes I/O log data
+ to be written immediately to disk instead of being buffered.
+
+ * I/O log files are now created with group ID 0 by default unless
+ the "iolog_user" or "iolog_group" options are set in sudoers.
+
+ * It is now possible to store I/O log files on an NFS-mounted
+ file system where uid 0 is remapped to an unprivileged user.
+ The "iolog_user" option must be set to a non-root user and the
+ top-level I/O log directory must exist and be owned by that user.
+
+ * Added the restricted_env_file setting to sudoers which is similar
+ to env_file but its contents are subject to the same restrictions
+ as variables in the invoking user's environment.
+
+ * Fixed a use after free bug in the SSSD back-end when the fqdn
+ sudoOption is enabled and no hostname value is present in
+ /etc/sssd/sssd.conf.
+
+ * Fixed a typo that resulted in a compilation error on systems
+ where the killpg() function is not found by configure.
+
+ * Fixed a compilation error with the included version of zlib
+ when sudo was built outside the source tree.
+
+ * Fixed the exit value of sudo when the command is terminated by
+ a signal other than SIGINT. This was broken in sudo 1.8.15 by
+ the fix for Bug #722. Bug #784.
+
+ * Fixed a regression introduced in sudo 1.8.18 where the "lecture"
+ option could not be used in a positive boolean context, only
+ a negative one.
+
+ * Fixed an issue where sudo would consume stdin if it was not
+ connected to a tty even if log_input is not enabled in sudoers.
+ Bug #786.
+
+ * Clarify in the sudoers manual that the #includedir directive
+ diverts control to the files in the specified directory and,
+ when parsing of those files is complete, returns control to the
+ original file. Bug #775.
+
+What's new in Sudo 1.8.19p2
+
+ * Fixed a crash in visudo introduced in sudo 1.8.9 when an IP address
+ or network is used in a host-based Defaults entry. Bug #766
+
+ * Added a missing check for the ignore_iolog_errors flag when
+ the sudoers plugin generates the I/O log file path name.
+
+ * Fixed a typo in sudo's vsyslog() replacement that resulted in
+ garbage being logged to syslog.
+
+What's new in Sudo 1.8.19p1
+
+ * Fixed a bug introduced in sudo 1.8.19 that resulted in the wrong
+ syslog priority and facility being used.
+
+What's new in Sudo 1.8.19
+
+ * New "syslog_maxlen" Defaults option to control the maximum size of
+ syslog messages generated by sudo.
+
+ * Sudo has been run against PVS-Studio and any issues that were
+ not false positives have been addressed.
+
+ * I/O log files are now created with the same group ID as the
+ parent directory and not the invoking user's group ID.
+
+ * I/O log permissions and ownership are now configurable via the
+ "iolog_mode", "iolog_user" and "iolog_group" sudoers Defaults
+ variables.
+
+ * Fixed configuration of the sudoers I/O log plugin debug subsystem.
+ Previously, I/O log information was not being written to the
+ sudoers debug log.
+
+ * Fixed a bug in visudo that broke editing of files in an include
+ dir that have a syntax error. Normally, visudo does not edit
+ those files, but if a syntax error is detected in one, the user
+ should get a chance to fix it.
+
+ * Warnings about unknown or unparsable sudoers Defaults entries now
+ include the file and line number of the problem.
+
+ * Visudo will now use the file and line number information about an
+ unknown or unparsable Defaults entry to go directly to the file
+ with the problem.
+
+ * Fixed a bug in the sudoers LDAP back-end where a negated sudoHost
+ entry would prevent other sudoHost entries following it from matching.
+
+ * Warnings from visudo about a cycle in an Alias entry now include the
+ file and line number of the problem.
+
+ * In strict mode, visudo will now use the file and line number
+ information about a cycle in an Alias entry to go directly to the
+ file with the problem.
+
+ * The sudo_noexec.so file is now linked with -ldl on systems that
+ require it for the wordexp() wrapper.
+
+ * Fixed linking of sudo_noexec.so on macOS systems where it must be
+ a dynamic library and not a module.
+
+ * Sudo's "make check" now includes a test for sudo_noexec.so
+ working.
+
+ * The sudo front-end now passes the user's umask to the plugin.
+ Previously the plugin had to determine this itself.
+
+ * Sudoreplay can now display the stdin and ttyin streams when they
+ are explicitly added to the filter list.
+
+ * Fixed a bug introduced in sudo 1.8.17 where the "all" setting
+ for verifypw and listpw was not being honored. Bug #762.
+
+ * The syslog priority (syslog_goodpri and syslog_badpri) can now
+ be negated or set to "none" to disable logging of successful or
+ unsuccessful sudo attempts via syslog.
+
+What's new in Sudo 1.8.18p1
+
+ * When sudo_noexec.so is used, the WRDE_NOCMD flag is now added
+ if the wordexp() function is called. This prevents commands
+ from being run via wordexp() without disabling it entirely.
+
+ * On Linux systems, sudo_noexec.so now uses a seccomp filter to
+ disable execute access if the kernel supports seccomp. This is
+ more robust than the traditional method of using stub functions
+ that return an error.
+
+What's new in Sudo 1.8.18
+
+ * The sudoers locale is now set before parsing the sudoers file.
+ If sudoers_locale is set in sudoers, it is applied before
+ evaluating other Defaults entries. Previously, sudoers_locale
+ was used when evaluating sudoers but not during the inital parse.
+ Bug #748.
+
+ * A missing or otherwise invalid #includedir is now ignored instead
+ of causing a parse error.
+
+ * During "make install", backup files are only used on HP-UX where
+ it is not possible to unlink a shared object that is in use.
+ This works around a bug in ldconfig on Linux which could create
+ links to the backup shared library file instead of the current
+ one.
+
+ * Fixed a bug introduced in 1.8.17 where sudoers entries with long
+ commands lines could be truncated, preventing a match. Bug #752.
+
+ * The fqdn, runas_default and sudoers_locale Defaults settings are
+ now applied before any other Defaults settings since they can
+ change how other Defaults settings are parsed.
+
+ * On systems without the O_NOFOLLOW open(2) flag, when the NOFOLLOW
+ flag is set, sudoedit now checks whether the file is a symbolic link
+ before opening it as well as after the open. Bug #753.
+
+ * Sudo will now only resolve a user's group IDs to group names
+ when sudoers includes group-based permissions. Group lookups
+ can be expensive on some systems where the group database is
+ not local.
+
+ * If the file system holding the sudo log file is full, allow
+ the command to run unless the new ignore_logfile_errors Defaults
+ option is disabled. Bug #751.
+
+ * The ignore_audit_errors and ignore_iolog_errors Defaults options
+ have been added to control sudo's behavior when it is unable to
+ write to the audit and I/O logs.
+
+ * Fixed a bug introduced in 1.8.17 where the SIGPIPE signal handler
+ was not being restored when sudo directly executes the command.
+
+ * Fixed a bug where "sudo -l command" would indicate that a command
+ was runnable even when denied by sudoers when using the LDAP or
+ SSSD back-ends.
+
+ * The match_group_by_gid Defaults option has been added to allow
+ sites where group name resolution is slow and where sudoers only
+ contains a small number of groups to match groups by group ID
+ instead of by group name.
+
+ * Fixed a bug on Linux where a 32-bit sudo binary could fail with
+ an "unable to allocate memory" error when run on a 64-bit system.
+ Bug #755
+
+ * When parsing ldap.conf, sudo will now only treat a '#' character
+ as the start of a comment when it is at the beginning of the
+ line.
+
+ * Fixed a potential crash when auditing is enabled and the audit
+ function fails with an error. Bug #756
+
+ * Norwegian Nynorsk translation for sudo from translationproject.org.
+
+ * Fixed a typo that broke short host name matching when the fqdn
+ flag is enabled in sudoers. Bug #757
+
+ * Negated sudoHost attributes are now supported by the LDAP and
+ SSSD back-ends.
+
+ * Fixed matching entries in the LDAP and SSSD back-ends when a
+ RunAsGroup is specified but no RunAsUser is present.
+
+ * Fixed "sudo -l" output in the LDAP and SSSD back-ends when a
+ RunAsGroup is specified but no RunAsUser is present.
+
+What's new in Sudo 1.8.17p1
+
+ * Fixed a bug introduced in 1.8.17 where the user's groups were
+ not set on systems that don't use PAM. Bug #749.
+
+What's new in Sudo 1.8.17
+
+ * On AIX, if /etc/security/login.cfg has auth_type set to PAM_AUTH
+ but pam_start(3) fails, fall back to AIX authentication.
+ Bug #740.
+
+ * Sudo now takes all sudoers sources into account when determining
+ whether or not "sudo -l" or "sudo -v" should prompt for a password.
+ In other words, if both file and ldap sudoers sources are in
+ specified in /etc/nsswitch.conf, "sudo -v" will now require that
+ all entries in both sources be have NOPASSWD (file) or !authenticate
+ (ldap) in the entries.
+
+ * Sudo now ignores SIGPIPE until the command is executed. Previously,
+ SIGPIPE was only ignored in a few select places. Bug #739.
+
+ * Fixed a bug introduced in sudo 1.8.14 where (non-syslog) log
+ file entries were missing the newline when loglinelen is set to
+ a non-positive number. Bug #742.
+
+ * Unix groups are now set before the plugin session intialization
+ code is run. This makes it possible to use dynamic groups with
+ the Linux-PAM pam_group module.
+
+ * Fixed a bug where a debugging statement could dereference a NULL
+ pointer when looking up a group that doesn't exist. Bug #743.
+
+ * Sudo has been run through the Coverity code scanner. A number of
+ minor bugs have been fixed as a result. None were security issues.
+
+ * SELinux support, which was broken in 1.8.16, has been repaired.
+
+ * Fixed a bug when logging I/O where all output buffers might not
+ get flushed at exit.
+
+ * Forward slashes are no longer escaped in the JSON output of
+ "visudo -x". This was never required by the standard and not
+ escaping them improves readability of the output.
+
+ * Sudo no longer treats PAM_SESSION_ERR as a fatal error when
+ opening the PAM session. Other errors from pam_open_session()
+ are still treated as fatal. This avoids the "policy plugin
+ failed session initialization" error message seen on some systems.
+
+ * Korean translation for sudo and sudoers from translationproject.org.
+
+ * Fixed a bug on AIX where the stack size hard resource limit was
+ being set to 2GB instead of 4GB on 64-bit systems.
+
+ * The SSSD back-end now properly supports "sudo -U otheruser -l".
+
+ * The SSSD back-end now uses the value of "ipa_hostname"
+ from sssd.conf, if specified, when matching the host name.
+
+ * Fixed a hang on some systems when the command is being run in
+ a pty and it failed to execute.
+
+ * When performing a wildcard match in sudoers, check for an exact
+ string match if the user command was fully-qualified (or resolved
+ via the PATH). This fixes an issue executing scripts on Linux
+ when there are multiple wildcard matches with the same base name.
+ Bug #746.
+
+What's new in Sudo 1.8.16
+
+ * Fixed a compilation error on Solaris 10 with Stun Studio 12.
+ Bug #727.
+
+ * When preserving variables from the invoking user's environment, if
+ there are duplicates sudo now only keeps the first instance.
+
+ * Fixed a bug that could cause warning mail to be sent in list
+ mode (sudo -l) for users without sudo privileges when the
+ LDAP and sssd back-ends are used.
+
+ * Fixed a bug that prevented the "mail_no_user" option from working
+ properly with the LDAP back-end.
+
+ * In the LDAP and sssd back-ends, white space is now ignored between
+ an operator (!, +, +=, -=) when parsing a sudoOption.
+
+ * It is now possible to disable Path settings in sudo.conf
+ by omitting the path name.
+
+ * The sudoedit_checkdir Defaults option is now enabled by default
+ and has been extended. When editing files with sudoedit, each
+ directory in the path to be edited is now checked. If a directory
+ is writable by the invoking user, symbolic links will not be
+ followed. If the parent directory of the file to be edited is
+ writable, sudoedit will refuse to edit it.
+ Bug #707.
+
+ * The netgroup_tuple Defaults option has been added to enable matching
+ of the entire netgroup tuple, not just the host or user portion.
+ Bug #717.
+
+ * When matching commands based on the SHA2 digest, sudo will now
+ use fexecve(2) to execute the command if it is available. This
+ fixes a time of check versus time of use race condition when the
+ directory holding the command is writable by the invoking user.
+
+ * On AIX systems, sudo now caches the auth registry string along
+ with password and group information. This fixes a potential
+ problem when a user or group of the same name exists in multiple
+ auth registries. For example, local and LDAP.
+
+ * Fixed a crash in the SSSD back-end when the invoking user is not
+ found. Bug #732.
+
+ * Added the --enable-asan configure flag to enable address sanitizer
+ support. A few minor memory leaks have been plugged to quiet
+ the ASAN leak detector.
+
+ * The value of _PATH_SUDO_CONF may once again be overridden via
+ the Makefile. Bug #735.
+
+ * The sudoers2ldif script now handles multiple roles with same name.
+
+ * Fixed a compilation error on systems that have the posix_spawn()
+ and posix_spawnp() functions but an unusable spawn.h header.
+ Bug #730.
+
+ * Fixed support for negating character classes in sudo's version
+ of the fnmatch() function.
+
+ * Fixed a bug in the LDAP and SSSD back-ends that could allow an
+ unauthorized user to list another user's privileges. Bug #738.
+
+ * The PAM conversation function now works around an ambiguity in the
+ PAM spec with respect to multiple messages. Bug #726.
+
+What's new in Sudo 1.8.15
+
+ * Fixed a bug that prevented sudo from building outside the source tree
+ on some platforms. Bug #708.
+
+ * Fixed the location of the sssd library in the RHEL/Centos packages.
+ Bug #710.
+
+ * Fixed a build problem on systems that don't implicitly include
+ sys/types.h from other header files. Bug #711.
+
+ * Fixed a problem on Linux using containers where sudo would ignore
+ signals sent by a process in a different container.
+
+ * Sudo now refuses to run a command if the PAM session module
+ returns an error.
+
+ * When editing files with sudoedit, symbolic links will no longer
+ be followed by default. The old behavior can be restored by
+ enabling the sudoedit_follow option in sudoers or on a per-command
+ basis with the FOLLOW and NOFOLLOW tags. Bug #707.
+
+ * Fixed a bug introduced in version 1.8.14 that caused the last
+ valid editor in the sudoers "editor" list to be used by visudo
+ and sudoedit instead of the first. Bug #714.
+
+ * Fixed a bug in visudo that prevented the addition of a final
+ newline to edited files without one.
+
+ * Fixed a bug decoding certain base64 digests in sudoers when the
+ intermediate format included a '=' character.
+
+ * Individual records are now locked in the time stamp file instead
+ of the entire file. This allows sudo to avoid prompting for a
+ password multiple times on the same terminal when used in a
+ pipeline. In other words, "sudo cat foo | sudo grep bar" now
+ only prompts for the password once. Previously, both sudo
+ processes would prompt for a password, often making it impossible
+ to enter.
+
+ * Fixed a bug where sudo would fail to run commands as a non-root
+ user on systems that lack both setresuid() and setreuid().
+ Bug #713.
+
+ * Fixed a bug introduced in sudo 1.8.14 that prevented visudo from
+ re-editing the correct file when a syntax error was detected.
+
+ * Fixed a bug where sudo would not relay a SIGHUP signal to the
+ command when the terminal is closed and the command is not run
+ in its own pseudo-tty. Bug #719
+
+ * If some, but not all, of the LOGNAME, USER or USERNAME environment
+ variables have been preserved from the invoking user's environment,
+ sudo will now use the preserved value to set the remaining variables
+ instead of using the runas user. This ensures that if, for example,
+ only LOGNAME is present in the env_keep list, that sudo will not
+ set USER and USERNAME to the runas user.
+
+* When the command sudo is running dies due to a signal, sudo will
+ now send itself that same signal with the default signal handler
+ installed instead of exiting. The bash shell appears to ignore
+ some signals, e.g. SIGINT, unless the command being run is killed
+ by that signal. This makes the behavior of commands run under
+ sudo the same as without sudo when bash is the shell. Bug #722
+
+ * Slovak translation for sudo from translationproject.org.
+
+ * Hungarian and Slovak translations for sudoers from translationproject.org.
+
+ * Previously, when env_reset was enabled (the default) and the -s
+ option was not used, the SHELL environment variable was set to the
+ shell of the invoking user. Now, when env_reset is enabled and
+ the -s option is not used, SHELL is set based on the target user.
+
+ * Fixed challenge/response style BSD authentication.
+
+ * Added the sudoedit_checkdir Defaults option to prevent sudoedit
+ from editing files located in a directory that is writable by
+ the invoking user.
+
+ * Added the always_query_group_plugin Defaults option to control
+ whether groups not found in the system group database are passed
+ to the group plugin. Previously, unknown system groups were
+ always passed to the group plugin.
+
+ * When creating a new file, sudoedit will now check that the file's
+ parent directory exists before running the editor.
+
+ * Fixed the compiler stack protector test in configure for compilers
+ that support -fstack-protector but don't actually have the ssp
+ library available.
+
+What's new in Sudo 1.8.14p3
+
+ * Fixed a bug introduced in sudo 1.8.14p2 that prevented sudo
+ from working when no tty was present.
+
+ * Fixed tty detection on newer AIX systems where dev_t is 64-bit.
+
+What's new in Sudo 1.8.14p2
+
+ * Fixed a bug introduced in sudo 1.8.14 that prevented the lecture
+ file from being created. Bug #704.
+
+What's new in Sudo 1.8.14p1
+
+ * Fixed a bug introduced in sudo 1.8.14 that prevented the sssd
+ back-end from working. Bug #703.
+
+What's new in Sudo 1.8.14
+
+ * Log messages on Mac OS X now respect sudoers_locale when sudo
+ is build with NLS support.
+
+ * The sudo manual pages now pass "mandoc -Tlint" with no warnings.
+
+ * Fixed a compilation problem on systems with the sig2str() function
+ that do not define SIG2STR_MAX in signal.h.
+
+ * Worked around a compiler bug that resulted in unexpected behavior
+ when returning an int from a function declared to return bool
+ without an explicit cast.
+
+ * Worked around a bug in Mac OS X 10.10 BSD auditing where the
+ au_preselect() fails for AUE_sudo events but succeeds for
+ AUE_DARWIN_sudo.
+
+ * Fixed a hang on Linux systems with glibc when sudo is linked with
+ jemalloc.
+
+ * When the user runs a command as a user ID that is not present in
+ the password database via the -u flag, the command is now run
+ with the group ID of the invoking user instead of group ID 0.
+
+ * Fixed a compilation problem on systems that don't pull in
+ definitions of uid_t and gid_t without sys/types.h or unistd.h.
+
+ * Fixed a compilation problem on newer AIX systems which use a
+ struct st_timespec for time stamps in struct stat that differs
+ from struct timespec. Bug #702.
+
+ * The example directory is now configurable via --with-exampledir
+ and defaults to DATAROOTDIR/examples/sudo on BSD systems.
+
+ * The /usr/lib/tmpfiles.d/sudo.conf file is now installed as part
+ of "make install" when systemd is in use.
+
+ * Fixed a linker problem on some systems with libintl. Bug #690.
+
+ * Fixed compilation with compilers that don't support __func__
+ or __FUNCTION__.
+
+ * Sudo no longer needs to uses weak symbols to support localization
+ in the warning functions. A registration function is used instead.
+
+ * Fixed a setresuid() failure in sudoers on Linux kernels where
+ uid changes take the nproc resource limit into account.
+
+ * Fixed LDAP netgroup queries on AIX.
+
+ * Sudo will now display the custom prompt on Linux systems with PAM
+ even if the "Password: " prompt is not localized by the PAM module.
+ Bug #701.
+
+ * Double-quoted values in an LDAP sudoOption are now supported
+ for consistency with file-based sudoers.
+
+ * Fixed a bug that prevented the btime entry in /proc/stat from
+ being parsed on Linux.
+
+What's new in Sudo 1.8.13
+
+ * The examples directory is now a subdirectory of the doc dir to
+ conform to Debian guidelines. Bug #682.
+
+ * Fixed a compilation error for siglist.c and signame.c on some
+ systems. Bug #686
+
+ * Weak symbols are now used for sudo_warn_gettext() and
+ sudo_warn_strerror() in libsudo_util to avoid link errors when
+ -Wl,--no-undefined is used in LDFLAGS. The --disable-weak-symbols
+ configure option can be used to disable the user of weak symbols.
+
+ * Fixed a bug in sudo's mkstemps() replacement function that
+ prevented the file extension from being preserved in sudoedit.
+
+ * A new mail_all_cmnds sudoers flag will send mail when a user runs
+ a command (or tries to). The behavior of the mail_always flag has
+ been restored to always send mail when sudo is run.
+
+ * New "MAIL" and "NOMAIL" command tags have been added to toggle
+ mail sending behavior on a per-command (or Cmnd_Alias) basis.
+
+ * Fixed matching of empty passwords when sudo is configured to
+ use passwd (or shadow) file authentication on systems where the
+ crypt() function returns NULL for invalid salts.
+
+ * On AIX, sudo now uses the value of the auth_type setting in
+ /etc/security/login.cfg to determine whether to use LAM or PAM
+ for user authentication.
+
+ * The "all" setting for listpw and verifypw now works correctly
+ with LDAP and sssd sudoers.
+
+ * The sudo timestamp directory is now created at boot time on
+ platforms that use systemd.
+
+ * Sudo will now restore the value of the SIGPIPE handler before
+ executing the command.
+
+ * Sudo now uses "struct timespec" instead of "struct timeval" for
+ time keeping when possible. If supported, sudoedit and visudo
+ now use nanosecond granularity time stamps.
+
+ * Fixed a symbol name collision with systems that have their own
+ SHA2 implementation. This fixes a problem where PAM could use
+ the wrong SHA2 implementation on Solaris 10 systems configured
+ to use SHA512 for passwords.
+
+ * The editor invoked by sudoedit once again uses an unmodified
+ copy of the user's environment as per the documentation. This
+ was inadvertantly changed in sudo 1.8.0. Bug #688.
+
+What's new in Sudo 1.8.12
+
+ * The embedded copy of zlib has been upgraded to version 1.2.8 and
+ is now installed as a shared library where supported.
+
+ * Debug settings for the sudo front end and sudoers plugin are now
+ configured separately.
+
+ * Multiple sudo.conf Debug entries may now be specified per program
+ (or plugin).
+
+ * The plugin API has been extended such that the path to the plugin
+ that was loaded is now included in the settings array. This
+ path can be used to register with the debugging subsystem. The
+ debug_flags setting is now prefixed with a file name and may be
+ specified multiple times if there is more than one matching Debug
+ setting in sudo.conf.
+
+ * The sudoers regression tests now run with the locale set to C
+ since some of the tests compare output that includes locale-specific
+ messages. Bug #672
+
+ * Fixed a bug where sudo would not run commands on Linux when
+ compiled with audit support if audit is disabled. Bug #671
+
+ * Added __BASH_FUNC<* to the environment blacklist to match
+ Apple's syntax for newer-style bash functions.
+
+ * The default password prompt now includes a trailing space after
+ "Password:" for consistency with su(1) on most systems.
+ Bug #663
+
+ * Fixed a problem on DragonFly BSD where SIGCHLD could be ignored,
+ preventing sudo from exiting. Bug #676
+
+ * Visudo will now use the optional sudoers_file, sudoers_mode,
+ sudoers_uid and sudoers_gid arguments if specified on the
+ sudoers.so Plugin line in the sudo.conf file.
+
+ * Fixed a problem introduced in sudo 1.8.8 that prevented the full
+ host name from being used when the "fqdn" sudoers option is used.
+ Bug #678
+
+ * French and Russian translations for sudoers from translationproject.org.
+
+ * Sudo now installs a handler for SIGCHLD signal handler immediately
+ before stating the process that will execute the command (or
+ start the monitor). The handler used to be installed earlier
+ but this causes problems with poorly behaved PAM modules that
+ install their own SIGCHLD signal handler and neglect to restore
+ sudo's original handler. Bug #657
+
+ * Removed a limit on the length of command line arguments expanded
+ by a wild card using sudo's version of the fnmatch() function.
+ This limit was introduced when sudo's version of fnmatch()
+ was replaced in sudo 1.8.4.
+
+ * LDAP-based sudoers can now query an LDAP server for a user's
+ netgroups directly. This is often much faster than fetching
+ every sudoRole object containing a sudoUser that begins with a
+ `+' prefix and checking whether the user is a member of any of
+ the returned netgroups.
+
+ * The mail_always sudoers option no longer sends mail for "sudo -l"
+ or "sudo -v" unless the user is unable to authenticate themselves.
+
+ * Fixed a crash when sudo is run with an empty argument vector.
+
+ * Fixed two potential crashes when sudo is run with very low
+ resource limits.
+
+ * The TZ environment variable is now checked for safety instead
+ of simply being copied to the environment of the command.
+
+What's new in Sudo 1.8.11p2
+
+ * Fixed a bug where dynamic shared objects loaded from a plugin
+ could use the hooked version of getenv() but not the hooked
+ versions of putenv(), setenv() or unsetenv(). This can cause
+ problems for PAM modules that use those functions.
+
+What's new in Sudo 1.8.11p1
+
+ * Fixed a compilation problem on some systems when the
+ --disable-shared-libutil configure option was specified.
+
+ * The user can no longer interrupt the sleep after an incorrect
+ password on PAM systems using pam_unix.
+ Bug #666
+
+ * Fixed a compilation problem on Linux systems that do not use PAM.
+ Bug #667
+
+ * "make install" will now work with the stock GNU autotools
+ install-sh script. Bug #669
+
+ * Fixed a crash with "sudo -i" when the current working directory
+ does not exist. Bug #670
+
+ * Fixed a potential crash in the debug subsystem when logging a message
+ larger that 1024 bytes.
+
+ * Fixed a "make check" failure for ttyname when stdin is closed and
+ stdout and stderr are redirected to a different tty. Bug #643
+
+ * Added BASH_FUNC_* to the environment blacklist to match newer-style
+ bash functions.
+
+What's new in Sudo 1.8.11
+
+ * The sudoers plugin no longer uses setjmp/longjmp to recover
+ from fatal errors. All errors are now propagated to the caller
+ via return codes.
+
+ * When running a command in the background, sudo will now forward
+ SIGINFO to the command (if supported).
+
+ * Sudo will now use the system versions of the sha2 functions from
+ libc or libmd if available.
+
+ * Visudo now works correctly on GNU Hurd. Bug #647
+
+ * Fixed suspend and resume of curses programs on some system when
+ the command is not being run in a pseudo-terminal. Bug #649
+
+ * Fixed a crash with LDAP-based sudoers on some systems when
+ Kerberos was enabled.
+
+ * Sudo now includes optional Solaris audit support.
+
+ * Catalan translation for sudoers from translationproject.org.
+
+ * Norwegian Bokmaal translation for sudo from translationproject.org.
+
+ * Greek translation for sudoers from translationproject.org
+
+ * The sudo source tree has been reorganized to more closely resemble
+ that of other gettext-enabled packages.
+
+ * Sudo and its associated programs now link against a shared version
+ of libsudo_util. The --disable-shared-libutil configure option
+ may be used to force static linking if the --enable-static-sudoers
+ option is also specified.
+
+ * The passwords in ldap.conf and ldap.secret may now be encoded
+ in base64.
+
+ * Audit updates. SELinux role changes are now audited. For
+ sudoedit, we now audit the actual editor being run, instead of
+ just the sudoedit command.
+
+ * Fixed bugs in the man page post-processing that could cause
+ portions of the manuals to be removed.
+
+ * Fixed a crash in the system_group plugin. Bug #653.
+
+ * Fixed sudoedit on platforms without a native version of the
+ getprogname() function. Bug #654.
+
+ * Fixed compilation problems with some pre-C99 compilers.
+
+ * Fixed sudo's -C option which was broken in version 1.8.9.
+
+ * It is now possible to match an environment variable's value as
+ well as its name using env_keep and env_check. This can be used
+ to preserve bash functions which would otherwise be removed from
+ the environment.
+
+ * New files created via sudoedit as a non-root user now have the
+ proper group id. Bug #656
+
+ * Sudoedit now works correctly in conjunction with sudo's SELinux
+ RBAC support. Temporary files are now created with the proper
+ security context.
+
+ * The sudo I/O logging plugin API has been updated. If a logging
+ function returns an error, the command will be terminated and
+ all of the plugin's logging functions will be disabled. If a
+ logging function rejects the command's output it will no longer
+ be displayed to the user's terminal.
+
+ * Fixed a compilation error on systems that lack openpty(), _getpty()
+ and grantpt(). Bug #660
+
+ * Fixed a hang when a sudoers source is listed more than once in
+ a single sudoers nsswitch.conf entry.
+
+ * On AIX, shell scripts without a #! magic number are now passed to
+ /usr/bin/sh, not /usr/bin/bsh. This is consistent with what the
+ execvp() function on AIX does and matches historic sudo behavior.
+ Bug #661
+
+ * Fixed a cross-compilation problem building mksiglist and mksigname.
+ Bug #662
+
+What's new in Sudo 1.8.10p3?
+
+ * Fixed expansion of %p in the prompt for "sudo -l" when rootpw,
+ runaspw or targetpw is set. Bug #639
+
+ * Fixed matching of UIDs and GIDs which was broken in version 1.8.9.
+ Bug #640
+
+ * PAM credential initialization has been re-enabled. It was
+ unintentionally disabled by default in version 1.8.8. The way
+ credentials are initialized has also been fixed. Bug #642.
+
+ * Fixed a descriptor leak on Linux when determining boot time. Sudo
+ normally closes extra descriptors before running a command so
+ the impact is limited. Bug #645
+
+ * Fixed flushing of the last buffer of data when I/O logging is
+ enabled. This bug, introduced in version 1.8.9, could cause
+ incomplete command output on some systems. Bug #646
+
+What's new in Sudo 1.8.10p2?
+
+ * Fixed a hang introduced in sudo 1.8.10 when timestamp_timeout
+ is set to zero.
+
+What's new in Sudo 1.8.10p1?
+
+ * Fixed a bug introduced in sudo 1.8.10 that prevented the disabling
+ of tty-based tickets.
+
+ * Fixed a bug with negated commands in "sudo -l command" that
+ could cause the command to be listed even when it was explicitly
+ denied. This only affected list mode when a command was specified.
+ Bug #636
+
+What's new in Sudo 1.8.10?
+
+ * It is now possible to disable network interface probing in
+ sudo.conf by changing the value of the probe_interfaces
+ setting.
+
+ * When listing a user's privileges (sudo -l), the sudoers plugin
+ will now prompt for the user's password even if the targetpw,
+ rootpw or runaspw options are set.
+
+ * The sudoers plugin uses a new format for its time stamp files.
+ Each user now has a single file which may contain multiple records
+ when per-tty time stamps are in use (the default). The time
+ stamps use a monotonic timer where available and are once again
+ located in a directory under /var/run. The lecture status is
+ now stored separately from the time stamps in a different directory.
+ Bug #616
+
+ * sudo's -K option will now remove all of the user's time stamps,
+ not just the time stamp for the current terminal. The -k option
+ can be used to only disable time stamps for the current terminal.
+
+ * If sudo was started in the background and needed to prompt for
+ a password, it was not possible to suspend it at the password
+ prompt. This now works properly.
+
+ * LDAP-based sudoers now uses a default search filter of
+ (objectClass=sudoRole) for more efficient queries. The netgroup
+ query has been modified to avoid falling below the minimum length
+ for OpenLDAP substring indices.
+
+ * The new "use_netgroups" sudoers option can be used to explicitly
+ enable or disable netgroups support. For LDAP-based sudoers,
+ netgroup support requires an expensive substring match on the
+ server. If netgroups are not needed, this option can be disabled
+ to reduce the load on the LDAP server.
+
+ * Sudo is once again able to open the sudoers file when the group
+ on sudoers doesn't match the expected value, so long as the file
+ is not group writable.
+
+ * Sudo now installs an init.d script to clear the time stamp
+ directory at boot time on AIX and HP-UX systems. These systems
+ either lack /var/run or do not clear it on boot.
+
+ * The JSON format used by "visudo -x" now properly supports the
+ negation operator. In addition, the Options object is now the
+ same for both Defaults and Cmnd_Specs.
+
+ * Czech and Serbian translations for sudoers from translationproject.org.
+
+ * Catalan translation for sudo from translationproject.org.
+
+What's new in Sudo 1.8.9p5?
+
+ * Fixed a compilation error on AIX when LDAP support is enabled.
+
+ * Fixed parsing of the "umask" defaults setting in sudoers. Bug #632.
+
+ * Fixed a failed assertion when the "closefrom_override" defaults
+ setting is enabled in sudoers and sudo's -C flag is used. Bug #633.
+
+What's new in Sudo 1.8.9p4?
+
+ * Fixed a bug where sudo could consume large amounts of CPU while
+ the command was running when I/O logging is not enabled. Bug #631
+
+ * Fixed a bug where sudo would exit with an error when the debug
+ level is set to util@debug or all@debug and I/O logging is not
+ enabled. The command would continue running after sudo exited.
+
+What's new in Sudo 1.8.9p3?
+
+ * Fixed a bug introduced in sudo 1.8.9 that prevented the tty name
+ from being resolved properly on Linux systems. Bug #630.
+
+What's new in Sudo 1.8.9p2?
+
+ * Updated config.guess, config.sub and libtool to support the ppc64le
+ architecture (IBM PowerPC Little Endian).
+
+What's new in Sudo 1.8.9p1?
+
+ * Fixed a problem with gcc 4.8's handling of bit fields that could
+ lead to the noexec flag being enabled even when it was not
+ explicitly set.
+
+What's new in Sudo 1.8.9?
+
+ * Reworked sudo's main event loop to use a simple event subsystem
+ using poll(2) or select(2) as the back end.
+
+ * It is now possible to statically compile the sudoers plugin into
+ the sudo binary without disabling shared library support. The
+ sudo.conf file may still be used to configure other plugins.
+
+ * Sudo can now be compiled again with a C preprocessor that does
+ not support variadic macros.
+
+ * Visudo can now export a sudoers file in JSON format using the
+ new -x flag.
+
+ * The locale is now set correctly again for visudo and sudoreplay.
+
+ * The plugin API has been extended to allow the plugin to exclude
+ specific file descriptors from the "closefrom" range.
+
+ * There is now a workaround for a Solaris-specific problem where
+ NOEXEC was overriding traditional root DAC behavior.
+
+ * Add user netgroup filtering for SSSD. Previously, rules for
+ a netgroup were applied to all even when they did not belong
+ to the specified netgroup.
+
+ * On systems with BSD login classes, if the user specified a group
+ (not a user) to run the command as, it was possible to specify
+ a different login class even when the command was not run as the
+ super user.
+
+ * The closefrom() emulation on Mac OS X now uses /dev/fd if possible.
+
+ * Fixed a bug where sudoedit would not update the original file
+ from the temporary when PAM or I/O logging is not enabled.
+
+ * When recycling I/O logs, the log files are now truncated properly.
+
+ * Fixes bugs #617, #621, #622, #623, #624, #625, #626
+
+What's new in Sudo 1.8.8?
+
+ * Removed a warning on PAM systems with stacked auth modules
+ where the first module on the stack does not succeed.
+
+ * Sudo, sudoreplay and visudo now support GNU-style long options.
+
+ * The -h (--host) option may now be used to specify a host name.
+ This is currently only used by the sudoers plugin in conjunction
+ with the -l (--list) option.
+
+ * Program usage messages and manual SYNOPSIS sections have been
+ simplified.
+
+ * Sudo's LDAP SASL support now works properly with Kerberos.
+ Previously, the SASL library was unable to locate the user's
+ credential cache.
+
+ * It is now possible to set the nproc resource limit to unlimited
+ via pam_limits on Linux (bug #565).
+
+ * New "pam_service" and "pam_login_service" sudoers options
+ that can be used to specify the PAM service name to use.
+
+ * New "pam_session" and "pam_setcred" sudoers options that
+ can be used to disable PAM session and credential support.
+
+ * The sudoers plugin now properly supports UIDs and GIDs
+ that are larger than 0x7fffffff on 32-bit platforms.
+
+ * Fixed a visudo bug introduced in sudo 1.8.7 where per-group
+ Defaults entries would cause an internal error.
+
+ * If the "tty_tickets" sudoers option is enabled (the default),
+ but there is no tty present, sudo will now use a ticket file
+ based on the parent process ID. This makes it possible to support
+ the normal timeout behavior for the session.
+
+ * Fixed a problem running commands that change their process
+ group and then attempt to change the terminal settings when not
+ running the command in a pseudo-terminal. Previously, the process
+ would receive SIGTTOU since it was effectively a background
+ process. Sudo will now grant the child the controlling tty and
+ continue it when this happens.
+
+ * The "closefrom_override" sudoers option may now be used in
+ a command-specified Defaults entry (bug #610).
+
+ * Sudo's BSM audit support now works on Solaris 11.
+
+ * Brazilian Portuguese translation for sudo and sudoers from
+ translationproject.org.
+
+ * Czech translation for sudo from translationproject.org.
+
+ * French translation for sudo from translationproject.org.
+
+ * Sudo's noexec support on Mac OS X 10.4 and above now uses dynamic
+ symbol interposition instead of setting DYLD_FORCE_FLAT_NAMESPACE=1
+ which causes issues with some programs.
+
+ * Fixed visudo's -q (--quiet) flag, broken in sudo 1.8.6.
+
+ * Root may no longer change its SELinux role without entering
+ a password.
+
+ * Fixed a bug introduced in Sudo 1.8.7 where the indexes written
+ to the I/O log timing file are two greater than they should be.
+ Sudoreplay now contains a work-around to parse those files.
+
+ * In sudoreplay's list mode, the "this" qualifier in "fromdate"
+ or "todate" expressions now behaves more sensibly. Previously,
+ it would often match a date that was "one more" than expected.
+ For example, "this week" now matches the current week instead
+ of the following week.
+
+What's new in Sudo 1.8.7?
+
+ * The non-Unix group plugin is now supported when sudoers data
+ is stored in LDAP.
+
+ * Sudo now uses a workaround for a locale bug on Solaris 11.0
+ that prevents setuid programs like sudo from fully using locales.
+
+ * User messages are now always displayed in the user's locale,
+ even when the same message is being logged or mailed in a
+ different locale.
+
+ * Log files created by sudo now explicitly have the group set
+ to group ID 0 rather than relying on BSD group semantics (which
+ may not be the default).
+
+ * A new "exec_background" sudoers option can be used to initially
+ run the command without read access to the terminal when running
+ a command in a pseudo-tty. If the command tries to read from
+ the terminal it will be stopped by the kernel (via SIGTTIN or
+ SIGTTOU) and sudo will immediately restart it as the foreground
+ process (if possible). This allows sudo to only pass terminal
+ input to the program if the program actually is expecting it.
+ Unfortunately, a few poorly-behaved programs (like "su" on most
+ Linux systems) do not handle SIGTTIN and SIGTTOU properly.
+
+ * Sudo now uses an efficient group query to get all the groups
+ for a user instead of iterating over every record in the group
+ database on HP-UX and Solaris.
+
+ * Sudo now produces better error messages when there is an error
+ in the sudo.conf file.
+
+ * Two new settings have been added to sudo.conf to give the admin
+ better control of how group database queries are performed. The
+ "group_source" specifies how the group list for a user will be
+ determined. Legal values are "static" (use the kernel groups
+ list), "dynamic" (perform a group database query) and "adaptive"
+ (only perform a group database query if the kernel list is full).
+ The "max_groups" setting specifies the maximum number of groups
+ a user may belong to when performing a group database query.
+
+ * The sudo.conf file now supports line continuation by using a
+ backslash as the last character on the line.
+
+ * There is now a standalone sudo.conf manual page.
+
+ * Sudo now stores its libexec files in a "sudo" sub-directory instead
+ of in libexec itself. For backwards compatibility, if the plugin
+ is not found in the default plugin directory, sudo will check
+ the parent directory if the default directory ends in "/sudo".
+
+ * The sudoers I/O logging plugin now logs the terminal size.
+
+ * A new sudoers option "maxseq" can be used to limit the number of
+ I/O log entries that are stored.
+
+ * The "system_group" and "group_file" sudoers group provider plugins
+ are now installed by default.
+
+ * The list output (sudo -l) output from the sudoers plugin is now
+ less ambiguous when an entry includes different runas users.
+ The long list output (sudo -ll) for file-based sudoers is now
+ more consistent with the format of LDAP-based sudoers.
+
+ * A UID may now be used in the sudoRunAsUser attributes for LDAP
+ sudoers.
+
+ * Minor plugin API change: the close and version functions are now
+ optional. If the policy plugin does not provide a close function
+ and the command is not being run in a new pseudo-tty, sudo may
+ now execute the command directly instead of in a child process.
+
+ * A new sudoers option "pam_session" can be used to disable sudo's
+ PAM session support.
+
+ * On HP-UX systems, sudo will now use the pstat() function to
+ determine the tty instead of ttyname().
+
+ * Turkish translation for sudo and sudoers from translationproject.org.
+
+ * Dutch translation for sudo and sudoers from translationproject.org.
+
+ * Tivoli Directory Server client libraries may now be used with
+ HP-UX where libibmldap has a hidden dependency on libCsup.
+
+ * The sudoers plugin will now ignore invalid domain names when
+ checking netgroup membership. Most Linux systems use the string
+ "(none)" for the NIS-style domain name instead of an empty string.
+
+ * New support for specifying a SHA-2 digest along with the command
+ in sudoers. Supported hash types are sha224, sha256, sha384 and
+ sha512. See the description of Digest_Spec in the sudoers manual
+ or the description of sudoCommand in the sudoers.ldap manual for
+ details.
+
+ * The paths to ldap.conf and ldap.secret may now be specified as
+ arguments to the sudoers plugin in the sudo.conf file.
+
+ * Fixed potential false positives in visudo's alias cycle detection.
+
+ * Fixed a problem where the time stamp file was being treated
+ as out of date on Linux systems where the change time on the
+ pseudo-tty device node can change after it is allocated.
+
+ * Sudo now only builds Position Independent Executables (PIE)
+ by default on Linux systems and verifies that a trivial test
+ program builds and runs.
+
+ * On Solaris 11.1 and higher, sudo binaries will now have the
+ ASLR tag enabled if supported by the linker.
+
+What's new in Sudo 1.8.6p8?
+
+ * Terminal detection now works properly on 64-bit AIX kernels.
+ This was broken by the removal of the ttyname() fallback in Sudo
+ 1.8.6p6. Sudo is now able to map an AIX 64-bit device number
+ to the corresponding device file in /dev.
+
+ * Sudo now checks for crypt() returning NULL when performing
+ passwd-based authentication.
+
+What's new in Sudo 1.8.6p7?
+
+ * A time stamp file with the date set to the epoch by "sudo -k"
+ is now completely ignored regardless of what the local clock is
+ set to. Previously, if the local clock was set to a value between
+ the epoch and the time stamp timeout value, a time stamp reset
+ by "sudo -k" would be considered current.
+
+ * The tty-specific time stamp file now includes the session ID
+ of the sudo process that created it. If a process with the same
+ tty but a different session ID runs sudo, the user will now be
+ prompted for a password (assuming authentication is required for
+ the command).
+
+What's new in Sudo 1.8.6p6?
+
+ * On systems where the controlling tty can be determined via /proc
+ or sysctl(), sudo will no longer fall back to using ttyname()
+ if the process has no controlling tty. This prevents sudo from
+ using a non-controlling tty for logging and time stamp purposes.
+
+What's new in Sudo 1.8.6p5?
+
+ * Fixed a potential crash in visudo's alias cycle detection.
+
+ * Improved performance on Solaris when retrieving the group list
+ for the target user. On systems with a large number of groups
+ where the group database is not local (NIS, LDAP, AD), fetching
+ the group list could take a minute or more.
+
+What's new in Sudo 1.8.6p4?
+
+ * The -fstack-protector is now used when linking visudo, sudoreplay
+ and testsudoers.
+
+ * Avoid building PIE binaries on FreeBSD/ia64 as they don't run
+ properly.
+
+ * Fixed a crash in visudo strict mode when an unknown Defaults
+ setting is encountered.
+
+ * Do not inform the user that the command was not permitted by the
+ policy if they do not successfully authenticate. This is a
+ regression introduced in sudo 1.8.6.
+
+ * Allow sudo to be build with sss support without also including
+ ldap support.
+
+ * Fixed running commands that need the terminal in the background
+ when I/O logging is enabled. E.g. "sudo vi &". When the command
+ is foregrounded, it will now resume properly.
+
+What's new in Sudo 1.8.6p3?
+
+ * Fixed post-processing of the man pages on systems with legacy
+ versions of sed.
+
+ * Fixed "sudoreplay -l" on Linux systems with file systems that
+ set DT_UNKNOWN in the d_type field of struct dirent.
+
+What's new in Sudo 1.8.6p2?
+
+ * Fixed suspending a command after it has already been resumed
+ once when I/O logging (or use_pty) is not enabled.
+ This was a regression introduced in version 1.8.6.
+
+What's new in Sudo 1.8.6p1?
+
+ * Fixed the setting of LOGNAME, USER and USERNAME variables in the
+ command's environment when env_reset is enabled (the default).
+ This was a regression introduced in version 1.8.6.
+
+ * Sudo now honors SUCCESS=return in /etc/nsswitch.conf.
+
+What's new in Sudo 1.8.6?
+
+ * Sudo is now built with the -fstack-protector flag if the the
+ compiler supports it. Also, the -zrelro linker flag is used if
+ supported. The --disable-hardening configure option can be used
+ to build sudo without stack smashing protection.
+
+ * Sudo is now built as a Position Independent Executable (PIE)
+ if supported by the compiler and linker.
+
+ * If the user is a member of the "exempt" group in sudoers, they
+ will no longer be prompted for a password even if the -k flag
+ is specified with the command. This makes "sudo -k command"
+ consistent with the behavior one would get if the user ran "sudo
+ -k" immediately before running the command.
+
+ * The sudoers file may now be a symbolic link. Previously, sudo
+ would refuse to read sudoers unless it was a regular file.
+
+ * The sudoreplay command can now properly replay sessions where
+ no tty was present.
+
+ * The sudoers plugin now takes advantage of symbol visibility
+ controls when supported by the compiler or linker. As a result,
+ only a small number of symbols are exported which significantly
+ reduces the chances of a conflict with other shared objects.
+
+ * Improved support for the Tivoli Directory Server LDAP client
+ libraries. This includes support for using LDAP over SSL (ldaps)
+ as well as support for the BIND_TIMELIMIT, TLS_KEY and TLS_CIPHERS
+ ldap.conf options. A new ldap.conf option, TLS_KEYPW can be
+ used to specify a password to decrypt the key database.
+
+ * When constructing a time filter for use with LDAP sudoNotBefore
+ and sudoNotAfter attributes, the current time now includes tenths
+ of a second. This fixes a problem with timed entries on Active
+ Directory.
+
+ * If a user fails to authenticate and the command would be rejected
+ by sudoers, it is now logged with "command not allowed" instead
+ of "N incorrect password attempts". Likewise, the "mail_no_perms"
+ sudoers option now takes precedence over "mail_badpass".
+
+ * The sudo manuals are now formatted using the mdoc macros. Versions
+ using the legacy man macros are provided for systems that lack mdoc.
+
+ * New support for Solaris privilege sets. This makes it possible
+ to specify fine-grained privileges in the sudoers file on Solaris
+ 10 and above. A Runas_Spec that contains no Runas_Lists can be
+ used to give a user the ability to run a command as themselves
+ but with an expanded privilege set.
+
+ * Fixed a problem with the reboot and shutdown commands on some
+ systems (such as HP-UX and BSD). On these systems, reboot sends
+ all processes (except itself) SIGTERM. When sudo received
+ SIGTERM, it would relay it to the reboot process, thus killing
+ reboot before it had a chance to actually reboot the system.
+
+ * Support for using the System Security Services Daemon (SSSD) as
+ a source of sudoers data.
+
+ * Slovenian translation for sudo and sudoers from translationproject.org.
+
+ * Visudo will now warn about unknown Defaults entries that are
+ per-host, per-user, per-runas or per-command.
+
+ * Fixed a race condition that could cause sudo to receive SIGTTOU
+ (and stop) when resuming a shell that was run via sudo when I/O
+ logging (and use_pty) is not enabled.
+
+ * Sending SIGTSTP directly to the sudo process will now suspend the
+ running command when I/O logging (and use_pty) is not enabled.
+
+What's new in Sudo 1.8.5p3?
+
+ * Fixed the loading of I/O plugins that conform to a plugin API
+ version older than 1.2.
+
+What's new in Sudo 1.8.5p2?
+
+ * Fixed use of the SUDO_ASKPASS environment variable which was
+ broken in Sudo 1.8.5.
+
+ * Fixed a problem reading the sudoers file when the file mode is
+ more restrictive than the expected mode. For example, when the
+ expected sudoers file mode is 0440 but the actual mode is 0400.
+
+What's new in Sudo 1.8.5p1?
+
+ * Fixed a bug that prevented files in an include directory from
+ being evaluated.
+
+What's new in Sudo 1.8.5?
+
+ * When "noexec" is enabled, sudo_noexec.so will now be prepended
+ to any existing LD_PRELOAD variable instead of replacing it.
+
+ * The sudo_noexec.so shared library now wraps the execvpe(),
+ exect(), posix_spawn() and posix_spawnp() functions.
+
+ * The user/group/mode checks on sudoers files have been relaxed.
+ As long as the file is owned by the sudoers UID, not world-writable
+ and not writable by a group other than the sudoers GID, the file
+ is considered OK. Note that visudo will still set the mode to
+ the value specified at configure time.
+
+ * It is now possible to specify the sudoers path, UID, GID and
+ file mode as options to the plugin in the sudo.conf file.
+
+ * Croatian, Galician, German, Lithuanian, Swedish and Vietnamese
+ translations from translationproject.org.
+
+ * /etc/environment is no longer read directly on Linux systems
+ when PAM is used. Sudo now merges the PAM environment into the
+ user's environment which is typically set by the pam_env module.
+
+ * The initial evironment created when env_reset is in effect now
+ includes the contents of /etc/environment on AIX systems and the
+ "setenv" and "path" entries from /etc/login.conf on BSD systems.
+
+ * The plugin API has been extended in three ways. First, options
+ specified in sudo.conf after the plugin pathname are passed to
+ the plugin's open function. Second, sudo has limited support
+ for hooks that can be used by plugins. Currently, the hooks are
+ limited to environment handling functions. Third, the init_session
+ policy plugin function is passed a pointer to the user environment
+ which can be updated during session setup. The plugin API version
+ has been incremented to version 1.2. See the sudo_plugin manual
+ for more information.
+
+ * The policy plugin's init_session function is now called by the
+ parent sudo process, not the child process that executes the
+ command. This allows the PAM session to be open and closed in
+ the same process, which some PAM modules require.
+
+ * Fixed parsing of "Path askpass" and "Path noexec" in sudo.conf,
+ which was broken in version 1.8.4.
+
+ * On systems with an SVR4-style /proc file system, the /proc/pid/psinfo
+ file is now uses to determine the controlling terminal, if possible.
+ This allows tty-based tickets to work properly even when, e.g.
+ standard input, output and error are redirected to /dev/null.
+
+ * The output of "sudoreplay -l" is now sorted by file name (or
+ sequence number). Previously, entries were displayed in the
+ order in which they were found on the file system.
+
+ * Sudo now behaves properly when I/O logging is enabled and the
+ controlling terminal is revoked (e.g. the running sshd is killed).
+ Previously, sudo may have exited without calling the I/O plugin's
+ close function which can lead to an incomplete I/O log.
+
+ * Sudo can now detect when a user has logged out and back in again
+ on Solaris 11, just like it can on Solaris 10.
+
+ * The built-in zlib included with Sudo has been upgraded to version
+ 1.2.6.
+
+ * Setting the SSL parameter to start_tls in ldap.conf now works
+ properly when using Mozilla-based SDKs that support the
+ ldap_start_tls_s() function.
+
+ * The TLS_CHECKPEER parameter in ldap.conf now works when the
+ Mozilla NSS crypto back-end is used with OpenLDAP.
+
+ * A new group provider plugin, system_group, is included which
+ performs group look ups by name using the system groups database.
+ This can be used to restore the pre-1.7.3 sudo group lookup
+ behavior.
+
+What's new in Sudo 1.8.4p5?
+
+ * Fixed a bug when matching against an IP address with an associated
+ netmask in the sudoers file. In certain circumstances, this
+ could allow users to run commands on hosts they are not authorized
+ for.
+
+What's new in Sudo 1.8.4p4?
+
+ * Fixed a bug introduced in Sudo 1.8.4 which prevented "sudo -v"
+ from working.
+
+What's new in Sudo 1.8.4p3?
+
+ * Fixed a crash on FreeBSD when no tty is present.
+
+ * Fixed a bug introduced in Sudo 1.8.4 that allowed users to
+ specify environment variables to set on the command line without
+ having sudo "ALL" permissions or the "SETENV" tag.
+
+ * When visudo is run with the -c (check) option, the sudoers
+ file(s) owner and mode are now also checked unless the -f option
+ was specified.
+
+What's new in Sudo 1.8.4p2?
+
+ * Fixed a bug introduced in Sudo 1.8.4 where insufficient space
+ was allocated for group IDs in the LDAP filter.
+
+ * Fixed a bug introduced in Sudo 1.8.4 where the path to sudo.conf
+ was "/sudo.conf" instead of "/etc/sudo.conf".
+
+ * Fixed a bug introduced in Sudo 1.8.4 which could cause a hang
+ when I/O logging is enabled and input is from a pipe or file.
+
+What's new in Sudo 1.8.4p1?
+
+ * Fixed a bug introduced in sudo 1.8.4 that broke adding to or
+ deleting from the env_keep, env_check and env_delete lists in
+ sudoers on some platforms.
+
+What's new in Sudo 1.8.4?
+
+ * The -D flag in sudo has been replaced with a more general debugging
+ framework that is configured in sudo.conf.
+
+ * Fixed a false positive in visudo strict mode when aliases are
+ in use.
+
+ * Fixed a crash with "sudo -i" when a runas group was specified
+ without a runas user.
+
+ * The line on which a syntax error is reported in the sudoers file
+ is now more accurate. Previously it was often off by a line.
+
+ * Fixed a bug where stack garbage could be printed at the end of
+ the lecture when the "lecture_file" option was enabled.
+
+ * "make install" now honors the LINGUAS environment variable.
+
+ * The #include and #includedir directives in sudoers now support
+ relative paths. If the path is not fully qualified it is expected
+ to be located in the same directory of the sudoers file that is
+ including it.
+
+ * Serbian and Spanish translations for sudo from translationproject.org.
+
+ * LDAP-based sudoers may now access by group ID in addition to
+ group name.
+
+ * visudo will now fix the mode on the sudoers file even if no changes
+ are made unless the -f option is specified.
+
+ * The "use_loginclass" sudoers option works properly again.
+
+ * On systems that use login.conf, "sudo -i" now sets environment
+ variables based on login.conf.
+
+ * For LDAP-based sudoers, values in the search expression are now
+ escaped as per RFC 4515.
+
+ * The plugin close function is now properly called when a login
+ session is killed (as opposed to the actual command being killed).
+ This can happen when an ssh session is disconnected or the
+ terminal window is closed.
+
+ * The deprecated "noexec_file" sudoers option is no longer supported.
+
+ * Fixed a race condition when I/O logging is not enabled that could
+ result in tty-generated signals (e.g. control-C) being received
+ by the command twice.
+
+ * If none of the standard input, output or error are connected to
+ a tty device, sudo will now check its parent's standard input,
+ output or error for the tty name on systems with /proc and BSD
+ systems that support the KERN_PROC_PID sysctl. This allows
+ tty-based tickets to work properly even when, e.g. standard
+ input, output and error are redirected to /dev/null.
+
+ * Added the --enable-kerb5-instance configure option to allow
+ people using Kerberos V authentication to specify a custom
+ instance so the principal name can be, e.g. "username/sudo"
+ similar to how ksu uses "username/root".
+
+ * Fixed a bug where a pattern like "/usr/*" included /usr/bin/ in
+ the results, which would be incorrectly be interpreted as if the
+ sudoers file had specified a directory.
+
+ * "visudo -c" will now list any include files that were checked
+ in addition to the main sudoers file when everything parses OK.
+
+ * Users that only have read-only access to the sudoers file may
+ now run "visudo -c". Previously, write permissions were required
+ even though no writing is down in check-only mode.
+
+ * It is now possible to prevent the disabling of core dumps from
+ within sudo itself by adding a line to the sudo.conf file like
+ "Set disable_coredump false".
+
+What's new in Sudo 1.8.3p2?
+
+ * Fixed a format string vulnerability when the sudo binary (or a
+ symbolic link to the sudo binary) contains printf format escapes
+ and the -D (debugging) flag is used.
+
+What's new in Sudo 1.8.3p1?
+
+ * Fixed a crash in the monitor process on Solaris when NOPASSWD
+ was specified or when authentication was disabled.
+
+ * Fixed matching of a Runas_Alias in the group section of a
+ Runas_Spec.
+
+What's new in Sudo 1.8.3?
+
+ * Fixed expansion of strftime() escape sequences in the "log_dir"
+ sudoers setting.
+
+ * Esperanto, Italian and Japanese translations from translationproject.org.
+
+ * Sudo will now use PAM by default on AIX 6 and higher.
+
+ * Added --enable-werror configure option for gcc's -Werror flag.
+
+ * Visudo no longer assumes all editors support the +linenumber
+ command line argument. It now uses a whitelist of editors known
+ to support the option.
+
+ * Fixed matching of network addresses when a netmask is specified
+ but the address is not the first one in the CIDR block.
+
+ * The configure script now check whether or not errno.h declares
+ the errno variable. Previously, sudo would always declare errno
+ itself for older systems that don't declare it in errno.h.
+
+ * The NOPASSWD tag is now honored for denied commands too, which
+ matches historic sudo behavior (prior to sudo 1.7.0).
+
+ * Sudo now honors the "DEREF" setting in ldap.conf which controls
+ how alias dereferencing is done during an LDAP search.
+
+ * A symbol conflict with the pam_ssh_agent_auth PAM module that
+ would cause a crash been resolved.
+
+ * The inability to load a group provider plugin is no longer
+ a fatal error.
+
+ * A potential crash in the utmp handling code has been fixed.
+
+ * Two PAM session issues have been resolved. In previous versions
+ of sudo, the PAM session was opened as one user and closed as
+ another. Additionally, if no authentication was performed, the
+ PAM session would never be closed.
+
+ * Sudo will now work correctly with LDAP-based sudoers using TLS
+ or SSL on Debian systems.
+
+ * The LOGNAME, USER and USERNAME environment variables are preserved
+ correctly again in sudoedit mode.
+
+What's new in Sudo 1.8.2?
+
+ * Sudo, visudo, sudoreplay and the sudoers plug-in now have natural
+ language support (NLS). This can be disabled by passing configure
+ the --disable-nls option. Sudo will use gettext(), if available,
+ to display translated messages. All translations are coordinated
+ via The Translation Project, http://translationproject.org/.
+
+ * Plug-ins are now loaded with the RTLD_GLOBAL flag instead of
+ RTLD_LOCAL. This fixes missing symbol problems in PAM modules
+ on certain platforms, such as FreeBSD and SuSE Linux Enterprise.
+
+ * I/O logging is now supported for commands run in background mode
+ (using sudo's -b flag).
+
+ * Group ownership of the sudoers file is now only enforced when
+ the file mode on sudoers allows group readability or writability.
+
+ * Visudo now checks the contents of an alias and warns about cycles
+ when the alias is expanded.
+
+ * If the user specifies a group via sudo's -g option that matches
+ the target user's group in the password database, it is now
+ allowed even if no groups are present in the Runas_Spec.
+
+ * The sudo Makefiles now have more complete dependencies which are
+ automatically generated instead of being maintained manually.
+
+ * The "use_pty" sudoers option is now correctly passed back to the
+ sudo front end. This was missing in previous versions of sudo
+ 1.8 which prevented "use_pty" from being honored.
+
+ * "sudo -i command" now works correctly with the bash version
+ 2.0 and higher. Previously, the .bash_profile would not be
+ sourced prior to running the command unless bash was built with
+ NON_INTERACTIVE_LOGIN_SHELLS defined.
+
+ * When matching groups in the sudoers file, sudo will now match
+ based on the name of the group instead of the group ID. This can
+ substantially reduce the number of group lookups for sudoers
+ files that contain a large number of groups.
+
+ * Multi-factor authentication is now supported on AIX.
+
+ * Added support for non-RFC 4517 compliant LDAP servers that require
+ that seconds be present in a timestamp, such as Tivoli Directory Server.
+
+ * If the group vector is to be preserved, the PATH search for the
+ command is now done with the user's original group vector.
+
+ * For LDAP-based sudoers, the "runas_default" sudoOption now works
+ properly in a sudoRole that contains a sudoCommand.
+
+ * Spaces in command line arguments for "sudo -s" and "sudo -i" are
+ now escaped with a backslash when checking the security policy.
+
+What's new in Sudo 1.8.1p2?
+
+ * Two-character CIDR-style IPv4 netmasks are now matched correctly
+ in the sudoers file.
+
+ * A build error with MIT Kerberos V has been resolved.
+
+ * A crash on HP-UX in the sudoers plugin when wildcards are
+ present in the sudoers file has been resolved.
+
+ * Sudo now works correctly on Tru64 Unix again.
+
+What's new in Sudo 1.8.1p1?
+
+ * Fixed a problem on AIX where sudo was unable to set the final
+ UID if the PAM module modified the effective UID.
+
+ * A non-existent includedir is now treated the same as an empty
+ directory and not reported as an error.
+
+ * Removed extraneous parens in LDAP filter when sudoers_search_filter
+ is enabled that can cause an LDAP search error.
+
+ * Fixed a "make -j" problem for "make install".
+
+What's new in Sudo 1.8.1?
+
+ * A new LDAP setting, sudoers_search_filter, has been added to
+ ldap.conf. This setting can be used to restrict the set of
+ records returned by the LDAP query. Based on changes from Matthew
+ Thomas.
+
+ * White space is now permitted within a User_List when used in
+ conjunction with a per-user Defaults definition.
+
+ * A group ID (%#GID) may now be specified in a User_List or Runas_List.
+ Likewise, for non-Unix groups the syntax is %:#GID.
+
+ * Support for double-quoted words in the sudoers file has been fixed.
+ The change in 1.7.5 for escaping the double quote character
+ caused the double quoting to only be available at the beginning
+ of an entry.
+
+ * The fix for resuming a suspended shell in 1.7.5 caused problems
+ with resuming non-shells on Linux. Sudo will now save the process
+ group ID of the program it is running on suspend and restore it
+ when resuming, which fixes both problems.
+
+ * A bug that could result in corrupted output in "sudo -l" has been
+ fixed.
+
+ * Sudo will now create an entry in the utmp (or utmpx) file when
+ allocating a pseudo-tty (e.g. when logging I/O). The "set_utmp"
+ and "utmp_runas" sudoers file options can be used to control this.
+ Other policy plugins may use the "set_utmp" and "utmp_user"
+ entries in the command_info list.
+
+ * The sudoers policy now stores the TSID field in the logs
+ even when the "iolog_file" sudoers option is defined to a value
+ other than %{sessid}. Previously, the TSID field was only
+ included in the log file when the "iolog_file" option was set
+ to its default value.
+
+ * The sudoreplay utility now supports arbitrary session IDs.
+ Previously, it would only work with the base-36 session IDs
+ that the sudoers plugin uses by default.
+
+ * Sudo now passes "run_shell=true" to the policy plugin in the
+ settings list when sudo's -s command line option is specified.
+ The sudoers policy plugin uses this to implement the "set_home"
+ sudoers option which was missing from sudo 1.8.0.
+
+ * The "noexec" functionality has been moved out of the sudoers
+ policy plugin and into the sudo front-end, which matches the
+ behavior documented in the plugin writer's guide. As a result,
+ the path to the noexec file is now specified in the sudo.conf
+ file instead of the sudoers file.
+
+ * On Solaris 10, the PRIV_PROC_EXEC privilege is now used to
+ implement the "noexec" feature. Previously, this was implemented
+ via the LD_PRELOAD environment variable.
+
+ * The exit values for "sudo -l", "sudo -v" and "sudo -l command"
+ have been fixed in the sudoers policy plugin.
+
+ * The sudoers policy plugin now passes the login class, if any,
+ back to the sudo front-end.
+
+ * The sudoers policy plugin was not being linked with requisite
+ libraries in certain configurations.
+
+ * Sudo now parses command line arguments before loading any plugins.
+ This allows "sudo -V" or "sudo -h" to work even if there is a problem
+ with sudo.conf
+
+ * Plugins are now linked with the static version of libgcc to allow
+ the plugin to run on a system where no shared libgcc is installed,
+ or where it is installed in a different location.
+
+What's new in Sudo 1.8.0?
+
+ * Sudo has been refactored to use a modular framework that can
+ support third-party policy and I/O logging plugins. The default
+ plugin is "sudoers" which provides the traditional sudo functionality.
+ See the sudo_plugin manual for details on the plugin API and the
+ sample in the plugins directory for a simple example.
+
+What's new in Sudo 1.7.5?
+
+ * When using visudo in check mode, a file named "-" may be used to
+ check sudoers data on the standard input.
+
+ * Sudo now only fetches shadow password entries when using the
+ password database directly for authentication.
+
+ * Password and group entries are now cached using the same key
+ that was used to look them up. This fixes a problem when looking
+ up entries by name if the name in the retrieved entry does not
+ match the name used to look it up. This may happen on some systems
+ that do case insensitive lookups or that truncate long names.
+
+ * GCC will no longer display warnings on glibc systems that use
+ the warn_unused_result attribute for write(2) and other system calls.
+
+ * If a PAM account management module denies access, sudo now prints
+ a more useful error message and stops trying to validate the user.
+
+ * Fixed a potential hang on idle systems when the sudo-run process
+ exits immediately.
+
+ * Sudo now includes a copy of zlib that will be used on systems
+ that do not have zlib installed.
+
+ * The --with-umask-override configure flag has been added to enable
+ the "umask_override" sudoers Defaults option at build time.
+
+ * Sudo now unblocks all signals on startup to avoid problems caused
+ by the parent process changing the default signal mask.
+
+ * LDAP Sudoers entries may now specify a time period for which
+ the entry is valid. This requires an updated sudoers schema
+ that includes the sudoNotBefore and sudoNotAfter attributes.
+ Support for timed entries must be explicitly enabled in the
+ ldap.conf file. Based on changes from Andreas Mueller.
+
+ * LDAP Sudoers entries may now specify a sudoOrder attribute that
+ determines the order in which matching entries are applied. The
+ last matching entry is used, just like file-based sudoers. This
+ requires an updated sudoers schema that includes the sudoOrder
+ attribute. Based on changes from Andreas Mueller.
+
+ * When run as sudoedit, or when given the -e flag, sudo now treats
+ command line arguments as pathnames. This means that slashes
+ in the sudoers file entry must explicitly match slashes in
+ the command line arguments. As a result, and entry such as:
+ user ALL = sudoedit /etc/*
+ will allow editing of /etc/motd but not /etc/security/default.
+
+ * NETWORK_TIMEOUT is now an alias for BIND_TIMELIMIT in ldap.conf for
+ compatibility with OpenLDAP configuration files.
+
+ * The LDAP API TIMEOUT parameter is now honored in ldap.conf.
+
+ * The I/O log directory may now be specified in the sudoers file.
+
+ * Sudo will no longer refuse to run if the sudoers file is writable
+ by root.
+
+ * Sudo now performs command line escaping for "sudo -s" and "sudo -i"
+ after validating the command so the sudoers entries do not need
+ to include the backslashes.
+
+ * Logging and email sending are now done in the locale specified
+ by the "sudoers_locale" setting ("C" by default). Email send by
+ sudo now includes MIME headers when "sudoers_locale" is not "C".
+
+ * The configure script has a new option, --disable-env-reset, to
+ allow one to change the default for the sudoers Default setting
+ "env_reset" at compile time.
+
+ * When logging "sudo -l command", sudo will now prepend "list "
+ to the command in the log line to distinguish between an
+ actual command invocation in the logs.
+
+ * Double-quoted group and user names may now include escaped double
+ quotes as part of the name. Previously this was a parse error.
+
+ * Sudo once again restores the state of the signal handlers it
+ modifies before executing the command. This allows sudo to be
+ used with the nohup command.
+
+ * Resuming a suspended shell now works properly when I/O logging
+ is not enabled (the I/O logging case was already correct).
+
+What's new in Sudo 1.7.4p6?
+
+ * A bug has been fixed in the I/O logging support that could cause
+ visual artifacts in full-screen programs such as text editors.
+
+What's new in Sudo 1.7.4p5?
+
+ * A bug has been fixed that would allow a command to be run without the
+ user entering a password when sudo's -g flag is used without the -u flag.
+
+ * If user has no supplementary groups, sudo will now fall back on checking
+ the group file explicitly, which restores historic sudo behavior.
+
+ * A crash has been fixed when sudo's -g flag is used without the -u flag
+ and the sudoers file contains an entry with no runas user or group listed.
+
+ * A crash has been fixed when the Solaris project support is enabled
+ and sudo's -g flag is used without the -u flag.
+
+ * Sudo no longer exits with an error when support for auditing is
+ compiled in but auditing is not enabled.
+
+ * Fixed a bug introduced in sudo 1.7.3 where the ticket file was not
+ being honored when the "targetpw" sudoers Defaults option was enabled.
+
+ * The LOG_INPUT and LOG_OUTPUT tags in sudoers are now parsed correctly.
+
+ * A crash has been fixed in "sudo -l" when sudo is built with auditing
+ support and the user is not allowed to run any commands on the host.
+
+What's new in Sudo 1.7.4p4?
+
+ * A potential security issue has been fixed with respect to the handling
+ of sudo's -g command line option when -u is also specified. The flaw
+ may allow an attacker to run commands as a user that is not authorized
+ by the sudoers file.
+
+ * A bug has been fixed where "sudo -l" output was incomplete if multiple
+ sudoers sources were defined in nsswitch.conf and there was an error
+ querying one of the sources.
+
+ * The log_input, log_output, and use_pty sudoers options now work correctly
+ on AIX. Previously, sudo would hang if they were enabled.
+
+ * The "make install" target now works correctly when sudo is built in a
+ directory other than the source directory.
+
+ * The "runas_default" sudoers setting now works properly in a per-command
+ Defaults line.
+
+ * Suspending and resuming the bash shell when PAM is in use now works
+ correctly. The SIGCONT signal was not propagated to the child process.
+
+What's new in Sudo 1.7.4p3?
+
+ * A bug has been fixed where duplicate HOME environment variables could be
+ present when the env_reset setting was disabled and the always_set_home
+ setting was enabled in sudoers.
+
+ * The value of sysconfdir is now substituted into the path to the sudoers.d
+ directory in the installed sudoers file.
+
+ * Compilation problems on IRIX and other platforms have been fixed.
+
+ * If multiple PAM "auth" actions are specified and the user enters ^C at
+ the password prompt, sudo will no longer prompt for a password for any
+ subsequent "auth" actions. Previously it was necessary to enter ^C for
+ each "auth" action.
+
+What's new in Sudo 1.7.4p2?
+
+ * A bug where sudo could spin in a busy loop waiting for the child process
+ has been fixed.
+
+What's new in Sudo 1.7.4p1?
+
+ * A bug introduced in sudo 1.7.3 that prevented the -k and -K options from
+ functioning when the tty_tickets sudoers option is enabled has been fixed.
+
+ * Sudo no longer prints a warning when the -k or -K options are specified
+ and the ticket file does not exist.
+
+ * It is now easier to cross-compile sudo.
+
+What's new in Sudo 1.7.4?
+
+ * Sudoedit will now preserve the file extension in the name of the
+ temporary file being edited. The extension is used by some
+ editors (such as emacs) to choose the editing mode.
+
+ * Time stamp files have moved from /var/run/sudo to either /var/db/sudo,
+ /var/lib/sudo or /var/adm/sudo. The directories are checked for
+ existence in that order. This prevents users from receiving the
+ sudo lecture every time the system reboots. Time stamp files older
+ than the boot time are ignored on systems where it is possible to
+ determine this.
+
+ * The tty_tickets sudoers option is now enabled by default.
+
+ * Ancillary documentation (README files, LICENSE, etc) is now installed
+ in a sudo documentation directory.
+
+ * Sudo now recognizes "tls_cacert" as an alias for "tls_cacertfile"
+ in ldap.conf.
+
+ * Defaults settings that are tied to a user, host or command may
+ now include the negation operator. For example:
+ Defaults:!millert lecture
+ will match any user but millert.
+
+ * The default PATH environment variable, used when no PATH variable
+ exists, now includes /usr/sbin and /sbin.
+
+ * Sudo now uses polypkg (http://rc.quest.com/topics/polypkg/)
+ for cross-platform packing.
+
+ * On Linux, sudo will now restore the nproc resource limit before
+ executing a command, unless the limit appears to have been modified
+ by pam_limits. This avoids a problem with bash scripts that open
+ more than 32 descriptors on SuSE Linux, where sysconf(_SC_CHILD_MAX)
+ will return -1 when RLIMIT_NPROC is set to RLIMIT_UNLIMITED (-1).
+
+ * The HOME and MAIL environment variables are now reset based on the
+ target user's password database entry when the env_reset sudoers option
+ is enabled (which is the case in the default configuration). Users
+ wishing to preserve the original values should use a sudoers entry like:
+ Defaults env_keep += HOME
+ to preserve the old value of HOME and
+ Defaults env_keep += MAIL
+ to preserve the old value of MAIL.
+
+ * Fixed a problem in the restoration of the AIX authdb registry setting.
+
+ * Sudo will now fork(2) and wait until the command has completed before
+ calling pam_close_session().
+
+ * The default syslog facility is now "authpriv" if the operating system
+ supports it, else "auth".
+
+What's new in Sudo 1.7.3?
+
+ * Support for logging I/O for the command being run.
+ For more information, see the documentation for the "log_input"
+ and "log_output" Defaults options in the sudoers manual. Also
+ see the sudoreplay manual for how to replay I/O log sessions.
+
+ * The use_pty sudoers option can be used to force a command to be
+ run in a pseudo-pty, even when I/O logging is not enabled.
+
+ * On some systems, sudo can now detect when a user has logged out
+ and back in again when tty-based time stamps are in use. Supported
+ systems include Solaris systems with the devices file system,
+ Mac OS X, and Linux systems with the devpts filesystem (pseudo-ttys
+ only).
+
+ * On AIX systems, the registry setting in /etc/security/user is
+ now taken into account when looking up users and groups. Sudo
+ now applies the correct the user and group ids when running a
+ command as a user whose account details come from a different
+ source (e.g. LDAP or DCE vs. local files).
+
+ * Support for multiple 'sudoers_base' and 'uri' entries in ldap.conf.
+ When multiple entries are listed, sudo will try each one in the
+ order in which they are specified.
+
+ * Sudo's SELinux support should now function correctly when running
+ commands as a non-root user and when one of stdin, stdout or stderr
+ is not a terminal.
+
+ * Sudo will now use the Linux audit system with configure with
+ the --with-linux-audit flag.
+
+ * Sudo now uses mbr_check_membership() on systems that support it
+ to determine group membership. Currently, only Darwin (Mac OS X)
+ supports this.
+
+ * When the tty_tickets sudoers option is enabled but there is no
+ terminal device, sudo will no longer use or create a tty-based
+ ticket file. Previously, sudo would use a tty name of "unknown".
+ As a consequence, if a user has no terminal device, sudo will
+ now always prompt for a password.
+
+ * The passwd_timeout and timestamp_timeout options may now be
+ specified as floating point numbers for more granular timeout
+ values.
+
+ * Negating the fqdn option in sudoers now works correctly when sudo
+ is configured with the --with-fqdn option. In previous versions
+ of sudo the fqdn was set before sudoers was parsed.
+
+What's new in Sudo 1.7.2?
+
+ * A new #includedir directive is available in sudoers. This can be
+ used to implement an /etc/sudo.d directory. Files in an includedir
+ are not edited by visudo unless they contain a syntax error.
+
+ * The -g option did not work properly when only setting the group
+ (and not the user). Also, in -l mode the wrong user was displayed
+ for sudoers entries where only the group was allowed to be set.
+
+ * Fixed a problem with the alias checking in visudo which
+ could prevent visudo from exiting.
+
+ * Sudo will now correctly parse the shell-style /etc/environment
+ file format used by pam_env on Linux.
+
+ * When doing password and group database lookups, sudo will only
+ cache an entry by name or by id, depending on how the entry was
+ looked up. Previously, sudo would cache by both name and id
+ from a single lookup, but this breaks sites that have multiple
+ password or group database names that map to the same UID or
+ GID.
+
+ * User and group names in sudoers may now be enclosed in double
+ quotes to avoid having to escape special characters.
+
+ * BSM audit fixes when changing to a non-root UID.
+
+ * Experimental non-Unix group support. Currently only works with
+ Quest Authorization Services and allows Active Directory groups
+ fixes for Minix-3.
+
+ * For Netscape/Mozilla-derived LDAP SDKs the certificate and key
+ paths may be specified as a directory or a file. However, version
+ 5.0 of the SDK only appears to support using a directory (despite
+ documentation to the contrary). If SSL client initialization
+ fails and the certificate or key paths look like they could be
+ default file name, strip off the last path element and try again.
+
+ * A setenv() compatibility fix for Linux systems, where a NULL
+ value is treated the same as an empty string and the variable
+ name is checked against the NULL pointer.
+
+What's new in Sudo 1.7.1?
+
+ * A new Defaults option "pwfeedback" will cause sudo to provide visual
+ feedback when the user is entering a password.
+
+ * A new Defaults option "fast_glob" will cause sudo to use the fnmatch()
+ function for file name globbing instead of glob(). When this option
+ is enabled, sudo will not check the file system when expanding wildcards.
+ This is faster but a side effect is that relative paths with wildcard
+ will no longer work.
+
+ * New BSM audit support for systems that support it such as FreeBSD
+ and Mac OS X.
+
+ * The file name specified with the #include directive may now include
+ a %h escape which is expanded to the short form of hostname.
+
+ * The -k flag may now be specified along with a command, causing the
+ user's timestamp file to be ignored.
+
+ * New support for Tivoli-based LDAP START_TLS, present in AIX.
+
+ * New support for /etc/netsvc.conf on AIX.
+
+ * The unused alias checks in visudo now handle the case of an alias
+ referring to another alias.
+
+What's new in Sudo 1.7.0?
+
+ * Rewritten parser that converts sudoers into a set of data structures.
+ This eliminates a number of ordering issues and makes it possible to
+ apply sudoers Defaults entries before searching for the command.
+ It also adds support for per-command Defaults specifications.
+
+ * Sudoers now supports a #include facility to allow the inclusion of other
+ sudoers-format files.
+
+ * Sudo's -l (list) flag has been enhanced:
+ o applicable Defaults options are now listed
+ o a command argument can be specified for testing whether a user
+ may run a specific command.
+ o a new -U flag can be used in conjunction with "sudo -l" to allow
+ root (or a user with "sudo ALL") list another user's privileges.
+
+ * A new -g flag has been added to allow the user to specify a
+ primary group to run the command as. The sudoers syntax has been
+ extended to include a group section in the Runas specification.
+
+ * A UID may now be used anywhere a username is valid.
+
+ * The "secure_path" run-time Defaults option has been restored.
+
+ * Password and group data is now cached for fast lookups.
+
+ * The file descriptor at which sudo starts closing all open files is now
+ configurable via sudoers and, optionally, the command line.
+
+ * Visudo will now warn about aliases that are defined but not used.
+
+ * The -i and -s command line flags now take an optional command
+ to be run via the shell. Previously, the argument was passed
+ to the shell as a script to run.
+
+ * Improved LDAP support. SASL authentication may now be used in
+ conjunction when connecting to an LDAP server. The krb5_ccname
+ parameter in ldap.conf may be used to enable Kerberos.
+
+ * Support for /etc/nsswitch.conf. LDAP users may now use nsswitch.conf
+ to specify the sudoers order. E.g.:
+ sudoers: ldap files
+ to check LDAP, then /etc/sudoers. The default is "files", even
+ when LDAP support is compiled in. This differs from sudo 1.6
+ where LDAP was always consulted first.
+
+ * Support for /etc/environment on AIX and Linux. If sudo is run
+ with the -i flag, the contents of /etc/environment are used to
+ populate the new environment that is passed to the command being
+ run.
+
+ * If no terminal is available or if the new -A flag is specified,
+ sudo will use a helper program to read the password if one is
+ configured. Typically, this is a graphical password prompter
+ such as ssh-askpass.
+
+ * A new Defaults option, "mailfrom" that sets the value of the
+ "From:" field in the warning/error mail. If unspecified, the
+ login name of the invoking user is used.
+
+ * A new Defaults option, "env_file" that refers to a file containing
+ environment variables to be set in the command being run.
+
+ * A new flag, -n, may be used to indicate that sudo should not
+ prompt the user for a password and, instead, exit with an error
+ if authentication is required.
+
+ * If sudo needs to prompt for a password and it is unable to disable
+ echo (and no askpass program is defined), it will refuse to run
+ unless the "visiblepw" Defaults option has been specified.
+
+ * Prior to version 1.7.0, hitting enter/return at the Password: prompt
+ would exit sudo. In sudo 1.7.0 and beyond, this is treated as
+ an empty password. To exit sudo, the user must press ^C or ^D
+ at the prompt.
+
+ * visudo will now check the sudoers file owner and mode in -c (check)
+ mode when the -s (strict) flag is specified.
+
+ * A new Defaults option "umask_override" will cause sudo to set the
+ umask specified in sudoers even if it is more permissive than the
+ invoking user's umask.
diff --git a/README b/README
new file mode 100644
index 0000000..8127d9e
--- /dev/null
+++ b/README
@@ -0,0 +1,80 @@
+The sudo philosophy
+===================
+Sudo is a program designed to allow a sysadmin to give limited root privileges
+to users and log root activity. The basic philosophy is to give as few
+privileges as possible but still allow people to get their work done.
+
+Where to find sudo
+==================
+Before you try and build sudo, *please* make sure you have the current
+version. The latest sudo may always be gotten via anonymous ftp from
+ftp.sudo.ws in the directory /pub/sudo/ or from the sudo web site,
+https://www.sudo.ws/
+
+The distribution is sudo-M.m.tar.gz where `M' is the major version
+number and `m' is the minor version number. BETA versions of sudo may
+also be available. If you join the `sudo-workers' mailing list you
+will get the BETA announcements (see the `Mailing lists' section below).
+
+What's new
+==========
+See the NEWS file for a list of major changes in this release.
+For a complete list of changes, see the ChangeLog file. For a
+summary of major changes to the current stable release, see the web
+page, https://www.sudo.ws/stable.html.
+
+If you are upgrading from an earlier version of Sudo, please see
+the UPGRADE file in the doc directory.
+
+For a history of sudo please see the HISTORY file in the doc directory.
+You can find a list of contributors to sudo in the doc/CONTRIBUTORS file.
+
+Building the release
+====================
+Please read the installation guide in the `INSTALL' file before trying to
+build sudo. Pay special attention to the "OS dependent notes" section.
+
+Copyright
+=========
+Sudo is distributed under an ISC-style license.
+Please refer to the `LICENSE' file included with the release for details.
+
+Mailing lists
+=============
+sudo-announce This list receives announcements whenever a new version
+ of sudo is released.
+ https://www.sudo.ws/mailman/listinfo/sudo-announce
+
+sudo-users This list is for questions and general discussion about sudo.
+ https://www.sudo.ws/mailman/listinfo/sudo-users
+
+sudo-workers This list is for people working on and porting sudo.
+ https://www.sudo.ws/mailman/listinfo/sudo-workers
+
+sudo-commits This list receives a message for each commit made to
+ the sudo source repository.
+ https://www.sudo.ws/mailman/listinfo/sudo-commits
+
+To subscribe to a list, visit its url (as listed above) and enter
+your email address to subscribe. Digest versions are available but
+these are fairly low traffic lists so the digest versions are not
+a significant win.
+
+Mailing list archives are also available. See the mailing list web sites
+for the appropriate links.
+
+Web page
+========
+There is a sudo web page at https://www.sudo.ws/ that contains an
+overview of sudo, documentation, downloads, a bug tracker, information
+about beta versions and other useful info.
+
+Bug reports
+===========
+If you have found what you believe to be a bug, you can file a bug
+report in the sudo bug database, on the web at https://bugzilla.sudo.ws/.
+
+Please read over the `TROUBLESHOOTING' file in the doc directory *before*
+submitting a bug report. When reporting bugs, please be sure to include
+the version of sudo you are using as well as the platform you are running
+it on.
diff --git a/README.LDAP b/README.LDAP
new file mode 100644
index 0000000..4680d43
--- /dev/null
+++ b/README.LDAP
@@ -0,0 +1,205 @@
+This file explains how to build the optional LDAP functionality of SUDO to
+store /etc/sudoers information. This feature is distinct from LDAP passwords.
+
+For general sudo LDAP configuration details, see the sudoers.ldap manual that
+comes with the sudo distribution. A pre-formatted version of the manual may
+be found in the sudoers.ldap.cat file.
+
+The sudo binary compiled with LDAP support should be totally backward
+compatible and be syntactically and source code equivalent to its
+non LDAP-enabled build.
+
+LDAP philosophy
+===============
+As times change and servers become cheap, an enterprise can easily have 500+
+UNIX servers. Using LDAP to synchronize Users, Groups, Hosts, Mounts, and
+others across an enterprise can greatly reduce the administrative overhead.
+
+In the past, sudo has used a single local configuration file, /etc/sudoers.
+While the same sudoers file can be shared among machines, no built-in
+mechanism exists to distribute it. Some have attempted to workaround this
+by synchronizing changes via CVS/RSYNC/RDIST/RCP/SCP and even NFS.
+
+By using LDAP for sudoers we gain a centrally administered, globally
+available configuration source for sudo.
+
+For information on OpenLDAP, please see http://www.openldap.org/.
+
+Definitions
+===========
+Many times the word 'Directory' is used in the document to refer to the LDAP
+server, structure and contents.
+
+Many times 'options' are used in this document to refer to sudoer 'defaults'.
+They are one and the same.
+
+Build instructions
+==================
+The simplest way to build sudo with LDAP support is to include the
+'--with-ldap' option.
+
+ $ ./configure --with-ldap
+
+If your ldap libraries and headers are in a non-standard place, you will need
+to specify them at configure time. E.g.
+
+ $ ./configure --with-ldap=/usr/local/ldapsdk
+
+Sudo is developed using OpenLDAP but Netscape-based LDAP libraries
+(such as those present in Solaris) are also known to work.
+
+Your mileage may vary. Please let the sudo workers mailing list
+<sudo-workers@sudo.ws> know if special configuration was required
+to build an LDAP-enabled sudo so we can improve sudo.
+
+Schema Changes
+==============
+You must add the appropriate schema to your LDAP server before it
+can store sudoers content.
+
+For OpenLDAP, there are two options, depending on how slapd is configured.
+
+The first option is to copy the file schema.OpenLDAP to the schema
+directory (e.g. /etc/openldap/schema). You must then edit your
+slapd.conf and add an include line the new schema, e.g.
+
+ # Sudo LDAP schema
+ include /etc/openldap/schema/sudo.schema
+
+In order for sudoRole LDAP queries to be efficient, the server must index
+the attribute 'sudoUser', e.g.
+
+ # Indices to maintain
+ index sudoUser eq
+
+After making the changes to slapd.conf, restart slapd.
+
+The second option is only for OpenLDAP 2.3 and higher where slapd.conf
+has been configured to use on-line configuration. If your slapd.conf
+file includes the line:
+
+ database config
+
+it should be possible to use the schema.olcSudo file.
+
+You can apply schema.olcSudo using the ldapadd utility or another
+suitable LDAP browser. For example:
+
+ # ldapadd -f schema.olcSudo -H ldap://ldapserver -W -x \
+ -D cn=Manager,dc=example,dc=com
+
+There is no need to restart slapd when updating on-line configuration.
+
+For Netscape-derived LDAP servers such as SunONE, iPlanet or Fedora Directory,
+copy the schema.iPlanet file to the schema directory with the name 99sudo.ldif.
+
+On Solaris, schemas are stored in /var/Sun/mps/slapd-`hostname`/config/schema/.
+For Fedora Directory Server, they are stored in /etc/dirsrv/schema/.
+
+After copying the schema file to the appropriate directory, restart
+the LDAP server.
+
+Finally, using an LDAP browser/editor, enable indexing by editing the
+client profile to provide a Service Search Descriptor (SSD) for sudoers,
+replacing example.com with your domain:
+
+ serviceSearchDescriptor: sudoers: ou=sudoers,dc=example,dc=com
+
+If using an Active Directory server, copy schema.ActiveDirectory
+to your Windows domain controller and run the following command:
+
+ ldifde -i -f schema.ActiveDirectory -c dc=X dc=example,dc=com
+
+Importing /etc/sudoers into LDAP
+================================
+Importing sudoers is a two-step process.
+
+Step 1:
+Ask your LDAP Administrator where to create the ou=SUDOers container.
+
+For instance, if using OpenLDAP:
+
+ dn: ou=SUDOers,dc=example,dc=com
+ objectClass: top
+ objectClass: organizationalUnit
+ ou: SUDOers
+
+(An example location is shown below). Then use the cvtsudoers utility to
+convert your sudoers file into LDIF format.
+
+ # SUDOERS_BASE=ou=SUDOers,dc=example,dc=com
+ # export SUDOERS_BASE
+ # cvtsudoers -f ldif -o /tmp/sudoers.ldif /etc/sudoers
+
+Step 2:
+Import into your directory server. The following example is for
+OpenLDAP. If you are using another directory, provide the LDIF
+file to your LDAP Administrator.
+
+ # ldapadd -f /tmp/sudoers.ldif -H ldap://ldapserver \
+ -D cn=Manager,dc=example,dc=com -W -x
+
+Step 3:
+Verify the sudoers LDAP data:
+
+ # ldapsearch -b "$SUDOERS_BASE" -D cn=Manager,dc=example,dc=com -W -x
+
+Managing LDAP entries
+=====================
+Doing a one-time bulk load of your ldap entries is fine. However what if you
+need to make minor changes on a daily basis? It doesn't make sense to delete
+and re-add objects. (You can, but this is tedious).
+
+I recommend using any of the following LDAP browsers to administer your SUDOers.
+ * GQ - The gentleman's LDAP client - Open Source - I use this a lot on Linux
+ and since it is Schema aware, I don't need to create a sudoRole template.
+ http://sourceforge.net/projects/gqclient/
+
+ * phpQLAdmin - Open Source - phpQLAdmin is an administration tool,
+ originally for QmailLDAP, that supports editing sudoRole objects
+ in version 2.3.2 and higher.
+ http://phpqladmin.com/
+
+ * LDAP Browser/Editor - by Jarek Gawor - I use this a lot on Windows
+ and Solaris. It runs anywhere in a Java Virtual Machine including
+ web pages. You have to make a template from an existing sudoRole entry.
+ http://www.iit.edu/~gawojar/ldap
+ http://www.mcs.anl.gov/~gawor/ldap
+ http://ldapmanager.com
+
+ * Apache Directory Studio - Open Source - an Eclipse-based LDAP
+ development platform. Includes an LDAP browser, and LDIF editor,
+ a schema editor and more.
+ http://directory.apache.org/studio
+
+ There are dozens of others, some Open Source, some free, some not.
+
+Configure your /etc/ldap.conf and /etc/nsswitch.conf
+====================================================
+The /etc/ldap.conf file is meant to be shared between sudo, pam_ldap, nss_ldap
+and other ldap applications and modules. IBM Secureway unfortunately uses
+the same file name but has a different syntax. If you need to change where
+this file is stored, re-run configure with the --with-ldap-conf-file=PATH
+option.
+
+See the "Configuring ldap.conf" section in the sudoers.ldap manual
+for a list of supported ldap.conf parameters and an example ldap.conf
+
+Make sure you sudoers_base matches the location you specified when you
+imported the sudoers ldif data.
+
+After configuring /etc/ldap.conf, you must add a line in /etc/nsswitch.conf
+to tell sudo to look in LDAP for sudoers. See the "Configuring nsswitch.conf"
+section in the sudoers.ldap manual for details. Note that sudo will use
+/etc/nsswitch.conf even if the underlying operating system does not support it.
+To disable nsswitch support, run configure with the --with-nsswitch=no option.
+This will cause sudo to consult LDAP first and /etc/sudoers second, unless the
+ignore_sudoers_file flag is set in the global LDAP options.
+
+Debugging your LDAP configuration
+=================================
+Enable debugging if you believe sudo is not parsing LDAP the way you think it
+should. Setting the 'sudoers_debug' parameter to a value of 1 shows moderate
+debugging. A value of 2 shows the results of the matches themselves. Make
+sure to set the value back to zero so that other users don't get confused by
+the debugging messages.
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..4bc9f8c
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,139 @@
+# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+# longlong.m4 serial 17
+dnl Copyright (C) 1999-2007, 2009-2016 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+# Define HAVE_LONG_LONG_INT if 'long long int' works.
+# This fixes a bug in Autoconf 2.61, and can be faster
+# than what's in Autoconf 2.62 through 2.68.
+
+# Note: If the type 'long long int' exists but is only 32 bits large
+# (as on some very old compilers), HAVE_LONG_LONG_INT will not be
+# defined. In this case you can treat 'long long int' like 'long int'.
+
+AC_DEFUN([AC_TYPE_LONG_LONG_INT],
+[
+ AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
+ AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int],
+ [ac_cv_type_long_long_int=yes
+ if test "x${ac_cv_prog_cc_c99-no}" = xno; then
+ ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int
+ if test $ac_cv_type_long_long_int = yes; then
+ dnl Catch a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004.
+ dnl If cross compiling, assume the bug is not important, since
+ dnl nobody cross compiles for this platform as far as we know.
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[@%:@include <limits.h>
+ @%:@ifndef LLONG_MAX
+ @%:@ define HALF \
+ (1LL << (sizeof (long long int) * CHAR_BIT - 2))
+ @%:@ define LLONG_MAX (HALF - 1 + HALF)
+ @%:@endif]],
+ [[long long int n = 1;
+ int i;
+ for (i = 0; ; i++)
+ {
+ long long int m = n << i;
+ if (m >> i != n)
+ return 1;
+ if (LLONG_MAX / 2 < m)
+ break;
+ }
+ return 0;]])],
+ [],
+ [ac_cv_type_long_long_int=no],
+ [:])
+ fi
+ fi])
+ if test $ac_cv_type_long_long_int = yes; then
+ AC_DEFINE([HAVE_LONG_LONG_INT], [1],
+ [Define to 1 if the system has the type 'long long int'.])
+ fi
+])
+
+# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works.
+# This fixes a bug in Autoconf 2.61, and can be faster
+# than what's in Autoconf 2.62 through 2.68.
+
+# Note: If the type 'unsigned long long int' exists but is only 32 bits
+# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT
+# will not be defined. In this case you can treat 'unsigned long long int'
+# like 'unsigned long int'.
+
+AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT],
+[
+ AC_CACHE_CHECK([for unsigned long long int],
+ [ac_cv_type_unsigned_long_long_int],
+ [ac_cv_type_unsigned_long_long_int=yes
+ if test "x${ac_cv_prog_cc_c99-no}" = xno; then
+ AC_LINK_IFELSE(
+ [_AC_TYPE_LONG_LONG_SNIPPET],
+ [],
+ [ac_cv_type_unsigned_long_long_int=no])
+ fi])
+ if test $ac_cv_type_unsigned_long_long_int = yes; then
+ AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1],
+ [Define to 1 if the system has the type 'unsigned long long int'.])
+ fi
+])
+
+# Expands to a C program that can be used to test for simultaneous support
+# of 'long long' and 'unsigned long long'. We don't want to say that
+# 'long long' is available if 'unsigned long long' is not, or vice versa,
+# because too many programs rely on the symmetry between signed and unsigned
+# integer types (excluding 'bool').
+AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET],
+[
+ AC_LANG_PROGRAM(
+ [[/* For now, do not test the preprocessor; as of 2007 there are too many
+ implementations with broken preprocessors. Perhaps this can
+ be revisited in 2012. In the meantime, code should not expect
+ #if to work with literals wider than 32 bits. */
+ /* Test literals. */
+ long long int ll = 9223372036854775807ll;
+ long long int nll = -9223372036854775807LL;
+ unsigned long long int ull = 18446744073709551615ULL;
+ /* Test constant expressions. */
+ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+ ? 1 : -1)];
+ typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+ ? 1 : -1)];
+ int i = 63;]],
+ [[/* Test availability of runtime routines for shift and division. */
+ long long int llmax = 9223372036854775807ll;
+ unsigned long long int ullmax = 18446744073709551615ull;
+ return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+ | (llmax / ll) | (llmax % ll)
+ | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+ | (ullmax / ull) | (ullmax % ull));]])
+])
+
+m4_include([m4/ax_append_flag.m4])
+m4_include([m4/ax_check_compile_flag.m4])
+m4_include([m4/ax_check_link_flag.m4])
+m4_include([m4/ax_func_getaddrinfo.m4])
+m4_include([m4/ax_func_snprintf.m4])
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
+m4_include([m4/sudo.m4])
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..890eac7
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# OpenBSD may have multiple versions of autoconf and automake installed
+# If the user hasn't chosen one themselves, we do here.
+if [ "`/usr/bin/uname 2>&1`" = "OpenBSD" ]; then
+ if [ X"$AUTOMAKE_VERSION" = X"" ]; then
+ AUTOMAKE_VERSION=1.15; export AUTOMAKE_VERSION
+ fi
+ if [ X"$AUTOCONF_VERSION" = X"" ]; then
+ AUTOCONF_VERSION=2.69; export AUTOCONF_VERSION
+ fi
+fi
+
+set -ex
+
+autoreconf -f -i -v -Wall -I m4
+
+rm -rf autom4te.cache
+
+exit 0
diff --git a/config.guess b/config.guess
new file mode 100644
index 0000000..2e9ad7f
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,1462 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2016 Free Software Foundation, Inc.
+
+timestamp='2016-10-02'
+
+# This file 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+#
+# Please send patches to <config-patches@gnu.org>.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2016 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+ /sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || \
+ echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ earmv*)
+ arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine=${arch}${endian}-unknown
+ ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently (or will in the future) and ABI.
+ case "${UNAME_MACHINE_ARCH}" in
+ earm*)
+ os=netbsdelf
+ ;;
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # Determine ABI tags.
+ case "${UNAME_MACHINE_ARCH}" in
+ earm*)
+ expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+ abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}${abi}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:LibertyBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:Sortix:*:*)
+ echo ${UNAME_MACHINE}-unknown-sortix
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE=alpha ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE=alpha ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE=alpha ;;
+ "EV5 (21164)")
+ UNAME_MACHINE=alphaev5 ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE=alphaev56 ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE=alphapca56 ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE=alphapca57 ;;
+ "EV6 (21264)")
+ UNAME_MACHINE=alphaev6 ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE=alphaev67 ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE=alphaev68 ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE=alphaev68 ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE=alphaev68 ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE=alphaev69 ;;
+ "EV7 (21364)")
+ UNAME_MACHINE=alphaev7 ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE=alphaev79 ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH=i386
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH=x86_64
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH=hppa2.0n ;;
+ 64) HP_ARCH=hppa2.0w ;;
+ '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = hppa2.0w ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH=hppa2.0w
+ else
+ HP_ARCH=hppa64
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ *:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ e2k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ k1om:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ mips64el:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ riscv32:Linux:*:* | riscv64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configure will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-ACE:SUPER-UX:*:*)
+ echo sxace-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = x86; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = 386; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+ amd64:Isilon\ OneFS:*:*)
+ echo x86_64-unknown-onefs
+ exit ;;
+esac
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite
+config.guess and config.sub with the latest versions from:
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches@gnu.org to
+provide the necessary information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..9b83b12
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,1303 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+#ifndef SUDO_CONFIG_H
+#define SUDO_CONFIG_H
+
+/* Define to 1 if you want the insults from the "classic" version sudo. */
+#undef CLASSIC_INSULTS
+
+/* Define to 1 if you want insults culled from the twisted minds of CSOps. */
+#undef CSOPS_INSULTS
+
+/* Define to 1 if you want sudo to display "command not allowed" instead of
+ "command not found" when a command cannot be found. */
+#undef DONT_LEAK_PATH_INFO
+
+/* A colon-separated list of pathnames to be used as the editor for visudo. */
+#undef EDITOR
+
+/* Define to 1 to enable sudo's plugin interface. */
+#undef ENABLE_SUDO_PLUGIN_API
+
+/* Define to 1 to enable environment function debugging. */
+#undef ENV_DEBUG
+
+/* Define to 1 if you want visudo to honor the EDITOR and VISUAL env
+ variables. */
+#undef ENV_EDITOR
+
+/* Define to 1 to enable environment resetting by default. */
+#undef ENV_RESET
+
+/* If defined, users in this group need not enter a passwd (ie "sudo"). */
+#undef EXEMPTGROUP
+
+/* Define to 1 if you want to require fully qualified hosts in sudoers. */
+#undef FQDN
+
+/* Define to the type of elements in the array set by `getgroups'. Usually
+ this is either `int' or `gid_t'. */
+#undef GETGROUPS_T
+
+/* Define to 1 if you want insults from the "Goon Show". */
+#undef GOONS_INSULTS
+
+/* Define to 1 if you want 2001-like insults. */
+#undef HAL_INSULTS
+
+/* Define to 1 if you use AFS. */
+#undef HAVE_AFS
+
+/* Define to 1 if you use AIX general authentication. */
+#undef HAVE_AIXAUTH
+
+/* Define to 1 if you have the `arc4random' function. */
+#undef HAVE_ARC4RANDOM
+
+/* Define to 1 if you have the `arc4random_uniform' function. */
+#undef HAVE_ARC4RANDOM_UNIFORM
+
+/* Define to 1 if you have the `asprintf' function. */
+#undef HAVE_ASPRINTF
+
+/* Define to 1 if the system has the type `authdb_t'. */
+#undef HAVE_AUTHDB_T
+
+/* Define to 1 if you have the `authenticate' function. */
+#undef HAVE_AUTHENTICATE
+
+/* Define to 1 if you have the `auth_challenge' function. */
+#undef HAVE_AUTH_CHALLENGE
+
+/* Define to 1 if the `au_close' functions takes 4 arguments like Solaris 11.
+ */
+#undef HAVE_AU_CLOSE_SOLARIS11
+
+/* Define to 1 if you have the `bigcrypt' function. */
+#undef HAVE_BIGCRYPT
+
+/* Define to 1 if you use BSD authentication. */
+#undef HAVE_BSD_AUTH_H
+
+/* Define to 1 to enable BSM audit support. */
+#undef HAVE_BSM_AUDIT
+
+/* Define to 1 if you have the `clock_gettime' function. */
+#undef HAVE_CLOCK_GETTIME
+
+/* Define to 1 if you have the `closefrom' function. */
+#undef HAVE_CLOSEFROM
+
+/* Define to 1 if you use OSF DCE. */
+#undef HAVE_DCE
+
+/* Define to 1 if your `DIR' contains dd_fd. */
+#undef HAVE_DD_FD
+
+/* Define to 1 if you have the declaration of `errno', and to 0 if you don't.
+ */
+#undef HAVE_DECL_ERRNO
+
+/* Define to 1 if you have the declaration of `getdomainname', and to 0 if you
+ don't. */
+#undef HAVE_DECL_GETDOMAINNAME
+
+/* Define to 1 if you have the declaration of `getgrouplist_2', and to 0 if
+ you don't. */
+#undef HAVE_DECL_GETGROUPLIST_2
+
+/* Define to 1 if you have the declaration of `getresuid', and to 0 if you
+ don't. */
+#undef HAVE_DECL_GETRESUID
+
+/* Define to 1 if you have the declaration of `h_errno', and to 0 if you
+ don't. */
+#undef HAVE_DECL_H_ERRNO
+
+/* Define to 1 if you have the declaration of `innetgr', and to 0 if you
+ don't. */
+#undef HAVE_DECL_INNETGR
+
+/* Define to 1 if you have the declaration of `LLONG_MAX', and to 0 if you
+ don't. */
+#undef HAVE_DECL_LLONG_MAX
+
+/* Define to 1 if you have the declaration of `LLONG_MIN', and to 0 if you
+ don't. */
+#undef HAVE_DECL_LLONG_MIN
+
+/* Define to 1 if you have the declaration of `PATH_MAX', and to 0 if you
+ don't. */
+#undef HAVE_DECL_PATH_MAX
+
+/* Define to 1 if you have the declaration of `QUAD_MAX', and to 0 if you
+ don't. */
+#undef HAVE_DECL_QUAD_MAX
+
+/* Define to 1 if you have the declaration of `QUAD_MIN', and to 0 if you
+ don't. */
+#undef HAVE_DECL_QUAD_MIN
+
+/* Define to 1 if you have the declaration of `SECCOMP_SET_MODE_FILTER', and
+ to 0 if you don't. */
+#undef HAVE_DECL_SECCOMP_SET_MODE_FILTER
+
+/* Define to 1 if you have the declaration of `setauthdb', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SETAUTHDB
+
+/* Define to 1 if you have the declaration of `setresuid', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SETRESUID
+
+/* Define to 1 if you have the declaration of `SIG2STR_MAX', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SIG2STR_MAX
+
+/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SIZE_MAX
+
+/* Define to 1 if you have the declaration of `SIZE_T_MAX', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SIZE_T_MAX
+
+/* Define to 1 if you have the declaration of `sys_sigabbrev', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SYS_SIGABBREV
+
+/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SYS_SIGLIST
+
+/* Define to 1 if you have the declaration of `sys_signame', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SYS_SIGNAME
+
+/* Define to 1 if you have the declaration of `ULLONG_MAX', and to 0 if you
+ don't. */
+#undef HAVE_DECL_ULLONG_MAX
+
+/* Define to 1 if you have the declaration of `UQUAD_MAX', and to 0 if you
+ don't. */
+#undef HAVE_DECL_UQUAD_MAX
+
+/* Define to 1 if you have the declaration of `usrinfo', and to 0 if you
+ don't. */
+#undef HAVE_DECL_USRINFO
+
+/* Define to 1 if you have the declaration of `_innetgr', and to 0 if you
+ don't. */
+#undef HAVE_DECL__INNETGR
+
+/* Define to 1 if you have the declaration of `_POSIX_PATH_MAX', and to 0 if
+ you don't. */
+#undef HAVE_DECL__POSIX_PATH_MAX
+
+/* Define to 1 if you have the declaration of `_sys_siglist', and to 0 if you
+ don't. */
+#undef HAVE_DECL__SYS_SIGLIST
+
+/* Define to 1 if you have the declaration of `_sys_signame', and to 0 if you
+ don't. */
+#undef HAVE_DECL__SYS_SIGNAME
+
+/* Define to 1 if you have the `devname' function. */
+#undef HAVE_DEVNAME
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the `dirfd' function or macro. */
+#undef HAVE_DIRFD
+
+/* Define to 1 if you have the `dispcrypt' function. */
+#undef HAVE_DISPCRYPT
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `dlopen' function. */
+#undef HAVE_DLOPEN
+
+/* Define to 1 if you have the `dl_iterate_phdr' function. */
+#undef HAVE_DL_ITERATE_PHDR
+
+/* Define to 1 if the compiler supports the __visibility__ attribute. */
+#undef HAVE_DSO_VISIBILITY
+
+/* Define to 1 if you have the <endian.h> header file. */
+#undef HAVE_ENDIAN_H
+
+/* Define to 1 if you have the `exect' function. */
+#undef HAVE_EXECT
+
+/* Define to 1 if you have the `execvP' function. */
+#undef HAVE_EXECVP
+
+/* Define to 1 if you have the `execvpe' function. */
+#undef HAVE_EXECVPE
+
+/* Define to 1 if you have the `faccessat' function. */
+#undef HAVE_FACCESSAT
+
+/* Define to 1 if your system has the F_CLOSEM fcntl. */
+#undef HAVE_FCNTL_CLOSEM
+
+/* Define to 1 if you have the `fexecve' function. */
+#undef HAVE_FEXECVE
+
+/* Define to 1 if you have the `fgetln' function. */
+#undef HAVE_FGETLN
+
+/* Define to 1 if you have the `fnmatch' function. */
+#undef HAVE_FNMATCH
+
+/* Define to 1 if you have the `freeifaddrs' function. */
+#undef HAVE_FREEIFADDRS
+
+/* Define to 1 if you have the `fseeko' function. */
+#undef HAVE_FSEEKO
+
+/* Define to 1 if you have the `futime' function. */
+#undef HAVE_FUTIME
+
+/* Define to 1 if you have the `futimens' function. */
+#undef HAVE_FUTIMENS
+
+/* Define to 1 if you have the `futimes' function. */
+#undef HAVE_FUTIMES
+
+/* Define to 1 if you have the `futimesat' function. */
+#undef HAVE_FUTIMESAT
+
+/* Define to 1 if you use the FWTK authsrv daemon. */
+#undef HAVE_FWTK
+
+/* Define to 1 if you are using gcrypt's sha2 functions. */
+#undef HAVE_GCRYPT
+
+/* Define to 1 if you have the `getaddrinfo' function. */
+#undef HAVE_GETADDRINFO
+
+/* Define to 1 if you have the `getauxval' function. */
+#undef HAVE_GETAUXVAL
+
+/* Define to 1 if you have the `getdomainname' function. */
+#undef HAVE_GETDOMAINNAME
+
+/* Define to 1 if you have the `getentropy' function. */
+#undef HAVE_GETENTROPY
+
+/* Define to 1 if you have the `getgrouplist' function. */
+#undef HAVE_GETGROUPLIST
+
+/* Define to 1 if you have the `getgrouplist_2' function. */
+#undef HAVE_GETGROUPLIST_2
+
+/* Define to 1 if your system has a working `getgroups' function. */
+#undef HAVE_GETGROUPS
+
+/* Define to 1 if you have the `getgrset' function. */
+#undef HAVE_GETGRSET
+
+/* Define to 1 if you have the `gethrtime' function. */
+#undef HAVE_GETHRTIME
+
+/* Define to 1 if you have the `getifaddrs' function. */
+#undef HAVE_GETIFADDRS
+
+/* Define to 1 if you have the `getline' function. */
+#undef HAVE_GETLINE
+
+/* Define to 1 if you have the `getopt_long' function. */
+#undef HAVE_GETOPT_LONG
+
+/* Define to 1 if you have the `getprogname' function. */
+#undef HAVE_GETPROGNAME
+
+/* Define to 1 if you have the `getprpwnam' function. (SecureWare-style shadow
+ passwords). */
+#undef HAVE_GETPRPWNAM
+
+/* Define to 1 if you have the `getpwnam_shadow' function. */
+#undef HAVE_GETPWNAM_SHADOW
+
+/* Define to 1 if you have the `getresuid' function. */
+#undef HAVE_GETRESUID
+
+/* Define to 1 if you have the `getspnam' function (SVR4-style shadow
+ passwords). */
+#undef HAVE_GETSPNAM
+
+/* Define to 1 if you have the `getttyent' function. */
+#undef HAVE_GETTTYENT
+
+/* Define to 1 if you have the `getuserattr' function. */
+#undef HAVE_GETUSERATTR
+
+/* Define to 1 if you have the `getutid' function. */
+#undef HAVE_GETUTID
+
+/* Define to 1 if you have the `getutsid' function. */
+#undef HAVE_GETUTSID
+
+/* Define to 1 if you have the `getutxid' function. */
+#undef HAVE_GETUTXID
+
+/* Define to 1 if you have the `glob' function. */
+#undef HAVE_GLOB
+
+/* Define to 1 if you have the `grantpt' function. */
+#undef HAVE_GRANTPT
+
+/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
+#undef HAVE_GSSAPI_GSSAPI_KRB5_H
+
+/* Define to 1 if you have the `gss_krb5_ccache_name' function. */
+#undef HAVE_GSS_KRB5_CCACHE_NAME
+
+/* Define to 1 if your Kerberos is Heimdal. */
+#undef HAVE_HEIMDAL
+
+/* Define to 1 if you have the `inet_ntop' function. */
+#undef HAVE_INET_NTOP
+
+/* Define to 1 if you have the `inet_pton' function. */
+#undef HAVE_INET_PTON
+
+/* Define to 1 if you have the `initprivs' function. */
+#undef HAVE_INITPRIVS
+
+/* Define to 1 if you have the `innetgr' function. */
+#undef HAVE_INNETGR
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if you have isblank(3). */
+#undef HAVE_ISBLANK
+
+/* Define to 1 if you have the `iscomsec' function. (HP-UX >= 10.x check for
+ shadow enabled). */
+#undef HAVE_ISCOMSEC
+
+/* Define to 1 if you use Kerberos V. */
+#undef HAVE_KERB5
+
+/* Define to 1 if you have the `killpg' function. */
+#undef HAVE_KILLPG
+
+/* Define to 1 if your system has a NetBSD-style kinfo_proc2 struct. */
+#undef HAVE_KINFO_PROC2_NETBSD
+
+/* Define to 1 if your system has a 4.4BSD-style kinfo_proc struct. */
+#undef HAVE_KINFO_PROC_44BSD
+
+/* Define to 1 if your system has a FreeBSD-style kinfo_proc struct. */
+#undef HAVE_KINFO_PROC_FREEBSD
+
+/* Define to 1 if your system has an OpenBSD-style kinfo_proc struct. */
+#undef HAVE_KINFO_PROC_OPENBSD
+
+/* Define to 1 if you have the `krb5_get_init_creds_opt_alloc' function. */
+#undef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
+
+/* Define to 1 if your `krb5_get_init_creds_opt_free' function takes two
+ arguments. */
+#undef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_TWO_ARGS
+
+/* Define to 1 if you have the `krb5_init_secure_context' function. */
+#undef HAVE_KRB5_INIT_SECURE_CONTEXT
+
+/* Define to 1 if you have the `krb5_verify_user' function. */
+#undef HAVE_KRB5_VERIFY_USER
+
+/* Define to 1 if your LDAP needs <lber.h>. (OpenLDAP does not). */
+#undef HAVE_LBER_H
+
+/* Define to 1 if you use LDAP for sudoers. */
+#undef HAVE_LDAP
+
+/* Define to 1 if you have the `ldapssl_init' function. */
+#undef HAVE_LDAPSSL_INIT
+
+/* Define to 1 if you have the `ldapssl_set_strength' function. */
+#undef HAVE_LDAPSSL_SET_STRENGTH
+
+/* Define to 1 if you have the `ldap_create' function. */
+#undef HAVE_LDAP_CREATE
+
+/* Define to 1 if you have the `ldap_initialize' function. */
+#undef HAVE_LDAP_INITIALIZE
+
+/* Define to 1 if you have the `ldap_sasl_bind_s' function. */
+#undef HAVE_LDAP_SASL_BIND_S
+
+/* Define to 1 if you have the `ldap_sasl_interactive_bind_s' function. */
+#undef HAVE_LDAP_SASL_INTERACTIVE_BIND_S
+
+/* Define to 1 if you have the `ldap_search_ext_s' function. */
+#undef HAVE_LDAP_SEARCH_EXT_S
+
+/* Define to 1 if you have the `ldap_search_st' function. */
+#undef HAVE_LDAP_SEARCH_ST
+
+/* Define to 1 if you have the `ldap_ssl_client_init' function. */
+#undef HAVE_LDAP_SSL_CLIENT_INIT
+
+/* Define to 1 if you have the <ldap_ssl.h> header file. */
+#undef HAVE_LDAP_SSL_H
+
+/* Define to 1 if you have the `ldap_ssl_init' function. */
+#undef HAVE_LDAP_SSL_INIT
+
+/* Define to 1 if you have the `ldap_start_tls_s' function. */
+#undef HAVE_LDAP_START_TLS_S
+
+/* Define to 1 if you have the `ldap_start_tls_s_np' function. */
+#undef HAVE_LDAP_START_TLS_S_NP
+
+/* Define to 1 if you have the `ldap_str2dn' function. */
+#undef HAVE_LDAP_STR2DN
+
+/* Define to 1 if you have the `ldap_unbind_ext_s' function. */
+#undef HAVE_LDAP_UNBIND_EXT_S
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define to 1 if you have the <libutil.h> header file. */
+#undef HAVE_LIBUTIL_H
+
+/* Define to 1 to enable Linux audit support. */
+#undef HAVE_LINUX_AUDIT
+
+/* Define to 1 if you have the <linux/random.h> header file. */
+#undef HAVE_LINUX_RANDOM_H
+
+/* Define to 1 if you have the `lockf' function. */
+#undef HAVE_LOCKF
+
+/* Define to 1 if you have the <login_cap.h> header file. */
+#undef HAVE_LOGIN_CAP_H
+
+/* Define to 1 if the system has the type 'long long int'. */
+#undef HAVE_LONG_LONG_INT
+
+/* Define to 1 if you have the `lrand48' function. */
+#undef HAVE_LRAND48
+
+/* Define to 1 if you have the <machine/endian.h> header file. */
+#undef HAVE_MACHINE_ENDIAN_H
+
+/* Define to 1 if you have the `mach_continuous_time' function. */
+#undef HAVE_MACH_CONTINUOUS_TIME
+
+/* Define to 1 if you have the <maillock.h> header file. */
+#undef HAVE_MAILLOCK_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memrchr' function. */
+#undef HAVE_MEMRCHR
+
+/* Define to 1 if you have the `memset_s' function. */
+#undef HAVE_MEMSET_S
+
+/* Define to 1 if you have the `mkdtemp' function. */
+#undef HAVE_MKDTEMP
+
+/* Define to 1 if you have the `mkstemps' function. */
+#undef HAVE_MKSTEMPS
+
+/* Define to 1 if you have the <mps/ldap_ssl.h> header file. */
+#undef HAVE_MPS_LDAP_SSL_H
+
+/* Define to 1 if you have the `nanosleep' function. */
+#undef HAVE_NANOSLEEP
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the <netgroup.h> header file. */
+#undef HAVE_NETGROUP_H
+
+/* Define to 1 if you have the `ngettext' function. */
+#undef HAVE_NGETTEXT
+
+/* Define to 1 if you have the `nl_langinfo' function. */
+#undef HAVE_NL_LANGINFO
+
+/* Define to 1 if you have the <nss_dbdefs.h> header file. */
+#undef HAVE_NSS_DBDEFS_H
+
+/* Define to 1 if you have the `nss_search' function. */
+#undef HAVE_NSS_SEARCH
+
+/* Define to 1 if you have the `openat' function. */
+#undef HAVE_OPENAT
+
+/* Define to 1 if you have the `openpty' function. */
+#undef HAVE_OPENPTY
+
+/* Define to 1 if you are using OpenSSL's sha2 functions. */
+#undef HAVE_OPENSSL
+
+/* Define to 1 if you use NRL OPIE. */
+#undef HAVE_OPIE
+
+/* Define to 1 if you have the `optreset' symbol. */
+#undef HAVE_OPTRESET
+
+/* Define to 1 if you use PAM authentication. */
+#undef HAVE_PAM
+
+/* Define to 1 if you have the `pam_getenvlist' function. */
+#undef HAVE_PAM_GETENVLIST
+
+/* Define to 1 if you use a specific PAM session for sudo -i. */
+#undef HAVE_PAM_LOGIN
+
+/* Define to 1 if you have the <pam/pam_appl.h> header file. */
+#undef HAVE_PAM_PAM_APPL_H
+
+/* Define to 1 if you have the <paths.h> header file. */
+#undef HAVE_PATHS_H
+
+/* Define to 1 if you have the `pipe2' function. */
+#undef HAVE_PIPE2
+
+/* Define to 1 if you have the `poll' function. */
+#undef HAVE_POLL
+
+/* Define to 1 if you have the `posix_openpt' function. */
+#undef HAVE_POSIX_OPENPT
+
+/* Define to 1 if you have the `posix_spawn' function. */
+#undef HAVE_POSIX_SPAWN
+
+/* Define to 1 if you have the `posix_spawnp' function. */
+#undef HAVE_POSIX_SPAWNP
+
+/* Define to 1 if you have the `ppoll' function. */
+#undef HAVE_PPOLL
+
+/* Define to 1 if you have the `pread' function. */
+#undef HAVE_PREAD
+
+/* Define to 1 if you have the `pread64' function. */
+#undef HAVE_PREAD64
+
+/* Define to 1 if you have the `priv_set' function. */
+#undef HAVE_PRIV_SET
+
+/* Define to 1 if you have the <procfs.h> header file. */
+#undef HAVE_PROCFS_H
+
+/* Define to 1 if you have the <project.h> header file. */
+#undef HAVE_PROJECT_H
+
+/* Define to 1 if you have the `pselect' function. */
+#undef HAVE_PSELECT
+
+/* Define to 1 if you have the `pstat_getproc' function. */
+#undef HAVE_PSTAT_GETPROC
+
+/* Define to 1 if you have the `pthread_atfork' function. */
+#undef HAVE_PTHREAD_ATFORK
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
+/* Define to 1 if you have the <pty.h> header file. */
+#undef HAVE_PTY_H
+
+/* Define to 1 if you have the `pwrite' function. */
+#undef HAVE_PWRITE
+
+/* Define to 1 if you have the `pwrite64' function. */
+#undef HAVE_PWRITE64
+
+/* Define to 1 if you have the `pw_dup' function. */
+#undef HAVE_PW_DUP
+
+/* Define to 1 if you have the `random' function. */
+#undef HAVE_RANDOM
+
+/* Define to 1 if you have the `reallocarray' function. */
+#undef HAVE_REALLOCARRAY
+
+/* Define to 1 if you have the `revoke' function. */
+#undef HAVE_REVOKE
+
+/* Define to 1 if the skeychallenge() function is RFC1938-compliant and takes
+ 4 arguments. */
+#undef HAVE_RFC1938_SKEYCHALLENGE
+
+/* Define to 1 if you have the <sasl.h> header file. */
+#undef HAVE_SASL_H
+
+/* Define to 1 if you have the <sasl/sasl.h> header file. */
+#undef HAVE_SASL_SASL_H
+
+/* Define to 1 if you use SecurID for authentication. */
+#undef HAVE_SECURID
+
+/* Define to 1 if you have the <security/pam_appl.h> header file. */
+#undef HAVE_SECURITY_PAM_APPL_H
+
+/* Define to 1 to enable SELinux RBAC support. */
+#undef HAVE_SELINUX
+
+/* Define to 1 if you have the `setauthdb' function. */
+#undef HAVE_SETAUTHDB
+
+/* Define to 1 if you have the `seteuid' function. */
+#undef HAVE_SETEUID
+
+/* Define to 1 if you have the `setgroupent' function. */
+#undef HAVE_SETGROUPENT
+
+/* Define to 1 if you have the `setkeycreatecon' function. */
+#undef HAVE_SETKEYCREATECON
+
+/* Define to 1 if you have the `setpassent' function. */
+#undef HAVE_SETPASSENT
+
+/* Define to 1 if you have the `setprogname' function. */
+#undef HAVE_SETPROGNAME
+
+/* Define to 1 if you have the `setresuid' function. */
+#undef HAVE_SETRESUID
+
+/* Define to 1 if you have the `setreuid' function. */
+#undef HAVE_SETREUID
+
+/* Define to 1 if you have the `setrlimit64' function. */
+#undef HAVE_SETRLIMIT64
+
+/* Define to 1 if you have the `set_auth_parameters' function. */
+#undef HAVE_SET_AUTH_PARAMETERS
+
+/* Define to 1 if you have the `SHA224Update' function. */
+#undef HAVE_SHA224UPDATE
+
+/* Define to 1 if you have the `shl_load' function. */
+#undef HAVE_SHL_LOAD
+
+/* Define to 1 if you have the `sia_ses_init' function. */
+#undef HAVE_SIA_SES_INIT
+
+/* Define to 1 if you have the `sig2str' function. */
+#undef HAVE_SIG2STR
+
+/* Define to 1 if you use S/Key. */
+#undef HAVE_SKEY
+
+/* Define to 1 if your S/Key library has skeyaccess(). */
+#undef HAVE_SKEYACCESS
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* Define to 1 to enable Solaris audit support. */
+#undef HAVE_SOLARIS_AUDIT
+
+/* Define to 1 if you have the <spawn.h> header file. */
+#undef HAVE_SPAWN_H
+
+/* Define to 1 to enable SSSD support. */
+#undef HAVE_SSSD
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strlcat' function. */
+#undef HAVE_STRLCAT
+
+/* Define to 1 if you have the `strlcpy' function. */
+#undef HAVE_STRLCPY
+
+/* Define to 1 if you have the `strndup' function. */
+#undef HAVE_STRNDUP
+
+/* Define to 1 if you have the `strnlen' function. */
+#undef HAVE_STRNLEN
+
+/* Define to 1 if you have the `strsignal' function. */
+#undef HAVE_STRSIGNAL
+
+/* Define to 1 if you have the `strtonum' function. */
+#undef HAVE_STRTONUM
+
+/* Define to 1 if `d_namlen' is a member of `struct dirent'. */
+#undef HAVE_STRUCT_DIRENT_D_NAMLEN
+
+/* Define to 1 if `d_type' is a member of `struct dirent'. */
+#undef HAVE_STRUCT_DIRENT_D_TYPE
+
+/* Define to 1 if the system has the type `struct in6_addr'. */
+#undef HAVE_STRUCT_IN6_ADDR
+
+/* Define to 1 if `pr_ttydev' is a member of `struct psinfo'. */
+#undef HAVE_STRUCT_PSINFO_PR_TTYDEV
+
+/* Define if your struct sockaddr_in has a sin_len field. */
+#undef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+
+/* Define if your struct sockaddr has an sa_len field. */
+#undef HAVE_STRUCT_SOCKADDR_SA_LEN
+
+/* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */
+#undef HAVE_STRUCT_TM_TM_GMTOFF
+
+/* Define to 1 if `ut_exit' is a member of `struct utmp'. */
+#undef HAVE_STRUCT_UTMP_UT_EXIT
+
+/* Define to 1 if `ut_exit.e_termination' is a member of `struct utmp'. */
+#undef HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION
+
+/* Define to 1 if `ut_exit.__e_termination' is a member of `struct utmp'. */
+#undef HAVE_STRUCT_UTMP_UT_EXIT___E_TERMINATION
+
+/* Define to 1 if `ut_id' is a member of `struct utmp'. */
+#undef HAVE_STRUCT_UTMP_UT_ID
+
+/* Define to 1 if `ut_pid' is a member of `struct utmp'. */
+#undef HAVE_STRUCT_UTMP_UT_PID
+
+/* Define to 1 if `ut_tv' is a member of `struct utmp'. */
+#undef HAVE_STRUCT_UTMP_UT_TV
+
+/* Define to 1 if `ut_type' is a member of `struct utmp'. */
+#undef HAVE_STRUCT_UTMP_UT_TYPE
+
+/* Define to 1 if `ut_user' is a member of `struct utmp'. */
+#undef HAVE_STRUCT_UTMP_UT_USER
+
+/* Define to 1 if your struct stat has an st_mtim member. */
+#undef HAVE_ST_MTIM
+
+/* Define to 1 if your struct stat has an st_mtimespec member. */
+#undef HAVE_ST_MTIMESPEC
+
+/* Define to 1 if your struct stat has an st_nmtime member. */
+#undef HAVE_ST_NMTIME
+
+/* Define to 1 if your struct stat uses an st__tim union. */
+#undef HAVE_ST__TIM
+
+/* Define to 1 if you have the `sysctl' function. */
+#undef HAVE_SYSCTL
+
+/* Define to 1 if you have the `sysinfo' function. */
+#undef HAVE_SYSINFO
+
+/* Define to 1 if you have the <sys/bsdtypes.h> header file. */
+#undef HAVE_SYS_BSDTYPES_H
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/endian.h> header file. */
+#undef HAVE_SYS_ENDIAN_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/procfs.h> header file. */
+#undef HAVE_SYS_PROCFS_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if your libc has the `sys_sigabbrev' symbol. */
+#undef HAVE_SYS_SIGABBREV
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+#undef HAVE_SYS_SOCKIO_H
+
+/* Define to 1 if you have the <sys/statvfs.h> header file. */
+#undef HAVE_SYS_STATVFS_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/stropts.h> header file. */
+#undef HAVE_SYS_STROPTS_H
+
+/* Define to 1 if you have the <sys/syscall.h> header file. */
+#undef HAVE_SYS_SYSCALL_H
+
+/* Define to 1 if you have the <sys/sysmacros.h> header file. */
+#undef HAVE_SYS_SYSMACROS_H
+
+/* Define to 1 if you have the <sys/systeminfo.h> header file. */
+#undef HAVE_SYS_SYSTEMINFO_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the `ttyslot' function. */
+#undef HAVE_TTYSLOT
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `unsetenv' function. */
+#undef HAVE_UNSETENV
+
+/* Define to 1 if the system has the type 'unsigned long long int'. */
+#undef HAVE_UNSIGNED_LONG_LONG_INT
+
+/* Define to 1 if you have the <util.h> header file. */
+#undef HAVE_UTIL_H
+
+/* Define to 1 if you have the `utimensat' function. */
+#undef HAVE_UTIMENSAT
+
+/* Define to 1 if you have the `utimes' function. */
+#undef HAVE_UTIMES
+
+/* Define to 1 if you have the <utmps.h> header file. */
+#undef HAVE_UTMPS_H
+
+/* Define to 1 if you have the <utmpx.h> header file. */
+#undef HAVE_UTMPX_H
+
+/* Define to 1 if you have the `vasprintf' function. */
+#undef HAVE_VASPRINTF
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define to 1 if you have the `vsyslog' function. */
+#undef HAVE_VSYSLOG
+
+/* Define to 1 if you have the `wordexp' function. */
+#undef HAVE_WORDEXP
+
+/* Define to 1 if you have the <wordexp.h> header file. */
+#undef HAVE_WORDEXP_H
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#undef HAVE_ZLIB_H
+
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
+/* Define to 1 if you have the `_getpty' function. */
+#undef HAVE__GETPTY
+
+/* Define to 1 if you have the `_innetgr' function. */
+#undef HAVE__INNETGR
+
+/* Define to 1 if you have the `_nss_initf_group' function. */
+#undef HAVE__NSS_INITF_GROUP
+
+/* Define to 1 if you have the `_nss_XbyY_buf_alloc' function. */
+#undef HAVE__NSS_XBYY_BUF_ALLOC
+
+/* Define to 1 if you have the `_ttyname_dev' function. */
+#undef HAVE__TTYNAME_DEV
+
+/* Define to 1 if the compiler supports the C99 __func__ variable. */
+#undef HAVE___FUNC__
+
+/* Define to 1 if you have dyld with __interpose attribute support. */
+#undef HAVE___INTERPOSE
+
+/* Define to 1 if you have the `__nss_initf_group' function. */
+#undef HAVE___NSS_INITF_GROUP
+
+/* Define to 1 if you have the `__nss_XbyY_buf_alloc' function. */
+#undef HAVE___NSS_XBYY_BUF_ALLOC
+
+/* Define to 1 if your crt0.o defines the __progname symbol for you. */
+#undef HAVE___PROGNAME
+
+/* Define to 1 if you want the hostname to be entered into the log file. */
+#undef HOST_IN_LOG
+
+/* Define to 1 if you want to ignore '.' and empty PATH elements. */
+#undef IGNORE_DOT_PATH
+
+/* The message given when a bad password is entered. */
+#undef INCORRECT_PASSWORD
+
+/* The syslog facility sudo will use. */
+#undef LOGFAC
+
+/* Define to SLOG_SYSLOG, SLOG_FILE, or SLOG_BOTH. */
+#undef LOGGING
+
+/* Define to 1 if you want a two line OTP (S/Key or OPIE) prompt. */
+#undef LONG_OTP_PROMPT
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* The subject of the mail sent by sudo to the MAILTO user/address. */
+#undef MAILSUBJECT
+
+/* The user or email address that sudo mail is sent to. */
+#undef MAILTO
+
+/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
+ */
+#undef MAJOR_IN_MKDEV
+
+/* Define to 1 if `major', `minor', and `makedev' are declared in
+ <sysmacros.h>. */
+#undef MAJOR_IN_SYSMACROS
+
+/* The max number of chars per log file line (for line wrapping). */
+#undef MAXLOGFILELEN
+
+/* Define to the max length of a uid_t in string context (excluding the NUL).
+ */
+#undef MAX_UID_T_LEN
+
+/* Define to 1 if resolv.h must be included to get the `inet_ntop' or
+ `inet_pton' function prototypes. */
+#undef NEED_RESOLV_H
+
+/* Define to 1 if you don't want sudo to prompt for a password by default. */
+#undef NO_AUTHENTICATION
+
+/* Define to 1 if you want sudo to free up memory before exiting. */
+#undef NO_LEAKS
+
+/* Define to 1 if you don't want users to get the lecture the first they user
+ sudo. */
+#undef NO_LECTURE
+
+/* Define to 1 if you don't want to use sudo's PAM session support. */
+#undef NO_PAM_SESSION
+
+/* Define to avoid runing the mailer as root. */
+#undef NO_ROOT_MAILER
+
+/* Define to 1 if root should not be allowed to use sudo. */
+#undef NO_ROOT_SUDO
+
+/* Define if your C preprocessor does not support variadic macros. */
+#undef NO_VARIADIC_MACROS
+
+/* Define to 1 to include offensive insults from the classic version of sudo.
+ */
+#undef OFFENSIVE_INSULTS
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if your system uses a Solaris-derived PAM and not Linux-PAM or
+ OpenPAM. */
+#undef PAM_SUN_CODEBASE
+
+/* The default password prompt. */
+#undef PASSPROMPT
+
+/* The passwd prompt timeout (in minutes). */
+#undef PASSWORD_TIMEOUT
+
+/* Define to 1 to enable replacement getcwd if system getcwd is broken. */
+#undef PREFER_PORTABLE_GETCWD
+
+/* Enable replacement (v)snprintf if system (v)snprintf is broken. */
+#undef PREFER_PORTABLE_SNPRINTF
+
+/* The syslog priority sudo will use for unsuccessful attempts/errors. */
+#undef PRI_FAILURE
+
+/* The syslog priority sudo will use for successful attempts. */
+#undef PRI_SUCCESS
+
+/* Define to const if the `putenv' takes a const argument. */
+#undef PUTENV_CONST
+
+/* Define to 1 if you want insults from "Monty Python's Flying Circus". */
+#undef PYTHON_INSULTS
+
+/* The default value of preloaded objects (if any). */
+#undef RTLD_PRELOAD_DEFAULT
+
+/* The delimiter to use when defining multiple preloaded objects. */
+#undef RTLD_PRELOAD_DELIM
+
+/* An extra environment variable that is required to enable preloading (if
+ any). */
+#undef RTLD_PRELOAD_ENABLE_VAR
+
+/* The environment variable that controls preloading of dynamic objects. */
+#undef RTLD_PRELOAD_VAR
+
+/* The user sudo should run commands as by default. */
+#undef RUNAS_DEFAULT
+
+/* A colon-separated list of directories to override the user's PATH with. */
+#undef SECURE_PATH
+
+/* Define to 1 to send mail when the user is not allowed to run a command. */
+#undef SEND_MAIL_WHEN_NOT_OK
+
+/* Define to 1 to send mail when the user is not allowed to run sudo on this
+ host. */
+#undef SEND_MAIL_WHEN_NO_HOST
+
+/* Define to 1 to send mail when the user is not in the sudoers file. */
+#undef SEND_MAIL_WHEN_NO_USER
+
+/* Define to 1 if the sha2 functions use `const void *' instead of `const
+ unsigned char'. */
+#undef SHA2_VOID_PTR
+
+/* Define to 1 if you want sudo to start a shell if given no arguments. */
+#undef SHELL_IF_NO_ARGS
+
+/* Define to 1 if you want sudo to set $HOME in shell mode. */
+#undef SHELL_SETS_HOME
+
+/* The size of `id_t', as computed by sizeof. */
+#undef SIZEOF_ID_T
+
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
+/* The size of `time_t', as computed by sizeof. */
+#undef SIZEOF_TIME_T
+
+/* Define to 1 to compile the sudoers plugin statically into the sudo binary.
+ */
+#undef STATIC_SUDOERS_PLUGIN
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if the code in interfaces.c does not compile for you. */
+#undef STUB_LOAD_INTERFACES
+
+/* An instance string to append to the username (separated by a slash) for
+ Kerberos V authentication. */
+#undef SUDO_KRB5_INSTANCE
+
+/* The umask that the sudo-run prog should use. */
+#undef SUDO_UMASK
+
+/* The number of minutes before sudo asks for a password again. */
+#undef TIMEOUT
+
+/* Define to global, ppid or tty to set the default timestamp record type. */
+#undef TIMESTAMP_TYPE
+
+/* The number of tries a user gets to enter their password. */
+#undef TRIES_FOR_PASSWORD
+
+/* Define to 1 to use the umask specified in sudoers even when it is less
+ restrictive than the invoking user's. */
+#undef UMASK_OVERRIDE
+
+/* Define to 1 if the `unsetenv' function returns void instead of `int'. */
+#undef UNSETENV_VOID
+
+/* Define to 1 if you want to create ~/.sudo_as_admin_successful if the user
+ is in the admin group the first time they run sudo. */
+#undef USE_ADMIN_FLAG
+
+/* Define to 1 if you want to insult the user for entering an incorrect
+ password. */
+#undef USE_INSULTS
+
+/* Define to 1 if you use GNU stow packaging. */
+#undef USE_STOW
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Define to avoid using the passwd/shadow file for authentication. */
+#undef WITHOUT_PASSWD
+
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define to 1 to enable 64-bit versions of standard C functions on 32-bit
+ systems. */
+#undef _LARGEFILE64_SOURCE
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to __FUNCTION__ if your compiler supports __FUNCTION__ but not
+ __func__ */
+#undef __func__
+
+/* Define to `int' if <time.h> does not define. */
+#undef clockid_t
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef errno_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `long long' if <sys/types.h> does not define. */
+#undef intmax_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef mode_t
+
+/* Define to an OS-specific initialization function or `os_init_common'. */
+#undef os_init
+
+/* Define to `size_t' if <sys/types.h> does not define. */
+#undef rsize_t
+
+/* Define to `int' if <signal.h> does not define. */
+#undef sig_atomic_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `unsigned int' if <sys/socket.h> doesn't define. */
+#undef socklen_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef uint32_t
+
+/* Define to `unsigned long long' if <sys/types.h> does not define. */
+#undef uint64_t
+
+/* Define to `unsigned char' if <sys/types.h> does not define. */
+#undef uint8_t
+
+/* Define to `unsigned long long' if <sys/types.h> does not define. */
+#undef uintmax_t
+
+/* Define to empty if the keyword `volatile' does not work. Warning: valid
+ code using `volatile' can become incorrect without. Disable with care. */
+#undef volatile
+
+/* BSD compatibility on some SVR4 systems. */
+#ifdef __svr4__
+# define BSD_COMP
+#endif
+
+/* Enable BSD extensions on systems that have them. */
+#ifndef _BSD_SOURCE
+# undef _BSD_SOURCE
+#endif
+
+/* Enable BSD types on IRIX. */
+#ifndef _BSD_TYPES
+# undef _BSD_TYPES
+#endif
+
+/* Enable Linux-compatible extensions on AIX. */
+#ifndef _LINUX_SOURCE_COMPAT
+# undef _LINUX_SOURCE_COMPAT
+#endif
+
+/* Enable prototypes in GCC fixed includes on older systems. */
+#ifndef __USE_FIXED_PROTOTYPES__
+# undef __USE_FIXED_PROTOTYPES__
+#endif
+
+/* Enable XPG4v2 extensions to POSIX, needed for MSG_WAITALL on older HP-UX. */
+#ifndef _XOPEN_SOURCE_EXTENDED
+# undef _XOPEN_SOURCE_EXTENDED
+#endif
+
+/* Enable reentrant versions of the standard C API (obsolete). */
+#ifndef _REENTRANT
+# undef _REENTRANT
+#endif
+
+/* Enable "safer" versions of the standard C API (ISO C11). */
+#ifndef __STDC_WANT_LIB_EXT1__
+# undef __STDC_WANT_LIB_EXT1__
+#endif
+
+/* Prevent static analyzers from genering bogus memory leak warnings. */
+#if defined(__COVERITY__) && !defined(NO_LEAKS)
+# define NO_LEAKS
+#endif
+
+#endif /* SUDO_CONFIG_H */
diff --git a/config.sub b/config.sub
new file mode 100644
index 0000000..040d5cb
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,1827 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2016 Free Software Foundation, Inc.
+
+timestamp='2016-09-05'
+
+# This file 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2016 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+ kopensolaris*-gnu* | cloudabi*-eabi* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze* | -sr2201*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | ba \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | e2k | epiphany \
+ | fido | fr30 | frv | ft32 \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | riscv32 | riscv64 \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | ba-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | e2k-* | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | riscv32-* | riscv64-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | visium-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ asmjs)
+ basic_machine=asmjs-unknown
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ e500v[12])
+ basic_machine=powerpc-unknown
+ os=$os"spe"
+ ;;
+ e500v[12]-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=$os"spe"
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ sr2201*)
+ basic_machine=harp1e-hitachi
+ os=-hiuxmpp
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* | -cloudabi* | -sortix* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+ | -onefs* | -tirtos* | -phoenix*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -ios)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/configure b/configure
new file mode 100755
index 0000000..e1b5dbb
--- /dev/null
+++ b/configure
@@ -0,0 +1,29294 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for sudo 1.8.27.
+#
+# Report bugs to <https://bugzilla.sudo.ws/>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: https://bugzilla.sudo.ws/ about your system, including
+$0: any error possibly output before this message. Then
+$0: install a modern shell, or manually run the script
+$0: under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='sudo'
+PACKAGE_TARNAME='sudo'
+PACKAGE_VERSION='1.8.27'
+PACKAGE_STRING='sudo 1.8.27'
+PACKAGE_BUGREPORT='https://bugzilla.sudo.ws/'
+PACKAGE_URL=''
+
+ac_unique_file="src/sudo.c"
+ac_config_libobj_dir=lib/util
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_header_list=
+ac_func_list=
+ac_c_werror_flag=
+ac_subst_vars='LTLIBOBJS
+KRB5CONFIG
+LIBOBJS
+FLEX
+YFLAGS
+YACC
+NROFFPROG
+MANDOCPROG
+TRPROG
+UNAMEPROG
+LT_SYS_LIBRARY_PATH
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+AWK
+STRIP
+ac_ct_AR
+DLLTOOL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+RANLIB
+AR
+EGREP
+GREP
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CC
+PLUGINDIR
+pam_login_service
+pam_session
+editor
+secure_path
+netsvc_conf
+nsswitch_conf
+sssd_lib
+ldap_secret
+ldap_conf
+path_info
+root_sudo
+insults
+timestamp_type
+passwd_tries
+env_reset
+env_editor
+runas_default
+fqdn
+badpass_message
+mailsub
+mailto
+mail_no_perms
+mail_no_host
+mail_no_user
+ignore_dot
+loglen
+badpri
+goodpri
+logfac
+lecture
+long_otp_prompt
+passprompt
+umask_override
+sudo_umask
+password_timeout
+timeout
+vardir
+rundir
+iolog_dir
+devsearch
+DIGEST
+exampledir
+TMPFILES_D
+COMPAT_EXP
+RC_LINK
+INIT_DIR
+INIT_SCRIPT
+SSP_CFLAGS
+SSP_LDFLAGS
+PIE_CFLAGS
+PIE_LDFLAGS
+ASAN_CFLAGS
+ASAN_LDFLAGS
+CROSS_COMPILING
+SUDOERS_TEST_PROGS
+COMPAT_TEST_PROGS
+LOCALEDIR_SUFFIX
+SUDO_NLS
+LIBPTHREAD
+LIBMD
+LIBINTL
+LIBRT
+LIBDL
+CONFIGURE_ARGS
+LIBTOOL_DEPS
+ZLIB_SRC
+ZLIB
+LOGINCAP_USAGE
+LDAP
+SELINUX_USAGE
+BSDAUTH_USAGE
+DONT_LEAK_PATH_INFO
+CHECK_NOEXEC
+INSTALL_NOEXEC
+INSTALL_BACKUP
+sesh_file
+noexec_file
+NOEXECDIR
+NOEXECFILE
+mansrcdir
+mansectform
+mansectsu
+devdir
+SEMAN
+PSMAN
+LCMAN
+BAMAN
+DEVEL
+SUDOERS_GID
+SUDOERS_UID
+SUDOERS_MODE
+SHLIB_MODE
+SHLIB_ENABLE
+MANCOMPRESSEXT
+MANCOMPRESS
+MANDIRTYPE
+MANTYPE
+AUTH_OBJS
+GETGROUPS_LIB
+REPLAY_LIBS
+AFS_LIBS
+NET_LIBS
+STATIC_SUDOERS
+SUDOERS_LIBS
+SUDO_LIBS
+SUDO_OBJS
+SUDOERS_OBJS
+COMMON_OBJS
+LT_DEP_LIBS
+LT_STATIC
+LT_LDEXPORTS
+LT_LDDEP
+LT_LDFLAGS
+ZLIB_LDFLAGS
+LIBUTIL_LDFLAGS
+SUDOERS_LDFLAGS
+SUDO_LDFLAGS
+LDFLAGS
+CPPFLAGS
+PROGS
+CFLAGS
+LIBTOOL
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL
+BSHELLPROG
+MVPROG
+VIPROG
+SENDMAILPROG'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_otp_only
+with_alertmail
+with_pc_insults
+with_devel
+with_CC
+with_rpath
+with_blibpath
+with_bsm_audit
+with_linux_audit
+with_solaris_audit
+with_sssd
+with_sssd_conf
+with_sssd_lib
+with_incpath
+with_libpath
+with_libraries
+with_efence
+with_csops
+with_passwd
+with_skey
+with_opie
+with_long_otp_prompt
+with_SecurID
+with_fwtk
+with_kerb5
+with_aixauth
+with_pam
+with_AFS
+with_DCE
+with_logincap
+with_bsdauth
+with_project
+with_lecture
+with_logging
+with_logfac
+with_goodpri
+with_badpri
+with_logpath
+with_loglen
+with_ignore_dot
+with_mail_if_no_user
+with_mail_if_no_host
+with_mail_if_noperms
+with_mailto
+with_mailsubject
+with_passprompt
+with_badpass_message
+with_fqdn
+with_timedir
+with_rundir
+with_vardir
+with_iologdir
+with_tzdir
+with_sendmail
+with_sudoers_mode
+with_sudoers_uid
+with_sudoers_gid
+with_umask
+with_umask_override
+with_runas_default
+with_exempt
+with_editor
+with_env_editor
+with_passwd_tries
+with_timeout
+with_password_timeout
+with_tty_tickets
+with_insults
+with_all_insults
+with_classic_insults
+with_csops_insults
+with_hal_insults
+with_goons_insults
+with_python_insults
+with_nsswitch
+with_ldap
+with_ldap_conf_file
+with_ldap_secret_file
+with_secure_path
+with_interfaces
+with_askpass
+with_exampledir
+with_plugindir
+with_man
+with_mdoc
+enable_authentication
+enable_root_mailer
+enable_setreuid
+enable_setresuid
+enable_shadow
+enable_root_sudo
+enable_log_host
+enable_noargs_shell
+enable_shell_sets_home
+enable_path_info
+enable_env_debug
+enable_zlib
+enable_env_reset
+enable_warnings
+enable_werror
+enable_openssl
+enable_gcrypt
+enable_hardening
+enable_pie
+enable_asan
+enable_poll
+enable_admin_flag
+enable_nls
+enable_rpath
+enable_static_sudoers
+enable_shared_libutil
+enable_tmpfiles_d
+enable_devsearch
+with_selinux
+enable_sasl
+enable_timestamp_type
+enable_offensive_insults
+enable_package_build
+enable_gss_krb5_ccache_name
+enable_pvs_studio
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_aix_soname
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+with_libtool
+with_noexec
+with_netsvc
+enable_sia
+enable_largefile
+with_pam_login
+enable_pam_session
+enable_kerb5_instance
+'
+ ac_precious_vars='SENDMAILPROG
+VIPROG
+MVPROG
+BSHELLPROG
+build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+LT_SYS_LIBRARY_PATH
+YACC
+YFLAGS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures sudo 1.8.27 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/sudo]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of sudo 1.8.27:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --disable-authentication
+ Do not require authentication by default
+ --disable-root-mailer Don't run the mailer as root, run as the user
+ --disable-setreuid Don't try to use the setreuid() function
+ --disable-setresuid Don't try to use the setresuid() function
+ --disable-shadow Never use shadow passwords
+ --disable-root-sudo Don't allow root to run sudo
+ --enable-log-host Log the hostname in the log file
+ --enable-noargs-shell If sudo is given no arguments run a shell
+ --enable-shell-sets-home
+ Set $HOME to target user in shell mode
+ --disable-path-info Print 'command not allowed' not 'command not found'
+ --enable-env-debug Whether to enable environment debugging.
+ --enable-zlib[=PATH] Whether to enable or disable zlib
+ --enable-env-reset Whether to enable environment resetting by default.
+ --enable-warnings Whether to enable compiler warnings
+ --enable-werror Whether to enable the -Werror compiler option
+ --enable-openssl Use OpenSSL's message digest functions instead of
+ sudo's
+ --enable-gcrypt Use GNU crypt's message digest functions instead of
+ sudo's
+ --disable-hardening Do not use compiler/linker exploit mitigation
+ options
+ --enable-pie Build sudo as a position independent executable.
+ --enable-asan Build sudo with address sanitizer support.
+ --disable-poll Use select() instead of poll().
+ --enable-admin-flag Whether to create a Ubuntu-style admin flag file
+ --disable-nls Disable natural language support using gettext
+ --disable-rpath Disable passing of -Rpath to the linker
+ --enable-static-sudoers Build the sudoers policy module as part of the sudo
+ binary instead as a plugin
+ --disable-shared-libutil
+ Disable use of the libsudo_util shared library.
+ --enable-tmpfiles.d=DIR Set the path to the systemd tmpfiles.d directory.
+ --enable-devsearch=PATH The colon-delimited path to search for device nodes
+ when determing the tty name.
+ --enable-sasl Enable/disable LDAP SASL support
+ --timestamp-type=TYPE Set the default time stamp record type to global,
+ ppid or tty.
+ --enable-offensive-insults
+ Enable potentially offensive sudo insults.
+ --enable-package-build Enable options for package building.
+ --enable-gss-krb5-ccache-name
+ Use GSS-API to set the Kerberos V cred cache name
+ --enable-pvs-studio Create a PVS-Studio.cfg file.
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --disable-sia Disable SIA on Digital UNIX
+ --disable-largefile omit support for large files
+ --disable-pam-session Disable PAM session support
+ --enable-kerb5-instance instance string to append to the username (separated
+ by a slash)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-otp-only deprecated
+ --with-alertmail deprecated
+ --with-pc-insults deprecated
+ --with-devel add development options
+ --with-CC C compiler to use
+ --with-rpath deprecated, use --disable-rpath
+ --with-blibpath[=PATH] deprecated
+ --with-bsm-audit enable BSM audit support
+ --with-linux-audit enable Linux audit support
+ --with-solaris-audit enable Solaris audit support
+ --with-sssd enable SSSD support
+ --with-sssd-conf path to the SSSD config file
+ --with-sssd-lib path to the SSSD library
+ --with-incpath additional places to look for include files
+ --with-libpath additional places to look for libraries
+ --with-libraries additional libraries to link with
+ --with-efence link with -lefence for malloc() debugging
+ --with-csops add CSOps standard options
+ --without-passwd don't use passwd/shadow file for authentication
+ --with-skey[=DIR] enable S/Key support
+ --with-opie[=DIR] enable OPIE support
+ --with-long-otp-prompt use a two line OTP (skey/opie) prompt
+ --with-SecurID[=DIR] enable SecurID support
+ --with-fwtk[=DIR] enable FWTK AuthSRV support
+ --with-kerb5[=DIR] enable Kerberos V support
+ --with-aixauth enable AIX general authentication support
+ --with-pam enable PAM support
+ --with-AFS enable AFS support
+ --with-DCE enable DCE support
+ --with-logincap enable BSD login class support
+ --with-bsdauth enable BSD authentication support
+ --with-project enable Solaris project support
+ --without-lecture don't print lecture for first-time sudoer
+ --with-logging log via syslog, file, or both
+ --with-logfac syslog facility to log with (default is "auth")
+ --with-goodpri syslog priority for commands (def is "notice")
+ --with-badpri syslog priority for failures (def is "alert")
+ --with-logpath path to the sudo log file
+ --with-loglen maximum length of a log file line (default is 80)
+ --with-ignore-dot ignore '.' in the PATH
+ --without-mail-if-no-user
+ do not send mail if user not in sudoers
+ --with-mail-if-no-host send mail if user in sudoers but not for this host
+ --with-mail-if-noperms send mail if user not allowed to run command
+ --with-mailto who should get sudo mail (default is "root")
+ --with-mailsubject subject of sudo mail
+ --with-passprompt default password prompt
+ --with-badpass-message message the user sees when the password is wrong
+ --with-fqdn expect fully qualified hosts in sudoers
+ --with-timedir=DIR deprecated
+ --with-rundir=DIR directory for sudo-specific files that do not
+ survive a system reboot, e.g. `/var/run/sudo'
+ --with-vardir=DIR directory for sudo-specific files that survive a
+ system reboot, e.g. `/var/db/sudo' or
+ `/var/lib/sudo'
+ --with-iologdir=DIR directory to store sudo I/O log files in
+ --with-tzdir=DIR path to the time zone data directory
+ --with-sendmail set path to sendmail
+ --without-sendmail do not send mail at all
+ --with-sudoers-mode mode of sudoers file (defaults to 0440)
+ --with-sudoers-uid uid that owns sudoers file (defaults to 0)
+ --with-sudoers-gid gid that owns sudoers file (defaults to 0)
+ --with-umask umask with which the prog should run (default is
+ 022)
+ --without-umask Preserves the umask of the user invoking sudo.
+ --with-umask-override Use the umask specified in sudoers even if it is
+ less restrictive than the user's.
+ --with-runas-default User to run commands as (default is "root")
+ --with-exempt=group no passwd needed for users in this group
+ --with-editor=path Default editor for visudo (defaults to vi)
+ --with-env-editor Use the environment variable EDITOR for visudo
+ --with-passwd-tries number of tries to enter password (default is 3)
+ --with-timeout minutes before sudo asks for passwd again (def is 5
+ minutes)
+ --with-password-timeout passwd prompt timeout in minutes (default is 5
+ minutes)
+ --with-tty-tickets use a different ticket file for each tty
+ --with-insults insult the user for entering an incorrect password
+ --with-all-insults include all the sudo insult sets
+ --with-classic-insults include the insults from the "classic" sudo
+ --with-csops-insults include CSOps insults
+ --with-hal-insults include 2001-like insults
+ --with-goons-insults include the insults from the "Goon Show"
+ --with-python-insults include the insults from "Monty Python's Flying
+ Circus"
+ --with-nsswitch[=PATH] path to nsswitch.conf
+ --with-ldap[=DIR] enable LDAP support
+ --with-ldap-conf-file path to LDAP configuration file
+ --with-ldap-secret-file path to LDAP secret password file
+ --with-secure-path override the user's path with a built-in one
+ --without-interfaces don't try to read the ip addr of ether interfaces
+ --with-askpass=PATH Fully qualified pathname of askpass helper
+ --with-exampledir=DIR path to install sudo examples in
+ --with-plugindir=DIR set directory to load plugins from
+ --with-man manual pages use man macros
+ --with-mdoc manual pages use mdoc macros
+ --with-selinux enable SELinux support
+ --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-aix-soname=aix|svr4|both
+ shared library versioning (aka "SONAME") variant to
+ provide on AIX, [default=aix].
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the
+ compiler's sysroot if not specified).
+ --with-libtool=PATH specify path to libtool
+ --with-noexec[=PATH] fully qualified pathname of sudo_noexec.so
+ --with-netsvc[=PATH] path to netsvc.conf
+ --with-pam-login enable specific PAM session for sudo -i
+
+Some influential environment variables:
+ SENDMAILPROG
+ The fully-qualified path to the sendmail program to use.
+ VIPROG The fully-qualified path to the vi program to use.
+ MVPROG The fully-qualified path to the mv program to use.
+ BSHELLPROG The fully-qualified path to the Bourne shell to use.
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+ LT_SYS_LIBRARY_PATH
+ User-defined run-time library search path.
+ YACC The `Yet Another Compiler Compiler' implementation to use.
+ Defaults to the first program found out of: `bison -y', `byacc',
+ `yacc'.
+ YFLAGS The list of arguments that will be passed by default to $YACC.
+ This script will default YFLAGS to the empty string to avoid a
+ default value of `-d' given by some make applications.
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <https://bugzilla.sudo.ws/>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+sudo configure 1.8.27
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ---------------------------------------- ##
+## Report this to https://bugzilla.sudo.ws/ ##
+## ---------------------------------------- ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
+# ---------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
+ac_fn_c_check_decl ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ as_decl_name=`echo $2|sed 's/ *(.*//'`
+ as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+ (void) $as_decl_use;
+#else
+ (void) $as_decl_name;
+#endif
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_decl
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if eval \${$4+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_member
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by sudo $as_me 1.8.27, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+as_fn_append ac_header_list " sys/types.h"
+as_fn_append ac_header_list " netgroup.h"
+as_fn_append ac_header_list " paths.h"
+as_fn_append ac_header_list " spawn.h"
+as_fn_append ac_header_list " wordexp.h"
+as_fn_append ac_header_list " sys/sockio.h"
+as_fn_append ac_header_list " sys/bsdtypes.h"
+as_fn_append ac_header_list " sys/select.h"
+as_fn_append ac_header_list " sys/stropts.h"
+as_fn_append ac_header_list " sys/sysmacros.h"
+as_fn_append ac_header_list " sys/syscall.h"
+as_fn_append ac_header_list " sys/statvfs.h"
+as_fn_append ac_func_list " fexecve"
+as_fn_append ac_func_list " killpg"
+as_fn_append ac_func_list " nl_langinfo"
+as_fn_append ac_func_list " pread"
+as_fn_append ac_func_list " pwrite"
+as_fn_append ac_func_list " openat"
+as_fn_append ac_func_list " faccessat"
+as_fn_append ac_func_list " wordexp"
+as_fn_append ac_func_list " getauxval"
+as_fn_append ac_func_list " seteuid"
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_config_headers="$ac_config_headers config.h pathnames.h"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: Configuring Sudo version $PACKAGE_VERSION" >&5
+$as_echo "$as_me: Configuring Sudo version $PACKAGE_VERSION" >&6;}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Begin initial values for man page substitution
+#
+iolog_dir=/var/log/sudo-io
+rundir=/var/run/sudo
+vardir=/var/adm/sudo
+timeout=5
+password_timeout=5
+sudo_umask=0022
+umask_override=off
+passprompt="Password: "
+long_otp_prompt=off
+lecture=once
+logfac=auth
+goodpri=notice
+badpri=alert
+loglen=80
+ignore_dot=off
+mail_no_user=on
+mail_no_host=off
+mail_no_perms=off
+mailto=root
+mailsub="*** SECURITY information for %h ***"
+badpass_message="Sorry, try again."
+fqdn=off
+runas_default=root
+env_editor=off
+env_reset=on
+editor=vi
+passwd_tries=3
+timestamp_type=tty
+insults=off
+root_sudo=on
+path_info=on
+ldap_conf=/etc/ldap.conf
+ldap_secret=/etc/ldap.secret
+netsvc_conf=/etc/netsvc.conf
+noexec_file=/usr/local/libexec/sudo/sudo_noexec.so
+sesh_file=/usr/local/libexec/sudo/sesh
+nsswitch_conf=/etc/nsswitch.conf
+secure_path="not set"
+pam_session=on
+pam_login_service=sudo
+PLUGINDIR=/usr/local/libexec/sudo
+DIGEST=digest.lo
+devsearch="/dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev"
+#
+# End initial values for man page substitution
+#
+INSTALL_BACKUP=
+INSTALL_NOEXEC=
+CHECK_NOEXEC=
+exampledir='$(docdir)/examples'
+devdir='$(srcdir)'
+PROGS="sudo"
+: ${MANDIRTYPE='man'}
+: ${mansrcdir='.'}
+: ${SHLIB_MODE='0644'}
+: ${SUDOERS_MODE='0440'}
+: ${SUDOERS_UID='0'}
+: ${SUDOERS_GID='0'}
+DEVEL=
+LDAP="#"
+BAMAN=0
+LCMAN=0
+PSMAN=0
+SEMAN=0
+LIBINTL=
+LIBMD=
+ZLIB=
+ZLIB_SRC=
+AUTH_OBJS=
+AUTH_REG=
+AUTH_EXCL=
+AUTH_EXCL_DEF=
+AUTH_DEF=passwd
+SUDO_NLS=disabled
+LOCALEDIR_SUFFIX=
+LT_LDEXPORTS="-export-symbols \$(shlib_exp)"
+LT_LDDEP="\$(shlib_exp)"
+OS_INIT=os_init_common
+INIT_SCRIPT=
+INIT_DIR=
+RC_LINK=
+COMPAT_EXP=
+WEAK_ALIAS=no
+CHECKSHADOW=true
+shadow_funcs=
+shadow_libs=
+TMPFILES_D=
+CONFIGURE_ARGS="$@"
+
+RTLD_PRELOAD_VAR="LD_PRELOAD"
+RTLD_PRELOAD_ENABLE_VAR=
+RTLD_PRELOAD_DELIM=":"
+RTLD_PRELOAD_DEFAULT=
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = xyes; then :
+ MINIX=yes
+else
+ MINIX=
+fi
+
+
+ if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if ${ac_cv_safe_to_define___extensions__+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# define __EXTENSIONS__ 1
+ $ac_includes_default
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_safe_to_define___extensions__=yes
+else
+ ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+ test $ac_cv_safe_to_define___extensions__ = yes &&
+ $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+ $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+ $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+#
+# Prior to sudo 1.8.7, sudo stored libexec files in $libexecdir.
+# Starting with sudo 1.8.7, $libexecdir/sudo is used so strip
+# off an extraneous "/sudo" from libexecdir.
+#
+case "$libexecdir" in
+ */sudo)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libexecdir should not include the \"sudo\" subdirectory" >&5
+$as_echo "$as_me: WARNING: libexecdir should not include the \"sudo\" subdirectory" >&2;}
+ libexecdir=`expr "$libexecdir" : '\\(.*\\)/sudo$'`
+ ;;
+esac
+
+
+
+# Check whether --with-otp-only was given.
+if test "${with_otp_only+set}" = set; then :
+ withval=$with_otp_only; case $with_otp_only in
+ yes) with_passwd="no"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: --with-otp-only option deprecated, treating as --without-passwd" >&5
+$as_echo "$as_me: --with-otp-only option deprecated, treating as --without-passwd" >&6;}
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-alertmail was given.
+if test "${with_alertmail+set}" = set; then :
+ withval=$with_alertmail; case $with_alertmail in
+ *) with_mailto="$with_alertmail"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: --with-alertmail option deprecated, treating as --mailto" >&5
+$as_echo "$as_me: --with-alertmail option deprecated, treating as --mailto" >&6;}
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-pc-insults was given.
+if test "${with_pc_insults+set}" = set; then :
+ withval=$with_pc_insults; case $with_pc_insults in
+ yes) enable_offensive_insults=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: --with-pc-insults option deprecated, it is now the default" >&5
+$as_echo "$as_me: --with-pc-insults option deprecated, it is now the default" >&6;}
+ ;;
+ no) enable_offensive_insults=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: --without-pc-insults option deprecated, use --enable-offensive-insults" >&5
+$as_echo "$as_me: --without-pc-insults option deprecated, use --enable-offensive-insults" >&6;}
+ ;;
+esac
+fi
+
+
+
+
+# Check whether --with-devel was given.
+if test "${with_devel+set}" = set; then :
+ withval=$with_devel; case $with_devel in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: Setting up for development: -Wall, flex, yacc" >&5
+$as_echo "$as_me: Setting up for development: -Wall, flex, yacc" >&6;}
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -DSUDO_DEVEL "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -DSUDO_DEVEL"; } >&5
+ (: CPPFLAGS already contains -DSUDO_DEVEL) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -DSUDO_DEVEL"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-DSUDO_DEVEL
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ DEVEL="true"
+ devdir=.
+ ;;
+ no) ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --with-devel: $with_devel" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --with-devel: $with_devel" >&2;}
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-CC was given.
+if test "${with_CC+set}" = set; then :
+ withval=$with_CC; case $with_CC in
+ *) as_fn_error $? "the --with-CC option is no longer supported, please set the CC environment variable instead." "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-rpath was given.
+if test "${with_rpath+set}" = set; then :
+ withval=$with_rpath; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-rpath deprecated, rpath is now the default" >&5
+$as_echo "$as_me: WARNING: --with-rpath deprecated, rpath is now the default" >&2;}
+fi
+
+
+
+# Check whether --with-blibpath was given.
+if test "${with_blibpath+set}" = set; then :
+ withval=$with_blibpath; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-blibpath deprecated, use --with-libpath" >&5
+$as_echo "$as_me: WARNING: --with-blibpath deprecated, use --with-libpath" >&2;}
+fi
+
+
+
+# Check whether --with-bsm-audit was given.
+if test "${with_bsm_audit+set}" = set; then :
+ withval=$with_bsm_audit; case $with_bsm_audit in
+ yes) $as_echo "#define HAVE_BSM_AUDIT 1" >>confdefs.h
+
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lbsm"
+ SUDOERS_OBJS="${SUDOERS_OBJS} bsm_audit.lo"
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-bsm-audit does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-linux-audit was given.
+if test "${with_linux_audit+set}" = set; then :
+ withval=$with_linux_audit; case $with_linux_audit in
+ yes) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <libaudit.h>
+int
+main ()
+{
+int i = AUDIT_USER_CMD; (void)i;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ $as_echo "#define HAVE_LINUX_AUDIT 1" >>confdefs.h
+
+ SUDO_LIBS="${SUDO_LIBS} -laudit"
+ SUDOERS_LIBS="${SUDO_LIBS} -laudit"
+ SUDOERS_OBJS="${SUDOERS_OBJS} linux_audit.lo"
+
+else
+
+ as_fn_error $? "unable to find AUDIT_USER_CMD in libaudit.h for --with-linux-audit" "$LINENO" 5
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-linux-audit does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-solaris-audit was given.
+if test "${with_solaris_audit+set}" = set; then :
+ withval=$with_solaris_audit; case $with_solaris_audit in
+ yes) $as_echo "#define HAVE_SOLARIS_AUDIT 1" >>confdefs.h
+
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lbsm"
+ SUDOERS_OBJS="${SUDOERS_OBJS} solaris_audit.lo"
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-solaris-audit does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-sssd was given.
+if test "${with_sssd+set}" = set; then :
+ withval=$with_sssd; case $with_sssd in
+ yes) SUDOERS_OBJS="${SUDOERS_OBJS} sssd.lo"
+ case "$SUDOERS_OBJS" in
+ *ldap_util.lo*) ;;
+ *) SUDOERS_OBJS="${SUDOERS_OBJS} ldap_util.lo";;
+ esac
+ $as_echo "#define HAVE_SSSD 1" >>confdefs.h
+
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-sssd does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-sssd-conf was given.
+if test "${with_sssd_conf+set}" = set; then :
+ withval=$with_sssd_conf;
+fi
+
+sssd_conf="/etc/sssd/sssd.conf"
+test -n "$with_sssd_conf" && sssd_conf="$with_sssd_conf"
+cat >>confdefs.h <<EOF
+#define _PATH_SSSD_CONF "$sssd_conf"
+EOF
+
+
+
+# Check whether --with-sssd-lib was given.
+if test "${with_sssd_lib+set}" = set; then :
+ withval=$with_sssd_lib;
+fi
+
+sssd_lib="\"LIBDIR\""
+test -n "$with_sssd_lib" && sssd_lib="$with_sssd_lib"
+cat >>confdefs.h <<EOF
+#define _PATH_SSSD_LIB "$sssd_lib"
+EOF
+
+
+
+# Check whether --with-incpath was given.
+if test "${with_incpath+set}" = set; then :
+ withval=$with_incpath; case $with_incpath in
+ yes) as_fn_error $? "\"must give --with-incpath an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-incpath not supported.\"" "$LINENO" 5
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: Adding ${with_incpath} to CPPFLAGS" >&5
+$as_echo "$as_me: Adding ${with_incpath} to CPPFLAGS" >&6;}
+ for i in ${with_incpath}; do
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I${i} "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I\${i}"; } >&5
+ (: CPPFLAGS already contains -I${i}) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I${i}"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I${i}
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ done
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-libpath was given.
+if test "${with_libpath+set}" = set; then :
+ withval=$with_libpath; case $with_libpath in
+ yes) as_fn_error $? "\"must give --with-libpath an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-libpath not supported.\"" "$LINENO" 5
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: Adding ${with_libpath} to LDFLAGS" >&5
+$as_echo "$as_me: Adding ${with_libpath} to LDFLAGS" >&6;}
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-libraries was given.
+if test "${with_libraries+set}" = set; then :
+ withval=$with_libraries; case $with_libraries in
+ yes) as_fn_error $? "\"must give --with-libraries an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-libraries not supported.\"" "$LINENO" 5
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: Adding ${with_libraries} to LIBS" >&5
+$as_echo "$as_me: Adding ${with_libraries} to LIBS" >&6;}
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-efence was given.
+if test "${with_efence+set}" = set; then :
+ withval=$with_efence; case $with_efence in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: Sudo will link with -lefence (Electric Fence)" >&5
+$as_echo "$as_me: Sudo will link with -lefence (Electric Fence)" >&6;}
+ LIBS="${LIBS} -lefence"
+ if test -f /usr/local/lib/libefence.a; then
+ with_libpath="${with_libpath} /usr/local/lib"
+ fi
+ ;;
+ no) ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --with-efence: $with_efence" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --with-efence: $with_efence" >&2;}
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-csops was given.
+if test "${with_csops+set}" = set; then :
+ withval=$with_csops; case $with_csops in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: Adding CSOps standard options" >&5
+$as_echo "$as_me: Adding CSOps standard options" >&6;}
+ CHECKSIA=false
+ with_ignore_dot=yes
+ insults=on
+ with_classic_insults=yes
+ with_csops_insults=yes
+ with_env_editor=yes
+ : ${mansectsu='8'}
+ : ${mansectform='5'}
+ ;;
+ no) ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --with-csops: $with_csops" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --with-csops: $with_csops" >&2;}
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-passwd was given.
+if test "${with_passwd+set}" = set; then :
+ withval=$with_passwd; case $with_passwd in
+ yes|no) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use shadow/passwd file authentication" >&5
+$as_echo_n "checking whether to use shadow/passwd file authentication... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_passwd" >&5
+$as_echo "$with_passwd" >&6; }
+ AUTH_DEF=""
+ test "$with_passwd" = "yes" && AUTH_REG="$AUTH_REG passwd"
+ ;;
+ *) as_fn_error $? "\"Sorry, --with-passwd does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-skey was given.
+if test "${with_skey+set}" = set; then :
+ withval=$with_skey; case $with_skey in
+ no) ;;
+ *) $as_echo "#define HAVE_SKEY 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to try S/Key authentication" >&5
+$as_echo_n "checking whether to try S/Key authentication... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ AUTH_REG="$AUTH_REG S/Key"
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-opie was given.
+if test "${with_opie+set}" = set; then :
+ withval=$with_opie; case $with_opie in
+ no) ;;
+ *) $as_echo "#define HAVE_OPIE 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to try NRL OPIE authentication" >&5
+$as_echo_n "checking whether to try NRL OPIE authentication... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ AUTH_REG="$AUTH_REG NRL_OPIE"
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-long-otp-prompt was given.
+if test "${with_long_otp_prompt+set}" = set; then :
+ withval=$with_long_otp_prompt; case $with_long_otp_prompt in
+ yes) $as_echo "#define LONG_OTP_PROMPT 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use a two line prompt for OTP authentication" >&5
+$as_echo_n "checking whether to use a two line prompt for OTP authentication... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ long_otp_prompt=on
+ ;;
+ no) long_otp_prompt=off
+ ;;
+ *) as_fn_error $? "\"--with-long-otp-prompt does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-SecurID was given.
+if test "${with_SecurID+set}" = set; then :
+ withval=$with_SecurID; case $with_SecurID in
+ no) ;;
+ *) $as_echo "#define HAVE_SECURID 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use SecurID for authentication" >&5
+$as_echo_n "checking whether to use SecurID for authentication... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ AUTH_EXCL="$AUTH_EXCL SecurID"
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-fwtk was given.
+if test "${with_fwtk+set}" = set; then :
+ withval=$with_fwtk; case $with_fwtk in
+ no) ;;
+ *) $as_echo "#define HAVE_FWTK 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use FWTK AuthSRV for authentication" >&5
+$as_echo_n "checking whether to use FWTK AuthSRV for authentication... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ AUTH_EXCL="$AUTH_EXCL FWTK"
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-kerb5 was given.
+if test "${with_kerb5+set}" = set; then :
+ withval=$with_kerb5; case $with_kerb5 in
+ no) ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to try Kerberos V authentication" >&5
+$as_echo_n "checking whether to try Kerberos V authentication... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ AUTH_REG="$AUTH_REG kerb5"
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-aixauth was given.
+if test "${with_aixauth+set}" = set; then :
+ withval=$with_aixauth; case $with_aixauth in
+ yes) AUTH_EXCL="$AUTH_EXCL AIX_AUTH";;
+ no) ;;
+ *) as_fn_error $? "\"--with-aixauth does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-pam was given.
+if test "${with_pam+set}" = set; then :
+ withval=$with_pam; case $with_pam in
+ yes) AUTH_EXCL="$AUTH_EXCL PAM";;
+ no) ;;
+ *) as_fn_error $? "\"--with-pam does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-AFS was given.
+if test "${with_AFS+set}" = set; then :
+ withval=$with_AFS; case $with_AFS in
+ yes) $as_echo "#define HAVE_AFS 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to try AFS (kerberos) authentication" >&5
+$as_echo_n "checking whether to try AFS (kerberos) authentication... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ AUTH_REG="$AUTH_REG AFS"
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-AFS does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-DCE was given.
+if test "${with_DCE+set}" = set; then :
+ withval=$with_DCE; case $with_DCE in
+ yes) $as_echo "#define HAVE_DCE 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to try DCE (kerberos) authentication" >&5
+$as_echo_n "checking whether to try DCE (kerberos) authentication... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ AUTH_REG="$AUTH_REG DCE"
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-DCE does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-logincap was given.
+if test "${with_logincap+set}" = set; then :
+ withval=$with_logincap; case $with_logincap in
+ yes|no) ;;
+ *) as_fn_error $? "\"--with-logincap does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-bsdauth was given.
+if test "${with_bsdauth+set}" = set; then :
+ withval=$with_bsdauth; case $with_bsdauth in
+ yes) AUTH_EXCL="$AUTH_EXCL BSD_AUTH";;
+ no) ;;
+ *) as_fn_error $? "\"--with-bsdauth does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-project was given.
+if test "${with_project+set}" = set; then :
+ withval=$with_project; case $with_project in
+ yes|no) ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-project does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to lecture users the first time they run sudo" >&5
+$as_echo_n "checking whether to lecture users the first time they run sudo... " >&6; }
+
+# Check whether --with-lecture was given.
+if test "${with_lecture+set}" = set; then :
+ withval=$with_lecture; case $with_lecture in
+ yes|short|always) lecture=once
+ ;;
+ no|none|never) lecture=never
+ ;;
+ *) as_fn_error $? "\"unknown argument to --with-lecture: $with_lecture\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+if test "$lecture" = "once"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ $as_echo "#define NO_LECTURE 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sudo should log via syslog or to a file by default" >&5
+$as_echo_n "checking whether sudo should log via syslog or to a file by default... " >&6; }
+
+# Check whether --with-logging was given.
+if test "${with_logging+set}" = set; then :
+ withval=$with_logging; case $with_logging in
+ yes) as_fn_error $? "\"must give --with-logging an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-logging not supported.\"" "$LINENO" 5
+ ;;
+ syslog) $as_echo "#define LOGGING SLOG_SYSLOG" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: syslog" >&5
+$as_echo "syslog" >&6; }
+ ;;
+ file) $as_echo "#define LOGGING SLOG_FILE" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: file" >&5
+$as_echo "file" >&6; }
+ ;;
+ both) $as_echo "#define LOGGING SLOG_BOTH" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: both" >&5
+$as_echo "both" >&6; }
+ ;;
+ *) as_fn_error $? "\"unknown argument to --with-logging: $with_logging\"" "$LINENO" 5
+ ;;
+esac
+else
+ $as_echo "#define LOGGING SLOG_SYSLOG" >>confdefs.h
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: syslog" >&5
+$as_echo "syslog" >&6; }
+fi
+
+
+
+# Check whether --with-logfac was given.
+if test "${with_logfac+set}" = set; then :
+ withval=$with_logfac; case $with_logfac in
+ yes) as_fn_error $? "\"must give --with-logfac an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-logfac not supported.\"" "$LINENO" 5
+ ;;
+ authpriv|auth|daemon|user|local0|local1|local2|local3|local4|local5|local6|local7) logfac=$with_logfac
+ ;;
+ *) as_fn_error $? "\"$with_logfac is not a supported syslog facility.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking at which syslog priority to log commands" >&5
+$as_echo_n "checking at which syslog priority to log commands... " >&6; }
+
+# Check whether --with-goodpri was given.
+if test "${with_goodpri+set}" = set; then :
+ withval=$with_goodpri; case $with_goodpri in
+ yes) as_fn_error $? "\"must give --with-goodpri an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-goodpri not supported.\"" "$LINENO" 5
+ ;;
+ alert|crit|debug|emerg|err|info|notice|warning)
+ goodpri=$with_goodpri
+ ;;
+ *) as_fn_error $? "\"$with_goodpri is not a supported syslog priority.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define PRI_SUCCESS "$goodpri"
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $goodpri" >&5
+$as_echo "$goodpri" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking at which syslog priority to log failures" >&5
+$as_echo_n "checking at which syslog priority to log failures... " >&6; }
+
+# Check whether --with-badpri was given.
+if test "${with_badpri+set}" = set; then :
+ withval=$with_badpri; case $with_badpri in
+ yes) as_fn_error $? "\"must give --with-badpri an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-badpri not supported.\"" "$LINENO" 5
+ ;;
+ alert|crit|debug|emerg|err|info|notice|warning)
+ badpri=$with_badpri
+ ;;
+ *) as_fn_error $? "$with_badpri is not a supported syslog priority." "$LINENO" 5
+ ;;
+esac
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define PRI_FAILURE "$badpri"
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $badpri" >&5
+$as_echo "$badpri" >&6; }
+
+
+# Check whether --with-logpath was given.
+if test "${with_logpath+set}" = set; then :
+ withval=$with_logpath; case $with_logpath in
+ yes) as_fn_error $? "\"must give --with-logpath an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-logpath not supported.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how long a line in the log file should be" >&5
+$as_echo_n "checking how long a line in the log file should be... " >&6; }
+
+# Check whether --with-loglen was given.
+if test "${with_loglen+set}" = set; then :
+ withval=$with_loglen; case $with_loglen in
+ yes) as_fn_error $? "\"must give --with-loglen an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-loglen not supported.\"" "$LINENO" 5
+ ;;
+ [0-9]*) loglen=$with_loglen
+ ;;
+ *) as_fn_error $? "\"you must enter a number, not $with_loglen\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define MAXLOGFILELEN $loglen
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $loglen" >&5
+$as_echo "$loglen" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sudo should ignore '.' or '' in \$PATH" >&5
+$as_echo_n "checking whether sudo should ignore '.' or '' in \$PATH... " >&6; }
+
+# Check whether --with-ignore-dot was given.
+if test "${with_ignore_dot+set}" = set; then :
+ withval=$with_ignore_dot; case $with_ignore_dot in
+ yes) ignore_dot=on
+ ;;
+ no) ignore_dot=off
+ ;;
+ *) as_fn_error $? "\"--with-ignore-dot does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+if test "$ignore_dot" = "on"; then
+ $as_echo "#define IGNORE_DOT_PATH 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to send mail when a user is not in sudoers" >&5
+$as_echo_n "checking whether to send mail when a user is not in sudoers... " >&6; }
+
+# Check whether --with-mail-if-no-user was given.
+if test "${with_mail_if_no_user+set}" = set; then :
+ withval=$with_mail_if_no_user; case $with_mail_if_no_user in
+ yes) mail_no_user=on
+ ;;
+ no) mail_no_user=off
+ ;;
+ *) as_fn_error $? "\"--with-mail-if-no-user does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+if test "$mail_no_user" = "on"; then
+ $as_echo "#define SEND_MAIL_WHEN_NO_USER 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to send mail when user listed but not for this host" >&5
+$as_echo_n "checking whether to send mail when user listed but not for this host... " >&6; }
+
+# Check whether --with-mail-if-no-host was given.
+if test "${with_mail_if_no_host+set}" = set; then :
+ withval=$with_mail_if_no_host; case $with_mail_if_no_host in
+ yes) mail_no_host=on
+ ;;
+ no) mail_no_host=off
+ ;;
+ *) as_fn_error $? "\"--with-mail-if-no-host does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+if test "$mail_no_host" = "on"; then
+ $as_echo "#define SEND_MAIL_WHEN_NO_HOST 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to send mail when a user tries a disallowed command" >&5
+$as_echo_n "checking whether to send mail when a user tries a disallowed command... " >&6; }
+
+# Check whether --with-mail-if-noperms was given.
+if test "${with_mail_if_noperms+set}" = set; then :
+ withval=$with_mail_if_noperms; case $with_mail_if_noperms in
+ yes) mail_noperms=on
+ ;;
+ no) mail_noperms=off
+ ;;
+ *) as_fn_error $? "\"--with-mail-if-noperms does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+if test "$mail_noperms" = "on"; then
+ $as_echo "#define SEND_MAIL_WHEN_NOT_OK 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking who should get the mail that sudo sends" >&5
+$as_echo_n "checking who should get the mail that sudo sends... " >&6; }
+
+# Check whether --with-mailto was given.
+if test "${with_mailto+set}" = set; then :
+ withval=$with_mailto; case $with_mailto in
+ yes) as_fn_error $? "\"must give --with-mailto an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-mailto not supported.\"" "$LINENO" 5
+ ;;
+ *) mailto=$with_mailto
+ ;;
+esac
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define MAILTO "$mailto"
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mailto" >&5
+$as_echo "$mailto" >&6; }
+
+
+# Check whether --with-mailsubject was given.
+if test "${with_mailsubject+set}" = set; then :
+ withval=$with_mailsubject; case $with_mailsubject in
+ yes) as_fn_error $? "\"must give --with-mailsubject an argument.\"" "$LINENO" 5
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Sorry, --without-mailsubject not supported." >&5
+$as_echo "$as_me: WARNING: Sorry, --without-mailsubject not supported." >&2;}
+ ;;
+ *) mailsub="$with_mailsubject"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking sudo mail subject" >&5
+$as_echo_n "checking sudo mail subject... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using alert mail subject: $mailsub" >&5
+$as_echo "Using alert mail subject: $mailsub" >&6; }
+ ;;
+esac
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define MAILSUBJECT "$mailsub"
+_ACEOF
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for bad password prompt" >&5
+$as_echo_n "checking for bad password prompt... " >&6; }
+
+# Check whether --with-passprompt was given.
+if test "${with_passprompt+set}" = set; then :
+ withval=$with_passprompt; case $with_passprompt in
+ yes) as_fn_error $? "\"must give --with-passprompt an argument.\"" "$LINENO" 5
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Sorry, --without-passprompt not supported." >&5
+$as_echo "$as_me: WARNING: Sorry, --without-passprompt not supported." >&2;}
+ ;;
+ *) passprompt="$with_passprompt"
+esac
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $passprompt" >&5
+$as_echo "$passprompt" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define PASSPROMPT "$passprompt"
+_ACEOF
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for bad password message" >&5
+$as_echo_n "checking for bad password message... " >&6; }
+
+# Check whether --with-badpass-message was given.
+if test "${with_badpass_message+set}" = set; then :
+ withval=$with_badpass_message; case $with_badpass_message in
+ yes) as_fn_error $? "\"Must give --with-badpass-message an argument.\"" "$LINENO" 5
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Sorry, --without-badpass-message not supported." >&5
+$as_echo "$as_me: WARNING: Sorry, --without-badpass-message not supported." >&2;}
+ ;;
+ *) badpass_message="$with_badpass_message"
+ ;;
+esac
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define INCORRECT_PASSWORD "$badpass_message"
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $badpass_message" >&5
+$as_echo "$badpass_message" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to expect fully qualified hosts in sudoers" >&5
+$as_echo_n "checking whether to expect fully qualified hosts in sudoers... " >&6; }
+
+# Check whether --with-fqdn was given.
+if test "${with_fqdn+set}" = set; then :
+ withval=$with_fqdn; case $with_fqdn in
+ yes) fqdn=on
+ ;;
+ no) fqdn=off
+ ;;
+ *) as_fn_error $? "\"--with-fqdn does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+if test "$fqdn" = "on"; then
+ $as_echo "#define FQDN 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Check whether --with-timedir was given.
+if test "${with_timedir+set}" = set; then :
+ withval=$with_timedir; case $with_timedir in
+ *) as_fn_error $? "\"--without-timedir no longer supported, see --with-rundir.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-rundir was given.
+if test "${with_rundir+set}" = set; then :
+ withval=$with_rundir; case $with_rundir in
+ yes) as_fn_error $? "\"must give --with-rundir an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-rundir not supported.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-vardir was given.
+if test "${with_vardir+set}" = set; then :
+ withval=$with_vardir; case $with_vardir in
+ yes) as_fn_error $? "\"must give --with-vardir an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-vardir not supported.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-iologdir was given.
+if test "${with_iologdir+set}" = set; then :
+ withval=$with_iologdir; case $with_iologdir in
+ yes) ;;
+ no) as_fn_error $? "\"--without-iologdir not supported.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-tzdir was given.
+if test "${with_tzdir+set}" = set; then :
+ withval=$with_tzdir; case $with_tzdir in
+ yes) as_fn_error $? "\"must give --with-tzdir an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-sendmail was given.
+if test "${with_sendmail+set}" = set; then :
+ withval=$with_sendmail; case $with_sendmail in
+ yes) with_sendmail=""
+ ;;
+ no) ;;
+ *) cat >>confdefs.h <<EOF
+#define _PATH_SUDO_SENDMAIL "$with_sendmail"
+EOF
+
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-sudoers-mode was given.
+if test "${with_sudoers_mode+set}" = set; then :
+ withval=$with_sudoers_mode; case $with_sudoers_mode in
+ yes) as_fn_error $? "\"must give --with-sudoers-mode an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-sudoers-mode not supported.\"" "$LINENO" 5
+ ;;
+ [1-9]*) SUDOERS_MODE=0${with_sudoers_mode}
+ ;;
+ 0*) SUDOERS_MODE=$with_sudoers_mode
+ ;;
+ *) as_fn_error $? "\"you must use an octal mode, not a name.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-sudoers-uid was given.
+if test "${with_sudoers_uid+set}" = set; then :
+ withval=$with_sudoers_uid; case $with_sudoers_uid in
+ yes) as_fn_error $? "\"must give --with-sudoers-uid an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-sudoers-uid not supported.\"" "$LINENO" 5
+ ;;
+ [0-9]*) SUDOERS_UID=$with_sudoers_uid
+ ;;
+ *) as_fn_error $? "\"you must use an unsigned numeric uid, not a name.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-sudoers-gid was given.
+if test "${with_sudoers_gid+set}" = set; then :
+ withval=$with_sudoers_gid; case $with_sudoers_gid in
+ yes) as_fn_error $? "\"must give --with-sudoers-gid an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-sudoers-gid not supported.\"" "$LINENO" 5
+ ;;
+ [0-9]*) SUDOERS_GID=$with_sudoers_gid
+ ;;
+ *) as_fn_error $? "\"you must use an unsigned numeric gid, not a name.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for umask programs should be run with" >&5
+$as_echo_n "checking for umask programs should be run with... " >&6; }
+
+# Check whether --with-umask was given.
+if test "${with_umask+set}" = set; then :
+ withval=$with_umask; case $with_umask in
+ yes) as_fn_error $? "\"must give --with-umask an argument.\"" "$LINENO" 5
+ ;;
+ no) sudo_umask=0777
+ ;;
+ [0-9]*) sudo_umask=$with_umask
+ ;;
+ *) as_fn_error $? "\"you must enter a numeric mask.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define SUDO_UMASK $sudo_umask
+_ACEOF
+
+if test "$sudo_umask" = "0777"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: user" >&5
+$as_echo "user" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_umask" >&5
+$as_echo "$sudo_umask" >&6; }
+fi
+
+
+# Check whether --with-umask-override was given.
+if test "${with_umask_override+set}" = set; then :
+ withval=$with_umask_override; case $with_umask_override in
+ yes) $as_echo "#define UMASK_OVERRIDE 1" >>confdefs.h
+
+ umask_override=on
+ ;;
+ no) umask_override=off
+ ;;
+ *) as_fn_error $? "\"--with-umask-override does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for default user to run commands as" >&5
+$as_echo_n "checking for default user to run commands as... " >&6; }
+
+# Check whether --with-runas-default was given.
+if test "${with_runas_default+set}" = set; then :
+ withval=$with_runas_default; case $with_runas_default in
+ yes) as_fn_error $? "\"must give --with-runas-default an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-runas-default not supported.\"" "$LINENO" 5
+ ;;
+ *) runas_default="$with_runas_default"
+ ;;
+esac
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define RUNAS_DEFAULT "$runas_default"
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $runas_default" >&5
+$as_echo "$runas_default" >&6; }
+
+
+# Check whether --with-exempt was given.
+if test "${with_exempt+set}" = set; then :
+ withval=$with_exempt; case $with_exempt in
+ yes) as_fn_error $? "\"must give --with-exempt an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-exempt not supported.\"" "$LINENO" 5
+ ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define EXEMPTGROUP "$with_exempt"
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for group to be exempt from password" >&5
+$as_echo_n "checking for group to be exempt from password... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_exempt" >&5
+$as_echo "$with_exempt" >&6; }
+ ;;
+esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for editor that visudo should use" >&5
+$as_echo_n "checking for editor that visudo should use... " >&6; }
+
+# Check whether --with-editor was given.
+if test "${with_editor+set}" = set; then :
+ withval=$with_editor; case $with_editor in
+ yes) as_fn_error $? "\"must give --with-editor an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-editor not supported.\"" "$LINENO" 5
+ ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define EDITOR "$with_editor"
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_editor" >&5
+$as_echo "$with_editor" >&6; }
+ editor="$with_editor"
+ ;;
+esac
+else
+ $as_echo "#define EDITOR _PATH_VI" >>confdefs.h
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: vi" >&5
+$as_echo "vi" >&6; }
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to obey EDITOR and VISUAL environment variables" >&5
+$as_echo_n "checking whether to obey EDITOR and VISUAL environment variables... " >&6; }
+
+# Check whether --with-env-editor was given.
+if test "${with_env_editor+set}" = set; then :
+ withval=$with_env_editor; case $with_env_editor in
+ yes) env_editor=on
+ ;;
+ no) env_editor=off
+ ;;
+ *) as_fn_error $? "\"--with-env-editor does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+if test "$env_editor" = "on"; then
+ $as_echo "#define ENV_EDITOR 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking number of tries a user gets to enter their password" >&5
+$as_echo_n "checking number of tries a user gets to enter their password... " >&6; }
+
+# Check whether --with-passwd-tries was given.
+if test "${with_passwd_tries+set}" = set; then :
+ withval=$with_passwd_tries; case $with_passwd_tries in
+ yes) ;;
+ no) as_fn_error $? "\"--without-editor not supported.\"" "$LINENO" 5
+ ;;
+ [1-9]*) passwd_tries=$with_passwd_tries
+ ;;
+ *) as_fn_error $? "\"you must enter the numer of tries, > 0\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define TRIES_FOR_PASSWORD $passwd_tries
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $passwd_tries" >&5
+$as_echo "$passwd_tries" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking time in minutes after which sudo will ask for a password again" >&5
+$as_echo_n "checking time in minutes after which sudo will ask for a password again... " >&6; }
+
+# Check whether --with-timeout was given.
+if test "${with_timeout+set}" = set; then :
+ withval=$with_timeout; case $with_timeout in
+ yes) ;;
+ no) timeout=0
+ ;;
+ [0-9]*) timeout=$with_timeout
+ ;;
+ *) as_fn_error $? "\"you must enter the numer of minutes.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define TIMEOUT $timeout
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $timeout" >&5
+$as_echo "$timeout" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking time in minutes after the password prompt will time out" >&5
+$as_echo_n "checking time in minutes after the password prompt will time out... " >&6; }
+
+# Check whether --with-password-timeout was given.
+if test "${with_password_timeout+set}" = set; then :
+ withval=$with_password_timeout; case $with_password_timeout in
+ yes) ;;
+ no) password_timeout=0
+ ;;
+ [0-9]*) password_timeout=$with_password_timeout
+ ;;
+ *) as_fn_error $? "\"you must enter the numer of minutes.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define PASSWORD_TIMEOUT $password_timeout
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $password_timeout" >&5
+$as_echo "$password_timeout" >&6; }
+
+
+# Check whether --with-tty-tickets was given.
+if test "${with_tty_tickets+set}" = set; then :
+ withval=$with_tty_tickets; case $with_tty_tickets in
+ yes) timestamp_type=tty
+ ;;
+ no) timestamp_type=global
+ ;;
+ *) as_fn_error $? "\"--with-tty-tickets does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include insults" >&5
+$as_echo_n "checking whether to include insults... " >&6; }
+
+# Check whether --with-insults was given.
+if test "${with_insults+set}" = set; then :
+ withval=$with_insults; case $with_insults in
+ yes) insults=on
+ with_classic_insults=yes
+ with_csops_insults=yes
+ ;;
+ disabled) insults=off
+ with_classic_insults=yes
+ with_csops_insults=yes
+ ;;
+ no) insults=off
+ ;;
+ *) as_fn_error $? "\"--with-insults does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+if test "$insults" = "on"; then
+ $as_echo "#define USE_INSULTS 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Check whether --with-all-insults was given.
+if test "${with_all_insults+set}" = set; then :
+ withval=$with_all_insults; case $with_all_insults in
+ yes) with_classic_insults=yes
+ with_csops_insults=yes
+ with_hal_insults=yes
+ with_goons_insults=yes
+ with_python_insults=yes
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-all-insults does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-classic-insults was given.
+if test "${with_classic_insults+set}" = set; then :
+ withval=$with_classic_insults; case $with_classic_insults in
+ yes) $as_echo "#define CLASSIC_INSULTS 1" >>confdefs.h
+
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-classic-insults does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-csops-insults was given.
+if test "${with_csops_insults+set}" = set; then :
+ withval=$with_csops_insults; case $with_csops_insults in
+ yes) $as_echo "#define CSOPS_INSULTS 1" >>confdefs.h
+
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-csops-insults does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-hal-insults was given.
+if test "${with_hal_insults+set}" = set; then :
+ withval=$with_hal_insults; case $with_hal_insults in
+ yes) $as_echo "#define HAL_INSULTS 1" >>confdefs.h
+
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-hal-insults does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-goons-insults was given.
+if test "${with_goons_insults+set}" = set; then :
+ withval=$with_goons_insults; case $with_goons_insults in
+ yes) $as_echo "#define GOONS_INSULTS 1" >>confdefs.h
+
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-goons-insults does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-python-insults was given.
+if test "${with_python_insults+set}" = set; then :
+ withval=$with_python_insults; case $with_python_insults in
+ yes) $as_echo "#define PYTHON_INSULTS 1" >>confdefs.h
+
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-python-insults does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-nsswitch was given.
+if test "${with_nsswitch+set}" = set; then :
+ withval=$with_nsswitch; case $with_nsswitch in
+ no) ;;
+ yes) with_nsswitch="/etc/nsswitch.conf"
+ ;;
+ *) ;;
+esac
+fi
+
+
+
+# Check whether --with-ldap was given.
+if test "${with_ldap+set}" = set; then :
+ withval=$with_ldap; case $with_ldap in
+ no) ;;
+ *) $as_echo "#define HAVE_LDAP 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use sudoers from LDAP" >&5
+$as_echo_n "checking whether to use sudoers from LDAP... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-ldap-conf-file was given.
+if test "${with_ldap_conf_file+set}" = set; then :
+ withval=$with_ldap_conf_file;
+fi
+
+test -n "$with_ldap_conf_file" && ldap_conf="$with_ldap_conf_file"
+cat >>confdefs.h <<EOF
+#define _PATH_LDAP_CONF "$ldap_conf"
+EOF
+
+
+
+# Check whether --with-ldap-secret-file was given.
+if test "${with_ldap_secret_file+set}" = set; then :
+ withval=$with_ldap_secret_file;
+fi
+
+test -n "$with_ldap_secret_file" && ldap_secret="$with_ldap_secret_file"
+cat >>confdefs.h <<EOF
+#define _PATH_LDAP_SECRET "$ldap_secret"
+EOF
+
+
+if test "$insults" = "on"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking which insult sets to include" >&5
+$as_echo_n "checking which insult sets to include... " >&6; }
+ i=""
+ test "$with_python_insults" = "yes" && i="python ${i}"
+ test "$with_goons_insults" = "yes" && i="goons ${i}"
+ test "$with_hal_insults" = "yes" && i="hal ${i}"
+ test "$with_csops_insults" = "yes" && i="csops ${i}"
+ test "$with_classic_insults" = "yes" && i="classic ${i}"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $i" >&5
+$as_echo "$i" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to override the user's path" >&5
+$as_echo_n "checking whether to override the user's path... " >&6; }
+
+# Check whether --with-secure-path was given.
+if test "${with_secure_path+set}" = set; then :
+ withval=$with_secure_path; case $with_secure_path in
+ yes) with_secure_path="/bin:/usr/ucb:/usr/bin:/usr/sbin:/sbin:/usr/etc:/etc"
+ cat >>confdefs.h <<_ACEOF
+#define SECURE_PATH "$with_secure_path"
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_secure_path" >&5
+$as_echo "$with_secure_path" >&6; }
+ secure_path="set to $with_secure_path"
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ *) cat >>confdefs.h <<_ACEOF
+#define SECURE_PATH "$with_secure_path"
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_secure_path" >&5
+$as_echo "$with_secure_path" >&6; }
+ secure_path="set to F<$with_secure_path>"
+ ;;
+esac
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to get ip addresses from the network interfaces" >&5
+$as_echo_n "checking whether to get ip addresses from the network interfaces... " >&6; }
+
+# Check whether --with-interfaces was given.
+if test "${with_interfaces+set}" = set; then :
+ withval=$with_interfaces; case $with_interfaces in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ;;
+ no) $as_echo "#define STUB_LOAD_INTERFACES 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ *) as_fn_error $? "\"--with-interfaces does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use an askpass helper" >&5
+$as_echo_n "checking whether to use an askpass helper... " >&6; }
+
+# Check whether --with-askpass was given.
+if test "${with_askpass+set}" = set; then :
+ withval=$with_askpass; case $with_askpass in
+ yes) as_fn_error $? "\"--with-askpass takes a path as an argument.\"" "$LINENO" 5
+ ;;
+ no) ;;
+ *) ;;
+esac
+else
+
+ with_askpass=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+
+if test X"$with_askpass" != X"no"; then
+ cat >>confdefs.h <<EOF
+#define _PATH_SUDO_ASKPASS "$with_askpass"
+EOF
+
+else
+ cat >>confdefs.h <<EOF
+#define _PATH_SUDO_ASKPASS NULL
+EOF
+
+fi
+
+
+# Check whether --with-exampledir was given.
+if test "${with_exampledir+set}" = set; then :
+ withval=$with_exampledir; case $with_exampledir in
+ yes) as_fn_error $? "\"must give --with-exampledir an argument.\"" "$LINENO" 5
+ ;;
+ no) as_fn_error $? "\"--without-exampledir not supported.\"" "$LINENO" 5
+ ;;
+ *) exampledir="$with_exampledir"
+esac
+fi
+
+
+
+# Check whether --with-plugindir was given.
+if test "${with_plugindir+set}" = set; then :
+ withval=$with_plugindir; case $with_plugindir in
+ no) as_fn_error $? "\"illegal argument: --without-plugindir.\"" "$LINENO" 5
+ ;;
+ *) ;;
+esac
+else
+ with_plugindir="$libexecdir/sudo"
+fi
+
+
+
+# Check whether --with-man was given.
+if test "${with_man+set}" = set; then :
+ withval=$with_man; case $with_man in
+ yes) MANTYPE=man
+ ;;
+ no) as_fn_error $? "\"--without-man not supported.\"" "$LINENO" 5
+ ;;
+ *) as_fn_error $? "\"ignoring unknown argument to --with-man: $with_man.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+# Check whether --with-mdoc was given.
+if test "${with_mdoc+set}" = set; then :
+ withval=$with_mdoc; case $with_mdoc in
+ yes) MANTYPE=mdoc
+ ;;
+ no) as_fn_error $? "\"--without-mdoc not supported.\"" "$LINENO" 5
+ ;;
+ *) as_fn_error $? "\"ignoring unknown argument to --with-mdoc: $with_mdoc.\"" "$LINENO" 5
+ ;;
+esac
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to do user authentication by default" >&5
+$as_echo_n "checking whether to do user authentication by default... " >&6; }
+# Check whether --enable-authentication was given.
+if test "${enable_authentication+set}" = set; then :
+ enableval=$enable_authentication; case "$enableval" in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ $as_echo "#define NO_AUTHENTICATION 1" >>confdefs.h
+
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-authentication: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-authentication: $enableval" >&2;}
+ ;;
+ esac
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to disable running the mailer as root" >&5
+$as_echo_n "checking whether to disable running the mailer as root... " >&6; }
+# Check whether --enable-root-mailer was given.
+if test "${enable_root_mailer+set}" = set; then :
+ enableval=$enable_root_mailer; case "$enableval" in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ $as_echo "#define NO_ROOT_MAILER 1" >>confdefs.h
+
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-root-mailer: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-root-mailer: $enableval" >&2;}
+ ;;
+ esac
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Check whether --enable-setreuid was given.
+if test "${enable_setreuid+set}" = set; then :
+ enableval=$enable_setreuid; case "$enableval" in
+ no) SKIP_SETREUID=yes
+ ;;
+ *) ;;
+ esac
+
+fi
+
+
+# Check whether --enable-setresuid was given.
+if test "${enable_setresuid+set}" = set; then :
+ enableval=$enable_setresuid; case "$enableval" in
+ no) SKIP_SETRESUID=yes
+ ;;
+ *) ;;
+ esac
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to disable shadow password support" >&5
+$as_echo_n "checking whether to disable shadow password support... " >&6; }
+# Check whether --enable-shadow was given.
+if test "${enable_shadow+set}" = set; then :
+ enableval=$enable_shadow; case "$enableval" in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CHECKSHADOW="false"
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-shadow: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-shadow: $enableval" >&2;}
+ ;;
+ esac
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether root should be allowed to use sudo" >&5
+$as_echo_n "checking whether root should be allowed to use sudo... " >&6; }
+# Check whether --enable-root-sudo was given.
+if test "${enable_root_sudo+set}" = set; then :
+ enableval=$enable_root_sudo; case "$enableval" in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ;;
+ no) $as_echo "#define NO_ROOT_SUDO 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ root_sudo=off
+ ;;
+ *) as_fn_error $? "\"--enable-root-sudo does not take an argument.\"" "$LINENO" 5
+ ;;
+ esac
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to log the hostname in the log file" >&5
+$as_echo_n "checking whether to log the hostname in the log file... " >&6; }
+# Check whether --enable-log-host was given.
+if test "${enable_log_host+set}" = set; then :
+ enableval=$enable_log_host; case "$enableval" in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ $as_echo "#define HOST_IN_LOG 1" >>confdefs.h
+
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-log-host: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-log-host: $enableval" >&2;}
+ ;;
+ esac
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to invoke a shell if sudo is given no arguments" >&5
+$as_echo_n "checking whether to invoke a shell if sudo is given no arguments... " >&6; }
+# Check whether --enable-noargs-shell was given.
+if test "${enable_noargs_shell+set}" = set; then :
+ enableval=$enable_noargs_shell; case "$enableval" in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ $as_echo "#define SHELL_IF_NO_ARGS 1" >>confdefs.h
+
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-noargs-shell: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-noargs-shell: $enableval" >&2;}
+ ;;
+ esac
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to set \$HOME to target user in shell mode" >&5
+$as_echo_n "checking whether to set \$HOME to target user in shell mode... " >&6; }
+# Check whether --enable-shell-sets-home was given.
+if test "${enable_shell_sets_home+set}" = set; then :
+ enableval=$enable_shell_sets_home; case "$enableval" in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ $as_echo "#define SHELL_SETS_HOME 1" >>confdefs.h
+
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-shell-sets-home: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-shell-sets-home: $enableval" >&2;}
+ ;;
+ esac
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to disable 'command not found' messages" >&5
+$as_echo_n "checking whether to disable 'command not found' messages... " >&6; }
+# Check whether --enable-path_info was given.
+if test "${enable_path_info+set}" = set; then :
+ enableval=$enable_path_info; case "$enableval" in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ $as_echo "#define DONT_LEAK_PATH_INFO 1" >>confdefs.h
+
+ path_info=off
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-path-info: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-path-info: $enableval" >&2;}
+ ;;
+ esac
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable environment debugging" >&5
+$as_echo_n "checking whether to enable environment debugging... " >&6; }
+# Check whether --enable-env_debug was given.
+if test "${enable_env_debug+set}" = set; then :
+ enableval=$enable_env_debug; case "$enableval" in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ $as_echo "#define ENV_DEBUG 1" >>confdefs.h
+
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-env-debug: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-env-debug: $enableval" >&2;}
+ ;;
+ esac
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Check whether --enable-zlib was given.
+if test "${enable_zlib+set}" = set; then :
+ enableval=$enable_zlib;
+else
+ enable_zlib=yes
+fi
+
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -DZLIB_CONST "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -DZLIB_CONST"; } >&5
+ (: CPPFLAGS already contains -DZLIB_CONST) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -DZLIB_CONST"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-DZLIB_CONST
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable environment resetting by default" >&5
+$as_echo_n "checking whether to enable environment resetting by default... " >&6; }
+# Check whether --enable-env_reset was given.
+if test "${enable_env_reset+set}" = set; then :
+ enableval=$enable_env_reset; case "$enableval" in
+ yes) env_reset=on
+ ;;
+ no) env_reset=off
+ ;;
+ *) env_reset=on
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-env-reset: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-env-reset: $enableval" >&2;}
+ ;;
+ esac
+
+fi
+
+if test "$env_reset" = "on"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ $as_echo "#define ENV_RESET 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ $as_echo "#define ENV_RESET 0" >>confdefs.h
+
+fi
+
+# Check whether --enable-warnings was given.
+if test "${enable_warnings+set}" = set; then :
+ enableval=$enable_warnings; case "$enableval" in
+ yes) ;;
+ no) ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-warnings: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-warnings: $enableval" >&2;}
+ ;;
+ esac
+
+fi
+
+
+# Check whether --enable-werror was given.
+if test "${enable_werror+set}" = set; then :
+ enableval=$enable_werror; case "$enableval" in
+ yes) ;;
+ no) ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-werror: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-werror: $enableval" >&2;}
+ ;;
+ esac
+
+fi
+
+
+# Check whether --enable-openssl was given.
+if test "${enable_openssl+set}" = set; then :
+ enableval=$enable_openssl; case $enableval in
+ no) ;;
+ *) LIBMD="-lcrypto"
+ DIGEST=digest_openssl.lo
+ $as_echo "#define HAVE_OPENSSL 1" >>confdefs.h
+
+ if test "$enableval" != "yes"; then
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I${enableval}/include "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I\${enableval}/include"; } >&5
+ (: CPPFLAGS already contains -I${enableval}/include) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I${enableval}/include"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I${enableval}/include
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" -L${enableval}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains -L\${enableval}/lib"; } >&5
+ (: SUDOERS_LDFLAGS already contains -L${enableval}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " -L${enableval}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=-L${enableval}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${SUDOERS_LDFLAGS_R+:} false; then :
+
+ case " $SUDOERS_LDFLAGS_R " in #(
+ *" -R${enableval}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R already contains -R\${enableval}/lib"; } >&5
+ (: SUDOERS_LDFLAGS_R already contains -R${enableval}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS_R " -R${enableval}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS_R=-R${enableval}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+ fi
+ ;;
+ esac
+
+fi
+
+
+# Check whether --enable-gcrypt was given.
+if test "${enable_gcrypt+set}" = set; then :
+ enableval=$enable_gcrypt; case $enableval in
+ no) ;;
+ *) LIBMD="-lgcrypt"
+ DIGEST=digest_gcrypt.lo
+ $as_echo "#define HAVE_GCRYPT 1" >>confdefs.h
+
+ if test "$enableval" != "yes"; then
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I${enableval}/include "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I\${enableval}/include"; } >&5
+ (: CPPFLAGS already contains -I${enableval}/include) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I${enableval}/include"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I${enableval}/include
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" -L${enableval}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains -L\${enableval}/lib"; } >&5
+ (: SUDOERS_LDFLAGS already contains -L${enableval}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " -L${enableval}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=-L${enableval}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${SUDOERS_LDFLAGS_R+:} false; then :
+
+ case " $SUDOERS_LDFLAGS_R " in #(
+ *" -R${enableval}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R already contains -R\${enableval}/lib"; } >&5
+ (: SUDOERS_LDFLAGS_R already contains -R${enableval}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS_R " -R${enableval}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS_R=-R${enableval}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+ fi
+ ;;
+ esac
+
+fi
+
+
+# Check whether --enable-hardening was given.
+if test "${enable_hardening+set}" = set; then :
+ enableval=$enable_hardening;
+else
+ enable_hardening=yes
+fi
+
+
+# Check whether --enable-pie was given.
+if test "${enable_pie+set}" = set; then :
+ enableval=$enable_pie;
+fi
+
+
+# Check whether --enable-asan was given.
+if test "${enable_asan+set}" = set; then :
+ enableval=$enable_asan;
+fi
+
+
+# Check whether --enable-poll was given.
+if test "${enable_poll+set}" = set; then :
+ enableval=$enable_poll;
+fi
+
+
+# Check whether --enable-admin-flag was given.
+if test "${enable_admin_flag+set}" = set; then :
+ enableval=$enable_admin_flag; case "$enableval" in
+ yes) $as_echo "#define USE_ADMIN_FLAG 1" >>confdefs.h
+
+ ;;
+ no) ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-admin-flag: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-admin-flag: $enableval" >&2;}
+ ;;
+ esac
+
+fi
+
+
+# Check whether --enable-nls was given.
+if test "${enable_nls+set}" = set; then :
+ enableval=$enable_nls;
+else
+ enable_nls=yes
+fi
+
+
+# Check whether --enable-rpath was given.
+if test "${enable_rpath+set}" = set; then :
+ enableval=$enable_rpath;
+else
+ enable_rpath=yes
+fi
+
+
+# Check whether --enable-static-sudoers was given.
+if test "${enable_static_sudoers+set}" = set; then :
+ enableval=$enable_static_sudoers;
+else
+ enable_static_sudoers=no
+fi
+
+
+# Check whether --enable-shared_libutil was given.
+if test "${enable_shared_libutil+set}" = set; then :
+ enableval=$enable_shared_libutil;
+else
+ enable_shared_libutil=yes
+fi
+
+
+# Check whether --enable-tmpfiles.d was given.
+if test "${enable_tmpfiles_d+set}" = set; then :
+ enableval=$enable_tmpfiles_d; case $enableval in
+ yes) TMPFILES_D=/usr/lib/tmpfiles.d
+ ;;
+ no) TMPFILES_D=
+ ;;
+ *) TMPFILES_D="$enableval"
+esac
+else
+
+ test -f /usr/lib/tmpfiles.d/systemd.conf && TMPFILES_D=/usr/lib/tmpfiles.d
+
+fi
+
+
+# Check whether --enable-devsearch was given.
+if test "${enable_devsearch+set}" = set; then :
+ enableval=$enable_devsearch; case $enableval in
+ yes) # use default value
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring attempt to disable the device search path" >&5
+$as_echo "$as_me: WARNING: Ignoring attempt to disable the device search path" >&2;}
+ ;;
+ *) devsearch="$enableval"
+ ;;
+esac
+fi
+
+ds="`echo \"$devsearch\"|sed 's@/dev/*\([^:]*:*\)@_PATH_DEV \"\1\" @g'`"
+cat >>confdefs.h <<EOF
+#define _PATH_SUDO_DEVSEARCH $ds
+EOF
+
+
+
+# Check whether --with-selinux was given.
+if test "${with_selinux+set}" = set; then :
+ withval=$with_selinux; case $with_selinux in
+ yes) SELINUX_USAGE="[-r role] [-t type] "
+ $as_echo "#define HAVE_SELINUX 1" >>confdefs.h
+
+ SUDO_LIBS="${SUDO_LIBS} -lselinux"
+ SUDO_OBJS="${SUDO_OBJS} selinux.o"
+ PROGS="${PROGS} sesh"
+ SEMAN=1
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setkeycreatecon in -lselinux" >&5
+$as_echo_n "checking for setkeycreatecon in -lselinux... " >&6; }
+if ${ac_cv_lib_selinux_setkeycreatecon+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lselinux $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setkeycreatecon ();
+int
+main ()
+{
+return setkeycreatecon ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_selinux_setkeycreatecon=yes
+else
+ ac_cv_lib_selinux_setkeycreatecon=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_setkeycreatecon" >&5
+$as_echo "$ac_cv_lib_selinux_setkeycreatecon" >&6; }
+if test "x$ac_cv_lib_selinux_setkeycreatecon" = xyes; then :
+ $as_echo "#define HAVE_SETKEYCREATECON 1" >>confdefs.h
+
+fi
+
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-selinux does not take an argument.\"" "$LINENO" 5
+ ;;
+esac
+else
+ with_selinux=no
+fi
+
+
+# Check whether --enable-sasl was given.
+if test "${enable_sasl+set}" = set; then :
+ enableval=$enable_sasl; case "$enableval" in
+ yes|no) ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-sasl: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-sasl: $enableval" >&2;}
+ ;;
+ esac
+
+fi
+
+
+# Check whether --enable-timestamp-type was given.
+if test "${enable_timestamp_type+set}" = set; then :
+ enableval=$enable_timestamp_type; case "$enableval" in
+ global|ppid|tty)
+ timestamp_type=$enableval
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-timestamp-type: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-timestamp-type: $enableval" >&2;}
+ ;;
+ esac
+
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define TIMESTAMP_TYPE $timestamp_type
+_ACEOF
+
+
+# Check whether --enable-offensive_insults was given.
+if test "${enable_offensive_insults+set}" = set; then :
+ enableval=$enable_offensive_insults;
+else
+ enable_offensive_insults=no
+fi
+
+if test "$enable_offensive_insults" = "yes"; then
+ $as_echo "#define OFFENSIVE_INSULTS 1" >>confdefs.h
+
+fi
+
+# Check whether --enable-package_build was given.
+if test "${enable_package_build+set}" = set; then :
+ enableval=$enable_package_build;
+else
+ enable_package_build=no
+fi
+
+
+# Check whether --enable-gss_krb5_ccache_name was given.
+if test "${enable_gss_krb5_ccache_name+set}" = set; then :
+ enableval=$enable_gss_krb5_ccache_name; check_gss_krb5_ccache_name=$enableval
+else
+ check_gss_krb5_ccache_name=no
+fi
+
+
+# Check whether --enable-pvs-studio was given.
+if test "${enable_pvs_studio+set}" = set; then :
+ enableval=$enable_pvs_studio;
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5
+$as_echo_n "checking for library containing strerror... " >&6; }
+if ${ac_cv_search_strerror+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char strerror ();
+int
+main ()
+{
+return strerror ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' cposix; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_strerror=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_strerror+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_strerror+:} false; then :
+
+else
+ ac_cv_search_strerror=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_strerror" >&5
+$as_echo "$ac_cv_search_strerror" >&6; }
+ac_res=$ac_cv_search_strerror
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test X"$AR" = X"false"; then
+ as_fn_error $? "the \"ar\" utility is required to build sudo" "$LINENO" 5
+fi
+
+if test "x$ac_cv_prog_cc_c89" = "xno"; then
+ as_fn_error $? "Sudo version $PACKAGE_VERSION requires an ANSI C compiler to build." "$LINENO" 5
+fi
+
+if test "$enable_static" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring --disable-static, sudo does not install static libs" >&5
+$as_echo "$as_me: WARNING: Ignoring --disable-static, sudo does not install static libs" >&2;}
+ enable_static=yes
+fi
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+
+case "$host_os" in
+aix4.[23]|aix4.[23].*|aix[5-9]*)
+
+if ${LDFLAGS+:} false; then :
+
+ case " $LDFLAGS " in #(
+ *" -Wl,-brtl "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains -Wl,-brtl"; } >&5
+ (: LDFLAGS already contains -Wl,-brtl) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append LDFLAGS " -Wl,-brtl"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS\""; } >&5
+ (: LDFLAGS="$LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ LDFLAGS=-Wl,-brtl
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS\""; } >&5
+ (: LDFLAGS="$LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ ;;
+esac
+
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.6'
+macro_revision='2.4.6'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case $ECHO in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return, which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD=$ac_prog
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test yes = "$with_gnu_ld"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi
+fi
+
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM=$NM
+else
+ lt_nm_to_check=${ac_tool_prefix}nm
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break 2
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break 2
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols -headers"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring=ABCD
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test 17 != "$i" # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n "$lt_cv_sys_max_cmd_len"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test yes != "$GCC"; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+os2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -eq "$ac_status"; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -ne "$ac_status"; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test no = "$lt_cv_ar_at_file"; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ bitrig* | openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test ia64 = "$host_cpu"; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS=conftstm.$ac_objext
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest$ac_exeext; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test yes = "$pipe_works"; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+ if test yes = "$GCC"; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
+$as_echo "$with_sysroot" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
+$as_echo_n "checking for a working dd... " >&6; }
+if ${ac_cv_path_lt_DD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+if test -z "$lt_DD"; then
+ ac_path_lt_DD_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in dd; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_lt_DD" || continue
+if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi
+ $ac_path_lt_DD_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_lt_DD"; then
+ :
+ fi
+else
+ ac_cv_path_lt_DD=$lt_DD
+fi
+
+rm -f conftest.i conftest2.i conftest.out
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
+$as_echo "$ac_cv_path_lt_DD" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
+$as_echo_n "checking how to truncate binary pipes... " >&6; }
+if ${lt_cv_truncate_bin+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
+$as_echo "$lt_cv_truncate_bin" >&6; }
+
+
+
+
+
+
+
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in $*""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE=32
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test yes != "$lt_cv_cc_needs_belf"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS=$SAVE_CFLAGS
+ fi
+ ;;
+*-*solaris*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*|x86_64-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD=${LD-ld}_sol2
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks=$enable_libtool_lock
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test yes != "$lt_cv_path_mainfest_tool"; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "$LT_MULTI_MODULE"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&5
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&5
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[012][,.]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ fi
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x$2 in
+ x)
+ ;;
+ *:)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+ ;;
+ x:*)
+ eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+ ;;
+ *)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+enable_dlopen=yes
+
+
+
+
+ enable_win32_dll=no
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+ # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for lt_pkg in $withval; do
+ IFS=$lt_save_ifs
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ pic_mode=default
+fi
+
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+ shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[5-9]*,yes)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
+$as_echo_n "checking which variant of shared library versioning to provide... " >&6; }
+
+# Check whether --with-aix-soname was given.
+if test "${with_aix_soname+set}" = set; then :
+ withval=$with_aix_soname; case $withval in
+ aix|svr4|both)
+ ;;
+ *)
+ as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5
+ ;;
+ esac
+ lt_cv_with_aix_soname=$with_aix_soname
+else
+ if ${lt_cv_with_aix_soname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_with_aix_soname=aix
+fi
+
+ with_aix_soname=$lt_cv_with_aix_soname
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
+$as_echo "$with_aix_soname" >&6; }
+ if test aix != "$with_aix_soname"; then
+ # For the AIX way of multilib, we name the shared archive member
+ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+ # the AIX toolchain works better with OBJECT_MODE set (default 32).
+ if test 64 = "${OBJECT_MODE-32}"; then
+ shared_archive_member_spec=shr_64
+ else
+ shared_archive_member_spec=shr
+ fi
+ fi
+ ;;
+*)
+ with_aix_soname=aix
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+func_cc_basename $compiler
+cc_basename=$func_cc_basename_result
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/${ac_tool_prefix}file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC=$CC
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test yes = "$GCC"; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+ if test yes = "$GCC"; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static='$wl-static'
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ if test -n "$lt_prog_compiler_pic"; then
+ lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static='$wl-static'
+ ;;
+ esac
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='$wl-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64, which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_pic_works"; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_static_works"; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links=nottested
+if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test no = "$hard_links"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ fix_hardcoded_libdir_flag_spec=
+ fix_hardcoded_libdir_flag_spec_ld=
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test yes != "$GCC"; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd* | bitrig*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test yes = "$with_gnu_ld"; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test yes = "$lt_use_gnu_ld_interface"; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='$wl'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ export_dynamic_flag_spec='$wl--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test ia64 != "$host_cpu"; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='$wl--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ shrext_cmds=.dll
+ archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test linux-dietlibc = "$host_os"; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test no = "$tmp_diet"
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ tcc*)
+ export_dynamic_flag_spec='-rdynamic'
+ ;;
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test no = "$ld_shlibs"; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # traditional, no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ ;;
+ esac
+
+ if test yes = "$GCC"; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ export_dynamic_flag_spec='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' $wl-bernotok'
+ allow_undefined_flag=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test yes = "$GCC"; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='$wl-E'
+ ;;
+
+ hpux10*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+ module_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+ else
+ archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags $fix_hardcoded_libdir_flag_ld'
+ module_cmds='$LD -b -o $lib $libobjs $deplibs $linker_flags $fix_hardcoded_libdir_flag_ld'
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir $fix_hardcoded_libdir_flag'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ # gcc-3.0.1 (collect2) breaks on -Wl,+cdp.
+ # HP-cc ignores -Wl,+cdp, and we test the linker for +cdp support.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if +cdp linker flag works" >&5
+$as_echo_n "checking if +cdp linker flag works... " >&6; }
+if ${lt_cv_ldflag_cdp_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ldflag_cdp_works=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,+cdp -Wl,/usr/lib/libc.1:/nonexistent -Wl,+cdp -Wl,/lib/libc.1:/nonexistent"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ldflag_cdp_works=yes
+else
+ lt_cv_ldflag_cdp_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ldflag_cdp_works" >&5
+$as_echo "$lt_cv_ldflag_cdp_works" >&6; }
+ if test "$lt_cv_ldflag_cdp_works" = yes; then
+ fix_hardcoded_libdir_flag_spec='${wl}+cdp ${wl}${linkdir}/${dlname}:${libdir}/${dlname}'
+ fix_hardcoded_libdir_flag_spec_ld='+cdp ${linkdir}/${dlname}:${libdir}/${dlname}'
+ fi
+ fi
+ ;;
+
+ hpux11*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ module_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ module_cmds='$CC -shared $pic_flag $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+ module_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ module_cmds='$CC -b -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ module_cmds='$CC -b $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test yes = "$lt_cv_prog_compiler__b"; then
+
+ archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+ module_cmds='$CC -b -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+
+else
+
+ archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags $fix_hardcoded_libdir_flag_ld'
+ module_cmds='$LD -b -o $lib $libobjs $deplibs $linker_flags $fix_hardcoded_libdir_flag_ld'
+
+fi
+
+ ;;
+ esac
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir $fix_hardcoded_libdir_flag'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ # gcc-3.0.1 (collect2) breaks on -Wl,+cdp.
+ # HP-cc ignores -Wl,+cdp, and we test the linker for +cdp support.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if +cdp linker flag works" >&5
+$as_echo_n "checking if +cdp linker flag works... " >&6; }
+if ${lt_cv_ldflag_cdp_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ldflag_cdp_works=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,+cdp -Wl,/usr/lib/libc.1:/nonexistent -Wl,+cdp -Wl,/lib/libc.1:/nonexistent"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ldflag_cdp_works=yes
+else
+ lt_cv_ldflag_cdp_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ldflag_cdp_works" >&5
+$as_echo "$lt_cv_ldflag_cdp_works" >&6; }
+ if test "$lt_cv_ldflag_cdp_works" = yes; then
+ fix_hardcoded_libdir_flag_spec='${wl}+cdp ${wl}${linkdir}/${dlname}:${libdir}/${dlname}'
+ fix_hardcoded_libdir_flag_spec_ld='+cdp ${linkdir}/${dlname}:${libdir}/${dlname}'
+ fi
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ linux*)
+ case $cc_basename in
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ ld_shlibs=yes
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ else
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ shrext_cmds=.dll
+ archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ osf3*)
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='$wl'
+ archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test yes = "$GCC"; then
+ whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test sequent = "$host_vendor"; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='$wl-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='$wl-z,text'
+ allow_undefined_flag='$wl-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test sni = "$host_vendor"; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='$wl-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test no = "$ld_shlibs" && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test yes = "$GCC"; then
+ case $host_os in
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary...
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo = "/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a(lib.so.V)'
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+ fi
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=sco
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test yes = "$hardcode_automatic"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$hardcode_direct" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&
+ test -z "$fix_hardcoded_libdir_flag_spec" &&
+ test no != "$hardcode_minus_L"; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test relink = "$hardcode_action" ||
+ test yes = "$inherit_rpath"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test yes != "$enable_dlopen"; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen=load_add_on
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+
+ lt_cv_dlopen=dyld
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+ lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test no = "$lt_cv_dlopen"; then
+ enable_dlopen=no
+ else
+ enable_dlopen=yes
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS=$LDFLAGS
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS=$LIBS
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test yes = "$lt_cv_dlopen_self"; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report what library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC=$lt_save_CC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+
+# Check whether --with-libtool was given.
+if test "${with_libtool+set}" = set; then :
+ withval=$with_libtool; case $with_libtool in
+ yes|builtin) ;;
+ no) as_fn_error $? "\"--without-libtool not supported.\"" "$LINENO" 5
+ ;;
+ system) LIBTOOL=libtool
+ ;;
+ *) LIBTOOL="$with_libtool"
+ ;;
+esac
+fi
+
+
+if test "$enable_shared" = "no"; then
+ with_noexec=no
+ enable_dlopen=no
+ lt_cv_dlopen=none
+ lt_cv_dlopen_libs=
+ ac_cv_func_dlopen=no
+ LT_LDFLAGS=-static
+fi
+LIBDL="$lt_cv_dlopen_libs"
+SHLIB_ENABLE="$enable_dlopen"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking path to sudo_noexec.so" >&5
+$as_echo_n "checking path to sudo_noexec.so... " >&6; }
+
+# Check whether --with-noexec was given.
+if test "${with_noexec+set}" = set; then :
+ withval=$with_noexec; case $with_noexec in
+ yes) with_noexec="$libexecdir/sudo/sudo_noexec.so"
+ ;;
+ no) ;;
+ *) ;;
+esac
+else
+ with_noexec="$libexecdir/sudo/sudo_noexec.so"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_noexec" >&5
+$as_echo "$with_noexec" >&6; }
+NOEXECFILE="sudo_noexec.so"
+NOEXECDIR="`echo $with_noexec|sed -e 's:^${\([^}]*\)}:$(\1):' -e 's:^\(.*\)/[^/]*:\1:'`"
+
+# Extract the first word of "uname", so it can be a program name with args.
+set dummy uname; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_UNAMEPROG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $UNAMEPROG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_UNAMEPROG="$UNAMEPROG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_UNAMEPROG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_UNAMEPROG" && ac_cv_path_UNAMEPROG="uname"
+ ;;
+esac
+fi
+UNAMEPROG=$ac_cv_path_UNAMEPROG
+if test -n "$UNAMEPROG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $UNAMEPROG" >&5
+$as_echo "$UNAMEPROG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "tr", so it can be a program name with args.
+set dummy tr; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_TRPROG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $TRPROG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_TRPROG="$TRPROG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_TRPROG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_TRPROG" && ac_cv_path_TRPROG="tr"
+ ;;
+esac
+fi
+TRPROG=$ac_cv_path_TRPROG
+if test -n "$TRPROG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TRPROG" >&5
+$as_echo "$TRPROG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "mandoc", so it can be a program name with args.
+set dummy mandoc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MANDOCPROG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MANDOCPROG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MANDOCPROG="$MANDOCPROG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MANDOCPROG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_MANDOCPROG" && ac_cv_path_MANDOCPROG="mandoc"
+ ;;
+esac
+fi
+MANDOCPROG=$ac_cv_path_MANDOCPROG
+if test -n "$MANDOCPROG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANDOCPROG" >&5
+$as_echo "$MANDOCPROG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "$MANDOCPROG" != "mandoc"; then
+ : ${MANTYPE='mdoc'}
+else
+ # Extract the first word of "nroff", so it can be a program name with args.
+set dummy nroff; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_NROFFPROG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $NROFFPROG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_NROFFPROG="$NROFFPROG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_NROFFPROG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+NROFFPROG=$ac_cv_path_NROFFPROG
+if test -n "$NROFFPROG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NROFFPROG" >&5
+$as_echo "$NROFFPROG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test -n "$NROFFPROG"; then
+ test -n "$MANTYPE" && sudo_cv_var_mantype="$MANTYPE"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking which macro set to use for manual pages" >&5
+$as_echo_n "checking which macro set to use for manual pages... " >&6; }
+if ${sudo_cv_var_mantype+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ sudo_cv_var_mantype="man"
+ echo ".Sh NAME" > conftest
+ echo ".Nm sudo" >> conftest
+ echo ".Nd sudo" >> conftest
+ echo ".Sh DESCRIPTION" >> conftest
+ echo "sudo" >> conftest
+ if $NROFFPROG -mdoc conftest >/dev/null 2>&1; then
+ sudo_cv_var_mantype="mdoc"
+ fi
+ rm -f conftest
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_var_mantype" >&5
+$as_echo "$sudo_cv_var_mantype" >&6; }
+ MANTYPE="$sudo_cv_var_mantype"
+ else
+ MANTYPE=cat
+ MANDIRTYPE=cat
+ mansrcdir='$(srcdir)'
+ fi
+fi
+
+if test -n "$sudo_cv_prev_host"; then
+ if test "$sudo_cv_prev_host" != "$host"; then
+ as_fn_error $? "config.cache was created on a different host; remove it and re-run configure." "$LINENO" 5
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking previous host type" >&5
+$as_echo_n "checking previous host type... " >&6; }
+ if ${sudo_cv_prev_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ sudo_cv_prev_host="$host"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_prev_host" >&5
+$as_echo "$sudo_cv_prev_host" >&6; }
+ fi
+else
+ # this will produce no output since there is no cached value
+ if ${sudo_cv_prev_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ sudo_cv_prev_host="$host"
+fi
+
+fi
+
+if test -n "$host_os"; then
+ OS=`echo $host_os | sed 's/[0-9].*//'`
+ OSREV=`echo $host_os | sed 's/^[^0-9\.]*\([0-9\.]*\).*$/\1/'`
+ OSMAJOR=`echo $OSREV | sed 's/\..*$//'`
+else
+ OS="unknown"
+ OSREV=0
+ OSMAJOR=0
+fi
+
+case "$host" in
+ *-*-solaris2*)
+ $as_echo "#define PAM_SUN_CODEBASE 1" >>confdefs.h
+
+
+ # LD_PRELOAD is space-delimited
+ RTLD_PRELOAD_DELIM=" "
+
+ # Solaris-specific initialization
+ OS_INIT=os_init_solaris
+ SUDO_OBJS="${SUDO_OBJS} solaris.o"
+
+ # AFS support needs -lucb
+ if test "$with_AFS" = "yes"; then
+ AFS_LIBS="-lc -lucb"
+ fi
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ for ac_func in priv_set
+do :
+ ac_fn_c_check_func "$LINENO" "priv_set" "ac_cv_func_priv_set"
+if test "x$ac_cv_func_priv_set" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_PRIV_SET 1
+_ACEOF
+ PSMAN=1
+fi
+done
+
+ ;;
+ *-*-aix*)
+ $as_echo "#define PAM_SUN_CODEBASE 1" >>confdefs.h
+
+
+ # To get all prototypes (so we pass -Wall)
+ $as_echo "#define _LINUX_SOURCE_COMPAT 1" >>confdefs.h
+
+
+ # For AIX we build in support for both LAM and PAM
+ # and choose which to use based on auth_type in
+ # /etc/security/login.cfg
+ if test X"${with_pam}${with_aixauth}" = X""; then
+ AUTH_EXCL_DEF="AIX_AUTH PAM"
+ fi
+
+ # AIX analog of nsswitch.conf, enabled by default
+
+# Check whether --with-netsvc was given.
+if test "${with_netsvc+set}" = set; then :
+ withval=$with_netsvc; case $with_netsvc in
+ no) ;;
+ yes) with_netsvc="/etc/netsvc.conf"
+ ;;
+ *) ;;
+ esac
+fi
+
+ if test -z "$with_nsswitch" -a -z "$with_netsvc"; then
+ with_netsvc="/etc/netsvc.conf"
+ fi
+
+ # LDR_PRELOAD is only supported in AIX 5.3 and later
+ case "$OSREV" in
+ [1-4].*) with_noexec=no;;
+ 5.[1-2]*) with_noexec=no;;
+ *) RTLD_PRELOAD_VAR="LDR_PRELOAD";;
+ esac
+
+ # strnlen/strndup may be broken on AIX < 6 depending
+ # on the libc version, use our own.
+ if test $OSMAJOR -lt 6; then
+ ac_cv_func_strnlen=no
+ fi
+
+ # getline() may or may ont be present on AIX <= 6.1.
+ # bos610 is missing getline/getdelim but bos61J has it.
+ if test "$enable_package_build" = "yes"; then
+ if test $OSMAJOR -le 6; then
+ ac_cv_func_getline=no
+ fi
+ fi
+
+ # memset_s() may or may ont be present on AIX <= 7.1.
+ # bos710 is missing memset_s but bos71L has it.
+ if test "$enable_package_build" = "yes"; then
+ if test $OSMAJOR -le 7; then
+ ac_cv_func_memset_s=no
+ fi
+ fi
+
+ # Remove timedir on boot, AIX does not have /var/run
+ INIT_SCRIPT=aix.sh
+ INIT_DIR=/etc/rc.d/init.d
+ RC_LINK=/etc/rc.d/rc2.d/S90sudo
+
+ # AIX-specific functions
+ for ac_func in getuserattr setrlimit64
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ for ac_func in setauthdb
+do :
+ ac_fn_c_check_func "$LINENO" "setauthdb" "ac_cv_func_setauthdb"
+if test "x$ac_cv_func_setauthdb" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SETAUTHDB 1
+_ACEOF
+ ac_fn_c_check_type "$LINENO" "authdb_t" "ac_cv_type_authdb_t" "#include <usersec.h>
+"
+if test "x$ac_cv_type_authdb_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_AUTHDB_T 1
+_ACEOF
+
+
+fi
+
+fi
+done
+
+
+ COMMON_OBJS="${COMMON_OBJS} aix.lo"
+
+ for _sym in aix_prep_user_v1 aix_restoreauthdb_v1 aix_setauthdb_v1 aix_setauthdb_v2 aix_getauthregistry_v1; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+ # These prototypes may be missing
+ ac_fn_c_check_decl "$LINENO" "usrinfo" "ac_cv_have_decl_usrinfo" "
+#include <sys/types.h>
+#include <uinfo.h>
+
+"
+if test "x$ac_cv_have_decl_usrinfo" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_USRINFO $ac_have_decl
+_ACEOF
+
+ ac_fn_c_check_decl "$LINENO" "setauthdb" "ac_cv_have_decl_setauthdb" "
+#include <sys/types.h>
+#include <usersec.h>
+
+"
+if test "x$ac_cv_have_decl_setauthdb" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SETAUTHDB $ac_have_decl
+_ACEOF
+
+ ;;
+ *-*-hiuxmpp*)
+ $as_echo "#define PAM_SUN_CODEBASE 1" >>confdefs.h
+
+
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+
+ # HP-UX does not clear /var/run so we need to do it
+ INIT_SCRIPT=hpux.sh
+ INIT_DIR=/sbin/init.d
+ RC_LINK=/sbin/rc2.d/S900sudo
+
+ # HP-UX shared libs must be executable.
+ # Load time is much greater if writable so use 0555.
+ SHLIB_MODE=0555
+
+ # HP-UX won't unlink a shared lib that is open
+ INSTALL_BACKUP='~'
+
+ for ac_func in pstat_getproc gethrtime
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ ;;
+ *-*-hpux*)
+ $as_echo "#define PAM_SUN_CODEBASE 1" >>confdefs.h
+
+
+ # AFS support needs -lBSD
+ if test "$with_AFS" = "yes"; then
+ AFS_LIBS="-lc -lBSD"
+ fi
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+
+ # HP-UX does not clear /var/run so we need to do it
+ INIT_SCRIPT=hpux.sh
+ INIT_DIR=/sbin/init.d
+ RC_LINK=/sbin/rc2.d/S900sudo
+
+ # HP-UX shared libs must be executable.
+ # Load time is much greater if writable so use 0555.
+ SHLIB_MODE=0555
+
+ # HP-UX won't unlink a shared lib that is open
+ INSTALL_BACKUP='~'
+
+ # The HP bundled compiler cannot generate shared libs
+ if test -z "$GCC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for HP bundled C compiler" >&5
+$as_echo_n "checking for HP bundled C compiler... " >&6; }
+if ${sudo_cv_var_hpccbundled+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $CC -V 2>&1 | grep '^(Bundled)' >/dev/null 2>&1; then
+ sudo_cv_var_hpccbundled=yes
+ else
+ sudo_cv_var_hpccbundled=no
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_var_hpccbundled" >&5
+$as_echo "$sudo_cv_var_hpccbundled" >&6; }
+ if test "$sudo_cv_var_hpccbundled" = "yes"; then
+ as_fn_error $? "The HP bundled C compiler is unable to build Sudo, you must use gcc or the HP ANSI C compiler instead." "$LINENO" 5
+ fi
+ fi
+
+ # Build PA-RISC1.1 objects for better portability
+ case "$host_cpu" in
+ hppa[2-9]*)
+ _CFLAGS="$CFLAGS"
+ if test -n "$GCC"; then
+ portable_flag="-march=1.1"
+ else
+ portable_flag="+DAportable"
+ fi
+ CFLAGS="$CFLAGS $portable_flag"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands $portable_flag" >&5
+$as_echo_n "checking whether $CC understands $portable_flag... " >&6; }
+if ${sudo_cv_var_daportable+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ sudo_cv_var_daportable=yes
+else
+ sudo_cv_var_daportable=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_var_daportable" >&5
+$as_echo "$sudo_cv_var_daportable" >&6; }
+ if test X"$sudo_cv_var_daportable" != X"yes"; then
+ CFLAGS="$_CFLAGS"
+ fi
+ ;;
+ esac
+
+ case "$host_os" in
+ hpux10.*)
+ shadow_funcs="getprpwnam iscomsec"
+ shadow_libs="-lsec"
+ # HP-UX 10.20 libc has an incompatible getline
+ ac_cv_func_getline="no"
+ # HP-UX 10.x doesn't support LD_PRELOAD
+ with_noexec=no
+ ;;
+ *)
+ shadow_funcs="getspnam iscomsec"
+ shadow_libs="-lsec"
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ ;;
+ esac
+ for ac_func in pstat_getproc gethrtime
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ ;;
+ *-dec-osf*)
+ # ignore envariables wrt dynamic lib path
+
+if ${SUDO_LDFLAGS+:} false; then :
+
+ case " $SUDO_LDFLAGS " in #(
+ *" -Wl,-no_library_replacement "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDO_LDFLAGS already contains -Wl,-no_library_replacement"; } >&5
+ (: SUDO_LDFLAGS already contains -Wl,-no_library_replacement) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDO_LDFLAGS " -Wl,-no_library_replacement"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDO_LDFLAGS=\"\$SUDO_LDFLAGS\""; } >&5
+ (: SUDO_LDFLAGS="$SUDO_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDO_LDFLAGS=-Wl,-no_library_replacement
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDO_LDFLAGS=\"\$SUDO_LDFLAGS\""; } >&5
+ (: SUDO_LDFLAGS="$SUDO_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+
+ : ${CHECKSIA='true'}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to disable sia support on Digital UNIX" >&5
+$as_echo_n "checking whether to disable sia support on Digital UNIX... " >&6; }
+ # Check whether --enable-sia was given.
+if test "${enable_sia+set}" = set; then :
+ enableval=$enable_sia; case "$enableval" in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ CHECKSIA=true
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CHECKSIA=false
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-sia: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-sia: $enableval" >&2;}
+ ;;
+ esac
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ shadow_funcs="getprpwnam dispcrypt"
+ # OSF/1 4.x and higher need -ldb too
+ if test $OSMAJOR -lt 4; then
+ shadow_libs="-lsecurity -laud -lm"
+ else
+ shadow_libs="-lsecurity -ldb -laud -lm"
+ fi
+
+ # use SIA by default, if we have it
+ test "$CHECKSIA" = "true" && AUTH_EXCL_DEF="SIA"
+
+ #
+ # Some versions of Digital Unix ship with a broken
+ # copy of prot.h, which we need for shadow passwords.
+ # XXX - make should remove this as part of distclean
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken prot.h" >&5
+$as_echo_n "checking for broken prot.h... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <sys/types.h>
+#include <sys/security.h>
+#include <prot.h>
+
+int
+main ()
+{
+exit(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, fixing locally" >&5
+$as_echo "yes, fixing locally" >&6; }
+ sed 's:<acl.h>:<sys/acl.h>:g' < /usr/include/prot.h > prot.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ # ":DEFAULT" must be appended to _RLD_LIST
+ RTLD_PRELOAD_VAR="_RLD_LIST"
+ RTLD_PRELOAD_DEFAULT="DEFAULT"
+ : ${mansectsu='8'}
+ : ${mansectform='4'}
+ ;;
+ *-*-irix*)
+ $as_echo "#define _BSD_TYPES 1" >>confdefs.h
+
+ if test -z "$NROFFPROG"; then
+ if test "$prefix" = "/usr/local" -a "$mandir" = '${datarootdir}/man'; then
+ if test -d /usr/share/catman/local; then
+ mandir="/usr/share/catman/local"
+ else
+ mandir="/usr/catman/local"
+ fi
+ fi
+ # Compress cat pages with pack
+ MANCOMPRESS='pack'
+ MANCOMPRESSEXT='.z'
+ else
+ if test "$prefix" = "/usr/local" -a "$mandir" = '${datarootdir}/man'; then
+ if test -d "/usr/share/man/local"; then
+ mandir="/usr/share/man/local"
+ else
+ mandir="/usr/man/local"
+ fi
+ fi
+ fi
+ # IRIX <= 4 needs -lsun
+ if test "$OSMAJOR" -le 4; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwnam in -lsun" >&5
+$as_echo_n "checking for getpwnam in -lsun... " >&6; }
+if ${ac_cv_lib_sun_getpwnam+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsun $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getpwnam ();
+int
+main ()
+{
+return getpwnam ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_sun_getpwnam=yes
+else
+ ac_cv_lib_sun_getpwnam=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sun_getpwnam" >&5
+$as_echo "$ac_cv_lib_sun_getpwnam" >&6; }
+if test "x$ac_cv_lib_sun_getpwnam" = xyes; then :
+ LIBS="${LIBS} -lsun"
+fi
+
+ fi
+ # ":DEFAULT" must be appended to _RLD_LIST
+ RTLD_PRELOAD_VAR="_RLD_LIST"
+ RTLD_PRELOAD_DEFAULT="DEFAULT"
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-*-linux*|*-*-k*bsd*-gnu)
+ shadow_funcs="getspnam"
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ # Check for SECCOMP_SET_MODE_FILTER in linux/seccomp.h
+ ac_fn_c_check_decl "$LINENO" "SECCOMP_SET_MODE_FILTER" "ac_cv_have_decl_SECCOMP_SET_MODE_FILTER" "
+#include <sys/types.h>
+#include <sys/prctl.h>
+#include <asm/unistd.h>
+#include <linux/seccomp.h>
+#include <linux/filter.h>
+
+"
+if test "x$ac_cv_have_decl_SECCOMP_SET_MODE_FILTER" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SECCOMP_SET_MODE_FILTER $ac_have_decl
+_ACEOF
+
+ # We call getrandom via syscall(3) in case it is not in libc
+ for ac_header in linux/random.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "linux/random.h" "ac_cv_header_linux_random_h" "$ac_includes_default"
+if test "x$ac_cv_header_linux_random_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LINUX_RANDOM_H 1
+_ACEOF
+
+fi
+
+done
+
+ ;;
+ *-*-gnu*)
+ # lockf() is broken on the Hurd
+ ac_cv_func_lockf=no
+ ;;
+ *-*-riscos*)
+ LIBS="${LIBS} -lsun -lbsd"
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I/usr/include "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I/usr/include"; } >&5
+ (: CPPFLAGS already contains -I/usr/include) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I/usr/include"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I/usr/include
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I/usr/include/bsd "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I/usr/include/bsd"; } >&5
+ (: CPPFLAGS already contains -I/usr/include/bsd) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I/usr/include/bsd"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I/usr/include/bsd
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -D_MIPS "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -D_MIPS"; } >&5
+ (: CPPFLAGS already contains -D_MIPS) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -D_MIPS"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-D_MIPS
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-*-isc*)
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -D_ISC "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -D_ISC"; } >&5
+ (: CPPFLAGS already contains -D_ISC) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -D_ISC"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-D_ISC
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ LIB_CRYPT=1
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lcrypt"
+
+ shadow_funcs="getspnam"
+ shadow_libs="-lsec"
+
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-*-sco*|*-sco-*)
+ shadow_funcs="getprpwnam"
+ shadow_libs="-lprot -lx"
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ m88k-motorola-sysv*)
+ # motorolla's cc (a variant of gcc) does -O but not -O2
+ CFLAGS=`echo $CFLAGS | sed 's/-O2/-O/g'`
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-sequent-sysv*)
+ shadow_funcs="getspnam"
+ shadow_libs="-lsec"
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-ncr-sysv4*|*-ncr-sysvr4*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strcasecmp in -lc89" >&5
+$as_echo_n "checking for strcasecmp in -lc89... " >&6; }
+if ${ac_cv_lib_c89_strcasecmp+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc89 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char strcasecmp ();
+int
+main ()
+{
+return strcasecmp ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_c89_strcasecmp=yes
+else
+ ac_cv_lib_c89_strcasecmp=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c89_strcasecmp" >&5
+$as_echo "$ac_cv_lib_c89_strcasecmp" >&6; }
+if test "x$ac_cv_lib_c89_strcasecmp" = xyes; then :
+ LIBS="${LIBS} -lc89"
+fi
+
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-ccur-sysv4*|*-ccur-sysvr4*)
+ LIBS="${LIBS} -lgen"
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-*-bsdi*)
+ SKIP_SETREUID=yes
+ # Check for newer BSD auth API
+ if test -z "$with_bsdauth"; then
+ for ac_func in auth_challenge
+do :
+ ac_fn_c_check_func "$LINENO" "auth_challenge" "ac_cv_func_auth_challenge"
+if test "x$ac_cv_func_auth_challenge" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_AUTH_CHALLENGE 1
+_ACEOF
+ AUTH_EXCL_DEF="BSD_AUTH"
+fi
+done
+
+ fi
+ ;;
+ *-*-freebsd*)
+ $as_echo "#define _BSD_SOURCE 1" >>confdefs.h
+
+
+ # FreeBSD has a real setreuid(2) starting with 2.1 and
+ # backported to 2.0.5. We just take 2.1 and above...
+ case "$OSREV" in
+ 0.*|1.*|2.0*)
+ SKIP_SETREUID=yes
+ ;;
+ esac
+ if test "${with_skey-'no'}" = "yes"; then
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lmd"
+ fi
+ CHECKSHADOW="false"
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ : ${with_logincap='maybe'}
+
+ # Examples go in share/examples/sudo
+ if test X"$with_exampledir" = X""; then
+ exampledir='$(datarootdir)/examples/$(PACKAGE_TARNAME)'
+ fi
+ ;;
+ *-*-*openbsd*)
+ $as_echo "#define _BSD_SOURCE 1" >>confdefs.h
+
+
+ # OpenBSD-specific initialization
+ OS_INIT=os_init_openbsd
+ SUDO_OBJS="${SUDO_OBJS} openbsd.o"
+
+ # OpenBSD has a real setreuid(2) starting with 3.3 but
+ # we will use setresuid(2) instead.
+ SKIP_SETREUID=yes
+
+ # OpenBSD >= 3.0 supports BSD auth
+ if test -z "$with_bsdauth"; then
+ if test "$OSMAJOR" -ge 3; then
+ AUTH_EXCL_DEF="BSD_AUTH"
+ fi
+ fi
+ : ${with_logincap='maybe'}
+
+ # Newer OpenBSD only fills in pw_password for getpwnam_shadow()
+ shadow_funcs="getpwnam_shadow"
+
+ # Examples go in share/examples/sudo
+ if test X"$with_exampledir" = X""; then
+ exampledir='$(datarootdir)/examples/$(PACKAGE_TARNAME)'
+ fi
+ ;;
+ *-*-*netbsd*)
+ # NetBSD has a real setreuid(2) starting with 1.3.2
+ case "$OSREV" in
+ 0.9*|1.[012]*|1.3|1.3.1)
+ SKIP_SETREUID=yes
+ ;;
+ esac
+ CHECKSHADOW="false"
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ : ${with_logincap='maybe'}
+
+ # Examples go in share/examples/sudo
+ if test X"$with_exampledir" = X""; then
+ exampledir='$(datarootdir)/examples/$(PACKAGE_TARNAME)'
+ fi
+ ;;
+ *-*-dragonfly*)
+ $as_echo "#define _BSD_SOURCE 1" >>confdefs.h
+
+
+ if test "${with_skey-'no'}" = "yes"; then
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lmd"
+ fi
+ CHECKSHADOW="false"
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ : ${with_logincap='yes'}
+
+ # Examples go in share/examples/sudo
+ if test X"$with_exampledir" = X""; then
+ exampledir='$(datarootdir)/examples/$(PACKAGE_TARNAME)'
+ fi
+ ;;
+ *-*-*bsd*)
+ CHECKSHADOW="false"
+ # Examples go in share/examples/sudo
+ if test X"$with_exampledir" = X""; then
+ exampledir='$(datarootdir)/examples/$(PACKAGE_TARNAME)'
+ fi
+ ;;
+ *-*-darwin*)
+ # Darwin has a real setreuid(2) starting with 9.0
+ if test $OSMAJOR -lt 9; then
+ SKIP_SETREUID=yes
+ fi
+ CHECKSHADOW="false"
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ : ${with_logincap='yes'}
+ # Darwin has a broken poll()
+ : ${enable_poll='no'}
+ # Darwin 8 and above can interpose library symbols cleanly
+ if test $OSMAJOR -ge 8; then
+ $as_echo "#define HAVE___INTERPOSE 1" >>confdefs.h
+
+ dlyld_interpose=yes
+ else
+ RTLD_PRELOAD_ENABLE_VAR="DYLD_FORCE_FLAT_NAMESPACE"
+ fi
+ RTLD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES"
+
+ # Mach monotonic timer that runs while sleeping
+ for ac_func in mach_continuous_time
+do :
+ ac_fn_c_check_func "$LINENO" "mach_continuous_time" "ac_cv_func_mach_continuous_time"
+if test "x$ac_cv_func_mach_continuous_time" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_MACH_CONTINUOUS_TIME 1
+_ACEOF
+
+fi
+done
+
+
+ # Undocumented API that dynamically allocates the groups.
+ for ac_func in getgrouplist_2
+do :
+ ac_fn_c_check_func "$LINENO" "getgrouplist_2" "ac_cv_func_getgrouplist_2"
+if test "x$ac_cv_func_getgrouplist_2" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETGROUPLIST_2 1
+_ACEOF
+ ac_fn_c_check_decl "$LINENO" "getgrouplist_2" "ac_cv_have_decl_getgrouplist_2" "$ac_includes_default"
+if test "x$ac_cv_have_decl_getgrouplist_2" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_GETGROUPLIST_2 $ac_have_decl
+_ACEOF
+
+fi
+done
+
+
+ # We need to force a flat namespace to make libc
+ # symbol hooking work like it does on ELF.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,-force_flat_namespace" >&5
+$as_echo_n "checking whether the linker accepts -Wl,-force_flat_namespace... " >&6; }
+if ${ax_cv_check_ldflags___Wl__force_flat_namespace+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-force_flat_namespace"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_cv_check_ldflags___Wl__force_flat_namespace=yes
+else
+ ax_cv_check_ldflags___Wl__force_flat_namespace=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl__force_flat_namespace" >&5
+$as_echo "$ax_cv_check_ldflags___Wl__force_flat_namespace" >&6; }
+if test x"$ax_cv_check_ldflags___Wl__force_flat_namespace" = xyes; then :
+
+if ${SUDO_LDFLAGS+:} false; then :
+
+ case " $SUDO_LDFLAGS " in #(
+ *" -Wl,-force_flat_namespace "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDO_LDFLAGS already contains -Wl,-force_flat_namespace"; } >&5
+ (: SUDO_LDFLAGS already contains -Wl,-force_flat_namespace) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDO_LDFLAGS " -Wl,-force_flat_namespace"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDO_LDFLAGS=\"\$SUDO_LDFLAGS\""; } >&5
+ (: SUDO_LDFLAGS="$SUDO_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDO_LDFLAGS=-Wl,-force_flat_namespace
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDO_LDFLAGS=\"\$SUDO_LDFLAGS\""; } >&5
+ (: SUDO_LDFLAGS="$SUDO_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+else
+ :
+fi
+
+
+ # Examples go in share/examples/sudo
+ if test X"$with_exampledir" = X""; then
+ exampledir='$(datarootdir)/examples/$(PACKAGE_TARNAME)'
+ fi
+ ;;
+ *-*-nextstep*)
+ # lockf() is broken on the NeXT
+ ac_cv_func_lockf=no
+ RTLD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES"
+ RTLD_PRELOAD_ENABLE_VAR="DYLD_FORCE_FLAT_NAMESPACE"
+ ;;
+ *-*-*sysv4*)
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-*-sysv*)
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+esac
+
+if test X"$enable_pvs_studio" = X"yes"; then
+ # Determine preprocessor type
+ case "$CC" in
+ *clang*) preprocessor=clang;;
+ *gcc*) preprocessor=gcc;;
+ *)
+ case `$CC --version 2>&1` in
+ *clang*) preprocessor=clang;;
+ *gcc*) preprocessor=gcc;;
+ *) as_fn_error $? "Compiler must be gcc or clang for PVS-Studio." "$LINENO" 5;;
+ esac
+ ;;
+ esac
+
+ # Determine platform (currently linux or macos)
+ case "$host" in
+ x86_64-*-linux*) pvs_platform=linux64;;
+ *86-*-linux*) pvs_platform=linux32;;
+ darwin*) pvs_platform=macos;;
+ *) as_fn_error $? "PVS-Studio does not support $host_os." "$LINENO" 5;;
+ esac
+
+ # create basic PVS-Studio.cfg file
+ cat > PVS-Studio.cfg <<-EOF
+ preprocessor = $preprocessor
+ platform = $pvs_platform
+ analysis-mode = 4
+ language = C
+EOF
+fi
+
+if test -n "$with_noexec"; then
+ cat >>confdefs.h <<EOF
+#define RTLD_PRELOAD_VAR "$RTLD_PRELOAD_VAR"
+EOF
+
+ cat >>confdefs.h <<EOF
+#define RTLD_PRELOAD_DELIM "$RTLD_PRELOAD_DELIM"
+EOF
+
+ if test -n "$RTLD_PRELOAD_DEFAULT"; then
+ cat >>confdefs.h <<EOF
+#define RTLD_PRELOAD_DEFAULT "$RTLD_PRELOAD_DEFAULT"
+EOF
+
+ fi
+ if test -n "$RTLD_PRELOAD_ENABLE_VAR"; then
+ cat >>confdefs.h <<EOF
+#define RTLD_PRELOAD_ENABLE_VAR "$RTLD_PRELOAD_ENABLE_VAR"
+EOF
+
+ fi
+fi
+
+AUTH_REG=${AUTH_REG# }
+AUTH_EXCL=${AUTH_EXCL# }
+if test -n "$AUTH_EXCL"; then
+ if test -n "$AUTH_REG"; then
+ as_fn_error $? "Cannot mix mutually exclusive ($AUTH_EXCL) and regular ($AUTH_REG) authentication methods" "$LINENO" 5
+ fi
+fi
+if test X"${with_skey}${with_opie}" = X"yesyes"; then
+ as_fn_error $? "\"cannot use both S/Key and OPIE\"" "$LINENO" 5
+fi
+
+: ${mansectsu='8'}
+: ${mansectform='5'}
+
+if test -n "$with_libpath"; then
+ for i in ${with_libpath}; do
+
+
+if ${LDFLAGS+:} false; then :
+
+ case " $LDFLAGS " in #(
+ *" -L$i "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains -L\$i"; } >&5
+ (: LDFLAGS already contains -L$i) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append LDFLAGS " -L$i"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS\""; } >&5
+ (: LDFLAGS="$LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ LDFLAGS=-L$i
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS\""; } >&5
+ (: LDFLAGS="$LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${LDFLAGS_R+:} false; then :
+
+ case " $LDFLAGS_R " in #(
+ *" -R$i "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS_R already contains -R\$i"; } >&5
+ (: LDFLAGS_R already contains -R$i) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append LDFLAGS_R " -R$i"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS_R=\"\$LDFLAGS_R\""; } >&5
+ (: LDFLAGS_R="$LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ LDFLAGS_R=-R$i
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS_R=\"\$LDFLAGS_R\""; } >&5
+ (: LDFLAGS_R="$LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+ done
+fi
+if test -n "$with_libraries"; then
+ for i in ${with_libraries}; do
+ case $i in
+ -l*) ;;
+ *.a) ;;
+ *.o) ;;
+ *) i="-l${i}";;
+ esac
+ LIBS="${LIBS} ${i}"
+ done
+fi
+
+ case $ac_cv_prog_cc_stdc in #(
+ no) :
+ ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #(
+ *) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
+$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
+if ${ac_cv_prog_cc_c99+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+
+// Check varargs macros. These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+ int x = 1234;
+ int y = 5678;
+ debug ("Flag");
+ debug ("X = %d\n", x);
+ showlist (The first, second, and third items.);
+ report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+ your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+ your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+ int datasize;
+ double data[];
+};
+
+struct named_init {
+ int number;
+ const wchar_t *name;
+ double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+ // See if C++-style comments work.
+ // Iterate through items via the restricted pointer.
+ // Also check for declarations in for loops.
+ for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+ continue;
+ return 0;
+}
+
+// Check varargs and va_copy.
+static void
+test_varargs (const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ va_list args_copy;
+ va_copy (args_copy, args);
+
+ const char *str;
+ int number;
+ float fnumber;
+
+ while (*format)
+ {
+ switch (*format++)
+ {
+ case 's': // string
+ str = va_arg (args_copy, const char *);
+ break;
+ case 'd': // int
+ number = va_arg (args_copy, int);
+ break;
+ case 'f': // float
+ fnumber = va_arg (args_copy, double);
+ break;
+ default:
+ break;
+ }
+ }
+ va_end (args_copy);
+ va_end (args);
+}
+
+int
+main ()
+{
+
+ // Check bool.
+ _Bool success = false;
+
+ // Check restrict.
+ if (test_restrict ("String literal") == 0)
+ success = true;
+ char *restrict newvar = "Another string";
+
+ // Check varargs.
+ test_varargs ("s, d' f .", "string", 65, 34.234);
+ test_varargs_macros ();
+
+ // Check flexible array members.
+ struct incomplete_array *ia =
+ malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+ ia->datasize = 10;
+ for (int i = 0; i < ia->datasize; ++i)
+ ia->data[i] = i * 1.234;
+
+ // Check named initializers.
+ struct named_init ni = {
+ .number = 34,
+ .name = L"Test wide string",
+ .average = 543.34343,
+ };
+
+ ni.number = 58;
+
+ int dynamic_array[ni.number];
+ dynamic_array[ni.number - 1] = 543;
+
+ // work around unused variable warnings
+ return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+ || dynamic_array[ni.number - 1] != 543);
+
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c99" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c99"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c99" != xno; then :
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+else
+ ac_cv_prog_cc_stdc=no
+fi
+
+fi
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5
+$as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; }
+ if ${ac_cv_prog_cc_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+
+ case $ac_cv_prog_cc_stdc in #(
+ no) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;; #(
+ '') :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;; #(
+ *) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5
+$as_echo "$ac_cv_prog_cc_stdc" >&6; } ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this sort of thing. */
+ typedef int charset[2];
+ const charset cs = { 0, 0 };
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *pcpcc;
+ char **ppc;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ pcpcc = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++pcpcc;
+ ppc = (char**) pcpcc;
+ pcpcc = (char const *const *) ppc;
+ { /* SCO 3.2v4 cc rejects this sort of thing. */
+ char tx;
+ char *t = &tx;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ if (s) return 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; } bx;
+ struct s *b = &bx; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ if (!foo) return 0;
+ }
+ return !cs[0] && !zero.x;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_const=yes
+else
+ ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5
+$as_echo_n "checking for working volatile... " >&6; }
+if ${ac_cv_c_volatile+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+volatile int x;
+int * volatile y = (int *) 0;
+return !x && !y;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_volatile=yes
+else
+ ac_cv_c_volatile=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5
+$as_echo "$ac_cv_c_volatile" >&6; }
+if test $ac_cv_c_volatile = no; then
+
+$as_echo "#define volatile /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for variadic macro support in cpp" >&5
+$as_echo_n "checking for variadic macro support in cpp... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+$ac_includes_default
+#if defined(__GNUC__) && __GNUC__ == 2
+# define sudo_fprintf(fp, fmt...) fprintf((fp), (fmt))
+#else
+# define sudo_fprintf(fp, ...) fprintf((fp), __VA_ARGS__)
+#endif
+
+int
+main ()
+{
+sudo_fprintf(stderr, "a %s", "test");
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define NO_VARIADIC_MACROS 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Your C preprocessor doesn't support variadic macros, debugging support will be limited" >&5
+$as_echo "$as_me: WARNING: Your C preprocessor doesn't support variadic macros, debugging support will be limited" >&2;}
+
+ for _sym in sudo_debug_printf_nvm_v1; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+for ac_prog in 'bison -y' byacc
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_YACC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_YACC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5
+$as_echo "$YACC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_FLEX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $FLEX in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_FLEX="$FLEX" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_FLEX="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_FLEX" && ac_cv_path_FLEX="flex"
+ ;;
+esac
+fi
+FLEX=$ac_cv_path_FLEX
+if test -n "$FLEX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FLEX" >&5
+$as_echo "$FLEX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+ # Extract the first word of "mv", so it can be a program name with args.
+set dummy mv; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MVPROG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MVPROG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MVPROG="$MVPROG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /usr/bin$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/ucb$PATH_SEPARATOR/usr/local/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MVPROG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MVPROG=$ac_cv_path_MVPROG
+if test -n "$MVPROG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MVPROG" >&5
+$as_echo "$MVPROG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "${ac_cv_path_MVPROG}" && cat >>confdefs.h <<EOF
+#define _PATH_MV "${ac_cv_path_MVPROG}"
+EOF
+
+
+
+ # Extract the first word of "sh", so it can be a program name with args.
+set dummy sh; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_BSHELLPROG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $BSHELLPROG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_BSHELLPROG="$BSHELLPROG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_BSHELLPROG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_BSHELLPROG" && ac_cv_path_BSHELLPROG="/usr/bin$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin"
+ ;;
+esac
+fi
+BSHELLPROG=$ac_cv_path_BSHELLPROG
+if test -n "$BSHELLPROG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BSHELLPROG" >&5
+$as_echo "$BSHELLPROG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "${ac_cv_path_BSHELLPROG}" && cat >>confdefs.h <<EOF
+#define _PATH_BSHELL "${ac_cv_path_BSHELLPROG}"
+EOF
+
+
+if test -z "$with_sendmail"; then
+
+ # Extract the first word of "sendmail", so it can be a program name with args.
+set dummy sendmail; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_SENDMAILPROG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $SENDMAILPROG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_SENDMAILPROG="$SENDMAILPROG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /usr/sbin$PATH_SEPARATOR/usr/lib$PATH_SEPARATOR/usr/etc$PATH_SEPARATOR/usr/ucblib$PATH_SEPARATOR/usr/local/lib$PATH_SEPARATOR/usr/local/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_SENDMAILPROG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+SENDMAILPROG=$ac_cv_path_SENDMAILPROG
+if test -n "$SENDMAILPROG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SENDMAILPROG" >&5
+$as_echo "$SENDMAILPROG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "${ac_cv_path_SENDMAILPROG}" && cat >>confdefs.h <<EOF
+#define _PATH_SUDO_SENDMAIL "${ac_cv_path_SENDMAILPROG}"
+EOF
+
+
+fi
+
+ # Extract the first word of "vi", so it can be a program name with args.
+set dummy vi; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_VIPROG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $VIPROG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_VIPROG="$VIPROG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /usr/bin$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/ucb$PATH_SEPARATOR/usr/bsd$PATH_SEPARATOR/usr/local/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_VIPROG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+VIPROG=$ac_cv_path_VIPROG
+if test -n "$VIPROG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $VIPROG" >&5
+$as_echo "$VIPROG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "${ac_cv_path_VIPROG}" && cat >>confdefs.h <<EOF
+#define _PATH_VI "${ac_cv_path_VIPROG}"
+EOF
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which syslog facility sudo should log with" >&5
+$as_echo_n "checking which syslog facility sudo should log with... " >&6; }
+if test X"$with_logfac" = X""; then
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <syslog.h>
+int
+main ()
+{
+int i = LOG_AUTHPRIV; (void)i;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ logfac=authpriv
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define LOGFAC "$logfac"
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $logfac" >&5
+$as_echo "$logfac" >&6; }
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+ as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if eval \${$as_ac_Header+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$as_ac_Header=yes"
+else
+ eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' dir; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_opendir+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' x; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_opendir+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
+$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
+if ${ac_cv_header_stdbool_h+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <stdbool.h>
+ #ifndef bool
+ "error: bool is not defined"
+ #endif
+ #ifndef false
+ "error: false is not defined"
+ #endif
+ #if false
+ "error: false is not 0"
+ #endif
+ #ifndef true
+ "error: true is not defined"
+ #endif
+ #if true != 1
+ "error: true is not 1"
+ #endif
+ #ifndef __bool_true_false_are_defined
+ "error: __bool_true_false_are_defined is not defined"
+ #endif
+
+ struct s { _Bool s: 1; _Bool t; } s;
+
+ char a[true == 1 ? 1 : -1];
+ char b[false == 0 ? 1 : -1];
+ char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+ char d[(bool) 0.5 == true ? 1 : -1];
+ /* See body of main program for 'e'. */
+ char f[(_Bool) 0.0 == false ? 1 : -1];
+ char g[true];
+ char h[sizeof (_Bool)];
+ char i[sizeof s.t];
+ enum { j = false, k = true, l = false * true, m = true * 256 };
+ /* The following fails for
+ HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
+ _Bool n[m];
+ char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+ char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+ /* Catch a bug in an HP-UX C compiler. See
+ http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+ http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+ */
+ _Bool q = true;
+ _Bool *pq = &q;
+
+int
+main ()
+{
+
+ bool e = &s;
+ *pq |= q;
+ *pq |= ! q;
+ /* Refer to every declared value, to avoid compiler optimizations. */
+ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
+ + !m + !n + !o + !p + !q + !pq);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdbool_h=yes
+else
+ ac_cv_header_stdbool_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
+$as_echo "$ac_cv_header_stdbool_h" >&6; }
+ ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
+if test "x$ac_cv_type__Bool" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE__BOOL 1
+_ACEOF
+
+
+fi
+
+
+if test $ac_cv_header_stdbool_h = yes; then
+
+$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
+
+fi
+
+
+
+
+ for ac_header in $ac_header_list
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/mkdev.h" "ac_cv_header_sys_mkdev_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_mkdev_h" = xyes; then :
+
+$as_echo "#define MAJOR_IN_MKDEV 1" >>confdefs.h
+
+fi
+
+
+if test $ac_cv_header_sys_mkdev_h = no; then
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/sysmacros.h" "ac_cv_header_sys_sysmacros_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_sysmacros_h" = xyes; then :
+
+$as_echo "#define MAJOR_IN_SYSMACROS 1" >>confdefs.h
+
+fi
+
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_header in utmps.h utmpx.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+
+done
+
+for ac_header in endian.h sys/endian.h machine/endian.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+
+done
+
+for ac_header in procfs.h sys/procfs.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ ac_fn_c_check_member "$LINENO" "struct psinfo" "pr_ttydev" "ac_cv_member_struct_psinfo_pr_ttydev" "$ac_includes_default
+#ifdef HAVE_PROCFS_H
+#include <procfs.h>
+#endif
+#ifdef HAVE_SYS_PROCFS_H
+#include <sys/procfs.h>
+#endif
+
+"
+if test "x$ac_cv_member_struct_psinfo_pr_ttydev" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_PSINFO_PR_TTYDEV 1
+_ACEOF
+
+for ac_func in _ttyname_dev
+do :
+ ac_fn_c_check_func "$LINENO" "_ttyname_dev" "ac_cv_func__ttyname_dev"
+if test "x$ac_cv_func__ttyname_dev" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__TTYNAME_DEV 1
+_ACEOF
+
+fi
+done
+
+fi
+
+break
+fi
+
+done
+
+#
+# Check for large file support.
+#
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then :
+ enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ ac_save_CC=$CC
+ while :; do
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_largefile_CC=' -n32'; break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+$as_echo "$ac_cv_sys_largefile_CC" >&6; }
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if ${ac_cv_sys_file_offset_bits+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=64; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_file_offset_bits=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ if test $ac_cv_sys_file_offset_bits = unknown; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
+if ${ac_cv_sys_large_files+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_large_files=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+$as_echo "$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ fi
+
+
+fi
+
+#
+# HP-UX may need to define _XOPEN_SOURCE_EXTENDED to expose MSG_WAITALL.
+# Also, HP-UX 11.23 has a broken sys/types.h when large files support
+# is enabled and _XOPEN_SOURCE_EXTENDED is not also defined.
+# The following test will define _XOPEN_SOURCE_EXTENDED in either case.
+#
+case "$host_os" in
+ hpux*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sys/socket.h needs _XOPEN_SOURCE_EXTENDED for MSG_WAITALL" >&5
+$as_echo_n "checking whether sys/socket.h needs _XOPEN_SOURCE_EXTENDED for MSG_WAITALL... " >&6; }
+if ${sudo_cv_xopen_source_extended+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+# include <sys/socket.h>
+int
+main ()
+{
+int a = MSG_WAITALL; return a;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ sudo_cv_xopen_source_extended=no
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _XOPEN_SOURCE_EXTENDED
+ $ac_includes_default
+# include <sys/socket.h>
+# include <net/if.h>
+int
+main ()
+{
+int a = MSG_WAITALL; return a;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ sudo_cv_xopen_source_extended=yes
+else
+ sudo_cv_xopen_source_extended=error
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_xopen_source_extended" >&5
+$as_echo "$sudo_cv_xopen_source_extended" >&6; }
+ if test "$sudo_cv_xopen_source_extended" = "yes"; then
+ $as_echo "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h
+
+ fi
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking POSIX termios" >&5
+$as_echo_n "checking POSIX termios... " >&6; }
+if ${ac_cv_sys_posix_termios+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <unistd.h>
+#include <termios.h>
+
+int
+main ()
+{
+/* SunOS 4.0.3 has termios.h but not the library calls. */
+ tcgetattr(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_sys_posix_termios=yes
+else
+ ac_cv_sys_posix_termios=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_posix_termios" >&5
+$as_echo "$ac_cv_sys_posix_termios" >&6; }
+
+if test "$ac_cv_sys_posix_termios" != "yes"; then
+ as_fn_error $? "Must have POSIX termios to build sudo" "$LINENO" 5
+fi
+
+maildir=no
+if test X"$ac_cv_header_paths_h" = X"yes"; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+#include <paths.h>
+int
+main ()
+{
+char *p = _PATH_MAILDIR;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ maildir=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+if test $maildir = no; then
+ # Solaris has maillock.h which defines MAILDIR
+ for ac_header in maillock.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "maillock.h" "ac_cv_header_maillock_h" "$ac_includes_default"
+if test "x$ac_cv_header_maillock_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_MAILLOCK_H 1
+_ACEOF
+
+ cat >>confdefs.h <<\EOF
+#define _PATH_MAILDIR MAILDIR
+EOF
+
+ maildir=yes
+
+fi
+
+done
+
+ if test $maildir = no; then
+ for d in /var/mail /var/spool/mail /usr/spool/mail; do
+ if test -d "$d"; then
+ maildir=yes
+ cat >>confdefs.h <<EOF
+#define _PATH_MAILDIR "$d"
+EOF
+
+ break
+ fi
+ done
+ if test $maildir = no; then
+ # unable to find mail dir, hope for the best
+ cat >>confdefs.h <<EOF
+#define _PATH_MAILDIR "/var/mail"
+EOF
+
+ fi
+ fi
+fi
+
+if test ${with_logincap-'no'} != "no"; then
+ for ac_header in login_cap.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "login_cap.h" "ac_cv_header_login_cap_h" "$ac_includes_default"
+if test "x$ac_cv_header_login_cap_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LOGIN_CAP_H 1
+_ACEOF
+ LOGINCAP_USAGE='[-c class] '; LCMAN=1
+ case "$OS" in
+ freebsd|netbsd)
+ SUDO_LIBS="${SUDO_LIBS} -lutil"
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lutil"
+ ;;
+ esac
+
+fi
+
+done
+
+fi
+if test ${with_project-'no'} != "no"; then
+ ac_fn_c_check_header_mongrel "$LINENO" "project.h" "ac_cv_header_project_h" "$ac_includes_default"
+if test "x$ac_cv_header_project_h" = xyes; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setproject in -lproject" >&5
+$as_echo_n "checking for setproject in -lproject... " >&6; }
+if ${ac_cv_lib_project_setproject+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lproject $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setproject ();
+int
+main ()
+{
+return setproject ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_project_setproject=yes
+else
+ ac_cv_lib_project_setproject=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_project_setproject" >&5
+$as_echo "$ac_cv_lib_project_setproject" >&6; }
+if test "x$ac_cv_lib_project_setproject" = xyes; then :
+
+ $as_echo "#define HAVE_PROJECT_H 1" >>confdefs.h
+
+ SUDO_LIBS="${SUDO_LIBS} -lproject"
+
+fi
+
+
+fi
+
+
+fi
+$as_echo "#define __STDC_WANT_LIB_EXT1__ 1" >>confdefs.h
+
+ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
+if test "x$ac_cv_type_mode_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define mode_t int
+_ACEOF
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
+$as_echo_n "checking for uid_t in sys/types.h... " >&6; }
+if ${ac_cv_type_uid_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "uid_t" >/dev/null 2>&1; then :
+ ac_cv_type_uid_t=yes
+else
+ ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
+$as_echo "$ac_cv_type_uid_t" >&6; }
+if test $ac_cv_type_uid_t = no; then
+
+$as_echo "#define uid_t int" >>confdefs.h
+
+
+$as_echo "#define gid_t int" >>confdefs.h
+
+fi
+
+ac_fn_c_check_type "$LINENO" "clockid_t" "ac_cv_type_clockid_t" "#include <sys/types.h>
+#include <time.h>
+"
+if test "x$ac_cv_type_clockid_t" = xyes; then :
+
+else
+ $as_echo "#define clockid_t int" >>confdefs.h
+
+fi
+
+ac_fn_c_check_type "$LINENO" "sig_atomic_t" "ac_cv_type_sig_atomic_t" "#include <sys/types.h>
+#include <signal.h>
+"
+if test "x$ac_cv_type_sig_atomic_t" = xyes; then :
+
+else
+ $as_echo "#define sig_atomic_t int" >>confdefs.h
+
+fi
+
+ac_fn_c_check_type "$LINENO" "struct in6_addr" "ac_cv_type_struct_in6_addr" "#include <sys/types.h>
+#include <netinet/in.h>
+"
+if test "x$ac_cv_type_struct_in6_addr" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_IN6_ADDR 1
+_ACEOF
+
+
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5
+$as_echo_n "checking for unsigned long long int... " >&6; }
+if ${ac_cv_type_unsigned_long_long_int+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_type_unsigned_long_long_int=yes
+ if test "x${ac_cv_prog_cc_c99-no}" = xno; then
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ /* For now, do not test the preprocessor; as of 2007 there are too many
+ implementations with broken preprocessors. Perhaps this can
+ be revisited in 2012. In the meantime, code should not expect
+ #if to work with literals wider than 32 bits. */
+ /* Test literals. */
+ long long int ll = 9223372036854775807ll;
+ long long int nll = -9223372036854775807LL;
+ unsigned long long int ull = 18446744073709551615ULL;
+ /* Test constant expressions. */
+ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+ ? 1 : -1)];
+ typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+ ? 1 : -1)];
+ int i = 63;
+int
+main ()
+{
+/* Test availability of runtime routines for shift and division. */
+ long long int llmax = 9223372036854775807ll;
+ unsigned long long int ullmax = 18446744073709551615ull;
+ return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+ | (llmax / ll) | (llmax % ll)
+ | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+ | (ullmax / ull) | (ullmax % ull));
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+ ac_cv_type_unsigned_long_long_int=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5
+$as_echo "$ac_cv_type_unsigned_long_long_int" >&6; }
+ if test $ac_cv_type_unsigned_long_long_int = yes; then
+
+$as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h
+
+ fi
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5
+$as_echo_n "checking for long long int... " >&6; }
+if ${ac_cv_type_long_long_int+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_type_long_long_int=yes
+ if test "x${ac_cv_prog_cc_c99-no}" = xno; then
+ ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int
+ if test $ac_cv_type_long_long_int = yes; then
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+ #ifndef LLONG_MAX
+ # define HALF \
+ (1LL << (sizeof (long long int) * CHAR_BIT - 2))
+ # define LLONG_MAX (HALF - 1 + HALF)
+ #endif
+int
+main ()
+{
+long long int n = 1;
+ int i;
+ for (i = 0; ; i++)
+ {
+ long long int m = n << i;
+ if (m >> i != n)
+ return 1;
+ if (LLONG_MAX / 2 < m)
+ break;
+ }
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_type_long_long_int=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5
+$as_echo "$ac_cv_type_long_long_int" >&6; }
+ if test $ac_cv_type_long_long_int = yes; then
+
+$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h
+
+ fi
+
+if test X"$ac_cv_type_long_long_int" != X"yes"; then
+ as_fn_error $? "\"C compiler does not appear to support the long long int type\"" "$LINENO" 5
+fi
+ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" "$ac_includes_default"
+if test "x$ac_cv_type_intmax_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define intmax_t long long
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default"
+if test "x$ac_cv_type_uintmax_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define uintmax_t unsigned long long
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "$ac_includes_default"
+if test "x$ac_cv_type_uint8_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define uint8_t unsigned char
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "$ac_includes_default"
+if test "x$ac_cv_type_uint32_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define uint32_t unsigned int
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "$ac_includes_default"
+if test "x$ac_cv_type_uint64_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define uint64_t unsigned long long
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "
+$ac_includes_default
+#include <sys/socket.h>
+"
+if test "x$ac_cv_type_socklen_t" = xyes; then :
+
+else
+ $as_echo "#define socklen_t unsigned int" >>confdefs.h
+
+fi
+
+ac_fn_c_check_type "$LINENO" "rsize_t" "ac_cv_type_rsize_t" "$ac_includes_default"
+if test "x$ac_cv_type_rsize_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define rsize_t size_t
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "errno_t" "ac_cv_type_errno_t" "$ac_includes_default"
+if test "x$ac_cv_type_errno_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define errno_t int
+_ACEOF
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking max length of uid_t" >&5
+$as_echo_n "checking max length of uid_t... " >&6; }
+if ${sudo_cv_uid_t_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f conftestdata
+if test "$cross_compiling" = yes; then :
+ sudo_cv_uid_t_len=10
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <pwd.h>
+#include <limits.h>
+#include <sys/types.h>
+main() {
+ FILE *f;
+ char b[1024];
+ uid_t u = (uid_t) -1;
+
+ if ((f = fopen("conftestdata", "w")) == NULL)
+ exit(1);
+
+ (void) sprintf(b, "%lu", (unsigned long) u);
+ (void) fprintf(f, "%d\n", strlen(b));
+ (void) fclose(f);
+ exit(0);
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ sudo_cv_uid_t_len=`cat conftestdata`
+else
+ sudo_cv_uid_t_len=10
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+
+rm -f conftestdata
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_uid_t_len" >&5
+$as_echo "$sudo_cv_uid_t_len" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define MAX_UID_T_LEN $sudo_cv_uid_t_len
+_ACEOF
+
+
+
+ ac_fn_c_check_member "$LINENO" "struct sockaddr" "sa_len" "ac_cv_member_struct_sockaddr_sa_len" "
+# include <sys/types.h>
+# include <sys/socket.h>
+
+"
+if test "x$ac_cv_member_struct_sockaddr_sa_len" = xyes; then :
+
+$as_echo "#define HAVE_STRUCT_SOCKADDR_SA_LEN 1" >>confdefs.h
+
+fi
+
+
+
+ ac_fn_c_check_member "$LINENO" "struct sockaddr_in" "sin_len" "ac_cv_member_struct_sockaddr_in_sin_len" "
+# include <sys/types.h>
+# include <sys/socket.h>
+
+"
+if test "x$ac_cv_member_struct_sockaddr_in_sin_len" = xyes; then :
+
+$as_echo "#define HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 1" >>confdefs.h
+
+fi
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of id_t" >&5
+$as_echo_n "checking size of id_t... " >&6; }
+if ${ac_cv_sizeof_id_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (id_t))" "ac_cv_sizeof_id_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_id_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (id_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_id_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_id_t" >&5
+$as_echo "$ac_cv_sizeof_id_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_ID_T $ac_cv_sizeof_id_t
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if ${ac_cv_sizeof_long_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5
+$as_echo_n "checking size of time_t... " >&6; }
+if ${ac_cv_sizeof_time_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_time_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (time_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_time_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5
+$as_echo "$ac_cv_sizeof_time_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_TIME_T $ac_cv_sizeof_time_t
+_ACEOF
+
+
+if test $ac_cv_header_utmps_h = "yes"; then
+
+ ac_fn_c_check_member "$LINENO" "struct utmps" "ut_id" "ac_cv_member_struct_utmps_ut_id" "
+# include <sys/types.h>
+# include <utmps.h>
+
+"
+if test "x$ac_cv_member_struct_utmps_ut_id" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_ID 1" >>confdefs.h
+
+
+fi
+
+ ac_fn_c_check_member "$LINENO" "struct utmps" "ut_pid" "ac_cv_member_struct_utmps_ut_pid" "
+# include <sys/types.h>
+# include <utmps.h>
+
+"
+if test "x$ac_cv_member_struct_utmps_ut_pid" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_PID 1" >>confdefs.h
+
+
+fi
+
+ ac_fn_c_check_member "$LINENO" "struct utmps" "ut_tv" "ac_cv_member_struct_utmps_ut_tv" "
+# include <sys/types.h>
+# include <utmps.h>
+
+"
+if test "x$ac_cv_member_struct_utmps_ut_tv" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_TV 1" >>confdefs.h
+
+
+fi
+
+ ac_fn_c_check_member "$LINENO" "struct utmps" "ut_type" "ac_cv_member_struct_utmps_ut_type" "
+# include <sys/types.h>
+# include <utmps.h>
+
+"
+if test "x$ac_cv_member_struct_utmps_ut_type" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_TYPE 1" >>confdefs.h
+
+
+fi
+
+ if test "utmps" = "utmp"; then
+ ac_fn_c_check_member "$LINENO" "struct utmp" "ut_user" "ac_cv_member_struct_utmp_ut_user" "
+# include <sys/types.h>
+# include <utmps.h>
+
+"
+if test "x$ac_cv_member_struct_utmp_ut_user" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_UTMP_UT_USER 1
+_ACEOF
+
+
+fi
+
+ fi
+ ac_fn_c_check_member "$LINENO" "struct utmps" "ut_exit.__e_termination" "ac_cv_member_struct_utmps_ut_exit___e_termination" "
+# include <sys/types.h>
+# include <utmps.h>
+
+"
+if test "x$ac_cv_member_struct_utmps_ut_exit___e_termination" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT___E_TERMINATION 1" >>confdefs.h
+
+
+else
+
+ ac_fn_c_check_member "$LINENO" "struct utmps" "ut_exit.e_termination" "ac_cv_member_struct_utmps_ut_exit_e_termination" "
+# include <sys/types.h>
+# include <utmps.h>
+
+"
+if test "x$ac_cv_member_struct_utmps_ut_exit_e_termination" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+elif test $ac_cv_header_utmpx_h = "yes"; then
+
+ ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_id" "ac_cv_member_struct_utmpx_ut_id" "
+# include <sys/types.h>
+# include <utmpx.h>
+
+"
+if test "x$ac_cv_member_struct_utmpx_ut_id" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_ID 1" >>confdefs.h
+
+
+fi
+
+ ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_pid" "ac_cv_member_struct_utmpx_ut_pid" "
+# include <sys/types.h>
+# include <utmpx.h>
+
+"
+if test "x$ac_cv_member_struct_utmpx_ut_pid" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_PID 1" >>confdefs.h
+
+
+fi
+
+ ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_tv" "ac_cv_member_struct_utmpx_ut_tv" "
+# include <sys/types.h>
+# include <utmpx.h>
+
+"
+if test "x$ac_cv_member_struct_utmpx_ut_tv" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_TV 1" >>confdefs.h
+
+
+fi
+
+ ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_type" "ac_cv_member_struct_utmpx_ut_type" "
+# include <sys/types.h>
+# include <utmpx.h>
+
+"
+if test "x$ac_cv_member_struct_utmpx_ut_type" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_TYPE 1" >>confdefs.h
+
+
+fi
+
+ if test "utmpx" = "utmp"; then
+ ac_fn_c_check_member "$LINENO" "struct utmp" "ut_user" "ac_cv_member_struct_utmp_ut_user" "
+# include <sys/types.h>
+# include <utmpx.h>
+
+"
+if test "x$ac_cv_member_struct_utmp_ut_user" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_UTMP_UT_USER 1
+_ACEOF
+
+
+fi
+
+ fi
+ ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_exit.__e_termination" "ac_cv_member_struct_utmpx_ut_exit___e_termination" "
+# include <sys/types.h>
+# include <utmpx.h>
+
+"
+if test "x$ac_cv_member_struct_utmpx_ut_exit___e_termination" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT___E_TERMINATION 1" >>confdefs.h
+
+
+else
+
+ ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_exit.e_termination" "ac_cv_member_struct_utmpx_ut_exit_e_termination" "
+# include <sys/types.h>
+# include <utmpx.h>
+
+"
+if test "x$ac_cv_member_struct_utmpx_ut_exit_e_termination" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+else
+
+ ac_fn_c_check_member "$LINENO" "struct utmp" "ut_id" "ac_cv_member_struct_utmp_ut_id" "
+# include <sys/types.h>
+# include <utmp.h>
+
+"
+if test "x$ac_cv_member_struct_utmp_ut_id" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_ID 1" >>confdefs.h
+
+
+fi
+
+ ac_fn_c_check_member "$LINENO" "struct utmp" "ut_pid" "ac_cv_member_struct_utmp_ut_pid" "
+# include <sys/types.h>
+# include <utmp.h>
+
+"
+if test "x$ac_cv_member_struct_utmp_ut_pid" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_PID 1" >>confdefs.h
+
+
+fi
+
+ ac_fn_c_check_member "$LINENO" "struct utmp" "ut_tv" "ac_cv_member_struct_utmp_ut_tv" "
+# include <sys/types.h>
+# include <utmp.h>
+
+"
+if test "x$ac_cv_member_struct_utmp_ut_tv" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_TV 1" >>confdefs.h
+
+
+fi
+
+ ac_fn_c_check_member "$LINENO" "struct utmp" "ut_type" "ac_cv_member_struct_utmp_ut_type" "
+# include <sys/types.h>
+# include <utmp.h>
+
+"
+if test "x$ac_cv_member_struct_utmp_ut_type" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_TYPE 1" >>confdefs.h
+
+
+fi
+
+ if test "utmp" = "utmp"; then
+ ac_fn_c_check_member "$LINENO" "struct utmp" "ut_user" "ac_cv_member_struct_utmp_ut_user" "
+# include <sys/types.h>
+# include <utmp.h>
+
+"
+if test "x$ac_cv_member_struct_utmp_ut_user" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_UTMP_UT_USER 1
+_ACEOF
+
+
+fi
+
+ fi
+ ac_fn_c_check_member "$LINENO" "struct utmp" "ut_exit.__e_termination" "ac_cv_member_struct_utmp_ut_exit___e_termination" "
+# include <sys/types.h>
+# include <utmp.h>
+
+"
+if test "x$ac_cv_member_struct_utmp_ut_exit___e_termination" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT___E_TERMINATION 1" >>confdefs.h
+
+
+else
+
+ ac_fn_c_check_member "$LINENO" "struct utmp" "ut_exit.e_termination" "ac_cv_member_struct_utmp_ut_exit_e_termination" "
+# include <sys/types.h>
+# include <utmp.h>
+
+"
+if test "x$ac_cv_member_struct_utmp_ut_exit_e_termination" = xyes; then :
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking type of array argument to getgroups" >&5
+$as_echo_n "checking type of array argument to getgroups... " >&6; }
+if ${ac_cv_type_getgroups+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_type_getgroups=cross
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Thanks to Mike Rendell for this test. */
+$ac_includes_default
+#define NGID 256
+#undef MAX
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+
+int
+main ()
+{
+ gid_t gidset[NGID];
+ int i, n;
+ union { gid_t gval; long int lval; } val;
+
+ val.lval = -1;
+ for (i = 0; i < NGID; i++)
+ gidset[i] = val.gval;
+ n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1,
+ gidset);
+ /* Exit non-zero if getgroups seems to require an array of ints. This
+ happens when gid_t is short int but getgroups modifies an array
+ of ints. */
+ return n > 0 && gidset[n] != val.gval;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_type_getgroups=gid_t
+else
+ ac_cv_type_getgroups=int
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+if test $ac_cv_type_getgroups = cross; then
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <unistd.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "getgroups.*int.*gid_t" >/dev/null 2>&1; then :
+ ac_cv_type_getgroups=gid_t
+else
+ ac_cv_type_getgroups=int
+fi
+rm -f conftest*
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_getgroups" >&5
+$as_echo "$ac_cv_type_getgroups" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define GETGROUPS_T $ac_cv_type_getgroups
+_ACEOF
+
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+ac_fn_c_check_func "$LINENO" "getgroups" "ac_cv_func_getgroups"
+if test "x$ac_cv_func_getgroups" = xyes; then :
+
+fi
+
+
+# If we don't yet have getgroups, see if it's in -lbsd.
+# This is reported to be necessary on an ITOS 3000WS running SEIUX 3.1.
+ac_save_LIBS=$LIBS
+if test $ac_cv_func_getgroups = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgroups in -lbsd" >&5
+$as_echo_n "checking for getgroups in -lbsd... " >&6; }
+if ${ac_cv_lib_bsd_getgroups+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getgroups ();
+int
+main ()
+{
+return getgroups ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_bsd_getgroups=yes
+else
+ ac_cv_lib_bsd_getgroups=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_getgroups" >&5
+$as_echo "$ac_cv_lib_bsd_getgroups" >&6; }
+if test "x$ac_cv_lib_bsd_getgroups" = xyes; then :
+ GETGROUPS_LIB=-lbsd
+fi
+
+fi
+
+# Run the program to test the functionality of the system-supplied
+# getgroups function only if there is such a function.
+if test $ac_cv_func_getgroups = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working getgroups" >&5
+$as_echo_n "checking for working getgroups... " >&6; }
+if ${ac_cv_func_getgroups_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_getgroups_works=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+/* On Ultrix 4.3, getgroups (0, 0) always fails. */
+ return getgroups (0, 0) == -1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_getgroups_works=yes
+else
+ ac_cv_func_getgroups_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getgroups_works" >&5
+$as_echo "$ac_cv_func_getgroups_works" >&6; }
+else
+ ac_cv_func_getgroups_works=no
+fi
+if test $ac_cv_func_getgroups_works = yes; then
+
+$as_echo "#define HAVE_GETGROUPS 1" >>confdefs.h
+
+fi
+LIBS=$ac_save_LIBS
+
+
+
+
+ for ac_func in $ac_func_list
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+case "$host_os" in
+ hpux*)
+ if test X"$ac_cv_func_pread" = X"yes"; then
+ O_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE"
+ for ac_func in pread64 pwrite64
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+
+$as_echo "#define _LARGEFILE64_SOURCE 1" >>confdefs.h
+
+
+fi
+done
+
+ CPPFLAGS="$O_CPPFLAGS"
+ fi
+ ;;
+esac
+for ac_func in getgrouplist
+do :
+ ac_fn_c_check_func "$LINENO" "getgrouplist" "ac_cv_func_getgrouplist"
+if test "x$ac_cv_func_getgrouplist" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETGROUPLIST 1
+_ACEOF
+
+else
+
+ case "$host_os" in
+ aix*)
+ for ac_func in getgrset
+do :
+ ac_fn_c_check_func "$LINENO" "getgrset" "ac_cv_func_getgrset"
+if test "x$ac_cv_func_getgrset" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETGRSET 1
+_ACEOF
+
+fi
+done
+
+ ;;
+ *)
+ ac_fn_c_check_func "$LINENO" "nss_search" "ac_cv_func_nss_search"
+if test "x$ac_cv_func_nss_search" = xyes; then :
+
+ ac_fn_c_check_func "$LINENO" "_nss_XbyY_buf_alloc" "ac_cv_func__nss_XbyY_buf_alloc"
+if test "x$ac_cv_func__nss_XbyY_buf_alloc" = xyes; then :
+
+ # Solaris
+ ac_fn_c_check_func "$LINENO" "_nss_initf_group" "ac_cv_func__nss_initf_group"
+if test "x$ac_cv_func__nss_initf_group" = xyes; then :
+
+ for ac_header in nss_dbdefs.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "nss_dbdefs.h" "ac_cv_header_nss_dbdefs_h" "$ac_includes_default"
+if test "x$ac_cv_header_nss_dbdefs_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_NSS_DBDEFS_H 1
+_ACEOF
+
+fi
+
+done
+
+ $as_echo "#define HAVE_NSS_SEARCH 1" >>confdefs.h
+
+ $as_echo "#define HAVE__NSS_XBYY_BUF_ALLOC 1" >>confdefs.h
+
+ $as_echo "#define HAVE__NSS_INITF_GROUP 1" >>confdefs.h
+
+
+else
+
+ for ac_header in nss_dbdefs.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "nss_dbdefs.h" "ac_cv_header_nss_dbdefs_h" "$ac_includes_default"
+if test "x$ac_cv_header_nss_dbdefs_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_NSS_DBDEFS_H 1
+_ACEOF
+
+ # Older Solaris does not export _nss_initf_group
+ # but we can use our own.
+ $as_echo "#define HAVE_NSS_SEARCH 1" >>confdefs.h
+
+ $as_echo "#define HAVE__NSS_XBYY_BUF_ALLOC 1" >>confdefs.h
+
+
+fi
+
+done
+
+
+fi
+
+
+else
+
+ # HP-UX
+ ac_fn_c_check_func "$LINENO" "__nss_XbyY_buf_alloc" "ac_cv_func___nss_XbyY_buf_alloc"
+if test "x$ac_cv_func___nss_XbyY_buf_alloc" = xyes; then :
+
+ ac_fn_c_check_func "$LINENO" "__nss_initf_group" "ac_cv_func___nss_initf_group"
+if test "x$ac_cv_func___nss_initf_group" = xyes; then :
+
+ for ac_header in nss_dbdefs.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "nss_dbdefs.h" "ac_cv_header_nss_dbdefs_h" "$ac_includes_default"
+if test "x$ac_cv_header_nss_dbdefs_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_NSS_DBDEFS_H 1
+_ACEOF
+
+fi
+
+done
+
+ $as_echo "#define HAVE_NSS_SEARCH 1" >>confdefs.h
+
+ $as_echo "#define HAVE___NSS_XBYY_BUF_ALLOC 1" >>confdefs.h
+
+ $as_echo "#define HAVE___NSS_INITF_GROUP 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ for _sym in sudo_getgrouplist; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+for ac_func in getline
+do :
+ ac_fn_c_check_func "$LINENO" "getline" "ac_cv_func_getline"
+if test "x$ac_cv_func_getline" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETLINE 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" getline.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS getline.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_getline; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ for ac_func in fgetln
+do :
+ ac_fn_c_check_func "$LINENO" "fgetln" "ac_cv_func_fgetln"
+if test "x$ac_cv_func_fgetln" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FGETLN 1
+_ACEOF
+
+fi
+done
+
+
+fi
+done
+
+for ac_func in reallocarray
+do :
+ ac_fn_c_check_func "$LINENO" "reallocarray" "ac_cv_func_reallocarray"
+if test "x$ac_cv_func_reallocarray" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_REALLOCARRAY 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" reallocarray.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS reallocarray.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_reallocarray; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+for ac_func in arc4random_uniform
+do :
+ ac_fn_c_check_func "$LINENO" "arc4random_uniform" "ac_cv_func_arc4random_uniform"
+if test "x$ac_cv_func_arc4random_uniform" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ARC4RANDOM_UNIFORM 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" arc4random_uniform.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS arc4random_uniform.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_arc4random_uniform; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ for ac_func in arc4random
+do :
+ ac_fn_c_check_func "$LINENO" "arc4random" "ac_cv_func_arc4random"
+if test "x$ac_cv_func_arc4random" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ARC4RANDOM 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" arc4random.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS arc4random.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_arc4random; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ # arc4random.c needs getentropy()
+ for ac_func in getentropy
+do :
+ ac_fn_c_check_func "$LINENO" "getentropy" "ac_cv_func_getentropy"
+if test "x$ac_cv_func_getentropy" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETENTROPY 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" getentropy.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS getentropy.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_getentropy; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+ # arc4random.c wants pthread_atfork
+ for ac_header in pthread.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
+if test "x$ac_cv_header_pthread_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_PTHREAD_H 1
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5
+$as_echo_n "checking for main in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread_main=yes
+else
+ ac_cv_lib_pthread_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5
+$as_echo "$ac_cv_lib_pthread_main" >&6; }
+if test "x$ac_cv_lib_pthread_main" = xyes; then :
+ LIBPTHREAD="-lpthread"
+fi
+
+ for ac_func in pthread_atfork
+do :
+ ac_fn_c_check_func "$LINENO" "pthread_atfork" "ac_cv_func_pthread_atfork"
+if test "x$ac_cv_func_pthread_atfork" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_PTHREAD_ATFORK 1
+_ACEOF
+
+fi
+done
+
+
+fi
+
+done
+
+
+fi
+done
+
+
+fi
+done
+
+
+utmp_style=LEGACY
+for ac_func in getutsid getutxid getutid
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ utmp_style=POSIX; break
+fi
+done
+
+if test "$utmp_style" = "LEGACY"; then
+ for ac_func in getttyent ttyslot
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+done
+
+ for ac_func in fseeko
+do :
+ ac_fn_c_check_func "$LINENO" "fseeko" "ac_cv_func_fseeko"
+if test "x$ac_cv_func_fseeko" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FSEEKO 1
+_ACEOF
+
+fi
+done
+
+fi
+
+for ac_func in sysctl
+do :
+ ac_fn_c_check_func "$LINENO" "sysctl" "ac_cv_func_sysctl"
+if test "x$ac_cv_func_sysctl" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYSCTL 1
+_ACEOF
+ for ac_func in devname
+do :
+ ac_fn_c_check_func "$LINENO" "devname" "ac_cv_func_devname"
+if test "x$ac_cv_func_devname" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DEVNAME 1
+_ACEOF
+
+fi
+done
+
+ ac_fn_c_check_member "$LINENO" "struct kinfo_proc" "ki_structsize" "ac_cv_member_struct_kinfo_proc_ki_structsize" "
+# include <sys/param.h>
+# include <sys/sysctl.h>
+# include <sys/user.h>
+
+"
+if test "x$ac_cv_member_struct_kinfo_proc_ki_structsize" = xyes; then :
+ $as_echo "#define HAVE_KINFO_PROC_FREEBSD 1" >>confdefs.h
+
+else
+
+ ac_fn_c_check_member "$LINENO" "struct kinfo_proc2" "p_paddr" "ac_cv_member_struct_kinfo_proc2_p_paddr" "
+# include <sys/param.h>
+# include <sys/sysctl.h>
+
+"
+if test "x$ac_cv_member_struct_kinfo_proc2_p_paddr" = xyes; then :
+ $as_echo "#define HAVE_KINFO_PROC2_NETBSD 1" >>confdefs.h
+
+else
+
+ ac_fn_c_check_member "$LINENO" "struct kinfo_proc" "p_paddr" "ac_cv_member_struct_kinfo_proc_p_paddr" "
+# include <sys/param.h>
+# include <sys/sysctl.h>
+
+"
+if test "x$ac_cv_member_struct_kinfo_proc_p_paddr" = xyes; then :
+ $as_echo "#define HAVE_KINFO_PROC_OPENBSD 1" >>confdefs.h
+
+else
+
+ ac_fn_c_check_member "$LINENO" "struct kinfo_proc" "kp_proc" "ac_cv_member_struct_kinfo_proc_kp_proc" "
+# include <sys/param.h>
+# include <sys/sysctl.h>
+
+"
+if test "x$ac_cv_member_struct_kinfo_proc_kp_proc" = xyes; then :
+ $as_echo "#define HAVE_KINFO_PROC_44BSD 1" >>confdefs.h
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in openpty
+do :
+ ac_fn_c_check_func "$LINENO" "openpty" "ac_cv_func_openpty"
+if test "x$ac_cv_func_openpty" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_OPENPTY 1
+_ACEOF
+ for ac_header in libutil.h util.h pty.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+
+done
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for openpty in -lutil" >&5
+$as_echo_n "checking for openpty in -lutil... " >&6; }
+if ${ac_cv_lib_util_openpty+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lutil $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char openpty ();
+int
+main ()
+{
+return openpty ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_util_openpty=yes
+else
+ ac_cv_lib_util_openpty=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_openpty" >&5
+$as_echo "$ac_cv_lib_util_openpty" >&6; }
+if test "x$ac_cv_lib_util_openpty" = xyes; then :
+
+ for ac_header in libutil.h util.h pty.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+
+done
+
+ case "$SUDO_LIBS" in
+ *-lutil*) ;;
+ *) SUDO_LIBS="${SUDO_LIBS} -lutil";;
+ esac
+ $as_echo "#define HAVE_OPENPTY 1" >>confdefs.h
+
+
+else
+
+ for ac_func in _getpty
+do :
+ ac_fn_c_check_func "$LINENO" "_getpty" "ac_cv_func__getpty"
+if test "x$ac_cv_func__getpty" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__GETPTY 1
+_ACEOF
+
+else
+
+ for ac_func in grantpt
+do :
+ ac_fn_c_check_func "$LINENO" "grantpt" "ac_cv_func_grantpt"
+if test "x$ac_cv_func_grantpt" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GRANTPT 1
+_ACEOF
+
+ for ac_func in posix_openpt
+do :
+ ac_fn_c_check_func "$LINENO" "posix_openpt" "ac_cv_func_posix_openpt"
+if test "x$ac_cv_func_posix_openpt" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_POSIX_OPENPT 1
+_ACEOF
+
+fi
+done
+
+
+else
+
+ for ac_func in revoke
+do :
+ ac_fn_c_check_func "$LINENO" "revoke" "ac_cv_func_revoke"
+if test "x$ac_cv_func_revoke" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_REVOKE 1
+_ACEOF
+
+fi
+done
+
+
+fi
+done
+
+
+fi
+done
+
+
+fi
+
+
+fi
+done
+
+for ac_func in unsetenv
+do :
+ ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv"
+if test "x$ac_cv_func_unsetenv" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_UNSETENV 1
+_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether unsetenv returns void" >&5
+$as_echo_n "checking whether unsetenv returns void... " >&6; }
+if ${sudo_cv_func_unsetenv_void+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ sudo_cv_func_unsetenv_void=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+ int unsetenv();
+
+int
+main ()
+{
+
+ return unsetenv("FOO") != 0;
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ sudo_cv_func_unsetenv_void=no
+else
+ sudo_cv_func_unsetenv_void=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_func_unsetenv_void" >&5
+$as_echo "$sudo_cv_func_unsetenv_void" >&6; }
+ if test $sudo_cv_func_unsetenv_void = yes; then
+
+$as_echo "#define UNSETENV_VOID 1" >>confdefs.h
+
+ fi
+
+fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether putenv takes a const argument" >&5
+$as_echo_n "checking whether putenv takes a const argument... " >&6; }
+if ${sudo_cv_func_putenv_const+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int putenv(const char *string) {return 0;}
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ sudo_cv_func_putenv_const=yes
+else
+ sudo_cv_func_putenv_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_func_putenv_const" >&5
+$as_echo "$sudo_cv_func_putenv_const" >&6; }
+ if test $sudo_cv_func_putenv_const = yes; then
+
+$as_echo "#define PUTENV_CONST const" >>confdefs.h
+
+ else
+ $as_echo "#define PUTENV_CONST /**/" >>confdefs.h
+
+ fi
+
+if test -z "$SKIP_SETRESUID"; then
+ for ac_func in setresuid
+do :
+ ac_fn_c_check_func "$LINENO" "setresuid" "ac_cv_func_setresuid"
+if test "x$ac_cv_func_setresuid" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SETRESUID 1
+_ACEOF
+
+ SKIP_SETREUID=yes
+ ac_fn_c_check_decl "$LINENO" "setresuid" "ac_cv_have_decl_setresuid" "$ac_includes_default"
+if test "x$ac_cv_have_decl_setresuid" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SETRESUID $ac_have_decl
+_ACEOF
+
+ for ac_func in getresuid
+do :
+ ac_fn_c_check_func "$LINENO" "getresuid" "ac_cv_func_getresuid"
+if test "x$ac_cv_func_getresuid" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETRESUID 1
+_ACEOF
+ ac_fn_c_check_decl "$LINENO" "getresuid" "ac_cv_have_decl_getresuid" "$ac_includes_default"
+if test "x$ac_cv_have_decl_getresuid" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_GETRESUID $ac_have_decl
+_ACEOF
+
+fi
+done
+
+
+fi
+done
+
+fi
+if test -z "$SKIP_SETREUID"; then
+ for ac_func in setreuid
+do :
+ ac_fn_c_check_func "$LINENO" "setreuid" "ac_cv_func_setreuid"
+if test "x$ac_cv_func_setreuid" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SETREUID 1
+_ACEOF
+
+fi
+done
+
+fi
+
+
+
+if test X"$with_interfaces" != X"no"; then
+ for ac_func in getifaddrs
+do :
+ ac_fn_c_check_func "$LINENO" "getifaddrs" "ac_cv_func_getifaddrs"
+if test "x$ac_cv_func_getifaddrs" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETIFADDRS 1
+_ACEOF
+ for ac_func in freeifaddrs
+do :
+ ac_fn_c_check_func "$LINENO" "freeifaddrs" "ac_cv_func_freeifaddrs"
+if test "x$ac_cv_func_freeifaddrs" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FREEIFADDRS 1
+_ACEOF
+
+fi
+done
+
+fi
+done
+
+fi
+for ac_func in lockf
+do :
+ ac_fn_c_check_func "$LINENO" "lockf" "ac_cv_func_lockf"
+if test "x$ac_cv_func_lockf" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LOCKF 1
+_ACEOF
+ break
+fi
+done
+
+for ac_func in innetgr
+do :
+ ac_fn_c_check_func "$LINENO" "innetgr" "ac_cv_func_innetgr"
+if test "x$ac_cv_func_innetgr" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_INNETGR 1
+_ACEOF
+
+ ac_fn_c_check_decl "$LINENO" "innetgr" "ac_cv_have_decl_innetgr" "
+$ac_includes_default
+#ifdef HAVE_NETGROUP_H
+# include <netgroup.h>
+#else
+# include <netdb.h>
+#endif /* HAVE_NETGROUP_H */
+
+"
+if test "x$ac_cv_have_decl_innetgr" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_INNETGR $ac_have_decl
+_ACEOF
+
+else
+
+ for ac_func in _innetgr
+do :
+ ac_fn_c_check_func "$LINENO" "_innetgr" "ac_cv_func__innetgr"
+if test "x$ac_cv_func__innetgr" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__INNETGR 1
+_ACEOF
+
+ ac_fn_c_check_decl "$LINENO" "_innetgr" "ac_cv_have_decl__innetgr" "
+$ac_includes_default
+#ifdef HAVE_NETGROUP_H
+# include <netgroup.h>
+#else
+# include <netdb.h>
+#endif /* HAVE_NETGROUP_H */
+
+"
+if test "x$ac_cv_have_decl__innetgr" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL__INNETGR $ac_have_decl
+_ACEOF
+
+
+fi
+done
+
+
+fi
+done
+
+for ac_func in getdomainname
+do :
+ ac_fn_c_check_func "$LINENO" "getdomainname" "ac_cv_func_getdomainname"
+if test "x$ac_cv_func_getdomainname" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETDOMAINNAME 1
+_ACEOF
+
+ ac_fn_c_check_decl "$LINENO" "getdomainname" "ac_cv_have_decl_getdomainname" "
+$ac_includes_default
+#include <netdb.h>
+
+"
+if test "x$ac_cv_have_decl_getdomainname" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_GETDOMAINNAME $ac_have_decl
+_ACEOF
+
+
+else
+
+ for ac_func in sysinfo
+do :
+ ac_fn_c_check_func "$LINENO" "sysinfo" "ac_cv_func_sysinfo"
+if test "x$ac_cv_func_sysinfo" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYSINFO 1
+_ACEOF
+ for ac_header in sys/systeminfo.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/systeminfo.h" "ac_cv_header_sys_systeminfo_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_systeminfo_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_SYSTEMINFO_H 1
+_ACEOF
+
+fi
+
+done
+
+fi
+done
+
+
+fi
+done
+
+for ac_func in utimensat
+do :
+ ac_fn_c_check_func "$LINENO" "utimensat" "ac_cv_func_utimensat"
+if test "x$ac_cv_func_utimensat" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_UTIMENSAT 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" utimens.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS utimens.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_utimensat; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ for ac_func in utimes
+do :
+ ac_fn_c_check_func "$LINENO" "utimes" "ac_cv_func_utimes"
+if test "x$ac_cv_func_utimes" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_UTIMES 1
+_ACEOF
+
+fi
+done
+
+
+fi
+done
+
+for ac_func in futimens
+do :
+ ac_fn_c_check_func "$LINENO" "futimens" "ac_cv_func_futimens"
+if test "x$ac_cv_func_futimens" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FUTIMENS 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" utimens.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS utimens.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_futimens; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ for ac_func in futimes futimesat futime
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+done
+
+
+fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fnmatch with FNM_CASEFOLD" >&5
+$as_echo_n "checking for working fnmatch with FNM_CASEFOLD... " >&6; }
+if ${sudo_cv_func_fnmatch+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f conftestdata; > conftestdata
+if test "$cross_compiling" = yes; then :
+ sudo_cv_func_fnmatch=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <fnmatch.h>
+main() { exit(fnmatch("/*/bin/echo *", "/usr/bin/echo just a test", FNM_CASEFOLD)); }
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ sudo_cv_func_fnmatch=yes
+else
+ sudo_cv_func_fnmatch=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+rm -f core core.* *.core
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_func_fnmatch" >&5
+$as_echo "$sudo_cv_func_fnmatch" >&6; }
+if test $sudo_cv_func_fnmatch = yes; then :
+ $as_echo "#define HAVE_FNMATCH 1" >>confdefs.h
+
+else
+
+ case " $LIBOBJS " in
+ *" fnmatch.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS fnmatch.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_fnmatch; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }fnm_test"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for isblank" >&5
+$as_echo_n "checking for isblank... " >&6; }
+if ${sudo_cv_func_isblank+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+int
+main ()
+{
+return (isblank('a'));
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ sudo_cv_func_isblank=yes
+else
+ sudo_cv_func_isblank=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_func_isblank" >&5
+$as_echo "$sudo_cv_func_isblank" >&6; }
+
+ if test "$sudo_cv_func_isblank" = "yes"; then
+
+$as_echo "#define HAVE_ISBLANK 1" >>confdefs.h
+
+ else
+ case " $LIBOBJS " in
+ *" isblank.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS isblank.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in isblank; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ fi
+
+for ac_func in glob
+do :
+ ac_fn_c_check_func "$LINENO" "glob" "ac_cv_func_glob"
+if test "x$ac_cv_func_glob" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GLOB 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" glob.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS glob.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_glob sudo_globfree; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+for ac_func in memrchr
+do :
+ ac_fn_c_check_func "$LINENO" "memrchr" "ac_cv_func_memrchr"
+if test "x$ac_cv_func_memrchr" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_MEMRCHR 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" memrchr.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS memrchr.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_memrchr; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+for ac_func in memset_s
+do :
+ ac_fn_c_check_func "$LINENO" "memset_s" "ac_cv_func_memset_s"
+if test "x$ac_cv_func_memset_s" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_MEMSET_S 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" memset_s.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS memset_s.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_memset_s; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+for ac_func in nanosleep
+do :
+ ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep"
+if test "x$ac_cv_func_nanosleep" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_NANOSLEEP 1
+_ACEOF
+
+else
+
+ # On Solaris, nanosleep is in librt
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nanosleep in -lrt" >&5
+$as_echo_n "checking for nanosleep in -lrt... " >&6; }
+if ${ac_cv_lib_rt_nanosleep+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char nanosleep ();
+int
+main ()
+{
+return nanosleep ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_rt_nanosleep=yes
+else
+ ac_cv_lib_rt_nanosleep=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_nanosleep" >&5
+$as_echo "$ac_cv_lib_rt_nanosleep" >&6; }
+if test "x$ac_cv_lib_rt_nanosleep" = xyes; then :
+
+ $as_echo "#define HAVE_NANOSLEEP 1" >>confdefs.h
+
+ LIBRT="-lrt"
+
+else
+
+ case " $LIBOBJS " in
+ *" nanosleep.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS nanosleep.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_nanosleep; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+
+
+fi
+done
+
+for ac_func in pipe2
+do :
+ ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_PIPE2 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" pipe2.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS pipe2.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_pipe2; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+for ac_func in pw_dup
+do :
+ ac_fn_c_check_func "$LINENO" "pw_dup" "ac_cv_func_pw_dup"
+if test "x$ac_cv_func_pw_dup" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_PW_DUP 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" pw_dup.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS pw_dup.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_pw_dup; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+for ac_func in strlcpy
+do :
+ ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy"
+if test "x$ac_cv_func_strlcpy" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRLCPY 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" strlcpy.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS strlcpy.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_strlcpy; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+for ac_func in strlcat
+do :
+ ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat"
+if test "x$ac_cv_func_strlcat" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRLCAT 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" strlcat.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS strlcat.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_strlcat; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+ac_fn_c_check_func "$LINENO" "strnlen" "ac_cv_func_strnlen"
+if test "x$ac_cv_func_strnlen" = xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strnlen" >&5
+$as_echo_n "checking for working strnlen... " >&6; }
+if ${ac_cv_func_strnlen_working+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ # Guess no on AIX systems, yes otherwise.
+ case "$host_os" in
+ aix*) ac_cv_func_strnlen_working=no;;
+ *) ac_cv_func_strnlen_working=yes;;
+ esac
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+#define S "foobar"
+#define S_LEN (sizeof S - 1)
+
+ /* At least one implementation is buggy: that of AIX 4.3 would
+ give strnlen (S, 1) == 3. */
+
+ int i;
+ for (i = 0; i < S_LEN + 1; ++i)
+ {
+ int expected = i <= S_LEN ? i : S_LEN;
+ if (strnlen (S, i) != expected)
+ return 1;
+ }
+ return 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_strnlen_working=yes
+else
+ ac_cv_func_strnlen_working=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strnlen_working" >&5
+$as_echo "$ac_cv_func_strnlen_working" >&6; }
+test $ac_cv_func_strnlen_working = no && case " $LIBOBJS " in
+ *" strnlen.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS strnlen.$ac_objext"
+ ;;
+esac
+
+
+else
+ case " $LIBOBJS " in
+ *" strnlen.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS strnlen.$ac_objext"
+ ;;
+esac
+
+fi
+
+if test X"$ac_cv_func_strnlen_working" = X"yes"; then
+ $as_echo "#define HAVE_STRNLEN 1" >>confdefs.h
+
+ for ac_func in strndup
+do :
+ ac_fn_c_check_func "$LINENO" "strndup" "ac_cv_func_strndup"
+if test "x$ac_cv_func_strndup" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRNDUP 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" strndup.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS strndup.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_strndup; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+else
+ # Broken or missing strnlen, use our own.
+
+ for _sym in sudo_strnlen; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ # Avoid libc strndup() since it is usually implemented using strnlen()
+ case " $LIBOBJS " in
+ *" strndup.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS strndup.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_strndup; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+fi
+for ac_func in clock_gettime
+do :
+ ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
+if test "x$ac_cv_func_clock_gettime" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOCK_GETTIME 1
+_ACEOF
+
+else
+
+ # On Solaris, clock_gettime is in librt
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
+$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
+if ${ac_cv_lib_rt_clock_gettime+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_rt_clock_gettime=yes
+else
+ ac_cv_lib_rt_clock_gettime=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5
+$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
+if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then :
+
+ $as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
+
+ LIBRT="-lrt"
+
+fi
+
+
+fi
+done
+
+for ac_func in getopt_long
+do :
+ ac_fn_c_check_func "$LINENO" "getopt_long" "ac_cv_func_getopt_long"
+if test "x$ac_cv_func_getopt_long" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETOPT_LONG 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" getopt_long.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS getopt_long.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_getopt_long sudo_getopt_long_only; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for optreset" >&5
+$as_echo_n "checking for optreset... " >&6; }
+ if ${sudo_cv_optreset+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+extern int optreset; optreset = 1; return optreset;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ sudo_cv_optreset=yes
+else
+ sudo_cv_optreset=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+
+ if test "$sudo_cv_optreset" = "yes"; then
+ $as_echo "#define HAVE_OPTRESET 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_optreset" >&5
+$as_echo "$sudo_cv_optreset" >&6; }
+
+fi
+done
+
+for ac_func in closefrom
+do :
+ ac_fn_c_check_func "$LINENO" "closefrom" "ac_cv_func_closefrom"
+if test "x$ac_cv_func_closefrom" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOSEFROM 1
+_ACEOF
+
+else
+ case " $LIBOBJS " in
+ *" closefrom.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS closefrom.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in closefrom_fallback sudo_closefrom; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ ac_fn_c_check_decl "$LINENO" "F_CLOSEM" "ac_cv_have_decl_F_CLOSEM" "
+# include <limits.h>
+# include <fcntl.h>
+"
+if test "x$ac_cv_have_decl_F_CLOSEM" = xyes; then :
+ $as_echo "#define HAVE_FCNTL_CLOSEM 1" >>confdefs.h
+
+fi
+
+
+fi
+done
+
+for ac_func in mkstemps mkdtemp
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+ break
+fi
+done
+
+if test X"$ac_cv_func_mkstemps$ac_cv_func_mkdtemp" != X"yesyes"; then
+ for ac_func in arc4random random lrand48
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+done
+
+ if test X"$ac_cv_func_arc4random" != X"yes"; then
+ for ac_func in getentropy
+do :
+ ac_fn_c_check_func "$LINENO" "getentropy" "ac_cv_func_getentropy"
+if test "x$ac_cv_func_getentropy" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETENTROPY 1
+_ACEOF
+
+fi
+done
+
+ fi
+ case " $LIBOBJS " in
+ *" mktemp.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS mktemp.$ac_objext"
+ ;;
+esac
+
+ # If either mkdtemp() or mkstemps() is missing, replace both.
+
+ for _sym in sudo_mkdtemp sudo_mkstemps; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }mktemp_test"
+fi
+for ac_func in snprintf vsnprintf
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working snprintf" >&5
+$as_echo_n "checking for working snprintf... " >&6; }
+if ${ac_cv_have_working_snprintf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_have_working_snprintf=cross
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+
+int main(void)
+{
+ char bufs[5] = { 'x', 'x', 'x', '\0', '\0' };
+ char bufd[5] = { 'x', 'x', 'x', '\0', '\0' };
+ int i;
+ i = snprintf (bufs, 2, "%s", "111");
+ if (strcmp (bufs, "1")) exit (1);
+ if (i != 3) exit (1);
+ i = snprintf (bufd, 2, "%d", 111);
+ if (strcmp (bufd, "1")) exit (1);
+ if (i != 3) exit (1);
+ exit(0);
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_have_working_snprintf=yes
+else
+ ac_cv_have_working_snprintf=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_working_snprintf" >&5
+$as_echo "$ac_cv_have_working_snprintf" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vsnprintf" >&5
+$as_echo_n "checking for working vsnprintf... " >&6; }
+if ${ac_cv_have_working_vsnprintf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_have_working_vsnprintf=cross
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+#include <stdarg.h>
+
+int my_vsnprintf (char *buf, const char *tmpl, ...)
+{
+ int i;
+ va_list args;
+ va_start (args, tmpl);
+ i = vsnprintf (buf, 2, tmpl, args);
+ va_end (args);
+ return i;
+}
+
+int main(void)
+{
+ char bufs[5] = { 'x', 'x', 'x', '\0', '\0' };
+ char bufd[5] = { 'x', 'x', 'x', '\0', '\0' };
+ int i;
+ i = my_vsnprintf (bufs, "%s", "111");
+ if (strcmp (bufs, "1")) exit (1);
+ if (i != 3) exit (1);
+ i = my_vsnprintf (bufd, "%d", 111);
+ if (strcmp (bufd, "1")) exit (1);
+ if (i != 3) exit (1);
+ exit(0);
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_have_working_vsnprintf=yes
+else
+ ac_cv_have_working_vsnprintf=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_working_vsnprintf" >&5
+$as_echo "$ac_cv_have_working_vsnprintf" >&6; }
+if test x$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf != "xyesyes"; then
+ case " $LIBOBJS " in
+ *" snprintf.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS snprintf.$ac_objext"
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Replacing missing/broken (v)snprintf() with sudo's version." >&5
+$as_echo "$as_me: WARNING: Replacing missing/broken (v)snprintf() with sudo's version." >&2;}
+
+$as_echo "#define PREFER_PORTABLE_SNPRINTF 1" >>confdefs.h
+
+fi
+if test X"$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf" = X"yesyes"; then
+ # System has a C99-compliant v?snprintf(), check for v?asprintf()
+ for ac_func in asprintf
+do :
+ ac_fn_c_check_func "$LINENO" "asprintf" "ac_cv_func_asprintf"
+if test "x$ac_cv_func_asprintf" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ASPRINTF 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" snprintf.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS snprintf.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_asprintf; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+ for ac_func in vasprintf
+do :
+ ac_fn_c_check_func "$LINENO" "vasprintf" "ac_cv_func_vasprintf"
+if test "x$ac_cv_func_vasprintf" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_VASPRINTF 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" snprintf.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS snprintf.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_vasprintf; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+else
+ # Missing or non-compliant v?snprintf(), assume missing/bad v?asprintf()
+
+ for _sym in sudo_snprintf sudo_vsnprintf sudo_asprintf sudo_vasprintf; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+fi
+# We wrap OpenBSD's strtonum() to get translatable error strings.
+for ac_func in strtonum
+do :
+ ac_fn_c_check_func "$LINENO" "strtonum" "ac_cv_func_strtonum"
+if test "x$ac_cv_func_strtonum" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRTONUM 1
+_ACEOF
+
+fi
+done
+
+case " $LIBOBJS " in
+ *" strtonum.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS strtonum.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_strtonum; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ac_fn_c_check_member "$LINENO" "struct tm" "tm_gmtoff" "ac_cv_member_struct_tm_tm_gmtoff" "
+$ac_includes_default
+#include <errno.h>
+
+"
+if test "x$ac_cv_member_struct_tm_tm_gmtoff" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_TM_TM_GMTOFF 1
+_ACEOF
+
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim" "ac_cv_member_struct_stat_st_mtim" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then :
+ $as_echo "#define HAVE_ST_MTIM 1" >>confdefs.h
+
+ ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim.st__tim" "ac_cv_member_struct_stat_st_mtim_st__tim" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_mtim_st__tim" = xyes; then :
+ $as_echo "#define HAVE_ST__TIM 1" >>confdefs.h
+
+fi
+
+else
+ ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimespec" "ac_cv_member_struct_stat_st_mtimespec" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_mtimespec" = xyes; then :
+ $as_echo "#define HAVE_ST_MTIMESPEC 1" >>confdefs.h
+
+else
+ ac_fn_c_check_member "$LINENO" "struct stat" "st_nmtime" "ac_cv_member_struct_stat_st_nmtime" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_nmtime" = xyes; then :
+ $as_echo "#define HAVE_ST_NMTIME 1" >>confdefs.h
+
+fi
+
+fi
+
+
+
+fi
+
+# Look for sha2 functions if not using openssl
+if test "$DIGEST" = "digest.lo"; then
+ FOUND_SHA2=no
+ ac_fn_c_check_header_mongrel "$LINENO" "sha2.h" "ac_cv_header_sha2_h" "$ac_includes_default"
+if test "x$ac_cv_header_sha2_h" = xyes; then :
+
+ FOUND_SHA2=yes
+ for ac_func in SHA224Update
+do :
+ ac_fn_c_check_func "$LINENO" "SHA224Update" "ac_cv_func_SHA224Update"
+if test "x$ac_cv_func_SHA224Update" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SHA224UPDATE 1
+_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the data argument of SHA224Update() is void *" >&5
+$as_echo_n "checking whether the data argument of SHA224Update() is void *... " >&6; }
+if ${sudo_cv_func_sha2_void_ptr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+#include <sha2.h>
+void SHA224Update(SHA2_CTX *context, const void *data, size_t len) {return;}
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ sudo_cv_func_sha2_void_ptr=yes
+else
+ sudo_cv_func_sha2_void_ptr=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_func_sha2_void_ptr" >&5
+$as_echo "$sudo_cv_func_sha2_void_ptr" >&6; }
+ if test $sudo_cv_func_sha2_void_ptr = yes; then
+
+$as_echo "#define SHA2_VOID_PTR 1" >>confdefs.h
+
+ fi
+
+else
+
+ # On some systems, SHA224Update is in libmd
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SHA224Update in -lmd" >&5
+$as_echo_n "checking for SHA224Update in -lmd... " >&6; }
+if ${ac_cv_lib_md_SHA224Update+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmd $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char SHA224Update ();
+int
+main ()
+{
+return SHA224Update ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_md_SHA224Update=yes
+else
+ ac_cv_lib_md_SHA224Update=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_md_SHA224Update" >&5
+$as_echo "$ac_cv_lib_md_SHA224Update" >&6; }
+if test "x$ac_cv_lib_md_SHA224Update" = xyes; then :
+
+ $as_echo "#define HAVE_SHA224UPDATE 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the data argument of SHA224Update() is void *" >&5
+$as_echo_n "checking whether the data argument of SHA224Update() is void *... " >&6; }
+if ${sudo_cv_func_sha2_void_ptr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+#include <sha2.h>
+void SHA224Update(SHA2_CTX *context, const void *data, size_t len) {return;}
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ sudo_cv_func_sha2_void_ptr=yes
+else
+ sudo_cv_func_sha2_void_ptr=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_func_sha2_void_ptr" >&5
+$as_echo "$sudo_cv_func_sha2_void_ptr" >&6; }
+ if test $sudo_cv_func_sha2_void_ptr = yes; then
+
+$as_echo "#define SHA2_VOID_PTR 1" >>confdefs.h
+
+ fi
+
+ LIBMD="-lmd"
+
+else
+
+ # Does not have SHA224Update
+ FOUND_SHA2=no
+
+fi
+
+
+fi
+done
+
+
+fi
+
+
+ if test X"$FOUND_SHA2" = X"no"; then
+ case " $LIBOBJS " in
+ *" sha2.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS sha2.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_SHA224Final sudo_SHA224Init sudo_SHA224Pad sudo_SHA224Transform sudo_SHA224Update sudo_SHA256Final sudo_SHA256Init sudo_SHA256Pad sudo_SHA256Transform sudo_SHA256Update sudo_SHA384Final sudo_SHA384Init sudo_SHA384Pad sudo_SHA384Transform sudo_SHA384Update sudo_SHA512Final sudo_SHA512Init sudo_SHA512Pad sudo_SHA512Transform sudo_SHA512Update; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ fi
+fi
+for ac_func in vsyslog
+do :
+ ac_fn_c_check_func "$LINENO" "vsyslog" "ac_cv_func_vsyslog"
+if test "x$ac_cv_func_vsyslog" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_VSYSLOG 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" vsyslog.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS vsyslog.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_vsyslog; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }vsyslog_test"
+
+fi
+done
+
+for ac_func in setpassent setgroupent
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+if test X"$with_noexec" != X"no"; then
+ # Check for non-standard exec functions
+ for ac_func in exect execvP execvpe
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ # Check for posix_spawn, and posix_spawnp
+ if test X"$ac_cv_header_spawn_h" = X"yes"; then
+ for ac_func in posix_spawn posix_spawnp
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+fi
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <$ac_header_dirent>
+int
+main ()
+{
+DIR *d; (void)dirfd(d);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ $as_echo "#define HAVE_DIRFD 1" >>confdefs.h
+
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <$ac_header_dirent>
+int
+main ()
+{
+DIR d; memset(&d, 0, sizeof(d)); return(d.dd_fd);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ $as_echo "#define HAVE_DD_FD 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ac_fn_c_check_member "$LINENO" "struct dirent" "d_type" "ac_cv_member_struct_dirent_d_type" "
+$ac_includes_default
+#include <$ac_header_dirent>
+
+"
+if test "x$ac_cv_member_struct_dirent_d_type" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_DIRENT_D_TYPE 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_member "$LINENO" "struct dirent" "d_namlen" "ac_cv_member_struct_dirent_d_namlen" "
+$ac_includes_default
+#include <$ac_header_dirent>
+
+"
+if test "x$ac_cv_member_struct_dirent_d_namlen" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_DIRENT_D_NAMLEN 1
+_ACEOF
+
+
+fi
+
+OLIBS="$LIBS"
+LIBS="${LIBS} ${NET_LIBS}"
+ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket"
+if test "x$ac_cv_func_socket" = xyes; then :
+
+else
+
+ for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+ _libs=
+ for lib in $libs; do
+ case "$NET_LIBS" in
+ *"$lib"*) ;;
+ *) _libs="$_libs $lib";;
+ esac
+ done
+ libs="${_libs# }"
+ test -z "$libs" && continue
+ lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+ extralibs="`echo \"$libs\"|sed 's/^-l[^ ]*//'`"
+
+ _sudo_check_lib_extras=`echo "$extralibs"|sed -e 's/ *//g' -e 's/-l/_/g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -l$lib${5+ }$extralibs" >&5
+$as_echo_n "checking for socket in -l$lib${5+ }$extralibs... " >&6; }
+ if { as_var=sudo_cv_lib_$lib''_socket$_sudo_check_lib_extras; eval \${$as_var+:} false; }; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ SUDO_CHECK_LIB_OLIBS="$LIBS"
+ LIBS="$LIBS -l$lib${5+ }$extralibs"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval sudo_cv_lib_$lib''_socket$_sudo_check_lib_extras=yes
+else
+ eval sudo_cv_lib_$lib''_socket$_sudo_check_lib_extras=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$SUDO_CHECK_LIB_OLIBS"
+
+fi
+
+ if eval test \$sudo_cv_lib_$lib''_socket$_sudo_check_lib_extras = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ NET_LIBS="${NET_LIBS} $libs"; break
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+ fi
+
+ done
+
+fi
+
+LIBS="$OLIBS"
+OLIBS="$LIBS"
+LIBS="${LIBS} ${NET_LIBS}"
+found=false
+INET_PTON_LIBS=
+ac_fn_c_check_func "$LINENO" "inet_pton" "ac_cv_func_inet_pton"
+if test "x$ac_cv_func_inet_pton" = xyes; then :
+
+ found=true
+ $as_echo "#define HAVE_INET_PTON 1" >>confdefs.h
+
+
+else
+
+ for libs in "-lsocket" "-linet" "-lsocket -lnsl" "-lresolv"; do
+ _libs=
+ for lib in $libs; do
+ case "$NET_LIBS" in
+ *"$lib"*) ;;
+ *) _libs="$_libs $lib";;
+ esac
+ done
+ libs="${_libs# }"
+ test -z "$libs" && continue
+ lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+ extralibs="`echo \"$libs\"|sed 's/^-l[^ ]*//'`"
+
+ _sudo_check_lib_extras=`echo "$extralibs"|sed -e 's/ *//g' -e 's/-l/_/g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_pton in -l$lib${5+ }$extralibs" >&5
+$as_echo_n "checking for inet_pton in -l$lib${5+ }$extralibs... " >&6; }
+ if { as_var=sudo_cv_lib_$lib''_inet_pton$_sudo_check_lib_extras; eval \${$as_var+:} false; }; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ SUDO_CHECK_LIB_OLIBS="$LIBS"
+ LIBS="$LIBS -l$lib${5+ }$extralibs"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_pton ();
+int
+main ()
+{
+return inet_pton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval sudo_cv_lib_$lib''_inet_pton$_sudo_check_lib_extras=yes
+else
+ eval sudo_cv_lib_$lib''_inet_pton$_sudo_check_lib_extras=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$SUDO_CHECK_LIB_OLIBS"
+
+fi
+
+ if eval test \$sudo_cv_lib_$lib''_inet_pton$_sudo_check_lib_extras = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+ found=true
+ $as_echo "#define HAVE_INET_PTON 1" >>confdefs.h
+
+ NET_LIBS="${NET_LIBS} $libs"
+ INET_PTON_LIBS="$libs"
+ case "$libs" in
+ *-lresolv*)
+ $as_echo "#define NEED_RESOLV_H 1" >>confdefs.h
+
+ ;;
+ esac
+ break
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+ fi
+
+ done
+
+fi
+
+LIBS="$OLIBS"
+if test X"$found" != X"true"; then
+ case " $LIBOBJS " in
+ *" inet_pton.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS inet_pton.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_inet_pton; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+fi
+OLIBS="$LIBS"
+LIBS="${LIBS} ${NET_LIBS}"
+found=false
+ac_fn_c_check_func "$LINENO" "inet_ntop" "ac_cv_func_inet_ntop"
+if test "x$ac_cv_func_inet_ntop" = xyes; then :
+
+ found=true
+ $as_echo "#define HAVE_INET_NTOP 1" >>confdefs.h
+
+
+else
+
+ for libs in "-lsocket" "-linet" "-lsocket -lnsl" "-lresolv"; do
+ _libs=
+ for lib in $libs; do
+ case "$NET_LIBS" in
+ *"$lib"*) ;;
+ *) _libs="$_libs $lib";;
+ esac
+ done
+ libs="${_libs# }"
+ test -z "$libs" && continue
+ lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+ extralibs="`echo \"$libs\"|sed 's/^-l[^ ]*//'`"
+
+ _sudo_check_lib_extras=`echo "$extralibs"|sed -e 's/ *//g' -e 's/-l/_/g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntop in -l$lib${5+ }$extralibs" >&5
+$as_echo_n "checking for inet_ntop in -l$lib${5+ }$extralibs... " >&6; }
+ if { as_var=sudo_cv_lib_$lib''_inet_ntop$_sudo_check_lib_extras; eval \${$as_var+:} false; }; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ SUDO_CHECK_LIB_OLIBS="$LIBS"
+ LIBS="$LIBS -l$lib${5+ }$extralibs"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntop ();
+int
+main ()
+{
+return inet_ntop ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval sudo_cv_lib_$lib''_inet_ntop$_sudo_check_lib_extras=yes
+else
+ eval sudo_cv_lib_$lib''_inet_ntop$_sudo_check_lib_extras=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$SUDO_CHECK_LIB_OLIBS"
+
+fi
+
+ if eval test \$sudo_cv_lib_$lib''_inet_ntop$_sudo_check_lib_extras = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+ found=true
+ $as_echo "#define HAVE_INET_NTOP 1" >>confdefs.h
+
+ NET_LIBS="${NET_LIBS} $libs"
+ break
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+ fi
+
+ done
+
+fi
+
+LIBS="$OLIBS"
+if test X"$found" != X"true"; then
+ case " $LIBOBJS " in
+ *" inet_ntop.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS inet_ntop.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_inet_ntop; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+fi
+OLIBS="$LIBS"
+LIBS="${LIBS} ${NET_LIBS}"
+ac_fn_c_check_func "$LINENO" "syslog" "ac_cv_func_syslog"
+if test "x$ac_cv_func_syslog" = xyes; then :
+
+else
+
+ for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+ _libs=
+ for lib in $libs; do
+ case "$NET_LIBS" in
+ *"$lib"*) ;;
+ *) _libs="$_libs $lib";;
+ esac
+ done
+ libs="${_libs# }"
+ test -z "$libs" && continue
+ lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+ extralibs="`echo \"$libs\"|sed 's/^-l[^ ]*//'`"
+
+ _sudo_check_lib_extras=`echo "$extralibs"|sed -e 's/ *//g' -e 's/-l/_/g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for syslog in -l$lib${5+ }$extralibs" >&5
+$as_echo_n "checking for syslog in -l$lib${5+ }$extralibs... " >&6; }
+ if { as_var=sudo_cv_lib_$lib''_syslog$_sudo_check_lib_extras; eval \${$as_var+:} false; }; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ SUDO_CHECK_LIB_OLIBS="$LIBS"
+ LIBS="$LIBS -l$lib${5+ }$extralibs"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char syslog ();
+int
+main ()
+{
+return syslog ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval sudo_cv_lib_$lib''_syslog$_sudo_check_lib_extras=yes
+else
+ eval sudo_cv_lib_$lib''_syslog$_sudo_check_lib_extras=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$SUDO_CHECK_LIB_OLIBS"
+
+fi
+
+ if eval test \$sudo_cv_lib_$lib''_syslog$_sudo_check_lib_extras = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ NET_LIBS="${NET_LIBS} $libs"; break
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+ fi
+
+ done
+
+fi
+
+LIBS="$OLIBS"
+#
+# Check for getaddrinfo and add any required libs to NET_LIBS.
+# If it was added to LIBOBJS we need to export the symbols.
+#
+OLIBS="$LIBS"
+GETADDRINFO_LIBS=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo" >&5
+$as_echo_n "checking for getaddrinfo... " >&6; }
+if ${ax_cv_func_getaddrinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+int main() { return getaddrinfo(0, 0, 0, 0); }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_cv_func_getaddrinfo=yes
+else
+ ax_cv_func_getaddrinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_func_getaddrinfo" >&5
+$as_echo "$ax_cv_func_getaddrinfo" >&6; }
+if test X"$ax_cv_func_getaddrinfo" = X"yes"; then
+
+$as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
+
+else
+ # Not found in libc, check libsocket and libinet
+ _found=no
+ for _libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+ _cv="ax_cv_lib_getaddrinfo`echo \"$_libs\"|sed -e 's/-l/_/g' -e 's/ *//g'`"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in $_libs" >&5
+$as_echo_n "checking for getaddrinfo in $_libs... " >&6; }
+ if eval \${$_cv+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ _nlibs=
+ for _l in $_libs; do
+ case "$LIBS" in
+ *"$_l"*) ;;
+ *) _nlibs="$_nlibs $_l";;
+ esac
+ done
+ _libs="${_nlibs# }"
+ if test -z "$_libs"; then
+ # No new libs to check
+ eval $_cv=no
+ else
+ AX_FUNC_GETADDRINFO_OLIBS="$LIBS"
+ LIBS="$LIBS $_libs"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netdb.h>
+ int main() { return getaddrinfo(0, 0, 0, 0); }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval $_cv=yes
+else
+ eval $_cv=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$AX_FUNC_GETADDRINFO_OLIBS"
+ fi
+
+fi
+
+ if eval test \$$_cv = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
+
+ test -n "$_libs" && LIBS="$LIBS $_libs"
+ break
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ done
+ if eval test \$$_cv != "yes"; then
+ case " $LIBOBJS " in
+ *" getaddrinfo.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext"
+ ;;
+esac
+
+ fi
+fi
+
+case " $LIBOBJS " in
+ *" getaddrinfo.$ac_objext "* )
+
+ for _sym in sudo_getaddrinfo sudo_freeaddrinfo sudo_gai_strerror; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ # We need libsudo_util to pull in dependent libraries for
+ # inet_pton(), gethostbyname(), and getservbyname()
+ if test -n "${INET_PTON_LIBS}"; then
+ LT_DEP_LIBS="${LT_DEP_LIBS}${LT_DEP_LIBS+ }${INET_PTON_LIBS}"
+ LIBS="${LIBS}${LIBS+ }${INET_PTON_LIBS}"
+ fi
+ ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
+if test "x$ac_cv_func_gethostbyname" = xyes; then :
+
+else
+
+ for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+ _libs=
+ for lib in $libs; do
+ case "$LT_DEP_LIBS" in
+ *"$lib"*) ;;
+ *) _libs="$_libs $lib";;
+ esac
+ done
+ libs="${_libs# }"
+ test -z "$libs" && continue
+ lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+ extralibs="`echo \"$libs\"|sed 's/^-l[^ ]*//'`"
+
+ _sudo_check_lib_extras=`echo "$extralibs"|sed -e 's/ *//g' -e 's/-l/_/g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -l$lib${5+ }$extralibs" >&5
+$as_echo_n "checking for gethostbyname in -l$lib${5+ }$extralibs... " >&6; }
+ if { as_var=sudo_cv_lib_$lib''_gethostbyname$_sudo_check_lib_extras; eval \${$as_var+:} false; }; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ SUDO_CHECK_LIB_OLIBS="$LIBS"
+ LIBS="$LIBS -l$lib${5+ }$extralibs"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval sudo_cv_lib_$lib''_gethostbyname$_sudo_check_lib_extras=yes
+else
+ eval sudo_cv_lib_$lib''_gethostbyname$_sudo_check_lib_extras=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$SUDO_CHECK_LIB_OLIBS"
+
+fi
+
+ if eval test \$sudo_cv_lib_$lib''_gethostbyname$_sudo_check_lib_extras = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ LT_DEP_LIBS="${LT_DEP_LIBS} $libs"; break
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+ fi
+
+ done
+
+fi
+
+ ;;
+ *)
+ for lib in $LIBS; do
+ case "$OLIBS" in
+ *"$lib"*) ;;
+ *) GETADDRINFO_LIBS="${GETADDRINFO_LIBS}${GETADDRINFO_LIBS+ }$lib";;
+ esac
+ done
+ if test -n "${GETADDRINFO_LIBS}"; then
+ # We need libsudo_util to pull in dependent libraries for
+ # gai_strerror()
+ LT_DEP_LIBS="${LT_DEP_LIBS}${LT_DEP_LIBS+ }${GETADDRINFO_LIBS}"
+ LIBS="${LIBS}${LIBS+ }${GETADDRINFO_LIBS}"
+
+ # Add to NET_LIBS if necessary
+ for lib in $GETADDRINFO_LIBS; do
+ case "$NET_LIBS" in
+ *"$lib"*) ;;
+ *) NET_LIBS="${NET_LIBS}${NET_LIBS+ }$lib";;
+ esac
+ done
+ fi
+ ;;
+esac
+LIBS="$OLIBS"
+
+for ac_func in getprogname
+do :
+ ac_fn_c_check_func "$LINENO" "getprogname" "ac_cv_func_getprogname"
+if test "x$ac_cv_func_getprogname" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETPROGNAME 1
+_ACEOF
+ for ac_func in setprogname
+do :
+ ac_fn_c_check_func "$LINENO" "setprogname" "ac_cv_func_setprogname"
+if test "x$ac_cv_func_setprogname" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SETPROGNAME 1
+_ACEOF
+
+fi
+done
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __progname" >&5
+$as_echo_n "checking for __progname... " >&6; }
+ if ${sudo_cv___progname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+extern char *__progname; (void)puts(__progname);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ sudo_cv___progname=yes
+else
+ sudo_cv___progname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+
+ if test "$sudo_cv___progname" = "yes"; then
+ $as_echo "#define HAVE___PROGNAME 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv___progname" >&5
+$as_echo "$sudo_cv___progname" >&6; }
+
+ for _sym in sudo_getprogname; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+
+fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __func__" >&5
+$as_echo_n "checking for __func__... " >&6; }
+if ${sudo_cv___func__+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+(void)puts(__func__);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ sudo_cv___func__=yes
+else
+ sudo_cv___func__=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv___func__" >&5
+$as_echo "$sudo_cv___func__" >&6; }
+if test "$sudo_cv___func__" = "yes"; then
+ $as_echo "#define HAVE___FUNC__ 1" >>confdefs.h
+
+elif test -n "$GCC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __FUNCTION__" >&5
+$as_echo_n "checking for __FUNCTION__... " >&6; }
+ if ${sudo_cv___FUNCTION__+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+(void)puts(__FUNCTION__);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ sudo_cv___FUNCTION__=yes
+else
+ sudo_cv___FUNCTION__=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv___FUNCTION__" >&5
+$as_echo "$sudo_cv___FUNCTION__" >&6; }
+ if test "$sudo_cv___FUNCTION__" = "yes"; then
+ $as_echo "#define HAVE___FUNC__ 1" >>confdefs.h
+
+
+$as_echo "#define __func__ __FUNCTION__" >>confdefs.h
+
+ fi
+fi
+
+# gettext() and friends may be located in libc (Linux and Solaris)
+# or in libintl. However, it is possible to have libintl installed
+# even when gettext() is present in libc. In the case of GNU libintl,
+# gettext() will be defined to gettext_libintl in libintl.h.
+# Since gcc prefers /usr/local/include to /usr/include, we need to
+# make sure we use the gettext() that matches the include file.
+if test "$enable_nls" != "no"; then
+ if test "$enable_nls" != "yes"; then
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I${enable_nls}/include "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I\${enable_nls}/include"; } >&5
+ (: CPPFLAGS already contains -I${enable_nls}/include) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I${enable_nls}/include"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I${enable_nls}/include
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+
+
+if ${LDFLAGS+:} false; then :
+
+ case " $LDFLAGS " in #(
+ *" -L$enable_nls/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains -L\$enable_nls/lib"; } >&5
+ (: LDFLAGS already contains -L$enable_nls/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append LDFLAGS " -L$enable_nls/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS\""; } >&5
+ (: LDFLAGS="$LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ LDFLAGS=-L$enable_nls/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS\""; } >&5
+ (: LDFLAGS="$LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${LDFLAGS_R+:} false; then :
+
+ case " $LDFLAGS_R " in #(
+ *" -R$enable_nls/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS_R already contains -R\$enable_nls/lib"; } >&5
+ (: LDFLAGS_R already contains -R$enable_nls/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append LDFLAGS_R " -R$enable_nls/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS_R=\"\$LDFLAGS_R\""; } >&5
+ (: LDFLAGS_R="$LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ LDFLAGS_R=-R$enable_nls/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS_R=\"\$LDFLAGS_R\""; } >&5
+ (: LDFLAGS_R="$LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+ fi
+ OLIBS="$LIBS"
+ for l in "libc" "-lintl" "-lintl -liconv"; do
+ if test "$l" = "libc"; then
+ # If user specified a dir for libintl ignore libc
+ if test "$enable_nls" != "yes"; then
+ continue
+ fi
+ gettext_name=sudo_cv_gettext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gettext" >&5
+$as_echo_n "checking for gettext... " >&6; }
+ else
+ LIBS="$OLIBS $l"
+ gettext_name=sudo_cv_gettext"`echo $l|sed -e 's/ //g' -e 's/-/_/g'`"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gettext in $l" >&5
+$as_echo_n "checking for gettext in $l... " >&6; }
+ fi
+ if eval \${$gettext_name+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <libintl.h>
+int
+main ()
+{
+(void)gettext((char *)0);
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval $gettext_name=yes
+else
+ eval $gettext_name=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+fi
+
+ eval gettext_result="\$$gettext_name"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gettext_result" >&5
+$as_echo "$gettext_result" >&6; }
+ if test "$gettext_result" = "yes"; then
+ for ac_func in ngettext
+do :
+ ac_fn_c_check_func "$LINENO" "ngettext" "ac_cv_func_ngettext"
+if test "x$ac_cv_func_ngettext" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_NGETTEXT 1
+_ACEOF
+
+fi
+done
+
+ break
+ fi
+ done
+ LIBS="$OLIBS"
+
+ if test "$sudo_cv_gettext" = "yes"; then
+ SUDO_NLS=enabled
+ # For Solaris we need links from lang to lang.UTF-8 in localedir
+ case "$host_os" in
+ solaris2*) LOCALEDIR_SUFFIX=".UTF-8";;
+ esac
+ elif test "$sudo_cv_gettext_lintl" = "yes"; then
+ SUDO_NLS=enabled
+ LIBINTL="-lintl"
+ elif test "$sudo_cv_gettext_lintl_liconv" = "yes"; then
+ SUDO_NLS=enabled
+ LIBINTL="-lintl -liconv"
+ fi
+ if test X"$SUDO_NLS" = X"enabled"; then
+ $as_echo "#define HAVE_LIBINTL_H 1" >>confdefs.h
+
+
+ for _sym in sudo_warn_gettext_v1; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ fi
+fi
+
+case "$enable_zlib" in
+ yes)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzdopen in -lz" >&5
+$as_echo_n "checking for gzdopen in -lz... " >&6; }
+if ${ac_cv_lib_z_gzdopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gzdopen ();
+int
+main ()
+{
+return gzdopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_z_gzdopen=yes
+else
+ ac_cv_lib_z_gzdopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzdopen" >&5
+$as_echo "$ac_cv_lib_z_gzdopen" >&6; }
+if test "x$ac_cv_lib_z_gzdopen" = xyes; then :
+
+ for ac_header in zlib.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ZLIB_H 1
+_ACEOF
+ ZLIB="-lz"
+else
+ enable_zlib=builtin
+fi
+
+done
+
+
+fi
+
+ ;;
+ no)
+ ;;
+ system)
+ $as_echo "#define HAVE_ZLIB_H 1" >>confdefs.h
+
+ ZLIB="-lz"
+ ;;
+ static|shared|builtin)
+ # handled below
+ ;;
+ *)
+ $as_echo "#define HAVE_ZLIB_H 1" >>confdefs.h
+
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I${enable_zlib}/include "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I\${enable_zlib}/include"; } >&5
+ (: CPPFLAGS already contains -I${enable_zlib}/include) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I${enable_zlib}/include"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I${enable_zlib}/include
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+
+
+if ${ZLIB+:} false; then :
+
+ case " $ZLIB " in #(
+ *" -L$enable_zlib/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : ZLIB already contains -L\$enable_zlib/lib"; } >&5
+ (: ZLIB already contains -L$enable_zlib/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append ZLIB " -L$enable_zlib/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : ZLIB=\"\$ZLIB\""; } >&5
+ (: ZLIB="$ZLIB") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ ZLIB=-L$enable_zlib/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : ZLIB=\"\$ZLIB\""; } >&5
+ (: ZLIB="$ZLIB") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${ZLIB_R+:} false; then :
+
+ case " $ZLIB_R " in #(
+ *" -R$enable_zlib/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : ZLIB_R already contains -R\$enable_zlib/lib"; } >&5
+ (: ZLIB_R already contains -R$enable_zlib/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append ZLIB_R " -R$enable_zlib/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : ZLIB_R=\"\$ZLIB_R\""; } >&5
+ (: ZLIB_R="$ZLIB_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ ZLIB_R=-R$enable_zlib/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : ZLIB_R=\"\$ZLIB_R\""; } >&5
+ (: ZLIB_R="$ZLIB_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+ ZLIB="${ZLIB} -lz"
+ ;;
+esac
+case "$enable_zlib" in
+ builtin|static|dynamic)
+ $as_echo "#define HAVE_ZLIB_H 1" >>confdefs.h
+
+ # XXX - can't use AX_APPEND_FLAG due to use of $(top_foo) and quoting
+ CPPFLAGS='-I$(top_builddir)/lib/zlib -I$(top_srcdir)/lib/zlib '"${CPPFLAGS}"
+ ZLIB="${ZLIB}"' $(top_builddir)/lib/zlib/libsudo_z.la'
+ ZLIB_SRC=lib/zlib
+ ac_config_headers="$ac_config_headers lib/zlib/zconf.h"
+
+ ac_config_files="$ac_config_files lib/zlib/Makefile"
+
+ if test X"$enable_shared" = X"no" -o "$enable_zlib" = "static"; then
+ if test "$enable_zlib" = "shared"; then
+ as_fn_error $? "\"Unable to build shared libraries on this system\"" "$LINENO" 5
+ fi
+ # Build as convenience library
+ ZLIB_LDFLAGS=-no-install
+ fi
+ ;;
+esac
+
+ac_fn_c_check_decl "$LINENO" "errno" "ac_cv_have_decl_errno" "
+$ac_includes_default
+#include <errno.h>
+
+"
+if test "x$ac_cv_have_decl_errno" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ERRNO $ac_have_decl
+_ACEOF
+
+
+ac_fn_c_check_decl "$LINENO" "h_errno" "ac_cv_have_decl_h_errno" "
+$ac_includes_default
+#include <netdb.h>
+
+"
+if test "x$ac_cv_have_decl_h_errno" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_H_ERRNO $ac_have_decl
+_ACEOF
+
+
+ac_fn_c_check_decl "$LINENO" "LLONG_MAX" "ac_cv_have_decl_LLONG_MAX" "
+#include <sys/types.h>
+#include <limits.h>
+
+"
+if test "x$ac_cv_have_decl_LLONG_MAX" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_LLONG_MAX $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "LLONG_MIN" "ac_cv_have_decl_LLONG_MIN" "
+#include <sys/types.h>
+#include <limits.h>
+
+"
+if test "x$ac_cv_have_decl_LLONG_MIN" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_LLONG_MIN $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "ULLONG_MAX" "ac_cv_have_decl_ULLONG_MAX" "
+#include <sys/types.h>
+#include <limits.h>
+
+"
+if test "x$ac_cv_have_decl_ULLONG_MAX" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ULLONG_MAX $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "PATH_MAX" "ac_cv_have_decl_PATH_MAX" "
+#include <sys/types.h>
+#include <limits.h>
+
+"
+if test "x$ac_cv_have_decl_PATH_MAX" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_PATH_MAX $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "SIZE_MAX" "ac_cv_have_decl_SIZE_MAX" "
+#include <sys/types.h>
+#include <limits.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+
+"
+if test "x$ac_cv_have_decl_SIZE_MAX" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SIZE_MAX $ac_have_decl
+_ACEOF
+
+if test "$ac_cv_have_decl_LLONG_MAX" != "yes"; then
+ ac_fn_c_check_decl "$LINENO" "QUAD_MAX" "ac_cv_have_decl_QUAD_MAX" "
+#include <sys/types.h>
+#include <limits.h>
+
+"
+if test "x$ac_cv_have_decl_QUAD_MAX" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_QUAD_MAX $ac_have_decl
+_ACEOF
+
+fi
+if test "$ac_cv_have_decl_LLONG_MIN" != "yes"; then
+ ac_fn_c_check_decl "$LINENO" "QUAD_MIN" "ac_cv_have_decl_QUAD_MIN" "
+#include <sys/types.h>
+#include <limits.h>
+
+"
+if test "x$ac_cv_have_decl_QUAD_MIN" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_QUAD_MIN $ac_have_decl
+_ACEOF
+
+fi
+if test "$ac_cv_have_decl_ULLONG_MAX" != "yes"; then
+ ac_fn_c_check_decl "$LINENO" "UQUAD_MAX" "ac_cv_have_decl_UQUAD_MAX" "
+#include <sys/types.h>
+#include <limits.h>
+
+"
+if test "x$ac_cv_have_decl_UQUAD_MAX" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_UQUAD_MAX $ac_have_decl
+_ACEOF
+
+fi
+if test "$ac_cv_have_decl_SIZE_MAX" != "yes"; then
+ ac_fn_c_check_decl "$LINENO" "SIZE_T_MAX" "ac_cv_have_decl_SIZE_T_MAX" "
+#include <sys/types.h>
+#include <limits.h>
+
+"
+if test "x$ac_cv_have_decl_SIZE_T_MAX" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SIZE_T_MAX $ac_have_decl
+_ACEOF
+
+fi
+if test "$ac_cv_have_decl_PATH_MAX" != "yes"; then
+ ac_fn_c_check_decl "$LINENO" "_POSIX_PATH_MAX" "ac_cv_have_decl__POSIX_PATH_MAX" "
+#include <sys/types.h>
+#include <limits.h>
+
+"
+if test "x$ac_cv_have_decl__POSIX_PATH_MAX" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL__POSIX_PATH_MAX $ac_have_decl
+_ACEOF
+
+fi
+
+for ac_func in strsignal
+do :
+ ac_fn_c_check_func "$LINENO" "strsignal" "ac_cv_func_strsignal"
+if test "x$ac_cv_func_strsignal" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRSIGNAL 1
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" strsignal.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS strsignal.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_strsignal; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ HAVE_SIGLIST="false"
+ ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "
+$ac_includes_default
+#include <signal.h>
+
+"
+if test "x$ac_cv_have_decl_sys_siglist" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SYS_SIGLIST $ac_have_decl
+_ACEOF
+if test $ac_have_decl = 1; then :
+
+ HAVE_SIGLIST="true"
+ break
+
+fi
+ac_fn_c_check_decl "$LINENO" "_sys_siglist" "ac_cv_have_decl__sys_siglist" "
+$ac_includes_default
+#include <signal.h>
+
+"
+if test "x$ac_cv_have_decl__sys_siglist" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL__SYS_SIGLIST $ac_have_decl
+_ACEOF
+if test $ac_have_decl = 1; then :
+
+ HAVE_SIGLIST="true"
+ break
+
+fi
+
+ if test "$HAVE_SIGLIST" != "true"; then
+ case " $LIBOBJS " in
+ *" siglist.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS siglist.$ac_objext"
+ ;;
+esac
+
+ fi
+
+fi
+done
+
+
+for ac_func in sig2str
+do :
+ ac_fn_c_check_func "$LINENO" "sig2str" "ac_cv_func_sig2str"
+if test "x$ac_cv_func_sig2str" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SIG2STR 1
+_ACEOF
+
+ ac_fn_c_check_decl "$LINENO" "SIG2STR_MAX" "ac_cv_have_decl_SIG2STR_MAX" "
+# include <signal.h>
+
+"
+if test "x$ac_cv_have_decl_SIG2STR_MAX" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SIG2STR_MAX $ac_have_decl
+_ACEOF
+
+else
+
+ case " $LIBOBJS " in
+ *" sig2str.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS sig2str.$ac_objext"
+ ;;
+esac
+
+
+ for _sym in sudo_sig2str; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+
+ HAVE_SIGNAME="false"
+ ac_fn_c_check_decl "$LINENO" "sys_signame" "ac_cv_have_decl_sys_signame" "
+$ac_includes_default
+#include <signal.h>
+
+"
+if test "x$ac_cv_have_decl_sys_signame" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SYS_SIGNAME $ac_have_decl
+_ACEOF
+if test $ac_have_decl = 1; then :
+
+ HAVE_SIGNAME="true"
+ break
+
+fi
+ac_fn_c_check_decl "$LINENO" "_sys_signame" "ac_cv_have_decl__sys_signame" "
+$ac_includes_default
+#include <signal.h>
+
+"
+if test "x$ac_cv_have_decl__sys_signame" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL__SYS_SIGNAME $ac_have_decl
+_ACEOF
+if test $ac_have_decl = 1; then :
+
+ HAVE_SIGNAME="true"
+ break
+
+fi
+ac_fn_c_check_decl "$LINENO" "sys_sigabbrev" "ac_cv_have_decl_sys_sigabbrev" "
+$ac_includes_default
+#include <signal.h>
+
+"
+if test "x$ac_cv_have_decl_sys_sigabbrev" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SYS_SIGABBREV $ac_have_decl
+_ACEOF
+if test $ac_have_decl = 1; then :
+
+ HAVE_SIGNAME="true"
+ break
+
+fi
+
+ if test "$HAVE_SIGNAME" != "true"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for undeclared sys_sigabbrev" >&5
+$as_echo_n "checking for undeclared sys_sigabbrev... " >&6; }
+if ${sudo_cv_var_sys_sigabbrev+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+extern char **sys_sigabbrev;
+int
+main ()
+{
+return sys_sigabbrev[1];
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ sudo_cv_var_sys_sigabbrev=yes
+else
+ sudo_cv_var_sys_sigabbrev=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_var_sys_sigabbrev" >&5
+$as_echo "$sudo_cv_var_sys_sigabbrev" >&6; }
+ if test "$sudo_cv_var_sys_sigabbrev" = yes; then
+ $as_echo "#define HAVE_SYS_SIGABBREV 1" >>confdefs.h
+
+ else
+ case " $LIBOBJS " in
+ *" signame.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS signame.$ac_objext"
+ ;;
+esac
+
+ fi
+ fi
+
+fi
+done
+
+
+OLIBS="$LIBS"
+LIBS="$LIBS $lt_cv_dlopen_libs"
+for ac_func in dl_iterate_phdr
+do :
+ ac_fn_c_check_func "$LINENO" "dl_iterate_phdr" "ac_cv_func_dl_iterate_phdr"
+if test "x$ac_cv_func_dl_iterate_phdr" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DL_ITERATE_PHDR 1
+_ACEOF
+
+fi
+done
+
+LIBS="$OLIBS"
+
+if test ${with_netsvc-"no"} != "no"; then
+ cat >>confdefs.h <<EOF
+#define _PATH_NETSVC_CONF "${with_netsvc-/etc/netsvc.conf}"
+EOF
+
+ netsvc_conf=${with_netsvc-/etc/netsvc.conf}
+elif test ${with_nsswitch-"yes"} != "no"; then
+ cat >>confdefs.h <<EOF
+#define _PATH_NSSWITCH_CONF "${with_nsswitch-/etc/nsswitch.conf}"
+EOF
+
+ nsswitch_conf=${with_nsswitch-/etc/nsswitch.conf}
+fi
+
+
+if test -z "${AUTH_EXCL}${AUTH_REG}" -a -n "$AUTH_EXCL_DEF"; then
+ for auth in $AUTH_EXCL_DEF; do
+ case $auth in
+ AIX_AUTH) with_aixauth=maybe;;
+ BSD_AUTH) with_bsdauth=maybe;;
+ PAM) with_pam=maybe;;
+ SIA) CHECKSIA=true;;
+ esac
+ done
+fi
+
+if test ${with_pam-"no"} != "no"; then
+ #
+ # Check for pam_start() in libpam first, then for pam_appl.h.
+ #
+ found_pam_lib=no
+ as_ac_Lib=`$as_echo "ac_cv_lib_pam_pam_start$lt_cv_dlopen_libs" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam_start in -lpam" >&5
+$as_echo_n "checking for pam_start in -lpam... " >&6; }
+if eval \${$as_ac_Lib+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpam $lt_cv_dlopen_libs $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pam_start ();
+int
+main ()
+{
+return pam_start ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$as_ac_Lib=yes"
+else
+ eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+ found_pam_lib=yes
+fi
+
+ #
+ # Some PAM implementations (macOS for example) put the PAM headers
+ # in /usr/include/pam instead of /usr/include/security...
+ #
+ found_pam_hdrs=no
+ for ac_header in security/pam_appl.h pam/pam_appl.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ found_pam_hdrs=yes; break
+fi
+
+done
+
+ if test "$found_pam_lib" = "yes" -a "$found_pam_hdrs" = "yes"; then
+ # Found both PAM libs and headers
+ with_pam=yes
+ elif test "$with_pam" = "yes"; then
+ if test "$found_pam_lib" = "no"; then
+ as_fn_error $? "\"--with-pam specified but unable to locate PAM development library.\"" "$LINENO" 5
+ fi
+ if test "$found_pam_hdrs" = "no"; then
+ as_fn_error $? "\"--with-pam specified but unable to locate PAM development headers.\"" "$LINENO" 5
+ fi
+ elif test "$found_pam_lib" != "$found_pam_hdrs"; then
+ if test "$found_pam_lib" = "no"; then
+ as_fn_error $? "\"found PAM headers but no PAM development library; specify --without-pam to build without PAM\"" "$LINENO" 5
+ fi
+ if test "$found_pam_hdrs" = "no"; then
+ as_fn_error $? "\"found PAM library but no PAM development headers; specify --without-pam to build without PAM\"" "$LINENO" 5
+ fi
+ fi
+
+ if test "$with_pam" = "yes"; then
+ # Older PAM implementations lack pam_getenvlist
+ OLIBS="$LIBS"
+ LIBS="$LIBS -lpam $lt_cv_dlopen_libs"
+ for ac_func in pam_getenvlist
+do :
+ ac_fn_c_check_func "$LINENO" "pam_getenvlist" "ac_cv_func_pam_getenvlist"
+if test "x$ac_cv_func_pam_getenvlist" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_PAM_GETENVLIST 1
+_ACEOF
+
+fi
+done
+
+ LIBS="$OLIBS"
+
+ # We already link with -ldl if needed (see LIBDL below)
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lpam"
+ $as_echo "#define HAVE_PAM 1" >>confdefs.h
+
+ AUTH_OBJS="$AUTH_OBJS pam.lo";
+ AUTH_EXCL=PAM
+
+
+# Check whether --with-pam-login was given.
+if test "${with_pam_login+set}" = set; then :
+ withval=$with_pam_login; case $with_pam_login in
+ yes) $as_echo "#define HAVE_PAM_LOGIN 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use PAM login" >&5
+$as_echo_n "checking whether to use PAM login... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ pam_login_service="sudo-i"
+ ;;
+ no) ;;
+ *) as_fn_error $? "\"--with-pam-login does not take an argument.\"" "$LINENO" 5
+ ;;
+ esac
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use PAM session support" >&5
+$as_echo_n "checking whether to use PAM session support... " >&6; }
+ # Check whether --enable-pam_session was given.
+if test "${enable_pam_session+set}" = set; then :
+ enableval=$enable_pam_session; case "$enableval" in
+ yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ $as_echo "#define NO_PAM_SESSION 1" >>confdefs.h
+
+ pam_session=off
+ ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-pam-session: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-pam-session: $enableval" >&2;}
+ ;;
+ esac
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+
+ fi
+fi
+
+if test ${with_aixauth-'no'} != "no"; then
+ for ac_func in authenticate
+do :
+ ac_fn_c_check_func "$LINENO" "authenticate" "ac_cv_func_authenticate"
+if test "x$ac_cv_func_authenticate" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_AUTHENTICATE 1
+_ACEOF
+ with_aixauth=yes
+fi
+done
+
+ if test "${with_aixauth}" = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: using AIX general authentication" >&5
+$as_echo "$as_me: using AIX general authentication" >&6;}
+ $as_echo "#define HAVE_AIXAUTH 1" >>confdefs.h
+
+ AUTH_OBJS="$AUTH_OBJS aix_auth.lo";
+ SUDOERS_LIBS="${SUDOERS_LIBS} -ls"
+ AUTH_EXCL=AIX_AUTH
+ fi
+fi
+
+if test ${with_bsdauth-'no'} != "no"; then
+ ac_fn_c_check_header_mongrel "$LINENO" "bsd_auth.h" "ac_cv_header_bsd_auth_h" "$ac_includes_default"
+if test "x$ac_cv_header_bsd_auth_h" = xyes; then :
+ $as_echo "#define HAVE_BSD_AUTH_H 1" >>confdefs.h
+
+ AUTH_OBJS="$AUTH_OBJS bsdauth.lo"
+ BSDAUTH_USAGE='[-a type] '
+ AUTH_EXCL=BSD_AUTH; BAMAN=1
+else
+ as_fn_error $? "BSD authentication was specified but bsd_auth.h could not be found" "$LINENO" 5
+fi
+
+
+fi
+
+if test ${CHECKSIA-'false'} = "true"; then
+ for ac_func in sia_ses_init
+do :
+ ac_fn_c_check_func "$LINENO" "sia_ses_init" "ac_cv_func_sia_ses_init"
+if test "x$ac_cv_func_sia_ses_init" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SIA_SES_INIT 1
+_ACEOF
+ found=true
+else
+ found=false
+fi
+done
+
+ if test "$found" = "true"; then
+ AUTH_EXCL=SIA
+ AUTH_OBJS="$AUTH_OBJS sia.lo"
+ fi
+fi
+
+if test ${with_fwtk-'no'} != "no"; then
+ if test "$with_fwtk" != "yes"; then
+
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" -L${with_fwtk} "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains -L\${with_fwtk}"; } >&5
+ (: SUDOERS_LDFLAGS already contains -L${with_fwtk}) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " -L${with_fwtk}"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=-L${with_fwtk}
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${SUDOERS_LDFLAGS_R+:} false; then :
+
+ case " $SUDOERS_LDFLAGS_R " in #(
+ *" -R${with_fwtk} "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R already contains -R\${with_fwtk}"; } >&5
+ (: SUDOERS_LDFLAGS_R already contains -R${with_fwtk}) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS_R " -R${with_fwtk}"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS_R=-R${with_fwtk}
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I${with_fwtk} "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I\${with_fwtk}"; } >&5
+ (: CPPFLAGS already contains -I${with_fwtk}) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I${with_fwtk}"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I${with_fwtk}
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ with_fwtk=yes
+ fi
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lauth -lfwall"
+ AUTH_OBJS="$AUTH_OBJS fwtk.lo"
+fi
+
+if test ${with_SecurID-'no'} != "no"; then
+ if test "$with_SecurID" != "yes"; then
+ :
+ elif test -d /usr/ace/examples; then
+ with_SecurID=/usr/ace/examples
+ else
+ with_SecurID=/usr/ace
+ fi
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I${with_SecurID} "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I\${with_SecurID}"; } >&5
+ (: CPPFLAGS already contains -I${with_SecurID}) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I${with_SecurID}"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I${with_SecurID}
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" -L${with_SecurID} "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains -L\${with_SecurID}"; } >&5
+ (: SUDOERS_LDFLAGS already contains -L${with_SecurID}) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " -L${with_SecurID}"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=-L${with_SecurID}
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${SUDOERS_LDFLAGS_R+:} false; then :
+
+ case " $SUDOERS_LDFLAGS_R " in #(
+ *" -R${with_SecurID} "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R already contains -R\${with_SecurID}"; } >&5
+ (: SUDOERS_LDFLAGS_R already contains -R${with_SecurID}) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS_R " -R${with_SecurID}"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS_R=-R${with_SecurID}
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+ SUDOERS_LIBS="${SUDOERS_LIBS} -laceclnt -lpthread"
+ AUTH_OBJS="$AUTH_OBJS securid5.lo";
+fi
+
+
+if test -z "${AUTH_EXCL}" -a -n "$AUTH_DEF"; then
+ for auth in $AUTH_DEF; do
+ case $auth in
+ passwd) : ${with_passwd='maybe'};;
+ esac
+ done
+fi
+
+if test ${with_kerb5-'no'} != "no"; then
+ # Extract the first word of "krb5-config", so it can be a program name with args.
+set dummy krb5-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_KRB5CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$KRB5CONFIG"; then
+ ac_cv_prog_KRB5CONFIG="$KRB5CONFIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_KRB5CONFIG="yes"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_KRB5CONFIG" && ac_cv_prog_KRB5CONFIG=""""
+fi
+fi
+KRB5CONFIG=$ac_cv_prog_KRB5CONFIG
+if test -n "$KRB5CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $KRB5CONFIG" >&5
+$as_echo "$KRB5CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test -n "$KRB5CONFIG"; then
+ $as_echo "#define HAVE_KERB5 1" >>confdefs.h
+
+ AUTH_OBJS="$AUTH_OBJS kerb5.lo"
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" `krb5-config --cflags` "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains \`krb5-config --cflags\`"; } >&5
+ (: CPPFLAGS already contains `krb5-config --cflags`) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " `krb5-config --cflags`"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=`krb5-config --cflags`
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ SUDOERS_LIBS="$SUDOERS_LIBS `krb5-config --libs`"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using Heimdal" >&5
+$as_echo_n "checking whether we are using Heimdal... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <krb5.h>
+int
+main ()
+{
+const char *tmp = heimdal_version;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ $as_echo "#define HAVE_HEIMDAL 1" >>confdefs.h
+
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ else
+ $as_echo "#define HAVE_KERB5 1" >>confdefs.h
+
+ if test "$with_kerb5" = "yes"; then
+ found=no
+ O_CPPFLAGS="$CPPFLAGS"
+ for dir in "" "kerberosV/" "krb5/" "kerberos5/" "kerberosv5/"; do
+ CPPFLAGS="$O_CPPFLAGS -I/usr/include/${dir}"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <krb5.h>
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ found=yes; break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+ done
+ if test X"$found" = X"no"; then
+ CPPFLAGS="$O_CPPFLAGS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to locate Kerberos V include files, you will have to edit the Makefile and add -I/path/to/krb/includes to CPPFLAGS" >&5
+$as_echo "$as_me: WARNING: Unable to locate Kerberos V include files, you will have to edit the Makefile and add -I/path/to/krb/includes to CPPFLAGS" >&2;}
+ fi
+ else
+
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" -L${with_kerb5}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains -L\${with_kerb5}/lib"; } >&5
+ (: SUDOERS_LDFLAGS already contains -L${with_kerb5}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " -L${with_kerb5}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=-L${with_kerb5}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${SUDOERS_LDFLAGS_R+:} false; then :
+
+ case " $SUDOERS_LDFLAGS_R " in #(
+ *" -R${with_kerb5}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R already contains -R\${with_kerb5}/lib"; } >&5
+ (: SUDOERS_LDFLAGS_R already contains -R${with_kerb5}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS_R " -R${with_kerb5}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS_R=-R${with_kerb5}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I${with_kerb5}/include "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I\${with_kerb5}/include"; } >&5
+ (: CPPFLAGS already contains -I${with_kerb5}/include) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I${with_kerb5}/include"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I${with_kerb5}/include
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using Heimdal" >&5
+$as_echo_n "checking whether we are using Heimdal... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <krb5.h>
+int
+main ()
+{
+const char *tmp = heimdal_version;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ $as_echo "#define HAVE_HEIMDAL 1" >>confdefs.h
+
+ # XXX - need to check whether -lcrypo is needed!
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lkrb5 -lcrypto -ldes -lcom_err -lasn1"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lroken" >&5
+$as_echo_n "checking for main in -lroken... " >&6; }
+if ${ac_cv_lib_roken_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lroken $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_roken_main=yes
+else
+ ac_cv_lib_roken_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_roken_main" >&5
+$as_echo "$ac_cv_lib_roken_main" >&6; }
+if test "x$ac_cv_lib_roken_main" = xyes; then :
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lroken"
+fi
+
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lkrb5 -lk5crypto -lcom_err"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lkrb5support" >&5
+$as_echo_n "checking for main in -lkrb5support... " >&6; }
+if ${ac_cv_lib_krb5support_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5support $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5support_main=yes
+else
+ ac_cv_lib_krb5support_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_krb5support_main" >&5
+$as_echo "$ac_cv_lib_krb5support_main" >&6; }
+if test "x$ac_cv_lib_krb5support_main" = xyes; then :
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lkrb5support"
+fi
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ AUTH_OBJS="$AUTH_OBJS kerb5.lo"
+ fi
+ _LIBS="$LIBS"
+ LIBS="${LIBS} ${SUDOERS_LIBS}"
+ for ac_func in krb5_verify_user krb5_init_secure_context
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ for ac_func in krb5_get_init_creds_opt_alloc
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_get_init_creds_opt_alloc" "ac_cv_func_krb5_get_init_creds_opt_alloc"
+if test "x$ac_cv_func_krb5_get_init_creds_opt_alloc" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC 1
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether krb5_get_init_creds_opt_free takes a context" >&5
+$as_echo_n "checking whether krb5_get_init_creds_opt_free takes a context... " >&6; }
+if ${sudo_cv_krb5_get_init_creds_opt_free_two_args+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <krb5.h>
+int
+main ()
+{
+krb5_get_init_creds_opt_free(NULL, NULL);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ sudo_cv_krb5_get_init_creds_opt_free_two_args=yes
+else
+ sudo_cv_krb5_get_init_creds_opt_free_two_args=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_krb5_get_init_creds_opt_free_two_args" >&5
+$as_echo "$sudo_cv_krb5_get_init_creds_opt_free_two_args" >&6; }
+
+fi
+done
+
+ if test X"$sudo_cv_krb5_get_init_creds_opt_free_two_args" = X"yes"; then
+ $as_echo "#define HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_TWO_ARGS 1" >>confdefs.h
+
+ fi
+ LIBS="$_LIBS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use an instance name for Kerberos V" >&5
+$as_echo_n "checking whether to use an instance name for Kerberos V... " >&6; }
+ # Check whether --enable-kerb5-instance was given.
+if test "${enable_kerb5_instance+set}" = set; then :
+ enableval=$enable_kerb5_instance; case "$enableval" in
+ yes) as_fn_error $? "\"must give --enable-kerb5-instance an argument.\"" "$LINENO" 5
+ ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ *) cat >>confdefs.h <<EOF
+#define SUDO_KRB5_INSTANCE "$enableval"
+EOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
+$as_echo "$enableval" >&6; }
+ ;;
+ esac
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+fi
+
+if test ${with_AFS-'no'} = "yes"; then
+
+ # looks like the "standard" place for AFS libs is /usr/afsws/lib
+ AFSLIBDIRS="/usr/lib/afs /usr/afsws/lib /usr/afsws/lib/afs"
+ for i in $AFSLIBDIRS; do
+ if test -d ${i}; then
+
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" -L$i "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains -L\$i"; } >&5
+ (: SUDOERS_LDFLAGS already contains -L$i) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " -L$i"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=-L$i
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${SUDOERS_LDFLAGS_R+:} false; then :
+
+ case " $SUDOERS_LDFLAGS_R " in #(
+ *" -R$i "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R already contains -R\$i"; } >&5
+ (: SUDOERS_LDFLAGS_R already contains -R$i) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS_R " -R$i"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS_R=-R$i
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+ FOUND_AFSLIBDIR=true
+ fi
+ done
+ if test -z "$FOUND_AFSLIBDIR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to locate AFS libraries, you will have to edit the Makefile and add -L/path/to/afs/libs to SUDOERS_LDFLAGS or rerun configure with the --with-libpath options." >&5
+$as_echo "$as_me: WARNING: Unable to locate AFS libraries, you will have to edit the Makefile and add -L/path/to/afs/libs to SUDOERS_LDFLAGS or rerun configure with the --with-libpath options." >&2;}
+ fi
+
+ # Order is important here. Note that we build AFS_LIBS from right to left
+ # since AFS_LIBS may be initialized with BSD compat libs that must go last
+ AFS_LIBS="-laudit ${AFS_LIBS}"
+ for i in $AFSLIBDIRS; do
+ if test -f ${i}/util.a; then
+ AFS_LIBS="${i}/util.a ${AFS_LIBS}"
+ FOUND_UTIL_A=true
+ break;
+ fi
+ done
+ if test -z "$FOUND_UTIL_A"; then
+ AFS_LIBS="-lutil ${AFS_LIBS}"
+ fi
+ AFS_LIBS="-lkauth -lprot -lubik -lauth -lrxkad -lsys -ldes -lrx -llwp -lcom_err ${AFS_LIBS}"
+
+ # AFS includes may live in /usr/include on some machines...
+ for i in /usr/afsws/include; do
+ if test -d ${i}; then
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I${i} "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I\${i}"; } >&5
+ (: CPPFLAGS already contains -I${i}) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I${i}"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I${i}
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ FOUND_AFSINCDIR=true
+ fi
+ done
+
+ if test -z "$FOUND_AFSLIBDIR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to locate AFS include dir, you may have to edit the Makefile and add -I/path/to/afs/includes to CPPFLAGS or rerun configure with the --with-incpath options." >&5
+$as_echo "$as_me: WARNING: Unable to locate AFS include dir, you may have to edit the Makefile and add -I/path/to/afs/includes to CPPFLAGS or rerun configure with the --with-incpath options." >&2;}
+ fi
+
+ AUTH_OBJS="$AUTH_OBJS afs.lo"
+fi
+
+if test ${with_DCE-'no'} = "yes"; then
+ DCE_OBJS="${DCE_OBJS} dce_pwent.o"
+ SUDOERS_LIBS="${SUDOERS_LIBS} -ldce"
+ AUTH_OBJS="$AUTH_OBJS dce.lo"
+fi
+
+if test "${with_skey-'no'}" = "yes"; then
+ O_LDFLAGS="$LDFLAGS"
+ if test "$with_skey" != "yes"; then
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I${with_skey}/include "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I\${with_skey}/include"; } >&5
+ (: CPPFLAGS already contains -I${with_skey}/include) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I${with_skey}/include"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I${with_skey}/include
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ LDFLAGS="$LDFLAGS -L${with_skey}/lib"
+
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" -L${with_skey}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains -L\${with_skey}/lib"; } >&5
+ (: SUDOERS_LDFLAGS already contains -L${with_skey}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " -L${with_skey}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=-L${with_skey}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${SUDOERS_LDFLAGS_R+:} false; then :
+
+ case " $SUDOERS_LDFLAGS_R " in #(
+ *" -R${with_skey}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R already contains -R\${with_skey}/lib"; } >&5
+ (: SUDOERS_LDFLAGS_R already contains -R${with_skey}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS_R " -R${with_skey}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS_R=-R${with_skey}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+ ac_fn_c_check_header_compile "$LINENO" "skey.h" "ac_cv_header_skey_h" "#include <stdio.h>
+"
+if test "x$ac_cv_header_skey_h" = xyes; then :
+ found=yes
+else
+ found=no
+fi
+
+
+ else
+ found=no
+ O_CPPFLAGS="$CPPFLAGS"
+ for dir in "" "/usr/local" "/usr/contrib"; do
+ test -n "$dir" && CPPFLAGS="$O_CPPFLAGS -I${dir}/include"
+ ac_fn_c_check_header_compile "$LINENO" "skey.h" "ac_cv_header_skey_h" "#include <stdio.h>
+"
+if test "x$ac_cv_header_skey_h" = xyes; then :
+ found=yes; break
+fi
+
+
+ done
+ if test "$found" = "no" -o -z "$dir"; then
+ CPPFLAGS="$O_CPPFLAGS"
+ else
+ LDFLAGS="$LDFLAGS -L${dir}/lib"
+
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" -L${dir}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains -L\${dir}/lib"; } >&5
+ (: SUDOERS_LDFLAGS already contains -L${dir}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " -L${dir}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=-L${dir}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${SUDOERS_LDFLAGS_R+:} false; then :
+
+ case " $SUDOERS_LDFLAGS_R " in #(
+ *" -R${dir}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R already contains -R\${dir}/lib"; } >&5
+ (: SUDOERS_LDFLAGS_R already contains -R${dir}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS_R " -R${dir}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS_R=-R${dir}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+ fi
+ if test "$found" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to locate skey.h, you will have to edit the Makefile and add -I/path/to/skey/includes to CPPFLAGS" >&5
+$as_echo "$as_me: WARNING: Unable to locate skey.h, you will have to edit the Makefile and add -I/path/to/skey/includes to CPPFLAGS" >&2;}
+ fi
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lskey" >&5
+$as_echo_n "checking for main in -lskey... " >&6; }
+if ${ac_cv_lib_skey_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lskey $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_skey_main=yes
+else
+ ac_cv_lib_skey_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_skey_main" >&5
+$as_echo "$ac_cv_lib_skey_main" >&6; }
+if test "x$ac_cv_lib_skey_main" = xyes; then :
+ found=yes
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to locate libskey.a, you will have to edit the Makefile and add -L/path/to/skey/lib to SUDOERS_LDFLAGS" >&5
+$as_echo "$as_me: WARNING: Unable to locate libskey.a, you will have to edit the Makefile and add -L/path/to/skey/lib to SUDOERS_LDFLAGS" >&2;}
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for skeyaccess in -lskey" >&5
+$as_echo_n "checking for skeyaccess in -lskey... " >&6; }
+if ${ac_cv_lib_skey_skeyaccess+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lskey $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char skeyaccess ();
+int
+main ()
+{
+return skeyaccess ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_skey_skeyaccess=yes
+else
+ ac_cv_lib_skey_skeyaccess=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_skey_skeyaccess" >&5
+$as_echo "$ac_cv_lib_skey_skeyaccess" >&6; }
+if test "x$ac_cv_lib_skey_skeyaccess" = xyes; then :
+ $as_echo "#define HAVE_SKEYACCESS 1" >>confdefs.h
+
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for RFC1938-compliant skeychallenge" >&5
+$as_echo_n "checking for RFC1938-compliant skeychallenge... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# include <stdio.h>
+# include <skey.h>
+int
+main ()
+{
+skeychallenge(NULL, NULL, NULL, 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ $as_echo "#define HAVE_RFC1938_SKEYCHALLENGE 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ LDFLAGS="$O_LDFLAGS"
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lskey"
+ AUTH_OBJS="$AUTH_OBJS rfc1938.lo"
+fi
+
+if test "${with_opie-'no'}" = "yes"; then
+ O_LDFLAGS="$LDFLAGS"
+ if test "$with_opie" != "yes"; then
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I${with_opie}/include "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I\${with_opie}/include"; } >&5
+ (: CPPFLAGS already contains -I${with_opie}/include) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I${with_opie}/include"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I${with_opie}/include
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ LDFLAGS="$LDFLAGS -L${with_opie}/lib"
+
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" -L${with_opie}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains -L\${with_opie}/lib"; } >&5
+ (: SUDOERS_LDFLAGS already contains -L${with_opie}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " -L${with_opie}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=-L${with_opie}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${SUDOERS_LDFLAGS_R+:} false; then :
+
+ case " $SUDOERS_LDFLAGS_R " in #(
+ *" -R${with_opie}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R already contains -R\${with_opie}/lib"; } >&5
+ (: SUDOERS_LDFLAGS_R already contains -R${with_opie}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS_R " -R${with_opie}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS_R=-R${with_opie}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <opie.h>
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ found=yes
+else
+ found=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+ else
+ found=no
+ O_CPPFLAGS="$CPPFLAGS"
+ for dir in "" "/usr/local" "/usr/contrib"; do
+ test -n "$dir" && CPPFLAGS="$O_CPPFLAGS -I${dir}/include"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <opie.h>
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ found=yes; break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+ done
+ if test "$found" = "no" -o -z "$dir"; then
+ CPPFLAGS="$O_CPPFLAGS"
+ else
+ LDFLAGS="$LDFLAGS -L${dir}/lib"
+
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" -L${dir}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains -L\${dir}/lib"; } >&5
+ (: SUDOERS_LDFLAGS already contains -L${dir}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " -L${dir}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=-L${dir}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${SUDOERS_LDFLAGS_R+:} false; then :
+
+ case " $SUDOERS_LDFLAGS_R " in #(
+ *" -R${dir}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R already contains -R\${dir}/lib"; } >&5
+ (: SUDOERS_LDFLAGS_R already contains -R${dir}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS_R " -R${dir}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS_R=-R${dir}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+ fi
+ if test "$found" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to locate opie.h, you will have to edit the Makefile and add -I/path/to/opie/includes to CPPFLAGS" >&5
+$as_echo "$as_me: WARNING: Unable to locate opie.h, you will have to edit the Makefile and add -I/path/to/opie/includes to CPPFLAGS" >&2;}
+ fi
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lopie" >&5
+$as_echo_n "checking for main in -lopie... " >&6; }
+if ${ac_cv_lib_opie_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lopie $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_opie_main=yes
+else
+ ac_cv_lib_opie_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_opie_main" >&5
+$as_echo "$ac_cv_lib_opie_main" >&6; }
+if test "x$ac_cv_lib_opie_main" = xyes; then :
+ found=yes
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to locate libopie.a, you will have to edit the Makefile and add -L/path/to/opie/lib to SUDOERS_LDFLAGS" >&5
+$as_echo "$as_me: WARNING: Unable to locate libopie.a, you will have to edit the Makefile and add -L/path/to/opie/lib to SUDOERS_LDFLAGS" >&2;}
+fi
+
+ LDFLAGS="$O_LDFLAGS"
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lopie"
+ AUTH_OBJS="$AUTH_OBJS rfc1938.lo"
+fi
+
+if test ${with_passwd-'no'} != "no"; then
+ if test -z "$LIB_CRYPT"; then
+ _LIBS="$LIBS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt" >&5
+$as_echo_n "checking for library containing crypt... " >&6; }
+if ${ac_cv_search_crypt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char crypt ();
+int
+main ()
+{
+return crypt ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' crypt crypt_d ufc; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_crypt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_crypt+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_crypt+:} false; then :
+
+else
+ ac_cv_search_crypt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt" >&5
+$as_echo "$ac_cv_search_crypt" >&6; }
+ac_res=$ac_cv_search_crypt
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ test -n "$ac_lib" && shadow_libs="${shadow_libs} $ac_res"
+fi
+
+ LIBS="$_LIBS"
+ fi
+
+ if test "$CHECKSHADOW" = "true" -a -n "$shadow_funcs"; then
+ _LIBS="$LIBS"
+ LIBS="$LIBS $shadow_libs"
+ found=no
+ for ac_func in $shadow_funcs
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ found=yes
+fi
+done
+
+ if test "$found" = "yes"; then
+ case "$shadow_funcs" in
+ *getprpwnam*) SECUREWARE=1;;
+ esac
+ else
+ shadow_libs=
+ fi
+ CHECKSHADOW=false
+ LIBS="$_LIBS"
+ fi
+ if test "$CHECKSHADOW" = "true"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getspnam" >&5
+$as_echo_n "checking for library containing getspnam... " >&6; }
+if ${ac_cv_search_getspnam+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getspnam ();
+int
+main ()
+{
+return getspnam ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' gen shadow; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_getspnam=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_getspnam+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_getspnam+:} false; then :
+
+else
+ ac_cv_search_getspnam=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_getspnam" >&5
+$as_echo "$ac_cv_search_getspnam" >&6; }
+ac_res=$ac_cv_search_getspnam
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ $as_echo "#define HAVE_GETSPNAM 1" >>confdefs.h
+ CHECKSHADOW=false; test -n "$ac_lib" && shadow_libs="${shadow_libs} $ac_res"
+fi
+
+ fi
+ if test "$CHECKSHADOW" = "true"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getprpwnam" >&5
+$as_echo_n "checking for library containing getprpwnam... " >&6; }
+if ${ac_cv_search_getprpwnam+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getprpwnam ();
+int
+main ()
+{
+return getprpwnam ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' sec security prot; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_getprpwnam=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_getprpwnam+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_getprpwnam+:} false; then :
+
+else
+ ac_cv_search_getprpwnam=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_getprpwnam" >&5
+$as_echo "$ac_cv_search_getprpwnam" >&6; }
+ac_res=$ac_cv_search_getprpwnam
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ $as_echo "#define HAVE_GETPRPWNAM 1" >>confdefs.h
+ CHECKSHADOW=false; SECUREWARE=1; test -n "$ac_lib" && shadow_libs="${shadow_libs} $ac_res"
+fi
+
+ fi
+ if test -n "$shadow_libs"; then
+ # sudoers needs to link with shadow libs for password auth
+ SUDOERS_LIBS="$SUDOERS_LIBS $shadow_libs"
+ fi
+ if test -n "$SECUREWARE"; then
+ _LIBS="$LIBS"
+ LIBS="$LIBS $shadow_libs"
+ for ac_func in bigcrypt
+do :
+ ac_fn_c_check_func "$LINENO" "bigcrypt" "ac_cv_func_bigcrypt"
+if test "x$ac_cv_func_bigcrypt" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_BIGCRYPT 1
+_ACEOF
+
+fi
+done
+
+ AUTH_OBJS="$AUTH_OBJS secureware.lo"
+ # set_auth_parameters() and initprivs() are called from sudo.c
+ for ac_func in set_auth_parameters initprivs
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ test -n "$shadow_libs" && SUDO_LIBS="$SUDO_LIBS $shadow_libs"
+fi
+done
+
+ LIBS="$_LIBS"
+ fi
+fi
+
+if test X"$with_bsm_audit" = X"yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether au_close() takes 4 arguments" >&5
+$as_echo_n "checking whether au_close() takes 4 arguments... " >&6; }
+if ${sudo_cv_func_au_close_solaris11+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+#include <bsm/audit.h>
+#include <bsm/libbsm.h>
+#include <bsm/audit_uevents.h>
+
+int au_close(int d, int keep, au_event_t event, au_emod_t emod) {return 0;}
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ sudo_cv_func_au_close_solaris11=yes
+else
+ sudo_cv_func_au_close_solaris11=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_func_au_close_solaris11" >&5
+$as_echo "$sudo_cv_func_au_close_solaris11" >&6; }
+ if test $sudo_cv_func_au_close_solaris11 = yes; then
+
+$as_echo "#define HAVE_AU_CLOSE_SOLARIS11 1" >>confdefs.h
+
+ fi
+
+fi
+
+if test X"$enable_poll" = X""; then
+ for ac_func in ppoll poll
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ enable_poll=yes; break
+else
+ enable_poll=no
+fi
+done
+
+elif test X"$enable_poll" = X"yes"; then
+ for ac_func in ppoll
+do :
+ ac_fn_c_check_func "$LINENO" "ppoll" "ac_cv_func_ppoll"
+if test "x$ac_cv_func_ppoll" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_PPOLL 1
+_ACEOF
+
+else
+ $as_echo "#define HAVE_POLL 1" >>confdefs.h
+
+fi
+done
+
+fi
+if test "$enable_poll" = "yes"; then
+ COMMON_OBJS="${COMMON_OBJS} event_poll.lo"
+else
+ for ac_func in pselect
+do :
+ ac_fn_c_check_func "$LINENO" "pselect" "ac_cv_func_pselect"
+if test "x$ac_cv_func_pselect" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_PSELECT 1
+_ACEOF
+
+fi
+done
+
+ COMMON_OBJS="${COMMON_OBJS} event_select.lo"
+fi
+
+if test ${with_ldap-'no'} != "no"; then
+ O_LDFLAGS="$LDFLAGS"
+ if test "$with_ldap" != "yes"; then
+
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" -L${with_ldap}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains -L\${with_ldap}/lib"; } >&5
+ (: SUDOERS_LDFLAGS already contains -L${with_ldap}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " -L${with_ldap}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=-L${with_ldap}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ if test X"$enable_rpath" = X"yes"; then
+
+if ${SUDOERS_LDFLAGS_R+:} false; then :
+
+ case " $SUDOERS_LDFLAGS_R " in #(
+ *" -R${with_ldap}/lib "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R already contains -R\${with_ldap}/lib"; } >&5
+ (: SUDOERS_LDFLAGS_R already contains -R${with_ldap}/lib) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS_R " -R${with_ldap}/lib"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS_R=-R${with_ldap}/lib
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS_R=\"\$SUDOERS_LDFLAGS_R\""; } >&5
+ (: SUDOERS_LDFLAGS_R="$SUDOERS_LDFLAGS_R") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+
+ LDFLAGS="$LDFLAGS -L${with_ldap}/lib"
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -I${with_ldap}/include "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -I\${with_ldap}/include"; } >&5
+ (: CPPFLAGS already contains -I${with_ldap}/include) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -I${with_ldap}/include"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-I${with_ldap}/include
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ with_ldap=yes
+ fi
+ SUDOERS_OBJS="${SUDOERS_OBJS} ldap.lo ldap_conf.lo"
+ case "$SUDOERS_OBJS" in
+ *ldap_util.lo*) ;;
+ *) SUDOERS_OBJS="${SUDOERS_OBJS} ldap_util.lo";;
+ esac
+ LDAP=""
+
+ _LIBS="$LIBS"
+ LDAP_LIBS=""
+ IBMLDAP_EXTRA=""
+ found=no
+ # On HP-UX, libibmldap has a hidden dependency on libCsup
+ case "$host_os" in
+ hpux*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lCsup" >&5
+$as_echo_n "checking for main in -lCsup... " >&6; }
+if ${ac_cv_lib_Csup_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lCsup $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_Csup_main=yes
+else
+ ac_cv_lib_Csup_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Csup_main" >&5
+$as_echo "$ac_cv_lib_Csup_main" >&6; }
+if test "x$ac_cv_lib_Csup_main" = xyes; then :
+ IBMLDAP_EXTRA=" -lCsup"
+fi
+;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ldap_init" >&5
+$as_echo_n "checking for library containing ldap_init... " >&6; }
+if ${ac_cv_search_ldap_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ldap_init ();
+int
+main ()
+{
+return ldap_init ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' "ibmldap${IBMLDAP_EXTRA}" "ibmldap -lidsldif${IBMLDAP_EXTRA}" "ldap" "ldap -llber" "ldap -llber -lssl -lcrypto" "ibmldap${IBMLDAP_EXTRA}"; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_ldap_init=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_ldap_init+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_ldap_init+:} false; then :
+
+else
+ ac_cv_search_ldap_init=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ldap_init" >&5
+$as_echo "$ac_cv_search_ldap_init" >&6; }
+ac_res=$ac_cv_search_ldap_init
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+ test "$ac_res" != "none required" && LDAP_LIBS="$ac_res"
+ found=yes
+
+fi
+
+ # If nothing linked, try -lldap and hope for the best
+ if test "$found" = "no"; then
+ LDAP_LIBS="-lldap"
+ fi
+ LIBS="${_LIBS} ${LDAP_LIBS}"
+ OLIBS="$LIBS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lber.h defines LBER_OPT_DEBUG_LEVEL" >&5
+$as_echo_n "checking whether lber.h defines LBER_OPT_DEBUG_LEVEL... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+# include <lber.h>
+int
+main ()
+{
+int opt=LBER_OPT_DEBUG_LEVEL;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ber_set_option" >&5
+$as_echo_n "checking for library containing ber_set_option... " >&6; }
+if ${ac_cv_search_ber_set_option+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ber_set_option ();
+int
+main ()
+{
+return ber_set_option ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' lber; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_ber_set_option=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_ber_set_option+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_ber_set_option+:} false; then :
+
+else
+ ac_cv_search_ber_set_option=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ber_set_option" >&5
+$as_echo "$ac_cv_search_ber_set_option" >&6; }
+ac_res=$ac_cv_search_ber_set_option
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ found=yes
+else
+ found=no
+fi
+
+ if test X"$found" = X"yes" -a X"$LIBS" != X"$OLIBS"; then
+ LDAP_LIBS="$LDAP_LIBS -llber"
+ fi
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lber.h is needed" >&5
+$as_echo_n "checking whether lber.h is needed... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+# include <ldap.h>
+int
+main ()
+{
+(void)ldap_init(0, 0)
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ $as_echo "#define HAVE_LBER_H 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ if test ${enable_sasl-'yes'} = "yes"; then
+ found_sasl_h=no
+ for ac_header in sasl/sasl.h sasl.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+ found_sasl_h=yes
+ for ac_func in ldap_sasl_interactive_bind_s
+do :
+ ac_fn_c_check_func "$LINENO" "ldap_sasl_interactive_bind_s" "ac_cv_func_ldap_sasl_interactive_bind_s"
+if test "x$ac_cv_func_ldap_sasl_interactive_bind_s" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LDAP_SASL_INTERACTIVE_BIND_S 1
+_ACEOF
+
+fi
+done
+
+ break
+
+fi
+
+done
+
+ if test X${enable_sasl} = X"yes"; then
+ if test X"$found_sasl_h" != X"yes"; then
+ as_fn_error $? "\"--enable-sasl specified but unable to locate SASL development headers.\"" "$LINENO" 5
+ fi
+ if test X"$ac_cv_func_ldap_sasl_interactive_bind_s" != X"yes"; then :
+ as_fn_error $? "\"--enable-sasl specified but SASL support is missing in your LDAP library\"" "$LINENO" 5
+ fi
+ fi
+ fi
+ for ac_header in ldap_ssl.h mps/ldap_ssl.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include <ldap.h>
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+
+done
+
+ for ac_func in ldap_initialize ldap_start_tls_s ldapssl_init ldapssl_set_strength ldap_unbind_ext_s ldap_str2dn ldap_create ldap_sasl_bind_s ldap_ssl_init ldap_ssl_client_init ldap_start_tls_s_np
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ for ac_func in ldap_search_ext_s ldap_search_st
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+done
+
+
+ if test X"$check_gss_krb5_ccache_name" = X"yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_krb5_ccache_name in -lgssapi" >&5
+$as_echo_n "checking for gss_krb5_ccache_name in -lgssapi... " >&6; }
+if ${ac_cv_lib_gssapi_gss_krb5_ccache_name+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gss_krb5_ccache_name ();
+int
+main ()
+{
+return gss_krb5_ccache_name ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gssapi_gss_krb5_ccache_name=yes
+else
+ ac_cv_lib_gssapi_gss_krb5_ccache_name=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gssapi_gss_krb5_ccache_name" >&5
+$as_echo "$ac_cv_lib_gssapi_gss_krb5_ccache_name" >&6; }
+if test "x$ac_cv_lib_gssapi_gss_krb5_ccache_name" = xyes; then :
+ $as_echo "#define HAVE_GSS_KRB5_CCACHE_NAME 1" >>confdefs.h
+
+ LDAP_LIBS="${LDAP_LIBS} -lgssapi"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_krb5_ccache_name in -lgssapi_krb5" >&5
+$as_echo_n "checking for gss_krb5_ccache_name in -lgssapi_krb5... " >&6; }
+if ${ac_cv_lib_gssapi_krb5_gss_krb5_ccache_name+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi_krb5 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gss_krb5_ccache_name ();
+int
+main ()
+{
+return gss_krb5_ccache_name ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gssapi_krb5_gss_krb5_ccache_name=yes
+else
+ ac_cv_lib_gssapi_krb5_gss_krb5_ccache_name=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gssapi_krb5_gss_krb5_ccache_name" >&5
+$as_echo "$ac_cv_lib_gssapi_krb5_gss_krb5_ccache_name" >&6; }
+if test "x$ac_cv_lib_gssapi_krb5_gss_krb5_ccache_name" = xyes; then :
+ $as_echo "#define HAVE_GSS_KRB5_CCACHE_NAME 1" >>confdefs.h
+
+ LDAP_LIBS="${LDAP_LIBS} -lgssapi_krb5"
+fi
+
+
+fi
+
+
+ # gssapi headers may be separate or part of Kerberos V
+ found=no
+ O_CPPFLAGS="$CPPFLAGS"
+ for dir in "" "kerberosV" "krb5" "kerberos5" "kerberosv5"; do
+ test X"$dir" != X"" && CPPFLAGS="$O_CPPFLAGS -I/usr/include/${dir}"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <gssapi/gssapi.h>
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ found="gssapi/gssapi.h"; break
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <gssapi.h>
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ found="gssapi.h"; break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+ done
+ if test X"$found" != X"no"; then
+ for ac_header in $found
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ if test X"$found" = X"gssapi/gssapi.h"; then
+ for ac_header in gssapi/gssapi_krb5.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "gssapi/gssapi_krb5.h" "ac_cv_header_gssapi_gssapi_krb5_h" "$ac_includes_default"
+if test "x$ac_cv_header_gssapi_gssapi_krb5_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GSSAPI_GSSAPI_KRB5_H 1
+_ACEOF
+
+fi
+
+done
+
+ fi
+ else
+ CPPFLAGS="$O_CPPFLAGS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to locate gssapi.h, you will have to edit the Makefile and add -I/path/to/gssapi/includes to CPPFLAGS" >&5
+$as_echo "$as_me: WARNING: Unable to locate gssapi.h, you will have to edit the Makefile and add -I/path/to/gssapi/includes to CPPFLAGS" >&2;}
+ fi
+ fi
+
+ SUDOERS_LIBS="${SUDOERS_LIBS} ${LDAP_LIBS}"
+ LIBS="$_LIBS"
+ LDFLAGS="$O_LDFLAGS"
+fi
+
+#
+# How to do dynamic object loading.
+# We support dlopen() and sh_load(), else fall back to static loading.
+#
+case "$lt_cv_dlopen" in
+ dlopen)
+ $as_echo "#define HAVE_DLOPEN 1" >>confdefs.h
+
+ if test "$enable_static_sudoers" = "yes"; then
+ $as_echo "#define STATIC_SUDOERS_PLUGIN 1" >>confdefs.h
+
+ SUDO_OBJS="${SUDO_OBJS} preload.o"
+ STATIC_SUDOERS="\$(top_builddir)/plugins/sudoers/sudoers.la"
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" --tag=disable-shared -static "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains --tag=disable-shared -static"; } >&5
+ (: SUDOERS_LDFLAGS already contains --tag=disable-shared -static) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " --tag=disable-shared -static"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=--tag=disable-shared -static
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ LT_STATIC=""
+ else
+ LT_STATIC="--tag=disable-static"
+ fi
+ ;;
+ shl_load)
+ $as_echo "#define HAVE_SHL_LOAD 1" >>confdefs.h
+
+ if test "$enable_static_sudoers" = "yes"; then
+ $as_echo "#define STATIC_SUDOERS_PLUGIN 1" >>confdefs.h
+
+ SUDO_OBJS="${SUDO_OBJS} preload.o"
+ STATIC_SUDOERS="\$(top_builddir)/plugins/sudoers/sudoers.la"
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" --tag=disable-shared -static "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains --tag=disable-shared -static"; } >&5
+ (: SUDOERS_LDFLAGS already contains --tag=disable-shared -static) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " --tag=disable-shared -static"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=--tag=disable-shared -static
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ LT_STATIC=""
+ else
+ LT_STATIC="--tag=disable-static"
+ fi
+ ;;
+ *)
+ if test X"${ac_cv_func_dlopen}" = X"yes"; then
+ as_fn_error $? "\"dlopen present but libtool doesn't appear to support your platform.\"" "$LINENO" 5
+ fi
+ # Preload sudoers module symbols
+ $as_echo "#define STATIC_SUDOERS_PLUGIN 1" >>confdefs.h
+
+ SUDO_OBJS="${SUDO_OBJS} preload.o"
+ STATIC_SUDOERS="\$(top_builddir)/plugins/sudoers/sudoers.la"
+ LT_STATIC=""
+ ;;
+esac
+
+#
+# The check_symbols test can only succeed with a dynamic sudoers plugin.
+#
+if test X"$STATIC_SUDOERS" = X""; then
+ SUDOERS_TEST_PROGS="${SUDOERS_TEST_PROGS}${SUDOERS_TEST_PROGS+ }check_symbols"
+fi
+
+#
+# We can only disable linking with the shared libsudo_util if
+# sudoers is linked statically too.
+#
+if test "$enable_shared_libutil" = "no"; then
+ if test X"$STATIC_SUDOERS" = X""; then
+ as_fn_error $? "\"--disable-shared-libutil may only be specified with --enable-static-sudoers or when dynamic linking is disabled.\"" "$LINENO" 5
+ else
+ # Do not install sudoers or libsudo_util.
+
+if ${SUDOERS_LDFLAGS+:} false; then :
+
+ case " $SUDOERS_LDFLAGS " in #(
+ *" -no-install "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS already contains -no-install"; } >&5
+ (: SUDOERS_LDFLAGS already contains -no-install) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append SUDOERS_LDFLAGS " -no-install"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ SUDOERS_LDFLAGS=-no-install
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : SUDOERS_LDFLAGS=\"\$SUDOERS_LDFLAGS\""; } >&5
+ (: SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+
+if ${LIBUTIL_LDFLAGS+:} false; then :
+
+ case " $LIBUTIL_LDFLAGS " in #(
+ *" -no-install "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LIBUTIL_LDFLAGS already contains -no-install"; } >&5
+ (: LIBUTIL_LDFLAGS already contains -no-install) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append LIBUTIL_LDFLAGS " -no-install"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LIBUTIL_LDFLAGS=\"\$LIBUTIL_LDFLAGS\""; } >&5
+ (: LIBUTIL_LDFLAGS="$LIBUTIL_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ LIBUTIL_LDFLAGS=-no-install
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LIBUTIL_LDFLAGS=\"\$LIBUTIL_LDFLAGS\""; } >&5
+ (: LIBUTIL_LDFLAGS="$LIBUTIL_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ fi
+fi
+
+# On HP-UX, you cannot dlopen() a shared object that uses pthreads unless
+# the main program is linked against -lpthread. We have no knowledge of
+# what libraries a plugin may depend on (e.g. HP-UX LDAP which uses pthreads)
+# so always link against -lpthread on HP-UX if it is available.
+# This check should go after all other libraries tests.
+case "$host_os" in
+ hpux*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5
+$as_echo_n "checking for main in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread_main=yes
+else
+ ac_cv_lib_pthread_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5
+$as_echo "$ac_cv_lib_pthread_main" >&6; }
+if test "x$ac_cv_lib_pthread_main" = xyes; then :
+ SUDO_LIBS="${SUDO_LIBS} -lpthread"
+fi
+
+ $as_echo "#define _REENTRANT 1" >>confdefs.h
+
+ ;;
+esac
+
+if test "$utmp_style" = "LEGACY"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for utmp file path" >&5
+$as_echo_n "checking for utmp file path... " >&6; }
+found=no
+for p in "/var/run/utmp" "/var/adm/utmp" "/etc/utmp"; do
+ if test -r "$p"; then
+ found=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $p" >&5
+$as_echo "$p" >&6; }
+ cat >>confdefs.h <<EOF
+#define _PATH_UTMP "$p"
+EOF
+
+ break
+ fi
+done
+if test X"$found" != X"yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for log file location" >&5
+$as_echo_n "checking for log file location... " >&6; }
+if test -n "$with_logpath"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_logpath" >&5
+$as_echo "$with_logpath" >&6; }
+ cat >>confdefs.h <<EOF
+#define _PATH_SUDO_LOGFILE "$with_logpath"
+EOF
+
+elif test -d "/var/log"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: /var/log/sudo.log" >&5
+$as_echo "/var/log/sudo.log" >&6; }
+ cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_LOGFILE "/var/log/sudo.log"
+EOF
+
+elif test -d "/var/adm"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: /var/adm/sudo.log" >&5
+$as_echo "/var/adm/sudo.log" >&6; }
+ cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_LOGFILE "/var/adm/sudo.log"
+EOF
+
+elif test -d "/usr/adm"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: /usr/adm/sudo.log" >&5
+$as_echo "/usr/adm/sudo.log" >&6; }
+ cat >>confdefs.h <<\EOF
+#define _PATH_SUDO_LOGFILE "/usr/adm/sudo.log"
+EOF
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5
+$as_echo "unknown" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sudo run dir location" >&5
+$as_echo_n "checking for sudo run dir location... " >&6; }
+rundir="$with_rundir"
+if test -z "$rundir"; then
+ for d in /run /var/run /var/db /var/lib /var/adm /usr/adm; do
+ if test -d "$d"; then
+ rundir="$d/sudo"
+ break
+ fi
+ done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rundir" >&5
+$as_echo "$rundir" >&6; }
+cat >>confdefs.h <<EOF
+#define _PATH_SUDO_TIMEDIR "$rundir/ts"
+EOF
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sudo var dir location" >&5
+$as_echo_n "checking for sudo var dir location... " >&6; }
+vardir="$with_vardir"
+if test -z "$vardir"; then
+ for d in /var/db /var/lib /var/adm /usr/adm; do
+ if test -d "$d"; then
+ vardir="$d/sudo"
+ break
+ fi
+ done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $vardir" >&5
+$as_echo "$vardir" >&6; }
+cat >>confdefs.h <<EOF
+#define _PATH_SUDO_LECTURE_DIR "$vardir/lectured"
+EOF
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for I/O log dir location" >&5
+$as_echo_n "checking for I/O log dir location... " >&6; }
+ if test "${with_iologdir-yes}" != "yes"; then
+ iolog_dir="$with_iologdir"
+ elif test -d "/var/log"; then
+ iolog_dir="/var/log/sudo-io"
+ elif test -d "/var/adm"; then
+ iolog_dir="/var/adm/sudo-io"
+ else
+ iolog_dir="/usr/adm/sudo-io"
+ fi
+ if test "${with_iologdir}" != "no"; then
+ cat >>confdefs.h <<EOF
+#define _PATH_SUDO_IO_LOGDIR "$iolog_dir"
+EOF
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $iolog_dir" >&5
+$as_echo "$iolog_dir" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking time zone data directory" >&5
+$as_echo_n "checking time zone data directory... " >&6; }
+tzdir="$with_tzdir"
+if test -z "$tzdir"; then
+ tzdir=no
+ for d in /usr/share /usr/share/lib /usr/lib /etc; do
+ if test -d "$d/zoneinfo"; then
+ tzdir="$d/zoneinfo"
+ break
+ fi
+ done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tzdir" >&5
+$as_echo "$tzdir" >&6; }
+if test "${tzdir}" != "no"; then
+ cat >>confdefs.h <<EOF
+#define _PATH_ZONEINFO "$tzdir"
+EOF
+
+fi
+
+
+if test "$enable_hardening" != "no"; then
+ O_CPPFLAGS="$CPPFLAGS"
+
+if ${CPPFLAGS+:} false; then :
+
+ case " $CPPFLAGS " in #(
+ *" -D_FORTIFY_SOURCE=2 "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS already contains -D_FORTIFY_SOURCE=2"; } >&5
+ (: CPPFLAGS already contains -D_FORTIFY_SOURCE=2) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append CPPFLAGS " -D_FORTIFY_SOURCE=2"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ CPPFLAGS=-D_FORTIFY_SOURCE=2
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : CPPFLAGS=\"\$CPPFLAGS\""; } >&5
+ (: CPPFLAGS="$CPPFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether _FORTIFY_SOURCE may be specified" >&5
+$as_echo_n "checking whether _FORTIFY_SOURCE may be specified... " >&6; }
+if ${sudo_cv_use_fortify_source+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+char buf[4]; (void)sprintf(buf, "%s", "foo");
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ sudo_cv_use_fortify_source=yes
+else
+ sudo_cv_use_fortify_source=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ sudo_cv_use_fortify_source=yes
+else
+ sudo_cv_use_fortify_source=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_use_fortify_source" >&5
+$as_echo "$sudo_cv_use_fortify_source" >&6; }
+ if test "$sudo_cv_use_fortify_source" != yes; then
+ CPPFLAGS="$O_CPPFLAGS"
+ fi
+fi
+
+
+ac_c_werror_flag=yes
+
+if test -n "$GCC" -a "$lt_cv_prog_gnu_ld" != "yes" -a -n "$GCC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -static-libgcc" >&5
+$as_echo_n "checking whether C compiler accepts -static-libgcc... " >&6; }
+if ${ax_cv_check_cflags___static_libgcc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$CFLAGS
+ CFLAGS="$CFLAGS -static-libgcc"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ax_cv_check_cflags___static_libgcc=yes
+else
+ ax_cv_check_cflags___static_libgcc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___static_libgcc" >&5
+$as_echo "$ax_cv_check_cflags___static_libgcc" >&6; }
+if test x"$ax_cv_check_cflags___static_libgcc" = xyes; then :
+
+if ${LT_LDFLAGS+:} false; then :
+
+ case " $LT_LDFLAGS " in #(
+ *" -Wc,-static-libgcc "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LT_LDFLAGS already contains -Wc,-static-libgcc"; } >&5
+ (: LT_LDFLAGS already contains -Wc,-static-libgcc) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append LT_LDFLAGS " -Wc,-static-libgcc"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LT_LDFLAGS=\"\$LT_LDFLAGS\""; } >&5
+ (: LT_LDFLAGS="$LT_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ LT_LDFLAGS=-Wc,-static-libgcc
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LT_LDFLAGS=\"\$LT_LDFLAGS\""; } >&5
+ (: LT_LDFLAGS="$LT_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+else
+ :
+fi
+
+fi
+
+if test -n "$GCC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fvisibility=hidden" >&5
+$as_echo_n "checking whether C compiler accepts -fvisibility=hidden... " >&6; }
+if ${ax_cv_check_cflags___fvisibility_hidden+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$CFLAGS
+ CFLAGS="$CFLAGS -fvisibility=hidden"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ax_cv_check_cflags___fvisibility_hidden=yes
+else
+ ax_cv_check_cflags___fvisibility_hidden=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fvisibility_hidden" >&5
+$as_echo "$ax_cv_check_cflags___fvisibility_hidden" >&6; }
+if test x"$ax_cv_check_cflags___fvisibility_hidden" = xyes; then :
+
+ $as_echo "#define HAVE_DSO_VISIBILITY 1" >>confdefs.h
+
+ CFLAGS="${CFLAGS} -fvisibility=hidden"
+ LT_LDEXPORTS=
+ LT_LDDEP=
+
+else
+ :
+fi
+
+else
+ case "$host_os" in
+ hpux*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Bhidden_def" >&5
+$as_echo_n "checking whether C compiler accepts -Bhidden_def... " >&6; }
+if ${ax_cv_check_cflags___Bhidden_def+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$CFLAGS
+ CFLAGS="$CFLAGS -Bhidden_def"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ax_cv_check_cflags___Bhidden_def=yes
+else
+ ax_cv_check_cflags___Bhidden_def=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Bhidden_def" >&5
+$as_echo "$ax_cv_check_cflags___Bhidden_def" >&6; }
+if test x"$ax_cv_check_cflags___Bhidden_def" = xyes; then :
+
+ $as_echo "#define HAVE_DSO_VISIBILITY 1" >>confdefs.h
+
+ CFLAGS="${CFLAGS} -Bhidden_def"
+ LT_LDEXPORTS=
+ LT_LDDEP=
+
+else
+ :
+fi
+
+ ;;
+ solaris2*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -xldscope=hidden" >&5
+$as_echo_n "checking whether C compiler accepts -xldscope=hidden... " >&6; }
+if ${ax_cv_check_cflags___xldscope_hidden+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$CFLAGS
+ CFLAGS="$CFLAGS -xldscope=hidden"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ax_cv_check_cflags___xldscope_hidden=yes
+else
+ ax_cv_check_cflags___xldscope_hidden=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___xldscope_hidden" >&5
+$as_echo "$ax_cv_check_cflags___xldscope_hidden" >&6; }
+if test x"$ax_cv_check_cflags___xldscope_hidden" = xyes; then :
+
+ $as_echo "#define HAVE_DSO_VISIBILITY 1" >>confdefs.h
+
+ CFLAGS="${CFLAGS} -xldscope=hidden"
+ LT_LDEXPORTS=
+ LT_LDDEP=
+
+else
+ :
+fi
+
+ ;;
+ esac
+fi
+
+if test -n "$LT_LDEXPORTS"; then
+ if test "$lt_cv_prog_gnu_ld" = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ld supports anonymous map files" >&5
+$as_echo_n "checking whether ld supports anonymous map files... " >&6; }
+if ${sudo_cv_var_gnu_ld_anon_map+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ sudo_cv_var_gnu_ld_anon_map=no
+ cat > conftest.map <<-EOF
+ {
+ global: foo;
+ local: *;
+ };
+EOF
+ _CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $lt_prog_compiler_pic"
+ _LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -fpic -shared -Wl,--version-script,./conftest.map"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo;
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ sudo_cv_var_gnu_ld_anon_map=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$_CFLAGS"
+ LDFLAGS="$_LDFLAGS"
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_var_gnu_ld_anon_map" >&5
+$as_echo "$sudo_cv_var_gnu_ld_anon_map" >&6; }
+ if test "$sudo_cv_var_gnu_ld_anon_map" = "yes"; then
+ LT_LDDEP="\$(shlib_map)"; LT_LDEXPORTS="-Wl,--version-script,\$(shlib_map)"
+ fi
+ else
+ case "$host_os" in
+ solaris2*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ld supports anonymous map files" >&5
+$as_echo_n "checking whether ld supports anonymous map files... " >&6; }
+if ${sudo_cv_var_solaris_ld_anon_map+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ sudo_cv_var_solaris_ld_anon_map=no
+ cat > conftest.map <<-EOF
+ {
+ global: foo;
+ local: *;
+ };
+EOF
+ _CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $lt_prog_compiler_pic"
+ _LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared -Wl,-M,./conftest.map"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo;
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ sudo_cv_var_solaris_ld_anon_map=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$_CFLAGS"
+ LDFLAGS="$_LDFLAGS"
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_var_solaris_ld_anon_map" >&5
+$as_echo "$sudo_cv_var_solaris_ld_anon_map" >&6; }
+ if test "$sudo_cv_var_solaris_ld_anon_map" = "yes"; then
+ LT_LDDEP="\$(shlib_map)"; LT_LDEXPORTS="-Wl,-M,\$(shlib_map)"
+ fi
+ ;;
+ hpux*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ld supports controlling exported symbols" >&5
+$as_echo_n "checking whether ld supports controlling exported symbols... " >&6; }
+if ${sudo_cv_var_hpux_ld_symbol_export+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ sudo_cv_var_hpux_ld_symbol_export=no
+ echo "+e foo" > conftest.opt
+ _CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $lt_prog_compiler_pic"
+ _LDFLAGS="$LDFLAGS"
+ if test -n "$GCC"; then
+ LDFLAGS="$LDFLAGS -shared -Wl,-c,./conftest.opt"
+ else
+ LDFLAGS="$LDFLAGS -Wl,-b -Wl,-c,./conftest.opt"
+ fi
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo;
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ sudo_cv_var_hpux_ld_symbol_export=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$_CFLAGS"
+ LDFLAGS="$_LDFLAGS"
+ rm -f conftest.opt
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_var_hpux_ld_symbol_export" >&5
+$as_echo "$sudo_cv_var_hpux_ld_symbol_export" >&6; }
+ if test "$sudo_cv_var_hpux_ld_symbol_export" = "yes"; then
+ LT_LDDEP="\$(shlib_opt)"; LT_LDEXPORTS="-Wl,-c,\$(shlib_opt)"
+ fi
+ ;;
+ esac
+ fi
+fi
+
+if test "$enable_asan" = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fsanitize=address -fsanitize=undefined" >&5
+$as_echo_n "checking whether C compiler accepts -fsanitize=address -fsanitize=undefined... " >&6; }
+if ${ax_cv_check_cflags___fsanitize_address__fsanitize_undefined+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$CFLAGS
+ CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ax_cv_check_cflags___fsanitize_address__fsanitize_undefined=yes
+else
+ ax_cv_check_cflags___fsanitize_address__fsanitize_undefined=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fsanitize_address__fsanitize_undefined" >&5
+$as_echo "$ax_cv_check_cflags___fsanitize_address__fsanitize_undefined" >&6; }
+if test x"$ax_cv_check_cflags___fsanitize_address__fsanitize_undefined" = xyes; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -fsanitize=address -fsanitize=undefined" >&5
+$as_echo_n "checking whether the linker accepts -fsanitize=address -fsanitize=undefined... " >&6; }
+if ${ax_cv_check_ldflags___fsanitize_address__fsanitize_undefined+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -fsanitize=address -fsanitize=undefined"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_cv_check_ldflags___fsanitize_address__fsanitize_undefined=yes
+else
+ ax_cv_check_ldflags___fsanitize_address__fsanitize_undefined=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___fsanitize_address__fsanitize_undefined" >&5
+$as_echo "$ax_cv_check_ldflags___fsanitize_address__fsanitize_undefined" >&6; }
+if test x"$ax_cv_check_ldflags___fsanitize_address__fsanitize_undefined" = xyes; then :
+
+ ASAN_LDFLAGS="-Wc,-fsanitize=address -Wc,-fsanitize=undefined"
+ ASAN_CFLAGS="-fsanitize=address -fsanitize=undefined"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-omit-frame-pointer" >&5
+$as_echo_n "checking whether C compiler accepts -fno-omit-frame-pointer... " >&6; }
+if ${ax_cv_check_cflags___fno_omit_frame_pointer+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$CFLAGS
+ CFLAGS="$CFLAGS -fno-omit-frame-pointer"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ax_cv_check_cflags___fno_omit_frame_pointer=yes
+else
+ ax_cv_check_cflags___fno_omit_frame_pointer=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fno_omit_frame_pointer" >&5
+$as_echo "$ax_cv_check_cflags___fno_omit_frame_pointer" >&6; }
+if test x"$ax_cv_check_cflags___fno_omit_frame_pointer" = xyes; then :
+
+ CFLAGS="$CFLAGS -fno-omit-frame-pointer"
+
+else
+ :
+fi
+
+ $as_echo "#define NO_LEAKS 1" >>confdefs.h
+
+
+else
+ :
+fi
+
+
+else
+ :
+fi
+
+fi
+
+if test -n "$GCC"; then
+ if test -z "$enable_pie"; then
+ case "$host_os" in
+ linux*)
+ # Attempt to build with PIE support
+ enable_pie="maybe"
+ ;;
+ esac
+ fi
+ if test -n "$enable_pie"; then
+ if test "$enable_pie" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-pie" >&5
+$as_echo_n "checking whether C compiler accepts -fno-pie... " >&6; }
+if ${ax_cv_check_cflags___fno_pie+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$CFLAGS
+ CFLAGS="$CFLAGS -fno-pie"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ax_cv_check_cflags___fno_pie=yes
+else
+ ax_cv_check_cflags___fno_pie=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fno_pie" >&5
+$as_echo "$ax_cv_check_cflags___fno_pie" >&6; }
+if test x"$ax_cv_check_cflags___fno_pie" = xyes; then :
+
+ _CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fno-pie"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -nopie" >&5
+$as_echo_n "checking whether the linker accepts -nopie... " >&6; }
+if ${ax_cv_check_ldflags___nopie+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -nopie"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_cv_check_ldflags___nopie=yes
+else
+ ax_cv_check_ldflags___nopie=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___nopie" >&5
+$as_echo "$ax_cv_check_ldflags___nopie" >&6; }
+if test x"$ax_cv_check_ldflags___nopie" = xyes; then :
+
+ PIE_CFLAGS="-fno-pie"
+ PIE_LDFLAGS="-nopie"
+
+else
+ :
+fi
+
+ CFLAGS="$_CFLAGS"
+
+else
+ :
+fi
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fPIE" >&5
+$as_echo_n "checking whether C compiler accepts -fPIE... " >&6; }
+if ${ax_cv_check_cflags___fPIE+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$CFLAGS
+ CFLAGS="$CFLAGS -fPIE"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ax_cv_check_cflags___fPIE=yes
+else
+ ax_cv_check_cflags___fPIE=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fPIE" >&5
+$as_echo "$ax_cv_check_cflags___fPIE" >&6; }
+if test x"$ax_cv_check_cflags___fPIE" = xyes; then :
+
+ _CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fPIE"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -pie" >&5
+$as_echo_n "checking whether the linker accepts -pie... " >&6; }
+if ${ax_cv_check_ldflags___pie+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -pie"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_cv_check_ldflags___pie=yes
+else
+ ax_cv_check_ldflags___pie=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___pie" >&5
+$as_echo "$ax_cv_check_ldflags___pie" >&6; }
+if test x"$ax_cv_check_ldflags___pie" = xyes; then :
+
+ if test "$enable_pie" = "maybe"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working PIE support" >&5
+$as_echo_n "checking for working PIE support... " >&6; }
+if ${sudo_cv_working_pie+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f conftestdata; > conftestdata
+if test "$cross_compiling" = yes; then :
+ sudo_cv_working_pie=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+main() { char *p = malloc(1024); if (p == NULL) return 1; memset(p, 0, 1024); return 0; }
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ sudo_cv_working_pie=yes
+else
+ sudo_cv_working_pie=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+rm -f core core.* *.core
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_working_pie" >&5
+$as_echo "$sudo_cv_working_pie" >&6; }
+if test $sudo_cv_working_pie = yes; then :
+ enable_pie=yes
+fi
+ fi
+ if test "$enable_pie" = "yes"; then
+ PIE_CFLAGS="-fPIE"
+ PIE_LDFLAGS="-Wc,-fPIE -pie"
+ fi
+
+else
+ :
+fi
+
+ CFLAGS="$_CFLAGS"
+
+else
+ :
+fi
+
+ fi
+ fi
+fi
+if test "$enable_pie" != "yes"; then
+ # Solaris 11.1 and higher supports tagging binaries to use ASLR
+ case "$host_os" in
+ solaris2.1[1-9]|solaris2.[2-9][0-9])
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,-z,aslr" >&5
+$as_echo_n "checking whether the linker accepts -Wl,-z,aslr... " >&6; }
+if ${ax_cv_check_ldflags___Wl__z_aslr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-z,aslr"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_cv_check_ldflags___Wl__z_aslr=yes
+else
+ ax_cv_check_ldflags___Wl__z_aslr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl__z_aslr" >&5
+$as_echo "$ax_cv_check_ldflags___Wl__z_aslr" >&6; }
+if test x"$ax_cv_check_ldflags___Wl__z_aslr" = xyes; then :
+
+if ${PIE_LDFLAGS+:} false; then :
+
+ case " $PIE_LDFLAGS " in #(
+ *" -Wl,-z,aslr "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : PIE_LDFLAGS already contains -Wl,-z,aslr"; } >&5
+ (: PIE_LDFLAGS already contains -Wl,-z,aslr) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append PIE_LDFLAGS " -Wl,-z,aslr"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : PIE_LDFLAGS=\"\$PIE_LDFLAGS\""; } >&5
+ (: PIE_LDFLAGS="$PIE_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ PIE_LDFLAGS=-Wl,-z,aslr
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : PIE_LDFLAGS=\"\$PIE_LDFLAGS\""; } >&5
+ (: PIE_LDFLAGS="$PIE_LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+else
+ :
+fi
+
+ ;;
+ esac
+fi
+
+if test "$enable_hardening" != "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compiler stack protector support" >&5
+$as_echo_n "checking for compiler stack protector support... " >&6; }
+if ${sudo_cv_var_stack_protector+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ # Avoid CFLAGS since the compiler might optimize away our test.
+ # We don't want CPPFLAGS or LIBS to interfere with the test but
+ # keep LDFLAGS as it may have an rpath needed to find the ssp lib.
+ _CPPFLAGS="$CPPFLAGS"
+ _CFLAGS="$CFLAGS"
+ _LDFLAGS="$LDFLAGS"
+ _LIBS="$LIBS"
+ CPPFLAGS=
+ LIBS=
+
+ sudo_cv_var_stack_protector="-fstack-protector-strong"
+ CFLAGS="$sudo_cv_var_stack_protector"
+ LDFLAGS="$_LDFLAGS $sudo_cv_var_stack_protector"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ $ac_includes_default
+int
+main ()
+{
+char buf[1024]; buf[1023] = '\0';
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+
+ sudo_cv_var_stack_protector="-fstack-protector-all"
+ CFLAGS="$sudo_cv_var_stack_protector"
+ LDFLAGS="$_LDFLAGS $sudo_cv_var_stack_protector"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ $ac_includes_default
+int
+main ()
+{
+char buf[1024]; buf[1023] = '\0';
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+
+ sudo_cv_var_stack_protector="-fstack-protector"
+ CFLAGS="$sudo_cv_var_stack_protector"
+ LDFLAGS="$_LDFLAGS $sudo_cv_var_stack_protector"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ $ac_includes_default
+int
+main ()
+{
+char buf[1024]; buf[1023] = '\0';
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+
+ sudo_cv_var_stack_protector=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CPPFLAGS="$_CPPFLAGS"
+ CFLAGS="$_CFLAGS"
+ LDFLAGS="$_LDFLAGS"
+ LIBS="$_LIBS"
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_var_stack_protector" >&5
+$as_echo "$sudo_cv_var_stack_protector" >&6; }
+ if test X"$sudo_cv_var_stack_protector" != X"no"; then
+ SSP_CFLAGS="$sudo_cv_var_stack_protector"
+ SSP_LDFLAGS="-Wc,$sudo_cv_var_stack_protector"
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,-z,relro" >&5
+$as_echo_n "checking whether the linker accepts -Wl,-z,relro... " >&6; }
+if ${ax_cv_check_ldflags___Wl__z_relro+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_check_save_flags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-z,relro"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_cv_check_ldflags___Wl__z_relro=yes
+else
+ ax_cv_check_ldflags___Wl__z_relro=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl__z_relro" >&5
+$as_echo "$ax_cv_check_ldflags___Wl__z_relro" >&6; }
+if test x"$ax_cv_check_ldflags___Wl__z_relro" = xyes; then :
+
+if ${LDFLAGS+:} false; then :
+
+ case " $LDFLAGS " in #(
+ *" -Wl,-z,relro "*) :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS already contains -Wl,-z,relro"; } >&5
+ (: LDFLAGS already contains -Wl,-z,relro) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } ;; #(
+ *) :
+
+ as_fn_append LDFLAGS " -Wl,-z,relro"
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS\""; } >&5
+ (: LDFLAGS="$LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ ;;
+esac
+
+else
+
+ LDFLAGS=-Wl,-z,relro
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: : LDFLAGS=\"\$LDFLAGS\""; } >&5
+ (: LDFLAGS="$LDFLAGS") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+fi
+
+else
+ :
+fi
+
+fi
+
+case "$with_passwd" in
+yes|maybe)
+ AUTH_OBJS="$AUTH_OBJS getspwuid.lo passwd.lo"
+ ;;
+*)
+ $as_echo "#define WITHOUT_PASSWD 1" >>confdefs.h
+
+ if test -z "$AUTH_OBJS"; then
+ as_fn_error $? "no authentication methods defined." "$LINENO" 5
+ fi
+ ;;
+esac
+AUTH_OBJS=${AUTH_OBJS# }
+_AUTH=`echo "$AUTH_OBJS" | sed -e 's/\.lo//g' -e 's/getspwuid *//'`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: using the following authentication methods: $_AUTH" >&5
+$as_echo "$as_me: using the following authentication methods: $_AUTH" >&6;}
+
+if test -n "$LIBS"; then
+ L="$LIBS"
+ LIBS=
+ for l in ${L}; do
+ dupe=0
+ for sl in ${SUDO_LIBS} ${SUDOERS_LIBS} ${NET_LIBS}; do
+ test $l = $sl && dupe=1
+ done
+ test $dupe = 0 && LIBS="${LIBS} $l"
+ done
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define os_init $OS_INIT
+_ACEOF
+
+
+if test -n "$GCC"; then
+ if test X"$enable_warnings" = X"yes" -o X"$with_devel" = X"yes"; then
+ CFLAGS="${CFLAGS} -Wall -Wsign-compare -Wpointer-arith"
+ fi
+ if test X"$enable_werror" = X"yes"; then
+ CFLAGS="${CFLAGS} -Werror"
+ fi
+fi
+
+CROSS_COMPILING="$cross_compiling"
+
+test "$exec_prefix" = "NONE" && exec_prefix='$(prefix)'
+
+if test X"$with_noexec" != X"no" -o X"$with_selinux" != X"no" -o "$enabled_shared" != X"no"; then
+ oexec_prefix="$exec_prefix"
+ if test "$exec_prefix" = '$(prefix)'; then
+ if test "$prefix" = "NONE"; then
+ exec_prefix="$ac_default_prefix"
+ else
+ exec_prefix="$prefix"
+ fi
+ fi
+ if test X"$with_noexec" != X"no"; then
+ PROGS="${PROGS} sudo_noexec.la"
+ INSTALL_NOEXEC="install-noexec"
+
+ # Can't use asan with LD_PRELOAD
+ if test "$enable_asan" != "yes"; then
+ CHECK_NOEXEC=check_noexec
+ fi
+
+ noexec_file="$with_noexec"
+ _noexec_file=
+ while test X"$noexec_file" != X"$_noexec_file"; do
+ _noexec_file="$noexec_file"
+ eval noexec_file="$_noexec_file"
+ done
+ cat >>confdefs.h <<EOF
+#define _PATH_SUDO_NOEXEC "$noexec_file"
+EOF
+
+ fi
+ if test X"$with_selinux" != X"no"; then
+ sesh_file="$libexecdir/sudo/sesh"
+ _sesh_file=
+ while test X"$sesh_file" != X"$_sesh_file"; do
+ _sesh_file="$sesh_file"
+ eval sesh_file="$_sesh_file"
+ done
+ cat >>confdefs.h <<EOF
+#define _PATH_SUDO_SESH "$sesh_file"
+EOF
+
+ fi
+ if test X"$enable_shared" != X"no"; then
+ PLUGINDIR="$with_plugindir"
+ _PLUGINDIR=
+ while test X"$PLUGINDIR" != X"$_PLUGINDIR"; do
+ _PLUGINDIR="$PLUGINDIR"
+ eval PLUGINDIR="$_PLUGINDIR"
+ done
+ cat >>confdefs.h <<EOF
+#define _PATH_SUDO_PLUGIN_DIR "$PLUGINDIR/"
+EOF
+
+
+$as_echo "#define ENABLE_SUDO_PLUGIN_API 1" >>confdefs.h
+
+ fi
+ exec_prefix="$oexec_prefix"
+fi
+if test X"$with_noexec" = X"no"; then
+ cat >>confdefs.h <<EOF
+#define _PATH_SUDO_NOEXEC NULL
+EOF
+
+fi
+if test X"$with_selinux" = X"no"; then
+ cat >>confdefs.h <<EOF
+#define _PATH_SUDO_SESH NULL
+EOF
+
+fi
+if test X"$enable_shared" = X"no"; then
+ cat >>confdefs.h <<EOF
+#define _PATH_SUDO_PLUGIN_DIR NULL
+EOF
+
+fi
+
+if test X"$LDFLAGS_R" != X""; then
+ LDFLAGS="$LDFLAGS $LDFLAGS_R"
+fi
+if test X"$SUDOERS_LDFLAGS_R" != X""; then
+ SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS $SUDOERS_LDFLAGS_R"
+fi
+if test X"$ZLIB_R" != X""; then
+ ZLIB="$ZLIB_R $ZLIB"
+fi
+
+if test X"$prefix" = X"NONE"; then
+ test "$mandir" = '${datarootdir}/man' && mandir='$(prefix)/man'
+else
+ test "$mandir" = '${datarootdir}/man' && mandir='$(datarootdir)/man'
+fi
+test "$bindir" = '${exec_prefix}/bin' && bindir='$(exec_prefix)/bin'
+test "$sbindir" = '${exec_prefix}/sbin' && sbindir='$(exec_prefix)/sbin'
+test "$libexecdir" = '${exec_prefix}/libexec' && libexecdir='$(exec_prefix)/libexec'
+test "$includedir" = '${prefix}/include' && includedir='$(prefix)/include'
+test "$datarootdir" = '${prefix}/share' && datarootdir='$(prefix)/share'
+test "$docdir" = '${datarootdir}/doc/${PACKAGE_TARNAME}' && docdir='$(datarootdir)/doc/$(PACKAGE_TARNAME)'
+test "$localedir" = '${datarootdir}/locale' && localedir='$(datarootdir)/locale'
+test "$localstatedir" = '${prefix}/var' && localstatedir='$(prefix)/var'
+test "$sysconfdir" = '${prefix}/etc' && sysconfdir='/etc'
+
+if test X"$INIT_SCRIPT" != X""; then
+ ac_config_files="$ac_config_files init.d/$INIT_SCRIPT"
+
+elif test X"$TMPFILES_D" != X""; then
+ ac_config_files="$ac_config_files init.d/sudo.conf"
+
+fi
+ac_config_files="$ac_config_files Makefile doc/Makefile examples/Makefile include/Makefile lib/util/Makefile lib/util/util.exp src/sudo_usage.h src/Makefile plugins/sample/Makefile plugins/group_file/Makefile plugins/system_group/Makefile plugins/sudoers/Makefile plugins/sudoers/sudoers"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by sudo $as_me 1.8.27, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <https://bugzilla.sudo.ws/>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+sudo config.status 1.8.27
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+fix_hardcoded_libdir_flag_spec='`$ECHO "$fix_hardcoded_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+fix_hardcoded_libdir_flag_spec_ld='`$ECHO "$fix_hardcoded_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
+configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_import \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+lt_cv_nm_interface \
+nm_file_list_spec \
+lt_cv_truncate_bin \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+fix_hardcoded_libdir_flag_spec \
+fix_hardcoded_libdir_flag_spec_ld \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+configure_time_dlsearch_path \
+configure_time_lt_sys_library_path; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "pathnames.h") CONFIG_HEADERS="$CONFIG_HEADERS pathnames.h" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "lib/zlib/zconf.h") CONFIG_HEADERS="$CONFIG_HEADERS lib/zlib/zconf.h" ;;
+ "lib/zlib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/zlib/Makefile" ;;
+ "init.d/$INIT_SCRIPT") CONFIG_FILES="$CONFIG_FILES init.d/$INIT_SCRIPT" ;;
+ "init.d/sudo.conf") CONFIG_FILES="$CONFIG_FILES init.d/sudo.conf" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
+ "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
+ "lib/util/Makefile") CONFIG_FILES="$CONFIG_FILES lib/util/Makefile" ;;
+ "lib/util/util.exp") CONFIG_FILES="$CONFIG_FILES lib/util/util.exp" ;;
+ "src/sudo_usage.h") CONFIG_FILES="$CONFIG_FILES src/sudo_usage.h" ;;
+ "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+ "plugins/sample/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/sample/Makefile" ;;
+ "plugins/group_file/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/group_file/Makefile" ;;
+ "plugins/system_group/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/system_group/Makefile" ;;
+ "plugins/sudoers/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/sudoers/Makefile" ;;
+ "plugins/sudoers/sudoers") CONFIG_FILES="$CONFIG_FILES plugins/sudoers/sudoers" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+ ;;
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool 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 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 <http://www.gnu.org/licenses/>.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=''
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shared archive member basename,for filename based shared library versioning on AIX.
+shared_archive_member_spec=$shared_archive_member_spec
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm into a list of symbols to manually relocate.
+global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name lister interface.
+nm_interface=$lt_lt_cv_nm_interface
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and where our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# Command to truncate a binary pipe.
+lt_truncate_bin=$lt_lt_cv_truncate_bin
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Detected run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
+
+# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
+configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Flag to modify a path being hardcoded into the resulting binary.
+fix_hardcoded_libdir_flag_spec=$lt_fix_hardcoded_libdir_flag_spec
+
+# If ld is used when linking,flag to modify a path being hardcoded into the resulting binary.
+fix_hardcoded_libdir_flag_spec_ld=$lt_fix_hardcoded_libdir_flag_spec_ld
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x$2 in
+ x)
+ ;;
+ *:)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+ ;;
+ x:*)
+ eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+ ;;
+ *)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+
+
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in $*""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+if test "$with_pam" = "yes"; then
+ case $host_os in
+ hpux*)
+ if test -f /usr/lib/security/libpam_hpsec.so.1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You may wish to add the following line to /etc/pam.conf" >&5
+$as_echo "$as_me: You may wish to add the following line to /etc/pam.conf" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: sudo session required libpam_hpsec.so.1 bypass_umask bypass_last_login" >&5
+$as_echo "$as_me: sudo session required libpam_hpsec.so.1 bypass_umask bypass_last_login" >&6;}
+ fi
+ ;;
+ linux*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You will need to customize examples/pam.conf and install it as /etc/pam.d/sudo" >&5
+$as_echo "$as_me: You will need to customize examples/pam.conf and install it as /etc/pam.d/sudo" >&6;}
+ ;;
+ esac
+fi
+case "$rundir" in
+ /run/*|/var/run/*)
+ clear_rundir=0
+ ;;
+ *)
+ clear_rundir=1
+ ;;
+esac
+if test $clear_rundir -eq 1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: the $rundir/ts directory must be cleared at boot time." >&5
+$as_echo "$as_me: Warning: the $rundir/ts directory must be cleared at boot time." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You may need to create a startup item to do this." >&5
+$as_echo "$as_me: You may need to create a startup item to do this." >&6;}
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..962a032
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,4659 @@
+dnl
+dnl Use the top-level autogen.sh script to generate configure and config.h.in
+dnl
+dnl Copyright (c) 1994-1996,1998-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+dnl
+AC_PREREQ([2.59])
+AC_INIT([sudo], [1.8.27], [https://bugzilla.sudo.ws/], [sudo])
+AC_CONFIG_HEADER([config.h pathnames.h])
+AC_CONFIG_SRCDIR([src/sudo.c])
+dnl
+dnl Note: this must come after AC_INIT
+dnl
+AC_MSG_NOTICE([Configuring Sudo version $PACKAGE_VERSION])
+dnl
+dnl Variables that get substituted in the Makefile and man pages
+dnl
+AC_SUBST([SHELL])
+AC_SUBST([LIBTOOL])
+AC_SUBST([CFLAGS])
+AC_SUBST([PROGS])
+AC_SUBST([CPPFLAGS])
+AC_SUBST([LDFLAGS])
+AC_SUBST([SUDO_LDFLAGS])
+AC_SUBST([SUDOERS_LDFLAGS])
+AC_SUBST([LIBUTIL_LDFLAGS])
+AC_SUBST([ZLIB_LDFLAGS])
+AC_SUBST([LT_LDFLAGS])
+AC_SUBST([LT_LDDEP])
+AC_SUBST([LT_LDEXPORTS])
+AC_SUBST([LT_STATIC])
+AC_SUBST([LT_DEP_LIBS])
+AC_SUBST([COMMON_OBJS])
+AC_SUBST([SUDOERS_OBJS])
+AC_SUBST([SUDO_OBJS])
+AC_SUBST([LIBS])
+AC_SUBST([SUDO_LIBS])
+AC_SUBST([SUDOERS_LIBS])
+AC_SUBST([STATIC_SUDOERS])
+AC_SUBST([NET_LIBS])
+AC_SUBST([AFS_LIBS])
+AC_SUBST([REPLAY_LIBS])
+AC_SUBST([GETGROUPS_LIB])
+AC_SUBST([AUTH_OBJS])
+AC_SUBST([MANTYPE])
+AC_SUBST([MANDIRTYPE])
+AC_SUBST([MANCOMPRESS])
+AC_SUBST([MANCOMPRESSEXT])
+AC_SUBST([SHLIB_ENABLE])
+AC_SUBST([SHLIB_MODE])
+AC_SUBST([SUDOERS_MODE])
+AC_SUBST([SUDOERS_UID])
+AC_SUBST([SUDOERS_GID])
+AC_SUBST([DEVEL])
+AC_SUBST([BAMAN])
+AC_SUBST([LCMAN])
+AC_SUBST([PSMAN])
+AC_SUBST([SEMAN])
+AC_SUBST([devdir])
+AC_SUBST([mansectsu])
+AC_SUBST([mansectform])
+AC_SUBST([mansrcdir])
+AC_SUBST([NOEXECFILE])
+AC_SUBST([NOEXECDIR])
+AC_SUBST([noexec_file])
+AC_SUBST([sesh_file])
+AC_SUBST([INSTALL_BACKUP])
+AC_SUBST([INSTALL_NOEXEC])
+AC_SUBST([CHECK_NOEXEC])
+AC_SUBST([DONT_LEAK_PATH_INFO])
+AC_SUBST([BSDAUTH_USAGE])
+AC_SUBST([SELINUX_USAGE])
+AC_SUBST([LDAP])
+AC_SUBST([LOGINCAP_USAGE])
+AC_SUBST([ZLIB])
+AC_SUBST([ZLIB_SRC])
+AC_SUBST([LIBTOOL_DEPS])
+AC_SUBST([CONFIGURE_ARGS])
+AC_SUBST([LIBDL])
+AC_SUBST([LIBRT])
+AC_SUBST([LIBINTL])
+AC_SUBST([LIBMD])
+AC_SUBST([LIBPTHREAD])
+AC_SUBST([SUDO_NLS])
+AC_SUBST([LOCALEDIR_SUFFIX])
+AC_SUBST([COMPAT_TEST_PROGS])
+AC_SUBST([SUDOERS_TEST_PROGS])
+AC_SUBST([CROSS_COMPILING])
+AC_SUBST([ASAN_LDFLAGS])
+AC_SUBST([ASAN_CFLAGS])
+AC_SUBST([PIE_LDFLAGS])
+AC_SUBST([PIE_CFLAGS])
+AC_SUBST([SSP_LDFLAGS])
+AC_SUBST([SSP_CFLAGS])
+AC_SUBST([INIT_SCRIPT])
+AC_SUBST([INIT_DIR])
+AC_SUBST([RC_LINK])
+AC_SUBST([COMPAT_EXP])
+AC_SUBST([TMPFILES_D])
+AC_SUBST([exampledir])
+AC_SUBST([DIGEST])
+AC_SUBST([devsearch])
+dnl
+dnl Variables that get substituted in docs (not overridden by environment)
+dnl
+AC_SUBST([iolog_dir])dnl real initial value from SUDO_IO_LOGDIR
+AC_SUBST([rundir])dnl real initial value from SUDO_RUNDIR
+AC_SUBST([vardir])dnl real initial value from SUDO_VARDIR
+AC_SUBST([timeout])
+AC_SUBST([password_timeout])
+AC_SUBST([sudo_umask])
+AC_SUBST([umask_override])
+AC_SUBST([passprompt])
+AC_SUBST([long_otp_prompt])
+AC_SUBST([lecture])
+AC_SUBST([logfac])
+AC_SUBST([goodpri])
+AC_SUBST([badpri])
+AC_SUBST([loglen])
+AC_SUBST([ignore_dot])
+AC_SUBST([mail_no_user])
+AC_SUBST([mail_no_host])
+AC_SUBST([mail_no_perms])
+AC_SUBST([mailto])
+AC_SUBST([mailsub])
+AC_SUBST([badpass_message])
+AC_SUBST([fqdn])
+AC_SUBST([runas_default])
+AC_SUBST([env_editor])
+AC_SUBST([env_reset])
+AC_SUBST([passwd_tries])
+AC_SUBST([timestamp_type])
+AC_SUBST([insults])
+AC_SUBST([root_sudo])
+AC_SUBST([path_info])
+AC_SUBST([ldap_conf])
+AC_SUBST([ldap_secret])
+AC_SUBST([sssd_lib])
+AC_SUBST([nsswitch_conf])
+AC_SUBST([netsvc_conf])
+AC_SUBST([secure_path])
+AC_SUBST([editor])
+AC_SUBST([pam_session])
+AC_SUBST([pam_login_service])
+AC_SUBST([PLUGINDIR])
+#
+# Begin initial values for man page substitution
+#
+iolog_dir=/var/log/sudo-io
+rundir=/var/run/sudo
+vardir=/var/adm/sudo
+timeout=5
+password_timeout=5
+sudo_umask=0022
+umask_override=off
+passprompt="Password: "
+long_otp_prompt=off
+lecture=once
+logfac=auth
+goodpri=notice
+badpri=alert
+loglen=80
+ignore_dot=off
+mail_no_user=on
+mail_no_host=off
+mail_no_perms=off
+mailto=root
+mailsub="*** SECURITY information for %h ***"
+badpass_message="Sorry, try again."
+fqdn=off
+runas_default=root
+env_editor=off
+env_reset=on
+editor=vi
+passwd_tries=3
+timestamp_type=tty
+insults=off
+root_sudo=on
+path_info=on
+ldap_conf=/etc/ldap.conf
+ldap_secret=/etc/ldap.secret
+netsvc_conf=/etc/netsvc.conf
+noexec_file=/usr/local/libexec/sudo/sudo_noexec.so
+sesh_file=/usr/local/libexec/sudo/sesh
+nsswitch_conf=/etc/nsswitch.conf
+secure_path="not set"
+pam_session=on
+pam_login_service=sudo
+PLUGINDIR=/usr/local/libexec/sudo
+DIGEST=digest.lo
+devsearch="/dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev"
+#
+# End initial values for man page substitution
+#
+dnl
+dnl Initial values for Makefile variables listed above
+dnl May be overridden by environment variables..
+dnl
+INSTALL_BACKUP=
+INSTALL_NOEXEC=
+CHECK_NOEXEC=
+exampledir='$(docdir)/examples'
+devdir='$(srcdir)'
+PROGS="sudo"
+: ${MANDIRTYPE='man'}
+: ${mansrcdir='.'}
+: ${SHLIB_MODE='0644'}
+: ${SUDOERS_MODE='0440'}
+: ${SUDOERS_UID='0'}
+: ${SUDOERS_GID='0'}
+DEVEL=
+LDAP="#"
+BAMAN=0
+LCMAN=0
+PSMAN=0
+SEMAN=0
+LIBINTL=
+LIBMD=
+ZLIB=
+ZLIB_SRC=
+AUTH_OBJS=
+AUTH_REG=
+AUTH_EXCL=
+AUTH_EXCL_DEF=
+AUTH_DEF=passwd
+SUDO_NLS=disabled
+LOCALEDIR_SUFFIX=
+LT_LDEXPORTS="-export-symbols \$(shlib_exp)"
+LT_LDDEP="\$(shlib_exp)"
+OS_INIT=os_init_common
+INIT_SCRIPT=
+INIT_DIR=
+RC_LINK=
+COMPAT_EXP=
+dnl
+dnl Other vaiables
+dnl
+WEAK_ALIAS=no
+CHECKSHADOW=true
+shadow_funcs=
+shadow_libs=
+TMPFILES_D=
+CONFIGURE_ARGS="$@"
+
+dnl
+dnl LD_PRELOAD equivalents
+dnl
+RTLD_PRELOAD_VAR="LD_PRELOAD"
+RTLD_PRELOAD_ENABLE_VAR=
+RTLD_PRELOAD_DELIM=":"
+RTLD_PRELOAD_DEFAULT=
+
+dnl
+dnl libc replacement functions live in libsudo_util.a
+dnl
+AC_CONFIG_LIBOBJ_DIR(lib/util)
+
+dnl
+dnl We must call AC_USE_SYSTEM_EXTENSIONS before the compiler is run.
+dnl
+AC_USE_SYSTEM_EXTENSIONS
+
+#
+# Prior to sudo 1.8.7, sudo stored libexec files in $libexecdir.
+# Starting with sudo 1.8.7, $libexecdir/sudo is used so strip
+# off an extraneous "/sudo" from libexecdir.
+#
+case "$libexecdir" in
+ */sudo)
+ AC_MSG_WARN([libexecdir should not include the "sudo" subdirectory])
+ libexecdir=`expr "$libexecdir" : '\\(.*\\)/sudo$'`
+ ;;
+esac
+
+dnl
+dnl Deprecated --with options (these all warn or generate an error)
+dnl
+
+AC_ARG_WITH(otp-only, [AS_HELP_STRING([--with-otp-only], [deprecated])],
+[case $with_otp_only in
+ yes) with_passwd="no"
+ AC_MSG_NOTICE([--with-otp-only option deprecated, treating as --without-passwd])
+ ;;
+esac])
+
+AC_ARG_WITH(alertmail, [AS_HELP_STRING([--with-alertmail], [deprecated])],
+[case $with_alertmail in
+ *) with_mailto="$with_alertmail"
+ AC_MSG_NOTICE([--with-alertmail option deprecated, treating as --mailto])
+ ;;
+esac])
+
+AC_ARG_WITH(pc-insults, [AS_HELP_STRING([--with-pc-insults], [deprecated])],
+[case $with_pc_insults in
+ yes) enable_offensive_insults=no
+ AC_MSG_NOTICE([--with-pc-insults option deprecated, it is now the default])
+ ;;
+ no) enable_offensive_insults=yes
+ AC_MSG_NOTICE([--without-pc-insults option deprecated, use --enable-offensive-insults])
+ ;;
+esac])
+
+dnl
+dnl Options for --with
+dnl
+
+AC_ARG_WITH(devel, [AS_HELP_STRING([--with-devel], [add development options])],
+[case $with_devel in
+ yes) AC_MSG_NOTICE([Setting up for development: -Wall, flex, yacc])
+ AX_APPEND_FLAG([-DSUDO_DEVEL], [CPPFLAGS])
+ DEVEL="true"
+ devdir=.
+ ;;
+ no) ;;
+ *) AC_MSG_WARN([Ignoring unknown argument to --with-devel: $with_devel])
+ ;;
+esac])
+
+AC_ARG_WITH(CC, [AS_HELP_STRING([--with-CC], [C compiler to use])],
+[case $with_CC in
+ *) AC_MSG_ERROR([the --with-CC option is no longer supported, please set the CC environment variable instead.])
+ ;;
+esac])
+
+AC_ARG_WITH(rpath, [AS_HELP_STRING([--with-rpath], [deprecated, use --disable-rpath])],
+[AC_MSG_WARN([--with-rpath deprecated, rpath is now the default])])
+
+AC_ARG_WITH(blibpath, [AS_HELP_STRING([--with-blibpath[[=PATH]]], [deprecated])],
+[AC_MSG_WARN([--with-blibpath deprecated, use --with-libpath])])
+
+dnl
+dnl Handle BSM auditing support.
+dnl
+AC_ARG_WITH(bsm-audit, [AS_HELP_STRING([--with-bsm-audit], [enable BSM audit support])],
+[case $with_bsm_audit in
+ yes) AC_DEFINE(HAVE_BSM_AUDIT)
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lbsm"
+ SUDOERS_OBJS="${SUDOERS_OBJS} bsm_audit.lo"
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-bsm-audit does not take an argument."])
+ ;;
+esac])
+
+dnl
+dnl Handle Linux auditing support.
+dnl
+AC_ARG_WITH(linux-audit, [AS_HELP_STRING([--with-linux-audit], [enable Linux audit support])],
+[case $with_linux_audit in
+ yes) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <libaudit.h>]], [[int i = AUDIT_USER_CMD; (void)i;]])], [
+ AC_DEFINE(HAVE_LINUX_AUDIT)
+ SUDO_LIBS="${SUDO_LIBS} -laudit"
+ SUDOERS_LIBS="${SUDO_LIBS} -laudit"
+ SUDOERS_OBJS="${SUDOERS_OBJS} linux_audit.lo"
+ ], [
+ AC_MSG_ERROR([unable to find AUDIT_USER_CMD in libaudit.h for --with-linux-audit])
+ ])
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-linux-audit does not take an argument."])
+ ;;
+esac])
+
+dnl
+dnl Handle Solaris auditing support.
+dnl
+AC_ARG_WITH(solaris-audit, [AS_HELP_STRING([--with-solaris-audit], [enable Solaris audit support])],
+[case $with_solaris_audit in
+ yes) AC_DEFINE(HAVE_SOLARIS_AUDIT)
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lbsm"
+ SUDOERS_OBJS="${SUDOERS_OBJS} solaris_audit.lo"
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-solaris-audit does not take an argument."])
+ ;;
+esac])
+
+dnl
+dnl Handle SSSD support.
+dnl
+AC_ARG_WITH(sssd, [AS_HELP_STRING([--with-sssd], [enable SSSD support])],
+[case $with_sssd in
+ yes) SUDOERS_OBJS="${SUDOERS_OBJS} sssd.lo"
+ case "$SUDOERS_OBJS" in
+ *ldap_util.lo*) ;;
+ *) SUDOERS_OBJS="${SUDOERS_OBJS} ldap_util.lo";;
+ esac
+ AC_DEFINE(HAVE_SSSD)
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-sssd does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(sssd-conf, [AS_HELP_STRING([--with-sssd-conf], [path to the SSSD config file])])
+sssd_conf="/etc/sssd/sssd.conf"
+test -n "$with_sssd_conf" && sssd_conf="$with_sssd_conf"
+SUDO_DEFINE_UNQUOTED(_PATH_SSSD_CONF, "$sssd_conf", [Path to the SSSD config file])
+
+AC_ARG_WITH(sssd-lib, [AS_HELP_STRING([--with-sssd-lib], [path to the SSSD library])])
+sssd_lib="\"LIBDIR\""
+test -n "$with_sssd_lib" && sssd_lib="$with_sssd_lib"
+SUDO_DEFINE_UNQUOTED(_PATH_SSSD_LIB, "$sssd_lib", [Path to the SSSD library])
+
+AC_ARG_WITH(incpath, [AS_HELP_STRING([--with-incpath], [additional places to look for include files])],
+[case $with_incpath in
+ yes) AC_MSG_ERROR(["must give --with-incpath an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-incpath not supported."])
+ ;;
+ *) AC_MSG_NOTICE([Adding ${with_incpath} to CPPFLAGS])
+ for i in ${with_incpath}; do
+ AX_APPEND_FLAG([-I${i}], [CPPFLAGS])
+ done
+ ;;
+esac])
+
+AC_ARG_WITH(libpath, [AS_HELP_STRING([--with-libpath], [additional places to look for libraries])],
+[case $with_libpath in
+ yes) AC_MSG_ERROR(["must give --with-libpath an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-libpath not supported."])
+ ;;
+ *) AC_MSG_NOTICE([Adding ${with_libpath} to LDFLAGS])
+ ;;
+esac])
+
+AC_ARG_WITH(libraries, [AS_HELP_STRING([--with-libraries], [additional libraries to link with])],
+[case $with_libraries in
+ yes) AC_MSG_ERROR(["must give --with-libraries an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-libraries not supported."])
+ ;;
+ *) AC_MSG_NOTICE([Adding ${with_libraries} to LIBS])
+ ;;
+esac])
+
+AC_ARG_WITH(efence, [AS_HELP_STRING([--with-efence], [link with -lefence for malloc() debugging])],
+[case $with_efence in
+ yes) AC_MSG_NOTICE([Sudo will link with -lefence (Electric Fence)])
+ LIBS="${LIBS} -lefence"
+ if test -f /usr/local/lib/libefence.a; then
+ with_libpath="${with_libpath} /usr/local/lib"
+ fi
+ ;;
+ no) ;;
+ *) AC_MSG_WARN([Ignoring unknown argument to --with-efence: $with_efence])
+ ;;
+esac])
+
+AC_ARG_WITH(csops, [AS_HELP_STRING([--with-csops], [add CSOps standard options])],
+[case $with_csops in
+ yes) AC_MSG_NOTICE([Adding CSOps standard options])
+ CHECKSIA=false
+ with_ignore_dot=yes
+ insults=on
+ with_classic_insults=yes
+ with_csops_insults=yes
+ with_env_editor=yes
+ : ${mansectsu='8'}
+ : ${mansectform='5'}
+ ;;
+ no) ;;
+ *) AC_MSG_WARN([Ignoring unknown argument to --with-csops: $with_csops])
+ ;;
+esac])
+
+AC_ARG_WITH(passwd, [AS_HELP_STRING([--without-passwd], [don't use passwd/shadow file for authentication])],
+[case $with_passwd in
+ yes|no) AC_MSG_CHECKING(whether to use shadow/passwd file authentication)
+ AC_MSG_RESULT($with_passwd)
+ AUTH_DEF=""
+ test "$with_passwd" = "yes" && AUTH_REG="$AUTH_REG passwd"
+ ;;
+ *) AC_MSG_ERROR(["Sorry, --with-passwd does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(skey, [AS_HELP_STRING([--with-skey[[=DIR]]], [enable S/Key support ])],
+[case $with_skey in
+ no) ;;
+ *) AC_DEFINE(HAVE_SKEY)
+ AC_MSG_CHECKING(whether to try S/Key authentication)
+ AC_MSG_RESULT(yes)
+ AUTH_REG="$AUTH_REG S/Key"
+ ;;
+esac])
+
+AC_ARG_WITH(opie, [AS_HELP_STRING([--with-opie[[=DIR]]], [enable OPIE support ])],
+[case $with_opie in
+ no) ;;
+ *) AC_DEFINE(HAVE_OPIE)
+ AC_MSG_CHECKING(whether to try NRL OPIE authentication)
+ AC_MSG_RESULT(yes)
+ AUTH_REG="$AUTH_REG NRL_OPIE"
+ ;;
+esac])
+
+AC_ARG_WITH(long-otp-prompt, [AS_HELP_STRING([--with-long-otp-prompt], [use a two line OTP (skey/opie) prompt])],
+[case $with_long_otp_prompt in
+ yes) AC_DEFINE(LONG_OTP_PROMPT)
+ AC_MSG_CHECKING(whether to use a two line prompt for OTP authentication)
+ AC_MSG_RESULT(yes)
+ long_otp_prompt=on
+ ;;
+ no) long_otp_prompt=off
+ ;;
+ *) AC_MSG_ERROR(["--with-long-otp-prompt does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(SecurID, [AS_HELP_STRING([--with-SecurID[[=DIR]]], [enable SecurID support])],
+[case $with_SecurID in
+ no) ;;
+ *) AC_DEFINE(HAVE_SECURID)
+ AC_MSG_CHECKING(whether to use SecurID for authentication)
+ AC_MSG_RESULT(yes)
+ AUTH_EXCL="$AUTH_EXCL SecurID"
+ ;;
+esac])
+
+AC_ARG_WITH(fwtk, [AS_HELP_STRING([--with-fwtk[[=DIR]]], [enable FWTK AuthSRV support])],
+[case $with_fwtk in
+ no) ;;
+ *) AC_DEFINE(HAVE_FWTK)
+ AC_MSG_CHECKING(whether to use FWTK AuthSRV for authentication)
+ AC_MSG_RESULT(yes)
+ AUTH_EXCL="$AUTH_EXCL FWTK"
+ ;;
+esac])
+
+AC_ARG_WITH(kerb5, [AS_HELP_STRING([--with-kerb5[[=DIR]]], [enable Kerberos V support])],
+[case $with_kerb5 in
+ no) ;;
+ *) AC_MSG_CHECKING(whether to try Kerberos V authentication)
+ AC_MSG_RESULT(yes)
+ AUTH_REG="$AUTH_REG kerb5"
+ ;;
+esac])
+
+AC_ARG_WITH(aixauth, [AS_HELP_STRING([--with-aixauth], [enable AIX general authentication support])],
+[case $with_aixauth in
+ yes) AUTH_EXCL="$AUTH_EXCL AIX_AUTH";;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-aixauth does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(pam, [AS_HELP_STRING([--with-pam], [enable PAM support])],
+[case $with_pam in
+ yes) AUTH_EXCL="$AUTH_EXCL PAM";;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-pam does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(AFS, [AS_HELP_STRING([--with-AFS], [enable AFS support])],
+[case $with_AFS in
+ yes) AC_DEFINE(HAVE_AFS)
+ AC_MSG_CHECKING(whether to try AFS (kerberos) authentication)
+ AC_MSG_RESULT(yes)
+ AUTH_REG="$AUTH_REG AFS"
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-AFS does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(DCE, [AS_HELP_STRING([--with-DCE], [enable DCE support])],
+[case $with_DCE in
+ yes) AC_DEFINE(HAVE_DCE)
+ AC_MSG_CHECKING(whether to try DCE (kerberos) authentication)
+ AC_MSG_RESULT(yes)
+ AUTH_REG="$AUTH_REG DCE"
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-DCE does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(logincap, [AS_HELP_STRING([--with-logincap], [enable BSD login class support])],
+[case $with_logincap in
+ yes|no) ;;
+ *) AC_MSG_ERROR(["--with-logincap does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(bsdauth, [AS_HELP_STRING([--with-bsdauth], [enable BSD authentication support])],
+[case $with_bsdauth in
+ yes) AUTH_EXCL="$AUTH_EXCL BSD_AUTH";;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-bsdauth does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(project, [AS_HELP_STRING([--with-project], [enable Solaris project support])],
+[case $with_project in
+ yes|no) ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-project does not take an argument."])
+ ;;
+esac])
+
+AC_MSG_CHECKING(whether to lecture users the first time they run sudo)
+AC_ARG_WITH(lecture, [AS_HELP_STRING([--without-lecture], [don't print lecture for first-time sudoer])],
+[case $with_lecture in
+ yes|short|always) lecture=once
+ ;;
+ no|none|never) lecture=never
+ ;;
+ *) AC_MSG_ERROR(["unknown argument to --with-lecture: $with_lecture"])
+ ;;
+esac])
+if test "$lecture" = "once"; then
+ AC_MSG_RESULT(yes)
+else
+ AC_DEFINE(NO_LECTURE)
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether sudo should log via syslog or to a file by default)
+AC_ARG_WITH(logging, [AS_HELP_STRING([--with-logging], [log via syslog, file, or both])],
+[case $with_logging in
+ yes) AC_MSG_ERROR(["must give --with-logging an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-logging not supported."])
+ ;;
+ syslog) AC_DEFINE(LOGGING, SLOG_SYSLOG)
+ AC_MSG_RESULT(syslog)
+ ;;
+ file) AC_DEFINE(LOGGING, SLOG_FILE)
+ AC_MSG_RESULT(file)
+ ;;
+ both) AC_DEFINE(LOGGING, SLOG_BOTH)
+ AC_MSG_RESULT(both)
+ ;;
+ *) AC_MSG_ERROR(["unknown argument to --with-logging: $with_logging"])
+ ;;
+esac], [AC_DEFINE(LOGGING, SLOG_SYSLOG) AC_MSG_RESULT(syslog)])
+
+AC_ARG_WITH(logfac, [AS_HELP_STRING([--with-logfac], [syslog facility to log with (default is "auth")])],
+[case $with_logfac in
+ yes) AC_MSG_ERROR(["must give --with-logfac an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-logfac not supported."])
+ ;;
+ authpriv|auth|daemon|user|local0|local1|local2|local3|local4|local5|local6|local7) logfac=$with_logfac
+ ;;
+ *) AC_MSG_ERROR(["$with_logfac is not a supported syslog facility."])
+ ;;
+esac])
+
+AC_MSG_CHECKING(at which syslog priority to log commands)
+AC_ARG_WITH(goodpri, [AS_HELP_STRING([--with-goodpri], [syslog priority for commands (def is "notice")])],
+[case $with_goodpri in
+ yes) AC_MSG_ERROR(["must give --with-goodpri an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-goodpri not supported."])
+ ;;
+ alert|crit|debug|emerg|err|info|notice|warning)
+ goodpri=$with_goodpri
+ ;;
+ *) AC_MSG_ERROR(["$with_goodpri is not a supported syslog priority."])
+ ;;
+esac])
+AC_DEFINE_UNQUOTED(PRI_SUCCESS, "$goodpri", [The syslog priority sudo will use for successful attempts.])
+AC_MSG_RESULT($goodpri)
+
+AC_MSG_CHECKING(at which syslog priority to log failures)
+AC_ARG_WITH(badpri, [AS_HELP_STRING([--with-badpri], [syslog priority for failures (def is "alert")])],
+[case $with_badpri in
+ yes) AC_MSG_ERROR(["must give --with-badpri an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-badpri not supported."])
+ ;;
+ alert|crit|debug|emerg|err|info|notice|warning)
+ badpri=$with_badpri
+ ;;
+ *) AC_MSG_ERROR([$with_badpri is not a supported syslog priority.])
+ ;;
+esac])
+AC_DEFINE_UNQUOTED(PRI_FAILURE, "$badpri", [The syslog priority sudo will use for unsuccessful attempts/errors.])
+AC_MSG_RESULT($badpri)
+
+AC_ARG_WITH(logpath, [AS_HELP_STRING([--with-logpath], [path to the sudo log file])],
+[case $with_logpath in
+ yes) AC_MSG_ERROR(["must give --with-logpath an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-logpath not supported."])
+ ;;
+esac])
+
+AC_MSG_CHECKING(how long a line in the log file should be)
+AC_ARG_WITH(loglen, [AS_HELP_STRING([--with-loglen], [maximum length of a log file line (default is 80)])],
+[case $with_loglen in
+ yes) AC_MSG_ERROR(["must give --with-loglen an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-loglen not supported."])
+ ;;
+ [[0-9]]*) loglen=$with_loglen
+ ;;
+ *) AC_MSG_ERROR(["you must enter a number, not $with_loglen"])
+ ;;
+esac])
+AC_DEFINE_UNQUOTED(MAXLOGFILELEN, $loglen, [The max number of chars per log file line (for line wrapping).])
+AC_MSG_RESULT($loglen)
+
+AC_MSG_CHECKING(whether sudo should ignore '.' or '' in \$PATH)
+AC_ARG_WITH(ignore-dot, [AS_HELP_STRING([--with-ignore-dot], [ignore '.' in the PATH])],
+[case $with_ignore_dot in
+ yes) ignore_dot=on
+ ;;
+ no) ignore_dot=off
+ ;;
+ *) AC_MSG_ERROR(["--with-ignore-dot does not take an argument."])
+ ;;
+esac])
+if test "$ignore_dot" = "on"; then
+ AC_DEFINE(IGNORE_DOT_PATH)
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to send mail when a user is not in sudoers)
+AC_ARG_WITH(mail-if-no-user, [AS_HELP_STRING([--without-mail-if-no-user], [do not send mail if user not in sudoers])],
+[case $with_mail_if_no_user in
+ yes) mail_no_user=on
+ ;;
+ no) mail_no_user=off
+ ;;
+ *) AC_MSG_ERROR(["--with-mail-if-no-user does not take an argument."])
+ ;;
+esac])
+if test "$mail_no_user" = "on"; then
+ AC_DEFINE(SEND_MAIL_WHEN_NO_USER)
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to send mail when user listed but not for this host)
+AC_ARG_WITH(mail-if-no-host, [AS_HELP_STRING([--with-mail-if-no-host], [send mail if user in sudoers but not for this host])],
+[case $with_mail_if_no_host in
+ yes) mail_no_host=on
+ ;;
+ no) mail_no_host=off
+ ;;
+ *) AC_MSG_ERROR(["--with-mail-if-no-host does not take an argument."])
+ ;;
+esac])
+if test "$mail_no_host" = "on"; then
+ AC_DEFINE(SEND_MAIL_WHEN_NO_HOST)
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to send mail when a user tries a disallowed command)
+AC_ARG_WITH(mail-if-noperms, [AS_HELP_STRING([--with-mail-if-noperms], [send mail if user not allowed to run command])],
+[case $with_mail_if_noperms in
+ yes) mail_noperms=on
+ ;;
+ no) mail_noperms=off
+ ;;
+ *) AC_MSG_ERROR(["--with-mail-if-noperms does not take an argument."])
+ ;;
+esac])
+if test "$mail_noperms" = "on"; then
+ AC_DEFINE(SEND_MAIL_WHEN_NOT_OK)
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(who should get the mail that sudo sends)
+AC_ARG_WITH(mailto, [AS_HELP_STRING([--with-mailto], [who should get sudo mail (default is "root")])],
+[case $with_mailto in
+ yes) AC_MSG_ERROR(["must give --with-mailto an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-mailto not supported."])
+ ;;
+ *) mailto=$with_mailto
+ ;;
+esac])
+AC_DEFINE_UNQUOTED(MAILTO, "$mailto", [The user or email address that sudo mail is sent to.])
+AC_MSG_RESULT([$mailto])
+
+AC_ARG_WITH(mailsubject, [AS_HELP_STRING([--with-mailsubject], [subject of sudo mail])],
+[case $with_mailsubject in
+ yes) AC_MSG_ERROR(["must give --with-mailsubject an argument."])
+ ;;
+ no) AC_MSG_WARN([Sorry, --without-mailsubject not supported.])
+ ;;
+ *) mailsub="$with_mailsubject"
+ AC_MSG_CHECKING(sudo mail subject)
+ AC_MSG_RESULT([Using alert mail subject: $mailsub])
+ ;;
+esac])
+AC_DEFINE_UNQUOTED(MAILSUBJECT, "$mailsub", [The subject of the mail sent by sudo to the MAILTO user/address.])
+
+AC_MSG_CHECKING(for bad password prompt)
+AC_ARG_WITH(passprompt, [AS_HELP_STRING([--with-passprompt], [default password prompt])],
+[case $with_passprompt in
+ yes) AC_MSG_ERROR(["must give --with-passprompt an argument."])
+ ;;
+ no) AC_MSG_WARN([Sorry, --without-passprompt not supported.])
+ ;;
+ *) passprompt="$with_passprompt"
+esac])
+AC_MSG_RESULT($passprompt)
+AC_DEFINE_UNQUOTED(PASSPROMPT, "$passprompt", [The default password prompt.])
+
+AC_MSG_CHECKING(for bad password message)
+AC_ARG_WITH(badpass-message, [AS_HELP_STRING([--with-badpass-message], [message the user sees when the password is wrong])],
+[case $with_badpass_message in
+ yes) AC_MSG_ERROR(["Must give --with-badpass-message an argument."])
+ ;;
+ no) AC_MSG_WARN([Sorry, --without-badpass-message not supported.])
+ ;;
+ *) badpass_message="$with_badpass_message"
+ ;;
+esac])
+AC_DEFINE_UNQUOTED(INCORRECT_PASSWORD, "$badpass_message", [The message given when a bad password is entered.])
+AC_MSG_RESULT([$badpass_message])
+
+AC_MSG_CHECKING(whether to expect fully qualified hosts in sudoers)
+AC_ARG_WITH(fqdn, [AS_HELP_STRING([--with-fqdn], [expect fully qualified hosts in sudoers])],
+[case $with_fqdn in
+ yes) fqdn=on
+ ;;
+ no) fqdn=off
+ ;;
+ *) AC_MSG_ERROR(["--with-fqdn does not take an argument."])
+ ;;
+esac])
+if test "$fqdn" = "on"; then
+ AC_DEFINE(FQDN)
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_ARG_WITH(timedir, [AS_HELP_STRING([--with-timedir=DIR], [deprecated])],
+[case $with_timedir in
+ *) AC_MSG_ERROR(["--without-timedir no longer supported, see --with-rundir."])
+ ;;
+esac])
+
+AC_ARG_WITH(rundir, [AS_HELP_STRING([--with-rundir=DIR], [directory for sudo-specific files that do not survive a system reboot, e.g. `/var/run/sudo'])],
+[case $with_rundir in
+ yes) AC_MSG_ERROR(["must give --with-rundir an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-rundir not supported."])
+ ;;
+esac])
+
+AC_ARG_WITH(vardir, [AS_HELP_STRING([--with-vardir=DIR], [directory for sudo-specific files that survive a system reboot, e.g. `/var/db/sudo' or `/var/lib/sudo'])],
+[case $with_vardir in
+ yes) AC_MSG_ERROR(["must give --with-vardir an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-vardir not supported."])
+ ;;
+esac])
+
+AC_ARG_WITH(iologdir, [AS_HELP_STRING([--with-iologdir=DIR], [directory to store sudo I/O log files in])],
+[case $with_iologdir in
+ yes) ;;
+ no) AC_MSG_ERROR(["--without-iologdir not supported."])
+ ;;
+esac])
+
+AC_ARG_WITH(tzdir, [AS_HELP_STRING([--with-tzdir=DIR], [path to the time zone data directory])],
+[case $with_tzdir in
+ yes) AC_MSG_ERROR(["must give --with-tzdir an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(sendmail, [AS_HELP_STRING([--with-sendmail], [set path to sendmail])
+AS_HELP_STRING([--without-sendmail], [do not send mail at all])],
+[case $with_sendmail in
+ yes) with_sendmail=""
+ ;;
+ no) ;;
+ *) SUDO_DEFINE_UNQUOTED(_PATH_SUDO_SENDMAIL, "$with_sendmail")
+ ;;
+esac])
+
+AC_ARG_WITH(sudoers-mode, [AS_HELP_STRING([--with-sudoers-mode], [mode of sudoers file (defaults to 0440)])],
+[case $with_sudoers_mode in
+ yes) AC_MSG_ERROR(["must give --with-sudoers-mode an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-sudoers-mode not supported."])
+ ;;
+ [[1-9]]*) SUDOERS_MODE=0${with_sudoers_mode}
+ ;;
+ 0*) SUDOERS_MODE=$with_sudoers_mode
+ ;;
+ *) AC_MSG_ERROR(["you must use an octal mode, not a name."])
+ ;;
+esac])
+
+AC_ARG_WITH(sudoers-uid, [AS_HELP_STRING([--with-sudoers-uid], [uid that owns sudoers file (defaults to 0)])],
+[case $with_sudoers_uid in
+ yes) AC_MSG_ERROR(["must give --with-sudoers-uid an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-sudoers-uid not supported."])
+ ;;
+ [[0-9]]*) SUDOERS_UID=$with_sudoers_uid
+ ;;
+ *) AC_MSG_ERROR(["you must use an unsigned numeric uid, not a name."])
+ ;;
+esac])
+
+AC_ARG_WITH(sudoers-gid, [AS_HELP_STRING([--with-sudoers-gid], [gid that owns sudoers file (defaults to 0)])],
+[case $with_sudoers_gid in
+ yes) AC_MSG_ERROR(["must give --with-sudoers-gid an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-sudoers-gid not supported."])
+ ;;
+ [[0-9]]*) SUDOERS_GID=$with_sudoers_gid
+ ;;
+ *) AC_MSG_ERROR(["you must use an unsigned numeric gid, not a name."])
+ ;;
+esac])
+
+AC_MSG_CHECKING(for umask programs should be run with)
+AC_ARG_WITH(umask, [AS_HELP_STRING([--with-umask], [umask with which the prog should run (default is 022)])
+AS_HELP_STRING([--without-umask], [Preserves the umask of the user invoking sudo.])],
+[case $with_umask in
+ yes) AC_MSG_ERROR(["must give --with-umask an argument."])
+ ;;
+ no) sudo_umask=0777
+ ;;
+ [[0-9]]*) sudo_umask=$with_umask
+ ;;
+ *) AC_MSG_ERROR(["you must enter a numeric mask."])
+ ;;
+esac])
+AC_DEFINE_UNQUOTED(SUDO_UMASK, $sudo_umask, [The umask that the sudo-run prog should use.])
+if test "$sudo_umask" = "0777"; then
+ AC_MSG_RESULT(user)
+else
+ AC_MSG_RESULT($sudo_umask)
+fi
+
+AC_ARG_WITH(umask-override, [AS_HELP_STRING([--with-umask-override], [Use the umask specified in sudoers even if it is less restrictive than the user's.])],
+[case $with_umask_override in
+ yes) AC_DEFINE(UMASK_OVERRIDE)
+ umask_override=on
+ ;;
+ no) umask_override=off
+ ;;
+ *) AC_MSG_ERROR(["--with-umask-override does not take an argument."])
+ ;;
+esac])
+
+AC_MSG_CHECKING(for default user to run commands as)
+AC_ARG_WITH(runas-default, [AS_HELP_STRING([--with-runas-default], [User to run commands as (default is "root")])],
+[case $with_runas_default in
+ yes) AC_MSG_ERROR(["must give --with-runas-default an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-runas-default not supported."])
+ ;;
+ *) runas_default="$with_runas_default"
+ ;;
+esac])
+AC_DEFINE_UNQUOTED(RUNAS_DEFAULT, "$runas_default", [The user sudo should run commands as by default.])
+AC_MSG_RESULT([$runas_default])
+
+AC_ARG_WITH(exempt, [AS_HELP_STRING([--with-exempt=group], [no passwd needed for users in this group])],
+[case $with_exempt in
+ yes) AC_MSG_ERROR(["must give --with-exempt an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-exempt not supported."])
+ ;;
+ *) AC_DEFINE_UNQUOTED(EXEMPTGROUP, "$with_exempt", [If defined, users in this group need not enter a passwd (ie "sudo").])
+ AC_MSG_CHECKING(for group to be exempt from password)
+ AC_MSG_RESULT([$with_exempt])
+ ;;
+esac])
+
+AC_MSG_CHECKING(for editor that visudo should use)
+AC_ARG_WITH(editor, [AS_HELP_STRING([--with-editor=path], [Default editor for visudo (defaults to vi)])],
+[case $with_editor in
+ yes) AC_MSG_ERROR(["must give --with-editor an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-editor not supported."])
+ ;;
+ *) AC_DEFINE_UNQUOTED(EDITOR, "$with_editor", [A colon-separated list of pathnames to be used as the editor for visudo.])
+ AC_MSG_RESULT([$with_editor])
+ editor="$with_editor"
+ ;;
+esac], [AC_DEFINE(EDITOR, _PATH_VI) AC_MSG_RESULT(vi)])
+
+AC_MSG_CHECKING(whether to obey EDITOR and VISUAL environment variables)
+AC_ARG_WITH(env-editor, [AS_HELP_STRING([--with-env-editor], [Use the environment variable EDITOR for visudo])],
+[case $with_env_editor in
+ yes) env_editor=on
+ ;;
+ no) env_editor=off
+ ;;
+ *) AC_MSG_ERROR(["--with-env-editor does not take an argument."])
+ ;;
+esac])
+if test "$env_editor" = "on"; then
+ AC_DEFINE(ENV_EDITOR)
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(number of tries a user gets to enter their password)
+AC_ARG_WITH(passwd-tries, [AS_HELP_STRING([--with-passwd-tries], [number of tries to enter password (default is 3)])],
+[case $with_passwd_tries in
+ yes) ;;
+ no) AC_MSG_ERROR(["--without-editor not supported."])
+ ;;
+ [[1-9]]*) passwd_tries=$with_passwd_tries
+ ;;
+ *) AC_MSG_ERROR(["you must enter the numer of tries, > 0"])
+ ;;
+esac])
+AC_DEFINE_UNQUOTED(TRIES_FOR_PASSWORD, $passwd_tries, [The number of tries a user gets to enter their password.])
+AC_MSG_RESULT($passwd_tries)
+
+AC_MSG_CHECKING(time in minutes after which sudo will ask for a password again)
+AC_ARG_WITH(timeout, [AS_HELP_STRING([--with-timeout], [minutes before sudo asks for passwd again (def is 5 minutes)])],
+[case $with_timeout in
+ yes) ;;
+ no) timeout=0
+ ;;
+ [[0-9]]*) timeout=$with_timeout
+ ;;
+ *) AC_MSG_ERROR(["you must enter the numer of minutes."])
+ ;;
+esac])
+AC_DEFINE_UNQUOTED(TIMEOUT, $timeout, [The number of minutes before sudo asks for a password again.])
+AC_MSG_RESULT($timeout)
+
+AC_MSG_CHECKING(time in minutes after the password prompt will time out)
+AC_ARG_WITH(password-timeout, [AS_HELP_STRING([--with-password-timeout], [passwd prompt timeout in minutes (default is 5 minutes)])],
+[case $with_password_timeout in
+ yes) ;;
+ no) password_timeout=0
+ ;;
+ [[0-9]]*) password_timeout=$with_password_timeout
+ ;;
+ *) AC_MSG_ERROR(["you must enter the numer of minutes."])
+ ;;
+esac])
+AC_DEFINE_UNQUOTED(PASSWORD_TIMEOUT, $password_timeout, [The passwd prompt timeout (in minutes).])
+AC_MSG_RESULT($password_timeout)
+
+AC_ARG_WITH(tty-tickets, [AS_HELP_STRING([--with-tty-tickets], [use a different ticket file for each tty])],
+[case $with_tty_tickets in
+ yes) timestamp_type=tty
+ ;;
+ no) timestamp_type=global
+ ;;
+ *) AC_MSG_ERROR(["--with-tty-tickets does not take an argument."])
+ ;;
+esac])
+
+AC_MSG_CHECKING(whether to include insults)
+AC_ARG_WITH(insults, [AS_HELP_STRING([--with-insults], [insult the user for entering an incorrect password])],
+[case $with_insults in
+ yes) insults=on
+ with_classic_insults=yes
+ with_csops_insults=yes
+ ;;
+ disabled) insults=off
+ with_classic_insults=yes
+ with_csops_insults=yes
+ ;;
+ no) insults=off
+ ;;
+ *) AC_MSG_ERROR(["--with-insults does not take an argument."])
+ ;;
+esac])
+if test "$insults" = "on"; then
+ AC_DEFINE(USE_INSULTS)
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_ARG_WITH(all-insults, [AS_HELP_STRING([--with-all-insults], [include all the sudo insult sets])],
+[case $with_all_insults in
+ yes) with_classic_insults=yes
+ with_csops_insults=yes
+ with_hal_insults=yes
+ with_goons_insults=yes
+ with_python_insults=yes
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-all-insults does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(classic-insults, [AS_HELP_STRING([--with-classic-insults], [include the insults from the "classic" sudo])],
+[case $with_classic_insults in
+ yes) AC_DEFINE(CLASSIC_INSULTS)
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-classic-insults does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(csops-insults, [AS_HELP_STRING([--with-csops-insults], [include CSOps insults])],
+[case $with_csops_insults in
+ yes) AC_DEFINE(CSOPS_INSULTS)
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-csops-insults does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(hal-insults, [AS_HELP_STRING([--with-hal-insults], [include 2001-like insults])],
+[case $with_hal_insults in
+ yes) AC_DEFINE(HAL_INSULTS)
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-hal-insults does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(goons-insults, [AS_HELP_STRING([--with-goons-insults], [include the insults from the "Goon Show"])],
+[case $with_goons_insults in
+ yes) AC_DEFINE(GOONS_INSULTS)
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-goons-insults does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(python-insults, [AS_HELP_STRING([--with-python-insults], [include the insults from "Monty Python's Flying Circus"])],
+[case $with_python_insults in
+ yes) AC_DEFINE(PYTHON_INSULTS)
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-python-insults does not take an argument."])
+ ;;
+esac])
+
+AC_ARG_WITH(nsswitch, [AS_HELP_STRING([--with-nsswitch[[=PATH]]], [path to nsswitch.conf])],
+[case $with_nsswitch in
+ no) ;;
+ yes) with_nsswitch="/etc/nsswitch.conf"
+ ;;
+ *) ;;
+esac])
+
+AC_ARG_WITH(ldap, [AS_HELP_STRING([--with-ldap[[=DIR]]], [enable LDAP support])],
+[case $with_ldap in
+ no) ;;
+ *) AC_DEFINE(HAVE_LDAP)
+ AC_MSG_CHECKING(whether to use sudoers from LDAP)
+ AC_MSG_RESULT(yes)
+ ;;
+esac])
+
+AC_ARG_WITH(ldap-conf-file, [AS_HELP_STRING([--with-ldap-conf-file], [path to LDAP configuration file])])
+test -n "$with_ldap_conf_file" && ldap_conf="$with_ldap_conf_file"
+SUDO_DEFINE_UNQUOTED(_PATH_LDAP_CONF, "$ldap_conf", [Path to the ldap.conf file])
+
+AC_ARG_WITH(ldap-secret-file, [AS_HELP_STRING([--with-ldap-secret-file], [path to LDAP secret password file])])
+test -n "$with_ldap_secret_file" && ldap_secret="$with_ldap_secret_file"
+SUDO_DEFINE_UNQUOTED(_PATH_LDAP_SECRET, "$ldap_secret", [Path to the ldap.secret file])
+
+dnl include all insult sets on one line
+if test "$insults" = "on"; then
+ AC_MSG_CHECKING(which insult sets to include)
+ i=""
+ test "$with_python_insults" = "yes" && i="python ${i}"
+ test "$with_goons_insults" = "yes" && i="goons ${i}"
+ test "$with_hal_insults" = "yes" && i="hal ${i}"
+ test "$with_csops_insults" = "yes" && i="csops ${i}"
+ test "$with_classic_insults" = "yes" && i="classic ${i}"
+ AC_MSG_RESULT([$i])
+fi
+
+AC_MSG_CHECKING(whether to override the user's path)
+AC_ARG_WITH(secure-path, [AS_HELP_STRING([--with-secure-path], [override the user's path with a built-in one])],
+[case $with_secure_path in
+ yes) with_secure_path="/bin:/usr/ucb:/usr/bin:/usr/sbin:/sbin:/usr/etc:/etc"
+ AC_DEFINE_UNQUOTED(SECURE_PATH, "$with_secure_path")
+ AC_MSG_RESULT([$with_secure_path])
+ secure_path="set to $with_secure_path"
+ ;;
+ no) AC_MSG_RESULT(no)
+ ;;
+ *) AC_DEFINE_UNQUOTED(SECURE_PATH, "$with_secure_path")
+ AC_MSG_RESULT([$with_secure_path])
+ secure_path="set to F<$with_secure_path>"
+ ;;
+esac], AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(whether to get ip addresses from the network interfaces)
+AC_ARG_WITH(interfaces, [AS_HELP_STRING([--without-interfaces], [don't try to read the ip addr of ether interfaces])],
+[case $with_interfaces in
+ yes) AC_MSG_RESULT(yes)
+ ;;
+ no) AC_DEFINE(STUB_LOAD_INTERFACES)
+ AC_MSG_RESULT(no)
+ ;;
+ *) AC_MSG_ERROR(["--with-interfaces does not take an argument."])
+ ;;
+esac], AC_MSG_RESULT(yes))
+
+AC_MSG_CHECKING(whether to use an askpass helper)
+AC_ARG_WITH(askpass, [AS_HELP_STRING([--with-askpass=PATH], [Fully qualified pathname of askpass helper])],
+[case $with_askpass in
+ yes) AC_MSG_ERROR(["--with-askpass takes a path as an argument."])
+ ;;
+ no) ;;
+ *) ;;
+esac], [
+ with_askpass=no
+ AC_MSG_RESULT(no)
+])
+if test X"$with_askpass" != X"no"; then
+ SUDO_DEFINE_UNQUOTED(_PATH_SUDO_ASKPASS, "$with_askpass")
+else
+ SUDO_DEFINE_UNQUOTED(_PATH_SUDO_ASKPASS, NULL)
+fi
+
+AC_ARG_WITH(exampledir, [AS_HELP_STRING([--with-exampledir=DIR], [path to install sudo examples in])],
+[case $with_exampledir in
+ yes) AC_MSG_ERROR(["must give --with-exampledir an argument."])
+ ;;
+ no) AC_MSG_ERROR(["--without-exampledir not supported."])
+ ;;
+ *) exampledir="$with_exampledir"
+esac])
+
+AC_ARG_WITH(plugindir, [AS_HELP_STRING([--with-plugindir=DIR], [set directory to load plugins from])],
+[case $with_plugindir in
+ no) AC_MSG_ERROR(["illegal argument: --without-plugindir."])
+ ;;
+ *) ;;
+esac], [with_plugindir="$libexecdir/sudo"])
+
+AC_ARG_WITH(man, [AS_HELP_STRING([--with-man], [manual pages use man macros])],
+[case $with_man in
+ yes) MANTYPE=man
+ ;;
+ no) AC_MSG_ERROR(["--without-man not supported."])
+ ;;
+ *) AC_MSG_ERROR(["ignoring unknown argument to --with-man: $with_man."])
+ ;;
+esac])
+
+AC_ARG_WITH(mdoc, [AS_HELP_STRING([--with-mdoc], [manual pages use mdoc macros])],
+[case $with_mdoc in
+ yes) MANTYPE=mdoc
+ ;;
+ no) AC_MSG_ERROR(["--without-mdoc not supported."])
+ ;;
+ *) AC_MSG_ERROR(["ignoring unknown argument to --with-mdoc: $with_mdoc."])
+ ;;
+esac])
+
+dnl
+dnl Options for --enable
+dnl
+
+AC_MSG_CHECKING(whether to do user authentication by default)
+AC_ARG_ENABLE(authentication,
+[AS_HELP_STRING([--disable-authentication], [Do not require authentication by default])],
+[ case "$enableval" in
+ yes) AC_MSG_RESULT(yes)
+ ;;
+ no) AC_MSG_RESULT(no)
+ AC_DEFINE(NO_AUTHENTICATION)
+ ;;
+ *) AC_MSG_RESULT(no)
+ AC_MSG_WARN([Ignoring unknown argument to --enable-authentication: $enableval])
+ ;;
+ esac
+], AC_MSG_RESULT(yes))
+
+AC_MSG_CHECKING(whether to disable running the mailer as root)
+AC_ARG_ENABLE(root-mailer,
+[AS_HELP_STRING([--disable-root-mailer], [Don't run the mailer as root, run as the user])],
+[ case "$enableval" in
+ yes) AC_MSG_RESULT(no)
+ ;;
+ no) AC_MSG_RESULT(yes)
+ AC_DEFINE(NO_ROOT_MAILER)
+ ;;
+ *) AC_MSG_RESULT(no)
+ AC_MSG_WARN([Ignoring unknown argument to --enable-root-mailer: $enableval])
+ ;;
+ esac
+], AC_MSG_RESULT(no))
+
+AC_ARG_ENABLE(setreuid,
+[AS_HELP_STRING([--disable-setreuid], [Don't try to use the setreuid() function])],
+[ case "$enableval" in
+ no) SKIP_SETREUID=yes
+ ;;
+ *) ;;
+ esac
+])
+
+AC_ARG_ENABLE(setresuid,
+[AS_HELP_STRING([--disable-setresuid], [Don't try to use the setresuid() function])],
+[ case "$enableval" in
+ no) SKIP_SETRESUID=yes
+ ;;
+ *) ;;
+ esac
+])
+
+AC_MSG_CHECKING(whether to disable shadow password support)
+AC_ARG_ENABLE(shadow,
+[AS_HELP_STRING([--disable-shadow], [Never use shadow passwords])],
+[ case "$enableval" in
+ yes) AC_MSG_RESULT(no)
+ ;;
+ no) AC_MSG_RESULT(yes)
+ CHECKSHADOW="false"
+ ;;
+ *) AC_MSG_RESULT(no)
+ AC_MSG_WARN([Ignoring unknown argument to --enable-shadow: $enableval])
+ ;;
+ esac
+], AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(whether root should be allowed to use sudo)
+AC_ARG_ENABLE(root-sudo,
+[AS_HELP_STRING([--disable-root-sudo], [Don't allow root to run sudo])],
+[ case "$enableval" in
+ yes) AC_MSG_RESULT(yes)
+ ;;
+ no) AC_DEFINE(NO_ROOT_SUDO)
+ AC_MSG_RESULT(no)
+ root_sudo=off
+ ;;
+ *) AC_MSG_ERROR(["--enable-root-sudo does not take an argument."])
+ ;;
+ esac
+], AC_MSG_RESULT(yes))
+
+AC_MSG_CHECKING(whether to log the hostname in the log file)
+AC_ARG_ENABLE(log-host,
+[AS_HELP_STRING([--enable-log-host], [Log the hostname in the log file])],
+[ case "$enableval" in
+ yes) AC_MSG_RESULT(yes)
+ AC_DEFINE(HOST_IN_LOG)
+ ;;
+ no) AC_MSG_RESULT(no)
+ ;;
+ *) AC_MSG_RESULT(no)
+ AC_MSG_WARN([Ignoring unknown argument to --enable-log-host: $enableval])
+ ;;
+ esac
+], AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(whether to invoke a shell if sudo is given no arguments)
+AC_ARG_ENABLE(noargs-shell,
+[AS_HELP_STRING([--enable-noargs-shell], [If sudo is given no arguments run a shell])],
+[ case "$enableval" in
+ yes) AC_MSG_RESULT(yes)
+ AC_DEFINE(SHELL_IF_NO_ARGS)
+ ;;
+ no) AC_MSG_RESULT(no)
+ ;;
+ *) AC_MSG_RESULT(no)
+ AC_MSG_WARN([Ignoring unknown argument to --enable-noargs-shell: $enableval])
+ ;;
+ esac
+], AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(whether to set \$HOME to target user in shell mode)
+AC_ARG_ENABLE(shell-sets-home,
+[AS_HELP_STRING([--enable-shell-sets-home], [Set $HOME to target user in shell mode])],
+[ case "$enableval" in
+ yes) AC_MSG_RESULT(yes)
+ AC_DEFINE(SHELL_SETS_HOME)
+ ;;
+ no) AC_MSG_RESULT(no)
+ ;;
+ *) AC_MSG_RESULT(no)
+ AC_MSG_WARN([Ignoring unknown argument to --enable-shell-sets-home: $enableval])
+ ;;
+ esac
+], AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(whether to disable 'command not found' messages)
+AC_ARG_ENABLE(path_info,
+[AS_HELP_STRING([--disable-path-info], [Print 'command not allowed' not 'command not found'])],
+[ case "$enableval" in
+ yes) AC_MSG_RESULT(no)
+ ;;
+ no) AC_MSG_RESULT(yes)
+ AC_DEFINE(DONT_LEAK_PATH_INFO)
+ path_info=off
+ ;;
+ *) AC_MSG_RESULT(no)
+ AC_MSG_WARN([Ignoring unknown argument to --enable-path-info: $enableval])
+ ;;
+ esac
+], AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(whether to enable environment debugging)
+AC_ARG_ENABLE(env_debug,
+[AS_HELP_STRING([--enable-env-debug], [Whether to enable environment debugging.])],
+[ case "$enableval" in
+ yes) AC_MSG_RESULT(yes)
+ AC_DEFINE(ENV_DEBUG)
+ ;;
+ no) AC_MSG_RESULT(no)
+ ;;
+ *) AC_MSG_RESULT(no)
+ AC_MSG_WARN([Ignoring unknown argument to --enable-env-debug: $enableval])
+ ;;
+ esac
+], AC_MSG_RESULT(no))
+
+AC_ARG_ENABLE(zlib,
+[AS_HELP_STRING([--enable-zlib[[=PATH]]], [Whether to enable or disable zlib])],
+[], [enable_zlib=yes])
+AX_APPEND_FLAG([-DZLIB_CONST], [CPPFLAGS])
+
+AC_MSG_CHECKING(whether to enable environment resetting by default)
+AC_ARG_ENABLE(env_reset,
+[AS_HELP_STRING([--enable-env-reset], [Whether to enable environment resetting by default.])],
+[ case "$enableval" in
+ yes) env_reset=on
+ ;;
+ no) env_reset=off
+ ;;
+ *) env_reset=on
+ AC_MSG_WARN([Ignoring unknown argument to --enable-env-reset: $enableval])
+ ;;
+ esac
+])
+if test "$env_reset" = "on"; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(ENV_RESET, 1)
+else
+ AC_MSG_RESULT(no)
+ AC_DEFINE(ENV_RESET, 0)
+fi
+
+AC_ARG_ENABLE(warnings,
+[AS_HELP_STRING([--enable-warnings], [Whether to enable compiler warnings])],
+[ case "$enableval" in
+ yes) ;;
+ no) ;;
+ *) AC_MSG_WARN([Ignoring unknown argument to --enable-warnings: $enableval])
+ ;;
+ esac
+])
+
+AC_ARG_ENABLE(werror,
+[AS_HELP_STRING([--enable-werror], [Whether to enable the -Werror compiler option])],
+[ case "$enableval" in
+ yes) ;;
+ no) ;;
+ *) AC_MSG_WARN([Ignoring unknown argument to --enable-werror: $enableval])
+ ;;
+ esac
+])
+
+AC_ARG_ENABLE(openssl,
+[AS_HELP_STRING([--enable-openssl], [Use OpenSSL's message digest functions instead of sudo's])],
+[ case $enableval in
+ no) ;;
+ *) LIBMD="-lcrypto"
+ DIGEST=digest_openssl.lo
+ AC_DEFINE(HAVE_OPENSSL)
+ if test "$enableval" != "yes"; then
+ AX_APPEND_FLAG([-I${enableval}/include], [CPPFLAGS])
+ SUDO_APPEND_LIBPATH(SUDOERS_LDFLAGS, [${enableval}/lib])
+ fi
+ ;;
+ esac
+])
+
+AC_ARG_ENABLE(gcrypt,
+[AS_HELP_STRING([--enable-gcrypt], [Use GNU crypt's message digest functions instead of sudo's])],
+[ case $enableval in
+ no) ;;
+ *) LIBMD="-lgcrypt"
+ DIGEST=digest_gcrypt.lo
+ AC_DEFINE(HAVE_GCRYPT)
+ if test "$enableval" != "yes"; then
+ AX_APPEND_FLAG([-I${enableval}/include], [CPPFLAGS])
+ SUDO_APPEND_LIBPATH(SUDOERS_LDFLAGS, [${enableval}/lib])
+ fi
+ ;;
+ esac
+])
+
+AC_ARG_ENABLE(hardening,
+[AS_HELP_STRING([--disable-hardening], [Do not use compiler/linker exploit mitigation options])],
+[], [enable_hardening=yes])
+
+AC_ARG_ENABLE(pie,
+[AS_HELP_STRING([--enable-pie], [Build sudo as a position independent executable.])])
+
+AC_ARG_ENABLE(asan,
+[AS_HELP_STRING([--enable-asan], [Build sudo with address sanitizer support.])])
+
+AC_ARG_ENABLE(poll,
+[AS_HELP_STRING([--disable-poll], [Use select() instead of poll().])])
+
+AC_ARG_ENABLE(admin-flag,
+[AS_HELP_STRING([--enable-admin-flag], [Whether to create a Ubuntu-style admin flag file])],
+[ case "$enableval" in
+ yes) AC_DEFINE(USE_ADMIN_FLAG)
+ ;;
+ no) ;;
+ *) AC_MSG_WARN([Ignoring unknown argument to --enable-admin-flag: $enableval])
+ ;;
+ esac
+])
+
+AC_ARG_ENABLE(nls,
+[AS_HELP_STRING([--disable-nls], [Disable natural language support using gettext])],
+[], [enable_nls=yes])
+
+AC_ARG_ENABLE(rpath,
+[AS_HELP_STRING([--disable-rpath], [Disable passing of -Rpath to the linker])],
+[], [enable_rpath=yes])
+
+AC_ARG_ENABLE(static-sudoers,
+[AS_HELP_STRING([--enable-static-sudoers], [Build the sudoers policy module as part of the sudo binary instead as a plugin])],
+[], [enable_static_sudoers=no])
+
+AC_ARG_ENABLE(shared_libutil,
+[AS_HELP_STRING([--disable-shared-libutil], [Disable use of the libsudo_util shared library.])],
+[], [enable_shared_libutil=yes])
+
+AC_ARG_ENABLE(tmpfiles.d,
+[AS_HELP_STRING([--enable-tmpfiles.d=DIR], [Set the path to the systemd tmpfiles.d directory.])],
+[case $enableval in
+ yes) TMPFILES_D=/usr/lib/tmpfiles.d
+ ;;
+ no) TMPFILES_D=
+ ;;
+ *) TMPFILES_D="$enableval"
+esac], [
+ test -f /usr/lib/tmpfiles.d/systemd.conf && TMPFILES_D=/usr/lib/tmpfiles.d
+])
+
+AC_ARG_ENABLE(devsearch,
+[AS_HELP_STRING([--enable-devsearch=PATH], [The colon-delimited path to search for device nodes when determing the tty name.])],
+[case $enableval in
+ yes) # use default value
+ ;;
+ no) AC_MSG_WARN([Ignoring attempt to disable the device search path])
+ ;;
+ *) devsearch="$enableval"
+ ;;
+esac])
+ds="`echo \"$devsearch\"|sed 's@/dev/*\([[^:]]*:*\)@_PATH_DEV \"\1\" @g'`"
+SUDO_DEFINE_UNQUOTED(_PATH_SUDO_DEVSEARCH, $ds)
+
+AC_ARG_WITH(selinux, [AS_HELP_STRING([--with-selinux], [enable SELinux support])],
+[case $with_selinux in
+ yes) SELINUX_USAGE="[[-r role]] [[-t type]] "
+ AC_DEFINE(HAVE_SELINUX)
+ SUDO_LIBS="${SUDO_LIBS} -lselinux"
+ SUDO_OBJS="${SUDO_OBJS} selinux.o"
+ PROGS="${PROGS} sesh"
+ SEMAN=1
+ AC_CHECK_LIB([selinux], [setkeycreatecon],
+ [AC_DEFINE(HAVE_SETKEYCREATECON)])
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-selinux does not take an argument."])
+ ;;
+esac], [with_selinux=no])
+
+AC_ARG_ENABLE(sasl,
+[AS_HELP_STRING([--enable-sasl], [Enable/disable LDAP SASL support])],
+[ case "$enableval" in
+ yes|no) ;;
+ *) AC_MSG_WARN([Ignoring unknown argument to --enable-sasl: $enableval])
+ ;;
+ esac
+])
+
+AC_ARG_ENABLE(timestamp-type,
+[AS_HELP_STRING([--timestamp-type=TYPE], [Set the default time stamp record type to global, ppid or tty.])],
+[ case "$enableval" in
+ global|ppid|tty)
+ timestamp_type=$enableval
+ ;;
+ *) AC_MSG_WARN([Ignoring unknown argument to --enable-timestamp-type: $enableval])
+ ;;
+ esac
+])
+AC_DEFINE_UNQUOTED(TIMESTAMP_TYPE, $timestamp_type)
+
+AC_ARG_ENABLE(offensive_insults,
+[AS_HELP_STRING([--enable-offensive-insults], [Enable potentially offensive sudo insults.])],
+[], [enable_offensive_insults=no])
+if test "$enable_offensive_insults" = "yes"; then
+ AC_DEFINE(OFFENSIVE_INSULTS)
+fi
+
+AC_ARG_ENABLE(package_build,
+[AS_HELP_STRING([--enable-package-build], [Enable options for package building.])],
+[], [enable_package_build=no])
+
+dnl
+dnl gss_krb5_ccache_name() may not work on Heimdal so we don't use it by default
+dnl
+AC_ARG_ENABLE(gss_krb5_ccache_name,
+[AS_HELP_STRING([--enable-gss-krb5-ccache-name], [Use GSS-API to set the Kerberos V cred cache name])],
+[check_gss_krb5_ccache_name=$enableval], [check_gss_krb5_ccache_name=no])
+
+AC_ARG_ENABLE(pvs-studio,
+[AS_HELP_STRING([--enable-pvs-studio], [Create a PVS-Studio.cfg file.])])
+
+dnl
+dnl C compiler checks
+dnl
+AC_SEARCH_LIBS([strerror], [cposix])
+AC_PROG_CPP
+AC_CHECK_TOOL(AR, ar, false)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+if test X"$AR" = X"false"; then
+ AC_MSG_ERROR([the "ar" utility is required to build sudo])
+fi
+
+if test "x$ac_cv_prog_cc_c89" = "xno"; then
+ AC_MSG_ERROR([Sudo version $PACKAGE_VERSION requires an ANSI C compiler to build.])
+fi
+
+dnl
+dnl If the user specified --disable-static, override them or we'll
+dnl be unable to build the executables in the sudoers plugin dir.
+dnl
+if test "$enable_static" = "no"; then
+ AC_MSG_WARN([Ignoring --disable-static, sudo does not install static libs])
+ enable_static=yes
+fi
+
+dnl
+dnl Set host variables and m4 macro dir
+dnl
+AC_CANONICAL_HOST
+AC_CONFIG_MACRO_DIR([m4])
+
+dnl
+dnl On AIX we need to force libtool to install .so files for the plugins
+dnl instead of a .a file that contains the .so. We do this by enabling
+dnl runtime linking (where the .so file is installed). This must happen
+dnl before the call to LT_INIT
+dnl
+case "$host_os" in
+aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ AX_APPEND_FLAG([-Wl,-brtl], [LDFLAGS])
+ ;;
+esac
+
+dnl
+dnl Libtool init, we require libtool 2.2.6b or higher
+dnl
+LT_PREREQ([2.2.6b])
+LT_INIT([dlopen])
+
+dnl
+dnl Allow the user to specify an alternate libtool.
+dnl XXX - should be able to skip LT_INIT if we are using a different libtool
+dnl
+AC_ARG_WITH(libtool, [AS_HELP_STRING([--with-libtool=PATH], [specify path to libtool])],
+[case $with_libtool in
+ yes|builtin) ;;
+ no) AC_MSG_ERROR(["--without-libtool not supported."])
+ ;;
+ system) LIBTOOL=libtool
+ ;;
+ *) LIBTOOL="$with_libtool"
+ ;;
+esac])
+
+dnl
+dnl Defer with_noexec until after libtool magic runs
+dnl
+if test "$enable_shared" = "no"; then
+ with_noexec=no
+ enable_dlopen=no
+ lt_cv_dlopen=none
+ lt_cv_dlopen_libs=
+ ac_cv_func_dlopen=no
+ LT_LDFLAGS=-static
+fi
+LIBDL="$lt_cv_dlopen_libs"
+SHLIB_ENABLE="$enable_dlopen"
+
+AC_MSG_CHECKING(path to sudo_noexec.so)
+AC_ARG_WITH(noexec, [AS_HELP_STRING([--with-noexec[[=PATH]]], [fully qualified pathname of sudo_noexec.so])],
+[case $with_noexec in
+ yes) with_noexec="$libexecdir/sudo/sudo_noexec.so"
+ ;;
+ no) ;;
+ *) ;;
+esac], [with_noexec="$libexecdir/sudo/sudo_noexec.so"])
+AC_MSG_RESULT($with_noexec)
+NOEXECFILE="sudo_noexec.so"
+NOEXECDIR="`echo $with_noexec|sed -e 's:^${\([[^}]]*\)}:$(\1):' -e 's:^\(.*\)/[[^/]]*:\1:'`"
+
+dnl
+dnl Find programs we use
+dnl
+AC_PATH_PROG(UNAMEPROG, [uname], [uname])
+AC_PATH_PROG(TRPROG, [tr], [tr])
+AC_PATH_PROG(MANDOCPROG, [mandoc], [mandoc])
+if test "$MANDOCPROG" != "mandoc"; then
+ : ${MANTYPE='mdoc'}
+else
+ AC_PATH_PROG(NROFFPROG, [nroff])
+ if test -n "$NROFFPROG"; then
+ test -n "$MANTYPE" && sudo_cv_var_mantype="$MANTYPE"
+ AC_CACHE_CHECK([which macro set to use for manual pages],
+ [sudo_cv_var_mantype],
+ [
+ sudo_cv_var_mantype="man"
+ echo ".Sh NAME" > conftest
+ echo ".Nm sudo" >> conftest
+ echo ".Nd sudo" >> conftest
+ echo ".Sh DESCRIPTION" >> conftest
+ echo "sudo" >> conftest
+ if $NROFFPROG -mdoc conftest >/dev/null 2>&1; then
+ sudo_cv_var_mantype="mdoc"
+ fi
+ rm -f conftest
+ ]
+ )
+ MANTYPE="$sudo_cv_var_mantype"
+ else
+ MANTYPE=cat
+ MANDIRTYPE=cat
+ mansrcdir='$(srcdir)'
+ fi
+fi
+
+dnl
+dnl What kind of beastie are we being run on?
+dnl Barf if config.cache was generated on another host.
+dnl
+if test -n "$sudo_cv_prev_host"; then
+ if test "$sudo_cv_prev_host" != "$host"; then
+ AC_MSG_ERROR([config.cache was created on a different host; remove it and re-run configure.])
+ else
+ AC_MSG_CHECKING(previous host type)
+ AC_CACHE_VAL(sudo_cv_prev_host, sudo_cv_prev_host="$host")
+ AC_MSG_RESULT([$sudo_cv_prev_host])
+ fi
+else
+ # this will produce no output since there is no cached value
+ AC_CACHE_VAL(sudo_cv_prev_host, sudo_cv_prev_host="$host")
+fi
+
+dnl
+dnl We want to be able to differentiate between different rev's
+dnl
+if test -n "$host_os"; then
+ OS=`echo $host_os | sed 's/[[0-9]].*//'`
+ OSREV=`echo $host_os | sed 's/^[[^0-9\.]]*\([[0-9\.]]*\).*$/\1/'`
+ OSMAJOR=`echo $OSREV | sed 's/\..*$//'`
+else
+ OS="unknown"
+ OSREV=0
+ OSMAJOR=0
+fi
+
+case "$host" in
+ *-*-solaris2*)
+ AC_DEFINE([PAM_SUN_CODEBASE])
+
+ # LD_PRELOAD is space-delimited
+ RTLD_PRELOAD_DELIM=" "
+
+ # Solaris-specific initialization
+ OS_INIT=os_init_solaris
+ SUDO_OBJS="${SUDO_OBJS} solaris.o"
+
+ # AFS support needs -lucb
+ if test "$with_AFS" = "yes"; then
+ AFS_LIBS="-lc -lucb"
+ fi
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ AC_CHECK_FUNCS([priv_set], [PSMAN=1])
+ ;;
+ *-*-aix*)
+ AC_DEFINE([PAM_SUN_CODEBASE])
+
+ # To get all prototypes (so we pass -Wall)
+ AC_DEFINE([_LINUX_SOURCE_COMPAT])
+
+ # For AIX we build in support for both LAM and PAM
+ # and choose which to use based on auth_type in
+ # /etc/security/login.cfg
+ if test X"${with_pam}${with_aixauth}" = X""; then
+ AUTH_EXCL_DEF="AIX_AUTH PAM"
+ fi
+
+ # AIX analog of nsswitch.conf, enabled by default
+ AC_ARG_WITH(netsvc, [AS_HELP_STRING([--with-netsvc[[=PATH]]], [path to netsvc.conf])],
+ [case $with_netsvc in
+ no) ;;
+ yes) with_netsvc="/etc/netsvc.conf"
+ ;;
+ *) ;;
+ esac])
+ if test -z "$with_nsswitch" -a -z "$with_netsvc"; then
+ with_netsvc="/etc/netsvc.conf"
+ fi
+
+ # LDR_PRELOAD is only supported in AIX 5.3 and later
+ case "$OSREV" in
+ [[1-4]].*) with_noexec=no;;
+ 5.[[1-2]]*) with_noexec=no;;
+ *) RTLD_PRELOAD_VAR="LDR_PRELOAD";;
+ esac
+
+ # strnlen/strndup may be broken on AIX < 6 depending
+ # on the libc version, use our own.
+ if test $OSMAJOR -lt 6; then
+ ac_cv_func_strnlen=no
+ fi
+
+ # getline() may or may ont be present on AIX <= 6.1.
+ # bos610 is missing getline/getdelim but bos61J has it.
+ if test "$enable_package_build" = "yes"; then
+ if test $OSMAJOR -le 6; then
+ ac_cv_func_getline=no
+ fi
+ fi
+
+ # memset_s() may or may ont be present on AIX <= 7.1.
+ # bos710 is missing memset_s but bos71L has it.
+ if test "$enable_package_build" = "yes"; then
+ if test $OSMAJOR -le 7; then
+ ac_cv_func_memset_s=no
+ fi
+ fi
+
+ # Remove timedir on boot, AIX does not have /var/run
+ INIT_SCRIPT=aix.sh
+ INIT_DIR=/etc/rc.d/init.d
+ RC_LINK=/etc/rc.d/rc2.d/S90sudo
+
+ # AIX-specific functions
+ AC_CHECK_FUNCS([getuserattr setrlimit64])
+ AC_CHECK_FUNCS([setauthdb],
+ [AC_CHECK_TYPES([authdb_t], [], [], [#include <usersec.h>])])
+
+ COMMON_OBJS="${COMMON_OBJS} aix.lo"
+ SUDO_APPEND_COMPAT_EXP(aix_prep_user_v1 aix_restoreauthdb_v1 aix_setauthdb_v1 aix_setauthdb_v2 aix_getauthregistry_v1)
+
+ # These prototypes may be missing
+ AC_CHECK_DECLS([usrinfo], [], [], [
+#include <sys/types.h>
+#include <uinfo.h>
+ ])
+ AC_CHECK_DECLS([setauthdb], [], [], [
+#include <sys/types.h>
+#include <usersec.h>
+ ])
+ ;;
+ *-*-hiuxmpp*)
+ AC_DEFINE([PAM_SUN_CODEBASE])
+
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+
+ # HP-UX does not clear /var/run so we need to do it
+ INIT_SCRIPT=hpux.sh
+ INIT_DIR=/sbin/init.d
+ RC_LINK=/sbin/rc2.d/S900sudo
+
+ # HP-UX shared libs must be executable.
+ # Load time is much greater if writable so use 0555.
+ SHLIB_MODE=0555
+
+ # HP-UX won't unlink a shared lib that is open
+ INSTALL_BACKUP='~'
+
+ AC_CHECK_FUNCS([pstat_getproc gethrtime])
+ ;;
+ *-*-hpux*)
+ AC_DEFINE([PAM_SUN_CODEBASE])
+
+ # AFS support needs -lBSD
+ if test "$with_AFS" = "yes"; then
+ AFS_LIBS="-lc -lBSD"
+ fi
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+
+ # HP-UX does not clear /var/run so we need to do it
+ INIT_SCRIPT=hpux.sh
+ INIT_DIR=/sbin/init.d
+ RC_LINK=/sbin/rc2.d/S900sudo
+
+ # HP-UX shared libs must be executable.
+ # Load time is much greater if writable so use 0555.
+ SHLIB_MODE=0555
+
+ # HP-UX won't unlink a shared lib that is open
+ INSTALL_BACKUP='~'
+
+ # The HP bundled compiler cannot generate shared libs
+ if test -z "$GCC"; then
+ AC_CACHE_CHECK([for HP bundled C compiler],
+ [sudo_cv_var_hpccbundled],
+ [if $CC -V 2>&1 | grep '^(Bundled)' >/dev/null 2>&1; then
+ sudo_cv_var_hpccbundled=yes
+ else
+ sudo_cv_var_hpccbundled=no
+ fi]
+ )
+ if test "$sudo_cv_var_hpccbundled" = "yes"; then
+ AC_MSG_ERROR([The HP bundled C compiler is unable to build Sudo, you must use gcc or the HP ANSI C compiler instead.])
+ fi
+ fi
+
+ # Build PA-RISC1.1 objects for better portability
+ case "$host_cpu" in
+ hppa[[2-9]]*)
+ _CFLAGS="$CFLAGS"
+ if test -n "$GCC"; then
+ portable_flag="-march=1.1"
+ else
+ portable_flag="+DAportable"
+ fi
+ CFLAGS="$CFLAGS $portable_flag"
+ AC_CACHE_CHECK([whether $CC understands $portable_flag],
+ [sudo_cv_var_daportable],
+ [AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[]], [[]])],
+ [sudo_cv_var_daportable=yes],
+ [sudo_cv_var_daportable=no]
+ )
+ ]
+ )
+ if test X"$sudo_cv_var_daportable" != X"yes"; then
+ CFLAGS="$_CFLAGS"
+ fi
+ ;;
+ esac
+
+ case "$host_os" in
+ hpux10.*)
+ shadow_funcs="getprpwnam iscomsec"
+ shadow_libs="-lsec"
+ # HP-UX 10.20 libc has an incompatible getline
+ ac_cv_func_getline="no"
+ # HP-UX 10.x doesn't support LD_PRELOAD
+ with_noexec=no
+ ;;
+ *)
+ shadow_funcs="getspnam iscomsec"
+ shadow_libs="-lsec"
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ ;;
+ esac
+ AC_CHECK_FUNCS([pstat_getproc gethrtime])
+ ;;
+ *-dec-osf*)
+ # ignore envariables wrt dynamic lib path
+ AX_APPEND_FLAG([-Wl,-no_library_replacement], [SUDO_LDFLAGS])
+
+ : ${CHECKSIA='true'}
+ AC_MSG_CHECKING(whether to disable sia support on Digital UNIX)
+ AC_ARG_ENABLE(sia,
+ [AS_HELP_STRING([--disable-sia], [Disable SIA on Digital UNIX])],
+ [ case "$enableval" in
+ yes) AC_MSG_RESULT(no)
+ CHECKSIA=true
+ ;;
+ no) AC_MSG_RESULT(yes)
+ CHECKSIA=false
+ ;;
+ *) AC_MSG_RESULT(no)
+ AC_MSG_WARN([Ignoring unknown argument to --enable-sia: $enableval])
+ ;;
+ esac
+ ], AC_MSG_RESULT(no))
+
+ shadow_funcs="getprpwnam dispcrypt"
+ # OSF/1 4.x and higher need -ldb too
+ if test $OSMAJOR -lt 4; then
+ shadow_libs="-lsecurity -laud -lm"
+ else
+ shadow_libs="-lsecurity -ldb -laud -lm"
+ fi
+
+ # use SIA by default, if we have it
+ test "$CHECKSIA" = "true" && AUTH_EXCL_DEF="SIA"
+
+ #
+ # Some versions of Digital Unix ship with a broken
+ # copy of prot.h, which we need for shadow passwords.
+ # XXX - make should remove this as part of distclean
+ #
+ AC_MSG_CHECKING([for broken prot.h])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/security.h>
+#include <prot.h>
+ ]], [[exit(0);]])], [AC_MSG_RESULT(no)], [AC_MSG_RESULT([yes, fixing locally])
+ sed 's:<acl.h>:<sys/acl.h>:g' < /usr/include/prot.h > prot.h
+ ])
+ # ":DEFAULT" must be appended to _RLD_LIST
+ RTLD_PRELOAD_VAR="_RLD_LIST"
+ RTLD_PRELOAD_DEFAULT="DEFAULT"
+ : ${mansectsu='8'}
+ : ${mansectform='4'}
+ ;;
+ *-*-irix*)
+ AC_DEFINE([_BSD_TYPES])
+ if test -z "$NROFFPROG"; then
+ if test "$prefix" = "/usr/local" -a "$mandir" = '${datarootdir}/man'; then
+ if test -d /usr/share/catman/local; then
+ mandir="/usr/share/catman/local"
+ else
+ mandir="/usr/catman/local"
+ fi
+ fi
+ # Compress cat pages with pack
+ MANCOMPRESS='pack'
+ MANCOMPRESSEXT='.z'
+ else
+ if test "$prefix" = "/usr/local" -a "$mandir" = '${datarootdir}/man'; then
+ if test -d "/usr/share/man/local"; then
+ mandir="/usr/share/man/local"
+ else
+ mandir="/usr/man/local"
+ fi
+ fi
+ fi
+ # IRIX <= 4 needs -lsun
+ if test "$OSMAJOR" -le 4; then
+ AC_CHECK_LIB(sun, getpwnam, [LIBS="${LIBS} -lsun"])
+ fi
+ # ":DEFAULT" must be appended to _RLD_LIST
+ RTLD_PRELOAD_VAR="_RLD_LIST"
+ RTLD_PRELOAD_DEFAULT="DEFAULT"
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-*-linux*|*-*-k*bsd*-gnu)
+ shadow_funcs="getspnam"
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ # Check for SECCOMP_SET_MODE_FILTER in linux/seccomp.h
+ AC_CHECK_DECLS([SECCOMP_SET_MODE_FILTER], [], [], [
+#include <sys/types.h>
+#include <sys/prctl.h>
+#include <asm/unistd.h>
+#include <linux/seccomp.h>
+#include <linux/filter.h>
+ ])
+ # We call getrandom via syscall(3) in case it is not in libc
+ AC_CHECK_HEADERS([linux/random.h])
+ ;;
+ *-*-gnu*)
+ # lockf() is broken on the Hurd
+ ac_cv_func_lockf=no
+ ;;
+ *-*-riscos*)
+ LIBS="${LIBS} -lsun -lbsd"
+ AX_APPEND_FLAG([-I/usr/include], [CPPFLAGS])
+ AX_APPEND_FLAG([-I/usr/include/bsd], [CPPFLAGS])
+ AX_APPEND_FLAG([-D_MIPS], [CPPFLAGS])
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-*-isc*)
+ AX_APPEND_FLAG([-D_ISC], [CPPFLAGS])
+ LIB_CRYPT=1
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lcrypt"
+
+ shadow_funcs="getspnam"
+ shadow_libs="-lsec"
+
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-*-sco*|*-sco-*)
+ shadow_funcs="getprpwnam"
+ shadow_libs="-lprot -lx"
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ m88k-motorola-sysv*)
+ # motorolla's cc (a variant of gcc) does -O but not -O2
+ CFLAGS=`echo $CFLAGS | sed 's/-O2/-O/g'`
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-sequent-sysv*)
+ shadow_funcs="getspnam"
+ shadow_libs="-lsec"
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-ncr-sysv4*|*-ncr-sysvr4*)
+ AC_CHECK_LIB(c89, strcasecmp, [LIBS="${LIBS} -lc89"])
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-ccur-sysv4*|*-ccur-sysvr4*)
+ LIBS="${LIBS} -lgen"
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-*-bsdi*)
+ SKIP_SETREUID=yes
+ # Check for newer BSD auth API
+ if test -z "$with_bsdauth"; then
+ AC_CHECK_FUNCS([auth_challenge], [AUTH_EXCL_DEF="BSD_AUTH"])
+ fi
+ ;;
+ *-*-freebsd*)
+ AC_DEFINE([_BSD_SOURCE])
+
+ # FreeBSD has a real setreuid(2) starting with 2.1 and
+ # backported to 2.0.5. We just take 2.1 and above...
+ case "$OSREV" in
+ 0.*|1.*|2.0*)
+ SKIP_SETREUID=yes
+ ;;
+ esac
+ if test "${with_skey-'no'}" = "yes"; then
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lmd"
+ fi
+ CHECKSHADOW="false"
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ : ${with_logincap='maybe'}
+
+ # Examples go in share/examples/sudo
+ if test X"$with_exampledir" = X""; then
+ exampledir='$(datarootdir)/examples/$(PACKAGE_TARNAME)'
+ fi
+ ;;
+ *-*-*openbsd*)
+ AC_DEFINE([_BSD_SOURCE])
+
+ # OpenBSD-specific initialization
+ OS_INIT=os_init_openbsd
+ SUDO_OBJS="${SUDO_OBJS} openbsd.o"
+
+ # OpenBSD has a real setreuid(2) starting with 3.3 but
+ # we will use setresuid(2) instead.
+ SKIP_SETREUID=yes
+
+ # OpenBSD >= 3.0 supports BSD auth
+ if test -z "$with_bsdauth"; then
+ if test "$OSMAJOR" -ge 3; then
+ AUTH_EXCL_DEF="BSD_AUTH"
+ fi
+ fi
+ : ${with_logincap='maybe'}
+
+ # Newer OpenBSD only fills in pw_password for getpwnam_shadow()
+ shadow_funcs="getpwnam_shadow"
+
+ # Examples go in share/examples/sudo
+ if test X"$with_exampledir" = X""; then
+ exampledir='$(datarootdir)/examples/$(PACKAGE_TARNAME)'
+ fi
+ ;;
+ *-*-*netbsd*)
+ # NetBSD has a real setreuid(2) starting with 1.3.2
+ case "$OSREV" in
+ 0.9*|1.[[012]]*|1.3|1.3.1)
+ SKIP_SETREUID=yes
+ ;;
+ esac
+ CHECKSHADOW="false"
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ : ${with_logincap='maybe'}
+
+ # Examples go in share/examples/sudo
+ if test X"$with_exampledir" = X""; then
+ exampledir='$(datarootdir)/examples/$(PACKAGE_TARNAME)'
+ fi
+ ;;
+ *-*-dragonfly*)
+ AC_DEFINE([_BSD_SOURCE])
+
+ if test "${with_skey-'no'}" = "yes"; then
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lmd"
+ fi
+ CHECKSHADOW="false"
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ : ${with_logincap='yes'}
+
+ # Examples go in share/examples/sudo
+ if test X"$with_exampledir" = X""; then
+ exampledir='$(datarootdir)/examples/$(PACKAGE_TARNAME)'
+ fi
+ ;;
+ *-*-*bsd*)
+ CHECKSHADOW="false"
+ # Examples go in share/examples/sudo
+ if test X"$with_exampledir" = X""; then
+ exampledir='$(datarootdir)/examples/$(PACKAGE_TARNAME)'
+ fi
+ ;;
+ *-*-darwin*)
+ # Darwin has a real setreuid(2) starting with 9.0
+ if test $OSMAJOR -lt 9; then
+ SKIP_SETREUID=yes
+ fi
+ CHECKSHADOW="false"
+ test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ : ${with_logincap='yes'}
+ # Darwin has a broken poll()
+ : ${enable_poll='no'}
+ # Darwin 8 and above can interpose library symbols cleanly
+ if test $OSMAJOR -ge 8; then
+ AC_DEFINE(HAVE___INTERPOSE)
+ dlyld_interpose=yes
+ else
+ RTLD_PRELOAD_ENABLE_VAR="DYLD_FORCE_FLAT_NAMESPACE"
+ fi
+ RTLD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES"
+
+ # Mach monotonic timer that runs while sleeping
+ AC_CHECK_FUNCS([mach_continuous_time])
+
+ # Undocumented API that dynamically allocates the groups.
+ AC_CHECK_FUNCS([getgrouplist_2], [AC_CHECK_DECLS([getgrouplist_2])])
+
+ # We need to force a flat namespace to make libc
+ # symbol hooking work like it does on ELF.
+ AX_CHECK_LINK_FLAG([-Wl,-force_flat_namespace], [AX_APPEND_FLAG([-Wl,-force_flat_namespace], [SUDO_LDFLAGS])])
+
+ # Examples go in share/examples/sudo
+ if test X"$with_exampledir" = X""; then
+ exampledir='$(datarootdir)/examples/$(PACKAGE_TARNAME)'
+ fi
+ ;;
+ *-*-nextstep*)
+ # lockf() is broken on the NeXT
+ ac_cv_func_lockf=no
+ RTLD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES"
+ RTLD_PRELOAD_ENABLE_VAR="DYLD_FORCE_FLAT_NAMESPACE"
+ ;;
+ *-*-*sysv4*)
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+ *-*-sysv*)
+ : ${mansectsu='1m'}
+ : ${mansectform='4'}
+ ;;
+esac
+
+if test X"$enable_pvs_studio" = X"yes"; then
+ # Determine preprocessor type
+ case "$CC" in
+ *clang*) preprocessor=clang;;
+ *gcc*) preprocessor=gcc;;
+ *)
+ case `$CC --version 2>&1` in
+ *clang*) preprocessor=clang;;
+ *gcc*) preprocessor=gcc;;
+ *) AC_MSG_ERROR([Compiler must be gcc or clang for PVS-Studio.]);;
+ esac
+ ;;
+ esac
+
+ # Determine platform (currently linux or macos)
+ case "$host" in
+ x86_64-*-linux*) pvs_platform=linux64;;
+ *86-*-linux*) pvs_platform=linux32;;
+ darwin*) pvs_platform=macos;;
+ *) AC_MSG_ERROR([PVS-Studio does not support $host_os.]);;
+ esac
+
+ # create basic PVS-Studio.cfg file
+ cat > PVS-Studio.cfg <<-EOF
+ preprocessor = $preprocessor
+ platform = $pvs_platform
+ analysis-mode = 4
+ language = C
+EOF
+fi
+
+dnl
+dnl Library preloading to support NOEXEC
+dnl
+if test -n "$with_noexec"; then
+ SUDO_DEFINE_UNQUOTED(RTLD_PRELOAD_VAR, "$RTLD_PRELOAD_VAR")
+ SUDO_DEFINE_UNQUOTED(RTLD_PRELOAD_DELIM, "$RTLD_PRELOAD_DELIM")
+ if test -n "$RTLD_PRELOAD_DEFAULT"; then
+ SUDO_DEFINE_UNQUOTED(RTLD_PRELOAD_DEFAULT, "$RTLD_PRELOAD_DEFAULT")
+ fi
+ if test -n "$RTLD_PRELOAD_ENABLE_VAR"; then
+ SUDO_DEFINE_UNQUOTED(RTLD_PRELOAD_ENABLE_VAR, "$RTLD_PRELOAD_ENABLE_VAR")
+ fi
+fi
+
+dnl
+dnl Check for mixing mutually exclusive and regular auth methods
+dnl
+AUTH_REG=${AUTH_REG# }
+AUTH_EXCL=${AUTH_EXCL# }
+if test -n "$AUTH_EXCL"; then
+ if test -n "$AUTH_REG"; then
+ AC_MSG_ERROR([Cannot mix mutually exclusive ($AUTH_EXCL) and regular ($AUTH_REG) authentication methods])
+ fi
+fi
+dnl
+dnl Only one of S/Key and OPIE may be specified
+dnl
+if test X"${with_skey}${with_opie}" = X"yesyes"; then
+ AC_MSG_ERROR(["cannot use both S/Key and OPIE"])
+fi
+
+dnl
+dnl Use BSD-style man sections by default
+dnl
+: ${mansectsu='8'}
+: ${mansectform='5'}
+
+dnl
+dnl Add in any libpaths or libraries specified via configure
+dnl
+if test -n "$with_libpath"; then
+ for i in ${with_libpath}; do
+ SUDO_APPEND_LIBPATH(LDFLAGS, [$i])
+ done
+fi
+if test -n "$with_libraries"; then
+ for i in ${with_libraries}; do
+ case $i in
+ -l*) ;;
+ *.a) ;;
+ *.o) ;;
+ *) i="-l${i}";;
+ esac
+ LIBS="${LIBS} ${i}"
+ done
+fi
+
+dnl
+dnl C compiler checks (to be done after os checks)
+dnl
+AC_PROG_CC_STDC
+AC_C_CONST
+AC_C_INLINE
+AC_C_VOLATILE
+AC_MSG_CHECKING([for variadic macro support in cpp])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
+AC_INCLUDES_DEFAULT
+#if defined(__GNUC__) && __GNUC__ == 2
+# define sudo_fprintf(fp, fmt...) fprintf((fp), (fmt))
+#else
+# define sudo_fprintf(fp, ...) fprintf((fp), __VA_ARGS__)
+#endif
+], [sudo_fprintf(stderr, "a %s", "test");])], [AC_MSG_RESULT([yes])],
+[AC_MSG_RESULT([no])
+ AC_DEFINE([NO_VARIADIC_MACROS], [1], [Define if your C preprocessor does not support variadic macros.])
+ AC_MSG_WARN([Your C preprocessor doesn't support variadic macros, debugging support will be limited])
+ SUDO_APPEND_COMPAT_EXP(sudo_debug_printf_nvm_v1)
+])
+
+dnl
+dnl Program checks
+dnl
+AC_PROG_AWK
+AC_PROG_YACC
+AC_PATH_PROG([FLEX], [flex], [flex])
+SUDO_PROG_MV
+SUDO_PROG_BSHELL
+if test -z "$with_sendmail"; then
+ SUDO_PROG_SENDMAIL
+fi
+SUDO_PROG_VI
+dnl
+dnl Check for authpriv support in syslog
+dnl
+AC_MSG_CHECKING(which syslog facility sudo should log with)
+if test X"$with_logfac" = X""; then
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <syslog.h>]], [[int i = LOG_AUTHPRIV; (void)i;]])], [logfac=authpriv])
+fi
+AC_DEFINE_UNQUOTED(LOGFAC, "$logfac", [The syslog facility sudo will use.])
+AC_MSG_RESULT($logfac)
+dnl
+dnl Header file checks
+dnl
+AC_HEADER_DIRENT
+AC_HEADER_STDBOOL
+AC_HEADER_MAJOR
+AC_CHECK_HEADERS_ONCE([netgroup.h paths.h spawn.h wordexp.h sys/sockio.h sys/bsdtypes.h sys/select.h sys/stropts.h sys/sysmacros.h sys/syscall.h sys/statvfs.h])
+AC_CHECK_HEADERS([utmps.h] [utmpx.h], [break])
+AC_CHECK_HEADERS([endian.h] [sys/endian.h] [machine/endian.h], [break])
+AC_CHECK_HEADERS([procfs.h] [sys/procfs.h], [AC_CHECK_MEMBERS(struct psinfo.pr_ttydev, [AC_CHECK_FUNCS([_ttyname_dev])], [], [AC_INCLUDES_DEFAULT
+#ifdef HAVE_PROCFS_H
+#include <procfs.h>
+#endif
+#ifdef HAVE_SYS_PROCFS_H
+#include <sys/procfs.h>
+#endif
+])]
+break)
+#
+# Check for large file support.
+#
+AC_SYS_LARGEFILE
+#
+# HP-UX may need to define _XOPEN_SOURCE_EXTENDED to expose MSG_WAITALL.
+# Also, HP-UX 11.23 has a broken sys/types.h when large files support
+# is enabled and _XOPEN_SOURCE_EXTENDED is not also defined.
+# The following test will define _XOPEN_SOURCE_EXTENDED in either case.
+#
+case "$host_os" in
+ hpux*)
+ AC_CACHE_CHECK([whether sys/socket.h needs _XOPEN_SOURCE_EXTENDED for MSG_WAITALL], [sudo_cv_xopen_source_extended],
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
+# include <sys/socket.h>], [int a = MSG_WAITALL; return a;])],
+ [sudo_cv_xopen_source_extended=no], [
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#define _XOPEN_SOURCE_EXTENDED
+ AC_INCLUDES_DEFAULT
+# include <sys/socket.h>
+# include <net/if.h>], [int a = MSG_WAITALL; return a;])],
+ [sudo_cv_xopen_source_extended=yes],
+ [sudo_cv_xopen_source_extended=error])
+ ])])
+ if test "$sudo_cv_xopen_source_extended" = "yes"; then
+ AC_DEFINE([_XOPEN_SOURCE_EXTENDED])
+ fi
+ ;;
+esac
+AC_SYS_POSIX_TERMIOS
+if test "$ac_cv_sys_posix_termios" != "yes"; then
+ AC_MSG_ERROR([Must have POSIX termios to build sudo])
+fi
+SUDO_MAILDIR
+if test ${with_logincap-'no'} != "no"; then
+ AC_CHECK_HEADERS([login_cap.h], [LOGINCAP_USAGE='[[-c class]] '; LCMAN=1
+ case "$OS" in
+ freebsd|netbsd)
+ SUDO_LIBS="${SUDO_LIBS} -lutil"
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lutil"
+ ;;
+ esac
+ ])
+fi
+if test ${with_project-'no'} != "no"; then
+ AC_CHECK_HEADER(project.h, [
+ AC_CHECK_LIB(project, setproject, [
+ AC_DEFINE(HAVE_PROJECT_H)
+ SUDO_LIBS="${SUDO_LIBS} -lproject"
+ ])
+ ], [])
+fi
+dnl
+dnl typedef checks
+dnl We need to define __STDC_WANT_LIB_EXT1__ for errno_t and rsize_t
+dnl
+AC_DEFINE([__STDC_WANT_LIB_EXT1__])
+AC_TYPE_MODE_T
+AC_TYPE_UID_T
+AC_CHECK_TYPE([clockid_t], [], [AC_DEFINE(clockid_t, int)], [#include <sys/types.h>
+#include <time.h>])
+AC_CHECK_TYPE([sig_atomic_t], [], [AC_DEFINE(sig_atomic_t, int)], [#include <sys/types.h>
+#include <signal.h>])
+AC_CHECK_TYPES([struct in6_addr], [], [], [#include <sys/types.h>
+#include <netinet/in.h>])
+AC_TYPE_LONG_LONG_INT
+if test X"$ac_cv_type_long_long_int" != X"yes"; then
+ AC_MSG_ERROR(["C compiler does not appear to support the long long int type"])
+fi
+AC_CHECK_TYPE(intmax_t, long long)
+AC_CHECK_TYPE(uintmax_t, unsigned long long)
+AC_CHECK_TYPE(uint8_t, unsigned char)
+AC_CHECK_TYPE(uint32_t, unsigned int)
+AC_CHECK_TYPE(uint64_t, unsigned long long)
+AC_CHECK_TYPE(socklen_t, [], [AC_DEFINE(socklen_t, unsigned int)], [
+AC_INCLUDES_DEFAULT
+#include <sys/socket.h>])
+AC_CHECK_TYPE(rsize_t, size_t)
+AC_CHECK_TYPE(errno_t, int)
+SUDO_UID_T_LEN
+SUDO_SOCK_SA_LEN
+SUDO_SOCK_SIN_LEN
+AC_CHECK_SIZEOF([id_t])
+AC_CHECK_SIZEOF([long long])
+AC_CHECK_SIZEOF([time_t])
+if test $ac_cv_header_utmps_h = "yes"; then
+ SUDO_CHECK_UTMP_MEMBERS([utmps])
+elif test $ac_cv_header_utmpx_h = "yes"; then
+ SUDO_CHECK_UTMP_MEMBERS([utmpx])
+else
+ SUDO_CHECK_UTMP_MEMBERS([utmp])
+fi
+
+dnl
+dnl Function checks
+dnl
+AC_FUNC_GETGROUPS
+AC_CHECK_FUNCS_ONCE([fexecve killpg nl_langinfo pread pwrite openat faccessat wordexp getauxval])
+case "$host_os" in
+ hpux*)
+ if test X"$ac_cv_func_pread" = X"yes"; then
+ O_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE"
+ AC_CHECK_FUNCS([pread64 pwrite64], [
+ AC_DEFINE([_LARGEFILE64_SOURCE], [1], [Define to 1 to enable 64-bit versions of standard C functions on 32-bit systems.])
+ ])
+ CPPFLAGS="$O_CPPFLAGS"
+ fi
+ ;;
+esac
+AC_CHECK_FUNCS([getgrouplist], [], [
+ case "$host_os" in
+ aix*)
+ AC_CHECK_FUNCS([getgrset])
+ ;;
+ *)
+ AC_CHECK_FUNC([nss_search], [
+ AC_CHECK_FUNC([_nss_XbyY_buf_alloc], [
+ # Solaris
+ AC_CHECK_FUNC([_nss_initf_group], [
+ AC_CHECK_HEADERS([nss_dbdefs.h])
+ AC_DEFINE([HAVE_NSS_SEARCH])
+ AC_DEFINE([HAVE__NSS_XBYY_BUF_ALLOC])
+ AC_DEFINE([HAVE__NSS_INITF_GROUP])
+ ], [
+ AC_CHECK_HEADERS([nss_dbdefs.h], [
+ # Older Solaris does not export _nss_initf_group
+ # but we can use our own.
+ AC_DEFINE([HAVE_NSS_SEARCH])
+ AC_DEFINE([HAVE__NSS_XBYY_BUF_ALLOC])
+ ])
+ ])
+ ], [
+ # HP-UX
+ AC_CHECK_FUNC([__nss_XbyY_buf_alloc], [
+ AC_CHECK_FUNC([__nss_initf_group], [
+ AC_CHECK_HEADERS([nss_dbdefs.h])
+ AC_DEFINE([HAVE_NSS_SEARCH])
+ AC_DEFINE([HAVE___NSS_XBYY_BUF_ALLOC])
+ AC_DEFINE([HAVE___NSS_INITF_GROUP])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+ SUDO_APPEND_COMPAT_EXP(sudo_getgrouplist)
+])
+AC_CHECK_FUNCS([getline], [], [
+ AC_LIBOBJ(getline)
+ SUDO_APPEND_COMPAT_EXP(sudo_getline)
+ AC_CHECK_FUNCS([fgetln])
+])
+AC_CHECK_FUNCS([reallocarray], [], [
+ AC_LIBOBJ(reallocarray)
+ SUDO_APPEND_COMPAT_EXP(sudo_reallocarray)
+])
+AC_CHECK_FUNCS([arc4random_uniform], [], [
+ AC_LIBOBJ(arc4random_uniform)
+ SUDO_APPEND_COMPAT_EXP(sudo_arc4random_uniform)
+ AC_CHECK_FUNCS([arc4random], [], [
+ AC_LIBOBJ(arc4random)
+ SUDO_APPEND_COMPAT_EXP(sudo_arc4random)
+ # arc4random.c needs getentropy()
+ AC_CHECK_FUNCS([getentropy], [], [
+ AC_LIBOBJ(getentropy)
+ SUDO_APPEND_COMPAT_EXP(sudo_getentropy)
+ ])
+ # arc4random.c wants pthread_atfork
+ AC_CHECK_HEADERS([pthread.h], [
+ AC_CHECK_LIB(pthread, main, [LIBPTHREAD="-lpthread"])
+ AC_CHECK_FUNCS([pthread_atfork])
+ ])
+ ])
+])
+
+utmp_style=LEGACY
+AC_CHECK_FUNCS([getutsid getutxid getutid], [utmp_style=POSIX; break])
+if test "$utmp_style" = "LEGACY"; then
+ AC_CHECK_FUNCS([getttyent ttyslot], [break])
+ AC_CHECK_FUNCS([fseeko])
+fi
+
+AC_CHECK_FUNCS([sysctl], [AC_CHECK_FUNCS([devname])
+ AC_CHECK_MEMBER([struct kinfo_proc.ki_structsize], [AC_DEFINE(HAVE_KINFO_PROC_FREEBSD)], [
+ AC_CHECK_MEMBER([struct kinfo_proc2.p_paddr], [AC_DEFINE(HAVE_KINFO_PROC2_NETBSD)], [
+ AC_CHECK_MEMBER([struct kinfo_proc.p_paddr], [AC_DEFINE(HAVE_KINFO_PROC_OPENBSD)], [
+ AC_CHECK_MEMBER([struct kinfo_proc.kp_proc], [AC_DEFINE(HAVE_KINFO_PROC_44BSD)], [], [
+# include <sys/param.h>
+# include <sys/sysctl.h>
+ ])
+ ], [
+# include <sys/param.h>
+# include <sys/sysctl.h>
+ ])
+ ],
+ [
+# include <sys/param.h>
+# include <sys/sysctl.h>
+ ])
+ ],
+ [
+# include <sys/param.h>
+# include <sys/sysctl.h>
+# include <sys/user.h>
+ ])
+])
+
+AC_CHECK_FUNCS([openpty], [AC_CHECK_HEADERS([libutil.h util.h pty.h], [break])], [
+ AC_CHECK_LIB(util, openpty, [
+ AC_CHECK_HEADERS([libutil.h util.h pty.h], [break])
+ case "$SUDO_LIBS" in
+ *-lutil*) ;;
+ *) SUDO_LIBS="${SUDO_LIBS} -lutil";;
+ esac
+ AC_DEFINE(HAVE_OPENPTY)
+ ], [
+ AC_CHECK_FUNCS([_getpty], [], [
+ AC_CHECK_FUNCS([grantpt], [
+ AC_CHECK_FUNCS([posix_openpt])
+ ], [
+ AC_CHECK_FUNCS([revoke])
+ ])
+ ])
+ ])
+])
+AC_CHECK_FUNCS([unsetenv], [SUDO_FUNC_UNSETENV_VOID], [])
+SUDO_FUNC_PUTENV_CONST
+if test -z "$SKIP_SETRESUID"; then
+ AC_CHECK_FUNCS([setresuid], [
+ SKIP_SETREUID=yes
+ AC_CHECK_DECLS([setresuid])
+ AC_CHECK_FUNCS([getresuid], [AC_CHECK_DECLS([getresuid])])
+ ])
+fi
+if test -z "$SKIP_SETREUID"; then
+ AC_CHECK_FUNCS([setreuid])
+fi
+AC_CHECK_FUNCS_ONCE([seteuid])
+if test X"$with_interfaces" != X"no"; then
+ AC_CHECK_FUNCS([getifaddrs], [AC_CHECK_FUNCS([freeifaddrs])])
+fi
+AC_CHECK_FUNCS([lockf], [break])
+AC_CHECK_FUNCS([innetgr], [
+ AC_CHECK_DECLS([innetgr], [], [], [
+AC_INCLUDES_DEFAULT
+#ifdef HAVE_NETGROUP_H
+# include <netgroup.h>
+#else
+# include <netdb.h>
+#endif /* HAVE_NETGROUP_H */
+])], [
+ AC_CHECK_FUNCS([_innetgr], [
+ AC_CHECK_DECLS([_innetgr], [], [], [
+AC_INCLUDES_DEFAULT
+#ifdef HAVE_NETGROUP_H
+# include <netgroup.h>
+#else
+# include <netdb.h>
+#endif /* HAVE_NETGROUP_H */
+ ])
+ ])
+])
+AC_CHECK_FUNCS([getdomainname], [
+ AC_CHECK_DECLS([getdomainname], [], [], [
+AC_INCLUDES_DEFAULT
+#include <netdb.h>
+ ])
+], [
+ AC_CHECK_FUNCS([sysinfo], [AC_CHECK_HEADERS([sys/systeminfo.h])])
+])
+AC_CHECK_FUNCS([utimensat], [], [
+ AC_LIBOBJ(utimens)
+ SUDO_APPEND_COMPAT_EXP(sudo_utimensat)
+ AC_CHECK_FUNCS([utimes])
+])
+AC_CHECK_FUNCS([futimens], [], [
+ AC_LIBOBJ(utimens)
+ SUDO_APPEND_COMPAT_EXP(sudo_futimens)
+ AC_CHECK_FUNCS([futimes futimesat futime], [break])
+])
+SUDO_FUNC_FNMATCH([AC_DEFINE(HAVE_FNMATCH)], [
+ AC_LIBOBJ(fnmatch)
+ SUDO_APPEND_COMPAT_EXP(sudo_fnmatch)
+ COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }fnm_test"
+])
+SUDO_FUNC_ISBLANK
+AC_CHECK_FUNCS([glob], [], [
+ AC_LIBOBJ(glob)
+ SUDO_APPEND_COMPAT_EXP(sudo_glob sudo_globfree)
+])
+AC_CHECK_FUNCS([memrchr], [], [
+ AC_LIBOBJ(memrchr)
+ SUDO_APPEND_COMPAT_EXP(sudo_memrchr)
+])
+AC_CHECK_FUNCS([memset_s], [], [
+ AC_LIBOBJ(memset_s)
+ SUDO_APPEND_COMPAT_EXP(sudo_memset_s)
+])
+AC_CHECK_FUNCS(nanosleep, [], [
+ # On Solaris, nanosleep is in librt
+ AC_CHECK_LIB(rt, nanosleep, [
+ AC_DEFINE(HAVE_NANOSLEEP)
+ LIBRT="-lrt"
+ ], [
+ AC_LIBOBJ(nanosleep)
+ SUDO_APPEND_COMPAT_EXP(sudo_nanosleep)
+ ])
+])
+AC_CHECK_FUNCS([pipe2], [], [
+ AC_LIBOBJ(pipe2)
+ SUDO_APPEND_COMPAT_EXP(sudo_pipe2)
+])
+AC_CHECK_FUNCS([pw_dup], [], [
+ AC_LIBOBJ(pw_dup)
+ SUDO_APPEND_COMPAT_EXP(sudo_pw_dup)
+])
+AC_CHECK_FUNCS([strlcpy], [], [
+ AC_LIBOBJ(strlcpy)
+ SUDO_APPEND_COMPAT_EXP(sudo_strlcpy)
+])
+AC_CHECK_FUNCS([strlcat], [], [
+ AC_LIBOBJ(strlcat)
+ SUDO_APPEND_COMPAT_EXP(sudo_strlcat)
+])
+AC_CHECK_FUNC([strnlen], [AC_FUNC_STRNLEN], [AC_LIBOBJ(strnlen)])
+if test X"$ac_cv_func_strnlen_working" = X"yes"; then
+ AC_DEFINE(HAVE_STRNLEN)
+ AC_CHECK_FUNCS([strndup], [], [
+ AC_LIBOBJ(strndup)
+ SUDO_APPEND_COMPAT_EXP(sudo_strndup)
+ ])
+else
+ # Broken or missing strnlen, use our own.
+ SUDO_APPEND_COMPAT_EXP(sudo_strnlen)
+ # Avoid libc strndup() since it is usually implemented using strnlen()
+ AC_LIBOBJ(strndup)
+ SUDO_APPEND_COMPAT_EXP(sudo_strndup)
+fi
+AC_CHECK_FUNCS([clock_gettime], [], [
+ # On Solaris, clock_gettime is in librt
+ AC_CHECK_LIB(rt, clock_gettime, [
+ AC_DEFINE(HAVE_CLOCK_GETTIME)
+ LIBRT="-lrt"
+ ])
+])
+AC_CHECK_FUNCS([getopt_long], [], [
+ AC_LIBOBJ(getopt_long)
+ SUDO_APPEND_COMPAT_EXP(sudo_getopt_long sudo_getopt_long_only)
+ AC_MSG_CHECKING([for optreset])
+ AC_CACHE_VAL(sudo_cv_optreset, [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[extern int optreset; optreset = 1; return optreset;]])], [sudo_cv_optreset=yes], [sudo_cv_optreset=no])])
+ if test "$sudo_cv_optreset" = "yes"; then
+ AC_DEFINE(HAVE_OPTRESET)
+ fi
+ AC_MSG_RESULT($sudo_cv_optreset)
+])
+AC_CHECK_FUNCS([closefrom], [], [AC_LIBOBJ(closefrom)
+ SUDO_APPEND_COMPAT_EXP(closefrom_fallback sudo_closefrom)
+ AC_CHECK_DECL(F_CLOSEM, AC_DEFINE(HAVE_FCNTL_CLOSEM), [], [
+# include <limits.h>
+# include <fcntl.h> ])
+])
+AC_CHECK_FUNCS([mkstemps mkdtemp], [], [break])
+if test X"$ac_cv_func_mkstemps$ac_cv_func_mkdtemp" != X"yesyes"; then
+ AC_CHECK_FUNCS([arc4random random lrand48], [break])
+ if test X"$ac_cv_func_arc4random" != X"yes"; then
+ AC_CHECK_FUNCS([getentropy])
+ fi
+ AC_LIBOBJ(mktemp)
+ # If either mkdtemp() or mkstemps() is missing, replace both.
+ SUDO_APPEND_COMPAT_EXP(sudo_mkdtemp sudo_mkstemps)
+ COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }mktemp_test"
+fi
+AX_FUNC_SNPRINTF
+if test X"$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf" = X"yesyes"; then
+ # System has a C99-compliant v?snprintf(), check for v?asprintf()
+ AC_CHECK_FUNCS([asprintf], [], [
+ AC_LIBOBJ(snprintf)
+ SUDO_APPEND_COMPAT_EXP(sudo_asprintf)
+ ])
+ AC_CHECK_FUNCS([vasprintf], [], [
+ AC_LIBOBJ(snprintf)
+ SUDO_APPEND_COMPAT_EXP(sudo_vasprintf)
+ ])
+else
+ # Missing or non-compliant v?snprintf(), assume missing/bad v?asprintf()
+ SUDO_APPEND_COMPAT_EXP(sudo_snprintf sudo_vsnprintf sudo_asprintf sudo_vasprintf)
+fi
+# We wrap OpenBSD's strtonum() to get translatable error strings.
+AC_CHECK_FUNCS([strtonum])
+AC_LIBOBJ(strtonum)
+SUDO_APPEND_COMPAT_EXP(sudo_strtonum)
+AC_CHECK_MEMBERS([struct tm.tm_gmtoff], [], [], [
+AC_INCLUDES_DEFAULT
+#include <errno.h>
+])
+AC_CHECK_MEMBER([struct stat.st_mtim],
+ [AC_DEFINE(HAVE_ST_MTIM)]
+ [AC_CHECK_MEMBER([struct stat.st_mtim.st__tim], AC_DEFINE(HAVE_ST__TIM))],
+ [AC_CHECK_MEMBER([struct stat.st_mtimespec],
+ [AC_DEFINE([HAVE_ST_MTIMESPEC])],
+ [AC_CHECK_MEMBER([struct stat.st_nmtime], AC_DEFINE(HAVE_ST_NMTIME))])
+ ]
+)
+# Look for sha2 functions if not using openssl
+if test "$DIGEST" = "digest.lo"; then
+ FOUND_SHA2=no
+ AC_CHECK_HEADER([sha2.h], [
+ FOUND_SHA2=yes
+ AC_CHECK_FUNCS([SHA224Update], [SUDO_FUNC_SHA2_VOID_PTR], [
+ # On some systems, SHA224Update is in libmd
+ AC_CHECK_LIB(md, SHA224Update, [
+ AC_DEFINE(HAVE_SHA224UPDATE)
+ SUDO_FUNC_SHA2_VOID_PTR
+ LIBMD="-lmd"
+ ], [
+ # Does not have SHA224Update
+ FOUND_SHA2=no
+ ])
+ ])
+ ])
+ if test X"$FOUND_SHA2" = X"no"; then
+ AC_LIBOBJ(sha2)
+ SUDO_APPEND_COMPAT_EXP(sudo_SHA224Final sudo_SHA224Init sudo_SHA224Pad sudo_SHA224Transform sudo_SHA224Update sudo_SHA256Final sudo_SHA256Init sudo_SHA256Pad sudo_SHA256Transform sudo_SHA256Update sudo_SHA384Final sudo_SHA384Init sudo_SHA384Pad sudo_SHA384Transform sudo_SHA384Update sudo_SHA512Final sudo_SHA512Init sudo_SHA512Pad sudo_SHA512Transform sudo_SHA512Update)
+ fi
+fi
+AC_CHECK_FUNCS([vsyslog], [], [
+ AC_LIBOBJ(vsyslog)
+ SUDO_APPEND_COMPAT_EXP(sudo_vsyslog)
+ COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }vsyslog_test"
+])
+dnl
+dnl 4.4BSD-based systems can force the password or group file to be held open
+dnl
+AC_CHECK_FUNCS([setpassent setgroupent])
+dnl
+dnl Function checks for sudo_noexec
+dnl
+if test X"$with_noexec" != X"no"; then
+ # Check for non-standard exec functions
+ AC_CHECK_FUNCS([exect execvP execvpe])
+ # Check for posix_spawn, and posix_spawnp
+ if test X"$ac_cv_header_spawn_h" = X"yes"; then
+ AC_CHECK_FUNCS([posix_spawn posix_spawnp])
+ fi
+fi
+
+dnl
+dnl Check for the dirfd function/macro. If not found, look for dd_fd in DIR.
+dnl
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
+#include <$ac_header_dirent>]], [[DIR *d; (void)dirfd(d);]])], [AC_DEFINE(HAVE_DIRFD)], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
+#include <$ac_header_dirent>]], [[DIR d; memset(&d, 0, sizeof(d)); return(d.dd_fd);]])], [AC_DEFINE(HAVE_DD_FD)], [])])
+AC_CHECK_MEMBERS([struct dirent.d_type, struct dirent.d_namlen], [], [], [
+AC_INCLUDES_DEFAULT
+#include <$ac_header_dirent>
+])
+dnl
+dnl If socket(2) not in libc, check -lsocket and -linet
+dnl May need to link with *both* -lnsl and -lsocket due to unresolved symbols
+dnl
+OLIBS="$LIBS"
+LIBS="${LIBS} ${NET_LIBS}"
+AC_CHECK_FUNC([socket], [], [
+ for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+ _libs=
+ for lib in $libs; do
+ case "$NET_LIBS" in
+ *"$lib"*) ;;
+ *) _libs="$_libs $lib";;
+ esac
+ done
+ libs="${_libs# }"
+ test -z "$libs" && continue
+ lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+ extralibs="`echo \"$libs\"|sed 's/^-l[[^ ]]*//'`"
+ SUDO_CHECK_LIB($lib, socket, [NET_LIBS="${NET_LIBS} $libs"; break], [], [$extralibs])
+ done
+])
+LIBS="$OLIBS"
+dnl
+dnl If inet_pton(3) not in libc, check -lnsl and -linet
+dnl May need to link with *both* -lnsl and -lsocket due to unresolved symbols
+dnl Some systems may have inet_pton() in libresolv.
+dnl
+OLIBS="$LIBS"
+LIBS="${LIBS} ${NET_LIBS}"
+found=false
+INET_PTON_LIBS=
+AC_CHECK_FUNC([inet_pton], [
+ found=true
+ AC_DEFINE(HAVE_INET_PTON)
+], [
+ for libs in "-lsocket" "-linet" "-lsocket -lnsl" "-lresolv"; do
+ _libs=
+ for lib in $libs; do
+ case "$NET_LIBS" in
+ *"$lib"*) ;;
+ *) _libs="$_libs $lib";;
+ esac
+ done
+ libs="${_libs# }"
+ test -z "$libs" && continue
+ lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+ extralibs="`echo \"$libs\"|sed 's/^-l[[^ ]]*//'`"
+ SUDO_CHECK_LIB($lib, inet_pton, [
+ found=true
+ AC_DEFINE(HAVE_INET_PTON)
+ NET_LIBS="${NET_LIBS} $libs"
+ INET_PTON_LIBS="$libs"
+ case "$libs" in
+ *-lresolv*)
+ AC_DEFINE(NEED_RESOLV_H)
+ ;;
+ esac
+ break
+ ], [], [$extralibs])
+ done
+])
+LIBS="$OLIBS"
+if test X"$found" != X"true"; then
+ AC_LIBOBJ(inet_pton)
+ SUDO_APPEND_COMPAT_EXP(sudo_inet_pton)
+fi
+dnl
+dnl If inet_ntop(3) not in libc, check -lnsl and -linet
+dnl May need to link with *both* -lnsl and -lsocket due to unresolved symbols
+dnl Some systems may have inet_ntop() in libresolv.
+dnl
+OLIBS="$LIBS"
+LIBS="${LIBS} ${NET_LIBS}"
+found=false
+AC_CHECK_FUNC([inet_ntop], [
+ found=true
+ AC_DEFINE(HAVE_INET_NTOP)
+], [
+ for libs in "-lsocket" "-linet" "-lsocket -lnsl" "-lresolv"; do
+ _libs=
+ for lib in $libs; do
+ case "$NET_LIBS" in
+ *"$lib"*) ;;
+ *) _libs="$_libs $lib";;
+ esac
+ done
+ libs="${_libs# }"
+ test -z "$libs" && continue
+ lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+ extralibs="`echo \"$libs\"|sed 's/^-l[[^ ]]*//'`"
+ SUDO_CHECK_LIB($lib, inet_ntop, [
+ found=true
+ AC_DEFINE(HAVE_INET_NTOP)
+ NET_LIBS="${NET_LIBS} $libs"
+ break
+ ], [], [$extralibs])
+ done
+])
+LIBS="$OLIBS"
+if test X"$found" != X"true"; then
+ AC_LIBOBJ(inet_ntop)
+ SUDO_APPEND_COMPAT_EXP(sudo_inet_ntop)
+fi
+dnl
+dnl If syslog(3) not in libc, check -lsocket, -lnsl and -linet
+dnl
+OLIBS="$LIBS"
+LIBS="${LIBS} ${NET_LIBS}"
+AC_CHECK_FUNC([syslog], [], [
+ for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+ _libs=
+ for lib in $libs; do
+ case "$NET_LIBS" in
+ *"$lib"*) ;;
+ *) _libs="$_libs $lib";;
+ esac
+ done
+ libs="${_libs# }"
+ test -z "$libs" && continue
+ lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+ extralibs="`echo \"$libs\"|sed 's/^-l[[^ ]]*//'`"
+ SUDO_CHECK_LIB($lib, syslog, [NET_LIBS="${NET_LIBS} $libs"; break], [], [$extralibs])
+ done
+])
+LIBS="$OLIBS"
+#
+# Check for getaddrinfo and add any required libs to NET_LIBS.
+# If it was added to LIBOBJS we need to export the symbols.
+#
+OLIBS="$LIBS"
+GETADDRINFO_LIBS=
+AX_FUNC_GETADDRINFO
+case " $LIBOBJS " in
+ *" getaddrinfo.$ac_objext "* )
+ SUDO_APPEND_COMPAT_EXP(sudo_getaddrinfo sudo_freeaddrinfo sudo_gai_strerror)
+ # We need libsudo_util to pull in dependent libraries for
+ # inet_pton(), gethostbyname(), and getservbyname()
+ if test -n "${INET_PTON_LIBS}"; then
+ LT_DEP_LIBS="${LT_DEP_LIBS}${LT_DEP_LIBS+ }${INET_PTON_LIBS}"
+ LIBS="${LIBS}${LIBS+ }${INET_PTON_LIBS}"
+ fi
+ AC_CHECK_FUNC([gethostbyname], [], [
+ for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+ _libs=
+ for lib in $libs; do
+ case "$LT_DEP_LIBS" in
+ *"$lib"*) ;;
+ *) _libs="$_libs $lib";;
+ esac
+ done
+ libs="${_libs# }"
+ test -z "$libs" && continue
+ lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+ extralibs="`echo \"$libs\"|sed 's/^-l[[^ ]]*//'`"
+ SUDO_CHECK_LIB($lib, gethostbyname, [LT_DEP_LIBS="${LT_DEP_LIBS} $libs"; break], [], [$extralibs])
+ done
+ ])
+ ;;
+ *)
+ for lib in $LIBS; do
+ case "$OLIBS" in
+ *"$lib"*) ;;
+ *) GETADDRINFO_LIBS="${GETADDRINFO_LIBS}${GETADDRINFO_LIBS+ }$lib";;
+ esac
+ done
+ if test -n "${GETADDRINFO_LIBS}"; then
+ # We need libsudo_util to pull in dependent libraries for
+ # gai_strerror()
+ LT_DEP_LIBS="${LT_DEP_LIBS}${LT_DEP_LIBS+ }${GETADDRINFO_LIBS}"
+ LIBS="${LIBS}${LIBS+ }${GETADDRINFO_LIBS}"
+
+ # Add to NET_LIBS if necessary
+ for lib in $GETADDRINFO_LIBS; do
+ case "$NET_LIBS" in
+ *"$lib"*) ;;
+ *) NET_LIBS="${NET_LIBS}${NET_LIBS+ }$lib";;
+ esac
+ done
+ fi
+ ;;
+esac
+LIBS="$OLIBS"
+
+dnl
+dnl Check for getprogname() or __progname
+dnl
+AC_CHECK_FUNCS([getprogname], [AC_CHECK_FUNCS([setprogname])], [
+ AC_MSG_CHECKING([for __progname])
+ AC_CACHE_VAL(sudo_cv___progname, [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[extern char *__progname; (void)puts(__progname);]])], [sudo_cv___progname=yes], [sudo_cv___progname=no])])
+ if test "$sudo_cv___progname" = "yes"; then
+ AC_DEFINE(HAVE___PROGNAME)
+ fi
+ AC_MSG_RESULT($sudo_cv___progname)
+ SUDO_APPEND_COMPAT_EXP(sudo_getprogname)
+])
+dnl
+dnl Check for __func__ or __FUNCTION__
+dnl
+AC_MSG_CHECKING([for __func__])
+AC_CACHE_VAL(sudo_cv___func__, [
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[(void)puts(__func__);]])], [sudo_cv___func__=yes], [sudo_cv___func__=no])])
+AC_MSG_RESULT($sudo_cv___func__)
+if test "$sudo_cv___func__" = "yes"; then
+ AC_DEFINE(HAVE___FUNC__)
+elif test -n "$GCC"; then
+ AC_MSG_CHECKING([for __FUNCTION__])
+ AC_CACHE_VAL(sudo_cv___FUNCTION__, [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[(void)puts(__FUNCTION__);]])], [sudo_cv___FUNCTION__=yes], [sudo_cv___FUNCTION__=no])])
+ AC_MSG_RESULT($sudo_cv___FUNCTION__)
+ if test "$sudo_cv___FUNCTION__" = "yes"; then
+ AC_DEFINE(HAVE___FUNC__)
+ AC_DEFINE(__func__, __FUNCTION__, [Define to __FUNCTION__ if your compiler supports __FUNCTION__ but not __func__])
+ fi
+fi
+
+# gettext() and friends may be located in libc (Linux and Solaris)
+# or in libintl. However, it is possible to have libintl installed
+# even when gettext() is present in libc. In the case of GNU libintl,
+# gettext() will be defined to gettext_libintl in libintl.h.
+# Since gcc prefers /usr/local/include to /usr/include, we need to
+# make sure we use the gettext() that matches the include file.
+if test "$enable_nls" != "no"; then
+ if test "$enable_nls" != "yes"; then
+ AX_APPEND_FLAG([-I${enable_nls}/include], [CPPFLAGS])
+ SUDO_APPEND_LIBPATH(LDFLAGS, [$enable_nls/lib])
+ fi
+ OLIBS="$LIBS"
+ for l in "libc" "-lintl" "-lintl -liconv"; do
+ if test "$l" = "libc"; then
+ # If user specified a dir for libintl ignore libc
+ if test "$enable_nls" != "yes"; then
+ continue
+ fi
+ gettext_name=sudo_cv_gettext
+ AC_MSG_CHECKING([for gettext])
+ else
+ LIBS="$OLIBS $l"
+ gettext_name=sudo_cv_gettext"`echo $l|sed -e 's/ //g' -e 's/-/_/g'`"
+ AC_MSG_CHECKING([for gettext in $l])
+ fi
+ AC_CACHE_VAL($gettext_name, [
+ AC_LINK_IFELSE(
+ [
+ AC_LANG_PROGRAM([[#include <libintl.h>]], [(void)gettext((char *)0);])
+ ], [eval $gettext_name=yes], [eval $gettext_name=no]
+ )
+ ])
+ eval gettext_result="\$$gettext_name"
+ AC_MSG_RESULT($gettext_result)
+ if test "$gettext_result" = "yes"; then
+ AC_CHECK_FUNCS([ngettext])
+ break
+ fi
+ done
+ LIBS="$OLIBS"
+
+ if test "$sudo_cv_gettext" = "yes"; then
+ SUDO_NLS=enabled
+ # For Solaris we need links from lang to lang.UTF-8 in localedir
+ case "$host_os" in
+ solaris2*) LOCALEDIR_SUFFIX=".UTF-8";;
+ esac
+ elif test "$sudo_cv_gettext_lintl" = "yes"; then
+ SUDO_NLS=enabled
+ LIBINTL="-lintl"
+ elif test "$sudo_cv_gettext_lintl_liconv" = "yes"; then
+ SUDO_NLS=enabled
+ LIBINTL="-lintl -liconv"
+ fi
+ if test X"$SUDO_NLS" = X"enabled"; then
+ AC_DEFINE(HAVE_LIBINTL_H)
+ SUDO_APPEND_COMPAT_EXP(sudo_warn_gettext_v1)
+ fi
+fi
+
+dnl
+dnl Deferred zlib option processing.
+dnl By default we use the system zlib if it is present.
+dnl If a directory was specified for zlib (or we are use sudo's version),
+dnl prepend the include dir to make sure we get the right zlib header.
+dnl
+case "$enable_zlib" in
+ yes)
+ AC_CHECK_LIB(z, gzdopen, [
+ AC_CHECK_HEADERS([zlib.h], [ZLIB="-lz"], [enable_zlib=builtin])
+ ])
+ ;;
+ no)
+ ;;
+ system)
+ AC_DEFINE(HAVE_ZLIB_H)
+ ZLIB="-lz"
+ ;;
+ static|shared|builtin)
+ # handled below
+ ;;
+ *)
+ AC_DEFINE(HAVE_ZLIB_H)
+ AX_APPEND_FLAG([-I${enable_zlib}/include], [CPPFLAGS])
+ SUDO_APPEND_LIBPATH(ZLIB, [$enable_zlib/lib])
+ ZLIB="${ZLIB} -lz"
+ ;;
+esac
+case "$enable_zlib" in
+ builtin|static|dynamic)
+ AC_DEFINE(HAVE_ZLIB_H)
+ # XXX - can't use AX_APPEND_FLAG due to use of $(top_foo) and quoting
+ CPPFLAGS='-I$(top_builddir)/lib/zlib -I$(top_srcdir)/lib/zlib '"${CPPFLAGS}"
+ ZLIB="${ZLIB}"' $(top_builddir)/lib/zlib/libsudo_z.la'
+ ZLIB_SRC=lib/zlib
+ AC_CONFIG_HEADER([lib/zlib/zconf.h])
+ AC_CONFIG_FILES([lib/zlib/Makefile])
+ if test X"$enable_shared" = X"no" -o "$enable_zlib" = "static"; then
+ if test "$enable_zlib" = "shared"; then
+ AC_MSG_ERROR(["Unable to build shared libraries on this system"])
+ fi
+ # Build as convenience library
+ ZLIB_LDFLAGS=-no-install
+ fi
+ ;;
+esac
+
+dnl
+dnl Check for errno declaration in errno.h
+dnl
+AC_CHECK_DECLS([errno], [], [], [
+AC_INCLUDES_DEFAULT
+#include <errno.h>
+])
+
+dnl
+dnl Check for h_errno declaration in netdb.h
+dnl
+AC_CHECK_DECLS([h_errno], [], [], [
+AC_INCLUDES_DEFAULT
+#include <netdb.h>
+])
+
+dnl
+dnl Check for incomplete limits.h and missing SIZE_MAX.
+dnl
+AC_CHECK_DECLS([LLONG_MAX, LLONG_MIN, ULLONG_MAX, PATH_MAX], [], [], [
+#include <sys/types.h>
+#include <limits.h>
+])
+AC_CHECK_DECLS([SIZE_MAX], [], [], [
+#include <sys/types.h>
+#include <limits.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+])
+dnl
+dnl Try to find equivalents for missing types
+dnl
+if test "$ac_cv_have_decl_LLONG_MAX" != "yes"; then
+ AC_CHECK_DECLS([QUAD_MAX], [], [], [[
+#include <sys/types.h>
+#include <limits.h>
+ ]])
+fi
+if test "$ac_cv_have_decl_LLONG_MIN" != "yes"; then
+ AC_CHECK_DECLS([QUAD_MIN], [], [], [[
+#include <sys/types.h>
+#include <limits.h>
+ ]])
+fi
+if test "$ac_cv_have_decl_ULLONG_MAX" != "yes"; then
+ AC_CHECK_DECLS([UQUAD_MAX], [], [], [[
+#include <sys/types.h>
+#include <limits.h>
+ ]])
+fi
+if test "$ac_cv_have_decl_SIZE_MAX" != "yes"; then
+ AC_CHECK_DECLS([SIZE_T_MAX], [], [], [[
+#include <sys/types.h>
+#include <limits.h>
+ ]])
+fi
+if test "$ac_cv_have_decl_PATH_MAX" != "yes"; then
+ AC_CHECK_DECLS([_POSIX_PATH_MAX], [], [], [[
+#include <sys/types.h>
+#include <limits.h>
+ ]])
+fi
+
+dnl
+dnl Check for strsignal() or sys_siglist
+dnl
+AC_CHECK_FUNCS([strsignal], [], [
+ AC_LIBOBJ(strsignal)
+ SUDO_APPEND_COMPAT_EXP(sudo_strsignal)
+ HAVE_SIGLIST="false"
+ AC_CHECK_DECLS([sys_siglist, _sys_siglist], [
+ HAVE_SIGLIST="true"
+ break
+ ], [ ], [
+AC_INCLUDES_DEFAULT
+#include <signal.h>
+ ])
+ if test "$HAVE_SIGLIST" != "true"; then
+ AC_LIBOBJ(siglist)
+ fi
+])
+
+dnl
+dnl Check for sig2str(), sys_signame or sys_sigabbrev
+dnl
+AC_CHECK_FUNCS([sig2str], [
+ AC_CHECK_DECLS(SIG2STR_MAX, [], [], [
+# include <signal.h>
+])], [
+ AC_LIBOBJ(sig2str)
+ SUDO_APPEND_COMPAT_EXP(sudo_sig2str)
+ HAVE_SIGNAME="false"
+ AC_CHECK_DECLS([sys_signame, _sys_signame, sys_sigabbrev], [
+ HAVE_SIGNAME="true"
+ break
+ ], [ ], [
+AC_INCLUDES_DEFAULT
+#include <signal.h>
+ ])
+ if test "$HAVE_SIGNAME" != "true"; then
+ AC_CACHE_CHECK([for undeclared sys_sigabbrev],
+ [sudo_cv_var_sys_sigabbrev],
+ [AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[extern char **sys_sigabbrev;]], [[return sys_sigabbrev[1];]])],
+ [sudo_cv_var_sys_sigabbrev=yes],
+ [sudo_cv_var_sys_sigabbrev=no]
+ )
+ ]
+ )
+ if test "$sudo_cv_var_sys_sigabbrev" = yes; then
+ AC_DEFINE(HAVE_SYS_SIGABBREV)
+ else
+ AC_LIBOBJ(signame)
+ fi
+ fi
+])
+
+dnl
+dnl Check for dl_iterate_phdr, may require -ldl
+dnl
+OLIBS="$LIBS"
+LIBS="$LIBS $lt_cv_dlopen_libs"
+AC_CHECK_FUNCS([dl_iterate_phdr])
+LIBS="$OLIBS"
+
+dnl
+dnl nsswitch.conf and its equivalents
+dnl
+if test ${with_netsvc-"no"} != "no"; then
+ SUDO_DEFINE_UNQUOTED(_PATH_NETSVC_CONF, "${with_netsvc-/etc/netsvc.conf}")
+ netsvc_conf=${with_netsvc-/etc/netsvc.conf}
+elif test ${with_nsswitch-"yes"} != "no"; then
+ SUDO_DEFINE_UNQUOTED(_PATH_NSSWITCH_CONF, "${with_nsswitch-/etc/nsswitch.conf}")
+ nsswitch_conf=${with_nsswitch-/etc/nsswitch.conf}
+fi
+
+dnl
+dnl Mutually exclusive auth checks come first, followed by
+dnl non-exclusive ones. Note: passwd must be last of all!
+dnl
+
+dnl
+dnl Convert default authentication methods to with_* if
+dnl no explicit authentication scheme was specified.
+dnl
+if test -z "${AUTH_EXCL}${AUTH_REG}" -a -n "$AUTH_EXCL_DEF"; then
+ for auth in $AUTH_EXCL_DEF; do
+ case $auth in
+ AIX_AUTH) with_aixauth=maybe;;
+ BSD_AUTH) with_bsdauth=maybe;;
+ PAM) with_pam=maybe;;
+ SIA) CHECKSIA=true;;
+ esac
+ done
+fi
+
+dnl
+dnl PAM support. Systems that use PAM by default set with_pam=default
+dnl and we do the actual tests here.
+dnl
+if test ${with_pam-"no"} != "no"; then
+ #
+ # Check for pam_start() in libpam first, then for pam_appl.h.
+ #
+ found_pam_lib=no
+ AC_CHECK_LIB(pam, pam_start, [found_pam_lib=yes], [], [$lt_cv_dlopen_libs])
+ #
+ # Some PAM implementations (macOS for example) put the PAM headers
+ # in /usr/include/pam instead of /usr/include/security...
+ #
+ found_pam_hdrs=no
+ AC_CHECK_HEADERS([security/pam_appl.h] [pam/pam_appl.h], [found_pam_hdrs=yes; break])
+ if test "$found_pam_lib" = "yes" -a "$found_pam_hdrs" = "yes"; then
+ # Found both PAM libs and headers
+ with_pam=yes
+ elif test "$with_pam" = "yes"; then
+ if test "$found_pam_lib" = "no"; then
+ AC_MSG_ERROR(["--with-pam specified but unable to locate PAM development library."])
+ fi
+ if test "$found_pam_hdrs" = "no"; then
+ AC_MSG_ERROR(["--with-pam specified but unable to locate PAM development headers."])
+ fi
+ elif test "$found_pam_lib" != "$found_pam_hdrs"; then
+ if test "$found_pam_lib" = "no"; then
+ AC_MSG_ERROR(["found PAM headers but no PAM development library; specify --without-pam to build without PAM"])
+ fi
+ if test "$found_pam_hdrs" = "no"; then
+ AC_MSG_ERROR(["found PAM library but no PAM development headers; specify --without-pam to build without PAM"])
+ fi
+ fi
+
+ if test "$with_pam" = "yes"; then
+ # Older PAM implementations lack pam_getenvlist
+ OLIBS="$LIBS"
+ LIBS="$LIBS -lpam $lt_cv_dlopen_libs"
+ AC_CHECK_FUNCS([pam_getenvlist])
+ LIBS="$OLIBS"
+
+ # We already link with -ldl if needed (see LIBDL below)
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lpam"
+ AC_DEFINE(HAVE_PAM)
+ AUTH_OBJS="$AUTH_OBJS pam.lo";
+ AUTH_EXCL=PAM
+
+ AC_ARG_WITH(pam-login, [AS_HELP_STRING([--with-pam-login], [enable specific PAM session for sudo -i])],
+ [case $with_pam_login in
+ yes) AC_DEFINE([HAVE_PAM_LOGIN])
+ AC_MSG_CHECKING(whether to use PAM login)
+ AC_MSG_RESULT(yes)
+ pam_login_service="sudo-i"
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-pam-login does not take an argument."])
+ ;;
+ esac])
+
+ AC_MSG_CHECKING(whether to use PAM session support)
+ AC_ARG_ENABLE(pam_session,
+ [AS_HELP_STRING([--disable-pam-session], [Disable PAM session support])],
+ [ case "$enableval" in
+ yes) AC_MSG_RESULT(yes)
+ ;;
+ no) AC_MSG_RESULT(no)
+ AC_DEFINE(NO_PAM_SESSION)
+ pam_session=off
+ ;;
+ *) AC_MSG_RESULT(no)
+ AC_MSG_WARN([Ignoring unknown argument to --enable-pam-session: $enableval])
+ ;;
+ esac], AC_MSG_RESULT(yes))
+ fi
+fi
+
+dnl
+dnl AIX general authentication
+dnl We may build in support for both AIX LAM and PAM and select
+dnl which one to use at run-time.
+dnl
+if test ${with_aixauth-'no'} != "no"; then
+ AC_CHECK_FUNCS([authenticate], [with_aixauth=yes])
+ if test "${with_aixauth}" = "yes"; then
+ AC_MSG_NOTICE([using AIX general authentication])
+ AC_DEFINE(HAVE_AIXAUTH)
+ AUTH_OBJS="$AUTH_OBJS aix_auth.lo";
+ SUDOERS_LIBS="${SUDOERS_LIBS} -ls"
+ AUTH_EXCL=AIX_AUTH
+ fi
+fi
+
+dnl
+dnl BSD authentication
+dnl If set to "maybe" only enable if no other exclusive method in use.
+dnl
+if test ${with_bsdauth-'no'} != "no"; then
+ AC_CHECK_HEADER(bsd_auth.h, AC_DEFINE(HAVE_BSD_AUTH_H)
+ [AUTH_OBJS="$AUTH_OBJS bsdauth.lo"]
+ [BSDAUTH_USAGE='[[-a type]] ']
+ [AUTH_EXCL=BSD_AUTH; BAMAN=1],
+ [AC_MSG_ERROR([BSD authentication was specified but bsd_auth.h could not be found])])
+fi
+
+dnl
+dnl SIA authentication for Tru64 Unix
+dnl
+if test ${CHECKSIA-'false'} = "true"; then
+ AC_CHECK_FUNCS([sia_ses_init], [found=true], [found=false])
+ if test "$found" = "true"; then
+ AUTH_EXCL=SIA
+ AUTH_OBJS="$AUTH_OBJS sia.lo"
+ fi
+fi
+
+dnl
+dnl extra FWTK libs + includes
+dnl
+if test ${with_fwtk-'no'} != "no"; then
+ if test "$with_fwtk" != "yes"; then
+ SUDO_APPEND_LIBPATH(SUDOERS_LDFLAGS, [${with_fwtk}])
+ AX_APPEND_FLAG([-I${with_fwtk}], [CPPFLAGS])
+ with_fwtk=yes
+ fi
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lauth -lfwall"
+ AUTH_OBJS="$AUTH_OBJS fwtk.lo"
+fi
+
+dnl
+dnl extra SecurID lib + includes
+dnl
+if test ${with_SecurID-'no'} != "no"; then
+ if test "$with_SecurID" != "yes"; then
+ :
+ elif test -d /usr/ace/examples; then
+ with_SecurID=/usr/ace/examples
+ else
+ with_SecurID=/usr/ace
+ fi
+ AX_APPEND_FLAG([-I${with_SecurID}], [CPPFLAGS])
+ SUDO_APPEND_LIBPATH(SUDOERS_LDFLAGS, [${with_SecurID}])
+ SUDOERS_LIBS="${SUDOERS_LIBS} -laceclnt -lpthread"
+ AUTH_OBJS="$AUTH_OBJS securid5.lo";
+fi
+
+dnl
+dnl Non-mutually exclusive auth checks come next.
+dnl Note: passwd must be last of all!
+dnl
+
+dnl
+dnl Convert default authentication methods to with_* if
+dnl no explicit authentication scheme was specified.
+dnl
+if test -z "${AUTH_EXCL}" -a -n "$AUTH_DEF"; then
+ for auth in $AUTH_DEF; do
+ case $auth in
+ passwd) : ${with_passwd='maybe'};;
+ esac
+ done
+fi
+
+dnl
+dnl Kerberos V
+dnl There is an easy way and a hard way...
+dnl
+if test ${with_kerb5-'no'} != "no"; then
+ AC_CHECK_PROG(KRB5CONFIG, krb5-config, yes, "")
+ if test -n "$KRB5CONFIG"; then
+ AC_DEFINE(HAVE_KERB5)
+ AUTH_OBJS="$AUTH_OBJS kerb5.lo"
+ AX_APPEND_FLAG([`krb5-config --cflags`], [CPPFLAGS])
+ SUDOERS_LIBS="$SUDOERS_LIBS `krb5-config --libs`"
+ dnl
+ dnl Try to determine whether we have Heimdal or MIT Kerberos
+ dnl
+ AC_MSG_CHECKING(whether we are using Heimdal)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <krb5.h>]], [[const char *tmp = heimdal_version;]])], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_HEIMDAL)
+ ], [
+ AC_MSG_RESULT(no)
+ ]
+ )
+ else
+ AC_DEFINE(HAVE_KERB5)
+ dnl
+ dnl Use the specified directory, if any, else search for correct inc dir
+ dnl
+ if test "$with_kerb5" = "yes"; then
+ found=no
+ O_CPPFLAGS="$CPPFLAGS"
+ for dir in "" "kerberosV/" "krb5/" "kerberos5/" "kerberosv5/"; do
+ CPPFLAGS="$O_CPPFLAGS -I/usr/include/${dir}"
+ AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#include <krb5.h>]])], [found=yes; break])
+ done
+ if test X"$found" = X"no"; then
+ CPPFLAGS="$O_CPPFLAGS"
+ AC_MSG_WARN([Unable to locate Kerberos V include files, you will have to edit the Makefile and add -I/path/to/krb/includes to CPPFLAGS])
+ fi
+ else
+ dnl XXX - try to include krb5.h here too
+ SUDO_APPEND_LIBPATH(SUDOERS_LDFLAGS, [${with_kerb5}/lib])
+ AX_APPEND_FLAG([-I${with_kerb5}/include], [CPPFLAGS])
+ fi
+
+ dnl
+ dnl Try to determine whether we have Heimdal or MIT Kerberos
+ dnl
+ AC_MSG_CHECKING(whether we are using Heimdal)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <krb5.h>]], [[const char *tmp = heimdal_version;]])], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_HEIMDAL)
+ # XXX - need to check whether -lcrypo is needed!
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lkrb5 -lcrypto -ldes -lcom_err -lasn1"
+ AC_CHECK_LIB(roken, main, [SUDOERS_LIBS="${SUDOERS_LIBS} -lroken"])
+ ], [
+ AC_MSG_RESULT(no)
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lkrb5 -lk5crypto -lcom_err"
+ AC_CHECK_LIB(krb5support, main, [SUDOERS_LIBS="${SUDOERS_LIBS} -lkrb5support"])
+ ])
+ AUTH_OBJS="$AUTH_OBJS kerb5.lo"
+ fi
+ _LIBS="$LIBS"
+ LIBS="${LIBS} ${SUDOERS_LIBS}"
+ AC_CHECK_FUNCS([krb5_verify_user krb5_init_secure_context])
+ AC_CHECK_FUNCS([krb5_get_init_creds_opt_alloc], [
+ AC_CACHE_CHECK([whether krb5_get_init_creds_opt_free takes a context],
+ sudo_cv_krb5_get_init_creds_opt_free_two_args, [
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <krb5.h>]],
+ [[krb5_get_init_creds_opt_free(NULL, NULL);]]
+ )],
+ [sudo_cv_krb5_get_init_creds_opt_free_two_args=yes],
+ [sudo_cv_krb5_get_init_creds_opt_free_two_args=no]
+ )
+ ]
+ )
+ ])
+ if test X"$sudo_cv_krb5_get_init_creds_opt_free_two_args" = X"yes"; then
+ AC_DEFINE(HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_TWO_ARGS)
+ fi
+ LIBS="$_LIBS"
+ AC_MSG_CHECKING(whether to use an instance name for Kerberos V)
+ AC_ARG_ENABLE(kerb5-instance,
+ [AS_HELP_STRING([--enable-kerb5-instance], [instance string to append to the username (separated by a slash)])],
+ [ case "$enableval" in
+ yes) AC_MSG_ERROR(["must give --enable-kerb5-instance an argument."])
+ ;;
+ no) AC_MSG_RESULT(no)
+ ;;
+ *) SUDO_DEFINE_UNQUOTED(SUDO_KRB5_INSTANCE, "$enableval")
+ AC_MSG_RESULT([$enableval])
+ ;;
+ esac], AC_MSG_RESULT(no))
+fi
+
+dnl
+dnl extra AFS libs and includes
+dnl
+if test ${with_AFS-'no'} = "yes"; then
+
+ # looks like the "standard" place for AFS libs is /usr/afsws/lib
+ AFSLIBDIRS="/usr/lib/afs /usr/afsws/lib /usr/afsws/lib/afs"
+ for i in $AFSLIBDIRS; do
+ if test -d ${i}; then
+ SUDO_APPEND_LIBPATH(SUDOERS_LDFLAGS, [$i])
+ FOUND_AFSLIBDIR=true
+ fi
+ done
+ if test -z "$FOUND_AFSLIBDIR"; then
+ AC_MSG_WARN([Unable to locate AFS libraries, you will have to edit the Makefile and add -L/path/to/afs/libs to SUDOERS_LDFLAGS or rerun configure with the --with-libpath options.])
+ fi
+
+ # Order is important here. Note that we build AFS_LIBS from right to left
+ # since AFS_LIBS may be initialized with BSD compat libs that must go last
+ AFS_LIBS="-laudit ${AFS_LIBS}"
+ for i in $AFSLIBDIRS; do
+ if test -f ${i}/util.a; then
+ AFS_LIBS="${i}/util.a ${AFS_LIBS}"
+ FOUND_UTIL_A=true
+ break;
+ fi
+ done
+ if test -z "$FOUND_UTIL_A"; then
+ AFS_LIBS="-lutil ${AFS_LIBS}"
+ fi
+ AFS_LIBS="-lkauth -lprot -lubik -lauth -lrxkad -lsys -ldes -lrx -llwp -lcom_err ${AFS_LIBS}"
+
+ # AFS includes may live in /usr/include on some machines...
+ for i in /usr/afsws/include; do
+ if test -d ${i}; then
+ AX_APPEND_FLAG([-I${i}], [CPPFLAGS])
+ FOUND_AFSINCDIR=true
+ fi
+ done
+
+ if test -z "$FOUND_AFSLIBDIR"; then
+ AC_MSG_WARN([Unable to locate AFS include dir, you may have to edit the Makefile and add -I/path/to/afs/includes to CPPFLAGS or rerun configure with the --with-incpath options.])
+ fi
+
+ AUTH_OBJS="$AUTH_OBJS afs.lo"
+fi
+
+dnl
+dnl extra DCE obj + lib
+dnl Order of libs in HP-UX 10.x is important, -ldce must be last.
+dnl
+if test ${with_DCE-'no'} = "yes"; then
+ DCE_OBJS="${DCE_OBJS} dce_pwent.o"
+ SUDOERS_LIBS="${SUDOERS_LIBS} -ldce"
+ AUTH_OBJS="$AUTH_OBJS dce.lo"
+fi
+
+dnl
+dnl extra S/Key lib and includes
+dnl
+if test "${with_skey-'no'}" = "yes"; then
+ O_LDFLAGS="$LDFLAGS"
+ if test "$with_skey" != "yes"; then
+ AX_APPEND_FLAG([-I${with_skey}/include], [CPPFLAGS])
+ LDFLAGS="$LDFLAGS -L${with_skey}/lib"
+ SUDO_APPEND_LIBPATH(SUDOERS_LDFLAGS, [${with_skey}/lib])
+ AC_CHECK_HEADER([skey.h], [found=yes], [found=no], [#include <stdio.h>])
+ else
+ found=no
+ O_CPPFLAGS="$CPPFLAGS"
+ for dir in "" "/usr/local" "/usr/contrib"; do
+ test -n "$dir" && CPPFLAGS="$O_CPPFLAGS -I${dir}/include"
+ AC_CHECK_HEADER([skey.h], [found=yes; break], [], [#include <stdio.h>])
+ done
+ if test "$found" = "no" -o -z "$dir"; then
+ CPPFLAGS="$O_CPPFLAGS"
+ else
+ LDFLAGS="$LDFLAGS -L${dir}/lib"
+ SUDO_APPEND_LIBPATH(SUDOERS_LDFLAGS, [${dir}/lib])
+ fi
+ if test "$found" = "no"; then
+ AC_MSG_WARN([Unable to locate skey.h, you will have to edit the Makefile and add -I/path/to/skey/includes to CPPFLAGS])
+ fi
+ fi
+ AC_CHECK_LIB(skey, main, [found=yes], [AC_MSG_WARN([Unable to locate libskey.a, you will have to edit the Makefile and add -L/path/to/skey/lib to SUDOERS_LDFLAGS])])
+ AC_CHECK_LIB(skey, skeyaccess, AC_DEFINE(HAVE_SKEYACCESS))
+
+ AC_MSG_CHECKING([for RFC1938-compliant skeychallenge])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+# include <stdio.h>
+# include <skey.h>]],
+ [[skeychallenge(NULL, NULL, NULL, 0);]]
+ )], [
+ AC_DEFINE(HAVE_RFC1938_SKEYCHALLENGE)
+ AC_MSG_RESULT([yes])
+ ], [
+ AC_MSG_RESULT([no])
+ ]
+ )
+
+ LDFLAGS="$O_LDFLAGS"
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lskey"
+ AUTH_OBJS="$AUTH_OBJS rfc1938.lo"
+fi
+
+dnl
+dnl extra OPIE lib and includes
+dnl
+if test "${with_opie-'no'}" = "yes"; then
+ O_LDFLAGS="$LDFLAGS"
+ if test "$with_opie" != "yes"; then
+ AX_APPEND_FLAG([-I${with_opie}/include], [CPPFLAGS])
+ LDFLAGS="$LDFLAGS -L${with_opie}/lib"
+ SUDO_APPEND_LIBPATH(SUDOERS_LDFLAGS, [${with_opie}/lib])
+ AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#include <opie.h>]])], [found=yes], [found=no])
+ else
+ found=no
+ O_CPPFLAGS="$CPPFLAGS"
+ for dir in "" "/usr/local" "/usr/contrib"; do
+ test -n "$dir" && CPPFLAGS="$O_CPPFLAGS -I${dir}/include"
+ AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#include <opie.h>]])], [found=yes; break])
+ done
+ if test "$found" = "no" -o -z "$dir"; then
+ CPPFLAGS="$O_CPPFLAGS"
+ else
+ LDFLAGS="$LDFLAGS -L${dir}/lib"
+ SUDO_APPEND_LIBPATH(SUDOERS_LDFLAGS, [${dir}/lib])
+ fi
+ if test "$found" = "no"; then
+ AC_MSG_WARN([Unable to locate opie.h, you will have to edit the Makefile and add -I/path/to/opie/includes to CPPFLAGS])
+ fi
+ fi
+ AC_CHECK_LIB(opie, main, [found=yes], [AC_MSG_WARN([Unable to locate libopie.a, you will have to edit the Makefile and add -L/path/to/opie/lib to SUDOERS_LDFLAGS])])
+ LDFLAGS="$O_LDFLAGS"
+ SUDOERS_LIBS="${SUDOERS_LIBS} -lopie"
+ AUTH_OBJS="$AUTH_OBJS rfc1938.lo"
+fi
+
+dnl
+dnl Check for shadow password routines if we have not already done so.
+dnl If there is a specific list of functions to check we do that first.
+dnl Otherwise, we check for SVR4-style and then SecureWare-style.
+dnl
+if test ${with_passwd-'no'} != "no"; then
+ dnl
+ dnl if crypt(3) not in libc, look elsewhere
+ dnl
+ if test -z "$LIB_CRYPT"; then
+ _LIBS="$LIBS"
+ AC_SEARCH_LIBS([crypt], [crypt crypt_d ufc], [test -n "$ac_lib" && shadow_libs="${shadow_libs} $ac_res"])
+ LIBS="$_LIBS"
+ fi
+
+ if test "$CHECKSHADOW" = "true" -a -n "$shadow_funcs"; then
+ _LIBS="$LIBS"
+ LIBS="$LIBS $shadow_libs"
+ found=no
+ AC_CHECK_FUNCS($shadow_funcs, [found=yes])
+ if test "$found" = "yes"; then
+ case "$shadow_funcs" in
+ *getprpwnam*) SECUREWARE=1;;
+ esac
+ else
+ shadow_libs=
+ fi
+ CHECKSHADOW=false
+ LIBS="$_LIBS"
+ fi
+ if test "$CHECKSHADOW" = "true"; then
+ AC_SEARCH_LIBS([getspnam], [gen shadow], [AC_DEFINE(HAVE_GETSPNAM)] [CHECKSHADOW=false; test -n "$ac_lib" && shadow_libs="${shadow_libs} $ac_res"])
+ fi
+ if test "$CHECKSHADOW" = "true"; then
+ AC_SEARCH_LIBS([getprpwnam], [sec security prot], [AC_DEFINE(HAVE_GETPRPWNAM)] [CHECKSHADOW=false; SECUREWARE=1; test -n "$ac_lib" && shadow_libs="${shadow_libs} $ac_res"])
+ fi
+ if test -n "$shadow_libs"; then
+ # sudoers needs to link with shadow libs for password auth
+ SUDOERS_LIBS="$SUDOERS_LIBS $shadow_libs"
+ fi
+ if test -n "$SECUREWARE"; then
+ _LIBS="$LIBS"
+ LIBS="$LIBS $shadow_libs"
+ AC_CHECK_FUNCS([bigcrypt])
+ AUTH_OBJS="$AUTH_OBJS secureware.lo"
+ # set_auth_parameters() and initprivs() are called from sudo.c
+ AC_CHECK_FUNCS([set_auth_parameters initprivs], [test -n "$shadow_libs" && SUDO_LIBS="$SUDO_LIBS $shadow_libs"])
+ LIBS="$_LIBS"
+ fi
+fi
+
+dnl
+dnl Solaris 11 added a 4th argument to the au_close() function
+dnl
+if test X"$with_bsm_audit" = X"yes"; then
+ SUDO_FUNC_AU_CLOSE_SOLARIS11
+fi
+
+dnl
+dnl Choose event subsystem backend: poll or select
+dnl
+if test X"$enable_poll" = X""; then
+ AC_CHECK_FUNCS([ppoll poll], [enable_poll=yes; break], [enable_poll=no])
+elif test X"$enable_poll" = X"yes"; then
+ AC_CHECK_FUNCS([ppoll], [], AC_DEFINE(HAVE_POLL))
+fi
+if test "$enable_poll" = "yes"; then
+ COMMON_OBJS="${COMMON_OBJS} event_poll.lo"
+else
+ AC_CHECK_FUNCS([pselect])
+ COMMON_OBJS="${COMMON_OBJS} event_select.lo"
+fi
+
+dnl
+dnl extra lib and .o file for LDAP support
+dnl
+if test ${with_ldap-'no'} != "no"; then
+ O_LDFLAGS="$LDFLAGS"
+ if test "$with_ldap" != "yes"; then
+ SUDO_APPEND_LIBPATH(SUDOERS_LDFLAGS, [${with_ldap}/lib])
+ LDFLAGS="$LDFLAGS -L${with_ldap}/lib"
+ AX_APPEND_FLAG([-I${with_ldap}/include], [CPPFLAGS])
+ with_ldap=yes
+ fi
+ SUDOERS_OBJS="${SUDOERS_OBJS} ldap.lo ldap_conf.lo"
+ case "$SUDOERS_OBJS" in
+ *ldap_util.lo*) ;;
+ *) SUDOERS_OBJS="${SUDOERS_OBJS} ldap_util.lo";;
+ esac
+ LDAP=""
+
+ _LIBS="$LIBS"
+ LDAP_LIBS=""
+ IBMLDAP_EXTRA=""
+ found=no
+ # On HP-UX, libibmldap has a hidden dependency on libCsup
+ case "$host_os" in
+ hpux*) AC_CHECK_LIB(Csup, main, [IBMLDAP_EXTRA=" -lCsup"]);;
+ esac
+ AC_SEARCH_LIBS(ldap_init, "ibmldap${IBMLDAP_EXTRA}" "ibmldap -lidsldif${IBMLDAP_EXTRA}" "ldap" "ldap -llber" "ldap -llber -lssl -lcrypto" "ibmldap${IBMLDAP_EXTRA}", [
+ test "$ac_res" != "none required" && LDAP_LIBS="$ac_res"
+ found=yes
+ ])
+ # If nothing linked, try -lldap and hope for the best
+ if test "$found" = "no"; then
+ LDAP_LIBS="-lldap"
+ fi
+ LIBS="${_LIBS} ${LDAP_LIBS}"
+ dnl check if we need to link with -llber for ber_set_option
+ OLIBS="$LIBS"
+ AC_MSG_CHECKING([whether lber.h defines LBER_OPT_DEBUG_LEVEL])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
+# include <lber.h>]], [[int opt=LBER_OPT_DEBUG_LEVEL;]])], [
+ AC_MSG_RESULT([yes])
+ AC_SEARCH_LIBS([ber_set_option], [lber], [found=yes], [found=no])
+ if test X"$found" = X"yes" -a X"$LIBS" != X"$OLIBS"; then
+ LDAP_LIBS="$LDAP_LIBS -llber"
+ fi
+ ], [
+ AC_MSG_RESULT([no])
+ ])
+ dnl check if ldap.h includes lber.h for us
+ AC_MSG_CHECKING([whether lber.h is needed])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
+# include <ldap.h>]], [[(void)ldap_init(0, 0)]])], [AC_MSG_RESULT([no])], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_LBER_H)])
+
+ if test ${enable_sasl-'yes'} = "yes"; then
+ found_sasl_h=no
+ AC_CHECK_HEADERS([sasl/sasl.h] [sasl.h], [
+ found_sasl_h=yes
+ AC_CHECK_FUNCS([ldap_sasl_interactive_bind_s])
+ break
+ ])
+ if test X${enable_sasl} = X"yes"; then
+ if test X"$found_sasl_h" != X"yes"; then
+ AC_MSG_ERROR(["--enable-sasl specified but unable to locate SASL development headers."])
+ fi
+ if test X"$ac_cv_func_ldap_sasl_interactive_bind_s" != X"yes"; then :
+ AC_MSG_ERROR(["--enable-sasl specified but SASL support is missing in your LDAP library"])
+ fi
+ fi
+ fi
+ AC_CHECK_HEADERS([ldap_ssl.h] [mps/ldap_ssl.h], [break], [], [#include <ldap.h>])
+ AC_CHECK_FUNCS([ldap_initialize ldap_start_tls_s ldapssl_init ldapssl_set_strength ldap_unbind_ext_s ldap_str2dn ldap_create ldap_sasl_bind_s ldap_ssl_init ldap_ssl_client_init ldap_start_tls_s_np])
+ AC_CHECK_FUNCS([ldap_search_ext_s ldap_search_st], [break])
+
+ if test X"$check_gss_krb5_ccache_name" = X"yes"; then
+ AC_CHECK_LIB(gssapi, gss_krb5_ccache_name,
+ AC_DEFINE(HAVE_GSS_KRB5_CCACHE_NAME)
+ [LDAP_LIBS="${LDAP_LIBS} -lgssapi"],
+ AC_CHECK_LIB(gssapi_krb5, gss_krb5_ccache_name,
+ AC_DEFINE(HAVE_GSS_KRB5_CCACHE_NAME)
+ [LDAP_LIBS="${LDAP_LIBS} -lgssapi_krb5"])
+ )
+
+ # gssapi headers may be separate or part of Kerberos V
+ found=no
+ O_CPPFLAGS="$CPPFLAGS"
+ for dir in "" "kerberosV" "krb5" "kerberos5" "kerberosv5"; do
+ test X"$dir" != X"" && CPPFLAGS="$O_CPPFLAGS -I/usr/include/${dir}"
+ AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#include <gssapi/gssapi.h>]])], [found="gssapi/gssapi.h"; break], [AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#include <gssapi.h>]])], [found="gssapi.h"; break])])
+ done
+ if test X"$found" != X"no"; then
+ AC_CHECK_HEADERS([$found])
+ if test X"$found" = X"gssapi/gssapi.h"; then
+ AC_CHECK_HEADERS([gssapi/gssapi_krb5.h])
+ fi
+ else
+ CPPFLAGS="$O_CPPFLAGS"
+ AC_MSG_WARN([Unable to locate gssapi.h, you will have to edit the Makefile and add -I/path/to/gssapi/includes to CPPFLAGS])
+ fi
+ fi
+
+ SUDOERS_LIBS="${SUDOERS_LIBS} ${LDAP_LIBS}"
+ LIBS="$_LIBS"
+ LDFLAGS="$O_LDFLAGS"
+fi
+
+#
+# How to do dynamic object loading.
+# We support dlopen() and sh_load(), else fall back to static loading.
+#
+case "$lt_cv_dlopen" in
+ dlopen)
+ AC_DEFINE(HAVE_DLOPEN)
+ if test "$enable_static_sudoers" = "yes"; then
+ AC_DEFINE(STATIC_SUDOERS_PLUGIN)
+ SUDO_OBJS="${SUDO_OBJS} preload.o"
+ STATIC_SUDOERS="\$(top_builddir)/plugins/sudoers/sudoers.la"
+ AX_APPEND_FLAG([--tag=disable-shared -static], [SUDOERS_LDFLAGS])
+ LT_STATIC=""
+ else
+ LT_STATIC="--tag=disable-static"
+ fi
+ ;;
+ shl_load)
+ AC_DEFINE(HAVE_SHL_LOAD)
+ if test "$enable_static_sudoers" = "yes"; then
+ AC_DEFINE(STATIC_SUDOERS_PLUGIN)
+ SUDO_OBJS="${SUDO_OBJS} preload.o"
+ STATIC_SUDOERS="\$(top_builddir)/plugins/sudoers/sudoers.la"
+ AX_APPEND_FLAG([--tag=disable-shared -static], [SUDOERS_LDFLAGS])
+ LT_STATIC=""
+ else
+ LT_STATIC="--tag=disable-static"
+ fi
+ ;;
+ *)
+ if test X"${ac_cv_func_dlopen}" = X"yes"; then
+ AC_MSG_ERROR(["dlopen present but libtool doesn't appear to support your platform."])
+ fi
+ # Preload sudoers module symbols
+ AC_DEFINE(STATIC_SUDOERS_PLUGIN)
+ SUDO_OBJS="${SUDO_OBJS} preload.o"
+ STATIC_SUDOERS="\$(top_builddir)/plugins/sudoers/sudoers.la"
+ LT_STATIC=""
+ ;;
+esac
+
+#
+# The check_symbols test can only succeed with a dynamic sudoers plugin.
+#
+if test X"$STATIC_SUDOERS" = X""; then
+ SUDOERS_TEST_PROGS="${SUDOERS_TEST_PROGS}${SUDOERS_TEST_PROGS+ }check_symbols"
+fi
+
+#
+# We can only disable linking with the shared libsudo_util if
+# sudoers is linked statically too.
+#
+if test "$enable_shared_libutil" = "no"; then
+ if test X"$STATIC_SUDOERS" = X""; then
+ AC_MSG_ERROR(["--disable-shared-libutil may only be specified with --enable-static-sudoers or when dynamic linking is disabled."])
+ else
+ # Do not install sudoers or libsudo_util.
+ AX_APPEND_FLAG([-no-install], [SUDOERS_LDFLAGS])
+ AX_APPEND_FLAG([-no-install], [LIBUTIL_LDFLAGS])
+ fi
+fi
+
+# On HP-UX, you cannot dlopen() a shared object that uses pthreads unless
+# the main program is linked against -lpthread. We have no knowledge of
+# what libraries a plugin may depend on (e.g. HP-UX LDAP which uses pthreads)
+# so always link against -lpthread on HP-UX if it is available.
+# This check should go after all other libraries tests.
+case "$host_os" in
+ hpux*)
+ AC_CHECK_LIB(pthread, main, [SUDO_LIBS="${SUDO_LIBS} -lpthread"])
+ AC_DEFINE(_REENTRANT)
+ ;;
+esac
+
+dnl
+dnl Check for log file, timestamp and iolog locations
+dnl
+if test "$utmp_style" = "LEGACY"; then
+ SUDO_PATH_UTMP
+fi
+SUDO_LOGFILE
+SUDO_RUNDIR
+SUDO_VARDIR
+SUDO_IO_LOGDIR
+SUDO_TZDIR
+
+dnl
+dnl Attempt to use _FORTIFY_SOURCE with sprintf. If the headers support
+dnl it but libc does not, __sprintf_chk should be an undefined symbol.
+dnl
+if test "$enable_hardening" != "no"; then
+ O_CPPFLAGS="$CPPFLAGS"
+ AX_APPEND_FLAG([-D_FORTIFY_SOURCE=2], [CPPFLAGS])
+ AC_CACHE_CHECK([whether _FORTIFY_SOURCE may be specified],
+ [sudo_cv_use_fortify_source],
+ [AC_LINK_IFELSE([
+ AC_LANG_PROGRAM(
+ [[]], [[char buf[4]; (void)sprintf(buf, "%s", "foo");]]
+ )],
+ [sudo_cv_use_fortify_source=yes],
+ [sudo_cv_use_fortify_source=no]
+ )
+ ]
+ [AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[]], [[]])],
+ [sudo_cv_use_fortify_source=yes],
+ [sudo_cv_use_fortify_source=no]
+ )
+ ]
+ )
+ if test "$sudo_cv_use_fortify_source" != yes; then
+ CPPFLAGS="$O_CPPFLAGS"
+ fi
+fi
+
+dnl
+dnl Turn warnings into errors.
+dnl All compiler/loader tests after this point will fail if
+dnl a warning is displayed (normally, warnings are not fatal).
+dnl
+AC_LANG_WERROR
+
+dnl
+dnl If compiler supports the -static-libgcc flag use it unless we have
+dnl GNU ld (which can avoid linking in libgcc when it is not needed).
+dnl This test relies on AC_LANG_WERROR
+dnl
+if test -n "$GCC" -a "$lt_cv_prog_gnu_ld" != "yes" -a -n "$GCC"; then
+ AX_CHECK_COMPILE_FLAG([-static-libgcc], [AX_APPEND_FLAG([-Wc,-static-libgcc], [LT_LDFLAGS])])
+fi
+
+dnl
+dnl Check for symbol visibility support.
+dnl This test relies on AC_LANG_WERROR
+dnl
+if test -n "$GCC"; then
+ AX_CHECK_COMPILE_FLAG([-fvisibility=hidden], [
+ AC_DEFINE(HAVE_DSO_VISIBILITY)
+ CFLAGS="${CFLAGS} -fvisibility=hidden"
+ LT_LDEXPORTS=
+ LT_LDDEP=
+ ])
+else
+ case "$host_os" in
+ hpux*)
+ AX_CHECK_COMPILE_FLAG([-Bhidden_def], [
+ AC_DEFINE(HAVE_DSO_VISIBILITY)
+ CFLAGS="${CFLAGS} -Bhidden_def"
+ LT_LDEXPORTS=
+ LT_LDDEP=
+ ])
+ ;;
+ solaris2*)
+ AX_CHECK_COMPILE_FLAG([-xldscope=hidden], [
+ AC_DEFINE(HAVE_DSO_VISIBILITY)
+ CFLAGS="${CFLAGS} -xldscope=hidden"
+ LT_LDEXPORTS=
+ LT_LDDEP=
+ ])
+ ;;
+ esac
+fi
+
+dnl
+dnl If the compiler doesn't have symbol visibility support, it may
+dnl support version scripts (only GNU and Solaris ld).
+dnl This test relies on AC_LANG_WERROR
+dnl
+if test -n "$LT_LDEXPORTS"; then
+ if test "$lt_cv_prog_gnu_ld" = "yes"; then
+ AC_CACHE_CHECK([whether ld supports anonymous map files],
+ [sudo_cv_var_gnu_ld_anon_map],
+ [
+ sudo_cv_var_gnu_ld_anon_map=no
+ cat > conftest.map <<-EOF
+ {
+ global: foo;
+ local: *;
+ };
+EOF
+ _CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $lt_prog_compiler_pic"
+ _LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -fpic -shared -Wl,--version-script,./conftest.map"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[int foo;]], [[]])],
+ [sudo_cv_var_gnu_ld_anon_map=yes])
+ CFLAGS="$_CFLAGS"
+ LDFLAGS="$_LDFLAGS"
+ ]
+ )
+ if test "$sudo_cv_var_gnu_ld_anon_map" = "yes"; then
+ LT_LDDEP="\$(shlib_map)"; LT_LDEXPORTS="-Wl,--version-script,\$(shlib_map)"
+ fi
+ else
+ case "$host_os" in
+ solaris2*)
+ AC_CACHE_CHECK([whether ld supports anonymous map files],
+ [sudo_cv_var_solaris_ld_anon_map],
+ [
+ sudo_cv_var_solaris_ld_anon_map=no
+ cat > conftest.map <<-EOF
+ {
+ global: foo;
+ local: *;
+ };
+EOF
+ _CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $lt_prog_compiler_pic"
+ _LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared -Wl,-M,./conftest.map"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[int foo;]], [[]])],
+ [sudo_cv_var_solaris_ld_anon_map=yes])
+ CFLAGS="$_CFLAGS"
+ LDFLAGS="$_LDFLAGS"
+ ]
+ )
+ if test "$sudo_cv_var_solaris_ld_anon_map" = "yes"; then
+ LT_LDDEP="\$(shlib_map)"; LT_LDEXPORTS="-Wl,-M,\$(shlib_map)"
+ fi
+ ;;
+ hpux*)
+ AC_CACHE_CHECK([whether ld supports controlling exported symbols],
+ [sudo_cv_var_hpux_ld_symbol_export],
+ [
+ sudo_cv_var_hpux_ld_symbol_export=no
+ echo "+e foo" > conftest.opt
+ _CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $lt_prog_compiler_pic"
+ _LDFLAGS="$LDFLAGS"
+ if test -n "$GCC"; then
+ LDFLAGS="$LDFLAGS -shared -Wl,-c,./conftest.opt"
+ else
+ LDFLAGS="$LDFLAGS -Wl,-b -Wl,-c,./conftest.opt"
+ fi
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[int foo;]], [[]])],
+ [sudo_cv_var_hpux_ld_symbol_export=yes])
+ CFLAGS="$_CFLAGS"
+ LDFLAGS="$_LDFLAGS"
+ rm -f conftest.opt
+ ]
+ )
+ if test "$sudo_cv_var_hpux_ld_symbol_export" = "yes"; then
+ LT_LDDEP="\$(shlib_opt)"; LT_LDEXPORTS="-Wl,-c,\$(shlib_opt)"
+ fi
+ ;;
+ esac
+ fi
+fi
+
+dnl
+dnl Check for -fsanitize=address,undefined support
+dnl This test relies on AC_LANG_WERROR
+dnl
+if test "$enable_asan" = "yes"; then
+ AX_CHECK_COMPILE_FLAG([-fsanitize=address -fsanitize=undefined], [
+ AX_CHECK_LINK_FLAG([-fsanitize=address -fsanitize=undefined], [
+ ASAN_LDFLAGS="-Wc,-fsanitize=address -Wc,-fsanitize=undefined"
+ ASAN_CFLAGS="-fsanitize=address -fsanitize=undefined"
+ AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer], [
+ CFLAGS="$CFLAGS -fno-omit-frame-pointer"
+ ])
+ AC_DEFINE(NO_LEAKS)
+ ])
+ ])
+fi
+
+dnl
+dnl Check for PIE executable support if using gcc.
+dnl This test relies on AC_LANG_WERROR
+dnl
+if test -n "$GCC"; then
+ if test -z "$enable_pie"; then
+ case "$host_os" in
+ linux*)
+ # Attempt to build with PIE support
+ enable_pie="maybe"
+ ;;
+ esac
+ fi
+ if test -n "$enable_pie"; then
+ if test "$enable_pie" = "no"; then
+ AX_CHECK_COMPILE_FLAG([-fno-pie], [
+ _CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fno-pie"
+ AX_CHECK_LINK_FLAG([-nopie], [
+ PIE_CFLAGS="-fno-pie"
+ PIE_LDFLAGS="-nopie"
+ ])
+ CFLAGS="$_CFLAGS"
+ ])
+ else
+ AX_CHECK_COMPILE_FLAG([-fPIE], [
+ _CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fPIE"
+ AX_CHECK_LINK_FLAG([-pie], [
+ if test "$enable_pie" = "maybe"; then
+ SUDO_WORKING_PIE([enable_pie=yes], [])
+ fi
+ if test "$enable_pie" = "yes"; then
+ PIE_CFLAGS="-fPIE"
+ PIE_LDFLAGS="-Wc,-fPIE -pie"
+ fi
+ ])
+ CFLAGS="$_CFLAGS"
+ ])
+ fi
+ fi
+fi
+if test "$enable_pie" != "yes"; then
+ # Solaris 11.1 and higher supports tagging binaries to use ASLR
+ case "$host_os" in
+ solaris2.1[[1-9]]|solaris2.[[2-9]][[0-9]])
+ AX_CHECK_LINK_FLAG([-Wl,-z,aslr], [AX_APPEND_FLAG([-Wl,-z,aslr], [PIE_LDFLAGS])])
+ ;;
+ esac
+fi
+
+dnl
+dnl Check for -fstack-protector and -z relro support
+dnl This test relies on AC_LANG_WERROR
+dnl
+if test "$enable_hardening" != "no"; then
+ AC_CACHE_CHECK([for compiler stack protector support],
+ [sudo_cv_var_stack_protector],
+ [
+ # Avoid CFLAGS since the compiler might optimize away our test.
+ # We don't want CPPFLAGS or LIBS to interfere with the test but
+ # keep LDFLAGS as it may have an rpath needed to find the ssp lib.
+ _CPPFLAGS="$CPPFLAGS"
+ _CFLAGS="$CFLAGS"
+ _LDFLAGS="$LDFLAGS"
+ _LIBS="$LIBS"
+ CPPFLAGS=
+ LIBS=
+
+ sudo_cv_var_stack_protector="-fstack-protector-strong"
+ CFLAGS="$sudo_cv_var_stack_protector"
+ LDFLAGS="$_LDFLAGS $sudo_cv_var_stack_protector"
+ AC_LINK_IFELSE([
+ AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
+ [[char buf[1024]; buf[1023] = '\0';]])
+ ], [], [
+ sudo_cv_var_stack_protector="-fstack-protector-all"
+ CFLAGS="$sudo_cv_var_stack_protector"
+ LDFLAGS="$_LDFLAGS $sudo_cv_var_stack_protector"
+ AC_LINK_IFELSE([
+ AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
+ [[char buf[1024]; buf[1023] = '\0';]])
+ ], [], [
+ sudo_cv_var_stack_protector="-fstack-protector"
+ CFLAGS="$sudo_cv_var_stack_protector"
+ LDFLAGS="$_LDFLAGS $sudo_cv_var_stack_protector"
+ AC_LINK_IFELSE([
+ AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
+ [[char buf[1024]; buf[1023] = '\0';]])
+ ], [], [
+ sudo_cv_var_stack_protector=no
+ ])
+ ])
+ ])
+ CPPFLAGS="$_CPPFLAGS"
+ CFLAGS="$_CFLAGS"
+ LDFLAGS="$_LDFLAGS"
+ LIBS="$_LIBS"
+ ]
+ )
+ if test X"$sudo_cv_var_stack_protector" != X"no"; then
+ SSP_CFLAGS="$sudo_cv_var_stack_protector"
+ SSP_LDFLAGS="-Wc,$sudo_cv_var_stack_protector"
+ fi
+ AX_CHECK_LINK_FLAG([-Wl,-z,relro], [AX_APPEND_FLAG([-Wl,-z,relro], [LDFLAGS])])
+fi
+
+dnl
+dnl Use passwd auth module?
+dnl
+case "$with_passwd" in
+yes|maybe)
+ AUTH_OBJS="$AUTH_OBJS getspwuid.lo passwd.lo"
+ ;;
+*)
+ AC_DEFINE(WITHOUT_PASSWD)
+ if test -z "$AUTH_OBJS"; then
+ AC_MSG_ERROR([no authentication methods defined.])
+ fi
+ ;;
+esac
+AUTH_OBJS=${AUTH_OBJS# }
+_AUTH=`echo "$AUTH_OBJS" | sed -e 's/\.lo//g' -e 's/getspwuid *//'`
+AC_MSG_NOTICE([using the following authentication methods: $_AUTH])
+
+dnl
+dnl LIBS may contain duplicates from SUDO_LIBS, SUDOERS_LIBS, or NET_LIBS
+dnl
+if test -n "$LIBS"; then
+ L="$LIBS"
+ LIBS=
+ for l in ${L}; do
+ dupe=0
+ for sl in ${SUDO_LIBS} ${SUDOERS_LIBS} ${NET_LIBS}; do
+ test $l = $sl && dupe=1
+ done
+ test $dupe = 0 && LIBS="${LIBS} $l"
+ done
+fi
+
+dnl
+dnl OS-specific initialization
+dnl
+AC_DEFINE_UNQUOTED(os_init, $OS_INIT, [Define to an OS-specific initialization function or `os_init_common'.])
+
+dnl
+dnl We add -Wall and -Werror after all tests so they don't cause failures
+dnl
+if test -n "$GCC"; then
+ if test X"$enable_warnings" = X"yes" -o X"$with_devel" = X"yes"; then
+ CFLAGS="${CFLAGS} -Wall -Wsign-compare -Wpointer-arith"
+ fi
+ if test X"$enable_werror" = X"yes"; then
+ CFLAGS="${CFLAGS} -Werror"
+ fi
+fi
+
+dnl
+dnl Skip regress tests and sudoers sanity check if cross compiling.
+dnl
+CROSS_COMPILING="$cross_compiling"
+
+dnl
+dnl Set exec_prefix
+dnl
+test "$exec_prefix" = "NONE" && exec_prefix='$(prefix)'
+
+dnl
+dnl Defer setting _PATH_SUDO_NOEXEC until after exec_prefix is set
+dnl XXX - this is gross!
+dnl
+if test X"$with_noexec" != X"no" -o X"$with_selinux" != X"no" -o "$enabled_shared" != X"no"; then
+ oexec_prefix="$exec_prefix"
+ if test "$exec_prefix" = '$(prefix)'; then
+ if test "$prefix" = "NONE"; then
+ exec_prefix="$ac_default_prefix"
+ else
+ exec_prefix="$prefix"
+ fi
+ fi
+ if test X"$with_noexec" != X"no"; then
+ PROGS="${PROGS} sudo_noexec.la"
+ INSTALL_NOEXEC="install-noexec"
+
+ # Can't use asan with LD_PRELOAD
+ if test "$enable_asan" != "yes"; then
+ CHECK_NOEXEC=check_noexec
+ fi
+
+ noexec_file="$with_noexec"
+ _noexec_file=
+ while test X"$noexec_file" != X"$_noexec_file"; do
+ _noexec_file="$noexec_file"
+ eval noexec_file="$_noexec_file"
+ done
+ SUDO_DEFINE_UNQUOTED(_PATH_SUDO_NOEXEC, "$noexec_file", [The fully qualified pathname of sudo_noexec.so])
+ fi
+ if test X"$with_selinux" != X"no"; then
+ sesh_file="$libexecdir/sudo/sesh"
+ _sesh_file=
+ while test X"$sesh_file" != X"$_sesh_file"; do
+ _sesh_file="$sesh_file"
+ eval sesh_file="$_sesh_file"
+ done
+ SUDO_DEFINE_UNQUOTED(_PATH_SUDO_SESH, "$sesh_file")
+ fi
+ if test X"$enable_shared" != X"no"; then
+ PLUGINDIR="$with_plugindir"
+ _PLUGINDIR=
+ while test X"$PLUGINDIR" != X"$_PLUGINDIR"; do
+ _PLUGINDIR="$PLUGINDIR"
+ eval PLUGINDIR="$_PLUGINDIR"
+ done
+ SUDO_DEFINE_UNQUOTED(_PATH_SUDO_PLUGIN_DIR, "$PLUGINDIR/")
+ AC_DEFINE(ENABLE_SUDO_PLUGIN_API, 1, [Define to 1 to enable sudo's plugin interface.])
+ fi
+ exec_prefix="$oexec_prefix"
+fi
+if test X"$with_noexec" = X"no"; then
+ SUDO_DEFINE_UNQUOTED(_PATH_SUDO_NOEXEC, NULL)
+fi
+if test X"$with_selinux" = X"no"; then
+ SUDO_DEFINE_UNQUOTED(_PATH_SUDO_SESH, NULL)
+fi
+if test X"$enable_shared" = X"no"; then
+ SUDO_DEFINE_UNQUOTED(_PATH_SUDO_PLUGIN_DIR, NULL)
+fi
+
+dnl
+dnl Add -R options to LDFLAGS, etc.
+dnl
+if test X"$LDFLAGS_R" != X""; then
+ LDFLAGS="$LDFLAGS $LDFLAGS_R"
+fi
+if test X"$SUDOERS_LDFLAGS_R" != X""; then
+ SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS $SUDOERS_LDFLAGS_R"
+fi
+if test X"$ZLIB_R" != X""; then
+ ZLIB="$ZLIB_R $ZLIB"
+fi
+
+dnl
+dnl Override default configure dirs for the Makefile
+dnl
+if test X"$prefix" = X"NONE"; then
+ test "$mandir" = '${datarootdir}/man' && mandir='$(prefix)/man'
+else
+ test "$mandir" = '${datarootdir}/man' && mandir='$(datarootdir)/man'
+fi
+test "$bindir" = '${exec_prefix}/bin' && bindir='$(exec_prefix)/bin'
+test "$sbindir" = '${exec_prefix}/sbin' && sbindir='$(exec_prefix)/sbin'
+test "$libexecdir" = '${exec_prefix}/libexec' && libexecdir='$(exec_prefix)/libexec'
+test "$includedir" = '${prefix}/include' && includedir='$(prefix)/include'
+test "$datarootdir" = '${prefix}/share' && datarootdir='$(prefix)/share'
+test "$docdir" = '${datarootdir}/doc/${PACKAGE_TARNAME}' && docdir='$(datarootdir)/doc/$(PACKAGE_TARNAME)'
+test "$localedir" = '${datarootdir}/locale' && localedir='$(datarootdir)/locale'
+test "$localstatedir" = '${prefix}/var' && localstatedir='$(prefix)/var'
+test "$sysconfdir" = '${prefix}/etc' && sysconfdir='/etc'
+
+dnl
+dnl Substitute into the Makefile and man pages
+dnl
+if test X"$INIT_SCRIPT" != X""; then
+ AC_CONFIG_FILES([init.d/$INIT_SCRIPT])
+elif test X"$TMPFILES_D" != X""; then
+ AC_CONFIG_FILES([init.d/sudo.conf])
+fi
+AC_CONFIG_FILES([Makefile doc/Makefile examples/Makefile include/Makefile lib/util/Makefile lib/util/util.exp src/sudo_usage.h src/Makefile plugins/sample/Makefile plugins/group_file/Makefile plugins/system_group/Makefile plugins/sudoers/Makefile plugins/sudoers/sudoers])
+AC_OUTPUT
+
+dnl
+dnl Spew any text the user needs to know about
+dnl
+if test "$with_pam" = "yes"; then
+ case $host_os in
+ hpux*)
+ if test -f /usr/lib/security/libpam_hpsec.so.1; then
+ AC_MSG_NOTICE([You may wish to add the following line to /etc/pam.conf])
+ AC_MSG_NOTICE([sudo session required libpam_hpsec.so.1 bypass_umask bypass_last_login])
+ fi
+ ;;
+ linux*)
+ AC_MSG_NOTICE([You will need to customize examples/pam.conf and install it as /etc/pam.d/sudo])
+ ;;
+ esac
+fi
+dnl
+dnl Warn user if they may need to clear rundir manually.
+dnl
+case "$rundir" in
+ /run/*|/var/run/*)
+ clear_rundir=0
+ ;;
+ *)
+ clear_rundir=1
+ ;;
+esac
+if test $clear_rundir -eq 1; then
+ AC_MSG_NOTICE([Warning: the $rundir/ts directory must be cleared at boot time.])
+ AC_MSG_NOTICE([ You may need to create a startup item to do this.])
+fi
+
+dnl
+dnl Autoheader templates
+dnl
+AH_TEMPLATE(CLASSIC_INSULTS, [Define to 1 if you want the insults from the "classic" version sudo.])
+AH_TEMPLATE(CSOPS_INSULTS, [Define to 1 if you want insults culled from the twisted minds of CSOps.])
+AH_TEMPLATE(DONT_LEAK_PATH_INFO, [Define to 1 if you want sudo to display "command not allowed" instead of "command not found" when a command cannot be found.])
+AH_TEMPLATE(ENV_DEBUG, [Define to 1 to enable environment function debugging.])
+AH_TEMPLATE(ENV_EDITOR, [Define to 1 if you want visudo to honor the EDITOR and VISUAL env variables.])
+AH_TEMPLATE(FQDN, [Define to 1 if you want to require fully qualified hosts in sudoers.])
+AH_TEMPLATE(ENV_RESET, [Define to 1 to enable environment resetting by default.])
+AH_TEMPLATE(PYTHON_INSULTS, [Define to 1 if you want insults from "Monty Python's Flying Circus".])
+AH_TEMPLATE(GOONS_INSULTS, [Define to 1 if you want insults from the "Goon Show".])
+AH_TEMPLATE(HAL_INSULTS, [Define to 1 if you want 2001-like insults.])
+AH_TEMPLATE(HAVE_AFS, [Define to 1 if you use AFS.])
+AH_TEMPLATE(HAVE_AIXAUTH, [Define to 1 if you use AIX general authentication.])
+AH_TEMPLATE(HAVE_BSD_AUTH_H, [Define to 1 if you use BSD authentication.])
+AH_TEMPLATE(HAVE_BSM_AUDIT, [Define to 1 to enable BSM audit support.])
+AH_TEMPLATE(HAVE_DCE, [Define to 1 if you use OSF DCE.])
+AH_TEMPLATE(HAVE_DD_FD, [Define to 1 if your `DIR' contains dd_fd.])
+AH_TEMPLATE(HAVE_DIRFD, [Define to 1 if you have the `dirfd' function or macro.])
+AH_TEMPLATE(HAVE_DISPCRYPT, [Define to 1 if you have the `dispcrypt' function.])
+AH_TEMPLATE(HAVE_DLOPEN, [Define to 1 if you have the `dlopen' function.])
+AH_TEMPLATE(HAVE_FCNTL_CLOSEM, [Define to 1 if your system has the F_CLOSEM fcntl.])
+AH_TEMPLATE(HAVE_FNMATCH, [Define to 1 if you have the `fnmatch' function.])
+AH_TEMPLATE(HAVE_FWTK, [Define to 1 if you use the FWTK authsrv daemon.])
+AH_TEMPLATE(HAVE_GETPRPWNAM, [Define to 1 if you have the `getprpwnam' function. (SecureWare-style shadow passwords).])
+AH_TEMPLATE(HAVE_GETPWNAM_SHADOW, [Define to 1 if you have the `getpwnam_shadow' function.])
+AH_TEMPLATE(HAVE_GETSPNAM, [Define to 1 if you have the `getspnam' function (SVR4-style shadow passwords).])
+AH_TEMPLATE(HAVE_GSS_KRB5_CCACHE_NAME, [Define to 1 if you have the `gss_krb5_ccache_name' function.])
+AH_TEMPLATE(HAVE_HEIMDAL, [Define to 1 if your Kerberos is Heimdal.])
+AH_TEMPLATE(HAVE_INET_NTOP, [Define to 1 if you have the `inet_ntop' function.])
+AH_TEMPLATE(HAVE_INET_PTON, [Define to 1 if you have the `inet_pton' function.])
+AH_TEMPLATE(HAVE_ISCOMSEC, [Define to 1 if you have the `iscomsec' function. (HP-UX >= 10.x check for shadow enabled).])
+AH_TEMPLATE(HAVE_KERB5, [Define to 1 if you use Kerberos V.])
+AH_TEMPLATE(HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC, [Define to 1 if you have the `krb5_get_init_creds_opt_alloc' function.])
+AH_TEMPLATE(HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_TWO_ARGS, [Define to 1 if your `krb5_get_init_creds_opt_free' function takes two arguments.])
+AH_TEMPLATE(HAVE_KRB5_INIT_SECURE_CONTEXT, [Define to 1 if you have the `krb5_init_secure_context' function.])
+AH_TEMPLATE(HAVE_KRB5_VERIFY_USER, [Define to 1 if you have the `krb5_verify_user' function.])
+AH_TEMPLATE(HAVE_LBER_H, [Define to 1 if your LDAP needs <lber.h>. (OpenLDAP does not).])
+AH_TEMPLATE(HAVE_LDAP, [Define to 1 if you use LDAP for sudoers.])
+AH_TEMPLATE(HAVE_LIBINTL_H, [Define to 1 if you have the <libintl.h> header file.])
+AH_TEMPLATE(HAVE_LINUX_AUDIT, [Define to 1 to enable Linux audit support.])
+AH_TEMPLATE(HAVE_SSSD, [Define to 1 to enable SSSD support.])
+AH_TEMPLATE(HAVE_OPIE, [Define to 1 if you use NRL OPIE.])
+AH_TEMPLATE(HAVE_OPTRESET, [Define to 1 if you have the `optreset' symbol.])
+AH_TEMPLATE(HAVE_PAM, [Define to 1 if you use PAM authentication.])
+AH_TEMPLATE(HAVE_PAM_LOGIN, [Define to 1 if you use a specific PAM session for sudo -i.])
+AH_TEMPLATE(HAVE_PROJECT_H, [Define to 1 if you have the <project.h> header file.])
+AH_TEMPLATE(HAVE_SECURID, [Define to 1 if you use SecurID for authentication.])
+AH_TEMPLATE(HAVE_SELINUX, [Define to 1 to enable SELinux RBAC support.])
+AH_TEMPLATE(HAVE_SETKEYCREATECON, [Define to 1 if you have the `setkeycreatecon' function.])
+AH_TEMPLATE(HAVE_SHL_LOAD, [Define to 1 if you have the `shl_load' function.])
+AH_TEMPLATE(HAVE_SKEY, [Define to 1 if you use S/Key.])
+AH_TEMPLATE(HAVE_SKEYACCESS, [Define to 1 if your S/Key library has skeyaccess().])
+AH_TEMPLATE(HAVE_RFC1938_SKEYCHALLENGE, [Define to 1 if the skeychallenge() function is RFC1938-compliant and takes 4 arguments.])
+AH_TEMPLATE(HAVE_SOLARIS_AUDIT, [Define to 1 to enable Solaris audit support.])
+AH_TEMPLATE(HAVE_ST__TIM, [Define to 1 if your struct stat uses an st__tim union.])
+AH_TEMPLATE(HAVE_ST_MTIM, [Define to 1 if your struct stat has an st_mtim member.])
+AH_TEMPLATE(HAVE_ST_MTIMESPEC, [Define to 1 if your struct stat has an st_mtimespec member.])
+AH_TEMPLATE(HAVE_ST_NMTIME, [Define to 1 if your struct stat has an st_nmtime member.])
+AH_TEMPLATE(HAVE___PROGNAME, [Define to 1 if your crt0.o defines the __progname symbol for you.])
+AH_TEMPLATE(HOST_IN_LOG, [Define to 1 if you want the hostname to be entered into the log file.])
+AH_TEMPLATE(IGNORE_DOT_PATH, [Define to 1 if you want to ignore '.' and empty PATH elements.])
+AH_TEMPLATE(LOGGING, [Define to SLOG_SYSLOG, SLOG_FILE, or SLOG_BOTH.])
+AH_TEMPLATE(LONG_OTP_PROMPT, [Define to 1 if you want a two line OTP (S/Key or OPIE) prompt.])
+AH_TEMPLATE(NO_AUTHENTICATION, [Define to 1 if you don't want sudo to prompt for a password by default.])
+AH_TEMPLATE(NO_LEAKS, [Define to 1 if you want sudo to free up memory before exiting.])
+AH_TEMPLATE(NO_LECTURE, [Define to 1 if you don't want users to get the lecture the first they user sudo.])
+AH_TEMPLATE(NO_PAM_SESSION, [Define to 1 if you don't want to use sudo's PAM session support.])
+AH_TEMPLATE(NO_ROOT_MAILER, [Define to avoid runing the mailer as root.])
+AH_TEMPLATE(NO_ROOT_SUDO, [Define to 1 if root should not be allowed to use sudo.])
+AH_TEMPLATE(TIMESTAMP_TYPE, [Define to global, ppid or tty to set the default timestamp record type.])
+AH_TEMPLATE(OFFENSIVE_INSULTS, [Define to 1 to include offensive insults from the classic version of sudo.])
+AH_TEMPLATE(PREFER_PORTABLE_GETCWD, [Define to 1 to enable replacement getcwd if system getcwd is broken.])
+AH_TEMPLATE(SECURE_PATH, [A colon-separated list of directories to override the user's PATH with.])
+AH_TEMPLATE(SEND_MAIL_WHEN_NOT_OK, [Define to 1 to send mail when the user is not allowed to run a command.])
+AH_TEMPLATE(SEND_MAIL_WHEN_NO_HOST, [Define to 1 to send mail when the user is not allowed to run sudo on this host.])
+AH_TEMPLATE(SEND_MAIL_WHEN_NO_USER, [Define to 1 to send mail when the user is not in the sudoers file.])
+AH_TEMPLATE(SHELL_IF_NO_ARGS, [Define to 1 if you want sudo to start a shell if given no arguments.])
+AH_TEMPLATE(SHELL_SETS_HOME, [Define to 1 if you want sudo to set $HOME in shell mode.])
+AH_TEMPLATE(STATIC_SUDOERS_PLUGIN, [Define to 1 to compile the sudoers plugin statically into the sudo binary.])
+AH_TEMPLATE(STUB_LOAD_INTERFACES, [Define to 1 if the code in interfaces.c does not compile for you.])
+AH_TEMPLATE(UMASK_OVERRIDE, [Define to 1 to use the umask specified in sudoers even when it is less restrictive than the invoking user's.])
+AH_TEMPLATE(USE_ADMIN_FLAG, [Define to 1 if you want to create ~/.sudo_as_admin_successful if the user is in the admin group the first time they run sudo.])
+AH_TEMPLATE(USE_INSULTS, [Define to 1 if you want to insult the user for entering an incorrect password.])
+AH_TEMPLATE(USE_STOW, [Define to 1 if you use GNU stow packaging.])
+AH_TEMPLATE(WITHOUT_PASSWD, [Define to avoid using the passwd/shadow file for authentication.])
+AH_TEMPLATE(clockid_t, [Define to `int' if <time.h> does not define.])
+AH_TEMPLATE(sig_atomic_t, [Define to `int' if <signal.h> does not define.])
+AH_TEMPLATE(socklen_t, [Define to `unsigned int' if <sys/socket.h> doesn't define.])
+AH_TEMPLATE(HAVE___FUNC__, [Define to 1 if the compiler supports the C99 __func__ variable.])
+AH_TEMPLATE(HAVE___INTERPOSE, [Define to 1 if you have dyld with __interpose attribute support.])
+AH_TEMPLATE(SUDO_KRB5_INSTANCE, [An instance string to append to the username (separated by a slash) for Kerberos V authentication.])
+AH_TEMPLATE(RTLD_PRELOAD_VAR, [The environment variable that controls preloading of dynamic objects.])
+AH_TEMPLATE(RTLD_PRELOAD_ENABLE_VAR, [An extra environment variable that is required to enable preloading (if any).])
+AH_TEMPLATE(RTLD_PRELOAD_DELIM, [The delimiter to use when defining multiple preloaded objects.])
+AH_TEMPLATE(RTLD_PRELOAD_DEFAULT, [The default value of preloaded objects (if any).])
+AH_TEMPLATE(HAVE_DSO_VISIBILITY, [Define to 1 if the compiler supports the __visibility__ attribute.])
+AH_TEMPLATE(HAVE_SYS_SIGABBREV, [Define to 1 if your libc has the `sys_sigabbrev' symbol.])
+AH_TEMPLATE(HAVE_NSS_SEARCH, [Define to 1 if you have the `nss_search' function.])
+AH_TEMPLATE(HAVE__NSS_INITF_GROUP, [Define to 1 if you have the `_nss_initf_group' function.])
+AH_TEMPLATE(HAVE___NSS_INITF_GROUP, [Define to 1 if you have the `__nss_initf_group' function.])
+AH_TEMPLATE(HAVE__NSS_XBYY_BUF_ALLOC, [Define to 1 if you have the `_nss_XbyY_buf_alloc' function.])
+AH_TEMPLATE(HAVE___NSS_XBYY_BUF_ALLOC, [Define to 1 if you have the `__nss_XbyY_buf_alloc' function.])
+AH_TEMPLATE(NEED_RESOLV_H, [Define to 1 if resolv.h must be included to get the `inet_ntop' or `inet_pton' function prototypes.])
+AH_TEMPLATE(HAVE_STRNLEN, [Define to 1 if you have the `strnlen' function.])
+AH_TEMPLATE(PAM_SUN_CODEBASE, [Define to 1 if your system uses a Solaris-derived PAM and not Linux-PAM or OpenPAM.])
+AH_TEMPLATE(HAVE_KINFO_PROC_44BSD, [Define to 1 if your system has a 4.4BSD-style kinfo_proc struct.])
+AH_TEMPLATE(HAVE_KINFO_PROC_FREEBSD, [Define to 1 if your system has a FreeBSD-style kinfo_proc struct.])
+AH_TEMPLATE(HAVE_KINFO_PROC2_NETBSD, [Define to 1 if your system has a NetBSD-style kinfo_proc2 struct.])
+AH_TEMPLATE(HAVE_KINFO_PROC_OPENBSD, [Define to 1 if your system has an OpenBSD-style kinfo_proc struct.])
+AH_TEMPLATE(HAVE_OPENSSL, [Define to 1 if you are using OpenSSL's sha2 functions.])
+AH_TEMPLATE(HAVE_GCRYPT, [Define to 1 if you are using gcrypt's sha2 functions.])
+dnl
+dnl Bits to copy verbatim into config.h.in
+dnl
+AH_TOP([#ifndef SUDO_CONFIG_H
+#define SUDO_CONFIG_H])
+
+AH_BOTTOM([/* BSD compatibility on some SVR4 systems. */
+#ifdef __svr4__
+# define BSD_COMP
+#endif
+
+/* Enable BSD extensions on systems that have them. */
+#ifndef _BSD_SOURCE
+# undef _BSD_SOURCE
+#endif
+
+/* Enable BSD types on IRIX. */
+#ifndef _BSD_TYPES
+# undef _BSD_TYPES
+#endif
+
+/* Enable Linux-compatible extensions on AIX. */
+#ifndef _LINUX_SOURCE_COMPAT
+# undef _LINUX_SOURCE_COMPAT
+#endif
+
+/* Enable prototypes in GCC fixed includes on older systems. */
+#ifndef __USE_FIXED_PROTOTYPES__
+# undef __USE_FIXED_PROTOTYPES__
+#endif
+
+/* Enable XPG4v2 extensions to POSIX, needed for MSG_WAITALL on older HP-UX. */
+#ifndef _XOPEN_SOURCE_EXTENDED
+# undef _XOPEN_SOURCE_EXTENDED
+#endif
+
+/* Enable reentrant versions of the standard C API (obsolete). */
+#ifndef _REENTRANT
+# undef _REENTRANT
+#endif
+
+/* Enable "safer" versions of the standard C API (ISO C11). */
+#ifndef __STDC_WANT_LIB_EXT1__
+# undef __STDC_WANT_LIB_EXT1__
+#endif
+
+/* Prevent static analyzers from genering bogus memory leak warnings. */
+#if defined(__COVERITY__) && !defined(NO_LEAKS)
+# define NO_LEAKS
+#endif
+
+#endif /* SUDO_CONFIG_H */])
diff --git a/doc/CONTRIBUTORS b/doc/CONTRIBUTORS
new file mode 100644
index 0000000..487322b
--- /dev/null
+++ b/doc/CONTRIBUTORS
@@ -0,0 +1,230 @@
+The following list of people, sorted by last name, have contributed
+code or patches to this implementation of sudo since I began
+maintaining it in 1993. This list is known to be incomplete--if
+you believe you should be listed, please send a note to sudo@sudo.ws.
+
+ Ackeret, Matt
+ Adler, Mark
+ Allbery, Russ
+ Anderson, Jamie
+ Andrew, Nick
+ Andric, Dimitry
+ Barron, Danny
+ Bates, Tom
+ Behan, Zdeněk
+ Bellis, Ray
+ Benali, Elias
+ Beverly, Jamie
+ Boardman, Spider
+ Bostley, P.J.
+ Bowes, Keith
+ Boyce, Keith Garry
+ Brantley, Michael
+ Braun, Rob
+ Březina, Pavel
+ Brooks, Piete
+ Brown, Jerry
+ Burr, Michael E
+ Burton, Ross
+ Bussjaeger, Andreas
+ Calvin, Gary
+ Campbell, Aaron
+ Chazelas, Stephane
+ Cheloha, Scott
+ Čížek, Vítězslav
+ Coleman, Chris
+ Corzine, Deven T.
+ Cusack, Frank
+ Dai, Wei
+ Dill, David
+ Earickson, Jeff
+ Eckhardt, Drew
+ Edgington, Ben
+ Esipovich, Marc
+ Espie, Marc
+ Faigon, Ariel
+ Farrell, Brian
+ Fobes, Steve
+ Frysinger, Mike
+ G., Daniel Richard
+ Gailly, Jean-loup
+ Gelman, Stephen
+ Gerraty, Simon J.
+ Graber, Stephane
+ Guillory, B.
+ Hayman, Randy M.
+ Henke, Joachim
+ Hideaki, Yoshifuji
+ Hieb, Dave
+ Holloway, Nick
+ Hoover, Adam
+ Hunter, Michael T.
+ Hutchings, Ben
+ Irrgang, Eric
+ Jackson, Brian
+ Jackson, John R.
+ Jackson, Richard L., Jr.
+ Janssen, Mark
+ Jepeway, Chris
+ Jorge, Joel Peláe
+ Jover, Guillem
+ Juhani, Timo
+ Kikuchi, Ayamura
+ Kadow, Kevin
+ Kasal, Stepan
+ Kienenberger, Mike
+ King, Dale
+ King, Michael
+ Klyachkin, Andrey
+ Knoble, Jim
+ Knox, Tim
+ Komarnitsky, Alek O.
+ Kondrashov, Nikolai
+ Kopeček, Daniel
+ Kranenburg, Paul
+ Krause, David
+ Lakin, Eric
+ Larsen, Case
+ Levin, Dmitry V.
+ Libby, Kendall
+ Lobbes, Phillip E.
+ McIntyre, Jason
+ MacKenzie, David J.
+ McLaughlin, Tom
+ Makey, Jeff
+ Marchionna, Michael D.
+ Markham, Paul
+ Martinian, Emin
+ Meskes, Michael
+ Michael, David
+ Miller, Todd C.
+ Minier, Loïc
+ Moffat, Darren
+ Moldung, Jan Thomas
+ Morris, Charles
+ Mueller, Andreas
+ Müller, Dworkin
+ Nieusma, Jeff
+ Nikitser, Peter A.
+ Nussel, Ludwig
+ Ouellet, Jean-Philippe
+ Paquet, Eric
+ Paradis, Chantal
+ Pasteleurs, Frederic
+ Percival, Ted
+ Perera, Andres
+ Peron, Christian S.J.
+ Peschel, Aaron
+ Peslyak, Alexander
+ Peterson, Toby
+ Pettenò, Diego Elio
+ Pickett, Joel
+ Plotnick, Alex
+ de Raadt, Theo
+ Rasch, Gudleik
+ Reid, Steve
+ Richards, Matt
+ Rossum, Guido van
+ Rouillard, John P.
+ Rowe, William A., Jr.
+ Roy, Alain
+ Ruusamäe, Elan
+ Ryabinkin, Eygene
+ Sato, Yuichi
+ Sánchez, Wilfredo
+ Sanders, Miguel
+ Sasaki, Kan
+ Saucier, Jean-Francois
+ Schoenfeld, Patrick
+ Schuring, Arno
+ Schwarze, Ingo
+ Scott, Dougal
+ Sieger, Nick
+ Simon, Thor Lancelot
+ Slemko, Marc
+ Smith, Andy
+ Sobrado, Igor
+ Soulen, Steven
+ Spangler, Aaron
+ Spradling, Cloyce D.
+ Stier, Matthew
+ Stoeckmann, Tobias
+ Street, Russell
+ Stritzky, Tilo
+ Stroucken, Michael
+ Tarrall, Robert
+ Thomas, Matthew
+ Todd, Giles
+ Toft, Martin
+ Torek, Chris
+ Tucker, Darren
+ Uhl, Robert
+ Uzel, Petr
+ Valery, Reznic
+ Van Dinter, Theo
+ Venckus, Martynas
+ de Vries, Maarten
+ Wagner, Klaus
+ Walsh, Dan
+ Warburton, John
+ Webb, Kirk
+ Wetzel, Timm
+ Wieringen, Marco van
+ Wilk, Jakub
+ Winiger, Gary
+ Wood, David
+ Zacarias, Gustavo
+ Zolnowsky, John
+
+The following people have worked to translate sudo into
+other languages as part of the Translation Project, see
+https://translationproject.org for more details.
+
+ Albuquerque, Pedro
+ Blättermann, Mario
+ Bogusz, Jakub
+ Buo-ren, Lin
+ Casagrande, Milo
+ Castro, Felipe
+ Cho, Seong-ho
+ Chornoivan, Yuri
+ Diéguez, Francisco
+ Fontenelle, Rafael
+ García-Fontes, Walter
+ Gezer, Volkan
+ Hamasaki, Takeshi
+ Hamming, Peter
+ Hansen, Joe
+ Hantrais, Frédéric
+ Hein, Jochen
+ Hufthammer, Karl Ove
+ Jerovšek, Damir
+ Karvonen, Jorma
+ Kazik, Dušan
+ Kelemen, Gábor
+ Keçeci, Mehmet
+ Košir, Klemen
+ Kozlov, Yuri
+ Kramer, Jakob
+ Krznar, Tomislav
+ Marchal, Frédéric
+ Margevičius, Algimantas
+ Maryanov, Pavel
+ Nikolić, Miroslav
+ Nylander, Daniel
+ Písař, Petr
+ Puente, Enol
+ Putanec, Božidar
+ Quân, Trần Ngọc
+ Rasmussen, Sebastian
+ Regueiro, Leandro
+ Sarıer, Özgür
+ Sendón, Abel
+ Sikrom, Åka
+ Spingos, Dimitris
+ Taniguchi, Yasuaki
+ Tomat, Fábio
+ Úr, Balázs
+ Uranga, Mikel Olasagasti
+ Vorotnikov, Artem
+ Wang, Wylmer
diff --git a/doc/HISTORY b/doc/HISTORY
new file mode 100644
index 0000000..0ad9512
--- /dev/null
+++ b/doc/HISTORY
@@ -0,0 +1,76 @@
+A Brief History of Sudo:
+
+The Early Years
+
+Sudo was first conceived and implemented by Bob Coggeshall and Cliff Spencer
+around 1980 at the Department of Computer Science at SUNY/Buffalo. It ran on
+a VAX-11/750 running 4.1BSD. An updated version, credited to Phil Betchel,
+Cliff Spencer, Gretchen Phillips, John LoVerso and Don Gworek, was posted to
+the net.sources Usenet newsgroup in December of 1985.
+
+Sudo at CU-Boulder
+
+In the Summer of 1986, Garth Snyder released an enhanced version of sudo.
+For the next 5 years, sudo was fed and watered by a handful of folks at
+CU-Boulder, including Bob Coggeshall, Bob Manchek, and Trent Hein.
+
+Root Group Sudo
+
+In 1991, Dave Hieb and Jeff Nieusma wrote a new version of sudo with an
+enhanced sudoers format under contract to a consulting firm called "The Root
+Group". This version was later released under the GNU public license.
+
+CU Sudo
+
+In 1994, after maintaining sudo informally within CU-Boulder for some time,
+Todd C. Miller made a public release of "CU sudo" (version 1.3) with bug
+fixes and support for more operating systems. The "CU" was added to
+differentiate it from the "official" version from "The Root Group".
+
+In 1995, a new parser for the sudoers file was contributed by Chris Jepeway.
+The new parser was a proper grammar (unlike the old one) and could work with
+both sudo and visudo (previously they had slightly different parsers).
+
+In 1996, Todd, who had been maintaining sudo for several years in his spare
+time, moved distribution of sudo from a CU-Boulder ftp site to his domain,
+courtesan.com.
+
+Just Plain Sudo
+
+In 1999, the "CU" prefix was dropped from the name since there had been no
+formal release of sudo from "The Root Group" since 1991 (the original
+authors now work elsewhere). As of version 1.6, Sudo no longer contains any
+of the original "Root Group" code and is available under an ISC-style
+license.
+
+In 2001, the sudo web site, ftp site and mailing lists were moved from
+courtesan.com to the sudo.ws domain (sudo.org was already taken).
+
+LDAP Integration
+
+In 2003, Nationwide Mutual Insurance Company contributed code written by
+Aaron Spangler to store the sudoers data in LDAP. These changes were
+incorporated into Sudo 1.6.8.
+
+New Parser
+
+In 2005, Todd rewrote the sudoers parser to better support the features that
+had been added in the past ten years. This new parser removes some
+limitations of the previous one, removes ordering constraints and adds
+support for including multiple sudoers files.
+
+Quest Sponsorship
+
+In 2010, Quest Software began sponsoring Sudo development by hiring
+Todd to work on Sudo as part of his full-time job. This enabled
+the addition of I/O logging, the plugin interface, additional
+regression tests, support for binary packages and more regular
+releases.
+
+Present Day
+
+Sudo, in its current form, is maintained by:
+
+ Todd C. Miller <Todd.Miller@sudo.ws>
+
+Todd continues to enhance sudo and fix bugs.
diff --git a/doc/LICENSE b/doc/LICENSE
new file mode 100644
index 0000000..46dd8f2
--- /dev/null
+++ b/doc/LICENSE
@@ -0,0 +1,236 @@
+Sudo is distributed under the following license:
+
+ Copyright (c) 1994-1996, 1998-2019
+ Todd C. Miller <Todd.Miller@sudo.ws>
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ Sponsored in part by the Defense Advanced Research Projects
+ Agency (DARPA) and Air Force Research Laboratory, Air Force
+ Materiel Command, USAF, under agreement number F39502-99-1-0512.
+
+The file redblack.c bears the following license:
+
+ Copyright (c) 2001 Emin Martinian
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that neither the name of Emin
+ Martinian nor the names of any contributors are be used to endorse or
+ promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The file reallocarray.c bears the following license:
+
+ Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+The files getcwd.c, glob.c, glob.h, snprintf.c and sudo_queue.h bear the
+following license:
+
+ Copyright (c) 1989, 1990, 1991, 1993
+ The Regents of the University of California. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+The file fnmatch.c bears the following license:
+
+ Copyright (c) 2011, VMware, Inc.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the VMware, Inc. nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The file getopt_long.c bears the following license:
+
+ Copyright (c) 2000 The NetBSD Foundation, Inc.
+ All rights reserved.
+
+ This code is derived from software contributed to The NetBSD Foundation
+ by Dieter Baron and Thomas Klausner.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+The file inet_pton.c bears the following license:
+
+ Copyright (c) 1996 by Internet Software Consortium.
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ SOFTWARE.
+
+The file arc4random.c bears the following license:
+
+ Copyright (c) 1996, David Mazieres <dm@uun.org>
+ Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+The file arc4random_uniform.c bears the following license:
+
+ Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+The file getentropy.c bears the following license:
+
+ Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
+ Copyright (c) 2014 Bob Beck <beck@obtuse.com>
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+The embedded copy of zlib bears the following license:
+
+ Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
diff --git a/doc/Makefile.in b/doc/Makefile.in
new file mode 100644
index 0000000..e8d2605
--- /dev/null
+++ b/doc/Makefile.in
@@ -0,0 +1,395 @@
+#
+# Copyright (c) 2010-2015, 2017-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# @configure_input@
+#
+
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+docdir = @docdir@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Tools to use
+SED = @SED@
+IGOR = igor
+MANDOC = @MANDOCPROG@
+MANCOMPRESS = @MANCOMPRESS@
+MANCOMPRESSEXT = @MANCOMPRESSEXT@
+TR = @TRPROG@
+
+# Our install program supports extra flags...
+INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
+INSTALL_OWNER = -o $(install_uid) -g $(install_gid)
+
+# Where to install things...
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+
+# Directory to copy man pages from
+mansrcdir = @mansrcdir@
+
+# Directory in which to install the man page
+mantype = @MANTYPE@
+mansectsu = @mansectsu@
+mansectform = @mansectform@
+mandirexe = $(mandir)/@MANDIRTYPE@1
+mandirsu = $(mandir)/@MANDIRTYPE@$(mansectsu)
+mandirform = $(mandir)/@MANDIRTYPE@$(mansectform)
+
+# User and group ids the installed files should be "owned" by
+install_uid = 0
+install_gid = 0
+
+# Set to non-empty for development mode
+DEVEL = @DEVEL@
+
+#### End of system configuration section. ####
+
+SHELL = @SHELL@
+
+DOCS = $(mansrcdir)/cvtsudoers.$(mantype) $(mansrcdir)/sudo.$(mantype) \
+ $(mansrcdir)/sudo.conf.$(mantype) $(mansrcdir)/sudo_plugin.$(mantype) \
+ $(mansrcdir)/sudoers.$(mantype) $(mansrcdir)/sudoers.ldap.$(mantype) \
+ $(mansrcdir)/sudoers_timestamp.$(mantype) \
+ $(mansrcdir)/sudoreplay.$(mantype) $(mansrcdir)/visudo.$(mantype)
+
+DEVDOCS = $(srcdir)/cvtsudoers.man.in $(srcdir)/cvtsudoers.cat \
+ $(srcdir)/sudo.conf.man.in $(srcdir)/sudo.conf.cat \
+ $(srcdir)/sudo.man.in $(srcdir)/sudo.cat \
+ $(srcdir)/sudo_plugin.man.in $(srcdir)/sudo_plugin.cat \
+ $(srcdir)/sudoers.ldap.man.in $(srcdir)/sudoers.ldap.cat \
+ $(srcdir)/sudoers.man.in $(srcdir)/sudoers.cat \
+ $(srcdir)/sudoers_timestamp.man.in $(srcdir)/sudoers_timestamp.cat \
+ $(srcdir)/sudoreplay.man.in $(srcdir)/sudoreplay.cat \
+ $(srcdir)/visudo.man.in $(srcdir)/visudo.cat
+
+OTHER_DOCS = $(top_srcdir)/ChangeLog $(top_srcdir)/README \
+ $(top_srcdir)/NEWS $(srcdir)/HISTORY $(srcdir)/CONTRIBUTORS \
+ $(srcdir)/LICENSE $(srcdir)/TROUBLESHOOTING $(srcdir)/UPGRADE
+
+OTHER_DOCS_LDAP = $(top_srcdir)/README.LDAP $(srcdir)/schema.*
+
+VERSION = @PACKAGE_VERSION@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+
+all: $(DEVDOCS) $(DOCS)
+
+igor: all
+ @if [ "$(mantype)" != "mdoc" ]; then \
+ echo "make igor only supported for mdoc manuals" 1>&2; \
+ exit 1; \
+ else \
+ rval=0; \
+ for m in $(DOCS); do \
+ echo $(IGOR) -D $$m; \
+ $(IGOR) -D $$m || rval=`expr $$rval + $$?`; \
+ done; \
+ exit $$rval; \
+ fi
+
+lint: all
+ @if [ "$(mantype)" != "mdoc" ]; then \
+ echo "make lint only supported for mdoc manuals" 1>&2; \
+ exit 1; \
+ else \
+ rval=0; \
+ for m in $(DOCS); do \
+ echo $(MANDOC) -Tlint -Wstyle $$m; \
+ $(MANDOC) -Tlint -Wstyle $$m || rval=`expr $$rval + $$?`; \
+ done; \
+ exit $$rval; \
+ fi
+
+Makefile: $(srcdir)/Makefile.in
+ cd $(top_builddir) && ./config.status --file doc/Makefile
+
+.SUFFIXES: .man
+
+varsub: $(top_srcdir)/configure.ac
+ @if [ -n "$(DEVEL)" ]; then \
+ printf 's#@%s@#1#\ns#@%s@#1#\ns#@%s@#1#\ns#@%s@#1#\ns#@%s@#/etc#g\ns#@%s@#/usr/local#g\ns#@%s@#5#g\ns#@%s@#8#g\ns#@%s@#%s#\n' SEMAN BAMAN LCMAN PSMAN sysconfdir prefix mansectform mansectsu PACKAGE_VERSION $(VERSION) > $@; \
+ $(SED) -n '/Begin initial values for man page substitution/,/End initial values for man page substitution/{;p;}' $(top_srcdir)/configure.ac | $(SED) -e '/^#/d' -e 's/^/s#@/' -e 's/=[\\"]*/@#/' -e 's/[\\"]*$$/#g/' >> $@; \
+ fi
+
+$(srcdir)/sudo.man.in: $(srcdir)/sudo.mdoc.in $(srcdir)/sudo.man.in.sed
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \
+ mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \
+ $(SED) -e 's/^\(\.nr [A-Z][A-Z]\) .[A-Z][A-Z]MAN./\1 1/' -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudo.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDO" \)"8"\(.*\)/\1"'$$mansectsu'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" -f $(srcdir)/sudo.man.in.sed > $@; \
+ fi
+
+fixman.sed: $(srcdir)/fixman.sh
+ $(SHELL) $(srcdir)/fixman.sh $@
+
+$(mansrcdir)/sudo.man: $(top_builddir)/config.status $(srcdir)/sudo.man.in fixman.sed
+ (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudo.man.in | $(SED) -f fixman.sed > $@
+
+$(mansrcdir)/sudo.mdoc: $(top_builddir)/config.status $(srcdir)/sudo.mdoc.in
+ cd $(top_builddir) && $(SHELL) config.status --file=doc/$@
+
+$(srcdir)/sudo.cat: varsub $(srcdir)/sudo.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ $(SED) -f varsub $(srcdir)/sudo.mdoc.in | $(MANDOC) -Tascii -mdoc | $(SED) -e 's/(5)/(4)/g' -e 's/(8)/(1m)/g' > $@; \
+ fi
+
+$(srcdir)/visudo.man.in: $(srcdir)/visudo.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \
+ mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \
+ $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/visudo.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "VISUDO" \)"8"\(.*\)/\1"'$$mansectsu'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \
+ fi
+
+$(mansrcdir)/visudo.man: $(top_builddir)/config.status $(srcdir)/visudo.man.in fixman.sed
+ (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/visudo.man.in | $(SED) -f fixman.sed > $@
+
+$(mansrcdir)/visudo.mdoc: $(top_builddir)/config.status $(srcdir)/visudo.mdoc.in
+ cd $(top_builddir) && $(SHELL) config.status --file=doc/$@
+
+$(srcdir)/visudo.cat: varsub $(srcdir)/visudo.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ $(SED) -f varsub $(srcdir)/visudo.mdoc.in | $(MANDOC) -Tascii -mdoc | $(SED) -e 's/(5)/(4)/g' -e 's/(8)/(1m)/g' > $@; \
+ fi
+
+$(srcdir)/sudo.conf.man.in: $(srcdir)/sudo.conf.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \
+ mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \
+ $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudo.conf.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDO.CONF" \)"5"\(.*\)/\1"'$$mansectform'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \
+ fi
+
+$(mansrcdir)/sudo.conf.man: $(top_builddir)/config.status $(srcdir)/sudo.conf.man.in fixman.sed
+ (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudo.conf.man.in | $(SED) -f fixman.sed > $@
+
+$(mansrcdir)/sudo.conf.mdoc: $(top_builddir)/config.status $(srcdir)/sudo.conf.mdoc.in
+ cd $(top_builddir) && $(SHELL) config.status --file=doc/$@
+
+$(srcdir)/sudo.conf.cat: varsub $(srcdir)/sudo.conf.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ $(SED) -f varsub $(srcdir)/sudo.conf.mdoc.in | $(MANDOC) -Tascii -mdoc | $(SED) -e 's/(5)/(4)/g' -e 's/(8)/(1m)/g' > $@; \
+ fi
+
+$(srcdir)/sudoers.man.in: $(srcdir)/sudoers.mdoc.in $(srcdir)/sudoers.man.in.sed
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \
+ mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \
+ $(SED) -e 's/^\(\.nr [A-Z][A-Z]\) .[A-Z][A-Z]MAN./\1 1/' -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudoers.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDOERS" \)"5"\(.*\)/\1"'$$mansectform'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" -f $(srcdir)/sudoers.man.in.sed> $@; \
+ fi
+
+$(mansrcdir)/sudoers.man: $(top_builddir)/config.status $(srcdir)/sudoers.man.in fixman.sed
+ (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudoers.man.in | $(SED) -f fixman.sed > $@
+
+$(mansrcdir)/sudoers.mdoc: $(top_builddir)/config.status $(srcdir)/sudoers.mdoc.in $(srcdir)/fixmdoc.sed
+ (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudoers.mdoc.in | $(SED) -f $(srcdir)/fixmdoc.sed > $@
+
+$(srcdir)/sudoers.cat: varsub $(srcdir)/sudoers.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ $(SED) -f varsub $(srcdir)/sudoers.mdoc.in | $(MANDOC) -Tascii -mdoc | $(SED) -e 's/(5)/(4)/g' -e 's/(8)/(1m)/g' > $@; \
+ fi
+
+$(srcdir)/sudoers.ldap.man.in: $(srcdir)/sudoers.ldap.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \
+ mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \
+ $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudoers.ldap.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDOERS.LDAP" \)"5"\(.*\)/\1"'$$mansectform'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \
+ fi
+
+$(mansrcdir)/sudoers.ldap.man: $(top_builddir)/config.status $(srcdir)/sudoers.ldap.man.in fixman.sed
+ (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudoers.ldap.man.in | $(SED) -f fixman.sed > $@
+
+$(mansrcdir)/sudoers.ldap.mdoc: $(top_builddir)/config.status $(srcdir)/sudoers.ldap.mdoc.in
+ cd $(top_builddir) && $(SHELL) config.status --file=doc/$@
+
+$(srcdir)/sudoers.ldap.cat: varsub $(srcdir)/sudoers.ldap.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ $(SED) -f varsub $(srcdir)/sudoers.ldap.mdoc.in | $(MANDOC) -Tascii -mdoc | $(SED) -e 's/(5)/(4)/g' -e 's/(8)/(1m)/g' > $@; \
+ fi
+
+$(srcdir)/sudoers_timestamp.man.in: $(srcdir)/sudoers_timestamp.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \
+ mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \
+ $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudoers_timestamp.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDOERS_TIMESTAMP" \)"5"\(.*\)/\1"'$$mansectform'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \
+ fi
+
+$(mansrcdir)/sudoers_timestamp.man: $(top_builddir)/config.status $(srcdir)/sudoers_timestamp.man.in fixman.sed
+ (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudoers_timestamp.man.in | $(SED) -f fixman.sed > $@
+
+$(mansrcdir)/sudoers_timestamp.mdoc: $(top_builddir)/config.status $(srcdir)/sudoers_timestamp.mdoc.in
+ cd $(top_builddir) && $(SHELL) config.status --file=doc/$@
+
+$(srcdir)/sudoers_timestamp.cat: varsub $(srcdir)/sudoers_timestamp.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ $(SED) -f varsub $(srcdir)/sudoers_timestamp.mdoc.in | $(MANDOC) -Tascii -mdoc | $(SED) -e 's/(5)/(4)/g' -e 's/(8)/(1m)/g' > $@; \
+ fi
+
+$(srcdir)/cvtsudoers.man.in: $(srcdir)/cvtsudoers.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \
+ mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \
+ $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/cvtsudoers.mdoc.in | $(MANDOC) -Tman | $(SED) -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \
+ fi
+
+$(mansrcdir)/cvtsudoers.man: $(top_builddir)/config.status $(srcdir)/cvtsudoers.man.in fixman.sed
+ (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/cvtsudoers.man.in | $(SED) -f fixman.sed > $@
+
+$(mansrcdir)/cvtsudoers.mdoc: $(top_builddir)/config.status $(srcdir)/cvtsudoers.mdoc.in
+ cd $(top_builddir) && $(SHELL) config.status --file=doc/$@
+
+$(srcdir)/cvtsudoers.cat: varsub $(srcdir)/cvtsudoers.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ $(SED) -f varsub $(srcdir)/cvtsudoers.mdoc.in | $(MANDOC) -Tascii -mdoc | $(SED) -e 's/(5)/(4)/g' -e 's/(8)/(1m)/g' > $@; \
+ fi
+
+$(srcdir)/sudoreplay.man.in: $(srcdir)/sudoreplay.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \
+ mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \
+ $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudoreplay.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDOREPLAY" \)"8"\(.*\)/\1"'$$mansectsu'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \
+ fi
+
+$(mansrcdir)/sudoreplay.man: $(top_builddir)/config.status $(srcdir)/sudoreplay.man.in fixman.sed
+ (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudoreplay.man.in | $(SED) -f fixman.sed > $@
+
+$(mansrcdir)/sudoreplay.mdoc: $(top_builddir)/config.status $(srcdir)/sudoreplay.mdoc.in
+ cd $(top_builddir) && $(SHELL) config.status --file=doc/$@
+
+$(srcdir)/sudoreplay.cat: varsub $(srcdir)/sudoreplay.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ $(SED) -f varsub $(srcdir)/sudoreplay.mdoc.in | $(MANDOC) -Tascii -mdoc | $(SED) -e 's/(5)/(4)/g' -e 's/(8)/(1m)/g' > $@; \
+ fi
+
+$(srcdir)/sudo_plugin.man.in: $(srcdir)/sudo_plugin.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \
+ mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \
+ $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudo_plugin.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDO_PLUGIN" \)"8"\(.*\)/\1"'$$mansectsu'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \
+ fi
+
+$(mansrcdir)/sudo_plugin.man: $(top_builddir)/config.status $(srcdir)/sudo_plugin.man.in fixman.sed
+ (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudo_plugin.man.in | $(SED) -f fixman.sed > $@
+
+$(mansrcdir)/sudo_plugin.mdoc: $(top_builddir)/config.status $(srcdir)/sudo_plugin.mdoc.in
+ cd $(top_builddir) && $(SHELL) config.status --file=doc/$@
+
+$(srcdir)/sudo_plugin.cat: varsub $(srcdir)/sudo_plugin.mdoc.in
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "Generating $@"; \
+ $(SED) -f varsub $(srcdir)/sudo_plugin.mdoc.in | $(MANDOC) -Tascii -mdoc | $(SED) -e 's/(5)/(4)/g' -e 's/(8)/(1m)/g' > $@; \
+ fi
+
+pre-install:
+
+install: install-doc
+
+install-dirs:
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(docdir) \
+ $(DESTDIR)$(mandirexe) $(DESTDIR)$(mandirform) $(DESTDIR)$(mandirsu)
+
+install-binaries:
+
+install-includes:
+
+install-doc: install-dirs
+ for f in $(OTHER_DOCS); do $(INSTALL) $(INSTALL_OWNER) -m 0644 $$f $(DESTDIR)$(docdir); done
+ @LDAP@for f in $(OTHER_DOCS_LDAP); do $(INSTALL) $(INSTALL_OWNER) -m 0644 $$f $(DESTDIR)$(docdir); done
+ $(INSTALL) $(INSTALL_OWNER) -m 0644 $(mansrcdir)/cvtsudoers.$(mantype) $(DESTDIR)$(mandirexe)/cvtsudoers.1
+ $(INSTALL) $(INSTALL_OWNER) -m 0644 $(mansrcdir)/sudo.$(mantype) $(DESTDIR)$(mandirsu)/sudo.$(mansectsu)
+ $(INSTALL) $(INSTALL_OWNER) -m 0644 $(mansrcdir)/sudo_plugin.$(mantype) $(DESTDIR)$(mandirsu)/sudo_plugin.$(mansectsu)
+ $(INSTALL) $(INSTALL_OWNER) -m 0644 $(mansrcdir)/sudoreplay.$(mantype) $(DESTDIR)$(mandirsu)/sudoreplay.$(mansectsu)
+ $(INSTALL) $(INSTALL_OWNER) -m 0644 $(mansrcdir)/visudo.$(mantype) $(DESTDIR)$(mandirsu)/visudo.$(mansectsu)
+ $(INSTALL) $(INSTALL_OWNER) -m 0644 $(mansrcdir)/sudo.conf.$(mantype) $(DESTDIR)$(mandirform)/sudo.conf.$(mansectform)
+ $(INSTALL) $(INSTALL_OWNER) -m 0644 $(mansrcdir)/sudoers.$(mantype) $(DESTDIR)$(mandirform)/sudoers.$(mansectform)
+ $(INSTALL) $(INSTALL_OWNER) -m 0644 $(mansrcdir)/sudoers_timestamp.$(mantype) $(DESTDIR)$(mandirform)/sudoers_timestamp.$(mansectform)
+ @LDAP@$(INSTALL) $(INSTALL_OWNER) -m 0644 $(mansrcdir)/sudoers.ldap.$(mantype) $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform)
+ @if test -n "$(MANCOMPRESS)"; then \
+ for f in $(mandirexe)/cvtsudoers.1 $(mandirsu)/sudo.$(mansectsu) $(mandirsu)/sudo_plugin.$(mansectsu) $(mandirsu)/sudoreplay.$(mansectsu) $(mandirsu)/visudo.$(mansectsu) $(mandirform)/sudo.conf.$(mansectform) $(mandirform)/sudoers.$(mansectform) $(mandirform)/sudoers_timestamp.$(mansectform) $(mandirform)/sudoers.ldap.$(mansectform); do \
+ if test -f $(DESTDIR)$$f; then \
+ echo $(MANCOMPRESS) -f $(DESTDIR)$$f; \
+ $(MANCOMPRESS) -f $(DESTDIR)$$f; \
+ fi; \
+ done; \
+ rm -f $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \
+ echo ln -s sudo.$(mansectsu)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \
+ ln -s sudo.$(mansectsu)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \
+ else \
+ rm -f $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \
+ echo ln -s sudo.$(mansectsu) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \
+ ln -s sudo.$(mansectsu) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \
+ fi
+
+install-plugin:
+
+uninstall:
+ -rm -rf $(DESTDIR)$(docdir)
+ -rm -f $(DESTDIR)$(mandirexe)/cvtsudoers.1 \
+ $(DESTDIR)$(mandirsu)/sudo.$(mansectsu) \
+ $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu) \
+ $(DESTDIR)$(mandirsu)/sudo_plugin.$(mansectsu) \
+ $(DESTDIR)$(mandirsu)/sudoreplay.$(mansectsu) \
+ $(DESTDIR)$(mandirsu)/visudo.$(mansectsu) \
+ $(DESTDIR)$(mandirform)/sudo.conf.$(mansectform) \
+ $(DESTDIR)$(mandirform)/sudoers.$(mansectform) \
+ $(DESTDIR)$(mandirform)/sudoers_timestamp.$(mansectform)
+ $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform)
+
+splint:
+
+cppcheck:
+
+pvs-log-files:
+
+pvs-studio:
+
+check:
+
+clean:
+ -rm -f varsub fixman.sed
+
+mostlyclean: clean
+
+distclean: clean
+ -rm -rf Makefile config.log *.man *.mdoc
+
+clobber: distclean
+
+realclean: distclean
+
+cleandir: distclean
diff --git a/doc/TROUBLESHOOTING b/doc/TROUBLESHOOTING
new file mode 100644
index 0000000..3bb6f14
--- /dev/null
+++ b/doc/TROUBLESHOOTING
@@ -0,0 +1,282 @@
+Troubleshooting tips and FAQ for Sudo
+=====================================
+
+Q) When I run configure, it says "C compiler cannot create executables".
+A) This usually means you either don't have a working compiler. This
+ could be due to the lack of a license or that some component of the
+ compiler suite could not be found. Check config.log for clues as
+ to why this is happening. On many systems, compiler components live
+ in /usr/ccs/bin which may not be in your PATH environment variable.
+
+Q) When I run configure, it says "sudo requires the 'ar' utility to build".
+A) As part of the build process, sudo creates a temporary library containing
+ objects that are shared amongst the different sudo executables.
+ On Unix systems, the "ar" utility is used to do this. This error
+ indicates that "ar" is missing on your system. On Solaris systems,
+ you may need to install the SUNWbtool package. On other systems
+ "ar" may be included in the GNU binutils package.
+
+Q) Sudo compiles and installs OK but when I try to run it I get:
+ /usr/local/bin/sudo must be owned by uid 0 and have the setuid bit set
+A) Sudo must be setuid root to do its work. Either /usr/local/bin/sudo
+ is not owned by uid 0 or the setuid bit is not set. This should have
+ been done for you by "make install" but you can fix it manually by
+ running the following as root:
+ # chown root /usr/local/bin/sudo; chmod 4755 /usr/local/bin/sudo
+
+Q) Sudo compiles and installs OK but when I try to run it I get:
+ effective uid is not 0, is /usr/local/bin/sudo on a file system with the
+ 'nosuid' option set or an NFS file system without root privileges?
+A) The owner and permissions on the sudo binary appear to be OK but when
+ sudo ran, the setuid bit did not have an effect. There are two common
+ causes for this. The first is that the file system the sudo binary
+ is located on is mounted with the 'nosuid' mount option, which disables
+ setuid binaries. The output of the "mount" command should tell you if
+ the file system is mounted with the 'nosuid' option. The other possible
+ cause is that sudo is installed on an NFS-mounted file system that is
+ exported without root privileges. By default, NFS file systems are
+ exported with uid 0 mapped to a non-privileged uid (usually -2). You
+ should be able to determine whether sudo is located on an NFS-mounted
+ filesystem by running "df `which sudo'".
+
+Q) Sudo never gives me a chance to enter a password using PAM, it just
+ says 'Sorry, try again.' three times and exits.
+A) You didn't setup PAM to work with sudo. On RedHat Linux or Fedora
+ Core this generally means installing the sample pam.conf file as
+ /etc/pam.d/sudo. See the example pam.conf file for hints on what
+ to use for other Linux systems.
+
+Q) Sudo says 'Account expired or PAM config lacks an "account"
+ section for sudo, contact your system administrator' and exits
+ but I know my account has not expired.
+A) Your PAM config lacks an "account" specification. On Linux this
+ usually means you are missing a line like:
+ account required pam_unix.so
+ in /etc/pam.d/sudo.
+
+Q) Sudo is setup to log via syslog(3) but I'm not getting any log
+ messages.
+A) Make sure you have an entry in your syslog.conf file to save
+ the sudo messages (see the example syslog.conf file). The default
+ log facility is authpriv (changeable via configure or in sudoers).
+ Don't forget to send a SIGHUP to your syslogd so that it re-reads
+ its conf file. Also, remember that syslogd does *not* create
+ log files, you need to create the file before syslogd will log
+ to it (ie: touch /var/log/sudo).
+ Note: the facility (e.g. "auth.debug") must be separated from the
+ destination (e.g. "/var/log/auth" or "@loghost") by
+ tabs, *not* spaces. This is a common error.
+
+Q) When sudo asks me for my password it never accepts what I enter even
+ though I know I entered my password correctly.
+A) If you are not using pam and your system uses shadow passwords,
+ it is possible that sudo didn't properly detect that shadow
+ passwords are in use. Take a look at the generated config.h
+ file and verify that the C function used for shadow password
+ look ups was detected. For instance, for SVR4-style shadow
+ passwords, HAVE_GETSPNAM should be defined (you can search for
+ the string "shadow passwords" in config.h with your editor).
+ Note that there is no define for 4.4BSD-based shadow passwords
+ since that just uses the standard getpw* routines.
+
+Q) Can sudo use the ssh agent for authentication instead of asking
+ for the user's Unix password?
+A) Not directly, but you can use a PAM module like pam_ssh_agent_auth
+ or pam_ssh for this purpose.
+
+Q) I don't want the sudoers file in /etc, how can I specify where it
+ should go?
+A) Use the --sysconfdir option to configure. Ie:
+ configure --sysconfdir=/dir/you/want/sudoers/in
+
+Q) Can I put the sudoers file in NIS/NIS+ or do I have to have a
+ copy on each machine?
+A) There is no support for making an NIS/NIS+ map/table out of
+ the sudoers file at this time. You can distribute the sudoers
+ file via rsync or rdist. It is also possible to NFS-mount the
+ sudoers file. If you use LDAP at your site you may be interested
+ in sudo's LDAP sudoers support, see the README.LDAP file and the
+ sudoers.ldap manual.
+
+Q) I don't run sendmail on my machine. Does this mean that I cannot
+ use sudo?
+A) No, you just need to disable mailing with a line like:
+ Defaults !mailerpath
+ in your sudoers file or run configure with the --without-sendmail
+ option.
+
+Q) When I run visudo it uses vi as the editor and I hate vi. How
+ can I make it use another editor?
+A) You can specify the editor to use in visudo in the sudoers file.
+ See the "editor" and "env_editor" entries in the sudoers manual.
+ The defaults can also be set at configure time using the
+ --with-editor and --with-env-editor configure options.
+
+Q) Sudo appears to be removing some variables from my environment, why?
+A) By default, sudo runs commands with new, minimal environment.
+ It is possible to control what environment variables are copied
+ from the invoking user's environment using the "env_keep" setting
+ in sudoers. Another, less secure, option is to disable the
+ "env_reset" setting to copy all variables from the invoking
+ user's environment that are not considered "dangerous". See the
+ "Command Environment" section of the sudoers manual for more
+ information.
+
+Q) How can I keep sudo from asking for a password?
+A) To specify this on a per-user (and per-command) basis, use the
+ 'NOPASSWD' tag right before the command list in sudoers. See
+ the sudoers man page and examples/sudoers for details. To disable
+ passwords completely, add !authenticate" to the Defaults line
+ in /etc/sudoers. You can also turn off authentication on a
+ per-user or per-host basis using a user or host-specific Defaults
+ entry in sudoers. To hard-code the global default, you can
+ configure with the --without-passwd option.
+
+Q) When I run configure, it dies with the following error:
+ "no acceptable cc found in $PATH".
+A) /usr/ucb/cc was the only C compiler that configure could find.
+ You need to tell configure the path to the "real" C compiler
+ via the --with-CC option. On Solaris, the path is probably
+ something like "/opt/SUNWspro/SC4.0/bin/cc". If you have gcc
+ that will also work.
+
+Q) When I run configure, it dies with the following error:
+ Fatal Error: config.cache exists from another platform!
+ Please remove it and re-run configure.
+A) configure caches the results of its tests in a file called
+ config.cache to make re-running configure speedy. However,
+ if you are building sudo for a different platform the results
+ in config.cache will be wrong so you need to remove config.cache.
+ You can do this by "rm config.cache" or "make realclean".
+ Note that "make realclean" will also remove any object files
+ and configure temp files that are laying around as well.
+
+Q) I built sudo on a Solaris 11 (or higher) machine but the resulting
+ binary doesn't work older Solaris versions. Why?
+A) Starting with Solaris 11, asprintf(3) is included in the standard
+ C library. To build a version of sudo on a Solaris 11 machine that
+ will run on an older Solaris release, edit config.h and comment out
+ the lines:
+ #define HAVE_ASPRINTF 1
+ #define HAVE_VASPRINTF 1
+ and run make.
+
+Q) When I run "visudo" it says "sudoers file busy, try again later."
+ and doesn't do anything.
+A) Someone else is currently editing the sudoers file with visudo.
+
+Q) When I try to use "cd" with sudo it says "cd: command not found".
+A) "cd" is a shell built-in command, you can't run it as a command
+ since a child process (sudo) cannot affect the current working
+ directory of the parent (your shell).
+
+Q) When I try to use "cd" with sudo the command completes without
+ errors but nothing happens.
+A) Even though "cd" is a shell built-in command, some operating systems
+ include a /usr/bin/cd command for some reason. A standalone
+ "cd" command is totally useless since a child process (cd) cannot
+ affect the current working directory of the parent (your shell).
+ Thus, "sudo cd /foo" will start a child process, change the
+ directory and immediately exit without doing anything useful.
+
+Q) When I run sudo it says I am not allowed to run the command as root
+ but I don't want to run it as root, I want to run it as another user.
+ My sudoers file entry looks like:
+ bob ALL=(oracle) ALL
+A) The default user sudo tries to run things as is always root, even if
+ the invoking user can only run commands as a single, specific user.
+ This may change in the future but at the present time you have to
+ work around this using the 'runas_default' option in sudoers.
+ For example:
+ Defaults:bob runas_default=oracle
+ would achieve the desired result for the preceding sudoers fragment.
+
+Q) When I try to run sudo via ssh, I get the error:
+ sudo: no tty present and no askpass program specified
+A) ssh does not allocate a tty by default when running a remote command.
+ Without a tty, sudo cannot disable echo when prompting for a password.
+ You can use ssh's "-t" option to force it to allocate a tty.
+ Alternately, if you do not mind your password being echoed to the
+ screen, you can use the "visiblepw" sudoers option to allow this.
+
+Q) When I try to use SSL-enabled LDAP with sudo I get an error:
+ unable to initialize SSL cert and key db: security library: bad database.
+ you must set TLS_CERT in /etc/ldap.conf to use SSL
+A) On systems that use a Mozilla-derived LDAP SDK there must be a
+ certificate database in place to use SSL-encrypted LDAP connections.
+ This file is usually /var/ldap/cert8.db or /etc/ldap/cert8.db.
+ The actual number after "cert" will vary, depending on the version
+ of the LDAP SDK that is being used. If you do not have a certificate
+ database you can either copy one from a mozilla-derived browser, such
+ as firefox, or create one using the "certutil" command. You can run
+ "certutil" as follows and press the <return> (or <enter>) key at the
+ password prompt:
+ # certutil -N -d /var/ldap
+ Enter a password which will be used to encrypt your keys.
+ The password should be at least 8 characters long,
+ and should contain at least one non-alphabetic character.
+
+ Enter new password: <return>
+ Re-enter password: <return>
+
+Q) On Solaris, when I run command via sudo it displays information
+ about the last login for every command. How can I fix this?
+A) This output comes from /usr/lib/security/pam_unix_session.so.1.
+ To suppress it, first create /etc/pam.d/sudo if it doesn't exist:
+ cp /etc/pam.d/other /etc/pam.d/sudo
+ Then add "nowarn" to the end of the pam_unix_session.so.1 line:
+ session required pam_unix_session.so.1 nowarm
+
+Q) On HP-UX, when I run command via sudo it displays information
+ about the last successful login and last authentication failure
+ for every command. How can I fix this?
+A) This output comes from /usr/lib/security/libpam_hpsec.so.1.
+ To suppress it, add a line like the following to /etc/pam.conf:
+ sudo session required libpam_hpsec.so.1 bypass_umask bypass_last_login
+
+Q) On HP-UX, the umask setting in sudoers has no effect.
+A) If your /etc/pam.conf file has the libpam_hpsec.so.1 session module
+ enabled, you may need to a add line like the following to pam.conf:
+ sudo session required libpam_hpsec.so.1 bypass_umask
+
+Q) When I run "sudo -i shell_alias" I get "command not found" even
+ though the alias is defined in my shell startup files.
+A) Commands run via "sudo -i" are executed by the shell in
+ non-interactive mode. The bash shell will ony parse aliases in
+ interactive mode unless the "expand_aliases" shell option is
+ set. If you add "shopt -s expand_aliases" to your .bash_profile
+ (or .profile if using that instead) the aliases should now be
+ available to "sudo -i".
+
+Q) When I run sudo on AIX I get the following error:
+ setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID): Operation not permitted.
+A) AIX's Enhanced RBAC is preventing sudo from running. To fix
+ this, add the following entry to /etc/security/privcmds (adjust
+ the path to sudo as needed) and run the setkst command as root:
+
+ /usr/local/bin/sudo:
+ accessauths = ALLOW_ALL
+ innateprivs = PV_DAC_GID,PV_DAC_R,PV_DAC_UID,PV_DAC_X,PV_FS_CHOWN,PV_PROC_PRIO,PV_NET_PORT,PV_NET_CNTL,PV_SU_UID
+ secflags = FSF_EPS
+
+Q) Sudo configures and builds without error but when I run it I get
+ a Segmentation fault.
+A) If you are on a Linux system, the first thing to try is to run
+ configure with the --disable-pie option, then "make clean" and
+ "make". If that fixes the problem then your operating system
+ does not properly support position independent executables.
+ Please send a message to sudo@sudo.ws with system details such
+ as the Linux distro, kernel version and CPU architecture.
+
+Q) When I run configure I get the following error:
+ dlopen present but libtool doesn't appear to support your platform.
+A) Libtool doesn't know how to support dynamic linking on the operating
+ system you are building for. If you are cross-compiling, you need to
+ specify the operating system, not just the CPU type. For example:
+ --host powerpc-unknown-linux
+ instead of just:
+ --host powerpc
+
+Q) How do you pronounce `sudo'?
+A) The official pronunciation is soo-doo (for su "do"). However, an
+ alternate pronunciation, a homophone of "pseudo", is also common.
diff --git a/doc/UPGRADE b/doc/UPGRADE
new file mode 100644
index 0000000..1b787c1
--- /dev/null
+++ b/doc/UPGRADE
@@ -0,0 +1,463 @@
+Notes on upgrading from an older release
+========================================
+
+o Upgrading from a version prior to 1.8.26:
+
+ Starting with version 1.8.26, sudo no long sets the USERNAME
+ environment variable when running commands. This is a non-standard
+ environment variable that was set on some older Linux systems.
+ Sudo still sets the LOGNAME, USER and, on AIX systems, LOGIN
+ environment variables.
+
+ Handling of the LOGNAME, USER (and on AIX, LOGIN) environment
+ variables has changed slightly in version 1.8.26. Sudo now
+ treats those variables as a single unit. This means that if
+ one variable is preserved or removed from the environment using
+ env_keep, env_check or env_delete, the others are too.
+
+o Upgrading from a version prior to 1.8.23:
+
+ In sudo 1.8.23 the "sudoers2ldif" script and the "visudo -x"
+ functionality has been superseded by the "cvtsudoers" utility.
+ The cvtsudoers utility is intended to be a drop-in replacement
+ for "sudoers2ldif". Because it uses the same parser as sudo
+ and visudo, cvtsudoers can perform a more accurate conversion
+ than sudoers2ldif could.
+
+ To convert a sudoers file to JSON, the format option must be
+ specified. For example, instead of:
+
+ visudo -f sudoers_file -x output_file
+
+ one would use:
+
+ cvtsudoers -f json -o output_file sudoers_file
+
+ Note that unlike "visudo -x", "cvtsudoers" reads from the
+ standard input by default. Also, the base DN may be specified
+ on the command line, if desired, using the -b option.
+
+o Upgrading from a version prior to 1.8.20:
+
+ Prior to version 1.8.20, when log_input, log_output or use_pty
+ were enabled, if any of the standard input, output or error
+ were not connected to a terminal, sudo would use a pipe. The
+ pipe allows sudo to interpose itself between the old standard
+ input, output or error and log the contents. Beginning with
+ version 1.8.20, a pipe is only used when I/O logging is enabled.
+ If use_pty is set without log_input or log_output, no pipe will
+ be used. Additionally, if log_input is set without log_output,
+ a pipe is only used for the standard input. Likewise, if
+ log_output is set without log_input, a pipe is only used for
+ the standard output and standard error. This results in a
+ noticeable change in behavior if the use_pty flag is set and no
+ terminal is present when running commands such as scripts that
+ execute other commands asynchronously (in the background).
+ Previously, sudo would exit immediately, causing background
+ commands to terminate with a broken pipe if they attempt to
+ write to the standard output or standard error. As of version
+ 1.8.20, a pipe will not be used in this case so the command
+ will no longer be terminated.
+
+o Upgrading from a version prior to 1.8.16:
+
+ When editing files with sudoedit, files in a directory that is
+ writable by the invoking user may no longer be edited by default.
+ Also, sudoedit will refuse to follow a symbolic link in the
+ path to be edited if that directory containing the link is
+ writable by the user. This behavior can be disabled by negating
+ the sudoedit_checkdir sudoers option, which is now enabled by
+ default.
+
+o Upgrading from a version prior to 1.8.15:
+
+ Prior to version 1.8.15, when env_reset was enabled (the default)
+ and the -s option was not used, the SHELL environment variable
+ was set to the shell of the invoking user. In 1.8.15 and above,
+ when env_reset is enabled and the -s option is not used, SHELL
+ is set based on the target user.
+
+ When editing files with sudoedit, symbolic links will no longer
+ be followed by default. The old behavior can be restored by
+ enabling the sudoedit_follow option in sudoers or on a per-command
+ basis with the FOLLOW and NOFOLLOW tags.
+
+ Prior to version 1.8.15, groups listed in sudoers that were not
+ found in the system group database were passed to the group
+ plugin, if any. Starting with 1.8.15, only groups of the form
+ %:group are resolved via the group plugin by default. The old
+ behavior can be restored by using the always_query_group_plugin
+ sudoers option.
+
+ Locking of the time stamp file has changed in sudo 1.8.15.
+ Previously, the user's entire time stamp file was locked while
+ retrieving and updating a time stamp record. Now, only a single
+ record, specific to the tty or parent process ID, is locked.
+ This lock is held while the user enters their password. If
+ sudo is suspended at the password prompt (or run in the
+ background), the lock is dropped until sudo is resumed, at which
+ point it will be reacquired. This allows sudo to be used in a
+ pipeline even when a password is required--only one instance
+ of sudo will prompt for a password.
+
+o Upgrading from a version prior to 1.8.14:
+
+ On HP-UX, sudo will no longer check for "plugin.sl" if "plugin.so"
+ is specified but does not exist. This was a temporary hack for
+ backwards compatibility with Sudo 1.8.6 and below when the
+ plugin path name was not listed in sudo.conf. A plugin path
+ name that explicitly ends in ".sl" will still work as expected.
+
+o Upgrading from a version prior to 1.8.12:
+
+ On Solaris, sudo is now able to determine the NIS domain name.
+ As a result, if you had previously been using netgroups that
+ do not include the domain, you will need to either set the
+ domain in the entry or leave the domain part of the tuple blank.
+
+ For example, the following will no longer work:
+ my-hosts (foo,-,-) (bar,-,-) (baz,-,-)
+ and should be changed to:
+ my-hosts (foo,-,) (bar,-,) (baz,-,)
+
+o Upgrading from a version prior to 1.8.10:
+
+ The time stamp file format has changed in sudo 1.8.10. There
+ is now a single time stamp file for each user, even when tty-based
+ time stamps are used. Each time stamp file may contain multiple
+ records to support tty-based time stamps as well as multiple
+ authentication users. On systems that support it, monotonic
+ time is stored instead of wall clock time. As a result, it is
+ important that the time stamp files not persist when the system
+ reboots. For this reason, the default location for the time
+ stamp files has changed back to a directory located in /var/run.
+ Systems that do not have /var/run (e.g. AIX) or that do not clear
+ it on boot (e.g. HP-UX) will need to clear the time stamp
+ directory via a start up script. Such a script is installed by
+ default on AIX and HP-UX systems.
+
+ Because there is now a single time stamp file per user, the -K
+ option will remove all of the user's time stamps, not just the
+ time stamp for the current terminal.
+
+ Lecture status is now stored separately from the time stamps
+ in a separate directory: /var/db/sudo/lectured, /var/lib/sudo/lectured
+ or /var/adm/sudo/lectured depending on what is present on the
+ system.
+
+ LDAP-based sudoers now uses a default search filter of
+ (objectClass=sudoRole) for more efficient queries. It is
+ possible to disable the default search filter by specifying
+ SUDOERS_SEARCH_FILTER in ldap.conf but omitting a value.
+
+o Upgrading from a version prior to 1.8.7:
+
+ Sudo now stores its libexec files in a "sudo" sub-directory
+ instead of in libexec itself. For backwards compatibility, if
+ the plugin is not found in the default plugin directory, sudo
+ will check the parent directory default directory ends in "/sudo".
+
+ The default sudo plugins now all use the .so extension, regardless
+ of the extension used by native shared libraries. For backwards
+ compatibility, sudo on HP-UX will also search for a plugin with
+ an .sl extension if the .so version is not found.
+
+ Handling of users belonging to a large number of groups has
+ changed. Previously, sudo would only use the group list from
+ the kernel unless the system_group plugin was enabled in sudoers.
+ Now, sudo will query the groups database if the user belongs
+ to the maximum number of groups supported by the kernel. See
+ the group_source and max_groups settings in the sudo.conf manual
+ for details.
+
+o Upgrading from a version prior to 1.8.2:
+
+ When matching Unix groups in the sudoers file, sudo will now
+ match based on the name of the group as it appears in sudoers
+ instead of the group ID. This can substantially reduce the
+ number of group lookups for sudoers files that contain a large
+ number of groups. There are a few side effects of this change.
+
+ 1) Unix groups with different names but the same group ID are
+ can no longer be used interchangeably. Sudo will look up all
+ of a user's groups by group ID and use the resulting group
+ names when matching sudoers entries. If there are multiple
+ groups with the same ID, the group name returned by the
+ system getgrgid() library function is the name that will be
+ used when matching sudoers entries.
+
+ 2) Unix group names specified in the sudoers file that are
+ longer than the system maximum will no longer match. For
+ instance, if there is a Unix group "fireflie" on a system
+ where group names are limited to eight characters, "%fireflies"
+ in sudoers will no longer match "fireflie". Previously, a
+ lookup by name of the group "fireflies" would have matched
+ the "fireflie" group on most systems.
+
+ The legacy group matching behavior may be restored by enabling
+ the match_group_by_gid Defaults option in sudoers available
+ in sudo 1.8.18 and higher.
+
+o Upgrading from a version prior to 1.8.1:
+
+ Changes in the sudoers parser could result in parse errors for
+ existing sudoers file. These changes cause certain erroneous
+ entries to be flagged as errors where before they allowed.
+ Changes include:
+
+ Combining multiple Defaults entries with a backslash. E.g.
+
+ Defaults set_path \
+ Defaults syslog
+
+ which should be:
+
+ Defaults set_path
+ Defaults syslog
+
+ Also, double-quoted strings with a missing end-quote are now
+ detected and result in an error. Previously, text starting a
+ double quote and ending with a newline was ignored. E.g.
+
+ Defaults set_path"foo
+
+ In previous versions of sudo, the `"foo' portion would have
+ been ignored.
+
+ To avoid problems, sudo 1.8.1's "make install" will not install
+ a new sudo binary if the existing sudoers file has errors.
+
+ In Sudo 1.8.1 the "noexec" functionality has moved out of the
+ sudoers policy plugin and into the sudo front-end. As a result,
+ the path to the noexec file is now specified in the sudo.conf
+ file instead of the sudoers file. If you have a sudoers file
+ that uses the "noexec_file" option, you will need to move the
+ definition to the sudo.conf file instead.
+
+ Old style in /etc/sudoers:
+ Defaults noexec_file=/usr/local/libexec/sudo_noexec.so
+
+ New style in /etc/sudo.conf:
+ Path noexec /usr/local/libexec/sudo_noexec.so
+
+o Upgrading from a version prior to 1.8.0:
+
+ Starting with version 1.8.0, sudo uses a modular framework to
+ support policy and I/O logging plugins. The default policy
+ plugin is "sudoers" which provides the traditional sudoers
+ evaluation and I/O logging. Plugins are typically located in
+ /usr/libexec or /usr/local/libexec, though this is system-dependent.
+ The sudoers plugin is named "sudoers.so" on most systems.
+
+ The sudo.conf file, usually stored in /etc, is used to configure
+ plugins. This file is optional--if no plugins are specified
+ in sudo.conf, the "sudoers" plugin is used. See the example
+ sudo.conf file in the doc directory or refer to the updated
+ sudo manual to see how to configure sudo.conf.
+
+ The "askpass" setting has moved from the sudoers file to the
+ sudo.conf file. If you have a sudoers file that uses the
+ "askpass" option, you will need to move the definition to the
+ sudo.conf file.
+
+ Old style in /etc/sudoers:
+ Defaults askpass=/usr/X11R6/bin/ssh-askpass
+
+ New style in /etc/sudo.conf:
+ Path askpass /usr/X11R6/bin/ssh-askpass
+
+o Upgrading from a version prior to 1.7.5:
+
+ Sudo 1.7.5 includes an updated LDAP schema with support for
+ the sudoNotBefore, sudoNotAfter and sudoOrder attributes.
+
+ The sudoNotBefore and sudoNotAfter attribute support is only
+ used when the SUDOERS_TIMED setting is enabled in ldap.conf.
+ If enabled, those attributes are used directly when constructing
+ an LDAP filter. As a result, your LDAP server must have the
+ updated schema if you want to use sudoNotBefore and sudoNotAfter.
+
+ The sudoOrder support does not affect the LDAP filter sudo
+ constructs and so there is no need to explicitly enable it in
+ ldap.conf. If the sudoOrder attribute is not present in an
+ entry, a value of 0 is used. If no entries contain sudoOrder
+ attributes, the results are in whatever order the LDAP server
+ returns them, as in past versions of sudo.
+
+ Older versions of sudo will simply ignore the new attributes
+ if they are present in an entry. There are no compatibility
+ problems using the updated schema with older versions of sudo.
+
+o Upgrading from a version prior to 1.7.4:
+
+ Starting with sudo 1.7.4, the time stamp files have moved from
+ /var/run/sudo to either /var/db/sudo, /var/lib/sudo or /var/adm/sudo.
+ The directories are checked for existence in that order. This
+ prevents users from receiving the sudo lecture every time the
+ system reboots. Time stamp files older than the boot time are
+ ignored on systems where it is possible to determine this.
+
+ Additionally, the tty_tickets sudoers option is now enabled by
+ default. To restore the old behavior (single time stamp per user),
+ add a line like:
+ Defaults !tty_tickets
+ to sudoers or use the --without-tty-tickets configure option.
+
+ The HOME and MAIL environment variables are now reset based on the
+ target user's password database entry when the env_reset sudoers option
+ is enabled (which is the case in the default configuration). Users
+ wishing to preserve the original values should use a sudoers entry like:
+ Defaults env_keep += HOME
+ to preserve the old value of HOME and
+ Defaults env_keep += MAIL
+ to preserve the old value of MAIL.
+
+ NOTE: preserving HOME has security implications since many programs
+ use it when searching for configuration files. Adding HOME to env_keep
+ may enable a user to run unrestricted commands via sudo.
+
+ The default syslog facility has changed from "local2" to "authpriv"
+ (or "auth" if the operating system doesn't have "authpriv").
+ The --with-logfac configure option can be used to change this
+ or it can be changed in the sudoers file.
+
+o Upgrading from a version prior to 1.7.0:
+
+ Starting with sudo 1.7.0, comments in the sudoers file must not
+ have a digit or minus sign immediately after the comment character
+ ('#'). Otherwise, the comment may be interpreted as a user or
+ group ID.
+
+ When sudo is build with LDAP support the /etc/nsswitch.conf file is
+ now used to determine the sudoers sea ch order. sudo will default to
+ only using /etc/sudoers unless /etc/nsswitch.conf says otherwise.
+ This can be changed with an nsswitch.conf line, e.g.:
+ sudoers: ldap files
+ Would case LDAP to be searched first, then the sudoers file.
+ To restore the pre-1.7.0 behavior, run configure with the
+ --with-nsswitch=no flag.
+
+ Sudo now ignores user .ldaprc files as well as system LDAP defaults.
+ All LDAP configuration is now in /etc/ldap.conf (or whichever file
+ was specified by configure's --with-ldap-conf-file option).
+ If you are using TLS, you may now need to specify:
+ tls_checkpeer no
+ in sudo's ldap.conf unless ldap.conf references a valid certificate
+ authority file(s).
+
+ Please also see the NEWS file for a list of new features in
+ sudo 1.7.0.
+
+o Upgrading from a version prior to 1.6.9:
+
+ Starting with sudo 1.6.9, if an OS supports a modular authentication
+ method such as PAM, it will be used by default by configure.
+
+ Environment variable handling has changed significantly in sudo
+ 1.6.9. Prior to version 1.6.9, sudo would preserve the user's
+ environment, pruning out potentially dangerous variables.
+ Beginning with sudo 1.6.9, the environment is reset to a default
+ set of values with only a small number of "safe" variables
+ preserved. To preserve specific environment variables, add
+ them to the "env_keep" list in sudoers. E.g.
+
+ Defaults env_keep += "EDITOR"
+
+ The old behavior can be restored by negating the "env_reset"
+ option in sudoers. E.g.
+
+ Defaults !env_reset
+
+ There have also been changes to how the "env_keep" and
+ "env_check" options behave.
+
+ Prior to sudo 1.6.9, the TERM and PATH environment variables
+ would always be preserved even if the env_keep option was
+ redefined. That is no longer the case. Consequently, if
+ env_keep is set with "=" and not simply appended to (i.e. using
+ "+="), PATH and TERM must be explicitly included in the list
+ of environment variables to keep. The LOGNAME, SHELL, USER,
+ and USERNAME environment variables are still always set.
+
+ Additionally, the env_check setting previously had no effect
+ when env_reset was set (which is now on by default). Starting
+ with sudo 1.6.9, environment variables listed in env_check are
+ also preserved in the env_reset case, provided that they do not
+ contain a '/' or '%' character. Note that it is not necessary
+ to also list a variable in env_keep--having it in env_check is
+ sufficient.
+
+ The default lists of variables to be preserved and/or checked
+ are displayed when sudo is run by root with the -V flag.
+
+o Upgrading from a version prior to 1.6.8:
+
+ Prior to sudo 1.6.8, if /var/run did not exist, sudo would put
+ the time stamp files in /tmp/.odus. As of sudo 1.6.8, the
+ time stamp files will be placed in /var/adm/sudo or /usr/adm/sudo
+ if there is no /var/run directory. This directory will be
+ created if it does not already exist.
+
+ Previously, a sudoers entry that explicitly prohibited running
+ a command as a certain user did not override a previous entry
+ allowing the same command. This has been fixed in sudo 1.6.8
+ such that the last match is now used (as it is documented).
+ Hopefully no one was depending on the previous (buggy) behavior.
+
+o Upgrading from a version prior to 1.6:
+
+ As of sudo 1.6, parsing of runas entries and the NOPASSWD tag
+ has changed. Prior to 1.6, a runas specifier applied only to
+ a single command directly following it. Likewise, the NOPASSWD
+ tag only allowed the command directly following it to be run
+ without a password. Starting with sudo 1.6, both the runas
+ specifier and the NOPASSWD tag are "sticky" for an entire
+ command list. So, given the following line in sudo < 1.6
+
+ millert ALL=(daemon) NOPASSWD:/usr/bin/whoami,/bin/ls
+
+ millert would be able to run /usr/bin/whoami as user daemon
+ without a password and /bin/ls as root with a password.
+
+ As of sudo 1.6, the same line now means that millert is able
+ to run run both /usr/bin/whoami and /bin/ls as user daemon
+ without a password. To expand on this, take the following
+ example:
+
+ millert ALL=(daemon) NOPASSWD:/usr/bin/whoami, (root) /bin/ls, \
+ /sbin/dump
+
+ millert can run /usr/bin/whoami as daemon and /bin/ls and
+ /sbin/dump as root. No password need be given for either
+ command. In other words, the "(root)" sets the default runas
+ user to root for the rest of the list. If we wanted to require
+ a password for /bin/ls and /sbin/dump the line could be written
+ as:
+
+ millert ALL=(daemon) NOPASSWD:/usr/bin/whoami, \
+ (root) PASSWD:/bin/ls, /sbin/dump
+
+ Additionally, sudo now uses a per-user time stamp directory
+ instead of a time stamp file. This allows tty time stamps to
+ simply be files within the user's time stamp dir. For the
+ default, non-tty case, the time stamp on the directory itself
+ is used.
+
+ Also, the temporary file used by visudo is now /etc/sudoers.tmp
+ since some versions of vipw on systems with shadow passwords use
+ /etc/stmp for the temporary shadow file.
+
+o Upgrading from a version prior to 1.5:
+
+ By default, sudo expects the sudoers file to be mode 0440 and
+ to be owned by user and group 0. This differs from version 1.4
+ and below which expected the sudoers file to be mode 0400 and
+ to be owned by root. Doing a `make install' will set the sudoers
+ file to the new mode and group. If sudo encounters a sudoers
+ file with the old permissions it will attempt to update it to
+ the new scheme. You cannot, however, use a sudoers file with
+ the new permissions with an old sudo binary. It is suggested
+ that if have a means of distributing sudo you distribute the
+ new binaries first, then the new sudoers file (or you can leave
+ sudoers as is and sudo will fix the permissions itself as long
+ as sudoers is on a local file system).
diff --git a/doc/cvtsudoers.cat b/doc/cvtsudoers.cat
new file mode 100644
index 0000000..d6fcbe3
--- /dev/null
+++ b/doc/cvtsudoers.cat
@@ -0,0 +1,282 @@
+CVTSUDOERS(1) General Commands Manual CVTSUDOERS(1)
+
+NNAAMMEE
+ ccvvttssuuddooeerrss - convert between sudoers file formats
+
+SSYYNNOOPPSSIISS
+ ccvvttssuuddooeerrss [--eehhMMppVV] [--bb _d_n] [--cc _c_o_n_f___f_i_l_e] [--dd _d_e_f_t_y_p_e_s]
+ [--ff _o_u_t_p_u_t___f_o_r_m_a_t] [--ii _i_n_p_u_t___f_o_r_m_a_t] [--II _i_n_c_r_e_m_e_n_t]
+ [--mm _f_i_l_t_e_r] [--oo _o_u_t_p_u_t___f_i_l_e] [--OO _s_t_a_r_t___p_o_i_n_t] [--PP _p_a_d_d_i_n_g]
+ [--ss _s_e_c_t_i_o_n_s] [_i_n_p_u_t___f_i_l_e]
+
+DDEESSCCRRIIPPTTIIOONN
+ ccvvttssuuddooeerrss can be used to convert between _s_u_d_o_e_r_s security policy file
+ formats. The default input format is sudoers. The default output format
+ is LDIF. It is only possible to convert a _s_u_d_o_e_r_s file that is
+ syntactically correct.
+
+ If no _i_n_p_u_t___f_i_l_e is specified, or if it is `-', the policy is read from
+ the standard input. By default, the result is written to the standard
+ output.
+
+ The options are as follows:
+
+ --bb _d_n, ----bbaassee=_d_n
+ The base DN (distinguished name) that will be used when
+ performing LDAP queries. Typically this is of the form
+ ou=SUDOers,dc=my-domain,dc=com for the domain my-domain.com.
+ If this option is not specified, the value of the
+ SUDOERS_BASE environment variable will be used instead. Only
+ necessary when converting to LDIF format.
+
+ --cc _c_o_n_f___f_i_l_e, ----ccoonnffiigg=_c_o_n_f___f_i_l_e
+ Specify the path to the configuration file. Defaults to
+ _/_e_t_c_/_c_v_t_s_u_d_o_e_r_s_._c_o_n_f.
+
+ --dd _d_e_f_t_y_p_e_s, ----ddeeffaauullttss=_d_e_f_t_y_p_e_s
+ Only convert Defaults entries of the specified types. One or
+ more Defaults types may be specified, separated by a comma
+ (`,'). The supported types are:
+
+ all All Defaults entries.
+
+ global Global Defaults entries that are applied regardless
+ of user, runas, host or command.
+
+ user Per-user Defaults entries.
+
+ runas Per-runas user Defaults entries.
+
+ host Per-host Defaults entries.
+
+ command Per-command Defaults entries.
+
+ See the DDeeffaauullttss section in sudoers(4) for more information.
+
+ If the --dd option is not specified, all Defaults entries will
+ be converted.
+
+ --ee, ----eexxppaanndd--aalliiaasseess
+ Expand aliases in _i_n_p_u_t___f_i_l_e. Aliases are preserved by
+ default when the output _f_o_r_m_a_t is JSON or sudoers.
+
+ --ff _o_u_t_p_u_t___f_o_r_m_a_t, ----oouuttppuutt--ffoorrmmaatt=_o_u_t_p_u_t___f_o_r_m_a_t
+ Specify the output format (case-insensitive). The following
+ formats are supported:
+
+ JSON JSON (JavaScript Object Notation) files are usually
+ easier for third-party applications to consume than
+ the traditional _s_u_d_o_e_r_s format. The various values
+ have explicit types which removes much of the
+ ambiguity of the _s_u_d_o_e_r_s format.
+
+ LDIF LDIF (LDAP Data Interchange Format) files can be
+ imported into an LDAP server for use with
+ sudoers.ldap(4).
+
+ Conversion to LDIF has the following limitations:
+
+ ++oo Command, host, runas and user-specific Defaults
+ lines cannot be translated as they don't have an
+ equivalent in the sudoers LDAP schema.
+
+ ++oo Command, host, runas and user aliases are not
+ supported by the sudoers LDAP schema so they are
+ expanded during the conversion.
+
+ sudoers Traditional sudoers format. A new sudoers file
+ will be reconstructed from the parsed input file.
+ Comments are not preserved and data from any
+ include files will be output inline.
+
+ --hh, ----hheellpp Display a short help message to the standard output and exit.
+
+ --ii _i_n_p_u_t___f_o_r_m_a_t, ----iinnppuutt--ffoorrmmaatt=_i_n_p_u_t___f_o_r_m_a_t
+ Specify the input format. The following formats are
+ supported:
+
+ LDIF LDIF (LDAP Data Interchange Format) files can be
+ exported from an LDAP server to convert security
+ policies used by sudoers.ldap(4). If a base DN
+ (distinguished name) is specified, only sudoRole
+ objects that match the base DN will be processed.
+ Not all sudoOptions specified in a sudoRole can be
+ translated from LDIF to sudoers format.
+
+ sudoers Traditional sudoers format. This is the default
+ input format.
+
+ --II _i_n_c_r_e_m_e_n_t, ----iinnccrreemmeenntt=_i_n_c_r_e_m_e_n_t
+ When generating LDIF output, increment each sudoOrder
+ attribute by the specified number. Defaults to an increment
+ of 1.
+
+ --mm _f_i_l_t_e_r, ----mmaattcchh=_f_i_l_t_e_r
+ Only output rules that match the specified _f_i_l_t_e_r. A _f_i_l_t_e_r
+ expression is made up of one or more kkeeyy == _v_a_l_u_e pairs,
+ separated by a comma (`,'). The kkeeyy may be "user", "group"
+ or "host". For example, uusseerr = _o_p_e_r_a_t_o_r or hhoosstt = _w_w_w. An
+ upper-case User_Alias or Host_Alias may be specified as the
+ "user" or "host".
+
+ A matching _s_u_d_o_e_r_s rule may also include users, groups and
+ hosts that are not part of the _f_i_l_t_e_r. This can happen when
+ a rule includes multiple users, groups or hosts. To prune
+ out any non-matching user, group or host from the rules, the
+ --pp option may be used.
+
+ By default, the password and group databases are not
+ consulted when matching against the filter so the users and
+ groups do not need to be present on the local system (see the
+ --MM option). Only aliases that are referenced by the filtered
+ policy rules will be displayed.
+
+ --MM, ----mmaattcchh--llooccaall
+ When the --mm option is also specified, use password and group
+ database information when matching users and groups in the
+ filter. Only users and groups in the filter that exist on
+ the local system will match, and a user's groups will
+ automatically be added to the filter. If the --MM is _n_o_t
+ specified, users and groups in the filter do not need to
+ exist on the local system, but all groups used for matching
+ must be explicitly listed in the filter.
+
+ --oo _o_u_t_p_u_t___f_i_l_e, ----oouuttppuutt=_o_u_t_p_u_t___f_i_l_e
+ Write the converted output to _o_u_t_p_u_t___f_i_l_e. If no _o_u_t_p_u_t___f_i_l_e
+ is specified, or if it is `-', the converted _s_u_d_o_e_r_s policy
+ will be written to the standard output.
+
+ --OO _s_t_a_r_t___p_o_i_n_t, ----oorrddeerr--ssttaarrtt=_s_t_a_r_t___p_o_i_n_t
+ When generating LDIF output, use the number specified by
+ _s_t_a_r_t___p_o_i_n_t in the sudoOrder attribute of the first sudoRole
+ object. Subsequent sudoRole object use a sudoOrder value
+ generated by adding an _i_n_c_r_e_m_e_n_t, see the --II option for
+ details. Defaults to a starting point of 1. A starting
+ point of 0 will disable the generation of sudoOrder
+ attributes in the resulting LDIF file.
+
+ --pp, ----pprruunnee--mmaattcchheess
+ When the --mm option is also specified, ccvvttssuuddooeerrss will prune
+ out non-matching users, groups and hosts from matching
+ entries.
+
+ --PP _p_a_d_d_i_n_g, ----ppaaddddiinngg=_p_a_d_d_i_n_g
+ When generating LDIF output, construct the initial sudoOrder
+ value by concatenating _o_r_d_e_r___s_t_a_r_t and _i_n_c_r_e_m_e_n_t, padding the
+ _i_n_c_r_e_m_e_n_t with zeros until it consists of _p_a_d_d_i_n_g digits.
+ For example, if _o_r_d_e_r___s_t_a_r_t is 1027, _p_a_d_d_i_n_g is 3, and
+ _i_n_c_r_e_m_e_n_t is 1, the value of sudoOrder for the first entry
+ will be 1027000, followed by 1027001, 1027002, etc. If the
+ number of sudoRole entries is larger than the padding would
+ allow, ccvvttssuuddooeerrss will exit with an error. By default, no
+ padding is performed.
+
+ --ss _s_e_c_t_i_o_n_s, ----ssuupppprreessss=_s_e_c_t_i_o_n_s
+ Suppress the output of specific _s_e_c_t_i_o_n_s of the security
+ policy. One or more section names may be specified,
+ separated by a comma (`,'). The supported section name are:
+ ddeeffaauullttss, aalliiaasseess and pprriivviilleeggeess (which may be shortened to
+ pprriivvss).
+
+ --VV, ----vveerrssiioonn
+ Print the ccvvttssuuddooeerrss and _s_u_d_o_e_r_s grammar versions and exit.
+
+ Options in the form "keyword = value" may also be specified in a
+ configuration file, _/_e_t_c_/_c_v_t_s_u_d_o_e_r_s_._c_o_n_f by default. The following
+ keywords are recognized:
+
+ ddeeffaauullttss == _d_e_f_t_y_p_e_s
+ See the description of the --dd command line option.
+
+ eexxppaanndd__aalliiaasseess == _y_e_s | _n_o
+ See the description of the --ee command line option.
+
+ iinnppuutt__ffoorrmmaatt == _l_d_i_f | _s_u_d_o_e_r_s
+ See the description of the --ii command line option.
+
+ mmaattcchh == _f_i_l_t_e_r
+ See the description of the --mm command line option.
+
+ oorrddeerr__iinnccrreemmeenntt == _i_n_c_r_e_m_e_n_t
+ See the description of the --II command line option.
+
+ oorrddeerr__ssttaarrtt == _s_t_a_r_t___p_o_i_n_t
+ See the description of the --OO command line option.
+
+ oouuttppuutt__ffoorrmmaatt == _j_s_o_n | _l_d_i_f | _s_u_d_o_e_r_s
+ See the description of the --ff command line option.
+
+ ppaaddddiinngg == _p_a_d_d_i_n_g
+ See the description of the --PP command line option.
+
+ pprruunnee__mmaattcchheess == _y_e_s | _n_o
+ See the description of the --pp command line option.
+
+ ssuuddooeerrss__bbaassee == _d_n
+ See the description of the --bb command line option.
+
+ ssuupppprreessss == _s_e_c_t_i_o_n_s
+ See the description of the --ss command line option.
+
+ Options on the command line will override values from the configuration
+ file.
+
+FFIILLEESS
+ _/_e_t_c_/_c_v_t_s_u_d_o_e_r_s_._c_o_n_f default configuration for cvtsudoers
+
+EEXXAAMMPPLLEESS
+ Convert _/_e_t_c_/_s_u_d_o_e_r_s to LDIF (LDAP Data Interchange Format) where the
+ _l_d_a_p_._c_o_n_f file uses a _s_u_d_o_e_r_s___b_a_s_e of my-domain,dc=com, storing the
+ result in _s_u_d_o_e_r_s_._l_d_i_f:
+
+ $ cvtsudoers -b ou=SUDOers,dc=my-domain,dc=com -o sudoers.ldif \
+ /etc/sudoers
+
+ Convert _/_e_t_c_/_s_u_d_o_e_r_s to JSON format, storing the result in _s_u_d_o_e_r_s_._j_s_o_n:
+
+ $ cvtsudoers -f json -o sudoers.json /etc/sudoers
+
+ Parse _/_e_t_c_/_s_u_d_o_e_r_s and display only rules that match user _a_m_b_r_o_s_e on host
+ _h_a_s_t_u_r:
+
+ $ cvtsudoers -f sudoers -m user=ambrose,host=hastur /etc/sudoers
+
+ Same as above, but expand aliases and prune out any non-matching users
+ and hosts from the expanded entries.
+
+ $ cvtsudoers -ep -f sudoers -m user=ambrose,host=hastur /etc/sudoers
+
+ Convert _s_u_d_o_e_r_s_._l_d_i_f from LDIF to traditional _s_u_d_o_e_r_s format:
+
+ $ cvtsudoers -i ldif -f sudoers -o sudoers.new sudoers.ldif
+
+SSEEEE AALLSSOO
+ sudoers(4), sudoers.ldap(4), sudo(1m)
+
+AAUUTTHHOORRSS
+ Many people have worked on ssuuddoo over the years; this version consists of
+ code written primarily by:
+
+ Todd C. Miller
+
+ See the CONTRIBUTORS file in the ssuuddoo distribution
+ (https://www.sudo.ws/contributors.html) for an exhaustive list of people
+ who have contributed to ssuuddoo.
+
+BBUUGGSS
+ If you feel you have found a bug in ccvvttssuuddooeerrss, please submit a bug
+ report at https://bugzilla.sudo.ws/
+
+SSUUPPPPOORRTT
+ Limited free support is available via the sudo-users mailing list, see
+ https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search
+ the archives.
+
+DDIISSCCLLAAIIMMEERR
+ ccvvttssuuddooeerrss is provided "AS IS" and any express or implied warranties,
+ including, but not limited to, the implied warranties of merchantability
+ and fitness for a particular purpose are disclaimed. See the LICENSE
+ file distributed with ssuuddoo or https://www.sudo.ws/license.html for
+ complete details.
+
+Sudo 1.8.26 December 11, 2018 Sudo 1.8.26
diff --git a/doc/cvtsudoers.man.in b/doc/cvtsudoers.man.in
new file mode 100644
index 0000000..41929ea
--- /dev/null
+++ b/doc/cvtsudoers.man.in
@@ -0,0 +1,511 @@
+.\" Automatically generated from an mdoc input file. Do not edit.
+.\"
+.\" Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "CVTSUDOERS" "1" "December 11, 2018" "Sudo @PACKAGE_VERSION@" "General Commands Manual"
+.nh
+.if n .ad l
+.SH "NAME"
+\fBcvtsudoers\fR
+\- convert between sudoers file formats
+.SH "SYNOPSIS"
+.HP 11n
+\fBcvtsudoers\fR
+[\fB\-ehMpV\fR]
+[\fB\-b\fR\ \fIdn\fR]
+[\fB\-c\fR\ \fIconf_file\fR]
+[\fB\-d\fR\ \fIdeftypes\fR]
+[\fB\-f\fR\ \fIoutput_format\fR]
+[\fB\-i\fR\ \fIinput_format\fR]
+[\fB\-I\fR\ \fIincrement\fR]
+[\fB\-m\fR\ \fIfilter\fR]
+[\fB\-o\fR\ \fIoutput_file\fR]
+[\fB\-O\fR\ \fIstart_point\fR]
+[\fB\-P\fR\ \fIpadding\fR]
+[\fB\-s\fR\ \fIsections\fR]
+[\fIinput_file\fR]
+.SH "DESCRIPTION"
+\fBcvtsudoers\fR
+can be used to convert between
+\fIsudoers\fR
+security policy file formats.
+The default input format is sudoers.
+The default output format is LDIF.
+It is only possible to convert a
+\fIsudoers\fR
+file that is syntactically correct.
+.PP
+If no
+\fIinput_file\fR
+is specified, or if it is
+\(oq-\(cq,
+the policy is read from the standard input.
+By default, the result is written to the standard output.
+.PP
+The options are as follows:
+.TP 12n
+\fB\-b\fR \fIdn\fR, \fB\--base\fR=\fIdn\fR
+The base DN (distinguished name) that will be used when performing
+LDAP queries.
+Typically this is of the form
+\fRou=SUDOers,dc=my-domain,dc=com\fR
+for the domain
+\fRmy-domain.com\fR.
+If this option is not specified, the value of the
+\fRSUDOERS_BASE\fR
+environment variable will be used instead.
+Only necessary when converting to LDIF format.
+.TP 12n
+\fB\-c\fR \fIconf_file\fR, \fB\--config\fR=\fIconf_file\fR
+Specify the path to the configuration file.
+Defaults to
+\fI@sysconfdir@/cvtsudoers.conf\fR.
+.TP 12n
+\fB\-d\fR \fIdeftypes\fR, \fB\--defaults\fR=\fIdeftypes\fR
+Only convert
+\fRDefaults\fR
+entries of the specified types.
+One or more
+\fRDefaults\fR
+types may be specified, separated by a comma
+(\(oq\&,\(cq).
+The supported types are:
+.PP
+.RS 12n
+.PD 0
+.TP 10n
+all
+All Defaults entries.
+.PD
+.TP 10n
+global
+Global Defaults entries that are applied regardless of
+user, runas, host or command.
+.TP 10n
+user
+Per-user Defaults entries.
+.TP 10n
+runas
+Per-runas user Defaults entries.
+.TP 10n
+host
+Per-host Defaults entries.
+.TP 10n
+command
+Per-command Defaults entries.
+.PP
+See the
+\fBDefaults\fR
+section in
+sudoers(@mansectform@)
+for more information.
+.sp
+If the
+\fB\-d\fR
+option is not specified, all
+\fRDefaults\fR
+entries will be converted.
+.RE
+.TP 12n
+\fB\-e\fR, \fB\--expand-aliases\fR
+Expand aliases in
+\fIinput_file\fR.
+Aliases are preserved by default when the output
+\fIformat\fR
+is JSON or sudoers.
+.TP 12n
+\fB\-f\fR \fIoutput_format\fR, \fB\--output-format\fR=\fIoutput_format\fR
+Specify the output format (case-insensitive).
+The following formats are supported:
+.PP
+.RS 12n
+.PD 0
+.TP 10n
+JSON
+JSON (JavaScript Object Notation) files are usually easier for
+third-party applications to consume than the traditional
+\fIsudoers\fR
+format.
+The various values have explicit types which removes much of the
+ambiguity of the
+\fIsudoers\fR
+format.
+.PD
+.TP 10n
+LDIF
+LDIF (LDAP Data Interchange Format) files can be imported into an LDAP
+server for use with
+sudoers.ldap(@mansectform@).
+.sp
+Conversion to LDIF has the following limitations:
+.PP
+.RS 10n
+.PD 0
+.TP 3n
+\fB\(bu\fR
+Command, host, runas and user-specific Defaults lines cannot be
+translated as they don't have an equivalent in the sudoers LDAP schema.
+.PD
+.TP 3n
+\fB\(bu\fR
+Command, host, runas and user aliases are not supported by the
+sudoers LDAP schema so they are expanded during the conversion.
+.PD 0
+.PP
+.RE
+.PD
+.TP 10n
+sudoers
+Traditional sudoers format.
+A new sudoers file will be reconstructed from the parsed input file.
+Comments are not preserved and data from any include files will be
+output inline.
+.PD 0
+.PP
+.RE
+.PD
+.TP 12n
+\fB\-h\fR, \fB\--help\fR
+Display a short help message to the standard output and exit.
+.TP 12n
+\fB\-i\fR \fIinput_format\fR, \fB\--input-format\fR=\fIinput_format\fR
+Specify the input format.
+The following formats are supported:
+.PP
+.RS 12n
+.PD 0
+.TP 10n
+LDIF
+LDIF (LDAP Data Interchange Format) files can be exported from an LDAP
+server to convert security policies used by
+sudoers.ldap(@mansectform@).
+If a base DN (distinguished name) is specified, only sudoRole objects
+that match the base DN will be processed.
+Not all sudoOptions specified in a sudoRole can be translated from
+LDIF to sudoers format.
+.PD
+.TP 10n
+sudoers
+Traditional sudoers format.
+This is the default input format.
+.PD 0
+.PP
+.RE
+.PD
+.TP 12n
+\fB\-I\fR \fIincrement\fR, \fB\--increment\fR=\fIincrement\fR
+When generating LDIF output, increment each sudoOrder attribute by
+the specified number.
+Defaults to an increment of 1.
+.TP 12n
+\fB\-m\fR \fIfilter\fR, \fB\--match\fR=\fIfilter\fR
+Only output rules that match the specified
+\fIfilter\fR.
+A
+\fIfilter\fR
+expression is made up of one or more
+\fBkey =\fR \fIvalue\fR
+pairs, separated by a comma
+(\(oq\&,\(cq).
+The
+\fBkey\fR
+may be
+\(lquser\(rq,
+\(lqgroup\(rq
+or
+\(lqhost\(rq.
+For example,
+\fBuser\fR = \fIoperator\fR
+or
+\fBhost\fR = \fIwww\fR.
+An upper-case User_Alias or Host_Alias may be specified as the
+\(lquser\(rq
+or
+\(lqhost\(rq.
+.sp
+A matching
+\fIsudoers\fR
+rule may also include users, groups and hosts that are not part of the
+\fIfilter\fR.
+This can happen when a rule includes multiple users, groups or hosts.
+To prune out any non-matching user, group or host from the rules, the
+\fB\-p\fR
+option may be used.
+.sp
+By default, the password and group databases are not consulted when matching
+against the filter so the users and groups do not need to be present
+on the local system (see the
+\fB\-M\fR
+option).
+Only aliases that are referenced by the filtered policy rules will
+be displayed.
+.TP 12n
+\fB\-M\fR, \fB\--match-local\fR
+When the
+\fB\-m\fR
+option is also specified, use password and group database information
+when matching users and groups in the filter.
+Only users and groups in the filter that exist on the local system will match,
+and a user's groups will automatically be added to the filter.
+If the
+\fB\-M\fR
+is
+\fInot\fR
+specified, users and groups in the filter do not need to exist on the
+local system, but all groups used for matching must be explicitly listed
+in the filter.
+.TP 12n
+\fB\-o\fR \fIoutput_file\fR, \fB\--output\fR=\fIoutput_file\fR
+Write the converted output to
+\fIoutput_file\fR.
+If no
+\fIoutput_file\fR
+is specified, or if it is
+\(oq-\(cq,
+the converted
+\fIsudoers\fR
+policy will be written to the standard output.
+.TP 12n
+\fB\-O\fR \fIstart_point\fR, \fB\--order-start\fR=\fIstart_point\fR
+When generating LDIF output, use the number specified by
+\fIstart_point\fR
+in the sudoOrder attribute of the first sudoRole object.
+Subsequent sudoRole object use a sudoOrder value generated by adding an
+\fIincrement\fR,
+see the
+\fB\-I\fR
+option for details.
+Defaults to a starting point of 1.
+A starting point of 0 will disable the generation of sudoOrder
+attributes in the resulting LDIF file.
+.TP 12n
+\fB\-p\fR, \fB\--prune-matches\fR
+When the
+\fB\-m\fR
+option is also specified,
+\fBcvtsudoers\fR
+will prune out non-matching users, groups and hosts from
+matching entries.
+.TP 12n
+\fB\-P\fR \fIpadding\fR, \fB\--padding\fR=\fIpadding\fR
+When generating LDIF output, construct the initial sudoOrder value by
+concatenating
+\fIorder_start\fR
+and
+\fIincrement\fR,
+padding the
+\fIincrement\fR
+with zeros until it consists of
+\fIpadding\fR
+digits.
+For example, if
+\fIorder_start\fR
+is 1027,
+\fIpadding\fR
+is 3, and
+\fIincrement\fR
+is 1, the value of sudoOrder for the first entry will be 1027000,
+followed by 1027001, 1027002, etc.
+If the number of sudoRole entries is larger than the padding would allow,
+\fBcvtsudoers\fR
+will exit with an error.
+By default, no padding is performed.
+.TP 12n
+\fB\-s\fR \fIsections\fR, \fB\--suppress\fR=\fIsections\fR
+Suppress the output of specific
+\fIsections\fR
+of the security policy.
+One or more section names may be specified, separated by a comma
+(\(oq\&,\(cq).
+The supported section name are:
+\fBdefaults\fR,
+\fBaliases\fR
+and
+\fBprivileges\fR
+(which may be shortened to
+\fBprivs\fR).
+.TP 12n
+\fB\-V\fR, \fB\--version\fR
+Print the
+\fBcvtsudoers\fR
+and
+\fIsudoers\fR
+grammar versions and exit.
+.PP
+Options in the form
+\(lqkeyword = value\(rq
+may also be specified in a configuration file,
+\fI@sysconfdir@/cvtsudoers.conf\fR
+by default.
+The following keywords are recognized:
+.TP 6n
+\fBdefaults =\fR \fIdeftypes\fR
+See the description of the
+\fB\-d\fR
+command line option.
+.TP 6n
+\fBexpand_aliases =\fR \fIyes\fR | \fIno\fR
+See the description of the
+\fB\-e\fR
+command line option.
+.TP 6n
+\fBinput_format =\fR \fIldif\fR | \fIsudoers\fR
+See the description of the
+\fB\-i\fR
+command line option.
+.TP 6n
+\fBmatch =\fR \fIfilter\fR
+See the description of the
+\fB\-m\fR
+command line option.
+.TP 6n
+\fBorder_increment =\fR \fIincrement\fR
+See the description of the
+\fB\-I\fR
+command line option.
+.TP 6n
+\fBorder_start =\fR \fIstart_point\fR
+See the description of the
+\fB\-O\fR
+command line option.
+.TP 6n
+\fBoutput_format =\fR \fIjson\fR | \fIldif\fR | \fIsudoers\fR
+See the description of the
+\fB\-f\fR
+command line option.
+.TP 6n
+\fBpadding =\fR \fIpadding\fR
+See the description of the
+\fB\-P\fR
+command line option.
+.TP 6n
+\fBprune_matches =\fR \fIyes\fR | \fIno\fR
+See the description of the
+\fB\-p\fR
+command line option.
+.TP 6n
+\fBsudoers_base =\fR \fIdn\fR
+See the description of the
+\fB\-b\fR
+command line option.
+.TP 6n
+\fBsuppress =\fR \fIsections\fR
+See the description of the
+\fB\-s\fR
+command line option.
+.PP
+Options on the command line will override values from the
+configuration file.
+.SH "FILES"
+.TP 26n
+\fI@sysconfdir@/cvtsudoers.conf\fR
+default configuration for cvtsudoers
+.SH "EXAMPLES"
+Convert
+\fI/etc/sudoers\fR
+to LDIF (LDAP Data Interchange Format) where the
+\fIldap.conf\fR
+file uses a
+\fIsudoers_base\fR
+of my-domain,dc=com, storing the result in
+\fIsudoers.ldif\fR:
+.nf
+.sp
+.RS 6n
+$ cvtsudoers -b ou=SUDOers,dc=my-domain,dc=com -o sudoers.ldif \e
+ /etc/sudoers
+.RE
+.fi
+.PP
+Convert
+\fI/etc/sudoers\fR
+to JSON format, storing the result in
+\fIsudoers.json\fR:
+.nf
+.sp
+.RS 6n
+$ cvtsudoers -f json -o sudoers.json /etc/sudoers
+.RE
+.fi
+.PP
+Parse
+\fI/etc/sudoers\fR
+and display only rules that match user
+\fIambrose\fR
+on host
+\fIhastur\fR:
+.nf
+.sp
+.RS 6n
+$ cvtsudoers -f sudoers -m user=ambrose,host=hastur /etc/sudoers
+.RE
+.fi
+.PP
+Same as above, but expand aliases and prune out any non-matching
+users and hosts from the expanded entries.
+.nf
+.sp
+.RS 6n
+$ cvtsudoers -ep -f sudoers -m user=ambrose,host=hastur /etc/sudoers
+.RE
+.fi
+.PP
+Convert
+\fIsudoers.ldif\fR
+from LDIF to traditional
+\fIsudoers\fR
+format:
+.nf
+.sp
+.RS 6n
+$ cvtsudoers -i ldif -f sudoers -o sudoers.new sudoers.ldif
+.RE
+.fi
+.SH "SEE ALSO"
+sudoers(@mansectform@),
+sudoers.ldap(@mansectform@),
+sudo(@mansectsu@)
+.SH "AUTHORS"
+Many people have worked on
+\fBsudo\fR
+over the years; this version consists of code written primarily by:
+.sp
+.RS 6n
+Todd C. Miller
+.RE
+.PP
+See the CONTRIBUTORS file in the
+\fBsudo\fR
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+\fBsudo\fR.
+.SH "BUGS"
+If you feel you have found a bug in
+\fBcvtsudoers\fR,
+please submit a bug report at https://bugzilla.sudo.ws/
+.SH "SUPPORT"
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.SH "DISCLAIMER"
+\fBcvtsudoers\fR
+is provided
+\(lqAS IS\(rq
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+\fBsudo\fR
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/cvtsudoers.mdoc.in b/doc/cvtsudoers.mdoc.in
new file mode 100644
index 0000000..ce5d4c3
--- /dev/null
+++ b/doc/cvtsudoers.mdoc.in
@@ -0,0 +1,437 @@
+.\"
+.\" Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd December 11, 2018
+.Dt CVTSUDOERS 1
+.Os Sudo @PACKAGE_VERSION@
+.Sh NAME
+.Nm cvtsudoers
+.Nd convert between sudoers file formats
+.Sh SYNOPSIS
+.Nm cvtsudoers
+.Op Fl ehMpV
+.Op Fl b Ar dn
+.Op Fl c Ar conf_file
+.Op Fl d Ar deftypes
+.Op Fl f Ar output_format
+.Op Fl i Ar input_format
+.Op Fl I Ar increment
+.Op Fl m Ar filter
+.Op Fl o Ar output_file
+.Op Fl O Ar start_point
+.Op Fl P Ar padding
+.Op Fl s Ar sections
+.Op Ar input_file
+.Sh DESCRIPTION
+.Nm
+can be used to convert between
+.Em sudoers
+security policy file formats.
+The default input format is sudoers.
+The default output format is LDIF.
+It is only possible to convert a
+.Em sudoers
+file that is syntactically correct.
+.Pp
+If no
+.Ar input_file
+is specified, or if it is
+.Ql - ,
+the policy is read from the standard input.
+By default, the result is written to the standard output.
+.Pp
+The options are as follows:
+.Bl -tag -width Fl
+.It Fl b Ar dn , Fl -base Ns = Ns Ar dn
+The base DN (distinguished name) that will be used when performing
+LDAP queries.
+Typically this is of the form
+.Li ou=SUDOers,dc=my-domain,dc=com
+for the domain
+.Li my-domain.com .
+If this option is not specified, the value of the
+.Ev SUDOERS_BASE
+environment variable will be used instead.
+Only necessary when converting to LDIF format.
+.It Fl c Ar conf_file , Fl -config Ns = Ns Ar conf_file
+Specify the path to the configuration file.
+Defaults to
+.Pa @sysconfdir@/cvtsudoers.conf .
+.It Fl d Ar deftypes , Fl -defaults Ns = Ns Ar deftypes
+Only convert
+.Li Defaults
+entries of the specified types.
+One or more
+.Li Defaults
+types may be specified, separated by a comma
+.Pq Ql \&, .
+The supported types are:
+.Bl -tag -width 8n
+.It all
+All Defaults entries.
+.It global
+Global Defaults entries that are applied regardless of
+user, runas, host or command.
+.It user
+Per-user Defaults entries.
+.It runas
+Per-runas user Defaults entries.
+.It host
+Per-host Defaults entries.
+.It command
+Per-command Defaults entries.
+.El
+.Pp
+See the
+.Sy Defaults
+section in
+.Xr sudoers @mansectform@
+for more information.
+.Pp
+If the
+.Fl d
+option is not specified, all
+.Li Defaults
+entries will be converted.
+.It Fl e , Fl -expand-aliases
+Expand aliases in
+.Ar input_file .
+Aliases are preserved by default when the output
+.Ar format
+is JSON or sudoers.
+.It Fl f Ar output_format , Fl -output-format Ns = Ns Ar output_format
+Specify the output format (case-insensitive).
+The following formats are supported:
+.Bl -tag -width 8n
+.It JSON
+JSON (JavaScript Object Notation) files are usually easier for
+third-party applications to consume than the traditional
+.Em sudoers
+format.
+The various values have explicit types which removes much of the
+ambiguity of the
+.Em sudoers
+format.
+.It LDIF
+LDIF (LDAP Data Interchange Format) files can be imported into an LDAP
+server for use with
+.Xr sudoers.ldap @mansectform@ .
+.Pp
+Conversion to LDIF has the following limitations:
+.Bl -bullet -width 1n
+.It
+Command, host, runas and user-specific Defaults lines cannot be
+translated as they don't have an equivalent in the sudoers LDAP schema.
+.It
+Command, host, runas and user aliases are not supported by the
+sudoers LDAP schema so they are expanded during the conversion.
+.El
+.It sudoers
+Traditional sudoers format.
+A new sudoers file will be reconstructed from the parsed input file.
+Comments are not preserved and data from any include files will be
+output inline.
+.El
+.It Fl h , Fl -help
+Display a short help message to the standard output and exit.
+.It Fl i Ar input_format , Fl -input-format Ns = Ns Ar input_format
+Specify the input format.
+The following formats are supported:
+.Bl -tag -width 8n
+.It LDIF
+LDIF (LDAP Data Interchange Format) files can be exported from an LDAP
+server to convert security policies used by
+.Xr sudoers.ldap @mansectform@ .
+If a base DN (distinguished name) is specified, only sudoRole objects
+that match the base DN will be processed.
+Not all sudoOptions specified in a sudoRole can be translated from
+LDIF to sudoers format.
+.It sudoers
+Traditional sudoers format.
+This is the default input format.
+.El
+.It Fl I Ar increment , Fl -increment Ns = Ns Ar increment
+When generating LDIF output, increment each sudoOrder attribute by
+the specified number.
+Defaults to an increment of 1.
+.It Fl m Ar filter , Fl -match Ns = Ns Ar filter
+Only output rules that match the specified
+.Ar filter .
+A
+.Ar filter
+expression is made up of one or more
+.Sy key = Ar value
+pairs, separated by a comma
+.Pq Ql \&, .
+The
+.Sy key
+may be
+.Dq user ,
+.Dq group
+or
+.Dq host .
+For example,
+.Sy user No = Ar operator
+or
+.Sy host No = Ar www .
+An upper-case User_Alias or Host_Alias may be specified as the
+.Dq user
+or
+.Dq host .
+.Pp
+A matching
+.Em sudoers
+rule may also include users, groups and hosts that are not part of the
+.Ar filter .
+This can happen when a rule includes multiple users, groups or hosts.
+To prune out any non-matching user, group or host from the rules, the
+.Fl p
+option may be used.
+.Pp
+By default, the password and group databases are not consulted when matching
+against the filter so the users and groups do not need to be present
+on the local system (see the
+.Fl M
+option).
+Only aliases that are referenced by the filtered policy rules will
+be displayed.
+.It Fl M , Fl -match-local
+When the
+.Fl m
+option is also specified, use password and group database information
+when matching users and groups in the filter.
+Only users and groups in the filter that exist on the local system will match,
+and a user's groups will automatically be added to the filter.
+If the
+.Fl M
+is
+.Em not
+specified, users and groups in the filter do not need to exist on the
+local system, but all groups used for matching must be explicitly listed
+in the filter.
+.It Fl o Ar output_file , Fl -output Ns = Ns Ar output_file
+Write the converted output to
+.Ar output_file .
+If no
+.Ar output_file
+is specified, or if it is
+.Ql - ,
+the converted
+.Em sudoers
+policy will be written to the standard output.
+.It Fl O Ar start_point , Fl -order-start Ns = Ns Ar start_point
+When generating LDIF output, use the number specified by
+.Ar start_point
+in the sudoOrder attribute of the first sudoRole object.
+Subsequent sudoRole object use a sudoOrder value generated by adding an
+.Ar increment ,
+see the
+.Fl I
+option for details.
+Defaults to a starting point of 1.
+A starting point of 0 will disable the generation of sudoOrder
+attributes in the resulting LDIF file.
+.It Fl p , Fl -prune-matches
+When the
+.Fl m
+option is also specified,
+.Nm
+will prune out non-matching users, groups and hosts from
+matching entries.
+.It Fl P Ar padding , Fl -padding Ns = Ns Ar padding
+When generating LDIF output, construct the initial sudoOrder value by
+concatenating
+.Ar order_start
+and
+.Ar increment ,
+padding the
+.Ar increment
+with zeros until it consists of
+.Ar padding
+digits.
+For example, if
+.Ar order_start
+is 1027,
+.Ar padding
+is 3, and
+.Ar increment
+is 1, the value of sudoOrder for the first entry will be 1027000,
+followed by 1027001, 1027002, etc.
+If the number of sudoRole entries is larger than the padding would allow,
+.Nm
+will exit with an error.
+By default, no padding is performed.
+.It Fl s Ar sections , Fl -suppress Ns = Ns Ar sections
+Suppress the output of specific
+.Ar sections
+of the security policy.
+One or more section names may be specified, separated by a comma
+.Pq Ql \&, .
+The supported section name are:
+.Sy defaults ,
+.Sy aliases
+and
+.Sy privileges
+(which may be shortened to
+.Sy privs ) .
+.It Fl V , -version
+Print the
+.Nm
+and
+.Em sudoers
+grammar versions and exit.
+.El
+.Pp
+Options in the form
+.Dq keyword = value
+may also be specified in a configuration file,
+.Pa @sysconfdir@/cvtsudoers.conf
+by default.
+The following keywords are recognized:
+.Bl -tag -width 4n
+.It Sy defaults = Ar deftypes
+See the description of the
+.Fl d
+command line option.
+.It Sy expand_aliases = Ar yes | no
+See the description of the
+.Fl e
+command line option.
+.It Sy input_format = Ar ldif | sudoers
+See the description of the
+.Fl i
+command line option.
+.It Sy match = Ar filter
+See the description of the
+.Fl m
+command line option.
+.It Sy order_increment = Ar increment
+See the description of the
+.Fl I
+command line option.
+.It Sy order_start = Ar start_point
+See the description of the
+.Fl O
+command line option.
+.It Sy output_format = Ar json | ldif | sudoers
+See the description of the
+.Fl f
+command line option.
+.It Sy padding = Ar padding
+See the description of the
+.Fl P
+command line option.
+.It Sy prune_matches = Ar yes | no
+See the description of the
+.Fl p
+command line option.
+.It Sy sudoers_base = Ar dn
+See the description of the
+.Fl b
+command line option.
+.It Sy suppress = Ar sections
+See the description of the
+.Fl s
+command line option.
+.El
+.Pp
+Options on the command line will override values from the
+configuration file.
+.Sh FILES
+.Bl -tag -width 24n
+.It Pa @sysconfdir@/cvtsudoers.conf
+default configuration for cvtsudoers
+.El
+.Sh EXAMPLES
+Convert
+.Pa /etc/sudoers
+to LDIF (LDAP Data Interchange Format) where the
+.Pa ldap.conf
+file uses a
+.Em sudoers_base
+of my-domain,dc=com, storing the result in
+.Pa sudoers.ldif :
+.Bd -literal -offset indent
+$ cvtsudoers -b ou=SUDOers,dc=my-domain,dc=com -o sudoers.ldif \e
+ /etc/sudoers
+.Ed
+.Pp
+Convert
+.Pa /etc/sudoers
+to JSON format, storing the result in
+.Pa sudoers.json :
+.Bd -literal -offset indent
+$ cvtsudoers -f json -o sudoers.json /etc/sudoers
+.Ed
+.Pp
+Parse
+.Pa /etc/sudoers
+and display only rules that match user
+.Em ambrose
+on host
+.Em hastur :
+.Bd -literal -offset indent
+$ cvtsudoers -f sudoers -m user=ambrose,host=hastur /etc/sudoers
+.Ed
+.Pp
+Same as above, but expand aliases and prune out any non-matching
+users and hosts from the expanded entries.
+.Bd -literal -offset indent
+$ cvtsudoers -ep -f sudoers -m user=ambrose,host=hastur /etc/sudoers
+.Ed
+.Pp
+Convert
+.Pa sudoers.ldif
+from LDIF to traditional
+.Em sudoers
+format:
+.Bd -literal -offset indent
+$ cvtsudoers -i ldif -f sudoers -o sudoers.new sudoers.ldif
+.Ed
+.Sh SEE ALSO
+.Xr sudoers @mansectform@ ,
+.Xr sudoers.ldap @mansectform@ ,
+.Xr sudo @mansectsu@
+.Sh AUTHORS
+Many people have worked on
+.Nm sudo
+over the years; this version consists of code written primarily by:
+.Bd -ragged -offset indent
+.An Todd C. Miller
+.Ed
+.Pp
+See the CONTRIBUTORS file in the
+.Nm sudo
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+.Nm sudo .
+.Sh BUGS
+If you feel you have found a bug in
+.Nm ,
+please submit a bug report at https://bugzilla.sudo.ws/
+.Sh SUPPORT
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.Sh DISCLAIMER
+.Nm
+is provided
+.Dq AS IS
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+.Nm sudo
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/fixman.sh b/doc/fixman.sh
new file mode 100755
index 0000000..f7ed1a8
--- /dev/null
+++ b/doc/fixman.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+#
+# Copyright (c) 2012-2014, 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+OUTFILE="$1"
+rm -f "$OUTFILE"
+> "$OUTFILE"
+
+# HP-UX friendly header/footer for all man pages
+if [ X"`uname 2>&1`" = X"HP-UX" ]; then
+ cat >>"$OUTFILE" <<-'EOF'
+ s/^\.TH \("[^"]*"\) \("[^"]*"\) "\([^"]*\)" "\([^"]*\)" \("[^"]*"\)/.TH \1 \2\
+ .ds )H \4\
+ .ds ]W \3/
+EOF
+fi
+
+# Replace "0 minutes" with "unlimited"
+cat >>"$OUTFILE" <<-'EOF'
+ /^\\fR0\\fR$/ {
+ N
+ s/^\\fR0\\fR\nminutes\.$/unlimited./
+ }
+EOF
diff --git a/doc/fixmdoc.sed b/doc/fixmdoc.sed
new file mode 100644
index 0000000..3d57216
--- /dev/null
+++ b/doc/fixmdoc.sed
@@ -0,0 +1,5 @@
+# Replace "0 minutes" with "unlimited"
+/^\.Li 0$/ {
+ N
+ s/^\.Li 0\nminutes\.$/unlimited./
+}
diff --git a/doc/schema.ActiveDirectory b/doc/schema.ActiveDirectory
new file mode 100644
index 0000000..f488eef
--- /dev/null
+++ b/doc/schema.ActiveDirectory
@@ -0,0 +1,255 @@
+#
+# Active Directory Schema for sudo configuration (sudoers)
+#
+# To extend your Active Directory schema, run one of the following command
+# on your Windows DC (default port - Active Directory):
+#
+# ldifde -i -f schema.ActiveDirectory -c "CN=Schema,CN=Configuration,DC=X" #schemaNamingContext
+#
+# or on your Windows DC if using another port (with Active Directory LightWeight Directory Services / ADAM-Active Directory Application Mode)
+# Port 50000 by example (or any other port specified when defining the ADLDS/ADAM instance
+#
+# ldifde -i -f schema.ActiveDirectory -t 50000 -c "CN=Schema,CN=Configuration,DC=X" #schemaNamingContext
+#
+# or
+#
+# ldifde -i -f schema.ActiveDirectory -s server:port -c "CN=Schema,CN=Configuration,DC=X" #schemaNamingContext
+#
+# Can add username domain and password
+#
+# -b username domain password
+#
+# Can create Log file in current or any directory
+#
+# -j .
+#
+
+dn: CN=sudoUser,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoUser
+distinguishedName: CN=sudoUser,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.1
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoUser
+adminDescription: User(s) who may run sudo
+oMSyntax: 22
+searchFlags: 1
+lDAPDisplayName: sudoUser
+name: sudoUser
+schemaIDGUID:: JrGcaKpnoU+0s+HgeFjAbg==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoHost,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoHost
+distinguishedName: CN=sudoHost,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.2
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoHost
+adminDescription: Host(s) who may run sudo
+oMSyntax: 22
+lDAPDisplayName: sudoHost
+name: sudoHost
+schemaIDGUID:: d0TTjg+Y6U28g/Y+ns2k4w==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoCommand,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoCommand
+distinguishedName: CN=sudoCommand,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.3
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoCommand
+adminDescription: Command(s) to be executed by sudo
+oMSyntax: 22
+lDAPDisplayName: sudoCommand
+name: sudoCommand
+schemaIDGUID:: D6QR4P5UyUen3RGYJCHCPg==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoRunAs,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoRunAs
+distinguishedName: CN=sudoRunAs,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.4
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoRunAs
+adminDescription: User(s) impersonated by sudo (deprecated)
+oMSyntax: 22
+lDAPDisplayName: sudoRunAs
+name: sudoRunAs
+schemaIDGUID:: CP98mCQTyUKKxGrQeM80hQ==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoOption,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoOption
+distinguishedName: CN=sudoOption,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.5
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoOption
+adminDescription: Option(s) followed by sudo
+oMSyntax: 22
+lDAPDisplayName: sudoOption
+name: sudoOption
+schemaIDGUID:: ojaPzBBlAEmsvrHxQctLnA==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoRunAsUser,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoRunAsUser
+distinguishedName: CN=sudoRunAsUser,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.6
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoRunAsUser
+adminDescription: User(s) impersonated by sudo
+oMSyntax: 22
+lDAPDisplayName: sudoRunAsUser
+name: sudoRunAsUser
+schemaIDGUID:: 9C52yPYd3RG3jMR2VtiVkw==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoRunAsGroup,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoRunAsGroup
+distinguishedName: CN=sudoRunAsGroup,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.7
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoRunAsGroup
+adminDescription: Groups(s) impersonated by sudo
+oMSyntax: 22
+lDAPDisplayName: sudoRunAsGroup
+name: sudoRunAsGroup
+schemaIDGUID:: xJhSt/Yd3RGJPTB1VtiVkw==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoNotBefore,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoNotBefore
+distinguishedName: CN=sudoNotBefore,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.8
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoNotBefore
+adminDescription: Start of time interval for which the entry is valid
+oMSyntax: 24
+lDAPDisplayName: sudoNotBefore
+name: sudoNotBefore
+schemaIDGUID:: dm1HnRfY4RGf4gopYYhwmw==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoNotAfter,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoNotAfter
+distinguishedName: CN=sudoNotAfter,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.9
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoNotAfter
+adminDescription: End of time interval for which the entry is valid
+oMSyntax: 24
+lDAPDisplayName: sudoNotAfter
+name: sudoNotAfter
+schemaIDGUID:: OAr/pBfY4RG9dBIpYYhwmw==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoOrder,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoOrder
+distinguishedName: CN=sudoOrder,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.10
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoOrder
+adminDescription: an integer to order the sudoRole entries
+oMSyntax: 2
+lDAPDisplayName: sudoOrder
+name: sudoOrder
+schemaIDGUID:: 0J8yrRfY4RGIYBUpYYhwmw==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn:
+changetype: modify
+add: schemaUpdateNow
+schemaUpdateNow: 1
+-
+
+dn: CN=sudoRole,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: classSchema
+cn: sudoRole
+distinguishedName: CN=sudoRole,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+possSuperiors: container
+possSuperiors: top
+subClassOf: top
+governsID: 1.3.6.1.4.1.15953.9.2.1
+mayContain: sudoCommand
+mayContain: sudoHost
+mayContain: sudoOption
+mayContain: sudoRunAs
+mayContain: sudoRunAsUser
+mayContain: sudoRunAsGroup
+mayContain: sudoUser
+mayContain: sudoNotBefore
+mayContain: sudoNotAfter
+mayContain: sudoOrder
+rDNAttID: cn
+showInAdvancedViewOnly: FALSE
+adminDisplayName: sudoRole
+adminDescription: Sudoer Entries
+objectClassCategory: 1
+lDAPDisplayName: sudoRole
+name: sudoRole
+schemaIDGUID:: SQn432lnZ0+ukbdh3+gN3w==
+systemOnly: FALSE
+objectCategory: CN=Class-Schema,CN=Schema,CN=Configuration,DC=X
+defaultObjectCategory: CN=sudoRole,CN=Schema,CN=Configuration,DC=X
diff --git a/doc/schema.OpenLDAP b/doc/schema.OpenLDAP
new file mode 100644
index 0000000..e1d525f
--- /dev/null
+++ b/doc/schema.OpenLDAP
@@ -0,0 +1,78 @@
+#
+# OpenLDAP schema file for Sudo
+# Save as /etc/openldap/schema/sudo.schema and restart slapd.
+# For a version that uses online configuration, see schema.olcSudo.
+#
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.1
+ NAME 'sudoUser'
+ DESC 'User(s) who may run sudo'
+ EQUALITY caseExactIA5Match
+ SUBSTR caseExactIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.2
+ NAME 'sudoHost'
+ DESC 'Host(s) who may run sudo'
+ EQUALITY caseExactIA5Match
+ SUBSTR caseExactIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.3
+ NAME 'sudoCommand'
+ DESC 'Command(s) to be executed by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.4
+ NAME 'sudoRunAs'
+ DESC 'User(s) impersonated by sudo (deprecated)'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.5
+ NAME 'sudoOption'
+ DESC 'Options(s) followed by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.6
+ NAME 'sudoRunAsUser'
+ DESC 'User(s) impersonated by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.7
+ NAME 'sudoRunAsGroup'
+ DESC 'Group(s) impersonated by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.8
+ NAME 'sudoNotBefore'
+ DESC 'Start of time interval for which the entry is valid'
+ EQUALITY generalizedTimeMatch
+ ORDERING generalizedTimeOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.9
+ NAME 'sudoNotAfter'
+ DESC 'End of time interval for which the entry is valid'
+ EQUALITY generalizedTimeMatch
+ ORDERING generalizedTimeOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.10
+ NAME 'sudoOrder'
+ DESC 'an integer to order the sudoRole entries'
+ EQUALITY integerMatch
+ ORDERING integerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL
+ DESC 'Sudoer Entries'
+ MUST ( cn )
+ MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $
+ sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotBefore $
+ sudoNotAfter $ description )
+ )
diff --git a/doc/schema.iPlanet b/doc/schema.iPlanet
new file mode 100644
index 0000000..e512864
--- /dev/null
+++ b/doc/schema.iPlanet
@@ -0,0 +1,12 @@
+dn: cn=schema
+attributeTypes: ( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
+attributeTypes: ( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
+attributeTypes: ( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Command(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
+attributeTypes: ( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(s) impersonated by sudo (deprecated)' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
+attributeTypes: ( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Options(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
+attributeTypes: ( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'User(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
+attributeTypes: ( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Group(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
+attributeTypes: ( 1.3.6.1.4.1.15953.9.1.8 NAME 'sudoNotBefore' DESC 'Start of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
+attributeTypes: ( 1.3.6.1.4.1.15953.9.1.9 NAME 'sudoNotAfter' DESC 'End of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
+attributeTypes: ( 1.3.6.1.4.1.15953.9.1.10 NAME 'sudoOrder' DESC 'an integer to order the sudoRole entries' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+objectClasses: ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL DESC 'Sudoer Entries' MUST ( cn ) MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotBefore $ sudoNotAfter $ description ) X-ORIGIN 'SUDO' )
diff --git a/doc/schema.olcSudo b/doc/schema.olcSudo
new file mode 100644
index 0000000..8748dfc
--- /dev/null
+++ b/doc/schema.olcSudo
@@ -0,0 +1,79 @@
+dn: cn=sudoschema,cn=schema,cn=config
+objectClass: olcSchemaConfig
+cn: sudoschema
+#
+# OpenLDAP schema file for Sudo in on-line configuration (OLC) format.
+# Import using ldapadd or another suitable LDAP browser.
+# Converted to OLC format by Frederic Pasteleurs <frederic@askarel.be>
+#
+olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.1
+ NAME 'sudoUser'
+ DESC 'User(s) who may run sudo'
+ EQUALITY caseExactIA5Match
+ SUBSTR caseExactIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+#
+olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.2
+ NAME 'sudoHost'
+ DESC 'Host(s) who may run sudo'
+ EQUALITY caseExactIA5Match
+ SUBSTR caseExactIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+#
+olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.3
+ NAME 'sudoCommand'
+ DESC 'Command(s) to be executed by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+#
+olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.4
+ NAME 'sudoRunAs'
+ DESC 'User(s) impersonated by sudo (deprecated)'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+#
+olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.5
+ NAME 'sudoOption'
+ DESC 'Options(s) followed by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+#
+olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.6
+ NAME 'sudoRunAsUser'
+ DESC 'User(s) impersonated by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+#
+olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.7
+ NAME 'sudoRunAsGroup'
+ DESC 'Group(s) impersonated by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+#
+olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.8
+ NAME 'sudoNotBefore'
+ DESC 'Start of time interval for which the entry is valid'
+ EQUALITY generalizedTimeMatch
+ ORDERING generalizedTimeOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
+#
+olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.9
+ NAME 'sudoNotAfter'
+ DESC 'End of time interval for which the entry is valid'
+ EQUALITY generalizedTimeMatch
+ ORDERING generalizedTimeOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
+#
+olcattributeTypes: ( 1.3.6.1.4.1.15953.9.1.10
+ NAME 'sudoOrder'
+ DESC 'an integer to order the sudoRole entries'
+ EQUALITY integerMatch
+ ORDERING integerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+#
+olcobjectclasses: ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL
+ DESC 'Sudoer Entries'
+ MUST ( cn )
+ MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotBefore $ sudoNotAfter $
+ description )
+ )
diff --git a/doc/sudo.cat b/doc/sudo.cat
new file mode 100644
index 0000000..6d7671b
--- /dev/null
+++ b/doc/sudo.cat
@@ -0,0 +1,741 @@
+SUDO(1m) System Manager's Manual SUDO(1m)
+
+NNAAMMEE
+ ssuuddoo, ssuuddooeeddiitt - execute a command as another user
+
+SSYYNNOOPPSSIISS
+ ssuuddoo --hh | --KK | --kk | --VV
+ ssuuddoo --vv [--AAkknnSS] [--aa _t_y_p_e] [--gg _g_r_o_u_p] [--hh _h_o_s_t] [--pp _p_r_o_m_p_t] [--uu _u_s_e_r]
+ ssuuddoo --ll [--AAkknnSS] [--aa _t_y_p_e] [--gg _g_r_o_u_p] [--hh _h_o_s_t] [--pp _p_r_o_m_p_t] [--UU _u_s_e_r]
+ [--uu _u_s_e_r] [_c_o_m_m_a_n_d]
+ ssuuddoo [--AAbbEEHHnnPPSS] [--aa _t_y_p_e] [--CC _n_u_m] [--cc _c_l_a_s_s] [--gg _g_r_o_u_p] [--hh _h_o_s_t]
+ [--pp _p_r_o_m_p_t] [--rr _r_o_l_e] [--tt _t_y_p_e] [--TT _t_i_m_e_o_u_t] [--uu _u_s_e_r] [_V_A_R=_v_a_l_u_e]
+ [--ii | --ss] [_c_o_m_m_a_n_d]
+ ssuuddooeeddiitt [--AAkknnSS] [--aa _t_y_p_e] [--CC _n_u_m] [--cc _c_l_a_s_s] [--gg _g_r_o_u_p] [--hh _h_o_s_t]
+ [--pp _p_r_o_m_p_t] [--TT _t_i_m_e_o_u_t] [--uu _u_s_e_r] _f_i_l_e _._._.
+
+DDEESSCCRRIIPPTTIIOONN
+ ssuuddoo allows a permitted user to execute a _c_o_m_m_a_n_d as the superuser or
+ another user, as specified by the security policy. The invoking user's
+ real (_n_o_t effective) user ID is used to determine the user name with
+ which to query the security policy.
+
+ ssuuddoo supports a plugin architecture for security policies and
+ input/output logging. Third parties can develop and distribute their own
+ policy and I/O logging plugins to work seamlessly with the ssuuddoo front
+ end. The default security policy is _s_u_d_o_e_r_s, which is configured via the
+ file _/_e_t_c_/_s_u_d_o_e_r_s, or via LDAP. See the _P_l_u_g_i_n_s section for more
+ information.
+
+ The security policy determines what privileges, if any, a user has to run
+ ssuuddoo. The policy may require that users authenticate themselves with a
+ password or another authentication mechanism. If authentication is
+ required, ssuuddoo will exit if the user's password is not entered within a
+ configurable time limit. This limit is policy-specific; the default
+ password prompt timeout for the _s_u_d_o_e_r_s security policy is 5 minutes.
+
+ Security policies may support credential caching to allow the user to run
+ ssuuddoo again for a period of time without requiring authentication. The
+ _s_u_d_o_e_r_s policy caches credentials for 5 minutes, unless overridden in
+ sudoers(4). By running ssuuddoo with the --vv option, a user can update the
+ cached credentials without running a _c_o_m_m_a_n_d.
+
+ When invoked as ssuuddooeeddiitt, the --ee option (described below), is implied.
+
+ Security policies may log successful and failed attempts to use ssuuddoo. If
+ an I/O plugin is configured, the running command's input and output may
+ be logged as well.
+
+ The options are as follows:
+
+ --AA, ----aasskkppaassss
+ Normally, if ssuuddoo requires a password, it will read it from
+ the user's terminal. If the --AA (_a_s_k_p_a_s_s) option is
+ specified, a (possibly graphical) helper program is executed
+ to read the user's password and output the password to the
+ standard output. If the SUDO_ASKPASS environment variable is
+ set, it specifies the path to the helper program. Otherwise,
+ if sudo.conf(4) contains a line specifying the askpass
+ program, that value will be used. For example:
+
+ # Path to askpass helper program
+ Path askpass /usr/X11R6/bin/ssh-askpass
+
+ If no askpass program is available, ssuuddoo will exit with an
+ error.
+
+ --aa _t_y_p_e, ----aauutthh--ttyyppee=_t_y_p_e
+ Use the specified BSD authentication _t_y_p_e when validating the
+ user, if allowed by _/_e_t_c_/_l_o_g_i_n_._c_o_n_f. The system
+ administrator may specify a list of sudo-specific
+ authentication methods by adding an "auth-sudo" entry in
+ _/_e_t_c_/_l_o_g_i_n_._c_o_n_f. This option is only available on systems
+ that support BSD authentication.
+
+ --bb, ----bbaacckkggrroouunndd
+ Run the given command in the background. Note that it is not
+ possible to use shell job control to manipulate background
+ processes started by ssuuddoo. Most interactive commands will
+ fail to work properly in background mode.
+
+ --CC _n_u_m, ----cclloossee--ffrroomm=_n_u_m
+ Close all file descriptors greater than or equal to _n_u_m
+ before executing a command. Values less than three are not
+ permitted. By default, ssuuddoo will close all open file
+ descriptors other than standard input, standard output and
+ standard error when executing a command. The security policy
+ may restrict the user's ability to use this option. The
+ _s_u_d_o_e_r_s policy only permits use of the --CC option when the
+ administrator has enabled the _c_l_o_s_e_f_r_o_m___o_v_e_r_r_i_d_e option.
+
+ --cc _c_l_a_s_s, ----llooggiinn--ccllaassss=_c_l_a_s_s
+ Run the command with resource limits and scheduling priority
+ of the specified login _c_l_a_s_s. The _c_l_a_s_s argument can be
+ either a class name as defined in _/_e_t_c_/_l_o_g_i_n_._c_o_n_f, or a
+ single `-' character. If _c_l_a_s_s is --, the default login class
+ of the target user will be used. Otherwise, the command must
+ be run as the superuser (user ID 0), or ssuuddoo must be run from
+ a shell that is already running as the superuser. If the
+ command is being run as a login shell, additional
+ _/_e_t_c_/_l_o_g_i_n_._c_o_n_f settings, such as the umask and environment
+ variables, will be applied, if present. This option is only
+ available on systems with BSD login classes.
+
+ --EE, ----pprreesseerrvvee--eennvv
+ Indicates to the security policy that the user wishes to
+ preserve their existing environment variables. The security
+ policy may return an error if the user does not have
+ permission to preserve the environment.
+
+ ----pprreesseerrvvee--eennvv==lliisstt
+ Indicates to the security policy that the user wishes to add
+ the comma-separated list of environment variables to those
+ preserved from the user's environment. The security policy
+ may return an error if the user does not have permission to
+ preserve the environment.
+
+ --ee, ----eeddiitt Edit one or more files instead of running a command. In lieu
+ of a path name, the string "sudoedit" is used when consulting
+ the security policy. If the user is authorized by the
+ policy, the following steps are taken:
+
+ 1. Temporary copies are made of the files to be edited
+ with the owner set to the invoking user.
+
+ 2. The editor specified by the policy is run to edit the
+ temporary files. The _s_u_d_o_e_r_s policy uses the
+ SUDO_EDITOR, VISUAL and EDITOR environment variables
+ (in that order). If none of SUDO_EDITOR, VISUAL or
+ EDITOR are set, the first program listed in the _e_d_i_t_o_r
+ sudoers(4) option is used.
+
+ 3. If they have been modified, the temporary files are
+ copied back to their original location and the
+ temporary versions are removed.
+
+ To help prevent the editing of unauthorized files, the
+ following restrictions are enforced unless explicitly allowed
+ by the security policy:
+
+ ++oo Symbolic links may not be edited (version 1.8.15 and
+ higher).
+
+ ++oo Symbolic links along the path to be edited are not
+ followed when the parent directory is writable by the
+ invoking user unless that user is root (version 1.8.16
+ and higher).
+
+ ++oo Files located in a directory that is writable by the
+ invoking user may not be edited unless that user is root
+ (version 1.8.16 and higher).
+
+ Users are never allowed to edit device special files.
+
+ If the specified file does not exist, it will be created.
+ Note that unlike most commands run by _s_u_d_o, the editor is run
+ with the invoking user's environment unmodified. If, for
+ some reason, ssuuddoo is unable to update a file with its edited
+ version, the user will receive a warning and the edited copy
+ will remain in a temporary file.
+
+ --gg _g_r_o_u_p, ----ggrroouupp=_g_r_o_u_p
+ Run the command with the primary group set to _g_r_o_u_p instead
+ of the primary group specified by the target user's password
+ database entry. The _g_r_o_u_p may be either a group name or a
+ numeric group ID (GID) prefixed with the `#' character (e.g.,
+ #0 for GID 0). When running a command as a GID, many shells
+ require that the `#' be escaped with a backslash (`\'). If
+ no --uu option is specified, the command will be run as the
+ invoking user. In either case, the primary group will be set
+ to _g_r_o_u_p. The _s_u_d_o_e_r_s policy permits any of the target
+ user's groups to be specified via the --gg option as long as
+ the --PP option is not in use.
+
+ --HH, ----sseett--hhoommee
+ Request that the security policy set the HOME environment
+ variable to the home directory specified by the target user's
+ password database entry. Depending on the policy, this may
+ be the default behavior.
+
+ --hh, ----hheellpp Display a short help message to the standard output and exit.
+
+ --hh _h_o_s_t, ----hhoosstt=_h_o_s_t
+ Run the command on the specified _h_o_s_t if the security policy
+ plugin supports remote commands. Note that the _s_u_d_o_e_r_s
+ plugin does not currently support running remote commands.
+ This may also be used in conjunction with the --ll option to
+ list a user's privileges for the remote host.
+
+ --ii, ----llooggiinn
+ Run the shell specified by the target user's password
+ database entry as a login shell. This means that login-
+ specific resource files such as _._p_r_o_f_i_l_e, _._b_a_s_h___p_r_o_f_i_l_e or
+ _._l_o_g_i_n will be read by the shell. If a command is specified,
+ it is passed to the shell for execution via the shell's --cc
+ option. If no command is specified, an interactive shell is
+ executed. ssuuddoo attempts to change to that user's home
+ directory before running the shell. The command is run with
+ an environment similar to the one a user would receive at log
+ in. Note that most shells behave differently when a command
+ is specified as compared to an interactive session; consult
+ the shell's manual for details. The _C_o_m_m_a_n_d _e_n_v_i_r_o_n_m_e_n_t
+ section in the sudoers(4) manual documents how the --ii option
+ affects the environment in which a command is run when the
+ _s_u_d_o_e_r_s policy is in use.
+
+ --KK, ----rreemmoovvee--ttiimmeessttaammpp
+ Similar to the --kk option, except that it removes the user's
+ cached credentials entirely and may not be used in
+ conjunction with a command or other option. This option does
+ not require a password. Not all security policies support
+ credential caching.
+
+ --kk, ----rreesseett--ttiimmeessttaammpp
+ When used without a command, invalidates the user's cached
+ credentials. In other words, the next time ssuuddoo is run a
+ password will be required. This option does not require a
+ password and was added to allow a user to revoke ssuuddoo
+ permissions from a _._l_o_g_o_u_t file.
+
+ When used in conjunction with a command or an option that may
+ require a password, this option will cause ssuuddoo to ignore the
+ user's cached credentials. As a result, ssuuddoo will prompt for
+ a password (if one is required by the security policy) and
+ will not update the user's cached credentials.
+
+ Not all security policies support credential caching.
+
+ --ll, ----lliisstt If no _c_o_m_m_a_n_d is specified, list the allowed (and forbidden)
+ commands for the invoking user (or the user specified by the
+ --UU option) on the current host. A longer list format is used
+ if this option is specified multiple times and the security
+ policy supports a verbose output format.
+
+ If a _c_o_m_m_a_n_d is specified and is permitted by the security
+ policy, the fully-qualified path to the command is displayed
+ along with any command line arguments. If a _c_o_m_m_a_n_d is
+ specified but not allowed by the policy, ssuuddoo will exit with
+ a status value of 1.
+
+ --nn, ----nnoonn--iinntteerraaccttiivvee
+ Avoid prompting the user for input of any kind. If a
+ password is required for the command to run, ssuuddoo will
+ display an error message and exit.
+
+ --PP, ----pprreesseerrvvee--ggrroouuppss
+ Preserve the invoking user's group vector unaltered. By
+ default, the _s_u_d_o_e_r_s policy will initialize the group vector
+ to the list of groups the target user is a member of. The
+ real and effective group IDs, however, are still set to match
+ the target user.
+
+ --pp _p_r_o_m_p_t, ----pprroommpptt=_p_r_o_m_p_t
+ Use a custom password prompt with optional escape sequences.
+ The following percent (`%') escape sequences are supported by
+ the _s_u_d_o_e_r_s policy:
+
+ %H expanded to the host name including the domain name (on
+ if the machine's host name is fully qualified or the _f_q_d_n
+ option is set in sudoers(4))
+
+ %h expanded to the local host name without the domain name
+
+ %p expanded to the name of the user whose password is being
+ requested (respects the _r_o_o_t_p_w, _t_a_r_g_e_t_p_w, and _r_u_n_a_s_p_w
+ flags in sudoers(4))
+
+ %U expanded to the login name of the user the command will
+ be run as (defaults to root unless the --uu option is also
+ specified)
+
+ %u expanded to the invoking user's login name
+
+ %% two consecutive `%' characters are collapsed into a
+ single `%' character
+
+ The custom prompt will override the default prompt specified
+ by either the security policy or the SUDO_PROMPT environment
+ variable. On systems that use PAM, the custom prompt will
+ also override the prompt specified by a PAM module unless the
+ _p_a_s_s_p_r_o_m_p_t___o_v_e_r_r_i_d_e flag is disabled in _s_u_d_o_e_r_s.
+
+ --rr _r_o_l_e, ----rroollee=_r_o_l_e
+ Run the command with an SELinux security context that
+ includes the specified _r_o_l_e.
+
+ --SS, ----ssttddiinn
+ Write the prompt to the standard error and read the password
+ from the standard input instead of using the terminal device.
+
+ --ss, ----sshheellll
+ Run the shell specified by the SHELL environment variable if
+ it is set or the shell specified by the invoking user's
+ password database entry. If a command is specified, it is
+ passed to the shell for execution via the shell's --cc option.
+ If no command is specified, an interactive shell is executed.
+ Note that most shells behave differently when a command is
+ specified as compared to an interactive session; consult the
+ shell's manual for details.
+
+ --tt _t_y_p_e, ----ttyyppee=_t_y_p_e
+ Run the command with an SELinux security context that
+ includes the specified _t_y_p_e. If no _t_y_p_e is specified, the
+ default type is derived from the role.
+
+ --UU _u_s_e_r, ----ootthheerr--uusseerr=_u_s_e_r
+ Used in conjunction with the --ll option to list the privileges
+ for _u_s_e_r instead of for the invoking user. The security
+ policy may restrict listing other users' privileges. The
+ _s_u_d_o_e_r_s policy only allows root or a user with the ALL
+ privilege on the current host to use this option.
+
+ --TT _t_i_m_e_o_u_t, ----ccoommmmaanndd--ttiimmeeoouutt=_t_i_m_e_o_u_t
+ Used to set a timeout for the command. If the timeout
+ expires before the command has exited, the command will be
+ terminated. The security policy may restrict the ability to
+ set command timeouts. The _s_u_d_o_e_r_s policy requires that user-
+ specified timeouts be explicitly enabled.
+
+ --uu _u_s_e_r, ----uusseerr=_u_s_e_r
+ Run the command as a user other than the default target user
+ (usually _r_o_o_t). The _u_s_e_r may be either a user name or a
+ numeric user ID (UID) prefixed with the `#' character (e.g.,
+ #0 for UID 0). When running commands as a UID, many shells
+ require that the `#' be escaped with a backslash (`\'). Some
+ security policies may restrict UIDs to those listed in the
+ password database. The _s_u_d_o_e_r_s policy allows UIDs that are
+ not in the password database as long as the _t_a_r_g_e_t_p_w option
+ is not set. Other security policies may not support this.
+
+ --VV, ----vveerrssiioonn
+ Print the ssuuddoo version string as well as the version string
+ of the security policy plugin and any I/O plugins. If the
+ invoking user is already root the --VV option will display the
+ arguments passed to configure when ssuuddoo was built and plugins
+ may display more verbose information such as default options.
+
+ --vv, ----vvaalliiddaattee
+ Update the user's cached credentials, authenticating the user
+ if necessary. For the _s_u_d_o_e_r_s plugin, this extends the ssuuddoo
+ timeout for another 5 minutes by default, but does not run a
+ command. Not all security policies support cached
+ credentials.
+
+ ---- The ---- option indicates that ssuuddoo should stop processing
+ command line arguments.
+
+ Environment variables to be set for the command may also be passed on the
+ command line in the form of _V_A_R=_v_a_l_u_e, e.g.,
+ LD_LIBRARY_PATH=_/_u_s_r_/_l_o_c_a_l_/_p_k_g_/_l_i_b. Variables passed on the command line
+ are subject to restrictions imposed by the security policy plugin. The
+ _s_u_d_o_e_r_s policy subjects variables passed on the command line to the same
+ restrictions as normal environment variables with one important
+ exception. If the _s_e_t_e_n_v option is set in _s_u_d_o_e_r_s, the command to be run
+ has the SETENV tag set or the command matched is ALL, the user may set
+ variables that would otherwise be forbidden. See sudoers(4) for more
+ information.
+
+CCOOMMMMAANNDD EEXXEECCUUTTIIOONN
+ When ssuuddoo executes a command, the security policy specifies the execution
+ environment for the command. Typically, the real and effective user and
+ group and IDs are set to match those of the target user, as specified in
+ the password database, and the group vector is initialized based on the
+ group database (unless the --PP option was specified).
+
+ The following parameters may be specified by security policy:
+
+ ++oo real and effective user ID
+
+ ++oo real and effective group ID
+
+ ++oo supplementary group IDs
+
+ ++oo the environment list
+
+ ++oo current working directory
+
+ ++oo file creation mode mask (umask)
+
+ ++oo SELinux role and type
+
+ ++oo Solaris project
+
+ ++oo Solaris privileges
+
+ ++oo BSD login class
+
+ ++oo scheduling priority (aka nice value)
+
+ PPrroocceessss mmooddeell
+ There are two distinct ways ssuuddoo can run a command.
+
+ If an I/O logging plugin is configured or if the security policy
+ explicitly requests it, a new pseudo-terminal ("pty") is allocated and
+ fork(2) is used to create a second ssuuddoo process, referred to as the
+ _m_o_n_i_t_o_r. The _m_o_n_i_t_o_r creates a new terminal session with itself as the
+ leader and the pty as its controlling terminal, calls fork(2), sets up
+ the execution environment as described above, and then uses the execve(2)
+ system call to run the command in the child process. The _m_o_n_i_t_o_r exists
+ to relay job control signals between the user's existing terminal and the
+ pty the command is being run in. This makes it possible to suspend and
+ resume the command. Without the monitor, the command would be in what
+ POSIX terms an "orphaned process group" and it would not receive any job
+ control signals from the kernel. When the command exits or is terminated
+ by a signal, the _m_o_n_i_t_o_r passes the command's exit status to the main
+ ssuuddoo process and exits. After receiving the command's exit status, the
+ main ssuuddoo passes the command's exit status to the security policy's close
+ function and exits.
+
+ If no pty is used, ssuuddoo calls fork(2), sets up the execution environment
+ as described above, and uses the execve(2) system call to run the command
+ in the child process. The main ssuuddoo process waits until the command has
+ completed, then passes the command's exit status to the security policy's
+ close function and exits. As a special case, if the policy plugin does
+ not define a close function, ssuuddoo will execute the command directly
+ instead of calling fork(2) first. The _s_u_d_o_e_r_s policy plugin will only
+ define a close function when I/O logging is enabled, a pty is required,
+ or the _p_a_m___s_e_s_s_i_o_n or _p_a_m___s_e_t_c_r_e_d options are enabled. Note that
+ _p_a_m___s_e_s_s_i_o_n and _p_a_m___s_e_t_c_r_e_d are enabled by default on systems using PAM.
+
+ SSiiggnnaall hhaannddlliinngg
+ When the command is run as a child of the ssuuddoo process, ssuuddoo will relay
+ signals it receives to the command. The SIGINT and SIGQUIT signals are
+ only relayed when the command is being run in a new pty or when the
+ signal was sent by a user process, not the kernel. This prevents the
+ command from receiving SIGINT twice each time the user enters control-C.
+ Some signals, such as SIGSTOP and SIGKILL, cannot be caught and thus will
+ not be relayed to the command. As a general rule, SIGTSTP should be used
+ instead of SIGSTOP when you wish to suspend a command being run by ssuuddoo.
+
+ As a special case, ssuuddoo will not relay signals that were sent by the
+ command it is running. This prevents the command from accidentally
+ killing itself. On some systems, the reboot(1m) command sends SIGTERM to
+ all non-system processes other than itself before rebooting the system.
+ This prevents ssuuddoo from relaying the SIGTERM signal it received back to
+ reboot(1m), which might then exit before the system was actually rebooted,
+ leaving it in a half-dead state similar to single user mode. Note,
+ however, that this check only applies to the command run by ssuuddoo and not
+ any other processes that the command may create. As a result, running a
+ script that calls reboot(1m) or shutdown(1m) via ssuuddoo may cause the system
+ to end up in this undefined state unless the reboot(1m) or shutdown(1m) are
+ run using the eexxeecc() family of functions instead of ssyysstteemm() (which
+ interposes a shell between the command and the calling process).
+
+ If no I/O logging plugins are loaded and the policy plugin has not
+ defined a cclloossee() function, set a command timeout or required that the
+ command be run in a new pty, ssuuddoo may execute the command directly
+ instead of running it as a child process.
+
+ PPlluuggiinnss
+ Plugins may be specified via Plugin directives in the sudo.conf(4) file.
+ They may be loaded as dynamic shared objects (on systems that support
+ them), or compiled directly into the ssuuddoo binary. If no sudo.conf(4)
+ file is present, or it contains no Plugin lines, ssuuddoo will use the
+ traditional _s_u_d_o_e_r_s security policy and I/O logging. See the
+ sudo.conf(4) manual for details of the _/_e_t_c_/_s_u_d_o_._c_o_n_f file and the
+ sudo_plugin(4) manual for more information about the ssuuddoo plugin
+ architecture.
+
+EEXXIITT VVAALLUUEE
+ Upon successful execution of a command, the exit status from ssuuddoo will be
+ the exit status of the program that was executed. If the command
+ terminated due to receipt of a signal, ssuuddoo will send itself the same
+ signal that terminated the command.
+
+ If the --ll option was specified without a command, ssuuddoo will exit with a
+ value of 0 if the user is allowed to run ssuuddoo and they authenticated
+ successfully (as required by the security policy). If a command is
+ specified with the --ll option, the exit value will only be 0 if the
+ command is permitted by the security policy, otherwise it will be 1.
+
+ If there is an authentication failure, a configuration/permission problem
+ or if the given command cannot be executed, ssuuddoo exits with a value of 1.
+ In the latter case, the error string is printed to the standard error.
+ If ssuuddoo cannot stat(2) one or more entries in the user's PATH, an error
+ is printed to the standard error. (If the directory does not exist or if
+ it is not really a directory, the entry is ignored and no error is
+ printed.) This should not happen under normal circumstances. The most
+ common reason for stat(2) to return "permission denied" is if you are
+ running an automounter and one of the directories in your PATH is on a
+ machine that is currently unreachable.
+
+SSEECCUURRIITTYY NNOOTTEESS
+ ssuuddoo tries to be safe when executing external commands.
+
+ To prevent command spoofing, ssuuddoo checks "." and "" (both denoting
+ current directory) last when searching for a command in the user's PATH
+ (if one or both are in the PATH). Note, however, that the actual PATH
+ environment variable is _n_o_t modified and is passed unchanged to the
+ program that ssuuddoo executes.
+
+ Users should _n_e_v_e_r be granted ssuuddoo privileges to execute files that are
+ writable by the user or that reside in a directory that is writable by
+ the user. If the user can modify or replace the command there is no way
+ to limit what additional commands they can run.
+
+ Please note that ssuuddoo will normally only log the command it explicitly
+ runs. If a user runs a command such as sudo su or sudo sh, subsequent
+ commands run from that shell are not subject to ssuuddoo's security policy.
+ The same is true for commands that offer shell escapes (including most
+ editors). If I/O logging is enabled, subsequent commands will have their
+ input and/or output logged, but there will not be traditional logs for
+ those commands. Because of this, care must be taken when giving users
+ access to commands via ssuuddoo to verify that the command does not
+ inadvertently give the user an effective root shell. For more
+ information, please see the _P_r_e_v_e_n_t_i_n_g _s_h_e_l_l _e_s_c_a_p_e_s section in
+ sudoers(4).
+
+ To prevent the disclosure of potentially sensitive information, ssuuddoo
+ disables core dumps by default while it is executing (they are re-enabled
+ for the command that is run). This historical practice dates from a time
+ when most operating systems allowed setuid processes to dump core by
+ default. To aid in debugging ssuuddoo crashes, you may wish to re-enable
+ core dumps by setting "disable_coredump" to false in the sudo.conf(4)
+ file as follows:
+
+ Set disable_coredump false
+
+ See the sudo.conf(4) manual for more information.
+
+EENNVVIIRROONNMMEENNTT
+ ssuuddoo utilizes the following environment variables. The security policy
+ has control over the actual content of the command's environment.
+
+ EDITOR Default editor to use in --ee (sudoedit) mode if neither
+ SUDO_EDITOR nor VISUAL is set.
+
+ MAIL Set to the mail spool of the target user when the --ii
+ option is specified or when _e_n_v___r_e_s_e_t is enabled in
+ _s_u_d_o_e_r_s (unless MAIL is present in the _e_n_v___k_e_e_p list).
+
+ HOME Set to the home directory of the target user when the --ii
+ or --HH options are specified, when the --ss option is
+ specified and _s_e_t___h_o_m_e is set in _s_u_d_o_e_r_s, when
+ _a_l_w_a_y_s___s_e_t___h_o_m_e is enabled in _s_u_d_o_e_r_s, or when _e_n_v___r_e_s_e_t
+ is enabled in _s_u_d_o_e_r_s and _H_O_M_E is not present in the
+ _e_n_v___k_e_e_p list.
+
+ LOGNAME Set to the login name of the target user when the --ii
+ option is specified, when the _s_e_t___l_o_g_n_a_m_e option is
+ enabled in _s_u_d_o_e_r_s or when the _e_n_v___r_e_s_e_t option is
+ enabled in _s_u_d_o_e_r_s (unless LOGNAME is present in the
+ _e_n_v___k_e_e_p list).
+
+ PATH May be overridden by the security policy.
+
+ SHELL Used to determine shell to run with --ss option.
+
+ SUDO_ASKPASS Specifies the path to a helper program used to read the
+ password if no terminal is available or if the --AA option
+ is specified.
+
+ SUDO_COMMAND Set to the command run by sudo.
+
+ SUDO_EDITOR Default editor to use in --ee (sudoedit) mode.
+
+ SUDO_GID Set to the group ID of the user who invoked sudo.
+
+ SUDO_PROMPT Used as the default password prompt unless the --pp option
+ was specified.
+
+ SUDO_PS1 If set, PS1 will be set to its value for the program
+ being run.
+
+ SUDO_UID Set to the user ID of the user who invoked sudo.
+
+ SUDO_USER Set to the login name of the user who invoked sudo.
+
+ USER Set to the same value as LOGNAME, described above.
+
+ VISUAL Default editor to use in --ee (sudoedit) mode if
+ SUDO_EDITOR is not set.
+
+FFIILLEESS
+ _/_e_t_c_/_s_u_d_o_._c_o_n_f ssuuddoo front end configuration
+
+EEXXAAMMPPLLEESS
+ Note: the following examples assume a properly configured security
+ policy.
+
+ To get a file listing of an unreadable directory:
+
+ $ sudo ls /usr/local/protected
+
+ To list the home directory of user yaz on a machine where the file system
+ holding ~yaz is not exported as root:
+
+ $ sudo -u yaz ls ~yaz
+
+ To edit the _i_n_d_e_x_._h_t_m_l file as user www:
+
+ $ sudoedit -u www ~www/htdocs/index.html
+
+ To view system logs only accessible to root and users in the adm group:
+
+ $ sudo -g adm more /var/log/syslog
+
+ To run an editor as jim with a different primary group:
+
+ $ sudoedit -u jim -g audio ~jim/sound.txt
+
+ To shut down a machine:
+
+ $ sudo shutdown -r +15 "quick reboot"
+
+ To make a usage listing of the directories in the /home partition. Note
+ that this runs the commands in a sub-shell to make the cd and file
+ redirection work.
+
+ $ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
+
+DDIIAAGGNNOOSSTTIICCSS
+ Error messages produced by ssuuddoo include:
+
+ editing files in a writable directory is not permitted
+ By default, ssuuddooeeddiitt does not permit editing a file when any of the
+ parent directories are writable by the invoking user. This avoids
+ a race condition that could allow the user to overwrite an
+ arbitrary file. See the _s_u_d_o_e_d_i_t___c_h_e_c_k_d_i_r option in sudoers(4) for
+ more information.
+
+ editing symbolic links is not permitted
+ By default, ssuuddooeeddiitt does not follow symbolic links when opening
+ files. See the _s_u_d_o_e_d_i_t___f_o_l_l_o_w option in sudoers(4) for more
+ information.
+
+ effective uid is not 0, is sudo installed setuid root?
+ ssuuddoo was not run with root privileges. The ssuuddoo binary must be
+ owned by the root user and have the Set-user-ID bit set. Also, it
+ must not be located on a file system mounted with the `nosuid'
+ option or on an NFS file system that maps uid 0 to an unprivileged
+ uid.
+
+ effective uid is not 0, is sudo on a file system with the 'nosuid' option
+ set or an NFS file system without root privileges?
+ ssuuddoo was not run with root privileges. The ssuuddoo binary has the
+ proper owner and permissions but it still did not run with root
+ privileges. The most common reason for this is that the file
+ system the ssuuddoo binary is located on is mounted with the `nosuid'
+ option or it is an NFS file system that maps uid 0 to an
+ unprivileged uid.
+
+ fatal error, unable to load plugins
+ An error occurred while loading or initializing the plugins
+ specified in sudo.conf(4).
+
+ invalid environment variable name
+ One or more environment variable names specified via the --EE option
+ contained an equal sign (`='). The arguments to the --EE option
+ should be environment variable names without an associated value.
+
+ no password was provided
+ When ssuuddoo tried to read the password, it did not receive any
+ characters. This may happen if no terminal is available (or the --SS
+ option is specified) and the standard input has been redirected
+ from _/_d_e_v_/_n_u_l_l.
+
+ no tty present and no askpass program specified
+ ssuuddoo needs to read the password but there is no mechanism available
+ to do so. A terminal is not present to read the password from,
+ ssuuddoo has not been configured to read from the standard input, and
+ no askpass program has been specified either via the --AA option or
+ the SUDO_ASKPASS environment variable.
+
+ no writable temporary directory found
+ ssuuddooeeddiitt was unable to find a usable temporary directory in which
+ to store its intermediate files.
+
+ sudo must be owned by uid 0 and have the setuid bit set
+ ssuuddoo was not run with root privileges. The ssuuddoo binary does not
+ have the correct owner or permissions. It must be owned by the
+ root user and have the Set-user-ID bit set.
+
+ sudoedit is not supported on this platform
+ It is only possible to run ssuuddooeeddiitt on systems that support setting
+ the effective user-ID.
+
+ timed out reading password
+ The user did not enter a password before the password timeout (5
+ minutes by default) expired.
+
+ you do not exist in the passwd database
+ Your user ID does not appear in the system passwd database.
+
+ you may not specify environment variables in edit mode
+ It is only possible to specify environment variables when running a
+ command. When editing a file, the editor is run with the user's
+ environment unmodified.
+
+SSEEEE AALLSSOO
+ su(1), stat(2), login_cap(3), passwd(4), sudo.conf(4), sudo_plugin(4),
+ sudoers(4), sudoreplay(1m), visudo(1m)
+
+HHIISSTTOORRYY
+ See the HISTORY file in the ssuuddoo distribution
+ (https://www.sudo.ws/history.html) for a brief history of sudo.
+
+AAUUTTHHOORRSS
+ Many people have worked on ssuuddoo over the years; this version consists of
+ code written primarily by:
+
+ Todd C. Miller
+
+ See the CONTRIBUTORS file in the ssuuddoo distribution
+ (https://www.sudo.ws/contributors.html) for an exhaustive list of people
+ who have contributed to ssuuddoo.
+
+CCAAVVEEAATTSS
+ There is no easy way to prevent a user from gaining a root shell if that
+ user is allowed to run arbitrary commands via ssuuddoo. Also, many programs
+ (such as editors) allow the user to run commands via shell escapes, thus
+ avoiding ssuuddoo's checks. However, on most systems it is possible to
+ prevent shell escapes with the sudoers(4) plugin's _n_o_e_x_e_c functionality.
+
+ It is not meaningful to run the cd command directly via sudo, e.g.,
+
+ $ sudo cd /usr/local/protected
+
+ since when the command exits the parent process (your shell) will still
+ be the same. Please see the _E_X_A_M_P_L_E_S section for more information.
+
+ Running shell scripts via ssuuddoo can expose the same kernel bugs that make
+ setuid shell scripts unsafe on some operating systems (if your OS has a
+ /dev/fd/ directory, setuid shell scripts are generally safe).
+
+BBUUGGSS
+ If you feel you have found a bug in ssuuddoo, please submit a bug report at
+ https://bugzilla.sudo.ws/
+
+SSUUPPPPOORRTT
+ Limited free support is available via the sudo-users mailing list, see
+ https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search
+ the archives.
+
+DDIISSCCLLAAIIMMEERR
+ ssuuddoo is provided "AS IS" and any express or implied warranties,
+ including, but not limited to, the implied warranties of merchantability
+ and fitness for a particular purpose are disclaimed. See the LICENSE
+ file distributed with ssuuddoo or https://www.sudo.ws/license.html for
+ complete details.
+
+Sudo 1.8.26 November 25, 2018 Sudo 1.8.26
diff --git a/doc/sudo.conf.cat b/doc/sudo.conf.cat
new file mode 100644
index 0000000..b43217b
--- /dev/null
+++ b/doc/sudo.conf.cat
@@ -0,0 +1,434 @@
+SUDO.CONF(4) File Formats Manual SUDO.CONF(4)
+
+NNAAMMEE
+ ssuuddoo..ccoonnff - configuration for sudo front end
+
+DDEESSCCRRIIPPTTIIOONN
+ The ssuuddoo..ccoonnff file is used to configure the ssuuddoo front end. It specifies
+ the security policy and I/O logging plugins, debug flags as well as
+ plugin-agnostic path names and settings.
+
+ The ssuuddoo..ccoonnff file supports the following directives, described in detail
+ below.
+
+ Plugin a security policy or I/O logging plugin
+
+ Path a plugin-agnostic path
+
+ Set a front end setting, such as _d_i_s_a_b_l_e___c_o_r_e_d_u_m_p or _g_r_o_u_p___s_o_u_r_c_e
+
+ Debug debug flags to aid in debugging ssuuddoo, ssuuddoorreeppllaayy, vviissuuddoo, and
+ the ssuuddooeerrss plugin.
+
+ The pound sign (`#') is used to indicate a comment. Both the comment
+ character and any text after it, up to the end of the line, are ignored.
+
+ Long lines can be continued with a backslash (`\') as the last character
+ on the line. Note that leading white space is removed from the beginning
+ of lines even when the continuation character is used.
+
+ Non-comment lines that don't begin with Plugin, Path, Debug, or Set are
+ silently ignored.
+
+ The ssuuddoo..ccoonnff file is always parsed in the "C" locale.
+
+ PPlluuggiinn ccoonnffiigguurraattiioonn
+ ssuuddoo supports a plugin architecture for security policies and
+ input/output logging. Third parties can develop and distribute their own
+ policy and I/O logging plugins to work seamlessly with the ssuuddoo front
+ end. Plugins are dynamically loaded based on the contents of ssuuddoo..ccoonnff.
+
+ A Plugin line consists of the Plugin keyword, followed by the _s_y_m_b_o_l___n_a_m_e
+ and the _p_a_t_h to the dynamic shared object that contains the plugin. The
+ _s_y_m_b_o_l___n_a_m_e is the name of the struct policy_plugin or struct io_plugin
+ symbol contained in the plugin. The _p_a_t_h may be fully qualified or
+ relative. If not fully qualified, it is relative to the directory
+ specified by the _p_l_u_g_i_n___d_i_r Path setting, which defaults to
+ _/_u_s_r_/_l_o_c_a_l_/_l_i_b_e_x_e_c_/_s_u_d_o. In other words:
+
+ Plugin sudoers_policy sudoers.so
+
+ is equivalent to:
+
+ Plugin sudoers_policy /usr/local/libexec/sudo/sudoers.so
+
+ If the plugin was compiled statically into the ssuuddoo binary instead of
+ being installed as a dynamic shared object, the _p_a_t_h should be specified
+ without a leading directory, as it does not actually exist in the file
+ system. For example:
+
+ Plugin sudoers_policy sudoers.so
+
+ Starting with ssuuddoo 1.8.5, any additional parameters after the _p_a_t_h are
+ passed as arguments to the plugin's _o_p_e_n function. For example, to
+ override the compile-time default sudoers file mode:
+
+ Plugin sudoers_policy sudoers.so sudoers_mode=0440
+
+ See the sudoers(4) manual for a list of supported arguments.
+
+ The same dynamic shared object may contain multiple plugins, each with a
+ different symbol name. The file must be owned by uid 0 and only writable
+ by its owner. Because of ambiguities that arise from composite policies,
+ only a single policy plugin may be specified. This limitation does not
+ apply to I/O plugins.
+
+ If no ssuuddoo..ccoonnff file is present, or if it contains no Plugin lines, the
+ ssuuddooeerrss plugin will be used as the default security policy and for I/O
+ logging (if enabled by the policy). This is equivalent to the following:
+
+ Plugin sudoers_policy sudoers.so
+ Plugin sudoers_io sudoers.so
+
+ For more information on the ssuuddoo plugin architecture, see the
+ sudo_plugin(4) manual.
+
+ PPaatthh sseettttiinnggss
+ A Path line consists of the Path keyword, followed by the name of the
+ path to set and its value. For example:
+
+ Path noexec /usr/local/libexec/sudo/sudo_noexec.so
+ Path askpass /usr/X11R6/bin/ssh-askpass
+
+ If no path name is specified, features relying on the specified setting
+ will be disabled. Disabling Path settings is only supported in ssuuddoo
+ version 1.8.16 and higher.
+
+ The following plugin-agnostic paths may be set in the _/_e_t_c_/_s_u_d_o_._c_o_n_f
+ file:
+
+ askpass The fully qualified path to a helper program used to read the
+ user's password when no terminal is available. This may be the
+ case when ssuuddoo is executed from a graphical (as opposed to
+ text-based) application. The program specified by _a_s_k_p_a_s_s
+ should display the argument passed to it as the prompt and
+ write the user's password to the standard output. The value of
+ _a_s_k_p_a_s_s may be overridden by the SUDO_ASKPASS environment
+ variable.
+
+ devsearch
+ An ordered, colon-separated search path of directories to look
+ in for device nodes. This is used when mapping the process's
+ tty device number to a device name on systems that do not
+ provide such a mechanism. Sudo will _n_o_t recurse into sub-
+ directories. If terminal devices may be located in a sub-
+ directory of _/_d_e_v, that path must be explicitly listed in
+ _d_e_v_s_e_a_r_c_h. The default value is:
+ /dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev
+
+ This option is ignored on systems that support either the
+ ddeevvnnaammee() or __ttttyynnaammee__ddeevv() functions, for example BSD, macOS
+ and Solaris.
+
+ noexec The fully-qualified path to a shared library containing
+ wrappers for the eexxeeccll(), eexxeeccllee(), eexxeeccllpp(), eexxeecctt(), eexxeeccvv(),
+ eexxeeccvvee(), eexxeeccvvPP(), eexxeeccvvpp(), eexxeeccvvppee(), ffeexxeeccvvee(), ppooppeenn(),
+ ppoossiixx__ssppaawwnn(), ppoossiixx__ssppaawwnnpp(), ssyysstteemm(), and wwoorrddeexxpp() library
+ functions that prevent the execution of further commands. This
+ is used to implement the _n_o_e_x_e_c functionality on systems that
+ support LD_PRELOAD or its equivalent. The default value is:
+ _/_u_s_r_/_l_o_c_a_l_/_l_i_b_e_x_e_c_/_s_u_d_o_/_s_u_d_o___n_o_e_x_e_c_._s_o.
+
+ plugin_dir
+ The default directory to use when searching for plugins that
+ are specified without a fully qualified path name. The default
+ value is _/_u_s_r_/_l_o_c_a_l_/_l_i_b_e_x_e_c_/_s_u_d_o.
+
+ sesh The fully-qualified path to the sseesshh binary. This setting is
+ only used when ssuuddoo is built with SELinux support. The default
+ value is _/_u_s_r_/_l_o_c_a_l_/_l_i_b_e_x_e_c_/_s_u_d_o_/_s_e_s_h.
+
+ OOtthheerr sseettttiinnggss
+ The ssuuddoo..ccoonnff file also supports the following front end settings:
+
+ disable_coredump
+ Core dumps of ssuuddoo itself are disabled by default to prevent
+ the disclosure of potentially sensitive information. To aid in
+ debugging ssuuddoo crashes, you may wish to re-enable core dumps by
+ setting "disable_coredump" to false in ssuuddoo..ccoonnff as follows:
+
+ Set disable_coredump false
+
+ All modern operating systems place restrictions on core dumps
+ from setuid processes like ssuuddoo so this option can be enabled
+ without compromising security. To actually get a ssuuddoo core
+ file you will likely need to enable core dumps for setuid
+ processes. On BSD and Linux systems this is accomplished in
+ the sysctl(1m) command. On Solaris, the coreadm(1m) command is
+ used to configure core dump behavior.
+
+ This setting is only available in ssuuddoo version 1.8.4 and
+ higher.
+
+ group_source
+ ssuuddoo passes the invoking user's group list to the policy and
+ I/O plugins. On most systems, there is an upper limit to the
+ number of groups that a user may belong to simultaneously
+ (typically 16 for compatibility with NFS). On systems with the
+ getconf(1) utility, running:
+ getconf NGROUPS_MAX
+ will return the maximum number of groups.
+
+ However, it is still possible to be a member of a larger number
+ of groups--they simply won't be included in the group list
+ returned by the kernel for the user. Starting with ssuuddoo
+ version 1.8.7, if the user's kernel group list has the maximum
+ number of entries, ssuuddoo will consult the group database
+ directly to determine the group list. This makes it possible
+ for the security policy to perform matching by group name even
+ when the user is a member of more than the maximum number of
+ groups.
+
+ The _g_r_o_u_p___s_o_u_r_c_e setting allows the administrator to change
+ this default behavior. Supported values for _g_r_o_u_p___s_o_u_r_c_e are:
+
+ static Use the static group list that the kernel returns.
+ Retrieving the group list this way is very fast but
+ it is subject to an upper limit as described above.
+ It is "static" in that it does not reflect changes to
+ the group database made after the user logs in. This
+ was the default behavior prior to ssuuddoo 1.8.7.
+
+ dynamic Always query the group database directly. It is
+ "dynamic" in that changes made to the group database
+ after the user logs in will be reflected in the group
+ list. On some systems, querying the group database
+ for all of a user's groups can be time consuming when
+ querying a network-based group database. Most
+ operating systems provide an efficient method of
+ performing such queries. Currently, ssuuddoo supports
+ efficient group queries on AIX, BSD, HP-UX, Linux and
+ Solaris.
+
+ adaptive Only query the group database if the static group
+ list returned by the kernel has the maximum number of
+ entries. This is the default behavior in ssuuddoo 1.8.7
+ and higher.
+
+ For example, to cause ssuuddoo to only use the kernel's static list
+ of groups for the user:
+
+ Set group_source static
+
+ This setting is only available in ssuuddoo version 1.8.7 and
+ higher.
+
+ max_groups
+ The maximum number of user groups to retrieve from the group
+ database. Values less than one will be ignored. This setting
+ is only used when querying the group database directly. It is
+ intended to be used on systems where it is not possible to
+ detect when the array to be populated with group entries is not
+ sufficiently large. By default, ssuuddoo will allocate four times
+ the system's maximum number of groups (see above) and retry
+ with double that number if the group database query fails.
+
+ This setting is only available in ssuuddoo version 1.8.7 and
+ higher. It should not be required in ssuuddoo versions 1.8.24 and
+ higher and may be removed in a later release.
+
+ probe_interfaces
+ By default, ssuuddoo will probe the system's network interfaces and
+ pass the IP address of each enabled interface to the policy
+ plugin. This makes it possible for the plugin to match rules
+ based on the IP address without having to query DNS. On Linux
+ systems with a large number of virtual interfaces, this may
+ take a non-negligible amount of time. If IP-based matching is
+ not required, network interface probing can be disabled as
+ follows:
+
+ Set probe_interfaces false
+
+ This setting is only available in ssuuddoo version 1.8.10 and
+ higher.
+
+ DDeebbuugg ffllaaggss
+ ssuuddoo versions 1.8.4 and higher support a flexible debugging framework
+ that can help track down what ssuuddoo is doing internally if there is a
+ problem.
+
+ A Debug line consists of the Debug keyword, followed by the name of the
+ program (or plugin) to debug (ssuuddoo, vviissuuddoo, ssuuddoorreeppllaayy, ssuuddooeerrss), the
+ debug file name and a comma-separated list of debug flags. The debug
+ flag syntax used by ssuuddoo and the ssuuddooeerrss plugin is _s_u_b_s_y_s_t_e_m@_p_r_i_o_r_i_t_y but
+ a plugin is free to use a different format so long as it does not include
+ a comma (`,').
+
+ For example:
+
+ Debug sudo /var/log/sudo_debug all@warn,plugin@info
+
+ would log all debugging statements at the _w_a_r_n level and higher in
+ addition to those at the _i_n_f_o level for the plugin subsystem.
+
+ As of ssuuddoo 1.8.12, multiple Debug entries may be specified per program.
+ Older versions of ssuuddoo only support a single Debug entry per program.
+ Plugin-specific Debug entries are also supported starting with ssuuddoo
+ 1.8.12 and are matched by either the base name of the plugin that was
+ loaded (for example sudoers.so) or by the plugin's fully-qualified path
+ name. Previously, the ssuuddooeerrss plugin shared the same Debug entry as the
+ ssuuddoo front end and could not be configured separately.
+
+ The following priorities are supported, in order of decreasing severity:
+ _c_r_i_t, _e_r_r, _w_a_r_n, _n_o_t_i_c_e, _d_i_a_g, _i_n_f_o, _t_r_a_c_e and _d_e_b_u_g. Each priority,
+ when specified, also includes all priorities higher than it. For
+ example, a priority of _n_o_t_i_c_e would include debug messages logged at
+ _n_o_t_i_c_e and higher.
+
+ The priorities _t_r_a_c_e and _d_e_b_u_g also include function call tracing which
+ logs when a function is entered and when it returns. For example, the
+ following trace is for the ggeett__uusseerr__ggrroouuppss() function located in
+ src/sudo.c:
+
+ sudo[123] -> get_user_groups @ src/sudo.c:385
+ sudo[123] <- get_user_groups @ src/sudo.c:429 := groups=10,0,5
+
+ When the function is entered, indicated by a right arrow `->', the
+ program, process ID, function, source file and line number are logged.
+ When the function returns, indicated by a left arrow `<-', the same
+ information is logged along with the return value. In this case, the
+ return value is a string.
+
+ The following subsystems are used by the ssuuddoo front-end:
+
+ _a_l_l matches every subsystem
+
+ _a_r_g_s command line argument processing
+
+ _c_o_n_v user conversation
+
+ _e_d_i_t sudoedit
+
+ _e_v_e_n_t event subsystem
+
+ _e_x_e_c command execution
+
+ _m_a_i_n ssuuddoo main function
+
+ _n_e_t_i_f network interface handling
+
+ _p_c_o_m_m communication with the plugin
+
+ _p_l_u_g_i_n plugin configuration
+
+ _p_t_y pseudo-tty related code
+
+ _s_e_l_i_n_u_x SELinux-specific handling
+
+ _u_t_i_l utility functions
+
+ _u_t_m_p utmp handling
+
+ The sudoers(4) plugin includes support for additional subsystems.
+
+FFIILLEESS
+ _/_e_t_c_/_s_u_d_o_._c_o_n_f ssuuddoo front end configuration
+
+EEXXAAMMPPLLEESS
+ #
+ # Default /etc/sudo.conf file
+ #
+ # Format:
+ # Plugin plugin_name plugin_path plugin_options ...
+ # Path askpass /path/to/askpass
+ # Path noexec /path/to/sudo_noexec.so
+ # Debug sudo /var/log/sudo_debug all@warn
+ # Set disable_coredump true
+ #
+ # The plugin_path is relative to /usr/local/libexec/sudo unless
+ # fully qualified.
+ # The plugin_name corresponds to a global symbol in the plugin
+ # that contains the plugin interface structure.
+ # The plugin_options are optional.
+ #
+ # The sudoers plugin is used by default if no Plugin lines are
+ # present.
+ Plugin sudoers_policy sudoers.so
+ Plugin sudoers_io sudoers.so
+
+ #
+ # Sudo askpass:
+ #
+ # An askpass helper program may be specified to provide a graphical
+ # password prompt for "sudo -A" support. Sudo does not ship with
+ # its own askpass program but can use the OpenSSH askpass.
+ #
+ # Use the OpenSSH askpass
+ #Path askpass /usr/X11R6/bin/ssh-askpass
+ #
+ # Use the Gnome OpenSSH askpass
+ #Path askpass /usr/libexec/openssh/gnome-ssh-askpass
+
+ #
+ # Sudo noexec:
+ #
+ # Path to a shared library containing dummy versions of the execv(),
+ # execve() and fexecve() library functions that just return an error.
+ # This is used to implement the "noexec" functionality on systems that
+ # support C<LD_PRELOAD> or its equivalent.
+ # The compiled-in value is usually sufficient and should only be
+ # changed if you rename or move the sudo_noexec.so file.
+ #
+ #Path noexec /usr/local/libexec/sudo/sudo_noexec.so
+
+ #
+ # Core dumps:
+ #
+ # By default, sudo disables core dumps while it is executing
+ # (they are re-enabled for the command that is run).
+ # To aid in debugging sudo problems, you may wish to enable core
+ # dumps by setting "disable_coredump" to false.
+ #
+ #Set disable_coredump false
+
+ #
+ # User groups:
+ #
+ # Sudo passes the user's group list to the policy plugin.
+ # If the user is a member of the maximum number of groups (usually 16),
+ # sudo will query the group database directly to be sure to include
+ # the full list of groups.
+ #
+ # On some systems, this can be expensive so the behavior is configurable.
+ # The "group_source" setting has three possible values:
+ # static - use the user's list of groups returned by the kernel.
+ # dynamic - query the group database to find the list of groups.
+ # adaptive - if user is in less than the maximum number of groups.
+ # use the kernel list, else query the group database.
+ #
+ #Set group_source static
+
+SSEEEE AALLSSOO
+ sudo_plugin(4), sudoers(4), sudo(1m)
+
+HHIISSTTOORRYY
+ See the HISTORY file in the ssuuddoo distribution
+ (https://www.sudo.ws/history.html) for a brief history of sudo.
+
+AAUUTTHHOORRSS
+ Many people have worked on ssuuddoo over the years; this version consists of
+ code written primarily by:
+
+ Todd C. Miller
+
+ See the CONTRIBUTORS file in the ssuuddoo distribution
+ (https://www.sudo.ws/contributors.html) for an exhaustive list of people
+ who have contributed to ssuuddoo.
+
+BBUUGGSS
+ If you feel you have found a bug in ssuuddoo, please submit a bug report at
+ https://bugzilla.sudo.ws/
+
+SSUUPPPPOORRTT
+ Limited free support is available via the sudo-users mailing list, see
+ https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search
+ the archives.
+
+DDIISSCCLLAAIIMMEERR
+ ssuuddoo is provided "AS IS" and any express or implied warranties,
+ including, but not limited to, the implied warranties of merchantability
+ and fitness for a particular purpose are disclaimed. See the LICENSE
+ file distributed with ssuuddoo or https://www.sudo.ws/license.html for
+ complete details.
+
+Sudo 1.8.26 October 7, 2018 Sudo 1.8.26
diff --git a/doc/sudo.conf.man.in b/doc/sudo.conf.man.in
new file mode 100644
index 0000000..8a8a311
--- /dev/null
+++ b/doc/sudo.conf.man.in
@@ -0,0 +1,752 @@
+.\" Automatically generated from an mdoc input file. Do not edit.
+.\"
+.\" Copyright (c) 2010-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "SUDO.CONF" "@mansectform@" "October 7, 2018" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
+.nh
+.if n .ad l
+.SH "NAME"
+\fBsudo.conf\fR
+\- configuration for sudo front end
+.SH "DESCRIPTION"
+The
+\fBsudo.conf\fR
+file is used to configure the
+\fBsudo\fR
+front end.
+It specifies the security policy and I/O logging plugins, debug flags
+as well as plugin-agnostic path names and settings.
+.PP
+The
+\fBsudo.conf\fR
+file supports the following directives, described in detail below.
+.TP 10n
+Plugin
+a security policy or I/O logging plugin
+.TP 10n
+Path
+a plugin-agnostic path
+.TP 10n
+Set
+a front end setting, such as
+\fIdisable_coredump\fR
+or
+\fIgroup_source\fR
+.TP 10n
+Debug
+debug flags to aid in debugging
+\fBsudo\fR,
+\fBsudoreplay\fR,
+\fBvisudo\fR,
+and the
+\fBsudoers\fR
+plugin.
+.PP
+The pound sign
+(\(oq#\(cq)
+is used to indicate a comment.
+Both the comment character and any text after it, up to the end of
+the line, are ignored.
+.PP
+Long lines can be continued with a backslash
+(\(oq\e\(cq)
+as the last character on the line.
+Note that leading white space is removed from the beginning of lines
+even when the continuation character is used.
+.PP
+Non-comment lines that don't begin with
+\fRPlugin\fR,
+\fRPath\fR,
+\fRDebug\fR,
+or
+\fRSet\fR
+are silently ignored.
+.PP
+The
+\fBsudo.conf\fR
+file is always parsed in the
+\(lq\fRC\fR\(rq
+locale.
+.SS "Plugin configuration"
+\fBsudo\fR
+supports a plugin architecture for security policies and input/output
+logging.
+Third parties can develop and distribute their own policy and I/O
+logging plugins to work seamlessly with the
+\fBsudo\fR
+front end.
+Plugins are dynamically loaded based on the contents of
+\fBsudo.conf\fR.
+.PP
+A
+\fRPlugin\fR
+line consists of the
+\fRPlugin\fR
+keyword, followed by the
+\fIsymbol_name\fR
+and the
+\fIpath\fR
+to the dynamic shared object that contains the plugin.
+The
+\fIsymbol_name\fR
+is the name of the
+\fRstruct policy_plugin\fR
+or
+\fRstruct io_plugin\fR
+symbol contained in the plugin.
+The
+\fIpath\fR
+may be fully qualified or relative.
+If not fully qualified, it is relative to the directory
+specified by the
+\fIplugin_dir\fR
+\fRPath\fR
+setting, which defaults to
+\fI@PLUGINDIR@\fR.
+In other words:
+.nf
+.sp
+.RS 6n
+Plugin sudoers_policy sudoers.so
+.RE
+.fi
+.PP
+is equivalent to:
+.nf
+.sp
+.RS 6n
+Plugin sudoers_policy @PLUGINDIR@/sudoers.so
+.RE
+.fi
+.PP
+If the plugin was compiled statically into the
+\fBsudo\fR
+binary instead of being installed as a dynamic shared object, the
+\fIpath\fR
+should be specified without a leading directory,
+as it does not actually exist in the file system.
+For example:
+.nf
+.sp
+.RS 6n
+Plugin sudoers_policy sudoers.so
+.RE
+.fi
+.PP
+Starting with
+\fBsudo\fR
+1.8.5, any additional parameters after the
+\fIpath\fR
+are passed as arguments to the plugin's
+\fIopen\fR
+function.
+For example, to override the compile-time default sudoers file mode:
+.nf
+.sp
+.RS 6n
+Plugin sudoers_policy sudoers.so sudoers_mode=0440
+.RE
+.fi
+.PP
+See the
+sudoers(@mansectform@)
+manual for a list of supported arguments.
+.PP
+The same dynamic shared object may contain multiple plugins,
+each with a different symbol name.
+The file must be owned by uid 0 and only writable by its owner.
+Because of ambiguities that arise from composite policies, only a single
+policy plugin may be specified.
+This limitation does not apply to I/O plugins.
+.PP
+If no
+\fBsudo.conf\fR
+file is present, or if it contains no
+\fRPlugin\fR
+lines, the
+\fBsudoers\fR
+plugin will be used as the default security policy and for I/O logging
+(if enabled by the policy).
+This is equivalent to the following:
+.nf
+.sp
+.RS 6n
+Plugin sudoers_policy sudoers.so
+Plugin sudoers_io sudoers.so
+.RE
+.fi
+.PP
+For more information on the
+\fBsudo\fR
+plugin architecture, see the
+sudo_plugin(@mansectform@)
+manual.
+.SS "Path settings"
+A
+\fRPath\fR
+line consists of the
+\fRPath\fR
+keyword, followed by the name of the path to set and its value.
+For example:
+.nf
+.sp
+.RS 6n
+Path noexec @noexec_file@
+Path askpass /usr/X11R6/bin/ssh-askpass
+.RE
+.fi
+.PP
+If no path name is specified, features relying on the specified
+setting will be disabled.
+Disabling
+\fRPath\fR
+settings is only supported in
+\fBsudo\fR
+version 1.8.16 and higher.
+.PP
+The following plugin-agnostic paths may be set in the
+\fI@sysconfdir@/sudo.conf\fR
+file:
+.TP 10n
+askpass
+The fully qualified path to a helper program used to read the user's
+password when no terminal is available.
+This may be the case when
+\fBsudo\fR
+is executed from a graphical (as opposed to text-based) application.
+The program specified by
+\fIaskpass\fR
+should display the argument passed to it as the prompt and write
+the user's password to the standard output.
+The value of
+\fIaskpass\fR
+may be overridden by the
+\fRSUDO_ASKPASS\fR
+environment variable.
+.TP 10n
+devsearch
+.br
+An ordered, colon-separated search path of directories to look in for
+device nodes.
+This is used when mapping the process's tty device number to a device name
+on systems that do not provide such a mechanism.
+Sudo will
+\fInot\fR
+recurse into sub-directories.
+If terminal devices may be located in a sub-directory of
+\fI/dev\fR,
+that path must be explicitly listed in
+\fIdevsearch\fR.
+The default value is:
+\fR/dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev\fR
+.sp
+This option is ignored on systems that support either the
+\fBdevname\fR()
+or
+\fB_ttyname_dev\fR()
+functions, for example
+BSD,
+macOS and Solaris.
+.TP 10n
+noexec
+The fully-qualified path to a shared library containing wrappers
+for the
+\fBexecl\fR(),
+\fBexecle\fR(),
+\fBexeclp\fR(),
+\fBexect\fR(),
+\fBexecv\fR(),
+\fBexecve\fR(),
+\fBexecvP\fR(),
+\fBexecvp\fR(),
+\fBexecvpe\fR(),
+\fBfexecve\fR(),
+\fBpopen\fR(),
+\fBposix_spawn\fR(),
+\fBposix_spawnp\fR(),
+\fBsystem\fR(),
+and
+\fBwordexp\fR()
+library functions that prevent the execution of further commands.
+This is used to implement the
+\fInoexec\fR
+functionality on systems that support
+\fRLD_PRELOAD\fR
+or its equivalent.
+The default value is:
+\fI@noexec_file@\fR.
+.TP 10n
+plugin_dir
+The default directory to use when searching for plugins
+that are specified without a fully qualified path name.
+The default value is
+\fI@PLUGINDIR@\fR.
+.TP 10n
+sesh
+The fully-qualified path to the
+\fBsesh\fR
+binary.
+This setting is only used when
+\fBsudo\fR
+is built with SELinux support.
+The default value is
+\fI@sesh_file@\fR.
+.SS "Other settings"
+The
+\fBsudo.conf\fR
+file also supports the following front end settings:
+.TP 10n
+disable_coredump
+Core dumps of
+\fBsudo\fR
+itself are disabled by default to prevent the disclosure of potentially
+sensitive information.
+To aid in debugging
+\fBsudo\fR
+crashes, you may wish to re-enable core dumps by setting
+\(lqdisable_coredump\(rq
+to false in
+\fBsudo.conf\fR
+as follows:
+.nf
+.sp
+.RS 16n
+Set disable_coredump false
+.RE
+.fi
+.RS 10n
+.sp
+All modern operating systems place restrictions on core dumps
+from setuid processes like
+\fBsudo\fR
+so this option can be enabled without compromising security.
+To actually get a
+\fBsudo\fR
+core file you will likely need to enable core dumps for setuid processes.
+On
+BSD
+and Linux systems this is accomplished in the
+sysctl(@mansectsu@)
+command.
+On Solaris, the
+coreadm(1m)
+command is used to configure core dump behavior.
+.sp
+This setting is only available in
+\fBsudo\fR
+version 1.8.4 and higher.
+.RE
+.TP 10n
+group_source
+\fBsudo\fR
+passes the invoking user's group list to the policy and I/O plugins.
+On most systems, there is an upper limit to the number of groups that
+a user may belong to simultaneously (typically 16 for compatibility
+with NFS).
+On systems with the
+getconf(1)
+utility, running:
+.RS 16n
+getconf NGROUPS_MAX
+.RE
+.RS 10n
+will return the maximum number of groups.
+.sp
+However, it is still possible to be a member of a larger number of
+groups--they simply won't be included in the group list returned
+by the kernel for the user.
+Starting with
+\fBsudo\fR
+version 1.8.7, if the user's kernel group list has the maximum number
+of entries,
+\fBsudo\fR
+will consult the group database directly to determine the group list.
+This makes it possible for the security policy to perform matching by group
+name even when the user is a member of more than the maximum number of groups.
+.sp
+The
+\fIgroup_source\fR
+setting allows the administrator to change this default behavior.
+Supported values for
+\fIgroup_source\fR
+are:
+.TP 10n
+static
+Use the static group list that the kernel returns.
+Retrieving the group list this way is very fast but it is subject
+to an upper limit as described above.
+It is
+\(lqstatic\(rq
+in that it does not reflect changes to the group database made
+after the user logs in.
+This was the default behavior prior to
+\fBsudo\fR
+1.8.7.
+.TP 10n
+dynamic
+Always query the group database directly.
+It is
+\(lqdynamic\(rq
+in that changes made to the group database after the user logs in
+will be reflected in the group list.
+On some systems, querying the group database for all of a user's
+groups can be time consuming when querying a network-based group
+database.
+Most operating systems provide an efficient method of performing
+such queries.
+Currently,
+\fBsudo\fR
+supports efficient group queries on AIX,
+BSD,
+HP-UX, Linux and Solaris.
+.TP 10n
+adaptive
+Only query the group database if the static group list returned
+by the kernel has the maximum number of entries.
+This is the default behavior in
+\fBsudo\fR
+1.8.7 and higher.
+.PP
+For example, to cause
+\fBsudo\fR
+to only use the kernel's static list of groups for the user:
+.nf
+.sp
+.RS 16n
+Set group_source static
+.RE
+.fi
+.sp
+This setting is only available in
+\fBsudo\fR
+version 1.8.7 and higher.
+.RE
+.TP 10n
+max_groups
+The maximum number of user groups to retrieve from the group database.
+Values less than one will be ignored.
+This setting is only used when querying the group database directly.
+It is intended to be used on systems where it is not possible to detect
+when the array to be populated with group entries is not sufficiently large.
+By default,
+\fBsudo\fR
+will allocate four times the system's maximum number of groups (see above)
+and retry with double that number if the group database query fails.
+.sp
+This setting is only available in
+\fBsudo\fR
+version 1.8.7 and higher.
+It should not be required in
+\fBsudo\fR
+versions 1.8.24 and higher and may be removed in a later release.
+.TP 10n
+probe_interfaces
+By default,
+\fBsudo\fR
+will probe the system's network interfaces and pass the IP address
+of each enabled interface to the policy plugin.
+This makes it possible for the plugin to match rules based on the IP address
+without having to query DNS.
+On Linux systems with a large number of virtual interfaces, this may
+take a non-negligible amount of time.
+If IP-based matching is not required, network interface probing
+can be disabled as follows:
+.nf
+.sp
+.RS 16n
+Set probe_interfaces false
+.RE
+.fi
+.RS 10n
+.sp
+This setting is only available in
+\fBsudo\fR
+version 1.8.10 and higher.
+.RE
+.SS "Debug flags"
+\fBsudo\fR
+versions 1.8.4 and higher support a flexible debugging framework
+that can help track down what
+\fBsudo\fR
+is doing internally if there is a problem.
+.PP
+A
+\fRDebug\fR
+line consists of the
+\fRDebug\fR
+keyword, followed by the name of the program (or plugin) to debug
+(\fBsudo\fR, \fBvisudo\fR, \fBsudoreplay\fR, \fBsudoers\fR),
+the debug file name and a comma-separated list of debug flags.
+The debug flag syntax used by
+\fBsudo\fR
+and the
+\fBsudoers\fR
+plugin is
+\fIsubsystem\fR@\fIpriority\fR
+but a plugin is free to use a different format so long as it does
+not include a comma
+(\(oq\&,\(cq).
+.PP
+For example:
+.nf
+.sp
+.RS 6n
+Debug sudo /var/log/sudo_debug all@warn,plugin@info
+.RE
+.fi
+.PP
+would log all debugging statements at the
+\fIwarn\fR
+level and higher in addition to those at the
+\fIinfo\fR
+level for the plugin subsystem.
+.PP
+As of
+\fBsudo\fR
+1.8.12, multiple
+\fRDebug\fR
+entries may be specified per program.
+Older versions of
+\fBsudo\fR
+only support a single
+\fRDebug\fR
+entry per program.
+Plugin-specific
+\fRDebug\fR
+entries are also supported starting with
+\fBsudo\fR
+1.8.12 and are matched by either the base name of the plugin that was loaded
+(for example
+\fRsudoers.so\fR)
+or by the plugin's fully-qualified path name.
+Previously, the
+\fBsudoers\fR
+plugin shared the same
+\fRDebug\fR
+entry as the
+\fBsudo\fR
+front end and could not be configured separately.
+.PP
+The following priorities are supported, in order of decreasing severity:
+\fIcrit\fR, \fIerr\fR, \fIwarn\fR, \fInotice\fR, \fIdiag\fR, \fIinfo\fR, \fItrace\fR
+and
+\fIdebug\fR.
+Each priority, when specified, also includes all priorities higher
+than it.
+For example, a priority of
+\fInotice\fR
+would include debug messages logged at
+\fInotice\fR
+and higher.
+.PP
+The priorities
+\fItrace\fR
+and
+\fIdebug\fR
+also include function call tracing which logs when a function is
+entered and when it returns.
+For example, the following trace is for the
+\fBget_user_groups\fR()
+function located in src/sudo.c:
+.nf
+.sp
+.RS 6n
+sudo[123] -> get_user_groups @ src/sudo.c:385
+sudo[123] <- get_user_groups @ src/sudo.c:429 := groups=10,0,5
+.RE
+.fi
+.PP
+When the function is entered, indicated by a right arrow
+\(oq->\(cq,
+the program, process ID, function, source file and line number
+are logged.
+When the function returns, indicated by a left arrow
+\(oq<-\(cq,
+the same information is logged along with the return value.
+In this case, the return value is a string.
+.PP
+The following subsystems are used by the
+\fBsudo\fR
+front-end:
+.TP 12n
+\fIall\fR
+matches every subsystem
+.TP 12n
+\fIargs\fR
+command line argument processing
+.TP 12n
+\fIconv\fR
+user conversation
+.TP 12n
+\fIedit\fR
+sudoedit
+.TP 12n
+\fIevent\fR
+event subsystem
+.TP 12n
+\fIexec\fR
+command execution
+.TP 12n
+\fImain\fR
+\fBsudo\fR
+main function
+.TP 12n
+\fInetif\fR
+network interface handling
+.TP 12n
+\fIpcomm\fR
+communication with the plugin
+.TP 12n
+\fIplugin\fR
+plugin configuration
+.TP 12n
+\fIpty\fR
+pseudo-tty related code
+.TP 12n
+\fIselinux\fR
+SELinux-specific handling
+.TP 12n
+\fIutil\fR
+utility functions
+.TP 12n
+\fIutmp\fR
+utmp handling
+.PP
+The
+sudoers(@mansectform@)
+plugin includes support for additional subsystems.
+.SH "FILES"
+.TP 26n
+\fI@sysconfdir@/sudo.conf\fR
+\fBsudo\fR
+front end configuration
+.SH "EXAMPLES"
+.nf
+.RS 0n
+#
+# Default @sysconfdir@/sudo.conf file
+#
+# Format:
+# Plugin plugin_name plugin_path plugin_options ...
+# Path askpass /path/to/askpass
+# Path noexec /path/to/sudo_noexec.so
+# Debug sudo /var/log/sudo_debug all@warn
+# Set disable_coredump true
+#
+# The plugin_path is relative to @PLUGINDIR@ unless
+# fully qualified.
+# The plugin_name corresponds to a global symbol in the plugin
+# that contains the plugin interface structure.
+# The plugin_options are optional.
+#
+# The sudoers plugin is used by default if no Plugin lines are
+# present.
+Plugin sudoers_policy sudoers.so
+Plugin sudoers_io sudoers.so
+
+#
+# Sudo askpass:
+#
+# An askpass helper program may be specified to provide a graphical
+# password prompt for "sudo -A" support. Sudo does not ship with
+# its own askpass program but can use the OpenSSH askpass.
+#
+# Use the OpenSSH askpass
+#Path askpass /usr/X11R6/bin/ssh-askpass
+#
+# Use the Gnome OpenSSH askpass
+#Path askpass /usr/libexec/openssh/gnome-ssh-askpass
+
+#
+# Sudo noexec:
+#
+# Path to a shared library containing dummy versions of the execv(),
+# execve() and fexecve() library functions that just return an error.
+# This is used to implement the "noexec" functionality on systems that
+# support C<LD_PRELOAD> or its equivalent.
+# The compiled-in value is usually sufficient and should only be
+# changed if you rename or move the sudo_noexec.so file.
+#
+#Path noexec @noexec_file@
+
+#
+# Core dumps:
+#
+# By default, sudo disables core dumps while it is executing
+# (they are re-enabled for the command that is run).
+# To aid in debugging sudo problems, you may wish to enable core
+# dumps by setting "disable_coredump" to false.
+#
+#Set disable_coredump false
+
+#
+# User groups:
+#
+# Sudo passes the user's group list to the policy plugin.
+# If the user is a member of the maximum number of groups (usually 16),
+# sudo will query the group database directly to be sure to include
+# the full list of groups.
+#
+# On some systems, this can be expensive so the behavior is configurable.
+# The "group_source" setting has three possible values:
+# static - use the user's list of groups returned by the kernel.
+# dynamic - query the group database to find the list of groups.
+# adaptive - if user is in less than the maximum number of groups.
+# use the kernel list, else query the group database.
+#
+#Set group_source static
+.RE
+.fi
+.SH "SEE ALSO"
+sudo_plugin(@mansectform@),
+sudoers(@mansectform@),
+sudo(@mansectsu@)
+.SH "HISTORY"
+See the HISTORY file in the
+\fBsudo\fR
+distribution (https://www.sudo.ws/history.html) for a brief
+history of sudo.
+.SH "AUTHORS"
+Many people have worked on
+\fBsudo\fR
+over the years; this version consists of code written primarily by:
+.sp
+.RS 6n
+Todd C. Miller
+.RE
+.PP
+See the CONTRIBUTORS file in the
+\fBsudo\fR
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+\fBsudo\fR.
+.SH "BUGS"
+If you feel you have found a bug in
+\fBsudo\fR,
+please submit a bug report at https://bugzilla.sudo.ws/
+.SH "SUPPORT"
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.SH "DISCLAIMER"
+\fBsudo\fR
+is provided
+\(lqAS IS\(rq
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+\fBsudo\fR
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/sudo.conf.mdoc.in b/doc/sudo.conf.mdoc.in
new file mode 100644
index 0000000..4823a0b
--- /dev/null
+++ b/doc/sudo.conf.mdoc.in
@@ -0,0 +1,687 @@
+.\"
+.\" Copyright (c) 2010-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd October 7, 2018
+.Dt SUDO.CONF @mansectform@
+.Os Sudo @PACKAGE_VERSION@
+.Sh NAME
+.Nm sudo.conf
+.Nd configuration for sudo front end
+.Sh DESCRIPTION
+The
+.Nm sudo.conf
+file is used to configure the
+.Nm sudo
+front end.
+It specifies the security policy and I/O logging plugins, debug flags
+as well as plugin-agnostic path names and settings.
+.Pp
+The
+.Nm
+file supports the following directives, described in detail below.
+.Bl -tag -width 8n
+.It Plugin
+a security policy or I/O logging plugin
+.It Path
+a plugin-agnostic path
+.It Set
+a front end setting, such as
+.Em disable_coredump
+or
+.Em group_source
+.It Debug
+debug flags to aid in debugging
+.Nm sudo ,
+.Nm sudoreplay ,
+.Nm visudo ,
+and the
+.Nm sudoers
+plugin.
+.El
+.Pp
+The pound sign
+.Pq Ql #
+is used to indicate a comment.
+Both the comment character and any text after it, up to the end of
+the line, are ignored.
+.Pp
+Long lines can be continued with a backslash
+.Pq Ql \e
+as the last character on the line.
+Note that leading white space is removed from the beginning of lines
+even when the continuation character is used.
+.Pp
+Non-comment lines that don't begin with
+.Li Plugin ,
+.Li Path ,
+.Li Debug ,
+or
+.Li Set
+are silently ignored.
+.Pp
+The
+.Nm
+file is always parsed in the
+.Dq Li C
+locale.
+.Ss Plugin configuration
+.Nm sudo
+supports a plugin architecture for security policies and input/output
+logging.
+Third parties can develop and distribute their own policy and I/O
+logging plugins to work seamlessly with the
+.Nm sudo
+front end.
+Plugins are dynamically loaded based on the contents of
+.Nm .
+.Pp
+A
+.Li Plugin
+line consists of the
+.Li Plugin
+keyword, followed by the
+.Em symbol_name
+and the
+.Em path
+to the dynamic shared object that contains the plugin.
+The
+.Em symbol_name
+is the name of the
+.Li struct policy_plugin
+or
+.Li struct io_plugin
+symbol contained in the plugin.
+The
+.Em path
+may be fully qualified or relative.
+If not fully qualified, it is relative to the directory
+specified by the
+.Em plugin_dir
+.Li Path
+setting, which defaults to
+.Pa @PLUGINDIR@ .
+In other words:
+.Bd -literal -offset indent
+Plugin sudoers_policy sudoers.so
+.Ed
+.Pp
+is equivalent to:
+.Bd -literal -offset indent
+Plugin sudoers_policy @PLUGINDIR@/sudoers.so
+.Ed
+.Pp
+If the plugin was compiled statically into the
+.Nm sudo
+binary instead of being installed as a dynamic shared object, the
+.Em path
+should be specified without a leading directory,
+as it does not actually exist in the file system.
+For example:
+.Bd -literal -offset indent
+Plugin sudoers_policy sudoers.so
+.Ed
+.Pp
+Starting with
+.Nm sudo
+1.8.5, any additional parameters after the
+.Em path
+are passed as arguments to the plugin's
+.Em open
+function.
+For example, to override the compile-time default sudoers file mode:
+.Bd -literal -offset indent
+Plugin sudoers_policy sudoers.so sudoers_mode=0440
+.Ed
+.Pp
+See the
+.Xr sudoers @mansectform@
+manual for a list of supported arguments.
+.Pp
+The same dynamic shared object may contain multiple plugins,
+each with a different symbol name.
+The file must be owned by uid 0 and only writable by its owner.
+Because of ambiguities that arise from composite policies, only a single
+policy plugin may be specified.
+This limitation does not apply to I/O plugins.
+.Pp
+If no
+.Nm
+file is present, or if it contains no
+.Li Plugin
+lines, the
+.Nm sudoers
+plugin will be used as the default security policy and for I/O logging
+(if enabled by the policy).
+This is equivalent to the following:
+.Bd -literal -offset indent
+Plugin sudoers_policy sudoers.so
+Plugin sudoers_io sudoers.so
+.Ed
+.Pp
+For more information on the
+.Nm sudo
+plugin architecture, see the
+.Xr sudo_plugin @mansectform@
+manual.
+.Ss Path settings
+A
+.Li Path
+line consists of the
+.Li Path
+keyword, followed by the name of the path to set and its value.
+For example:
+.Bd -literal -offset indent
+Path noexec @noexec_file@
+Path askpass /usr/X11R6/bin/ssh-askpass
+.Ed
+.Pp
+If no path name is specified, features relying on the specified
+setting will be disabled.
+Disabling
+.Li Path
+settings is only supported in
+.Nm sudo
+version 1.8.16 and higher.
+.Pp
+The following plugin-agnostic paths may be set in the
+.Pa @sysconfdir@/sudo.conf
+file:
+.Bl -tag -width 8n
+.It askpass
+The fully qualified path to a helper program used to read the user's
+password when no terminal is available.
+This may be the case when
+.Nm sudo
+is executed from a graphical (as opposed to text-based) application.
+The program specified by
+.Em askpass
+should display the argument passed to it as the prompt and write
+the user's password to the standard output.
+The value of
+.Em askpass
+may be overridden by the
+.Ev SUDO_ASKPASS
+environment variable.
+.It devsearch
+An ordered, colon-separated search path of directories to look in for
+device nodes.
+This is used when mapping the process's tty device number to a device name
+on systems that do not provide such a mechanism.
+Sudo will
+.Em not
+recurse into sub-directories.
+If terminal devices may be located in a sub-directory of
+.Pa /dev ,
+that path must be explicitly listed in
+.Em devsearch .
+The default value is:
+.Li /dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev
+.Pp
+This option is ignored on systems that support either the
+.Fn devname
+or
+.Fn _ttyname_dev
+functions, for example
+.Bx ,
+macOS and Solaris.
+.It noexec
+The fully-qualified path to a shared library containing wrappers
+for the
+.Fn execl ,
+.Fn execle ,
+.Fn execlp ,
+.Fn exect ,
+.Fn execv ,
+.Fn execve ,
+.Fn execvP ,
+.Fn execvp ,
+.Fn execvpe ,
+.Fn fexecve ,
+.Fn popen ,
+.Fn posix_spawn ,
+.Fn posix_spawnp ,
+.Fn system ,
+and
+.Fn wordexp
+library functions that prevent the execution of further commands.
+This is used to implement the
+.Em noexec
+functionality on systems that support
+.Ev LD_PRELOAD
+or its equivalent.
+The default value is:
+.Pa @noexec_file@ .
+.It plugin_dir
+The default directory to use when searching for plugins
+that are specified without a fully qualified path name.
+The default value is
+.Pa @PLUGINDIR@ .
+.It sesh
+The fully-qualified path to the
+.Nm sesh
+binary.
+This setting is only used when
+.Nm sudo
+is built with SELinux support.
+The default value is
+.Pa @sesh_file@ .
+.El
+.Ss Other settings
+The
+.Nm
+file also supports the following front end settings:
+.Bl -tag -width 8n
+.It disable_coredump
+Core dumps of
+.Nm sudo
+itself are disabled by default to prevent the disclosure of potentially
+sensitive information.
+To aid in debugging
+.Nm sudo
+crashes, you may wish to re-enable core dumps by setting
+.Dq disable_coredump
+to false in
+.Nm
+as follows:
+.Bd -literal -offset indent
+Set disable_coredump false
+.Ed
+.Pp
+All modern operating systems place restrictions on core dumps
+from setuid processes like
+.Nm sudo
+so this option can be enabled without compromising security.
+To actually get a
+.Nm sudo
+core file you will likely need to enable core dumps for setuid processes.
+On
+.Bx
+and Linux systems this is accomplished in the
+.Xr sysctl 8
+command.
+On Solaris, the
+.Xr coreadm 1m
+command is used to configure core dump behavior.
+.Pp
+This setting is only available in
+.Nm sudo
+version 1.8.4 and higher.
+.It group_source
+.Nm sudo
+passes the invoking user's group list to the policy and I/O plugins.
+On most systems, there is an upper limit to the number of groups that
+a user may belong to simultaneously (typically 16 for compatibility
+with NFS).
+On systems with the
+.Xr getconf 1
+utility, running:
+.Dl getconf NGROUPS_MAX
+will return the maximum number of groups.
+.Pp
+However, it is still possible to be a member of a larger number of
+groups--they simply won't be included in the group list returned
+by the kernel for the user.
+Starting with
+.Nm sudo
+version 1.8.7, if the user's kernel group list has the maximum number
+of entries,
+.Nm sudo
+will consult the group database directly to determine the group list.
+This makes it possible for the security policy to perform matching by group
+name even when the user is a member of more than the maximum number of groups.
+.Pp
+The
+.Em group_source
+setting allows the administrator to change this default behavior.
+Supported values for
+.Em group_source
+are:
+.Bl -tag -width 8n
+.It static
+Use the static group list that the kernel returns.
+Retrieving the group list this way is very fast but it is subject
+to an upper limit as described above.
+It is
+.Dq static
+in that it does not reflect changes to the group database made
+after the user logs in.
+This was the default behavior prior to
+.Nm sudo
+1.8.7.
+.It dynamic
+Always query the group database directly.
+It is
+.Dq dynamic
+in that changes made to the group database after the user logs in
+will be reflected in the group list.
+On some systems, querying the group database for all of a user's
+groups can be time consuming when querying a network-based group
+database.
+Most operating systems provide an efficient method of performing
+such queries.
+Currently,
+.Nm sudo
+supports efficient group queries on AIX,
+.Bx ,
+HP-UX, Linux and Solaris.
+.It adaptive
+Only query the group database if the static group list returned
+by the kernel has the maximum number of entries.
+This is the default behavior in
+.Nm sudo
+1.8.7 and higher.
+.El
+.Pp
+For example, to cause
+.Nm sudo
+to only use the kernel's static list of groups for the user:
+.Bd -literal -offset indent
+Set group_source static
+.Ed
+.Pp
+This setting is only available in
+.Nm sudo
+version 1.8.7 and higher.
+.It max_groups
+The maximum number of user groups to retrieve from the group database.
+Values less than one will be ignored.
+This setting is only used when querying the group database directly.
+It is intended to be used on systems where it is not possible to detect
+when the array to be populated with group entries is not sufficiently large.
+By default,
+.Nm sudo
+will allocate four times the system's maximum number of groups (see above)
+and retry with double that number if the group database query fails.
+.Pp
+This setting is only available in
+.Nm sudo
+version 1.8.7 and higher.
+It should not be required in
+.Nm sudo
+versions 1.8.24 and higher and may be removed in a later release.
+.It probe_interfaces
+By default,
+.Nm sudo
+will probe the system's network interfaces and pass the IP address
+of each enabled interface to the policy plugin.
+This makes it possible for the plugin to match rules based on the IP address
+without having to query DNS.
+On Linux systems with a large number of virtual interfaces, this may
+take a non-negligible amount of time.
+If IP-based matching is not required, network interface probing
+can be disabled as follows:
+.Bd -literal -offset indent
+Set probe_interfaces false
+.Ed
+.Pp
+This setting is only available in
+.Nm sudo
+version 1.8.10 and higher.
+.El
+.Ss Debug flags
+.Nm sudo
+versions 1.8.4 and higher support a flexible debugging framework
+that can help track down what
+.Nm sudo
+is doing internally if there is a problem.
+.Pp
+A
+.Li Debug
+line consists of the
+.Li Debug
+keyword, followed by the name of the program (or plugin) to debug
+.Pq Nm sudo , Nm visudo , Nm sudoreplay , Nm sudoers ,
+the debug file name and a comma-separated list of debug flags.
+The debug flag syntax used by
+.Nm sudo
+and the
+.Nm sudoers
+plugin is
+.Em subsystem Ns @ Ns Em priority
+but a plugin is free to use a different format so long as it does
+not include a comma
+.Pq Ql \&, .
+.Pp
+For example:
+.Bd -literal -offset indent
+Debug sudo /var/log/sudo_debug all@warn,plugin@info
+.Ed
+.Pp
+would log all debugging statements at the
+.Em warn
+level and higher in addition to those at the
+.Em info
+level for the plugin subsystem.
+.Pp
+As of
+.Nm sudo
+1.8.12, multiple
+.Li Debug
+entries may be specified per program.
+Older versions of
+.Nm sudo
+only support a single
+.Li Debug
+entry per program.
+Plugin-specific
+.Li Debug
+entries are also supported starting with
+.Nm sudo
+1.8.12 and are matched by either the base name of the plugin that was loaded
+(for example
+.Li sudoers.so )
+or by the plugin's fully-qualified path name.
+Previously, the
+.Nm sudoers
+plugin shared the same
+.Li Debug
+entry as the
+.Nm sudo
+front end and could not be configured separately.
+.Pp
+The following priorities are supported, in order of decreasing severity:
+.Em crit , err , warn , notice , diag , info , trace
+and
+.Em debug .
+Each priority, when specified, also includes all priorities higher
+than it.
+For example, a priority of
+.Em notice
+would include debug messages logged at
+.Em notice
+and higher.
+.Pp
+The priorities
+.Em trace
+and
+.Em debug
+also include function call tracing which logs when a function is
+entered and when it returns.
+For example, the following trace is for the
+.Fn get_user_groups
+function located in src/sudo.c:
+.Bd -literal -offset indent
+sudo[123] -> get_user_groups @ src/sudo.c:385
+sudo[123] <- get_user_groups @ src/sudo.c:429 := groups=10,0,5
+.Ed
+.Pp
+When the function is entered, indicated by a right arrow
+.Ql -> ,
+the program, process ID, function, source file and line number
+are logged.
+When the function returns, indicated by a left arrow
+.Ql <- ,
+the same information is logged along with the return value.
+In this case, the return value is a string.
+.Pp
+The following subsystems are used by the
+.Nm sudo
+front-end:
+.Bl -tag -width Fl
+.It Em all
+matches every subsystem
+.It Em args
+command line argument processing
+.It Em conv
+user conversation
+.It Em edit
+sudoedit
+.It Em event
+event subsystem
+.It Em exec
+command execution
+.It Em main
+.Nm sudo
+main function
+.It Em netif
+network interface handling
+.It Em pcomm
+communication with the plugin
+.It Em plugin
+plugin configuration
+.It Em pty
+pseudo-tty related code
+.It Em selinux
+SELinux-specific handling
+.It Em util
+utility functions
+.It Em utmp
+utmp handling
+.El
+.Pp
+The
+.Xr sudoers @mansectform@
+plugin includes support for additional subsystems.
+.Sh FILES
+.Bl -tag -width 24n
+.It Pa @sysconfdir@/sudo.conf
+.Nm sudo
+front end configuration
+.El
+.Sh EXAMPLES
+.Bd -literal
+#
+# Default @sysconfdir@/sudo.conf file
+#
+# Format:
+# Plugin plugin_name plugin_path plugin_options ...
+# Path askpass /path/to/askpass
+# Path noexec /path/to/sudo_noexec.so
+# Debug sudo /var/log/sudo_debug all@warn
+# Set disable_coredump true
+#
+# The plugin_path is relative to @PLUGINDIR@ unless
+# fully qualified.
+# The plugin_name corresponds to a global symbol in the plugin
+# that contains the plugin interface structure.
+# The plugin_options are optional.
+#
+# The sudoers plugin is used by default if no Plugin lines are
+# present.
+Plugin sudoers_policy sudoers.so
+Plugin sudoers_io sudoers.so
+
+#
+# Sudo askpass:
+#
+# An askpass helper program may be specified to provide a graphical
+# password prompt for "sudo -A" support. Sudo does not ship with
+# its own askpass program but can use the OpenSSH askpass.
+#
+# Use the OpenSSH askpass
+#Path askpass /usr/X11R6/bin/ssh-askpass
+#
+# Use the Gnome OpenSSH askpass
+#Path askpass /usr/libexec/openssh/gnome-ssh-askpass
+
+#
+# Sudo noexec:
+#
+# Path to a shared library containing dummy versions of the execv(),
+# execve() and fexecve() library functions that just return an error.
+# This is used to implement the "noexec" functionality on systems that
+# support C<LD_PRELOAD> or its equivalent.
+# The compiled-in value is usually sufficient and should only be
+# changed if you rename or move the sudo_noexec.so file.
+#
+#Path noexec @noexec_file@
+
+#
+# Core dumps:
+#
+# By default, sudo disables core dumps while it is executing
+# (they are re-enabled for the command that is run).
+# To aid in debugging sudo problems, you may wish to enable core
+# dumps by setting "disable_coredump" to false.
+#
+#Set disable_coredump false
+
+#
+# User groups:
+#
+# Sudo passes the user's group list to the policy plugin.
+# If the user is a member of the maximum number of groups (usually 16),
+# sudo will query the group database directly to be sure to include
+# the full list of groups.
+#
+# On some systems, this can be expensive so the behavior is configurable.
+# The "group_source" setting has three possible values:
+# static - use the user's list of groups returned by the kernel.
+# dynamic - query the group database to find the list of groups.
+# adaptive - if user is in less than the maximum number of groups.
+# use the kernel list, else query the group database.
+#
+#Set group_source static
+.Ed
+.Sh SEE ALSO
+.Xr sudo_plugin @mansectform@ ,
+.Xr sudoers @mansectform@ ,
+.Xr sudo @mansectsu@
+.Sh HISTORY
+See the HISTORY file in the
+.Nm sudo
+distribution (https://www.sudo.ws/history.html) for a brief
+history of sudo.
+.Sh AUTHORS
+Many people have worked on
+.Nm sudo
+over the years; this version consists of code written primarily by:
+.Bd -ragged -offset indent
+.An Todd C. Miller
+.Ed
+.Pp
+See the CONTRIBUTORS file in the
+.Nm sudo
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+.Nm sudo .
+.Sh BUGS
+If you feel you have found a bug in
+.Nm sudo ,
+please submit a bug report at https://bugzilla.sudo.ws/
+.Sh SUPPORT
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.Sh DISCLAIMER
+.Nm sudo
+is provided
+.Dq AS IS
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+.Nm sudo
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/sudo.man.in b/doc/sudo.man.in
new file mode 100644
index 0000000..ffcd468
--- /dev/null
+++ b/doc/sudo.man.in
@@ -0,0 +1,1431 @@
+.\" Automatically generated from an mdoc input file. Do not edit.
+.\"
+.\" Copyright (c) 1994-1996, 1998-2005, 2007-2018
+.\" Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Sponsored in part by the Defense Advanced Research Projects
+.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
+.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
+.\"
+.nr SL @SEMAN@
+.nr BA @BAMAN@
+.nr LC @LCMAN@
+.nr PS @PSMAN@
+.TH "SUDO" "@mansectsu@" "November 25, 2018" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
+.nh
+.if n .ad l
+.SH "NAME"
+\fBsudo\fR,
+\fBsudoedit\fR
+\- execute a command as another user
+.SH "SYNOPSIS"
+.HP 5n
+\fBsudo\fR
+\fB\-h\fR\ |\ \fB\-K\fR\ |\ \fB\-k\fR\ |\ \fB\-V\fR
+.br
+.PD 0
+.HP 5n
+\fBsudo\fR
+\fB\-v\fR
+[\fB\-AknS\fR]
+.if \n(BA [\fB\-a\fR\ \fItype\fR]
+[\fB\-g\fR\ \fIgroup\fR]
+[\fB\-h\fR\ \fIhost\fR]
+[\fB\-p\fR\ \fIprompt\fR]
+[\fB\-u\fR\ \fIuser\fR]
+.br
+.HP 5n
+\fBsudo\fR
+\fB\-l\fR
+[\fB\-AknS\fR]
+.if \n(BA [\fB\-a\fR\ \fItype\fR]
+[\fB\-g\fR\ \fIgroup\fR]
+[\fB\-h\fR\ \fIhost\fR]
+[\fB\-p\fR\ \fIprompt\fR]
+[\fB\-U\fR\ \fIuser\fR]
+[\fB\-u\fR\ \fIuser\fR]
+[\fIcommand\fR]
+.br
+.HP 5n
+\fBsudo\fR
+[\fB\-AbEHnPS\fR]
+.if \n(BA [\fB\-a\fR\ \fItype\fR]
+[\fB\-C\fR\ \fInum\fR]
+.if \n(LC [\fB\-c\fR\ \fIclass\fR]
+[\fB\-g\fR\ \fIgroup\fR]
+[\fB\-h\fR\ \fIhost\fR]
+[\fB\-p\fR\ \fIprompt\fR]
+.if \n(SL [\fB\-r\fR\ \fIrole\fR]
+.if \n(SL [\fB\-t\fR\ \fItype\fR]
+[\fB\-T\fR\ \fItimeout\fR]
+[\fB\-u\fR\ \fIuser\fR]
+[\fIVAR\fR=\fIvalue\fR]
+[\fB\-i\fR\ |\ \fB\-s\fR]
+[\fIcommand\fR]
+.br
+.HP 9n
+\fBsudoedit\fR
+[\fB\-AknS\fR]
+.if \n(BA [\fB\-a\fR\ \fItype\fR]
+[\fB\-C\fR\ \fInum\fR]
+.if \n(LC [\fB\-c\fR\ \fIclass\fR]
+[\fB\-g\fR\ \fIgroup\fR]
+[\fB\-h\fR\ \fIhost\fR]
+[\fB\-p\fR\ \fIprompt\fR]
+[\fB\-T\fR\ \fItimeout\fR]
+[\fB\-u\fR\ \fIuser\fR]
+\fIfile\ ...\fR
+.PD
+.SH "DESCRIPTION"
+\fBsudo\fR
+allows a permitted user to execute a
+\fIcommand\fR
+as the superuser or another user, as specified by the security
+policy.
+The invoking user's real
+(\fInot\fR effective)
+user ID is used to determine the user name with which
+to query the security policy.
+.PP
+\fBsudo\fR
+supports a plugin architecture for security policies and input/output
+logging.
+Third parties can develop and distribute their own policy and I/O
+logging plugins to work seamlessly with the
+\fBsudo\fR
+front end.
+The default security policy is
+\fIsudoers\fR,
+which is configured via the file
+\fI@sysconfdir@/sudoers\fR,
+or via LDAP.
+See the
+\fIPlugins\fR
+section for more information.
+.PP
+The security policy determines what privileges, if any, a user has
+to run
+\fBsudo\fR.
+The policy may require that users authenticate themselves with a
+password or another authentication mechanism.
+If authentication is required,
+\fBsudo\fR
+will exit if the user's password is not entered within a configurable
+time limit.
+This limit is policy-specific; the default password prompt timeout
+for the
+\fIsudoers\fR
+security policy is
+\fR@password_timeout@\fR
+minutes.
+.PP
+Security policies may support credential caching to allow the user
+to run
+\fBsudo\fR
+again for a period of time without requiring authentication.
+The
+\fIsudoers\fR
+policy caches credentials for
+\fR@timeout@\fR
+minutes, unless overridden in
+sudoers(@mansectform@).
+By running
+\fBsudo\fR
+with the
+\fB\-v\fR
+option, a user can update the cached credentials without running a
+\fIcommand\fR.
+.PP
+When invoked as
+\fBsudoedit\fR,
+the
+\fB\-e\fR
+option (described below), is implied.
+.PP
+Security policies may log successful and failed attempts to use
+\fBsudo\fR.
+If an I/O plugin is configured, the running command's input and
+output may be logged as well.
+.PP
+The options are as follows:
+.TP 12n
+\fB\-A\fR, \fB\--askpass\fR
+Normally, if
+\fBsudo\fR
+requires a password, it will read it from the user's terminal.
+If the
+\fB\-A\fR (\fIaskpass\fR)
+option is specified, a (possibly graphical) helper program is
+executed to read the user's password and output the password to the
+standard output.
+If the
+\fRSUDO_ASKPASS\fR
+environment variable is set, it specifies the path to the helper
+program.
+Otherwise, if
+sudo.conf(@mansectform@)
+contains a line specifying the askpass program, that value will be
+used.
+For example:
+.nf
+.sp
+.RS 16n
+# Path to askpass helper program
+Path askpass /usr/X11R6/bin/ssh-askpass
+.RE
+.fi
+.RS 12n
+.sp
+If no askpass program is available,
+\fBsudo\fR
+will exit with an error.
+.RE
+.if \n(BA \{\
+.TP 12n
+\fB\-a\fR \fItype\fR, \fB\--auth-type\fR=\fItype\fR
+Use the specified
+BSD
+authentication
+\fItype\fR
+when validating the user, if allowed by
+\fI/etc/login.conf\fR.
+The system administrator may specify a list of sudo-specific
+authentication methods by adding an
+\(lqauth-sudo\(rq
+entry in
+\fI/etc/login.conf\fR.
+This option is only available on systems that support
+BSD
+authentication.
+.\}
+.TP 12n
+\fB\-b\fR, \fB\--background\fR
+Run the given command in the background.
+Note that it is not possible to use shell job control to manipulate
+background processes started by
+\fBsudo\fR.
+Most interactive commands will fail to work properly in background
+mode.
+.TP 12n
+\fB\-C\fR \fInum\fR, \fB\--close-from\fR=\fInum\fR
+Close all file descriptors greater than or equal to
+\fInum\fR
+before executing a command.
+Values less than three are not permitted.
+By default,
+\fBsudo\fR
+will close all open file descriptors other than standard input,
+standard output and standard error when executing a command.
+The security policy may restrict the user's ability to use this option.
+The
+\fIsudoers\fR
+policy only permits use of the
+\fB\-C\fR
+option when the administrator has enabled the
+\fIclosefrom_override\fR
+option.
+.if \n(LC \{\
+.TP 12n
+\fB\-c\fR \fIclass\fR, \fB\--login-class\fR=\fIclass\fR
+Run the command with resource limits and scheduling priority of
+the specified login
+\fIclass\fR.
+The
+\fIclass\fR
+argument can be either a class name as defined in
+\fI/etc/login.conf\fR,
+or a single
+\(oq\-\(cq
+character.
+If
+\fIclass\fR
+is
+\fB-\fR,
+the default login class of the target user will be used.
+Otherwise, the command must be run as the superuser (user ID 0), or
+\fBsudo\fR
+must be run from a shell that is already running as the superuser.
+If the command is being run as a login shell, additional
+\fI/etc/login.conf\fR
+settings, such as the umask and environment variables, will
+be applied, if present.
+This option is only available on systems with
+BSD
+login classes.
+.\}
+.TP 12n
+\fB\-E\fR, \fB\--preserve-env\fR
+Indicates to the security policy that the user wishes to
+preserve their existing environment variables.
+The security policy may return an error if the user does not have
+permission to preserve the environment.
+.TP 12n
+\fB\--preserve-env=list\fR
+Indicates to the security policy that the user wishes to add the
+comma-separated list of environment variables to those preserved
+from the user's environment.
+The security policy may return an error if the user does not have
+permission to preserve the environment.
+.TP 12n
+\fB\-e\fR, \fB\--edit\fR
+Edit one or more files instead of running a command.
+In lieu of a path name, the string "sudoedit" is used when consulting
+the security policy.
+If the user is authorized by the policy, the following steps are
+taken:
+.RS 16n
+.TP 5n
+1.\&
+Temporary copies are made of the files to be edited with the owner
+set to the invoking user.
+.TP 5n
+2.\&
+The editor specified by the policy is run to edit the temporary
+files.
+The
+\fIsudoers\fR
+policy uses the
+\fRSUDO_EDITOR\fR,
+\fRVISUAL\fR
+and
+\fREDITOR\fR
+environment variables (in that order).
+If none of
+\fRSUDO_EDITOR\fR,
+\fRVISUAL\fR
+or
+\fREDITOR\fR
+are set, the first program listed in the
+\fIeditor\fR
+sudoers(@mansectform@)
+option is used.
+.TP 5n
+3.\&
+If they have been modified, the temporary files are copied back to
+their original location and the temporary versions are removed.
+.RE
+.RS 12n
+.sp
+To help prevent the editing of unauthorized files, the following
+restrictions are enforced unless explicitly allowed by the security policy:
+.RS 16n
+.TP 3n
+\fB\(bu\fR
+Symbolic links may not be edited (version 1.8.15 and higher).
+.TP 3n
+\fB\(bu\fR
+Symbolic links along the path to be edited are not followed when the
+parent directory is writable by the invoking user unless that user
+is root (version 1.8.16 and higher).
+.TP 3n
+\fB\(bu\fR
+Files located in a directory that is writable by the invoking user may
+not be edited unless that user is root (version 1.8.16 and higher).
+.RE
+.sp
+Users are never allowed to edit device special files.
+.sp
+If the specified file does not exist, it will be created.
+Note that unlike most commands run by
+\fIsudo\fR,
+the editor is run with the invoking user's environment unmodified.
+If, for some reason,
+\fBsudo\fR
+is unable to update a file with its edited version, the user will
+receive a warning and the edited copy will remain in a temporary
+file.
+.RE
+.TP 12n
+\fB\-g\fR \fIgroup\fR, \fB\--group\fR=\fIgroup\fR
+Run the command with the primary group set to
+\fIgroup\fR
+instead of the primary group specified by the target
+user's password database entry.
+The
+\fIgroup\fR
+may be either a group name or a numeric group ID
+(GID)
+prefixed with the
+\(oq#\(cq
+character (e.g.,
+\fR#0\fR
+for GID 0).
+When running a command as a GID, many shells require that the
+\(oq#\(cq
+be escaped with a backslash
+(\(oq\e\(cq).
+If no
+\fB\-u\fR
+option is specified, the command will be run as the invoking user.
+In either case, the primary group will be set to
+\fIgroup\fR.
+The
+\fIsudoers\fR
+policy permits any of the target user's groups to be specified via
+the
+\fB\-g\fR
+option as long as the
+\fB\-P\fR
+option is not in use.
+.TP 12n
+\fB\-H\fR, \fB\--set-home\fR
+Request that the security policy set the
+\fRHOME\fR
+environment variable to the home directory specified by the target
+user's password database entry.
+Depending on the policy, this may be the default behavior.
+.TP 12n
+\fB\-h\fR, \fB\--help\fR
+Display a short help message to the standard output and exit.
+.TP 12n
+\fB\-h\fR \fIhost\fR, \fB\--host\fR=\fIhost\fR
+Run the command on the specified
+\fIhost\fR
+if the security policy plugin supports remote commands.
+Note that the
+\fIsudoers\fR
+plugin does not currently support running remote commands.
+This may also be used in conjunction with the
+\fB\-l\fR
+option to list a user's privileges for the remote host.
+.TP 12n
+\fB\-i\fR, \fB\--login\fR
+Run the shell specified by the target user's password database entry
+as a login shell.
+This means that login-specific resource files such as
+\fI.profile\fR,
+\fI.bash_profile\fR
+or
+\fI.login\fR
+will be read by the shell.
+If a command is specified, it is passed to the shell for execution
+via the shell's
+\fB\-c\fR
+option.
+If no command is specified, an interactive shell is executed.
+\fBsudo\fR
+attempts to change to that user's home directory before running the
+shell.
+The command is run with an environment similar to the one
+a user would receive at log in.
+Note that most shells behave differently when a command is specified
+as compared to an interactive session; consult the shell's manual
+for details.
+The
+\fICommand environment\fR
+section in the
+sudoers(@mansectform@)
+manual documents how the
+\fB\-i\fR
+option affects the environment in which a command is run when the
+\fIsudoers\fR
+policy is in use.
+.TP 12n
+\fB\-K\fR, \fB\--remove-timestamp\fR
+Similar to the
+\fB\-k\fR
+option, except that it removes the user's cached credentials entirely
+and may not be used in conjunction with a command or other option.
+This option does not require a password.
+Not all security policies support credential caching.
+.TP 12n
+\fB\-k\fR, \fB\--reset-timestamp\fR
+When used without a command, invalidates the user's cached credentials.
+In other words, the next time
+\fBsudo\fR
+is run a password will be required.
+This option does not require a password and was added to allow a
+user to revoke
+\fBsudo\fR
+permissions from a
+\fI.logout\fR
+file.
+.sp
+When used in conjunction with a command or an option that may require
+a password, this option will cause
+\fBsudo\fR
+to ignore the user's cached credentials.
+As a result,
+\fBsudo\fR
+will prompt for a password (if one is required by the security
+policy) and will not update the user's cached credentials.
+.sp
+Not all security policies support credential caching.
+.TP 12n
+\fB\-l\fR, \fB\--list\fR
+If no
+\fIcommand\fR
+is specified,
+list the allowed (and forbidden) commands for the
+invoking user (or the user specified by the
+\fB\-U\fR
+option) on the current host.
+A longer list format is used if this option is specified multiple times
+and the security policy supports a verbose output format.
+.sp
+If a
+\fIcommand\fR
+is specified and is permitted by the security policy, the fully-qualified
+path to the command is displayed along with any command line
+arguments.
+If a
+\fIcommand\fR
+is specified but not allowed by the policy,
+\fBsudo\fR
+will exit with a status value of 1.
+.TP 12n
+\fB\-n\fR, \fB\--non-interactive\fR
+Avoid prompting the user for input of any kind.
+If a password is required for the command to run,
+\fBsudo\fR
+will display an error message and exit.
+.TP 12n
+\fB\-P\fR, \fB\--preserve-groups\fR
+Preserve the invoking user's group vector unaltered.
+By default, the
+\fIsudoers\fR
+policy will initialize the group vector to the list of groups the
+target user is a member of.
+The real and effective group IDs, however, are still set to match
+the target user.
+.TP 12n
+\fB\-p\fR \fIprompt\fR, \fB\--prompt\fR=\fIprompt\fR
+Use a custom password prompt with optional escape sequences.
+The following percent
+(\(oq%\(cq)
+escape sequences are supported by the
+\fIsudoers\fR
+policy:
+.PP
+.RS 12n
+.PD 0
+.TP 4n
+\fR%H\fR
+expanded to the host name including the domain name (on if the
+machine's host name is fully qualified or the
+\fIfqdn\fR
+option is set in
+sudoers(@mansectform@))
+.PD
+.TP 4n
+\fR%h\fR
+expanded to the local host name without the domain name
+.TP 4n
+\fR%p\fR
+expanded to the name of the user whose password is being requested
+(respects the
+\fIrootpw\fR,
+\fItargetpw\fR,
+and
+\fIrunaspw\fR
+flags in
+sudoers(@mansectform@))
+.TP 4n
+\fR\&%U\fR
+expanded to the login name of the user the command will be run as
+(defaults to root unless the
+\fB\-u\fR
+option is also specified)
+.TP 4n
+\fR%u\fR
+expanded to the invoking user's login name
+.TP 4n
+\fR%%\fR
+two consecutive
+\(oq%\(cq
+characters are collapsed into a single
+\(oq%\(cq
+character
+.PP
+The custom prompt will override the default prompt specified by either
+the security policy or the
+\fRSUDO_PROMPT\fR
+environment variable.
+On systems that use PAM, the custom prompt will also override the prompt
+specified by a PAM module unless the
+\fIpassprompt_override\fR
+flag is disabled in
+\fIsudoers\fR.
+.RE
+.if \n(SL \{\
+.TP 12n
+\fB\-r\fR \fIrole\fR, \fB\--role\fR=\fIrole\fR
+Run the command with an SELinux security context that includes
+the specified
+\fIrole\fR.
+.\}
+.TP 12n
+\fB\-S\fR, \fB\--stdin\fR
+Write the prompt to the standard error and read the password from the
+standard input instead of using the terminal device.
+.TP 12n
+\fB\-s\fR, \fB\--shell\fR
+Run the shell specified by the
+\fRSHELL\fR
+environment variable if it is set or the shell specified by the
+invoking user's password database entry.
+If a command is specified, it is passed to the shell for execution
+via the shell's
+\fB\-c\fR
+option.
+If no command is specified, an interactive shell is executed.
+Note that most shells behave differently when a command is specified
+as compared to an interactive session; consult the shell's manual
+for details.
+.if \n(SL \{\
+.TP 12n
+\fB\-t\fR \fItype\fR, \fB\--type\fR=\fItype\fR
+Run the command with an SELinux security context that includes
+the specified
+\fItype\fR.
+If no
+\fItype\fR
+is specified, the default type is derived from the role.
+.\}
+.TP 12n
+\fB\-U\fR \fIuser\fR, \fB\--other-user\fR=\fIuser\fR
+Used in conjunction with the
+\fB\-l\fR
+option to list the privileges for
+\fIuser\fR
+instead of for the invoking user.
+The security policy may restrict listing other users' privileges.
+The
+\fIsudoers\fR
+policy only allows root or a user with the
+\fRALL\fR
+privilege on the current host to use this option.
+.TP 12n
+\fB\-T\fR \fItimeout\fR, \fB\--command-timeout\fR=\fItimeout\fR
+Used to set a timeout for the command.
+If the timeout expires before the command has exited, the
+command will be terminated.
+The security policy may restrict the ability to set command timeouts.
+The
+\fIsudoers\fR
+policy requires that user-specified timeouts be explicitly enabled.
+.TP 12n
+\fB\-u\fR \fIuser\fR, \fB\--user\fR=\fIuser\fR
+Run the command as a user other than the default target user
+(usually
+\fIroot\fR).
+The
+\fIuser\fR
+may be either a user name or a numeric user ID
+(UID)
+prefixed with the
+\(oq#\(cq
+character (e.g.,
+\fR#0\fR
+for UID 0).
+When running commands as a UID, many shells require that the
+\(oq#\(cq
+be escaped with a backslash
+(\(oq\e\(cq).
+Some security policies may restrict UIDs
+to those listed in the password database.
+The
+\fIsudoers\fR
+policy allows UIDs that are not in the password database as long as the
+\fItargetpw\fR
+option is not set.
+Other security policies may not support this.
+.TP 12n
+\fB\-V\fR, \fB\--version\fR
+Print the
+\fBsudo\fR
+version string as well as the version string of the security
+policy plugin and any I/O plugins.
+If the invoking user is already root the
+\fB\-V\fR
+option will display the arguments passed to configure when
+\fBsudo\fR
+was built and plugins may display more verbose information such as
+default options.
+.TP 12n
+\fB\-v\fR, \fB\--validate\fR
+Update the user's cached credentials, authenticating the user
+if necessary.
+For the
+\fIsudoers\fR
+plugin, this extends the
+\fBsudo\fR
+timeout for another
+\fR@timeout@\fR
+minutes by default, but does not run a command.
+Not all security policies support cached credentials.
+.TP 12n
+\fB\--\fR
+The
+\fB\--\fR
+option indicates that
+\fBsudo\fR
+should stop processing command line arguments.
+.PP
+Environment variables to be set for the command may also be passed
+on the command line in the form of
+\fIVAR\fR=\fIvalue\fR,
+e.g.,
+\fRLD_LIBRARY_PATH\fR=\fI/usr/local/pkg/lib\fR.
+Variables passed on the command line are subject to restrictions
+imposed by the security policy plugin.
+The
+\fIsudoers\fR
+policy subjects variables passed on the command line to the same
+restrictions as normal environment variables with one important
+exception.
+If the
+\fIsetenv\fR
+option is set in
+\fIsudoers\fR,
+the command to be run has the
+\fRSETENV\fR
+tag set or the command matched is
+\fRALL\fR,
+the user may set variables that would otherwise be forbidden.
+See
+sudoers(@mansectform@)
+for more information.
+.SH "COMMAND EXECUTION"
+When
+\fBsudo\fR
+executes a command, the security policy specifies the execution
+environment for the command.
+Typically, the real and effective user and group and IDs are set to
+match those of the target user, as specified in the password database,
+and the group vector is initialized based on the group database
+(unless the
+\fB\-P\fR
+option was specified).
+.PP
+The following parameters may be specified by security policy:
+.TP 3n
+\fB\(bu\fR
+real and effective user ID
+.TP 3n
+\fB\(bu\fR
+real and effective group ID
+.TP 3n
+\fB\(bu\fR
+supplementary group IDs
+.TP 3n
+\fB\(bu\fR
+the environment list
+.TP 3n
+\fB\(bu\fR
+current working directory
+.TP 3n
+\fB\(bu\fR
+file creation mode mask (umask)
+.if \n(SL \{\
+.TP 3n
+\fB\(bu\fR
+SELinux role and type
+.\}
+.if \n(PS \{\
+.TP 3n
+\fB\(bu\fR
+Solaris project
+.\}
+.if \n(PS \{\
+.TP 3n
+\fB\(bu\fR
+Solaris privileges
+.\}
+.if \n(LC \{\
+.TP 3n
+\fB\(bu\fR
+BSD
+login class
+.\}
+.TP 3n
+\fB\(bu\fR
+scheduling priority (aka nice value)
+.SS "Process model"
+There are two distinct ways
+\fBsudo\fR
+can run a command.
+.PP
+If an I/O logging plugin is configured or if the security policy
+explicitly requests it, a new pseudo-terminal
+(\(lqpty\(rq)
+is allocated and
+fork(2)
+is used to create a second
+\fBsudo\fR
+process, referred to as the
+\fImonitor\fR.
+The
+\fImonitor\fR
+creates a new terminal session with itself as the leader and the pty as its
+controlling terminal, calls
+fork(2),
+sets up the execution environment as described above, and then uses the
+execve(2)
+system call to run the command in the child process.
+The
+\fImonitor\fR
+exists to relay job control signals between the user's
+existing terminal and the pty the command is being run in.
+This makes it possible to suspend and resume the command.
+Without the monitor, the command would be in what POSIX terms an
+\(lqorphaned process group\(rq
+and it would not receive any job control signals from the kernel.
+When the command exits or is terminated by a signal, the
+\fImonitor\fR
+passes the command's exit status to the main
+\fBsudo\fR
+process and exits.
+After receiving the command's exit status, the main
+\fBsudo\fR
+passes the command's exit status to the security policy's close function
+and exits.
+.PP
+If no pty is used,
+\fBsudo\fR
+calls
+fork(2),
+sets up the execution environment as described above, and uses the
+execve(2)
+system call to run the command in the child process.
+The main
+\fBsudo\fR
+process waits until the command has completed, then passes the
+command's exit status to the security policy's close function and exits.
+As a special case, if the policy plugin does not define a close
+function,
+\fBsudo\fR
+will execute the command directly instead of calling
+fork(2)
+first.
+The
+\fIsudoers\fR
+policy plugin will only define a close function when I/O logging
+is enabled, a pty is required, or the
+\fIpam_session\fR
+or
+\fIpam_setcred\fR
+options are enabled.
+Note that
+\fIpam_session\fR
+and
+\fIpam_setcred\fR
+are enabled by default on systems using PAM.
+.SS "Signal handling"
+When the command is run as a child of the
+\fBsudo\fR
+process,
+\fBsudo\fR
+will relay signals it receives to the command.
+The
+\fRSIGINT\fR
+and
+\fRSIGQUIT\fR
+signals are only relayed when the command is being run in a new pty
+or when the signal was sent by a user process, not the kernel.
+This prevents the command from receiving
+\fRSIGINT\fR
+twice each time the user enters control-C.
+Some signals, such as
+\fRSIGSTOP\fR
+and
+\fRSIGKILL\fR,
+cannot be caught and thus will not be relayed to the command.
+As a general rule,
+\fRSIGTSTP\fR
+should be used instead of
+\fRSIGSTOP\fR
+when you wish to suspend a command being run by
+\fBsudo\fR.
+.PP
+As a special case,
+\fBsudo\fR
+will not relay signals that were sent by the command it is running.
+This prevents the command from accidentally killing itself.
+On some systems, the
+reboot(@mansectsu@)
+command sends
+\fRSIGTERM\fR
+to all non-system processes other than itself before rebooting
+the system.
+This prevents
+\fBsudo\fR
+from relaying the
+\fRSIGTERM\fR
+signal it received back to
+reboot(@mansectsu@),
+which might then exit before the system was actually rebooted,
+leaving it in a half-dead state similar to single user mode.
+Note, however, that this check only applies to the command run by
+\fBsudo\fR
+and not any other processes that the command may create.
+As a result, running a script that calls
+reboot(@mansectsu@)
+or
+shutdown(@mansectsu@)
+via
+\fBsudo\fR
+may cause the system to end up in this undefined state unless the
+reboot(@mansectsu@)
+or
+shutdown(@mansectsu@)
+are run using the
+\fBexec\fR()
+family of functions instead of
+\fBsystem\fR()
+(which interposes a shell between the command and the calling process).
+.PP
+If no I/O logging plugins are loaded and the policy plugin has not
+defined a
+\fBclose\fR()
+function, set a command timeout or required that the command be
+run in a new pty,
+\fBsudo\fR
+may execute the command directly instead of running it as a child process.
+.SS "Plugins"
+Plugins may be specified via
+\fRPlugin\fR
+directives in the
+sudo.conf(@mansectform@)
+file.
+They may be loaded as dynamic shared objects (on systems that support them),
+or compiled directly into the
+\fBsudo\fR
+binary.
+If no
+sudo.conf(@mansectform@)
+file is present, or it contains no
+\fRPlugin\fR
+lines,
+\fBsudo\fR
+will use the traditional
+\fIsudoers\fR
+security policy and I/O logging.
+See the
+sudo.conf(@mansectform@)
+manual for details of the
+\fI@sysconfdir@/sudo.conf\fR
+file and the
+sudo_plugin(@mansectform@)
+manual for more information about the
+\fBsudo\fR
+plugin architecture.
+.SH "EXIT VALUE"
+Upon successful execution of a command, the exit status from
+\fBsudo\fR
+will be the exit status of the program that was executed.
+If the command terminated due to receipt of a signal,
+\fBsudo\fR
+will send itself the same signal that terminated the command.
+.PP
+If the
+\fB\-l\fR
+option was specified without a command,
+\fBsudo\fR
+will exit with a value of 0 if the user is allowed to run
+\fBsudo\fR
+and they authenticated successfully (as required by the security policy).
+If a command is specified with the
+\fB\-l\fR
+option, the exit value will only be 0 if the command is permitted by the
+security policy, otherwise it will be 1.
+.PP
+If there is an authentication failure, a configuration/permission
+problem or if the given command cannot be executed,
+\fBsudo\fR
+exits with a value of 1.
+In the latter case, the error string is printed to the standard error.
+If
+\fBsudo\fR
+cannot
+stat(2)
+one or more entries in the user's
+\fRPATH\fR,
+an error is printed to the standard error.
+(If the directory does not exist or if it is not really a directory,
+the entry is ignored and no error is printed.)
+This should not happen under normal circumstances.
+The most common reason for
+stat(2)
+to return
+\(lqpermission denied\(rq
+is if you are running an automounter and one of the directories in
+your
+\fRPATH\fR
+is on a machine that is currently unreachable.
+.SH "SECURITY NOTES"
+\fBsudo\fR
+tries to be safe when executing external commands.
+.PP
+To prevent command spoofing,
+\fBsudo\fR
+checks "." and "" (both denoting current directory) last when
+searching for a command in the user's
+\fRPATH\fR
+(if one or both are in the
+\fRPATH\fR).
+Note, however, that the actual
+\fRPATH\fR
+environment variable is
+\fInot\fR
+modified and is passed unchanged to the program that
+\fBsudo\fR
+executes.
+.PP
+Users should
+\fInever\fR
+be granted
+\fBsudo\fR
+privileges to execute files that are writable by the user or
+that reside in a directory that is writable by the user.
+If the user can modify or replace the command there is no way
+to limit what additional commands they can run.
+.PP
+Please note that
+\fBsudo\fR
+will normally only log the command it explicitly runs.
+If a user runs a command such as
+\fRsudo su\fR
+or
+\fRsudo sh\fR,
+subsequent commands run from that shell are not subject to
+\fBsudo\fR's
+security policy.
+The same is true for commands that offer shell escapes (including
+most editors).
+If I/O logging is enabled, subsequent commands will have their input and/or
+output logged, but there will not be traditional logs for those commands.
+Because of this, care must be taken when giving users access to commands via
+\fBsudo\fR
+to verify that the command does not inadvertently give the user an
+effective root shell.
+For more information, please see the
+\fIPreventing shell escapes\fR
+section in
+sudoers(@mansectform@).
+.PP
+To prevent the disclosure of potentially sensitive information,
+\fBsudo\fR
+disables core dumps by default while it is executing (they are
+re-enabled for the command that is run).
+This historical practice dates from a time when most operating
+systems allowed setuid processes to dump core by default.
+To aid in debugging
+\fBsudo\fR
+crashes, you may wish to re-enable core dumps by setting
+\(lqdisable_coredump\(rq
+to false in the
+sudo.conf(@mansectform@)
+file as follows:
+.nf
+.sp
+.RS 6n
+Set disable_coredump false
+.RE
+.fi
+.PP
+See the
+sudo.conf(@mansectform@)
+manual for more information.
+.SH "ENVIRONMENT"
+\fBsudo\fR
+utilizes the following environment variables.
+The security policy has control over the actual content of the command's
+environment.
+.TP 17n
+\fREDITOR\fR
+Default editor to use in
+\fB\-e\fR
+(sudoedit) mode if neither
+\fRSUDO_EDITOR\fR
+nor
+\fRVISUAL\fR
+is set.
+.TP 17n
+\fRMAIL\fR
+Set to the mail spool of the target user when the
+\fB\-i\fR
+option is specified or when
+\fIenv_reset\fR
+is enabled in
+\fIsudoers\fR
+(unless
+\fRMAIL\fR
+is present in the
+\fIenv_keep\fR
+list).
+.TP 17n
+\fRHOME\fR
+Set to the home directory of the target user when the
+\fB\-i\fR
+or
+\fB\-H\fR
+options are specified, when the
+\fB\-s\fR
+option is specified and
+\fIset_home\fR
+is set in
+\fIsudoers\fR,
+when
+\fIalways_set_home\fR
+is enabled in
+\fIsudoers\fR,
+or when
+\fIenv_reset\fR
+is enabled in
+\fIsudoers\fR
+and
+\fIHOME\fR
+is not present in the
+\fIenv_keep\fR
+list.
+.TP 17n
+\fRLOGNAME\fR
+Set to the login name of the target user when the
+\fB\-i\fR
+option is specified, when the
+\fIset_logname\fR
+option is enabled in
+\fIsudoers\fR
+or when the
+\fIenv_reset\fR
+option is enabled in
+\fIsudoers\fR
+(unless
+\fRLOGNAME\fR
+is present in the
+\fIenv_keep\fR
+list).
+.TP 17n
+\fRPATH\fR
+May be overridden by the security policy.
+.TP 17n
+\fRSHELL\fR
+Used to determine shell to run with
+\fB\-s\fR
+option.
+.TP 17n
+\fRSUDO_ASKPASS\fR
+Specifies the path to a helper program used to read the password
+if no terminal is available or if the
+\fB\-A\fR
+option is specified.
+.TP 17n
+\fRSUDO_COMMAND\fR
+Set to the command run by sudo.
+.TP 17n
+\fRSUDO_EDITOR\fR
+Default editor to use in
+\fB\-e\fR
+(sudoedit) mode.
+.TP 17n
+\fRSUDO_GID\fR
+Set to the group ID of the user who invoked sudo.
+.TP 17n
+\fRSUDO_PROMPT\fR
+Used as the default password prompt unless
+the
+\fB\-p\fR
+option was specified.
+.TP 17n
+\fRSUDO_PS1\fR
+If set,
+\fRPS1\fR
+will be set to its value for the program being run.
+.TP 17n
+\fRSUDO_UID\fR
+Set to the user ID of the user who invoked sudo.
+.TP 17n
+\fRSUDO_USER\fR
+Set to the login name of the user who invoked sudo.
+.TP 17n
+\fRUSER\fR
+Set to the same value as
+\fRLOGNAME\fR,
+described above.
+.TP 17n
+\fRVISUAL\fR
+Default editor to use in
+\fB\-e\fR
+(sudoedit) mode if
+\fRSUDO_EDITOR\fR
+is not set.
+.SH "FILES"
+.TP 26n
+\fI@sysconfdir@/sudo.conf\fR
+\fBsudo\fR
+front end configuration
+.SH "EXAMPLES"
+Note: the following examples assume a properly configured security
+policy.
+.PP
+To get a file listing of an unreadable directory:
+.nf
+.sp
+.RS 6n
+$ sudo ls /usr/local/protected
+.RE
+.fi
+.PP
+To list the home directory of user yaz on a machine where the file
+system holding ~yaz is not exported as root:
+.nf
+.sp
+.RS 6n
+$ sudo -u yaz ls ~yaz
+.RE
+.fi
+.PP
+To edit the
+\fIindex.html\fR
+file as user www:
+.nf
+.sp
+.RS 6n
+$ sudoedit -u www ~www/htdocs/index.html
+.RE
+.fi
+.PP
+To view system logs only accessible to root and users in the adm
+group:
+.nf
+.sp
+.RS 6n
+$ sudo -g adm more /var/log/syslog
+.RE
+.fi
+.PP
+To run an editor as jim with a different primary group:
+.nf
+.sp
+.RS 6n
+$ sudoedit -u jim -g audio ~jim/sound.txt
+.RE
+.fi
+.PP
+To shut down a machine:
+.nf
+.sp
+.RS 6n
+$ sudo shutdown -r +15 "quick reboot"
+.RE
+.fi
+.PP
+To make a usage listing of the directories in the /home partition.
+Note that this runs the commands in a sub-shell to make the
+\fRcd\fR
+and file redirection work.
+.nf
+.sp
+.RS 6n
+$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
+.RE
+.fi
+.SH "DIAGNOSTICS"
+Error messages produced by
+\fBsudo\fR
+include:
+.TP 6n
+\fRediting files in a writable directory is not permitted\fR
+By default,
+\fBsudoedit\fR
+does not permit editing a file when any of the parent directories are writable
+by the invoking user.
+This avoids a race condition that could allow the user to overwrite
+an arbitrary file.
+See the
+\fIsudoedit_checkdir\fR
+option in
+sudoers(@mansectform@)
+for more information.
+.TP 6n
+\fRediting symbolic links is not permitted\fR
+By default,
+\fBsudoedit\fR
+does not follow symbolic links when opening files.
+See the
+\fIsudoedit_follow\fR
+option in
+sudoers(@mansectform@)
+for more information.
+.TP 6n
+\fReffective uid is not 0, is sudo installed setuid root?\fR
+\fBsudo\fR
+was not run with root privileges.
+The
+\fBsudo\fR
+binary must be owned by the root user and have the Set-user-ID bit set.
+Also, it must not be located on a file system mounted with the
+\(oqnosuid\(cq
+option or on an NFS file system that maps uid 0 to an unprivileged uid.
+.TP 6n
+\fReffective uid is not 0, is sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?\fR
+\fBsudo\fR
+was not run with root privileges.
+The
+\fBsudo\fR
+binary has the proper owner and permissions but it still did not run
+with root privileges.
+The most common reason for this is that the file system the
+\fBsudo\fR
+binary is located on is mounted with the
+\(oqnosuid\(cq
+option or it is an NFS file system that maps uid 0 to an unprivileged uid.
+.TP 6n
+\fRfatal error, unable to load plugins\fR
+An error occurred while loading or initializing the plugins specified in
+sudo.conf(@mansectform@).
+.TP 6n
+\fRinvalid environment variable name\fR
+One or more environment variable names specified via the
+\fB\-E\fR
+option contained an equal sign
+(\(oq=\(cq).
+The arguments to the
+\fB\-E\fR
+option should be environment variable names without an associated value.
+.TP 6n
+\fRno password was provided\fR
+When
+\fBsudo\fR
+tried to read the password, it did not receive any characters.
+This may happen if no terminal is available (or the
+\fB\-S\fR
+option is specified) and the standard input has been redirected from
+\fI/dev/null\fR.
+.TP 6n
+\fRno tty present and no askpass program specified\fR
+\fBsudo\fR
+needs to read the password but there is no mechanism available to do so.
+A terminal is not present to read the password from,
+\fBsudo\fR
+has not been configured to read from the standard input,
+and no askpass program has been specified either via the
+\fB\-A\fR
+option or the
+\fRSUDO_ASKPASS\fR
+environment variable.
+.TP 6n
+\fRno writable temporary directory found\fR
+\fBsudoedit\fR
+was unable to find a usable temporary directory in which to store its
+intermediate files.
+.TP 6n
+\fRsudo must be owned by uid 0 and have the setuid bit set\fR
+\fBsudo\fR
+was not run with root privileges.
+The
+\fBsudo\fR
+binary does not have the correct owner or permissions.
+It must be owned by the root user and have the Set-user-ID bit set.
+.TP 6n
+\fRsudoedit is not supported on this platform\fR
+It is only possible to run
+\fBsudoedit\fR
+on systems that support setting the effective user-ID.
+.TP 6n
+\fRtimed out reading password\fR
+The user did not enter a password before the password timeout
+(5 minutes by default) expired.
+.TP 6n
+\fRyou do not exist in the passwd database\fR
+Your user ID does not appear in the system passwd database.
+.TP 6n
+\fRyou may not specify environment variables in edit mode\fR
+It is only possible to specify environment variables when running
+a command.
+When editing a file, the editor is run with the user's environment unmodified.
+.SH "SEE ALSO"
+su(1),
+stat(2),
+login_cap(3),
+passwd(@mansectform@),
+sudo.conf(@mansectform@),
+sudo_plugin(@mansectform@),
+sudoers(@mansectform@),
+sudoreplay(@mansectsu@),
+visudo(@mansectsu@)
+.SH "HISTORY"
+See the HISTORY file in the
+\fBsudo\fR
+distribution (https://www.sudo.ws/history.html) for a brief
+history of sudo.
+.SH "AUTHORS"
+Many people have worked on
+\fBsudo\fR
+over the years; this version consists of code written primarily by:
+.sp
+.RS 6n
+Todd C. Miller
+.RE
+.PP
+See the CONTRIBUTORS file in the
+\fBsudo\fR
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+\fBsudo\fR.
+.SH "CAVEATS"
+There is no easy way to prevent a user from gaining a root shell
+if that user is allowed to run arbitrary commands via
+\fBsudo\fR.
+Also, many programs (such as editors) allow the user to run commands
+via shell escapes, thus avoiding
+\fBsudo\fR's
+checks.
+However, on most systems it is possible to prevent shell escapes with the
+sudoers(@mansectform@)
+plugin's
+\fInoexec\fR
+functionality.
+.PP
+It is not meaningful to run the
+\fRcd\fR
+command directly via sudo, e.g.,
+.nf
+.sp
+.RS 6n
+$ sudo cd /usr/local/protected
+.RE
+.fi
+.PP
+since when the command exits the parent process (your shell) will
+still be the same.
+Please see the
+\fIEXAMPLES\fR
+section for more information.
+.PP
+Running shell scripts via
+\fBsudo\fR
+can expose the same kernel bugs that make setuid shell scripts
+unsafe on some operating systems (if your OS has a /dev/fd/ directory,
+setuid shell scripts are generally safe).
+.SH "BUGS"
+If you feel you have found a bug in
+\fBsudo\fR,
+please submit a bug report at https://bugzilla.sudo.ws/
+.SH "SUPPORT"
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.SH "DISCLAIMER"
+\fBsudo\fR
+is provided
+\(lqAS IS\(rq
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+\fBsudo\fR
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/sudo.man.in.sed b/doc/sudo.man.in.sed
new file mode 100644
index 0000000..432dd74
--- /dev/null
+++ b/doc/sudo.man.in.sed
@@ -0,0 +1,76 @@
+s/^\(.TH .*\)/.nr SL @SEMAN@\
+.nr BA @BAMAN@\
+.nr LC @LCMAN@\
+.nr PS @PSMAN@\
+\1/
+
+s/^\(\[\\fB\\-a\\fR.*\\fItype\\fR\]\) *$/.if \\n(BA \1/
+s/^\(\[\\fB\\-c\\fR.*\\fIclass\\fR\]\) *$/.if \\n(LC \1/
+s/^\(\[\\fB\\-r\\fR.*\\fIrole\\fR\]\) *$/.if \\n(SL \1/
+s/^\(\[\\fB\\-t\\fR.*\\fItype\\fR\]\) *$/.if \\n(SL \1/
+
+/^\.TP 12n$/ {
+ N
+ /^\.TP 12n\n\\fB\\-a\\fR.*\\fItype\\fR$/,/^\.TP 12n/ {
+ /^\.TP 12n/ {
+ /^\.TP 12n\n\\fB\\-a\\fR.*\\fItype\\fR$/i\
+.if \\n(BA \\{\\
+ /^\.TP 12n\n\\fB\\-a\\fR.*\\fItype\\fR$/!i\
+.\\}
+ }
+ }
+ /^\.TP 12n\n\\fB\\-c\\fR.*\\fIclass\\fR$/,/^\.TP 12n/ {
+ /^\.TP 12n/ {
+ /^\.TP 12n\n\\fB\\-c\\fR.*\\fIclass\\fR$/i\
+.if \\n(LC \\{\\
+ /^\.TP 12n\n\\fB\\-c\\fR.*\\fIclass\\fR$/!i\
+.\\}
+ }
+ }
+ /^\.TP 12n\n\\fB\\-r\\fR.*\\fIrole\\fR$/,/^\.TP 12n/ {
+ /^\.TP 12n/ {
+ /^\.TP 12n\n\\fB\\-r\\fR.*\\fIrole\\fR$/i\
+.if \\n(SL \\{\\
+ /^\.TP 12n\n\\fB\\-r\\fR.*\\fIrole\\fR$/!i\
+.\\}
+ }
+ }
+ /^\.TP 12n\n\\fB\\-t\\fR.*\\fItype\\fR$/,/^\.TP 12n/ {
+ /^\.TP 12n/ {
+ /^\.TP 12n\n\\fB\\-t\\fR.*\\fItype\\fR$/i\
+.if \\n(SL \\{\\
+ /^\.TP 12n\n\\fB\\-t\\fR.*\\fItype\\fR$/!i\
+.\\}
+ }
+ }
+}
+
+/^\.TP 3n$/ {
+ N
+ N
+ /^.TP 3n\n\\fB\\(bu\\fR\nSELinux role and type$/ {
+ i\
+.if \\n(SL \\{\\
+ a\
+.\\}
+ }
+ /^.TP 3n\n\\fB\\(bu\\fR\nSolaris project$/ {
+ i\
+.if \\n(PS \\{\\
+ a\
+.\\}
+ }
+ /^.TP 3n\n\\fB\\(bu\\fR\nSolaris privileges$/ {
+ i\
+.if \\n(PS \\{\\
+ a\
+.\\}
+ }
+ /^.TP 3n\n\\fB\\(bu\\fR\nBSD$/ {
+ N
+ i\
+.if \\n(LC \\{\\
+ a\
+.\\}
+ }
+}
diff --git a/doc/sudo.mdoc.in b/doc/sudo.mdoc.in
new file mode 100644
index 0000000..c9b928e
--- /dev/null
+++ b/doc/sudo.mdoc.in
@@ -0,0 +1,1320 @@
+.\"
+.\" Copyright (c) 1994-1996, 1998-2005, 2007-2018
+.\" Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Sponsored in part by the Defense Advanced Research Projects
+.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
+.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
+.\"
+.nr SL @SEMAN@
+.nr BA @BAMAN@
+.nr LC @LCMAN@
+.nr PS @PSMAN@
+.Dd November 25, 2018
+.Dt SUDO @mansectsu@
+.Os Sudo @PACKAGE_VERSION@
+.Sh NAME
+.Nm sudo ,
+.Nm sudoedit
+.Nd execute a command as another user
+.Sh SYNOPSIS
+.Nm sudo
+.Fl h | K | k | V
+.Nm sudo
+.Fl v
+.Op Fl AknS
+.if \n(BA \{\
+.Op Fl a Ar type
+.\}
+.Op Fl g Ar group
+.Op Fl h Ar host
+.Op Fl p Ar prompt
+.Op Fl u Ar user
+.Nm sudo
+.Fl l
+.Op Fl AknS
+.if \n(BA \{\
+.Op Fl a Ar type
+.\}
+.Op Fl g Ar group
+.Op Fl h Ar host
+.Op Fl p Ar prompt
+.Op Fl U Ar user
+.Op Fl u Ar user
+.Op Ar command
+.Nm sudo
+.Op Fl AbEHnPS
+.if \n(BA \{\
+.Op Fl a Ar type
+.\}
+.Op Fl C Ar num
+.if \n(LC \{\
+.Op Fl c Ar class
+.\}
+.Op Fl g Ar group
+.Op Fl h Ar host
+.Op Fl p Ar prompt
+.if \n(SL \{\
+.Op Fl r Ar role
+.Op Fl t Ar type
+.\}
+.Op Fl T Ar timeout
+.Op Fl u Ar user
+.Op Ar VAR Ns = Ns Ar value
+.Op Fl i | s
+.Op Ar command
+.Nm sudoedit
+.Op Fl AknS
+.if \n(BA \{\
+.Op Fl a Ar type
+.\}
+.Op Fl C Ar num
+.if \n(LC \{\
+.Op Fl c Ar class
+.\}
+.Op Fl g Ar group
+.Op Fl h Ar host
+.Op Fl p Ar prompt
+.Op Fl T Ar timeout
+.Op Fl u Ar user
+.Ar
+.Sh DESCRIPTION
+.Nm
+allows a permitted user to execute a
+.Ar command
+as the superuser or another user, as specified by the security
+policy.
+The invoking user's real
+.Pq Em not No effective
+user ID is used to determine the user name with which
+to query the security policy.
+.Pp
+.Nm
+supports a plugin architecture for security policies and input/output
+logging.
+Third parties can develop and distribute their own policy and I/O
+logging plugins to work seamlessly with the
+.Nm
+front end.
+The default security policy is
+.Em sudoers ,
+which is configured via the file
+.Pa @sysconfdir@/sudoers ,
+or via LDAP.
+See the
+.Sx Plugins
+section for more information.
+.Pp
+The security policy determines what privileges, if any, a user has
+to run
+.Nm .
+The policy may require that users authenticate themselves with a
+password or another authentication mechanism.
+If authentication is required,
+.Nm
+will exit if the user's password is not entered within a configurable
+time limit.
+This limit is policy-specific; the default password prompt timeout
+for the
+.Em sudoers
+security policy is
+.Li @password_timeout@
+minutes.
+.Pp
+Security policies may support credential caching to allow the user
+to run
+.Nm
+again for a period of time without requiring authentication.
+The
+.Em sudoers
+policy caches credentials for
+.Li @timeout@
+minutes, unless overridden in
+.Xr sudoers @mansectform@ .
+By running
+.Nm
+with the
+.Fl v
+option, a user can update the cached credentials without running a
+.Ar command .
+.Pp
+When invoked as
+.Nm sudoedit ,
+the
+.Fl e
+option (described below), is implied.
+.Pp
+Security policies may log successful and failed attempts to use
+.Nm .
+If an I/O plugin is configured, the running command's input and
+output may be logged as well.
+.Pp
+The options are as follows:
+.Bl -tag -width Fl
+.It Fl A , -askpass
+Normally, if
+.Nm
+requires a password, it will read it from the user's terminal.
+If the
+.Fl A Pq Em askpass
+option is specified, a (possibly graphical) helper program is
+executed to read the user's password and output the password to the
+standard output.
+If the
+.Ev SUDO_ASKPASS
+environment variable is set, it specifies the path to the helper
+program.
+Otherwise, if
+.Xr sudo.conf @mansectform@
+contains a line specifying the askpass program, that value will be
+used.
+For example:
+.Bd -literal -offset 4n
+# Path to askpass helper program
+Path askpass /usr/X11R6/bin/ssh-askpass
+.Ed
+.Pp
+If no askpass program is available,
+.Nm
+will exit with an error.
+.if \n(BA \{\
+.It Fl a Ar type , Fl -auth-type Ns = Ns Ar type
+Use the specified
+.Bx
+authentication
+.Ar type
+when validating the user, if allowed by
+.Pa /etc/login.conf .
+The system administrator may specify a list of sudo-specific
+authentication methods by adding an
+.Dq auth-sudo
+entry in
+.Pa /etc/login.conf .
+This option is only available on systems that support
+.Bx
+authentication.
+.\}
+.It Fl b , -background
+Run the given command in the background.
+Note that it is not possible to use shell job control to manipulate
+background processes started by
+.Nm .
+Most interactive commands will fail to work properly in background
+mode.
+.It Fl C Ar num , Fl -close-from Ns = Ns Ar num
+Close all file descriptors greater than or equal to
+.Ar num
+before executing a command.
+Values less than three are not permitted.
+By default,
+.Nm
+will close all open file descriptors other than standard input,
+standard output and standard error when executing a command.
+The security policy may restrict the user's ability to use this option.
+The
+.Em sudoers
+policy only permits use of the
+.Fl C
+option when the administrator has enabled the
+.Em closefrom_override
+option.
+.if \n(LC \{\
+.It Fl c Ar class , Fl -login-class Ns = Ns Ar class
+Run the command with resource limits and scheduling priority of
+the specified login
+.Ar class .
+The
+.Ar class
+argument can be either a class name as defined in
+.Pa /etc/login.conf ,
+or a single
+.Ql \-
+character.
+If
+.Ar class
+is
+.Cm - ,
+the default login class of the target user will be used.
+Otherwise, the command must be run as the superuser (user ID 0), or
+.Nm
+must be run from a shell that is already running as the superuser.
+If the command is being run as a login shell, additional
+.Pa /etc/login.conf
+settings, such as the umask and environment variables, will
+be applied, if present.
+This option is only available on systems with
+.Bx
+login classes.
+.\}
+.It Fl E , -preserve-env
+Indicates to the security policy that the user wishes to
+preserve their existing environment variables.
+The security policy may return an error if the user does not have
+permission to preserve the environment.
+.It Fl -preserve-env=list
+Indicates to the security policy that the user wishes to add the
+comma-separated list of environment variables to those preserved
+from the user's environment.
+The security policy may return an error if the user does not have
+permission to preserve the environment.
+.It Fl e , -edit
+Edit one or more files instead of running a command.
+In lieu of a path name, the string "sudoedit" is used when consulting
+the security policy.
+If the user is authorized by the policy, the following steps are
+taken:
+.Bl -enum -offset 4
+.It
+Temporary copies are made of the files to be edited with the owner
+set to the invoking user.
+.It
+The editor specified by the policy is run to edit the temporary
+files.
+The
+.Em sudoers
+policy uses the
+.Ev SUDO_EDITOR ,
+.Ev VISUAL
+and
+.Ev EDITOR
+environment variables (in that order).
+If none of
+.Ev SUDO_EDITOR ,
+.Ev VISUAL
+or
+.Ev EDITOR
+are set, the first program listed in the
+.Em editor
+.Xr sudoers @mansectform@
+option is used.
+.It
+If they have been modified, the temporary files are copied back to
+their original location and the temporary versions are removed.
+.El
+.Pp
+To help prevent the editing of unauthorized files, the following
+restrictions are enforced unless explicitly allowed by the security policy:
+.Bl -bullet -offset 4 -width 1n
+.It
+Symbolic links may not be edited (version 1.8.15 and higher).
+.It
+Symbolic links along the path to be edited are not followed when the
+parent directory is writable by the invoking user unless that user
+is root (version 1.8.16 and higher).
+.It
+Files located in a directory that is writable by the invoking user may
+not be edited unless that user is root (version 1.8.16 and higher).
+.El
+.Pp
+Users are never allowed to edit device special files.
+.Pp
+If the specified file does not exist, it will be created.
+Note that unlike most commands run by
+.Em sudo ,
+the editor is run with the invoking user's environment unmodified.
+If, for some reason,
+.Nm
+is unable to update a file with its edited version, the user will
+receive a warning and the edited copy will remain in a temporary
+file.
+.It Fl g Ar group , Fl -group Ns = Ns Ar group
+Run the command with the primary group set to
+.Ar group
+instead of the primary group specified by the target
+user's password database entry.
+The
+.Ar group
+may be either a group name or a numeric group ID
+.Pq GID
+prefixed with the
+.Ql #
+character (e.g.,
+.Li #0
+for GID 0).
+When running a command as a GID, many shells require that the
+.Ql #
+be escaped with a backslash
+.Pq Ql \e .
+If no
+.Fl u
+option is specified, the command will be run as the invoking user.
+In either case, the primary group will be set to
+.Ar group .
+The
+.Em sudoers
+policy permits any of the target user's groups to be specified via
+the
+.Fl g
+option as long as the
+.Fl P
+option is not in use.
+.It Fl H , -set-home
+Request that the security policy set the
+.Ev HOME
+environment variable to the home directory specified by the target
+user's password database entry.
+Depending on the policy, this may be the default behavior.
+.It Fl h , -help
+Display a short help message to the standard output and exit.
+.It Fl h Ar host , Fl -host Ns = Ns Ar host
+Run the command on the specified
+.Ar host
+if the security policy plugin supports remote commands.
+Note that the
+.Em sudoers
+plugin does not currently support running remote commands.
+This may also be used in conjunction with the
+.Fl l
+option to list a user's privileges for the remote host.
+.It Fl i , -login
+Run the shell specified by the target user's password database entry
+as a login shell.
+This means that login-specific resource files such as
+.Pa .profile ,
+.Pa .bash_profile
+or
+.Pa .login
+will be read by the shell.
+If a command is specified, it is passed to the shell for execution
+via the shell's
+.Fl c
+option.
+If no command is specified, an interactive shell is executed.
+.Nm
+attempts to change to that user's home directory before running the
+shell.
+The command is run with an environment similar to the one
+a user would receive at log in.
+Note that most shells behave differently when a command is specified
+as compared to an interactive session; consult the shell's manual
+for details.
+The
+.Em Command environment
+section in the
+.Xr sudoers @mansectform@
+manual documents how the
+.Fl i
+option affects the environment in which a command is run when the
+.Em sudoers
+policy is in use.
+.It Fl K , -remove-timestamp
+Similar to the
+.Fl k
+option, except that it removes the user's cached credentials entirely
+and may not be used in conjunction with a command or other option.
+This option does not require a password.
+Not all security policies support credential caching.
+.It Fl k , -reset-timestamp
+When used without a command, invalidates the user's cached credentials.
+In other words, the next time
+.Nm
+is run a password will be required.
+This option does not require a password and was added to allow a
+user to revoke
+.Nm
+permissions from a
+.Pa .logout
+file.
+.Pp
+When used in conjunction with a command or an option that may require
+a password, this option will cause
+.Nm
+to ignore the user's cached credentials.
+As a result,
+.Nm
+will prompt for a password (if one is required by the security
+policy) and will not update the user's cached credentials.
+.Pp
+Not all security policies support credential caching.
+.It Fl l , Fl -list
+If no
+.Ar command
+is specified,
+list the allowed (and forbidden) commands for the
+invoking user (or the user specified by the
+.Fl U
+option) on the current host.
+A longer list format is used if this option is specified multiple times
+and the security policy supports a verbose output format.
+.Pp
+If a
+.Ar command
+is specified and is permitted by the security policy, the fully-qualified
+path to the command is displayed along with any command line
+arguments.
+If a
+.Ar command
+is specified but not allowed by the policy,
+.Nm
+will exit with a status value of 1.
+.It Fl n , -non-interactive
+Avoid prompting the user for input of any kind.
+If a password is required for the command to run,
+.Nm
+will display an error message and exit.
+.It Fl P , -preserve-groups
+Preserve the invoking user's group vector unaltered.
+By default, the
+.Em sudoers
+policy will initialize the group vector to the list of groups the
+target user is a member of.
+The real and effective group IDs, however, are still set to match
+the target user.
+.It Fl p Ar prompt , Fl -prompt Ns = Ns Ar prompt
+Use a custom password prompt with optional escape sequences.
+The following percent
+.Pq Ql %
+escape sequences are supported by the
+.Em sudoers
+policy:
+.Bl -tag -width 2n
+.It Li %H
+expanded to the host name including the domain name (on if the
+machine's host name is fully qualified or the
+.Em fqdn
+option is set in
+.Xr sudoers @mansectform@ )
+.It Li %h
+expanded to the local host name without the domain name
+.It Li %p
+expanded to the name of the user whose password is being requested
+(respects the
+.Em rootpw ,
+.Em targetpw ,
+and
+.Em runaspw
+flags in
+.Xr sudoers @mansectform@ )
+.It Li \&%U
+expanded to the login name of the user the command will be run as
+(defaults to root unless the
+.Fl u
+option is also specified)
+.It Li %u
+expanded to the invoking user's login name
+.It Li %%
+two consecutive
+.Ql %
+characters are collapsed into a single
+.Ql %
+character
+.El
+.Pp
+The custom prompt will override the default prompt specified by either
+the security policy or the
+.Ev SUDO_PROMPT
+environment variable.
+On systems that use PAM, the custom prompt will also override the prompt
+specified by a PAM module unless the
+.Em passprompt_override
+flag is disabled in
+.Em sudoers .
+.if \n(SL \{\
+.It Fl r Ar role , Fl -role Ns = Ns Ar role
+Run the command with an SELinux security context that includes
+the specified
+.Ar role .
+.\}
+.It Fl S , -stdin
+Write the prompt to the standard error and read the password from the
+standard input instead of using the terminal device.
+.It Fl s , -shell
+Run the shell specified by the
+.Ev SHELL
+environment variable if it is set or the shell specified by the
+invoking user's password database entry.
+If a command is specified, it is passed to the shell for execution
+via the shell's
+.Fl c
+option.
+If no command is specified, an interactive shell is executed.
+Note that most shells behave differently when a command is specified
+as compared to an interactive session; consult the shell's manual
+for details.
+.if \n(SL \{\
+.It Fl t Ar type , Fl -type Ns = Ns Ar type
+Run the command with an SELinux security context that includes
+the specified
+.Ar type .
+If no
+.Ar type
+is specified, the default type is derived from the role.
+.\}
+.It Fl U Ar user , Fl -other-user Ns = Ns Ar user
+Used in conjunction with the
+.Fl l
+option to list the privileges for
+.Ar user
+instead of for the invoking user.
+The security policy may restrict listing other users' privileges.
+The
+.Em sudoers
+policy only allows root or a user with the
+.Li ALL
+privilege on the current host to use this option.
+.It Fl T Ar timeout , Fl -command-timeout Ns = Ns Ar timeout
+Used to set a timeout for the command.
+If the timeout expires before the command has exited, the
+command will be terminated.
+The security policy may restrict the ability to set command timeouts.
+The
+.Em sudoers
+policy requires that user-specified timeouts be explicitly enabled.
+.It Fl u Ar user , Fl -user Ns = Ns Ar user
+Run the command as a user other than the default target user
+(usually
+.Em root ) .
+The
+.Ar user
+may be either a user name or a numeric user ID
+.Pq UID
+prefixed with the
+.Ql #
+character (e.g.,
+.Li #0
+for UID 0).
+When running commands as a UID, many shells require that the
+.Ql #
+be escaped with a backslash
+.Pq Ql \e .
+Some security policies may restrict UIDs
+to those listed in the password database.
+The
+.Em sudoers
+policy allows UIDs that are not in the password database as long as the
+.Em targetpw
+option is not set.
+Other security policies may not support this.
+.It Fl V , -version
+Print the
+.Nm
+version string as well as the version string of the security
+policy plugin and any I/O plugins.
+If the invoking user is already root the
+.Fl V
+option will display the arguments passed to configure when
+.Nm
+was built and plugins may display more verbose information such as
+default options.
+.It Fl v , -validate
+Update the user's cached credentials, authenticating the user
+if necessary.
+For the
+.Em sudoers
+plugin, this extends the
+.Nm
+timeout for another
+.Li @timeout@
+minutes by default, but does not run a command.
+Not all security policies support cached credentials.
+.It Fl -
+The
+.Fl -
+option indicates that
+.Nm
+should stop processing command line arguments.
+.El
+.Pp
+Environment variables to be set for the command may also be passed
+on the command line in the form of
+.Ar VAR Ns = Ns Ar value ,
+e.g.,
+.Ev LD_LIBRARY_PATH Ns = Ns Pa /usr/local/pkg/lib .
+Variables passed on the command line are subject to restrictions
+imposed by the security policy plugin.
+The
+.Em sudoers
+policy subjects variables passed on the command line to the same
+restrictions as normal environment variables with one important
+exception.
+If the
+.Em setenv
+option is set in
+.Em sudoers ,
+the command to be run has the
+.Li SETENV
+tag set or the command matched is
+.Li ALL ,
+the user may set variables that would otherwise be forbidden.
+See
+.Xr sudoers @mansectform@
+for more information.
+.Sh COMMAND EXECUTION
+When
+.Nm
+executes a command, the security policy specifies the execution
+environment for the command.
+Typically, the real and effective user and group and IDs are set to
+match those of the target user, as specified in the password database,
+and the group vector is initialized based on the group database
+(unless the
+.Fl P
+option was specified).
+.Pp
+The following parameters may be specified by security policy:
+.Bl -bullet -width 1n
+.It
+real and effective user ID
+.It
+real and effective group ID
+.It
+supplementary group IDs
+.It
+the environment list
+.It
+current working directory
+.It
+file creation mode mask (umask)
+.if \n(SL \{\
+.It
+SELinux role and type
+.\}
+.if \n(PS \{\
+.It
+Solaris project
+.It
+Solaris privileges
+.\}
+.if \n(LC \{\
+.It
+.Bx
+login class
+.\}
+.It
+scheduling priority (aka nice value)
+.El
+.Ss Process model
+There are two distinct ways
+.Nm
+can run a command.
+.Pp
+If an I/O logging plugin is configured or if the security policy
+explicitly requests it, a new pseudo-terminal
+.Pq Dq pty
+is allocated and
+.Xr fork 2
+is used to create a second
+.Nm
+process, referred to as the
+.Em monitor .
+The
+.Em monitor
+creates a new terminal session with itself as the leader and the pty as its
+controlling terminal, calls
+.Xr fork 2 ,
+sets up the execution environment as described above, and then uses the
+.Xr execve 2
+system call to run the command in the child process.
+The
+.Em monitor
+exists to relay job control signals between the user's
+existing terminal and the pty the command is being run in.
+This makes it possible to suspend and resume the command.
+Without the monitor, the command would be in what POSIX terms an
+.Dq orphaned process group
+and it would not receive any job control signals from the kernel.
+When the command exits or is terminated by a signal, the
+.Em monitor
+passes the command's exit status to the main
+.Nm
+process and exits.
+After receiving the command's exit status, the main
+.Nm
+passes the command's exit status to the security policy's close function
+and exits.
+.Pp
+If no pty is used,
+.Nm
+calls
+.Xr fork 2 ,
+sets up the execution environment as described above, and uses the
+.Xr execve 2
+system call to run the command in the child process.
+The main
+.Nm
+process waits until the command has completed, then passes the
+command's exit status to the security policy's close function and exits.
+As a special case, if the policy plugin does not define a close
+function,
+.Nm
+will execute the command directly instead of calling
+.Xr fork 2
+first.
+The
+.Em sudoers
+policy plugin will only define a close function when I/O logging
+is enabled, a pty is required, or the
+.Em pam_session
+or
+.Em pam_setcred
+options are enabled.
+Note that
+.Em pam_session
+and
+.Em pam_setcred
+are enabled by default on systems using PAM.
+.Ss Signal handling
+When the command is run as a child of the
+.Nm
+process,
+.Nm
+will relay signals it receives to the command.
+The
+.Dv SIGINT
+and
+.Dv SIGQUIT
+signals are only relayed when the command is being run in a new pty
+or when the signal was sent by a user process, not the kernel.
+This prevents the command from receiving
+.Dv SIGINT
+twice each time the user enters control-C.
+Some signals, such as
+.Dv SIGSTOP
+and
+.Dv SIGKILL ,
+cannot be caught and thus will not be relayed to the command.
+As a general rule,
+.Dv SIGTSTP
+should be used instead of
+.Dv SIGSTOP
+when you wish to suspend a command being run by
+.Nm .
+.Pp
+As a special case,
+.Nm
+will not relay signals that were sent by the command it is running.
+This prevents the command from accidentally killing itself.
+On some systems, the
+.Xr reboot @mansectsu@
+command sends
+.Dv SIGTERM
+to all non-system processes other than itself before rebooting
+the system.
+This prevents
+.Nm
+from relaying the
+.Dv SIGTERM
+signal it received back to
+.Xr reboot @mansectsu@ ,
+which might then exit before the system was actually rebooted,
+leaving it in a half-dead state similar to single user mode.
+Note, however, that this check only applies to the command run by
+.Nm
+and not any other processes that the command may create.
+As a result, running a script that calls
+.Xr reboot @mansectsu@
+or
+.Xr shutdown @mansectsu@
+via
+.Nm
+may cause the system to end up in this undefined state unless the
+.Xr reboot @mansectsu@
+or
+.Xr shutdown @mansectsu@
+are run using the
+.Fn exec
+family of functions instead of
+.Fn system
+(which interposes a shell between the command and the calling process).
+.Pp
+If no I/O logging plugins are loaded and the policy plugin has not
+defined a
+.Fn close
+function, set a command timeout or required that the command be
+run in a new pty,
+.Nm
+may execute the command directly instead of running it as a child process.
+.Ss Plugins
+Plugins may be specified via
+.Li Plugin
+directives in the
+.Xr sudo.conf @mansectform@
+file.
+They may be loaded as dynamic shared objects (on systems that support them),
+or compiled directly into the
+.Nm
+binary.
+If no
+.Xr sudo.conf @mansectform@
+file is present, or it contains no
+.Li Plugin
+lines,
+.Nm
+will use the traditional
+.Em sudoers
+security policy and I/O logging.
+See the
+.Xr sudo.conf @mansectform@
+manual for details of the
+.Pa @sysconfdir@/sudo.conf
+file and the
+.Xr sudo_plugin @mansectform@
+manual for more information about the
+.Nm
+plugin architecture.
+.Sh EXIT VALUE
+Upon successful execution of a command, the exit status from
+.Nm
+will be the exit status of the program that was executed.
+If the command terminated due to receipt of a signal,
+.Nm
+will send itself the same signal that terminated the command.
+.Pp
+If the
+.Fl l
+option was specified without a command,
+.Nm
+will exit with a value of 0 if the user is allowed to run
+.Nm
+and they authenticated successfully (as required by the security policy).
+If a command is specified with the
+.Fl l
+option, the exit value will only be 0 if the command is permitted by the
+security policy, otherwise it will be 1.
+.Pp
+If there is an authentication failure, a configuration/permission
+problem or if the given command cannot be executed,
+.Nm
+exits with a value of 1.
+In the latter case, the error string is printed to the standard error.
+If
+.Nm
+cannot
+.Xr stat 2
+one or more entries in the user's
+.Ev PATH ,
+an error is printed to the standard error.
+(If the directory does not exist or if it is not really a directory,
+the entry is ignored and no error is printed.)
+This should not happen under normal circumstances.
+The most common reason for
+.Xr stat 2
+to return
+.Dq permission denied
+is if you are running an automounter and one of the directories in
+your
+.Ev PATH
+is on a machine that is currently unreachable.
+.Sh SECURITY NOTES
+.Nm
+tries to be safe when executing external commands.
+.Pp
+To prevent command spoofing,
+.Nm
+checks "." and "" (both denoting current directory) last when
+searching for a command in the user's
+.Ev PATH
+(if one or both are in the
+.Ev PATH ) .
+Note, however, that the actual
+.Ev PATH
+environment variable is
+.Em not
+modified and is passed unchanged to the program that
+.Nm
+executes.
+.Pp
+Users should
+.Em never
+be granted
+.Nm
+privileges to execute files that are writable by the user or
+that reside in a directory that is writable by the user.
+If the user can modify or replace the command there is no way
+to limit what additional commands they can run.
+.Pp
+Please note that
+.Nm
+will normally only log the command it explicitly runs.
+If a user runs a command such as
+.Li sudo su
+or
+.Li sudo sh ,
+subsequent commands run from that shell are not subject to
+.Nm sudo Ns 's
+security policy.
+The same is true for commands that offer shell escapes (including
+most editors).
+If I/O logging is enabled, subsequent commands will have their input and/or
+output logged, but there will not be traditional logs for those commands.
+Because of this, care must be taken when giving users access to commands via
+.Nm
+to verify that the command does not inadvertently give the user an
+effective root shell.
+For more information, please see the
+.Em Preventing shell escapes
+section in
+.Xr sudoers @mansectform@ .
+.Pp
+To prevent the disclosure of potentially sensitive information,
+.Nm
+disables core dumps by default while it is executing (they are
+re-enabled for the command that is run).
+This historical practice dates from a time when most operating
+systems allowed setuid processes to dump core by default.
+To aid in debugging
+.Nm
+crashes, you may wish to re-enable core dumps by setting
+.Dq disable_coredump
+to false in the
+.Xr sudo.conf @mansectform@
+file as follows:
+.Bd -literal -offset indent
+Set disable_coredump false
+.Ed
+.Pp
+See the
+.Xr sudo.conf @mansectform@
+manual for more information.
+.Sh ENVIRONMENT
+.Nm
+utilizes the following environment variables.
+The security policy has control over the actual content of the command's
+environment.
+.Bl -tag -width 15n
+.It Ev EDITOR
+Default editor to use in
+.Fl e
+(sudoedit) mode if neither
+.Ev SUDO_EDITOR
+nor
+.Ev VISUAL
+is set.
+.It Ev MAIL
+Set to the mail spool of the target user when the
+.Fl i
+option is specified or when
+.Em env_reset
+is enabled in
+.Em sudoers
+(unless
+.Ev MAIL
+is present in the
+.Em env_keep
+list).
+.It Ev HOME
+Set to the home directory of the target user when the
+.Fl i
+or
+.Fl H
+options are specified, when the
+.Fl s
+option is specified and
+.Em set_home
+is set in
+.Em sudoers ,
+when
+.Em always_set_home
+is enabled in
+.Em sudoers ,
+or when
+.Em env_reset
+is enabled in
+.Em sudoers
+and
+.Em HOME
+is not present in the
+.Em env_keep
+list.
+.It Ev LOGNAME
+Set to the login name of the target user when the
+.Fl i
+option is specified, when the
+.Em set_logname
+option is enabled in
+.Em sudoers
+or when the
+.Em env_reset
+option is enabled in
+.Em sudoers
+(unless
+.Ev LOGNAME
+is present in the
+.Em env_keep
+list).
+.It Ev PATH
+May be overridden by the security policy.
+.It Ev SHELL
+Used to determine shell to run with
+.Fl s
+option.
+.It Ev SUDO_ASKPASS
+Specifies the path to a helper program used to read the password
+if no terminal is available or if the
+.Fl A
+option is specified.
+.It Ev SUDO_COMMAND
+Set to the command run by sudo.
+.It Ev SUDO_EDITOR
+Default editor to use in
+.Fl e
+(sudoedit) mode.
+.It Ev SUDO_GID
+Set to the group ID of the user who invoked sudo.
+.It Ev SUDO_PROMPT
+Used as the default password prompt unless
+the
+.Fl p
+option was specified.
+.It Ev SUDO_PS1
+If set,
+.Ev PS1
+will be set to its value for the program being run.
+.It Ev SUDO_UID
+Set to the user ID of the user who invoked sudo.
+.It Ev SUDO_USER
+Set to the login name of the user who invoked sudo.
+.It Ev USER
+Set to the same value as
+.Ev LOGNAME ,
+described above.
+.It Ev VISUAL
+Default editor to use in
+.Fl e
+(sudoedit) mode if
+.Ev SUDO_EDITOR
+is not set.
+.El
+.Sh FILES
+.Bl -tag -width 24n
+.It Pa @sysconfdir@/sudo.conf
+.Nm
+front end configuration
+.El
+.Sh EXAMPLES
+Note: the following examples assume a properly configured security
+policy.
+.Pp
+To get a file listing of an unreadable directory:
+.Bd -literal -offset indent
+$ sudo ls /usr/local/protected
+.Ed
+.Pp
+To list the home directory of user yaz on a machine where the file
+system holding ~yaz is not exported as root:
+.Bd -literal -offset indent
+$ sudo -u yaz ls ~yaz
+.Ed
+.Pp
+To edit the
+.Pa index.html
+file as user www:
+.Bd -literal -offset indent
+$ sudoedit -u www ~www/htdocs/index.html
+.Ed
+.Pp
+To view system logs only accessible to root and users in the adm
+group:
+.Bd -literal -offset indent
+$ sudo -g adm more /var/log/syslog
+.Ed
+.Pp
+To run an editor as jim with a different primary group:
+.Bd -literal -offset indent
+$ sudoedit -u jim -g audio ~jim/sound.txt
+.Ed
+.Pp
+To shut down a machine:
+.Bd -literal -offset indent
+$ sudo shutdown -r +15 "quick reboot"
+.Ed
+.Pp
+To make a usage listing of the directories in the /home partition.
+Note that this runs the commands in a sub-shell to make the
+.Li cd
+and file redirection work.
+.Bd -literal -offset indent
+$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
+.Ed
+.Sh DIAGNOSTICS
+Error messages produced by
+.Nm
+include:
+.Bl -tag -width 4n
+.It Li editing files in a writable directory is not permitted
+By default,
+.Nm sudoedit
+does not permit editing a file when any of the parent directories are writable
+by the invoking user.
+This avoids a race condition that could allow the user to overwrite
+an arbitrary file.
+See the
+.Em sudoedit_checkdir
+option in
+.Xr sudoers @mansectform@
+for more information.
+.It Li editing symbolic links is not permitted
+By default,
+.Nm sudoedit
+does not follow symbolic links when opening files.
+See the
+.Em sudoedit_follow
+option in
+.Xr sudoers @mansectform@
+for more information.
+.It Li effective uid is not 0, is sudo installed setuid root?
+.Nm
+was not run with root privileges.
+The
+.Nm
+binary must be owned by the root user and have the Set-user-ID bit set.
+Also, it must not be located on a file system mounted with the
+.Sq nosuid
+option or on an NFS file system that maps uid 0 to an unprivileged uid.
+.It Li effective uid is not 0, is sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?
+.Nm
+was not run with root privileges.
+The
+.Nm
+binary has the proper owner and permissions but it still did not run
+with root privileges.
+The most common reason for this is that the file system the
+.Nm
+binary is located on is mounted with the
+.Sq nosuid
+option or it is an NFS file system that maps uid 0 to an unprivileged uid.
+.It Li fatal error, unable to load plugins
+An error occurred while loading or initializing the plugins specified in
+.Xr sudo.conf @mansectform@ .
+.It Li invalid environment variable name
+One or more environment variable names specified via the
+.Fl E
+option contained an equal sign
+.Pq Ql = .
+The arguments to the
+.Fl E
+option should be environment variable names without an associated value.
+.It Li no password was provided
+When
+.Nm
+tried to read the password, it did not receive any characters.
+This may happen if no terminal is available (or the
+.Fl S
+option is specified) and the standard input has been redirected from
+.Pa /dev/null .
+.It Li no tty present and no askpass program specified
+.Nm
+needs to read the password but there is no mechanism available to do so.
+A terminal is not present to read the password from,
+.Nm
+has not been configured to read from the standard input,
+and no askpass program has been specified either via the
+.Fl A
+option or the
+.Ev SUDO_ASKPASS
+environment variable.
+.It Li no writable temporary directory found
+.Nm sudoedit
+was unable to find a usable temporary directory in which to store its
+intermediate files.
+.It Li sudo must be owned by uid 0 and have the setuid bit set
+.Nm
+was not run with root privileges.
+The
+.Nm
+binary does not have the correct owner or permissions.
+It must be owned by the root user and have the Set-user-ID bit set.
+.It Li sudoedit is not supported on this platform
+It is only possible to run
+.Nm sudoedit
+on systems that support setting the effective user-ID.
+.It Li timed out reading password
+The user did not enter a password before the password timeout
+(5 minutes by default) expired.
+.It Li you do not exist in the passwd database
+Your user ID does not appear in the system passwd database.
+.It Li you may not specify environment variables in edit mode
+It is only possible to specify environment variables when running
+a command.
+When editing a file, the editor is run with the user's environment unmodified.
+.El
+.Sh SEE ALSO
+.Xr su 1 ,
+.Xr stat 2 ,
+.Xr login_cap 3 ,
+.Xr passwd @mansectform@ ,
+.Xr sudo.conf @mansectform@ ,
+.Xr sudo_plugin @mansectform@ ,
+.Xr sudoers @mansectform@ ,
+.Xr sudoreplay @mansectsu@ ,
+.Xr visudo @mansectsu@
+.Sh HISTORY
+See the HISTORY file in the
+.Nm
+distribution (https://www.sudo.ws/history.html) for a brief
+history of sudo.
+.Sh AUTHORS
+Many people have worked on
+.Nm
+over the years; this version consists of code written primarily by:
+.Bd -ragged -offset indent
+.An Todd C. Miller
+.Ed
+.Pp
+See the CONTRIBUTORS file in the
+.Nm
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+.Nm .
+.Sh CAVEATS
+There is no easy way to prevent a user from gaining a root shell
+if that user is allowed to run arbitrary commands via
+.Nm .
+Also, many programs (such as editors) allow the user to run commands
+via shell escapes, thus avoiding
+.Nm sudo Ns 's
+checks.
+However, on most systems it is possible to prevent shell escapes with the
+.Xr sudoers @mansectform@
+plugin's
+.Em noexec
+functionality.
+.Pp
+It is not meaningful to run the
+.Li cd
+command directly via sudo, e.g.,
+.Bd -literal -offset indent
+$ sudo cd /usr/local/protected
+.Ed
+.Pp
+since when the command exits the parent process (your shell) will
+still be the same.
+Please see the
+.Sx EXAMPLES
+section for more information.
+.Pp
+Running shell scripts via
+.Nm
+can expose the same kernel bugs that make setuid shell scripts
+unsafe on some operating systems (if your OS has a /dev/fd/ directory,
+setuid shell scripts are generally safe).
+.Sh BUGS
+If you feel you have found a bug in
+.Nm ,
+please submit a bug report at https://bugzilla.sudo.ws/
+.Sh SUPPORT
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.Sh DISCLAIMER
+.Nm
+is provided
+.Dq AS IS
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+.Nm
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/sudo_plugin.cat b/doc/sudo_plugin.cat
new file mode 100644
index 0000000..eda4ceb
--- /dev/null
+++ b/doc/sudo_plugin.cat
@@ -0,0 +1,1683 @@
+SUDO_PLUGIN(4) File Formats Manual SUDO_PLUGIN(4)
+
+NNAAMMEE
+ ssuuddoo__pplluuggiinn - Sudo Plugin API
+
+DDEESSCCRRIIPPTTIIOONN
+ Starting with version 1.8, ssuuddoo supports a plugin API for policy and
+ session logging. Plugins may be compiled as dynamic shared objects (the
+ default on systems that support them) or compiled statically into the
+ ssuuddoo binary itself. By default, the ssuuddooeerrss policy plugin and an
+ associated I/O logging plugin are used. Via the plugin API, ssuuddoo can be
+ configured to use alternate policy and/or I/O logging plugins provided by
+ third parties. The plugins to be used are specified in the sudo.conf(4)
+ file.
+
+ The API is versioned with a major and minor number. The minor version
+ number is incremented when additions are made. The major number is
+ incremented when incompatible changes are made. A plugin should be check
+ the version passed to it and make sure that the major version matches.
+
+ The plugin API is defined by the sudo_plugin.h header file.
+
+ PPoolliiccyy pplluuggiinn AAPPII
+ A policy plugin must declare and populate a policy_plugin struct in the
+ global scope. This structure contains pointers to the functions that
+ implement the ssuuddoo policy checks. The name of the symbol should be
+ specified in sudo.conf(4) along with a path to the plugin so that ssuuddoo
+ can load it.
+
+ struct policy_plugin {
+ #define SUDO_POLICY_PLUGIN 1
+ unsigned int type; /* always SUDO_POLICY_PLUGIN */
+ unsigned int version; /* always SUDO_API_VERSION */
+ int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const user_env[],
+ char * const plugin_options[]);
+ void (*close)(int exit_status, int error);
+ int (*show_version)(int verbose);
+ int (*check_policy)(int argc, char * const argv[],
+ char *env_add[], char **command_info[],
+ char **argv_out[], char **user_env_out[]);
+ int (*list)(int argc, char * const argv[], int verbose,
+ const char *list_user);
+ int (*validate)(void);
+ void (*invalidate)(int remove);
+ int (*init_session)(struct passwd *pwd, char **user_env[]);
+ void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+ void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
+ };
+
+ The policy_plugin struct has the following fields:
+
+ type The type field should always be set to SUDO_POLICY_PLUGIN.
+
+ version
+ The version field should be set to SUDO_API_VERSION.
+
+ This allows ssuuddoo to determine the API version the plugin was built
+ against.
+
+ open
+ int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const user_env[],
+ char * const plugin_options[]);
+
+ Returns 1 on success, 0 on failure, -1 if a general error occurred,
+ or -2 if there was a usage error. In the latter case, ssuuddoo will
+ print a usage message before it exits. If an error occurs, the
+ plugin may optionally call the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff()
+ function with SUDO_CONF_ERROR_MSG to present additional error
+ information to the user.
+
+ The function arguments are as follows:
+
+ version
+ The version passed in by ssuuddoo allows the plugin to determine
+ the major and minor version number of the plugin API
+ supported by ssuuddoo.
+
+ conversation
+ A pointer to the ccoonnvveerrssaattiioonn() function that can be used by
+ the plugin to interact with the user (see below). Returns 0
+ on success and -1 on failure.
+
+ plugin_printf
+ A pointer to a pprriinnttff()-style function that may be used to
+ display informational or error messages (see below). Returns
+ the number of characters printed on success and -1 on
+ failure.
+
+ settings
+ A vector of user-supplied ssuuddoo settings in the form of
+ "name=value" strings. The vector is terminated by a NULL
+ pointer. These settings correspond to flags the user
+ specified when running ssuuddoo. As such, they will only be
+ present when the corresponding flag has been specified on the
+ command line.
+
+ When parsing _s_e_t_t_i_n_g_s, the plugin should split on the ffiirrsstt
+ equal sign (`=') since the _n_a_m_e field will never include one
+ itself but the _v_a_l_u_e might.
+
+ bsdauth_type=string
+ Authentication type, if specified by the --aa flag, to
+ use on systems where BSD authentication is supported.
+
+ closefrom=number
+ If specified, the user has requested via the --CC flag
+ that ssuuddoo close all files descriptors with a value of
+ _n_u_m_b_e_r or higher. The plugin may optionally pass this,
+ or another value, back in the _c_o_m_m_a_n_d___i_n_f_o list.
+
+ debug_flags=string
+ A debug file path name followed by a space and a comma-
+ separated list of debug flags that correspond to the
+ plugin's Debug entry in sudo.conf(4), if there is one.
+ The flags are passed to the plugin exactly as they
+ appear in sudo.conf(4). The syntax used by ssuuddoo and
+ the ssuuddooeerrss plugin is _s_u_b_s_y_s_t_e_m@_p_r_i_o_r_i_t_y but a plugin
+ is free to use a different format so long as it does
+ not include a comma (`,'). Prior to ssuuddoo 1.8.12, there
+ was no way to specify plugin-specific _d_e_b_u_g___f_l_a_g_s so
+ the value was always the same as that used by the ssuuddoo
+ front end and did not include a path name, only the
+ flags themselves. As of version 1.7 of the plugin
+ interface, ssuuddoo will only pass _d_e_b_u_g___f_l_a_g_s if
+ sudo.conf(4) contains a plugin-specific Debug entry.
+
+ debug_level=number
+ This setting has been deprecated in favor of
+ _d_e_b_u_g___f_l_a_g_s.
+
+ ignore_ticket=bool
+ Set to true if the user specified the --kk flag along
+ with a command, indicating that the user wishes to
+ ignore any cached authentication credentials.
+ _i_m_p_l_i_e_d___s_h_e_l_l to true. This allows ssuuddoo with no
+ arguments to be used similarly to su(1). If the plugin
+ does not to support this usage, it may return a value
+ of -2 from the cchheecckk__ppoolliiccyy() function, which will
+ cause ssuuddoo to print a usage message and exit.
+
+ implied_shell=bool
+ If the user does not specify a program on the command
+ line, ssuuddoo will pass the plugin the path to the user's
+ shell and set
+
+ login_class=string
+ BSD login class to use when setting resource limits and
+ nice value, if specified by the --cc flag.
+
+ login_shell=bool
+ Set to true if the user specified the --ii flag,
+ indicating that the user wishes to run a login shell.
+
+ max_groups=int
+ The maximum number of groups a user may belong to.
+ This will only be present if there is a corresponding
+ setting in sudo.conf(4).
+
+ network_addrs=list
+ A space-separated list of IP network addresses and
+ netmasks in the form "addr/netmask", e.g.,
+ "192.168.1.2/255.255.255.0". The address and netmask
+ pairs may be either IPv4 or IPv6, depending on what the
+ operating system supports. If the address contains a
+ colon (`:'), it is an IPv6 address, else it is IPv4.
+
+ noninteractive=bool
+ Set to true if the user specified the --nn flag,
+ indicating that ssuuddoo should operate in non-interactive
+ mode. The plugin may reject a command run in non-
+ interactive mode if user interaction is required.
+
+ plugin_dir=string
+ The default plugin directory used by the ssuuddoo front
+ end. This is the default directory set at compile time
+ and may not correspond to the directory the running
+ plugin was loaded from. It may be used by a plugin to
+ locate support files.
+
+ plugin_path=string
+ The path name of plugin loaded by the ssuuddoo front end.
+ The path name will be a fully-qualified unless the
+ plugin was statically compiled into ssuuddoo.
+
+ preserve_environment=bool
+ Set to true if the user specified the --EE flag,
+ indicating that the user wishes to preserve the
+ environment.
+
+ preserve_groups=bool
+ Set to true if the user specified the --PP flag,
+ indicating that the user wishes to preserve the group
+ vector instead of setting it based on the runas user.
+
+ progname=string
+ The command name that sudo was run as, typically "sudo"
+ or "sudoedit".
+
+ prompt=string
+ The prompt to use when requesting a password, if
+ specified via the --pp flag.
+
+ remote_host=string
+ The name of the remote host to run the command on, if
+ specified via the --hh option. Support for running the
+ command on a remote host is meant to be implemented via
+ a helper program that is executed in place of the user-
+ specified command. The ssuuddoo front end is only capable
+ of executing commands on the local host. Only
+ available starting with API version 1.4.
+
+ run_shell=bool
+ Set to true if the user specified the --ss flag,
+ indicating that the user wishes to run a shell.
+
+ runas_group=string
+ The group name or gid to run the command as, if
+ specified via the --gg flag.
+
+ runas_user=string
+ The user name or uid to run the command as, if
+ specified via the --uu flag.
+
+ selinux_role=string
+ SELinux role to use when executing the command, if
+ specified by the --rr flag.
+
+ selinux_type=string
+ SELinux type to use when executing the command, if
+ specified by the --tt flag.
+
+ set_home=bool
+ Set to true if the user specified the --HH flag. If
+ true, set the HOME environment variable to the target
+ user's home directory.
+
+ sudoedit=bool
+ Set to true when the --ee flag is specified or if invoked
+ as ssuuddooeeddiitt. The plugin shall substitute an editor
+ into _a_r_g_v in the cchheecckk__ppoolliiccyy() function or return -2
+ with a usage error if the plugin does not support
+ _s_u_d_o_e_d_i_t. For more information, see the _c_h_e_c_k___p_o_l_i_c_y
+ section.
+
+ timeout=string
+ User-specified command timeout. Not all plugins
+ support command timeouts and the ability for the user
+ to set a timeout may be restricted by policy. The
+ format of the timeout string is plugin-specific.
+
+ Additional settings may be added in the future so the plugin
+ should silently ignore settings that it does not recognize.
+
+ user_info
+ A vector of information about the user running the command in
+ the form of "name=value" strings. The vector is terminated
+ by a NULL pointer.
+
+ When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt
+ equal sign (`=') since the _n_a_m_e field will never include one
+ itself but the _v_a_l_u_e might.
+
+ cols=int
+ The number of columns the user's terminal supports. If
+ there is no terminal device available, a default value
+ of 80 is used.
+
+ cwd=string
+ The user's current working directory.
+
+ egid=gid_t
+ The effective group ID of the user invoking ssuuddoo.
+
+ euid=uid_t
+ The effective user ID of the user invoking ssuuddoo.
+
+ gid=gid_t
+ The real group ID of the user invoking ssuuddoo.
+
+ groups=list
+ The user's supplementary group list formatted as a
+ string of comma-separated group IDs.
+
+ host=string
+ The local machine's hostname as returned by the
+ gethostname(2) system call.
+
+ lines=int
+ The number of lines the user's terminal supports. If
+ there is no terminal device available, a default value
+ of 24 is used.
+
+ pgid=int
+ The ID of the process group that the running ssuuddoo
+ process is a member of. Only available starting with
+ API version 1.2.
+
+ pid=int
+ The process ID of the running ssuuddoo process. Only
+ available starting with API version 1.2.
+
+ plugin_options
+ Any (non-comment) strings immediately after the plugin
+ path are passed as arguments to the plugin. These
+ arguments are split on a white space boundary and are
+ passed to the plugin in the form of a NULL-terminated
+ array of strings. If no arguments were specified,
+ _p_l_u_g_i_n___o_p_t_i_o_n_s will be the NULL pointer.
+
+ NOTE: the _p_l_u_g_i_n___o_p_t_i_o_n_s parameter is only available
+ starting with API version 1.2. A plugin mmuusstt check the
+ API version specified by the ssuuddoo front end before
+ using _p_l_u_g_i_n___o_p_t_i_o_n_s. Failure to do so may result in a
+ crash.
+
+ ppid=int
+ The parent process ID of the running ssuuddoo process.
+ Only available starting with API version 1.2.
+
+ sid=int
+ The session ID of the running ssuuddoo process or 0 if ssuuddoo
+ is not part of a POSIX job control session. Only
+ available starting with API version 1.2.
+
+ tcpgid=int
+ The ID of the foreground process group associated with
+ the terminal device associated with the ssuuddoo process or
+ -1 if there is no terminal present. Only available
+ starting with API version 1.2.
+
+ tty=string
+ The path to the user's terminal device. If the user
+ has no terminal device associated with the session, the
+ value will be empty, as in "tty=".
+
+ uid=uid_t
+ The real user ID of the user invoking ssuuddoo.
+
+ umask=octal
+ The invoking user's file creation mask. Only available
+ starting with API version 1.10.
+
+ user=string
+ The name of the user invoking ssuuddoo.
+
+ user_env
+ The user's environment in the form of a NULL-terminated
+ vector of "name=value" strings.
+
+ When parsing _u_s_e_r___e_n_v, the plugin should split on the ffiirrsstt
+ equal sign (`=') since the _n_a_m_e field will never include one
+ itself but the _v_a_l_u_e might.
+
+ close
+ void (*close)(int exit_status, int error);
+
+ The cclloossee() function is called when the command being run by ssuuddoo
+ finishes.
+
+ The function arguments are as follows:
+
+ exit_status
+ The command's exit status, as returned by the wait(2) system
+ call. The value of exit_status is undefined if error is non-
+ zero.
+
+ error
+ If the command could not be executed, this is set to the
+ value of errno set by the execve(2) system call. The plugin
+ is responsible for displaying error information via the
+ ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff() function. If the command
+ was successfully executed, the value of error is 0.
+
+ If no cclloossee() function is defined, no I/O logging plugins are
+ loaded, and neither the _t_i_m_e_o_u_t not _u_s_e___p_t_y options are set in the
+ command_info list, the ssuuddoo front end may execute the command
+ directly instead of running it as a child process.
+
+ show_version
+ int (*show_version)(int verbose);
+
+ The sshhooww__vveerrssiioonn() function is called by ssuuddoo when the user
+ specifies the --VV option. The plugin may display its version
+ information to the user via the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff()
+ function using SUDO_CONV_INFO_MSG. If the user requests detailed
+ version information, the verbose flag will be set.
+
+ Returns 1 on success, 0 on failure, -1 if a general error occurred,
+ or -2 if there was a usage error, although the return value is
+ currently ignored.
+
+ check_policy
+ int (*check_policy)(int argc, char * const argv[],
+ char *env_add[], char **command_info[],
+ char **argv_out[], char **user_env_out[]);
+
+ The cchheecckk__ppoolliiccyy() function is called by ssuuddoo to determine whether
+ the user is allowed to run the specified commands.
+
+ If the _s_u_d_o_e_d_i_t option was enabled in the _s_e_t_t_i_n_g_s array passed to
+ the ooppeenn() function, the user has requested _s_u_d_o_e_d_i_t mode.
+ _s_u_d_o_e_d_i_t is a mechanism for editing one or more files where an
+ editor is run with the user's credentials instead of with elevated
+ privileges. ssuuddoo achieves this by creating user-writable temporary
+ copies of the files to be edited and then overwriting the originals
+ with the temporary copies after editing is complete. If the plugin
+ supports _s_u_d_o_e_d_i_t, it should choose the editor to be used,
+ potentially from a variable in the user's environment, such as
+ EDITOR, and include it in _a_r_g_v___o_u_t (note that environment variables
+ may include command line flags). The files to be edited should be
+ copied from _a_r_g_v into _a_r_g_v___o_u_t, separated from the editor and its
+ arguments by a "--" element. The "--" will be removed by ssuuddoo
+ before the editor is executed. The plugin should also set
+ _s_u_d_o_e_d_i_t_=_t_r_u_e in the _c_o_m_m_a_n_d___i_n_f_o list.
+
+ The cchheecckk__ppoolliiccyy() function returns 1 if the command is allowed, 0
+ if not allowed, -1 for a general error, or -2 for a usage error or
+ if _s_u_d_o_e_d_i_t was specified but is unsupported by the plugin. In the
+ latter case, ssuuddoo will print a usage message before it exits. If
+ an error occurs, the plugin may optionally call the ccoonnvveerrssaattiioonn()
+ or pplluuggiinn__pprriinnttff() function with SUDO_CONF_ERROR_MSG to present
+ additional error information to the user.
+
+ The function arguments are as follows:
+
+ argc The number of elements in _a_r_g_v, not counting the final NULL
+ pointer.
+
+ argv The argument vector describing the command the user wishes to
+ run, in the same form as what would be passed to the
+ execve(2) system call. The vector is terminated by a NULL
+ pointer.
+
+ env_add
+ Additional environment variables specified by the user on the
+ command line in the form of a NULL-terminated vector of
+ "name=value" strings. The plugin may reject the command if
+ one or more variables are not allowed to be set, or it may
+ silently ignore such variables.
+
+ When parsing _e_n_v___a_d_d, the plugin should split on the ffiirrsstt
+ equal sign (`=') since the _n_a_m_e field will never include one
+ itself but the _v_a_l_u_e might.
+
+ command_info
+ Information about the command being run in the form of
+ "name=value" strings. These values are used by ssuuddoo to set
+ the execution environment when running a command. The plugin
+ is responsible for creating and populating the vector, which
+ must be terminated with a NULL pointer. The following values
+ are recognized by ssuuddoo:
+
+ chroot=string
+ The root directory to use when running the command.
+
+ closefrom=number
+ If specified, ssuuddoo will close all files descriptors
+ with a value of _n_u_m_b_e_r or higher.
+
+ command=string
+ Fully qualified path to the command to be executed.
+
+ cwd=string
+ The current working directory to change to when
+ executing the command.
+
+ exec_background=bool
+ By default, ssuuddoo runs a command as the foreground
+ process as long as ssuuddoo itself is running in the
+ foreground. When _e_x_e_c___b_a_c_k_g_r_o_u_n_d is enabled and the
+ command is being run in a pty (due to I/O logging or
+ the _u_s_e___p_t_y setting), the command will be run as a
+ background process. Attempts to read from the
+ controlling terminal (or to change terminal settings)
+ will result in the command being suspended with the
+ SIGTTIN signal (or SIGTTOU in the case of terminal
+ settings). If this happens when ssuuddoo is a foreground
+ process, the command will be granted the controlling
+ terminal and resumed in the foreground with no user
+ intervention required. The advantage of initially
+ running the command in the background is that ssuuddoo need
+ not read from the terminal unless the command
+ explicitly requests it. Otherwise, any terminal input
+ must be passed to the command, whether it has required
+ it or not (the kernel buffers terminals so it is not
+ possible to tell whether the command really wants the
+ input). This is different from historic _s_u_d_o behavior
+ or when the command is not being run in a pty.
+
+ For this to work seamlessly, the operating system must
+ support the automatic restarting of system calls.
+ Unfortunately, not all operating systems do this by
+ default, and even those that do may have bugs. For
+ example, macOS fails to restart the ttccggeettaattttrr() and
+ ttccsseettaattttrr() system calls (this is a bug in macOS).
+ Furthermore, because this behavior depends on the
+ command stopping with the SIGTTIN or SIGTTOU signals,
+ programs that catch these signals and suspend
+ themselves with a different signal (usually SIGTOP)
+ will not be automatically foregrounded. Some versions
+ of the linux su(1) command behave this way. Because of
+ this, a plugin should not set _e_x_e_c___b_a_c_k_g_r_o_u_n_d unless it
+ is explicitly enabled by the administrator and there
+ should be a way to enabled or disable it on a per-
+ command basis.
+
+ This setting has no effect unless I/O logging is
+ enabled or _u_s_e___p_t_y is enabled.
+
+ execfd=number
+ If specified, ssuuddoo will use the fexecve(2) system call
+ to execute the command instead of execve(2). The
+ specified _n_u_m_b_e_r must refer to an open file descriptor.
+
+ iolog_compress=bool
+ Set to true if the I/O logging plugins, if any, should
+ compress the log data. This is a hint to the I/O
+ logging plugin which may choose to ignore it.
+
+ iolog_group=string
+ The group that will own newly created I/O log files and
+ directories. This is a hint to the I/O logging plugin
+ which may choose to ignore it.
+
+ iolog_mode=octal
+ The file permission mode to use when creating I/O log
+ files and directories. This is a hint to the I/O
+ logging plugin which may choose to ignore it.
+
+ iolog_user=string
+ The user that will own newly created I/O log files and
+ directories. This is a hint to the I/O logging plugin
+ which may choose to ignore it.
+
+ iolog_path=string
+ Fully qualified path to the file or directory in which
+ I/O log is to be stored. This is a hint to the I/O
+ logging plugin which may choose to ignore it. If no
+ I/O logging plugin is loaded, this setting has no
+ effect.
+
+ iolog_stdin=bool
+ Set to true if the I/O logging plugins, if any, should
+ log the standard input if it is not connected to a
+ terminal device. This is a hint to the I/O logging
+ plugin which may choose to ignore it.
+
+ iolog_stdout=bool
+ Set to true if the I/O logging plugins, if any, should
+ log the standard output if it is not connected to a
+ terminal device. This is a hint to the I/O logging
+ plugin which may choose to ignore it.
+
+ iolog_stderr=bool
+ Set to true if the I/O logging plugins, if any, should
+ log the standard error if it is not connected to a
+ terminal device. This is a hint to the I/O logging
+ plugin which may choose to ignore it.
+
+ iolog_ttyin=bool
+ Set to true if the I/O logging plugins, if any, should
+ log all terminal input. This only includes input typed
+ by the user and not from a pipe or redirected from a
+ file. This is a hint to the I/O logging plugin which
+ may choose to ignore it.
+
+ iolog_ttyout=bool
+ Set to true if the I/O logging plugins, if any, should
+ log all terminal output. This only includes output to
+ the screen, not output to a pipe or file. This is a
+ hint to the I/O logging plugin which may choose to
+ ignore it.
+
+ login_class=string
+ BSD login class to use when setting resource limits and
+ nice value (optional). This option is only set on
+ systems that support login classes.
+
+ nice=int
+ Nice value (priority) to use when executing the
+ command. The nice value, if specified, overrides the
+ priority associated with the _l_o_g_i_n___c_l_a_s_s on BSD
+ systems.
+
+ noexec=bool
+ If set, prevent the command from executing other
+ programs.
+
+ preserve_fds=list
+ A comma-separated list of file descriptors that should
+ be preserved, regardless of the value of the _c_l_o_s_e_f_r_o_m
+ setting. Only available starting with API version 1.5.
+
+ preserve_groups=bool
+ If set, ssuuddoo will preserve the user's group vector
+ instead of initializing the group vector based on
+ runas_user.
+
+ runas_egid=gid
+ Effective group ID to run the command as. If not
+ specified, the value of _r_u_n_a_s___g_i_d is used.
+
+ runas_euid=uid
+ Effective user ID to run the command as. If not
+ specified, the value of _r_u_n_a_s___u_i_d is used.
+
+ runas_gid=gid
+ Group ID to run the command as.
+
+ runas_groups=list
+ The supplementary group vector to use for the command
+ in the form of a comma-separated list of group IDs. If
+ _p_r_e_s_e_r_v_e___g_r_o_u_p_s is set, this option is ignored.
+
+ runas_uid=uid
+ User ID to run the command as.
+
+ selinux_role=string
+ SELinux role to use when executing the command.
+
+ selinux_type=string
+ SELinux type to use when executing the command.
+
+ set_utmp=bool
+ Create a utmp (or utmpx) entry when a pseudo-tty is
+ allocated. By default, the new entry will be a copy of
+ the user's existing utmp entry (if any), with the tty,
+ time, type and pid fields updated.
+
+ sudoedit=bool
+ Set to true when in _s_u_d_o_e_d_i_t mode. The plugin may
+ enable _s_u_d_o_e_d_i_t mode even if ssuuddoo was not invoked as
+ ssuuddooeeddiitt. This allows the plugin to perform command
+ substitution and transparently enable _s_u_d_o_e_d_i_t when the
+ user attempts to run an editor.
+
+ sudoedit_checkdir=bool
+ Set to false to disable directory writability checks in
+ ssuuddooeeddiitt. By default, ssuuddooeeddiitt 1.8.16 and higher will
+ check all directory components of the path to be edited
+ for writability by the invoking user. Symbolic links
+ will not be followed in writable directories and
+ ssuuddooeeddiitt will refuse to edit a file located in a
+ writable directory. These restrictions are not
+ enforced when ssuuddooeeddiitt is run by root. The
+ _s_u_d_o_e_d_i_t___f_o_l_l_o_w option can be set to false to disable
+ this check. Only available starting with API version
+ 1.8.
+
+ sudoedit_follow=bool
+ Set to true to allow ssuuddooeeddiitt to edit files that are
+ symbolic links. By default, ssuuddooeeddiitt 1.8.15 and higher
+ will refuse to open a symbolic link. The
+ _s_u_d_o_e_d_i_t___f_o_l_l_o_w option can be used to restore the older
+ behavior and allow ssuuddooeeddiitt to open symbolic links.
+ Only available starting with API version 1.8.
+
+ timeout=int
+ Command timeout. If non-zero then when the timeout
+ expires the command will be killed.
+
+ umask=octal
+ The file creation mask to use when executing the
+ command.
+
+ use_pty=bool
+ Allocate a pseudo-tty to run the command in, regardless
+ of whether or not I/O logging is in use. By default,
+ ssuuddoo will only run the command in a pty when an I/O log
+ plugin is loaded.
+
+ utmp_user=string
+ User name to use when constructing a new utmp (or
+ utmpx) entry when _s_e_t___u_t_m_p is enabled. This option can
+ be used to set the user field in the utmp entry to the
+ user the command runs as rather than the invoking user.
+ If not set, ssuuddoo will base the new entry on the
+ invoking user's existing entry.
+
+ Unsupported values will be ignored.
+
+ argv_out
+ The NULL-terminated argument vector to pass to the execve(2)
+ system call when executing the command. The plugin is
+ responsible for allocating and populating the vector.
+
+ user_env_out
+ The NULL-terminated environment vector to use when executing
+ the command. The plugin is responsible for allocating and
+ populating the vector.
+
+ list
+ int (*list)(int argc, char * const argv[],
+ int verbose, const char *list_user);
+
+ List available privileges for the invoking user. Returns 1 on
+ success, 0 on failure and -1 on error. On error, the plugin may
+ optionally call the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff() function with
+ SUDO_CONF_ERROR_MSG to present additional error information to the
+ user.
+
+ Privileges should be output via the ccoonnvveerrssaattiioonn() or
+ pplluuggiinn__pprriinnttff() function using SUDO_CONV_INFO_MSG,
+
+ verbose
+ Flag indicating whether to list in verbose mode or not.
+
+ list_user
+ The name of a different user to list privileges for if the
+ policy allows it. If NULL, the plugin should list the
+ privileges of the invoking user.
+
+ argc The number of elements in _a_r_g_v, not counting the final NULL
+ pointer.
+
+ argv If non-NULL, an argument vector describing a command the user
+ wishes to check against the policy in the same form as what
+ would be passed to the execve(2) system call. If the command
+ is permitted by the policy, the fully-qualified path to the
+ command should be displayed along with any command line
+ arguments.
+
+ validate
+ int (*validate)(void);
+
+ The vvaalliiddaattee() function is called when ssuuddoo is run with the --vv
+ flag. For policy plugins such as ssuuddooeerrss that cache authentication
+ credentials, this function will validate and cache the credentials.
+
+ The vvaalliiddaattee() function should be NULL if the plugin does not
+ support credential caching.
+
+ Returns 1 on success, 0 on failure and -1 on error. On error, the
+ plugin may optionally call the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff()
+ function with SUDO_CONF_ERROR_MSG to present additional error
+ information to the user.
+
+ invalidate
+ void (*invalidate)(int remove);
+
+ The iinnvvaalliiddaattee() function is called when ssuuddoo is called with the --kk
+ or --KK flag. For policy plugins such as ssuuddooeerrss that cache
+ authentication credentials, this function will invalidate the
+ credentials. If the _r_e_m_o_v_e flag is set, the plugin may remove the
+ credentials instead of simply invalidating them.
+
+ The iinnvvaalliiddaattee() function should be NULL if the plugin does not
+ support credential caching.
+
+ init_session
+ int (*init_session)(struct passwd *pwd, char **user_envp[);
+
+ The iinniitt__sseessssiioonn() function is called before ssuuddoo sets up the
+ execution environment for the command. It is run in the parent
+ ssuuddoo process and before any uid or gid changes. This can be used
+ to perform session setup that is not supported by _c_o_m_m_a_n_d___i_n_f_o,
+ such as opening the PAM session. The cclloossee() function can be used
+ to tear down the session that was opened by init_session.
+
+ The _p_w_d argument points to a passwd struct for the user the command
+ will be run as if the uid the command will run as was found in the
+ password database, otherwise it will be NULL.
+
+ The _u_s_e_r___e_n_v argument points to the environment the command will
+ run in, in the form of a NULL-terminated vector of "name=value"
+ strings. This is the same string passed back to the front end via
+ the Policy Plugin's _u_s_e_r___e_n_v___o_u_t parameter. If the iinniitt__sseessssiioonn()
+ function needs to modify the user environment, it should update the
+ pointer stored in _u_s_e_r___e_n_v. The expected use case is to merge the
+ contents of the PAM environment (if any) with the contents of
+ _u_s_e_r___e_n_v. NOTE: the _u_s_e_r___e_n_v parameter is only available starting
+ with API version 1.2. A plugin mmuusstt check the API version
+ specified by the ssuuddoo front end before using _u_s_e_r___e_n_v. Failure to
+ do so may result in a crash.
+
+ Returns 1 on success, 0 on failure and -1 on error. On error, the
+ plugin may optionally call the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff()
+ function with SUDO_CONF_ERROR_MSG to present additional error
+ information to the user.
+
+ register_hooks
+ void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+
+ The rreeggiisstteerr__hhooookkss() function is called by the sudo front end to
+ register any hooks the plugin needs. If the plugin does not
+ support hooks, register_hooks should be set to the NULL pointer.
+
+ The _v_e_r_s_i_o_n argument describes the version of the hooks API
+ supported by the ssuuddoo front end.
+
+ The rreeggiisstteerr__hhooookk() function should be used to register any
+ supported hooks the plugin needs. It returns 0 on success, 1 if
+ the hook type is not supported and -1 if the major version in
+ struct hook does not match the front end's major hook API version.
+
+ See the _H_o_o_k _f_u_n_c_t_i_o_n _A_P_I section below for more information about
+ hooks.
+
+ NOTE: the rreeggiisstteerr__hhooookkss() function is only available starting with
+ API version 1.2. If the ssuuddoo front end doesn't support API version
+ 1.2 or higher, register_hooks will not be called.
+
+ deregister_hooks
+ void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
+
+ The ddeerreeggiisstteerr__hhooookkss() function is called by the sudo front end to
+ deregister any hooks the plugin has registered. If the plugin does
+ not support hooks, deregister_hooks should be set to the NULL
+ pointer.
+
+ The _v_e_r_s_i_o_n argument describes the version of the hooks API
+ supported by the ssuuddoo front end.
+
+ The ddeerreeggiisstteerr__hhooookk() function should be used to deregister any
+ hooks that were put in place by the rreeggiisstteerr__hhooookk() function. If
+ the plugin tries to deregister a hook that the front end does not
+ support, deregister_hook will return an error.
+
+ See the _H_o_o_k _f_u_n_c_t_i_o_n _A_P_I section below for more information about
+ hooks.
+
+ NOTE: the ddeerreeggiisstteerr__hhooookkss() function is only available starting
+ with API version 1.2. If the ssuuddoo front end doesn't support API
+ version 1.2 or higher, deregister_hooks will not be called.
+
+ _P_o_l_i_c_y _P_l_u_g_i_n _V_e_r_s_i_o_n _M_a_c_r_o_s
+
+ /* Plugin API version major/minor. */
+ #define SUDO_API_VERSION_MAJOR 1
+ #define SUDO_API_VERSION_MINOR 13
+ #define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
+ #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\
+ SUDO_API_VERSION_MINOR)
+
+ /* Getters and setters for API version */
+ #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
+ #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
+ #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \
+ *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
+ } while(0)
+ #define SUDO_API_VERSION_SET_MINOR(vp, n) do { \
+ *(vp) = (*(vp) & 0xffff0000) | (n); \
+ } while(0)
+
+ II//OO pplluuggiinn AAPPII
+ struct io_plugin {
+ #define SUDO_IO_PLUGIN 2
+ unsigned int type; /* always SUDO_IO_PLUGIN */
+ unsigned int version; /* always SUDO_API_VERSION */
+ int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[],
+ char * const plugin_options[]);
+ void (*close)(int exit_status, int error); /* wait status or error */
+ int (*show_version)(int verbose);
+ int (*log_ttyin)(const char *buf, unsigned int len);
+ int (*log_ttyout)(const char *buf, unsigned int len);
+ int (*log_stdin)(const char *buf, unsigned int len);
+ int (*log_stdout)(const char *buf, unsigned int len);
+ int (*log_stderr)(const char *buf, unsigned int len);
+ void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+ void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
+ int (*change_winsize)(unsigned int lines, unsigned int cols);
+ int (*log_suspend)(int signo);
+ };
+
+ When an I/O plugin is loaded, ssuuddoo runs the command in a pseudo-tty.
+ This makes it possible to log the input and output from the user's
+ session. If any of the standard input, standard output or standard error
+ do not correspond to a tty, ssuuddoo will open a pipe to capture the I/O for
+ logging before passing it on.
+
+ The log_ttyin function receives the raw user input from the terminal
+ device (note that this will include input even when echo is disabled,
+ such as when a password is read). The log_ttyout function receives
+ output from the pseudo-tty that is suitable for replaying the user's
+ session at a later time. The lloogg__ssttddiinn(), lloogg__ssttddoouutt() and lloogg__ssttddeerrrr()
+ functions are only called if the standard input, standard output or
+ standard error respectively correspond to something other than a tty.
+
+ Any of the logging functions may be set to the NULL pointer if no logging
+ is to be performed. If the open function returns 0, no I/O will be sent
+ to the plugin.
+
+ If a logging function returns an error (-1), the running command will be
+ terminated and all of the plugin's logging functions will be disabled.
+ Other I/O logging plugins will still receive any remaining input or
+ output that has not yet been processed.
+
+ If an input logging function rejects the data by returning 0, the command
+ will be terminated and the data will not be passed to the command, though
+ it will still be sent to any other I/O logging plugins. If an output
+ logging function rejects the data by returning 0, the command will be
+ terminated and the data will not be written to the terminal, though it
+ will still be sent to any other I/O logging plugins.
+
+ The io_plugin struct has the following fields:
+
+ type The type field should always be set to SUDO_IO_PLUGIN.
+
+ version
+ The version field should be set to SUDO_API_VERSION.
+
+ This allows ssuuddoo to determine the API version the plugin was built
+ against.
+
+ open
+ int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[],
+ char * const plugin_options[]);
+
+ The ooppeenn() function is run before the lloogg__ttttyyiinn(), lloogg__ttttyyoouutt(),
+ lloogg__ssttddiinn(), lloogg__ssttddoouutt(), lloogg__ssttddeerrrr(), lloogg__ssuussppeenndd(),
+ cchhaannggee__wwiinnssiizzee(), or sshhooww__vveerrssiioonn() functions are called. It is
+ only called if the version is being requested or if the policy
+ plugin's cchheecckk__ppoolliiccyy() function has returned successfully. It
+ returns 1 on success, 0 on failure, -1 if a general error occurred,
+ or -2 if there was a usage error. In the latter case, ssuuddoo will
+ print a usage message before it exits. If an error occurs, the
+ plugin may optionally call the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff()
+ function with SUDO_CONF_ERROR_MSG to present additional error
+ information to the user.
+
+ The function arguments are as follows:
+
+ version
+ The version passed in by ssuuddoo allows the plugin to determine
+ the major and minor version number of the plugin API
+ supported by ssuuddoo.
+
+ conversation
+ A pointer to the ccoonnvveerrssaattiioonn() function that may be used by
+ the sshhooww__vveerrssiioonn() function to display version information
+ (see sshhooww__vveerrssiioonn() below). The ccoonnvveerrssaattiioonn() function may
+ also be used to display additional error message to the user.
+ The ccoonnvveerrssaattiioonn() function returns 0 on success and -1 on
+ failure.
+
+ plugin_printf
+ A pointer to a pprriinnttff()-style function that may be used by
+ the sshhooww__vveerrssiioonn() function to display version information
+ (see show_version below). The pplluuggiinn__pprriinnttff() function may
+ also be used to display additional error message to the user.
+ The pplluuggiinn__pprriinnttff() function returns number of characters
+ printed on success and -1 on failure.
+
+ settings
+ A vector of user-supplied ssuuddoo settings in the form of
+ "name=value" strings. The vector is terminated by a NULL
+ pointer. These settings correspond to flags the user
+ specified when running ssuuddoo. As such, they will only be
+ present when the corresponding flag has been specified on the
+ command line.
+
+ When parsing _s_e_t_t_i_n_g_s, the plugin should split on the ffiirrsstt
+ equal sign (`=') since the _n_a_m_e field will never include one
+ itself but the _v_a_l_u_e might.
+
+ See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a list of all possible
+ settings.
+
+ user_info
+ A vector of information about the user running the command in
+ the form of "name=value" strings. The vector is terminated
+ by a NULL pointer.
+
+ When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt
+ equal sign (`=') since the _n_a_m_e field will never include one
+ itself but the _v_a_l_u_e might.
+
+ See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a list of all possible
+ strings.
+
+ argc The number of elements in _a_r_g_v, not counting the final NULL
+ pointer. It can be zero, when ssuuddoo is called with --VV.
+
+ argv If non-NULL, an argument vector describing a command the user
+ wishes to run in the same form as what would be passed to the
+ execve(2) system call.
+
+ user_env
+ The user's environment in the form of a NULL-terminated
+ vector of "name=value" strings.
+
+ When parsing _u_s_e_r___e_n_v, the plugin should split on the ffiirrsstt
+ equal sign (`=') since the _n_a_m_e field will never include one
+ itself but the _v_a_l_u_e might.
+
+ plugin_options
+ Any (non-comment) strings immediately after the plugin path
+ are treated as arguments to the plugin. These arguments are
+ split on a white space boundary and are passed to the plugin
+ in the form of a NULL-terminated array of strings. If no
+ arguments were specified, _p_l_u_g_i_n___o_p_t_i_o_n_s will be the NULL
+ pointer.
+
+ NOTE: the _p_l_u_g_i_n___o_p_t_i_o_n_s parameter is only available starting
+ with API version 1.2. A plugin mmuusstt check the API version
+ specified by the ssuuddoo front end before using _p_l_u_g_i_n___o_p_t_i_o_n_s.
+ Failure to do so may result in a crash.
+
+ close
+ void (*close)(int exit_status, int error);
+
+ The cclloossee() function is called when the command being run by ssuuddoo
+ finishes.
+
+ The function arguments are as follows:
+
+ exit_status
+ The command's exit status, as returned by the wait(2) system
+ call. The value of exit_status is undefined if error is non-
+ zero.
+
+ error
+ If the command could not be executed, this is set to the
+ value of errno set by the execve(2) system call. If the
+ command was successfully executed, the value of error is 0.
+
+ show_version
+ int (*show_version)(int verbose);
+
+ The sshhooww__vveerrssiioonn() function is called by ssuuddoo when the user
+ specifies the --VV option. The plugin may display its version
+ information to the user via the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff()
+ function using SUDO_CONV_INFO_MSG. If the user requests detailed
+ version information, the verbose flag will be set.
+
+ Returns 1 on success, 0 on failure, -1 if a general error occurred,
+ or -2 if there was a usage error, although the return value is
+ currently ignored.
+
+ log_ttyin
+ int (*log_ttyin)(const char *buf, unsigned int len);
+
+ The lloogg__ttttyyiinn() function is called whenever data can be read from
+ the user but before it is passed to the running command. This
+ allows the plugin to reject data if it chooses to (for instance if
+ the input contains banned content). Returns 1 if the data should
+ be passed to the command, 0 if the data is rejected (which will
+ terminate the running command) or -1 if an error occurred.
+
+ The function arguments are as follows:
+
+ buf The buffer containing user input.
+
+ len The length of _b_u_f in bytes.
+
+ log_ttyout
+ int (*log_ttyout)(const char *buf, unsigned int len);
+
+ The lloogg__ttttyyoouutt() function is called whenever data can be read from
+ the command but before it is written to the user's terminal. This
+ allows the plugin to reject data if it chooses to (for instance if
+ the output contains banned content). Returns 1 if the data should
+ be passed to the user, 0 if the data is rejected (which will
+ terminate the running command) or -1 if an error occurred.
+
+ The function arguments are as follows:
+
+ buf The buffer containing command output.
+
+ len The length of _b_u_f in bytes.
+
+ log_stdin
+ int (*log_stdin)(const char *buf, unsigned int len);
+
+ The lloogg__ssttddiinn() function is only used if the standard input does
+ not correspond to a tty device. It is called whenever data can be
+ read from the standard input but before it is passed to the running
+ command. This allows the plugin to reject data if it chooses to
+ (for instance if the input contains banned content). Returns 1 if
+ the data should be passed to the command, 0 if the data is rejected
+ (which will terminate the running command) or -1 if an error
+ occurred.
+
+ The function arguments are as follows:
+
+ buf The buffer containing user input.
+
+ len The length of _b_u_f in bytes.
+
+ log_stdout
+ int (*log_stdout)(const char *buf, unsigned int len);
+
+ The lloogg__ssttddoouutt() function is only used if the standard output does
+ not correspond to a tty device. It is called whenever data can be
+ read from the command but before it is written to the standard
+ output. This allows the plugin to reject data if it chooses to
+ (for instance if the output contains banned content). Returns 1 if
+ the data should be passed to the user, 0 if the data is rejected
+ (which will terminate the running command) or -1 if an error
+ occurred.
+
+ The function arguments are as follows:
+
+ buf The buffer containing command output.
+
+ len The length of _b_u_f in bytes.
+
+ log_stderr
+ int (*log_stderr)(const char *buf, unsigned int len);
+
+ The lloogg__ssttddeerrrr() function is only used if the standard error does
+ not correspond to a tty device. It is called whenever data can be
+ read from the command but before it is written to the standard
+ error. This allows the plugin to reject data if it chooses to (for
+ instance if the output contains banned content). Returns 1 if the
+ data should be passed to the user, 0 if the data is rejected (which
+ will terminate the running command) or -1 if an error occurred.
+
+ The function arguments are as follows:
+
+ buf The buffer containing command output.
+
+ len The length of _b_u_f in bytes.
+
+ register_hooks
+ See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a description of
+ register_hooks.
+
+ deregister_hooks
+ See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a description of
+ deregister_hooks.
+
+ change_winsize
+ int (*change_winsize)(unsigned int lines, unsigned int cols);
+
+ The cchhaannggee__wwiinnssiizzee() function is called whenever the window size of
+ the terminal changes from the initial values specified in the
+ user_info list. Returns -1 if an error occurred, in which case no
+ further calls to cchhaannggee__wwiinnssiizzee() will be made,
+
+ log_suspend
+ int (*log_suspend)(int signo);
+
+ The lloogg__ssuussppeenndd() function is called whenever a command is
+ suspended or resumed. The _s_i_g_n_o argument is either the signal that
+ caused the command to be suspended or SIGCONT if the command was
+ resumed. Logging this information makes it possible to skip the
+ period of time when the command was suspended during playback of a
+ session. Returns -1 if an error occurred, in which case no further
+ calls to lloogg__ssuussppeenndd() will be made,
+
+ _I_/_O _P_l_u_g_i_n _V_e_r_s_i_o_n _M_a_c_r_o_s
+
+ Same as for the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I.
+
+ SSiiggnnaall hhaannddlleerrss
+ The ssuuddoo front end installs default signal handlers to trap common
+ signals while the plugin functions are run. The following signals are
+ trapped by default before the command is executed:
+
+ ++oo SIGALRM
+ ++oo SIGHUP
+ ++oo SIGINT
+ ++oo SIGPIPE
+ ++oo SIGQUIT
+ ++oo SIGTERM
+ ++oo SIGTSTP
+ ++oo SIGUSR1
+ ++oo SIGUSR2
+
+ If a fatal signal is received before the command is executed, ssuuddoo will
+ call the plugin's cclloossee() function with an exit status of 128 plus the
+ value of the signal that was received. This allows for consistent
+ logging of commands killed by a signal for plugins that log such
+ information in their cclloossee() function. An exception to this is SIGPIPE,
+ which is ignored until the command is executed.
+
+ A plugin may temporarily install its own signal handlers but must restore
+ the original handler before the plugin function returns.
+
+ HHooookk ffuunnccttiioonn AAPPII
+ Beginning with plugin API version 1.2, it is possible to install hooks
+ for certain functions called by the ssuuddoo front end.
+
+ Currently, the only supported hooks relate to the handling of environment
+ variables. Hooks can be used to intercept attempts to get, set, or
+ remove environment variables so that these changes can be reflected in
+ the version of the environment that is used to execute a command. A
+ future version of the API will support hooking internal ssuuddoo front end
+ functions as well.
+
+ _H_o_o_k _s_t_r_u_c_t_u_r_e
+
+ Hooks in ssuuddoo are described by the following structure:
+
+ typedef int (*sudo_hook_fn_t)();
+
+ struct sudo_hook {
+ unsigned int hook_version;
+ unsigned int hook_type;
+ sudo_hook_fn_t hook_fn;
+ void *closure;
+ };
+
+ The sudo_hook structure has the following fields:
+
+ hook_version
+ The hook_version field should be set to SUDO_HOOK_VERSION.
+
+ hook_type
+ The hook_type field may be one of the following supported hook
+ types:
+
+ SUDO_HOOK_SETENV
+ The C library setenv(3) function. Any registered hooks will
+ run before the C library implementation. The hook_fn field
+ should be a function that matches the following typedef:
+
+ typedef int (*sudo_hook_fn_setenv_t)(const char *name,
+ const char *value, int overwrite, void *closure);
+
+ If the registered hook does not match the typedef the results
+ are unspecified.
+
+ SUDO_HOOK_UNSETENV
+ The C library unsetenv(3) function. Any registered hooks
+ will run before the C library implementation. The hook_fn
+ field should be a function that matches the following
+ typedef:
+
+ typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
+ void *closure);
+
+ SUDO_HOOK_GETENV
+ The C library getenv(3) function. Any registered hooks will
+ run before the C library implementation. The hook_fn field
+ should be a function that matches the following typedef:
+
+ typedef int (*sudo_hook_fn_getenv_t)(const char *name,
+ char **value, void *closure);
+
+ If the registered hook does not match the typedef the results
+ are unspecified.
+
+ SUDO_HOOK_PUTENV
+ The C library putenv(3) function. Any registered hooks will
+ run before the C library implementation. The hook_fn field
+ should be a function that matches the following typedef:
+
+ typedef int (*sudo_hook_fn_putenv_t)(char *string,
+ void *closure);
+
+ If the registered hook does not match the typedef the results
+ are unspecified.
+
+ hook_fn
+ sudo_hook_fn_t hook_fn;
+
+ The hook_fn field should be set to the plugin's hook
+ implementation. The actual function arguments will vary depending
+ on the hook_type (see hook_type above). In all cases, the closure
+ field of struct sudo_hook is passed as the last function parameter.
+ This can be used to pass arbitrary data to the plugin's hook
+ implementation.
+
+ The function return value may be one of the following:
+
+ SUDO_HOOK_RET_ERROR
+ The hook function encountered an error.
+
+ SUDO_HOOK_RET_NEXT
+ The hook completed without error, go on to the next hook
+ (including the native implementation if applicable). For
+ example, a getenv(3) hook might return SUDO_HOOK_RET_NEXT if
+ the specified variable was not found in the private copy of
+ the environment.
+
+ SUDO_HOOK_RET_STOP
+ The hook completed without error, stop processing hooks for
+ this invocation. This can be used to replace the native
+ implementation. For example, a setenv hook that operates on
+ a private copy of the environment but leaves environ
+ unchanged.
+
+ Note that it is very easy to create an infinite loop when hooking C
+ library functions. For example, a getenv(3) hook that calls the
+ snprintf(3) function may create a loop if the snprintf(3) implementation
+ calls getenv(3) to check the locale. To prevent this, you may wish to
+ use a static variable in the hook function to guard against nested calls.
+ For example:
+
+ static int in_progress = 0; /* avoid recursion */
+ if (in_progress)
+ return SUDO_HOOK_RET_NEXT;
+ in_progress = 1;
+ ...
+ in_progress = 0;
+ return SUDO_HOOK_RET_STOP;
+
+ _H_o_o_k _A_P_I _V_e_r_s_i_o_n _M_a_c_r_o_s
+
+ /* Hook API version major/minor */
+ #define SUDO_HOOK_VERSION_MAJOR 1
+ #define SUDO_HOOK_VERSION_MINOR 0
+ #define SUDO_HOOK_VERSION SUDO_API_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\
+ SUDO_HOOK_VERSION_MINOR)
+
+ For getters and setters see the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I.
+
+ RReemmoottee ccoommmmaanndd eexxeeccuuttiioonn
+ The ssuuddoo front end does not have native support for running remote
+ commands. However, starting with ssuuddoo 1.8.8, the --hh option may be used
+ to specify a remote host that is passed to the policy plugin. A plugin
+ may also accept a _r_u_n_a_s___u_s_e_r in the form of "user@hostname" which will
+ work with older versions of ssuuddoo. It is anticipated that remote commands
+ will be supported by executing a "helper" program. The policy plugin
+ should setup the execution environment such that the ssuuddoo front end will
+ run the helper which, in turn, will connect to the remote host and run
+ the command.
+
+ For example, the policy plugin could utilize sssshh to perform remote
+ command execution. The helper program would be responsible for running
+ sssshh with the proper options to use a private key or certificate that the
+ remote host will accept and run a program on the remote host that would
+ setup the execution environment accordingly.
+
+ Note that remote ssuuddooeeddiitt functionality must be handled by the policy
+ plugin, not ssuuddoo itself as the front end has no knowledge that a remote
+ command is being executed. This may be addressed in a future revision of
+ the plugin API.
+
+ CCoonnvveerrssaattiioonn AAPPII
+ If the plugin needs to interact with the user, it may do so via the
+ ccoonnvveerrssaattiioonn() function. A plugin should not attempt to read directly
+ from the standard input or the user's tty (neither of which are
+ guaranteed to exist). The caller must include a trailing newline in msg
+ if one is to be printed.
+
+ A pprriinnttff()-style function is also available that can be used to display
+ informational or error messages to the user, which is usually more
+ convenient for simple messages where no use input is required.
+
+ _C_o_n_v_e_r_s_a_t_i_o_n _f_u_n_c_t_i_o_n _s_t_r_u_c_t_u_r_e_s
+
+ The conversation function takes as arguments pointers to the following
+ structures:
+
+ struct sudo_conv_message {
+ #define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */
+ #define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */
+ #define SUDO_CONV_ERROR_MSG 0x0003 /* error message */
+ #define SUDO_CONV_INFO_MSG 0x0004 /* informational message */
+ #define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */
+ #define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */
+ #define SUDO_CONV_PREFER_TTY 0x2000 /* flag: use tty if possible */
+ int msg_type;
+ int timeout;
+ const char *msg;
+ };
+
+ #define SUDO_CONV_REPL_MAX 255
+
+ struct sudo_conv_reply {
+ char *reply;
+ };
+
+ typedef int (*sudo_conv_callback_fn_t)(int signo, void *closure);
+ struct sudo_conv_callback {
+ unsigned int version;
+ void *closure;
+ sudo_conv_callback_fn_t on_suspend;
+ sudo_conv_callback_fn_t on_resume;
+ };
+
+ Pointers to the ccoonnvveerrssaattiioonn() and pprriinnttff()-style functions are passed in
+ to the plugin's ooppeenn() function when the plugin is initialized. The
+ following type definitions can be used in the declaration of the ooppeenn()
+ function:
+
+ typedef int (*sudo_conv_t)(int num_msgs,
+ const struct sudo_conv_message msgs[],
+ struct sudo_conv_reply replies[],
+ struct sudo_conv_callback *callback);
+
+ typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
+
+ To use the ccoonnvveerrssaattiioonn() function, the plugin must pass an array of
+ sudo_conv_message and sudo_conv_reply structures. There must be a struct
+ sudo_conv_message and struct sudo_conv_reply for each message in the
+ conversation, that is, both arrays must have the same number of elements.
+ Each struct sudo_conv_reply must have its _r_e_p_l_y member initialized to
+ NULL. The struct sudo_conv_callback pointer, if not NULL, should contain
+ function pointers to be called when the ssuuddoo process is suspended and/or
+ resumed during conversation input. The _o_n___s_u_s_p_e_n_d and _o_n___r_e_s_u_m_e
+ functions are called with the signal that caused ssuuddoo to be suspended and
+ the _c_l_o_s_u_r_e pointer from the struct sudo_conv_callback. These functions
+ should return 0 on success and -1 on error. On error, the conversation
+ will end and the conversation function will return a value of -1. The
+ intended use is to allow the plugin to release resources, such as locks,
+ that should not be held indefinitely while suspended and then reacquire
+ them when the process is resumed. Note that the functions are not
+ actually invoked from within a signal handler.
+
+ The _m_s_g___t_y_p_e must be set to one of the following values:
+
+ SUDO_CONV_PROMPT_ECHO_OFF
+ Prompt the user for input with echo disabled; this is generally
+ used for passwords. The reply will be stored in the _r_e_p_l_i_e_s array,
+ and it will never be NULL.
+
+ SUDO_CONV_PROMPT_ECHO_ON
+ Prompt the user for input with echo enabled. The reply will be
+ stored in the _r_e_p_l_i_e_s array, and it will never be NULL.
+
+ SUDO_CONV_ERROR_MSG
+ Display an error message. The message is written to the standard
+ error unless the SUDO_CONV_PREFER_TTY flag is set, in which case it
+ is written to the user's terminal if possible.
+
+ SUDO_CONV_INFO_MSG
+ Display a message. The message is written to the standard output
+ unless the SUDO_CONV_PREFER_TTY flag is set, in which case it is
+ written to the user's terminal if possible.
+
+ SUDO_CONV_PROMPT_MASK
+ Prompt the user for input but echo an asterisk character for each
+ character read. The reply will be stored in the _r_e_p_l_i_e_s array, and
+ it will never be NULL. This can be used to provide visual feedback
+ to the user while reading sensitive information that should not be
+ displayed.
+
+ In addition to the above values, the following flag bits may also be set:
+
+ SUDO_CONV_PROMPT_ECHO_OK
+ Allow input to be read when echo cannot be disabled when the
+ message type is SUDO_CONV_PROMPT_ECHO_OFF or SUDO_CONV_PROMPT_MASK.
+ By default, ssuuddoo will refuse to read input if the echo cannot be
+ disabled for those message types.
+
+ SUDO_CONV_PREFER_TTY
+ When displaying a message via SUDO_CONV_ERROR_MSG or
+ SUDO_CONV_INFO_MSG, try to write the message to the user's
+ terminal. If the terminal is unavailable, the standard error or
+ standard output will be used, depending upon whether The user's
+ terminal is always used when possible for input, this flag is only
+ used for output. SUDO_CONV_ERROR_MSG or SUDO_CONV_INFO_MSG was
+ used.
+
+ The _t_i_m_e_o_u_t in seconds until the prompt will wait for no more input. A
+ zero value implies an infinite timeout.
+
+ The plugin is responsible for freeing the reply buffer located in each
+ struct sudo_conv_reply, if it is not NULL. SUDO_CONV_REPL_MAX represents
+ the maximum length of the reply buffer (not including the trailing NUL
+ character). In practical terms, this is the longest password ssuuddoo will
+ support. It is also useful as a maximum value for the mmeemmsseett__ss()
+ function when clearing passwords filled in by the conversation function.
+
+ The pprriinnttff()-style function uses the same underlying mechanism as the
+ ccoonnvveerrssaattiioonn() function but only supports SUDO_CONV_INFO_MSG and
+ SUDO_CONV_ERROR_MSG for the _m_s_g___t_y_p_e parameter. It can be more
+ convenient than using the ccoonnvveerrssaattiioonn() function if no user reply is
+ needed and supports standard pprriinnttff() escape sequences.
+
+ See the sample plugin for an example of the ccoonnvveerrssaattiioonn() function
+ usage.
+
+ SSuuddooeerrss ggrroouupp pplluuggiinn AAPPII
+ The ssuuddooeerrss plugin supports its own plugin interface to allow non-Unix
+ group lookups. This can be used to query a group source other than the
+ standard Unix group database. Two sample group plugins are bundled with
+ ssuuddoo, _g_r_o_u_p___f_i_l_e and _s_y_s_t_e_m___g_r_o_u_p, are detailed in sudoers(4). Third
+ party group plugins include a QAS AD plugin available from Quest
+ Software.
+
+ A group plugin must declare and populate a sudoers_group_plugin struct in
+ the global scope. This structure contains pointers to the functions that
+ implement plugin initialization, cleanup and group lookup.
+
+ struct sudoers_group_plugin {
+ unsigned int version;
+ int (*init)(int version, sudo_printf_t sudo_printf,
+ char *const argv[]);
+ void (*cleanup)(void);
+ int (*query)(const char *user, const char *group,
+ const struct passwd *pwd);
+ };
+
+ The sudoers_group_plugin struct has the following fields:
+
+ version
+ The version field should be set to GROUP_API_VERSION.
+
+ This allows ssuuddooeerrss to determine the API version the group plugin
+ was built against.
+
+ init
+ int (*init)(int version, sudo_printf_t plugin_printf,
+ char *const argv[]);
+
+ The iinniitt() function is called after _s_u_d_o_e_r_s has been parsed but
+ before any policy checks. It returns 1 on success, 0 on failure
+ (or if the plugin is not configured), and -1 if a error occurred.
+ If an error occurs, the plugin may call the pplluuggiinn__pprriinnttff()
+ function with SUDO_CONF_ERROR_MSG to present additional error
+ information to the user.
+
+ The function arguments are as follows:
+
+ version
+ The version passed in by ssuuddooeerrss allows the plugin to
+ determine the major and minor version number of the group
+ plugin API supported by ssuuddooeerrss.
+
+ plugin_printf
+ A pointer to a pprriinnttff()-style function that may be used to
+ display informational or error message to the user. Returns
+ the number of characters printed on success and -1 on
+ failure.
+
+ argv A NULL-terminated array of arguments generated from the
+ _g_r_o_u_p___p_l_u_g_i_n option in _s_u_d_o_e_r_s. If no arguments were given,
+ _a_r_g_v will be NULL.
+
+ cleanup
+ void (*cleanup)();
+
+ The cclleeaannuupp() function is called when ssuuddooeerrss has finished its
+ group checks. The plugin should free any memory it has allocated
+ and close open file handles.
+
+ query
+ int (*query)(const char *user, const char *group,
+ const struct passwd *pwd);
+
+ The qquueerryy() function is used to ask the group plugin whether _u_s_e_r
+ is a member of _g_r_o_u_p.
+
+ The function arguments are as follows:
+
+ user The name of the user being looked up in the external group
+ database.
+
+ group
+ The name of the group being queried.
+
+ pwd The password database entry for _u_s_e_r, if any. If _u_s_e_r is not
+ present in the password database, _p_w_d will be NULL.
+
+ _G_r_o_u_p _A_P_I _V_e_r_s_i_o_n _M_a_c_r_o_s
+
+ /* Sudoers group plugin version major/minor */
+ #define GROUP_API_VERSION_MAJOR 1
+ #define GROUP_API_VERSION_MINOR 0
+ #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \
+ GROUP_API_VERSION_MINOR)
+ For getters and setters see the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I.
+
+PPLLUUGGIINN AAPPII CCHHAANNGGEELLOOGG
+ The following revisions have been made to the Sudo Plugin API.
+
+ Version 1.0
+ Initial API version.
+
+ Version 1.1 (sudo 1.8.0)
+ The I/O logging plugin's ooppeenn() function was modified to take the
+ command_info list as an argument.
+
+ Version 1.2 (sudo 1.8.5)
+ The Policy and I/O logging plugins' ooppeenn() functions are now passed
+ a list of plugin parameters if any are specified in sudo.conf(4).
+
+ A simple hooks API has been introduced to allow plugins to hook in
+ to the system's environment handling functions.
+
+ The init_session Policy plugin function is now passed a pointer to
+ the user environment which can be updated as needed. This can be
+ used to merge in environment variables stored in the PAM handle
+ before a command is run.
+
+ Version 1.3 (sudo 1.8.7)
+ Support for the _e_x_e_c___b_a_c_k_g_r_o_u_n_d entry has been added to the
+ command_info list.
+
+ The _m_a_x___g_r_o_u_p_s and _p_l_u_g_i_n___d_i_r entries were added to the settings
+ list.
+
+ The vveerrssiioonn() and cclloossee() functions are now optional. Previously,
+ a missing vveerrssiioonn() or cclloossee() function would result in a crash.
+ If no policy plugin cclloossee() function is defined, a default cclloossee()
+ function will be provided by the ssuuddoo front end that displays a
+ warning if the command could not be executed.
+
+ The ssuuddoo front end now installs default signal handlers to trap
+ common signals while the plugin functions are run.
+
+ Version 1.4 (sudo 1.8.8)
+ The _r_e_m_o_t_e___h_o_s_t entry was added to the settings list.
+
+ Version 1.5 (sudo 1.8.9)
+ The _p_r_e_s_e_r_v_e___f_d_s entry was added to the command_info list.
+
+ Version 1.6 (sudo 1.8.11)
+ The behavior when an I/O logging plugin returns an error (-1) has
+ changed. Previously, the ssuuddoo front end took no action when the
+ lloogg__ttttyyiinn(), lloogg__ttttyyoouutt(), lloogg__ssttddiinn(), lloogg__ssttddoouutt(), or
+ lloogg__ssttddeerrrr() function returned an error.
+
+ The behavior when an I/O logging plugin returns 0 has changed.
+ Previously, output from the command would be displayed to the
+ terminal even if an output logging function returned 0.
+
+ Version 1.7 (sudo 1.8.12)
+ The _p_l_u_g_i_n___p_a_t_h entry was added to the settings list.
+
+ The _d_e_b_u_g___f_l_a_g_s entry now starts with a debug file path name and
+ may occur multiple times if there are multiple plugin-specific
+ Debug lines in the sudo.conf(4) file.
+
+ Version 1.8 (sudo 1.8.15)
+ The _s_u_d_o_e_d_i_t___c_h_e_c_k_d_i_r and _s_u_d_o_e_d_i_t___f_o_l_l_o_w entries were added to the
+ command_info list. The default value of _s_u_d_o_e_d_i_t___c_h_e_c_k_d_i_r was
+ changed to true in sudo 1.8.16.
+
+ The sudo _c_o_n_v_e_r_s_a_t_i_o_n function now takes a pointer to a struct
+ sudo_conv_callback as its fourth argument. The sudo_conv_t
+ definition has been updated to match. The plugin must specify that
+ it supports plugin API version 1.8 or higher to receive a
+ conversation function pointer that supports this argument.
+
+ Version 1.9 (sudo 1.8.16)
+ The _e_x_e_c_f_d entry was added to the command_info list.
+
+ Version 1.10 (sudo 1.8.19)
+ The _u_m_a_s_k entry was added to the user_info list. The _i_o_l_o_g___g_r_o_u_p,
+ _i_o_l_o_g___m_o_d_e, and _i_o_l_o_g___u_s_e_r entries were added to the command_info
+ list.
+
+ Version 1.11 (sudo 1.8.20)
+ The _t_i_m_e_o_u_t entry was added to the settings list.
+
+ Version 1.12 (sudo 1.8.21)
+ The change_winsize field was added to the io_plugin struct.
+
+ Version 1.13 (sudo 1.8.26)
+ The log_suspend field was added to the io_plugin struct.
+
+SSEEEE AALLSSOO
+ sudo.conf(4), sudoers(4), sudo(1m)
+
+AAUUTTHHOORRSS
+ Many people have worked on ssuuddoo over the years; this version consists of
+ code written primarily by:
+
+ Todd C. Miller
+
+ See the CONTRIBUTORS file in the ssuuddoo distribution
+ (https://www.sudo.ws/contributors.html) for an exhaustive list of people
+ who have contributed to ssuuddoo.
+
+BBUUGGSS
+ If you feel you have found a bug in ssuuddoo, please submit a bug report at
+ https://bugzilla.sudo.ws/
+
+SSUUPPPPOORRTT
+ Limited free support is available via the sudo-users mailing list, see
+ https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search
+ the archives.
+
+DDIISSCCLLAAIIMMEERR
+ ssuuddoo is provided "AS IS" and any express or implied warranties,
+ including, but not limited to, the implied warranties of merchantability
+ and fitness for a particular purpose are disclaimed. See the LICENSE
+ file distributed with ssuuddoo or https://www.sudo.ws/license.html for
+ complete details.
+
+Sudo 1.8.26 October 24, 2018 Sudo 1.8.26
diff --git a/doc/sudo_plugin.man.in b/doc/sudo_plugin.man.in
new file mode 100644
index 0000000..c336033
--- /dev/null
+++ b/doc/sudo_plugin.man.in
@@ -0,0 +1,2986 @@
+.\" Automatically generated from an mdoc input file. Do not edit.
+.\"
+.\" Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "SUDO_PLUGIN" "5" "October 24, 2018" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
+.nh
+.if n .ad l
+.SH "NAME"
+\fBsudo_plugin\fR
+\- Sudo Plugin API
+.SH "DESCRIPTION"
+Starting with version 1.8,
+\fBsudo\fR
+supports a plugin API
+for policy and session logging.
+Plugins may be compiled as dynamic shared objects (the default on
+systems that support them) or compiled statically into the
+\fBsudo\fR
+binary itself.
+By default, the
+\fBsudoers\fR
+policy plugin and an associated I/O logging plugin are used.
+Via the plugin API,
+\fBsudo\fR
+can be configured to use alternate policy and/or I/O logging plugins
+provided by third parties.
+The plugins to be used are specified in the
+sudo.conf(@mansectform@)
+file.
+.PP
+The API is versioned with a major and minor number.
+The minor version number is incremented when additions are made.
+The major number is incremented when incompatible changes are made.
+A plugin should be check the version passed to it and make sure that the
+major version matches.
+.PP
+The plugin API is defined by the
+\fRsudo_plugin.h\fR
+header file.
+.SS "Policy plugin API"
+A policy plugin must declare and populate a
+\fRpolicy_plugin\fR
+struct in the global scope.
+This structure contains pointers to the functions that implement the
+\fBsudo\fR
+policy checks.
+The name of the symbol should be specified in
+sudo.conf(@mansectform@)
+along with a path to the plugin so that
+\fBsudo\fR
+can load it.
+.nf
+.sp
+.RS 0n
+struct policy_plugin {
+#define SUDO_POLICY_PLUGIN 1
+ unsigned int type; /* always SUDO_POLICY_PLUGIN */
+ unsigned int version; /* always SUDO_API_VERSION */
+ int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const user_env[],
+ char * const plugin_options[]);
+ void (*close)(int exit_status, int error);
+ int (*show_version)(int verbose);
+ int (*check_policy)(int argc, char * const argv[],
+ char *env_add[], char **command_info[],
+ char **argv_out[], char **user_env_out[]);
+ int (*list)(int argc, char * const argv[], int verbose,
+ const char *list_user);
+ int (*validate)(void);
+ void (*invalidate)(int remove);
+ int (*init_session)(struct passwd *pwd, char **user_env[]);
+ void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+ void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
+};
+.RE
+.fi
+.PP
+The policy_plugin struct has the following fields:
+.TP 6n
+type
+The
+\fRtype\fR
+field should always be set to SUDO_POLICY_PLUGIN.
+.TP 6n
+version
+The
+\fRversion\fR
+field should be set to
+\fRSUDO_API_VERSION\fR.
+.sp
+This allows
+\fBsudo\fR
+to determine the API version the plugin was
+built against.
+.TP 6n
+open
+.nf
+.RS 6n
+int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const user_env[],
+ char * const plugin_options[]);
+.RE
+.fi
+.RS 6n
+.sp
+Returns 1 on success, 0 on failure, \-1 if a general error occurred,
+or \-2 if there was a usage error.
+In the latter case,
+\fBsudo\fR
+will print a usage message before it exits.
+If an error occurs, the plugin may optionally call the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present additional error information to the user.
+.sp
+The function arguments are as follows:
+.TP 6n
+version
+The version passed in by
+\fBsudo\fR
+allows the plugin to determine the
+major and minor version number of the plugin API supported by
+\fBsudo\fR.
+.TP 6n
+conversation
+A pointer to the
+\fBconversation\fR()
+function that can be used by the plugin to interact with the user (see below).
+Returns 0 on success and \-1 on failure.
+.TP 6n
+plugin_printf
+A pointer to a
+\fBprintf\fR()-style
+function that may be used to display informational or error messages
+(see below).
+Returns the number of characters printed on success and \-1 on failure.
+.TP 6n
+settings
+A vector of user-supplied
+\fBsudo\fR
+settings in the form of
+\(lqname=value\(rq
+strings.
+The vector is terminated by a
+\fRNULL\fR
+pointer.
+These settings correspond to flags the user specified when running
+\fBsudo\fR.
+As such, they will only be present when the corresponding flag has
+been specified on the command line.
+.sp
+When parsing
+\fIsettings\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.PP
+.RS 6n
+.PD 0
+.TP 6n
+bsdauth_type=string
+Authentication type, if specified by the
+\fB\-a\fR
+flag, to use on
+systems where
+BSD
+authentication is supported.
+.PD
+.TP 6n
+closefrom=number
+If specified, the user has requested via the
+\fB\-C\fR
+flag that
+\fBsudo\fR
+close all files descriptors with a value of
+\fInumber\fR
+or higher.
+The plugin may optionally pass this, or another value, back in the
+\fIcommand_info\fR
+list.
+.TP 6n
+debug_flags=string
+A debug file path name followed by a space and a comma-separated
+list of debug flags that correspond to the plugin's
+\fRDebug\fR
+entry in
+sudo.conf(@mansectform@),
+if there is one.
+The flags are passed to the plugin exactly as they appear in
+sudo.conf(@mansectform@).
+The syntax used by
+\fBsudo\fR
+and the
+\fBsudoers\fR
+plugin is
+\fIsubsystem\fR@\fIpriority\fR
+but a plugin is free to use a different
+format so long as it does not include a comma
+(\(oq,\&\(cq).
+Prior to
+\fBsudo\fR
+1.8.12, there was no way to specify plugin-specific
+\fIdebug_flags\fR
+so the value was always the same as that used by the
+\fBsudo\fR
+front end and did not include a path name, only the flags themselves.
+As of version 1.7 of the plugin interface,
+\fBsudo\fR
+will only pass
+\fIdebug_flags\fR
+if
+sudo.conf(@mansectform@)
+contains a plugin-specific
+\fRDebug\fR
+entry.
+.TP 6n
+debug_level=number
+This setting has been deprecated in favor of
+\fIdebug_flags\fR.
+.TP 6n
+ignore_ticket=bool
+Set to true if the user specified the
+\fB\-k\fR
+flag along with a
+command, indicating that the user wishes to ignore any cached
+authentication credentials.
+\fIimplied_shell\fR
+to true.
+This allows
+\fBsudo\fR
+with no arguments
+to be used similarly to
+su(1).
+If the plugin does not to support this usage, it may return a value of \-2
+from the
+\fBcheck_policy\fR()
+function, which will cause
+\fBsudo\fR
+to print a usage message and
+exit.
+.TP 6n
+implied_shell=bool
+If the user does not specify a program on the command line,
+\fBsudo\fR
+will pass the plugin the path to the user's shell and set
+.TP 6n
+login_class=string
+BSD
+login class to use when setting resource limits and nice value,
+if specified by the
+\fB\-c\fR
+flag.
+.TP 6n
+login_shell=bool
+Set to true if the user specified the
+\fB\-i\fR
+flag, indicating that
+the user wishes to run a login shell.
+.TP 6n
+max_groups=int
+The maximum number of groups a user may belong to.
+This will only be present if there is a corresponding setting in
+sudo.conf(@mansectform@).
+.TP 6n
+network_addrs=list
+A space-separated list of IP network addresses and netmasks in the
+form
+\(lqaddr/netmask\(rq,
+e.g.,
+\(lq192.168.1.2/255.255.255.0\(rq.
+The address and netmask pairs may be either IPv4 or IPv6, depending on
+what the operating system supports.
+If the address contains a colon
+(\(oq:\&\(cq),
+it is an IPv6 address, else it is IPv4.
+.TP 6n
+noninteractive=bool
+Set to true if the user specified the
+\fB\-n\fR
+flag, indicating that
+\fBsudo\fR
+should operate in non-interactive mode.
+The plugin may reject a command run in non-interactive mode if user
+interaction is required.
+.TP 6n
+plugin_dir=string
+The default plugin directory used by the
+\fBsudo\fR
+front end.
+This is the default directory set at compile time and may not
+correspond to the directory the running plugin was loaded from.
+It may be used by a plugin to locate support files.
+.TP 6n
+plugin_path=string
+The path name of plugin loaded by the
+\fBsudo\fR
+front end.
+The path name will be a fully-qualified unless the plugin was
+statically compiled into
+\fBsudo\fR.
+.TP 6n
+preserve_environment=bool
+Set to true if the user specified the
+\fB\-E\fR
+flag, indicating that
+the user wishes to preserve the environment.
+.TP 6n
+preserve_groups=bool
+Set to true if the user specified the
+\fB\-P\fR
+flag, indicating that
+the user wishes to preserve the group vector instead of setting it
+based on the runas user.
+.TP 6n
+progname=string
+The command name that sudo was run as, typically
+\(lqsudo\(rq
+or
+\(lqsudoedit\(rq.
+.TP 6n
+prompt=string
+The prompt to use when requesting a password, if specified via
+the
+\fB\-p\fR
+flag.
+.TP 6n
+remote_host=string
+The name of the remote host to run the command on, if specified via
+the
+\fB\-h\fR
+option.
+Support for running the command on a remote host is meant to be implemented
+via a helper program that is executed in place of the user-specified command.
+The
+\fBsudo\fR
+front end is only capable of executing commands on the local host.
+Only available starting with API version 1.4.
+.TP 6n
+run_shell=bool
+Set to true if the user specified the
+\fB\-s\fR
+flag, indicating that the user wishes to run a shell.
+.TP 6n
+runas_group=string
+The group name or gid to run the command as, if specified via
+the
+\fB\-g\fR
+flag.
+.TP 6n
+runas_user=string
+The user name or uid to run the command as, if specified via the
+\fB\-u\fR
+flag.
+.TP 6n
+selinux_role=string
+SELinux role to use when executing the command, if specified by
+the
+\fB\-r\fR
+flag.
+.TP 6n
+selinux_type=string
+SELinux type to use when executing the command, if specified by
+the
+\fB\-t\fR
+flag.
+.TP 6n
+set_home=bool
+Set to true if the user specified the
+\fB\-H\fR
+flag.
+If true, set the
+\fRHOME\fR
+environment variable to the target user's home directory.
+.TP 6n
+sudoedit=bool
+Set to true when the
+\fB\-e\fR
+flag is specified or if invoked as
+\fBsudoedit\fR.
+The plugin shall substitute an editor into
+\fIargv\fR
+in the
+\fBcheck_policy\fR()
+function or return \-2 with a usage error
+if the plugin does not support
+\fIsudoedit\fR.
+For more information, see the
+\fIcheck_policy\fR
+section.
+.TP 6n
+timeout=string
+User-specified command timeout.
+Not all plugins support command timeouts and the ability for the
+user to set a timeout may be restricted by policy.
+The format of the timeout string is plugin-specific.
+.PP
+Additional settings may be added in the future so the plugin should
+silently ignore settings that it does not recognize.
+.RE
+.TP 6n
+user_info
+A vector of information about the user running the command in the form of
+\(lqname=value\(rq
+strings.
+The vector is terminated by a
+\fRNULL\fR
+pointer.
+.sp
+When parsing
+\fIuser_info\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.PP
+.RS 6n
+.PD 0
+.TP 6n
+cols=int
+The number of columns the user's terminal supports.
+If there is no terminal device available, a default value of 80 is used.
+.PD
+.TP 6n
+cwd=string
+The user's current working directory.
+.TP 6n
+egid=gid_t
+The effective group ID of the user invoking
+\fBsudo\fR.
+.TP 6n
+euid=uid_t
+The effective user ID of the user invoking
+\fBsudo\fR.
+.TP 6n
+gid=gid_t
+The real group ID of the user invoking
+\fBsudo\fR.
+.TP 6n
+groups=list
+The user's supplementary group list formatted as a string of
+comma-separated group IDs.
+.TP 6n
+host=string
+The local machine's hostname as returned by the
+gethostname(2)
+system call.
+.TP 6n
+lines=int
+The number of lines the user's terminal supports.
+If there is
+no terminal device available, a default value of 24 is used.
+.TP 6n
+pgid=int
+The ID of the process group that the running
+\fBsudo\fR
+process is a member of.
+Only available starting with API version 1.2.
+.TP 6n
+pid=int
+The process ID of the running
+\fBsudo\fR
+process.
+Only available starting with API version 1.2.
+.TP 6n
+plugin_options
+Any (non-comment) strings immediately after the plugin path are
+passed as arguments to the plugin.
+These arguments are split on a white space boundary and are passed to
+the plugin in the form of a
+\fRNULL\fR-terminated
+array of strings.
+If no arguments were
+specified,
+\fIplugin_options\fR
+will be the
+\fRNULL\fR
+pointer.
+.sp
+NOTE: the
+\fIplugin_options\fR
+parameter is only available starting with
+API version 1.2.
+A plugin
+\fBmust\fR
+check the API version specified
+by the
+\fBsudo\fR
+front end before using
+\fIplugin_options\fR.
+Failure to do so may result in a crash.
+.TP 6n
+ppid=int
+The parent process ID of the running
+\fBsudo\fR
+process.
+Only available starting with API version 1.2.
+.TP 6n
+sid=int
+The session ID of the running
+\fBsudo\fR
+process or 0 if
+\fBsudo\fR
+is not part of a POSIX job control session.
+Only available starting with API version 1.2.
+.TP 6n
+tcpgid=int
+The ID of the foreground process group associated with the terminal
+device associated with the
+\fBsudo\fR
+process or \-1 if there is no
+terminal present.
+Only available starting with API version 1.2.
+.TP 6n
+tty=string
+The path to the user's terminal device.
+If the user has no terminal device associated with the session,
+the value will be empty, as in
+\(lq\fRtty=\fR\(rq.
+.TP 6n
+uid=uid_t
+The real user ID of the user invoking
+\fBsudo\fR.
+.TP 6n
+umask=octal
+The invoking user's file creation mask.
+Only available starting with API version 1.10.
+.TP 6n
+user=string
+The name of the user invoking
+\fBsudo\fR.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+user_env
+The user's environment in the form of a
+\fRNULL\fR-terminated vector of
+\(lqname=value\(rq
+strings.
+.sp
+When parsing
+\fIuser_env\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+close
+.br
+.nf
+.RS 6n
+void (*close)(int exit_status, int error);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBclose\fR()
+function is called when the command being run by
+\fBsudo\fR
+finishes.
+.sp
+The function arguments are as follows:
+.TP 6n
+exit_status
+The command's exit status, as returned by the
+wait(2)
+system call.
+The value of
+\fRexit_status\fR
+is undefined if
+\fRerror\fR
+is non-zero.
+.TP 6n
+error
+.br
+If the command could not be executed, this is set to the value of
+\fRerrno\fR
+set by the
+execve(2)
+system call.
+The plugin is responsible for displaying error information via the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function.
+If the command was successfully executed, the value of
+\fRerror\fR
+is 0.
+.PP
+If no
+\fBclose\fR()
+function is defined, no I/O logging plugins are loaded,
+and neither the
+\fItimeout\fR
+not
+\fIuse_pty\fR
+options are set in the
+\fRcommand_info\fR
+list, the
+\fBsudo\fR
+front end may execute the command directly instead of running
+it as a child process.
+.RE
+.TP 6n
+show_version
+.nf
+.RS 6n
+int (*show_version)(int verbose);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBshow_version\fR()
+function is called by
+\fBsudo\fR
+when the user specifies
+the
+\fB\-V\fR
+option.
+The plugin may display its version information to the user via the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function using
+\fRSUDO_CONV_INFO_MSG\fR.
+If the user requests detailed version information, the verbose flag will be set.
+.sp
+Returns 1 on success, 0 on failure, \-1 if a general error occurred,
+or \-2 if there was a usage error, although the return value is currently
+ignored.
+.RE
+.TP 6n
+check_policy
+.nf
+.RS 6n
+int (*check_policy)(int argc, char * const argv[],
+ char *env_add[], char **command_info[],
+ char **argv_out[], char **user_env_out[]);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBcheck_policy\fR()
+function is called by
+\fBsudo\fR
+to determine
+whether the user is allowed to run the specified commands.
+.sp
+If the
+\fIsudoedit\fR
+option was enabled in the
+\fIsettings\fR
+array
+passed to the
+\fBopen\fR()
+function, the user has requested
+\fIsudoedit\fR
+mode.
+\fIsudoedit\fR
+is a mechanism for editing one or more files
+where an editor is run with the user's credentials instead of with
+elevated privileges.
+\fBsudo\fR
+achieves this by creating user-writable
+temporary copies of the files to be edited and then overwriting the
+originals with the temporary copies after editing is complete.
+If the plugin supports
+\fIsudoedit\fR,
+it should choose the editor to be used, potentially from a variable
+in the user's environment, such as
+\fREDITOR\fR,
+and include it in
+\fIargv_out\fR
+(note that environment
+variables may include command line flags).
+The files to be edited should be copied from
+\fIargv\fR
+into
+\fIargv_out\fR,
+separated from the
+editor and its arguments by a
+\(lq\fR--\fR\(rq
+element.
+The
+\(lq\fR--\fR\(rq
+will
+be removed by
+\fBsudo\fR
+before the editor is executed.
+The plugin should also set
+\fIsudoedit=true\fR
+in the
+\fIcommand_info\fR
+list.
+.sp
+The
+\fBcheck_policy\fR()
+function returns 1 if the command is allowed,
+0 if not allowed, \-1 for a general error, or \-2 for a usage error
+or if
+\fIsudoedit\fR
+was specified but is unsupported by the plugin.
+In the latter case,
+\fBsudo\fR
+will print a usage message before it
+exits.
+If an error occurs, the plugin may optionally call the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present additional error information to the user.
+.sp
+The function arguments are as follows:
+.TP 6n
+argc
+The number of elements in
+\fIargv\fR,
+not counting the final
+\fRNULL\fR
+pointer.
+.TP 6n
+argv
+The argument vector describing the command the user wishes to run,
+in the same form as what would be passed to the
+execve(2)
+system call.
+The vector is terminated by a
+\fRNULL\fR
+pointer.
+.TP 6n
+env_add
+Additional environment variables specified by the user on the command
+line in the form of a
+\fRNULL\fR-terminated
+vector of
+\(lqname=value\(rq
+strings.
+The plugin may reject the command if one or more variables
+are not allowed to be set, or it may silently ignore such variables.
+.sp
+When parsing
+\fIenv_add\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.TP 6n
+command_info
+Information about the command being run in the form of
+\(lqname=value\(rq
+strings.
+These values are used by
+\fBsudo\fR
+to set the execution
+environment when running a command.
+The plugin is responsible for creating and populating the vector,
+which must be terminated with a
+\fRNULL\fR
+pointer.
+The following values are recognized by
+\fBsudo\fR:
+.PP
+.RS 6n
+.PD 0
+.TP 6n
+chroot=string
+The root directory to use when running the command.
+.PD
+.TP 6n
+closefrom=number
+If specified,
+\fBsudo\fR
+will close all files descriptors with a value
+of
+\fInumber\fR
+or higher.
+.TP 6n
+command=string
+Fully qualified path to the command to be executed.
+.TP 6n
+cwd=string
+The current working directory to change to when executing the command.
+.TP 6n
+exec_background=bool
+By default,
+\fBsudo\fR
+runs a command as the foreground process as long as
+\fBsudo\fR
+itself is running in the foreground.
+When
+\fIexec_background\fR
+is enabled and the command is being run in a pty (due to I/O logging
+or the
+\fIuse_pty\fR
+setting), the command will be run as a background process.
+Attempts to read from the controlling terminal (or to change terminal
+settings) will result in the command being suspended with the
+\fRSIGTTIN\fR
+signal (or
+\fRSIGTTOU\fR
+in the case of terminal settings).
+If this happens when
+\fBsudo\fR
+is a foreground process, the command will be granted the controlling terminal
+and resumed in the foreground with no user intervention required.
+The advantage of initially running the command in the background is that
+\fBsudo\fR
+need not read from the terminal unless the command explicitly requests it.
+Otherwise, any terminal input must be passed to the command, whether it
+has required it or not (the kernel buffers terminals so it is not possible
+to tell whether the command really wants the input).
+This is different from historic
+\fIsudo\fR
+behavior or when the command is not being run in a pty.
+.sp
+For this to work seamlessly, the operating system must support the
+automatic restarting of system calls.
+Unfortunately, not all operating systems do this by default,
+and even those that do may have bugs.
+For example, macOS fails to restart the
+\fBtcgetattr\fR()
+and
+\fBtcsetattr\fR()
+system calls (this is a bug in macOS).
+Furthermore, because this behavior depends on the command stopping with the
+\fRSIGTTIN\fR
+or
+\fRSIGTTOU\fR
+signals, programs that catch these signals and suspend themselves
+with a different signal (usually
+\fRSIGTOP\fR)
+will not be automatically foregrounded.
+Some versions of the linux
+su(1)
+command behave this way.
+Because of this, a plugin should not set
+\fIexec_background\fR
+unless it is explicitly enabled by the administrator and there should
+be a way to enabled or disable it on a per-command basis.
+.sp
+This setting has no effect unless I/O logging is enabled or
+\fIuse_pty\fR
+is enabled.
+.TP 6n
+execfd=number
+If specified,
+\fBsudo\fR
+will use the
+fexecve(2)
+system call to execute the command instead of
+execve(2).
+The specified
+\fInumber\fR
+must refer to an open file descriptor.
+.TP 6n
+iolog_compress=bool
+Set to true if the I/O logging plugins, if any, should compress the
+log data.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_group=string
+The group that will own newly created I/O log files and directories.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_mode=octal
+The file permission mode to use when creating I/O log files and directories.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_user=string
+The user that will own newly created I/O log files and directories.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_path=string
+Fully qualified path to the file or directory in which I/O log is
+to be stored.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+If no I/O logging plugin is loaded, this setting has no effect.
+.TP 6n
+iolog_stdin=bool
+Set to true if the I/O logging plugins, if any, should log the
+standard input if it is not connected to a terminal device.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_stdout=bool
+Set to true if the I/O logging plugins, if any, should log the
+standard output if it is not connected to a terminal device.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_stderr=bool
+Set to true if the I/O logging plugins, if any, should log the
+standard error if it is not connected to a terminal device.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_ttyin=bool
+Set to true if the I/O logging plugins, if any, should log all
+terminal input.
+This only includes input typed by the user and not from a pipe or
+redirected from a file.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_ttyout=bool
+Set to true if the I/O logging plugins, if any, should log all
+terminal output.
+This only includes output to the screen, not output to a pipe or file.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+login_class=string
+BSD
+login class to use when setting resource limits and nice value (optional).
+This option is only set on systems that support login classes.
+.TP 6n
+nice=int
+Nice value (priority) to use when executing the command.
+The nice value, if specified, overrides the priority associated with the
+\fIlogin_class\fR
+on
+BSD
+systems.
+.TP 6n
+noexec=bool
+If set, prevent the command from executing other programs.
+.TP 6n
+preserve_fds=list
+A comma-separated list of file descriptors that should be
+preserved, regardless of the value of the
+\fIclosefrom\fR
+setting.
+Only available starting with API version 1.5.
+.TP 6n
+preserve_groups=bool
+If set,
+\fBsudo\fR
+will preserve the user's group vector instead of
+initializing the group vector based on
+\fRrunas_user\fR.
+.TP 6n
+runas_egid=gid
+Effective group ID to run the command as.
+If not specified, the value of
+\fIrunas_gid\fR
+is used.
+.TP 6n
+runas_euid=uid
+Effective user ID to run the command as.
+If not specified, the value of
+\fIrunas_uid\fR
+is used.
+.TP 6n
+runas_gid=gid
+Group ID to run the command as.
+.TP 6n
+runas_groups=list
+The supplementary group vector to use for the command in the form
+of a comma-separated list of group IDs.
+If
+\fIpreserve_groups\fR
+is set, this option is ignored.
+.TP 6n
+runas_uid=uid
+User ID to run the command as.
+.TP 6n
+selinux_role=string
+SELinux role to use when executing the command.
+.TP 6n
+selinux_type=string
+SELinux type to use when executing the command.
+.TP 6n
+set_utmp=bool
+Create a utmp (or utmpx) entry when a pseudo-tty is allocated.
+By default, the new entry will be a copy of the user's existing utmp
+entry (if any), with the tty, time, type and pid fields updated.
+.TP 6n
+sudoedit=bool
+Set to true when in
+\fIsudoedit\fR
+mode.
+The plugin may enable
+\fIsudoedit\fR
+mode even if
+\fBsudo\fR
+was not invoked as
+\fBsudoedit\fR.
+This allows the plugin to perform command substitution and transparently
+enable
+\fIsudoedit\fR
+when the user attempts to run an editor.
+.TP 6n
+sudoedit_checkdir=bool
+Set to false to disable directory writability checks in
+\fBsudoedit\fR.
+By default,
+\fBsudoedit\fR
+1.8.16 and higher will check all directory components of the path to be
+edited for writability by the invoking user.
+Symbolic links will not be followed in writable directories and
+\fBsudoedit\fR
+will refuse to edit a file located in a writable directory.
+These restrictions are not enforced when
+\fBsudoedit\fR
+is run by root.
+The
+\fIsudoedit_follow\fR
+option can be set to false to disable this check.
+Only available starting with API version 1.8.
+.TP 6n
+sudoedit_follow=bool
+Set to true to allow
+\fBsudoedit\fR
+to edit files that are symbolic links.
+By default,
+\fBsudoedit\fR
+1.8.15 and higher will refuse to open a symbolic link.
+The
+\fIsudoedit_follow\fR
+option can be used to restore the older behavior and allow
+\fBsudoedit\fR
+to open symbolic links.
+Only available starting with API version 1.8.
+.TP 6n
+timeout=int
+Command timeout.
+If non-zero then when the timeout expires the command will be killed.
+.TP 6n
+umask=octal
+The file creation mask to use when executing the command.
+.TP 6n
+use_pty=bool
+Allocate a pseudo-tty to run the command in, regardless of whether
+or not I/O logging is in use.
+By default,
+\fBsudo\fR
+will only run
+the command in a pty when an I/O log plugin is loaded.
+.TP 6n
+utmp_user=string
+User name to use when constructing a new utmp (or utmpx) entry when
+\fIset_utmp\fR
+is enabled.
+This option can be used to set the user field in the utmp entry to
+the user the command runs as rather than the invoking user.
+If not set,
+\fBsudo\fR
+will base the new entry on
+the invoking user's existing entry.
+.PP
+Unsupported values will be ignored.
+.RE
+.TP 6n
+argv_out
+The
+\fRNULL\fR-terminated
+argument vector to pass to the
+execve(2)
+system call when executing the command.
+The plugin is responsible for allocating and populating the vector.
+.TP 6n
+user_env_out
+The
+\fRNULL\fR-terminated
+environment vector to use when executing the command.
+The plugin is responsible for allocating and populating the vector.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+list
+.nf
+.RS 6n
+int (*list)(int argc, char * const argv[],
+ int verbose, const char *list_user);
+.RE
+.fi
+.RS 6n
+.sp
+List available privileges for the invoking user.
+Returns 1 on success, 0 on failure and \-1 on error.
+On error, the plugin may optionally call the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present additional error information to
+the user.
+.sp
+Privileges should be output via the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function using
+\fRSUDO_CONV_INFO_MSG\fR,
+.TP 6n
+verbose
+Flag indicating whether to list in verbose mode or not.
+.TP 6n
+list_user
+The name of a different user to list privileges for if the policy
+allows it.
+If
+\fRNULL\fR,
+the plugin should list the privileges of the invoking user.
+.TP 6n
+argc
+The number of elements in
+\fIargv\fR,
+not counting the final
+\fRNULL\fR
+pointer.
+.TP 6n
+argv
+If
+non-\fRNULL\fR,
+an argument vector describing a command the user
+wishes to check against the policy in the same form as what would
+be passed to the
+execve(2)
+system call.
+If the command is permitted by the policy, the fully-qualified path
+to the command should be displayed along with any command line arguments.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+validate
+.nf
+.RS 6n
+int (*validate)(void);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBvalidate\fR()
+function is called when
+\fBsudo\fR
+is run with the
+\fB\-v\fR
+flag.
+For policy plugins such as
+\fBsudoers\fR
+that cache
+authentication credentials, this function will validate and cache
+the credentials.
+.sp
+The
+\fBvalidate\fR()
+function should be
+\fRNULL\fR
+if the plugin does not support credential caching.
+.sp
+Returns 1 on success, 0 on failure and \-1 on error.
+On error, the plugin may optionally call the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present additional
+error information to the user.
+.RE
+.TP 6n
+invalidate
+.nf
+.RS 6n
+void (*invalidate)(int remove);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBinvalidate\fR()
+function is called when
+\fBsudo\fR
+is called with
+the
+\fB\-k\fR
+or
+\fB\-K\fR
+flag.
+For policy plugins such as
+\fBsudoers\fR
+that
+cache authentication credentials, this function will invalidate the
+credentials.
+If the
+\fIremove\fR
+flag is set, the plugin may remove
+the credentials instead of simply invalidating them.
+.sp
+The
+\fBinvalidate\fR()
+function should be
+\fRNULL\fR
+if the plugin does not support credential caching.
+.RE
+.TP 6n
+init_session
+.nf
+.RS 6n
+int (*init_session)(struct passwd *pwd, char **user_envp[);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBinit_session\fR()
+function is called before
+\fBsudo\fR
+sets up the
+execution environment for the command.
+It is run in the parent
+\fBsudo\fR
+process and before any uid or gid changes.
+This can be used to perform session setup that is not supported by
+\fIcommand_info\fR,
+such as opening the PAM session.
+The
+\fBclose\fR()
+function can be
+used to tear down the session that was opened by
+\fRinit_session\fR.
+.sp
+The
+\fIpwd\fR
+argument points to a passwd struct for the user the
+command will be run as if the uid the command will run as was found
+in the password database, otherwise it will be
+\fRNULL\fR.
+.sp
+The
+\fIuser_env\fR
+argument points to the environment the command will
+run in, in the form of a
+\fRNULL\fR-terminated
+vector of
+\(lqname=value\(rq
+strings.
+This is the same string passed back to the front end via
+the Policy Plugin's
+\fIuser_env_out\fR
+parameter.
+If the
+\fBinit_session\fR()
+function needs to modify the user environment, it should update the
+pointer stored in
+\fIuser_env\fR.
+The expected use case is to merge the contents of the PAM environment
+(if any) with the contents of
+\fIuser_env\fR.
+NOTE: the
+\fIuser_env\fR
+parameter is only available
+starting with API version 1.2.
+A plugin
+\fBmust\fR
+check the API
+version specified by the
+\fBsudo\fR
+front end before using
+\fIuser_env\fR.
+Failure to do so may result in a crash.
+.sp
+Returns 1 on success, 0 on failure and \-1 on error.
+On error, the plugin may optionally call the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present additional
+error information to the user.
+.RE
+.TP 6n
+register_hooks
+.nf
+.RS 6n
+void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBregister_hooks\fR()
+function is called by the sudo front end to
+register any hooks the plugin needs.
+If the plugin does not support hooks,
+\fRregister_hooks\fR
+should be set to the
+\fRNULL\fR
+pointer.
+.sp
+The
+\fIversion\fR
+argument describes the version of the hooks API
+supported by the
+\fBsudo\fR
+front end.
+.sp
+The
+\fBregister_hook\fR()
+function should be used to register any supported
+hooks the plugin needs.
+It returns 0 on success, 1 if the hook type is not supported and \-1
+if the major version in
+\fRstruct hook\fR
+does not match the front end's major hook API version.
+.sp
+See the
+\fIHook function API\fR
+section below for more information
+about hooks.
+.sp
+NOTE: the
+\fBregister_hooks\fR()
+function is only available starting
+with API version 1.2.
+If the
+\fBsudo\fR
+front end doesn't support API
+version 1.2 or higher,
+\fRregister_hooks\fR
+will not be called.
+.RE
+.TP 6n
+deregister_hooks
+.nf
+.RS 6n
+void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBderegister_hooks\fR()
+function is called by the sudo front end
+to deregister any hooks the plugin has registered.
+If the plugin does not support hooks,
+\fRderegister_hooks\fR
+should be set to the
+\fRNULL\fR
+pointer.
+.sp
+The
+\fIversion\fR
+argument describes the version of the hooks API
+supported by the
+\fBsudo\fR
+front end.
+.sp
+The
+\fBderegister_hook\fR()
+function should be used to deregister any
+hooks that were put in place by the
+\fBregister_hook\fR()
+function.
+If the plugin tries to deregister a hook that the front end does not support,
+\fRderegister_hook\fR
+will return an error.
+.sp
+See the
+\fIHook function API\fR
+section below for more information
+about hooks.
+.sp
+NOTE: the
+\fBderegister_hooks\fR()
+function is only available starting
+with API version 1.2.
+If the
+\fBsudo\fR
+front end doesn't support API
+version 1.2 or higher,
+\fRderegister_hooks\fR
+will not be called.
+.RE
+.PP
+\fIPolicy Plugin Version Macros\fR
+.nf
+.sp
+.RS 0n
+/* Plugin API version major/minor. */
+#define SUDO_API_VERSION_MAJOR 1
+#define SUDO_API_VERSION_MINOR 13
+#define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
+#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\e
+ SUDO_API_VERSION_MINOR)
+
+/* Getters and setters for API version */
+#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
+#define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
+#define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \e
+ *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
+} while(0)
+#define SUDO_API_VERSION_SET_MINOR(vp, n) do { \e
+ *(vp) = (*(vp) & 0xffff0000) | (n); \e
+} while(0)
+.RE
+.fi
+.SS "I/O plugin API"
+.nf
+.RS 0n
+struct io_plugin {
+#define SUDO_IO_PLUGIN 2
+ unsigned int type; /* always SUDO_IO_PLUGIN */
+ unsigned int version; /* always SUDO_API_VERSION */
+ int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[],
+ char * const plugin_options[]);
+ void (*close)(int exit_status, int error); /* wait status or error */
+ int (*show_version)(int verbose);
+ int (*log_ttyin)(const char *buf, unsigned int len);
+ int (*log_ttyout)(const char *buf, unsigned int len);
+ int (*log_stdin)(const char *buf, unsigned int len);
+ int (*log_stdout)(const char *buf, unsigned int len);
+ int (*log_stderr)(const char *buf, unsigned int len);
+ void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+ void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
+ int (*change_winsize)(unsigned int lines, unsigned int cols);
+ int (*log_suspend)(int signo);
+};
+.RE
+.fi
+.PP
+When an I/O plugin is loaded,
+\fBsudo\fR
+runs the command in a pseudo-tty.
+This makes it possible to log the input and output from the user's
+session.
+If any of the standard input, standard output or standard error do not
+correspond to a tty,
+\fBsudo\fR
+will open a pipe to capture
+the I/O for logging before passing it on.
+.PP
+The log_ttyin function receives the raw user input from the terminal
+device (note that this will include input even when echo is disabled,
+such as when a password is read).
+The log_ttyout function receives output from the pseudo-tty that is
+suitable for replaying the user's session at a later time.
+The
+\fBlog_stdin\fR(),
+\fBlog_stdout\fR()
+and
+\fBlog_stderr\fR()
+functions are only called if the standard input, standard output
+or standard error respectively correspond to something other than
+a tty.
+.PP
+Any of the logging functions may be set to the
+\fRNULL\fR
+pointer if no logging is to be performed.
+If the open function returns 0, no I/O will be sent to the plugin.
+.PP
+If a logging function returns an error
+(\-1),
+the running command will be terminated and all of the plugin's logging
+functions will be disabled.
+Other I/O logging plugins will still receive any remaining
+input or output that has not yet been processed.
+.PP
+If an input logging function rejects the data by returning 0, the
+command will be terminated and the data will not be passed to the
+command, though it will still be sent to any other I/O logging plugins.
+If an output logging function rejects the data by returning 0, the
+command will be terminated and the data will not be written to the
+terminal, though it will still be sent to any other I/O logging plugins.
+.PP
+The io_plugin struct has the following fields:
+.TP 6n
+type
+The
+\fRtype\fR
+field should always be set to
+\fRSUDO_IO_PLUGIN\fR.
+.TP 6n
+version
+The
+\fRversion\fR
+field should be set to
+\fRSUDO_API_VERSION\fR.
+.sp
+This allows
+\fBsudo\fR
+to determine the API version the plugin was
+built against.
+.TP 6n
+open
+.nf
+.RS 6n
+int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[],
+ char * const plugin_options[]);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBopen\fR()
+function is run before the
+\fBlog_ttyin\fR(),
+\fBlog_ttyout\fR(),
+\fBlog_stdin\fR(),
+\fBlog_stdout\fR(),
+\fBlog_stderr\fR(),
+\fBlog_suspend\fR(),
+\fBchange_winsize\fR(),
+or
+\fBshow_version\fR()
+functions are called.
+It is only called if the version is being requested or if the
+policy plugin's
+\fBcheck_policy\fR()
+function has returned successfully.
+It returns 1 on success, 0 on failure, \-1 if a general error occurred,
+or \-2 if there was a usage error.
+In the latter case,
+\fBsudo\fR
+will print a usage message before it exits.
+If an error occurs, the plugin may optionally call the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present
+additional error information to the user.
+.sp
+The function arguments are as follows:
+.TP 6n
+version
+The version passed in by
+\fBsudo\fR
+allows the plugin to determine the
+major and minor version number of the plugin API supported by
+\fBsudo\fR.
+.TP 6n
+conversation
+A pointer to the
+\fBconversation\fR()
+function that may be used by the
+\fBshow_version\fR()
+function to display version information (see
+\fBshow_version\fR()
+below).
+The
+\fBconversation\fR()
+function may also be used to display additional error message to the user.
+The
+\fBconversation\fR()
+function returns 0 on success and \-1 on failure.
+.TP 6n
+plugin_printf
+A pointer to a
+\fBprintf\fR()-style
+function that may be used by the
+\fBshow_version\fR()
+function to display version information (see
+show_version below).
+The
+\fBplugin_printf\fR()
+function may also be used to display additional error message to the user.
+The
+\fBplugin_printf\fR()
+function returns number of characters printed on success and \-1 on failure.
+.TP 6n
+settings
+A vector of user-supplied
+\fBsudo\fR
+settings in the form of
+\(lqname=value\(rq
+strings.
+The vector is terminated by a
+\fRNULL\fR
+pointer.
+These settings correspond to flags the user specified when running
+\fBsudo\fR.
+As such, they will only be present when the corresponding flag has
+been specified on the command line.
+.sp
+When parsing
+\fIsettings\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.sp
+See the
+\fIPolicy plugin API\fR
+section for a list of all possible settings.
+.TP 6n
+user_info
+A vector of information about the user running the command in the form of
+\(lqname=value\(rq
+strings.
+The vector is terminated by a
+\fRNULL\fR
+pointer.
+.sp
+When parsing
+\fIuser_info\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.sp
+See the
+\fIPolicy plugin API\fR
+section for a list of all possible strings.
+.TP 6n
+argc
+The number of elements in
+\fIargv\fR,
+not counting the final
+\fRNULL\fR
+pointer.
+It can be zero, when
+\fBsudo\fR
+is called with
+\fB\-V\fR.
+.TP 6n
+argv
+If
+non-\fRNULL\fR,
+an argument vector describing a command the user
+wishes to run in the same form as what would be passed to the
+execve(2)
+system call.
+.TP 6n
+user_env
+The user's environment in the form of a
+\fRNULL\fR-terminated
+vector of
+\(lqname=value\(rq
+strings.
+.sp
+When parsing
+\fIuser_env\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.TP 6n
+plugin_options
+Any (non-comment) strings immediately after the plugin path are
+treated as arguments to the plugin.
+These arguments are split on a white space boundary and are passed to
+the plugin in the form of a
+\fRNULL\fR-terminated
+array of strings.
+If no arguments were specified,
+\fIplugin_options\fR
+will be the
+\fRNULL\fR
+pointer.
+.sp
+NOTE: the
+\fIplugin_options\fR
+parameter is only available starting with
+API version 1.2.
+A plugin
+\fBmust\fR
+check the API version specified
+by the
+\fBsudo\fR
+front end before using
+\fIplugin_options\fR.
+Failure to do so may result in a crash.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+close
+.br
+.nf
+.RS 6n
+void (*close)(int exit_status, int error);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBclose\fR()
+function is called when the command being run by
+\fBsudo\fR
+finishes.
+.sp
+The function arguments are as follows:
+.TP 6n
+exit_status
+The command's exit status, as returned by the
+wait(2)
+system call.
+The value of
+\fRexit_status\fR
+is undefined if
+\fRerror\fR
+is non-zero.
+.TP 6n
+error
+.br
+If the command could not be executed, this is set to the value of
+\fRerrno\fR
+set by the
+execve(2)
+system call.
+If the command was successfully executed, the value of
+\fRerror\fR
+is 0.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+show_version
+.nf
+.RS 6n
+int (*show_version)(int verbose);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBshow_version\fR()
+function is called by
+\fBsudo\fR
+when the user specifies
+the
+\fB\-V\fR
+option.
+The plugin may display its version information to the user via the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function using
+\fRSUDO_CONV_INFO_MSG\fR.
+If the user requests detailed version information, the verbose flag will be set.
+.sp
+Returns 1 on success, 0 on failure, \-1 if a general error occurred,
+or \-2 if there was a usage error, although the return value is currently
+ignored.
+.RE
+.TP 6n
+log_ttyin
+.nf
+.RS 6n
+int (*log_ttyin)(const char *buf, unsigned int len);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBlog_ttyin\fR()
+function is called whenever data can be read from
+the user but before it is passed to the running command.
+This allows the plugin to reject data if it chooses to (for instance
+if the input contains banned content).
+Returns 1 if the data should be passed to the command, 0 if the data
+is rejected (which will terminate the running command) or \-1 if an
+error occurred.
+.sp
+The function arguments are as follows:
+.TP 6n
+buf
+The buffer containing user input.
+.TP 6n
+len
+The length of
+\fIbuf\fR
+in bytes.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+log_ttyout
+.nf
+.RS 6n
+int (*log_ttyout)(const char *buf, unsigned int len);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBlog_ttyout\fR()
+function is called whenever data can be read from
+the command but before it is written to the user's terminal.
+This allows the plugin to reject data if it chooses to (for instance
+if the output contains banned content).
+Returns 1 if the data should be passed to the user, 0 if the data is rejected
+(which will terminate the running command) or \-1 if an error occurred.
+.sp
+The function arguments are as follows:
+.TP 6n
+buf
+The buffer containing command output.
+.TP 6n
+len
+The length of
+\fIbuf\fR
+in bytes.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+log_stdin
+.nf
+.RS 6n
+int (*log_stdin)(const char *buf, unsigned int len);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBlog_stdin\fR()
+function is only used if the standard input does
+not correspond to a tty device.
+It is called whenever data can be read from the standard input but
+before it is passed to the running command.
+This allows the plugin to reject data if it chooses to
+(for instance if the input contains banned content).
+Returns 1 if the data should be passed to the command, 0 if the data is
+rejected (which will terminate the running command) or \-1 if an error occurred.
+.sp
+The function arguments are as follows:
+.TP 6n
+buf
+The buffer containing user input.
+.TP 6n
+len
+The length of
+\fIbuf\fR
+in bytes.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+log_stdout
+.nf
+.RS 6n
+int (*log_stdout)(const char *buf, unsigned int len);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBlog_stdout\fR()
+function is only used if the standard output does not correspond
+to a tty device.
+It is called whenever data can be read from the command but before
+it is written to the standard output.
+This allows the plugin to reject data if it chooses to
+(for instance if the output contains banned content).
+Returns 1 if the data should be passed to the user, 0 if the data is
+rejected (which will terminate the running command) or \-1 if an error occurred.
+.sp
+The function arguments are as follows:
+.TP 6n
+buf
+The buffer containing command output.
+.TP 6n
+len
+The length of
+\fIbuf\fR
+in bytes.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+log_stderr
+.nf
+.RS 6n
+int (*log_stderr)(const char *buf, unsigned int len);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBlog_stderr\fR()
+function is only used if the standard error does
+not correspond to a tty device.
+It is called whenever data can be read from the command but before it
+is written to the standard error.
+This allows the plugin to reject data if it chooses to
+(for instance if the output contains banned content).
+Returns 1 if the data should be passed to the user, 0 if the data is
+rejected (which will terminate the running command) or \-1 if an error occurred.
+.sp
+The function arguments are as follows:
+.TP 6n
+buf
+The buffer containing command output.
+.TP 6n
+len
+The length of
+\fIbuf\fR
+in bytes.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+register_hooks
+See the
+\fIPolicy plugin API\fR
+section for a description of
+\fRregister_hooks\fR.
+.TP 6n
+deregister_hooks
+See the
+\fIPolicy plugin API\fR
+section for a description of
+\fRderegister_hooks\fR.
+.TP 6n
+change_winsize
+.nf
+.RS 6n
+int (*change_winsize)(unsigned int lines, unsigned int cols);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBchange_winsize\fR()
+function is called whenever the window size of the terminal changes from
+the initial values specified in the
+\fRuser_info\fR
+list.
+Returns \-1 if an error occurred, in which case no further calls to
+\fBchange_winsize\fR()
+will be made,
+.RE
+.TP 6n
+log_suspend
+.nf
+.RS 6n
+int (*log_suspend)(int signo);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBlog_suspend\fR()
+function is called whenever a command is suspended or resumed.
+The
+\fIsigno\fR
+argument is either the signal that caused the command to be suspended or
+\fRSIGCONT\fR
+if the command was resumed.
+Logging this information makes it possible to skip the period of time when
+the command was suspended during playback of a session.
+Returns \-1 if an error occurred, in which case no further calls to
+\fBlog_suspend\fR()
+will be made,
+.RE
+.PP
+\fII/O Plugin Version Macros\fR
+.PP
+Same as for the
+\fIPolicy plugin API\fR.
+.SS "Signal handlers"
+The
+\fBsudo\fR
+front end installs default signal handlers to trap common signals
+while the plugin functions are run.
+The following signals are trapped by default before the command is
+executed:
+.TP 3n
+\fB\(bu\fR
+\fRSIGALRM\fR
+.PD 0
+.TP 3n
+\fB\(bu\fR
+\fRSIGHUP\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGINT\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGPIPE\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGQUIT\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGTERM\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGTSTP\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGUSR1\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGUSR2\fR
+.PD
+.PP
+If a fatal signal is received before the command is executed,
+\fBsudo\fR
+will call the plugin's
+\fBclose\fR()
+function with an exit status of 128 plus the value of the signal
+that was received.
+This allows for consistent logging of commands killed by a signal
+for plugins that log such information in their
+\fBclose\fR()
+function.
+An exception to this is
+\fRSIGPIPE\fR,
+which is ignored until the command is executed.
+.PP
+A plugin may temporarily install its own signal handlers but must
+restore the original handler before the plugin function returns.
+.SS "Hook function API"
+Beginning with plugin API version 1.2, it is possible to install
+hooks for certain functions called by the
+\fBsudo\fR
+front end.
+.PP
+Currently, the only supported hooks relate to the handling of
+environment variables.
+Hooks can be used to intercept attempts to get, set, or remove
+environment variables so that these changes can be reflected in
+the version of the environment that is used to execute a command.
+A future version of the API will support hooking internal
+\fBsudo\fR
+front end functions as well.
+.PP
+\fIHook structure\fR
+.PP
+Hooks in
+\fBsudo\fR
+are described by the following structure:
+.nf
+.sp
+.RS 0n
+typedef int (*sudo_hook_fn_t)();
+
+struct sudo_hook {
+ unsigned int hook_version;
+ unsigned int hook_type;
+ sudo_hook_fn_t hook_fn;
+ void *closure;
+};
+.RE
+.fi
+.PP
+The
+\fRsudo_hook\fR
+structure has the following fields:
+.TP 6n
+hook_version
+The
+\fRhook_version\fR
+field should be set to
+\fRSUDO_HOOK_VERSION\fR.
+.TP 6n
+hook_type
+The
+\fRhook_type\fR
+field may be one of the following supported hook types:
+.PP
+.RS 6n
+.PD 0
+.TP 6n
+\fRSUDO_HOOK_SETENV\fR
+The C library
+setenv(3)
+function.
+Any registered hooks will run before the C library implementation.
+The
+\fRhook_fn\fR
+field should
+be a function that matches the following typedef:
+.nf
+.sp
+.RS 6n
+typedef int (*sudo_hook_fn_setenv_t)(const char *name,
+ const char *value, int overwrite, void *closure);
+.RE
+.fi
+.RS 6n
+.sp
+If the registered hook does not match the typedef the results are
+unspecified.
+.RE
+.PD
+.TP 6n
+\fRSUDO_HOOK_UNSETENV\fR
+The C library
+unsetenv(3)
+function.
+Any registered hooks will run before the C library implementation.
+The
+\fRhook_fn\fR
+field should
+be a function that matches the following typedef:
+.nf
+.sp
+.RS 6n
+typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
+ void *closure);
+.RE
+.fi
+.TP 6n
+\fRSUDO_HOOK_GETENV\fR
+The C library
+getenv(3)
+function.
+Any registered hooks will run before the C library implementation.
+The
+\fRhook_fn\fR
+field should
+be a function that matches the following typedef:
+.nf
+.sp
+.RS 6n
+typedef int (*sudo_hook_fn_getenv_t)(const char *name,
+ char **value, void *closure);
+.RE
+.fi
+.RS 6n
+.sp
+If the registered hook does not match the typedef the results are
+unspecified.
+.RE
+.TP 6n
+\fRSUDO_HOOK_PUTENV\fR
+The C library
+putenv(3)
+function.
+Any registered hooks will run before the C library implementation.
+The
+\fRhook_fn\fR
+field should
+be a function that matches the following typedef:
+.nf
+.sp
+.RS 6n
+typedef int (*sudo_hook_fn_putenv_t)(char *string,
+ void *closure);
+.RE
+.fi
+.RS 6n
+.sp
+If the registered hook does not match the typedef the results are
+unspecified.
+.RE
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+hook_fn
+sudo_hook_fn_t hook_fn;
+.sp
+The
+\fRhook_fn\fR
+field should be set to the plugin's hook implementation.
+The actual function arguments will vary depending on the
+\fRhook_type\fR
+(see
+\fRhook_type\fR
+above).
+In all cases, the
+\fRclosure\fR
+field of
+\fRstruct sudo_hook\fR
+is passed as the last function parameter.
+This can be used to pass arbitrary data to the plugin's hook implementation.
+.sp
+The function return value may be one of the following:
+.PP
+.RS 6n
+.PD 0
+.TP 6n
+\fRSUDO_HOOK_RET_ERROR\fR
+The hook function encountered an error.
+.PD
+.TP 6n
+\fRSUDO_HOOK_RET_NEXT\fR
+The hook completed without error, go on to the next hook (including
+the native implementation if applicable).
+For example, a
+getenv(3)
+hook might return
+\fRSUDO_HOOK_RET_NEXT\fR
+if the specified variable was not found in the private copy of the environment.
+.TP 6n
+\fRSUDO_HOOK_RET_STOP\fR
+The hook completed without error, stop processing hooks for this invocation.
+This can be used to replace the native implementation.
+For example, a
+\fRsetenv\fR
+hook that operates on a private copy of
+the environment but leaves
+\fRenviron\fR
+unchanged.
+.PD 0
+.PP
+.RE
+.PD
+.PP
+Note that it is very easy to create an infinite loop when hooking
+C library functions.
+For example, a
+getenv(3)
+hook that calls the
+snprintf(3)
+function may create a loop if the
+snprintf(3)
+implementation calls
+getenv(3)
+to check the locale.
+To prevent this, you may wish to use a static variable in the hook
+function to guard against nested calls.
+For example:
+.nf
+.sp
+.RS 0n
+static int in_progress = 0; /* avoid recursion */
+if (in_progress)
+ return SUDO_HOOK_RET_NEXT;
+in_progress = 1;
+\&...
+in_progress = 0;
+return SUDO_HOOK_RET_STOP;
+.RE
+.fi
+.PP
+\fIHook API Version Macros\fR
+.nf
+.sp
+.RS 0n
+/* Hook API version major/minor */
+#define SUDO_HOOK_VERSION_MAJOR 1
+#define SUDO_HOOK_VERSION_MINOR 0
+#define SUDO_HOOK_VERSION SUDO_API_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\e
+ SUDO_HOOK_VERSION_MINOR)
+.RE
+.fi
+.PP
+For getters and setters see the
+\fIPolicy plugin API\fR.
+.SS "Remote command execution"
+The
+\fBsudo\fR
+front end does not have native support for running remote commands.
+However, starting with
+\fBsudo\fR
+1.8.8, the
+\fB\-h\fR
+option may be used to specify a remote host that is passed
+to the policy plugin.
+A plugin may also accept a
+\fIrunas_user\fR
+in the form of
+\(lquser@hostname\(rq
+which will work with older versions of
+\fBsudo\fR.
+It is anticipated that remote commands will be supported by executing a
+\(lqhelper\(rq
+program.
+The policy plugin should setup the execution environment such that the
+\fBsudo\fR
+front end will run the helper which, in turn, will connect to the
+remote host and run the command.
+.PP
+For example, the policy plugin could utilize
+\fBssh\fR
+to perform remote command execution.
+The helper program would be responsible for running
+\fBssh\fR
+with the proper options to use a private key or certificate
+that the remote host will accept and run a program
+on the remote host that would setup the execution environment
+accordingly.
+.PP
+Note that remote
+\fBsudoedit\fR
+functionality must be handled by the policy plugin, not
+\fBsudo\fR
+itself as the front end has no knowledge that a remote command is
+being executed.
+This may be addressed in a future revision of the plugin API.
+.SS "Conversation API"
+If the plugin needs to interact with the user, it may do so via the
+\fBconversation\fR()
+function.
+A plugin should not attempt to read directly from the standard input
+or the user's tty (neither of which are guaranteed to exist).
+The caller must include a trailing newline in
+\fRmsg\fR
+if one is to be printed.
+.PP
+A
+\fBprintf\fR()-style
+function is also available that can be used to display informational
+or error messages to the user, which is usually more convenient for
+simple messages where no use input is required.
+.PP
+\fIConversation function structures\fR
+.PP
+The conversation function takes as arguments pointers to the following
+structures:
+.nf
+.sp
+.RS 0n
+struct sudo_conv_message {
+#define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */
+#define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */
+#define SUDO_CONV_ERROR_MSG 0x0003 /* error message */
+#define SUDO_CONV_INFO_MSG 0x0004 /* informational message */
+#define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */
+#define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */
+#define SUDO_CONV_PREFER_TTY 0x2000 /* flag: use tty if possible */
+ int msg_type;
+ int timeout;
+ const char *msg;
+};
+
+#define SUDO_CONV_REPL_MAX 255
+
+struct sudo_conv_reply {
+ char *reply;
+};
+
+typedef int (*sudo_conv_callback_fn_t)(int signo, void *closure);
+struct sudo_conv_callback {
+ unsigned int version;
+ void *closure;
+ sudo_conv_callback_fn_t on_suspend;
+ sudo_conv_callback_fn_t on_resume;
+};
+.RE
+.fi
+.PP
+Pointers to the
+\fBconversation\fR()
+and
+\fBprintf\fR()-style
+functions are passed
+in to the plugin's
+\fBopen\fR()
+function when the plugin is initialized.
+The following type definitions can be used in the declaration of the
+\fBopen\fR()
+function:
+.nf
+.sp
+.RS 0n
+typedef int (*sudo_conv_t)(int num_msgs,
+ const struct sudo_conv_message msgs[],
+ struct sudo_conv_reply replies[],
+ struct sudo_conv_callback *callback);
+
+typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
+.RE
+.fi
+.PP
+To use the
+\fBconversation\fR()
+function, the plugin must pass an array of
+\fRsudo_conv_message\fR
+and
+\fRsudo_conv_reply\fR
+structures.
+There must be a
+\fRstruct sudo_conv_message\fR
+and
+\fRstruct sudo_conv_reply\fR
+for
+each message in the conversation, that is, both arrays must have the same
+number of elements.
+Each
+\fRstruct sudo_conv_reply\fR
+must have its
+\fIreply\fR
+member initialized to
+\fRNULL\fR.
+The
+\fRstruct sudo_conv_callback\fR
+pointer, if not
+\fRNULL\fR,
+should contain function pointers to be called when the
+\fBsudo\fR
+process is suspended and/or resumed during conversation input.
+The
+\fIon_suspend\fR
+and
+\fIon_resume\fR
+functions are called with the signal that caused
+\fBsudo\fR
+to be suspended and the
+\fIclosure\fR
+pointer from the
+\fRstruct sudo_conv_callback\fR.
+These functions should return 0 on success and \-1 on error.
+On error, the conversation will end and the conversation function
+will return a value of \-1.
+The intended use is to allow the plugin to release resources, such as locks,
+that should not be held indefinitely while suspended and then reacquire them
+when the process is resumed.
+Note that the functions are not actually invoked from within a signal handler.
+.PP
+The
+\fImsg_type\fR
+must be set to one of the following values:
+.TP 6n
+SUDO_CONV_PROMPT_ECHO_OFF
+Prompt the user for input with echo disabled;
+this is generally used for passwords.
+The reply will be stored in the
+\fIreplies\fR
+array, and it will never be
+\fRNULL\fR.
+.TP 6n
+SUDO_CONV_PROMPT_ECHO_ON
+Prompt the user for input with echo enabled.
+The reply will be stored in the
+\fIreplies\fR
+array, and it will never be
+\fRNULL\fR.
+.TP 6n
+SUDO_CONV_ERROR_MSG
+Display an error message.
+The message is written to the standard error unless the
+\fRSUDO_CONV_PREFER_TTY\fR
+flag is set, in which case it is written to the user's terminal if possible.
+.TP 6n
+SUDO_CONV_INFO_MSG
+Display a message.
+The message is written to the standard output unless the
+\fRSUDO_CONV_PREFER_TTY\fR
+flag is set, in which case it is written to the user's terminal if possible.
+.TP 6n
+SUDO_CONV_PROMPT_MASK
+Prompt the user for input but echo an asterisk character for each
+character read.
+The reply will be stored in the
+\fIreplies\fR
+array, and it will never be
+\fRNULL\fR.
+This can be used to provide visual feedback to the user while reading
+sensitive information that should not be displayed.
+.PP
+In addition to the above values, the following flag bits may also be set:
+.TP 6n
+SUDO_CONV_PROMPT_ECHO_OK
+Allow input to be read when echo cannot be disabled
+when the message type is
+\fRSUDO_CONV_PROMPT_ECHO_OFF\fR
+or
+\fRSUDO_CONV_PROMPT_MASK\fR.
+By default,
+\fBsudo\fR
+will refuse to read input if the echo cannot be disabled for those
+message types.
+.TP 6n
+SUDO_CONV_PREFER_TTY
+When displaying a message via
+\fRSUDO_CONV_ERROR_MSG\fR
+or
+\fRSUDO_CONV_INFO_MSG\fR,
+try to write the message to the user's terminal.
+If the terminal is unavailable, the standard error or standard output
+will be used, depending upon whether
+The user's terminal is always used when possible for input,
+this flag is only used for output.
+\fRSUDO_CONV_ERROR_MSG\fR
+or
+\fRSUDO_CONV_INFO_MSG\fR
+was used.
+.PP
+The
+\fItimeout\fR
+in seconds until the prompt will wait for no more input.
+A zero value implies an infinite timeout.
+.PP
+The plugin is responsible for freeing the reply buffer located in each
+\fRstruct sudo_conv_reply\fR,
+if it is not
+\fRNULL\fR.
+\fRSUDO_CONV_REPL_MAX\fR
+represents the maximum length of the reply buffer (not including
+the trailing NUL character).
+In practical terms, this is the longest password
+\fBsudo\fR
+will support.
+It is also useful as a maximum value for the
+\fBmemset_s\fR()
+function when clearing passwords filled in by the conversation function.
+.PP
+The
+\fBprintf\fR()-style
+function uses the same underlying mechanism as the
+\fBconversation\fR()
+function but only supports
+\fRSUDO_CONV_INFO_MSG\fR
+and
+\fRSUDO_CONV_ERROR_MSG\fR
+for the
+\fImsg_type\fR
+parameter.
+It can be more convenient than using the
+\fBconversation\fR()
+function if no user reply is needed and supports standard
+\fBprintf\fR()
+escape sequences.
+.PP
+See the sample plugin for an example of the
+\fBconversation\fR()
+function usage.
+.SS "Sudoers group plugin API"
+The
+\fBsudoers\fR
+plugin supports its own plugin interface to allow non-Unix
+group lookups.
+This can be used to query a group source other than the standard Unix
+group database.
+Two sample group plugins are bundled with
+\fBsudo\fR,
+\fIgroup_file\fR
+and
+\fIsystem_group\fR,
+are detailed in
+sudoers(@mansectform@).
+Third party group plugins include a QAS AD plugin available from Quest Software.
+.PP
+A group plugin must declare and populate a
+\fRsudoers_group_plugin\fR
+struct in the global scope.
+This structure contains pointers to the functions that implement plugin
+initialization, cleanup and group lookup.
+.nf
+.sp
+.RS 0n
+struct sudoers_group_plugin {
+ unsigned int version;
+ int (*init)(int version, sudo_printf_t sudo_printf,
+ char *const argv[]);
+ void (*cleanup)(void);
+ int (*query)(const char *user, const char *group,
+ const struct passwd *pwd);
+};
+.RE
+.fi
+.PP
+The
+\fRsudoers_group_plugin\fR
+struct has the following fields:
+.TP 6n
+version
+The
+\fRversion\fR
+field should be set to GROUP_API_VERSION.
+.sp
+This allows
+\fBsudoers\fR
+to determine the API version the group plugin
+was built against.
+.TP 6n
+init
+.nf
+.RS 6n
+int (*init)(int version, sudo_printf_t plugin_printf,
+ char *const argv[]);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBinit\fR()
+function is called after
+\fIsudoers\fR
+has been parsed but
+before any policy checks.
+It returns 1 on success, 0 on failure (or if the plugin is not configured),
+and \-1 if a error occurred.
+If an error occurs, the plugin may call the
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present additional error information
+to the user.
+.sp
+The function arguments are as follows:
+.TP 6n
+version
+The version passed in by
+\fBsudoers\fR
+allows the plugin to determine the
+major and minor version number of the group plugin API supported by
+\fBsudoers\fR.
+.TP 6n
+plugin_printf
+A pointer to a
+\fBprintf\fR()-style
+function that may be used to display informational or error message to the user.
+Returns the number of characters printed on success and \-1 on failure.
+.TP 6n
+argv
+A
+\fRNULL\fR-terminated
+array of arguments generated from the
+\fIgroup_plugin\fR
+option in
+\fIsudoers\fR.
+If no arguments were given,
+\fIargv\fR
+will be
+\fRNULL\fR.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+cleanup
+.nf
+.RS 6n
+void (*cleanup)();
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBcleanup\fR()
+function is called when
+\fBsudoers\fR
+has finished its
+group checks.
+The plugin should free any memory it has allocated and close open file handles.
+.RE
+.TP 6n
+query
+.br
+.nf
+.RS 6n
+int (*query)(const char *user, const char *group,
+ const struct passwd *pwd);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBquery\fR()
+function is used to ask the group plugin whether
+\fIuser\fR
+is a member of
+\fIgroup\fR.
+.sp
+The function arguments are as follows:
+.TP 6n
+user
+The name of the user being looked up in the external group database.
+.TP 6n
+group
+.br
+The name of the group being queried.
+.TP 6n
+pwd
+The password database entry for
+\fIuser\fR,
+if any.
+If
+\fIuser\fR
+is not
+present in the password database,
+\fIpwd\fR
+will be
+\fRNULL\fR.
+.PD 0
+.PP
+.RE
+.PD
+.PP
+\fIGroup API Version Macros\fR
+.nf
+.sp
+.RS 0n
+/* Sudoers group plugin version major/minor */
+#define GROUP_API_VERSION_MAJOR 1
+#define GROUP_API_VERSION_MINOR 0
+#define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \e
+ GROUP_API_VERSION_MINOR)
+.RE
+.fi
+For getters and setters see the
+\fIPolicy plugin API\fR.
+.SH "PLUGIN API CHANGELOG"
+The following revisions have been made to the Sudo Plugin API.
+.TP 6n
+Version 1.0
+Initial API version.
+.TP 6n
+Version 1.1 (sudo 1.8.0)
+The I/O logging plugin's
+\fBopen\fR()
+function was modified to take the
+\fRcommand_info\fR
+list as an argument.
+.TP 6n
+Version 1.2 (sudo 1.8.5)
+The Policy and I/O logging plugins'
+\fBopen\fR()
+functions are now passed
+a list of plugin parameters if any are specified in
+sudo.conf(@mansectform@).
+.sp
+A simple hooks API has been introduced to allow plugins to hook in to the
+system's environment handling functions.
+.sp
+The
+\fRinit_session\fR
+Policy plugin function is now passed a pointer
+to the user environment which can be updated as needed.
+This can be used to merge in environment variables stored in the PAM
+handle before a command is run.
+.TP 6n
+Version 1.3 (sudo 1.8.7)
+Support for the
+\fIexec_background\fR
+entry has been added to the
+\fRcommand_info\fR
+list.
+.sp
+The
+\fImax_groups\fR
+and
+\fIplugin_dir\fR
+entries were added to the
+\fRsettings\fR
+list.
+.sp
+The
+\fBversion\fR()
+and
+\fBclose\fR()
+functions are now optional.
+Previously, a missing
+\fBversion\fR()
+or
+\fBclose\fR()
+function would result in a crash.
+If no policy plugin
+\fBclose\fR()
+function is defined, a default
+\fBclose\fR()
+function will be provided by the
+\fBsudo\fR
+front end that displays a warning if the command could not be
+executed.
+.sp
+The
+\fBsudo\fR
+front end now installs default signal handlers to trap common signals
+while the plugin functions are run.
+.TP 6n
+Version 1.4 (sudo 1.8.8)
+The
+\fIremote_host\fR
+entry was added to the
+\fRsettings\fR
+list.
+.TP 6n
+Version 1.5 (sudo 1.8.9)
+The
+\fIpreserve_fds\fR
+entry was added to the
+\fRcommand_info\fR
+list.
+.TP 6n
+Version 1.6 (sudo 1.8.11)
+The behavior when an I/O logging plugin returns an error
+(\-1)
+has changed.
+Previously, the
+\fBsudo\fR
+front end took no action when the
+\fBlog_ttyin\fR(),
+\fBlog_ttyout\fR(),
+\fBlog_stdin\fR(),
+\fBlog_stdout\fR(),
+or
+\fBlog_stderr\fR()
+function returned an error.
+.sp
+The behavior when an I/O logging plugin returns 0 has changed.
+Previously, output from the command would be displayed to the
+terminal even if an output logging function returned 0.
+.TP 6n
+Version 1.7 (sudo 1.8.12)
+The
+\fIplugin_path\fR
+entry was added to the
+\fRsettings\fR
+list.
+.sp
+The
+\fIdebug_flags\fR
+entry now starts with a debug file path name and may occur multiple
+times if there are multiple plugin-specific Debug lines in the
+sudo.conf(@mansectform@) file.
+.TP 6n
+Version 1.8 (sudo 1.8.15)
+The
+\fIsudoedit_checkdir\fR
+and
+\fIsudoedit_follow\fR
+entries were added to the
+\fRcommand_info\fR
+list.
+The default value of
+\fIsudoedit_checkdir\fR
+was changed to true in sudo 1.8.16.
+.sp
+The sudo
+\fIconversation\fR
+function now takes a pointer to a
+\fRstruct sudo_conv_callback\fR
+as its fourth argument.
+The
+\fRsudo_conv_t\fR
+definition has been updated to match.
+The plugin must specify that it supports plugin API version 1.8 or higher
+to receive a conversation function pointer that supports this argument.
+.TP 6n
+Version 1.9 (sudo 1.8.16)
+The
+\fIexecfd\fR
+entry was added to the
+\fRcommand_info\fR
+list.
+.TP 6n
+Version 1.10 (sudo 1.8.19)
+The
+\fIumask\fR
+entry was added to the
+\fRuser_info\fR
+list.
+The
+\fIiolog_group\fR,
+\fIiolog_mode\fR,
+and
+\fIiolog_user\fR
+entries were added to the
+\fRcommand_info\fR
+list.
+.TP 6n
+Version 1.11 (sudo 1.8.20)
+The
+\fItimeout\fR
+entry was added to the
+\fRsettings\fR
+list.
+.TP 6n
+Version 1.12 (sudo 1.8.21)
+The
+\fRchange_winsize\fR
+field was added to the io_plugin struct.
+.TP 6n
+Version 1.13 (sudo 1.8.26)
+The
+\fRlog_suspend\fR
+field was added to the io_plugin struct.
+.SH "SEE ALSO"
+sudo.conf(@mansectform@),
+sudoers(@mansectform@),
+sudo(@mansectsu@)
+.SH "AUTHORS"
+Many people have worked on
+\fBsudo\fR
+over the years; this version consists of code written primarily by:
+.sp
+.RS 6n
+Todd C. Miller
+.RE
+.PP
+See the CONTRIBUTORS file in the
+\fBsudo\fR
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+\fBsudo\fR.
+.SH "BUGS"
+If you feel you have found a bug in
+\fBsudo\fR,
+please submit a bug report at https://bugzilla.sudo.ws/
+.SH "SUPPORT"
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.SH "DISCLAIMER"
+\fBsudo\fR
+is provided
+\(lqAS IS\(rq
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+\fBsudo\fR
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/sudo_plugin.mdoc.in b/doc/sudo_plugin.mdoc.in
new file mode 100644
index 0000000..a293ee3
--- /dev/null
+++ b/doc/sudo_plugin.mdoc.in
@@ -0,0 +1,2625 @@
+.\"
+.\" Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd October 24, 2018
+.Dt SUDO_PLUGIN @mansectform@
+.Os Sudo @PACKAGE_VERSION@
+.Sh NAME
+.Nm sudo_plugin
+.Nd Sudo Plugin API
+.Sh DESCRIPTION
+Starting with version 1.8,
+.Nm sudo
+supports a plugin API
+for policy and session logging.
+Plugins may be compiled as dynamic shared objects (the default on
+systems that support them) or compiled statically into the
+.Nm sudo
+binary itself.
+By default, the
+.Nm sudoers
+policy plugin and an associated I/O logging plugin are used.
+Via the plugin API,
+.Nm sudo
+can be configured to use alternate policy and/or I/O logging plugins
+provided by third parties.
+The plugins to be used are specified in the
+.Xr sudo.conf @mansectform@
+file.
+.Pp
+The API is versioned with a major and minor number.
+The minor version number is incremented when additions are made.
+The major number is incremented when incompatible changes are made.
+A plugin should be check the version passed to it and make sure that the
+major version matches.
+.Pp
+The plugin API is defined by the
+.Li sudo_plugin.h
+header file.
+.Ss Policy plugin API
+A policy plugin must declare and populate a
+.Li policy_plugin
+struct in the global scope.
+This structure contains pointers to the functions that implement the
+.Nm sudo
+policy checks.
+The name of the symbol should be specified in
+.Xr sudo.conf @mansectform@
+along with a path to the plugin so that
+.Nm sudo
+can load it.
+.Bd -literal
+struct policy_plugin {
+#define SUDO_POLICY_PLUGIN 1
+ unsigned int type; /* always SUDO_POLICY_PLUGIN */
+ unsigned int version; /* always SUDO_API_VERSION */
+ int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const user_env[],
+ char * const plugin_options[]);
+ void (*close)(int exit_status, int error);
+ int (*show_version)(int verbose);
+ int (*check_policy)(int argc, char * const argv[],
+ char *env_add[], char **command_info[],
+ char **argv_out[], char **user_env_out[]);
+ int (*list)(int argc, char * const argv[], int verbose,
+ const char *list_user);
+ int (*validate)(void);
+ void (*invalidate)(int remove);
+ int (*init_session)(struct passwd *pwd, char **user_env[]);
+ void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+ void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
+};
+.Ed
+.Pp
+The policy_plugin struct has the following fields:
+.Bl -tag -width 4n
+.It type
+The
+.Li type
+field should always be set to SUDO_POLICY_PLUGIN.
+.It version
+The
+.Li version
+field should be set to
+.Dv SUDO_API_VERSION .
+.Pp
+This allows
+.Nm sudo
+to determine the API version the plugin was
+built against.
+.It open
+.Bd -literal -compact
+int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const user_env[],
+ char * const plugin_options[]);
+.Ed
+.Pp
+Returns 1 on success, 0 on failure, \-1 if a general error occurred,
+or \-2 if there was a usage error.
+In the latter case,
+.Nm sudo
+will print a usage message before it exits.
+If an error occurs, the plugin may optionally call the
+.Fn conversation
+or
+.Fn plugin_printf
+function with
+.Dv SUDO_CONF_ERROR_MSG
+to present additional error information to the user.
+.Pp
+The function arguments are as follows:
+.Bl -tag -width 4n
+.It version
+The version passed in by
+.Nm sudo
+allows the plugin to determine the
+major and minor version number of the plugin API supported by
+.Nm sudo .
+.It conversation
+A pointer to the
+.Fn conversation
+function that can be used by the plugin to interact with the user (see below).
+Returns 0 on success and \-1 on failure.
+.It plugin_printf
+A pointer to a
+.Fn printf Ns -style
+function that may be used to display informational or error messages
+(see below).
+Returns the number of characters printed on success and \-1 on failure.
+.It settings
+A vector of user-supplied
+.Nm sudo
+settings in the form of
+.Dq name=value
+strings.
+The vector is terminated by a
+.Dv NULL
+pointer.
+These settings correspond to flags the user specified when running
+.Nm sudo .
+As such, they will only be present when the corresponding flag has
+been specified on the command line.
+.Pp
+When parsing
+.Em settings ,
+the plugin should split on the
+.Sy first
+equal sign
+.Pq Ql =
+since the
+.Em name
+field will never include one
+itself but the
+.Em value
+might.
+.Bl -tag -width 4n
+.It bsdauth_type=string
+Authentication type, if specified by the
+.Fl a
+flag, to use on
+systems where
+.Bx
+authentication is supported.
+.It closefrom=number
+If specified, the user has requested via the
+.Fl C
+flag that
+.Nm sudo
+close all files descriptors with a value of
+.Em number
+or higher.
+The plugin may optionally pass this, or another value, back in the
+.Em command_info
+list.
+.It debug_flags=string
+A debug file path name followed by a space and a comma-separated
+list of debug flags that correspond to the plugin's
+.Li Debug
+entry in
+.Xr sudo.conf @mansectform@ ,
+if there is one.
+The flags are passed to the plugin exactly as they appear in
+.Xr sudo.conf @mansectform@ .
+The syntax used by
+.Nm sudo
+and the
+.Nm sudoers
+plugin is
+.Em subsystem Ns @ Ns Em priority
+but a plugin is free to use a different
+format so long as it does not include a comma
+.Pq Ql ,\& .
+Prior to
+.Nm sudo
+1.8.12, there was no way to specify plugin-specific
+.Em debug_flags
+so the value was always the same as that used by the
+.Nm sudo
+front end and did not include a path name, only the flags themselves.
+As of version 1.7 of the plugin interface,
+.Nm sudo
+will only pass
+.Em debug_flags
+if
+.Xr sudo.conf @mansectform@
+contains a plugin-specific
+.Li Debug
+entry.
+.It debug_level=number
+This setting has been deprecated in favor of
+.Em debug_flags .
+.It ignore_ticket=bool
+Set to true if the user specified the
+.Fl k
+flag along with a
+command, indicating that the user wishes to ignore any cached
+authentication credentials.
+.Em implied_shell
+to true.
+This allows
+.Nm sudo
+with no arguments
+to be used similarly to
+.Xr su 1 .
+If the plugin does not to support this usage, it may return a value of \-2
+from the
+.Fn check_policy
+function, which will cause
+.Nm sudo
+to print a usage message and
+exit.
+.It implied_shell=bool
+If the user does not specify a program on the command line,
+.Nm sudo
+will pass the plugin the path to the user's shell and set
+.It login_class=string
+.Bx
+login class to use when setting resource limits and nice value,
+if specified by the
+.Fl c
+flag.
+.It login_shell=bool
+Set to true if the user specified the
+.Fl i
+flag, indicating that
+the user wishes to run a login shell.
+.It max_groups=int
+The maximum number of groups a user may belong to.
+This will only be present if there is a corresponding setting in
+.Xr sudo.conf @mansectform@ .
+.It network_addrs=list
+A space-separated list of IP network addresses and netmasks in the
+form
+.Dq addr/netmask ,
+e.g.,
+.Dq 192.168.1.2/255.255.255.0 .
+The address and netmask pairs may be either IPv4 or IPv6, depending on
+what the operating system supports.
+If the address contains a colon
+.Pq Ql :\& ,
+it is an IPv6 address, else it is IPv4.
+.It noninteractive=bool
+Set to true if the user specified the
+.Fl n
+flag, indicating that
+.Nm sudo
+should operate in non-interactive mode.
+The plugin may reject a command run in non-interactive mode if user
+interaction is required.
+.It plugin_dir=string
+The default plugin directory used by the
+.Nm sudo
+front end.
+This is the default directory set at compile time and may not
+correspond to the directory the running plugin was loaded from.
+It may be used by a plugin to locate support files.
+.It plugin_path=string
+The path name of plugin loaded by the
+.Nm sudo
+front end.
+The path name will be a fully-qualified unless the plugin was
+statically compiled into
+.Nm sudo .
+.It preserve_environment=bool
+Set to true if the user specified the
+.Fl E
+flag, indicating that
+the user wishes to preserve the environment.
+.It preserve_groups=bool
+Set to true if the user specified the
+.Fl P
+flag, indicating that
+the user wishes to preserve the group vector instead of setting it
+based on the runas user.
+.It progname=string
+The command name that sudo was run as, typically
+.Dq sudo
+or
+.Dq sudoedit .
+.It prompt=string
+The prompt to use when requesting a password, if specified via
+the
+.Fl p
+flag.
+.It remote_host=string
+The name of the remote host to run the command on, if specified via
+the
+.Fl h
+option.
+Support for running the command on a remote host is meant to be implemented
+via a helper program that is executed in place of the user-specified command.
+The
+.Nm sudo
+front end is only capable of executing commands on the local host.
+Only available starting with API version 1.4.
+.It run_shell=bool
+Set to true if the user specified the
+.Fl s
+flag, indicating that the user wishes to run a shell.
+.It runas_group=string
+The group name or gid to run the command as, if specified via
+the
+.Fl g
+flag.
+.It runas_user=string
+The user name or uid to run the command as, if specified via the
+.Fl u
+flag.
+.It selinux_role=string
+SELinux role to use when executing the command, if specified by
+the
+.Fl r
+flag.
+.It selinux_type=string
+SELinux type to use when executing the command, if specified by
+the
+.Fl t
+flag.
+.It set_home=bool
+Set to true if the user specified the
+.Fl H
+flag.
+If true, set the
+.Li HOME
+environment variable to the target user's home directory.
+.It sudoedit=bool
+Set to true when the
+.Fl e
+flag is specified or if invoked as
+.Nm sudoedit .
+The plugin shall substitute an editor into
+.Em argv
+in the
+.Fn check_policy
+function or return \-2 with a usage error
+if the plugin does not support
+.Em sudoedit .
+For more information, see the
+.Em check_policy
+section.
+.It timeout=string
+User-specified command timeout.
+Not all plugins support command timeouts and the ability for the
+user to set a timeout may be restricted by policy.
+The format of the timeout string is plugin-specific.
+.El
+.Pp
+Additional settings may be added in the future so the plugin should
+silently ignore settings that it does not recognize.
+.It user_info
+A vector of information about the user running the command in the form of
+.Dq name=value
+strings.
+The vector is terminated by a
+.Dv NULL
+pointer.
+.Pp
+When parsing
+.Em user_info ,
+the plugin should split on the
+.Sy first
+equal sign
+.Pq Ql =
+since the
+.Em name
+field will never include one
+itself but the
+.Em value
+might.
+.Bl -tag -width 4n
+.It cols=int
+The number of columns the user's terminal supports.
+If there is no terminal device available, a default value of 80 is used.
+.It cwd=string
+The user's current working directory.
+.It egid=gid_t
+The effective group ID of the user invoking
+.Nm sudo .
+.It euid=uid_t
+The effective user ID of the user invoking
+.Nm sudo .
+.It gid=gid_t
+The real group ID of the user invoking
+.Nm sudo .
+.It groups=list
+The user's supplementary group list formatted as a string of
+comma-separated group IDs.
+.It host=string
+The local machine's hostname as returned by the
+.Xr gethostname 2
+system call.
+.It lines=int
+The number of lines the user's terminal supports.
+If there is
+no terminal device available, a default value of 24 is used.
+.It pgid=int
+The ID of the process group that the running
+.Nm sudo
+process is a member of.
+Only available starting with API version 1.2.
+.It pid=int
+The process ID of the running
+.Nm sudo
+process.
+Only available starting with API version 1.2.
+.It plugin_options
+Any (non-comment) strings immediately after the plugin path are
+passed as arguments to the plugin.
+These arguments are split on a white space boundary and are passed to
+the plugin in the form of a
+.Dv NULL Ns -terminated
+array of strings.
+If no arguments were
+specified,
+.Em plugin_options
+will be the
+.Dv NULL
+pointer.
+.Pp
+NOTE: the
+.Em plugin_options
+parameter is only available starting with
+API version 1.2.
+A plugin
+.Sy must
+check the API version specified
+by the
+.Nm sudo
+front end before using
+.Em plugin_options .
+Failure to do so may result in a crash.
+.It ppid=int
+The parent process ID of the running
+.Nm sudo
+process.
+Only available starting with API version 1.2.
+.It sid=int
+The session ID of the running
+.Nm sudo
+process or 0 if
+.Nm sudo
+is not part of a POSIX job control session.
+Only available starting with API version 1.2.
+.It tcpgid=int
+The ID of the foreground process group associated with the terminal
+device associated with the
+.Nm sudo
+process or \-1 if there is no
+terminal present.
+Only available starting with API version 1.2.
+.It tty=string
+The path to the user's terminal device.
+If the user has no terminal device associated with the session,
+the value will be empty, as in
+.Dq Li tty= .
+.It uid=uid_t
+The real user ID of the user invoking
+.Nm sudo .
+.It umask=octal
+The invoking user's file creation mask.
+Only available starting with API version 1.10.
+.It user=string
+The name of the user invoking
+.Nm sudo .
+.El
+.It user_env
+The user's environment in the form of a
+.Dv NULL Ns -terminated vector of
+.Dq name=value
+strings.
+.Pp
+When parsing
+.Em user_env ,
+the plugin should split on the
+.Sy first
+equal sign
+.Pq Ql =
+since the
+.Em name
+field will never include one
+itself but the
+.Em value
+might.
+.El
+.It close
+.Bd -literal -compact
+void (*close)(int exit_status, int error);
+.Ed
+.Pp
+The
+.Fn close
+function is called when the command being run by
+.Nm sudo
+finishes.
+.Pp
+The function arguments are as follows:
+.Bl -tag -width 4n
+.It exit_status
+The command's exit status, as returned by the
+.Xr wait 2
+system call.
+The value of
+.Li exit_status
+is undefined if
+.Li error
+is non-zero.
+.It error
+If the command could not be executed, this is set to the value of
+.Li errno
+set by the
+.Xr execve 2
+system call.
+The plugin is responsible for displaying error information via the
+.Fn conversation
+or
+.Fn plugin_printf
+function.
+If the command was successfully executed, the value of
+.Li error
+is 0.
+.El
+.Pp
+If no
+.Fn close
+function is defined, no I/O logging plugins are loaded,
+and neither the
+.Em timeout
+not
+.Em use_pty
+options are set in the
+.Li command_info
+list, the
+.Nm sudo
+front end may execute the command directly instead of running
+it as a child process.
+.It show_version
+.Bd -literal -compact
+int (*show_version)(int verbose);
+.Ed
+.Pp
+The
+.Fn show_version
+function is called by
+.Nm sudo
+when the user specifies
+the
+.Fl V
+option.
+The plugin may display its version information to the user via the
+.Fn conversation
+or
+.Fn plugin_printf
+function using
+.Dv SUDO_CONV_INFO_MSG .
+If the user requests detailed version information, the verbose flag will be set.
+.Pp
+Returns 1 on success, 0 on failure, \-1 if a general error occurred,
+or \-2 if there was a usage error, although the return value is currently
+ignored.
+.It check_policy
+.Bd -literal -compact
+int (*check_policy)(int argc, char * const argv[],
+ char *env_add[], char **command_info[],
+ char **argv_out[], char **user_env_out[]);
+.Ed
+.Pp
+The
+.Fn check_policy
+function is called by
+.Nm sudo
+to determine
+whether the user is allowed to run the specified commands.
+.Pp
+If the
+.Em sudoedit
+option was enabled in the
+.Em settings
+array
+passed to the
+.Fn open
+function, the user has requested
+.Em sudoedit
+mode.
+.Em sudoedit
+is a mechanism for editing one or more files
+where an editor is run with the user's credentials instead of with
+elevated privileges.
+.Nm sudo
+achieves this by creating user-writable
+temporary copies of the files to be edited and then overwriting the
+originals with the temporary copies after editing is complete.
+If the plugin supports
+.Em sudoedit ,
+it should choose the editor to be used, potentially from a variable
+in the user's environment, such as
+.Li EDITOR ,
+and include it in
+.Em argv_out
+(note that environment
+variables may include command line flags).
+The files to be edited should be copied from
+.Em argv
+into
+.Em argv_out ,
+separated from the
+editor and its arguments by a
+.Dq Li --
+element.
+The
+.Dq Li --
+will
+be removed by
+.Nm sudo
+before the editor is executed.
+The plugin should also set
+.Em sudoedit=true
+in the
+.Em command_info
+list.
+.Pp
+The
+.Fn check_policy
+function returns 1 if the command is allowed,
+0 if not allowed, \-1 for a general error, or \-2 for a usage error
+or if
+.Em sudoedit
+was specified but is unsupported by the plugin.
+In the latter case,
+.Nm sudo
+will print a usage message before it
+exits.
+If an error occurs, the plugin may optionally call the
+.Fn conversation
+or
+.Fn plugin_printf
+function with
+.Dv SUDO_CONF_ERROR_MSG
+to present additional error information to the user.
+.Pp
+The function arguments are as follows:
+.Bl -tag -width 4n
+.It argc
+The number of elements in
+.Em argv ,
+not counting the final
+.Dv NULL
+pointer.
+.It argv
+The argument vector describing the command the user wishes to run,
+in the same form as what would be passed to the
+.Xr execve 2
+system call.
+The vector is terminated by a
+.Dv NULL
+pointer.
+.It env_add
+Additional environment variables specified by the user on the command
+line in the form of a
+.Dv NULL Ns -terminated
+vector of
+.Dq name=value
+strings.
+The plugin may reject the command if one or more variables
+are not allowed to be set, or it may silently ignore such variables.
+.Pp
+When parsing
+.Em env_add ,
+the plugin should split on the
+.Sy first
+equal sign
+.Pq Ql =
+since the
+.Em name
+field will never include one
+itself but the
+.Em value
+might.
+.It command_info
+Information about the command being run in the form of
+.Dq name=value
+strings.
+These values are used by
+.Nm sudo
+to set the execution
+environment when running a command.
+The plugin is responsible for creating and populating the vector,
+which must be terminated with a
+.Dv NULL
+pointer.
+The following values are recognized by
+.Nm sudo :
+.Bl -tag -width 4n
+.It chroot=string
+The root directory to use when running the command.
+.It closefrom=number
+If specified,
+.Nm sudo
+will close all files descriptors with a value
+of
+.Em number
+or higher.
+.It command=string
+Fully qualified path to the command to be executed.
+.It cwd=string
+The current working directory to change to when executing the command.
+.It exec_background=bool
+By default,
+.Nm sudo
+runs a command as the foreground process as long as
+.Nm sudo
+itself is running in the foreground.
+When
+.Em exec_background
+is enabled and the command is being run in a pty (due to I/O logging
+or the
+.Em use_pty
+setting), the command will be run as a background process.
+Attempts to read from the controlling terminal (or to change terminal
+settings) will result in the command being suspended with the
+.Dv SIGTTIN
+signal (or
+.Dv SIGTTOU
+in the case of terminal settings).
+If this happens when
+.Nm sudo
+is a foreground process, the command will be granted the controlling terminal
+and resumed in the foreground with no user intervention required.
+The advantage of initially running the command in the background is that
+.Nm sudo
+need not read from the terminal unless the command explicitly requests it.
+Otherwise, any terminal input must be passed to the command, whether it
+has required it or not (the kernel buffers terminals so it is not possible
+to tell whether the command really wants the input).
+This is different from historic
+.Em sudo
+behavior or when the command is not being run in a pty.
+.Pp
+For this to work seamlessly, the operating system must support the
+automatic restarting of system calls.
+Unfortunately, not all operating systems do this by default,
+and even those that do may have bugs.
+For example, macOS fails to restart the
+.Fn tcgetattr
+and
+.Fn tcsetattr
+system calls (this is a bug in macOS).
+Furthermore, because this behavior depends on the command stopping with the
+.Dv SIGTTIN
+or
+.Dv SIGTTOU
+signals, programs that catch these signals and suspend themselves
+with a different signal (usually
+.Dv SIGTOP )
+will not be automatically foregrounded.
+Some versions of the linux
+.Xr su 1
+command behave this way.
+Because of this, a plugin should not set
+.Em exec_background
+unless it is explicitly enabled by the administrator and there should
+be a way to enabled or disable it on a per-command basis.
+.Pp
+This setting has no effect unless I/O logging is enabled or
+.Em use_pty
+is enabled.
+.It execfd=number
+If specified,
+.Nm sudo
+will use the
+.Xr fexecve 2
+system call to execute the command instead of
+.Xr execve 2 .
+The specified
+.Em number
+must refer to an open file descriptor.
+.It iolog_compress=bool
+Set to true if the I/O logging plugins, if any, should compress the
+log data.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.It iolog_group=string
+The group that will own newly created I/O log files and directories.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.It iolog_mode=octal
+The file permission mode to use when creating I/O log files and directories.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.It iolog_user=string
+The user that will own newly created I/O log files and directories.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.It iolog_path=string
+Fully qualified path to the file or directory in which I/O log is
+to be stored.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+If no I/O logging plugin is loaded, this setting has no effect.
+.It iolog_stdin=bool
+Set to true if the I/O logging plugins, if any, should log the
+standard input if it is not connected to a terminal device.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.It iolog_stdout=bool
+Set to true if the I/O logging plugins, if any, should log the
+standard output if it is not connected to a terminal device.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.It iolog_stderr=bool
+Set to true if the I/O logging plugins, if any, should log the
+standard error if it is not connected to a terminal device.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.It iolog_ttyin=bool
+Set to true if the I/O logging plugins, if any, should log all
+terminal input.
+This only includes input typed by the user and not from a pipe or
+redirected from a file.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.It iolog_ttyout=bool
+Set to true if the I/O logging plugins, if any, should log all
+terminal output.
+This only includes output to the screen, not output to a pipe or file.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.It login_class=string
+.Bx
+login class to use when setting resource limits and nice value (optional).
+This option is only set on systems that support login classes.
+.It nice=int
+Nice value (priority) to use when executing the command.
+The nice value, if specified, overrides the priority associated with the
+.Em login_class
+on
+.Bx
+systems.
+.It noexec=bool
+If set, prevent the command from executing other programs.
+.It preserve_fds=list
+A comma-separated list of file descriptors that should be
+preserved, regardless of the value of the
+.Em closefrom
+setting.
+Only available starting with API version 1.5.
+.It preserve_groups=bool
+If set,
+.Nm sudo
+will preserve the user's group vector instead of
+initializing the group vector based on
+.Li runas_user .
+.It runas_egid=gid
+Effective group ID to run the command as.
+If not specified, the value of
+.Em runas_gid
+is used.
+.It runas_euid=uid
+Effective user ID to run the command as.
+If not specified, the value of
+.Em runas_uid
+is used.
+.It runas_gid=gid
+Group ID to run the command as.
+.It runas_groups=list
+The supplementary group vector to use for the command in the form
+of a comma-separated list of group IDs.
+If
+.Em preserve_groups
+is set, this option is ignored.
+.It runas_uid=uid
+User ID to run the command as.
+.It selinux_role=string
+SELinux role to use when executing the command.
+.It selinux_type=string
+SELinux type to use when executing the command.
+.It set_utmp=bool
+Create a utmp (or utmpx) entry when a pseudo-tty is allocated.
+By default, the new entry will be a copy of the user's existing utmp
+entry (if any), with the tty, time, type and pid fields updated.
+.It sudoedit=bool
+Set to true when in
+.Em sudoedit
+mode.
+The plugin may enable
+.Em sudoedit
+mode even if
+.Nm sudo
+was not invoked as
+.Nm sudoedit .
+This allows the plugin to perform command substitution and transparently
+enable
+.Em sudoedit
+when the user attempts to run an editor.
+.It sudoedit_checkdir=bool
+Set to false to disable directory writability checks in
+.Nm sudoedit .
+By default,
+.Nm sudoedit
+1.8.16 and higher will check all directory components of the path to be
+edited for writability by the invoking user.
+Symbolic links will not be followed in writable directories and
+.Nm sudoedit
+will refuse to edit a file located in a writable directory.
+These restrictions are not enforced when
+.Nm sudoedit
+is run by root.
+The
+.Em sudoedit_follow
+option can be set to false to disable this check.
+Only available starting with API version 1.8.
+.It sudoedit_follow=bool
+Set to true to allow
+.Nm sudoedit
+to edit files that are symbolic links.
+By default,
+.Nm sudoedit
+1.8.15 and higher will refuse to open a symbolic link.
+The
+.Em sudoedit_follow
+option can be used to restore the older behavior and allow
+.Nm sudoedit
+to open symbolic links.
+Only available starting with API version 1.8.
+.It timeout=int
+Command timeout.
+If non-zero then when the timeout expires the command will be killed.
+.It umask=octal
+The file creation mask to use when executing the command.
+.It use_pty=bool
+Allocate a pseudo-tty to run the command in, regardless of whether
+or not I/O logging is in use.
+By default,
+.Nm sudo
+will only run
+the command in a pty when an I/O log plugin is loaded.
+.It utmp_user=string
+User name to use when constructing a new utmp (or utmpx) entry when
+.Em set_utmp
+is enabled.
+This option can be used to set the user field in the utmp entry to
+the user the command runs as rather than the invoking user.
+If not set,
+.Nm sudo
+will base the new entry on
+the invoking user's existing entry.
+.El
+.Pp
+Unsupported values will be ignored.
+.It argv_out
+The
+.Dv NULL Ns -terminated
+argument vector to pass to the
+.Xr execve 2
+system call when executing the command.
+The plugin is responsible for allocating and populating the vector.
+.It user_env_out
+The
+.Dv NULL Ns -terminated
+environment vector to use when executing the command.
+The plugin is responsible for allocating and populating the vector.
+.El
+.It list
+.Bd -literal -compact
+int (*list)(int argc, char * const argv[],
+ int verbose, const char *list_user);
+.Ed
+.Pp
+List available privileges for the invoking user.
+Returns 1 on success, 0 on failure and \-1 on error.
+On error, the plugin may optionally call the
+.Fn conversation
+or
+.Fn plugin_printf
+function with
+.Dv SUDO_CONF_ERROR_MSG
+to present additional error information to
+the user.
+.Pp
+Privileges should be output via the
+.Fn conversation
+or
+.Fn plugin_printf
+function using
+.Dv SUDO_CONV_INFO_MSG ,
+.Bl -tag -width 4n
+.It verbose
+Flag indicating whether to list in verbose mode or not.
+.It list_user
+The name of a different user to list privileges for if the policy
+allows it.
+If
+.Dv NULL ,
+the plugin should list the privileges of the invoking user.
+.It argc
+The number of elements in
+.Em argv ,
+not counting the final
+.Dv NULL
+pointer.
+.It argv
+If
+.No non- Ns Dv NULL ,
+an argument vector describing a command the user
+wishes to check against the policy in the same form as what would
+be passed to the
+.Xr execve 2
+system call.
+If the command is permitted by the policy, the fully-qualified path
+to the command should be displayed along with any command line arguments.
+.El
+.It validate
+.Bd -literal -compact
+int (*validate)(void);
+.Ed
+.Pp
+The
+.Fn validate
+function is called when
+.Nm sudo
+is run with the
+.Fl v
+flag.
+For policy plugins such as
+.Nm sudoers
+that cache
+authentication credentials, this function will validate and cache
+the credentials.
+.Pp
+The
+.Fn validate
+function should be
+.Dv NULL
+if the plugin does not support credential caching.
+.Pp
+Returns 1 on success, 0 on failure and \-1 on error.
+On error, the plugin may optionally call the
+.Fn conversation
+or
+.Fn plugin_printf
+function with
+.Dv SUDO_CONF_ERROR_MSG
+to present additional
+error information to the user.
+.It invalidate
+.Bd -literal -compact
+void (*invalidate)(int remove);
+.Ed
+.Pp
+The
+.Fn invalidate
+function is called when
+.Nm sudo
+is called with
+the
+.Fl k
+or
+.Fl K
+flag.
+For policy plugins such as
+.Nm sudoers
+that
+cache authentication credentials, this function will invalidate the
+credentials.
+If the
+.Em remove
+flag is set, the plugin may remove
+the credentials instead of simply invalidating them.
+.Pp
+The
+.Fn invalidate
+function should be
+.Dv NULL
+if the plugin does not support credential caching.
+.It init_session
+.Bd -literal -compact
+int (*init_session)(struct passwd *pwd, char **user_envp[);
+.Ed
+.Pp
+The
+.Fn init_session
+function is called before
+.Nm sudo
+sets up the
+execution environment for the command.
+It is run in the parent
+.Nm sudo
+process and before any uid or gid changes.
+This can be used to perform session setup that is not supported by
+.Em command_info ,
+such as opening the PAM session.
+The
+.Fn close
+function can be
+used to tear down the session that was opened by
+.Li init_session .
+.Pp
+The
+.Em pwd
+argument points to a passwd struct for the user the
+command will be run as if the uid the command will run as was found
+in the password database, otherwise it will be
+.Dv NULL .
+.Pp
+The
+.Em user_env
+argument points to the environment the command will
+run in, in the form of a
+.Dv NULL Ns -terminated
+vector of
+.Dq name=value
+strings.
+This is the same string passed back to the front end via
+the Policy Plugin's
+.Em user_env_out
+parameter.
+If the
+.Fn init_session
+function needs to modify the user environment, it should update the
+pointer stored in
+.Em user_env .
+The expected use case is to merge the contents of the PAM environment
+(if any) with the contents of
+.Em user_env .
+NOTE: the
+.Em user_env
+parameter is only available
+starting with API version 1.2.
+A plugin
+.Sy must
+check the API
+version specified by the
+.Nm sudo
+front end before using
+.Em user_env .
+Failure to do so may result in a crash.
+.Pp
+Returns 1 on success, 0 on failure and \-1 on error.
+On error, the plugin may optionally call the
+.Fn conversation
+or
+.Fn plugin_printf
+function with
+.Dv SUDO_CONF_ERROR_MSG
+to present additional
+error information to the user.
+.It register_hooks
+.Bd -literal -compact
+void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+.Ed
+.Pp
+The
+.Fn register_hooks
+function is called by the sudo front end to
+register any hooks the plugin needs.
+If the plugin does not support hooks,
+.Li register_hooks
+should be set to the
+.Dv NULL
+pointer.
+.Pp
+The
+.Em version
+argument describes the version of the hooks API
+supported by the
+.Nm sudo
+front end.
+.Pp
+The
+.Fn register_hook
+function should be used to register any supported
+hooks the plugin needs.
+It returns 0 on success, 1 if the hook type is not supported and \-1
+if the major version in
+.Li struct hook
+does not match the front end's major hook API version.
+.Pp
+See the
+.Sx Hook function API
+section below for more information
+about hooks.
+.Pp
+NOTE: the
+.Fn register_hooks
+function is only available starting
+with API version 1.2.
+If the
+.Nm sudo
+front end doesn't support API
+version 1.2 or higher,
+.Li register_hooks
+will not be called.
+.It deregister_hooks
+.Bd -literal -compact
+void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
+.Ed
+.Pp
+The
+.Fn deregister_hooks
+function is called by the sudo front end
+to deregister any hooks the plugin has registered.
+If the plugin does not support hooks,
+.Li deregister_hooks
+should be set to the
+.Dv NULL
+pointer.
+.Pp
+The
+.Em version
+argument describes the version of the hooks API
+supported by the
+.Nm sudo
+front end.
+.Pp
+The
+.Fn deregister_hook
+function should be used to deregister any
+hooks that were put in place by the
+.Fn register_hook
+function.
+If the plugin tries to deregister a hook that the front end does not support,
+.Li deregister_hook
+will return an error.
+.Pp
+See the
+.Sx Hook function API
+section below for more information
+about hooks.
+.Pp
+NOTE: the
+.Fn deregister_hooks
+function is only available starting
+with API version 1.2.
+If the
+.Nm sudo
+front end doesn't support API
+version 1.2 or higher,
+.Li deregister_hooks
+will not be called.
+.El
+.Pp
+.Em Policy Plugin Version Macros
+.Bd -literal
+/* Plugin API version major/minor. */
+#define SUDO_API_VERSION_MAJOR 1
+#define SUDO_API_VERSION_MINOR 13
+#define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
+#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\e
+ SUDO_API_VERSION_MINOR)
+
+/* Getters and setters for API version */
+#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
+#define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
+#define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \e
+ *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
+} while(0)
+#define SUDO_API_VERSION_SET_MINOR(vp, n) do { \e
+ *(vp) = (*(vp) & 0xffff0000) | (n); \e
+} while(0)
+.Ed
+.Ss I/O plugin API
+.Bd -literal
+struct io_plugin {
+#define SUDO_IO_PLUGIN 2
+ unsigned int type; /* always SUDO_IO_PLUGIN */
+ unsigned int version; /* always SUDO_API_VERSION */
+ int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[],
+ char * const plugin_options[]);
+ void (*close)(int exit_status, int error); /* wait status or error */
+ int (*show_version)(int verbose);
+ int (*log_ttyin)(const char *buf, unsigned int len);
+ int (*log_ttyout)(const char *buf, unsigned int len);
+ int (*log_stdin)(const char *buf, unsigned int len);
+ int (*log_stdout)(const char *buf, unsigned int len);
+ int (*log_stderr)(const char *buf, unsigned int len);
+ void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+ void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
+ int (*change_winsize)(unsigned int lines, unsigned int cols);
+ int (*log_suspend)(int signo);
+};
+.Ed
+.Pp
+When an I/O plugin is loaded,
+.Nm sudo
+runs the command in a pseudo-tty.
+This makes it possible to log the input and output from the user's
+session.
+If any of the standard input, standard output or standard error do not
+correspond to a tty,
+.Nm sudo
+will open a pipe to capture
+the I/O for logging before passing it on.
+.Pp
+The log_ttyin function receives the raw user input from the terminal
+device (note that this will include input even when echo is disabled,
+such as when a password is read).
+The log_ttyout function receives output from the pseudo-tty that is
+suitable for replaying the user's session at a later time.
+The
+.Fn log_stdin ,
+.Fn log_stdout
+and
+.Fn log_stderr
+functions are only called if the standard input, standard output
+or standard error respectively correspond to something other than
+a tty.
+.Pp
+Any of the logging functions may be set to the
+.Dv NULL
+pointer if no logging is to be performed.
+If the open function returns 0, no I/O will be sent to the plugin.
+.Pp
+If a logging function returns an error
+.Pq \-1 ,
+the running command will be terminated and all of the plugin's logging
+functions will be disabled.
+Other I/O logging plugins will still receive any remaining
+input or output that has not yet been processed.
+.Pp
+If an input logging function rejects the data by returning 0, the
+command will be terminated and the data will not be passed to the
+command, though it will still be sent to any other I/O logging plugins.
+If an output logging function rejects the data by returning 0, the
+command will be terminated and the data will not be written to the
+terminal, though it will still be sent to any other I/O logging plugins.
+.Pp
+The io_plugin struct has the following fields:
+.Bl -tag -width 4n
+.It type
+The
+.Li type
+field should always be set to
+.Dv SUDO_IO_PLUGIN .
+.It version
+The
+.Li version
+field should be set to
+.Dv SUDO_API_VERSION .
+.Pp
+This allows
+.Nm sudo
+to determine the API version the plugin was
+built against.
+.It open
+.Bd -literal -compact
+int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[],
+ char * const plugin_options[]);
+.Ed
+.Pp
+The
+.Fn open
+function is run before the
+.Fn log_ttyin ,
+.Fn log_ttyout ,
+.Fn log_stdin ,
+.Fn log_stdout ,
+.Fn log_stderr ,
+.Fn log_suspend ,
+.Fn change_winsize ,
+or
+.Fn show_version
+functions are called.
+It is only called if the version is being requested or if the
+policy plugin's
+.Fn check_policy
+function has returned successfully.
+It returns 1 on success, 0 on failure, \-1 if a general error occurred,
+or \-2 if there was a usage error.
+In the latter case,
+.Nm sudo
+will print a usage message before it exits.
+If an error occurs, the plugin may optionally call the
+.Fn conversation
+or
+.Fn plugin_printf
+function with
+.Dv SUDO_CONF_ERROR_MSG
+to present
+additional error information to the user.
+.Pp
+The function arguments are as follows:
+.Bl -tag -width 4n
+.It version
+The version passed in by
+.Nm sudo
+allows the plugin to determine the
+major and minor version number of the plugin API supported by
+.Nm sudo .
+.It conversation
+A pointer to the
+.Fn conversation
+function that may be used by the
+.Fn show_version
+function to display version information (see
+.Fn show_version
+below).
+The
+.Fn conversation
+function may also be used to display additional error message to the user.
+The
+.Fn conversation
+function returns 0 on success and \-1 on failure.
+.It plugin_printf
+A pointer to a
+.Fn printf Ns -style
+function that may be used by the
+.Fn show_version
+function to display version information (see
+show_version below).
+The
+.Fn plugin_printf
+function may also be used to display additional error message to the user.
+The
+.Fn plugin_printf
+function returns number of characters printed on success and \-1 on failure.
+.It settings
+A vector of user-supplied
+.Nm sudo
+settings in the form of
+.Dq name=value
+strings.
+The vector is terminated by a
+.Dv NULL
+pointer.
+These settings correspond to flags the user specified when running
+.Nm sudo .
+As such, they will only be present when the corresponding flag has
+been specified on the command line.
+.Pp
+When parsing
+.Em settings ,
+the plugin should split on the
+.Sy first
+equal sign
+.Pq Ql =
+since the
+.Em name
+field will never include one
+itself but the
+.Em value
+might.
+.Pp
+See the
+.Sx Policy plugin API
+section for a list of all possible settings.
+.It user_info
+A vector of information about the user running the command in the form of
+.Dq name=value
+strings.
+The vector is terminated by a
+.Dv NULL
+pointer.
+.Pp
+When parsing
+.Em user_info ,
+the plugin should split on the
+.Sy first
+equal sign
+.Pq Ql =
+since the
+.Em name
+field will never include one
+itself but the
+.Em value
+might.
+.Pp
+See the
+.Sx Policy plugin API
+section for a list of all possible strings.
+.It argc
+The number of elements in
+.Em argv ,
+not counting the final
+.Dv NULL
+pointer.
+It can be zero, when
+.Nm sudo
+is called with
+.Fl V .
+.It argv
+If
+.No non- Ns Dv NULL ,
+an argument vector describing a command the user
+wishes to run in the same form as what would be passed to the
+.Xr execve 2
+system call.
+.It user_env
+The user's environment in the form of a
+.Dv NULL Ns -terminated
+vector of
+.Dq name=value
+strings.
+.Pp
+When parsing
+.Em user_env ,
+the plugin should split on the
+.Sy first
+equal sign
+.Pq Ql =
+since the
+.Em name
+field will never include one
+itself but the
+.Em value
+might.
+.It plugin_options
+Any (non-comment) strings immediately after the plugin path are
+treated as arguments to the plugin.
+These arguments are split on a white space boundary and are passed to
+the plugin in the form of a
+.Dv NULL Ns -terminated
+array of strings.
+If no arguments were specified,
+.Em plugin_options
+will be the
+.Dv NULL
+pointer.
+.Pp
+NOTE: the
+.Em plugin_options
+parameter is only available starting with
+API version 1.2.
+A plugin
+.Sy must
+check the API version specified
+by the
+.Nm sudo
+front end before using
+.Em plugin_options .
+Failure to do so may result in a crash.
+.El
+.It close
+.Bd -literal -compact
+void (*close)(int exit_status, int error);
+.Ed
+.Pp
+The
+.Fn close
+function is called when the command being run by
+.Nm sudo
+finishes.
+.Pp
+The function arguments are as follows:
+.Bl -tag -width 4n
+.It exit_status
+The command's exit status, as returned by the
+.Xr wait 2
+system call.
+The value of
+.Li exit_status
+is undefined if
+.Li error
+is non-zero.
+.It error
+If the command could not be executed, this is set to the value of
+.Li errno
+set by the
+.Xr execve 2
+system call.
+If the command was successfully executed, the value of
+.Li error
+is 0.
+.El
+.It show_version
+.Bd -literal -compact
+int (*show_version)(int verbose);
+.Ed
+.Pp
+The
+.Fn show_version
+function is called by
+.Nm sudo
+when the user specifies
+the
+.Fl V
+option.
+The plugin may display its version information to the user via the
+.Fn conversation
+or
+.Fn plugin_printf
+function using
+.Dv SUDO_CONV_INFO_MSG .
+If the user requests detailed version information, the verbose flag will be set.
+.Pp
+Returns 1 on success, 0 on failure, \-1 if a general error occurred,
+or \-2 if there was a usage error, although the return value is currently
+ignored.
+.It log_ttyin
+.Bd -literal -compact
+int (*log_ttyin)(const char *buf, unsigned int len);
+.Ed
+.Pp
+The
+.Fn log_ttyin
+function is called whenever data can be read from
+the user but before it is passed to the running command.
+This allows the plugin to reject data if it chooses to (for instance
+if the input contains banned content).
+Returns 1 if the data should be passed to the command, 0 if the data
+is rejected (which will terminate the running command) or \-1 if an
+error occurred.
+.Pp
+The function arguments are as follows:
+.Bl -tag -width 4n
+.It buf
+The buffer containing user input.
+.It len
+The length of
+.Em buf
+in bytes.
+.El
+.It log_ttyout
+.Bd -literal -compact
+int (*log_ttyout)(const char *buf, unsigned int len);
+.Ed
+.Pp
+The
+.Fn log_ttyout
+function is called whenever data can be read from
+the command but before it is written to the user's terminal.
+This allows the plugin to reject data if it chooses to (for instance
+if the output contains banned content).
+Returns 1 if the data should be passed to the user, 0 if the data is rejected
+(which will terminate the running command) or \-1 if an error occurred.
+.Pp
+The function arguments are as follows:
+.Bl -tag -width 4n
+.It buf
+The buffer containing command output.
+.It len
+The length of
+.Em buf
+in bytes.
+.El
+.It log_stdin
+.Bd -literal -compact
+int (*log_stdin)(const char *buf, unsigned int len);
+.Ed
+.Pp
+The
+.Fn log_stdin
+function is only used if the standard input does
+not correspond to a tty device.
+It is called whenever data can be read from the standard input but
+before it is passed to the running command.
+This allows the plugin to reject data if it chooses to
+(for instance if the input contains banned content).
+Returns 1 if the data should be passed to the command, 0 if the data is
+rejected (which will terminate the running command) or \-1 if an error occurred.
+.Pp
+The function arguments are as follows:
+.Bl -tag -width 4n
+.It buf
+The buffer containing user input.
+.It len
+The length of
+.Em buf
+in bytes.
+.El
+.It log_stdout
+.Bd -literal -compact
+int (*log_stdout)(const char *buf, unsigned int len);
+.Ed
+.Pp
+The
+.Fn log_stdout
+function is only used if the standard output does not correspond
+to a tty device.
+It is called whenever data can be read from the command but before
+it is written to the standard output.
+This allows the plugin to reject data if it chooses to
+(for instance if the output contains banned content).
+Returns 1 if the data should be passed to the user, 0 if the data is
+rejected (which will terminate the running command) or \-1 if an error occurred.
+.Pp
+The function arguments are as follows:
+.Bl -tag -width 4n
+.It buf
+The buffer containing command output.
+.It len
+The length of
+.Em buf
+in bytes.
+.El
+.It log_stderr
+.Bd -literal -compact
+int (*log_stderr)(const char *buf, unsigned int len);
+.Ed
+.Pp
+The
+.Fn log_stderr
+function is only used if the standard error does
+not correspond to a tty device.
+It is called whenever data can be read from the command but before it
+is written to the standard error.
+This allows the plugin to reject data if it chooses to
+(for instance if the output contains banned content).
+Returns 1 if the data should be passed to the user, 0 if the data is
+rejected (which will terminate the running command) or \-1 if an error occurred.
+.Pp
+The function arguments are as follows:
+.Bl -tag -width 4n
+.It buf
+The buffer containing command output.
+.It len
+The length of
+.Em buf
+in bytes.
+.El
+.It register_hooks
+See the
+.Sx Policy plugin API
+section for a description of
+.Li register_hooks .
+.It deregister_hooks
+See the
+.Sx Policy plugin API
+section for a description of
+.Li deregister_hooks .
+.It change_winsize
+.Bd -literal -compact
+int (*change_winsize)(unsigned int lines, unsigned int cols);
+.Ed
+.Pp
+The
+.Fn change_winsize
+function is called whenever the window size of the terminal changes from
+the initial values specified in the
+.Li user_info
+list.
+Returns \-1 if an error occurred, in which case no further calls to
+.Fn change_winsize
+will be made,
+.It log_suspend
+.Bd -literal -compact
+int (*log_suspend)(int signo);
+.Ed
+.Pp
+The
+.Fn log_suspend
+function is called whenever a command is suspended or resumed.
+The
+.Fa signo
+argument is either the signal that caused the command to be suspended or
+.Dv SIGCONT
+if the command was resumed.
+Logging this information makes it possible to skip the period of time when
+the command was suspended during playback of a session.
+Returns \-1 if an error occurred, in which case no further calls to
+.Fn log_suspend
+will be made,
+.El
+.Pp
+.Em I/O Plugin Version Macros
+.Pp
+Same as for the
+.Sx Policy plugin API .
+.Ss Signal handlers
+The
+.Nm sudo
+front end installs default signal handlers to trap common signals
+while the plugin functions are run.
+The following signals are trapped by default before the command is
+executed:
+.Pp
+.Bl -bullet -compact -width 1n
+.It
+.Dv SIGALRM
+.It
+.Dv SIGHUP
+.It
+.Dv SIGINT
+.It
+.Dv SIGPIPE
+.It
+.Dv SIGQUIT
+.It
+.Dv SIGTERM
+.It
+.Dv SIGTSTP
+.It
+.Dv SIGUSR1
+.It
+.Dv SIGUSR2
+.El
+.Pp
+If a fatal signal is received before the command is executed,
+.Nm sudo
+will call the plugin's
+.Fn close
+function with an exit status of 128 plus the value of the signal
+that was received.
+This allows for consistent logging of commands killed by a signal
+for plugins that log such information in their
+.Fn close
+function.
+An exception to this is
+.Ev SIGPIPE ,
+which is ignored until the command is executed.
+.Pp
+A plugin may temporarily install its own signal handlers but must
+restore the original handler before the plugin function returns.
+.Ss Hook function API
+Beginning with plugin API version 1.2, it is possible to install
+hooks for certain functions called by the
+.Nm sudo
+front end.
+.Pp
+Currently, the only supported hooks relate to the handling of
+environment variables.
+Hooks can be used to intercept attempts to get, set, or remove
+environment variables so that these changes can be reflected in
+the version of the environment that is used to execute a command.
+A future version of the API will support hooking internal
+.Nm sudo
+front end functions as well.
+.Pp
+.Em Hook structure
+.Pp
+Hooks in
+.Nm sudo
+are described by the following structure:
+.Bd -literal
+typedef int (*sudo_hook_fn_t)();
+
+struct sudo_hook {
+ unsigned int hook_version;
+ unsigned int hook_type;
+ sudo_hook_fn_t hook_fn;
+ void *closure;
+};
+.Ed
+.Pp
+The
+.Li sudo_hook
+structure has the following fields:
+.Bl -tag -width 4n
+.It hook_version
+The
+.Li hook_version
+field should be set to
+.Dv SUDO_HOOK_VERSION .
+.It hook_type
+The
+.Li hook_type
+field may be one of the following supported hook types:
+.Bl -tag -width 4n
+.It Dv SUDO_HOOK_SETENV
+The C library
+.Xr setenv 3
+function.
+Any registered hooks will run before the C library implementation.
+The
+.Li hook_fn
+field should
+be a function that matches the following typedef:
+.Bd -literal
+typedef int (*sudo_hook_fn_setenv_t)(const char *name,
+ const char *value, int overwrite, void *closure);
+.Ed
+.Pp
+If the registered hook does not match the typedef the results are
+unspecified.
+.It Dv SUDO_HOOK_UNSETENV
+The C library
+.Xr unsetenv 3
+function.
+Any registered hooks will run before the C library implementation.
+The
+.Li hook_fn
+field should
+be a function that matches the following typedef:
+.Bd -literal
+typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
+ void *closure);
+.Ed
+.It Dv SUDO_HOOK_GETENV
+The C library
+.Xr getenv 3
+function.
+Any registered hooks will run before the C library implementation.
+The
+.Li hook_fn
+field should
+be a function that matches the following typedef:
+.Bd -literal
+typedef int (*sudo_hook_fn_getenv_t)(const char *name,
+ char **value, void *closure);
+.Ed
+.Pp
+If the registered hook does not match the typedef the results are
+unspecified.
+.It Dv SUDO_HOOK_PUTENV
+The C library
+.Xr putenv 3
+function.
+Any registered hooks will run before the C library implementation.
+The
+.Li hook_fn
+field should
+be a function that matches the following typedef:
+.Bd -literal
+typedef int (*sudo_hook_fn_putenv_t)(char *string,
+ void *closure);
+.Ed
+.Pp
+If the registered hook does not match the typedef the results are
+unspecified.
+.El
+.It hook_fn
+sudo_hook_fn_t hook_fn;
+.Pp
+The
+.Li hook_fn
+field should be set to the plugin's hook implementation.
+The actual function arguments will vary depending on the
+.Li hook_type
+(see
+.Li hook_type
+above).
+In all cases, the
+.Li closure
+field of
+.Li struct sudo_hook
+is passed as the last function parameter.
+This can be used to pass arbitrary data to the plugin's hook implementation.
+.Pp
+The function return value may be one of the following:
+.Bl -tag -width 4n
+.It Dv SUDO_HOOK_RET_ERROR
+The hook function encountered an error.
+.It Dv SUDO_HOOK_RET_NEXT
+The hook completed without error, go on to the next hook (including
+the native implementation if applicable).
+For example, a
+.Xr getenv 3
+hook might return
+.Dv SUDO_HOOK_RET_NEXT
+if the specified variable was not found in the private copy of the environment.
+.It Dv SUDO_HOOK_RET_STOP
+The hook completed without error, stop processing hooks for this invocation.
+This can be used to replace the native implementation.
+For example, a
+.Li setenv
+hook that operates on a private copy of
+the environment but leaves
+.Li environ
+unchanged.
+.El
+.El
+.Pp
+Note that it is very easy to create an infinite loop when hooking
+C library functions.
+For example, a
+.Xr getenv 3
+hook that calls the
+.Xr snprintf 3
+function may create a loop if the
+.Xr snprintf 3
+implementation calls
+.Xr getenv 3
+to check the locale.
+To prevent this, you may wish to use a static variable in the hook
+function to guard against nested calls.
+For example:
+.Bd -literal
+static int in_progress = 0; /* avoid recursion */
+if (in_progress)
+ return SUDO_HOOK_RET_NEXT;
+in_progress = 1;
+\&...
+in_progress = 0;
+return SUDO_HOOK_RET_STOP;
+.Ed
+.Pp
+.Em Hook API Version Macros
+.Bd -literal
+/* Hook API version major/minor */
+#define SUDO_HOOK_VERSION_MAJOR 1
+#define SUDO_HOOK_VERSION_MINOR 0
+#define SUDO_HOOK_VERSION SUDO_API_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\e
+ SUDO_HOOK_VERSION_MINOR)
+.Ed
+.Pp
+For getters and setters see the
+.Sx Policy plugin API .
+.Ss Remote command execution
+The
+.Nm sudo
+front end does not have native support for running remote commands.
+However, starting with
+.Nm sudo
+1.8.8, the
+.Fl h
+option may be used to specify a remote host that is passed
+to the policy plugin.
+A plugin may also accept a
+.Em runas_user
+in the form of
+.Dq user@hostname
+which will work with older versions of
+.Nm sudo .
+It is anticipated that remote commands will be supported by executing a
+.Dq helper
+program.
+The policy plugin should setup the execution environment such that the
+.Nm sudo
+front end will run the helper which, in turn, will connect to the
+remote host and run the command.
+.Pp
+For example, the policy plugin could utilize
+.Nm ssh
+to perform remote command execution.
+The helper program would be responsible for running
+.Nm ssh
+with the proper options to use a private key or certificate
+that the remote host will accept and run a program
+on the remote host that would setup the execution environment
+accordingly.
+.Pp
+Note that remote
+.Nm sudoedit
+functionality must be handled by the policy plugin, not
+.Nm sudo
+itself as the front end has no knowledge that a remote command is
+being executed.
+This may be addressed in a future revision of the plugin API.
+.Ss Conversation API
+If the plugin needs to interact with the user, it may do so via the
+.Fn conversation
+function.
+A plugin should not attempt to read directly from the standard input
+or the user's tty (neither of which are guaranteed to exist).
+The caller must include a trailing newline in
+.Li msg
+if one is to be printed.
+.Pp
+A
+.Fn printf Ns -style
+function is also available that can be used to display informational
+or error messages to the user, which is usually more convenient for
+simple messages where no use input is required.
+.Pp
+.Em Conversation function structures
+.Pp
+The conversation function takes as arguments pointers to the following
+structures:
+.Bd -literal
+struct sudo_conv_message {
+#define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */
+#define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */
+#define SUDO_CONV_ERROR_MSG 0x0003 /* error message */
+#define SUDO_CONV_INFO_MSG 0x0004 /* informational message */
+#define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */
+#define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */
+#define SUDO_CONV_PREFER_TTY 0x2000 /* flag: use tty if possible */
+ int msg_type;
+ int timeout;
+ const char *msg;
+};
+
+#define SUDO_CONV_REPL_MAX 255
+
+struct sudo_conv_reply {
+ char *reply;
+};
+
+typedef int (*sudo_conv_callback_fn_t)(int signo, void *closure);
+struct sudo_conv_callback {
+ unsigned int version;
+ void *closure;
+ sudo_conv_callback_fn_t on_suspend;
+ sudo_conv_callback_fn_t on_resume;
+};
+.Ed
+.Pp
+Pointers to the
+.Fn conversation
+and
+.Fn printf Ns -style
+functions are passed
+in to the plugin's
+.Fn open
+function when the plugin is initialized.
+The following type definitions can be used in the declaration of the
+.Fn open
+function:
+.Bd -literal
+typedef int (*sudo_conv_t)(int num_msgs,
+ const struct sudo_conv_message msgs[],
+ struct sudo_conv_reply replies[],
+ struct sudo_conv_callback *callback);
+
+typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
+.Ed
+.Pp
+To use the
+.Fn conversation
+function, the plugin must pass an array of
+.Li sudo_conv_message
+and
+.Li sudo_conv_reply
+structures.
+There must be a
+.Li struct sudo_conv_message
+and
+.Li struct sudo_conv_reply
+for
+each message in the conversation, that is, both arrays must have the same
+number of elements.
+Each
+.Li struct sudo_conv_reply
+must have its
+.Em reply
+member initialized to
+.Dv NULL .
+The
+.Li struct sudo_conv_callback
+pointer, if not
+.Dv NULL ,
+should contain function pointers to be called when the
+.Nm sudo
+process is suspended and/or resumed during conversation input.
+The
+.Fa on_suspend
+and
+.Fa on_resume
+functions are called with the signal that caused
+.Nm sudo
+to be suspended and the
+.Fa closure
+pointer from the
+.Li struct sudo_conv_callback .
+These functions should return 0 on success and \-1 on error.
+On error, the conversation will end and the conversation function
+will return a value of \-1.
+The intended use is to allow the plugin to release resources, such as locks,
+that should not be held indefinitely while suspended and then reacquire them
+when the process is resumed.
+Note that the functions are not actually invoked from within a signal handler.
+.Pp
+The
+.Em msg_type
+must be set to one of the following values:
+.Bl -tag -width 4n
+.It SUDO_CONV_PROMPT_ECHO_OFF
+Prompt the user for input with echo disabled;
+this is generally used for passwords.
+The reply will be stored in the
+.Em replies
+array, and it will never be
+.Dv NULL .
+.It SUDO_CONV_PROMPT_ECHO_ON
+Prompt the user for input with echo enabled.
+The reply will be stored in the
+.Em replies
+array, and it will never be
+.Dv NULL .
+.It SUDO_CONV_ERROR_MSG
+Display an error message.
+The message is written to the standard error unless the
+.Dv SUDO_CONV_PREFER_TTY
+flag is set, in which case it is written to the user's terminal if possible.
+.It SUDO_CONV_INFO_MSG
+Display a message.
+The message is written to the standard output unless the
+.Dv SUDO_CONV_PREFER_TTY
+flag is set, in which case it is written to the user's terminal if possible.
+.It SUDO_CONV_PROMPT_MASK
+Prompt the user for input but echo an asterisk character for each
+character read.
+The reply will be stored in the
+.Em replies
+array, and it will never be
+.Dv NULL .
+This can be used to provide visual feedback to the user while reading
+sensitive information that should not be displayed.
+.El
+.Pp
+In addition to the above values, the following flag bits may also be set:
+.Bl -tag -width 4n
+.It SUDO_CONV_PROMPT_ECHO_OK
+Allow input to be read when echo cannot be disabled
+when the message type is
+.Dv SUDO_CONV_PROMPT_ECHO_OFF
+or
+.Dv SUDO_CONV_PROMPT_MASK .
+By default,
+.Nm sudo
+will refuse to read input if the echo cannot be disabled for those
+message types.
+.It SUDO_CONV_PREFER_TTY
+When displaying a message via
+.Dv SUDO_CONV_ERROR_MSG
+or
+.Dv SUDO_CONV_INFO_MSG ,
+try to write the message to the user's terminal.
+If the terminal is unavailable, the standard error or standard output
+will be used, depending upon whether
+The user's terminal is always used when possible for input,
+this flag is only used for output.
+.Dv SUDO_CONV_ERROR_MSG
+or
+.Dv SUDO_CONV_INFO_MSG
+was used.
+.El
+.Pp
+The
+.Em timeout
+in seconds until the prompt will wait for no more input.
+A zero value implies an infinite timeout.
+.Pp
+The plugin is responsible for freeing the reply buffer located in each
+.Li struct sudo_conv_reply ,
+if it is not
+.Dv NULL .
+.Dv SUDO_CONV_REPL_MAX
+represents the maximum length of the reply buffer (not including
+the trailing NUL character).
+In practical terms, this is the longest password
+.Nm sudo
+will support.
+It is also useful as a maximum value for the
+.Fn memset_s
+function when clearing passwords filled in by the conversation function.
+.Pp
+The
+.Fn printf Ns -style
+function uses the same underlying mechanism as the
+.Fn conversation
+function but only supports
+.Dv SUDO_CONV_INFO_MSG
+and
+.Dv SUDO_CONV_ERROR_MSG
+for the
+.Em msg_type
+parameter.
+It can be more convenient than using the
+.Fn conversation
+function if no user reply is needed and supports standard
+.Fn printf
+escape sequences.
+.Pp
+See the sample plugin for an example of the
+.Fn conversation
+function usage.
+.Ss Sudoers group plugin API
+The
+.Nm sudoers
+plugin supports its own plugin interface to allow non-Unix
+group lookups.
+This can be used to query a group source other than the standard Unix
+group database.
+Two sample group plugins are bundled with
+.Nm sudo ,
+.Em group_file
+and
+.Em system_group ,
+are detailed in
+.Xr sudoers @mansectform@ .
+Third party group plugins include a QAS AD plugin available from Quest Software.
+.Pp
+A group plugin must declare and populate a
+.Li sudoers_group_plugin
+struct in the global scope.
+This structure contains pointers to the functions that implement plugin
+initialization, cleanup and group lookup.
+.Bd -literal
+struct sudoers_group_plugin {
+ unsigned int version;
+ int (*init)(int version, sudo_printf_t sudo_printf,
+ char *const argv[]);
+ void (*cleanup)(void);
+ int (*query)(const char *user, const char *group,
+ const struct passwd *pwd);
+};
+.Ed
+.Pp
+The
+.Li sudoers_group_plugin
+struct has the following fields:
+.Bl -tag -width 4n
+.It version
+The
+.Li version
+field should be set to GROUP_API_VERSION.
+.Pp
+This allows
+.Nm sudoers
+to determine the API version the group plugin
+was built against.
+.It init
+.Bd -literal -compact
+int (*init)(int version, sudo_printf_t plugin_printf,
+ char *const argv[]);
+.Ed
+.Pp
+The
+.Fn init
+function is called after
+.Em sudoers
+has been parsed but
+before any policy checks.
+It returns 1 on success, 0 on failure (or if the plugin is not configured),
+and \-1 if a error occurred.
+If an error occurs, the plugin may call the
+.Fn plugin_printf
+function with
+.Dv SUDO_CONF_ERROR_MSG
+to present additional error information
+to the user.
+.Pp
+The function arguments are as follows:
+.Bl -tag -width 4n
+.It version
+The version passed in by
+.Nm sudoers
+allows the plugin to determine the
+major and minor version number of the group plugin API supported by
+.Nm sudoers .
+.It plugin_printf
+A pointer to a
+.Fn printf Ns -style
+function that may be used to display informational or error message to the user.
+Returns the number of characters printed on success and \-1 on failure.
+.It argv
+A
+.Dv NULL Ns -terminated
+array of arguments generated from the
+.Em group_plugin
+option in
+.Em sudoers .
+If no arguments were given,
+.Em argv
+will be
+.Dv NULL .
+.El
+.It cleanup
+.Bd -literal -compact
+void (*cleanup)();
+.Ed
+.Pp
+The
+.Fn cleanup
+function is called when
+.Nm sudoers
+has finished its
+group checks.
+The plugin should free any memory it has allocated and close open file handles.
+.It query
+.Bd -literal -compact
+int (*query)(const char *user, const char *group,
+ const struct passwd *pwd);
+.Ed
+.Pp
+The
+.Fn query
+function is used to ask the group plugin whether
+.Em user
+is a member of
+.Em group .
+.Pp
+The function arguments are as follows:
+.Bl -tag -width 4n
+.It user
+The name of the user being looked up in the external group database.
+.It group
+The name of the group being queried.
+.It pwd
+The password database entry for
+.Em user ,
+if any.
+If
+.Em user
+is not
+present in the password database,
+.Em pwd
+will be
+.Dv NULL .
+.El
+.El
+.Pp
+.Em Group API Version Macros
+.Bd -literal
+/* Sudoers group plugin version major/minor */
+#define GROUP_API_VERSION_MAJOR 1
+#define GROUP_API_VERSION_MINOR 0
+#define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \e
+ GROUP_API_VERSION_MINOR)
+.Ed
+For getters and setters see the
+.Sx Policy plugin API .
+.Sh PLUGIN API CHANGELOG
+The following revisions have been made to the Sudo Plugin API.
+.Bl -tag -width 4n
+.It Version 1.0
+Initial API version.
+.It Version 1.1 (sudo 1.8.0)
+The I/O logging plugin's
+.Fn open
+function was modified to take the
+.Li command_info
+list as an argument.
+.It Version 1.2 (sudo 1.8.5)
+The Policy and I/O logging plugins'
+.Fn open
+functions are now passed
+a list of plugin parameters if any are specified in
+.Xr sudo.conf @mansectform@ .
+.Pp
+A simple hooks API has been introduced to allow plugins to hook in to the
+system's environment handling functions.
+.Pp
+The
+.Li init_session
+Policy plugin function is now passed a pointer
+to the user environment which can be updated as needed.
+This can be used to merge in environment variables stored in the PAM
+handle before a command is run.
+.It Version 1.3 (sudo 1.8.7)
+Support for the
+.Em exec_background
+entry has been added to the
+.Li command_info
+list.
+.Pp
+The
+.Em max_groups
+and
+.Em plugin_dir
+entries were added to the
+.Li settings
+list.
+.Pp
+The
+.Fn version
+and
+.Fn close
+functions are now optional.
+Previously, a missing
+.Fn version
+or
+.Fn close
+function would result in a crash.
+If no policy plugin
+.Fn close
+function is defined, a default
+.Fn close
+function will be provided by the
+.Nm sudo
+front end that displays a warning if the command could not be
+executed.
+.Pp
+The
+.Nm sudo
+front end now installs default signal handlers to trap common signals
+while the plugin functions are run.
+.It Version 1.4 (sudo 1.8.8)
+The
+.Em remote_host
+entry was added to the
+.Li settings
+list.
+.It Version 1.5 (sudo 1.8.9)
+The
+.Em preserve_fds
+entry was added to the
+.Li command_info
+list.
+.It Version 1.6 (sudo 1.8.11)
+The behavior when an I/O logging plugin returns an error
+.Pq \-1
+has changed.
+Previously, the
+.Nm sudo
+front end took no action when the
+.Fn log_ttyin ,
+.Fn log_ttyout ,
+.Fn log_stdin ,
+.Fn log_stdout ,
+or
+.Fn log_stderr
+function returned an error.
+.Pp
+The behavior when an I/O logging plugin returns 0 has changed.
+Previously, output from the command would be displayed to the
+terminal even if an output logging function returned 0.
+.It Version 1.7 (sudo 1.8.12)
+The
+.Em plugin_path
+entry was added to the
+.Li settings
+list.
+.Pp
+The
+.Em debug_flags
+entry now starts with a debug file path name and may occur multiple
+times if there are multiple plugin-specific Debug lines in the
+.Xr sudo.conf @mansectform@ file.
+.It Version 1.8 (sudo 1.8.15)
+The
+.Em sudoedit_checkdir
+and
+.Em sudoedit_follow
+entries were added to the
+.Li command_info
+list.
+The default value of
+.Em sudoedit_checkdir
+was changed to true in sudo 1.8.16.
+.Pp
+The sudo
+.Em conversation
+function now takes a pointer to a
+.Li struct sudo_conv_callback
+as its fourth argument.
+The
+.Li sudo_conv_t
+definition has been updated to match.
+The plugin must specify that it supports plugin API version 1.8 or higher
+to receive a conversation function pointer that supports this argument.
+.It Version 1.9 (sudo 1.8.16)
+The
+.Em execfd
+entry was added to the
+.Li command_info
+list.
+.It Version 1.10 (sudo 1.8.19)
+The
+.Em umask
+entry was added to the
+.Li user_info
+list.
+The
+.Em iolog_group ,
+.Em iolog_mode ,
+and
+.Em iolog_user
+entries were added to the
+.Li command_info
+list.
+.It Version 1.11 (sudo 1.8.20)
+The
+.Em timeout
+entry was added to the
+.Li settings
+list.
+.It Version 1.12 (sudo 1.8.21)
+The
+.Li change_winsize
+field was added to the io_plugin struct.
+.It Version 1.13 (sudo 1.8.26)
+The
+.Li log_suspend
+field was added to the io_plugin struct.
+.El
+.Sh SEE ALSO
+.Xr sudo.conf @mansectform@ ,
+.Xr sudoers @mansectform@ ,
+.Xr sudo @mansectsu@
+.Sh AUTHORS
+Many people have worked on
+.Nm sudo
+over the years; this version consists of code written primarily by:
+.Bd -ragged -offset indent
+.An Todd C. Miller
+.Ed
+.Pp
+See the CONTRIBUTORS file in the
+.Nm sudo
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+.Nm sudo .
+.Sh BUGS
+If you feel you have found a bug in
+.Nm sudo ,
+please submit a bug report at https://bugzilla.sudo.ws/
+.Sh SUPPORT
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.Sh DISCLAIMER
+.Nm sudo
+is provided
+.Dq AS IS
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+.Nm sudo
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/sudoers.cat b/doc/sudoers.cat
new file mode 100644
index 0000000..9cc6a95
--- /dev/null
+++ b/doc/sudoers.cat
@@ -0,0 +1,2931 @@
+SUDOERS(4) File Formats Manual SUDOERS(4)
+
+NNAAMMEE
+ ssuuddooeerrss - default sudo security policy plugin
+
+DDEESSCCRRIIPPTTIIOONN
+ The ssuuddooeerrss policy plugin determines a user's ssuuddoo privileges. It is the
+ default ssuuddoo policy plugin. The policy is driven by the _/_e_t_c_/_s_u_d_o_e_r_s
+ file or, optionally in LDAP. The policy format is described in detail in
+ the _S_U_D_O_E_R_S _F_I_L_E _F_O_R_M_A_T section. For information on storing ssuuddooeerrss
+ policy information in LDAP, please see sudoers.ldap(4).
+
+ CCoonnffiigguurriinngg ssuuddoo..ccoonnff ffoorr ssuuddooeerrss
+ ssuuddoo consults the sudo.conf(4) file to determine which policy and I/O
+ logging plugins to load. If no sudo.conf(4) file is present, or if it
+ contains no Plugin lines, ssuuddooeerrss will be used for policy decisions and
+ I/O logging. To explicitly configure sudo.conf(4) to use the ssuuddooeerrss
+ plugin, the following configuration can be used.
+
+ Plugin sudoers_policy sudoers.so
+ Plugin sudoers_io sudoers.so
+
+ Starting with ssuuddoo 1.8.5, it is possible to specify optional arguments to
+ the ssuuddooeerrss plugin in the sudo.conf(4) file. These arguments, if
+ present, should be listed after the path to the plugin (i.e., after
+ _s_u_d_o_e_r_s_._s_o). Multiple arguments may be specified, separated by white
+ space. For example:
+
+ Plugin sudoers_policy sudoers.so sudoers_mode=0400
+
+ The following plugin arguments are supported:
+
+ ldap_conf=pathname
+ The _l_d_a_p___c_o_n_f argument can be used to override the default path
+ to the _l_d_a_p_._c_o_n_f file.
+
+ ldap_secret=pathname
+ The _l_d_a_p___s_e_c_r_e_t argument can be used to override the default
+ path to the _l_d_a_p_._s_e_c_r_e_t file.
+
+ sudoers_file=pathname
+ The _s_u_d_o_e_r_s___f_i_l_e argument can be used to override the default
+ path to the _s_u_d_o_e_r_s file.
+
+ sudoers_uid=uid
+ The _s_u_d_o_e_r_s___u_i_d argument can be used to override the default
+ owner of the sudoers file. It should be specified as a numeric
+ user ID.
+
+ sudoers_gid=gid
+ The _s_u_d_o_e_r_s___g_i_d argument can be used to override the default
+ group of the sudoers file. It must be specified as a numeric
+ group ID (not a group name).
+
+ sudoers_mode=mode
+ The _s_u_d_o_e_r_s___m_o_d_e argument can be used to override the default
+ file mode for the sudoers file. It should be specified as an
+ octal value.
+
+ For more information on configuring sudo.conf(4), please refer to its
+ manual.
+
+ UUsseerr AAuutthheennttiiccaattiioonn
+ The ssuuddooeerrss security policy requires that most users authenticate
+ themselves before they can use ssuuddoo. A password is not required if the
+ invoking user is root, if the target user is the same as the invoking
+ user, or if the policy has disabled authentication for the user or
+ command. Unlike su(1), when ssuuddooeerrss requires authentication, it
+ validates the invoking user's credentials, not the target user's (or
+ root's) credentials. This can be changed via the _r_o_o_t_p_w, _t_a_r_g_e_t_p_w and
+ _r_u_n_a_s_p_w flags, described later.
+
+ If a user who is not listed in the policy tries to run a command via
+ ssuuddoo, mail is sent to the proper authorities. The address used for such
+ mail is configurable via the _m_a_i_l_t_o Defaults entry (described later) and
+ defaults to root.
+
+ Note that no mail will be sent if an unauthorized user tries to run ssuuddoo
+ with the --ll or --vv option unless there is an authentication error and
+ either the _m_a_i_l___a_l_w_a_y_s or _m_a_i_l___b_a_d_p_a_s_s flags are enabled. This allows
+ users to determine for themselves whether or not they are allowed to use
+ ssuuddoo. All attempts to run ssuuddoo (successful or not) will be logged,
+ regardless of whether or not mail is sent.
+
+ If ssuuddoo is run by root and the SUDO_USER environment variable is set, the
+ ssuuddooeerrss policy will use this value to determine who the actual user is.
+ This can be used by a user to log commands through sudo even when a root
+ shell has been invoked. It also allows the --ee option to remain useful
+ even when invoked via a sudo-run script or program. Note, however, that
+ the _s_u_d_o_e_r_s file lookup is still done for root, not the user specified by
+ SUDO_USER.
+
+ ssuuddooeerrss uses per-user time stamp files for credential caching. Once a
+ user has been authenticated, a record is written containing the user ID
+ that was used to authenticate, the terminal session ID, the start time of
+ the session leader (or parent process) and a time stamp (using a
+ monotonic clock if one is available). The user may then use ssuuddoo without
+ a password for a short period of time (5 minutes unless overridden by the
+ _t_i_m_e_s_t_a_m_p___t_i_m_e_o_u_t option). By default, ssuuddooeerrss uses a separate record
+ for each terminal, which means that a user's login sessions are
+ authenticated separately. The _t_i_m_e_s_t_a_m_p___t_y_p_e option can be used to
+ select the type of time stamp record ssuuddooeerrss will use.
+
+ LLooggggiinngg
+ ssuuddooeerrss can log both successful and unsuccessful attempts (as well as
+ errors) to syslog(3), a log file, or both. By default, ssuuddooeerrss will log
+ via syslog(3) but this is changeable via the _s_y_s_l_o_g and _l_o_g_f_i_l_e Defaults
+ settings. See _L_O_G _F_O_R_M_A_T for a description of the log file format.
+
+ ssuuddooeerrss is also capable of running a command in a pseudo-tty and logging
+ all input and/or output. The standard input, standard output and
+ standard error can be logged even when not associated with a terminal.
+ I/O logging is not on by default but can be enabled using the _l_o_g___i_n_p_u_t
+ and _l_o_g___o_u_t_p_u_t options as well as the LOG_INPUT and LOG_OUTPUT command
+ tags. See _I_/_O _L_O_G _F_I_L_E_S for details on how I/O log files are stored.
+
+ CCoommmmaanndd eennvviirroonnmmeenntt
+ Since environment variables can influence program behavior, ssuuddooeerrss
+ provides a means to restrict which variables from the user's environment
+ are inherited by the command to be run. There are two distinct ways
+ ssuuddooeerrss can deal with environment variables.
+
+ By default, the _e_n_v___r_e_s_e_t option is enabled. This causes commands to be
+ executed with a new, minimal environment. On AIX (and Linux systems
+ without PAM), the environment is initialized with the contents of the
+ _/_e_t_c_/_e_n_v_i_r_o_n_m_e_n_t file. On BSD systems, if the _u_s_e___l_o_g_i_n_c_l_a_s_s option is
+ enabled, the environment is initialized based on the _p_a_t_h and _s_e_t_e_n_v
+ settings in _/_e_t_c_/_l_o_g_i_n_._c_o_n_f. The new environment contains the TERM,
+ PATH, HOME, MAIL, SHELL, LOGNAME, USER and SUDO_* variables in addition
+ to variables from the invoking process permitted by the _e_n_v___c_h_e_c_k and
+ _e_n_v___k_e_e_p options. This is effectively a whitelist for environment
+ variables. The environment variables LOGNAME and USER are treated
+ specially. If one of them is preserved (or removed) from user's
+ environment, the other will be as well. If LOGNAME and USER are to be
+ preserved but only one of them is present in the user's environment, the
+ other will be set to the same value. This avoids an inconsistent
+ environment where one of the variables describing the user name is set to
+ the invoking user and one is set to the target user. () are removed
+ unless both the name and value parts are matched by _e_n_v___k_e_e_p or
+ _e_n_v___c_h_e_c_k, as they may be interpreted as functions by the bbaasshh shell.
+ Prior to version 1.8.11, such variables were always removed.
+
+ If, however, the _e_n_v___r_e_s_e_t option is disabled, any variables not
+ explicitly denied by the _e_n_v___c_h_e_c_k and _e_n_v___d_e_l_e_t_e options are inherited
+ from the invoking process. In this case, _e_n_v___c_h_e_c_k and _e_n_v___d_e_l_e_t_e behave
+ like a blacklist. Prior to version 1.8.21, environment variables with a
+ value beginning with () were always removed. Beginning with version
+ 1.8.21, a pattern in _e_n_v___d_e_l_e_t_e is used to match bbaasshh shell functions
+ instead. Since it is not possible to blacklist all potentially dangerous
+ environment variables, use of the default _e_n_v___r_e_s_e_t behavior is
+ encouraged.
+
+ Environment variables specified by _e_n_v___c_h_e_c_k, _e_n_v___d_e_l_e_t_e, or _e_n_v___k_e_e_p may
+ include one or more `*' characters which will match zero or more
+ characters. No other wildcard characters are supported.
+
+ By default, environment variables are matched by name. However, if the
+ pattern includes an equal sign (`='), both the variables name and value
+ must match. For example, a bbaasshh shell function could be matched as
+ follows:
+
+ env_keep += "BASH_FUNC_my_func%%=()*"
+
+ Without the "=()*" suffix, this would not match, as bbaasshh shell functions
+ are not preserved by default.
+
+ The complete list of environment variables that ssuuddoo allows or denies is
+ contained in the output of "sudo -V" when run as root. Please note that
+ this list varies based on the operating system ssuuddoo is running on.
+
+ On systems that support PAM where the ppaamm__eennvv module is enabled for ssuuddoo,
+ variables in the PAM environment may be merged in to the environment. If
+ a variable in the PAM environment is already present in the user's
+ environment, the value will only be overridden if the variable was not
+ preserved by ssuuddooeerrss. When _e_n_v___r_e_s_e_t is enabled, variables preserved
+ from the invoking user's environment by the _e_n_v___k_e_e_p list take precedence
+ over those in the PAM environment. When _e_n_v___r_e_s_e_t is disabled, variables
+ present the invoking user's environment take precedence over those in the
+ PAM environment unless they match a pattern in the _e_n_v___d_e_l_e_t_e list.
+
+ Note that the dynamic linker on most operating systems will remove
+ variables that can control dynamic linking from the environment of setuid
+ executables, including ssuuddoo. Depending on the operating system this may
+ include _RLD*, DYLD_*, LD_*, LDR_*, LIBPATH, SHLIB_PATH, and others.
+ These type of variables are removed from the environment before ssuuddoo even
+ begins execution and, as such, it is not possible for ssuuddoo to preserve
+ them.
+
+ As a special case, if ssuuddoo's --ii option (initial login) is specified,
+ ssuuddooeerrss will initialize the environment regardless of the value of
+ _e_n_v___r_e_s_e_t. The DISPLAY, PATH and TERM variables remain unchanged; HOME,
+ MAIL, SHELL, USER, and LOGNAME are set based on the target user. On AIX
+ (and Linux systems without PAM), the contents of _/_e_t_c_/_e_n_v_i_r_o_n_m_e_n_t are
+ also included. On BSD systems, if the _u_s_e___l_o_g_i_n_c_l_a_s_s flag is enabled,
+ the _p_a_t_h and _s_e_t_e_n_v variables in _/_e_t_c_/_l_o_g_i_n_._c_o_n_f are also applied. All
+ other environment variables are removed unless permitted by _e_n_v___k_e_e_p or
+ _e_n_v___c_h_e_c_k, described above.
+
+ Finally, the _r_e_s_t_r_i_c_t_e_d___e_n_v___f_i_l_e and _e_n_v___f_i_l_e files are applied, if
+ present. The variables in _r_e_s_t_r_i_c_t_e_d___e_n_v___f_i_l_e are applied first and are
+ subject to the same restrictions as the invoking user's environment, as
+ detailed above. The variables in _e_n_v___f_i_l_e are applied last and are not
+ subject to these restrictions. In both cases, variables present in the
+ files will only be set to their specified values if they would not
+ conflict with an existing environment variable.
+
+SSUUDDOOEERRSS FFIILLEE FFOORRMMAATT
+ The _s_u_d_o_e_r_s file is composed of two types of entries: aliases (basically
+ variables) and user specifications (which specify who may run what).
+
+ When multiple entries match for a user, they are applied in order. Where
+ there are multiple matches, the last match is used (which is not
+ necessarily the most specific match).
+
+ The _s_u_d_o_e_r_s file grammar will be described below in Extended Backus-Naur
+ Form (EBNF). Don't despair if you are unfamiliar with EBNF; it is fairly
+ simple, and the definitions below are annotated.
+
+ QQuuiicckk gguuiiddee ttoo EEBBNNFF
+ EBNF is a concise and exact way of describing the grammar of a language.
+ Each EBNF definition is made up of _p_r_o_d_u_c_t_i_o_n _r_u_l_e_s. E.g.,
+
+ symbol ::= definition | alternate1 | alternate2 ...
+
+ Each _p_r_o_d_u_c_t_i_o_n _r_u_l_e references others and thus makes up a grammar for
+ the language. EBNF also contains the following operators, which many
+ readers will recognize from regular expressions. Do not, however,
+ confuse them with "wildcard" characters, which have different meanings.
+
+ ? Means that the preceding symbol (or group of symbols) is optional.
+ That is, it may appear once or not at all.
+
+ * Means that the preceding symbol (or group of symbols) may appear
+ zero or more times.
+
+ + Means that the preceding symbol (or group of symbols) may appear
+ one or more times.
+
+ Parentheses may be used to group symbols together. For clarity, we will
+ use single quotes ('') to designate what is a verbatim character string
+ (as opposed to a symbol name).
+
+ AAlliiaasseess
+ There are four kinds of aliases: User_Alias, Runas_Alias, Host_Alias and
+ Cmnd_Alias.
+
+ Alias ::= 'User_Alias' User_Alias_Spec (':' User_Alias_Spec)* |
+ 'Runas_Alias' Runas_Alias_Spec (':' Runas_Alias_Spec)* |
+ 'Host_Alias' Host_Alias_Spec (':' Host_Alias_Spec)* |
+ 'Cmnd_Alias' Cmnd_Alias_Spec (':' Cmnd_Alias_Spec)*
+
+ User_Alias ::= NAME
+
+ User_Alias_Spec ::= User_Alias '=' User_List
+
+ Runas_Alias ::= NAME
+
+ Runas_Alias_Spec ::= Runas_Alias '=' Runas_List
+
+ Host_Alias ::= NAME
+
+ Host_Alias_Spec ::= Host_Alias '=' Host_List
+
+ Cmnd_Alias ::= NAME
+
+ Cmnd_Alias_Spec ::= Cmnd_Alias '=' Cmnd_List
+
+ NAME ::= [A-Z]([A-Z][0-9]_)*
+
+ Each _a_l_i_a_s definition is of the form
+
+ Alias_Type NAME = item1, item2, ...
+
+ where _A_l_i_a_s___T_y_p_e is one of User_Alias, Runas_Alias, Host_Alias, or
+ Cmnd_Alias. A NAME is a string of uppercase letters, numbers, and
+ underscore characters (`_'). A NAME mmuusstt start with an uppercase letter.
+ It is possible to put several alias definitions of the same type on a
+ single line, joined by a colon (`:'). E.g.,
+
+ Alias_Type NAME = item1, item2, item3 : NAME = item4, item5
+
+ It is a syntax error to redefine an existing _a_l_i_a_s. It is possible to
+ use the same name for _a_l_i_a_s_e_s of different types, but this is not
+ recommended.
+
+ The definitions of what constitutes a valid _a_l_i_a_s member follow.
+
+ User_List ::= User |
+ User ',' User_List
+
+ User ::= '!'* user name |
+ '!'* #uid |
+ '!'* %group |
+ '!'* %#gid |
+ '!'* +netgroup |
+ '!'* %:nonunix_group |
+ '!'* %:#nonunix_gid |
+ '!'* User_Alias
+
+ A User_List is made up of one or more user names, user IDs (prefixed with
+ `#'), system group names and IDs (prefixed with `%' and `%#'
+ respectively), netgroups (prefixed with `+'), non-Unix group names and
+ IDs (prefixed with `%:' and `%:#' respectively) and User_Aliases. Each
+ list item may be prefixed with zero or more `!' operators. An odd number
+ of `!' operators negate the value of the item; an even number just cancel
+ each other out. User netgroups are matched using the user and domain
+ members only; the host member is not used when matching.
+
+ A user name, uid, group, gid, netgroup, nonunix_group or nonunix_gid may
+ be enclosed in double quotes to avoid the need for escaping special
+ characters. Alternately, special characters may be specified in escaped
+ hex mode, e.g., \x20 for space. When using double quotes, any prefix
+ characters must be included inside the quotes.
+
+ The actual nonunix_group and nonunix_gid syntax depends on the underlying
+ group provider plugin. For instance, the QAS AD plugin supports the
+ following formats:
+
+ ++oo Group in the same domain: "%:Group Name"
+
+ ++oo Group in any domain: "%:Group Name@FULLY.QUALIFIED.DOMAIN"
+
+ ++oo Group SID: "%:S-1-2-34-5678901234-5678901234-5678901234-567"
+
+ See _G_R_O_U_P _P_R_O_V_I_D_E_R _P_L_U_G_I_N_S for more information.
+
+ Note that quotes around group names are optional. Unquoted strings must
+ use a backslash (`\') to escape spaces and special characters. See _O_t_h_e_r
+ _s_p_e_c_i_a_l _c_h_a_r_a_c_t_e_r_s _a_n_d _r_e_s_e_r_v_e_d _w_o_r_d_s for a list of characters that need
+ to be escaped.
+
+ Runas_List ::= Runas_Member |
+ Runas_Member ',' Runas_List
+
+ Runas_Member ::= '!'* user name |
+ '!'* #uid |
+ '!'* %group |
+ '!'* %#gid |
+ '!'* %:nonunix_group |
+ '!'* %:#nonunix_gid |
+ '!'* +netgroup |
+ '!'* Runas_Alias
+
+ A Runas_List is similar to a User_List except that instead of
+ User_Aliases it can contain Runas_Aliases. Note that user names and
+ groups are matched as strings. In other words, two users (groups) with
+ the same uid (gid) are considered to be distinct. If you wish to match
+ all user names with the same uid (e.g., root and toor), you can use a uid
+ instead (#0 in the example given).
+
+ Host_List ::= Host |
+ Host ',' Host_List
+
+ Host ::= '!'* host name |
+ '!'* ip_addr |
+ '!'* network(/netmask)? |
+ '!'* +netgroup |
+ '!'* Host_Alias
+
+ A Host_List is made up of one or more host names, IP addresses, network
+ numbers, netgroups (prefixed with `+') and other aliases. Again, the
+ value of an item may be negated with the `!' operator. Host netgroups
+ are matched using the host (both qualified and unqualified) and domain
+ members only; the user member is not used when matching. If you specify
+ a network number without a netmask, ssuuddoo will query each of the local
+ host's network interfaces and, if the network number corresponds to one
+ of the hosts's network interfaces, will use the netmask of that
+ interface. The netmask may be specified either in standard IP address
+ notation (e.g., 255.255.255.0 or ffff:ffff:ffff:ffff::), or CIDR notation
+ (number of bits, e.g., 24 or 64). A host name may include shell-style
+ wildcards (see the _W_i_l_d_c_a_r_d_s section below), but unless the host name
+ command on your machine returns the fully qualified host name, you'll
+ need to use the _f_q_d_n option for wildcards to be useful. Note that ssuuddoo
+ only inspects actual network interfaces; this means that IP address
+ 127.0.0.1 (localhost) will never match. Also, the host name "localhost"
+ will only match if that is the actual host name, which is usually only
+ the case for non-networked systems.
+
+ digest ::= [A-Fa-f0-9]+ |
+ [[A-Za-z0-9+/=]+
+
+ Digest_Spec ::= "sha224" ':' digest |
+ "sha256" ':' digest |
+ "sha384" ':' digest |
+ "sha512" ':' digest
+
+ Cmnd_List ::= Cmnd |
+ Cmnd ',' Cmnd_List
+
+ command name ::= file name |
+ file name args |
+ file name '""'
+
+ Cmnd ::= Digest_Spec? '!'* command name |
+ '!'* directory |
+ '!'* "sudoedit" |
+ '!'* Cmnd_Alias
+
+ A Cmnd_List is a list of one or more command names, directories, and
+ other aliases. A command name is a fully qualified file name which may
+ include shell-style wildcards (see the _W_i_l_d_c_a_r_d_s section below). A
+ simple file name allows the user to run the command with any arguments
+ he/she wishes. However, you may also specify command line arguments
+ (including wildcards). Alternately, you can specify "" to indicate that
+ the command may only be run wwiitthhoouutt command line arguments. A directory
+ is a fully qualified path name ending in a `/'. When you specify a
+ directory in a Cmnd_List, the user will be able to run any file within
+ that directory (but not in any sub-directories therein).
+
+ If a Cmnd has associated command line arguments, then the arguments in
+ the Cmnd must match exactly those given by the user on the command line
+ (or match the wildcards if there are any). Note that the following
+ characters must be escaped with a `\' if they are used in command
+ arguments: `,', `:', `=', `\'. The built-in command "sudoedit" is used
+ to permit a user to run ssuuddoo with the --ee option (or as ssuuddooeeddiitt). It may
+ take command line arguments just as a normal command does. Note that
+ "sudoedit" is a command built into ssuuddoo itself and must be specified in
+ the _s_u_d_o_e_r_s file without a leading path.
+
+ If a command name is prefixed with a Digest_Spec, the command will only
+ match successfully if it can be verified using the specified SHA-2
+ digest. The following digest formats are supported: sha224, sha256,
+ sha384 and sha512. The string may be specified in either hex or base64
+ format (base64 is more compact). There are several utilities capable of
+ generating SHA-2 digests in hex format such as openssl, shasum,
+ sha224sum, sha256sum, sha384sum, sha512sum.
+
+ For example, using openssl:
+
+ $ openssl dgst -sha224 /bin/ls
+ SHA224(/bin/ls)= 118187da8364d490b4a7debbf483004e8f3e053ec954309de2c41a25
+
+ It is also possible to use openssl to generate base64 output:
+
+ $ openssl dgst -binary -sha224 /bin/ls | openssl base64
+ EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
+
+ Warning, if the user has write access to the command itself (directly or
+ via a ssuuddoo command), it may be possible for the user to replace the
+ command after the digest check has been performed but before the command
+ is executed. A similar race condition exists on systems that lack the
+ fexecve(2) system call when the directory in which the command is located
+ is writable by the user. See the description of the _f_d_e_x_e_c setting for
+ more information on how ssuuddoo executes commands that have an associated
+ digest.
+
+ Command digests are only supported by version 1.8.7 or higher.
+
+ DDeeffaauullttss
+ Certain configuration options may be changed from their default values at
+ run-time via one or more Default_Entry lines. These may affect all users
+ on any host, all users on a specific host, a specific user, a specific
+ command, or commands being run as a specific user. Note that per-command
+ entries may not include command line arguments. If you need to specify
+ arguments, define a Cmnd_Alias and reference that instead.
+
+ Default_Type ::= 'Defaults' |
+ 'Defaults' '@' Host_List |
+ 'Defaults' ':' User_List |
+ 'Defaults' '!' Cmnd_List |
+ 'Defaults' '>' Runas_List
+
+ Default_Entry ::= Default_Type Parameter_List
+
+ Parameter_List ::= Parameter |
+ Parameter ',' Parameter_List
+
+ Parameter ::= Parameter '=' Value |
+ Parameter '+=' Value |
+ Parameter '-=' Value |
+ '!'* Parameter
+
+ Parameters may be ffllaaggss, iinntteeggeerr values, ssttrriinnggss, or lliissttss. Flags are
+ implicitly boolean and can be turned off via the `!' operator. Some
+ integer, string and list parameters may also be used in a boolean context
+ to disable them. Values may be enclosed in double quotes ("") when they
+ contain multiple words. Special characters may be escaped with a
+ backslash (`\').
+
+ Lists have two additional assignment operators, += and -=. These
+ operators are used to add to and delete from a list respectively. It is
+ not an error to use the -= operator to remove an element that does not
+ exist in a list.
+
+ Defaults entries are parsed in the following order: generic, host, user
+ and runas Defaults first, then command defaults. If there are multiple
+ Defaults settings of the same type, the last matching setting is used.
+ The following Defaults settings are parsed before all others since they
+ may affect subsequent entries: _f_q_d_n, _g_r_o_u_p___p_l_u_g_i_n, _r_u_n_a_s___d_e_f_a_u_l_t,
+ _s_u_d_o_e_r_s___l_o_c_a_l_e.
+
+ See _S_U_D_O_E_R_S _O_P_T_I_O_N_S for a list of supported Defaults parameters.
+
+ UUsseerr ssppeecciiffiiccaattiioonn
+ User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \
+ (':' Host_List '=' Cmnd_Spec_List)*
+
+ Cmnd_Spec_List ::= Cmnd_Spec |
+ Cmnd_Spec ',' Cmnd_Spec_List
+
+ Cmnd_Spec ::= Runas_Spec? Option_Spec* Tag_Spec* Cmnd
+
+ Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
+
+ Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Date_Spec | Timeout_Spec)
+
+ SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')
+
+ Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset')
+
+ Date_Spec ::= ('NOTBEFORE=timestamp' | 'NOTAFTER=timestamp')
+
+ Timeout_Spec ::= 'TIMEOUT=timeout'
+
+ Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
+ 'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
+ 'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' |
+ 'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')
+
+ A uusseerr ssppeecciiffiiccaattiioonn determines which commands a user may run (and as
+ what user) on specified hosts. By default, commands are run as rroooott, but
+ this can be changed on a per-command basis.
+
+ The basic structure of a user specification is "who where = (as_whom)
+ what". Let's break that down into its constituent parts:
+
+ RRuunnaass__SSppeecc
+ A Runas_Spec determines the user and/or the group that a command may be
+ run as. A fully-specified Runas_Spec consists of two Runas_Lists (as
+ defined above) separated by a colon (`:') and enclosed in a set of
+ parentheses. The first Runas_List indicates which users the command may
+ be run as via ssuuddoo's --uu option. The second defines a list of groups that
+ can be specified via ssuuddoo's --gg option in addition to any of the target
+ user's groups. If both Runas_Lists are specified, the command may be run
+ with any combination of users and groups listed in their respective
+ Runas_Lists. If only the first is specified, the command may be run as
+ any user in the list but no --gg option may be specified. If the first
+ Runas_List is empty but the second is specified, the command may be run
+ as the invoking user with the group set to any listed in the Runas_List.
+ If both Runas_Lists are empty, the command may only be run as the
+ invoking user. If no Runas_Spec is specified the command may be run as
+ rroooott and no group may be specified.
+
+ A Runas_Spec sets the default for the commands that follow it. What this
+ means is that for the entry:
+
+ dgb boulder = (operator) /bin/ls, /bin/kill, /usr/bin/lprm
+
+ The user ddggbb may run _/_b_i_n_/_l_s, _/_b_i_n_/_k_i_l_l, and _/_u_s_r_/_b_i_n_/_l_p_r_m on the host
+ boulder--but only as ooppeerraattoorr. E.g.,
+
+ $ sudo -u operator /bin/ls
+
+ It is also possible to override a Runas_Spec later on in an entry. If we
+ modify the entry like so:
+
+ dgb boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm
+
+ Then user ddggbb is now allowed to run _/_b_i_n_/_l_s as ooppeerraattoorr, but _/_b_i_n_/_k_i_l_l
+ and _/_u_s_r_/_b_i_n_/_l_p_r_m as rroooott.
+
+ We can extend this to allow ddggbb to run /bin/ls with either the user or
+ group set to ooppeerraattoorr:
+
+ dgb boulder = (operator : operator) /bin/ls, (root) /bin/kill,\
+ /usr/bin/lprm
+
+ Note that while the group portion of the Runas_Spec permits the user to
+ run as command with that group, it does not force the user to do so. If
+ no group is specified on the command line, the command will run with the
+ group listed in the target user's password database entry. The following
+ would all be permitted by the sudoers entry above:
+
+ $ sudo -u operator /bin/ls
+ $ sudo -u operator -g operator /bin/ls
+ $ sudo -g operator /bin/ls
+
+ In the following example, user ttccmm may run commands that access a modem
+ device file with the dialer group.
+
+ tcm boulder = (:dialer) /usr/bin/tip, /usr/bin/cu,\
+ /usr/local/bin/minicom
+
+ Note that in this example only the group will be set, the command still
+ runs as user ttccmm. E.g.
+
+ $ sudo -g dialer /usr/bin/cu
+
+ Multiple users and groups may be present in a Runas_Spec, in which case
+ the user may select any combination of users and groups via the --uu and --gg
+ options. In this example:
+
+ alan ALL = (root, bin : operator, system) ALL
+
+ user aallaann may run any command as either user root or bin, optionally
+ setting the group to operator or system.
+
+ OOppttiioonn__SSppeecc
+ A Cmnd may have zero or more options associated with it. Options may
+ consist of SELinux roles and/or types, Solaris privileges sets, start
+ and/or end dates and command timeouts. Once an option is set for a Cmnd,
+ subsequent Cmnds in the Cmnd_Spec_List, inherit that option unless it is
+ overridden by another option.
+
+ SSEELLiinnuuxx__SSppeecc
+ On systems with SELinux support, _s_u_d_o_e_r_s file entries may optionally have
+ an SELinux role and/or type associated with a command. If a role or type
+ is specified with the command it will override any default values
+ specified in _s_u_d_o_e_r_s. A role or type specified on the command line,
+ however, will supersede the values in _s_u_d_o_e_r_s.
+
+ SSoollaarriiss__PPrriivv__SSppeecc
+ On Solaris systems, _s_u_d_o_e_r_s file entries may optionally specify Solaris
+ privilege set and/or limit privilege set associated with a command. If
+ privileges or limit privileges are specified with the command it will
+ override any default values specified in _s_u_d_o_e_r_s.
+
+ A privilege set is a comma-separated list of privilege names. The
+ ppriv(1) command can be used to list all privileges known to the system.
+ For example:
+
+ $ ppriv -l
+
+ In addition, there are several "special" privilege strings:
+
+ none the empty set
+
+ all the set of all privileges
+
+ zone the set of all privileges available in the current zone
+
+ basic the default set of privileges normal users are granted at login
+ time
+
+ Privileges can be excluded from a set by prefixing the privilege name
+ with either an `!' or `-' character.
+
+ DDaattee__SSppeecc
+ ssuuddooeerrss rules can be specified with a start and end date via the
+ NOTBEFORE and NOTAFTER settings. The time stamp must be specified in
+ _G_e_n_e_r_a_l_i_z_e_d _T_i_m_e as defined by RFC 4517. The format is effectively
+ yyyymmddHHMMSSZ where the minutes and seconds are optional. The `Z'
+ suffix indicates that the time stamp is in Coordinated Universal Time
+ (UTC). It is also possible to specify a timezone offset from UTC in
+ hours and minutes instead of a `Z'. For example, `-0500' would
+ correspond to Eastern Standard time in the US. As an extension, if no
+ `Z' or timezone offset is specified, local time will be used.
+
+ The following are all valid time stamps:
+
+ 20170214083000Z
+ 2017021408Z
+ 20160315220000-0500
+ 20151201235900
+
+ TTiimmeeoouutt__SSppeecc
+ A command may have a timeout associated with it. If the timeout expires
+ before the command has exited, the command will be terminated. The
+ timeout may be specified in combinations of days, hours, minutes and
+ seconds with a single-letter case-insensitive suffix that indicates the
+ unit of time. For example, a timeout of 7 days, 8 hours, 30 minutes and
+ 10 seconds would be written as 7d8h30m10s. If a number is specified
+ without a unit, seconds are assumed. Any of the days, minutes, hours or
+ seconds may be omitted. The order must be from largest to smallest unit
+ and a unit may not be specified more than once.
+
+ The following are all _v_a_l_i_d timeout values: 7d8h30m10s, 14d, 8h30m, 600s,
+ 3600. The following are _i_n_v_a_l_i_d timeout values: 12m2w1d, 30s10m4h,
+ 1d2d3h.
+
+ This option is only supported by version 1.8.20 or higher.
+
+ TTaagg__SSppeecc
+ A command may have zero or more tags associated with it. The following
+ tag values are supported: EXEC, NOEXEC, FOLLOW, NOFOLLOW, LOG_INPUT,
+ NOLOG_INPUT, LOG_OUTPUT, NOLOG_OUTPUT, MAIL, NOMAIL, PASSWD, NOPASSWD,
+ SETENV, and NOSETENV. Once a tag is set on a Cmnd, subsequent Cmnds in
+ the Cmnd_Spec_List, inherit the tag unless it is overridden by the
+ opposite tag (in other words, PASSWD overrides NOPASSWD and NOEXEC
+ overrides EXEC).
+
+ _E_X_E_C and _N_O_E_X_E_C
+
+ If ssuuddoo has been compiled with _n_o_e_x_e_c support and the underlying
+ operating system supports it, the NOEXEC tag can be used to prevent a
+ dynamically-linked executable from running further commands itself.
+
+ In the following example, user aaaarroonn may run _/_u_s_r_/_b_i_n_/_m_o_r_e and
+ _/_u_s_r_/_b_i_n_/_v_i but shell escapes will be disabled.
+
+ aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi
+
+ See the _P_r_e_v_e_n_t_i_n_g _s_h_e_l_l _e_s_c_a_p_e_s section below for more details on how
+ NOEXEC works and whether or not it will work on your system.
+
+ _F_O_L_L_O_W and _N_O_F_O_L_L_O_W Starting with version 1.8.15, ssuuddooeeddiitt will not open
+ a file that is a symbolic link unless the _s_u_d_o_e_d_i_t___f_o_l_l_o_w option is
+ enabled. The _F_O_L_L_O_W and _N_O_F_O_L_L_O_W tags override the value of
+ _s_u_d_o_e_d_i_t___f_o_l_l_o_w and can be used to permit (or deny) the editing of
+ symbolic links on a per-command basis. These tags are only effective
+ for the _s_u_d_o_e_d_i_t command and are ignored for all other commands.
+
+ _L_O_G___I_N_P_U_T and _N_O_L_O_G___I_N_P_U_T
+
+ These tags override the value of the _l_o_g___i_n_p_u_t option on a per-command
+ basis. For more information, see the description of _l_o_g___i_n_p_u_t in the
+ _S_U_D_O_E_R_S _O_P_T_I_O_N_S section below.
+
+ _L_O_G___O_U_T_P_U_T and _N_O_L_O_G___O_U_T_P_U_T
+
+ These tags override the value of the _l_o_g___o_u_t_p_u_t option on a per-command
+ basis. For more information, see the description of _l_o_g___o_u_t_p_u_t in the
+ _S_U_D_O_E_R_S _O_P_T_I_O_N_S section below.
+
+ _M_A_I_L and _N_O_M_A_I_L
+
+ These tags provide fine-grained control over whether mail will be sent
+ when a user runs a command by overriding the value of the
+ _m_a_i_l___a_l_l___c_m_n_d_s option on a per-command basis. They have no effect when
+ ssuuddoo is run with the --ll or --vv options. A _N_O_M_A_I_L tag will also override
+ the _m_a_i_l___a_l_w_a_y_s and _m_a_i_l___n_o___p_e_r_m_s options. For more information, see
+ the descriptions of _m_a_i_l___a_l_l___c_m_n_d_s, _m_a_i_l___a_l_w_a_y_s, and _m_a_i_l___n_o___p_e_r_m_s in
+ the _S_U_D_O_E_R_S _O_P_T_I_O_N_S section below.
+
+ _P_A_S_S_W_D and _N_O_P_A_S_S_W_D
+
+ By default, ssuuddoo requires that a user authenticate him or herself
+ before running a command. This behavior can be modified via the
+ NOPASSWD tag. Like a Runas_Spec, the NOPASSWD tag sets a default for
+ the commands that follow it in the Cmnd_Spec_List. Conversely, the
+ PASSWD tag can be used to reverse things. For example:
+
+ ray rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm
+
+ would allow the user rraayy to run _/_b_i_n_/_k_i_l_l, _/_b_i_n_/_l_s, and _/_u_s_r_/_b_i_n_/_l_p_r_m
+ as rroooott on the machine rushmore without authenticating himself. If we
+ only want rraayy to be able to run _/_b_i_n_/_k_i_l_l without a password the entry
+ would be:
+
+ ray rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm
+
+ Note, however, that the PASSWD tag has no effect on users who are in
+ the group specified by the _e_x_e_m_p_t___g_r_o_u_p option.
+
+ By default, if the NOPASSWD tag is applied to any of the entries for a
+ user on the current host, he or she will be able to run "sudo -l"
+ without a password. Additionally, a user may only run "sudo -v"
+ without a password if the NOPASSWD tag is present for all a user's
+ entries that pertain to the current host. This behavior may be
+ overridden via the _v_e_r_i_f_y_p_w and _l_i_s_t_p_w options.
+
+ _S_E_T_E_N_V and _N_O_S_E_T_E_N_V
+
+ These tags override the value of the _s_e_t_e_n_v option on a per-command
+ basis. Note that if SETENV has been set for a command, the user may
+ disable the _e_n_v___r_e_s_e_t option from the command line via the --EE option.
+ Additionally, environment variables set on the command line are not
+ subject to the restrictions imposed by _e_n_v___c_h_e_c_k, _e_n_v___d_e_l_e_t_e, or
+ _e_n_v___k_e_e_p. As such, only trusted users should be allowed to set
+ variables in this manner. If the command matched is AALLLL, the SETENV
+ tag is implied for that command; this default may be overridden by use
+ of the NOSETENV tag.
+
+ WWiillddccaarrddss
+ ssuuddoo allows shell-style _w_i_l_d_c_a_r_d_s (aka meta or glob characters) to be
+ used in host names, path names and command line arguments in the _s_u_d_o_e_r_s
+ file. Wildcard matching is done via the glob(3) and fnmatch(3) functions
+ as specified by IEEE Std 1003.1 ("POSIX.1").
+
+ * Matches any set of zero or more characters (including white
+ space).
+
+ ? Matches any single character (including white space).
+
+ [...] Matches any character in the specified range.
+
+ [!...] Matches any character _n_o_t in the specified range.
+
+ \x For any character `x', evaluates to `x'. This is used to
+ escape special characters such as: `*', `?', `[', and `]'.
+
+ NNoottee tthhaatt tthheessee aarree nnoott rreegguullaarr eexxpprreessssiioonnss.. Unlike a regular expression
+ there is no way to match one or more characters within a range.
+
+ Character classes may be used if your system's glob(3) and fnmatch(3)
+ functions support them. However, because the `:' character has special
+ meaning in _s_u_d_o_e_r_s, it must be escaped. For example:
+
+ /bin/ls [[\:alpha\:]]*
+
+ Would match any file name beginning with a letter.
+
+ Note that a forward slash (`/') will _n_o_t be matched by wildcards used in
+ the file name portion of the command. This is to make a path like:
+
+ /usr/bin/*
+
+ match _/_u_s_r_/_b_i_n_/_w_h_o but not _/_u_s_r_/_b_i_n_/_X_1_1_/_x_t_e_r_m.
+
+ When matching the command line arguments, however, a slash _d_o_e_s get
+ matched by wildcards since command line arguments may contain arbitrary
+ strings and not just path names.
+
+ WWiillddccaarrddss iinn ccoommmmaanndd lliinnee aarrgguummeennttss sshhoouulldd bbee uusseedd wwiitthh ccaarree..
+ Command line arguments are matched as a single, concatenated string.
+ This mean a wildcard character such as `?' or `*' will match across word
+ boundaries, which may be unexpected. For example, while a sudoers entry
+ like:
+
+ %operator ALL = /bin/cat /var/log/messages*
+
+ will allow command like:
+
+ $ sudo cat /var/log/messages.1
+
+ It will also allow:
+
+ $ sudo cat /var/log/messages /etc/shadow
+
+ which is probably not what was intended. In most cases it is better to
+ do command line processing outside of the _s_u_d_o_e_r_s file in a scripting
+ language.
+
+ EExxcceeppttiioonnss ttoo wwiillddccaarrdd rruulleess
+ The following exceptions apply to the above rules:
+
+ "" If the empty string "" is the only command line argument in the
+ _s_u_d_o_e_r_s file entry it means that command is not allowed to be
+ run with _a_n_y arguments.
+
+ sudoedit Command line arguments to the _s_u_d_o_e_d_i_t built-in command should
+ always be path names, so a forward slash (`/') will not be
+ matched by a wildcard.
+
+ IInncclluuddiinngg ootthheerr ffiilleess ffrroomm wwiitthhiinn ssuuddooeerrss
+ It is possible to include other _s_u_d_o_e_r_s files from within the _s_u_d_o_e_r_s
+ file currently being parsed using the #include and #includedir
+ directives.
+
+ This can be used, for example, to keep a site-wide _s_u_d_o_e_r_s file in
+ addition to a local, per-machine file. For the sake of this example the
+ site-wide _s_u_d_o_e_r_s file will be _/_e_t_c_/_s_u_d_o_e_r_s and the per-machine one will
+ be _/_e_t_c_/_s_u_d_o_e_r_s_._l_o_c_a_l. To include _/_e_t_c_/_s_u_d_o_e_r_s_._l_o_c_a_l from within
+ _/_e_t_c_/_s_u_d_o_e_r_s we would use the following line in _/_e_t_c_/_s_u_d_o_e_r_s:
+
+ #include /etc/sudoers.local
+
+ When ssuuddoo reaches this line it will suspend processing of the current
+ file (_/_e_t_c_/_s_u_d_o_e_r_s) and switch to _/_e_t_c_/_s_u_d_o_e_r_s_._l_o_c_a_l. Upon reaching the
+ end of _/_e_t_c_/_s_u_d_o_e_r_s_._l_o_c_a_l, the rest of _/_e_t_c_/_s_u_d_o_e_r_s will be processed.
+ Files that are included may themselves include other files. A hard limit
+ of 128 nested include files is enforced to prevent include file loops.
+
+ If the path to the include file is not fully-qualified (does not begin
+ with a `/'), it must be located in the same directory as the sudoers file
+ it was included from. For example, if _/_e_t_c_/_s_u_d_o_e_r_s contains the line:
+
+ #include sudoers.local
+
+ the file that will be included is _/_e_t_c_/_s_u_d_o_e_r_s_._l_o_c_a_l.
+
+ The file name may also include the %h escape, signifying the short form
+ of the host name. In other words, if the machine's host name is
+ "xerxes", then
+
+ #include /etc/sudoers.%h
+
+ will cause ssuuddoo to include the file _/_e_t_c_/_s_u_d_o_e_r_s_._x_e_r_x_e_s.
+
+ The #includedir directive can be used to create a _s_u_d_o_e_r_s_._d directory
+ that the system package manager can drop _s_u_d_o_e_r_s file rules into as part
+ of package installation. For example, given:
+
+ #includedir /etc/sudoers.d
+
+ ssuuddoo will suspend processing of the current file and read each file in
+ _/_e_t_c_/_s_u_d_o_e_r_s_._d, skipping file names that end in `~' or contain a `.'
+ character to avoid causing problems with package manager or editor
+ temporary/backup files. Files are parsed in sorted lexical order. That
+ is, _/_e_t_c_/_s_u_d_o_e_r_s_._d_/_0_1___f_i_r_s_t will be parsed before
+ _/_e_t_c_/_s_u_d_o_e_r_s_._d_/_1_0___s_e_c_o_n_d. Be aware that because the sorting is lexical,
+ not numeric, _/_e_t_c_/_s_u_d_o_e_r_s_._d_/_1___w_h_o_o_p_s would be loaded _a_f_t_e_r
+ _/_e_t_c_/_s_u_d_o_e_r_s_._d_/_1_0___s_e_c_o_n_d. Using a consistent number of leading zeroes in
+ the file names can be used to avoid such problems. After parsing the
+ files in the directory, control returns to the file that contained the
+ #includedir directive.
+
+ Note that unlike files included via #include, vviissuuddoo will not edit the
+ files in a #includedir directory unless one of them contains a syntax
+ error. It is still possible to run vviissuuddoo with the --ff flag to edit the
+ files directly, but this will not catch the redefinition of an _a_l_i_a_s that
+ is also present in a different file.
+
+ OOtthheerr ssppeecciiaall cchhaarraacctteerrss aanndd rreesseerrvveedd wwoorrddss
+ The pound sign (`#') is used to indicate a comment (unless it is part of
+ a #include directive or unless it occurs in the context of a user name
+ and is followed by one or more digits, in which case it is treated as a
+ uid). Both the comment character and any text after it, up to the end of
+ the line, are ignored.
+
+ The reserved word AALLLL is a built-in _a_l_i_a_s that always causes a match to
+ succeed. It can be used wherever one might otherwise use a Cmnd_Alias,
+ User_Alias, Runas_Alias, or Host_Alias. You should not try to define
+ your own _a_l_i_a_s called AALLLL as the built-in alias will be used in
+ preference to your own. Please note that using AALLLL can be dangerous
+ since in a command context, it allows the user to run _a_n_y command on the
+ system.
+
+ An exclamation point (`!') can be used as a logical _n_o_t operator in a
+ list or _a_l_i_a_s as well as in front of a Cmnd. This allows one to exclude
+ certain values. For the `!' operator to be effective, there must be
+ something for it to exclude. For example, to match all users except for
+ root one would use:
+
+ ALL,!root
+
+ If the AALLLL, is omitted, as in:
+
+ !root
+
+ it would explicitly deny root but not match any other users. This is
+ different from a true "negation" operator.
+
+ Note, however, that using a `!' in conjunction with the built-in AALLLL
+ alias to allow a user to run "all but a few" commands rarely works as
+ intended (see _S_E_C_U_R_I_T_Y _N_O_T_E_S below).
+
+ Long lines can be continued with a backslash (`\') as the last character
+ on the line.
+
+ White space between elements in a list as well as special syntactic
+ characters in a _U_s_e_r _S_p_e_c_i_f_i_c_a_t_i_o_n (`=', `:', `(', `)') is optional.
+
+ The following characters must be escaped with a backslash (`\') when used
+ as part of a word (e.g., a user name or host name): `!', `=', `:', `,',
+ `(', `)', `\'.
+
+SSUUDDOOEERRSS OOPPTTIIOONNSS
+ ssuuddoo's behavior can be modified by Default_Entry lines, as explained
+ earlier. A list of all supported Defaults parameters, grouped by type,
+ are listed below.
+
+ BBoooolleeaann FFllaaggss:
+
+ always_query_group_plugin
+ If a _g_r_o_u_p___p_l_u_g_i_n is configured, use it to resolve
+ groups of the form %group as long as there is not also
+ a system group of the same name. Normally, only groups
+ of the form %:group are passed to the _g_r_o_u_p___p_l_u_g_i_n.
+ This flag is _o_f_f by default.
+
+ always_set_home If enabled, ssuuddoo will set the HOME environment variable
+ to the home directory of the target user (which is root
+ unless the --uu option is used). This effectively means
+ that the --HH option is always implied. Note that by
+ default, HOME will be set to the home directory of the
+ target user when the _e_n_v___r_e_s_e_t option is enabled, so
+ _a_l_w_a_y_s___s_e_t___h_o_m_e only has an effect for configurations
+ where either _e_n_v___r_e_s_e_t is disabled or HOME is present
+ in the _e_n_v___k_e_e_p list. This flag is _o_f_f by default.
+
+ authenticate If set, users must authenticate themselves via a
+ password (or other means of authentication) before they
+ may run commands. This default may be overridden via
+ the PASSWD and NOPASSWD tags. This flag is _o_n by
+ default.
+
+ case_insensitive_group
+ If enabled, group names in _s_u_d_o_e_r_s will be matched in a
+ case insensitive manner. This may be necessary when
+ users are stored in LDAP or AD. This flag is _o_n by
+ default.
+
+ case_insensitive_user
+ If enabled, user names in _s_u_d_o_e_r_s will be matched in a
+ case insensitive manner. This may be necessary when
+ groups are stored in LDAP or AD. This flag is _o_n by
+ default.
+
+ closefrom_override
+ If set, the user may use ssuuddoo's --CC option which
+ overrides the default starting point at which ssuuddoo
+ begins closing open file descriptors. This flag is _o_f_f
+ by default.
+
+ compress_io If set, and ssuuddoo is configured to log a command's input
+ or output, the I/O logs will be compressed using zzlliibb.
+ This flag is _o_n by default when ssuuddoo is compiled with
+ zzlliibb support.
+
+ exec_background By default, ssuuddoo runs a command as the foreground
+ process as long as ssuuddoo itself is running in the
+ foreground. When the _e_x_e_c___b_a_c_k_g_r_o_u_n_d flag is enabled
+ and the command is being run in a pty (due to I/O
+ logging or the _u_s_e___p_t_y flag), the command will be run
+ as a background process. Attempts to read from the
+ controlling terminal (or to change terminal settings)
+ will result in the command being suspended with the
+ SIGTTIN signal (or SIGTTOU in the case of terminal
+ settings). If this happens when ssuuddoo is a foreground
+ process, the command will be granted the controlling
+ terminal and resumed in the foreground with no user
+ intervention required. The advantage of initially
+ running the command in the background is that ssuuddoo need
+ not read from the terminal unless the command
+ explicitly requests it. Otherwise, any terminal input
+ must be passed to the command, whether it has required
+ it or not (the kernel buffers terminals so it is not
+ possible to tell whether the command really wants the
+ input). This is different from historic _s_u_d_o behavior
+ or when the command is not being run in a pty.
+
+ For this to work seamlessly, the operating system must
+ support the automatic restarting of system calls.
+ Unfortunately, not all operating systems do this by
+ default, and even those that do may have bugs. For
+ example, macOS fails to restart the ttccggeettaattttrr() and
+ ttccsseettaattttrr() system calls (this is a bug in macOS).
+ Furthermore, because this behavior depends on the
+ command stopping with the SIGTTIN or SIGTTOU signals,
+ programs that catch these signals and suspend
+ themselves with a different signal (usually SIGTOP)
+ will not be automatically foregrounded. Some versions
+ of the linux su(1) command behave this way. This flag
+ is _o_f_f by default.
+
+ This setting is only supported by version 1.8.7 or
+ higher. It has no effect unless I/O logging is enabled
+ or the _u_s_e___p_t_y flag is enabled.
+
+ env_editor If set, vviissuuddoo will use the value of the SUDO_EDITOR,
+ VISUAL or EDITOR environment variables before falling
+ back on the default editor list. Note that this may
+ create a security hole as it allows the user to run any
+ arbitrary command as root without logging. A safer
+ alternative is to place a colon-separated list of
+ editors in the _e_d_i_t_o_r variable. vviissuuddoo will then only
+ use SUDO_EDITOR, VISUAL or EDITOR if they match a value
+ specified in _e_d_i_t_o_r. If the _e_n_v___r_e_s_e_t flag is enabled,
+ the SUDO_EDITOR, VISUAL and/or EDITOR environment
+ variables must be present in the _e_n_v___k_e_e_p list for the
+ _e_n_v___e_d_i_t_o_r flag to function when vviissuuddoo is invoked via
+ ssuuddoo. This flag is _o_f_f by default.
+
+ env_reset If set, ssuuddoo will run the command in a minimal
+ environment containing the TERM, PATH, HOME, MAIL,
+ SHELL, LOGNAME, USER and SUDO_* variables. Any
+ variables in the caller's environment or in the file
+ specified by the _r_e_s_t_r_i_c_t_e_d___e_n_v___f_i_l_e option that match
+ the env_keep and env_check lists are then added,
+ followed by any variables present in the file specified
+ by the _e_n_v___f_i_l_e option (if any). The contents of the
+ env_keep and env_check lists, as modified by global
+ Defaults parameters in _s_u_d_o_e_r_s, are displayed when ssuuddoo
+ is run by root with the --VV option. If the _s_e_c_u_r_e___p_a_t_h
+ option is set, its value will be used for the PATH
+ environment variable. This flag is _o_n by default.
+
+ fast_glob Normally, ssuuddoo uses the glob(3) function to do shell-
+ style globbing when matching path names. However,
+ since it accesses the file system, glob(3) can take a
+ long time to complete for some patterns, especially
+ when the pattern references a network file system that
+ is mounted on demand (auto mounted). The _f_a_s_t___g_l_o_b
+ option causes ssuuddoo to use the fnmatch(3) function,
+ which does not access the file system to do its
+ matching. The disadvantage of _f_a_s_t___g_l_o_b is that it is
+ unable to match relative path names such as _._/_l_s or
+ _._._/_b_i_n_/_l_s. This has security implications when path
+ names that include globbing characters are used with
+ the negation operator, `!', as such rules can be
+ trivially bypassed. As such, this option should not be
+ used when the _s_u_d_o_e_r_s file contains rules that contain
+ negated path names which include globbing characters.
+ This flag is _o_f_f by default.
+
+ fqdn Set this flag if you want to put fully qualified host
+ names in the _s_u_d_o_e_r_s file when the local host name (as
+ returned by the hostname command) does not contain the
+ domain name. In other words, instead of myhost you
+ would use myhost.mydomain.edu. You may still use the
+ short form if you wish (and even mix the two). This
+ option is only effective when the "canonical" host
+ name, as returned by the ggeettaaddddrriinnffoo() or
+ ggeetthhoossttbbyynnaammee() function, is a fully-qualified domain
+ name. This is usually the case when the system is
+ configured to use DNS for host name resolution.
+
+ If the system is configured to use the _/_e_t_c_/_h_o_s_t_s file
+ in preference to DNS, the "canonical" host name may not
+ be fully-qualified. The order that sources are queried
+ for host name resolution is usually specified in the
+ _/_e_t_c_/_n_s_s_w_i_t_c_h_._c_o_n_f, _/_e_t_c_/_n_e_t_s_v_c_._c_o_n_f, _/_e_t_c_/_h_o_s_t_._c_o_n_f,
+ or, in some cases, _/_e_t_c_/_r_e_s_o_l_v_._c_o_n_f file. In the
+ _/_e_t_c_/_h_o_s_t_s file, the first host name of the entry is
+ considered to be the "canonical" name; subsequent names
+ are aliases that are not used by ssuuddooeerrss. For example,
+ the following hosts file line for the machine "xyzzy"
+ has the fully-qualified domain name as the "canonical"
+ host name, and the short version as an alias.
+
+ 192.168.1.1 xyzzy.sudo.ws xyzzy
+
+ If the machine's hosts file entry is not formatted
+ properly, the _f_q_d_n option will not be effective if it
+ is queried before DNS.
+
+ Beware that when using DNS for host name resolution,
+ turning on _f_q_d_n requires ssuuddooeerrss to make DNS lookups
+ which renders ssuuddoo unusable if DNS stops working (for
+ example if the machine is disconnected from the
+ network). Also note that just like with the hosts
+ file, you must use the "canonical" name as DNS knows
+ it. That is, you may not use a host alias (CNAME
+ entry) due to performance issues and the fact that
+ there is no way to get all aliases from DNS.
+
+ This flag is _o_f_f by default.
+
+ ignore_audit_errors
+ Allow commands to be run even if ssuuddooeerrss cannot write
+ to the audit log. If enabled, an audit log write
+ failure is not treated as a fatal error. If disabled,
+ a command may only be run after the audit event is
+ successfully written. This flag is only effective on
+ systems for which ssuuddooeerrss supports audit logging,
+ including FreeBSD, Linux, macOS and Solaris. This flag
+ is _o_n by default.
+
+ ignore_dot If set, ssuuddoo will ignore "." or "" (both denoting
+ current directory) in the PATH environment variable;
+ the PATH itself is not modified. This flag is _o_f_f by
+ default.
+
+ ignore_iolog_errors
+ Allow commands to be run even if ssuuddooeerrss cannot write
+ to the I/O log. If enabled, an I/O log write failure
+ is not treated as a fatal error. If disabled, the
+ command will be terminated if the I/O log cannot be
+ written to. This flag is _o_f_f by default.
+
+ ignore_logfile_errors
+ Allow commands to be run even if ssuuddooeerrss cannot write
+ to the log file. If enabled, a log file write failure
+ is not treated as a fatal error. If disabled, a
+ command may only be run after the log file entry is
+ successfully written. This flag only has an effect
+ when ssuuddooeerrss is configured to use file-based logging
+ via the _l_o_g_f_i_l_e option. This flag is _o_n by default.
+
+ ignore_local_sudoers
+ If set via LDAP, parsing of _/_e_t_c_/_s_u_d_o_e_r_s will be
+ skipped. This is intended for Enterprises that wish to
+ prevent the usage of local sudoers files so that only
+ LDAP is used. This thwarts the efforts of rogue
+ operators who would attempt to add roles to
+ _/_e_t_c_/_s_u_d_o_e_r_s. When this option is present,
+ _/_e_t_c_/_s_u_d_o_e_r_s does not even need to exist. Since this
+ option tells ssuuddoo how to behave when no specific LDAP
+ entries have been matched, this sudoOption is only
+ meaningful for the cn=defaults section. This flag is
+ _o_f_f by default.
+
+ ignore_unknown_defaults
+ If set, ssuuddoo will not produce a warning if it
+ encounters an unknown Defaults entry in the _s_u_d_o_e_r_s
+ file or an unknown sudoOption in LDAP. This flag is
+ _o_f_f by default.
+
+ insults If set, ssuuddoo will insult users when they enter an
+ incorrect password. This flag is _o_f_f by default.
+
+ log_host If set, the host name will be logged in the (non-
+ syslog) ssuuddoo log file. This flag is _o_f_f by default.
+
+ log_input If set, ssuuddoo will run the command in a pseudo-tty and
+ log all user input. If the standard input is not
+ connected to the user's tty, due to I/O redirection or
+ because the command is part of a pipeline, that input
+ is also captured and stored in a separate log file.
+ Anything sent to the standard input will be consumed,
+ regardless of whether or not the command run via ssuuddoo
+ is actually reading the standard input. This may have
+ unexpected results when using ssuuddoo in a shell script
+ that expects to process the standard input. For more
+ information about I/O logging, see the _I_/_O _L_O_G _F_I_L_E_S
+ section. This flag is _o_f_f by default.
+
+ log_output If set, ssuuddoo will run the command in a pseudo-tty and
+ log all output that is sent to the screen, similar to
+ the script(1) command. For more information about I/O
+ logging, see the _I_/_O _L_O_G _F_I_L_E_S section. This flag is
+ _o_f_f by default.
+
+ log_year If set, the four-digit year will be logged in the (non-
+ syslog) ssuuddoo log file. This flag is _o_f_f by default.
+
+ long_otp_prompt When validating with a One Time Password (OTP) scheme
+ such as SS//KKeeyy or OOPPIIEE, a two-line prompt is used to
+ make it easier to cut and paste the challenge to a
+ local window. It's not as pretty as the default but
+ some people find it more convenient. This flag is _o_f_f
+ by default.
+
+ mail_all_cmnds Send mail to the _m_a_i_l_t_o user every time a user attempts
+ to run a command via ssuuddoo (this includes ssuuddooeeddiitt). No
+ mail will be sent if the user runs ssuuddoo with the --ll or
+ --vv option unless there is an authentication error and
+ the _m_a_i_l___b_a_d_p_a_s_s flag is also set. This flag is _o_f_f by
+ default.
+
+ mail_always Send mail to the _m_a_i_l_t_o user every time a user runs
+ ssuuddoo. This flag is _o_f_f by default.
+
+ mail_badpass Send mail to the _m_a_i_l_t_o user if the user running ssuuddoo
+ does not enter the correct password. If the command
+ the user is attempting to run is not permitted by
+ ssuuddooeerrss and one of the _m_a_i_l___a_l_l___c_m_n_d_s, _m_a_i_l___a_l_w_a_y_s,
+ _m_a_i_l___n_o___h_o_s_t, _m_a_i_l___n_o___p_e_r_m_s or _m_a_i_l___n_o___u_s_e_r flags are
+ set, this flag will have no effect. This flag is _o_f_f
+ by default.
+
+ mail_no_host If set, mail will be sent to the _m_a_i_l_t_o user if the
+ invoking user exists in the _s_u_d_o_e_r_s file, but is not
+ allowed to run commands on the current host. This flag
+ is _o_f_f by default.
+
+ mail_no_perms If set, mail will be sent to the _m_a_i_l_t_o user if the
+ invoking user is allowed to use ssuuddoo but the command
+ they are trying is not listed in their _s_u_d_o_e_r_s file
+ entry or is explicitly denied. This flag is _o_f_f by
+ default.
+
+ mail_no_user If set, mail will be sent to the _m_a_i_l_t_o user if the
+ invoking user is not in the _s_u_d_o_e_r_s file. This flag is
+ _o_n by default.
+
+ match_group_by_gid
+ By default, ssuuddooeerrss will look up each group the user is
+ a member of by group ID to determine the group name
+ (this is only done once). The resulting list of the
+ user's group names is used when matching groups listed
+ in the _s_u_d_o_e_r_s file. This works well on systems where
+ the number of groups listed in the _s_u_d_o_e_r_s file is
+ larger than the number of groups a typical user belongs
+ to. On systems where group lookups are slow, where
+ users may belong to a large number of groups, and where
+ the number of groups listed in the _s_u_d_o_e_r_s file is
+ relatively small, it may be prohibitively expensive and
+ running commands via ssuuddoo may take longer than normal.
+ On such systems it may be faster to use the
+ _m_a_t_c_h___g_r_o_u_p___b_y___g_i_d flag to avoid resolving the user's
+ group IDs to group names. In this case, ssuuddooeerrss must
+ look up any group name listed in the _s_u_d_o_e_r_s file and
+ use the group ID instead of the group name when
+ determining whether the user is a member of the group.
+
+ Note that if _m_a_t_c_h___g_r_o_u_p___b_y___g_i_d is enabled, group
+ database lookups performed by ssuuddooeerrss will be keyed by
+ group name as opposed to group ID. On systems where
+ there are multiple sources for the group database, it
+ is possible to have conflicting group names or group
+ IDs in the local _/_e_t_c_/_g_r_o_u_p file and the remote group
+ database. On such systems, enabling or disabling
+ _m_a_t_c_h___g_r_o_u_p___b_y___g_i_d can be used to choose whether group
+ database queries are performed by name (enabled) or ID
+ (disabled), which may aid in working around group entry
+ conflicts.
+
+ The _m_a_t_c_h___g_r_o_u_p___b_y___g_i_d flag has no effect when _s_u_d_o_e_r_s
+ data is stored in LDAP. This flag is _o_f_f by default.
+
+ This setting is only supported by version 1.8.18 or
+ higher.
+
+ netgroup_tuple If set, netgroup lookups will be performed using the
+ full netgroup tuple: host name, user name and domain
+ (if one is set). Historically, ssuuddoo only matched the
+ user name and domain for netgroups used in a User_List
+ and only matched the host name and domain for netgroups
+ used in a Host_List. This flag is _o_f_f by default.
+
+ noexec If set, all commands run via ssuuddoo will behave as if the
+ NOEXEC tag has been set, unless overridden by an EXEC
+ tag. See the description of _E_X_E_C _a_n_d _N_O_E_X_E_C above as
+ well as the _P_r_e_v_e_n_t_i_n_g _s_h_e_l_l _e_s_c_a_p_e_s section at the end
+ of this manual. This flag is _o_f_f by default.
+
+ pam_session On systems that use PAM for authentication, ssuuddoo will
+ create a new PAM session for the command to be run in.
+ Disabling _p_a_m___s_e_s_s_i_o_n may be needed on older PAM
+ implementations or on operating systems where opening a
+ PAM session changes the utmp or wtmp files. If PAM
+ session support is disabled, resource limits may not be
+ updated for the command being run. If _p_a_m___s_e_s_s_i_o_n,
+ _p_a_m___s_e_t_c_r_e_d, and _u_s_e___p_t_y are disabled and I/O logging
+ has not been configured, ssuuddoo will execute the command
+ directly instead of running it as a child process.
+ This flag is _o_n by default.
+
+ This setting is only supported by version 1.8.7 or
+ higher.
+
+ pam_setcred On systems that use PAM for authentication, ssuuddoo will
+ attempt to establish credentials for the target user by
+ default, if supported by the underlying authentication
+ system. One example of a credential is a Kerberos
+ ticket. If _p_a_m___s_e_s_s_i_o_n, _p_a_m___s_e_t_c_r_e_d, and _u_s_e___p_t_y are
+ disabled and I/O logging has not been configured, ssuuddoo
+ will execute the command directly instead of running it
+ as a child process. This flag is _o_n by default.
+
+ This setting is only supported by version 1.8.8 or
+ higher.
+
+ passprompt_override
+ If set, the prompt specified by _p_a_s_s_p_r_o_m_p_t or the
+ SUDO_PROMPT environment variable will always be used
+ and will replace the prompt provided by a PAM module or
+ other authentication method. This flag is _o_f_f by
+ default.
+
+ path_info Normally, ssuuddoo will tell the user when a command could
+ not be found in their PATH environment variable. Some
+ sites may wish to disable this as it could be used to
+ gather information on the location of executables that
+ the normal user does not have access to. The
+ disadvantage is that if the executable is simply not in
+ the user's PATH, ssuuddoo will tell the user that they are
+ not allowed to run it, which can be confusing. This
+ flag is _o_n by default.
+
+ preserve_groups By default, ssuuddoo will initialize the group vector to
+ the list of groups the target user is in. When
+ _p_r_e_s_e_r_v_e___g_r_o_u_p_s is set, the user's existing group
+ vector is left unaltered. The real and effective group
+ IDs, however, are still set to match the target user.
+ This flag is _o_f_f by default.
+
+ pwfeedback By default, ssuuddoo reads the password like most other
+ Unix programs, by turning off echo until the user hits
+ the return (or enter) key. Some users become confused
+ by this as it appears to them that ssuuddoo has hung at
+ this point. When _p_w_f_e_e_d_b_a_c_k is set, ssuuddoo will provide
+ visual feedback when the user presses a key. Note that
+ this does have a security impact as an onlooker may be
+ able to determine the length of the password being
+ entered. This flag is _o_f_f by default.
+
+ requiretty If set, ssuuddoo will only run when the user is logged in
+ to a real tty. When this flag is set, ssuuddoo can only be
+ run from a login session and not via other means such
+ as cron(1m) or cgi-bin scripts. This flag is _o_f_f by
+ default.
+
+ root_sudo If set, root is allowed to run ssuuddoo too. Disabling
+ this prevents users from "chaining" ssuuddoo commands to
+ get a root shell by doing something like "sudo sudo
+ /bin/sh". Note, however, that turning off _r_o_o_t___s_u_d_o
+ will also prevent root from running ssuuddooeeddiitt.
+ Disabling _r_o_o_t___s_u_d_o provides no real additional
+ security; it exists purely for historical reasons.
+ This flag is _o_n by default.
+
+ rootpw If set, ssuuddoo will prompt for the root password instead
+ of the password of the invoking user when running a
+ command or editing a file. This flag is _o_f_f by
+ default.
+
+ runaspw If set, ssuuddoo will prompt for the password of the user
+ defined by the _r_u_n_a_s___d_e_f_a_u_l_t option (defaults to root)
+ instead of the password of the invoking user when
+ running a command or editing a file. This flag is _o_f_f
+ by default.
+
+ set_home If enabled and ssuuddoo is invoked with the --ss option the
+ HOME environment variable will be set to the home
+ directory of the target user (which is root unless the
+ --uu option is used). This effectively makes the --ss
+ option imply --HH. Note that HOME is already set when
+ the _e_n_v___r_e_s_e_t option is enabled, so _s_e_t___h_o_m_e is only
+ effective for configurations where either _e_n_v___r_e_s_e_t is
+ disabled or HOME is present in the _e_n_v___k_e_e_p list. This
+ flag is _o_f_f by default.
+
+ set_logname Normally, ssuuddoo will set the LOGNAME and USER
+ environment variables to the name of the target user
+ (usually root unless the --uu option is given). However,
+ since some programs (including the RCS revision control
+ system) use LOGNAME to determine the real identity of
+ the user, it may be desirable to change this behavior.
+ This can be done by negating the set_logname option.
+ Note that _s_e_t___l_o_g_n_a_m_e will have no effect if the
+ _e_n_v___r_e_s_e_t option has not been disabled and the _e_n_v___k_e_e_p
+ list contains LOGNAME or USER. This flag is _o_n by
+ default.
+
+ set_utmp When enabled, ssuuddoo will create an entry in the utmp (or
+ utmpx) file when a pseudo-tty is allocated. A pseudo-
+ tty is allocated by ssuuddoo when the _l_o_g___i_n_p_u_t, _l_o_g___o_u_t_p_u_t
+ or _u_s_e___p_t_y flags are enabled. By default, the new
+ entry will be a copy of the user's existing utmp entry
+ (if any), with the tty, time, type and pid fields
+ updated. This flag is _o_n by default.
+
+ setenv Allow the user to disable the _e_n_v___r_e_s_e_t option from the
+ command line via the --EE option. Additionally,
+ environment variables set via the command line are not
+ subject to the restrictions imposed by _e_n_v___c_h_e_c_k,
+ _e_n_v___d_e_l_e_t_e, or _e_n_v___k_e_e_p. As such, only trusted users
+ should be allowed to set variables in this manner.
+ This flag is _o_f_f by default.
+
+ shell_noargs If set and ssuuddoo is invoked with no arguments it acts as
+ if the --ss option had been given. That is, it runs a
+ shell as root (the shell is determined by the SHELL
+ environment variable if it is set, falling back on the
+ shell listed in the invoking user's /etc/passwd entry
+ if not). This flag is _o_f_f by default.
+
+ stay_setuid Normally, when ssuuddoo executes a command the real and
+ effective UIDs are set to the target user (root by
+ default). This option changes that behavior such that
+ the real UID is left as the invoking user's UID. In
+ other words, this makes ssuuddoo act as a setuid wrapper.
+ This can be useful on systems that disable some
+ potentially dangerous functionality when a program is
+ run setuid. This option is only effective on systems
+ that support either the setreuid(2) or setresuid(2)
+ system call. This flag is _o_f_f by default.
+
+ sudoedit_checkdir
+ If set, ssuuddooeeddiitt will check all directory components of
+ the path to be edited for writability by the invoking
+ user. Symbolic links will not be followed in writable
+ directories and ssuuddooeeddiitt will refuse to edit a file
+ located in a writable directory. These restrictions
+ are not enforced when ssuuddooeeddiitt is run by root. On some
+ systems, if all directory components of the path to be
+ edited are not readable by the target user, ssuuddooeeddiitt
+ will be unable to edit the file. This flag is _o_n by
+ default.
+
+ This setting was first introduced in version 1.8.15 but
+ initially suffered from a race condition. The check
+ for symbolic links in writable intermediate directories
+ was added in version 1.8.16.
+
+ sudoedit_follow By default, ssuuddooeeddiitt will not follow symbolic links
+ when opening files. The _s_u_d_o_e_d_i_t___f_o_l_l_o_w option can be
+ enabled to allow ssuuddooeeddiitt to open symbolic links. It
+ may be overridden on a per-command basis by the _F_O_L_L_O_W
+ and _N_O_F_O_L_L_O_W tags. This flag is _o_f_f by default.
+
+ This setting is only supported by version 1.8.15 or
+ higher.
+
+ syslog_pid When logging via syslog(3), include the process ID in
+ the log entry. This flag is _o_f_f by default.
+
+ This setting is only supported by version 1.8.21 or
+ higher.
+
+ targetpw If set, ssuuddoo will prompt for the password of the user
+ specified by the --uu option (defaults to root) instead
+ of the password of the invoking user when running a
+ command or editing a file. Note that this flag
+ precludes the use of a uid not listed in the passwd
+ database as an argument to the --uu option. This flag is
+ _o_f_f by default.
+
+ tty_tickets If set, users must authenticate on a per-tty basis.
+ With this flag enabled, ssuuddoo will use a separate record
+ in the time stamp file for each terminal. If disabled,
+ a single record is used for all login sessions.
+
+ This option has been superseded by the _t_i_m_e_s_t_a_m_p___t_y_p_e
+ option.
+
+ umask_override If set, ssuuddoo will set the umask as specified in the
+ _s_u_d_o_e_r_s file without modification. This makes it
+ possible to specify a umask in the _s_u_d_o_e_r_s file that is
+ more permissive than the user's own umask and matches
+ historical behavior. If _u_m_a_s_k___o_v_e_r_r_i_d_e is not set,
+ ssuuddoo will set the umask to be the union of the user's
+ umask and what is specified in _s_u_d_o_e_r_s. This flag is
+ _o_f_f by default.
+
+ use_loginclass If set, ssuuddoo will apply the defaults specified for the
+ target user's login class if one exists. Only
+ available if ssuuddoo is configured with the
+ --with-logincap option. This flag is _o_f_f by default.
+
+ use_netgroups If set, netgroups (prefixed with `+'), may be used in
+ place of a user or host. For LDAP-based sudoers,
+ netgroup support requires an expensive sub-string match
+ on the server unless the NNEETTGGRROOUUPP__BBAASSEE directive is
+ present in the _/_e_t_c_/_l_d_a_p_._c_o_n_f file. If netgroups are
+ not needed, this option can be disabled to reduce the
+ load on the LDAP server. This flag is _o_n by default.
+
+ use_pty If set, and ssuuddoo is running in a terminal, the command
+ will be run in a pseudo-pty (even if no I/O logging is
+ being done). If the ssuuddoo process is not attached to a
+ terminal, _u_s_e___p_t_y has no effect.
+
+ A malicious program run under ssuuddoo may be capable of
+ injecting commands into the user's terminal or running
+ a background process that retains access to the user's
+ terminal device even after the main program has
+ finished executing. By running the command in a
+ separate pseudo-pty, this attack is no longer possible.
+ This flag is _o_f_f by default.
+
+ user_command_timeouts
+ If set, the user may specify a timeout on the command
+ line. If the timeout expires before the command has
+ exited, the command will be terminated. If a timeout
+ is specified both in the _s_u_d_o_e_r_s file and on the
+ command line, the smaller of the two timeouts will be
+ used. See the Timeout_Spec section for a description
+ of the timeout syntax. This flag is _o_f_f by default.
+
+ This setting is only supported by version 1.8.20 or
+ higher.
+
+ utmp_runas If set, ssuuddoo will store the name of the runas user when
+ updating the utmp (or utmpx) file. By default, ssuuddoo
+ stores the name of the invoking user. This flag is _o_f_f
+ by default.
+
+ visiblepw By default, ssuuddoo will refuse to run if the user must
+ enter a password but it is not possible to disable echo
+ on the terminal. If the _v_i_s_i_b_l_e_p_w flag is set, ssuuddoo
+ will prompt for a password even when it would be
+ visible on the screen. This makes it possible to run
+ things like "ssh somehost sudo ls" since by default,
+ ssh(1) does not allocate a tty when running a command.
+ This flag is _o_f_f by default.
+
+ IInntteeggeerrss:
+
+ closefrom Before it executes a command, ssuuddoo will close all open
+ file descriptors other than standard input, standard
+ output and standard error (ie: file descriptors 0-2).
+ The _c_l_o_s_e_f_r_o_m option can be used to specify a different
+ file descriptor at which to start closing. The default
+ is 3.
+
+ command_timeout The maximum amount of time a command is allowed to run
+ before it is terminated. See the Timeout_Spec section
+ for a description of the timeout syntax.
+
+ This setting is only supported by version 1.8.20 or
+ higher.
+
+ maxseq The maximum sequence number that will be substituted
+ for the "%{seq}" escape in the I/O log file (see the
+ _i_o_l_o_g___d_i_r description below for more information).
+ While the value substituted for "%{seq}" is in base 36,
+ _m_a_x_s_e_q itself should be expressed in decimal. Values
+ larger than 2176782336 (which corresponds to the base
+ 36 sequence number "ZZZZZZ") will be silently truncated
+ to 2176782336. The default value is 2176782336.
+
+ Once the local sequence number reaches the value of
+ _m_a_x_s_e_q, it will "roll over" to zero, after which
+ ssuuddooeerrss will truncate and re-use any existing I/O log
+ path names.
+
+ This setting is only supported by version 1.8.7 or
+ higher.
+
+ passwd_tries The number of tries a user gets to enter his/her
+ password before ssuuddoo logs the failure and exits. The
+ default is 3.
+
+ syslog_maxlen On many systems, syslog(3) has a relatively small log
+ buffer. IETF RFC 5424 states that syslog servers must
+ support messages of at least 480 bytes and should
+ support messages up to 2048 bytes. By default, ssuuddooeerrss
+ creates log messages up to 980 bytes which corresponds
+ to the historic BSD syslog implementation which used a
+ 1024 byte buffer to store the message, date, hostname
+ and program name. To prevent syslog messages from
+ being truncated, ssuuddooeerrss will split up log messages
+ that are larger than _s_y_s_l_o_g___m_a_x_l_e_n bytes. When a
+ message is split, additional parts will include the
+ string "(command continued)" after the user name and
+ before the continued command line arguments.
+
+ This setting is only supported by version 1.8.19 or
+ higher.
+
+ IInntteeggeerrss tthhaatt ccaann bbee uusseedd iinn aa bboooolleeaann ccoonntteexxtt:
+
+ loglinelen Number of characters per line for the file log. This
+ value is used to decide when to wrap lines for nicer
+ log files. This has no effect on the syslog log file,
+ only the file log. The default is 80 (use 0 or negate
+ the option to disable word wrap).
+
+ passwd_timeout Number of minutes before the ssuuddoo password prompt times
+ out, or 0 for no timeout. The timeout may include a
+ fractional component if minute granularity is
+ insufficient, for example 2.5. The default is 5.
+
+ timestamp_timeout
+ Number of minutes that can elapse before ssuuddoo will ask
+ for a passwd again. The timeout may include a
+ fractional component if minute granularity is
+ insufficient, for example 2.5. The default is 5. Set
+ this to 0 to always prompt for a password. If set to a
+ value less than 0 the user's time stamp will not expire
+ until the system is rebooted. This can be used to
+ allow users to create or delete their own time stamps
+ via "sudo -v" and "sudo -k" respectively.
+
+ umask Umask to use when running the command. Negate this
+ option or set it to 0777 to preserve the user's umask.
+ The actual umask that is used will be the union of the
+ user's umask and the value of the _u_m_a_s_k option, which
+ defaults to 0022. This guarantees that ssuuddoo never
+ lowers the umask when running a command. Note: on
+ systems that use PAM, the default PAM configuration may
+ specify its own umask which will override the value set
+ in _s_u_d_o_e_r_s.
+
+ SSttrriinnggss:
+
+ authfail_message Message that is displayed after a user fails to
+ authenticate. The message may include the `%d' escape
+ which will expand to the number of failed password
+ attempts. If set, it overrides the default message, %d
+ incorrect password attempt(s).
+
+ badpass_message Message that is displayed if a user enters an incorrect
+ password. The default is Sorry, try again. unless
+ insults are enabled.
+
+ editor A colon (`:') separated list of editors path names used
+ by ssuuddooeeddiitt and vviissuuddoo. For ssuuddooeeddiitt, this list is
+ used to find an editor when none of the SUDO_EDITOR,
+ VISUAL or EDITOR environment variables are set to an
+ editor that exists and is executable. For vviissuuddoo, it
+ is used as a white list of allowed editors; vviissuuddoo will
+ choose the editor that matches the user's SUDO_EDITOR,
+ VISUAL or EDITOR environment variable if possible, or
+ the first editor in the list that exists and is
+ executable if not. Unless invoked as ssuuddooeeddiitt, ssuuddoo
+ does not preserve the SUDO_EDITOR, VISUAL and EDITOR
+ environment variables by default, even when the
+ _e_n_v___r_e_s_e_t option is enabled. The default is _v_i.
+
+ iolog_dir The top-level directory to use when constructing the
+ path name for the input/output log directory. Only
+ used if the _l_o_g___i_n_p_u_t or _l_o_g___o_u_t_p_u_t options are enabled
+ or when the LOG_INPUT or LOG_OUTPUT tags are present
+ for a command. The session sequence number, if any, is
+ stored in the directory. The default is
+ _/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o.
+
+ The following percent (`%') escape sequences are
+ supported:
+
+ %{seq}
+ expanded to a monotonically increasing base-36
+ sequence number, such as 0100A5, where every two
+ digits are used to form a new directory, e.g.,
+ _0_1_/_0_0_/_A_5
+
+ %{user}
+ expanded to the invoking user's login name
+
+ %{group}
+ expanded to the name of the invoking user's real
+ group ID
+
+ %{runas_user}
+ expanded to the login name of the user the
+ command will be run as (e.g., root)
+
+ %{runas_group}
+ expanded to the group name of the user the
+ command will be run as (e.g., wheel)
+
+ %{hostname}
+ expanded to the local host name without the
+ domain name
+
+ %{command}
+ expanded to the base name of the command being
+ run
+
+ In addition, any escape sequences supported by the
+ system's strftime(3) function will be expanded.
+
+ To include a literal `%' character, the string `%%'
+ should be used.
+
+ iolog_file The path name, relative to _i_o_l_o_g___d_i_r, in which to store
+ input/output logs when the _l_o_g___i_n_p_u_t or _l_o_g___o_u_t_p_u_t
+ options are enabled or when the LOG_INPUT or LOG_OUTPUT
+ tags are present for a command. Note that _i_o_l_o_g___f_i_l_e
+ may contain directory components. The default is
+ "%{seq}".
+
+ See the _i_o_l_o_g___d_i_r option above for a list of supported
+ percent (`%') escape sequences.
+
+ In addition to the escape sequences, path names that
+ end in six or more Xs will have the Xs replaced with a
+ unique combination of digits and letters, similar to
+ the mktemp(3) function.
+
+ If the path created by concatenating _i_o_l_o_g___d_i_r and
+ _i_o_l_o_g___f_i_l_e already exists, the existing I/O log file
+ will be truncated and overwritten unless _i_o_l_o_g___f_i_l_e
+ ends in six or more Xs.
+
+ iolog_flush If set, ssuuddoo will flush I/O log data to disk after each
+ write instead of buffering it. This makes it possible
+ to view the logs in real-time as the program is
+ executing but may significantly reduce the
+ effectiveness of I/O log compression. This flag is _o_f_f
+ by default.
+
+ This setting is only supported by version 1.8.20 or
+ higher.
+
+ iolog_group The group name to look up when setting the group ID on
+ new I/O log files and directories. If _i_o_l_o_g___g_r_o_u_p is
+ not set, the primary group ID of the user specified by
+ _i_o_l_o_g___u_s_e_r is used. If neither _i_o_l_o_g___g_r_o_u_p nor
+ _i_o_l_o_g___u_s_e_r are set, I/O log files and directories are
+ created with group ID 0.
+
+ This setting is only supported by version 1.8.19 or
+ higher.
+
+ iolog_mode The file mode to use when creating I/O log files. Mode
+ bits for read and write permissions for owner, group or
+ other are honored, everything else is ignored. The
+ file permissions will always include the owner read and
+ write bits, even if they are not present in the
+ specified mode. When creating I/O log directories,
+ search (execute) bits are added to match the read and
+ write bits specified by _i_o_l_o_g___m_o_d_e. Defaults to 0600
+ (read and write by user only).
+
+ This setting is only supported by version 1.8.19 or
+ higher.
+
+ iolog_user The user name to look up when setting the user and
+ group IDs on new I/O log files and directories. If
+ _i_o_l_o_g___g_r_o_u_p is set, it will be used instead of the
+ user's primary group ID. By default, I/O log files and
+ directories are created with user and group ID 0.
+
+ This setting can be useful when the I/O logs are stored
+ on a Network File System (NFS) share. Having a
+ dedicated user own the I/O log files means that ssuuddooeerrss
+ does not write to the log files as user ID 0, which is
+ usually not permitted by NFS.
+
+ This setting is only supported by version 1.8.19 or
+ higher.
+
+ lecture_status_dir
+ The directory in which ssuuddoo stores per-user lecture
+ status files. Once a user has received the lecture, a
+ zero-length file is created in this directory so that
+ ssuuddoo will not lecture the user again. This directory
+ should _n_o_t be cleared when the system reboots. The
+ default is _/_v_a_r_/_a_d_m_/_s_u_d_o_/_l_e_c_t_u_r_e_d.
+
+ limitprivs The default Solaris limit privileges to use when
+ constructing a new privilege set for a command. This
+ bounds all privileges of the executing process. The
+ default limit privileges may be overridden on a per-
+ command basis in _s_u_d_o_e_r_s. This option is only
+ available if ssuuddooeerrss is built on Solaris 10 or higher.
+
+ mailsub Subject of the mail sent to the _m_a_i_l_t_o user. The
+ escape %h will expand to the host name of the machine.
+ Default is "*** SECURITY information for %h ***".
+
+ noexec_file As of ssuuddoo version 1.8.1 this option is no longer
+ supported. The path to the noexec file should now be
+ set in the sudo.conf(4) file.
+
+ pam_login_service
+ On systems that use PAM for authentication, this is the
+ service name used when the --ii option is specified. The
+ default value is "sudo". See the description of
+ _p_a_m___s_e_r_v_i_c_e for more information.
+
+ This setting is only supported by version 1.8.8 or
+ higher.
+
+ pam_service On systems that use PAM for authentication, the service
+ name specifies the PAM policy to apply. This usually
+ corresponds to an entry in the _p_a_m_._c_o_n_f file or a file
+ in the _/_e_t_c_/_p_a_m_._d directory. The default value is
+ "sudo".
+
+ This setting is only supported by version 1.8.8 or
+ higher.
+
+ passprompt The default prompt to use when asking for a password;
+ can be overridden via the --pp option or the SUDO_PROMPT
+ environment variable. The following percent (`%')
+ escape sequences are supported:
+
+ %H expanded to the local host name including the
+ domain name (only if the machine's host name is
+ fully qualified or the _f_q_d_n option is set)
+
+ %h expanded to the local host name without the
+ domain name
+
+ %p expanded to the user whose password is being
+ asked for (respects the _r_o_o_t_p_w, _t_a_r_g_e_t_p_w and
+ _r_u_n_a_s_p_w flags in _s_u_d_o_e_r_s)
+
+ %U expanded to the login name of the user the
+ command will be run as (defaults to root)
+
+ %u expanded to the invoking user's login name
+
+ %% two consecutive % characters are collapsed into a
+ single % character
+
+ On systems that use PAM for authentication, _p_a_s_s_p_r_o_m_p_t
+ will only be used if the prompt provided by the PAM
+ module matches the string "Password: " or "username's
+ Password: ". This ensures that the _p_a_s_s_p_r_o_m_p_t setting
+ does not interfere with challenge-response style
+ authentication. The _p_a_s_s_p_r_o_m_p_t___o_v_e_r_r_i_d_e flag can be
+ used to change this behavior.
+
+ The default value is "Password: ".
+
+ privs The default Solaris privileges to use when constructing
+ a new privilege set for a command. This is passed to
+ the executing process via the inherited privilege set,
+ but is bounded by the limit privileges. If the _p_r_i_v_s
+ option is specified but the _l_i_m_i_t_p_r_i_v_s option is not,
+ the limit privileges of the executing process is set to
+ _p_r_i_v_s. The default privileges may be overridden on a
+ per-command basis in _s_u_d_o_e_r_s. This option is only
+ available if ssuuddooeerrss is built on Solaris 10 or higher.
+
+ role The default SELinux role to use when constructing a new
+ security context to run the command. The default role
+ may be overridden on a per-command basis in the _s_u_d_o_e_r_s
+ file or via command line options. This option is only
+ available when ssuuddoo is built with SELinux support.
+
+ runas_default The default user to run commands as if the --uu option is
+ not specified on the command line. This defaults to
+ root.
+
+ sudoers_locale Locale to use when parsing the sudoers file, logging
+ commands, and sending email. Note that changing the
+ locale may affect how sudoers is interpreted. Defaults
+ to "C".
+
+ timestamp_type ssuuddooeerrss uses per-user time stamp files for credential
+ caching. The _t_i_m_e_s_t_a_m_p___t_y_p_e option can be used to
+ specify the type of time stamp record used. It has the
+ following possible values:
+
+ global A single time stamp record is used for all of a
+ user's login sessions, regardless of the
+ terminal or parent process ID. An additional
+ record is used to serialize password prompts
+ when ssuuddoo is used multiple times in a pipeline,
+ but this does not affect authentication.
+
+ ppid A single time stamp record is used for all
+ processes with the same parent process ID
+ (usually the shell). Commands run from the
+ same shell (or other common parent process)
+ will not require a password for
+ _t_i_m_e_s_t_a_m_p___t_i_m_e_o_u_t minutes (5 by default).
+ Commands run via ssuuddoo with a different parent
+ process ID, for example from a shell script,
+ will be authenticated separately.
+
+ tty One time stamp record is used for each
+ terminal, which means that a user's login
+ sessions are authenticated separately. If no
+ terminal is present, the behavior is the same
+ as _p_p_i_d. Commands run from the same terminal
+ will not require a password for
+ _t_i_m_e_s_t_a_m_p___t_i_m_e_o_u_t minutes (5 by default).
+
+ kernel The time stamp is stored in the kernel as an
+ attribute of the terminal device. If no
+ terminal is present, the behavior is the same
+ as _p_p_i_d. Negative _t_i_m_e_s_t_a_m_p___t_i_m_e_o_u_t values are
+ not supported and positive values are limited
+ to a maximum of 60 minutes. This is currently
+ only supported on OpenBSD.
+
+ The default value is _t_t_y.
+
+ This setting is only supported by version 1.8.21 or
+ higher.
+
+ timestampdir The directory in which ssuuddoo stores its time stamp
+ files. This directory should be cleared when the
+ system reboots. The default is _/_v_a_r_/_r_u_n_/_s_u_d_o_/_t_s.
+
+ timestampowner The owner of the lecture status directory, time stamp
+ directory and all files stored therein. The default is
+ root.
+
+ type The default SELinux type to use when constructing a new
+ security context to run the command. The default type
+ may be overridden on a per-command basis in the _s_u_d_o_e_r_s
+ file or via command line options. This option is only
+ available when ssuuddoo is built with SELinux support.
+
+ SSttrriinnggss tthhaatt ccaann bbee uusseedd iinn aa bboooolleeaann ccoonntteexxtt:
+
+ env_file The _e_n_v___f_i_l_e option specifies the fully qualified path to a
+ file containing variables to be set in the environment of
+ the program being run. Entries in this file should either
+ be of the form "VARIABLE=value" or "export VARIABLE=value".
+ The value may optionally be surrounded by single or double
+ quotes. Variables in this file are only added if the
+ variable does not already exist in the environment. This
+ file is considered to be part of the security policy, its
+ contents are not subject to other ssuuddoo environment
+ restrictions such as _e_n_v___k_e_e_p and _e_n_v___c_h_e_c_k.
+
+ exempt_group Users in this group are exempt from password and PATH
+ requirements. The group name specified should not include
+ a % prefix. This is not set by default.
+
+ fdexec Determines whether ssuuddoo will execute a command by its path
+ or by an open file descriptor. It has the following
+ possible values:
+
+ always Always execute by file descriptor.
+
+ never Never execute by file descriptor.
+
+ digest_only
+ Only execute by file descriptor if the command has
+ an associated digest in the _s_u_d_o_e_r_s file.
+
+ The default value is _d_i_g_e_s_t___o_n_l_y. This avoids a time of
+ check versus time of use race condition when the command is
+ located in a directory writable by the invoking user.
+
+ Note that _f_d_e_x_e_c will change the first element of the
+ argument vector for scripts ($0 in the shell) due to the
+ way the kernel runs script interpreters. Instead of being
+ a normal path, it will refer to a file descriptor. For
+ example, _/_d_e_v_/_f_d_/_4 on Solaris and _/_p_r_o_c_/_s_e_l_f_/_f_d_/_4 on Linux.
+ A workaround is to use the SUDO_COMMAND environment
+ variable instead.
+
+ The _f_d_e_x_e_c setting is only used when the command is matched
+ by path name. It has no effect if the command is matched
+ by the built-in AALLLL alias.
+
+ This setting is only supported by version 1.8.20 or higher.
+ If the operating system does not support the fexecve(2)
+ system call, this setting has no effect.
+
+ group_plugin A string containing a ssuuddooeerrss group plugin with optional
+ arguments. The string should consist of the plugin path,
+ either fully-qualified or relative to the
+ _/_u_s_r_/_l_o_c_a_l_/_l_i_b_e_x_e_c_/_s_u_d_o directory, followed by any
+ configuration arguments the plugin requires. These
+ arguments (if any) will be passed to the plugin's
+ initialization function. If arguments are present, the
+ string must be enclosed in double quotes ("").
+
+ For more information see _G_R_O_U_P _P_R_O_V_I_D_E_R _P_L_U_G_I_N_S.
+
+ lecture This option controls when a short lecture will be printed
+ along with the password prompt. It has the following
+ possible values:
+
+ always Always lecture the user.
+
+ never Never lecture the user.
+
+ once Only lecture the user the first time they run ssuuddoo.
+
+ If no value is specified, a value of _o_n_c_e is implied.
+ Negating the option results in a value of _n_e_v_e_r being used.
+ The default value is _o_n_c_e.
+
+ lecture_file Path to a file containing an alternate ssuuddoo lecture that
+ will be used in place of the standard lecture if the named
+ file exists. By default, ssuuddoo uses a built-in lecture.
+
+ listpw This option controls when a password will be required when
+ a user runs ssuuddoo with the --ll option. It has the following
+ possible values:
+
+ all All the user's _s_u_d_o_e_r_s file entries for the
+ current host must have the NOPASSWD flag set to
+ avoid entering a password.
+
+ always The user must always enter a password to use the
+ --ll option.
+
+ any At least one of the user's _s_u_d_o_e_r_s file entries
+ for the current host must have the NOPASSWD flag
+ set to avoid entering a password.
+
+ never The user need never enter a password to use the
+ --ll option.
+
+ If no value is specified, a value of _a_n_y is implied.
+ Negating the option results in a value of _n_e_v_e_r being used.
+ The default value is _a_n_y.
+
+ logfile Path to the ssuuddoo log file (not the syslog log file).
+ Setting a path turns on logging to a file; negating this
+ option turns it off. By default, ssuuddoo logs via syslog.
+
+ mailerflags Flags to use when invoking mailer. Defaults to --tt.
+
+ mailerpath Path to mail program used to send warning mail. Defaults
+ to the path to sendmail found at configure time.
+
+ mailfrom Address to use for the "from" address when sending warning
+ and error mail. The address should be enclosed in double
+ quotes ("") to protect against ssuuddoo interpreting the @
+ sign. Defaults to the name of the user running ssuuddoo.
+
+ mailto Address to send warning and error mail to. The address
+ should be enclosed in double quotes ("") to protect against
+ ssuuddoo interpreting the @ sign. Defaults to root.
+
+ restricted_env_file
+ The _r_e_s_t_r_i_c_t_e_d___e_n_v___f_i_l_e option specifies the fully
+ qualified path to a file containing variables to be set in
+ the environment of the program being run. Entries in this
+ file should either be of the form "VARIABLE=value" or
+ "export VARIABLE=value". The value may optionally be
+ surrounded by single or double quotes. Variables in this
+ file are only added if the variable does not already exist
+ in the environment. Unlike _e_n_v___f_i_l_e, the file's contents
+ are not trusted and are processed in a manner similar to
+ that of the invoking user's environment. If _e_n_v___r_e_s_e_t is
+ enabled, variables in the file will only be added if they
+ are matched by either the _e_n_v___c_h_e_c_k or _e_n_v___k_e_e_p list. If
+ _e_n_v___r_e_s_e_t is disabled, variables in the file are added as
+ long as they are not matched by the _e_n_v___d_e_l_e_t_e list. In
+ either case, the contents of _r_e_s_t_r_i_c_t_e_d___e_n_v___f_i_l_e are
+ processed before the contents of _e_n_v___f_i_l_e.
+
+ secure_path Path used for every command run from ssuuddoo. If you don't
+ trust the people running ssuuddoo to have a sane PATH
+ environment variable you may want to use this. Another use
+ is if you want to have the "root path" be separate from the
+ "user path". Users in the group specified by the
+ _e_x_e_m_p_t___g_r_o_u_p option are not affected by _s_e_c_u_r_e___p_a_t_h. This
+ option is not set by default.
+
+ syslog Syslog facility if syslog is being used for logging (negate
+ to disable syslog logging). Defaults to auth.
+
+ The following syslog facilities are supported: aauutthhpprriivv (if
+ your OS supports it), aauutthh, ddaaeemmoonn, uusseerr, llooccaall00, llooccaall11,
+ llooccaall22, llooccaall33, llooccaall44, llooccaall55, llooccaall66, and llooccaall77.
+
+ syslog_badpri
+ Syslog priority to use when the user is not allowed to run
+ a command or when authentication is unsuccessful. Defaults
+ to alert.
+
+ The following syslog priorities are supported: aalleerrtt, ccrriitt,
+ ddeebbuugg, eemmeerrgg, eerrrr, iinnffoo, nnoottiiccee, wwaarrnniinngg, and nnoonnee.
+ Negating the option or setting it to a value of nnoonnee will
+ disable logging of unsuccessful commands.
+
+ syslog_goodpri
+ Syslog priority to use when the user is allowed to run a
+ command and authentication is successful. Defaults to
+ notice.
+
+ See _s_y_s_l_o_g___b_a_d_p_r_i for the list of supported syslog
+ priorities. Negating the option or setting it to a value
+ of nnoonnee will disable logging of successful commands.
+
+ verifypw This option controls when a password will be required when
+ a user runs ssuuddoo with the --vv option. It has the following
+ possible values:
+
+ all All the user's _s_u_d_o_e_r_s file entries for the current
+ host must have the NOPASSWD flag set to avoid
+ entering a password.
+
+ always The user must always enter a password to use the --vv
+ option.
+
+ any At least one of the user's _s_u_d_o_e_r_s file entries for
+ the current host must have the NOPASSWD flag set to
+ avoid entering a password.
+
+ never The user need never enter a password to use the --vv
+ option.
+
+ If no value is specified, a value of _a_l_l is implied.
+ Negating the option results in a value of _n_e_v_e_r being used.
+ The default value is _a_l_l.
+
+ LLiissttss tthhaatt ccaann bbee uusseedd iinn aa bboooolleeaann ccoonntteexxtt:
+
+ env_check Environment variables to be removed from the user's
+ environment unless they are considered "safe". For all
+ variables except TZ, "safe" means that the variable's
+ value does not contain any `%' or `/' characters. This
+ can be used to guard against printf-style format
+ vulnerabilities in poorly-written programs. The TZ
+ variable is considered unsafe if any of the following
+ are true:
+
+ ++oo It consists of a fully-qualified path name,
+ optionally prefixed with a colon (`:'), that does
+ not match the location of the _z_o_n_e_i_n_f_o directory.
+
+ ++oo It contains a _._. path element.
+
+ ++oo It contains white space or non-printable characters.
+
+ ++oo It is longer than the value of PATH_MAX.
+
+ The argument may be a double-quoted, space-separated
+ list or a single value without double-quotes. The list
+ can be replaced, added to, deleted from, or disabled by
+ using the =, +=, -=, and ! operators respectively.
+ Regardless of whether the env_reset option is enabled
+ or disabled, variables specified by env_check will be
+ preserved in the environment if they pass the
+ aforementioned check. The global list of environment
+ variables to check is displayed when ssuuddoo is run by
+ root with the --VV option.
+
+ env_delete Environment variables to be removed from the user's
+ environment when the _e_n_v___r_e_s_e_t option is not in effect.
+ The argument may be a double-quoted, space-separated
+ list or a single value without double-quotes. The list
+ can be replaced, added to, deleted from, or disabled by
+ using the =, +=, -=, and ! operators respectively. The
+ global list of environment variables to remove is
+ displayed when ssuuddoo is run by root with the --VV option.
+ Note that many operating systems will remove
+ potentially dangerous variables from the environment of
+ any setuid process (such as ssuuddoo).
+
+ env_keep Environment variables to be preserved in the user's
+ environment when the _e_n_v___r_e_s_e_t option is in effect.
+ This allows fine-grained control over the environment
+ ssuuddoo-spawned processes will receive. The argument may
+ be a double-quoted, space-separated list or a single
+ value without double-quotes. The list can be replaced,
+ added to, deleted from, or disabled by using the =, +=,
+ -=, and ! operators respectively. The global list of
+ variables to keep is displayed when ssuuddoo is run by root
+ with the --VV option.
+
+GGRROOUUPP PPRROOVVIIDDEERR PPLLUUGGIINNSS
+ The ssuuddooeerrss plugin supports its own plugin interface to allow non-Unix
+ group lookups which can query a group source other than the standard Unix
+ group database. This can be used to implement support for the
+ nonunix_group syntax described earlier.
+
+ Group provider plugins are specified via the _g_r_o_u_p___p_l_u_g_i_n Defaults
+ setting. The argument to _g_r_o_u_p___p_l_u_g_i_n should consist of the plugin path,
+ either fully-qualified or relative to the _/_u_s_r_/_l_o_c_a_l_/_l_i_b_e_x_e_c_/_s_u_d_o
+ directory, followed by any configuration options the plugin requires.
+ These options (if specified) will be passed to the plugin's
+ initialization function. If options are present, the string must be
+ enclosed in double quotes ("").
+
+ The following group provider plugins are installed by default:
+
+ group_file
+ The _g_r_o_u_p___f_i_l_e plugin supports an alternate group file that
+ uses the same syntax as the _/_e_t_c_/_g_r_o_u_p file. The path to the
+ group file should be specified as an option to the plugin. For
+ example, if the group file to be used is _/_e_t_c_/_s_u_d_o_-_g_r_o_u_p:
+
+ Defaults group_plugin="group_file.so /etc/sudo-group"
+
+ system_group
+ The _s_y_s_t_e_m___g_r_o_u_p plugin supports group lookups via the standard
+ C library functions ggeettggrrnnaamm() and ggeettggrriidd(). This plugin can
+ be used in instances where the user belongs to groups not
+ present in the user's supplemental group vector. This plugin
+ takes no options:
+
+ Defaults group_plugin=system_group.so
+
+ The group provider plugin API is described in detail in sudo_plugin(4).
+
+LLOOGG FFOORRMMAATT
+ ssuuddooeerrss can log events using either syslog(3) or a simple log file. The
+ log format is almost identical in both cases.
+
+ AAcccceepptteedd ccoommmmaanndd lloogg eennttrriieess
+ Commands that sudo runs are logged using the following format (split into
+ multiple lines for readability):
+
+ date hostname progname: username : TTY=ttyname ; PWD=cwd ; \
+ USER=runasuser ; GROUP=runasgroup ; TSID=logid ; \
+ ENV=env_vars COMMAND=command
+
+ Where the fields are as follows:
+
+ date The date the command was run. Typically, this is in the
+ format "MMM, DD, HH:MM:SS". If logging via syslog(3), the
+ actual date format is controlled by the syslog daemon. If
+ logging to a file and the _l_o_g___y_e_a_r option is enabled, the
+ date will also include the year.
+
+ hostname The name of the host ssuuddoo was run on. This field is only
+ present when logging via syslog(3).
+
+ progname The name of the program, usually _s_u_d_o or _s_u_d_o_e_d_i_t. This
+ field is only present when logging via syslog(3).
+
+ username The login name of the user who ran ssuuddoo.
+
+ ttyname The short name of the terminal (e.g., "console", "tty01",
+ or "pts/0") ssuuddoo was run on, or "unknown" if there was no
+ terminal present.
+
+ cwd The current working directory that ssuuddoo was run in.
+
+ runasuser The user the command was run as.
+
+ runasgroup The group the command was run as if one was specified on
+ the command line.
+
+ logid An I/O log identifier that can be used to replay the
+ command's output. This is only present when the _l_o_g___i_n_p_u_t
+ or _l_o_g___o_u_t_p_u_t option is enabled.
+
+ env_vars A list of environment variables specified on the command
+ line, if specified.
+
+ command The actual command that was executed.
+
+ Messages are logged using the locale specified by _s_u_d_o_e_r_s___l_o_c_a_l_e, which
+ defaults to the "C" locale.
+
+ DDeenniieedd ccoommmmaanndd lloogg eennttrriieess
+ If the user is not allowed to run the command, the reason for the denial
+ will follow the user name. Possible reasons include:
+
+ user NOT in sudoers
+ The user is not listed in the _s_u_d_o_e_r_s file.
+
+ user NOT authorized on host
+ The user is listed in the _s_u_d_o_e_r_s file but is not allowed to run
+ commands on the host.
+
+ command not allowed
+ The user is listed in the _s_u_d_o_e_r_s file for the host but they are not
+ allowed to run the specified command.
+
+ 3 incorrect password attempts
+ The user failed to enter their password after 3 tries. The actual
+ number of tries will vary based on the number of failed attempts and
+ the value of the _p_a_s_s_w_d___t_r_i_e_s option.
+
+ a password is required
+ ssuuddoo's --nn option was specified but a password was required.
+
+ sorry, you are not allowed to set the following environment variables
+ The user specified environment variables on the command line that were
+ not allowed by _s_u_d_o_e_r_s.
+
+ EErrrroorr lloogg eennttrriieess
+ If an error occurs, ssuuddooeerrss will log a message and, in most cases, send a
+ message to the administrator via email. Possible errors include:
+
+ parse error in /etc/sudoers near line N
+ ssuuddooeerrss encountered an error when parsing the specified file. In some
+ cases, the actual error may be one line above or below the line number
+ listed, depending on the type of error.
+
+ problem with defaults entries
+ The _s_u_d_o_e_r_s file contains one or more unknown Defaults settings. This
+ does not prevent ssuuddoo from running, but the _s_u_d_o_e_r_s file should be
+ checked using vviissuuddoo.
+
+ timestamp owner (username): No such user
+ The time stamp directory owner, as specified by the _t_i_m_e_s_t_a_m_p_o_w_n_e_r
+ setting, could not be found in the password database.
+
+ unable to open/read /etc/sudoers
+ The _s_u_d_o_e_r_s file could not be opened for reading. This can happen
+ when the _s_u_d_o_e_r_s file is located on a remote file system that maps
+ user ID 0 to a different value. Normally, ssuuddooeerrss tries to open the
+ _s_u_d_o_e_r_s file using group permissions to avoid this problem. Consider
+ either changing the ownership of _/_e_t_c_/_s_u_d_o_e_r_s or adding an argument
+ like "sudoers_uid=N" (where `N' is the user ID that owns the _s_u_d_o_e_r_s
+ file) to the end of the ssuuddooeerrss Plugin line in the sudo.conf(4) file.
+
+ unable to stat /etc/sudoers
+ The _/_e_t_c_/_s_u_d_o_e_r_s file is missing.
+
+ /etc/sudoers is not a regular file
+ The _/_e_t_c_/_s_u_d_o_e_r_s file exists but is not a regular file or symbolic
+ link.
+
+ /etc/sudoers is owned by uid N, should be 0
+ The _s_u_d_o_e_r_s file has the wrong owner. If you wish to change the
+ _s_u_d_o_e_r_s file owner, please add "sudoers_uid=N" (where `N' is the user
+ ID that owns the _s_u_d_o_e_r_s file) to the ssuuddooeerrss Plugin line in the
+ sudo.conf(4) file.
+
+ /etc/sudoers is world writable
+ The permissions on the _s_u_d_o_e_r_s file allow all users to write to it.
+ The _s_u_d_o_e_r_s file must not be world-writable, the default file mode is
+ 0440 (readable by owner and group, writable by none). The default
+ mode may be changed via the "sudoers_mode" option to the ssuuddooeerrss
+ Plugin line in the sudo.conf(4) file.
+
+ /etc/sudoers is owned by gid N, should be 1
+ The _s_u_d_o_e_r_s file has the wrong group ownership. If you wish to change
+ the _s_u_d_o_e_r_s file group ownership, please add "sudoers_gid=N" (where
+ `N' is the group ID that owns the _s_u_d_o_e_r_s file) to the ssuuddooeerrss Plugin
+ line in the sudo.conf(4) file.
+
+ unable to open /var/run/sudo/ts/username
+ ssuuddooeerrss was unable to read or create the user's time stamp file. This
+ can happen when _t_i_m_e_s_t_a_m_p_o_w_n_e_r is set to a user other than root and
+ the mode on _/_v_a_r_/_r_u_n_/_s_u_d_o is not searchable by group or other. The
+ default mode for _/_v_a_r_/_r_u_n_/_s_u_d_o is 0711.
+
+ unable to write to /var/run/sudo/ts/username
+ ssuuddooeerrss was unable to write to the user's time stamp file.
+
+ /var/run/sudo/ts is owned by uid X, should be Y
+ The time stamp directory is owned by a user other than _t_i_m_e_s_t_a_m_p_o_w_n_e_r.
+ This can occur when the value of _t_i_m_e_s_t_a_m_p_o_w_n_e_r has been changed.
+ ssuuddooeerrss will ignore the time stamp directory until the owner is
+ corrected.
+
+ /var/run/sudo/ts is group writable
+ The time stamp directory is group-writable; it should be writable only
+ by _t_i_m_e_s_t_a_m_p_o_w_n_e_r. The default mode for the time stamp directory is
+ 0700. ssuuddooeerrss will ignore the time stamp directory until the mode is
+ corrected.
+
+ NNootteess oonn llooggggiinngg vviiaa ssyysslloogg
+ By default, ssuuddooeerrss logs messages via syslog(3). The _d_a_t_e, _h_o_s_t_n_a_m_e, and
+ _p_r_o_g_n_a_m_e fields are added by the system's ssyysslloogg() function, not ssuuddooeerrss
+ itself. As such, they may vary in format on different systems.
+
+ The maximum size of syslog messages varies from system to system. The
+ _s_y_s_l_o_g___m_a_x_l_e_n setting can be used to change the maximum syslog message
+ size from the default value of 980 bytes. For more information, see the
+ description of _s_y_s_l_o_g___m_a_x_l_e_n.
+
+ NNootteess oonn llooggggiinngg ttoo aa ffiillee
+ If the _l_o_g_f_i_l_e option is set, ssuuddooeerrss will log to a local file, such as
+ _/_v_a_r_/_l_o_g_/_s_u_d_o. When logging to a file, ssuuddooeerrss uses a format similar to
+ syslog(3), with a few important differences:
+
+ 1. The _p_r_o_g_n_a_m_e and _h_o_s_t_n_a_m_e fields are not present.
+
+ 2. If the _l_o_g___y_e_a_r option is enabled, the date will also include the
+ year.
+
+ 3. Lines that are longer than _l_o_g_l_i_n_e_l_e_n characters (80 by default) are
+ word-wrapped and continued on the next line with a four character
+ indent. This makes entries easier to read for a human being, but
+ makes it more difficult to use grep(1) on the log files. If the
+ _l_o_g_l_i_n_e_l_e_n option is set to 0 (or negated with a `!'), word wrap
+ will be disabled.
+
+II//OO LLOOGG FFIILLEESS
+ When I/O logging is enabled, ssuuddoo will run the command in a pseudo-tty
+ and log all user input and/or output, depending on which options are
+ enabled. I/O is logged to the directory specified by the _i_o_l_o_g___d_i_r
+ option (_/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o by default) using a unique session ID that is
+ included in the ssuuddoo log line, prefixed with "TSID=". The _i_o_l_o_g___f_i_l_e
+ option may be used to control the format of the session ID.
+
+ Each I/O log is stored in a separate directory that contains the
+ following files:
+
+ _l_o_g a text file containing the time the command was run, the name
+ of the user who ran ssuuddoo, the name of the target user, the name
+ of the target group (optional), the terminal that ssuuddoo was run
+ from, the number of rows and columns of the terminal, the
+ working directory the command was run from and the path name of
+ the command itself (with arguments if present)
+
+ _t_i_m_i_n_g a log of the amount of time between, and the number of bytes
+ in, each I/O log entry (used for session playback)
+
+ _t_t_y_i_n input from the user's tty (what the user types)
+
+ _s_t_d_i_n input from a pipe or file
+
+ _t_t_y_o_u_t output from the pseudo-tty (what the command writes to the
+ screen)
+
+ _s_t_d_o_u_t standard output to a pipe or redirected to a file
+
+ _s_t_d_e_r_r standard error to a pipe or redirected to a file
+
+ All files other than _l_o_g are compressed in gzip format unless the
+ _c_o_m_p_r_e_s_s___i_o flag has been disabled. Due to buffering, it is not normally
+ possible to display the I/O logs in real-time as the program is executing
+ The I/O log data will not be complete until the program run by ssuuddoo has
+ exited or has been terminated by a signal. The _i_o_l_o_g___f_l_u_s_h flag can be
+ used to disable buffering, in which case I/O log data is written to disk
+ as soon as it is available. The output portion of an I/O log file can be
+ viewed with the sudoreplay(1m) utility, which can also be used to list or
+ search the available logs.
+
+ Note that user input may contain sensitive information such as passwords
+ (even if they are not echoed to the screen), which will be stored in the
+ log file unencrypted. In most cases, logging the command output via
+ _l_o_g___o_u_t_p_u_t or LOG_OUTPUT is all that is required.
+
+ Since each session's I/O logs are stored in a separate directory,
+ traditional log rotation utilities cannot be used to limit the number of
+ I/O logs. The simplest way to limit the number of I/O is by setting the
+ _m_a_x_s_e_q option to the maximum number of logs you wish to store. Once the
+ I/O log sequence number reaches _m_a_x_s_e_q, it will be reset to zero and
+ ssuuddooeerrss will truncate and re-use any existing I/O logs.
+
+FFIILLEESS
+ _/_e_t_c_/_s_u_d_o_._c_o_n_f Sudo front end configuration
+
+ _/_e_t_c_/_s_u_d_o_e_r_s List of who can run what
+
+ _/_e_t_c_/_g_r_o_u_p Local groups file
+
+ _/_e_t_c_/_n_e_t_g_r_o_u_p List of network groups
+
+ _/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o I/O log files
+
+ _/_v_a_r_/_r_u_n_/_s_u_d_o_/_t_s Directory containing time stamps for the
+ ssuuddooeerrss security policy
+
+ _/_v_a_r_/_a_d_m_/_s_u_d_o_/_l_e_c_t_u_r_e_d Directory containing lecture status files for
+ the ssuuddooeerrss security policy
+
+ _/_e_t_c_/_e_n_v_i_r_o_n_m_e_n_t Initial environment for --ii mode on AIX and
+ Linux systems
+
+EEXXAAMMPPLLEESS
+ Below are example _s_u_d_o_e_r_s file entries. Admittedly, some of these are a
+ bit contrived. First, we allow a few environment variables to pass and
+ then define our _a_l_i_a_s_e_s:
+
+ # Run X applications through sudo; HOME is used to find the
+ # .Xauthority file. Note that other programs use HOME to find
+ # configuration files and this may lead to privilege escalation!
+ Defaults env_keep += "DISPLAY HOME"
+
+ # User alias specification
+ User_Alias FULLTIMERS = millert, mikef, dowdy
+ User_Alias PARTTIMERS = bostley, jwfox, crawl
+ User_Alias WEBMASTERS = will, wendy, wim
+
+ # Runas alias specification
+ Runas_Alias OP = root, operator
+ Runas_Alias DB = oracle, sybase
+ Runas_Alias ADMINGRP = adm, oper
+
+ # Host alias specification
+ Host_Alias SPARC = bigtime, eclipse, moet, anchor :\
+ SGI = grolsch, dandelion, black :\
+ ALPHA = widget, thalamus, foobar :\
+ HPPA = boa, nag, python
+ Host_Alias CUNETS = 128.138.0.0/255.255.0.0
+ Host_Alias CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0
+ Host_Alias SERVERS = master, mail, www, ns
+ Host_Alias CDROM = orion, perseus, hercules
+
+ # Cmnd alias specification
+ Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\
+ /usr/sbin/restore, /usr/sbin/rrestore,\
+ sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \
+ /home/operator/bin/start_backups
+ Cmnd_Alias KILL = /usr/bin/kill
+ Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
+ Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown
+ Cmnd_Alias HALT = /usr/sbin/halt
+ Cmnd_Alias REBOOT = /usr/sbin/reboot
+ Cmnd_Alias SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh,\
+ /usr/local/bin/tcsh, /usr/bin/rsh,\
+ /usr/local/bin/zsh
+ Cmnd_Alias SU = /usr/bin/su
+ Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+
+ Here we override some of the compiled in default values. We want ssuuddoo to
+ log via syslog(3) using the _a_u_t_h facility in all cases. We don't want to
+ subject the full time staff to the ssuuddoo lecture, user mmiilllleerrtt need not
+ give a password, and we don't want to reset the LOGNAME or USER
+ environment variables when running commands as root. Additionally, on
+ the machines in the _S_E_R_V_E_R_S Host_Alias, we keep an additional local log
+ file and make sure we log the year in each log line since the log entries
+ will be kept around for several years. Lastly, we disable shell escapes
+ for the commands in the PAGERS Cmnd_Alias (_/_u_s_r_/_b_i_n_/_m_o_r_e, _/_u_s_r_/_b_i_n_/_p_g and
+ _/_u_s_r_/_b_i_n_/_l_e_s_s). Note that this will not effectively constrain users with
+ ssuuddoo AALLLL privileges.
+
+ # Override built-in defaults
+ Defaults syslog=auth
+ Defaults>root !set_logname
+ Defaults:FULLTIMERS !lecture
+ Defaults:millert !authenticate
+ Defaults@SERVERS log_year, logfile=/var/log/sudo.log
+ Defaults!PAGERS noexec
+
+ The _U_s_e_r _s_p_e_c_i_f_i_c_a_t_i_o_n is the part that actually determines who may run
+ what.
+
+ root ALL = (ALL) ALL
+ %wheel ALL = (ALL) ALL
+
+ We let rroooott and any user in group wwhheeeell run any command on any host as
+ any user.
+
+ FULLTIMERS ALL = NOPASSWD: ALL
+
+ Full time sysadmins (mmiilllleerrtt, mmiikkeeff, and ddoowwddyy) may run any command on
+ any host without authenticating themselves.
+
+ PARTTIMERS ALL = ALL
+
+ Part time sysadmins bboossttlleeyy, jjwwffooxx, and ccrraawwll) may run any command on any
+ host but they must authenticate themselves first (since the entry lacks
+ the NOPASSWD tag).
+
+ jack CSNETS = ALL
+
+ The user jjaacckk may run any command on the machines in the _C_S_N_E_T_S alias
+ (the networks 128.138.243.0, 128.138.204.0, and 128.138.242.0). Of those
+ networks, only 128.138.204.0 has an explicit netmask (in CIDR notation)
+ indicating it is a class C network. For the other networks in _C_S_N_E_T_S,
+ the local machine's netmask will be used during matching.
+
+ lisa CUNETS = ALL
+
+ The user lliissaa may run any command on any host in the _C_U_N_E_T_S alias (the
+ class B network 128.138.0.0).
+
+ operator ALL = DUMPS, KILL, SHUTDOWN, HALT, REBOOT, PRINTING,\
+ sudoedit /etc/printcap, /usr/oper/bin/
+
+ The ooppeerraattoorr user may run commands limited to simple maintenance. Here,
+ those are commands related to backups, killing processes, the printing
+ system, shutting down the system, and any commands in the directory
+ _/_u_s_r_/_o_p_e_r_/_b_i_n_/. Note that one command in the DUMPS Cmnd_Alias includes a
+ sha224 digest, _/_h_o_m_e_/_o_p_e_r_a_t_o_r_/_b_i_n_/_s_t_a_r_t___b_a_c_k_u_p_s. This is because the
+ directory containing the script is writable by the operator user. If the
+ script is modified (resulting in a digest mismatch) it will no longer be
+ possible to run it via ssuuddoo.
+
+ joe ALL = /usr/bin/su operator
+
+ The user jjooee may only su(1) to operator.
+
+ pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd *root*
+
+ %opers ALL = (: ADMINGRP) /usr/sbin/
+
+ Users in the ooppeerrss group may run commands in _/_u_s_r_/_s_b_i_n_/ as themselves
+ with any group in the _A_D_M_I_N_G_R_P Runas_Alias (the aaddmm and ooppeerr groups).
+
+ The user ppeettee is allowed to change anyone's password except for root on
+ the _H_P_P_A machines. Because command line arguments are matched as a
+ single, concatenated string, the `*' wildcard will match _m_u_l_t_i_p_l_e words.
+ This example assumes that passwd(1) does not take multiple user names on
+ the command line. Note that on GNU systems, options to passwd(1) may be
+ specified after the user argument. As a result, this rule will also
+ allow:
+
+ passwd username --expire
+
+ which may not be desirable.
+
+ bob SPARC = (OP) ALL : SGI = (OP) ALL
+
+ The user bboobb may run anything on the _S_P_A_R_C and _S_G_I machines as any user
+ listed in the _O_P Runas_Alias (rroooott and ooppeerraattoorr.)
+
+ jim +biglab = ALL
+
+ The user jjiimm may run any command on machines in the _b_i_g_l_a_b netgroup.
+ ssuuddoo knows that "biglab" is a netgroup due to the `+' prefix.
+
+ +secretaries ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser
+
+ Users in the sseeccrreettaarriieess netgroup need to help manage the printers as
+ well as add and remove users, so they are allowed to run those commands
+ on all machines.
+
+ fred ALL = (DB) NOPASSWD: ALL
+
+ The user ffrreedd can run commands as any user in the _D_B Runas_Alias (oorraaccllee
+ or ssyybbaassee) without giving a password.
+
+ john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
+
+ On the _A_L_P_H_A machines, user jjoohhnn may su to anyone except root but he is
+ not allowed to specify any options to the su(1) command.
+
+ jen ALL, !SERVERS = ALL
+
+ The user jjeenn may run any command on any machine except for those in the
+ _S_E_R_V_E_R_S Host_Alias (master, mail, www and ns).
+
+ jill SERVERS = /usr/bin/, !SU, !SHELLS
+
+ For any machine in the _S_E_R_V_E_R_S Host_Alias, jjiillll may run any commands in
+ the directory _/_u_s_r_/_b_i_n_/ except for those commands belonging to the _S_U and
+ _S_H_E_L_L_S Cmnd_Aliases. While not specifically mentioned in the rule, the
+ commands in the _P_A_G_E_R_S Cmnd_Alias all reside in _/_u_s_r_/_b_i_n and have the
+ _n_o_e_x_e_c option set.
+
+ steve CSNETS = (operator) /usr/local/op_commands/
+
+ The user sstteevvee may run any command in the directory
+ /usr/local/op_commands/ but only as user operator.
+
+ matt valkyrie = KILL
+
+ On his personal workstation, valkyrie, mmaatttt needs to be able to kill hung
+ processes.
+
+ WEBMASTERS www = (www) ALL, (root) /usr/bin/su www
+
+ On the host www, any user in the _W_E_B_M_A_S_T_E_R_S User_Alias (will, wendy, and
+ wim), may run any command as user www (which owns the web pages) or
+ simply su(1) to www.
+
+ ALL CDROM = NOPASSWD: /sbin/umount /CDROM,\
+ /sbin/mount -o nosuid\,nodev /dev/cd0a /CDROM
+
+ Any user may mount or unmount a CD-ROM on the machines in the CDROM
+ Host_Alias (orion, perseus, hercules) without entering a password. This
+ is a bit tedious for users to type, so it is a prime candidate for
+ encapsulating in a shell script.
+
+SSEECCUURRIITTYY NNOOTTEESS
+ LLiimmiittaattiioonnss ooff tthhee ``!!'' ooppeerraattoorr
+ It is generally not effective to "subtract" commands from AALLLL using the
+ `!' operator. A user can trivially circumvent this by copying the
+ desired command to a different name and then executing that. For
+ example:
+
+ bill ALL = ALL, !SU, !SHELLS
+
+ Doesn't really prevent bbiillll from running the commands listed in _S_U or
+ _S_H_E_L_L_S since he can simply copy those commands to a different name, or
+ use a shell escape from an editor or other program. Therefore, these
+ kind of restrictions should be considered advisory at best (and
+ reinforced by policy).
+
+ In general, if a user has sudo AALLLL there is nothing to prevent them from
+ creating their own program that gives them a root shell (or making their
+ own copy of a shell) regardless of any `!' elements in the user
+ specification.
+
+ SSeeccuurriittyy iimmpplliiccaattiioonnss ooff _f_a_s_t___g_l_o_b
+ If the _f_a_s_t___g_l_o_b option is in use, it is not possible to reliably negate
+ commands where the path name includes globbing (aka wildcard) characters.
+ This is because the C library's fnmatch(3) function cannot resolve
+ relative paths. While this is typically only an inconvenience for rules
+ that grant privileges, it can result in a security issue for rules that
+ subtract or revoke privileges.
+
+ For example, given the following _s_u_d_o_e_r_s file entry:
+
+ john ALL = /usr/bin/passwd [a-zA-Z0-9]*, /usr/bin/chsh [a-zA-Z0-9]*,\
+ /usr/bin/chfn [a-zA-Z0-9]*, !/usr/bin/* root
+
+ User jjoohhnn can still run /usr/bin/passwd root if _f_a_s_t___g_l_o_b is enabled by
+ changing to _/_u_s_r_/_b_i_n and running ./passwd root instead.
+
+ PPrreevveennttiinngg sshheellll eessccaappeess
+ Once ssuuddoo executes a program, that program is free to do whatever it
+ pleases, including run other programs. This can be a security issue
+ since it is not uncommon for a program to allow shell escapes, which lets
+ a user bypass ssuuddoo's access control and logging. Common programs that
+ permit shell escapes include shells (obviously), editors, paginators,
+ mail and terminal programs.
+
+ There are two basic approaches to this problem:
+
+ restrict Avoid giving users access to commands that allow the user to
+ run arbitrary commands. Many editors have a restricted mode
+ where shell escapes are disabled, though ssuuddooeeddiitt is a better
+ solution to running editors via ssuuddoo. Due to the large number
+ of programs that offer shell escapes, restricting users to the
+ set of programs that do not is often unworkable.
+
+ noexec Many systems that support shared libraries have the ability to
+ override default library functions by pointing an environment
+ variable (usually LD_PRELOAD) to an alternate shared library.
+ On such systems, ssuuddoo's _n_o_e_x_e_c functionality can be used to
+ prevent a program run by ssuuddoo from executing any other
+ programs. Note, however, that this applies only to native
+ dynamically-linked executables. Statically-linked executables
+ and foreign executables running under binary emulation are not
+ affected.
+
+ The _n_o_e_x_e_c feature is known to work on SunOS, Solaris, *BSD,
+ Linux, IRIX, Tru64 UNIX, macOS, HP-UX 11.x and AIX 5.3 and
+ above. It should be supported on most operating systems that
+ support the LD_PRELOAD environment variable. Check your
+ operating system's manual pages for the dynamic linker (usually
+ ld.so, ld.so.1, dyld, dld.sl, rld, or loader) to see if
+ LD_PRELOAD is supported.
+
+ On Solaris 10 and higher, _n_o_e_x_e_c uses Solaris privileges
+ instead of the LD_PRELOAD environment variable.
+
+ To enable _n_o_e_x_e_c for a command, use the NOEXEC tag as
+ documented in the User Specification section above. Here is
+ that example again:
+
+ aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi
+
+ This allows user aaaarroonn to run _/_u_s_r_/_b_i_n_/_m_o_r_e and _/_u_s_r_/_b_i_n_/_v_i
+ with _n_o_e_x_e_c enabled. This will prevent those two commands from
+ executing other commands (such as a shell). If you are unsure
+ whether or not your system is capable of supporting _n_o_e_x_e_c you
+ can always just try it out and check whether shell escapes work
+ when _n_o_e_x_e_c is enabled.
+
+ Note that restricting shell escapes is not a panacea. Programs running
+ as root are still capable of many potentially hazardous operations (such
+ as changing or overwriting files) that could lead to unintended privilege
+ escalation. In the specific case of an editor, a safer approach is to
+ give the user permission to run ssuuddooeeddiitt (see below).
+
+ SSeeccuurree eeddiittiinngg
+ The ssuuddooeerrss plugin includes ssuuddooeeddiitt support which allows users to
+ securely edit files with the editor of their choice. As ssuuddooeeddiitt is a
+ built-in command, it must be specified in the _s_u_d_o_e_r_s file without a
+ leading path. However, it may take command line arguments just as a
+ normal command does. Wildcards used in _s_u_d_o_e_d_i_t command line arguments
+ are expected to be path names, so a forward slash (`/') will not be
+ matched by a wildcard.
+
+ Unlike other ssuuddoo commands, the editor is run with the permissions of the
+ invoking user and with the environment unmodified. More information may
+ be found in the description of the --ee option in sudo(1m).
+
+ For example, to allow user operator to edit the "message of the day"
+ file:
+
+ operator sudoedit /etc/motd
+
+ The operator user then runs ssuuddooeeddiitt as follows:
+
+ $ sudoedit /etc/motd
+
+ The editor will run as the operator user, not root, on a temporary copy
+ of _/_e_t_c_/_m_o_t_d. After the file has been edited, _/_e_t_c_/_m_o_t_d will be updated
+ with the contents of the temporary copy.
+
+ Users should _n_e_v_e_r be granted ssuuddooeeddiitt permission to edit a file that
+ resides in a directory the user has write access to, either directly or
+ via a wildcard. If the user has write access to the directory it is
+ possible to replace the legitimate file with a link to another file,
+ allowing the editing of arbitrary files. To prevent this, starting with
+ version 1.8.16, symbolic links will not be followed in writable
+ directories and ssuuddooeeddiitt will refuse to edit a file located in a writable
+ directory unless the _s_u_d_o_e_d_i_t___c_h_e_c_k_d_i_r option has been disabled or the
+ invoking user is root. Additionally, in version 1.8.15 and higher,
+ ssuuddooeeddiitt will refuse to open a symbolic link unless either the
+ _s_u_d_o_e_d_i_t___f_o_l_l_o_w option is enabled or the _s_u_d_o_e_d_i_t command is prefixed
+ with the FOLLOW tag in the _s_u_d_o_e_r_s file.
+
+ TTiimmee ssttaammpp ffiillee cchheecckkss
+ ssuuddooeerrss will check the ownership of its time stamp directory
+ (_/_v_a_r_/_r_u_n_/_s_u_d_o_/_t_s by default) and ignore the directory's contents if it
+ is not owned by root or if it is writable by a user other than root.
+ Older versions of ssuuddoo stored time stamp files in _/_t_m_p; this is no longer
+ recommended as it may be possible for a user to create the time stamp
+ themselves on systems that allow unprivileged users to change the
+ ownership of files they create.
+
+ While the time stamp directory _s_h_o_u_l_d be cleared at reboot time, not all
+ systems contain a _/_r_u_n or _/_v_a_r_/_r_u_n directory. To avoid potential
+ problems, ssuuddooeerrss will ignore time stamp files that date from before the
+ machine booted on systems where the boot time is available.
+
+ Some systems with graphical desktop environments allow unprivileged users
+ to change the system clock. Since ssuuddooeerrss relies on the system clock for
+ time stamp validation, it may be possible on such systems for a user to
+ run ssuuddoo for longer than _t_i_m_e_s_t_a_m_p___t_i_m_e_o_u_t by setting the clock back. To
+ combat this, ssuuddooeerrss uses a monotonic clock (which never moves backwards)
+ for its time stamps if the system supports it.
+
+ ssuuddooeerrss will not honor time stamps set far in the future. Time stamps
+ with a date greater than current_time + 2 * TIMEOUT will be ignored and
+ ssuuddooeerrss will log and complain.
+
+ If the _t_i_m_e_s_t_a_m_p___t_y_p_e option is set to "tty", the time stamp record
+ includes the device number of the terminal the user authenticated with.
+ This provides per-terminal granularity but time stamp records may still
+ outlive the user's session.
+
+ Unless the _t_i_m_e_s_t_a_m_p___t_y_p_e option is set to "global", the time stamp
+ record also includes the session ID of the process that last
+ authenticated. This prevents processes in different terminal sessions
+ from using the same time stamp record. On systems where a process's
+ start time can be queried, the start time of the session leader is
+ recorded in the time stamp record. If no terminal is present or the
+ _t_i_m_e_s_t_a_m_p___t_y_p_e option is set to "ppid", the start time of the parent
+ process is used instead. In most cases this will prevent a time stamp
+ record from being re-used without the user entering a password when
+ logging out and back in again.
+
+DDEEBBUUGGGGIINNGG
+ Versions 1.8.4 and higher of the ssuuddooeerrss plugin support a flexible
+ debugging framework that can help track down what the plugin is doing
+ internally if there is a problem. This can be configured in the
+ sudo.conf(4) file.
+
+ The ssuuddooeerrss plugin uses the same debug flag format as the ssuuddoo front-end:
+ _s_u_b_s_y_s_t_e_m@_p_r_i_o_r_i_t_y.
+
+ The priorities used by ssuuddooeerrss, in order of decreasing severity, are:
+ _c_r_i_t, _e_r_r, _w_a_r_n, _n_o_t_i_c_e, _d_i_a_g, _i_n_f_o, _t_r_a_c_e and _d_e_b_u_g. Each priority,
+ when specified, also includes all priorities higher than it. For
+ example, a priority of _n_o_t_i_c_e would include debug messages logged at
+ _n_o_t_i_c_e and higher.
+
+ The following subsystems are used by the ssuuddooeerrss plugin:
+
+ _a_l_i_a_s User_Alias, Runas_Alias, Host_Alias and Cmnd_Alias processing
+
+ _a_l_l matches every subsystem
+
+ _a_u_d_i_t BSM and Linux audit code
+
+ _a_u_t_h user authentication
+
+ _d_e_f_a_u_l_t_s _s_u_d_o_e_r_s file _D_e_f_a_u_l_t_s settings
+
+ _e_n_v environment handling
+
+ _l_d_a_p LDAP-based sudoers
+
+ _l_o_g_g_i_n_g logging support
+
+ _m_a_t_c_h matching of users, groups, hosts and netgroups in the _s_u_d_o_e_r_s
+ file
+
+ _n_e_t_i_f network interface handling
+
+ _n_s_s network service switch handling in ssuuddooeerrss
+
+ _p_a_r_s_e_r _s_u_d_o_e_r_s file parsing
+
+ _p_e_r_m_s permission setting
+
+ _p_l_u_g_i_n The equivalent of _m_a_i_n for the plugin.
+
+ _p_t_y pseudo-tty related code
+
+ _r_b_t_r_e_e redblack tree internals
+
+ _s_s_s_d SSSD-based sudoers
+
+ _u_t_i_l utility functions
+ For example:
+
+ Debug sudo /var/log/sudo_debug match@info,nss@info
+
+ For more information, see the sudo.conf(4) manual.
+
+SSEEEE AALLSSOO
+ ssh(1), su(1), fnmatch(3), glob(3), mktemp(3), strftime(3), sudo.conf(4),
+ sudo_plugin(4), sudoers.ldap(4), sudoers_timestamp(4), sudo(1m), visudo(1m)
+
+AAUUTTHHOORRSS
+ Many people have worked on ssuuddoo over the years; this version consists of
+ code written primarily by:
+
+ Todd C. Miller
+
+ See the CONTRIBUTORS file in the ssuuddoo distribution
+ (https://www.sudo.ws/contributors.html) for an exhaustive list of people
+ who have contributed to ssuuddoo.
+
+CCAAVVEEAATTSS
+ The _s_u_d_o_e_r_s file should aallwwaayyss be edited by the vviissuuddoo command which
+ locks the file and does grammatical checking. It is imperative that the
+ _s_u_d_o_e_r_s file be free of syntax errors since ssuuddoo will not run with a
+ syntactically incorrect _s_u_d_o_e_r_s file.
+
+ When using netgroups of machines (as opposed to users), if you store
+ fully qualified host name in the netgroup (as is usually the case), you
+ either need to have the machine's host name be fully qualified as
+ returned by the hostname command or use the _f_q_d_n option in _s_u_d_o_e_r_s.
+
+BBUUGGSS
+ If you feel you have found a bug in ssuuddoo, please submit a bug report at
+ https://bugzilla.sudo.ws/
+
+SSUUPPPPOORRTT
+ Limited free support is available via the sudo-users mailing list, see
+ https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search
+ the archives.
+
+DDIISSCCLLAAIIMMEERR
+ ssuuddoo is provided "AS IS" and any express or implied warranties,
+ including, but not limited to, the implied warranties of merchantability
+ and fitness for a particular purpose are disclaimed. See the LICENSE
+ file distributed with ssuuddoo or https://www.sudo.ws/license.html for
+ complete details.
+
+Sudo 1.8.26 December 20, 2018 Sudo 1.8.26
diff --git a/doc/sudoers.ldap.cat b/doc/sudoers.ldap.cat
new file mode 100644
index 0000000..0d48b9a
--- /dev/null
+++ b/doc/sudoers.ldap.cat
@@ -0,0 +1,1033 @@
+SUDOERS.LDAP(4) File Formats Manual SUDOERS.LDAP(4)
+
+NNAAMMEE
+ ssuuddooeerrss..llddaapp - sudo LDAP configuration
+
+DDEESSCCRRIIPPTTIIOONN
+ In addition to the standard _s_u_d_o_e_r_s file, ssuuddoo may be configured via
+ LDAP. This can be especially useful for synchronizing _s_u_d_o_e_r_s in a
+ large, distributed environment.
+
+ Using LDAP for _s_u_d_o_e_r_s has several benefits:
+
+ ++oo ssuuddoo no longer needs to read _s_u_d_o_e_r_s in its entirety. When LDAP is
+ used, there are only two or three LDAP queries per invocation. This
+ makes it especially fast and particularly usable in LDAP environments.
+
+ ++oo ssuuddoo no longer exits if there is a typo in _s_u_d_o_e_r_s. It is not
+ possible to load LDAP data into the server that does not conform to
+ the sudoers schema, so proper syntax is guaranteed. It is still
+ possible to have typos in a user or host name, but this will not
+ prevent ssuuddoo from running.
+
+ ++oo It is possible to specify per-entry options that override the global
+ default options. _/_e_t_c_/_s_u_d_o_e_r_s only supports default options and
+ limited options associated with user/host/commands/aliases. The
+ syntax is complicated and can be difficult for users to understand.
+ Placing the options directly in the entry is more natural.
+
+ ++oo The vviissuuddoo program is no longer needed. vviissuuddoo provides locking and
+ syntax checking of the _/_e_t_c_/_s_u_d_o_e_r_s file. Since LDAP updates are
+ atomic, locking is no longer necessary. Because syntax is checked
+ when the data is inserted into LDAP, there is no need for a
+ specialized tool to check syntax.
+
+ SSUUDDOOeerrss LLDDAAPP ccoonnttaaiinneerr
+ The _s_u_d_o_e_r_s configuration is contained in the ou=SUDOers LDAP container.
+
+ Sudo first looks for the cn=defaults entry in the SUDOers container. If
+ found, the multi-valued sudoOption attribute is parsed in the same manner
+ as a global Defaults line in _/_e_t_c_/_s_u_d_o_e_r_s. In the following example, the
+ SSH_AUTH_SOCK variable will be preserved in the environment for all
+ users.
+
+ dn: cn=defaults,ou=SUDOers,dc=my-domain,dc=com
+ objectClass: top
+ objectClass: sudoRole
+ cn: defaults
+ description: Default sudoOption's go here
+ sudoOption: env_keep+=SSH_AUTH_SOCK
+
+ The equivalent of a sudoer in LDAP is a sudoRole. It consists of the
+ following attributes:
+
+ ssuuddooUUsseerr
+ A user name, user ID (prefixed with `#'), Unix group name or ID
+ (prefixed with `%' or `%#' respectively), user netgroup (prefixed
+ with `+'), or non-Unix group name or ID (prefixed with `%:' or
+ `%:#' respectively). User netgroups are matched using the user and
+ domain members only; the host member is not used when matching.
+ Non-Unix group support is only available when an appropriate
+ _g_r_o_u_p___p_l_u_g_i_n is defined in the global _d_e_f_a_u_l_t_s sudoRole object.
+
+ ssuuddooHHoosstt
+ A host name, IP address, IP network, or host netgroup (prefixed
+ with a `+'). The special value ALL will match any host. Host
+ netgroups are matched using the host (both qualified and
+ unqualified) and domain members only; the user member is not used
+ when matching. If a sudoHost entry is preceded by an exclamation
+ point, `!', and the entry matches, the sudoRole in which it resides
+ will be ignored. Negated sudoHost entries are only supported by
+ version 1.8.18 or higher.
+
+ ssuuddooCCoommmmaanndd
+ A fully-qualified Unix command name with optional command line
+ arguments, potentially including globbing characters (aka wild
+ cards). If a command name is preceded by an exclamation point,
+ `!', the user will be prohibited from running that command.
+
+ The built-in command "sudoedit" is used to permit a user to run
+ ssuuddoo with the --ee option (or as ssuuddooeeddiitt). It may take command line
+ arguments just as a normal command does. Note that "sudoedit" is a
+ command built into ssuuddoo itself and must be specified in without a
+ leading path.
+
+ The special value ALL will match any command.
+
+ If a command name is prefixed with a SHA-2 digest, it will only be
+ allowed if the digest matches. This may be useful in situations
+ where the user invoking ssuuddoo has write access to the command or its
+ parent directory. The following digest formats are supported:
+ sha224, sha256, sha384 and sha512. The digest name must be
+ followed by a colon (`:') and then the actual digest, in either hex
+ or base64 format. For example, given the following value for
+ sudoCommand:
+
+ sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ /bin/ls
+
+ The user may only run _/_b_i_n_/_l_s if its sha224 digest matches the
+ specified value. Command digests are only supported by version
+ 1.8.7 or higher.
+
+ ssuuddooOOppttiioonn
+ Identical in function to the global options described above, but
+ specific to the sudoRole in which it resides.
+
+ ssuuddooRRuunnAAssUUsseerr
+ A user name or uid (prefixed with `#') that commands may be run as
+ or a Unix group (prefixed with a `%') or user netgroup (prefixed
+ with a `+') that contains a list of users that commands may be run
+ as. The special value ALL will match any user. If a sudoRunAsUser
+ entry is preceded by an exclamation point, `!', and the entry
+ matches, the sudoRole in which it resides will be ignored. If
+ sudoRunAsUser is specified but empty, it will match the invoking
+ user. If neither sudoRunAsUser nor sudoRunAsGroup are present, the
+ value of the _r_u_n_a_s___d_e_f_a_u_l_t sudoOption is used (defaults to root).
+
+ The sudoRunAsUser attribute is only available in ssuuddoo versions
+ 1.7.0 and higher. Older versions of ssuuddoo use the sudoRunAs
+ attribute instead. Negated sudoRunAsUser entries are only
+ supported by version 1.8.26 or higher.
+
+ ssuuddooRRuunnAAssGGrroouupp
+ A Unix group or gid (prefixed with `#') that commands may be run
+ as. The special value ALL will match any group. If a
+ sudoRunAsGroup entry is preceded by an exclamation point, `!', and
+ the entry matches, the sudoRole in which it resides will be
+ ignored.
+
+ The sudoRunAsGroup attribute is only available in ssuuddoo versions
+ 1.7.0 and higher. Negated sudoRunAsGroup entries are only
+ supported by version 1.8.26 or higher.
+
+ ssuuddooNNoottBBeeffoorree
+ A timestamp in the form yyyymmddHHMMSSZ that can be used to provide
+ a start date/time for when the sudoRole will be valid. If multiple
+ sudoNotBefore entries are present, the earliest is used. Note that
+ timestamps must be in Coordinated Universal Time (UTC), not the
+ local timezone. The minute and seconds portions are optional, but
+ some LDAP servers require that they be present (contrary to the
+ RFC).
+
+ The sudoNotBefore attribute is only available in ssuuddoo versions
+ 1.7.5 and higher and must be explicitly enabled via the
+ SSUUDDOOEERRSS__TTIIMMEEDD option in _/_e_t_c_/_l_d_a_p_._c_o_n_f.
+
+ ssuuddooNNoottAAfftteerr
+ A timestamp in the form yyyymmddHHMMSSZ that indicates an
+ expiration date/time, after which the sudoRole will no longer be
+ valid. If multiple sudoNotAfter entries are present, the last one
+ is used. Note that timestamps must be in Coordinated Universal
+ Time (UTC), not the local timezone. The minute and seconds
+ portions are optional, but some LDAP servers require that they be
+ present (contrary to the RFC).
+
+ The sudoNotAfter attribute is only available in ssuuddoo versions 1.7.5
+ and higher and must be explicitly enabled via the SSUUDDOOEERRSS__TTIIMMEEDD
+ option in _/_e_t_c_/_l_d_a_p_._c_o_n_f.
+
+ ssuuddooOOrrddeerr
+ The sudoRole entries retrieved from the LDAP directory have no
+ inherent order. The sudoOrder attribute is an integer (or floating
+ point value for LDAP servers that support it) that is used to sort
+ the matching entries. This allows LDAP-based sudoers entries to
+ more closely mimic the behavior of the sudoers file, where the
+ order of the entries influences the result. If multiple entries
+ match, the entry with the highest sudoOrder attribute is chosen.
+ This corresponds to the "last match" behavior of the sudoers file.
+ If the sudoOrder attribute is not present, a value of 0 is assumed.
+
+ The sudoOrder attribute is only available in ssuuddoo versions 1.7.5
+ and higher.
+
+ Each attribute listed above should contain a single value, but there may
+ be multiple instances of each attribute type. A sudoRole must contain at
+ least one sudoUser, sudoHost and sudoCommand.
+
+ The following example allows users in group wheel to run any command on
+ any host via ssuuddoo:
+
+ dn: cn=%wheel,ou=SUDOers,dc=my-domain,dc=com
+ objectClass: top
+ objectClass: sudoRole
+ cn: %wheel
+ sudoUser: %wheel
+ sudoHost: ALL
+ sudoCommand: ALL
+
+ AAnnaattoommyy ooff LLDDAAPP ssuuddooeerrss llooookkuupp
+ When looking up a sudoer using LDAP there are only two or three LDAP
+ queries per invocation. The first query is to parse the global options.
+ The second is to match against the user's name and the groups that the
+ user belongs to. (The special ALL tag is matched in this query too.) If
+ no match is returned for the user's name and groups, a third query
+ returns all entries containing user netgroups and other non-Unix groups
+ and checks to see if the user belongs to any of them.
+
+ If timed entries are enabled with the SSUUDDOOEERRSS__TTIIMMEEDD configuration
+ directive, the LDAP queries include a sub-filter that limits retrieval to
+ entries that satisfy the time constraints, if any.
+
+ If the NNEETTGGRROOUUPP__BBAASSEE configuration directive is present (see _C_o_n_f_i_g_u_r_i_n_g
+ _l_d_a_p_._c_o_n_f below), queries are performed to determine the list of
+ netgroups the user belongs to before the sudoers query. This makes it
+ possible to include netgroups in the sudoers query string in the same
+ manner as Unix groups. The third query mentioned above is not performed
+ unless a group provider plugin is also configured. The actual LDAP
+ queries performed by ssuuddoo are as follows:
+
+ 1. Match all nisNetgroup records with a nisNetgroupTriple containing
+ the user, host and NIS domain. The query will match
+ nisNetgroupTriple entries with either the short or long form of the
+ host name or no host name specified in the tuple. If the NIS domain
+ is set, the query will match only match entries that include the
+ domain or for which there is no domain present. If the NIS domain
+ is _n_o_t set, a wildcard is used to match any domain name but be aware
+ that the NIS schema used by some LDAP servers may not support wild
+ cards for nisNetgroupTriple.
+
+ 2. Repeated queries are performed to find any nested nisNetgroup
+ records with a memberNisNetgroup entry that refers to an already-
+ matched record.
+
+ For sites with a large number of netgroups, using NNEETTGGRROOUUPP__BBAASSEE can
+ significantly speed up ssuuddoo's execution time.
+
+ DDiiffffeerreenncceess bbeettwweeeenn LLDDAAPP aanndd nnoonn--LLDDAAPP ssuuddooeerrss
+ One of the major differences between LDAP and file-based _s_u_d_o_e_r_s is that
+ in LDAP, ssuuddoo-specific Aliases are not supported.
+
+ For the most part, there is little need for ssuuddoo-specific Aliases. Unix
+ groups, non-Unix groups (via the _g_r_o_u_p___p_l_u_g_i_n) or user netgroups can be
+ used in place of User_Aliases and Runas_Aliases. Host netgroups can be
+ used in place of Host_Aliases. Since groups and netgroups can also be
+ stored in LDAP there is no real need for ssuuddoo-specific aliases.
+
+ There are also some subtle differences in the way sudoers is handled once
+ in LDAP. Probably the biggest is that according to the RFC, LDAP
+ ordering is arbitrary and you cannot expect that Attributes and Entries
+ are returned in any specific order.
+
+ The order in which different entries are applied can be controlled using
+ the sudoOrder attribute, but there is no way to guarantee the order of
+ attributes within a specific entry. If there are conflicting command
+ rules in an entry, the negative takes precedence. This is called
+ paranoid behavior (not necessarily the most specific match).
+
+ Here is an example:
+
+ # /etc/sudoers:
+ # Allow all commands except shell
+ johnny ALL=(root) ALL,!/bin/sh
+ # Always allows all commands because ALL is matched last
+ puddles ALL=(root) !/bin/sh,ALL
+
+ # LDAP equivalent of johnny
+ # Allows all commands except shell
+ dn: cn=role1,ou=Sudoers,dc=my-domain,dc=com
+ objectClass: sudoRole
+ objectClass: top
+ cn: role1
+ sudoUser: johnny
+ sudoHost: ALL
+ sudoCommand: ALL
+ sudoCommand: !/bin/sh
+
+ # LDAP equivalent of puddles
+ # Notice that even though ALL comes last, it still behaves like
+ # role1 since the LDAP code assumes the more paranoid configuration
+ dn: cn=role2,ou=Sudoers,dc=my-domain,dc=com
+ objectClass: sudoRole
+ objectClass: top
+ cn: role2
+ sudoUser: puddles
+ sudoHost: ALL
+ sudoCommand: !/bin/sh
+ sudoCommand: ALL
+
+ Another difference is that it is not possible to use negation in a
+ sudoUser, sudoRunAsUser or sudoRunAsGroup attribute. For example, the
+ following attributes do not behave the way one might expect.
+
+ # does not match all but joe
+ # rather, does not match anyone
+ sudoUser: !joe
+
+ # does not match all but joe
+ # rather, matches everyone including Joe
+ sudoUser: ALL
+ sudoUser: !joe
+
+ CCoonnvveerrttiinngg bbeettwweeeenn ffiillee--bbaasseedd aanndd LLDDAAPP ssuuddooeerrss
+ The cvtsudoers(1) utility can be used to convert between file-based and
+ LDAP _s_u_d_o_e_r_s. However, there are features in the file-based sudoers that
+ have no equivalent in LDAP-based sudoers (and vice versa). These cannot
+ be converted automatically.
+
+ For example, a Cmnd_Alias in a _s_u_d_o_e_r_s file may be converted to a
+ sudoRole that contains multiple commands. Multiple users and/or groups
+ may be assigned to the sudoRole.
+
+ Also, host, user, runas and command-based Defaults entries are not
+ supported. However, a sudoRole may contain one or more sudoOption
+ attributes which can often serve the same purpose.
+
+ Consider the following _s_u_d_o_e_r_s lines:
+
+ Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+ Defaults!PAGERS noexec
+ alice, bob ALL = ALL
+
+ In this example, alice and bob are allowed to run all commands, but the
+ commands listed in PAGERS will have the noexec flag set, preventing shell
+ escapes.
+
+ When converting this to LDAP, two sudoRole objects can be used:
+
+ dn: cn=PAGERS,ou=SUDOers,dc=my-domain,dc=com
+ objectClass: top
+ objectClass: sudoRole
+ cn: PAGERS
+ sudoUser: alice
+ sudoUser: bob
+ sudoHost: ALL
+ sudoCommand: /usr/bin/more
+ sudoCommand: /usr/bin/pg
+ sudoCommand: /usr/bin/less
+ sudoOption: noexec
+ sudoOrder: 900
+
+ dn: cn=ADMINS,ou=SUDOers,dc=my-domain,dc=com
+ objectClass: top
+ objectClass: sudoRole
+ cn: ADMINS
+ sudoUser: alice
+ sudoUser: bob
+ sudoHost: ALL
+ sudoCommand: ALL
+ sudoOrder: 100
+
+ In the LDAP version, the sudoOrder attribute is used to guarantee that
+ the PAGERS sudoRole with _n_o_e_x_e_c has precedence. Unlike the _s_u_d_o_e_r_s
+ version, the LDAP version requires that all users for whom the
+ restriction should apply be assigned to the PAGERS sudoRole. Using a
+ Unix group or netgroup in PAGERS rather than listing each user would make
+ this easier to maintain.
+
+ Per-user Defaults entries can be emulated by using one or more sudoOption
+ attributes in a sudoRole. Consider the following _s_u_d_o_e_r_s lines:
+
+ User_Alias ADMINS = john, sally
+ Defaults:ADMINS !authenticate
+ ADMINS ALL = (ALL:ALL) ALL
+
+ In this example, john and sally are allowed to run any command as any
+ user or group.
+
+ When converting this to LDAP, we can use a Unix group instead of the
+ User_Alias.
+
+ dn: cn=admins,ou=SUDOers,dc=my-domain,dc=com
+ objectClass: top
+ objectClass: sudoRole
+ cn: admins
+ sudoUser: %admin
+ sudoHost: ALL
+ sudoRunAsUser: ALL
+ sudoRunAsGroup: ALL
+ sudoCommand: ALL
+ sudoOption: !authenticate
+
+ This assumes that users john and sally are members of the "admins" Unix
+ group.
+
+ SSuuddooeerrss sscchheemmaa
+ In order to use ssuuddoo's LDAP support, the ssuuddoo schema must be installed on
+ your LDAP server. In addition, be sure to index the sudoUser attribute.
+
+ The ssuuddoo distribution includes versions of the ssuuddooeerrss schema for
+ multiple LDAP servers:
+
+ _s_c_h_e_m_a_._O_p_e_n_L_D_A_P
+ OpenLDAP slapd and OpenBSD ldapd
+
+ _s_c_h_e_m_a_._o_l_c_S_u_d_o
+ OpenLDAP slapd 2.3 and higher when on-line configuration is enabled
+
+ _s_c_h_e_m_a_._i_P_l_a_n_e_t
+ Netscape-derived servers such as the iPlanet, Oracle, and 389
+ Directory Servers
+
+ _s_c_h_e_m_a_._A_c_t_i_v_e_D_i_r_e_c_t_o_r_y
+ Microsoft Active Directory
+
+ The schema in OpenLDAP format is also included in the _E_X_A_M_P_L_E_S section.
+
+ CCoonnffiigguurriinngg llddaapp..ccoonnff
+ Sudo reads the _/_e_t_c_/_l_d_a_p_._c_o_n_f file for LDAP-specific configuration.
+ Typically, this file is shared between different LDAP-aware clients. As
+ such, most of the settings are not ssuuddoo-specific. Note that ssuuddoo parses
+ _/_e_t_c_/_l_d_a_p_._c_o_n_f itself and may support options that differ from those
+ described in the system's ldap.conf(4) manual. The path to _l_d_a_p_._c_o_n_f may
+ be overridden via the _l_d_a_p___c_o_n_f plugin argument in sudo.conf(4).
+
+ Also note that on systems using the OpenLDAP libraries, default values
+ specified in _/_e_t_c_/_o_p_e_n_l_d_a_p_/_l_d_a_p_._c_o_n_f or the user's _._l_d_a_p_r_c files are not
+ used.
+
+ Only those options explicitly listed in _/_e_t_c_/_l_d_a_p_._c_o_n_f as being supported
+ by ssuuddoo are honored. Configuration options are listed below in upper
+ case but are parsed in a case-independent manner.
+
+ Lines beginning with a pound sign (`#') are ignored. Leading white space
+ is removed from the beginning of lines.
+
+ BBIINNDD__TTIIMMEELLIIMMIITT _s_e_c_o_n_d_s
+ The BBIINNDD__TTIIMMEELLIIMMIITT parameter specifies the amount of time, in
+ seconds, to wait while trying to connect to an LDAP server. If
+ multiple UURRIIs or HHOOSSTTs are specified, this is the amount of time to
+ wait before trying the next one in the list.
+
+ BBIINNDDDDNN _D_N
+ The BBIINNDDDDNN parameter specifies the identity, in the form of a
+ Distinguished Name (DN), to use when performing LDAP operations.
+ If not specified, LDAP operations are performed with an anonymous
+ identity. By default, most LDAP servers will allow anonymous
+ access.
+
+ BBIINNDDPPWW _s_e_c_r_e_t
+ The BBIINNDDPPWW parameter specifies the password to use when performing
+ LDAP operations. This is typically used in conjunction with the
+ BBIINNDDDDNN parameter. The _s_e_c_r_e_t may be a plain text password or a
+ base64-encoded string with a "base64:" prefix. For example:
+
+ BINDPW base64:dGVzdA==
+
+ If a plain text password is used, it should be a simple string
+ without quotes. Plain text passwords may not include the comment
+ character (`#') and the escaping of special characters with a
+ backslash (`\') is not supported.
+
+ DDEERREEFF _n_e_v_e_r_/_s_e_a_r_c_h_i_n_g_/_f_i_n_d_i_n_g_/_a_l_w_a_y_s
+ How alias dereferencing is to be performed when searching. See the
+ ldap.conf(4) manual for a full description of this option.
+
+ HHOOSSTT _n_a_m_e_[_:_p_o_r_t_] _._._.
+ If no UURRII is specified (see below), the HHOOSSTT parameter specifies a
+ white space-delimited list of LDAP servers to connect to. Each
+ host may include an optional _p_o_r_t separated by a colon (`:'). The
+ HHOOSSTT parameter is deprecated in favor of the UURRII specification and
+ is included for backwards compatibility only.
+
+ KKRRBB55__CCCCNNAAMMEE _f_i_l_e _n_a_m_e
+ The path to the Kerberos 5 credential cache to use when
+ authenticating with the remote server. This option is only
+ relevant when using SASL authentication (see below).
+
+ LLDDAAPP__VVEERRSSIIOONN _n_u_m_b_e_r
+ The version of the LDAP protocol to use when connecting to the
+ server. The default value is protocol version 3.
+
+ NNEETTGGRROOUUPP__BBAASSEE _b_a_s_e
+ The base DN to use when performing LDAP netgroup queries.
+ Typically this is of the form ou=netgroup,dc=my-domain,dc=com for
+ the domain my-domain.com. Multiple NNEETTGGRROOUUPP__BBAASSEE lines may be
+ specified, in which case they are queried in the order specified.
+
+ This option can be used to query a user's netgroups directly via
+ LDAP which is usually faster than fetching every sudoRole object
+ containing a sudoUser that begins with a `+' prefix. The NIS
+ schema used by some LDAP servers need a modification to support
+ querying the nisNetgroup object by its nisNetgroupTriple member.
+ OpenLDAP's ssllaappdd requires the following change to the
+ nisNetgroupTriple attribute:
+
+ attributetype ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
+ DESC 'Netgroup triple'
+ EQUALITY caseIgnoreIA5Match
+ SUBSTR caseIgnoreIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+ NNEETTGGRROOUUPP__SSEEAARRCCHH__FFIILLTTEERR _l_d_a_p___f_i_l_t_e_r
+ An LDAP filter which is used to restrict the set of records
+ returned when performing an LDAP netgroup query. Typically, this
+ is of the form attribute=value or
+ (&(attribute=value)(attribute2=value2)). The default search filter
+ is: objectClass=nisNetgroup. If _l_d_a_p___f_i_l_t_e_r is omitted, no search
+ filter will be used. This option is only when querying netgroups
+ directly via LDAP.
+
+ NNEETTWWOORRKK__TTIIMMEEOOUUTT _s_e_c_o_n_d_s
+ An alias for BBIINNDD__TTIIMMEELLIIMMIITT provided for OpenLDAP compatibility.
+
+ PPOORRTT _p_o_r_t___n_u_m_b_e_r
+ If no UURRII is specified, the PPOORRTT parameter specifies the default
+ port to connect to on the LDAP server if a HHOOSSTT parameter does not
+ specify the port itself. If no PPOORRTT parameter is used, the default
+ is port 389 for LDAP and port 636 for LDAP over TLS (SSL). The
+ PPOORRTT parameter is deprecated in favor of the UURRII specification and
+ is included for backwards compatibility only.
+
+ RROOOOTTBBIINNDDDDNN _D_N
+ The RROOOOTTBBIINNDDDDNN parameter specifies the identity, in the form of a
+ Distinguished Name (DN), to use when performing privileged LDAP
+ operations, such as _s_u_d_o_e_r_s queries. The password corresponding to
+ the identity should be stored in the or the path specified by the
+ _l_d_a_p___s_e_c_r_e_t plugin argument in sudo.conf(4), which defaults to
+ _/_e_t_c_/_l_d_a_p_._s_e_c_r_e_t. If no RROOOOTTBBIINNDDDDNN is specified, the BBIINNDDDDNN
+ identity is used (if any).
+
+ RROOOOTTUUSSEE__SSAASSLL _o_n_/_t_r_u_e_/_y_e_s_/_o_f_f_/_f_a_l_s_e_/_n_o
+ Enable RROOOOTTUUSSEE__SSAASSLL to enable SASL authentication when connecting
+ to an LDAP server from a privileged process, such as ssuuddoo.
+
+ SSAASSLL__AAUUTTHH__IIDD _i_d_e_n_t_i_t_y
+ The SASL user name to use when connecting to the LDAP server. By
+ default, ssuuddoo will use an anonymous connection. This option is
+ only relevant when using SASL authentication.
+
+ SSAASSLL__MMEECCHH _m_e_c_h_a_n_i_s_m_s
+ A white space-delimited list of SASL authentication mechanisms to
+ use. By default, ssuuddoo will use GSSAPI authentication.
+
+ SSAASSLL__SSEECCPPRROOPPSS _n_o_n_e_/_p_r_o_p_e_r_t_i_e_s
+ SASL security properties or _n_o_n_e for no properties. See the SASL
+ programmer's manual for details. This option is only relevant when
+ using SASL authentication.
+
+ SSSSLL _o_n_/_t_r_u_e_/_y_e_s_/_o_f_f_/_f_a_l_s_e_/_n_o
+ If the SSSSLL parameter is set to on, true or yes, TLS (SSL)
+ encryption is always used when communicating with the LDAP server.
+ Typically, this involves connecting to the server on port 636
+ (ldaps).
+
+ SSSSLL _s_t_a_r_t___t_l_s
+ If the SSSSLL parameter is set to start_tls, the LDAP server
+ connection is initiated normally and TLS encryption is begun before
+ the bind credentials are sent. This has the advantage of not
+ requiring a dedicated port for encrypted communications. This
+ parameter is only supported by LDAP servers that honor the
+ _s_t_a_r_t___t_l_s extension, such as the OpenLDAP and Tivoli Directory
+ servers.
+
+ SSUUDDOOEERRSS__BBAASSEE _b_a_s_e
+ The base DN to use when performing ssuuddoo LDAP queries. Typically
+ this is of the form ou=SUDOers,dc=my-domain,dc=com for the domain
+ my-domain.com. Multiple SSUUDDOOEERRSS__BBAASSEE lines may be specified, in
+ which case they are queried in the order specified.
+
+ SSUUDDOOEERRSS__DDEEBBUUGG _d_e_b_u_g___l_e_v_e_l
+ This sets the debug level for ssuuddoo LDAP queries. Debugging
+ information is printed to the standard error. A value of 1 results
+ in a moderate amount of debugging information. A value of 2 shows
+ the results of the matches themselves. This parameter should not
+ be set in a production environment as the extra information is
+ likely to confuse users.
+
+ The SSUUDDOOEERRSS__DDEEBBUUGG parameter is deprecated and will be removed in a
+ future release. The same information is now logged via the ssuuddoo
+ debugging framework using the "ldap" subsystem at priorities _d_i_a_g
+ and _i_n_f_o for _d_e_b_u_g___l_e_v_e_l values 1 and 2 respectively. See the
+ sudo.conf(4) manual for details on how to configure ssuuddoo debugging.
+
+ SSUUDDOOEERRSS__SSEEAARRCCHH__FFIILLTTEERR _l_d_a_p___f_i_l_t_e_r
+ An LDAP filter which is used to restrict the set of records
+ returned when performing a ssuuddoo LDAP query. Typically, this is of
+ the form attribute=value or
+ (&(attribute=value)(attribute2=value2)). The default search filter
+ is: objectClass=sudoRole. If _l_d_a_p___f_i_l_t_e_r is omitted, no search
+ filter will be used.
+
+ SSUUDDOOEERRSS__TTIIMMEEDD _o_n_/_t_r_u_e_/_y_e_s_/_o_f_f_/_f_a_l_s_e_/_n_o
+ Whether or not to evaluate the sudoNotBefore and sudoNotAfter
+ attributes that implement time-dependent sudoers entries.
+
+ TTIIMMEELLIIMMIITT _s_e_c_o_n_d_s
+ The TTIIMMEELLIIMMIITT parameter specifies the amount of time, in seconds,
+ to wait for a response to an LDAP query.
+
+ TTIIMMEEOOUUTT _s_e_c_o_n_d_s
+ The TTIIMMEEOOUUTT parameter specifies the amount of time, in seconds, to
+ wait for a response from the various LDAP APIs.
+
+ TTLLSS__CCAACCEERRTT _f_i_l_e _n_a_m_e
+ An alias for TTLLSS__CCAACCEERRTTFFIILLEE for OpenLDAP compatibility.
+
+ TTLLSS__CCAACCEERRTTFFIILLEE _f_i_l_e _n_a_m_e
+ The path to a certificate authority bundle which contains the
+ certificates for all the Certificate Authorities the client knows
+ to be valid, e.g., _/_e_t_c_/_s_s_l_/_c_a_-_b_u_n_d_l_e_._p_e_m. This option is only
+ supported by the OpenLDAP libraries. Netscape-derived LDAP
+ libraries use the same certificate database for CA and client
+ certificates (see TTLLSS__CCEERRTT).
+
+ TTLLSS__CCAACCEERRTTDDIIRR _d_i_r_e_c_t_o_r_y
+ Similar to TTLLSS__CCAACCEERRTTFFIILLEE but instead of a file, it is a directory
+ containing individual Certificate Authority certificates, e.g.,
+ _/_e_t_c_/_s_s_l_/_c_e_r_t_s. The directory specified by TTLLSS__CCAACCEERRTTDDIIRR is
+ checked after TTLLSS__CCAACCEERRTTFFIILLEE. This option is only supported by the
+ OpenLDAP libraries.
+
+ TTLLSS__CCEERRTT _f_i_l_e _n_a_m_e
+ The path to a file containing the client certificate which can be
+ used to authenticate the client to the LDAP server. The
+ certificate type depends on the LDAP libraries used.
+
+ OpenLDAP:
+ tls_cert /etc/ssl/client_cert.pem
+
+ Netscape-derived:
+ tls_cert /var/ldap/cert7.db
+
+ Tivoli Directory Server:
+ Unused, the key database specified by TTLLSS__KKEEYY contains both
+ keys and certificates.
+
+ When using Netscape-derived libraries, this file may also
+ contain Certificate Authority certificates.
+
+ TTLLSS__CCHHEECCKKPPEEEERR _o_n_/_t_r_u_e_/_y_e_s_/_o_f_f_/_f_a_l_s_e_/_n_o
+ If enabled, TTLLSS__CCHHEECCKKPPEEEERR will cause the LDAP server's TLS
+ certificated to be verified. If the server's TLS certificate
+ cannot be verified (usually because it is signed by an unknown
+ certificate authority), ssuuddoo will be unable to connect to it. If
+ TTLLSS__CCHHEECCKKPPEEEERR is disabled, no check is made. Note that disabling
+ the check creates an opportunity for man-in-the-middle attacks
+ since the server's identity will not be authenticated. If
+ possible, the CA's certificate should be installed locally so it
+ can be verified. This option is not supported by the Tivoli
+ Directory Server LDAP libraries.
+
+ TTLLSS__KKEEYY _f_i_l_e _n_a_m_e
+ The path to a file containing the private key which matches the
+ certificate specified by TTLLSS__CCEERRTT. The private key must not be
+ password-protected. The key type depends on the LDAP libraries
+ used.
+
+ OpenLDAP:
+ tls_key /etc/ssl/client_key.pem
+
+ Netscape-derived:
+ tls_key /var/ldap/key3.db
+
+ Tivoli Directory Server:
+ tls_key /usr/ldap/ldapkey.kdb
+ When using Tivoli LDAP libraries, this file may also contain
+ Certificate Authority and client certificates and may be encrypted.
+
+ TTLLSS__CCIIPPHHEERRSS _c_i_p_h_e_r _l_i_s_t
+ The TTLLSS__CCIIPPHHEERRSS parameter allows the administer to restrict which
+ encryption algorithms may be used for TLS (SSL) connections. See
+ the OpenLDAP or Tivoli Directory Server manual for a list of valid
+ ciphers. This option is not supported by Netscape-derived
+ libraries.
+
+ TTLLSS__KKEEYYPPWW _s_e_c_r_e_t
+ The TTLLSS__KKEEYYPPWW contains the password used to decrypt the key
+ database on clients using the Tivoli Directory Server LDAP library.
+ The _s_e_c_r_e_t may be a plain text password or a base64-encoded string
+ with a "base64:" prefix. For example:
+
+ TLS_KEYPW base64:dGVzdA==
+
+ If a plain text password is used, it should be a simple string
+ without quotes. Plain text passwords may not include the comment
+ character (`#') and the escaping of special characters with a
+ backslash (`\') is not supported. If this option is used,
+ _/_e_t_c_/_l_d_a_p_._c_o_n_f must not be world-readable to avoid exposing the
+ password. Alternately, a _s_t_a_s_h _f_i_l_e can be used to store the
+ password in encrypted form (see below).
+
+ If no TTLLSS__KKEEYYPPWW is specified, a _s_t_a_s_h _f_i_l_e will be used if it
+ exists. The _s_t_a_s_h _f_i_l_e must have the same path as the file
+ specified by TTLLSS__KKEEYY, but use a .sth file extension instead of
+ .kdb, e.g., ldapkey.sth. The default ldapkey.kdb that ships with
+ Tivoli Directory Server is encrypted with the password
+ ssl_password. The _g_s_k_8_c_a_p_i_c_m_d utility can be used to manage the
+ key database and create a _s_t_a_s_h _f_i_l_e. This option is only
+ supported by the Tivoli LDAP libraries.
+
+ TTLLSS__RREEQQCCEERRTT _l_e_v_e_l
+ The TTLLSS__RREEQQCCEERRTT parameter controls how the LDAP server's TLS
+ certificated will be verified (if at all). If the server's TLS
+ certificate cannot be verified (usually because it is signed by an
+ unknown certificate authority), ssuuddoo will be unable to connect to
+ it. The following _l_e_v_e_l values are supported:
+
+ never The server certificate will not be requested or
+ checked.
+
+ allow The server certificate will be requested. A missing
+ or invalid certificate is ignored and not considered
+ an error.
+
+ try The server certificate will be requested. A missing
+ certificate is ignored but an invalid certificate
+ will result in a connection error.
+
+ demand | _h_a_r_d
+ The server certificate will be requested. A missing
+ or invalid certificate will result in a connection
+ error. This is the default behavior.
+
+ This option is only supported by the OpenLDAP libraries. Other
+ LDAP libraries only support the TTLLSS__CCHHEECCKKPPEEEERR parameter.
+
+ TTLLSS__RRAANNDDFFIILLEE _f_i_l_e _n_a_m_e
+ The TTLLSS__RRAANNDDFFIILLEE parameter specifies the path to an entropy source
+ for systems that lack a random device. It is generally used in
+ conjunction with _p_r_n_g_d or _e_g_d. This option is only supported by
+ the OpenLDAP libraries.
+
+ UURRII _l_d_a_p_[_s_]_:_/_/_[_h_o_s_t_n_a_m_e_[_:_p_o_r_t_]_] _._._.
+ Specifies a white space-delimited list of one or more URIs
+ describing the LDAP server(s) to connect to. The _p_r_o_t_o_c_o_l may be
+ either _l_d_a_p _l_d_a_p_s, the latter being for servers that support TLS
+ (SSL) encryption. If no _p_o_r_t is specified, the default is port 389
+ for ldap:// or port 636 for ldaps://. If no _h_o_s_t_n_a_m_e is specified,
+ ssuuddoo will connect to _l_o_c_a_l_h_o_s_t. Multiple UURRII lines are treated
+ identically to a UURRII line containing multiple entries. Only
+ systems using the OpenSSL libraries support the mixing of ldap://
+ and ldaps:// URIs. Both the Netscape-derived and Tivoli LDAP
+ libraries used on most commercial versions of Unix are only capable
+ of supporting one or the other.
+
+ UUSSEE__SSAASSLL _o_n_/_t_r_u_e_/_y_e_s_/_o_f_f_/_f_a_l_s_e_/_n_o
+ Enable UUSSEE__SSAASSLL for LDAP servers that support SASL authentication.
+
+ RROOOOTTSSAASSLL__AAUUTTHH__IIDD _i_d_e_n_t_i_t_y
+ The SASL user name to use when RROOOOTTUUSSEE__SSAASSLL is enabled.
+
+ See the _l_d_a_p_._c_o_n_f entry in the _E_X_A_M_P_L_E_S section.
+
+ CCoonnffiigguurriinngg nnsssswwiittcchh..ccoonnff
+ Unless it is disabled at build time, ssuuddoo consults the Name Service
+ Switch file, _/_e_t_c_/_n_s_s_w_i_t_c_h_._c_o_n_f, to specify the _s_u_d_o_e_r_s search order.
+ Sudo looks for a line beginning with sudoers: and uses this to determine
+ the search order. Note that ssuuddoo does not stop searching after the first
+ match and later matches take precedence over earlier ones. The following
+ sources are recognized:
+
+ files read sudoers from _/_e_t_c_/_s_u_d_o_e_r_s
+ ldap read sudoers from LDAP
+
+ In addition, the entry [NOTFOUND=return] will short-circuit the search if
+ the user was not found in the preceding source.
+
+ To consult LDAP first followed by the local sudoers file (if it exists),
+ use:
+
+ sudoers: ldap files
+
+ The local _s_u_d_o_e_r_s file can be ignored completely by using:
+
+ sudoers: ldap
+
+ If the _/_e_t_c_/_n_s_s_w_i_t_c_h_._c_o_n_f file is not present or there is no sudoers
+ line, the following default is assumed:
+
+ sudoers: files
+
+ Note that _/_e_t_c_/_n_s_s_w_i_t_c_h_._c_o_n_f is supported even when the underlying
+ operating system does not use an nsswitch.conf file, except on AIX (see
+ below).
+
+ CCoonnffiigguurriinngg nneettssvvcc..ccoonnff
+ On AIX systems, the _/_e_t_c_/_n_e_t_s_v_c_._c_o_n_f file is consulted instead of
+ _/_e_t_c_/_n_s_s_w_i_t_c_h_._c_o_n_f. ssuuddoo simply treats _n_e_t_s_v_c_._c_o_n_f as a variant of
+ _n_s_s_w_i_t_c_h_._c_o_n_f; information in the previous section unrelated to the file
+ format itself still applies.
+
+ To consult LDAP first followed by the local sudoers file (if it exists),
+ use:
+
+ sudoers = ldap, files
+
+ The local _s_u_d_o_e_r_s file can be ignored completely by using:
+
+ sudoers = ldap
+
+ To treat LDAP as authoritative and only use the local sudoers file if the
+ user is not present in LDAP, use:
+
+ sudoers = ldap = auth, files
+
+ Note that in the above example, the auth qualifier only affects user
+ lookups; both LDAP and _s_u_d_o_e_r_s will be queried for Defaults entries.
+
+ If the _/_e_t_c_/_n_e_t_s_v_c_._c_o_n_f file is not present or there is no sudoers line,
+ the following default is assumed:
+
+ sudoers = files
+
+ IInntteeggrraattiioonn wwiitthh ssssssdd
+ On systems with the _S_y_s_t_e_m _S_e_c_u_r_i_t_y _S_e_r_v_i_c_e_s _D_a_e_m_o_n (SSSD) and where ssuuddoo
+ has been built with SSSD support, it is possible to use SSSD to cache
+ LDAP _s_u_d_o_e_r_s rules. To use SSSD as the _s_u_d_o_e_r_s source, you should use
+ sssd instead of ldap for the sudoers entry in _/_e_t_c_/_n_s_s_w_i_t_c_h_._c_o_n_f. Note
+ that the _/_e_t_c_/_l_d_a_p_._c_o_n_f file is not used by the SSSD ssuuddoo back end.
+ Please see sssd-sudo(4) for more information on configuring ssuuddoo to work
+ with SSSD.
+
+FFIILLEESS
+ _/_e_t_c_/_l_d_a_p_._c_o_n_f LDAP configuration file
+
+ _/_e_t_c_/_n_s_s_w_i_t_c_h_._c_o_n_f determines sudoers source order
+
+ _/_e_t_c_/_n_e_t_s_v_c_._c_o_n_f determines sudoers source order on AIX
+
+EEXXAAMMPPLLEESS
+ EExxaammppllee llddaapp..ccoonnff
+ # Either specify one or more URIs or one or more host:port pairs.
+ # If neither is specified sudo will default to localhost, port 389.
+ #
+ #host ldapserver
+ #host ldapserver1 ldapserver2:390
+ #
+ # Default port if host is specified without one, defaults to 389.
+ #port 389
+ #
+ # URI will override the host and port settings.
+ uri ldap://ldapserver
+ #uri ldaps://secureldapserver
+ #uri ldaps://secureldapserver ldap://ldapserver
+ #
+ # The amount of time, in seconds, to wait while trying to connect to
+ # an LDAP server.
+ bind_timelimit 30
+ #
+ # The amount of time, in seconds, to wait while performing an LDAP query.
+ timelimit 30
+ #
+ # Must be set or sudo will ignore LDAP; may be specified multiple times.
+ sudoers_base ou=SUDOers,dc=my-domain,dc=com
+ #
+ # verbose sudoers matching from ldap
+ #sudoers_debug 2
+ #
+ # Enable support for time-based entries in sudoers.
+ #sudoers_timed yes
+ #
+ # optional proxy credentials
+ #binddn <who to search as>
+ #bindpw <password>
+ #rootbinddn <who to search as, uses /etc/ldap.secret for bindpw>
+ #
+ # LDAP protocol version, defaults to 3
+ #ldap_version 3
+ #
+ # Define if you want to use an encrypted LDAP connection.
+ # Typically, you must also set the port to 636 (ldaps).
+ #ssl on
+ #
+ # Define if you want to use port 389 and switch to
+ # encryption before the bind credentials are sent.
+ # Only supported by LDAP servers that support the start_tls
+ # extension such as OpenLDAP.
+ #ssl start_tls
+ #
+ # Additional TLS options follow that allow tweaking of the
+ # SSL/TLS connection.
+ #
+ #tls_checkpeer yes # verify server SSL certificate
+ #tls_checkpeer no # ignore server SSL certificate
+ #
+ # If you enable tls_checkpeer, specify either tls_cacertfile
+ # or tls_cacertdir. Only supported when using OpenLDAP.
+ #
+ #tls_cacertfile /etc/certs/trusted_signers.pem
+ #tls_cacertdir /etc/certs
+ #
+ # For systems that don't have /dev/random
+ # use this along with PRNGD or EGD.pl to seed the
+ # random number pool to generate cryptographic session keys.
+ # Only supported when using OpenLDAP.
+ #
+ #tls_randfile /etc/egd-pool
+ #
+ # You may restrict which ciphers are used. Consult your SSL
+ # documentation for which options go here.
+ # Only supported when using OpenLDAP.
+ #
+ #tls_ciphers <cipher-list>
+ #
+ # Sudo can provide a client certificate when communicating to
+ # the LDAP server.
+ # Tips:
+ # * Enable both lines at the same time.
+ # * Do not password protect the key file.
+ # * Ensure the keyfile is only readable by root.
+ #
+ # For OpenLDAP:
+ #tls_cert /etc/certs/client_cert.pem
+ #tls_key /etc/certs/client_key.pem
+ #
+ # For SunONE or iPlanet LDAP, tls_cert and tls_key may specify either
+ # a directory, in which case the files in the directory must have the
+ # default names (e.g., cert8.db and key4.db), or the path to the cert
+ # and key files themselves. However, a bug in version 5.0 of the LDAP
+ # SDK will prevent specific file names from working. For this reason
+ # it is suggested that tls_cert and tls_key be set to a directory,
+ # not a file name.
+ #
+ # The certificate database specified by tls_cert may contain CA certs
+ # and/or the client's cert. If the client's cert is included, tls_key
+ # should be specified as well.
+ # For backward compatibility, "sslpath" may be used in place of tls_cert.
+ #tls_cert /var/ldap
+ #tls_key /var/ldap
+ #
+ # If using SASL authentication for LDAP (OpenSSL)
+ # use_sasl yes
+ # sasl_auth_id <SASL user name>
+ # rootuse_sasl yes
+ # rootsasl_auth_id <SASL user name for root access>
+ # sasl_secprops none
+ # krb5_ccname /etc/.ldapcache
+
+ SSuuddooeerrss sscchheemmaa ffoorr OOppeennLLDDAAPP
+ The following schema, in OpenLDAP format, is included with ssuuddoo source
+ and binary distributions as _s_c_h_e_m_a_._O_p_e_n_L_D_A_P. Simply copy it to the
+ schema directory (e.g., _/_e_t_c_/_o_p_e_n_l_d_a_p_/_s_c_h_e_m_a), add the proper include
+ line in _s_l_a_p_d_._c_o_n_f and restart ssllaappdd. Sites using the optional on-line
+ configuration supported by OpenLDAP 2.3 and higher should apply the
+ _s_c_h_e_m_a_._o_l_c_S_u_d_o file instead.
+
+ attributetype ( 1.3.6.1.4.1.15953.9.1.1
+ NAME 'sudoUser'
+ DESC 'User(s) who may run sudo'
+ EQUALITY caseExactIA5Match
+ SUBSTR caseExactIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+ attributetype ( 1.3.6.1.4.1.15953.9.1.2
+ NAME 'sudoHost'
+ DESC 'Host(s) who may run sudo'
+ EQUALITY caseExactIA5Match
+ SUBSTR caseExactIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+ attributetype ( 1.3.6.1.4.1.15953.9.1.3
+ NAME 'sudoCommand'
+ DESC 'Command(s) to be executed by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+ attributetype ( 1.3.6.1.4.1.15953.9.1.4
+ NAME 'sudoRunAs'
+ DESC 'User(s) impersonated by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+ attributetype ( 1.3.6.1.4.1.15953.9.1.5
+ NAME 'sudoOption'
+ DESC 'Options(s) followed by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+ attributetype ( 1.3.6.1.4.1.15953.9.1.6
+ NAME 'sudoRunAsUser'
+ DESC 'User(s) impersonated by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+ attributetype ( 1.3.6.1.4.1.15953.9.1.7
+ NAME 'sudoRunAsGroup'
+ DESC 'Group(s) impersonated by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+ attributetype ( 1.3.6.1.4.1.15953.9.1.8
+ NAME 'sudoNotBefore'
+ DESC 'Start of time interval for which the entry is valid'
+ EQUALITY generalizedTimeMatch
+ ORDERING generalizedTimeOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
+
+ attributetype ( 1.3.6.1.4.1.15953.9.1.9
+ NAME 'sudoNotAfter'
+ DESC 'End of time interval for which the entry is valid'
+ EQUALITY generalizedTimeMatch
+ ORDERING generalizedTimeOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
+
+ attributetype ( 1.3.6.1.4.1.15953.9.1.10
+ NAME 'sudoOrder'
+ DESC 'an integer to order the sudoRole entries'
+ EQUALITY integerMatch
+ ORDERING integerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+ objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL
+ DESC 'Sudoer Entries'
+ MUST ( cn )
+ MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $
+ sudoRunAsGroup $ sudoOption $ sudoNotBefore $ sudoNotAfter $
+ sudoOrder $ description )
+ )
+
+SSEEEE AALLSSOO
+ cvtsudoers(1), ldap.conf(4), sssd-sudo(4), sudo.conf(4), sudoers(4)
+
+AAUUTTHHOORRSS
+ Many people have worked on ssuuddoo over the years; this version consists of
+ code written primarily by:
+
+ Todd C. Miller
+
+ See the CONTRIBUTORS file in the ssuuddoo distribution
+ (https://www.sudo.ws/contributors.html) for an exhaustive list of people
+ who have contributed to ssuuddoo.
+
+CCAAVVEEAATTSS
+ Note that there are differences in the way that LDAP-based _s_u_d_o_e_r_s is
+ parsed compared to file-based _s_u_d_o_e_r_s. See the _D_i_f_f_e_r_e_n_c_e_s _b_e_t_w_e_e_n _L_D_A_P
+ _a_n_d _n_o_n_-_L_D_A_P _s_u_d_o_e_r_s section for more information.
+
+BBUUGGSS
+ If you feel you have found a bug in ssuuddoo, please submit a bug report at
+ https://bugzilla.sudo.ws/
+
+SSUUPPPPOORRTT
+ Limited free support is available via the sudo-users mailing list, see
+ https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search
+ the archives.
+
+DDIISSCCLLAAIIMMEERR
+ ssuuddoo is provided "AS IS" and any express or implied warranties,
+ including, but not limited to, the implied warranties of merchantability
+ and fitness for a particular purpose are disclaimed. See the LICENSE
+ file distributed with ssuuddoo or https://www.sudo.ws/license.html for
+ complete details.
+
+Sudo 1.8.26 November 9, 2018 Sudo 1.8.26
diff --git a/doc/sudoers.ldap.man.in b/doc/sudoers.ldap.man.in
new file mode 100644
index 0000000..a767d64
--- /dev/null
+++ b/doc/sudoers.ldap.man.in
@@ -0,0 +1,1712 @@
+.\" Automatically generated from an mdoc input file. Do not edit.
+.\"
+.\" Copyright (c) 2003-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "SUDOERS.LDAP" "@mansectform@" "November 9, 2018" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
+.nh
+.if n .ad l
+.SH "NAME"
+\fBsudoers.ldap\fR
+\- sudo LDAP configuration
+.SH "DESCRIPTION"
+In addition to the standard
+\fIsudoers\fR
+file,
+\fBsudo\fR
+may be configured
+via LDAP.
+This can be especially useful for synchronizing
+\fIsudoers\fR
+in a large, distributed environment.
+.PP
+Using LDAP for
+\fIsudoers\fR
+has several benefits:
+.TP 3n
+\fB\(bu\fR
+\fBsudo\fR
+no longer needs to read
+\fIsudoers\fR
+in its entirety.
+When LDAP is used, there are only two or three LDAP queries per invocation.
+This makes it especially fast and particularly usable in LDAP environments.
+.TP 3n
+\fB\(bu\fR
+\fBsudo\fR
+no longer exits if there is a typo in
+\fIsudoers\fR.
+It is not possible to load LDAP data into the server that does
+not conform to the sudoers schema, so proper syntax is guaranteed.
+It is still possible to have typos in a user or host name, but
+this will not prevent
+\fBsudo\fR
+from running.
+.TP 3n
+\fB\(bu\fR
+It is possible to specify per-entry options that override the global
+default options.
+\fI@sysconfdir@/sudoers\fR
+only supports default options and limited options associated with
+user/host/commands/aliases.
+The syntax is complicated and can be difficult for users to understand.
+Placing the options directly in the entry is more natural.
+.TP 3n
+\fB\(bu\fR
+The
+\fBvisudo\fR
+program is no longer needed.
+\fBvisudo\fR
+provides locking and syntax checking of the
+\fI@sysconfdir@/sudoers\fR
+file.
+Since LDAP updates are atomic, locking is no longer necessary.
+Because syntax is checked when the data is inserted into LDAP, there
+is no need for a specialized tool to check syntax.
+.SS "SUDOers LDAP container"
+The
+\fIsudoers\fR
+configuration is contained in the
+\fRou=SUDOers\fR
+LDAP container.
+.PP
+Sudo first looks for the
+\fRcn=defaults\fR
+entry in the SUDOers container.
+If found, the multi-valued
+\fRsudoOption\fR
+attribute is parsed in the same manner as a global
+\fRDefaults\fR
+line in
+\fI@sysconfdir@/sudoers\fR.
+In the following example, the
+\fRSSH_AUTH_SOCK\fR
+variable will be preserved in the environment for all users.
+.nf
+.sp
+.RS 4n
+dn: cn=defaults,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption: env_keep+=SSH_AUTH_SOCK
+.RE
+.fi
+.PP
+The equivalent of a sudoer in LDAP is a
+\fRsudoRole\fR.
+It consists of the following attributes:
+.TP 6n
+\fBsudoUser\fR
+A user name, user ID (prefixed with
+\(oq#\(cq),
+Unix group name or ID (prefixed with
+\(oq%\(cq
+or
+\(oq%#\(cq
+respectively), user netgroup (prefixed with
+\(oq+\(cq),
+or non-Unix group name or ID (prefixed with
+\(oq%:\(cq
+or
+\(oq%:#\(cq
+respectively).
+User netgroups are matched using the user and domain members only;
+the host member is not used when matching.
+Non-Unix group support is only available when an appropriate
+\fIgroup_plugin\fR
+is defined in the global
+\fIdefaults\fR
+\fRsudoRole\fR
+object.
+.TP 6n
+\fBsudoHost\fR
+A host name, IP address, IP network, or host netgroup (prefixed with a
+\(oq+\(cq).
+The special value
+\fRALL\fR
+will match any host.
+Host netgroups are matched using the host (both qualified and unqualified)
+and domain members only; the user member is not used when matching.
+If a
+\fRsudoHost\fR
+entry is preceded by an exclamation point,
+\(oq\&!\(cq,
+and the entry matches, the
+\fRsudoRole\fR
+in which it resides will be ignored.
+Negated
+\fRsudoHost\fR
+entries are only supported by version 1.8.18 or higher.
+.TP 6n
+\fBsudoCommand\fR
+A fully-qualified Unix command name with optional command line arguments,
+potentially including globbing characters (aka wild cards).
+If a command name is preceded by an exclamation point,
+\(oq\&!\(cq,
+the user will be prohibited from running that command.
+.sp
+The built-in command
+\(lq\fRsudoedit\fR\(rq
+is used to permit a user to run
+\fBsudo\fR
+with the
+\fB\-e\fR
+option (or as
+\fBsudoedit\fR).
+It may take command line arguments just as a normal command does.
+Note that
+\(lq\fRsudoedit\fR\(rq
+is a command built into
+\fBsudo\fR
+itself and must be specified in without a leading path.
+.sp
+The special value
+\fRALL\fR
+will match any command.
+.sp
+If a command name is prefixed with a SHA-2 digest, it will
+only be allowed if the digest matches.
+This may be useful in situations where the user invoking
+\fBsudo\fR
+has write access to the command or its parent directory.
+The following digest formats are supported: sha224, sha256, sha384 and sha512.
+The digest name must be followed by a colon
+(\(oq:\&\(cq)
+and then the actual digest, in either hex or base64 format.
+For example, given the following value for sudoCommand:
+.nf
+.sp
+.RS 10n
+sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ /bin/ls
+.RE
+.fi
+.RS 6n
+.sp
+The user may only run
+\fI/bin/ls\fR
+if its sha224 digest matches the specified value.
+Command digests are only supported by version 1.8.7 or higher.
+.RE
+.TP 6n
+\fBsudoOption\fR
+Identical in function to the global options described above, but
+specific to the
+\fRsudoRole\fR
+in which it resides.
+.TP 6n
+\fBsudoRunAsUser\fR
+A user name or uid (prefixed with
+\(oq#\(cq)
+that commands may be run as or a Unix group (prefixed with a
+\(oq%\(cq)
+or user netgroup (prefixed with a
+\(oq+\(cq)
+that contains a list of users that commands may be run as.
+The special value
+\fRALL\fR
+will match any user.
+If a
+\fRsudoRunAsUser\fR
+entry is preceded by an exclamation point,
+\(oq\&!\(cq,
+and the entry matches, the
+\fRsudoRole\fR
+in which it resides will be ignored.
+If
+\fRsudoRunAsUser\fR
+is specified but empty, it will match the invoking user.
+If neither
+\fRsudoRunAsUser\fR
+nor
+\fRsudoRunAsGroup\fR
+are present, the value of the
+\fIrunas_default\fR
+\fRsudoOption\fR
+is used (defaults to
+\fR@runas_default@\fR).
+.sp
+The
+\fRsudoRunAsUser\fR
+attribute is only available in
+\fBsudo\fR
+versions
+1.7.0 and higher.
+Older versions of
+\fBsudo\fR
+use the
+\fRsudoRunAs\fR
+attribute instead.
+Negated
+\fRsudoRunAsUser\fR
+entries are only supported by version 1.8.26 or higher.
+.TP 6n
+\fBsudoRunAsGroup\fR
+A Unix group or gid (prefixed with
+\(oq#\(cq)
+that commands may be run as.
+The special value
+\fRALL\fR
+will match any group.
+If a
+\fRsudoRunAsGroup\fR
+entry is preceded by an exclamation point,
+\(oq\&!\(cq,
+and the entry matches, the
+\fRsudoRole\fR
+in which it resides will be ignored.
+.sp
+The
+\fRsudoRunAsGroup\fR
+attribute is only available in
+\fBsudo\fR
+versions
+1.7.0 and higher.
+Negated
+\fRsudoRunAsGroup\fR
+entries are only supported by version 1.8.26 or higher.
+.TP 6n
+\fBsudoNotBefore\fR
+A timestamp in the form
+\fRyyyymmddHHMMSSZ\fR
+that can be used to provide a start date/time for when the
+\fRsudoRole\fR
+will be valid.
+If multiple
+\fRsudoNotBefore\fR
+entries are present, the earliest is used.
+Note that timestamps must be in Coordinated Universal Time (UTC),
+not the local timezone.
+The minute and seconds portions are optional, but some LDAP servers
+require that they be present (contrary to the RFC).
+.sp
+The
+\fRsudoNotBefore\fR
+attribute is only available in
+\fBsudo\fR
+versions 1.7.5 and higher and must be explicitly enabled via the
+\fBSUDOERS_TIMED\fR
+option in
+\fI@ldap_conf@\fR.
+.TP 6n
+\fBsudoNotAfter\fR
+A timestamp in the form
+\fRyyyymmddHHMMSSZ\fR
+that indicates an expiration date/time, after which the
+\fRsudoRole\fR
+will no longer be valid.
+If multiple
+\fRsudoNotAfter\fR
+entries are present, the last one is used.
+Note that timestamps must be in Coordinated Universal Time (UTC),
+not the local timezone.
+The minute and seconds portions are optional, but some LDAP servers
+require that they be present (contrary to the RFC).
+.sp
+The
+\fRsudoNotAfter\fR
+attribute is only available in
+\fBsudo\fR
+versions
+1.7.5 and higher and must be explicitly enabled via the
+\fBSUDOERS_TIMED\fR
+option in
+\fI@ldap_conf@\fR.
+.TP 6n
+\fBsudoOrder\fR
+The
+\fRsudoRole\fR
+entries retrieved from the LDAP directory have no inherent order.
+The
+\fRsudoOrder\fR
+attribute is an integer (or floating point value for LDAP servers
+that support it) that is used to sort the matching entries.
+This allows LDAP-based sudoers entries to more closely mimic the behavior
+of the sudoers file, where the order of the entries influences the result.
+If multiple entries match, the entry with the highest
+\fRsudoOrder\fR
+attribute is chosen.
+This corresponds to the
+\(lqlast match\(rq
+behavior of the sudoers file.
+If the
+\fRsudoOrder\fR
+attribute is not present, a value of 0 is assumed.
+.sp
+The
+\fRsudoOrder\fR
+attribute is only available in
+\fBsudo\fR
+versions 1.7.5 and higher.
+.PP
+Each attribute listed above should contain a single value, but there
+may be multiple instances of each attribute type.
+A
+\fRsudoRole\fR
+must contain at least one
+\fRsudoUser\fR,
+\fRsudoHost\fR
+and
+\fRsudoCommand\fR.
+.PP
+The following example allows users in group wheel to run any command
+on any host via
+\fBsudo\fR:
+.nf
+.sp
+.RS 4n
+dn: cn=%wheel,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: %wheel
+sudoUser: %wheel
+sudoHost: ALL
+sudoCommand: ALL
+.RE
+.fi
+.SS "Anatomy of LDAP sudoers lookup"
+When looking up a sudoer using LDAP there are only two or three
+LDAP queries per invocation.
+The first query is to parse the global options.
+The second is to match against the user's name and the groups that
+the user belongs to.
+(The special
+\fRALL\fR
+tag is matched in this query too.)
+If no match is returned for the user's name and groups, a third
+query returns all entries containing user netgroups and other
+non-Unix groups and checks to see if the user belongs to any of them.
+.PP
+If timed entries are enabled with the
+\fBSUDOERS_TIMED\fR
+configuration directive, the LDAP queries include a sub-filter that
+limits retrieval to entries that satisfy the time constraints, if any.
+.PP
+If the
+\fBNETGROUP_BASE\fR
+configuration directive is present (see
+\fIConfiguring ldap.conf\fR
+below), queries are performed to determine
+the list of netgroups the user belongs to before the sudoers query.
+This makes it possible to include netgroups in the sudoers query
+string in the same manner as Unix groups.
+The third query mentioned above is not performed unless a group provider
+plugin is also configured.
+The actual LDAP queries performed by
+\fBsudo\fR
+are as follows:
+.TP 5n
+1.\&
+Match all
+\fRnisNetgroup\fR
+records with a
+\fRnisNetgroupTriple\fR
+containing the user, host and NIS domain.
+The query will match
+\fRnisNetgroupTriple\fR
+entries with either the short or long form of the host name or
+no host name specified in the tuple.
+If the NIS domain is set, the query will match only match entries
+that include the domain or for which there is no domain present.
+If the NIS domain is
+\fInot\fR
+set, a wildcard is used to match any domain name but be aware that the
+NIS schema used by some LDAP servers may not support wild cards for
+\fRnisNetgroupTriple\fR.
+.TP 5n
+2.\&
+Repeated queries are performed to find any nested
+\fRnisNetgroup\fR
+records with a
+\fRmemberNisNetgroup\fR
+entry that refers to an already-matched record.
+.PP
+For sites with a large number of netgroups, using
+\fBNETGROUP_BASE\fR
+can significantly speed up
+\fBsudo\fR's
+execution time.
+.SS "Differences between LDAP and non-LDAP sudoers"
+One of the major differences between LDAP and file-based
+\fIsudoers\fR
+is that in LDAP,
+\fBsudo\fR-specific
+Aliases are not supported.
+.PP
+For the most part, there is little need for
+\fBsudo\fR-specific
+Aliases.
+Unix groups, non-Unix groups (via the
+\fIgroup_plugin\fR)
+or user netgroups can be used in place of User_Aliases and Runas_Aliases.
+Host netgroups can be used in place of Host_Aliases.
+Since groups and netgroups can also be stored in LDAP there is no real need for
+\fBsudo\fR-specific
+aliases.
+.PP
+There are also some subtle differences in the way sudoers is handled
+once in LDAP.
+Probably the biggest is that according to the RFC, LDAP ordering
+is arbitrary and you cannot expect that Attributes and Entries are
+returned in any specific order.
+.PP
+The order in which different entries are applied can be controlled
+using the
+\fRsudoOrder\fR
+attribute, but there is no way to guarantee the order of attributes
+within a specific entry.
+If there are conflicting command rules in an entry, the negative
+takes precedence.
+This is called paranoid behavior (not necessarily the most specific
+match).
+.PP
+Here is an example:
+.nf
+.sp
+.RS 4n
+# /etc/sudoers:
+# Allow all commands except shell
+johnny ALL=(root) ALL,!/bin/sh
+# Always allows all commands because ALL is matched last
+puddles ALL=(root) !/bin/sh,ALL
+
+# LDAP equivalent of johnny
+# Allows all commands except shell
+dn: cn=role1,ou=Sudoers,dc=my-domain,dc=com
+objectClass: sudoRole
+objectClass: top
+cn: role1
+sudoUser: johnny
+sudoHost: ALL
+sudoCommand: ALL
+sudoCommand: !/bin/sh
+
+# LDAP equivalent of puddles
+# Notice that even though ALL comes last, it still behaves like
+# role1 since the LDAP code assumes the more paranoid configuration
+dn: cn=role2,ou=Sudoers,dc=my-domain,dc=com
+objectClass: sudoRole
+objectClass: top
+cn: role2
+sudoUser: puddles
+sudoHost: ALL
+sudoCommand: !/bin/sh
+sudoCommand: ALL
+.RE
+.fi
+.PP
+Another difference is that it is not possible to use negation in a
+sudoUser, sudoRunAsUser or sudoRunAsGroup attribute.
+For example, the following attributes do not behave the way one might expect.
+.nf
+.sp
+.RS 4n
+# does not match all but joe
+# rather, does not match anyone
+sudoUser: !joe
+
+# does not match all but joe
+# rather, matches everyone including Joe
+sudoUser: ALL
+sudoUser: !joe
+.RE
+.fi
+.SS "Converting between file-based and LDAP sudoers"
+The
+cvtsudoers(1)
+utility can be used to convert between file-based and LDAP
+\fIsudoers\fR.
+However, there are features in the file-based sudoers that have
+no equivalent in LDAP-based sudoers (and vice versa).
+These cannot be converted automatically.
+.PP
+For example, a Cmnd_Alias in a
+\fIsudoers\fR
+file may be converted to a
+\fRsudoRole\fR
+that contains multiple commands.
+Multiple users and/or groups may be assigned to the
+\fRsudoRole\fR.
+.PP
+Also, host, user, runas and command-based
+\fRDefaults\fR
+entries are not supported.
+However, a
+\fRsudoRole\fR
+may contain one or more
+\fRsudoOption\fR
+attributes which can often serve the same purpose.
+.PP
+Consider the following
+\fIsudoers\fR
+lines:
+.nf
+.sp
+.RS 4n
+Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+Defaults!PAGERS noexec
+alice, bob ALL = ALL
+.RE
+.fi
+.PP
+In this example, alice and bob are allowed to run all commands, but
+the commands listed in PAGERS will have the noexec flag set,
+preventing shell escapes.
+.PP
+When converting this to LDAP, two sudoRole objects can be used:
+.nf
+.sp
+.RS 4n
+dn: cn=PAGERS,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: PAGERS
+sudoUser: alice
+sudoUser: bob
+sudoHost: ALL
+sudoCommand: /usr/bin/more
+sudoCommand: /usr/bin/pg
+sudoCommand: /usr/bin/less
+sudoOption: noexec
+sudoOrder: 900
+
+dn: cn=ADMINS,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: ADMINS
+sudoUser: alice
+sudoUser: bob
+sudoHost: ALL
+sudoCommand: ALL
+sudoOrder: 100
+.RE
+.fi
+.PP
+In the LDAP version, the sudoOrder attribute is used to guarantee
+that the PAGERS sudoRole with
+\fInoexec\fR
+has precedence.
+Unlike the
+\fIsudoers\fR
+version, the LDAP version requires that all users for whom the restriction
+should apply be assigned to the PAGERS sudoRole.
+Using a Unix group or netgroup in PAGERS rather than listing each
+user would make this easier to maintain.
+.PP
+Per-user
+\fRDefaults\fR
+entries can be emulated by using one or more sudoOption attributes
+in a sudoRole.
+Consider the following
+\fIsudoers\fR
+lines:
+.nf
+.sp
+.RS 4n
+User_Alias ADMINS = john, sally
+Defaults:ADMINS !authenticate
+ADMINS ALL = (ALL:ALL) ALL
+.RE
+.fi
+.PP
+In this example, john and sally are allowed to run any command
+as any user or group.
+.PP
+When converting this to LDAP, we can use a Unix group instead
+of the User_Alias.
+.nf
+.sp
+.RS 4n
+dn: cn=admins,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: admins
+sudoUser: %admin
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOption: !authenticate
+.RE
+.fi
+.PP
+This assumes that users john and sally are members of the
+\(lqadmins\(rq
+Unix group.
+.SS "Sudoers schema"
+In order to use
+\fBsudo\fR's
+LDAP support, the
+\fBsudo\fR
+schema must be
+installed on your LDAP server.
+In addition, be sure to index the
+\fRsudoUser\fR
+attribute.
+.PP
+The
+\fBsudo\fR
+distribution includes versions of the
+\fBsudoers\fR
+schema for multiple LDAP servers:
+.TP 6n
+\fIschema.OpenLDAP\fR
+OpenLDAP slapd and
+OpenBSD
+ldapd
+.TP 6n
+\fIschema.olcSudo\fR
+OpenLDAP slapd 2.3 and higher when on-line configuration is enabled
+.TP 6n
+\fIschema.iPlanet\fR
+Netscape-derived servers such as the iPlanet, Oracle,
+and 389 Directory Servers
+.TP 6n
+\fIschema.ActiveDirectory\fR
+Microsoft Active Directory
+.PP
+The schema in OpenLDAP format is also included in the
+\fIEXAMPLES\fR
+section.
+.SS "Configuring ldap.conf"
+Sudo reads the
+\fI@ldap_conf@\fR
+file for LDAP-specific configuration.
+Typically, this file is shared between different LDAP-aware clients.
+As such, most of the settings are not
+\fBsudo\fR-specific.
+Note that
+\fBsudo\fR
+parses
+\fI@ldap_conf@\fR
+itself and may support options that differ from those described in the
+system's
+ldap.conf(@mansectform@)
+manual.
+The path to
+\fIldap.conf\fR
+may be overridden via the
+\fIldap_conf\fR
+plugin argument in
+sudo.conf(@mansectform@).
+.PP
+Also note that on systems using the OpenLDAP libraries, default
+values specified in
+\fI/etc/openldap/ldap.conf\fR
+or the user's
+\fI.ldaprc\fR
+files are not used.
+.PP
+Only those options explicitly listed in
+\fI@ldap_conf@\fR
+as being supported by
+\fBsudo\fR
+are honored.
+Configuration options are listed below in upper case but are parsed
+in a case-independent manner.
+.PP
+Lines beginning with a pound sign
+(\(oq#\(cq)
+are ignored.
+Leading white space is removed from the beginning of lines.
+.TP 6n
+\fBBIND_TIMELIMIT\fR \fIseconds\fR
+The
+\fBBIND_TIMELIMIT\fR
+parameter specifies the amount of time, in seconds, to wait while trying
+to connect to an LDAP server.
+If multiple
+\fBURI\fRs
+or
+\fBHOST\fRs
+are specified, this is the amount of time to wait before trying
+the next one in the list.
+.TP 6n
+\fBBINDDN\fR \fIDN\fR
+The
+\fBBINDDN\fR
+parameter specifies the identity, in the form of a Distinguished Name (DN),
+to use when performing LDAP operations.
+If not specified, LDAP operations are performed with an anonymous identity.
+By default, most LDAP servers will allow anonymous access.
+.TP 6n
+\fBBINDPW\fR \fIsecret\fR
+The
+\fBBINDPW\fR
+parameter specifies the password to use when performing LDAP operations.
+This is typically used in conjunction with the
+\fBBINDDN\fR
+parameter.
+The
+\fIsecret\fR
+may be a plain text password or a base64-encoded string with a
+\(lqbase64:\(rq
+prefix.
+For example:
+.nf
+.sp
+.RS 10n
+BINDPW base64:dGVzdA==
+.RE
+.fi
+.RS 6n
+.sp
+If a plain text password is used, it should be a simple string without quotes.
+Plain text passwords may not include the comment character
+(\(oq#\(cq)
+and the escaping of special characters with a backslash
+(\(oq\e\(cq)
+is not supported.
+.RE
+.TP 6n
+\fBDEREF\fR \fInever/searching/finding/always\fR
+How alias dereferencing is to be performed when searching.
+See the
+ldap.conf(@mansectform@)
+manual for a full description of this option.
+.TP 6n
+\fBHOST\fR \fIname[:port] ...\fR
+If no
+\fBURI\fR
+is specified (see below), the
+\fBHOST\fR
+parameter specifies a white space-delimited list of LDAP servers to connect to.
+Each host may include an optional
+\fIport\fR
+separated by a colon
+(\(oq:\&\(cq).
+The
+\fBHOST\fR
+parameter is deprecated in favor of the
+\fBURI\fR
+specification and is included for backwards compatibility only.
+.TP 6n
+\fBKRB5_CCNAME\fR \fIfile name\fR
+The path to the Kerberos 5 credential cache to use when authenticating
+with the remote server.
+This option is only relevant when using SASL authentication (see below).
+.TP 6n
+\fBLDAP_VERSION\fR \fInumber\fR
+The version of the LDAP protocol to use when connecting to the server.
+The default value is protocol version 3.
+.TP 6n
+\fBNETGROUP_BASE\fR \fIbase\fR
+The base DN to use when performing LDAP netgroup queries.
+Typically this is of the form
+\fRou=netgroup,dc=my-domain,dc=com\fR
+for the domain
+\fRmy-domain.com\fR.
+Multiple
+\fBNETGROUP_BASE\fR
+lines may be specified, in which case they are queried in the order specified.
+.sp
+This option can be used to query a user's netgroups directly via LDAP
+which is usually faster than fetching every
+\fRsudoRole\fR
+object containing a
+\fRsudoUser\fR
+that begins with a
+\(oq+\(cq
+prefix.
+The NIS schema used by some LDAP servers need a modification to
+support querying the
+\fRnisNetgroup\fR
+object by its
+\fRnisNetgroupTriple\fR
+member.
+OpenLDAP's
+\fBslapd\fR
+requires the following change to the
+\fRnisNetgroupTriple\fR
+attribute:
+.nf
+.sp
+.RS 10n
+attributetype ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
+ DESC 'Netgroup triple'
+ EQUALITY caseIgnoreIA5Match
+ SUBSTR caseIgnoreIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+.RE
+.fi
+.TP 6n
+\fBNETGROUP_SEARCH_FILTER\fR \fIldap_filter\fR
+An LDAP filter which is used to restrict the set of records returned
+when performing an LDAP netgroup query.
+Typically, this is of the
+form
+\fRattribute=value\fR
+or
+\fR(&(attribute=value)(attribute2=value2))\fR.
+The default search filter is:
+\fRobjectClass=nisNetgroup\fR.
+If
+\fIldap_filter\fR
+is omitted, no search filter will be used.
+This option is only when querying netgroups directly via LDAP.
+.TP 6n
+\fBNETWORK_TIMEOUT\fR \fIseconds\fR
+An alias for
+\fBBIND_TIMELIMIT\fR
+provided for OpenLDAP compatibility.
+.TP 6n
+\fBPORT\fR \fIport_number\fR
+If no
+\fBURI\fR
+is specified, the
+\fBPORT\fR
+parameter specifies the default port to connect to on the LDAP server if a
+\fBHOST\fR
+parameter does not specify the port itself.
+If no
+\fBPORT\fR
+parameter is used, the default is port 389 for LDAP and port 636 for LDAP
+over TLS (SSL).
+The
+\fBPORT\fR
+parameter is deprecated in favor of the
+\fBURI\fR
+specification and is included for backwards compatibility only.
+.TP 6n
+\fBROOTBINDDN\fR \fIDN\fR
+The
+\fBROOTBINDDN\fR
+parameter specifies the identity, in the form of a Distinguished Name (DN),
+to use when performing privileged LDAP operations, such as
+\fIsudoers\fR
+queries.
+The password corresponding to the identity should be stored in the
+or the path specified by the
+\fIldap_secret\fR
+plugin argument in
+sudo.conf(@mansectform@),
+which defaults to
+\fI@ldap_secret@\fR.
+If no
+\fBROOTBINDDN\fR
+is specified, the
+\fBBINDDN\fR
+identity is used (if any).
+.TP 6n
+\fBROOTUSE_SASL\fR \fIon/true/yes/off/false/no\fR
+Enable
+\fBROOTUSE_SASL\fR
+to enable SASL authentication when connecting
+to an LDAP server from a privileged process, such as
+\fBsudo\fR.
+.TP 6n
+\fBSASL_AUTH_ID\fR \fIidentity\fR
+The SASL user name to use when connecting to the LDAP server.
+By default,
+\fBsudo\fR
+will use an anonymous connection.
+This option is only relevant when using SASL authentication.
+.TP 6n
+\fBSASL_MECH\fR \fImechanisms\fR
+A white space-delimited list of SASL authentication mechanisms to use.
+By default,
+\fBsudo\fR
+will use
+\fRGSSAPI\fR
+authentication.
+.TP 6n
+\fBSASL_SECPROPS\fR \fInone/properties\fR
+SASL security properties or
+\fInone\fR
+for no properties.
+See the SASL programmer's manual for details.
+This option is only relevant when using SASL authentication.
+.TP 6n
+\fBSSL\fR \fIon/true/yes/off/false/no\fR
+If the
+\fBSSL\fR
+parameter is set to
+\fRon\fR,
+\fRtrue\fR
+\fRor\fR
+\fRyes\fR,
+TLS (SSL) encryption is always used when communicating with the LDAP server.
+Typically, this involves connecting to the server on port 636 (ldaps).
+.TP 6n
+\fBSSL\fR \fIstart_tls\fR
+If the
+\fBSSL\fR
+parameter is set to
+\fRstart_tls\fR,
+the LDAP server connection is initiated normally and TLS encryption is
+begun before the bind credentials are sent.
+This has the advantage of not requiring a dedicated port for encrypted
+communications.
+This parameter is only supported by LDAP servers that honor the
+\fIstart_tls\fR
+extension, such as the OpenLDAP and Tivoli Directory servers.
+.TP 6n
+\fBSUDOERS_BASE\fR \fIbase\fR
+The base DN to use when performing
+\fBsudo\fR
+LDAP queries.
+Typically this is of the form
+\fRou=SUDOers,dc=my-domain,dc=com\fR
+for the domain
+\fRmy-domain.com\fR.
+Multiple
+\fBSUDOERS_BASE\fR
+lines may be specified, in which case they are queried in the order specified.
+.TP 6n
+\fBSUDOERS_DEBUG\fR \fIdebug_level\fR
+This sets the debug level for
+\fBsudo\fR
+LDAP queries.
+Debugging information is printed to the standard error.
+A value of 1 results in a moderate amount of debugging information.
+A value of 2 shows the results of the matches themselves.
+This parameter should not be set in a production environment as the
+extra information is likely to confuse users.
+.sp
+The
+\fBSUDOERS_DEBUG\fR
+parameter is deprecated and will be removed in a future release.
+The same information is now logged via the
+\fBsudo\fR
+debugging framework using the
+\(lqldap\(rq
+subsystem at priorities
+\fIdiag\fR
+and
+\fIinfo\fR
+for
+\fIdebug_level\fR
+values 1 and 2 respectively.
+See the
+sudo.conf(@mansectform@)
+manual for details on how to configure
+\fBsudo\fR
+debugging.
+.TP 6n
+\fBSUDOERS_SEARCH_FILTER\fR \fIldap_filter\fR
+An LDAP filter which is used to restrict the set of records returned
+when performing a
+\fBsudo\fR
+LDAP query.
+Typically, this is of the
+form
+\fRattribute=value\fR
+or
+\fR(&(attribute=value)(attribute2=value2))\fR.
+The default search filter is:
+\fRobjectClass=sudoRole\fR.
+If
+\fIldap_filter\fR
+is omitted, no search filter will be used.
+.TP 6n
+\fBSUDOERS_TIMED\fR \fIon/true/yes/off/false/no\fR
+Whether or not to evaluate the
+\fRsudoNotBefore\fR
+and
+\fRsudoNotAfter\fR
+attributes that implement time-dependent sudoers entries.
+.TP 6n
+\fBTIMELIMIT\fR \fIseconds\fR
+The
+\fBTIMELIMIT\fR
+parameter specifies the amount of time, in seconds, to wait for a
+response to an LDAP query.
+.TP 6n
+\fBTIMEOUT\fR \fIseconds\fR
+The
+\fBTIMEOUT\fR
+parameter specifies the amount of time, in seconds, to wait for a
+response from the various LDAP APIs.
+.TP 6n
+\fBTLS_CACERT\fR \fIfile name\fR
+An alias for
+\fBTLS_CACERTFILE\fR
+for OpenLDAP compatibility.
+.TP 6n
+\fBTLS_CACERTFILE\fR \fIfile name\fR
+The path to a certificate authority bundle which contains the certificates
+for all the Certificate Authorities the client knows to be valid, e.g.,
+\fI/etc/ssl/ca-bundle.pem\fR.
+This option is only supported by the OpenLDAP libraries.
+Netscape-derived LDAP libraries use the same certificate
+database for CA and client certificates (see
+\fBTLS_CERT\fR).
+.TP 6n
+\fBTLS_CACERTDIR\fR \fIdirectory\fR
+Similar to
+\fBTLS_CACERTFILE\fR
+but instead of a file, it is a directory containing individual
+Certificate Authority certificates, e.g.,
+\fI/etc/ssl/certs\fR.
+The directory specified by
+\fBTLS_CACERTDIR\fR
+is checked after
+\fBTLS_CACERTFILE\fR.
+This option is only supported by the OpenLDAP libraries.
+.TP 6n
+\fBTLS_CERT\fR \fIfile name\fR
+The path to a file containing the client certificate which can
+be used to authenticate the client to the LDAP server.
+The certificate type depends on the LDAP libraries used.
+.PP
+.RS 6n
+.PD 0
+.TP 6n
+OpenLDAP:
+\fRtls_cert /etc/ssl/client_cert.pem\fR
+.PD
+.TP 6n
+Netscape-derived:
+\fRtls_cert /var/ldap/cert7.db\fR
+.TP 6n
+Tivoli Directory Server:
+Unused, the key database specified by
+\fBTLS_KEY\fR
+contains both keys and certificates.
+.sp
+When using Netscape-derived libraries, this file may also contain
+Certificate Authority certificates.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+\fBTLS_CHECKPEER\fR \fIon/true/yes/off/false/no\fR
+If enabled,
+\fBTLS_CHECKPEER\fR
+will cause the LDAP server's TLS certificated to be verified.
+If the server's TLS certificate cannot be verified (usually because it
+is signed by an unknown certificate authority),
+\fBsudo\fR
+will be unable to connect to it.
+If
+\fBTLS_CHECKPEER\fR
+is disabled, no check is made.
+Note that disabling the check creates an opportunity for man-in-the-middle
+attacks since the server's identity will not be authenticated.
+If possible, the CA's certificate should be installed locally so it can
+be verified.
+This option is not supported by the Tivoli Directory Server LDAP libraries.
+.TP 6n
+\fBTLS_KEY\fR \fIfile name\fR
+The path to a file containing the private key which matches the
+certificate specified by
+\fBTLS_CERT\fR.
+The private key must not be password-protected.
+The key type depends on the LDAP libraries used.
+.PP
+.RS 6n
+.PD 0
+.TP 6n
+OpenLDAP:
+\fRtls_key /etc/ssl/client_key.pem\fR
+.PD
+.TP 6n
+Netscape-derived:
+\fRtls_key /var/ldap/key3.db\fR
+.TP 6n
+Tivoli Directory Server:
+\fRtls_key /usr/ldap/ldapkey.kdb\fR
+.PD 0
+.PP
+When using Tivoli LDAP libraries, this file may also contain
+Certificate Authority and client certificates and may be encrypted.
+.RE
+.PD
+.TP 6n
+\fBTLS_CIPHERS\fR \fIcipher list\fR
+The
+\fBTLS_CIPHERS\fR
+parameter allows the administer to restrict which encryption algorithms
+may be used for TLS (SSL) connections.
+See the OpenLDAP or Tivoli Directory Server manual for a list of valid
+ciphers.
+This option is not supported by Netscape-derived libraries.
+.TP 6n
+\fBTLS_KEYPW\fR \fIsecret\fR
+The
+\fBTLS_KEYPW\fR
+contains the password used to decrypt the key database on clients
+using the Tivoli Directory Server LDAP library.
+The
+\fIsecret\fR
+may be a plain text password or a base64-encoded string with a
+\(lqbase64:\(rq
+prefix.
+For example:
+.nf
+.sp
+.RS 10n
+TLS_KEYPW base64:dGVzdA==
+.RE
+.fi
+.RS 6n
+.sp
+If a plain text password is used, it should be a simple string without quotes.
+Plain text passwords may not include the comment character
+(\(oq#\(cq)
+and the escaping of special characters with a backslash
+(\(oq\e\(cq)
+is not supported.
+If this option is used,
+\fI@ldap_conf@\fR
+must not be world-readable to avoid exposing the password.
+Alternately, a
+\fIstash file\fR
+can be used to store the password in encrypted form (see below).
+.sp
+If no
+\fBTLS_KEYPW\fR
+is specified, a
+\fIstash file\fR
+will be used if it exists.
+The
+\fIstash file\fR
+must have the same path as the file specified by
+\fBTLS_KEY\fR,
+but use a
+\fR.sth\fR
+file extension instead of
+\fR.kdb\fR,
+e.g.,
+\fRldapkey.sth\fR.
+The default
+\fRldapkey.kdb\fR
+that ships with Tivoli Directory Server is encrypted with the password
+\fRssl_password\fR.
+The
+\fIgsk8capicmd\fR
+utility can be used to manage the key database and create a
+\fIstash file\fR.
+This option is only supported by the Tivoli LDAP libraries.
+.RE
+.TP 6n
+\fBTLS_REQCERT\fR \fIlevel\fR
+The
+\fBTLS_REQCERT\fR
+parameter controls how the LDAP server's TLS certificated will be
+verified (if at all).
+If the server's TLS certificate cannot be verified (usually because it
+is signed by an unknown certificate authority),
+\fBsudo\fR
+will be unable to connect to it.
+The following
+\fIlevel\fR
+values are supported:
+.RS 10n
+.TP 10n
+never
+The server certificate will not be requested or checked.
+.TP 10n
+allow
+The server certificate will be requested.
+A missing or invalid certificate is ignored and not considered an error.
+.TP 10n
+try
+The server certificate will be requested.
+A missing certificate is ignored but an invalid certificate will
+result in a connection error.
+.TP 10n
+demand | \fIhard\fR
+The server certificate will be requested.
+A missing or invalid certificate will result in a connection error.
+This is the default behavior.
+.RE
+.RS 6n
+.sp
+This option is only supported by the OpenLDAP libraries.
+Other LDAP libraries only support the
+\fBTLS_CHECKPEER\fR
+parameter.
+.RE
+.TP 6n
+\fBTLS_RANDFILE\fR \fIfile name\fR
+The
+\fBTLS_RANDFILE\fR
+parameter specifies the path to an entropy source for systems that lack
+a random device.
+It is generally used in conjunction with
+\fIprngd\fR
+or
+\fIegd\fR.
+This option is only supported by the OpenLDAP libraries.
+.TP 6n
+\fBURI\fR \fIldap[s]://[hostname[:port]] ...\fR
+Specifies a white space-delimited list of one or more URIs describing
+the LDAP server(s) to connect to.
+The
+\fIprotocol\fR
+may be either
+\fIldap\fR
+\fIldaps\fR,
+the latter being for servers that support TLS (SSL) encryption.
+If no
+\fIport\fR
+is specified, the default is port 389 for
+\fRldap://\fR
+or port 636 for
+\fRldaps://\fR.
+If no
+\fIhostname\fR
+is specified,
+\fBsudo\fR
+will connect to
+\fIlocalhost\fR.
+Multiple
+\fBURI\fR
+lines are treated identically to a
+\fBURI\fR
+line containing multiple entries.
+Only systems using the OpenSSL libraries support the mixing of
+\fRldap://\fR
+and
+\fRldaps://\fR
+URIs.
+Both the Netscape-derived and Tivoli LDAP libraries used on most commercial
+versions of Unix are only capable of supporting one or the other.
+.TP 6n
+\fBUSE_SASL\fR \fIon/true/yes/off/false/no\fR
+Enable
+\fBUSE_SASL\fR
+for LDAP servers that support SASL authentication.
+.TP 6n
+\fBROOTSASL_AUTH_ID\fR \fIidentity\fR
+The SASL user name to use when
+\fBROOTUSE_SASL\fR
+is enabled.
+.PP
+See the
+\fIldap.conf\fR
+entry in the
+\fIEXAMPLES\fR
+section.
+.SS "Configuring nsswitch.conf"
+Unless it is disabled at build time,
+\fBsudo\fR
+consults the Name Service Switch file,
+\fI@nsswitch_conf@\fR,
+to specify the
+\fIsudoers\fR
+search order.
+Sudo looks for a line beginning with
+\fRsudoers\fR:
+and uses this to determine the search order.
+Note that
+\fBsudo\fR
+does
+not stop searching after the first match and later matches take
+precedence over earlier ones.
+The following sources are recognized:
+.PP
+.RS 4n
+.PD 0
+.TP 10n
+files
+read sudoers from
+\fI@sysconfdir@/sudoers\fR
+.TP 10n
+ldap
+read sudoers from LDAP
+.RE
+.PD
+.PP
+In addition, the entry
+\fR[NOTFOUND=return]\fR
+will short-circuit the search if the user was not found in the
+preceding source.
+.PP
+To consult LDAP first followed by the local sudoers file (if it
+exists), use:
+.nf
+.sp
+.RS 4n
+sudoers: ldap files
+.RE
+.fi
+.PP
+The local
+\fIsudoers\fR
+file can be ignored completely by using:
+.nf
+.sp
+.RS 4n
+sudoers: ldap
+.RE
+.fi
+.PP
+If the
+\fI@nsswitch_conf@\fR
+file is not present or there is no sudoers line, the following
+default is assumed:
+.nf
+.sp
+.RS 4n
+sudoers: files
+.RE
+.fi
+.PP
+Note that
+\fI@nsswitch_conf@\fR
+is supported even when the underlying operating system does not use
+an nsswitch.conf file, except on AIX (see below).
+.SS "Configuring netsvc.conf"
+On AIX systems, the
+\fI@netsvc_conf@\fR
+file is consulted instead of
+\fI@nsswitch_conf@\fR.
+\fBsudo\fR
+simply treats
+\fInetsvc.conf\fR
+as a variant of
+\fInsswitch.conf\fR;
+information in the previous section unrelated to the file format
+itself still applies.
+.PP
+To consult LDAP first followed by the local sudoers file (if it
+exists), use:
+.nf
+.sp
+.RS 4n
+sudoers = ldap, files
+.RE
+.fi
+.PP
+The local
+\fIsudoers\fR
+file can be ignored completely by using:
+.nf
+.sp
+.RS 4n
+sudoers = ldap
+.RE
+.fi
+.PP
+To treat LDAP as authoritative and only use the local sudoers file
+if the user is not present in LDAP, use:
+.nf
+.sp
+.RS 4n
+sudoers = ldap = auth, files
+.RE
+.fi
+.PP
+Note that in the above example, the
+\fRauth\fR
+qualifier only affects user lookups; both LDAP and
+\fIsudoers\fR
+will be queried for
+\fRDefaults\fR
+entries.
+.PP
+If the
+\fI@netsvc_conf@\fR
+file is not present or there is no sudoers line, the following
+default is assumed:
+.nf
+.sp
+.RS 4n
+sudoers = files
+.RE
+.fi
+.SS "Integration with sssd"
+On systems with the
+\fISystem Security Services Daemon\fR
+(SSSD) and where
+\fBsudo\fR
+has been built with SSSD support,
+it is possible to use SSSD to cache LDAP
+\fIsudoers\fR
+rules.
+To use SSSD as the
+\fIsudoers\fR
+source, you should use
+\fRsssd\fR
+instead of
+\fRldap\fR
+for the sudoers entry in
+\fI@nsswitch_conf@\fR.
+Note that the
+\fI@ldap_conf@\fR
+file is not used by the SSSD
+\fBsudo\fR
+back end.
+Please see
+sssd-sudo(@mansectform@)
+for more information on configuring
+\fBsudo\fR
+to work with SSSD.
+.SH "FILES"
+.TP 26n
+\fI@ldap_conf@\fR
+LDAP configuration file
+.TP 26n
+\fI@nsswitch_conf@\fR
+determines sudoers source order
+.TP 26n
+\fI@netsvc_conf@\fR
+determines sudoers source order on AIX
+.SH "EXAMPLES"
+.SS "Example ldap.conf"
+.nf
+.RS 2n
+# Either specify one or more URIs or one or more host:port pairs.
+# If neither is specified sudo will default to localhost, port 389.
+#
+#host ldapserver
+#host ldapserver1 ldapserver2:390
+#
+# Default port if host is specified without one, defaults to 389.
+#port 389
+#
+# URI will override the host and port settings.
+uri ldap://ldapserver
+#uri ldaps://secureldapserver
+#uri ldaps://secureldapserver ldap://ldapserver
+#
+# The amount of time, in seconds, to wait while trying to connect to
+# an LDAP server.
+bind_timelimit 30
+#
+# The amount of time, in seconds, to wait while performing an LDAP query.
+timelimit 30
+#
+# Must be set or sudo will ignore LDAP; may be specified multiple times.
+sudoers_base ou=SUDOers,dc=my-domain,dc=com
+#
+# verbose sudoers matching from ldap
+#sudoers_debug 2
+#
+# Enable support for time-based entries in sudoers.
+#sudoers_timed yes
+#
+# optional proxy credentials
+#binddn <who to search as>
+#bindpw <password>
+#rootbinddn <who to search as, uses /etc/ldap.secret for bindpw>
+#
+# LDAP protocol version, defaults to 3
+#ldap_version 3
+#
+# Define if you want to use an encrypted LDAP connection.
+# Typically, you must also set the port to 636 (ldaps).
+#ssl on
+#
+# Define if you want to use port 389 and switch to
+# encryption before the bind credentials are sent.
+# Only supported by LDAP servers that support the start_tls
+# extension such as OpenLDAP.
+#ssl start_tls
+#
+# Additional TLS options follow that allow tweaking of the
+# SSL/TLS connection.
+#
+#tls_checkpeer yes # verify server SSL certificate
+#tls_checkpeer no # ignore server SSL certificate
+#
+# If you enable tls_checkpeer, specify either tls_cacertfile
+# or tls_cacertdir. Only supported when using OpenLDAP.
+#
+#tls_cacertfile /etc/certs/trusted_signers.pem
+#tls_cacertdir /etc/certs
+#
+# For systems that don't have /dev/random
+# use this along with PRNGD or EGD.pl to seed the
+# random number pool to generate cryptographic session keys.
+# Only supported when using OpenLDAP.
+#
+#tls_randfile /etc/egd-pool
+#
+# You may restrict which ciphers are used. Consult your SSL
+# documentation for which options go here.
+# Only supported when using OpenLDAP.
+#
+#tls_ciphers <cipher-list>
+#
+# Sudo can provide a client certificate when communicating to
+# the LDAP server.
+# Tips:
+# * Enable both lines at the same time.
+# * Do not password protect the key file.
+# * Ensure the keyfile is only readable by root.
+#
+# For OpenLDAP:
+#tls_cert /etc/certs/client_cert.pem
+#tls_key /etc/certs/client_key.pem
+#
+# For SunONE or iPlanet LDAP, tls_cert and tls_key may specify either
+# a directory, in which case the files in the directory must have the
+# default names (e.g., cert8.db and key4.db), or the path to the cert
+# and key files themselves. However, a bug in version 5.0 of the LDAP
+# SDK will prevent specific file names from working. For this reason
+# it is suggested that tls_cert and tls_key be set to a directory,
+# not a file name.
+#
+# The certificate database specified by tls_cert may contain CA certs
+# and/or the client's cert. If the client's cert is included, tls_key
+# should be specified as well.
+# For backward compatibility, "sslpath" may be used in place of tls_cert.
+#tls_cert /var/ldap
+#tls_key /var/ldap
+#
+# If using SASL authentication for LDAP (OpenSSL)
+# use_sasl yes
+# sasl_auth_id <SASL user name>
+# rootuse_sasl yes
+# rootsasl_auth_id <SASL user name for root access>
+# sasl_secprops none
+# krb5_ccname /etc/.ldapcache
+.RE
+.fi
+.SS "Sudoers schema for OpenLDAP"
+The following schema, in OpenLDAP format, is included with
+\fBsudo\fR
+source and binary distributions as
+\fIschema.OpenLDAP\fR.
+Simply copy
+it to the schema directory (e.g.,
+\fI/etc/openldap/schema\fR),
+add the proper
+\fRinclude\fR
+line in
+\fIslapd.conf\fR
+and restart
+\fBslapd\fR.
+Sites using the optional on-line configuration supported by OpenLDAP 2.3
+and higher should apply the
+\fIschema.olcSudo\fR
+file instead.
+.nf
+.sp
+.RS 2n
+attributetype ( 1.3.6.1.4.1.15953.9.1.1
+ NAME 'sudoUser'
+ DESC 'User(s) who may run sudo'
+ EQUALITY caseExactIA5Match
+ SUBSTR caseExactIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.2
+ NAME 'sudoHost'
+ DESC 'Host(s) who may run sudo'
+ EQUALITY caseExactIA5Match
+ SUBSTR caseExactIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.3
+ NAME 'sudoCommand'
+ DESC 'Command(s) to be executed by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.4
+ NAME 'sudoRunAs'
+ DESC 'User(s) impersonated by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.5
+ NAME 'sudoOption'
+ DESC 'Options(s) followed by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.6
+ NAME 'sudoRunAsUser'
+ DESC 'User(s) impersonated by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.7
+ NAME 'sudoRunAsGroup'
+ DESC 'Group(s) impersonated by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.8
+ NAME 'sudoNotBefore'
+ DESC 'Start of time interval for which the entry is valid'
+ EQUALITY generalizedTimeMatch
+ ORDERING generalizedTimeOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.9
+ NAME 'sudoNotAfter'
+ DESC 'End of time interval for which the entry is valid'
+ EQUALITY generalizedTimeMatch
+ ORDERING generalizedTimeOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.10
+ NAME 'sudoOrder'
+ DESC 'an integer to order the sudoRole entries'
+ EQUALITY integerMatch
+ ORDERING integerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL
+ DESC 'Sudoer Entries'
+ MUST ( cn )
+ MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $
+ sudoRunAsGroup $ sudoOption $ sudoNotBefore $ sudoNotAfter $
+ sudoOrder $ description )
+ )
+.RE
+.fi
+.SH "SEE ALSO"
+cvtsudoers(1),
+ldap.conf(@mansectform@),
+sssd-sudo(@mansectform@),
+sudo.conf(@mansectform@),
+sudoers(@mansectform@)
+.SH "AUTHORS"
+Many people have worked on
+\fBsudo\fR
+over the years; this version consists of code written primarily by:
+.sp
+.RS 6n
+Todd C. Miller
+.RE
+.PP
+See the CONTRIBUTORS file in the
+\fBsudo\fR
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+\fBsudo\fR.
+.SH "CAVEATS"
+Note that there are differences in the way that LDAP-based
+\fIsudoers\fR
+is parsed compared to file-based
+\fIsudoers\fR.
+See the
+\fIDifferences between LDAP and non-LDAP sudoers\fR
+section for more information.
+.SH "BUGS"
+If you feel you have found a bug in
+\fBsudo\fR,
+please submit a bug report at https://bugzilla.sudo.ws/
+.SH "SUPPORT"
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.SH "DISCLAIMER"
+\fBsudo\fR
+is provided
+\(lqAS IS\(rq
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+\fBsudo\fR
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/sudoers.ldap.mdoc.in b/doc/sudoers.ldap.mdoc.in
new file mode 100644
index 0000000..c7ab8a8
--- /dev/null
+++ b/doc/sudoers.ldap.mdoc.in
@@ -0,0 +1,1567 @@
+.\"
+.\" Copyright (c) 2003-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd November 9, 2018
+.Dt SUDOERS.LDAP @mansectform@
+.Os Sudo @PACKAGE_VERSION@
+.Sh NAME
+.Nm sudoers.ldap
+.Nd sudo LDAP configuration
+.Sh DESCRIPTION
+In addition to the standard
+.Em sudoers
+file,
+.Nm sudo
+may be configured
+via LDAP.
+This can be especially useful for synchronizing
+.Em sudoers
+in a large, distributed environment.
+.Pp
+Using LDAP for
+.Em sudoers
+has several benefits:
+.Bl -bullet -width 1n
+.It
+.Nm sudo
+no longer needs to read
+.Em sudoers
+in its entirety.
+When LDAP is used, there are only two or three LDAP queries per invocation.
+This makes it especially fast and particularly usable in LDAP environments.
+.It
+.Nm sudo
+no longer exits if there is a typo in
+.Em sudoers .
+It is not possible to load LDAP data into the server that does
+not conform to the sudoers schema, so proper syntax is guaranteed.
+It is still possible to have typos in a user or host name, but
+this will not prevent
+.Nm sudo
+from running.
+.It
+It is possible to specify per-entry options that override the global
+default options.
+.Pa @sysconfdir@/sudoers
+only supports default options and limited options associated with
+user/host/commands/aliases.
+The syntax is complicated and can be difficult for users to understand.
+Placing the options directly in the entry is more natural.
+.It
+The
+.Nm visudo
+program is no longer needed.
+.Nm visudo
+provides locking and syntax checking of the
+.Pa @sysconfdir@/sudoers
+file.
+Since LDAP updates are atomic, locking is no longer necessary.
+Because syntax is checked when the data is inserted into LDAP, there
+is no need for a specialized tool to check syntax.
+.El
+.Ss SUDOers LDAP container
+The
+.Em sudoers
+configuration is contained in the
+.Li ou=SUDOers
+LDAP container.
+.Pp
+Sudo first looks for the
+.Li cn=defaults
+entry in the SUDOers container.
+If found, the multi-valued
+.Li sudoOption
+attribute is parsed in the same manner as a global
+.Li Defaults
+line in
+.Pa @sysconfdir@/sudoers .
+In the following example, the
+.Ev SSH_AUTH_SOCK
+variable will be preserved in the environment for all users.
+.Bd -literal -offset 4n
+dn: cn=defaults,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption: env_keep+=SSH_AUTH_SOCK
+.Ed
+.Pp
+The equivalent of a sudoer in LDAP is a
+.Li sudoRole .
+It consists of the following attributes:
+.Bl -tag -width 4n
+.It Sy sudoUser
+A user name, user ID (prefixed with
+.Ql # ) ,
+Unix group name or ID (prefixed with
+.Ql %
+or
+.Ql %#
+respectively), user netgroup (prefixed with
+.Ql + ) ,
+or non-Unix group name or ID (prefixed with
+.Ql %:
+or
+.Ql %:#
+respectively).
+User netgroups are matched using the user and domain members only;
+the host member is not used when matching.
+Non-Unix group support is only available when an appropriate
+.Em group_plugin
+is defined in the global
+.Em defaults
+.Li sudoRole
+object.
+.It Sy sudoHost
+A host name, IP address, IP network, or host netgroup (prefixed with a
+.Ql + ) .
+The special value
+.Li ALL
+will match any host.
+Host netgroups are matched using the host (both qualified and unqualified)
+and domain members only; the user member is not used when matching.
+If a
+.Li sudoHost
+entry is preceded by an exclamation point,
+.Ql \&! ,
+and the entry matches, the
+.Li sudoRole
+in which it resides will be ignored.
+Negated
+.Li sudoHost
+entries are only supported by version 1.8.18 or higher.
+.It Sy sudoCommand
+A fully-qualified Unix command name with optional command line arguments,
+potentially including globbing characters (aka wild cards).
+If a command name is preceded by an exclamation point,
+.Ql \&! ,
+the user will be prohibited from running that command.
+.Pp
+The built-in command
+.Dq Li sudoedit
+is used to permit a user to run
+.Nm sudo
+with the
+.Fl e
+option (or as
+.Nm sudoedit ) .
+It may take command line arguments just as a normal command does.
+Note that
+.Dq Li sudoedit
+is a command built into
+.Nm sudo
+itself and must be specified in without a leading path.
+.Pp
+The special value
+.Li ALL
+will match any command.
+.Pp
+If a command name is prefixed with a SHA-2 digest, it will
+only be allowed if the digest matches.
+This may be useful in situations where the user invoking
+.Nm sudo
+has write access to the command or its parent directory.
+The following digest formats are supported: sha224, sha256, sha384 and sha512.
+The digest name must be followed by a colon
+.Pq Ql :\&
+and then the actual digest, in either hex or base64 format.
+For example, given the following value for sudoCommand:
+.Bd -literal -offset 4n
+sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ /bin/ls
+.Ed
+.Pp
+The user may only run
+.Pa /bin/ls
+if its sha224 digest matches the specified value.
+Command digests are only supported by version 1.8.7 or higher.
+.It Sy sudoOption
+Identical in function to the global options described above, but
+specific to the
+.Li sudoRole
+in which it resides.
+.It Sy sudoRunAsUser
+A user name or uid (prefixed with
+.Ql # )
+that commands may be run as or a Unix group (prefixed with a
+.Ql % )
+or user netgroup (prefixed with a
+.Ql + )
+that contains a list of users that commands may be run as.
+The special value
+.Li ALL
+will match any user.
+If a
+.Li sudoRunAsUser
+entry is preceded by an exclamation point,
+.Ql \&! ,
+and the entry matches, the
+.Li sudoRole
+in which it resides will be ignored.
+If
+.Li sudoRunAsUser
+is specified but empty, it will match the invoking user.
+If neither
+.Li sudoRunAsUser
+nor
+.Li sudoRunAsGroup
+are present, the value of the
+.Em runas_default
+.Li sudoOption
+is used (defaults to
+.Li @runas_default@ ) .
+.Pp
+The
+.Li sudoRunAsUser
+attribute is only available in
+.Nm sudo
+versions
+1.7.0 and higher.
+Older versions of
+.Nm sudo
+use the
+.Li sudoRunAs
+attribute instead.
+Negated
+.Li sudoRunAsUser
+entries are only supported by version 1.8.26 or higher.
+.It Sy sudoRunAsGroup
+A Unix group or gid (prefixed with
+.Ql # )
+that commands may be run as.
+The special value
+.Li ALL
+will match any group.
+If a
+.Li sudoRunAsGroup
+entry is preceded by an exclamation point,
+.Ql \&! ,
+and the entry matches, the
+.Li sudoRole
+in which it resides will be ignored.
+.Pp
+The
+.Li sudoRunAsGroup
+attribute is only available in
+.Nm sudo
+versions
+1.7.0 and higher.
+Negated
+.Li sudoRunAsGroup
+entries are only supported by version 1.8.26 or higher.
+.It Sy sudoNotBefore
+A timestamp in the form
+.Li yyyymmddHHMMSSZ
+that can be used to provide a start date/time for when the
+.Li sudoRole
+will be valid.
+If multiple
+.Li sudoNotBefore
+entries are present, the earliest is used.
+Note that timestamps must be in Coordinated Universal Time (UTC),
+not the local timezone.
+The minute and seconds portions are optional, but some LDAP servers
+require that they be present (contrary to the RFC).
+.Pp
+The
+.Li sudoNotBefore
+attribute is only available in
+.Nm sudo
+versions 1.7.5 and higher and must be explicitly enabled via the
+.Sy SUDOERS_TIMED
+option in
+.Pa @ldap_conf@ .
+.It Sy sudoNotAfter
+A timestamp in the form
+.Li yyyymmddHHMMSSZ
+that indicates an expiration date/time, after which the
+.Li sudoRole
+will no longer be valid.
+If multiple
+.Li sudoNotAfter
+entries are present, the last one is used.
+Note that timestamps must be in Coordinated Universal Time (UTC),
+not the local timezone.
+The minute and seconds portions are optional, but some LDAP servers
+require that they be present (contrary to the RFC).
+.Pp
+The
+.Li sudoNotAfter
+attribute is only available in
+.Nm sudo
+versions
+1.7.5 and higher and must be explicitly enabled via the
+.Sy SUDOERS_TIMED
+option in
+.Pa @ldap_conf@ .
+.It Sy sudoOrder
+The
+.Li sudoRole
+entries retrieved from the LDAP directory have no inherent order.
+The
+.Li sudoOrder
+attribute is an integer (or floating point value for LDAP servers
+that support it) that is used to sort the matching entries.
+This allows LDAP-based sudoers entries to more closely mimic the behavior
+of the sudoers file, where the order of the entries influences the result.
+If multiple entries match, the entry with the highest
+.Li sudoOrder
+attribute is chosen.
+This corresponds to the
+.Dq last match
+behavior of the sudoers file.
+If the
+.Li sudoOrder
+attribute is not present, a value of 0 is assumed.
+.Pp
+The
+.Li sudoOrder
+attribute is only available in
+.Nm sudo
+versions 1.7.5 and higher.
+.El
+.Pp
+Each attribute listed above should contain a single value, but there
+may be multiple instances of each attribute type.
+A
+.Li sudoRole
+must contain at least one
+.Li sudoUser ,
+.Li sudoHost
+and
+.Li sudoCommand .
+.Pp
+The following example allows users in group wheel to run any command
+on any host via
+.Nm sudo :
+.Bd -literal -offset 4n
+dn: cn=%wheel,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: %wheel
+sudoUser: %wheel
+sudoHost: ALL
+sudoCommand: ALL
+.Ed
+.Ss Anatomy of LDAP sudoers lookup
+When looking up a sudoer using LDAP there are only two or three
+LDAP queries per invocation.
+The first query is to parse the global options.
+The second is to match against the user's name and the groups that
+the user belongs to.
+(The special
+.Li ALL
+tag is matched in this query too.)
+If no match is returned for the user's name and groups, a third
+query returns all entries containing user netgroups and other
+non-Unix groups and checks to see if the user belongs to any of them.
+.Pp
+If timed entries are enabled with the
+.Sy SUDOERS_TIMED
+configuration directive, the LDAP queries include a sub-filter that
+limits retrieval to entries that satisfy the time constraints, if any.
+.Pp
+If the
+.Sy NETGROUP_BASE
+configuration directive is present (see
+.Sx Configuring ldap.conf
+below), queries are performed to determine
+the list of netgroups the user belongs to before the sudoers query.
+This makes it possible to include netgroups in the sudoers query
+string in the same manner as Unix groups.
+The third query mentioned above is not performed unless a group provider
+plugin is also configured.
+The actual LDAP queries performed by
+.Nm sudo
+are as follows:
+.Bl -enum
+.It
+Match all
+.Li nisNetgroup
+records with a
+.Li nisNetgroupTriple
+containing the user, host and NIS domain.
+The query will match
+.Li nisNetgroupTriple
+entries with either the short or long form of the host name or
+no host name specified in the tuple.
+If the NIS domain is set, the query will match only match entries
+that include the domain or for which there is no domain present.
+If the NIS domain is
+.Em not
+set, a wildcard is used to match any domain name but be aware that the
+NIS schema used by some LDAP servers may not support wild cards for
+.Li nisNetgroupTriple .
+.It
+Repeated queries are performed to find any nested
+.Li nisNetgroup
+records with a
+.Li memberNisNetgroup
+entry that refers to an already-matched record.
+.El
+.Pp
+For sites with a large number of netgroups, using
+.Sy NETGROUP_BASE
+can significantly speed up
+.Nm sudo Ns 's
+execution time.
+.Ss Differences between LDAP and non-LDAP sudoers
+One of the major differences between LDAP and file-based
+.Em sudoers
+is that in LDAP,
+.Nm sudo Ns -specific
+Aliases are not supported.
+.Pp
+For the most part, there is little need for
+.Nm sudo Ns -specific
+Aliases.
+Unix groups, non-Unix groups (via the
+.Em group_plugin )
+or user netgroups can be used in place of User_Aliases and Runas_Aliases.
+Host netgroups can be used in place of Host_Aliases.
+Since groups and netgroups can also be stored in LDAP there is no real need for
+.Nm sudo Ns -specific
+aliases.
+.Pp
+There are also some subtle differences in the way sudoers is handled
+once in LDAP.
+Probably the biggest is that according to the RFC, LDAP ordering
+is arbitrary and you cannot expect that Attributes and Entries are
+returned in any specific order.
+.Pp
+The order in which different entries are applied can be controlled
+using the
+.Li sudoOrder
+attribute, but there is no way to guarantee the order of attributes
+within a specific entry.
+If there are conflicting command rules in an entry, the negative
+takes precedence.
+This is called paranoid behavior (not necessarily the most specific
+match).
+.Pp
+Here is an example:
+.Bd -literal -offset 4n
+# /etc/sudoers:
+# Allow all commands except shell
+johnny ALL=(root) ALL,!/bin/sh
+# Always allows all commands because ALL is matched last
+puddles ALL=(root) !/bin/sh,ALL
+
+# LDAP equivalent of johnny
+# Allows all commands except shell
+dn: cn=role1,ou=Sudoers,dc=my-domain,dc=com
+objectClass: sudoRole
+objectClass: top
+cn: role1
+sudoUser: johnny
+sudoHost: ALL
+sudoCommand: ALL
+sudoCommand: !/bin/sh
+
+# LDAP equivalent of puddles
+# Notice that even though ALL comes last, it still behaves like
+# role1 since the LDAP code assumes the more paranoid configuration
+dn: cn=role2,ou=Sudoers,dc=my-domain,dc=com
+objectClass: sudoRole
+objectClass: top
+cn: role2
+sudoUser: puddles
+sudoHost: ALL
+sudoCommand: !/bin/sh
+sudoCommand: ALL
+.Ed
+.Pp
+Another difference is that it is not possible to use negation in a
+sudoUser, sudoRunAsUser or sudoRunAsGroup attribute.
+For example, the following attributes do not behave the way one might expect.
+.Bd -literal -offset 4n
+# does not match all but joe
+# rather, does not match anyone
+sudoUser: !joe
+
+# does not match all but joe
+# rather, matches everyone including Joe
+sudoUser: ALL
+sudoUser: !joe
+.Ed
+.Ss Converting between file-based and LDAP sudoers
+The
+.Xr cvtsudoers 1
+utility can be used to convert between file-based and LDAP
+.Em sudoers .
+However, there are features in the file-based sudoers that have
+no equivalent in LDAP-based sudoers (and vice versa).
+These cannot be converted automatically.
+.Pp
+For example, a Cmnd_Alias in a
+.Em sudoers
+file may be converted to a
+.Li sudoRole
+that contains multiple commands.
+Multiple users and/or groups may be assigned to the
+.Li sudoRole .
+.Pp
+Also, host, user, runas and command-based
+.Li Defaults
+entries are not supported.
+However, a
+.Li sudoRole
+may contain one or more
+.Li sudoOption
+attributes which can often serve the same purpose.
+.Pp
+Consider the following
+.Em sudoers
+lines:
+.Bd -literal -offset 4n
+Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+Defaults!PAGERS noexec
+alice, bob ALL = ALL
+.Ed
+.Pp
+In this example, alice and bob are allowed to run all commands, but
+the commands listed in PAGERS will have the noexec flag set,
+preventing shell escapes.
+.Pp
+When converting this to LDAP, two sudoRole objects can be used:
+.Bd -literal -offset 4n
+dn: cn=PAGERS,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: PAGERS
+sudoUser: alice
+sudoUser: bob
+sudoHost: ALL
+sudoCommand: /usr/bin/more
+sudoCommand: /usr/bin/pg
+sudoCommand: /usr/bin/less
+sudoOption: noexec
+sudoOrder: 900
+
+dn: cn=ADMINS,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: ADMINS
+sudoUser: alice
+sudoUser: bob
+sudoHost: ALL
+sudoCommand: ALL
+sudoOrder: 100
+.Ed
+.Pp
+In the LDAP version, the sudoOrder attribute is used to guarantee
+that the PAGERS sudoRole with
+.Em noexec
+has precedence.
+Unlike the
+.Em sudoers
+version, the LDAP version requires that all users for whom the restriction
+should apply be assigned to the PAGERS sudoRole.
+Using a Unix group or netgroup in PAGERS rather than listing each
+user would make this easier to maintain.
+.Pp
+Per-user
+.Li Defaults
+entries can be emulated by using one or more sudoOption attributes
+in a sudoRole.
+Consider the following
+.Em sudoers
+lines:
+.Bd -literal -offset 4n
+User_Alias ADMINS = john, sally
+Defaults:ADMINS !authenticate
+ADMINS ALL = (ALL:ALL) ALL
+.Ed
+.Pp
+In this example, john and sally are allowed to run any command
+as any user or group.
+.Pp
+When converting this to LDAP, we can use a Unix group instead
+of the User_Alias.
+.Bd -literal -offset 4n
+dn: cn=admins,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: admins
+sudoUser: %admin
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOption: !authenticate
+.Ed
+.Pp
+This assumes that users john and sally are members of the
+.Dq admins
+Unix group.
+.Ss Sudoers schema
+In order to use
+.Nm sudo Ns 's
+LDAP support, the
+.Nm sudo
+schema must be
+installed on your LDAP server.
+In addition, be sure to index the
+.Li sudoUser
+attribute.
+.Pp
+The
+.Nm sudo
+distribution includes versions of the
+.Nm sudoers
+schema for multiple LDAP servers:
+.Bl -tag -width 4n
+.It Pa schema.OpenLDAP
+OpenLDAP slapd and
+.Ox
+ldapd
+.It Pa schema.olcSudo
+OpenLDAP slapd 2.3 and higher when on-line configuration is enabled
+.It Pa schema.iPlanet
+Netscape-derived servers such as the iPlanet, Oracle,
+and 389 Directory Servers
+.It Pa schema.ActiveDirectory
+Microsoft Active Directory
+.El
+.Pp
+The schema in OpenLDAP format is also included in the
+.Sx EXAMPLES
+section.
+.Ss Configuring ldap.conf
+Sudo reads the
+.Pa @ldap_conf@
+file for LDAP-specific configuration.
+Typically, this file is shared between different LDAP-aware clients.
+As such, most of the settings are not
+.Nm sudo Ns -specific.
+Note that
+.Nm sudo
+parses
+.Pa @ldap_conf@
+itself and may support options that differ from those described in the
+system's
+.Xr ldap.conf @mansectform@
+manual.
+The path to
+.Pa ldap.conf
+may be overridden via the
+.Em ldap_conf
+plugin argument in
+.Xr sudo.conf @mansectform@ .
+.Pp
+Also note that on systems using the OpenLDAP libraries, default
+values specified in
+.Pa /etc/openldap/ldap.conf
+or the user's
+.Pa .ldaprc
+files are not used.
+.Pp
+Only those options explicitly listed in
+.Pa @ldap_conf@
+as being supported by
+.Nm sudo
+are honored.
+Configuration options are listed below in upper case but are parsed
+in a case-independent manner.
+.Pp
+Lines beginning with a pound sign
+.Pq Ql #
+are ignored.
+Leading white space is removed from the beginning of lines.
+.Bl -tag -width 4n
+.It Sy BIND_TIMELIMIT Ar seconds
+The
+.Sy BIND_TIMELIMIT
+parameter specifies the amount of time, in seconds, to wait while trying
+to connect to an LDAP server.
+If multiple
+.Sy URI Ns s
+or
+.Sy HOST Ns s
+are specified, this is the amount of time to wait before trying
+the next one in the list.
+.It Sy BINDDN Ar DN
+The
+.Sy BINDDN
+parameter specifies the identity, in the form of a Distinguished Name (DN),
+to use when performing LDAP operations.
+If not specified, LDAP operations are performed with an anonymous identity.
+By default, most LDAP servers will allow anonymous access.
+.It Sy BINDPW Ar secret
+The
+.Sy BINDPW
+parameter specifies the password to use when performing LDAP operations.
+This is typically used in conjunction with the
+.Sy BINDDN
+parameter.
+The
+.Ar secret
+may be a plain text password or a base64-encoded string with a
+.Dq base64:
+prefix.
+For example:
+.Bd -literal -offset 4n
+BINDPW base64:dGVzdA==
+.Ed
+.Pp
+If a plain text password is used, it should be a simple string without quotes.
+Plain text passwords may not include the comment character
+.Pq Ql #
+and the escaping of special characters with a backslash
+.Pq Ql \e
+is not supported.
+.It Sy DEREF Ar never/searching/finding/always
+How alias dereferencing is to be performed when searching.
+See the
+.Xr ldap.conf @mansectform@
+manual for a full description of this option.
+.It Sy HOST Ar name[:port] ...
+If no
+.Sy URI
+is specified (see below), the
+.Sy HOST
+parameter specifies a white space-delimited list of LDAP servers to connect to.
+Each host may include an optional
+.Em port
+separated by a colon
+.Pq Ql :\& .
+The
+.Sy HOST
+parameter is deprecated in favor of the
+.Sy URI
+specification and is included for backwards compatibility only.
+.It Sy KRB5_CCNAME Ar file name
+The path to the Kerberos 5 credential cache to use when authenticating
+with the remote server.
+This option is only relevant when using SASL authentication (see below).
+.It Sy LDAP_VERSION Ar number
+The version of the LDAP protocol to use when connecting to the server.
+The default value is protocol version 3.
+.It Sy NETGROUP_BASE Ar base
+The base DN to use when performing LDAP netgroup queries.
+Typically this is of the form
+.Li ou=netgroup,dc=my-domain,dc=com
+for the domain
+.Li my-domain.com .
+Multiple
+.Sy NETGROUP_BASE
+lines may be specified, in which case they are queried in the order specified.
+.Pp
+This option can be used to query a user's netgroups directly via LDAP
+which is usually faster than fetching every
+.Li sudoRole
+object containing a
+.Li sudoUser
+that begins with a
+.Ql +
+prefix.
+The NIS schema used by some LDAP servers need a modification to
+support querying the
+.Li nisNetgroup
+object by its
+.Li nisNetgroupTriple
+member.
+OpenLDAP's
+.Sy slapd
+requires the following change to the
+.Li nisNetgroupTriple
+attribute:
+.Bd -literal -offset 4n
+attributetype ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
+ DESC 'Netgroup triple'
+ EQUALITY caseIgnoreIA5Match
+ SUBSTR caseIgnoreIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+.Ed
+.It Sy NETGROUP_SEARCH_FILTER Ar ldap_filter
+An LDAP filter which is used to restrict the set of records returned
+when performing an LDAP netgroup query.
+Typically, this is of the
+form
+.Li attribute=value
+or
+.Li (&(attribute=value)(attribute2=value2)) .
+The default search filter is:
+.Li objectClass=nisNetgroup .
+If
+.Ar ldap_filter
+is omitted, no search filter will be used.
+This option is only when querying netgroups directly via LDAP.
+.It Sy NETWORK_TIMEOUT Ar seconds
+An alias for
+.Sy BIND_TIMELIMIT
+provided for OpenLDAP compatibility.
+.It Sy PORT Ar port_number
+If no
+.Sy URI
+is specified, the
+.Sy PORT
+parameter specifies the default port to connect to on the LDAP server if a
+.Sy HOST
+parameter does not specify the port itself.
+If no
+.Sy PORT
+parameter is used, the default is port 389 for LDAP and port 636 for LDAP
+over TLS (SSL).
+The
+.Sy PORT
+parameter is deprecated in favor of the
+.Sy URI
+specification and is included for backwards compatibility only.
+.It Sy ROOTBINDDN Ar DN
+The
+.Sy ROOTBINDDN
+parameter specifies the identity, in the form of a Distinguished Name (DN),
+to use when performing privileged LDAP operations, such as
+.Em sudoers
+queries.
+The password corresponding to the identity should be stored in the
+or the path specified by the
+.Em ldap_secret
+plugin argument in
+.Xr sudo.conf @mansectform@ ,
+which defaults to
+.Pa @ldap_secret@ .
+If no
+.Sy ROOTBINDDN
+is specified, the
+.Sy BINDDN
+identity is used (if any).
+.It Sy ROOTUSE_SASL Ar on/true/yes/off/false/no
+Enable
+.Sy ROOTUSE_SASL
+to enable SASL authentication when connecting
+to an LDAP server from a privileged process, such as
+.Nm sudo .
+.It Sy SASL_AUTH_ID Ar identity
+The SASL user name to use when connecting to the LDAP server.
+By default,
+.Nm sudo
+will use an anonymous connection.
+This option is only relevant when using SASL authentication.
+.It Sy SASL_MECH Ar mechanisms
+A white space-delimited list of SASL authentication mechanisms to use.
+By default,
+.Nm sudo
+will use
+.Dv GSSAPI
+authentication.
+.It Sy SASL_SECPROPS Ar none/properties
+SASL security properties or
+.Em none
+for no properties.
+See the SASL programmer's manual for details.
+This option is only relevant when using SASL authentication.
+.It Sy SSL Ar on/true/yes/off/false/no
+If the
+.Sy SSL
+parameter is set to
+.Li on ,
+.Li true
+.Li or
+.Li yes ,
+TLS (SSL) encryption is always used when communicating with the LDAP server.
+Typically, this involves connecting to the server on port 636 (ldaps).
+.It Sy SSL Ar start_tls
+If the
+.Sy SSL
+parameter is set to
+.Li start_tls ,
+the LDAP server connection is initiated normally and TLS encryption is
+begun before the bind credentials are sent.
+This has the advantage of not requiring a dedicated port for encrypted
+communications.
+This parameter is only supported by LDAP servers that honor the
+.Em start_tls
+extension, such as the OpenLDAP and Tivoli Directory servers.
+.It Sy SUDOERS_BASE Ar base
+The base DN to use when performing
+.Nm sudo
+LDAP queries.
+Typically this is of the form
+.Li ou=SUDOers,dc=my-domain,dc=com
+for the domain
+.Li my-domain.com .
+Multiple
+.Sy SUDOERS_BASE
+lines may be specified, in which case they are queried in the order specified.
+.It Sy SUDOERS_DEBUG Ar debug_level
+This sets the debug level for
+.Nm sudo
+LDAP queries.
+Debugging information is printed to the standard error.
+A value of 1 results in a moderate amount of debugging information.
+A value of 2 shows the results of the matches themselves.
+This parameter should not be set in a production environment as the
+extra information is likely to confuse users.
+.Pp
+The
+.Sy SUDOERS_DEBUG
+parameter is deprecated and will be removed in a future release.
+The same information is now logged via the
+.Nm sudo
+debugging framework using the
+.Dq ldap
+subsystem at priorities
+.Em diag
+and
+.Em info
+for
+.Em debug_level
+values 1 and 2 respectively.
+See the
+.Xr sudo.conf @mansectform@
+manual for details on how to configure
+.Nm sudo
+debugging.
+.It Sy SUDOERS_SEARCH_FILTER Ar ldap_filter
+An LDAP filter which is used to restrict the set of records returned
+when performing a
+.Nm sudo
+LDAP query.
+Typically, this is of the
+form
+.Li attribute=value
+or
+.Li (&(attribute=value)(attribute2=value2)) .
+The default search filter is:
+.Li objectClass=sudoRole .
+If
+.Ar ldap_filter
+is omitted, no search filter will be used.
+.It Sy SUDOERS_TIMED Ar on/true/yes/off/false/no
+Whether or not to evaluate the
+.Li sudoNotBefore
+and
+.Li sudoNotAfter
+attributes that implement time-dependent sudoers entries.
+.It Sy TIMELIMIT Ar seconds
+The
+.Sy TIMELIMIT
+parameter specifies the amount of time, in seconds, to wait for a
+response to an LDAP query.
+.It Sy TIMEOUT Ar seconds
+The
+.Sy TIMEOUT
+parameter specifies the amount of time, in seconds, to wait for a
+response from the various LDAP APIs.
+.It Sy TLS_CACERT Ar file name
+An alias for
+.Sy TLS_CACERTFILE
+for OpenLDAP compatibility.
+.It Sy TLS_CACERTFILE Ar file name
+The path to a certificate authority bundle which contains the certificates
+for all the Certificate Authorities the client knows to be valid, e.g.,
+.Pa /etc/ssl/ca-bundle.pem .
+This option is only supported by the OpenLDAP libraries.
+Netscape-derived LDAP libraries use the same certificate
+database for CA and client certificates (see
+.Sy TLS_CERT ) .
+.It Sy TLS_CACERTDIR Ar directory
+Similar to
+.Sy TLS_CACERTFILE
+but instead of a file, it is a directory containing individual
+Certificate Authority certificates, e.g.,
+.Pa /etc/ssl/certs .
+The directory specified by
+.Sy TLS_CACERTDIR
+is checked after
+.Sy TLS_CACERTFILE .
+This option is only supported by the OpenLDAP libraries.
+.It Sy TLS_CERT Ar file name
+The path to a file containing the client certificate which can
+be used to authenticate the client to the LDAP server.
+The certificate type depends on the LDAP libraries used.
+.Bl -tag -width 4n
+.It OpenLDAP:
+.Li tls_cert /etc/ssl/client_cert.pem
+.It Netscape-derived:
+.Li tls_cert /var/ldap/cert7.db
+.It Tivoli Directory Server:
+Unused, the key database specified by
+.Sy TLS_KEY
+contains both keys and certificates.
+.Pp
+When using Netscape-derived libraries, this file may also contain
+Certificate Authority certificates.
+.El
+.It Sy TLS_CHECKPEER Ar on/true/yes/off/false/no
+If enabled,
+.Sy TLS_CHECKPEER
+will cause the LDAP server's TLS certificated to be verified.
+If the server's TLS certificate cannot be verified (usually because it
+is signed by an unknown certificate authority),
+.Nm sudo
+will be unable to connect to it.
+If
+.Sy TLS_CHECKPEER
+is disabled, no check is made.
+Note that disabling the check creates an opportunity for man-in-the-middle
+attacks since the server's identity will not be authenticated.
+If possible, the CA's certificate should be installed locally so it can
+be verified.
+This option is not supported by the Tivoli Directory Server LDAP libraries.
+.It Sy TLS_KEY Ar file name
+The path to a file containing the private key which matches the
+certificate specified by
+.Sy TLS_CERT .
+The private key must not be password-protected.
+The key type depends on the LDAP libraries used.
+.Bl -tag -width 4n
+.It OpenLDAP:
+.Li tls_key /etc/ssl/client_key.pem
+.It Netscape-derived:
+.Li tls_key /var/ldap/key3.db
+.It Tivoli Directory Server:
+.Li tls_key /usr/ldap/ldapkey.kdb
+.El
+When using Tivoli LDAP libraries, this file may also contain
+Certificate Authority and client certificates and may be encrypted.
+.It Sy TLS_CIPHERS Ar cipher list
+The
+.Sy TLS_CIPHERS
+parameter allows the administer to restrict which encryption algorithms
+may be used for TLS (SSL) connections.
+See the OpenLDAP or Tivoli Directory Server manual for a list of valid
+ciphers.
+This option is not supported by Netscape-derived libraries.
+.It Sy TLS_KEYPW Ar secret
+The
+.Sy TLS_KEYPW
+contains the password used to decrypt the key database on clients
+using the Tivoli Directory Server LDAP library.
+The
+.Ar secret
+may be a plain text password or a base64-encoded string with a
+.Dq base64:
+prefix.
+For example:
+.Bd -literal -offset 4n
+TLS_KEYPW base64:dGVzdA==
+.Ed
+.Pp
+If a plain text password is used, it should be a simple string without quotes.
+Plain text passwords may not include the comment character
+.Pq Ql #
+and the escaping of special characters with a backslash
+.Pq Ql \e
+is not supported.
+If this option is used,
+.Pa @ldap_conf@
+must not be world-readable to avoid exposing the password.
+Alternately, a
+.Em stash file
+can be used to store the password in encrypted form (see below).
+.Pp
+If no
+.Sy TLS_KEYPW
+is specified, a
+.Em stash file
+will be used if it exists.
+The
+.Em stash file
+must have the same path as the file specified by
+.Sy TLS_KEY ,
+but use a
+.Li .sth
+file extension instead of
+.Li .kdb ,
+e.g.,
+.Li ldapkey.sth .
+The default
+.Li ldapkey.kdb
+that ships with Tivoli Directory Server is encrypted with the password
+.Li ssl_password .
+The
+.Em gsk8capicmd
+utility can be used to manage the key database and create a
+.Em stash file .
+This option is only supported by the Tivoli LDAP libraries.
+.It Sy TLS_REQCERT Ar level
+The
+.Sy TLS_REQCERT
+parameter controls how the LDAP server's TLS certificated will be
+verified (if at all).
+If the server's TLS certificate cannot be verified (usually because it
+is signed by an unknown certificate authority),
+.Nm sudo
+will be unable to connect to it.
+The following
+.Ar level
+values are supported:
+.Bl -tag -width 8n -offset 4n
+.It never
+The server certificate will not be requested or checked.
+.It allow
+The server certificate will be requested.
+A missing or invalid certificate is ignored and not considered an error.
+.It try
+The server certificate will be requested.
+A missing certificate is ignored but an invalid certificate will
+result in a connection error.
+.It demand | Ar hard
+The server certificate will be requested.
+A missing or invalid certificate will result in a connection error.
+This is the default behavior.
+.El
+.Pp
+This option is only supported by the OpenLDAP libraries.
+Other LDAP libraries only support the
+.Sy TLS_CHECKPEER
+parameter.
+.It Sy TLS_RANDFILE Ar file name
+The
+.Sy TLS_RANDFILE
+parameter specifies the path to an entropy source for systems that lack
+a random device.
+It is generally used in conjunction with
+.Em prngd
+or
+.Em egd .
+This option is only supported by the OpenLDAP libraries.
+.It Sy URI Ar ldap[s]://[hostname[:port]] ...
+Specifies a white space-delimited list of one or more URIs describing
+the LDAP server(s) to connect to.
+The
+.Em protocol
+may be either
+.Em ldap
+.Em ldaps ,
+the latter being for servers that support TLS (SSL) encryption.
+If no
+.Em port
+is specified, the default is port 389 for
+.Li ldap://
+or port 636 for
+.Li ldaps:// .
+If no
+.Em hostname
+is specified,
+.Nm sudo
+will connect to
+.Em localhost .
+Multiple
+.Sy URI
+lines are treated identically to a
+.Sy URI
+line containing multiple entries.
+Only systems using the OpenSSL libraries support the mixing of
+.Li ldap://
+and
+.Li ldaps://
+URIs.
+Both the Netscape-derived and Tivoli LDAP libraries used on most commercial
+versions of Unix are only capable of supporting one or the other.
+.It Sy USE_SASL Ar on/true/yes/off/false/no
+Enable
+.Sy USE_SASL
+for LDAP servers that support SASL authentication.
+.It Sy ROOTSASL_AUTH_ID Ar identity
+The SASL user name to use when
+.Sy ROOTUSE_SASL
+is enabled.
+.El
+.Pp
+See the
+.Pa ldap.conf
+entry in the
+.Sx EXAMPLES
+section.
+.Ss Configuring nsswitch.conf
+Unless it is disabled at build time,
+.Nm sudo
+consults the Name Service Switch file,
+.Pa @nsswitch_conf@ ,
+to specify the
+.Em sudoers
+search order.
+Sudo looks for a line beginning with
+.Li sudoers :
+and uses this to determine the search order.
+Note that
+.Nm sudo
+does
+not stop searching after the first match and later matches take
+precedence over earlier ones.
+The following sources are recognized:
+.Pp
+.Bl -tag -width 8n -offset 4n -compact
+.It files
+read sudoers from
+.Pa @sysconfdir@/sudoers
+.It ldap
+read sudoers from LDAP
+.El
+.Pp
+In addition, the entry
+.Li [NOTFOUND=return]
+will short-circuit the search if the user was not found in the
+preceding source.
+.Pp
+To consult LDAP first followed by the local sudoers file (if it
+exists), use:
+.Bd -literal -offset 4n
+sudoers: ldap files
+.Ed
+.Pp
+The local
+.Em sudoers
+file can be ignored completely by using:
+.Bd -literal -offset 4n
+sudoers: ldap
+.Ed
+.Pp
+If the
+.Pa @nsswitch_conf@
+file is not present or there is no sudoers line, the following
+default is assumed:
+.Bd -literal -offset 4n
+sudoers: files
+.Ed
+.Pp
+Note that
+.Pa @nsswitch_conf@
+is supported even when the underlying operating system does not use
+an nsswitch.conf file, except on AIX (see below).
+.Ss Configuring netsvc.conf
+On AIX systems, the
+.Pa @netsvc_conf@
+file is consulted instead of
+.Pa @nsswitch_conf@ .
+.Nm sudo
+simply treats
+.Pa netsvc.conf
+as a variant of
+.Pa nsswitch.conf ;
+information in the previous section unrelated to the file format
+itself still applies.
+.Pp
+To consult LDAP first followed by the local sudoers file (if it
+exists), use:
+.Bd -literal -offset 4n
+sudoers = ldap, files
+.Ed
+.Pp
+The local
+.Em sudoers
+file can be ignored completely by using:
+.Bd -literal -offset 4n
+sudoers = ldap
+.Ed
+.Pp
+To treat LDAP as authoritative and only use the local sudoers file
+if the user is not present in LDAP, use:
+.Bd -literal -offset 4n
+sudoers = ldap = auth, files
+.Ed
+.Pp
+Note that in the above example, the
+.Li auth
+qualifier only affects user lookups; both LDAP and
+.Em sudoers
+will be queried for
+.Li Defaults
+entries.
+.Pp
+If the
+.Pa @netsvc_conf@
+file is not present or there is no sudoers line, the following
+default is assumed:
+.Bd -literal -offset 4n
+sudoers = files
+.Ed
+.Ss Integration with sssd
+On systems with the
+.Em System Security Services Daemon
+(SSSD) and where
+.Nm sudo
+has been built with SSSD support,
+it is possible to use SSSD to cache LDAP
+.Em sudoers
+rules.
+To use SSSD as the
+.Em sudoers
+source, you should use
+.Li sssd
+instead of
+.Li ldap
+for the sudoers entry in
+.Pa @nsswitch_conf@ .
+Note that the
+.Pa @ldap_conf@
+file is not used by the SSSD
+.Nm sudo
+back end.
+Please see
+.Xr sssd-sudo @mansectform@
+for more information on configuring
+.Nm sudo
+to work with SSSD.
+.Sh FILES
+.Bl -tag -width 24n
+.It Pa @ldap_conf@
+LDAP configuration file
+.It Pa @nsswitch_conf@
+determines sudoers source order
+.It Pa @netsvc_conf@
+determines sudoers source order on AIX
+.El
+.Sh EXAMPLES
+.Ss Example ldap.conf
+.Bd -literal -offset 2n
+# Either specify one or more URIs or one or more host:port pairs.
+# If neither is specified sudo will default to localhost, port 389.
+#
+#host ldapserver
+#host ldapserver1 ldapserver2:390
+#
+# Default port if host is specified without one, defaults to 389.
+#port 389
+#
+# URI will override the host and port settings.
+uri ldap://ldapserver
+#uri ldaps://secureldapserver
+#uri ldaps://secureldapserver ldap://ldapserver
+#
+# The amount of time, in seconds, to wait while trying to connect to
+# an LDAP server.
+bind_timelimit 30
+#
+# The amount of time, in seconds, to wait while performing an LDAP query.
+timelimit 30
+#
+# Must be set or sudo will ignore LDAP; may be specified multiple times.
+sudoers_base ou=SUDOers,dc=my-domain,dc=com
+#
+# verbose sudoers matching from ldap
+#sudoers_debug 2
+#
+# Enable support for time-based entries in sudoers.
+#sudoers_timed yes
+#
+# optional proxy credentials
+#binddn <who to search as>
+#bindpw <password>
+#rootbinddn <who to search as, uses /etc/ldap.secret for bindpw>
+#
+# LDAP protocol version, defaults to 3
+#ldap_version 3
+#
+# Define if you want to use an encrypted LDAP connection.
+# Typically, you must also set the port to 636 (ldaps).
+#ssl on
+#
+# Define if you want to use port 389 and switch to
+# encryption before the bind credentials are sent.
+# Only supported by LDAP servers that support the start_tls
+# extension such as OpenLDAP.
+#ssl start_tls
+#
+# Additional TLS options follow that allow tweaking of the
+# SSL/TLS connection.
+#
+#tls_checkpeer yes # verify server SSL certificate
+#tls_checkpeer no # ignore server SSL certificate
+#
+# If you enable tls_checkpeer, specify either tls_cacertfile
+# or tls_cacertdir. Only supported when using OpenLDAP.
+#
+#tls_cacertfile /etc/certs/trusted_signers.pem
+#tls_cacertdir /etc/certs
+#
+# For systems that don't have /dev/random
+# use this along with PRNGD or EGD.pl to seed the
+# random number pool to generate cryptographic session keys.
+# Only supported when using OpenLDAP.
+#
+#tls_randfile /etc/egd-pool
+#
+# You may restrict which ciphers are used. Consult your SSL
+# documentation for which options go here.
+# Only supported when using OpenLDAP.
+#
+#tls_ciphers <cipher-list>
+#
+# Sudo can provide a client certificate when communicating to
+# the LDAP server.
+# Tips:
+# * Enable both lines at the same time.
+# * Do not password protect the key file.
+# * Ensure the keyfile is only readable by root.
+#
+# For OpenLDAP:
+#tls_cert /etc/certs/client_cert.pem
+#tls_key /etc/certs/client_key.pem
+#
+# For SunONE or iPlanet LDAP, tls_cert and tls_key may specify either
+# a directory, in which case the files in the directory must have the
+# default names (e.g., cert8.db and key4.db), or the path to the cert
+# and key files themselves. However, a bug in version 5.0 of the LDAP
+# SDK will prevent specific file names from working. For this reason
+# it is suggested that tls_cert and tls_key be set to a directory,
+# not a file name.
+#
+# The certificate database specified by tls_cert may contain CA certs
+# and/or the client's cert. If the client's cert is included, tls_key
+# should be specified as well.
+# For backward compatibility, "sslpath" may be used in place of tls_cert.
+#tls_cert /var/ldap
+#tls_key /var/ldap
+#
+# If using SASL authentication for LDAP (OpenSSL)
+# use_sasl yes
+# sasl_auth_id <SASL user name>
+# rootuse_sasl yes
+# rootsasl_auth_id <SASL user name for root access>
+# sasl_secprops none
+# krb5_ccname /etc/.ldapcache
+.Ed
+.Ss Sudoers schema for OpenLDAP
+The following schema, in OpenLDAP format, is included with
+.Nm sudo
+source and binary distributions as
+.Pa schema.OpenLDAP .
+Simply copy
+it to the schema directory (e.g.,
+.Pa /etc/openldap/schema ) ,
+add the proper
+.Li include
+line in
+.Pa slapd.conf
+and restart
+.Nm slapd .
+Sites using the optional on-line configuration supported by OpenLDAP 2.3
+and higher should apply the
+.Pa schema.olcSudo
+file instead.
+.Bd -literal -offset 2n
+attributetype ( 1.3.6.1.4.1.15953.9.1.1
+ NAME 'sudoUser'
+ DESC 'User(s) who may run sudo'
+ EQUALITY caseExactIA5Match
+ SUBSTR caseExactIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.2
+ NAME 'sudoHost'
+ DESC 'Host(s) who may run sudo'
+ EQUALITY caseExactIA5Match
+ SUBSTR caseExactIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.3
+ NAME 'sudoCommand'
+ DESC 'Command(s) to be executed by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.4
+ NAME 'sudoRunAs'
+ DESC 'User(s) impersonated by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.5
+ NAME 'sudoOption'
+ DESC 'Options(s) followed by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.6
+ NAME 'sudoRunAsUser'
+ DESC 'User(s) impersonated by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.7
+ NAME 'sudoRunAsGroup'
+ DESC 'Group(s) impersonated by sudo'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.8
+ NAME 'sudoNotBefore'
+ DESC 'Start of time interval for which the entry is valid'
+ EQUALITY generalizedTimeMatch
+ ORDERING generalizedTimeOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.9
+ NAME 'sudoNotAfter'
+ DESC 'End of time interval for which the entry is valid'
+ EQUALITY generalizedTimeMatch
+ ORDERING generalizedTimeOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
+
+attributetype ( 1.3.6.1.4.1.15953.9.1.10
+ NAME 'sudoOrder'
+ DESC 'an integer to order the sudoRole entries'
+ EQUALITY integerMatch
+ ORDERING integerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL
+ DESC 'Sudoer Entries'
+ MUST ( cn )
+ MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $
+ sudoRunAsGroup $ sudoOption $ sudoNotBefore $ sudoNotAfter $
+ sudoOrder $ description )
+ )
+.Ed
+.Sh SEE ALSO
+.Xr cvtsudoers 1 ,
+.Xr ldap.conf @mansectform@ ,
+.Xr sssd-sudo @mansectform@ ,
+.Xr sudo.conf @mansectform@ ,
+.Xr sudoers @mansectform@
+.Sh AUTHORS
+Many people have worked on
+.Nm sudo
+over the years; this version consists of code written primarily by:
+.Bd -ragged -offset indent
+.An Todd C. Miller
+.Ed
+.Pp
+See the CONTRIBUTORS file in the
+.Nm sudo
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+.Nm sudo .
+.Sh CAVEATS
+Note that there are differences in the way that LDAP-based
+.Em sudoers
+is parsed compared to file-based
+.Em sudoers .
+See the
+.Sx Differences between LDAP and non-LDAP sudoers
+section for more information.
+.Sh BUGS
+If you feel you have found a bug in
+.Nm sudo ,
+please submit a bug report at https://bugzilla.sudo.ws/
+.Sh SUPPORT
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.Sh DISCLAIMER
+.Nm sudo
+is provided
+.Dq AS IS
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+.Nm sudo
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/sudoers.man.in b/doc/sudoers.man.in
new file mode 100644
index 0000000..e2470b5
--- /dev/null
+++ b/doc/sudoers.man.in
@@ -0,0 +1,5831 @@
+.\" Automatically generated from an mdoc input file. Do not edit.
+.\"
+.\" Copyright (c) 1994-1996, 1998-2005, 2007-2018
+.\" Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Sponsored in part by the Defense Advanced Research Projects
+.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
+.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
+.\"
+.nr SL @SEMAN@
+.nr BA @BAMAN@
+.nr LC @LCMAN@
+.nr PS @PSMAN@
+.TH "SUDOERS" "@mansectform@" "December 20, 2018" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
+.nh
+.if n .ad l
+.SH "NAME"
+\fBsudoers\fR
+\- default sudo security policy plugin
+.SH "DESCRIPTION"
+The
+\fBsudoers\fR
+policy plugin determines a user's
+\fBsudo\fR
+privileges.
+It is the default
+\fBsudo\fR
+policy plugin.
+The policy is driven by
+the
+\fI@sysconfdir@/sudoers\fR
+file or, optionally in LDAP.
+The policy format is described in detail in the
+\fISUDOERS FILE FORMAT\fR
+section.
+For information on storing
+\fBsudoers\fR
+policy information
+in LDAP, please see
+sudoers.ldap(@mansectform@).
+.SS "Configuring sudo.conf for sudoers"
+\fBsudo\fR
+consults the
+sudo.conf(@mansectform@)
+file to determine which policy and I/O logging plugins to load.
+If no
+sudo.conf(@mansectform@)
+file is present, or if it contains no
+\fRPlugin\fR
+lines,
+\fBsudoers\fR
+will be used for policy decisions and I/O logging.
+To explicitly configure
+sudo.conf(@mansectform@)
+to use the
+\fBsudoers\fR
+plugin, the following configuration can be used.
+.nf
+.sp
+.RS 6n
+Plugin sudoers_policy sudoers.so
+Plugin sudoers_io sudoers.so
+.RE
+.fi
+.PP
+Starting with
+\fBsudo\fR
+1.8.5, it is possible to specify optional arguments to the
+\fBsudoers\fR
+plugin in the
+sudo.conf(@mansectform@)
+file.
+These arguments, if present, should be listed after the path to the plugin
+(i.e., after
+\fIsudoers.so\fR).
+Multiple arguments may be specified, separated by white space.
+For example:
+.nf
+.sp
+.RS 6n
+Plugin sudoers_policy sudoers.so sudoers_mode=0400
+.RE
+.fi
+.PP
+The following plugin arguments are supported:
+.TP 10n
+ldap_conf=pathname
+The
+\fIldap_conf\fR
+argument can be used to override the default path to the
+\fIldap.conf\fR
+file.
+.TP 10n
+ldap_secret=pathname
+The
+\fIldap_secret\fR
+argument can be used to override the default path to the
+\fIldap.secret\fR
+file.
+.TP 10n
+sudoers_file=pathname
+The
+\fIsudoers_file\fR
+argument can be used to override the default path to the
+\fIsudoers\fR
+file.
+.TP 10n
+sudoers_uid=uid
+The
+\fIsudoers_uid\fR
+argument can be used to override the default owner of the sudoers file.
+It should be specified as a numeric user ID.
+.TP 10n
+sudoers_gid=gid
+The
+\fIsudoers_gid\fR
+argument can be used to override the default group of the sudoers file.
+It must be specified as a numeric group ID (not a group name).
+.TP 10n
+sudoers_mode=mode
+The
+\fIsudoers_mode\fR
+argument can be used to override the default file mode for the sudoers file.
+It should be specified as an octal value.
+.PP
+For more information on configuring
+sudo.conf(@mansectform@),
+please refer to its manual.
+.SS "User Authentication"
+The
+\fBsudoers\fR
+security policy requires that most users authenticate
+themselves before they can use
+\fBsudo\fR.
+A password is not required
+if the invoking user is root, if the target user is the same as the
+invoking user, or if the policy has disabled authentication for the
+user or command.
+Unlike
+su(1),
+when
+\fBsudoers\fR
+requires
+authentication, it validates the invoking user's credentials, not
+the target user's (or root's) credentials.
+This can be changed via
+the
+\fIrootpw\fR,
+\fItargetpw\fR
+and
+\fIrunaspw\fR
+flags, described later.
+.PP
+If a user who is not listed in the policy tries to run a command
+via
+\fBsudo\fR,
+mail is sent to the proper authorities.
+The address
+used for such mail is configurable via the
+\fImailto\fR
+Defaults entry
+(described later) and defaults to
+\fR@mailto@\fR.
+.PP
+Note that no mail will be sent if an unauthorized user tries to run
+\fBsudo\fR
+with the
+\fB\-l\fR
+or
+\fB\-v\fR
+option unless there is an authentication error and
+either the
+\fImail_always\fR
+or
+\fImail_badpass\fR
+flags are enabled.
+This allows users to
+determine for themselves whether or not they are allowed to use
+\fBsudo\fR.
+All attempts to run
+\fBsudo\fR
+(successful or not)
+will be logged, regardless of whether or not mail is sent.
+.PP
+If
+\fBsudo\fR
+is run by root and the
+\fRSUDO_USER\fR
+environment variable
+is set, the
+\fBsudoers\fR
+policy will use this value to determine who
+the actual user is.
+This can be used by a user to log commands
+through sudo even when a root shell has been invoked.
+It also
+allows the
+\fB\-e\fR
+option to remain useful even when invoked via a
+sudo-run script or program.
+Note, however, that the
+\fIsudoers\fR
+file lookup is still done for root, not the user specified by
+\fRSUDO_USER\fR.
+.PP
+\fBsudoers\fR
+uses per-user time stamp files for credential caching.
+Once a user has been authenticated, a record is written
+containing the user ID that was used to authenticate, the
+terminal session ID, the start time of the session leader
+(or parent process) and a time stamp
+(using a monotonic clock if one is available).
+The user may then use
+\fBsudo\fR
+without a password for a short period of time
+(\fR@timeout@\fR
+minutes unless overridden by the
+\fItimestamp_timeout\fR
+option)
+\&.
+By default,
+\fBsudoers\fR
+uses a separate record for each terminal, which means that
+a user's login sessions are authenticated separately.
+The
+\fItimestamp_type\fR
+option can be used to select the type of time stamp record
+\fBsudoers\fR
+will use.
+.SS "Logging"
+\fBsudoers\fR
+can log both successful and unsuccessful attempts (as well
+as errors) to
+syslog(3),
+a log file, or both.
+By default,
+\fBsudoers\fR
+will log via
+syslog(3)
+but this is changeable via the
+\fIsyslog\fR
+and
+\fIlogfile\fR
+Defaults settings.
+See
+\fILOG FORMAT\fR
+for a description of the log file format.
+.PP
+\fBsudoers\fR
+is also capable of running a command in a pseudo-tty and logging all
+input and/or output.
+The standard input, standard output and standard error can be logged
+even when not associated with a terminal.
+I/O logging is not on by default but can be enabled using
+the
+\fIlog_input\fR
+and
+\fIlog_output\fR
+options as well as the
+\fRLOG_INPUT\fR
+and
+\fRLOG_OUTPUT\fR
+command tags.
+See
+\fII/O LOG FILES\fR
+for details on how I/O log files are stored.
+.SS "Command environment"
+Since environment variables can influence program behavior,
+\fBsudoers\fR
+provides a means to restrict which variables from the user's
+environment are inherited by the command to be run.
+There are two
+distinct ways
+\fBsudoers\fR
+can deal with environment variables.
+.PP
+By default, the
+\fIenv_reset\fR
+option is enabled.
+This causes commands
+to be executed with a new, minimal environment.
+On AIX (and Linux
+systems without PAM), the environment is initialized with the
+contents of the
+\fI/etc/environment\fR
+file.
+.if \n(LC \{\
+On
+BSD
+systems, if the
+\fIuse_loginclass\fR
+option is enabled, the environment is initialized
+based on the
+\fIpath\fR
+and
+\fIsetenv\fR
+settings in
+\fI/etc/login.conf\fR.
+.\}
+The new environment contains the
+\fRTERM\fR,
+\fRPATH\fR,
+\fRHOME\fR,
+\fRMAIL\fR,
+\fRSHELL\fR,
+\fRLOGNAME\fR,
+\fRUSER\fR
+and
+\fRSUDO_*\fR
+variables
+in addition to variables from the invoking process permitted by the
+\fIenv_check\fR
+and
+\fIenv_keep\fR
+options.
+This is effectively a whitelist
+for environment variables.
+The environment variables
+\fRLOGNAME\fR
+and
+\fRUSER\fR
+are treated specially.
+If one of them is preserved (or removed) from user's environment, the other
+will be as well.
+If
+\fRLOGNAME\fR
+and
+\fRUSER\fR
+are to be preserved but only one of them is present in the user's environment,
+the other will be set to the same value.
+This avoids an inconsistent environment where one of the variables
+describing the user name is set to the invoking user and one is
+set to the target user.
+\fR()\fR
+are removed unless both the name and value parts are matched by
+\fIenv_keep\fR
+or
+\fIenv_check\fR,
+as they may be interpreted as functions by the
+\fBbash\fR
+shell.
+Prior to version 1.8.11, such variables were always removed.
+.PP
+If, however, the
+\fIenv_reset\fR
+option is disabled, any variables not
+explicitly denied by the
+\fIenv_check\fR
+and
+\fIenv_delete\fR
+options are
+inherited from the invoking process.
+In this case,
+\fIenv_check\fR
+and
+\fIenv_delete\fR
+behave like a blacklist.
+Prior to version 1.8.21, environment variables with a value beginning with
+\fR()\fR
+were always removed.
+Beginning with version 1.8.21, a pattern in
+\fIenv_delete\fR
+is used to match
+\fBbash\fR
+shell functions instead.
+Since it is not possible
+to blacklist all potentially dangerous environment variables, use
+of the default
+\fIenv_reset\fR
+behavior is encouraged.
+.PP
+Environment variables specified by
+\fIenv_check\fR,
+\fIenv_delete\fR,
+or
+\fIenv_keep\fR
+may include one or more
+\(oq*\(cq
+characters which will match zero or more characters.
+No other wildcard characters are supported.
+.PP
+By default, environment variables are matched by name.
+However, if the pattern includes an equal sign
+(\(oq=\&\(cq),
+both the variables name and value must match.
+For example, a
+\fBbash\fR
+shell function could be matched as follows:
+.nf
+.sp
+.RS 4n
+env_keep += "BASH_FUNC_my_func%%=()*"
+.RE
+.fi
+.PP
+Without the
+\(lq\fR=()*\fR\(rq
+suffix, this would not match, as
+\fBbash\fR
+shell functions are not preserved by default.
+.PP
+The complete list of environment variables that
+\fBsudo\fR
+allows or denies is contained in the output of
+\(lq\fRsudo -V\fR\(rq
+when run as root.
+Please note that this list varies based on the operating system
+\fBsudo\fR
+is running on.
+.PP
+On systems that support PAM where the
+\fBpam_env\fR
+module is enabled for
+\fBsudo\fR,
+variables in the PAM environment may be merged in to the environment.
+If a variable in the PAM environment is already present in the
+user's environment, the value will only be overridden if the variable
+was not preserved by
+\fBsudoers\fR.
+When
+\fIenv_reset\fR
+is enabled, variables preserved from the invoking user's environment
+by the
+\fIenv_keep\fR
+list take precedence over those in the PAM environment.
+When
+\fIenv_reset\fR
+is disabled, variables present the invoking user's environment
+take precedence over those in the PAM environment unless they
+match a pattern in the
+\fIenv_delete\fR
+list.
+.PP
+Note that the dynamic linker on most operating systems will remove
+variables that can control dynamic linking from the environment of
+setuid executables, including
+\fBsudo\fR.
+Depending on the operating
+system this may include
+\fR_RLD*\fR,
+\fRDYLD_*\fR,
+\fRLD_*\fR,
+\fRLDR_*\fR,
+\fRLIBPATH\fR,
+\fRSHLIB_PATH\fR,
+and others.
+These type of variables are
+removed from the environment before
+\fBsudo\fR
+even begins execution
+and, as such, it is not possible for
+\fBsudo\fR
+to preserve them.
+.PP
+As a special case, if
+\fBsudo\fR's
+\fB\-i\fR
+option (initial login) is
+specified,
+\fBsudoers\fR
+will initialize the environment regardless
+of the value of
+\fIenv_reset\fR.
+The
+\fRDISPLAY\fR,
+\fRPATH\fR
+and
+\fRTERM\fR
+variables remain unchanged;
+\fRHOME\fR,
+\fRMAIL\fR,
+\fRSHELL\fR,
+\fRUSER\fR,
+and
+\fRLOGNAME\fR
+are set based on the target user.
+On AIX (and Linux
+systems without PAM), the contents of
+\fI/etc/environment\fR
+are also
+included.
+.if \n(LC \{\
+On
+BSD
+systems, if the
+\fIuse_loginclass\fR
+flag is
+enabled, the
+\fIpath\fR
+and
+\fIsetenv\fR
+variables in
+\fI/etc/login.conf\fR
+are also applied.
+.\}
+All other environment variables are removed unless permitted by
+\fIenv_keep\fR
+or
+\fIenv_check\fR,
+described above.
+.PP
+Finally, the
+\fIrestricted_env_file\fR
+and
+\fIenv_file\fR
+files are applied, if present.
+The variables in
+\fIrestricted_env_file\fR
+are applied first and are subject to the same restrictions as the
+invoking user's environment, as detailed above.
+The variables in
+\fIenv_file\fR
+are applied last and are not subject to these restrictions.
+In both cases, variables present in the files will only be set to
+their specified values if they would not conflict with an existing
+environment variable.
+.SH "SUDOERS FILE FORMAT"
+The
+\fIsudoers\fR
+file is composed of two types of entries: aliases
+(basically variables) and user specifications (which specify who
+may run what).
+.PP
+When multiple entries match for a user, they are applied in order.
+Where there are multiple matches, the last match is used (which is
+not necessarily the most specific match).
+.PP
+The
+\fIsudoers\fR
+file grammar will be described below in Extended Backus-Naur
+Form (EBNF).
+Don't despair if you are unfamiliar with EBNF; it is fairly simple,
+and the definitions below are annotated.
+.SS "Quick guide to EBNF"
+EBNF is a concise and exact way of describing the grammar of a language.
+Each EBNF definition is made up of
+\fIproduction rules\fR.
+E.g.,
+.PP
+\fRsymbol ::= definition\fR | \fRalternate1\fR | \fRalternate2 ...\fR
+.PP
+Each
+\fIproduction rule\fR
+references others and thus makes up a
+grammar for the language.
+EBNF also contains the following
+operators, which many readers will recognize from regular
+expressions.
+Do not, however, confuse them with
+\(lqwildcard\(rq
+characters, which have different meanings.
+.TP 6n
+\fR\&?\fR
+Means that the preceding symbol (or group of symbols) is optional.
+That is, it may appear once or not at all.
+.TP 6n
+\fR*\fR
+Means that the preceding symbol (or group of symbols) may appear
+zero or more times.
+.TP 6n
+\fR+\fR
+Means that the preceding symbol (or group of symbols) may appear
+one or more times.
+.PP
+Parentheses may be used to group symbols together.
+For clarity,
+we will use single quotes
+('')
+to designate what is a verbatim character string (as opposed to a symbol name).
+.SS "Aliases"
+There are four kinds of aliases:
+\fRUser_Alias\fR,
+\fRRunas_Alias\fR,
+\fRHost_Alias\fR
+and
+\fRCmnd_Alias\fR.
+.nf
+.sp
+.RS 0n
+Alias ::= 'User_Alias' User_Alias_Spec (':' User_Alias_Spec)* |
+ 'Runas_Alias' Runas_Alias_Spec (':' Runas_Alias_Spec)* |
+ 'Host_Alias' Host_Alias_Spec (':' Host_Alias_Spec)* |
+ 'Cmnd_Alias' Cmnd_Alias_Spec (':' Cmnd_Alias_Spec)*
+
+User_Alias ::= NAME
+
+User_Alias_Spec ::= User_Alias '=' User_List
+
+Runas_Alias ::= NAME
+
+Runas_Alias_Spec ::= Runas_Alias '=' Runas_List
+
+Host_Alias ::= NAME
+
+Host_Alias_Spec ::= Host_Alias '=' Host_List
+
+Cmnd_Alias ::= NAME
+
+Cmnd_Alias_Spec ::= Cmnd_Alias '=' Cmnd_List
+
+NAME ::= [A-Z]([A-Z][0-9]_)*
+.RE
+.fi
+.PP
+Each
+\fIalias\fR
+definition is of the form
+.nf
+.sp
+.RS 0n
+Alias_Type NAME = item1, item2, ...
+.RE
+.fi
+.PP
+where
+\fIAlias_Type\fR
+is one of
+\fRUser_Alias\fR,
+\fRRunas_Alias\fR,
+\fRHost_Alias\fR,
+or
+\fRCmnd_Alias\fR.
+A
+\fRNAME\fR
+is a string of uppercase letters, numbers,
+and underscore characters
+(\(oq_\(cq).
+A
+\fRNAME\fR
+\fBmust\fR
+start with an
+uppercase letter.
+It is possible to put several alias definitions
+of the same type on a single line, joined by a colon
+(\(oq:\&\(cq).
+E.g.,
+.nf
+.sp
+.RS 0n
+Alias_Type NAME = item1, item2, item3 : NAME = item4, item5
+.RE
+.fi
+.PP
+It is a syntax error to redefine an existing
+\fIalias\fR.
+It is possible to use the same name for
+\fIaliases\fR
+of different types, but this is not recommended.
+.PP
+The definitions of what constitutes a valid
+\fIalias\fR
+member follow.
+.nf
+.sp
+.RS 0n
+User_List ::= User |
+ User ',' User_List
+
+User ::= '!'* user name |
+ '!'* #uid |
+ '!'* %group |
+ '!'* %#gid |
+ '!'* +netgroup |
+ '!'* %:nonunix_group |
+ '!'* %:#nonunix_gid |
+ '!'* User_Alias
+.RE
+.fi
+.PP
+A
+\fRUser_List\fR
+is made up of one or more user names, user IDs
+(prefixed with
+\(oq#\(cq),
+system group names and IDs (prefixed with
+\(oq%\(cq
+and
+\(oq%#\(cq
+respectively), netgroups (prefixed with
+\(oq+\(cq),
+non-Unix group names and IDs (prefixed with
+\(oq%:\(cq
+and
+\(oq%:#\(cq
+respectively) and
+\fRUser_Alias\fRes.
+Each list item may be prefixed with zero or more
+\(oq\&!\(cq
+operators.
+An odd number of
+\(oq\&!\(cq
+operators negate the value of
+the item; an even number just cancel each other out.
+User netgroups are matched using the user and domain members only;
+the host member is not used when matching.
+.PP
+A
+\fRuser name\fR,
+\fRuid\fR,
+\fRgroup\fR,
+\fRgid\fR,
+\fRnetgroup\fR,
+\fRnonunix_group\fR
+or
+\fRnonunix_gid\fR
+may be enclosed in double quotes to avoid the
+need for escaping special characters.
+Alternately, special characters
+may be specified in escaped hex mode, e.g., \ex20 for space.
+When
+using double quotes, any prefix characters must be included inside
+the quotes.
+.PP
+The actual
+\fRnonunix_group\fR
+and
+\fRnonunix_gid\fR
+syntax depends on
+the underlying group provider plugin.
+For instance, the QAS AD plugin supports the following formats:
+.TP 3n
+\fB\(bu\fR
+Group in the same domain: "%:Group Name"
+.TP 3n
+\fB\(bu\fR
+Group in any domain: "%:Group Name@FULLY.QUALIFIED.DOMAIN"
+.TP 3n
+\fB\(bu\fR
+Group SID: "%:S-1-2-34-5678901234-5678901234-5678901234-567"
+.PP
+See
+\fIGROUP PROVIDER PLUGINS\fR
+for more information.
+.PP
+Note that quotes around group names are optional.
+Unquoted strings must use a backslash
+(\(oq\e\(cq)
+to escape spaces and special characters.
+See
+\fIOther special characters and reserved words\fR
+for a list of
+characters that need to be escaped.
+.nf
+.sp
+.RS 0n
+Runas_List ::= Runas_Member |
+ Runas_Member ',' Runas_List
+
+Runas_Member ::= '!'* user name |
+ '!'* #uid |
+ '!'* %group |
+ '!'* %#gid |
+ '!'* %:nonunix_group |
+ '!'* %:#nonunix_gid |
+ '!'* +netgroup |
+ '!'* Runas_Alias
+.RE
+.fi
+.PP
+A
+\fRRunas_List\fR
+is similar to a
+\fRUser_List\fR
+except that instead
+of
+\fRUser_Alias\fRes
+it can contain
+\fRRunas_Alias\fRes.
+Note that
+user names and groups are matched as strings.
+In other words, two
+users (groups) with the same uid (gid) are considered to be distinct.
+If you wish to match all user names with the same uid (e.g.,
+root and toor), you can use a uid instead (#0 in the example given).
+.nf
+.sp
+.RS 0n
+Host_List ::= Host |
+ Host ',' Host_List
+
+Host ::= '!'* host name |
+ '!'* ip_addr |
+ '!'* network(/netmask)? |
+ '!'* +netgroup |
+ '!'* Host_Alias
+.RE
+.fi
+.PP
+A
+\fRHost_List\fR
+is made up of one or more host names, IP addresses,
+network numbers, netgroups (prefixed with
+\(oq+\(cq)
+and other aliases.
+Again, the value of an item may be negated with the
+\(oq\&!\(cq
+operator.
+Host netgroups are matched using the host (both qualified and unqualified)
+and domain members only; the user member is not used when matching.
+If you specify a network number without a netmask,
+\fBsudo\fR
+will query each of the local host's network interfaces and,
+if the network number corresponds to one of the hosts's network
+interfaces, will use the netmask of that interface.
+The netmask may be specified either in standard IP address notation
+(e.g., 255.255.255.0 or ffff:ffff:ffff:ffff::),
+or CIDR notation (number of bits, e.g., 24 or 64).
+A host name may include shell-style wildcards (see the
+\fIWildcards\fR
+section below),
+but unless the
+\fRhost name\fR
+command on your machine returns the fully
+qualified host name, you'll need to use the
+\fIfqdn\fR
+option for wildcards to be useful.
+Note that
+\fBsudo\fR
+only inspects actual network interfaces; this means that IP address
+127.0.0.1 (localhost) will never match.
+Also, the host name
+\(lqlocalhost\(rq
+will only match if that is the actual host name, which is usually
+only the case for non-networked systems.
+.nf
+.sp
+.RS 0n
+digest ::= [A-Fa-f0-9]+ |
+ [[A-Za-z0-9\+/=]+
+
+Digest_Spec ::= "sha224" ':' digest |
+ "sha256" ':' digest |
+ "sha384" ':' digest |
+ "sha512" ':' digest
+
+Cmnd_List ::= Cmnd |
+ Cmnd ',' Cmnd_List
+
+command name ::= file name |
+ file name args |
+ file name '""'
+
+Cmnd ::= Digest_Spec? '!'* command name |
+ '!'* directory |
+ '!'* "sudoedit" |
+ '!'* Cmnd_Alias
+.RE
+.fi
+.PP
+A
+\fRCmnd_List\fR
+is a list of one or more command names, directories, and other aliases.
+A command name is a fully qualified file name which may include
+shell-style wildcards (see the
+\fIWildcards\fR
+section below).
+A simple file name allows the user to run the command with any
+arguments he/she wishes.
+However, you may also specify command line arguments (including
+wildcards).
+Alternately, you can specify
+\fR\&""\fR
+to indicate that the command
+may only be run
+\fBwithout\fR
+command line arguments.
+A directory is a
+fully qualified path name ending in a
+\(oq/\(cq.
+When you specify a directory in a
+\fRCmnd_List\fR,
+the user will be able to run any file within that directory
+(but not in any sub-directories therein).
+.PP
+If a
+\fRCmnd\fR
+has associated command line arguments, then the arguments
+in the
+\fRCmnd\fR
+must match exactly those given by the user on the command line
+(or match the wildcards if there are any).
+Note that the following characters must be escaped with a
+\(oq\e\(cq
+if they are used in command arguments:
+\(oq,\&\(cq,
+\(oq:\&\(cq,
+\(oq=\&\(cq,
+\(oq\e\(cq.
+The built-in command
+\(lq\fRsudoedit\fR\(rq
+is used to permit a user to run
+\fBsudo\fR
+with the
+\fB\-e\fR
+option (or as
+\fBsudoedit\fR).
+It may take command line arguments just as a normal command does.
+Note that
+\(lq\fRsudoedit\fR\(rq
+is a command built into
+\fBsudo\fR
+itself and must be specified in the
+\fIsudoers\fR
+file without a leading path.
+.PP
+If a
+\fRcommand name\fR
+is prefixed with a
+\fRDigest_Spec\fR,
+the command will only match successfully if it can be verified
+using the specified SHA-2 digest.
+The following digest formats are supported: sha224, sha256, sha384 and sha512.
+The string may be specified in either hex or base64 format
+(base64 is more compact).
+There are several utilities capable of generating SHA-2 digests in hex
+format such as openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum.
+.PP
+For example, using openssl:
+.nf
+.sp
+.RS 0n
+$ openssl dgst -sha224 /bin/ls
+SHA224(/bin/ls)= 118187da8364d490b4a7debbf483004e8f3e053ec954309de2c41a25
+.RE
+.fi
+.PP
+It is also possible to use openssl to generate base64 output:
+.nf
+.sp
+.RS 0n
+$ openssl dgst -binary -sha224 /bin/ls | openssl base64
+EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
+.RE
+.fi
+.PP
+Warning, if the user has write access to the command itself (directly or via a
+\fBsudo\fR
+command), it may be possible for the user to replace the command after the
+digest check has been performed but before the command is executed.
+A similar race condition exists on systems that lack the
+fexecve(2)
+system call when the directory in which the command is located
+is writable by the user.
+See the description of the
+\fIfdexec\fR
+setting for more information on how
+\fBsudo\fR
+executes commands that have an associated digest.
+.PP
+Command digests are only supported by version 1.8.7 or higher.
+.SS "Defaults"
+Certain configuration options may be changed from their default
+values at run-time via one or more
+\fRDefault_Entry\fR
+lines.
+These may affect all users on any host, all users on a specific host, a
+specific user, a specific command, or commands being run as a specific user.
+Note that per-command entries may not include command line arguments.
+If you need to specify arguments, define a
+\fRCmnd_Alias\fR
+and reference
+that instead.
+.nf
+.sp
+.RS 0n
+Default_Type ::= 'Defaults' |
+ 'Defaults' '@' Host_List |
+ 'Defaults' ':' User_List |
+ 'Defaults' '!' Cmnd_List |
+ 'Defaults' '>' Runas_List
+
+Default_Entry ::= Default_Type Parameter_List
+
+Parameter_List ::= Parameter |
+ Parameter ',' Parameter_List
+
+Parameter ::= Parameter '=' Value |
+ Parameter '+=' Value |
+ Parameter '-=' Value |
+ '!'* Parameter
+.RE
+.fi
+.PP
+Parameters may be
+\fBflags\fR,
+\fBinteger\fR
+values,
+\fBstrings\fR,
+or
+\fBlists\fR.
+Flags are implicitly boolean and can be turned off via the
+\(oq\&!\(cq
+operator.
+Some integer, string and list parameters may also be
+used in a boolean context to disable them.
+Values may be enclosed
+in double quotes
+(\&"")
+when they contain multiple words.
+Special characters may be escaped with a backslash
+(\(oq\e\(cq).
+.PP
+Lists have two additional assignment operators,
+\fR+=\fR
+and
+\fR-=\fR.
+These operators are used to add to and delete from a list respectively.
+It is not an error to use the
+\fR-=\fR
+operator to remove an element
+that does not exist in a list.
+.PP
+Defaults entries are parsed in the following order: generic, host,
+user and runas Defaults first, then command defaults.
+If there are multiple Defaults settings of the same type, the last
+matching setting is used.
+The following Defaults settings are parsed before all others since
+they may affect subsequent entries:
+\fIfqdn\fR,
+\fIgroup_plugin\fR,
+\fIrunas_default\fR,
+\fIsudoers_locale\fR.
+.PP
+See
+\fISUDOERS OPTIONS\fR
+for a list of supported Defaults parameters.
+.SS "User specification"
+.nf
+.RS 0n
+User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \e
+ (':' Host_List '=' Cmnd_Spec_List)*
+
+Cmnd_Spec_List ::= Cmnd_Spec |
+ Cmnd_Spec ',' Cmnd_Spec_List
+
+Cmnd_Spec ::= Runas_Spec? Option_Spec* Tag_Spec* Cmnd
+
+Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
+
+.ie \n(SL \{\
+.ie \n(PS Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Date_Spec | Timeout_Spec)
+.el Option_Spec ::= (SELinux_Spec | Date_Spec | Timeout_Spec)
+.\}
+.el \{\
+.ie \n(PS Option_Spec ::= (Solaris_Priv_Spec | Date_Spec | Timeout_Spec)
+.el Option_Spec ::= (Date_Spec | Timeout_Spec)
+.\}
+
+.if \n(SL \{\
+SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')
+
+.\}
+.if \n(PS \{\
+Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset')
+
+.\}
+Date_Spec ::= ('NOTBEFORE=timestamp' | 'NOTAFTER=timestamp')
+
+Timeout_Spec ::= 'TIMEOUT=timeout'
+
+Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
+ 'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
+ 'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' |
+ 'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')
+.RE
+.fi
+.PP
+A
+\fBuser specification\fR
+determines which commands a user may run
+(and as what user) on specified hosts.
+By default, commands are
+run as
+\fBroot\fR,
+but this can be changed on a per-command basis.
+.PP
+The basic structure of a user specification is
+\(lqwho where = (as_whom) what\(rq.
+Let's break that down into its constituent parts:
+.SS "Runas_Spec"
+A
+\fRRunas_Spec\fR
+determines the user and/or the group that a command
+may be run as.
+A fully-specified
+\fRRunas_Spec\fR
+consists of two
+\fRRunas_List\fRs
+(as defined above) separated by a colon
+(\(oq:\&\(cq)
+and enclosed in a set of parentheses.
+The first
+\fRRunas_List\fR
+indicates
+which users the command may be run as via
+\fBsudo\fR's
+\fB\-u\fR
+option.
+The second defines a list of groups that can be specified via
+\fBsudo\fR's
+\fB\-g\fR
+option in addition to any of the target user's groups.
+If both
+\fRRunas_List\fRs
+are specified, the command may be run with any combination of users
+and groups listed in their respective
+\fRRunas_List\fRs.
+If only the first is specified, the command may be run as any user
+in the list but no
+\fB\-g\fR
+option
+may be specified.
+If the first
+\fRRunas_List\fR
+is empty but the
+second is specified, the command may be run as the invoking user
+with the group set to any listed in the
+\fRRunas_List\fR.
+If both
+\fRRunas_List\fRs
+are empty, the command may only be run as the invoking user.
+If no
+\fRRunas_Spec\fR
+is specified the command may be run as
+\fBroot\fR
+and
+no group may be specified.
+.PP
+A
+\fRRunas_Spec\fR
+sets the default for the commands that follow it.
+What this means is that for the entry:
+.nf
+.sp
+.RS 0n
+dgb boulder = (operator) /bin/ls, /bin/kill, /usr/bin/lprm
+.RE
+.fi
+.PP
+The user
+\fBdgb\fR
+may run
+\fI/bin/ls\fR,
+\fI/bin/kill\fR,
+and
+\fI/usr/bin/lprm\fR
+on the host
+boulder\(embut
+only as
+\fBoperator\fR.
+E.g.,
+.nf
+.sp
+.RS 0n
+$ sudo -u operator /bin/ls
+.RE
+.fi
+.PP
+It is also possible to override a
+\fRRunas_Spec\fR
+later on in an entry.
+If we modify the entry like so:
+.nf
+.sp
+.RS 0n
+dgb boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm
+.RE
+.fi
+.PP
+Then user
+\fBdgb\fR
+is now allowed to run
+\fI/bin/ls\fR
+as
+\fBoperator\fR,
+but
+\fI/bin/kill\fR
+and
+\fI/usr/bin/lprm\fR
+as
+\fBroot\fR.
+.PP
+We can extend this to allow
+\fBdgb\fR
+to run
+\fR/bin/ls\fR
+with either
+the user or group set to
+\fBoperator\fR:
+.nf
+.sp
+.RS 0n
+dgb boulder = (operator : operator) /bin/ls, (root) /bin/kill,\e
+ /usr/bin/lprm
+.RE
+.fi
+.PP
+Note that while the group portion of the
+\fRRunas_Spec\fR
+permits the
+user to run as command with that group, it does not force the user
+to do so.
+If no group is specified on the command line, the command
+will run with the group listed in the target user's password database
+entry.
+The following would all be permitted by the sudoers entry above:
+.nf
+.sp
+.RS 0n
+$ sudo -u operator /bin/ls
+$ sudo -u operator -g operator /bin/ls
+$ sudo -g operator /bin/ls
+.RE
+.fi
+.PP
+In the following example, user
+\fBtcm\fR
+may run commands that access
+a modem device file with the dialer group.
+.nf
+.sp
+.RS 0n
+tcm boulder = (:dialer) /usr/bin/tip, /usr/bin/cu,\e
+ /usr/local/bin/minicom
+.RE
+.fi
+.PP
+Note that in this example only the group will be set, the command
+still runs as user
+\fBtcm\fR.
+E.g.\&
+.nf
+.sp
+.RS 0n
+$ sudo -g dialer /usr/bin/cu
+.RE
+.fi
+.PP
+Multiple users and groups may be present in a
+\fRRunas_Spec\fR,
+in which case the user may select any combination of users and groups via the
+\fB\-u\fR
+and
+\fB\-g\fR
+options.
+In this example:
+.nf
+.sp
+.RS 0n
+alan ALL = (root, bin : operator, system) ALL
+.RE
+.fi
+.PP
+user
+\fBalan\fR
+may run any command as either user root or bin,
+optionally setting the group to operator or system.
+.SS "Option_Spec"
+A
+\fRCmnd\fR
+may have zero or more options associated with it.
+Options may consist of
+.if \n(SL \{\
+SELinux roles and/or types,
+.\}
+.if \n(PS \{\
+Solaris privileges sets,
+.\}
+start and/or end dates and command timeouts.
+Once an option is set for a
+\fRCmnd\fR,
+subsequent
+\fRCmnd\fRs
+in the
+\fRCmnd_Spec_List\fR,
+inherit that option unless it is overridden by another option.
+.if \n(SL \{\
+.SS "SELinux_Spec"
+On systems with SELinux support,
+\fIsudoers\fR
+file entries may optionally have an SELinux role and/or type associated
+with a command.
+If a role or
+type is specified with the command it will override any default values
+specified in
+\fIsudoers\fR.
+A role or type specified on the command line,
+however, will supersede the values in
+\fIsudoers\fR.
+.\}
+.if \n(PS \{\
+.SS "Solaris_Priv_Spec"
+On Solaris systems,
+\fIsudoers\fR
+file entries may optionally specify Solaris privilege set and/or limit
+privilege set associated with a command.
+If privileges or limit privileges are specified with the command
+it will override any default values specified in
+\fIsudoers\fR.
+.PP
+A privilege set is a comma-separated list of privilege names.
+The
+ppriv(1)
+command can be used to list all privileges known to the system.
+For example:
+.nf
+.sp
+.RS 0n
+$ ppriv -l
+.RE
+.fi
+.PP
+In addition, there are several
+\(lqspecial\(rq
+privilege strings:
+.TP 10n
+none
+the empty set
+.TP 10n
+all
+the set of all privileges
+.TP 10n
+zone
+the set of all privileges available in the current zone
+.TP 10n
+basic
+the default set of privileges normal users are granted at login time
+.PP
+Privileges can be excluded from a set by prefixing the privilege
+name with either an
+\(oq\&!\(cq
+or
+\(oq\-\(cq
+character.
+.\}
+.SS "Date_Spec"
+\fBsudoers\fR
+rules can be specified with a start and end date via the
+\fRNOTBEFORE\fR
+and
+\fRNOTAFTER\fR
+settings.
+The time stamp must be specified in
+\fIGeneralized Time\fR
+as defined by RFC 4517.
+The format is effectively
+\fRyyyymmddHHMMSSZ\fR
+where the minutes and seconds are optional.
+The
+\(oqZ\(cq
+suffix indicates that the time stamp is in Coordinated Universal Time (UTC).
+It is also possible to specify a timezone offset from UTC in hours
+and minutes instead of a
+\(oqZ\(cq.
+For example,
+\(oq-0500\(cq
+would correspond to Eastern Standard time in the US.
+As an extension, if no
+\(oqZ\(cq
+or timezone offset is specified, local time will be used.
+.PP
+The following are all valid time stamps:
+.nf
+.sp
+.RS 4n
+20170214083000Z
+2017021408Z
+20160315220000-0500
+20151201235900
+.RE
+.fi
+.SS "Timeout_Spec"
+A command may have a timeout associated with it.
+If the timeout expires before the command has exited, the
+command will be terminated.
+The timeout may be specified in combinations of days, hours,
+minutes and seconds with a single-letter case-insensitive suffix
+that indicates the unit of time.
+For example, a timeout of 7 days, 8 hours, 30 minutes and
+10 seconds would be written as
+\fR7d8h30m10s\fR.
+If a number is specified without a unit, seconds are assumed.
+Any of the days, minutes, hours or seconds may be omitted.
+The order must be from largest to smallest unit and a unit
+may not be specified more than once.
+.PP
+The following are all
+\fIvalid\fR
+timeout values:
+\fR7d8h30m10s\fR,
+\fR14d\fR,
+\fR8h30m\fR,
+\fR600s\fR,
+\fR3600\fR.
+The following are
+\fIinvalid\fR
+timeout values:
+\fR12m2w1d\fR,
+\fR30s10m4h\fR,
+\fR1d2d3h\fR.
+.PP
+This option is only supported by version 1.8.20 or higher.
+.SS "Tag_Spec"
+A command may have zero or more tags associated with it.
+The following tag values are supported:
+\fREXEC\fR,
+\fRNOEXEC\fR,
+\fRFOLLOW\fR,
+\fRNOFOLLOW\fR,
+\fRLOG_INPUT\fR,
+\fRNOLOG_INPUT\fR,
+\fRLOG_OUTPUT\fR,
+\fRNOLOG_OUTPUT\fR,
+\fRMAIL\fR,
+\fRNOMAIL\fR,
+\fRPASSWD\fR,
+\fRNOPASSWD\fR,
+\fRSETENV\fR,
+and
+\fRNOSETENV\fR.
+Once a tag is set on a
+\fRCmnd\fR,
+subsequent
+\fRCmnd\fRs
+in the
+\fRCmnd_Spec_List\fR,
+inherit the tag unless it is overridden by the opposite tag (in other words,
+\fRPASSWD\fR
+overrides
+\fRNOPASSWD\fR
+and
+\fRNOEXEC\fR
+overrides
+\fREXEC\fR).
+.TP 2n
+\fIEXEC\fR and \fINOEXEC\fR
+.sp
+If
+\fBsudo\fR
+has been compiled with
+\fInoexec\fR
+support and the underlying operating system supports it, the
+\fRNOEXEC\fR
+tag can be used to prevent a dynamically-linked executable from
+running further commands itself.
+.sp
+In the following example, user
+\fBaaron\fR
+may run
+\fI/usr/bin/more\fR
+and
+\fI/usr/bin/vi\fR
+but shell escapes will be disabled.
+.nf
+.sp
+.RS 2n
+aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi
+.RE
+.fi
+.RS 2n
+.sp
+See the
+\fIPreventing shell escapes\fR
+section below for more details on how
+\fRNOEXEC\fR
+works and whether or not it will work on your system.
+.RE
+.TP 2n
+\fIFOLLOW\fR and \fINOFOLLOW\fR
+Starting with version 1.8.15,
+\fBsudoedit\fR
+will not open a file that is a symbolic link unless the
+\fIsudoedit_follow\fR
+option is enabled.
+The
+\fIFOLLOW\fR
+and
+\fINOFOLLOW\fR
+tags override the value of
+\fIsudoedit_follow\fR
+and can be used to permit (or deny) the editing of symbolic links
+on a per-command basis.
+These tags are only effective for the
+\fIsudoedit\fR
+command and are ignored for all other commands.
+.TP 2n
+\fILOG_INPUT\fR and \fINOLOG_INPUT\fR
+.sp
+These tags override the value of the
+\fIlog_input\fR
+option on a per-command basis.
+For more information, see the description of
+\fIlog_input\fR
+in the
+\fISUDOERS OPTIONS\fR
+section below.
+.TP 2n
+\fILOG_OUTPUT\fR and \fINOLOG_OUTPUT\fR
+.sp
+These tags override the value of the
+\fIlog_output\fR
+option on a per-command basis.
+For more information, see the description of
+\fIlog_output\fR
+in the
+\fISUDOERS OPTIONS\fR
+section below.
+.TP 2n
+\fIMAIL\fR and \fINOMAIL\fR
+.sp
+These tags provide fine-grained control over whether
+mail will be sent when a user runs a command by
+overriding the value of the
+\fImail_all_cmnds\fR
+option on a per-command basis.
+They have no effect when
+\fBsudo\fR
+is run with the
+\fB\-l\fR
+or
+\fB\-v\fR
+options.
+A
+\fINOMAIL\fR
+tag will also override the
+\fImail_always\fR
+and
+\fImail_no_perms\fR
+options.
+For more information, see the descriptions of
+\fImail_all_cmnds\fR,
+\fImail_always\fR,
+and
+\fImail_no_perms\fR
+in the
+\fISUDOERS OPTIONS\fR
+section below.
+.TP 2n
+\fIPASSWD\fR and \fINOPASSWD\fR
+.sp
+By default,
+\fBsudo\fR
+requires that a user authenticate him or herself
+before running a command.
+This behavior can be modified via the
+\fRNOPASSWD\fR
+tag.
+Like a
+\fRRunas_Spec\fR,
+the
+\fRNOPASSWD\fR
+tag sets
+a default for the commands that follow it in the
+\fRCmnd_Spec_List\fR.
+Conversely, the
+\fRPASSWD\fR
+tag can be used to reverse things.
+For example:
+.nf
+.sp
+.RS 2n
+ray rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm
+.RE
+.fi
+.RS 2n
+.sp
+would allow the user
+\fBray\fR
+to run
+\fI/bin/kill\fR,
+\fI/bin/ls\fR,
+and
+\fI/usr/bin/lprm\fR
+as
+\fBroot\fR
+on the machine rushmore without authenticating himself.
+If we only want
+\fBray\fR
+to be able to
+run
+\fI/bin/kill\fR
+without a password the entry would be:
+.nf
+.sp
+.RS 2n
+ray rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm
+.RE
+.fi
+.sp
+Note, however, that the
+\fRPASSWD\fR
+tag has no effect on users who are in the group specified by the
+\fIexempt_group\fR
+option.
+.sp
+By default, if the
+\fRNOPASSWD\fR
+tag is applied to any of the entries for a user on the current host,
+he or she will be able to run
+\(lq\fRsudo -l\fR\(rq
+without a password.
+Additionally, a user may only run
+\(lq\fRsudo -v\fR\(rq
+without a password if the
+\fRNOPASSWD\fR
+tag is present for all a user's entries that pertain to the current host.
+This behavior may be overridden via the
+\fIverifypw\fR
+and
+\fIlistpw\fR
+options.
+.RE
+.TP 2n
+\fISETENV\fR and \fINOSETENV\fR
+.sp
+These tags override the value of the
+\fIsetenv\fR
+option on a per-command basis.
+Note that if
+\fRSETENV\fR
+has been set for a command, the user may disable the
+\fIenv_reset\fR
+option from the command line via the
+\fB\-E\fR
+option.
+Additionally, environment variables set on the command
+line are not subject to the restrictions imposed by
+\fIenv_check\fR,
+\fIenv_delete\fR,
+or
+\fIenv_keep\fR.
+As such, only trusted users should be allowed to set variables in this manner.
+If the command matched is
+\fBALL\fR,
+the
+\fRSETENV\fR
+tag is implied for that command; this default may be overridden by use of the
+\fRNOSETENV\fR
+tag.
+.SS "Wildcards"
+\fBsudo\fR
+allows shell-style
+\fIwildcards\fR
+(aka meta or glob characters)
+to be used in host names, path names and command line arguments in the
+\fIsudoers\fR
+file.
+Wildcard matching is done via the
+glob(3)
+and
+fnmatch(3)
+functions as specified by
+IEEE Std 1003.1 (\(lqPOSIX.1\(rq).
+.TP 10n
+\fR*\fR
+Matches any set of zero or more characters (including white space).
+.TP 10n
+\fR\&?\fR
+Matches any single character (including white space).
+.TP 10n
+\fR[...]\fR
+Matches any character in the specified range.
+.TP 10n
+\fR[!...]\fR
+Matches any character
+\fInot\fR
+in the specified range.
+.TP 10n
+\fR\ex\fR
+For any character
+\(oqx\(cq,
+evaluates to
+\(oqx\(cq.
+This is used to escape special characters such as:
+\(oq*\(cq,
+\(oq\&?\(cq,
+\(oq[\&\(cq,
+and
+\(oq]\&\(cq.
+.PP
+\fBNote that these are not regular expressions.\fR
+Unlike a regular expression there is no way to match one or more
+characters within a range.
+.PP
+Character classes may be used if your system's
+glob(3)
+and
+fnmatch(3)
+functions support them.
+However, because the
+\(oq:\&\(cq
+character has special meaning in
+\fIsudoers\fR,
+it must be
+escaped.
+For example:
+.nf
+.sp
+.RS 4n
+/bin/ls [[\e:\&alpha\e:\&]]*
+.RE
+.fi
+.PP
+Would match any file name beginning with a letter.
+.PP
+Note that a forward slash
+(\(oq/\(cq)
+will
+\fInot\fR
+be matched by
+wildcards used in the file name portion of the command.
+This is to make a path like:
+.nf
+.sp
+.RS 4n
+/usr/bin/*
+.RE
+.fi
+.PP
+match
+\fI/usr/bin/who\fR
+but not
+\fI/usr/bin/X11/xterm\fR.
+.PP
+When matching the command line arguments, however, a slash
+\fIdoes\fR
+get matched by wildcards since command line arguments may contain
+arbitrary strings and not just path names.
+.PP
+\fBWildcards in command line arguments should be used with care.\fR
+.br
+Command line arguments are matched as a single, concatenated string.
+This mean a wildcard character such as
+\(oq\&?\(cq
+or
+\(oq*\(cq
+will match across word boundaries, which may be unexpected.
+For example, while a sudoers entry like:
+.nf
+.sp
+.RS 4n
+%operator ALL = /bin/cat /var/log/messages*
+.RE
+.fi
+.PP
+will allow command like:
+.nf
+.sp
+.RS 4n
+$ sudo cat /var/log/messages.1
+.RE
+.fi
+.PP
+It will also allow:
+.nf
+.sp
+.RS 4n
+$ sudo cat /var/log/messages /etc/shadow
+.RE
+.fi
+.PP
+which is probably not what was intended.
+In most cases it is better to do command line processing
+outside of the
+\fIsudoers\fR
+file in a scripting language.
+.SS "Exceptions to wildcard rules"
+The following exceptions apply to the above rules:
+.TP 10n
+\fR\&""\fR
+If the empty string
+\fR\&""\fR
+is the only command line argument in the
+\fIsudoers\fR
+file entry it means that command is not allowed to be run with
+\fIany\fR
+arguments.
+.TP 10n
+sudoedit
+Command line arguments to the
+\fIsudoedit\fR
+built-in command should always be path names, so a forward slash
+(\(oq/\(cq)
+will not be matched by a wildcard.
+.SS "Including other files from within sudoers"
+It is possible to include other
+\fIsudoers\fR
+files from within the
+\fIsudoers\fR
+file currently being parsed using the
+\fR#include\fR
+and
+\fR#includedir\fR
+directives.
+.PP
+This can be used, for example, to keep a site-wide
+\fIsudoers\fR
+file in addition to a local, per-machine file.
+For the sake of this example the site-wide
+\fIsudoers\fR
+file will be
+\fI/etc/sudoers\fR
+and the per-machine one will be
+\fI/etc/sudoers.local\fR.
+To include
+\fI/etc/sudoers.local\fR
+from within
+\fI/etc/sudoers\fR
+we would use the
+following line in
+\fI/etc/sudoers\fR:
+.nf
+.sp
+.RS 4n
+#include /etc/sudoers.local
+.RE
+.fi
+.PP
+When
+\fBsudo\fR
+reaches this line it will suspend processing of the current file
+(\fI/etc/sudoers\fR)
+and switch to
+\fI/etc/sudoers.local\fR.
+Upon reaching the end of
+\fI/etc/sudoers.local\fR,
+the rest of
+\fI/etc/sudoers\fR
+will be processed.
+Files that are included may themselves include other files.
+A hard limit of 128 nested include files is enforced to prevent include
+file loops.
+.PP
+If the path to the include file is not fully-qualified (does not
+begin with a
+\(oq/\(cq),
+it must be located in the same directory as the sudoers file it was
+included from.
+For example, if
+\fI/etc/sudoers\fR
+contains the line:
+.nf
+.sp
+.RS 4n
+\fR#include sudoers.local\fR
+.RE
+.fi
+.PP
+the file that will be included is
+\fI/etc/sudoers.local\fR.
+.PP
+The file name may also include the
+\fR%h\fR
+escape, signifying the short form of the host name.
+In other words, if the machine's host name is
+\(lqxerxes\(rq,
+then
+.nf
+.sp
+.RS 4n
+#include /etc/sudoers.%h
+.RE
+.fi
+.PP
+will cause
+\fBsudo\fR
+to include the file
+\fI/etc/sudoers.xerxes\fR.
+.PP
+The
+\fR#includedir\fR
+directive can be used to create a
+\fIsudoers.d\fR
+directory that the system package manager can drop
+\fIsudoers\fR
+file rules into as part of package installation.
+For example, given:
+.nf
+.sp
+.RS 4n
+#includedir /etc/sudoers.d
+.RE
+.fi
+.PP
+\fBsudo\fR
+will suspend processing of the current file and read each file in
+\fI/etc/sudoers.d\fR,
+skipping file names that end in
+\(oq~\(cq
+or contain a
+\(oq.\&\(cq
+character to avoid causing problems with package manager or editor
+temporary/backup files.
+Files are parsed in sorted lexical order.
+That is,
+\fI/etc/sudoers.d/01_first\fR
+will be parsed before
+\fI/etc/sudoers.d/10_second\fR.
+Be aware that because the sorting is lexical, not numeric,
+\fI/etc/sudoers.d/1_whoops\fR
+would be loaded
+\fIafter\fR
+\fI/etc/sudoers.d/10_second\fR.
+Using a consistent number of leading zeroes in the file names can be used
+to avoid such problems.
+After parsing the files in the directory, control returns to the
+file that contained the
+\fR#includedir\fR
+directive.
+.PP
+Note that unlike files included via
+\fR#include\fR,
+\fBvisudo\fR
+will not edit the files in a
+\fR#includedir\fR
+directory unless one of them contains a syntax error.
+It is still possible to run
+\fBvisudo\fR
+with the
+\fB\-f\fR
+flag to edit the files directly, but this will not catch the
+redefinition of an
+\fIalias\fR
+that is also present in a different file.
+.SS "Other special characters and reserved words"
+The pound sign
+(\(oq#\(cq)
+is used to indicate a comment (unless it is part of a #include
+directive or unless it occurs in the context of a user name and is
+followed by one or more digits, in which case it is treated as a
+uid).
+Both the comment character and any text after it, up to the end of
+the line, are ignored.
+.PP
+The reserved word
+\fBALL\fR
+is a built-in
+\fIalias\fR
+that always causes a match to succeed.
+It can be used wherever one might otherwise use a
+\fRCmnd_Alias\fR,
+\fRUser_Alias\fR,
+\fRRunas_Alias\fR,
+or
+\fRHost_Alias\fR.
+You should not try to define your own
+\fIalias\fR
+called
+\fBALL\fR
+as the built-in alias will be used in preference to your own.
+Please note that using
+\fBALL\fR
+can be dangerous since in a command context, it allows the user to run
+\fIany\fR
+command on the system.
+.PP
+An exclamation point
+(\(oq\&!\(cq)
+can be used as a logical
+\fInot\fR
+operator in a list or
+\fIalias\fR
+as well as in front of a
+\fRCmnd\fR.
+This allows one to exclude certain values.
+For the
+\(oq\&!\(cq
+operator to be effective, there must be something for it to exclude.
+For example, to match all users except for root one would use:
+.nf
+.sp
+.RS 4n
+ALL,!root
+.RE
+.fi
+.PP
+If the
+\fBALL\fR,
+is omitted, as in:
+.nf
+.sp
+.RS 4n
+!root
+.RE
+.fi
+.PP
+it would explicitly deny root but not match any other users.
+This is different from a true
+\(lqnegation\(rq
+operator.
+.PP
+Note, however, that using a
+\(oq\&!\(cq
+in conjunction with the built-in
+\fBALL\fR
+alias to allow a user to run
+\(lqall but a few\(rq
+commands rarely works as intended (see
+\fISECURITY NOTES\fR
+below).
+.PP
+Long lines can be continued with a backslash
+(\(oq\e\(cq)
+as the last character on the line.
+.PP
+White space between elements in a list as well as special syntactic
+characters in a
+\fIUser Specification\fR
+(\(oq=\&\(cq,
+\(oq:\&\(cq,
+\(oq(\&\(cq,
+\(oq)\&\(cq)
+is optional.
+.PP
+The following characters must be escaped with a backslash
+(\(oq\e\(cq)
+when used as part of a word (e.g., a user name or host name):
+\(oq\&!\(cq,
+\(oq=\&\(cq,
+\(oq:\&\(cq,
+\(oq,\&\(cq,
+\(oq(\&\(cq,
+\(oq)\&\(cq,
+\(oq\e\(cq.
+.SH "SUDOERS OPTIONS"
+\fBsudo\fR's
+behavior can be modified by
+\fRDefault_Entry\fR
+lines, as explained earlier.
+A list of all supported Defaults parameters, grouped by type, are listed below.
+.PP
+\fBBoolean Flags\fR:
+.TP 18n
+always_query_group_plugin
+If a
+\fIgroup_plugin\fR
+is configured, use it to resolve groups of the form %group as long
+as there is not also a system group of the same name.
+Normally, only groups of the form %:group are passed to the
+\fIgroup_plugin\fR.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+always_set_home
+If enabled,
+\fBsudo\fR
+will set the
+\fRHOME\fR
+environment variable to the home directory of the target user
+(which is root unless the
+\fB\-u\fR
+option is used).
+This effectively means that the
+\fB\-H\fR
+option is always implied.
+Note that by default,
+\fRHOME\fR
+will be set to the home directory of the target user when the
+\fIenv_reset\fR
+option is enabled, so
+\fIalways_set_home\fR
+only has an effect for configurations where either
+\fIenv_reset\fR
+is disabled or
+\fRHOME\fR
+is present in the
+\fIenv_keep\fR
+list.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+authenticate
+If set, users must authenticate themselves via a password (or other
+means of authentication) before they may run commands.
+This default may be overridden via the
+\fRPASSWD\fR
+and
+\fRNOPASSWD\fR
+tags.
+This flag is
+\fIon\fR
+by default.
+.TP 18n
+case_insensitive_group
+If enabled, group names in
+\fIsudoers\fR
+will be matched in a case insensitive manner.
+This may be necessary when users are stored in LDAP or AD.
+This flag is
+\fIon\fR
+by default.
+.TP 18n
+case_insensitive_user
+If enabled, user names in
+\fIsudoers\fR
+will be matched in a case insensitive manner.
+This may be necessary when groups are stored in LDAP or AD.
+This flag is
+\fIon\fR
+by default.
+.TP 18n
+closefrom_override
+If set, the user may use
+\fBsudo\fR's
+\fB\-C\fR
+option which overrides the default starting point at which
+\fBsudo\fR
+begins closing open file descriptors.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+compress_io
+If set, and
+\fBsudo\fR
+is configured to log a command's input or output,
+the I/O logs will be compressed using
+\fBzlib\fR.
+This flag is
+\fIon\fR
+by default when
+\fBsudo\fR
+is compiled with
+\fBzlib\fR
+support.
+.TP 18n
+exec_background
+By default,
+\fBsudo\fR
+runs a command as the foreground process as long as
+\fBsudo\fR
+itself is running in the foreground.
+When the
+\fIexec_background\fR
+flag is enabled and the command is being run in a pty (due to I/O logging
+or the
+\fIuse_pty\fR
+flag), the command will be run as a background process.
+Attempts to read from the controlling terminal (or to change terminal
+settings) will result in the command being suspended with the
+\fRSIGTTIN\fR
+signal (or
+\fRSIGTTOU\fR
+in the case of terminal settings).
+If this happens when
+\fBsudo\fR
+is a foreground process, the command will be granted the controlling terminal
+and resumed in the foreground with no user intervention required.
+The advantage of initially running the command in the background is that
+\fBsudo\fR
+need not read from the terminal unless the command explicitly requests it.
+Otherwise, any terminal input must be passed to the command, whether it
+has required it or not (the kernel buffers terminals so it is not possible
+to tell whether the command really wants the input).
+This is different from historic
+\fIsudo\fR
+behavior or when the command is not being run in a pty.
+.sp
+For this to work seamlessly, the operating system must support the
+automatic restarting of system calls.
+Unfortunately, not all operating systems do this by default,
+and even those that do may have bugs.
+For example, macOS fails to restart the
+\fBtcgetattr\fR()
+and
+\fBtcsetattr\fR()
+system calls (this is a bug in macOS).
+Furthermore, because this behavior depends on the command stopping with the
+\fRSIGTTIN\fR
+or
+\fRSIGTTOU\fR
+signals, programs that catch these signals and suspend themselves
+with a different signal (usually
+\fRSIGTOP\fR)
+will not be automatically foregrounded.
+Some versions of the linux
+su(1)
+command behave this way.
+This flag is
+\fIoff\fR
+by default.
+.sp
+This setting is only supported by version 1.8.7 or higher.
+It has no effect unless I/O logging is enabled or the
+\fIuse_pty\fR
+flag is enabled.
+.TP 18n
+env_editor
+If set,
+\fBvisudo\fR
+will use the value of the
+\fRSUDO_EDITOR\fR,
+\fRVISUAL\fR
+or
+\fREDITOR\fR
+environment variables before falling back on the default editor list.
+Note that this may create a security hole as it allows the user to
+run any arbitrary command as root without logging.
+A safer alternative is to place a colon-separated list of editors
+in the
+\fIeditor\fR
+variable.
+\fBvisudo\fR
+will then only use
+\fRSUDO_EDITOR\fR,
+\fRVISUAL\fR
+or
+\fREDITOR\fR
+if they match a value specified in
+\fIeditor\fR.
+If the
+\fIenv_reset\fR
+flag is enabled, the
+\fRSUDO_EDITOR\fR,
+\fRVISUAL\fR
+and/or
+\fREDITOR\fR
+environment variables must be present in the
+\fIenv_keep\fR
+list for the
+\fIenv_editor\fR
+flag to function when
+\fBvisudo\fR
+is invoked via
+\fBsudo\fR.
+This flag is
+\fI@env_editor@\fR
+by default.
+.TP 18n
+env_reset
+If set,
+\fBsudo\fR
+will run the command in a minimal environment containing the
+\fRTERM\fR,
+\fRPATH\fR,
+\fRHOME\fR,
+\fRMAIL\fR,
+\fRSHELL\fR,
+\fRLOGNAME\fR,
+\fRUSER\fR
+and
+\fRSUDO_*\fR
+variables.
+Any variables in the caller's environment or in the file specified
+by the
+\fIrestricted_env_file\fR
+option that match the
+\fRenv_keep\fR
+and
+\fRenv_check\fR
+lists are then added, followed by any variables present in the file
+specified by the
+\fIenv_file\fR
+option (if any).
+The contents of the
+\fRenv_keep\fR
+and
+\fRenv_check\fR
+lists, as modified by global Defaults parameters in
+\fIsudoers\fR,
+are displayed when
+\fBsudo\fR
+is run by root with the
+\fB\-V\fR
+option.
+If the
+\fIsecure_path\fR
+option is set, its value will be used for the
+\fRPATH\fR
+environment variable.
+This flag is
+\fI@env_reset@\fR
+by default.
+.TP 18n
+fast_glob
+Normally,
+\fBsudo\fR
+uses the
+glob(3)
+function to do shell-style globbing when matching path names.
+However, since it accesses the file system,
+glob(3)
+can take a long time to complete for some patterns, especially
+when the pattern references a network file system that is mounted
+on demand (auto mounted).
+The
+\fIfast_glob\fR
+option causes
+\fBsudo\fR
+to use the
+fnmatch(3)
+function, which does not access the file system to do its matching.
+The disadvantage of
+\fIfast_glob\fR
+is that it is unable to match relative path names such as
+\fI./ls\fR
+or
+\fI../bin/ls\fR.
+This has security implications when path names that include globbing
+characters are used with the negation operator,
+\(oq!\&\(cq,
+as such rules can be trivially bypassed.
+As such, this option should not be used when the
+\fIsudoers\fR
+file contains rules that contain negated path names which include globbing
+characters.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+fqdn
+Set this flag if you want to put fully qualified host names in the
+\fIsudoers\fR
+file when the local host name (as returned by the
+\fRhostname\fR
+command) does not contain the domain name.
+In other words, instead of myhost you would use myhost.mydomain.edu.
+You may still use the short form if you wish (and even mix the two).
+This option is only effective when the
+\(lqcanonical\(rq
+host name, as returned by the
+\fBgetaddrinfo\fR()
+or
+\fBgethostbyname\fR()
+function, is a fully-qualified domain name.
+This is usually the case when the system is configured to use DNS
+for host name resolution.
+.sp
+If the system is configured to use the
+\fI/etc/hosts\fR
+file in preference to DNS, the
+\(lqcanonical\(rq
+host name may not be fully-qualified.
+The order that sources are queried for host name resolution
+is usually specified in the
+\fI@nsswitch_conf@\fR,
+\fI@netsvc_conf@\fR,
+\fI/etc/host.conf\fR,
+or, in some cases,
+\fI/etc/resolv.conf\fR
+file.
+In the
+\fI/etc/hosts\fR
+file, the first host name of the entry is considered to be the
+\(lqcanonical\(rq
+name; subsequent names are aliases that are not used by
+\fBsudoers\fR.
+For example, the following hosts file line for the machine
+\(lqxyzzy\(rq
+has the fully-qualified domain name as the
+\(lqcanonical\(rq
+host name, and the short version as an alias.
+.sp
+.RS 24n
+192.168.1.1 xyzzy.sudo.ws xyzzy
+.RE
+.RS 18n
+.sp
+If the machine's hosts file entry is not formatted properly, the
+\fIfqdn\fR
+option will not be effective if it is queried before DNS.
+.sp
+Beware that when using DNS for host name resolution, turning on
+\fIfqdn\fR
+requires
+\fBsudoers\fR
+to make DNS lookups which renders
+\fBsudo\fR
+unusable if DNS stops working (for example if the machine is disconnected
+from the network).
+Also note that just like with the hosts file, you must use the
+\(lqcanonical\(rq
+name as DNS knows it.
+That is, you may not use a host alias
+(\fRCNAME\fR
+entry)
+due to performance issues and the fact that there is no way to get all
+aliases from DNS.
+.sp
+This flag is
+\fI@fqdn@\fR
+by default.
+.RE
+.TP 18n
+ignore_audit_errors
+Allow commands to be run even if
+\fBsudoers\fR
+cannot write to the audit log.
+If enabled, an audit log write failure is not treated as a fatal error.
+If disabled, a command may only be run after the audit event is successfully
+written.
+This flag is only effective on systems for which
+\fBsudoers\fR
+supports audit logging, including
+FreeBSD,
+Linux, macOS and Solaris.
+This flag is
+\fIon\fR
+by default.
+.TP 18n
+ignore_dot
+If set,
+\fBsudo\fR
+will ignore "." or "" (both denoting current directory) in the
+\fRPATH\fR
+environment variable; the
+\fRPATH\fR
+itself is not modified.
+This flag is
+\fI@ignore_dot@\fR
+by default.
+.TP 18n
+ignore_iolog_errors
+Allow commands to be run even if
+\fBsudoers\fR
+cannot write to the I/O log.
+If enabled, an I/O log write failure is not treated as a fatal error.
+If disabled, the command will be terminated if the I/O log cannot be written to.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+ignore_logfile_errors
+Allow commands to be run even if
+\fBsudoers\fR
+cannot write to the log file.
+If enabled, a log file write failure is not treated as a fatal error.
+If disabled, a command may only be run after the log file entry is successfully
+written.
+This flag only has an effect when
+\fBsudoers\fR
+is configured to use file-based logging via the
+\fIlogfile\fR
+option.
+This flag is
+\fIon\fR
+by default.
+.TP 18n
+ignore_local_sudoers
+If set via LDAP, parsing of
+\fI@sysconfdir@/sudoers\fR
+will be skipped.
+This is intended for Enterprises that wish to prevent the usage of local
+sudoers files so that only LDAP is used.
+This thwarts the efforts of rogue operators who would attempt to add roles to
+\fI@sysconfdir@/sudoers\fR.
+When this option is present,
+\fI@sysconfdir@/sudoers\fR
+does not even need to exist.
+Since this option tells
+\fBsudo\fR
+how to behave when no specific LDAP entries have been matched, this
+sudoOption is only meaningful for the
+\fRcn=defaults\fR
+section.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+ignore_unknown_defaults
+If set,
+\fBsudo\fR
+will not produce a warning if it encounters an unknown Defaults entry
+in the
+\fIsudoers\fR
+file or an unknown sudoOption in LDAP.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+insults
+If set,
+\fBsudo\fR
+will insult users when they enter an incorrect password.
+This flag is
+\fI@insults@\fR
+by default.
+.TP 18n
+log_host
+If set, the host name will be logged in the (non-syslog)
+\fBsudo\fR
+log file.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+log_input
+If set,
+\fBsudo\fR
+will run the command in a pseudo-tty and log all user input.
+If the standard input is not connected to the user's tty, due to
+I/O redirection or because the command is part of a pipeline, that
+input is also captured and stored in a separate log file.
+Anything sent to the standard input will be consumed, regardless of
+whether or not the command run via
+\fBsudo\fR
+is actually reading the standard input.
+This may have unexpected results when using
+\fBsudo\fR
+in a shell script that expects to process the standard input.
+For more information about I/O logging, see the
+\fII/O LOG FILES\fR
+section.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+log_output
+If set,
+\fBsudo\fR
+will run the command in a pseudo-tty and log all output that is sent
+to the screen, similar to the
+script(1)
+command.
+For more information about I/O logging, see the
+\fII/O LOG FILES\fR
+section.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+log_year
+If set, the four-digit year will be logged in the (non-syslog)
+\fBsudo\fR
+log file.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+long_otp_prompt
+When validating with a One Time Password (OTP) scheme such as
+\fBS/Key\fR
+or
+\fBOPIE\fR,
+a two-line prompt is used to make it easier
+to cut and paste the challenge to a local window.
+It's not as pretty as the default but some people find it more convenient.
+This flag is
+\fI@long_otp_prompt@\fR
+by default.
+.TP 18n
+mail_all_cmnds
+Send mail to the
+\fImailto\fR
+user every time a user attempts to run a command via
+\fBsudo\fR
+(this includes
+\fBsudoedit\fR).
+No mail will be sent if the user runs
+\fBsudo\fR
+with the
+\fB\-l\fR
+or
+\fB\-v\fR
+option unless there is an authentication error and the
+\fImail_badpass\fR
+flag is also set.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+mail_always
+Send mail to the
+\fImailto\fR
+user every time a user runs
+\fBsudo\fR.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+mail_badpass
+Send mail to the
+\fImailto\fR
+user if the user running
+\fBsudo\fR
+does not enter the correct password.
+If the command the user is attempting to run is not permitted by
+\fBsudoers\fR
+and one of the
+\fImail_all_cmnds\fR,
+\fImail_always\fR,
+\fImail_no_host\fR,
+\fImail_no_perms\fR
+or
+\fImail_no_user\fR
+flags are set, this flag will have no effect.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+mail_no_host
+If set, mail will be sent to the
+\fImailto\fR
+user if the invoking user exists in the
+\fIsudoers\fR
+file, but is not allowed to run commands on the current host.
+This flag is
+\fI@mail_no_host@\fR
+by default.
+.TP 18n
+mail_no_perms
+If set, mail will be sent to the
+\fImailto\fR
+user if the invoking user is allowed to use
+\fBsudo\fR
+but the command they are trying is not listed in their
+\fIsudoers\fR
+file entry or is explicitly denied.
+This flag is
+\fI@mail_no_perms@\fR
+by default.
+.TP 18n
+mail_no_user
+If set, mail will be sent to the
+\fImailto\fR
+user if the invoking user is not in the
+\fIsudoers\fR
+file.
+This flag is
+\fI@mail_no_user@\fR
+by default.
+.TP 18n
+match_group_by_gid
+By default,
+\fBsudoers\fR
+will look up each group the user is a member of by group ID to
+determine the group name (this is only done once).
+The resulting list of the user's group names is used when matching
+groups listed in the
+\fIsudoers\fR
+file.
+This works well on systems where the number of groups listed in the
+\fIsudoers\fR
+file is larger than the number of groups a typical user belongs to.
+On systems where group lookups are slow, where users may belong
+to a large number of groups, and where the number of groups listed
+in the
+\fIsudoers\fR
+file is relatively small, it may be prohibitively expensive and
+running commands via
+\fBsudo\fR
+may take longer than normal.
+On such systems it may be faster to use the
+\fImatch_group_by_gid\fR
+flag to avoid resolving the user's group IDs to group names.
+In this case,
+\fBsudoers\fR
+must look up any group name listed in the
+\fIsudoers\fR
+file and use the group ID instead of the group name when determining
+whether the user is a member of the group.
+.sp
+Note that if
+\fImatch_group_by_gid\fR
+is enabled, group database lookups performed by
+\fBsudoers\fR
+will be keyed by group name as opposed to group ID.
+On systems where there are multiple sources for the group database,
+it is possible to have conflicting group names or group IDs in the local
+\fI/etc/group\fR
+file and the remote group database.
+On such systems, enabling or disabling
+\fImatch_group_by_gid\fR
+can be used to choose whether group database queries are performed
+by name (enabled) or ID (disabled), which may aid in working around
+group entry conflicts.
+.sp
+The
+\fImatch_group_by_gid\fR
+flag has no effect when
+\fIsudoers\fR
+data is stored in LDAP.
+This flag is
+\fIoff\fR
+by default.
+.sp
+This setting is only supported by version 1.8.18 or higher.
+.TP 18n
+netgroup_tuple
+If set, netgroup lookups will be performed using the full netgroup
+tuple: host name, user name and domain (if one is set).
+Historically,
+\fBsudo\fR
+only matched the user name and domain for netgroups used in a
+\fRUser_List\fR
+and only matched the host name and domain for netgroups used in a
+\fRHost_List\fR.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+noexec
+If set, all commands run via
+\fBsudo\fR
+will behave as if the
+\fRNOEXEC\fR
+tag has been set, unless overridden by an
+\fREXEC\fR
+tag.
+See the description of
+\fIEXEC and NOEXEC\fR
+above as well as the
+\fIPreventing shell escapes\fR
+section at the end of this manual.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+pam_session
+On systems that use PAM for authentication,
+\fBsudo\fR
+will create a new PAM session for the command to be run in.
+Disabling
+\fIpam_session\fR
+may be needed on older PAM implementations or on operating systems where
+opening a PAM session changes the utmp or wtmp files.
+If PAM session support is disabled, resource limits may not be updated
+for the command being run.
+If
+\fIpam_session\fR,
+\fIpam_setcred\fR,
+and
+\fIuse_pty\fR
+are disabled and I/O logging has not been configured,
+\fBsudo\fR
+will execute the command directly instead of running it as a child
+process.
+This flag is
+\fI@pam_session@\fR
+by default.
+.sp
+This setting is only supported by version 1.8.7 or higher.
+.TP 18n
+pam_setcred
+On systems that use PAM for authentication,
+\fBsudo\fR
+will attempt to establish credentials for the target user by default,
+if supported by the underlying authentication system.
+One example of a credential is a Kerberos ticket.
+If
+\fIpam_session\fR,
+\fIpam_setcred\fR,
+and
+\fIuse_pty\fR
+are disabled and I/O logging has not been configured,
+\fBsudo\fR
+will execute the command directly instead of running it as a child
+process.
+This flag is
+\fIon\fR
+by default.
+.sp
+This setting is only supported by version 1.8.8 or higher.
+.TP 18n
+passprompt_override
+If set, the prompt specified by
+\fIpassprompt\fR
+or the
+\fRSUDO_PROMPT\fR
+environment variable will always be used and will replace the
+prompt provided by a PAM module or other authentication method.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+path_info
+Normally,
+\fBsudo\fR
+will tell the user when a command could not be
+found in their
+\fRPATH\fR
+environment variable.
+Some sites may wish to disable this as it could be used to gather
+information on the location of executables that the normal user does
+not have access to.
+The disadvantage is that if the executable is simply not in the user's
+\fRPATH\fR,
+\fBsudo\fR
+will tell the user that they are not allowed to run it, which can be confusing.
+This flag is
+\fI@path_info@\fR
+by default.
+.TP 18n
+preserve_groups
+By default,
+\fBsudo\fR
+will initialize the group vector to the list of groups the target user is in.
+When
+\fIpreserve_groups\fR
+is set, the user's existing group vector is left unaltered.
+The real and effective group IDs, however, are still set to match the
+target user.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+pwfeedback
+By default,
+\fBsudo\fR
+reads the password like most other Unix programs,
+by turning off echo until the user hits the return (or enter) key.
+Some users become confused by this as it appears to them that
+\fBsudo\fR
+has hung at this point.
+When
+\fIpwfeedback\fR
+is set,
+\fBsudo\fR
+will provide visual feedback when the user presses a key.
+Note that this does have a security impact as an onlooker may be able to
+determine the length of the password being entered.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+requiretty
+If set,
+\fBsudo\fR
+will only run when the user is logged in to a real tty.
+When this flag is set,
+\fBsudo\fR
+can only be run from a login session and not via other means such as
+cron(@mansectsu@)
+or cgi-bin scripts.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+root_sudo
+If set, root is allowed to run
+\fBsudo\fR
+too.
+Disabling this prevents users from
+\(lqchaining\(rq
+\fBsudo\fR
+commands to get a root shell by doing something like
+\(lq\fRsudo sudo /bin/sh\fR\(rq.
+Note, however, that turning off
+\fIroot_sudo\fR
+will also prevent root from running
+\fBsudoedit\fR.
+Disabling
+\fIroot_sudo\fR
+provides no real additional security; it exists purely for historical reasons.
+This flag is
+\fI@root_sudo@\fR
+by default.
+.TP 18n
+rootpw
+If set,
+\fBsudo\fR
+will prompt for the root password instead of the password of the invoking user
+when running a command or editing a file.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+runaspw
+If set,
+\fBsudo\fR
+will prompt for the password of the user defined by the
+\fIrunas_default\fR
+option (defaults to
+\fR@runas_default@\fR)
+instead of the password of the invoking user
+when running a command or editing a file.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+set_home
+If enabled and
+\fBsudo\fR
+is invoked with the
+\fB\-s\fR
+option the
+\fRHOME\fR
+environment variable will be set to the home directory of the target
+user (which is root unless the
+\fB\-u\fR
+option is used).
+This effectively makes the
+\fB\-s\fR
+option imply
+\fB\-H\fR.
+Note that
+\fRHOME\fR
+is already set when the
+\fIenv_reset\fR
+option is enabled, so
+\fIset_home\fR
+is only effective for configurations where either
+\fIenv_reset\fR
+is disabled
+or
+\fRHOME\fR
+is present in the
+\fIenv_keep\fR
+list.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+set_logname
+Normally,
+\fBsudo\fR
+will set the
+\fRLOGNAME\fR
+and
+\fRUSER\fR
+environment variables to the name of the target user (usually root unless the
+\fB\-u\fR
+option is given).
+However, since some programs (including the RCS revision control system) use
+\fRLOGNAME\fR
+to determine the real identity of the user, it may be desirable to
+change this behavior.
+This can be done by negating the set_logname option.
+Note that
+\fIset_logname\fR
+will have no effect
+if the
+\fIenv_reset\fR
+option has not been disabled and the
+\fIenv_keep\fR
+list contains
+\fRLOGNAME\fR
+or
+\fRUSER\fR.
+This flag is
+\fIon\fR
+by default.
+.TP 18n
+set_utmp
+When enabled,
+\fBsudo\fR
+will create an entry in the utmp (or utmpx) file when a pseudo-tty
+is allocated.
+A pseudo-tty is allocated by
+\fBsudo\fR
+when the
+\fIlog_input\fR,
+\fIlog_output\fR
+or
+\fIuse_pty\fR
+flags are enabled.
+By default, the new entry will be a copy of the user's existing utmp
+entry (if any), with the tty, time, type and pid fields updated.
+This flag is
+\fIon\fR
+by default.
+.TP 18n
+setenv
+Allow the user to disable the
+\fIenv_reset\fR
+option from the command line via the
+\fB\-E\fR
+option.
+Additionally, environment variables set via the command line are
+not subject to the restrictions imposed by
+\fIenv_check\fR,
+\fIenv_delete\fR,
+or
+\fIenv_keep\fR.
+As such, only trusted users should be allowed to set variables in this manner.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+shell_noargs
+If set and
+\fBsudo\fR
+is invoked with no arguments it acts as if the
+\fB\-s\fR
+option had been given.
+That is, it runs a shell as root (the shell is determined by the
+\fRSHELL\fR
+environment variable if it is set, falling back on the shell listed
+in the invoking user's /etc/passwd entry if not).
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+stay_setuid
+Normally, when
+\fBsudo\fR
+executes a command the real and effective UIDs are set to the target
+user (root by default).
+This option changes that behavior such that the real UID is left
+as the invoking user's UID.
+In other words, this makes
+\fBsudo\fR
+act as a setuid wrapper.
+This can be useful on systems that disable some potentially
+dangerous functionality when a program is run setuid.
+This option is only effective on systems that support either the
+setreuid(2)
+or
+setresuid(2)
+system call.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+sudoedit_checkdir
+.br
+If set,
+\fBsudoedit\fR
+will check all directory components of the path to be edited for writability
+by the invoking user.
+Symbolic links will not be followed in writable directories and
+\fBsudoedit\fR
+will refuse to edit a file located in a writable directory.
+These restrictions are not enforced when
+\fBsudoedit\fR
+is run by root.
+On some systems, if all directory components of the path to be edited
+are not readable by the target user,
+\fBsudoedit\fR
+will be unable to edit the file.
+This flag is
+\fIon\fR
+by default.
+.sp
+This setting was first introduced in version 1.8.15 but initially
+suffered from a race condition.
+The check for symbolic links in writable intermediate directories
+was added in version 1.8.16.
+.TP 18n
+sudoedit_follow
+By default,
+\fBsudoedit\fR
+will not follow symbolic links when opening files.
+The
+\fIsudoedit_follow\fR
+option can be enabled to allow
+\fBsudoedit\fR
+to open symbolic links.
+It may be overridden on a per-command basis by the
+\fIFOLLOW\fR
+and
+\fINOFOLLOW\fR
+tags.
+This flag is
+\fIoff\fR
+by default.
+.sp
+This setting is only supported by version 1.8.15 or higher.
+.TP 18n
+syslog_pid
+When logging via
+syslog(3),
+include the process ID in the log entry.
+This flag is
+\fIoff\fR
+by default.
+.sp
+This setting is only supported by version 1.8.21 or higher.
+.TP 18n
+targetpw
+If set,
+\fBsudo\fR
+will prompt for the password of the user specified
+by the
+\fB\-u\fR
+option (defaults to
+\fRroot\fR)
+instead of the password of the invoking user
+when running a command or editing a file.
+Note that this flag precludes the use of a uid not listed in the passwd
+database as an argument to the
+\fB\-u\fR
+option.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+tty_tickets
+If set, users must authenticate on a per-tty basis.
+With this flag enabled,
+\fBsudo\fR
+will use a separate record in the time stamp file for each terminal.
+If disabled, a single record is used for all login sessions.
+.sp
+This option has been superseded by the
+\fItimestamp_type\fR
+option.
+.TP 18n
+umask_override
+If set,
+\fBsudo\fR
+will set the umask as specified in the
+\fIsudoers\fR
+file without modification.
+This makes it possible to specify a umask in the
+\fIsudoers\fR
+file that is more permissive than the user's own umask and matches
+historical behavior.
+If
+\fIumask_override\fR
+is not set,
+\fBsudo\fR
+will set the umask to be the union of the user's umask and what is specified in
+\fIsudoers\fR.
+This flag is
+\fI@umask_override@\fR
+by default.
+.if \n(BA \{\
+.TP 18n
+use_loginclass
+If set,
+\fBsudo\fR
+will apply the defaults specified for the target user's login class
+if one exists.
+Only available if
+\fBsudo\fR
+is configured with the
+\fR--with-logincap\fR
+option.
+This flag is
+\fIoff\fR
+by default.
+.\}
+.TP 18n
+use_netgroups
+If set, netgroups (prefixed with
+\(oq+\(cq),
+may be used in place of a user or host.
+For LDAP-based sudoers, netgroup support requires an expensive
+sub-string match on the server unless the
+\fBNETGROUP_BASE\fR
+directive is present in the
+\fI@ldap_conf@\fR
+file.
+If netgroups are not needed, this option can be disabled to reduce the
+load on the LDAP server.
+This flag is
+\fIon\fR
+by default.
+.TP 18n
+use_pty
+If set, and
+\fBsudo\fR
+is running in a terminal, the command will be run in a pseudo-pty
+(even if no I/O logging is being done).
+If the
+\fBsudo\fR
+process is not attached to a terminal,
+\fIuse_pty\fR
+has no effect.
+.sp
+A malicious program run under
+\fBsudo\fR
+may be capable of injecting commands into the user's
+terminal or running a background process that retains access to the
+user's terminal device even after the main program has finished
+executing.
+By running the command in a separate pseudo-pty, this attack is
+no longer possible.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+user_command_timeouts
+If set, the user may specify a timeout on the command line.
+If the timeout expires before the command has exited, the
+command will be terminated.
+If a timeout is specified both in the
+\fIsudoers\fR
+file and on the command line, the smaller of the two timeouts will be used.
+See the
+\fRTimeout_Spec\fR
+section for a description of the timeout syntax.
+This flag is
+\fIoff\fR
+by default.
+.sp
+This setting is only supported by version 1.8.20 or higher.
+.TP 18n
+utmp_runas
+If set,
+\fBsudo\fR
+will store the name of the runas user when updating the utmp (or utmpx) file.
+By default,
+\fBsudo\fR
+stores the name of the invoking user.
+This flag is
+\fIoff\fR
+by default.
+.TP 18n
+visiblepw
+By default,
+\fBsudo\fR
+will refuse to run if the user must enter a password but it is not
+possible to disable echo on the terminal.
+If the
+\fIvisiblepw\fR
+flag is set,
+\fBsudo\fR
+will prompt for a password even when it would be visible on the screen.
+This makes it possible to run things like
+\(lq\fRssh somehost sudo ls\fR\(rq
+since by default,
+ssh(1)
+does
+not allocate a tty when running a command.
+This flag is
+\fIoff\fR
+by default.
+.PP
+\fBIntegers\fR:
+.TP 18n
+closefrom
+Before it executes a command,
+\fBsudo\fR
+will close all open file descriptors other than standard input,
+standard output and standard error (ie: file descriptors 0-2).
+The
+\fIclosefrom\fR
+option can be used to specify a different file descriptor at which
+to start closing.
+The default is
+\fR3\fR.
+.TP 18n
+command_timeout
+The maximum amount of time a command is allowed to run before
+it is terminated.
+See the
+\fRTimeout_Spec\fR
+section for a description of the timeout syntax.
+.sp
+This setting is only supported by version 1.8.20 or higher.
+.TP 18n
+maxseq
+The maximum sequence number that will be substituted for the
+\(lq\fR%{seq}\fR\(rq
+escape in the I/O log file (see the
+\fIiolog_dir\fR
+description below for more information).
+While the value substituted for
+\(lq\fR%{seq}\fR\(rq
+is in base 36,
+\fImaxseq\fR
+itself should be expressed in decimal.
+Values larger than 2176782336 (which corresponds to the
+base 36 sequence number
+\(lqZZZZZZ\(rq)
+will be silently truncated to 2176782336.
+The default value is 2176782336.
+.sp
+Once the local sequence number reaches the value of
+\fImaxseq\fR,
+it will
+\(lqroll over\(rq
+to zero, after which
+\fBsudoers\fR
+will truncate and re-use any existing I/O log path names.
+.sp
+This setting is only supported by version 1.8.7 or higher.
+.TP 18n
+passwd_tries
+The number of tries a user gets to enter his/her password before
+\fBsudo\fR
+logs the failure and exits.
+The default is
+\fR@passwd_tries@\fR.
+.TP 18n
+syslog_maxlen
+On many systems,
+syslog(3)
+has a relatively small log buffer.
+IETF RFC 5424 states that syslog servers must support messages of
+at least 480 bytes and should support messages up to 2048 bytes.
+By default,
+\fBsudoers\fR
+creates log messages up to 980 bytes which corresponds to the
+historic
+BSD
+syslog implementation which used a 1024 byte buffer
+to store the message, date, hostname and program name.
+To prevent syslog messages from being truncated,
+\fBsudoers\fR
+will split up log messages that are larger than
+\fIsyslog_maxlen\fR
+bytes.
+When a message is split, additional parts will include the string
+\(lq(command continued)\(rq
+after the user name and before the continued command line arguments.
+.sp
+This setting is only supported by version 1.8.19 or higher.
+.PP
+\fBIntegers that can be used in a boolean context\fR:
+.TP 18n
+loglinelen
+Number of characters per line for the file log.
+This value is used to decide when to wrap lines for nicer log files.
+This has no effect on the syslog log file, only the file log.
+The default is
+\fR@loglen@\fR
+(use 0 or negate the option to disable word wrap).
+.TP 18n
+passwd_timeout
+Number of minutes before the
+\fBsudo\fR
+password prompt times out, or
+\fR0\fR
+for no timeout.
+The timeout may include a fractional component
+if minute granularity is insufficient, for example
+\fR2.5\fR.
+The
+default is
+\fR@password_timeout@\fR.
+.TP 18n
+timestamp_timeout
+.br
+Number of minutes that can elapse before
+\fBsudo\fR
+will ask for a passwd again.
+The timeout may include a fractional component if
+minute granularity is insufficient, for example
+\fR2.5\fR.
+The default is
+\fR@timeout@\fR.
+Set this to
+\fR0\fR
+to always prompt for a password.
+If set to a value less than
+\fR0\fR
+the user's time stamp will not expire until the system is rebooted.
+This can be used to allow users to create or delete their own time stamps via
+\(lq\fRsudo -v\fR\(rq
+and
+\(lq\fRsudo -k\fR\(rq
+respectively.
+.TP 18n
+umask
+Umask to use when running the command.
+Negate this option or set it to 0777 to preserve the user's umask.
+The actual umask that is used will be the union of the user's umask
+and the value of the
+\fIumask\fR
+option, which defaults to
+\fR@sudo_umask@\fR.
+This guarantees
+that
+\fBsudo\fR
+never lowers the umask when running a command.
+Note: on systems that use PAM, the default PAM configuration may specify
+its own umask which will override the value set in
+\fIsudoers\fR.
+.PP
+\fBStrings\fR:
+.TP 18n
+authfail_message
+Message that is displayed after a user fails to authenticate.
+The message may include the
+\(oq%d\(cq
+escape which will expand to the number of failed password attempts.
+If set, it overrides the default message,
+\fR%d incorrect password attempt(s)\fR.
+.TP 18n
+badpass_message
+Message that is displayed if a user enters an incorrect password.
+The default is
+\fR@badpass_message@\fR
+unless insults are enabled.
+.TP 18n
+editor
+A colon
+(\(oq:\&\(cq)
+separated list of editors path names used by
+\fBsudoedit\fR
+and
+\fBvisudo\fR.
+For
+\fBsudoedit\fR,
+this list is used to find an editor when none of the
+\fRSUDO_EDITOR\fR,
+\fRVISUAL\fR
+or
+\fREDITOR\fR
+environment variables are set to an editor that exists and is executable.
+For
+\fBvisudo\fR,
+it is used as a white list of allowed editors;
+\fBvisudo\fR
+will choose the editor that matches the user's
+\fRSUDO_EDITOR\fR,
+\fRVISUAL\fR
+or
+\fREDITOR\fR
+environment variable if possible, or the first editor in the
+list that exists and is executable if not.
+Unless invoked as
+\fBsudoedit\fR,
+\fBsudo\fR
+does not preserve the
+\fRSUDO_EDITOR\fR,
+\fRVISUAL\fR
+and
+\fREDITOR\fR
+environment variables by default, even when the
+\fIenv_reset\fR
+option is enabled.
+The default is
+\fI@editor@\fR.
+.TP 18n
+iolog_dir
+The top-level directory to use when constructing the path name for
+the input/output log directory.
+Only used if the
+\fIlog_input\fR
+or
+\fIlog_output\fR
+options are enabled or when the
+\fRLOG_INPUT\fR
+or
+\fRLOG_OUTPUT\fR
+tags are present for a command.
+The session sequence number, if any, is stored in the directory.
+The default is
+\fI@iolog_dir@\fR.
+.sp
+The following percent
+(\(oq%\(cq)
+escape sequences are supported:
+.PP
+.RS 18n
+.PD 0
+.TP 6n
+\fR%{seq}\fR
+expanded to a monotonically increasing base-36 sequence number, such as 0100A5,
+where every two digits are used to form a new directory, e.g.,
+\fI01/00/A5\fR
+.PD
+.TP 6n
+\fR%{user}\fR
+expanded to the invoking user's login name
+.TP 6n
+\fR%{group}\fR
+expanded to the name of the invoking user's real group ID
+.TP 6n
+\fR%{runas_user}\fR
+expanded to the login name of the user the command will
+be run as (e.g., root)
+.TP 6n
+\fR%{runas_group}\fR
+expanded to the group name of the user the command will
+be run as (e.g., wheel)
+.TP 6n
+\fR%{hostname}\fR
+expanded to the local host name without the domain name
+.TP 6n
+\fR%{command}\fR
+expanded to the base name of the command being run
+.PP
+In addition, any escape sequences supported by the system's
+strftime(3)
+function will be expanded.
+.sp
+To include a literal
+\(oq%\(cq
+character, the string
+\(oq%%\(cq
+should be used.
+.RE
+.TP 18n
+iolog_file
+The path name, relative to
+\fIiolog_dir\fR,
+in which to store input/output logs when the
+\fIlog_input\fR
+or
+\fIlog_output\fR
+options are enabled or when the
+\fRLOG_INPUT\fR
+or
+\fRLOG_OUTPUT\fR
+tags are present for a command.
+Note that
+\fIiolog_file\fR
+may contain directory components.
+The default is
+\(lq\fR%{seq}\fR\(rq.
+.sp
+See the
+\fIiolog_dir\fR
+option above for a list of supported percent
+(\(oq%\(cq)
+escape sequences.
+.sp
+In addition to the escape sequences, path names that end in six or
+more
+\fRX\fRs
+will have the
+\fRX\fRs
+replaced with a unique combination of digits and letters, similar to the
+mktemp(3)
+function.
+.sp
+If the path created by concatenating
+\fIiolog_dir\fR
+and
+\fIiolog_file\fR
+already exists, the existing I/O log file will be truncated and
+overwritten unless
+\fIiolog_file\fR
+ends in six or
+more
+\fRX\fRs.
+.TP 18n
+iolog_flush
+If set,
+\fBsudo\fR
+will flush I/O log data to disk after each write instead of buffering it.
+This makes it possible to view the logs in real-time as the program
+is executing but may significantly reduce the effectiveness of I/O
+log compression.
+This flag is
+\fIoff\fR
+by default.
+.sp
+This setting is only supported by version 1.8.20 or higher.
+.TP 18n
+iolog_group
+The group name to look up when setting the group ID on new I/O log
+files and directories.
+If
+\fIiolog_group\fR
+is not set,
+the primary group ID of the user specified by
+\fIiolog_user\fR
+is used.
+If neither
+\fIiolog_group\fR
+nor
+\fIiolog_user\fR
+are set, I/O log files and directories are created with group ID 0.
+.sp
+This setting is only supported by version 1.8.19 or higher.
+.TP 18n
+iolog_mode
+The file mode to use when creating I/O log files.
+Mode bits for read and write permissions for owner, group or other
+are honored, everything else is ignored.
+The file permissions will always include the owner read and
+write bits, even if they are not present in the specified mode.
+When creating I/O log directories, search (execute) bits are added
+to match the read and write bits specified by
+\fIiolog_mode\fR.
+Defaults to 0600 (read and write by user only).
+.sp
+This setting is only supported by version 1.8.19 or higher.
+.TP 18n
+iolog_user
+The user name to look up when setting the user and group IDs on new
+I/O log files and directories.
+If
+\fIiolog_group\fR
+is set, it will be used instead of the user's primary group ID.
+By default, I/O log files and directories are created with user and
+group ID 0.
+.sp
+This setting can be useful when the I/O logs are stored on a Network
+File System (NFS) share.
+Having a dedicated user own the I/O log files means that
+\fBsudoers\fR
+does not write to the log files as user ID 0, which is usually
+not permitted by NFS.
+.sp
+This setting is only supported by version 1.8.19 or higher.
+.TP 18n
+lecture_status_dir
+The directory in which
+\fBsudo\fR
+stores per-user lecture status files.
+Once a user has received the lecture, a zero-length file is
+created in this directory so that
+\fBsudo\fR
+will not lecture the user again.
+This directory should
+\fInot\fR
+be cleared when the system reboots.
+The default is
+\fI@vardir@/lectured\fR.
+.if \n(PS \{\
+.TP 18n
+limitprivs
+The default Solaris limit privileges to use when constructing a new
+privilege set for a command.
+This bounds all privileges of the executing process.
+The default limit privileges may be overridden on a per-command basis in
+\fIsudoers\fR.
+This option is only available if
+\fBsudoers\fR
+is built on Solaris 10 or higher.
+.\}
+.TP 18n
+mailsub
+Subject of the mail sent to the
+\fImailto\fR
+user.
+The escape
+\fR%h\fR
+will expand to the host name of the machine.
+Default is
+\(lq\fR@mailsub@\fR\(rq.
+.TP 18n
+noexec_file
+As of
+\fBsudo\fR
+version 1.8.1 this option is no longer supported.
+The path to the noexec file should now be set in the
+sudo.conf(@mansectform@)
+file.
+.TP 18n
+pam_login_service
+.br
+On systems that use PAM for authentication, this is the service
+name used when the
+\fB\-i\fR
+option is specified.
+The default value is
+\(lq\fR@pam_login_service@\fR\(rq.
+See the description of
+\fIpam_service\fR
+for more information.
+.sp
+This setting is only supported by version 1.8.8 or higher.
+.TP 18n
+pam_service
+On systems that use PAM for authentication, the service name
+specifies the PAM policy to apply.
+This usually corresponds to an entry in the
+\fIpam.conf\fR
+file or a file in the
+\fI/etc/pam.d\fR
+directory.
+The default value is
+\(lq\fRsudo\fR\(rq.
+.sp
+This setting is only supported by version 1.8.8 or higher.
+.TP 18n
+passprompt
+The default prompt to use when asking for a password; can be overridden via the
+\fB\-p\fR
+option or the
+\fRSUDO_PROMPT\fR
+environment variable.
+The following percent
+(\(oq%\(cq)
+escape sequences are supported:
+.PP
+.RS 18n
+.PD 0
+.TP 6n
+\fR%H\fR
+expanded to the local host name including the domain name
+(only if the machine's host name is fully qualified or the
+\fIfqdn\fR
+option is set)
+.PD
+.TP 6n
+\fR%h\fR
+expanded to the local host name without the domain name
+.TP 6n
+\fR%p\fR
+expanded to the user whose password is being asked for (respects the
+\fIrootpw\fR,
+\fItargetpw\fR
+and
+\fIrunaspw\fR
+flags in
+\fIsudoers\fR)
+.TP 6n
+\fR\&%U\fR
+expanded to the login name of the user the command will
+be run as (defaults to root)
+.TP 6n
+\fR%u\fR
+expanded to the invoking user's login name
+.TP 6n
+\fR%%\fR
+two consecutive
+\fR%\fR
+characters are collapsed into a single
+\fR%\fR
+character
+.PP
+On systems that use PAM for authentication,
+\fIpassprompt\fR
+will only be used if the prompt provided by the PAM module matches the string
+\(lqPassword: \(rq
+or
+\(lqusername's Password: \(rq.
+This ensures that the
+\fIpassprompt\fR
+setting does not interfere with challenge-response style authentication.
+The
+\fIpassprompt_override\fR
+flag can be used to change this behavior.
+.sp
+The default value is
+\(lq\fR@passprompt@\fR\(rq.
+.RE
+.if \n(PS \{\
+.TP 18n
+privs
+The default Solaris privileges to use when constructing a new
+privilege set for a command.
+This is passed to the executing process via the inherited privilege set,
+but is bounded by the limit privileges.
+If the
+\fIprivs\fR
+option is specified but the
+\fIlimitprivs\fR
+option is not, the limit privileges of the executing process is set to
+\fIprivs\fR.
+The default privileges may be overridden on a per-command basis in
+\fIsudoers\fR.
+This option is only available if
+\fBsudoers\fR
+is built on Solaris 10 or higher.
+.\}
+.if \n(SL \{\
+.TP 18n
+role
+The default SELinux role to use when constructing a new security
+context to run the command.
+The default role may be overridden on a per-command basis in the
+\fIsudoers\fR
+file or via command line options.
+This option is only available when
+\fBsudo\fR
+is built with SELinux support.
+.\}
+.TP 18n
+runas_default
+The default user to run commands as if the
+\fB\-u\fR
+option is not specified on the command line.
+This defaults to
+\fR@runas_default@\fR.
+.TP 18n
+sudoers_locale
+Locale to use when parsing the sudoers file, logging commands, and
+sending email.
+Note that changing the locale may affect how sudoers is interpreted.
+Defaults to
+\(lq\fRC\fR\(rq.
+.TP 18n
+timestamp_type
+\fBsudoers\fR
+uses per-user time stamp files for credential caching.
+The
+\fItimestamp_type\fR
+option can be used to specify the type of time stamp record used.
+It has the following possible values:
+.PP
+.RS 18n
+.PD 0
+.TP 8n
+global
+A single time stamp record is used for all of a user's login sessions,
+regardless of the terminal or parent process ID.
+An additional record is used to serialize password prompts when
+\fBsudo\fR
+is used multiple times in a pipeline, but this does not affect authentication.
+.PD
+.TP 8n
+ppid
+A single time stamp record is used for all processes with the same parent
+process ID (usually the shell).
+Commands run from the same shell (or other common parent process)
+will not require a password for
+\fItimestamp_timeout\fR
+minutes
+(\fR@timeout@\fR
+by default)
+\&.
+Commands run via
+\fBsudo\fR
+with a different parent process ID, for example from a shell script,
+will be authenticated separately.
+.TP 8n
+tty
+One time stamp record is used for each terminal,
+which means that a user's login sessions are authenticated separately.
+If no terminal is present, the behavior is the same as
+\fIppid\fR.
+Commands run from the same terminal will not require a password for
+\fItimestamp_timeout\fR
+minutes
+(\fR@timeout@\fR
+by default)
+\&.
+.TP 8n
+kernel
+The time stamp is stored in the kernel as an attribute of the terminal
+device.
+If no terminal is present, the behavior is the same as
+\fIppid\fR.
+Negative
+\fItimestamp_timeout\fR
+values are not supported and positive values are limited to a maximum
+of 60 minutes.
+This is currently only supported on
+OpenBSD.
+.PP
+The default value is
+\fI@timestamp_type@\fR.
+.sp
+This setting is only supported by version 1.8.21 or higher.
+.RE
+.TP 18n
+timestampdir
+The directory in which
+\fBsudo\fR
+stores its time stamp files.
+This directory should be cleared when the system reboots.
+The default is
+\fI@rundir@/ts\fR.
+.TP 18n
+timestampowner
+The owner of the lecture status directory, time stamp directory and all
+files stored therein.
+The default is
+\fRroot\fR.
+.if \n(SL \{\
+.TP 18n
+type
+The default SELinux type to use when constructing a new security
+context to run the command.
+The default type may be overridden on a per-command basis in the
+\fIsudoers\fR
+file or via command line options.
+This option is only available when
+\fBsudo\fR
+is built with SELinux support.
+.PP
+\fBStrings that can be used in a boolean context\fR:
+.TP 14n
+env_file
+The
+\fIenv_file\fR
+option specifies the fully qualified path to a file containing variables
+to be set in the environment of the program being run.
+Entries in this file should either be of the form
+\(lq\fRVARIABLE=value\fR\(rq
+or
+\(lq\fRexport VARIABLE=value\fR\(rq.
+The value may optionally be surrounded by single or double quotes.
+Variables in this file are only added if the variable does not already
+exist in the environment.
+This file is considered to be part of the security policy,
+its contents are not subject to other
+\fBsudo\fR
+environment restrictions such as
+\fIenv_keep\fR
+and
+\fIenv_check\fR.
+.TP 14n
+exempt_group
+Users in this group are exempt from password and PATH requirements.
+The group name specified should not include a
+\fR%\fR
+prefix.
+This is not set by default.
+.TP 14n
+fdexec
+Determines whether
+\fBsudo\fR
+will execute a command by its path or by an open file descriptor.
+It has the following possible values:
+.PP
+.RS 14n
+.PD 0
+.TP 8n
+always
+Always execute by file descriptor.
+.PD
+.TP 8n
+never
+Never execute by file descriptor.
+.TP 8n
+digest_only
+Only execute by file descriptor if the command has an associated digest
+in the
+\fIsudoers\fR
+file.
+.PP
+The default value is
+\fIdigest_only\fR.
+This avoids a time of check versus time of use race condition when
+the command is located in a directory writable by the invoking user.
+.sp
+Note that
+\fIfdexec\fR
+will change the first element of the argument vector for scripts
+($0 in the shell) due to the way the kernel runs script interpreters.
+Instead of being a normal path, it will refer to a file descriptor.
+For example,
+\fI/dev/fd/4\fR
+on Solaris and
+\fI/proc/self/fd/4\fR
+on Linux.
+A workaround is to use the
+\fRSUDO_COMMAND\fR
+environment variable instead.
+.sp
+The
+\fIfdexec\fR
+setting is only used when the command is matched by path name.
+It has no effect if the command is matched by the built-in
+\fBALL\fR
+alias.
+.sp
+This setting is only supported by version 1.8.20 or higher.
+If the operating system does not support the
+fexecve(2)
+system call, this setting has no effect.
+.RE
+.TP 14n
+group_plugin
+A string containing a
+\fBsudoers\fR
+group plugin with optional arguments.
+The string should consist of the plugin
+path, either fully-qualified or relative to the
+\fI@PLUGINDIR@\fR
+directory, followed by any configuration arguments the plugin requires.
+These arguments (if any) will be passed to the plugin's initialization function.
+If arguments are present, the string must be enclosed in double quotes
+(\&"").
+.sp
+For more information see
+\fIGROUP PROVIDER PLUGINS\fR.
+.TP 14n
+lecture
+This option controls when a short lecture will be printed along with
+the password prompt.
+It has the following possible values:
+.PP
+.RS 14n
+.PD 0
+.TP 8n
+always
+Always lecture the user.
+.PD
+.TP 8n
+never
+Never lecture the user.
+.TP 8n
+once
+Only lecture the user the first time they run
+\fBsudo\fR.
+.PP
+If no value is specified, a value of
+\fIonce\fR
+is implied.
+Negating the option results in a value of
+\fInever\fR
+being used.
+The default value is
+\fI@lecture@\fR.
+.RE
+.TP 14n
+lecture_file
+Path to a file containing an alternate
+\fBsudo\fR
+lecture that will be used in place of the standard lecture if the named
+file exists.
+By default,
+\fBsudo\fR
+uses a built-in lecture.
+.TP 14n
+listpw
+This option controls when a password will be required when a user runs
+\fBsudo\fR
+with the
+\fB\-l\fR
+option.
+It has the following possible values:
+.PP
+.RS 14n
+.PD 0
+.TP 10n
+all
+All the user's
+\fIsudoers\fR
+file entries for the current host must have
+the
+\fRNOPASSWD\fR
+flag set to avoid entering a password.
+.PD
+.TP 10n
+always
+The user must always enter a password to use the
+\fB\-l\fR
+option.
+.TP 10n
+any
+At least one of the user's
+\fIsudoers\fR
+file entries for the current host
+must have the
+\fRNOPASSWD\fR
+flag set to avoid entering a password.
+.TP 10n
+never
+The user need never enter a password to use the
+\fB\-l\fR
+option.
+.PP
+If no value is specified, a value of
+\fIany\fR
+is implied.
+Negating the option results in a value of
+\fInever\fR
+being used.
+The default value is
+\fIany\fR.
+.RE
+.TP 14n
+logfile
+Path to the
+\fBsudo\fR
+log file (not the syslog log file).
+Setting a path turns on logging to a file;
+negating this option turns it off.
+By default,
+\fBsudo\fR
+logs via syslog.
+.TP 14n
+mailerflags
+Flags to use when invoking mailer.
+Defaults to
+\fB\-t\fR.
+.TP 14n
+mailerpath
+Path to mail program used to send warning mail.
+Defaults to the path to sendmail found at configure time.
+.TP 14n
+mailfrom
+Address to use for the
+\(lqfrom\(rq
+address when sending warning and error mail.
+The address should be enclosed in double quotes
+(\&"")
+to protect against
+\fBsudo\fR
+interpreting the
+\fR@\fR
+sign.
+Defaults to the name of the user running
+\fBsudo\fR.
+.TP 14n
+mailto
+Address to send warning and error mail to.
+The address should be enclosed in double quotes
+(\&"")
+to protect against
+\fBsudo\fR
+interpreting the
+\fR@\fR
+sign.
+Defaults to
+\fR@mailto@\fR.
+.TP 14n
+restricted_env_file
+The
+\fIrestricted_env_file\fR
+option specifies the fully qualified path to a file containing variables
+to be set in the environment of the program being run.
+Entries in this file should either be of the form
+\(lq\fRVARIABLE=value\fR\(rq
+or
+\(lq\fRexport VARIABLE=value\fR\(rq.
+The value may optionally be surrounded by single or double quotes.
+Variables in this file are only added if the variable does not already
+exist in the environment.
+Unlike
+\fIenv_file\fR,
+the file's contents are not trusted and are processed in a manner
+similar to that of the invoking user's environment.
+If
+\fIenv_reset\fR
+is enabled, variables in the file will only be added if they are
+matched by either the
+\fIenv_check\fR
+or
+\fIenv_keep\fR
+list.
+If
+\fIenv_reset\fR
+is disabled, variables in the file are added as long as they
+are not matched by the
+\fIenv_delete\fR
+list.
+In either case, the contents of
+\fIrestricted_env_file\fR
+are processed before the contents of
+\fIenv_file\fR.
+.TP 14n
+secure_path
+Path used for every command run from
+\fBsudo\fR.
+If you don't trust the
+people running
+\fBsudo\fR
+to have a sane
+\fRPATH\fR
+environment variable you may want to use this.
+Another use is if you want to have the
+\(lqroot path\(rq
+be separate from the
+\(lquser path\(rq.
+Users in the group specified by the
+\fIexempt_group\fR
+option are not affected by
+\fIsecure_path\fR.
+This option is @secure_path@ by default.
+.TP 14n
+syslog
+Syslog facility if syslog is being used for logging (negate to
+disable syslog logging).
+Defaults to
+\fR@logfac@\fR.
+.sp
+The following syslog facilities are supported:
+\fBauthpriv\fR
+(if your
+OS supports it),
+\fBauth\fR,
+\fBdaemon\fR,
+\fBuser\fR,
+\fBlocal0\fR,
+\fBlocal1\fR,
+\fBlocal2\fR,
+\fBlocal3\fR,
+\fBlocal4\fR,
+\fBlocal5\fR,
+\fBlocal6\fR,
+and
+\fBlocal7\fR.
+.TP 14n
+syslog_badpri
+.br
+Syslog priority to use when the user is not allowed to run a command or
+when authentication is unsuccessful.
+Defaults to
+\fR@badpri@\fR.
+.sp
+The following syslog priorities are supported:
+\fBalert\fR,
+\fBcrit\fR,
+\fBdebug\fR,
+\fBemerg\fR,
+\fBerr\fR,
+\fBinfo\fR,
+\fBnotice\fR,
+\fBwarning\fR,
+and
+\fBnone\fR.
+Negating the option or setting it to a value of
+\fBnone\fR
+will disable logging of unsuccessful commands.
+.TP 14n
+syslog_goodpri
+Syslog priority to use when the user is allowed to run a command and
+authentication is successful.
+Defaults to
+\fR@goodpri@\fR.
+.sp
+See
+\fIsyslog_badpri\fR
+for the list of supported syslog priorities.
+Negating the option or setting it to a value of
+\fBnone\fR
+will disable logging of successful commands.
+.TP 14n
+verifypw
+This option controls when a password will be required when a user runs
+\fBsudo\fR
+with the
+\fB\-v\fR
+option.
+It has the following possible values:
+.PP
+.RS 14n
+.PD 0
+.TP 8n
+all
+All the user's
+\fIsudoers\fR
+file entries for the current host must have the
+\fRNOPASSWD\fR
+flag set to avoid entering a password.
+.PD
+.TP 8n
+always
+The user must always enter a password to use the
+\fB\-v\fR
+option.
+.TP 8n
+any
+At least one of the user's
+\fIsudoers\fR
+file entries for the current host must have the
+\fRNOPASSWD\fR
+flag set to avoid entering a password.
+.TP 8n
+never
+The user need never enter a password to use the
+\fB\-v\fR
+option.
+.PP
+If no value is specified, a value of
+\fIall\fR
+is implied.
+Negating the option results in a value of
+\fInever\fR
+being used.
+The default value is
+\fIall\fR.
+.RE
+.PP
+\fBLists that can be used in a boolean context\fR:
+.\}
+.TP 18n
+env_check
+Environment variables to be removed from the user's environment
+unless they are considered
+\(lqsafe\(rq.
+For all variables except
+\fRTZ\fR,
+\(lqsafe\(rq
+means that the variable's value does not contain any
+\(oq%\(cq
+or
+\(oq/\(cq
+characters.
+This can be used to guard against printf-style format vulnerabilities
+in poorly-written programs.
+The
+\fRTZ\fR
+variable is considered unsafe if any of the following are true:
+.PP
+.RS 18n
+.PD 0
+.TP 3n
+\fB\(bu\fR
+It consists of a fully-qualified path name,
+optionally prefixed with a colon
+(\(oq:\&\(cq),
+that does not match the location of the
+\fIzoneinfo\fR
+directory.
+.PD
+.TP 3n
+\fB\(bu\fR
+It contains a
+\fI..\fR
+path element.
+.TP 3n
+\fB\(bu\fR
+It contains white space or non-printable characters.
+.TP 3n
+\fB\(bu\fR
+It is longer than the value of
+\fRPATH_MAX\fR.
+.PP
+The argument may be a double-quoted, space-separated list or a
+single value without double-quotes.
+The list can be replaced, added to, deleted from, or disabled by using
+the
+\fR=\fR,
+\fR+=\fR,
+\fR-=\fR,
+and
+\fR\&!\fR
+operators respectively.
+Regardless of whether the
+\fRenv_reset\fR
+option is enabled or disabled, variables specified by
+\fRenv_check\fR
+will be preserved in the environment if they pass the aforementioned check.
+The global list of environment variables to check is displayed when
+\fBsudo\fR
+is run by root with
+the
+\fB\-V\fR
+option.
+.RE
+.TP 18n
+env_delete
+Environment variables to be removed from the user's environment when the
+\fIenv_reset\fR
+option is not in effect.
+The argument may be a double-quoted, space-separated list or a
+single value without double-quotes.
+The list can be replaced, added to, deleted from, or disabled by using the
+\fR=\fR,
+\fR+=\fR,
+\fR-=\fR,
+and
+\fR\&!\fR
+operators respectively.
+The global list of environment variables to remove is displayed when
+\fBsudo\fR
+is run by root with the
+\fB\-V\fR
+option.
+Note that many operating systems will remove potentially dangerous
+variables from the environment of any setuid process (such as
+\fBsudo\fR).
+.TP 18n
+env_keep
+Environment variables to be preserved in the user's environment when the
+\fIenv_reset\fR
+option is in effect.
+This allows fine-grained control over the environment
+\fBsudo\fR-spawned
+processes will receive.
+The argument may be a double-quoted, space-separated list or a
+single value without double-quotes.
+The list can be replaced, added to, deleted from, or disabled by using the
+\fR=\fR,
+\fR+=\fR,
+\fR-=\fR,
+and
+\fR\&!\fR
+operators respectively.
+The global list of variables to keep
+is displayed when
+\fBsudo\fR
+is run by root with the
+\fB\-V\fR
+option.
+.SH "GROUP PROVIDER PLUGINS"
+The
+\fBsudoers\fR
+plugin supports its own plugin interface to allow non-Unix
+group lookups which can query a group source other
+than the standard Unix group database.
+This can be used to implement support for the
+\fRnonunix_group\fR
+syntax described earlier.
+.PP
+Group provider plugins are specified via the
+\fIgroup_plugin\fR
+Defaults setting.
+The argument to
+\fIgroup_plugin\fR
+should consist of the plugin path, either fully-qualified or relative to the
+\fI@PLUGINDIR@\fR
+directory, followed by any configuration options the plugin requires.
+These options (if specified) will be passed to the plugin's initialization
+function.
+If options are present, the string must be enclosed in double quotes
+(\&"").
+.PP
+The following group provider plugins are installed by default:
+.TP 10n
+group_file
+The
+\fIgroup_file\fR
+plugin supports an alternate group file that uses the same syntax as the
+\fI/etc/group\fR
+file.
+The path to the group file should be specified as an option
+to the plugin.
+For example, if the group file to be used is
+\fI/etc/sudo-group\fR:
+.nf
+.sp
+.RS 10n
+Defaults group_plugin="group_file.so /etc/sudo-group"
+.RE
+.fi
+.TP 10n
+system_group
+The
+\fIsystem_group\fR
+plugin supports group lookups via the standard C library functions
+\fBgetgrnam\fR()
+and
+\fBgetgrid\fR().
+This plugin can be used in instances where the user belongs to
+groups not present in the user's supplemental group vector.
+This plugin takes no options:
+.nf
+.sp
+.RS 10n
+Defaults group_plugin=system_group.so
+.RE
+.fi
+.PP
+The group provider plugin API is described in detail in
+sudo_plugin(@mansectform@).
+.SH "LOG FORMAT"
+\fBsudoers\fR
+can log events using either
+syslog(3)
+or a simple log file.
+The log format is almost identical in both cases.
+.SS "Accepted command log entries"
+Commands that sudo runs are logged using the following format (split
+into multiple lines for readability):
+.nf
+.sp
+.RS 4n
+date hostname progname: username : TTY=ttyname ; PWD=cwd ; \e
+ USER=runasuser ; GROUP=runasgroup ; TSID=logid ; \e
+ ENV=env_vars COMMAND=command
+.RE
+.fi
+.PP
+Where the fields are as follows:
+.TP 14n
+date
+The date the command was run.
+Typically, this is in the format
+\(lqMMM, DD, HH:MM:SS\(rq.
+If logging via
+syslog(3),
+the actual date format is controlled by the syslog daemon.
+If logging to a file and the
+\fIlog_year\fR
+option is enabled,
+the date will also include the year.
+.TP 14n
+hostname
+The name of the host
+\fBsudo\fR
+was run on.
+This field is only present when logging via
+syslog(3).
+.TP 14n
+progname
+The name of the program, usually
+\fIsudo\fR
+or
+\fIsudoedit\fR.
+This field is only present when logging via
+syslog(3).
+.TP 14n
+username
+The login name of the user who ran
+\fBsudo\fR.
+.TP 14n
+ttyname
+The short name of the terminal (e.g.,
+\(lqconsole\(rq,
+\(lqtty01\(rq,
+or
+\(lqpts/0\(rq)
+\fBsudo\fR
+was run on, or
+\(lqunknown\(rq
+if there was no terminal present.
+.TP 14n
+cwd
+The current working directory that
+\fBsudo\fR
+was run in.
+.TP 14n
+runasuser
+The user the command was run as.
+.TP 14n
+runasgroup
+The group the command was run as if one was specified on the command line.
+.TP 14n
+logid
+An I/O log identifier that can be used to replay the command's output.
+This is only present when the
+\fIlog_input\fR
+or
+\fIlog_output\fR
+option is enabled.
+.TP 14n
+env_vars
+A list of environment variables specified on the command line,
+if specified.
+.TP 14n
+command
+The actual command that was executed.
+.PP
+Messages are logged using the locale specified by
+\fIsudoers_locale\fR,
+which defaults to the
+\(lq\fRC\fR\(rq
+locale.
+.SS "Denied command log entries"
+If the user is not allowed to run the command, the reason for the denial
+will follow the user name.
+Possible reasons include:
+.TP 3n
+user NOT in sudoers
+The user is not listed in the
+\fIsudoers\fR
+file.
+.TP 3n
+user NOT authorized on host
+The user is listed in the
+\fIsudoers\fR
+file but is not allowed to run commands on the host.
+.TP 3n
+command not allowed
+The user is listed in the
+\fIsudoers\fR
+file for the host but they are not allowed to run the specified command.
+.TP 3n
+3 incorrect password attempts
+The user failed to enter their password after 3 tries.
+The actual number of tries will vary based on the number of
+failed attempts and the value of the
+\fIpasswd_tries\fR
+option.
+.TP 3n
+a password is required
+\fBsudo\fR's
+\fB\-n\fR
+option was specified but a password was required.
+.TP 3n
+sorry, you are not allowed to set the following environment variables
+The user specified environment variables on the command line that
+were not allowed by
+\fIsudoers\fR.
+.SS "Error log entries"
+If an error occurs,
+\fBsudoers\fR
+will log a message and, in most cases, send a message to the
+administrator via email.
+Possible errors include:
+.TP 3n
+parse error in @sysconfdir@/sudoers near line N
+\fBsudoers\fR
+encountered an error when parsing the specified file.
+In some cases, the actual error may be one line above or below the
+line number listed, depending on the type of error.
+.TP 3n
+problem with defaults entries
+The
+\fIsudoers\fR
+file contains one or more unknown Defaults settings.
+This does not prevent
+\fBsudo\fR
+from running, but the
+\fIsudoers\fR
+file should be checked using
+\fBvisudo\fR.
+.TP 3n
+timestamp owner (username): \&No such user
+The time stamp directory owner, as specified by the
+\fItimestampowner\fR
+setting, could not be found in the password database.
+.TP 3n
+unable to open/read @sysconfdir@/sudoers
+The
+\fIsudoers\fR
+file could not be opened for reading.
+This can happen when the
+\fIsudoers\fR
+file is located on a remote file system that maps user ID 0 to
+a different value.
+Normally,
+\fBsudoers\fR
+tries to open the
+\fIsudoers\fR
+file using group permissions to avoid this problem.
+Consider either changing the ownership of
+\fI@sysconfdir@/sudoers\fR
+or adding an argument like
+\(lqsudoers_uid=N\(rq
+(where
+\(oqN\(cq
+is the user ID that owns the
+\fIsudoers\fR
+file) to the end of the
+\fBsudoers\fR
+\fRPlugin\fR
+line in the
+sudo.conf(@mansectform@)
+file.
+.TP 3n
+unable to stat @sysconfdir@/sudoers
+The
+\fI@sysconfdir@/sudoers\fR
+file is missing.
+.TP 3n
+@sysconfdir@/sudoers is not a regular file
+The
+\fI@sysconfdir@/sudoers\fR
+file exists but is not a regular file or symbolic link.
+.TP 3n
+@sysconfdir@/sudoers is owned by uid N, should be 0
+The
+\fIsudoers\fR
+file has the wrong owner.
+If you wish to change the
+\fIsudoers\fR
+file owner, please add
+\(lqsudoers_uid=N\(rq
+(where
+\(oqN\(cq
+is the user ID that owns the
+\fIsudoers\fR
+file) to the
+\fBsudoers\fR
+\fRPlugin\fR
+line in the
+sudo.conf(@mansectform@)
+file.
+.TP 3n
+@sysconfdir@/sudoers is world writable
+The permissions on the
+\fIsudoers\fR
+file allow all users to write to it.
+The
+\fIsudoers\fR
+file must not be world-writable, the default file mode
+is 0440 (readable by owner and group, writable by none).
+The default mode may be changed via the
+\(lqsudoers_mode\(rq
+option to the
+\fBsudoers\fR
+\fRPlugin\fR
+line in the
+sudo.conf(@mansectform@)
+file.
+.TP 3n
+@sysconfdir@/sudoers is owned by gid N, should be 1
+The
+\fIsudoers\fR
+file has the wrong group ownership.
+If you wish to change the
+\fIsudoers\fR
+file group ownership, please add
+\(lqsudoers_gid=N\(rq
+(where
+\(oqN\(cq
+is the group ID that owns the
+\fIsudoers\fR
+file) to the
+\fBsudoers\fR
+\fRPlugin\fR
+line in the
+sudo.conf(@mansectform@)
+file.
+.TP 3n
+unable to open @rundir@/ts/username
+\fBsudoers\fR
+was unable to read or create the user's time stamp file.
+This can happen when
+\fItimestampowner\fR
+is set to a user other than root and the mode on
+\fI@rundir@\fR
+is not searchable by group or other.
+The default mode for
+\fI@rundir@\fR
+is 0711.
+.TP 3n
+unable to write to @rundir@/ts/username
+\fBsudoers\fR
+was unable to write to the user's time stamp file.
+.TP 3n
+@rundir@/ts is owned by uid X, should be Y
+The time stamp directory is owned by a user other than
+\fItimestampowner\fR.
+This can occur when the value of
+\fItimestampowner\fR
+has been changed.
+\fBsudoers\fR
+will ignore the time stamp directory until the owner is corrected.
+.TP 3n
+@rundir@/ts is group writable
+The time stamp directory is group-writable; it should be writable only by
+\fItimestampowner\fR.
+The default mode for the time stamp directory is 0700.
+\fBsudoers\fR
+will ignore the time stamp directory until the mode is corrected.
+.SS "Notes on logging via syslog"
+By default,
+\fBsudoers\fR
+logs messages via
+syslog(3).
+The
+\fIdate\fR,
+\fIhostname\fR,
+and
+\fIprogname\fR
+fields are added by the system's
+\fBsyslog\fR()
+function, not
+\fBsudoers\fR
+itself.
+As such, they may vary in format on different systems.
+.PP
+The maximum size of syslog messages varies from system to system.
+The
+\fIsyslog_maxlen\fR
+setting can be used to change the maximum syslog message size
+from the default value of 980 bytes.
+For more information, see the description of
+\fIsyslog_maxlen\fR.
+.SS "Notes on logging to a file"
+If the
+\fIlogfile\fR
+option is set,
+\fBsudoers\fR
+will log to a local file, such as
+\fI/var/log/sudo\fR.
+When logging to a file,
+\fBsudoers\fR
+uses a format similar to
+syslog(3),
+with a few important differences:
+.TP 5n
+1.\&
+The
+\fIprogname\fR
+and
+\fIhostname\fR
+fields are not present.
+.TP 5n
+2.\&
+If the
+\fIlog_year\fR
+option is enabled,
+the date will also include the year.
+.TP 5n
+3.\&
+Lines that are longer than
+\fIloglinelen\fR
+characters (80 by default) are word-wrapped and continued on the
+next line with a four character indent.
+This makes entries easier to read for a human being, but makes it
+more difficult to use
+grep(1)
+on the log files.
+If the
+\fIloglinelen\fR
+option is set to 0 (or negated with a
+\(oq\&!\(cq),
+word wrap will be disabled.
+.SH "I/O LOG FILES"
+When I/O logging is enabled,
+\fBsudo\fR
+will run the command in a pseudo-tty and log all user input and/or output,
+depending on which options are enabled.
+I/O is logged to the directory specified by the
+\fIiolog_dir\fR
+option
+(\fI@iolog_dir@\fR
+by default)
+using a unique session ID that is included in the
+\fBsudo\fR
+log line, prefixed with
+\(lq\fRTSID=\fR\(rq.
+The
+\fIiolog_file\fR
+option may be used to control the format of the session ID.
+.PP
+Each I/O log is stored in a separate directory that contains the
+following files:
+.TP 10n
+\fIlog\fR
+a text file containing the time the command was run, the name of the user
+who ran
+\fBsudo\fR,
+the name of the target user, the name of the target group (optional),
+the terminal that
+\fBsudo\fR
+was run from, the number of rows and columns of the terminal,
+the working directory the command was run from and the path name of
+the command itself (with arguments if present)
+.TP 10n
+\fItiming\fR
+a log of the amount of time between, and the number of bytes in, each
+I/O log entry (used for session playback)
+.TP 10n
+\fIttyin\fR
+input from the user's tty (what the user types)
+.TP 10n
+\fIstdin\fR
+input from a pipe or file
+.TP 10n
+\fIttyout\fR
+output from the pseudo-tty (what the command writes to the screen)
+.TP 10n
+\fIstdout\fR
+standard output to a pipe or redirected to a file
+.TP 10n
+\fIstderr\fR
+standard error to a pipe or redirected to a file
+.PP
+All files other than
+\fIlog\fR
+are compressed in gzip format unless the
+\fIcompress_io\fR
+flag has been disabled.
+Due to buffering, it is not normally possible to display the I/O logs in
+real-time as the program is executing
+The I/O log data will not be complete until the program run by
+\fBsudo\fR
+has exited or has been terminated by a signal.
+The
+\fIiolog_flush\fR
+flag can be used to disable buffering, in which case I/O log data
+is written to disk as soon as it is available.
+The output portion of an I/O log file can be viewed with the
+sudoreplay(@mansectsu@)
+utility, which can also be used to list or search the available logs.
+.PP
+Note that user input may contain sensitive information such as
+passwords (even if they are not echoed to the screen), which will
+be stored in the log file unencrypted.
+In most cases, logging the command output via
+\fIlog_output\fR
+or
+\fRLOG_OUTPUT\fR
+is all that is required.
+.PP
+Since each session's I/O logs are stored in a separate directory,
+traditional log rotation utilities cannot be used to limit the
+number of I/O logs.
+The simplest way to limit the number of I/O is by setting the
+\fImaxseq\fR
+option to the maximum number of logs you wish to store.
+Once the I/O log sequence number reaches
+\fImaxseq\fR,
+it will be reset to zero and
+\fBsudoers\fR
+will truncate and re-use any existing I/O logs.
+.SH "FILES"
+.TP 26n
+\fI@sysconfdir@/sudo.conf\fR
+Sudo front end configuration
+.TP 26n
+\fI@sysconfdir@/sudoers\fR
+List of who can run what
+.TP 26n
+\fI/etc/group\fR
+Local groups file
+.TP 26n
+\fI/etc/netgroup\fR
+List of network groups
+.TP 26n
+\fI@iolog_dir@\fR
+I/O log files
+.TP 26n
+\fI@rundir@/ts\fR
+Directory containing time stamps for the
+\fBsudoers\fR
+security policy
+.TP 26n
+\fI@vardir@/lectured\fR
+Directory containing lecture status files for the
+\fBsudoers\fR
+security policy
+.TP 26n
+\fI/etc/environment\fR
+Initial environment for
+\fB\-i\fR
+mode on AIX and Linux systems
+.SH "EXAMPLES"
+Below are example
+\fIsudoers\fR
+file entries.
+Admittedly, some of these are a bit contrived.
+First, we allow a few environment variables to pass and then define our
+\fIaliases\fR:
+.nf
+.sp
+.RS 0n
+# Run X applications through sudo; HOME is used to find the
+# .Xauthority file. Note that other programs use HOME to find
+# configuration files and this may lead to privilege escalation!
+Defaults env_keep += "DISPLAY HOME"
+
+# User alias specification
+User_Alias FULLTIMERS = millert, mikef, dowdy
+User_Alias PARTTIMERS = bostley, jwfox, crawl
+User_Alias WEBMASTERS = will, wendy, wim
+
+# Runas alias specification
+Runas_Alias OP = root, operator
+Runas_Alias DB = oracle, sybase
+Runas_Alias ADMINGRP = adm, oper
+
+# Host alias specification
+Host_Alias SPARC = bigtime, eclipse, moet, anchor :\e
+ SGI = grolsch, dandelion, black :\e
+ ALPHA = widget, thalamus, foobar :\e
+ HPPA = boa, nag, python
+Host_Alias CUNETS = 128.138.0.0/255.255.0.0
+Host_Alias CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0
+Host_Alias SERVERS = master, mail, www, ns
+Host_Alias CDROM = orion, perseus, hercules
+
+# Cmnd alias specification
+Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\e
+ /usr/sbin/restore, /usr/sbin/rrestore,\e
+ sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \e
+ /home/operator/bin/start_backups
+Cmnd_Alias KILL = /usr/bin/kill
+Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
+Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown
+Cmnd_Alias HALT = /usr/sbin/halt
+Cmnd_Alias REBOOT = /usr/sbin/reboot
+Cmnd_Alias SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh,\e
+ /usr/local/bin/tcsh, /usr/bin/rsh,\e
+ /usr/local/bin/zsh
+Cmnd_Alias SU = /usr/bin/su
+Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+.RE
+.fi
+.PP
+Here we override some of the compiled in default values.
+We want
+\fBsudo\fR
+to log via
+syslog(3)
+using the
+\fIauth\fR
+facility in all cases.
+We don't want to subject the full time staff to the
+\fBsudo\fR
+lecture, user
+\fBmillert\fR
+need not give a password, and we don't want to reset the
+\fRLOGNAME\fR
+or
+\fRUSER\fR
+environment variables when running commands as root.
+Additionally, on the machines in the
+\fISERVERS\fR
+\fRHost_Alias\fR,
+we keep an additional local log file and make sure we log the year
+in each log line since the log entries will be kept around for several years.
+Lastly, we disable shell escapes for the commands in the PAGERS
+\fRCmnd_Alias\fR
+(\fI/usr/bin/more\fR,
+\fI/usr/bin/pg\fR
+and
+\fI/usr/bin/less\fR)
+\&.
+Note that this will not effectively constrain users with
+\fBsudo\fR
+\fBALL\fR
+privileges.
+.nf
+.sp
+.RS 0n
+# Override built-in defaults
+Defaults syslog=auth
+Defaults>root !set_logname
+Defaults:FULLTIMERS !lecture
+Defaults:millert !authenticate
+Defaults@SERVERS log_year, logfile=/var/log/sudo.log
+Defaults!PAGERS noexec
+.RE
+.fi
+.PP
+The
+\fIUser specification\fR
+is the part that actually determines who may run what.
+.nf
+.sp
+.RS 0n
+root ALL = (ALL) ALL
+%wheel ALL = (ALL) ALL
+.RE
+.fi
+.PP
+We let
+\fBroot\fR
+and any user in group
+\fBwheel\fR
+run any command on any host as any user.
+.nf
+.sp
+.RS 0n
+FULLTIMERS ALL = NOPASSWD: ALL
+.RE
+.fi
+.PP
+Full time sysadmins
+(\fBmillert\fR,
+\fBmikef\fR,
+and
+\fBdowdy\fR)
+may run any command on any host without authenticating themselves.
+.nf
+.sp
+.RS 0n
+PARTTIMERS ALL = ALL
+.RE
+.fi
+.PP
+Part time sysadmins
+\fBbostley\fR,
+\fBjwfox\fR,
+and
+\fBcrawl\fR)
+may run any command on any host but they must authenticate themselves
+first (since the entry lacks the
+\fRNOPASSWD\fR
+tag).
+.nf
+.sp
+.RS 0n
+jack CSNETS = ALL
+.RE
+.fi
+.PP
+The user
+\fBjack\fR
+may run any command on the machines in the
+\fICSNETS\fR
+alias (the networks
+\fR128.138.243.0\fR,
+\fR128.138.204.0\fR,
+and
+\fR128.138.242.0\fR).
+Of those networks, only
+\fR128.138.204.0\fR
+has an explicit netmask (in CIDR notation) indicating it is a class C network.
+For the other networks in
+\fICSNETS\fR,
+the local machine's netmask will be used during matching.
+.nf
+.sp
+.RS 0n
+lisa CUNETS = ALL
+.RE
+.fi
+.PP
+The user
+\fBlisa\fR
+may run any command on any host in the
+\fICUNETS\fR
+alias (the class B network
+\fR128.138.0.0\fR).
+.nf
+.sp
+.RS 0n
+operator ALL = DUMPS, KILL, SHUTDOWN, HALT, REBOOT, PRINTING,\e
+ sudoedit /etc/printcap, /usr/oper/bin/
+.RE
+.fi
+.PP
+The
+\fBoperator\fR
+user may run commands limited to simple maintenance.
+Here, those are commands related to backups, killing processes, the
+printing system, shutting down the system, and any commands in the
+directory
+\fI/usr/oper/bin/\fR.
+Note that one command in the
+\fRDUMPS\fR
+Cmnd_Alias includes a sha224 digest,
+\fI/home/operator/bin/start_backups\fR.
+This is because the directory containing the script is writable by the
+operator user.
+If the script is modified (resulting in a digest mismatch) it will no longer
+be possible to run it via
+\fBsudo\fR.
+.nf
+.sp
+.RS 0n
+joe ALL = /usr/bin/su operator
+.RE
+.fi
+.PP
+The user
+\fBjoe\fR
+may only
+su(1)
+to operator.
+.nf
+.sp
+.RS 0n
+pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd *root*
+
+%opers ALL = (: ADMINGRP) /usr/sbin/
+.RE
+.fi
+.PP
+Users in the
+\fBopers\fR
+group may run commands in
+\fI/usr/sbin/\fR
+as themselves
+with any group in the
+\fIADMINGRP\fR
+\fRRunas_Alias\fR
+(the
+\fBadm\fR
+and
+\fBoper\fR
+groups).
+.PP
+The user
+\fBpete\fR
+is allowed to change anyone's password except for
+root on the
+\fIHPPA\fR
+machines.
+Because command line arguments are matched as a single,
+concatenated string, the
+\(oq*\(cq
+wildcard will match
+\fImultiple\fR
+words.
+This example assumes that
+passwd(1)
+does not take multiple user names on the command line.
+Note that on GNU systems, options to
+passwd(1)
+may be specified after the user argument.
+As a result, this rule will also allow:
+.nf
+.sp
+.RS 4n
+passwd username --expire
+.RE
+.fi
+.PP
+which may not be desirable.
+.nf
+.sp
+.RS 0n
+bob SPARC = (OP) ALL : SGI = (OP) ALL
+.RE
+.fi
+.PP
+The user
+\fBbob\fR
+may run anything on the
+\fISPARC\fR
+and
+\fISGI\fR
+machines as any user listed in the
+\fIOP\fR
+\fRRunas_Alias\fR
+(\fBroot\fR
+and
+\fBoperator\fR.)
+.nf
+.sp
+.RS 0n
+jim +biglab = ALL
+.RE
+.fi
+.PP
+The user
+\fBjim\fR
+may run any command on machines in the
+\fIbiglab\fR
+netgroup.
+\fBsudo\fR
+knows that
+\(lqbiglab\(rq
+is a netgroup due to the
+\(oq+\(cq
+prefix.
+.nf
+.sp
+.RS 0n
++secretaries ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser
+.RE
+.fi
+.PP
+Users in the
+\fBsecretaries\fR
+netgroup need to help manage the printers as well as add and remove users,
+so they are allowed to run those commands on all machines.
+.nf
+.sp
+.RS 0n
+fred ALL = (DB) NOPASSWD: ALL
+.RE
+.fi
+.PP
+The user
+\fBfred\fR
+can run commands as any user in the
+\fIDB\fR
+\fRRunas_Alias\fR
+(\fBoracle\fR
+or
+\fBsybase\fR)
+without giving a password.
+.nf
+.sp
+.RS 0n
+john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
+.RE
+.fi
+.PP
+On the
+\fIALPHA\fR
+machines, user
+\fBjohn\fR
+may su to anyone except root but he is not allowed to specify any options
+to the
+su(1)
+command.
+.nf
+.sp
+.RS 0n
+jen ALL, !SERVERS = ALL
+.RE
+.fi
+.PP
+The user
+\fBjen\fR
+may run any command on any machine except for those in the
+\fISERVERS\fR
+\fRHost_Alias\fR
+(master, mail, www and ns).
+.nf
+.sp
+.RS 0n
+jill SERVERS = /usr/bin/, !SU, !SHELLS
+.RE
+.fi
+.PP
+For any machine in the
+\fISERVERS\fR
+\fRHost_Alias\fR,
+\fBjill\fR
+may run
+any commands in the directory
+\fI/usr/bin/\fR
+except for those commands
+belonging to the
+\fISU\fR
+and
+\fISHELLS\fR
+\fRCmnd_Aliases\fR.
+While not specifically mentioned in the rule, the commands in the
+\fIPAGERS\fR
+\fRCmnd_Alias\fR
+all reside in
+\fI/usr/bin\fR
+and have the
+\fInoexec\fR
+option set.
+.nf
+.sp
+.RS 0n
+steve CSNETS = (operator) /usr/local/op_commands/
+.RE
+.fi
+.PP
+The user
+\fBsteve\fR
+may run any command in the directory /usr/local/op_commands/
+but only as user operator.
+.nf
+.sp
+.RS 0n
+matt valkyrie = KILL
+.RE
+.fi
+.PP
+On his personal workstation, valkyrie,
+\fBmatt\fR
+needs to be able to kill hung processes.
+.nf
+.sp
+.RS 0n
+WEBMASTERS www = (www) ALL, (root) /usr/bin/su www
+.RE
+.fi
+.PP
+On the host www, any user in the
+\fIWEBMASTERS\fR
+\fRUser_Alias\fR
+(will, wendy, and wim), may run any command as user www (which owns the
+web pages) or simply
+su(1)
+to www.
+.nf
+.sp
+.RS 0n
+ALL CDROM = NOPASSWD: /sbin/umount /CDROM,\e
+ /sbin/mount -o nosuid\e,nodev /dev/cd0a /CDROM
+.RE
+.fi
+.PP
+Any user may mount or unmount a CD-ROM on the machines in the CDROM
+\fRHost_Alias\fR
+(orion, perseus, hercules) without entering a password.
+This is a bit tedious for users to type, so it is a prime candidate
+for encapsulating in a shell script.
+.SH "SECURITY NOTES"
+.SS "Limitations of the \(oq!\&\(cq operator"
+It is generally not effective to
+\(lqsubtract\(rq
+commands from
+\fBALL\fR
+using the
+\(oq!\&\(cq
+operator.
+A user can trivially circumvent this by copying the desired command
+to a different name and then executing that.
+For example:
+.nf
+.sp
+.RS 0n
+bill ALL = ALL, !SU, !SHELLS
+.RE
+.fi
+.PP
+Doesn't really prevent
+\fBbill\fR
+from running the commands listed in
+\fISU\fR
+or
+\fISHELLS\fR
+since he can simply copy those commands to a different name, or use
+a shell escape from an editor or other program.
+Therefore, these kind of restrictions should be considered
+advisory at best (and reinforced by policy).
+.PP
+In general, if a user has sudo
+\fBALL\fR
+there is nothing to prevent them from creating their own program that gives
+them a root shell (or making their own copy of a shell) regardless of any
+\(oq!\&\(cq
+elements in the user specification.
+.SS "Security implications of \fIfast_glob\fR"
+If the
+\fIfast_glob\fR
+option is in use, it is not possible to reliably negate commands where the
+path name includes globbing (aka wildcard) characters.
+This is because the C library's
+fnmatch(3)
+function cannot resolve relative paths.
+While this is typically only an inconvenience for rules that grant privileges,
+it can result in a security issue for rules that subtract or revoke privileges.
+.PP
+For example, given the following
+\fIsudoers\fR
+file entry:
+.nf
+.sp
+.RS 0n
+john ALL = /usr/bin/passwd [a-zA-Z0-9]*, /usr/bin/chsh [a-zA-Z0-9]*,\e
+ /usr/bin/chfn [a-zA-Z0-9]*, !/usr/bin/* root
+.RE
+.fi
+.PP
+User
+\fBjohn\fR
+can still run
+\fR/usr/bin/passwd root\fR
+if
+\fIfast_glob\fR
+is enabled by changing to
+\fI/usr/bin\fR
+and running
+\fR./passwd root\fR
+instead.
+.SS "Preventing shell escapes"
+Once
+\fBsudo\fR
+executes a program, that program is free to do whatever
+it pleases, including run other programs.
+This can be a security issue since it is not uncommon for a program to
+allow shell escapes, which lets a user bypass
+\fBsudo\fR's
+access control and logging.
+Common programs that permit shell escapes include shells (obviously),
+editors, paginators, mail and terminal programs.
+.PP
+There are two basic approaches to this problem:
+.TP 10n
+restrict
+Avoid giving users access to commands that allow the user to run
+arbitrary commands.
+Many editors have a restricted mode where shell
+escapes are disabled, though
+\fBsudoedit\fR
+is a better solution to
+running editors via
+\fBsudo\fR.
+Due to the large number of programs that
+offer shell escapes, restricting users to the set of programs that
+do not is often unworkable.
+.TP 10n
+noexec
+Many systems that support shared libraries have the ability to
+override default library functions by pointing an environment
+variable (usually
+\fRLD_PRELOAD\fR)
+to an alternate shared library.
+On such systems,
+\fBsudo\fR's
+\fInoexec\fR
+functionality can be used to prevent a program run by
+\fBsudo\fR
+from executing any other programs.
+Note, however, that this applies only to native dynamically-linked
+executables.
+Statically-linked executables and foreign executables
+running under binary emulation are not affected.
+.sp
+The
+\fInoexec\fR
+feature is known to work on SunOS, Solaris, *BSD,
+Linux, IRIX, Tru64 UNIX, macOS, HP-UX 11.x and AIX 5.3 and above.
+It should be supported on most operating systems that support the
+\fRLD_PRELOAD\fR
+environment variable.
+Check your operating system's manual pages for the dynamic linker
+(usually ld.so, ld.so.1, dyld, dld.sl, rld, or loader) to see if
+\fRLD_PRELOAD\fR
+is supported.
+.sp
+On Solaris 10 and higher,
+\fInoexec\fR
+uses Solaris privileges instead of the
+\fRLD_PRELOAD\fR
+environment variable.
+.sp
+To enable
+\fInoexec\fR
+for a command, use the
+\fRNOEXEC\fR
+tag as documented
+in the User Specification section above.
+Here is that example again:
+.nf
+.sp
+.RS 10n
+aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi
+.RE
+.fi
+.RS 10n
+.sp
+This allows user
+\fBaaron\fR
+to run
+\fI/usr/bin/more\fR
+and
+\fI/usr/bin/vi\fR
+with
+\fInoexec\fR
+enabled.
+This will prevent those two commands from
+executing other commands (such as a shell).
+If you are unsure whether or not your system is capable of supporting
+\fInoexec\fR
+you can always just try it out and check whether shell escapes work when
+\fInoexec\fR
+is enabled.
+.RE
+.PP
+Note that restricting shell escapes is not a panacea.
+Programs running as root are still capable of many potentially hazardous
+operations (such as changing or overwriting files) that could lead
+to unintended privilege escalation.
+In the specific case of an editor, a safer approach is to give the
+user permission to run
+\fBsudoedit\fR
+(see below).
+.SS "Secure editing"
+The
+\fBsudoers\fR
+plugin includes
+\fBsudoedit\fR
+support which allows users to securely edit files with the editor
+of their choice.
+As
+\fBsudoedit\fR
+is a built-in command, it must be specified in the
+\fIsudoers\fR
+file without a leading path.
+However, it may take command line arguments just as a normal command does.
+Wildcards used in
+\fIsudoedit\fR
+command line arguments are expected to be path names, so a forward slash
+(\(oq/\(cq)
+will not be matched by a wildcard.
+.PP
+Unlike other
+\fBsudo\fR
+commands, the editor is run with the permissions of the invoking
+user and with the environment unmodified.
+More information may be found in the description of the
+\fB\-e\fR
+option in
+sudo(@mansectsu@).
+.PP
+For example, to allow user operator to edit the
+\(lqmessage of the day\(rq
+file:
+.nf
+.sp
+.RS 6n
+operator sudoedit /etc/motd
+.RE
+.fi
+.PP
+The operator user then runs
+\fBsudoedit\fR
+as follows:
+.nf
+.sp
+.RS 6n
+$ sudoedit /etc/motd
+.RE
+.fi
+.PP
+The editor will run as the operator user, not root, on a temporary copy of
+\fI/etc/motd\fR.
+After the file has been edited,
+\fI/etc/motd\fR
+will be updated with the contents of the temporary copy.
+.PP
+Users should
+\fInever\fR
+be granted
+\fBsudoedit\fR
+permission to edit a file that resides in a directory the user
+has write access to, either directly or via a wildcard.
+If the user has write access to the directory it is possible to
+replace the legitimate file with a link to another file,
+allowing the editing of arbitrary files.
+To prevent this, starting with version 1.8.16, symbolic links will
+not be followed in writable directories and
+\fBsudoedit\fR
+will refuse to edit a file located in a writable directory
+unless the
+\fIsudoedit_checkdir\fR
+option has been disabled or the invoking user is root.
+Additionally, in version 1.8.15 and higher,
+\fBsudoedit\fR
+will refuse to open a symbolic link unless either the
+\fIsudoedit_follow\fR
+option is enabled or the
+\fIsudoedit\fR
+command is prefixed with the
+\fRFOLLOW\fR
+tag in the
+\fIsudoers\fR
+file.
+.SS "Time stamp file checks"
+\fBsudoers\fR
+will check the ownership of its time stamp directory
+(\fI@rundir@/ts\fR
+by default)
+and ignore the directory's contents if it is not owned by root or
+if it is writable by a user other than root.
+Older versions of
+\fBsudo\fR
+stored time stamp files in
+\fI/tmp\fR;
+this is no longer recommended as it may be possible for a user
+to create the time stamp themselves on systems that allow
+unprivileged users to change the ownership of files they create.
+.PP
+While the time stamp directory
+\fIshould\fR
+be cleared at reboot time, not all systems contain a
+\fI/run\fR
+or
+\fI/var/run\fR
+directory.
+To avoid potential problems,
+\fBsudoers\fR
+will ignore time stamp files that date from before the machine booted
+on systems where the boot time is available.
+.PP
+Some systems with graphical desktop environments allow unprivileged
+users to change the system clock.
+Since
+\fBsudoers\fR
+relies on the system clock for time stamp validation, it may be
+possible on such systems for a user to run
+\fBsudo\fR
+for longer than
+\fItimestamp_timeout\fR
+by setting the clock back.
+To combat this,
+\fBsudoers\fR
+uses a monotonic clock (which never moves backwards) for its time stamps
+if the system supports it.
+.PP
+\fBsudoers\fR
+will not honor time stamps set far in the future.
+Time stamps with a date greater than current_time + 2 *
+\fRTIMEOUT\fR
+will be ignored and
+\fBsudoers\fR
+will log and complain.
+.PP
+If the
+\fItimestamp_type\fR
+option is set to
+\(lqtty\(rq,
+the time stamp record includes the device number of the terminal
+the user authenticated with.
+This provides per-terminal granularity but time stamp records may still
+outlive the user's session.
+.PP
+Unless the
+\fItimestamp_type\fR
+option is set to
+\(lqglobal\(rq,
+the time stamp record also includes the session ID of the process
+that last authenticated.
+This prevents processes in different terminal sessions from using
+the same time stamp record.
+On systems where a process's start time can be queried,
+the start time of the session leader
+is recorded in the time stamp record.
+If no terminal is present or the
+\fItimestamp_type\fR
+option is set to
+\(lqppid\(rq,
+the start time of the parent process is used instead.
+In most cases this will prevent a time stamp record from being re-used
+without the user entering a password when logging out and back in again.
+.SH "DEBUGGING"
+Versions 1.8.4 and higher of the
+\fBsudoers\fR
+plugin support a flexible debugging framework that can help track
+down what the plugin is doing internally if there is a problem.
+This can be configured in the
+sudo.conf(@mansectform@)
+file.
+.PP
+The
+\fBsudoers\fR
+plugin uses the same debug flag format as the
+\fBsudo\fR
+front-end:
+\fIsubsystem\fR@\fIpriority\fR.
+.PP
+The priorities used by
+\fBsudoers\fR,
+in order of decreasing severity,
+are:
+\fIcrit\fR, \fIerr\fR, \fIwarn\fR, \fInotice\fR, \fIdiag\fR, \fIinfo\fR, \fItrace\fR
+and
+\fIdebug\fR.
+Each priority, when specified, also includes all priorities higher
+than it.
+For example, a priority of
+\fInotice\fR
+would include debug messages logged at
+\fInotice\fR
+and higher.
+.PP
+The following subsystems are used by the
+\fBsudoers\fR
+plugin:
+.TP 10n
+\fIalias\fR
+\fRUser_Alias\fR,
+\fRRunas_Alias\fR,
+\fRHost_Alias\fR
+and
+\fRCmnd_Alias\fR
+processing
+.TP 10n
+\fIall\fR
+matches every subsystem
+.TP 10n
+\fIaudit\fR
+BSM and Linux audit code
+.TP 10n
+\fIauth\fR
+user authentication
+.TP 10n
+\fIdefaults\fR
+\fIsudoers\fR
+file
+\fIDefaults\fR
+settings
+.TP 10n
+\fIenv\fR
+environment handling
+.TP 10n
+\fIldap\fR
+LDAP-based sudoers
+.TP 10n
+\fIlogging\fR
+logging support
+.TP 10n
+\fImatch\fR
+matching of users, groups, hosts and netgroups in the
+\fIsudoers\fR
+file
+.TP 10n
+\fInetif\fR
+network interface handling
+.TP 10n
+\fInss\fR
+network service switch handling in
+\fBsudoers\fR
+.TP 10n
+\fIparser\fR
+\fIsudoers\fR
+file parsing
+.TP 10n
+\fIperms\fR
+permission setting
+.TP 10n
+\fIplugin\fR
+The equivalent of
+\fImain\fR
+for the plugin.
+.TP 10n
+\fIpty\fR
+pseudo-tty related code
+.TP 10n
+\fIrbtree\fR
+redblack tree internals
+.TP 10n
+\fIsssd\fR
+SSSD-based sudoers
+.TP 10n
+\fIutil\fR
+utility functions
+.PD 0
+.PP
+For example:
+.nf
+.sp
+.RS 0n
+Debug sudo /var/log/sudo_debug match@info,nss@info
+.RE
+.fi
+.PD
+.PP
+For more information, see the
+sudo.conf(@mansectform@)
+manual.
+.SH "SEE ALSO"
+ssh(1),
+su(1),
+fnmatch(3),
+glob(3),
+mktemp(3),
+strftime(3),
+sudo.conf(@mansectform@),
+sudo_plugin(@mansectform@),
+sudoers.ldap(@mansectform@),
+sudoers_timestamp(@mansectform@),
+sudo(@mansectsu@),
+visudo(@mansectsu@)
+.SH "AUTHORS"
+Many people have worked on
+\fBsudo\fR
+over the years; this version consists of code written primarily by:
+.sp
+.RS 6n
+Todd C. Miller
+.RE
+.PP
+See the CONTRIBUTORS file in the
+\fBsudo\fR
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+\fBsudo\fR.
+.SH "CAVEATS"
+The
+\fIsudoers\fR
+file should
+\fBalways\fR
+be edited by the
+\fBvisudo\fR
+command which locks the file and does grammatical checking.
+It is
+imperative that the
+\fIsudoers\fR
+file be free of syntax errors since
+\fBsudo\fR
+will not run with a syntactically incorrect
+\fIsudoers\fR
+file.
+.PP
+When using netgroups of machines (as opposed to users), if you
+store fully qualified host name in the netgroup (as is usually the
+case), you either need to have the machine's host name be fully qualified
+as returned by the
+\fRhostname\fR
+command or use the
+\fIfqdn\fR
+option in
+\fIsudoers\fR.
+.SH "BUGS"
+If you feel you have found a bug in
+\fBsudo\fR,
+please submit a bug report at https://bugzilla.sudo.ws/
+.SH "SUPPORT"
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.SH "DISCLAIMER"
+\fBsudo\fR
+is provided
+\(lqAS IS\(rq
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+\fBsudo\fR
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/sudoers.man.in.sed b/doc/sudoers.man.in.sed
new file mode 100644
index 0000000..37df7af
--- /dev/null
+++ b/doc/sudoers.man.in.sed
@@ -0,0 +1,116 @@
+s/^\(.TH .*\)/.nr SL @SEMAN@\
+.nr BA @BAMAN@\
+.nr LC @LCMAN@\
+.nr PS @PSMAN@\
+\1/
+
+/^On$/N
+/^On\nBSD$/,/^.*\.$/ {
+ /^On\nBSD$/i\
+.if \\n(LC \\{\\
+ /\.$/a\
+.\\}
+}
+
+/^\.SS "SELinux_Spec"$/,/^\.SS/ {
+ /^\.SS / {
+ /^\.SS "SELinux_Spec"$/i\
+.if \\n(SL \\{\\
+ /^\.SS "SELinux_Spec"$/!i\
+.\\}
+ }
+}
+
+/^\.SS "Solaris_Priv_Spec"$/,/^\.SS/ {
+ /^\.SS / {
+ /^\.SS "Solaris_Priv_Spec"$/i\
+.if \\n(PS \\{\\
+ /^\.SS "Solaris_Priv_Spec"$/!i\
+.\\}
+ }
+}
+
+/^Option_Spec ::= / {
+ s/^.*$/.ie \\n(SL \\{\\\
+.ie \\n(PS Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Date_Spec | Timeout_Spec)\
+.el Option_Spec ::= (SELinux_Spec | Date_Spec | Timeout_Spec)\
+.\\}\
+.el \\{\\\
+.ie \\n(PS Option_Spec ::= (Solaris_Priv_Spec | Date_Spec | Timeout_Spec)\
+.el Option_Spec ::= (Date_Spec | Timeout_Spec)\
+.\\}/
+}
+
+/^SELinux_Spec ::=/ {
+ i\
+.if \\n(SL \\{\\
+ N
+ a\
+.\\}
+}
+
+/^Solaris_Priv_Spec ::=/ {
+ i\
+.if \\n(PS \\{\\
+ N
+ a\
+.\\}
+}
+
+/^SELinux roles.*types,/ {
+ i\
+.if \\n(SL \\{\\
+ a\
+.\\}
+}
+
+/^Solaris privileges sets,/ {
+ i\
+.if \\n(PS \\{\\
+ a\
+.\\}
+}
+
+/^\.TP 18n$/ {
+ N
+ /^\.TP 18n\nuse_loginclass$/,/^\.TP 18n/ {
+ /^\.TP 18n/ {
+ /^\.TP 18n\nuse_loginclass$/i\
+.if \\n(BA \\{\\
+ /^\.TP 18n\nuse_loginclass$/!i\
+.\\}
+ }
+ }
+ /^\.TP 18n\nlimitprivs$/,/^\.TP 18n/ {
+ /^\.TP 18n/ {
+ /^\.TP 18n\nlimitprivs$/i\
+.if \\n(PS \\{\\
+ /^\.TP 18n\nlimitprivs$/!i\
+.\\}
+ }
+ }
+ /^\.TP 18n\nprivs$/,/^\.TP 18n/ {
+ /^\.TP 18n/ {
+ /^\.TP 18n\nprivs$/i\
+.if \\n(PS \\{\\
+ /^\.TP 18n\nprivs$/!i\
+.\\}
+ }
+ }
+ /^\.TP 18n\nrole$/,/^\.TP 18n/ {
+ /^\.TP 18n/ {
+ /^\.TP 18n\nrole$/i\
+.if \\n(SL \\{\\
+ /^\.TP 18n\nrole$/!i\
+.\\}
+ }
+ }
+ /^\.TP 18n\ntype$/,/^\.TP 18n/ {
+ /^\.TP 18n/ {
+ /^\.TP 18n\ntype$/i\
+.if \\n(SL \\{\\
+ /^\.TP 18n\ntype$/!i\
+.\\}
+ }
+ }
+}
diff --git a/doc/sudoers.mdoc.in b/doc/sudoers.mdoc.in
new file mode 100644
index 0000000..2053b5d
--- /dev/null
+++ b/doc/sudoers.mdoc.in
@@ -0,0 +1,5398 @@
+.\"
+.\" Copyright (c) 1994-1996, 1998-2005, 2007-2018
+.\" Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Sponsored in part by the Defense Advanced Research Projects
+.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
+.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
+.\"
+.nr SL @SEMAN@
+.nr BA @BAMAN@
+.nr LC @LCMAN@
+.nr PS @PSMAN@
+.Dd December 20, 2018
+.Dt SUDOERS @mansectform@
+.Os Sudo @PACKAGE_VERSION@
+.Sh NAME
+.Nm sudoers
+.Nd default sudo security policy plugin
+.Sh DESCRIPTION
+The
+.Nm
+policy plugin determines a user's
+.Nm sudo
+privileges.
+It is the default
+.Nm sudo
+policy plugin.
+The policy is driven by
+the
+.Pa @sysconfdir@/sudoers
+file or, optionally in LDAP.
+The policy format is described in detail in the
+.Sx SUDOERS FILE FORMAT
+section.
+For information on storing
+.Nm sudoers
+policy information
+in LDAP, please see
+.Xr sudoers.ldap @mansectform@ .
+.Ss Configuring sudo.conf for sudoers
+.Nm sudo
+consults the
+.Xr sudo.conf @mansectform@
+file to determine which policy and I/O logging plugins to load.
+If no
+.Xr sudo.conf @mansectform@
+file is present, or if it contains no
+.Li Plugin
+lines,
+.Nm
+will be used for policy decisions and I/O logging.
+To explicitly configure
+.Xr sudo.conf @mansectform@
+to use the
+.Nm
+plugin, the following configuration can be used.
+.Bd -literal -offset indent
+Plugin sudoers_policy sudoers.so
+Plugin sudoers_io sudoers.so
+.Ed
+.Pp
+Starting with
+.Nm sudo
+1.8.5, it is possible to specify optional arguments to the
+.Nm
+plugin in the
+.Xr sudo.conf @mansectform@
+file.
+These arguments, if present, should be listed after the path to the plugin
+(i.e., after
+.Pa sudoers.so ) .
+Multiple arguments may be specified, separated by white space.
+For example:
+.Bd -literal -offset indent
+Plugin sudoers_policy sudoers.so sudoers_mode=0400
+.Ed
+.Pp
+The following plugin arguments are supported:
+.Bl -tag -width 8n
+.It ldap_conf=pathname
+The
+.Em ldap_conf
+argument can be used to override the default path to the
+.Pa ldap.conf
+file.
+.It ldap_secret=pathname
+The
+.Em ldap_secret
+argument can be used to override the default path to the
+.Pa ldap.secret
+file.
+.It sudoers_file=pathname
+The
+.Em sudoers_file
+argument can be used to override the default path to the
+.Em sudoers
+file.
+.It sudoers_uid=uid
+The
+.Em sudoers_uid
+argument can be used to override the default owner of the sudoers file.
+It should be specified as a numeric user ID.
+.It sudoers_gid=gid
+The
+.Em sudoers_gid
+argument can be used to override the default group of the sudoers file.
+It must be specified as a numeric group ID (not a group name).
+.It sudoers_mode=mode
+The
+.Em sudoers_mode
+argument can be used to override the default file mode for the sudoers file.
+It should be specified as an octal value.
+.El
+.Pp
+For more information on configuring
+.Xr sudo.conf @mansectform@ ,
+please refer to its manual.
+.Ss User Authentication
+The
+.Nm sudoers
+security policy requires that most users authenticate
+themselves before they can use
+.Nm sudo .
+A password is not required
+if the invoking user is root, if the target user is the same as the
+invoking user, or if the policy has disabled authentication for the
+user or command.
+Unlike
+.Xr su 1 ,
+when
+.Nm sudoers
+requires
+authentication, it validates the invoking user's credentials, not
+the target user's (or root's) credentials.
+This can be changed via
+the
+.Em rootpw ,
+.Em targetpw
+and
+.Em runaspw
+flags, described later.
+.Pp
+If a user who is not listed in the policy tries to run a command
+via
+.Nm sudo ,
+mail is sent to the proper authorities.
+The address
+used for such mail is configurable via the
+.Em mailto
+Defaults entry
+(described later) and defaults to
+.Li @mailto@ .
+.Pp
+Note that no mail will be sent if an unauthorized user tries to run
+.Nm sudo
+with the
+.Fl l
+or
+.Fl v
+option unless there is an authentication error and
+either the
+.Em mail_always
+or
+.Em mail_badpass
+flags are enabled.
+This allows users to
+determine for themselves whether or not they are allowed to use
+.Nm sudo .
+All attempts to run
+.Nm sudo
+(successful or not)
+will be logged, regardless of whether or not mail is sent.
+.Pp
+If
+.Nm sudo
+is run by root and the
+.Ev SUDO_USER
+environment variable
+is set, the
+.Nm sudoers
+policy will use this value to determine who
+the actual user is.
+This can be used by a user to log commands
+through sudo even when a root shell has been invoked.
+It also
+allows the
+.Fl e
+option to remain useful even when invoked via a
+sudo-run script or program.
+Note, however, that the
+.Em sudoers
+file lookup is still done for root, not the user specified by
+.Ev SUDO_USER .
+.Pp
+.Nm sudoers
+uses per-user time stamp files for credential caching.
+Once a user has been authenticated, a record is written
+containing the user ID that was used to authenticate, the
+terminal session ID, the start time of the session leader
+(or parent process) and a time stamp
+(using a monotonic clock if one is available).
+The user may then use
+.Nm sudo
+without a password for a short period of time
+.Po
+.Li @timeout@
+minutes unless overridden by the
+.Em timestamp_timeout
+option
+.Pc .
+By default,
+.Nm sudoers
+uses a separate record for each terminal, which means that
+a user's login sessions are authenticated separately.
+The
+.Em timestamp_type
+option can be used to select the type of time stamp record
+.Nm sudoers
+will use.
+.Ss Logging
+.Nm sudoers
+can log both successful and unsuccessful attempts (as well
+as errors) to
+.Xr syslog 3 ,
+a log file, or both.
+By default,
+.Nm sudoers
+will log via
+.Xr syslog 3
+but this is changeable via the
+.Em syslog
+and
+.Em logfile
+Defaults settings.
+See
+.Sx "LOG FORMAT"
+for a description of the log file format.
+.Pp
+.Nm sudoers
+is also capable of running a command in a pseudo-tty and logging all
+input and/or output.
+The standard input, standard output and standard error can be logged
+even when not associated with a terminal.
+I/O logging is not on by default but can be enabled using
+the
+.Em log_input
+and
+.Em log_output
+options as well as the
+.Li LOG_INPUT
+and
+.Li LOG_OUTPUT
+command tags.
+See
+.Sx "I/O LOG FILES"
+for details on how I/O log files are stored.
+.Ss Command environment
+Since environment variables can influence program behavior,
+.Nm sudoers
+provides a means to restrict which variables from the user's
+environment are inherited by the command to be run.
+There are two
+distinct ways
+.Nm sudoers
+can deal with environment variables.
+.Pp
+By default, the
+.Em env_reset
+option is enabled.
+This causes commands
+to be executed with a new, minimal environment.
+On AIX (and Linux
+systems without PAM), the environment is initialized with the
+contents of the
+.Pa /etc/environment
+file.
+.if \n(LC \{\
+On
+.Bx
+systems, if the
+.Em use_loginclass
+option is enabled, the environment is initialized
+based on the
+.Em path
+and
+.Em setenv
+settings in
+.Pa /etc/login.conf .
+.\}
+The new environment contains the
+.Ev TERM ,
+.Ev PATH ,
+.Ev HOME ,
+.Ev MAIL ,
+.Ev SHELL ,
+.Ev LOGNAME ,
+.Ev USER
+and
+.Ev SUDO_*
+variables
+in addition to variables from the invoking process permitted by the
+.Em env_check
+and
+.Em env_keep
+options.
+This is effectively a whitelist
+for environment variables.
+The environment variables
+.Ev LOGNAME
+and
+.Ev USER
+are treated specially.
+If one of them is preserved (or removed) from user's environment, the other
+will be as well.
+If
+.Ev LOGNAME
+and
+.Ev USER
+are to be preserved but only one of them is present in the user's environment,
+the other will be set to the same value.
+This avoids an inconsistent environment where one of the variables
+describing the user name is set to the invoking user and one is
+set to the target user.
+.Li ()
+are removed unless both the name and value parts are matched by
+.Em env_keep
+or
+.Em env_check ,
+as they may be interpreted as functions by the
+.Sy bash
+shell.
+Prior to version 1.8.11, such variables were always removed.
+.Pp
+If, however, the
+.Em env_reset
+option is disabled, any variables not
+explicitly denied by the
+.Em env_check
+and
+.Em env_delete
+options are
+inherited from the invoking process.
+In this case,
+.Em env_check
+and
+.Em env_delete
+behave like a blacklist.
+Prior to version 1.8.21, environment variables with a value beginning with
+.Li ()
+were always removed.
+Beginning with version 1.8.21, a pattern in
+.Em env_delete
+is used to match
+.Sy bash
+shell functions instead.
+Since it is not possible
+to blacklist all potentially dangerous environment variables, use
+of the default
+.Em env_reset
+behavior is encouraged.
+.Pp
+Environment variables specified by
+.Em env_check ,
+.Em env_delete ,
+or
+.Em env_keep
+may include one or more
+.Ql *
+characters which will match zero or more characters.
+No other wildcard characters are supported.
+.Pp
+By default, environment variables are matched by name.
+However, if the pattern includes an equal sign
+.Pq Ql =\& ,
+both the variables name and value must match.
+For example, a
+.Sy bash
+shell function could be matched as follows:
+.Bd -literal -offset 4n
+env_keep += "BASH_FUNC_my_func%%=()*"
+.Ed
+.Pp
+Without the
+.Dq Li =()*
+suffix, this would not match, as
+.Sy bash
+shell functions are not preserved by default.
+.Pp
+The complete list of environment variables that
+.Nm sudo
+allows or denies is contained in the output of
+.Dq Li sudo -V
+when run as root.
+Please note that this list varies based on the operating system
+.Nm sudo
+is running on.
+.Pp
+On systems that support PAM where the
+.Sy pam_env
+module is enabled for
+.Nm sudo ,
+variables in the PAM environment may be merged in to the environment.
+If a variable in the PAM environment is already present in the
+user's environment, the value will only be overridden if the variable
+was not preserved by
+.Nm .
+When
+.Em env_reset
+is enabled, variables preserved from the invoking user's environment
+by the
+.Em env_keep
+list take precedence over those in the PAM environment.
+When
+.Em env_reset
+is disabled, variables present the invoking user's environment
+take precedence over those in the PAM environment unless they
+match a pattern in the
+.Em env_delete
+list.
+.Pp
+Note that the dynamic linker on most operating systems will remove
+variables that can control dynamic linking from the environment of
+setuid executables, including
+.Nm sudo .
+Depending on the operating
+system this may include
+.Ev _RLD* ,
+.Ev DYLD_* ,
+.Ev LD_* ,
+.Ev LDR_* ,
+.Ev LIBPATH ,
+.Ev SHLIB_PATH ,
+and others.
+These type of variables are
+removed from the environment before
+.Nm sudo
+even begins execution
+and, as such, it is not possible for
+.Nm sudo
+to preserve them.
+.Pp
+As a special case, if
+.Nm sudo Ns 's
+.Fl i
+option (initial login) is
+specified,
+.Nm sudoers
+will initialize the environment regardless
+of the value of
+.Em env_reset .
+The
+.Ev DISPLAY ,
+.Ev PATH
+and
+.Ev TERM
+variables remain unchanged;
+.Ev HOME ,
+.Ev MAIL ,
+.Ev SHELL ,
+.Ev USER ,
+and
+.Ev LOGNAME
+are set based on the target user.
+On AIX (and Linux
+systems without PAM), the contents of
+.Pa /etc/environment
+are also
+included.
+.if \n(LC \{\
+On
+.Bx
+systems, if the
+.Em use_loginclass
+flag is
+enabled, the
+.Em path
+and
+.Em setenv
+variables in
+.Pa /etc/login.conf
+are also applied.
+.\}
+All other environment variables are removed unless permitted by
+.Em env_keep
+or
+.Em env_check ,
+described above.
+.Pp
+Finally, the
+.Em restricted_env_file
+and
+.Em env_file
+files are applied, if present.
+The variables in
+.Em restricted_env_file
+are applied first and are subject to the same restrictions as the
+invoking user's environment, as detailed above.
+The variables in
+.Em env_file
+are applied last and are not subject to these restrictions.
+In both cases, variables present in the files will only be set to
+their specified values if they would not conflict with an existing
+environment variable.
+.Sh SUDOERS FILE FORMAT
+The
+.Em sudoers
+file is composed of two types of entries: aliases
+(basically variables) and user specifications (which specify who
+may run what).
+.Pp
+When multiple entries match for a user, they are applied in order.
+Where there are multiple matches, the last match is used (which is
+not necessarily the most specific match).
+.Pp
+The
+.Em sudoers
+file grammar will be described below in Extended Backus-Naur
+Form (EBNF).
+Don't despair if you are unfamiliar with EBNF; it is fairly simple,
+and the definitions below are annotated.
+.Ss Quick guide to EBNF
+EBNF is a concise and exact way of describing the grammar of a language.
+Each EBNF definition is made up of
+.Em production rules .
+E.g.,
+.Pp
+.Li symbol ::= definition | alternate1 | alternate2 ...
+.Pp
+Each
+.Em production rule
+references others and thus makes up a
+grammar for the language.
+EBNF also contains the following
+operators, which many readers will recognize from regular
+expressions.
+Do not, however, confuse them with
+.Dq wildcard
+characters, which have different meanings.
+.Bl -tag -width 4n
+.It Li \&?
+Means that the preceding symbol (or group of symbols) is optional.
+That is, it may appear once or not at all.
+.It Li *
+Means that the preceding symbol (or group of symbols) may appear
+zero or more times.
+.It Li +
+Means that the preceding symbol (or group of symbols) may appear
+one or more times.
+.El
+.Pp
+Parentheses may be used to group symbols together.
+For clarity,
+we will use single quotes
+.Pq ''
+to designate what is a verbatim character string (as opposed to a symbol name).
+.Ss Aliases
+There are four kinds of aliases:
+.Li User_Alias ,
+.Li Runas_Alias ,
+.Li Host_Alias
+and
+.Li Cmnd_Alias .
+.Bd -literal
+Alias ::= 'User_Alias' User_Alias_Spec (':' User_Alias_Spec)* |
+ 'Runas_Alias' Runas_Alias_Spec (':' Runas_Alias_Spec)* |
+ 'Host_Alias' Host_Alias_Spec (':' Host_Alias_Spec)* |
+ 'Cmnd_Alias' Cmnd_Alias_Spec (':' Cmnd_Alias_Spec)*
+
+User_Alias ::= NAME
+
+User_Alias_Spec ::= User_Alias '=' User_List
+
+Runas_Alias ::= NAME
+
+Runas_Alias_Spec ::= Runas_Alias '=' Runas_List
+
+Host_Alias ::= NAME
+
+Host_Alias_Spec ::= Host_Alias '=' Host_List
+
+Cmnd_Alias ::= NAME
+
+Cmnd_Alias_Spec ::= Cmnd_Alias '=' Cmnd_List
+
+NAME ::= [A-Z]([A-Z][0-9]_)*
+.Ed
+.Pp
+Each
+.Em alias
+definition is of the form
+.Bd -literal
+Alias_Type NAME = item1, item2, ...
+.Ed
+.Pp
+where
+.Em Alias_Type
+is one of
+.Li User_Alias ,
+.Li Runas_Alias ,
+.Li Host_Alias ,
+or
+.Li Cmnd_Alias .
+A
+.Li NAME
+is a string of uppercase letters, numbers,
+and underscore characters
+.Pq Ql _ .
+A
+.Li NAME
+.Sy must
+start with an
+uppercase letter.
+It is possible to put several alias definitions
+of the same type on a single line, joined by a colon
+.Pq Ql :\& .
+E.g.,
+.Bd -literal
+Alias_Type NAME = item1, item2, item3 : NAME = item4, item5
+.Ed
+.Pp
+It is a syntax error to redefine an existing
+.Em alias .
+It is possible to use the same name for
+.Em aliases
+of different types, but this is not recommended.
+.Pp
+The definitions of what constitutes a valid
+.Em alias
+member follow.
+.Bd -literal
+User_List ::= User |
+ User ',' User_List
+
+User ::= '!'* user name |
+ '!'* #uid |
+ '!'* %group |
+ '!'* %#gid |
+ '!'* +netgroup |
+ '!'* %:nonunix_group |
+ '!'* %:#nonunix_gid |
+ '!'* User_Alias
+.Ed
+.Pp
+A
+.Li User_List
+is made up of one or more user names, user IDs
+(prefixed with
+.Ql # ) ,
+system group names and IDs (prefixed with
+.Ql %
+and
+.Ql %#
+respectively), netgroups (prefixed with
+.Ql + ) ,
+non-Unix group names and IDs (prefixed with
+.Ql %:
+and
+.Ql %:#
+respectively) and
+.Li User_Alias Ns es.
+Each list item may be prefixed with zero or more
+.Ql \&!
+operators.
+An odd number of
+.Ql \&!
+operators negate the value of
+the item; an even number just cancel each other out.
+User netgroups are matched using the user and domain members only;
+the host member is not used when matching.
+.Pp
+A
+.Li user name ,
+.Li uid ,
+.Li group ,
+.Li gid ,
+.Li netgroup ,
+.Li nonunix_group
+or
+.Li nonunix_gid
+may be enclosed in double quotes to avoid the
+need for escaping special characters.
+Alternately, special characters
+may be specified in escaped hex mode, e.g., \ex20 for space.
+When
+using double quotes, any prefix characters must be included inside
+the quotes.
+.Pp
+The actual
+.Li nonunix_group
+and
+.Li nonunix_gid
+syntax depends on
+the underlying group provider plugin.
+For instance, the QAS AD plugin supports the following formats:
+.Bl -bullet -width 1n
+.It
+Group in the same domain: "%:Group Name"
+.It
+Group in any domain: "%:Group Name@FULLY.QUALIFIED.DOMAIN"
+.It
+Group SID: "%:S-1-2-34-5678901234-5678901234-5678901234-567"
+.El
+.Pp
+See
+.Sx "GROUP PROVIDER PLUGINS"
+for more information.
+.Pp
+Note that quotes around group names are optional.
+Unquoted strings must use a backslash
+.Pq Ql \e
+to escape spaces and special characters.
+See
+.Sx Other special characters and reserved words
+for a list of
+characters that need to be escaped.
+.Bd -literal
+Runas_List ::= Runas_Member |
+ Runas_Member ',' Runas_List
+
+Runas_Member ::= '!'* user name |
+ '!'* #uid |
+ '!'* %group |
+ '!'* %#gid |
+ '!'* %:nonunix_group |
+ '!'* %:#nonunix_gid |
+ '!'* +netgroup |
+ '!'* Runas_Alias
+.Ed
+.Pp
+A
+.Li Runas_List
+is similar to a
+.Li User_List
+except that instead
+of
+.Li User_Alias Ns es
+it can contain
+.Li Runas_Alias Ns es .
+Note that
+user names and groups are matched as strings.
+In other words, two
+users (groups) with the same uid (gid) are considered to be distinct.
+If you wish to match all user names with the same uid (e.g.,
+root and toor), you can use a uid instead (#0 in the example given).
+.Bd -literal
+Host_List ::= Host |
+ Host ',' Host_List
+
+Host ::= '!'* host name |
+ '!'* ip_addr |
+ '!'* network(/netmask)? |
+ '!'* +netgroup |
+ '!'* Host_Alias
+.Ed
+.Pp
+A
+.Li Host_List
+is made up of one or more host names, IP addresses,
+network numbers, netgroups (prefixed with
+.Ql + )
+and other aliases.
+Again, the value of an item may be negated with the
+.Ql \&!
+operator.
+Host netgroups are matched using the host (both qualified and unqualified)
+and domain members only; the user member is not used when matching.
+If you specify a network number without a netmask,
+.Nm sudo
+will query each of the local host's network interfaces and,
+if the network number corresponds to one of the hosts's network
+interfaces, will use the netmask of that interface.
+The netmask may be specified either in standard IP address notation
+(e.g., 255.255.255.0 or ffff:ffff:ffff:ffff::),
+or CIDR notation (number of bits, e.g., 24 or 64).
+A host name may include shell-style wildcards (see the
+.Sx Wildcards
+section below),
+but unless the
+.Li host name
+command on your machine returns the fully
+qualified host name, you'll need to use the
+.Em fqdn
+option for wildcards to be useful.
+Note that
+.Nm sudo
+only inspects actual network interfaces; this means that IP address
+127.0.0.1 (localhost) will never match.
+Also, the host name
+.Dq localhost
+will only match if that is the actual host name, which is usually
+only the case for non-networked systems.
+.Bd -literal
+digest ::= [A-Fa-f0-9]+ |
+ [[A-Za-z0-9\+/=]+
+
+Digest_Spec ::= "sha224" ':' digest |
+ "sha256" ':' digest |
+ "sha384" ':' digest |
+ "sha512" ':' digest
+
+Cmnd_List ::= Cmnd |
+ Cmnd ',' Cmnd_List
+
+command name ::= file name |
+ file name args |
+ file name '""'
+
+Cmnd ::= Digest_Spec? '!'* command name |
+ '!'* directory |
+ '!'* "sudoedit" |
+ '!'* Cmnd_Alias
+.Ed
+.Pp
+A
+.Li Cmnd_List
+is a list of one or more command names, directories, and other aliases.
+A command name is a fully qualified file name which may include
+shell-style wildcards (see the
+.Sx Wildcards
+section below).
+A simple file name allows the user to run the command with any
+arguments he/she wishes.
+However, you may also specify command line arguments (including
+wildcards).
+Alternately, you can specify
+.Li \&""
+to indicate that the command
+may only be run
+.Sy without
+command line arguments.
+A directory is a
+fully qualified path name ending in a
+.Ql / .
+When you specify a directory in a
+.Li Cmnd_List ,
+the user will be able to run any file within that directory
+(but not in any sub-directories therein).
+.Pp
+If a
+.Li Cmnd
+has associated command line arguments, then the arguments
+in the
+.Li Cmnd
+must match exactly those given by the user on the command line
+(or match the wildcards if there are any).
+Note that the following characters must be escaped with a
+.Ql \e
+if they are used in command arguments:
+.Ql ,\& ,
+.Ql :\& ,
+.Ql =\& ,
+.Ql \e .
+The built-in command
+.Dq Li sudoedit
+is used to permit a user to run
+.Nm sudo
+with the
+.Fl e
+option (or as
+.Nm sudoedit ) .
+It may take command line arguments just as a normal command does.
+Note that
+.Dq Li sudoedit
+is a command built into
+.Nm sudo
+itself and must be specified in the
+.Em sudoers
+file without a leading path.
+.Pp
+If a
+.Li command name
+is prefixed with a
+.Li Digest_Spec ,
+the command will only match successfully if it can be verified
+using the specified SHA-2 digest.
+The following digest formats are supported: sha224, sha256, sha384 and sha512.
+The string may be specified in either hex or base64 format
+(base64 is more compact).
+There are several utilities capable of generating SHA-2 digests in hex
+format such as openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum.
+.Pp
+For example, using openssl:
+.Bd -literal
+$ openssl dgst -sha224 /bin/ls
+SHA224(/bin/ls)= 118187da8364d490b4a7debbf483004e8f3e053ec954309de2c41a25
+.Ed
+.Pp
+It is also possible to use openssl to generate base64 output:
+.Bd -literal
+$ openssl dgst -binary -sha224 /bin/ls | openssl base64
+EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
+.Ed
+.Pp
+Warning, if the user has write access to the command itself (directly or via a
+.Nm sudo
+command), it may be possible for the user to replace the command after the
+digest check has been performed but before the command is executed.
+A similar race condition exists on systems that lack the
+.Xr fexecve 2
+system call when the directory in which the command is located
+is writable by the user.
+See the description of the
+.Em fdexec
+setting for more information on how
+.Nm sudo
+executes commands that have an associated digest.
+.Pp
+Command digests are only supported by version 1.8.7 or higher.
+.Ss Defaults
+Certain configuration options may be changed from their default
+values at run-time via one or more
+.Li Default_Entry
+lines.
+These may affect all users on any host, all users on a specific host, a
+specific user, a specific command, or commands being run as a specific user.
+Note that per-command entries may not include command line arguments.
+If you need to specify arguments, define a
+.Li Cmnd_Alias
+and reference
+that instead.
+.Bd -literal
+Default_Type ::= 'Defaults' |
+ 'Defaults' '@' Host_List |
+ 'Defaults' ':' User_List |
+ 'Defaults' '!' Cmnd_List |
+ 'Defaults' '>' Runas_List
+
+Default_Entry ::= Default_Type Parameter_List
+
+Parameter_List ::= Parameter |
+ Parameter ',' Parameter_List
+
+Parameter ::= Parameter '=' Value |
+ Parameter '+=' Value |
+ Parameter '-=' Value |
+ '!'* Parameter
+.Ed
+.Pp
+Parameters may be
+.Sy flags ,
+.Sy integer
+values,
+.Sy strings ,
+or
+.Sy lists .
+Flags are implicitly boolean and can be turned off via the
+.Ql \&!
+operator.
+Some integer, string and list parameters may also be
+used in a boolean context to disable them.
+Values may be enclosed
+in double quotes
+.Pq \&""
+when they contain multiple words.
+Special characters may be escaped with a backslash
+.Pq Ql \e .
+.Pp
+Lists have two additional assignment operators,
+.Li +=
+and
+.Li -= .
+These operators are used to add to and delete from a list respectively.
+It is not an error to use the
+.Li -=
+operator to remove an element
+that does not exist in a list.
+.Pp
+Defaults entries are parsed in the following order: generic, host,
+user and runas Defaults first, then command defaults.
+If there are multiple Defaults settings of the same type, the last
+matching setting is used.
+The following Defaults settings are parsed before all others since
+they may affect subsequent entries:
+.Em fqdn ,
+.Em group_plugin ,
+.Em runas_default ,
+.Em sudoers_locale .
+.Pp
+See
+.Sx SUDOERS OPTIONS
+for a list of supported Defaults parameters.
+.Ss User specification
+.Bd -literal
+User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \e
+ (':' Host_List '=' Cmnd_Spec_List)*
+
+Cmnd_Spec_List ::= Cmnd_Spec |
+ Cmnd_Spec ',' Cmnd_Spec_List
+
+Cmnd_Spec ::= Runas_Spec? Option_Spec* Tag_Spec* Cmnd
+
+Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
+
+.ie \n(SL \{\
+.ie \n(PS Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Date_Spec | Timeout_Spec)
+.el Option_Spec ::= (SELinux_Spec | Date_Spec | Timeout_Spec)
+.\}
+.el \{\
+.ie \n(PS Option_Spec ::= (Solaris_Priv_Spec | Date_Spec | Timeout_Spec)
+.el Option_Spec ::= (Date_Spec | Timeout_Spec)
+.\}
+
+.if \n(SL \{\
+SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')
+
+.\}
+.if \n(PS \{\
+Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset')
+
+.\}
+Date_Spec ::= ('NOTBEFORE=timestamp' | 'NOTAFTER=timestamp')
+
+Timeout_Spec ::= 'TIMEOUT=timeout'
+
+Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
+ 'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
+ 'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' |
+ 'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')
+.Ed
+.Pp
+A
+.Sy user specification
+determines which commands a user may run
+(and as what user) on specified hosts.
+By default, commands are
+run as
+.Sy root ,
+but this can be changed on a per-command basis.
+.Pp
+The basic structure of a user specification is
+.Dq who where = (as_whom) what .
+Let's break that down into its constituent parts:
+.Ss Runas_Spec
+A
+.Li Runas_Spec
+determines the user and/or the group that a command
+may be run as.
+A fully-specified
+.Li Runas_Spec
+consists of two
+.Li Runas_List Ns s
+(as defined above) separated by a colon
+.Pq Ql :\&
+and enclosed in a set of parentheses.
+The first
+.Li Runas_List
+indicates
+which users the command may be run as via
+.Nm sudo Ns 's
+.Fl u
+option.
+The second defines a list of groups that can be specified via
+.Nm sudo Ns 's
+.Fl g
+option in addition to any of the target user's groups.
+If both
+.Li Runas_List Ns s
+are specified, the command may be run with any combination of users
+and groups listed in their respective
+.Li Runas_List Ns s.
+If only the first is specified, the command may be run as any user
+in the list but no
+.Fl g
+option
+may be specified.
+If the first
+.Li Runas_List
+is empty but the
+second is specified, the command may be run as the invoking user
+with the group set to any listed in the
+.Li Runas_List .
+If both
+.Li Runas_List Ns s
+are empty, the command may only be run as the invoking user.
+If no
+.Li Runas_Spec
+is specified the command may be run as
+.Sy root
+and
+no group may be specified.
+.Pp
+A
+.Li Runas_Spec
+sets the default for the commands that follow it.
+What this means is that for the entry:
+.Bd -literal
+dgb boulder = (operator) /bin/ls, /bin/kill, /usr/bin/lprm
+.Ed
+.Pp
+The user
+.Sy dgb
+may run
+.Pa /bin/ls ,
+.Pa /bin/kill ,
+and
+.Pa /usr/bin/lprm
+on the host
+.No boulder Ns \(em Ns but
+only as
+.Sy operator .
+E.g.,
+.Bd -literal
+$ sudo -u operator /bin/ls
+.Ed
+.Pp
+It is also possible to override a
+.Li Runas_Spec
+later on in an entry.
+If we modify the entry like so:
+.Bd -literal
+dgb boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm
+.Ed
+.Pp
+Then user
+.Sy dgb
+is now allowed to run
+.Pa /bin/ls
+as
+.Sy operator ,
+but
+.Pa /bin/kill
+and
+.Pa /usr/bin/lprm
+as
+.Sy root .
+.Pp
+We can extend this to allow
+.Sy dgb
+to run
+.Li /bin/ls
+with either
+the user or group set to
+.Sy operator :
+.Bd -literal
+dgb boulder = (operator : operator) /bin/ls, (root) /bin/kill,\e
+ /usr/bin/lprm
+.Ed
+.Pp
+Note that while the group portion of the
+.Li Runas_Spec
+permits the
+user to run as command with that group, it does not force the user
+to do so.
+If no group is specified on the command line, the command
+will run with the group listed in the target user's password database
+entry.
+The following would all be permitted by the sudoers entry above:
+.Bd -literal
+$ sudo -u operator /bin/ls
+$ sudo -u operator -g operator /bin/ls
+$ sudo -g operator /bin/ls
+.Ed
+.Pp
+In the following example, user
+.Sy tcm
+may run commands that access
+a modem device file with the dialer group.
+.Bd -literal
+tcm boulder = (:dialer) /usr/bin/tip, /usr/bin/cu,\e
+ /usr/local/bin/minicom
+.Ed
+.Pp
+Note that in this example only the group will be set, the command
+still runs as user
+.Sy tcm .
+E.g.\&
+.Bd -literal
+$ sudo -g dialer /usr/bin/cu
+.Ed
+.Pp
+Multiple users and groups may be present in a
+.Li Runas_Spec ,
+in which case the user may select any combination of users and groups via the
+.Fl u
+and
+.Fl g
+options.
+In this example:
+.Bd -literal
+alan ALL = (root, bin : operator, system) ALL
+.Ed
+.Pp
+user
+.Sy alan
+may run any command as either user root or bin,
+optionally setting the group to operator or system.
+.Ss Option_Spec
+A
+.Li Cmnd
+may have zero or more options associated with it.
+Options may consist of
+.if \n(SL \{\
+SELinux roles and/or types,
+.\}
+.if \n(PS \{\
+Solaris privileges sets,
+.\}
+start and/or end dates and command timeouts.
+Once an option is set for a
+.Li Cmnd ,
+subsequent
+.Li Cmnd Ns s
+in the
+.Li Cmnd_Spec_List ,
+inherit that option unless it is overridden by another option.
+.if \n(SL \{\
+.Ss SELinux_Spec
+On systems with SELinux support,
+.Em sudoers
+file entries may optionally have an SELinux role and/or type associated
+with a command.
+If a role or
+type is specified with the command it will override any default values
+specified in
+.Em sudoers .
+A role or type specified on the command line,
+however, will supersede the values in
+.Em sudoers .
+.\}
+.if \n(PS \{\
+.Ss Solaris_Priv_Spec
+On Solaris systems,
+.Em sudoers
+file entries may optionally specify Solaris privilege set and/or limit
+privilege set associated with a command.
+If privileges or limit privileges are specified with the command
+it will override any default values specified in
+.Em sudoers .
+.Pp
+A privilege set is a comma-separated list of privilege names.
+The
+.Xr ppriv 1
+command can be used to list all privileges known to the system.
+For example:
+.Bd -literal
+$ ppriv -l
+.Ed
+.Pp
+In addition, there are several
+.Dq special
+privilege strings:
+.Bl -tag -width 8n
+.It none
+the empty set
+.It all
+the set of all privileges
+.It zone
+the set of all privileges available in the current zone
+.It basic
+the default set of privileges normal users are granted at login time
+.El
+.Pp
+Privileges can be excluded from a set by prefixing the privilege
+name with either an
+.Ql \&!
+or
+.Ql \-
+character.
+.\}
+.Ss Date_Spec
+.Nm sudoers
+rules can be specified with a start and end date via the
+.Li NOTBEFORE
+and
+.Li NOTAFTER
+settings.
+The time stamp must be specified in
+.Em Generalized Time
+as defined by RFC 4517.
+The format is effectively
+.Li yyyymmddHHMMSSZ
+where the minutes and seconds are optional.
+The
+.Ql Z
+suffix indicates that the time stamp is in Coordinated Universal Time (UTC).
+It is also possible to specify a timezone offset from UTC in hours
+and minutes instead of a
+.Ql Z .
+For example,
+.Ql -0500
+would correspond to Eastern Standard time in the US.
+As an extension, if no
+.Ql Z
+or timezone offset is specified, local time will be used.
+.Pp
+The following are all valid time stamps:
+.Bd -literal -offset 4n
+20170214083000Z
+2017021408Z
+20160315220000-0500
+20151201235900
+.Ed
+.Ss Timeout_Spec
+A command may have a timeout associated with it.
+If the timeout expires before the command has exited, the
+command will be terminated.
+The timeout may be specified in combinations of days, hours,
+minutes and seconds with a single-letter case-insensitive suffix
+that indicates the unit of time.
+For example, a timeout of 7 days, 8 hours, 30 minutes and
+10 seconds would be written as
+.Li 7d8h30m10s .
+If a number is specified without a unit, seconds are assumed.
+Any of the days, minutes, hours or seconds may be omitted.
+The order must be from largest to smallest unit and a unit
+may not be specified more than once.
+.Pp
+The following are all
+.Em valid
+timeout values:
+.Li 7d8h30m10s ,
+.Li 14d ,
+.Li 8h30m ,
+.Li 600s ,
+.Li 3600 .
+The following are
+.Em invalid
+timeout values:
+.Li 12m2w1d ,
+.Li 30s10m4h ,
+.Li 1d2d3h .
+.Pp
+This option is only supported by version 1.8.20 or higher.
+.Ss Tag_Spec
+A command may have zero or more tags associated with it.
+The following tag values are supported:
+.Li EXEC ,
+.Li NOEXEC ,
+.Li FOLLOW ,
+.Li NOFOLLOW ,
+.Li LOG_INPUT ,
+.Li NOLOG_INPUT ,
+.Li LOG_OUTPUT ,
+.Li NOLOG_OUTPUT ,
+.Li MAIL ,
+.Li NOMAIL ,
+.Li PASSWD ,
+.Li NOPASSWD ,
+.Li SETENV ,
+and
+.Li NOSETENV .
+Once a tag is set on a
+.Li Cmnd ,
+subsequent
+.Li Cmnd Ns s
+in the
+.Li Cmnd_Spec_List ,
+inherit the tag unless it is overridden by the opposite tag (in other words,
+.Li PASSWD
+overrides
+.Li NOPASSWD
+and
+.Li NOEXEC
+overrides
+.Li EXEC ) .
+.Bl -hang -width 0n
+.It Em EXEC No and Em NOEXEC
+.sp
+If
+.Nm sudo
+has been compiled with
+.Em noexec
+support and the underlying operating system supports it, the
+.Li NOEXEC
+tag can be used to prevent a dynamically-linked executable from
+running further commands itself.
+.Pp
+In the following example, user
+.Sy aaron
+may run
+.Pa /usr/bin/more
+and
+.Pa /usr/bin/vi
+but shell escapes will be disabled.
+.Bd -literal
+aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi
+.Ed
+.Pp
+See the
+.Sx Preventing shell escapes
+section below for more details on how
+.Li NOEXEC
+works and whether or not it will work on your system.
+.It Em FOLLOW No and Em NOFOLLOW
+Starting with version 1.8.15,
+.Nm sudoedit
+will not open a file that is a symbolic link unless the
+.Em sudoedit_follow
+option is enabled.
+The
+.Em FOLLOW
+and
+.Em NOFOLLOW
+tags override the value of
+.Em sudoedit_follow
+and can be used to permit (or deny) the editing of symbolic links
+on a per-command basis.
+These tags are only effective for the
+.Em sudoedit
+command and are ignored for all other commands.
+.It Em LOG_INPUT No and Em NOLOG_INPUT
+.sp
+These tags override the value of the
+.Em log_input
+option on a per-command basis.
+For more information, see the description of
+.Em log_input
+in the
+.Sx SUDOERS OPTIONS
+section below.
+.It Em LOG_OUTPUT No and Em NOLOG_OUTPUT
+.sp
+These tags override the value of the
+.Em log_output
+option on a per-command basis.
+For more information, see the description of
+.Em log_output
+in the
+.Sx SUDOERS OPTIONS
+section below.
+.It Em MAIL No and Em NOMAIL
+.sp
+These tags provide fine-grained control over whether
+mail will be sent when a user runs a command by
+overriding the value of the
+.Em mail_all_cmnds
+option on a per-command basis.
+They have no effect when
+.Nm sudo
+is run with the
+.Fl l
+or
+.Fl v
+options.
+A
+.Em NOMAIL
+tag will also override the
+.Em mail_always
+and
+.Em mail_no_perms
+options.
+For more information, see the descriptions of
+.Em mail_all_cmnds ,
+.Em mail_always ,
+and
+.Em mail_no_perms
+in the
+.Sx SUDOERS OPTIONS
+section below.
+.It Em PASSWD No and Em NOPASSWD
+.sp
+By default,
+.Nm sudo
+requires that a user authenticate him or herself
+before running a command.
+This behavior can be modified via the
+.Li NOPASSWD
+tag.
+Like a
+.Li Runas_Spec ,
+the
+.Li NOPASSWD
+tag sets
+a default for the commands that follow it in the
+.Li Cmnd_Spec_List .
+Conversely, the
+.Li PASSWD
+tag can be used to reverse things.
+For example:
+.Bd -literal
+ray rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm
+.Ed
+.Pp
+would allow the user
+.Sy ray
+to run
+.Pa /bin/kill ,
+.Pa /bin/ls ,
+and
+.Pa /usr/bin/lprm
+as
+.Sy root
+on the machine rushmore without authenticating himself.
+If we only want
+.Sy ray
+to be able to
+run
+.Pa /bin/kill
+without a password the entry would be:
+.Bd -literal
+ray rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm
+.Ed
+.Pp
+Note, however, that the
+.Li PASSWD
+tag has no effect on users who are in the group specified by the
+.Em exempt_group
+option.
+.Pp
+By default, if the
+.Li NOPASSWD
+tag is applied to any of the entries for a user on the current host,
+he or she will be able to run
+.Dq Li sudo -l
+without a password.
+Additionally, a user may only run
+.Dq Li sudo -v
+without a password if the
+.Li NOPASSWD
+tag is present for all a user's entries that pertain to the current host.
+This behavior may be overridden via the
+.Em verifypw
+and
+.Em listpw
+options.
+.It Em SETENV No and Em NOSETENV
+.sp
+These tags override the value of the
+.Em setenv
+option on a per-command basis.
+Note that if
+.Li SETENV
+has been set for a command, the user may disable the
+.Em env_reset
+option from the command line via the
+.Fl E
+option.
+Additionally, environment variables set on the command
+line are not subject to the restrictions imposed by
+.Em env_check ,
+.Em env_delete ,
+or
+.Em env_keep .
+As such, only trusted users should be allowed to set variables in this manner.
+If the command matched is
+.Sy ALL ,
+the
+.Li SETENV
+tag is implied for that command; this default may be overridden by use of the
+.Li NOSETENV
+tag.
+.El
+.Ss Wildcards
+.Nm sudo
+allows shell-style
+.Em wildcards
+(aka meta or glob characters)
+to be used in host names, path names and command line arguments in the
+.Em sudoers
+file.
+Wildcard matching is done via the
+.Xr glob 3
+and
+.Xr fnmatch 3
+functions as specified by
+.St -p1003.1 .
+.Bl -tag -width 8n
+.It Li *
+Matches any set of zero or more characters (including white space).
+.It Li \&?
+Matches any single character (including white space).
+.It Li [...]
+Matches any character in the specified range.
+.It Li [!...]
+Matches any character
+.Em not
+in the specified range.
+.It Li \ex
+For any character
+.Sq x ,
+evaluates to
+.Sq x .
+This is used to escape special characters such as:
+.Ql * ,
+.Ql \&? ,
+.Ql [\& ,
+and
+.Ql ]\& .
+.El
+.Pp
+.Bf -symbolic
+Note that these are not regular expressions.
+.Ef
+Unlike a regular expression there is no way to match one or more
+characters within a range.
+.Pp
+Character classes may be used if your system's
+.Xr glob 3
+and
+.Xr fnmatch 3
+functions support them.
+However, because the
+.Ql :\&
+character has special meaning in
+.Em sudoers ,
+it must be
+escaped.
+For example:
+.Bd -literal -offset 4n
+/bin/ls [[\e:\&alpha\e:\&]]*
+.Ed
+.Pp
+Would match any file name beginning with a letter.
+.Pp
+Note that a forward slash
+.Pq Ql /
+will
+.Em not
+be matched by
+wildcards used in the file name portion of the command.
+This is to make a path like:
+.Bd -literal -offset 4n
+/usr/bin/*
+.Ed
+.Pp
+match
+.Pa /usr/bin/who
+but not
+.Pa /usr/bin/X11/xterm .
+.Pp
+When matching the command line arguments, however, a slash
+.Em does
+get matched by wildcards since command line arguments may contain
+arbitrary strings and not just path names.
+.Pp
+.Bf -symbolic
+Wildcards in command line arguments should be used with care.
+.Ef
+.br
+Command line arguments are matched as a single, concatenated string.
+This mean a wildcard character such as
+.Ql \&?
+or
+.Ql *
+will match across word boundaries, which may be unexpected.
+For example, while a sudoers entry like:
+.Bd -literal -offset 4n
+%operator ALL = /bin/cat /var/log/messages*
+.Ed
+.Pp
+will allow command like:
+.Bd -literal -offset 4n
+$ sudo cat /var/log/messages.1
+.Ed
+.Pp
+It will also allow:
+.Bd -literal -offset 4n
+$ sudo cat /var/log/messages /etc/shadow
+.Ed
+.Pp
+which is probably not what was intended.
+In most cases it is better to do command line processing
+outside of the
+.Em sudoers
+file in a scripting language.
+.Ss Exceptions to wildcard rules
+The following exceptions apply to the above rules:
+.Bl -tag -width 8n
+.It Li \&""
+If the empty string
+.Li \&""
+is the only command line argument in the
+.Em sudoers
+file entry it means that command is not allowed to be run with
+.Em any
+arguments.
+.It sudoedit
+Command line arguments to the
+.Em sudoedit
+built-in command should always be path names, so a forward slash
+.Pq Ql /
+will not be matched by a wildcard.
+.El
+.Ss Including other files from within sudoers
+It is possible to include other
+.Em sudoers
+files from within the
+.Em sudoers
+file currently being parsed using the
+.Li #include
+and
+.Li #includedir
+directives.
+.Pp
+This can be used, for example, to keep a site-wide
+.Em sudoers
+file in addition to a local, per-machine file.
+For the sake of this example the site-wide
+.Em sudoers
+file will be
+.Pa /etc/sudoers
+and the per-machine one will be
+.Pa /etc/sudoers.local .
+To include
+.Pa /etc/sudoers.local
+from within
+.Pa /etc/sudoers
+we would use the
+following line in
+.Pa /etc/sudoers :
+.Bd -literal -offset 4n
+#include /etc/sudoers.local
+.Ed
+.Pp
+When
+.Nm sudo
+reaches this line it will suspend processing of the current file
+.Pq Pa /etc/sudoers
+and switch to
+.Pa /etc/sudoers.local .
+Upon reaching the end of
+.Pa /etc/sudoers.local ,
+the rest of
+.Pa /etc/sudoers
+will be processed.
+Files that are included may themselves include other files.
+A hard limit of 128 nested include files is enforced to prevent include
+file loops.
+.Pp
+If the path to the include file is not fully-qualified (does not
+begin with a
+.Ql / ) ,
+it must be located in the same directory as the sudoers file it was
+included from.
+For example, if
+.Pa /etc/sudoers
+contains the line:
+.Bd -literal -offset 4n
+.Li #include sudoers.local
+.Ed
+.Pp
+the file that will be included is
+.Pa /etc/sudoers.local .
+.Pp
+The file name may also include the
+.Li %h
+escape, signifying the short form of the host name.
+In other words, if the machine's host name is
+.Dq xerxes ,
+then
+.Bd -literal -offset 4n
+#include /etc/sudoers.%h
+.Ed
+.Pp
+will cause
+.Nm sudo
+to include the file
+.Pa /etc/sudoers.xerxes .
+.Pp
+The
+.Li #includedir
+directive can be used to create a
+.Pa sudoers.d
+directory that the system package manager can drop
+.Em sudoers
+file rules into as part of package installation.
+For example, given:
+.Bd -literal -offset 4n
+#includedir /etc/sudoers.d
+.Ed
+.Pp
+.Nm sudo
+will suspend processing of the current file and read each file in
+.Pa /etc/sudoers.d ,
+skipping file names that end in
+.Ql ~
+or contain a
+.Ql .\&
+character to avoid causing problems with package manager or editor
+temporary/backup files.
+Files are parsed in sorted lexical order.
+That is,
+.Pa /etc/sudoers.d/01_first
+will be parsed before
+.Pa /etc/sudoers.d/10_second .
+Be aware that because the sorting is lexical, not numeric,
+.Pa /etc/sudoers.d/1_whoops
+would be loaded
+.Em after
+.Pa /etc/sudoers.d/10_second .
+Using a consistent number of leading zeroes in the file names can be used
+to avoid such problems.
+After parsing the files in the directory, control returns to the
+file that contained the
+.Li #includedir
+directive.
+.Pp
+Note that unlike files included via
+.Li #include ,
+.Nm visudo
+will not edit the files in a
+.Li #includedir
+directory unless one of them contains a syntax error.
+It is still possible to run
+.Nm visudo
+with the
+.Fl f
+flag to edit the files directly, but this will not catch the
+redefinition of an
+.Em alias
+that is also present in a different file.
+.Ss Other special characters and reserved words
+The pound sign
+.Pq Ql #
+is used to indicate a comment (unless it is part of a #include
+directive or unless it occurs in the context of a user name and is
+followed by one or more digits, in which case it is treated as a
+uid).
+Both the comment character and any text after it, up to the end of
+the line, are ignored.
+.Pp
+The reserved word
+.Sy ALL
+is a built-in
+.Em alias
+that always causes a match to succeed.
+It can be used wherever one might otherwise use a
+.Li Cmnd_Alias ,
+.Li User_Alias ,
+.Li Runas_Alias ,
+or
+.Li Host_Alias .
+You should not try to define your own
+.Em alias
+called
+.Sy ALL
+as the built-in alias will be used in preference to your own.
+Please note that using
+.Sy ALL
+can be dangerous since in a command context, it allows the user to run
+.Em any
+command on the system.
+.Pp
+An exclamation point
+.Pq Ql \&!
+can be used as a logical
+.Em not
+operator in a list or
+.Em alias
+as well as in front of a
+.Li Cmnd .
+This allows one to exclude certain values.
+For the
+.Ql \&!
+operator to be effective, there must be something for it to exclude.
+For example, to match all users except for root one would use:
+.Bd -literal -offset 4n
+ALL,!root
+.Ed
+.Pp
+If the
+.Sy ALL ,
+is omitted, as in:
+.Bd -literal -offset 4n
+!root
+.Ed
+.Pp
+it would explicitly deny root but not match any other users.
+This is different from a true
+.Dq negation
+operator.
+.Pp
+Note, however, that using a
+.Ql \&!
+in conjunction with the built-in
+.Sy ALL
+alias to allow a user to run
+.Dq all but a few
+commands rarely works as intended (see
+.Sx SECURITY NOTES
+below).
+.Pp
+Long lines can be continued with a backslash
+.Pq Ql \e
+as the last character on the line.
+.Pp
+White space between elements in a list as well as special syntactic
+characters in a
+.Em User Specification
+.Po
+.Ql =\& ,
+.Ql :\& ,
+.Ql (\& ,
+.Ql )\&
+.Pc
+is optional.
+.Pp
+The following characters must be escaped with a backslash
+.Pq Ql \e
+when used as part of a word (e.g., a user name or host name):
+.Ql \&! ,
+.Ql =\& ,
+.Ql :\& ,
+.Ql ,\& ,
+.Ql (\& ,
+.Ql )\& ,
+.Ql \e .
+.Sh SUDOERS OPTIONS
+.Nm sudo Ns 's
+behavior can be modified by
+.Li Default_Entry
+lines, as explained earlier.
+A list of all supported Defaults parameters, grouped by type, are listed below.
+.Pp
+.Sy Boolean Flags :
+.Bl -tag -width 16n
+.It always_query_group_plugin
+If a
+.Em group_plugin
+is configured, use it to resolve groups of the form %group as long
+as there is not also a system group of the same name.
+Normally, only groups of the form %:group are passed to the
+.Em group_plugin .
+This flag is
+.Em off
+by default.
+.It always_set_home
+If enabled,
+.Nm sudo
+will set the
+.Ev HOME
+environment variable to the home directory of the target user
+(which is root unless the
+.Fl u
+option is used).
+This effectively means that the
+.Fl H
+option is always implied.
+Note that by default,
+.Ev HOME
+will be set to the home directory of the target user when the
+.Em env_reset
+option is enabled, so
+.Em always_set_home
+only has an effect for configurations where either
+.Em env_reset
+is disabled or
+.Ev HOME
+is present in the
+.Em env_keep
+list.
+This flag is
+.Em off
+by default.
+.It authenticate
+If set, users must authenticate themselves via a password (or other
+means of authentication) before they may run commands.
+This default may be overridden via the
+.Li PASSWD
+and
+.Li NOPASSWD
+tags.
+This flag is
+.Em on
+by default.
+.It case_insensitive_group
+If enabled, group names in
+.Em sudoers
+will be matched in a case insensitive manner.
+This may be necessary when users are stored in LDAP or AD.
+This flag is
+.Em on
+by default.
+.It case_insensitive_user
+If enabled, user names in
+.Em sudoers
+will be matched in a case insensitive manner.
+This may be necessary when groups are stored in LDAP or AD.
+This flag is
+.Em on
+by default.
+.It closefrom_override
+If set, the user may use
+.Nm sudo Ns 's
+.Fl C
+option which overrides the default starting point at which
+.Nm sudo
+begins closing open file descriptors.
+This flag is
+.Em off
+by default.
+.It compress_io
+If set, and
+.Nm sudo
+is configured to log a command's input or output,
+the I/O logs will be compressed using
+.Sy zlib .
+This flag is
+.Em on
+by default when
+.Nm sudo
+is compiled with
+.Sy zlib
+support.
+.It exec_background
+By default,
+.Nm sudo
+runs a command as the foreground process as long as
+.Nm sudo
+itself is running in the foreground.
+When the
+.Em exec_background
+flag is enabled and the command is being run in a pty (due to I/O logging
+or the
+.Em use_pty
+flag), the command will be run as a background process.
+Attempts to read from the controlling terminal (or to change terminal
+settings) will result in the command being suspended with the
+.Dv SIGTTIN
+signal (or
+.Dv SIGTTOU
+in the case of terminal settings).
+If this happens when
+.Nm sudo
+is a foreground process, the command will be granted the controlling terminal
+and resumed in the foreground with no user intervention required.
+The advantage of initially running the command in the background is that
+.Nm sudo
+need not read from the terminal unless the command explicitly requests it.
+Otherwise, any terminal input must be passed to the command, whether it
+has required it or not (the kernel buffers terminals so it is not possible
+to tell whether the command really wants the input).
+This is different from historic
+.Em sudo
+behavior or when the command is not being run in a pty.
+.Pp
+For this to work seamlessly, the operating system must support the
+automatic restarting of system calls.
+Unfortunately, not all operating systems do this by default,
+and even those that do may have bugs.
+For example, macOS fails to restart the
+.Fn tcgetattr
+and
+.Fn tcsetattr
+system calls (this is a bug in macOS).
+Furthermore, because this behavior depends on the command stopping with the
+.Dv SIGTTIN
+or
+.Dv SIGTTOU
+signals, programs that catch these signals and suspend themselves
+with a different signal (usually
+.Dv SIGTOP )
+will not be automatically foregrounded.
+Some versions of the linux
+.Xr su 1
+command behave this way.
+This flag is
+.Em off
+by default.
+.Pp
+This setting is only supported by version 1.8.7 or higher.
+It has no effect unless I/O logging is enabled or the
+.Em use_pty
+flag is enabled.
+.It env_editor
+If set,
+.Nm visudo
+will use the value of the
+.Ev SUDO_EDITOR ,
+.Ev VISUAL
+or
+.Ev EDITOR
+environment variables before falling back on the default editor list.
+Note that this may create a security hole as it allows the user to
+run any arbitrary command as root without logging.
+A safer alternative is to place a colon-separated list of editors
+in the
+.Em editor
+variable.
+.Nm visudo
+will then only use
+.Ev SUDO_EDITOR ,
+.Ev VISUAL
+or
+.Ev EDITOR
+if they match a value specified in
+.Em editor .
+If the
+.Em env_reset
+flag is enabled, the
+.Ev SUDO_EDITOR ,
+.Ev VISUAL
+and/or
+.Ev EDITOR
+environment variables must be present in the
+.Em env_keep
+list for the
+.Em env_editor
+flag to function when
+.Nm visudo
+is invoked via
+.Nm sudo .
+This flag is
+.Em @env_editor@
+by default.
+.It env_reset
+If set,
+.Nm sudo
+will run the command in a minimal environment containing the
+.Ev TERM ,
+.Ev PATH ,
+.Ev HOME ,
+.Ev MAIL ,
+.Ev SHELL ,
+.Ev LOGNAME ,
+.Ev USER
+and
+.Ev SUDO_*
+variables.
+Any variables in the caller's environment or in the file specified
+by the
+.Em restricted_env_file
+option that match the
+.Li env_keep
+and
+.Li env_check
+lists are then added, followed by any variables present in the file
+specified by the
+.Em env_file
+option (if any).
+The contents of the
+.Li env_keep
+and
+.Li env_check
+lists, as modified by global Defaults parameters in
+.Em sudoers ,
+are displayed when
+.Nm sudo
+is run by root with the
+.Fl V
+option.
+If the
+.Em secure_path
+option is set, its value will be used for the
+.Ev PATH
+environment variable.
+This flag is
+.Em @env_reset@
+by default.
+.It fast_glob
+Normally,
+.Nm sudo
+uses the
+.Xr glob 3
+function to do shell-style globbing when matching path names.
+However, since it accesses the file system,
+.Xr glob 3
+can take a long time to complete for some patterns, especially
+when the pattern references a network file system that is mounted
+on demand (auto mounted).
+The
+.Em fast_glob
+option causes
+.Nm sudo
+to use the
+.Xr fnmatch 3
+function, which does not access the file system to do its matching.
+The disadvantage of
+.Em fast_glob
+is that it is unable to match relative path names such as
+.Pa ./ls
+or
+.Pa ../bin/ls .
+This has security implications when path names that include globbing
+characters are used with the negation operator,
+.Ql !\& ,
+as such rules can be trivially bypassed.
+As such, this option should not be used when the
+.Em sudoers
+file contains rules that contain negated path names which include globbing
+characters.
+This flag is
+.Em off
+by default.
+.It fqdn
+Set this flag if you want to put fully qualified host names in the
+.Em sudoers
+file when the local host name (as returned by the
+.Li hostname
+command) does not contain the domain name.
+In other words, instead of myhost you would use myhost.mydomain.edu.
+You may still use the short form if you wish (and even mix the two).
+This option is only effective when the
+.Dq canonical
+host name, as returned by the
+.Fn getaddrinfo
+or
+.Fn gethostbyname
+function, is a fully-qualified domain name.
+This is usually the case when the system is configured to use DNS
+for host name resolution.
+.Pp
+If the system is configured to use the
+.Pa /etc/hosts
+file in preference to DNS, the
+.Dq canonical
+host name may not be fully-qualified.
+The order that sources are queried for host name resolution
+is usually specified in the
+.Pa @nsswitch_conf@ ,
+.Pa @netsvc_conf@ ,
+.Pa /etc/host.conf ,
+or, in some cases,
+.Pa /etc/resolv.conf
+file.
+In the
+.Pa /etc/hosts
+file, the first host name of the entry is considered to be the
+.Dq canonical
+name; subsequent names are aliases that are not used by
+.Nm .
+For example, the following hosts file line for the machine
+.Dq xyzzy
+has the fully-qualified domain name as the
+.Dq canonical
+host name, and the short version as an alias.
+.sp
+.Dl 192.168.1.1 xyzzy.sudo.ws xyzzy
+.sp
+If the machine's hosts file entry is not formatted properly, the
+.Em fqdn
+option will not be effective if it is queried before DNS.
+.Pp
+Beware that when using DNS for host name resolution, turning on
+.Em fqdn
+requires
+.Nm
+to make DNS lookups which renders
+.Nm sudo
+unusable if DNS stops working (for example if the machine is disconnected
+from the network).
+Also note that just like with the hosts file, you must use the
+.Dq canonical
+name as DNS knows it.
+That is, you may not use a host alias
+.Po
+.Li CNAME
+entry
+.Pc
+due to performance issues and the fact that there is no way to get all
+aliases from DNS.
+.Pp
+This flag is
+.Em @fqdn@
+by default.
+.It ignore_audit_errors
+Allow commands to be run even if
+.Nm
+cannot write to the audit log.
+If enabled, an audit log write failure is not treated as a fatal error.
+If disabled, a command may only be run after the audit event is successfully
+written.
+This flag is only effective on systems for which
+.Nm
+supports audit logging, including
+.Fx ,
+Linux, macOS and Solaris.
+This flag is
+.Em on
+by default.
+.It ignore_dot
+If set,
+.Nm sudo
+will ignore "." or "" (both denoting current directory) in the
+.Ev PATH
+environment variable; the
+.Ev PATH
+itself is not modified.
+This flag is
+.Em @ignore_dot@
+by default.
+.It ignore_iolog_errors
+Allow commands to be run even if
+.Nm
+cannot write to the I/O log.
+If enabled, an I/O log write failure is not treated as a fatal error.
+If disabled, the command will be terminated if the I/O log cannot be written to.
+This flag is
+.Em off
+by default.
+.It ignore_logfile_errors
+Allow commands to be run even if
+.Nm
+cannot write to the log file.
+If enabled, a log file write failure is not treated as a fatal error.
+If disabled, a command may only be run after the log file entry is successfully
+written.
+This flag only has an effect when
+.Nm
+is configured to use file-based logging via the
+.Em logfile
+option.
+This flag is
+.Em on
+by default.
+.It ignore_local_sudoers
+If set via LDAP, parsing of
+.Pa @sysconfdir@/sudoers
+will be skipped.
+This is intended for Enterprises that wish to prevent the usage of local
+sudoers files so that only LDAP is used.
+This thwarts the efforts of rogue operators who would attempt to add roles to
+.Pa @sysconfdir@/sudoers .
+When this option is present,
+.Pa @sysconfdir@/sudoers
+does not even need to exist.
+Since this option tells
+.Nm sudo
+how to behave when no specific LDAP entries have been matched, this
+sudoOption is only meaningful for the
+.Li cn=defaults
+section.
+This flag is
+.Em off
+by default.
+.It ignore_unknown_defaults
+If set,
+.Nm sudo
+will not produce a warning if it encounters an unknown Defaults entry
+in the
+.Em sudoers
+file or an unknown sudoOption in LDAP.
+This flag is
+.Em off
+by default.
+.It insults
+If set,
+.Nm sudo
+will insult users when they enter an incorrect password.
+This flag is
+.Em @insults@
+by default.
+.It log_host
+If set, the host name will be logged in the (non-syslog)
+.Nm sudo
+log file.
+This flag is
+.Em off
+by default.
+.It log_input
+If set,
+.Nm sudo
+will run the command in a pseudo-tty and log all user input.
+If the standard input is not connected to the user's tty, due to
+I/O redirection or because the command is part of a pipeline, that
+input is also captured and stored in a separate log file.
+Anything sent to the standard input will be consumed, regardless of
+whether or not the command run via
+.Nm sudo
+is actually reading the standard input.
+This may have unexpected results when using
+.Nm sudo
+in a shell script that expects to process the standard input.
+For more information about I/O logging, see the
+.Sx "I/O LOG FILES"
+section.
+This flag is
+.Em off
+by default.
+.It log_output
+If set,
+.Nm sudo
+will run the command in a pseudo-tty and log all output that is sent
+to the screen, similar to the
+.Xr script 1
+command.
+For more information about I/O logging, see the
+.Sx "I/O LOG FILES"
+section.
+This flag is
+.Em off
+by default.
+.It log_year
+If set, the four-digit year will be logged in the (non-syslog)
+.Nm sudo
+log file.
+This flag is
+.Em off
+by default.
+.It long_otp_prompt
+When validating with a One Time Password (OTP) scheme such as
+.Sy S/Key
+or
+.Sy OPIE ,
+a two-line prompt is used to make it easier
+to cut and paste the challenge to a local window.
+It's not as pretty as the default but some people find it more convenient.
+This flag is
+.Em @long_otp_prompt@
+by default.
+.It mail_all_cmnds
+Send mail to the
+.Em mailto
+user every time a user attempts to run a command via
+.Nm sudo
+(this includes
+.Nm sudoedit ) .
+No mail will be sent if the user runs
+.Nm sudo
+with the
+.Fl l
+or
+.Fl v
+option unless there is an authentication error and the
+.Em mail_badpass
+flag is also set.
+This flag is
+.Em off
+by default.
+.It mail_always
+Send mail to the
+.Em mailto
+user every time a user runs
+.Nm sudo .
+This flag is
+.Em off
+by default.
+.It mail_badpass
+Send mail to the
+.Em mailto
+user if the user running
+.Nm sudo
+does not enter the correct password.
+If the command the user is attempting to run is not permitted by
+.Nm sudoers
+and one of the
+.Em mail_all_cmnds ,
+.Em mail_always ,
+.Em mail_no_host ,
+.Em mail_no_perms
+or
+.Em mail_no_user
+flags are set, this flag will have no effect.
+This flag is
+.Em off
+by default.
+.It mail_no_host
+If set, mail will be sent to the
+.Em mailto
+user if the invoking user exists in the
+.Em sudoers
+file, but is not allowed to run commands on the current host.
+This flag is
+.Em @mail_no_host@
+by default.
+.It mail_no_perms
+If set, mail will be sent to the
+.Em mailto
+user if the invoking user is allowed to use
+.Nm sudo
+but the command they are trying is not listed in their
+.Em sudoers
+file entry or is explicitly denied.
+This flag is
+.Em @mail_no_perms@
+by default.
+.It mail_no_user
+If set, mail will be sent to the
+.Em mailto
+user if the invoking user is not in the
+.Em sudoers
+file.
+This flag is
+.Em @mail_no_user@
+by default.
+.It match_group_by_gid
+By default,
+.Nm
+will look up each group the user is a member of by group ID to
+determine the group name (this is only done once).
+The resulting list of the user's group names is used when matching
+groups listed in the
+.Em sudoers
+file.
+This works well on systems where the number of groups listed in the
+.Em sudoers
+file is larger than the number of groups a typical user belongs to.
+On systems where group lookups are slow, where users may belong
+to a large number of groups, and where the number of groups listed
+in the
+.Em sudoers
+file is relatively small, it may be prohibitively expensive and
+running commands via
+.Nm sudo
+may take longer than normal.
+On such systems it may be faster to use the
+.Em match_group_by_gid
+flag to avoid resolving the user's group IDs to group names.
+In this case,
+.Nm
+must look up any group name listed in the
+.Em sudoers
+file and use the group ID instead of the group name when determining
+whether the user is a member of the group.
+.Pp
+Note that if
+.Em match_group_by_gid
+is enabled, group database lookups performed by
+.Nm
+will be keyed by group name as opposed to group ID.
+On systems where there are multiple sources for the group database,
+it is possible to have conflicting group names or group IDs in the local
+.Pa /etc/group
+file and the remote group database.
+On such systems, enabling or disabling
+.Em match_group_by_gid
+can be used to choose whether group database queries are performed
+by name (enabled) or ID (disabled), which may aid in working around
+group entry conflicts.
+.Pp
+The
+.Em match_group_by_gid
+flag has no effect when
+.Em sudoers
+data is stored in LDAP.
+This flag is
+.Em off
+by default.
+.Pp
+This setting is only supported by version 1.8.18 or higher.
+.It netgroup_tuple
+If set, netgroup lookups will be performed using the full netgroup
+tuple: host name, user name and domain (if one is set).
+Historically,
+.Nm sudo
+only matched the user name and domain for netgroups used in a
+.Li User_List
+and only matched the host name and domain for netgroups used in a
+.Li Host_List .
+This flag is
+.Em off
+by default.
+.It noexec
+If set, all commands run via
+.Nm sudo
+will behave as if the
+.Li NOEXEC
+tag has been set, unless overridden by an
+.Li EXEC
+tag.
+See the description of
+.Em EXEC and NOEXEC
+above as well as the
+.Sx Preventing shell escapes
+section at the end of this manual.
+This flag is
+.Em off
+by default.
+.It pam_session
+On systems that use PAM for authentication,
+.Nm sudo
+will create a new PAM session for the command to be run in.
+Disabling
+.Em pam_session
+may be needed on older PAM implementations or on operating systems where
+opening a PAM session changes the utmp or wtmp files.
+If PAM session support is disabled, resource limits may not be updated
+for the command being run.
+If
+.Em pam_session ,
+.Em pam_setcred ,
+and
+.Em use_pty
+are disabled and I/O logging has not been configured,
+.Nm sudo
+will execute the command directly instead of running it as a child
+process.
+This flag is
+.Em @pam_session@
+by default.
+.Pp
+This setting is only supported by version 1.8.7 or higher.
+.It pam_setcred
+On systems that use PAM for authentication,
+.Nm sudo
+will attempt to establish credentials for the target user by default,
+if supported by the underlying authentication system.
+One example of a credential is a Kerberos ticket.
+If
+.Em pam_session ,
+.Em pam_setcred ,
+and
+.Em use_pty
+are disabled and I/O logging has not been configured,
+.Nm sudo
+will execute the command directly instead of running it as a child
+process.
+This flag is
+.Em on
+by default.
+.Pp
+This setting is only supported by version 1.8.8 or higher.
+.It passprompt_override
+If set, the prompt specified by
+.Em passprompt
+or the
+.Ev SUDO_PROMPT
+environment variable will always be used and will replace the
+prompt provided by a PAM module or other authentication method.
+This flag is
+.Em off
+by default.
+.It path_info
+Normally,
+.Nm sudo
+will tell the user when a command could not be
+found in their
+.Ev PATH
+environment variable.
+Some sites may wish to disable this as it could be used to gather
+information on the location of executables that the normal user does
+not have access to.
+The disadvantage is that if the executable is simply not in the user's
+.Ev PATH ,
+.Nm sudo
+will tell the user that they are not allowed to run it, which can be confusing.
+This flag is
+.Em @path_info@
+by default.
+.It preserve_groups
+By default,
+.Nm sudo
+will initialize the group vector to the list of groups the target user is in.
+When
+.Em preserve_groups
+is set, the user's existing group vector is left unaltered.
+The real and effective group IDs, however, are still set to match the
+target user.
+This flag is
+.Em off
+by default.
+.It pwfeedback
+By default,
+.Nm sudo
+reads the password like most other Unix programs,
+by turning off echo until the user hits the return (or enter) key.
+Some users become confused by this as it appears to them that
+.Nm sudo
+has hung at this point.
+When
+.Em pwfeedback
+is set,
+.Nm sudo
+will provide visual feedback when the user presses a key.
+Note that this does have a security impact as an onlooker may be able to
+determine the length of the password being entered.
+This flag is
+.Em off
+by default.
+.It requiretty
+If set,
+.Nm sudo
+will only run when the user is logged in to a real tty.
+When this flag is set,
+.Nm sudo
+can only be run from a login session and not via other means such as
+.Xr cron @mansectsu@
+or cgi-bin scripts.
+This flag is
+.Em off
+by default.
+.It root_sudo
+If set, root is allowed to run
+.Nm sudo
+too.
+Disabling this prevents users from
+.Dq chaining
+.Nm sudo
+commands to get a root shell by doing something like
+.Dq Li sudo sudo /bin/sh .
+Note, however, that turning off
+.Em root_sudo
+will also prevent root from running
+.Nm sudoedit .
+Disabling
+.Em root_sudo
+provides no real additional security; it exists purely for historical reasons.
+This flag is
+.Em @root_sudo@
+by default.
+.It rootpw
+If set,
+.Nm sudo
+will prompt for the root password instead of the password of the invoking user
+when running a command or editing a file.
+This flag is
+.Em off
+by default.
+.It runaspw
+If set,
+.Nm sudo
+will prompt for the password of the user defined by the
+.Em runas_default
+option (defaults to
+.Li @runas_default@ )
+instead of the password of the invoking user
+when running a command or editing a file.
+This flag is
+.Em off
+by default.
+.It set_home
+If enabled and
+.Nm sudo
+is invoked with the
+.Fl s
+option the
+.Ev HOME
+environment variable will be set to the home directory of the target
+user (which is root unless the
+.Fl u
+option is used).
+This effectively makes the
+.Fl s
+option imply
+.Fl H .
+Note that
+.Ev HOME
+is already set when the
+.Em env_reset
+option is enabled, so
+.Em set_home
+is only effective for configurations where either
+.Em env_reset
+is disabled
+or
+.Ev HOME
+is present in the
+.Em env_keep
+list.
+This flag is
+.Em off
+by default.
+.It set_logname
+Normally,
+.Nm sudo
+will set the
+.Ev LOGNAME
+and
+.Ev USER
+environment variables to the name of the target user (usually root unless the
+.Fl u
+option is given).
+However, since some programs (including the RCS revision control system) use
+.Ev LOGNAME
+to determine the real identity of the user, it may be desirable to
+change this behavior.
+This can be done by negating the set_logname option.
+Note that
+.Em set_logname
+will have no effect
+if the
+.Em env_reset
+option has not been disabled and the
+.Em env_keep
+list contains
+.Ev LOGNAME
+or
+.Ev USER .
+This flag is
+.Em on
+by default.
+.It set_utmp
+When enabled,
+.Nm sudo
+will create an entry in the utmp (or utmpx) file when a pseudo-tty
+is allocated.
+A pseudo-tty is allocated by
+.Nm sudo
+when the
+.Em log_input ,
+.Em log_output
+or
+.Em use_pty
+flags are enabled.
+By default, the new entry will be a copy of the user's existing utmp
+entry (if any), with the tty, time, type and pid fields updated.
+This flag is
+.Em on
+by default.
+.It setenv
+Allow the user to disable the
+.Em env_reset
+option from the command line via the
+.Fl E
+option.
+Additionally, environment variables set via the command line are
+not subject to the restrictions imposed by
+.Em env_check ,
+.Em env_delete ,
+or
+.Em env_keep .
+As such, only trusted users should be allowed to set variables in this manner.
+This flag is
+.Em off
+by default.
+.It shell_noargs
+If set and
+.Nm sudo
+is invoked with no arguments it acts as if the
+.Fl s
+option had been given.
+That is, it runs a shell as root (the shell is determined by the
+.Ev SHELL
+environment variable if it is set, falling back on the shell listed
+in the invoking user's /etc/passwd entry if not).
+This flag is
+.Em off
+by default.
+.It stay_setuid
+Normally, when
+.Nm sudo
+executes a command the real and effective UIDs are set to the target
+user (root by default).
+This option changes that behavior such that the real UID is left
+as the invoking user's UID.
+In other words, this makes
+.Nm sudo
+act as a setuid wrapper.
+This can be useful on systems that disable some potentially
+dangerous functionality when a program is run setuid.
+This option is only effective on systems that support either the
+.Xr setreuid 2
+or
+.Xr setresuid 2
+system call.
+This flag is
+.Em off
+by default.
+.It sudoedit_checkdir
+If set,
+.Nm sudoedit
+will check all directory components of the path to be edited for writability
+by the invoking user.
+Symbolic links will not be followed in writable directories and
+.Nm sudoedit
+will refuse to edit a file located in a writable directory.
+These restrictions are not enforced when
+.Nm sudoedit
+is run by root.
+On some systems, if all directory components of the path to be edited
+are not readable by the target user,
+.Nm sudoedit
+will be unable to edit the file.
+This flag is
+.Em on
+by default.
+.Pp
+This setting was first introduced in version 1.8.15 but initially
+suffered from a race condition.
+The check for symbolic links in writable intermediate directories
+was added in version 1.8.16.
+.It sudoedit_follow
+By default,
+.Nm sudoedit
+will not follow symbolic links when opening files.
+The
+.Em sudoedit_follow
+option can be enabled to allow
+.Nm sudoedit
+to open symbolic links.
+It may be overridden on a per-command basis by the
+.Em FOLLOW
+and
+.Em NOFOLLOW
+tags.
+This flag is
+.Em off
+by default.
+.Pp
+This setting is only supported by version 1.8.15 or higher.
+.It syslog_pid
+When logging via
+.Xr syslog 3 ,
+include the process ID in the log entry.
+This flag is
+.Em off
+by default.
+.Pp
+This setting is only supported by version 1.8.21 or higher.
+.It targetpw
+If set,
+.Nm sudo
+will prompt for the password of the user specified
+by the
+.Fl u
+option (defaults to
+.Li root )
+instead of the password of the invoking user
+when running a command or editing a file.
+Note that this flag precludes the use of a uid not listed in the passwd
+database as an argument to the
+.Fl u
+option.
+This flag is
+.Em off
+by default.
+.It tty_tickets
+If set, users must authenticate on a per-tty basis.
+With this flag enabled,
+.Nm sudo
+will use a separate record in the time stamp file for each terminal.
+If disabled, a single record is used for all login sessions.
+.Pp
+This option has been superseded by the
+.Em timestamp_type
+option.
+.It umask_override
+If set,
+.Nm sudo
+will set the umask as specified in the
+.Em sudoers
+file without modification.
+This makes it possible to specify a umask in the
+.Em sudoers
+file that is more permissive than the user's own umask and matches
+historical behavior.
+If
+.Em umask_override
+is not set,
+.Nm sudo
+will set the umask to be the union of the user's umask and what is specified in
+.Em sudoers .
+This flag is
+.Em @umask_override@
+by default.
+.if \n(LC \{\
+.It use_loginclass
+If set,
+.Nm sudo
+will apply the defaults specified for the target user's login class
+if one exists.
+Only available if
+.Nm sudo
+is configured with the
+.Li --with-logincap
+option.
+This flag is
+.Em off
+by default.
+.\}
+.It use_netgroups
+If set, netgroups (prefixed with
+.Ql + ) ,
+may be used in place of a user or host.
+For LDAP-based sudoers, netgroup support requires an expensive
+sub-string match on the server unless the
+.Sy NETGROUP_BASE
+directive is present in the
+.Pa @ldap_conf@
+file.
+If netgroups are not needed, this option can be disabled to reduce the
+load on the LDAP server.
+This flag is
+.Em on
+by default.
+.It use_pty
+If set, and
+.Nm sudo
+is running in a terminal, the command will be run in a pseudo-pty
+(even if no I/O logging is being done).
+If the
+.Nm sudo
+process is not attached to a terminal,
+.Em use_pty
+has no effect.
+.Pp
+A malicious program run under
+.Nm sudo
+may be capable of injecting commands into the user's
+terminal or running a background process that retains access to the
+user's terminal device even after the main program has finished
+executing.
+By running the command in a separate pseudo-pty, this attack is
+no longer possible.
+This flag is
+.Em off
+by default.
+.It user_command_timeouts
+If set, the user may specify a timeout on the command line.
+If the timeout expires before the command has exited, the
+command will be terminated.
+If a timeout is specified both in the
+.Pa sudoers
+file and on the command line, the smaller of the two timeouts will be used.
+See the
+.Li Timeout_Spec
+section for a description of the timeout syntax.
+This flag is
+.Em off
+by default.
+.Pp
+This setting is only supported by version 1.8.20 or higher.
+.It utmp_runas
+If set,
+.Nm sudo
+will store the name of the runas user when updating the utmp (or utmpx) file.
+By default,
+.Nm sudo
+stores the name of the invoking user.
+This flag is
+.Em off
+by default.
+.It visiblepw
+By default,
+.Nm sudo
+will refuse to run if the user must enter a password but it is not
+possible to disable echo on the terminal.
+If the
+.Em visiblepw
+flag is set,
+.Nm sudo
+will prompt for a password even when it would be visible on the screen.
+This makes it possible to run things like
+.Dq Li ssh somehost sudo ls
+since by default,
+.Xr ssh 1
+does
+not allocate a tty when running a command.
+This flag is
+.Em off
+by default.
+.El
+.Pp
+.Sy Integers :
+.Bl -tag -width 16n
+.It closefrom
+Before it executes a command,
+.Nm sudo
+will close all open file descriptors other than standard input,
+standard output and standard error (ie: file descriptors 0-2).
+The
+.Em closefrom
+option can be used to specify a different file descriptor at which
+to start closing.
+The default is
+.Li 3 .
+.It command_timeout
+The maximum amount of time a command is allowed to run before
+it is terminated.
+See the
+.Li Timeout_Spec
+section for a description of the timeout syntax.
+.Pp
+This setting is only supported by version 1.8.20 or higher.
+.It maxseq
+The maximum sequence number that will be substituted for the
+.Dq Li %{seq}
+escape in the I/O log file (see the
+.Em iolog_dir
+description below for more information).
+While the value substituted for
+.Dq Li %{seq}
+is in base 36,
+.Em maxseq
+itself should be expressed in decimal.
+Values larger than 2176782336 (which corresponds to the
+base 36 sequence number
+.Dq ZZZZZZ )
+will be silently truncated to 2176782336.
+The default value is 2176782336.
+.Pp
+Once the local sequence number reaches the value of
+.Em maxseq ,
+it will
+.Dq roll over
+to zero, after which
+.Nm
+will truncate and re-use any existing I/O log path names.
+.Pp
+This setting is only supported by version 1.8.7 or higher.
+.It passwd_tries
+The number of tries a user gets to enter his/her password before
+.Nm sudo
+logs the failure and exits.
+The default is
+.Li @passwd_tries@ .
+.It syslog_maxlen
+On many systems,
+.Xr syslog 3
+has a relatively small log buffer.
+IETF RFC 5424 states that syslog servers must support messages of
+at least 480 bytes and should support messages up to 2048 bytes.
+By default,
+.Nm
+creates log messages up to 980 bytes which corresponds to the
+historic
+.Bx
+syslog implementation which used a 1024 byte buffer
+to store the message, date, hostname and program name.
+To prevent syslog messages from being truncated,
+.Nm
+will split up log messages that are larger than
+.Em syslog_maxlen
+bytes.
+When a message is split, additional parts will include the string
+.Dq Pq command continued
+after the user name and before the continued command line arguments.
+.Pp
+This setting is only supported by version 1.8.19 or higher.
+.El
+.Pp
+.Sy Integers that can be used in a boolean context :
+.Bl -tag -width 16n
+.It loglinelen
+Number of characters per line for the file log.
+This value is used to decide when to wrap lines for nicer log files.
+This has no effect on the syslog log file, only the file log.
+The default is
+.Li @loglen@
+(use 0 or negate the option to disable word wrap).
+.It passwd_timeout
+Number of minutes before the
+.Nm sudo
+password prompt times out, or
+.Li 0
+for no timeout.
+The timeout may include a fractional component
+if minute granularity is insufficient, for example
+.Li 2.5 .
+The
+default is
+.Li @password_timeout@ .
+.It timestamp_timeout
+Number of minutes that can elapse before
+.Nm sudo
+will ask for a passwd again.
+The timeout may include a fractional component if
+minute granularity is insufficient, for example
+.Li 2.5 .
+The default is
+.Li @timeout@ .
+Set this to
+.Li 0
+to always prompt for a password.
+If set to a value less than
+.Li 0
+the user's time stamp will not expire until the system is rebooted.
+This can be used to allow users to create or delete their own time stamps via
+.Dq Li sudo -v
+and
+.Dq Li sudo -k
+respectively.
+.It umask
+Umask to use when running the command.
+Negate this option or set it to 0777 to preserve the user's umask.
+The actual umask that is used will be the union of the user's umask
+and the value of the
+.Em umask
+option, which defaults to
+.Li @sudo_umask@ .
+This guarantees
+that
+.Nm sudo
+never lowers the umask when running a command.
+Note: on systems that use PAM, the default PAM configuration may specify
+its own umask which will override the value set in
+.Em sudoers .
+.El
+.Pp
+.Sy Strings :
+.Bl -tag -width 16n
+.It authfail_message
+Message that is displayed after a user fails to authenticate.
+The message may include the
+.Ql %d
+escape which will expand to the number of failed password attempts.
+If set, it overrides the default message,
+.Li %d incorrect password attempt(s) .
+.It badpass_message
+Message that is displayed if a user enters an incorrect password.
+The default is
+.Li @badpass_message@
+unless insults are enabled.
+.It editor
+A colon
+.Pq Ql :\&
+separated list of editors path names used by
+.Nm sudoedit
+and
+.Nm visudo .
+For
+.Nm sudoedit ,
+this list is used to find an editor when none of the
+.Ev SUDO_EDITOR ,
+.Ev VISUAL
+or
+.Ev EDITOR
+environment variables are set to an editor that exists and is executable.
+For
+.Nm visudo ,
+it is used as a white list of allowed editors;
+.Nm visudo
+will choose the editor that matches the user's
+.Ev SUDO_EDITOR ,
+.Ev VISUAL
+or
+.Ev EDITOR
+environment variable if possible, or the first editor in the
+list that exists and is executable if not.
+Unless invoked as
+.Nm sudoedit ,
+.Nm sudo
+does not preserve the
+.Ev SUDO_EDITOR ,
+.Ev VISUAL
+and
+.Ev EDITOR
+environment variables by default, even when the
+.Em env_reset
+option is enabled.
+The default is
+.Pa @editor@ .
+.It iolog_dir
+The top-level directory to use when constructing the path name for
+the input/output log directory.
+Only used if the
+.Em log_input
+or
+.Em log_output
+options are enabled or when the
+.Li LOG_INPUT
+or
+.Li LOG_OUTPUT
+tags are present for a command.
+The session sequence number, if any, is stored in the directory.
+The default is
+.Pa @iolog_dir@ .
+.Pp
+The following percent
+.Pq Ql %
+escape sequences are supported:
+.Bl -tag -width 4n
+.It Li %{seq}
+expanded to a monotonically increasing base-36 sequence number, such as 0100A5,
+where every two digits are used to form a new directory, e.g.,
+.Pa 01/00/A5
+.It Li %{user}
+expanded to the invoking user's login name
+.It Li %{group}
+expanded to the name of the invoking user's real group ID
+.It Li %{runas_user}
+expanded to the login name of the user the command will
+be run as (e.g., root)
+.It Li %{runas_group}
+expanded to the group name of the user the command will
+be run as (e.g., wheel)
+.It Li %{hostname}
+expanded to the local host name without the domain name
+.It Li %{command}
+expanded to the base name of the command being run
+.El
+.Pp
+In addition, any escape sequences supported by the system's
+.Xr strftime 3
+function will be expanded.
+.Pp
+To include a literal
+.Ql %
+character, the string
+.Ql %%
+should be used.
+.It iolog_file
+The path name, relative to
+.Em iolog_dir ,
+in which to store input/output logs when the
+.Em log_input
+or
+.Em log_output
+options are enabled or when the
+.Li LOG_INPUT
+or
+.Li LOG_OUTPUT
+tags are present for a command.
+Note that
+.Em iolog_file
+may contain directory components.
+The default is
+.Dq Li %{seq} .
+.Pp
+See the
+.Em iolog_dir
+option above for a list of supported percent
+.Pq Ql %
+escape sequences.
+.Pp
+In addition to the escape sequences, path names that end in six or
+more
+.Li X Ns s
+will have the
+.Li X Ns s
+replaced with a unique combination of digits and letters, similar to the
+.Xr mktemp 3
+function.
+.Pp
+If the path created by concatenating
+.Em iolog_dir
+and
+.Em iolog_file
+already exists, the existing I/O log file will be truncated and
+overwritten unless
+.Em iolog_file
+ends in six or
+more
+.Li X Ns s .
+.It iolog_flush
+If set,
+.Nm sudo
+will flush I/O log data to disk after each write instead of buffering it.
+This makes it possible to view the logs in real-time as the program
+is executing but may significantly reduce the effectiveness of I/O
+log compression.
+This flag is
+.Em off
+by default.
+.Pp
+This setting is only supported by version 1.8.20 or higher.
+.It iolog_group
+The group name to look up when setting the group ID on new I/O log
+files and directories.
+If
+.Em iolog_group
+is not set,
+the primary group ID of the user specified by
+.Em iolog_user
+is used.
+If neither
+.Em iolog_group
+nor
+.Em iolog_user
+are set, I/O log files and directories are created with group ID 0.
+.Pp
+This setting is only supported by version 1.8.19 or higher.
+.It iolog_mode
+The file mode to use when creating I/O log files.
+Mode bits for read and write permissions for owner, group or other
+are honored, everything else is ignored.
+The file permissions will always include the owner read and
+write bits, even if they are not present in the specified mode.
+When creating I/O log directories, search (execute) bits are added
+to match the read and write bits specified by
+.Em iolog_mode .
+Defaults to 0600 (read and write by user only).
+.Pp
+This setting is only supported by version 1.8.19 or higher.
+.It iolog_user
+The user name to look up when setting the user and group IDs on new
+I/O log files and directories.
+If
+.Em iolog_group
+is set, it will be used instead of the user's primary group ID.
+By default, I/O log files and directories are created with user and
+group ID 0.
+.Pp
+This setting can be useful when the I/O logs are stored on a Network
+File System (NFS) share.
+Having a dedicated user own the I/O log files means that
+.Nm
+does not write to the log files as user ID 0, which is usually
+not permitted by NFS.
+.Pp
+This setting is only supported by version 1.8.19 or higher.
+.It lecture_status_dir
+The directory in which
+.Nm sudo
+stores per-user lecture status files.
+Once a user has received the lecture, a zero-length file is
+created in this directory so that
+.Nm sudo
+will not lecture the user again.
+This directory should
+.Em not
+be cleared when the system reboots.
+The default is
+.Pa @vardir@/lectured .
+.if \n(PS \{\
+.It limitprivs
+The default Solaris limit privileges to use when constructing a new
+privilege set for a command.
+This bounds all privileges of the executing process.
+The default limit privileges may be overridden on a per-command basis in
+.Em sudoers .
+This option is only available if
+.Nm
+is built on Solaris 10 or higher.
+.\}
+.It mailsub
+Subject of the mail sent to the
+.Em mailto
+user.
+The escape
+.Li %h
+will expand to the host name of the machine.
+Default is
+.Dq Li @mailsub@ .
+.It noexec_file
+As of
+.Nm sudo
+version 1.8.1 this option is no longer supported.
+The path to the noexec file should now be set in the
+.Xr sudo.conf @mansectform@
+file.
+.It pam_login_service
+On systems that use PAM for authentication, this is the service
+name used when the
+.Fl i
+option is specified.
+The default value is
+.Dq Li @pam_login_service@ .
+See the description of
+.Em pam_service
+for more information.
+.Pp
+This setting is only supported by version 1.8.8 or higher.
+.It pam_service
+On systems that use PAM for authentication, the service name
+specifies the PAM policy to apply.
+This usually corresponds to an entry in the
+.Pa pam.conf
+file or a file in the
+.Pa /etc/pam.d
+directory.
+The default value is
+.Dq Li sudo .
+.Pp
+This setting is only supported by version 1.8.8 or higher.
+.It passprompt
+The default prompt to use when asking for a password; can be overridden via the
+.Fl p
+option or the
+.Ev SUDO_PROMPT
+environment variable.
+The following percent
+.Pq Ql %
+escape sequences are supported:
+.Bl -tag -width 4n
+.It Li %H
+expanded to the local host name including the domain name
+(only if the machine's host name is fully qualified or the
+.Em fqdn
+option is set)
+.It Li %h
+expanded to the local host name without the domain name
+.It Li %p
+expanded to the user whose password is being asked for (respects the
+.Em rootpw ,
+.Em targetpw
+and
+.Em runaspw
+flags in
+.Em sudoers )
+.It Li \&%U
+expanded to the login name of the user the command will
+be run as (defaults to root)
+.It Li %u
+expanded to the invoking user's login name
+.It Li %%
+two consecutive
+.Li %
+characters are collapsed into a single
+.Li %
+character
+.El
+.Pp
+On systems that use PAM for authentication,
+.Em passprompt
+will only be used if the prompt provided by the PAM module matches the string
+.Dq "Password: "
+or
+.Dq "username's Password: " .
+This ensures that the
+.Em passprompt
+setting does not interfere with challenge-response style authentication.
+The
+.Em passprompt_override
+flag can be used to change this behavior.
+.Pp
+The default value is
+.Dq Li "@passprompt@" .
+.if \n(PS \{\
+.It privs
+The default Solaris privileges to use when constructing a new
+privilege set for a command.
+This is passed to the executing process via the inherited privilege set,
+but is bounded by the limit privileges.
+If the
+.Em privs
+option is specified but the
+.Em limitprivs
+option is not, the limit privileges of the executing process is set to
+.Em privs .
+The default privileges may be overridden on a per-command basis in
+.Em sudoers .
+This option is only available if
+.Nm
+is built on Solaris 10 or higher.
+.\}
+.if \n(SL \{\
+.It role
+The default SELinux role to use when constructing a new security
+context to run the command.
+The default role may be overridden on a per-command basis in the
+.Em sudoers
+file or via command line options.
+This option is only available when
+.Nm sudo
+is built with SELinux support.
+.\}
+.It runas_default
+The default user to run commands as if the
+.Fl u
+option is not specified on the command line.
+This defaults to
+.Li @runas_default@ .
+.It sudoers_locale
+Locale to use when parsing the sudoers file, logging commands, and
+sending email.
+Note that changing the locale may affect how sudoers is interpreted.
+Defaults to
+.Dq Li C .
+.It timestamp_type
+.Nm sudoers
+uses per-user time stamp files for credential caching.
+The
+.Em timestamp_type
+option can be used to specify the type of time stamp record used.
+It has the following possible values:
+.Bl -tag -width 6n
+.It global
+A single time stamp record is used for all of a user's login sessions,
+regardless of the terminal or parent process ID.
+An additional record is used to serialize password prompts when
+.Nm sudo
+is used multiple times in a pipeline, but this does not affect authentication.
+.It ppid
+A single time stamp record is used for all processes with the same parent
+process ID (usually the shell).
+Commands run from the same shell (or other common parent process)
+will not require a password for
+.Em timestamp_timeout
+minutes
+.Po
+.Li @timeout@
+by default
+.Pc .
+Commands run via
+.Nm sudo
+with a different parent process ID, for example from a shell script,
+will be authenticated separately.
+.It tty
+One time stamp record is used for each terminal,
+which means that a user's login sessions are authenticated separately.
+If no terminal is present, the behavior is the same as
+.Em ppid .
+Commands run from the same terminal will not require a password for
+.Em timestamp_timeout
+minutes
+.Po
+.Li @timeout@
+by default
+.Pc .
+.It kernel
+The time stamp is stored in the kernel as an attribute of the terminal
+device.
+If no terminal is present, the behavior is the same as
+.Em ppid .
+Negative
+.Em timestamp_timeout
+values are not supported and positive values are limited to a maximum
+of 60 minutes.
+This is currently only supported on
+.Ox .
+.El
+.Pp
+The default value is
+.Em @timestamp_type@ .
+.Pp
+This setting is only supported by version 1.8.21 or higher.
+.It timestampdir
+The directory in which
+.Nm sudo
+stores its time stamp files.
+This directory should be cleared when the system reboots.
+The default is
+.Pa @rundir@/ts .
+.It timestampowner
+The owner of the lecture status directory, time stamp directory and all
+files stored therein.
+The default is
+.Li root .
+.if \n(SL \{\
+.It type
+The default SELinux type to use when constructing a new security
+context to run the command.
+The default type may be overridden on a per-command basis in the
+.Em sudoers
+file or via command line options.
+This option is only available when
+.Nm sudo
+is built with SELinux support.
+.\}
+.El
+.Pp
+.Sy Strings that can be used in a boolean context :
+.Bl -tag -width 12n
+.It env_file
+The
+.Em env_file
+option specifies the fully qualified path to a file containing variables
+to be set in the environment of the program being run.
+Entries in this file should either be of the form
+.Dq Li VARIABLE=value
+or
+.Dq Li export VARIABLE=value .
+The value may optionally be surrounded by single or double quotes.
+Variables in this file are only added if the variable does not already
+exist in the environment.
+This file is considered to be part of the security policy,
+its contents are not subject to other
+.Nm sudo
+environment restrictions such as
+.Em env_keep
+and
+.Em env_check .
+.It exempt_group
+Users in this group are exempt from password and PATH requirements.
+The group name specified should not include a
+.Li %
+prefix.
+This is not set by default.
+.It fdexec
+Determines whether
+.Nm sudo
+will execute a command by its path or by an open file descriptor.
+It has the following possible values:
+.Bl -tag -width 6n
+.It always
+Always execute by file descriptor.
+.It never
+Never execute by file descriptor.
+.It digest_only
+Only execute by file descriptor if the command has an associated digest
+in the
+.Em sudoers
+file.
+.El
+.Pp
+The default value is
+.Em digest_only .
+This avoids a time of check versus time of use race condition when
+the command is located in a directory writable by the invoking user.
+.Pp
+Note that
+.Em fdexec
+will change the first element of the argument vector for scripts
+($0 in the shell) due to the way the kernel runs script interpreters.
+Instead of being a normal path, it will refer to a file descriptor.
+For example,
+.Pa /dev/fd/4
+on Solaris and
+.Pa /proc/self/fd/4
+on Linux.
+A workaround is to use the
+.Dv SUDO_COMMAND
+environment variable instead.
+.Pp
+The
+.Em fdexec
+setting is only used when the command is matched by path name.
+It has no effect if the command is matched by the built-in
+.Sy ALL
+alias.
+.Pp
+This setting is only supported by version 1.8.20 or higher.
+If the operating system does not support the
+.Xr fexecve 2
+system call, this setting has no effect.
+.It group_plugin
+A string containing a
+.Nm sudoers
+group plugin with optional arguments.
+The string should consist of the plugin
+path, either fully-qualified or relative to the
+.Pa @PLUGINDIR@
+directory, followed by any configuration arguments the plugin requires.
+These arguments (if any) will be passed to the plugin's initialization function.
+If arguments are present, the string must be enclosed in double quotes
+.Pq \&"" .
+.Pp
+For more information see
+.Sx "GROUP PROVIDER PLUGINS" .
+.It lecture
+This option controls when a short lecture will be printed along with
+the password prompt.
+It has the following possible values:
+.Bl -tag -width 6n
+.It always
+Always lecture the user.
+.It never
+Never lecture the user.
+.It once
+Only lecture the user the first time they run
+.Nm sudo .
+.El
+.Pp
+If no value is specified, a value of
+.Em once
+is implied.
+Negating the option results in a value of
+.Em never
+being used.
+The default value is
+.Em @lecture@ .
+.It lecture_file
+Path to a file containing an alternate
+.Nm sudo
+lecture that will be used in place of the standard lecture if the named
+file exists.
+By default,
+.Nm sudo
+uses a built-in lecture.
+.It listpw
+This option controls when a password will be required when a user runs
+.Nm sudo
+with the
+.Fl l
+option.
+It has the following possible values:
+.Bl -tag -width 8n
+.It all
+All the user's
+.Em sudoers
+file entries for the current host must have
+the
+.Li NOPASSWD
+flag set to avoid entering a password.
+.It always
+The user must always enter a password to use the
+.Fl l
+option.
+.It any
+At least one of the user's
+.Em sudoers
+file entries for the current host
+must have the
+.Li NOPASSWD
+flag set to avoid entering a password.
+.It never
+The user need never enter a password to use the
+.Fl l
+option.
+.El
+.Pp
+If no value is specified, a value of
+.Em any
+is implied.
+Negating the option results in a value of
+.Em never
+being used.
+The default value is
+.Em any .
+.It logfile
+Path to the
+.Nm sudo
+log file (not the syslog log file).
+Setting a path turns on logging to a file;
+negating this option turns it off.
+By default,
+.Nm sudo
+logs via syslog.
+.It mailerflags
+Flags to use when invoking mailer.
+Defaults to
+.Fl t .
+.It mailerpath
+Path to mail program used to send warning mail.
+Defaults to the path to sendmail found at configure time.
+.It mailfrom
+Address to use for the
+.Dq from
+address when sending warning and error mail.
+The address should be enclosed in double quotes
+.Pq \&""
+to protect against
+.Nm sudo
+interpreting the
+.Li @
+sign.
+Defaults to the name of the user running
+.Nm sudo .
+.It mailto
+Address to send warning and error mail to.
+The address should be enclosed in double quotes
+.Pq \&""
+to protect against
+.Nm sudo
+interpreting the
+.Li @
+sign.
+Defaults to
+.Li @mailto@ .
+.It restricted_env_file
+The
+.Em restricted_env_file
+option specifies the fully qualified path to a file containing variables
+to be set in the environment of the program being run.
+Entries in this file should either be of the form
+.Dq Li VARIABLE=value
+or
+.Dq Li export VARIABLE=value .
+The value may optionally be surrounded by single or double quotes.
+Variables in this file are only added if the variable does not already
+exist in the environment.
+Unlike
+.Em env_file ,
+the file's contents are not trusted and are processed in a manner
+similar to that of the invoking user's environment.
+If
+.Em env_reset
+is enabled, variables in the file will only be added if they are
+matched by either the
+.Em env_check
+or
+.Em env_keep
+list.
+If
+.Em env_reset
+is disabled, variables in the file are added as long as they
+are not matched by the
+.Em env_delete
+list.
+In either case, the contents of
+.Em restricted_env_file
+are processed before the contents of
+.Em env_file .
+.It secure_path
+Path used for every command run from
+.Nm sudo .
+If you don't trust the
+people running
+.Nm sudo
+to have a sane
+.Ev PATH
+environment variable you may want to use this.
+Another use is if you want to have the
+.Dq root path
+be separate from the
+.Dq user path .
+Users in the group specified by the
+.Em exempt_group
+option are not affected by
+.Em secure_path .
+This option is @secure_path@ by default.
+.It syslog
+Syslog facility if syslog is being used for logging (negate to
+disable syslog logging).
+Defaults to
+.Li @logfac@ .
+.Pp
+The following syslog facilities are supported:
+.Sy authpriv
+(if your
+OS supports it),
+.Sy auth ,
+.Sy daemon ,
+.Sy user ,
+.Sy local0 ,
+.Sy local1 ,
+.Sy local2 ,
+.Sy local3 ,
+.Sy local4 ,
+.Sy local5 ,
+.Sy local6 ,
+and
+.Sy local7 .
+.It syslog_badpri
+Syslog priority to use when the user is not allowed to run a command or
+when authentication is unsuccessful.
+Defaults to
+.Li @badpri@ .
+.Pp
+The following syslog priorities are supported:
+.Sy alert ,
+.Sy crit ,
+.Sy debug ,
+.Sy emerg ,
+.Sy err ,
+.Sy info ,
+.Sy notice ,
+.Sy warning ,
+and
+.Sy none .
+Negating the option or setting it to a value of
+.Sy none
+will disable logging of unsuccessful commands.
+.It syslog_goodpri
+Syslog priority to use when the user is allowed to run a command and
+authentication is successful.
+Defaults to
+.Li @goodpri@ .
+.Pp
+See
+.Em syslog_badpri
+for the list of supported syslog priorities.
+Negating the option or setting it to a value of
+.Sy none
+will disable logging of successful commands.
+.It verifypw
+This option controls when a password will be required when a user runs
+.Nm sudo
+with the
+.Fl v
+option.
+It has the following possible values:
+.Bl -tag -width 6n
+.It all
+All the user's
+.Em sudoers
+file entries for the current host must have the
+.Li NOPASSWD
+flag set to avoid entering a password.
+.It always
+The user must always enter a password to use the
+.Fl v
+option.
+.It any
+At least one of the user's
+.Em sudoers
+file entries for the current host must have the
+.Li NOPASSWD
+flag set to avoid entering a password.
+.It never
+The user need never enter a password to use the
+.Fl v
+option.
+.El
+.Pp
+If no value is specified, a value of
+.Em all
+is implied.
+Negating the option results in a value of
+.Em never
+being used.
+The default value is
+.Em all .
+.El
+.Pp
+.Sy Lists that can be used in a boolean context :
+.Bl -tag -width 16n
+.It env_check
+Environment variables to be removed from the user's environment
+unless they are considered
+.Dq safe .
+For all variables except
+.Li TZ ,
+.Dq safe
+means that the variable's value does not contain any
+.Ql %
+or
+.Ql /
+characters.
+This can be used to guard against printf-style format vulnerabilities
+in poorly-written programs.
+The
+.Li TZ
+variable is considered unsafe if any of the following are true:
+.Bl -bullet -width 1n
+.It
+It consists of a fully-qualified path name,
+optionally prefixed with a colon
+.Pq Ql :\& ,
+that does not match the location of the
+.Pa zoneinfo
+directory.
+.It
+It contains a
+.Pa ..
+path element.
+.It
+It contains white space or non-printable characters.
+.It
+It is longer than the value of
+.Li PATH_MAX .
+.El
+.Pp
+The argument may be a double-quoted, space-separated list or a
+single value without double-quotes.
+The list can be replaced, added to, deleted from, or disabled by using
+the
+.Li = ,
+.Li += ,
+.Li -= ,
+and
+.Li \&!
+operators respectively.
+Regardless of whether the
+.Li env_reset
+option is enabled or disabled, variables specified by
+.Li env_check
+will be preserved in the environment if they pass the aforementioned check.
+The global list of environment variables to check is displayed when
+.Nm sudo
+is run by root with
+the
+.Fl V
+option.
+.It env_delete
+Environment variables to be removed from the user's environment when the
+.Em env_reset
+option is not in effect.
+The argument may be a double-quoted, space-separated list or a
+single value without double-quotes.
+The list can be replaced, added to, deleted from, or disabled by using the
+.Li = ,
+.Li += ,
+.Li -= ,
+and
+.Li \&!
+operators respectively.
+The global list of environment variables to remove is displayed when
+.Nm sudo
+is run by root with the
+.Fl V
+option.
+Note that many operating systems will remove potentially dangerous
+variables from the environment of any setuid process (such as
+.Nm sudo ) .
+.It env_keep
+Environment variables to be preserved in the user's environment when the
+.Em env_reset
+option is in effect.
+This allows fine-grained control over the environment
+.Nm sudo Ns -spawned
+processes will receive.
+The argument may be a double-quoted, space-separated list or a
+single value without double-quotes.
+The list can be replaced, added to, deleted from, or disabled by using the
+.Li = ,
+.Li += ,
+.Li -= ,
+and
+.Li \&!
+operators respectively.
+The global list of variables to keep
+is displayed when
+.Nm sudo
+is run by root with the
+.Fl V
+option.
+.El
+.Sh GROUP PROVIDER PLUGINS
+The
+.Nm
+plugin supports its own plugin interface to allow non-Unix
+group lookups which can query a group source other
+than the standard Unix group database.
+This can be used to implement support for the
+.Li nonunix_group
+syntax described earlier.
+.Pp
+Group provider plugins are specified via the
+.Em group_plugin
+Defaults setting.
+The argument to
+.Em group_plugin
+should consist of the plugin path, either fully-qualified or relative to the
+.Pa @PLUGINDIR@
+directory, followed by any configuration options the plugin requires.
+These options (if specified) will be passed to the plugin's initialization
+function.
+If options are present, the string must be enclosed in double quotes
+.Pq \&"" .
+.Pp
+The following group provider plugins are installed by default:
+.Bl -tag -width 8n
+.It group_file
+The
+.Em group_file
+plugin supports an alternate group file that uses the same syntax as the
+.Pa /etc/group
+file.
+The path to the group file should be specified as an option
+to the plugin.
+For example, if the group file to be used is
+.Pa /etc/sudo-group :
+.Bd -literal
+Defaults group_plugin="group_file.so /etc/sudo-group"
+.Ed
+.It system_group
+The
+.Em system_group
+plugin supports group lookups via the standard C library functions
+.Fn getgrnam
+and
+.Fn getgrid .
+This plugin can be used in instances where the user belongs to
+groups not present in the user's supplemental group vector.
+This plugin takes no options:
+.Bd -literal
+Defaults group_plugin=system_group.so
+.Ed
+.El
+.Pp
+The group provider plugin API is described in detail in
+.Xr sudo_plugin @mansectform@ .
+.Sh LOG FORMAT
+.Nm
+can log events using either
+.Xr syslog 3
+or a simple log file.
+The log format is almost identical in both cases.
+.Ss Accepted command log entries
+Commands that sudo runs are logged using the following format (split
+into multiple lines for readability):
+.Bd -literal -offset 4n
+date hostname progname: username : TTY=ttyname ; PWD=cwd ; \e
+ USER=runasuser ; GROUP=runasgroup ; TSID=logid ; \e
+ ENV=env_vars COMMAND=command
+.Ed
+.Pp
+Where the fields are as follows:
+.Bl -tag -width 12n
+.It date
+The date the command was run.
+Typically, this is in the format
+.Dq MMM, DD, HH:MM:SS .
+If logging via
+.Xr syslog 3 ,
+the actual date format is controlled by the syslog daemon.
+If logging to a file and the
+.Em log_year
+option is enabled,
+the date will also include the year.
+.It hostname
+The name of the host
+.Nm sudo
+was run on.
+This field is only present when logging via
+.Xr syslog 3 .
+.It progname
+The name of the program, usually
+.Em sudo
+or
+.Em sudoedit .
+This field is only present when logging via
+.Xr syslog 3 .
+.It username
+The login name of the user who ran
+.Nm sudo .
+.It ttyname
+The short name of the terminal (e.g.,
+.Dq console ,
+.Dq tty01 ,
+or
+.Dq pts/0 )
+.Nm sudo
+was run on, or
+.Dq unknown
+if there was no terminal present.
+.It cwd
+The current working directory that
+.Nm sudo
+was run in.
+.It runasuser
+The user the command was run as.
+.It runasgroup
+The group the command was run as if one was specified on the command line.
+.It logid
+An I/O log identifier that can be used to replay the command's output.
+This is only present when the
+.Em log_input
+or
+.Em log_output
+option is enabled.
+.It env_vars
+A list of environment variables specified on the command line,
+if specified.
+.It command
+The actual command that was executed.
+.El
+.Pp
+Messages are logged using the locale specified by
+.Em sudoers_locale ,
+which defaults to the
+.Dq Li C
+locale.
+.Ss Denied command log entries
+If the user is not allowed to run the command, the reason for the denial
+will follow the user name.
+Possible reasons include:
+.Bl -tag -width 4
+.It user NOT in sudoers
+The user is not listed in the
+.Em sudoers
+file.
+.It user NOT authorized on host
+The user is listed in the
+.Em sudoers
+file but is not allowed to run commands on the host.
+.It command not allowed
+The user is listed in the
+.Em sudoers
+file for the host but they are not allowed to run the specified command.
+.It 3 incorrect password attempts
+The user failed to enter their password after 3 tries.
+The actual number of tries will vary based on the number of
+failed attempts and the value of the
+.Em passwd_tries
+option.
+.It a password is required
+.Nm sudo Ns 's
+.Fl n
+option was specified but a password was required.
+.It sorry, you are not allowed to set the following environment variables
+The user specified environment variables on the command line that
+were not allowed by
+.Em sudoers .
+.El
+.Ss Error log entries
+If an error occurs,
+.Nm
+will log a message and, in most cases, send a message to the
+administrator via email.
+Possible errors include:
+.Bl -tag -width 4
+.It parse error in @sysconfdir@/sudoers near line N
+.Nm
+encountered an error when parsing the specified file.
+In some cases, the actual error may be one line above or below the
+line number listed, depending on the type of error.
+.It problem with defaults entries
+The
+.Em sudoers
+file contains one or more unknown Defaults settings.
+This does not prevent
+.Nm sudo
+from running, but the
+.Em sudoers
+file should be checked using
+.Nm visudo .
+.It timestamp owner (username): \&No such user
+The time stamp directory owner, as specified by the
+.Em timestampowner
+setting, could not be found in the password database.
+.It unable to open/read @sysconfdir@/sudoers
+The
+.Em sudoers
+file could not be opened for reading.
+This can happen when the
+.Em sudoers
+file is located on a remote file system that maps user ID 0 to
+a different value.
+Normally,
+.Nm
+tries to open the
+.Em sudoers
+file using group permissions to avoid this problem.
+Consider either changing the ownership of
+.Pa @sysconfdir@/sudoers
+or adding an argument like
+.Dq sudoers_uid=N
+(where
+.Sq N
+is the user ID that owns the
+.Em sudoers
+file) to the end of the
+.Nm
+.Li Plugin
+line in the
+.Xr sudo.conf @mansectform@
+file.
+.It unable to stat @sysconfdir@/sudoers
+The
+.Pa @sysconfdir@/sudoers
+file is missing.
+.It @sysconfdir@/sudoers is not a regular file
+The
+.Pa @sysconfdir@/sudoers
+file exists but is not a regular file or symbolic link.
+.It @sysconfdir@/sudoers is owned by uid N, should be 0
+The
+.Em sudoers
+file has the wrong owner.
+If you wish to change the
+.Em sudoers
+file owner, please add
+.Dq sudoers_uid=N
+(where
+.Sq N
+is the user ID that owns the
+.Em sudoers
+file) to the
+.Nm
+.Li Plugin
+line in the
+.Xr sudo.conf @mansectform@
+file.
+.It @sysconfdir@/sudoers is world writable
+The permissions on the
+.Em sudoers
+file allow all users to write to it.
+The
+.Em sudoers
+file must not be world-writable, the default file mode
+is 0440 (readable by owner and group, writable by none).
+The default mode may be changed via the
+.Dq sudoers_mode
+option to the
+.Nm
+.Li Plugin
+line in the
+.Xr sudo.conf @mansectform@
+file.
+.It @sysconfdir@/sudoers is owned by gid N, should be 1
+The
+.Em sudoers
+file has the wrong group ownership.
+If you wish to change the
+.Em sudoers
+file group ownership, please add
+.Dq sudoers_gid=N
+(where
+.Sq N
+is the group ID that owns the
+.Em sudoers
+file) to the
+.Nm
+.Li Plugin
+line in the
+.Xr sudo.conf @mansectform@
+file.
+.It unable to open @rundir@/ts/username
+.Nm sudoers
+was unable to read or create the user's time stamp file.
+This can happen when
+.Em timestampowner
+is set to a user other than root and the mode on
+.Pa @rundir@
+is not searchable by group or other.
+The default mode for
+.Pa @rundir@
+is 0711.
+.It unable to write to @rundir@/ts/username
+.Nm sudoers
+was unable to write to the user's time stamp file.
+.It @rundir@/ts is owned by uid X, should be Y
+The time stamp directory is owned by a user other than
+.Em timestampowner .
+This can occur when the value of
+.Em timestampowner
+has been changed.
+.Nm sudoers
+will ignore the time stamp directory until the owner is corrected.
+.It @rundir@/ts is group writable
+The time stamp directory is group-writable; it should be writable only by
+.Em timestampowner .
+The default mode for the time stamp directory is 0700.
+.Nm sudoers
+will ignore the time stamp directory until the mode is corrected.
+.El
+.Ss Notes on logging via syslog
+By default,
+.Nm sudoers
+logs messages via
+.Xr syslog 3 .
+The
+.Em date ,
+.Em hostname ,
+and
+.Em progname
+fields are added by the system's
+.Fn syslog
+function, not
+.Nm
+itself.
+As such, they may vary in format on different systems.
+.Pp
+The maximum size of syslog messages varies from system to system.
+The
+.Em syslog_maxlen
+setting can be used to change the maximum syslog message size
+from the default value of 980 bytes.
+For more information, see the description of
+.Em syslog_maxlen .
+.Ss Notes on logging to a file
+If the
+.Em logfile
+option is set,
+.Nm sudoers
+will log to a local file, such as
+.Pa /var/log/sudo .
+When logging to a file,
+.Nm sudoers
+uses a format similar to
+.Xr syslog 3 ,
+with a few important differences:
+.Bl -enum
+.It
+The
+.Em progname
+and
+.Em hostname
+fields are not present.
+.It
+If the
+.Em log_year
+option is enabled,
+the date will also include the year.
+.It
+Lines that are longer than
+.Em loglinelen
+characters (80 by default) are word-wrapped and continued on the
+next line with a four character indent.
+This makes entries easier to read for a human being, but makes it
+more difficult to use
+.Xr grep 1
+on the log files.
+If the
+.Em loglinelen
+option is set to 0 (or negated with a
+.Ql \&! ) ,
+word wrap will be disabled.
+.El
+.Sh I/O LOG FILES
+When I/O logging is enabled,
+.Nm sudo
+will run the command in a pseudo-tty and log all user input and/or output,
+depending on which options are enabled.
+I/O is logged to the directory specified by the
+.Em iolog_dir
+option
+.Po
+.Pa @iolog_dir@
+by default
+.Pc
+using a unique session ID that is included in the
+.Nm sudo
+log line, prefixed with
+.Dq Li TSID= .
+The
+.Em iolog_file
+option may be used to control the format of the session ID.
+.Pp
+Each I/O log is stored in a separate directory that contains the
+following files:
+.Bl -tag -width 8n
+.It Pa log
+a text file containing the time the command was run, the name of the user
+who ran
+.Nm sudo ,
+the name of the target user, the name of the target group (optional),
+the terminal that
+.Nm sudo
+was run from, the number of rows and columns of the terminal,
+the working directory the command was run from and the path name of
+the command itself (with arguments if present)
+.It Pa timing
+a log of the amount of time between, and the number of bytes in, each
+I/O log entry (used for session playback)
+.It Pa ttyin
+input from the user's tty (what the user types)
+.It Pa stdin
+input from a pipe or file
+.It Pa ttyout
+output from the pseudo-tty (what the command writes to the screen)
+.It Pa stdout
+standard output to a pipe or redirected to a file
+.It Pa stderr
+standard error to a pipe or redirected to a file
+.El
+.Pp
+All files other than
+.Pa log
+are compressed in gzip format unless the
+.Em compress_io
+flag has been disabled.
+Due to buffering, it is not normally possible to display the I/O logs in
+real-time as the program is executing
+The I/O log data will not be complete until the program run by
+.Nm sudo
+has exited or has been terminated by a signal.
+The
+.Em iolog_flush
+flag can be used to disable buffering, in which case I/O log data
+is written to disk as soon as it is available.
+The output portion of an I/O log file can be viewed with the
+.Xr sudoreplay @mansectsu@
+utility, which can also be used to list or search the available logs.
+.Pp
+Note that user input may contain sensitive information such as
+passwords (even if they are not echoed to the screen), which will
+be stored in the log file unencrypted.
+In most cases, logging the command output via
+.Em log_output
+or
+.Li LOG_OUTPUT
+is all that is required.
+.Pp
+Since each session's I/O logs are stored in a separate directory,
+traditional log rotation utilities cannot be used to limit the
+number of I/O logs.
+The simplest way to limit the number of I/O is by setting the
+.Em maxseq
+option to the maximum number of logs you wish to store.
+Once the I/O log sequence number reaches
+.Em maxseq ,
+it will be reset to zero and
+.Nm
+will truncate and re-use any existing I/O logs.
+.Sh FILES
+.Bl -tag -width 24n
+.It Pa @sysconfdir@/sudo.conf
+Sudo front end configuration
+.It Pa @sysconfdir@/sudoers
+List of who can run what
+.It Pa /etc/group
+Local groups file
+.It Pa /etc/netgroup
+List of network groups
+.It Pa @iolog_dir@
+I/O log files
+.It Pa @rundir@/ts
+Directory containing time stamps for the
+.Nm sudoers
+security policy
+.It Pa @vardir@/lectured
+Directory containing lecture status files for the
+.Nm sudoers
+security policy
+.It Pa /etc/environment
+Initial environment for
+.Fl i
+mode on AIX and Linux systems
+.El
+.Sh EXAMPLES
+Below are example
+.Em sudoers
+file entries.
+Admittedly, some of these are a bit contrived.
+First, we allow a few environment variables to pass and then define our
+.Em aliases :
+.Bd -literal
+# Run X applications through sudo; HOME is used to find the
+# .Xauthority file. Note that other programs use HOME to find
+# configuration files and this may lead to privilege escalation!
+Defaults env_keep += "DISPLAY HOME"
+
+# User alias specification
+User_Alias FULLTIMERS = millert, mikef, dowdy
+User_Alias PARTTIMERS = bostley, jwfox, crawl
+User_Alias WEBMASTERS = will, wendy, wim
+
+# Runas alias specification
+Runas_Alias OP = root, operator
+Runas_Alias DB = oracle, sybase
+Runas_Alias ADMINGRP = adm, oper
+
+# Host alias specification
+Host_Alias SPARC = bigtime, eclipse, moet, anchor :\e
+ SGI = grolsch, dandelion, black :\e
+ ALPHA = widget, thalamus, foobar :\e
+ HPPA = boa, nag, python
+Host_Alias CUNETS = 128.138.0.0/255.255.0.0
+Host_Alias CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0
+Host_Alias SERVERS = master, mail, www, ns
+Host_Alias CDROM = orion, perseus, hercules
+
+# Cmnd alias specification
+Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\e
+ /usr/sbin/restore, /usr/sbin/rrestore,\e
+ sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \e
+ /home/operator/bin/start_backups
+Cmnd_Alias KILL = /usr/bin/kill
+Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
+Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown
+Cmnd_Alias HALT = /usr/sbin/halt
+Cmnd_Alias REBOOT = /usr/sbin/reboot
+Cmnd_Alias SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh,\e
+ /usr/local/bin/tcsh, /usr/bin/rsh,\e
+ /usr/local/bin/zsh
+Cmnd_Alias SU = /usr/bin/su
+Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+.Ed
+.Pp
+Here we override some of the compiled in default values.
+We want
+.Nm sudo
+to log via
+.Xr syslog 3
+using the
+.Em auth
+facility in all cases.
+We don't want to subject the full time staff to the
+.Nm sudo
+lecture, user
+.Sy millert
+need not give a password, and we don't want to reset the
+.Ev LOGNAME
+or
+.Ev USER
+environment variables when running commands as root.
+Additionally, on the machines in the
+.Em SERVERS
+.Li Host_Alias ,
+we keep an additional local log file and make sure we log the year
+in each log line since the log entries will be kept around for several years.
+Lastly, we disable shell escapes for the commands in the PAGERS
+.Li Cmnd_Alias
+.Po
+.Pa /usr/bin/more ,
+.Pa /usr/bin/pg
+and
+.Pa /usr/bin/less
+.Pc .
+Note that this will not effectively constrain users with
+.Nm sudo
+.Sy ALL
+privileges.
+.Bd -literal
+# Override built-in defaults
+Defaults syslog=auth
+Defaults>root !set_logname
+Defaults:FULLTIMERS !lecture
+Defaults:millert !authenticate
+Defaults@SERVERS log_year, logfile=/var/log/sudo.log
+Defaults!PAGERS noexec
+.Ed
+.Pp
+The
+.Em User specification
+is the part that actually determines who may run what.
+.Bd -literal
+root ALL = (ALL) ALL
+%wheel ALL = (ALL) ALL
+.Ed
+.Pp
+We let
+.Sy root
+and any user in group
+.Sy wheel
+run any command on any host as any user.
+.Bd -literal
+FULLTIMERS ALL = NOPASSWD: ALL
+.Ed
+.Pp
+Full time sysadmins
+.Po
+.Sy millert ,
+.Sy mikef ,
+and
+.Sy dowdy
+.Pc
+may run any command on any host without authenticating themselves.
+.Bd -literal
+PARTTIMERS ALL = ALL
+.Ed
+.Pp
+Part time sysadmins
+.Sy bostley ,
+.Sy jwfox ,
+and
+.Sy crawl )
+may run any command on any host but they must authenticate themselves
+first (since the entry lacks the
+.Li NOPASSWD
+tag).
+.Bd -literal
+jack CSNETS = ALL
+.Ed
+.Pp
+The user
+.Sy jack
+may run any command on the machines in the
+.Em CSNETS
+alias (the networks
+.Li 128.138.243.0 ,
+.Li 128.138.204.0 ,
+and
+.Li 128.138.242.0 ) .
+Of those networks, only
+.Li 128.138.204.0
+has an explicit netmask (in CIDR notation) indicating it is a class C network.
+For the other networks in
+.Em CSNETS ,
+the local machine's netmask will be used during matching.
+.Bd -literal
+lisa CUNETS = ALL
+.Ed
+.Pp
+The user
+.Sy lisa
+may run any command on any host in the
+.Em CUNETS
+alias (the class B network
+.Li 128.138.0.0 ) .
+.Bd -literal
+operator ALL = DUMPS, KILL, SHUTDOWN, HALT, REBOOT, PRINTING,\e
+ sudoedit /etc/printcap, /usr/oper/bin/
+.Ed
+.Pp
+The
+.Sy operator
+user may run commands limited to simple maintenance.
+Here, those are commands related to backups, killing processes, the
+printing system, shutting down the system, and any commands in the
+directory
+.Pa /usr/oper/bin/ .
+Note that one command in the
+.Li DUMPS
+Cmnd_Alias includes a sha224 digest,
+.Pa /home/operator/bin/start_backups .
+This is because the directory containing the script is writable by the
+operator user.
+If the script is modified (resulting in a digest mismatch) it will no longer
+be possible to run it via
+.Nm sudo .
+.Bd -literal
+joe ALL = /usr/bin/su operator
+.Ed
+.Pp
+The user
+.Sy joe
+may only
+.Xr su 1
+to operator.
+.Bd -literal
+pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd *root*
+
+%opers ALL = (: ADMINGRP) /usr/sbin/
+.Ed
+.Pp
+Users in the
+.Sy opers
+group may run commands in
+.Pa /usr/sbin/
+as themselves
+with any group in the
+.Em ADMINGRP
+.Li Runas_Alias
+(the
+.Sy adm
+and
+.Sy oper
+groups).
+.Pp
+The user
+.Sy pete
+is allowed to change anyone's password except for
+root on the
+.Em HPPA
+machines.
+Because command line arguments are matched as a single,
+concatenated string, the
+.Ql *
+wildcard will match
+.Em multiple
+words.
+This example assumes that
+.Xr passwd 1
+does not take multiple user names on the command line.
+Note that on GNU systems, options to
+.Xr passwd 1
+may be specified after the user argument.
+As a result, this rule will also allow:
+.Bd -literal -offset 4n
+passwd username --expire
+.Ed
+.Pp
+which may not be desirable.
+.Bd -literal
+bob SPARC = (OP) ALL : SGI = (OP) ALL
+.Ed
+.Pp
+The user
+.Sy bob
+may run anything on the
+.Em SPARC
+and
+.Em SGI
+machines as any user listed in the
+.Em OP
+.Li Runas_Alias
+.Po
+.Sy root
+and
+.Sy operator .
+.Pc
+.Bd -literal
+jim +biglab = ALL
+.Ed
+.Pp
+The user
+.Sy jim
+may run any command on machines in the
+.Em biglab
+netgroup.
+.Nm sudo
+knows that
+.Dq biglab
+is a netgroup due to the
+.Ql +
+prefix.
+.Bd -literal
++secretaries ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser
+.Ed
+.Pp
+Users in the
+.Sy secretaries
+netgroup need to help manage the printers as well as add and remove users,
+so they are allowed to run those commands on all machines.
+.Bd -literal
+fred ALL = (DB) NOPASSWD: ALL
+.Ed
+.Pp
+The user
+.Sy fred
+can run commands as any user in the
+.Em DB
+.Li Runas_Alias
+.Po
+.Sy oracle
+or
+.Sy sybase
+.Pc
+without giving a password.
+.Bd -literal
+john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
+.Ed
+.Pp
+On the
+.Em ALPHA
+machines, user
+.Sy john
+may su to anyone except root but he is not allowed to specify any options
+to the
+.Xr su 1
+command.
+.Bd -literal
+jen ALL, !SERVERS = ALL
+.Ed
+.Pp
+The user
+.Sy jen
+may run any command on any machine except for those in the
+.Em SERVERS
+.Li Host_Alias
+(master, mail, www and ns).
+.Bd -literal
+jill SERVERS = /usr/bin/, !SU, !SHELLS
+.Ed
+.Pp
+For any machine in the
+.Em SERVERS
+.Li Host_Alias ,
+.Sy jill
+may run
+any commands in the directory
+.Pa /usr/bin/
+except for those commands
+belonging to the
+.Em SU
+and
+.Em SHELLS
+.Li Cmnd_Aliases .
+While not specifically mentioned in the rule, the commands in the
+.Em PAGERS
+.Li Cmnd_Alias
+all reside in
+.Pa /usr/bin
+and have the
+.Em noexec
+option set.
+.Bd -literal
+steve CSNETS = (operator) /usr/local/op_commands/
+.Ed
+.Pp
+The user
+.Sy steve
+may run any command in the directory /usr/local/op_commands/
+but only as user operator.
+.Bd -literal
+matt valkyrie = KILL
+.Ed
+.Pp
+On his personal workstation, valkyrie,
+.Sy matt
+needs to be able to kill hung processes.
+.Bd -literal
+WEBMASTERS www = (www) ALL, (root) /usr/bin/su www
+.Ed
+.Pp
+On the host www, any user in the
+.Em WEBMASTERS
+.Li User_Alias
+(will, wendy, and wim), may run any command as user www (which owns the
+web pages) or simply
+.Xr su 1
+to www.
+.Bd -literal
+ALL CDROM = NOPASSWD: /sbin/umount /CDROM,\e
+ /sbin/mount -o nosuid\e,nodev /dev/cd0a /CDROM
+.Ed
+.Pp
+Any user may mount or unmount a CD-ROM on the machines in the CDROM
+.Li Host_Alias
+(orion, perseus, hercules) without entering a password.
+This is a bit tedious for users to type, so it is a prime candidate
+for encapsulating in a shell script.
+.Sh SECURITY NOTES
+.Ss Limitations of the So !\& Sc operator
+It is generally not effective to
+.Dq subtract
+commands from
+.Sy ALL
+using the
+.Ql !\&
+operator.
+A user can trivially circumvent this by copying the desired command
+to a different name and then executing that.
+For example:
+.Bd -literal
+bill ALL = ALL, !SU, !SHELLS
+.Ed
+.Pp
+Doesn't really prevent
+.Sy bill
+from running the commands listed in
+.Em SU
+or
+.Em SHELLS
+since he can simply copy those commands to a different name, or use
+a shell escape from an editor or other program.
+Therefore, these kind of restrictions should be considered
+advisory at best (and reinforced by policy).
+.Pp
+In general, if a user has sudo
+.Sy ALL
+there is nothing to prevent them from creating their own program that gives
+them a root shell (or making their own copy of a shell) regardless of any
+.Ql !\&
+elements in the user specification.
+.Ss Security implications of Em fast_glob
+If the
+.Em fast_glob
+option is in use, it is not possible to reliably negate commands where the
+path name includes globbing (aka wildcard) characters.
+This is because the C library's
+.Xr fnmatch 3
+function cannot resolve relative paths.
+While this is typically only an inconvenience for rules that grant privileges,
+it can result in a security issue for rules that subtract or revoke privileges.
+.Pp
+For example, given the following
+.Em sudoers
+file entry:
+.Bd -literal
+john ALL = /usr/bin/passwd [a-zA-Z0-9]*, /usr/bin/chsh [a-zA-Z0-9]*,\e
+ /usr/bin/chfn [a-zA-Z0-9]*, !/usr/bin/* root
+.Ed
+.Pp
+User
+.Sy john
+can still run
+.Li /usr/bin/passwd root
+if
+.Em fast_glob
+is enabled by changing to
+.Pa /usr/bin
+and running
+.Li ./passwd root
+instead.
+.Ss Preventing shell escapes
+Once
+.Nm sudo
+executes a program, that program is free to do whatever
+it pleases, including run other programs.
+This can be a security issue since it is not uncommon for a program to
+allow shell escapes, which lets a user bypass
+.Nm sudo Ns 's
+access control and logging.
+Common programs that permit shell escapes include shells (obviously),
+editors, paginators, mail and terminal programs.
+.Pp
+There are two basic approaches to this problem:
+.Bl -tag -width 8n
+.It restrict
+Avoid giving users access to commands that allow the user to run
+arbitrary commands.
+Many editors have a restricted mode where shell
+escapes are disabled, though
+.Nm sudoedit
+is a better solution to
+running editors via
+.Nm sudo .
+Due to the large number of programs that
+offer shell escapes, restricting users to the set of programs that
+do not is often unworkable.
+.It noexec
+Many systems that support shared libraries have the ability to
+override default library functions by pointing an environment
+variable (usually
+.Ev LD_PRELOAD )
+to an alternate shared library.
+On such systems,
+.Nm sudo Ns 's
+.Em noexec
+functionality can be used to prevent a program run by
+.Nm sudo
+from executing any other programs.
+Note, however, that this applies only to native dynamically-linked
+executables.
+Statically-linked executables and foreign executables
+running under binary emulation are not affected.
+.Pp
+The
+.Em noexec
+feature is known to work on SunOS, Solaris, *BSD,
+Linux, IRIX, Tru64 UNIX, macOS, HP-UX 11.x and AIX 5.3 and above.
+It should be supported on most operating systems that support the
+.Ev LD_PRELOAD
+environment variable.
+Check your operating system's manual pages for the dynamic linker
+(usually ld.so, ld.so.1, dyld, dld.sl, rld, or loader) to see if
+.Ev LD_PRELOAD
+is supported.
+.Pp
+On Solaris 10 and higher,
+.Em noexec
+uses Solaris privileges instead of the
+.Ev LD_PRELOAD
+environment variable.
+.Pp
+To enable
+.Em noexec
+for a command, use the
+.Li NOEXEC
+tag as documented
+in the User Specification section above.
+Here is that example again:
+.Bd -literal
+aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi
+.Ed
+.Pp
+This allows user
+.Sy aaron
+to run
+.Pa /usr/bin/more
+and
+.Pa /usr/bin/vi
+with
+.Em noexec
+enabled.
+This will prevent those two commands from
+executing other commands (such as a shell).
+If you are unsure whether or not your system is capable of supporting
+.Em noexec
+you can always just try it out and check whether shell escapes work when
+.Em noexec
+is enabled.
+.El
+.Pp
+Note that restricting shell escapes is not a panacea.
+Programs running as root are still capable of many potentially hazardous
+operations (such as changing or overwriting files) that could lead
+to unintended privilege escalation.
+In the specific case of an editor, a safer approach is to give the
+user permission to run
+.Nm sudoedit
+(see below).
+.Ss Secure editing
+The
+.Nm sudoers
+plugin includes
+.Nm sudoedit
+support which allows users to securely edit files with the editor
+of their choice.
+As
+.Nm sudoedit
+is a built-in command, it must be specified in the
+.Em sudoers
+file without a leading path.
+However, it may take command line arguments just as a normal command does.
+Wildcards used in
+.Em sudoedit
+command line arguments are expected to be path names, so a forward slash
+.Pq Ql /
+will not be matched by a wildcard.
+.Pp
+Unlike other
+.Nm sudo
+commands, the editor is run with the permissions of the invoking
+user and with the environment unmodified.
+More information may be found in the description of the
+.Fl e
+option in
+.Xr sudo @mansectsu@ .
+.Pp
+For example, to allow user operator to edit the
+.Dq message of the day
+file:
+.Bd -literal -offset indent
+operator sudoedit /etc/motd
+.Ed
+.Pp
+The operator user then runs
+.Nm sudoedit
+as follows:
+.Bd -literal -offset indent
+$ sudoedit /etc/motd
+.Ed
+.Pp
+The editor will run as the operator user, not root, on a temporary copy of
+.Pa /etc/motd .
+After the file has been edited,
+.Pa /etc/motd
+will be updated with the contents of the temporary copy.
+.Pp
+Users should
+.Em never
+be granted
+.Nm sudoedit
+permission to edit a file that resides in a directory the user
+has write access to, either directly or via a wildcard.
+If the user has write access to the directory it is possible to
+replace the legitimate file with a link to another file,
+allowing the editing of arbitrary files.
+To prevent this, starting with version 1.8.16, symbolic links will
+not be followed in writable directories and
+.Nm sudoedit
+will refuse to edit a file located in a writable directory
+unless the
+.Em sudoedit_checkdir
+option has been disabled or the invoking user is root.
+Additionally, in version 1.8.15 and higher,
+.Nm sudoedit
+will refuse to open a symbolic link unless either the
+.Em sudoedit_follow
+option is enabled or the
+.Em sudoedit
+command is prefixed with the
+.Li FOLLOW
+tag in the
+.Em sudoers
+file.
+.Ss Time stamp file checks
+.Nm sudoers
+will check the ownership of its time stamp directory
+.Po
+.Pa @rundir@/ts
+by default
+.Pc
+and ignore the directory's contents if it is not owned by root or
+if it is writable by a user other than root.
+Older versions of
+.Nm sudo
+stored time stamp files in
+.Pa /tmp ;
+this is no longer recommended as it may be possible for a user
+to create the time stamp themselves on systems that allow
+unprivileged users to change the ownership of files they create.
+.Pp
+While the time stamp directory
+.Em should
+be cleared at reboot time, not all systems contain a
+.Pa /run
+or
+.Pa /var/run
+directory.
+To avoid potential problems,
+.Nm sudoers
+will ignore time stamp files that date from before the machine booted
+on systems where the boot time is available.
+.Pp
+Some systems with graphical desktop environments allow unprivileged
+users to change the system clock.
+Since
+.Nm sudoers
+relies on the system clock for time stamp validation, it may be
+possible on such systems for a user to run
+.Nm sudo
+for longer than
+.Em timestamp_timeout
+by setting the clock back.
+To combat this,
+.Nm sudoers
+uses a monotonic clock (which never moves backwards) for its time stamps
+if the system supports it.
+.Pp
+.Nm sudoers
+will not honor time stamps set far in the future.
+Time stamps with a date greater than current_time + 2 *
+.Li TIMEOUT
+will be ignored and
+.Nm sudoers
+will log and complain.
+.Pp
+If the
+.Em timestamp_type
+option is set to
+.Dq tty ,
+the time stamp record includes the device number of the terminal
+the user authenticated with.
+This provides per-terminal granularity but time stamp records may still
+outlive the user's session.
+.Pp
+Unless the
+.Em timestamp_type
+option is set to
+.Dq global ,
+the time stamp record also includes the session ID of the process
+that last authenticated.
+This prevents processes in different terminal sessions from using
+the same time stamp record.
+On systems where a process's start time can be queried,
+the start time of the session leader
+is recorded in the time stamp record.
+If no terminal is present or the
+.Em timestamp_type
+option is set to
+.Dq ppid ,
+the start time of the parent process is used instead.
+In most cases this will prevent a time stamp record from being re-used
+without the user entering a password when logging out and back in again.
+.Sh DEBUGGING
+Versions 1.8.4 and higher of the
+.Nm
+plugin support a flexible debugging framework that can help track
+down what the plugin is doing internally if there is a problem.
+This can be configured in the
+.Xr sudo.conf @mansectform@
+file.
+.Pp
+The
+.Nm
+plugin uses the same debug flag format as the
+.Nm sudo
+front-end:
+.Em subsystem Ns @ Ns Em priority .
+.Pp
+The priorities used by
+.Nm ,
+in order of decreasing severity,
+are:
+.Em crit , err , warn , notice , diag , info , trace
+and
+.Em debug .
+Each priority, when specified, also includes all priorities higher
+than it.
+For example, a priority of
+.Em notice
+would include debug messages logged at
+.Em notice
+and higher.
+.Pp
+The following subsystems are used by the
+.Nm
+plugin:
+.Bl -tag -width 8n
+.It Em alias
+.Li User_Alias ,
+.Li Runas_Alias ,
+.Li Host_Alias
+and
+.Li Cmnd_Alias
+processing
+.It Em all
+matches every subsystem
+.It Em audit
+BSM and Linux audit code
+.It Em auth
+user authentication
+.It Em defaults
+.Em sudoers
+file
+.Em Defaults
+settings
+.It Em env
+environment handling
+.It Em ldap
+LDAP-based sudoers
+.It Em logging
+logging support
+.It Em match
+matching of users, groups, hosts and netgroups in the
+.Em sudoers
+file
+.It Em netif
+network interface handling
+.It Em nss
+network service switch handling in
+.Nm sudoers
+.It Em parser
+.Em sudoers
+file parsing
+.It Em perms
+permission setting
+.It Em plugin
+The equivalent of
+.Em main
+for the plugin.
+.It Em pty
+pseudo-tty related code
+.It Em rbtree
+redblack tree internals
+.It Em sssd
+SSSD-based sudoers
+.It Em util
+utility functions
+.El
+For example:
+.Bd -literal
+Debug sudo /var/log/sudo_debug match@info,nss@info
+.Ed
+.Pp
+For more information, see the
+.Xr sudo.conf @mansectform@
+manual.
+.Sh SEE ALSO
+.Xr ssh 1 ,
+.Xr su 1 ,
+.Xr fnmatch 3 ,
+.Xr glob 3 ,
+.Xr mktemp 3 ,
+.Xr strftime 3 ,
+.Xr sudo.conf @mansectform@ ,
+.Xr sudo_plugin @mansectform@ ,
+.Xr sudoers.ldap @mansectform@ ,
+.Xr sudoers_timestamp @mansectform@ ,
+.Xr sudo @mansectsu@ ,
+.Xr visudo @mansectsu@
+.Sh AUTHORS
+Many people have worked on
+.Nm sudo
+over the years; this version consists of code written primarily by:
+.Bd -ragged -offset indent
+.An Todd C. Miller
+.Ed
+.Pp
+See the CONTRIBUTORS file in the
+.Nm sudo
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+.Nm sudo .
+.Sh CAVEATS
+The
+.Em sudoers
+file should
+.Sy always
+be edited by the
+.Nm visudo
+command which locks the file and does grammatical checking.
+It is
+imperative that the
+.Em sudoers
+file be free of syntax errors since
+.Nm sudo
+will not run with a syntactically incorrect
+.Em sudoers
+file.
+.Pp
+When using netgroups of machines (as opposed to users), if you
+store fully qualified host name in the netgroup (as is usually the
+case), you either need to have the machine's host name be fully qualified
+as returned by the
+.Li hostname
+command or use the
+.Em fqdn
+option in
+.Em sudoers .
+.Sh BUGS
+If you feel you have found a bug in
+.Nm sudo ,
+please submit a bug report at https://bugzilla.sudo.ws/
+.Sh SUPPORT
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.Sh DISCLAIMER
+.Nm sudo
+is provided
+.Dq AS IS
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+.Nm sudo
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/sudoers_timestamp.cat b/doc/sudoers_timestamp.cat
new file mode 100644
index 0000000..cf87d70
--- /dev/null
+++ b/doc/sudoers_timestamp.cat
@@ -0,0 +1,201 @@
+SUDOERS_TIMESTAMP(4) File Formats Manual SUDOERS_TIMESTAMP(4)
+
+NNAAMMEE
+ ssuuddooeerrss__ttiimmeessttaammpp - Sudoers Time Stamp Format
+
+DDEESSCCRRIIPPTTIIOONN
+ The ssuuddooeerrss plugin uses per-user time stamp files for credential caching.
+ Once a user has been authenticated, they may use ssuuddoo without a password
+ for a short period of time (5 minutes unless overridden by the
+ _t_i_m_e_s_t_a_m_p___t_i_m_e_o_u_t option). By default, ssuuddooeerrss uses a separate record
+ for each terminal, which means that a user's login sessions are
+ authenticated separately. The _t_i_m_e_s_t_a_m_p___t_y_p_e option can be used to
+ select the type of time stamp record ssuuddooeerrss will use.
+
+ A multi-record time stamp file format was introduced in ssuuddoo 1.8.10 that
+ uses a single file per user. Previously, a separate file was used for
+ each user and terminal combination unless tty-based time stamps were
+ disabled. The new format is extensible and records of multiple types and
+ versions may coexist within the same file.
+
+ All records, regardless of type or version, begin with a 16-bit version
+ number and a 16-bit record size.
+
+ Time stamp records have the following structure:
+
+ /* Time stamp entry types */
+ #define TS_GLOBAL 0x01 /* not restricted by tty or ppid */
+ #define TS_TTY 0x02 /* restricted by tty */
+ #define TS_PPID 0x03 /* restricted by ppid */
+ #define TS_LOCKEXCL 0x04 /* special lock record */
+
+ /* Time stamp flags */
+ #define TS_DISABLED 0x01 /* entry disabled */
+ #define TS_ANYUID 0x02 /* ignore uid, only valid in key */
+
+ struct timestamp_entry {
+ unsigned short version; /* version number */
+ unsigned short size; /* entry size */
+ unsigned short type; /* TS_GLOBAL, TS_TTY, TS_PPID */
+ unsigned short flags; /* TS_DISABLED, TS_ANYUID */
+ uid_t auth_uid; /* uid to authenticate as */
+ pid_t sid; /* session ID associated with tty/ppid */
+ struct timespec start_time; /* session/ppid start time */
+ struct timespec ts; /* time stamp (CLOCK_MONOTONIC) */
+ union {
+ dev_t ttydev; /* tty device number */
+ pid_t ppid; /* parent pid */
+ } u;
+ };
+
+ The timestamp_entry struct fields are as follows:
+
+ version
+ The version number of the timestamp_entry struct. New entries are
+ created with a version number of 2. Records with different version
+ numbers may coexist in the same file but are not inter-operable.
+
+ size The size of the record in bytes.
+
+ type The record type, currently TS_GLOBAL, TS_TTY, or TS_PPID.
+
+ flags
+ Zero or more record flags which can be bit-wise ORed together.
+ Supported flags are TS_DISABLED, for records disabled via ssuuddoo --kk
+ and TS_ANYUID, which is used only when matching records.
+
+ auth_uid
+ The user ID that was used for authentication. Depending on the
+ value of the _r_o_o_t_p_w, _r_u_n_a_s_p_w and _t_a_r_g_e_t_p_w options, the user ID may
+ be that of the invoking user, the root user, the default runas user
+ or the target user.
+
+ sid The ID of the user's terminal session, if present. The session ID
+ is only used when matching records of type TS_TTY.
+
+ start_time
+ The start time of the session leader for records of type TS_TTY or
+ of the parent process for records of type TS_PPID. The _s_t_a_r_t___t_i_m_e
+ is used to help prevent re-use of a time stamp record after a user
+ has logged out. Not all systems support a method to easily
+ retrieve a process's start time. The _s_t_a_r_t___t_i_m_e field was added in
+ ssuuddooeerrss version 1.8.22 for the second revision of the
+ timestamp_entry struct.
+
+ ts The actual time stamp. A monotonic time source (which does not
+ move backward) is used if the system supports it. Where possible,
+ ssuuddooeerrss uses a monotonic timer that increments even while the
+ system is suspended. The value of _t_s is updated each time a
+ command is run via ssuuddoo. If the difference between _t_s and the
+ current time is less than the value of the _t_i_m_e_s_t_a_m_p___t_i_m_e_o_u_t
+ option, no password is required.
+
+ u.ttydev
+ The device number of the terminal associated with the session for
+ records of type TS_TTY.
+
+ u.ppid
+ The ID of the parent process for records of type TS_PPID.
+
+LLOOCCKKIINNGG
+ In ssuuddooeerrss versions 1.8.10 through 1.8.14, the entire time stamp file was
+ locked for exclusive access when reading or writing to the file.
+ Starting in ssuuddooeerrss 1.8.15, individual records are locked in the time
+ stamp file instead of the entire file and the lock is held for a longer
+ period of time. This scheme is described below.
+
+ The first record in the time stamp file is of type TS_LOCKEXCL and is
+ used as a _l_o_c_k record to prevent more than one ssuuddoo process from adding a
+ new record at the same time. Once the desired time stamp record has been
+ located or created (and locked), the TS_LOCKEXCL record is unlocked. The
+ lock on the individual time stamp record, however, is held until
+ authentication is complete. This allows ssuuddooeerrss to avoid prompting for a
+ password multiple times when it is used more than once in a pipeline.
+
+ Records of type TS_GLOBAL cannot be locked for a long period of time
+ since doing so would interfere with other ssuuddoo processes. Instead, a
+ separate lock record is used to prevent multiple ssuuddoo processes using the
+ same terminal (or parent process ID) from prompting for a password as the
+ same time.
+
+SSEEEE AALLSSOO
+ sudoers(4), sudo(1m)
+
+HHIISSTTOORRYY
+ Originally, ssuuddoo used a single zero-length file per user and the file's
+ modification time was used as the time stamp. Later versions of ssuuddoo
+ added restrictions on the ownership of the time stamp files and directory
+ as well as sanity checks on the time stamp itself. Notable changes were
+ introduced in the following ssuuddoo versions:
+
+ 1.4.0
+ Support for tty-based time stamp file was added by appending the
+ terminal name to the time stamp file name.
+
+ 1.6.2
+ The time stamp file was replaced by a per-user directory which
+ contained any tty-based time stamp files.
+
+ 1.6.3p2
+ The target user name was added to the time stamp file name when the
+ _t_a_r_g_e_t_p_w option was set.
+
+ 1.7.3
+ Information about the terminal device was stored in tty-based time
+ stamp files for sanity checking. This included the terminal device
+ numbers, inode number and, on systems where it was not updated when
+ the device was written to, the inode change time. This helped
+ prevent re-use of the time stamp file after logout.
+
+ 1.8.6p7
+ The terminal session ID was added to tty-based time stamp files to
+ prevent re-use of the time stamp by the same user in a different
+ terminal session. It also helped prevent re-use of the time stamp
+ file on systems where the terminal device's inode change time was
+ updated by writing.
+
+ 1.8.10
+ A new, multi-record time stamp file format was introduced that uses
+ a single file per user. The terminal device's change time was not
+ included since most systems now update the change time after a
+ write is performed as required by POSIX.
+
+ 1.8.15
+ Individual records are locked in the time stamp file instead of the
+ entire file and the lock is held until authentication is complete.
+
+ 1.8.22
+ The start time of the terminal session leader or parent process is
+ now stored in non-global time stamp records. This prevents re-use
+ of the time stamp file after logout in most cases.
+
+ Support was added for the kernel-based tty time stamps available in
+ OpenBSD which do not use an on-disk time stamp file.
+
+AAUUTTHHOORRSS
+ Many people have worked on ssuuddoo over the years; this version consists of
+ code written primarily by:
+
+ Todd C. Miller
+
+ See the CONTRIBUTORS file in the ssuuddoo distribution
+ (https://www.sudo.ws/contributors.html) for an exhaustive list of people
+ who have contributed to ssuuddoo.
+
+BBUUGGSS
+ If you feel you have found a bug in ssuuddoo, please submit a bug report at
+ https://bugzilla.sudo.ws/
+
+SSUUPPPPOORRTT
+ Limited free support is available via the sudo-users mailing list, see
+ https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search
+ the archives.
+
+DDIISSCCLLAAIIMMEERR
+ ssuuddoo is provided "AS IS" and any express or implied warranties,
+ including, but not limited to, the implied warranties of merchantability
+ and fitness for a particular purpose are disclaimed. See the LICENSE
+ file distributed with ssuuddoo or https://www.sudo.ws/license.html for
+ complete details.
+
+Sudo 1.8.26 October 7, 2018 Sudo 1.8.26
diff --git a/doc/sudoers_timestamp.man.in b/doc/sudoers_timestamp.man.in
new file mode 100644
index 0000000..86acce4
--- /dev/null
+++ b/doc/sudoers_timestamp.man.in
@@ -0,0 +1,310 @@
+.\" Automatically generated from an mdoc input file. Do not edit.
+.\"
+.\" Copyright (c) 2017-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "SUDOERS_TIMESTAMP" "@mansectform@" "October 7, 2018" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
+.nh
+.if n .ad l
+.SH "NAME"
+\fBsudoers_timestamp\fR
+\- Sudoers Time Stamp Format
+.SH "DESCRIPTION"
+The
+\fBsudoers\fR
+plugin uses per-user time stamp files for credential caching.
+Once a user has been authenticated, they may use
+\fBsudo\fR
+without a password for a short period of time
+(\fR@timeout@\fR
+minutes unless overridden by the
+\fItimestamp_timeout\fR
+option)
+\&.
+By default,
+\fBsudoers\fR
+uses a separate record for each terminal, which means that
+a user's login sessions are authenticated separately.
+The
+\fItimestamp_type\fR
+option can be used to select the type of time stamp record
+\fBsudoers\fR
+will use.
+.PP
+A multi-record time stamp file format was introduced in
+\fBsudo\fR
+1.8.10 that uses a single file per user.
+Previously, a separate file was used for each user and terminal
+combination unless tty-based time stamps were disabled.
+The new format is extensible and records of multiple types and versions
+may coexist within the same file.
+.PP
+All records, regardless of type or version, begin with a 16-bit version
+number and a 16-bit record size.
+.PP
+Time stamp records have the following structure:
+.nf
+.sp
+.RS 0n
+/* Time stamp entry types */
+#define TS_GLOBAL 0x01 /* not restricted by tty or ppid */
+#define TS_TTY 0x02 /* restricted by tty */
+#define TS_PPID 0x03 /* restricted by ppid */
+#define TS_LOCKEXCL 0x04 /* special lock record */
+
+/* Time stamp flags */
+#define TS_DISABLED 0x01 /* entry disabled */
+#define TS_ANYUID 0x02 /* ignore uid, only valid in key */
+
+struct timestamp_entry {
+ unsigned short version; /* version number */
+ unsigned short size; /* entry size */
+ unsigned short type; /* TS_GLOBAL, TS_TTY, TS_PPID */
+ unsigned short flags; /* TS_DISABLED, TS_ANYUID */
+ uid_t auth_uid; /* uid to authenticate as */
+ pid_t sid; /* session ID associated with tty/ppid */
+ struct timespec start_time; /* session/ppid start time */
+ struct timespec ts; /* time stamp (CLOCK_MONOTONIC) */
+ union {
+ dev_t ttydev; /* tty device number */
+ pid_t ppid; /* parent pid */
+ } u;
+};
+.RE
+.fi
+.PP
+The timestamp_entry struct fields are as follows:
+.TP 6n
+version
+The version number of the timestamp_entry struct.
+New entries are created with a version number of 2.
+Records with different version numbers may coexist in the
+same file but are not inter-operable.
+.TP 6n
+size
+The size of the record in bytes.
+.TP 6n
+type
+The record type, currently
+\fRTS_GLOBAL\fR,
+\fRTS_TTY\fR,
+or
+\fRTS_PPID\fR.
+.TP 6n
+flags
+.br
+Zero or more record flags which can be bit-wise ORed together.
+Supported flags are
+\fRTS_DISABLED\fR,
+for records disabled via
+\fBsudo\fR
+\fB\-k\fR
+and
+\fRTS_ANYUID\fR,
+which is used only when matching records.
+.TP 6n
+auth_uid
+The user ID that was used for authentication.
+Depending on the value of the
+\fIrootpw\fR,
+\fIrunaspw\fR
+and
+\fItargetpw\fR
+options, the user ID may be that of the invoking user, the root user,
+the default runas user or the target user.
+.TP 6n
+sid
+The ID of the user's terminal session, if present.
+The session ID is only used when matching records of type
+\fRTS_TTY\fR.
+.TP 6n
+start_time
+The start time of the session leader for records of type
+\fRTS_TTY\fR
+or of the parent process for records of type
+\fRTS_PPID\fR.
+The
+\fIstart_time\fR
+is used to help prevent re-use of a time stamp record after a
+user has logged out.
+Not all systems support a method to easily retrieve a process's
+start time.
+The
+\fIstart_time\fR
+field was added in
+\fBsudoers\fR
+version 1.8.22 for the second revision of the timestamp_entry struct.
+.TP 6n
+ts
+The actual time stamp.
+A monotonic time source (which does not move backward) is used if the
+system supports it.
+Where possible,
+\fBsudoers\fR
+uses a monotonic timer that increments even while the system
+is suspended.
+The value of
+\fIts\fR
+is updated each time a command is run via
+\fBsudo\fR.
+If the difference between
+\fIts\fR
+and the current time is less than the value of the
+\fItimestamp_timeout\fR
+option, no password is required.
+.TP 6n
+u.ttydev
+The device number of the terminal associated with the session for
+records of type
+\fRTS_TTY\fR.
+.TP 6n
+u.ppid
+The ID of the parent process for records of type
+\fRTS_PPID\fR.
+.SH "LOCKING"
+In
+\fBsudoers\fR
+versions 1.8.10 through 1.8.14, the entire time stamp file was
+locked for exclusive access when reading or writing to the file.
+Starting in
+\fBsudoers\fR
+1.8.15, individual records are locked in the time stamp file instead
+of the entire file and the lock is held for a longer period of time.
+This scheme is described below.
+.PP
+The first record in the time stamp file is of type
+\fRTS_LOCKEXCL\fR
+and is used as a
+\fIlock\fR
+record to prevent more than one
+\fBsudo\fR
+process from adding a new record at the same time.
+Once the desired time stamp record has been located or created (and
+locked), the
+\fRTS_LOCKEXCL\fR
+record is unlocked.
+The lock on the individual time stamp record, however, is held until
+authentication is complete.
+This allows
+\fBsudoers\fR
+to avoid prompting for a password multiple times when it
+is used more than once in a pipeline.
+.PP
+Records of type
+\fRTS_GLOBAL\fR
+cannot be locked for a long period of time since doing so would
+interfere with other
+\fBsudo\fR
+processes.
+Instead, a separate lock record is used to prevent multiple
+\fBsudo\fR
+processes using the same terminal (or parent process ID) from
+prompting for a password as the same time.
+.SH "SEE ALSO"
+sudoers(@mansectform@),
+sudo(@mansectsu@)
+.SH "HISTORY"
+Originally,
+\fBsudo\fR
+used a single zero-length file per user and the file's modification
+time was used as the time stamp.
+Later versions of
+\fBsudo\fR
+added restrictions on the ownership of the time stamp files and
+directory as well as sanity checks on the time stamp itself.
+Notable changes were introduced in the following
+\fBsudo\fR
+versions:
+.TP 6n
+1.4.0
+.br
+Support for tty-based time stamp file was added
+by appending the terminal name to the time stamp file name.
+.TP 6n
+1.6.2
+.br
+The time stamp file was replaced by a per-user directory which
+contained any tty-based time stamp files.
+.TP 6n
+1.6.3p2
+The target user name was added to the time stamp file name when the
+\fItargetpw\fR
+option was set.
+.TP 6n
+1.7.3
+.br
+Information about the terminal device was stored in
+tty-based time stamp files for sanity checking.
+This included the terminal device numbers, inode number and, on systems
+where it was not updated when the device was written to, the inode change time.
+This helped prevent re-use of the time stamp file after logout.
+.TP 6n
+1.8.6p7
+The terminal session ID was added to tty-based time stamp files to
+prevent re-use of the time stamp by the same user in a different
+terminal session.
+It also helped prevent re-use of the time stamp file on systems where
+the terminal device's inode change time was updated by writing.
+.TP 6n
+1.8.10
+A new, multi-record time stamp file format was introduced that uses a
+single file per user.
+The terminal device's change time was not included since most
+systems now update the change time after a write is performed
+as required by POSIX.
+.TP 6n
+1.8.15
+Individual records are locked in the time stamp file instead of the
+entire file and the lock is held until authentication is complete.
+.TP 6n
+1.8.22
+The start time of the terminal session leader or parent process is
+now stored in non-global time stamp records.
+This prevents re-use of the time stamp file after logout in most cases.
+.sp
+Support was added for the kernel-based tty time stamps available in
+OpenBSD
+which do not use an on-disk time stamp file.
+.SH "AUTHORS"
+Many people have worked on
+\fBsudo\fR
+over the years; this version consists of code written primarily by:
+.sp
+.RS 6n
+Todd C. Miller
+.RE
+.PP
+See the CONTRIBUTORS file in the
+\fBsudo\fR
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+\fBsudo\fR.
+.SH "BUGS"
+If you feel you have found a bug in
+\fBsudo\fR,
+please submit a bug report at https://bugzilla.sudo.ws/
+.SH "SUPPORT"
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.SH "DISCLAIMER"
+\fBsudo\fR
+is provided
+\(lqAS IS\(rq
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+\fBsudo\fR
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/sudoers_timestamp.mdoc.in b/doc/sudoers_timestamp.mdoc.in
new file mode 100644
index 0000000..b385590
--- /dev/null
+++ b/doc/sudoers_timestamp.mdoc.in
@@ -0,0 +1,288 @@
+.\"
+.\" Copyright (c) 2017-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd October 7, 2018
+.Dt SUDOERS_TIMESTAMP @mansectform@
+.Os Sudo @PACKAGE_VERSION@
+.Sh NAME
+.Nm sudoers_timestamp
+.Nd Sudoers Time Stamp Format
+.Sh DESCRIPTION
+The
+.Nm sudoers
+plugin uses per-user time stamp files for credential caching.
+Once a user has been authenticated, they may use
+.Nm sudo
+without a password for a short period of time
+.Po
+.Li @timeout@
+minutes unless overridden by the
+.Em timestamp_timeout
+option
+.Pc .
+By default,
+.Nm sudoers
+uses a separate record for each terminal, which means that
+a user's login sessions are authenticated separately.
+The
+.Em timestamp_type
+option can be used to select the type of time stamp record
+.Nm sudoers
+will use.
+.Pp
+A multi-record time stamp file format was introduced in
+.Nm sudo
+1.8.10 that uses a single file per user.
+Previously, a separate file was used for each user and terminal
+combination unless tty-based time stamps were disabled.
+The new format is extensible and records of multiple types and versions
+may coexist within the same file.
+.Pp
+All records, regardless of type or version, begin with a 16-bit version
+number and a 16-bit record size.
+.Pp
+Time stamp records have the following structure:
+.Bd -literal
+/* Time stamp entry types */
+#define TS_GLOBAL 0x01 /* not restricted by tty or ppid */
+#define TS_TTY 0x02 /* restricted by tty */
+#define TS_PPID 0x03 /* restricted by ppid */
+#define TS_LOCKEXCL 0x04 /* special lock record */
+
+/* Time stamp flags */
+#define TS_DISABLED 0x01 /* entry disabled */
+#define TS_ANYUID 0x02 /* ignore uid, only valid in key */
+
+struct timestamp_entry {
+ unsigned short version; /* version number */
+ unsigned short size; /* entry size */
+ unsigned short type; /* TS_GLOBAL, TS_TTY, TS_PPID */
+ unsigned short flags; /* TS_DISABLED, TS_ANYUID */
+ uid_t auth_uid; /* uid to authenticate as */
+ pid_t sid; /* session ID associated with tty/ppid */
+ struct timespec start_time; /* session/ppid start time */
+ struct timespec ts; /* time stamp (CLOCK_MONOTONIC) */
+ union {
+ dev_t ttydev; /* tty device number */
+ pid_t ppid; /* parent pid */
+ } u;
+};
+.Ed
+.Pp
+The timestamp_entry struct fields are as follows:
+.Bl -tag -width 4n
+.It version
+The version number of the timestamp_entry struct.
+New entries are created with a version number of 2.
+Records with different version numbers may coexist in the
+same file but are not inter-operable.
+.It size
+The size of the record in bytes.
+.It type
+The record type, currently
+.Li TS_GLOBAL ,
+.Li TS_TTY ,
+or
+.Li TS_PPID .
+.It flags
+Zero or more record flags which can be bit-wise ORed together.
+Supported flags are
+.Li TS_DISABLED ,
+for records disabled via
+.Nm sudo
+.Fl k
+and
+.Li TS_ANYUID ,
+which is used only when matching records.
+.It auth_uid
+The user ID that was used for authentication.
+Depending on the value of the
+.Em rootpw ,
+.Em runaspw
+and
+.Em targetpw
+options, the user ID may be that of the invoking user, the root user,
+the default runas user or the target user.
+.It sid
+The ID of the user's terminal session, if present.
+The session ID is only used when matching records of type
+.Li TS_TTY .
+.It start_time
+The start time of the session leader for records of type
+.Li TS_TTY
+or of the parent process for records of type
+.Li TS_PPID .
+The
+.Em start_time
+is used to help prevent re-use of a time stamp record after a
+user has logged out.
+Not all systems support a method to easily retrieve a process's
+start time.
+The
+.Em start_time
+field was added in
+.Nm sudoers
+version 1.8.22 for the second revision of the timestamp_entry struct.
+.It ts
+The actual time stamp.
+A monotonic time source (which does not move backward) is used if the
+system supports it.
+Where possible,
+.Nm sudoers
+uses a monotonic timer that increments even while the system
+is suspended.
+The value of
+.Em ts
+is updated each time a command is run via
+.Nm sudo .
+If the difference between
+.Em ts
+and the current time is less than the value of the
+.Em timestamp_timeout
+option, no password is required.
+.It u.ttydev
+The device number of the terminal associated with the session for
+records of type
+.Li TS_TTY .
+.It u.ppid
+The ID of the parent process for records of type
+.Li TS_PPID .
+.El
+.Sh LOCKING
+In
+.Nm sudoers
+versions 1.8.10 through 1.8.14, the entire time stamp file was
+locked for exclusive access when reading or writing to the file.
+Starting in
+.Nm sudoers
+1.8.15, individual records are locked in the time stamp file instead
+of the entire file and the lock is held for a longer period of time.
+This scheme is described below.
+.Pp
+The first record in the time stamp file is of type
+.Li TS_LOCKEXCL
+and is used as a
+.Em lock
+record to prevent more than one
+.Nm sudo
+process from adding a new record at the same time.
+Once the desired time stamp record has been located or created (and
+locked), the
+.Li TS_LOCKEXCL
+record is unlocked.
+The lock on the individual time stamp record, however, is held until
+authentication is complete.
+This allows
+.Nm sudoers
+to avoid prompting for a password multiple times when it
+is used more than once in a pipeline.
+.Pp
+Records of type
+.Li TS_GLOBAL
+cannot be locked for a long period of time since doing so would
+interfere with other
+.Nm sudo
+processes.
+Instead, a separate lock record is used to prevent multiple
+.Nm sudo
+processes using the same terminal (or parent process ID) from
+prompting for a password as the same time.
+.Sh SEE ALSO
+.Xr sudoers @mansectform@ ,
+.Xr sudo @mansectsu@
+.Sh HISTORY
+Originally,
+.Nm sudo
+used a single zero-length file per user and the file's modification
+time was used as the time stamp.
+Later versions of
+.Nm sudo
+added restrictions on the ownership of the time stamp files and
+directory as well as sanity checks on the time stamp itself.
+Notable changes were introduced in the following
+.Nm sudo
+versions:
+.Bl -tag -width 4n
+.It 1.4.0
+Support for tty-based time stamp file was added
+by appending the terminal name to the time stamp file name.
+.It 1.6.2
+The time stamp file was replaced by a per-user directory which
+contained any tty-based time stamp files.
+.It 1.6.3p2
+The target user name was added to the time stamp file name when the
+.Em targetpw
+option was set.
+.It 1.7.3
+Information about the terminal device was stored in
+tty-based time stamp files for sanity checking.
+This included the terminal device numbers, inode number and, on systems
+where it was not updated when the device was written to, the inode change time.
+This helped prevent re-use of the time stamp file after logout.
+.It 1.8.6p7
+The terminal session ID was added to tty-based time stamp files to
+prevent re-use of the time stamp by the same user in a different
+terminal session.
+It also helped prevent re-use of the time stamp file on systems where
+the terminal device's inode change time was updated by writing.
+.It 1.8.10
+A new, multi-record time stamp file format was introduced that uses a
+single file per user.
+The terminal device's change time was not included since most
+systems now update the change time after a write is performed
+as required by POSIX.
+.It 1.8.15
+Individual records are locked in the time stamp file instead of the
+entire file and the lock is held until authentication is complete.
+.It 1.8.22
+The start time of the terminal session leader or parent process is
+now stored in non-global time stamp records.
+This prevents re-use of the time stamp file after logout in most cases.
+.Pp
+Support was added for the kernel-based tty time stamps available in
+.Ox
+which do not use an on-disk time stamp file.
+.El
+.Sh AUTHORS
+Many people have worked on
+.Nm sudo
+over the years; this version consists of code written primarily by:
+.Bd -ragged -offset indent
+.An Todd C. Miller
+.Ed
+.Pp
+See the CONTRIBUTORS file in the
+.Nm sudo
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+.Nm sudo .
+.Sh BUGS
+If you feel you have found a bug in
+.Nm sudo ,
+please submit a bug report at https://bugzilla.sudo.ws/
+.Sh SUPPORT
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.Sh DISCLAIMER
+.Nm sudo
+is provided
+.Dq AS IS
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+.Nm sudo
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/sudoreplay.cat b/doc/sudoreplay.cat
new file mode 100644
index 0000000..d3dd9ba
--- /dev/null
+++ b/doc/sudoreplay.cat
@@ -0,0 +1,303 @@
+SUDOREPLAY(1m) System Manager's Manual SUDOREPLAY(1m)
+
+NNAAMMEE
+ ssuuddoorreeppllaayy - replay sudo session logs
+
+SSYYNNOOPPSSIISS
+ ssuuddoorreeppllaayy [--hhnnRRSS] [--dd _d_i_r] [--ff _f_i_l_t_e_r] [--mm _n_u_m] [--ss _n_u_m] ID
+
+ ssuuddoorreeppllaayy [--hh] [--dd _d_i_r] --ll [search expression]
+
+DDEESSCCRRIIPPTTIIOONN
+ ssuuddoorreeppllaayy plays back or lists the output logs created by ssuuddoo. When
+ replaying, ssuuddoorreeppllaayy can play the session back in real-time, or the
+ playback speed may be adjusted (faster or slower) based on the command
+ line options.
+
+ The _I_D should either be a six character sequence of digits and upper case
+ letters, e.g., 0100A5, or a pattern matching the _i_o_l_o_g___f_i_l_e option in the
+ _s_u_d_o_e_r_s file. When a command is run via ssuuddoo with _l_o_g___o_u_t_p_u_t enabled in
+ the _s_u_d_o_e_r_s file, a TSID=ID string is logged via syslog or to the ssuuddoo
+ log file. The _I_D may also be determined using ssuuddoorreeppllaayy's list mode.
+
+ In list mode, ssuuddoorreeppllaayy can be used to find the ID of a session based on
+ a number of criteria such as the user, tty or command run.
+
+ In replay mode, if the standard input and output are connected to a
+ terminal and the --nn option is not specified, ssuuddoorreeppllaayy will operate
+ interactively. In interactive mode, ssuuddoorreeppllaayy will attempt to adjust
+ the terminal size to match that of the session and write directly to the
+ terminal (not all terminals support this). Additionally, it will poll
+ the keyboard and act on the following keys:
+
+ `\n' or `\r' Skip to the next replay event; useful for long pauses.
+
+ ` ' (space) Pause output; press any key to resume.
+
+ `<' Reduce the playback speed by one half.
+
+ `>' Double the playback speed.
+
+ The session can be interrupted via control-C. When the session has
+ finished, the terminal is restored to its original size if it was changed
+ during playback.
+
+ The options are as follows:
+
+ --dd _d_i_r, ----ddiirreeccttoorryy=_d_i_r
+ Store session logs in _d_i_r instead of the default,
+ _/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o.
+
+ --ff _f_i_l_t_e_r, ----ffiilltteerr=_f_i_l_t_e_r
+ Select which I/O type(s) to display. By default, ssuuddoorreeppllaayy
+ will display the command's standard output, standard error
+ and tty output. The _f_i_l_t_e_r argument is a comma-separated
+ list, consisting of one or more of following: _s_t_d_i_n, _s_t_d_o_u_t,
+ _s_t_d_e_r_r, _t_t_y_i_n, and _t_t_y_o_u_t.
+
+ --hh, ----hheellpp Display a short help message to the standard output and exit.
+
+ --ll, ----lliisstt [_s_e_a_r_c_h _e_x_p_r_e_s_s_i_o_n]
+ Enable "list mode". In this mode, ssuuddoorreeppllaayy will list
+ available sessions in a format similar to the ssuuddoo log file
+ format, sorted by file name (or sequence number). If a
+ _s_e_a_r_c_h _e_x_p_r_e_s_s_i_o_n is specified, it will be used to restrict
+ the IDs that are displayed. An expression is composed of the
+ following predicates:
+
+ command _p_a_t_t_e_r_n
+ Evaluates to true if the command run matches the
+ POSIX extended regular expression _p_a_t_t_e_r_n.
+
+ cwd _d_i_r_e_c_t_o_r_y
+ Evaluates to true if the command was run with the
+ specified current working directory.
+
+ fromdate _d_a_t_e
+ Evaluates to true if the command was run on or after
+ _d_a_t_e. See _D_a_t_e _a_n_d _t_i_m_e _f_o_r_m_a_t for a description of
+ supported date and time formats.
+
+ group _r_u_n_a_s___g_r_o_u_p
+ Evaluates to true if the command was run with the
+ specified _r_u_n_a_s___g_r_o_u_p. Note that unless a
+ _r_u_n_a_s___g_r_o_u_p was explicitly specified when ssuuddoo was
+ run this field will be empty in the log.
+
+ runas _r_u_n_a_s___u_s_e_r
+ Evaluates to true if the command was run as the
+ specified _r_u_n_a_s___u_s_e_r. Note that ssuuddoo runs commands
+ as user _r_o_o_t by default.
+
+ todate _d_a_t_e
+ Evaluates to true if the command was run on or prior
+ to _d_a_t_e. See _D_a_t_e _a_n_d _t_i_m_e _f_o_r_m_a_t for a description
+ of supported date and time formats.
+
+ tty _t_t_y _n_a_m_e
+ Evaluates to true if the command was run on the
+ specified terminal device. The _t_t_y _n_a_m_e should be
+ specified without the _/_d_e_v_/ prefix, e.g., _t_t_y_0_1
+ instead of _/_d_e_v_/_t_t_y_0_1.
+
+ user _u_s_e_r _n_a_m_e
+ Evaluates to true if the ID matches a command run by
+ _u_s_e_r _n_a_m_e.
+
+ Predicates may be abbreviated to the shortest unique string.
+
+ Predicates may be combined using _a_n_d, _o_r and _! operators as
+ well as `(' and `)' grouping (note that parentheses must
+ generally be escaped from the shell). The _a_n_d operator is
+ optional, adjacent predicates have an implied _a_n_d unless
+ separated by an _o_r.
+
+ --mm, ----mmaaxx--wwaaiitt _m_a_x___w_a_i_t
+ Specify an upper bound on how long to wait between key
+ presses or output data. By default, ssuuddoorreeppllaayy will
+ accurately reproduce the delays between key presses or
+ program output. However, this can be tedious when the
+ session includes long pauses. When the --mm option is
+ specified, ssuuddoorreeppllaayy will limit these pauses to at most
+ _m_a_x___w_a_i_t seconds. The value may be specified as a floating
+ point number, e.g., _2_._5. A _m_a_x___w_a_i_t of zero or less will
+ eliminate the pauses entirely.
+
+ --nn, ----nnoonn--iinntteerraaccttiivvee
+ Do not prompt for user input or attempt to re-size the
+ terminal. The session is written to the standard output, not
+ directly to the user's terminal.
+
+ --RR, ----nnoo--rreessiizzee
+ Do not attempt to re-size the terminal to match the terminal
+ size of the session.
+
+ --SS, ----ssuussppeenndd--wwaaiitt
+ Wait while the command was suspended. By default, ssuuddoorreeppllaayy
+ will ignore the time interval between when the command was
+ suspended and when it was resumed. If the --SS option is
+ specified, ssuuddoorreeppllaayy will wait instead.
+
+ --ss, ----ssppeeeedd _s_p_e_e_d___f_a_c_t_o_r
+ This option causes ssuuddoorreeppllaayy to adjust the number of seconds
+ it will wait between key presses or program output. This can
+ be used to slow down or speed up the display. For example, a
+ _s_p_e_e_d___f_a_c_t_o_r of _2 would make the output twice as fast whereas
+ a _s_p_e_e_d___f_a_c_t_o_r of _._5 would make the output twice as slow.
+
+ --VV, ----vveerrssiioonn
+ Print the ssuuddoorreeppllaayy versions version number and exit.
+
+ DDaattee aanndd ttiimmee ffoorrmmaatt
+ The time and date may be specified multiple ways, common formats include:
+
+ HH:MM:SS am MM/DD/CCYY timezone
+ 24 hour time may be used in place of am/pm.
+
+ HH:MM:SS am Month, Day Year timezone
+ 24 hour time may be used in place of am/pm, and month and day
+ names may be abbreviated. Note that month and day of the week
+ names must be specified in English.
+
+ CCYY-MM-DD HH:MM:SS
+ ISO time format
+
+ DD Month CCYY HH:MM:SS
+ The month name may be abbreviated.
+
+ Either time or date may be omitted, the am/pm and timezone are optional.
+ If no date is specified, the current day is assumed; if no time is
+ specified, the first second of the specified date is used. The less
+ significant parts of both time and date may also be omitted, in which
+ case zero is assumed.
+
+ The following are all valid time and date specifications:
+
+ now The current time and date.
+
+ tomorrow
+ Exactly one day from now.
+
+ yesterday
+ 24 hours ago.
+
+ 2 hours ago
+ 2 hours ago.
+
+ next Friday
+ The first second of the Friday in the next (upcoming) week. Not
+ to be confused with "this Friday" which would match the Friday of
+ the current week.
+
+ last week
+ The current time but 7 days ago. This is equivalent to "a week
+ ago".
+
+ a fortnight ago
+ The current time but 14 days ago.
+
+ 10:01 am 9/17/2009
+ 10:01 am, September 17, 2009.
+
+ 10:01 am
+ 10:01 am on the current day.
+
+ 10 10:00 am on the current day.
+
+ 9/17/2009
+ 00:00 am, September 17, 2009.
+
+ 10:01 am Sep 17, 2009
+ 10:01 am, September 17, 2009.
+
+ Note that relative time specifications do not always work as expected.
+ For example, the "next" qualifier is intended to be used in conjunction
+ with a day such as "next Monday". When used with units of weeks, months,
+ years, etc the result will be one more than expected. For example, "next
+ week" will result in a time exactly two weeks from now, which is probably
+ not what was intended. This will be addressed in a future version of
+ ssuuddoorreeppllaayy.
+
+ DDeebbuuggggiinngg ssuuddoorreeppllaayy
+ ssuuddoorreeppllaayy versions 1.8.4 and higher support a flexible debugging
+ framework that is configured via Debug lines in the sudo.conf(4) file.
+
+ For more information on configuring sudo.conf(4), please refer to its
+ manual.
+
+FFIILLEESS
+ _/_e_t_c_/_s_u_d_o_._c_o_n_f Debugging framework configuration
+
+ _/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o The default I/O log directory.
+
+ _/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o_/_0_0_/_0_0_/_0_1_/_l_o_g
+ Example session log info.
+
+ _/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o_/_0_0_/_0_0_/_0_1_/_s_t_d_i_n
+ Example session standard input log.
+
+ _/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o_/_0_0_/_0_0_/_0_1_/_s_t_d_o_u_t
+ Example session standard output log.
+
+ _/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o_/_0_0_/_0_0_/_0_1_/_s_t_d_e_r_r
+ Example session standard error log.
+
+ _/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o_/_0_0_/_0_0_/_0_1_/_t_t_y_i_n
+ Example session tty input file.
+
+ _/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o_/_0_0_/_0_0_/_0_1_/_t_t_y_o_u_t
+ Example session tty output file.
+
+ _/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o_/_0_0_/_0_0_/_0_1_/_t_i_m_i_n_g
+ Example session timing file.
+
+ Note that the _s_t_d_i_n, _s_t_d_o_u_t and _s_t_d_e_r_r files will be empty unless ssuuddoo
+ was used as part of a pipeline for a particular command.
+
+EEXXAAMMPPLLEESS
+ List sessions run by user _m_i_l_l_e_r_t:
+
+ # sudoreplay -l user millert
+
+ List sessions run by user _b_o_b with a command containing the string vi:
+
+ # sudoreplay -l user bob command vi
+
+ List sessions run by user _j_e_f_f that match a regular expression:
+
+ # sudoreplay -l user jeff command '/bin/[a-z]*sh'
+
+ List sessions run by jeff or bob on the console:
+
+ # sudoreplay -l ( user jeff or user bob ) tty console
+
+SSEEEE AALLSSOO
+ script(1), sudo.conf(4), sudo(1m)
+
+AAUUTTHHOORRSS
+ Many people have worked on ssuuddoo over the years; this version consists of
+ code written primarily by:
+
+ Todd C. Miller
+
+ See the CONTRIBUTORS file in the ssuuddoo distribution
+ (https://www.sudo.ws/contributors.html) for an exhaustive list of people
+ who have contributed to ssuuddoo.
+
+BBUUGGSS
+ If you feel you have found a bug in ssuuddoorreeppllaayy, please submit a bug
+ report at https://bugzilla.sudo.ws/
+
+SSUUPPPPOORRTT
+ Limited free support is available via the sudo-users mailing list, see
+ https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search
+ the archives.
+
+DDIISSCCLLAAIIMMEERR
+ ssuuddoorreeppllaayy is provided "AS IS" and any express or implied warranties,
+ including, but not limited to, the implied warranties of merchantability
+ and fitness for a particular purpose are disclaimed. See the LICENSE
+ file distributed with ssuuddoo or https://www.sudo.ws/license.html for
+ complete details.
+
+Sudo 1.8.26 October 6, 2018 Sudo 1.8.26
diff --git a/doc/sudoreplay.man.in b/doc/sudoreplay.man.in
new file mode 100644
index 0000000..7bb2da6
--- /dev/null
+++ b/doc/sudoreplay.man.in
@@ -0,0 +1,486 @@
+.\" Automatically generated from an mdoc input file. Do not edit.
+.\"
+.\" Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "SUDOREPLAY" "@mansectsu@" "October 6, 2018" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
+.nh
+.if n .ad l
+.SH "NAME"
+\fBsudoreplay\fR
+\- replay sudo session logs
+.SH "SYNOPSIS"
+.HP 11n
+\fBsudoreplay\fR
+[\fB\-hnRS\fR]
+[\fB\-d\fR\ \fIdir\fR]
+[\fB\-f\fR\ \fIfilter\fR]
+[\fB\-m\fR\ \fInum\fR]
+[\fB\-s\fR\ \fInum\fR]
+ID
+.HP 11n
+\fBsudoreplay\fR
+[\fB\-h\fR]
+[\fB\-d\fR\ \fIdir\fR]
+\fB\-l\fR
+[search\ expression]
+.SH "DESCRIPTION"
+\fBsudoreplay\fR
+plays back or lists the output logs created by
+\fBsudo\fR.
+When replaying,
+\fBsudoreplay\fR
+can play the session back in real-time, or the playback speed may be
+adjusted (faster or slower) based on the command line options.
+.PP
+The
+\fIID\fR
+should either be a six character sequence of digits and
+upper case letters, e.g.,
+\fR0100A5\fR,
+or a pattern matching the
+\fIiolog_file\fR
+option in the
+\fIsudoers\fR
+file.
+When a command is run via
+\fBsudo\fR
+with
+\fIlog_output\fR
+enabled in the
+\fIsudoers\fR
+file, a
+\fRTSID=ID\fR
+string is logged via syslog or to the
+\fBsudo\fR
+log file.
+The
+\fIID\fR
+may also be determined using
+\fBsudoreplay\fR's
+list mode.
+.PP
+In list mode,
+\fBsudoreplay\fR
+can be used to find the ID of a session based on a number of criteria
+such as the user, tty or command run.
+.PP
+In replay mode, if the standard input and output are connected to a terminal
+and the
+\fB\-n\fR
+option is not specified,
+\fBsudoreplay\fR
+will operate interactively.
+In interactive mode,
+\fBsudoreplay\fR
+will attempt to adjust the terminal size to match that of the session and
+write directly to the terminal (not all terminals support this).
+Additionally, it will poll the keyboard and act on the following keys:
+.TP 14n
+\(oq\fR\en\fR\(cq or \(oq\fR\er\fR\(cq
+Skip to the next replay event; useful for long pauses.
+.TP 14n
+\(oq\fR\ \fR\(cq (space)
+Pause output; press any key to resume.
+.TP 14n
+\(oq<\(cq
+Reduce the playback speed by one half.
+.TP 14n
+\(oq>\(cq
+Double the playback speed.
+.PP
+The session can be interrupted via control-C.
+When the session has finished, the terminal is restored to its
+original size if it was changed during playback.
+.PP
+The options are as follows:
+.TP 12n
+\fB\-d\fR \fIdir\fR, \fB\--directory\fR=\fIdir\fR
+Store session logs in
+\fIdir\fR
+instead of the default,
+\fI@iolog_dir@\fR.
+.TP 12n
+\fB\-f\fR \fIfilter\fR, \fB\--filter\fR=\fIfilter\fR
+Select which I/O type(s) to display.
+By default,
+\fBsudoreplay\fR
+will display the command's standard output, standard error and tty output.
+The
+\fIfilter\fR
+argument is a comma-separated list, consisting of one or more of following:
+\fIstdin\fR,
+\fIstdout\fR,
+\fIstderr\fR,
+\fIttyin\fR,
+and
+\fIttyout\fR.
+.TP 12n
+\fB\-h\fR, \fB\--help\fR
+Display a short help message to the standard output and exit.
+.TP 12n
+\fB\-l\fR, \fB\--list\fR [\fIsearch expression\fR]
+Enable
+\(lqlist mode\(rq.
+In this mode,
+\fBsudoreplay\fR
+will list available sessions in a format similar to the
+\fBsudo\fR
+log file format, sorted by file name (or sequence number).
+If a
+\fIsearch expression\fR
+is specified, it will be used to restrict the IDs that are displayed.
+An expression is composed of the following predicates:
+.PP
+.RS 12n
+.PD 0
+.TP 8n
+command \fIpattern\fR
+Evaluates to true if the command run matches the POSIX extended
+regular expression
+\fIpattern\fR.
+.PD
+.TP 8n
+cwd \fIdirectory\fR
+Evaluates to true if the command was run with the specified current
+working directory.
+.TP 8n
+fromdate \fIdate\fR
+Evaluates to true if the command was run on or after
+\fIdate\fR.
+See
+\fIDate and time format\fR
+for a description of supported date and time formats.
+.TP 8n
+group \fIrunas_group\fR
+Evaluates to true if the command was run with the specified
+\fIrunas_group\fR.
+Note that unless a
+\fIrunas_group\fR
+was explicitly specified when
+\fBsudo\fR
+was run this field will be empty in the log.
+.TP 8n
+runas \fIrunas_user\fR
+Evaluates to true if the command was run as the specified
+\fIrunas_user\fR.
+Note that
+\fBsudo\fR
+runs commands as user
+\fIroot\fR
+by default.
+.TP 8n
+todate \fIdate\fR
+Evaluates to true if the command was run on or prior to
+\fIdate\fR.
+See
+\fIDate and time format\fR
+for a description of supported date and time formats.
+.TP 8n
+tty \fItty name\fR
+Evaluates to true if the command was run on the specified terminal device.
+The
+\fItty name\fR
+should be specified without the
+\fI/dev/\fR
+prefix, e.g.,
+\fItty01\fR
+instead of
+\fI/dev/tty01\fR.
+.TP 8n
+user \fIuser name\fR
+Evaluates to true if the ID matches a command run by
+\fIuser name\fR.
+.PP
+Predicates may be abbreviated to the shortest unique string.
+.sp
+Predicates may be combined using
+\fIand\fR,
+\fIor\fR
+and
+\fI\&!\fR
+operators as well as
+\(oq\&(\(cq
+and
+\(oq\&)\(cq
+grouping (note that parentheses must generally be escaped from the shell).
+The
+\fIand\fR
+operator is optional, adjacent predicates have an implied
+\fIand\fR
+unless separated by an
+\fIor\fR.
+.RE
+.TP 12n
+\fB\-m\fR, \fB\--max-wait\fR \fImax_wait\fR
+Specify an upper bound on how long to wait between key presses or output data.
+By default,
+\fBsudoreplay\fR
+will accurately reproduce the delays between key presses or program output.
+However, this can be tedious when the session includes long pauses.
+When the
+\fB\-m\fR
+option is specified,
+\fBsudoreplay\fR
+will limit these pauses to at most
+\fImax_wait\fR
+seconds.
+The value may be specified as a floating point number, e.g.,
+\fI2.5\fR.
+A
+\fImax_wait\fR
+of zero or less will eliminate the pauses entirely.
+.TP 12n
+\fB\-n\fR, \fB\--non-interactive\fR
+Do not prompt for user input or attempt to re-size the terminal.
+The session is written to the standard output, not directly to
+the user's terminal.
+.TP 12n
+\fB\-R\fR, \fB\--no-resize\fR
+Do not attempt to re-size the terminal to match the terminal size
+of the session.
+.TP 12n
+\fB\-S\fR, \fB\--suspend-wait\fR
+Wait while the command was suspended.
+By default,
+\fBsudoreplay\fR
+will ignore the time interval between when the command was suspended
+and when it was resumed.
+If the
+\fB\-S\fR
+option is specified,
+\fBsudoreplay\fR
+will wait instead.
+.TP 12n
+\fB\-s\fR, \fB\--speed\fR \fIspeed_factor\fR
+This option causes
+\fBsudoreplay\fR
+to adjust the number of seconds it will wait between key presses or
+program output.
+This can be used to slow down or speed up the display.
+For example, a
+\fIspeed_factor\fR
+of
+\fI2\fR
+would make the output twice as fast whereas a
+\fIspeed_factor\fR
+of
+\fI.5\fR
+would make the output twice as slow.
+.TP 12n
+\fB\-V\fR, \fB\--version\fR
+Print the
+\fBsudoreplay\fR
+versions version number and exit.
+.SS "Date and time format"
+The time and date may be specified multiple ways, common formats include:
+.TP 8n
+HH:MM:SS am MM/DD/CCYY timezone
+24 hour time may be used in place of am/pm.
+.TP 8n
+HH:MM:SS am Month, Day Year timezone
+24 hour time may be used in place of am/pm, and month and day names
+may be abbreviated.
+Note that month and day of the week names must be specified in English.
+.TP 8n
+CCYY-MM-DD HH:MM:SS
+ISO time format
+.TP 8n
+DD Month CCYY HH:MM:SS
+The month name may be abbreviated.
+.PP
+Either time or date may be omitted, the am/pm and timezone are optional.
+If no date is specified, the current day is assumed; if no time is
+specified, the first second of the specified date is used.
+The less significant parts of both time and date may also be omitted,
+in which case zero is assumed.
+.PP
+The following are all valid time and date specifications:
+.TP 8n
+now
+The current time and date.
+.TP 8n
+tomorrow
+Exactly one day from now.
+.TP 8n
+yesterday
+24 hours ago.
+.TP 8n
+2 hours ago
+2 hours ago.
+.TP 8n
+next Friday
+The first second of the Friday in the next (upcoming) week.
+Not to be confused with
+\(lqthis Friday\(rq
+which would match the Friday of the current week.
+.TP 8n
+last week
+The current time but 7 days ago.
+This is equivalent to
+\(lqa week ago\(rq.
+.TP 8n
+a fortnight ago
+The current time but 14 days ago.
+.TP 8n
+10:01 am 9/17/2009
+10:01 am, September 17, 2009.
+.TP 8n
+10:01 am
+10:01 am on the current day.
+.TP 8n
+10
+10:00 am on the current day.
+.TP 8n
+9/17/2009
+00:00 am, September 17, 2009.
+.TP 8n
+10:01 am Sep 17, 2009
+10:01 am, September 17, 2009.
+.PP
+Note that relative time specifications do not always work as expected.
+For example, the
+\(lqnext\(rq
+qualifier is intended to be used in conjunction with a day such as
+\(lqnext Monday\(rq.
+When used with units of weeks, months, years, etc
+the result will be one more than expected.
+For example,
+\(lqnext week\(rq
+will result in a time exactly two weeks from now, which is probably
+not what was intended.
+This will be addressed in a future version of
+\fBsudoreplay\fR.
+.SS "Debugging sudoreplay"
+\fBsudoreplay\fR
+versions 1.8.4 and higher support a flexible debugging framework
+that is configured via
+\fRDebug\fR
+lines in the
+sudo.conf(@mansectform@)
+file.
+.PP
+For more information on configuring
+sudo.conf(@mansectform@),
+please refer to its manual.
+.SH "FILES"
+.TP 26n
+\fI@sysconfdir@/sudo.conf\fR
+Debugging framework configuration
+.TP 26n
+\fI@iolog_dir@\fR
+The default I/O log directory.
+.TP 26n
+\fI@iolog_dir@/00/00/01/log\fR
+Example session log info.
+.TP 26n
+\fI@iolog_dir@/00/00/01/stdin\fR
+Example session standard input log.
+.TP 26n
+\fI@iolog_dir@/00/00/01/stdout\fR
+Example session standard output log.
+.TP 26n
+\fI@iolog_dir@/00/00/01/stderr\fR
+Example session standard error log.
+.TP 26n
+\fI@iolog_dir@/00/00/01/ttyin\fR
+Example session tty input file.
+.TP 26n
+\fI@iolog_dir@/00/00/01/ttyout\fR
+Example session tty output file.
+.TP 26n
+\fI@iolog_dir@/00/00/01/timing\fR
+Example session timing file.
+.PP
+Note that the
+\fIstdin\fR,
+\fIstdout\fR
+and
+\fIstderr\fR
+files will be empty unless
+\fBsudo\fR
+was used as part of a pipeline for a particular command.
+.SH "EXAMPLES"
+List sessions run by user
+\fImillert\fR:
+.nf
+.sp
+.RS 6n
+# sudoreplay -l user millert
+.RE
+.fi
+.PP
+List sessions run by user
+\fIbob\fR
+with a command containing the string vi:
+.nf
+.sp
+.RS 6n
+# sudoreplay -l user bob command vi
+.RE
+.fi
+.PP
+List sessions run by user
+\fIjeff\fR
+that match a regular expression:
+.nf
+.sp
+.RS 6n
+# sudoreplay -l user jeff command '/bin/[a-z]*sh'
+.RE
+.fi
+.PP
+List sessions run by jeff or bob on the console:
+.nf
+.sp
+.RS 6n
+# sudoreplay -l ( user jeff or user bob ) tty console
+.RE
+.fi
+.SH "SEE ALSO"
+script(1),
+sudo.conf(@mansectform@),
+sudo(@mansectsu@)
+.SH "AUTHORS"
+Many people have worked on
+\fBsudo\fR
+over the years; this version consists of code written primarily by:
+.sp
+.RS 6n
+Todd C. Miller
+.RE
+.PP
+See the CONTRIBUTORS file in the
+\fBsudo\fR
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+\fBsudo\fR.
+.SH "BUGS"
+If you feel you have found a bug in
+\fBsudoreplay\fR,
+please submit a bug report at https://bugzilla.sudo.ws/
+.SH "SUPPORT"
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.SH "DISCLAIMER"
+\fBsudoreplay\fR
+is provided
+\(lqAS IS\(rq
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+\fBsudo\fR
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/sudoreplay.mdoc.in b/doc/sudoreplay.mdoc.in
new file mode 100644
index 0000000..4eefaf6
--- /dev/null
+++ b/doc/sudoreplay.mdoc.in
@@ -0,0 +1,431 @@
+.\"
+.\" Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd October 6, 2018
+.Dt SUDOREPLAY @mansectsu@
+.Os Sudo @PACKAGE_VERSION@
+.Sh NAME
+.Nm sudoreplay
+.Nd replay sudo session logs
+.Sh SYNOPSIS
+.Nm sudoreplay
+.Op Fl hnRS
+.Op Fl d Ar dir
+.Op Fl f Ar filter
+.Op Fl m Ar num
+.Op Fl s Ar num
+ID
+.Pp
+.Nm
+.Op Fl h
+.Op Fl d Ar dir
+.Fl l
+.Op search expression
+.Sh DESCRIPTION
+.Nm
+plays back or lists the output logs created by
+.Nm sudo .
+When replaying,
+.Nm
+can play the session back in real-time, or the playback speed may be
+adjusted (faster or slower) based on the command line options.
+.Pp
+The
+.Em ID
+should either be a six character sequence of digits and
+upper case letters, e.g.,
+.Li 0100A5 ,
+or a pattern matching the
+.Em iolog_file
+option in the
+.Em sudoers
+file.
+When a command is run via
+.Nm sudo
+with
+.Em log_output
+enabled in the
+.Em sudoers
+file, a
+.Li TSID=ID
+string is logged via syslog or to the
+.Nm sudo
+log file.
+The
+.Em ID
+may also be determined using
+.Nm sudoreplay Ns 's
+list mode.
+.Pp
+In list mode,
+.Nm
+can be used to find the ID of a session based on a number of criteria
+such as the user, tty or command run.
+.Pp
+In replay mode, if the standard input and output are connected to a terminal
+and the
+.Fl n
+option is not specified,
+.Nm
+will operate interactively.
+In interactive mode,
+.Nm
+will attempt to adjust the terminal size to match that of the session and
+write directly to the terminal (not all terminals support this).
+Additionally, it will poll the keyboard and act on the following keys:
+.Bl -tag -width 12n
+.It So Li \en Sc No or So Li \er Sc
+Skip to the next replay event; useful for long pauses.
+.It So Li \ Sc Pq space
+Pause output; press any key to resume.
+.It Ql <
+Reduce the playback speed by one half.
+.It Ql >
+Double the playback speed.
+.El
+.Pp
+The session can be interrupted via control-C.
+When the session has finished, the terminal is restored to its
+original size if it was changed during playback.
+.Pp
+The options are as follows:
+.Bl -tag -width Fl
+.It Fl d Ar dir , Fl -directory Ns = Ns Ar dir
+Store session logs in
+.Ar dir
+instead of the default,
+.Pa @iolog_dir@ .
+.It Fl f Ar filter , Fl -filter Ns = Ns Ar filter
+Select which I/O type(s) to display.
+By default,
+.Nm
+will display the command's standard output, standard error and tty output.
+The
+.Ar filter
+argument is a comma-separated list, consisting of one or more of following:
+.Em stdin ,
+.Em stdout ,
+.Em stderr ,
+.Em ttyin ,
+and
+.Em ttyout .
+.It Fl h , -help
+Display a short help message to the standard output and exit.
+.It Fl l , -list Op Ar search expression
+Enable
+.Dq list mode .
+In this mode,
+.Nm
+will list available sessions in a format similar to the
+.Nm sudo
+log file format, sorted by file name (or sequence number).
+If a
+.Ar search expression
+is specified, it will be used to restrict the IDs that are displayed.
+An expression is composed of the following predicates:
+.Bl -tag -width 6n
+.It command Ar pattern
+Evaluates to true if the command run matches the POSIX extended
+regular expression
+.Ar pattern .
+.It cwd Ar directory
+Evaluates to true if the command was run with the specified current
+working directory.
+.It fromdate Ar date
+Evaluates to true if the command was run on or after
+.Ar date .
+See
+.Sx Date and time format
+for a description of supported date and time formats.
+.It group Ar runas_group
+Evaluates to true if the command was run with the specified
+.Ar runas_group .
+Note that unless a
+.Ar runas_group
+was explicitly specified when
+.Nm sudo
+was run this field will be empty in the log.
+.It runas Ar runas_user
+Evaluates to true if the command was run as the specified
+.Ar runas_user .
+Note that
+.Nm sudo
+runs commands as user
+.Em root
+by default.
+.It todate Ar date
+Evaluates to true if the command was run on or prior to
+.Ar date .
+See
+.Sx Date and time format
+for a description of supported date and time formats.
+.It tty Ar tty name
+Evaluates to true if the command was run on the specified terminal device.
+The
+.Ar tty name
+should be specified without the
+.Pa /dev/
+prefix, e.g.,
+.Pa tty01
+instead of
+.Pa /dev/tty01 .
+.It user Ar user name
+Evaluates to true if the ID matches a command run by
+.Ar user name .
+.El
+.Pp
+Predicates may be abbreviated to the shortest unique string.
+.Pp
+Predicates may be combined using
+.Em and ,
+.Em or
+and
+.Em \&!
+operators as well as
+.Ql \&(
+and
+.Ql \&)
+grouping (note that parentheses must generally be escaped from the shell).
+The
+.Em and
+operator is optional, adjacent predicates have an implied
+.Em and
+unless separated by an
+.Em or .
+.It Fl m , -max-wait Ar max_wait
+Specify an upper bound on how long to wait between key presses or output data.
+By default,
+.Nm
+will accurately reproduce the delays between key presses or program output.
+However, this can be tedious when the session includes long pauses.
+When the
+.Fl m
+option is specified,
+.Nm
+will limit these pauses to at most
+.Em max_wait
+seconds.
+The value may be specified as a floating point number, e.g.,
+.Em 2.5 .
+A
+.Em max_wait
+of zero or less will eliminate the pauses entirely.
+.It Fl n , -non-interactive
+Do not prompt for user input or attempt to re-size the terminal.
+The session is written to the standard output, not directly to
+the user's terminal.
+.It Fl R , -no-resize
+Do not attempt to re-size the terminal to match the terminal size
+of the session.
+.It Fl S , -suspend-wait
+Wait while the command was suspended.
+By default,
+.Nm
+will ignore the time interval between when the command was suspended
+and when it was resumed.
+If the
+.Fl S
+option is specified,
+.Nm
+will wait instead.
+.It Fl s , -speed Ar speed_factor
+This option causes
+.Nm
+to adjust the number of seconds it will wait between key presses or
+program output.
+This can be used to slow down or speed up the display.
+For example, a
+.Ar speed_factor
+of
+.Em 2
+would make the output twice as fast whereas a
+.Ar speed_factor
+of
+.Em .5
+would make the output twice as slow.
+.It Fl V , -version
+Print the
+.Nm
+versions version number and exit.
+.El
+.Ss Date and time format
+The time and date may be specified multiple ways, common formats include:
+.Bl -tag -width 6n
+.It HH:MM:SS am MM/DD/CCYY timezone
+24 hour time may be used in place of am/pm.
+.It HH:MM:SS am Month, Day Year timezone
+24 hour time may be used in place of am/pm, and month and day names
+may be abbreviated.
+Note that month and day of the week names must be specified in English.
+.It CCYY-MM-DD HH:MM:SS
+ISO time format
+.It DD Month CCYY HH:MM:SS
+The month name may be abbreviated.
+.El
+.Pp
+Either time or date may be omitted, the am/pm and timezone are optional.
+If no date is specified, the current day is assumed; if no time is
+specified, the first second of the specified date is used.
+The less significant parts of both time and date may also be omitted,
+in which case zero is assumed.
+.Pp
+The following are all valid time and date specifications:
+.Bl -tag -width 6n
+.It now
+The current time and date.
+.It tomorrow
+Exactly one day from now.
+.It yesterday
+24 hours ago.
+.It 2 hours ago
+2 hours ago.
+.It next Friday
+The first second of the Friday in the next (upcoming) week.
+Not to be confused with
+.Dq this Friday
+which would match the Friday of the current week.
+.It last week
+The current time but 7 days ago.
+This is equivalent to
+.Dq a week ago .
+.It a fortnight ago
+The current time but 14 days ago.
+.It 10:01 am 9/17/2009
+10:01 am, September 17, 2009.
+.It 10:01 am
+10:01 am on the current day.
+.It 10
+10:00 am on the current day.
+.It 9/17/2009
+00:00 am, September 17, 2009.
+.It 10:01 am Sep 17, 2009
+10:01 am, September 17, 2009.
+.El
+.Pp
+Note that relative time specifications do not always work as expected.
+For example, the
+.Dq next
+qualifier is intended to be used in conjunction with a day such as
+.Dq next Monday .
+When used with units of weeks, months, years, etc
+the result will be one more than expected.
+For example,
+.Dq next week
+will result in a time exactly two weeks from now, which is probably
+not what was intended.
+This will be addressed in a future version of
+.Nm .
+.Ss Debugging sudoreplay
+.Nm
+versions 1.8.4 and higher support a flexible debugging framework
+that is configured via
+.Li Debug
+lines in the
+.Xr sudo.conf @mansectform@
+file.
+.Pp
+For more information on configuring
+.Xr sudo.conf @mansectform@ ,
+please refer to its manual.
+.Sh FILES
+.Bl -tag -width 24n
+.It Pa @sysconfdir@/sudo.conf
+Debugging framework configuration
+.It Pa @iolog_dir@
+The default I/O log directory.
+.It Pa @iolog_dir@/00/00/01/log
+Example session log info.
+.It Pa @iolog_dir@/00/00/01/stdin
+Example session standard input log.
+.It Pa @iolog_dir@/00/00/01/stdout
+Example session standard output log.
+.It Pa @iolog_dir@/00/00/01/stderr
+Example session standard error log.
+.It Pa @iolog_dir@/00/00/01/ttyin
+Example session tty input file.
+.It Pa @iolog_dir@/00/00/01/ttyout
+Example session tty output file.
+.It Pa @iolog_dir@/00/00/01/timing
+Example session timing file.
+.El
+.Pp
+Note that the
+.Em stdin ,
+.Em stdout
+and
+.Em stderr
+files will be empty unless
+.Nm sudo
+was used as part of a pipeline for a particular command.
+.Sh EXAMPLES
+List sessions run by user
+.Em millert :
+.Bd -literal -offset indent
+# sudoreplay -l user millert
+.Ed
+.Pp
+List sessions run by user
+.Em bob
+with a command containing the string vi:
+.Bd -literal -offset indent
+# sudoreplay -l user bob command vi
+.Ed
+.Pp
+List sessions run by user
+.Em jeff
+that match a regular expression:
+.Bd -literal -offset indent
+# sudoreplay -l user jeff command '/bin/[a-z]*sh'
+.Ed
+.Pp
+List sessions run by jeff or bob on the console:
+.Bd -literal -offset indent
+# sudoreplay -l ( user jeff or user bob ) tty console
+.Ed
+.Sh SEE ALSO
+.Xr script 1 ,
+.Xr sudo.conf @mansectform@ ,
+.Xr sudo @mansectsu@
+.Sh AUTHORS
+Many people have worked on
+.Nm sudo
+over the years; this version consists of code written primarily by:
+.Bd -ragged -offset indent
+.An Todd C. Miller
+.Ed
+.Pp
+See the CONTRIBUTORS file in the
+.Nm sudo
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+.Nm sudo .
+.Sh BUGS
+If you feel you have found a bug in
+.Nm ,
+please submit a bug report at https://bugzilla.sudo.ws/
+.Sh SUPPORT
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.Sh DISCLAIMER
+.Nm
+is provided
+.Dq AS IS
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+.Nm sudo
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/visudo.cat b/doc/visudo.cat
new file mode 100644
index 0000000..ac5eca3
--- /dev/null
+++ b/doc/visudo.cat
@@ -0,0 +1,226 @@
+VISUDO(1m) System Manager's Manual VISUDO(1m)
+
+NNAAMMEE
+ vviissuuddoo - edit the sudoers file
+
+SSYYNNOOPPSSIISS
+ vviissuuddoo [--cchhqqssVV] [[--ff] _s_u_d_o_e_r_s]
+
+DDEESSCCRRIIPPTTIIOONN
+ vviissuuddoo edits the _s_u_d_o_e_r_s file in a safe fashion, analogous to vipw(1m).
+ vviissuuddoo locks the _s_u_d_o_e_r_s file against multiple simultaneous edits,
+ provides basic sanity checks, and checks for parse errors. If the
+ _s_u_d_o_e_r_s file is currently being edited you will receive a message to try
+ again later.
+
+ vviissuuddoo parses the _s_u_d_o_e_r_s file after editing and will not save the
+ changes if there is a syntax error. Upon finding an error, vviissuuddoo will
+ print a message stating the line number(s) where the error occurred and
+ the user will receive the "What now?" prompt. At this point the user may
+ enter `e' to re-edit the _s_u_d_o_e_r_s file, `x' to exit without saving the
+ changes, or `Q' to quit and save changes. The `Q' option should be used
+ with extreme caution because if vviissuuddoo believes there to be a parse
+ error, so will ssuuddoo and no one will be able to run ssuuddoo again until the
+ error is fixed. If `e' is typed to edit the _s_u_d_o_e_r_s file after a parse
+ error has been detected, the cursor will be placed on the line where the
+ error occurred (if the editor supports this feature).
+
+ There are two _s_u_d_o_e_r_s settings that determine which editor vviissuuddoo will
+ run.
+
+ editor A colon (`:') separated list of editors allowed to be used with
+ vviissuuddoo. vviissuuddoo will choose the editor that matches the user's
+ SUDO_EDITOR, VISUAL or EDITOR environment variable if possible,
+ or the first editor in the list that exists and is executable.
+ Note that the SUDO_EDITOR, VISUAL and EDITOR environment
+ variables are not preserved by default when the _e_n_v___r_e_s_e_t
+ _s_u_d_o_e_r_s option is enabled. The default editor path is _v_i which
+ can be set at compile time via the --with-editor configure
+ option.
+
+ env_editor
+ If set, vviissuuddoo will use the value of the SUDO_EDITOR, VISUAL or
+ EDITOR environment variables before falling back on the default
+ editor list. Note that this may create a security hole as it
+ allows the user to run any arbitrary command as root without
+ logging. A safer alternative is to place a colon-separated
+ list of editors in the _e_d_i_t_o_r variable. vviissuuddoo will then only
+ use SUDO_EDITOR, VISUAL or EDITOR if they match a value
+ specified in _e_d_i_t_o_r. If the _e_n_v___r_e_s_e_t flag is enabled, the
+ SUDO_EDITOR, VISUAL and/or EDITOR environment variables must be
+ present in the _e_n_v___k_e_e_p list for the _e_n_v___e_d_i_t_o_r flag to
+ function when vviissuuddoo is invoked via ssuuddoo. The default value is
+ _o_f_f, which can be set at compile time via the --with-env-editor
+ configure option.
+
+ The options are as follows:
+
+ --cc, ----cchheecckk
+ Enable _c_h_e_c_k_-_o_n_l_y mode. The existing _s_u_d_o_e_r_s file (and any
+ other files it includes) will be checked for syntax errors.
+ If the path to the _s_u_d_o_e_r_s file was not specified, vviissuuddoo
+ will also check the file owner and mode. A message will be
+ printed to the standard output describing the status of
+ _s_u_d_o_e_r_s unless the --qq option was specified. If the check
+ completes successfully, vviissuuddoo will exit with a value of 0.
+ If an error is encountered, vviissuuddoo will exit with a value of
+ 1.
+
+ --ff _s_u_d_o_e_r_s, ----ffiillee=_s_u_d_o_e_r_s
+ Specify an alternate _s_u_d_o_e_r_s file location, see below. As of
+ version 1.8.27, the _s_u_d_o_e_r_s path can be specified without
+ using the --ff option.
+
+ --hh, ----hheellpp Display a short help message to the standard output and exit.
+
+ --qq, ----qquuiieett
+ Enable _q_u_i_e_t mode. In this mode details about syntax errors
+ are not printed. This option is only useful when combined
+ with the --cc option.
+
+ --ss, ----ssttrriicctt
+ Enable _s_t_r_i_c_t checking of the _s_u_d_o_e_r_s file. If an alias is
+ referenced but not actually defined or if there is a cycle in
+ an alias, vviissuuddoo will consider this a parse error. Note that
+ it is not possible to differentiate between an alias and a
+ host name or user name that consists solely of uppercase
+ letters, digits, and the underscore (`_') character.
+
+ --VV, ----vveerrssiioonn
+ Print the vviissuuddoo and _s_u_d_o_e_r_s grammar versions and exit.
+
+ A _s_u_d_o_e_r_s file may be specified instead of the default, _/_e_t_c_/_s_u_d_o_e_r_s.
+ The lock file used is the specified _s_u_d_o_e_r_s file with ".tmp" appended to
+ it. In _c_h_e_c_k_-_o_n_l_y mode only, `-' may be used to indicate that _s_u_d_o_e_r_s
+ will be read from the standard input. Because the policy is evaluated in
+ its entirety, it is not sufficient to check an individual _s_u_d_o_e_r_s include
+ file for syntax errors.
+
+ DDeebbuuggggiinngg aanndd ssuuddooeerrss pplluuggiinn aarrgguummeennttss
+ vviissuuddoo versions 1.8.4 and higher support a flexible debugging framework
+ that is configured via Debug lines in the sudo.conf(4) file.
+
+ Starting with ssuuddoo 1.8.12, vviissuuddoo will also parse the arguments to the
+ _s_u_d_o_e_r_s plugin to override the default _s_u_d_o_e_r_s path name, UID, GID and
+ file mode. These arguments, if present, should be listed after the path
+ to the plugin (i.e., after _s_u_d_o_e_r_s_._s_o). Multiple arguments may be
+ specified, separated by white space. For example:
+
+ Plugin sudoers_policy sudoers.so sudoers_mode=0400
+
+ The following arguments are supported:
+
+ sudoers_file=pathname
+ The _s_u_d_o_e_r_s___f_i_l_e argument can be used to override the default
+ path to the _s_u_d_o_e_r_s file.
+
+ sudoers_uid=uid
+ The _s_u_d_o_e_r_s___u_i_d argument can be used to override the default
+ owner of the sudoers file. It should be specified as a numeric
+ user ID.
+
+ sudoers_gid=gid
+ The _s_u_d_o_e_r_s___g_i_d argument can be used to override the default
+ group of the sudoers file. It must be specified as a numeric
+ group ID (not a group name).
+
+ sudoers_mode=mode
+ The _s_u_d_o_e_r_s___m_o_d_e argument can be used to override the default
+ file mode for the sudoers file. It should be specified as an
+ octal value.
+
+ For more information on configuring sudo.conf(4), please refer to its
+ manual.
+
+EENNVVIIRROONNMMEENNTT
+ The following environment variables may be consulted depending on the
+ value of the _e_d_i_t_o_r and _e_n_v___e_d_i_t_o_r _s_u_d_o_e_r_s settings:
+
+ SUDO_EDITOR Invoked by vviissuuddoo as the editor to use
+
+ VISUAL Used by vviissuuddoo if SUDO_EDITOR is not set
+
+ EDITOR Used by vviissuuddoo if neither SUDO_EDITOR nor VISUAL is set
+
+FFIILLEESS
+ _/_e_t_c_/_s_u_d_o_._c_o_n_f Sudo front end configuration
+
+ _/_e_t_c_/_s_u_d_o_e_r_s List of who can run what
+
+ _/_e_t_c_/_s_u_d_o_e_r_s_._t_m_p Lock file for visudo
+
+DDIIAAGGNNOOSSTTIICCSS
+ In addition to reporting _s_u_d_o_e_r_s parse errors, vviissuuddoo may produce the
+ following messages:
+
+ sudoers file busy, try again later.
+ Someone else is currently editing the _s_u_d_o_e_r_s file.
+
+ /etc/sudoers.tmp: Permission denied
+ You didn't run vviissuuddoo as root.
+
+ you do not exist in the passwd database
+ Your user ID does not appear in the system passwd database.
+
+ Warning: {User,Runas,Host,Cmnd}_Alias referenced but not defined
+ Either you are trying to use an undeclared
+ {User,Runas,Host,Cmnd}_Alias or you have a user or host name listed
+ that consists solely of uppercase letters, digits, and the
+ underscore (`_') character. In the latter case, you can ignore the
+ warnings (ssuuddoo will not complain). The message is prefixed with
+ the path name of the _s_u_d_o_e_r_s file and the line number where the
+ undefined alias was used. In --ss (strict) mode these are errors,
+ not warnings.
+
+ Warning: unused {User,Runas,Host,Cmnd}_Alias
+ The specified {User,Runas,Host,Cmnd}_Alias was defined but never
+ used. The message is prefixed with the path name of the _s_u_d_o_e_r_s
+ file and the line number where the unused alias was defined. You
+ may wish to comment out or remove the unused alias.
+
+ Warning: cycle in {User,Runas,Host,Cmnd}_Alias
+ The specified {User,Runas,Host,Cmnd}_Alias includes a reference to
+ itself, either directly or through an alias it includes. The
+ message is prefixed with the path name of the _s_u_d_o_e_r_s file and the
+ line number where the cycle was detected. This is only a warning
+ unless vviissuuddoo is run in --ss (strict) mode as ssuuddoo will ignore cycles
+ when parsing the _s_u_d_o_e_r_s file.
+
+ unknown defaults entry "name"
+ The _s_u_d_o_e_r_s file contains a Defaults setting not recognized by
+ vviissuuddoo.
+
+SSEEEE AALLSSOO
+ vi(1), sudo.conf(4), sudoers(4), sudo(1m), vipw(1m)
+
+AAUUTTHHOORRSS
+ Many people have worked on ssuuddoo over the years; this version consists of
+ code written primarily by:
+
+ Todd C. Miller
+
+ See the CONTRIBUTORS file in the ssuuddoo distribution
+ (https://www.sudo.ws/contributors.html) for an exhaustive list of people
+ who have contributed to ssuuddoo.
+
+CCAAVVEEAATTSS
+ There is no easy way to prevent a user from gaining a root shell if the
+ editor used by vviissuuddoo allows shell escapes.
+
+BBUUGGSS
+ If you feel you have found a bug in vviissuuddoo, please submit a bug report at
+ https://bugzilla.sudo.ws/
+
+SSUUPPPPOORRTT
+ Limited free support is available via the sudo-users mailing list, see
+ https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search
+ the archives.
+
+DDIISSCCLLAAIIMMEERR
+ vviissuuddoo is provided "AS IS" and any express or implied warranties,
+ including, but not limited to, the implied warranties of merchantability
+ and fitness for a particular purpose are disclaimed. See the LICENSE
+ file distributed with ssuuddoo or https://www.sudo.ws/license.html for
+ complete details.
+
+Sudo 1.8.26 December 24, 2018 Sudo 1.8.26
diff --git a/doc/visudo.man.in b/doc/visudo.man.in
new file mode 100644
index 0000000..9d6fc48
--- /dev/null
+++ b/doc/visudo.man.in
@@ -0,0 +1,465 @@
+.\" Automatically generated from an mdoc input file. Do not edit.
+.\"
+.\" Copyright (c) 1996,1998-2005, 2007-2018
+.\" Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Sponsored in part by the Defense Advanced Research Projects
+.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
+.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
+.\"
+.TH "VISUDO" "@mansectsu@" "December 24, 2018" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
+.nh
+.if n .ad l
+.SH "NAME"
+\fBvisudo\fR
+\- edit the sudoers file
+.SH "SYNOPSIS"
+.HP 7n
+\fBvisudo\fR
+[\fB\-chqsV\fR]
+[[\fB\-f\fR]\ \fIsudoers\fR]
+.SH "DESCRIPTION"
+\fBvisudo\fR
+edits the
+\fIsudoers\fR
+file in a safe fashion, analogous to
+vipw(@mansectsu@).
+\fBvisudo\fR
+locks the
+\fIsudoers\fR
+file against multiple simultaneous edits, provides basic sanity checks,
+and checks for parse errors.
+If the
+\fIsudoers\fR
+file is currently being edited you will receive a message to try again later.
+.PP
+\fBvisudo\fR
+parses the
+\fIsudoers\fR
+file after editing and will not save the changes if there is a syntax error.
+Upon finding an error,
+\fBvisudo\fR
+will print a message stating the line number(s)
+where the error occurred and the user will receive the
+\(lqWhat now?\(rq
+prompt.
+At this point the user may enter
+\(oqe\(cq
+to re-edit the
+\fIsudoers\fR
+file,
+\(oqx\(cq
+to exit without saving the changes, or
+\(oqQ\(cq
+to quit and save changes.
+The
+\(oqQ\(cq
+option should be used with extreme caution because if
+\fBvisudo\fR
+believes there to be a parse error, so will
+\fBsudo\fR
+and no one
+will be able to run
+\fBsudo\fR
+again until the error is fixed.
+If
+\(oqe\(cq
+is typed to edit the
+\fIsudoers\fR
+file after a parse error has been detected, the cursor will be placed on
+the line where the error occurred (if the editor supports this feature).
+.PP
+There are two
+\fIsudoers\fR
+settings that determine which editor
+\fBvisudo\fR
+will run.
+.TP 10n
+editor
+A colon
+(\(oq:\&\(cq)
+separated list of editors allowed to be used with
+\fBvisudo\fR.
+\fBvisudo\fR
+will choose the editor that matches the user's
+\fRSUDO_EDITOR\fR,
+\fRVISUAL\fR
+or
+\fREDITOR\fR
+environment variable if possible, or the first editor in the
+list that exists and is executable.
+Note that the
+\fRSUDO_EDITOR\fR,
+\fRVISUAL\fR
+and
+\fREDITOR\fR
+environment variables are not preserved by default when the
+\fIenv_reset\fR
+\fIsudoers\fR
+option is enabled.
+The default editor path is
+\fI@editor@\fR
+which can be set at compile time via the
+\fR--with-editor\fR
+configure option.
+.TP 10n
+env_editor
+If set,
+\fBvisudo\fR
+will use the value of the
+\fRSUDO_EDITOR\fR,
+\fRVISUAL\fR
+or
+\fREDITOR\fR
+environment variables before falling back on the default editor list.
+Note that this may create a security hole as it allows the user to
+run any arbitrary command as root without logging.
+A safer alternative is to place a colon-separated list of editors
+in the
+\fIeditor\fR
+variable.
+\fBvisudo\fR
+will then only use
+\fRSUDO_EDITOR\fR,
+\fRVISUAL\fR
+or
+\fREDITOR\fR
+if they match a value specified in
+\fIeditor\fR.
+If the
+\fIenv_reset\fR
+flag is enabled, the
+\fRSUDO_EDITOR\fR,
+\fRVISUAL\fR
+and/or
+\fREDITOR\fR
+environment variables must be present in the
+\fIenv_keep\fR
+list for the
+\fIenv_editor\fR
+flag to function when
+\fBvisudo\fR
+is invoked via
+\fBsudo\fR.
+The default value is
+\fI@env_editor@\fR,
+which can be set at compile time via the
+\fR--with-env-editor\fR
+configure option.
+.PP
+The options are as follows:
+.TP 12n
+\fB\-c\fR, \fB\--check\fR
+Enable
+\fIcheck-only\fR
+mode.
+The existing
+\fIsudoers\fR
+file (and any other files it includes) will be
+checked for syntax errors.
+If the path to the
+\fIsudoers\fR
+file was not specified,
+\fBvisudo\fR
+will also check the file owner and mode.
+A message will be printed to the standard output describing the status of
+\fIsudoers\fR
+unless the
+\fB\-q\fR
+option was specified.
+If the check completes successfully,
+\fBvisudo\fR
+will exit with a value of 0.
+If an error is encountered,
+\fBvisudo\fR
+will exit with a value of 1.
+.TP 12n
+\fB\-f\fR \fIsudoers\fR, \fB\--file\fR=\fIsudoers\fR
+Specify an alternate
+\fIsudoers\fR
+file location, see below.
+As of version 1.8.27, the
+\fIsudoers\fR
+path can be specified without using the
+\fB\-f\fR
+option.
+.TP 12n
+\fB\-h\fR, \fB\--help\fR
+Display a short help message to the standard output and exit.
+.TP 12n
+\fB\-q\fR, \fB\--quiet\fR
+Enable
+\fIquiet\fR
+mode.
+In this mode details about syntax errors are not printed.
+This option is only useful when combined with
+the
+\fB\-c\fR
+option.
+.TP 12n
+\fB\-s\fR, \fB\--strict\fR
+Enable
+\fIstrict\fR
+checking of the
+\fIsudoers\fR
+file.
+If an alias is referenced but not actually defined
+or if there is a cycle in an alias,
+\fBvisudo\fR
+will consider this a parse error.
+Note that it is not possible to differentiate between an
+alias and a host name or user name that consists solely of uppercase
+letters, digits, and the underscore
+(\(oq_\(cq)
+character.
+.TP 12n
+\fB\-V\fR, \fB\--version\fR
+Print the
+\fBvisudo\fR
+and
+\fIsudoers\fR
+grammar versions and exit.
+.PP
+A
+\fIsudoers\fR
+file may be specified instead of the default,
+\fI@sysconfdir@/sudoers\fR.
+The lock file used is the specified
+\fIsudoers\fR
+file with
+\(lq\.tmp\(rq
+appended to it.
+In
+\fIcheck-only\fR
+mode only,
+\(oq-\(cq
+may be used to indicate that
+\fIsudoers\fR
+will be read from the standard input.
+Because the policy is evaluated in its entirety, it is not sufficient
+to check an individual
+\fIsudoers\fR
+include file for syntax errors.
+.SS "Debugging and sudoers plugin arguments"
+\fBvisudo\fR
+versions 1.8.4 and higher support a flexible debugging framework
+that is configured via
+\fRDebug\fR
+lines in the
+sudo.conf(@mansectform@)
+file.
+.PP
+Starting with
+\fBsudo\fR
+1.8.12,
+\fBvisudo\fR
+will also parse the arguments to the
+\fIsudoers\fR
+plugin to override the default
+\fIsudoers\fR
+path name, UID, GID and file mode.
+These arguments, if present, should be listed after the path to the plugin
+(i.e., after
+\fIsudoers.so\fR).
+Multiple arguments may be specified, separated by white space.
+For example:
+.nf
+.sp
+.RS 6n
+Plugin sudoers_policy sudoers.so sudoers_mode=0400
+.RE
+.fi
+.PP
+The following arguments are supported:
+.TP 10n
+sudoers_file=pathname
+The
+\fIsudoers_file\fR
+argument can be used to override the default path to the
+\fIsudoers\fR
+file.
+.TP 10n
+sudoers_uid=uid
+The
+\fIsudoers_uid\fR
+argument can be used to override the default owner of the sudoers file.
+It should be specified as a numeric user ID.
+.TP 10n
+sudoers_gid=gid
+The
+\fIsudoers_gid\fR
+argument can be used to override the default group of the sudoers file.
+It must be specified as a numeric group ID (not a group name).
+.TP 10n
+sudoers_mode=mode
+The
+\fIsudoers_mode\fR
+argument can be used to override the default file mode for the sudoers file.
+It should be specified as an octal value.
+.PP
+For more information on configuring
+sudo.conf(@mansectform@),
+please refer to its manual.
+.SH "ENVIRONMENT"
+The following environment variables may be consulted depending on
+the value of the
+\fIeditor\fR
+and
+\fIenv_editor\fR
+\fIsudoers\fR
+settings:
+.TP 17n
+\fRSUDO_EDITOR\fR
+Invoked by
+\fBvisudo\fR
+as the editor to use
+.TP 17n
+\fRVISUAL\fR
+Used by
+\fBvisudo\fR
+if
+\fRSUDO_EDITOR\fR
+is not set
+.TP 17n
+\fREDITOR\fR
+Used by
+\fBvisudo\fR
+if neither
+\fRSUDO_EDITOR\fR
+nor
+\fRVISUAL\fR
+is set
+.SH "FILES"
+.TP 26n
+\fI@sysconfdir@/sudo.conf\fR
+Sudo front end configuration
+.TP 26n
+\fI@sysconfdir@/sudoers\fR
+List of who can run what
+.TP 26n
+\fI@sysconfdir@/sudoers.tmp\fR
+Lock file for visudo
+.SH "DIAGNOSTICS"
+In addition to reporting
+\fIsudoers\fR
+parse errors,
+\fBvisudo\fR
+may produce the following messages:
+.TP 6n
+\fRsudoers file busy, try again later.\fR
+Someone else is currently editing the
+\fIsudoers\fR
+file.
+.TP 6n
+\fR@sysconfdir@/sudoers.tmp: Permission denied\fR
+You didn't run
+\fBvisudo\fR
+as root.
+.TP 6n
+\fRyou do not exist in the passwd database\fR
+Your user ID does not appear in the system passwd database.
+.TP 6n
+\fRWarning: {User,Runas,Host,Cmnd}_Alias referenced but not defined\fR
+Either you are trying to use an undeclared {User,Runas,Host,Cmnd}_Alias
+or you have a user or host name listed that consists solely of
+uppercase letters, digits, and the underscore
+(\(oq_\(cq)
+character.
+In the latter case, you can ignore the warnings
+(\fBsudo\fR
+will not complain)
+\&.
+The message is prefixed with the path name of the
+\fIsudoers\fR
+file and the line number where the undefined alias was used.
+In
+\fB\-s\fR
+(strict) mode these are errors, not warnings.
+.TP 6n
+\fRWarning: unused {User,Runas,Host,Cmnd}_Alias\fR
+The specified {User,Runas,Host,Cmnd}_Alias was defined but never
+used.
+The message is prefixed with the path name of the
+\fIsudoers\fR
+file and the line number where the unused alias was defined.
+You may wish to comment out or remove the unused alias.
+.TP 6n
+\fRWarning: cycle in {User,Runas,Host,Cmnd}_Alias\fR
+The specified {User,Runas,Host,Cmnd}_Alias includes a reference to
+itself, either directly or through an alias it includes.
+The message is prefixed with the path name of the
+\fIsudoers\fR
+file and the line number where the cycle was detected.
+This is only a warning unless
+\fBvisudo\fR
+is run in
+\fB\-s\fR
+(strict) mode as
+\fBsudo\fR
+will ignore cycles when parsing
+the
+\fIsudoers\fR
+file.
+.TP 6n
+\fRunknown defaults entry \&"name\&"\fR
+The
+\fIsudoers\fR
+file contains a
+\fRDefaults\fR
+setting not recognized by
+\fBvisudo\fR.
+.SH "SEE ALSO"
+vi(1),
+sudo.conf(@mansectform@),
+sudoers(@mansectform@),
+sudo(@mansectsu@),
+vipw(@mansectsu@)
+.SH "AUTHORS"
+Many people have worked on
+\fBsudo\fR
+over the years; this version consists of code written primarily by:
+.sp
+.RS 6n
+Todd C. Miller
+.RE
+.PP
+See the CONTRIBUTORS file in the
+\fBsudo\fR
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+\fBsudo\fR.
+.SH "CAVEATS"
+There is no easy way to prevent a user from gaining a root shell if
+the editor used by
+\fBvisudo\fR
+allows shell escapes.
+.SH "BUGS"
+If you feel you have found a bug in
+\fBvisudo\fR,
+please submit a bug report at https://bugzilla.sudo.ws/
+.SH "SUPPORT"
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.SH "DISCLAIMER"
+\fBvisudo\fR
+is provided
+\(lqAS IS\(rq
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+\fBsudo\fR
+or https://www.sudo.ws/license.html for complete details.
diff --git a/doc/visudo.mdoc.in b/doc/visudo.mdoc.in
new file mode 100644
index 0000000..140d5d6
--- /dev/null
+++ b/doc/visudo.mdoc.in
@@ -0,0 +1,447 @@
+.\"
+.\" Copyright (c) 1996,1998-2005, 2007-2018
+.\" Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Sponsored in part by the Defense Advanced Research Projects
+.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
+.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
+.\"
+.Dd December 24, 2018
+.Dt VISUDO @mansectsu@
+.Os Sudo @PACKAGE_VERSION@
+.Sh NAME
+.Nm visudo
+.Nd edit the sudoers file
+.Sh SYNOPSIS
+.Nm visudo
+.Op Fl chqsV
+.Op Bo Fl f Bc Ar sudoers
+.Sh DESCRIPTION
+.Nm
+edits the
+.Em sudoers
+file in a safe fashion, analogous to
+.Xr vipw @mansectsu@ .
+.Nm
+locks the
+.Em sudoers
+file against multiple simultaneous edits, provides basic sanity checks,
+and checks for parse errors.
+If the
+.Em sudoers
+file is currently being edited you will receive a message to try again later.
+.Pp
+.Nm
+parses the
+.Em sudoers
+file after editing and will not save the changes if there is a syntax error.
+Upon finding an error,
+.Nm
+will print a message stating the line number(s)
+where the error occurred and the user will receive the
+.Dq What now?
+prompt.
+At this point the user may enter
+.Ql e
+to re-edit the
+.Em sudoers
+file,
+.Ql x
+to exit without saving the changes, or
+.Ql Q
+to quit and save changes.
+The
+.Ql Q
+option should be used with extreme caution because if
+.Nm
+believes there to be a parse error, so will
+.Nm sudo
+and no one
+will be able to run
+.Nm sudo
+again until the error is fixed.
+If
+.Ql e
+is typed to edit the
+.Em sudoers
+file after a parse error has been detected, the cursor will be placed on
+the line where the error occurred (if the editor supports this feature).
+.Pp
+There are two
+.Em sudoers
+settings that determine which editor
+.Nm visudo
+will run.
+.Bl -tag -width 8n
+.It editor
+A colon
+.Pq Ql :\&
+separated list of editors allowed to be used with
+.Nm .
+.Nm
+will choose the editor that matches the user's
+.Ev SUDO_EDITOR ,
+.Ev VISUAL
+or
+.Ev EDITOR
+environment variable if possible, or the first editor in the
+list that exists and is executable.
+Note that the
+.Ev SUDO_EDITOR ,
+.Ev VISUAL
+and
+.Ev EDITOR
+environment variables are not preserved by default when the
+.Em env_reset
+.Em sudoers
+option is enabled.
+The default editor path is
+.Pa @editor@
+which can be set at compile time via the
+.Li --with-editor
+configure option.
+.It env_editor
+If set,
+.Nm
+will use the value of the
+.Ev SUDO_EDITOR ,
+.Ev VISUAL
+or
+.Ev EDITOR
+environment variables before falling back on the default editor list.
+Note that this may create a security hole as it allows the user to
+run any arbitrary command as root without logging.
+A safer alternative is to place a colon-separated list of editors
+in the
+.Em editor
+variable.
+.Nm
+will then only use
+.Ev SUDO_EDITOR ,
+.Ev VISUAL
+or
+.Ev EDITOR
+if they match a value specified in
+.Em editor .
+If the
+.Em env_reset
+flag is enabled, the
+.Ev SUDO_EDITOR ,
+.Ev VISUAL
+and/or
+.Ev EDITOR
+environment variables must be present in the
+.Em env_keep
+list for the
+.Em env_editor
+flag to function when
+.Nm
+is invoked via
+.Nm sudo .
+The default value is
+.Em @env_editor@ ,
+which can be set at compile time via the
+.Li --with-env-editor
+configure option.
+.El
+.Pp
+The options are as follows:
+.Bl -tag -width Fl
+.It Fl c , -check
+Enable
+.Em check-only
+mode.
+The existing
+.Em sudoers
+file (and any other files it includes) will be
+checked for syntax errors.
+If the path to the
+.Em sudoers
+file was not specified,
+.Nm
+will also check the file owner and mode.
+A message will be printed to the standard output describing the status of
+.Em sudoers
+unless the
+.Fl q
+option was specified.
+If the check completes successfully,
+.Nm
+will exit with a value of 0.
+If an error is encountered,
+.Nm
+will exit with a value of 1.
+.It Fl f Ar sudoers , Fl -file Ns = Ns Ar sudoers
+Specify an alternate
+.Em sudoers
+file location, see below.
+As of version 1.8.27, the
+.Em sudoers
+path can be specified without using the
+.Fl f
+option.
+.It Fl h , -help
+Display a short help message to the standard output and exit.
+.It Fl q , -quiet
+Enable
+.Em quiet
+mode.
+In this mode details about syntax errors are not printed.
+This option is only useful when combined with
+the
+.Fl c
+option.
+.It Fl s , -strict
+Enable
+.Em strict
+checking of the
+.Em sudoers
+file.
+If an alias is referenced but not actually defined
+or if there is a cycle in an alias,
+.Nm
+will consider this a parse error.
+Note that it is not possible to differentiate between an
+alias and a host name or user name that consists solely of uppercase
+letters, digits, and the underscore
+.Pq Ql _
+character.
+.It Fl V , -version
+Print the
+.Nm
+and
+.Em sudoers
+grammar versions and exit.
+.El
+.Pp
+A
+.Em sudoers
+file may be specified instead of the default,
+.Pa @sysconfdir@/sudoers .
+The lock file used is the specified
+.Em sudoers
+file with
+.Dq \.tmp
+appended to it.
+In
+.Em check-only
+mode only,
+.Ql -
+may be used to indicate that
+.Em sudoers
+will be read from the standard input.
+Because the policy is evaluated in its entirety, it is not sufficient
+to check an individual
+.Em sudoers
+include file for syntax errors.
+.Ss Debugging and sudoers plugin arguments
+.Nm
+versions 1.8.4 and higher support a flexible debugging framework
+that is configured via
+.Li Debug
+lines in the
+.Xr sudo.conf @mansectform@
+file.
+.Pp
+Starting with
+.Nm sudo
+1.8.12,
+.Nm
+will also parse the arguments to the
+.Em sudoers
+plugin to override the default
+.Em sudoers
+path name, UID, GID and file mode.
+These arguments, if present, should be listed after the path to the plugin
+(i.e., after
+.Pa sudoers.so ) .
+Multiple arguments may be specified, separated by white space.
+For example:
+.Bd -literal -offset indent
+Plugin sudoers_policy sudoers.so sudoers_mode=0400
+.Ed
+.Pp
+The following arguments are supported:
+.Bl -tag -width 8n
+.It sudoers_file=pathname
+The
+.Em sudoers_file
+argument can be used to override the default path to the
+.Em sudoers
+file.
+.It sudoers_uid=uid
+The
+.Em sudoers_uid
+argument can be used to override the default owner of the sudoers file.
+It should be specified as a numeric user ID.
+.It sudoers_gid=gid
+The
+.Em sudoers_gid
+argument can be used to override the default group of the sudoers file.
+It must be specified as a numeric group ID (not a group name).
+.It sudoers_mode=mode
+The
+.Em sudoers_mode
+argument can be used to override the default file mode for the sudoers file.
+It should be specified as an octal value.
+.El
+.Pp
+For more information on configuring
+.Xr sudo.conf @mansectform@ ,
+please refer to its manual.
+.Sh ENVIRONMENT
+The following environment variables may be consulted depending on
+the value of the
+.Em editor
+and
+.Em env_editor
+.Em sudoers
+settings:
+.Bl -tag -width 15n
+.It Ev SUDO_EDITOR
+Invoked by
+.Nm
+as the editor to use
+.It Ev VISUAL
+Used by
+.Nm
+if
+.Ev SUDO_EDITOR
+is not set
+.It Ev EDITOR
+Used by
+.Nm
+if neither
+.Ev SUDO_EDITOR
+nor
+.Ev VISUAL
+is set
+.El
+.Sh FILES
+.Bl -tag -width 24n
+.It Pa @sysconfdir@/sudo.conf
+Sudo front end configuration
+.It Pa @sysconfdir@/sudoers
+List of who can run what
+.It Pa @sysconfdir@/sudoers.tmp
+Lock file for visudo
+.El
+.Sh DIAGNOSTICS
+In addition to reporting
+.Em sudoers
+parse errors,
+.Nm
+may produce the following messages:
+.Bl -tag -width 4n
+.It Li sudoers file busy, try again later.
+Someone else is currently editing the
+.Em sudoers
+file.
+.It Li @sysconfdir@/sudoers.tmp: Permission denied
+You didn't run
+.Nm
+as root.
+.It Li you do not exist in the passwd database
+Your user ID does not appear in the system passwd database.
+.It Li Warning: {User,Runas,Host,Cmnd}_Alias referenced but not defined
+Either you are trying to use an undeclared {User,Runas,Host,Cmnd}_Alias
+or you have a user or host name listed that consists solely of
+uppercase letters, digits, and the underscore
+.Pq Ql _
+character.
+In the latter case, you can ignore the warnings
+.Po
+.Nm sudo
+will not complain
+.Pc .
+The message is prefixed with the path name of the
+.Em sudoers
+file and the line number where the undefined alias was used.
+In
+.Fl s
+(strict) mode these are errors, not warnings.
+.It Li Warning: unused {User,Runas,Host,Cmnd}_Alias
+The specified {User,Runas,Host,Cmnd}_Alias was defined but never
+used.
+The message is prefixed with the path name of the
+.Em sudoers
+file and the line number where the unused alias was defined.
+You may wish to comment out or remove the unused alias.
+.It Li Warning: cycle in {User,Runas,Host,Cmnd}_Alias
+The specified {User,Runas,Host,Cmnd}_Alias includes a reference to
+itself, either directly or through an alias it includes.
+The message is prefixed with the path name of the
+.Em sudoers
+file and the line number where the cycle was detected.
+This is only a warning unless
+.Nm
+is run in
+.Fl s
+(strict) mode as
+.Nm sudo
+will ignore cycles when parsing
+the
+.Em sudoers
+file.
+.It Li unknown defaults entry \&"name\&"
+The
+.Em sudoers
+file contains a
+.Li Defaults
+setting not recognized by
+.Nm .
+.El
+.Sh SEE ALSO
+.Xr vi 1 ,
+.Xr sudo.conf @mansectform@ ,
+.Xr sudoers @mansectform@ ,
+.Xr sudo @mansectsu@ ,
+.Xr vipw @mansectsu@
+.Sh AUTHORS
+Many people have worked on
+.Nm sudo
+over the years; this version consists of code written primarily by:
+.Bd -ragged -offset indent
+.An Todd C. Miller
+.Ed
+.Pp
+See the CONTRIBUTORS file in the
+.Nm sudo
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+.Nm sudo .
+.Sh CAVEATS
+There is no easy way to prevent a user from gaining a root shell if
+the editor used by
+.Nm
+allows shell escapes.
+.Sh BUGS
+If you feel you have found a bug in
+.Nm ,
+please submit a bug report at https://bugzilla.sudo.ws/
+.Sh SUPPORT
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.Sh DISCLAIMER
+.Nm
+is provided
+.Dq AS IS
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+.Nm sudo
+or https://www.sudo.ws/license.html for complete details.
diff --git a/examples/Makefile.in b/examples/Makefile.in
new file mode 100644
index 0000000..bb9e533
--- /dev/null
+++ b/examples/Makefile.in
@@ -0,0 +1,100 @@
+#
+# Copyright (c) 2014, 2017-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# @configure_input@
+#
+
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+docdir = @docdir@
+exampledir = @exampledir@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Our install program supports extra flags...
+INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
+INSTALL_OWNER = -o $(install_uid) -g $(install_gid)
+
+# Where to install things...
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+localstatedir = @localstatedir@
+
+# User and group ids the installed files should be "owned" by
+install_uid = 0
+install_gid = 0
+
+#### End of system configuration section. ####
+
+SHELL = @SHELL@
+
+EXAMPLES = $(srcdir)/pam.conf $(srcdir)/sudo.conf $(srcdir)/sudoers \
+ $(srcdir)/syslog.conf
+
+VERSION = @PACKAGE_VERSION@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+
+all: $(EXAMPLES)
+
+Makefile: $(srcdir)/Makefile.in
+ cd $(top_builddir) && ./config.status --file examples/Makefile
+
+pre-install:
+
+install: install-doc
+
+install-dirs:
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(exampledir)
+
+install-binaries:
+
+install-includes:
+
+install-doc: install-dirs
+ for f in $(EXAMPLES); do $(INSTALL) $(INSTALL_OWNER) -m 0644 $$f $(DESTDIR)$(exampledir); done
+
+install-plugin:
+
+uninstall:
+ -rm -rf $(DESTDIR)$(exampledir)
+
+splint:
+
+cppcheck:
+
+pvs-log-files:
+
+pvs-studio:
+
+check:
+
+clean:
+
+mostlyclean: clean
+
+distclean: clean
+ -rm -rf Makefile
+
+clobber: distclean
+
+realclean: distclean
+
+cleandir: distclean
diff --git a/examples/pam.conf b/examples/pam.conf
new file mode 100644
index 0000000..d56e712
--- /dev/null
+++ b/examples/pam.conf
@@ -0,0 +1,30 @@
+#%PAM-1.0
+# Sample /etc/pam.d/sudo file for RedHat 9 / Fedora Core.
+# For other Linux distributions you may want to
+# use /etc/pam.d/sshd or /etc/pam.d/su as a guide.
+#
+# There are two basic ways to configure PAM, either via pam_stack
+# or by explicitly specifying the various methods to use.
+#
+# Here we use pam_stack
+auth required pam_stack.so service=system-auth
+account required pam_stack.so service=system-auth
+password required pam_stack.so service=system-auth
+session required pam_stack.so service=system-auth
+#
+# Alternately, you can specify the authentication method directly.
+# Here we use pam_unix for normal password authentication.
+#auth required pam_env.so
+#auth sufficient pam_unix.so
+#account required pam_unix.so
+#password required pam_cracklib.so retry=3 type=
+#password required pam_unix.so nullok use_authtok md5 shadow
+#session required pam_limits.so
+#session required pam_unix.so
+#
+# Another option is to use SMB for authentication.
+#auth required pam_env.so
+#auth sufficient pam_smb_auth.so
+#account required pam_smb_auth.so
+#password required pam_smb_auth.so
+#session required pam_limits.so
diff --git a/examples/sudo.conf b/examples/sudo.conf
new file mode 100644
index 0000000..c605bb5
--- /dev/null
+++ b/examples/sudo.conf
@@ -0,0 +1,72 @@
+#
+# Sample /etc/sudo.conf file
+#
+# Format:
+# Plugin plugin_name plugin_path plugin_options ...
+# Path askpass /path/to/askpass
+# Path noexec /path/to/sudo_noexec.so
+# Debug sudo /var/log/sudo_debug all@warn
+# Set disable_coredump true
+#
+# Sudo plugins:
+#
+# The plugin_path is relative to ${prefix}/libexec unless fully qualified.
+# The plugin_name corresponds to a global symbol in the plugin
+# that contains the plugin interface structure.
+# The plugin_options are optional.
+#
+# The sudoers plugin is used by default if no Plugin lines are present.
+Plugin sudoers_policy sudoers.so
+Plugin sudoers_io sudoers.so
+
+#
+# Sudo askpass:
+#
+# An askpass helper program may be specified to provide a graphical
+# password prompt for "sudo -A" support. Sudo does not ship with its
+# own askpass program but can use the OpenSSH askpass.
+#
+# Use the OpenSSH askpass
+#Path askpass /usr/X11R6/bin/ssh-askpass
+#
+# Use the Gnome OpenSSH askpass
+#Path askpass /usr/libexec/openssh/gnome-ssh-askpass
+
+#
+# Sudo noexec:
+#
+# Path to a shared library containing dummy versions of the execv(),
+# execve() and fexecve() library functions that just return an error.
+# This is used to implement the "noexec" functionality on systems that
+# support C<LD_PRELOAD> or its equivalent.
+# The compiled-in value is usually sufficient and should only be changed
+# if you rename or move the sudo_noexec.so file.
+#
+#Path noexec /usr/libexec/sudo_noexec.so
+
+#
+# Core dumps:
+#
+# By default, sudo disables core dumps while it is executing (they
+# are re-enabled for the command that is run).
+# To aid in debugging sudo problems, you may wish to enable core
+# dumps by setting "disable_coredump" to false.
+#
+#Set disable_coredump false
+
+#
+# User groups:
+#
+# Sudo passes the user's group list to the policy plugin.
+# If the user is a member of the maximum number of groups (usually 16),
+# sudo will query the group database directly to be sure to include
+# the full list of groups.
+#
+# On some systems, this can be expensive so the behavior is configurable.
+# The "group_source" setting has three possible values:
+# static - use the user's list of groups returned by the kernel.
+# dynamic - query the group database to find the list of groups.
+# adaptive - if user is in less than the maximum number of groups.
+# use the kernel list, else query the group database.
+#
+#Set group_source static
diff --git a/examples/sudoers b/examples/sudoers
new file mode 100644
index 0000000..4d95095
--- /dev/null
+++ b/examples/sudoers
@@ -0,0 +1,133 @@
+#
+# Sample /etc/sudoers file.
+#
+# This file MUST be edited with the 'visudo' command as root.
+#
+# See the sudoers man page for the details on how to write a sudoers file.
+
+##
+# Override built-in defaults
+##
+Defaults syslog=auth
+Defaults>root !set_logname
+Defaults:FULLTIMERS !lecture
+Defaults:millert !authenticate
+Defaults@SERVERS log_year, logfile=/var/log/sudo.log
+Defaults!PAGERS noexec
+
+##
+# User alias specification
+##
+User_Alias FULLTIMERS = millert, mikef, dowdy
+User_Alias PARTTIMERS = bostley, jwfox, crawl
+User_Alias WEBMASTERS = will, wendy, wim
+
+##
+# Runas alias specification
+##
+Runas_Alias OP = root, operator
+Runas_Alias DB = oracle, sybase
+
+##
+# Host alias specification
+##
+Host_Alias SPARC = bigtime, eclipse, moet, anchor:\
+ SGI = grolsch, dandelion, black:\
+ ALPHA = widget, thalamus, foobar:\
+ HPPA = boa, nag, python
+Host_Alias CUNETS = 128.138.0.0/255.255.0.0
+Host_Alias CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0
+Host_Alias SERVERS = master, mail, www, ns
+Host_Alias CDROM = orion, perseus, hercules
+
+##
+# Cmnd alias specification
+##
+Cmnd_Alias DUMPS = /usr/sbin/dump, /usr/sbin/rdump, /usr/sbin/restore, \
+ /usr/sbin/rrestore, /usr/bin/mt, \
+ sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \
+ /home/operator/bin/start_backups
+Cmnd_Alias KILL = /usr/bin/kill, /usr/bin/top
+Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
+Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown
+Cmnd_Alias HALT = /usr/sbin/halt
+Cmnd_Alias REBOOT = /usr/sbin/reboot
+Cmnd_Alias SHELLS = /sbin/sh, /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh, \
+ /usr/local/bin/tcsh, /usr/bin/rsh, \
+ /usr/local/bin/zsh
+Cmnd_Alias SU = /usr/bin/su
+Cmnd_Alias VIPW = /usr/sbin/vipw, /usr/bin/passwd, /usr/bin/chsh, \
+ /usr/bin/chfn
+Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+
+##
+# User specification
+##
+
+# root and users in group wheel can run anything on any machine as any user
+root ALL = (ALL) ALL
+%wheel ALL = (ALL) ALL
+
+# full time sysadmins can run anything on any machine without a password
+FULLTIMERS ALL = NOPASSWD: ALL
+
+# part time sysadmins may run anything but need a password
+PARTTIMERS ALL = ALL
+
+# jack may run anything on machines in CSNETS
+jack CSNETS = ALL
+
+# lisa may run any command on any host in CUNETS (a class B network)
+lisa CUNETS = ALL
+
+# operator may run maintenance commands and anything in /usr/oper/bin/
+operator ALL = DUMPS, KILL, SHUTDOWN, HALT, REBOOT, PRINTING,\
+ sudoedit /etc/printcap, /usr/oper/bin/
+
+# joe may su only to operator
+joe ALL = /usr/bin/su operator
+
+# pete may change passwords for anyone but root on the hp snakes
+pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd *root*
+
+# bob may run anything on the sparc and sgi machines as any user
+# listed in the Runas_Alias "OP" (ie: root and operator)
+bob SPARC = (OP) ALL : SGI = (OP) ALL
+
+# jim may run anything on machines in the biglab netgroup
+jim +biglab = ALL
+
+# users in the secretaries netgroup need to help manage the printers
+# as well as add and remove users
++secretaries ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser
+
+# fred can run commands as oracle or sybase without a password
+fred ALL = (DB) NOPASSWD: ALL
+
+# on the alphas, john may su to anyone but root and flags are not allowed
+john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
+
+# jen can run anything on all machines except the ones
+# in the "SERVERS" Host_Alias
+jen ALL, !SERVERS = ALL
+
+# jill can run any commands in the directory /usr/bin/, except for
+# those in the SU and SHELLS aliases.
+jill SERVERS = /usr/bin/, !SU, !SHELLS
+
+# steve can run any command in the directory /usr/local/op_commands/
+# as user operator.
+steve CSNETS = (operator) /usr/local/op_commands/
+
+# matt needs to be able to kill things on his workstation when
+# they get hung.
+matt valkyrie = KILL
+
+# users in the WEBMASTERS User_Alias (will, wendy, and wim)
+# may run any command as user www (which owns the web pages)
+# or simply su to www.
+WEBMASTERS www = (www) ALL, (root) /usr/bin/su www
+
+# anyone can mount/unmount a cd-rom on the machines in the CDROM alias
+ALL CDROM = NOPASSWD: /sbin/umount /CDROM,\
+ /sbin/mount -o nosuid\,nodev /dev/cd0a /CDROM
diff --git a/examples/syslog.conf b/examples/syslog.conf
new file mode 100644
index 0000000..686cd19
--- /dev/null
+++ b/examples/syslog.conf
@@ -0,0 +1,26 @@
+# This is a sample syslog.conf fragment for use with Sudo.
+#
+# By default, sudo logs to "authpriv" if your system supports it, else it
+# uses "auth". The facility can be set via the --with-logfac configure
+# option or in the sudoers file.
+# To see what syslog facility a sudo binary uses, run `sudo -V' as *root*.
+#
+# NOTES:
+# The whitespace in the following line is made up of <TAB>
+# characters, *not* spaces. You cannot just cut and paste!
+#
+# If you edit syslog.conf you need to send syslogd a HUP signal.
+# Ie: kill -HUP process_id
+#
+# Syslogd will not create new log files for you, you must first
+# create the file before syslogd will log to it. Eg.
+# 'touch /var/log/sudo'
+
+# This logs successful and failed sudo attempts to the file /var/log/auth
+# If your system has the authpriv syslog facility, use authpriv.debug
+auth.debug /var/log/auth
+
+# To log to a remote machine, use something like the following,
+# where "loghost" is the name of the remote machine.
+# If your system has the authpriv syslog facility, use authpriv.debug
+auth.debug @loghost
diff --git a/include/Makefile.in b/include/Makefile.in
new file mode 100644
index 0000000..cb39b36
--- /dev/null
+++ b/include/Makefile.in
@@ -0,0 +1,96 @@
+#
+# Copyright (c) 2011-2015, 2017-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# @configure_input@
+#
+
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+includedir = @includedir@
+cross_compiling = @CROSS_COMPILING@
+
+# Our install program supports extra flags...
+INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
+INSTALL_OWNER = -o $(install_uid) -g $(install_gid)
+
+# Where to install things...
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+localstatedir = @localstatedir@
+
+# User and group ids the installed files should be "owned" by
+install_uid = 0
+install_gid = 0
+
+#### End of system configuration section. ####
+
+SHELL = @SHELL@
+
+all:
+
+Makefile: $(srcdir)/Makefile.in
+ cd $(top_builddir) && ./config.status --file include/Makefile
+
+.SUFFIXES: .h
+
+pre-install:
+
+install: install-includes
+
+install-dirs:
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(includedir)
+
+install-binaries:
+
+install-doc:
+
+install-includes: install-dirs
+ $(INSTALL) $(INSTALL_OWNER) -m 0644 $(srcdir)/sudo_plugin.h $(DESTDIR)$(includedir)
+
+install-plugin:
+
+uninstall:
+ -rm -f $(DESTDIR)$(includedir)/sudo_plugin.h
+
+splint:
+
+cppcheck:
+
+pvs-log-files:
+
+pvs-studio:
+
+check:
+
+clean:
+
+mostlyclean: clean
+
+distclean: clean
+ -rm -rf Makefile
+
+clobber: distclean
+
+realclean: distclean
+
+cleandir: distclean
diff --git a/include/compat/charclass.h b/include/compat/charclass.h
new file mode 100644
index 0000000..645e884
--- /dev/null
+++ b/include/compat/charclass.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2008, 2010 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * POSIX character class support for fnmatch() and glob().
+ */
+static struct cclass {
+ const char *name;
+ int (*isctype)(int);
+} cclasses[] = {
+ { "alnum", isalnum },
+ { "alpha", isalpha },
+ { "blank", isblank },
+ { "cntrl", iscntrl },
+ { "digit", isdigit },
+ { "graph", isgraph },
+ { "lower", islower },
+ { "print", isprint },
+ { "punct", ispunct },
+ { "space", isspace },
+ { "upper", isupper },
+ { "xdigit", isxdigit },
+ { NULL, NULL }
+};
+
+#define NCCLASSES (nitems(cclasses) - 1)
diff --git a/include/compat/endian.h b/include/compat/endian.h
new file mode 100644
index 0000000..279549c
--- /dev/null
+++ b/include/compat/endian.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2013 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef COMPAT_ENDIAN_H
+#define COMPAT_ENDIAN_H
+
+#ifndef BYTE_ORDER
+# undef LITTLE_ENDIAN
+# define LITTLE_ENDIAN 1234
+# undef BIG_ENDIAN
+# define BIG_ENDIAN 4321
+# undef UNKNOWN_ENDIAN
+# define UNKNOWN_ENDIAN 0
+
+/*
+ * Attempt to guess endianness.
+ * Solaris may define _LITTLE_ENDIAN and _BIG_ENDIAN to 1
+ * HP-UX may define __LITTLE_ENDIAN__ and __BIG_ENDIAN__ to 1
+ * Otherwise, check for cpu-specific cpp defines.
+ * Note that some CPUs are bi-endian, including: arm, powerpc, alpha,
+ * sparc64, mips, hppa, sh4 and ia64.
+ * We just check for the most common uses.
+ */
+
+# if defined(__BYTE_ORDER)
+# define BYTE_ORDER __BYTE_ORDER
+# elif defined(_BYTE_ORDER)
+# define BYTE_ORDER _BYTE_ORDER
+# elif defined(_LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__)
+# define BYTE_ORDER LITTLE_ENDIAN
+# elif defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN__)
+# define BYTE_ORDER BIG_ENDIAN
+# elif defined(__alpha__) || defined(__alpha) || defined(__amd64) || \
+ defined(BIT_ZERO_ON_RIGHT) || defined(i386) || defined(__i386) || \
+ defined(MIPSEL) || defined(_MIPSEL) || defined(ns32000) || \
+ defined(__ns3200) || defined(sun386) || defined(vax) || \
+ defined(__vax) || defined(__x86__) || \
+ (defined(sun) && defined(__powerpc)) || \
+ (!defined(__hpux) && defined(__ia64))
+# define BYTE_ORDER LITTLE_ENDIAN
+# elif defined(__68k__) || defined(apollo) || defined(BIT_ZERO_ON_LEFT) || \
+ defined(__convex__) || defined(_CRAY) || defined(DGUX) || \
+ defined(__hppa) || defined(__hp9000) || defined(__hp9000s300) || \
+ defined(__hp9000s700) || defined(__hp3000s900) || \
+ defined(ibm032) || defined(ibm370) || defined(_IBMR2) || \
+ defined(is68k) || defined(mc68000) || defined(m68k) || \
+ defined(__m68k) || defined(m88k) || defined(__m88k) || \
+ defined(MIPSEB) || defined(_MIPSEB) || defined(MPE) || \
+ defined(pyr) || defined(__powerpc) || defined(__powerpc__) || \
+ defined(sel) || defined(__sparc) || defined(__sparc__) || \
+ defined(tahoe) || (defined(__hpux) && defined(__ia64)) || \
+ (defined(sun) && defined(__powerpc))
+# define BYTE_ORDER BIG_ENDIAN
+# else
+# define BYTE_ORDER UNKNOWN_ENDIAN
+# endif
+#endif /* BYTE_ORDER */
+
+#endif /* COMPAT_ENDIAN_H */
diff --git a/include/compat/fnmatch.h b/include/compat/fnmatch.h
new file mode 100644
index 0000000..fb81e38
--- /dev/null
+++ b/include/compat/fnmatch.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef COMPAT_FNMATCH_H
+#define COMPAT_FNMATCH_H
+
+#define FNM_NOMATCH 1 /* String does not match pattern */
+
+#define FNM_PATHNAME (1 << 0) /* Globbing chars don't match '/' */
+#define FNM_PERIOD (1 << 1) /* Leading '.' in string must exactly */
+#define FNM_NOESCAPE (1 << 2) /* Backslash treated as ordinary char */
+#define FNM_LEADING_DIR (1 << 3) /* Only match the leading directory */
+#define FNM_CASEFOLD (1 << 4) /* Case insensitive matching */
+
+__dso_public int sudo_fnmatch(const char *pattern, const char *string, int flags);
+
+#define fnmatch(_a, _b, _c) sudo_fnmatch((_a), (_b), (_c))
+
+#endif /* COMPAT_FNMATCH_H */
diff --git a/include/compat/getaddrinfo.h b/include/compat/getaddrinfo.h
new file mode 100644
index 0000000..6f2f203
--- /dev/null
+++ b/include/compat/getaddrinfo.h
@@ -0,0 +1,83 @@
+/*
+ * Replacement implementation of getaddrinfo.
+ *
+ * This is an implementation of the getaddrinfo family of functions for
+ * systems that lack it, so that code can use getaddrinfo always. It provides
+ * IPv4 support only; for IPv6 support, a native getaddrinfo implemenation is
+ * required.
+ *
+ * The canonical version of this file is maintained in the rra-c-util package,
+ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ *
+ * The authors hereby relinquish any claim to any copyright that they may have
+ * in this work, whether granted under contract or by operation of law or
+ * international treaty, and hereby commit to the public, at large, that they
+ * shall not, at any time in the future, seek to enforce any copyright in this
+ * work against any person or entity, or prevent any person or entity from
+ * copying, publishing, distributing or creating derivative works of this
+ * work.
+ */
+
+#ifndef COMPAT_GETADDRINFO_H
+#define COMPAT_GETADDRINFO_H
+
+#include <config.h>
+
+/* Skip this entire file if a system getaddrinfo was detected. */
+#ifndef HAVE_GETADDRINFO
+
+/* OpenBSD likes to have sys/types.h included before sys/socket.h. */
+#include <sys/types.h>
+#include <sys/socket.h>
+
+/* The struct returned by getaddrinfo, from RFC 3493. */
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME, .. */
+ int ai_family; /* AF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ socklen_t ai_addrlen; /* Length of ai_addr */
+ char *ai_canonname; /* Canonical name for nodename */
+ struct sockaddr *ai_addr; /* Binary address */
+ struct addrinfo *ai_next; /* Next structure in linked list */
+};
+
+/* Constants for ai_flags from RFC 3493, combined with binary or. */
+#define AI_PASSIVE 0x0001
+#define AI_CANONNAME 0x0002
+#define AI_NUMERICHOST 0x0004
+#define AI_NUMERICSERV 0x0008
+#define AI_V4MAPPED 0x0010
+#define AI_ALL 0x0020
+#define AI_ADDRCONFIG 0x0040
+
+/* Error return codes from RFC 3493. */
+#define EAI_AGAIN 1 /* Temporary name resolution failure */
+#define EAI_BADFLAGS 2 /* Invalid value in ai_flags parameter */
+#define EAI_FAIL 3 /* Permanent name resolution failure */
+#define EAI_FAMILY 4 /* Address family not recognized */
+#define EAI_MEMORY 5 /* Memory allocation failure */
+#define EAI_NONAME 6 /* nodename or servname unknown */
+#define EAI_SERVICE 7 /* Service not recognized for socket type */
+#define EAI_SOCKTYPE 8 /* Socket type not recognized */
+#define EAI_SYSTEM 9 /* System error occurred, see errno */
+#define EAI_OVERFLOW 10 /* An argument buffer overflowed */
+
+/* Function prototypes. */
+__dso_public int sudo_getaddrinfo(const char *nodename, const char *servname,
+ const struct addrinfo *hints, struct addrinfo **res);
+__dso_public void sudo_freeaddrinfo(struct addrinfo *ai);
+__dso_public const char *sudo_gai_strerror(int ecode);
+
+/* Map sudo_* to RFC 3493 names. */
+#undef getaddrinfo
+#define getaddrinfo(_a, _b, _c, _d) sudo_getaddrinfo((_a), (_b), (_c), (_d))
+#undef freeaddrinfo
+#define freeaddrinfo(_a) sudo_freeaddrinfo((_a))
+#undef gai_strerror
+#define gai_strerror(_a) sudo_gai_strerror((_a))
+
+#endif /* !HAVE_GETADDRINFO */
+#endif /* COMPAT_GETADDRINFO_H */
diff --git a/include/compat/getopt.h b/include/compat/getopt.h
new file mode 100644
index 0000000..8f49518
--- /dev/null
+++ b/include/compat/getopt.h
@@ -0,0 +1,81 @@
+/* $OpenBSD: getopt.h,v 1.2 2008/06/26 05:42:04 ray Exp $ */
+/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
+/* $FreeBSD: head/include/getopt.h 203963 2010-02-16 19:28:10Z imp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef COMPAT_GETOPT_H
+#define COMPAT_GETOPT_H
+
+/*
+ * GNU-like getopt_long()/getopt_long_only() with 4.4BSD optreset extension.
+ */
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+struct option {
+ /* name of long option */
+ const char *name;
+ /*
+ * one of no_argument, required_argument, and optional_argument:
+ * whether option takes an argument
+ */
+ int has_arg;
+ /* if not NULL, set *flag to val when option found */
+ int *flag;
+ /* if flag not NULL, value to set *flag to; else return value */
+ int val;
+};
+
+__dso_public int sudo_getopt_long(int, char * const *, const char *,
+ const struct option *, int *);
+#undef getopt_long
+#define getopt_long(_a, _b, _c, _d, _e) \
+ sudo_getopt_long((_a), (_b), (_c), (_d), (_e))
+
+__dso_public int sudo_getopt_long_only(int, char * const *, const char *,
+ const struct option *, int *);
+#undef getopt_long_only
+#define getopt_long_only(_a, _b, _c, _d, _e) \
+ sudo_getopt_long_only((_a), (_b), (_c), (_d), (_e))
+#if 0
+__dso_public int sudo_getopt(int, char * const [], const char *);
+#undef getopt
+#define getopt(_a, _b, _c) sudo_getopt((_a), (_b), (_c))
+#endif
+
+extern char *optarg; /* getopt(3) external variables */
+extern int opterr;
+extern int optind;
+extern int optopt;
+extern int optreset;
+
+#endif /* !COMPAT_GETOPT_H */
diff --git a/include/compat/glob.h b/include/compat/glob.h
new file mode 100644
index 0000000..40f5d39
--- /dev/null
+++ b/include/compat/glob.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)glob.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef COMPAT_GLOB_H
+#define COMPAT_GLOB_H
+
+struct stat;
+typedef struct {
+ int gl_pathc; /* Count of total paths so far. */
+ int gl_matchc; /* Count of paths matching pattern. */
+ int gl_offs; /* Reserved at beginning of gl_pathv. */
+ int gl_flags; /* Copy of flags parameter to glob. */
+ char **gl_pathv; /* List of paths matching pattern. */
+ /* Copy of errfunc parameter to glob. */
+ int (*gl_errfunc)(const char *, int);
+} glob_t;
+
+/* Flags */
+#define GLOB_APPEND 0x0001 /* Append to output from previous call. */
+#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */
+#define GLOB_ERR 0x0004 /* Return on error. */
+#define GLOB_MARK 0x0008 /* Append / to matching directories. */
+#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */
+#define GLOB_NOSORT 0x0020 /* Don't sort. */
+#define GLOB_NOESCAPE 0x0040 /* Disable backslash escaping. */
+
+/* Non-POSIX extensions */
+#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */
+#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */
+#define GLOB_TILDE 0x0200 /* Expand tilde names from the passwd file. */
+#define GLOB_LIMIT 0x0400 /* Limit pattern match output to ARG_MAX */
+
+/* Error values returned by glob(3) */
+#define GLOB_NOSPACE (-1) /* Malloc call failed. */
+#define GLOB_ABORTED (-2) /* Unignored error. */
+#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */
+#define GLOB_NOSYS (-4) /* Function not supported. */
+
+__dso_public int sudo_glob(const char *, int, int (*)(const char *, int), glob_t *);
+__dso_public void sudo_globfree(glob_t *);
+
+#define glob(_a, _b, _c, _d) sudo_glob((_a), (_b), (_c), (_d))
+#define globfree(_a) sudo_globfree((_a))
+
+#endif /* !COMPAT_GLOB_H */
diff --git a/include/compat/nss_dbdefs.h b/include/compat/nss_dbdefs.h
new file mode 100644
index 0000000..bc3f9b9
--- /dev/null
+++ b/include/compat/nss_dbdefs.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2013 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef COMPAT_NSS_DBDEFS_H
+#define COMPAT_NSS_DBDEFS_H
+
+/*
+ * Bits of nss_dbdefs.h and nss_common.h needed to implement
+ * getgrouplist(3) using nss_search(3).
+ *
+ * HP-UX does not ship those headers so we need this compatibility header.
+ * It may also work on other systems that use a Solaris-derived nsswitch
+ * API.
+ */
+
+#ifdef NEED_HPUX_MUTEX
+# include <synch.h>
+#endif
+
+typedef enum {
+ NSS_SUCCESS,
+ NSS_NOTFOUND,
+ NSS_UNAVAIL
+} nss_status_t;
+
+typedef struct nss_db_params {
+ const char *name;
+ const char *config_name;
+ const char *default_config;
+ unsigned int max_active_per_src;
+ unsigned int max_dormant_per_src;
+ int flags;
+ void *finders;
+ void *private;
+ void (*cleanup)(struct nss_db_params *);
+} nss_db_params_t;
+
+struct nss_groupsbymem {
+ const char *username;
+ gid_t *gid_array;
+ int maxgids;
+ int force_slow_way;
+ int (*str2ent)(const char *, int, void *, char *, int);
+ nss_status_t (*process_cstr)(const char *, int, struct nss_groupsbymem *);
+ int numgids;
+};
+
+typedef struct {
+ void *result; /* group struct to fill in. */
+ char *buffer; /* string buffer for above */
+ size_t buflen; /* string buffer size */
+} nss_XbyY_buf_t;
+
+typedef struct {
+ void *state; /* really struct nss_db_state * */
+#ifdef NEED_HPUX_MUTEX
+ lwp_mutex_t lock;
+#endif
+} nss_db_root_t;
+
+#ifdef NEED_HPUX_MUTEX
+# define NSS_DB_ROOT_INIT { 0, LWP_MUTEX_INITIALIZER }
+#else
+# define NSS_DB_ROOT_INIT { 0 }
+#endif
+# define DEFINE_NSS_DB_ROOT(name) nss_db_root_t name = NSS_DB_ROOT_INIT
+
+/* Backend function to find all groups a user belongs to for initgroups(). */
+#define NSS_DBOP_GROUP_BYMEMBER 6
+
+/* str2ent function return values */
+#define NSS_STR_PARSE_SUCCESS 0
+#define NSS_STR_PARSE_PARSE 1
+#define NSS_STR_PARSE_ERANGE 2
+
+/* Max length for an /etc/group file line. */
+#define NSS_BUFLEN_GROUP 8192
+
+/* HP-UX uses an extra underscore for these functions. */
+#ifdef HAVE___NSS_INITF_GROUP
+# define _nss_initf_group __nss_initf_group
+#endif
+#ifdef HAVE___NSS_XBYY_BUF_ALLOC
+# define _nss_XbyY_buf_alloc __nss_XbyY_buf_alloc
+# define _nss_XbyY_buf_free __nss_XbyY_buf_free
+#endif
+
+typedef void (*nss_db_initf_t)(nss_db_params_t *);
+extern nss_status_t nss_search(nss_db_root_t *, nss_db_initf_t, int, void *);
+extern nss_XbyY_buf_t *_nss_XbyY_buf_alloc(int, int);
+extern void _nss_XbyY_buf_free(nss_XbyY_buf_t *);
+
+#endif /* COMPAT_NSS_DBDEFS_H */
diff --git a/include/compat/sha2.h b/include/compat/sha2.h
new file mode 100644
index 0000000..3638423
--- /dev/null
+++ b/include/compat/sha2.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2013-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Derived from the public domain SHA-1 and SHA-2 implementations
+ * by Steve Reid and Wei Dai respectively.
+ */
+
+#ifndef COMPAT_SHA2_H
+#define COMPAT_SHA2_H
+
+#define SHA224_BLOCK_LENGTH 64
+#define SHA224_DIGEST_LENGTH 28
+#define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1)
+
+#define SHA256_BLOCK_LENGTH 64
+#define SHA256_DIGEST_LENGTH 32
+#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
+
+#define SHA384_BLOCK_LENGTH 128
+#define SHA384_DIGEST_LENGTH 48
+#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
+
+#define SHA512_BLOCK_LENGTH 128
+#define SHA512_DIGEST_LENGTH 64
+#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
+
+typedef struct {
+ union {
+ uint32_t st32[8]; /* sha224 and sha256 */
+ uint64_t st64[8]; /* sha384 and sha512 */
+ } state;
+ uint64_t count[2];
+ uint8_t buffer[SHA512_BLOCK_LENGTH];
+} SHA2_CTX;
+
+__dso_public void sudo_SHA224Init(SHA2_CTX *ctx);
+__dso_public void sudo_SHA224Pad(SHA2_CTX *ctx);
+__dso_public void sudo_SHA224Transform(uint32_t state[8], const uint8_t buffer[SHA224_BLOCK_LENGTH]);
+__dso_public void sudo_SHA224Update(SHA2_CTX *ctx, const uint8_t *data, size_t len);
+__dso_public void sudo_SHA224Final(uint8_t digest[SHA224_DIGEST_LENGTH], SHA2_CTX *ctx);
+
+#define SHA224Init sudo_SHA224Init
+#define SHA224Pad sudo_SHA224Pad
+#define SHA224Transform sudo_SHA224Transform
+#define SHA224Update sudo_SHA224Update
+#define SHA224Final sudo_SHA224Final
+
+__dso_public void sudo_SHA256Init(SHA2_CTX *ctx);
+__dso_public void sudo_SHA256Pad(SHA2_CTX *ctx);
+__dso_public void sudo_SHA256Transform(uint32_t state[8], const uint8_t buffer[SHA256_BLOCK_LENGTH]);
+__dso_public void sudo_SHA256Update(SHA2_CTX *ctx, const uint8_t *data, size_t len);
+__dso_public void sudo_SHA256Final(uint8_t digest[SHA256_DIGEST_LENGTH], SHA2_CTX *ctx);
+
+#define SHA256Init sudo_SHA256Init
+#define SHA256Pad sudo_SHA256Pad
+#define SHA256Transform sudo_SHA256Transform
+#define SHA256Update sudo_SHA256Update
+#define SHA256Final sudo_SHA256Final
+
+__dso_public void sudo_SHA384Init(SHA2_CTX *ctx);
+__dso_public void sudo_SHA384Pad(SHA2_CTX *ctx);
+__dso_public void sudo_SHA384Transform(uint64_t state[8], const uint8_t buffer[SHA384_BLOCK_LENGTH]);
+__dso_public void sudo_SHA384Update(SHA2_CTX *ctx, const uint8_t *data, size_t len);
+__dso_public void sudo_SHA384Final(uint8_t digest[SHA384_DIGEST_LENGTH], SHA2_CTX *ctx);
+
+#define SHA384Init sudo_SHA384Init
+#define SHA384Pad sudo_SHA384Pad
+#define SHA384Transform sudo_SHA384Transform
+#define SHA384Update sudo_SHA384Update
+#define SHA384Final sudo_SHA384Final
+
+__dso_public void sudo_SHA512Init(SHA2_CTX *ctx);
+__dso_public void sudo_SHA512Pad(SHA2_CTX *ctx);
+__dso_public void sudo_SHA512Transform(uint64_t state[8], const uint8_t buffer[SHA512_BLOCK_LENGTH]);
+__dso_public void sudo_SHA512Update(SHA2_CTX *ctx, const uint8_t *data, size_t len);
+__dso_public void sudo_SHA512Final(uint8_t digest[SHA512_DIGEST_LENGTH], SHA2_CTX *ctx);
+
+#define SHA512Init sudo_SHA512Init
+#define SHA512Pad sudo_SHA512Pad
+#define SHA512Transform sudo_SHA512Transform
+#define SHA512Update sudo_SHA512Update
+#define SHA512Final sudo_SHA512Final
+
+#endif /* COMPAT_SHA2_H */
diff --git a/include/compat/stdbool.h b/include/compat/stdbool.h
new file mode 100644
index 0000000..b865a46
--- /dev/null
+++ b/include/compat/stdbool.h
@@ -0,0 +1,44 @@
+/* $OpenBSD: stdbool.h,v 1.5 2010/07/24 22:17:03 guenther Exp $ */
+
+/*
+ * Written by Marc Espie, September 25, 1999
+ * Public domain.
+ */
+
+#ifndef COMPAT_STDBOOL_H
+#define COMPAT_STDBOOL_H
+
+#ifndef __cplusplus
+
+#if (defined(HAVE__BOOL) && HAVE__BOOL > 0) || defined(lint)
+/* Support for _C99: type _Bool is already built-in. */
+#define false 0
+#define true 1
+
+#else
+/* `_Bool' type must promote to `int' or `unsigned int'. */
+typedef enum {
+ false = 0,
+ true = 1
+} _Bool;
+
+/* And those constants must also be available as macros. */
+#define false false
+#define true true
+
+#endif
+
+/* User visible type `bool' is provided as a macro which may be redefined */
+#define bool _Bool
+
+#else /* __cplusplus */
+#define _Bool bool
+#define bool bool
+#define false false
+#define true true
+#endif /* __cplusplus */
+
+/* Inform that everything is fine */
+#define __bool_true_false_are_defined 1
+
+#endif /* COMPAT_STDBOOL_H */
diff --git a/include/sudo_compat.h b/include/sudo_compat.h
new file mode 100644
index 0000000..5c32840
--- /dev/null
+++ b/include/sudo_compat.h
@@ -0,0 +1,531 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2008, 2009-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#ifndef SUDO_COMPAT_H
+#define SUDO_COMPAT_H
+
+#include <stdio.h>
+#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_VASPRINTF) || \
+ !defined(HAVE_VSYSLOG) || defined(PREFER_PORTABLE_SNPRINTF)
+# include <stdarg.h>
+#endif
+#if !defined(HAVE_MEMSET_S) && !defined(rsize_t)
+# include <stddef.h> /* for rsize_t */
+# ifdef HAVE_STRING_H
+# include <string.h> /* for rsize_t on AIX */
+# endif /* HAVE_STRING_H */
+#endif /* HAVE_MEMSET_S && rsize_t */
+
+/*
+ * Macros and functions that may be missing on some operating systems.
+ */
+
+#ifndef __GNUC_PREREQ__
+# ifdef __GNUC__
+# define __GNUC_PREREQ__(ma, mi) \
+ ((__GNUC__ > (ma)) || (__GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)))
+# else
+# define __GNUC_PREREQ__(ma, mi) 0
+# endif
+#endif
+
+/* Define away __attribute__ for non-gcc or old gcc */
+#if !defined(__attribute__) && !__GNUC_PREREQ__(2, 5)
+# define __attribute__(x)
+#endif
+
+/* For catching format string mismatches */
+#ifndef __printflike
+# if __GNUC_PREREQ__(3, 3)
+# define __printflike(f, v) __attribute__((__format__ (__printf__, f, v))) __attribute__((__nonnull__ (f)))
+# elif __GNUC_PREREQ__(2, 7)
+# define __printflike(f, v) __attribute__((__format__ (__printf__, f, v)))
+# else
+# define __printflike(f, v)
+# endif
+#endif
+#ifndef __printf0like
+# if __GNUC_PREREQ__(2, 7)
+# define __printf0like(f, v) __attribute__((__format__ (__printf__, f, v)))
+# else
+# define __printf0like(f, v)
+# endif
+#endif
+#ifndef __format_arg
+# if __GNUC_PREREQ__(2, 7)
+# define __format_arg(f) __attribute__((__format_arg__ (f)))
+# else
+# define __format_arg(f)
+# endif
+#endif
+
+/*
+ * Given the pointer x to the member m of the struct s, return
+ * a pointer to the containing structure.
+ */
+#ifndef __containerof
+# define __containerof(x, s, m) ((s *)((char *)(x) - offsetof(s, m)))
+#endif
+
+#ifndef __dso_public
+# ifdef HAVE_DSO_VISIBILITY
+# if defined(__GNUC__)
+# define __dso_public __attribute__((__visibility__("default")))
+# define __dso_hidden __attribute__((__visibility__("hidden")))
+# elif defined(__SUNPRO_C)
+# define __dso_public __global
+# define __dso_hidden __hidden
+# else
+# define __dso_public __declspec(dllexport)
+# define __dso_hidden
+# endif
+# else
+# define __dso_public
+# define __dso_hidden
+# endif
+#endif
+
+/*
+ * Pre-C99 compilers may lack a va_copy macro.
+ */
+#ifndef va_copy
+# ifdef __va_copy
+# define va_copy(d, s) __va_copy(d, s)
+# else
+# define va_copy(d, s) memcpy(&(d), &(s), sizeof(d));
+# endif
+#endif
+
+/*
+ * Some systems lack full limit definitions.
+ */
+#if defined(HAVE_DECL_LLONG_MAX) && !HAVE_DECL_LLONG_MAX
+# if defined(HAVE_DECL_QUAD_MAX) && HAVE_DECL_QUAD_MAX
+# define LLONG_MAX QUAD_MAX
+# else
+# define LLONG_MAX 0x7fffffffffffffffLL
+# endif
+#endif
+
+#if defined(HAVE_DECL_LLONG_MIN) && !HAVE_DECL_LLONG_MIN
+# if defined(HAVE_DECL_QUAD_MIN) && HAVE_DECL_QUAD_MIN
+# define LLONG_MIN QUAD_MIN
+# else
+# define LLONG_MIN (-0x7fffffffffffffffLL-1)
+# endif
+#endif
+
+#if defined(HAVE_DECL_ULLONG_MAX) && !HAVE_DECL_ULLONG_MAX
+# if defined(HAVE_DECL_UQUAD_MAX) && HAVE_DECL_UQUAD_MAX
+# define ULLONG_MAX UQUAD_MAX
+# else
+# define ULLONG_MAX 0xffffffffffffffffULL
+# endif
+#endif
+
+#if defined(HAVE_DECL_SIZE_MAX) && !HAVE_DECL_SIZE_MAX
+# if defined(HAVE_DECL_SIZE_T_MAX) && HAVE_DECL_SIZE_T_MAX
+# define SIZE_MAX SIZE_T_MAX
+# else
+# define SIZE_MAX ULONG_MAX
+# endif
+#endif
+
+#if defined(HAVE_DECL_PATH_MAX) && !HAVE_DECL_PATH_MAX
+# if defined(HAVE_DECL__POSIX_PATH_MAX) && HAVE_DECL__POSIX_PATH_MAX
+# define PATH_MAX _POSIX_PATH_MAX
+# else
+# define PATH_MAX 256
+# endif
+#endif
+
+/*
+ * POSIX versions for those without...
+ */
+#ifndef _S_IFMT
+# define _S_IFMT S_IFMT
+#endif /* _S_IFMT */
+#ifndef _S_IFREG
+# define _S_IFREG S_IFREG
+#endif /* _S_IFREG */
+#ifndef _S_IFDIR
+# define _S_IFDIR S_IFDIR
+#endif /* _S_IFDIR */
+#ifndef _S_IFLNK
+# define _S_IFLNK S_IFLNK
+#endif /* _S_IFLNK */
+#ifndef _S_IFIFO
+# define _S_IFIFO S_IFIFO
+#endif /* _S_IFIFO */
+#ifndef S_ISREG
+# define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
+#endif /* S_ISREG */
+#ifndef S_ISDIR
+# define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
+#endif /* S_ISDIR */
+#ifndef S_ISLNK
+# define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK)
+#endif /* S_ISLNK */
+#ifndef S_ISFIFO
+# define S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFIFO)
+#endif /* S_ISLNK */
+#ifndef S_ISTXT
+# define S_ISTXT 0001000
+#endif /* S_ISTXT */
+
+/*
+ * ACCESSPERMS (00777) and ALLPERMS (07777) are handy BSDisms
+ */
+#ifndef ACCESSPERMS
+# define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO)
+#endif /* ACCESSPERMS */
+#ifndef ALLPERMS
+# define ALLPERMS (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO)
+#endif /* ALLPERMS */
+
+/* For futimens() and utimensat() emulation. */
+#if !defined(HAVE_FUTIMENS) && !defined(HAVE_UTIMENSAT)
+# ifndef UTIME_OMIT
+# define UTIME_OMIT -1L
+# endif
+# ifndef UTIME_NOW
+# define UTIME_NOW -2L
+# endif
+#endif
+#if !defined(HAVE_OPENAT) || (!defined(HAVE_FUTIMENS) && !defined(HAVE_UTIMENSAT))
+# ifndef AT_FDCWD
+# define AT_FDCWD -100
+# endif
+#endif
+
+/* For pipe2() emulation. */
+#if !defined(HAVE_PIPE2) && defined(O_NONBLOCK) && !defined(O_CLOEXEC)
+# define O_CLOEXEC 0x80000000
+#endif
+
+/*
+ * BSD defines these in <sys/param.h> but we don't include that anymore.
+ */
+#ifndef MIN
+# define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+#ifndef MAX
+# define MAX(a,b) (((a)>(b))?(a):(b))
+#endif
+
+/* Macros to set/clear/test flags. */
+#undef SET
+#define SET(t, f) ((t) |= (f))
+#undef CLR
+#define CLR(t, f) ((t) &= ~(f))
+#undef ISSET
+#define ISSET(t, f) ((t) & (f))
+
+/*
+ * Some systems define this in <sys/param.h> but we don't include that anymore.
+ */
+#ifndef howmany
+# define howmany(x, y) (((x) + ((y) - 1)) / (y))
+#endif
+
+/*
+ * Simple isblank() macro and function for systems without it.
+ */
+#ifndef HAVE_ISBLANK
+__dso_public int isblank(int);
+# define isblank(_x) ((_x) == ' ' || (_x) == '\t')
+#endif
+
+/*
+ * NCR's SVr4 has _innetgr(3) instead of innetgr(3) for some reason.
+ */
+#ifdef HAVE__INNETGR
+# define innetgr(n, h, u, d) (_innetgr(n, h, u, d))
+# define HAVE_INNETGR 1
+#endif /* HAVE__INNETGR */
+
+/*
+ * The nitems macro may be defined in sys/param.h
+ */
+#ifndef nitems
+# define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
+#endif
+
+/*
+ * If dirfd() does not exists, hopefully dd_fd does.
+ */
+#if !defined(HAVE_DIRFD) && defined(HAVE_DD_FD)
+# define dirfd(_d) ((_d)->dd_fd)
+# define HAVE_DIRFD
+#endif
+
+#if !defined(HAVE_KILLPG) && !defined(killpg)
+# define killpg(p, s) kill(-(p), (s))
+#endif
+
+/*
+ * Declare errno if errno.h doesn't do it for us.
+ */
+#if defined(HAVE_DECL_ERRNO) && !HAVE_DECL_ERRNO
+extern int errno;
+#endif /* !HAVE_DECL_ERRNO */
+
+/* Not all systems define NSIG in signal.h */
+#if !defined(NSIG)
+# if defined(_NSIG)
+# define NSIG _NSIG
+# elif defined(__NSIG)
+# define NSIG __NSIG
+# else
+# define NSIG 64
+# endif
+#endif
+
+/* For sig2str() */
+#if !defined(HAVE_DECL_SIG2STR_MAX) || !HAVE_DECL_SIG2STR_MAX
+# define SIG2STR_MAX 32
+#endif
+
+/* WCOREDUMP is not POSIX, this usually works (verified on AIX). */
+#ifndef WCOREDUMP
+# define WCOREDUMP(x) ((x) & 0x80)
+#endif
+
+/* W_EXITCODE is not POSIX but the encoding of wait status is. */
+#ifndef W_EXITCODE
+# define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
+#endif
+
+/* Number of bits in a byte. */
+#ifndef NBBY
+# ifdef __NBBY
+# define NBBY __NBBY
+# else
+# define NBBY 8
+# endif
+#endif
+
+#ifndef HAVE_SETEUID
+# if defined(HAVE_SETRESUID)
+# define seteuid(u) setresuid(-1, (u), -1)
+# define setegid(g) setresgid(-1, (g), -1)
+# define HAVE_SETEUID 1
+# elif defined(HAVE_SETREUID)
+# define seteuid(u) setreuid(-1, (u))
+# define setegid(g) setregid(-1, (g))
+# define HAVE_SETEUID 1
+# endif
+#endif /* HAVE_SETEUID */
+
+/*
+ * Older HP-UX does not declare setresuid() or setresgid().
+ */
+#if defined(HAVE_DECL_SETRESUID) && !HAVE_DECL_SETRESUID
+int setresuid(uid_t, uid_t, uid_t);
+int setresgid(gid_t, gid_t, gid_t);
+#endif
+#if defined(HAVE_DECL_GETRESUID) && !HAVE_DECL_GETRESUID
+int getresuid(uid_t *, uid_t *, uid_t *);
+int getresgid(gid_t *, gid_t *, gid_t *);
+#endif
+
+/*
+ * HP-UX does not declare innetgr() or getdomainname().
+ * Solaris does not declare getdomainname().
+ */
+#if defined(HAVE_DECL_INNETGR) && !HAVE_DECL_INNETGR
+int innetgr(const char *, const char *, const char *, const char *);
+#endif
+#if defined(HAVE_DECL__INNETGR) && !HAVE_DECL__INNETGR
+int _innetgr(const char *, const char *, const char *, const char *);
+#endif
+#if defined(HAVE_DECL_GETDOMAINNAME) && !HAVE_DECL_GETDOMAINNAME
+int getdomainname(char *, size_t);
+#endif
+
+/*
+ * HP-UX 11.00 has broken pread/pwrite that can't handle a 64-bit off_t
+ * on 32-bit machines.
+ */
+#if defined(__hpux) && !defined(__LP64__)
+# ifdef HAVE_PREAD64
+# undef pread
+# define pread(_a, _b, _c, _d) pread64((_a), (_b), (_c), (_d))
+# endif
+# ifdef HAVE_PWRITE64
+# undef pwrite
+# define pwrite(_a, _b, _c, _d) pwrite64((_a), (_b), (_c), (_d))
+# endif
+#endif /* __hpux && !__LP64__ */
+
+/* We wrap OpenBSD's strtonum() to get translatable error strings. */
+__dso_public long long sudo_strtonum(const char *, long long, long long, const char **);
+#undef strtonum
+#define strtonum(_a, _b, _c, _d) sudo_strtonum((_a), (_b), (_c), (_d))
+
+/*
+ * Functions "missing" from libc.
+ * All libc replacements are prefixed with "sudo_" to avoid namespace issues.
+ */
+
+struct passwd;
+struct timespec;
+
+#ifndef HAVE_CLOSEFROM
+__dso_public void sudo_closefrom(int);
+# undef closefrom
+# define closefrom(_a) sudo_closefrom((_a))
+#endif /* HAVE_CLOSEFROM */
+#ifdef PREFER_PORTABLE_GETCWD
+__dso_public char *sudo_getcwd(char *, size_t size);
+# undef getcwd
+# define getcwd(_a, _b) sudo_getcwd((_a), (_b))
+#endif /* PREFER_PORTABLE_GETCWD */
+#ifndef HAVE_GETGROUPLIST
+__dso_public int sudo_getgrouplist(const char *name, GETGROUPS_T basegid, GETGROUPS_T *groups, int *ngroupsp);
+# undef getgrouplist
+# define getgrouplist(_a, _b, _c, _d) sudo_getgrouplist((_a), (_b), (_c), (_d))
+#endif /* GETGROUPLIST */
+#ifndef HAVE_GETLINE
+__dso_public ssize_t sudo_getline(char **bufp, size_t *bufsizep, FILE *fp);
+# undef getline
+# define getline(_a, _b, _c) sudo_getline((_a), (_b), (_c))
+#endif /* HAVE_GETLINE */
+#ifndef HAVE_UTIMENSAT
+__dso_public int sudo_utimensat(int fd, const char *file, const struct timespec *times, int flag);
+# undef utimensat
+# define utimensat(_a, _b, _c, _d) sudo_utimensat((_a), (_b), (_c), (_d))
+#endif /* HAVE_UTIMENSAT */
+#ifndef HAVE_FUTIMENS
+__dso_public int sudo_futimens(int fd, const struct timespec *times);
+# undef futimens
+# define futimens(_a, _b) sudo_futimens((_a), (_b))
+#endif /* HAVE_FUTIMENS */
+#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
+__dso_public int sudo_snprintf(char *str, size_t n, char const *fmt, ...) __printflike(3, 4);
+# undef snprintf
+# define snprintf sudo_snprintf
+#endif /* HAVE_SNPRINTF */
+#if !defined(HAVE_VSNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
+__dso_public int sudo_vsnprintf(char *str, size_t n, const char *fmt, va_list ap) __printflike(3, 0);
+# undef vsnprintf
+# define vsnprintf sudo_vsnprintf
+#endif /* HAVE_VSNPRINTF */
+#if !defined(HAVE_ASPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
+__dso_public int sudo_asprintf(char **str, char const *fmt, ...) __printflike(2, 3);
+# undef asprintf
+# define asprintf sudo_asprintf
+#endif /* HAVE_ASPRINTF */
+#if !defined(HAVE_VASPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
+__dso_public int sudo_vasprintf(char **str, const char *fmt, va_list ap) __printflike(2, 0);
+# undef vasprintf
+# define vasprintf sudo_vasprintf
+#endif /* HAVE_VASPRINTF */
+#ifndef HAVE_STRLCAT
+__dso_public size_t sudo_strlcat(char *dst, const char *src, size_t siz);
+# undef strlcat
+# define strlcat(_a, _b, _c) sudo_strlcat((_a), (_b), (_c))
+#endif /* HAVE_STRLCAT */
+#ifndef HAVE_STRLCPY
+__dso_public size_t sudo_strlcpy(char *dst, const char *src, size_t siz);
+# undef strlcpy
+# define strlcpy(_a, _b, _c) sudo_strlcpy((_a), (_b), (_c))
+#endif /* HAVE_STRLCPY */
+#ifndef HAVE_STRNDUP
+__dso_public char *sudo_strndup(const char *str, size_t maxlen);
+# undef strndup
+# define strndup(_a, _b) sudo_strndup((_a), (_b))
+#endif /* HAVE_STRNDUP */
+#ifndef HAVE_STRNLEN
+__dso_public size_t sudo_strnlen(const char *str, size_t maxlen);
+# undef strnlen
+# define strnlen(_a, _b) sudo_strnlen((_a), (_b))
+#endif /* HAVE_STRNLEN */
+#ifndef HAVE_MEMRCHR
+__dso_public void *sudo_memrchr(const void *s, int c, size_t n);
+# undef memrchr
+# define memrchr(_a, _b, _c) sudo_memrchr((_a), (_b), (_c))
+#endif /* HAVE_MEMRCHR */
+#ifndef HAVE_MEMSET_S
+__dso_public errno_t sudo_memset_s(void *v, rsize_t smax, int c, rsize_t n);
+# undef memset_s
+# define memset_s(_a, _b, _c, _d) sudo_memset_s((_a), (_b), (_c), (_d))
+#endif /* HAVE_MEMSET_S */
+#if !defined(HAVE_MKDTEMP) || !defined(HAVE_MKSTEMPS)
+__dso_public char *sudo_mkdtemp(char *path);
+# undef mkdtemp
+# define mkdtemp(_a) sudo_mkdtemp((_a))
+__dso_public int sudo_mkstemps(char *path, int slen);
+# undef mkstemps
+# define mkstemps(_a, _b) sudo_mkstemps((_a), (_b))
+#endif /* !HAVE_MKDTEMP || !HAVE_MKSTEMPS */
+#ifndef HAVE_NANOSLEEP
+__dso_public int sudo_nanosleep(const struct timespec *timeout, struct timespec *remainder);
+#undef nanosleep
+# define nanosleep(_a, _b) sudo_nanosleep((_a), (_b))
+#endif
+#ifndef HAVE_PW_DUP
+__dso_public struct passwd *sudo_pw_dup(const struct passwd *pw);
+# undef pw_dup
+# define pw_dup(_a) sudo_pw_dup((_a))
+#endif /* HAVE_PW_DUP */
+#ifndef HAVE_STRSIGNAL
+__dso_public char *sudo_strsignal(int signo);
+# undef strsignal
+# define strsignal(_a) sudo_strsignal((_a))
+#endif /* HAVE_STRSIGNAL */
+#ifndef HAVE_SIG2STR
+__dso_public int sudo_sig2str(int signo, char *signame);
+# undef sig2str
+# define sig2str(_a, _b) sudo_sig2str((_a), (_b))
+#endif /* HAVE_SIG2STR */
+#if !defined(HAVE_INET_NTOP) && defined(SUDO_NET_IFS_C)
+__dso_public char *sudo_inet_ntop(int af, const void *src, char *dst, socklen_t size);
+# undef inet_ntop
+# define inet_ntop(_a, _b, _c, _d) sudo_inet_ntop((_a), (_b), (_c), (_d))
+#endif /* HAVE_INET_NTOP */
+#ifndef HAVE_INET_PTON
+__dso_public int sudo_inet_pton(int af, const char *src, void *dst);
+# undef inet_pton
+# define inet_pton(_a, _b, _c) sudo_inet_pton((_a), (_b), (_c))
+#endif /* HAVE_INET_PTON */
+#ifndef HAVE_GETPROGNAME
+__dso_public const char *sudo_getprogname(void);
+# undef getprogname
+# define getprogname() sudo_getprogname()
+#endif /* HAVE_GETPROGNAME */
+#ifndef HAVE_REALLOCARRAY
+__dso_public void *sudo_reallocarray(void *ptr, size_t nmemb, size_t size);
+# undef reallocarray
+# define reallocarray(_a, _b, _c) sudo_reallocarray((_a), (_b), (_c))
+#endif /* HAVE_REALLOCARRAY */
+#ifndef HAVE_VSYSLOG
+__dso_public void sudo_vsyslog(int pri, const char *fmt, va_list ap);
+# undef vsyslog
+# define vsyslog(_a, _b, _c) sudo_vsyslog((_a), (_b), (_c))
+#endif /* HAVE_VSYSLOG */
+#ifndef HAVE_PIPE2
+__dso_public int sudo_pipe2(int fildes[2], int flags);
+# undef pipe2
+# define pipe2(_a, _b) sudo_pipe2((_a), (_b))
+#endif /* HAVE_PIPE2 */
+
+#endif /* SUDO_COMPAT_H */
diff --git a/include/sudo_conf.h b/include/sudo_conf.h
new file mode 100644
index 0000000..6676116
--- /dev/null
+++ b/include/sudo_conf.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2011-2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_CONF_H
+#define SUDO_CONF_H
+
+#include "sudo_queue.h"
+
+/* Flags for sudo_conf_read() */
+#define SUDO_CONF_DEBUG 0x01
+#define SUDO_CONF_PATHS 0x02
+#define SUDO_CONF_PLUGINS 0x04
+#define SUDO_CONF_SETTINGS 0x08
+#define SUDO_CONF_ALL 0x0f
+
+/* Values of sudo_conf_group_source() */
+#define GROUP_SOURCE_ADAPTIVE 0
+#define GROUP_SOURCE_STATIC 1
+#define GROUP_SOURCE_DYNAMIC 2
+
+struct sudo_debug_file;
+TAILQ_HEAD(sudo_conf_debug_file_list, sudo_debug_file);
+
+struct plugin_info {
+ TAILQ_ENTRY(plugin_info) entries;
+ char *path;
+ char *symbol_name;
+ char **options;
+ unsigned int lineno;
+};
+TAILQ_HEAD(plugin_info_list, plugin_info);
+
+struct sudo_conf_debug {
+ TAILQ_ENTRY(sudo_conf_debug) entries;
+ struct sudo_conf_debug_file_list debug_files;
+ char *progname;
+};
+TAILQ_HEAD(sudo_conf_debug_list, sudo_conf_debug);
+
+/* Read main sudo.conf file. */
+__dso_public int sudo_conf_read_v1(const char *conf_file, int conf_types);
+#define sudo_conf_read(_a, _b) sudo_conf_read_v1((_a), (_b))
+
+/* Accessor functions. */
+__dso_public const char *sudo_conf_askpass_path_v1(void);
+__dso_public const char *sudo_conf_sesh_path_v1(void);
+__dso_public const char *sudo_conf_noexec_path_v1(void);
+__dso_public const char *sudo_conf_plugin_dir_path_v1(void);
+__dso_public const char *sudo_conf_devsearch_path_v1(void);
+__dso_public struct sudo_conf_debug_list *sudo_conf_debugging_v1(void);
+__dso_public struct sudo_conf_debug_file_list *sudo_conf_debug_files_v1(const char *progname);
+__dso_public struct plugin_info_list *sudo_conf_plugins_v1(void);
+__dso_public bool sudo_conf_disable_coredump_v1(void);
+__dso_public bool sudo_conf_probe_interfaces_v1(void);
+__dso_public int sudo_conf_group_source_v1(void);
+__dso_public int sudo_conf_max_groups_v1(void);
+__dso_public void sudo_conf_clear_paths_v1(void);
+#define sudo_conf_askpass_path() sudo_conf_askpass_path_v1()
+#define sudo_conf_sesh_path() sudo_conf_sesh_path_v1()
+#define sudo_conf_noexec_path() sudo_conf_noexec_path_v1()
+#define sudo_conf_plugin_dir_path() sudo_conf_plugin_dir_path_v1()
+#define sudo_conf_devsearch_path() sudo_conf_devsearch_path_v1()
+#define sudo_conf_debugging() sudo_conf_debugging_v1()
+#define sudo_conf_debug_files(_a) sudo_conf_debug_files_v1((_a))
+#define sudo_conf_plugins() sudo_conf_plugins_v1()
+#define sudo_conf_disable_coredump() sudo_conf_disable_coredump_v1()
+#define sudo_conf_probe_interfaces() sudo_conf_probe_interfaces_v1()
+#define sudo_conf_group_source() sudo_conf_group_source_v1()
+#define sudo_conf_max_groups() sudo_conf_max_groups_v1()
+#define sudo_conf_clear_paths() sudo_conf_clear_paths_v1()
+
+#endif /* SUDO_CONF_H */
diff --git a/include/sudo_debug.h b/include/sudo_debug.h
new file mode 100644
index 0000000..105a7e6
--- /dev/null
+++ b/include/sudo_debug.h
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2011-2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_DEBUG_H
+#define SUDO_DEBUG_H
+
+#include <stdarg.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+#include "sudo_queue.h"
+
+/*
+ * List of debug files and flags for use in registration.
+ */
+struct sudo_debug_file {
+ TAILQ_ENTRY(sudo_debug_file) entries;
+ char *debug_file;
+ char *debug_flags;
+};
+struct sudo_conf_debug_file_list;
+
+/*
+ * The priority and subsystem are encoded in a single 32-bit value.
+ * The lower 4 bits are the priority and the top 26 bits are the subsystem.
+ * This allows for 16 priorities and a very large number of subsystems.
+ * Bit 5 is used as a flag to specify whether to log the errno value.
+ * Bit 6 specifies whether to log the function, file and line number data.
+ */
+
+/*
+ * Sudo debug priorities, ordered least to most verbose,
+ * in other words, highest to lowest priority. Max pri is 15.
+ * Note: order must match sudo_debug_priorities[]
+ */
+#define SUDO_DEBUG_CRIT 1 /* critical errors */
+#define SUDO_DEBUG_ERROR 2 /* non-critical errors */
+#define SUDO_DEBUG_WARN 3 /* non-fatal warnings */
+#define SUDO_DEBUG_NOTICE 4 /* non-error condition notices */
+#define SUDO_DEBUG_DIAG 5 /* diagnostic messages */
+#define SUDO_DEBUG_INFO 6 /* informational message */
+#define SUDO_DEBUG_TRACE 7 /* log function enter/exit */
+#define SUDO_DEBUG_DEBUG 8 /* very verbose debugging */
+
+/* Flag to include string version of errno in debug info. */
+#define SUDO_DEBUG_ERRNO (1<<4)
+
+/* Flag to include function, file and line number in debug info. */
+#define SUDO_DEBUG_LINENO (1<<5)
+
+/*
+ * Sudo debug subsystems.
+ * This includes subsystems in the sudoers plugin.
+ * Note: order must match sudo_debug_subsystems[]
+ */
+#define SUDO_DEBUG_ARGS ( 1<<6) /* command line argument handling */
+#define SUDO_DEBUG_CONV ( 2<<6) /* user conversation */
+#define SUDO_DEBUG_EDIT ( 3<<6) /* sudoedit */
+#define SUDO_DEBUG_EVENT ( 4<<6) /* event handling */
+#define SUDO_DEBUG_EXEC ( 5<<6) /* command execution */
+#define SUDO_DEBUG_HOOKS ( 6<<6) /* hook functions */
+#define SUDO_DEBUG_MAIN ( 7<<6) /* sudo main() */
+#define SUDO_DEBUG_NETIF ( 8<<6) /* network interface functions */
+#define SUDO_DEBUG_PCOMM ( 9<<6) /* plugin communications */
+#define SUDO_DEBUG_PLUGIN (10<<6) /* main plugin functions */
+#define SUDO_DEBUG_PTY (11<<6) /* pseudo-tty */
+#define SUDO_DEBUG_SELINUX (12<<6) /* selinux */
+#define SUDO_DEBUG_UTIL (13<<6) /* utility functions */
+#define SUDO_DEBUG_UTMP (14<<6) /* utmp file ops */
+#define SUDO_DEBUG_ALL 0xffff0000 /* all subsystems */
+
+/* Error return for sudo_debug_register(). */
+#define SUDO_DEBUG_INSTANCE_ERROR -2
+
+/* Initializer for instance index to indicate that debugging is not setup. */
+#define SUDO_DEBUG_INSTANCE_INITIALIZER -1
+
+/* Extract priority number and convert to an index. */
+#define SUDO_DEBUG_PRI(n) (((n) & 0x0f) - 1)
+
+/* Extract subsystem number and convert to an index. */
+#define SUDO_DEBUG_SUBSYS(n) (((n) >> 6) - 1)
+
+/*
+ * Wrapper for sudo_debug_enter() that declares __func__ as needed
+ * and sets sudo_debug_subsys for sudo_debug_exit().
+ */
+#ifdef HAVE___FUNC__
+# define debug_decl_func(funcname)
+# define debug_decl_vars(funcname, subsys) \
+ const int sudo_debug_subsys = (subsys);
+#else
+# define debug_decl_func(funcname) \
+ const char __func__[] = #funcname;
+# define debug_decl_vars(funcname, subsys) \
+ const int sudo_debug_subsys = (subsys); \
+ debug_decl_func(funcname);
+#endif
+#define debug_decl(funcname, subsys) \
+ debug_decl_vars((funcname), (subsys)) \
+ sudo_debug_enter(__func__, __FILE__, __LINE__, sudo_debug_subsys);
+
+/*
+ * Wrappers for sudo_debug_exit() and friends.
+ */
+#define debug_return \
+ do { \
+ sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys); \
+ return; \
+ } while (0)
+
+#define debug_return_int(ret) \
+ do { \
+ int sudo_debug_ret = (ret); \
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, \
+ sudo_debug_ret); \
+ return sudo_debug_ret; \
+ } while (0)
+
+#define debug_return_id_t(ret) \
+ do { \
+ id_t sudo_debug_ret = (ret); \
+ sudo_debug_exit_id_t(__func__, __FILE__, __LINE__, sudo_debug_subsys,\
+ sudo_debug_ret); \
+ return sudo_debug_ret; \
+ } while (0)
+
+#define debug_return_size_t(ret) \
+ do { \
+ size_t sudo_debug_ret = (ret); \
+ sudo_debug_exit_size_t(__func__, __FILE__, __LINE__, sudo_debug_subsys,\
+ sudo_debug_ret); \
+ return sudo_debug_ret; \
+ } while (0)
+
+#define debug_return_ssize_t(ret) \
+ do { \
+ ssize_t sudo_debug_ret = (ret); \
+ sudo_debug_exit_ssize_t(__func__, __FILE__, __LINE__, sudo_debug_subsys,\
+ sudo_debug_ret); \
+ return sudo_debug_ret; \
+ } while (0)
+
+#define debug_return_time_t(ret) \
+ do { \
+ time_t sudo_debug_ret = (ret); \
+ sudo_debug_exit_time_t(__func__, __FILE__, __LINE__, sudo_debug_subsys,\
+ sudo_debug_ret); \
+ return sudo_debug_ret; \
+ } while (0)
+
+#define debug_return_long(ret) \
+ do { \
+ long sudo_debug_ret = (ret); \
+ sudo_debug_exit_long(__func__, __FILE__, __LINE__, sudo_debug_subsys, \
+ sudo_debug_ret); \
+ return sudo_debug_ret; \
+ } while (0)
+
+#define debug_return_bool(ret) \
+ do { \
+ bool sudo_debug_ret = (ret); \
+ sudo_debug_exit_bool(__func__, __FILE__, __LINE__, sudo_debug_subsys, \
+ sudo_debug_ret); \
+ return sudo_debug_ret; \
+ } while (0)
+
+#define debug_return_str(ret) \
+ do { \
+ char *sudo_debug_ret = (ret); \
+ sudo_debug_exit_str(__func__, __FILE__, __LINE__, sudo_debug_subsys, \
+ sudo_debug_ret); \
+ return sudo_debug_ret; \
+ } while (0)
+
+#define debug_return_const_str(ret) \
+ do { \
+ const char *sudo_debug_ret = (ret); \
+ sudo_debug_exit_str(__func__, __FILE__, __LINE__, sudo_debug_subsys, \
+ sudo_debug_ret); \
+ return sudo_debug_ret; \
+ } while (0)
+
+#define debug_return_str_masked(ret) \
+ do { \
+ char *sudo_debug_ret = (ret); \
+ sudo_debug_exit_str_masked(__func__, __FILE__, __LINE__, \
+ sudo_debug_subsys, sudo_debug_ret); \
+ return sudo_debug_ret; \
+ } while (0)
+
+#define debug_return_ptr(ret) \
+ do { \
+ void *sudo_debug_ret = (ret); \
+ sudo_debug_exit_ptr(__func__, __FILE__, __LINE__, sudo_debug_subsys, \
+ sudo_debug_ret); \
+ return sudo_debug_ret; \
+ } while (0)
+
+#define debug_return_const_ptr(ret) \
+ do { \
+ const void *sudo_debug_ret = (ret); \
+ sudo_debug_exit_ptr(__func__, __FILE__, __LINE__, sudo_debug_subsys, \
+ sudo_debug_ret); \
+ return sudo_debug_ret; \
+ } while (0)
+
+/*
+ * Variadic macros are a C99 feature but GNU cpp has supported
+ * a (different) version of them for a long time.
+ */
+#if defined(NO_VARIADIC_MACROS)
+# define sudo_debug_printf sudo_debug_printf_nvm
+#elif defined(__GNUC__) && __GNUC__ == 2
+# define sudo_debug_printf(pri, fmt...) \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, (pri)|sudo_debug_subsys, \
+ fmt)
+#else
+# define sudo_debug_printf(pri, ...) \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, (pri)|sudo_debug_subsys, \
+ __VA_ARGS__)
+#endif
+
+#define sudo_debug_execve(pri, path, argv, envp) \
+ sudo_debug_execve2((pri)|sudo_debug_subsys, (path), (argv), (envp))
+
+#define sudo_debug_write(fd, str, len, errnum) \
+ sudo_debug_write2(fd, NULL, NULL, 0, (str), (len), (errnum))
+
+__dso_public int sudo_debug_deregister_v1(int instance_id);
+__dso_public void sudo_debug_enter_v1(const char *func, const char *file, int line, int subsys);
+__dso_public void sudo_debug_execve2_v1(int level, const char *path, char *const argv[], char *const envp[]);
+__dso_public void sudo_debug_exit_v1(const char *func, const char *file, int line, int subsys);
+__dso_public void sudo_debug_exit_bool_v1(const char *func, const char *file, int line, int subsys, bool ret);
+__dso_public void sudo_debug_exit_int_v1(const char *func, const char *file, int line, int subsys, int ret);
+__dso_public void sudo_debug_exit_long_v1(const char *func, const char *file, int line, int subsys, long ret);
+__dso_public void sudo_debug_exit_ptr_v1(const char *func, const char *file, int line, int subsys, const void *ret);
+__dso_public void sudo_debug_exit_id_t_v1(const char *func, const char *file, int line, int subsys, id_t ret);
+__dso_public void sudo_debug_exit_size_t_v1(const char *func, const char *file, int line, int subsys, size_t ret);
+__dso_public void sudo_debug_exit_ssize_t_v1(const char *func, const char *file, int line, int subsys, ssize_t ret);
+__dso_public void sudo_debug_exit_str_v1(const char *func, const char *file, int line, int subsys, const char *ret);
+__dso_public void sudo_debug_exit_str_masked_v1(const char *func, const char *file, int line, int subsys, const char *ret);
+__dso_public void sudo_debug_exit_time_t_v1(const char *func, const char *file, int line, int subsys, time_t ret);
+__dso_public pid_t sudo_debug_fork_v1(void);
+__dso_public int sudo_debug_get_active_instance_v1(void);
+__dso_public int sudo_debug_get_fds_v1(unsigned char **fds);
+__dso_public int sudo_debug_get_instance_v1(const char *program);
+__dso_public void sudo_debug_printf2_v1(const char *func, const char *file, int line, int level, const char *fmt, ...) __printf0like(5, 6);
+__dso_public void sudo_debug_printf_nvm_v1(int pri, const char *fmt, ...) __printf0like(2, 3);
+__dso_public int sudo_debug_register_v1(const char *program, const char *const subsystems[], unsigned int ids[], struct sudo_conf_debug_file_list *debug_files);
+__dso_public int sudo_debug_set_active_instance_v1(int inst);
+__dso_public void sudo_debug_update_fd_v1(int ofd, int nfd);
+__dso_public void sudo_debug_vprintf2_v1(const char *func, const char *file, int line, int level, const char *fmt, va_list ap) __printf0like(5, 0);
+__dso_public void sudo_debug_write2_v1(int fd, const char *func, const char *file, int line, const char *str, int len, int errnum);
+
+#define sudo_debug_deregister(_a) sudo_debug_deregister_v1((_a))
+#define sudo_debug_enter(_a, _b, _c, _d) sudo_debug_enter_v1((_a), (_b), (_c), (_d))
+#define sudo_debug_execve2(_a, _b, _c, _d) sudo_debug_execve2_v1((_a), (_b), (_c), (_d))
+#define sudo_debug_exit(_a, _b, _c, _d) sudo_debug_exit_v1((_a), (_b), (_c), (_d))
+#define sudo_debug_exit_bool(_a, _b, _c, _d, _e) sudo_debug_exit_bool_v1((_a), (_b), (_c), (_d), (_e))
+#define sudo_debug_exit_int(_a, _b, _c, _d, _e) sudo_debug_exit_int_v1((_a), (_b), (_c), (_d), (_e))
+#define sudo_debug_exit_long(_a, _b, _c, _d, _e) sudo_debug_exit_long_v1((_a), (_b), (_c), (_d), (_e))
+#define sudo_debug_exit_ptr(_a, _b, _c, _d, _e) sudo_debug_exit_ptr_v1((_a), (_b), (_c), (_d), (_e))
+#define sudo_debug_exit_id_t(_a, _b, _c, _d, _e) sudo_debug_exit_id_t_v1((_a), (_b), (_c), (_d), (_e))
+#define sudo_debug_exit_size_t(_a, _b, _c, _d, _e) sudo_debug_exit_size_t_v1((_a), (_b), (_c), (_d), (_e))
+#define sudo_debug_exit_ssize_t(_a, _b, _c, _d, _e) sudo_debug_exit_ssize_t_v1((_a), (_b), (_c), (_d), (_e))
+#define sudo_debug_exit_str(_a, _b, _c, _d, _e) sudo_debug_exit_str_v1((_a), (_b), (_c), (_d), (_e))
+#define sudo_debug_exit_str_masked(_a, _b, _c, _d, _e) sudo_debug_exit_str_masked_v1((_a), (_b), (_c), (_d), (_e))
+#define sudo_debug_exit_time_t(_a, _b, _c, _d, _e) sudo_debug_exit_time_t_v1((_a), (_b), (_c), (_d), (_e))
+#define sudo_debug_fork() sudo_debug_fork_v1()
+#define sudo_debug_get_active_instance() sudo_debug_get_active_instance_v1()
+#define sudo_debug_get_fds(_a) sudo_debug_get_fds_v1((_a))
+#define sudo_debug_get_instance(_a) sudo_debug_get_instance_v1((_a))
+#define sudo_debug_printf2 sudo_debug_printf2_v1
+#define sudo_debug_printf_nvm sudo_debug_printf_nvm_v1
+#define sudo_debug_register(_a, _b, _c, _d) sudo_debug_register_v1((_a), (_b), (_c), (_d))
+#define sudo_debug_set_active_instance(_a) sudo_debug_set_active_instance_v1((_a))
+#define sudo_debug_update_fd(_a, _b) sudo_debug_update_fd_v1((_a), (_b))
+#define sudo_debug_vprintf2(_a, _b, _c, _d, _e, _f) sudo_debug_vprintf2_v1((_a), (_b), (_c), (_d), (_e), (_f))
+#define sudo_debug_write2(_a, _b, _c, _d, _e, _f, _g) sudo_debug_write2_v1((_a), (_b), (_c), (_d), (_e), (_f), (_g))
+
+#endif /* SUDO_DEBUG_H */
diff --git a/include/sudo_digest.h b/include/sudo_digest.h
new file mode 100644
index 0000000..9fffa1b
--- /dev/null
+++ b/include/sudo_digest.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_DIGEST_H
+#define SUDO_DIGEST_H
+
+/* Digest types. */
+#define SUDO_DIGEST_SHA224 0
+#define SUDO_DIGEST_SHA256 1
+#define SUDO_DIGEST_SHA384 2
+#define SUDO_DIGEST_SHA512 3
+#define SUDO_DIGEST_INVALID 4
+
+struct sudo_digest;
+
+/* Public functions. */
+__dso_public struct sudo_digest *sudo_digest_alloc_v1(int digest_type);
+__dso_public void sudo_digest_free_v1(struct sudo_digest *dig);
+__dso_public void sudo_digest_reset_v1(struct sudo_digest *dig);
+__dso_public int sudo_digest_getlen_v1(int digest_type);
+__dso_public void sudo_digest_update_v1(struct sudo_digest *dig, const void *data, size_t len);
+__dso_public void sudo_digest_final_v1(struct sudo_digest *dig, unsigned char *md);
+
+#define sudo_digest_alloc(_a) sudo_digest_alloc_v1((_a))
+#define sudo_digest_free(_a) sudo_digest_free_v1((_a))
+#define sudo_digest_reset(_a) sudo_digest_reset_v1((_a))
+#define sudo_digest_getlen(_a) sudo_digest_getlen_v1((_a))
+#define sudo_digest_update(_a, _b, _c) sudo_digest_update_v1((_a), (_b), (_c))
+#define sudo_digest_final(_a, _b) sudo_digest_final_v1((_a), (_b))
+
+#endif /* SUDO_DIGEST_H */
diff --git a/include/sudo_dso.h b/include/sudo_dso.h
new file mode 100644
index 0000000..08fd8a8
--- /dev/null
+++ b/include/sudo_dso.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, 2013, 2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_DSO_H
+#define SUDO_DSO_H
+
+/* Values for sudo_dso_load() mode. */
+#define SUDO_DSO_LAZY 0x1
+#define SUDO_DSO_NOW 0x2
+#define SUDO_DSO_GLOBAL 0x4
+#define SUDO_DSO_LOCAL 0x8
+
+/* Special handle arguments for sudo_dso_findsym(). */
+#define SUDO_DSO_NEXT ((void *)-1) /* Search subsequent objects. */
+#define SUDO_DSO_DEFAULT ((void *)-2) /* Use default search algorithm. */
+#define SUDO_DSO_SELF ((void *)-3) /* Search the caller itself. */
+
+/* Internal structs for static linking of plugins. */
+struct sudo_preload_symbol {
+ const char *name;
+ void *addr;
+};
+struct sudo_preload_table {
+ const char *path;
+ void *handle;
+ struct sudo_preload_symbol *symbols;
+};
+
+/* Public functions. */
+__dso_public char *sudo_dso_strerror_v1(void);
+__dso_public int sudo_dso_unload_v1(void *handle);
+__dso_public void *sudo_dso_findsym_v1(void *handle, const char *symbol);
+__dso_public void *sudo_dso_load_v1(const char *path, int mode);
+__dso_public void sudo_dso_preload_table_v1(struct sudo_preload_table *table);
+
+#define sudo_dso_strerror() sudo_dso_strerror_v1()
+#define sudo_dso_unload(_a) sudo_dso_unload_v1((_a))
+#define sudo_dso_findsym(_a, _b) sudo_dso_findsym_v1((_a), (_b))
+#define sudo_dso_load(_a, _b) sudo_dso_load_v1((_a), (_b))
+#define sudo_dso_preload_table(_a) sudo_dso_preload_table_v1((_a))
+
+#endif /* SUDO_DSO_H */
diff --git a/include/sudo_event.h b/include/sudo_event.h
new file mode 100644
index 0000000..9797d58
--- /dev/null
+++ b/include/sudo_event.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2013-2015, 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_EVENT_H
+#define SUDO_EVENT_H
+
+#include <signal.h> /* for sigatomic_t and NSIG */
+#include "sudo_queue.h"
+
+/* Event types */
+#define SUDO_EV_TIMEOUT 0x01 /* fire after timeout */
+#define SUDO_EV_READ 0x02 /* fire when readable */
+#define SUDO_EV_WRITE 0x04 /* fire when writable */
+#define SUDO_EV_PERSIST 0x08 /* persist until deleted */
+#define SUDO_EV_SIGNAL 0x10 /* fire on signal receipt */
+#define SUDO_EV_SIGINFO 0x20 /* fire on signal receipt (siginfo) */
+
+/* Event flags (internal) */
+#define SUDO_EVQ_INSERTED 0x01 /* event is on the event queue */
+#define SUDO_EVQ_ACTIVE 0x02 /* event is on the active queue */
+#define SUDO_EVQ_TIMEOUTS 0x04 /* event is on the timeouts queue */
+
+/* Event loop flags */
+#define SUDO_EVLOOP_ONCE 0x01 /* Only run once through the loop */
+#define SUDO_EVLOOP_NONBLOCK 0x02 /* Do not block in event loop */
+
+/* Event base flags (internal) */
+#define SUDO_EVBASE_LOOPONCE SUDO_EVLOOP_ONCE
+#define SUDO_EVBASE_LOOPEXIT 0x02
+#define SUDO_EVBASE_LOOPBREAK 0x04
+#define SUDO_EVBASE_LOOPCONT 0x08
+#define SUDO_EVBASE_GOT_EXIT 0x10
+#define SUDO_EVBASE_GOT_BREAK 0x20
+#define SUDO_EVBASE_GOT_MASK 0xf0
+
+typedef void (*sudo_ev_callback_t)(int fd, int what, void *closure);
+
+/*
+ * Container for SUDO_EV_SIGINFO events that gets passed as the closure
+ * pointer. This allows us to pass a siginfo_t without changing everything.
+ */
+struct sudo_ev_siginfo_container {
+ void *closure;
+ siginfo_t *siginfo;
+ char si_buf[1];
+};
+
+/* Member of struct sudo_event_base. */
+struct sudo_event {
+ TAILQ_ENTRY(sudo_event) entries;
+ TAILQ_ENTRY(sudo_event) active_entries;
+ TAILQ_ENTRY(sudo_event) timeouts_entries;
+ struct sudo_event_base *base; /* base this event belongs to */
+ int fd; /* fd/signal we are interested in */
+ short events; /* SUDO_EV_* flags (in) */
+ short revents; /* SUDO_EV_* flags (out) */
+ short flags; /* internal event flags */
+ short pfd_idx; /* index into pfds array (XXX) */
+ sudo_ev_callback_t callback;/* user-provided callback */
+ struct timespec timeout; /* for SUDO_EV_TIMEOUT */
+ void *closure; /* user-provided data pointer */
+};
+TAILQ_HEAD(sudo_event_list, sudo_event);
+
+struct sudo_event_base {
+ struct sudo_event_list events; /* tail queue of all events */
+ struct sudo_event_list active; /* tail queue of active events */
+ struct sudo_event_list timeouts; /* tail queue of timeout events */
+ struct sudo_event signal_event; /* storage for signal pipe event */
+ struct sudo_event_list signals[NSIG]; /* array of signal event tail queues */
+ struct sigaction *orig_handlers[NSIG]; /* original signal handlers */
+ siginfo_t *siginfo[NSIG]; /* detailed signal info */
+ sig_atomic_t signal_pending[NSIG]; /* pending signals */
+ sig_atomic_t signal_caught; /* at least one signal caught */
+ int num_handlers; /* number of installed handlers */
+ int signal_pipe[2]; /* so we can wake up on singal */
+#if defined(HAVE_POLL) || defined(HAVE_PPOLL)
+ struct pollfd *pfds; /* array of struct pollfd */
+ int pfd_max; /* size of the pfds array */
+ int pfd_high; /* highest slot used */
+ int pfd_free; /* idx of next free entry or pfd_max if full */
+#else
+ fd_set *readfds_in; /* read I/O descriptor set (in) */
+ fd_set *writefds_in; /* write I/O descriptor set (in) */
+ fd_set *readfds_out; /* read I/O descriptor set (out) */
+ fd_set *writefds_out; /* write I/O descriptor set (out) */
+ int maxfd; /* max fd we can store in readfds/writefds */
+ int highfd; /* highest fd to pass as 1st arg to select */
+#endif /* HAVE_POLL */
+ unsigned int flags; /* SUDO_EVBASE_* */
+};
+
+/* Allocate a new event base. */
+__dso_public struct sudo_event_base *sudo_ev_base_alloc_v1(void);
+#define sudo_ev_base_alloc() sudo_ev_base_alloc_v1()
+
+/* Free an event base. */
+__dso_public void sudo_ev_base_free_v1(struct sudo_event_base *base);
+#define sudo_ev_base_free(_a) sudo_ev_base_free_v1((_a))
+
+/* Set the default event base. */
+__dso_public void sudo_ev_base_setdef_v1(struct sudo_event_base *base);
+#define sudo_ev_base_setdef(_a) sudo_ev_base_setdef_v1((_a))
+
+/* Allocate a new event. */
+__dso_public struct sudo_event *sudo_ev_alloc_v1(int fd, short events, sudo_ev_callback_t callback, void *closure);
+#define sudo_ev_alloc(_a, _b, _c, _d) sudo_ev_alloc_v1((_a), (_b), (_c), (_d))
+
+/* Free an event. */
+__dso_public void sudo_ev_free_v1(struct sudo_event *ev);
+#define sudo_ev_free(_a) sudo_ev_free_v1((_a))
+
+/* Add an event, returns 0 on success, -1 on error */
+__dso_public int sudo_ev_add_v1(struct sudo_event_base *head, struct sudo_event *ev, struct timeval *timo, bool tohead);
+__dso_public int sudo_ev_add_v2(struct sudo_event_base *head, struct sudo_event *ev, struct timespec *timo, bool tohead);
+#define sudo_ev_add(_a, _b, _c, _d) sudo_ev_add_v2((_a), (_b), (_c), (_d))
+
+/* Delete an event, returns 0 on success, -1 on error */
+__dso_public int sudo_ev_del_v1(struct sudo_event_base *head, struct sudo_event *ev);
+#define sudo_ev_del(_a, _b) sudo_ev_del_v1((_a), (_b))
+
+/* Dispatch events, returns SUDO_CB_SUCCESS, SUDO_CB_BREAK or SUDO_CB_ERROR */
+__dso_public int sudo_ev_dispatch_v1(struct sudo_event_base *head);
+#define sudo_ev_dispatch(_a) sudo_ev_dispatch_v1((_a))
+
+/* Main event loop, returns SUDO_CB_SUCCESS, SUDO_CB_BREAK or SUDO_CB_ERROR */
+__dso_public int sudo_ev_loop_v1(struct sudo_event_base *head, int flags);
+#define sudo_ev_loop(_a, _b) sudo_ev_loop_v1((_a), (_b))
+
+/* Return the remaining timeout associated with an event. */
+__dso_public int sudo_ev_get_timeleft_v1(struct sudo_event *ev, struct timeval *tv);
+__dso_public int sudo_ev_get_timeleft_v2(struct sudo_event *ev, struct timespec *tv);
+#define sudo_ev_get_timeleft(_a, _b) sudo_ev_get_timeleft_v2((_a), (_b))
+
+/* Cause the event loop to exit after one run through. */
+__dso_public void sudo_ev_loopexit_v1(struct sudo_event_base *base);
+#define sudo_ev_loopexit(_a) sudo_ev_loopexit_v1((_a))
+
+/* Break out of the event loop right now. */
+__dso_public void sudo_ev_loopbreak_v1(struct sudo_event_base *base);
+#define sudo_ev_loopbreak(_a) sudo_ev_loopbreak_v1((_a))
+
+/* Rescan for events and restart the event loop. */
+__dso_public void sudo_ev_loopcontinue_v1(struct sudo_event_base *base);
+#define sudo_ev_loopcontinue(_a) sudo_ev_loopcontinue_v1((_a))
+
+/* Returns true if event loop stopped due to sudo_ev_loopexit(). */
+__dso_public bool sudo_ev_got_exit_v1(struct sudo_event_base *base);
+#define sudo_ev_got_exit(_a) sudo_ev_got_exit_v1((_a))
+
+/* Returns true if event loop stopped due to sudo_ev_loopbreak(). */
+__dso_public bool sudo_ev_got_break_v1(struct sudo_event_base *base);
+#define sudo_ev_got_break(_a) sudo_ev_got_break_v1((_a))
+
+/* Return the fd associated with an event. */
+#define sudo_ev_get_fd(_ev) ((_ev) ? (_ev)->fd : -1)
+
+/* Return the (absolute) timeout associated with an event or NULL. */
+#define sudo_ev_get_timeout(_ev) \
+ (ISSET((_ev)->flags, SUDO_EVQ_TIMEOUTS) ? &(_ev)->timeout : NULL)
+
+/* Return the base an event is associated with or NULL. */
+#define sudo_ev_get_base(_ev) ((_ev) ? (_ev)->base : NULL)
+
+/* Magic pointer value to use self pointer as callback arg. */
+#define sudo_ev_self_cbarg() ((void *)-1)
+
+/* Add an event to the base's active queue and mark it active (internal). */
+void sudo_ev_activate(struct sudo_event_base *base, struct sudo_event *ev);
+
+/*
+ * Backend implementation.
+ */
+int sudo_ev_base_alloc_impl(struct sudo_event_base *base);
+void sudo_ev_base_free_impl(struct sudo_event_base *base);
+int sudo_ev_add_impl(struct sudo_event_base *base, struct sudo_event *ev);
+int sudo_ev_del_impl(struct sudo_event_base *base, struct sudo_event *ev);
+int sudo_ev_scan_impl(struct sudo_event_base *base, int flags);
+
+#endif /* SUDO_EVENT_H */
diff --git a/include/sudo_fatal.h b/include/sudo_fatal.h
new file mode 100644
index 0000000..ea92b3b
--- /dev/null
+++ b/include/sudo_fatal.h
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2004, 2010-2015, 2017-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_FATAL_H
+#define SUDO_FATAL_H
+
+#include <stdarg.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+
+/*
+ * We wrap fatal/fatalx and warn/warnx so that the same output can
+ * go to the debug file, if there is one.
+ */
+#if (defined(SUDO_ERROR_WRAP) && SUDO_ERROR_WRAP == 0) || defined(NO_VARIADIC_MACROS)
+# define sudo_fatal sudo_fatal_nodebug_v1
+# define sudo_fatalx sudo_fatalx_nodebug_v1
+# define sudo_gai_fatal sudo_gai_fatal_nodebug_v1
+# define sudo_warn sudo_warn_nodebug_v1
+# define sudo_warnx sudo_warnx_nodebug_v1
+# define sudo_gai_warn sudo_gai_warn_nodebug_v1
+# define sudo_vfatal(fmt, ap) sudo_vfatal_nodebug_v1((fmt), (ap))
+# define sudo_vfatalx(fmt, ap) sudo_vfatalx_nodebug_v1((fmt), (ap))
+# define sudo_gai_vfatal(en, fmt, ap) sudo_vfatal_nodebug_v1((en), (fmt), (ap))
+# define sudo_vwarn(fmt, ap) sudo_vwarn_nodebug_v1((fmt), (ap))
+# define sudo_vwarnx(fmt, ap) sudo_vwarnx_nodebug_v1((fmt), (ap))
+# define sudo_gai_vwarn(en, fmt, ap) sudo_vwarn_nodebug_v1((en), (fmt), (ap))
+#else /* SUDO_ERROR_WRAP */
+# if defined(__GNUC__) && __GNUC__ == 2
+# define sudo_fatal(fmt...) do { \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
+ fmt); \
+ sudo_fatal_nodebug_v1(fmt); \
+} while (0)
+# define sudo_fatalx(fmt...) do { \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \
+ sudo_fatalx_nodebug_v1(fmt); \
+} while (0)
+# define sudo_gai_fatal(en, fmt...) do { \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \
+ sudo_gai_fatal_nodebug_v1((en), fmt); \
+} while (0)
+# define sudo_warn(fmt...) do { \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
+ fmt); \
+ sudo_warn_nodebug_v1(fmt); \
+} while (0)
+# define sudo_warnx(fmt...) do { \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \
+ sudo_warnx_nodebug_v1(fmt); \
+} while (0)
+# define sudo_gai_warn(en, fmt...) do { \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \
+ sudo_gai_warn_nodebug_v1((en), fmt); \
+} while (0)
+# else
+# define sudo_fatal(...) do { \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
+ __VA_ARGS__); \
+ sudo_fatal_nodebug_v1(__VA_ARGS__); \
+} while (0)
+# define sudo_fatalx(...) do { \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \
+ sudo_fatalx_nodebug_v1(__VA_ARGS__); \
+} while (0)
+# define sudo_gai_fatal(en, ...) do { \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \
+ sudo_gai_fatal_nodebug_v1((en), __VA_ARGS__); \
+} while (0)
+# define sudo_warn(...) do { \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
+ __VA_ARGS__); \
+ sudo_warn_nodebug_v1(__VA_ARGS__); \
+} while (0)
+# define sudo_warnx(...) do { \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \
+ sudo_warnx_nodebug_v1(__VA_ARGS__); \
+} while (0)
+# define sudo_gai_warn(en, ...) do { \
+ sudo_debug_printf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \
+ sudo_gai_warn_nodebug_v1((en), __VA_ARGS__); \
+} while (0)
+# endif /* __GNUC__ == 2 */
+# define sudo_vfatal(fmt, ap) do { \
+ va_list ap2; \
+ va_copy(ap2, (ap)); \
+ sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
+ (fmt), ap2); \
+ sudo_vfatal_nodebug_v1((fmt), (ap)); \
+} while (0)
+# define sudo_vfatalx(fmt, ap) do { \
+ va_list ap2; \
+ va_copy(ap2, (ap)); \
+ sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2); \
+ sudo_vfatalx_nodebug_v1((fmt), (ap)); \
+} while (0)
+# define sudo_gai_vfatal(en, fmt, ap) do { \
+ va_list ap2; \
+ va_copy(ap2, (ap)); \
+ sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2); \
+ sudo_gai_vfatal_nodebug_v1((en), (fmt), (ap)); \
+} while (0)
+# define sudo_vwarn(fmt, ap) do { \
+ va_list ap2; \
+ va_copy(ap2, (ap)); \
+ sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
+ (fmt), ap2); \
+ sudo_vwarn_nodebug_v1((fmt), (ap)); \
+} while (0)
+# define sudo_vwarnx(fmt, ap) do { \
+ va_list ap2; \
+ va_copy(ap2, (ap)); \
+ sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2); \
+ sudo_vwarnx_nodebug_v1((fmt), (ap)); \
+} while (0)
+# define sudo_gai_vwarn(en, fmt, ap) do { \
+ va_list ap2; \
+ va_copy(ap2, (ap)); \
+ sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \
+ SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2); \
+ sudo_gai_vwarn_nodebug_v1((en), (fmt), (ap)); \
+} while (0)
+#endif /* SUDO_ERROR_WRAP */
+
+typedef void (*sudo_fatal_callback_t)(void);
+
+struct sudo_conv_message;
+struct sudo_conv_reply;
+struct sudo_conv_callback;
+
+__dso_public int sudo_fatal_callback_deregister_v1(sudo_fatal_callback_t func);
+__dso_public int sudo_fatal_callback_register_v1(sudo_fatal_callback_t func);
+__dso_public char *sudo_warn_gettext_v1(const char *domainname, const char *msgid) __format_arg(2);
+__dso_public void sudo_warn_set_locale_func_v1(bool (*func)(bool, int *));
+__dso_public void sudo_fatal_nodebug_v1(const char *fmt, ...) __printf0like(1, 2) __attribute__((__noreturn__));
+__dso_public void sudo_fatalx_nodebug_v1(const char *fmt, ...) __printflike(1, 2) __attribute__((__noreturn__));
+__dso_public void sudo_gai_fatal_nodebug_v1(int errnum, const char *fmt, ...) __printflike(2, 3) __attribute__((__noreturn__));
+__dso_public void sudo_vfatal_nodebug_v1(const char *fmt, va_list ap) __printf0like(1, 0) __attribute__((__noreturn__));
+__dso_public void sudo_vfatalx_nodebug_v1(const char *fmt, va_list ap) __printflike(1, 0) __attribute__((__noreturn__));
+__dso_public void sudo_gai_vfatal_nodebug_v1(int errnum, const char *fmt, va_list ap) __printflike(2, 0) __attribute__((__noreturn__));
+__dso_public void sudo_warn_nodebug_v1(const char *fmt, ...) __printf0like(1, 2);
+__dso_public void sudo_warnx_nodebug_v1(const char *fmt, ...) __printflike(1, 2);
+__dso_public void sudo_gai_warn_nodebug_v1(int errnum, const char *fmt, ...) __printflike(2, 3);
+__dso_public void sudo_vwarn_nodebug_v1(const char *fmt, va_list ap) __printf0like(1, 0);
+__dso_public void sudo_vwarnx_nodebug_v1(const char *fmt, va_list ap) __printflike(1, 0);
+__dso_public void sudo_gai_vwarn_nodebug_v1(int errnum, const char *fmt, va_list ap) __printflike(2, 0);
+__dso_public void sudo_warn_set_conversation_v1(int (*conv)(int num_msgs, const struct sudo_conv_message *msgs, struct sudo_conv_reply *replies, struct sudo_conv_callback *callback));
+
+#define sudo_fatal_callback_deregister(_a) sudo_fatal_callback_deregister_v1((_a))
+#define sudo_fatal_callback_register(_a) sudo_fatal_callback_register_v1((_a))
+#define sudo_warn_set_locale_func(_a) sudo_warn_set_locale_func_v1((_a))
+#define sudo_fatal_nodebug sudo_fatal_nodebug_v1
+#define sudo_fatalx_nodebug sudo_fatalx_nodebug_v1
+#define sudo_gai_fatal_nodebug sudo_gai_fatal_nodebug_v1
+#define sudo_vfatal_nodebug(_a, _b) sudo_vfatal_nodebug_v1((_a), (_b))
+#define sudo_vfatalx_nodebug(_a, _b) sudo_vfatalx_nodebug_v1((_a), (_b))
+#define sudo_gai_vfatal_nodebug(_a, _b, _c) sudo_gai_vfatal_nodebug_v1((_a), (_b), (_c))
+#define sudo_warn_nodebug sudo_warn_nodebug_v1
+#define sudo_warnx_nodebug sudo_warnx_nodebug_v1
+#define sudo_gai_warn_nodebug sudo_gai_warn_nodebug_v1
+#define sudo_vwarn_nodebug(_a, _b) sudo_vwarn_nodebug_v1((_a), (_b))
+#define sudo_vwarnx_nodebug(_a, _b) sudo_vwarnx_nodebug_v1((_a), (_b))
+#define sudo_gai_vwarn_nodebug(_a, _b, _c) sudo_gai_vwarn_nodebug_v1((_a), (_b), (_c))
+#define sudo_warn_set_conversation(_a) sudo_warn_set_conversation_v1(_a)
+
+#ifdef DEFAULT_TEXT_DOMAIN
+# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(DEFAULT_TEXT_DOMAIN, (_a))
+#else
+# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
+#endif
+
+#endif /* SUDO_FATAL_H */
diff --git a/include/sudo_gettext.h b/include/sudo_gettext.h
new file mode 100644
index 0000000..a770b08
--- /dev/null
+++ b/include/sudo_gettext.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2011-2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_GETTEXT_H
+#define SUDO_GETTEXT_H
+
+/*
+ * Solaris locale.h includes libintl.h which causes problems when we
+ * redefine the gettext functions. We include it first to avoid this.
+ */
+#include <locale.h>
+
+#ifdef HAVE_LIBINTL_H
+
+# include <libintl.h>
+
+/*
+ * If DEFAULT_TEXT_DOMAIN is defined, use its value as the domain for
+ * gettext() and ngettext() instead of the value set by textdomain().
+ * This is used by the sudoers plugin as well as the convenience libraries.
+ */
+# ifdef DEFAULT_TEXT_DOMAIN
+# undef gettext
+# define gettext(String) \
+ dgettext(DEFAULT_TEXT_DOMAIN, String)
+# undef ngettext
+# define ngettext(String, String_Plural, N) \
+ dngettext(DEFAULT_TEXT_DOMAIN, String, String_Plural, N)
+# endif
+
+/*
+ * Older versions of Solaris lack ngettext() so we have to kludge it.
+ */
+# ifndef HAVE_NGETTEXT
+# undef ngettext
+# define ngettext(String, String_Plural, N) \
+ ((N) == 1 ? gettext(String) : gettext(String_Plural))
+# endif
+
+/* Gettext convenience macros */
+# define _(String) gettext(String)
+# define gettext_noop(String) String
+# define N_(String) gettext_noop(String)
+# define U_(String) sudo_warn_gettext(String)
+
+#else /* !HAVE_LIBINTL_H */
+
+/*
+ * Internationalization is either unavailable or has been disabled.
+ * Define away the gettext functions used by sudo.
+ */
+# define _(String) String
+# define N_(String) String
+# define U_(String) String
+# define textdomain(Domain)
+# define bindtextdomain(Package, Directory)
+# define ngettext(String, String_Plural, N) \
+ ((N) == 1 ? (String) : (String_Plural))
+
+#endif /* HAVE_LIBINTL_H */
+
+#endif /* SUDO_GETTEXT_H */
diff --git a/include/sudo_lbuf.h b/include/sudo_lbuf.h
new file mode 100644
index 0000000..8e07063
--- /dev/null
+++ b/include/sudo_lbuf.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2007, 2010, 2011, 2013-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_LBUF_H
+#define SUDO_LBUF_H
+
+/*
+ * Line buffer struct.
+ */
+struct sudo_lbuf {
+ int (*output)(const char *);
+ char *buf;
+ const char *continuation;
+ int indent;
+ int len;
+ int size;
+ short cols;
+ short error;
+};
+
+typedef int (*sudo_lbuf_output_t)(const char *);
+
+__dso_public void sudo_lbuf_init_v1(struct sudo_lbuf *lbuf, sudo_lbuf_output_t output, int indent, const char *continuation, int cols);
+__dso_public void sudo_lbuf_destroy_v1(struct sudo_lbuf *lbuf);
+__dso_public bool sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...) __printflike(2, 3);
+__dso_public bool sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char *fmt, ...) __printflike(3, 4);
+__dso_public void sudo_lbuf_print_v1(struct sudo_lbuf *lbuf);
+__dso_public bool sudo_lbuf_error_v1(struct sudo_lbuf *lbuf);
+__dso_public void sudo_lbuf_clearerr_v1(struct sudo_lbuf *lbuf);
+
+#define sudo_lbuf_init(_a, _b, _c, _d, _e) sudo_lbuf_init_v1((_a), (_b), (_c), (_d), (_e))
+#define sudo_lbuf_destroy(_a) sudo_lbuf_destroy_v1((_a))
+#define sudo_lbuf_append sudo_lbuf_append_v1
+#define sudo_lbuf_append_quoted sudo_lbuf_append_quoted_v1
+#define sudo_lbuf_print(_a) sudo_lbuf_print_v1((_a))
+#define sudo_lbuf_error(_a) sudo_lbuf_error_v1((_a))
+#define sudo_lbuf_clearerr(_a) sudo_lbuf_clearerr_v1((_a))
+
+#endif /* SUDO_LBUF_H */
diff --git a/include/sudo_plugin.h b/include/sudo_plugin.h
new file mode 100644
index 0000000..31d96cc
--- /dev/null
+++ b/include/sudo_plugin.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_PLUGIN_H
+#define SUDO_PLUGIN_H
+
+/* API version major/minor */
+#define SUDO_API_VERSION_MAJOR 1
+#define SUDO_API_VERSION_MINOR 13
+#define SUDO_API_MKVERSION(x, y) (((x) << 16) | (y))
+#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
+
+/* Getters and setters for plugin API versions */
+#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
+#define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffffU)
+#define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \
+ *(vp) = (*(vp) & 0x0000ffffU) | ((n) << 16); \
+} while(0)
+#define SUDO_API_VERSION_SET_MINOR(vp, n) do { \
+ *(vp) = (*(vp) & 0xffff0000U) | (n); \
+} while(0)
+
+/* Conversation function types and defines */
+struct sudo_conv_message {
+#define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */
+#define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */
+#define SUDO_CONV_ERROR_MSG 0x0003 /* error message */
+#define SUDO_CONV_INFO_MSG 0x0004 /* informational message */
+#define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */
+#define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */
+#define SUDO_CONV_PREFER_TTY 0x2000 /* flag: use tty if possible */
+ int msg_type;
+ int timeout;
+ const char *msg;
+};
+
+/*
+ * Maximum length of a reply (not including the trailing NUL) when
+ * conversing with the user. In practical terms, this is the longest
+ * password sudo will support. This means that a buffer of size
+ * SUDO_CONV_REPL_MAX+1 is guaranteed to be able to hold any reply
+ * from the conversation function. It is also useful as a max value
+ * for memset_s() when clearing passwords returned by the conversation
+ * function.
+ */
+#define SUDO_CONV_REPL_MAX 255
+
+struct sudo_conv_reply {
+ char *reply;
+};
+
+/* Conversation callback API version major/minor */
+#define SUDO_CONV_CALLBACK_VERSION_MAJOR 1
+#define SUDO_CONV_CALLBACK_VERSION_MINOR 0
+#define SUDO_CONV_CALLBACK_VERSION SUDO_API_MKVERSION(SUDO_CONV_CALLBACK_VERSION_MAJOR, SUDO_CONV_CALLBACK_VERSION_MINOR)
+
+/*
+ * Callback struct to be passed to the conversation function.
+ * Can be used to perform operations on suspend/resume such
+ * as dropping/acquiring locks.
+ */
+typedef int (*sudo_conv_callback_fn_t)(int signo, void *closure);
+struct sudo_conv_callback {
+ unsigned int version;
+ void *closure;
+ sudo_conv_callback_fn_t on_suspend;
+ sudo_conv_callback_fn_t on_resume;
+};
+
+typedef int (*sudo_conv_t)(int num_msgs, const struct sudo_conv_message msgs[],
+ struct sudo_conv_reply replies[], struct sudo_conv_callback *callback);
+typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
+
+/*
+ * Hooks allow a plugin to hook into specific sudo and/or libc functions.
+ */
+
+/* Hook functions typedefs. */
+typedef int (*sudo_hook_fn_t)();
+typedef int (*sudo_hook_fn_setenv_t)(const char *name, const char *value, int overwrite, void *closure);
+typedef int (*sudo_hook_fn_putenv_t)(char *string, void *closure);
+typedef int (*sudo_hook_fn_getenv_t)(const char *name, char **value, void *closure);
+typedef int (*sudo_hook_fn_unsetenv_t)(const char *name, void *closure);
+
+/* Hook structure definition. */
+struct sudo_hook {
+ unsigned int hook_version;
+ unsigned int hook_type;
+ sudo_hook_fn_t hook_fn;
+ void *closure;
+};
+
+/* Hook API version major/minor */
+#define SUDO_HOOK_VERSION_MAJOR 1
+#define SUDO_HOOK_VERSION_MINOR 0
+#define SUDO_HOOK_VERSION SUDO_API_MKVERSION(SUDO_HOOK_VERSION_MAJOR, SUDO_HOOK_VERSION_MINOR)
+
+/*
+ * Hook function return values.
+ */
+#define SUDO_HOOK_RET_ERROR -1 /* error */
+#define SUDO_HOOK_RET_NEXT 0 /* go to the next hook in the list */
+#define SUDO_HOOK_RET_STOP 1 /* stop hook processing for this type */
+
+/*
+ * Hooks for setenv/unsetenv/putenv/getenv.
+ * This allows the plugin to be notified when a PAM module modifies
+ * the environment so it can update the copy of the environment that
+ * is passed to execve().
+ */
+#define SUDO_HOOK_SETENV 1
+#define SUDO_HOOK_UNSETENV 2
+#define SUDO_HOOK_PUTENV 3
+#define SUDO_HOOK_GETENV 4
+
+/* Policy plugin type and defines */
+struct passwd;
+struct policy_plugin {
+#define SUDO_POLICY_PLUGIN 1
+ unsigned int type; /* always SUDO_POLICY_PLUGIN */
+ unsigned int version; /* always SUDO_API_VERSION */
+ int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t sudo_printf, char * const settings[],
+ char * const user_info[], char * const user_env[],
+ char * const plugin_options[]);
+ void (*close)(int exit_status, int error); /* wait status or error */
+ int (*show_version)(int verbose);
+ int (*check_policy)(int argc, char * const argv[],
+ char *env_add[], char **command_info[],
+ char **argv_out[], char **user_env_out[]);
+ int (*list)(int argc, char * const argv[], int verbose,
+ const char *list_user);
+ int (*validate)(void);
+ void (*invalidate)(int remove);
+ int (*init_session)(struct passwd *pwd, char **user_env_out[]);
+ void (*register_hooks)(int version, int (*register_hook)(struct sudo_hook *hook));
+ void (*deregister_hooks)(int version, int (*deregister_hook)(struct sudo_hook *hook));
+};
+
+/* I/O plugin type and defines */
+struct io_plugin {
+#define SUDO_IO_PLUGIN 2
+ unsigned int type; /* always SUDO_IO_PLUGIN */
+ unsigned int version; /* always SUDO_API_VERSION */
+ int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t sudo_printf, char * const settings[],
+ char * const user_info[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[],
+ char * const plugin_options[]);
+ void (*close)(int exit_status, int error); /* wait status or error */
+ int (*show_version)(int verbose);
+ int (*log_ttyin)(const char *buf, unsigned int len);
+ int (*log_ttyout)(const char *buf, unsigned int len);
+ int (*log_stdin)(const char *buf, unsigned int len);
+ int (*log_stdout)(const char *buf, unsigned int len);
+ int (*log_stderr)(const char *buf, unsigned int len);
+ void (*register_hooks)(int version, int (*register_hook)(struct sudo_hook *hook));
+ void (*deregister_hooks)(int version, int (*deregister_hook)(struct sudo_hook *hook));
+ int (*change_winsize)(unsigned int rows, unsigned int cols);
+ int (*log_suspend)(int signo);
+};
+
+/* Sudoers group plugin version major/minor */
+#define GROUP_API_VERSION_MAJOR 1
+#define GROUP_API_VERSION_MINOR 0
+#define GROUP_API_VERSION SUDO_API_MKVERSION(GROUP_API_VERSION_MAJOR, GROUP_API_VERSION_MINOR)
+
+/* Getters and setters for group version (for source compat only) */
+#define GROUP_API_VERSION_GET_MAJOR(v) SUDO_API_VERSION_GET_MAJOR(v)
+#define GROUP_API_VERSION_GET_MINOR(v) SUDO_API_VERSION_GET_MINOR(v)
+#define GROUP_API_VERSION_SET_MAJOR(vp, n) SUDO_API_VERSION_SET_MAJOR(vp, n)
+#define GROUP_API_VERSION_SET_MINOR(vp, n) SUDO_API_VERSION_SET_MINOR(vp, n)
+
+/*
+ * version: for compatibility checking
+ * group_init: return 1 on success, 0 if unconfigured, -1 on error.
+ * group_cleanup: called to clean up resources used by provider
+ * user_in_group: returns 1 if user is in group, 0 if not.
+ * note that pwd may be NULL if the user is not in passwd.
+ */
+struct sudoers_group_plugin {
+ unsigned int version;
+ int (*init)(int version, sudo_printf_t sudo_printf, char *const argv[]);
+ void (*cleanup)(void);
+ int (*query)(const char *user, const char *group, const struct passwd *pwd);
+};
+
+#endif /* SUDO_PLUGIN_H */
diff --git a/include/sudo_queue.h b/include/sudo_queue.h
new file mode 100644
index 0000000..f48daf9
--- /dev/null
+++ b/include/sudo_queue.h
@@ -0,0 +1,821 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ * $FreeBSD: head/sys/sys/queue.h 251887 2013-06-18 02:57:56Z lstewart $
+ */
+
+#ifndef SUDO_QUEUE_H
+#define SUDO_QUEUE_H
+
+/*
+ * This file defines four types of data structures: singly-linked lists,
+ * singly-linked tail queues, lists and tail queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction. Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may be traversed in either direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * A headless tail queue lacks a head structure, The first element acts
+ * as a de facto list head. It uses the same entry struct as a regular
+ * tail queue for easy conversion from headless to headful.
+ * It is capable of concatenating queues as well as individual elements.
+ * Traversing in reverse is more expensive due to lack of a list head.
+ * Note: elements must be initialized before use.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ * SLIST LIST STAILQ TAILQ
+ * _HEAD + + + +
+ * _HEAD_INITIALIZER + + + +
+ * _ENTRY + + + +
+ * _INIT + + + +
+ * _EMPTY + + + +
+ * _FIRST + + + +
+ * _NEXT + + + +
+ * _PREV - + - +
+ * _LAST - - + +
+ * _FOREACH + + + +
+ * _FOREACH_FROM + + + +
+ * _FOREACH_SAFE + + + +
+ * _FOREACH_FROM_SAFE + + + +
+ * _FOREACH_REVERSE - - - +
+ * _FOREACH_REVERSE_FROM - - - +
+ * _FOREACH_REVERSE_SAFE - - - +
+ * _FOREACH_REVERSE_FROM_SAFE - - - +
+ * _INSERT_HEAD + + + +
+ * _INSERT_BEFORE - + - +
+ * _INSERT_AFTER + + + +
+ * _INSERT_TAIL - - + +
+ * _CONCAT - - + +
+ * _REMOVE_AFTER + - + -
+ * _REMOVE_HEAD + - + -
+ * _REMOVE + + + +
+ * _SWAP + + + +
+ *
+ */
+#ifdef QUEUE_MACRO_DEBUG
+/* Store the last 2 places the queue element or head was altered */
+struct qm_trace {
+ unsigned long lastline;
+ unsigned long prevline;
+ const char *lastfile;
+ const char *prevfile;
+};
+
+#undef TRACEBUF
+#define TRACEBUF struct qm_trace trace;
+#undef TRACEBUF_INITIALIZER
+#define TRACEBUF_INITIALIZER { __FILE__, __LINE__, NULL, 0 } ,
+#undef TRASHIT
+#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
+#undef QMD_SAVELINK
+#define QMD_SAVELINK(name, link) void **name = (void *)&(link)
+
+#undef QMD_TRACE_HEAD
+#define QMD_TRACE_HEAD(head) do { \
+ (head)->trace.prevline = (head)->trace.lastline; \
+ (head)->trace.prevfile = (head)->trace.lastfile; \
+ (head)->trace.lastline = __LINE__; \
+ (head)->trace.lastfile = __FILE__; \
+} while (0)
+
+#undef QMD_TRACE_ELEM
+#define QMD_TRACE_ELEM(elem) do { \
+ (elem)->trace.prevline = (elem)->trace.lastline; \
+ (elem)->trace.prevfile = (elem)->trace.lastfile; \
+ (elem)->trace.lastline = __LINE__; \
+ (elem)->trace.lastfile = __FILE__; \
+} while (0)
+
+#else
+#undef QMD_TRACE_ELEM
+#define QMD_TRACE_ELEM(elem)
+#undef QMD_TRACE_HEAD
+#define QMD_TRACE_HEAD(head)
+#undef QMD_SAVELINK
+#define QMD_SAVELINK(name, link)
+#undef TRACEBUF
+#define TRACEBUF
+#undef TRACEBUF_INITIALIZER
+#define TRACEBUF_INITIALIZER
+#undef TRASHIT
+#define TRASHIT(x)
+#endif /* QUEUE_MACRO_DEBUG */
+
+/*
+ * XXX - Work around a bug in the llvm static analyzer.
+ * https://bugs.llvm.org//show_bug.cgi?id=18222
+ */
+#ifdef __clang_analyzer__
+# define ANALYZER_ASSERT(x) do { \
+ if (!__builtin_expect(!(x), 0)) \
+ __builtin_trap(); \
+} while (0)
+#else
+# define ANALYZER_ASSERT(x) do {} while (0)
+#endif /* __clang_analyzer__ */
+
+ /*
+ * Singly-linked List declarations.
+ */
+#undef SLIST_HEAD
+#define SLIST_HEAD(name, type) \
+struct name { \
+ struct type *slh_first; /* first element */ \
+}
+
+#undef SLIST_HEAD_INITIALIZER
+#define SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#undef SLIST_ENTRY
+#define SLIST_ENTRY(type) \
+struct { \
+ struct type *sle_next; /* next element */ \
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#undef SLIST_EMPTY
+#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
+
+#undef SLIST_FIRST
+#define SLIST_FIRST(head) ((head)->slh_first)
+
+#undef SLIST_FOREACH
+#define SLIST_FOREACH(var, head, field) \
+ for ((var) = SLIST_FIRST((head)); \
+ (var); \
+ (var) = SLIST_NEXT((var), field))
+
+#undef SLIST_FOREACH_FROM
+#define SLIST_FOREACH_FROM(var, head, field) \
+ for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \
+ (var); \
+ (var) = SLIST_NEXT((var), field))
+
+#undef SLIST_FOREACH_SAFE
+#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = SLIST_FIRST((head)); \
+ (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#undef SLIST_FOREACH_FROM_SAFE
+#define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \
+ for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \
+ (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#undef SLIST_FOREACH_PREVPTR
+#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
+ for ((varp) = &SLIST_FIRST((head)); \
+ ((var) = *(varp)) != NULL; \
+ (varp) = &SLIST_NEXT((var), field))
+
+#undef SLIST_INIT
+#define SLIST_INIT(head) do { \
+ SLIST_FIRST((head)) = NULL; \
+} while (0)
+
+#undef SLIST_INSERT_AFTER
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+ SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
+ SLIST_NEXT((slistelm), field) = (elm); \
+} while (0)
+
+#undef SLIST_INSERT_HEAD
+#define SLIST_INSERT_HEAD(head, elm, field) do { \
+ SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
+ SLIST_FIRST((head)) = (elm); \
+} while (0)
+
+#undef SLIST_NEXT
+#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+#undef SLIST_REMOVE
+#define SLIST_REMOVE(head, elm, type, field) do { \
+ QMD_SAVELINK(oldnext, (elm)->field.sle_next); \
+ if (SLIST_FIRST((head)) == (elm)) { \
+ SLIST_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ struct type *curelm = SLIST_FIRST((head)); \
+ while (SLIST_NEXT(curelm, field) != (elm)) \
+ curelm = SLIST_NEXT(curelm, field); \
+ SLIST_REMOVE_AFTER(curelm, field); \
+ } \
+ TRASHIT(*oldnext); \
+} while (0)
+
+#undef SLIST_REMOVE_AFTER
+#define SLIST_REMOVE_AFTER(elm, field) do { \
+ SLIST_NEXT(elm, field) = \
+ SLIST_NEXT(SLIST_NEXT(elm, field), field); \
+} while (0)
+
+#undef SLIST_REMOVE_HEAD
+#define SLIST_REMOVE_HEAD(head, field) do { \
+ SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
+} while (0)
+
+#undef SLIST_SWAP
+#define SLIST_SWAP(head1, head2, type) do { \
+ struct type *swap_first = SLIST_FIRST(head1); \
+ SLIST_FIRST(head1) = SLIST_FIRST(head2); \
+ SLIST_FIRST(head2) = swap_first; \
+} while (0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#undef STAILQ_HEAD
+#define STAILQ_HEAD(name, type) \
+struct name { \
+ struct type *stqh_first;/* first element */ \
+ struct type **stqh_last;/* addr of last next element */ \
+}
+
+#undef STAILQ_HEAD_INITIALIZER
+#define STAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).stqh_first }
+
+#undef STAILQ_ENTRY
+#define STAILQ_ENTRY(type) \
+struct { \
+ struct type *stqe_next; /* next element */ \
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#undef STAILQ_CONCAT
+#define STAILQ_CONCAT(head1, head2) do { \
+ if (!STAILQ_EMPTY((head2))) { \
+ *(head1)->stqh_last = (head2)->stqh_first; \
+ (head1)->stqh_last = (head2)->stqh_last; \
+ STAILQ_INIT((head2)); \
+ } \
+} while (0)
+
+#undef STAILQ_EMPTY
+#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
+
+#undef STAILQ_FIRST
+#define STAILQ_FIRST(head) ((head)->stqh_first)
+
+#undef STAILQ_FOREACH
+#define STAILQ_FOREACH(var, head, field) \
+ for ((var) = STAILQ_FIRST((head)); \
+ (var); \
+ (var) = STAILQ_NEXT((var), field))
+
+#undef STAILQ_FOREACH_FROM
+#define STAILQ_FOREACH_FROM(var, head, field) \
+ for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \
+ (var); \
+ (var) = STAILQ_NEXT((var), field))
+
+#undef STAILQ_FOREACH_SAFE
+#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = STAILQ_FIRST((head)); \
+ (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#undef STAILQ_FOREACH_FROM_SAFE
+#define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \
+ for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \
+ (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#undef STAILQ_INIT
+#define STAILQ_INIT(head) do { \
+ STAILQ_FIRST((head)) = NULL; \
+ (head)->stqh_last = &STAILQ_FIRST((head)); \
+} while (0)
+
+#undef STAILQ_INSERT_AFTER
+#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
+ if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
+ STAILQ_NEXT((tqelm), field) = (elm); \
+} while (0)
+
+#undef STAILQ_INSERT_HEAD
+#define STAILQ_INSERT_HEAD(head, elm, field) do { \
+ if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
+ STAILQ_FIRST((head)) = (elm); \
+} while (0)
+
+#undef STAILQ_INSERT_TAIL
+#define STAILQ_INSERT_TAIL(head, elm, field) do { \
+ STAILQ_NEXT((elm), field) = NULL; \
+ *(head)->stqh_last = (elm); \
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
+} while (0)
+
+#undef STAILQ_LAST
+#define STAILQ_LAST(head, type, field) \
+ (STAILQ_EMPTY((head)) ? NULL : \
+ __containerof((head)->stqh_last, struct type, field.stqe_next))
+
+#undef STAILQ_NEXT
+#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
+
+#undef STAILQ_REMOVE
+#define STAILQ_REMOVE(head, elm, type, field) do { \
+ QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \
+ if (STAILQ_FIRST((head)) == (elm)) { \
+ STAILQ_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ struct type *curelm = STAILQ_FIRST((head)); \
+ while (STAILQ_NEXT(curelm, field) != (elm)) \
+ curelm = STAILQ_NEXT(curelm, field); \
+ STAILQ_REMOVE_AFTER(head, curelm, field); \
+ } \
+ TRASHIT(*oldnext); \
+} while (0)
+
+#undef STAILQ_REMOVE_AFTER
+#define STAILQ_REMOVE_AFTER(head, elm, field) do { \
+ if ((STAILQ_NEXT(elm, field) = \
+ STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
+ (head)->stqh_last = &STAILQ_NEXT((elm), field); \
+} while (0)
+
+#undef STAILQ_REMOVE_HEAD
+#define STAILQ_REMOVE_HEAD(head, field) do { \
+ if ((STAILQ_FIRST((head)) = \
+ STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
+ (head)->stqh_last = &STAILQ_FIRST((head)); \
+} while (0)
+
+#undef STAILQ_SWAP
+#define STAILQ_SWAP(head1, head2, type) do { \
+ struct type *swap_first = STAILQ_FIRST(head1); \
+ struct type **swap_last = (head1)->stqh_last; \
+ STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \
+ (head1)->stqh_last = (head2)->stqh_last; \
+ STAILQ_FIRST(head2) = swap_first; \
+ (head2)->stqh_last = swap_last; \
+ if (STAILQ_EMPTY(head1)) \
+ (head1)->stqh_last = &STAILQ_FIRST(head1); \
+ if (STAILQ_EMPTY(head2)) \
+ (head2)->stqh_last = &STAILQ_FIRST(head2); \
+} while (0)
+
+
+/*
+ * List declarations.
+ */
+#undef LIST_HEAD
+#define LIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#undef LIST_HEAD_INITIALIZER
+#define LIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#undef LIST_ENTRY
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+/*
+ * List functions.
+ */
+#undef LIST_EMPTY
+#define LIST_EMPTY(head) ((head)->lh_first == NULL)
+
+#undef LIST_FIRST
+#define LIST_FIRST(head) ((head)->lh_first)
+
+#undef LIST_FOREACH
+#define LIST_FOREACH(var, head, field) \
+ for ((var) = LIST_FIRST((head)); \
+ (var); \
+ (var) = LIST_NEXT((var), field))
+
+#undef LIST_FOREACH_FROM
+#define LIST_FOREACH_FROM(var, head, field) \
+ for ((var) = ((var) ? (var) : LIST_FIRST((head))); \
+ (var); \
+ (var) = LIST_NEXT((var), field))
+
+#undef LIST_FOREACH_SAFE
+#define LIST_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = LIST_FIRST((head)); \
+ (var) && ((tvar) = LIST_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#undef LIST_FOREACH_FROM_SAFE
+#define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \
+ for ((var) = ((var) ? (var) : LIST_FIRST((head))); \
+ (var) && ((tvar) = LIST_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#undef LIST_INIT
+#define LIST_INIT(head) do { \
+ LIST_FIRST((head)) = NULL; \
+} while (0)
+
+#undef LIST_INSERT_AFTER
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+ if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
+ LIST_NEXT((listelm), field)->field.le_prev = \
+ &LIST_NEXT((elm), field); \
+ LIST_NEXT((listelm), field) = (elm); \
+ (elm)->field.le_prev = &LIST_NEXT((listelm), field); \
+} while (0)
+
+#undef LIST_INSERT_BEFORE
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ LIST_NEXT((elm), field) = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &LIST_NEXT((elm), field); \
+} while (0)
+
+#undef LIST_INSERT_HEAD
+#define LIST_INSERT_HEAD(head, elm, field) do { \
+ if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
+ LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
+ LIST_FIRST((head)) = (elm); \
+ (elm)->field.le_prev = &LIST_FIRST((head)); \
+} while (0)
+
+#undef LIST_NEXT
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+#undef LIST_PREV
+#define LIST_PREV(elm, head, type, field) \
+ ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \
+ __containerof((elm)->field.le_prev, struct type, field.le_next))
+
+#undef LIST_REMOVE
+#define LIST_REMOVE(elm, field) do { \
+ ANALYZER_ASSERT(elm != NULL); \
+ QMD_SAVELINK(oldnext, (elm)->field.le_next); \
+ QMD_SAVELINK(oldprev, (elm)->field.le_prev); \
+ if (LIST_NEXT((elm), field) != NULL) \
+ LIST_NEXT((elm), field)->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = LIST_NEXT((elm), field); \
+ TRASHIT(*oldnext); \
+ TRASHIT(*oldprev); \
+} while (0)
+
+#undef LIST_SWAP
+#define LIST_SWAP(head1, head2, type, field) do { \
+ struct type *swap_tmp = LIST_FIRST((head1)); \
+ LIST_FIRST((head1)) = LIST_FIRST((head2)); \
+ LIST_FIRST((head2)) = swap_tmp; \
+ if ((swap_tmp = LIST_FIRST((head1))) != NULL) \
+ swap_tmp->field.le_prev = &LIST_FIRST((head1)); \
+ if ((swap_tmp = LIST_FIRST((head2))) != NULL) \
+ swap_tmp->field.le_prev = &LIST_FIRST((head2)); \
+} while (0)
+
+/*
+ * Tail queue declarations.
+ */
+#undef TAILQ_HEAD
+#define TAILQ_HEAD(name, type) \
+struct name { \
+ struct type *tqh_first; /* first element */ \
+ struct type **tqh_last; /* addr of last next element */ \
+ TRACEBUF \
+}
+
+#undef TAILQ_HEAD_INITIALIZER
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
+
+#undef TAILQ_ENTRY
+#define TAILQ_ENTRY(type) \
+struct { \
+ struct type *tqe_next; /* next element */ \
+ struct type **tqe_prev; /* address of previous next element */ \
+ TRACEBUF \
+}
+
+/*
+ * Tail queue functions.
+ */
+#undef TAILQ_CONCAT
+#define TAILQ_CONCAT(head1, head2, field) do { \
+ if (!TAILQ_EMPTY(head2)) { \
+ *(head1)->tqh_last = (head2)->tqh_first; \
+ (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
+ (head1)->tqh_last = (head2)->tqh_last; \
+ TAILQ_INIT((head2)); \
+ QMD_TRACE_HEAD(head1); \
+ QMD_TRACE_HEAD(head2); \
+ } \
+} while (0)
+
+#undef TAILQ_EMPTY
+#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
+
+#undef TAILQ_FIRST
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+
+#undef TAILQ_FOREACH
+#define TAILQ_FOREACH(var, head, field) \
+ for ((var) = TAILQ_FIRST((head)); \
+ (var); \
+ (var) = TAILQ_NEXT((var), field))
+
+#undef TAILQ_FOREACH_FROM
+#define TAILQ_FOREACH_FROM(var, head, field) \
+ for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
+ (var); \
+ (var) = TAILQ_NEXT((var), field))
+
+#undef TAILQ_FOREACH_SAFE
+#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = TAILQ_FIRST((head)); \
+ (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#undef TAILQ_FOREACH_FROM_SAFE
+#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \
+ for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
+ (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#undef TAILQ_FOREACH_REVERSE
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = TAILQ_LAST((head), headname); \
+ (var); \
+ (var) = TAILQ_PREV((var), headname, field))
+
+#undef TAILQ_FOREACH_REVERSE_FROM
+#define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \
+ for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
+ (var); \
+ (var) = TAILQ_PREV((var), headname, field))
+
+#undef TAILQ_FOREACH_REVERSE_SAFE
+#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
+ for ((var) = TAILQ_LAST((head), headname); \
+ (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
+ (var) = (tvar))
+
+#undef TAILQ_FOREACH_REVERSE_FROM_SAFE
+#define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \
+ for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
+ (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
+ (var) = (tvar))
+
+#undef TAILQ_INIT
+#define TAILQ_INIT(head) do { \
+ TAILQ_FIRST((head)) = NULL; \
+ (head)->tqh_last = &TAILQ_FIRST((head)); \
+ QMD_TRACE_HEAD(head); \
+} while (0)
+
+#undef TAILQ_INSERT_AFTER
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
+ TAILQ_NEXT((elm), field)->field.tqe_prev = \
+ &TAILQ_NEXT((elm), field); \
+ else { \
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
+ QMD_TRACE_HEAD(head); \
+ } \
+ TAILQ_NEXT((listelm), field) = (elm); \
+ (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+ QMD_TRACE_ELEM(&listelm->field); \
+} while (0)
+
+#undef TAILQ_INSERT_BEFORE
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ TAILQ_NEXT((elm), field) = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+ QMD_TRACE_ELEM(&listelm->field); \
+} while (0)
+
+#undef TAILQ_INSERT_HEAD
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
+ TAILQ_FIRST((head))->field.tqe_prev = \
+ &TAILQ_NEXT((elm), field); \
+ else \
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
+ TAILQ_FIRST((head)) = (elm); \
+ (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
+ QMD_TRACE_HEAD(head); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+} while (0)
+
+#undef TAILQ_INSERT_TAIL
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ TAILQ_NEXT((elm), field) = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
+ QMD_TRACE_HEAD(head); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+} while (0)
+
+#undef TAILQ_LAST
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#undef TAILQ_NEXT
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#undef TAILQ_PREV
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#undef TAILQ_REMOVE
+#define TAILQ_REMOVE(head, elm, field) do { \
+ ANALYZER_ASSERT(elm != NULL); \
+ QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \
+ QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \
+ if ((TAILQ_NEXT((elm), field)) != NULL) \
+ TAILQ_NEXT((elm), field)->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else { \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ QMD_TRACE_HEAD(head); \
+ } \
+ *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
+ TRASHIT(*oldnext); \
+ TRASHIT(*oldprev); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+} while (0)
+
+#undef TAILQ_SWAP
+#define TAILQ_SWAP(head1, head2, type, field) do { \
+ struct type *swap_first = (head1)->tqh_first; \
+ struct type **swap_last = (head1)->tqh_last; \
+ (head1)->tqh_first = (head2)->tqh_first; \
+ (head1)->tqh_last = (head2)->tqh_last; \
+ (head2)->tqh_first = swap_first; \
+ (head2)->tqh_last = swap_last; \
+ if ((swap_first = (head1)->tqh_first) != NULL) \
+ swap_first->field.tqe_prev = &(head1)->tqh_first; \
+ else \
+ (head1)->tqh_last = &(head1)->tqh_first; \
+ if ((swap_first = (head2)->tqh_first) != NULL) \
+ swap_first->field.tqe_prev = &(head2)->tqh_first; \
+ else \
+ (head2)->tqh_last = &(head2)->tqh_first; \
+} while (0)
+
+/*
+ * Headless Tail queue definitions.
+ */
+#undef HLTQ_ENTRY
+#define HLTQ_ENTRY(type) TAILQ_ENTRY(type)
+
+#undef HLTQ_INIT
+#define HLTQ_INIT(entry, field) do { \
+ (entry)->field.tqe_next = NULL; \
+ (entry)->field.tqe_prev = &(entry)->field.tqe_next; \
+} while (0)
+
+#undef HLTQ_INITIALIZER
+#define HLTQ_INITIALIZER(entry, field) \
+ { NULL, &(entry)->field.tqe_next }
+
+#undef HLTQ_FIRST
+#define HLTQ_FIRST(elm) (elm)
+
+#undef HLTQ_END
+#define HLTQ_END(elm) NULL
+
+#undef HLTQ_NEXT
+#define HLTQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#undef HLTQ_LAST
+#define HLTQ_LAST(elm, type, field) \
+ ((elm)->field.tqe_next == NULL ? (elm) : \
+ __containerof((elm)->field.tqe_prev, struct type, field.tqe_next))
+
+#undef HLTQ_PREV
+#define HLTQ_PREV(elm, type, field) \
+ (*(elm)->field.tqe_prev == NULL ? NULL : \
+ __containerof((elm)->field.tqe_prev, struct type, field.tqe_next))
+
+#undef HLTQ_FOREACH
+#define HLTQ_FOREACH(var, head, field) \
+ for ((var) = HLTQ_FIRST(head); \
+ (var) != HLTQ_END(head); \
+ (var) = HLTQ_NEXT(var, field))
+
+#undef HLTQ_FOREACH_SAFE
+#define HLTQ_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = HLTQ_FIRST(head); \
+ (var) != HLTQ_END(head) && \
+ ((tvar) = HLTQ_NEXT(var, field), 1); \
+ (var) = (tvar))
+
+#undef HLTQ_FOREACH_REVERSE
+#define HLTQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = HLTQ_LAST(head, headname); \
+ (var) != HLTQ_END(head); \
+ (var) = HLTQ_PREV(var, headname, field))
+
+#undef HLTQ_FOREACH_REVERSE_SAFE
+#define HLTQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
+ for ((var) = HLTQ_LAST(head, headname); \
+ (var) != HLTQ_END(head) && \
+ ((tvar) = HLTQ_PREV(var, headname, field), 1); \
+ (var) = (tvar))
+
+/* Concatenate queue2 to the end of queue1. */
+#undef HLTQ_CONCAT
+#define HLTQ_CONCAT(queue1, queue2, field) do { \
+ (queue2)->field.tqe_prev = (queue1)->field.tqe_prev; \
+ *(queue1)->field.tqe_prev = (queue2); \
+ (queue1)->field.tqe_prev = &(queue2)->field.tqe_next; \
+} while (0)
+
+/* Convert a headless tailq to a headful one. */
+#define HLTQ_TO_TAILQ(head, hl, field) do { \
+ (head)->tqh_first = (hl); \
+ (head)->tqh_last = (hl)->field.tqe_prev; \
+ (hl)->field.tqe_prev = &(head)->tqh_first; \
+} while (0)
+
+/* Concatenate a headless tail queue to the end of a regular tail queue. */
+#define TAILQ_CONCAT_HLTQ(head, hl, field) do { \
+ void *last = (hl)->field.tqe_prev; \
+ (hl)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (hl); \
+ (head)->tqh_last = last; \
+} while (0)
+
+#endif /* !SUDO_QUEUE_H */
diff --git a/include/sudo_rand.h b/include/sudo_rand.h
new file mode 100644
index 0000000..2e83085
--- /dev/null
+++ b/include/sudo_rand.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#ifndef SUDO_RAND_H
+#define SUDO_RAND_H
+
+#include <stdlib.h> /* For arc4random() on systems that have it */
+
+/*
+ * All libc replacements are prefixed with "sudo_" to avoid namespace issues.
+ */
+
+#ifndef HAVE_ARC4RANDOM
+/* Note: not exported by libutil. */
+uint32_t sudo_arc4random(void);
+# undef arc4random
+# define arc4random() sudo_arc4random()
+#endif /* ARC4RANDOM */
+
+#ifndef HAVE_ARC4RANDOM_UNIFORM
+__dso_public uint32_t sudo_arc4random_uniform(uint32_t upper_bound);
+# undef arc4random_uniform
+# define arc4random_uniform(_a) sudo_arc4random_uniform((_a))
+#endif /* ARC4RANDOM_UNIFORM */
+
+#ifndef HAVE_GETENTROPY
+/* Note: not exported by libutil. */
+int sudo_getentropy(void *buf, size_t buflen);
+# undef getentropy
+# define getentropy(_a, _b) sudo_getentropy((_a), (_b))
+#endif /* HAVE_GETENTROPY */
+
+#endif /* SUDO_RAND_H */
diff --git a/include/sudo_util.h b/include/sudo_util.h
new file mode 100644
index 0000000..96cac16
--- /dev/null
+++ b/include/sudo_util.h
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2013-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_UTIL_H
+#define SUDO_UTIL_H
+
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+
+#ifndef TIME_T_MAX
+# if SIZEOF_TIME_T == 8
+# define TIME_T_MAX LLONG_MAX
+# else
+# define TIME_T_MAX INT_MAX
+# endif
+#endif
+
+/*
+ * Macros for operating on struct timeval.
+ */
+#define sudo_timevalclear(tv) ((tv)->tv_sec = (tv)->tv_usec = 0)
+
+#define sudo_timevalisset(tv) ((tv)->tv_sec || (tv)->tv_usec)
+
+#define sudo_timevalcmp(tv1, tv2, op) \
+ (((tv1)->tv_sec == (tv2)->tv_sec) ? \
+ ((tv1)->tv_usec op (tv2)->tv_usec) : \
+ ((tv1)->tv_sec op (tv2)->tv_sec))
+
+#define sudo_timevaladd(tv1, tv2, tv3) \
+ do { \
+ (tv3)->tv_sec = (tv1)->tv_sec + (tv2)->tv_sec; \
+ (tv3)->tv_usec = (tv1)->tv_usec + (tv2)->tv_usec; \
+ if ((tv3)->tv_usec >= 1000000) { \
+ (tv3)->tv_sec++; \
+ (tv3)->tv_usec -= 1000000; \
+ } \
+ } while (0)
+
+#define sudo_timevalsub(tv1, tv2, tv3) \
+ do { \
+ (tv3)->tv_sec = (tv1)->tv_sec - (tv2)->tv_sec; \
+ (tv3)->tv_usec = (tv1)->tv_usec - (tv2)->tv_usec; \
+ if ((tv3)->tv_usec < 0) { \
+ (tv3)->tv_sec--; \
+ (tv3)->tv_usec += 1000000; \
+ } \
+ } while (0)
+
+#ifndef TIMEVAL_TO_TIMESPEC
+# define TIMEVAL_TO_TIMESPEC(tv, ts) \
+ do { \
+ (ts)->tv_sec = (tv)->tv_sec; \
+ (ts)->tv_nsec = (tv)->tv_usec * 1000; \
+ } while (0)
+#endif
+
+/*
+ * Macros for operating on struct timespec.
+ */
+#define sudo_timespecclear(ts) ((ts)->tv_sec = (ts)->tv_nsec = 0)
+
+#define sudo_timespecisset(ts) ((ts)->tv_sec || (ts)->tv_nsec)
+
+#define sudo_timespeccmp(ts1, ts2, op) \
+ (((ts1)->tv_sec == (ts2)->tv_sec) ? \
+ ((ts1)->tv_nsec op (ts2)->tv_nsec) : \
+ ((ts1)->tv_sec op (ts2)->tv_sec))
+
+#define sudo_timespecadd(ts1, ts2, ts3) \
+ do { \
+ (ts3)->tv_sec = (ts1)->tv_sec + (ts2)->tv_sec; \
+ (ts3)->tv_nsec = (ts1)->tv_nsec + (ts2)->tv_nsec; \
+ while ((ts3)->tv_nsec >= 1000000000) { \
+ (ts3)->tv_sec++; \
+ (ts3)->tv_nsec -= 1000000000; \
+ } \
+ } while (0)
+
+#define sudo_timespecsub(ts1, ts2, ts3) \
+ do { \
+ (ts3)->tv_sec = (ts1)->tv_sec - (ts2)->tv_sec; \
+ (ts3)->tv_nsec = (ts1)->tv_nsec - (ts2)->tv_nsec; \
+ while ((ts3)->tv_nsec < 0) { \
+ (ts3)->tv_sec--; \
+ (ts3)->tv_nsec += 1000000000; \
+ } \
+ } while (0)
+
+#ifndef TIMESPEC_TO_TIMEVAL
+# define TIMESPEC_TO_TIMEVAL(tv, ts) \
+ do { \
+ (tv)->tv_sec = (ts)->tv_sec; \
+ (tv)->tv_usec = (ts)->tv_nsec / 1000; \
+ } while (0)
+#endif
+
+/*
+ * The timespec version of st_mtime may vary on different platforms.
+ */
+#if defined(HAVE_ST_MTIM)
+# if defined(HAVE_ST__TIM)
+# define SUDO_ST_MTIM st_mtim.st__tim
+# else
+# define SUDO_ST_MTIM st_mtim
+# endif
+#elif defined(HAVE_ST_MTIMESPEC)
+# define SUDO_ST_MTIM st_mtimespec
+#endif
+
+/*
+ * Macro to extract mtime as timespec.
+ * If there is no way to set the timestamp using nanosecond precision,
+ * we only fetch microsecond precision. Otherwise there is a mismatch
+ * between the timestamp we read and the one we wrote.
+ */
+#if defined(SUDO_ST_MTIM)
+# if defined(HAVE_FUTIMENS) && defined(HAVE_UTIMENSAT)
+# define mtim_get(_x, _y) do { (_y).tv_sec = (_x)->SUDO_ST_MTIM.tv_sec; (_y).tv_nsec = (_x)->SUDO_ST_MTIM.tv_nsec; } while (0)
+# else
+# define mtim_get(_x, _y) do { (_y).tv_sec = (_x)->SUDO_ST_MTIM.tv_sec; (_y).tv_nsec = ((_x)->SUDO_ST_MTIM.tv_nsec / 1000) * 1000; } while (0)
+# endif
+#elif defined(HAVE_ST_NMTIME)
+# define mtim_get(_x, _y) do { (_y).tv_sec = (_x)->st_mtime; (_y).tv_nsec = (_x)->st_nmtime; } while (0)
+#else
+# define mtim_get(_x, _y) do { (_y).tv_sec = (_x)->st_mtime; (_y).tv_nsec = 0; } while (0)
+#endif /* HAVE_ST_MTIM */
+
+/* Bit map macros. */
+#define sudo_setbit(_a, _i) ((_a)[(_i) / NBBY] |= 1 << ((_i) % NBBY))
+#define sudo_clrbit(_a, _i) ((_a)[(_i) / NBBY] &= ~(1<<((_i) % NBBY)))
+#define sudo_isset(_a, _i) ((_a)[(_i) / NBBY] & (1<<((_i) % NBBY)))
+#define sudo_isclr(_a, _i) (((_a)[(_i) / NBBY] & (1<<((_i) % NBBY))) == 0)
+
+/* sudo_parseln() flags */
+#define PARSELN_COMM_BOL 0x01 /* comments only at begining of line */
+#define PARSELN_CONT_IGN 0x02 /* ignore line continuation char */
+
+/*
+ * Macros to quiet gcc's warn_unused_result attribute.
+ */
+#ifdef __GNUC__
+# define ignore_result(x) do { \
+ __typeof__(x) y = (x); \
+ (void)y; \
+} while(0)
+#else
+# define ignore_result(x) (void)(x)
+#endif
+
+/* aix.c */
+__dso_public int aix_getauthregistry_v1(char *user, char *saved_registry);
+#define aix_getauthregistry(_a, _b) aix_getauthregistry_v1((_a), (_b))
+__dso_public int aix_prep_user_v1(char *user, const char *tty);
+#define aix_prep_user(_a, _b) aix_prep_user_v1((_a), (_b))
+__dso_public int aix_restoreauthdb_v1(void);
+#define aix_restoreauthdb() aix_restoreauthdb_v1()
+__dso_public int aix_setauthdb_v1(char *user);
+__dso_public int aix_setauthdb_v2(char *user, char *registry);
+#define aix_setauthdb(_a, _b) aix_setauthdb_v2((_a), (_b))
+
+/* gethostname.c */
+__dso_public char *sudo_gethostname_v1(void);
+#define sudo_gethostname() sudo_gethostname_v1()
+
+/* gettime.c */
+__dso_public int sudo_gettime_awake_v1(struct timespec *ts);
+#define sudo_gettime_awake(_a) sudo_gettime_awake_v1((_a))
+__dso_public int sudo_gettime_mono_v1(struct timespec *ts);
+#define sudo_gettime_mono(_a) sudo_gettime_mono_v1((_a))
+__dso_public int sudo_gettime_real_v1(struct timespec *ts);
+#define sudo_gettime_real(_a) sudo_gettime_real_v1((_a))
+
+/* gidlist.c */
+__dso_public int sudo_parse_gids_v1(const char *gidstr, const gid_t *basegid, GETGROUPS_T **gidsp);
+#define sudo_parse_gids(_a, _b, _c) sudo_parse_gids_v1((_a), (_b), (_c))
+
+/* getgrouplist.c */
+__dso_public int sudo_getgrouplist2_v1(const char *name, gid_t basegid, GETGROUPS_T **groupsp, int *ngroupsp);
+#define sudo_getgrouplist2(_a, _b, _c, _d) sudo_getgrouplist2_v1((_a), (_b), (_c), (_d))
+
+/* key_val.c */
+__dso_public char *sudo_new_key_val_v1(const char *key, const char *value);
+#define sudo_new_key_val(_a, _b) sudo_new_key_val_v1((_a), (_b))
+
+/* locking.c */
+#define SUDO_LOCK 1 /* lock a file */
+#define SUDO_TLOCK 2 /* test & lock a file (non-blocking) */
+#define SUDO_UNLOCK 4 /* unlock a file */
+__dso_public bool sudo_lock_file_v1(int fd, int action);
+#define sudo_lock_file(_a, _b) sudo_lock_file_v1((_a), (_b))
+__dso_public bool sudo_lock_region_v1(int fd, int action, off_t len);
+#define sudo_lock_region(_a, _b, _c) sudo_lock_region_v1((_a), (_b), (_c))
+
+/* parseln.c */
+__dso_public ssize_t sudo_parseln_v1(char **buf, size_t *bufsize, unsigned int *lineno, FILE *fp);
+__dso_public ssize_t sudo_parseln_v2(char **buf, size_t *bufsize, unsigned int *lineno, FILE *fp, int flags);
+#define sudo_parseln(_a, _b, _c, _d, _e) sudo_parseln_v2((_a), (_b), (_c), (_d), (_e))
+
+/* progname.c */
+__dso_public void initprogname(const char *);
+
+/* secure_path.c */
+#define SUDO_PATH_SECURE 0
+#define SUDO_PATH_MISSING -1
+#define SUDO_PATH_BAD_TYPE -2
+#define SUDO_PATH_WRONG_OWNER -3
+#define SUDO_PATH_WORLD_WRITABLE -4
+#define SUDO_PATH_GROUP_WRITABLE -5
+struct stat;
+__dso_public int sudo_secure_dir_v1(const char *path, uid_t uid, gid_t gid, struct stat *sbp);
+#define sudo_secure_dir(_a, _b, _c, _d) sudo_secure_dir_v1((_a), (_b), (_c), (_d))
+__dso_public int sudo_secure_file_v1(const char *path, uid_t uid, gid_t gid, struct stat *sbp);
+#define sudo_secure_file(_a, _b, _c, _d) sudo_secure_file_v1((_a), (_b), (_c), (_d))
+
+/* setgroups.c */
+__dso_public int sudo_setgroups_v1(int ngids, const GETGROUPS_T *gids);
+#define sudo_setgroups(_a, _b) sudo_setgroups_v1((_a), (_b))
+
+/* strsplit.c */
+__dso_public const char *sudo_strsplit_v1(const char *str, const char *endstr, const char *sep, const char **last);
+#define sudo_strsplit(_a, _b, _c, _d) sudo_strsplit_v1(_a, _b, _c, _d)
+
+/* strtobool.c */
+__dso_public int sudo_strtobool_v1(const char *str);
+#define sudo_strtobool(_a) sudo_strtobool_v1((_a))
+
+/* strtoid.c */
+__dso_public id_t sudo_strtoid_v1(const char *str, const char *sep, char **endp, const char **errstr);
+#define sudo_strtoid(_a, _b, _c, _d) sudo_strtoid_v1((_a), (_b), (_c), (_d))
+
+/* strtomode.c */
+__dso_public int sudo_strtomode_v1(const char *cp, const char **errstr);
+#define sudo_strtomode(_a, _b) sudo_strtomode_v1((_a), (_b))
+
+/* sudo_printf.c */
+extern int (*sudo_printf)(int msg_type, const char *fmt, ...);
+
+/* term.c */
+__dso_public bool sudo_term_cbreak_v1(int fd);
+#define sudo_term_cbreak(_a) sudo_term_cbreak_v1((_a))
+__dso_public bool sudo_term_copy_v1(int src, int dst);
+#define sudo_term_copy(_a, _b) sudo_term_copy_v1((_a), (_b))
+__dso_public bool sudo_term_noecho_v1(int fd);
+#define sudo_term_noecho(_a) sudo_term_noecho_v1((_a))
+__dso_public bool sudo_term_raw_v1(int fd, int isig);
+#define sudo_term_raw(_a, _b) sudo_term_raw_v1((_a), (_b))
+__dso_public bool sudo_term_restore_v1(int fd, bool flush);
+#define sudo_term_restore(_a, _b) sudo_term_restore_v1((_a), (_b))
+
+/* ttyname_dev.c */
+__dso_public char *sudo_ttyname_dev_v1(dev_t tdev, char *name, size_t namelen);
+#define sudo_ttyname_dev(_a, _b, _c) sudo_ttyname_dev_v1((_a), (_b), (_c))
+
+/* ttysize.c */
+__dso_public void sudo_get_ttysize_v1(int *rowp, int *colp);
+#define sudo_get_ttysize(_a, _b) sudo_get_ttysize_v1((_a), (_b))
+
+#endif /* SUDO_UTIL_H */
diff --git a/indent.pro b/indent.pro
new file mode 100644
index 0000000..db27ed3
--- /dev/null
+++ b/indent.pro
@@ -0,0 +1,36 @@
+-br
+-cdb
+-ce
+-d0
+-di1
+-ei
+-i4
+-nlp
+-npcs
+-npsl
+-ps
+-sc
+-TYYSTYPE
+-TLIST
+-TLINK
+-Tu_char
+-Tu_short
+-Tu_int
+-Tu_long
+-Tushort
+-Tuint
+-Tdaddr_t
+-Tcaddr_t
+-Tino_t
+-Tswblk_t
+-Tsize_t
+-Ttime_t
+-Tdev_t
+-Toff_t
+-Tuid_t
+-Tgid_t
+-Tfixpt_t
+-Tkey_t
+-Tpaddr_t
+-Tfd_mask
+-Tfd_set
diff --git a/init.d/aix.sh.in b/init.d/aix.sh.in
new file mode 100644
index 0000000..3d11241
--- /dev/null
+++ b/init.d/aix.sh.in
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Simple AIX rc.d script to remove the sudo timestamp directory on boot.
+# This is needed because AIX does not have /var/run.
+# Install as /etc/rc.d/init.d/sudo with a link /etc/rc.d/rc2.d/S90sudo
+#
+
+PATH=/usr/sbin:/usr/bin:/sbin
+export PATH
+
+TSDIR="@rundir@/ts"
+rval=0
+
+case "$1" in
+start)
+ echo "Removing the $TSDIR directory"
+ rm -rf "$TSDIR"
+ ;;
+*)
+ echo "usage: $0 start"
+ rval=1
+ ;;
+esac
+
+exit $rval
diff --git a/init.d/hpux.sh.in b/init.d/hpux.sh.in
new file mode 100644
index 0000000..5a76bd2
--- /dev/null
+++ b/init.d/hpux.sh.in
@@ -0,0 +1,27 @@
+#!/sbin/sh
+#
+# Simple HP-UX init.d script to remove the sudo timestamp directory on boot.
+# This is needed because HP-UX does not clear /var/run on its own.
+# Install as /sbin/init.d/sudo with a link /sbin/rc2.d/S900sudo
+#
+
+PATH=/usr/sbin:/usr/bin:/sbin
+export PATH
+
+TSDIR="@rundir@/ts"
+rval=0
+
+case "$1" in
+start_msg)
+ echo "Removing the $TSDIR directory"
+ ;;
+start)
+ rm -rf "$TSDIR"
+ ;;
+*)
+ echo "usage: $0 {start|start_msg}"
+ rval=1
+ ;;
+esac
+
+exit $rval
diff --git a/init.d/sudo.conf.in b/init.d/sudo.conf.in
new file mode 100644
index 0000000..dfae56b
--- /dev/null
+++ b/init.d/sudo.conf.in
@@ -0,0 +1,6 @@
+# Create an empty sudo time stamp directory on OSes using systemd.
+# Sudo will create the directory itself but this can cause problems
+# on systems that have SELinux enabled since the directories will be
+# created with the user's security context.
+d @rundir@ 0711 root root
+D @rundir@/ts 0700 root root
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000..6944fba
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,239 @@
+#! /bin/sh
+
+## (From INN-1.4, written by Rich Salz)
+## $Revision$
+## A script to install files and directories.
+
+PROGNAME=`basename $0`
+
+## Paths to programs. CHOWN, STRIP and WHOAMI are checked below.
+CHOWN=chown
+CHGRP=chgrp
+CHMOD=chmod
+CP=cp
+LN=ln
+MKDIR=mkdir
+MV=mv
+RM=rm
+STRIP=strip
+WHOAMI="echo root"
+
+## Some systems don't support -x, so we have to use -f.
+for d in /sbin /etc /usr/sbin /usr/etc; do
+ if [ -f $d/chown ]; then
+ CHOWN=${d}/chown
+ break
+ fi
+done
+
+for d in /usr/bin /bin /usr/ucb /usr/bsd; do
+ if [ -f $d/whoami ]; then
+ WHOAMI=${d}/whoami
+ break
+ elif [ -f $d/id ]; then
+ WHOAMI=${d}/id | sed -n 's/^[^(]*(\([^)]*\)).*/\1/p'
+ fi
+done
+
+for d in /usr/ccs/bin /usr/bin /bin; do
+ if [ -f $d/strip ]; then
+ STRIP=${d}/strip
+ break
+ fi
+done
+
+## Defaults.
+CHOWNIT=false
+CHGROUPIT=false
+CHMODIT=false
+STRIPIT=false
+BACKIT=false
+TOUCHIT=true
+DIRMODE=false
+
+# INSTALL_BACKUP is like -b but for use with libtool
+if test X"${INSTALL_BACKUP}" != X""; then
+ BACKIT=true
+ BACKUP="${INSTALL_BACKUP}"
+fi
+
+case `${WHOAMI}` in
+root)
+ ROOT=true
+ ;;
+*)
+ ROOT=false
+ ;;
+esac
+
+## Process JCL.
+MORETODO=true
+while ${MORETODO} ; do
+ case X"$1" in
+ X-b)
+ BACKIT=true
+ BACKUP="$2"
+ shift
+ ;;
+ X-b*)
+ BACKIT=true
+ BACKUP="`echo \"$1\" | sed 's/^..//'`"
+ ;;
+ X-c)
+ # backwards compatibility
+ ;;
+ X-d)
+ DIRMODE=true
+ ;;
+ X-g)
+ GROUP="$2"
+ CHGROUPIT=true
+ shift
+ ;;
+ X-g*)
+ GROUP="`echo \"$1\" | sed 's/^..//'`"
+ CHGROUPIT=true
+ ;;
+ X-G)
+ GROUP="$2"
+ shift
+ ${ROOT} && CHGROUPIT=true
+ ;;
+ X-G*)
+ if ${ROOT} ; then
+ GROUP="`echo \"$1\" | sed 's/^..//'`"
+ CHGROUPIT=true
+ fi
+ ;;
+ X-m)
+ MODE="$2"
+ CHMODIT=true
+ shift
+ ;;
+ X-m*)
+ MODE="`echo \"$1\" | sed 's/^..//'`"
+ CHMODIT=true
+ ;;
+ X-M)
+ MODE="$2"
+ ${ROOT} && CHMODIT=true
+ shift
+ ;;
+ X-M*)
+ MODE="`echo \"$1\" | sed 's/^..//'`"
+ ${ROOT} && CHMODIT=true
+ ;;
+ X-n)
+ TOUCHIT=false
+ ;;
+ X-o)
+ OWNER="$2"
+ CHOWNIT=true
+ shift
+ ;;
+ X-o*)
+ OWNER="`echo \"$1\" | sed 's/^..//'`"
+ CHOWNIT=true
+ ;;
+ X-O)
+ OWNER="$2"
+ shift
+ ${ROOT} && CHOWNIT=true
+ ;;
+ X-O*)
+ if ${ROOT} ; then
+ OWNER="`echo \"$1\" | sed 's/^..//'`"
+ CHOWNIT=true
+ fi
+ ;;
+ X-s)
+ STRIPIT=true
+ ;;
+ X--)
+ shift
+ MORETODO=false
+ ;;
+ X-*)
+ echo "${PROGNAME}: Unknown flag $1" 1>&2
+ exit 1
+ ;;
+ *)
+ MORETODO=false
+ ;;
+ esac
+ ${MORETODO} && shift
+done
+
+## Making a directory?
+if ${DIRMODE} ; then
+ while test $# != 0; do
+ DEST="$1"
+ if [ ! -d "${DEST}" ] ; then
+ ${MKDIR} "${DEST}" || exit 1
+ fi
+ if ${CHOWNIT} ; then
+ ${CHOWN} "${OWNER}" "${DEST}" || exit 1
+ fi
+ if ${CHGROUPIT} ; then
+ ${CHGRP} "${GROUP}" "${DEST}" || exit 1
+ fi
+ if ${CHMODIT} ; then
+ ${CHMOD} "${MODE}" "${DEST}" || exit 1
+ fi
+ shift;
+ done
+ exit 0
+fi
+
+## Process arguments.
+if [ $# -ne 2 ] ; then
+ echo "Usage: ${PROGNAME} [flags] source destination"
+ exit 1
+fi
+
+## Get the destination and a temp file in the destination diretory.
+if [ -d "$2" ] ; then
+ DEST="$2/`basename $1`"
+ TEMP="$2/$$.tmp"
+else
+ DEST="$2"
+ TEMP="`expr "$2" : '\(.*\)/.*'`/$$.tmp"
+fi
+
+## If not given the same name, we must try to copy.
+if [ X"$1" != X"$2" ] ; then
+ if cmp -s "$1" "${DEST}" ; then
+ ## Files are same; touch or not.
+ ${TOUCHIT} && touch "${DEST}"
+ else
+ ## If destination exists and we wish to backup, link to backup.
+ if [ -f "${DEST}" ] ; then
+ if ${BACKIT} ; then
+ ${RM} -f "${DEST}${BACKUP}"
+ ${LN} "${DEST}" "${DEST}${BACKUP}"
+ fi
+ fi
+ ## Copy source to the right dir, then move to right spot.
+ ## Done in two parts so we can hope for atomicity.
+ ## We need to rm DEST due to bugs in "mv -f" on some systems.
+ ${RM} -f "${TEMP}" || exit 1
+ ${CP} "$1" "${TEMP}" || exit 1
+ ${RM} -f "${DEST}" || exit 1
+ ${MV} -f "${TEMP}" "${DEST}" || exit 1
+ fi
+fi
+
+## Strip and set the owner/mode.
+if ${STRIPIT} ; then
+ ${STRIP} "${DEST}" || exit 1
+fi
+if ${CHOWNIT} ; then
+ ${CHOWN} "${OWNER}" "${DEST}" || exit 1
+fi
+if ${CHGROUPIT} ; then
+ ${CHGRP} "${GROUP}" "${DEST}" || exit 1
+fi
+if ${CHMODIT} ; then
+ ${CHMOD} "${MODE}" "${DEST}" || exit 1
+fi
+exit 0
diff --git a/lib/util/Makefile.in b/lib/util/Makefile.in
new file mode 100644
index 0000000..cadfcf2
--- /dev/null
+++ b/lib/util/Makefile.in
@@ -0,0 +1,1120 @@
+#
+# Copyright (c) 2011-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# @configure_input@
+#
+
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+devdir = @devdir@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+incdir = $(top_srcdir)/include
+cross_compiling = @CROSS_COMPILING@
+
+# Where to install things...
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+localstatedir = @localstatedir@
+
+# File extension, mode and map file to use for shared libraries/objects
+shlib_enable = @SHLIB_ENABLE@
+shlib_mode = @SHLIB_MODE@
+shlib_exp = ./util.exp
+shlib_map = util.map
+shlib_opt = util.opt
+
+# Compiler & tools to use
+CC = @CC@
+LIBTOOL = @LIBTOOL@
+SED = @SED@
+AWK = @AWK@
+
+# Our install program supports extra flags...
+INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
+INSTALL_OWNER = -o $(install_uid) -g $(install_gid)
+INSTALL_BACKUP = @INSTALL_BACKUP@
+
+# C preprocessor defines
+CPPDEFS = -D_PATH_SUDO_CONF=\"$(sysconfdir)/sudo.conf\"
+
+# C preprocessor flags
+CPPFLAGS = -I$(incdir) -I$(top_builddir) -I$(srcdir) -I$(top_srcdir) $(CPPDEFS) @CPPFLAGS@
+
+# Usually -O and/or -g
+CFLAGS = @CFLAGS@
+
+# Flags to pass to the link stage
+LDFLAGS = @LDFLAGS@
+LT_LDFLAGS = @LIBUTIL_LDFLAGS@ @LT_LDFLAGS@ @LT_LDEXPORTS@
+
+# Flags to pass to libtool
+LTFLAGS = @LT_STATIC@
+
+# Address sanitizer flags
+ASAN_CFLAGS = @ASAN_CFLAGS@
+ASAN_LDFLAGS = @ASAN_LDFLAGS@
+
+# PIE flags
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+
+# Stack smashing protection flags
+SSP_CFLAGS = @SSP_CFLAGS@
+SSP_LDFLAGS = @SSP_LDFLAGS@
+
+# Libtool style shared library version
+SHLIB_VERSION = 0:0:0
+
+# cppcheck options, usually set in the top-level Makefile
+CPPCHECK_OPTS = -q --force --enable=warning,performance,portability --suppress=constStatement --error-exitcode=1 --inline-suppr -Dva_copy=va_copy -U__cplusplus -UQUAD_MAX -UQUAD_MIN -UUQUAD_MAX -U_POSIX_HOST_NAME_MAX -U_POSIX_PATH_MAX -U__NBBY -DNSIG=64
+
+# splint options, usually set in the top-level Makefile
+SPLINT_OPTS = -D__restrict= -checks
+
+# PVS-studio options
+PVS_CFG = $(top_srcdir)/PVS-Studio.cfg
+PVS_IGNORE = 'V707,V011,V002,V536'
+PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE)
+
+# Regression tests
+TEST_PROGS = atofoo_test conf_test hltq_test parseln_test progname_test \
+ strsplit_test parse_gids_test getgrouplist_test @COMPAT_TEST_PROGS@
+TEST_LIBS = @LIBS@
+TEST_LDFLAGS = @LDFLAGS@
+
+# User and group ids the installed files should be "owned" by
+install_uid = 0
+install_gid = 0
+
+# Set to non-empty for development mode
+DEVEL = @DEVEL@
+
+#### End of system configuration section. ####
+
+SHELL = @SHELL@
+
+LTOBJS = @DIGEST@ event.lo fatal.lo key_val.lo gethostname.lo gettime.lo \
+ getgrouplist.lo gidlist.lo lbuf.lo locking.lo parseln.lo progname.lo \
+ secure_path.lo setgroups.lo strsplit.lo strtobool.lo strtoid.lo \
+ strtomode.lo sudo_conf.lo sudo_debug.lo sudo_dso.lo term.lo \
+ ttyname_dev.lo ttysize.lo @COMMON_OBJS@ @LTLIBOBJS@
+
+IOBJS = $(LTOBJS:.lo=.i)
+
+POBJS = $(IOBJS:.i=.plog)
+
+ATOFOO_TEST_OBJS = atofoo_test.lo
+
+MKTEMP_TEST_OBJS = mktemp_test.lo
+
+PARSELN_TEST_OBJS = parseln_test.lo
+
+PROGNAME_TEST_OBJS = progname_test.lo progname.lo
+
+CONF_TEST_OBJS = conf_test.lo
+
+HLTQ_TEST_OBJS = hltq_test.lo
+
+FNM_TEST_OBJS = fnm_test.lo
+
+GLOBTEST_OBJS = globtest.lo
+
+STRSPLIT_TEST_OBJS = strsplit_test.lo
+
+PARSE_GIDS_TEST_OBJS = parse_gids_test.lo
+
+GETGROUPLIST_TEST_OBJS = getgrouplist_test.lo
+
+VSYSLOG_TEST_OBJS = vsyslog_test.lo vsyslog.lo
+
+all: libsudo_util.la
+
+pvs-log-files: $(POBJS)
+
+pvs-studio: $(POBJS)
+ plog-converter $(PVS_LOG_OPTS) $(POBJS)
+
+Makefile: $(srcdir)/Makefile.in
+ cd $(top_builddir) && ./config.status --file lib/util/Makefile
+
+.SUFFIXES: .c .h .i .lo .plog
+
+.c.lo:
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $<
+
+.c.i:
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+
+.i.plog:
+ ifile=$<; rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $${ifile%i}c --i-file $< --output-file $@
+
+$(shlib_map): $(shlib_exp)
+ @$(AWK) 'BEGIN { print "{\n\tglobal:" } { print "\t\t"$$0";" } END { print "\tlocal:\n\t\t*;\n};" }' $(shlib_exp) > $@
+
+$(shlib_opt): $(shlib_exp)
+ @$(SED) 's/^/+e /' $(shlib_exp) > $@
+
+libsudo_util.la: $(LTOBJS) @LT_LDDEP@
+ case "$(LT_LDFLAGS)" in \
+ *-no-install*) \
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(LDFLAGS) $(LT_LDFLAGS) $(LTOBJS) @LIBINTL@ @LIBMD@ @LIBPTHREAD@ @LIBDL@ @LIBRT@;; \
+ *) \
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(LDFLAGS) $(ASAN_LDFLAGS) $(SSP_LDFLAGS) $(LT_LDFLAGS) $(LTOBJS) -version-info $(SHLIB_VERSION) -rpath $(libexecdir)/sudo @LT_DEP_LIBS@ @LIBINTL@ @LIBMD@ @LIBPTHREAD@ @LIBDL@ @LIBRT@;; \
+ esac
+
+siglist.c: mksiglist
+ ./mksiglist > $@
+
+signame.c: mksigname
+ ./mksigname > $@
+
+mksiglist: $(srcdir)/mksiglist.c $(srcdir)/mksiglist.h $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(srcdir)/mksiglist.c -o $@
+
+mksigname: $(srcdir)/mksigname.c $(srcdir)/mksigname.h $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(srcdir)/mksigname.c -o $@
+
+$(srcdir)/mksiglist.h: $(srcdir)/siglist.in
+ @if [ -n "$(DEVEL)" ]; then \
+ $(AWK) 'BEGIN {print "/* public domain */\n"} /^ [A-Z]/ {printf("#ifdef SIG%s\n if (sudo_sys_siglist[SIG%s] == NULL)\n\tsudo_sys_siglist[SIG%s] = \"%s\";\n#endif\n", $$1, $$1, $$1, substr($$0, 13))}' < $(srcdir)/siglist.in > $@; \
+ fi
+
+$(srcdir)/mksigname.h: $(srcdir)/siglist.in
+ @if [ -n "$(DEVEL)" ]; then \
+ $(AWK) 'BEGIN {print "/* public domain */\n"} /^ [A-Z]/ {printf("#ifdef SIG%s\n if (sudo_sys_signame[SIG%s] == NULL)\n\tsudo_sys_signame[SIG%s] = \"%s\";\n#endif\n", $$1, $$1, $$1, $$1)}' < $(srcdir)/siglist.in > $@; \
+ fi
+
+atofoo_test: $(ATOFOO_TEST_OBJS) libsudo_util.la
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(ATOFOO_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
+
+conf_test: $(CONF_TEST_OBJS) libsudo_util.la
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CONF_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
+
+fnm_test: $(FNM_TEST_OBJS) libsudo_util.la
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(FNM_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
+
+globtest: $(GLOBTEST_OBJS) libsudo_util.la
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(GLOBTEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
+
+hltq_test: $(HLTQ_TEST_OBJS) libsudo_util.la
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(HLTQ_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
+
+mktemp_test: $(MKTEMP_TEST_OBJS) libsudo_util.la
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(MKTEMP_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
+
+parseln_test: $(PARSELN_TEST_OBJS) libsudo_util.la
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(PARSELN_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
+
+progname_test: $(PROGNAME_TEST_OBJS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(PROGNAME_TEST_OBJS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
+
+parse_gids_test: $(PARSE_GIDS_TEST_OBJS) libsudo_util.la
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(PARSE_GIDS_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
+
+getgrouplist_test: $(GETGROUPLIST_TEST_OBJS) libsudo_util.la
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(GETGROUPLIST_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
+
+strsplit_test: $(STRSPLIT_TEST_OBJS) libsudo_util.la
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(STRSPLIT_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
+
+vsyslog_test: $(VSYSLOG_TEST_OBJS) libsudo_util.la
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(VSYSLOG_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
+
+pre-install:
+
+install: install-dirs
+ case "$(LT_LDFLAGS)" in \
+ *-no-install*) ;; \
+ *) if [ X"$(shlib_enable)" = X"yes" ]; then \
+ INSTALL_BACKUP='$(INSTALL_BACKUP)' $(LIBTOOL) $(LTFLAGS) --quiet --mode=install $(INSTALL) $(INSTALL_OWNER) libsudo_util.la $(DESTDIR)$(libexecdir)/sudo; \
+ fi;; \
+ esac
+
+install-dirs:
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(libexecdir)/sudo
+
+install-binaries:
+
+install-includes:
+
+install-doc:
+
+install-plugin:
+
+uninstall:
+ $(LIBTOOL) $(LTFLAGS) --mode=uninstall rm -f $(DESTDIR)$(libexecdir)/sudo/libsudo_util.la
+ -test -z "$(INSTALL_BACKUP)" || \
+ rf -f $(DESTDIR)$(libexecdir)/sudo/libsudo_util.*~
+
+splint:
+ splint $(SPLINT_OPTS) -I$(incdir) -I$(top_builddir) -I$(top_srcdir) $(srcdir)/*.c
+
+cppcheck:
+ cppcheck $(CPPCHECK_OPTS) -I$(incdir) -I$(top_builddir) -I$(top_srcdir) $(srcdir)/*.c
+
+pvs-log-files: $(POBJS)
+
+# Note: some regress checks are run from srcdir for consistent error messages
+check: $(TEST_PROGS)
+ @if test X"$(cross_compiling)" != X"yes"; then \
+ rval=0; \
+ if test -f parse_gids_test; then \
+ ./parse_gids_test || rval=`expr $$rval + $$?`; \
+ fi; \
+ if test -f strsplit_test; then \
+ ./strsplit_test || rval=`expr $$rval + $$?`; \
+ fi; \
+ if test -f fnm_test; then \
+ ./fnm_test $(srcdir)/regress/fnmatch/fnm_test.in || rval=`expr $$rval + $$?`; \
+ fi; \
+ if test -f globtest; then \
+ mkdir -p `$(SED) 's@/[^/]*$$@@' $(srcdir)/regress/glob/files | sort -u`; \
+ touch `cat $(srcdir)/regress/glob/files`; \
+ chmod 0755 `grep '/r[^/]*$$' $(srcdir)/regress/glob/files`; \
+ chmod 0444 `grep '/s[^/]*$$' $(srcdir)/regress/glob/files`; \
+ chmod 0711 `grep '/t[^/]*$$' $(srcdir)/regress/glob/files`; \
+ ./globtest $(srcdir)/regress/glob/globtest.in || rval=`expr $$rval + $$?`; \
+ rm -rf fake; \
+ fi; \
+ if test -f mktemp_test; then \
+ ./mktemp_test || rval=`expr $$rval + $$?`; \
+ fi; \
+ ./getgrouplist_test || rval=`expr $$rval + $$?`; \
+ ./atofoo_test || rval=`expr $$rval + $$?`; \
+ ./hltq_test || rval=`expr $$rval + $$?`; \
+ ./progname_test || rval=`expr $$rval + $$?`; \
+ rm -f ./progname_test2; ln -s ./progname_test ./progname_test2; \
+ ./progname_test2 || rval=`expr $$rval + $$?`; \
+ rm -f ./progname_test2; \
+ if test -f vsyslog_test; then \
+ ./vsyslog_test || rval=`expr $$rval + $$?`; \
+ fi; \
+ build_dir=`pwd`; \
+ cd $(srcdir); \
+ for dir in sudo_conf sudo_parseln; do \
+ passed=0; failed=0; total=0; \
+ mkdir -p $$build_dir/regress/$$dir; \
+ for t in regress/$$dir/*.in; do \
+ base=`basename $$t .in`; \
+ out="$$build_dir/regress/$$dir/$${base}.out"; \
+ out_ok="regress/$$dir/$${base}.out.ok"; \
+ err="$$build_dir/regress/$$dir/$${base}.err"; \
+ err_ok="regress/$$dir/$${base}.err.ok"; \
+ if test "$$dir" = "sudo_conf"; then \
+ $$build_dir/conf_test $$t >$$out 2>$$err; \
+ else \
+ $$build_dir/parseln_test <$$t >$$out 2>$$err; \
+ fi; \
+ if cmp $$out $$out_ok >/dev/null; then \
+ passed=`expr $$passed + 1`; \
+ echo "$$dir/$$base: OK"; \
+ else \
+ failed=`expr $$failed + 1`; \
+ echo "$$dir/$$base: FAIL"; \
+ diff $$out $$out_ok || true; \
+ fi; \
+ total=`expr $$total + 1`; \
+ if test -s $$err_ok; then \
+ if cmp $$err $$err_ok >/dev/null; then \
+ passed=`expr $$passed + 1`; \
+ echo "$$dir/$$base (stderr): OK"; \
+ else \
+ failed=`expr $$failed + 1`; \
+ echo "$$dir/$$base (stderr): FAIL"; \
+ diff $$err $$err_ok || true; \
+ fi; \
+ total=`expr $$total + 1`; \
+ elif test -s $$err; then \
+ failed=`expr $$failed + 1`; \
+ echo "$$dir/$$base (stderr): FAIL"; \
+ cat $$err 1>&2; \
+ fi; \
+ done; \
+ if test $$failed -ne 0; then \
+ rval=`expr $$rval + $$failed`; \
+ fi; \
+ echo "$$dir: $$passed/$$total tests passed; $$failed/$$total tests failed"; \
+ done; \
+ exit $$rval; \
+ fi
+
+clean:
+ -$(LIBTOOL) $(LTFLAGS) --mode=clean rm -f $(TEST_PROGS) *.lo *.o \
+ *.la *.a *.i *.plog stamp-* core *.core core.* regress/*/*.out \
+ regress/*/*.err
+
+mostlyclean: clean
+
+distclean: clean
+ -rm -rf Makefile mksiglist siglist.c mksigname signame.c .libs \
+ $(shlib_exp) $(shlib_map) $(shlib_opt)
+
+clobber: distclean
+
+realclean: distclean
+ rm -f TAGS tags
+
+cleandir: realclean
+
+# Autogenerated dependencies, do not modify
+aix.lo: $(srcdir)/aix.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/aix.c
+aix.i: $(srcdir)/aix.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+aix.plog: aix.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/aix.c --i-file $< --output-file $@
+arc4random.lo: $(srcdir)/arc4random.c $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_rand.h $(srcdir)/arc4random.h \
+ $(srcdir)/chacha_private.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/arc4random.c
+arc4random.i: $(srcdir)/arc4random.c $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_rand.h $(srcdir)/arc4random.h \
+ $(srcdir)/chacha_private.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+arc4random.plog: arc4random.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/arc4random.c --i-file $< --output-file $@
+arc4random_uniform.lo: $(srcdir)/arc4random_uniform.c $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_rand.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/arc4random_uniform.c
+arc4random_uniform.i: $(srcdir)/arc4random_uniform.c $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_rand.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+arc4random_uniform.plog: arc4random_uniform.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/arc4random_uniform.c --i-file $< --output-file $@
+atofoo_test.lo: $(srcdir)/regress/atofoo/atofoo_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/atofoo/atofoo_test.c
+atofoo_test.i: $(srcdir)/regress/atofoo/atofoo_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+atofoo_test.plog: atofoo_test.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/atofoo/atofoo_test.c --i-file $< --output-file $@
+closefrom.lo: $(srcdir)/closefrom.c $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/closefrom.c
+closefrom.i: $(srcdir)/closefrom.c $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+closefrom.plog: closefrom.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/closefrom.c --i-file $< --output-file $@
+conf_test.lo: $(srcdir)/regress/sudo_conf/conf_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/sudo_conf/conf_test.c
+conf_test.i: $(srcdir)/regress/sudo_conf/conf_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+conf_test.plog: conf_test.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/sudo_conf/conf_test.c --i-file $< --output-file $@
+digest.lo: $(srcdir)/digest.c $(incdir)/compat/sha2.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_digest.h \
+ $(incdir)/sudo_queue.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/digest.c
+digest.i: $(srcdir)/digest.c $(incdir)/compat/sha2.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_digest.h \
+ $(incdir)/sudo_queue.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+digest.plog: digest.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/digest.c --i-file $< --output-file $@
+digest_gcrypt.lo: $(srcdir)/digest_gcrypt.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_queue.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/digest_gcrypt.c
+digest_gcrypt.i: $(srcdir)/digest_gcrypt.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_queue.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+digest_gcrypt.plog: digest_gcrypt.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/digest_gcrypt.c --i-file $< --output-file $@
+digest_openssl.lo: $(srcdir)/digest_openssl.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_queue.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/digest_openssl.c
+digest_openssl.i: $(srcdir)/digest_openssl.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_queue.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+digest_openssl.plog: digest_openssl.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/digest_openssl.c --i-file $< --output-file $@
+event.lo: $(srcdir)/event.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_event.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/event.c
+event.i: $(srcdir)/event.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_event.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+event.plog: event.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/event.c --i-file $< --output-file $@
+event_poll.lo: $(srcdir)/event_poll.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_event.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/event_poll.c
+event_poll.i: $(srcdir)/event_poll.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_event.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+event_poll.plog: event_poll.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/event_poll.c --i-file $< --output-file $@
+event_select.lo: $(srcdir)/event_select.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_event.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/event_select.c
+event_select.i: $(srcdir)/event_select.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_event.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+event_select.plog: event_select.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/event_select.c --i-file $< --output-file $@
+fatal.lo: $(srcdir)/fatal.c $(incdir)/compat/getaddrinfo.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/fatal.c
+fatal.i: $(srcdir)/fatal.c $(incdir)/compat/getaddrinfo.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+fatal.plog: fatal.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/fatal.c --i-file $< --output-file $@
+fnm_test.lo: $(srcdir)/regress/fnmatch/fnm_test.c $(incdir)/compat/fnmatch.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/fnmatch/fnm_test.c
+fnm_test.i: $(srcdir)/regress/fnmatch/fnm_test.c $(incdir)/compat/fnmatch.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+fnm_test.plog: fnm_test.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/fnmatch/fnm_test.c --i-file $< --output-file $@
+fnmatch.lo: $(srcdir)/fnmatch.c $(incdir)/compat/charclass.h \
+ $(incdir)/compat/fnmatch.h $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/fnmatch.c
+fnmatch.i: $(srcdir)/fnmatch.c $(incdir)/compat/charclass.h \
+ $(incdir)/compat/fnmatch.h $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+fnmatch.plog: fnmatch.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/fnmatch.c --i-file $< --output-file $@
+getaddrinfo.lo: $(srcdir)/getaddrinfo.c $(incdir)/compat/getaddrinfo.h \
+ $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getaddrinfo.c
+getaddrinfo.i: $(srcdir)/getaddrinfo.c $(incdir)/compat/getaddrinfo.h \
+ $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+getaddrinfo.plog: getaddrinfo.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getaddrinfo.c --i-file $< --output-file $@
+getcwd.lo: $(srcdir)/getcwd.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getcwd.c
+getcwd.i: $(srcdir)/getcwd.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+getcwd.plog: getcwd.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getcwd.c --i-file $< --output-file $@
+getentropy.lo: $(srcdir)/getentropy.c $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_rand.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getentropy.c
+getentropy.i: $(srcdir)/getentropy.c $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_rand.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+getentropy.plog: getentropy.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getentropy.c --i-file $< --output-file $@
+getgrouplist.lo: $(srcdir)/getgrouplist.c $(incdir)/compat/nss_dbdefs.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getgrouplist.c
+getgrouplist.i: $(srcdir)/getgrouplist.c $(incdir)/compat/nss_dbdefs.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+getgrouplist.plog: getgrouplist.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getgrouplist.c --i-file $< --output-file $@
+getgrouplist_test.lo: $(srcdir)/regress/getgrouplist/getgrouplist_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/getgrouplist/getgrouplist_test.c
+getgrouplist_test.i: $(srcdir)/regress/getgrouplist/getgrouplist_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+getgrouplist_test.plog: getgrouplist_test.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/getgrouplist/getgrouplist_test.c --i-file $< --output-file $@
+gethostname.lo: $(srcdir)/gethostname.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/gethostname.c
+gethostname.i: $(srcdir)/gethostname.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+gethostname.plog: gethostname.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/gethostname.c --i-file $< --output-file $@
+getline.lo: $(srcdir)/getline.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getline.c
+getline.i: $(srcdir)/getline.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+getline.plog: getline.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getline.c --i-file $< --output-file $@
+getopt_long.lo: $(srcdir)/getopt_long.c $(incdir)/compat/getopt.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getopt_long.c
+getopt_long.i: $(srcdir)/getopt_long.c $(incdir)/compat/getopt.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+getopt_long.plog: getopt_long.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getopt_long.c --i-file $< --output-file $@
+gettime.lo: $(srcdir)/gettime.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/gettime.c
+gettime.i: $(srcdir)/gettime.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+gettime.plog: gettime.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/gettime.c --i-file $< --output-file $@
+gidlist.lo: $(srcdir)/gidlist.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/gidlist.c
+gidlist.i: $(srcdir)/gidlist.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+gidlist.plog: gidlist.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/gidlist.c --i-file $< --output-file $@
+glob.lo: $(srcdir)/glob.c $(incdir)/compat/charclass.h $(incdir)/compat/glob.h \
+ $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/glob.c
+glob.i: $(srcdir)/glob.c $(incdir)/compat/charclass.h $(incdir)/compat/glob.h \
+ $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+glob.plog: glob.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/glob.c --i-file $< --output-file $@
+globtest.lo: $(srcdir)/regress/glob/globtest.c $(incdir)/compat/glob.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/glob/globtest.c
+globtest.i: $(srcdir)/regress/glob/globtest.c $(incdir)/compat/glob.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+globtest.plog: globtest.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/glob/globtest.c --i-file $< --output-file $@
+hltq_test.lo: $(srcdir)/regress/tailq/hltq_test.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/tailq/hltq_test.c
+hltq_test.i: $(srcdir)/regress/tailq/hltq_test.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+hltq_test.plog: hltq_test.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/tailq/hltq_test.c --i-file $< --output-file $@
+inet_pton.lo: $(srcdir)/inet_pton.c $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/inet_pton.c
+inet_pton.i: $(srcdir)/inet_pton.c $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+inet_pton.plog: inet_pton.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/inet_pton.c --i-file $< --output-file $@
+isblank.lo: $(srcdir)/isblank.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/isblank.c
+isblank.i: $(srcdir)/isblank.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+isblank.plog: isblank.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/isblank.c --i-file $< --output-file $@
+key_val.lo: $(srcdir)/key_val.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/key_val.c
+key_val.i: $(srcdir)/key_val.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+key_val.plog: key_val.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/key_val.c --i-file $< --output-file $@
+lbuf.lo: $(srcdir)/lbuf.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_lbuf.h $(incdir)/sudo_queue.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/lbuf.c
+lbuf.i: $(srcdir)/lbuf.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_lbuf.h $(incdir)/sudo_queue.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+lbuf.plog: lbuf.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/lbuf.c --i-file $< --output-file $@
+locking.lo: $(srcdir)/locking.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/locking.c
+locking.i: $(srcdir)/locking.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+locking.plog: locking.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/locking.c --i-file $< --output-file $@
+memrchr.lo: $(srcdir)/memrchr.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/memrchr.c
+memrchr.i: $(srcdir)/memrchr.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+memrchr.plog: memrchr.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/memrchr.c --i-file $< --output-file $@
+memset_s.lo: $(srcdir)/memset_s.c $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/memset_s.c
+memset_s.i: $(srcdir)/memset_s.c $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+memset_s.plog: memset_s.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/memset_s.c --i-file $< --output-file $@
+mksiglist.lo: $(srcdir)/mksiglist.c $(incdir)/sudo_compat.h \
+ $(srcdir)/mksiglist.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/mksiglist.c
+mksiglist.i: $(srcdir)/mksiglist.c $(incdir)/sudo_compat.h \
+ $(srcdir)/mksiglist.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+mksiglist.plog: mksiglist.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/mksiglist.c --i-file $< --output-file $@
+mksigname.lo: $(srcdir)/mksigname.c $(incdir)/sudo_compat.h \
+ $(srcdir)/mksigname.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/mksigname.c
+mksigname.i: $(srcdir)/mksigname.c $(incdir)/sudo_compat.h \
+ $(srcdir)/mksigname.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+mksigname.plog: mksigname.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/mksigname.c --i-file $< --output-file $@
+mktemp.lo: $(srcdir)/mktemp.c $(incdir)/sudo_compat.h $(incdir)/sudo_rand.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/mktemp.c
+mktemp.i: $(srcdir)/mktemp.c $(incdir)/sudo_compat.h $(incdir)/sudo_rand.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+mktemp.plog: mktemp.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/mktemp.c --i-file $< --output-file $@
+mktemp_test.lo: $(srcdir)/regress/mktemp/mktemp_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/mktemp/mktemp_test.c
+mktemp_test.i: $(srcdir)/regress/mktemp/mktemp_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+mktemp_test.plog: mktemp_test.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/mktemp/mktemp_test.c --i-file $< --output-file $@
+nanosleep.lo: $(srcdir)/nanosleep.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/nanosleep.c
+nanosleep.i: $(srcdir)/nanosleep.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+nanosleep.plog: nanosleep.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/nanosleep.c --i-file $< --output-file $@
+parse_gids_test.lo: $(srcdir)/regress/parse_gids/parse_gids_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/parse_gids/parse_gids_test.c
+parse_gids_test.i: $(srcdir)/regress/parse_gids/parse_gids_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+parse_gids_test.plog: parse_gids_test.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/parse_gids/parse_gids_test.c --i-file $< --output-file $@
+parseln.lo: $(srcdir)/parseln.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/parseln.c
+parseln.i: $(srcdir)/parseln.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+parseln.plog: parseln.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/parseln.c --i-file $< --output-file $@
+parseln_test.lo: $(srcdir)/regress/sudo_parseln/parseln_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/sudo_parseln/parseln_test.c
+parseln_test.i: $(srcdir)/regress/sudo_parseln/parseln_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+parseln_test.plog: parseln_test.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/sudo_parseln/parseln_test.c --i-file $< --output-file $@
+pipe2.lo: $(srcdir)/pipe2.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/pipe2.c
+pipe2.i: $(srcdir)/pipe2.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+pipe2.plog: pipe2.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/pipe2.c --i-file $< --output-file $@
+progname.lo: $(srcdir)/progname.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/progname.c
+progname.i: $(srcdir)/progname.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+progname.plog: progname.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/progname.c --i-file $< --output-file $@
+progname_test.lo: $(srcdir)/regress/progname/progname_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/progname/progname_test.c
+progname_test.i: $(srcdir)/regress/progname/progname_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+progname_test.plog: progname_test.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/progname/progname_test.c --i-file $< --output-file $@
+pw_dup.lo: $(srcdir)/pw_dup.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/pw_dup.c
+pw_dup.i: $(srcdir)/pw_dup.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+pw_dup.plog: pw_dup.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/pw_dup.c --i-file $< --output-file $@
+reallocarray.lo: $(srcdir)/reallocarray.c $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/reallocarray.c
+reallocarray.i: $(srcdir)/reallocarray.c $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+reallocarray.plog: reallocarray.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/reallocarray.c --i-file $< --output-file $@
+secure_path.lo: $(srcdir)/secure_path.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/secure_path.c
+secure_path.i: $(srcdir)/secure_path.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+secure_path.plog: secure_path.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/secure_path.c --i-file $< --output-file $@
+setgroups.lo: $(srcdir)/setgroups.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/setgroups.c
+setgroups.i: $(srcdir)/setgroups.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+setgroups.plog: setgroups.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/setgroups.c --i-file $< --output-file $@
+sha2.lo: $(srcdir)/sha2.c $(incdir)/compat/endian.h $(incdir)/compat/sha2.h \
+ $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sha2.c
+sha2.i: $(srcdir)/sha2.c $(incdir)/compat/endian.h $(incdir)/compat/sha2.h \
+ $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sha2.plog: sha2.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sha2.c --i-file $< --output-file $@
+sig2str.lo: $(srcdir)/sig2str.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sig2str.c
+sig2str.i: $(srcdir)/sig2str.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sig2str.plog: sig2str.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sig2str.c --i-file $< --output-file $@
+siglist.lo: siglist.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) siglist.c
+siglist.i: siglist.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+siglist.plog: siglist.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file siglist.c --i-file $< --output-file $@
+signame.lo: signame.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) signame.c
+signame.i: signame.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+signame.plog: signame.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file signame.c --i-file $< --output-file $@
+snprintf.lo: $(srcdir)/snprintf.c $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/snprintf.c
+snprintf.i: $(srcdir)/snprintf.c $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+snprintf.plog: snprintf.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/snprintf.c --i-file $< --output-file $@
+strlcat.lo: $(srcdir)/strlcat.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strlcat.c
+strlcat.i: $(srcdir)/strlcat.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+strlcat.plog: strlcat.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/strlcat.c --i-file $< --output-file $@
+strlcpy.lo: $(srcdir)/strlcpy.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strlcpy.c
+strlcpy.i: $(srcdir)/strlcpy.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+strlcpy.plog: strlcpy.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/strlcpy.c --i-file $< --output-file $@
+strndup.lo: $(srcdir)/strndup.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strndup.c
+strndup.i: $(srcdir)/strndup.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+strndup.plog: strndup.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/strndup.c --i-file $< --output-file $@
+strnlen.lo: $(srcdir)/strnlen.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strnlen.c
+strnlen.i: $(srcdir)/strnlen.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+strnlen.plog: strnlen.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/strnlen.c --i-file $< --output-file $@
+strsignal.lo: $(srcdir)/strsignal.c $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_gettext.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strsignal.c
+strsignal.i: $(srcdir)/strsignal.c $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_gettext.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+strsignal.plog: strsignal.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/strsignal.c --i-file $< --output-file $@
+strsplit.lo: $(srcdir)/strsplit.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strsplit.c
+strsplit.i: $(srcdir)/strsplit.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+strsplit.plog: strsplit.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/strsplit.c --i-file $< --output-file $@
+strsplit_test.lo: $(srcdir)/regress/strsplit/strsplit_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/strsplit/strsplit_test.c
+strsplit_test.i: $(srcdir)/regress/strsplit/strsplit_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+strsplit_test.plog: strsplit_test.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/strsplit/strsplit_test.c --i-file $< --output-file $@
+strtobool.lo: $(srcdir)/strtobool.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strtobool.c
+strtobool.i: $(srcdir)/strtobool.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+strtobool.plog: strtobool.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/strtobool.c --i-file $< --output-file $@
+strtoid.lo: $(srcdir)/strtoid.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strtoid.c
+strtoid.i: $(srcdir)/strtoid.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+strtoid.plog: strtoid.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/strtoid.c --i-file $< --output-file $@
+strtomode.lo: $(srcdir)/strtomode.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strtomode.c
+strtomode.i: $(srcdir)/strtomode.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+strtomode.plog: strtomode.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/strtomode.c --i-file $< --output-file $@
+strtonum.lo: $(srcdir)/strtonum.c $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_gettext.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strtonum.c
+strtonum.i: $(srcdir)/strtonum.c $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_gettext.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+strtonum.plog: strtonum.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/strtonum.c --i-file $< --output-file $@
+sudo_conf.lo: $(srcdir)/sudo_conf.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sudo_conf.c
+sudo_conf.i: $(srcdir)/sudo_conf.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sudo_conf.plog: sudo_conf.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudo_conf.c --i-file $< --output-file $@
+sudo_debug.lo: $(srcdir)/sudo_debug.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sudo_debug.c
+sudo_debug.i: $(srcdir)/sudo_debug.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sudo_debug.plog: sudo_debug.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudo_debug.c --i-file $< --output-file $@
+sudo_dso.lo: $(srcdir)/sudo_dso.c $(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sudo_dso.c
+sudo_dso.i: $(srcdir)/sudo_dso.c $(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sudo_dso.plog: sudo_dso.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudo_dso.c --i-file $< --output-file $@
+term.lo: $(srcdir)/term.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/term.c
+term.i: $(srcdir)/term.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+term.plog: term.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/term.c --i-file $< --output-file $@
+ttyname_dev.lo: $(srcdir)/ttyname_dev.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/ttyname_dev.c
+ttyname_dev.i: $(srcdir)/ttyname_dev.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+ttyname_dev.plog: ttyname_dev.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/ttyname_dev.c --i-file $< --output-file $@
+ttysize.lo: $(srcdir)/ttysize.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/ttysize.c
+ttysize.i: $(srcdir)/ttysize.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+ttysize.plog: ttysize.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/ttysize.c --i-file $< --output-file $@
+utimens.lo: $(srcdir)/utimens.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/utimens.c
+utimens.i: $(srcdir)/utimens.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+utimens.plog: utimens.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/utimens.c --i-file $< --output-file $@
+vsyslog.lo: $(srcdir)/vsyslog.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/vsyslog.c
+vsyslog.i: $(srcdir)/vsyslog.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+vsyslog.plog: vsyslog.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/vsyslog.c --i-file $< --output-file $@
+vsyslog_test.lo: $(srcdir)/regress/vsyslog/vsyslog_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/vsyslog/vsyslog_test.c
+vsyslog_test.i: $(srcdir)/regress/vsyslog/vsyslog_test.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+vsyslog_test.plog: vsyslog_test.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/vsyslog/vsyslog_test.c --i-file $< --output-file $@
diff --git a/lib/util/aix.c b/lib/util/aix.c
new file mode 100644
index 0000000..137de23
--- /dev/null
+++ b/lib/util/aix.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2008, 2010-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/resource.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <usersec.h>
+#include <uinfo.h>
+
+#define DEFAULT_TEXT_DOMAIN "sudo"
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+#ifdef HAVE_GETUSERATTR
+
+#ifndef HAVE_SETRLIMIT64
+# define setrlimit64(a, b) setrlimit(a, b)
+# define rlimit64 rlimit
+# define rlim64_t rlim_t
+# define RLIM64_INFINITY RLIM_INFINITY
+#endif /* HAVE_SETRLIMIT64 */
+
+#ifndef RLIM_SAVED_MAX
+# define RLIM_SAVED_MAX RLIM64_INFINITY
+#endif
+
+struct aix_limit {
+ int resource;
+ char *soft;
+ char *hard;
+ int factor;
+};
+
+static struct aix_limit aix_limits[] = {
+ { RLIMIT_FSIZE, S_UFSIZE, S_UFSIZE_HARD, 512 },
+ { RLIMIT_CPU, S_UCPU, S_UCPU_HARD, 1 },
+ { RLIMIT_DATA, S_UDATA, S_UDATA_HARD, 512 },
+ { RLIMIT_STACK, S_USTACK, S_USTACK_HARD, 512 },
+ { RLIMIT_RSS, S_URSS, S_URSS_HARD, 512 },
+ { RLIMIT_CORE, S_UCORE, S_UCORE_HARD, 512 },
+ { RLIMIT_NOFILE, S_UNOFILE, S_UNOFILE_HARD, 1 }
+};
+
+static int
+aix_getlimit(char *user, char *lim, int *valp)
+{
+ debug_decl(aix_getlimit, SUDO_DEBUG_UTIL)
+
+ if (getuserattr(user, lim, valp, SEC_INT) != 0)
+ debug_return_int(-1);
+ debug_return_int(0);
+}
+
+static int
+aix_setlimits(char *user)
+{
+ struct rlimit64 rlim;
+ int val;
+ size_t n;
+ debug_decl(aix_setlimits, SUDO_DEBUG_UTIL)
+
+ if (setuserdb(S_READ) != 0) {
+ sudo_warn(U_("unable to open userdb"));
+ debug_return_int(-1);
+ }
+
+ /*
+ * For each resource limit, get the soft/hard values for the user
+ * and set those values via setrlimit64(). Must be run as euid 0.
+ */
+ for (n = 0; n < nitems(aix_limits); n++) {
+ /*
+ * We have two strategies, depending on whether or not the
+ * hard limit has been defined.
+ */
+ if (aix_getlimit(user, aix_limits[n].hard, &val) == 0) {
+ rlim.rlim_max = val == -1 ? RLIM64_INFINITY : (rlim64_t)val * aix_limits[n].factor;
+ if (aix_getlimit(user, aix_limits[n].soft, &val) == 0)
+ rlim.rlim_cur = val == -1 ? RLIM64_INFINITY : (rlim64_t)val * aix_limits[n].factor;
+ else
+ rlim.rlim_cur = rlim.rlim_max; /* soft not specd, use hard */
+ } else {
+ /* No hard limit set, try soft limit, if it exists. */
+ if (aix_getlimit(user, aix_limits[n].soft, &val) == -1)
+ continue;
+ rlim.rlim_cur = val == -1 ? RLIM64_INFINITY : (rlim64_t)val * aix_limits[n].factor;
+
+ /* Set default hard limit as per limits(4). */
+ switch (aix_limits[n].resource) {
+ case RLIMIT_CPU:
+ case RLIMIT_FSIZE:
+ rlim.rlim_max = rlim.rlim_cur;
+ break;
+ case RLIMIT_STACK:
+ rlim.rlim_max = 4194304UL * aix_limits[n].factor;
+ break;
+ default:
+ rlim.rlim_max = RLIM64_INFINITY;
+ break;
+ }
+ }
+ (void)setrlimit64(aix_limits[n].resource, &rlim);
+ }
+ enduserdb();
+ debug_return_int(0);
+}
+
+#ifdef HAVE_SETAUTHDB
+
+# ifndef HAVE_AUTHDB_T
+typedef char authdb_t[16];
+# endif
+
+/* The empty string means to access all defined authentication registries. */
+static authdb_t old_registry;
+
+# if defined(HAVE_DECL_SETAUTHDB) && !HAVE_DECL_SETAUTHDB
+int setauthdb(authdb_t new, authdb_t old);
+int getauthdb(authdb_t val);
+# endif
+# if defined(HAVE_DECL_USRINFO) && !HAVE_DECL_USRINFO
+int usrinfo(int cmd, char *buf, int count);
+# endif
+
+/*
+ * Look up authentication registry for user (SYSTEM in /etc/security/user) and
+ * set it as the default for the process. This ensures that password and
+ * group lookups are made against the correct source (files, NIS, LDAP, etc).
+ * Does not modify errno even on error since callers do not check return value.
+ */
+int
+aix_getauthregistry_v1(char *user, char *saved_registry)
+{
+ int serrno = errno;
+ int ret = -1;
+ debug_decl(aix_getauthregistry, SUDO_DEBUG_UTIL)
+
+ saved_registry[0] = '\0';
+ if (user != NULL) {
+ char *registry;
+
+ if (setuserdb(S_READ) != 0) {
+ sudo_warn(U_("unable to open userdb"));
+ goto done;
+ }
+ ret = getuserattr(user, S_REGISTRY, &registry, SEC_CHAR);
+ if (ret == 0) {
+ /* sizeof(authdb_t) is guaranteed to be 16 */
+ if (strlcpy(saved_registry, registry, 16) >= 16) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "registry for user %s too long: %s", user, registry);
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: saved authentication registry for user %s is %s",
+ __func__, user, saved_registry);
+ }
+ enduserdb();
+ } else {
+ /* Get the process-wide registry. */
+ ret = getauthdb(saved_registry);
+ }
+done:
+ errno = serrno;
+ debug_return_int(ret);
+}
+
+/*
+ * Set the specified authentication registry for user (SYSTEM in
+ * /etc/security/user) and set it as the default for the process.
+ * This ensures that password and group lookups are made against
+ * the correct source (files, NIS, LDAP, etc).
+ * If registry is NULL, look it up based on the user name.
+ * Does not modify errno even on error since callers do not check return value.
+ */
+int
+aix_setauthdb_v1(char *user)
+{
+ return aix_setauthdb_v2(user, NULL);
+}
+
+int
+aix_setauthdb_v2(char *user, char *registry)
+{
+ authdb_t regbuf;
+ int serrno = errno;
+ int ret = -1;
+ debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
+
+ if (user != NULL) {
+ /* Look up authentication registry if one is not provided. */
+ if (registry == NULL) {
+ if (aix_getauthregistry(user, regbuf) != 0)
+ goto done;
+ registry = regbuf;
+ }
+ ret = setauthdb(registry, old_registry);
+ if (ret != 0) {
+ sudo_warn(U_("unable to switch to registry \"%s\" for %s"),
+ registry, user);
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: setting authentication registry to %s",
+ __func__, registry);
+ }
+ }
+done:
+ errno = serrno;
+ debug_return_int(ret);
+}
+
+/*
+ * Restore the saved authentication registry, if any.
+ * Does not modify errno even on error since callers do not check return value.
+ */
+int
+aix_restoreauthdb_v1(void)
+{
+ int serrno = errno;
+ int ret = 0;
+ debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
+
+ if (setauthdb(old_registry, NULL) != 0) {
+ sudo_warn(U_("unable to restore registry"));
+ ret = -1;
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: setting authentication registry to %s",
+ __func__, old_registry);
+ }
+ errno = serrno;
+ debug_return_int(ret);
+}
+#endif
+
+int
+aix_prep_user_v1(char *user, const char *tty)
+{
+ char *info;
+ int len;
+ debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
+
+ /* set usrinfo, like login(1) does */
+ len = asprintf(&info, "NAME=%s%cLOGIN=%s%cLOGNAME=%s%cTTY=%s%c",
+ user, '\0', user, '\0', user, '\0', tty ? tty : "", '\0');
+ if (len == -1) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+ (void)usrinfo(SETUINFO, info, len);
+ free(info);
+
+#ifdef HAVE_SETAUTHDB
+ /* set authentication registry */
+ if (aix_setauthdb(user, NULL) != 0)
+ debug_return_int(-1);
+#endif
+
+ /* set resource limits */
+ if (aix_setlimits(user) != 0)
+ debug_return_int(-1);
+
+ debug_return_int(0);
+}
+#endif /* HAVE_GETUSERATTR */
diff --git a/lib/util/arc4random.c b/lib/util/arc4random.c
new file mode 100644
index 0000000..8935d36
--- /dev/null
+++ b/lib/util/arc4random.c
@@ -0,0 +1,217 @@
+/* $OpenBSD: arc4random.c,v 1.54 2015/09/13 08:31:47 guenther Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+/*
+ * ChaCha based random number generator for OpenBSD.
+ */
+
+#include <config.h>
+
+#ifndef HAVE_ARC4RANDOM
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_rand.h"
+
+#define KEYSTREAM_ONLY
+#include "chacha_private.h"
+
+#define minimum(a, b) ((a) < (b) ? (a) : (b))
+
+#if defined(__GNUC__) || defined(_MSC_VER)
+#define inline __inline
+#else /* __GNUC__ || _MSC_VER */
+#define inline
+#endif /* !__GNUC__ && !_MSC_VER */
+
+#define KEYSZ 32
+#define IVSZ 8
+#define BLOCKSZ 64
+#define RSBUFSZ (16*BLOCKSZ)
+
+/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
+static struct _rs {
+ size_t rs_have; /* valid bytes at end of rs_buf */
+ size_t rs_count; /* bytes till reseed */
+} *rs;
+
+/* Maybe be preserved in fork children, if _rs_allocate() decides. */
+static struct _rsx {
+ chacha_ctx rs_chacha; /* chacha context for random keystream */
+ unsigned char rs_buf[RSBUFSZ]; /* keystream blocks */
+} *rsx;
+
+static inline int _rs_allocate(struct _rs **, struct _rsx **);
+static inline void _rs_forkdetect(void);
+#include "arc4random.h"
+
+static inline void _rs_rekey(unsigned char *dat, size_t datlen);
+
+static inline void
+_rs_init(unsigned char *buf, size_t n)
+{
+ if (n < KEYSZ + IVSZ)
+ return;
+
+ if (rs == NULL) {
+ if (_rs_allocate(&rs, &rsx) == -1)
+ abort();
+ }
+
+ chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0);
+ chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
+}
+
+static void
+_rs_stir(void)
+{
+ unsigned char rnd[KEYSZ + IVSZ];
+
+ if (getentropy(rnd, sizeof rnd) == -1)
+ _getentropy_fail();
+
+ if (!rs)
+ _rs_init(rnd, sizeof(rnd));
+ else
+ _rs_rekey(rnd, sizeof(rnd));
+ memset_s(rnd, sizeof(rnd), 0, sizeof(rnd)); /* discard source seed */
+
+ /* invalidate rs_buf */
+ rs->rs_have = 0;
+ memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
+
+ rs->rs_count = 1600000;
+}
+
+static inline void
+_rs_stir_if_needed(size_t len)
+{
+ _rs_forkdetect();
+ if (!rs || rs->rs_count <= len)
+ _rs_stir();
+ if (rs->rs_count <= len)
+ rs->rs_count = 0;
+ else
+ rs->rs_count -= len;
+}
+
+static inline void
+_rs_rekey(unsigned char *dat, size_t datlen)
+{
+#ifndef KEYSTREAM_ONLY
+ memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
+#endif
+ /* fill rs_buf with the keystream */
+ chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf,
+ rsx->rs_buf, sizeof(rsx->rs_buf));
+ /* mix in optional user provided data */
+ if (dat) {
+ size_t i, m;
+
+ m = minimum(datlen, KEYSZ + IVSZ);
+ for (i = 0; i < m; i++)
+ rsx->rs_buf[i] ^= dat[i];
+ }
+ /* immediately reinit for backtracking resistance */
+ _rs_init(rsx->rs_buf, KEYSZ + IVSZ);
+ memset(rsx->rs_buf, 0, KEYSZ + IVSZ);
+ rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
+}
+
+static inline void
+_rs_random_buf(void *_buf, size_t n)
+{
+ unsigned char *buf = (unsigned char *)_buf;
+ unsigned char *keystream;
+ size_t m;
+
+ _rs_stir_if_needed(n);
+ while (n > 0) {
+ if (rs->rs_have > 0) {
+ m = minimum(n, rs->rs_have);
+ keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
+ - rs->rs_have;
+ memcpy(buf, keystream, m);
+ memset(keystream, 0, m);
+ buf += m;
+ n -= m;
+ rs->rs_have -= m;
+ }
+ if (rs->rs_have == 0)
+ _rs_rekey(NULL, 0);
+ }
+}
+
+static inline void
+_rs_random_u32(uint32_t *val)
+{
+ unsigned char *keystream;
+
+ _rs_stir_if_needed(sizeof(*val));
+ if (rs->rs_have < sizeof(*val))
+ _rs_rekey(NULL, 0);
+ keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have;
+ memcpy(val, keystream, sizeof(*val));
+ memset(keystream, 0, sizeof(*val));
+ rs->rs_have -= sizeof(*val);
+}
+
+uint32_t
+sudo_arc4random(void)
+{
+ uint32_t val;
+
+ _ARC4_LOCK();
+ _rs_random_u32(&val);
+ _ARC4_UNLOCK();
+ return val;
+}
+
+#ifdef notdef
+void
+sudo_arc4random_buf(void *buf, size_t n)
+{
+ _ARC4_LOCK();
+ _rs_random_buf(buf, n);
+ _ARC4_UNLOCK();
+}
+#endif
+
+#endif /* HAVE_ARC4RANDOM */
diff --git a/lib/util/arc4random.h b/lib/util/arc4random.h
new file mode 100644
index 0000000..d649017
--- /dev/null
+++ b/lib/util/arc4random.h
@@ -0,0 +1,107 @@
+/* $OpenBSD: arc4random.h,v 1.4 2015/01/15 06:57:18 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+#include <sys/mman.h>
+
+#include <signal.h>
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+
+static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
+#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx)
+#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
+#else
+#define _ARC4_LOCK()
+#define _ARC4_UNLOCK()
+#endif /* HAVE_PTHREAD_H */
+
+#ifdef HAVE_PTHREAD_ATFORK
+# define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
+# else
+# define _ARC4_ATFORK(f)
+#endif
+
+#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+
+static inline void
+_getentropy_fail(void)
+{
+ raise(SIGKILL);
+}
+
+static volatile sig_atomic_t _rs_forked;
+
+#ifdef HAVE_PTHREAD_ATFORK
+static inline void
+_rs_forkhandler(void)
+{
+ _rs_forked = 1;
+}
+#endif /* HAVE_PTHREAD_ATFORK */
+
+static int wipeonfork;
+
+static inline void
+_rs_forkdetect(void)
+{
+ if (!wipeonfork) {
+ static pid_t _rs_pid = 0;
+ pid_t pid = getpid();
+
+ if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) {
+ _rs_pid = pid;
+ _rs_forked = 0;
+ if (rs)
+ memset(rs, 0, sizeof(*rs));
+ }
+ }
+}
+
+static inline int
+_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
+{
+ if ((*rsp = (void *)mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ return (-1);
+
+ if ((*rsxp = (void *)mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
+ munmap((void *)*rsp, sizeof(**rsp));
+ *rsp = NULL;
+ return (-1);
+ }
+
+#ifdef MADV_WIPEONFORK
+ if (madvise (*rsp, sizeof(**rsp), MADV_WIPEONFORK) == 0 &&
+ madvise (*rsxp, sizeof(**rsxp), MADV_WIPEONFORK) == 0) {
+ wipeonfork = 1;
+ }
+#endif
+
+ _ARC4_ATFORK(_rs_forkhandler);
+ return (0);
+}
diff --git a/lib/util/arc4random_uniform.c b/lib/util/arc4random_uniform.c
new file mode 100644
index 0000000..51f4714
--- /dev/null
+++ b/lib/util/arc4random_uniform.c
@@ -0,0 +1,75 @@
+/* $OpenBSD: arc4random_uniform.c,v 1.2 2015/09/13 08:31:47 guenther Exp $ */
+
+/*
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_ARC4RANDOM_UNIFORM
+
+#include <sys/types.h>
+#include <stdlib.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_rand.h"
+
+/*
+ * Calculate a uniformly distributed random number less than upper_bound
+ * avoiding "modulo bias".
+ *
+ * Uniformity is achieved by generating new random numbers until the one
+ * returned is outside the range [0, 2**32 % upper_bound). This
+ * guarantees the selected random number will be inside
+ * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
+ * after reduction modulo upper_bound.
+ */
+uint32_t
+sudo_arc4random_uniform(uint32_t upper_bound)
+{
+ uint32_t r, min;
+
+ if (upper_bound < 2)
+ return 0;
+
+ /* 2**32 % x == (2**32 - x) % x */
+ min = -upper_bound % upper_bound;
+
+ /*
+ * This could theoretically loop forever but each retry has
+ * p > 0.5 (worst case, usually far better) of selecting a
+ * number inside the range we need, so it should rarely need
+ * to re-roll.
+ */
+ for (;;) {
+ r = arc4random();
+ if (r >= min)
+ break;
+ }
+
+ return r % upper_bound;
+}
+
+#endif /* HAVE_ARC4RANDOM_UNIFORM */
diff --git a/lib/util/chacha_private.h b/lib/util/chacha_private.h
new file mode 100644
index 0000000..7c3680f
--- /dev/null
+++ b/lib/util/chacha_private.h
@@ -0,0 +1,222 @@
+/*
+chacha-merged.c version 20080118
+D. J. Bernstein
+Public domain.
+*/
+
+/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+
+typedef struct
+{
+ u32 input[16]; /* could be compressed */
+} chacha_ctx;
+
+#define U8C(v) (v##U)
+#define U32C(v) (v##U)
+
+#define U8V(v) ((u8)(v) & U8C(0xFF))
+#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
+
+#define ROTL32(v, n) \
+ (U32V((v) << (n)) | ((v) >> (32 - (n))))
+
+#define U8TO32_LITTLE(p) \
+ (((u32)((p)[0]) ) | \
+ ((u32)((p)[1]) << 8) | \
+ ((u32)((p)[2]) << 16) | \
+ ((u32)((p)[3]) << 24))
+
+#define U32TO8_LITTLE(p, v) \
+ do { \
+ (p)[0] = U8V((v) ); \
+ (p)[1] = U8V((v) >> 8); \
+ (p)[2] = U8V((v) >> 16); \
+ (p)[3] = U8V((v) >> 24); \
+ } while (0)
+
+#define ROTATE(v,c) (ROTL32(v,c))
+#define XOR(v,w) ((v) ^ (w))
+#define PLUS(v,w) (U32V((v) + (w)))
+#define PLUSONE(v) (PLUS((v),1))
+
+#define QUARTERROUND(a,b,c,d) \
+ a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
+ c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
+ a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
+ c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
+
+static const char sigma[16] = "expand 32-byte k";
+static const char tau[16] = "expand 16-byte k";
+
+static void
+chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits)
+{
+ const char *constants;
+
+ x->input[4] = U8TO32_LITTLE(k + 0);
+ x->input[5] = U8TO32_LITTLE(k + 4);
+ x->input[6] = U8TO32_LITTLE(k + 8);
+ x->input[7] = U8TO32_LITTLE(k + 12);
+ if (kbits == 256) { /* recommended */
+ k += 16;
+ constants = sigma;
+ } else { /* kbits == 128 */
+ constants = tau;
+ }
+ x->input[8] = U8TO32_LITTLE(k + 0);
+ x->input[9] = U8TO32_LITTLE(k + 4);
+ x->input[10] = U8TO32_LITTLE(k + 8);
+ x->input[11] = U8TO32_LITTLE(k + 12);
+ x->input[0] = U8TO32_LITTLE(constants + 0);
+ x->input[1] = U8TO32_LITTLE(constants + 4);
+ x->input[2] = U8TO32_LITTLE(constants + 8);
+ x->input[3] = U8TO32_LITTLE(constants + 12);
+}
+
+static void
+chacha_ivsetup(chacha_ctx *x,const u8 *iv)
+{
+ x->input[12] = 0;
+ x->input[13] = 0;
+ x->input[14] = U8TO32_LITTLE(iv + 0);
+ x->input[15] = U8TO32_LITTLE(iv + 4);
+}
+
+static void
+chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
+{
+ u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
+ u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
+ u8 *ctarget = NULL;
+ u8 tmp[64];
+ u_int i;
+
+ if (!bytes) return;
+
+ j0 = x->input[0];
+ j1 = x->input[1];
+ j2 = x->input[2];
+ j3 = x->input[3];
+ j4 = x->input[4];
+ j5 = x->input[5];
+ j6 = x->input[6];
+ j7 = x->input[7];
+ j8 = x->input[8];
+ j9 = x->input[9];
+ j10 = x->input[10];
+ j11 = x->input[11];
+ j12 = x->input[12];
+ j13 = x->input[13];
+ j14 = x->input[14];
+ j15 = x->input[15];
+
+ for (;;) {
+ if (bytes < 64) {
+ for (i = 0;i < bytes;++i) tmp[i] = m[i];
+ m = tmp;
+ ctarget = c;
+ c = tmp;
+ }
+ x0 = j0;
+ x1 = j1;
+ x2 = j2;
+ x3 = j3;
+ x4 = j4;
+ x5 = j5;
+ x6 = j6;
+ x7 = j7;
+ x8 = j8;
+ x9 = j9;
+ x10 = j10;
+ x11 = j11;
+ x12 = j12;
+ x13 = j13;
+ x14 = j14;
+ x15 = j15;
+ for (i = 20;i > 0;i -= 2) {
+ QUARTERROUND( x0, x4, x8,x12)
+ QUARTERROUND( x1, x5, x9,x13)
+ QUARTERROUND( x2, x6,x10,x14)
+ QUARTERROUND( x3, x7,x11,x15)
+ QUARTERROUND( x0, x5,x10,x15)
+ QUARTERROUND( x1, x6,x11,x12)
+ QUARTERROUND( x2, x7, x8,x13)
+ QUARTERROUND( x3, x4, x9,x14)
+ }
+ x0 = PLUS(x0,j0);
+ x1 = PLUS(x1,j1);
+ x2 = PLUS(x2,j2);
+ x3 = PLUS(x3,j3);
+ x4 = PLUS(x4,j4);
+ x5 = PLUS(x5,j5);
+ x6 = PLUS(x6,j6);
+ x7 = PLUS(x7,j7);
+ x8 = PLUS(x8,j8);
+ x9 = PLUS(x9,j9);
+ x10 = PLUS(x10,j10);
+ x11 = PLUS(x11,j11);
+ x12 = PLUS(x12,j12);
+ x13 = PLUS(x13,j13);
+ x14 = PLUS(x14,j14);
+ x15 = PLUS(x15,j15);
+
+#ifndef KEYSTREAM_ONLY
+ x0 = XOR(x0,U8TO32_LITTLE(m + 0));
+ x1 = XOR(x1,U8TO32_LITTLE(m + 4));
+ x2 = XOR(x2,U8TO32_LITTLE(m + 8));
+ x3 = XOR(x3,U8TO32_LITTLE(m + 12));
+ x4 = XOR(x4,U8TO32_LITTLE(m + 16));
+ x5 = XOR(x5,U8TO32_LITTLE(m + 20));
+ x6 = XOR(x6,U8TO32_LITTLE(m + 24));
+ x7 = XOR(x7,U8TO32_LITTLE(m + 28));
+ x8 = XOR(x8,U8TO32_LITTLE(m + 32));
+ x9 = XOR(x9,U8TO32_LITTLE(m + 36));
+ x10 = XOR(x10,U8TO32_LITTLE(m + 40));
+ x11 = XOR(x11,U8TO32_LITTLE(m + 44));
+ x12 = XOR(x12,U8TO32_LITTLE(m + 48));
+ x13 = XOR(x13,U8TO32_LITTLE(m + 52));
+ x14 = XOR(x14,U8TO32_LITTLE(m + 56));
+ x15 = XOR(x15,U8TO32_LITTLE(m + 60));
+#endif
+
+ j12 = PLUSONE(j12);
+ if (!j12) {
+ j13 = PLUSONE(j13);
+ /* stopping at 2^70 bytes per nonce is user's responsibility */
+ }
+
+ U32TO8_LITTLE(c + 0,x0);
+ U32TO8_LITTLE(c + 4,x1);
+ U32TO8_LITTLE(c + 8,x2);
+ U32TO8_LITTLE(c + 12,x3);
+ U32TO8_LITTLE(c + 16,x4);
+ U32TO8_LITTLE(c + 20,x5);
+ U32TO8_LITTLE(c + 24,x6);
+ U32TO8_LITTLE(c + 28,x7);
+ U32TO8_LITTLE(c + 32,x8);
+ U32TO8_LITTLE(c + 36,x9);
+ U32TO8_LITTLE(c + 40,x10);
+ U32TO8_LITTLE(c + 44,x11);
+ U32TO8_LITTLE(c + 48,x12);
+ U32TO8_LITTLE(c + 52,x13);
+ U32TO8_LITTLE(c + 56,x14);
+ U32TO8_LITTLE(c + 60,x15);
+
+ if (bytes <= 64) {
+ if (bytes < 64) {
+ for (i = 0;i < bytes;++i) ctarget[i] = c[i];
+ }
+ x->input[12] = j12;
+ x->input[13] = j13;
+ return;
+ }
+ bytes -= 64;
+ c += 64;
+#ifndef KEYSTREAM_ONLY
+ m += 64;
+#endif
+ }
+}
diff --git a/lib/util/closefrom.c b/lib/util/closefrom.c
new file mode 100644
index 0000000..6cfe320
--- /dev/null
+++ b/lib/util/closefrom.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2004-2005, 2007, 2010, 2012-2015, 2017-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_CLOSEFROM
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <limits.h>
+#ifdef HAVE_PSTAT_GETPROC
+# include <sys/pstat.h>
+#else
+# include <dirent.h>
+#endif
+
+#include "sudo_compat.h"
+#include "pathnames.h"
+
+#ifndef _POSIX_OPEN_MAX
+# define _POSIX_OPEN_MAX 20
+#endif
+
+/*
+ * Close all file descriptors greater than or equal to lowfd.
+ * This is the expensive (fallback) method.
+ */
+static void
+closefrom_fallback(int lowfd)
+{
+ long fd, maxfd;
+
+ /*
+ * Fall back on sysconf(_SC_OPEN_MAX). We avoid checking
+ * resource limits since it is possible to open a file descriptor
+ * and then drop the rlimit such that it is below the open fd.
+ */
+ maxfd = sysconf(_SC_OPEN_MAX);
+ if (maxfd < 0)
+ maxfd = _POSIX_OPEN_MAX;
+
+ for (fd = lowfd; fd < maxfd; fd++) {
+#ifdef __APPLE__
+ /* Avoid potential libdispatch crash when we close its fds. */
+ (void) fcntl((int) fd, F_SETFD, FD_CLOEXEC);
+#else
+ (void) close((int) fd);
+#endif
+ }
+}
+
+/*
+ * Close all file descriptors greater than or equal to lowfd.
+ * We try the fast way first, falling back on the slow method.
+ */
+void
+sudo_closefrom(int lowfd)
+{
+#if defined(HAVE_PSTAT_GETPROC)
+ struct pst_status pstat;
+#elif defined(HAVE_DIRFD)
+ const char *path;
+ DIR *dirp;
+#endif
+
+ /* Try the fast method first, if possible. */
+#if defined(HAVE_FCNTL_CLOSEM)
+ if (fcntl(lowfd, F_CLOSEM, 0) != -1)
+ return;
+#endif
+#if defined(HAVE_PSTAT_GETPROC)
+ if (pstat_getproc(&pstat, sizeof(pstat), 0, getpid()) != -1) {
+ int fd;
+
+ for (fd = lowfd; fd <= pstat.pst_highestfd; fd++)
+ (void) close(fd);
+ return;
+ }
+#elif defined(HAVE_DIRFD)
+ /* Use /proc/self/fd (or /dev/fd on FreeBSD) if it exists. */
+# if defined(__FreeBSD__) || defined(__APPLE__)
+ path = _PATH_DEV "fd";
+# else
+ path = "/proc/self/fd";
+# endif
+ if ((dirp = opendir(path)) != NULL) {
+ struct dirent *dent;
+ while ((dent = readdir(dirp)) != NULL) {
+ const char *errstr;
+ int fd = strtonum(dent->d_name, lowfd, INT_MAX, &errstr);
+ if (errstr == NULL && fd != dirfd(dirp)) {
+# ifdef __APPLE__
+ /* Avoid potential libdispatch crash when we close its fds. */
+ (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
+# else
+ (void) close(fd);
+# endif
+ }
+ }
+ (void) closedir(dirp);
+ return;
+ }
+#endif /* HAVE_DIRFD */
+
+ /* Do things the slow way. */
+ closefrom_fallback(lowfd);
+}
+
+#endif /* HAVE_CLOSEFROM */
diff --git a/lib/util/digest.c b/lib/util/digest.c
new file mode 100644
index 0000000..f81d463
--- /dev/null
+++ b/lib/util/digest.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2013-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_digest.h"
+
+#ifdef HAVE_SHA224UPDATE
+# include <sha2.h>
+#else
+# include "compat/sha2.h"
+#endif
+
+static struct digest_function {
+ const unsigned int digest_len;
+ void (*init)(SHA2_CTX *);
+#ifdef SHA2_VOID_PTR
+ void (*update)(SHA2_CTX *, const void *, size_t);
+ void (*final)(void *, SHA2_CTX *);
+#else
+ void (*update)(SHA2_CTX *, const unsigned char *, size_t);
+ void (*final)(unsigned char *, SHA2_CTX *);
+#endif
+} digest_functions[] = {
+ {
+ SHA224_DIGEST_LENGTH,
+ SHA224Init,
+ SHA224Update,
+ SHA224Final
+ }, {
+ SHA256_DIGEST_LENGTH,
+ SHA256Init,
+ SHA256Update,
+ SHA256Final
+ }, {
+ SHA384_DIGEST_LENGTH,
+ SHA384Init,
+ SHA384Update,
+ SHA384Final
+ }, {
+ SHA512_DIGEST_LENGTH,
+ SHA512Init,
+ SHA512Update,
+ SHA512Final
+ }, {
+ 0
+ }
+};
+
+struct sudo_digest {
+ struct digest_function *func;
+ SHA2_CTX ctx;
+};
+
+struct sudo_digest *
+sudo_digest_alloc_v1(int digest_type)
+{
+ debug_decl(sudo_digest_alloc, SUDO_DEBUG_UTIL)
+ struct digest_function *func = NULL;
+ struct sudo_digest *dig;
+ int i;
+
+ for (i = 0; digest_functions[i].digest_len != 0; i++) {
+ if (digest_type == i) {
+ func = &digest_functions[i];
+ break;
+ }
+ }
+ if (func == NULL) {
+ errno = EINVAL;
+ debug_return_ptr(NULL);
+ }
+
+ if ((dig = malloc(sizeof(*dig))) == NULL)
+ debug_return_ptr(NULL);
+ func->init(&dig->ctx);
+ dig->func = func;
+
+ debug_return_ptr(dig);
+}
+
+void
+sudo_digest_free_v1(struct sudo_digest *dig)
+{
+ debug_decl(sudo_digest_free, SUDO_DEBUG_UTIL)
+
+ free(dig);
+
+ debug_return;
+}
+
+void
+sudo_digest_reset_v1(struct sudo_digest *dig)
+{
+ debug_decl(sudo_digest_reset, SUDO_DEBUG_UTIL)
+
+ dig->func->init(&dig->ctx);
+
+ debug_return;
+}
+
+int
+sudo_digest_getlen_v1(int digest_type)
+{
+ debug_decl(sudo_digest_getlen, SUDO_DEBUG_UTIL)
+ int i;
+
+ for (i = 0; digest_functions[i].digest_len != 0; i++) {
+ if (digest_type == i)
+ debug_return_int(digest_functions[i].digest_len);
+ }
+
+ debug_return_int(-1);
+}
+
+void
+sudo_digest_update_v1(struct sudo_digest *dig, const void *data, size_t len)
+{
+ debug_decl(sudo_digest_update, SUDO_DEBUG_UTIL)
+
+ dig->func->update(&dig->ctx, data, len);
+
+ debug_return;
+}
+
+void
+sudo_digest_final_v1(struct sudo_digest *dig, unsigned char *md)
+{
+ debug_decl(sudo_digest_final, SUDO_DEBUG_UTIL)
+
+ dig->func->final(md, &dig->ctx);
+
+ debug_return;
+}
diff --git a/lib/util/digest_gcrypt.c b/lib/util/digest_gcrypt.c
new file mode 100644
index 0000000..7d12fe2
--- /dev/null
+++ b/lib/util/digest_gcrypt.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2017-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <gcrypt.h>
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_digest.h"
+
+struct sudo_digest {
+ int gcry_digest_type;
+ unsigned int digest_len;
+ gcry_md_hd_t ctx;
+};
+
+/* Map sudo digest type to gcrypt digest type. */
+static int
+sudo_digest_type_to_gcry(int digest_type)
+{
+ switch (digest_type) {
+ case SUDO_DIGEST_SHA224:
+ return GCRY_MD_SHA224;
+ break;
+ case SUDO_DIGEST_SHA256:
+ return GCRY_MD_SHA256;
+ break;
+ case SUDO_DIGEST_SHA384:
+ return GCRY_MD_SHA384;
+ break;
+ case SUDO_DIGEST_SHA512:
+ return GCRY_MD_SHA512;
+ break;
+ default:
+ return -1;
+ }
+}
+
+struct sudo_digest *
+sudo_digest_alloc_v1(int digest_type)
+{
+ debug_decl(sudo_digest_alloc, SUDO_DEBUG_UTIL)
+ struct sudo_digest *dig;
+ int gcry_digest_type;
+
+ gcry_digest_type = sudo_digest_type_to_gcry(digest_type);
+ if (gcry_digest_type == -1) {
+ errno = EINVAL;
+ debug_return_ptr(NULL);
+ }
+
+ if ((dig = malloc(sizeof(*dig))) == NULL)
+ debug_return_ptr(NULL);
+ dig->gcry_digest_type = gcry_digest_type;
+ dig->digest_len = gcry_md_get_algo_dlen(gcry_digest_type);
+
+ if (gcry_md_open(&dig->ctx, gcry_digest_type, 0) != 0) {
+ free(dig);
+ debug_return_ptr(NULL);
+ }
+
+ debug_return_ptr(dig);
+}
+
+void
+sudo_digest_free_v1(struct sudo_digest *dig)
+{
+ debug_decl(sudo_digest_free, SUDO_DEBUG_UTIL)
+
+ if (dig != NULL) {
+ gcry_md_close(dig->ctx);
+ free(dig);
+ }
+
+ debug_return;
+}
+
+void
+sudo_digest_reset_v1(struct sudo_digest *dig)
+{
+ debug_decl(sudo_digest_reset, SUDO_DEBUG_UTIL)
+
+ gcry_md_reset(dig->ctx);
+
+ debug_return;
+}
+
+int
+sudo_digest_getlen_v1(int digest_type)
+{
+ debug_decl(sudo_digest_getlen, SUDO_DEBUG_UTIL)
+ int gcry_digest_type;
+
+ gcry_digest_type = sudo_digest_type_to_gcry(digest_type);
+ if (gcry_digest_type == -1)
+ debug_return_int(-1);
+
+ debug_return_int(gcry_md_get_algo_dlen(gcry_digest_type));
+}
+
+void
+sudo_digest_update_v1(struct sudo_digest *dig, const void *data, size_t len)
+{
+ debug_decl(sudo_digest_update, SUDO_DEBUG_UTIL)
+
+ gcry_md_write(dig->ctx, data, len);
+
+ debug_return;
+}
+
+void
+sudo_digest_final_v1(struct sudo_digest *dig, unsigned char *md)
+{
+ debug_decl(sudo_digest_final, SUDO_DEBUG_UTIL)
+
+ gcry_md_final(dig->ctx);
+ memcpy(md, gcry_md_read(dig->ctx, 0), dig->digest_len);
+
+ debug_return;
+}
diff --git a/lib/util/digest_openssl.c b/lib/util/digest_openssl.c
new file mode 100644
index 0000000..af09684
--- /dev/null
+++ b/lib/util/digest_openssl.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2013-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <openssl/sha.h>
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_digest.h"
+
+union ANY_CTX {
+ SHA256_CTX sha256;
+ SHA512_CTX sha512;
+};
+
+static struct digest_function {
+ const unsigned int digest_len;
+ int (*init)(union ANY_CTX *);
+ int (*update)(union ANY_CTX *, const void *, size_t);
+ int (*final)(unsigned char *, union ANY_CTX *);
+} digest_functions[] = {
+ {
+ SHA224_DIGEST_LENGTH,
+ (int (*)(union ANY_CTX *))SHA224_Init,
+ (int (*)(union ANY_CTX *, const void *, size_t))SHA224_Update,
+ (int (*)(unsigned char *, union ANY_CTX *))SHA224_Final
+ }, {
+ SHA256_DIGEST_LENGTH,
+ (int (*)(union ANY_CTX *))SHA256_Init,
+ (int (*)(union ANY_CTX *, const void *, size_t))SHA256_Update,
+ (int (*)(unsigned char *, union ANY_CTX *))SHA256_Final
+ }, {
+ SHA384_DIGEST_LENGTH,
+ (int (*)(union ANY_CTX *))SHA384_Init,
+ (int (*)(union ANY_CTX *, const void *, size_t))SHA384_Update,
+ (int (*)(unsigned char *, union ANY_CTX *))SHA384_Final
+ }, {
+ SHA512_DIGEST_LENGTH,
+ (int (*)(union ANY_CTX *))SHA512_Init,
+ (int (*)(union ANY_CTX *, const void *, size_t))SHA512_Update,
+ (int (*)(unsigned char *, union ANY_CTX *))SHA512_Final
+ }, {
+ 0
+ }
+};
+
+struct sudo_digest {
+ struct digest_function *func;
+ union ANY_CTX ctx;
+};
+
+struct sudo_digest *
+sudo_digest_alloc_v1(int digest_type)
+{
+ debug_decl(sudo_digest_alloc, SUDO_DEBUG_UTIL)
+ struct digest_function *func = NULL;
+ struct sudo_digest *dig;
+ int i;
+
+ for (i = 0; digest_functions[i].digest_len != 0; i++) {
+ if (digest_type == i) {
+ func = &digest_functions[i];
+ break;
+ }
+ }
+ if (func == NULL) {
+ errno = EINVAL;
+ debug_return_ptr(NULL);
+ }
+
+ if ((dig = malloc(sizeof(*dig))) == NULL)
+ debug_return_ptr(NULL);
+ func->init(&dig->ctx);
+ dig->func = func;
+
+ debug_return_ptr(dig);
+}
+
+void
+sudo_digest_free_v1(struct sudo_digest *dig)
+{
+ debug_decl(sudo_digest_free, SUDO_DEBUG_UTIL)
+
+ free(dig);
+
+ debug_return;
+}
+
+void
+sudo_digest_reset_v1(struct sudo_digest *dig)
+{
+ debug_decl(sudo_digest_reset, SUDO_DEBUG_UTIL)
+
+ dig->func->init(&dig->ctx);
+
+ debug_return;
+}
+int
+sudo_digest_getlen_v1(int digest_type)
+{
+ debug_decl(sudo_digest_getlen, SUDO_DEBUG_UTIL)
+ int i;
+
+ for (i = 0; digest_functions[i].digest_len != 0; i++) {
+ if (digest_type == i)
+ debug_return_int(digest_functions[i].digest_len);
+ }
+
+ debug_return_int(-1);
+}
+
+void
+sudo_digest_update_v1(struct sudo_digest *dig, const void *data, size_t len)
+{
+ debug_decl(sudo_digest_update, SUDO_DEBUG_UTIL)
+
+ dig->func->update(&dig->ctx, data, len);
+
+ debug_return;
+}
+
+void
+sudo_digest_final_v1(struct sudo_digest *dig, unsigned char *md)
+{
+ debug_decl(sudo_digest_final, SUDO_DEBUG_UTIL)
+
+ dig->func->final(md, &dig->ctx);
+
+ debug_return;
+}
diff --git a/lib/util/event.c b/lib/util/event.c
new file mode 100644
index 0000000..05b3fd0
--- /dev/null
+++ b/lib/util/event.c
@@ -0,0 +1,798 @@
+/*
+ * Copyright (c) 2013-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <errno.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_debug.h"
+#include "sudo_event.h"
+#include "sudo_util.h"
+
+static void sudo_ev_init(struct sudo_event *ev, int fd, short events,
+ sudo_ev_callback_t callback, void *closure);
+
+/* Default event base when none is specified. */
+static struct sudo_event_base *default_base;
+
+/* We need the event base to be available from the signal handler. */
+static struct sudo_event_base *signal_base;
+
+/*
+ * Add an event to the base's active queue and mark it active.
+ * This is extern so sudo_ev_scan_impl() can call it.
+ */
+void
+sudo_ev_activate(struct sudo_event_base *base, struct sudo_event *ev)
+{
+ TAILQ_INSERT_TAIL(&base->active, ev, active_entries);
+ SET(ev->flags, SUDO_EVQ_ACTIVE);
+}
+
+/*
+ * Remove an event from the base's active queue and mark it inactive.
+ */
+static inline void
+sudo_ev_deactivate(struct sudo_event_base *base, struct sudo_event *ev)
+{
+ CLR(ev->flags, SUDO_EVQ_ACTIVE);
+ TAILQ_REMOVE(&base->active, ev, active_entries);
+}
+
+/*
+ * Clear out the base's active queue and mark all events as inactive.
+ */
+static void
+sudo_ev_deactivate_all(struct sudo_event_base *base)
+{
+ struct sudo_event *ev;
+ debug_decl(sudo_ev_deactivate_all, SUDO_DEBUG_EVENT)
+
+ while ((ev = TAILQ_FIRST(&base->active)) != NULL)
+ sudo_ev_deactivate(base, ev);
+
+ debug_return;
+}
+
+/*
+ * Activate all signal events for which the corresponding signal_pending[]
+ * flag is set.
+ */
+static void
+sudo_ev_activate_sigevents(struct sudo_event_base *base)
+{
+ struct sudo_event *ev;
+ sigset_t set, oset;
+ int i;
+ debug_decl(sudo_ev_activate_sigevents, SUDO_DEBUG_EVENT)
+
+ /*
+ * We treat this as a critical section since the signal handler
+ * could modify the siginfo[] entry.
+ */
+ sigfillset(&set);
+ sigprocmask(SIG_BLOCK, &set, &oset);
+ base->signal_caught = 0;
+ for (i = 0; i < NSIG; i++) {
+ if (!base->signal_pending[i])
+ continue;
+ base->signal_pending[i] = 0;
+ TAILQ_FOREACH(ev, &base->signals[i], entries) {
+ if (ISSET(ev->events, SUDO_EV_SIGINFO)) {
+ struct sudo_ev_siginfo_container *sc = ev->closure;
+ if (base->siginfo[i]->si_signo == 0) {
+ /* No siginfo available. */
+ sc->siginfo = NULL;
+ } else {
+ sc->siginfo = (siginfo_t *)sc->si_buf;
+ memcpy(sc->siginfo, base->siginfo[i], sizeof(siginfo_t));
+ }
+ }
+ /* Make event active. */
+ ev->revents = ev->events & (SUDO_EV_SIGNAL|SUDO_EV_SIGINFO);
+ TAILQ_INSERT_TAIL(&base->active, ev, active_entries);
+ SET(ev->flags, SUDO_EVQ_ACTIVE);
+ }
+ }
+ sigprocmask(SIG_SETMASK, &oset, NULL);
+
+ debug_return;
+}
+
+/*
+ * Internal callback for SUDO_EV_SIGNAL and SUDO_EV_SIGINFO.
+ */
+static void
+signal_pipe_cb(int fd, int what, void *v)
+{
+ struct sudo_event_base *base = v;
+ unsigned char ch;
+ ssize_t nread;
+ debug_decl(signal_pipe_cb, SUDO_DEBUG_EVENT)
+
+ /*
+ * Drain signal_pipe, the signal handler updated base->signals_pending.
+ * Actual processing of signal events is done when poll/select is
+ * interrupted by a signal.
+ */
+ while ((nread = read(fd, &ch, 1)) > 0) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: received signal %d", __func__, (int)ch);
+ }
+ if (nread == -1 && errno != EAGAIN) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "%s: error reading from signal pipe fd %d", __func__, fd);
+ }
+
+ /* Activate signal events. */
+ sudo_ev_activate_sigevents(base);
+
+ debug_return;
+}
+
+static int
+sudo_ev_base_init(struct sudo_event_base *base)
+{
+ int i;
+ debug_decl(sudo_ev_base_init, SUDO_DEBUG_EVENT)
+
+ TAILQ_INIT(&base->events);
+ TAILQ_INIT(&base->timeouts);
+ for (i = 0; i < NSIG; i++)
+ TAILQ_INIT(&base->signals[i]);
+ if (sudo_ev_base_alloc_impl(base) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "%s: unable to allocate impl base", __func__);
+ goto bad;
+ }
+ if (pipe2(base->signal_pipe, O_NONBLOCK|O_CLOEXEC) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "%s: unable to create signal pipe", __func__);
+ goto bad;
+ }
+ sudo_ev_init(&base->signal_event, base->signal_pipe[0],
+ SUDO_EV_READ|SUDO_EV_PERSIST, signal_pipe_cb, base);
+
+ debug_return_int(0);
+bad:
+ /* Note: signal_pipe[] not filled in. */
+ sudo_ev_base_free_impl(base);
+ debug_return_int(-1);
+}
+
+struct sudo_event_base *
+sudo_ev_base_alloc_v1(void)
+{
+ struct sudo_event_base *base;
+ debug_decl(sudo_ev_base_alloc, SUDO_DEBUG_EVENT)
+
+ base = calloc(1, sizeof(*base));
+ if (base == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: unable to allocate base", __func__);
+ debug_return_ptr(NULL);
+ }
+ if (sudo_ev_base_init(base) != 0) {
+ free(base);
+ debug_return_ptr(NULL);
+ }
+ debug_return_ptr(base);
+}
+
+void
+sudo_ev_base_free_v1(struct sudo_event_base *base)
+{
+ struct sudo_event *ev, *next;
+ int i;
+ debug_decl(sudo_ev_base_free, SUDO_DEBUG_EVENT)
+
+ if (base == NULL)
+ debug_return;
+
+ /* Reset the default base if necessary. */
+ if (default_base == base)
+ default_base = NULL;
+
+ /* Remove any existing events before freeing the base. */
+ TAILQ_FOREACH_SAFE(ev, &base->events, entries, next) {
+ sudo_ev_del(base, ev);
+ }
+ for (i = 0; i < NSIG; i++) {
+ TAILQ_FOREACH_SAFE(ev, &base->signals[i], entries, next) {
+ sudo_ev_del(base, ev);
+ }
+ free(base->siginfo[i]);
+ free(base->orig_handlers[i]);
+ }
+ sudo_ev_base_free_impl(base);
+ close(base->signal_pipe[0]);
+ close(base->signal_pipe[1]);
+ free(base);
+
+ debug_return;
+}
+
+void
+sudo_ev_base_setdef_v1(struct sudo_event_base *base)
+{
+ debug_decl(sudo_ev_base_setdef, SUDO_DEBUG_EVENT)
+
+ default_base = base;
+
+ debug_return;
+}
+
+/*
+ * Clear and fill in a struct sudo_event.
+ */
+static void
+sudo_ev_init(struct sudo_event *ev, int fd, short events,
+ sudo_ev_callback_t callback, void *closure)
+{
+ debug_decl(sudo_ev_init, SUDO_DEBUG_EVENT)
+
+ /* XXX - sanity check events value */
+ memset(ev, 0, sizeof(*ev));
+ ev->fd = fd;
+ ev->events = events;
+ ev->pfd_idx = -1;
+ ev->callback = callback;
+ ev->closure = closure;
+
+ debug_return;
+}
+
+struct sudo_event *
+sudo_ev_alloc_v1(int fd, short events, sudo_ev_callback_t callback, void *closure)
+{
+ struct sudo_event *ev;
+ debug_decl(sudo_ev_alloc, SUDO_DEBUG_EVENT)
+
+ ev = malloc(sizeof(*ev));
+ if (ev == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: unable to allocate event", __func__);
+ debug_return_ptr(NULL);
+ }
+ /* For SUDO_EV_SIGINFO we use a container to store closure + siginfo_t */
+ if (ISSET(events, SUDO_EV_SIGINFO)) {
+ struct sudo_ev_siginfo_container *container =
+ malloc(sizeof(*container) + sizeof(siginfo_t) - 1);
+ if (container == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: unable to allocate siginfo container", __func__);
+ free(ev);
+ debug_return_ptr(NULL);
+ }
+ container->closure = closure;
+ closure = container;
+ }
+ sudo_ev_init(ev, fd, events, callback, closure);
+
+ debug_return_ptr(ev);
+}
+
+void
+sudo_ev_free_v1(struct sudo_event *ev)
+{
+ debug_decl(sudo_ev_free, SUDO_DEBUG_EVENT)
+
+ if (ev == NULL)
+ debug_return;
+
+ /* Make sure ev is not in use before freeing it. */
+ if (ISSET(ev->flags, SUDO_EVQ_INSERTED))
+ (void)sudo_ev_del(NULL, ev);
+ if (ISSET(ev->events, SUDO_EV_SIGINFO))
+ free(ev->closure);
+ free(ev);
+
+ debug_return;
+}
+
+static void
+sudo_ev_handler(int signo, siginfo_t *info, void *context)
+{
+ unsigned char ch = (unsigned char)signo;
+
+ if (signal_base != NULL) {
+ /*
+ * Update signals_pending[] and siginfo[].
+ * All signals must be blocked any time siginfo[] is accessed.
+ * If no siginfo available, zero out the struct in base.
+ */
+ if (info == NULL)
+ memset(signal_base->siginfo[signo], 0, sizeof(*info));
+ else
+ memcpy(signal_base->siginfo[signo], info, sizeof(*info));
+ signal_base->signal_pending[signo] = 1;
+ signal_base->signal_caught = 1;
+
+ /* Wake up the other end of the pipe. */
+ ignore_result(write(signal_base->signal_pipe[1], &ch, 1));
+ }
+}
+
+static int
+sudo_ev_add_signal(struct sudo_event_base *base, struct sudo_event *ev,
+ bool tohead)
+{
+ const int signo = ev->fd;
+ debug_decl(sudo_ev_add_signal, SUDO_DEBUG_EVENT)
+
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: adding event %p to base %p, signal %d, events %d",
+ __func__, ev, base, signo, ev->events);
+ if (signo >= NSIG) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: signo %d larger than max %d", __func__, signo, NSIG - 1);
+ debug_return_int(-1);
+ }
+ if ((ev->events & ~(SUDO_EV_SIGNAL|SUDO_EV_SIGINFO|SUDO_EV_PERSIST)) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: invalid event set 0x%x", __func__, ev->events);
+ debug_return_int(-1);
+ }
+
+ /*
+ * Allocate base->siginfo[signo] and base->orig_handlers[signo] as needed.
+ */
+ if (base->siginfo[signo] == NULL) {
+ base->siginfo[signo] = malloc(sizeof(*base->siginfo[signo]));
+ if (base->siginfo[signo] == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: unable to allocate siginfo for signo %d",
+ __func__, signo);
+ debug_return_int(-1);
+ }
+ }
+ if (base->orig_handlers[signo] == NULL) {
+ base->orig_handlers[signo] =
+ malloc(sizeof(*base->orig_handlers[signo]));
+ if (base->orig_handlers[signo] == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: unable to allocate orig_handlers for signo %d",
+ __func__, signo);
+ debug_return_int(-1);
+ }
+ }
+
+ /* Install signal handler as needed, saving the original value. */
+ if (TAILQ_EMPTY(&base->signals[signo])) {
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sigfillset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART|SA_SIGINFO;
+ sa.sa_sigaction = sudo_ev_handler;
+ if (sigaction(signo, &sa, base->orig_handlers[signo]) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: unable to install handler for signo %d", __func__, signo);
+ debug_return_int(-1);
+ }
+ base->num_handlers++;
+ }
+
+ /*
+ * Insert signal event into the proper tail queue.
+ * Signal events are always persistent.
+ */
+ ev->base = base;
+ if (tohead) {
+ TAILQ_INSERT_HEAD(&base->signals[signo], ev, entries);
+ } else {
+ TAILQ_INSERT_TAIL(&base->signals[signo], ev, entries);
+ }
+ SET(ev->events, SUDO_EV_PERSIST);
+ SET(ev->flags, SUDO_EVQ_INSERTED);
+
+ /* Add the internal signal_pipe event on demand. */
+ if (!ISSET(base->signal_event.flags, SUDO_EVQ_INSERTED))
+ sudo_ev_add(base, &base->signal_event, NULL, true);
+
+ /* Update global signal base so handler to update signals_pending[] */
+ signal_base = base;
+
+ debug_return_int(0);
+}
+
+int
+sudo_ev_add_v1(struct sudo_event_base *base, struct sudo_event *ev,
+ struct timeval *timo, bool tohead)
+{
+ struct timespec tsbuf, *ts = NULL;
+
+ if (timo != NULL) {
+ TIMEVAL_TO_TIMESPEC(timo, &tsbuf);
+ ts = &tsbuf;
+ }
+
+ return sudo_ev_add_v2(base, ev, ts, tohead);
+}
+
+int
+sudo_ev_add_v2(struct sudo_event_base *base, struct sudo_event *ev,
+ struct timespec *timo, bool tohead)
+{
+ debug_decl(sudo_ev_add, SUDO_DEBUG_EVENT)
+
+ /* If no base specified, use existing or default base. */
+ if (base == NULL) {
+ if (ev->base != NULL) {
+ base = ev->base;
+ } else if (default_base != NULL) {
+ base = default_base;
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "%s: no base specified",
+ __func__);
+ debug_return_int(-1);
+ }
+ }
+
+ /* Only add new events to the events list. */
+ if (ISSET(ev->flags, SUDO_EVQ_INSERTED)) {
+ /* If event no longer has a timeout, remove from timeouts queue. */
+ if (timo == NULL && ISSET(ev->flags, SUDO_EVQ_TIMEOUTS)) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: removing event %p from timeouts queue", __func__, ev);
+ CLR(ev->flags, SUDO_EVQ_TIMEOUTS);
+ TAILQ_REMOVE(&base->timeouts, ev, timeouts_entries);
+ }
+ } else {
+ /* Special handling for signal events. */
+ if (ev->events & (SUDO_EV_SIGNAL|SUDO_EV_SIGINFO))
+ debug_return_int(sudo_ev_add_signal(base, ev, tohead));
+
+ /* Add event to the base. */
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: adding event %p to base %p, fd %d, events %d",
+ __func__, ev, base, ev->fd, ev->events);
+ if (ev->events & (SUDO_EV_READ|SUDO_EV_WRITE)) {
+ if (sudo_ev_add_impl(base, ev) != 0)
+ debug_return_int(-1);
+ }
+ ev->base = base;
+ if (tohead) {
+ TAILQ_INSERT_HEAD(&base->events, ev, entries);
+ } else {
+ TAILQ_INSERT_TAIL(&base->events, ev, entries);
+ }
+ SET(ev->flags, SUDO_EVQ_INSERTED);
+ }
+ /* Timeouts can be changed for existing events. */
+ if (timo != NULL) {
+ struct sudo_event *evtmp;
+ if (ISSET(ev->flags, SUDO_EVQ_TIMEOUTS)) {
+ /* Remove from timeouts list, then add back. */
+ TAILQ_REMOVE(&base->timeouts, ev, timeouts_entries);
+ }
+ /* Convert to absolute time and insert in sorted order; O(n). */
+ sudo_gettime_mono(&ev->timeout);
+ sudo_timespecadd(&ev->timeout, timo, &ev->timeout);
+ TAILQ_FOREACH(evtmp, &base->timeouts, timeouts_entries) {
+ if (sudo_timespeccmp(timo, &evtmp->timeout, <))
+ break;
+ }
+ if (evtmp != NULL) {
+ TAILQ_INSERT_BEFORE(evtmp, ev, timeouts_entries);
+ } else {
+ TAILQ_INSERT_TAIL(&base->timeouts, ev, timeouts_entries);
+ }
+ SET(ev->flags, SUDO_EVQ_TIMEOUTS);
+ }
+ debug_return_int(0);
+}
+
+/*
+ * Remove an event from the base, if specified, or the base embedded
+ * in the event if not. Note that there are multiple tail queues.
+ */
+int
+sudo_ev_del_v1(struct sudo_event_base *base, struct sudo_event *ev)
+{
+ debug_decl(sudo_ev_del, SUDO_DEBUG_EVENT)
+
+ /* Make sure event is really in the queue. */
+ if (!ISSET(ev->flags, SUDO_EVQ_INSERTED)) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: event %p not in queue",
+ __func__, ev);
+ debug_return_int(0);
+ }
+
+ /* Check for event base mismatch, if one is specified. */
+ if (base == NULL) {
+ if (ev->base == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "%s: no base specified",
+ __func__);
+ debug_return_int(-1);
+ }
+ base = ev->base;
+ } else if (base != ev->base) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "%s: mismatch base %p, ev->base %p",
+ __func__, base, ev->base);
+ debug_return_int(-1);
+ }
+
+ if (ev->events & (SUDO_EV_SIGNAL|SUDO_EV_SIGINFO)) {
+ const int signo = ev->fd;
+
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: removing event %p from base %p, signo %d, events %d",
+ __func__, ev, base, signo, ev->events);
+
+ /* Unlink from signal event list. */
+ TAILQ_REMOVE(&base->signals[signo], ev, entries);
+ if (TAILQ_EMPTY(&base->signals[signo])) {
+ if (sigaction(signo, base->orig_handlers[signo], NULL) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: unable to restore handler for signo %d",
+ __func__, signo);
+ debug_return_int(-1);
+ }
+ base->num_handlers--;
+ }
+ if (base->num_handlers == 0) {
+ /* No registered signal events, remove internal event. */
+ sudo_ev_del(base, &base->signal_event);
+ }
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: removing event %p from base %p, fd %d, events %d",
+ __func__, ev, base, ev->fd, ev->events);
+
+ /* Call backend. */
+ if (ev->events & (SUDO_EV_READ|SUDO_EV_WRITE)) {
+ if (sudo_ev_del_impl(base, ev) != 0)
+ debug_return_int(-1);
+ }
+
+ /* Unlink from event list. */
+ TAILQ_REMOVE(&base->events, ev, entries);
+
+ /* Unlink from timeouts list. */
+ if (ISSET(ev->flags, SUDO_EVQ_TIMEOUTS))
+ TAILQ_REMOVE(&base->timeouts, ev, timeouts_entries);
+ }
+
+ /* Unlink from active list. */
+ if (ISSET(ev->flags, SUDO_EVQ_ACTIVE))
+ TAILQ_REMOVE(&base->active, ev, active_entries);
+
+ /* Mark event unused. */
+ ev->flags = 0;
+ ev->pfd_idx = -1;
+
+ debug_return_int(0);
+}
+
+int
+sudo_ev_dispatch_v1(struct sudo_event_base *base)
+{
+ return sudo_ev_loop_v1(base, 0);
+}
+
+/*
+ * Run main event loop.
+ * Returns 0 on success, 1 if no events registered and -1 on error
+ */
+int
+sudo_ev_loop_v1(struct sudo_event_base *base, int flags)
+{
+ struct timespec now;
+ struct sudo_event *ev;
+ int nready, rc = 0;
+ debug_decl(sudo_ev_loop, SUDO_DEBUG_EVENT)
+
+ /*
+ * If sudo_ev_loopexit() was called when events were not running
+ * the next invocation of sudo_ev_loop() only runs once.
+ * All other base flags are ignored unless we are running events.
+ * Note that SUDO_EVLOOP_ONCE and SUDO_EVBASE_LOOPONCE are equivalent.
+ */
+ base->flags |= (flags & SUDO_EVLOOP_ONCE);
+ base->flags &= (SUDO_EVBASE_LOOPEXIT|SUDO_EVBASE_LOOPONCE);
+
+ for (;;) {
+rescan:
+ /* Make sure we have some events. */
+ if (TAILQ_EMPTY(&base->events)) {
+ rc = 1;
+ break;
+ }
+
+ /* Call backend to scan for I/O events. */
+ TAILQ_INIT(&base->active);
+ nready = sudo_ev_scan_impl(base, flags);
+ switch (nready) {
+ case -1:
+ if (errno == ENOMEM)
+ continue;
+ if (errno == EINTR) {
+ /* Interrupted by signal, check for sigevents. */
+ if (base->signal_caught) {
+ signal_pipe_cb(base->signal_pipe[0], SUDO_EV_READ, base);
+ break;
+ }
+ continue;
+ }
+ rc = -1;
+ goto done;
+ case 0:
+ /* Timed out, activate timeout events. */
+ sudo_gettime_mono(&now);
+ while ((ev = TAILQ_FIRST(&base->timeouts)) != NULL) {
+ if (sudo_timespeccmp(&ev->timeout, &now, >))
+ break;
+ /* Remove from timeouts list. */
+ CLR(ev->flags, SUDO_EVQ_TIMEOUTS);
+ TAILQ_REMOVE(&base->timeouts, ev, timeouts_entries);
+ /* Make event active. */
+ ev->revents = SUDO_EV_TIMEOUT;
+ TAILQ_INSERT_TAIL(&base->active, ev, active_entries);
+ SET(ev->flags, SUDO_EVQ_ACTIVE);
+ }
+ if (ISSET(flags, SUDO_EVLOOP_NONBLOCK)) {
+ /* If nonblocking, return immediately if no active events. */
+ if (TAILQ_EMPTY(&base->active))
+ goto done;
+ }
+ break;
+ default:
+ /* I/O events active, sudo_ev_scan_impl() already added them. */
+ break;
+ }
+
+ /*
+ * Service each event in the active queue.
+ * We store the current event pointer in the base so that
+ * it can be cleared by sudo_ev_del(). This prevents a use
+ * after free if the callback frees its own event.
+ */
+ while ((ev = TAILQ_FIRST(&base->active)) != NULL) {
+ /* Pop first event off the active queue. */
+ sudo_ev_deactivate(base, ev);
+ /* Remove from base unless persistent. */
+ if (!ISSET(ev->events, SUDO_EV_PERSIST))
+ sudo_ev_del(base, ev);
+ ev->callback(ev->fd, ev->revents,
+ ev->closure == sudo_ev_self_cbarg() ? ev : ev->closure);
+ if (ISSET(base->flags, SUDO_EVBASE_LOOPBREAK)) {
+ /* Stop processing events immediately. */
+ SET(base->flags, SUDO_EVBASE_GOT_BREAK);
+ sudo_ev_deactivate_all(base);
+ goto done;
+ }
+ if (ISSET(base->flags, SUDO_EVBASE_LOOPCONT)) {
+ /* Rescan events and start polling again. */
+ CLR(base->flags, SUDO_EVBASE_LOOPCONT);
+ sudo_ev_deactivate_all(base);
+ goto rescan;
+ }
+ }
+ if (ISSET(base->flags, SUDO_EVBASE_LOOPONCE)) {
+ /* SUDO_EVBASE_LOOPEXIT is always set w/ SUDO_EVBASE_LOOPONCE */
+ if (ISSET(base->flags, SUDO_EVBASE_LOOPEXIT))
+ SET(base->flags, SUDO_EVBASE_GOT_EXIT);
+ sudo_ev_deactivate_all(base);
+ break;
+ }
+ }
+done:
+ base->flags &= SUDO_EVBASE_GOT_MASK;
+ debug_return_int(rc);
+}
+
+void
+sudo_ev_loopexit_v1(struct sudo_event_base *base)
+{
+ debug_decl(sudo_ev_loopexit, SUDO_DEBUG_EVENT)
+ /* SUDO_EVBASE_LOOPBREAK trumps SUDO_EVBASE_LOOPEXIT */
+ if (!ISSET(base->flags, SUDO_EVBASE_LOOPBREAK)) {
+ /* SUDO_EVBASE_LOOPEXIT trumps SUDO_EVBASE_LOOPCONT */
+ CLR(base->flags, SUDO_EVBASE_LOOPCONT);
+ SET(base->flags, (SUDO_EVBASE_LOOPEXIT|SUDO_EVBASE_LOOPONCE));
+ }
+ debug_return;
+}
+
+void
+sudo_ev_loopbreak_v1(struct sudo_event_base *base)
+{
+ debug_decl(sudo_ev_loopbreak, SUDO_DEBUG_EVENT)
+ /* SUDO_EVBASE_LOOPBREAK trumps SUDO_EVBASE_LOOP{CONT,EXIT,ONCE}. */
+ CLR(base->flags, (SUDO_EVBASE_LOOPCONT|SUDO_EVBASE_LOOPEXIT|SUDO_EVBASE_LOOPONCE));
+ SET(base->flags, SUDO_EVBASE_LOOPBREAK);
+ debug_return;
+}
+
+void
+sudo_ev_loopcontinue_v1(struct sudo_event_base *base)
+{
+ debug_decl(sudo_ev_loopcontinue, SUDO_DEBUG_EVENT)
+ /* SUDO_EVBASE_LOOP{BREAK,EXIT} trumps SUDO_EVBASE_LOOPCONT */
+ if (!ISSET(base->flags, SUDO_EVBASE_LOOPONCE|SUDO_EVBASE_LOOPBREAK)) {
+ SET(base->flags, SUDO_EVBASE_LOOPCONT);
+ }
+ debug_return;
+}
+
+bool
+sudo_ev_got_exit_v1(struct sudo_event_base *base)
+{
+ debug_decl(sudo_ev_got_exit, SUDO_DEBUG_EVENT)
+ debug_return_bool(ISSET(base->flags, SUDO_EVBASE_GOT_EXIT));
+}
+
+bool
+sudo_ev_got_break_v1(struct sudo_event_base *base)
+{
+ debug_decl(sudo_ev_got_break, SUDO_DEBUG_EVENT)
+ debug_return_bool(ISSET(base->flags, SUDO_EVBASE_GOT_BREAK));
+}
+
+int
+sudo_ev_get_timeleft_v1(struct sudo_event *ev, struct timeval *tv)
+{
+ struct timespec ts;
+ int ret;
+
+ ret = sudo_ev_get_timeleft_v2(ev, &ts);
+ TIMESPEC_TO_TIMEVAL(tv, &ts);
+
+ return ret;
+}
+
+int
+sudo_ev_get_timeleft_v2(struct sudo_event *ev, struct timespec *ts)
+{
+ struct timespec now;
+ debug_decl(sudo_ev_get_timeleft, SUDO_DEBUG_EVENT)
+
+ if (!ISSET(ev->flags, SUDO_EVQ_TIMEOUTS)) {
+ sudo_timespecclear(ts);
+ debug_return_int(-1);
+ }
+
+ sudo_gettime_mono(&now);
+ sudo_timespecsub(&ev->timeout, &now, ts);
+ if (ts->tv_sec < 0)
+ sudo_timespecclear(ts);
+ debug_return_int(0);
+}
diff --git a/lib/util/event_poll.c b/lib/util/event_poll.c
new file mode 100644
index 0000000..22cda24
--- /dev/null
+++ b/lib/util/event_poll.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2013-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <time.h>
+#include <unistd.h>
+#include <errno.h>
+#include <poll.h>
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+#include "sudo_fatal.h"
+#include "sudo_debug.h"
+#include "sudo_event.h"
+
+int
+sudo_ev_base_alloc_impl(struct sudo_event_base *base)
+{
+ int i;
+ debug_decl(sudo_ev_base_alloc_impl, SUDO_DEBUG_EVENT)
+
+ base->pfd_high = -1;
+ base->pfd_max = 32;
+ base->pfds = reallocarray(NULL, base->pfd_max, sizeof(struct pollfd));
+ if (base->pfds == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: unable to allocate %d pollfds", __func__, base->pfd_max);
+ base->pfd_max = 0;
+ debug_return_int(-1);
+ }
+ for (i = 0; i < base->pfd_max; i++) {
+ base->pfds[i].fd = -1;
+ }
+
+ debug_return_int(0);
+}
+
+void
+sudo_ev_base_free_impl(struct sudo_event_base *base)
+{
+ debug_decl(sudo_ev_base_free_impl, SUDO_DEBUG_EVENT)
+ free(base->pfds);
+ debug_return;
+}
+
+int
+sudo_ev_add_impl(struct sudo_event_base *base, struct sudo_event *ev)
+{
+ struct pollfd *pfd;
+ debug_decl(sudo_ev_add_impl, SUDO_DEBUG_EVENT)
+
+ /* If out of space in pfds array, realloc. */
+ if (base->pfd_free == base->pfd_max) {
+ struct pollfd *pfds;
+ int i;
+
+ pfds =
+ reallocarray(base->pfds, base->pfd_max, 2 * sizeof(struct pollfd));
+ if (pfds == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: unable to allocate %d pollfds", __func__, base->pfd_max * 2);
+ debug_return_int(-1);
+ }
+ base->pfds = pfds;
+ base->pfd_max *= 2;
+ for (i = base->pfd_free; i < base->pfd_max; i++) {
+ base->pfds[i].fd = -1;
+ }
+ }
+
+ /* Fill in pfd entry. */
+ ev->pfd_idx = base->pfd_free;
+ pfd = &base->pfds[ev->pfd_idx];
+ pfd->fd = ev->fd;
+ pfd->events = 0;
+ if (ISSET(ev->events, SUDO_EV_READ))
+ pfd->events |= POLLIN;
+ if (ISSET(ev->events, SUDO_EV_WRITE))
+ pfd->events |= POLLOUT;
+
+ /* Update pfd_high and pfd_free. */
+ if (ev->pfd_idx > base->pfd_high)
+ base->pfd_high = ev->pfd_idx;
+ for (;;) {
+ if (++base->pfd_free == base->pfd_max)
+ break;
+ if (base->pfds[base->pfd_free].fd == -1)
+ break;
+ }
+
+ debug_return_int(0);
+}
+
+int
+sudo_ev_del_impl(struct sudo_event_base *base, struct sudo_event *ev)
+{
+ debug_decl(sudo_ev_del_impl, SUDO_DEBUG_EVENT)
+
+ /* Mark pfd entry unused, add to free list and adjust high slot. */
+ base->pfds[ev->pfd_idx].fd = -1;
+ if (ev->pfd_idx < base->pfd_free)
+ base->pfd_free = ev->pfd_idx;
+ while (base->pfd_high >= 0 && base->pfds[base->pfd_high].fd == -1)
+ base->pfd_high--;
+
+ debug_return_int(0);
+}
+
+#ifdef HAVE_PPOLL
+static int
+sudo_ev_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timo)
+{
+ return ppoll(fds, nfds, timo, NULL);
+}
+#else
+static int
+sudo_ev_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timo)
+{
+ const int timeout =
+ timo ? (timo->tv_sec * 1000) + (timo->tv_nsec / 1000000) : -1;
+
+ return poll(fds, nfds, timeout);
+}
+#endif /* HAVE_PPOLL */
+
+int
+sudo_ev_scan_impl(struct sudo_event_base *base, int flags)
+{
+ struct timespec now, ts, *timeout;
+ struct sudo_event *ev;
+ int nready;
+ debug_decl(sudo_ev_scan_impl, SUDO_DEBUG_EVENT)
+
+ if ((ev = TAILQ_FIRST(&base->timeouts)) != NULL) {
+ sudo_gettime_mono(&now);
+ sudo_timespecsub(&ev->timeout, &now, &ts);
+ if (ts.tv_sec < 0)
+ sudo_timespecclear(&ts);
+ timeout = &ts;
+ } else {
+ if (ISSET(flags, SUDO_EVLOOP_NONBLOCK)) {
+ sudo_timespecclear(&ts);
+ timeout = &ts;
+ } else {
+ timeout = NULL;
+ }
+ }
+
+ nready = sudo_ev_poll(base->pfds, base->pfd_high + 1, timeout);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %d fds ready", __func__, nready);
+ switch (nready) {
+ case -1:
+ /* Error or interrupted by signal. */
+ debug_return_int(-1);
+ case 0:
+ /* Front end will activate timeout events. */
+ break;
+ default:
+ /* Activate each I/O event that fired. */
+ TAILQ_FOREACH(ev, &base->events, entries) {
+ if (ev->pfd_idx != -1 && base->pfds[ev->pfd_idx].revents) {
+ int what = 0;
+ if (base->pfds[ev->pfd_idx].revents & (POLLIN|POLLHUP|POLLNVAL|POLLERR))
+ what |= (ev->events & SUDO_EV_READ);
+ if (base->pfds[ev->pfd_idx].revents & (POLLOUT|POLLHUP|POLLNVAL|POLLERR))
+ what |= (ev->events & SUDO_EV_WRITE);
+ /* Make event active. */
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s: polled fd %d, events %d, activating %p",
+ __func__, ev->fd, what, ev);
+ ev->revents = what;
+ sudo_ev_activate(base, ev);
+ }
+ }
+ break;
+ }
+ debug_return_int(nready);
+}
diff --git a/lib/util/event_select.c b/lib/util/event_select.c
new file mode 100644
index 0000000..a733633
--- /dev/null
+++ b/lib/util/event_select.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2013-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/param.h> /* for howmany() on Linux */
+#include <sys/time.h>
+#ifdef HAVE_SYS_SYSMACROS_H
+# include <sys/sysmacros.h> /* for howmany() on Solaris */
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H */
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <time.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+#include "sudo_fatal.h"
+#include "sudo_debug.h"
+#include "sudo_event.h"
+
+int
+sudo_ev_base_alloc_impl(struct sudo_event_base *base)
+{
+ debug_decl(sudo_ev_base_alloc_impl, SUDO_DEBUG_EVENT)
+
+ base->maxfd = NFDBITS - 1;
+ base->readfds_in = calloc(1, sizeof(fd_mask));
+ base->writefds_in = calloc(1, sizeof(fd_mask));
+ base->readfds_out = calloc(1, sizeof(fd_mask));
+ base->writefds_out = calloc(1, sizeof(fd_mask));
+
+ if (base->readfds_in == NULL || base->writefds_in == NULL ||
+ base->readfds_out == NULL || base->writefds_out == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: unable to calloc(1, %zu)", __func__, sizeof(fd_mask));
+ sudo_ev_base_free_impl(base);
+ debug_return_int(-1);
+ }
+ debug_return_int(0);
+}
+
+void
+sudo_ev_base_free_impl(struct sudo_event_base *base)
+{
+ debug_decl(sudo_ev_base_free_impl, SUDO_DEBUG_EVENT)
+ free(base->readfds_in);
+ free(base->writefds_in);
+ free(base->readfds_out);
+ free(base->writefds_out);
+ debug_return;
+}
+
+int
+sudo_ev_add_impl(struct sudo_event_base *base, struct sudo_event *ev)
+{
+ debug_decl(sudo_ev_add_impl, SUDO_DEBUG_EVENT)
+
+ /* If out of space in fd sets, realloc. */
+ if (ev->fd > base->maxfd) {
+ const int o = (base->maxfd + 1) / NFDBITS;
+ const int n = howmany(ev->fd + 1, NFDBITS);
+ const size_t used_bytes = o * sizeof(fd_mask);
+ const size_t new_bytes = (n - o) * sizeof(fd_mask);
+ fd_set *rfds_in, *wfds_in, *rfds_out, *wfds_out;
+
+ rfds_in = reallocarray(base->readfds_in, n, sizeof(fd_mask));
+ wfds_in = reallocarray(base->writefds_in, n, sizeof(fd_mask));
+ rfds_out = reallocarray(base->readfds_out, n, sizeof(fd_mask));
+ wfds_out = reallocarray(base->writefds_out, n, sizeof(fd_mask));
+ if (rfds_in == NULL || wfds_in == NULL ||
+ rfds_out == NULL || wfds_out == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: unable to reallocarray(%d, %zu)",
+ __func__, n, sizeof(fd_mask));
+ free(rfds_in);
+ free(wfds_in);
+ free(rfds_out);
+ free(wfds_out);
+ debug_return_int(-1);
+ }
+
+ /* Clear newly allocated space. */
+ memset((char *)rfds_in + used_bytes, 0, new_bytes);
+ memset((char *)wfds_in + used_bytes, 0, new_bytes);
+ memset((char *)rfds_out + used_bytes, 0, new_bytes);
+ memset((char *)wfds_out + used_bytes, 0, new_bytes);
+
+ /* Update base. */
+ base->readfds_in = rfds_in;
+ base->writefds_in = wfds_in;
+ base->readfds_out = rfds_out;
+ base->writefds_out = wfds_out;
+ base->maxfd = (n * NFDBITS) - 1;
+ }
+
+ /* Set events and adjust high fd as needed. */
+ if (ISSET(ev->events, SUDO_EV_READ)) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: added fd %d to readfs",
+ __func__, ev->fd);
+ FD_SET(ev->fd, base->readfds_in);
+ }
+ if (ISSET(ev->events, SUDO_EV_WRITE)) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: added fd %d to writefds",
+ __func__, ev->fd);
+ FD_SET(ev->fd, base->writefds_in);
+ }
+ if (ev->fd > base->highfd)
+ base->highfd = ev->fd;
+
+ debug_return_int(0);
+}
+
+int
+sudo_ev_del_impl(struct sudo_event_base *base, struct sudo_event *ev)
+{
+ debug_decl(sudo_ev_del_impl, SUDO_DEBUG_EVENT)
+
+ /* Remove from readfds and writefds and adjust high fd. */
+ if (ISSET(ev->events, SUDO_EV_READ)) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: removed fd %d from readfds",
+ __func__, ev->fd);
+ FD_CLR(ev->fd, base->readfds_in);
+ }
+ if (ISSET(ev->events, SUDO_EV_WRITE)) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: removed fd %d from writefds",
+ __func__, ev->fd);
+ FD_CLR(ev->fd, base->writefds_in);
+ }
+ if (base->highfd == ev->fd) {
+ for (;;) {
+ if (FD_ISSET(base->highfd, base->readfds_in) ||
+ FD_ISSET(base->highfd, base->writefds_in))
+ break;
+ if (--base->highfd < 0)
+ break;
+ }
+ }
+
+ debug_return_int(0);
+}
+
+#ifdef HAVE_PSELECT
+static int
+sudo_ev_select(int nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, const struct timespec *timeout)
+{
+ return pselect(nfds, readfds, writefds, exceptfds, timeout, NULL);
+}
+#else
+static int
+sudo_ev_select(int nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, const struct timespec *timeout)
+{
+ struct timeval tvbuf, *tv = NULL;
+
+ if (timeout != NULL) {
+ TIMESPEC_TO_TIMEVAL(&tvbuf, timeout);
+ tv = &tvbuf;
+ }
+ return select(nfds, readfds, writefds, exceptfds, tv);
+}
+#endif /* HAVE_PSELECT */
+
+int
+sudo_ev_scan_impl(struct sudo_event_base *base, int flags)
+{
+ struct timespec now, ts, *timeout;
+ struct sudo_event *ev;
+ size_t setsize;
+ int nready;
+ debug_decl(sudo_ev_loop, SUDO_DEBUG_EVENT)
+
+ if ((ev = TAILQ_FIRST(&base->timeouts)) != NULL) {
+ sudo_gettime_mono(&now);
+ sudo_timespecsub(&ev->timeout, &now, &ts);
+ if (ts.tv_sec < 0)
+ sudo_timespecclear(&ts);
+ timeout = &ts;
+ } else {
+ if (ISSET(flags, SUDO_EVLOOP_NONBLOCK)) {
+ sudo_timespecclear(&ts);
+ timeout = &ts;
+ } else {
+ timeout = NULL;
+ }
+ }
+
+ /* select() overwrites readfds/writefds so make a copy. */
+ setsize = howmany(base->highfd + 1, NFDBITS) * sizeof(fd_mask);
+ memcpy(base->readfds_out, base->readfds_in, setsize);
+ memcpy(base->writefds_out, base->writefds_in, setsize);
+
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: select high fd %d",
+ __func__, base->highfd);
+ nready = sudo_ev_select(base->highfd + 1, base->readfds_out,
+ base->writefds_out, NULL, timeout);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %d fds ready", __func__, nready);
+ switch (nready) {
+ case -1:
+ /* Error or interrupted by signal. */
+ debug_return_int(-1);
+ case 0:
+ /* Front end will activate timeout events. */
+ break;
+ default:
+ /* Activate each I/O event that fired. */
+ TAILQ_FOREACH(ev, &base->events, entries) {
+ if (ev->fd >= 0) {
+ int what = 0;
+ if (FD_ISSET(ev->fd, base->readfds_out))
+ what |= (ev->events & SUDO_EV_READ);
+ if (FD_ISSET(ev->fd, base->writefds_out))
+ what |= (ev->events & SUDO_EV_WRITE);
+ if (what != 0) {
+ /* Make event active. */
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s: selected fd %d, events %d, activating %p",
+ __func__, ev->fd, what, ev);
+ ev->revents = what;
+ sudo_ev_activate(base, ev);
+ }
+ }
+ }
+ break;
+ }
+ debug_return_int(nready);
+}
diff --git a/lib/util/fatal.c b/lib/util/fatal.c
new file mode 100644
index 0000000..645b590
--- /dev/null
+++ b/lib/util/fatal.c
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2004-2005, 2010-2015, 2017-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+
+#define DEFAULT_TEXT_DOMAIN "sudo"
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_queue.h"
+#include "sudo_util.h"
+#include "sudo_plugin.h"
+
+#ifndef HAVE_GETADDRINFO
+# include "compat/getaddrinfo.h"
+#endif
+
+struct sudo_fatal_callback {
+ SLIST_ENTRY(sudo_fatal_callback) entries;
+ void (*func)(void);
+};
+SLIST_HEAD(sudo_fatal_callback_list, sudo_fatal_callback);
+
+static struct sudo_fatal_callback_list callbacks = SLIST_HEAD_INITIALIZER(&callbacks);
+static sudo_conv_t sudo_warn_conversation;
+static bool (*sudo_warn_setlocale)(bool, int *);
+static bool (*sudo_warn_setlocale_prev)(bool, int *);
+
+static void warning(const char *errstr, const char *fmt, va_list ap);
+
+static void
+do_cleanup(void)
+{
+ struct sudo_fatal_callback *cb;
+
+ /* Run callbacks, removing them from the list as we go. */
+ while ((cb = SLIST_FIRST(&callbacks)) != NULL) {
+ SLIST_REMOVE_HEAD(&callbacks, entries);
+ cb->func();
+ free(cb);
+ }
+}
+
+void
+sudo_fatal_nodebug_v1(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ warning(strerror(errno), fmt, ap);
+ va_end(ap);
+ do_cleanup();
+ exit(EXIT_FAILURE);
+}
+
+void
+sudo_fatalx_nodebug_v1(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ warning(NULL, fmt, ap);
+ va_end(ap);
+ do_cleanup();
+ exit(EXIT_FAILURE);
+}
+
+void
+sudo_vfatal_nodebug_v1(const char *fmt, va_list ap)
+{
+ warning(strerror(errno), fmt, ap);
+ do_cleanup();
+ exit(EXIT_FAILURE);
+}
+
+void
+sudo_vfatalx_nodebug_v1(const char *fmt, va_list ap)
+{
+ warning(NULL, fmt, ap);
+ do_cleanup();
+ exit(EXIT_FAILURE);
+}
+
+void
+sudo_warn_nodebug_v1(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ warning(strerror(errno), fmt, ap);
+ va_end(ap);
+}
+
+void
+sudo_warnx_nodebug_v1(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ warning(NULL, fmt, ap);
+ va_end(ap);
+}
+
+void
+sudo_vwarn_nodebug_v1(const char *fmt, va_list ap)
+{
+ warning(strerror(errno), fmt, ap);
+}
+
+void
+sudo_vwarnx_nodebug_v1(const char *fmt, va_list ap)
+{
+ warning(NULL, fmt, ap);
+}
+
+void
+sudo_gai_fatal_nodebug_v1(int errnum, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ warning(gai_strerror(errnum), fmt, ap);
+ va_end(ap);
+ do_cleanup();
+ exit(EXIT_FAILURE);
+}
+
+void
+sudo_gai_vfatal_nodebug_v1(int errnum, const char *fmt, va_list ap)
+{
+ warning(gai_strerror(errnum), fmt, ap);
+ do_cleanup();
+ exit(EXIT_FAILURE);
+}
+
+void
+sudo_gai_warn_nodebug_v1(int errnum, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ warning(gai_strerror(errnum), fmt, ap);
+ va_end(ap);
+}
+
+void
+sudo_gai_vwarn_nodebug_v1(int errnum, const char *fmt, va_list ap)
+{
+ warning(gai_strerror(errnum), fmt, ap);
+}
+
+static void
+warning(const char *errstr, const char *fmt, va_list ap)
+{
+ int cookie;
+
+ /* Set user locale if setter was specified. */
+ if (sudo_warn_setlocale != NULL)
+ sudo_warn_setlocale(false, &cookie);
+
+ if (sudo_warn_conversation != NULL) {
+ struct sudo_conv_message msgs[6];
+ char static_buf[1024], *buf = static_buf;
+ int nmsgs = 0;
+
+ /* Use conversation function. */
+ msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
+ msgs[nmsgs++].msg = getprogname();
+ if (fmt != NULL) {
+ va_list ap2;
+ int buflen;
+
+ /* Use static buffer if possible, else dynamic. */
+ va_copy(ap2, ap);
+ buflen = vsnprintf(static_buf, sizeof(static_buf), fmt, ap2);
+ va_end(ap2);
+ if (buflen >= (int)sizeof(static_buf)) {
+ buf = malloc(++buflen);
+ if (buf != NULL)
+ (void)vsnprintf(buf, buflen, fmt, ap);
+ else
+ buf = static_buf;
+ }
+ msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
+ msgs[nmsgs++].msg = ": ";
+ msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
+ msgs[nmsgs++].msg = buf;
+ }
+ if (errstr != NULL) {
+ msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
+ msgs[nmsgs++].msg = ": ";
+ msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
+ msgs[nmsgs++].msg = errstr;
+ }
+ msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
+ msgs[nmsgs++].msg = "\n";
+ sudo_warn_conversation(nmsgs, msgs, NULL, NULL);
+ if (buf != static_buf)
+ free(buf);
+ } else {
+ /* Write to the standard error. */
+ fputs(getprogname(), stderr);
+ if (fmt != NULL) {
+ fputs(": ", stderr);
+ vfprintf(stderr, fmt, ap);
+ }
+ if (errstr != NULL) {
+ fputs(": ", stderr);
+ fputs(errstr, stderr);
+ }
+ putc('\n', stderr);
+ }
+
+ /* Restore old locale as needed. */
+ if (sudo_warn_setlocale != NULL)
+ sudo_warn_setlocale(true, &cookie);
+}
+
+/*
+ * Register a callback to be run when sudo_fatal()/sudo_fatalx() is called.
+ */
+int
+sudo_fatal_callback_register_v1(sudo_fatal_callback_t func)
+{
+ struct sudo_fatal_callback *cb;
+
+ /* Do not register the same callback twice. */
+ SLIST_FOREACH(cb, &callbacks, entries) {
+ if (func == cb->func)
+ return -1; /* dupe! */
+ }
+
+ /* Allocate and insert new callback. */
+ cb = malloc(sizeof(*cb));
+ if (cb == NULL)
+ return -1;
+ cb->func = func;
+ SLIST_INSERT_HEAD(&callbacks, cb, entries);
+
+ return 0;
+}
+
+/*
+ * Deregister a sudo_fatal()/sudo_fatalx() callback.
+ */
+int
+sudo_fatal_callback_deregister_v1(sudo_fatal_callback_t func)
+{
+ struct sudo_fatal_callback *cb, **prev;
+
+ /* Search for callback and remove if found, dupes are not allowed. */
+ SLIST_FOREACH_PREVPTR(cb, prev, &callbacks, entries) {
+ if (cb->func == func) {
+ if (cb == SLIST_FIRST(&callbacks))
+ SLIST_REMOVE_HEAD(&callbacks, entries);
+ else
+ SLIST_REMOVE_AFTER(*prev, entries);
+ free(cb);
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+/*
+ * Set the conversation function to use for output insteaf of the
+ * standard error. If conv is NULL, switch back to standard error.
+ */
+void
+sudo_warn_set_conversation_v1(sudo_conv_t conv)
+{
+ sudo_warn_conversation = conv;
+}
+
+/*
+ * Set the locale function so the plugin can use a non-default
+ * locale for user warnings.
+ */
+void
+sudo_warn_set_locale_func_v1(bool (*func)(bool, int *))
+{
+ sudo_warn_setlocale_prev = sudo_warn_setlocale;
+ sudo_warn_setlocale = func;
+}
+
+#ifdef HAVE_LIBINTL_H
+char *
+sudo_warn_gettext_v1(const char *domainname, const char *msgid)
+{
+ int cookie;
+ char *msg;
+
+ /* Set user locale if setter was specified. */
+ if (sudo_warn_setlocale != NULL)
+ sudo_warn_setlocale(false, &cookie);
+
+ msg = dgettext(domainname, msgid);
+
+ /* Restore old locale as needed. */
+ if (sudo_warn_setlocale != NULL)
+ sudo_warn_setlocale(true, &cookie);
+
+ return msg;
+}
+#endif /* HAVE_LIBINTL_H */
diff --git a/lib/util/fnmatch.c b/lib/util/fnmatch.c
new file mode 100644
index 0000000..3526fda
--- /dev/null
+++ b/lib/util/fnmatch.c
@@ -0,0 +1,502 @@
+/* $OpenBSD: fnmatch.c,v 1.15 2011/02/10 21:31:59 stsp Exp $ */
+
+/* Copyright (c) 2011, VMware, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the VMware, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2008, 2016 Todd C. Miller <millert@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+/* Authored by William A. Rowe Jr. <wrowe; apache.org, vmware.com>, April 2011
+ *
+ * Derived from The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2008
+ * as described in;
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/fnmatch.html
+ *
+ * Filename pattern matches defined in section 2.13, "Pattern Matching Notation"
+ * from chapter 2. "Shell Command Language"
+ * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13
+ * where; 1. A bracket expression starting with an unquoted <circumflex> '^'
+ * character CONTINUES to specify a non-matching list; 2. an explicit <period> '.'
+ * in a bracket expression matching list, e.g. "[.abc]" does NOT match a leading
+ * <period> in a filename; 3. a <left-square-bracket> '[' which does not introduce
+ * a valid bracket expression is treated as an ordinary character; 4. a differing
+ * number of consecutive slashes within pattern and string will NOT match;
+ * 5. a trailing '\' in FNM_ESCAPE mode is treated as an ordinary '\' character.
+ *
+ * Bracket expansion defined in section 9.3.5, "RE Bracket Expression",
+ * from chapter 9, "Regular Expressions"
+ * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05
+ * with no support for collating symbols, equivalence class expressions or
+ * character class expressions. A partial range expression with a leading
+ * hyphen following a valid range expression will match only the ordinary
+ * <hyphen> and the ending character (e.g. "[a-m-z]" will match characters
+ * 'a' through 'm', a <hyphen> '-', or a 'z').
+ *
+ * Supports BSD extensions FNM_LEADING_DIR to match pattern to the end of one
+ * path segment of string, and FNM_CASEFOLD to ignore alpha case.
+ *
+ * NOTE: Only POSIX/C single byte locales are correctly supported at this time.
+ * Notably, non-POSIX locales with FNM_CASEFOLD produce undefined results,
+ * particularly in ranges of mixed case (e.g. "[A-z]") or spanning alpha and
+ * nonalpha characters within a range.
+ *
+ * XXX comments below indicate porting required for multi-byte character sets
+ * and non-POSIX locale collation orders; requires mbr* APIs to track shift
+ * state of pattern and string (rewinding pattern and string repeatedly).
+ *
+ * Certain parts of the code assume 0x00-0x3F are unique with any MBCS (e.g.
+ * UTF-8, SHIFT-JIS, etc). Any implementation allowing '\' as an alternate
+ * path delimiter must be aware that 0x5C is NOT unique within SHIFT-JIS.
+ */
+
+#include <config.h>
+
+#ifndef HAVE_FNMATCH
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "sudo_compat.h"
+#include "compat/charclass.h"
+#include "compat/fnmatch.h"
+
+#define RANGE_MATCH 1
+#define RANGE_NOMATCH 0
+#define RANGE_ERROR (-1)
+
+static int
+classmatch(const char *pattern, char test, int foldcase, const char **ep)
+{
+ const char * const mismatch = pattern;
+ const char *colon;
+ struct cclass *cc;
+ int result = RANGE_NOMATCH;
+ size_t len;
+
+ if (pattern[0] != '[' || pattern[1] != ':') {
+ *ep = mismatch;
+ return RANGE_ERROR;
+ }
+ pattern += 2;
+
+ if ((colon = strchr(pattern, ':')) == NULL || colon[1] != ']') {
+ *ep = mismatch;
+ return RANGE_ERROR;
+ }
+ *ep = colon + 2;
+ len = (size_t)(colon - pattern);
+
+ if (foldcase && strncmp(pattern, "upper:]", 7) == 0)
+ pattern = "lower:]";
+ for (cc = cclasses; cc->name != NULL; cc++) {
+ if (!strncmp(pattern, cc->name, len) && cc->name[len] == '\0') {
+ if (cc->isctype((unsigned char)test))
+ result = RANGE_MATCH;
+ break;
+ }
+ }
+ if (cc->name == NULL) {
+ /* invalid character class, treat as normal text */
+ *ep = mismatch;
+ result = RANGE_ERROR;
+ }
+ return result;
+}
+
+/* Most MBCS/collation/case issues handled here. Wildcard '*' is not handled.
+ * EOS '\0' and the FNM_PATHNAME '/' delimiters are not advanced over,
+ * however the "\/" sequence is advanced to '/'.
+ *
+ * Both pattern and string are **char to support pointer increment of arbitrary
+ * multibyte characters for the given locale, in a later iteration of this code
+ */
+static int fnmatch_ch(const char **pattern, const char **string, int flags)
+{
+ const char * const mismatch = *pattern;
+ const int nocase = !!(flags & FNM_CASEFOLD);
+ const int escape = !(flags & FNM_NOESCAPE);
+ const int slash = !!(flags & FNM_PATHNAME);
+ int result = FNM_NOMATCH;
+ const char *startch;
+ int negate;
+
+ if (**pattern == '[')
+ {
+ ++*pattern;
+
+ /* Handle negation, either leading ! or ^ operators (never both) */
+ negate = ((**pattern == '!') || (**pattern == '^'));
+ if (negate)
+ ++*pattern;
+
+ /* ']' is an ordinary character at the start of the range pattern */
+ if (**pattern == ']')
+ goto leadingclosebrace;
+
+ while (**pattern)
+ {
+ if (**pattern == ']') {
+ ++*pattern;
+ /* XXX: Fix for MBCS character width */
+ ++*string;
+ return (result ^ negate);
+ }
+
+ if (escape && (**pattern == '\\')) {
+ ++*pattern;
+
+ /* Patterns must be terminated with ']', not EOS */
+ if (!**pattern)
+ break;
+ }
+
+ /* Patterns must be terminated with ']' not '/' */
+ if (slash && (**pattern == '/'))
+ break;
+
+ /* Match character classes. */
+ switch (classmatch(*pattern, **string, nocase, pattern)) {
+ case RANGE_MATCH:
+ result = 0;
+ continue;
+ case RANGE_NOMATCH:
+ /* Valid character class but no match. */
+ continue;
+ default:
+ /* Not a valid character class. */
+ break;
+ }
+ if (!**pattern)
+ break;
+
+leadingclosebrace:
+ /* Look at only well-formed range patterns;
+ * "x-]" is not allowed unless escaped ("x-\]")
+ * XXX: Fix for locale/MBCS character width
+ */
+ if (((*pattern)[1] == '-') && ((*pattern)[2] != ']'))
+ {
+ startch = *pattern;
+ *pattern += (escape && ((*pattern)[2] == '\\')) ? 3 : 2;
+
+ /* NOT a properly balanced [expr] pattern, EOS terminated
+ * or ranges containing a slash in FNM_PATHNAME mode pattern
+ * fall out to to the rewind and test '[' literal code path
+ */
+ if (!**pattern || (slash && (**pattern == '/')))
+ break;
+
+ /* XXX: handle locale/MBCS comparison, advance by MBCS char width */
+ if ((**string >= *startch) && (**string <= **pattern))
+ result = 0;
+ else if (nocase && (isupper((unsigned char)**string) ||
+ isupper((unsigned char)*startch) ||
+ isupper((unsigned char)**pattern))
+ && (tolower((unsigned char)**string) >= tolower((unsigned char)*startch))
+ && (tolower((unsigned char)**string) <= tolower((unsigned char)**pattern)))
+ result = 0;
+
+ ++*pattern;
+ continue;
+ }
+
+ /* XXX: handle locale/MBCS comparison, advance by MBCS char width */
+ if ((**string == **pattern))
+ result = 0;
+ else if (nocase && (isupper((unsigned char)**string) ||
+ isupper((unsigned char)**pattern))
+ && (tolower((unsigned char)**string) == tolower((unsigned char)**pattern)))
+ result = 0;
+
+ ++*pattern;
+ }
+
+ /* NOT a properly balanced [expr] pattern; Rewind
+ * and reset result to test '[' literal
+ */
+ *pattern = mismatch;
+ result = FNM_NOMATCH;
+ }
+ else if (**pattern == '?') {
+ /* Optimize '?' match before unescaping **pattern */
+ if (!**string || (slash && (**string == '/')))
+ return FNM_NOMATCH;
+ result = 0;
+ goto fnmatch_ch_success;
+ }
+ else if (escape && (**pattern == '\\') && (*pattern)[1]) {
+ ++*pattern;
+ }
+
+ /* XXX: handle locale/MBCS comparison, advance by the MBCS char width */
+ if (**string == **pattern)
+ result = 0;
+ else if (nocase && (isupper((unsigned char)**string) || isupper((unsigned char)**pattern))
+ && (tolower((unsigned char)**string) == tolower((unsigned char)**pattern)))
+ result = 0;
+
+ /* Refuse to advance over trailing slash or nulls
+ */
+ if (!**string || !**pattern || (slash && ((**string == '/') || (**pattern == '/'))))
+ return result;
+
+fnmatch_ch_success:
+ ++*pattern;
+ ++*string;
+ return result;
+}
+
+int sudo_fnmatch(const char *pattern, const char *string, int flags)
+{
+ static const char dummystring[2] = {' ', 0};
+ const int escape = !(flags & FNM_NOESCAPE);
+ const int slash = !!(flags & FNM_PATHNAME);
+ const int leading_dir = !!(flags & FNM_LEADING_DIR);
+ const char *strendseg;
+ const char *dummyptr;
+ const char *matchptr;
+ int wild;
+ /* For '*' wild processing only; surpress 'used before initialization'
+ * warnings with dummy initialization values;
+ */
+ const char *strstartseg = NULL;
+ const char *mismatch = NULL;
+ int matchlen = 0;
+
+ if (*pattern == '*')
+ goto firstsegment;
+
+ while (*pattern && *string)
+ {
+ /* Pre-decode "\/" which has no special significance, and
+ * match balanced slashes, starting a new segment pattern
+ */
+ if (slash && escape && (*pattern == '\\') && (pattern[1] == '/'))
+ ++pattern;
+ if (slash && (*pattern == '/') && (*string == '/')) {
+ ++pattern;
+ ++string;
+ }
+
+firstsegment:
+ /* At the beginning of each segment, validate leading period behavior.
+ */
+ if ((flags & FNM_PERIOD) && (*string == '.'))
+ {
+ if (*pattern == '.')
+ ++pattern;
+ else if (escape && (*pattern == '\\') && (pattern[1] == '.'))
+ pattern += 2;
+ else
+ return FNM_NOMATCH;
+ ++string;
+ }
+
+ /* Determine the end of string segment
+ *
+ * Presumes '/' character is unique, not composite in any MBCS encoding
+ */
+ if (slash) {
+ strendseg = strchr(string, '/');
+ if (!strendseg)
+ strendseg = strchr(string, '\0');
+ }
+ else {
+ strendseg = strchr(string, '\0');
+ }
+
+ /* Allow pattern '*' to be consumed even with no remaining string to match
+ */
+ while (*pattern)
+ {
+ if ((string > strendseg)
+ || ((string == strendseg) && (*pattern != '*')))
+ break;
+
+ if (slash && ((*pattern == '/')
+ || (escape && (*pattern == '\\')
+ && (pattern[1] == '/'))))
+ break;
+
+ /* Reduce groups of '*' and '?' to n '?' matches
+ * followed by one '*' test for simplicity
+ */
+ for (wild = 0; ((*pattern == '*') || (*pattern == '?')); ++pattern)
+ {
+ if (*pattern == '*') {
+ wild = 1;
+ }
+ else if (string < strendseg) { /* && (*pattern == '?') */
+ /* XXX: Advance 1 char for MBCS locale */
+ ++string;
+ }
+ else { /* (string >= strendseg) && (*pattern == '?') */
+ return FNM_NOMATCH;
+ }
+ }
+
+ if (wild)
+ {
+ strstartseg = string;
+ mismatch = pattern;
+
+ /* Count fixed (non '*') char matches remaining in pattern
+ * excluding '/' (or "\/") and '*'
+ */
+ for (matchptr = pattern, matchlen = 0; 1; ++matchlen)
+ {
+ if ((*matchptr == '\0')
+ || (slash && ((*matchptr == '/')
+ || (escape && (*matchptr == '\\')
+ && (matchptr[1] == '/')))))
+ {
+ /* Compare precisely this many trailing string chars,
+ * the resulting match needs no wildcard loop
+ */
+ /* XXX: Adjust for MBCS */
+ if (string + matchlen > strendseg)
+ return FNM_NOMATCH;
+
+ string = strendseg - matchlen;
+ wild = 0;
+ break;
+ }
+
+ if (*matchptr == '*')
+ {
+ /* Ensure at least this many trailing string chars remain
+ * for the first comparison
+ */
+ /* XXX: Adjust for MBCS */
+ if (string + matchlen > strendseg)
+ return FNM_NOMATCH;
+
+ /* Begin first wild comparison at the current position */
+ break;
+ }
+
+ /* Skip forward in pattern by a single character match
+ * Use a dummy fnmatch_ch() test to count one "[range]" escape
+ */
+ /* XXX: Adjust for MBCS */
+ if (escape && (*matchptr == '\\') && matchptr[1]) {
+ matchptr += 2;
+ }
+ else if (*matchptr == '[') {
+ dummyptr = dummystring;
+ fnmatch_ch(&matchptr, &dummyptr, flags);
+ }
+ else {
+ ++matchptr;
+ }
+ }
+ }
+
+ /* Incrementally match string against the pattern
+ */
+ while (*pattern && (string < strendseg))
+ {
+ /* Success; begin a new wild pattern search
+ */
+ if (*pattern == '*')
+ break;
+
+ if (slash && ((*string == '/')
+ || (*pattern == '/')
+ || (escape && (*pattern == '\\')
+ && (pattern[1] == '/'))))
+ break;
+
+ /* Compare ch's (the pattern is advanced over "\/" to the '/',
+ * but slashes will mismatch, and are not consumed)
+ */
+ if (!fnmatch_ch(&pattern, &string, flags))
+ continue;
+
+ /* Failed to match, loop against next char offset of string segment
+ * until not enough string chars remain to match the fixed pattern
+ */
+ if (wild) {
+ /* XXX: Advance 1 char for MBCS locale */
+ string = ++strstartseg;
+ if (string + matchlen > strendseg)
+ return FNM_NOMATCH;
+
+ pattern = mismatch;
+ continue;
+ }
+ else
+ return FNM_NOMATCH;
+ }
+ }
+
+ if (*string && !((slash || leading_dir) && (*string == '/')))
+ return FNM_NOMATCH;
+
+ if (*pattern && !(slash && ((*pattern == '/')
+ || (escape && (*pattern == '\\')
+ && (pattern[1] == '/')))))
+ return FNM_NOMATCH;
+
+ if (leading_dir && !*pattern && *string == '/')
+ return 0;
+ }
+
+ /* Where both pattern and string are at EOS, declare success
+ */
+ if (!*string && !*pattern)
+ return 0;
+
+ /* pattern didn't match to the end of string */
+ return FNM_NOMATCH;
+}
+#endif /* HAVE_FNMATCH */
diff --git a/lib/util/getaddrinfo.c b/lib/util/getaddrinfo.c
new file mode 100644
index 0000000..046e4db
--- /dev/null
+++ b/lib/util/getaddrinfo.c
@@ -0,0 +1,412 @@
+/*
+ * Replacement for a missing getaddrinfo.
+ *
+ * This is an implementation of getaddrinfo for systems that don't have one so
+ * that networking code can use a consistant interface without #ifdef. It is
+ * a fairly minimal implementation, with the following limitations:
+ *
+ * - IPv4 support only. IPv6 is not supported.
+ * - AI_ADDRCONFIG is ignored.
+ * - Not thread-safe due to gethostbyname and getservbyname.
+ * - SOCK_DGRAM and SOCK_STREAM only.
+ * - Multiple possible socket types only generate one addrinfo struct.
+ * - Protocol hints aren't used correctly.
+ *
+ * The last four issues could probably be easily remedied, but haven't been
+ * needed to date. Adding IPv6 support isn't worth it; systems with IPv6
+ * support should already support getaddrinfo natively.
+ *
+ * The canonical version of this file is maintained in the rra-c-util package,
+ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ *
+ * The authors hereby relinquish any claim to any copyright that they may have
+ * in this work, whether granted under contract or by operation of law or
+ * international treaty, and hereby commit to the public, at large, that they
+ * shall not, at any time in the future, seek to enforce any copyright in this
+ * work against any person or entity, or prevent any person or entity from
+ * copying, publishing, distributing or creating derivative works of this
+ * work.
+ */
+
+#include <config.h>
+
+#ifndef HAVE_GETADDRINFO
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <limits.h>
+#include <netdb.h>
+#include <errno.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#ifdef NEED_RESOLV_H
+# include <arpa/nameser.h>
+# include <resolv.h>
+#endif /* NEED_RESOLV_H */
+
+#include "sudo_compat.h"
+#include "compat/getaddrinfo.h"
+
+/* We need access to h_errno to map errors from gethostbyname. */
+#ifndef HAVE_DECL_H_ERRNO
+extern int h_errno;
+#endif
+
+/*
+ * The netdb constants, which aren't always defined (particularly if h_errno
+ * isn't declared). We also make sure that a few of the less-used ones are
+ * defined so that we can deal with them in case statements.
+ */
+#ifndef HOST_NOT_FOUND
+# define HOST_NOT_FOUND 1
+# define TRY_AGAIN 2
+# define NO_RECOVERY 3
+# define NO_DATA 4
+#endif
+#ifndef NETDB_INTERNAL
+# define NETDB_INTERNAL -1
+#endif
+
+/*
+ * If we're running the test suite, rename the functions to avoid conflicts
+ * with the system version. Note that we don't rename the structures and
+ * constants, but that should be okay (except possibly for gai_strerror).
+ */
+#ifdef TESTING
+# define gai_strerror test_gai_strerror
+# define freeaddrinfo test_freeaddrinfo
+# define getaddrinfo test_getaddrinfo
+const char *test_gai_strerror(int);
+void test_freeaddrinfo(struct addrinfo *);
+int test_getaddrinfo(const char *, const char *, const struct addrinfo *,
+ struct addrinfo **);
+#endif
+
+/*
+ * If the native platform doesn't support AI_NUMERICSERV or AI_NUMERICHOST,
+ * pick some other values for them.
+ */
+#ifdef TESTING
+# if AI_NUMERICSERV == 0
+# undef AI_NUMERICSERV
+# define AI_NUMERICSERV 0x0080
+# endif
+# if AI_NUMERICHOST == 0
+# undef AI_NUMERICHOST
+# define AI_NUMERICHOST 0x0100
+# endif
+#endif
+
+/*
+ * Value representing all of the hint flags set. Linux uses flags up to
+ * 0x0400, so be sure not to break when testing on that platform.
+ */
+#ifdef TESTING
+# ifdef HAVE_GETADDRINFO
+# define AI_INTERNAL_ALL 0x04ff
+# else
+# define AI_INTERNAL_ALL 0x01ff
+# endif
+#else
+# define AI_INTERNAL_ALL 0x007f
+#endif
+
+/* Table of strings corresponding to the EAI_* error codes. */
+static const char * const gai_errors[] = {
+ "Host name lookup failure", /* 1 EAI_AGAIN */
+ "Invalid flag value", /* 2 EAI_BADFLAGS */
+ "Unknown server error", /* 3 EAI_FAIL */
+ "Unsupported address family", /* 4 EAI_FAMILY */
+ "Memory allocation failure", /* 5 EAI_MEMORY */
+ "Host unknown or not given", /* 6 EAI_NONAME */
+ "Service not supported for socket", /* 7 EAI_SERVICE */
+ "Unsupported socket type", /* 8 EAI_SOCKTYPE */
+ "System error", /* 9 EAI_SYSTEM */
+ "Supplied buffer too small", /* 10 EAI_OVERFLOW */
+};
+
+/* Macro to set the len attribute of sockaddr_in. */
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+# define sin_set_length(s) ((s)->sin_len = sizeof(struct sockaddr_in))
+#else
+# define sin_set_length(s) /* empty */
+#endif
+
+/*
+ * Return a constant string for a given EAI_* error code or a string
+ * indicating an unknown error.
+ */
+const char *
+sudo_gai_strerror(int ecode)
+{
+ if (ecode < 1 || (size_t) ecode > nitems(gai_errors))
+ return "Unknown error";
+ else
+ return gai_errors[ecode - 1];
+}
+
+
+/*
+ * Free a linked list of addrinfo structs.
+ */
+void
+sudo_freeaddrinfo(struct addrinfo *ai)
+{
+ struct addrinfo *next;
+
+ while (ai != NULL) {
+ next = ai->ai_next;
+ if (ai->ai_addr != NULL)
+ free(ai->ai_addr);
+ if (ai->ai_canonname != NULL)
+ free(ai->ai_canonname);
+ free(ai);
+ ai = next;
+ }
+}
+
+
+/*
+ * Allocate a new addrinfo struct, setting some defaults given that this
+ * implementation is IPv4 only. Also allocates an attached sockaddr_in and
+ * zeroes it, per the requirement for getaddrinfo. Takes the socktype,
+ * canonical name (which is copied if not NULL), address, and port. Returns
+ * NULL on a memory allocation failure.
+ */
+static struct addrinfo *
+gai_addrinfo_new(int socktype, const char *canonical, struct in_addr addr,
+ unsigned short port)
+{
+ struct addrinfo *ai;
+
+ ai = malloc(sizeof(*ai));
+ if (ai == NULL)
+ return NULL;
+ ai->ai_addr = malloc(sizeof(struct sockaddr_in));
+ if (ai->ai_addr == NULL) {
+ free(ai);
+ return NULL;
+ }
+ ai->ai_next = NULL;
+ if (canonical == NULL)
+ ai->ai_canonname = NULL;
+ else {
+ ai->ai_canonname = strdup(canonical);
+ if (ai->ai_canonname == NULL) {
+ freeaddrinfo(ai);
+ return NULL;
+ }
+ }
+ memset(ai->ai_addr, 0, sizeof(struct sockaddr_in));
+ ai->ai_flags = 0;
+ ai->ai_family = AF_INET;
+ ai->ai_socktype = socktype;
+ ai->ai_protocol = (socktype == SOCK_DGRAM) ? IPPROTO_UDP : IPPROTO_TCP;
+ ai->ai_addrlen = sizeof(struct sockaddr_in);
+ ((struct sockaddr_in *) ai->ai_addr)->sin_family = AF_INET;
+ ((struct sockaddr_in *) ai->ai_addr)->sin_addr = addr;
+ ((struct sockaddr_in *) ai->ai_addr)->sin_port = htons(port);
+ sin_set_length((struct sockaddr_in *) ai->ai_addr);
+ return ai;
+}
+
+
+/*
+ * Look up a service. Takes the service name (which may be numeric), the hint
+ * flags, a pointer to the socket type (used to determine whether TCP or UDP
+ * services are of interest and, if 0, is filled in with the result of
+ * getservbyname if the service was not numeric), and a pointer to the
+ * addrinfo struct to fill in. Returns 0 on success or an EAI_* error on
+ * failure.
+ */
+static int
+gai_service(const char *servname, int flags, int *type, unsigned short *port)
+{
+ struct servent *servent;
+ const char *protocol;
+ const char *errstr;
+ unsigned short value;
+
+ value = strtonum(servname, 0, USHRT_MAX, &errstr);
+ if (errstr == NULL) {
+ *port = value;
+ } else if (errno == ERANGE) {
+ return EAI_SERVICE;
+ } else {
+ if (flags & AI_NUMERICSERV)
+ return EAI_NONAME;
+ if (*type != 0)
+ protocol = (*type == SOCK_DGRAM) ? "udp" : "tcp";
+ else
+ protocol = NULL;
+
+ /*
+ * We really technically should be generating an addrinfo struct for
+ * each possible protocol unless type is set, but this works well
+ * enough for what I need this for.
+ */
+ servent = getservbyname(servname, protocol);
+ if (servent == NULL)
+ return EAI_NONAME;
+ if (strcmp(servent->s_proto, "udp") == 0)
+ *type = SOCK_DGRAM;
+ else if (strcmp(servent->s_proto, "tcp") == 0)
+ *type = SOCK_STREAM;
+ else
+ return EAI_SERVICE;
+ *port = htons(servent->s_port);
+ }
+ return 0;
+}
+
+
+/*
+ * Look up a host and fill in a linked list of addrinfo structs with the
+ * results, one per IP address of the returned host. Takes the name or IP
+ * address of the host as a string, the lookup flags, the type of socket (to
+ * fill into the addrinfo structs), the port (likewise), and a pointer to
+ * where the head of the linked list should be put. Returns 0 on success or
+ * the appropriate EAI_* error.
+ */
+static int
+gai_lookup(const char *nodename, int flags, int socktype, unsigned short port,
+ struct addrinfo **res)
+{
+ struct addrinfo *ai, *first, *prev;
+ struct in_addr addr;
+ struct hostent *host;
+ const char *canonical;
+ int i;
+
+ if (inet_pton(AF_INET, nodename, &addr)) {
+ canonical = (flags & AI_CANONNAME) ? nodename : NULL;
+ ai = gai_addrinfo_new(socktype, canonical, addr, port);
+ if (ai == NULL)
+ return EAI_MEMORY;
+ *res = ai;
+ return 0;
+ } else {
+ if (flags & AI_NUMERICHOST)
+ return EAI_NONAME;
+ host = gethostbyname(nodename);
+ if (host == NULL)
+ switch (h_errno) {
+ case HOST_NOT_FOUND:
+ return EAI_NONAME;
+ case TRY_AGAIN:
+ case NO_DATA:
+ return EAI_AGAIN;
+ case NO_RECOVERY:
+ return EAI_FAIL;
+ case NETDB_INTERNAL:
+ default:
+ return EAI_SYSTEM;
+ }
+ if (host->h_addr_list[0] == NULL)
+ return EAI_FAIL;
+ canonical = (flags & AI_CANONNAME)
+ ? ((host->h_name != NULL) ? host->h_name : nodename)
+ : NULL;
+ first = NULL;
+ prev = NULL;
+ for (i = 0; host->h_addr_list[i] != NULL; i++) {
+ if (host->h_length != sizeof(addr)) {
+ freeaddrinfo(first);
+ return EAI_FAIL;
+ }
+ memcpy(&addr, host->h_addr_list[i], sizeof(addr));
+ ai = gai_addrinfo_new(socktype, canonical, addr, port);
+ if (ai == NULL) {
+ freeaddrinfo(first);
+ return EAI_MEMORY;
+ }
+ if (first == NULL) {
+ first = ai;
+ prev = ai;
+ } else {
+ prev->ai_next = ai;
+ prev = ai;
+ }
+ }
+ *res = first;
+ return 0;
+ }
+}
+
+
+/*
+ * The actual getaddrinfo implementation.
+ */
+int
+sudo_getaddrinfo(const char *nodename, const char *servname,
+ const struct addrinfo *hints, struct addrinfo **res)
+{
+ struct addrinfo *ai;
+ struct in_addr addr;
+ int flags, socktype, status;
+ unsigned short port;
+
+ /* Take the hints into account and check them for validity. */
+ if (hints != NULL) {
+ flags = hints->ai_flags;
+ socktype = hints->ai_socktype;
+ if ((flags & AI_INTERNAL_ALL) != flags)
+ return EAI_BADFLAGS;
+ if (hints->ai_family != AF_UNSPEC && hints->ai_family != AF_INET)
+ return EAI_FAMILY;
+ if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM)
+ return EAI_SOCKTYPE;
+
+ /* EAI_SOCKTYPE isn't quite right, but there isn't anything better. */
+ if (hints->ai_protocol != 0) {
+ int protocol = hints->ai_protocol;
+ if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP)
+ return EAI_SOCKTYPE;
+ }
+ } else {
+ flags = 0;
+ socktype = 0;
+ }
+
+ /*
+ * See what we're doing. If nodename is null, either AI_PASSIVE is set or
+ * we're getting information for connecting to a service on the loopback
+ * address. Otherwise, we're getting information for connecting to a
+ * remote system.
+ */
+ if (servname == NULL)
+ port = 0;
+ else {
+ status = gai_service(servname, flags, &socktype, &port);
+ if (status != 0)
+ return status;
+ }
+ if (nodename != NULL)
+ return gai_lookup(nodename, flags, socktype, port, res);
+ else {
+ if (servname == NULL)
+ return EAI_NONAME;
+ if ((flags & AI_PASSIVE) == AI_PASSIVE)
+ addr.s_addr = INADDR_ANY;
+ else
+ addr.s_addr = htonl(0x7f000001UL);
+ ai = gai_addrinfo_new(socktype, NULL, addr, port);
+ if (ai == NULL)
+ return EAI_MEMORY;
+ *res = ai;
+ return 0;
+ }
+}
+#endif /* HAVE_GETADDRINFO */
diff --git a/lib/util/getcwd.c b/lib/util/getcwd.c
new file mode 100644
index 0000000..b7f2012
--- /dev/null
+++ b/lib/util/getcwd.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 1989, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifndef HAVE_GETCWD
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <dirent.h>
+
+#include "sudo_compat.h"
+
+#define ISDOT(dp) \
+ (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
+ (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
+
+#if defined(HAVE_STRUCT_DIRENT_D_NAMLEN) && HAVE_STRUCT_DIRENT_D_NAMLEN
+# define NAMLEN(dirent) (dirent)->d_namlen
+#else
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#endif
+
+char *
+sudo_getcwd(char *pt, size_t size)
+{
+ struct dirent *dp;
+ DIR *dir = NULL;
+ dev_t dev;
+ ino_t ino;
+ int first;
+ char *bpt, *bup;
+ struct stat s;
+ dev_t root_dev;
+ ino_t root_ino;
+ size_t ptsize, upsize;
+ int save_errno;
+ char *ept, *eup, *up;
+
+ /*
+ * If no buffer specified by the user, allocate one as necessary.
+ * If a buffer is specified, the size has to be non-zero. The path
+ * is built from the end of the buffer backwards.
+ */
+ if (pt) {
+ ptsize = 0;
+ if (!size) {
+ errno = EINVAL;
+ return NULL;
+ }
+ ept = pt + size;
+ } else {
+ if ((pt = malloc(ptsize = 1024 - 4)) == NULL)
+ return NULL;
+ ept = pt + ptsize;
+ }
+ bpt = ept - 1;
+ *bpt = '\0';
+
+ /*
+ * Allocate bytes (1024 - malloc space) for the string of "../"'s.
+ * Should always be enough (it's 340 levels). If it's not, allocate
+ * as necessary. Special * case the first stat, it's ".", not "..".
+ */
+ if ((up = malloc(upsize = 1024 - 4)) == NULL)
+ goto err;
+ eup = up + PATH_MAX;
+ bup = up;
+ up[0] = '.';
+ up[1] = '\0';
+
+ /* Save root values, so know when to stop. */
+ if (stat("/", &s))
+ goto err;
+ root_dev = s.st_dev;
+ root_ino = s.st_ino;
+
+ errno = 0; /* XXX readdir has no error return. */
+
+ for (first = 1;; first = 0) {
+ /* Stat the current level. */
+ if (lstat(up, &s))
+ goto err;
+
+ /* Save current node values. */
+ ino = s.st_ino;
+ dev = s.st_dev;
+
+ /* Check for reaching root. */
+ if (root_dev == dev && root_ino == ino) {
+ *--bpt = '/';
+ /*
+ * It's unclear that it's a requirement to copy the
+ * path to the beginning of the buffer, but it's always
+ * been that way and stuff would probably break.
+ */
+ bcopy(bpt, pt, ept - bpt);
+ free(up);
+ return pt;
+ }
+
+ /*
+ * Build pointer to the parent directory, allocating memory
+ * as necessary. Max length is 3 for "../", the largest
+ * possible component name, plus a trailing NULL.
+ */
+ if (bup + 3 + MAXNAMLEN + 1 >= eup) {
+ char *nup;
+
+ if ((nup = reallocarray(up, upsize, 2)) == NULL)
+ goto err;
+ upsize *= 2;
+ up = nup;
+ bup = up;
+ eup = up + upsize;
+ }
+ *bup++ = '.';
+ *bup++ = '.';
+ *bup = '\0';
+
+ /* Open and stat parent directory. */
+ if (!(dir = opendir(up)) || fstat(dirfd(dir), &s))
+ goto err;
+
+ /* Add trailing slash for next directory. */
+ *bup++ = '/';
+
+ /*
+ * If it's a mount point, have to stat each element because
+ * the inode number in the directory is for the entry in the
+ * parent directory, not the inode number of the mounted file.
+ */
+ save_errno = 0;
+ if (s.st_dev == dev) {
+ for (;;) {
+ if (!(dp = readdir(dir)))
+ goto notfound;
+ if (dp->d_fileno == ino)
+ break;
+ }
+ } else
+ for (;;) {
+ if (!(dp = readdir(dir)))
+ goto notfound;
+ if (ISDOT(dp))
+ continue;
+ bcopy(dp->d_name, bup, NAMLEN(dp) + 1);
+
+ /* Save the first error for later. */
+ if (lstat(up, &s)) {
+ if (!save_errno)
+ save_errno = errno;
+ errno = 0;
+ continue;
+ }
+ if (s.st_dev == dev && s.st_ino == ino)
+ break;
+ }
+
+ /*
+ * Check for length of the current name, preceding slash,
+ * leading slash.
+ */
+ if (bpt - pt <= NAMLEN(dp) + (first ? 1 : 2)) {
+ size_t len, off;
+ char *npt;
+
+ if (!ptsize) {
+ errno = ERANGE;
+ goto err;
+ }
+ off = bpt - pt;
+ len = ept - bpt;
+ if ((npt = reallocarray(pt, ptsize, 2)) == NULL)
+ goto err;
+ ptsize *= 2;
+ pt = npt;
+ bpt = pt + off;
+ ept = pt + ptsize;
+ bcopy(bpt, ept - len, len);
+ bpt = ept - len;
+ }
+ if (!first)
+ *--bpt = '/';
+ bpt -= NAMLEN(dp);
+ bcopy(dp->d_name, bpt, NAMLEN(dp));
+ (void)closedir(dir);
+
+ /* Truncate any file name. */
+ *bup = '\0';
+ }
+
+notfound:
+ /*
+ * If readdir set errno, use it, not any saved error; otherwise,
+ * didn't find the current directory in its parent directory, set
+ * errno to ENOENT.
+ */
+ if (!errno)
+ errno = save_errno ? save_errno : ENOENT;
+ /* FALLTHROUGH */
+err:
+ if (ptsize)
+ free(pt);
+ if (up)
+ free(up);
+ if (dir)
+ (void)closedir(dir);
+ return NULL;
+}
+#endif /* HAVE_GETCWD */
diff --git a/lib/util/getentropy.c b/lib/util/getentropy.c
new file mode 100644
index 0000000..bfd7dcd
--- /dev/null
+++ b/lib/util/getentropy.c
@@ -0,0 +1,605 @@
+/*
+ * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
+ * Copyright (c) 2014 Bob Beck <beck@obtuse.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Emulation of getentropy(2) as documented at:
+ * http://man.openbsd.org/getentropy.2
+ */
+
+#include <config.h>
+
+#ifndef HAVE_GETENTROPY
+
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#ifdef HAVE_SYSCTL
+# include <sys/sysctl.h>
+#endif
+#ifdef HAVE_SYS_STATVFS_H
+# include <sys/statvfs.h>
+#endif
+#include <sys/stat.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_SYSCALL_H
+# include <sys/syscall.h>
+#endif
+#ifdef HAVE_LINUX_RANDOM_H
+# include <linux/types.h>
+# include <linux/random.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <time.h>
+#include <unistd.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#ifdef HAVE_GETAUXVAL
+# include <sys/auxv.h>
+#endif
+#ifdef HAVE_DL_ITERATE_PHDR
+# include <link.h>
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_digest.h"
+#include "sudo_rand.h"
+
+#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+
+#define REPEAT 5
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
+#define HX(a, b) \
+ do { \
+ if ((a)) \
+ HD(errno); \
+ else \
+ HD(b); \
+ } while (0)
+
+#define HR(x, l) (sudo_digest_update(ctx, (char *)(x), (l)))
+#define HD(x) (sudo_digest_update(ctx, (char *)&(x), sizeof (x)))
+#define HF(x) (sudo_digest_update(ctx, (char *)&(x), sizeof (void*)))
+
+int sudo_getentropy(void *buf, size_t len);
+
+static int getentropy_getrandom(void *buf, size_t len);
+static int getentropy_sysctl(void *buf, size_t len);
+static int getentropy_urandom(void *buf, size_t len, const char *path,
+ int devfscheck);
+static int getentropy_fallback(void *buf, size_t len);
+static int gotdata(char *buf, size_t len);
+#ifdef HAVE_DL_ITERATE_PHDR
+static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
+#endif
+
+int
+sudo_getentropy(void *buf, size_t len)
+{
+ int ret = -1;
+
+ if (len > 256) {
+ errno = EIO;
+ return (-1);
+ }
+
+ ret = getentropy_getrandom(buf, len);
+ if (ret != -1)
+ return (ret);
+
+ ret = getentropy_sysctl(buf, len);
+ if (ret != -1)
+ return (ret);
+
+ /*
+ * Try to get entropy with /dev/urandom
+ */
+ ret = getentropy_urandom(buf, len, "/dev/urandom", 0);
+ if (ret != -1)
+ return (ret);
+
+ /*
+ * Entropy collection via /dev/urandom has failed.
+ *
+ * No other API exists for collecting entropy, and we have no
+ * failsafe way to get it that is not sensitive to resource exhaustion.
+ *
+ * We have very few options:
+ * - Even syslog_r is unsafe to call at this low level, so
+ * there is no way to alert the user or program.
+ * - Cannot call abort() because some systems have unsafe
+ * corefiles.
+ * - Could raise(SIGKILL) resulting in silent program termination.
+ * - Return EIO, to hint that arc4random's stir function
+ * should raise(SIGKILL)
+ * - Do the best under the circumstances....
+ *
+ * This code path exists to bring light to the issue that the OS
+ * does not provide a failsafe API for entropy collection.
+ *
+ * We hope this demonstrates that the OS should consider
+ * providing a new failsafe API which works in a chroot or
+ * when file descriptors are exhausted.
+ */
+#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
+#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
+ raise(SIGKILL);
+#endif
+ ret = getentropy_fallback(buf, len);
+ if (ret != -1)
+ return (ret);
+
+ errno = EIO;
+ return (ret);
+}
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+/*
+ * Basic sanity checking; wish we could do better.
+ */
+static int
+gotdata(char *buf, size_t len)
+{
+ char any_set = 0;
+ size_t i;
+
+ for (i = 0; i < len; ++i)
+ any_set |= buf[i];
+ if (any_set == 0)
+ return (-1);
+ return (0);
+}
+
+static int
+getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck)
+{
+ struct stat st;
+ size_t i;
+ int fd, flags;
+ int save_errno = errno;
+
+start:
+
+ /* We do not use O_NOFOLLOW since /dev/urandom is a link on Solaris. */
+ flags = O_RDONLY;
+#ifdef O_CLOEXEC
+ flags |= O_CLOEXEC;
+#endif
+ fd = open(path, flags, 0);
+ if (fd == -1) {
+ if (errno == EINTR)
+ goto start;
+ goto nodevrandom;
+ }
+#ifndef O_CLOEXEC
+ fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+#endif
+
+ /* Lightly verify that the device node looks sane */
+ if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) {
+ close(fd);
+ goto nodevrandom;
+ }
+ for (i = 0; i < len; ) {
+ size_t wanted = len - i;
+ ssize_t ret = read(fd, (char *)buf + i, wanted);
+
+ if (ret == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ close(fd);
+ goto nodevrandom;
+ }
+ i += ret;
+ }
+ close(fd);
+ if (gotdata(buf, len) == 0) {
+ errno = save_errno;
+ return (0); /* satisfied */
+ }
+nodevrandom:
+ errno = EIO;
+ return (-1);
+}
+
+#if defined(HAVE_SYSCTL) && defined(KERN_ARND)
+static int
+getentropy_sysctl(void *buf, size_t len)
+{
+ int save_errno = errno;
+ int mib[2];
+ size_t i;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_ARND;
+
+ for (i = 0; i < len; ) {
+ size_t chunk = len - i;
+
+ if (sysctl(mib, 2, (char *)buf + i, &chunk, NULL, 0) == -1)
+ goto sysctlfailed;
+ i += chunk;
+ }
+ if (gotdata(buf, len) == 0) {
+ errno = save_errno;
+ return (0); /* satisfied */
+ }
+sysctlfailed:
+ errno = EIO;
+ return (-1);
+}
+#elif defined(SYS__sysctl) && defined(RANDOM_UUID)
+static int
+getentropy_sysctl(void *buf, size_t len)
+{
+ static int mib[3];
+ size_t i;
+ int save_errno = errno;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_RANDOM;
+ mib[2] = RANDOM_UUID;
+
+ for (i = 0; i < len; ) {
+ size_t chunk = min(len - i, 16);
+
+ /* SYS__sysctl because some systems already removed sysctl() */
+ struct __sysctl_args args = {
+ .name = mib,
+ .nlen = 3,
+ .oldval = (char *)buf + i,
+ .oldlenp = &chunk,
+ };
+ if (syscall(SYS__sysctl, &args) != 0)
+ goto sysctlfailed;
+ i += chunk;
+ }
+ if (gotdata(buf, len) == 0) {
+ errno = save_errno;
+ return (0); /* satisfied */
+ }
+sysctlfailed:
+ errno = EIO;
+ return (-1);
+}
+#else
+static int
+getentropy_sysctl(void *buf, size_t len)
+{
+ errno = ENOTSUP;
+ return (-1);
+}
+#endif
+
+#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
+static int
+getentropy_getrandom(void *buf, size_t len)
+{
+ int pre_errno = errno;
+ int ret;
+
+ /*
+ * Try descriptor-less getrandom(), in non-blocking mode.
+ *
+ * The design of Linux getrandom is broken. It has an
+ * uninitialized phase coupled with blocking behaviour, which
+ * is unacceptable from within a library at boot time without
+ * possible recovery. See http://bugs.python.org/issue26839#msg267745
+ */
+ do {
+ ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK);
+ } while (ret == -1 && errno == EINTR);
+
+ if (ret < 0 || (size_t)ret != len)
+ return (-1);
+ errno = pre_errno;
+ return (0);
+}
+#else
+static int
+getentropy_getrandom(void *buf, size_t len)
+{
+ errno = ENOTSUP;
+ return (-1);
+}
+#endif
+
+#ifdef HAVE_CLOCK_GETTIME
+static const int cl[] = {
+ CLOCK_REALTIME,
+#ifdef CLOCK_MONOTONIC
+ CLOCK_MONOTONIC,
+#endif
+#ifdef CLOCK_MONOTONIC_RAW
+ CLOCK_MONOTONIC_RAW,
+#endif
+#ifdef CLOCK_TAI
+ CLOCK_TAI,
+#endif
+#ifdef CLOCK_VIRTUAL
+ CLOCK_VIRTUAL,
+#endif
+#ifdef CLOCK_UPTIME
+ CLOCK_UPTIME,
+#endif
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+ CLOCK_PROCESS_CPUTIME_ID,
+#endif
+#ifdef CLOCK_THREAD_CPUTIME_ID
+ CLOCK_THREAD_CPUTIME_ID,
+#endif
+};
+#endif /* HAVE_CLOCK_GETTIME */
+
+#ifdef HAVE_DL_ITERATE_PHDR
+static int
+getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
+{
+ struct sudo_digest *ctx = data;
+
+ sudo_digest_update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
+ return (0);
+}
+#endif
+
+static int
+getentropy_fallback(void *buf, size_t len)
+{
+ unsigned char *results = NULL;
+ int save_errno = errno, e, pgs = sysconf(_SC_PAGESIZE), faster = 0, repeat;
+ int ret = -1;
+ static int cnt;
+ struct timespec ts;
+ struct timeval tv;
+ struct rusage ru;
+ sigset_t sigset;
+ struct stat st;
+ struct sudo_digest *ctx;
+ static pid_t lastpid;
+ pid_t pid;
+ size_t i, ii, m, digest_len;
+ char *p;
+
+ if ((ctx = sudo_digest_alloc(SUDO_DIGEST_SHA512)) == NULL)
+ goto done;
+ digest_len = sudo_digest_getlen(SUDO_DIGEST_SHA512);
+ if (digest_len == (size_t)-1 || (results = malloc(digest_len)) == NULL)
+ goto done;
+
+ pid = getpid();
+ if (lastpid == pid) {
+ faster = 1;
+ repeat = 2;
+ } else {
+ faster = 0;
+ lastpid = pid;
+ repeat = REPEAT;
+ }
+ for (i = 0; i < len; ) {
+ int j;
+ for (j = 0; j < repeat; j++) {
+ HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+ if (e != -1) {
+ cnt += (int)tv.tv_sec;
+ cnt += (int)tv.tv_usec;
+ }
+#ifdef HAVE_DL_ITERATE_PHDR
+ dl_iterate_phdr(getentropy_phdr, ctx);
+#endif
+
+#ifdef HAVE_CLOCK_GETTIME
+ for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
+ HX(clock_gettime(cl[ii], &ts) == -1, ts);
+#endif /* HAVE_CLOCK_GETTIME */
+
+ HX((pid = getpid()) == -1, pid);
+ HX((pid = getsid(pid)) == -1, pid);
+ HX((pid = getppid()) == -1, pid);
+ HX((pid = getpgid(0)) == -1, pid);
+ HX((e = getpriority(0, 0)) == -1, e);
+
+ if (!faster) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1;
+ (void) nanosleep(&ts, NULL);
+ }
+
+ HX(sigpending(&sigset) == -1, sigset);
+ HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
+ sigset);
+
+ HF(sudo_getentropy); /* an addr in this library */
+ HF(printf); /* an addr in libc */
+ p = (char *)&p;
+ HD(p); /* an addr on stack */
+ p = (char *)&errno;
+ HD(p); /* the addr of errno */
+
+ if (i == 0) {
+#ifdef HAVE_SYS_STATVFS_H
+ struct statvfs stvfs;
+#endif
+ struct termios tios;
+ off_t off;
+
+ /*
+ * Prime-sized mappings encourage fragmentation;
+ * thus exposing some address entropy.
+ */
+ struct mm {
+ size_t npg;
+ void *p;
+ } mm[] = {
+ { 17, MAP_FAILED }, { 3, MAP_FAILED },
+ { 11, MAP_FAILED }, { 2, MAP_FAILED },
+ { 5, MAP_FAILED }, { 3, MAP_FAILED },
+ { 7, MAP_FAILED }, { 1, MAP_FAILED },
+ { 57, MAP_FAILED }, { 3, MAP_FAILED },
+ { 131, MAP_FAILED }, { 1, MAP_FAILED },
+ };
+
+ for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+ HX(mm[m].p = mmap(NULL,
+ mm[m].npg * pgs,
+ PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANON, -1,
+ (off_t)0), mm[m].p);
+ if (mm[m].p != MAP_FAILED) {
+ size_t mo;
+
+ /* Touch some memory... */
+ p = mm[m].p;
+ mo = cnt %
+ (mm[m].npg * pgs - 1);
+ p[mo] = 1;
+ cnt += (int)((long)(mm[m].p)
+ / pgs);
+ }
+
+ /* Check cnts and times... */
+ for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
+ ii++) {
+ HX((e = clock_gettime(cl[ii],
+ &ts)) == -1, ts);
+ if (e != -1)
+ cnt += (int)ts.tv_nsec;
+ }
+
+ HX((e = getrusage(RUSAGE_SELF,
+ &ru)) == -1, ru);
+ if (e != -1) {
+ cnt += (int)ru.ru_utime.tv_sec;
+ cnt += (int)ru.ru_utime.tv_usec;
+ }
+ }
+
+ for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+ if (mm[m].p != MAP_FAILED)
+ munmap(mm[m].p, mm[m].npg * pgs);
+ mm[m].p = MAP_FAILED;
+ }
+
+ HX(stat(".", &st) == -1, st);
+ HX(stat("/", &st) == -1, st);
+
+#ifdef HAVE_SYS_STATVFS_H
+ HX(statvfs(".", &stvfs) == -1, stvfs);
+ HX(statvfs("/", &stvfs) == -1, stvfs);
+#endif
+ HX((e = fstat(0, &st)) == -1, st);
+ if (e == -1) {
+ if (S_ISREG(st.st_mode) ||
+ S_ISFIFO(st.st_mode) ||
+ S_ISSOCK(st.st_mode)) {
+#ifdef HAVE_SYS_STATVFS_H
+ HX(fstatvfs(0, &stvfs) == -1,
+ stvfs);
+#endif
+ HX((off = lseek(0, (off_t)0,
+ SEEK_CUR)) < 0, off);
+ }
+ if (S_ISCHR(st.st_mode)) {
+ HX(tcgetattr(0, &tios) == -1,
+ tios);
+#if 0
+ } else if (S_ISSOCK(st.st_mode)) {
+ struct sockaddr_storage ss;
+ socklen_t ssl;
+ memset(&ss, 0, sizeof ss);
+ ssl = sizeof(ss);
+ HX(getpeername(0,
+ (void *)&ss, &ssl) == -1,
+ ss);
+#endif
+ }
+ }
+
+ HX((e = getrusage(RUSAGE_CHILDREN,
+ &ru)) == -1, ru);
+ if (e != -1) {
+ cnt += (int)ru.ru_utime.tv_sec;
+ cnt += (int)ru.ru_utime.tv_usec;
+ }
+ } else {
+ /* Subsequent hashes absorb previous result */
+ HR(results, digest_len);
+ }
+
+ HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+ if (e != -1) {
+ cnt += (int)tv.tv_sec;
+ cnt += (int)tv.tv_usec;
+ }
+
+ HD(cnt);
+ }
+
+#ifdef HAVE_GETAUXVAL
+#ifdef AT_RANDOM
+ /* Not as random as you think but we take what we are given */
+ p = (char *) getauxval(AT_RANDOM);
+ if (p)
+ HR(p, 16);
+#endif
+#ifdef AT_SYSINFO_EHDR
+ p = (char *) getauxval(AT_SYSINFO_EHDR);
+ if (p)
+ HR(p, pgs);
+#endif
+#ifdef AT_BASE
+ p = (char *) getauxval(AT_BASE);
+ if (p)
+ HD(p);
+#endif
+#endif /* HAVE_GETAUXVAL */
+
+ sudo_digest_final(ctx, results);
+ sudo_digest_reset(ctx);
+ memcpy((char *)buf + i, results, min(digest_len, len - i));
+ i += min(digest_len, len - i);
+ }
+ if (gotdata(buf, len) == 0) {
+ errno = save_errno;
+ ret = 0; /* satisfied */
+ } else {
+ errno = EIO;
+ }
+done:
+ sudo_digest_free(ctx);
+ if (results != NULL) {
+ memset_s(results, sizeof(results), 0, sizeof(results));
+ free(results);
+ }
+ return (ret);
+}
+
+#endif /* HAVE_GETENTROPY */
diff --git a/lib/util/getgrouplist.c b/lib/util/getgrouplist.c
new file mode 100644
index 0000000..2537363
--- /dev/null
+++ b/lib/util/getgrouplist.c
@@ -0,0 +1,517 @@
+/*
+ * Copyright (c) 2010, 2011, 2013-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <grp.h>
+#include <limits.h>
+#include <unistd.h>
+#ifdef HAVE_NSS_SEARCH
+# include <errno.h>
+# include <limits.h>
+# include <nsswitch.h>
+# ifdef HAVE_NSS_DBDEFS_H
+# include <nss_dbdefs.h>
+# else
+# include "compat/nss_dbdefs.h"
+# endif
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+
+#ifndef HAVE_GETGROUPLIST
+int
+sudo_getgrouplist(const char *name, GETGROUPS_T basegid, GETGROUPS_T *groups,
+ int *ngroupsp)
+{
+ return sudo_getgrouplist2(name, basegid, &groups, ngroupsp);
+}
+#endif /* HAVE_GETGROUPLIST */
+
+#if defined(HAVE_GETGROUPLIST)
+
+#if defined(HAVE_GETGROUPLIST_2) && !HAVE_DECL_GETGROUPLIST_2
+int getgrouplist_2(const char *name, GETGROUPS_T basegid, GETGROUPS_T **groups);
+#endif /* HAVE_GETGROUPLIST_2 && !HAVE_DECL_GETGROUPLIST_2 */
+
+/*
+ * Extended getgrouplist(3) using getgrouplist(3) and getgrouplist_2(3)
+ */
+int
+sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid,
+ GETGROUPS_T **groupsp, int *ngroupsp)
+{
+ GETGROUPS_T *groups = *groupsp;
+ int ngroups;
+#ifndef HAVE_GETGROUPLIST_2
+ int grpsize, tries;
+#endif
+
+ /* For static group vector, just use getgrouplist(3). */
+ if (groups != NULL)
+ return getgrouplist(name, basegid, groups, ngroupsp);
+
+#ifdef HAVE_GETGROUPLIST_2
+ if ((ngroups = getgrouplist_2(name, basegid, groupsp)) == -1)
+ return -1;
+ *ngroupsp = ngroups;
+ return 0;
+#else
+ grpsize = (int)sysconf(_SC_NGROUPS_MAX);
+ if (grpsize < 0)
+ grpsize = NGROUPS_MAX;
+ grpsize++; /* include space for the primary gid */
+ /*
+ * It is possible to belong to more groups in the group database
+ * than NGROUPS_MAX.
+ */
+ for (tries = 0; tries < 10; tries++) {
+ free(groups);
+ groups = reallocarray(NULL, grpsize, sizeof(*groups));
+ if (groups == NULL)
+ return -1;
+ ngroups = grpsize;
+ if (getgrouplist(name, basegid, groups, &ngroups) != -1) {
+ *groupsp = groups;
+ *ngroupsp = ngroups;
+ return 0;
+ }
+ if (ngroups == grpsize) {
+ /* Failed for some reason other than ngroups too small. */
+ break;
+ }
+ /* getgrouplist(3) set ngroups to the required length, use it. */
+ grpsize = ngroups;
+ }
+ free(groups);
+ return -1;
+#endif /* HAVE_GETGROUPLIST_2 */
+}
+
+#elif defined(HAVE_GETGRSET)
+
+/*
+ * Extended getgrouplist(3) using AIX getgrset(3)
+ */
+int
+sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid,
+ GETGROUPS_T **groupsp, int *ngroupsp)
+{
+ GETGROUPS_T *groups = *groupsp;
+ char *cp, *last, *grset = NULL;
+ const char *errstr;
+ int ngroups = 1;
+ int grpsize = *ngroupsp;
+ int ret = -1;
+ gid_t gid;
+
+#ifdef HAVE_SETAUTHDB
+ aix_setauthdb((char *) name, NULL);
+#endif
+ if ((grset = getgrset(name)) == NULL)
+ goto done;
+
+ if (groups == NULL) {
+ /* Dynamically-sized group vector, count groups and alloc. */
+ grpsize = 1; /* reserve one for basegid */
+ if (*grset != '\0') {
+ for (cp = grset; *cp != '\0'; cp++) {
+ if (*cp == ',')
+ grpsize++;
+ }
+ }
+ groups = reallocarray(NULL, grpsize, sizeof(*groups));
+ if (groups == NULL)
+ return -1;
+ } else {
+ /* Static group vector. */
+ if (grpsize < 1)
+ return -1;
+ }
+
+ /* We support BSD semantics where the first element is the base gid */
+ groups[0] = basegid;
+
+ for (cp = strtok_r(grset, ",", &last); cp != NULL; cp = strtok_r(NULL, ",", &last)) {
+ gid = sudo_strtoid(cp, NULL, NULL, &errstr);
+ if (errstr == NULL && gid != basegid) {
+ if (ngroups == grpsize)
+ goto done;
+ groups[ngroups++] = gid;
+ }
+ }
+ ret = 0;
+
+done:
+ free(grset);
+#ifdef HAVE_SETAUTHDB
+ aix_restoreauthdb();
+#endif
+ *groupsp = groups;
+ *ngroupsp = ngroups;
+
+ return ret;
+}
+
+#elif defined(HAVE_NSS_SEARCH)
+
+#ifndef ALIGNBYTES
+# define ALIGNBYTES (sizeof(long) - 1L)
+#endif
+#ifndef ALIGN
+# define ALIGN(p) (((unsigned long)(p) + ALIGNBYTES) & ~ALIGNBYTES)
+#endif
+
+#if defined(HAVE__NSS_INITF_GROUP) || defined(HAVE___NSS_INITF_GROUP)
+extern void _nss_initf_group(nss_db_params_t *params);
+#else
+static void
+_nss_initf_group(nss_db_params_t *params)
+{
+ params->name = NSS_DBNAM_GROUP;
+ params->default_config = NSS_DEFCONF_GROUP;
+}
+#endif
+
+/*
+ * Convert a groups file string (instr) to a struct group (ent) using
+ * buf for storage.
+ */
+static int
+str2grp(const char *instr, int inlen, void *ent, char *buf, int buflen)
+{
+ struct group *grp = ent;
+ char *cp, *fieldsep = buf;
+ char **gr_mem, **gr_end;
+ const char *errstr;
+ int yp = 0;
+ id_t id;
+
+ /* Must at least have space to copy instr -> buf. */
+ if (inlen >= buflen)
+ return NSS_STR_PARSE_ERANGE;
+
+ /* Paranoia: buf and instr should be distinct. */
+ if (buf != instr) {
+ memmove(buf, instr, inlen);
+ buf[inlen] = '\0';
+ }
+
+ if ((fieldsep = strchr(cp = fieldsep, ':')) == NULL)
+ return NSS_STR_PARSE_PARSE;
+ *fieldsep++ = '\0';
+ grp->gr_name = cp;
+
+ /* Check for YP inclusion/exclusion entries. */
+ if (*cp == '+' || *cp == '-') {
+ /* Only the name is required for YP inclusion/exclusion entries. */
+ grp->gr_passwd = "";
+ grp->gr_gid = 0;
+ grp->gr_mem = NULL;
+ yp = 1;
+ }
+
+ if ((fieldsep = strchr(cp = fieldsep, ':')) == NULL)
+ return yp ? NSS_STR_PARSE_SUCCESS : NSS_STR_PARSE_PARSE;
+ *fieldsep++ = '\0';
+ grp->gr_passwd = cp;
+
+ if ((fieldsep = strchr(cp = fieldsep, ':')) == NULL)
+ return yp ? NSS_STR_PARSE_SUCCESS : NSS_STR_PARSE_PARSE;
+ *fieldsep++ = '\0';
+ id = sudo_strtoid(cp, NULL, NULL, &errstr);
+ if (errstr != NULL) {
+ /*
+ * A range error is always a fatal error, but ignore garbage
+ * at the end of YP entries since it has no meaning.
+ */
+ if (errno == ERANGE)
+ return NSS_STR_PARSE_ERANGE;
+ return yp ? NSS_STR_PARSE_SUCCESS : NSS_STR_PARSE_PARSE;
+ }
+#ifdef GID_NOBODY
+ /* Negative gids get mapped to nobody on Solaris. */
+ if (*cp == '-' && id != 0)
+ grp->gr_gid = GID_NOBODY;
+ else
+#endif
+ grp->gr_gid = (gid_t)id;
+
+ /* Store group members, taking care to use proper alignment. */
+ grp->gr_mem = NULL;
+ if (*fieldsep != '\0') {
+ grp->gr_mem = gr_mem = (char **)ALIGN(buf + inlen + 1);
+ gr_end = (char **)((unsigned long)(buf + buflen) & ~ALIGNBYTES);
+ for (;;) {
+ if (gr_mem == gr_end)
+ return NSS_STR_PARSE_ERANGE; /* out of space! */
+ *gr_mem++ = cp;
+ if (fieldsep == NULL)
+ break;
+ if ((fieldsep = strchr(cp = fieldsep, ',')) != NULL)
+ *fieldsep++ = '\0';
+ }
+ *gr_mem = NULL;
+ }
+ return NSS_STR_PARSE_SUCCESS;
+}
+
+static nss_status_t
+process_cstr(const char *instr, int inlen, struct nss_groupsbymem *gbm,
+ int dynamic)
+{
+ const char *user = gbm->username;
+ nss_status_t ret = NSS_NOTFOUND;
+ nss_XbyY_buf_t *buf;
+ struct group *grp;
+ char **gr_mem;
+ int error, i;
+
+ /* Hack to let us check whether the query was handled by nscd or us. */
+ if (gbm->force_slow_way != 0)
+ gbm->force_slow_way = 2;
+
+ buf = _nss_XbyY_buf_alloc(sizeof(struct group), NSS_BUFLEN_GROUP);
+ if (buf == NULL)
+ return NSS_UNAVAIL;
+
+ /* Parse groups file string -> struct group. */
+ grp = buf->result;
+ error = (*gbm->str2ent)(instr, inlen, grp, buf->buffer, buf->buflen);
+ if (error || grp->gr_mem == NULL)
+ goto done;
+
+ for (gr_mem = grp->gr_mem; *gr_mem != NULL; gr_mem++) {
+ if (strcmp(*gr_mem, user) == 0) {
+ /* Append to gid_array unless gr_gid is a dupe. */
+ for (i = 0; i < gbm->numgids; i++) {
+ if (gbm->gid_array[i] == grp->gr_gid)
+ goto done; /* already present */
+ }
+ if (i == gbm->maxgids && dynamic) {
+ GETGROUPS_T *tmp = reallocarray(gbm->gid_array, gbm->maxgids,
+ 2 * sizeof(GETGROUPS_T));
+ if (tmp == NULL) {
+ /* Out of memory, just return what we have. */
+ dynamic = 0;
+ } else {
+ gbm->gid_array = tmp;
+ gbm->maxgids <<= 1;
+ }
+ }
+ /* Store gid if there is space. */
+ if (i < gbm->maxgids)
+ gbm->gid_array[i] = grp->gr_gid;
+ /* Always increment numgids so we can detect when out of space. */
+ gbm->numgids++;
+ goto done;
+ }
+ }
+done:
+ _nss_XbyY_buf_free(buf);
+ return ret;
+}
+
+static nss_status_t
+process_cstr_static(const char *instr, int inlen, struct nss_groupsbymem *gbm)
+{
+ return process_cstr(instr, inlen, gbm, 0);
+}
+
+static nss_status_t
+process_cstr_dynamic(const char *instr, int inlen, struct nss_groupsbymem *gbm)
+{
+ return process_cstr(instr, inlen, gbm, 1);
+}
+
+/*
+ * Extended getgrouplist(3) using nss_search(3)
+ */
+int
+sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid,
+ GETGROUPS_T **groupsp, int *ngroupsp)
+{
+ struct nss_groupsbymem gbm;
+ static DEFINE_NSS_DB_ROOT(db_root);
+
+ memset(&gbm, 0, sizeof(gbm));
+ gbm.username = name;
+ gbm.gid_array = *groupsp;
+ gbm.maxgids = *ngroupsp;
+ gbm.numgids = 1; /* for basegid */
+ gbm.force_slow_way = 1;
+ gbm.str2ent = str2grp;
+
+ if (gbm.gid_array == NULL) {
+ /* Dynamically-sized group vector. */
+ gbm.maxgids = (int)sysconf(_SC_NGROUPS_MAX);
+ if (gbm.maxgids < 0)
+ gbm.maxgids = NGROUPS_MAX;
+ gbm.gid_array = reallocarray(NULL, gbm.maxgids, 4 * sizeof(GETGROUPS_T));
+ if (gbm.gid_array == NULL)
+ return -1;
+ gbm.maxgids <<= 2;
+ gbm.process_cstr = process_cstr_dynamic;
+ } else {
+ /* Static group vector. */
+ if (gbm.maxgids <= 0)
+ return -1;
+ gbm.process_cstr = process_cstr_static;
+ }
+
+ /* We support BSD semantics where the first element is the base gid */
+ gbm.gid_array[0] = basegid;
+
+ /*
+ * Can't use nss_search return value since it may return NSS_UNAVAIL
+ * when no nsswitch.conf entry (e.g. compat mode).
+ */
+ for (;;) {
+ GETGROUPS_T *tmp;
+
+ (void)nss_search(&db_root, _nss_initf_group, NSS_DBOP_GROUP_BYMEMBER,
+ &gbm);
+
+ /*
+ * If this was a statically-sized group vector or nscd was not used
+ * we are done.
+ */
+ if (gbm.process_cstr != process_cstr_dynamic || gbm.force_slow_way == 2)
+ break;
+
+ /*
+ * If gid_array is full and the query was handled by nscd, there
+ * may be more data, so double gid_array and try again.
+ */
+ if (gbm.numgids != gbm.maxgids)
+ break;
+
+ tmp = reallocarray(gbm.gid_array, gbm.maxgids, 2 * sizeof(GETGROUPS_T));
+ if (tmp == NULL) {
+ free(gbm.gid_array);
+ return -1;
+ }
+ gbm.gid_array = tmp;
+ gbm.maxgids <<= 1;
+ }
+
+ /* Note: we can only detect a too-small group list if nscd is not used. */
+ *groupsp = gbm.gid_array;
+ if (gbm.numgids <= gbm.maxgids) {
+ *ngroupsp = gbm.numgids;
+ return 0;
+ }
+ *ngroupsp = gbm.maxgids;
+ return -1;
+}
+
+#else /* !HAVE_GETGROUPLIST && !HAVE_GETGRSET && !HAVE__GETGROUPSBYMEMBER */
+
+/*
+ * Extended getgrouplist(3) using getgrent(3)
+ */
+int
+sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid,
+ GETGROUPS_T **groupsp, int *ngroupsp)
+{
+ GETGROUPS_T *groups = *groupsp;
+ int grpsize = *ngroupsp;
+ int i, ngroups = 1;
+ int ret = -1;
+ struct group *grp;
+
+ if (groups == NULL) {
+ /* Dynamically-sized group vector. */
+ grpsize = (int)sysconf(_SC_NGROUPS_MAX);
+ if (grpsize < 0)
+ grpsize = NGROUPS_MAX;
+ groups = reallocarray(NULL, grpsize, 4 * sizeof(*groups));
+ if (groups == NULL)
+ return -1;
+ grpsize <<= 2;
+ } else {
+ /* Static group vector. */
+ if (grpsize < 1)
+ return -1;
+ }
+
+ /* We support BSD semantics where the first element is the base gid */
+ groups[0] = basegid;
+
+ setgrent();
+ while ((grp = getgrent()) != NULL) {
+ if (grp->gr_gid == basegid || grp->gr_mem == NULL)
+ continue;
+
+ for (i = 0; grp->gr_mem[i] != NULL; i++) {
+ if (strcmp(name, grp->gr_mem[i]) == 0)
+ break;
+ }
+ if (grp->gr_mem[i] == NULL)
+ continue; /* user not found */
+
+ /* Only add if it is not the same as an existing gid */
+ for (i = 0; i < ngroups; i++) {
+ if (grp->gr_gid == groups[i])
+ break;
+ }
+ if (i == ngroups) {
+ if (ngroups == grpsize) {
+ GETGROUPS_T *tmp;
+
+ if (*groupsp != NULL) {
+ /* Static group vector. */
+ goto done;
+ }
+ tmp = reallocarray(groups, grpsize, 2 * sizeof(*groups));
+ if (tmp == NULL) {
+ free(groups);
+ groups = NULL;
+ ngroups = 0;
+ goto done;
+ }
+ groups = tmp;
+ grpsize <<= 1;
+ }
+ groups[ngroups++] = grp->gr_gid;
+ }
+ }
+ ret = 0;
+
+done:
+ endgrent();
+ *groupsp = groups;
+ *ngroupsp = ngroups;
+
+ return ret;
+}
+#endif /* !HAVE_GETGROUPLIST && !HAVE_GETGRSET && !HAVE__GETGROUPSBYMEMBER */
diff --git a/lib/util/gethostname.c b/lib/util/gethostname.c
new file mode 100644
index 0000000..ed5061c
--- /dev/null
+++ b/lib/util/gethostname.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+
+/*
+ * Return a malloc()ed copy of the system hostname, or NULL if
+ * malloc() or gethostname() fails.
+ */
+char *
+sudo_gethostname_v1(void)
+{
+ char *hname;
+ size_t host_name_max;
+
+#ifdef _SC_HOST_NAME_MAX
+ host_name_max = (size_t)sysconf(_SC_HOST_NAME_MAX);
+ if (host_name_max == (size_t)-1)
+#endif
+ host_name_max = 255; /* POSIX and historic BSD */
+
+ hname = malloc(host_name_max + 1);
+ if (hname != NULL) {
+ if (gethostname(hname, host_name_max + 1) == 0 && *hname != '\0') {
+ /* Old gethostname() may not NUL-terminate if there is no room. */
+ hname[host_name_max] = '\0';
+ } else {
+ free(hname);
+ hname = NULL;
+ }
+ }
+ return hname;
+}
diff --git a/lib/util/getline.c b/lib/util/getline.c
new file mode 100644
index 0000000..153037b
--- /dev/null
+++ b/lib/util/getline.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2009-2010, 2012-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_GETLINE
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <limits.h>
+
+#include "sudo_compat.h"
+
+#ifdef HAVE_FGETLN
+ssize_t
+sudo_getline(char **bufp, size_t *bufsizep, FILE *fp)
+{
+ char *buf, *cp;
+ size_t bufsize;
+ size_t len;
+
+ buf = fgetln(fp, &len);
+ if (buf) {
+ bufsize = *bufp ? *bufsizep : 0;
+ if (bufsize == 0 || bufsize - 1 < len) {
+ bufsize = len + 1;
+ cp = realloc(*bufp, bufsize);
+ if (cp == NULL)
+ return -1;
+ *bufp = cp;
+ *bufsizep = bufsize;
+ }
+ memcpy(*bufp, buf, len);
+ (*bufp)[len] = '\0';
+ }
+ return buf ? len : -1;
+}
+#else
+ssize_t
+sudo_getline(char **bufp, size_t *bufsizep, FILE *fp)
+{
+ char *buf, *cp;
+ size_t bufsize;
+ ssize_t len = 0;
+
+ buf = *bufp;
+ bufsize = *bufsizep;
+ if (buf == NULL || bufsize == 0) {
+ bufsize = LINE_MAX;
+ cp = realloc(buf, bufsize);
+ if (cp == NULL)
+ return -1;
+ buf = cp;
+ }
+
+ for (;;) {
+ if (fgets(buf + len, bufsize - len, fp) == NULL) {
+ len = -1;
+ break;
+ }
+ len = strlen(buf);
+ if (!len || buf[len - 1] == '\n' || feof(fp))
+ break;
+ cp = reallocarray(buf, bufsize, 2);
+ if (cp == NULL)
+ return -1;
+ bufsize *= 2;
+ buf = cp;
+ }
+ *bufp = buf;
+ *bufsizep = bufsize;
+ return len;
+}
+#endif /* HAVE_FGETLN */
+#endif /* HAVE_GETLINE */
diff --git a/lib/util/getopt_long.c b/lib/util/getopt_long.c
new file mode 100644
index 0000000..d88c3a5
--- /dev/null
+++ b/lib/util/getopt_long.c
@@ -0,0 +1,629 @@
+/* $OpenBSD: getopt_long.c,v 1.26 2013/06/08 22:47:56 millert Exp $ */
+/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
+/* $FreeBSD: head/lib/libc/stdlib/getopt_long.c 236936 2012-06-11 22:25:20Z delphij $ */
+
+/*
+ * Copyright (c) 2002 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#define SUDO_ERROR_WRAP 0
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "compat/getopt.h"
+
+#define GNU_COMPATIBLE /* Be more compatible with GNU getopt. */
+
+#ifdef REPLACE_GETOPT
+int opterr = 1; /* if error message should be printed */
+int optind = 1; /* index into parent argv vector */
+int optopt = '?'; /* character checked for validity */
+char *optarg; /* argument associated with option */
+#else
+extern int opterr; /* if error message should be printed */
+extern int optind; /* index into parent argv vector */
+extern int optopt; /* character checked for validity */
+extern char *optarg; /* argument associated with option */
+#endif
+#if !defined(REPLACE_GETOPT) && !defined(HAVE_OPTRESET)
+int optreset; /* reset getopt */
+#endif
+
+#define PRINT_ERROR ((opterr) && (*options != ':'))
+
+#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
+#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
+#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
+
+/* return values */
+#define BADCH (int)'?'
+#define BADARG ((*options == ':') ? (int)':' : (int)'?')
+#define INORDER (int)1
+
+#define EMSG ""
+
+#ifdef GNU_COMPATIBLE
+#define NO_PREFIX (-1)
+#define D_PREFIX 0
+#define DD_PREFIX 1
+#define W_PREFIX 2
+#endif
+
+static int getopt_internal(int, char * const *, const char *,
+ const struct option *, int *, int);
+static int parse_long_options(char * const *, const char *,
+ const struct option *, int *, int, int);
+static int gcd(int, int);
+static void permute_args(int, int, int, char * const *);
+
+static char *place = EMSG; /* option letter processing */
+
+/* XXX: set optreset to 1 rather than these two */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1; /* first option after non options (for permute) */
+
+/* Error messages */
+static const char recargchar[] = "option requires an argument -- %c";
+static const char illoptchar[] = "illegal option -- %c"; /* From P1003.2 */
+#ifdef GNU_COMPATIBLE
+static int dash_prefix = NO_PREFIX;
+static const char gnuoptchar[] = "invalid option -- %c";
+
+static const char recargstring[] = "option `%s%s' requires an argument";
+static const char ambig[] = "option `%s%.*s' is ambiguous";
+static const char noarg[] = "option `%s%.*s' doesn't allow an argument";
+static const char illoptstring[] = "unrecognized option `%s%s'";
+#else
+static const char recargstring[] = "option requires an argument -- %s";
+static const char ambig[] = "ambiguous option -- %.*s";
+static const char noarg[] = "option doesn't take an argument -- %.*s";
+static const char illoptstring[] = "unknown option -- %s";
+#endif
+
+/*
+ * Compute the greatest common divisor of a and b.
+ */
+static int
+gcd(int a, int b)
+{
+ int c;
+
+ c = a % b;
+ while (c != 0) {
+ a = b;
+ b = c;
+ c = a % b;
+ }
+
+ return (b);
+}
+
+/*
+ * Exchange the block from nonopt_start to nonopt_end with the block
+ * from nonopt_end to opt_end (keeping the same order of arguments
+ * in each block).
+ */
+static void
+permute_args(int panonopt_start, int panonopt_end, int opt_end,
+ char * const *nargv)
+{
+ int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+ char *swap;
+
+ /*
+ * compute lengths of blocks and number and size of cycles
+ */
+ nnonopts = panonopt_end - panonopt_start;
+ nopts = opt_end - panonopt_end;
+ ncycle = gcd(nnonopts, nopts);
+ cyclelen = (opt_end - panonopt_start) / ncycle;
+
+ for (i = 0; i < ncycle; i++) {
+ cstart = panonopt_end+i;
+ pos = cstart;
+ for (j = 0; j < cyclelen; j++) {
+ if (pos >= panonopt_end)
+ pos -= nnonopts;
+ else
+ pos += nopts;
+ swap = nargv[pos];
+ /* LINTED const cast */
+ ((char **) nargv)[pos] = nargv[cstart];
+ /* LINTED const cast */
+ ((char **)nargv)[cstart] = swap;
+ }
+ }
+}
+
+/*
+ * parse_long_options --
+ * Parse long options in argc/argv argument vector.
+ * Returns -1 if short_too is set and the option does not match long_options.
+ */
+static int
+parse_long_options(char * const *nargv, const char *options,
+ const struct option *long_options, int *idx, int short_too, int flags)
+{
+ char *current_argv, *has_equal;
+#ifdef GNU_COMPATIBLE
+ char *current_dash;
+#endif
+ size_t current_argv_len;
+ int i, match, exact_match, second_partial_match;
+
+ current_argv = place;
+#ifdef GNU_COMPATIBLE
+ switch (dash_prefix) {
+ case D_PREFIX:
+ current_dash = "-";
+ break;
+ case DD_PREFIX:
+ current_dash = "--";
+ break;
+ case W_PREFIX:
+ current_dash = "-W ";
+ break;
+ default:
+ current_dash = "";
+ break;
+ }
+#endif
+ match = -1;
+ exact_match = 0;
+ second_partial_match = 0;
+
+ optind++;
+
+ if ((has_equal = strchr(current_argv, '=')) != NULL) {
+ /* argument found (--option=arg) */
+ current_argv_len = has_equal - current_argv;
+ has_equal++;
+ } else
+ current_argv_len = strlen(current_argv);
+
+ for (i = 0; long_options[i].name; i++) {
+ /* find matching long option */
+ if (strncmp(current_argv, long_options[i].name,
+ current_argv_len))
+ continue;
+
+ if (strlen(long_options[i].name) == current_argv_len) {
+ /* exact match */
+ match = i;
+ exact_match = 1;
+ break;
+ }
+ /*
+ * If this is a known short option, don't allow
+ * a partial match of a single character.
+ */
+ if (short_too && current_argv_len == 1)
+ continue;
+
+ if (match == -1) /* first partial match */
+ match = i;
+ else if ((flags & FLAG_LONGONLY) ||
+ long_options[i].has_arg !=
+ long_options[match].has_arg ||
+ long_options[i].flag != long_options[match].flag ||
+ long_options[i].val != long_options[match].val)
+ second_partial_match = 1;
+ }
+ if (!exact_match && second_partial_match) {
+ /* ambiguous abbreviation */
+ if (PRINT_ERROR)
+ sudo_warnx(ambig,
+#ifdef GNU_COMPATIBLE
+ current_dash,
+#endif
+ (int)current_argv_len,
+ current_argv);
+ optopt = 0;
+ return (BADCH);
+ }
+ if (match != -1) { /* option found */
+ if (long_options[match].has_arg == no_argument
+ && has_equal) {
+ if (PRINT_ERROR)
+ sudo_warnx(noarg,
+#ifdef GNU_COMPATIBLE
+ current_dash,
+#endif
+ (int)current_argv_len,
+ current_argv);
+ /*
+ * XXX: GNU sets optopt to val regardless of flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+#ifdef GNU_COMPATIBLE
+ return (BADCH);
+#else
+ return (BADARG);
+#endif
+ }
+ if (long_options[match].has_arg == required_argument ||
+ long_options[match].has_arg == optional_argument) {
+ if (has_equal)
+ optarg = has_equal;
+ else if (long_options[match].has_arg ==
+ required_argument) {
+ /*
+ * optional argument doesn't use next nargv
+ */
+ optarg = nargv[optind++];
+ }
+ }
+ if ((long_options[match].has_arg == required_argument)
+ && (optarg == NULL)) {
+ /*
+ * Missing argument; leading ':' indicates no error
+ * should be generated.
+ */
+ if (PRINT_ERROR)
+ sudo_warnx(recargstring,
+#ifdef GNU_COMPATIBLE
+ current_dash,
+#endif
+ current_argv);
+ /*
+ * XXX: GNU sets optopt to val regardless of flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+ --optind;
+ return (BADARG);
+ }
+ } else { /* unknown option */
+ if (short_too) {
+ --optind;
+ return (-1);
+ }
+ if (PRINT_ERROR)
+ sudo_warnx(illoptstring,
+#ifdef GNU_COMPATIBLE
+ current_dash,
+#endif
+ current_argv);
+ optopt = 0;
+ return (BADCH);
+ }
+ if (idx)
+ *idx = match;
+ if (long_options[match].flag) {
+ *long_options[match].flag = long_options[match].val;
+ return (0);
+ } else
+ return (long_options[match].val);
+}
+
+/*
+ * getopt_internal --
+ * Parse argc/argv argument vector. Called by user level routines.
+ */
+static int
+getopt_internal(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx, int flags)
+{
+ char *oli; /* option letter list index */
+ int optchar, short_too;
+ int posixly_correct; /* no static, can be changed on the fly */
+
+ if (options == NULL)
+ return (-1);
+
+ /*
+ * Disable GNU extensions if POSIXLY_CORRECT is set or options
+ * string begins with a '+'.
+ */
+ posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
+#ifdef GNU_COMPATIBLE
+ if (*options == '-')
+ flags |= FLAG_ALLARGS;
+ else if (posixly_correct || *options == '+')
+ flags &= ~FLAG_PERMUTE;
+#else
+ if (posixly_correct || *options == '+')
+ flags &= ~FLAG_PERMUTE;
+ else if (*options == '-')
+ flags |= FLAG_ALLARGS;
+#endif
+ if (*options == '+' || *options == '-')
+ options++;
+
+ /*
+ * XXX Some GNU programs (like cvs) set optind to 0 instead of
+ * XXX using optreset. Work around this braindamage.
+ */
+ if (optind == 0)
+ optind = optreset = 1;
+
+ optarg = NULL;
+ if (optreset)
+ nonopt_start = nonopt_end = -1;
+start:
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc) { /* end of argument vector */
+ place = EMSG;
+ if (nonopt_end != -1) {
+ /* do permutation, if we have to */
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ else if (nonopt_start != -1) {
+ /*
+ * If we skipped non-options, set optind
+ * to the first of them.
+ */
+ optind = nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return (-1);
+ }
+ if (*(place = nargv[optind]) != '-' ||
+#ifdef GNU_COMPATIBLE
+ place[1] == '\0') {
+#else
+ (place[1] == '\0' && strchr(options, '-') == NULL)) {
+#endif
+ place = EMSG; /* found non-option */
+ if (flags & FLAG_ALLARGS) {
+ /*
+ * GNU extension:
+ * return non-option as argument to option 1
+ */
+ optarg = nargv[optind++];
+ return (INORDER);
+ }
+ if (!(flags & FLAG_PERMUTE)) {
+ /*
+ * If no permutation wanted, stop parsing
+ * at first non-option.
+ */
+ return (-1);
+ }
+ /* do permutation */
+ if (nonopt_start == -1)
+ nonopt_start = optind;
+ else if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ nonopt_start = optind -
+ (nonopt_end - nonopt_start);
+ nonopt_end = -1;
+ }
+ optind++;
+ /* process next argument */
+ goto start;
+ }
+ if (nonopt_start != -1 && nonopt_end == -1)
+ nonopt_end = optind;
+
+ /*
+ * If we have "-" do nothing, if "--" we are done.
+ */
+ if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
+ optind++;
+ place = EMSG;
+ /*
+ * We found an option (--), so if we skipped
+ * non-options, we have to permute.
+ */
+ if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return (-1);
+ }
+ }
+
+ /*
+ * Check long options if:
+ * 1) we were passed some
+ * 2) the arg is not just "-"
+ * 3) either the arg starts with -- we are getopt_long_only()
+ */
+ if (long_options != NULL && place != nargv[optind] &&
+ (*place == '-' || (flags & FLAG_LONGONLY))) {
+ short_too = 0;
+#ifdef GNU_COMPATIBLE
+ dash_prefix = D_PREFIX;
+#endif
+ if (*place == '-') {
+ place++; /* --foo long option */
+#ifdef GNU_COMPATIBLE
+ dash_prefix = DD_PREFIX;
+#endif
+ } else if (*place != ':' && strchr(options, *place) != NULL)
+ short_too = 1; /* could be short option too */
+
+ optchar = parse_long_options(nargv, options, long_options,
+ idx, short_too, flags);
+ if (optchar != -1) {
+ place = EMSG;
+ return (optchar);
+ }
+ }
+
+ if ((optchar = (int)*place++) == (int)':' ||
+ (optchar == (int)'-' && *place != '\0') ||
+ (oli = strchr(options, optchar)) == NULL) {
+ /*
+ * If the user specified "-" and '-' isn't listed in
+ * options, return -1 (non-option) as per POSIX.
+ * Otherwise, it is an unknown option character (or ':').
+ */
+ if (optchar == (int)'-' && *place == '\0')
+ return (-1);
+ if (!*place)
+ ++optind;
+#ifdef GNU_COMPATIBLE
+ if (PRINT_ERROR)
+ sudo_warnx(posixly_correct ? illoptchar : gnuoptchar,
+ optchar);
+#else
+ if (PRINT_ERROR)
+ sudo_warnx(illoptchar, optchar);
+#endif
+ optopt = optchar;
+ return (BADCH);
+ }
+ if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
+ /* -W long-option */
+ if (*place) /* no space */
+ /* NOTHING */;
+ else if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+ if (PRINT_ERROR)
+ sudo_warnx(recargchar, optchar);
+ optopt = optchar;
+ return (BADARG);
+ } else /* white space */
+ place = nargv[optind];
+#ifdef GNU_COMPATIBLE
+ dash_prefix = W_PREFIX;
+#endif
+ optchar = parse_long_options(nargv, options, long_options,
+ idx, 0, flags);
+ place = EMSG;
+ return (optchar);
+ }
+ if (*++oli != ':') { /* doesn't take argument */
+ if (!*place)
+ ++optind;
+ } else { /* takes (optional) argument */
+ optarg = NULL;
+ if (*place) /* no white space */
+ optarg = place;
+ else if (oli[1] != ':') { /* arg not optional */
+ if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+ if (PRINT_ERROR)
+ sudo_warnx(recargchar, optchar);
+ optopt = optchar;
+ return (BADARG);
+ } else
+ optarg = nargv[optind];
+ }
+ place = EMSG;
+ ++optind;
+ }
+ /* dump back option letter */
+ return (optchar);
+}
+
+#ifdef REPLACE_GETOPT
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ */
+int
+sudo_getopt(int nargc, char * const *nargv, const char *options)
+{
+
+ /*
+ * We don't pass FLAG_PERMUTE to getopt_internal() since
+ * the BSD getopt(3) (unlike GNU) has never done this.
+ *
+ * Furthermore, since many privileged programs call getopt()
+ * before dropping privileges it makes sense to keep things
+ * as simple (and bug-free) as possible.
+ */
+ return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
+}
+#endif /* REPLACE_GETOPT */
+
+/*
+ * getopt_long --
+ * Parse argc/argv argument vector.
+ */
+int
+sudo_getopt_long(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx)
+{
+
+ return (getopt_internal(nargc, nargv, options, long_options, idx,
+ FLAG_PERMUTE));
+}
+
+/*
+ * getopt_long_only --
+ * Parse argc/argv argument vector.
+ */
+int
+sudo_getopt_long_only(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx)
+{
+
+ return (getopt_internal(nargc, nargv, options, long_options, idx,
+ FLAG_PERMUTE|FLAG_LONGONLY));
+}
diff --git a/lib/util/gettime.c b/lib/util/gettime.c
new file mode 100644
index 0000000..f4d4664
--- /dev/null
+++ b/lib/util/gettime.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2014-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+
+#if defined(__MACH__) && !defined(HAVE_CLOCK_GETTIME)
+# include <mach/mach.h>
+# include <mach/mach_time.h>
+# include <mach/clock.h>
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+/*
+ * On Linux and FreeBSD, CLOCK_MONOTONIC does not run while sleeping.
+ * Linux provides CLOCK_BOOTTIME which runs while sleeping (FreeBSD does not).
+ * Some systems provide CLOCK_UPTIME which only runs while awake.
+ */
+#if defined(CLOCK_BOOTTIME)
+# define SUDO_CLOCK_BOOTTIME CLOCK_BOOTTIME
+#elif defined(CLOCK_MONOTONIC_RAW)
+# define SUDO_CLOCK_BOOTTIME CLOCK_MONOTONIC_RAW
+#elif defined(CLOCK_MONOTONIC)
+# define SUDO_CLOCK_BOOTTIME CLOCK_MONOTONIC
+#endif
+#if defined(CLOCK_UPTIME_RAW)
+# define SUDO_CLOCK_UPTIME CLOCK_UPTIME_RAW
+#elif defined(CLOCK_UPTIME)
+# define SUDO_CLOCK_UPTIME CLOCK_UPTIME
+#elif defined(CLOCK_MONOTONIC)
+# define SUDO_CLOCK_UPTIME CLOCK_MONOTONIC
+#endif
+
+/*
+ * Wall clock time, may run backward.
+ */
+#if defined(HAVE_CLOCK_GETTIME)
+int
+sudo_gettime_real_v1(struct timespec *ts)
+{
+ debug_decl(sudo_gettime_real, SUDO_DEBUG_UTIL)
+
+ if (clock_gettime(CLOCK_REALTIME, ts) == -1) {
+ struct timeval tv;
+
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "clock_gettime(CLOCK_REALTIME) failed, trying gettimeofday()");
+ if (gettimeofday(&tv, NULL) == -1)
+ debug_return_int(-1);
+ TIMEVAL_TO_TIMESPEC(&tv, ts);
+ }
+ debug_return_int(0);
+}
+#else
+int
+sudo_gettime_real_v1(struct timespec *ts)
+{
+ struct timeval tv;
+ debug_decl(sudo_gettime_real, SUDO_DEBUG_UTIL)
+
+ if (gettimeofday(&tv, NULL) == -1)
+ debug_return_int(-1);
+ TIMEVAL_TO_TIMESPEC(&tv, ts);
+ debug_return_int(0);
+}
+#endif
+
+/*
+ * Monotonic time, only runs forward.
+ * We use a timer that only increments while sleeping, if possible.
+ */
+#if defined(HAVE_CLOCK_GETTIME) && defined(SUDO_CLOCK_BOOTTIME)
+int
+sudo_gettime_mono_v1(struct timespec *ts)
+{
+ static int has_monoclock = -1;
+ debug_decl(sudo_gettime_mono, SUDO_DEBUG_UTIL)
+
+ /* Check whether the kernel/libc actually supports a monotonic clock. */
+# ifdef _SC_MONOTONIC_CLOCK
+ if (has_monoclock == -1)
+ has_monoclock = sysconf(_SC_MONOTONIC_CLOCK) != -1;
+# endif
+ if (!has_monoclock)
+ debug_return_int(sudo_gettime_real(ts));
+ if (clock_gettime(SUDO_CLOCK_BOOTTIME, ts) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "clock_gettime(%d) failed, using wall clock",
+ (int)SUDO_CLOCK_BOOTTIME);
+ has_monoclock = 0;
+ debug_return_int(sudo_gettime_real(ts));
+ }
+ debug_return_int(0);
+}
+#elif defined(HAVE_GETHRTIME)
+int
+sudo_gettime_mono_v1(struct timespec *ts)
+{
+ hrtime_t nsec;
+ debug_decl(sudo_gettime_mono, SUDO_DEBUG_UTIL)
+
+ nsec = gethrtime();
+ ts->tv_sec = nsec / 1000000000;
+ ts->tv_nsec = nsec % 1000000000;
+ debug_return_int(0);
+}
+#elif defined(__MACH__)
+int
+sudo_gettime_mono_v1(struct timespec *ts)
+{
+ uint64_t abstime, nsec;
+ static mach_timebase_info_data_t timebase_info;
+ debug_decl(sudo_gettime_mono, SUDO_DEBUG_UTIL)
+
+ if (timebase_info.denom == 0)
+ (void) mach_timebase_info(&timebase_info);
+#ifdef HAVE_MACH_CONTINUOUS_TIME
+ abstime = mach_continuous_time(); /* runs while asleep */
+#else
+ abstime = mach_absolute_time(); /* doesn't run while asleep */
+#endif
+ nsec = abstime * timebase_info.numer / timebase_info.denom;
+ ts->tv_sec = nsec / 1000000000;
+ ts->tv_nsec = nsec % 1000000000;
+ debug_return_int(0);
+}
+#else
+int
+sudo_gettime_mono_v1(struct timespec *ts)
+{
+ /* No monotonic clock available, use wall clock. */
+ return sudo_gettime_real(ts);
+}
+#endif
+
+/*
+ * Monotonic time, only runs forward.
+ * We use a timer that only increments while awake, if possible.
+ */
+#if defined(HAVE_CLOCK_GETTIME) && defined(SUDO_CLOCK_UPTIME)
+int
+sudo_gettime_awake_v1(struct timespec *ts)
+{
+ static int has_monoclock = -1;
+ debug_decl(sudo_gettime_awake, SUDO_DEBUG_UTIL)
+
+ /* Check whether the kernel/libc actually supports a monotonic clock. */
+# ifdef _SC_MONOTONIC_CLOCK
+ if (has_monoclock == -1)
+ has_monoclock = sysconf(_SC_MONOTONIC_CLOCK) != -1;
+# endif
+ if (!has_monoclock)
+ debug_return_int(sudo_gettime_real(ts));
+ if (clock_gettime(SUDO_CLOCK_UPTIME, ts) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "clock_gettime(%d) failed, using wall clock",
+ (int)SUDO_CLOCK_UPTIME);
+ has_monoclock = 0;
+ debug_return_int(sudo_gettime_real(ts));
+ }
+ debug_return_int(0);
+}
+#elif defined(HAVE_GETHRTIME)
+int
+sudo_gettime_awake_v1(struct timespec *ts)
+{
+ hrtime_t nsec;
+ debug_decl(sudo_gettime_awake, SUDO_DEBUG_UTIL)
+
+ /* Currently the same as sudo_gettime_mono() */
+ nsec = gethrtime();
+ ts->tv_sec = nsec / 1000000000;
+ ts->tv_nsec = nsec % 1000000000;
+ debug_return_int(0);
+}
+#elif defined(__MACH__)
+int
+sudo_gettime_awake_v1(struct timespec *ts)
+{
+ uint64_t abstime, nsec;
+ static mach_timebase_info_data_t timebase_info;
+ debug_decl(sudo_gettime_awake, SUDO_DEBUG_UTIL)
+
+ if (timebase_info.denom == 0)
+ (void) mach_timebase_info(&timebase_info);
+ abstime = mach_absolute_time();
+ nsec = abstime * timebase_info.numer / timebase_info.denom;
+ ts->tv_sec = nsec / 1000000000;
+ ts->tv_nsec = nsec % 1000000000;
+ debug_return_int(0);
+}
+#else
+int
+sudo_gettime_awake_v1(struct timespec *ts)
+{
+ /* No monotonic uptime clock available, use wall clock. */
+ return sudo_gettime_real(ts);
+}
+#endif
diff --git a/lib/util/gidlist.c b/lib/util/gidlist.c
new file mode 100644
index 0000000..1adf9bc
--- /dev/null
+++ b/lib/util/gidlist.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2013-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grp.h>
+
+#define DEFAULT_TEXT_DOMAIN "sudo"
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+/*
+ * Parse a comma-separated list of gids into an allocated array of GETGROUPS_T.
+ * If a pointer to the base gid is specified, it is stored as the first element
+ * in the array.
+ * Returns the number of gids in the allocated array.
+ */
+int
+sudo_parse_gids_v1(const char *gidstr, const gid_t *basegid, GETGROUPS_T **gidsp)
+{
+ int ngids = 0;
+ GETGROUPS_T *gids;
+ const char *cp = gidstr;
+ const char *errstr;
+ char *ep;
+ debug_decl(sudo_parse_gids, SUDO_DEBUG_UTIL)
+
+ /* Count groups. */
+ if (*cp != '\0') {
+ ngids++;
+ do {
+ if (*cp++ == ',')
+ ngids++;
+ } while (*cp != '\0');
+ }
+ /* Base gid is optional. */
+ if (basegid != NULL)
+ ngids++;
+ /* Allocate and fill in array. */
+ if (ngids != 0) {
+ gids = reallocarray(NULL, ngids, sizeof(GETGROUPS_T));
+ if (gids == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+ ngids = 0;
+ if (basegid != NULL)
+ gids[ngids++] = *basegid;
+ cp = gidstr;
+ do {
+ gids[ngids] = (GETGROUPS_T) sudo_strtoid(cp, ",", &ep, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("%s: %s"), cp, U_(errstr));
+ free(gids);
+ debug_return_int(-1);
+ }
+ if (basegid == NULL || gids[ngids] != *basegid)
+ ngids++;
+ cp = ep + 1;
+ } while (*ep != '\0');
+ *gidsp = gids;
+ }
+ debug_return_int(ngids);
+}
diff --git a/lib/util/glob.c b/lib/util/glob.c
new file mode 100644
index 0000000..f3a6d57
--- /dev/null
+++ b/lib/util/glob.c
@@ -0,0 +1,958 @@
+/*
+ * Copyright (c) 2008-2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)glob.c 8.3 (Berkeley) 10/13/93
+ */
+
+/*
+ * glob(3) -- a superset of the one defined in POSIX 1003.2.
+ *
+ * The [!...] convention to negate a range is supported (SysV, Posix, ksh).
+ *
+ * Optional extra services, controlled by flags not defined by POSIX:
+ *
+ * GLOB_MAGCHAR:
+ * Set in gl_flags if pattern contained a globbing character.
+ * GLOB_TILDE:
+ * expand ~user/foo to the /home/dir/of/user/foo
+ * GLOB_BRACE:
+ * expand {1,2}{a,b} to 1a 1b 2a 2b
+ * gl_matchc:
+ * Number of matches in the current invocation of glob.
+ */
+
+#include <config.h>
+
+#ifndef HAVE_GLOB
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <limits.h>
+#include <pwd.h>
+
+#include "sudo_compat.h"
+#include "compat/glob.h"
+#include "compat/charclass.h"
+
+#define DOLLAR '$'
+#define DOT '.'
+#define EOS '\0'
+#define LBRACKET '['
+#define NOT '!'
+#define QUESTION '?'
+#define QUOTE '\\'
+#define RANGE '-'
+#define RBRACKET ']'
+#define SEP '/'
+#define STAR '*'
+#define TILDE '~'
+#define UNDERSCORE '_'
+#define LBRACE '{'
+#define RBRACE '}'
+#define SLASH '/'
+#define COMMA ','
+
+#ifndef DEBUG
+
+#define M_QUOTE 0x8000
+#define M_PROTECT 0x4000
+#define M_MASK 0xffff
+#define M_ASCII 0x00ff
+
+typedef unsigned short Char;
+
+#else
+
+#define M_QUOTE 0x80
+#define M_PROTECT 0x40
+#define M_MASK 0xff
+#define M_ASCII 0x7f
+
+typedef char Char;
+
+#endif
+
+
+#define CHAR(c) ((Char)((c)&M_ASCII))
+#define META(c) ((Char)((c)|M_QUOTE))
+#define M_ALL META('*')
+#define M_END META(']')
+#define M_NOT META('!')
+#define M_ONE META('?')
+#define M_RNG META('-')
+#define M_SET META('[')
+#define M_CLASS META(':')
+#define ismeta(c) (((c)&M_QUOTE) != 0)
+
+#define GLOB_LIMIT_MALLOC 65536
+#define GLOB_LIMIT_STAT 2048
+#define GLOB_LIMIT_READDIR 16384
+
+struct glob_lim {
+ size_t glim_malloc;
+ size_t glim_stat;
+ size_t glim_readdir;
+};
+
+static int compare(const void *, const void *);
+static int g_Ctoc(const Char *, char *, unsigned int);
+static int g_lstat(Char *, struct stat *, glob_t *);
+static DIR *g_opendir(Char *, glob_t *);
+static Char *g_strchr(const Char *, int);
+static int g_strncmp(const Char *, const char *, size_t);
+static int g_stat(Char *, struct stat *, glob_t *);
+static int glob0(const Char *, glob_t *, struct glob_lim *);
+static int glob1(Char *, Char *, glob_t *, struct glob_lim *);
+static int glob2(Char *, Char *, Char *, Char *, Char *, Char *,
+ glob_t *, struct glob_lim *);
+static int glob3(Char *, Char *, Char *, Char *, Char *,
+ Char *, Char *, glob_t *, struct glob_lim *);
+static int globextend(const Char *, glob_t *, struct glob_lim *,
+ struct stat *);
+static const Char *
+ globtilde(const Char *, Char *, size_t, glob_t *);
+static int globexp1(const Char *, glob_t *, struct glob_lim *);
+static int globexp2(const Char *, const Char *, glob_t *,
+ struct glob_lim *);
+static int match(Char *, Char *, Char *);
+#ifdef DEBUG
+static void qprintf(const char *, Char *);
+#endif
+
+int
+sudo_glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
+ glob_t *pglob)
+{
+ const unsigned char *patnext;
+ int c;
+ Char *bufnext, *bufend, patbuf[PATH_MAX];
+ struct glob_lim limit = { 0, 0, 0 };
+
+ patnext = (unsigned char *) pattern;
+ if (!(flags & GLOB_APPEND)) {
+ pglob->gl_pathc = 0;
+ pglob->gl_pathv = NULL;
+ if (!(flags & GLOB_DOOFFS))
+ pglob->gl_offs = 0;
+ }
+ pglob->gl_flags = flags & ~GLOB_MAGCHAR;
+ pglob->gl_errfunc = errfunc;
+ pglob->gl_matchc = 0;
+
+ if (pglob->gl_offs < 0 || pglob->gl_pathc < 0 ||
+ pglob->gl_offs >= INT_MAX || pglob->gl_pathc >= INT_MAX ||
+ pglob->gl_pathc >= INT_MAX - pglob->gl_offs - 1)
+ return GLOB_NOSPACE;
+
+ if (strnlen(pattern, PATH_MAX) == PATH_MAX)
+ return GLOB_NOMATCH;
+
+ bufnext = patbuf;
+ bufend = bufnext + PATH_MAX - 1;
+ if (flags & GLOB_NOESCAPE)
+ while (bufnext < bufend && (c = *patnext++) != EOS)
+ *bufnext++ = c;
+ else {
+ /* Protect the quoted characters. */
+ while (bufnext < bufend && (c = *patnext++) != EOS)
+ if (c == QUOTE) {
+ if ((c = *patnext++) == EOS) {
+ c = QUOTE;
+ --patnext;
+ }
+ *bufnext++ = c | M_PROTECT;
+ } else
+ *bufnext++ = c;
+ }
+ *bufnext = EOS;
+
+ if (flags & GLOB_BRACE)
+ return globexp1(patbuf, pglob, &limit);
+ else
+ return glob0(patbuf, pglob, &limit);
+}
+
+/*
+ * Expand recursively a glob {} pattern. When there is no more expansion
+ * invoke the standard globbing routine to glob the rest of the magic
+ * characters
+ */
+static int
+globexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
+{
+ const Char* ptr = pattern;
+
+ /* Protect a single {}, for find(1), like csh */
+ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
+ return glob0(pattern, pglob, limitp);
+
+ if ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL)
+ return globexp2(ptr, pattern, pglob, limitp);
+
+ return glob0(pattern, pglob, limitp);
+}
+
+
+/*
+ * Recursive brace globbing helper. Tries to expand a single brace.
+ * If it succeeds then it invokes globexp1 with the new pattern.
+ * If it fails then it tries to glob the rest of the pattern and returns.
+ */
+static int
+globexp2(const Char *ptr, const Char *pattern, glob_t *pglob,
+ struct glob_lim *limitp)
+{
+ int i, rv;
+ Char *lm, *ls;
+ const Char *pe, *pm, *pl;
+ Char patbuf[PATH_MAX];
+
+ /* copy part up to the brace */
+ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
+ continue;
+ *lm = EOS;
+ ls = lm;
+
+ /* Find the balanced brace */
+ for (i = 0, pe = ++ptr; *pe; pe++)
+ if (*pe == LBRACKET) {
+ /* Ignore everything between [] */
+ for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
+ continue;
+ if (*pe == EOS) {
+ /*
+ * We could not find a matching RBRACKET.
+ * Ignore and just look for RBRACE
+ */
+ pe = pm;
+ }
+ } else if (*pe == LBRACE)
+ i++;
+ else if (*pe == RBRACE) {
+ if (i == 0)
+ break;
+ i--;
+ }
+
+ /* Non matching braces; just glob the pattern */
+ if (i != 0 || *pe == EOS)
+ return glob0(patbuf, pglob, limitp);
+
+ for (i = 0, pl = pm = ptr; pm <= pe; pm++) {
+ switch (*pm) {
+ case LBRACKET:
+ /* Ignore everything between [] */
+ for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
+ continue;
+ if (*pm == EOS) {
+ /*
+ * We could not find a matching RBRACKET.
+ * Ignore and just look for RBRACE
+ */
+ pm = pl;
+ }
+ break;
+
+ case LBRACE:
+ i++;
+ break;
+
+ case RBRACE:
+ if (i) {
+ i--;
+ break;
+ }
+ /* FALLTHROUGH */
+ case COMMA:
+ if (i && *pm == COMMA)
+ break;
+ else {
+ /* Append the current string */
+ for (lm = ls; (pl < pm); *lm++ = *pl++)
+ continue;
+
+ /*
+ * Append the rest of the pattern after the
+ * closing brace
+ */
+ for (pl = pe + 1; (*lm++ = *pl++) != EOS; )
+ continue;
+
+ /* Expand the current pattern */
+#ifdef DEBUG
+ qprintf("globexp2:", patbuf);
+#endif
+ rv = globexp1(patbuf, pglob, limitp);
+ if (rv && rv != GLOB_NOMATCH)
+ return rv;
+
+ /* move after the comma, to the next string */
+ pl = pm + 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+
+
+/*
+ * expand tilde from the passwd file.
+ */
+static const Char *
+globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
+{
+ struct passwd *pwd;
+ char *h;
+ const Char *p;
+ Char *b, *eb;
+
+ if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
+ return pattern;
+
+ /* Copy up to the end of the string or / */
+ eb = &patbuf[patbuf_len - 1];
+ for (p = pattern + 1, h = (char *) patbuf;
+ h < (char *)eb && *p && *p != SLASH; *h++ = *p++)
+ continue;
+
+ *h = EOS;
+
+ if (((char *) patbuf)[0] == EOS) {
+ /*
+ * handle a plain ~ or ~/ by expanding $HOME
+ * first and then trying the password file
+ */
+ if ((h = getenv("HOME")) == NULL) {
+ if ((pwd = getpwuid(getuid())) == NULL)
+ return pattern;
+ else
+ h = pwd->pw_dir;
+ }
+ } else {
+ /*
+ * Expand a ~user
+ */
+ if ((pwd = getpwnam((char*) patbuf)) == NULL)
+ return pattern;
+ else
+ h = pwd->pw_dir;
+ }
+
+ /* Copy the home directory */
+ for (b = patbuf; b < eb && *h; *b++ = *h++)
+ continue;
+
+ /* Append the rest of the pattern */
+ while (b < eb && (*b++ = *p++) != EOS)
+ continue;
+ *b = EOS;
+
+ return patbuf;
+}
+
+static int
+g_strncmp(const Char *s1, const char *s2, size_t n)
+{
+ int rv = 0;
+
+ while (n--) {
+ rv = *(Char *)s1 - *(const unsigned char *)s2++;
+ if (rv)
+ break;
+ if (*s1++ == '\0')
+ break;
+ }
+ return rv;
+}
+
+static int
+g_charclass(const Char **patternp, Char **bufnextp)
+{
+ const Char *pattern = *patternp + 1;
+ Char *bufnext = *bufnextp;
+ const Char *colon;
+ struct cclass *cc;
+ size_t len;
+
+ if ((colon = g_strchr(pattern, ':')) == NULL || colon[1] != ']')
+ return 1; /* not a character class */
+
+ len = (size_t)(colon - pattern);
+ for (cc = cclasses; cc->name != NULL; cc++) {
+ if (!g_strncmp(pattern, cc->name, len) && cc->name[len] == '\0')
+ break;
+ }
+ if (cc->name == NULL)
+ return -1; /* invalid character class */
+ *bufnext++ = M_CLASS;
+ *bufnext++ = (Char)(cc - &cclasses[0]);
+ *bufnextp = bufnext;
+ *patternp += len + 3;
+
+ return 0;
+}
+
+/*
+ * The main glob() routine: compiles the pattern (optionally processing
+ * quotes), calls glob1() to do the real pattern matching, and finally
+ * sorts the list (unless unsorted operation is requested). Returns 0
+ * if things went well, nonzero if errors occurred. It is not an error
+ * to find no matches.
+ */
+static int
+glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
+{
+ const Char *qpatnext;
+ int c, err, oldpathc;
+ Char *bufnext, patbuf[PATH_MAX];
+
+ qpatnext = globtilde(pattern, patbuf, PATH_MAX, pglob);
+ oldpathc = pglob->gl_pathc;
+ bufnext = patbuf;
+
+ /* We don't need to check for buffer overflow any more. */
+ while ((c = *qpatnext++) != EOS) {
+ switch (c) {
+ case LBRACKET:
+ c = *qpatnext;
+ if (c == NOT)
+ ++qpatnext;
+ if (*qpatnext == EOS ||
+ g_strchr(qpatnext+1, RBRACKET) == NULL) {
+ *bufnext++ = LBRACKET;
+ if (c == NOT)
+ --qpatnext;
+ break;
+ }
+ *bufnext++ = M_SET;
+ if (c == NOT)
+ *bufnext++ = M_NOT;
+ c = *qpatnext++;
+ do {
+ if (c == LBRACKET && *qpatnext == ':') {
+ do {
+ err = g_charclass(&qpatnext,
+ &bufnext);
+ if (err)
+ break;
+ c = *qpatnext++;
+ } while (c == LBRACKET && *qpatnext == ':');
+ if (err == -1 &&
+ !(pglob->gl_flags & GLOB_NOCHECK))
+ return GLOB_NOMATCH;
+ if (c == RBRACKET)
+ break;
+ }
+ *bufnext++ = CHAR(c);
+ if (*qpatnext == RANGE &&
+ (c = qpatnext[1]) != RBRACKET) {
+ *bufnext++ = M_RNG;
+ *bufnext++ = CHAR(c);
+ qpatnext += 2;
+ }
+ } while ((c = *qpatnext++) != RBRACKET);
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ *bufnext++ = M_END;
+ break;
+ case QUESTION:
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ *bufnext++ = M_ONE;
+ break;
+ case STAR:
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ /* collapse adjacent stars to one,
+ * to avoid exponential behavior
+ */
+ if (bufnext == patbuf || bufnext[-1] != M_ALL)
+ *bufnext++ = M_ALL;
+ break;
+ default:
+ *bufnext++ = CHAR(c);
+ break;
+ }
+ }
+ *bufnext = EOS;
+#ifdef DEBUG
+ qprintf("glob0:", patbuf);
+#endif
+
+ if ((err = glob1(patbuf, patbuf + PATH_MAX - 1, pglob, limitp)) != 0)
+ return err;
+
+ /*
+ * If there was no match we are going to append the pattern
+ * if GLOB_NOCHECK was specified.
+ */
+ if (pglob->gl_pathc == oldpathc) {
+ if ((pglob->gl_flags & GLOB_NOCHECK))
+ return globextend(pattern, pglob, limitp, NULL);
+ else
+ return GLOB_NOMATCH;
+ }
+ if (!(pglob->gl_flags & GLOB_NOSORT)) {
+ qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
+ pglob->gl_pathc - oldpathc, sizeof(char *), compare);
+ }
+ return 0;
+}
+
+static int
+compare(const void *p, const void *q)
+{
+ return strcmp(*(char **)p, *(char **)q);
+}
+
+static int
+glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)
+{
+ Char pathbuf[PATH_MAX];
+
+ /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
+ if (*pattern == EOS)
+ return 0;
+ return glob2(pathbuf, pathbuf + PATH_MAX - 1,
+ pathbuf, pathbuf + PATH_MAX - 1,
+ pattern, pattern_last, pglob, limitp);
+}
+
+/*
+ * The functions glob2 and glob3 are mutually recursive; there is one level
+ * of recursion for each segment in the pattern that contains one or more
+ * meta characters.
+ */
+static int
+glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
+ Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)
+{
+ struct stat sb;
+ Char *p, *q;
+ int anymeta;
+
+ /*
+ * Loop over pattern segments until end of pattern or until
+ * segment with meta character found.
+ */
+ for (anymeta = 0;;) {
+ if (*pattern == EOS) { /* End of pattern? */
+ *pathend = EOS;
+
+ if ((pglob->gl_flags & GLOB_LIMIT) &&
+ limitp->glim_stat++ >= GLOB_LIMIT_STAT) {
+ errno = 0;
+ *pathend++ = SEP;
+ *pathend = EOS;
+ return GLOB_NOSPACE;
+ }
+ if (g_lstat(pathbuf, &sb, pglob))
+ return 0;
+
+ if (((pglob->gl_flags & GLOB_MARK) &&
+ pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ||
+ (S_ISLNK(sb.st_mode) &&
+ (g_stat(pathbuf, &sb, pglob) == 0) &&
+ S_ISDIR(sb.st_mode)))) {
+ if (pathend+1 > pathend_last)
+ return 1;
+ *pathend++ = SEP;
+ *pathend = EOS;
+ }
+ ++pglob->gl_matchc;
+ return globextend(pathbuf, pglob, limitp, &sb);
+ }
+
+ /* Find end of next segment, copy tentatively to pathend. */
+ q = pathend;
+ p = pattern;
+ while (*p != EOS && *p != SEP) {
+ if (ismeta(*p))
+ anymeta = 1;
+ if (q+1 > pathend_last)
+ return 1;
+ *q++ = *p++;
+ }
+
+ if (!anymeta) { /* No expansion, do next segment. */
+ pathend = q;
+ pattern = p;
+ while (*pattern == SEP) {
+ if (pathend+1 > pathend_last)
+ return 1;
+ *pathend++ = *pattern++;
+ }
+ } else
+ /* Need expansion, recurse. */
+ return glob3(pathbuf, pathbuf_last, pathend,
+ pathend_last, pattern, p, pattern_last,
+ pglob, limitp);
+ }
+ /* NOTREACHED */
+}
+
+static int
+glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
+ Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob,
+ struct glob_lim *limitp)
+{
+ struct dirent *dp;
+ DIR *dirp;
+ int err;
+ char buf[PATH_MAX];
+
+ if (pathend > pathend_last)
+ return 1;
+ *pathend = EOS;
+ errno = 0;
+
+ if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
+ /* TODO: don't call for ENOENT or ENOTDIR? */
+ if (pglob->gl_errfunc) {
+ if (g_Ctoc(pathbuf, buf, sizeof(buf)))
+ return GLOB_ABORTED;
+ if (pglob->gl_errfunc(buf, errno) ||
+ pglob->gl_flags & GLOB_ERR)
+ return GLOB_ABORTED;
+ }
+ return 0;
+ }
+
+ err = 0;
+
+ /* Search directory for matching names. */
+ while ((dp = readdir(dirp))) {
+ unsigned char *sc;
+ Char *dc;
+
+ if ((pglob->gl_flags & GLOB_LIMIT) &&
+ limitp->glim_readdir++ >= GLOB_LIMIT_READDIR) {
+ errno = 0;
+ *pathend++ = SEP;
+ *pathend = EOS;
+ err = GLOB_NOSPACE;
+ break;
+ }
+
+ /* Initial DOT must be matched literally. */
+ if (dp->d_name[0] == DOT && *pattern != DOT)
+ continue;
+ dc = pathend;
+ sc = (unsigned char *) dp->d_name;
+ while (dc < pathend_last && (*dc++ = *sc++) != EOS)
+ continue;
+ if (dc >= pathend_last) {
+ *dc = EOS;
+ err = 1;
+ break;
+ }
+
+ if (!match(pathend, pattern, restpattern)) {
+ *pathend = EOS;
+ continue;
+ }
+ err = glob2(pathbuf, pathbuf_last, --dc, pathend_last,
+ restpattern, restpattern_last, pglob, limitp);
+ if (err)
+ break;
+ }
+
+ closedir(dirp);
+ return err;
+}
+
+/*
+ * Extend the gl_pathv member of a glob_t structure to accommodate a new item,
+ * add the new item, and update gl_pathc.
+ *
+ * This assumes the BSD realloc, which only copies the block when its size
+ * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
+ * behavior.
+ *
+ * Return 0 if new item added, error code if memory couldn't be allocated.
+ *
+ * Invariant of the glob_t structure:
+ * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
+ * gl_pathv points to (gl_offs + gl_pathc + 1) items.
+ */
+static int
+globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp,
+ struct stat *sb)
+{
+ char **pathv;
+ ssize_t i;
+ size_t newn, len;
+ char *copy = NULL;
+ const Char *p;
+
+ newn = 2 + pglob->gl_pathc + pglob->gl_offs;
+ if (pglob->gl_offs >= INT_MAX ||
+ pglob->gl_pathc >= INT_MAX ||
+ newn >= INT_MAX ||
+ SIZE_MAX / sizeof(*pathv) <= newn) {
+ nospace:
+ for (i = pglob->gl_offs; i < (ssize_t)(newn - 2); i++) {
+ if (pglob->gl_pathv && pglob->gl_pathv[i])
+ free(pglob->gl_pathv[i]);
+ }
+ if (pglob->gl_pathv) {
+ free(pglob->gl_pathv);
+ pglob->gl_pathv = NULL;
+ }
+ return GLOB_NOSPACE;
+ }
+
+ pathv = reallocarray(pglob->gl_pathv, newn, sizeof(*pathv));
+ if (pathv == NULL)
+ goto nospace;
+ if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
+ /* first time around -- clear initial gl_offs items */
+ pathv += pglob->gl_offs;
+ for (i = pglob->gl_offs; --i >= 0; )
+ *--pathv = NULL;
+ }
+ pglob->gl_pathv = pathv;
+
+ for (p = path; *p++;)
+ continue;
+ len = (size_t)(p - path);
+ limitp->glim_malloc += len;
+ if ((copy = malloc(len)) != NULL) {
+ if (g_Ctoc(path, copy, len)) {
+ free(copy);
+ return GLOB_NOSPACE;
+ }
+ pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
+ }
+ pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
+
+ if ((pglob->gl_flags & GLOB_LIMIT) &&
+ (newn * sizeof(*pathv)) + limitp->glim_malloc >
+ GLOB_LIMIT_MALLOC) {
+ errno = 0;
+ return GLOB_NOSPACE;
+ }
+ return copy == NULL ? GLOB_NOSPACE : 0;
+}
+
+
+/*
+ * pattern matching function for filenames. Each occurrence of the *
+ * pattern causes an iteration.
+ *
+ * Note, this function differs from the original as per the discussion
+ * here: https://research.swtch.com/glob
+ *
+ * Basically we removed the recursion and made it use the algorithm
+ * from Russ Cox to not go quadratic on cases like a file called
+ * ("a" x 100) . "x" matched against a pattern like "a*a*a*a*a*a*a*y".
+ */
+static int
+match(Char *name, Char *pat, Char *patend)
+{
+ int ok, negate_range;
+ Char c, k;
+ Char *nextp = NULL;
+ Char *nextn = NULL;
+
+loop:
+ while (pat < patend) {
+ c = *pat++;
+ switch (c & M_MASK) {
+ case M_ALL:
+ while (pat < patend && (*pat & M_MASK) == M_ALL)
+ pat++; /* eat consecutive '*' */
+ if (pat == patend)
+ return 1;
+ if (*name == EOS)
+ return 0;
+ nextn = name + 1;
+ nextp = pat - 1;
+ break;
+ case M_ONE:
+ if (*name++ == EOS)
+ goto fail;
+ break;
+ case M_SET:
+ ok = 0;
+ if ((k = *name++) == EOS)
+ goto fail;
+ if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
+ ++pat;
+ while (((c = *pat++) & M_MASK) != M_END) {
+ if ((c & M_MASK) == M_CLASS) {
+ Char idx = *pat & M_MASK;
+ if (idx < NCCLASSES &&
+ cclasses[idx].isctype(k))
+ ok = 1;
+ ++pat;
+ }
+ if ((*pat & M_MASK) == M_RNG) {
+ if (c <= k && k <= pat[1])
+ ok = 1;
+ pat += 2;
+ } else if (c == k)
+ ok = 1;
+ }
+ if (ok == negate_range)
+ goto fail;
+ break;
+ default:
+ if (*name++ != c)
+ goto fail;
+ break;
+ }
+ }
+ if (*name == EOS)
+ return 1;
+fail:
+ if (nextn) {
+ pat = nextp;
+ name = nextn;
+ goto loop;
+ }
+ return 0;
+}
+
+/* Free allocated data belonging to a glob_t structure. */
+void
+sudo_globfree(glob_t *pglob)
+{
+ int i;
+ char **pp;
+
+ if (pglob->gl_pathv != NULL) {
+ pp = pglob->gl_pathv + pglob->gl_offs;
+ for (i = pglob->gl_pathc; i--; ++pp)
+ if (*pp)
+ free(*pp);
+ free(pglob->gl_pathv);
+ pglob->gl_pathv = NULL;
+ }
+}
+
+static DIR *
+g_opendir(Char *str, glob_t *pglob)
+{
+ char buf[PATH_MAX];
+
+ if (!*str) {
+ buf[0] = '.';
+ buf[1] = '\0';
+ } else {
+ if (g_Ctoc(str, buf, sizeof(buf)))
+ return NULL;
+ }
+
+ return opendir(buf);
+}
+
+static int
+g_lstat(Char *fn, struct stat *sb, glob_t *pglob)
+{
+ char buf[PATH_MAX];
+
+ if (g_Ctoc(fn, buf, sizeof(buf)))
+ return -1;
+ return lstat(buf, sb);
+}
+
+static int
+g_stat(Char *fn, struct stat *sb, glob_t *pglob)
+{
+ char buf[PATH_MAX];
+
+ if (g_Ctoc(fn, buf, sizeof(buf)))
+ return -1;
+ return stat(buf, sb);
+}
+
+static Char *
+g_strchr(const Char *str, int ch)
+{
+ do {
+ if (*str == ch)
+ return (Char *)str;
+ } while (*str++);
+ return NULL;
+}
+
+static int
+g_Ctoc(const Char *str, char *buf, unsigned int len)
+{
+
+ while (len--) {
+ if ((*buf++ = *str++) == EOS)
+ return 0;
+ }
+ return 1;
+}
+
+#ifdef DEBUG
+static void
+qprintf(const char *str, Char *s)
+{
+ Char *p;
+
+ (void)printf("%s:\n", str);
+ for (p = s; *p; p++)
+ (void)printf("%c", CHAR(*p));
+ (void)printf("\n");
+ for (p = s; *p; p++)
+ (void)printf("%c", *p & M_PROTECT ? '"' : ' ');
+ (void)printf("\n");
+ for (p = s; *p; p++)
+ (void)printf("%c", ismeta(*p) ? '_' : ' ');
+ (void)printf("\n");
+}
+#endif /* DEBUG */
+#endif /* HAVE_GLOB */
diff --git a/lib/util/inet_ntop.c b/lib/util/inet_ntop.c
new file mode 100644
index 0000000..f9072c5
--- /dev/null
+++ b/lib/util/inet_ntop.c
@@ -0,0 +1,229 @@
+/* $OpenBSD: inet_ntop.c,v 1.9 2014/02/05 14:20:43 millert Exp $ */
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include <config.h>
+
+#if !defined(HAVE_INET_NTOP)
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "sudo_compat.h"
+
+#ifndef EAFNOSUPPORT
+# define EAFNOSUPPORT EINVAL
+#endif
+
+#ifndef NS_IN6ADDRSZ
+# ifdef IN6ADDRSZ
+# define NS_IN6ADDRSZ IN6ADDRSZ
+# else
+# define NS_IN6ADDRSZ 16
+# endif
+#endif
+#ifndef NS_INT16SZ
+# ifdef INT16SZ
+# define NS_INT16SZ INT16SZ
+# else
+# define NS_INT16SZ 2
+# endif
+#endif
+#ifndef INET6_ADDRSTRLEN
+# define INET6_ADDRSTRLEN 46
+#endif
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ * format an IPv4 address, more or less like inet_ntoa()
+ * return:
+ * `dst' (as a const)
+ * notes:
+ * (1) uses no statics
+ * (2) takes a unsigned char* not an in_addr as input
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(const unsigned char *src, char *dst, socklen_t size)
+{
+ const char fmt[] = "%u.%u.%u.%u";
+ int len;
+
+ len = snprintf(dst, size, fmt, src[0], src[1], src[2], src[3]);
+ if (len <= 0 || len >= size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ return (dst);
+}
+
+#ifdef HAVE_STRUCT_IN6_ADDR
+/* const char *
+ * inet_ntop6(src, dst, size)
+ * convert IPv6 binary address into presentation (printable) format
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop6(const unsigned char *src, char *dst, socklen_t size)
+{
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char *cp, *ep;
+ struct { int base, len; } best, cur;
+ unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
+ int i;
+ int advance;
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, 0, sizeof(words));
+ for (i = 0; i < NS_IN6ADDRSZ; i++)
+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ best.base = -1;
+ best.len = 0;
+ cur.base = -1;
+ cur.len = 0;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ if (words[i] == 0) {
+ if (cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ } else {
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ }
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ }
+ if (best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ cp = dst;
+ ep = dst + size;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ) && cp < ep; i++) {
+ /* Are we inside the best run of 0x00's? */
+ if (best.base != -1 && i >= best.base &&
+ i < (best.base + best.len)) {
+ if (i == best.base) {
+ if (cp + 1 >= ep) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ *cp++ = ':';
+ }
+ continue;
+ }
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if (i != 0) {
+ if (cp + 1 >= ep) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ *cp++ = ':';
+ }
+ /* Is this address an encapsulated IPv4? */
+ if (i == 6 && best.base == 0 &&
+ (best.len == 6 ||
+ (best.len == 7 && words[7] != 0x0001) ||
+ (best.len == 5 && words[5] == 0xffff))) {
+ if (!inet_ntop4(src + 12, cp, (socklen_t)(ep - cp)))
+ return (NULL);
+ cp += strlen(cp);
+ break;
+ }
+ advance = snprintf(cp, (size_t)(ep - cp), "%x", words[i]);
+ if (advance <= 0 || advance >= ep - cp) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ cp += advance;
+ }
+ /* Was it a trailing run of 0x00's? */
+ if (best.base != -1 &&
+ (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) {
+ if (cp + 1 >= ep) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ *cp++ = ':';
+ }
+ if (cp + 1 >= ep) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ *cp++ = '\0';
+
+ return (dst);
+}
+#endif /* HAVE_STRUCT_IN6_ADDR */
+
+/* const char *
+ * inet_ntop(af, src, dst, size)
+ * convert a network format address to presentation format.
+ * return:
+ * pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ * Paul Vixie, 1996.
+ */
+const char *
+sudo_inet_ntop(int af, const void *src, char *dst, socklen_t size)
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_ntop4(src, dst, size));
+#ifdef HAVE_STRUCT_IN6_ADDR
+ case AF_INET6:
+ return (inet_ntop6(src, dst, size));
+#endif
+ default:
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+ /* NOTREACHED */
+}
+
+#endif /* !HAVE_INET_NTOP */
diff --git a/lib/util/inet_pton.c b/lib/util/inet_pton.c
new file mode 100644
index 0000000..ba3ec61
--- /dev/null
+++ b/lib/util/inet_pton.c
@@ -0,0 +1,254 @@
+/* $OpenBSD: inet_pton.c,v 1.8 2010/05/06 15:47:14 claudio Exp $ */
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include <config.h>
+
+#if !defined(HAVE_INET_PTON)
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <errno.h>
+
+#include "sudo_compat.h"
+
+#ifndef EAFNOSUPPORT
+# define EAFNOSUPPORT EINVAL
+#endif
+
+#ifndef NS_INADDRSZ
+# ifdef INADDRSZ
+# define NS_INADDRSZ INADDRSZ
+# else
+# define NS_INADDRSZ 4
+# endif
+#endif
+#ifndef NS_IN6ADDRSZ
+# ifdef IN6ADDRSZ
+# define NS_IN6ADDRSZ IN6ADDRSZ
+# else
+# define NS_IN6ADDRSZ 16
+# endif
+#endif
+#ifndef NS_INT16SZ
+# ifdef INT16SZ
+# define NS_INT16SZ INT16SZ
+# else
+# define NS_INT16SZ 2
+# endif
+#endif
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+/* int
+ * inet_pton4(src, dst)
+ * like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ * 1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ * does not touch `dst' unless it's returning 1.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, u_char *dst)
+{
+ const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ u_char tmp[NS_INADDRSZ], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ /* cppcheck-suppress uninitvar */
+ *(tp = tmp) = '\0';
+ while ((ch = (unsigned char)*src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr(digits, ch)) != NULL) {
+ u_int new = *tp * 10 + (pch - digits);
+
+ if (new > 255)
+ return (0);
+ if (!saw_digit) {
+ if (++octets > 4)
+ return (0);
+ saw_digit = 1;
+ }
+ *tp = new;
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return (0);
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return (0);
+ }
+ if (octets < 4)
+ return (0);
+
+ memcpy(dst, tmp, NS_INADDRSZ);
+ return (1);
+}
+
+#ifdef HAVE_STRUCT_IN6_ADDR
+/* int
+ * inet_pton6(src, dst)
+ * convert presentation level address to network order binary form.
+ * return:
+ * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ * does not touch `dst' unless it's returning 1.
+ * credit:
+ * inspired by Mark Andrews.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, u_char *dst)
+{
+ const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+ const char *xdigits, *curtok;
+ int ch, saw_xdigit, count_xdigit;
+ u_int val;
+
+ /* cppcheck-suppress uninitvar */
+ memset((tp = tmp), 0, NS_IN6ADDRSZ);
+ endp = tp + NS_IN6ADDRSZ;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if (*src == ':')
+ if (*++src != ':')
+ return (0);
+ curtok = src;
+ saw_xdigit = count_xdigit = 0;
+ val = 0;
+ while ((ch = (unsigned char)*src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if (pch != NULL) {
+ if (count_xdigit >= 4)
+ return (0);
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (val > 0xffff)
+ return (0);
+ saw_xdigit = 1;
+ count_xdigit++;
+ continue;
+ }
+ if (ch == ':') {
+ curtok = src;
+ if (!saw_xdigit) {
+ if (colonp)
+ return (0);
+ colonp = tp;
+ continue;
+ } else if (*src == '\0') {
+ return (0);
+ }
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ saw_xdigit = 0;
+ count_xdigit = 0;
+ val = 0;
+ continue;
+ }
+ if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+ inet_pton4(curtok, tp) > 0) {
+ tp += NS_INADDRSZ;
+ saw_xdigit = 0;
+ count_xdigit = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ return (0);
+ }
+ if (saw_xdigit) {
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ }
+ if (colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const long n = tp - colonp;
+ long i;
+
+ if (tp == endp)
+ return (0);
+ for (i = 1; i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if (tp != endp)
+ return (0);
+ memcpy(dst, tmp, NS_IN6ADDRSZ);
+ return (1);
+}
+#endif /* HAVE_STRUCT_IN6_ADDR */
+
+/* int
+ * inet_pton(af, src, dst)
+ * convert from presentation format (which usually means ASCII printable)
+ * to network format (which is usually some kind of binary format).
+ * return:
+ * 1 if the address was valid for the specified address family
+ * 0 if the address wasn't valid (`dst' is untouched in this case)
+ * -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ * Paul Vixie, 1996.
+ */
+int
+sudo_inet_pton(int af, const char *src, void *dst)
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_pton4(src, dst));
+#ifdef HAVE_STRUCT_IN6_ADDR
+ case AF_INET6:
+ return (inet_pton6(src, dst));
+#endif /* HAVE_STRUCT_IN6_ADDR */
+ default:
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+ /* NOTREACHED */
+}
+
+#endif /* HAVE_INET_PTON */
diff --git a/lib/util/isblank.c b/lib/util/isblank.c
new file mode 100644
index 0000000..54f88a5
--- /dev/null
+++ b/lib/util/isblank.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2008, 2010-2011, 2013
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_ISBLANK
+
+#include <sys/types.h>
+
+#include "sudo_compat.h"
+
+#undef isblank
+int
+isblank(int ch)
+{
+ return ch == ' ' || ch == '\t';
+}
+#endif /* HAVE_ISBLANK */
diff --git a/lib/util/key_val.c b/lib/util/key_val.c
new file mode 100644
index 0000000..9bbd043
--- /dev/null
+++ b/lib/util/key_val.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010-2012, 2014-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+/*
+ * Create a new key=value pair and return it.
+ * The caller is responsible for freeing the string.
+ */
+char *
+sudo_new_key_val_v1(const char *key, const char *val)
+{
+ size_t key_len = strlen(key);
+ size_t val_len = strlen(val);
+ char *cp, *str;
+ debug_decl(sudo_new_key_val, SUDO_DEBUG_UTIL)
+
+ cp = str = malloc(key_len + 1 + val_len + 1);
+ if (cp != NULL) {
+ memcpy(cp, key, key_len);
+ cp += key_len;
+ *cp++ = '=';
+ memcpy(cp, val, val_len);
+ cp += val_len;
+ *cp = '\0';
+ }
+
+ debug_return_str(str);
+}
diff --git a/lib/util/lbuf.c b/lib/util/lbuf.c
new file mode 100644
index 0000000..5e48258
--- /dev/null
+++ b/lib/util/lbuf.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2007-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <ctype.h>
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_lbuf.h"
+
+void
+sudo_lbuf_init_v1(struct sudo_lbuf *lbuf, sudo_lbuf_output_t output,
+ int indent, const char *continuation, int cols)
+{
+ debug_decl(sudo_lbuf_init, SUDO_DEBUG_UTIL)
+
+ lbuf->output = output;
+ lbuf->continuation = continuation;
+ lbuf->indent = indent;
+ lbuf->cols = cols;
+ lbuf->error = 0;
+ lbuf->len = 0;
+ lbuf->size = 0;
+ lbuf->buf = NULL;
+
+ debug_return;
+}
+
+void
+sudo_lbuf_destroy_v1(struct sudo_lbuf *lbuf)
+{
+ debug_decl(sudo_lbuf_destroy, SUDO_DEBUG_UTIL)
+
+ free(lbuf->buf);
+ lbuf->buf = NULL;
+
+ debug_return;
+}
+
+static bool
+sudo_lbuf_expand(struct sudo_lbuf *lbuf, int extra)
+{
+ debug_decl(sudo_lbuf_expand, SUDO_DEBUG_UTIL)
+
+ if (lbuf->len + extra + 1 >= lbuf->size) {
+ char *new_buf;
+ int new_size = lbuf->size;
+
+ do {
+ new_size += 256;
+ } while (lbuf->len + extra + 1 >= new_size);
+ if ((new_buf = realloc(lbuf->buf, new_size)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ lbuf->error = 1;
+ debug_return_bool(false);
+ }
+ lbuf->buf = new_buf;
+ lbuf->size = new_size;
+ }
+ debug_return_bool(true);
+}
+
+/*
+ * Parse the format and append strings, only %s and %% escapes are supported.
+ * Any characters in set are quoted with a backslash.
+ */
+bool
+sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char *fmt, ...)
+{
+ int len, saved_len = lbuf->len;
+ bool ret = false;
+ char *cp, *s;
+ va_list ap;
+ debug_decl(sudo_lbuf_append_quoted, SUDO_DEBUG_UTIL)
+
+ if (sudo_lbuf_error(lbuf))
+ debug_return_bool(false);
+
+ va_start(ap, fmt);
+ while (*fmt != '\0') {
+ if (fmt[0] == '%' && fmt[1] == 's') {
+ if ((s = va_arg(ap, char *)) == NULL)
+ s = "(NULL)";
+ while ((cp = strpbrk(s, set)) != NULL) {
+ len = (int)(cp - s);
+ if (!sudo_lbuf_expand(lbuf, len + 2))
+ goto done;
+ memcpy(lbuf->buf + lbuf->len, s, len);
+ lbuf->len += len;
+ lbuf->buf[lbuf->len++] = '\\';
+ lbuf->buf[lbuf->len++] = *cp;
+ s = cp + 1;
+ }
+ if (*s != '\0') {
+ len = strlen(s);
+ if (!sudo_lbuf_expand(lbuf, len))
+ goto done;
+ memcpy(lbuf->buf + lbuf->len, s, len);
+ lbuf->len += len;
+ }
+ fmt += 2;
+ continue;
+ }
+ if (!sudo_lbuf_expand(lbuf, 2))
+ goto done;
+ if (strchr(set, *fmt) != NULL)
+ lbuf->buf[lbuf->len++] = '\\';
+ lbuf->buf[lbuf->len++] = *fmt++;
+ }
+ ret = true;
+
+done:
+ if (!ret)
+ lbuf->len = saved_len;
+ if (lbuf->size != 0)
+ lbuf->buf[lbuf->len] = '\0';
+ va_end(ap);
+
+ debug_return_bool(ret);
+}
+
+/*
+ * Parse the format and append strings, only %s and %% escapes are supported.
+ */
+bool
+sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...)
+{
+ int len, saved_len = lbuf->len;
+ bool ret = false;
+ va_list ap;
+ char *s;
+ debug_decl(sudo_lbuf_append, SUDO_DEBUG_UTIL)
+
+ if (sudo_lbuf_error(lbuf))
+ debug_return_bool(false);
+
+ va_start(ap, fmt);
+ while (*fmt != '\0') {
+ if (fmt[0] == '%' && fmt[1] == 's') {
+ if ((s = va_arg(ap, char *)) == NULL)
+ s = "(NULL)";
+ len = strlen(s);
+ if (!sudo_lbuf_expand(lbuf, len))
+ goto done;
+ memcpy(lbuf->buf + lbuf->len, s, len);
+ lbuf->len += len;
+ fmt += 2;
+ continue;
+ }
+ if (!sudo_lbuf_expand(lbuf, 1))
+ goto done;
+ lbuf->buf[lbuf->len++] = *fmt++;
+ }
+ ret = true;
+
+done:
+ if (!ret)
+ lbuf->len = saved_len;
+ if (lbuf->size != 0)
+ lbuf->buf[lbuf->len] = '\0';
+ va_end(ap);
+
+ debug_return_bool(ret);
+}
+
+/* XXX - check output function return value */
+static void
+sudo_lbuf_println(struct sudo_lbuf *lbuf, char *line, int len)
+{
+ char *cp, save;
+ int i, have, contlen = 0;
+ int indent = lbuf->indent;
+ bool is_comment = false;
+ debug_decl(sudo_lbuf_println, SUDO_DEBUG_UTIL)
+
+ /* Comment lines don't use continuation and only indent is for "# " */
+ if (line[0] == '#' && isblank((unsigned char)line[1])) {
+ is_comment = true;
+ indent = 2;
+ }
+ if (lbuf->continuation != NULL && !is_comment)
+ contlen = strlen(lbuf->continuation);
+
+ /*
+ * Print the buffer, splitting the line as needed on a word
+ * boundary.
+ */
+ cp = line;
+ have = lbuf->cols;
+ while (cp != NULL && *cp != '\0') {
+ char *ep = NULL;
+ int need = len - (int)(cp - line);
+
+ if (need > have) {
+ have -= contlen; /* subtract for continuation char */
+ if ((ep = memrchr(cp, ' ', have)) == NULL)
+ ep = memchr(cp + have, ' ', need - have);
+ if (ep != NULL)
+ need = (int)(ep - cp);
+ }
+ if (cp != line) {
+ if (is_comment) {
+ lbuf->output("# ");
+ } else {
+ /* indent continued lines */
+ /* XXX - build up string instead? */
+ for (i = 0; i < indent; i++)
+ lbuf->output(" ");
+ }
+ }
+ /* NUL-terminate cp for the output function and restore afterwards */
+ save = cp[need];
+ cp[need] = '\0';
+ lbuf->output(cp);
+ cp[need] = save;
+ cp = ep;
+
+ /*
+ * If there is more to print, reset have, incremement cp past
+ * the whitespace, and print a line continuaton char if needed.
+ */
+ if (cp != NULL) {
+ have = lbuf->cols - indent;
+ ep = line + len;
+ while (cp < ep && isblank((unsigned char)*cp)) {
+ cp++;
+ }
+ if (contlen)
+ lbuf->output(lbuf->continuation);
+ }
+ lbuf->output("\n");
+ }
+
+ debug_return;
+}
+
+/*
+ * Print the buffer with word wrap based on the tty width.
+ * The lbuf is reset on return.
+ * XXX - check output function return value
+ */
+void
+sudo_lbuf_print_v1(struct sudo_lbuf *lbuf)
+{
+ char *cp, *ep;
+ int len;
+ debug_decl(sudo_lbuf_print, SUDO_DEBUG_UTIL)
+
+ if (lbuf->buf == NULL || lbuf->len == 0)
+ goto done;
+
+ /* For very small widths just give up... */
+ len = lbuf->continuation ? strlen(lbuf->continuation) : 0;
+ if (lbuf->cols <= lbuf->indent + len + 20) {
+ if (lbuf->len > 0) {
+ lbuf->buf[lbuf->len] = '\0';
+ lbuf->output(lbuf->buf);
+ if (lbuf->buf[lbuf->len - 1] != '\n')
+ lbuf->output("\n");
+ }
+ goto done;
+ }
+
+ /* Print each line in the buffer */
+ for (cp = lbuf->buf; cp != NULL && *cp != '\0'; ) {
+ if (*cp == '\n') {
+ lbuf->output("\n");
+ cp++;
+ } else {
+ len = lbuf->len - (cp - lbuf->buf);
+ if ((ep = memchr(cp, '\n', len)) != NULL)
+ len = (int)(ep - cp);
+ if (len)
+ sudo_lbuf_println(lbuf, cp, len);
+ cp = ep ? ep + 1 : NULL;
+ }
+ }
+
+done:
+ lbuf->len = 0; /* reset the buffer for re-use. */
+ lbuf->error = 0;
+
+ debug_return;
+}
+
+bool
+sudo_lbuf_error_v1(struct sudo_lbuf *lbuf)
+{
+ if (lbuf != NULL && lbuf->error != 0)
+ return true;
+ return false;
+}
+
+void
+sudo_lbuf_clearerr_v1(struct sudo_lbuf *lbuf)
+{
+ if (lbuf != NULL)
+ lbuf->error = 0;
+}
diff --git a/lib/util/locking.c b/lib/util/locking.c
new file mode 100644
index 0000000..64499e6
--- /dev/null
+++ b/lib/util/locking.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 1999-2005, 2007, 2009-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+#include "sudo_debug.h"
+
+/*
+ * Lock/unlock all or part of a file.
+ */
+#ifdef HAVE_LOCKF
+bool
+sudo_lock_file_v1(int fd, int type)
+{
+ return sudo_lock_region_v1(fd, type, 0);
+}
+
+bool
+sudo_lock_region_v1(int fd, int type, off_t len)
+{
+ int op;
+ debug_decl(sudo_lock_region, SUDO_DEBUG_UTIL)
+
+ switch (type) {
+ case SUDO_LOCK:
+ op = F_LOCK;
+ break;
+ case SUDO_TLOCK:
+ op = F_TLOCK;
+ break;
+ case SUDO_UNLOCK:
+ op = F_ULOCK;
+ break;
+ default:
+ errno = EINVAL;
+ debug_return_bool(false);
+ }
+ debug_return_bool(lockf(fd, op, len) == 0);
+}
+#else
+bool
+sudo_lock_file_v1(int fd, int type)
+{
+ return sudo_lock_region_v1(fd, type, 0);
+}
+
+bool
+sudo_lock_region_v1(int fd, int type, off_t len)
+{
+ struct flock lock;
+ int func;
+ debug_decl(sudo_lock_file, SUDO_DEBUG_UTIL)
+
+ switch (type) {
+ case SUDO_LOCK:
+ lock.l_type = F_WRLCK;
+ func = F_SETLKW;
+ break;
+ case SUDO_TLOCK:
+ lock.l_type = F_WRLCK;
+ func = F_SETLK;
+ break;
+ case SUDO_UNLOCK:
+ lock.l_type = F_UNLCK;
+ func = F_SETLK;
+ break;
+ default:
+ errno = EINVAL;
+ debug_return_bool(false);
+ }
+ lock.l_start = 0;
+ lock.l_len = len;
+ lock.l_pid = 0;
+ lock.l_whence = len ? SEEK_CUR : SEEK_SET;
+
+ debug_return_bool(fcntl(fd, func, &lock) == 0);
+}
+#endif
diff --git a/lib/util/memrchr.c b/lib/util/memrchr.c
new file mode 100644
index 0000000..225b542
--- /dev/null
+++ b/lib/util/memrchr.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 2010-2014
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_MEMRCHR
+
+#include <sys/types.h>
+
+#include "sudo_compat.h"
+
+/*
+ * Reverse memchr()
+ * Find the last occurrence of 'c' in the buffer 's' of size 'n'.
+ */
+void *
+sudo_memrchr(const void *s, int c, size_t n)
+{
+ const unsigned char *cp;
+
+ if (n != 0) {
+ cp = (unsigned char *)s + n;
+ do {
+ if (*(--cp) == (unsigned char)c)
+ return (void *)cp;
+ } while (--n != 0);
+ }
+ return (void *)0;
+}
+#endif /* HAVE_MEMRCHR */
diff --git a/lib/util/memset_s.c b/lib/util/memset_s.c
new file mode 100644
index 0000000..2fea12d
--- /dev/null
+++ b/lib/util/memset_s.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2013-2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <limits.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+
+#include "sudo_compat.h"
+
+#ifndef RSIZE_MAX
+# if defined(SIZE_MAX)
+# define RSIZE_MAX (SIZE_MAX >> 1)
+# elif defined(__LP64__)
+# define RSIZE_MAX 0x7fffffffffffffffUL
+# else
+# define RSIZE_MAX 0x7fffffffU
+# endif
+#endif
+
+/*
+ * Simple implementation of C11 memset_s() function.
+ * We use a volatile pointer when updating the byte string.
+ * Most compilers will avoid optimizing away access to a
+ * volatile pointer, even if the pointer appears to be unused
+ * after the call.
+ *
+ * Note that C11 does not specify the return value on error, only
+ * that it be non-zero. We use EINVAL for all errors.
+ */
+errno_t
+sudo_memset_s(void *v, rsize_t smax, int c, rsize_t n)
+{
+ errno_t ret = 0;
+ volatile unsigned char *s = v;
+
+ /* Fatal runtime-constraint violations. */
+ if (s == NULL || smax > RSIZE_MAX) {
+ ret = errno = EINVAL;
+ goto done;
+ }
+ /* Non-fatal runtime-constraint violation, n must not exceed smax. */
+ if (n > smax) {
+ n = smax;
+ ret = errno = EINVAL;
+ }
+ /* Updating through a volatile pointer should not be optimized away. */
+ while (n--)
+ *s++ = (unsigned char)c;
+done:
+ return ret;
+}
diff --git a/lib/util/mksiglist.c b/lib/util/mksiglist.c
new file mode 100644
index 0000000..6b5d1ca
--- /dev/null
+++ b/lib/util/mksiglist.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2010-2012, 2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+
+#include "sudo_compat.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+int
+main(int argc, char *argv[])
+{
+ static char *sudo_sys_siglist[NSIG];
+ int i;
+
+#include "mksiglist.h"
+
+ printf("#include <config.h>\n");
+ printf("#include <sys/types.h>\n");
+ printf("#include <signal.h>\n");
+ printf("#include \"sudo_compat.h\"\n\n");
+ printf("const char *const sudo_sys_siglist[NSIG] = {\n");
+ for (i = 0; i < NSIG; i++) {
+ if (sudo_sys_siglist[i] != NULL) {
+ printf(" \"%s\",\n", sudo_sys_siglist[i]);
+ } else {
+ printf(" \"Signal %d\",\n", i);
+ }
+ }
+ printf("};\n");
+
+ exit(0);
+}
diff --git a/lib/util/mksiglist.h b/lib/util/mksiglist.h
new file mode 100644
index 0000000..c17cf88
--- /dev/null
+++ b/lib/util/mksiglist.h
@@ -0,0 +1,174 @@
+/* public domain */
+
+#ifdef SIGHUP
+ if (sudo_sys_siglist[SIGHUP] == NULL)
+ sudo_sys_siglist[SIGHUP] = "Hangup";
+#endif
+#ifdef SIGINT
+ if (sudo_sys_siglist[SIGINT] == NULL)
+ sudo_sys_siglist[SIGINT] = "Interrupt";
+#endif
+#ifdef SIGQUIT
+ if (sudo_sys_siglist[SIGQUIT] == NULL)
+ sudo_sys_siglist[SIGQUIT] = "Quit";
+#endif
+#ifdef SIGILL
+ if (sudo_sys_siglist[SIGILL] == NULL)
+ sudo_sys_siglist[SIGILL] = "Illegal instruction";
+#endif
+#ifdef SIGTRAP
+ if (sudo_sys_siglist[SIGTRAP] == NULL)
+ sudo_sys_siglist[SIGTRAP] = "Trace trap";
+#endif
+#ifdef SIGABRT
+ if (sudo_sys_siglist[SIGABRT] == NULL)
+ sudo_sys_siglist[SIGABRT] = "Abort";
+#endif
+#ifdef SIGIOT
+ if (sudo_sys_siglist[SIGIOT] == NULL)
+ sudo_sys_siglist[SIGIOT] = "IOT instruction";
+#endif
+#ifdef SIGEMT
+ if (sudo_sys_siglist[SIGEMT] == NULL)
+ sudo_sys_siglist[SIGEMT] = "EMT trap";
+#endif
+#ifdef SIGFPE
+ if (sudo_sys_siglist[SIGFPE] == NULL)
+ sudo_sys_siglist[SIGFPE] = "Floating point exception";
+#endif
+#ifdef SIGKILL
+ if (sudo_sys_siglist[SIGKILL] == NULL)
+ sudo_sys_siglist[SIGKILL] = "Killed";
+#endif
+#ifdef SIGUNUSED
+ if (sudo_sys_siglist[SIGUNUSED] == NULL)
+ sudo_sys_siglist[SIGUNUSED] = "Unused";
+#endif
+#ifdef SIGBUS
+ if (sudo_sys_siglist[SIGBUS] == NULL)
+ sudo_sys_siglist[SIGBUS] = "Bus error";
+#endif
+#ifdef SIGSEGV
+ if (sudo_sys_siglist[SIGSEGV] == NULL)
+ sudo_sys_siglist[SIGSEGV] = "Memory fault";
+#endif
+#ifdef SIGSYS
+ if (sudo_sys_siglist[SIGSYS] == NULL)
+ sudo_sys_siglist[SIGSYS] = "Bad system call";
+#endif
+#ifdef SIGPIPE
+ if (sudo_sys_siglist[SIGPIPE] == NULL)
+ sudo_sys_siglist[SIGPIPE] = "Broken pipe";
+#endif
+#ifdef SIGALRM
+ if (sudo_sys_siglist[SIGALRM] == NULL)
+ sudo_sys_siglist[SIGALRM] = "Alarm clock";
+#endif
+#ifdef SIGTERM
+ if (sudo_sys_siglist[SIGTERM] == NULL)
+ sudo_sys_siglist[SIGTERM] = "Terminated";
+#endif
+#ifdef SIGSTKFLT
+ if (sudo_sys_siglist[SIGSTKFLT] == NULL)
+ sudo_sys_siglist[SIGSTKFLT] = "Stack fault";
+#endif
+#ifdef SIGIO
+ if (sudo_sys_siglist[SIGIO] == NULL)
+ sudo_sys_siglist[SIGIO] = "I/O possible";
+#endif
+#ifdef SIGXCPU
+ if (sudo_sys_siglist[SIGXCPU] == NULL)
+ sudo_sys_siglist[SIGXCPU] = "CPU time limit exceeded";
+#endif
+#ifdef SIGXFSZ
+ if (sudo_sys_siglist[SIGXFSZ] == NULL)
+ sudo_sys_siglist[SIGXFSZ] = "File size limit exceeded";
+#endif
+#ifdef SIGVTALRM
+ if (sudo_sys_siglist[SIGVTALRM] == NULL)
+ sudo_sys_siglist[SIGVTALRM] = "Virtual timer expired";
+#endif
+#ifdef SIGPROF
+ if (sudo_sys_siglist[SIGPROF] == NULL)
+ sudo_sys_siglist[SIGPROF] = "Profiling timer expired";
+#endif
+#ifdef SIGWINCH
+ if (sudo_sys_siglist[SIGWINCH] == NULL)
+ sudo_sys_siglist[SIGWINCH] = "Window size change";
+#endif
+#ifdef SIGLOST
+ if (sudo_sys_siglist[SIGLOST] == NULL)
+ sudo_sys_siglist[SIGLOST] = "File lock lost";
+#endif
+#ifdef SIGUSR1
+ if (sudo_sys_siglist[SIGUSR1] == NULL)
+ sudo_sys_siglist[SIGUSR1] = "User defined signal 1";
+#endif
+#ifdef SIGUSR2
+ if (sudo_sys_siglist[SIGUSR2] == NULL)
+ sudo_sys_siglist[SIGUSR2] = "User defined signal 2";
+#endif
+#ifdef SIGPWR
+ if (sudo_sys_siglist[SIGPWR] == NULL)
+ sudo_sys_siglist[SIGPWR] = "Power-fail/Restart";
+#endif
+#ifdef SIGPOLL
+ if (sudo_sys_siglist[SIGPOLL] == NULL)
+ sudo_sys_siglist[SIGPOLL] = "Pollable event occurred";
+#endif
+#ifdef SIGSTOP
+ if (sudo_sys_siglist[SIGSTOP] == NULL)
+ sudo_sys_siglist[SIGSTOP] = "Stopped (signal)";
+#endif
+#ifdef SIGTSTP
+ if (sudo_sys_siglist[SIGTSTP] == NULL)
+ sudo_sys_siglist[SIGTSTP] = "Stopped";
+#endif
+#ifdef SIGCONT
+ if (sudo_sys_siglist[SIGCONT] == NULL)
+ sudo_sys_siglist[SIGCONT] = "Continued";
+#endif
+#ifdef SIGCHLD
+ if (sudo_sys_siglist[SIGCHLD] == NULL)
+ sudo_sys_siglist[SIGCHLD] = "Child exited";
+#endif
+#ifdef SIGCLD
+ if (sudo_sys_siglist[SIGCLD] == NULL)
+ sudo_sys_siglist[SIGCLD] = "Child exited";
+#endif
+#ifdef SIGTTIN
+ if (sudo_sys_siglist[SIGTTIN] == NULL)
+ sudo_sys_siglist[SIGTTIN] = "Stopped (tty input)";
+#endif
+#ifdef SIGTTOU
+ if (sudo_sys_siglist[SIGTTOU] == NULL)
+ sudo_sys_siglist[SIGTTOU] = "Stopped (tty output)";
+#endif
+#ifdef SIGINFO
+ if (sudo_sys_siglist[SIGINFO] == NULL)
+ sudo_sys_siglist[SIGINFO] = "Information request";
+#endif
+#ifdef SIGURG
+ if (sudo_sys_siglist[SIGURG] == NULL)
+ sudo_sys_siglist[SIGURG] = "Urgent I/O condition";
+#endif
+#ifdef SIGWAITING
+ if (sudo_sys_siglist[SIGWAITING] == NULL)
+ sudo_sys_siglist[SIGWAITING] = "No runnable LWPs";
+#endif
+#ifdef SIGLWP
+ if (sudo_sys_siglist[SIGLWP] == NULL)
+ sudo_sys_siglist[SIGLWP] = "Inter-LWP signal";
+#endif
+#ifdef SIGFREEZE
+ if (sudo_sys_siglist[SIGFREEZE] == NULL)
+ sudo_sys_siglist[SIGFREEZE] = "Checkpoint freeze";
+#endif
+#ifdef SIGTHAW
+ if (sudo_sys_siglist[SIGTHAW] == NULL)
+ sudo_sys_siglist[SIGTHAW] = "Checkpoint thaw";
+#endif
+#ifdef SIGCANCEL
+ if (sudo_sys_siglist[SIGCANCEL] == NULL)
+ sudo_sys_siglist[SIGCANCEL] = "Thread cancellation";
+#endif
diff --git a/lib/util/mksigname.c b/lib/util/mksigname.c
new file mode 100644
index 0000000..535ef46
--- /dev/null
+++ b/lib/util/mksigname.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2010-2012, 2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+
+#include "sudo_compat.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+int
+main(int argc, char *argv[])
+{
+ static char *sudo_sys_signame[NSIG];
+ int i;
+
+#include "mksigname.h"
+
+ printf("#include <config.h>\n");
+ printf("#include <sys/types.h>\n");
+ printf("#include <signal.h>\n");
+ printf("#include \"sudo_compat.h\"\n\n");
+ printf("const char *const sudo_sys_signame[NSIG] = {\n");
+ for (i = 0; i < NSIG; i++) {
+ if (sudo_sys_signame[i] != NULL) {
+ printf(" \"%s\",\n", sudo_sys_signame[i]);
+ } else {
+ printf(" \"Signal %d\",\n", i);
+ }
+ }
+ printf("};\n");
+
+ exit(0);
+}
diff --git a/lib/util/mksigname.h b/lib/util/mksigname.h
new file mode 100644
index 0000000..f3bc5d7
--- /dev/null
+++ b/lib/util/mksigname.h
@@ -0,0 +1,175 @@
+/* public domain */
+
+sudo_sys_signame[0] = "Signal 0";
+#ifdef SIGHUP
+ if (sudo_sys_signame[SIGHUP] == NULL)
+ sudo_sys_signame[SIGHUP] = "HUP";
+#endif
+#ifdef SIGINT
+ if (sudo_sys_signame[SIGINT] == NULL)
+ sudo_sys_signame[SIGINT] = "INT";
+#endif
+#ifdef SIGQUIT
+ if (sudo_sys_signame[SIGQUIT] == NULL)
+ sudo_sys_signame[SIGQUIT] = "QUIT";
+#endif
+#ifdef SIGILL
+ if (sudo_sys_signame[SIGILL] == NULL)
+ sudo_sys_signame[SIGILL] = "ILL";
+#endif
+#ifdef SIGTRAP
+ if (sudo_sys_signame[SIGTRAP] == NULL)
+ sudo_sys_signame[SIGTRAP] = "TRAP";
+#endif
+#ifdef SIGABRT
+ if (sudo_sys_signame[SIGABRT] == NULL)
+ sudo_sys_signame[SIGABRT] = "ABRT";
+#endif
+#ifdef SIGIOT
+ if (sudo_sys_signame[SIGIOT] == NULL)
+ sudo_sys_signame[SIGIOT] = "IOT";
+#endif
+#ifdef SIGEMT
+ if (sudo_sys_signame[SIGEMT] == NULL)
+ sudo_sys_signame[SIGEMT] = "EMT";
+#endif
+#ifdef SIGFPE
+ if (sudo_sys_signame[SIGFPE] == NULL)
+ sudo_sys_signame[SIGFPE] = "FPE";
+#endif
+#ifdef SIGKILL
+ if (sudo_sys_signame[SIGKILL] == NULL)
+ sudo_sys_signame[SIGKILL] = "KILL";
+#endif
+#ifdef SIGUNUSED
+ if (sudo_sys_signame[SIGUNUSED] == NULL)
+ sudo_sys_signame[SIGUNUSED] = "UNUSED";
+#endif
+#ifdef SIGBUS
+ if (sudo_sys_signame[SIGBUS] == NULL)
+ sudo_sys_signame[SIGBUS] = "BUS";
+#endif
+#ifdef SIGSEGV
+ if (sudo_sys_signame[SIGSEGV] == NULL)
+ sudo_sys_signame[SIGSEGV] = "SEGV";
+#endif
+#ifdef SIGSYS
+ if (sudo_sys_signame[SIGSYS] == NULL)
+ sudo_sys_signame[SIGSYS] = "SYS";
+#endif
+#ifdef SIGPIPE
+ if (sudo_sys_signame[SIGPIPE] == NULL)
+ sudo_sys_signame[SIGPIPE] = "PIPE";
+#endif
+#ifdef SIGALRM
+ if (sudo_sys_signame[SIGALRM] == NULL)
+ sudo_sys_signame[SIGALRM] = "ALRM";
+#endif
+#ifdef SIGTERM
+ if (sudo_sys_signame[SIGTERM] == NULL)
+ sudo_sys_signame[SIGTERM] = "TERM";
+#endif
+#ifdef SIGSTKFLT
+ if (sudo_sys_signame[SIGSTKFLT] == NULL)
+ sudo_sys_signame[SIGSTKFLT] = "STKFLT";
+#endif
+#ifdef SIGIO
+ if (sudo_sys_signame[SIGIO] == NULL)
+ sudo_sys_signame[SIGIO] = "IO";
+#endif
+#ifdef SIGXCPU
+ if (sudo_sys_signame[SIGXCPU] == NULL)
+ sudo_sys_signame[SIGXCPU] = "XCPU";
+#endif
+#ifdef SIGXFSZ
+ if (sudo_sys_signame[SIGXFSZ] == NULL)
+ sudo_sys_signame[SIGXFSZ] = "XFSZ";
+#endif
+#ifdef SIGVTALRM
+ if (sudo_sys_signame[SIGVTALRM] == NULL)
+ sudo_sys_signame[SIGVTALRM] = "VTALRM";
+#endif
+#ifdef SIGPROF
+ if (sudo_sys_signame[SIGPROF] == NULL)
+ sudo_sys_signame[SIGPROF] = "PROF";
+#endif
+#ifdef SIGWINCH
+ if (sudo_sys_signame[SIGWINCH] == NULL)
+ sudo_sys_signame[SIGWINCH] = "WINCH";
+#endif
+#ifdef SIGLOST
+ if (sudo_sys_signame[SIGLOST] == NULL)
+ sudo_sys_signame[SIGLOST] = "LOST";
+#endif
+#ifdef SIGUSR1
+ if (sudo_sys_signame[SIGUSR1] == NULL)
+ sudo_sys_signame[SIGUSR1] = "USR1";
+#endif
+#ifdef SIGUSR2
+ if (sudo_sys_signame[SIGUSR2] == NULL)
+ sudo_sys_signame[SIGUSR2] = "USR2";
+#endif
+#ifdef SIGPWR
+ if (sudo_sys_signame[SIGPWR] == NULL)
+ sudo_sys_signame[SIGPWR] = "PWR";
+#endif
+#ifdef SIGPOLL
+ if (sudo_sys_signame[SIGPOLL] == NULL)
+ sudo_sys_signame[SIGPOLL] = "POLL";
+#endif
+#ifdef SIGSTOP
+ if (sudo_sys_signame[SIGSTOP] == NULL)
+ sudo_sys_signame[SIGSTOP] = "STOP";
+#endif
+#ifdef SIGTSTP
+ if (sudo_sys_signame[SIGTSTP] == NULL)
+ sudo_sys_signame[SIGTSTP] = "TSTP";
+#endif
+#ifdef SIGCONT
+ if (sudo_sys_signame[SIGCONT] == NULL)
+ sudo_sys_signame[SIGCONT] = "CONT";
+#endif
+#ifdef SIGCHLD
+ if (sudo_sys_signame[SIGCHLD] == NULL)
+ sudo_sys_signame[SIGCHLD] = "CHLD";
+#endif
+#ifdef SIGCLD
+ if (sudo_sys_signame[SIGCLD] == NULL)
+ sudo_sys_signame[SIGCLD] = "CLD";
+#endif
+#ifdef SIGTTIN
+ if (sudo_sys_signame[SIGTTIN] == NULL)
+ sudo_sys_signame[SIGTTIN] = "TTIN";
+#endif
+#ifdef SIGTTOU
+ if (sudo_sys_signame[SIGTTOU] == NULL)
+ sudo_sys_signame[SIGTTOU] = "TTOU";
+#endif
+#ifdef SIGINFO
+ if (sudo_sys_signame[SIGINFO] == NULL)
+ sudo_sys_signame[SIGINFO] = "INFO";
+#endif
+#ifdef SIGURG
+ if (sudo_sys_signame[SIGURG] == NULL)
+ sudo_sys_signame[SIGURG] = "URG";
+#endif
+#ifdef SIGWAITING
+ if (sudo_sys_signame[SIGWAITING] == NULL)
+ sudo_sys_signame[SIGWAITING] = "WAITING";
+#endif
+#ifdef SIGLWP
+ if (sudo_sys_signame[SIGLWP] == NULL)
+ sudo_sys_signame[SIGLWP] = "LWP";
+#endif
+#ifdef SIGFREEZE
+ if (sudo_sys_signame[SIGFREEZE] == NULL)
+ sudo_sys_signame[SIGFREEZE] = "FREEZE";
+#endif
+#ifdef SIGTHAW
+ if (sudo_sys_signame[SIGTHAW] == NULL)
+ sudo_sys_signame[SIGTHAW] = "THAW";
+#endif
+#ifdef SIGCANCEL
+ if (sudo_sys_signame[SIGCANCEL] == NULL)
+ sudo_sys_signame[SIGCANCEL] = "CANCEL";
+#endif
diff --git a/lib/util/mktemp.c b/lib/util/mktemp.c
new file mode 100644
index 0000000..f153924
--- /dev/null
+++ b/lib/util/mktemp.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2001, 2003, 2004, 2008-2011, 2013, 2015, 2017, 2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#if !defined(HAVE_MKSTEMPS) || !defined(HAVE_MKDTEMP)
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif /* HAVE_STDLIB_H */
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <ctype.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "sudo_compat.h"
+#include "sudo_rand.h"
+#include "pathnames.h"
+
+#define MKTEMP_FILE 1
+#define MKTEMP_DIR 2
+
+#define TEMPCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+#define NUM_CHARS (sizeof(TEMPCHARS) - 1)
+#define MIN_X 6
+
+static int
+mktemp_internal(char *path, int slen, int mode)
+{
+ char *start, *cp, *ep;
+ const char tempchars[] = TEMPCHARS;
+ unsigned int r, tries;
+ size_t len;
+ int fd;
+
+ len = strlen(path);
+ if (len < MIN_X || slen < 0 || (size_t)slen > len - MIN_X) {
+ errno = EINVAL;
+ return -1;
+ }
+ ep = path + len - slen;
+
+ tries = 1;
+ for (start = ep; start > path && start[-1] == 'X'; start--) {
+ if (tries < INT_MAX / NUM_CHARS)
+ tries *= NUM_CHARS;
+ }
+ tries *= 2;
+ if (ep - start < MIN_X) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ do {
+ for (cp = start; cp != ep; cp++) {
+ r = arc4random_uniform(NUM_CHARS);
+ *cp = tempchars[r];
+ }
+
+ switch (mode) {
+ case MKTEMP_FILE:
+ fd = open(path, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
+ if (fd != -1 || errno != EEXIST)
+ return fd;
+ break;
+ case MKTEMP_DIR:
+ if (mkdir(path, S_IRWXU) == 0)
+ return 0;
+ if (errno != EEXIST)
+ return -1;
+ break;
+ }
+ } while (--tries);
+
+ errno = EEXIST;
+ return -1;
+}
+
+int
+sudo_mkstemps(char *path, int slen)
+{
+ return mktemp_internal(path, slen, MKTEMP_FILE);
+}
+
+char *
+sudo_mkdtemp(char *path)
+{
+ if (mktemp_internal(path, 0, MKTEMP_DIR) == -1)
+ return NULL;
+ return path;
+}
+#endif /* !HAVE_MKSTEMPS || !HAVE_MKDTEMP */
diff --git a/lib/util/nanosleep.c b/lib/util/nanosleep.c
new file mode 100644
index 0000000..7c09b5b
--- /dev/null
+++ b/lib/util/nanosleep.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009-2011, 2013, 2017-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_NANOSLEEP
+
+#include <sys/types.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H */
+#include <time.h>
+#include <errno.h>
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+
+int
+sudo_nanosleep(const struct timespec *ts, struct timespec *rts)
+{
+ struct timeval timeout, endtime, now;
+ int rval;
+
+ if (ts->tv_sec == 0 && ts->tv_nsec < 1000) {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 1;
+ } else {
+ TIMESPEC_TO_TIMEVAL(&timeout, ts);
+ }
+ if (rts != NULL) {
+ if (gettimeofday(&endtime, NULL) == -1)
+ return -1;
+ sudo_timevaladd(&endtime, &timeout, &endtime);
+ }
+ rval = select(0, NULL, NULL, NULL, &timeout);
+ if (rts != NULL && rval == -1 && errno == EINTR) {
+ if (gettimeofday(&now, NULL) == -1)
+ return -1;
+ sudo_timevalsub(&endtime, &now, &endtime);
+ TIMEVAL_TO_TIMESPEC(&endtime, rts);
+ }
+ return rval;
+}
+#endif /* HAVE_NANOSLEEP */
diff --git a/lib/util/parseln.c b/lib/util/parseln.c
new file mode 100644
index 0000000..ec345a3
--- /dev/null
+++ b/lib/util/parseln.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2007, 2013-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRING_H */
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+#include "sudo_debug.h"
+
+/*
+ * Read a line of input, honoring line continuation chars.
+ * Remove comments and strip off leading and trailing spaces.
+ * Returns the line length and updates the buf and bufsize pointers.
+ * XXX - just use a struct w/ state, including getline buffer?
+ * could also make comment char and line continuation configurable
+ */
+ssize_t
+sudo_parseln_v2(char **bufp, size_t *bufsizep, unsigned int *lineno, FILE *fp, int flags)
+{
+ size_t linesize = 0, total = 0;
+ ssize_t len;
+ char *cp, *line = NULL;
+ bool continued, comment;
+ debug_decl(sudo_parseln, SUDO_DEBUG_UTIL)
+
+ do {
+ comment = false;
+ continued = false;
+ len = getline(&line, &linesize, fp);
+ if (len == -1)
+ break;
+ if (lineno != NULL)
+ (*lineno)++;
+
+ /* Remove trailing newline(s) if present. */
+ while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
+ line[--len] = '\0';
+
+ /* Remove comments or check for line continuation (but not both) */
+ if ((cp = strchr(line, '#')) != NULL) {
+ if (cp == line || !ISSET(flags, PARSELN_COMM_BOL)) {
+ *cp = '\0';
+ len = (ssize_t)(cp - line);
+ comment = true;
+ }
+ }
+ if (!comment && !ISSET(flags, PARSELN_CONT_IGN)) {
+ if (len > 0 && line[len - 1] == '\\' && (len == 1 || line[len - 2] != '\\')) {
+ line[--len] = '\0';
+ continued = true;
+ }
+ }
+
+ /* Trim leading and trailing whitespace */
+ if (!continued) {
+ while (len > 0 && isblank((unsigned char)line[len - 1]))
+ line[--len] = '\0';
+ }
+ for (cp = line; isblank((unsigned char)*cp); cp++)
+ len--;
+
+ if (*bufp == NULL || total + len >= *bufsizep) {
+ void *tmp;
+ size_t size = total + len + 1;
+
+ if (size < 64) {
+ size = 64;
+ } else if (size <= 0x80000000) {
+ /* Round up to next highest power of two. */
+ size--;
+ size |= size >> 1;
+ size |= size >> 2;
+ size |= size >> 4;
+ size |= size >> 8;
+ size |= size >> 16;
+ size++;
+ }
+ if ((tmp = realloc(*bufp, size)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ len = -1;
+ total = 0;
+ break;
+ }
+ *bufp = tmp;
+ *bufsizep = size;
+ }
+ memcpy(*bufp + total, cp, len + 1);
+ total += len;
+ } while (continued);
+ free(line);
+ if (len == -1 && total == 0)
+ debug_return_ssize_t(-1);
+ debug_return_ssize_t(total);
+}
+
+ssize_t
+sudo_parseln_v1(char **bufp, size_t *bufsizep, unsigned int *lineno, FILE *fp)
+{
+ return sudo_parseln_v2(bufp, bufsizep, lineno, fp, 0);
+}
diff --git a/lib/util/pipe2.c b/lib/util/pipe2.c
new file mode 100644
index 0000000..89a904c
--- /dev/null
+++ b/lib/util/pipe2.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_PIPE2
+
+#include <sys/types.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "sudo_compat.h"
+
+int
+sudo_pipe2(int fildes[2], int flags)
+{
+ if (pipe(fildes) != 0)
+ return -1;
+
+ if (ISSET(flags, O_NONBLOCK)) {
+ int flags = fcntl(fildes[0], F_GETFL, 0);
+ if (flags == -1)
+ goto bad;
+ if (fcntl(fildes[0], F_SETFL, flags | O_NONBLOCK) == -1)
+ goto bad;
+ flags = fcntl(fildes[1], F_GETFL, 0);
+ if (flags == -1)
+ goto bad;
+ if (fcntl(fildes[1], F_SETFL, flags | O_NONBLOCK) == -1)
+ goto bad;
+ }
+ if (ISSET(flags, O_CLOEXEC)) {
+ if (fcntl(fildes[0], F_SETFD, FD_CLOEXEC) == -1)
+ goto bad;
+ if (fcntl(fildes[1], F_SETFD, FD_CLOEXEC) == -1)
+ goto bad;
+ }
+ return 0;
+bad:
+ close(fildes[0]);
+ close(fildes[1]);
+ return -1;
+}
+
+#endif /* HAVE_PIPE2 */
diff --git a/lib/util/progname.c b/lib/util/progname.c
new file mode 100644
index 0000000..ffe946c
--- /dev/null
+++ b/lib/util/progname.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+
+#ifdef HAVE_GETPROGNAME
+
+void
+initprogname(const char *name)
+{
+# ifdef HAVE_SETPROGNAME
+ const char *progname;
+
+ /* Fall back on "name" if getprogname() returns an empty string. */
+ if ((progname = getprogname()) != NULL && *progname != '\0')
+ name = progname;
+
+ /* Check for libtool prefix and strip it if present. */
+ if (name[0] == 'l' && name[1] == 't' && name[2] == '-' && name[3] != '\0')
+ name += 3;
+
+ /* Update internal progname if needed. */
+ if (name != progname)
+ setprogname(name);
+# endif
+ return;
+}
+
+#else /* !HAVE_GETPROGNAME */
+
+static const char *progname = "";
+
+void
+initprogname(const char *name)
+{
+# ifdef HAVE___PROGNAME
+ extern const char *__progname;
+
+ if (__progname != NULL && *__progname != '\0')
+ progname = __progname;
+ else
+# endif
+ if ((progname = strrchr(name, '/')) != NULL) {
+ progname++;
+ } else {
+ progname = name;
+ }
+
+ /* Check for libtool prefix and strip it if present. */
+ if (progname[0] == 'l' && progname[1] == 't' && progname[2] == '-' &&
+ progname[3] != '\0')
+ progname += 3;
+}
+
+const char *
+sudo_getprogname(void)
+{
+ return progname;
+}
+#endif /* !HAVE_GETPROGNAME */
diff --git a/lib/util/pw_dup.c b/lib/util/pw_dup.c
new file mode 100644
index 0000000..4257adf
--- /dev/null
+++ b/lib/util/pw_dup.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2000, 2002, 2012-2014
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_PW_DUP
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <pwd.h>
+
+#include "sudo_compat.h"
+
+#define PW_SIZE(name, size) \
+do { \
+ if (pw->name) { \
+ size = strlen(pw->name) + 1; \
+ total += size; \
+ } \
+} while (0)
+
+#define PW_COPY(name, size) \
+do { \
+ if (pw->name) { \
+ (void)memcpy(cp, pw->name, size); \
+ newpw->name = cp; \
+ cp += size; \
+ } \
+} while (0)
+
+struct passwd *
+sudo_pw_dup(const struct passwd *pw)
+{
+ size_t nsize = 0, psize = 0, gsize = 0, dsize = 0, ssize = 0, total;
+#ifdef HAVE_LOGIN_CAP_H
+ size_t csize = 0;
+#endif
+ struct passwd *newpw;
+ char *cp;
+
+ /* Allocate in one big chunk for easy freeing */
+ total = sizeof(struct passwd);
+ PW_SIZE(pw_name, nsize);
+ PW_SIZE(pw_passwd, psize);
+#ifdef HAVE_LOGIN_CAP_H
+ PW_SIZE(pw_class, csize);
+#endif
+ PW_SIZE(pw_gecos, gsize);
+ PW_SIZE(pw_dir, dsize);
+ PW_SIZE(pw_shell, ssize);
+
+ if ((cp = malloc(total)) == NULL)
+ return NULL;
+ newpw = (struct passwd *)cp;
+
+ /*
+ * Copy in passwd contents and make strings relative to space
+ * at the end of the buffer.
+ */
+ (void)memcpy(newpw, pw, sizeof(struct passwd));
+ cp += sizeof(struct passwd);
+
+ PW_COPY(pw_name, nsize);
+ PW_COPY(pw_passwd, psize);
+#ifdef HAVE_LOGIN_CAP_H
+ PW_COPY(pw_class, csize);
+#endif
+ PW_COPY(pw_gecos, gsize);
+ PW_COPY(pw_dir, dsize);
+ PW_COPY(pw_shell, ssize);
+
+ return newpw;
+}
+#endif /* HAVE_PW_DUP */
diff --git a/lib/util/reallocarray.c b/lib/util/reallocarray.c
new file mode 100644
index 0000000..ee2ef4a
--- /dev/null
+++ b/lib/util/reallocarray.c
@@ -0,0 +1,56 @@
+/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */
+/*
+ * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_REALLOCARRAY
+
+#include <sys/types.h>
+#include <stdlib.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#include <errno.h>
+#include <limits.h>
+
+#include "sudo_compat.h"
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
+
+void *
+sudo_reallocarray(void *optr, size_t nmemb, size_t size)
+{
+ if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+ nmemb > 0 && SIZE_MAX / nmemb < size) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ return realloc(optr, size * nmemb);
+}
+
+#endif /* HAVE_REALLOCARRAY */
diff --git a/lib/util/regress/atofoo/atofoo_test.c b/lib/util/regress/atofoo/atofoo_test.c
new file mode 100644
index 0000000..1ad78eb
--- /dev/null
+++ b/lib/util/regress/atofoo/atofoo_test.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+#include "sudo_fatal.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+/* sudo_strtobool() tests */
+static struct strtobool_data {
+ const char *bool_str;
+ int value;
+} strtobool_data[] = {
+ { "true", true },
+ { "false", false },
+ { "TrUe", true },
+ { "fAlSe", false },
+ { "1", true },
+ { "0", false },
+ { "on", true },
+ { "off", false },
+ { "yes", true },
+ { "no", false },
+ { "nope", -1 },
+ { "10", -1 },
+ { "one", -1 },
+ { "zero", -1 },
+ { NULL, 0 }
+};
+
+static int
+test_strtobool(int *ntests)
+{
+ struct strtobool_data *d;
+ int errors = 0;
+ int value;
+
+ for (d = strtobool_data; d->bool_str != NULL; d++) {
+ (*ntests)++;
+ value = sudo_strtobool(d->bool_str);
+ if (value != d->value) {
+ sudo_warnx_nodebug("FAIL: %s != %d", d->bool_str, d->value);
+ errors++;
+ }
+ }
+
+ return errors;
+}
+
+/* sudo_strtoid() tests */
+static struct strtoid_data {
+ const char *idstr;
+ id_t id;
+ const char *sep;
+ const char *ep;
+} strtoid_data[] = {
+ { "0,1", 0, ",", "," },
+ { "10", 10, NULL, NULL },
+ { "-2", -2, NULL, NULL },
+#if SIZEOF_ID_T != SIZEOF_LONG_LONG
+ { "-2", (id_t)4294967294U, NULL, NULL },
+#endif
+ { "4294967294", (id_t)4294967294U, NULL, NULL },
+ { NULL, 0, NULL, NULL }
+};
+
+static int
+test_strtoid(int *ntests)
+{
+ struct strtoid_data *d;
+ const char *errstr;
+ char *ep;
+ int errors = 0;
+ id_t value;
+
+ for (d = strtoid_data; d->idstr != NULL; d++) {
+ (*ntests)++;
+ errstr = "some error";
+ value = sudo_strtoid(d->idstr, d->sep, &ep, &errstr);
+ if (errstr != NULL) {
+ if (d->id != (id_t)-1) {
+ sudo_warnx_nodebug("FAIL: %s: %s", d->idstr, errstr);
+ errors++;
+ }
+ } else if (value != d->id) {
+ sudo_warnx_nodebug("FAIL: %s != %u", d->idstr, (unsigned int)d->id);
+ errors++;
+ } else if (d->ep != NULL && ep[0] != d->ep[0]) {
+ sudo_warnx_nodebug("FAIL: ep[0] %d != %d", (int)(unsigned char)ep[0],
+ (int)(unsigned char)d->ep[0]);
+ errors++;
+ }
+ }
+
+ return errors;
+}
+
+/* sudo_strtomode() tests */
+static struct strtomode_data {
+ const char *mode_str;
+ mode_t mode;
+} strtomode_data[] = {
+ { "755", 0755 },
+ { "007", 007 },
+ { "7", 7 },
+ { "8", (mode_t)-1 },
+ { NULL, 0 }
+};
+
+static int
+test_strtomode(int *ntests)
+{
+ struct strtomode_data *d;
+ const char *errstr;
+ int errors = 0;
+ mode_t mode;
+
+ for (d = strtomode_data; d->mode_str != NULL; d++) {
+ (*ntests)++;
+ errstr = "some error";
+ mode = sudo_strtomode(d->mode_str, &errstr);
+ if (errstr != NULL) {
+ if (d->mode != (mode_t)-1) {
+ sudo_warnx_nodebug("FAIL: %s: %s", d->mode_str, errstr);
+ errors++;
+ }
+ } else if (mode != d->mode) {
+ sudo_warnx_nodebug("FAIL: %s != 0%o", d->mode_str,
+ (unsigned int) d->mode);
+ errors++;
+ }
+ }
+
+ return errors;
+}
+
+/*
+ * Simple tests for sudo_strtobool(), sudo_strtoid(), sudo_strtomode().
+ */
+int
+main(int argc, char *argv[])
+{
+ int errors = 0;
+ int ntests = 0;
+
+ initprogname(argc > 0 ? argv[0] : "atofoo");
+
+ errors += test_strtobool(&ntests);
+ errors += test_strtoid(&ntests);
+ errors += test_strtomode(&ntests);
+
+ if (ntests != 0) {
+ printf("%s: %d tests run, %d errors, %d%% success rate\n",
+ getprogname(), ntests, errors, (ntests - errors) * 100 / ntests);
+ }
+
+ exit(errors);
+}
diff --git a/lib/util/regress/fnmatch/fnm_test.c b/lib/util/regress/fnmatch/fnm_test.c
new file mode 100644
index 0000000..a70a847
--- /dev/null
+++ b/lib/util/regress/fnmatch/fnm_test.c
@@ -0,0 +1,85 @@
+/* $OpenBSD: fnm_test.c,v 1.1 2008/10/01 23:04:58 millert Exp $ */
+
+/*
+ * Public domain, 2008, Todd C. Miller <Todd.Miller@sudo.ws>
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+
+#ifdef HAVE_FNMATCH
+# include <fnmatch.h>
+#else
+# include "compat/fnmatch.h"
+#endif
+
+__dso_public int main(int argc, char *argv[]);
+
+int
+main(int argc, char *argv[])
+{
+ FILE *fp = stdin;
+ char pattern[1024], string[1024], flagstr[1024];
+ int errors = 0, tests = 0, flags, got, want;
+
+ initprogname(argc > 0 ? argv[0] : "fnm_test");
+
+ if (argc > 1) {
+ if ((fp = fopen(argv[1], "r")) == NULL) {
+ perror(argv[1]);
+ exit(1);
+ }
+ }
+
+ /*
+ * Read in test file, which is formatted thusly:
+ *
+ * pattern string flags expected_result
+ *
+ */
+ for (;;) {
+ got = fscanf(fp, "%s %s %s %d\n", pattern, string, flagstr,
+ &want);
+ if (got == EOF)
+ break;
+ if (got == 4) {
+ flags = 0;
+ if (strcmp(flagstr, "FNM_NOESCAPE") == 0)
+ flags |= FNM_NOESCAPE;
+ else if (strcmp(flagstr, "FNM_PATHNAME") == 0)
+ flags |= FNM_PATHNAME;
+ else if (strcmp(flagstr, "FNM_PERIOD") == 0)
+ flags |= FNM_PERIOD;
+ else if (strcmp(flagstr, "FNM_LEADING_DIR") == 0)
+ flags |= FNM_LEADING_DIR;
+ else if (strcmp(flagstr, "FNM_CASEFOLD") == 0)
+ flags |= FNM_CASEFOLD;
+ got = fnmatch(pattern, string, flags);
+ if (got != want) {
+ fprintf(stderr,
+ "fnmatch: %s %s %d: want %d, got %d\n",
+ pattern, string, flags, want, got);
+ errors++;
+ }
+ tests++;
+ }
+ }
+ if (tests != 0) {
+ printf("fnmatch: %d test%s run, %d errors, %d%% success rate\n",
+ tests, tests == 1 ? "" : "s", errors,
+ (tests - errors) * 100 / tests);
+ }
+ exit(errors);
+}
diff --git a/lib/util/regress/fnmatch/fnm_test.in b/lib/util/regress/fnmatch/fnm_test.in
new file mode 100644
index 0000000..3f53f93
--- /dev/null
+++ b/lib/util/regress/fnmatch/fnm_test.in
@@ -0,0 +1,6 @@
+/bin/[[:alpha:][:alnum:]]* /bin/ls FNM_PATHNAME 0
+/bin/[[:alpha:][:alnum:]]* /bin/LS FNM_CASEFOLD 0
+/bin/[[:opper:][:alnum:]]* /bin/ls NONE 1
+[[:alpha:][:alnum:]]*.c foo1.c FNM_PERIOD 0
+[[:upper:]]* FOO NONE 0
+[![:space:]]* bar NONE 0
diff --git a/lib/util/regress/getgrouplist/getgrouplist_test.c b/lib/util/regress/getgrouplist/getgrouplist_test.c
new file mode 100644
index 0000000..4d44cf2
--- /dev/null
+++ b/lib/util/regress/getgrouplist/getgrouplist_test.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+#include <pwd.h>
+#include <grp.h>
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_util.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+/*
+ * Test that sudo_getgrouplist2() works as expected.
+ */
+
+int
+main(int argc, char *argv[])
+{
+ int errors = 0;
+#ifndef HAVE_GETGROUPLIST_2
+ GETGROUPS_T *groups = NULL;
+ struct passwd *pw;
+ struct group *grp;
+ char *username;
+ int i, j, ntests = 0;
+ int ngroups;
+ gid_t basegid;
+ initprogname(argc > 0 ? argv[0] : "getgrouplist_test");
+
+ if ((pw = getpwuid(0)) == NULL)
+ sudo_fatal_nodebug("getpwuid(0)");
+ basegid = pw->pw_gid;
+ if ((username = strdup(pw->pw_name)) == NULL)
+ sudo_fatal_nodebug(NULL);
+
+ if (sudo_getgrouplist2(username, basegid, &groups, &ngroups) == -1)
+ sudo_fatal_nodebug("sudo_getgroulist2");
+
+ for (i = 0; i < ngroups; i++) {
+ ntests++;
+
+ /* Verify group ID exists. */
+ if ((grp = getgrgid(groups[i])) == NULL) {
+ sudo_warnx_nodebug("unable to look up group ID %u",
+ (unsigned int)groups[i]);
+ errors++;
+ continue;
+ }
+
+ /* Check user's primary gid from the passwd file. */
+ if (grp->gr_gid == basegid)
+ continue;
+
+ /* Verify group membership. */
+ for (j = 0; grp->gr_mem[j] != NULL; j++) {
+ if (strcmp(username, grp->gr_mem[j]) == 0) {
+ /* match */
+ break;
+ }
+ }
+ if (grp->gr_mem[j] == NULL) {
+ sudo_warnx_nodebug("unable to find %s in group %s",
+ username, grp->gr_name);
+ errors++;
+ continue;
+ }
+ }
+ if (errors != 0) {
+ printf("%s: %d tests run, %d errors, %d%% success rate\n",
+ getprogname(), ntests, errors, (ntests - errors) * 100 / ntests);
+ }
+#endif /* HAVE_GETGROUPLIST_2 */
+ exit(errors);
+}
diff --git a/lib/util/regress/glob/files b/lib/util/regress/glob/files
new file mode 100644
index 0000000..c5e92aa
--- /dev/null
+++ b/lib/util/regress/glob/files
@@ -0,0 +1,47 @@
+fake/bin/[
+fake/bin/cat
+fake/bin/chgrp
+fake/bin/chio
+fake/bin/chmod
+fake/bin/cksum
+fake/bin/cp
+fake/bin/cpio
+fake/bin/csh
+fake/bin/date
+fake/bin/dd
+fake/bin/df
+fake/bin/domainname
+fake/bin/echo
+fake/bin/ed
+fake/bin/eject
+fake/bin/expr
+fake/bin/hostname
+fake/bin/kill
+fake/bin/ksh
+fake/bin/ln
+fake/bin/ls
+fake/bin/md5
+fake/bin/mkdir
+fake/bin/mt
+fake/bin/mv
+fake/bin/pax
+fake/bin/ps
+fake/bin/pwd
+fake/bin/rcp
+fake/bin/rksh
+fake/bin/rm
+fake/bin/rmail
+fake/bin/rmd160
+fake/bin/rmdir
+fake/bin/sh
+fake/bin/sha1
+fake/bin/sha256
+fake/bin/sha384
+fake/bin/sha512
+fake/bin/sleep
+fake/bin/stty
+fake/bin/sum
+fake/bin/sync
+fake/bin/systrace
+fake/bin/tar
+fake/bin/test
diff --git a/lib/util/regress/glob/globtest.c b/lib/util/regress/glob/globtest.c
new file mode 100644
index 0000000..99859f0
--- /dev/null
+++ b/lib/util/regress/glob/globtest.c
@@ -0,0 +1,216 @@
+/* $OpenBSD: globtest.c,v 1.1 2008/10/01 23:04:36 millert Exp $ */
+
+/*
+ * Public domain, 2008, Todd C. Miller <Todd.Miller@sudo.ws>
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_GLOB
+# include <glob.h>
+#else
+# include "compat/glob.h"
+#endif
+#include <errno.h>
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+
+#define MAX_RESULTS 256
+
+struct gl_entry {
+ int flags;
+ int nresults;
+ char pattern[1024];
+ char *results[MAX_RESULTS];
+};
+
+int test_glob(struct gl_entry *);
+__dso_public int main(int argc, char *argv[]);
+
+int
+main(int argc, char **argv)
+{
+ FILE *fp = stdin;
+ char buf[2048], *cp, *ep;
+ int errors = 0, tests = 0, lineno;
+ struct gl_entry entry;
+ size_t len;
+
+ initprogname(argc > 0 ? argv[0] : "globtest");
+
+ if (argc > 1) {
+ if ((fp = fopen(argv[1], "r")) == NULL) {
+ perror(argv[1]);
+ exit(1);
+ }
+ }
+
+ /*
+ * Read in test file, which is formatted thusly:
+ *
+ * [pattern] <flags>
+ * result1
+ * result2
+ * result3
+ * ...
+ *
+ */
+ lineno = 0;
+ memset(&entry, 0, sizeof(entry));
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ lineno++;
+ len = strlen(buf);
+ if (len > 0) {
+ if (buf[len - 1] != '\n') {
+ fprintf(stderr,
+ "globtest: missing newline at EOF\n");
+ exit(1);
+ }
+ buf[--len] = '\0';
+ }
+ if (len == 0)
+ continue; /* blank line */
+
+ if (buf[0] == '[') {
+ /* check previous pattern */
+ if (entry.pattern[0]) {
+ errors += test_glob(&entry);
+ tests++;
+ }
+
+ /* start new entry */
+ if ((cp = strrchr(buf + 1, ']')) == NULL) {
+ fprintf(stderr,
+ "globtest: invalid entry on line %d\n",
+ lineno);
+ exit(1);
+ }
+ len = cp - buf - 1;
+ if (len >= sizeof(entry.pattern)) {
+ fprintf(stderr,
+ "globtest: pattern too big on line %d\n",
+ lineno);
+ exit(1);
+ }
+ memcpy(entry.pattern, buf + 1, len);
+ entry.pattern[len] = '\0';
+
+ cp += 2;
+ if (*cp++ != '<') {
+ fprintf(stderr,
+ "globtest: invalid entry on line %d\n",
+ lineno);
+ exit(1);
+ }
+ ep = strchr(cp, '>');
+ if (ep == NULL) {
+ fprintf(stderr,
+ "globtest: invalid entry on line %d\n",
+ lineno);
+ exit(1);
+ }
+ *ep = '\0';
+ entry.flags = 0;
+ for ((cp = strtok_r(cp, "|", &ep)); cp != NULL; (cp = strtok_r(NULL, "|", &ep))) {
+ if (strcmp(cp, "GLOB_APPEND") == 0)
+ entry.flags |= GLOB_APPEND;
+ else if (strcmp(cp, "GLOB_DOOFFS") == 0)
+ entry.flags |= GLOB_DOOFFS;
+ else if (strcmp(cp, "GLOB_ERR") == 0)
+ entry.flags |= GLOB_ERR;
+ else if (strcmp(cp, "GLOB_MARK") == 0)
+ entry.flags |= GLOB_MARK;
+ else if (strcmp(cp, "GLOB_NOCHECK") == 0)
+ entry.flags |= GLOB_NOCHECK;
+ else if (strcmp(cp, "GLOB_NOSORT") == 0)
+ entry.flags |= GLOB_NOSORT;
+ else if (strcmp(cp, "GLOB_NOESCAPE") == 0)
+ entry.flags |= GLOB_NOESCAPE;
+ else if (strcmp(cp, "GLOB_BRACE") == 0)
+ entry.flags |= GLOB_BRACE;
+ else if (strcmp(cp, "GLOB_TILDE") == 0)
+ entry.flags |= GLOB_TILDE;
+ else if (strcmp(cp, "NONE") != 0) {
+ fprintf(stderr,
+ "globtest: invalid flags on line %d\n",
+ lineno);
+ exit(1);
+ }
+ }
+ entry.nresults = 0;
+ continue;
+ }
+ if (!entry.pattern[0]) {
+ fprintf(stderr, "globtest: missing entry on line %d\n",
+ lineno);
+ exit(1);
+ }
+
+ if (entry.nresults + 1 > MAX_RESULTS) {
+ fprintf(stderr,
+ "globtest: too many results for %s, max %d\n",
+ entry.pattern, MAX_RESULTS);
+ exit(1);
+ }
+ entry.results[entry.nresults++] = strdup(buf);
+ }
+ if (entry.pattern[0]) {
+ errors += test_glob(&entry); /* test last pattern */
+ tests++;
+ }
+ if (tests != 0) {
+ printf("glob: %d test%s run, %d errors, %d%% success rate\n",
+ tests, tests == 1 ? "" : "s", errors,
+ (tests - errors) * 100 / tests);
+ }
+ exit(errors);
+}
+
+int test_glob(struct gl_entry *entry)
+{
+ glob_t gl;
+ char **ap;
+ int nmatches = 0, i = 0;
+
+ if (glob(entry->pattern, entry->flags, NULL, &gl) != 0) {
+ fprintf(stderr, "glob failed: %s: %s\n", entry->pattern,
+ strerror(errno));
+ exit(1);
+ }
+
+ for (ap = gl.gl_pathv; *ap != NULL; ap++)
+ nmatches++;
+
+ if (nmatches != entry->nresults)
+ goto mismatch;
+
+ for (i = 0; i < entry->nresults; i++) {
+ if (strcmp(gl.gl_pathv[i], entry->results[i]) != 0)
+ goto mismatch;
+ free(entry->results[i]);
+ }
+ return 0;
+ mismatch:
+ if (nmatches != entry->nresults) {
+ fprintf(stderr,
+ "globtest: mismatch in number of results (found %d, expected %d) for pattern %s\n",
+ nmatches, entry->nresults, entry->pattern);
+ } else {
+ fprintf(stderr, "globtest: mismatch for pattern %s, flags 0x%x "
+ "(found \"%s\", expected \"%s\")\n", entry->pattern, entry->flags,
+ gl.gl_pathv[i], entry->results[i]);
+ while (i < entry->nresults)
+ free(entry->results[i++]);
+ }
+ return 1;
+}
diff --git a/lib/util/regress/glob/globtest.in b/lib/util/regress/glob/globtest.in
new file mode 100644
index 0000000..20a86c1
--- /dev/null
+++ b/lib/util/regress/glob/globtest.in
@@ -0,0 +1,64 @@
+[fake/bin/[[:alpha:]]*] <NONE>
+fake/bin/cat
+fake/bin/chgrp
+fake/bin/chio
+fake/bin/chmod
+fake/bin/cksum
+fake/bin/cp
+fake/bin/cpio
+fake/bin/csh
+fake/bin/date
+fake/bin/dd
+fake/bin/df
+fake/bin/domainname
+fake/bin/echo
+fake/bin/ed
+fake/bin/eject
+fake/bin/expr
+fake/bin/hostname
+fake/bin/kill
+fake/bin/ksh
+fake/bin/ln
+fake/bin/ls
+fake/bin/md5
+fake/bin/mkdir
+fake/bin/mt
+fake/bin/mv
+fake/bin/pax
+fake/bin/ps
+fake/bin/pwd
+fake/bin/rcp
+fake/bin/rksh
+fake/bin/rm
+fake/bin/rmail
+fake/bin/rmd160
+fake/bin/rmdir
+fake/bin/sh
+fake/bin/sha1
+fake/bin/sha256
+fake/bin/sha384
+fake/bin/sha512
+fake/bin/sleep
+fake/bin/stty
+fake/bin/sum
+fake/bin/sync
+fake/bin/systrace
+fake/bin/tar
+fake/bin/test
+
+[fake/bin/rm{,dir,ail}] <GLOB_BRACE>
+fake/bin/rm
+fake/bin/rmdir
+fake/bin/rmail
+
+[fake/bin/sha[[:digit:]]] <NONE>
+fake/bin/sha1
+
+[fake/bin/sha[[:digit:]]*] <NONE>
+fake/bin/sha1
+fake/bin/sha256
+fake/bin/sha384
+fake/bin/sha512
+
+[fake/bin/ca[a-z]] <NONE>
+fake/bin/cat
diff --git a/lib/util/regress/mktemp/mktemp_test.c b/lib/util/regress/mktemp/mktemp_test.c
new file mode 100644
index 0000000..c8b9ceb
--- /dev/null
+++ b/lib/util/regress/mktemp/mktemp_test.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2010 Philip Guenther <guenther@openbsd.org>
+ *
+ * Public domain.
+ *
+ * Verify that mkdtemp() and mkstemps() doesn't overrun or underrun
+ * the template buffer and that it can generate names that don't
+ * contain any X's
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <fcntl.h>
+#include <unistd.h>
+
+#define SUDO_ERROR_WRAP 0
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+#include "sudo_fatal.h"
+
+#ifndef MAP_ANON
+# if defined(MAP_ANONYMOUS)
+# define MAP_ANON MAP_ANONYMOUS
+# endif
+#endif
+
+#define MAX_TEMPLATE_LEN 10
+#define MAX_TRIES 100
+#define MIN_Xs 6
+
+#define SUFFIX ".suff"
+#define SLEN (sizeof SUFFIX - 1)
+
+__dso_public int main(int argc, char *argv[]);
+
+/*
+ * verify that a path generated by mkdtemp() or mkstemp() looks like a
+ * reasonable expansion of the template and matches the fd. Returns true
+ * if all the X's were replaced with non-X's
+ */
+int
+check(int fd, char const *kind, char const *path, char const *prefix,
+ size_t plen, char const *suffix, size_t slen, int tlen)
+{
+ struct stat sb, fsb;
+ char const *p;
+
+ if (tlen < MIN_Xs) {
+ if (fd != -1)
+ sudo_fatalx("%s(%s) succeed with too few Xs", kind, path);
+ if (errno != EINVAL)
+ sudo_fatal("%s(%s) failed with wrong errno: %d", kind, path, errno);
+ return 1;
+ }
+ if (fd == -1)
+ sudo_fatal("%s(%s)", kind, path);
+ if (stat(path, &sb))
+ sudo_fatal("%s: stat(%s)", kind, path);
+ if (fd >= 0) {
+ if (fstat(fd, &fsb))
+ sudo_fatal("%s: fstat(%d==%s)", kind, fd, path);
+ if (sb.st_dev != fsb.st_dev || sb.st_ino != fsb.st_ino)
+ sudo_fatalx("%s: stat mismatch", kind);
+ }
+ if (memcmp(path, prefix, plen) != 0)
+ sudo_fatalx("%s: prefix changed! %s vs %s", kind, prefix, path);
+ if (memcmp(path + plen + tlen, suffix, slen + 1) != 0)
+ sudo_fatalx("%s: suffix changed! %s vs %s", kind, suffix, path);
+ for (p = path + plen; p < path + plen + tlen; p++)
+ if (*p == '\0')
+ sudo_fatalx("%s: unexpected truncation", kind);
+ else if (*p == 'X')
+ return 0;
+ return 1;
+}
+
+void
+try_mkdtemp(char *p, char const *prefix, int len)
+{
+ size_t plen = strlen(prefix);
+ int fd, tries, ok;
+
+ for (tries = 0; tries < MAX_TRIES; tries++) {
+ memcpy(p, prefix, plen);
+ memset(p + plen, 'X', len);
+ p[plen + len] = '\0';
+ fd = mkdtemp(p) ? -2 : -1;
+ ok = check(fd, "mkdtemp", p, prefix, plen, "", 0, len);
+ rmdir(p);
+ if (ok)
+ return;
+ }
+ sudo_fatalx("mkdtemp: exceeded MAX_TRIES");
+}
+
+void
+try_mkstemps(char *p, char const *prefix, int len, char const *suffix)
+{
+ size_t plen = strlen(prefix);
+ size_t slen = strlen(suffix);
+ int tries, fd, ok;
+
+ for (tries = 0; tries < MAX_TRIES; tries++) {
+ memcpy(p, prefix, plen);
+ memset(p + plen, 'X', len);
+ memcpy(p + plen + len, suffix, slen + 1);
+ fd = mkstemps(p, slen);
+ ok = check(fd, "mkstemp", p, prefix, plen, suffix, slen, len);
+ close(fd);
+ unlink(p);
+ if (ok)
+ return;
+ }
+ sudo_fatalx("mkstemps: exceeded MAX_TRIES");
+}
+
+int
+main(int argc, char *argv[])
+{
+ char cwd[PATH_MAX + 1];
+ char *p;
+ size_t clen;
+ long pg;
+ int i;
+
+ initprogname(argc > 0 ? argv[0] : "mktemp_test");
+
+ pg = sysconf(_SC_PAGESIZE);
+ if (getcwd(cwd, sizeof cwd - 1) == NULL)
+ sudo_fatal("getcwd");
+ clen = strlen(cwd);
+ cwd[clen++] = '/';
+ cwd[clen] = '\0';
+#ifdef MAP_ANON
+ p = mmap(NULL, pg * 3, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
+#else
+ i = open("/dev/zero", O_RDWR);
+ if (i == -1)
+ sudo_fatal("/dev/zero");
+ p = mmap(NULL, pg * 3, PROT_READ | PROT_WRITE, MAP_PRIVATE, i, 0);
+#endif
+ if (p == MAP_FAILED)
+ sudo_fatal("mmap");
+ if (mprotect(p, pg, PROT_NONE) || mprotect(p + pg * 2, pg, PROT_NONE))
+ sudo_fatal("mprotect");
+ p += pg;
+
+ i = MAX_TEMPLATE_LEN + 1;
+ while (i-- > 0) {
+ /* try first at the start of a page, no prefix */
+ try_mkdtemp(p, "", i);
+ /* now at the end of the page, no prefix */
+ try_mkdtemp(p + pg - i - 1, "", i);
+ /* start of the page, prefixed with the cwd */
+ try_mkdtemp(p, cwd, i);
+ /* how about at the end of the page, prefixed with cwd? */
+ try_mkdtemp(p + pg - clen - i - 1, cwd, i);
+
+ /* again, with mkstemps() and an empty suffix */
+ /* try first at the start of a page, no prefix */
+ try_mkstemps(p, "", i, "");
+ /* now at the end of the page, no prefix */
+ try_mkstemps(p + pg - i - 1, "", i, "");
+ /* start of the page, prefixed with the cwd */
+ try_mkstemps(p, cwd, i, "");
+ /* how about at the end of the page, prefixed with cwd? */
+ try_mkstemps(p + pg - clen - i - 1, cwd, i, "");
+
+ /* mkstemps() and a non-empty suffix */
+ /* try first at the start of a page, no prefix */
+ try_mkstemps(p, "", i, SUFFIX);
+ /* now at the end of the page, no prefix */
+ try_mkstemps(p + pg - i - SLEN - 1, "", i, SUFFIX);
+ /* start of the page, prefixed with the cwd */
+ try_mkstemps(p, cwd, i, SUFFIX);
+ /* how about at the end of the page, prefixed with cwd? */
+ try_mkstemps(p + pg - clen - i - SLEN - 1, cwd, i, SUFFIX);
+ }
+
+ return 0;
+}
diff --git a/lib/util/regress/parse_gids/parse_gids_test.c b/lib/util/regress/parse_gids/parse_gids_test.c
new file mode 100644
index 0000000..674bd96
--- /dev/null
+++ b/lib/util/regress/parse_gids/parse_gids_test.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_util.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+/*
+ * Test that sudo_parse_gids() works as expected.
+ */
+
+struct parse_gids_test {
+ const char *gids;
+ gid_t *baseptr;
+ gid_t basegid;
+ int ngids;
+ const GETGROUPS_T *gidlist;
+};
+
+static const GETGROUPS_T test1_out[] = { 0, 1, 2, 3, 4 };
+static const GETGROUPS_T test2_out[] = { 1, 2, 3, 4 };
+static const GETGROUPS_T test3_out[] = { 0, 1, (gid_t)-2, 3, 4 };
+
+/* XXX - test syntax errors too */
+static struct parse_gids_test test_data[] = {
+ { "1,2,3,4", &test_data[0].basegid, 0, 5, test1_out },
+ { "1,2,3,4", NULL, 0, 4, test2_out },
+ { "1,-2,3,4", &test_data[2].basegid, 0, 5, test3_out },
+ { NULL, false, 0, 0, NULL }
+};
+
+static void
+dump_gids(const char *prefix, int ngids, const GETGROUPS_T *gidlist)
+{
+ int i;
+
+ fprintf(stderr, "%s: %s: ", getprogname(), prefix);
+ for (i = 0; i < ngids; i++) {
+ fprintf(stderr, "%s%d", i ? ", " : "", (int)gidlist[i]);
+ }
+ fputc('\n', stderr);
+}
+
+int
+main(int argc, char *argv[])
+{
+ GETGROUPS_T *gidlist = NULL;
+ int i, j, errors = 0, ntests = 0;
+ int ngids;
+ initprogname(argc > 0 ? argv[0] : "parse_gids_test");
+
+ for (i = 0; test_data[i].gids != NULL; i++) {
+ free(gidlist);
+ ngids = sudo_parse_gids(test_data[i].gids, test_data[i].baseptr, &gidlist);
+ if (ngids == -1)
+ exit(1); /* out of memory? */
+ ntests++;
+ if (ngids != test_data[i].ngids) {
+ sudo_warnx_nodebug("test #%d: expected %d gids, got %d",
+ ntests, test_data[i].ngids, ngids);
+ dump_gids("expected", test_data[i].ngids, test_data[i].gidlist);
+ dump_gids("received", ngids, gidlist);
+ errors++;
+ continue;
+ }
+ ntests++;
+ for (j = 0; j < ngids; j++) {
+ if (test_data[i].gidlist[j] != gidlist[j]) {
+ sudo_warnx_nodebug("test #%d: gid mismatch", ntests);
+ dump_gids("expected", test_data[i].ngids, test_data[i].gidlist);
+ dump_gids("received", ngids, gidlist);
+ errors++;
+ break;
+ }
+ }
+ }
+ if (ntests != 0) {
+ printf("%s: %d tests run, %d errors, %d%% success rate\n",
+ getprogname(), ntests, errors, (ntests - errors) * 100 / ntests);
+ }
+ exit(errors);
+}
diff --git a/lib/util/regress/progname/progname_test.c b/lib/util/regress/progname/progname_test.c
new file mode 100644
index 0000000..37c5c22
--- /dev/null
+++ b/lib/util/regress/progname/progname_test.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+/*
+ * Test that getprogname() returns the expected result.
+ * On some systems (AIX), we may have issues with symbolic links.
+ */
+
+int
+main(int argc, char *argv[])
+{
+ char *progbase = "progname_test";
+
+ if (argc > 0) {
+ if ((progbase = strrchr(argv[0], '/')) != NULL)
+ progbase++;
+ else
+ progbase = argv[0];
+ }
+ initprogname(progbase);
+
+ /* Make sure getprogname() matches basename of argv[0]. */
+ if (strcmp(getprogname(), progbase) != 0) {
+ printf("%s: FAIL: incorrect program name \"%s\"\n",
+ progbase, getprogname());
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/lib/util/regress/strsplit/strsplit_test.c b/lib/util/regress/strsplit/strsplit_test.c
new file mode 100644
index 0000000..c9aecda
--- /dev/null
+++ b/lib/util/regress/strsplit/strsplit_test.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_util.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+/*
+ * Test that sudo_strsplit() works as expected.
+ */
+
+struct strsplit_test {
+ const char *input;
+ size_t input_len;
+ const char **output;
+};
+
+static const char test1_in[] = " vi ";
+static const char *test1_out[] = { "vi", NULL };
+static const char test2_in[] = "vi -r ";
+static const char *test2_out[] = { "vi", "-r", NULL };
+static const char test3_in[] = "vi -r -R abc\tdef ";
+static const char *test3_out[] = { "vi", "-r", "-R", "abc", "def", NULL };
+static const char test4_in[] = "vi -r -R abc\tdef ";
+static const char *test4_out[] = { "vi", "-r", "-R", "abc", NULL };
+static const char test5_in[] = "";
+static const char *test5_out[] = { NULL };
+
+static struct strsplit_test test_data[] = {
+ { test1_in, sizeof(test1_in) - 1, test1_out },
+ { test2_in, sizeof(test2_in) - 1, test2_out },
+ { test3_in, sizeof(test3_in) - 1, test3_out },
+ { test4_in, sizeof(test4_in) - 5, test4_out },
+ { test5_in, sizeof(test5_in) - 1, test5_out },
+ { NULL, 0, NULL }
+};
+
+int
+main(int argc, char *argv[])
+{
+ const char *cp, *ep, *input_end;
+ int i, j, errors = 0, ntests = 0;
+ size_t len;
+ initprogname(argc > 0 ? argv[0] : "strsplit_test");
+
+ for (i = 0; test_data[i].input != NULL; i++) {
+ input_end = test_data[i].input + test_data[i].input_len;
+ cp = sudo_strsplit(test_data[i].input, input_end, " \t", &ep);
+ for (j = 0; test_data[i].output[j] != NULL; j++) {
+ ntests++;
+ len = strlen(test_data[i].output[j]);
+ if ((size_t)(ep - cp) != len) {
+ sudo_warnx_nodebug("failed test #%d: bad length, expected "
+ "%zu, got %zu", ntests, len, (size_t)(ep - cp));
+ errors++;
+ continue;
+ }
+ ntests++;
+ if (strncmp(cp, test_data[i].output[j], len) != 0) {
+ sudo_warnx_nodebug("failed test #%d: expected %s, got %.*s",
+ ntests, test_data[i].output[j], (int)(ep - cp), cp);
+ errors++;
+ continue;
+ }
+ cp = sudo_strsplit(NULL, input_end, " \t", &ep);
+ }
+ ntests++;
+ if (cp != NULL) {
+ sudo_warnx_nodebug("failed test #%d: extra tokens \"%.*s\"",
+ ntests, (int)(input_end - cp), cp);
+ errors++;
+ }
+ }
+ if (ntests != 0) {
+ printf("%s: %d tests run, %d errors, %d%% success rate\n",
+ getprogname(), ntests, errors, (ntests - errors) * 100 / ntests);
+ }
+ exit(errors);
+}
diff --git a/lib/util/regress/sudo_conf/conf_test.c b/lib/util/regress/sudo_conf/conf_test.c
new file mode 100644
index 0000000..534b1df
--- /dev/null
+++ b/lib/util/regress/sudo_conf/conf_test.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2013-2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_conf.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+static void sudo_conf_dump(void);
+
+__dso_public int main(int argc, char *argv[]);
+
+/*
+ * Simple test driver for sudo_conf().
+ * Parses the given configuration file and dumps the resulting
+ * sudo_conf_data struct to the standard output.
+ */
+int
+main(int argc, char *argv[])
+{
+ initprogname(argc > 0 ? argv[0] : "conf_test");
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s conf_file\n", getprogname());
+ exit(EXIT_FAILURE);
+ }
+ sudo_conf_clear_paths();
+ if (sudo_conf_read(argv[1], SUDO_CONF_ALL) == -1)
+ exit(EXIT_FAILURE);
+ sudo_conf_dump();
+
+ exit(EXIT_SUCCESS);
+}
+
+static void
+sudo_conf_dump(void)
+{
+ struct plugin_info_list *plugins = sudo_conf_plugins();
+ struct sudo_conf_debug_list *debug_list = sudo_conf_debugging();
+ struct sudo_conf_debug *debug_spec;
+ struct sudo_debug_file *debug_file;
+ struct plugin_info *info;
+
+ printf("Set disable_coredump %s\n",
+ sudo_conf_disable_coredump() ? "true" : "false");
+ printf("Set group_source %s\n",
+ sudo_conf_group_source() == GROUP_SOURCE_ADAPTIVE ? "adaptive" :
+ sudo_conf_group_source() == GROUP_SOURCE_STATIC ? "static" : "dynamic");
+ printf("Set max_groups %d\n", sudo_conf_max_groups());
+ if (sudo_conf_askpass_path() != NULL)
+ printf("Path askpass %s\n", sudo_conf_askpass_path());
+ if (sudo_conf_sesh_path() != NULL)
+ printf("Path sesh %s\n", sudo_conf_sesh_path());
+ if (sudo_conf_noexec_path() != NULL)
+ printf("Path noexec %s\n", sudo_conf_noexec_path());
+ if (sudo_conf_plugin_dir_path() != NULL)
+ printf("Path plugin_dir %s\n", sudo_conf_plugin_dir_path());
+ TAILQ_FOREACH(info, plugins, entries) {
+ printf("Plugin %s %s", info->symbol_name, info->path);
+ if (info->options) {
+ char * const * op;
+ for (op = info->options; *op != NULL; op++)
+ printf(" %s", *op);
+ }
+ putchar('\n');
+ }
+ TAILQ_FOREACH(debug_spec, debug_list, entries) {
+ TAILQ_FOREACH(debug_file, &debug_spec->debug_files, entries) {
+ printf("Debug %s %s %s\n", debug_spec->progname,
+ debug_file->debug_file, debug_file->debug_flags);
+ }
+ }
+}
diff --git a/lib/util/regress/sudo_conf/test1.in b/lib/util/regress/sudo_conf/test1.in
new file mode 100644
index 0000000..41282d7
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test1.in
@@ -0,0 +1,73 @@
+#
+# Sample /etc/sudo.conf file
+#
+# Format:
+# Plugin plugin_name plugin_path plugin_options ...
+# Path askpass /path/to/askpass
+# Path noexec /path/to/sudo_noexec.so
+# Debug sudo /var/log/sudo_debug all@warn
+# Set disable_coredump true
+#
+# Sudo plugins:
+#
+# The plugin_path is relative to ${prefix}/libexec unless fully qualified.
+# The plugin_name corresponds to a global symbol in the plugin
+# that contains the plugin interface structure.
+# The plugin_options are optional.
+#
+# The sudoers plugin is used by default if no Plugin lines are present.
+Plugin sudoers_policy sudoers.so
+Plugin sudoers_io sudoers.so
+
+#
+# Sudo askpass:
+#
+# An askpass helper program may be specified to provide a graphical
+# password prompt for "sudo -A" support. Sudo does not ship with its
+# own askpass program but can use the OpenSSH askpass.
+#
+# Use the OpenSSH askpass
+Path askpass /usr/X11R6/bin/ssh-askpass
+#
+# Use the Gnome OpenSSH askpass
+#Path askpass /usr/libexec/openssh/gnome-ssh-askpass
+
+#
+# Sudo noexec:
+#
+# Path to a shared library containing dummy versions of the execv(),
+# execve() and fexecve() library functions that just return an error.
+# This is used to implement the "noexec" functionality on systems that
+# support C<LD_PRELOAD> or its equivalent.
+# The compiled-in value is usually sufficient and should only be changed
+# if you rename or move the sudo_noexec.so file.
+#
+Path noexec /usr/local/libexec/sudo_noexec.so
+Path noexec /usr/libexec/sudo_noexec.so
+
+#
+# Core dumps:
+#
+# By default, sudo disables core dumps while it is executing (they
+# are re-enabled for the command that is run).
+# To aid in debugging sudo problems, you may wish to enable core
+# dumps by setting "disable_coredump" to false.
+#
+Set disable_coredump false
+
+#
+# User groups:
+#
+# Sudo passes the user's group list to the policy plugin.
+# If the user is a member of the maximum number of groups (usually 16),
+# sudo will query the group database directly to be sure to include
+# the full list of groups.
+#
+# On some systems, this can be expensive so the behavior is configurable.
+# The "group_source" setting has three possible values:
+# static - use the user's list of groups returned by the kernel.
+# dynamic - query the group database to find the list of groups.
+# adaptive - if user is in less than the maximum number of groups.
+# use the kernel list, else query the group database.
+#
+Set group_source static
diff --git a/lib/util/regress/sudo_conf/test1.out.ok b/lib/util/regress/sudo_conf/test1.out.ok
new file mode 100644
index 0000000..1880748
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test1.out.ok
@@ -0,0 +1,7 @@
+Set disable_coredump false
+Set group_source static
+Set max_groups -1
+Path askpass /usr/X11R6/bin/ssh-askpass
+Path noexec /usr/libexec/sudo_noexec.so
+Plugin sudoers_policy sudoers.so
+Plugin sudoers_io sudoers.so
diff --git a/lib/util/regress/sudo_conf/test2.in b/lib/util/regress/sudo_conf/test2.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test2.in
diff --git a/lib/util/regress/sudo_conf/test2.out.ok b/lib/util/regress/sudo_conf/test2.out.ok
new file mode 100644
index 0000000..af42145
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test2.out.ok
@@ -0,0 +1,3 @@
+Set disable_coredump true
+Set group_source adaptive
+Set max_groups -1
diff --git a/lib/util/regress/sudo_conf/test3.in b/lib/util/regress/sudo_conf/test3.in
new file mode 100644
index 0000000..b111a23
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test3.in
@@ -0,0 +1,2 @@
+Plugin sudoers_policy sudoers.so sudoers_file=/etc/sudoers sudoers_mode=0400 sudoers_gid=0 sudoers_uid=0
+Plugin sudoers_io sudoers.so
diff --git a/lib/util/regress/sudo_conf/test3.out.ok b/lib/util/regress/sudo_conf/test3.out.ok
new file mode 100644
index 0000000..819d638
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test3.out.ok
@@ -0,0 +1,5 @@
+Set disable_coredump true
+Set group_source adaptive
+Set max_groups -1
+Plugin sudoers_policy sudoers.so sudoers_file=/etc/sudoers sudoers_mode=0400 sudoers_gid=0 sudoers_uid=0
+Plugin sudoers_io sudoers.so
diff --git a/lib/util/regress/sudo_conf/test4.err.ok b/lib/util/regress/sudo_conf/test4.err.ok
new file mode 100644
index 0000000..2d68831
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test4.err.ok
@@ -0,0 +1 @@
+conf_test: invalid value for disable_coredump "foo" in regress/sudo_conf/test4.in, line 1
diff --git a/lib/util/regress/sudo_conf/test4.in b/lib/util/regress/sudo_conf/test4.in
new file mode 100644
index 0000000..a60236a
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test4.in
@@ -0,0 +1 @@
+Set disable_coredump foo
diff --git a/lib/util/regress/sudo_conf/test4.out.ok b/lib/util/regress/sudo_conf/test4.out.ok
new file mode 100644
index 0000000..af42145
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test4.out.ok
@@ -0,0 +1,3 @@
+Set disable_coredump true
+Set group_source adaptive
+Set max_groups -1
diff --git a/lib/util/regress/sudo_conf/test5.err.ok b/lib/util/regress/sudo_conf/test5.err.ok
new file mode 100644
index 0000000..85ef46b
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test5.err.ok
@@ -0,0 +1 @@
+conf_test: invalid max groups "0" in regress/sudo_conf/test5.in, line 1
diff --git a/lib/util/regress/sudo_conf/test5.in b/lib/util/regress/sudo_conf/test5.in
new file mode 100644
index 0000000..3a20495
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test5.in
@@ -0,0 +1 @@
+Set max_groups 0
diff --git a/lib/util/regress/sudo_conf/test5.out.ok b/lib/util/regress/sudo_conf/test5.out.ok
new file mode 100644
index 0000000..af42145
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test5.out.ok
@@ -0,0 +1,3 @@
+Set disable_coredump true
+Set group_source adaptive
+Set max_groups -1
diff --git a/lib/util/regress/sudo_conf/test6.in b/lib/util/regress/sudo_conf/test6.in
new file mode 100644
index 0000000..537fa57
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test6.in
@@ -0,0 +1 @@
+Set max_groups 16
diff --git a/lib/util/regress/sudo_conf/test6.out.ok b/lib/util/regress/sudo_conf/test6.out.ok
new file mode 100644
index 0000000..1f62f84
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test6.out.ok
@@ -0,0 +1,3 @@
+Set disable_coredump true
+Set group_source adaptive
+Set max_groups 16
diff --git a/lib/util/regress/sudo_conf/test7.in b/lib/util/regress/sudo_conf/test7.in
new file mode 100644
index 0000000..7438131
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test7.in
@@ -0,0 +1,4 @@
+Debug sudo /var/log/sudo_debug all@info
+Debug sudo /var/log/sudo_debug util@debug
+Debug visudo /var/log/sudo_debug match@debug
+Debug sudoers.so /var/log/sudoers_debug match@debug,nss@info
diff --git a/lib/util/regress/sudo_conf/test7.out.ok b/lib/util/regress/sudo_conf/test7.out.ok
new file mode 100644
index 0000000..5644109
--- /dev/null
+++ b/lib/util/regress/sudo_conf/test7.out.ok
@@ -0,0 +1,7 @@
+Set disable_coredump true
+Set group_source adaptive
+Set max_groups -1
+Debug sudo /var/log/sudo_debug all@info
+Debug sudo /var/log/sudo_debug util@debug
+Debug visudo /var/log/sudo_debug match@debug
+Debug sudoers.so /var/log/sudoers_debug match@debug,nss@info
diff --git a/lib/util/regress/sudo_parseln/parseln_test.c b/lib/util/regress/sudo_parseln/parseln_test.c
new file mode 100644
index 0000000..ac46dd8
--- /dev/null
+++ b/lib/util/regress/sudo_parseln/parseln_test.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+/*
+ * Simple test driver for sudo_parseln().
+ * Behaves similarly to "cat -n" but with comment removal
+ * and line continuation.
+ */
+
+int
+main(int argc, char *argv[])
+{
+ unsigned int lineno = 0;
+ size_t linesize = 0;
+ char *line = NULL;
+
+ initprogname(argc > 0 ? argv[0] : "parseln_test");
+
+ while (sudo_parseln(&line, &linesize, &lineno, stdin, 0) != -1)
+ printf("%6u\t%s\n", lineno, line);
+ free(line);
+ exit(0);
+}
diff --git a/lib/util/regress/sudo_parseln/test1.in b/lib/util/regress/sudo_parseln/test1.in
new file mode 100644
index 0000000..c605bb5
--- /dev/null
+++ b/lib/util/regress/sudo_parseln/test1.in
@@ -0,0 +1,72 @@
+#
+# Sample /etc/sudo.conf file
+#
+# Format:
+# Plugin plugin_name plugin_path plugin_options ...
+# Path askpass /path/to/askpass
+# Path noexec /path/to/sudo_noexec.so
+# Debug sudo /var/log/sudo_debug all@warn
+# Set disable_coredump true
+#
+# Sudo plugins:
+#
+# The plugin_path is relative to ${prefix}/libexec unless fully qualified.
+# The plugin_name corresponds to a global symbol in the plugin
+# that contains the plugin interface structure.
+# The plugin_options are optional.
+#
+# The sudoers plugin is used by default if no Plugin lines are present.
+Plugin sudoers_policy sudoers.so
+Plugin sudoers_io sudoers.so
+
+#
+# Sudo askpass:
+#
+# An askpass helper program may be specified to provide a graphical
+# password prompt for "sudo -A" support. Sudo does not ship with its
+# own askpass program but can use the OpenSSH askpass.
+#
+# Use the OpenSSH askpass
+#Path askpass /usr/X11R6/bin/ssh-askpass
+#
+# Use the Gnome OpenSSH askpass
+#Path askpass /usr/libexec/openssh/gnome-ssh-askpass
+
+#
+# Sudo noexec:
+#
+# Path to a shared library containing dummy versions of the execv(),
+# execve() and fexecve() library functions that just return an error.
+# This is used to implement the "noexec" functionality on systems that
+# support C<LD_PRELOAD> or its equivalent.
+# The compiled-in value is usually sufficient and should only be changed
+# if you rename or move the sudo_noexec.so file.
+#
+#Path noexec /usr/libexec/sudo_noexec.so
+
+#
+# Core dumps:
+#
+# By default, sudo disables core dumps while it is executing (they
+# are re-enabled for the command that is run).
+# To aid in debugging sudo problems, you may wish to enable core
+# dumps by setting "disable_coredump" to false.
+#
+#Set disable_coredump false
+
+#
+# User groups:
+#
+# Sudo passes the user's group list to the policy plugin.
+# If the user is a member of the maximum number of groups (usually 16),
+# sudo will query the group database directly to be sure to include
+# the full list of groups.
+#
+# On some systems, this can be expensive so the behavior is configurable.
+# The "group_source" setting has three possible values:
+# static - use the user's list of groups returned by the kernel.
+# dynamic - query the group database to find the list of groups.
+# adaptive - if user is in less than the maximum number of groups.
+# use the kernel list, else query the group database.
+#
+#Set group_source static
diff --git a/lib/util/regress/sudo_parseln/test1.out.ok b/lib/util/regress/sudo_parseln/test1.out.ok
new file mode 100644
index 0000000..c98ca77
--- /dev/null
+++ b/lib/util/regress/sudo_parseln/test1.out.ok
@@ -0,0 +1,72 @@
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19 Plugin sudoers_policy sudoers.so
+ 20 Plugin sudoers_io sudoers.so
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
diff --git a/lib/util/regress/sudo_parseln/test2.in b/lib/util/regress/sudo_parseln/test2.in
new file mode 100644
index 0000000..49166ee
--- /dev/null
+++ b/lib/util/regress/sudo_parseln/test2.in
@@ -0,0 +1,8 @@
+this \
+is all \
+one line
+# this is a comment, and does not get continued\
+trim the \
+ leading \
+ white \
+space
diff --git a/lib/util/regress/sudo_parseln/test2.out.ok b/lib/util/regress/sudo_parseln/test2.out.ok
new file mode 100644
index 0000000..d921968
--- /dev/null
+++ b/lib/util/regress/sudo_parseln/test2.out.ok
@@ -0,0 +1,3 @@
+ 3 this is all one line
+ 4
+ 8 trim the leading white space
diff --git a/lib/util/regress/sudo_parseln/test3.in b/lib/util/regress/sudo_parseln/test3.in
new file mode 100644
index 0000000..e372c07
--- /dev/null
+++ b/lib/util/regress/sudo_parseln/test3.in
@@ -0,0 +1 @@
+line continuation at EOF \
diff --git a/lib/util/regress/sudo_parseln/test3.out.ok b/lib/util/regress/sudo_parseln/test3.out.ok
new file mode 100644
index 0000000..2e8d16d
--- /dev/null
+++ b/lib/util/regress/sudo_parseln/test3.out.ok
@@ -0,0 +1 @@
+ 1 line continuation at EOF
diff --git a/lib/util/regress/sudo_parseln/test4.in b/lib/util/regress/sudo_parseln/test4.in
new file mode 100644
index 0000000..3583f3b
--- /dev/null
+++ b/lib/util/regress/sudo_parseln/test4.in
@@ -0,0 +1,4 @@
+line contin\
+uation raw
+line contin\
+ uation indented
diff --git a/lib/util/regress/sudo_parseln/test4.out.ok b/lib/util/regress/sudo_parseln/test4.out.ok
new file mode 100644
index 0000000..38afbeb
--- /dev/null
+++ b/lib/util/regress/sudo_parseln/test4.out.ok
@@ -0,0 +1,2 @@
+ 2 line continuation raw
+ 4 line continuation indented
diff --git a/lib/util/regress/sudo_parseln/test5.in b/lib/util/regress/sudo_parseln/test5.in
new file mode 100644
index 0000000..57ddad2
--- /dev/null
+++ b/lib/util/regress/sudo_parseln/test5.in
@@ -0,0 +1 @@
+\
diff --git a/lib/util/regress/sudo_parseln/test5.out.ok b/lib/util/regress/sudo_parseln/test5.out.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/util/regress/sudo_parseln/test5.out.ok
diff --git a/lib/util/regress/sudo_parseln/test6.in b/lib/util/regress/sudo_parseln/test6.in
new file mode 100644
index 0000000..95cac84
--- /dev/null
+++ b/lib/util/regress/sudo_parseln/test6.in
@@ -0,0 +1,3 @@
+ leading and trailing white space
+ # a comment
+\
diff --git a/lib/util/regress/sudo_parseln/test6.out.ok b/lib/util/regress/sudo_parseln/test6.out.ok
new file mode 100644
index 0000000..340765e
--- /dev/null
+++ b/lib/util/regress/sudo_parseln/test6.out.ok
@@ -0,0 +1,2 @@
+ 1 leading and trailing white space
+ 2
diff --git a/lib/util/regress/tailq/hltq_test.c b/lib/util/regress/tailq/hltq_test.c
new file mode 100644
index 0000000..5333a15
--- /dev/null
+++ b/lib/util/regress/tailq/hltq_test.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2013 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_queue.h"
+#include "sudo_util.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+/*
+ * Note: HLTQ_ENTRY is intentionally in the middle of the struct
+ * to catch bad assumptions in the PREV/NEXT macros.
+ */
+struct test_data {
+ int a;
+ HLTQ_ENTRY(test_data) entries;
+ char b;
+};
+
+TAILQ_HEAD(test_data_list, test_data);
+
+/*
+ * Simple tests for headless tail queue macros.
+ */
+int
+main(int argc, char *argv[])
+{
+ struct test_data d1, d2, d3;
+ struct test_data *hltq;
+ struct test_data_list tq;
+ int errors = 0;
+ int ntests = 0;
+
+ initprogname(argc > 0 ? argv[0] : "hltq_test");
+
+ /*
+ * Initialize three data elements and concatenate them in order.
+ */
+ HLTQ_INIT(&d1, entries);
+ d1.a = 1;
+ d1.b = 'a';
+ if (HLTQ_FIRST(&d1) != &d1) {
+ sudo_warnx_nodebug("FAIL: HLTQ_FIRST(1 entry) doesn't return first element: got %p, expected %p", HLTQ_FIRST(&d1), &d1);
+ errors++;
+ }
+ ntests++;
+ if (HLTQ_LAST(&d1, test_data, entries) != &d1) {
+ sudo_warnx_nodebug("FAIL: HLTQ_LAST(1 entry) doesn't return first element: got %p, expected %p", HLTQ_LAST(&d1, test_data, entries), &d1);
+ errors++;
+ }
+ ntests++;
+ if (HLTQ_PREV(&d1, test_data, entries) != NULL) {
+ sudo_warnx_nodebug("FAIL: HLTQ_PREV(1 entry) doesn't return NULL: got %p", HLTQ_PREV(&d1, test_data, entries));
+ errors++;
+ }
+ ntests++;
+
+ HLTQ_INIT(&d2, entries);
+ d2.a = 2;
+ d2.b = 'b';
+
+ HLTQ_INIT(&d3, entries);
+ d3.a = 3;
+ d3.b = 'c';
+
+ HLTQ_CONCAT(&d1, &d2, entries);
+ HLTQ_CONCAT(&d1, &d3, entries);
+ hltq = &d1;
+
+ /*
+ * Verify that HLTQ_FIRST, HLTQ_LAST, HLTQ_NEXT, HLTQ_PREV
+ * work as expected.
+ */
+ if (HLTQ_FIRST(hltq) != &d1) {
+ sudo_warnx_nodebug("FAIL: HLTQ_FIRST(3 entries) doesn't return first element: got %p, expected %p", HLTQ_FIRST(hltq), &d1);
+ errors++;
+ }
+ ntests++;
+ if (HLTQ_LAST(hltq, test_data, entries) != &d3) {
+ sudo_warnx_nodebug("FAIL: HLTQ_LAST(3 entries) doesn't return third element: got %p, expected %p", HLTQ_LAST(hltq, test_data, entries), &d3);
+ errors++;
+ }
+ ntests++;
+
+ if (HLTQ_NEXT(&d1, entries) != &d2) {
+ sudo_warnx_nodebug("FAIL: HLTQ_NEXT(&d1) doesn't return &d2: got %p, expected %p", HLTQ_NEXT(&d1, entries), &d2);
+ errors++;
+ }
+ ntests++;
+ if (HLTQ_NEXT(&d2, entries) != &d3) {
+ sudo_warnx_nodebug("FAIL: HLTQ_NEXT(&d2) doesn't return &d3: got %p, expected %p", HLTQ_NEXT(&d2, entries), &d3);
+ errors++;
+ }
+ ntests++;
+ if (HLTQ_NEXT(&d3, entries) != NULL) {
+ sudo_warnx_nodebug("FAIL: HLTQ_NEXT(&d3) doesn't return NULL: got %p", HLTQ_NEXT(&d3, entries));
+ errors++;
+ }
+ ntests++;
+
+ if (HLTQ_PREV(&d1, test_data, entries) != NULL) {
+ sudo_warnx_nodebug("FAIL: HLTQ_PREV(&d1) doesn't return NULL: got %p", HLTQ_PREV(&d1, test_data, entries));
+ errors++;
+ }
+ ntests++;
+ if (HLTQ_PREV(&d2, test_data, entries) != &d1) {
+ sudo_warnx_nodebug("FAIL: HLTQ_PREV(&d2) doesn't return &d1: got %p, expected %p", HLTQ_PREV(&d2, test_data, entries), &d1);
+ errors++;
+ }
+ ntests++;
+ if (HLTQ_PREV(&d3, test_data, entries) != &d2) {
+ sudo_warnx_nodebug("FAIL: HLTQ_PREV(&d3) doesn't return &d2: got %p, expected %p", HLTQ_PREV(&d3, test_data, entries), &d2);
+ errors++;
+ }
+ ntests++;
+
+ /* Test conversion to TAILQ. */
+ HLTQ_TO_TAILQ(&tq, hltq, entries);
+
+ if (TAILQ_FIRST(&tq) != &d1) {
+ sudo_warnx_nodebug("FAIL: TAILQ_FIRST(&tq) doesn't return first element: got %p, expected %p", TAILQ_FIRST(&tq), &d1);
+ errors++;
+ }
+ ntests++;
+ if (TAILQ_LAST(&tq, test_data_list) != &d3) {
+ sudo_warnx_nodebug("FAIL: TAILQ_LAST(&tq) doesn't return third element: got %p, expected %p", TAILQ_LAST(&tq, test_data_list), &d3);
+ errors++;
+ }
+ ntests++;
+
+ if (TAILQ_NEXT(&d1, entries) != &d2) {
+ sudo_warnx_nodebug("FAIL: TAILQ_NEXT(&d1) doesn't return &d2: got %p, expected %p", TAILQ_NEXT(&d1, entries), &d2);
+ errors++;
+ }
+ ntests++;
+ if (TAILQ_NEXT(&d2, entries) != &d3) {
+ sudo_warnx_nodebug("FAIL: TAILQ_NEXT(&d2) doesn't return &d3: got %p, expected %p", TAILQ_NEXT(&d2, entries), &d3);
+ errors++;
+ }
+ ntests++;
+ if (TAILQ_NEXT(&d3, entries) != NULL) {
+ sudo_warnx_nodebug("FAIL: TAILQ_NEXT(&d3) doesn't return NULL: got %p", TAILQ_NEXT(&d3, entries));
+ errors++;
+ }
+ ntests++;
+
+ if (TAILQ_PREV(&d1, test_data_list, entries) != NULL) {
+ sudo_warnx_nodebug("FAIL: TAILQ_PREV(&d1) doesn't return NULL: got %p", TAILQ_PREV(&d1, test_data_list, entries));
+ errors++;
+ }
+ ntests++;
+ if (TAILQ_PREV(&d2, test_data_list, entries) != &d1) {
+ sudo_warnx_nodebug("FAIL: TAILQ_PREV(&d2) doesn't return &d1: got %p, expected %p", TAILQ_PREV(&d2, test_data_list, entries), &d1);
+ errors++;
+ }
+ ntests++;
+ if (TAILQ_PREV(&d3, test_data_list, entries) != &d2) {
+ sudo_warnx_nodebug("FAIL: TAILQ_PREV(&d3) doesn't return &d2: got %p, expected %p", TAILQ_PREV(&d3, test_data_list, entries), &d2);
+ errors++;
+ }
+ ntests++;
+
+ printf("%s: %d tests run, %d errors, %d%% success rate\n", getprogname(),
+ ntests, errors, (ntests - errors) * 100 / ntests);
+
+ exit(errors);
+}
diff --git a/lib/util/regress/vsyslog/vsyslog_test.c b/lib/util/regress/vsyslog/vsyslog_test.c
new file mode 100644
index 0000000..70a8d0d
--- /dev/null
+++ b/lib/util/regress/vsyslog/vsyslog_test.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+#include <errno.h>
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_util.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+/*
+ * Test that sudo_vsyslog() works as expected.
+ */
+static char *expected_result;
+static int errors;
+static int ntests;
+
+/*
+ * Dummy version of syslog to verify the message
+ */
+void
+syslog(int priority, const char *fmt, ...)
+{
+ va_list ap;
+ const char *msg;
+
+ if (strcmp(fmt, "%s") != 0)
+ sudo_fatalx_nodebug("Expected syslog format \"%%s\", got \"%s\"", fmt);
+
+ va_start(ap, fmt);
+ msg = va_arg(ap, char *);
+ if (strcmp(msg, expected_result) != 0) {
+ sudo_warnx_nodebug("Expected \"%s\", got \"%s\"", expected_result, msg);
+ errors++;
+ } else {
+ ntests++;
+ }
+ va_end(ap);
+}
+
+static void
+test_vsyslog(int priority, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ sudo_vsyslog(priority, fmt, ap);
+ va_end(ap);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char buf1[1024 * 16], buf2[1024 * 16];
+ initprogname(argc > 0 ? argv[0] : "vsyslog_test");
+
+ /* Test small buffer. */
+ expected_result = "sudo: millert : TTY=ttypa ; PWD=/etc/mail ; USER=root ; TSID=000AB0 ; COMMAND=/usr/sbin/newaliases";
+ test_vsyslog(0,
+ "%s: %s : TTY=%s ; PWD=%s ; USER=%s ; TSID=%s ; COMMAND=%s",
+ "sudo", "millert", "ttypa", "/etc/mail", "root", "000AB0",
+ "/usr/sbin/newaliases");
+
+ /* Test small buffer w/ errno. */
+ snprintf(buf1, sizeof(buf1),
+ "unable to open %s: %s", "/var/log/sudo-io/seq", strerror(ENOENT));
+ expected_result = buf1;
+ errno = ENOENT;
+ test_vsyslog(0, "unable to open %s: %m", "/var/log/sudo-io/seq");
+
+ /* Test large buffer > 8192 bytes. */
+ memset(buf1, 'a', 8192);
+ buf1[8192] = '\0';
+ expected_result = buf1;
+ test_vsyslog(0, "%s", buf1);
+
+ /* Test large buffer w/ errno > 8192 bytes. */
+ memset(buf1, 'b', 8184);
+ buf1[8184] = '\0';
+ snprintf(buf2, sizeof(buf2), "%s: %s", buf1, strerror(EINVAL));
+ expected_result = buf2;
+ errno = EINVAL;
+ test_vsyslog(0, "%s: %m", buf1);
+
+ /* Test large format string > 8192 bytes, expect truncation to 2048. */
+ memset(buf1, 'b', 8184);
+ buf1[8184] = '\0';
+ snprintf(buf2, sizeof(buf2), "%.*s", 2047, buf1);
+ expected_result = buf2;
+ test_vsyslog(0, buf1);
+
+ if (ntests != 0) {
+ printf("%s: %d tests run, %d errors, %d%% success rate\n",
+ getprogname(), ntests, errors, (ntests - errors) * 100 / ntests);
+ } else {
+ printf("%s: error, no tests run!\n", getprogname());
+ errors = 1;
+ }
+ exit(errors);
+}
diff --git a/lib/util/secure_path.c b/lib/util/secure_path.c
new file mode 100644
index 0000000..b1d4415
--- /dev/null
+++ b/lib/util/secure_path.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2012, 2014-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+#include "sudo_debug.h"
+
+/*
+ * Verify that path is the right type and not writable by other users.
+ */
+static int
+sudo_secure_path(const char *path, unsigned int type, uid_t uid, gid_t gid, struct stat *sbp)
+{
+ struct stat sb;
+ int ret = SUDO_PATH_MISSING;
+ debug_decl(sudo_secure_path, SUDO_DEBUG_UTIL)
+
+ if (path != NULL && stat(path, &sb) == 0) {
+ if ((sb.st_mode & _S_IFMT) != type) {
+ ret = SUDO_PATH_BAD_TYPE;
+ } else if (uid != (uid_t)-1 && sb.st_uid != uid) {
+ ret = SUDO_PATH_WRONG_OWNER;
+ } else if (sb.st_mode & S_IWOTH) {
+ ret = SUDO_PATH_WORLD_WRITABLE;
+ } else if (ISSET(sb.st_mode, S_IWGRP) &&
+ (gid == (gid_t)-1 || sb.st_gid != gid)) {
+ ret = SUDO_PATH_GROUP_WRITABLE;
+ } else {
+ ret = SUDO_PATH_SECURE;
+ }
+ if (sbp)
+ (void) memcpy(sbp, &sb, sizeof(struct stat));
+ }
+
+ debug_return_int(ret);
+}
+
+/*
+ * Verify that path is a regular file and not writable by other users.
+ */
+int
+sudo_secure_file_v1(const char *path, uid_t uid, gid_t gid, struct stat *sbp)
+{
+ return sudo_secure_path(path, _S_IFREG, uid, gid, sbp);
+}
+
+/*
+ * Verify that path is a directory and not writable by other users.
+ */
+int
+sudo_secure_dir_v1(const char *path, uid_t uid, gid_t gid, struct stat *sbp)
+{
+ return sudo_secure_path(path, _S_IFDIR, uid, gid, sbp);
+}
diff --git a/lib/util/setgroups.c b/lib/util/setgroups.c
new file mode 100644
index 0000000..9b81456
--- /dev/null
+++ b/lib/util/setgroups.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <grp.h>
+#include <limits.h>
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+int
+sudo_setgroups_v1(int ngids, const GETGROUPS_T *gids)
+{
+ int maxgids, ret;
+ debug_decl(sudo_setgroups, SUDO_DEBUG_UTIL)
+
+ ret = setgroups(ngids, (GETGROUPS_T *)gids);
+ if (ret == -1 && errno == EINVAL) {
+ /* Too many groups, try again with fewer. */
+ maxgids = (int)sysconf(_SC_NGROUPS_MAX);
+ if (maxgids == -1)
+ maxgids = NGROUPS_MAX;
+ if (ngids > maxgids)
+ ret = setgroups(maxgids, (GETGROUPS_T *)gids);
+ }
+ debug_return_int(ret);
+}
diff --git a/lib/util/sha2.c b/lib/util/sha2.c
new file mode 100644
index 0000000..9a172e3
--- /dev/null
+++ b/lib/util/sha2.c
@@ -0,0 +1,522 @@
+/*
+ * Copyright (c) 2013-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+/*
+ * Implementation of SHA-224, SHA-256, SHA-384 and SHA-512
+ * as per FIPS 180-4: Secure Hash Standard (SHS)
+ * http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
+ *
+ * Derived from the public domain SHA-1 and SHA-2 implementations
+ * by Steve Reid and Wei Dai respectively.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#if defined(HAVE_ENDIAN_H)
+# include <endian.h>
+#elif defined(HAVE_SYS_ENDIAN_H)
+# include <sys/endian.h>
+#elif defined(HAVE_MACHINE_ENDIAN_H)
+# include <machine/endian.h>
+#else
+# include "compat/endian.h"
+#endif
+
+#include "sudo_compat.h"
+#include "compat/sha2.h"
+
+/*
+ * SHA-2 operates on 32-bit and 64-bit words in big endian byte order.
+ * The following macros convert between character arrays and big endian words.
+ */
+#define BE8TO32(x, y) do { \
+ (x) = (((uint32_t)((y)[0] & 255) << 24) | \
+ ((uint32_t)((y)[1] & 255) << 16) | \
+ ((uint32_t)((y)[2] & 255) << 8) | \
+ ((uint32_t)((y)[3] & 255))); \
+} while (0)
+
+#define BE8TO64(x, y) do { \
+ (x) = (((uint64_t)((y)[0] & 255) << 56) | \
+ ((uint64_t)((y)[1] & 255) << 48) | \
+ ((uint64_t)((y)[2] & 255) << 40) | \
+ ((uint64_t)((y)[3] & 255) << 32) | \
+ ((uint64_t)((y)[4] & 255) << 24) | \
+ ((uint64_t)((y)[5] & 255) << 16) | \
+ ((uint64_t)((y)[6] & 255) << 8) | \
+ ((uint64_t)((y)[7] & 255))); \
+} while (0)
+
+#define BE32TO8(x, y) do { \
+ (x)[0] = (uint8_t)(((y) >> 24) & 255); \
+ (x)[1] = (uint8_t)(((y) >> 16) & 255); \
+ (x)[2] = (uint8_t)(((y) >> 8) & 255); \
+ (x)[3] = (uint8_t)((y) & 255); \
+} while (0)
+
+#define BE64TO8(x, y) do { \
+ (x)[0] = (uint8_t)(((y) >> 56) & 255); \
+ (x)[1] = (uint8_t)(((y) >> 48) & 255); \
+ (x)[2] = (uint8_t)(((y) >> 40) & 255); \
+ (x)[3] = (uint8_t)(((y) >> 32) & 255); \
+ (x)[4] = (uint8_t)(((y) >> 24) & 255); \
+ (x)[5] = (uint8_t)(((y) >> 16) & 255); \
+ (x)[6] = (uint8_t)(((y) >> 8) & 255); \
+ (x)[7] = (uint8_t)((y) & 255); \
+} while (0)
+
+#define rotrFixed(x,y) (y ? ((x>>y) | (x<<(sizeof(x)*8-y))) : x)
+
+#define blk0(i) (W[i])
+#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
+
+#define Ch(x,y,z) (z^(x&(y^z)))
+#define Maj(x,y,z) (y^((x^y)&(y^z)))
+
+#define a(i) T[(0-i)&7]
+#define b(i) T[(1-i)&7]
+#define c(i) T[(2-i)&7]
+#define d(i) T[(3-i)&7]
+#define e(i) T[(4-i)&7]
+#define f(i) T[(5-i)&7]
+#define g(i) T[(6-i)&7]
+#define h(i) T[(7-i)&7]
+
+void
+SHA224Init(SHA2_CTX *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->state.st32[0] = 0xc1059ed8UL;
+ ctx->state.st32[1] = 0x367cd507UL;
+ ctx->state.st32[2] = 0x3070dd17UL;
+ ctx->state.st32[3] = 0xf70e5939UL;
+ ctx->state.st32[4] = 0xffc00b31UL;
+ ctx->state.st32[5] = 0x68581511UL;
+ ctx->state.st32[6] = 0x64f98fa7UL;
+ ctx->state.st32[7] = 0xbefa4fa4UL;
+}
+
+void
+SHA224Transform(uint32_t state[8], const uint8_t buffer[SHA224_BLOCK_LENGTH])
+{
+ SHA256Transform(state, buffer);
+}
+
+void
+SHA224Update(SHA2_CTX *ctx, const uint8_t *data, size_t len)
+{
+ SHA256Update(ctx, data, len);
+}
+
+void
+SHA224Pad(SHA2_CTX *ctx)
+{
+ SHA256Pad(ctx);
+}
+
+void
+SHA224Final(uint8_t digest[SHA224_DIGEST_LENGTH], SHA2_CTX *ctx)
+{
+ SHA256Pad(ctx);
+ if (digest != NULL) {
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy(digest, ctx->state.st32, SHA224_DIGEST_LENGTH);
+#else
+ unsigned int i;
+
+ for (i = 0; i < 7; i++)
+ BE32TO8(digest + (i * 4), ctx->state.st32[i]);
+#endif
+ memset(ctx, 0, sizeof(*ctx));
+ }
+}
+
+static const uint32_t SHA256_K[64] = {
+ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+ 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+ 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+ 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+ 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+ 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+ 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+ 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+ 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+ 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+ 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+ 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+ 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+void
+SHA256Init(SHA2_CTX *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->state.st32[0] = 0x6a09e667UL;
+ ctx->state.st32[1] = 0xbb67ae85UL;
+ ctx->state.st32[2] = 0x3c6ef372UL;
+ ctx->state.st32[3] = 0xa54ff53aUL;
+ ctx->state.st32[4] = 0x510e527fUL;
+ ctx->state.st32[5] = 0x9b05688cUL;
+ ctx->state.st32[6] = 0x1f83d9abUL;
+ ctx->state.st32[7] = 0x5be0cd19UL;
+}
+
+/* Round macros for SHA256 */
+#define R(i) do { \
+ h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i)); \
+ d(i)+=h(i); \
+ h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)); \
+} while (0)
+
+#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))
+#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))
+#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))
+#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))
+
+void
+SHA256Transform(uint32_t state[8], const uint8_t data[SHA256_BLOCK_LENGTH])
+{
+ uint32_t W[16];
+ uint32_t T[8];
+ unsigned int j;
+
+ /* Copy context state to working vars. */
+ memcpy(T, state, sizeof(T));
+ /* Copy data to W in big endian format. */
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy(W, data, sizeof(W));
+#else
+ for (j = 0; j < 16; j++) {
+ BE8TO32(W[j], data);
+ data += 4;
+ }
+#endif
+ /* 64 operations, partially loop unrolled. */
+ for (j = 0; j < 64; j += 16)
+ {
+ R( 0); R( 1); R( 2); R( 3);
+ R( 4); R( 5); R( 6); R( 7);
+ R( 8); R( 9); R(10); R(11);
+ R(12); R(13); R(14); R(15);
+ }
+ /* Add the working vars back into context state. */
+ state[0] += a(0);
+ state[1] += b(0);
+ state[2] += c(0);
+ state[3] += d(0);
+ state[4] += e(0);
+ state[5] += f(0);
+ state[6] += g(0);
+ state[7] += h(0);
+ /* Cleanup */
+ memset_s(T, sizeof(T), 0, sizeof(T));
+ memset_s(W, sizeof(W), 0, sizeof(W));
+}
+
+#undef S0
+#undef S1
+#undef s0
+#undef s1
+#undef R
+
+void
+SHA256Update(SHA2_CTX *ctx, const uint8_t *data, size_t len)
+{
+ size_t i = 0, j;
+
+ j = (size_t)((ctx->count[0] >> 3) & (SHA256_BLOCK_LENGTH - 1));
+ ctx->count[0] += ((uint64_t)len << 3);
+ if ((j + len) > SHA256_BLOCK_LENGTH - 1) {
+ memcpy(&ctx->buffer[j], data, (i = SHA256_BLOCK_LENGTH - j));
+ SHA256Transform(ctx->state.st32, ctx->buffer);
+ for ( ; i + SHA256_BLOCK_LENGTH - 1 < len; i += SHA256_BLOCK_LENGTH)
+ SHA256Transform(ctx->state.st32, (uint8_t *)&data[i]);
+ j = 0;
+ }
+ memcpy(&ctx->buffer[j], &data[i], len - i);
+}
+
+void
+SHA256Pad(SHA2_CTX *ctx)
+{
+ uint8_t finalcount[8];
+
+ /* Store unpadded message length in bits in big endian format. */
+ BE64TO8(finalcount, ctx->count[0]);
+
+ /* Append a '1' bit (0x80) to the message. */
+ SHA256Update(ctx, (uint8_t *)"\200", 1);
+
+ /* Pad message such that the resulting length modulo 512 is 448. */
+ while ((ctx->count[0] & 504) != 448)
+ SHA256Update(ctx, (uint8_t *)"\0", 1);
+
+ /* Append length of message in bits and do final SHA256Transform(). */
+ SHA256Update(ctx, finalcount, sizeof(finalcount));
+}
+
+void
+SHA256Final(uint8_t digest[SHA256_DIGEST_LENGTH], SHA2_CTX *ctx)
+{
+ SHA256Pad(ctx);
+ if (digest != NULL) {
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy(digest, ctx->state.st32, SHA256_DIGEST_LENGTH);
+#else
+ unsigned int i;
+
+ for (i = 0; i < 8; i++)
+ BE32TO8(digest + (i * 4), ctx->state.st32[i]);
+#endif
+ memset(ctx, 0, sizeof(*ctx));
+ }
+}
+
+void
+SHA384Init(SHA2_CTX *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->state.st64[0] = 0xcbbb9d5dc1059ed8ULL;
+ ctx->state.st64[1] = 0x629a292a367cd507ULL;
+ ctx->state.st64[2] = 0x9159015a3070dd17ULL;
+ ctx->state.st64[3] = 0x152fecd8f70e5939ULL;
+ ctx->state.st64[4] = 0x67332667ffc00b31ULL;
+ ctx->state.st64[5] = 0x8eb44a8768581511ULL;
+ ctx->state.st64[6] = 0xdb0c2e0d64f98fa7ULL;
+ ctx->state.st64[7] = 0x47b5481dbefa4fa4ULL;
+}
+
+void
+SHA384Transform(uint64_t state[8], const uint8_t data[SHA384_BLOCK_LENGTH])
+{
+ SHA512Transform(state, data);
+}
+
+void
+SHA384Update(SHA2_CTX *ctx, const uint8_t *data, size_t len)
+{
+ SHA512Update(ctx, data, len);
+}
+
+void
+SHA384Pad(SHA2_CTX *ctx)
+{
+ SHA512Pad(ctx);
+}
+
+void
+SHA384Final(uint8_t digest[SHA384_DIGEST_LENGTH], SHA2_CTX *ctx)
+{
+ SHA384Pad(ctx);
+ if (digest != NULL) {
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy(digest, ctx->state.st64, SHA384_DIGEST_LENGTH);
+#else
+ unsigned int i;
+
+ for (i = 0; i < 6; i++)
+ BE64TO8(digest + (i * 8), ctx->state.st64[i]);
+#endif
+ memset(ctx, 0, sizeof(*ctx));
+ }
+}
+
+static const uint64_t SHA512_K[80] = {
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+ 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+ 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+ 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+ 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+ 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+ 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+ 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+ 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+ 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+ 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+ 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+ 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+ 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+ 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+ 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+ 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+ 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+ 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+ 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+ 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+ 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+ 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+ 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+ 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+ 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+ 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+void
+SHA512Init(SHA2_CTX *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->state.st64[0] = 0x6a09e667f3bcc908ULL;
+ ctx->state.st64[1] = 0xbb67ae8584caa73bULL;
+ ctx->state.st64[2] = 0x3c6ef372fe94f82bULL;
+ ctx->state.st64[3] = 0xa54ff53a5f1d36f1ULL;
+ ctx->state.st64[4] = 0x510e527fade682d1ULL;
+ ctx->state.st64[5] = 0x9b05688c2b3e6c1fULL;
+ ctx->state.st64[6] = 0x1f83d9abfb41bd6bULL;
+ ctx->state.st64[7] = 0x5be0cd19137e2179ULL;
+}
+
+/* Round macros for SHA512 */
+#define R(i) do { \
+ h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i)); \
+ d(i)+=h(i); \
+ h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)); \
+} while (0)
+
+#define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39))
+#define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41))
+#define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7))
+#define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6))
+
+void
+SHA512Transform(uint64_t state[8], const uint8_t data[SHA512_BLOCK_LENGTH])
+{
+ uint64_t W[16];
+ uint64_t T[8];
+ unsigned int j;
+
+ /* Copy context state to working vars. */
+ memcpy(T, state, sizeof(T));
+ /* Copy data to W in big endian format. */
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy(W, data, sizeof(W));
+#else
+ for (j = 0; j < 16; j++) {
+ BE8TO64(W[j], data);
+ data += 8;
+ }
+#endif
+ /* 80 operations, partially loop unrolled. */
+ for (j = 0; j < 80; j += 16)
+ {
+ R( 0); R( 1); R( 2); R( 3);
+ R( 4); R( 5); R( 6); R( 7);
+ R( 8); R( 9); R(10); R(11);
+ R(12); R(13); R(14); R(15);
+ }
+ /* Add the working vars back into context state. */
+ state[0] += a(0);
+ state[1] += b(0);
+ state[2] += c(0);
+ state[3] += d(0);
+ state[4] += e(0);
+ state[5] += f(0);
+ state[6] += g(0);
+ state[7] += h(0);
+ /* Cleanup. */
+ memset_s(T, sizeof(T), 0, sizeof(T));
+ memset_s(W, sizeof(W), 0, sizeof(W));
+}
+
+void
+SHA512Update(SHA2_CTX *ctx, const uint8_t *data, size_t len)
+{
+ size_t i = 0, j;
+
+ j = (size_t)((ctx->count[0] >> 3) & (SHA512_BLOCK_LENGTH - 1));
+ ctx->count[0] += ((uint64_t)len << 3);
+ if (ctx->count[0] < ((uint64_t)len << 3))
+ ctx->count[1]++;
+ if ((j + len) > SHA512_BLOCK_LENGTH - 1) {
+ memcpy(&ctx->buffer[j], data, (i = SHA512_BLOCK_LENGTH - j));
+ SHA512Transform(ctx->state.st64, ctx->buffer);
+ for ( ; i + SHA512_BLOCK_LENGTH - 1 < len; i += SHA512_BLOCK_LENGTH)
+ SHA512Transform(ctx->state.st64, (uint8_t *)&data[i]);
+ j = 0;
+ }
+ memcpy(&ctx->buffer[j], &data[i], len - i);
+}
+
+void
+SHA512Pad(SHA2_CTX *ctx)
+{
+ uint8_t finalcount[16];
+
+ /* Store unpadded message length in bits in big endian format. */
+ BE64TO8(finalcount, ctx->count[1]);
+ BE64TO8(finalcount + 8, ctx->count[0]);
+
+ /* Append a '1' bit (0x80) to the message. */
+ SHA512Update(ctx, (uint8_t *)"\200", 1);
+
+ /* Pad message such that the resulting length modulo 1024 is 896. */
+ while ((ctx->count[0] & 1008) != 896)
+ SHA512Update(ctx, (uint8_t *)"\0", 1);
+
+ /* Append length of message in bits and do final SHA512Transform(). */
+ SHA512Update(ctx, finalcount, sizeof(finalcount));
+}
+
+void
+SHA512Final(uint8_t digest[SHA512_DIGEST_LENGTH], SHA2_CTX *ctx)
+{
+ SHA512Pad(ctx);
+ if (digest != NULL) {
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy(digest, ctx->state.st64, SHA512_DIGEST_LENGTH);
+#else
+ unsigned int i;
+
+ for (i = 0; i < 8; i++)
+ BE64TO8(digest + (i * 8), ctx->state.st64[i]);
+#endif
+ memset(ctx, 0, sizeof(*ctx));
+ }
+}
diff --git a/lib/util/sig2str.c b/lib/util/sig2str.c
new file mode 100644
index 0000000..a6d4c1a
--- /dev/null
+++ b/lib/util/sig2str.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012-2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_SIG2STR
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <signal.h>
+#include <unistd.h>
+
+#include "sudo_compat.h"
+
+#if defined(HAVE_DECL_SYS_SIGNAME) && HAVE_DECL_SYS_SIGNAME == 1
+# define sudo_sys_signame sys_signame
+#elif defined(HAVE_DECL__SYS_SIGNAME) && HAVE_DECL__SYS_SIGNAME == 1
+# define sudo_sys_signame _sys_signame
+#elif defined(HAVE_DECL_SYS_SIGABBREV) && HAVE_DECL_SYS_SIGABBREV == 1
+# define sudo_sys_signame sys_sigabbrev
+#else
+# ifdef HAVE_SYS_SIGABBREV
+ /* sys_sigabbrev is not declared by glibc */
+# define sudo_sys_signame sys_sigabbrev
+# endif
+extern const char *const sudo_sys_signame[NSIG];
+#endif
+
+/*
+ * Translate signal number to name.
+ */
+int
+sudo_sig2str(int signo, char *signame)
+{
+#if defined(SIGRTMIN) && defined(SIGRTMAX)
+ /* Realtime signal support as per Solaris. */
+ if (signo >= SIGRTMIN && signo <= SIGRTMAX) {
+ snprintf(signame, SIG2STR_MAX, "RTMIN+%d", (signo - SIGRTMIN));
+ return 0;
+ }
+#endif
+ if (signo > 0 && signo < NSIG && sudo_sys_signame[signo] != NULL) {
+ strlcpy(signame, sudo_sys_signame[signo], SIG2STR_MAX);
+ return 0;
+ }
+ errno = EINVAL;
+ return -1;
+}
+#endif /* HAVE_SIG2STR */
diff --git a/lib/util/siglist.in b/lib/util/siglist.in
new file mode 100644
index 0000000..f149eb5
--- /dev/null
+++ b/lib/util/siglist.in
@@ -0,0 +1,56 @@
+#
+# List of signals used to build sys_siglist (see mksiglist.c)
+# Adapted from pdksh; public domain
+#
+# Note that if a system has multiple defines for the same signal
+# (eg, SIGABRT vs SIGIOT, SIGCHLD vs SIGCLD), only the first one
+# will be seen, so the order in this list is important.
+#
+ HUP Hangup
+ INT Interrupt
+ QUIT Quit
+ ILL Illegal instruction
+ TRAP Trace trap
+# before IOT (ABRT is posix and ABRT is sometimes the same as IOT)
+ ABRT Abort
+ IOT IOT instruction
+ EMT EMT trap
+ FPE Floating point exception
+ KILL Killed
+# before BUS (Older Linux doesn't really have a BUS, but defines it to UNUSED)
+ UNUSED Unused
+ BUS Bus error
+ SEGV Memory fault
+ SYS Bad system call
+ PIPE Broken pipe
+ ALRM Alarm clock
+ TERM Terminated
+ STKFLT Stack fault
+# before POLL (POLL is sometimes the same as IO)
+ IO I/O possible
+ XCPU CPU time limit exceeded
+ XFSZ File size limit exceeded
+ VTALRM Virtual timer expired
+ PROF Profiling timer expired
+ WINCH Window size change
+ LOST File lock lost
+ USR1 User defined signal 1
+ USR2 User defined signal 2
+ PWR Power-fail/Restart
+ POLL Pollable event occurred
+ STOP Stopped (signal)
+ TSTP Stopped
+ CONT Continued
+# before CLD (CHLD is posix and CHLD is sometimes the same as CLD)
+ CHLD Child exited
+ CLD Child exited
+ TTIN Stopped (tty input)
+ TTOU Stopped (tty output)
+ INFO Information request
+ URG Urgent I/O condition
+# Solaris (svr4?) signals
+ WAITING No runnable LWPs
+ LWP Inter-LWP signal
+ FREEZE Checkpoint freeze
+ THAW Checkpoint thaw
+ CANCEL Thread cancellation
diff --git a/lib/util/snprintf.c b/lib/util/snprintf.c
new file mode 100644
index 0000000..4b779d1
--- /dev/null
+++ b/lib/util/snprintf.c
@@ -0,0 +1,1592 @@
+/* $OpenBSD: vfprintf.c,v 1.67 2014/12/21 00:23:30 daniel Exp $ */
+/*-
+ * Copyright (c) 1999-2005, 2008, 2010-2016
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * From: @(#)vfprintf.c 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * v?snprintf/v?asprintf based on OpenBSD vfprintf.c.
+ */
+
+#include <config.h>
+
+#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_SNPRINTF) || \
+ !defined(HAVE_VASPRINTF) || !defined(HAVE_ASPRINTF) || \
+ defined(PREFER_PORTABLE_SNPRINTF)
+
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <errno.h>
+#ifdef HAVE_NL_LANGINFO
+# include <langinfo.h>
+#endif
+#include <limits.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stddef.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#ifdef PRINTF_WIDE_CHAR
+# include <wchar.h>
+#endif
+#include <fcntl.h>
+
+#include "sudo_compat.h"
+
+/* Avoid printf format attacks by ignoring the %n escape. */
+#define NO_PRINTF_PERCENT_N
+
+union arg {
+ int intarg;
+ unsigned int uintarg;
+ long longarg;
+ unsigned long ulongarg;
+ long long longlongarg;
+ unsigned long long ulonglongarg;
+ ptrdiff_t ptrdiffarg;
+ size_t sizearg;
+ ssize_t ssizearg;
+ intmax_t intmaxarg;
+ uintmax_t uintmaxarg;
+ void *pvoidarg;
+ char *pchararg;
+ signed char *pschararg;
+ short *pshortarg;
+ int *pintarg;
+ long *plongarg;
+ long long *plonglongarg;
+ ptrdiff_t *pptrdiffarg;
+ ssize_t *pssizearg;
+ intmax_t *pintmaxarg;
+#ifdef FLOATING_POINT
+ double doublearg;
+ long double longdoublearg;
+#endif
+#ifdef PRINTF_WIDE_CHAR
+ wint_t wintarg;
+ wchar_t *pwchararg;
+#endif
+};
+
+static int __find_arguments(const char *fmt0, va_list ap, union arg **argtable,
+ size_t *argtablesiz);
+static int __grow_type_table(unsigned char **typetable, int *tablesize);
+static int xxxprintf(char **, size_t, int, const char *, va_list);
+
+#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+
+/*
+ * Allocate "size" bytes via mmap.
+ */
+static void *
+mmap_alloc(size_t size)
+{
+ void *p;
+#ifndef MAP_ANON
+ int fd;
+
+ if ((fd = open("/dev/zero", O_RDWR)) == -1)
+ return NULL;
+ p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ close(fd);
+#else
+ p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
+#endif
+ if (p == MAP_FAILED)
+ return NULL;
+ return p;
+}
+
+/*
+ * Unmap "size" bytes of the ptr.
+ */
+static void
+mmap_free(void *ptr, size_t size)
+{
+ if (ptr != NULL)
+ munmap(ptr, size);
+}
+
+#ifdef PRINTF_WIDE_CHAR
+/*
+ * Convert a wide character string argument for the %ls format to a multibyte
+ * string representation. If not -1, prec specifies the maximum number of
+ * bytes to output, and also means that we can't assume that the wide char
+ * string is null-terminated.
+ */
+static char *
+__wcsconv(wchar_t *wcsarg, int prec)
+{
+ mbstate_t mbs;
+ char buf[MB_LEN_MAX];
+ wchar_t *p;
+ char *convbuf;
+ size_t clen, nbytes;
+
+ /* Allocate space for the maximum number of bytes we could output. */
+ if (prec < 0) {
+ memset(&mbs, 0, sizeof(mbs));
+ p = wcsarg;
+ nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs);
+ if (nbytes == (size_t)-1) {
+ errno = EILSEQ;
+ return NULL;
+ }
+ } else {
+ /*
+ * Optimisation: if the output precision is small enough,
+ * just allocate enough memory for the maximum instead of
+ * scanning the string.
+ */
+ if (prec < 128)
+ nbytes = prec;
+ else {
+ nbytes = 0;
+ p = wcsarg;
+ memset(&mbs, 0, sizeof(mbs));
+ for (;;) {
+ clen = wcrtomb(buf, *p++, &mbs);
+ if (clen == 0 || clen == (size_t)-1 ||
+ nbytes + clen > (size_t)prec)
+ break;
+ nbytes += clen;
+ }
+ if (clen == (size_t)-1) {
+ errno = EILSEQ;
+ return NULL;
+ }
+ }
+ }
+ if ((convbuf = malloc(nbytes + 1)) == NULL)
+ return NULL;
+
+ /* Fill the output buffer. */
+ p = wcsarg;
+ memset(&mbs, 0, sizeof(mbs));
+ if ((nbytes = wcsrtombs(convbuf, (const wchar_t **)&p,
+ nbytes, &mbs)) == (size_t)-1) {
+ free(convbuf);
+ errno = EILSEQ;
+ return NULL;
+ }
+ convbuf[nbytes] = '\0';
+ return convbuf;
+}
+#endif
+
+#ifdef FLOATING_POINT
+#include <float.h>
+#include <locale.h>
+#include <math.h>
+#include "floatio.h"
+#include "gdtoa.h"
+
+#define DEFPREC 6
+
+static int exponent(char *, int, int);
+#endif /* FLOATING_POINT */
+
+/*
+ * The size of the buffer we use as scratch space for integer
+ * conversions, among other things. Technically, we would need the
+ * most space for base 10 conversions with thousands' grouping
+ * characters between each pair of digits. 100 bytes is a
+ * conservative overestimate even for a 128-bit uintmax_t.
+ */
+#define BUF 100
+
+#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
+
+
+/*
+ * Macros for converting digits to letters and vice versa
+ */
+#define to_digit(c) ((c) - '0')
+#define is_digit(c) ((unsigned int)to_digit(c) <= 9)
+#define to_char(n) ((n) + '0')
+
+/*
+ * Flags used during conversion.
+ */
+#define ALT 0x0001 /* alternate form */
+#define LADJUST 0x0004 /* left adjustment */
+#define LONGDBL 0x0008 /* long double */
+#define LONGINT 0x0010 /* long integer */
+#define LLONGINT 0x0020 /* long long integer */
+#define SHORTINT 0x0040 /* short integer */
+#define ZEROPAD 0x0080 /* zero (as opposed to blank) pad */
+#define FPT 0x0100 /* Floating point number */
+#define PTRINT 0x0200 /* (unsigned) ptrdiff_t */
+#define SIZEINT 0x0400 /* (signed) size_t */
+#define CHARINT 0x0800 /* 8 bit integer */
+#undef MAXINT /* Also defined by HP-UX param.h... */
+#define MAXINT 0x1000 /* largest integer size (intmax_t) */
+
+/*
+ * Actual printf innards.
+ */
+static int
+xxxprintf(char **strp, size_t strsize, int alloc, const char *fmt0, va_list ap)
+{
+ char *fmt; /* format string */
+ int ch; /* character from fmt */
+ int n, n2; /* handy integers (short term usage) */
+ char *cp; /* handy char pointer (short term usage) */
+ int flags; /* flags as above */
+ int ret; /* return value accumulator */
+ int width; /* width from format (%8d), or 0 */
+ int prec; /* precision from format; <0 for N/A */
+ char sign; /* sign prefix (' ', '+', '-', or \0) */
+#ifdef FLOATING_POINT
+ /*
+ * We can decompose the printed representation of floating
+ * point numbers into several parts, some of which may be empty:
+ *
+ * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
+ * A B ---C--- D E F
+ *
+ * A: 'sign' holds this value if present; '\0' otherwise
+ * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
+ * C: cp points to the string MMMNNN. Leading and trailing
+ * zeros are not in the string and must be added.
+ * D: expchar holds this character; '\0' if no exponent, e.g. %f
+ * F: at least two digits for decimal, at least one digit for hex
+ */
+#ifdef HAVE_NL_LANGINFO
+ const char *decimal_point = NULL;
+#else
+ const char *decimal_point = ".";
+#endif
+ int signflag; /* true if float is negative */
+ union { /* floating point arguments %[aAeEfFgG] */
+ double dbl;
+ long double ldbl;
+ } fparg;
+ int expt; /* integer value of exponent */
+ char expchar; /* exponent character: [eEpP\0] */
+ char *dtoaend; /* pointer to end of converted digits */
+ int expsize; /* character count for expstr */
+ int lead; /* sig figs before decimal or group sep */
+ int ndig; /* actual number of digits returned by dtoa */
+ char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
+ char *dtoaresult = NULL;
+#endif
+
+ uintmax_t _umax; /* integer arguments %[diouxX] */
+ enum { OCT, DEC, HEX } base; /* base for %[diouxX] conversion */
+ int dprec; /* a copy of prec if %[diouxX], 0 otherwise */
+ int realsz; /* field size expanded by dprec */
+ int size; /* size of converted field or string */
+ const char *xdigs = ""; /* digits for %[xX] conversion */
+#define NIOV 8
+ char buf[BUF]; /* buffer with space for digits of uintmax_t */
+ char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */
+ char *str; /* pointer to string to fill */
+ char *estr; /* pointer to last char in str */
+ union arg *argtable; /* args, built due to positional arg */
+ union arg statargtable[STATIC_ARG_TBL_SIZE];
+ size_t argtablesiz;
+ int nextarg; /* 1-based argument index */
+ va_list orgap; /* original argument pointer */
+#ifdef PRINTF_WIDE_CHAR
+ char *convbuf; /* buffer for wide to multi-byte conversion */
+#endif
+
+ /*
+ * Choose PADSIZE to trade efficiency vs. size. If larger printf
+ * fields occur frequently, increase PADSIZE and make the initialisers
+ * below longer.
+ */
+#define PADSIZE 16 /* pad chunk size */
+ static char blanks[PADSIZE] =
+ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
+ static char zeroes[PADSIZE] =
+ {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
+
+ static const char xdigs_lower[16] = "0123456789abcdef";
+ static const char xdigs_upper[16] = "0123456789ABCDEF";
+
+ /* Print chars to "str", (allocate as needed if alloc is set). */
+#define PRINT(ptr, len) do { \
+ const char *p = ptr; \
+ const char *endp = ptr + len; \
+ while (p < endp && (str < estr || alloc)) { \
+ if (alloc && str >= estr) { \
+ char *t; \
+ strsize = (strsize << 1) + 1; \
+ if (!(t = realloc(*strp, strsize))) { \
+ free(str); \
+ *strp = NULL; \
+ ret = -1; \
+ goto done; \
+ } \
+ str = t + (str - *strp); \
+ estr = t + strsize - 1; \
+ *strp = t; \
+ } \
+ *str++ = *p++; \
+ } \
+} while (0)
+
+ /* BEWARE, PAD uses `n' and PRINTANDPAD uses `n2'. */
+#define PAD(plen, pstr) do { \
+ if ((n = (plen)) > 0) { \
+ while (n > PADSIZE) { \
+ PRINT(pstr, PADSIZE); \
+ n -= PADSIZE; \
+ } \
+ PRINT(pstr, n); \
+ } \
+} while (0)
+#define PRINTANDPAD(p, ep, len, with) do { \
+ n2 = (ep) - (p); \
+ if (n2 > (len)) \
+ n2 = (len); \
+ if (n2 > 0) \
+ PRINT((p), n2); \
+ PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
+} while(0)
+
+ /*
+ * To extend shorts properly, we need both signed and unsigned
+ * argument extraction methods.
+ */
+#define SARG() \
+ ((intmax_t)(flags&MAXINT ? GETARG(intmax_t) : \
+ flags&LLONGINT ? GETARG(long long) : \
+ flags&LONGINT ? GETARG(long) : \
+ flags&PTRINT ? GETARG(ptrdiff_t) : \
+ flags&SIZEINT ? GETARG(ssize_t) : \
+ flags&SHORTINT ? (short)GETARG(int) : \
+ flags&CHARINT ? (signed char)GETARG(int) : \
+ GETARG(int)))
+#define UARG() \
+ ((uintmax_t)(flags&MAXINT ? GETARG(uintmax_t) : \
+ flags&LLONGINT ? GETARG(unsigned long long) : \
+ flags&LONGINT ? GETARG(unsigned long) : \
+ flags&PTRINT ? (uintptr_t)GETARG(ptrdiff_t) : /* XXX */ \
+ flags&SIZEINT ? GETARG(size_t) : \
+ flags&SHORTINT ? (unsigned short)GETARG(int) : \
+ flags&CHARINT ? (unsigned char)GETARG(int) : \
+ GETARG(unsigned int)))
+
+ /*
+ * Append a digit to a value and check for overflow.
+ */
+#define APPEND_DIGIT(val, dig) do { \
+ if ((val) > INT_MAX / 10) \
+ goto overflow; \
+ (val) *= 10; \
+ if ((val) > INT_MAX - to_digit((dig))) \
+ goto overflow; \
+ (val) += to_digit((dig)); \
+} while (0)
+
+ /*
+ * Get * arguments, including the form *nn$. Preserve the nextarg
+ * that the argument can be gotten once the type is determined.
+ */
+#define GETASTER(val) \
+ n2 = 0; \
+ cp = fmt; \
+ while (is_digit(*cp)) { \
+ APPEND_DIGIT(n2, *cp); \
+ cp++; \
+ } \
+ if (*cp == '$') { \
+ int hold = nextarg; \
+ if (argtable == NULL) { \
+ argtable = statargtable; \
+ __find_arguments(fmt0, orgap, &argtable, &argtablesiz); \
+ } \
+ nextarg = n2; \
+ val = GETARG(int); \
+ nextarg = hold; \
+ fmt = ++cp; \
+ } else { \
+ val = GETARG(int); \
+ }
+
+/*
+* Get the argument indexed by nextarg. If the argument table is
+* built, use it to get the argument. If its not, get the next
+* argument (and arguments must be gotten sequentially).
+*/
+#define GETARG(type) \
+ ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
+ (nextarg++, va_arg(ap, type)))
+
+ fmt = (char *)fmt0;
+ argtable = NULL;
+ nextarg = 1;
+ va_copy(orgap, ap);
+ ret = 0;
+#ifdef PRINTF_WIDE_CHAR
+ convbuf = NULL;
+#endif
+
+ if (alloc) {
+ strsize = 128;
+ *strp = str = malloc(strsize);
+ if (str == NULL) {
+ ret = -1;
+ goto done;
+ }
+ estr = str + 127;
+ } else {
+ str = *strp;
+ if (strsize)
+ estr = str + strsize - 1;
+ else
+ estr = NULL;
+ }
+
+ /*
+ * Scan the format for conversions (`%' character).
+ */
+ for (;;) {
+ for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
+ /* void */;
+ if ((n = fmt - cp) != 0) {
+ if (n > INT_MAX - ret)
+ goto overflow;
+ PRINT(cp, n);
+ ret += n;
+ }
+ if (ch == '\0')
+ goto done;
+ fmt++; /* skip over '%' */
+
+ flags = 0;
+ dprec = 0;
+ width = 0;
+ prec = -1;
+ sign = '\0';
+ ox[1] = '\0';
+
+rflag: ch = *fmt++;
+reswitch: switch (ch) {
+ case ' ':
+ /*
+ * ``If the space and + flags both appear, the space
+ * flag will be ignored.''
+ * -- ANSI X3J11
+ */
+ if (!sign)
+ sign = ' ';
+ goto rflag;
+ case '#':
+ flags |= ALT;
+ goto rflag;
+ case '\'':
+ /* grouping not implemented */
+ goto rflag;
+ case '*':
+ /*
+ * ``A negative field width argument is taken as a
+ * - flag followed by a positive field width.''
+ * -- ANSI X3J11
+ * They don't exclude field widths read from args.
+ */
+ GETASTER(width);
+ if (width >= 0)
+ goto rflag;
+ if (width == INT_MIN)
+ goto overflow;
+ width = -width;
+ /* FALLTHROUGH */
+ case '-':
+ flags |= LADJUST;
+ goto rflag;
+ case '+':
+ sign = '+';
+ goto rflag;
+ case '.':
+ if ((ch = *fmt++) == '*') {
+ GETASTER(n);
+ prec = n < 0 ? -1 : n;
+ goto rflag;
+ }
+ n = 0;
+ while (is_digit(ch)) {
+ APPEND_DIGIT(n, ch);
+ ch = *fmt++;
+ }
+ if (ch == '$') {
+ nextarg = n;
+ if (argtable == NULL) {
+ argtable = statargtable;
+ __find_arguments(fmt0, orgap,
+ &argtable, &argtablesiz);
+ }
+ goto rflag;
+ }
+ prec = n;
+ goto reswitch;
+ case '0':
+ /*
+ * ``Note that 0 is taken as a flag, not as the
+ * beginning of a field width.''
+ * -- ANSI X3J11
+ */
+ flags |= ZEROPAD;
+ goto rflag;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n = 0;
+ do {
+ APPEND_DIGIT(n, ch);
+ ch = *fmt++;
+ } while (is_digit(ch));
+ if (ch == '$') {
+ nextarg = n;
+ if (argtable == NULL) {
+ argtable = statargtable;
+ __find_arguments(fmt0, orgap,
+ &argtable, &argtablesiz);
+ }
+ goto rflag;
+ }
+ width = n;
+ goto reswitch;
+#ifdef FLOATING_POINT
+ case 'L':
+ flags |= LONGDBL;
+ goto rflag;
+#endif
+ case 'h':
+ if (*fmt == 'h') {
+ fmt++;
+ flags |= CHARINT;
+ } else {
+ flags |= SHORTINT;
+ }
+ goto rflag;
+ case 'j':
+ flags |= MAXINT;
+ goto rflag;
+ case 'l':
+ if (*fmt == 'l') {
+ fmt++;
+ flags |= LLONGINT;
+ } else {
+ flags |= LONGINT;
+ }
+ goto rflag;
+ case 'q':
+ flags |= LLONGINT;
+ goto rflag;
+ case 't':
+ flags |= PTRINT;
+ goto rflag;
+ case 'z':
+ flags |= SIZEINT;
+ goto rflag;
+ case 'c':
+#ifdef PRINTF_WIDE_CHAR
+ if (flags & LONGINT) {
+ mbstate_t mbs;
+ size_t mbseqlen;
+
+ memset(&mbs, 0, sizeof(mbs));
+ mbseqlen = wcrtomb(buf,
+ (wchar_t)GETARG(wint_t), &mbs);
+ if (mbseqlen == (size_t)-1) {
+ errno = EILSEQ;
+ goto done;
+ }
+ cp = buf;
+ size = (int)mbseqlen;
+ } else {
+#endif
+ *(cp = buf) = GETARG(int);
+ size = 1;
+#ifdef PRINTF_WIDE_CHAR
+ }
+#endif
+ sign = '\0';
+ break;
+ case 'D':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'd':
+ case 'i':
+ _umax = SARG();
+ if ((intmax_t)_umax < 0) {
+ _umax = -_umax;
+ sign = '-';
+ }
+ base = DEC;
+ goto number;
+#ifdef FLOATING_POINT
+ case 'a':
+ case 'A':
+ if (ch == 'a') {
+ ox[1] = 'x';
+ xdigs = xdigs_lower;
+ expchar = 'p';
+ } else {
+ ox[1] = 'X';
+ xdigs = xdigs_upper;
+ expchar = 'P';
+ }
+ if (prec >= 0)
+ prec++;
+ if (dtoaresult)
+ __freedtoa(dtoaresult);
+ if (flags & LONGDBL) {
+ fparg.ldbl = GETARG(long double);
+ dtoaresult = cp =
+ __hldtoa(fparg.ldbl, xdigs, prec,
+ &expt, &signflag, &dtoaend);
+ if (dtoaresult == NULL) {
+ errno = ENOMEM;
+ goto done;
+ }
+ } else {
+ fparg.dbl = GETARG(double);
+ dtoaresult = cp =
+ __hdtoa(fparg.dbl, xdigs, prec,
+ &expt, &signflag, &dtoaend);
+ if (dtoaresult == NULL) {
+ errno = ENOMEM;
+ goto done;
+ }
+ }
+ if (prec < 0)
+ prec = dtoaend - cp;
+ if (expt == INT_MAX)
+ ox[1] = '\0';
+ goto fp_common;
+ case 'e':
+ case 'E':
+ expchar = ch;
+ if (prec < 0) /* account for digit before decpt */
+ prec = DEFPREC + 1;
+ else
+ prec++;
+ goto fp_begin;
+ case 'f':
+ case 'F':
+ expchar = '\0';
+ goto fp_begin;
+ case 'g':
+ case 'G':
+ expchar = ch - ('g' - 'e');
+ if (prec == 0)
+ prec = 1;
+fp_begin:
+ if (prec < 0)
+ prec = DEFPREC;
+ if (dtoaresult)
+ __freedtoa(dtoaresult);
+ if (flags & LONGDBL) {
+ fparg.ldbl = GETARG(long double);
+ dtoaresult = cp =
+ __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
+ &expt, &signflag, &dtoaend);
+ if (dtoaresult == NULL) {
+ errno = ENOMEM;
+ goto done;
+ }
+ } else {
+ fparg.dbl = GETARG(double);
+ dtoaresult = cp =
+ __dtoa(fparg.dbl, expchar ? 2 : 3, prec,
+ &expt, &signflag, &dtoaend);
+ if (dtoaresult == NULL) {
+ errno = ENOMEM;
+ goto done;
+ }
+ if (expt == 9999)
+ expt = INT_MAX;
+ }
+fp_common:
+ if (signflag)
+ sign = '-';
+ if (expt == INT_MAX) { /* inf or nan */
+ if (*cp == 'N')
+ cp = (ch >= 'a') ? "nan" : "NAN";
+ else
+ cp = (ch >= 'a') ? "inf" : "INF";
+ size = 3;
+ flags &= ~ZEROPAD;
+ break;
+ }
+ flags |= FPT;
+ ndig = dtoaend - cp;
+ if (ch == 'g' || ch == 'G') {
+ if (expt > -4 && expt <= prec) {
+ /* Make %[gG] smell like %[fF] */
+ expchar = '\0';
+ if (flags & ALT)
+ prec -= expt;
+ else
+ prec = ndig - expt;
+ if (prec < 0)
+ prec = 0;
+ } else {
+ /*
+ * Make %[gG] smell like %[eE], but
+ * trim trailing zeroes if no # flag.
+ */
+ if (!(flags & ALT))
+ prec = ndig;
+ }
+ }
+ if (expchar) {
+ expsize = exponent(expstr, expt - 1, expchar);
+ size = expsize + prec;
+ if (prec > 1 || flags & ALT)
+ ++size;
+ } else {
+ /* space for digits before decimal point */
+ if (expt > 0)
+ size = expt;
+ else /* "0" */
+ size = 1;
+ /* space for decimal pt and following digits */
+ if (prec || flags & ALT)
+ size += prec + 1;
+ lead = expt;
+ }
+ break;
+#endif /* FLOATING_POINT */
+#ifndef NO_PRINTF_PERCENT_N
+ case 'n':
+ if (flags & LLONGINT)
+ *GETARG(long long *) = ret;
+ else if (flags & LONGINT)
+ *GETARG(long *) = ret;
+ else if (flags & SHORTINT)
+ *GETARG(short *) = ret;
+ else if (flags & CHARINT)
+ *GETARG(signed char *) = ret;
+ else if (flags & PTRINT)
+ *GETARG(ptrdiff_t *) = ret;
+ else if (flags & SIZEINT)
+ *GETARG(ssize_t *) = ret;
+ else if (flags & MAXINT)
+ *GETARG(intmax_t *) = ret;
+ else
+ *GETARG(int *) = ret;
+ continue; /* no output */
+#endif /* NO_PRINTF_PERCENT_N */
+ case 'O':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'o':
+ _umax = UARG();
+ base = OCT;
+ goto nosign;
+ case 'p':
+ /*
+ * ``The argument shall be a pointer to void. The
+ * value of the pointer is converted to a sequence
+ * of printable characters, in an implementation-
+ * defined manner.''
+ * -- ANSI X3J11
+ */
+ /* NOSTRICT */
+ _umax = (u_long)GETARG(void *);
+ base = HEX;
+ xdigs = xdigs_lower;
+ ox[1] = 'x';
+ goto nosign;
+ case 's':
+#ifdef PRINTF_WIDE_CHAR
+ if (flags & LONGINT) {
+ wchar_t *wcp;
+
+ if (convbuf != NULL) {
+ free(convbuf);
+ convbuf = NULL;
+ }
+ if ((wcp = GETARG(wchar_t *)) == NULL) {
+ cp = "(null)";
+ } else {
+ convbuf = __wcsconv(wcp, prec);
+ if (convbuf == NULL)
+ goto done;
+ cp = convbuf;
+ }
+ } else
+#endif /* PRINTF_WIDE_CHAR */
+ if ((cp = GETARG(char *)) == NULL)
+ cp = "(null)";
+ if (prec >= 0) {
+ /*
+ * can't use strlen; can only look for the
+ * NUL in the first `prec' characters, and
+ * strlen() will go further.
+ */
+ char *p = memchr(cp, 0, prec);
+
+ size = p ? (p - cp) : prec;
+ } else {
+ size_t len;
+
+ if ((len = strlen(cp)) > INT_MAX)
+ goto overflow;
+ size = (int)len;
+ }
+ sign = '\0';
+ break;
+ case 'U':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'u':
+ _umax = UARG();
+ base = DEC;
+ goto nosign;
+ case 'X':
+ xdigs = xdigs_upper;
+ goto hex;
+ case 'x':
+ xdigs = xdigs_lower;
+hex: _umax = UARG();
+ base = HEX;
+ /* leading 0x/X only if non-zero */
+ if (flags & ALT && _umax != 0)
+ ox[1] = ch;
+
+ /* unsigned conversions */
+nosign: sign = '\0';
+ /*
+ * ``... diouXx conversions ... if a precision is
+ * specified, the 0 flag will be ignored.''
+ * -- ANSI X3J11
+ */
+number: if ((dprec = prec) >= 0)
+ flags &= ~ZEROPAD;
+
+ /*
+ * ``The result of converting a zero value with an
+ * explicit precision of zero is no characters.''
+ * -- ANSI X3J11
+ */
+ cp = buf + BUF;
+ if (_umax != 0 || prec != 0) {
+ /*
+ * Unsigned mod is hard, and unsigned mod
+ * by a constant is easier than that by
+ * a variable; hence this switch.
+ */
+ switch (base) {
+ case OCT:
+ do {
+ *--cp = to_char(_umax & 7);
+ _umax >>= 3;
+ } while (_umax);
+ /* handle octal leading 0 */
+ if (flags & ALT && *cp != '0')
+ *--cp = '0';
+ break;
+
+ case DEC:
+ /* many numbers are 1 digit */
+ while (_umax >= 10) {
+ *--cp = to_char(_umax % 10);
+ _umax /= 10;
+ }
+ *--cp = to_char(_umax);
+ break;
+
+ case HEX:
+ do {
+ *--cp = xdigs[_umax & 15];
+ _umax >>= 4;
+ } while (_umax);
+ break;
+
+ default:
+ cp = "bug in vfprintf: bad base";
+ size = strlen(cp);
+ goto skipsize;
+ }
+ }
+ size = buf + BUF - cp;
+ if (size > BUF) /* should never happen */
+ abort();
+ skipsize:
+ break;
+ default: /* "%?" prints ?, unless ? is NUL */
+ if (ch == '\0')
+ goto done;
+ /* pretend it was %c with argument ch */
+ cp = buf;
+ *cp = ch;
+ size = 1;
+ sign = '\0';
+ break;
+ }
+
+ /*
+ * All reasonable formats wind up here. At this point, `cp'
+ * points to a string which (if not flags&LADJUST) should be
+ * padded out to `width' places. If flags&ZEROPAD, it should
+ * first be prefixed by any sign or other prefix; otherwise,
+ * it should be blank padded before the prefix is emitted.
+ * After any left-hand padding and prefixing, emit zeroes
+ * required by a decimal %[diouxX] precision, then print the
+ * string proper, then emit zeroes required by any leftover
+ * floating precision; finally, if LADJUST, pad with blanks.
+ *
+ * Compute actual size, so we know how much to pad.
+ * size excludes decimal prec; realsz includes it.
+ */
+ realsz = dprec > size ? dprec : size;
+ if (sign)
+ realsz++;
+ if (ox[1])
+ realsz+= 2;
+
+ /* right-adjusting blank padding */
+ if ((flags & (LADJUST|ZEROPAD)) == 0)
+ PAD(width - realsz, blanks);
+
+ /* prefix */
+ if (sign)
+ PRINT(&sign, 1);
+ if (ox[1]) { /* ox[1] is either x, X, or \0 */
+ ox[0] = '0';
+ PRINT(ox, 2);
+ }
+
+ /* right-adjusting zero padding */
+ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
+ PAD(width - realsz, zeroes);
+
+ /* leading zeroes from decimal precision */
+ PAD(dprec - size, zeroes);
+
+ /* the string or number proper */
+#ifdef FLOATING_POINT
+ if ((flags & FPT) == 0) {
+ PRINT(cp, size);
+ } else { /* glue together f_p fragments */
+#ifdef HAVE_NL_LANGINFO
+ if (decimal_point == NULL)
+ decimal_point = nl_langinfo(RADIXCHAR);
+#endif
+ if (!expchar) { /* %[fF] or sufficiently short %[gG] */
+ if (expt <= 0) {
+ PRINT(zeroes, 1);
+ if (prec || flags & ALT)
+ PRINT(decimal_point, 1);
+ PAD(-expt, zeroes);
+ /* already handled initial 0's */
+ prec += expt;
+ } else {
+ PRINTANDPAD(cp, dtoaend, lead, zeroes);
+ cp += lead;
+ if (prec || flags & ALT)
+ PRINT(decimal_point, 1);
+ }
+ PRINTANDPAD(cp, dtoaend, prec, zeroes);
+ } else { /* %[eE] or sufficiently long %[gG] */
+ if (prec > 1 || flags & ALT) {
+ buf[0] = *cp++;
+ buf[1] = *decimal_point;
+ PRINT(buf, 2);
+ PRINT(cp, ndig-1);
+ PAD(prec - ndig, zeroes);
+ } else { /* XeYYY */
+ PRINT(cp, 1);
+ }
+ PRINT(expstr, expsize);
+ }
+ }
+#else
+ PRINT(cp, size);
+#endif
+ /* left-adjusting padding (always blank) */
+ if (flags & LADJUST)
+ PAD(width - realsz, blanks);
+
+ /* finally, adjust ret */
+ if (width < realsz)
+ width = realsz;
+ if (width > INT_MAX - ret)
+ goto overflow;
+ ret += width;
+ }
+done:
+ va_end(orgap);
+ if (strsize)
+ *str = '\0';
+ goto finish;
+
+overflow:
+ errno = EOVERFLOW;
+ ret = -1;
+
+finish:
+#ifdef PRINTF_WIDE_CHAR
+ if (convbuf)
+ free(convbuf);
+#endif
+#ifdef FLOATING_POINT
+ if (dtoaresult)
+ __freedtoa(dtoaresult);
+#endif
+ if (argtable != NULL && argtable != statargtable) {
+ mmap_free(argtable, argtablesiz);
+ argtable = NULL;
+ }
+ return ret;
+}
+
+/*
+ * Type ids for argument type table.
+ */
+#define T_UNUSED 0
+#define T_SHORT 1
+#define T_U_SHORT 2
+#define TP_SHORT 3
+#define T_INT 4
+#define T_U_INT 5
+#define TP_INT 6
+#define T_LONG 7
+#define T_U_LONG 8
+#define TP_LONG 9
+#define T_LLONG 10
+#define T_U_LLONG 11
+#define TP_LLONG 12
+#define T_DOUBLE 13
+#define T_LONG_DOUBLE 14
+#define TP_CHAR 15
+#define TP_VOID 16
+#define T_PTRINT 17
+#define TP_PTRINT 18
+#define T_SIZEINT 19
+#define T_SSIZEINT 20
+#define TP_SSIZEINT 21
+#define T_MAXINT 22
+#define T_MAXUINT 23
+#define TP_MAXINT 24
+#define T_CHAR 25
+#define T_U_CHAR 26
+#define T_WINT 27
+#define TP_WCHAR 28
+
+/*
+ * Find all arguments when a positional parameter is encountered. Returns a
+ * table, indexed by argument number, of pointers to each arguments. The
+ * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
+ * It will be replaced with a mmap-ed one if it overflows (malloc cannot be
+ * used since we are attempting to make snprintf thread safe, and alloca is
+ * problematic since we have nested functions..)
+ */
+static int
+__find_arguments(const char *fmt0, va_list ap, union arg **argtable,
+ size_t *argtablesiz)
+{
+ char *fmt; /* format string */
+ int ch; /* character from fmt */
+ int n, n2; /* handy integer (short term usage) */
+ char *cp; /* handy char pointer (short term usage) */
+ int flags; /* flags as above */
+ unsigned char *typetable; /* table of types */
+ unsigned char stattypetable[STATIC_ARG_TBL_SIZE];
+ int tablesize; /* current size of type table */
+ int tablemax; /* largest used index in table */
+ int nextarg; /* 1-based argument index */
+ int ret = 0; /* return value */
+
+ /*
+ * Add an argument type to the table, expanding if necessary.
+ */
+#define ADDTYPE(type) \
+ ((nextarg >= tablesize) ? \
+ __grow_type_table(&typetable, &tablesize) : 0, \
+ (nextarg > tablemax) ? tablemax = nextarg : 0, \
+ typetable[nextarg++] = type)
+
+#define ADDSARG() \
+ ((flags&MAXINT) ? ADDTYPE(T_MAXINT) : \
+ ((flags&PTRINT) ? ADDTYPE(T_PTRINT) : \
+ ((flags&SIZEINT) ? ADDTYPE(T_SSIZEINT) : \
+ ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \
+ ((flags&LONGINT) ? ADDTYPE(T_LONG) : \
+ ((flags&SHORTINT) ? ADDTYPE(T_SHORT) : \
+ ((flags&CHARINT) ? ADDTYPE(T_CHAR) : ADDTYPE(T_INT))))))))
+
+#define ADDUARG() \
+ ((flags&MAXINT) ? ADDTYPE(T_MAXUINT) : \
+ ((flags&PTRINT) ? ADDTYPE(T_PTRINT) : \
+ ((flags&SIZEINT) ? ADDTYPE(T_SIZEINT) : \
+ ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \
+ ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : \
+ ((flags&SHORTINT) ? ADDTYPE(T_U_SHORT) : \
+ ((flags&CHARINT) ? ADDTYPE(T_U_CHAR) : ADDTYPE(T_U_INT))))))))
+
+ /*
+ * Add * arguments to the type array.
+ */
+#define ADDASTER() \
+ n2 = 0; \
+ cp = fmt; \
+ while (is_digit(*cp)) { \
+ APPEND_DIGIT(n2, *cp); \
+ cp++; \
+ } \
+ if (*cp == '$') { \
+ int hold = nextarg; \
+ nextarg = n2; \
+ ADDTYPE(T_INT); \
+ nextarg = hold; \
+ fmt = ++cp; \
+ } else { \
+ ADDTYPE(T_INT); \
+ }
+ fmt = (char *)fmt0;
+ typetable = stattypetable;
+ tablesize = STATIC_ARG_TBL_SIZE;
+ tablemax = 0;
+ nextarg = 1;
+ memset(typetable, T_UNUSED, STATIC_ARG_TBL_SIZE);
+
+ /*
+ * Scan the format for conversions (`%' character).
+ */
+ for (;;) {
+ for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
+ /* void */;
+ fmt++; /* skip over '%' */
+
+ flags = 0;
+
+rflag: ch = *fmt++;
+reswitch: switch (ch) {
+ case ' ':
+ case '#':
+ case '\'':
+ goto rflag;
+ case '*':
+ ADDASTER();
+ goto rflag;
+ case '-':
+ case '+':
+ goto rflag;
+ case '.':
+ if ((ch = *fmt++) == '*') {
+ ADDASTER();
+ goto rflag;
+ }
+ while (is_digit(ch)) {
+ ch = *fmt++;
+ }
+ goto reswitch;
+ case '0':
+ goto rflag;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n = 0;
+ do {
+ APPEND_DIGIT(n ,ch);
+ ch = *fmt++;
+ } while (is_digit(ch));
+ if (ch == '$') {
+ nextarg = n;
+ goto rflag;
+ }
+ goto reswitch;
+#ifdef FLOATING_POINT
+ case 'L':
+ flags |= LONGDBL;
+ goto rflag;
+#endif
+ case 'h':
+ if (*fmt == 'h') {
+ fmt++;
+ flags |= CHARINT;
+ } else {
+ flags |= SHORTINT;
+ }
+ goto rflag;
+ case 'j':
+ flags |= MAXINT;
+ goto rflag;
+ case 'l':
+ if (*fmt == 'l') {
+ fmt++;
+ flags |= LLONGINT;
+ } else {
+ flags |= LONGINT;
+ }
+ goto rflag;
+ case 'q':
+ flags |= LLONGINT;
+ goto rflag;
+ case 't':
+ flags |= PTRINT;
+ goto rflag;
+ case 'z':
+ flags |= SIZEINT;
+ goto rflag;
+ case 'c':
+#ifdef PRINTF_WIDE_CHAR
+ if (flags & LONGINT)
+ ADDTYPE(T_WINT);
+ else
+#endif
+ ADDTYPE(T_INT);
+ break;
+ case 'D':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'd':
+ case 'i':
+ ADDSARG();
+ break;
+#ifdef FLOATING_POINT
+ case 'a':
+ case 'A':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ if (flags & LONGDBL)
+ ADDTYPE(T_LONG_DOUBLE);
+ else
+ ADDTYPE(T_DOUBLE);
+ break;
+#endif /* FLOATING_POINT */
+#ifndef NO_PRINTF_PERCENT_N
+ case 'n':
+ if (flags & LLONGINT)
+ ADDTYPE(TP_LLONG);
+ else if (flags & LONGINT)
+ ADDTYPE(TP_LONG);
+ else if (flags & SHORTINT)
+ ADDTYPE(TP_SHORT);
+ else if (flags & PTRINT)
+ ADDTYPE(TP_PTRINT);
+ else if (flags & SIZEINT)
+ ADDTYPE(TP_SSIZEINT);
+ else if (flags & MAXINT)
+ ADDTYPE(TP_MAXINT);
+ else
+ ADDTYPE(TP_INT);
+ continue; /* no output */
+#endif /* NO_PRINTF_PERCENT_N */
+ case 'O':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'o':
+ ADDUARG();
+ break;
+ case 'p':
+ ADDTYPE(TP_VOID);
+ break;
+ case 's':
+#ifdef PRINTF_WIDE_CHAR
+ if (flags & LONGINT)
+ ADDTYPE(TP_WCHAR);
+ else
+#endif
+ ADDTYPE(TP_CHAR);
+ break;
+ case 'U':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'u':
+ case 'X':
+ case 'x':
+ ADDUARG();
+ break;
+ default: /* "%?" prints ?, unless ? is NUL */
+ if (ch == '\0')
+ goto done;
+ break;
+ }
+ }
+done:
+ /*
+ * Build the argument table.
+ */
+ if (tablemax >= STATIC_ARG_TBL_SIZE) {
+ *argtablesiz = sizeof(union arg) * (tablemax + 1);
+ *argtable = mmap_alloc(*argtablesiz);
+ if (*argtable == NULL)
+ return -1;
+ }
+
+ for (n = 1; n <= tablemax; n++) {
+ switch (typetable[n]) {
+ case T_UNUSED:
+ case T_CHAR:
+ case T_U_CHAR:
+ case T_SHORT:
+ case T_U_SHORT:
+ case T_INT:
+ (*argtable)[n].intarg = va_arg(ap, int);
+ break;
+ case TP_SHORT:
+ (*argtable)[n].pshortarg = va_arg(ap, short *);
+ break;
+ case T_U_INT:
+ (*argtable)[n].uintarg = va_arg(ap, unsigned int);
+ break;
+ case TP_INT:
+ (*argtable)[n].pintarg = va_arg(ap, int *);
+ break;
+ case T_LONG:
+ (*argtable)[n].longarg = va_arg(ap, long);
+ break;
+ case T_U_LONG:
+ (*argtable)[n].ulongarg = va_arg(ap, unsigned long);
+ break;
+ case TP_LONG:
+ (*argtable)[n].plongarg = va_arg(ap, long *);
+ break;
+ case T_LLONG:
+ (*argtable)[n].longlongarg = va_arg(ap, long long);
+ break;
+ case T_U_LLONG:
+ (*argtable)[n].ulonglongarg = va_arg(ap, unsigned long long);
+ break;
+ case TP_LLONG:
+ (*argtable)[n].plonglongarg = va_arg(ap, long long *);
+ break;
+#ifdef FLOATING_POINT
+ case T_DOUBLE:
+ (*argtable)[n].doublearg = va_arg(ap, double);
+ break;
+ case T_LONG_DOUBLE:
+ (*argtable)[n].longdoublearg = va_arg(ap, long double);
+ break;
+#endif
+ case TP_CHAR:
+ (*argtable)[n].pchararg = va_arg(ap, char *);
+ break;
+ case TP_VOID:
+ (*argtable)[n].pvoidarg = va_arg(ap, void *);
+ break;
+ case T_PTRINT:
+ (*argtable)[n].ptrdiffarg = va_arg(ap, ptrdiff_t);
+ break;
+ case TP_PTRINT:
+ (*argtable)[n].pptrdiffarg = va_arg(ap, ptrdiff_t *);
+ break;
+ case T_SIZEINT:
+ (*argtable)[n].sizearg = va_arg(ap, size_t);
+ break;
+ case T_SSIZEINT:
+ (*argtable)[n].ssizearg = va_arg(ap, ssize_t);
+ break;
+ case TP_SSIZEINT:
+ (*argtable)[n].pssizearg = va_arg(ap, ssize_t *);
+ break;
+ case T_MAXINT:
+ (*argtable)[n].intmaxarg = va_arg(ap, intmax_t);
+ break;
+ case T_MAXUINT:
+ (*argtable)[n].uintmaxarg = va_arg(ap, uintmax_t);
+ break;
+ case TP_MAXINT:
+ (*argtable)[n].pintmaxarg = va_arg(ap, intmax_t *);
+ break;
+#ifdef PRINTF_WIDE_CHAR
+ case T_WINT:
+ (*argtable)[n].wintarg = va_arg(ap, wint_t);
+ break;
+ case TP_WCHAR:
+ (*argtable)[n].pwchararg = va_arg(ap, wchar_t *);
+ break;
+#endif
+ }
+ }
+ goto finish;
+
+overflow:
+ errno = EOVERFLOW;
+ ret = -1;
+
+finish:
+ if (typetable != NULL && typetable != stattypetable) {
+ mmap_free(typetable, *argtablesiz);
+ typetable = NULL;
+ }
+ return ret;
+}
+
+/*
+ * Increase the size of the type table.
+ */
+static int
+__grow_type_table(unsigned char **typetable, int *tablesize)
+{
+ unsigned char *oldtable = *typetable;
+ int newsize = *tablesize * 2;
+
+ if (newsize < sysconf(_SC_PAGESIZE))
+ newsize = sysconf(_SC_PAGESIZE);
+
+ if (*tablesize == STATIC_ARG_TBL_SIZE) {
+ *typetable = mmap_alloc(newsize);
+ if (*typetable == NULL)
+ return -1;
+ memcpy(*typetable, oldtable, *tablesize);
+ } else {
+ unsigned char *new = mmap_alloc(newsize);
+ if (new == NULL)
+ return -1;
+ memmove(new, *typetable, *tablesize);
+ mmap_free(*typetable, *tablesize);
+ *typetable = new;
+ }
+ memset(*typetable + *tablesize, T_UNUSED, (newsize - *tablesize));
+
+ *tablesize = newsize;
+ return 0;
+}
+
+
+#ifdef FLOATING_POINT
+static int
+exponent(char *p0, int exp, int fmtch)
+{
+ char *p, *t;
+ char expbuf[MAXEXPDIG];
+
+ p = p0;
+ *p++ = fmtch;
+ if (exp < 0) {
+ exp = -exp;
+ *p++ = '-';
+ } else
+ *p++ = '+';
+ t = expbuf + MAXEXPDIG;
+ if (exp > 9) {
+ do {
+ *--t = to_char(exp % 10);
+ } while ((exp /= 10) > 9);
+ *--t = to_char(exp);
+ for (; t < expbuf + MAXEXPDIG; *p++ = *t++)
+ /* nothing */;
+ } else {
+ /*
+ * Exponents for decimal floating point conversions
+ * (%[eEgG]) must be at least two characters long,
+ * whereas exponents for hexadecimal conversions can
+ * be only one character long.
+ */
+ if (fmtch == 'e' || fmtch == 'E')
+ *p++ = '0';
+ *p++ = to_char(exp);
+ }
+ return p - p0;
+}
+#endif /* FLOATING_POINT */
+
+#if !defined(HAVE_VSNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
+int
+sudo_vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
+{
+ if (n > INT_MAX) {
+ errno = EOVERFLOW;
+ *str = '\0';
+ return -1;
+ }
+ return xxxprintf(&str, n, 0, fmt, ap);
+}
+#endif /* !HAVE_VSNPRINTF || PREFER_PORTABLE_SNPRINTF */
+
+#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
+int
+sudo_snprintf(char *str, size_t n, char const *fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ if (n > INT_MAX) {
+ errno = EOVERFLOW;
+ *str = '\0';
+ return -1;
+ }
+ va_start(ap, fmt);
+ ret = xxxprintf(&str, n, 0, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+#endif /* !HAVE_SNPRINTF || PREFER_PORTABLE_SNPRINTF */
+
+#if !defined(HAVE_VASPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
+int
+sudo_vasprintf(char **str, const char *fmt, va_list ap)
+{
+ int ret;
+
+ ret = xxxprintf(str, 0, 1, fmt, ap);
+ if (ret == -1)
+ *str = NULL;
+ return ret;
+}
+#endif /* !HAVE_VASPRINTF || PREFER_PORTABLE_SNPRINTF */
+
+#if !defined(HAVE_ASPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
+int
+sudo_asprintf(char **str, char const *fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = xxxprintf(str, 0, 1, fmt, ap);
+ va_end(ap);
+ if (ret == -1)
+ *str = NULL;
+ return ret;
+}
+#endif /* !HAVE_ASPRINTF || PREFER_PORTABLE_SNPRINTF */
+
+#endif /* !HAVE_VSNPRINTF || !HAVE_SNPRINTF || !HAVE_VASPRINTF || !HAVE_ASPRINTF || PREFER_PORTABLE_SNPRINTF */
diff --git a/lib/util/strlcat.c b/lib/util/strlcat.c
new file mode 100644
index 0000000..fee8dc1
--- /dev/null
+++ b/lib/util/strlcat.c
@@ -0,0 +1,68 @@
+/* $OpenBSD: strlcat.c,v 1.15 2015/03/02 21:41:08 millert Exp $ */
+
+/*
+ * Copyright (c) 1998, 2003-2005, 2010-2011, 2013-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_STRLCAT
+
+#include <sys/types.h>
+#include <string.h>
+
+#include "sudo_compat.h"
+
+/*
+ * Appends src to string dst of size dsize (unlike strncat, dsize is the
+ * full size of dst, not space left). At most dsize-1 characters
+ * will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
+ * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
+ * If retval >= dsize, truncation occurred.
+ */
+size_t
+sudo_strlcat(char *dst, const char *src, size_t dsize)
+{
+ const char *odst = dst;
+ const char *osrc = src;
+ size_t n = dsize;
+ size_t dlen;
+
+ /* Find the end of dst and adjust bytes left but don't go past end. */
+ while (n-- != 0 && *dst != '\0')
+ dst++;
+ dlen = dst - odst;
+ n = dsize - dlen;
+
+ if (n-- == 0)
+ return(dlen + strlen(src));
+ while (*src != '\0') {
+ if (n != 0) {
+ *dst++ = *src;
+ n--;
+ }
+ src++;
+ }
+ *dst = '\0';
+
+ return(dlen + (src - osrc)); /* count does not include NUL */
+}
+#endif /* HAVE_STRLCAT */
diff --git a/lib/util/strlcpy.c b/lib/util/strlcpy.c
new file mode 100644
index 0000000..ea8ab4d
--- /dev/null
+++ b/lib/util/strlcpy.c
@@ -0,0 +1,62 @@
+/* $OpenBSD: strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $ */
+
+/*
+ * Copyright (c) 1998, 2003-2005, 2010-2011, 2013-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_STRLCPY
+
+#include <sys/types.h>
+
+#include "sudo_compat.h"
+
+/*
+ * Copy string src to buffer dst of size dsize. At most dsize-1
+ * chars will be copied. Always NUL terminates (unless dsize == 0).
+ * Returns strlen(src); if retval >= dsize, truncation occurred.
+ */
+size_t
+sudo_strlcpy(char *dst, const char *src, size_t dsize)
+{
+ const char *osrc = src;
+ size_t nleft = dsize;
+
+ /* Copy as many bytes as will fit. */
+ if (nleft != 0) {
+ while (--nleft != 0) {
+ if ((*dst++ = *src++) == '\0')
+ break;
+ }
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src. */
+ if (nleft == 0) {
+ if (dsize != 0)
+ *dst = '\0'; /* NUL-terminate dst */
+ while (*src++)
+ continue;
+ }
+
+ return(src - osrc - 1); /* count does not include NUL */
+}
+#endif /* HAVE_STRLCPY */
diff --git a/lib/util/strndup.c b/lib/util/strndup.c
new file mode 100644
index 0000000..5d9ea5a
--- /dev/null
+++ b/lib/util/strndup.c
@@ -0,0 +1,56 @@
+/* $OpenBSD: strndup.c,v 1.1 2010/05/18 22:24:55 tedu Exp $ */
+
+/*
+ * Copyright (c) 2010 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_STRNDUP
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "sudo_compat.h"
+
+char *
+sudo_strndup(const char *str, size_t maxlen)
+{
+ char *copy;
+ size_t len;
+
+ len = strnlen(str, maxlen);
+ copy = malloc(len + 1);
+ if (copy != NULL) {
+ (void)memcpy(copy, str, len);
+ copy[len] = '\0';
+ }
+
+ return copy;
+}
+
+#endif /* HAVE_STRNDUP */
diff --git a/lib/util/strnlen.c b/lib/util/strnlen.c
new file mode 100644
index 0000000..7344e9f
--- /dev/null
+++ b/lib/util/strnlen.c
@@ -0,0 +1,43 @@
+/* $OpenBSD: strnlen.c,v 1.5 2014/06/10 04:17:37 deraadt Exp $ */
+
+/*
+ * Copyright (c) 2010 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_STRNLEN
+
+#include <sys/types.h>
+
+#include "sudo_compat.h"
+
+size_t
+sudo_strnlen(const char *str, size_t maxlen)
+{
+ const char *cp;
+
+ for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--)
+ continue;
+
+ return (size_t)(cp - str);
+}
+
+#endif /* HAVE_STRNLEN */
diff --git a/lib/util/strsignal.c b/lib/util/strsignal.c
new file mode 100644
index 0000000..a6f9eea
--- /dev/null
+++ b/lib/util/strsignal.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009-2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifndef HAVE_STRSIGNAL
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <signal.h>
+
+#define DEFAULT_TEXT_DOMAIN "sudo"
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+
+#if defined(HAVE_DECL_SYS_SIGLIST) && HAVE_DECL_SYS_SIGLIST == 1
+# define sudo_sys_siglist sys_siglist
+#elif defined(HAVE_DECL__SYS_SIGLIST) && HAVE_DECL__SYS_SIGLIST == 1
+# define sudo_sys_siglist _sys_siglist
+#else
+extern const char *const sudo_sys_siglist[NSIG];
+#endif
+
+/*
+ * Get signal description string
+ */
+char *
+sudo_strsignal(int signo)
+{
+ if (signo > 0 && signo < NSIG && sudo_sys_siglist[signo] != NULL)
+ return (char *)sudo_sys_siglist[signo];
+ /* XXX - should be "Unknown signal: %d" */
+ return _("Unknown signal");
+}
+#endif /* HAVE_STRSIGNAL */
diff --git a/lib/util/strsplit.c b/lib/util/strsplit.c
new file mode 100644
index 0000000..728f225
--- /dev/null
+++ b/lib/util/strsplit.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <grp.h>
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+/*
+ * Like strtok_r but non-destructive and works w/o a NUL terminator.
+ * TODO: Optimize by storing current char in a variable ch
+ */
+const char *
+sudo_strsplit_v1(const char *str, const char *endstr, const char *sep, const char **last)
+{
+ const char *cp, *s;
+ debug_decl(sudo_strsplit, SUDO_DEBUG_UTIL)
+
+ /* If no str specified, use last ptr (if any). */
+ if (str == NULL)
+ str = *last;
+
+ /* Skip leading separator characters. */
+ while (str < endstr) {
+ for (s = sep; *s != '\0'; s++) {
+ if (*str == *s) {
+ str++;
+ break;
+ }
+ }
+ if (*s == '\0')
+ break;
+ }
+
+ /* Empty string? */
+ if (str >= endstr) {
+ *last = endstr;
+ debug_return_ptr(NULL);
+ }
+
+ /* Scan str until we hit a char from sep. */
+ for (cp = str; cp < endstr; cp++) {
+ for (s = sep; *s != '\0'; s++) {
+ if (*cp == *s)
+ break;
+ }
+ if (*s != '\0')
+ break;
+ }
+ *last = cp;
+ debug_return_const_ptr(str);
+}
diff --git a/lib/util/strtobool.c b/lib/util/strtobool.c
new file mode 100644
index 0000000..74a6fd3
--- /dev/null
+++ b/lib/util/strtobool.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+int
+sudo_strtobool_v1(const char *str)
+{
+ debug_decl(sudo_strtobool, SUDO_DEBUG_UTIL)
+
+ switch (*str) {
+ case '0':
+ case '1':
+ if (str[1] == '\0')
+ debug_return_int(*str - '0');
+ break;
+ case 'y':
+ case 'Y':
+ if (strcasecmp(str, "yes") == 0)
+ debug_return_int(1);
+ break;
+ case 't':
+ case 'T':
+ if (strcasecmp(str, "true") == 0)
+ debug_return_int(1);
+ break;
+ case 'o':
+ case 'O':
+ if (strcasecmp(str, "on") == 0)
+ debug_return_int(1);
+ if (strcasecmp(str, "off") == 0)
+ debug_return_int(0);
+ break;
+ case 'n':
+ case 'N':
+ if (strcasecmp(str, "no") == 0)
+ debug_return_int(0);
+ break;
+ case 'f':
+ case 'F':
+ if (strcasecmp(str, "false") == 0)
+ debug_return_int(0);
+ break;
+ }
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "invalid boolean value \"%s\"", str);
+
+ debug_return_int(-1);
+}
diff --git a/lib/util/strtoid.c b/lib/util/strtoid.c
new file mode 100644
index 0000000..2339a88
--- /dev/null
+++ b/lib/util/strtoid.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2013-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+
+#define DEFAULT_TEXT_DOMAIN "sudo"
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+/*
+ * Parse a uid/gid in string form.
+ * If sep is non-NULL, it contains valid separator characters (e.g. comma, space)
+ * If endp is non-NULL it is set to the next char after the ID.
+ * On success, returns the parsed ID and clears errstr.
+ * On error, returns 0 and sets errstr.
+ */
+#if SIZEOF_ID_T == SIZEOF_LONG_LONG
+id_t
+sudo_strtoid_v1(const char *p, const char *sep, char **endp, const char **errstr)
+{
+ char *ep;
+ id_t ret = 0;
+ long long llval;
+ bool valid = false;
+ debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL)
+
+ /* skip leading space so we can pick up the sign, if any */
+ while (isspace((unsigned char)*p))
+ p++;
+ if (sep == NULL)
+ sep = "";
+ errno = 0;
+ llval = strtoll(p, &ep, 10);
+ if (ep != p) {
+ /* check for valid separator (including '\0') */
+ do {
+ if (*ep == *sep)
+ valid = true;
+ } while (*sep++ != '\0');
+ }
+ if (!valid) {
+ if (errstr != NULL)
+ *errstr = N_("invalid value");
+ errno = EINVAL;
+ goto done;
+ }
+ if (errno == ERANGE) {
+ if (errstr != NULL) {
+ if (llval == LLONG_MAX)
+ *errstr = N_("value too large");
+ else
+ *errstr = N_("value too small");
+ }
+ goto done;
+ }
+ ret = (id_t)llval;
+ if (errstr != NULL)
+ *errstr = NULL;
+ if (endp != NULL)
+ *endp = ep;
+done:
+ debug_return_id_t(ret);
+}
+#else
+id_t
+sudo_strtoid_v1(const char *p, const char *sep, char **endp, const char **errstr)
+{
+ char *ep;
+ id_t ret = 0;
+ bool valid = false;
+ debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL)
+
+ /* skip leading space so we can pick up the sign, if any */
+ while (isspace((unsigned char)*p))
+ p++;
+ if (sep == NULL)
+ sep = "";
+ errno = 0;
+ if (*p == '-') {
+ long lval = strtol(p, &ep, 10);
+ if (ep != p) {
+ /* check for valid separator (including '\0') */
+ do {
+ if (*ep == *sep)
+ valid = true;
+ } while (*sep++ != '\0');
+ }
+ if (!valid) {
+ if (errstr != NULL)
+ *errstr = N_("invalid value");
+ errno = EINVAL;
+ goto done;
+ }
+ if ((errno == ERANGE && lval == LONG_MAX) || lval > INT_MAX) {
+ errno = ERANGE;
+ if (errstr != NULL)
+ *errstr = N_("value too large");
+ goto done;
+ }
+ if ((errno == ERANGE && lval == LONG_MIN) || lval < INT_MIN) {
+ errno = ERANGE;
+ if (errstr != NULL)
+ *errstr = N_("value too small");
+ goto done;
+ }
+ ret = (id_t)lval;
+ } else {
+ unsigned long ulval = strtoul(p, &ep, 10);
+ if (ep != p) {
+ /* check for valid separator (including '\0') */
+ do {
+ if (*ep == *sep)
+ valid = true;
+ } while (*sep++ != '\0');
+ }
+ if (!valid) {
+ if (errstr != NULL)
+ *errstr = N_("invalid value");
+ errno = EINVAL;
+ goto done;
+ }
+ if ((errno == ERANGE && ulval == ULONG_MAX) || ulval > UINT_MAX) {
+ errno = ERANGE;
+ if (errstr != NULL)
+ *errstr = N_("value too large");
+ goto done;
+ }
+ ret = (id_t)ulval;
+ }
+ if (errstr != NULL)
+ *errstr = NULL;
+ if (endp != NULL)
+ *endp = ep;
+done:
+ debug_return_id_t(ret);
+}
+#endif /* SIZEOF_ID_T == 8 */
diff --git a/lib/util/strtomode.c b/lib/util/strtomode.c
new file mode 100644
index 0000000..5a1ec94
--- /dev/null
+++ b/lib/util/strtomode.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2013-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#define DEFAULT_TEXT_DOMAIN "sudo"
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+/*
+ * Parse an octal file mode in the range [0, 0777].
+ * On success, returns the parsed mode and clears errstr.
+ * On error, returns 0 and sets errstr.
+ */
+int
+sudo_strtomode_v1(const char *cp, const char **errstr)
+{
+ char *ep;
+ long lval;
+ debug_decl(sudo_strtomode, SUDO_DEBUG_UTIL)
+
+ errno = 0;
+ lval = strtol(cp, &ep, 8);
+ if (ep == cp || *ep != '\0') {
+ if (errstr != NULL)
+ *errstr = N_("invalid value");
+ errno = EINVAL;
+ debug_return_int(0);
+ }
+ if (lval < 0 || lval > ACCESSPERMS) {
+ if (errstr != NULL)
+ *errstr = lval < 0 ? N_("value too small") : N_("value too large");
+ errno = ERANGE;
+ debug_return_int(0);
+ }
+ if (errstr != NULL)
+ *errstr = NULL;
+ debug_return_int((int)lval);
+}
diff --git a/lib/util/strtonum.c b/lib/util/strtonum.c
new file mode 100644
index 0000000..aedbc02
--- /dev/null
+++ b/lib/util/strtonum.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2013-2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#define DEFAULT_TEXT_DOMAIN "sudo"
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+
+#ifdef HAVE_STRTONUM
+
+/*
+ * The OpenBSD strtonum error string too short to be translated sensibly.
+ * This wrapper just changes errstr as follows:
+ * invalid -> invalid value
+ * too large -> value too large
+ * too small -> value too small
+ */
+long long
+sudo_strtonum(const char *str, long long minval, long long maxval,
+ const char **errstrp)
+{
+ long long retval;
+ const char *errstr;
+
+# undef strtonum
+ retval = strtonum(str, minval, maxval, &errstr);
+ if (errstr != NULL) {
+ if (errno == EINVAL) {
+ errstr = N_("invalid value");
+ } else if (errno == ERANGE) {
+ errstr = strcmp(errstr, "too large") == 0 ?
+ N_("value too large") : N_("value too small");
+ }
+ }
+ if (errstrp != NULL)
+ *errstrp = errstr;
+ return retval;
+}
+
+#else
+
+enum strtonum_err {
+ STN_VALID,
+ STN_INVALID,
+ STN_TOOSMALL,
+ STN_TOOBIG
+};
+
+/*
+ * Convert a string to a number in the range [minval, maxval]
+ */
+long long
+sudo_strtonum(const char *str, long long minval, long long maxval,
+ const char **errstrp)
+{
+ const unsigned char *ustr = (const unsigned char *)str;
+ enum strtonum_err errval = STN_VALID;
+ long long lastval, result = 0;
+ unsigned char dig, sign;
+ int remainder;
+
+ if (minval > maxval) {
+ errval = STN_INVALID;
+ goto done;
+ }
+
+ /* Trim leading space and check sign, if any. */
+ while (isspace(*ustr)) {
+ ustr++;
+ }
+ switch (*ustr) {
+ case '-':
+ sign = '-';
+ ustr++;
+ break;
+ case '+':
+ ustr++;
+ /* FALLTHROUGH */
+ default:
+ sign = '+';
+ break;
+ }
+
+ /*
+ * To prevent overflow we determine the highest (or lowest in
+ * the case of negative numbers) value result can have *before*
+ * if its multiplied (divided) by 10 as well as the remainder.
+ * If result matches this value and the next digit is larger than
+ * the remainder, we know the result is out of range.
+ * The remainder is always positive since it is compared against
+ * an unsigned digit.
+ */
+ if (sign == '-') {
+ lastval = minval / 10;
+ remainder = -(minval % 10);
+ if (remainder < 0) {
+ lastval += 1;
+ remainder += 10;
+ }
+ while ((dig = *ustr++) != '\0') {
+ if (!isdigit(dig)) {
+ errval = STN_INVALID;
+ break;
+ }
+ dig -= '0';
+ if (result < lastval || (result == lastval && dig > remainder)) {
+ errval = STN_TOOSMALL;
+ break;
+ } else {
+ result *= 10;
+ result -= dig;
+ }
+ }
+ if (result > maxval)
+ errval = STN_TOOBIG;
+ } else {
+ lastval = maxval / 10;
+ remainder = maxval % 10;
+ while ((dig = *ustr++) != '\0') {
+ if (!isdigit(dig)) {
+ errval = STN_INVALID;
+ break;
+ }
+ dig -= '0';
+ if (result > lastval || (result == lastval && dig > remainder)) {
+ errval = STN_TOOBIG;
+ break;
+ } else {
+ result *= 10;
+ result += dig;
+ }
+ }
+ if (result < minval)
+ errval = STN_TOOSMALL;
+ }
+
+done:
+ switch (errval) {
+ case STN_VALID:
+ if (errstrp != NULL)
+ *errstrp = NULL;
+ break;
+ case STN_INVALID:
+ result = 0;
+ errno = EINVAL;
+ if (errstrp != NULL)
+ *errstrp = N_("invalid value");
+ break;
+ case STN_TOOSMALL:
+ result = 0;
+ errno = ERANGE;
+ if (errstrp != NULL)
+ *errstrp = N_("value too small");
+ break;
+ case STN_TOOBIG:
+ result = 0;
+ errno = ERANGE;
+ if (errstrp != NULL)
+ *errstrp = N_("value too large");
+ break;
+ }
+ return result;
+}
+#endif /* HAVE_STRTONUM */
diff --git a/lib/util/sudo_conf.c b/lib/util/sudo_conf.c
new file mode 100644
index 0000000..1af6929
--- /dev/null
+++ b/lib/util/sudo_conf.c
@@ -0,0 +1,658 @@
+/*
+ * Copyright (c) 2009-2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+
+#define DEFAULT_TEXT_DOMAIN "sudo"
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#define SUDO_ERROR_WRAP 0
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "pathnames.h"
+#include "sudo_plugin.h"
+#include "sudo_conf.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+#ifdef __TANDEM
+# define ROOT_UID 65535
+#else
+# define ROOT_UID 0
+#endif
+
+struct sudo_conf_table {
+ const char *name;
+ unsigned int namelen;
+ int (*parser)(const char *entry, const char *conf_file, unsigned int lineno);
+};
+
+struct sudo_conf_path_table {
+ const char *pname;
+ unsigned int pnamelen;
+ bool dynamic;
+ char *pval;
+};
+
+static int parse_debug(const char *entry, const char *conf_file, unsigned int lineno);
+static int parse_path(const char *entry, const char *conf_file, unsigned int lineno);
+static int parse_plugin(const char *entry, const char *conf_file, unsigned int lineno);
+static int parse_variable(const char *entry, const char *conf_file, unsigned int lineno);
+
+static struct sudo_conf_table sudo_conf_table[] = {
+ { "Debug", sizeof("Debug") - 1, parse_debug },
+ { "Path", sizeof("Path") - 1, parse_path },
+ { "Plugin", sizeof("Plugin") - 1, parse_plugin },
+ { "Set", sizeof("Set") - 1, parse_variable },
+ { NULL }
+};
+
+static int set_var_disable_coredump(const char *entry, const char *conf_file, unsigned int);
+static int set_var_group_source(const char *entry, const char *conf_file, unsigned int);
+static int set_var_max_groups(const char *entry, const char *conf_file, unsigned int);
+static int set_var_probe_interfaces(const char *entry, const char *conf_file, unsigned int);
+
+static struct sudo_conf_table sudo_conf_var_table[] = {
+ { "disable_coredump", sizeof("disable_coredump") - 1, set_var_disable_coredump },
+ { "group_source", sizeof("group_source") - 1, set_var_group_source },
+ { "max_groups", sizeof("max_groups") - 1, set_var_max_groups },
+ { "probe_interfaces", sizeof("probe_interfaces") - 1, set_var_probe_interfaces },
+ { NULL }
+};
+
+/* Indexes into path_table[] below (order is important). */
+#define SUDO_CONF_PATH_ASKPASS 0
+#define SUDO_CONF_PATH_SESH 1
+#define SUDO_CONF_PATH_NOEXEC 2
+#define SUDO_CONF_PATH_PLUGIN_DIR 3
+#define SUDO_CONF_PATH_DEVSEARCH 4
+
+static struct sudo_conf_data {
+ bool disable_coredump;
+ bool probe_interfaces;
+ int group_source;
+ int max_groups;
+ struct sudo_conf_debug_list debugging;
+ struct plugin_info_list plugins;
+ struct sudo_conf_path_table path_table[6];
+} sudo_conf_data = {
+ true,
+ true,
+ GROUP_SOURCE_ADAPTIVE,
+ -1,
+ TAILQ_HEAD_INITIALIZER(sudo_conf_data.debugging),
+ TAILQ_HEAD_INITIALIZER(sudo_conf_data.plugins),
+ {
+ { "askpass", sizeof("askpass") - 1, false, _PATH_SUDO_ASKPASS },
+ { "sesh", sizeof("sesh") - 1, false, _PATH_SUDO_SESH },
+ { "noexec", sizeof("noexec") - 1, false, _PATH_SUDO_NOEXEC },
+ { "plugin_dir", sizeof("plugin_dir") - 1, false, _PATH_SUDO_PLUGIN_DIR },
+ { "devsearch", sizeof("devsearch") - 1, false, _PATH_SUDO_DEVSEARCH },
+ { NULL }
+ }
+};
+
+/*
+ * "Set variable_name value"
+ */
+static int
+parse_variable(const char *entry, const char *conf_file, unsigned int lineno)
+{
+ struct sudo_conf_table *var;
+ int ret;
+ debug_decl(parse_variable, SUDO_DEBUG_UTIL)
+
+ for (var = sudo_conf_var_table; var->name != NULL; var++) {
+ if (strncmp(entry, var->name, var->namelen) == 0 &&
+ isblank((unsigned char)entry[var->namelen])) {
+ entry += var->namelen + 1;
+ while (isblank((unsigned char)*entry))
+ entry++;
+ ret = var->parser(entry, conf_file, lineno);
+ sudo_debug_printf(ret ? SUDO_DEBUG_INFO : SUDO_DEBUG_ERROR,
+ "%s: %s:%u: Set %s %s", __func__, conf_file,
+ lineno, var->name, entry);
+ debug_return_int(ret);
+ }
+ }
+ sudo_debug_printf(SUDO_DEBUG_WARN, "%s: %s:%u: unknown setting %s",
+ __func__, conf_file, lineno, entry);
+ debug_return_int(false);
+}
+
+/*
+ * "Path name /path/to/file"
+ * If path is missing it will be set to the NULL pointer.
+ */
+static int
+parse_path(const char *entry, const char *conf_file, unsigned int lineno)
+{
+ const char *entry_end = entry + strlen(entry);
+ const char *ep, *name, *path;
+ struct sudo_conf_path_table *cur;
+ size_t namelen;
+ debug_decl(parse_path, SUDO_DEBUG_UTIL)
+
+ /* Parse name. */
+ name = sudo_strsplit(entry, entry_end, " \t", &ep);
+ if (name == NULL)
+ goto bad;
+ namelen = (size_t)(ep - name);
+
+ /* Parse path (if present). */
+ path = sudo_strsplit(NULL, entry_end, " \t", &ep);
+
+ /* Match supported paths, ignoring unknown paths. */
+ for (cur = sudo_conf_data.path_table; cur->pname != NULL; cur++) {
+ if (namelen == cur->pnamelen &&
+ strncasecmp(name, cur->pname, cur->pnamelen) == 0) {
+ char *pval = NULL;
+ if (path != NULL) {
+ if ((pval = strdup(path)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+ }
+ if (cur->dynamic)
+ free(cur->pval);
+ cur->pval = pval;
+ cur->dynamic = true;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %s:%u: Path %s %s",
+ __func__, conf_file, lineno, cur->pname,
+ pval ? pval : "(none)");
+ debug_return_int(true);
+ }
+ }
+ sudo_debug_printf(SUDO_DEBUG_WARN, "%s: %s:%u: unknown path %s",
+ __func__, conf_file, lineno, entry);
+ debug_return_int(false);
+bad:
+ sudo_warnx(U_("invalid Path value \"%s\" in %s, line %u"),
+ entry, conf_file, lineno);
+ debug_return_int(false);
+}
+
+/*
+ * "Debug program /path/to/log flags,..."
+ */
+static int
+parse_debug(const char *entry, const char *conf_file, unsigned int lineno)
+{
+ struct sudo_conf_debug *debug_spec;
+ struct sudo_debug_file *debug_file = NULL;
+ const char *ep, *path, *progname, *flags;
+ const char *entry_end = entry + strlen(entry);
+ size_t pathlen, prognamelen;
+ debug_decl(parse_debug, SUDO_DEBUG_UTIL)
+
+ /* Parse progname. */
+ progname = sudo_strsplit(entry, entry_end, " \t", &ep);
+ if (progname == NULL)
+ debug_return_int(false); /* not enough fields */
+ prognamelen = (size_t)(ep - progname);
+
+ /* Parse path. */
+ path = sudo_strsplit(NULL, entry_end, " \t", &ep);
+ if (path == NULL)
+ debug_return_int(false); /* not enough fields */
+ pathlen = (size_t)(ep - path);
+
+ /* Remainder is flags (freeform). */
+ flags = sudo_strsplit(NULL, entry_end, " \t", &ep);
+ if (flags == NULL)
+ debug_return_int(false); /* not enough fields */
+
+ /* If progname already exists, use it, else alloc a new one. */
+ TAILQ_FOREACH(debug_spec, &sudo_conf_data.debugging, entries) {
+ if (strncmp(debug_spec->progname, progname, prognamelen) == 0 &&
+ debug_spec->progname[prognamelen] == '\0')
+ break;
+ }
+ if (debug_spec == NULL) {
+ debug_spec = malloc(sizeof(*debug_spec));
+ if (debug_spec == NULL)
+ goto oom;
+ debug_spec->progname = strndup(progname, prognamelen);
+ if (debug_spec->progname == NULL) {
+ free(debug_spec);
+ debug_spec = NULL;
+ goto oom;
+ }
+ TAILQ_INIT(&debug_spec->debug_files);
+ TAILQ_INSERT_TAIL(&sudo_conf_data.debugging, debug_spec, entries);
+ }
+ debug_file = calloc(1, sizeof(*debug_file));
+ if (debug_file == NULL)
+ goto oom;
+ debug_file->debug_file = strndup(path, pathlen);
+ if (debug_file->debug_file == NULL)
+ goto oom;
+ debug_file->debug_flags = strdup(flags);
+ if (debug_file->debug_flags == NULL)
+ goto oom;
+ TAILQ_INSERT_TAIL(&debug_spec->debug_files, debug_file, entries);
+
+ debug_return_int(true);
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (debug_file != NULL) {
+ free(debug_file->debug_file);
+ free(debug_file->debug_flags);
+ free(debug_file);
+ }
+ debug_return_int(-1);
+}
+
+/*
+ * "Plugin symbol /path/to/log args..."
+ */
+static int
+parse_plugin(const char *entry, const char *conf_file, unsigned int lineno)
+{
+ struct plugin_info *info = NULL;
+ const char *ep, *path, *symbol;
+ const char *entry_end = entry + strlen(entry);
+ char **options = NULL;
+ size_t pathlen, symlen;
+ unsigned int nopts = 0;
+ debug_decl(parse_plugin, SUDO_DEBUG_UTIL)
+
+ /* Parse symbol. */
+ symbol = sudo_strsplit(entry, entry_end, " \t", &ep);
+ if (symbol == NULL)
+ debug_return_int(false); /* not enough fields */
+ symlen = (size_t)(ep - symbol);
+
+ /* Parse path. */
+ path = sudo_strsplit(NULL, entry_end, " \t", &ep);
+ if (path == NULL)
+ debug_return_int(false); /* not enough fields */
+ pathlen = (size_t)(ep - path);
+
+ /* Split options into an array if present. */
+ while (isblank((unsigned char)*ep))
+ ep++;
+ if (*ep != '\0') {
+ /* Count number of options and allocate array. */
+ const char *cp, *opt = ep;
+
+ /* Count and allocate options array. */
+ for (nopts = 0, cp = sudo_strsplit(opt, entry_end, " \t", &ep);
+ cp != NULL; cp = sudo_strsplit(NULL, entry_end, " \t", &ep)) {
+ nopts++;
+ }
+ options = reallocarray(NULL, nopts + 1, sizeof(*options));
+ if (options == NULL)
+ goto oom;
+
+ /* Fill in options array. */
+ for (nopts = 0, cp = sudo_strsplit(opt, entry_end, " \t", &ep);
+ cp != NULL; cp = sudo_strsplit(NULL, entry_end, " \t", &ep)) {
+ options[nopts] = strndup(cp, (size_t)(ep - cp));
+ if (options[nopts] == NULL)
+ goto oom;
+ nopts++;
+ }
+ options[nopts] = NULL;
+ }
+
+ info = calloc(sizeof(*info), 1);
+ if (info == NULL)
+ goto oom;
+ info->symbol_name = strndup(symbol, symlen);
+ if (info->symbol_name == NULL)
+ goto oom;
+ info->path = strndup(path, pathlen);
+ if (info->path == NULL)
+ goto oom;
+ info->options = options;
+ info->lineno = lineno;
+ TAILQ_INSERT_TAIL(&sudo_conf_data.plugins, info, entries);
+
+ debug_return_int(true);
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (options != NULL) {
+ while (nopts--)
+ free(options[nopts]);
+ free(options);
+ }
+ if (info != NULL) {
+ free(info->symbol_name);
+ free(info->path);
+ free(info);
+ }
+ debug_return_int(-1);
+}
+
+static int
+set_var_disable_coredump(const char *strval, const char *conf_file,
+ unsigned int lineno)
+{
+ int val = sudo_strtobool(strval);
+ debug_decl(set_var_disable_coredump, SUDO_DEBUG_UTIL)
+
+ if (val == -1) {
+ sudo_warnx(U_("invalid value for %s \"%s\" in %s, line %u"),
+ "disable_coredump", strval, conf_file, lineno);
+ debug_return_bool(false);
+ }
+ sudo_conf_data.disable_coredump = val;
+ debug_return_bool(true);
+}
+
+static int
+set_var_group_source(const char *strval, const char *conf_file,
+ unsigned int lineno)
+{
+ debug_decl(set_var_group_source, SUDO_DEBUG_UTIL)
+
+ if (strcasecmp(strval, "adaptive") == 0) {
+ sudo_conf_data.group_source = GROUP_SOURCE_ADAPTIVE;
+ } else if (strcasecmp(strval, "static") == 0) {
+ sudo_conf_data.group_source = GROUP_SOURCE_STATIC;
+ } else if (strcasecmp(strval, "dynamic") == 0) {
+ sudo_conf_data.group_source = GROUP_SOURCE_DYNAMIC;
+ } else {
+ sudo_warnx(U_("unsupported group source \"%s\" in %s, line %u"), strval,
+ conf_file, lineno);
+ debug_return_bool(false);
+ }
+ debug_return_bool(true);
+}
+
+static int
+set_var_max_groups(const char *strval, const char *conf_file,
+ unsigned int lineno)
+{
+ int max_groups;
+ debug_decl(set_var_max_groups, SUDO_DEBUG_UTIL)
+
+ max_groups = strtonum(strval, 1, INT_MAX, NULL);
+ if (max_groups <= 0) {
+ sudo_warnx(U_("invalid max groups \"%s\" in %s, line %u"), strval,
+ conf_file, lineno);
+ debug_return_bool(false);
+ }
+ sudo_conf_data.max_groups = max_groups;
+ debug_return_bool(true);
+}
+
+static int
+set_var_probe_interfaces(const char *strval, const char *conf_file,
+ unsigned int lineno)
+{
+ int val = sudo_strtobool(strval);
+ debug_decl(set_var_probe_interfaces, SUDO_DEBUG_UTIL)
+
+ if (val == -1) {
+ sudo_warnx(U_("invalid value for %s \"%s\" in %s, line %u"),
+ "probe_interfaces", strval, conf_file, lineno);
+ debug_return_bool(false);
+ }
+ sudo_conf_data.probe_interfaces = val;
+ debug_return_bool(true);
+}
+
+const char *
+sudo_conf_askpass_path_v1(void)
+{
+ return sudo_conf_data.path_table[SUDO_CONF_PATH_ASKPASS].pval;
+}
+
+const char *
+sudo_conf_sesh_path_v1(void)
+{
+ return sudo_conf_data.path_table[SUDO_CONF_PATH_SESH].pval;
+}
+
+const char *
+sudo_conf_noexec_path_v1(void)
+{
+ return sudo_conf_data.path_table[SUDO_CONF_PATH_NOEXEC].pval;
+}
+
+const char *
+sudo_conf_plugin_dir_path_v1(void)
+{
+ return sudo_conf_data.path_table[SUDO_CONF_PATH_PLUGIN_DIR].pval;
+}
+
+const char *
+sudo_conf_devsearch_path_v1(void)
+{
+ return sudo_conf_data.path_table[SUDO_CONF_PATH_DEVSEARCH].pval;
+}
+
+int
+sudo_conf_group_source_v1(void)
+{
+ return sudo_conf_data.group_source;
+}
+
+int
+sudo_conf_max_groups_v1(void)
+{
+ return sudo_conf_data.max_groups;
+}
+
+struct plugin_info_list *
+sudo_conf_plugins_v1(void)
+{
+ return &sudo_conf_data.plugins;
+}
+
+struct sudo_conf_debug_list *
+sudo_conf_debugging_v1(void)
+{
+ return &sudo_conf_data.debugging;
+}
+
+/* Return the debug files list for a program, or NULL if none. */
+struct sudo_conf_debug_file_list *
+sudo_conf_debug_files_v1(const char *progname)
+{
+ struct sudo_conf_debug *debug_spec;
+ size_t prognamelen, progbaselen;
+ const char *progbase = progname;
+ debug_decl(sudo_conf_debug_files, SUDO_DEBUG_UTIL)
+
+ /* Determine basename if program is fully qualified (like for plugins). */
+ prognamelen = progbaselen = strlen(progname);
+ if (*progname == '/') {
+ progbase = strrchr(progname, '/');
+ progbaselen = strlen(++progbase);
+ }
+ /* Convert sudoedit -> sudo. */
+ if (progbaselen > 4 && strcmp(progbase + 4, "edit") == 0) {
+ progbaselen -= 4;
+ }
+ TAILQ_FOREACH(debug_spec, &sudo_conf_data.debugging, entries) {
+ const char *prog = progbase;
+ size_t len = progbaselen;
+
+ if (debug_spec->progname[0] == '/') {
+ /* Match fully-qualified name, if possible. */
+ prog = progname;
+ len = prognamelen;
+ }
+ if (strncmp(debug_spec->progname, prog, len) == 0 &&
+ debug_spec->progname[len] == '\0') {
+ debug_return_ptr(&debug_spec->debug_files);
+ }
+ }
+ debug_return_ptr(NULL);
+}
+
+bool
+sudo_conf_disable_coredump_v1(void)
+{
+ return sudo_conf_data.disable_coredump;
+}
+
+bool
+sudo_conf_probe_interfaces_v1(void)
+{
+ return sudo_conf_data.probe_interfaces;
+}
+
+/*
+ * Reads in /etc/sudo.conf and populates sudo_conf_data.
+ */
+int
+sudo_conf_read_v1(const char *conf_file, int conf_types)
+{
+ struct stat sb;
+ FILE *fp = NULL;
+ int ret = false;
+ char *prev_locale, *line = NULL;
+ unsigned int conf_lineno = 0;
+ size_t linesize = 0;
+ debug_decl(sudo_conf_read, SUDO_DEBUG_UTIL)
+
+ if ((prev_locale = setlocale(LC_ALL, NULL)) == NULL) {
+ sudo_warn("setlocale(LC_ALL, NULL)");
+ debug_return_int(-1);
+ }
+ if ((prev_locale = strdup(prev_locale)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+
+ /* Parse sudo.conf in the "C" locale. */
+ if (prev_locale[0] != 'C' || prev_locale[1] != '\0')
+ setlocale(LC_ALL, "C");
+
+ if (conf_file == NULL) {
+ conf_file = _PATH_SUDO_CONF;
+ switch (sudo_secure_file(conf_file, ROOT_UID, -1, &sb)) {
+ case SUDO_PATH_SECURE:
+ break;
+ case SUDO_PATH_MISSING:
+ /* Root should always be able to read sudo.conf. */
+ if (errno != ENOENT && geteuid() == ROOT_UID)
+ sudo_warn(U_("unable to stat %s"), conf_file);
+ goto done;
+ case SUDO_PATH_BAD_TYPE:
+ sudo_warnx(U_("%s is not a regular file"), conf_file);
+ goto done;
+ case SUDO_PATH_WRONG_OWNER:
+ sudo_warnx(U_("%s is owned by uid %u, should be %u"),
+ conf_file, (unsigned int) sb.st_uid, ROOT_UID);
+ goto done;
+ case SUDO_PATH_WORLD_WRITABLE:
+ sudo_warnx(U_("%s is world writable"), conf_file);
+ goto done;
+ case SUDO_PATH_GROUP_WRITABLE:
+ sudo_warnx(U_("%s is group writable"), conf_file);
+ goto done;
+ default:
+ /* NOTREACHED */
+ goto done;
+ }
+ }
+
+ if ((fp = fopen(conf_file, "r")) == NULL) {
+ if (errno != ENOENT && geteuid() == ROOT_UID)
+ sudo_warn(U_("unable to open %s"), conf_file);
+ goto done;
+ }
+
+ while (sudo_parseln(&line, &linesize, &conf_lineno, fp, 0) != -1) {
+ struct sudo_conf_table *cur;
+ unsigned int i;
+ char *cp;
+
+ if (*(cp = line) == '\0')
+ continue; /* empty line or comment */
+
+ for (i = 0, cur = sudo_conf_table; cur->name != NULL; i++, cur++) {
+ if (strncasecmp(cp, cur->name, cur->namelen) == 0 &&
+ isblank((unsigned char)cp[cur->namelen])) {
+ if (ISSET(conf_types, (1 << i))) {
+ cp += cur->namelen;
+ while (isblank((unsigned char)*cp))
+ cp++;
+ ret = cur->parser(cp, conf_file, conf_lineno);
+ if (ret == -1)
+ goto done;
+ }
+ break;
+ }
+ }
+ if (cur->name == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_WARN,
+ "%s: %s:%u: unsupported entry: %s", __func__, conf_file,
+ conf_lineno, line);
+ }
+ }
+ ret = true;
+
+done:
+ if (fp != NULL)
+ fclose(fp);
+ free(line);
+
+ /* Restore locale if needed. */
+ if (prev_locale[0] != 'C' || prev_locale[1] != '\0')
+ setlocale(LC_ALL, prev_locale);
+ free(prev_locale);
+ debug_return_int(ret);
+}
+
+/*
+ * Used by the sudo_conf regress test to clear compile-time path settings.
+ */
+void
+sudo_conf_clear_paths_v1(void)
+{
+ struct sudo_conf_path_table *cur;
+ debug_decl(sudo_conf_clear_paths, SUDO_DEBUG_UTIL)
+
+ for (cur = sudo_conf_data.path_table; cur->pname != NULL; cur++) {
+ if (cur->dynamic)
+ free(cur->pval);
+ cur->pval = NULL;
+ cur->dynamic = false;
+ }
+}
diff --git a/lib/util/sudo_debug.c b/lib/util/sudo_debug.c
new file mode 100644
index 0000000..593af92
--- /dev/null
+++ b/lib/util/sudo_debug.c
@@ -0,0 +1,877 @@
+/*
+ * Copyright (c) 2011-2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <time.h>
+
+#define DEFAULT_TEXT_DOMAIN "sudo"
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_plugin.h"
+#include "sudo_debug.h"
+#include "sudo_conf.h"
+#include "sudo_util.h"
+
+/*
+ * The debug priorities and subsystems are currently hard-coded.
+ * In the future we might consider allowing plugins to register their
+ * own subsystems and provide direct access to the debugging API.
+ */
+
+/* Note: this must match the order in sudo_debug.h */
+static const char *const sudo_debug_priorities[] = {
+ "crit",
+ "err",
+ "warn",
+ "notice",
+ "diag",
+ "info",
+ "trace",
+ "debug",
+ NULL
+};
+
+/* Note: this must match the order in sudo_debug.h */
+static const char *const sudo_debug_default_subsystems[] = {
+ "args",
+ "conv",
+ "edit",
+ "event",
+ "exec",
+ "hooks",
+ "main",
+ "netif",
+ "pcomm",
+ "plugin",
+ "pty",
+ "selinux",
+ "util",
+ "utmp",
+ NULL
+};
+
+#define NUM_DEF_SUBSYSTEMS (nitems(sudo_debug_default_subsystems) - 1)
+
+/*
+ * For multiple programs/plugins there is a per-program instance
+ * and one or more outputs (files).
+ */
+struct sudo_debug_output {
+ SLIST_ENTRY(sudo_debug_output) entries;
+ char *filename;
+ int *settings;
+ int fd;
+};
+SLIST_HEAD(sudo_debug_output_list, sudo_debug_output);
+struct sudo_debug_instance {
+ char *program;
+ const char *const *subsystems;
+ const unsigned int *subsystem_ids;
+ unsigned int max_subsystem;
+ struct sudo_debug_output_list outputs;
+};
+
+/* Support up to 10 instances. */
+#define SUDO_DEBUG_INSTANCE_MAX 10
+static struct sudo_debug_instance *sudo_debug_instances[SUDO_DEBUG_INSTANCE_MAX];
+static int sudo_debug_last_instance = -1;
+
+static char sudo_debug_pidstr[(((sizeof(int) * 8) + 2) / 3) + 3];
+static size_t sudo_debug_pidlen;
+
+#define round_nfds(_n) (((_n) + (4 * NBBY) - 1) & ~((4 * NBBY) - 1))
+static int sudo_debug_fds_size;
+static unsigned char *sudo_debug_fds;
+static int sudo_debug_max_fd = -1;
+
+/* Default instance index to use for common utility functions. */
+static int sudo_debug_active_instance = -1;
+
+/*
+ * Free the specified output structure.
+ */
+static void
+sudo_debug_free_output(struct sudo_debug_output *output)
+{
+ free(output->filename);
+ free(output->settings);
+ if (output->fd != -1)
+ close(output->fd);
+ free(output);
+}
+
+/*
+ * Create a new output file for the specified debug instance.
+ * Returns NULL if the file cannot be opened or memory cannot be allocated.
+ */
+static struct sudo_debug_output *
+sudo_debug_new_output(struct sudo_debug_instance *instance,
+ struct sudo_debug_file *debug_file)
+{
+ char *buf, *cp, *last, *subsys, *pri;
+ struct sudo_debug_output *output;
+ unsigned int j;
+ int i;
+
+ /* Create new output for the instance. */
+ /* XXX - reuse fd for existing filename? */
+ output = calloc(1, sizeof(*output));
+ if (output == NULL)
+ goto bad;
+ output->fd = -1;
+ output->settings = reallocarray(NULL, instance->max_subsystem + 1,
+ sizeof(int));
+ if (output->settings == NULL)
+ goto bad;
+ output->filename = strdup(debug_file->debug_file);
+ if (output->filename == NULL)
+ goto bad;
+ output->fd = -1;
+
+ /* Init per-subsystems settings to -1 since 0 is a valid priority. */
+ for (j = 0; j <= instance->max_subsystem; j++)
+ output->settings[j] = -1;
+
+ /* Open debug file. */
+ output->fd = open(output->filename, O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR);
+ if (output->fd == -1) {
+ /* Create debug file as needed and set group ownership. */
+ if (errno == ENOENT) {
+ output->fd = open(output->filename, O_WRONLY|O_APPEND|O_CREAT,
+ S_IRUSR|S_IWUSR);
+ }
+ if (output->fd == -1)
+ goto bad;
+ ignore_result(fchown(output->fd, (uid_t)-1, 0));
+ }
+ (void)fcntl(output->fd, F_SETFD, FD_CLOEXEC);
+ if (sudo_debug_fds_size < output->fd) {
+ /* Bump fds size to the next multiple of 4 * NBBY. */
+ const int old_size = sudo_debug_fds_size / NBBY;
+ const int new_size = round_nfds(output->fd + 1) / NBBY;
+ unsigned char *new_fds;
+
+ new_fds = realloc(sudo_debug_fds, new_size);
+ if (new_fds == NULL)
+ goto bad;
+ memset(new_fds + old_size, 0, new_size - old_size);
+ sudo_debug_fds = new_fds;
+ sudo_debug_fds_size = new_size * NBBY;
+ }
+ sudo_setbit(sudo_debug_fds, output->fd);
+ if (output->fd > sudo_debug_max_fd)
+ sudo_debug_max_fd = output->fd;
+
+ /* Parse Debug conf string. */
+ buf = strdup(debug_file->debug_flags);
+ if (buf == NULL)
+ goto bad;
+ for ((cp = strtok_r(buf, ",", &last)); cp != NULL; (cp = strtok_r(NULL, ",", &last))) {
+ /* Should be in the form subsys@pri. */
+ subsys = cp;
+ if ((pri = strchr(cp, '@')) == NULL)
+ continue;
+ *pri++ = '\0';
+
+ /* Look up priority and subsystem, fill in sudo_debug_settings[]. */
+ for (i = 0; sudo_debug_priorities[i] != NULL; i++) {
+ if (strcasecmp(pri, sudo_debug_priorities[i]) == 0) {
+ for (j = 0; instance->subsystems[j] != NULL; j++) {
+ if (strcasecmp(subsys, "all") == 0) {
+ const unsigned int idx = instance->subsystem_ids ?
+ SUDO_DEBUG_SUBSYS(instance->subsystem_ids[j]) : j;
+ if (i > output->settings[idx])
+ output->settings[idx] = i;
+ continue;
+ }
+ if (strcasecmp(subsys, instance->subsystems[j]) == 0) {
+ const unsigned int idx = instance->subsystem_ids ?
+ SUDO_DEBUG_SUBSYS(instance->subsystem_ids[j]) : j;
+ if (i > output->settings[idx])
+ output->settings[idx] = i;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ free(buf);
+
+ return output;
+bad:
+ sudo_warn_nodebug(NULL);
+ if (output != NULL)
+ sudo_debug_free_output(output);
+ return NULL;
+}
+
+/*
+ * Register a program/plugin with the debug framework,
+ * parses settings string from sudo.conf and opens debug_files.
+ * If subsystem names are specified they override the default values.
+ * NOTE: subsystems must not be freed by caller unless deregistered.
+ * Sets the active instance to the newly registered instance.
+ * Returns instance index on success, SUDO_DEBUG_INSTANCE_INITIALIZER
+ * if no debug files are specified and SUDO_DEBUG_INSTANCE_ERROR
+ * on error.
+ */
+int
+sudo_debug_register_v1(const char *program, const char *const subsystems[],
+ unsigned int ids[], struct sudo_conf_debug_file_list *debug_files)
+{
+ struct sudo_debug_instance *instance = NULL;
+ struct sudo_debug_output *output;
+ struct sudo_debug_file *debug_file;
+ int idx, free_idx = -1;
+ debug_decl_func(sudo_debug_register);
+
+ if (debug_files == NULL)
+ return SUDO_DEBUG_INSTANCE_INITIALIZER;
+
+ /* Use default subsystem names if none are provided. */
+ if (subsystems == NULL) {
+ subsystems = sudo_debug_default_subsystems;
+ } else if (ids == NULL) {
+ /* If subsystems are specified we must have ids[] too. */
+ return SUDO_DEBUG_INSTANCE_ERROR;
+ }
+
+ /* Search for existing instance. */
+ for (idx = 0; idx <= sudo_debug_last_instance; idx++) {
+ if (sudo_debug_instances[idx] == NULL) {
+ free_idx = idx;
+ continue;
+ }
+ if (sudo_debug_instances[idx]->subsystems == subsystems &&
+ strcmp(sudo_debug_instances[idx]->program, program) == 0) {
+ instance = sudo_debug_instances[idx];
+ break;
+ }
+ }
+
+ if (instance == NULL) {
+ unsigned int i, j, max_id = NUM_DEF_SUBSYSTEMS - 1;
+
+ /* Fill in subsystem name -> id mapping as needed. */
+ if (ids != NULL) {
+ for (i = 0; subsystems[i] != NULL; i++) {
+ /* Check default subsystems. */
+ for (j = 0; j < NUM_DEF_SUBSYSTEMS; j++) {
+ if (strcmp(subsystems[i], sudo_debug_default_subsystems[j]) == 0)
+ break;
+ }
+ if (j == NUM_DEF_SUBSYSTEMS)
+ j = ++max_id;
+ ids[i] = ((j + 1) << 6);
+ }
+ }
+
+ if (free_idx != -1)
+ idx = free_idx;
+ if (idx == SUDO_DEBUG_INSTANCE_MAX) {
+ /* XXX - realloc? */
+ sudo_warnx_nodebug("too many debug instances (max %d)", SUDO_DEBUG_INSTANCE_MAX);
+ return SUDO_DEBUG_INSTANCE_ERROR;
+ }
+ if (idx != sudo_debug_last_instance + 1 && idx != free_idx) {
+ sudo_warnx_nodebug("%s: instance number mismatch: expected %d or %d, got %d", __func__, sudo_debug_last_instance + 1, free_idx, idx);
+ return SUDO_DEBUG_INSTANCE_ERROR;
+ }
+ if ((instance = malloc(sizeof(*instance))) == NULL)
+ return SUDO_DEBUG_INSTANCE_ERROR;
+ if ((instance->program = strdup(program)) == NULL) {
+ free(instance);
+ return SUDO_DEBUG_INSTANCE_ERROR;
+ }
+ instance->subsystems = subsystems;
+ instance->subsystem_ids = ids;
+ instance->max_subsystem = max_id;
+ SLIST_INIT(&instance->outputs);
+ sudo_debug_instances[idx] = instance;
+ if (idx != free_idx)
+ sudo_debug_last_instance++;
+ } else {
+ /* Check for matching instance but different ids[]. */
+ if (ids != NULL && instance->subsystem_ids != ids) {
+ unsigned int i;
+
+ for (i = 0; subsystems[i] != NULL; i++)
+ ids[i] = instance->subsystem_ids[i];
+ }
+ }
+
+ TAILQ_FOREACH(debug_file, debug_files, entries) {
+ output = sudo_debug_new_output(instance, debug_file);
+ if (output != NULL)
+ SLIST_INSERT_HEAD(&instance->outputs, output, entries);
+ }
+
+ /* Set active instance. */
+ sudo_debug_active_instance = idx;
+
+ /* Stash the pid string so we only have to format it once. */
+ if (sudo_debug_pidlen == 0) {
+ (void)snprintf(sudo_debug_pidstr, sizeof(sudo_debug_pidstr), "[%d] ",
+ (int)getpid());
+ sudo_debug_pidlen = strlen(sudo_debug_pidstr);
+ }
+
+ return idx;
+}
+
+/*
+ * De-register the specified instance from the debug subsystem
+ * and free up any associated data structures.
+ */
+int
+sudo_debug_deregister_v1(int idx)
+{
+ struct sudo_debug_instance *instance;
+ struct sudo_debug_output *output, *next;
+ debug_decl_func(sudo_debug_deregister);
+
+ if (idx < 0 || idx > sudo_debug_last_instance) {
+ sudo_warnx_nodebug("%s: invalid instance ID %d, max %d",
+ __func__, idx, sudo_debug_last_instance);
+ return -1;
+ }
+ /* Reset active instance as needed. */
+ if (sudo_debug_active_instance == idx)
+ sudo_debug_active_instance = -1;
+
+ instance = sudo_debug_instances[idx];
+ if (instance == NULL)
+ return -1; /* already deregistered */
+
+ /* Free up instance data, note that subsystems[] is owned by caller. */
+ sudo_debug_instances[idx] = NULL;
+ SLIST_FOREACH_SAFE(output, &instance->outputs, entries, next) {
+ close(output->fd);
+ free(output->filename);
+ free(output->settings);
+ free(output);
+ }
+ free(instance->program);
+ free(instance);
+
+ if (idx == sudo_debug_last_instance)
+ sudo_debug_last_instance--;
+
+ return 0;
+}
+
+int
+sudo_debug_get_instance_v1(const char *program)
+{
+ int idx;
+
+ for (idx = 0; idx <= sudo_debug_last_instance; idx++) {
+ if (sudo_debug_instances[idx] == NULL)
+ continue;
+ if (strcmp(sudo_debug_instances[idx]->program, program) == 0)
+ return idx;
+ }
+ return SUDO_DEBUG_INSTANCE_INITIALIZER;
+}
+
+pid_t
+sudo_debug_fork_v1(void)
+{
+ pid_t pid;
+
+ if ((pid = fork()) == 0) {
+ (void)snprintf(sudo_debug_pidstr, sizeof(sudo_debug_pidstr), "[%d] ",
+ (int)getpid());
+ sudo_debug_pidlen = strlen(sudo_debug_pidstr);
+ }
+
+ return pid;
+}
+
+void
+sudo_debug_enter_v1(const char *func, const char *file, int line,
+ int subsys)
+{
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "-> %s @ %s:%d", func, file, line);
+}
+
+void
+sudo_debug_exit_v1(const char *func, const char *file, int line,
+ int subsys)
+{
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "<- %s @ %s:%d", func, file, line);
+}
+
+void
+sudo_debug_exit_int_v1(const char *func, const char *file, int line,
+ int subsys, int ret)
+{
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "<- %s @ %s:%d := %d", func, file, line, ret);
+}
+
+void
+sudo_debug_exit_long_v1(const char *func, const char *file, int line,
+ int subsys, long ret)
+{
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "<- %s @ %s:%d := %ld", func, file, line, ret);
+}
+
+void
+sudo_debug_exit_id_t_v1(const char *func, const char *file, int line,
+ int subsys, id_t ret)
+{
+#if SIZEOF_ID_T == 8
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "<- %s @ %s:%d := %lld", func, file, line, (long long)ret);
+#else
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "<- %s @ %s:%d := %d", func, file, line, (int)ret);
+#endif
+}
+
+void
+sudo_debug_exit_size_t_v1(const char *func, const char *file, int line,
+ int subsys, size_t ret)
+{
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "<- %s @ %s:%d := %zu", func, file, line, ret);
+}
+
+void
+sudo_debug_exit_ssize_t_v1(const char *func, const char *file, int line,
+ int subsys, ssize_t ret)
+{
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "<- %s @ %s:%d := %zd", func, file, line, ret);
+}
+
+void
+sudo_debug_exit_time_t_v1(const char *func, const char *file, int line,
+ int subsys, time_t ret)
+{
+#if SIZEOF_TIME_T == 8
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "<- %s @ %s:%d := %lld", func, file, line, (long long)ret);
+#else
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "<- %s @ %s:%d := %d", func, file, line, (int)ret);
+#endif
+}
+
+void
+sudo_debug_exit_bool_v1(const char *func, const char *file, int line,
+ int subsys, bool ret)
+{
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "<- %s @ %s:%d := %s", func, file, line, ret ? "true" : "false");
+}
+
+void
+sudo_debug_exit_str_v1(const char *func, const char *file, int line,
+ int subsys, const char *ret)
+{
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "<- %s @ %s:%d := %s", func, file, line, ret ? ret : "(null)");
+}
+
+void
+sudo_debug_exit_str_masked_v1(const char *func, const char *file, int line,
+ int subsys, const char *ret)
+{
+ static const char stars[] = "********************************************************************************";
+ int len = ret ? strlen(ret) : sizeof("(null)") - 1;
+
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "<- %s @ %s:%d := %.*s", func, file, line, len, ret ? stars : "(null)");
+}
+
+void
+sudo_debug_exit_ptr_v1(const char *func, const char *file, int line,
+ int subsys, const void *ret)
+{
+ sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
+ "<- %s @ %s:%d := %p", func, file, line, ret);
+}
+
+void
+sudo_debug_write2_v1(int fd, const char *func, const char *file, int lineno,
+ const char *str, int len, int errnum)
+{
+ char *timestr, numbuf[(((sizeof(int) * 8) + 2) / 3) + 2];
+ time_t now;
+ struct iovec iov[12];
+ int iovcnt = 3;
+
+ /* Prepend program name and pid with a trailing space. */
+ iov[1].iov_base = (char *)getprogname();
+ iov[1].iov_len = strlen(iov[1].iov_base);
+ iov[2].iov_base = sudo_debug_pidstr;
+ iov[2].iov_len = sudo_debug_pidlen;
+
+ /* Add string, trimming any trailing newlines. */
+ while (len > 0 && str[len - 1] == '\n')
+ len--;
+ if (len > 0) {
+ iov[iovcnt].iov_base = (char *)str;
+ iov[iovcnt].iov_len = len;
+ iovcnt++;
+ }
+
+ /* Append error string if errno is specified. */
+ if (errnum) {
+ if (len > 0) {
+ iov[iovcnt].iov_base = ": ";
+ iov[iovcnt].iov_len = 2;
+ iovcnt++;
+ }
+ iov[iovcnt].iov_base = strerror(errnum);
+ iov[iovcnt].iov_len = strlen(iov[iovcnt].iov_base);
+ iovcnt++;
+ }
+
+ /* If function, file and lineno are specified, append them. */
+ if (func != NULL && file != NULL && lineno != 0) {
+ iov[iovcnt].iov_base = " @ ";
+ iov[iovcnt].iov_len = 3;
+ iovcnt++;
+
+ iov[iovcnt].iov_base = (char *)func;
+ iov[iovcnt].iov_len = strlen(func);
+ iovcnt++;
+
+ iov[iovcnt].iov_base = "() ";
+ iov[iovcnt].iov_len = 3;
+ iovcnt++;
+
+ iov[iovcnt].iov_base = (char *)file;
+ iov[iovcnt].iov_len = strlen(file);
+ iovcnt++;
+
+ (void)snprintf(numbuf, sizeof(numbuf), ":%d", lineno);
+ iov[iovcnt].iov_base = numbuf;
+ iov[iovcnt].iov_len = strlen(numbuf);
+ iovcnt++;
+ }
+
+ /* Append newline. */
+ iov[iovcnt].iov_base = "\n";
+ iov[iovcnt].iov_len = 1;
+ iovcnt++;
+
+ /* Do timestamp last due to ctime's static buffer. */
+ time(&now);
+ timestr = ctime(&now) + 4;
+ timestr[15] = ' '; /* replace year with a space */
+ timestr[16] = '\0';
+ iov[0].iov_base = timestr;
+ iov[0].iov_len = 16;
+
+ /* Write message in a single syscall */
+ ignore_result(writev(fd, iov, iovcnt));
+}
+
+void
+sudo_debug_vprintf2_v1(const char *func, const char *file, int lineno, int level,
+ const char *fmt, va_list ap)
+{
+ int buflen, pri, saved_errno = errno;
+ unsigned int subsys;
+ char static_buf[1024], *buf = static_buf;
+ struct sudo_debug_instance *instance;
+ struct sudo_debug_output *output;
+ debug_decl_func(sudo_debug_vprintf2);
+
+ if (sudo_debug_active_instance == -1)
+ goto out;
+
+ /* Extract priority and subsystem from level. */
+ pri = SUDO_DEBUG_PRI(level);
+ subsys = SUDO_DEBUG_SUBSYS(level);
+
+ /* Find matching instance. */
+ if (sudo_debug_active_instance > sudo_debug_last_instance) {
+ sudo_warnx_nodebug("%s: invalid instance ID %d, max %d",
+ __func__, sudo_debug_active_instance, sudo_debug_last_instance);
+ goto out;
+ }
+ instance = sudo_debug_instances[sudo_debug_active_instance];
+ if (instance == NULL) {
+ sudo_warnx_nodebug("%s: unregistered instance index %d", __func__,
+ sudo_debug_active_instance);
+ goto out;
+ }
+
+ SLIST_FOREACH(output, &instance->outputs, entries) {
+ /* Make sure we want debug info at this level. */
+ if (subsys <= instance->max_subsystem && output->settings[subsys] >= pri) {
+ va_list ap2;
+
+ /* Operate on a copy of ap to support multiple outputs. */
+ va_copy(ap2, ap);
+ buflen = fmt ? vsnprintf(static_buf, sizeof(static_buf), fmt, ap2) : 0;
+ va_end(ap2);
+ if (buflen >= (int)sizeof(static_buf)) {
+ va_list ap3;
+
+ /* Not enough room in static buf, allocate dynamically. */
+ va_copy(ap3, ap);
+ buflen = vasprintf(&buf, fmt, ap3);
+ va_end(ap3);
+ }
+ if (buflen != -1) {
+ int errcode = ISSET(level, SUDO_DEBUG_ERRNO) ? saved_errno : 0;
+ if (ISSET(level, SUDO_DEBUG_LINENO))
+ sudo_debug_write2(output->fd, func, file, lineno, buf, buflen, errcode);
+ else
+ sudo_debug_write2(output->fd, NULL, NULL, 0, buf, buflen, errcode);
+ if (buf != static_buf) {
+ free(buf);
+ buf = static_buf;
+ }
+ }
+ }
+ }
+out:
+ errno = saved_errno;
+}
+
+#ifdef NO_VARIADIC_MACROS
+void
+sudo_debug_printf_nvm_v1(int pri, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ sudo_debug_vprintf2(NULL, NULL, 0, pri, fmt, ap);
+ va_end(ap);
+}
+#endif /* NO_VARIADIC_MACROS */
+
+void
+sudo_debug_printf2_v1(const char *func, const char *file, int lineno, int level,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ sudo_debug_vprintf2(func, file, lineno, level, fmt, ap);
+ va_end(ap);
+}
+
+#define EXEC_PREFIX "exec "
+
+void
+sudo_debug_execve2_v1(int level, const char *path, char *const argv[], char *const envp[])
+{
+ int buflen, pri, saved_errno = errno;
+ unsigned int subsys;
+ struct sudo_debug_instance *instance;
+ struct sudo_debug_output *output;
+ char * const *av;
+ char *cp, static_buf[4096], *buf = static_buf;
+ size_t plen;
+ debug_decl_func(sudo_debug_execve2);
+
+ if (sudo_debug_active_instance == -1)
+ goto out;
+
+ /* Extract priority and subsystem from level. */
+ pri = SUDO_DEBUG_PRI(level);
+ subsys = SUDO_DEBUG_SUBSYS(level);
+
+ /* Find matching instance. */
+ if (sudo_debug_active_instance > sudo_debug_last_instance) {
+ sudo_warnx_nodebug("%s: invalid instance ID %d, max %d",
+ __func__, sudo_debug_active_instance, sudo_debug_last_instance);
+ goto out;
+ }
+ instance = sudo_debug_instances[sudo_debug_active_instance];
+ if (instance == NULL) {
+ sudo_warnx_nodebug("%s: unregistered instance index %d", __func__,
+ sudo_debug_active_instance);
+ goto out;
+ }
+ if (subsys > instance->max_subsystem)
+ goto out;
+
+ SLIST_FOREACH(output, &instance->outputs, entries) {
+ bool log_envp = false;
+
+ /* Make sure we want debug info at this level. */
+ if (output->settings[subsys] < pri)
+ continue;
+
+ /* Log envp for debug level "debug". */
+ if (output->settings[subsys] >= SUDO_DEBUG_DEBUG - 1 && envp[0] != NULL)
+ log_envp = true;
+
+ /* Alloc and build up buffer. */
+ plen = strlen(path);
+ buflen = sizeof(EXEC_PREFIX) -1 + plen;
+ if (argv[0] != NULL) {
+ buflen += sizeof(" []") - 1;
+ for (av = argv; *av; av++)
+ buflen += strlen(*av) + 1;
+ buflen--;
+ }
+ if (log_envp) {
+ buflen += sizeof(" []") - 1;
+ for (av = envp; *av; av++)
+ buflen += strlen(*av) + 1;
+ buflen--;
+ }
+ if (buflen >= (int)sizeof(static_buf)) {
+ buf = malloc(buflen + 1);
+ if (buf == NULL)
+ goto out;
+ }
+
+ /* Copy prefix and command. */
+ memcpy(buf, EXEC_PREFIX, sizeof(EXEC_PREFIX) - 1);
+ cp = buf + sizeof(EXEC_PREFIX) - 1;
+ memcpy(cp, path, plen);
+ cp += plen;
+
+ /* Copy argv. */
+ if (argv[0] != NULL) {
+ *cp++ = ' ';
+ *cp++ = '[';
+ for (av = argv; *av; av++) {
+ size_t avlen = strlen(*av);
+ memcpy(cp, *av, avlen);
+ cp += avlen;
+ *cp++ = ' ';
+ }
+ cp[-1] = ']';
+ }
+
+ if (log_envp) {
+ *cp++ = ' ';
+ *cp++ = '[';
+ for (av = envp; *av; av++) {
+ size_t avlen = strlen(*av);
+ memcpy(cp, *av, avlen);
+ cp += avlen;
+ *cp++ = ' ';
+ }
+ cp[-1] = ']';
+ }
+
+ *cp = '\0';
+
+ sudo_debug_write(output->fd, buf, buflen, 0);
+ if (buf != static_buf) {
+ free(buf);
+ buf = static_buf;
+ }
+ }
+out:
+ errno = saved_errno;
+}
+
+/*
+ * Returns the active instance or SUDO_DEBUG_INSTANCE_INITIALIZER
+ * if no instance is active.
+ */
+int
+sudo_debug_get_active_instance_v1(void)
+{
+ return sudo_debug_active_instance;
+}
+
+/*
+ * Sets a new active instance, returning the old one.
+ * Note that the old instance may be SUDO_DEBUG_INSTANCE_INITIALIZER
+ * if this is the only instance.
+ */
+int
+sudo_debug_set_active_instance_v1(int idx)
+{
+ const int old_idx = sudo_debug_active_instance;
+
+ if (idx >= -1 && idx <= sudo_debug_last_instance)
+ sudo_debug_active_instance = idx;
+ return old_idx;
+}
+
+/*
+ * Replace the ofd with nfd in all outputs if present.
+ * Also updates sudo_debug_fds.
+ */
+void
+sudo_debug_update_fd_v1(int ofd, int nfd)
+{
+ int idx;
+
+ if (ofd <= sudo_debug_max_fd && sudo_isset(sudo_debug_fds, ofd)) {
+ /* Update sudo_debug_fds. */
+ sudo_clrbit(sudo_debug_fds, ofd);
+ sudo_setbit(sudo_debug_fds, nfd);
+
+ /* Update the outputs. */
+ for (idx = 0; idx <= sudo_debug_last_instance; idx++) {
+ struct sudo_debug_instance *instance;
+ struct sudo_debug_output *output;
+
+ instance = sudo_debug_instances[idx];
+ if (instance == NULL)
+ continue;
+ SLIST_FOREACH(output, &instance->outputs, entries) {
+ if (output->fd == ofd)
+ output->fd = nfd;
+ }
+ }
+ }
+}
+
+/*
+ * Returns the highest debug output fd or -1 if no debug files open.
+ * Fills in fds with the value of sudo_debug_fds.
+ */
+int
+sudo_debug_get_fds_v1(unsigned char **fds)
+{
+ *fds = sudo_debug_fds;
+ return sudo_debug_max_fd;
+}
diff --git a/lib/util/sudo_dso.c b/lib/util/sudo_dso.c
new file mode 100644
index 0000000..39d4381
--- /dev/null
+++ b/lib/util/sudo_dso.c
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2010, 2012-2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#if defined(HAVE_SHL_LOAD)
+# include <dl.h>
+#elif defined(HAVE_DLOPEN)
+# include <dlfcn.h>
+#endif
+#include <errno.h>
+
+#include "sudo_compat.h"
+#include "sudo_dso.h"
+
+/*
+ * Pointer for statically compiled symbols.
+ */
+static struct sudo_preload_table *preload_table;
+
+void
+sudo_dso_preload_table_v1(struct sudo_preload_table *table)
+{
+ preload_table = table;
+}
+
+#if defined(HAVE_SHL_LOAD)
+
+# ifndef DYNAMIC_PATH
+# define DYNAMIC_PATH 0
+# endif
+
+void *
+sudo_dso_load_v1(const char *path, int mode)
+{
+ struct sudo_preload_table *pt;
+ int flags = DYNAMIC_PATH | BIND_VERBOSE;
+
+ if (mode == 0)
+ mode = SUDO_DSO_LAZY; /* default behavior */
+
+ /* Check prelinked symbols first. */
+ if (preload_table != NULL) {
+ for (pt = preload_table; pt->handle != NULL; pt++) {
+ if (pt->path != NULL && strcmp(path, pt->path) == 0)
+ return pt->handle;
+ }
+ }
+
+ /* We don't support SUDO_DSO_GLOBAL or SUDO_DSO_LOCAL yet. */
+ if (ISSET(mode, SUDO_DSO_LAZY))
+ flags |= BIND_DEFERRED;
+ if (ISSET(mode, SUDO_DSO_NOW))
+ flags |= BIND_IMMEDIATE;
+
+ return (void *)shl_load(path, flags, 0L);
+}
+
+int
+sudo_dso_unload_v1(void *handle)
+{
+ struct sudo_preload_table *pt;
+
+ /* Check prelinked symbols first. */
+ if (preload_table != NULL) {
+ for (pt = preload_table; pt->handle != NULL; pt++) {
+ if (pt->handle == handle)
+ return 0;
+ }
+ }
+
+ return shl_unload((shl_t)handle);
+}
+
+void *
+sudo_dso_findsym_v1(void *vhandle, const char *symbol)
+{
+ struct sudo_preload_table *pt;
+ shl_t handle = vhandle;
+ void *value = NULL;
+
+ /* Check prelinked symbols first. */
+ if (preload_table != NULL) {
+ for (pt = preload_table; pt->handle != NULL; pt++) {
+ if (pt->handle == handle) {
+ struct sudo_preload_symbol *sym;
+ for (sym = pt->symbols; sym->name != NULL; sym++) {
+ if (strcmp(sym->name, symbol) == 0)
+ return sym->addr;
+ }
+ errno = ENOENT;
+ return NULL;
+ }
+ }
+ }
+
+ /*
+ * Note that the behavior of of SUDO_DSO_NEXT and SUDO_DSO_SELF
+ * differs from most implementations when called from
+ * a shared library.
+ */
+ if (vhandle == SUDO_DSO_NEXT) {
+ /* Iterate over all shared libs looking for symbol. */
+ shl_t myhandle = PROG_HANDLE;
+ struct shl_descriptor *desc;
+ int idx = 0;
+
+ /* Find program's real handle. */
+ if (shl_gethandle(PROG_HANDLE, &desc) == 0)
+ myhandle = desc->handle;
+ while (shl_get(idx++, &desc) == 0) {
+ if (desc->handle == myhandle)
+ continue;
+ if (shl_findsym(&desc->handle, symbol, TYPE_UNDEFINED, &value) == 0)
+ break;
+ }
+ } else {
+ if (vhandle == SUDO_DSO_DEFAULT)
+ handle = NULL;
+ else if (vhandle == SUDO_DSO_SELF)
+ handle = PROG_HANDLE;
+ (void)shl_findsym(&handle, symbol, TYPE_UNDEFINED, &value);
+ }
+
+ return value;
+}
+
+char *
+sudo_dso_strerror_v1(void)
+{
+ return strerror(errno);
+}
+
+#elif defined(HAVE_DLOPEN)
+
+# ifndef RTLD_GLOBAL
+# define RTLD_GLOBAL 0
+# endif
+
+void *
+sudo_dso_load_v1(const char *path, int mode)
+{
+ struct sudo_preload_table *pt;
+ int flags = 0;
+
+ /* Check prelinked symbols first. */
+ if (preload_table != NULL) {
+ for (pt = preload_table; pt->handle != NULL; pt++) {
+ if (pt->path != NULL && strcmp(path, pt->path) == 0)
+ return pt->handle;
+ }
+ }
+
+ /* Map SUDO_DSO_* -> RTLD_* */
+ if (ISSET(mode, SUDO_DSO_LAZY))
+ flags |= RTLD_LAZY;
+ if (ISSET(mode, SUDO_DSO_NOW))
+ flags |= RTLD_NOW;
+ if (ISSET(mode, SUDO_DSO_GLOBAL))
+ flags |= RTLD_GLOBAL;
+ if (ISSET(mode, SUDO_DSO_LOCAL))
+ flags |= RTLD_LOCAL;
+
+ return dlopen(path, flags);
+}
+
+int
+sudo_dso_unload_v1(void *handle)
+{
+ struct sudo_preload_table *pt;
+
+ /* Check prelinked symbols first. */
+ if (preload_table != NULL) {
+ for (pt = preload_table; pt->handle != NULL; pt++) {
+ if (pt->handle == handle)
+ return 0;
+ }
+ }
+
+ return dlclose(handle);
+}
+
+void *
+sudo_dso_findsym_v1(void *handle, const char *symbol)
+{
+ struct sudo_preload_table *pt;
+
+ /* Check prelinked symbols first. */
+ if (preload_table != NULL) {
+ for (pt = preload_table; pt->handle != NULL; pt++) {
+ if (pt->handle == handle) {
+ struct sudo_preload_symbol *sym;
+ for (sym = pt->symbols; sym->name != NULL; sym++) {
+ if (strcmp(sym->name, symbol) == 0)
+ return sym->addr;
+ }
+ errno = ENOENT;
+ return NULL;
+ }
+ }
+ }
+
+ /*
+ * Not all implementations support the special handles.
+ */
+ if (handle == SUDO_DSO_NEXT) {
+# ifdef RTLD_NEXT
+ handle = RTLD_NEXT;
+# else
+ errno = ENOENT;
+ return NULL;
+# endif
+ } else if (handle == SUDO_DSO_DEFAULT) {
+# ifdef RTLD_DEFAULT
+ handle = RTLD_DEFAULT;
+# else
+ errno = ENOENT;
+ return NULL;
+# endif
+ } else if (handle == SUDO_DSO_SELF) {
+# ifdef RTLD_SELF
+ handle = RTLD_SELF;
+# else
+ errno = ENOENT;
+ return NULL;
+# endif
+ }
+
+ return dlsym(handle, symbol);
+}
+
+char *
+sudo_dso_strerror_v1(void)
+{
+ return dlerror();
+}
+
+#else /* !HAVE_SHL_LOAD && !HAVE_DLOPEN */
+
+/*
+ * Emulate dlopen() using a static list of symbols compiled into sudo.
+ */
+void *
+sudo_dso_load_v1(const char *path, int mode)
+{
+ struct sudo_preload_table *pt;
+
+ /* Check prelinked symbols first. */
+ if (preload_table != NULL) {
+ for (pt = preload_table; pt->handle != NULL; pt++) {
+ if (pt->path != NULL && strcmp(path, pt->path) == 0)
+ return pt->handle;
+ }
+ }
+ return NULL;
+}
+
+int
+sudo_dso_unload_v1(void *handle)
+{
+ struct sudo_preload_table *pt;
+
+ if (preload_table != NULL) {
+ for (pt = preload_table; pt->handle != NULL; pt++) {
+ if (pt->handle == handle)
+ return 0;
+ }
+ }
+ return -1;
+}
+
+void *
+sudo_dso_findsym_v1(void *handle, const char *symbol)
+{
+ struct sudo_preload_table *pt;
+
+ if (preload_table != NULL) {
+ for (pt = preload_table; pt->handle != NULL; pt++) {
+ if (pt->handle == handle) {
+ struct sudo_preload_symbol *sym;
+ for (sym = pt->symbols; sym->name != NULL; sym++) {
+ if (strcmp(sym->name, symbol) == 0)
+ return sym->addr;
+ }
+ }
+ }
+ }
+ errno = ENOENT;
+ return NULL;
+}
+
+char *
+sudo_dso_strerror_v1(void)
+{
+ return strerror(errno);
+}
+#endif /* !HAVE_SHL_LOAD && !HAVE_DLOPEN */
diff --git a/lib/util/term.c b/lib/util/term.c
new file mode 100644
index 0000000..5151ffd
--- /dev/null
+++ b/lib/util/term.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2011-2015, 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <errno.h>
+#include <signal.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+/* TCSASOFT is a BSD extension that ignores control flags and speed. */
+#ifndef TCSASOFT
+# define TCSASOFT 0
+#endif
+
+/* Non-standard termios input flags */
+#ifndef IUCLC
+# define IUCLC 0
+#endif
+#ifndef IMAXBEL
+# define IMAXBEL 0
+#endif
+#ifndef IUTF8
+# define IUTF8 0
+#endif
+
+/* Non-standard termios output flags */
+#ifndef OLCUC
+# define OLCUC 0
+#endif
+#ifndef ONLCR
+# define ONLCR 0
+#endif
+#ifndef OCRNL
+# define OCRNL 0
+#endif
+#ifndef ONOCR
+# define ONOCR 0
+#endif
+#ifndef ONLRET
+# define ONLRET 0
+#endif
+
+/* Non-standard termios local flags */
+#ifndef XCASE
+# define XCASE 0
+#endif
+#ifndef IEXTEN
+# define IEXTEN 0
+#endif
+#ifndef ECHOCTL
+# define ECHOCTL 0
+#endif
+#ifndef ECHOKE
+# define ECHOKE 0
+#endif
+#ifndef PENDIN
+# define PENDIN 0
+#endif
+
+#ifndef _POSIX_VDISABLE
+# ifdef VDISABLE
+# define _POSIX_VDISABLE VDISABLE
+# else
+# define _POSIX_VDISABLE 0
+# endif
+#endif
+
+static struct termios term, oterm;
+static int changed;
+
+/* tgetpass() needs to know the erase and kill chars for cbreak mode. */
+__dso_public int sudo_term_eof;
+__dso_public int sudo_term_erase;
+__dso_public int sudo_term_kill;
+
+static volatile sig_atomic_t got_sigttou;
+
+/*
+ * SIGTTOU signal handler for term_restore that just sets a flag.
+ */
+static void
+sigttou(int signo)
+{
+ got_sigttou = 1;
+}
+
+/*
+ * Like tcsetattr() but restarts on EINTR _except_ for SIGTTOU.
+ * Returns 0 on success or -1 on failure, setting errno.
+ * Sets got_sigttou on failure if interrupted by SIGTTOU.
+ */
+static int
+tcsetattr_nobg(int fd, int flags, struct termios *tp)
+{
+ struct sigaction sa, osa;
+ int rc;
+
+ /*
+ * If we receive SIGTTOU from tcsetattr() it means we are
+ * not in the foreground process group.
+ * This should be less racy than using tcgetpgrp().
+ */
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = sigttou;
+ got_sigttou = 0;
+ sigaction(SIGTTOU, &sa, &osa);
+ do {
+ rc = tcsetattr(fd, flags, tp);
+ } while (rc != 0 && errno == EINTR && !got_sigttou);
+ sigaction(SIGTTOU, &osa, NULL);
+
+ return rc;
+}
+
+/*
+ * Restore saved terminal settings if we are in the foreground process group.
+ * Returns true on success or false on failure.
+ */
+bool
+sudo_term_restore_v1(int fd, bool flush)
+{
+ debug_decl(sudo_term_restore, SUDO_DEBUG_UTIL)
+
+ if (changed) {
+ const int flags = flush ? (TCSASOFT|TCSAFLUSH) : (TCSASOFT|TCSADRAIN);
+ if (tcsetattr_nobg(fd, flags, &oterm) != 0)
+ debug_return_bool(false);
+ changed = 0;
+ }
+ debug_return_bool(true);
+}
+
+/*
+ * Disable terminal echo.
+ * Returns true on success or false on failure.
+ */
+bool
+sudo_term_noecho_v1(int fd)
+{
+ debug_decl(sudo_term_noecho, SUDO_DEBUG_UTIL)
+
+ if (!changed && tcgetattr(fd, &oterm) != 0)
+ debug_return_bool(false);
+ (void) memcpy(&term, &oterm, sizeof(term));
+ CLR(term.c_lflag, ECHO|ECHONL);
+#ifdef VSTATUS
+ term.c_cc[VSTATUS] = _POSIX_VDISABLE;
+#endif
+ if (tcsetattr_nobg(fd, TCSASOFT|TCSADRAIN, &term) == 0) {
+ changed = 1;
+ debug_return_bool(true);
+ }
+ debug_return_bool(false);
+}
+
+/*
+ * Set terminal to raw mode.
+ * Returns true on success or false on failure.
+ */
+bool
+sudo_term_raw_v1(int fd, int isig)
+{
+ struct termios term;
+ debug_decl(sudo_term_raw, SUDO_DEBUG_UTIL)
+
+ if (!changed && tcgetattr(fd, &oterm) != 0)
+ debug_return_bool(false);
+ (void) memcpy(&term, &oterm, sizeof(term));
+ /* Set terminal to raw mode */
+ term.c_cc[VMIN] = 1;
+ term.c_cc[VTIME] = 0;
+ CLR(term.c_iflag, ICRNL | IGNCR | INLCR | IUCLC | IXON);
+ CLR(term.c_oflag, OPOST);
+ CLR(term.c_lflag, ECHO | ICANON | ISIG | IEXTEN);
+ if (isig)
+ SET(term.c_lflag, ISIG);
+ if (tcsetattr_nobg(fd, TCSASOFT|TCSADRAIN, &term) == 0) {
+ changed = 1;
+ debug_return_bool(true);
+ }
+ debug_return_bool(false);
+}
+
+/*
+ * Set terminal to cbreak mode.
+ * Returns true on success or false on failure.
+ */
+bool
+sudo_term_cbreak_v1(int fd)
+{
+ debug_decl(sudo_term_cbreak, SUDO_DEBUG_UTIL)
+
+ if (!changed && tcgetattr(fd, &oterm) != 0)
+ debug_return_bool(false);
+ (void) memcpy(&term, &oterm, sizeof(term));
+ /* Set terminal to half-cooked mode */
+ term.c_cc[VMIN] = 1;
+ term.c_cc[VTIME] = 0;
+ /* cppcheck-suppress redundantAssignment */
+ CLR(term.c_lflag, ECHO | ECHONL | ICANON | IEXTEN);
+ /* cppcheck-suppress redundantAssignment */
+ SET(term.c_lflag, ISIG);
+#ifdef VSTATUS
+ term.c_cc[VSTATUS] = _POSIX_VDISABLE;
+#endif
+ if (tcsetattr_nobg(fd, TCSASOFT|TCSADRAIN, &term) == 0) {
+ sudo_term_eof = term.c_cc[VEOF];
+ sudo_term_erase = term.c_cc[VERASE];
+ sudo_term_kill = term.c_cc[VKILL];
+ changed = 1;
+ debug_return_bool(true);
+ }
+ debug_return_bool(false);
+}
+
+/* Termios flags to copy between terminals. */
+#define INPUT_FLAGS (IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXANY|IXOFF|IMAXBEL|IUTF8)
+#define OUTPUT_FLAGS (OPOST|OLCUC|ONLCR|OCRNL|ONOCR|ONLRET)
+#define CONTROL_FLAGS (CS7|CS8|PARENB|PARODD)
+#define LOCAL_FLAGS (ISIG|ICANON|XCASE|ECHO|ECHOE|ECHOK|ECHONL|NOFLSH|TOSTOP|IEXTEN|ECHOCTL|ECHOKE|PENDIN)
+
+/*
+ * Copy terminal settings from one descriptor to another.
+ * We cannot simply copy the struct termios as src and dst may be
+ * different terminal types (pseudo-tty vs. console or glass tty).
+ * Returns true on success or false on failure.
+ */
+bool
+sudo_term_copy_v1(int src, int dst)
+{
+ struct termios tt_src, tt_dst;
+ struct winsize wsize;
+ speed_t speed;
+ int i;
+ debug_decl(sudo_term_copy, SUDO_DEBUG_UTIL)
+
+ if (tcgetattr(src, &tt_src) != 0 || tcgetattr(dst, &tt_dst) != 0)
+ debug_return_bool(false);
+
+ /* Clear select input, output, control and local flags. */
+ CLR(tt_dst.c_iflag, INPUT_FLAGS);
+ CLR(tt_dst.c_oflag, OUTPUT_FLAGS);
+ CLR(tt_dst.c_cflag, CONTROL_FLAGS);
+ CLR(tt_dst.c_lflag, LOCAL_FLAGS);
+
+ /* Copy select input, output, control and local flags. */
+ SET(tt_dst.c_iflag, (tt_src.c_iflag & INPUT_FLAGS));
+ SET(tt_dst.c_oflag, (tt_src.c_oflag & OUTPUT_FLAGS));
+ SET(tt_dst.c_cflag, (tt_src.c_cflag & CONTROL_FLAGS));
+ SET(tt_dst.c_lflag, (tt_src.c_lflag & LOCAL_FLAGS));
+
+ /* Copy special chars from src verbatim. */
+ for (i = 0; i < NCCS; i++)
+ tt_dst.c_cc[i] = tt_src.c_cc[i];
+
+ /* Copy speed from src (zero output speed closes the connection). */
+ if ((speed = cfgetospeed(&tt_src)) == B0)
+ speed = B38400;
+ cfsetospeed(&tt_dst, speed);
+ speed = cfgetispeed(&tt_src);
+ cfsetispeed(&tt_dst, speed);
+
+ if (tcsetattr_nobg(dst, TCSASOFT|TCSAFLUSH, &tt_dst) == -1)
+ debug_return_bool(false);
+
+ if (ioctl(src, TIOCGWINSZ, &wsize) == 0)
+ (void)ioctl(dst, TIOCSWINSZ, &wsize);
+
+ debug_return_bool(true);
+}
diff --git a/lib/util/ttyname_dev.c b/lib/util/ttyname_dev.c
new file mode 100644
index 0000000..3d8e20a
--- /dev/null
+++ b/lib/util/ttyname_dev.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2012-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#if defined(MAJOR_IN_MKDEV)
+# include <sys/mkdev.h>
+#elif defined(MAJOR_IN_SYSMACROS)
+# include <sys/sysmacros.h>
+#else
+# include <sys/param.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <dirent.h>
+
+#include <pathnames.h>
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_conf.h"
+#include "sudo_util.h"
+
+#if defined(HAVE_DEVNAME)
+/*
+ * Like ttyname() but uses a dev_t instead of an open fd.
+ * Returns name on success and NULL on failure, setting errno.
+ * The BSD version uses devname().
+ */
+char *
+sudo_ttyname_dev_v1(dev_t tdev, char *name, size_t namelen)
+{
+ char *dev;
+ debug_decl(sudo_ttyname_dev, SUDO_DEBUG_UTIL)
+
+ /* Some versions of devname() return NULL on failure, others do not. */
+ dev = devname(tdev, S_IFCHR);
+ if (dev != NULL && *dev != '?' && *dev != '#') {
+ if (strlcpy(name, _PATH_DEV, namelen) < namelen &&
+ strlcat(name, dev, namelen) < namelen)
+ debug_return_str(name);
+ errno = ERANGE;
+ } else {
+ /* Not all versions of devname() set errno. */
+ errno = ENOENT;
+ }
+ debug_return_str(NULL);
+}
+#elif defined(HAVE__TTYNAME_DEV)
+extern char *_ttyname_dev(dev_t rdev, char *buffer, size_t buflen);
+
+/*
+ * Like ttyname() but uses a dev_t instead of an open fd.
+ * Returns name on success and NULL on failure, setting errno.
+ * This version is just a wrapper around _ttyname_dev().
+ */
+char *
+sudo_ttyname_dev_v1(dev_t tdev, char *name, size_t namelen)
+{
+ int serrno = errno;
+ debug_decl(sudo_ttyname_dev, SUDO_DEBUG_UTIL)
+
+ /*
+ * _ttyname_dev() sets errno to ERANGE if namelen is too small
+ * but does not modify it if tdev is not found.
+ */
+ errno = ENOENT;
+ if (_ttyname_dev(tdev, name, namelen) == NULL)
+ debug_return_str(NULL);
+ errno = serrno;
+
+ debug_return_str(name);
+}
+#else
+/*
+ * Device nodes to ignore.
+ */
+static const char *ignore_devs[] = {
+ _PATH_DEV "stdin",
+ _PATH_DEV "stdout",
+ _PATH_DEV "stderr",
+ NULL
+};
+
+/*
+ * Do a scan of a directory looking for the specified device.
+ * Does not descend into subdirectories.
+ * Returns name on success and NULL on failure, setting errno.
+ */
+static char *
+sudo_ttyname_scan(const char *dir, dev_t rdev, char *name, size_t namelen)
+{
+ size_t sdlen;
+ char pathbuf[PATH_MAX];
+ char *ret = NULL;
+ struct dirent *dp;
+ struct stat sb;
+ unsigned int i;
+ DIR *d = NULL;
+ debug_decl(sudo_ttyname_scan, SUDO_DEBUG_UTIL)
+
+ if (dir[0] == '\0') {
+ errno = ENOENT;
+ goto done;
+ }
+ if ((d = opendir(dir)) == NULL)
+ goto done;
+
+ if (fstat(dirfd(d), &sb) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to fstat %s", dir);
+ goto done;
+ }
+ if ((sb.st_mode & S_IWOTH) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "ignoring world-writable directory %s", dir);
+ errno = ENOENT;
+ goto done;
+ }
+
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "scanning for dev %u in %s", (unsigned int)rdev, dir);
+
+ sdlen = strlen(dir);
+ while (sdlen > 0 && dir[sdlen - 1] == '/')
+ sdlen--;
+ if (sdlen + 1 >= sizeof(pathbuf)) {
+ errno = ERANGE;
+ goto done;
+ }
+ memcpy(pathbuf, dir, sdlen);
+ pathbuf[sdlen++] = '/';
+
+ while ((dp = readdir(d)) != NULL) {
+ struct stat sb;
+
+ /* Skip anything starting with "." */
+ if (dp->d_name[0] == '.')
+ continue;
+
+ pathbuf[sdlen] = '\0';
+ if (strlcat(pathbuf, dp->d_name, sizeof(pathbuf)) >= sizeof(pathbuf)) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s%s is too big to fit in pathbuf", pathbuf, dp->d_name);
+ continue;
+ }
+
+ /* Ignore device nodes listed in ignore_devs[]. */
+ for (i = 0; ignore_devs[i] != NULL; i++) {
+ if (strcmp(pathbuf, ignore_devs[i]) == 0)
+ break;
+ }
+ if (ignore_devs[i] != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "ignoring %s", pathbuf);
+ continue;
+ }
+
+# if defined(HAVE_STRUCT_DIRENT_D_TYPE)
+ /*
+ * Avoid excessive stat() calls by checking dp->d_type.
+ */
+ switch (dp->d_type) {
+ case DT_CHR:
+ case DT_LNK:
+ case DT_UNKNOWN:
+ break;
+ default:
+ /* Not a character device or link, skip it. */
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "skipping non-device %s", pathbuf);
+ continue;
+ }
+# endif
+ if (stat(pathbuf, &sb) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "unable to stat %s", pathbuf);
+ continue;
+ }
+ if (S_ISCHR(sb.st_mode) && sb.st_rdev == rdev) {
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "resolved dev %u as %s", (unsigned int)rdev, pathbuf);
+ if (strlcpy(name, pathbuf, namelen) < namelen) {
+ ret = name;
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to store %s, have %zu, need %zu",
+ pathbuf, namelen, strlen(pathbuf) + 1);
+ errno = ERANGE;
+ }
+ goto done;
+ }
+ }
+
+done:
+ if (d != NULL)
+ closedir(d);
+ debug_return_str(ret);
+}
+
+static char *
+sudo_dev_check(dev_t rdev, const char *devname, char *buf, size_t buflen)
+{
+ struct stat sb;
+ debug_decl(sudo_dev_check, SUDO_DEBUG_UTIL)
+
+ if (stat(devname, &sb) == 0) {
+ if (S_ISCHR(sb.st_mode) && sb.st_rdev == rdev) {
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "comparing dev %u to %s: match!",
+ (unsigned int)rdev, devname);
+ if (strlcpy(buf, devname, buflen) < buflen)
+ debug_return_str(buf);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to store %s, have %zu, need %zu",
+ devname, buflen, strlen(devname) + 1);
+ errno = ERANGE;
+ }
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "comparing dev %u to %s: no", (unsigned int)rdev, devname);
+ debug_return_str(NULL);
+}
+
+/*
+ * Like ttyname() but uses a dev_t instead of an open fd.
+ * Returns name on success and NULL on failure, setting errno.
+ * Generic version.
+ */
+char *
+sudo_ttyname_dev_v1(dev_t rdev, char *buf, size_t buflen)
+{
+ const char *devsearch, *devsearch_end;
+ char path[PATH_MAX], *ret;
+ const char *cp, *ep;
+ size_t len;
+ debug_decl(sudo_ttyname_dev, SUDO_DEBUG_UTIL)
+
+ /*
+ * First, check /dev/console.
+ */
+ ret = sudo_dev_check(rdev, _PATH_DEV "console", buf, buflen);
+ if (ret != NULL)
+ goto done;
+
+ /*
+ * Then check the device search path.
+ */
+ devsearch = sudo_conf_devsearch_path();
+ devsearch_end = devsearch + strlen(devsearch);
+ for (cp = sudo_strsplit(devsearch, devsearch_end, ":", &ep);
+ cp != NULL; cp = sudo_strsplit(NULL, devsearch_end, ":", &ep)) {
+
+ len = (size_t)(ep - cp);
+ if (len >= sizeof(path)) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "devsearch entry %.*s too long", (int)len, cp);
+ continue;
+ }
+ memcpy(path, cp, len);
+ path[len] = '\0';
+
+ if (strcmp(path, _PATH_DEV "pts") == 0) {
+ /* Special case /dev/pts */
+ len = (size_t)snprintf(path, sizeof(path), "%spts/%u",
+ _PATH_DEV, (unsigned int)minor(rdev));
+ if (len >= sizeof(path)) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "devsearch entry %spts/%u too long",
+ _PATH_DEV, (unsigned int)minor(rdev));
+ continue;
+ }
+ ret = sudo_dev_check(rdev, path, buf, buflen);
+ if (ret != NULL)
+ goto done;
+ } else {
+ /* Scan path, looking for rdev. */
+ ret = sudo_ttyname_scan(path, rdev, buf, buflen);
+ if (ret != NULL || errno == ENOMEM)
+ goto done;
+ }
+ }
+
+done:
+ debug_return_str(ret);
+}
+#endif
diff --git a/lib/util/ttysize.c b/lib/util/ttysize.c
new file mode 100644
index 0000000..66fa146
--- /dev/null
+++ b/lib/util/ttysize.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010-2012, 2014-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <termios.h> /* for struct winsize on HP-UX */
+#include <limits.h>
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+static int
+get_ttysize_ioctl(int *rowp, int *colp)
+{
+ struct winsize wsize;
+ debug_decl(get_ttysize_ioctl, SUDO_DEBUG_UTIL)
+
+ if (ioctl(STDERR_FILENO, TIOCGWINSZ, &wsize) == 0 &&
+ wsize.ws_row != 0 && wsize.ws_col != 0) {
+ *rowp = wsize.ws_row;
+ *colp = wsize.ws_col;
+ debug_return_int(0);
+ }
+ debug_return_int(-1);
+}
+
+void
+sudo_get_ttysize_v1(int *rowp, int *colp)
+{
+ debug_decl(sudo_get_ttysize, SUDO_DEBUG_UTIL)
+
+ if (get_ttysize_ioctl(rowp, colp) == -1) {
+ char *p;
+
+ /* Fall back on $LINES and $COLUMNS. */
+ if ((p = getenv("LINES")) == NULL ||
+ (*rowp = strtonum(p, 1, INT_MAX, NULL)) <= 0) {
+ *rowp = 24;
+ }
+ if ((p = getenv("COLUMNS")) == NULL ||
+ (*colp = strtonum(p, 1, INT_MAX, NULL)) <= 0) {
+ *colp = 80;
+ }
+ }
+
+ debug_return;
+}
diff --git a/lib/util/util.exp.in b/lib/util/util.exp.in
new file mode 100644
index 0000000..510c34c
--- /dev/null
+++ b/lib/util/util.exp.in
@@ -0,0 +1,119 @@
+@COMPAT_EXP@initprogname
+sudo_arc4random_uniform
+sudo_conf_askpass_path_v1
+sudo_conf_clear_paths_v1
+sudo_conf_debug_files_v1
+sudo_conf_debugging_v1
+sudo_conf_devsearch_path_v1
+sudo_conf_disable_coredump_v1
+sudo_conf_group_source_v1
+sudo_conf_max_groups_v1
+sudo_conf_noexec_path_v1
+sudo_conf_plugin_dir_path_v1
+sudo_conf_plugins_v1
+sudo_conf_probe_interfaces_v1
+sudo_conf_read_v1
+sudo_conf_sesh_path_v1
+sudo_debug_deregister_v1
+sudo_debug_enter_v1
+sudo_debug_execve2_v1
+sudo_debug_exit_bool_v1
+sudo_debug_exit_id_t_v1
+sudo_debug_exit_int_v1
+sudo_debug_exit_long_v1
+sudo_debug_exit_ptr_v1
+sudo_debug_exit_size_t_v1
+sudo_debug_exit_ssize_t_v1
+sudo_debug_exit_str_masked_v1
+sudo_debug_exit_str_v1
+sudo_debug_exit_time_t_v1
+sudo_debug_exit_v1
+sudo_debug_fork_v1
+sudo_debug_get_active_instance_v1
+sudo_debug_get_fds_v1
+sudo_debug_get_instance_v1
+sudo_debug_printf2_v1
+sudo_debug_register_v1
+sudo_debug_set_active_instance_v1
+sudo_debug_update_fd_v1
+sudo_debug_vprintf2_v1
+sudo_debug_write2_v1
+sudo_digest_alloc_v1
+sudo_digest_final_v1
+sudo_digest_free_v1
+sudo_digest_getlen_v1
+sudo_digest_reset_v1
+sudo_digest_update_v1
+sudo_dso_findsym_v1
+sudo_dso_load_v1
+sudo_dso_preload_table_v1
+sudo_dso_strerror_v1
+sudo_dso_unload_v1
+sudo_ev_add_v1
+sudo_ev_add_v2
+sudo_ev_alloc_v1
+sudo_ev_base_alloc_v1
+sudo_ev_base_free_v1
+sudo_ev_base_setdef_v1
+sudo_ev_del_v1
+sudo_ev_dispatch_v1
+sudo_ev_free_v1
+sudo_ev_get_timeleft_v1
+sudo_ev_get_timeleft_v2
+sudo_ev_got_break_v1
+sudo_ev_got_exit_v1
+sudo_ev_loop_v1
+sudo_ev_loopbreak_v1
+sudo_ev_loopcontinue_v1
+sudo_ev_loopexit_v1
+sudo_fatal_callback_deregister_v1
+sudo_fatal_callback_register_v1
+sudo_fatal_nodebug_v1
+sudo_fatalx_nodebug_v1
+sudo_gai_fatal_nodebug_v1
+sudo_gai_vfatal_nodebug_v1
+sudo_gai_vwarn_nodebug_v1
+sudo_gai_warn_nodebug_v1
+sudo_get_ttysize_v1
+sudo_getgrouplist2_v1
+sudo_gethostname_v1
+sudo_gettime_awake_v1
+sudo_gettime_mono_v1
+sudo_gettime_real_v1
+sudo_lbuf_append_quoted_v1
+sudo_lbuf_append_v1
+sudo_lbuf_clearerr_v1
+sudo_lbuf_destroy_v1
+sudo_lbuf_error_v1
+sudo_lbuf_init_v1
+sudo_lbuf_print_v1
+sudo_lock_file_v1
+sudo_lock_region_v1
+sudo_new_key_val_v1
+sudo_parse_gids_v1
+sudo_parseln_v1
+sudo_parseln_v2
+sudo_secure_dir_v1
+sudo_secure_file_v1
+sudo_setgroups_v1
+sudo_strsplit_v1
+sudo_strtobool_v1
+sudo_strtoid_v1
+sudo_strtomode_v1
+sudo_term_cbreak_v1
+sudo_term_copy_v1
+sudo_term_eof
+sudo_term_erase
+sudo_term_kill
+sudo_term_noecho_v1
+sudo_term_raw_v1
+sudo_term_restore_v1
+sudo_ttyname_dev_v1
+sudo_vfatal_nodebug_v1
+sudo_vfatalx_nodebug_v1
+sudo_vwarn_nodebug_v1
+sudo_vwarnx_nodebug_v1
+sudo_warn_nodebug_v1
+sudo_warn_set_conversation_v1
+sudo_warn_set_locale_func_v1
+sudo_warnx_nodebug_v1
diff --git a/lib/util/utimens.c b/lib/util/utimens.c
new file mode 100644
index 0000000..579391f
--- /dev/null
+++ b/lib/util/utimens.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2015, 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#if !defined(HAVE_FUTIMENS) || !defined(HAVE_UTIMENSAT)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <errno.h>
+#include <time.h>
+#if !defined(HAVE_UTIMES) || defined(HAVE_FUTIME)
+# include <utime.h>
+#endif
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+
+#if !defined(HAVE_FUTIMES) && defined(HAVE_FUTIMESAT)
+# define futimes(_f, _tv) futimesat(_f, NULL, _tv)
+# define HAVE_FUTIMES
+#endif
+
+#if defined(HAVE_ST_MTIM)
+# ifdef HAVE_ST__TIM
+# define ATIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_atim.st__tim)
+# define MTIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_mtim.st__tim)
+# else
+# define ATIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_atim)
+# define MTIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_mtim)
+# endif
+#elif defined(HAVE_ST_MTIMESPEC)
+# define ATIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_atimespec)
+# define MTIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_mtimespec)
+#elif defined(HAVE_ST_NMTIME)
+# define ATIME_TO_TIMEVAL(_x, _y) do { (_x)->tv_sec = (_y)->st_atime; (_x)->tv_usec = (_y)->st_natime; } while (0)
+# define MTIME_TO_TIMEVAL(_x, _y) do { (_x)->tv_sec = (_y)->st_mtime; (_x)->tv_usec = (_y)->st_nmtime; } while (0)
+#else
+# define ATIME_TO_TIMEVAL(_x, _y) do { (_x)->tv_sec = (_y)->st_atime; (_x)->tv_usec = 0; } while (0)
+# define MTIME_TO_TIMEVAL(_x, _y) do { (_x)->tv_sec = (_y)->st_mtime; (_x)->tv_usec = 0; } while (0)
+#endif /* HAVE_ST_MTIM */
+
+/*
+ * Convert the pair of timespec structs passed to futimens() / utimensat()
+ * to a pair of timeval structs, handling UTIME_OMIT and UTIME_NOW.
+ * Returns 0 on success and -1 on failure (setting errno).
+ */
+static int
+utimens_ts_to_tv(int fd, const char *file, const struct timespec *ts,
+ struct timeval *tv)
+{
+ TIMESPEC_TO_TIMEVAL(&tv[0], &ts[0]);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &ts[1]);
+ if (ts[0].tv_nsec == UTIME_OMIT || ts[1].tv_nsec == UTIME_OMIT) {
+ struct stat sb;
+
+ if (fd != -1) {
+ /* For futimens() */
+ if (fstat(fd, &sb) == -1)
+ return -1;
+ } else {
+ /* For utimensat() */
+ if (stat(file, &sb) == -1)
+ return -1;
+ }
+ if (ts[0].tv_nsec == UTIME_OMIT)
+ ATIME_TO_TIMEVAL(&tv[0], &sb);
+ if (ts[1].tv_nsec == UTIME_OMIT)
+ MTIME_TO_TIMEVAL(&tv[1], &sb);
+ }
+ if (ts[0].tv_nsec == UTIME_NOW || ts[1].tv_nsec == UTIME_NOW) {
+ struct timeval now;
+
+ if (gettimeofday(&now, NULL) == -1)
+ return -1;
+ if (ts[0].tv_nsec == UTIME_NOW)
+ tv[0] = now;
+ if (ts[1].tv_nsec == UTIME_NOW)
+ tv[1] = now;
+ }
+ return 0;
+}
+
+#if defined(HAVE_FUTIMES)
+/*
+ * Emulate futimens() via futimes()
+ */
+int
+sudo_futimens(int fd, const struct timespec *ts)
+{
+ struct timeval tv[2], *times = NULL;
+
+ if (ts != NULL) {
+ if (utimens_ts_to_tv(fd, NULL, ts, tv) == -1)
+ return -1;
+ times = tv;
+ }
+ return futimes(fd, times);
+}
+#elif defined(HAVE_FUTIME)
+/*
+ * Emulate futimens() via futime()
+ */
+int
+sudo_futimens(int fd, const struct timespec *ts)
+{
+ struct utimbuf utb, *times = NULL;
+
+ if (ts != NULL) {
+ struct timeval tv[2];
+
+ if (utimens_ts_to_tv(fd, NULL, ts, tv) == -1)
+ return -1;
+ utb.actime = (time_t)(tv[0].tv_sec + tv[0].tv_usec / 1000000);
+ utb.modtime = (time_t)(tv[1].tv_sec + tv[1].tv_usec / 1000000);
+ times = &utb;
+ }
+ return futime(fd, times);
+}
+#else
+/*
+ * Nothing to do but fail.
+ */
+int
+sudo_futimens(int fd, const struct timespec *ts)
+{
+ errno = ENOSYS;
+ return -1;
+}
+#endif /* HAVE_FUTIMES */
+
+#if defined(HAVE_UTIMES)
+/*
+ * Emulate utimensat() via utimes()
+ */
+int
+sudo_utimensat(int fd, const char *file, const struct timespec *ts, int flag)
+{
+ struct timeval tv[2], *times = NULL;
+
+ if (fd != AT_FDCWD || flag != 0) {
+ errno = ENOTSUP;
+ return -1;
+ }
+
+ if (ts != NULL) {
+ if (utimens_ts_to_tv(-1, file, ts, tv) == -1)
+ return -1;
+ times = tv;
+ }
+ return utimes(file, times);
+}
+#else
+/*
+ * Emulate utimensat() via utime()
+ */
+int
+sudo_utimensat(int fd, const char *file, const struct timespec *ts, int flag)
+{
+ struct utimbuf utb, *times = NULL;
+
+ if (fd != AT_FDCWD || flag != 0) {
+ errno = ENOTSUP;
+ return -1;
+ }
+
+ if (ts != NULL) {
+ struct timeval tv[2];
+
+ if (utimens_ts_to_tv(-1, file, ts, tv) == -1)
+ return -1;
+ utb.actime = (time_t)(tv[0].tv_sec + tv[0].tv_usec / 1000000);
+ utb.modtime = (time_t)(tv[1].tv_sec + tv[1].tv_usec / 1000000);
+ times = &utb;
+ }
+ return utime(file, times);
+}
+#endif /* !HAVE_UTIMES */
+
+#endif /* !HAVE_FUTIMENS && !HAVE_UTIMENSAT */
diff --git a/lib/util/vsyslog.c b/lib/util/vsyslog.c
new file mode 100644
index 0000000..359a8f3
--- /dev/null
+++ b/lib/util/vsyslog.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016-2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <syslog.h>
+
+#include "sudo_compat.h"
+
+#ifndef HAVE_VSYSLOG
+void
+sudo_vsyslog(int pri, const char *fmt, va_list ap)
+{
+ int saved_errno = errno;
+ char *cp, *ep, msgbuf[8192], new_fmt[2048];
+ va_list ap2;
+ size_t len;
+
+ /* Rewrite fmt, replacing %m with an errno string. */
+ for (cp = new_fmt, ep = new_fmt + sizeof(new_fmt); *fmt != '\0'; fmt++) {
+ if (fmt[0] == '%' && fmt[1] == 'm') {
+ fmt++;
+ len = strlcpy(cp, strerror(saved_errno), (ep - cp));
+ if (len >= (size_t)(ep - cp))
+ len = (size_t)(ep - cp) - 1;
+ cp += len;
+ } else {
+ if (fmt[0] == '%' && fmt[1] == '%') {
+ fmt++;
+ if (cp < ep - 1)
+ *cp++ = '%';
+ }
+ if (cp < ep - 1)
+ *cp++ = *fmt;
+ }
+ }
+ *cp = '\0';
+
+ /* Format message and log it, using a static buffer if possible. */
+ va_copy(ap2, ap);
+ len = (size_t)vsnprintf(msgbuf, sizeof(msgbuf), new_fmt, ap2);
+ va_end(ap2);
+ if (len < sizeof(msgbuf)) {
+ syslog(pri, "%s", msgbuf);
+ } else {
+ /* Too big for static buffer? */
+ char *buf;
+ if (vasprintf(&buf, new_fmt, ap) != -1) {
+ syslog(pri, "%s", buf);
+ free(buf);
+ }
+ }
+}
+#endif /* HAVE_VSYSLOG */
diff --git a/lib/zlib/Makefile.in b/lib/zlib/Makefile.in
new file mode 100644
index 0000000..57647dc
--- /dev/null
+++ b/lib/zlib/Makefile.in
@@ -0,0 +1,209 @@
+#
+# Copyright (c) 2011-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# @configure_input@
+#
+
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+cross_compiling = @CROSS_COMPILING@
+
+# Where to install things...
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+localstatedir = @localstatedir@
+
+# File extension, mode and map file to use for shared libraries/objects
+shlib_enable = @SHLIB_ENABLE@
+shlib_mode = @SHLIB_MODE@
+shlib_exp = $(srcdir)/zlib.exp
+shlib_map = zlib.map
+shlib_opt = zlib.opt
+
+# Compiler & tools to use
+CC = @CC@
+LIBTOOL = @LIBTOOL@
+SED = @SED@
+AWK = @AWK@
+
+# Our install program supports extra flags...
+INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
+INSTALL_OWNER = -o $(install_uid) -g $(install_gid)
+INSTALL_BACKUP = @INSTALL_BACKUP@
+
+# C preprocessor flags
+CPPFLAGS = -I. -I$(srcdir)
+
+# Usually -O and/or -g
+CFLAGS = @CFLAGS@
+
+# Flags to pass to the link stage
+LDFLAGS =
+LT_LDFLAGS = @ZLIB_LDFLAGS@ @LT_LDFLAGS@ @LT_LDEXPORTS@
+
+# Flags to pass to libtool
+LTFLAGS =
+
+# Address sanitizer flags
+ASAN_CFLAGS = @ASAN_CFLAGS@
+ASAN_LDFLAGS = @ASAN_LDFLAGS@
+
+# PIE flags
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+
+# Stack smashing protection flags
+SSP_CFLAGS = @SSP_CFLAGS@
+SSP_LDFLAGS = @SSP_LDFLAGS@
+
+# Libtool style shared library version
+SHLIB_VERSION = 0:0:0
+
+# User and group ids the installed files should be "owned" by
+install_uid = 0
+install_gid = 0
+
+#### End of system configuration section. ####
+
+SHELL = @SHELL@
+
+LTOBJS = adler32.lo compress.lo crc32.lo deflate.lo gzclose.lo gzlib.lo \
+ gzread.lo gzwrite.lo infback.lo inffast.lo inflate.lo inftrees.lo \
+ trees.lo uncompr.lo zutil.lo
+
+all: libsudo_z.la
+
+Makefile: $(srcdir)/Makefile.in
+ cd $(top_builddir) && ./config.status --file lib/zlib/Makefile
+
+.SUFFIXES: .c .h .lo
+
+.c.lo:
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $<
+
+$(shlib_map): $(shlib_exp)
+ @$(AWK) 'BEGIN { print "{\n\tglobal:" } { print "\t\t"$$0";" } END { print "\tlocal:\n\t\t*;\n};" }' $(shlib_exp) > $@
+
+$(shlib_opt): $(shlib_exp)
+ @$(SED) 's/^/+e /' $(shlib_exp) > $@
+
+libsudo_z.la: $(LTOBJS) @LT_LDDEP@
+ case "$(LT_LDFLAGS)" in \
+ *-no-install*) \
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(LDFLAGS) $(LT_LDFLAGS) $(LTOBJS);; \
+ *) \
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(LDFLAGS) $(ASAN_LDFLAGS) $(SSP_LDFLAGS) $(LT_LDFLAGS) $(LTOBJS) -version-info $(SHLIB_VERSION) -rpath $(libexecdir)/sudo;; \
+ esac
+
+pre-install:
+
+install:
+ case "$(LT_LDFLAGS)" in \
+ *-no-install*) ;; \
+ *) if [ X"$(shlib_enable)" = X"yes" ]; then \
+ INSTALL_BACKUP='$(INSTALL_BACKUP)' $(LIBTOOL) $(LTFLAGS) --quiet --mode=install $(INSTALL) $(INSTALL_OWNER) libsudo_z.la $(DESTDIR)$(libexecdir)/sudo; \
+ fi;; \
+ esac
+
+install-dirs:
+
+install-binaries:
+
+install-includes:
+
+install-doc:
+
+install-plugin:
+
+uninstall:
+ $(LIBTOOL) $(LTFLAGS) --mode=uninstall rm -f $(DESTDIR)$(libexecdir)/sudo/libsudo_z.la
+ -test -z "$(INSTALL_BACKUP)" || \
+ rf -f $(DESTDIR)$(libexecdir)/sudo/libsudo_z.*~
+
+splint:
+
+cppcheck:
+
+pvs-log-files:
+
+pvs-studio:
+
+check:
+
+clean:
+ -$(LIBTOOL) $(LTFLAGS) --mode=clean rm -f *.lo *.o *.la *.a stamp-* \
+ core *.core core.*
+
+mostlyclean: clean
+
+distclean: clean
+ -rm -rf Makefile .libs zconf.h
+
+clobber: distclean
+
+realclean: distclean
+ rm -f TAGS tags
+
+cleandir: realclean
+
+# Autogenerated dependencies, do not modify
+adler32.lo: $(srcdir)/adler32.c $(srcdir)/zlib.h $(srcdir)/zutil.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/adler32.c
+compress.lo: $(srcdir)/compress.c $(srcdir)/zlib.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/compress.c
+crc32.lo: $(srcdir)/crc32.c $(srcdir)/crc32.h $(srcdir)/zlib.h \
+ $(srcdir)/zutil.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/crc32.c
+deflate.lo: $(srcdir)/deflate.c $(srcdir)/deflate.h $(srcdir)/zlib.h \
+ $(srcdir)/zutil.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/deflate.c
+gzclose.lo: $(srcdir)/gzclose.c $(srcdir)/gzguts.h $(srcdir)/zlib.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/gzclose.c
+gzlib.lo: $(srcdir)/gzlib.c $(srcdir)/gzguts.h $(srcdir)/zlib.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/gzlib.c
+gzread.lo: $(srcdir)/gzread.c $(srcdir)/gzguts.h $(srcdir)/zlib.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/gzread.c
+gzwrite.lo: $(srcdir)/gzwrite.c $(srcdir)/gzguts.h $(srcdir)/zlib.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/gzwrite.c
+infback.lo: $(srcdir)/infback.c $(srcdir)/inffast.h $(srcdir)/inffixed.h \
+ $(srcdir)/inflate.h $(srcdir)/inftrees.h $(srcdir)/zlib.h \
+ $(srcdir)/zutil.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/infback.c
+inffast.lo: $(srcdir)/inffast.c $(srcdir)/inffast.h $(srcdir)/inflate.h \
+ $(srcdir)/inftrees.h $(srcdir)/zlib.h $(srcdir)/zutil.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/inffast.c
+inflate.lo: $(srcdir)/inflate.c $(srcdir)/inffast.h $(srcdir)/inffixed.h \
+ $(srcdir)/inflate.h $(srcdir)/inftrees.h $(srcdir)/zlib.h \
+ $(srcdir)/zutil.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/inflate.c
+inftrees.lo: $(srcdir)/inftrees.c $(srcdir)/inftrees.h $(srcdir)/zlib.h \
+ $(srcdir)/zutil.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/inftrees.c
+trees.lo: $(srcdir)/trees.c $(srcdir)/deflate.h $(srcdir)/trees.h \
+ $(srcdir)/zlib.h $(srcdir)/zutil.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/trees.c
+uncompr.lo: $(srcdir)/uncompr.c $(srcdir)/zlib.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/uncompr.c
+zutil.lo: $(srcdir)/zutil.c $(srcdir)/gzguts.h $(srcdir)/zlib.h \
+ $(srcdir)/zutil.h ./zconf.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/zutil.c
diff --git a/lib/zlib/adler32.c b/lib/zlib/adler32.c
new file mode 100644
index 0000000..d0be438
--- /dev/null
+++ b/lib/zlib/adler32.c
@@ -0,0 +1,186 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2011, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
+
+#define BASE 65521U /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware --
+ try it both ways to see which is faster */
+#ifdef NO_DIVIDE
+/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
+ (thank you to John Reiser for pointing this out) */
+# define CHOP(a) \
+ do { \
+ unsigned long tmp = a >> 16; \
+ a &= 0xffffUL; \
+ a += (tmp << 4) - tmp; \
+ } while (0)
+# define MOD28(a) \
+ do { \
+ CHOP(a); \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+# define MOD(a) \
+ do { \
+ CHOP(a); \
+ MOD28(a); \
+ } while (0)
+# define MOD63(a) \
+ do { /* this assumes a is not negative */ \
+ z_off64_t tmp = a >> 32; \
+ a &= 0xffffffffL; \
+ a += (tmp << 8) - (tmp << 5) + tmp; \
+ tmp = a >> 16; \
+ a &= 0xffffL; \
+ a += (tmp << 4) - tmp; \
+ tmp = a >> 16; \
+ a &= 0xffffL; \
+ a += (tmp << 4) - tmp; \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+#else
+# define MOD(a) a %= BASE
+# define MOD28(a) a %= BASE
+# define MOD63(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_z(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ z_size_t len;
+{
+ unsigned long sum2;
+ unsigned n;
+
+ /* split Adler-32 into component sums */
+ sum2 = (adler >> 16) & 0xffff;
+ adler &= 0xffff;
+
+ /* in case user likes doing a byte at a time, keep it fast */
+ if (len == 1) {
+ adler += buf[0];
+ if (adler >= BASE)
+ adler -= BASE;
+ sum2 += adler;
+ if (sum2 >= BASE)
+ sum2 -= BASE;
+ return adler | (sum2 << 16);
+ }
+
+ /* initial Adler-32 value (deferred check for len == 1 speed) */
+ if (buf == Z_NULL)
+ return 1L;
+
+ /* in case short lengths are provided, keep it somewhat fast */
+ if (len < 16) {
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ if (adler >= BASE)
+ adler -= BASE;
+ MOD28(sum2); /* only added so many BASE's */
+ return adler | (sum2 << 16);
+ }
+
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while (len >= NMAX) {
+ len -= NMAX;
+ n = NMAX / 16; /* NMAX is divisible by 16 */
+ do {
+ DO16(buf); /* 16 sums unrolled */
+ buf += 16;
+ } while (--n);
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if (len) { /* avoid modulos if none remaining */
+ while (len >= 16) {
+ len -= 16;
+ DO16(buf);
+ buf += 16;
+ }
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* return recombined sums */
+ return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ uInt len;
+{
+ return adler32_z(adler, buf, len);
+}
+
+/* ========================================================================= */
+local uLong adler32_combine_(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off64_t len2;
+{
+ unsigned long sum1;
+ unsigned long sum2;
+ unsigned rem;
+
+ /* for negative len, return invalid adler32 as a clue for debugging */
+ if (len2 < 0)
+ return 0xffffffffUL;
+
+ /* the derivation of this formula is left as an exercise for the reader */
+ MOD63(len2); /* assumes len2 >= 0 */
+ rem = (unsigned)len2;
+ sum1 = adler1 & 0xffff;
+ sum2 = rem * sum1;
+ MOD(sum2);
+ sum1 += (adler2 & 0xffff) + BASE - 1;
+ sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1);
+ if (sum2 >= BASE) sum2 -= BASE;
+ return sum1 | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off_t len2;
+{
+ return adler32_combine_(adler1, adler2, len2);
+}
+
+uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off64_t len2;
+{
+ return adler32_combine_(adler1, adler2, len2);
+}
diff --git a/lib/zlib/compress.c b/lib/zlib/compress.c
new file mode 100644
index 0000000..e2db404
--- /dev/null
+++ b/lib/zlib/compress.c
@@ -0,0 +1,86 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+ int level;
+{
+ z_stream stream;
+ int err;
+ const uInt max = (uInt)-1;
+ uLong left;
+
+ left = *destLen;
+ *destLen = 0;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = deflateInit(&stream, level);
+ if (err != Z_OK) return err;
+
+ stream.next_out = dest;
+ stream.avail_out = 0;
+ stream.next_in = (z_const Bytef *)source;
+ stream.avail_in = 0;
+
+ do {
+ if (stream.avail_out == 0) {
+ stream.avail_out = left > (uLong)max ? max : (uInt)left;
+ left -= stream.avail_out;
+ }
+ if (stream.avail_in == 0) {
+ stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen;
+ sourceLen -= stream.avail_in;
+ }
+ err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH);
+ } while (err == Z_OK);
+
+ *destLen = stream.total_out;
+ deflateEnd(&stream);
+ return err == Z_STREAM_END ? Z_OK : err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+ If the default memLevel or windowBits for deflateInit() is changed, then
+ this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+ uLong sourceLen;
+{
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+ (sourceLen >> 25) + 13;
+}
diff --git a/lib/zlib/crc32.c b/lib/zlib/crc32.c
new file mode 100644
index 0000000..9580440
--- /dev/null
+++ b/lib/zlib/crc32.c
@@ -0,0 +1,442 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors. This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+ Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+ protection on the static variables used to control the first-use generation
+ of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+ first call get_crc_table() to initialize the tables before allowing more than
+ one thread to use crc32().
+
+ DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
+ */
+
+#ifdef MAKECRCH
+# include <stdio.h>
+# ifndef DYNAMIC_CRC_TABLE
+# define DYNAMIC_CRC_TABLE
+# endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h" /* for STDC and FAR definitions */
+
+/* Definitions for doing the crc four data bytes at a time. */
+#if !defined(NOBYFOUR) && defined(Z_U4)
+# define BYFOUR
+#endif
+#ifdef BYFOUR
+ local unsigned long crc32_little OF((unsigned long,
+ const unsigned char FAR *, z_size_t));
+ local unsigned long crc32_big OF((unsigned long,
+ const unsigned char FAR *, z_size_t));
+# define TBLS 8
+#else
+# define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+ unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
+
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local z_crc_t FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+ local void write_table OF((FILE *, const z_crc_t FAR *));
+#endif /* MAKECRCH */
+/*
+ Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ out is a one). We start with the highest power (least significant bit) of
+ q and repeat for all eight bits of q.
+
+ The first table is simply the CRC of all possible eight bit values. This is
+ all the information needed to generate CRCs on data a byte at a time for all
+ combinations of CRC register values and incoming bytes. The remaining tables
+ allow for word-at-a-time CRC calculation for both big-endian and little-
+ endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+ z_crc_t c;
+ int n, k;
+ z_crc_t poly; /* polynomial exclusive-or pattern */
+ /* terms of polynomial defining this crc (except x^32): */
+ static volatile int first = 1; /* flag to limit concurrent making */
+ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* See if another task is already doing this (not thread-safe, but better
+ than nothing -- significantly reduces duration of vulnerability in
+ case the advice about DYNAMIC_CRC_TABLE is ignored) */
+ if (first) {
+ first = 0;
+
+ /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+ poly = 0;
+ for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
+ poly |= (z_crc_t)1 << (31 - p[n]);
+
+ /* generate a crc for every 8-bit value */
+ for (n = 0; n < 256; n++) {
+ c = (z_crc_t)n;
+ for (k = 0; k < 8; k++)
+ c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+ crc_table[0][n] = c;
+ }
+
+#ifdef BYFOUR
+ /* generate crc for each value followed by one, two, and three zeros,
+ and then the byte reversal of those as well as the first table */
+ for (n = 0; n < 256; n++) {
+ c = crc_table[0][n];
+ crc_table[4][n] = ZSWAP32(c);
+ for (k = 1; k < 4; k++) {
+ c = crc_table[0][c & 0xff] ^ (c >> 8);
+ crc_table[k][n] = c;
+ crc_table[k + 4][n] = ZSWAP32(c);
+ }
+ }
+#endif /* BYFOUR */
+
+ crc_table_empty = 0;
+ }
+ else { /* not first */
+ /* wait for the other guy to finish (not efficient, but rare) */
+ while (crc_table_empty)
+ ;
+ }
+
+#ifdef MAKECRCH
+ /* write out CRC tables to crc32.h */
+ {
+ FILE *out;
+
+ out = fopen("crc32.h", "w");
+ if (out == NULL) return;
+ fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+ fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+ fprintf(out, "local const z_crc_t FAR ");
+ fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
+ write_table(out, crc_table[0]);
+# ifdef BYFOUR
+ fprintf(out, "#ifdef BYFOUR\n");
+ for (k = 1; k < 8; k++) {
+ fprintf(out, " },\n {\n");
+ write_table(out, crc_table[k]);
+ }
+ fprintf(out, "#endif\n");
+# endif /* BYFOUR */
+ fprintf(out, " }\n};\n");
+ fclose(out);
+ }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+ FILE *out;
+ const z_crc_t FAR *table;
+{
+ int n;
+
+ for (n = 0; n < 256; n++)
+ fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
+ (unsigned long)(table[n]),
+ n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const z_crc_t FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+ return (const z_crc_t FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32_z(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ z_size_t len;
+{
+ if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+ if (sizeof(void *) == sizeof(ptrdiff_t)) {
+ z_crc_t endian;
+
+ endian = 1;
+ if (*((unsigned char *)(&endian)))
+ return crc32_little(crc, buf, len);
+ else
+ return crc32_big(crc, buf, len);
+ }
+#endif /* BYFOUR */
+ crc = crc ^ 0xffffffffUL;
+ while (len >= 8) {
+ DO8;
+ len -= 8;
+ }
+ if (len) do {
+ DO1;
+ } while (--len);
+ return crc ^ 0xffffffffUL;
+}
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ uInt len;
+{
+ return crc32_z(crc, buf, len);
+}
+
+#ifdef BYFOUR
+
+/*
+ This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit
+ integer pointer type. This violates the strict aliasing rule, where a
+ compiler can assume, for optimization purposes, that two pointers to
+ fundamentally different types won't ever point to the same memory. This can
+ manifest as a problem only if one of the pointers is written to. This code
+ only reads from those pointers. So long as this code remains isolated in
+ this compilation unit, there won't be a problem. For this reason, this code
+ should not be copied and pasted into a compilation unit in which other code
+ writes to the buffer that is passed to these routines.
+ */
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ z_size_t len;
+{
+ register z_crc_t c;
+ register const z_crc_t FAR *buf4;
+
+ c = (z_crc_t)crc;
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ len--;
+ }
+
+ buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+ while (len >= 32) {
+ DOLIT32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOLIT4;
+ len -= 4;
+ }
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *buf4++; \
+ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ z_size_t len;
+{
+ register z_crc_t c;
+ register const z_crc_t FAR *buf4;
+
+ c = ZSWAP32((z_crc_t)crc);
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ len--;
+ }
+
+ buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+ while (len >= 32) {
+ DOBIG32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOBIG4;
+ len -= 4;
+ }
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)(ZSWAP32(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+ unsigned long *mat;
+ unsigned long vec;
+{
+ unsigned long sum;
+
+ sum = 0;
+ while (vec) {
+ if (vec & 1)
+ sum ^= *mat;
+ vec >>= 1;
+ mat++;
+ }
+ return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+ unsigned long *square;
+ unsigned long *mat;
+{
+ int n;
+
+ for (n = 0; n < GF2_DIM; n++)
+ square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+local uLong crc32_combine_(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off64_t len2;
+{
+ int n;
+ unsigned long row;
+ unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
+ unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
+
+ /* degenerate case (also disallow negative lengths) */
+ if (len2 <= 0)
+ return crc1;
+
+ /* put operator for one zero bit in odd */
+ odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
+ row = 1;
+ for (n = 1; n < GF2_DIM; n++) {
+ odd[n] = row;
+ row <<= 1;
+ }
+
+ /* put operator for two zero bits in even */
+ gf2_matrix_square(even, odd);
+
+ /* put operator for four zero bits in odd */
+ gf2_matrix_square(odd, even);
+
+ /* apply len2 zeros to crc1 (first square will put the operator for one
+ zero byte, eight zero bits, in even) */
+ do {
+ /* apply zeros operator for this bit of len2 */
+ gf2_matrix_square(even, odd);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(even, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ if (len2 == 0)
+ break;
+
+ /* another iteration of the loop with odd and even swapped */
+ gf2_matrix_square(odd, even);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(odd, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ } while (len2 != 0);
+
+ /* return combined crc */
+ crc1 ^= crc2;
+ return crc1;
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off_t len2;
+{
+ return crc32_combine_(crc1, crc2, len2);
+}
+
+uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off64_t len2;
+{
+ return crc32_combine_(crc1, crc2, len2);
+}
diff --git a/lib/zlib/crc32.h b/lib/zlib/crc32.h
new file mode 100644
index 0000000..9e0c778
--- /dev/null
+++ b/lib/zlib/crc32.h
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const z_crc_t FAR crc_table[TBLS][256] =
+{
+ {
+ 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+ 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+ 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+ 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+ 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+ 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+ 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+ 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+ 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+ 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+ 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+ 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+ 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+ 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+ 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+ 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+ 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+ 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+ 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+ 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+ 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+ 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+ 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+ 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+ 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+ 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+ 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+ 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+ 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+ 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+ 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+ 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+ 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+ 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+ 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+ 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+ 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+ 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+ 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+ 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+ 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+ 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+ 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+ 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+ 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+ 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+ 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+ 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+ 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+ 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+ 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+ 0x2d02ef8dUL
+#ifdef BYFOUR
+ },
+ {
+ 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+ 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+ 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+ 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+ 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+ 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+ 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+ 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+ 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+ 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+ 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+ 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+ 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+ 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+ 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+ 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+ 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+ 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+ 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+ 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+ 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+ 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+ 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+ 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+ 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+ 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+ 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+ 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+ 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+ 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+ 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+ 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+ 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+ 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+ 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+ 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+ 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+ 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+ 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+ 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+ 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+ 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+ 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+ 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+ 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+ 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+ 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+ 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+ 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+ 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+ 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+ 0x9324fd72UL
+ },
+ {
+ 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+ 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+ 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+ 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+ 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+ 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+ 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+ 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+ 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+ 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+ 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+ 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+ 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+ 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+ 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+ 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+ 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+ 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+ 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+ 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+ 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+ 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+ 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+ 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+ 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+ 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+ 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+ 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+ 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+ 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+ 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+ 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+ 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+ 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+ 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+ 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+ 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+ 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+ 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+ 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+ 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+ 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+ 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+ 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+ 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+ 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+ 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+ 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+ 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+ 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+ 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+ 0xbe9834edUL
+ },
+ {
+ 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+ 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+ 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+ 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+ 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+ 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+ 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+ 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+ 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+ 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+ 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+ 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+ 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+ 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+ 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+ 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+ 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+ 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+ 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+ 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+ 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+ 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+ 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+ 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+ 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+ 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+ 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+ 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+ 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+ 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+ 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+ 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+ 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+ 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+ 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+ 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+ 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+ 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+ 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+ 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+ 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+ 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+ 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+ 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+ 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+ 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+ 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+ 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+ 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+ 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+ 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+ 0xde0506f1UL
+ },
+ {
+ 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+ 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+ 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+ 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+ 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+ 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+ 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+ 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+ 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+ 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+ 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+ 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+ 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+ 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+ 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+ 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+ 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+ 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+ 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+ 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+ 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+ 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+ 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+ 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+ 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+ 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+ 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+ 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+ 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+ 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+ 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+ 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+ 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+ 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+ 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+ 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+ 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+ 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+ 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+ 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+ 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+ 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+ 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+ 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+ 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+ 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+ 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+ 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+ 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+ 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+ 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+ 0x8def022dUL
+ },
+ {
+ 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+ 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+ 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+ 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+ 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+ 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+ 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+ 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+ 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+ 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+ 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+ 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+ 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+ 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+ 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+ 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+ 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+ 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+ 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+ 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+ 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+ 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+ 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+ 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+ 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+ 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+ 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+ 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+ 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+ 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+ 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+ 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+ 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+ 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+ 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+ 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+ 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+ 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+ 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+ 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+ 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+ 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+ 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+ 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+ 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+ 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+ 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+ 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+ 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+ 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+ 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+ 0x72fd2493UL
+ },
+ {
+ 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+ 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+ 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+ 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+ 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+ 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+ 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+ 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+ 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+ 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+ 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+ 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+ 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+ 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+ 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+ 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+ 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+ 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+ 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+ 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+ 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+ 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+ 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+ 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+ 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+ 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+ 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+ 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+ 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+ 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+ 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+ 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+ 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+ 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+ 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+ 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+ 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+ 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+ 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+ 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+ 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+ 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+ 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+ 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+ 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+ 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+ 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+ 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+ 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+ 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+ 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+ 0xed3498beUL
+ },
+ {
+ 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+ 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+ 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+ 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+ 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+ 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+ 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+ 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+ 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+ 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+ 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+ 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+ 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+ 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+ 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+ 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+ 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+ 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+ 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+ 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+ 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+ 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+ 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+ 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+ 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+ 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+ 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+ 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+ 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+ 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+ 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+ 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+ 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+ 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+ 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+ 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+ 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+ 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+ 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+ 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+ 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+ 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+ 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+ 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+ 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+ 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+ 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+ 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+ 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+ 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+ 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+ 0xf10605deUL
+#endif
+ }
+};
diff --git a/lib/zlib/deflate.c b/lib/zlib/deflate.c
new file mode 100644
index 0000000..1e39dcb
--- /dev/null
+++ b/lib/zlib/deflate.c
@@ -0,0 +1,2165 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process depends on being able to identify portions
+ * of the input text which are identical to earlier input (within a
+ * sliding window trailing behind the input currently being processed).
+ *
+ * The most straightforward technique turns out to be the fastest for
+ * most input files: try all possible matches and select the longest.
+ * The key feature of this algorithm is that insertions into the string
+ * dictionary are very simple and thus fast, and deletions are avoided
+ * completely. Insertions are performed at each input character, whereas
+ * string matches are performed only when the previous match ends. So it
+ * is preferable to spend more time in matches to allow very fast string
+ * insertions and avoid deletions. The matching algorithm for small
+ * strings is inspired from that of Rabin & Karp. A brute force approach
+ * is used to find longer strings when a small match has been found.
+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ * (by Leonid Broukhis).
+ * A previous version of this file used a more sophisticated algorithm
+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
+ * time, but has a larger average cost, uses more memory and is patented.
+ * However the F&G algorithm may be faster for some highly redundant
+ * files if the parameter max_chain_length (described below) is too large.
+ *
+ * ACKNOWLEDGEMENTS
+ *
+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ * I found it in 'freeze' written by Leonid Broukhis.
+ * Thanks to many people for bug reports and testing.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ * Available in http://tools.ietf.org/html/rfc1951
+ *
+ * A description of the Rabin and Karp algorithm is given in the book
+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ * Fiala,E.R., and Greene,D.H.
+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+ " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ * Function prototypes.
+ */
+typedef enum {
+ need_more, /* block not completed, need more input or more output */
+ block_done, /* block flush performed */
+ finish_started, /* finish started, need only more output at next deflate */
+ finish_done /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local int deflateStateCheck OF((z_streamp strm));
+local void slide_hash OF((deflate_state *s));
+local void fill_window OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow OF((deflate_state *s, int flush));
+#endif
+local block_state deflate_rle OF((deflate_state *s, int flush));
+local block_state deflate_huff OF((deflate_state *s, int flush));
+local void lm_init OF((deflate_state *s));
+local void putShortMSB OF((deflate_state *s, uInt b));
+local void flush_pending OF((z_streamp strm));
+local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+# pragma message("Assembler code may have bugs -- use at your own risk")
+ void match_init OF((void)); /* asm code initialization */
+ uInt longest_match OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef ZLIB_DEBUG
+local void check_match OF((deflate_state *s, IPos start, IPos match,
+ int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+# define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+ ush good_length; /* reduce lazy search above this match length */
+ ush max_lazy; /* do not perform lazy search above this match length */
+ ush nice_length; /* quit search above this match length */
+ ush max_chain;
+ compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4, 5, 16, 8, deflate_fast},
+/* 3 */ {4, 6, 32, 32, deflate_fast},
+
+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
+/* 5 */ {8, 16, 32, 32, deflate_slow},
+/* 6 */ {8, 16, 128, 128, deflate_slow},
+/* 7 */ {8, 32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
+#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0))
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN assertion: all calls to UPDATE_HASH are made with consecutive input
+ * characters, so that a running hash key can be computed from the previous
+ * key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN assertion: all calls to INSERT_STRING are made with consecutive input
+ * characters and the first MIN_MATCH bytes of str are valid (except for
+ * the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+ s->head[s->hash_size-1] = NIL; \
+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ===========================================================================
+ * Slide the hash table when sliding the window down (could be avoided with 32
+ * bit values at the expense of memory usage). We slide even when level == 0 to
+ * keep the hash table consistent if we switch back to level > 0 later.
+ */
+local void slide_hash(s)
+ deflate_state *s;
+{
+ unsigned n, m;
+ Posf *p;
+ uInt wsize = s->w_size;
+
+ n = s->hash_size;
+ p = &s->head[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m - wsize : NIL);
+ } while (--n);
+ n = wsize;
+#ifndef FASTEST
+ p = &s->prev[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m - wsize : NIL);
+ /* If n is not on any hash chain, prev[n] is garbage but
+ * its value will never be used.
+ */
+ } while (--n);
+#endif
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+ z_streamp strm;
+ int level;
+ const char *version;
+ int stream_size;
+{
+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+ Z_DEFAULT_STRATEGY, version, stream_size);
+ /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+ version, stream_size)
+ z_streamp strm;
+ int level;
+ int method;
+ int windowBits;
+ int memLevel;
+ int strategy;
+ const char *version;
+ int stream_size;
+{
+ deflate_state *s;
+ int wrap = 1;
+ static const char my_version[] = ZLIB_VERSION;
+
+ ushf *overlay;
+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
+ * output size for (length,distance) codes is <= 24 bits.
+ */
+
+ if (version == Z_NULL || version[0] != my_version[0] ||
+ stream_size != sizeof(z_stream)) {
+ return Z_VERSION_ERROR;
+ }
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+ strm->msg = Z_NULL;
+ if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+#endif
+ }
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+ if (windowBits < 0) { /* suppress zlib wrapper */
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+#ifdef GZIP
+ else if (windowBits > 15) {
+ wrap = 2; /* write gzip wrapper instead */
+ windowBits -= 16;
+ }
+#endif
+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+ windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+ strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) {
+ return Z_STREAM_ERROR;
+ }
+ if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+ if (s == Z_NULL) return Z_MEM_ERROR;
+ strm->state = (struct internal_state FAR *)s;
+ s->strm = strm;
+ s->status = INIT_STATE; /* to pass state test in deflateReset() */
+
+ s->wrap = wrap;
+ s->gzhead = Z_NULL;
+ s->w_bits = (uInt)windowBits;
+ s->w_size = 1 << s->w_bits;
+ s->w_mask = s->w_size - 1;
+
+ s->hash_bits = (uInt)memLevel + 7;
+ s->hash_size = 1 << s->hash_bits;
+ s->hash_mask = s->hash_size - 1;
+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+ s->high_water = 0; /* nothing written to s->window yet */
+
+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+ s->pending_buf = (uchf *) overlay;
+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+ s->pending_buf == Z_NULL) {
+ s->status = FINISH_STATE;
+ strm->msg = ERR_MSG(Z_MEM_ERROR);
+ deflateEnd (strm);
+ return Z_MEM_ERROR;
+ }
+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+ s->level = level;
+ s->strategy = strategy;
+ s->method = (Byte)method;
+
+ return deflateReset(strm);
+}
+
+/* =========================================================================
+ * Check for a valid deflate stream state. Return 0 if ok, 1 if not.
+ */
+local int deflateStateCheck (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+ if (strm == Z_NULL ||
+ strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
+ return 1;
+ s = strm->state;
+ if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE &&
+#ifdef GZIP
+ s->status != GZIP_STATE &&
+#endif
+ s->status != EXTRA_STATE &&
+ s->status != NAME_STATE &&
+ s->status != COMMENT_STATE &&
+ s->status != HCRC_STATE &&
+ s->status != BUSY_STATE &&
+ s->status != FINISH_STATE))
+ return 1;
+ return 0;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+ z_streamp strm;
+ const Bytef *dictionary;
+ uInt dictLength;
+{
+ deflate_state *s;
+ uInt str, n;
+ int wrap;
+ unsigned avail;
+ z_const unsigned char *next;
+
+ if (deflateStateCheck(strm) || dictionary == Z_NULL)
+ return Z_STREAM_ERROR;
+ s = strm->state;
+ wrap = s->wrap;
+ if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
+ return Z_STREAM_ERROR;
+
+ /* when using zlib wrappers, compute Adler-32 for provided dictionary */
+ if (wrap == 1)
+ strm->adler = adler32(strm->adler, dictionary, dictLength);
+ s->wrap = 0; /* avoid computing Adler-32 in read_buf */
+
+ /* if dictionary would fill window, just replace the history */
+ if (dictLength >= s->w_size) {
+ if (wrap == 0) { /* already empty otherwise */
+ CLEAR_HASH(s);
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->insert = 0;
+ }
+ dictionary += dictLength - s->w_size; /* use the tail */
+ dictLength = s->w_size;
+ }
+
+ /* insert dictionary into window and hash */
+ avail = strm->avail_in;
+ next = strm->next_in;
+ strm->avail_in = dictLength;
+ strm->next_in = (z_const Bytef *)dictionary;
+ fill_window(s);
+ while (s->lookahead >= MIN_MATCH) {
+ str = s->strstart;
+ n = s->lookahead - (MIN_MATCH-1);
+ do {
+ UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+ s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+ s->head[s->ins_h] = (Pos)str;
+ str++;
+ } while (--n);
+ s->strstart = str;
+ s->lookahead = MIN_MATCH-1;
+ fill_window(s);
+ }
+ s->strstart += s->lookahead;
+ s->block_start = (long)s->strstart;
+ s->insert = s->lookahead;
+ s->lookahead = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ strm->next_in = next;
+ strm->avail_in = avail;
+ s->wrap = wrap;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength)
+ z_streamp strm;
+ Bytef *dictionary;
+ uInt *dictLength;
+{
+ deflate_state *s;
+ uInt len;
+
+ if (deflateStateCheck(strm))
+ return Z_STREAM_ERROR;
+ s = strm->state;
+ len = s->strstart + s->lookahead;
+ if (len > s->w_size)
+ len = s->w_size;
+ if (dictionary != Z_NULL && len)
+ zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len);
+ if (dictLength != Z_NULL)
+ *dictLength = len;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateResetKeep (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+
+ if (deflateStateCheck(strm)) {
+ return Z_STREAM_ERROR;
+ }
+
+ strm->total_in = strm->total_out = 0;
+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+ strm->data_type = Z_UNKNOWN;
+
+ s = (deflate_state *)strm->state;
+ s->pending = 0;
+ s->pending_out = s->pending_buf;
+
+ if (s->wrap < 0) {
+ s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+ }
+ s->status =
+#ifdef GZIP
+ s->wrap == 2 ? GZIP_STATE :
+#endif
+ s->wrap ? INIT_STATE : BUSY_STATE;
+ strm->adler =
+#ifdef GZIP
+ s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+ adler32(0L, Z_NULL, 0);
+ s->last_flush = Z_NO_FLUSH;
+
+ _tr_init(s);
+
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+ z_streamp strm;
+{
+ int ret;
+
+ ret = deflateResetKeep(strm);
+ if (ret == Z_OK)
+ lm_init(strm->state);
+ return ret;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+ z_streamp strm;
+ gz_headerp head;
+{
+ if (deflateStateCheck(strm) || strm->state->wrap != 2)
+ return Z_STREAM_ERROR;
+ strm->state->gzhead = head;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePending (strm, pending, bits)
+ unsigned *pending;
+ int *bits;
+ z_streamp strm;
+{
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+ if (pending != Z_NULL)
+ *pending = strm->state->pending;
+ if (bits != Z_NULL)
+ *bits = strm->state->bi_valid;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+ z_streamp strm;
+ int bits;
+ int value;
+{
+ deflate_state *s;
+ int put;
+
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+ s = strm->state;
+ if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
+ return Z_BUF_ERROR;
+ do {
+ put = Buf_size - s->bi_valid;
+ if (put > bits)
+ put = bits;
+ s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
+ s->bi_valid += put;
+ _tr_flush_bits(s);
+ value >>= put;
+ bits -= put;
+ } while (bits);
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+ z_streamp strm;
+ int level;
+ int strategy;
+{
+ deflate_state *s;
+ compress_func func;
+
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+ s = strm->state;
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
+ return Z_STREAM_ERROR;
+ }
+ func = configuration_table[s->level].func;
+
+ if ((strategy != s->strategy || func != configuration_table[level].func) &&
+ s->high_water) {
+ /* Flush the last buffer: */
+ int err = deflate(strm, Z_BLOCK);
+ if (err == Z_STREAM_ERROR)
+ return err;
+ if (strm->avail_out == 0)
+ return Z_BUF_ERROR;
+ }
+ if (s->level != level) {
+ if (s->level == 0 && s->matches != 0) {
+ if (s->matches == 1)
+ slide_hash(s);
+ else
+ CLEAR_HASH(s);
+ s->matches = 0;
+ }
+ s->level = level;
+ s->max_lazy_match = configuration_table[level].max_lazy;
+ s->good_match = configuration_table[level].good_length;
+ s->nice_match = configuration_table[level].nice_length;
+ s->max_chain_length = configuration_table[level].max_chain;
+ }
+ s->strategy = strategy;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+ z_streamp strm;
+ int good_length;
+ int max_lazy;
+ int nice_length;
+ int max_chain;
+{
+ deflate_state *s;
+
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+ s = strm->state;
+ s->good_match = (uInt)good_length;
+ s->max_lazy_match = (uInt)max_lazy;
+ s->nice_match = nice_length;
+ s->max_chain_length = (uInt)max_chain;
+ return Z_OK;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well. The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds for
+ * every combination of windowBits and memLevel. But even the conservative
+ * upper bound of about 14% expansion does not seem onerous for output buffer
+ * allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+ z_streamp strm;
+ uLong sourceLen;
+{
+ deflate_state *s;
+ uLong complen, wraplen;
+
+ /* conservative upper bound for compressed data */
+ complen = sourceLen +
+ ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
+
+ /* if can't get parameters, return conservative bound plus zlib wrapper */
+ if (deflateStateCheck(strm))
+ return complen + 6;
+
+ /* compute wrapper length */
+ s = strm->state;
+ switch (s->wrap) {
+ case 0: /* raw deflate */
+ wraplen = 0;
+ break;
+ case 1: /* zlib wrapper */
+ wraplen = 6 + (s->strstart ? 4 : 0);
+ break;
+#ifdef GZIP
+ case 2: /* gzip wrapper */
+ wraplen = 18;
+ if (s->gzhead != Z_NULL) { /* user-supplied gzip header */
+ Bytef *str;
+ if (s->gzhead->extra != Z_NULL)
+ wraplen += 2 + s->gzhead->extra_len;
+ str = s->gzhead->name;
+ if (str != Z_NULL)
+ do {
+ wraplen++;
+ } while (*str++);
+ str = s->gzhead->comment;
+ if (str != Z_NULL)
+ do {
+ wraplen++;
+ } while (*str++);
+ if (s->gzhead->hcrc)
+ wraplen += 2;
+ }
+ break;
+#endif
+ default: /* for compiler happiness */
+ wraplen = 6;
+ }
+
+ /* if not default parameters, return conservative bound */
+ if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+ return complen + wraplen;
+
+ /* default settings: return tight bound for that case */
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+ (sourceLen >> 25) + 13 - 6 + wraplen;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+ deflate_state *s;
+ uInt b;
+{
+ put_byte(s, (Byte)(b >> 8));
+ put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output, except for
+ * some deflate_stored() output, goes through this function so some
+ * applications may wish to modify it to avoid allocating a large
+ * strm->next_out buffer and copying into it. (See also read_buf()).
+ */
+local void flush_pending(strm)
+ z_streamp strm;
+{
+ unsigned len;
+ deflate_state *s = strm->state;
+
+ _tr_flush_bits(s);
+ len = s->pending;
+ if (len > strm->avail_out) len = strm->avail_out;
+ if (len == 0) return;
+
+ zmemcpy(strm->next_out, s->pending_out, len);
+ strm->next_out += len;
+ s->pending_out += len;
+ strm->total_out += len;
+ strm->avail_out -= len;
+ s->pending -= len;
+ if (s->pending == 0) {
+ s->pending_out = s->pending_buf;
+ }
+}
+
+/* ===========================================================================
+ * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1].
+ */
+#define HCRC_UPDATE(beg) \
+ do { \
+ if (s->gzhead->hcrc && s->pending > (beg)) \
+ strm->adler = crc32(strm->adler, s->pending_buf + (beg), \
+ s->pending - (beg)); \
+ } while (0)
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+ z_streamp strm;
+ int flush;
+{
+ int old_flush; /* value of flush param for previous deflate call */
+ deflate_state *s;
+
+ if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) {
+ return Z_STREAM_ERROR;
+ }
+ s = strm->state;
+
+ if (strm->next_out == Z_NULL ||
+ (strm->avail_in != 0 && strm->next_in == Z_NULL) ||
+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
+ ERR_RETURN(strm, Z_STREAM_ERROR);
+ }
+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+ old_flush = s->last_flush;
+ s->last_flush = flush;
+
+ /* Flush as much pending output as possible */
+ if (s->pending != 0) {
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ /* Since avail_out is 0, deflate will be called again with
+ * more output space, but possibly with both pending and
+ * avail_in equal to zero. There won't be anything to do,
+ * but this is not an error situation so make sure we
+ * return OK instead of BUF_ERROR at next call of deflate:
+ */
+ s->last_flush = -1;
+ return Z_OK;
+ }
+
+ /* Make sure there is something to do and avoid duplicate consecutive
+ * flushes. For repeated and useless calls with Z_FINISH, we keep
+ * returning Z_STREAM_END instead of Z_BUF_ERROR.
+ */
+ } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
+ flush != Z_FINISH) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* User must not provide more input after the first FINISH: */
+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* Write the header */
+ if (s->status == INIT_STATE) {
+ /* zlib header */
+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+ uInt level_flags;
+
+ if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+ level_flags = 0;
+ else if (s->level < 6)
+ level_flags = 1;
+ else if (s->level == 6)
+ level_flags = 2;
+ else
+ level_flags = 3;
+ header |= (level_flags << 6);
+ if (s->strstart != 0) header |= PRESET_DICT;
+ header += 31 - (header % 31);
+
+ putShortMSB(s, header);
+
+ /* Save the adler32 of the preset dictionary: */
+ if (s->strstart != 0) {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ strm->adler = adler32(0L, Z_NULL, 0);
+ s->status = BUSY_STATE;
+
+ /* Compression must start with an empty pending buffer */
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ }
+#ifdef GZIP
+ if (s->status == GZIP_STATE) {
+ /* gzip header */
+ strm->adler = crc32(0L, Z_NULL, 0);
+ put_byte(s, 31);
+ put_byte(s, 139);
+ put_byte(s, 8);
+ if (s->gzhead == Z_NULL) {
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, OS_CODE);
+ s->status = BUSY_STATE;
+
+ /* Compression must start with an empty pending buffer */
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ }
+ else {
+ put_byte(s, (s->gzhead->text ? 1 : 0) +
+ (s->gzhead->hcrc ? 2 : 0) +
+ (s->gzhead->extra == Z_NULL ? 0 : 4) +
+ (s->gzhead->name == Z_NULL ? 0 : 8) +
+ (s->gzhead->comment == Z_NULL ? 0 : 16)
+ );
+ put_byte(s, (Byte)(s->gzhead->time & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, s->gzhead->os & 0xff);
+ if (s->gzhead->extra != Z_NULL) {
+ put_byte(s, s->gzhead->extra_len & 0xff);
+ put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+ }
+ if (s->gzhead->hcrc)
+ strm->adler = crc32(strm->adler, s->pending_buf,
+ s->pending);
+ s->gzindex = 0;
+ s->status = EXTRA_STATE;
+ }
+ }
+ if (s->status == EXTRA_STATE) {
+ if (s->gzhead->extra != Z_NULL) {
+ ulg beg = s->pending; /* start of bytes to update crc */
+ uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex;
+ while (s->pending + left > s->pending_buf_size) {
+ uInt copy = s->pending_buf_size - s->pending;
+ zmemcpy(s->pending_buf + s->pending,
+ s->gzhead->extra + s->gzindex, copy);
+ s->pending = s->pending_buf_size;
+ HCRC_UPDATE(beg);
+ s->gzindex += copy;
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ beg = 0;
+ left -= copy;
+ }
+ zmemcpy(s->pending_buf + s->pending,
+ s->gzhead->extra + s->gzindex, left);
+ s->pending += left;
+ HCRC_UPDATE(beg);
+ s->gzindex = 0;
+ }
+ s->status = NAME_STATE;
+ }
+ if (s->status == NAME_STATE) {
+ if (s->gzhead->name != Z_NULL) {
+ ulg beg = s->pending; /* start of bytes to update crc */
+ int val;
+ do {
+ if (s->pending == s->pending_buf_size) {
+ HCRC_UPDATE(beg);
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ beg = 0;
+ }
+ val = s->gzhead->name[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ HCRC_UPDATE(beg);
+ s->gzindex = 0;
+ }
+ s->status = COMMENT_STATE;
+ }
+ if (s->status == COMMENT_STATE) {
+ if (s->gzhead->comment != Z_NULL) {
+ ulg beg = s->pending; /* start of bytes to update crc */
+ int val;
+ do {
+ if (s->pending == s->pending_buf_size) {
+ HCRC_UPDATE(beg);
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ beg = 0;
+ }
+ val = s->gzhead->comment[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ HCRC_UPDATE(beg);
+ }
+ s->status = HCRC_STATE;
+ }
+ if (s->status == HCRC_STATE) {
+ if (s->gzhead->hcrc) {
+ if (s->pending + 2 > s->pending_buf_size) {
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ }
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ strm->adler = crc32(0L, Z_NULL, 0);
+ }
+ s->status = BUSY_STATE;
+
+ /* Compression must start with an empty pending buffer */
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ }
+#endif
+
+ /* Start a new block or continue the current one.
+ */
+ if (strm->avail_in != 0 || s->lookahead != 0 ||
+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+ block_state bstate;
+
+ bstate = s->level == 0 ? deflate_stored(s, flush) :
+ s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
+ s->strategy == Z_RLE ? deflate_rle(s, flush) :
+ (*(configuration_table[s->level].func))(s, flush);
+
+ if (bstate == finish_started || bstate == finish_done) {
+ s->status = FINISH_STATE;
+ }
+ if (bstate == need_more || bstate == finish_started) {
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+ }
+ return Z_OK;
+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+ * of deflate should use the same flush parameter to make sure
+ * that the flush is complete. So we don't have to output an
+ * empty block here, this will be done at next call. This also
+ * ensures that for a very small output buffer, we emit at most
+ * one empty block.
+ */
+ }
+ if (bstate == block_done) {
+ if (flush == Z_PARTIAL_FLUSH) {
+ _tr_align(s);
+ } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
+ _tr_stored_block(s, (char*)0, 0L, 0);
+ /* For a full flush, this empty block will be recognized
+ * as a special marker by inflate_sync().
+ */
+ if (flush == Z_FULL_FLUSH) {
+ CLEAR_HASH(s); /* forget history */
+ if (s->lookahead == 0) {
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->insert = 0;
+ }
+ }
+ }
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+ return Z_OK;
+ }
+ }
+ }
+
+ if (flush != Z_FINISH) return Z_OK;
+ if (s->wrap <= 0) return Z_STREAM_END;
+
+ /* Write the trailer */
+#ifdef GZIP
+ if (s->wrap == 2) {
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+ put_byte(s, (Byte)(strm->total_in & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+ }
+ else
+#endif
+ {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ flush_pending(strm);
+ /* If avail_out is zero, the application will call deflate again
+ * to flush the rest.
+ */
+ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+ z_streamp strm;
+{
+ int status;
+
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+
+ status = strm->state->status;
+
+ /* Deallocate in reverse order of allocations: */
+ TRY_FREE(strm, strm->state->pending_buf);
+ TRY_FREE(strm, strm->state->head);
+ TRY_FREE(strm, strm->state->prev);
+ TRY_FREE(strm, strm->state->window);
+
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+
+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+ z_streamp dest;
+ z_streamp source;
+{
+#ifdef MAXSEG_64K
+ return Z_STREAM_ERROR;
+#else
+ deflate_state *ds;
+ deflate_state *ss;
+ ushf *overlay;
+
+
+ if (deflateStateCheck(source) || dest == Z_NULL) {
+ return Z_STREAM_ERROR;
+ }
+
+ ss = source->state;
+
+ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+
+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+ if (ds == Z_NULL) return Z_MEM_ERROR;
+ dest->state = (struct internal_state FAR *) ds;
+ zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
+ ds->strm = dest;
+
+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+ ds->pending_buf = (uchf *) overlay;
+
+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+ ds->pending_buf == Z_NULL) {
+ deflateEnd (dest);
+ return Z_MEM_ERROR;
+ }
+ /* following zmemcpy do not work for 16-bit MSDOS */
+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+ zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
+ zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+ ds->l_desc.dyn_tree = ds->dyn_ltree;
+ ds->d_desc.dyn_tree = ds->dyn_dtree;
+ ds->bl_desc.dyn_tree = ds->bl_tree;
+
+ return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read. All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local unsigned read_buf(strm, buf, size)
+ z_streamp strm;
+ Bytef *buf;
+ unsigned size;
+{
+ unsigned len = strm->avail_in;
+
+ if (len > size) len = size;
+ if (len == 0) return 0;
+
+ strm->avail_in -= len;
+
+ zmemcpy(buf, strm->next_in, len);
+ if (strm->state->wrap == 1) {
+ strm->adler = adler32(strm->adler, buf, len);
+ }
+#ifdef GZIP
+ else if (strm->state->wrap == 2) {
+ strm->adler = crc32(strm->adler, buf, len);
+ }
+#endif
+ strm->next_in += len;
+ strm->total_in += len;
+
+ return len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+ deflate_state *s;
+{
+ s->window_size = (ulg)2L*s->w_size;
+
+ CLEAR_HASH(s);
+
+ /* Set the default configuration parameters:
+ */
+ s->max_lazy_match = configuration_table[s->level].max_lazy;
+ s->good_match = configuration_table[s->level].good_length;
+ s->nice_match = configuration_table[s->level].nice_length;
+ s->max_chain_length = configuration_table[s->level].max_chain;
+
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->lookahead = 0;
+ s->insert = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ s->ins_h = 0;
+#ifndef FASTEST
+#ifdef ASMV
+ match_init(); /* initialize the asm code */
+#endif
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ int best_len = (int)s->prev_length; /* best match length so far */
+ int nice_match = s->nice_match; /* stop if match long enough */
+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+ s->strstart - (IPos)MAX_DIST(s) : NIL;
+ /* Stop when cur_match becomes <= limit. To simplify the code,
+ * we prevent matches with the string of window index 0.
+ */
+ Posf *prev = s->prev;
+ uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+ /* Compare two bytes at a time. Note: this is not always beneficial.
+ * Try with and without -DUNALIGNED_OK to check.
+ */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+ register ush scan_start = *(ushf*)scan;
+ register ush scan_end = *(ushf*)(scan+best_len-1);
+#else
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+ register Byte scan_end1 = scan[best_len-1];
+ register Byte scan_end = scan[best_len];
+#endif
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ /* Do not waste too much time if we already have a good match: */
+ if (s->prev_length >= s->good_match) {
+ chain_length >>= 2;
+ }
+ /* Do not look for matches beyond the end of the input. This is necessary
+ * to make deflate deterministic.
+ */
+ if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead;
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ do {
+ Assert(cur_match < s->strstart, "no future");
+ match = s->window + cur_match;
+
+ /* Skip to next match if the match length cannot increase
+ * or if the match length is less than 2. Note that the checks below
+ * for insufficient lookahead only occur occasionally for performance
+ * reasons. Therefore uninitialized memory will be accessed, and
+ * conditional jumps will be made that depend on those values.
+ * However the length of the match is limited to the lookahead, so
+ * the output of deflate is not affected by the uninitialized values.
+ */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+ /* This code assumes sizeof(unsigned short) == 2. Do not use
+ * UNALIGNED_OK if your compiler uses a different size.
+ */
+ if (*(ushf*)(match+best_len-1) != scan_end ||
+ *(ushf*)match != scan_start) continue;
+
+ /* It is not necessary to compare scan[2] and match[2] since they are
+ * always equal when the other bytes match, given that the hash keys
+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
+ * lookahead only every 4th comparison; the 128th check will be made
+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+ * necessary to put more guard bytes at the end of the window, or
+ * to check more often for insufficient lookahead.
+ */
+ Assert(scan[2] == match[2], "scan[2]?");
+ scan++, match++;
+ do {
+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ scan < strend);
+ /* The funny "do {}" generates better code on most compilers */
+
+ /* Here, scan <= window+strstart+257 */
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+ if (*scan == *match) scan++;
+
+ len = (MAX_MATCH - 1) - (int)(strend-scan);
+ scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+ if (match[best_len] != scan_end ||
+ match[best_len-1] != scan_end1 ||
+ *match != *scan ||
+ *++match != scan[1]) continue;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match++;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+ scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+ if (len > best_len) {
+ s->match_start = cur_match;
+ best_len = len;
+ if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+ scan_end = *(ushf*)(scan+best_len-1);
+#else
+ scan_end1 = scan[best_len-1];
+ scan_end = scan[best_len];
+#endif
+ }
+ } while ((cur_match = prev[cur_match & wmask]) > limit
+ && --chain_length != 0);
+
+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+ return s->lookahead;
+}
+#endif /* ASMV */
+
+#else /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for FASTEST only
+ */
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ Assert(cur_match < s->strstart, "no future");
+
+ match = s->window + cur_match;
+
+ /* Return failure if the match length is less than 2:
+ */
+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match += 2;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+
+ if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+ s->match_start = cur_match;
+ return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#endif /* FASTEST */
+
+#ifdef ZLIB_DEBUG
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+ deflate_state *s;
+ IPos start, match;
+ int length;
+{
+ /* check that the match is indeed a match */
+ if (zmemcmp(s->window + match,
+ s->window + start, length) != EQUAL) {
+ fprintf(stderr, " start %u, match %u, length %d\n",
+ start, match, length);
+ do {
+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+ } while (--length != 0);
+ z_error("invalid match");
+ }
+ if (z_verbose > 1) {
+ fprintf(stderr,"\\[%d,%d]", start-match, length);
+ do { putc(s->window[start++], stderr); } while (--length != 0);
+ }
+}
+#else
+# define check_match(s, start, match, length)
+#endif /* ZLIB_DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ * At least one byte has been read, or avail_in == 0; reads are
+ * performed for at least two bytes (required for the zip translate_eol
+ * option -- not supported here).
+ */
+local void fill_window(s)
+ deflate_state *s;
+{
+ unsigned n;
+ unsigned more; /* Amount of free space at the end of the window. */
+ uInt wsize = s->w_size;
+
+ Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
+
+ do {
+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+ /* Deal with !@#$% 64K limit: */
+ if (sizeof(int) <= 2) {
+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+ more = wsize;
+
+ } else if (more == (unsigned)(-1)) {
+ /* Very unlikely, but possible on 16 bit machine if
+ * strstart == 0 && lookahead == 1 (input done a byte at time)
+ */
+ more--;
+ }
+ }
+
+ /* If the window is almost full and there is insufficient lookahead,
+ * move the upper half to the lower one to make room in the upper half.
+ */
+ if (s->strstart >= wsize+MAX_DIST(s)) {
+
+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more);
+ s->match_start -= wsize;
+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
+ s->block_start -= (long) wsize;
+ slide_hash(s);
+ more += wsize;
+ }
+ if (s->strm->avail_in == 0) break;
+
+ /* If there was no sliding:
+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+ * more == window_size - lookahead - strstart
+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+ * => more >= window_size - 2*WSIZE + 2
+ * In the BIG_MEM or MMAP case (not yet supported),
+ * window_size == input_size + MIN_LOOKAHEAD &&
+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+ * Otherwise, window_size == 2*WSIZE so more >= 2.
+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+ */
+ Assert(more >= 2, "more < 2");
+
+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+ s->lookahead += n;
+
+ /* Initialize the hash value now that we have some input: */
+ if (s->lookahead + s->insert >= MIN_MATCH) {
+ uInt str = s->strstart - s->insert;
+ s->ins_h = s->window[str];
+ UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ while (s->insert) {
+ UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+ s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+ s->head[s->ins_h] = (Pos)str;
+ str++;
+ s->insert--;
+ if (s->lookahead + s->insert < MIN_MATCH)
+ break;
+ }
+ }
+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+ * but this is not important since only literal bytes will be emitted.
+ */
+
+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+
+ /* If the WIN_INIT bytes after the end of the current data have never been
+ * written, then zero those bytes in order to avoid memory check reports of
+ * the use of uninitialized (or uninitialised as Julian writes) bytes by
+ * the longest match routines. Update the high water mark for the next
+ * time through here. WIN_INIT is set to MAX_MATCH since the longest match
+ * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+ */
+ if (s->high_water < s->window_size) {
+ ulg curr = s->strstart + (ulg)(s->lookahead);
+ ulg init;
+
+ if (s->high_water < curr) {
+ /* Previous high water mark below current data -- zero WIN_INIT
+ * bytes or up to end of window, whichever is less.
+ */
+ init = s->window_size - curr;
+ if (init > WIN_INIT)
+ init = WIN_INIT;
+ zmemzero(s->window + curr, (unsigned)init);
+ s->high_water = curr + init;
+ }
+ else if (s->high_water < (ulg)curr + WIN_INIT) {
+ /* High water mark at or above current data, but below current data
+ * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+ * to end of window, whichever is less.
+ */
+ init = (ulg)curr + WIN_INIT - s->high_water;
+ if (init > s->window_size - s->high_water)
+ init = s->window_size - s->high_water;
+ zmemzero(s->window + s->high_water, (unsigned)init);
+ s->high_water += init;
+ }
+ }
+
+ Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
+ "not enough room for search");
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, last) { \
+ _tr_flush_block(s, (s->block_start >= 0L ? \
+ (charf *)&s->window[(unsigned)s->block_start] : \
+ (charf *)Z_NULL), \
+ (ulg)((long)s->strstart - s->block_start), \
+ (last)); \
+ s->block_start = s->strstart; \
+ flush_pending(s->strm); \
+ Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, last) { \
+ FLUSH_BLOCK_ONLY(s, last); \
+ if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
+}
+
+/* Maximum stored block length in deflate format (not including header). */
+#define MAX_STORED 65535
+
+/* Minimum of a and b. */
+#ifndef MIN
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+#endif
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ *
+ * In case deflateParams() is used to later switch to a non-zero compression
+ * level, s->matches (otherwise unused when storing) keeps track of the number
+ * of hash table slides to perform. If s->matches is 1, then one hash table
+ * slide will be done when switching. If s->matches is 2, the maximum value
+ * allowed here, then the hash table will be cleared, since two or more slides
+ * is the same as a clear.
+ *
+ * deflate_stored() is written to minimize the number of times an input byte is
+ * copied. It is most efficient with large input and output buffers, which
+ * maximizes the opportunites to have a single copy from next_in to next_out.
+ */
+local block_state deflate_stored(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ /* Smallest worthy block size when not flushing or finishing. By default
+ * this is 32K. This can be as small as 507 bytes for memLevel == 1. For
+ * large input and output buffers, the stored block size will be larger.
+ */
+ unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size);
+
+ /* Copy as many min_block or larger stored blocks directly to next_out as
+ * possible. If flushing, copy the remaining available input to next_out as
+ * stored blocks, if there is enough space.
+ */
+ unsigned len, left, have, last = 0;
+ unsigned used = s->strm->avail_in;
+ do {
+ /* Set len to the maximum size block that we can copy directly with the
+ * available input data and output space. Set left to how much of that
+ * would be copied from what's left in the window.
+ */
+ len = MAX_STORED; /* maximum deflate stored block length */
+ have = (s->bi_valid + 42) >> 3; /* number of header bytes */
+ if (s->strm->avail_out < have) /* need room for header */
+ break;
+ /* maximum stored block length that will fit in avail_out: */
+ have = s->strm->avail_out - have;
+ left = s->strstart - s->block_start; /* bytes left in window */
+ if (len > (ulg)left + s->strm->avail_in)
+ len = left + s->strm->avail_in; /* limit len to the input */
+ if (len > have)
+ len = have; /* limit len to the output */
+
+ /* If the stored block would be less than min_block in length, or if
+ * unable to copy all of the available input when flushing, then try
+ * copying to the window and the pending buffer instead. Also don't
+ * write an empty block when flushing -- deflate() does that.
+ */
+ if (len < min_block && ((len == 0 && flush != Z_FINISH) ||
+ flush == Z_NO_FLUSH ||
+ len != left + s->strm->avail_in))
+ break;
+
+ /* Make a dummy stored block in pending to get the header bytes,
+ * including any pending bits. This also updates the debugging counts.
+ */
+ last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0;
+ _tr_stored_block(s, (char *)0, 0L, last);
+
+ /* Replace the lengths in the dummy stored block with len. */
+ s->pending_buf[s->pending - 4] = len;
+ s->pending_buf[s->pending - 3] = len >> 8;
+ s->pending_buf[s->pending - 2] = ~len;
+ s->pending_buf[s->pending - 1] = ~len >> 8;
+
+ /* Write the stored block header bytes. */
+ flush_pending(s->strm);
+
+#ifdef ZLIB_DEBUG
+ /* Update debugging counts for the data about to be copied. */
+ s->compressed_len += len << 3;
+ s->bits_sent += len << 3;
+#endif
+
+ /* Copy uncompressed bytes from the window to next_out. */
+ if (left) {
+ if (left > len)
+ left = len;
+ zmemcpy(s->strm->next_out, s->window + s->block_start, left);
+ s->strm->next_out += left;
+ s->strm->avail_out -= left;
+ s->strm->total_out += left;
+ s->block_start += left;
+ len -= left;
+ }
+
+ /* Copy uncompressed bytes directly from next_in to next_out, updating
+ * the check value.
+ */
+ if (len) {
+ read_buf(s->strm, s->strm->next_out, len);
+ s->strm->next_out += len;
+ s->strm->avail_out -= len;
+ s->strm->total_out += len;
+ }
+ } while (last == 0);
+
+ /* Update the sliding window with the last s->w_size bytes of the copied
+ * data, or append all of the copied data to the existing window if less
+ * than s->w_size bytes were copied. Also update the number of bytes to
+ * insert in the hash tables, in the event that deflateParams() switches to
+ * a non-zero compression level.
+ */
+ used -= s->strm->avail_in; /* number of input bytes directly copied */
+ if (used) {
+ /* If any input was used, then no unused input remains in the window,
+ * therefore s->block_start == s->strstart.
+ */
+ if (used >= s->w_size) { /* supplant the previous history */
+ s->matches = 2; /* clear hash */
+ zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size);
+ s->strstart = s->w_size;
+ }
+ else {
+ if (s->window_size - s->strstart <= used) {
+ /* Slide the window down. */
+ s->strstart -= s->w_size;
+ zmemcpy(s->window, s->window + s->w_size, s->strstart);
+ if (s->matches < 2)
+ s->matches++; /* add a pending slide_hash() */
+ }
+ zmemcpy(s->window + s->strstart, s->strm->next_in - used, used);
+ s->strstart += used;
+ }
+ s->block_start = s->strstart;
+ s->insert += MIN(used, s->w_size - s->insert);
+ }
+ if (s->high_water < s->strstart)
+ s->high_water = s->strstart;
+
+ /* If the last block was written to next_out, then done. */
+ if (last)
+ return finish_done;
+
+ /* If flushing and all input has been consumed, then done. */
+ if (flush != Z_NO_FLUSH && flush != Z_FINISH &&
+ s->strm->avail_in == 0 && (long)s->strstart == s->block_start)
+ return block_done;
+
+ /* Fill the window with any remaining input. */
+ have = s->window_size - s->strstart - 1;
+ if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) {
+ /* Slide the window down. */
+ s->block_start -= s->w_size;
+ s->strstart -= s->w_size;
+ zmemcpy(s->window, s->window + s->w_size, s->strstart);
+ if (s->matches < 2)
+ s->matches++; /* add a pending slide_hash() */
+ have += s->w_size; /* more space now */
+ }
+ if (have > s->strm->avail_in)
+ have = s->strm->avail_in;
+ if (have) {
+ read_buf(s->strm, s->window + s->strstart, have);
+ s->strstart += have;
+ }
+ if (s->high_water < s->strstart)
+ s->high_water = s->strstart;
+
+ /* There was not enough avail_out to write a complete worthy or flushed
+ * stored block to next_out. Write a stored block to pending instead, if we
+ * have enough input for a worthy block, or if flushing and there is enough
+ * room for the remaining input as a stored block in the pending buffer.
+ */
+ have = (s->bi_valid + 42) >> 3; /* number of header bytes */
+ /* maximum stored block length that will fit in pending: */
+ have = MIN(s->pending_buf_size - have, MAX_STORED);
+ min_block = MIN(have, s->w_size);
+ left = s->strstart - s->block_start;
+ if (left >= min_block ||
+ ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH &&
+ s->strm->avail_in == 0 && left <= have)) {
+ len = MIN(left, have);
+ last = flush == Z_FINISH && s->strm->avail_in == 0 &&
+ len == left ? 1 : 0;
+ _tr_stored_block(s, (charf *)s->window + s->block_start, len, last);
+ s->block_start += len;
+ flush_pending(s->strm);
+ }
+
+ /* We've done all we can with the available input and output. */
+ return last ? finish_started : need_more;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head; /* head of the hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ hash_head = NIL;
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ * At this point we have always match_length < MIN_MATCH
+ */
+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ s->match_length = longest_match (s, hash_head);
+ /* longest_match() sets match_start */
+ }
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->match_start, s->match_length);
+
+ _tr_tally_dist(s, s->strstart - s->match_start,
+ s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+
+ /* Insert new strings in the hash table only if the match length
+ * is not too large. This saves time but degrades compression.
+ */
+#ifndef FASTEST
+ if (s->match_length <= s->max_insert_length &&
+ s->lookahead >= MIN_MATCH) {
+ s->match_length--; /* string at strstart already in table */
+ do {
+ s->strstart++;
+ INSERT_STRING(s, s->strstart, hash_head);
+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+ * always MIN_MATCH bytes ahead.
+ */
+ } while (--s->match_length != 0);
+ s->strstart++;
+ } else
+#endif
+ {
+ s->strstart += s->match_length;
+ s->match_length = 0;
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+ * matter since it will be recomputed at next deflate call.
+ */
+ }
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head; /* head of hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ /* Process the input block. */
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ hash_head = NIL;
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ */
+ s->prev_length = s->match_length, s->prev_match = s->match_start;
+ s->match_length = MIN_MATCH-1;
+
+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+ s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ s->match_length = longest_match (s, hash_head);
+ /* longest_match() sets match_start */
+
+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+ || (s->match_length == MIN_MATCH &&
+ s->strstart - s->match_start > TOO_FAR)
+#endif
+ )) {
+
+ /* If prev_match is also MIN_MATCH, match_start is garbage
+ * but we will ignore the current match anyway.
+ */
+ s->match_length = MIN_MATCH-1;
+ }
+ }
+ /* If there was a match at the previous step and the current
+ * match is not better, output the previous match:
+ */
+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+ /* Do not insert strings in hash table beyond this. */
+
+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+ s->prev_length - MIN_MATCH, bflush);
+
+ /* Insert in hash table all strings up to the end of the match.
+ * strstart-1 and strstart are already inserted. If there is not
+ * enough lookahead, the last two strings are not inserted in
+ * the hash table.
+ */
+ s->lookahead -= s->prev_length-1;
+ s->prev_length -= 2;
+ do {
+ if (++s->strstart <= max_insert) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+ } while (--s->prev_length != 0);
+ s->match_available = 0;
+ s->match_length = MIN_MATCH-1;
+ s->strstart++;
+
+ if (bflush) FLUSH_BLOCK(s, 0);
+
+ } else if (s->match_available) {
+ /* If there was no match at the previous position, output a
+ * single literal. If there was a match but the current match
+ * is longer, truncate the previous match to a single literal.
+ */
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ if (bflush) {
+ FLUSH_BLOCK_ONLY(s, 0);
+ }
+ s->strstart++;
+ s->lookahead--;
+ if (s->strm->avail_out == 0) return need_more;
+ } else {
+ /* There is no previous match to compare with, wait for
+ * the next step to decide.
+ */
+ s->match_available = 1;
+ s->strstart++;
+ s->lookahead--;
+ }
+ }
+ Assert (flush != Z_NO_FLUSH, "no flush?");
+ if (s->match_available) {
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ s->match_available = 0;
+ }
+ s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
+#endif /* FASTEST */
+
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one. Do not maintain a hash table. (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ int bflush; /* set if current block must be flushed */
+ uInt prev; /* byte at distance one to match */
+ Bytef *scan, *strend; /* scan goes up to strend for length of run */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the longest run, plus one for the unrolled loop.
+ */
+ if (s->lookahead <= MAX_MATCH) {
+ fill_window(s);
+ if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* See how many times the previous byte repeats */
+ s->match_length = 0;
+ if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
+ scan = s->window + s->strstart - 1;
+ prev = *scan;
+ if (prev == *++scan && prev == *++scan && prev == *++scan) {
+ strend = s->window + s->strstart + MAX_MATCH;
+ do {
+ } while (prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ scan < strend);
+ s->match_length = MAX_MATCH - (uInt)(strend - scan);
+ if (s->match_length > s->lookahead)
+ s->match_length = s->lookahead;
+ }
+ Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
+ }
+
+ /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->strstart - 1, s->match_length);
+
+ _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+ s->strstart += s->match_length;
+ s->match_length = 0;
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ s->insert = 0;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
+
+/* ===========================================================================
+ * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
+ * (It will be regenerated if this run of deflate switches away from Huffman.)
+ */
+local block_state deflate_huff(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we have a literal to write. */
+ if (s->lookahead == 0) {
+ fill_window(s);
+ if (s->lookahead == 0) {
+ if (flush == Z_NO_FLUSH)
+ return need_more;
+ break; /* flush the current block */
+ }
+ }
+
+ /* Output a literal byte */
+ s->match_length = 0;
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ s->insert = 0;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
diff --git a/lib/zlib/deflate.h b/lib/zlib/deflate.h
new file mode 100644
index 0000000..23ecdd3
--- /dev/null
+++ b/lib/zlib/deflate.h
@@ -0,0 +1,349 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2016 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer creation by deflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip encoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS 256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES 30
+/* number of distance codes */
+
+#define BL_CODES 19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define Buf_size 16
+/* size of bit buffer in bi_buf */
+
+#define INIT_STATE 42 /* zlib header -> BUSY_STATE */
+#ifdef GZIP
+# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */
+#endif
+#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */
+#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */
+#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */
+#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */
+#define BUSY_STATE 113 /* deflate -> FINISH_STATE */
+#define FINISH_STATE 666 /* stream complete */
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+ union {
+ ush freq; /* frequency count */
+ ush code; /* bit string */
+ } fc;
+ union {
+ ush dad; /* father node in Huffman tree */
+ ush len; /* length of bit string */
+ } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad dl.dad
+#define Len dl.len
+
+typedef struct static_tree_desc_s static_tree_desc;
+
+typedef struct tree_desc_s {
+ ct_data *dyn_tree; /* the dynamic tree */
+ int max_code; /* largest code with non zero frequency */
+ const static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+ z_streamp strm; /* pointer back to this zlib stream */
+ int status; /* as the name implies */
+ Bytef *pending_buf; /* output still pending */
+ ulg pending_buf_size; /* size of pending_buf */
+ Bytef *pending_out; /* next pending byte to output to the stream */
+ ulg pending; /* nb of bytes in the pending buffer */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ gz_headerp gzhead; /* gzip header information to write */
+ ulg gzindex; /* where in extra, name, or comment */
+ Byte method; /* can only be DEFLATED */
+ int last_flush; /* value of flush param for previous deflate call */
+
+ /* used by deflate.c: */
+
+ uInt w_size; /* LZ77 window size (32K by default) */
+ uInt w_bits; /* log2(w_size) (8..16) */
+ uInt w_mask; /* w_size - 1 */
+
+ Bytef *window;
+ /* Sliding window. Input bytes are read into the second half of the window,
+ * and move to the first half later to keep a dictionary of at least wSize
+ * bytes. With this organization, matches are limited to a distance of
+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
+ * performed with a length multiple of the block size. Also, it limits
+ * the window size to 64K, which is quite useful on MSDOS.
+ * To do: use the user input buffer as sliding window.
+ */
+
+ ulg window_size;
+ /* Actual size of window: 2*wSize, except when the user input buffer
+ * is directly used as sliding window.
+ */
+
+ Posf *prev;
+ /* Link to older string with same hash index. To limit the size of this
+ * array to 64K, this link is maintained only for the last 32K strings.
+ * An index in this array is thus a window index modulo 32K.
+ */
+
+ Posf *head; /* Heads of the hash chains or NIL. */
+
+ uInt ins_h; /* hash index of string to be inserted */
+ uInt hash_size; /* number of elements in hash table */
+ uInt hash_bits; /* log2(hash_size) */
+ uInt hash_mask; /* hash_size-1 */
+
+ uInt hash_shift;
+ /* Number of bits by which ins_h must be shifted at each input
+ * step. It must be such that after MIN_MATCH steps, the oldest
+ * byte no longer takes part in the hash key, that is:
+ * hash_shift * MIN_MATCH >= hash_bits
+ */
+
+ long block_start;
+ /* Window position at the beginning of the current output block. Gets
+ * negative when the window is moved backwards.
+ */
+
+ uInt match_length; /* length of best match */
+ IPos prev_match; /* previous match */
+ int match_available; /* set if previous match exists */
+ uInt strstart; /* start of string to insert */
+ uInt match_start; /* start of matching string */
+ uInt lookahead; /* number of valid bytes ahead in window */
+
+ uInt prev_length;
+ /* Length of the best match at previous step. Matches not greater than this
+ * are discarded. This is used in the lazy match evaluation.
+ */
+
+ uInt max_chain_length;
+ /* To speed up deflation, hash chains are never searched beyond this
+ * length. A higher limit improves compression ratio but degrades the
+ * speed.
+ */
+
+ uInt max_lazy_match;
+ /* Attempt to find a better match only when the current match is strictly
+ * smaller than this value. This mechanism is used only for compression
+ * levels >= 4.
+ */
+# define max_insert_length max_lazy_match
+ /* Insert new strings in the hash table only if the match length is not
+ * greater than this length. This saves time but degrades compression.
+ * max_insert_length is used only for compression levels <= 3.
+ */
+
+ int level; /* compression level (1..9) */
+ int strategy; /* favor or force Huffman coding*/
+
+ uInt good_match;
+ /* Use a faster search when the previous match is longer than this */
+
+ int nice_match; /* Stop searching when current match exceeds this */
+
+ /* used by trees.c: */
+ /* Didn't use ct_data typedef below to suppress compiler warning */
+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
+
+ struct tree_desc_s l_desc; /* desc. for literal tree */
+ struct tree_desc_s d_desc; /* desc. for distance tree */
+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
+
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
+ int heap_len; /* number of elements in the heap */
+ int heap_max; /* element of largest frequency */
+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+ * The same heap array is used to build all trees.
+ */
+
+ uch depth[2*L_CODES+1];
+ /* Depth of each subtree used as tie breaker for trees of equal frequency
+ */
+
+ uchf *l_buf; /* buffer for literals or lengths */
+
+ uInt lit_bufsize;
+ /* Size of match buffer for literals/lengths. There are 4 reasons for
+ * limiting lit_bufsize to 64K:
+ * - frequencies can be kept in 16 bit counters
+ * - if compression is not successful for the first block, all input
+ * data is still in the window so we can still emit a stored block even
+ * when input comes from standard input. (This can also be done for
+ * all blocks if lit_bufsize is not greater than 32K.)
+ * - if compression is not successful for a file smaller than 64K, we can
+ * even emit a stored file instead of a stored block (saving 5 bytes).
+ * This is applicable only for zip (not gzip or zlib).
+ * - creating new Huffman trees less frequently may not provide fast
+ * adaptation to changes in the input data statistics. (Take for
+ * example a binary file with poorly compressible code followed by
+ * a highly compressible string table.) Smaller buffer sizes give
+ * fast adaptation but have of course the overhead of transmitting
+ * trees more frequently.
+ * - I can't count above 4
+ */
+
+ uInt last_lit; /* running index in l_buf */
+
+ ushf *d_buf;
+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
+ * the same number of elements. To use different lengths, an extra flag
+ * array would be necessary.
+ */
+
+ ulg opt_len; /* bit length of current block with optimal trees */
+ ulg static_len; /* bit length of current block with static trees */
+ uInt matches; /* number of string matches in current block */
+ uInt insert; /* bytes at end of window left to insert */
+
+#ifdef ZLIB_DEBUG
+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
+#endif
+
+ ush bi_buf;
+ /* Output buffer. bits are inserted starting at the bottom (least
+ * significant bits).
+ */
+ int bi_valid;
+ /* Number of valid bits in bi_buf. All bits above the last valid bit
+ * are always zero.
+ */
+
+ ulg high_water;
+ /* High water mark offset in window for initialized bytes -- bytes above
+ * this are set to zero in order to avoid memory check warnings when
+ * longest match routines access bytes past the input. This is then
+ * updated to the new high water mark.
+ */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+#define WIN_INIT MAX_MATCH
+/* Number of bytes after end of data in window to initialize in order to avoid
+ memory checker errors from longest match routines */
+
+ /* in trees.c */
+void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
+int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
+ ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
+ ulg stored_len, int last));
+
+#define d_code(dist) \
+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef ZLIB_DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+ extern uch ZLIB_INTERNAL _length_code[];
+ extern uch ZLIB_INTERNAL _dist_code[];
+#else
+ extern const uch ZLIB_INTERNAL _length_code[];
+ extern const uch ZLIB_INTERNAL _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+ { uch cc = (c); \
+ s->d_buf[s->last_lit] = 0; \
+ s->l_buf[s->last_lit++] = cc; \
+ s->dyn_ltree[cc].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+# define _tr_tally_dist(s, distance, length, flush) \
+ { uch len = (uch)(length); \
+ ush dist = (ush)(distance); \
+ s->d_buf[s->last_lit] = dist; \
+ s->l_buf[s->last_lit++] = len; \
+ dist--; \
+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+ s->dyn_dtree[d_code(dist)].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+ flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
diff --git a/lib/zlib/gzclose.c b/lib/zlib/gzclose.c
new file mode 100644
index 0000000..caeb99a
--- /dev/null
+++ b/lib/zlib/gzclose.c
@@ -0,0 +1,25 @@
+/* gzclose.c -- zlib gzclose() function
+ * Copyright (C) 2004, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* gzclose() is in a separate file so that it is linked in only if it is used.
+ That way the other gzclose functions can be used instead to avoid linking in
+ unneeded compression or decompression routines. */
+int ZEXPORT gzclose(file)
+ gzFile file;
+{
+#ifndef NO_GZCOMPRESS
+ gz_statep state;
+
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
+#else
+ return gzclose_r(file);
+#endif
+}
diff --git a/lib/zlib/gzguts.h b/lib/zlib/gzguts.h
new file mode 100644
index 0000000..85de933
--- /dev/null
+++ b/lib/zlib/gzguts.h
@@ -0,0 +1,218 @@
+/* gzguts.h -- zlib internal header definitions for gz* operations
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifdef _LARGEFILE64_SOURCE
+# ifndef _LARGEFILE_SOURCE
+# define _LARGEFILE_SOURCE 1
+# endif
+# ifdef _FILE_OFFSET_BITS
+# undef _FILE_OFFSET_BITS
+# endif
+#endif
+
+#ifdef HAVE_HIDDEN
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+# define ZLIB_INTERNAL
+#endif
+
+#include "zlib.h"
+#include <stdio.h>
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+# include <limits.h>
+#endif
+
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
+#include <fcntl.h>
+
+#ifdef _WIN32
+# include <stddef.h>
+#endif
+
+#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
+# include <io.h>
+#endif
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define WIDECHAR
+#endif
+
+#ifdef WINAPI_FAMILY
+# define open _open
+# define read _read
+# define write _write
+# define close _close
+#endif
+
+#ifdef NO_DEFLATE /* for compatibility with old definition */
+# define NO_GZCOMPRESS
+#endif
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#if defined(__CYGWIN__)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#ifndef HAVE_VSNPRINTF
+# ifdef MSDOS
+/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+ but for now we just assume it doesn't. */
+# define NO_vsnprintf
+# endif
+# ifdef __TURBOC__
+# define NO_vsnprintf
+# endif
+# ifdef WIN32
+/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+# if !defined(vsnprintf) && !defined(NO_vsnprintf)
+# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
+# define vsnprintf _vsnprintf
+# endif
+# endif
+# endif
+# ifdef __SASC
+# define NO_vsnprintf
+# endif
+# ifdef VMS
+# define NO_vsnprintf
+# endif
+# ifdef __OS400__
+# define NO_vsnprintf
+# endif
+# ifdef __MVS__
+# define NO_vsnprintf
+# endif
+#endif
+
+/* unlike snprintf (which is required in C99), _snprintf does not guarantee
+ null termination of the result -- however this is only used in gzlib.c where
+ the result is assured to fit in the space provided */
+#if defined(_MSC_VER) && _MSC_VER < 1900
+# define snprintf _snprintf
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* since "static" is used to mean two completely different things in C, we
+ define "local" for the non-static meaning of "static", for readability
+ (compile with -Dlocal if your debugger can't find static symbols) */
+
+/* gz* functions always use library allocation functions */
+#ifndef STDC
+ extern voidp malloc OF((uInt size));
+ extern void free OF((voidpf ptr));
+#endif
+
+/* get errno and strerror definition */
+#if defined UNDER_CE
+# include <windows.h>
+# define zstrerror() gz_strwinerror((DWORD)GetLastError())
+#else
+# ifndef NO_STRERROR
+# include <errno.h>
+# define zstrerror() strerror(errno)
+# else
+# define zstrerror() "stdio error (consult errno)"
+# endif
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+#endif
+
+/* default memLevel */
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+
+/* default i/o buffer size -- double this for output when reading (this and
+ twice this must be able to fit in an unsigned type) */
+#define GZBUFSIZE 8192
+
+/* gzip modes, also provide a little integrity check on the passed structure */
+#define GZ_NONE 0
+#define GZ_READ 7247
+#define GZ_WRITE 31153
+#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */
+
+/* values for gz_state how */
+#define LOOK 0 /* look for a gzip header */
+#define COPY 1 /* copy input directly */
+#define GZIP 2 /* decompress a gzip stream */
+
+/* internal gzip file state data structure */
+typedef struct {
+ /* exposed contents for gzgetc() macro */
+ struct gzFile_s x; /* "x" for exposed */
+ /* x.have: number of bytes available at x.next */
+ /* x.next: next output data to deliver or write */
+ /* x.pos: current position in uncompressed data */
+ /* used for both reading and writing */
+ int mode; /* see gzip modes above */
+ int fd; /* file descriptor */
+ char *path; /* path or fd for error messages */
+ unsigned size; /* buffer size, zero if not allocated yet */
+ unsigned want; /* requested buffer size, default is GZBUFSIZE */
+ unsigned char *in; /* input buffer (double-sized when writing) */
+ unsigned char *out; /* output buffer (double-sized when reading) */
+ int direct; /* 0 if processing gzip, 1 if transparent */
+ /* just for reading */
+ int how; /* 0: get header, 1: copy, 2: decompress */
+ z_off64_t start; /* where the gzip data started, for rewinding */
+ int eof; /* true if end of input file reached */
+ int past; /* true if read requested past end */
+ /* just for writing */
+ int level; /* compression level */
+ int strategy; /* compression strategy */
+ /* seek request */
+ z_off64_t skip; /* amount to skip (already rewound if backwards) */
+ int seek; /* true if seek request pending */
+ /* error information */
+ int err; /* error code */
+ char *msg; /* error message */
+ /* zlib inflate or deflate stream */
+ z_stream strm; /* stream structure in-place (not a pointer) */
+} gz_state;
+typedef gz_state FAR *gz_statep;
+
+/* shared functions */
+void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
+#if defined UNDER_CE
+char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
+#endif
+
+/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
+ value -- needed when comparing unsigned to z_off64_t, which is signed
+ (possible z_off64_t types off_t, off64_t, and long are all signed) */
+#ifdef INT_MAX
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
+#else
+unsigned ZLIB_INTERNAL gz_intmax OF((void));
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
+#endif
diff --git a/lib/zlib/gzlib.c b/lib/zlib/gzlib.c
new file mode 100644
index 0000000..4105e6a
--- /dev/null
+++ b/lib/zlib/gzlib.c
@@ -0,0 +1,637 @@
+/* gzlib.c -- zlib functions common to reading and writing gzip files
+ * Copyright (C) 2004-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__)
+# define LSEEK _lseeki64
+#else
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+# define LSEEK lseek64
+#else
+# define LSEEK lseek
+#endif
+#endif
+
+/* Local functions */
+local void gz_reset OF((gz_statep));
+local gzFile gz_open OF((const void *, int, const char *));
+
+#if defined UNDER_CE
+
+/* Map the Windows error number in ERROR to a locale-dependent error message
+ string and return a pointer to it. Typically, the values for ERROR come
+ from GetLastError.
+
+ The string pointed to shall not be modified by the application, but may be
+ overwritten by a subsequent call to gz_strwinerror
+
+ The gz_strwinerror function does not change the current setting of
+ GetLastError. */
+char ZLIB_INTERNAL *gz_strwinerror (error)
+ DWORD error;
+{
+ static char buf[1024];
+
+ wchar_t *msgbuf;
+ DWORD lasterr = GetLastError();
+ DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL,
+ error,
+ 0, /* Default language */
+ (LPVOID)&msgbuf,
+ 0,
+ NULL);
+ if (chars != 0) {
+ /* If there is an \r\n appended, zap it. */
+ if (chars >= 2
+ && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+ chars -= 2;
+ msgbuf[chars] = 0;
+ }
+
+ if (chars > sizeof (buf) - 1) {
+ chars = sizeof (buf) - 1;
+ msgbuf[chars] = 0;
+ }
+
+ wcstombs(buf, msgbuf, chars + 1);
+ LocalFree(msgbuf);
+ }
+ else {
+ sprintf(buf, "unknown win32 error (%ld)", error);
+ }
+
+ SetLastError(lasterr);
+ return buf;
+}
+
+#endif /* UNDER_CE */
+
+/* Reset gzip file state */
+local void gz_reset(state)
+ gz_statep state;
+{
+ state->x.have = 0; /* no output data available */
+ if (state->mode == GZ_READ) { /* for reading ... */
+ state->eof = 0; /* not at end of file */
+ state->past = 0; /* have not read past end yet */
+ state->how = LOOK; /* look for gzip header */
+ }
+ state->seek = 0; /* no seek request pending */
+ gz_error(state, Z_OK, NULL); /* clear error */
+ state->x.pos = 0; /* no uncompressed data yet */
+ state->strm.avail_in = 0; /* no input data yet */
+}
+
+/* Open a gzip file either by name or file descriptor. */
+local gzFile gz_open(path, fd, mode)
+ const void *path;
+ int fd;
+ const char *mode;
+{
+ gz_statep state;
+ z_size_t len;
+ int oflag;
+#ifdef O_CLOEXEC
+ int cloexec = 0;
+#endif
+#ifdef O_EXCL
+ int exclusive = 0;
+#endif
+
+ /* check input */
+ if (path == NULL)
+ return NULL;
+
+ /* allocate gzFile structure to return */
+ state = (gz_statep)malloc(sizeof(gz_state));
+ if (state == NULL)
+ return NULL;
+ state->size = 0; /* no buffers allocated yet */
+ state->want = GZBUFSIZE; /* requested buffer size */
+ state->msg = NULL; /* no error message yet */
+
+ /* interpret mode */
+ state->mode = GZ_NONE;
+ state->level = Z_DEFAULT_COMPRESSION;
+ state->strategy = Z_DEFAULT_STRATEGY;
+ state->direct = 0;
+ while (*mode) {
+ if (*mode >= '0' && *mode <= '9')
+ state->level = *mode - '0';
+ else
+ switch (*mode) {
+ case 'r':
+ state->mode = GZ_READ;
+ break;
+#ifndef NO_GZCOMPRESS
+ case 'w':
+ state->mode = GZ_WRITE;
+ break;
+ case 'a':
+ state->mode = GZ_APPEND;
+ break;
+#endif
+ case '+': /* can't read and write at the same time */
+ free(state);
+ return NULL;
+ case 'b': /* ignore -- will request binary anyway */
+ break;
+#ifdef O_CLOEXEC
+ case 'e':
+ cloexec = 1;
+ break;
+#endif
+#ifdef O_EXCL
+ case 'x':
+ exclusive = 1;
+ break;
+#endif
+ case 'f':
+ state->strategy = Z_FILTERED;
+ break;
+ case 'h':
+ state->strategy = Z_HUFFMAN_ONLY;
+ break;
+ case 'R':
+ state->strategy = Z_RLE;
+ break;
+ case 'F':
+ state->strategy = Z_FIXED;
+ break;
+ case 'T':
+ state->direct = 1;
+ break;
+ default: /* could consider as an error, but just ignore */
+ ;
+ }
+ mode++;
+ }
+
+ /* must provide an "r", "w", or "a" */
+ if (state->mode == GZ_NONE) {
+ free(state);
+ return NULL;
+ }
+
+ /* can't force transparent read */
+ if (state->mode == GZ_READ) {
+ if (state->direct) {
+ free(state);
+ return NULL;
+ }
+ state->direct = 1; /* for empty file */
+ }
+
+ /* save the path name for error messages */
+#ifdef WIDECHAR
+ if (fd == -2) {
+ len = wcstombs(NULL, path, 0);
+ if (len == (z_size_t)-1)
+ len = 0;
+ }
+ else
+#endif
+ len = strlen((const char *)path);
+ state->path = (char *)malloc(len + 1);
+ if (state->path == NULL) {
+ free(state);
+ return NULL;
+ }
+#ifdef WIDECHAR
+ if (fd == -2)
+ if (len)
+ wcstombs(state->path, path, len + 1);
+ else
+ *(state->path) = 0;
+ else
+#endif
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ (void)snprintf(state->path, len + 1, "%s", (const char *)path);
+#else
+ strcpy(state->path, path);
+#endif
+
+ /* compute the flags for open() */
+ oflag =
+#ifdef O_LARGEFILE
+ O_LARGEFILE |
+#endif
+#ifdef O_BINARY
+ O_BINARY |
+#endif
+#ifdef O_CLOEXEC
+ (cloexec ? O_CLOEXEC : 0) |
+#endif
+ (state->mode == GZ_READ ?
+ O_RDONLY :
+ (O_WRONLY | O_CREAT |
+#ifdef O_EXCL
+ (exclusive ? O_EXCL : 0) |
+#endif
+ (state->mode == GZ_WRITE ?
+ O_TRUNC :
+ O_APPEND)));
+
+ /* open the file with the appropriate flags (or just use fd) */
+ state->fd = fd > -1 ? fd : (
+#ifdef WIDECHAR
+ fd == -2 ? _wopen(path, oflag, 0666) :
+#endif
+ open((const char *)path, oflag, 0666));
+ if (state->fd == -1) {
+ free(state->path);
+ free(state);
+ return NULL;
+ }
+ if (state->mode == GZ_APPEND) {
+ LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */
+ state->mode = GZ_WRITE; /* simplify later checks */
+ }
+
+ /* save the current position for rewinding (only if reading) */
+ if (state->mode == GZ_READ) {
+ state->start = LSEEK(state->fd, 0, SEEK_CUR);
+ if (state->start == -1) state->start = 0;
+ }
+
+ /* initialize stream */
+ gz_reset(state);
+
+ /* return stream */
+ return (gzFile)state;
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen(path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen64(path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzdopen(fd, mode)
+ int fd;
+ const char *mode;
+{
+ char *path; /* identifier for error messages */
+ gzFile gz;
+
+ if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
+ return NULL;
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
+#else
+ sprintf(path, "<fd:%d>", fd); /* for debugging */
+#endif
+ gz = gz_open(path, fd, mode);
+ free(path);
+ return gz;
+}
+
+/* -- see zlib.h -- */
+#ifdef WIDECHAR
+gzFile ZEXPORT gzopen_w(path, mode)
+ const wchar_t *path;
+ const char *mode;
+{
+ return gz_open(path, -2, mode);
+}
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzbuffer(file, size)
+ gzFile file;
+ unsigned size;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* make sure we haven't already allocated memory */
+ if (state->size != 0)
+ return -1;
+
+ /* check and set requested size */
+ if ((size << 1) < size)
+ return -1; /* need to be able to double it */
+ if (size < 2)
+ size = 2; /* need two bytes to check magic header */
+ state->want = size;
+ return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzrewind(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* back up and start over */
+ if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
+ return -1;
+ gz_reset(state);
+ return 0;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzseek64(file, offset, whence)
+ gzFile file;
+ z_off64_t offset;
+ int whence;
+{
+ unsigned n;
+ z_off64_t ret;
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* check that there's no error */
+ if (state->err != Z_OK && state->err != Z_BUF_ERROR)
+ return -1;
+
+ /* can only seek from start or relative to current position */
+ if (whence != SEEK_SET && whence != SEEK_CUR)
+ return -1;
+
+ /* normalize offset to a SEEK_CUR specification */
+ if (whence == SEEK_SET)
+ offset -= state->x.pos;
+ else if (state->seek)
+ offset += state->skip;
+ state->seek = 0;
+
+ /* if within raw area while reading, just go there */
+ if (state->mode == GZ_READ && state->how == COPY &&
+ state->x.pos + offset >= 0) {
+ ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
+ if (ret == -1)
+ return -1;
+ state->x.have = 0;
+ state->eof = 0;
+ state->past = 0;
+ state->seek = 0;
+ gz_error(state, Z_OK, NULL);
+ state->strm.avail_in = 0;
+ state->x.pos += offset;
+ return state->x.pos;
+ }
+
+ /* calculate skip amount, rewinding if needed for back seek when reading */
+ if (offset < 0) {
+ if (state->mode != GZ_READ) /* writing -- can't go backwards */
+ return -1;
+ offset += state->x.pos;
+ if (offset < 0) /* before start of file! */
+ return -1;
+ if (gzrewind(file) == -1) /* rewind, then skip to offset */
+ return -1;
+ }
+
+ /* if reading, skip what's in output buffer (one less gzgetc() check) */
+ if (state->mode == GZ_READ) {
+ n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
+ (unsigned)offset : state->x.have;
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
+ offset -= n;
+ }
+
+ /* request skip (if not zero) */
+ if (offset) {
+ state->seek = 1;
+ state->skip = offset;
+ }
+ return state->x.pos + offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzseek(file, offset, whence)
+ gzFile file;
+ z_off_t offset;
+ int whence;
+{
+ z_off64_t ret;
+
+ ret = gzseek64(file, (z_off64_t)offset, whence);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gztell64(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* return position */
+ return state->x.pos + (state->seek ? state->skip : 0);
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gztell(file)
+ gzFile file;
+{
+ z_off64_t ret;
+
+ ret = gztell64(file);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzoffset64(file)
+ gzFile file;
+{
+ z_off64_t offset;
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* compute and return effective offset in file */
+ offset = LSEEK(state->fd, 0, SEEK_CUR);
+ if (offset == -1)
+ return -1;
+ if (state->mode == GZ_READ) /* reading */
+ offset -= state->strm.avail_in; /* don't count buffered input */
+ return offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzoffset(file)
+ gzFile file;
+{
+ z_off64_t ret;
+
+ ret = gzoffset64(file);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzeof(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return 0;
+
+ /* return end-of-file state */
+ return state->mode == GZ_READ ? state->past : 0;
+}
+
+/* -- see zlib.h -- */
+const char * ZEXPORT gzerror(file, errnum)
+ gzFile file;
+ int *errnum;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return NULL;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return NULL;
+
+ /* return error information */
+ if (errnum != NULL)
+ *errnum = state->err;
+ return state->err == Z_MEM_ERROR ? "out of memory" :
+ (state->msg == NULL ? "" : state->msg);
+}
+
+/* -- see zlib.h -- */
+void ZEXPORT gzclearerr(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return;
+
+ /* clear error and end-of-file */
+ if (state->mode == GZ_READ) {
+ state->eof = 0;
+ state->past = 0;
+ }
+ gz_error(state, Z_OK, NULL);
+}
+
+/* Create an error message in allocated memory and set state->err and
+ state->msg accordingly. Free any previous error message already there. Do
+ not try to free or allocate space if the error is Z_MEM_ERROR (out of
+ memory). Simply save the error message as a static string. If there is an
+ allocation failure constructing the error message, then convert the error to
+ out of memory. */
+void ZLIB_INTERNAL gz_error(state, err, msg)
+ gz_statep state;
+ int err;
+ const char *msg;
+{
+ /* free previously allocated message and clear */
+ if (state->msg != NULL) {
+ if (state->err != Z_MEM_ERROR)
+ free(state->msg);
+ state->msg = NULL;
+ }
+
+ /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
+ if (err != Z_OK && err != Z_BUF_ERROR)
+ state->x.have = 0;
+
+ /* set error code, and if no message, then done */
+ state->err = err;
+ if (msg == NULL)
+ return;
+
+ /* for an out of memory error, return literal string when requested */
+ if (err == Z_MEM_ERROR)
+ return;
+
+ /* construct error message with path */
+ if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
+ NULL) {
+ state->err = Z_MEM_ERROR;
+ return;
+ }
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
+ "%s%s%s", state->path, ": ", msg);
+#else
+ strcpy(state->msg, state->path);
+ strcat(state->msg, ": ");
+ strcat(state->msg, msg);
+#endif
+}
+
+#ifndef INT_MAX
+/* portably return maximum value for an int (when limits.h presumed not
+ available) -- we need to do this to cover cases where 2's complement not
+ used, since C standard permits 1's complement and sign-bit representations,
+ otherwise we could just use ((unsigned)-1) >> 1 */
+unsigned ZLIB_INTERNAL gz_intmax()
+{
+ unsigned p, q;
+
+ p = 1;
+ do {
+ q = p;
+ p <<= 1;
+ p++;
+ } while (p > q);
+ return q >> 1;
+}
+#endif
diff --git a/lib/zlib/gzread.c b/lib/zlib/gzread.c
new file mode 100644
index 0000000..956b91e
--- /dev/null
+++ b/lib/zlib/gzread.c
@@ -0,0 +1,654 @@
+/* gzread.c -- zlib functions for reading gzip files
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* Local functions */
+local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
+local int gz_avail OF((gz_statep));
+local int gz_look OF((gz_statep));
+local int gz_decomp OF((gz_statep));
+local int gz_fetch OF((gz_statep));
+local int gz_skip OF((gz_statep, z_off64_t));
+local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
+
+/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
+ state->fd, and update state->eof, state->err, and state->msg as appropriate.
+ This function needs to loop on read(), since read() is not guaranteed to
+ read the number of bytes requested, depending on the type of descriptor. */
+local int gz_load(state, buf, len, have)
+ gz_statep state;
+ unsigned char *buf;
+ unsigned len;
+ unsigned *have;
+{
+ int ret;
+ unsigned get, max = ((unsigned)-1 >> 2) + 1;
+
+ *have = 0;
+ do {
+ get = len - *have;
+ if (get > max)
+ get = max;
+ ret = read(state->fd, buf + *have, get);
+ if (ret <= 0)
+ break;
+ *have += (unsigned)ret;
+ } while (*have < len);
+ if (ret < 0) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ if (ret == 0)
+ state->eof = 1;
+ return 0;
+}
+
+/* Load up input buffer and set eof flag if last data loaded -- return -1 on
+ error, 0 otherwise. Note that the eof flag is set when the end of the input
+ file is reached, even though there may be unused data in the buffer. Once
+ that data has been used, no more attempts will be made to read the file.
+ If strm->avail_in != 0, then the current data is moved to the beginning of
+ the input buffer, and then the remainder of the buffer is loaded with the
+ available data from the input file. */
+local int gz_avail(state)
+ gz_statep state;
+{
+ unsigned got;
+ z_streamp strm = &(state->strm);
+
+ if (state->err != Z_OK && state->err != Z_BUF_ERROR)
+ return -1;
+ if (state->eof == 0) {
+ if (strm->avail_in) { /* copy what's there to the start */
+ unsigned char *p = state->in;
+ unsigned const char *q = strm->next_in;
+ unsigned n = strm->avail_in;
+ do {
+ *p++ = *q++;
+ } while (--n);
+ }
+ if (gz_load(state, state->in + strm->avail_in,
+ state->size - strm->avail_in, &got) == -1)
+ return -1;
+ strm->avail_in += got;
+ strm->next_in = state->in;
+ }
+ return 0;
+}
+
+/* Look for gzip header, set up for inflate or copy. state->x.have must be 0.
+ If this is the first time in, allocate required memory. state->how will be
+ left unchanged if there is no more input data available, will be set to COPY
+ if there is no gzip header and direct copying will be performed, or it will
+ be set to GZIP for decompression. If direct copying, then leftover input
+ data from the input buffer will be copied to the output buffer. In that
+ case, all further file reads will be directly to either the output buffer or
+ a user buffer. If decompressing, the inflate state will be initialized.
+ gz_look() will return 0 on success or -1 on failure. */
+local int gz_look(state)
+ gz_statep state;
+{
+ z_streamp strm = &(state->strm);
+
+ /* allocate read buffers and inflate memory */
+ if (state->size == 0) {
+ /* allocate buffers */
+ state->in = (unsigned char *)malloc(state->want);
+ state->out = (unsigned char *)malloc(state->want << 1);
+ if (state->in == NULL || state->out == NULL) {
+ free(state->out);
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ state->size = state->want;
+
+ /* allocate inflate memory */
+ state->strm.zalloc = Z_NULL;
+ state->strm.zfree = Z_NULL;
+ state->strm.opaque = Z_NULL;
+ state->strm.avail_in = 0;
+ state->strm.next_in = Z_NULL;
+ if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */
+ free(state->out);
+ free(state->in);
+ state->size = 0;
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ }
+
+ /* get at least the magic bytes in the input buffer */
+ if (strm->avail_in < 2) {
+ if (gz_avail(state) == -1)
+ return -1;
+ if (strm->avail_in == 0)
+ return 0;
+ }
+
+ /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
+ a logical dilemma here when considering the case of a partially written
+ gzip file, to wit, if a single 31 byte is written, then we cannot tell
+ whether this is a single-byte file, or just a partially written gzip
+ file -- for here we assume that if a gzip file is being written, then
+ the header will be written in a single operation, so that reading a
+ single byte is sufficient indication that it is not a gzip file) */
+ if (strm->avail_in > 1 &&
+ strm->next_in[0] == 31 && strm->next_in[1] == 139) {
+ inflateReset(strm);
+ state->how = GZIP;
+ state->direct = 0;
+ return 0;
+ }
+
+ /* no gzip header -- if we were decoding gzip before, then this is trailing
+ garbage. Ignore the trailing garbage and finish. */
+ if (state->direct == 0) {
+ strm->avail_in = 0;
+ state->eof = 1;
+ state->x.have = 0;
+ return 0;
+ }
+
+ /* doing raw i/o, copy any leftover input to output -- this assumes that
+ the output buffer is larger than the input buffer, which also assures
+ space for gzungetc() */
+ state->x.next = state->out;
+ if (strm->avail_in) {
+ memcpy(state->x.next, strm->next_in, strm->avail_in);
+ state->x.have = strm->avail_in;
+ strm->avail_in = 0;
+ }
+ state->how = COPY;
+ state->direct = 1;
+ return 0;
+}
+
+/* Decompress from input to the provided next_out and avail_out in the state.
+ On return, state->x.have and state->x.next point to the just decompressed
+ data. If the gzip stream completes, state->how is reset to LOOK to look for
+ the next gzip stream or raw data, once state->x.have is depleted. Returns 0
+ on success, -1 on failure. */
+local int gz_decomp(state)
+ gz_statep state;
+{
+ int ret = Z_OK;
+ unsigned had;
+ z_streamp strm = &(state->strm);
+
+ /* fill output buffer up to end of deflate stream */
+ had = strm->avail_out;
+ do {
+ /* get more input for inflate() */
+ if (strm->avail_in == 0 && gz_avail(state) == -1)
+ return -1;
+ if (strm->avail_in == 0) {
+ gz_error(state, Z_BUF_ERROR, "unexpected end of file");
+ break;
+ }
+
+ /* decompress and handle errors */
+ ret = inflate(strm, Z_NO_FLUSH);
+ if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
+ gz_error(state, Z_STREAM_ERROR,
+ "internal error: inflate stream corrupt");
+ return -1;
+ }
+ if (ret == Z_MEM_ERROR) {
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
+ gz_error(state, Z_DATA_ERROR,
+ strm->msg == NULL ? "compressed data error" : strm->msg);
+ return -1;
+ }
+ } while (strm->avail_out && ret != Z_STREAM_END);
+
+ /* update available output */
+ state->x.have = had - strm->avail_out;
+ state->x.next = strm->next_out - state->x.have;
+
+ /* if the gzip stream completed successfully, look for another */
+ if (ret == Z_STREAM_END)
+ state->how = LOOK;
+
+ /* good decompression */
+ return 0;
+}
+
+/* Fetch data and put it in the output buffer. Assumes state->x.have is 0.
+ Data is either copied from the input file or decompressed from the input
+ file depending on state->how. If state->how is LOOK, then a gzip header is
+ looked for to determine whether to copy or decompress. Returns -1 on error,
+ otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the
+ end of the input file has been reached and all data has been processed. */
+local int gz_fetch(state)
+ gz_statep state;
+{
+ z_streamp strm = &(state->strm);
+
+ do {
+ switch(state->how) {
+ case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */
+ if (gz_look(state) == -1)
+ return -1;
+ if (state->how == LOOK)
+ return 0;
+ break;
+ case COPY: /* -> COPY */
+ if (gz_load(state, state->out, state->size << 1, &(state->x.have))
+ == -1)
+ return -1;
+ state->x.next = state->out;
+ return 0;
+ case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */
+ strm->avail_out = state->size << 1;
+ strm->next_out = state->out;
+ if (gz_decomp(state) == -1)
+ return -1;
+ }
+ } while (state->x.have == 0 && (!state->eof || strm->avail_in));
+ return 0;
+}
+
+/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
+local int gz_skip(state, len)
+ gz_statep state;
+ z_off64_t len;
+{
+ unsigned n;
+
+ /* skip over len bytes or reach end-of-file, whichever comes first */
+ while (len)
+ /* skip over whatever is in output buffer */
+ if (state->x.have) {
+ n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
+ (unsigned)len : state->x.have;
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
+ len -= n;
+ }
+
+ /* output buffer empty -- return if we're at the end of the input */
+ else if (state->eof && state->strm.avail_in == 0)
+ break;
+
+ /* need more data to skip -- load up output buffer */
+ else {
+ /* get more output, looking for header if required */
+ if (gz_fetch(state) == -1)
+ return -1;
+ }
+ return 0;
+}
+
+/* Read len bytes into buf from file, or less than len up to the end of the
+ input. Return the number of bytes read. If zero is returned, either the
+ end of file was reached, or there was an error. state->err must be
+ consulted in that case to determine which. */
+local z_size_t gz_read(state, buf, len)
+ gz_statep state;
+ voidp buf;
+ z_size_t len;
+{
+ z_size_t got;
+ unsigned n;
+
+ /* if len is zero, avoid unnecessary operations */
+ if (len == 0)
+ return 0;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return 0;
+ }
+
+ /* get len bytes to buf, or less than len if at the end */
+ got = 0;
+ do {
+ /* set n to the maximum amount of len that fits in an unsigned int */
+ n = -1;
+ if (n > len)
+ n = len;
+
+ /* first just try copying data from the output buffer */
+ if (state->x.have) {
+ if (state->x.have < n)
+ n = state->x.have;
+ memcpy(buf, state->x.next, n);
+ state->x.next += n;
+ state->x.have -= n;
+ }
+
+ /* output buffer empty -- return if we're at the end of the input */
+ else if (state->eof && state->strm.avail_in == 0) {
+ state->past = 1; /* tried to read past end */
+ break;
+ }
+
+ /* need output data -- for small len or new stream load up our output
+ buffer */
+ else if (state->how == LOOK || n < (state->size << 1)) {
+ /* get more output, looking for header if required */
+ if (gz_fetch(state) == -1)
+ return 0;
+ continue; /* no progress yet -- go back to copy above */
+ /* the copy above assures that we will leave with space in the
+ output buffer, allowing at least one gzungetc() to succeed */
+ }
+
+ /* large len -- read directly into user buffer */
+ else if (state->how == COPY) { /* read directly */
+ if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
+ return 0;
+ }
+
+ /* large len -- decompress directly into user buffer */
+ else { /* state->how == GZIP */
+ state->strm.avail_out = n;
+ state->strm.next_out = (unsigned char *)buf;
+ if (gz_decomp(state) == -1)
+ return 0;
+ n = state->x.have;
+ state->x.have = 0;
+ }
+
+ /* update progress */
+ len -= n;
+ buf = (char *)buf + n;
+ got += n;
+ state->x.pos += n;
+ } while (len);
+
+ /* return number of bytes read into user buffer */
+ return got;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzread(file, buf, len)
+ gzFile file;
+ voidp buf;
+ unsigned len;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* since an int is returned, make sure len fits in one, otherwise return
+ with an error (this avoids a flaw in the interface) */
+ if ((int)len < 0) {
+ gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
+ return -1;
+ }
+
+ /* read len or fewer bytes to buf */
+ len = gz_read(state, buf, len);
+
+ /* check for an error */
+ if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
+ return -1;
+
+ /* return the number of bytes read (this is assured to fit in an int) */
+ return (int)len;
+}
+
+/* -- see zlib.h -- */
+z_size_t ZEXPORT gzfread(buf, size, nitems, file)
+ voidp buf;
+ z_size_t size;
+ z_size_t nitems;
+ gzFile file;
+{
+ z_size_t len;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return 0;
+
+ /* compute bytes to read -- error on overflow */
+ len = nitems * size;
+ if (size && len / size != nitems) {
+ gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
+ return 0;
+ }
+
+ /* read len or fewer bytes to buf, return the number of full items read */
+ return len ? gz_read(state, buf, len) / size : 0;
+}
+
+/* -- see zlib.h -- */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+#else
+# undef gzgetc
+#endif
+int ZEXPORT gzgetc(file)
+ gzFile file;
+{
+ int ret;
+ unsigned char buf[1];
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* try output buffer (no need to check for skip request) */
+ if (state->x.have) {
+ state->x.have--;
+ state->x.pos++;
+ return *(state->x.next)++;
+ }
+
+ /* nothing there -- try gz_read() */
+ ret = gz_read(state, buf, 1);
+ return ret < 1 ? -1 : buf[0];
+}
+
+int ZEXPORT gzgetc_(file)
+gzFile file;
+{
+ return gzgetc(file);
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzungetc(c, file)
+ int c;
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* can't push EOF */
+ if (c < 0)
+ return -1;
+
+ /* if output buffer empty, put byte at end (allows more pushing) */
+ if (state->x.have == 0) {
+ state->x.have = 1;
+ state->x.next = state->out + (state->size << 1) - 1;
+ state->x.next[0] = (unsigned char)c;
+ state->x.pos--;
+ state->past = 0;
+ return c;
+ }
+
+ /* if no room, give up (must have already done a gzungetc()) */
+ if (state->x.have == (state->size << 1)) {
+ gz_error(state, Z_DATA_ERROR, "out of room to push characters");
+ return -1;
+ }
+
+ /* slide output data if needed and insert byte before existing data */
+ if (state->x.next == state->out) {
+ unsigned char *src = state->out + state->x.have;
+ unsigned char *dest = state->out + (state->size << 1);
+ while (src > state->out)
+ *--dest = *--src;
+ state->x.next = dest;
+ }
+ state->x.have++;
+ state->x.next--;
+ state->x.next[0] = (unsigned char)c;
+ state->x.pos--;
+ state->past = 0;
+ return c;
+}
+
+/* -- see zlib.h -- */
+char * ZEXPORT gzgets(file, buf, len)
+ gzFile file;
+ char *buf;
+ int len;
+{
+ unsigned left, n;
+ char *str;
+ unsigned char *eol;
+ gz_statep state;
+
+ /* check parameters and get internal structure */
+ if (file == NULL || buf == NULL || len < 1)
+ return NULL;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return NULL;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return NULL;
+ }
+
+ /* copy output bytes up to new line or len - 1, whichever comes first --
+ append a terminating zero to the string (we don't check for a zero in
+ the contents, let the user worry about that) */
+ str = buf;
+ left = (unsigned)len - 1;
+ if (left) do {
+ /* assure that something is in the output buffer */
+ if (state->x.have == 0 && gz_fetch(state) == -1)
+ return NULL; /* error */
+ if (state->x.have == 0) { /* end of file */
+ state->past = 1; /* read past end */
+ break; /* return what we have */
+ }
+
+ /* look for end-of-line in current output buffer */
+ n = state->x.have > left ? left : state->x.have;
+ eol = (unsigned char *)memchr(state->x.next, '\n', n);
+ if (eol != NULL)
+ n = (unsigned)(eol - state->x.next) + 1;
+
+ /* copy through end-of-line, or remainder if not found */
+ memcpy(buf, state->x.next, n);
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
+ left -= n;
+ buf += n;
+ } while (left && eol == NULL);
+
+ /* return terminated string, or if nothing, end of file */
+ if (buf == str)
+ return NULL;
+ buf[0] = 0;
+ return str;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzdirect(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* if the state is not known, but we can find out, then do so (this is
+ mainly for right after a gzopen() or gzdopen()) */
+ if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
+ (void)gz_look(state);
+
+ /* return 1 if transparent, 0 if processing a gzip stream */
+ return state->direct;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_r(file)
+ gzFile file;
+{
+ int ret, err;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ /* check that we're reading */
+ if (state->mode != GZ_READ)
+ return Z_STREAM_ERROR;
+
+ /* free memory and close file */
+ if (state->size) {
+ inflateEnd(&(state->strm));
+ free(state->out);
+ free(state->in);
+ }
+ err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
+ gz_error(state, Z_OK, NULL);
+ free(state->path);
+ ret = close(state->fd);
+ free(state);
+ return ret ? Z_ERRNO : err;
+}
diff --git a/lib/zlib/gzwrite.c b/lib/zlib/gzwrite.c
new file mode 100644
index 0000000..c7b5651
--- /dev/null
+++ b/lib/zlib/gzwrite.c
@@ -0,0 +1,665 @@
+/* gzwrite.c -- zlib functions for writing gzip files
+ * Copyright (C) 2004-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* Local functions */
+local int gz_init OF((gz_statep));
+local int gz_comp OF((gz_statep, int));
+local int gz_zero OF((gz_statep, z_off64_t));
+local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
+
+/* Initialize state for writing a gzip file. Mark initialization by setting
+ state->size to non-zero. Return -1 on a memory allocation failure, or 0 on
+ success. */
+local int gz_init(state)
+ gz_statep state;
+{
+ int ret;
+ z_streamp strm = &(state->strm);
+
+ /* allocate input buffer (double size for gzprintf) */
+ state->in = (unsigned char *)malloc(state->want << 1);
+ if (state->in == NULL) {
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+
+ /* only need output buffer and deflate state if compressing */
+ if (!state->direct) {
+ /* allocate output buffer */
+ state->out = (unsigned char *)malloc(state->want);
+ if (state->out == NULL) {
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+
+ /* allocate deflate memory, set up for gzip compression */
+ strm->zalloc = Z_NULL;
+ strm->zfree = Z_NULL;
+ strm->opaque = Z_NULL;
+ ret = deflateInit2(strm, state->level, Z_DEFLATED,
+ MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
+ if (ret != Z_OK) {
+ free(state->out);
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ strm->next_in = NULL;
+ }
+
+ /* mark state as initialized */
+ state->size = state->want;
+
+ /* initialize write buffer if compressing */
+ if (!state->direct) {
+ strm->avail_out = state->size;
+ strm->next_out = state->out;
+ state->x.next = strm->next_out;
+ }
+ return 0;
+}
+
+/* Compress whatever is at avail_in and next_in and write to the output file.
+ Return -1 if there is an error writing to the output file or if gz_init()
+ fails to allocate memory, otherwise 0. flush is assumed to be a valid
+ deflate() flush value. If flush is Z_FINISH, then the deflate() state is
+ reset to start a new gzip stream. If gz->direct is true, then simply write
+ to the output file without compressing, and ignore flush. */
+local int gz_comp(state, flush)
+ gz_statep state;
+ int flush;
+{
+ int ret, writ;
+ unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
+ z_streamp strm = &(state->strm);
+
+ /* allocate memory if this is the first time through */
+ if (state->size == 0 && gz_init(state) == -1)
+ return -1;
+
+ /* write directly if requested */
+ if (state->direct) {
+ while (strm->avail_in) {
+ put = strm->avail_in > max ? max : strm->avail_in;
+ writ = write(state->fd, strm->next_in, put);
+ if (writ < 0) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ strm->avail_in -= (unsigned)writ;
+ strm->next_in += writ;
+ }
+ return 0;
+ }
+
+ /* run deflate() on provided input until it produces no more output */
+ ret = Z_OK;
+ do {
+ /* write out current buffer contents if full, or if flushing, but if
+ doing Z_FINISH then don't write until we get to Z_STREAM_END */
+ if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
+ (flush != Z_FINISH || ret == Z_STREAM_END))) {
+ while (strm->next_out > state->x.next) {
+ put = strm->next_out - state->x.next > (int)max ? max :
+ (unsigned)(strm->next_out - state->x.next);
+ writ = write(state->fd, state->x.next, put);
+ if (writ < 0) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ state->x.next += writ;
+ }
+ if (strm->avail_out == 0) {
+ strm->avail_out = state->size;
+ strm->next_out = state->out;
+ state->x.next = state->out;
+ }
+ }
+
+ /* compress */
+ have = strm->avail_out;
+ ret = deflate(strm, flush);
+ if (ret == Z_STREAM_ERROR) {
+ gz_error(state, Z_STREAM_ERROR,
+ "internal error: deflate stream corrupt");
+ return -1;
+ }
+ have -= strm->avail_out;
+ } while (have);
+
+ /* if that completed a deflate stream, allow another to start */
+ if (flush == Z_FINISH)
+ deflateReset(strm);
+
+ /* all done, no errors */
+ return 0;
+}
+
+/* Compress len zeros to output. Return -1 on a write error or memory
+ allocation failure by gz_comp(), or 0 on success. */
+local int gz_zero(state, len)
+ gz_statep state;
+ z_off64_t len;
+{
+ int first;
+ unsigned n;
+ z_streamp strm = &(state->strm);
+
+ /* consume whatever's left in the input buffer */
+ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return -1;
+
+ /* compress len zeros (len guaranteed > 0) */
+ first = 1;
+ while (len) {
+ n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
+ (unsigned)len : state->size;
+ if (first) {
+ memset(state->in, 0, n);
+ first = 0;
+ }
+ strm->avail_in = n;
+ strm->next_in = state->in;
+ state->x.pos += n;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return -1;
+ len -= n;
+ }
+ return 0;
+}
+
+/* Write len bytes from buf to file. Return the number of bytes written. If
+ the returned value is less than len, then there was an error. */
+local z_size_t gz_write(state, buf, len)
+ gz_statep state;
+ voidpc buf;
+ z_size_t len;
+{
+ z_size_t put = len;
+
+ /* if len is zero, avoid unnecessary operations */
+ if (len == 0)
+ return 0;
+
+ /* allocate memory if this is the first time through */
+ if (state->size == 0 && gz_init(state) == -1)
+ return 0;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return 0;
+ }
+
+ /* for small len, copy to input buffer, otherwise compress directly */
+ if (len < state->size) {
+ /* copy to input buffer, compress when full */
+ do {
+ unsigned have, copy;
+
+ if (state->strm.avail_in == 0)
+ state->strm.next_in = state->in;
+ have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
+ state->in);
+ copy = state->size - have;
+ if (copy > len)
+ copy = len;
+ memcpy(state->in + have, buf, copy);
+ state->strm.avail_in += copy;
+ state->x.pos += copy;
+ buf = (const char *)buf + copy;
+ len -= copy;
+ if (len && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+ } while (len);
+ }
+ else {
+ /* consume whatever's left in the input buffer */
+ if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+
+ /* directly compress user buffer to file */
+ state->strm.next_in = (z_const Bytef *)buf;
+ do {
+ unsigned n = (unsigned)-1;
+ if (n > len)
+ n = len;
+ state->strm.avail_in = n;
+ state->x.pos += n;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+ len -= n;
+ } while (len);
+ }
+
+ /* input was all buffered or compressed */
+ return put;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzwrite(file, buf, len)
+ gzFile file;
+ voidpc buf;
+ unsigned len;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return 0;
+
+ /* since an int is returned, make sure len fits in one, otherwise return
+ with an error (this avoids a flaw in the interface) */
+ if ((int)len < 0) {
+ gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
+ return 0;
+ }
+
+ /* write len bytes from buf (the return value will fit in an int) */
+ return (int)gz_write(state, buf, len);
+}
+
+/* -- see zlib.h -- */
+z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
+ voidpc buf;
+ z_size_t size;
+ z_size_t nitems;
+ gzFile file;
+{
+ z_size_t len;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return 0;
+
+ /* compute bytes to read -- error on overflow */
+ len = nitems * size;
+ if (size && len / size != nitems) {
+ gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
+ return 0;
+ }
+
+ /* write len bytes to buf, return the number of full items written */
+ return len ? gz_write(state, buf, len) / size : 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputc(file, c)
+ gzFile file;
+ int c;
+{
+ unsigned have;
+ unsigned char buf[1];
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return -1;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* try writing to input buffer for speed (state->size == 0 if buffer not
+ initialized) */
+ if (state->size) {
+ if (strm->avail_in == 0)
+ strm->next_in = state->in;
+ have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
+ if (have < state->size) {
+ state->in[have] = (unsigned char)c;
+ strm->avail_in++;
+ state->x.pos++;
+ return c & 0xff;
+ }
+ }
+
+ /* no room in buffer or not initialized, use gz_write() */
+ buf[0] = (unsigned char)c;
+ if (gz_write(state, buf, 1) != 1)
+ return -1;
+ return c & 0xff;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputs(file, str)
+ gzFile file;
+ const char *str;
+{
+ int ret;
+ z_size_t len;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return -1;
+
+ /* write string */
+ len = strlen(str);
+ ret = gz_write(state, str, len);
+ return ret == 0 && len != 0 ? -1 : ret;
+}
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#include <stdarg.h>
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
+{
+ int len;
+ unsigned left;
+ char *next;
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* make sure we have some buffer space */
+ if (state->size == 0 && gz_init(state) == -1)
+ return state->err;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return state->err;
+ }
+
+ /* do the printf() into the input buffer, put length in len -- the input
+ buffer is double-sized just for this function, so there is guaranteed to
+ be state->size bytes available after the current contents */
+ if (strm->avail_in == 0)
+ strm->next_in = state->in;
+ next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
+ next[state->size - 1] = 0;
+#ifdef NO_vsnprintf
+# ifdef HAS_vsprintf_void
+ (void)vsprintf(next, format, va);
+ for (len = 0; len < state->size; len++)
+ if (next[len] == 0) break;
+# else
+ len = vsprintf(next, format, va);
+# endif
+#else
+# ifdef HAS_vsnprintf_void
+ (void)vsnprintf(next, state->size, format, va);
+ len = strlen(next);
+# else
+ len = vsnprintf(next, state->size, format, va);
+# endif
+#endif
+
+ /* check that printf() results fit in buffer */
+ if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
+ return 0;
+
+ /* update buffer and position, compress first half if past that */
+ strm->avail_in += (unsigned)len;
+ state->x.pos += len;
+ if (strm->avail_in >= state->size) {
+ left = strm->avail_in - state->size;
+ strm->avail_in = state->size;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return state->err;
+ memcpy(state->in, state->in + state->size, left);
+ strm->next_in = state->in;
+ strm->avail_in = left;
+ }
+ return len;
+}
+
+int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
+{
+ va_list va;
+ int ret;
+
+ va_start(va, format);
+ ret = gzvprintf(file, format, va);
+ va_end(va);
+ return ret;
+}
+
+#else /* !STDC && !Z_HAVE_STDARG_H */
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+ gzFile file;
+ const char *format;
+ int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+ unsigned len, left;
+ char *next;
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that can really pass pointer in ints */
+ if (sizeof(int) != sizeof(void *))
+ return Z_STREAM_ERROR;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* make sure we have some buffer space */
+ if (state->size == 0 && gz_init(state) == -1)
+ return state->error;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return state->error;
+ }
+
+ /* do the printf() into the input buffer, put length in len -- the input
+ buffer is double-sized just for this function, so there is guaranteed to
+ be state->size bytes available after the current contents */
+ if (strm->avail_in == 0)
+ strm->next_in = state->in;
+ next = (char *)(strm->next_in + strm->avail_in);
+ next[state->size - 1] = 0;
+#ifdef NO_snprintf
+# ifdef HAS_sprintf_void
+ sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
+ a13, a14, a15, a16, a17, a18, a19, a20);
+ for (len = 0; len < size; len++)
+ if (next[len] == 0)
+ break;
+# else
+ len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
+ a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#else
+# ifdef HAS_snprintf_void
+ snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ len = strlen(next);
+# else
+ len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#endif
+
+ /* check that printf() results fit in buffer */
+ if (len == 0 || len >= state->size || next[state->size - 1] != 0)
+ return 0;
+
+ /* update buffer and position, compress first half if past that */
+ strm->avail_in += len;
+ state->x.pos += len;
+ if (strm->avail_in >= state->size) {
+ left = strm->avail_in - state->size;
+ strm->avail_in = state->size;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return state->err;
+ memcpy(state->in, state->in + state->size, left);
+ strm->next_in = state->in;
+ strm->avail_in = left;
+ }
+ return (int)len;
+}
+
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzflush(file, flush)
+ gzFile file;
+ int flush;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* check flush parameter */
+ if (flush < 0 || flush > Z_FINISH)
+ return Z_STREAM_ERROR;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return state->err;
+ }
+
+ /* compress remaining data with requested flush */
+ (void)gz_comp(state, flush);
+ return state->err;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzsetparams(file, level, strategy)
+ gzFile file;
+ int level;
+ int strategy;
+{
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* if no change is requested, then do nothing */
+ if (level == state->level && strategy == state->strategy)
+ return Z_OK;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return state->err;
+ }
+
+ /* change compression parameters for subsequent input */
+ if (state->size) {
+ /* flush previous input with previous parameters before changing */
+ if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
+ return state->err;
+ deflateParams(strm, level, strategy);
+ }
+ state->level = level;
+ state->strategy = strategy;
+ return Z_OK;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_w(file)
+ gzFile file;
+{
+ int ret = Z_OK;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ /* check that we're writing */
+ if (state->mode != GZ_WRITE)
+ return Z_STREAM_ERROR;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ ret = state->err;
+ }
+
+ /* flush, free memory, and close file */
+ if (gz_comp(state, Z_FINISH) == -1)
+ ret = state->err;
+ if (state->size) {
+ if (!state->direct) {
+ (void)deflateEnd(&(state->strm));
+ free(state->out);
+ }
+ free(state->in);
+ }
+ gz_error(state, Z_OK, NULL);
+ free(state->path);
+ if (close(state->fd) == -1)
+ ret = Z_ERRNO;
+ free(state);
+ return ret;
+}
diff --git a/lib/zlib/infback.c b/lib/zlib/infback.c
new file mode 100644
index 0000000..59679ec
--- /dev/null
+++ b/lib/zlib/infback.c
@@ -0,0 +1,640 @@
+/* infback.c -- inflate using a call-back interface
+ * Copyright (C) 1995-2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ This code is largely copied from inflate.c. Normally either infback.o or
+ inflate.o would be linked into an application--not both. The interface
+ with inffast.c is retained so that optimized assembler-coded versions of
+ inflate_fast() can be used with either inflate.c or infback.c.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+
+/*
+ strm provides memory allocation functions in zalloc and zfree, or
+ Z_NULL to use the library memory allocation functions.
+
+ windowBits is in the range 8..15, and window is a user-supplied
+ window and output buffer that is 2**windowBits bytes.
+ */
+int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
+z_streamp strm;
+int windowBits;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL || window == Z_NULL ||
+ windowBits < 8 || windowBits > 15)
+ return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+#endif
+ }
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
+ state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+ sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (struct internal_state FAR *)state;
+ state->dmax = 32768U;
+ state->wbits = (uInt)windowBits;
+ state->wsize = 1U << windowBits;
+ state->window = window;
+ state->wnext = 0;
+ state->whave = 0;
+ return Z_OK;
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+/* Macros for inflateBack(): */
+
+/* Load returned state from inflate_fast() */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Set state from registers for inflate_fast() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Assure that some input is available. If input is requested, but denied,
+ then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+ do { \
+ if (have == 0) { \
+ have = in(in_desc, &next); \
+ if (have == 0) { \
+ next = Z_NULL; \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+ with an error if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ PULL(); \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflateBack() with
+ an error. */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/* Assure that some output space is available, by writing out the window
+ if it's full. If the write fails, return from inflateBack() with a
+ Z_BUF_ERROR. */
+#define ROOM() \
+ do { \
+ if (left == 0) { \
+ put = state->window; \
+ left = state->wsize; \
+ state->whave = left; \
+ if (out(out_desc, put, left)) { \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/*
+ strm provides the memory allocation functions and window buffer on input,
+ and provides information on the unused input on return. For Z_DATA_ERROR
+ returns, strm will also provide an error message.
+
+ in() and out() are the call-back input and output functions. When
+ inflateBack() needs more input, it calls in(). When inflateBack() has
+ filled the window with output, or when it completes with data in the
+ window, it calls out() to write out the data. The application must not
+ change the provided input until in() is called again or inflateBack()
+ returns. The application must not change the window/output buffer until
+ inflateBack() returns.
+
+ in() and out() are called with a descriptor parameter provided in the
+ inflateBack() call. This parameter can be a structure that provides the
+ information required to do the read or write, as well as accumulated
+ information on the input and output such as totals and check values.
+
+ in() should return zero on failure. out() should return non-zero on
+ failure. If either in() or out() fails, than inflateBack() returns a
+ Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
+ was in() or out() that caused in the error. Otherwise, inflateBack()
+ returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+ error, or Z_MEM_ERROR if it could not allocate memory for the state.
+ inflateBack() can also return Z_STREAM_ERROR if the input parameters
+ are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
+z_streamp strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+ struct inflate_state FAR *state;
+ z_const unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code here; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ /* Check that the strm exists and that the state was initialized */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* Reset the state */
+ strm->msg = Z_NULL;
+ state->mode = TYPE;
+ state->last = 0;
+ state->whave = 0;
+ next = strm->next_in;
+ have = next != Z_NULL ? strm->avail_in : 0;
+ hold = 0;
+ bits = 0;
+ put = state->window;
+ left = state->wsize;
+
+ /* Inflate until end of block marked as last */
+ for (;;)
+ switch (state->mode) {
+ case TYPE:
+ /* determine and dispatch block type */
+ if (state->last) {
+ BYTEBITS();
+ state->mode = DONE;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN; /* decode codes */
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+
+ case STORED:
+ /* get and verify stored block length */
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+
+ /* copy stored block from input to output */
+ while (state->length != 0) {
+ copy = state->length;
+ PULL();
+ ROOM();
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+
+ case TABLE:
+ /* get dynamic table entries descriptor */
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+
+ /* get code length code lengths (not a typo) */
+ state->have = 0;
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+
+ /* get length and distance code code lengths */
+ state->have = 0;
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.val < 16) {
+ DROPBITS(here.bits);
+ state->lens[state->have++] = here.val;
+ }
+ else {
+ if (here.val == 16) {
+ NEEDBITS(here.bits + 2);
+ DROPBITS(here.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = (unsigned)(state->lens[state->have - 1]);
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (here.val == 17) {
+ NEEDBITS(here.bits + 3);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(here.bits + 7);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* check for end-of-block code (better have one) */
+ if (state->lens[256] == 0) {
+ strm->msg = (char *)"invalid code -- missing end-of-block";
+ state->mode = BAD;
+ break;
+ }
+
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftrees.h
+ concerning the ENOUGH constants, which depend on those values */
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (code const FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN;
+
+ case LEN:
+ /* use inflate_fast() if we have enough input and output */
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ if (state->whave < state->wsize)
+ state->whave = state->wsize - left;
+ inflate_fast(strm, state->wsize);
+ LOAD();
+ break;
+ }
+
+ /* get a literal, length, or end-of-block code */
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(here.bits);
+ state->length = (unsigned)here.val;
+
+ /* process literal */
+ if (here.op == 0) {
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", here.val));
+ ROOM();
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ }
+
+ /* process end of block */
+ if (here.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+
+ /* invalid code */
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+
+ /* length code -- get extra bits, if any */
+ state->extra = (unsigned)(here.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+
+ /* get distance code */
+ for (;;) {
+ here = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(here.bits);
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)here.val;
+
+ /* get distance extra bits, if any */
+ state->extra = (unsigned)(here.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ if (state->offset > state->wsize - (state->whave < state->wsize ?
+ left : 0)) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+
+ /* copy match from window to output */
+ do {
+ ROOM();
+ copy = state->wsize - state->offset;
+ if (copy < left) {
+ from = put + copy;
+ copy = left - copy;
+ }
+ else {
+ from = put - state->offset;
+ copy = left;
+ }
+ if (copy > state->length) copy = state->length;
+ state->length -= copy;
+ left -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ } while (state->length != 0);
+ break;
+
+ case DONE:
+ /* inflate stream terminated properly -- write leftover output */
+ ret = Z_STREAM_END;
+ if (left < state->wsize) {
+ if (out(out_desc, state->window, state->wsize - left))
+ ret = Z_BUF_ERROR;
+ }
+ goto inf_leave;
+
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+
+ default: /* can't happen, but makes compilers happy */
+ ret = Z_STREAM_ERROR;
+ goto inf_leave;
+ }
+
+ /* Return unused input */
+ inf_leave:
+ strm->next_in = next;
+ strm->avail_in = have;
+ return ret;
+}
+
+int ZEXPORT inflateBackEnd(strm)
+z_streamp strm;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
diff --git a/lib/zlib/inffast.c b/lib/zlib/inffast.c
new file mode 100644
index 0000000..0dbd1db
--- /dev/null
+++ b/lib/zlib/inffast.c
@@ -0,0 +1,323 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef ASMINF
+# pragma message("Assembler code may have bugs -- use at your own risk")
+#else
+
+/*
+ Decode literal, length, and distance codes and write out the resulting
+ literal and match bytes until either not enough input or output is
+ available, an end-of-block is encountered, or a data error is encountered.
+ When large enough input and output buffers are supplied to inflate(), for
+ example, a 16K input buffer and a 64K output buffer, more than 95% of the
+ inflate execution time is spent in this routine.
+
+ Entry assumptions:
+
+ state->mode == LEN
+ strm->avail_in >= 6
+ strm->avail_out >= 258
+ start >= strm->avail_out
+ state->bits < 8
+
+ On return, state->mode is one of:
+
+ LEN -- ran out of enough output space or enough available input
+ TYPE -- reached end of block code, inflate() to interpret next block
+ BAD -- error in block data
+
+ Notes:
+
+ - The maximum input bits used by a length/distance pair is 15 bits for the
+ length code, 5 bits for the length extra, 15 bits for the distance code,
+ and 13 bits for the distance extra. This totals 48 bits, or six bytes.
+ Therefore if strm->avail_in >= 6, then there is enough input to avoid
+ checking for available input while decoding.
+
+ - The maximum bytes that a single length/distance pair can output is 258
+ bytes, which is the maximum length that can be coded. inflate_fast()
+ requires strm->avail_out >= 258 for each loop to avoid checking for
+ output space.
+ */
+void ZLIB_INTERNAL inflate_fast(strm, start)
+z_streamp strm;
+unsigned start; /* inflate()'s starting value for strm->avail_out */
+{
+ struct inflate_state FAR *state;
+ z_const unsigned char FAR *in; /* local strm->next_in */
+ z_const unsigned char FAR *last; /* have enough input while in < last */
+ unsigned char FAR *out; /* local strm->next_out */
+ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
+ unsigned char FAR *end; /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+ unsigned dmax; /* maximum distance from zlib header */
+#endif
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned wnext; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
+ unsigned long hold; /* local strm->hold */
+ unsigned bits; /* local strm->bits */
+ code const FAR *lcode; /* local strm->lencode */
+ code const FAR *dcode; /* local strm->distcode */
+ unsigned lmask; /* mask for first level of length codes */
+ unsigned dmask; /* mask for first level of distance codes */
+ code here; /* retrieved table entry */
+ unsigned op; /* code bits, operation, extra bits, or */
+ /* window position, window bytes to copy */
+ unsigned len; /* match length, unused bytes */
+ unsigned dist; /* match distance */
+ unsigned char FAR *from; /* where to copy match from */
+
+ /* copy state to local variables */
+ state = (struct inflate_state FAR *)strm->state;
+ in = strm->next_in;
+ last = in + (strm->avail_in - 5);
+ out = strm->next_out;
+ beg = out - (start - strm->avail_out);
+ end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+ dmax = state->dmax;
+#endif
+ wsize = state->wsize;
+ whave = state->whave;
+ wnext = state->wnext;
+ window = state->window;
+ hold = state->hold;
+ bits = state->bits;
+ lcode = state->lencode;
+ dcode = state->distcode;
+ lmask = (1U << state->lenbits) - 1;
+ dmask = (1U << state->distbits) - 1;
+
+ /* decode literals and length/distances until end-of-block or not enough
+ input data or output space */
+ do {
+ if (bits < 15) {
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ }
+ here = lcode[hold & lmask];
+ dolen:
+ op = (unsigned)(here.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(here.op);
+ if (op == 0) { /* literal */
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", here.val));
+ *out++ = (unsigned char)(here.val);
+ }
+ else if (op & 16) { /* length base */
+ len = (unsigned)(here.val);
+ op &= 15; /* number of extra bits */
+ if (op) {
+ if (bits < op) {
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ }
+ len += (unsigned)hold & ((1U << op) - 1);
+ hold >>= op;
+ bits -= op;
+ }
+ Tracevv((stderr, "inflate: length %u\n", len));
+ if (bits < 15) {
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ }
+ here = dcode[hold & dmask];
+ dodist:
+ op = (unsigned)(here.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(here.op);
+ if (op & 16) { /* distance base */
+ dist = (unsigned)(here.val);
+ op &= 15; /* number of extra bits */
+ if (bits < op) {
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ if (bits < op) {
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ }
+ }
+ dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+ if (dist > dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ hold >>= op;
+ bits -= op;
+ Tracevv((stderr, "inflate: distance %u\n", dist));
+ op = (unsigned)(out - beg); /* max distance in output */
+ if (dist > op) { /* see if copy from window */
+ op = dist - op; /* distance back in window */
+ if (op > whave) {
+ if (state->sane) {
+ strm->msg =
+ (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ if (len <= op - whave) {
+ do {
+ *out++ = 0;
+ } while (--len);
+ continue;
+ }
+ len -= op - whave;
+ do {
+ *out++ = 0;
+ } while (--op > whave);
+ if (op == 0) {
+ from = out - dist;
+ do {
+ *out++ = *from++;
+ } while (--len);
+ continue;
+ }
+#endif
+ }
+ from = window;
+ if (wnext == 0) { /* very common case */
+ from += wsize - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ *out++ = *from++;
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ else if (wnext < op) { /* wrap around window */
+ from += wsize + wnext - op;
+ op -= wnext;
+ if (op < len) { /* some from end of window */
+ len -= op;
+ do {
+ *out++ = *from++;
+ } while (--op);
+ from = window;
+ if (wnext < len) { /* some from start of window */
+ op = wnext;
+ len -= op;
+ do {
+ *out++ = *from++;
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ }
+ else { /* contiguous in window */
+ from += wnext - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ *out++ = *from++;
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ while (len > 2) {
+ *out++ = *from++;
+ *out++ = *from++;
+ *out++ = *from++;
+ len -= 3;
+ }
+ if (len) {
+ *out++ = *from++;
+ if (len > 1)
+ *out++ = *from++;
+ }
+ }
+ else {
+ from = out - dist; /* copy direct from output */
+ do { /* minimum length is three */
+ *out++ = *from++;
+ *out++ = *from++;
+ *out++ = *from++;
+ len -= 3;
+ } while (len > 2);
+ if (len) {
+ *out++ = *from++;
+ if (len > 1)
+ *out++ = *from++;
+ }
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level distance code */
+ here = dcode[here.val + (hold & ((1U << op) - 1))];
+ goto dodist;
+ }
+ else {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level length code */
+ here = lcode[here.val + (hold & ((1U << op) - 1))];
+ goto dolen;
+ }
+ else if (op & 32) { /* end-of-block */
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ else {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ } while (in < last && out < end);
+
+ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+ len = bits >> 3;
+ in -= len;
+ bits -= len << 3;
+ hold &= (1U << bits) - 1;
+
+ /* update state and return */
+ strm->next_in = in;
+ strm->next_out = out;
+ strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+ strm->avail_out = (unsigned)(out < end ?
+ 257 + (end - out) : 257 - (out - end));
+ state->hold = hold;
+ state->bits = bits;
+ return;
+}
+
+/*
+ inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+ - Using bit fields for code structure
+ - Different op definition to avoid & for extra bits (do & for table bits)
+ - Three separate decoding do-loops for direct, window, and wnext == 0
+ - Special case for distance > 1 copies to do overlapped load and store copy
+ - Explicit branch predictions (based on measured branch probabilities)
+ - Deferring match copy and interspersed it with decoding subsequent codes
+ - Swapping literal/length else
+ - Swapping window/direct else
+ - Larger unrolled copy loops (three is about right)
+ - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/lib/zlib/inffast.h b/lib/zlib/inffast.h
new file mode 100644
index 0000000..e5c1aa4
--- /dev/null
+++ b/lib/zlib/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/lib/zlib/inffixed.h b/lib/zlib/inffixed.h
new file mode 100644
index 0000000..d628327
--- /dev/null
+++ b/lib/zlib/inffixed.h
@@ -0,0 +1,94 @@
+ /* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by makefixed().
+ */
+
+ /* WARNING: this file should *not* be used by applications.
+ It is part of the implementation of this library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+ static const code lenfix[512] = {
+ {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+ {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+ {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+ {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+ {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+ {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+ {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+ {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+ {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+ {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+ {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+ {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+ {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+ {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+ {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+ {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+ {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+ {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+ {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+ {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+ {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+ {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+ {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+ {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+ {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+ {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+ {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+ {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+ {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+ {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+ {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+ {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+ {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+ {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+ {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+ {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+ {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+ {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+ {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+ {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+ {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+ {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+ {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+ {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+ {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+ {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+ {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+ {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+ {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+ {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+ {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+ {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+ {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+ {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+ {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+ {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+ {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+ {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+ {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+ {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+ {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+ {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+ {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+ {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+ {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+ {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+ {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+ {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+ {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+ {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+ {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+ {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+ {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+ {0,9,255}
+ };
+
+ static const code distfix[32] = {
+ {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+ {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+ {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+ {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+ {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+ {22,5,193},{64,5,0}
+ };
diff --git a/lib/zlib/inflate.c b/lib/zlib/inflate.c
new file mode 100644
index 0000000..ac333e8
--- /dev/null
+++ b/lib/zlib/inflate.c
@@ -0,0 +1,1561 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0 24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ * creation of window when not needed, minimize use of window when it is
+ * needed, make inffast.c even faster, implement gzip decoding, and to
+ * improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1 25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2 4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ * to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3 22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ * buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4 1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common wnext == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ * source file infback.c to provide a call-back interface to inflate for
+ * programs like gzip and unzip -- uses window as output buffer to avoid
+ * window copying
+ *
+ * 1.2.beta5 1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ * input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6 4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ * make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7 27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0 9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ * for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ * and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+# ifndef BUILDFIXED
+# define BUILDFIXED
+# endif
+#endif
+
+/* function prototypes */
+local int inflateStateCheck OF((z_streamp strm));
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
+ unsigned copy));
+#ifdef BUILDFIXED
+ void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
+ unsigned len));
+
+local int inflateStateCheck(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+ if (strm == Z_NULL ||
+ strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
+ return 1;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state == Z_NULL || state->strm != strm ||
+ state->mode < HEAD || state->mode > SYNC)
+ return 1;
+ return 0;
+}
+
+int ZEXPORT inflateResetKeep(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ strm->total_in = strm->total_out = state->total = 0;
+ strm->msg = Z_NULL;
+ if (state->wrap) /* to support ill-conceived Java test suite */
+ strm->adler = state->wrap & 1;
+ state->mode = HEAD;
+ state->last = 0;
+ state->havedict = 0;
+ state->dmax = 32768U;
+ state->head = Z_NULL;
+ state->hold = 0;
+ state->bits = 0;
+ state->lencode = state->distcode = state->next = state->codes;
+ state->sane = 1;
+ state->back = -1;
+ Tracev((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ state->wsize = 0;
+ state->whave = 0;
+ state->wnext = 0;
+ return inflateResetKeep(strm);
+}
+
+int ZEXPORT inflateReset2(strm, windowBits)
+z_streamp strm;
+int windowBits;
+{
+ int wrap;
+ struct inflate_state FAR *state;
+
+ /* get the state */
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* extract wrap request from windowBits parameter */
+ if (windowBits < 0) {
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+ else {
+ wrap = (windowBits >> 4) + 5;
+#ifdef GUNZIP
+ if (windowBits < 48)
+ windowBits &= 15;
+#endif
+ }
+
+ /* set number of window bits, free window if different */
+ if (windowBits && (windowBits < 8 || windowBits > 15))
+ return Z_STREAM_ERROR;
+ if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
+ ZFREE(strm, state->window);
+ state->window = Z_NULL;
+ }
+
+ /* update state and reset the rest of it */
+ state->wrap = wrap;
+ state->wbits = (unsigned)windowBits;
+ return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+ int ret;
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+#endif
+ }
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
+ state = (struct inflate_state FAR *)
+ ZALLOC(strm, 1, sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (struct internal_state FAR *)state;
+ state->strm = strm;
+ state->window = Z_NULL;
+ state->mode = HEAD; /* to pass state test in inflateReset2() */
+ ret = inflateReset2(strm, windowBits);
+ if (ret != Z_OK) {
+ ZFREE(strm, state);
+ strm->state = Z_NULL;
+ }
+ return ret;
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+ return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (bits < 0) {
+ state->hold = 0;
+ state->bits = 0;
+ return Z_OK;
+ }
+ if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;
+ value &= (1L << bits) - 1;
+ state->hold += (unsigned)value << state->bits;
+ state->bits += (uInt)bits;
+ return Z_OK;
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+ Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
+ defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
+ those tables to stdout, which would be piped to inffixed.h. A small program
+ can simply call makefixed to do this:
+
+ void makefixed(void);
+
+ int main(void)
+ {
+ makefixed();
+ return 0;
+ }
+
+ Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+ a.out > inffixed.h
+ */
+void makefixed()
+{
+ unsigned low, size;
+ struct inflate_state state;
+
+ fixedtables(&state);
+ puts(" /* inffixed.h -- table for decoding fixed codes");
+ puts(" * Generated automatically by makefixed().");
+ puts(" */");
+ puts("");
+ puts(" /* WARNING: this file should *not* be used by applications.");
+ puts(" It is part of the implementation of this library and is");
+ puts(" subject to change. Applications should only use zlib.h.");
+ puts(" */");
+ puts("");
+ size = 1U << 9;
+ printf(" static const code lenfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 7) == 0) printf("\n ");
+ printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
+ state.lencode[low].bits, state.lencode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+ size = 1U << 5;
+ printf("\n static const code distfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 6) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+ state.distcode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+}
+#endif /* MAKEFIXED */
+
+/*
+ Update the window with the last wsize (normally 32K) bytes written before
+ returning. If window does not exist yet, create it. This is only called
+ when a window is already in use, or when output has been written during this
+ inflate call, but the end of the deflate stream has not been reached yet.
+ It is also called to create a window for dictionary data when a dictionary
+ is loaded.
+
+ Providing output buffers larger than 32K to inflate() should provide a speed
+ advantage, since only the last 32K of output is copied to the sliding window
+ upon return from inflate(), and since all distances after the first 32K of
+ output will fall in the output data, making match copies simpler and faster.
+ The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, end, copy)
+z_streamp strm;
+const Bytef *end;
+unsigned copy;
+{
+ struct inflate_state FAR *state;
+ unsigned dist;
+
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* if it hasn't been done already, allocate space for the window */
+ if (state->window == Z_NULL) {
+ state->window = (unsigned char FAR *)
+ ZALLOC(strm, 1U << state->wbits,
+ sizeof(unsigned char));
+ if (state->window == Z_NULL) return 1;
+ }
+
+ /* if window not in use yet, initialize */
+ if (state->wsize == 0) {
+ state->wsize = 1U << state->wbits;
+ state->wnext = 0;
+ state->whave = 0;
+ }
+
+ /* copy state->wsize or less output bytes into the circular window */
+ if (copy >= state->wsize) {
+ zmemcpy(state->window, end - state->wsize, state->wsize);
+ state->wnext = 0;
+ state->whave = state->wsize;
+ }
+ else {
+ dist = state->wsize - state->wnext;
+ if (dist > copy) dist = copy;
+ zmemcpy(state->window + state->wnext, end - copy, dist);
+ copy -= dist;
+ if (copy) {
+ zmemcpy(state->window, end - copy, copy);
+ state->wnext = copy;
+ state->whave = state->wsize;
+ }
+ else {
+ state->wnext += dist;
+ if (state->wnext == state->wsize) state->wnext = 0;
+ if (state->whave < state->wsize) state->whave += dist;
+ }
+ }
+ return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+# define UPDATE(check, buf, len) \
+ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+# define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+# define CRC2(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ check = crc32(check, hbuf, 2); \
+ } while (0)
+
+# define CRC4(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ hbuf[2] = (unsigned char)((word) >> 16); \
+ hbuf[3] = (unsigned char)((word) >> 24); \
+ check = crc32(check, hbuf, 4); \
+ } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+ if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ if (have == 0) goto inf_leave; \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/*
+ inflate() uses a state machine to process as much input data and generate as
+ much output data as possible before returning. The state machine is
+ structured roughly as follows:
+
+ for (;;) switch (state) {
+ ...
+ case STATEn:
+ if (not enough input data or output space to make progress)
+ return;
+ ... make progress ...
+ state = STATEm;
+ break;
+ ...
+ }
+
+ so when inflate() is called again, the same case is attempted again, and
+ if the appropriate resources are provided, the machine proceeds to the
+ next state. The NEEDBITS() macro is usually the way the state evaluates
+ whether it can proceed or should return. NEEDBITS() does the return if
+ the requested bits are not available. The typical use of the BITS macros
+ is:
+
+ NEEDBITS(n);
+ ... do something with BITS(n) ...
+ DROPBITS(n);
+
+ where NEEDBITS(n) either returns from inflate() if there isn't enough
+ input left to load n bits into the accumulator, or it continues. BITS(n)
+ gives the low n bits in the accumulator. When done, DROPBITS(n) drops
+ the low n bits off the accumulator. INITBITS() clears the accumulator
+ and sets the number of available bits to zero. BYTEBITS() discards just
+ enough bits to put the accumulator on a byte boundary. After BYTEBITS()
+ and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+ NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+ if there is no input available. The decoding of variable length codes uses
+ PULLBYTE() directly in order to pull just enough bytes to decode the next
+ code, and no more.
+
+ Some states loop until they get enough input, making sure that enough
+ state information is maintained to continue the loop where it left off
+ if NEEDBITS() returns in the loop. For example, want, need, and keep
+ would all have to actually be part of the saved state in case NEEDBITS()
+ returns:
+
+ case STATEw:
+ while (want < need) {
+ NEEDBITS(n);
+ keep[want++] = BITS(n);
+ DROPBITS(n);
+ }
+ state = STATEx;
+ case STATEx:
+
+ As shown above, if the next state is also the next case, then the break
+ is omitted.
+
+ A state may also return if there is not enough output space available to
+ complete that state. Those states are copying stored data, writing a
+ literal byte, and copying a matching string.
+
+ When returning, a "goto inf_leave" is used to update the total counters,
+ update the check value, and determine whether any progress has been made
+ during that inflate() call in order to return the proper return code.
+ Progress is defined as a change in either strm->avail_in or strm->avail_out.
+ When there is a window, goto inf_leave will update the window with the last
+ output written. If a goto inf_leave occurs in the middle of decompression
+ and there is no window currently, goto inf_leave will create one and copy
+ output to the window for the next call of inflate().
+
+ In this implementation, the flush parameter of inflate() only affects the
+ return code (per zlib.h). inflate() always writes as much as possible to
+ strm->next_out, given the space available and the provided input--the effect
+ documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
+ the allocation of and copying into a sliding window until necessary, which
+ provides the effect documented in zlib.h for Z_FINISH when the entire input
+ stream available. So the only thing the flush parameter actually does is:
+ when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
+ will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+ struct inflate_state FAR *state;
+ z_const unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned in, out; /* save starting available input and output */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code here; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+#ifdef GUNZIP
+ unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
+#endif
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ if (inflateStateCheck(strm) || strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0))
+ return Z_STREAM_ERROR;
+
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
+ LOAD();
+ in = have;
+ out = left;
+ ret = Z_OK;
+ for (;;)
+ switch (state->mode) {
+ case HEAD:
+ if (state->wrap == 0) {
+ state->mode = TYPEDO;
+ break;
+ }
+ NEEDBITS(16);
+#ifdef GUNZIP
+ if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
+ if (state->wbits == 0)
+ state->wbits = 15;
+ state->check = crc32(0L, Z_NULL, 0);
+ CRC2(state->check, hold);
+ INITBITS();
+ state->mode = FLAGS;
+ break;
+ }
+ state->flags = 0; /* expect zlib header */
+ if (state->head != Z_NULL)
+ state->head->done = -1;
+ if (!(state->wrap & 1) || /* check if zlib header allowed */
+#else
+ if (
+#endif
+ ((BITS(8) << 8) + (hold >> 8)) % 31) {
+ strm->msg = (char *)"incorrect header check";
+ state->mode = BAD;
+ break;
+ }
+ if (BITS(4) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ DROPBITS(4);
+ len = BITS(4) + 8;
+ if (state->wbits == 0)
+ state->wbits = len;
+ if (len > 15 || len > state->wbits) {
+ strm->msg = (char *)"invalid window size";
+ state->mode = BAD;
+ break;
+ }
+ state->dmax = 1U << len;
+ Tracev((stderr, "inflate: zlib header ok\n"));
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = hold & 0x200 ? DICTID : TYPE;
+ INITBITS();
+ break;
+#ifdef GUNZIP
+ case FLAGS:
+ NEEDBITS(16);
+ state->flags = (int)(hold);
+ if ((state->flags & 0xff) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ if (state->flags & 0xe000) {
+ strm->msg = (char *)"unknown header flags set";
+ state->mode = BAD;
+ break;
+ }
+ if (state->head != Z_NULL)
+ state->head->text = (int)((hold >> 8) & 1);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC2(state->check, hold);
+ INITBITS();
+ state->mode = TIME;
+ case TIME:
+ NEEDBITS(32);
+ if (state->head != Z_NULL)
+ state->head->time = hold;
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC4(state->check, hold);
+ INITBITS();
+ state->mode = OS;
+ case OS:
+ NEEDBITS(16);
+ if (state->head != Z_NULL) {
+ state->head->xflags = (int)(hold & 0xff);
+ state->head->os = (int)(hold >> 8);
+ }
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC2(state->check, hold);
+ INITBITS();
+ state->mode = EXLEN;
+ case EXLEN:
+ if (state->flags & 0x0400) {
+ NEEDBITS(16);
+ state->length = (unsigned)(hold);
+ if (state->head != Z_NULL)
+ state->head->extra_len = (unsigned)hold;
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC2(state->check, hold);
+ INITBITS();
+ }
+ else if (state->head != Z_NULL)
+ state->head->extra = Z_NULL;
+ state->mode = EXTRA;
+ case EXTRA:
+ if (state->flags & 0x0400) {
+ copy = state->length;
+ if (copy > have) copy = have;
+ if (copy) {
+ if (state->head != Z_NULL &&
+ state->head->extra != Z_NULL) {
+ len = state->head->extra_len - state->length;
+ zmemcpy(state->head->extra + len, next,
+ len + copy > state->head->extra_max ?
+ state->head->extra_max - len : copy);
+ }
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ state->length -= copy;
+ }
+ if (state->length) goto inf_leave;
+ }
+ state->length = 0;
+ state->mode = NAME;
+ case NAME:
+ if (state->flags & 0x0800) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->name != Z_NULL &&
+ state->length < state->head->name_max)
+ state->head->name[state->length++] = (Bytef)len;
+ } while (len && copy < have);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->name = Z_NULL;
+ state->length = 0;
+ state->mode = COMMENT;
+ case COMMENT:
+ if (state->flags & 0x1000) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->comment != Z_NULL &&
+ state->length < state->head->comm_max)
+ state->head->comment[state->length++] = (Bytef)len;
+ } while (len && copy < have);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->comment = Z_NULL;
+ state->mode = HCRC;
+ case HCRC:
+ if (state->flags & 0x0200) {
+ NEEDBITS(16);
+ if ((state->wrap & 4) && hold != (state->check & 0xffff)) {
+ strm->msg = (char *)"header crc mismatch";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ }
+ if (state->head != Z_NULL) {
+ state->head->hcrc = (int)((state->flags >> 9) & 1);
+ state->head->done = 1;
+ }
+ strm->adler = state->check = crc32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ break;
+#endif
+ case DICTID:
+ NEEDBITS(32);
+ strm->adler = state->check = ZSWAP32(hold);
+ INITBITS();
+ state->mode = DICT;
+ case DICT:
+ if (state->havedict == 0) {
+ RESTORE();
+ return Z_NEED_DICT;
+ }
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ case TYPE:
+ if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
+ case TYPEDO:
+ if (state->last) {
+ BYTEBITS();
+ state->mode = CHECK;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN_; /* decode codes */
+ if (flush == Z_TREES) {
+ DROPBITS(2);
+ goto inf_leave;
+ }
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+ case STORED:
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+ state->mode = COPY_;
+ if (flush == Z_TREES) goto inf_leave;
+ case COPY_:
+ state->mode = COPY;
+ case COPY:
+ copy = state->length;
+ if (copy) {
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ if (copy == 0) goto inf_leave;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ break;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+ case TABLE:
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ state->have = 0;
+ state->mode = LENLENS;
+ case LENLENS:
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (const code FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+ state->have = 0;
+ state->mode = CODELENS;
+ case CODELENS:
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.val < 16) {
+ DROPBITS(here.bits);
+ state->lens[state->have++] = here.val;
+ }
+ else {
+ if (here.val == 16) {
+ NEEDBITS(here.bits + 2);
+ DROPBITS(here.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = state->lens[state->have - 1];
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (here.val == 17) {
+ NEEDBITS(here.bits + 3);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(here.bits + 7);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* check for end-of-block code (better have one) */
+ if (state->lens[256] == 0) {
+ strm->msg = (char *)"invalid code -- missing end-of-block";
+ state->mode = BAD;
+ break;
+ }
+
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftrees.h
+ concerning the ENOUGH constants, which depend on those values */
+ state->next = state->codes;
+ state->lencode = (const code FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (const code FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN_;
+ if (flush == Z_TREES) goto inf_leave;
+ case LEN_:
+ state->mode = LEN;
+ case LEN:
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ inflate_fast(strm, out);
+ LOAD();
+ if (state->mode == TYPE)
+ state->back = -1;
+ break;
+ }
+ state->back = 0;
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ state->back += last.bits;
+ }
+ DROPBITS(here.bits);
+ state->back += here.bits;
+ state->length = (unsigned)here.val;
+ if ((int)(here.op) == 0) {
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", here.val));
+ state->mode = LIT;
+ break;
+ }
+ if (here.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->back = -1;
+ state->mode = TYPE;
+ break;
+ }
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ state->extra = (unsigned)(here.op) & 15;
+ state->mode = LENEXT;
+ case LENEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ state->back += state->extra;
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+ state->was = state->length;
+ state->mode = DIST;
+ case DIST:
+ for (;;) {
+ here = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ state->back += last.bits;
+ }
+ DROPBITS(here.bits);
+ state->back += here.bits;
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)here.val;
+ state->extra = (unsigned)(here.op) & 15;
+ state->mode = DISTEXT;
+ case DISTEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ state->back += state->extra;
+ }
+#ifdef INFLATE_STRICT
+ if (state->offset > state->dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+ state->mode = MATCH;
+ case MATCH:
+ if (left == 0) goto inf_leave;
+ copy = out - left;
+ if (state->offset > copy) { /* copy from window */
+ copy = state->offset - copy;
+ if (copy > state->whave) {
+ if (state->sane) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ Trace((stderr, "inflate.c too far\n"));
+ copy -= state->whave;
+ if (copy > state->length) copy = state->length;
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = 0;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+#endif
+ }
+ if (copy > state->wnext) {
+ copy -= state->wnext;
+ from = state->window + (state->wsize - copy);
+ }
+ else
+ from = state->window + (state->wnext - copy);
+ if (copy > state->length) copy = state->length;
+ }
+ else { /* copy from output */
+ from = put - state->offset;
+ copy = state->length;
+ }
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+ case LIT:
+ if (left == 0) goto inf_leave;
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ case CHECK:
+ if (state->wrap) {
+ NEEDBITS(32);
+ out -= left;
+ strm->total_out += out;
+ state->total += out;
+ if ((state->wrap & 4) && out)
+ strm->adler = state->check =
+ UPDATE(state->check, put - out, out);
+ out = left;
+ if ((state->wrap & 4) && (
+#ifdef GUNZIP
+ state->flags ? hold :
+#endif
+ ZSWAP32(hold)) != state->check) {
+ strm->msg = (char *)"incorrect data check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: check matches trailer\n"));
+ }
+#ifdef GUNZIP
+ state->mode = LENGTH;
+ case LENGTH:
+ if (state->wrap && state->flags) {
+ NEEDBITS(32);
+ if (hold != (state->total & 0xffffffffUL)) {
+ strm->msg = (char *)"incorrect length check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: length matches trailer\n"));
+ }
+#endif
+ state->mode = DONE;
+ case DONE:
+ ret = Z_STREAM_END;
+ goto inf_leave;
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+ case MEM:
+ return Z_MEM_ERROR;
+ case SYNC:
+ default:
+ return Z_STREAM_ERROR;
+ }
+
+ /*
+ Return from inflate(), updating the total counts and the check value.
+ If there was no progress during the inflate() call, return a buffer
+ error. Call updatewindow() to create and/or update the window state.
+ Note: a memory error from inflate() is non-recoverable.
+ */
+ inf_leave:
+ RESTORE();
+ if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
+ (state->mode < CHECK || flush != Z_FINISH)))
+ if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ in -= strm->avail_in;
+ out -= strm->avail_out;
+ strm->total_in += in;
+ strm->total_out += out;
+ state->total += out;
+ if ((state->wrap & 4) && out)
+ strm->adler = state->check =
+ UPDATE(state->check, strm->next_out - out, out);
+ strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
+ (state->mode == TYPE ? 128 : 0) +
+ (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
+ if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+ ret = Z_BUF_ERROR;
+ return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+ if (inflateStateCheck(strm))
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->window != Z_NULL) ZFREE(strm, state->window);
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+Bytef *dictionary;
+uInt *dictLength;
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* copy dictionary */
+ if (state->whave && dictionary != Z_NULL) {
+ zmemcpy(dictionary, state->window + state->wnext,
+ state->whave - state->wnext);
+ zmemcpy(dictionary + state->whave - state->wnext,
+ state->window, state->wnext);
+ }
+ if (dictLength != Z_NULL)
+ *dictLength = state->whave;
+ return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+ struct inflate_state FAR *state;
+ unsigned long dictid;
+ int ret;
+
+ /* check state */
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->wrap != 0 && state->mode != DICT)
+ return Z_STREAM_ERROR;
+
+ /* check for correct dictionary identifier */
+ if (state->mode == DICT) {
+ dictid = adler32(0L, Z_NULL, 0);
+ dictid = adler32(dictid, dictionary, dictLength);
+ if (dictid != state->check)
+ return Z_DATA_ERROR;
+ }
+
+ /* copy dictionary to window using updatewindow(), which will amend the
+ existing dictionary if appropriate */
+ ret = updatewindow(strm, dictionary + dictLength, dictLength);
+ if (ret) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ state->havedict = 1;
+ Tracev((stderr, "inflate: dictionary set\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+ /* save header structure */
+ state->head = head;
+ head->done = 0;
+ return Z_OK;
+}
+
+/*
+ Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
+ or when out of input. When called, *have is the number of pattern bytes
+ found in order so far, in 0..3. On return *have is updated to the new
+ state. If on return *have equals four, then the pattern was found and the
+ return value is how many bytes were read including the last byte of the
+ pattern. If *have is less than four, then the pattern has not been found
+ yet and the return value is len. In the latter case, syncsearch() can be
+ called again with more data and the *have state. *have is initialized to
+ zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+const unsigned char FAR *buf;
+unsigned len;
+{
+ unsigned got;
+ unsigned next;
+
+ got = *have;
+ next = 0;
+ while (next < len && got < 4) {
+ if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+ got++;
+ else if (buf[next])
+ got = 0;
+ else
+ got = 4 - got;
+ next++;
+ }
+ *have = got;
+ return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+ unsigned len; /* number of bytes to look at or looked at */
+ unsigned long in, out; /* temporary to save total_in and total_out */
+ unsigned char buf[4]; /* to restore bit buffer to byte string */
+ struct inflate_state FAR *state;
+
+ /* check parameters */
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+ /* if first time, start search in bit buffer */
+ if (state->mode != SYNC) {
+ state->mode = SYNC;
+ state->hold <<= state->bits & 7;
+ state->bits -= state->bits & 7;
+ len = 0;
+ while (state->bits >= 8) {
+ buf[len++] = (unsigned char)(state->hold);
+ state->hold >>= 8;
+ state->bits -= 8;
+ }
+ state->have = 0;
+ syncsearch(&(state->have), buf, len);
+ }
+
+ /* search available input */
+ len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+ strm->avail_in -= len;
+ strm->next_in += len;
+ strm->total_in += len;
+
+ /* return no joy or set up to restart inflate() on a new block */
+ if (state->have != 4) return Z_DATA_ERROR;
+ in = strm->total_in; out = strm->total_out;
+ inflateReset(strm);
+ strm->total_in = in; strm->total_out = out;
+ state->mode = TYPE;
+ return Z_OK;
+}
+
+/*
+ Returns true if inflate is currently at the end of a block generated by
+ Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ implementation to provide an additional safety check. PPP uses
+ Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+ block. When decompressing, PPP checks that at the end of input packet,
+ inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+ struct inflate_state FAR *state;
+ struct inflate_state FAR *copy;
+ unsigned char FAR *window;
+ unsigned wsize;
+
+ /* check input */
+ if (inflateStateCheck(source) || dest == Z_NULL)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)source->state;
+
+ /* allocate space */
+ copy = (struct inflate_state FAR *)
+ ZALLOC(source, 1, sizeof(struct inflate_state));
+ if (copy == Z_NULL) return Z_MEM_ERROR;
+ window = Z_NULL;
+ if (state->window != Z_NULL) {
+ window = (unsigned char FAR *)
+ ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+ if (window == Z_NULL) {
+ ZFREE(source, copy);
+ return Z_MEM_ERROR;
+ }
+ }
+
+ /* copy state */
+ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+ zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
+ copy->strm = dest;
+ if (state->lencode >= state->codes &&
+ state->lencode <= state->codes + ENOUGH - 1) {
+ copy->lencode = copy->codes + (state->lencode - state->codes);
+ copy->distcode = copy->codes + (state->distcode - state->codes);
+ }
+ copy->next = copy->codes + (state->next - state->codes);
+ if (window != Z_NULL) {
+ wsize = 1U << state->wbits;
+ zmemcpy(window, state->window, wsize);
+ }
+ copy->window = window;
+ dest->state = (struct internal_state FAR *)copy;
+ return Z_OK;
+}
+
+int ZEXPORT inflateUndermine(strm, subvert)
+z_streamp strm;
+int subvert;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ state->sane = !subvert;
+ return Z_OK;
+#else
+ (void)subvert;
+ state->sane = 1;
+ return Z_DATA_ERROR;
+#endif
+}
+
+int ZEXPORT inflateValidate(strm, check)
+z_streamp strm;
+int check;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (check)
+ state->wrap |= 4;
+ else
+ state->wrap &= ~4;
+ return Z_OK;
+}
+
+long ZEXPORT inflateMark(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm))
+ return -(1L << 16);
+ state = (struct inflate_state FAR *)strm->state;
+ return (long)(((unsigned long)((long)state->back)) << 16) +
+ (state->mode == COPY ? state->length :
+ (state->mode == MATCH ? state->was - state->length : 0));
+}
+
+unsigned long ZEXPORT inflateCodesUsed(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+ if (inflateStateCheck(strm)) return (unsigned long)-1;
+ state = (struct inflate_state FAR *)strm->state;
+ return (unsigned long)(state->next - state->codes);
+}
diff --git a/lib/zlib/inflate.h b/lib/zlib/inflate.h
new file mode 100644
index 0000000..a46cce6
--- /dev/null
+++ b/lib/zlib/inflate.h
@@ -0,0 +1,125 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip decoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+ HEAD = 16180, /* i: waiting for magic header */
+ FLAGS, /* i: waiting for method and flags (gzip) */
+ TIME, /* i: waiting for modification time (gzip) */
+ OS, /* i: waiting for extra flags and operating system (gzip) */
+ EXLEN, /* i: waiting for extra length (gzip) */
+ EXTRA, /* i: waiting for extra bytes (gzip) */
+ NAME, /* i: waiting for end of file name (gzip) */
+ COMMENT, /* i: waiting for end of comment (gzip) */
+ HCRC, /* i: waiting for header crc (gzip) */
+ DICTID, /* i: waiting for dictionary check value */
+ DICT, /* waiting for inflateSetDictionary() call */
+ TYPE, /* i: waiting for type bits, including last-flag bit */
+ TYPEDO, /* i: same, but skip check to exit inflate on new block */
+ STORED, /* i: waiting for stored size (length and complement) */
+ COPY_, /* i/o: same as COPY below, but only first time in */
+ COPY, /* i/o: waiting for input or output to copy stored block */
+ TABLE, /* i: waiting for dynamic block table lengths */
+ LENLENS, /* i: waiting for code length code lengths */
+ CODELENS, /* i: waiting for length/lit and distance code lengths */
+ LEN_, /* i: same as LEN below, but only first time in */
+ LEN, /* i: waiting for length/lit/eob code */
+ LENEXT, /* i: waiting for length extra bits */
+ DIST, /* i: waiting for distance code */
+ DISTEXT, /* i: waiting for distance extra bits */
+ MATCH, /* o: waiting for output space to copy string */
+ LIT, /* o: waiting for output space to write literal */
+ CHECK, /* i: waiting for 32-bit check value */
+ LENGTH, /* i: waiting for 32-bit length (gzip) */
+ DONE, /* finished check, done -- remain here until reset */
+ BAD, /* got a data error -- remain here until reset */
+ MEM, /* got an inflate() memory error -- remain here until reset */
+ SYNC /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+ State transitions between above modes -
+
+ (most modes can go to BAD or MEM on error -- not shown for clarity)
+
+ Process header:
+ HEAD -> (gzip) or (zlib) or (raw)
+ (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
+ HCRC -> TYPE
+ (zlib) -> DICTID or TYPE
+ DICTID -> DICT -> TYPE
+ (raw) -> TYPEDO
+ Read deflate blocks:
+ TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
+ STORED -> COPY_ -> COPY -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN_
+ LEN_ -> LEN
+ Read deflate codes in fixed or dynamic block:
+ LEN -> LENEXT or LIT or TYPE
+ LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+ LIT -> LEN
+ Process trailer:
+ CHECK -> LENGTH -> DONE
+ */
+
+/* State maintained between inflate() calls -- approximately 7K bytes, not
+ including the allocated sliding window, which is up to 32K bytes. */
+struct inflate_state {
+ z_streamp strm; /* pointer back to this zlib stream */
+ inflate_mode mode; /* current inflate mode */
+ int last; /* true if processing last block */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
+ bit 2 true to validate check value */
+ int havedict; /* true if dictionary provided */
+ int flags; /* gzip header method and flags (0 if zlib) */
+ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
+ unsigned long check; /* protected copy of check value */
+ unsigned long total; /* protected copy of output count */
+ gz_headerp head; /* where to save gzip header information */
+ /* sliding window */
+ unsigned wbits; /* log base 2 of requested window size */
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned wnext; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if needed */
+ /* bit accumulator */
+ unsigned long hold; /* input bit accumulator */
+ unsigned bits; /* number of bits in "in" */
+ /* for string and stored block copying */
+ unsigned length; /* literal or length of data to copy */
+ unsigned offset; /* distance back to copy string from */
+ /* for table and code decoding */
+ unsigned extra; /* extra bits needed */
+ /* fixed and dynamic code tables */
+ code const FAR *lencode; /* starting table for length/literal codes */
+ code const FAR *distcode; /* starting table for distance codes */
+ unsigned lenbits; /* index bits for lencode */
+ unsigned distbits; /* index bits for distcode */
+ /* dynamic table building */
+ unsigned ncode; /* number of code length code lengths */
+ unsigned nlen; /* number of length code lengths */
+ unsigned ndist; /* number of distance code lengths */
+ unsigned have; /* number of code lengths in lens[] */
+ code FAR *next; /* next available space in codes[] */
+ unsigned short lens[320]; /* temporary storage for code lengths */
+ unsigned short work[288]; /* work area for code table building */
+ code codes[ENOUGH]; /* space for code tables */
+ int sane; /* if false, allow invalid distance too far */
+ int back; /* bits back of last unprocessed length/lit */
+ unsigned was; /* initial length of match */
+};
diff --git a/lib/zlib/inftrees.c b/lib/zlib/inftrees.c
new file mode 100644
index 0000000..2ea08fc
--- /dev/null
+++ b/lib/zlib/inftrees.c
@@ -0,0 +1,304 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+ " inflate 1.2.11 Copyright 1995-2017 Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/*
+ Build a set of tables to decode the provided canonical Huffman code.
+ The code lengths are lens[0..codes-1]. The result starts at *table,
+ whose indices are 0..2^bits-1. work is a writable array of at least
+ lens shorts, which is used as a work area. type is the type of code
+ to be generated, CODES, LENS, or DISTS. On return, zero is success,
+ -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
+ on return points to the next available entry's address. bits is the
+ requested root table index bits, and on return it is the actual root
+ table index bits. It will differ if the request is greater than the
+ longest code or if it is less than the shortest code.
+ */
+int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+ unsigned len; /* a code's length in bits */
+ unsigned sym; /* index of code symbols */
+ unsigned min, max; /* minimum and maximum code lengths */
+ unsigned root; /* number of index bits for root table */
+ unsigned curr; /* number of index bits for current table */
+ unsigned drop; /* code bits to drop for sub-table */
+ int left; /* number of prefix codes available */
+ unsigned used; /* code entries in table used */
+ unsigned huff; /* Huffman code */
+ unsigned incr; /* for incrementing code, index */
+ unsigned fill; /* index for replicating entries */
+ unsigned low; /* low bits for current root entry */
+ unsigned mask; /* mask for low root bits */
+ code here; /* table entry for duplication */
+ code FAR *next; /* next available space in table */
+ const unsigned short FAR *base; /* base value table to use */
+ const unsigned short FAR *extra; /* extra bits table to use */
+ unsigned match; /* use base and extra for symbol >= match */
+ unsigned short count[MAXBITS+1]; /* number of codes of each length */
+ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
+ static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202};
+ static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577, 0, 0};
+ static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+ 28, 28, 29, 29, 64, 64};
+
+ /*
+ Process a set of code lengths to create a canonical Huffman code. The
+ code lengths are lens[0..codes-1]. Each length corresponds to the
+ symbols 0..codes-1. The Huffman code is generated by first sorting the
+ symbols by length from short to long, and retaining the symbol order
+ for codes with equal lengths. Then the code starts with all zero bits
+ for the first code of the shortest length, and the codes are integer
+ increments for the same length, and zeros are appended as the length
+ increases. For the deflate format, these bits are stored backwards
+ from their more natural integer increment ordering, and so when the
+ decoding tables are built in the large loop below, the integer codes
+ are incremented backwards.
+
+ This routine assumes, but does not check, that all of the entries in
+ lens[] are in the range 0..MAXBITS. The caller must assure this.
+ 1..MAXBITS is interpreted as that code length. zero means that that
+ symbol does not occur in this code.
+
+ The codes are sorted by computing a count of codes for each length,
+ creating from that a table of starting indices for each length in the
+ sorted table, and then entering the symbols in order in the sorted
+ table. The sorted table is work[], with that space being provided by
+ the caller.
+
+ The length counts are used for other purposes as well, i.e. finding
+ the minimum and maximum length codes, determining if there are any
+ codes at all, checking for a valid set of lengths, and looking ahead
+ at length counts to determine sub-table sizes when building the
+ decoding tables.
+ */
+
+ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+ for (len = 0; len <= MAXBITS; len++)
+ count[len] = 0;
+ for (sym = 0; sym < codes; sym++)
+ count[lens[sym]]++;
+
+ /* bound code lengths, force root to be within code lengths */
+ root = *bits;
+ for (max = MAXBITS; max >= 1; max--)
+ if (count[max] != 0) break;
+ if (root > max) root = max;
+ if (max == 0) { /* no symbols to code at all */
+ here.op = (unsigned char)64; /* invalid code marker */
+ here.bits = (unsigned char)1;
+ here.val = (unsigned short)0;
+ *(*table)++ = here; /* make a table to force an error */
+ *(*table)++ = here;
+ *bits = 1;
+ return 0; /* no symbols, but wait for decoding to report error */
+ }
+ for (min = 1; min < max; min++)
+ if (count[min] != 0) break;
+ if (root < min) root = min;
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1;
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1;
+ left -= count[len];
+ if (left < 0) return -1; /* over-subscribed */
+ }
+ if (left > 0 && (type == CODES || max != 1))
+ return -1; /* incomplete set */
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + count[len];
+
+ /* sort symbols by length, by symbol order within each length */
+ for (sym = 0; sym < codes; sym++)
+ if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+ /*
+ Create and fill in decoding tables. In this loop, the table being
+ filled is at next and has curr index bits. The code being used is huff
+ with length len. That code is converted to an index by dropping drop
+ bits off of the bottom. For codes where len is less than drop + curr,
+ those top drop + curr - len bits are incremented through all values to
+ fill the table with replicated entries.
+
+ root is the number of index bits for the root table. When len exceeds
+ root, sub-tables are created pointed to by the root entry with an index
+ of the low root bits of huff. This is saved in low to check for when a
+ new sub-table should be started. drop is zero when the root table is
+ being filled, and drop is root when sub-tables are being filled.
+
+ When a new sub-table is needed, it is necessary to look ahead in the
+ code lengths to determine what size sub-table is needed. The length
+ counts are used for this, and so count[] is decremented as codes are
+ entered in the tables.
+
+ used keeps track of how many table entries have been allocated from the
+ provided *table space. It is checked for LENS and DIST tables against
+ the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+ the initial root table size constants. See the comments in inftrees.h
+ for more information.
+
+ sym increments through all symbols, and the loop terminates when
+ all codes of length max, i.e. all codes, have been processed. This
+ routine permits incomplete codes, so another loop after this one fills
+ in the rest of the decoding tables with invalid code markers.
+ */
+
+ /* set up for code type */
+ switch (type) {
+ case CODES:
+ base = extra = work; /* dummy value--not used */
+ match = 20;
+ break;
+ case LENS:
+ base = lbase;
+ extra = lext;
+ match = 257;
+ break;
+ default: /* DISTS */
+ base = dbase;
+ extra = dext;
+ match = 0;
+ }
+
+ /* initialize state for loop */
+ huff = 0; /* starting code */
+ sym = 0; /* starting code symbol */
+ len = min; /* starting code length */
+ next = *table; /* current table to fill in */
+ curr = root; /* current table index bits */
+ drop = 0; /* current bits to drop from code for index */
+ low = (unsigned)(-1); /* trigger new sub-table when len > root */
+ used = 1U << root; /* use root table entries */
+ mask = used - 1; /* mask for comparing low */
+
+ /* check available table space */
+ if ((type == LENS && used > ENOUGH_LENS) ||
+ (type == DISTS && used > ENOUGH_DISTS))
+ return 1;
+
+ /* process all codes and make table entries */
+ for (;;) {
+ /* create table entry */
+ here.bits = (unsigned char)(len - drop);
+ if (work[sym] + 1U < match) {
+ here.op = (unsigned char)0;
+ here.val = work[sym];
+ }
+ else if (work[sym] >= match) {
+ here.op = (unsigned char)(extra[work[sym] - match]);
+ here.val = base[work[sym] - match];
+ }
+ else {
+ here.op = (unsigned char)(32 + 64); /* end of block */
+ here.val = 0;
+ }
+
+ /* replicate for those indices with low len bits equal to huff */
+ incr = 1U << (len - drop);
+ fill = 1U << curr;
+ min = fill; /* save offset to next table */
+ do {
+ fill -= incr;
+ next[(huff >> drop) + fill] = here;
+ } while (fill != 0);
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+
+ /* go to next symbol, update count, len */
+ sym++;
+ if (--(count[len]) == 0) {
+ if (len == max) break;
+ len = lens[work[sym]];
+ }
+
+ /* create new sub-table if needed */
+ if (len > root && (huff & mask) != low) {
+ /* if first time, transition to sub-tables */
+ if (drop == 0)
+ drop = root;
+
+ /* increment past last table */
+ next += min; /* here min is 1 << curr */
+
+ /* determine length of next table */
+ curr = len - drop;
+ left = (int)(1 << curr);
+ while (curr + drop < max) {
+ left -= count[curr + drop];
+ if (left <= 0) break;
+ curr++;
+ left <<= 1;
+ }
+
+ /* check for enough space */
+ used += 1U << curr;
+ if ((type == LENS && used > ENOUGH_LENS) ||
+ (type == DISTS && used > ENOUGH_DISTS))
+ return 1;
+
+ /* point entry in root table to sub-table */
+ low = huff & mask;
+ (*table)[low].op = (unsigned char)curr;
+ (*table)[low].bits = (unsigned char)root;
+ (*table)[low].val = (unsigned short)(next - *table);
+ }
+ }
+
+ /* fill in remaining table entry if code is incomplete (guaranteed to have
+ at most one remaining entry, since if the code is incomplete, the
+ maximum code length that was allowed to get this far is one bit) */
+ if (huff != 0) {
+ here.op = (unsigned char)64; /* invalid code marker */
+ here.bits = (unsigned char)(len - drop);
+ here.val = (unsigned short)0;
+ next[huff] = here;
+ }
+
+ /* set return parameters */
+ *table += used;
+ *bits = root;
+ return 0;
+}
diff --git a/lib/zlib/inftrees.h b/lib/zlib/inftrees.h
new file mode 100644
index 0000000..baa53a0
--- /dev/null
+++ b/lib/zlib/inftrees.h
@@ -0,0 +1,62 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables. Each entry provides either the
+ information needed to do the operation requested by the code that
+ indexed that table entry, or it provides a pointer to another
+ table that indexes more bits of the code. op indicates whether
+ the entry is a pointer to another table, a literal, a length or
+ distance, an end-of-block, or an invalid code. For a table
+ pointer, the low four bits of op is the number of index bits of
+ that table. For a length or distance, the low four bits of op
+ is the number of extra bits to get after the code. bits is
+ the number of bits in this code or part of the code to drop off
+ of the bit buffer. val is the actual byte to output in the case
+ of a literal, the base length or distance, or the offset from
+ the current table to the next table. Each entry is four bytes. */
+typedef struct {
+ unsigned char op; /* operation, extra bits, table bits */
+ unsigned char bits; /* bits in this part of the code */
+ unsigned short val; /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+ 00000000 - literal
+ 0000tttt - table link, tttt != 0 is the number of table index bits
+ 0001eeee - length or distance, eeee is the number of extra bits
+ 01100000 - end of block
+ 01000000 - invalid code
+ */
+
+/* Maximum size of the dynamic table. The maximum number of code structures is
+ 1444, which is the sum of 852 for literal/length codes and 592 for distance
+ codes. These values were found by exhaustive searches using the program
+ examples/enough.c found in the zlib distribtution. The arguments to that
+ program are the number of symbols, the initial root table size, and the
+ maximum bit length of a code. "enough 286 9 15" for literal/length codes
+ returns returns 852, and "enough 30 6 15" for distance codes returns 592.
+ The initial root table size (9 or 6) is found in the fifth argument of the
+ inflate_table() calls in inflate.c and infback.c. If the root table size is
+ changed, then these maximum sizes would be need to be recalculated and
+ updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 592
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
+
+/* Type of code to build for inflate_table() */
+typedef enum {
+ CODES,
+ LENS,
+ DISTS
+} codetype;
+
+int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
+ unsigned codes, code FAR * FAR *table,
+ unsigned FAR *bits, unsigned short FAR *work));
diff --git a/lib/zlib/trees.c b/lib/zlib/trees.c
new file mode 100644
index 0000000..50cf4b4
--- /dev/null
+++ b/lib/zlib/trees.c
@@ -0,0 +1,1203 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2017 Jean-loup Gailly
+ * detect_data_type() function provided freely by Cosmin Truta, 2006
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process uses several Huffman trees. The more
+ * common source values are represented by shorter bit sequences.
+ *
+ * Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values). The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ * Storer, James A.
+ * Data Compression: Methods and Theory, pp. 49-50.
+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
+ *
+ * Sedgewick, R.
+ * Algorithms, p290.
+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef ZLIB_DEBUG
+# include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6 16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10 17
+/* repeat a zero length 3-10 times (3 bits of repeat count) */
+
+#define REPZ_11_138 18
+/* repeat a zero length 11-138 times (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+# include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+ const ct_data *static_tree; /* static tree or NULL */
+ const intf *extra_bits; /* extra bits for each code or NULL */
+ int extra_base; /* base index for extra_bits */
+ int elems; /* max number of elements in the tree */
+ int max_length; /* max bit length for the codes */
+};
+
+local const static_tree_desc static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local const static_tree_desc static_d_desc =
+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
+
+local const static_tree_desc static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block OF((deflate_state *s));
+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree OF((deflate_state *s, tree_desc *desc));
+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local int build_bl_tree OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+ int blcodes));
+local void compress_block OF((deflate_state *s, const ct_data *ltree,
+ const ct_data *dtree));
+local int detect_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup OF((deflate_state *s));
+local void bi_flush OF((deflate_state *s));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef ZLIB_DEBUG
+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+ /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* !ZLIB_DEBUG */
+# define send_code(s, c, tree) \
+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+ send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+ put_byte(s, (uch)((w) & 0xff)); \
+ put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef ZLIB_DEBUG
+local void send_bits OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+ deflate_state *s;
+ int value; /* value to send */
+ int length; /* number of bits */
+{
+ Tracevv((stderr," l %2d v %4x ", length, value));
+ Assert(length > 0 && length <= 15, "invalid length");
+ s->bits_sent += (ulg)length;
+
+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+ * unused bits in value.
+ */
+ if (s->bi_valid > (int)Buf_size - length) {
+ s->bi_buf |= (ush)value << s->bi_valid;
+ put_short(s, s->bi_buf);
+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+ s->bi_valid += length - Buf_size;
+ } else {
+ s->bi_buf |= (ush)value << s->bi_valid;
+ s->bi_valid += length;
+ }
+}
+#else /* !ZLIB_DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+ if (s->bi_valid > (int)Buf_size - len) {\
+ int val = (int)value;\
+ s->bi_buf |= (ush)val << s->bi_valid;\
+ put_short(s, s->bi_buf);\
+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+ s->bi_valid += len - Buf_size;\
+ } else {\
+ s->bi_buf |= (ush)(value) << s->bi_valid;\
+ s->bi_valid += len;\
+ }\
+}
+#endif /* ZLIB_DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+ static int static_init_done = 0;
+ int n; /* iterates over tree elements */
+ int bits; /* bit counter */
+ int length; /* length value */
+ int code; /* code value */
+ int dist; /* distance index */
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ if (static_init_done) return;
+
+ /* For some embedded targets, global variables are not initialized: */
+#ifdef NO_INIT_GLOBAL_POINTERS
+ static_l_desc.static_tree = static_ltree;
+ static_l_desc.extra_bits = extra_lbits;
+ static_d_desc.static_tree = static_dtree;
+ static_d_desc.extra_bits = extra_dbits;
+ static_bl_desc.extra_bits = extra_blbits;
+#endif
+
+ /* Initialize the mapping length (0..255) -> length code (0..28) */
+ length = 0;
+ for (code = 0; code < LENGTH_CODES-1; code++) {
+ base_length[code] = length;
+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
+ _length_code[length++] = (uch)code;
+ }
+ }
+ Assert (length == 256, "tr_static_init: length != 256");
+ /* Note that the length 255 (match length 258) can be represented
+ * in two different ways: code 284 + 5 bits or code 285, so we
+ * overwrite length_code[255] to use the best encoding:
+ */
+ _length_code[length-1] = (uch)code;
+
+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+ dist = 0;
+ for (code = 0 ; code < 16; code++) {
+ base_dist[code] = dist;
+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
+ _dist_code[dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: dist != 256");
+ dist >>= 7; /* from now on, all distances are divided by 128 */
+ for ( ; code < D_CODES; code++) {
+ base_dist[code] = dist << 7;
+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+ _dist_code[256 + dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+ /* Construct the codes of the static literal tree */
+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+ n = 0;
+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+ /* Codes 286 and 287 do not exist, but we must include them in the
+ * tree construction to get a canonical Huffman tree (longest code
+ * all ones)
+ */
+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+ /* The static distance tree is trivial: */
+ for (n = 0; n < D_CODES; n++) {
+ static_dtree[n].Len = 5;
+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+ }
+ static_init_done = 1;
+
+# ifdef GEN_TREES_H
+ gen_trees_header();
+# endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+# ifndef ZLIB_DEBUG
+# include <stdio.h>
+# endif
+
+# define SEPARATOR(i, last, width) \
+ ((i) == (last)? "\n};\n\n" : \
+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+ FILE *header = fopen("trees.h", "w");
+ int i;
+
+ Assert (header != NULL, "Can't open trees.h");
+ fprintf(header,
+ "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+ for (i = 0; i < L_CODES+2; i++) {
+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+ }
+
+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+ }
+
+ fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
+ for (i = 0; i < DIST_CODE_LEN; i++) {
+ fprintf(header, "%2u%s", _dist_code[i],
+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
+ }
+
+ fprintf(header,
+ "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+ fprintf(header, "%2u%s", _length_code[i],
+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+ }
+
+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+ for (i = 0; i < LENGTH_CODES; i++) {
+ fprintf(header, "%1u%s", base_length[i],
+ SEPARATOR(i, LENGTH_CODES-1, 20));
+ }
+
+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "%5u%s", base_dist[i],
+ SEPARATOR(i, D_CODES-1, 10));
+ }
+
+ fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void ZLIB_INTERNAL _tr_init(s)
+ deflate_state *s;
+{
+ tr_static_init();
+
+ s->l_desc.dyn_tree = s->dyn_ltree;
+ s->l_desc.stat_desc = &static_l_desc;
+
+ s->d_desc.dyn_tree = s->dyn_dtree;
+ s->d_desc.stat_desc = &static_d_desc;
+
+ s->bl_desc.dyn_tree = s->bl_tree;
+ s->bl_desc.stat_desc = &static_bl_desc;
+
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef ZLIB_DEBUG
+ s->compressed_len = 0L;
+ s->bits_sent = 0L;
+#endif
+
+ /* Initialize the first block of the first file: */
+ init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+ deflate_state *s;
+{
+ int n; /* iterates over tree elements */
+
+ /* Initialize the trees. */
+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+ s->dyn_ltree[END_BLOCK].Freq = 1;
+ s->opt_len = s->static_len = 0L;
+ s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+ top = s->heap[SMALLEST]; \
+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+ pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+ (tree[n].Freq < tree[m].Freq || \
+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+ deflate_state *s;
+ ct_data *tree; /* the tree to restore */
+ int k; /* node to move down */
+{
+ int v = s->heap[k];
+ int j = k << 1; /* left son of k */
+ while (j <= s->heap_len) {
+ /* Set j to the smallest of the two sons: */
+ if (j < s->heap_len &&
+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+ j++;
+ }
+ /* Exit if v is smaller than both sons */
+ if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+ /* Exchange v with the smallest son */
+ s->heap[k] = s->heap[j]; k = j;
+
+ /* And continue down the tree, setting j to the left son of k */
+ j <<= 1;
+ }
+ s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ * above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ * array bl_count contains the frequencies for each bit length.
+ * The length opt_len is updated; static_len is also updated if stree is
+ * not null.
+ */
+local void gen_bitlen(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ int max_code = desc->max_code;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ const intf *extra = desc->stat_desc->extra_bits;
+ int base = desc->stat_desc->extra_base;
+ int max_length = desc->stat_desc->max_length;
+ int h; /* heap index */
+ int n, m; /* iterate over the tree elements */
+ int bits; /* bit length */
+ int xbits; /* extra bits */
+ ush f; /* frequency */
+ int overflow = 0; /* number of elements with bit length too large */
+
+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+ /* In a first pass, compute the optimal bit lengths (which may
+ * overflow in the case of the bit length tree).
+ */
+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+ n = s->heap[h];
+ bits = tree[tree[n].Dad].Len + 1;
+ if (bits > max_length) bits = max_length, overflow++;
+ tree[n].Len = (ush)bits;
+ /* We overwrite tree[n].Dad which is no longer needed */
+
+ if (n > max_code) continue; /* not a leaf node */
+
+ s->bl_count[bits]++;
+ xbits = 0;
+ if (n >= base) xbits = extra[n-base];
+ f = tree[n].Freq;
+ s->opt_len += (ulg)f * (unsigned)(bits + xbits);
+ if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits);
+ }
+ if (overflow == 0) return;
+
+ Tracev((stderr,"\nbit length overflow\n"));
+ /* This happens for example on obj2 and pic of the Calgary corpus */
+
+ /* Find the first bit length which could increase: */
+ do {
+ bits = max_length-1;
+ while (s->bl_count[bits] == 0) bits--;
+ s->bl_count[bits]--; /* move one leaf down the tree */
+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+ s->bl_count[max_length]--;
+ /* The brother of the overflow item also moves one step up,
+ * but this does not affect bl_count[max_length]
+ */
+ overflow -= 2;
+ } while (overflow > 0);
+
+ /* Now recompute all bit lengths, scanning in increasing frequency.
+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+ * lengths instead of fixing only the wrong ones. This idea is taken
+ * from 'ar' written by Haruhiko Okumura.)
+ */
+ for (bits = max_length; bits != 0; bits--) {
+ n = s->bl_count[bits];
+ while (n != 0) {
+ m = s->heap[--h];
+ if (m > max_code) continue;
+ if ((unsigned) tree[m].Len != (unsigned) bits) {
+ Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+ s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq;
+ tree[m].Len = (ush)bits;
+ }
+ n--;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ * zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+ ct_data *tree; /* the tree to decorate */
+ int max_code; /* largest code with non zero frequency */
+ ushf *bl_count; /* number of codes at each bit length */
+{
+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+ unsigned code = 0; /* running code value */
+ int bits; /* bit index */
+ int n; /* code index */
+
+ /* The distribution counts are first used to generate the code values
+ * without bit reversal.
+ */
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ code = (code + bl_count[bits-1]) << 1;
+ next_code[bits] = (ush)code;
+ }
+ /* Check that the bit counts in bl_count are consistent. The last code
+ * must be all ones.
+ */
+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+ "inconsistent bit counts");
+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+ for (n = 0; n <= max_code; n++) {
+ int len = tree[n].Len;
+ if (len == 0) continue;
+ /* Now reverse the bits */
+ tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
+
+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+ }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ * and corresponding code. The length opt_len is updated; static_len is
+ * also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ int elems = desc->stat_desc->elems;
+ int n, m; /* iterate over heap elements */
+ int max_code = -1; /* largest code with non zero frequency */
+ int node; /* new node being created */
+
+ /* Construct the initial heap, with least frequent element in
+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+ * heap[0] is not used.
+ */
+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+ for (n = 0; n < elems; n++) {
+ if (tree[n].Freq != 0) {
+ s->heap[++(s->heap_len)] = max_code = n;
+ s->depth[n] = 0;
+ } else {
+ tree[n].Len = 0;
+ }
+ }
+
+ /* The pkzip format requires that at least one distance code exists,
+ * and that at least one bit should be sent even if there is only one
+ * possible code. So to avoid special checks later on we force at least
+ * two codes of non zero frequency.
+ */
+ while (s->heap_len < 2) {
+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+ tree[node].Freq = 1;
+ s->depth[node] = 0;
+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+ /* node is 0 or 1 so it does not have extra bits */
+ }
+ desc->max_code = max_code;
+
+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+ * establish sub-heaps of increasing lengths:
+ */
+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+ /* Construct the Huffman tree by repeatedly combining the least two
+ * frequent nodes.
+ */
+ node = elems; /* next internal node of the tree */
+ do {
+ pqremove(s, tree, n); /* n = node of least frequency */
+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+ s->heap[--(s->heap_max)] = m;
+
+ /* Create a new node father of n and m */
+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
+ s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+ s->depth[n] : s->depth[m]) + 1);
+ tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+ if (tree == s->bl_tree) {
+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+ }
+#endif
+ /* and insert the new node in the heap */
+ s->heap[SMALLEST] = node++;
+ pqdownheap(s, tree, SMALLEST);
+
+ } while (s->heap_len >= 2);
+
+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+ /* At this point, the fields freq and dad are set. We can now
+ * generate the bit lengths.
+ */
+ gen_bitlen(s, (tree_desc *)desc);
+
+ /* The field len is now set, we can generate the bit codes */
+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ if (nextlen == 0) max_count = 138, min_count = 3;
+ tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ s->bl_tree[curlen].Freq += count;
+ } else if (curlen != 0) {
+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+ s->bl_tree[REP_3_6].Freq++;
+ } else if (count <= 10) {
+ s->bl_tree[REPZ_3_10].Freq++;
+ } else {
+ s->bl_tree[REPZ_11_138].Freq++;
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ /* tree[max_code+1].Len = -1; */ /* guard already set */
+ if (nextlen == 0) max_count = 138, min_count = 3;
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+ } else if (curlen != 0) {
+ if (curlen != prevlen) {
+ send_code(s, curlen, s->bl_tree); count--;
+ }
+ Assert(count >= 3 && count <= 6, " 3_6?");
+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+ } else if (count <= 10) {
+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+ } else {
+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+ deflate_state *s;
+{
+ int max_blindex; /* index of last bit length code of non zero freq */
+
+ /* Determine the bit length frequencies for literal and distance trees */
+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+ /* Build the bit length tree: */
+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
+ /* opt_len now includes the length of the tree representations, except
+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+ */
+
+ /* Determine the number of bit length codes to send. The pkzip format
+ * requires that at least 4 bit length codes be sent. (appnote.txt says
+ * 3 but the actual value used is 4.)
+ */
+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+ }
+ /* Update opt_len to include the bit length tree and counts */
+ s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4;
+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+ s->opt_len, s->static_len));
+
+ return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+ deflate_state *s;
+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+ int rank; /* index in bl_order */
+
+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+ "too many codes");
+ Tracev((stderr, "\nbl counts: "));
+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+ send_bits(s, dcodes-1, 5);
+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
+ for (rank = 0; rank < blcodes; rank++) {
+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+ }
+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
+ deflate_state *s;
+ charf *buf; /* input block */
+ ulg stored_len; /* length of input block */
+ int last; /* one if this is the last block for a file */
+{
+ send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */
+ bi_windup(s); /* align on byte boundary */
+ put_short(s, (ush)stored_len);
+ put_short(s, (ush)~stored_len);
+ zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len);
+ s->pending += stored_len;
+#ifdef ZLIB_DEBUG
+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+ s->compressed_len += (stored_len + 4) << 3;
+ s->bits_sent += 2*16;
+ s->bits_sent += stored_len<<3;
+#endif
+}
+
+/* ===========================================================================
+ * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
+ */
+void ZLIB_INTERNAL _tr_flush_bits(s)
+ deflate_state *s;
+{
+ bi_flush(s);
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ */
+void ZLIB_INTERNAL _tr_align(s)
+ deflate_state *s;
+{
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef ZLIB_DEBUG
+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+ bi_flush(s);
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and write out the encoded block.
+ */
+void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
+ deflate_state *s;
+ charf *buf; /* input block, or NULL if too old */
+ ulg stored_len; /* length of input block */
+ int last; /* one if this is the last block for a file */
+{
+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+ int max_blindex = 0; /* index of last bit length code of non zero freq */
+
+ /* Build the Huffman trees unless a stored block is forced */
+ if (s->level > 0) {
+
+ /* Check if the file is binary or text */
+ if (s->strm->data_type == Z_UNKNOWN)
+ s->strm->data_type = detect_data_type(s);
+
+ /* Construct the literal and distance trees */
+ build_tree(s, (tree_desc *)(&(s->l_desc)));
+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+
+ build_tree(s, (tree_desc *)(&(s->d_desc)));
+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+ /* At this point, opt_len and static_len are the total bit lengths of
+ * the compressed block data, excluding the tree representations.
+ */
+
+ /* Build the bit length tree for the above two trees, and get the index
+ * in bl_order of the last bit length code to send.
+ */
+ max_blindex = build_bl_tree(s);
+
+ /* Determine the best encoding. Compute the block lengths in bytes. */
+ opt_lenb = (s->opt_len+3+7)>>3;
+ static_lenb = (s->static_len+3+7)>>3;
+
+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+ s->last_lit));
+
+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+ } else {
+ Assert(buf != (char*)0, "lost buf");
+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+ }
+
+#ifdef FORCE_STORED
+ if (buf != (char*)0) { /* force stored block */
+#else
+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+ /* 4: two words for the lengths */
+#endif
+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+ * Otherwise we can't have processed more than WSIZE input bytes since
+ * the last block flush, because compression would have been
+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+ * transform a block into a stored block.
+ */
+ _tr_stored_block(s, buf, stored_len, last);
+
+#ifdef FORCE_STATIC
+ } else if (static_lenb >= 0) { /* force static trees */
+#else
+ } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
+#endif
+ send_bits(s, (STATIC_TREES<<1)+last, 3);
+ compress_block(s, (const ct_data *)static_ltree,
+ (const ct_data *)static_dtree);
+#ifdef ZLIB_DEBUG
+ s->compressed_len += 3 + s->static_len;
+#endif
+ } else {
+ send_bits(s, (DYN_TREES<<1)+last, 3);
+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+ max_blindex+1);
+ compress_block(s, (const ct_data *)s->dyn_ltree,
+ (const ct_data *)s->dyn_dtree);
+#ifdef ZLIB_DEBUG
+ s->compressed_len += 3 + s->opt_len;
+#endif
+ }
+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+ /* The above check is made mod 2^32, for files larger than 512 MB
+ * and uLong implemented on 32 bits.
+ */
+ init_block(s);
+
+ if (last) {
+ bi_windup(s);
+#ifdef ZLIB_DEBUG
+ s->compressed_len += 7; /* align on byte boundary */
+#endif
+ }
+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+ s->compressed_len-7*last));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int ZLIB_INTERNAL _tr_tally (s, dist, lc)
+ deflate_state *s;
+ unsigned dist; /* distance of matched string */
+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+ s->d_buf[s->last_lit] = (ush)dist;
+ s->l_buf[s->last_lit++] = (uch)lc;
+ if (dist == 0) {
+ /* lc is the unmatched char */
+ s->dyn_ltree[lc].Freq++;
+ } else {
+ s->matches++;
+ /* Here, lc is the match length - MIN_MATCH */
+ dist--; /* dist = match distance - 1 */
+ Assert((ush)dist < (ush)MAX_DIST(s) &&
+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
+
+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+ s->dyn_dtree[d_code(dist)].Freq++;
+ }
+
+#ifdef TRUNCATE_BLOCK
+ /* Try to guess if it is profitable to stop the current block here */
+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+ /* Compute an upper bound for the compressed length */
+ ulg out_length = (ulg)s->last_lit*8L;
+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
+ int dcode;
+ for (dcode = 0; dcode < D_CODES; dcode++) {
+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
+ (5L+extra_dbits[dcode]);
+ }
+ out_length >>= 3;
+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+ s->last_lit, in_length, out_length,
+ 100L - out_length*100L/in_length));
+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+ }
+#endif
+ return (s->last_lit == s->lit_bufsize-1);
+ /* We avoid equality with lit_bufsize because of wraparound at 64K
+ * on 16 bit machines and because stored blocks are restricted to
+ * 64K-1 bytes.
+ */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+ deflate_state *s;
+ const ct_data *ltree; /* literal tree */
+ const ct_data *dtree; /* distance tree */
+{
+ unsigned dist; /* distance of matched string */
+ int lc; /* match length or unmatched char (if dist == 0) */
+ unsigned lx = 0; /* running index in l_buf */
+ unsigned code; /* the code to send */
+ int extra; /* number of extra bits to send */
+
+ if (s->last_lit != 0) do {
+ dist = s->d_buf[lx];
+ lc = s->l_buf[lx++];
+ if (dist == 0) {
+ send_code(s, lc, ltree); /* send a literal byte */
+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+ } else {
+ /* Here, lc is the match length - MIN_MATCH */
+ code = _length_code[lc];
+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
+ extra = extra_lbits[code];
+ if (extra != 0) {
+ lc -= base_length[code];
+ send_bits(s, lc, extra); /* send the extra length bits */
+ }
+ dist--; /* dist is now the match distance - 1 */
+ code = d_code(dist);
+ Assert (code < D_CODES, "bad d_code");
+
+ send_code(s, code, dtree); /* send the distance code */
+ extra = extra_dbits[code];
+ if (extra != 0) {
+ dist -= (unsigned)base_dist[code];
+ send_bits(s, dist, extra); /* send the extra distance bits */
+ }
+ } /* literal or match pair ? */
+
+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+ Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+ "pendingBuf overflow");
+
+ } while (lx < s->last_lit);
+
+ send_code(s, END_BLOCK, ltree);
+}
+
+/* ===========================================================================
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ * a) There are no non-portable control characters belonging to the
+ * "black list" (0..6, 14..25, 28..31).
+ * b) There is at least one printable character belonging to the
+ * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ * "gray list" that is ignored in this detection algorithm:
+ * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local int detect_data_type(s)
+ deflate_state *s;
+{
+ /* black_mask is the bit mask of black-listed bytes
+ * set bits 0..6, 14..25, and 28..31
+ * 0xf3ffc07f = binary 11110011111111111100000001111111
+ */
+ unsigned long black_mask = 0xf3ffc07fUL;
+ int n;
+
+ /* Check for non-textual ("black-listed") bytes. */
+ for (n = 0; n <= 31; n++, black_mask >>= 1)
+ if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+ return Z_BINARY;
+
+ /* Check for textual ("white-listed") bytes. */
+ if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+ || s->dyn_ltree[13].Freq != 0)
+ return Z_TEXT;
+ for (n = 32; n < LITERALS; n++)
+ if (s->dyn_ltree[n].Freq != 0)
+ return Z_TEXT;
+
+ /* There are no "black-listed" or "white-listed" bytes:
+ * this stream either is empty or has tolerated ("gray-listed") bytes only.
+ */
+ return Z_BINARY;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+ unsigned code; /* the value to invert */
+ int len; /* its bit length */
+{
+ register unsigned res = 0;
+ do {
+ res |= code & 1;
+ code >>= 1, res <<= 1;
+ } while (--len > 0);
+ return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+ deflate_state *s;
+{
+ if (s->bi_valid == 16) {
+ put_short(s, s->bi_buf);
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ } else if (s->bi_valid >= 8) {
+ put_byte(s, (Byte)s->bi_buf);
+ s->bi_buf >>= 8;
+ s->bi_valid -= 8;
+ }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+ deflate_state *s;
+{
+ if (s->bi_valid > 8) {
+ put_short(s, s->bi_buf);
+ } else if (s->bi_valid > 0) {
+ put_byte(s, (Byte)s->bi_buf);
+ }
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef ZLIB_DEBUG
+ s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
diff --git a/lib/zlib/trees.h b/lib/zlib/trees.h
new file mode 100644
index 0000000..d35639d
--- /dev/null
+++ b/lib/zlib/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
+};
+
diff --git a/lib/zlib/uncompr.c b/lib/zlib/uncompr.c
new file mode 100644
index 0000000..f03a1a8
--- /dev/null
+++ b/lib/zlib/uncompr.c
@@ -0,0 +1,93 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Decompresses the source buffer into the destination buffer. *sourceLen is
+ the byte length of the source buffer. Upon entry, *destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit,
+ *destLen is the size of the decompressed data and *sourceLen is the number
+ of source bytes consumed. Upon return, source + *sourceLen points to the
+ first unused input byte.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
+ Z_DATA_ERROR if the input data was corrupted, including if the input data is
+ an incomplete zlib stream.
+*/
+int ZEXPORT uncompress2 (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong *sourceLen;
+{
+ z_stream stream;
+ int err;
+ const uInt max = (uInt)-1;
+ uLong len, left;
+ Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */
+
+ len = *sourceLen;
+ if (*destLen) {
+ left = *destLen;
+ *destLen = 0;
+ }
+ else {
+ left = 1;
+ dest = buf;
+ }
+
+ stream.next_in = (z_const Bytef *)source;
+ stream.avail_in = 0;
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = inflateInit(&stream);
+ if (err != Z_OK) return err;
+
+ stream.next_out = dest;
+ stream.avail_out = 0;
+
+ do {
+ if (stream.avail_out == 0) {
+ stream.avail_out = left > (uLong)max ? max : (uInt)left;
+ left -= stream.avail_out;
+ }
+ if (stream.avail_in == 0) {
+ stream.avail_in = len > (uLong)max ? max : (uInt)len;
+ len -= stream.avail_in;
+ }
+ err = inflate(&stream, Z_NO_FLUSH);
+ } while (err == Z_OK);
+
+ *sourceLen -= len + stream.avail_in;
+ if (dest != buf)
+ *destLen = stream.total_out;
+ else if (stream.total_out && err == Z_BUF_ERROR)
+ left = 1;
+
+ inflateEnd(&stream);
+ return err == Z_STREAM_END ? Z_OK :
+ err == Z_NEED_DICT ? Z_DATA_ERROR :
+ err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR :
+ err;
+}
+
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ return uncompress2(dest, destLen, source, &sourceLen);
+}
diff --git a/lib/zlib/zconf.h.in b/lib/zlib/zconf.h.in
new file mode 100644
index 0000000..5e6c4a2
--- /dev/null
+++ b/lib/zlib/zconf.h.in
@@ -0,0 +1,556 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/* The following four defines are enabled by sudo's configure script. */
+#undef HAVE_DSO_VISIBILITY
+#undef HAVE_MEMCPY
+#undef HAVE_UNISTD_H
+#undef HAVE_VSNPRINTF
+#undef _FILE_OFFSET_BITS
+#undef _LARGE_FILES
+#undef const
+
+/* We build sudo and its libs with -fvisibility=hidden where supported. */
+#ifdef HAVE_DSO_VISIBILITY
+# if defined(__GNUC__)
+# define ZEXTERN extern __attribute__((__visibility__("default")))
+# elif defined(__SUNPRO_C)
+# define ZEXTERN extern __global
+# elif defined(ZLIB_INTERNAL)
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+#endif
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
+
+/* all linked symbols and init macros */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_bits z__tr_flush_bits
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# define adler32_z z_adler32_z
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define crc32_z z_crc32_z
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateGetDictionary z_deflateGetDictionary
+# define deflateInit z_deflateInit
+# define deflateInit2 z_deflateInit2
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzfread z_gzfread
+# define gzfwrite z_gzfwrite
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzvprintf z_gzvprintf
+# define gzwrite z_gzwrite
+# endif
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit z_inflateBackInit
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCodesUsed z_inflateCodesUsed
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetDictionary z_inflateGetDictionary
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit z_inflateInit
+# define inflateInit2 z_inflateInit2
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateResetKeep z_inflateResetKeep
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflateValidate z_inflateValidate
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# define uncompress2 z_uncompress2
+# endif
+# define zError z_zError
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
+#ifdef Z_SOLO
+ typedef unsigned long z_size_t;
+#else
+# define z_longlong long long
+# if defined(NO_SIZE_T)
+ typedef unsigned NO_SIZE_T z_size_t;
+# elif defined(STDC)
+# include <stddef.h>
+ typedef size_t z_size_t;
+# else
+ typedef unsigned long z_size_t;
+# endif
+# undef z_longlong
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# elif (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# elif (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+# ifndef Z_SOLO
+# include <sys/types.h> /* for off_t */
+# endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+# include <stdarg.h> /* for va_list */
+# endif
+#endif
+
+#ifdef _WIN32
+# ifndef Z_SOLO
+# include <stddef.h> /* for wchar_t */
+# endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+# endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+# define z_off64_t off64_t
+#else
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/lib/zlib/zlib.exp b/lib/zlib/zlib.exp
new file mode 100644
index 0000000..76ac35e
--- /dev/null
+++ b/lib/zlib/zlib.exp
@@ -0,0 +1,85 @@
+adler32
+adler32_combine
+adler32_combine64
+adler32_z
+compress
+compress2
+compressBound
+crc32
+crc32_combine
+crc32_combine64
+crc32_z
+deflate
+deflateBound
+deflateCopy
+deflateEnd
+deflateGetDictionary
+deflateInit2_
+deflateInit_
+deflateParams
+deflatePending
+deflatePrime
+deflateReset
+deflateResetKeep
+deflateSetDictionary
+deflateSetHeader
+deflateTune
+get_crc_table
+gzbuffer
+gzclearerr
+gzclose
+gzclose_r
+gzclose_w
+gzdirect
+gzdopen
+gzeof
+gzerror
+gzflush
+gzfread
+gzfwrite
+gzgetc
+gzgetc_
+gzgets
+gzoffset
+gzoffset64
+gzopen
+gzopen64
+gzprintf
+gzputc
+gzputs
+gzread
+gzrewind
+gzseek
+gzseek64
+gzsetparams
+gztell
+gztell64
+gzungetc
+gzvprintf
+gzwrite
+inflate
+inflateBack
+inflateBackEnd
+inflateBackInit_
+inflateCodesUsed
+inflateCopy
+inflateEnd
+inflateGetDictionary
+inflateGetHeader
+inflateInit2_
+inflateInit_
+inflateMark
+inflatePrime
+inflateReset
+inflateReset2
+inflateResetKeep
+inflateSetDictionary
+inflateSync
+inflateSyncPoint
+inflateUndermine
+inflateValidate
+uncompress
+uncompress2
+zError
+zlibCompileFlags
+zlibVersion
diff --git a/lib/zlib/zlib.h b/lib/zlib/zlib.h
new file mode 100644
index 0000000..f09cdaf
--- /dev/null
+++ b/lib/zlib/zlib.h
@@ -0,0 +1,1912 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.11, January 15th, 2017
+
+ Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+ (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.11"
+#define ZLIB_VERNUM 0x12b0
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 11
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed data.
+ This version of the library supports only one compression method (deflation)
+ but other algorithms will be added later and will have the same stream
+ interface.
+
+ Compression can be done in a single step if the buffers are large enough,
+ or can be done by repeated calls of the compression function. In the latter
+ case, the application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip and raw deflate streams in
+ memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never crash
+ even in the case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ z_const Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total number of input bytes read so far */
+
+ Bytef *next_out; /* next output byte will go here */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total number of bytes output so far */
+
+ z_const char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: binary or text
+ for deflate, or the decoding state for inflate */
+ uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ gzip header information passed to and from zlib routines. See RFC 1952
+ for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+ int text; /* true if compressed data believed to be text */
+ uLong time; /* modification time */
+ int xflags; /* extra flags (not used when writing a gzip file) */
+ int os; /* operating system */
+ Bytef *extra; /* pointer to extra field or Z_NULL if none */
+ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
+ uInt extra_max; /* space at extra (only when reading header) */
+ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
+ uInt name_max; /* space at name (only when reading header) */
+ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
+ uInt comm_max; /* space at comment (only when reading header) */
+ int hcrc; /* true if there was or will be a header crc */
+ int done; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+ The application must update next_in and avail_in when avail_in has dropped
+ to zero. It must update next_out and avail_out when avail_out has dropped
+ to zero. The application must initialize zalloc, zfree and opaque before
+ calling the init function. All other fields are set by the compression
+ library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe. In that case, zlib is thread-safe. When zalloc and zfree are
+ Z_NULL on entry to the initialization function, they are set to internal
+ routines that use the standard library functions malloc() and free().
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this if
+ the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers
+ returned by zalloc for objects of exactly 65536 bytes *must* have their
+ offset normalized to zero. The default allocation function provided by this
+ library ensures this (see zutil.c). To reduce memory requirements and avoid
+ any allocation of 64K objects, at the expense of compression ratio, compile
+ the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or progress
+ reports. After compression, total_in holds the total size of the
+ uncompressed data and may be saved for use by the decompressor (particularly
+ if the decompressor wants to decompress everything in a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+#define Z_TREES 6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_FIXED 4
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_TEXT 1
+#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field for deflate() */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is not
+ compatible with the zlib.h header file used by the application. This check
+ is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller. If
+ zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+ allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at all
+ (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION
+ requests a default compromise between speed and compression (currently
+ equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if level is not a valid compression level, or
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION). msg is set to null
+ if there is no error message. deflateInit does not perform any compression:
+ this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Generate more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary. Some output may be provided even if
+ flush is zero.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating avail_in or avail_out accordingly; avail_out should
+ never be zero before the call. The application can consume the compressed
+ output when it wants, for example when the output buffer is full (avail_out
+ == 0), or after each call of deflate(). If deflate returns Z_OK and with
+ zero avail_out, it must be called again after making room in the output
+ buffer because there might be more output pending. See deflatePending(),
+ which can be used if desired to determine whether or not there is more ouput
+ in that case.
+
+ Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+ decide how much data to accumulate before producing output, in order to
+ maximize compression.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In
+ particular avail_in is zero after the call if enough output space has been
+ provided before the call.) Flushing may degrade compression for some
+ compression algorithms and so it should be used only when necessary. This
+ completes the current deflate block and follows it with an empty stored block
+ that is three bits plus filler bits to the next byte, followed by four bytes
+ (00 00 ff ff).
+
+ If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+ output buffer, but the output is not aligned to a byte boundary. All of the
+ input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+ This completes the current deflate block and follows it with an empty fixed
+ codes block that is 10 bits long. This assures that enough bytes are output
+ in order for the decompressor to finish the block before the empty fixed
+ codes block.
+
+ If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+ for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+ seven bits of the current block are held to be written as the next byte after
+ the next deflate block is completed. In this case, the decompressor may not
+ be provided enough bits at this point in order to complete decompression of
+ the data provided so far to the compressor. It may need to wait for the next
+ block to be emitted. This is for advanced applications that need to control
+ the emission of deflate blocks.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there was
+ enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this
+ function must be called again with Z_FINISH and more output space (updated
+ avail_out) but no more input data, until it returns with Z_STREAM_END or an
+ error. After deflate has returned Z_STREAM_END, the only possible operations
+ on the stream are deflateReset or deflateEnd.
+
+ Z_FINISH can be used in the first deflate call after deflateInit if all the
+ compression is to be done in a single step. In order to complete in one
+ call, avail_out must be at least the value returned by deflateBound (see
+ below). Then deflate is guaranteed to return Z_STREAM_END. If not enough
+ output space is provided, deflate will not return Z_STREAM_END, and it must
+ be called again as described above.
+
+ deflate() sets strm->adler to the Adler-32 checksum of all input read
+ so far (that is, total_in bytes). If a gzip stream is being generated, then
+ strm->adler will be the CRC-32 checksum of the input read so far. (See
+ deflateInit2 below.)
+
+ deflate() may update strm->data_type if it can make a good guess about
+ the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is
+ considered binary. This field is only for information purposes and does not
+ affect the compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was Z_NULL or the state was inadvertently written over
+ by the application), or Z_BUF_ERROR if no progress is possible (for example
+ avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and
+ deflate() can be called again with more input and more output space to
+ continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case, msg
+ may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. In the current version of inflate, the provided input is not
+ read or consumed. The allocation of a sliding window will be deferred to
+ the first call of inflate (if the decompression does not complete on the
+ first call). If zalloc and zfree are set to Z_NULL, inflateInit updates
+ them to use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit does not perform any decompression.
+ Actual decompression will be done by inflate(). So next_in, and avail_in,
+ next_out, and avail_out are unused and unchanged. The current
+ implementation of inflateInit() does not process any header information --
+ that is deferred until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), then next_in and avail_in are updated
+ accordingly, and processing will resume at this point for the next call of
+ inflate().
+
+ - Generate more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there is
+ no more input data or no more space in the output buffer (see below about
+ the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating the next_* and avail_* values accordingly. If the
+ caller of inflate() does not provide both available input and available
+ output space, it is possible that there will be no progress made. The
+ application can consume the uncompressed output when it wants, for example
+ when the output buffer is full (avail_out == 0), or after each call of
+ inflate(). If inflate returns Z_OK and with zero avail_out, it must be
+ called again after making room in the output buffer because there might be
+ more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+ Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate()
+ stop if and when it gets to the next deflate block boundary. When decoding
+ the zlib or gzip format, this will cause inflate() to return immediately
+ after the header and before the first block. When doing a raw inflate,
+ inflate() will go ahead and process the first block, and will return when it
+ gets to the end of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ To assist in this, on return inflate() always sets strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64 if
+ inflate() is currently decoding the last block in the deflate stream, plus
+ 128 if inflate() returned immediately after decoding an end-of-block code or
+ decoding the complete header up to just before the first byte of the deflate
+ stream. The end-of-block will not be indicated until all of the uncompressed
+ data from that block has been written to strm->next_out. The number of
+ unused bits may in general be greater than seven, except when bit 7 of
+ data_type is set, in which case the number of unused bits will be less than
+ eight. data_type is set as noted here every time inflate() returns for all
+ flush options, and so can be used to determine the amount of currently
+ consumed input in bits.
+
+ The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+ end of each deflate block header is reached, before any actual data in that
+ block is decoded. This allows the caller to determine the length of the
+ deflate block header for later use in random access within a deflate block.
+ 256 is added to the value of strm->data_type when inflate() returns
+ immediately after reaching the end of the deflate block header.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step (a
+ single call of inflate), the parameter flush should be set to Z_FINISH. In
+ this case all pending input is processed and all pending output is flushed;
+ avail_out must be large enough to hold all of the uncompressed data for the
+ operation to complete. (The size of the uncompressed data may have been
+ saved by the compressor for this purpose.) The use of Z_FINISH is not
+ required to perform an inflation in one step. However it may be used to
+ inform inflate that a faster approach can be used for the single inflate()
+ call. Z_FINISH also informs inflate to not maintain a sliding window if the
+ stream completes, which reduces inflate's memory footprint. If the stream
+ does not complete, either because not all of the stream is provided or not
+ enough output space is provided, then a sliding window will be allocated and
+ inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+ been used.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the effects of the flush parameter in this implementation are
+ on the return value of inflate() as noted below, when inflate() returns early
+ when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+ memory for a sliding window when Z_FINISH is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the Adler-32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed Adler-32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically, if requested when
+ initializing with inflateInit2(). Any information contained in the gzip
+ header is not retained unless inflateGetHeader() is used. When processing
+ gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+ produced so far. The CRC-32 is checked against the gzip trailer, as is the
+ uncompressed length, modulo 2^32.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value, in which case strm->msg points to a string with a more specific
+ error), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ next_in or next_out was Z_NULL, or the state was inadvertently written over
+ by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR
+ if no progress was possible or if there was not enough room in the output
+ buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may
+ then call inflateSync() to look for a good compression block if a partial
+ recovery of the data is to be attempted.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state
+ was inconsistent.
+*/
+
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by the
+ caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ For the current implementation of deflate(), a windowBits value of 8 (a
+ window size of 256 bytes) is not supported. As a result, a request for 8
+ will result in 9 (a 512-byte window). In that case, providing 8 to
+ inflateInit2() will result in an error when the zlib header with 9 is
+ checked against the initialization of inflate(). The remedy is to not use 8
+ with deflateInit2() with this initialization, or at least in that case use 9
+ with inflateInit2().
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute a check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero), no
+ header crc, and the operating system will be set to the appropriate value,
+ if the operating system was determined at compile time. If a gzip stream is
+ being written, strm->adler is a CRC-32 instead of an Adler-32.
+
+ For raw deflate or gzip encoding, a request for a 256-byte window is
+ rejected as invalid, since only the zlib header provides a means of
+ transmitting the window size to the decompressor.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but is
+ slow and reduces compression ratio; memLevel=9 uses maximum memory for
+ optimal speed. The default value is 8. See zconf.h for total memory usage
+ as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
+ fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
+ strategy parameter only affects the compression ratio but not the
+ correctness of the compressed output even if it is not set appropriately.
+ Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+ decoder for special applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+ method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+ incompatible with the version assumed by the caller (ZLIB_VERSION). msg is
+ set to null if there is no error message. deflateInit2 does not perform any
+ compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. When using the zlib format, this
+ function must be called immediately after deflateInit, deflateInit2 or
+ deflateReset, and before any call of deflate. When doing raw deflate, this
+ function must be called either before any call of deflate, or immediately
+ after the completion of a deflate block, i.e. after all input has been
+ consumed and all output has been delivered when using any of the flush
+ options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
+ compressor and decompressor must use exactly the same dictionary (see
+ inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size
+ provided in deflateInit or deflateInit2. Thus the strings most likely to be
+ useful should be put at the end of the dictionary, not at the front. In
+ addition, the current implementation of deflate will use at most the window
+ size minus 262 bytes of the provided dictionary.
+
+ Upon return of this function, strm->adler is set to the Adler-32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The Adler-32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ Adler-32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if not at a block boundary for raw deflate). deflateSetDictionary does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
+ Bytef *dictionary,
+ uInt *dictLength));
+/*
+ Returns the sliding dictionary being maintained by deflate. dictLength is
+ set to the number of bytes in the dictionary, and that many bytes are copied
+ to dictionary. dictionary must have enough space, where 32768 bytes is
+ always enough. If deflateGetDictionary() is called with dictionary equal to
+ Z_NULL, then only the dictionary length is returned, and nothing is copied.
+ Similary, if dictLength is Z_NULL, then it is not set.
+
+ deflateGetDictionary() may return a length less than the window size, even
+ when more than the window size in input has been provided. It may return up
+ to 258 bytes less in that case, due to how zlib's implementation of deflate
+ manages the sliding window and lookahead for matches, where matches can be
+ up to 258 bytes long. If the application needs the last window-size bytes of
+ input, then that would need to be saved by the application outside of zlib.
+
+ deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+ stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and can
+ consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit, but
+ does not free and reallocate the internal compression state. The stream
+ will leave the compression level and any other attributes that may have been
+ set unchanged.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2(). This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different strategy.
+ If the compression approach (which is a function of the level) or the
+ strategy is changed, and if any input has been consumed in a previous
+ deflate() call, then the input available so far is compressed with the old
+ level and strategy using deflate(strm, Z_BLOCK). There are three approaches
+ for the compression levels 0, 1..3, and 4..9 respectively. The new level
+ and strategy will take effect at the next call of deflate().
+
+ If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does
+ not have enough output space to complete, then the parameter change will not
+ take effect. In this case, deflateParams() can be called again with the
+ same parameters and more output space to try again.
+
+ In order to assure a change in the parameters on the first try, the
+ deflate stream should be flushed using deflate() with Z_BLOCK or other flush
+ request until strm.avail_out is not zero, before calling deflateParams().
+ Then no more input data should be provided before the deflateParams() call.
+ If this is done, the old level and strategy will be applied to the data
+ compressed before deflateParams(), and the new level and strategy will be
+ applied to the the data compressed after deflateParams().
+
+ deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream
+ state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if
+ there was not enough output space to complete the compression of the
+ available input data before a change in the strategy or approach. Note that
+ in the case of a Z_BUF_ERROR, the parameters are not changed. A return
+ value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be
+ retried with more output space.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain));
+/*
+ Fine tune deflate's internal compression parameters. This should only be
+ used by someone who understands the algorithm used by zlib's deflate for
+ searching for the best matching string, and even then only by the most
+ fanatic optimizer trying to squeeze out the last compressed bit for their
+ specific input data. Read the deflate.c source code for the meaning of the
+ max_lazy, good_length, nice_length, and max_chain parameters.
+
+ deflateTune() can be called after deflateInit() or deflateInit2(), and
+ returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit() or
+ deflateInit2(), and after deflateSetHeader(), if used. This would be used
+ to allocate an output buffer for deflation in a single pass, and so would be
+ called before deflate(). If that first deflate() call is provided the
+ sourceLen input bytes, an output buffer allocated to the size returned by
+ deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+ to return Z_STREAM_END. Note that it is possible for the compressed size to
+ be larger than the value returned by deflateBound() if flush options other
+ than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+ unsigned *pending,
+ int *bits));
+/*
+ deflatePending() returns the number of bytes and bits of output that have
+ been generated, but not yet provided in the available output. The bytes not
+ provided would be due to the available output space having being consumed.
+ The number of bits of output not provided are between 0 and 7, where they
+ await more bits to join them in order to fill out a full byte. If pending
+ or bits are Z_NULL, then those values are not set.
+
+ deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+ */
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the bits
+ leftover from a previous deflate stream when appending to it. As such, this
+ function can only be used for raw deflate, and must be used before the first
+ deflate() call after a deflateInit2() or deflateReset(). bits must be less
+ than or equal to 16, and that many of the least significant bits of value
+ will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+ room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ deflateSetHeader() provides gzip header information for when a gzip
+ stream is requested by deflateInit2(). deflateSetHeader() may be called
+ after deflateInit2() or deflateReset() and before the first call of
+ deflate(). The text, time, os, extra field, name, and comment information
+ in the provided gz_header structure are written to the gzip header (xflag is
+ ignored -- the extra flags are set according to the compression level). The
+ caller must assure that, if not Z_NULL, name and comment are terminated with
+ a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+ available there. If hcrc is true, a gzip header crc is included. Note that
+ the current versions of the command-line version of gzip (up through version
+ 1.3.x) do not support header crc's, and will report that it is a "multi-part
+ gzip file" and give up.
+
+ If deflateSetHeader is not used, the default gzip header has text false,
+ the time set to zero, and os set to 255, with no extra, name, or comment
+ fields. The gzip header is returned to the default state by deflateReset().
+
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be zero to request that inflate use the window size in
+ the zlib header of the compressed stream.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an Adler-32 or a CRC-32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
+ CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see
+ below), inflate() will not automatically decode concatenated gzip streams.
+ inflate() will return Z_STREAM_END at the end of the gzip stream. The state
+ would need to be reset to continue decoding a subsequent gzip stream.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit2 does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit2() does not process any header information -- that is
+ deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the Adler-32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called at any
+ time to set the dictionary. If the provided dictionary is smaller than the
+ window and there is already data in the window, then the provided dictionary
+ will amend what's there. The application must insure that the dictionary
+ that was used for compression is provided.
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect Adler-32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+ Bytef *dictionary,
+ uInt *dictLength));
+/*
+ Returns the sliding dictionary being maintained by inflate. dictLength is
+ set to the number of bytes in the dictionary, and that many bytes are copied
+ to dictionary. dictionary must have enough space, where 32768 bytes is
+ always enough. If inflateGetDictionary() is called with dictionary equal to
+ Z_NULL, then only the dictionary length is returned, and nothing is copied.
+ Similary, if dictLength is Z_NULL, then it is not set.
+
+ inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+ stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a possible full flush point (see above
+ for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+ All full flush points have this pattern, but not all occurrences of this
+ pattern are full flush points.
+
+ inflateSync returns Z_OK if a possible full flush point has been found,
+ Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+ has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+ In the success case, the application may save the current current value of
+ total_in which indicates where valid compressed data was found. In the
+ error case, the application may repeatedly call inflateSync, providing more
+ input each time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate the internal decompression state. The
+ stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+ int windowBits));
+/*
+ This function is the same as inflateReset, but it also permits changing
+ the wrap and window size requests. The windowBits parameter is interpreted
+ the same as it is for inflateInit2. If the window size is changed, then the
+ memory allocated for the window is freed, and the window will be reallocated
+ by inflate() if needed.
+
+ inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+ the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ This function inserts bits in the inflate input stream. The intent is
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ If bits is negative, then the input stream bit buffer is emptied. Then
+ inflatePrime() can be called again to put bits in the buffer. This is used
+ to clear out bits leftover after feeding inflate a block description prior
+ to feeding inflate codes.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+ This function returns two values, one in the lower 16 bits of the return
+ value, and the other in the remaining upper bits, obtained by shifting the
+ return value down 16 bits. If the upper value is -1 and the lower value is
+ zero, then inflate() is currently decoding information outside of a block.
+ If the upper value is -1 and the lower value is non-zero, then inflate is in
+ the middle of a stored block, with the lower value equaling the number of
+ bytes from the input remaining to copy. If the upper value is not -1, then
+ it is the number of bits back from the current bit position in the input of
+ the code (literal or length/distance pair) currently being processed. In
+ that case the lower value is the number of bytes already emitted for that
+ code.
+
+ A code is being processed if inflate is waiting for more input to complete
+ decoding of the code, or if it has completed decoding but is waiting for
+ more output space to write the literal or match data.
+
+ inflateMark() is used to mark locations in the input data for random
+ access, which may be at bit positions, and to note those cases where the
+ output of a code may span boundaries of random access blocks. The current
+ location in the input stream can be determined from avail_in and data_type
+ as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+ inflateMark returns the value noted above, or -65536 if the provided
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ inflateGetHeader() requests that gzip header information be stored in the
+ provided gz_header structure. inflateGetHeader() may be called after
+ inflateInit2() or inflateReset(), and before the first call of inflate().
+ As inflate() processes the gzip stream, head->done is zero until the header
+ is completed, at which time head->done is set to one. If a zlib stream is
+ being decoded, then head->done is set to -1 to indicate that there will be
+ no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
+ used to force inflate() to return immediately after header processing is
+ complete and before any actual data is decompressed.
+
+ The text, time, xflags, and os fields are filled in with the gzip header
+ contents. hcrc is set to true if there is a header CRC. (The header CRC
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ contains the maximum number of bytes to write to extra. Once done is true,
+ extra_len contains the actual extra field length, and extra contains the
+ extra field, or that field truncated if extra_max is less than extra_len.
+ If name is not Z_NULL, then up to name_max characters are written there,
+ terminated with a zero unless the length is greater than name_max. If
+ comment is not Z_NULL, then up to comm_max characters are written there,
+ terminated with a zero unless the length is greater than comm_max. When any
+ of extra, name, or comment are not Z_NULL and the respective field is not
+ present in the header, then that field is set to Z_NULL to signal its
+ absence. This allows the use of deflateSetHeader() with the returned
+ structure to duplicate the header. However if those fields are set to
+ allocated memory, then the application will need to save those pointers
+ elsewhere so that they can be eventually freed.
+
+ If inflateGetHeader is not used, then the header information is simply
+ discarded. The header is always checked for validity, including the header
+ CRC if present. inflateReset() will reset the process to discard the header
+ information. The application would need to call inflateGetHeader() again to
+ retrieve the header from the next gzip stream.
+
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+ allocated, or Z_VERSION_ERROR if the version of the library does not match
+ the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *,
+ z_const unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is potentially more efficient than
+ inflate() for file i/o applications, in that it avoids copying between the
+ output and the sliding window by simply making the window itself the output
+ buffer. inflate() can be faster on modern CPUs when used with large
+ buffers. inflateBack() trusts the application to not change the output
+ buffer passed by the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free the
+ allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects only
+ the raw deflate stream to decompress. This is different from the default
+ behavior of inflate(), which expects a zlib header and trailer around the
+ deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero -- buf is ignored in that
+ case -- and inflateBack() will return a buffer error. inflateBack() will
+ call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].
+ out() should return zero on success, or non-zero on failure. If out()
+ returns non-zero, inflateBack() will return with an error. Neither in() nor
+ out() are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+ in the deflate stream (in which case strm->msg is set to indicate the nature
+ of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+ In the case of Z_BUF_ERROR, an input or output error can be distinguished
+ using strm->next_in which will be Z_NULL only if in() returned an error. If
+ strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+ non-zero. (in() will always be called before out(), so strm->next_in is
+ assured to be defined if out() returns non-zero.) Note that inflateBack()
+ cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: ZLIB_DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+#ifndef Z_SOLO
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the basic
+ stream-oriented functions. To simplify the interface, some default options
+ are assumed (compression level and memory usage, standard memory allocation
+ functions). The source code of these utility functions can be modified if
+ you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed data. compress() is equivalent to compress2() with a level
+ parameter of Z_DEFAULT_COMPRESSION.
+
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed data.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before a
+ compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit, destLen
+ is the actual size of the uncompressed data.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
+ the case where there is not enough room, uncompress() will fill the output
+ buffer with the uncompressed data up to that point.
+*/
+
+ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong *sourceLen));
+/*
+ Same as uncompress, except that sourceLen is a pointer, where the
+ length of the source is *sourceLen. On return, *sourceLen is the number of
+ source bytes consumed.
+*/
+
+ /* gzip file access functions */
+
+/*
+ This library supports reading and writing files in gzip (.gz) format with
+ an interface similar to that of stdio, using the functions that start with
+ "gz". The gzip format is different from the zlib format. gzip is a gzip
+ wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+ Opens a gzip (.gz) file for reading or writing. The mode parameter is as
+ in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+ a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+ compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+ for fixed code compression as in "wb9F". (See the description of
+ deflateInit2 for more information about the strategy parameter.) 'T' will
+ request transparent writing or appending with no compression and not using
+ the gzip format.
+
+ "a" can be used instead of "w" to request that the gzip stream that will
+ be written be appended to the file. "+" will result in an error, since
+ reading and writing to the same gzip file is not supported. The addition of
+ "x" when writing will create the file exclusively, which fails if the file
+ already exists. On systems that support it, the addition of "e" when
+ reading or writing will set the flag to close the file on an execve() call.
+
+ These functions, as well as gzip, will read and decode a sequence of gzip
+ streams in a file. The append function of gzopen() can be used to create
+ such a file. (Also see gzflush() for another way to do this.) When
+ appending, gzopen does not test whether the file begins with a gzip stream,
+ nor does it look for the end of the gzip streams to begin appending. gzopen
+ will simply append a gzip stream to the existing file.
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression. When
+ reading, this will be detected automatically by looking for the magic two-
+ byte gzip header.
+
+ gzopen returns NULL if the file could not be opened, if there was
+ insufficient memory to allocate the gzFile state, or if an invalid mode was
+ specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+ errno can be checked to determine if the reason gzopen failed was that the
+ file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen associates a gzFile with the file descriptor fd. File descriptors
+ are obtained from calls like open, dup, creat, pipe or fileno (if the file
+ has been previously opened with fopen). The mode parameter is as in gzopen.
+
+ The next call of gzclose on the returned gzFile will also close the file
+ descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+ fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+ mode);. The duplicated descriptor should be saved to avoid a leak, since
+ gzdopen does not close fd if it fails. If you are using fileno() to get the
+ file descriptor from a FILE *, then you will have to use dup() to avoid
+ double-close()ing the file descriptor. Both gzclose() and fclose() will
+ close the associated file descriptor, so they need to have different file
+ descriptors.
+
+ gzdopen returns NULL if there was insufficient memory to allocate the
+ gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+ provided, or '+' was provided), or if fd is -1. The file descriptor is not
+ used until the next gz* read, write, seek, or close operation, so gzdopen
+ will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+ Set the internal buffer size used by this library's functions. The
+ default buffer size is 8192 bytes. This function must be called after
+ gzopen() or gzdopen(), and before any other calls that read or write the
+ file. The buffer memory allocation is always deferred to the first read or
+ write. Three times that size in buffer space is allocated. A larger buffer
+ size of, for example, 64K or 128K bytes will noticeably increase the speed
+ of decompression (reading).
+
+ The new buffer size also affects the maximum length for gzprintf().
+
+ gzbuffer() returns 0 on success, or -1 on failure, such as being called
+ too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters. Previously provided
+ data is flushed before the parameter change.
+
+ gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not
+ opened for writing, Z_ERRNO if there is an error writing the flushed data,
+ or Z_MEM_ERROR if there is a memory allocation error.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file. If
+ the input file is not in gzip format, gzread copies the given number of
+ bytes into the buffer directly from the file.
+
+ After reaching the end of a gzip stream in the input, gzread will continue
+ to read, looking for another gzip stream. Any number of gzip streams may be
+ concatenated in the input file, and will all be decompressed by gzread().
+ If something other than a gzip stream is encountered after a gzip stream,
+ that remaining trailing garbage is ignored (and no error is returned).
+
+ gzread can be used to read a gzip file that is being concurrently written.
+ Upon reaching the end of the input, gzread will return with the available
+ data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+ gzclearerr can be used to clear the end of file indicator in order to permit
+ gzread to be tried again. Z_OK indicates that a gzip stream was completed
+ on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
+ middle of a gzip stream. Note that gzread does not return -1 in the event
+ of an incomplete gzip stream. This error is deferred until gzclose(), which
+ will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+ stream. Alternatively, gzerror can be used before gzclose to detect this
+ case.
+
+ gzread returns the number of uncompressed bytes actually read, less than
+ len for end of file, or -1 for error. If len is too large to fit in an int,
+ then nothing is read, -1 is returned, and the error state is set to
+ Z_STREAM_ERROR.
+*/
+
+ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
+ gzFile file));
+/*
+ Read up to nitems items of size size from file to buf, otherwise operating
+ as gzread() does. This duplicates the interface of stdio's fread(), with
+ size_t request and return types. If the library defines size_t, then
+ z_size_t is identical to size_t. If not, then z_size_t is an unsigned
+ integer type that can contain a pointer.
+
+ gzfread() returns the number of full items read of size size, or zero if
+ the end of the file was reached and a full item could not be read, or if
+ there was an error. gzerror() must be consulted if zero is returned in
+ order to determine if there was an error. If the multiplication of size and
+ nitems overflows, i.e. the product does not fit in a z_size_t, then nothing
+ is read, zero is returned, and the error state is set to Z_STREAM_ERROR.
+
+ In the event that the end of file is reached and only a partial item is
+ available at the end, i.e. the remaining uncompressed data length is not a
+ multiple of size, then the final partial item is nevetheless read into buf
+ and the end-of-file flag is set. The length of the partial item read is not
+ provided, but could be inferred from the result of gztell(). This behavior
+ is the same as the behavior of fread() implementations in common libraries,
+ but it prevents the direct use of gzfread() to read a concurrently written
+ file, reseting and retrying on end-of-file, when size is not 1.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes written or 0 in case of
+ error.
+*/
+
+ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
+ z_size_t nitems, gzFile file));
+/*
+ gzfwrite() writes nitems items of size size from buf to file, duplicating
+ the interface of stdio's fwrite(), with size_t request and return types. If
+ the library defines size_t, then z_size_t is identical to size_t. If not,
+ then z_size_t is an unsigned integer type that can contain a pointer.
+
+ gzfwrite() returns the number of full items written of size size, or zero
+ if there was an error. If the multiplication of size and nitems overflows,
+ i.e. the product does not fit in a z_size_t, then nothing is written, zero
+ is returned, and the error state is set to Z_STREAM_ERROR.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the arguments to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written, or a negative zlib error code in case
+ of error. The number of uncompressed bytes written is limited to 8191, or
+ one less than the buffer size given to gzbuffer(). The caller should assure
+ that this limit is not exceeded. If it is exceeded, then gzprintf() will
+ return an error (0) with nothing written. In this case, there may also be a
+ buffer overflow with unpredictable consequences, which is possible only if
+ zlib was compiled with the insecure functions sprintf() or vsprintf()
+ because the secure snprintf() or vsnprintf() functions were not available.
+ This can be determined using zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or a
+ newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. If any characters are read or if len == 1, the
+ string is terminated with a null character. If no characters are read due
+ to an end-of-file or len < 1, then the buffer is left untouched.
+
+ gzgets returns buf which is a null-terminated string, or it returns NULL
+ for end-of-file or in case of error. If there was an error, the contents at
+ buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file. gzputc
+ returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte or -1
+ in case of end of file or error. This is implemented as a macro for speed.
+ As such, it does not do all of the checking the other functions do. I.e.
+ it does not check to see if file is NULL, nor whether the structure file
+ points to has been clobbered or not.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read as the first character
+ on the next read. At least one character of push-back is allowed.
+ gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
+ fail if c is -1, and may fail if a character has been pushed but not read
+ yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
+ output buffer size of pushed characters is allowed. (See gzbuffer above.)
+ The pushed character will be discarded if the stream is repositioned with
+ gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter flush
+ is as in the deflate() function. The return value is the zlib error number
+ (see function gzerror below). gzflush is only permitted when writing.
+
+ If the flush parameter is Z_FINISH, the remaining data is written and the
+ gzip stream is completed in the output. If gzwrite() is called again, a new
+ gzip stream will be started in the output. gzread() is able to read such
+ concatenated gzip streams.
+
+ gzflush should be called only when strictly necessary because it will
+ degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+
+ Returns the starting position for the next gzread or gzwrite on the given
+ compressed file. This position represents a number of bytes in the
+ uncompressed data stream, and is zero when starting, even if appending or
+ reading a gzip stream from the middle of a file using gzdopen().
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+ Returns the current offset in the file being read or written. This offset
+ includes the count of bytes that precede the gzip stream, for example when
+ appending or when using gzdopen() for reading. When reading, the offset
+ does not include as yet unused buffered input. This information can be used
+ for a progress indicator. On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns true (1) if the end-of-file indicator has been set while reading,
+ false (0) otherwise. Note that the end-of-file indicator is set only if the
+ read tried to go past the end of the input, but came up short. Therefore,
+ just like feof(), gzeof() may return false even if there is no more data to
+ read, in the event that the last read request was for the exact number of
+ bytes remaining in the input file. This will happen if the input file size
+ is an exact multiple of the buffer size.
+
+ If gzeof() returns true, then the read functions will return no more data,
+ unless the end-of-file indicator is reset by gzclearerr() and the input file
+ has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns true (1) if file is being copied directly while reading, or false
+ (0) if file is a gzip stream being decompressed.
+
+ If the input file is empty, gzdirect() will return true, since the input
+ does not contain a gzip stream.
+
+ If gzdirect() is used immediately after gzopen() or gzdopen() it will
+ cause buffers to be allocated to allow reading the file to determine if it
+ is a gzip file. Therefore if gzbuffer() is used, it should be called before
+ gzdirect().
+
+ When writing, gzdirect() returns true (1) if transparent writing was
+ requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
+ gzdirect() is not needed when writing. Transparent writing must be
+ explicitly requested, so the application already knows the answer. When
+ linking statically, using gzdirect() will include all of the zlib code for
+ gzip file reading and decompression, which may not be desired.)
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file and
+ deallocates the (de)compression state. Note that once file is closed, you
+ cannot call gzerror with file, since its structures have been deallocated.
+ gzclose must not be called more than once on the same file, just as free
+ must not be called more than once on the same allocation.
+
+ gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+ file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+ last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+ Same as gzclose(), but gzclose_r() is only for use when reading, and
+ gzclose_w() is only for use when writing or appending. The advantage to
+ using these instead of gzclose() is that they avoid linking in zlib
+ compression or decompression code that is not used when only reading or only
+ writing respectively. If gzclose() is used, then both compression and
+ decompression code will be included the application when linking to a static
+ zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the given
+ compressed file. errnum is set to zlib error number. If an error occurred
+ in the file system and not in the compression library, errnum is set to
+ Z_ERRNO and the application may consult errno to get the exact error code.
+
+ The application must not modify the returned string. Future calls to
+ this function may invalidate the previously returned string. If file is
+ closed, then the string previously returned by gzerror will no longer be
+ available.
+
+ gzerror() should be used to distinguish errors from end-of-file for those
+ functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+#endif /* !Z_SOLO */
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the compression
+ library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is Z_NULL, this function returns the
+ required initial value for the checksum.
+
+ An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed
+ much faster.
+
+ Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf,
+ z_size_t len));
+/*
+ Same as adler32(), but with a size_t length.
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+ z_off_t len2));
+
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
+ that the z_off_t type (like off_t) is a signed integer. If len2 is
+ negative, the result has no meaning or utility.
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running CRC-32 with the bytes buf[0..len-1] and return the
+ updated CRC-32. If buf is Z_NULL, this function returns the required
+ initial value for the crc. Pre- and post-conditioning (one's complement) is
+ performed within this function so it shouldn't be done by the application.
+
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf,
+ z_size_t len));
+/*
+ Same as crc32(), but with a size_t length.
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#ifdef Z_PREFIX_SET
+# define z_deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+# define z_inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+# define z_inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+ (int)sizeof(z_stream))
+# define z_inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, (int)sizeof(z_stream))
+#else
+# define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+# define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+# define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+ (int)sizeof(z_stream))
+# define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, (int)sizeof(z_stream))
+#endif
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure. Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro. The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously. They can
+ * only be used by the gzgetc() macro. You have been warned.
+ */
+struct gzFile_s {
+ unsigned have;
+ unsigned char *next;
+ z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+# define z_gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
+#else
+# define gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+# ifdef Z_PREFIX_SET
+# define z_gzopen z_gzopen64
+# define z_gzseek z_gzseek64
+# define z_gztell z_gztell64
+# define z_gzoffset z_gzoffset64
+# define z_adler32_combine z_adler32_combine64
+# define z_crc32_combine z_crc32_combine64
+# else
+# define gzopen gzopen64
+# define gzseek gzseek64
+# define gztell gztell64
+# define gzoffset gzoffset64
+# define adler32_combine adler32_combine64
+# define crc32_combine crc32_combine64
+# endif
+# ifndef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+# endif
+#else
+ ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+#else /* Z_SOLO */
+
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
+/* undocumented functions */
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
+ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int));
+ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp));
+ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
+#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO)
+ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
+ const char *mode));
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+ const char *format,
+ va_list va));
+# endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/lib/zlib/zutil.c b/lib/zlib/zutil.c
new file mode 100644
index 0000000..a76c6b0
--- /dev/null
+++ b/lib/zlib/zutil.c
@@ -0,0 +1,325 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2017 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+#ifndef Z_SOLO
+# include "gzguts.h"
+#endif
+
+z_const char * const z_errmsg[10] = {
+ (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */
+ (z_const char *)"stream end", /* Z_STREAM_END 1 */
+ (z_const char *)"", /* Z_OK 0 */
+ (z_const char *)"file error", /* Z_ERRNO (-1) */
+ (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */
+ (z_const char *)"data error", /* Z_DATA_ERROR (-3) */
+ (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */
+ (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */
+ (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */
+ (z_const char *)""
+};
+
+
+const char * ZEXPORT zlibVersion()
+{
+ return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+ uLong flags;
+
+ flags = 0;
+ switch ((int)(sizeof(uInt))) {
+ case 2: break;
+ case 4: flags += 1; break;
+ case 8: flags += 2; break;
+ default: flags += 3;
+ }
+ switch ((int)(sizeof(uLong))) {
+ case 2: break;
+ case 4: flags += 1 << 2; break;
+ case 8: flags += 2 << 2; break;
+ default: flags += 3 << 2;
+ }
+ switch ((int)(sizeof(voidpf))) {
+ case 2: break;
+ case 4: flags += 1 << 4; break;
+ case 8: flags += 2 << 4; break;
+ default: flags += 3 << 4;
+ }
+ switch ((int)(sizeof(z_off_t))) {
+ case 2: break;
+ case 4: flags += 1 << 6; break;
+ case 8: flags += 2 << 6; break;
+ default: flags += 3 << 6;
+ }
+#ifdef ZLIB_DEBUG
+ flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+ flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+ flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+ flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+ flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+ flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+ flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+ flags += 1L << 20;
+#endif
+#ifdef FASTEST
+ flags += 1L << 21;
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifdef NO_vsnprintf
+ flags += 1L << 25;
+# ifdef HAS_vsprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_vsnprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#else
+ flags += 1L << 24;
+# ifdef NO_snprintf
+ flags += 1L << 25;
+# ifdef HAS_sprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_snprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#endif
+ return flags;
+}
+
+#ifdef ZLIB_DEBUG
+#include <stdlib.h>
+# ifndef verbose
+# define verbose 0
+# endif
+int ZLIB_INTERNAL z_verbose = verbose;
+
+void ZLIB_INTERNAL z_error (m)
+ char *m;
+{
+ fprintf(stderr, "%s\n", m);
+ exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+ int err;
+{
+ return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+ /* The Microsoft C Run-Time Library for Windows CE doesn't have
+ * errno. We define it as a global variable to simplify porting.
+ * Its value is always 0 and should not be used.
+ */
+ int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void ZLIB_INTERNAL zmemcpy(dest, source, len)
+ Bytef* dest;
+ const Bytef* source;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = *source++; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+
+int ZLIB_INTERNAL zmemcmp(s1, s2, len)
+ const Bytef* s1;
+ const Bytef* s2;
+ uInt len;
+{
+ uInt j;
+
+ for (j = 0; j < len; j++) {
+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+ }
+ return 0;
+}
+
+void ZLIB_INTERNAL zmemzero(dest, len)
+ Bytef* dest;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = 0; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+#endif
+
+#ifndef Z_SOLO
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+ voidpf org_ptr;
+ voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ voidpf buf;
+ ulg bsize = (ulg)items*size;
+
+ (void)opaque;
+
+ /* If we allocate less than 65520 bytes, we assume that farmalloc
+ * will return a usable pointer which doesn't have to be normalized.
+ */
+ if (bsize < 65520L) {
+ buf = farmalloc(bsize);
+ if (*(ush*)&buf != 0) return buf;
+ } else {
+ buf = farmalloc(bsize + 16L);
+ }
+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+ table[next_ptr].org_ptr = buf;
+
+ /* Normalize the pointer to seg:0 */
+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+ *(ush*)&buf = 0;
+ table[next_ptr++].new_ptr = buf;
+ return buf;
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+ int n;
+
+ (void)opaque;
+
+ if (*(ush*)&ptr != 0) { /* object < 64K */
+ farfree(ptr);
+ return;
+ }
+ /* Find the original pointer */
+ for (n = 0; n < next_ptr; n++) {
+ if (ptr != table[n].new_ptr) continue;
+
+ farfree(table[n].org_ptr);
+ while (++n < next_ptr) {
+ table[n-1] = table[n];
+ }
+ next_ptr--;
+ return;
+ }
+ Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+# define _halloc halloc
+# define _hfree hfree
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
+{
+ (void)opaque;
+ return _halloc((long)items, size);
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+ (void)opaque;
+ _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp malloc OF((uInt size));
+extern voidp calloc OF((uInt items, uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
+ voidpf opaque;
+ unsigned items;
+ unsigned size;
+{
+ (void)opaque;
+ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+ (voidpf)calloc(items, size);
+}
+
+void ZLIB_INTERNAL zcfree (opaque, ptr)
+ voidpf opaque;
+ voidpf ptr;
+{
+ (void)opaque;
+ free(ptr);
+}
+
+#endif /* MY_ZCALLOC */
+
+#endif /* !Z_SOLO */
diff --git a/lib/zlib/zutil.h b/lib/zlib/zutil.h
new file mode 100644
index 0000000..b079ea6
--- /dev/null
+++ b/lib/zlib/zutil.h
@@ -0,0 +1,271 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#ifdef HAVE_HIDDEN
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+# define ZLIB_INTERNAL
+#endif
+
+#include "zlib.h"
+
+#if defined(STDC) && !defined(Z_SOLO)
+# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
+# include <stddef.h>
+# endif
+# include <string.h>
+# include <stdlib.h>
+#endif
+
+#ifdef Z_SOLO
+ typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* since "static" is used to mean two completely different things in C, we
+ define "local" for the non-static meaning of "static", for readability
+ (compile with -Dlocal if your debugger can't find static symbols) */
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+ return (strm->msg = ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+ /* common constants */
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+ /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+# define OS_CODE 0x00
+# ifndef Z_SOLO
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include <alloc.h>
+# endif
+# else /* MSC or DJGPP */
+# include <malloc.h>
+# endif
+# endif
+#endif
+
+#ifdef AMIGA
+# define OS_CODE 1
+#endif
+
+#if defined(VAXC) || defined(VMS)
+# define OS_CODE 2
+# define F_OPEN(name, mode) \
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#ifdef __370__
+# if __TARGET_LIB__ < 0x20000000
+# define OS_CODE 4
+# elif __TARGET_LIB__ < 0x40000000
+# define OS_CODE 11
+# else
+# define OS_CODE 8
+# endif
+#endif
+
+#if defined(ATARI) || defined(atarist)
+# define OS_CODE 5
+#endif
+
+#ifdef OS2
+# define OS_CODE 6
+# if defined(M_I86) && !defined(Z_SOLO)
+# include <malloc.h>
+# endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+# define OS_CODE 7
+# ifndef Z_SOLO
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __acorn
+# define OS_CODE 13
+#endif
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+# define OS_CODE 10
+#endif
+
+#ifdef _BEOS_
+# define OS_CODE 16
+#endif
+
+#ifdef __TOS_OS400__
+# define OS_CODE 18
+#endif
+
+#ifdef __APPLE__
+# define OS_CODE 19
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
+# if defined(_WIN32_WCE)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# ifndef _PTRDIFF_T_DEFINED
+ typedef int ptrdiff_t;
+# define _PTRDIFF_T_DEFINED
+# endif
+# else
+# define fdopen(fd,type) _fdopen(fd,type)
+# endif
+#endif
+
+#if defined(__BORLANDC__) && !defined(MSDOS)
+ #pragma warn -8004
+ #pragma warn -8008
+ #pragma warn -8066
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_WIN32) && \
+ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#endif
+
+ /* common defaults */
+
+#ifndef OS_CODE
+# define OS_CODE 3 /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+# define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+ /* functions */
+
+#if defined(pyr) || defined(Z_SOLO)
+# define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+ * You may have to use the same strategy for Borland C (untested).
+ * The __SC__ check is for Symantec.
+ */
+# define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+# define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+# define zmemcpy _fmemcpy
+# define zmemcmp _fmemcmp
+# define zmemzero(dest, len) _fmemset(dest, 0, len)
+# else
+# define zmemcpy memcpy
+# define zmemcmp memcmp
+# define zmemzero(dest, len) memset(dest, 0, len)
+# endif
+#else
+ void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef ZLIB_DEBUG
+# include <stdio.h>
+ extern int ZLIB_INTERNAL z_verbose;
+ extern void ZLIB_INTERNAL z_error OF((char *m));
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+#ifndef Z_SOLO
+ voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+ unsigned size));
+ void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
+#endif
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+/* Reverse the bytes in a 32-bit value */
+#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+#endif /* ZUTIL_H */
diff --git a/log2cl.pl b/log2cl.pl
new file mode 100755
index 0000000..9cfd968
--- /dev/null
+++ b/log2cl.pl
@@ -0,0 +1,102 @@
+#!/usr/bin/env perl
+#
+# Copyright (c) 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Simple script to massage "git log" output into a GNU style ChangeLog.
+# The goal is to emulate "hg log --style=changelog" via perl format.
+
+use warnings;
+
+my $format="%ad %aN <%aE>%n%h%n%B%n";
+my @cmd = ("git", "log", "--log-size", "--name-only", "--date=short", "--format=$format", @ARGV);
+open(LOG, '-|', @cmd) || die "$0: unable to run git log: $!";
+
+my $hash;
+my $body;
+my @files;
+my $key_date = "";
+my $log_size = 0;
+my @lines;
+
+while (<LOG>) {
+ chomp;
+ if (/^log size (\d+)$/) {
+ $log_size = $1;
+
+ # Print previous entry if there is one
+ print_entry($hash, $body, @files) if defined($hash);
+
+ # Init new entry
+ undef $hash;
+ undef $body;
+ undef @files;
+ undef @lines;
+
+ # Read entry and split on newlines
+ read(LOG, my $buf, $log_size) ||
+ die "$0: unable to read $log_size bytes: $!\n";
+ @lines = split(/\r?\n/, $buf);
+
+ # Check for continued entry (duplicate Date + Author)
+ $_ = shift(@lines);
+ if ($_ ne $key_date) {
+ # New entry
+ print "$_\n\n";
+ $key_date = $_;
+ }
+
+ # Hash comes first
+ $hash = shift(@lines);
+
+ # Commit message body (multi-line)
+ foreach (@lines) {
+ last if $_ eq "--HG--";
+ if (defined($body)) {
+ $_ = "\r" if $_ eq "";
+ $body .= " $_";
+ } else {
+ $body = $_;
+ }
+ }
+ } else {
+ # Not a log entry, must be the file list
+ push(@files, $_) unless $_ eq "";
+ }
+}
+
+# Print the last entry
+print_entry($hash, $body, @files) if defined($hash);
+
+exit(0);
+
+sub print_entry
+{
+ my $hash = '[' . shift . ']';
+ my $body = shift;
+ my $files = "* " . join(", ", @_) . ":";
+
+ local $= = 9999; # to silence warning (hack)
+
+ format =
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $files
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
+ $body
+ @*
+ $hash
+
+.
+ write;
+}
diff --git a/ltmain.sh b/ltmain.sh
new file mode 100644
index 0000000..20bec0d
--- /dev/null
+++ b/ltmain.sh
@@ -0,0 +1,11167 @@
+#! /bin/sh
+## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
+## by inline-source v2014-01-03.01
+
+# libtool (GNU libtool) 2.4.6
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 <http://www.gnu.org/licenses/>.
+
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.4.6
+package_revision=2.4.6
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Run './libtool --help' for help with using this script from the
+# command line.
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# After configure completes, it has a better idea of some of the
+# shell tools we need than the defaults used by the functions shared
+# with bootstrap, so set those here where they can still be over-
+# ridden by the user, but otherwise take precedence.
+
+: ${AUTOCONF="autoconf"}
+: ${AUTOMAKE="automake"}
+
+
+## -------------------------- ##
+## Source external libraries. ##
+## -------------------------- ##
+
+# Much of our low-level functionality needs to be sourced from external
+# libraries, which are installed to $pkgauxdir.
+
+# Set a version string for this script.
+scriptversion=2015-01-20.17; # UTC
+
+# General shell script boiler plate, and helper functions.
+# Written by Gary V. Vaughan, 2004
+
+# Copyright (C) 2004-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# 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 3 of the License, or
+# (at your option) any later version.
+
+# As a special exception to the GNU General Public License, if you distribute
+# this file as part of a program or library that is built using GNU Libtool,
+# you may include this file under the same distribution terms that you use
+# for the rest of that program.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNES 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 <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Evaluate this file near the top of your script to gain access to
+# the functions and variables defined here:
+#
+# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
+#
+# If you need to override any of the default environment variable
+# settings, do that before evaluating this file.
+
+
+## -------------------- ##
+## Shell normalisation. ##
+## -------------------- ##
+
+# Some shells need a little help to be as Bourne compatible as possible.
+# Before doing anything else, make sure all that help has been provided!
+
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
+fi
+
+# NLS nuisances: We save the old values in case they are required later.
+_G_user_locale=
+_G_safe_locale=
+for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test set = \"\${$_G_var+set}\"; then
+ save_$_G_var=\$$_G_var
+ $_G_var=C
+ export $_G_var
+ _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
+ _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
+ fi"
+done
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Make sure IFS has a sensible default
+sp=' '
+nl='
+'
+IFS="$sp $nl"
+
+# There are apparently some retarded systems that use ';' as a PATH separator!
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+
+## ------------------------- ##
+## Locate command utilities. ##
+## ------------------------- ##
+
+
+# func_executable_p FILE
+# ----------------------
+# Check that FILE is an executable regular file.
+func_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+}
+
+
+# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
+# --------------------------------------------
+# Search for either a program that responds to --version with output
+# containing "GNU", or else returned by CHECK_FUNC otherwise, by
+# trying all the directories in PATH with each of the elements of
+# PROGS_LIST.
+#
+# CHECK_FUNC should accept the path to a candidate program, and
+# set $func_check_prog_result if it truncates its output less than
+# $_G_path_prog_max characters.
+func_path_progs ()
+{
+ _G_progs_list=$1
+ _G_check_func=$2
+ _G_PATH=${3-"$PATH"}
+
+ _G_path_prog_max=0
+ _G_path_prog_found=false
+ _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
+ for _G_dir in $_G_PATH; do
+ IFS=$_G_save_IFS
+ test -z "$_G_dir" && _G_dir=.
+ for _G_prog_name in $_G_progs_list; do
+ for _exeext in '' .EXE; do
+ _G_path_prog=$_G_dir/$_G_prog_name$_exeext
+ func_executable_p "$_G_path_prog" || continue
+ case `"$_G_path_prog" --version 2>&1` in
+ *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
+ *) $_G_check_func $_G_path_prog
+ func_path_progs_result=$func_check_prog_result
+ ;;
+ esac
+ $_G_path_prog_found && break 3
+ done
+ done
+ done
+ IFS=$_G_save_IFS
+ test -z "$func_path_progs_result" && {
+ echo "no acceptable sed could be found in \$PATH" >&2
+ exit 1
+ }
+}
+
+
+# We want to be able to use the functions in this file before configure
+# has figured out where the best binaries are kept, which means we have
+# to search for them ourselves - except when the results are already set
+# where we skip the searches.
+
+# Unless the user overrides by setting SED, search the path for either GNU
+# sed, or the sed that truncates its output the least.
+test -z "$SED" && {
+ _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for _G_i in 1 2 3 4 5 6 7; do
+ _G_sed_script=$_G_sed_script$nl$_G_sed_script
+ done
+ echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
+ _G_sed_script=
+
+ func_check_prog_sed ()
+ {
+ _G_path_prog=$1
+
+ _G_count=0
+ printf 0123456789 >conftest.in
+ while :
+ do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo '' >> conftest.nl
+ "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
+ diff conftest.out conftest.nl >/dev/null 2>&1 || break
+ _G_count=`expr $_G_count + 1`
+ if test "$_G_count" -gt "$_G_path_prog_max"; then
+ # Best one so far, save it but keep looking for a better one
+ func_check_prog_result=$_G_path_prog
+ _G_path_prog_max=$_G_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test 10 -lt "$_G_count" && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out
+ }
+
+ func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
+ rm -f conftest.sed
+ SED=$func_path_progs_result
+}
+
+
+# Unless the user overrides by setting GREP, search the path for either GNU
+# grep, or the grep that truncates its output the least.
+test -z "$GREP" && {
+ func_check_prog_grep ()
+ {
+ _G_path_prog=$1
+
+ _G_count=0
+ _G_path_prog_max=0
+ printf 0123456789 >conftest.in
+ while :
+ do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo 'GREP' >> conftest.nl
+ "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
+ diff conftest.out conftest.nl >/dev/null 2>&1 || break
+ _G_count=`expr $_G_count + 1`
+ if test "$_G_count" -gt "$_G_path_prog_max"; then
+ # Best one so far, save it but keep looking for a better one
+ func_check_prog_result=$_G_path_prog
+ _G_path_prog_max=$_G_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test 10 -lt "$_G_count" && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out
+ }
+
+ func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
+ GREP=$func_path_progs_result
+}
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# All uppercase variable names are used for environment variables. These
+# variables can be overridden by the user before calling a script that
+# uses them if a suitable command of that name is not already available
+# in the command search PATH.
+
+: ${CP="cp -f"}
+: ${ECHO="printf %s\n"}
+: ${EGREP="$GREP -E"}
+: ${FGREP="$GREP -F"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+
+
+## -------------------- ##
+## Useful sed snippets. ##
+## -------------------- ##
+
+sed_dirname='s|/[^/]*$||'
+sed_basename='s|^.*/||'
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
+
+# Same as above, but do not quote variable references.
+sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
+
+# Sed substitution that converts a w32 file name or path
+# that contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-'\' parameter expansions in output of sed_double_quote_subst that
+# were '\'-ed in input to the same. If an odd number of '\' preceded a
+# '$' in input to sed_double_quote_subst, that '$' was protected from
+# expansion. Since each input '\' is now two '\'s, look for any number
+# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'.
+_G_bs='\\'
+_G_bs2='\\\\'
+_G_bs4='\\\\\\\\'
+_G_dollar='\$'
+sed_double_backslash="\
+ s/$_G_bs4/&\\
+/g
+ s/^$_G_bs2$_G_dollar/$_G_bs&/
+ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
+ s/\n//g"
+
+
+## ----------------- ##
+## Global variables. ##
+## ----------------- ##
+
+# Except for the global variables explicitly listed below, the following
+# functions in the '^func_' namespace, and the '^require_' namespace
+# variables initialised in the 'Resource management' section, sourcing
+# this file will not pollute your global namespace with anything
+# else. There's no portable way to scope variables in Bourne shell
+# though, so actually running these functions will sometimes place
+# results into a variable named after the function, and often use
+# temporary variables in the '^_G_' namespace. If you are careful to
+# avoid using those namespaces casually in your sourcing script, things
+# should continue to work as you expect. And, of course, you can freely
+# overwrite any of the functions or variables defined here before
+# calling anything to customize them.
+
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+# Allow overriding, eg assuming that you follow the convention of
+# putting '$debug_cmd' at the start of all your functions, you can get
+# bash to show function call trace with:
+#
+# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+debug_cmd=${debug_cmd-":"}
+exit_cmd=:
+
+# By convention, finish your script with:
+#
+# exit $exit_status
+#
+# so that you can set exit_status to non-zero if you want to indicate
+# something went wrong during execution without actually bailing out at
+# the point of failure.
+exit_status=$EXIT_SUCCESS
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath=$0
+
+# The name of this program.
+progname=`$ECHO "$progpath" |$SED "$sed_basename"`
+
+# Make sure we have an absolute progpath for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
+ progdir=`cd "$progdir" && pwd`
+ progpath=$progdir/$progname
+ ;;
+ *)
+ _G_IFS=$IFS
+ IFS=${PATH_SEPARATOR-:}
+ for progdir in $PATH; do
+ IFS=$_G_IFS
+ test -x "$progdir/$progname" && break
+ done
+ IFS=$_G_IFS
+ test -n "$progdir" || progdir=`pwd`
+ progpath=$progdir/$progname
+ ;;
+esac
+
+
+## ----------------- ##
+## Standard options. ##
+## ----------------- ##
+
+# The following options affect the operation of the functions defined
+# below, and should be set appropriately depending on run-time para-
+# meters passed on the command line.
+
+opt_dry_run=false
+opt_quiet=false
+opt_verbose=false
+
+# Categories 'all' and 'none' are always available. Append any others
+# you will pass as the first argument to func_warning from your own
+# code.
+warning_categories=
+
+# By default, display warnings according to 'opt_warning_types'. Set
+# 'warning_func' to ':' to elide all warnings, or func_fatal_error to
+# treat the next displayed warning as a fatal error.
+warning_func=func_warn_and_continue
+
+# Set to 'all' to display all warnings, 'none' to suppress all
+# warnings, or a space delimited list of some subset of
+# 'warning_categories' to display only the listed warnings.
+opt_warning_types=all
+
+
+## -------------------- ##
+## Resource management. ##
+## -------------------- ##
+
+# This section contains definitions for functions that each ensure a
+# particular resource (a file, or a non-empty configuration variable for
+# example) is available, and if appropriate to extract default values
+# from pertinent package files. Call them using their associated
+# 'require_*' variable to ensure that they are executed, at most, once.
+#
+# It's entirely deliberate that calling these functions can set
+# variables that don't obey the namespace limitations obeyed by the rest
+# of this file, in order that that they be as useful as possible to
+# callers.
+
+
+# require_term_colors
+# -------------------
+# Allow display of bold text on terminals that support it.
+require_term_colors=func_require_term_colors
+func_require_term_colors ()
+{
+ $debug_cmd
+
+ test -t 1 && {
+ # COLORTERM and USE_ANSI_COLORS environment variables take
+ # precedence, because most terminfo databases neglect to describe
+ # whether color sequences are supported.
+ test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
+
+ if test 1 = "$USE_ANSI_COLORS"; then
+ # Standard ANSI escape sequences
+ tc_reset=''
+ tc_bold=''; tc_standout=''
+ tc_red=''; tc_green=''
+ tc_blue=''; tc_cyan=''
+ else
+ # Otherwise trust the terminfo database after all.
+ test -n "`tput sgr0 2>/dev/null`" && {
+ tc_reset=`tput sgr0`
+ test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
+ tc_standout=$tc_bold
+ test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
+ test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
+ test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
+ test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
+ test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
+ }
+ fi
+ }
+
+ require_term_colors=:
+}
+
+
+## ----------------- ##
+## Function library. ##
+## ----------------- ##
+
+# This section contains a variety of useful functions to call in your
+# scripts. Take note of the portable wrappers for features provided by
+# some modern shells, which will fall back to slower equivalents on
+# less featureful shells.
+
+
+# func_append VAR VALUE
+# ---------------------
+# Append VALUE onto the existing contents of VAR.
+
+ # We should try to minimise forks, especially on Windows where they are
+ # unreasonably slow, so skip the feature probes when bash or zsh are
+ # being used:
+ if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
+ : ${_G_HAVE_ARITH_OP="yes"}
+ : ${_G_HAVE_XSI_OPS="yes"}
+ # The += operator was introduced in bash 3.1
+ case $BASH_VERSION in
+ [12].* | 3.0 | 3.0*) ;;
+ *)
+ : ${_G_HAVE_PLUSEQ_OP="yes"}
+ ;;
+ esac
+ fi
+
+ # _G_HAVE_PLUSEQ_OP
+ # Can be empty, in which case the shell is probed, "yes" if += is
+ # useable or anything else if it does not work.
+ test -z "$_G_HAVE_PLUSEQ_OP" \
+ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
+ && _G_HAVE_PLUSEQ_OP=yes
+
+if test yes = "$_G_HAVE_PLUSEQ_OP"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_append ()
+ {
+ $debug_cmd
+
+ eval "$1+=\$2"
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_append ()
+ {
+ $debug_cmd
+
+ eval "$1=\$$1\$2"
+ }
+fi
+
+
+# func_append_quoted VAR VALUE
+# ----------------------------
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+if test yes = "$_G_HAVE_PLUSEQ_OP"; then
+ eval 'func_append_quoted ()
+ {
+ $debug_cmd
+
+ func_quote_for_eval "$2"
+ eval "$1+=\\ \$func_quote_for_eval_result"
+ }'
+else
+ func_append_quoted ()
+ {
+ $debug_cmd
+
+ func_quote_for_eval "$2"
+ eval "$1=\$$1\\ \$func_quote_for_eval_result"
+ }
+fi
+
+
+# func_append_uniq VAR VALUE
+# --------------------------
+# Append unique VALUE onto the existing contents of VAR, assuming
+# entries are delimited by the first character of VALUE. For example:
+#
+# func_append_uniq options " --another-option option-argument"
+#
+# will only append to $options if " --another-option option-argument "
+# is not already present somewhere in $options already (note spaces at
+# each end implied by leading space in second argument).
+func_append_uniq ()
+{
+ $debug_cmd
+
+ eval _G_current_value='`$ECHO $'$1'`'
+ _G_delim=`expr "$2" : '\(.\)'`
+
+ case $_G_delim$_G_current_value$_G_delim in
+ *"$2$_G_delim"*) ;;
+ *) func_append "$@" ;;
+ esac
+}
+
+
+# func_arith TERM...
+# ------------------
+# Set func_arith_result to the result of evaluating TERMs.
+ test -z "$_G_HAVE_ARITH_OP" \
+ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
+ && _G_HAVE_ARITH_OP=yes
+
+if test yes = "$_G_HAVE_ARITH_OP"; then
+ eval 'func_arith ()
+ {
+ $debug_cmd
+
+ func_arith_result=$(( $* ))
+ }'
+else
+ func_arith ()
+ {
+ $debug_cmd
+
+ func_arith_result=`expr "$@"`
+ }
+fi
+
+
+# func_basename FILE
+# ------------------
+# Set func_basename_result to FILE with everything up to and including
+# the last / stripped.
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ # If this shell supports suffix pattern removal, then use it to avoid
+ # forking. Hide the definitions single quotes in case the shell chokes
+ # on unsupported syntax...
+ _b='func_basename_result=${1##*/}'
+ _d='case $1 in
+ */*) func_dirname_result=${1%/*}$2 ;;
+ * ) func_dirname_result=$3 ;;
+ esac'
+
+else
+ # ...otherwise fall back to using sed.
+ _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
+ _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"`
+ if test "X$func_dirname_result" = "X$1"; then
+ func_dirname_result=$3
+ else
+ func_append func_dirname_result "$2"
+ fi'
+fi
+
+eval 'func_basename ()
+{
+ $debug_cmd
+
+ '"$_b"'
+}'
+
+
+# func_dirname FILE APPEND NONDIR_REPLACEMENT
+# -------------------------------------------
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+eval 'func_dirname ()
+{
+ $debug_cmd
+
+ '"$_d"'
+}'
+
+
+# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
+# --------------------------------------------------------
+# Perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# For efficiency, we do not delegate to the functions above but instead
+# duplicate the functionality here.
+eval 'func_dirname_and_basename ()
+{
+ $debug_cmd
+
+ '"$_b"'
+ '"$_d"'
+}'
+
+
+# func_echo ARG...
+# ----------------
+# Echo program name prefixed message.
+func_echo ()
+{
+ $debug_cmd
+
+ _G_message=$*
+
+ func_echo_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_IFS
+ $ECHO "$progname: $_G_line"
+ done
+ IFS=$func_echo_IFS
+}
+
+
+# func_echo_all ARG...
+# --------------------
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+
+# func_echo_infix_1 INFIX ARG...
+# ------------------------------
+# Echo program name, followed by INFIX on the first line, with any
+# additional lines not showing INFIX.
+func_echo_infix_1 ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ _G_infix=$1; shift
+ _G_indent=$_G_infix
+ _G_prefix="$progname: $_G_infix: "
+ _G_message=$*
+
+ # Strip color escape sequences before counting printable length
+ for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
+ do
+ test -n "$_G_tc" && {
+ _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
+ _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
+ }
+ done
+ _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes
+
+ func_echo_infix_1_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_infix_1_IFS
+ $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
+ _G_prefix=$_G_indent
+ done
+ IFS=$func_echo_infix_1_IFS
+}
+
+
+# func_error ARG...
+# -----------------
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2
+}
+
+
+# func_fatal_error ARG...
+# -----------------------
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ $debug_cmd
+
+ func_error "$*"
+ exit $EXIT_FAILURE
+}
+
+
+# func_grep EXPRESSION FILENAME
+# -----------------------------
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $debug_cmd
+
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_len STRING
+# ---------------
+# Set func_len_result to the length of STRING. STRING may not
+# start with a hyphen.
+ test -z "$_G_HAVE_XSI_OPS" \
+ && (eval 'x=a/b/c;
+ test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+ && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_len ()
+ {
+ $debug_cmd
+
+ func_len_result=${#1}
+ }'
+else
+ func_len ()
+ {
+ $debug_cmd
+
+ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+ }
+fi
+
+
+# func_mkdir_p DIRECTORY-PATH
+# ---------------------------
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ $debug_cmd
+
+ _G_directory_path=$1
+ _G_dir_list=
+
+ if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
+
+ # Protect directory names starting with '-'
+ case $_G_directory_path in
+ -*) _G_directory_path=./$_G_directory_path ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$_G_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ _G_dir_list=$_G_directory_path:$_G_dir_list
+
+ # If the last portion added has no slash in it, the list is done
+ case $_G_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
+ done
+ _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
+
+ func_mkdir_p_IFS=$IFS; IFS=:
+ for _G_dir in $_G_dir_list; do
+ IFS=$func_mkdir_p_IFS
+ # mkdir can fail with a 'File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$_G_dir" 2>/dev/null || :
+ done
+ IFS=$func_mkdir_p_IFS
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$_G_directory_path" || \
+ func_fatal_error "Failed to create '$1'"
+ fi
+}
+
+
+# func_mktempdir [BASENAME]
+# -------------------------
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, BASENAME is the basename for that directory.
+func_mktempdir ()
+{
+ $debug_cmd
+
+ _G_template=${TMPDIR-/tmp}/${1-$progname}
+
+ if test : = "$opt_dry_run"; then
+ # Return a directory name, but don't create it in dry-run mode
+ _G_tmpdir=$_G_template-$$
+ else
+
+ # If mktemp works, use that first and foremost
+ _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$_G_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ _G_tmpdir=$_G_template-${RANDOM-0}$$
+
+ func_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$_G_tmpdir"
+ umask $func_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$_G_tmpdir" || \
+ func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
+ fi
+
+ $ECHO "$_G_tmpdir"
+}
+
+
+# func_normal_abspath PATH
+# ------------------------
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+func_normal_abspath ()
+{
+ $debug_cmd
+
+ # These SED scripts presuppose an absolute path with a trailing slash.
+ _G_pathcar='s|^/\([^/]*\).*$|\1|'
+ _G_pathcdr='s|^/[^/]*||'
+ _G_removedotparts=':dotsl
+ s|/\./|/|g
+ t dotsl
+ s|/\.$|/|'
+ _G_collapseslashes='s|/\{1,\}|/|g'
+ _G_finalslash='s|/*$|/|'
+
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test / = "$func_normal_abspath_tpath"; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result"; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+
+# func_notquiet ARG...
+# --------------------
+# Echo program name prefixed message only when not in quiet mode.
+func_notquiet ()
+{
+ $debug_cmd
+
+ $opt_quiet || func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+
+# func_relative_path SRCDIR DSTDIR
+# --------------------------------
+# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
+func_relative_path ()
+{
+ $debug_cmd
+
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=$func_dirname_result
+ if test -z "$func_relative_path_tlibdir"; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
+
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test -n "$func_stripname_result"; then
+ func_append func_relative_path_result "/$func_stripname_result"
+ fi
+
+ # Normalisation. If bindir is libdir, return '.' else relative path.
+ if test -n "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ fi
+
+ test -n "$func_relative_path_result" || func_relative_path_result=.
+
+ :
+}
+
+
+# func_quote_for_eval ARG...
+# --------------------------
+# Aesthetically quote ARGs to be evaled later.
+# This function returns two values:
+# i) func_quote_for_eval_result
+# double-quoted, suitable for a subsequent eval
+# ii) func_quote_for_eval_unquoted_result
+# has all characters that are still active within double
+# quotes backslashified.
+func_quote_for_eval ()
+{
+ $debug_cmd
+
+ func_quote_for_eval_unquoted_result=
+ func_quote_for_eval_result=
+ while test 0 -lt $#; do
+ case $1 in
+ *[\\\`\"\$]*)
+ _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
+ *)
+ _G_unquoted_arg=$1 ;;
+ esac
+ if test -n "$func_quote_for_eval_unquoted_result"; then
+ func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
+ else
+ func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+ fi
+
+ case $_G_unquoted_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and variable expansion
+ # for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_quoted_arg=\"$_G_unquoted_arg\"
+ ;;
+ *)
+ _G_quoted_arg=$_G_unquoted_arg
+ ;;
+ esac
+
+ if test -n "$func_quote_for_eval_result"; then
+ func_append func_quote_for_eval_result " $_G_quoted_arg"
+ else
+ func_append func_quote_for_eval_result "$_G_quoted_arg"
+ fi
+ shift
+ done
+}
+
+
+# func_quote_for_expand ARG
+# -------------------------
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ $debug_cmd
+
+ case $1 in
+ *[\\\`\"]*)
+ _G_arg=`$ECHO "$1" | $SED \
+ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ _G_arg=$1 ;;
+ esac
+
+ case $_G_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_arg=\"$_G_arg\"
+ ;;
+ esac
+
+ func_quote_for_expand_result=$_G_arg
+}
+
+
+# func_stripname PREFIX SUFFIX NAME
+# ---------------------------------
+# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_stripname ()
+ {
+ $debug_cmd
+
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary variable first.
+ func_stripname_result=$3
+ func_stripname_result=${func_stripname_result#"$1"}
+ func_stripname_result=${func_stripname_result%"$2"}
+ }'
+else
+ func_stripname ()
+ {
+ $debug_cmd
+
+ case $2 in
+ .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
+ *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
+ esac
+ }
+fi
+
+
+# func_show_eval CMD [FAIL_EXP]
+# -----------------------------
+# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ $debug_cmd
+
+ _G_cmd=$1
+ _G_fail_exp=${2-':'}
+
+ func_quote_for_expand "$_G_cmd"
+ eval "func_notquiet $func_quote_for_expand_result"
+
+ $opt_dry_run || {
+ eval "$_G_cmd"
+ _G_status=$?
+ if test 0 -ne "$_G_status"; then
+ eval "(exit $_G_status); $_G_fail_exp"
+ fi
+ }
+}
+
+
+# func_show_eval_locale CMD [FAIL_EXP]
+# ------------------------------------
+# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ $debug_cmd
+
+ _G_cmd=$1
+ _G_fail_exp=${2-':'}
+
+ $opt_quiet || {
+ func_quote_for_expand "$_G_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ $opt_dry_run || {
+ eval "$_G_user_locale
+ $_G_cmd"
+ _G_status=$?
+ eval "$_G_safe_locale"
+ if test 0 -ne "$_G_status"; then
+ eval "(exit $_G_status); $_G_fail_exp"
+ fi
+ }
+}
+
+
+# func_tr_sh
+# ----------
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ $debug_cmd
+
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
+
+
+# func_verbose ARG...
+# -------------------
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $debug_cmd
+
+ $opt_verbose && func_echo "$*"
+
+ :
+}
+
+
+# func_warn_and_continue ARG...
+# -----------------------------
+# Echo program name prefixed warning message to standard error.
+func_warn_and_continue ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
+}
+
+
+# func_warning CATEGORY ARG...
+# ----------------------------
+# Echo program name prefixed warning message to standard error. Warning
+# messages can be filtered according to CATEGORY, where this function
+# elides messages where CATEGORY is not listed in the global variable
+# 'opt_warning_types'.
+func_warning ()
+{
+ $debug_cmd
+
+ # CATEGORY must be in the warning_categories list!
+ case " $warning_categories " in
+ *" $1 "*) ;;
+ *) func_internal_error "invalid warning category '$1'" ;;
+ esac
+
+ _G_category=$1
+ shift
+
+ case " $opt_warning_types " in
+ *" $_G_category "*) $warning_func ${1+"$@"} ;;
+ esac
+}
+
+
+# func_sort_ver VER1 VER2
+# -----------------------
+# 'sort -V' is not generally available.
+# Note this deviates from the version comparison in automake
+# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
+# but this should suffice as we won't be specifying old
+# version formats or redundant trailing .0 in bootstrap.conf.
+# If we did want full compatibility then we should probably
+# use m4_version_compare from autoconf.
+func_sort_ver ()
+{
+ $debug_cmd
+
+ printf '%s\n%s\n' "$1" "$2" \
+ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
+}
+
+# func_lt_ver PREV CURR
+# ---------------------
+# Return true if PREV and CURR are in the correct order according to
+# func_sort_ver, otherwise false. Use it like this:
+#
+# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
+func_lt_ver ()
+{
+ $debug_cmd
+
+ test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+#! /bin/sh
+
+# Set a version string for this script.
+scriptversion=2014-01-07.03; # UTC
+
+# A portable, pluggable option parser for Bourne shell.
+# Written by Gary V. Vaughan, 2010
+
+# Copyright (C) 2010-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# This file is a library for parsing options in your shell scripts along
+# with assorted other useful supporting features that you can make use
+# of too.
+#
+# For the simplest scripts you might need only:
+#
+# #!/bin/sh
+# . relative/path/to/funclib.sh
+# . relative/path/to/options-parser
+# scriptversion=1.0
+# func_options ${1+"$@"}
+# eval set dummy "$func_options_result"; shift
+# ...rest of your script...
+#
+# In order for the '--version' option to work, you will need to have a
+# suitably formatted comment like the one at the top of this file
+# starting with '# Written by ' and ending with '# warranty; '.
+#
+# For '-h' and '--help' to work, you will also need a one line
+# description of your script's purpose in a comment directly above the
+# '# Written by ' line, like the one at the top of this file.
+#
+# The default options also support '--debug', which will turn on shell
+# execution tracing (see the comment above debug_cmd below for another
+# use), and '--verbose' and the func_verbose function to allow your script
+# to display verbose messages only when your user has specified
+# '--verbose'.
+#
+# After sourcing this file, you can plug processing for additional
+# options by amending the variables from the 'Configuration' section
+# below, and following the instructions in the 'Option parsing'
+# section further down.
+
+## -------------- ##
+## Configuration. ##
+## -------------- ##
+
+# You should override these variables in your script after sourcing this
+# file so that they reflect the customisations you have added to the
+# option parser.
+
+# The usage line for option parsing errors and the start of '-h' and
+# '--help' output messages. You can embed shell variables for delayed
+# expansion at the time the message is displayed, but you will need to
+# quote other shell meta-characters carefully to prevent them being
+# expanded when the contents are evaled.
+usage='$progpath [OPTION]...'
+
+# Short help message in response to '-h' and '--help'. Add to this or
+# override it after sourcing this library to reflect the full set of
+# options your script accepts.
+usage_message="\
+ --debug enable verbose shell tracing
+ -W, --warnings=CATEGORY
+ report the warnings falling in CATEGORY [all]
+ -v, --verbose verbosely report processing
+ --version print version information and exit
+ -h, --help print short or long help message and exit
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+long_help_message="
+Warning categories include:
+ 'all' show all warnings
+ 'none' turn off all the warnings
+ 'error' warnings are treated as fatal errors"
+
+# Help message printed before fatal option parsing errors.
+fatal_help="Try '\$progname --help' for more information."
+
+
+
+## ------------------------- ##
+## Hook function management. ##
+## ------------------------- ##
+
+# This section contains functions for adding, removing, and running hooks
+# to the main code. A hook is just a named list of of function, that can
+# be run in order later on.
+
+# func_hookable FUNC_NAME
+# -----------------------
+# Declare that FUNC_NAME will run hooks added with
+# 'func_add_hook FUNC_NAME ...'.
+func_hookable ()
+{
+ $debug_cmd
+
+ func_append hookable_fns " $1"
+}
+
+
+# func_add_hook FUNC_NAME HOOK_FUNC
+# ---------------------------------
+# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must
+# first have been declared "hookable" by a call to 'func_hookable'.
+func_add_hook ()
+{
+ $debug_cmd
+
+ case " $hookable_fns " in
+ *" $1 "*) ;;
+ *) func_fatal_error "'$1' does not accept hook functions." ;;
+ esac
+
+ eval func_append ${1}_hooks '" $2"'
+}
+
+
+# func_remove_hook FUNC_NAME HOOK_FUNC
+# ------------------------------------
+# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
+func_remove_hook ()
+{
+ $debug_cmd
+
+ eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
+}
+
+
+# func_run_hooks FUNC_NAME [ARG]...
+# ---------------------------------
+# Run all hook functions registered to FUNC_NAME.
+# It is assumed that the list of hook functions contains nothing more
+# than a whitespace-delimited list of legal shell function names, and
+# no effort is wasted trying to catch shell meta-characters or preserve
+# whitespace.
+func_run_hooks ()
+{
+ $debug_cmd
+
+ case " $hookable_fns " in
+ *" $1 "*) ;;
+ *) func_fatal_error "'$1' does not support hook funcions.n" ;;
+ esac
+
+ eval _G_hook_fns=\$$1_hooks; shift
+
+ for _G_hook in $_G_hook_fns; do
+ eval $_G_hook '"$@"'
+
+ # store returned options list back into positional
+ # parameters for next 'cmd' execution.
+ eval _G_hook_result=\$${_G_hook}_result
+ eval set dummy "$_G_hook_result"; shift
+ done
+
+ func_quote_for_eval ${1+"$@"}
+ func_run_hooks_result=$func_quote_for_eval_result
+}
+
+
+
+## --------------- ##
+## Option parsing. ##
+## --------------- ##
+
+# In order to add your own option parsing hooks, you must accept the
+# full positional parameter list in your hook function, remove any
+# options that you action, and then pass back the remaining unprocessed
+# options in '<hooked_function_name>_result', escaped suitably for
+# 'eval'. Like this:
+#
+# my_options_prep ()
+# {
+# $debug_cmd
+#
+# # Extend the existing usage message.
+# usage_message=$usage_message'
+# -s, --silent don'\''t print informational messages
+# '
+#
+# func_quote_for_eval ${1+"$@"}
+# my_options_prep_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_options_prep my_options_prep
+#
+#
+# my_silent_option ()
+# {
+# $debug_cmd
+#
+# # Note that for efficiency, we parse as many options as we can
+# # recognise in a loop before passing the remainder back to the
+# # caller on the first unrecognised argument we encounter.
+# while test $# -gt 0; do
+# opt=$1; shift
+# case $opt in
+# --silent|-s) opt_silent=: ;;
+# # Separate non-argument short options:
+# -s*) func_split_short_opt "$_G_opt"
+# set dummy "$func_split_short_opt_name" \
+# "-$func_split_short_opt_arg" ${1+"$@"}
+# shift
+# ;;
+# *) set dummy "$_G_opt" "$*"; shift; break ;;
+# esac
+# done
+#
+# func_quote_for_eval ${1+"$@"}
+# my_silent_option_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_parse_options my_silent_option
+#
+#
+# my_option_validation ()
+# {
+# $debug_cmd
+#
+# $opt_silent && $opt_verbose && func_fatal_help "\
+# '--silent' and '--verbose' options are mutually exclusive."
+#
+# func_quote_for_eval ${1+"$@"}
+# my_option_validation_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_validate_options my_option_validation
+#
+# You'll alse need to manually amend $usage_message to reflect the extra
+# options you parse. It's preferable to append if you can, so that
+# multiple option parsing hooks can be added safely.
+
+
+# func_options [ARG]...
+# ---------------------
+# All the functions called inside func_options are hookable. See the
+# individual implementations for details.
+func_hookable func_options
+func_options ()
+{
+ $debug_cmd
+
+ func_options_prep ${1+"$@"}
+ eval func_parse_options \
+ ${func_options_prep_result+"$func_options_prep_result"}
+ eval func_validate_options \
+ ${func_parse_options_result+"$func_parse_options_result"}
+
+ eval func_run_hooks func_options \
+ ${func_validate_options_result+"$func_validate_options_result"}
+
+ # save modified positional parameters for caller
+ func_options_result=$func_run_hooks_result
+}
+
+
+# func_options_prep [ARG]...
+# --------------------------
+# All initialisations required before starting the option parse loop.
+# Note that when calling hook functions, we pass through the list of
+# positional parameters. If a hook function modifies that list, and
+# needs to propogate that back to rest of this script, then the complete
+# modified list must be put in 'func_run_hooks_result' before
+# returning.
+func_hookable func_options_prep
+func_options_prep ()
+{
+ $debug_cmd
+
+ # Option defaults:
+ opt_verbose=false
+ opt_warning_types=
+
+ func_run_hooks func_options_prep ${1+"$@"}
+
+ # save modified positional parameters for caller
+ func_options_prep_result=$func_run_hooks_result
+}
+
+
+# func_parse_options [ARG]...
+# ---------------------------
+# The main option parsing loop.
+func_hookable func_parse_options
+func_parse_options ()
+{
+ $debug_cmd
+
+ func_parse_options_result=
+
+ # this just eases exit handling
+ while test $# -gt 0; do
+ # Defer to hook functions for initial option parsing, so they
+ # get priority in the event of reusing an option name.
+ func_run_hooks func_parse_options ${1+"$@"}
+
+ # Adjust func_parse_options positional parameters to match
+ eval set dummy "$func_run_hooks_result"; shift
+
+ # Break out of the loop if we already parsed every option.
+ test $# -gt 0 || break
+
+ _G_opt=$1
+ shift
+ case $_G_opt in
+ --debug|-x) debug_cmd='set -x'
+ func_echo "enabling shell trace mode"
+ $debug_cmd
+ ;;
+
+ --no-warnings|--no-warning|--no-warn)
+ set dummy --warnings none ${1+"$@"}
+ shift
+ ;;
+
+ --warnings|--warning|-W)
+ test $# = 0 && func_missing_arg $_G_opt && break
+ case " $warning_categories $1" in
+ *" $1 "*)
+ # trailing space prevents matching last $1 above
+ func_append_uniq opt_warning_types " $1"
+ ;;
+ *all)
+ opt_warning_types=$warning_categories
+ ;;
+ *none)
+ opt_warning_types=none
+ warning_func=:
+ ;;
+ *error)
+ opt_warning_types=$warning_categories
+ warning_func=func_fatal_error
+ ;;
+ *)
+ func_fatal_error \
+ "unsupported warning category: '$1'"
+ ;;
+ esac
+ shift
+ ;;
+
+ --verbose|-v) opt_verbose=: ;;
+ --version) func_version ;;
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+
+ # Separate optargs to long options (plugins may need this):
+ --*=*) func_split_equals "$_G_opt"
+ set dummy "$func_split_equals_lhs" \
+ "$func_split_equals_rhs" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate optargs to short options:
+ -W*)
+ func_split_short_opt "$_G_opt"
+ set dummy "$func_split_short_opt_name" \
+ "$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-v*|-x*)
+ func_split_short_opt "$_G_opt"
+ set dummy "$func_split_short_opt_name" \
+ "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognised option: '$_G_opt'" ;;
+ *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+ # save modified positional parameters for caller
+ func_quote_for_eval ${1+"$@"}
+ func_parse_options_result=$func_quote_for_eval_result
+}
+
+
+# func_validate_options [ARG]...
+# ------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+func_hookable func_validate_options
+func_validate_options ()
+{
+ $debug_cmd
+
+ # Display all warnings if -W was not given.
+ test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
+
+ func_run_hooks func_validate_options ${1+"$@"}
+
+ # Bail if the options were screwed!
+ $exit_cmd $EXIT_FAILURE
+
+ # save modified positional parameters for caller
+ func_validate_options_result=$func_run_hooks_result
+}
+
+
+
+## ----------------- ##
+## Helper functions. ##
+## ----------------- ##
+
+# This section contains the helper functions used by the rest of the
+# hookable option parser framework in ascii-betical order.
+
+
+# func_fatal_help ARG...
+# ----------------------
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ $debug_cmd
+
+ eval \$ECHO \""Usage: $usage"\"
+ eval \$ECHO \""$fatal_help"\"
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+
+# func_help
+# ---------
+# Echo long help message to standard output and exit.
+func_help ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "$long_help_message"
+ exit 0
+}
+
+
+# func_missing_arg ARGNAME
+# ------------------------
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ $debug_cmd
+
+ func_error "Missing argument for '$1'."
+ exit_cmd=exit
+}
+
+
+# func_split_equals STRING
+# ------------------------
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
+# splitting STRING at the '=' sign.
+test -z "$_G_HAVE_XSI_OPS" \
+ && (eval 'x=a/b/c;
+ test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+ && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_split_equals ()
+ {
+ $debug_cmd
+
+ func_split_equals_lhs=${1%%=*}
+ func_split_equals_rhs=${1#*=}
+ test "x$func_split_equals_lhs" = "x$1" \
+ && func_split_equals_rhs=
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_split_equals ()
+ {
+ $debug_cmd
+
+ func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
+ func_split_equals_rhs=
+ test "x$func_split_equals_lhs" = "x$1" \
+ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
+ }
+fi #func_split_equals
+
+
+# func_split_short_opt SHORTOPT
+# -----------------------------
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_split_short_opt ()
+ {
+ $debug_cmd
+
+ func_split_short_opt_arg=${1#??}
+ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_split_short_opt ()
+ {
+ $debug_cmd
+
+ func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
+ func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
+ }
+fi #func_split_short_opt
+
+
+# func_usage
+# ----------
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
+ exit 0
+}
+
+
+# func_usage_message
+# ------------------
+# Echo short help message to standard output.
+func_usage_message ()
+{
+ $debug_cmd
+
+ eval \$ECHO \""Usage: $usage"\"
+ echo
+ $SED -n 's|^# ||
+ /^Written by/{
+ x;p;x
+ }
+ h
+ /^Written by/q' < "$progpath"
+ echo
+ eval \$ECHO \""$usage_message"\"
+}
+
+
+# func_version
+# ------------
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $debug_cmd
+
+ printf '%s\n' "$progname $scriptversion"
+ $SED -n '
+ /(C)/!b go
+ :more
+ /\./!{
+ N
+ s|\n# | |
+ b more
+ }
+ :go
+ /^# Written by /,/# warranty; / {
+ s|^# ||
+ s|^# *$||
+ s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
+ p
+ }
+ /^# Written by / {
+ s|^# ||
+ p
+ }
+ /^warranty; /q' < "$progpath"
+
+ exit $?
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+
+# Set a version string.
+scriptversion='(GNU libtool) 2.4.6'
+
+
+# func_echo ARG...
+# ----------------
+# Libtool also displays the current mode in messages, so override
+# funclib.sh func_echo with this custom definition.
+func_echo ()
+{
+ $debug_cmd
+
+ _G_message=$*
+
+ func_echo_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_IFS
+ $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
+ done
+ IFS=$func_echo_IFS
+}
+
+
+# func_warning ARG...
+# -------------------
+# Libtool warnings are not categorized, so override funclib.sh
+# func_warning with this simpler definition.
+func_warning ()
+{
+ $debug_cmd
+
+ $warning_func ${1+"$@"}
+}
+
+
+## ---------------- ##
+## Options parsing. ##
+## ---------------- ##
+
+# Hook in the functions to make sure our own options are parsed during
+# the option parsing loop.
+
+usage='$progpath [OPTION]... [MODE-ARG]...'
+
+# Short help message in response to '-h'.
+usage_message="Options:
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+ -n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --mode=MODE use operation mode MODE
+ --no-warnings equivalent to '-Wnone'
+ --preserve-dup-deps don't remove duplicate dependency libraries
+ --quiet, --silent don't print informational messages
+ --tag=TAG use configuration variables from tag TAG
+ -v, --verbose print more informational messages than default
+ --version print version information
+ -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all]
+ -h, --help, --help-all print short, long, or detailed help message
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+func_help ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "$long_help_message
+
+MODE must be one of the following:
+
+ clean remove files from the build directory
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. When passed as first option,
+'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
+Try '$progname --help --mode=MODE' for a more detailed description of MODE.
+
+When reporting a bug, please describe a test case to reproduce it and
+include the following information:
+
+ host-triplet: $host
+ shell: $SHELL
+ compiler: $LTCC
+ compiler flags: $LTCFLAGS
+ linker: $LD (gnu? $with_gnu_ld)
+ version: $progname (GNU libtool) 2.4.6
+ automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
+ autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q`
+
+Report bugs to <bug-libtool@gnu.org>.
+GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>."
+ exit 0
+}
+
+
+# func_lo2o OBJECT-NAME
+# ---------------------
+# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
+# object suffix.
+
+lo2o=s/\\.lo\$/.$objext/
+o2lo=s/\\.$objext\$/.lo/
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_lo2o ()
+ {
+ case $1 in
+ *.lo) func_lo2o_result=${1%.lo}.$objext ;;
+ * ) func_lo2o_result=$1 ;;
+ esac
+ }'
+
+ # func_xform LIBOBJ-OR-SOURCE
+ # ---------------------------
+ # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
+ # suffix to a '.lo' libtool-object suffix.
+ eval 'func_xform ()
+ {
+ func_xform_result=${1%.*}.lo
+ }'
+else
+ # ...otherwise fall back to using sed.
+ func_lo2o ()
+ {
+ func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
+ }
+
+ func_xform ()
+ {
+ func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
+ }
+fi
+
+
+# func_fatal_configuration ARG...
+# -------------------------------
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func__fatal_error ${1+"$@"} \
+ "See the $PACKAGE documentation for more information." \
+ "Fatal configuration error."
+}
+
+
+# func_config
+# -----------
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+
+# func_features
+# -------------
+# Display the features supported by this script.
+func_features ()
+{
+ echo "host: $host"
+ if test yes = "$build_libtool_libs"; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test yes = "$build_old_libs"; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+
+ exit $?
+}
+
+
+# func_enable_tag TAGNAME
+# -----------------------
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname=$1
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf=/$re_begincf/,/$re_endcf/p
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+
+# func_check_version_match
+# ------------------------
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+# libtool_options_prep [ARG]...
+# -----------------------------
+# Preparation for options parsed by libtool.
+libtool_options_prep ()
+{
+ $debug_mode
+
+ # Option defaults:
+ opt_config=false
+ opt_dlopen=
+ opt_dry_run=false
+ opt_help=false
+ opt_mode=
+ opt_preserve_dup_deps=false
+ opt_quiet=false
+
+ nonopt=
+ preserve_args=
+
+ # Shorthand for --mode=foo, only valid as the first argument
+ case $1 in
+ clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+ compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+ execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+ finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+ link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+ uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+ esac
+
+ # Pass back the list of options.
+ func_quote_for_eval ${1+"$@"}
+ libtool_options_prep_result=$func_quote_for_eval_result
+}
+func_add_hook func_options_prep libtool_options_prep
+
+
+# libtool_parse_options [ARG]...
+# ---------------------------------
+# Provide handling for libtool specific options.
+libtool_parse_options ()
+{
+ $debug_cmd
+
+ # Perform our own loop to consume as many options as possible in
+ # each iteration.
+ while test $# -gt 0; do
+ _G_opt=$1
+ shift
+ case $_G_opt in
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+
+ --config) func_config ;;
+
+ --dlopen|-dlopen)
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$1"
+ shift
+ ;;
+
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=: ;;
+
+ --features) func_features ;;
+
+ --finish) set dummy --mode finish ${1+"$@"}; shift ;;
+
+ --help) opt_help=: ;;
+
+ --help-all) opt_help=': help-all' ;;
+
+ --mode) test $# = 0 && func_missing_arg $_G_opt && break
+ opt_mode=$1
+ case $1 in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $_G_opt"
+ exit_cmd=exit
+ break
+ ;;
+ esac
+ shift
+ ;;
+
+ --no-silent|--no-quiet)
+ opt_quiet=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --no-warnings|--no-warning|--no-warn)
+ opt_warning=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --no-verbose)
+ opt_verbose=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --silent|--quiet)
+ opt_quiet=:
+ opt_verbose=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --tag) test $# = 0 && func_missing_arg $_G_opt && break
+ opt_tag=$1
+ func_append preserve_args " $_G_opt $1"
+ func_enable_tag "$1"
+ shift
+ ;;
+
+ --verbose|-v) opt_quiet=false
+ opt_verbose=:
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ # An option not handled by this hook function:
+ *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+
+ # save modified positional parameters for caller
+ func_quote_for_eval ${1+"$@"}
+ libtool_parse_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_parse_options libtool_parse_options
+
+
+
+# libtool_validate_options [ARG]...
+# ---------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+libtool_validate_options ()
+{
+ # save first non-option argument
+ if test 0 -lt $#; then
+ nonopt=$1
+ shift
+ fi
+
+ # preserve --debug
+ test : = "$debug_cmd" || func_append preserve_args " --debug"
+
+ case $host in
+ # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
+ # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
+ *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ test yes != "$build_libtool_libs" \
+ && test yes != "$build_old_libs" \
+ && func_fatal_configuration "not configured to build any kind of library"
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
+ func_error "unrecognized option '-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help=$help
+ help="Try '$progname --help --mode=$opt_mode' for more information."
+ }
+
+ # Pass back the unparsed argument list
+ func_quote_for_eval ${1+"$@"}
+ libtool_validate_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_validate_options libtool_validate_options
+
+
+# Process options as early as possible so that --help and --version
+# can return quickly.
+func_options ${1+"$@"}
+eval set dummy "$func_options_result"; shift
+
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+magic='%%%MAGIC variable%%%'
+magic_exe='%%%MAGIC EXE variable%%%'
+
+# Global variables.
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# func_generated_by_libtool
+# True iff stdin has been generated by Libtool. This function is only
+# a basic sanity check; it will hardly flush out determined imposters.
+func_generated_by_libtool_p ()
+{
+ $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if 'file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case $lalib_p_line in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test yes = "$lalib_p"
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ test -f "$1" &&
+ $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $debug_cmd
+
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$sp$nl
+ eval cmd=\"$cmd\"
+ IFS=$save_ifs
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# 'FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $debug_cmd
+
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case $lt_sysroot:$1 in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result='='$func_stripname_result
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $debug_cmd
+
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case "$@ " in
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with '--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=$1
+ if test yes = "$build_libtool_libs"; then
+ write_lobj=\'$2\'
+ else
+ write_lobj=none
+ fi
+
+ if test yes = "$build_old_libs"; then
+ write_oldobj=\'$3\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "$write_libobj"
+ }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+ $debug_cmd
+
+ func_convert_core_file_wine_to_w32_result=$1
+ if test -n "$1"; then
+ # Unfortunately, winepath does not exit with a non-zero error code, so we
+ # are forced to check the contents of stdout. On the other hand, if the
+ # command is not found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both error code of
+ # zero AND non-empty stdout, which explains the odd construction:
+ func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $debug_cmd
+
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result"; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $debug_cmd
+
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $debug_cmd
+
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $debug_cmd
+
+ if test -z "$2" && test -n "$1"; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result=$1
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $debug_cmd
+
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " '$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result=$3
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $debug_cmd
+
+ case $4 in
+ $1 ) func_to_host_path_result=$3$func_to_host_path_result
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via '$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $debug_cmd
+
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $debug_cmd
+
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result=$1
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result=$func_convert_core_msys_to_w32_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result=$func_cygpath_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result=$func_cygpath_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via '$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $debug_cmd
+
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd=func_convert_path_$func_stripname_result
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $debug_cmd
+
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+ func_to_host_path_result=$1
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from ARG. MSYS
+ # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+ # and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result=$func_convert_core_msys_to_w32_result
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format. Requires a wine environment and
+# a working winepath. Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+ func_to_host_path_result=$func_cygpath_result
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set. Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+ func_to_host_path_result=$func_cygpath_result
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_dll_def_p FILE
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with _LT_DLL_DEF_P in libtool.m4
+func_dll_def_p ()
+{
+ $debug_cmd
+
+ func_dll_def_p_tmp=`$SED -n \
+ -e 's/^[ ]*//' \
+ -e '/^\(;.*\)*$/d' \
+ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \
+ -e q \
+ "$1"`
+ test DEF = "$func_dll_def_p_tmp"
+}
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $debug_cmd
+
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile=$nonopt # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg=$arg
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj=$arg
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify '-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ func_append pie_flag " $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ func_append later " $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs=$IFS; IFS=,
+ for arg in $args; do
+ IFS=$save_ifs
+ func_append_quoted lastarg "$arg"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ func_append base_compile " $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg=$srcfile
+ srcfile=$arg
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_append_quoted base_compile "$lastarg"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with '-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj=$func_basename_result
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from '$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test yes = "$build_libtool_libs" \
+ || func_fatal_configuration "cannot build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name '$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname=$func_basename_result
+ xdir=$func_dirname_result
+ lobj=$xdir$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test yes = "$build_old_libs"; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test no = "$compiler_c_o"; then
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
+ lockfile=$output_obj.lock
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test yes = "$need_locks"; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test warn = "$need_locks"; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ func_append removelist " $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ func_append removelist " $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test yes = "$build_libtool_libs"; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test no != "$pic_mode"; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ func_append command " -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test warn = "$need_locks" &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test yes = "$suppress_opt"; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test yes = "$build_old_libs"; then
+ if test yes != "$pic_mode"; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test yes = "$compiler_c_o"; then
+ func_append command " -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ func_append command "$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test warn = "$need_locks" &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test no != "$need_locks"; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+ test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $opt_mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to build PIC objects only
+ -prefer-non-pic try to build non-PIC objects only
+ -shared do not build a '.o' file suitable for static linking
+ -static only build a '.o' file suitable for static linking
+ -Wc,FLAG pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a 'standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix '.c' with the
+library object suffix, '.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to '-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the '--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the 'install' or 'cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -bindir BINDIR specify path to binaries directory (for systems where
+ libraries must be found in the PATH setting at runtime)
+ -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE use a list of object files found in FILE to specify objects
+ -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes)
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+ -Wc,FLAG
+ -Xcompiler FLAG pass linker-specific FLAG directly to the compiler
+ -Wl,FLAG
+ -Xlinker FLAG pass linker-specific FLAG directly to the linker
+ -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with '-') are ignored.
+
+Every other argument is treated as a filename. Files ending in '.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in '.la', then a libtool library is created,
+only library objects ('.lo' files) may be specified, and '-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
+using 'ar' and 'ranlib', or on Windows using 'lib'.
+
+If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode '$opt_mode'"
+ ;;
+ esac
+
+ echo
+ $ECHO "Try '$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+ if test : = "$opt_help"; then
+ func_mode_help
+ else
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ func_mode_help
+ done
+ } | $SED -n '1p; 2,$s/^Usage:/ or: /p'
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ echo
+ func_mode_help
+ done
+ } |
+ $SED '1d
+ /^When reporting/,/^Report/{
+ H
+ d
+ }
+ $x
+ /information about other modes/d
+ /more detailed .*MODE/d
+ s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+ fi
+ exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $debug_cmd
+
+ # The first argument is the command name.
+ cmd=$nonopt
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $opt_dlopen; do
+ test -f "$file" \
+ || func_fatal_help "'$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "'$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "'$file' was not linked with '-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+
+ if test -f "$dir/$objdir/$dlname"; then
+ func_append dir "/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+ ;;
+
+ *)
+ func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir=$absdir
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic=$magic
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -* | *.la | *.lo ) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file=$progdir/$program
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file=$progdir/$program
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_append_quoted args "$file"
+ done
+
+ if $opt_dry_run; then
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ else
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd=\$cmd$args
+ fi
+}
+
+test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $debug_cmd
+
+ libs=
+ libdirs=
+ admincmds=
+
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "'$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument '$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and '=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_quiet && exit $EXIT_SUCCESS
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the '-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the '$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the '$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the '$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
+ fi
+ echo
+
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
+ exit $EXIT_SUCCESS
+}
+
+test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $debug_cmd
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
+ # Allow the use of GNU shtool's install command.
+ case $nonopt in *shtool*) :;; *) false;; esac
+ then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ func_append install_prog "$func_quote_for_eval_result"
+ install_shared_prog=$install_prog
+ case " $install_prog " in
+ *[\\\ /]cp\ *) install_cp=: ;;
+ *) install_cp=false ;;
+ esac
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=false
+ stripme=
+ no_mode=:
+ for arg
+ do
+ arg2=
+ if test -n "$dest"; then
+ func_append files " $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=: ;;
+ -f)
+ if $install_cp; then :; else
+ prev=$arg
+ fi
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ if test X-m = "X$prev" && test -n "$install_override_mode"; then
+ arg2=$install_override_mode
+ no_mode=false
+ fi
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ func_append install_prog " $func_quote_for_eval_result"
+ if test -n "$arg2"; then
+ func_quote_for_eval "$arg2"
+ fi
+ func_append install_shared_prog " $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the '$prev' option requires an argument"
+
+ if test -n "$install_override_mode" && $no_mode; then
+ if $install_cp; then :; else
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
+ fi
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=:
+ if $isdir; then
+ destdir=$dest
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir=$func_dirname_result
+ destname=$func_basename_result
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "'$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "'$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic=$magic
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ func_append staticlibs " $file"
+ ;;
+
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "'$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append current_libdirs " $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append future_libdirs " $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir=$func_dirname_result
+ func_append dir "$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking '$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname=$1
+ shift
+
+ srcname=$realname
+ test -n "$relink_command" && srcname=${realname}T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme=$stripme
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=
+ ;;
+ esac
+ ;;
+ os2*)
+ case $realname in
+ *_dll.a)
+ tstripme=
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try 'ln -sf' first, because the 'ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib=$destdir/$realname
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name=$func_basename_result
+ instname=$dir/${name}i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile=$destdir/$destname
+ else
+ func_basename "$file"
+ destfile=$func_basename_result
+ destfile=$destdir/$destfile
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest=$destfile
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to '$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test yes = "$build_old_libs"; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile=$destdir/$destname
+ else
+ func_basename "$file"
+ destfile=$func_basename_result
+ destfile=$destdir/$destfile
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=.exe
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script '$wrapper'"
+
+ finalize=:
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "'$lib' has not been installed in '$libdir'"
+ finalize=false
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test no = "$fast_install" && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if $finalize; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file=$func_basename_result
+ outputname=$tmpdir/$file
+ # Replace the output file specification.
+ relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_quiet || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink '$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file=$outputname
+ else
+ func_warning "cannot relink '$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name=$func_basename_result
+
+ # Set up the ranlib parameters.
+ oldlib=$destdir/$name
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run '$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test install = "$opt_mode" && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $debug_cmd
+
+ my_outputname=$1
+ my_originator=$2
+ my_pic_p=${3-false}
+ my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms=${my_outputname}S.c
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist=$output_objdir/$my_outputname.nm
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test yes = "$dlself"; then
+ func_verbose "generating symbol list for '$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols=$output_objdir/$outputname.exp
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from '$dlprefile'"
+ func_basename "$dlprefile"
+ name=$func_basename_result
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname"; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename=$func_basename_result
+ else
+ # no lafile. user explicitly requested -dlpreopen <import library>.
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename"; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ func_show_eval '$RM "${nlist}I"'
+ if test -n "$global_symbol_to_import"; then
+ eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
+ fi
+
+ echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];\
+"
+
+ if test -s "$nlist"I; then
+ echo >> "$output_objdir/$my_dlsyms" "\
+static void lt_syminit(void)
+{
+ LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
+ for (; symbol->name; ++symbol)
+ {"
+ $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
+ echo >> "$output_objdir/$my_dlsyms" "\
+ }
+}"
+ fi
+ echo >> "$output_objdir/$my_dlsyms" "\
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{ {\"$my_originator\", (void *) 0},"
+
+ if test -s "$nlist"I; then
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {\"@INIT@\", (void *) &lt_syminit},"
+ fi
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ $my_pic_p && pic_flag_for_symtable=" $pic_flag"
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) func_append symtab_cflags " $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj=$output_objdir/${my_outputname}S.$objext
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for '$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $debug_cmd
+
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $debug_cmd
+
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+ $debug_cmd
+
+ win32_libid_type=unknown
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ case $nm_interface in
+ "MS dumpbin")
+ if func_cygming_ms_implib_p "$1" ||
+ func_cygming_gnu_implib_p "$1"
+ then
+ win32_nmres=import
+ else
+ win32_nmres=
+ fi
+ ;;
+ *)
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s|.*|import|
+ p
+ q
+ }
+ }'`
+ ;;
+ esac
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $debug_cmd
+
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $debug_cmd
+
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive that possess that section. Heuristic: eliminate
+ # all those that have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $debug_cmd
+
+ if func_cygming_gnu_implib_p "$1"; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1"; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=
+ fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $debug_cmd
+
+ f_ex_an_ar_dir=$1; shift
+ f_ex_an_ar_oldlib=$1
+ if test yes = "$lock_old_archive_extraction"; then
+ lockfile=$f_ex_an_ar_oldlib.lock
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ fi
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test yes = "$lock_old_archive_extraction"; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $debug_cmd
+
+ my_gentop=$1; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=
+ my_xlib=
+ my_xabs=
+ my_xdir=
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib=$func_basename_result
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir=$my_gentop/$my_xlib_u
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ func_basename "$darwin_archive"
+ darwin_base_archive=$func_basename_result
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches; do
+ func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
+ $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
+ cd "unfat-$$/$darwin_base_archive-$darwin_arch"
+ func_extract_an_archive "`pwd`" "$darwin_base_archive"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+ done
+
+ func_extract_archives_result=$my_oldobjs
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory where it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=${1-no}
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ file=\"\$0\""
+
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+ $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+ ECHO=\"$qECHO\"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ that is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options that match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=\$0
+ shift
+ for lt_opt
+ do
+ case \"\$lt_opt\" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+ test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+ lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+ cat \"\$lt_dump_D/\$lt_dump_F\"
+ exit 0
+ ;;
+ --lt-*)
+ \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n \"\$lt_option_debug\"; then
+ echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case \" \$* \" in
+ *\\ --lt-*)
+ for lt_wr_arg
+ do
+ case \$lt_wr_arg in
+ --lt-*) ;;
+ *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core \${1+\"\$@\"}
+}
+
+ # Parse options
+ func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test yes = "$fast_install"; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ \$ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ # Export our shlibpath_var if we have one.
+ if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+ func_exec_program \${1+\"\$@\"}
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+*/
+EOF
+ cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* declarations of non-ANSI functions */
+#if defined __MINGW32__
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined __CYGWIN__
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined other_platform || defined ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined _MSC_VER
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+# define S_IXUSR _S_IEXEC
+#elif defined __MINGW32__
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+#elif defined __CYGWIN__
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined other platforms ... */
+#endif
+
+#if defined PATH_MAX
+# define LT_PATHMAX PATH_MAX
+#elif defined MAXPATHLEN
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
+ defined __OS2__
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free (stale); stale = 0; } \
+} while (0)
+
+#if defined LT_DEBUGWRAPPER
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+ cat <<EOF
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
+# define externally_visible volatile
+#else
+# define externally_visible __attribute__((externally_visible)) volatile
+#endif
+externally_visible const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_path "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_path "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test yes = "$fast_install"; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ int rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ newargz = XMALLOC (char *, (size_t) argc + 1);
+
+ /* very simple arg parsing; don't want to rely on getopt
+ * also, copy all non cwrapper options to newargz, except
+ * argz[0], which is handled differently
+ */
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (STREQ (argv[i], dumpscript_opt))
+ {
+EOF
+ case $host in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ lt_dump_script (stdout);
+ return 0;
+ }
+ if (STREQ (argv[i], debug_opt))
+ {
+ lt_debug = 1;
+ continue;
+ }
+ if (STREQ (argv[i], ltwrapper_option_prefix))
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal (__FILE__, __LINE__,
+ "unrecognized %s option: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+EOF
+ cat <<EOF
+ /* The GNU banner must be the first non-error debug message */
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");
+EOF
+ cat <<"EOF"
+ lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (before symlink chase) at: %s\n",
+ tmp_pathspec);
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (after symlink chase) at: %s\n",
+ actual_cwrapper_path);
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) libtool target name: %s\n",
+ target_name);
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must
+ be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+ because on Windows, both *_VARNAMEs are PATH but uninstalled
+ libraries must come first. */
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+ lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+ nonnull (lt_argv_zero));
+ for (i = 0; i < newargc; i++)
+ {
+ lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+ i, nonnull (newargz[i]));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ newargz = prepare_spawn (newargz);
+ rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) failed to launch target \"%s\": %s\n",
+ lt_argv_zero, nonnull (strerror (errno)));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ size_t tmp_len;
+ char *concat_name;
+
+ lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+ nonempty (wrapper));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = (size_t) (q - p);
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ lt_debugprintf (__FILE__, __LINE__,
+ "checking path component for symlinks: %s\n",
+ tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "error accessing file \"%s\": %s",
+ tmp_pathspec, nonnull (strerror (errno)));
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (STREQ (str, pat))
+ *str = '\0';
+ }
+ return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ if (lt_debug)
+ {
+ (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+ int line, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+ va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+ return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_setenv) setting '%s' to '%s'\n",
+ nonnull (name), nonnull (value));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ size_t len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ size_t orig_value_len = strlen (orig_value);
+ size_t add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ size_t len = strlen (new_value);
+ while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[--len] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+EOF
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+ Note that spawn() does not by itself call the command interpreter
+ (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+ ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&v);
+ v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+ }) ? "cmd.exe" : "command.com").
+ Instead it simply concatenates the arguments, separated by ' ', and calls
+ CreateProcess(). We must quote the arguments since Win32 CreateProcess()
+ interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+ special way:
+ - Space and tab are interpreted as delimiters. They are not treated as
+ delimiters if they are surrounded by double quotes: "...".
+ - Unescaped double quotes are removed from the input. Their only effect is
+ that within double quotes, space and tab are treated like normal
+ characters.
+ - Backslashes not followed by double quotes are not special.
+ - But 2*n+1 backslashes followed by a double quote become
+ n backslashes followed by a double quote (n >= 0):
+ \" -> "
+ \\\" -> \"
+ \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+ size_t argc;
+ char **new_argv;
+ size_t i;
+
+ /* Count number of arguments. */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ ;
+
+ /* Allocate new argument vector. */
+ new_argv = XMALLOC (char *, argc + 1);
+
+ /* Put quoted arguments into the new argument vector. */
+ for (i = 0; i < argc; i++)
+ {
+ const char *string = argv[i];
+
+ if (string[0] == '\0')
+ new_argv[i] = xstrdup ("\"\"");
+ else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+ {
+ int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+ size_t length;
+ unsigned int backslashes;
+ const char *s;
+ char *quoted_string;
+ char *p;
+
+ length = 0;
+ backslashes = 0;
+ if (quote_around)
+ length++;
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ length += backslashes + 1;
+ length++;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ length += backslashes + 1;
+
+ quoted_string = XMALLOC (char, length + 1);
+
+ p = quoted_string;
+ backslashes = 0;
+ if (quote_around)
+ *p++ = '"';
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ {
+ unsigned int j;
+ for (j = backslashes + 1; j > 0; j--)
+ *p++ = '\\';
+ }
+ *p++ = c;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ {
+ unsigned int j;
+ for (j = backslashes; j > 0; j--)
+ *p++ = '\\';
+ *p++ = '"';
+ }
+ *p = '\0';
+
+ new_argv[i] = quoted_string;
+ }
+ else
+ new_argv[i] = (char *) string;
+ }
+ new_argv[argc] = NULL;
+
+ return new_argv;
+}
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+ func_emit_wrapper yes |
+ $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/ fputs ("\1", f);/p
+g
+D'
+ cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+ $debug_cmd
+
+ case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+ *import*) : ;;
+ *) false ;;
+ esac
+}
+
+# func_suncc_cstd_abi
+# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
+# Several compiler flags select an ABI that is incompatible with the
+# Cstd library. Avoid specifying it if any are in CXXFLAGS.
+func_suncc_cstd_abi ()
+{
+ $debug_cmd
+
+ case " $compile_command " in
+ *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
+ suncc_use_cstd_abi=no
+ ;;
+ *)
+ suncc_use_cstd_abi=yes
+ ;;
+ esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $debug_cmd
+
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # what system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll that has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+ fix_hardcoded_libdir_flag=
+ fix_hardcoded_libdir_flag_ld=
+
+ avoid_version=no
+ bindir=
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ os2dllname=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=false
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module=$wl-single_module
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test yes != "$build_libtool_libs" \
+ && func_fatal_configuration "cannot build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg=$1
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ bindir)
+ bindir=$arg
+ prev=
+ continue
+ ;;
+ dlfiles|dlprefiles)
+ $preload || {
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=:
+ }
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test no = "$dlself"; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test dlprefiles = "$prev"; then
+ dlself=yes
+ elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test dlfiles = "$prev"; then
+ func_append dlfiles " $arg"
+ else
+ func_append dlprefiles " $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols=$arg
+ test -f "$arg" \
+ || func_fatal_error "symbol file '$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex=$arg
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) func_append deplibs " $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir=$arg
+ prev=
+ continue
+ ;;
+ mllvm)
+ # Clang does not use LLVM to link, so we can simply discard any
+ # '-mllvm $arg' options when doing the link step.
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# func_append moreargs " $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test none = "$pic_object" &&
+ test none = "$non_pic_object"; then
+ func_fatal_error "cannot find name of object for '$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ if test none != "$pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ pic_object=$xdir$pic_object
+
+ if test dlfiles = "$prev"; then
+ if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test dlprefiles = "$prev"; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg=$pic_object
+ fi
+
+ # Non-PIC object.
+ if test none != "$non_pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object=$xdir$non_pic_object
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test none = "$pic_object"; then
+ arg=$non_pic_object
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object=$pic_object
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "'$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file '$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ os2dllname)
+ os2dllname=$arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex=$arg
+ prev=
+ continue
+ ;;
+ release)
+ release=-$arg
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test rpath = "$prev"; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) func_append rpath " $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) func_append xrpath " $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds=$arg
+ prev=
+ continue
+ ;;
+ weak)
+ func_append weak_libs " $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg=$arg
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "'-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -bindir)
+ prev=bindir
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test X-export-symbols = "X$arg"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname "-L" '' "$arg"
+ if test -z "$func_stripname_result"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between '-L' and '$1'"
+ else
+ func_fatal_error "need path for '-L' option"
+ fi
+ fi
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of '$dir'"
+ dir=$absdir
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "* | *" $arg "*)
+ # Will only happen for absolute or sysroot arguments
+ ;;
+ *)
+ # Preserve sysroot, but never include relative directories
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+ *) func_append deplibs " -L$dir" ;;
+ esac
+ func_append lib_search_path " $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) func_append dllsearchpath ":$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test X-lc = "X$arg" || test X-lm = "X$arg"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ # Do not include libc due to us having libc/libc_r.
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ func_append deplibs " System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test X-lc = "X$arg" && continue
+ ;;
+ esac
+ elif test X-lc_r = "X$arg"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ func_append deplibs " $arg"
+ continue
+ ;;
+
+ -mllvm)
+ prev=mllvm
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot|--sysroot)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) func_append new_inherited_linker_flags " $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module=$wl-multi_module
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "'-no-install' is ignored for $host"
+ func_warning "assuming '-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -os2dllname)
+ prev=os2dllname
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ =*)
+ func_stripname '=' '' "$dir"
+ dir=$lt_sysroot$func_stripname_result
+ ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs=$IFS; IFS=,
+ for flag in $args; do
+ IFS=$save_ifs
+ func_quote_for_eval "$flag"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs=$IFS; IFS=,
+ for flag in $args; do
+ IFS=$save_ifs
+ func_quote_for_eval "$flag"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+
+ # Flags to be passed through unchanged, with rationale:
+ # -64, -mips[0-9] enable 64-bit mode for the SGI compiler
+ # -r[0-9][0-9]* specify processor for the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+ # +DA*, +DD* enable 64-bit mode for the HP compiler
+ # -q* compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+ # -F/path path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* profiling flags for GCC
+ # -fstack-protector* stack protector flags for GCC
+ # @file GCC response files
+ # -tp=* Portland pgcc target processor selection
+ # --sysroot=* for sysroot support
+ # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ # -stdlib=* select c++ std lib with clang
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ func_append compiler_flags " $arg"
+ continue
+ ;;
+
+ -Z*)
+ if test os2 = "`expr $host : '.*\(os2\)'`"; then
+ # OS/2 uses -Zxxx to specify OS/2-specific options
+ compiler_flags="$compiler_flags $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case $arg in
+ -Zlinker | -Zstack)
+ prev=xcompiler
+ ;;
+ esac
+ continue
+ else
+ # Otherwise treat like 'Some other compiler flag' below
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ fi
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+
+ *.$objext)
+ # A standard object.
+ func_append objs " $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test none = "$pic_object" &&
+ test none = "$non_pic_object"; then
+ func_fatal_error "cannot find name of object for '$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ test none = "$pic_object" || {
+ # Prepend the subdirectory the object is found in.
+ pic_object=$xdir$pic_object
+
+ if test dlfiles = "$prev"; then
+ if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test dlprefiles = "$prev"; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg=$pic_object
+ }
+
+ # Non-PIC object.
+ if test none != "$non_pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object=$xdir$non_pic_object
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test none = "$pic_object"; then
+ arg=$non_pic_object
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object=$pic_object
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "'$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ func_append deplibs " $arg"
+ func_append old_deplibs " $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ func_resolve_sysroot "$arg"
+ if test dlfiles = "$prev"; then
+ # This library was specified with -dlopen.
+ func_append dlfiles " $func_resolve_sysroot_result"
+ prev=
+ elif test dlprefiles = "$prev"; then
+ # The library was specified with -dlpreopen.
+ func_append dlprefiles " $func_resolve_sysroot_result"
+ prev=
+ else
+ func_append deplibs " $func_resolve_sysroot_result"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the '$prevarg' option requires an argument"
+
+ if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname=$func_basename_result
+ libobjs_save=$libobjs
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ # Definition is injected by LT_CONFIG during libtool generation.
+ func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"
+
+ func_dirname "$output" "/" ""
+ output_objdir=$func_dirname_result$objdir
+ func_to_tool_file "$output_objdir/"
+ tool_output_objdir=$func_to_tool_file_result
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_preserve_dup_deps; then
+ case "$libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append libs " $deplib"
+ done
+
+ if test lib = "$linkmode"; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+ esac
+ func_append pre_post_deps " $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=false
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test lib,link = "$linkmode,$pass"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs=$tmp_deplibs
+ fi
+
+ if test lib,link = "$linkmode,$pass" ||
+ test prog,scan = "$linkmode,$pass"; then
+ libs=$deplibs
+ deplibs=
+ fi
+ if test prog = "$linkmode"; then
+ case $pass in
+ dlopen) libs=$dlfiles ;;
+ dlpreopen) libs=$dlprefiles ;;
+ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ esac
+ fi
+ if test lib,dlpreopen = "$linkmode,$pass"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ func_resolve_sysroot "$lib"
+ case $lib in
+ *.la) func_source "$func_resolve_sysroot_result" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ func_basename "$deplib"
+ deplib_base=$func_basename_result
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) func_append deplibs " $deplib" ;;
+ esac
+ done
+ done
+ libs=$dlprefiles
+ fi
+ if test dlopen = "$pass"; then
+ # Collect dlpreopened libraries
+ save_deplibs=$deplibs
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=false
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append compiler_flags " $deplib"
+ if test lib = "$linkmode"; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test lib != "$linkmode" && test prog != "$linkmode"; then
+ func_warning "'-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test lib = "$linkmode"; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib=$searchdir/lib$name$search_ext
+ if test -f "$lib"; then
+ if test .la = "$search_ext"; then
+ found=:
+ else
+ found=false
+ fi
+ break 2
+ fi
+ done
+ done
+ if $found; then
+ # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll=$l
+ done
+ if test "X$ll" = "X$old_library"; then # only static version available
+ found=false
+ func_dirname "$lib" "" "."
+ ladir=$func_dirname_result
+ lib=$ladir/$old_library
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ else
+ # deplib doesn't seem to be a libtool library
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ ;; # -l
+ *.ltframework)
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test lib = "$linkmode"; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test conv = "$pass" && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ prog)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test scan = "$pass"; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ *)
+ func_warning "'-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test link = "$pass"; then
+ func_stripname '-R' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ lib=$func_resolve_sysroot_result
+ ;;
+ *.$libext)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=false
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=:
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=:
+ ;;
+ esac
+ if $valid_a_lib; then
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ else
+ echo
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not use here."
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test link != "$pass"; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ elif test prog = "$linkmode"; then
+ if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ func_append newdlprefiles " $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append newdlfiles " $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=:
+ continue
+ ;;
+ esac # case $deplib
+
+ $found || test -f "$lib" \
+ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "'$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir=$func_dirname_result
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test lib,link = "$linkmode,$pass" ||
+ test prog,scan = "$linkmode,$pass" ||
+ { test prog != "$linkmode" && test lib != "$linkmode"; }; then
+ test -n "$dlopen" && func_append dlfiles " $dlopen"
+ test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+ fi
+
+ if test conv = "$pass"; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for '$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ func_append convenience " $ladir/$objdir/$old_library"
+ func_append old_convenience " $ladir/$objdir/$old_library"
+ elif test prog != "$linkmode" && test lib != "$linkmode"; then
+ func_fatal_error "'$lib' is not a convenience library"
+ fi
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ if test -n "$old_library" &&
+ { test yes = "$prefer_static_libs" ||
+ test built,no = "$prefer_static_libs,$installed"; }; then
+ linklib=$old_library
+ else
+ for l in $old_library $library_names; do
+ linklib=$l
+ done
+ fi
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for '$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test dlopen = "$pass"; then
+ test -z "$libdir" \
+ && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
+ if test -z "$dlname" ||
+ test yes != "$dlopen_support" ||
+ test no = "$build_libtool_libs"
+ then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ func_append dlprefiles " $lib $dependency_libs"
+ else
+ func_append newdlfiles " $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of '$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir=$ladir
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname=$func_basename_result
+
+ # Find the relevant object directory and library name.
+ if test yes = "$installed"; then
+ if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library '$lib' was moved."
+ dir=$ladir
+ absdir=$abs_ladir
+ libdir=$abs_ladir
+ else
+ dir=$lt_sysroot$libdir
+ absdir=$lt_sysroot$libdir
+ fi
+ test yes = "$hardcode_automatic" && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir=$ladir
+ absdir=$abs_ladir
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ else
+ dir=$ladir/$objdir
+ absdir=$abs_ladir/$objdir
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test dlpreopen = "$pass"; then
+ if test -z "$libdir" && test prog = "$linkmode"; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
+ fi
+ case $host in
+ # special handling for platforms with PE-DLLs.
+ *cygwin* | *mingw* | *cegcc* )
+ # Linker will automatically link against shared library if both
+ # static and shared are present. Therefore, ensure we extract
+ # symbols from the import library if a shared library is present
+ # (otherwise, the dlopen module name will be incorrect). We do
+ # this by putting the import library name into $newdlprefiles.
+ # We recover the dlopen module name by 'saving' the la file
+ # name in a special purpose variable, and (later) extracting the
+ # dlname from the la file.
+ if test -n "$dlname"; then
+ func_tr_sh "$dir/$linklib"
+ eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+ func_append newdlprefiles " $dir/$linklib"
+ else
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ fi
+ ;;
+ * )
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ func_append newdlprefiles " $dir/$dlname"
+ else
+ func_append newdlprefiles " $dir/$linklib"
+ fi
+ ;;
+ esac
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test lib = "$linkmode"; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test prog = "$linkmode" && test link != "$pass"; then
+ func_append newlib_search_path " $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=false
+ if test no != "$link_all_deplibs" || test -z "$library_names" ||
+ test no = "$build_libtool_libs"; then
+ linkalldeplibs=:
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if $linkalldeplibs; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test prog,link = "$linkmode,$pass"; then
+ if test -n "$library_names" &&
+ { { test no = "$prefer_static_libs" ||
+ test built,yes = "$prefer_static_libs,$installed"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
+ # Make sure the rpath contains only unique directories.
+ case $temp_rpath: in
+ *"$absdir:"*) ;;
+ *) func_append temp_rpath "$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if $alldeplibs &&
+ { test pass_all = "$deplibs_check_method" ||
+ { test yes = "$build_libtool_libs" &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test built = "$use_static_libs" && test yes = "$installed"; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test no = "$use_static_libs" || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc* | *os2*)
+ # No point in relinking DLLs because paths are not encoded
+ func_append notinst_deplibs " $lib"
+ need_relink=no
+ ;;
+ *)
+ if test no = "$installed"; then
+ func_append notinst_deplibs " $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule=$dlpremoduletest
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
+ echo
+ if test prog = "$linkmode"; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test lib = "$linkmode" &&
+ test yes = "$hardcode_into_libs"; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname=$1
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname=$dlname
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc* | *os2*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix=-$major
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname=$realname
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot=$soname
+ func_basename "$soroot"
+ soname=$func_basename_result
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from '$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for '$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test prog = "$linkmode" || test relink != "$opt_mode"; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test no = "$hardcode_direct"; then
+ add=$dir/$linklib
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
+ *-*-sysv4*uw2*) add_dir=-L$dir ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir=-L$dir ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we cannot
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library"; then
+ echo
+ echo "*** And there doesn't seem to be a static archive available"
+ echo "*** The link will probably fail, sorry"
+ else
+ add=$dir/$old_library
+ fi
+ elif test -n "$old_library"; then
+ add=$dir/$old_library
+ fi
+ fi
+ esac
+ elif test no = "$hardcode_minus_L"; then
+ case $host in
+ *-*-sunos*) add_shlibpath=$dir ;;
+ esac
+ add_dir=-L$dir
+ add=-l$name
+ elif test no = "$hardcode_shlibpath_var"; then
+ add_shlibpath=$dir
+ add=-l$name
+ elif test -n "$fix_hardcoded_libdir_flag_spec"; then
+ add_dir="-L${absdir}"
+ add="-l$name"
+ if test "${linkmode}" = prog && test "X${absdir}" != "X${libdir}"; then
+ linkdir=$absdir
+ eval "fix_hardcoded_libdir_flag=\"\${fix_hardcoded_libdir_flag} ${fix_hardcoded_libdir_flag_spec}\""
+ # fix_hardcoded_libdir_flag_ld not needed, programs are linked with $CC
+ $lt_unset linkdir
+ fi
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test yes = "$hardcode_direct" &&
+ test no = "$hardcode_direct_absolute"; then
+ add=$dir/$linklib
+ elif test yes = "$hardcode_minus_L"; then
+ add_dir=-L$absdir
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add=-l$name
+ elif test yes = "$hardcode_shlibpath_var"; then
+ add_shlibpath=$dir
+ add=-l$name
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test yes != "$lib_linked"; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) func_append compile_shlibpath "$add_shlibpath:" ;;
+ esac
+ fi
+ if test prog = "$linkmode"; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test yes != "$hardcode_direct" &&
+ test yes != "$hardcode_minus_L" &&
+ test yes = "$hardcode_shlibpath_var"; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test prog = "$linkmode" || test relink = "$opt_mode"; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test yes = "$hardcode_direct" &&
+ test no = "$hardcode_direct_absolute"; then
+ add=$libdir/$linklib
+ elif test yes = "$hardcode_minus_L"; then
+ add_dir=-L$libdir
+ add=-l$name
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib" &&
+ test -n "${fix_hardcoded_libdir_flag_spec}"; then
+ linkdir="$inst_prefix_dir$libdir"
+ add_dir="-L$linkdir"
+ eval "fix_hardcoded_libdir_flag=\"\${fix_hardcoded_libdir_flag} ${fix_hardcoded_libdir_flag_spec}\""
+ eval "fix_hardcoded_libdir_flag_ld=\"\${fix_hardcoded_libdir_flag_ld} ${fix_hardcoded_libdir_flag_spec_ld}\""
+ $lt_unset linkdir
+ fi
+ elif test yes = "$hardcode_shlibpath_var"; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ add=-l$name
+ elif test yes = "$hardcode_automatic"; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib"; then
+ add=$inst_prefix_dir$libdir/$linklib
+ else
+ add=$libdir/$linklib
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir=-L$libdir
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add=-l$name
+ fi
+
+ if test prog = "$linkmode"; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test prog = "$linkmode"; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test unsupported != "$hardcode_direct"; then
+ test -n "$old_library" && linklib=$old_library
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test yes = "$build_libtool_libs"; then
+ # Not a shared library
+ if test pass_all != "$deplibs_check_method"; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ $ECHO "*** Warning: This system cannot link to static lib archive $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test yes = "$module"; then
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test no = "$build_old_libs"; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test lib = "$linkmode"; then
+ if test -n "$dependency_libs" &&
+ { test yes != "$hardcode_into_libs" ||
+ test yes = "$build_old_libs" ||
+ test yes = "$link_static"; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) func_append xrpath " $temp_xrpath";;
+ esac;;
+ *) func_append temp_deplibs " $libdir";;
+ esac
+ done
+ dependency_libs=$temp_deplibs
+ fi
+
+ func_append newlib_search_path " $absdir"
+ # Link against this library
+ test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result";;
+ *) func_resolve_sysroot "$deplib" ;;
+ esac
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $func_resolve_sysroot_result "*)
+ func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+ esac
+ fi
+ func_append tmp_libs " $func_resolve_sysroot_result"
+ done
+
+ if test no != "$link_all_deplibs"; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path=$deplib ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ deplib=$func_resolve_sysroot_result
+ func_dirname "$deplib" "" "."
+ dir=$func_dirname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of '$dir'"
+ absdir=$dir
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names"; then
+ for tmp in $deplibrary_names; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl"; then
+ depdepl=$absdir/$objdir/$depdepl
+ darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
+ func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path=-L$absdir/$objdir
+ ;;
+ esac
+ else
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "'$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "'$deplib' seems to be moved"
+
+ path=-L$absdir
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test link = "$pass"; then
+ if test prog = "$linkmode"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs=$newdependency_libs
+ if test dlpreopen = "$pass"; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test dlopen != "$pass"; then
+ test conv = "$pass" || {
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) func_append lib_search_path " $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ }
+
+ if test prog,link = "$linkmode,$pass"; then
+ vars="compile_deplibs finalize_deplibs"
+ else
+ vars=deplibs
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+
+ # Add Sun CC postdeps if required:
+ test CXX = "$tagname" && {
+ case $host_os in
+ linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C++ 5.9
+ func_suncc_cstd_abi
+
+ if test no != "$suncc_use_cstd_abi"; then
+ func_append postdeps ' -library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ func_cc_basename "$CC"
+ case $func_cc_basename_result in
+ CC* | sunCC*)
+ func_suncc_cstd_abi
+
+ if test no != "$suncc_use_cstd_abi"; then
+ func_append postdeps ' -library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ }
+
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=
+ ;;
+ esac
+ if test -n "$i"; then
+ func_append tmp_libs " $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test prog = "$linkmode"; then
+ dlfiles=$newdlfiles
+ fi
+ if test prog = "$linkmode" || test lib = "$linkmode"; then
+ dlprefiles=$newdlprefiles
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ func_warning "'-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "'-l' and '-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "'-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "'-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "'-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs=$output
+ func_append objs "$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form 'libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test no = "$module" \
+ && func_fatal_help "libtool library '$output' must begin with 'lib'"
+
+ if test no != "$need_lib_prefix"; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test pass_all != "$deplibs_check_method"; then
+ func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ func_append libobjs " $objs"
+ fi
+ fi
+
+ test no = "$dlself" \
+ || func_warning "'-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test 1 -lt "$#" \
+ && func_warning "ignoring multiple '-rpath's for a libtool library"
+
+ install_libdir=$1
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test yes = "$build_libtool_libs"; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a '.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs=$IFS; IFS=:
+ set dummy $vinfo 0 0 0
+ shift
+ IFS=$save_ifs
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to '-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major=$1
+ number_minor=$2
+ number_revision=$3
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # that has an extra 1 added just for fun
+ #
+ case $version_type in
+ # correct linux to gnu/linux during the next big refactor
+ darwin|freebsd-elf|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age=$number_minor
+ revision=$number_revision
+ ;;
+ freebsd-aout|qnx|sunos)
+ current=$number_major
+ revision=$number_minor
+ age=0
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age=$number_minor
+ revision=$number_minor
+ lt_irix_increment=no
+ ;;
+ esac
+ ;;
+ no)
+ current=$1
+ revision=$2
+ age=$3
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[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]) ;;
+ *)
+ func_error "CURRENT '$current' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[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]) ;;
+ *)
+ func_error "REVISION '$revision' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[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]) ;;
+ *)
+ func_error "AGE '$age' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE '$age' is greater than the current interface number '$current'"
+ func_fatal_error "'$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ # On Darwin other compilers
+ case $CC in
+ nagfor*)
+ verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+ ;;
+ *)
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+ esac
+ ;;
+
+ freebsd-aout)
+ major=.$current
+ versuffix=.$current.$revision
+ ;;
+
+ freebsd-elf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ ;;
+
+ irix | nonstopux)
+ if test no = "$lt_irix_increment"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring=$verstring_prefix$major.$revision
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test 0 -ne "$loop"; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring=$verstring_prefix$major.$iface:$verstring
+ done
+
+ # Before this point, $major must not contain '.'.
+ major=.$major
+ versuffix=$major.$revision
+ ;;
+
+ linux) # correct to gnu/linux during the next big refactor
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=.$current.$age.$revision
+ verstring=$current.$age.$revision
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test 0 -ne "$loop"; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring=$verstring:$iface.0
+ done
+
+ # Make executables depend on our current version.
+ func_append verstring ":$current.0"
+ ;;
+
+ qnx)
+ major=.$current
+ versuffix=.$current
+ ;;
+
+ sco)
+ major=.$current
+ versuffix=.$current
+ ;;
+
+ sunos)
+ major=.$current
+ versuffix=.$current.$revision
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 file systems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix=-$major
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type '$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring=0.0
+ ;;
+ esac
+ if test no = "$need_version"; then
+ versuffix=
+ else
+ versuffix=.0.0
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test yes,no = "$avoid_version,$need_version"; then
+ major=
+ versuffix=
+ verstring=
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test yes = "$allow_undefined"; then
+ if test unsupported = "$allow_undefined_flag"; then
+ if test yes = "$build_old_libs"; then
+ func_warning "undefined symbols not allowed in $host shared libraries; building static only"
+ build_libtool_libs=no
+ else
+ func_fatal_error "can't build $host shared library unless -no-undefined is specified"
+ fi
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag=$no_undefined_flag
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" :
+ func_append libobjs " $symfileobj"
+ test " " = "$libobjs" && libobjs=
+
+ if test relink != "$opt_mode"; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
+ if test -n "$precious_files_regex"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ func_append removelist " $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
+ func_append oldlibs " $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+ # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ func_replace_sysroot "$libdir"
+ func_append temp_xrpath " -R$func_replace_sysroot_result"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles=$dlfiles
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) func_append dlfiles " $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles=$dlprefiles
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) func_append dlprefiles " $lib" ;;
+ esac
+ done
+
+ if test yes = "$build_libtool_libs"; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ func_append deplibs " System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test yes = "$build_libtool_need_lc"; then
+ func_append deplibs " -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=
+ versuffix=
+ major=
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=
+ ;;
+ esac
+ fi
+ if test -n "$i"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=
+ ;;
+ esac
+ fi
+ if test -n "$i"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ if test -n "$file_magic_glob"; then
+ libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+ else
+ libnameglob=$libname
+ fi
+ test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test yes = "$want_nocaseglob"; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib=$potent_lib
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
+ *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib"; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib"; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib=$potent_lib # see symlink-check above in file_magic test
+ if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib"; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib"; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=
+ tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ for i in $predeps $postdeps; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
+ done
+ fi
+ case $tmp_deplibs in
+ *[!\ \ ]*)
+ echo
+ if test none = "$deplibs_check_method"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ ;;
+ esac
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test yes = "$droppeddeps"; then
+ if test yes = "$module"; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test no = "$build_old_libs"; then
+ oldlibs=$output_objdir/$libname.$libext
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test no = "$allow_undefined"; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test no = "$build_old_libs"; then
+ oldlibs=$output_objdir/$libname.$libext
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ deplibs=$new_libs
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test yes = "$build_libtool_libs"; then
+ # Remove $wl instances when linking with ld.
+ # FIXME: should test the right _cmds variable.
+ case $archive_cmds in
+ *\$LD\ *) wl= ;;
+ esac
+ if test yes = "$hardcode_into_libs"; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath=$finalize_rpath
+ test relink = "$opt_mode" || rpath=$compile_rpath$rpath
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append dep_rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath=$finalize_shlibpath
+ test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname=$1
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname=$realname
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib=$output_objdir/$realname
+ linknames=
+ for link
+ do
+ func_append linknames " $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols=$output_objdir/$libname.uexp
+ func_append delfiles " $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ func_dll_def_p "$export_symbols" || {
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols=$export_symbols
+ export_symbols=
+ always_export_symbols=yes
+ }
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for '$libname.la'"
+ export_symbols=$output_objdir/$libname.exp
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs=$IFS; IFS='~'
+ for cmd1 in $cmds; do
+ IFS=$save_ifs
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test yes = "$try_normal_branch" \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=$output_objdir/$output_la.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
+ func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS=$save_ifs
+ if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols=$export_symbols
+ test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands, which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ func_append tmp_deplibs " $test_deplib"
+ ;;
+ esac
+ done
+ deplibs=$tmp_deplibs
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test yes = "$compiler_needs_object" &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ func_append linker_flags " $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test relink = "$opt_mode"; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test yes = "$module" && test -n "$module_cmds"; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test : != "$skipped_export" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ func_basename "$output"
+ output_la=$func_basename_result
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
+ output=$output_objdir/$output_la.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ echo 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ echo ')' >> $output
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
+ elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
+ output=$output_objdir/$output_la.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test yes = "$compiler_needs_object"; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-$k.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test -z "$objlist" ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test 1 -eq "$k"; then
+ # The first file doesn't have a previous command to add.
+ reload_objs=$objlist
+ eval concat_cmds=\"$reload_cmds\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-$k.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-$k.$objext
+ objlist=" $obj"
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds$reload_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ func_append delfiles " $output"
+
+ else
+ output=
+ fi
+
+ ${skipped_export-false} && {
+ func_verbose "generating symbol list for '$libname.la'"
+ export_symbols=$output_objdir/$libname.exp
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ }
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs=$IFS; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS=$save_ifs
+ $opt_quiet || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS=$save_ifs
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ ${skipped_export-false} && {
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols=$export_symbols
+ test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands, which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ }
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test yes = "$module" && test -n "$module_cmds"; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs=$IFS; IFS='~'
+ for cmd in $cmds; do
+ IFS=$sp$nl
+ eval cmd=\"$cmd\"
+ IFS=$save_ifs
+ $opt_quiet || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS=$save_ifs
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test yes = "$module" || test yes = "$export_dynamic"; then
+ # On all known operating systems, these are identical.
+ dlname=$soname
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ func_warning "'-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "'-l' and '-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "'-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "'-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object '$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj=$output
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # if reload_cmds runs $LD directly, get rid of -Wl from
+ # whole_archive_flag_spec and hope we can get by with turning comma
+ # into space.
+ case $reload_cmds in
+ *\$LD[\ \$]*) wl= ;;
+ esac
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+ reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
+ else
+ gentop=$output_objdir/${obj}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # If we're not building shared, we need to use non_pic_objs
+ test yes = "$build_libtool_libs" || libobjs=$non_pic_objects
+
+ # Create the old-style object.
+ reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs
+
+ output=$obj
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ test yes = "$build_libtool_libs" || {
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ }
+
+ if test -n "$pic_flag" || test default != "$pic_mode"; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output=$libobj
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "'-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for programs"
+
+ $preload \
+ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
+ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test CXX = "$tagname"; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ func_append compile_command " $wl-bind_at_load"
+ func_append finalize_command " $wl-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ compile_deplibs=$new_libs
+
+
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) func_append dllsearchpath ":$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath=$rpath
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath=$rpath
+
+ if test -n "$libobjs" && test yes = "$build_old_libs"; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" false
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=:
+ case $host in
+ *cegcc* | *mingw32ce*)
+ # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+ wrappers_required=false
+ ;;
+ *cygwin* | *mingw* )
+ test yes = "$build_libtool_libs" || wrappers_required=false
+ ;;
+ *)
+ if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
+ wrappers_required=false
+ fi
+ ;;
+ esac
+ $wrappers_required || {
+ # Replace the output file specification.
+ compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ link_command=$compile_command$compile_rpath
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.$objext"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
+ fi
+
+ exit $exit_status
+ }
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test yes = "$no_install"; then
+ # We don't need to create a wrapper script.
+ link_command=$compile_var$compile_command$compile_rpath
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ case $hardcode_action,$fast_install in
+ relink,*)
+ # Fast installation is not supported
+ link_command=$compile_var$compile_command$compile_rpath
+ relink_command=$finalize_var$finalize_command$finalize_rpath
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "'$output' will be relinked during installation"
+ ;;
+ *,yes)
+ link_command=$finalize_var$compile_command$finalize_rpath
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+ ;;
+ *,no)
+ link_command=$compile_var$compile_command$compile_rpath
+ relink_command=$finalize_var$finalize_command$finalize_rpath
+ ;;
+ *,needless)
+ link_command=$finalize_var$compile_command$finalize_rpath
+ relink_command=
+ ;;
+ esac
+
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource=$output_path/$objdir/lt-$output_name.c
+ cwrapper=$output_path/$output_name.exe
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host"; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ case $build_libtool_libs in
+ convenience)
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs=$convenience
+ build_libtool_libs=no
+ ;;
+ module)
+ oldobjs=$libobjs_save
+ addlibs=$old_convenience
+ build_libtool_libs=no
+ ;;
+ *)
+ oldobjs="$old_deplibs $non_pic_objects"
+ $preload && test -f "$symfileobj" \
+ && func_append oldobjs " $symfileobj"
+ addlibs=$old_convenience
+ ;;
+ esac
+
+ if test -n "$addlibs"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $addlibs
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ echo "copying selected object files to avoid basename conflicts..."
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase=$func_basename_result
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
+ ;;
+ *) func_append oldobjs " $obj" ;;
+ esac
+ done
+ fi
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj"; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test -z "$oldobjs"; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test yes = "$build_old_libs" && old_library=$libname.$libext
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ if test yes = "$hardcode_automatic"; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test yes = "$installed"; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output=$output_objdir/${outputname}i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name=$func_basename_result
+ func_resolve_sysroot "$deplib"
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ test -z "$libdir" && \
+ func_fatal_error "'$deplib' is not a valid libtool archive"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
+ ;;
+ *) func_append newdependency_libs " $deplib" ;;
+ esac
+ done
+ dependency_libs=$newdependency_libs
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name=$func_basename_result
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "'$lib' is not a valid libtool archive"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ *) func_append newdlfiles " $lib" ;;
+ esac
+ done
+ dlfiles=$newdlfiles
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name=$func_basename_result
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "'$lib' is not a valid libtool archive"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles=$newdlprefiles
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlfiles " $abs"
+ done
+ dlfiles=$newdlfiles
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlprefiles " $abs"
+ done
+ dlprefiles=$newdlprefiles
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ # In fact, it would be nice if we could use this code for all target
+ # systems that can't hard-code library paths into their executables
+ # and that have no shared library path variable independent of PATH,
+ # but it turns out we can't easily determine that from inspecting
+ # libtool variables, so we have to hard-code the OSs to which it
+ # applies here; at the moment, that means platforms that use the PE
+ # object format with DLL files. See the long comment at the top of
+ # tests/bindir.at for full details.
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+ # If a -bindir argument was supplied, place the dll there.
+ if test -n "$bindir"; then
+ func_relative_path "$install_libdir" "$bindir"
+ tdlname=$func_relative_path_result/$dlname
+ else
+ # Otherwise fall back on heuristic.
+ tdlname=../bin/$dlname
+ fi
+ ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that cannot go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test no,yes = "$installed,$need_relink"; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+if test link = "$opt_mode" || test relink = "$opt_mode"; then
+ func_mode_link ${1+"$@"}
+fi
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $debug_cmd
+
+ RM=$nonopt
+ files=
+ rmforce=false
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic=$magic
+
+ for arg
+ do
+ case $arg in
+ -f) func_append RM " $arg"; rmforce=: ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+ if test . = "$dir"; then
+ odir=$objdir
+ else
+ odir=$dir/$objdir
+ fi
+ func_basename "$file"
+ name=$func_basename_result
+ test uninstall = "$opt_mode" && odir=$dir
+
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test clean = "$opt_mode"; then
+ case " $rmdirs " in
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif $rmforce; then
+ continue
+ fi
+
+ rmfiles=$file
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ func_append rmfiles " $odir/$n"
+ done
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+ case $opt_mode in
+ clean)
+ case " $library_names " in
+ *" $dlname "*) ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+ esac
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" && test none != "$pic_object"; then
+ func_append rmfiles " $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" && test none != "$non_pic_object"; then
+ func_append rmfiles " $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test clean = "$opt_mode"; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ func_append rmfiles " $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ func_append rmfiles " $odir/$name $odir/${name}S.$objext"
+ if test yes = "$fast_install" && test -n "$relink_command"; then
+ func_append rmfiles " $odir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name"; then
+ func_append rmfiles " $odir/lt-$noexename.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+
+ # Try to remove the $objdir's in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
+ func_mode_uninstall ${1+"$@"}
+fi
+
+test -z "$opt_mode" && {
+ help=$generic_help
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode '$opt_mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# where we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4
new file mode 100644
index 0000000..08f2e07
--- /dev/null
+++ b/m4/ax_append_flag.m4
@@ -0,0 +1,71 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#
+# DESCRIPTION
+#
+# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
+# added in between.
+#
+# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
+# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
+# FLAG.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 6
+
+AC_DEFUN([AX_APPEND_FLAG],
+[dnl
+AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
+AS_VAR_SET_IF(FLAGS,[
+ AS_CASE([" AS_VAR_GET(FLAGS) "],
+ [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
+ [
+ AS_VAR_APPEND(FLAGS,[" $1"])
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+ ],
+ [
+ AS_VAR_SET(FLAGS,[$1])
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_APPEND_FLAG
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
new file mode 100644
index 0000000..c3a8d69
--- /dev/null
+++ b/m4/ax_check_compile_flag.m4
@@ -0,0 +1,72 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the current language's compiler
+# or gives an error. (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the current language's default
+# flags (e.g. CFLAGS) when the check is done. The check is thus made with
+# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
+# force the compiler to issue an error when a bad flag is given.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+ _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4
new file mode 100644
index 0000000..e2d0d36
--- /dev/null
+++ b/m4/ax_check_link_flag.m4
@@ -0,0 +1,71 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the linker or gives an error.
+# (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the linker's default flags
+# when the check is done. The check is thus made with the flags: "LDFLAGS
+# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
+# issue an error when a bad flag is given.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_LINK_FLAG],
+[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
+AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
+ ax_check_save_flags=$LDFLAGS
+ LDFLAGS="$LDFLAGS $4 $1"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM()],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ LDFLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_LINK_FLAGS
diff --git a/m4/ax_func_getaddrinfo.m4 b/m4/ax_func_getaddrinfo.m4
new file mode 100644
index 0000000..de3301b
--- /dev/null
+++ b/m4/ax_func_getaddrinfo.m4
@@ -0,0 +1,70 @@
+#
+# SYNOPSIS
+#
+# AX_FUNC_GETADDRINFO
+#
+# DESCRIPTION
+#
+# Checks for the getaddrinfo function in the standard C library,
+# as well as the socket and inet libraries, if they are present.
+# If extra libraries are required, they are added to LIBS.
+# If no getaddrinfo function is found, it is added to LIBOBJS.
+# Note: Tru64 UNIX contains two versions of getaddrinfo and we must
+# include netdb.h to get the proper definition.
+#
+# LICENSE
+#
+# Placed in the public domain by Todd C. Miller on November 20, 2013.
+#
+
+AC_DEFUN([AX_FUNC_GETADDRINFO],
+[AC_MSG_CHECKING(for getaddrinfo)
+AC_CACHE_VAL(ax_cv_func_getaddrinfo,
+[AC_LINK_IFELSE([AC_LANG_SOURCE([[#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+int main() { return getaddrinfo(0, 0, 0, 0); }]])], [ax_cv_func_getaddrinfo=yes], [ax_cv_func_getaddrinfo=no])])
+AC_MSG_RESULT([$ax_cv_func_getaddrinfo])
+if test X"$ax_cv_func_getaddrinfo" = X"yes"; then
+ AC_DEFINE(HAVE_GETADDRINFO, 1, [Define to 1 if you have the `getaddrinfo' function.])
+else
+ # Not found in libc, check libsocket and libinet
+ _found=no
+ for _libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+ _cv="ax_cv_lib_getaddrinfo`echo \"$_libs\"|sed -e 's/-l/_/g' -e 's/ *//g'`"
+ AC_MSG_CHECKING([for getaddrinfo in $_libs])
+ AC_CACHE_VAL([$_cv], [
+ _nlibs=
+ for _l in $_libs; do
+ case "$LIBS" in
+ *"$_l"*) ;;
+ *) _nlibs="$_nlibs $_l";;
+ esac
+ done
+ _libs="${_nlibs# }"
+ if test -z "$_libs"; then
+ # No new libs to check
+ eval $_cv=no
+ else
+ AX_FUNC_GETADDRINFO_OLIBS="$LIBS"
+ LIBS="$LIBS $_libs"
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[#include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netdb.h>
+ int main() { return getaddrinfo(0, 0, 0, 0); }]])], [eval $_cv=yes], [eval $_cv=no])
+ LIBS="$AX_FUNC_GETADDRINFO_OLIBS"
+ fi
+ ])
+ if eval test \$$_cv = "yes"; then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_GETADDRINFO)
+ test -n "$_libs" && LIBS="$LIBS $_libs"
+ break
+ fi
+ AC_MSG_RESULT([no])
+ done
+ if eval test \$$_cv != "yes"; then
+ AC_LIBOBJ(getaddrinfo)
+ fi
+fi
+])
diff --git a/m4/ax_func_snprintf.m4 b/m4/ax_func_snprintf.m4
new file mode 100644
index 0000000..f0dccf0
--- /dev/null
+++ b/m4/ax_func_snprintf.m4
@@ -0,0 +1,82 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_func_snprintf.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_FUNC_SNPRINTF
+#
+# DESCRIPTION
+#
+# Checks for a fully C99 compliant snprintf, in particular checks whether
+# it does bounds checking and returns the correct string length; does the
+# same check for vsnprintf. If no working snprintf or vsnprintf is found,
+# request a replacement and warn the user about it. Note: the mentioned
+# replacement is freely available and may be used in any project
+# regardless of it's license.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Ruediger Kuhlmann <info@ruediger-kuhlmann.de>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 5
+
+AC_DEFUN([AX_FUNC_SNPRINTF],
+[AC_CHECK_FUNCS(snprintf vsnprintf)
+AC_MSG_CHECKING(for working snprintf)
+AC_CACHE_VAL(ac_cv_have_working_snprintf,
+[AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <stdio.h>
+
+int main(void)
+{
+ char bufs[5] = { 'x', 'x', 'x', '\0', '\0' };
+ char bufd[5] = { 'x', 'x', 'x', '\0', '\0' };
+ int i;
+ i = snprintf (bufs, 2, "%s", "111");
+ if (strcmp (bufs, "1")) exit (1);
+ if (i != 3) exit (1);
+ i = snprintf (bufd, 2, "%d", 111);
+ if (strcmp (bufd, "1")) exit (1);
+ if (i != 3) exit (1);
+ exit(0);
+}]])],[ac_cv_have_working_snprintf=yes],[ac_cv_have_working_snprintf=no],[ac_cv_have_working_snprintf=cross])])
+AC_MSG_RESULT([$ac_cv_have_working_snprintf])
+AC_MSG_CHECKING(for working vsnprintf)
+AC_CACHE_VAL(ac_cv_have_working_vsnprintf,
+[AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <stdio.h>
+#include <stdarg.h>
+
+int my_vsnprintf (char *buf, const char *tmpl, ...)
+{
+ int i;
+ va_list args;
+ va_start (args, tmpl);
+ i = vsnprintf (buf, 2, tmpl, args);
+ va_end (args);
+ return i;
+}
+
+int main(void)
+{
+ char bufs[5] = { 'x', 'x', 'x', '\0', '\0' };
+ char bufd[5] = { 'x', 'x', 'x', '\0', '\0' };
+ int i;
+ i = my_vsnprintf (bufs, "%s", "111");
+ if (strcmp (bufs, "1")) exit (1);
+ if (i != 3) exit (1);
+ i = my_vsnprintf (bufd, "%d", 111);
+ if (strcmp (bufd, "1")) exit (1);
+ if (i != 3) exit (1);
+ exit(0);
+}]])],[ac_cv_have_working_vsnprintf=yes],[ac_cv_have_working_vsnprintf=no],[ac_cv_have_working_vsnprintf=cross])])
+AC_MSG_RESULT([$ac_cv_have_working_vsnprintf])
+if test x$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf != "xyesyes"; then
+ AC_LIBOBJ(snprintf)
+ AC_MSG_WARN([Replacing missing/broken (v)snprintf() with sudo's version.])
+ AC_DEFINE(PREFER_PORTABLE_SNPRINTF, 1, [Enable replacement (v)snprintf if system (v)snprintf is broken.])
+fi])
diff --git a/m4/libtool.m4 b/m4/libtool.m4
new file mode 100644
index 0000000..f9aabab
--- /dev/null
+++ b/m4/libtool.m4
@@ -0,0 +1,8444 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool 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 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 <http://www.gnu.org/licenses/>.
+])
+
+# serial 58 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_PREPARE_CC_BASENAME
+# -----------------------
+m4_defun([_LT_PREPARE_CC_BASENAME], [
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in @S|@*""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+])# _LT_PREPARE_CC_BASENAME
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
+# but that macro is also expanded into generated libtool script, which
+# arranges for $SED and $ECHO to be set by different means.
+m4_defun([_LT_CC_BASENAME],
+[m4_require([_LT_PREPARE_CC_BASENAME])dnl
+AC_REQUIRE([_LT_DECL_SED])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+func_cc_basename $1
+cc_basename=$func_cc_basename_result
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+m4_require([_LT_CMD_TRUNCATE])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from 'configure', and 'config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain=$ac_aux_dir/ltmain.sh
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the 'libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to 'config.status' so that its
+# declaration there will have the same value as in 'configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags='_LT_TAGS'dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into 'config.status', and then the shell code to quote escape them in
+# for loops in 'config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable. If COMMENT is supplied, it is inserted after the
+# '#!' sequence but before initialization text begins. After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script. The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+'$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test 0 != $[#]
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try '$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try '$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test yes = "$silent" &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_PREPARE_MUNGE_PATH_LIST
+_LT_PREPARE_CC_BASENAME
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Go], [_LT_LANG(GO)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_GO. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC], [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+ fi
+fi
+if test -z "$GOC"; then
+ AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+ [LT_LANG(GO)],
+ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "$LT_MULTI_MODULE"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS=$save_LDFLAGS
+ ])
+
+ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+ [lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]][[,.]]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ fi
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+ m4_if([$1], [CXX],
+[ if test yes != "$lt_cv_apple_cc_single_mod"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+ lt_aix_libpath_sed='[
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }]'
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi],[])
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+ fi
+ ])
+ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script that will find a shell with a builtin
+# printf (that we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+case $ECHO in
+ printf*) AC_MSG_RESULT([printf]) ;;
+ print*) AC_MSG_RESULT([print -r]) ;;
+ *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test "X`printf %s $ECHO`" = "X$ECHO" \
+ || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
+ [Search for dependent libraries within DIR (or the compiler's sysroot
+ if not specified).])],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted. We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+ if test yes = "$GCC"; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ AC_MSG_RESULT([$with_sysroot])
+ AC_MSG_ERROR([The sysroot must be an absolute path.])
+ ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and where our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE=32
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test yes != "$lt_cv_cc_needs_belf"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS=$SAVE_CFLAGS
+ fi
+ ;;
+*-*solaris*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*|x86_64-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD=${LD-ld}_sol2
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks=$enable_libtool_lock
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+ [lt_cv_ar_at_file=no
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([lt_ar_try])
+ if test 0 -eq "$ac_status"; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ AC_TRY_EVAL([lt_ar_try])
+ if test 0 -ne "$ac_status"; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+ ])
+ ])
+
+if test no = "$lt_cv_ar_at_file"; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+ [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ bitrig* | openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+ [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test yes = "[$]$2"; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+])
+
+if test yes = "[$]$2"; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring=ABCD
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test 17 != "$i" # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n "$lt_cv_sys_max_cmd_len"; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes = "$cross_compiling"; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes != "$enable_dlopen"; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen=load_add_on
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
+ lt_cv_dlopen=dyld
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen=shl_load],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen=dlopen],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test no = "$lt_cv_dlopen"; then
+ enable_dlopen=no
+ else
+ enable_dlopen=yes
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS=$LDFLAGS
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS=$LIBS
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test yes = "$lt_cv_dlopen_self"; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links=nottested
+if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test no = "$hard_links"; then
+ AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
+ [Define to the sub-directory where libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
+ test -z "$_LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)" &&
+ test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
+ test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_PREPARE_MUNGE_PATH_LIST
+# ---------------------------
+# Make sure func_munge_path_list() is defined correctly.
+m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
+[[# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x@S|@2 in
+ x)
+ ;;
+ *:)
+ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
+ ;;
+ x:*)
+ eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
+ ;;
+ *)
+ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+]])# _LT_PREPARE_PATH_LIST
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test yes = "$GCC"; then
+ case $host_os in
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary...
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo = "/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
+[User-defined run-time library search path.])
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a[(]lib.so.V[)]'
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[23]].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+ fi
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+ [lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [lt_cv_shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+ ])
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=sco
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+ [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
+ [Detected run-time system search path for libraries])
+_LT_DECL([], [configure_time_lt_sys_library_path], [2],
+ [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program that can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$1"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac])
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program that can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test no = "$withval" || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return, which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD=$ac_prog
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test yes = "$with_gnu_ld"; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi])
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test yes != "$GCC"; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_PATH_DD
+# -----------
+# find a working dd
+m4_defun([_LT_PATH_DD],
+[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
+[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi])
+rm -f conftest.i conftest2.i conftest.out])
+])# _LT_PATH_DD
+
+
+# _LT_CMD_TRUNCATE
+# ----------------
+# find command to truncate a binary pipe
+m4_defun([_LT_CMD_TRUNCATE],
+[m4_require([_LT_PATH_DD])
+AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
+_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
+ [Command to truncate a binary pipe])
+])# _LT_CMD_TRUNCATE
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+os2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+ [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM=$NM
+else
+ lt_nm_to_check=${ac_tool_prefix}nm
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break 2
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break 2
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols -headers"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+ AC_SUBST([DUMPBIN])
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+ [lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*])
+if test yes != "$lt_cv_path_mainfest_tool"; then
+ MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# _LT_DLL_DEF_P([FILE])
+# ---------------------
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with func_dll_def_p in the libtool script
+AC_DEFUN([_LT_DLL_DEF_P],
+[dnl
+ test DEF = "`$SED -n dnl
+ -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace
+ -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments
+ -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl
+ -e q dnl Only consider the first "real" line
+ $1`" dnl
+])# _LT_DLL_DEF_P
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM=-lm)
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test yes = "$GCC"; then
+ case $cc_basename in
+ nvcc*)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+ esac
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test ia64 = "$host_cpu"; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT@&t@_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT@&t@_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS=conftstm.$ac_objext
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test yes = "$pipe_works"; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
+ [Transform the output of nm into a list of symbols to manually relocate])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
+ [The name lister interface])
+_LT_DECL([], [nm_file_list_spec], [1],
+ [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ if test ia64 != "$host_cpu"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64, which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd*)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64, which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Intel*\ [[CF]]*Compiler*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ *Portland\ Group*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ ;;
+ esac
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)=
+ _LT_TAGVAR(fix_hardcoded_libdir_flag_spec_ld, $1)=
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test yes != "$GCC"; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd* | bitrig*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test yes = "$with_gnu_ld"; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test yes = "$lt_use_gnu_ld_interface"; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='$wl'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test ia64 != "$host_cpu"; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test linux-dietlibc = "$host_os"; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test no = "$tmp_diet"
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
+ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ tcc*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
+ ;;
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # traditional, no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ ;;
+ esac
+
+ if test yes = "$GCC"; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ ;;
+
+ hpux10*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+ _LT_TAGVAR(module_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags $fix_hardcoded_libdir_flag_ld'
+ _LT_TAGVAR(module_cmds, $1)='$LD -b -o $lib $libobjs $deplibs $linker_flags $fix_hardcoded_libdir_flag_ld'
+ fi
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir $fix_hardcoded_libdir_flag'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ # gcc-3.0.1 (collect2) breaks on -Wl,+cdp.
+ # HP-cc ignores -Wl,+cdp, and we test the linker for +cdp support.
+ AC_CACHE_CHECK([if +cdp linker flag works],
+ [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)],
+ [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,+cdp -Wl,/usr/lib/libc.1:/nonexistent -Wl,+cdp -Wl,/lib/libc.1:/nonexistent"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=yes],
+ [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=no])
+ LDFLAGS="$save_LDFLAGS"
+ ])
+ if test "$_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)" = yes; then
+ _LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)='${wl}+cdp ${wl}${linkdir}/${dlname}:${libdir}/${dlname}'
+ _LT_TAGVAR(fix_hardcoded_libdir_flag_spec_ld, $1)='+cdp ${linkdir}/${dlname}:${libdir}/${dlname}'
+ fi
+ fi
+ ;;
+
+ hpux11*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(module_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(module_cmds, $1)='$CC -shared $pic_flag $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+ _LT_TAGVAR(module_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(module_cmds, $1)='$CC -b -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(module_cmds, $1)='$CC -b $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ m4_if($1, [], [
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ _LT_LINKER_OPTION([if $CC understands -b],
+ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+ [
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+ _LT_TAGVAR(module_cmds, $1)='$CC -b -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+ ], [
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags $fix_hardcoded_libdir_flag_ld'
+ _LT_TAGVAR(module_cmds, $1)='$LD -b -o $lib $libobjs $deplibs $linker_flags $fix_hardcoded_libdir_flag_ld'
+ ])],
+ [
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+ _LT_TAGVAR(module_cmds, $1)='$CC -b -o $lib $libobjs $deplibs $compiler_flags $fix_hardcoded_libdir_flag'
+ ])
+ ;;
+ esac
+ fi
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir $fix_hardcoded_libdir_flag'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ # gcc-3.0.1 (collect2) breaks on -Wl,+cdp.
+ # HP-cc ignores -Wl,+cdp, and we test the linker for +cdp support.
+ AC_CACHE_CHECK([if +cdp linker flag works],
+ [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)],
+ [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,+cdp -Wl,/usr/lib/libc.1:/nonexistent -Wl,+cdp -Wl,/lib/libc.1:/nonexistent"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=yes],
+ [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=no])
+ LDFLAGS="$save_LDFLAGS"
+ ])
+ if test "$_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)" = yes; then
+ _LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)='${wl}+cdp ${wl}${linkdir}/${dlname}:${libdir}/${dlname}'
+ _LT_TAGVAR(fix_hardcoded_libdir_flag_spec_ld, $1)='+cdp ${linkdir}/${dlname}:${libdir}/${dlname}'
+ fi
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+ [lt_cv_irix_exported_symbol],
+ [save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE(
+ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+ [C++], [[int foo (void) { return 0; }]],
+ [Fortran 77], [[
+ subroutine foo
+ end]],
+ [Fortran], [[
+ subroutine foo
+ end]])])],
+ [lt_cv_irix_exported_symbol=yes],
+ [lt_cv_irix_exported_symbol=no])
+ LDFLAGS=$save_LDFLAGS])
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ linux*)
+ case $cc_basename in
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ osf3*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test sequent = "$host_vendor"; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test sni = "$host_vendor"; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+ [$RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ ])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting $shlibpath_var if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [fix_hardcoded_libdir_flag_spec], [1],
+ [Flag to modify a path being hardcoded into the resulting binary])
+_LT_TAGDECL([], [fix_hardcoded_libdir_flag_spec_ld], [1],
+ [If ld is used when linking, flag to modify a path being hardcoded into the resulting binary])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+ [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC=$CC
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report what library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC=$lt_save_CC
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test no != "$CXX" &&
+ ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
+ (test g++ != "$CXX"))); then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)=
+_LT_TAGVAR(fix_hardcoded_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_caught_CXX_error"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test yes = "$GXX"; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test yes = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='$wl'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ ;;
+ esac
+
+ if test yes = "$GXX"; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag=$shared_flag' $wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ # The "-G" linker flag allows undefined symbols.
+ _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared
+ # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir $fix_hardcoded_libdir_flag'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ # gcc-3.0.1 (collect2) breaks on -Wl,+cdp.
+ # HP-aCC ignores -Wl,+cdp, and we test the linker for +cdp support.
+ AC_CACHE_CHECK([if +cdp linker flag works],
+ [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)],
+ [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,+cdp -Wl,/usr/lib/libc.1:/nonexistent -Wl,+cdp -Wl,/lib/libc.1:/nonexistent"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=yes],
+ [_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)=no])
+ LDFLAGS="$save_LDFLAGS"
+ ])
+ if test "$_LT_TAGVAR(lt_cv_ldflag_cdp_works, $1)" = yes; then
+ _LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)='${wl}+cdp ${wl}${linkdir}/${dlname}:${libdir}/${dlname}'
+ fi
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $fix_hardcoded_libdir_flag'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $fix_hardcoded_libdir_flag'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require '-G' NOT '-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+ '"$_LT_TAGVAR(reload_cmds, $1)"
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)=$GXX
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test yes != "$_lt_caught_CXX_error"
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+ case @S|@2 in
+ .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
+ *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+ esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case $prev$p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test x-L = "$p" ||
+ test x-R = "$p"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test no = "$pre_test_object_deps_done"; then
+ case $prev in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)=$prev$p
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test no = "$pre_test_object_deps_done"; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)=$p
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)=$p
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test no = "$F77"; then
+ _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)=
+_LT_TAGVAR(fix_hardcoded_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(fix_hardcoded_libdir_flag_spec, $1)=
+_LT_TAGVAR(fix_hardcoded_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_F77"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)=$G77
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_F77"
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test no = "$FC"; then
+ _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_FC"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${FC-"f95"}
+ CFLAGS=$FCFLAGS
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_FC"
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code=$lt_simple_compile_test_code
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f "$lt_ac_sed" && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test 10 -lt "$lt_ac_count" && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test "$lt_ac_count" -gt "$lt_ac_max"; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine what file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+ [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+ [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4
new file mode 100644
index 0000000..94b0829
--- /dev/null
+++ b/m4/ltoptions.m4
@@ -0,0 +1,437 @@
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 8 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option '$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
+ [_LT_WITH_AIX_SONAME([aix])])
+ ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the 'shared' and
+# 'disable-shared' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the 'static' and
+# 'disable-static' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the 'fast-install'
+# and 'disable-fast-install' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_AIX_SONAME([DEFAULT])
+# ----------------------------------
+# implement the --with-aix-soname flag, and support the `aix-soname=aix'
+# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
+# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
+m4_define([_LT_WITH_AIX_SONAME],
+[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
+shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[[5-9]]*,yes)
+ AC_MSG_CHECKING([which variant of shared library versioning to provide])
+ AC_ARG_WITH([aix-soname],
+ [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
+ [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
+ [case $withval in
+ aix|svr4|both)
+ ;;
+ *)
+ AC_MSG_ERROR([Unknown argument to --with-aix-soname])
+ ;;
+ esac
+ lt_cv_with_aix_soname=$with_aix_soname],
+ [AC_CACHE_VAL([lt_cv_with_aix_soname],
+ [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
+ with_aix_soname=$lt_cv_with_aix_soname])
+ AC_MSG_RESULT([$with_aix_soname])
+ if test aix != "$with_aix_soname"; then
+ # For the AIX way of multilib, we name the shared archive member
+ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+ # the AIX toolchain works better with OBJECT_MODE set (default 32).
+ if test 64 = "${OBJECT_MODE-32}"; then
+ shared_archive_member_spec=shr_64
+ else
+ shared_archive_member_spec=shr
+ fi
+ fi
+ ;;
+*)
+ with_aix_soname=aix
+ ;;
+esac
+
+_LT_DECL([], [shared_archive_member_spec], [0],
+ [Shared archive member basename, for filename based shared library versioning on AIX])dnl
+])# _LT_WITH_AIX_SONAME
+
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
+# LT_INIT options.
+# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for lt_pkg in $withval; do
+ IFS=$lt_save_ifs
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [pic_mode=m4_default([$1], [default])])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/m4/ltsugar.m4 b/m4/ltsugar.m4
new file mode 100644
index 0000000..48bc934
--- /dev/null
+++ b/m4/ltsugar.m4
@@ -0,0 +1,124 @@
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59, which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/m4/ltversion.m4 b/m4/ltversion.m4
new file mode 100644
index 0000000..fa04b52
--- /dev/null
+++ b/m4/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 4179 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.6])
+m4_define([LT_PACKAGE_REVISION], [2.4.6])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.6'
+macro_revision='2.4.6'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4
new file mode 100644
index 0000000..c6b26f8
--- /dev/null
+++ b/m4/lt~obsolete.m4
@@ -0,0 +1,99 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
diff --git a/m4/sudo.m4 b/m4/sudo.m4
new file mode 100644
index 0000000..f67ee56
--- /dev/null
+++ b/m4/sudo.m4
@@ -0,0 +1,496 @@
+dnl Local m4 macros for autoconf (used by sudo)
+dnl
+dnl Copyright (c) 1994-1996, 1998-2005, 2007-2015
+dnl Todd C. Miller <Todd.Miller@sudo.ws>
+dnl
+dnl XXX - should cache values in all cases!!!
+dnl
+dnl checks for programs
+
+dnl
+dnl check for sendmail in well-known locations
+dnl
+AC_ARG_VAR([SENDMAILPROG], [The fully-qualified path to the sendmail program to use.])
+AC_DEFUN([SUDO_PROG_SENDMAIL], [
+ AC_PATH_PROG([SENDMAILPROG], [sendmail], [], [/usr/sbin$PATH_SEPARATOR/usr/lib$PATH_SEPARATOR/usr/etc$PATH_SEPARATOR/usr/ucblib$PATH_SEPARATOR/usr/local/lib$PATH_SEPARATOR/usr/local/bin])
+ test -n "${ac_cv_path_SENDMAILPROG}" && SUDO_DEFINE_UNQUOTED(_PATH_SUDO_SENDMAIL, "${ac_cv_path_SENDMAILPROG}")
+])dnl
+
+dnl
+dnl check for vi in well-known locations
+dnl
+AC_ARG_VAR([VIPROG], [The fully-qualified path to the vi program to use.])
+AC_DEFUN([SUDO_PROG_VI], [
+ AC_PATH_PROG([VIPROG], [vi], [], [/usr/bin$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/ucb$PATH_SEPARATOR/usr/bsd$PATH_SEPARATOR/usr/local/bin])
+ test -n "${ac_cv_path_VIPROG}" && SUDO_DEFINE_UNQUOTED(_PATH_VI, "${ac_cv_path_VIPROG}")
+])dnl
+
+dnl
+dnl check for mv in well-known locations
+dnl
+AC_ARG_VAR([MVPROG], [The fully-qualified path to the mv program to use.])
+AC_DEFUN([SUDO_PROG_MV], [
+ AC_PATH_PROG([MVPROG], [mv], [], [/usr/bin$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/ucb$PATH_SEPARATOR/usr/local/bin])
+ test -n "${ac_cv_path_MVPROG}" && SUDO_DEFINE_UNQUOTED(_PATH_MV, "${ac_cv_path_MVPROG}")
+])dnl
+
+dnl
+dnl check for bourne shell in well-known locations
+dnl
+AC_ARG_VAR([BSHELLPROG], [The fully-qualified path to the Bourne shell to use.])
+AC_DEFUN([SUDO_PROG_BSHELL], [
+ AC_PATH_PROG([BSHELLPROG], [sh], [/usr/bin$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin])
+ test -n "${ac_cv_path_BSHELLPROG}" && SUDO_DEFINE_UNQUOTED(_PATH_BSHELL, "${ac_cv_path_BSHELLPROG}")
+])dnl
+
+dnl
+dnl check for utmp file
+dnl
+AC_DEFUN([SUDO_PATH_UTMP], [AC_MSG_CHECKING([for utmp file path])
+found=no
+for p in "/var/run/utmp" "/var/adm/utmp" "/etc/utmp"; do
+ if test -r "$p"; then
+ found=yes
+ AC_MSG_RESULT([$p])
+ SUDO_DEFINE_UNQUOTED(_PATH_UTMP, "$p")
+ break
+ fi
+done
+if test X"$found" != X"yes"; then
+ AC_MSG_RESULT([not found])
+fi
+])dnl
+
+dnl
+dnl Where the log file goes, use /var/log if it exists, else /{var,usr}/adm
+dnl
+AC_DEFUN([SUDO_LOGFILE], [AC_MSG_CHECKING(for log file location)
+if test -n "$with_logpath"; then
+ AC_MSG_RESULT($with_logpath)
+ SUDO_DEFINE_UNQUOTED(_PATH_SUDO_LOGFILE, "$with_logpath")
+elif test -d "/var/log"; then
+ AC_MSG_RESULT(/var/log/sudo.log)
+ SUDO_DEFINE(_PATH_SUDO_LOGFILE, "/var/log/sudo.log")
+elif test -d "/var/adm"; then
+ AC_MSG_RESULT(/var/adm/sudo.log)
+ SUDO_DEFINE(_PATH_SUDO_LOGFILE, "/var/adm/sudo.log")
+elif test -d "/usr/adm"; then
+ AC_MSG_RESULT(/usr/adm/sudo.log)
+ SUDO_DEFINE(_PATH_SUDO_LOGFILE, "/usr/adm/sudo.log")
+else
+ AC_MSG_RESULT(unknown, you will have to set _PATH_SUDO_LOGFILE by hand)
+fi
+])dnl
+
+dnl
+dnl Detect time zone file directory, if any.
+dnl
+AC_DEFUN([SUDO_TZDIR], [AC_MSG_CHECKING(time zone data directory)
+tzdir="$with_tzdir"
+if test -z "$tzdir"; then
+ tzdir=no
+ for d in /usr/share /usr/share/lib /usr/lib /etc; do
+ if test -d "$d/zoneinfo"; then
+ tzdir="$d/zoneinfo"
+ break
+ fi
+ done
+fi
+AC_MSG_RESULT([$tzdir])
+if test "${tzdir}" != "no"; then
+ SUDO_DEFINE_UNQUOTED(_PATH_ZONEINFO, "$tzdir")
+fi
+])dnl
+
+dnl
+dnl Parent directory for time stamp dir.
+dnl
+AC_DEFUN([SUDO_RUNDIR], [AC_MSG_CHECKING(for sudo run dir location)
+rundir="$with_rundir"
+if test -z "$rundir"; then
+ for d in /run /var/run /var/db /var/lib /var/adm /usr/adm; do
+ if test -d "$d"; then
+ rundir="$d/sudo"
+ break
+ fi
+ done
+fi
+AC_MSG_RESULT([$rundir])
+SUDO_DEFINE_UNQUOTED(_PATH_SUDO_TIMEDIR, "$rundir/ts")
+])dnl
+
+dnl
+dnl Parent directory for the lecture status dir.
+dnl
+AC_DEFUN([SUDO_VARDIR], [AC_MSG_CHECKING(for sudo var dir location)
+vardir="$with_vardir"
+if test -z "$vardir"; then
+ for d in /var/db /var/lib /var/adm /usr/adm; do
+ if test -d "$d"; then
+ vardir="$d/sudo"
+ break
+ fi
+ done
+fi
+AC_MSG_RESULT([$vardir])
+SUDO_DEFINE_UNQUOTED(_PATH_SUDO_LECTURE_DIR, "$vardir/lectured")
+])dnl
+
+dnl
+dnl Where the I/O log files go, use /var/log/sudo-io if
+dnl /var/log exists, else /{var,usr}/adm/sudo-io
+dnl
+AC_DEFUN([SUDO_IO_LOGDIR], [
+ AC_MSG_CHECKING(for I/O log dir location)
+ if test "${with_iologdir-yes}" != "yes"; then
+ iolog_dir="$with_iologdir"
+ elif test -d "/var/log"; then
+ iolog_dir="/var/log/sudo-io"
+ elif test -d "/var/adm"; then
+ iolog_dir="/var/adm/sudo-io"
+ else
+ iolog_dir="/usr/adm/sudo-io"
+ fi
+ if test "${with_iologdir}" != "no"; then
+ SUDO_DEFINE_UNQUOTED(_PATH_SUDO_IO_LOGDIR, "$iolog_dir")
+ fi
+ AC_MSG_RESULT($iolog_dir)
+])dnl
+
+dnl
+dnl check for working fnmatch(3)
+dnl
+AC_DEFUN([SUDO_FUNC_FNMATCH],
+[AC_MSG_CHECKING([for working fnmatch with FNM_CASEFOLD])
+AC_CACHE_VAL(sudo_cv_func_fnmatch,
+[rm -f conftestdata; > conftestdata
+AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <fnmatch.h>
+main() { exit(fnmatch("/*/bin/echo *", "/usr/bin/echo just a test", FNM_CASEFOLD)); }]])], [sudo_cv_func_fnmatch=yes], [sudo_cv_func_fnmatch=no],
+ [sudo_cv_func_fnmatch=no])
+rm -f core core.* *.core])
+AC_MSG_RESULT($sudo_cv_func_fnmatch)
+AS_IF([test $sudo_cv_func_fnmatch = yes], [$1], [$2])])
+
+dnl
+dnl Attempt to check for working PIE support.
+dnl This is a bit of a hack but on Solaris 10 with GNU ld and GNU as
+dnl we can end up with strange values from malloc().
+dnl A better check would be to verify that ASLR works with PIE.
+dnl
+AC_DEFUN([SUDO_WORKING_PIE],
+[AC_MSG_CHECKING([for working PIE support])
+AC_CACHE_VAL(sudo_cv_working_pie,
+[rm -f conftestdata; > conftestdata
+AC_RUN_IFELSE([AC_LANG_SOURCE([AC_INCLUDES_DEFAULT
+main() { char *p = malloc(1024); if (p == NULL) return 1; memset(p, 0, 1024); return 0; }])], [sudo_cv_working_pie=yes], [sudo_cv_working_pie=no],
+ [sudo_cv_working_pie=no])
+rm -f core core.* *.core])
+AC_MSG_RESULT($sudo_cv_working_pie)
+AS_IF([test $sudo_cv_working_pie = yes], [$1], [$2])])
+
+dnl
+dnl check for isblank(3)
+dnl
+AC_DEFUN([SUDO_FUNC_ISBLANK],
+ [AC_CACHE_CHECK([for isblank], [sudo_cv_func_isblank],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <ctype.h>]], [[return (isblank('a'));]])],
+ [sudo_cv_func_isblank=yes], [sudo_cv_func_isblank=no])])
+] [
+ if test "$sudo_cv_func_isblank" = "yes"; then
+ AC_DEFINE(HAVE_ISBLANK, 1, [Define if you have isblank(3).])
+ else
+ AC_LIBOBJ(isblank)
+ SUDO_APPEND_COMPAT_EXP(isblank)
+ fi
+])
+
+AC_DEFUN([SUDO_CHECK_LIB], [
+ _sudo_check_lib_extras=`echo "$5"|sed -e 's/[ ]*//g' -e 's/-l/_/g'`
+ AC_MSG_CHECKING([for $2 in -l$1${5+ }$5])
+ AC_CACHE_VAL([sudo_cv_lib_$1''_$2$_sudo_check_lib_extras], [
+ SUDO_CHECK_LIB_OLIBS="$LIBS"
+ LIBS="$LIBS -l$1${5+ }$5"
+ AC_LINK_IFELSE(
+ [AC_LANG_CALL([], [$2])],
+ [eval sudo_cv_lib_$1''_$2$_sudo_check_lib_extras=yes],
+ [eval sudo_cv_lib_$1''_$2$_sudo_check_lib_extras=no]
+ )
+ LIBS="$SUDO_CHECK_LIB_OLIBS"
+ ])
+ if eval test \$sudo_cv_lib_$1''_$2$_sudo_check_lib_extras = "yes"; then
+ AC_MSG_RESULT([yes])
+ $3
+ else
+ AC_MSG_RESULT([no])
+ $4
+ fi
+])
+
+dnl
+dnl check unsetenv() return value
+dnl
+AC_DEFUN([SUDO_FUNC_UNSETENV_VOID],
+ [AC_CACHE_CHECK([whether unsetenv returns void], [sudo_cv_func_unsetenv_void],
+ [AC_RUN_IFELSE([AC_LANG_PROGRAM(
+ [AC_INCLUDES_DEFAULT
+ int unsetenv();
+ ], [
+ [return unsetenv("FOO") != 0;]
+ ])
+ ],
+ [sudo_cv_func_unsetenv_void=no],
+ [sudo_cv_func_unsetenv_void=yes],
+ [sudo_cv_func_unsetenv_void=no])])
+ if test $sudo_cv_func_unsetenv_void = yes; then
+ AC_DEFINE(UNSETENV_VOID, 1,
+ [Define to 1 if the `unsetenv' function returns void instead of `int'.])
+ fi
+ ])
+
+dnl
+dnl check putenv() argument for const
+dnl
+AC_DEFUN([SUDO_FUNC_PUTENV_CONST],
+[AC_CACHE_CHECK([whether putenv takes a const argument],
+sudo_cv_func_putenv_const,
+[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
+int putenv(const char *string) {return 0;}], [])],
+ [sudo_cv_func_putenv_const=yes],
+ [sudo_cv_func_putenv_const=no])
+ ])
+ if test $sudo_cv_func_putenv_const = yes; then
+ AC_DEFINE(PUTENV_CONST, const, [Define to const if the `putenv' takes a const argument.])
+ else
+ AC_DEFINE(PUTENV_CONST, [])
+ fi
+])
+
+dnl
+dnl check whether au_close() takes 3 or 4 arguments
+dnl
+AC_DEFUN([SUDO_FUNC_AU_CLOSE_SOLARIS11],
+[AC_CACHE_CHECK([whether au_close() takes 4 arguments],
+sudo_cv_func_au_close_solaris11,
+[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
+#include <bsm/audit.h>
+#include <bsm/libbsm.h>
+#include <bsm/audit_uevents.h>
+
+int au_close(int d, int keep, au_event_t event, au_emod_t emod) {return 0;}], [])],
+ [sudo_cv_func_au_close_solaris11=yes],
+ [sudo_cv_func_au_close_solaris11=no])
+ ])
+ if test $sudo_cv_func_au_close_solaris11 = yes; then
+ AC_DEFINE(HAVE_AU_CLOSE_SOLARIS11, 1, [Define to 1 if the `au_close' functions takes 4 arguments like Solaris 11.])
+ fi
+])
+
+dnl
+dnl Check if the data argument for the sha2 functions is void * or u_char *
+dnl
+AC_DEFUN([SUDO_FUNC_SHA2_VOID_PTR],
+[AC_CACHE_CHECK([whether the data argument of SHA224Update() is void *],
+sudo_cv_func_sha2_void_ptr,
+[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
+#include <sha2.h>
+void SHA224Update(SHA2_CTX *context, const void *data, size_t len) {return;}], [])],
+ [sudo_cv_func_sha2_void_ptr=yes],
+ [sudo_cv_func_sha2_void_ptr=no])
+ ])
+ if test $sudo_cv_func_sha2_void_ptr = yes; then
+ AC_DEFINE(SHA2_VOID_PTR, 1,
+ [Define to 1 if the sha2 functions use `const void *' instead of `const unsigned char'.])
+ fi
+])
+
+dnl
+dnl check for sa_len field in struct sockaddr
+dnl
+AC_DEFUN([SUDO_SOCK_SA_LEN], [
+ AC_CHECK_MEMBER([struct sockaddr.sa_len],
+ [AC_DEFINE(HAVE_STRUCT_SOCKADDR_SA_LEN, 1, [Define if your struct sockaddr has an sa_len field.])],
+ [], [
+# include <sys/types.h>
+# include <sys/socket.h>]
+ )]
+)
+
+dnl
+dnl check for sin_len field in struct sockaddr_in
+dnl
+AC_DEFUN([SUDO_SOCK_SIN_LEN], [
+ AC_CHECK_MEMBER([struct sockaddr_in.sin_len],
+ [AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN_SIN_LEN, 1, [Define if your struct sockaddr_in has a sin_len field.])],
+ [], [
+# include <sys/types.h>
+# include <sys/socket.h>]
+ )]
+)
+
+dnl
+dnl check for max length of uid_t in string representation.
+dnl we can't really trust UID_MAX or MAXUID since they may exist
+dnl only for backwards compatibility.
+dnl
+AC_DEFUN([SUDO_UID_T_LEN],
+[AC_REQUIRE([AC_TYPE_UID_T])
+AC_MSG_CHECKING(max length of uid_t)
+AC_CACHE_VAL(sudo_cv_uid_t_len,
+[rm -f conftestdata
+AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <pwd.h>
+#include <limits.h>
+#include <sys/types.h>
+main() {
+ FILE *f;
+ char b[1024];
+ uid_t u = (uid_t) -1;
+
+ if ((f = fopen("conftestdata", "w")) == NULL)
+ exit(1);
+
+ (void) sprintf(b, "%lu", (unsigned long) u);
+ (void) fprintf(f, "%d\n", strlen(b));
+ (void) fclose(f);
+ exit(0);
+}]])], [sudo_cv_uid_t_len=`cat conftestdata`], [sudo_cv_uid_t_len=10], [sudo_cv_uid_t_len=10])
+])
+rm -f conftestdata
+AC_MSG_RESULT($sudo_cv_uid_t_len)
+AC_DEFINE_UNQUOTED(MAX_UID_T_LEN, $sudo_cv_uid_t_len, [Define to the max length of a uid_t in string context (excluding the NUL).])
+])
+
+dnl
+dnl There are three different utmp variants we need to check for.
+dnl SUDO_CHECK_UTMP_MEMBERS(utmp_type)
+dnl
+AC_DEFUN([SUDO_CHECK_UTMP_MEMBERS], [
+ dnl
+ dnl Check for utmp/utmpx/utmps struct members.
+ dnl
+ AC_CHECK_MEMBER([struct $1.ut_id], [
+ AC_DEFINE(HAVE_STRUCT_UTMP_UT_ID, 1, [Define to 1 if `ut_id' is a member of `struct utmp'.])
+ ], [], [
+# include <sys/types.h>
+# include <$1.h>
+ ])
+ AC_CHECK_MEMBER([struct $1.ut_pid], [
+ AC_DEFINE(HAVE_STRUCT_UTMP_UT_PID, 1, [Define to 1 if `ut_pid' is a member of `struct utmp'.])
+ ], [], [
+# include <sys/types.h>
+# include <$1.h>
+ ])
+ AC_CHECK_MEMBER([struct $1.ut_tv], [
+ AC_DEFINE(HAVE_STRUCT_UTMP_UT_TV, 1, [Define to 1 if `ut_tv' is a member of `struct utmp'.])
+ ], [], [
+# include <sys/types.h>
+# include <$1.h>
+ ])
+ AC_CHECK_MEMBER([struct $1.ut_type], [
+ AC_DEFINE(HAVE_STRUCT_UTMP_UT_TYPE, 1, [Define to 1 if `ut_type' is a member of `struct utmp'.])
+ ], [], [
+# include <sys/types.h>
+# include <$1.h>
+ ])
+ dnl
+ dnl Older struct utmp has ut_name instead of ut_user
+ dnl
+ if test "$1" = "utmp"; then
+ AC_CHECK_MEMBERS([struct utmp.ut_user], [], [], [
+# include <sys/types.h>
+# include <$1.h>
+ ])
+ fi
+ dnl
+ dnl Check for ut_exit.__e_termination first, then ut_exit.e_termination
+ dnl We need to have already defined _GNU_SOURCE on glibc which only has
+ dnl __e_termination visible when _GNU_SOURCE is *not* defined.
+ dnl
+ AC_CHECK_MEMBER([struct $1.ut_exit.__e_termination], [
+ AC_DEFINE(HAVE_STRUCT_UTMP_UT_EXIT, 1, [Define to 1 if `ut_exit' is a member of `struct utmp'.])
+ AC_DEFINE(HAVE_STRUCT_UTMP_UT_EXIT___E_TERMINATION, 1, [Define to 1 if `ut_exit.__e_termination' is a member of `struct utmp'.])
+ ], [
+ AC_CHECK_MEMBER([struct $1.ut_exit.e_termination], [
+ AC_DEFINE(HAVE_STRUCT_UTMP_UT_EXIT, 1, [Define to 1 if `ut_exit' is a member of `struct utmp'.])
+ AC_DEFINE(HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION, 1, [Define to 1 if `ut_exit.e_termination' is a member of `struct utmp'.])
+ ], [], [
+# include <sys/types.h>
+# include <$1.h>
+ ])
+ ], [
+# include <sys/types.h>
+# include <$1.h>
+ ])
+])
+
+dnl
+dnl Append a libpath to an LDFLAGS style variable if not already present.
+dnl Also appends to the _R version unless rpath is disabled.
+dnl
+AC_DEFUN([SUDO_APPEND_LIBPATH], [
+ AX_APPEND_FLAG([-L$2], [$1])
+ if test X"$enable_rpath" = X"yes"; then
+ AX_APPEND_FLAG([-R$2], [$1_R])
+ fi
+])
+
+dnl
+dnl Append one or more symbols to COMPAT_EXP
+dnl
+AC_DEFUN([SUDO_APPEND_COMPAT_EXP], [
+ for _sym in $1; do
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
+"
+ done
+])
+
+dnl
+dnl Determine the mail spool location
+dnl NOTE: must be run *after* check for paths.h
+dnl
+AC_DEFUN([SUDO_MAILDIR], [
+maildir=no
+if test X"$ac_cv_header_paths_h" = X"yes"; then
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
+#include <paths.h>],
+[char *p = _PATH_MAILDIR;])], [maildir=yes], [])
+fi
+if test $maildir = no; then
+ # Solaris has maillock.h which defines MAILDIR
+ AC_CHECK_HEADERS(maillock.h, [
+ SUDO_DEFINE(_PATH_MAILDIR, MAILDIR)
+ maildir=yes
+ ])
+ if test $maildir = no; then
+ for d in /var/mail /var/spool/mail /usr/spool/mail; do
+ if test -d "$d"; then
+ maildir=yes
+ SUDO_DEFINE_UNQUOTED(_PATH_MAILDIR, "$d")
+ break
+ fi
+ done
+ if test $maildir = no; then
+ # unable to find mail dir, hope for the best
+ SUDO_DEFINE_UNQUOTED(_PATH_MAILDIR, "/var/mail")
+ fi
+ fi
+fi
+])
+
+dnl
+dnl private versions of AC_DEFINE and AC_DEFINE_UNQUOTED that don't support
+dnl tracing that we use to define paths for pathnames.h so autoheader doesn't
+dnl put them in config.h.in. An awful hack.
+dnl
+m4_define([SUDO_DEFINE],
+[cat >>confdefs.h <<\EOF
+[@%:@define] $1 m4_if($#, 2, [$2], $#, 3, [$2], 1)
+EOF
+])
+
+m4_define([SUDO_DEFINE_UNQUOTED],
+[cat >>confdefs.h <<EOF
+[@%:@define] $1 m4_if($#, 2, [$2], $#, 3, [$2], 1)
+EOF
+])
diff --git a/mkdep.pl b/mkdep.pl
new file mode 100755
index 0000000..2040320
--- /dev/null
+++ b/mkdep.pl
@@ -0,0 +1,283 @@
+#!/usr/bin/env perl
+#
+# Copyright (c) 2011-2017 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+use File::Temp qw/ :mktemp /;
+use Fcntl;
+use warnings;
+
+die "usage: $0 [--builddir=dir] [--srcdir=dir] Makefile.in ...\n" unless $#ARGV >= 0;
+
+my @incpaths;
+my %dir_vars;
+my %implicit;
+my %generated;
+my $top_builddir = ".";
+my $top_srcdir;
+
+# Check for srcdir and/or builddir, if present
+while ($ARGV[0] =~ /^--(src|build)dir=(.*)/) {
+ if ($1 eq 'src') {
+ $top_srcdir = $2;
+ } else {
+ $top_builddir = $2;
+ }
+ shift @ARGV;
+}
+chdir($top_srcdir) if defined($top_srcdir);
+
+# Read in MANIFEST or fail if not present
+my %manifest;
+die "unable to open MANIFEST: $!\n" unless open(MANIFEST, "<MANIFEST");
+while (<MANIFEST>) {
+ chomp;
+ next unless /([^\/]+\.[cly])$/;
+ $manifest{$1} = $_;
+}
+
+foreach (@ARGV) {
+ mkdep($_);
+}
+
+sub fmt_depend {
+ my ($obj, $src) = @_;
+ my $ret;
+
+ my $deps = sprintf("%s: %s %s", $obj, $src,
+ join(' ', find_depends($src)));
+ if (length($deps) > 80) {
+ my $off = 0;
+ my $indent = length($obj) + 2;
+ while (length($deps) - $off > 80 - $indent) {
+ my $pos;
+ if ($off != 0) {
+ $ret .= ' ' x $indent;
+ $pos = rindex($deps, ' ', $off + 80 - $indent - 2);
+ } else {
+ $pos = rindex($deps, ' ', $off + 78);
+ }
+ $ret .= substr($deps, $off, $pos - $off) . " \\\n";
+ $off = $pos + 1;
+ }
+ $ret .= ' ' x $indent;
+ $ret .= substr($deps, $off) . "\n";
+ } else {
+ $ret = "$deps\n";
+ }
+
+ $ret;
+}
+
+sub mkdep {
+ my $file = $_[0];
+ $file =~ s:^\./+::; # strip off leading ./
+
+ my $makefile;
+ if (open(MF, "<$file")) {
+ local $/; # enable "slurp" mode
+ $makefile = <MF>;
+ } else {
+ warn "$0: $file: $!\n";
+ return undef;
+ }
+ close(MF);
+
+ # New makefile, minus the autogenerated dependencies
+ my $separator = "# Autogenerated dependencies, do not modify";
+ my $new_makefile = $makefile;
+ $new_makefile =~ s/${separator}.*$//s;
+ $new_makefile .= "$separator\n";
+
+ # Old makefile, join lines with continuation characters
+ $makefile =~ s/\\\n//mg;
+
+ # Expand some configure bits
+ $makefile =~ s:\@DEV\@::g;
+ $makefile =~ s:\@COMMON_OBJS\@:aix.lo event_poll.lo event_select.lo:;
+ $makefile =~ s:\@SUDO_OBJS\@:openbsd.o preload.o selinux.o sesh.o solaris.o:;
+ $makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo ldap_util.lo ldap_conf.lo solaris_audit.lo sssd.lo:;
+ # XXX - fill in AUTH_OBJS from contents of the auth dir instead
+ $makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
+ $makefile =~ s:\@DIGEST\@:digest.lo digest_openssl.lo digest_gcrypt.lo:;
+ $makefile =~ s:\@LTLIBOBJS\@:arc4random.lo arc4random_uniform.lo closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getentropy.lo getgrouplist.lo getline.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo strtonum.lo utimens.lo vsyslog.lo pipe2.lo:;
+
+ # Parse OBJS lines
+ my %objs;
+ while ($makefile =~ /^[A-Z0-9_]*OBJS\s*=\s*(.*)/mg) {
+ foreach (split/\s+/, $1) {
+ next if /^\$[\(\{].*[\)\}]$/; # skip included vars for now
+ $objs{$_} = 1;
+ }
+ }
+
+ # Find include paths
+ @incpaths = ();
+ while ($makefile =~ /-I(\S+)/mg) {
+ push(@incpaths, $1) unless $1 eq ".";
+ }
+
+ # Check for generated files
+ if ($makefile =~ /GENERATED\s*=\s*(.+)$/m) {
+ foreach (split(/\s+/, $1)) {
+ $generated{$_} = 1;
+ }
+ }
+
+ # Values of srcdir, top_srcdir, top_builddir, incdir
+ %dir_vars = ();
+ $file =~ m:^(.*)/+[^/]+:;
+ $dir_vars{'srcdir'} = $1 || '.';
+ $dir_vars{'devdir'} = $dir_vars{'srcdir'};
+ $dir_vars{'authdir'} = $dir_vars{'srcdir'} . "/auth";
+ $dir_vars{'builddir'} = $top_builddir . "/" . $dir_vars{'srcdir'};
+ $dir_vars{'top_srcdir'} = '.';
+ #$dir_vars{'top_builddir'} = '.';
+ $dir_vars{'incdir'} = 'include';
+
+ # Find implicit rules for generated .o and .lo files
+ %implicit = ();
+ while ($makefile =~ /^\.[ci]\.(l?o|i|plog):\s*\n\t+(.*)$/mg) {
+ $implicit{$1} = $2;
+ }
+
+ # Find existing .o and .lo dependencies
+ my %old_deps;
+ while ($makefile =~ /^(\w+\.l?o):\s*(\S+\.c)/mg) {
+ $old_deps{$1} = $2;
+ }
+
+ # Sort files so we do .lo files first
+ foreach my $obj (sort keys %objs) {
+ next unless $obj =~ /(\S+)\.(l?o)$/;
+ if ($2 eq "o" && exists($objs{"$1.lo"})) {
+ # We have both .lo and .o files, only the .lo should be used
+ warn "$file: $obj should be $1.lo\n";
+ } else {
+ # Use old depenencies when mapping objects to their source.
+ # If no old depenency, use the MANIFEST file to find the source.
+ my $src = $1 . '.c';
+ my $ext = $2;
+ if (exists $old_deps{$obj}) {
+ $src = $old_deps{$obj};
+ } elsif (exists $manifest{$src}) {
+ $src = $manifest{$src};
+ foreach (sort { length($b) <=> length($a) } keys %dir_vars) {
+ next if $_ eq "devdir";
+ last if $src =~ s:^\Q$dir_vars{$_}/\E:\$\($_\)/:;
+ }
+ } else {
+ warn "$file: unable to find source for $obj\n";
+ }
+ my $imp = $implicit{$ext};
+ $imp =~ s/\$</$src/g;
+
+ my $deps = fmt_depend($obj, $src);
+ $new_makefile .= $deps;
+ $new_makefile .= "\t$imp\n";
+
+ # PVS Studio files (.i and .plog)
+ $imp = $implicit{"i"};
+ if (exists $implicit{"i"} && exists $implicit{"plog"}) {
+ $imp = $implicit{"i"};
+ $deps =~ s/\.l?o/.i/;
+ $new_makefile .= $deps;
+ $new_makefile .= "\t$imp\n";
+
+ $imp = $implicit{"plog"};
+ $imp =~ s/ifile=\$<; *//;
+ $imp =~ s/\$\$\{ifile\%i\}c/$src/;
+ $obj =~ /(.*)\.[a-z]+$/;
+ $new_makefile .= "${1}.plog: ${1}.i\n";
+ $new_makefile .= "\t$imp\n";
+ }
+ }
+ }
+
+ my $newfile = $file . ".new";
+ if (!open(MF, ">$newfile")) {
+ warn("cannot open $newfile: $!\n");
+ } else {
+ print MF $new_makefile || warn("cannot write $newfile: $!\n");
+ close(MF) || warn("cannot close $newfile: $!\n");;
+ rename($newfile, $file);
+ }
+}
+
+exit(0);
+
+sub find_depends {
+ my $src = $_[0];
+ my ($deps, $code, %headers);
+
+ if ($src !~ /\//) {
+ # generated file, local to build dir
+ $src = "$dir_vars{'builddir'}/$src";
+ }
+
+ # resolve $(srcdir) etc.
+ foreach (keys %dir_vars) {
+ $src =~ s/\$[\(\{]$_[\)\}]/$dir_vars{$_}/g;
+ }
+
+ # find open source file and find headers used by it
+ if (!open(FILE, "<$src")) {
+ warn "unable to open $src\n";
+ return "";
+ }
+ local $/; # enable "slurp" mode
+ $code = <FILE>;
+ close(FILE);
+
+ # find all headers
+ while ($code =~ /^#\s*include\s+["<](\S+)[">]/mg) {
+ my ($hdr, $hdr_path) = find_header($1);
+ if (defined($hdr)) {
+ $headers{$hdr} = 1;
+ # Look for other includes in the .h file
+ foreach (find_depends($hdr_path)) {
+ $headers{$_} = 1;
+ }
+ }
+ }
+
+ sort keys %headers;
+}
+
+# find the path to a header file
+# returns path or undef if not found
+sub find_header {
+ my $hdr = $_[0];
+
+ # Look for .h.in files in top_builddir and build dir
+ return ("\$(top_builddir\)/$hdr", "./${hdr}.in") if -r "./${hdr}.in";
+ return ("./$hdr", "$dir_vars{'srcdir'}/${hdr}.in") if -r "$dir_vars{'srcdir'}/${hdr}.in";
+
+ if (exists $generated{$hdr}) {
+ my $hdr_path = $dir_vars{'devdir'} . '/' . $hdr;
+ return ('$(devdir)/' . $hdr, $hdr_path) if -r $hdr_path;
+ }
+ foreach my $inc (@incpaths) {
+ my $hdr_path = "$inc/$hdr";
+ # resolve variables in include path
+ foreach (keys %dir_vars) {
+ next if $_ eq "devdir";
+ $hdr_path =~ s/\$[\(\{]$_[\)\}]/$dir_vars{$_}/g;
+ }
+ return ("$inc/$hdr", $hdr_path) if -r $hdr_path;
+ }
+
+ undef;
+}
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755
index 0000000..0330343
--- /dev/null
+++ b/mkinstalldirs
@@ -0,0 +1,84 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+umask 022
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+
+# process command line arguments
+while test $# -gt 0 ; do
+ case $1 in
+ -h | --help | --h*) # -h for help
+ echo "$usage" 1>&2
+ exit 0
+ ;;
+ -m) # -m PERM arg
+ shift
+ test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+ dirmode=$1
+ shift
+ ;;
+ --) # stop option processing
+ shift
+ break
+ ;;
+ -*) # unknown option
+ echo "$usage" 1>&2
+ exit 1
+ ;;
+ *) # first non-opt arg
+ break
+ ;;
+ esac
+done
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case $pathcomp in
+ -*) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ else
+ if test ! -z "$dirmode"; then
+ echo "chmod $dirmode $pathcomp"
+ lasterr=""
+ chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+ if test ! -z "$lasterr"; then
+ errstatus=$lasterr
+ fi
+ fi
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# End:
+# mkinstalldirs ends here
diff --git a/mkpkg b/mkpkg
new file mode 100755
index 0000000..bd465e7
--- /dev/null
+++ b/mkpkg
@@ -0,0 +1,407 @@
+#!/bin/sh
+#
+# Copyright (c) 2010-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Build a binary package using polypkg
+# Usage: mkpkg [--debug] [--flavor flavor] [--platform platform] [--osversion ver]
+#
+
+# Make sure IFS is set to space, tab, newline in that order.
+space=' '
+tab=' '
+nl='
+'
+IFS=" $nl"
+
+# Parse arguments
+usage="usage: mkpkg [--debug] [--flavor flavor] [--platform platform] [--osversion ver]"
+debug=0
+flavor=vanilla
+crossbuild=false
+while test $# -gt 0; do
+ case "$1" in
+ --debug)
+ set -x
+ debug=1
+ PPFLAGS="--debug${PPFLAGS+$space}${PPFLAGS}"
+ ;;
+ --flavor=?*)
+ flavor=`echo "$1" | sed -n 's/^--flavor=\(.*\)/\1/p'`
+ PPVARS="${PPVARS}${PPVARS+$space}flavor=$flavor"
+ ;;
+ --flavor)
+ if [ $# -lt 2 ]; then
+ echo "$usage" 1>&2
+ exit 1
+ fi
+ flavor="$2"
+ PPVARS="${PPVARS}${PPVARS+$space}flavor=$flavor"
+ shift
+ ;;
+ --platform=?*)
+ arg=`echo "$1" | sed -n 's/^--platform=\(.*\)/\1/p'`
+ PPFLAGS="${PPFLAGS}${PPFLAGS+$space}--platform $arg"
+ ;;
+ --platform)
+ if [ $# -lt 2 ]; then
+ echo "$usage" 1>&2
+ exit 1
+ fi
+ PPFLAGS="${PPFLAGS}${PPFLAGS+$space}--platform $2"
+ shift
+ ;;
+ --osversion=?*)
+ arg=`echo "$1" | sed -n 's/^--osversion=\(.*\)/\1/p'`
+ osversion="$arg"
+ ;;
+ --osversion)
+ if [ $# -lt 2 ]; then
+ echo "$usage" 1>&2
+ exit 1
+ fi
+ osversion="$2"
+ shift
+ ;;
+ --build|--host)
+ crossbuild=true
+ configure_opts="${configure_opts}${configure_opts+$tab}$1"
+ ;;
+ *)
+ # Pass unknown options to configure
+ configure_opts="${configure_opts}${configure_opts+$tab}$1"
+ ;;
+ esac
+ shift
+done
+
+top_srcdir=`dirname $0`
+
+: ${osversion="`$top_srcdir/pp --probe`"}
+test -n "$osversion" || exit 1
+osrelease=`echo "$osversion" | sed -e 's/^[^0-9]*//' -e 's/-.*$//'`
+: ${MAKE=make}
+
+# If using GNU make, set number of jobs
+if ${MAKE} --version 2>&1 | grep GNU >/dev/null; then
+ NJOBS=0
+ case "`uname`" in
+ Darwin)
+ # macOS
+ NJOBS=`sysctl -n hw.ncpu`
+ ;;
+ Linux)
+ if [ -r /proc/cpuinfo ]; then
+ for c in `sed -n 's/^cpu cores[ ]*: *//p' /proc/cpuinfo`; do
+ NJOBS=`expr $NJOBS + $c`
+ done
+ fi
+ ;;
+ SunOS)
+ # Solaris
+ if [ -x /usr/sbin/psrinfo ]; then
+ NJOBS=`/usr/sbin/psrinfo | wc -l`
+ fi
+ ;;
+ HP-UX)
+ NJOBS=`sar -Mu 1 1 | awk 'END {print NR-5}'`
+ ;;
+ AIX)
+ NJOBS=`bindprocessor -q | awk '{print NF-4}'`
+ ;;
+ esac
+ if [ $NJOBS -gt 1 ]; then
+ make_opts="-j$NJOBS"
+ fi
+fi
+
+# Choose compiler options by osversion if not cross-compiling.
+if [ "$crossbuild" = "false" ]; then
+ case "$osversion" in
+ macos*)
+ # Use clang on macOS if present
+ if [ -z "$CC" -a -x /usr/bin/clang ]; then
+ CC=/usr/bin/clang; export CC
+ fi
+ ;;
+ sol[0-9]*)
+ # Use the Sun Studio C compiler on Solaris if possible
+ if [ -z "$CC" -a -x /usr/bin/cc ]; then
+ CC=/usr/bin/cc; export CC
+ if [ -z "$CFLAGS" ]; then
+ CFLAGS=-O; export CFLAGS
+ fi
+ fi
+ ;;
+ esac
+fi
+
+# Give configure a hint that we are building a package.
+# Some libc functions are only available on certain OS revisions.
+configure_opts="${configure_opts}${configure_opts+$tab}--enable-package-build"
+
+# Choose configure options by osversion.
+# We use the same configure options as vendor packages when possible.
+case "$osversion" in
+ centos*|rhel*|f[0-9]*)
+ case "$osversion" in
+ centos*|rhel*)
+ if [ $osrelease -ge 40 ]; then
+ # RHEL 4 and up support SELinux
+ with_selinux=true
+ if [ $osrelease -ge 50 ]; then
+ # RHEL 5 and up has audit support and uses a
+ # separate PAM config file for "sudo -i".
+ with_linux_audit=true
+ with_pam_login=true
+ if [ $osrelease -ge 60 ]; then
+ # RHEL 6 and above builds sudo with SSSD support
+ with_sssd=true
+ # RHEL 6 and above use /etc/sudo-ldap.conf
+ with_sudo_ldap_conf=true
+ fi
+ fi
+ fi
+ ;;
+ f[0-9]*)
+ # XXX - investigate which features were in which fedora version
+ with_selinux=true
+ with_linux_audit=true
+ with_pam_login=true
+ with_sssd=true
+ ;;
+ esac
+
+ if [ X"$with_selinux" = X"true" ]; then
+ configure_opts="${configure_opts}${configure_opts+$tab}--with-selinux"
+ fi
+ if [ X"$with_linux_audit" = X"true" ]; then
+ configure_opts="${configure_opts}${configure_opts+$tab}--with-linux-audit"
+ PPVARS="${PPVARS}${PPVARS+$space}linux_audit=1.4.0"
+ fi
+ if [ X"$with_pam_login" = X"true" ]; then
+ configure_opts="${configure_opts}${configure_opts+$tab}--with-pam-login"
+ fi
+ if [ X"$with_sssd" = X"true" ]; then
+ configure_opts="${configure_opts}${configure_opts+$tab}--with-sssd"
+ if test "`getconf LONG_BIT`" = "64"; then
+ # SSSD backend needs to know where to find the sssd lib
+ configure_opts="${configure_opts}${configure_opts+$tab}--with-sssd-lib=/usr/lib64"
+ fi
+ fi
+ if [ X"$with_sudo_ldap_conf" = X"true" ]; then
+ configure_opts="${configure_opts}${configure_opts+$tab}--with-ldap-conf-file=/etc/sudo-ldap.conf"
+ fi
+ # Note, must indent with tabs, not spaces due to IFS trickery
+ configure_opts="--prefix=/usr
+ --with-logging=syslog
+ --with-logfac=authpriv
+ --with-pam
+ --enable-zlib=system
+ --with-editor=/bin/vi
+ --with-env-editor
+ --with-ignore-dot
+ --with-tty-tickets
+ --with-ldap
+ --with-passprompt=[sudo] password for %p:
+ --with-sendmail=/usr/sbin/sendmail
+ $configure_opts"
+ ;;
+ sles*)
+ if [ $osrelease -ge 10 ]; then
+ # SLES 11 and higher has SELinux
+ if [ $osrelease -ge 11 ]; then
+ configure_opts="${configure_opts}${configure_opts+$tab}--with-selinux"
+ fi
+ fi
+ # SuSE doesn't have /usr/libexec
+ libexec=lib
+ case "$osversion" in
+ *64*) gcc -v 2>&1 | grep "with-cpu=[^ ]*32" >/dev/null || libexec=lib64
+ ;;
+ esac
+ # Note, must indent with tabs, not spaces due to IFS trickery
+ # XXX - SuSE uses secure path but only for env_reset
+ configure_opts="--prefix=/usr
+ --libexecdir=/usr/$libexec
+ --with-logging=syslog
+ --with-logfac=auth
+ --with-all-insults
+ --with-ignore-dot
+ --with-tty-tickets
+ --enable-shell-sets-home
+ --with-sudoers-mode=0440
+ --with-pam
+ --enable-zlib=system
+ --with-ldap
+ --with-env-editor
+ --with-passprompt=%p\'s password:
+ --with-sendmail=/usr/sbin/sendmail
+ $configure_opts"
+
+ make_opts="${make_opts}${make_opts+ }"'docdir=$(datarootdir)/doc/packages/$(PACKAGE_TARNAME)'
+ ;;
+ deb*|ubu*)
+ # Man pages should be compressed in .deb files
+ export MANCOMPRESS='gzip -9'
+ export MANCOMPRESSEXT='.gz'
+ # If Ubuntu, add --enable-admin-flag
+ case "$osversion" in
+ ubu*)
+ configure_opts="${configure_opts}${configure_opts+$tab}--enable-admin-flag${tab}--without-lecture"
+ ;;
+ esac
+ # Newer Debian uses arch-specific lib dirs
+ MULTIARCH=`dpkg-architecture -qDEB_HOST_MULTIARCH 2>/dev/null`
+ # Note, must indent with tabs, not spaces due to IFS trickery
+ if test "$flavor" = "ldap"; then
+ configure_opts="${configure_opts}${configure_opts+$tab}--with-ldap
+ --with-ldap-conf-file=/etc/sudo-ldap.conf"
+ else
+ configure_opts="${configure_opts}${configure_opts+$tab}--with-sssd"
+ if test -n "$MULTIARCH"; then
+ # SSSD backend needs to know where to find the sssd lib
+ configure_opts="${configure_opts}${configure_opts+$tab}--with-sssd-lib=/usr/lib/$MULTIARCH"
+ fi
+ fi
+ configure_opts="--prefix=/usr
+ --with-all-insults
+ --with-pam
+ --enable-zlib=system
+ --with-fqdn
+ --with-logging=syslog
+ --with-logfac=authpriv
+ --with-env-editor
+ --with-editor=/usr/bin/editor
+ --with-timeout=15
+ --with-password-timeout=0
+ --with-passprompt=[sudo] password for %p:
+ --disable-root-mailer
+ --with-sendmail=/usr/sbin/sendmail
+ --mandir=/usr/share/man
+ --libexecdir=/usr/lib
+ --with-selinux
+ --with-linux-audit
+ $configure_opts"
+ # Use correct libaudit dependency
+ for f in /lib/${MULTIARCH}${MULTIARCH:+/}libaudit.so.[0-9]* /lib/libaudit.so.[0-9]*; do
+ if test -f "$f"; then
+ linux_audit=`dpkg-query -S "$f" 2>/dev/null | sed -n 's/:.*//p'`
+ test -n "$linux_audit" && break;
+ fi
+ done
+ if [ -z "linux_audit" ]; then
+ echo "unable to determine package for libaudit" 1>&2
+ exit 1
+ fi
+ PPVARS="${PPVARS}${PPVARS+$space}linux_audit=$linux_audit"
+ ;;
+ macos*)
+ case "$osversion" in
+ macos10[0-6]-i386|macos10[0-6]-x86_64)
+ # Build intel universal binaries for 10.6 and below
+ ARCH_FLAGS="-arch i386 -arch x86_64"
+ ;;
+ esac
+ if test "${osversion}" != "`$top_srcdir/pp --probe`"; then
+ sdkvers=`echo "${osversion}" | sed 's/^macos\([0-9][0-9]\)\([0-9]*\)-.*$/\1.\2/'`
+ # Newer Xcode puts /Developer under the app Contents dir.
+ SDK_DIR="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs"
+ if test -d "${SDK_DIR}/MacOSX${sdkvers}.sdk"; then
+ SDK_DIR="${SDK_DIR}/MacOSX${sdkvers}.sdk"
+ elif test -d "/Developer/SDKs/MacOSX${sdkvers}.sdk"; then
+ SDK_DIR="/Developer/SDKs/MacOSX${sdkvers}.sdk"
+ fi
+ SDK_FLAGS="-isysroot ${SDK_DIR} -mmacosx-version-min=${sdkvers}"
+ fi
+ export CFLAGS="-O2 -g $ARCH_FLAGS $SDK_FLAGS"
+ export LDFLAGS="$ARCH_FLAGS $SDK_FLAGS"
+ # Note, must indent with tabs, not spaces due to IFS trickery
+ configure_opts="--with-pam
+ --with-bsm-audit
+ --without-tty-tickets
+ --enable-zlib=system
+ --with-ldap
+ --with-insults=disabled
+ --with-logging=syslog
+ --with-logfac=authpriv
+ --with-editor=/usr/bin/vim
+ --with-env-editor
+ $configure_opts"
+ ;;
+ aix*)
+ # Use -gxcoff with gcc instead of -g for dbx-style debugging symbols.
+ if test -z "$CC" && gcc -v >/dev/null 2>&1; then
+ CFLAGS=-gxcoff; export CFLAGS
+ fi
+ # Note, must indent with tabs, not spaces due to IFS trickery
+ # Note: we include our own zlib instead of relying on the
+ # AIX freeware version being installed.
+ configure_opts="
+ --prefix=/opt/freeware
+ --mandir=/opt/freeware/man
+ --with-insults=disabled
+ --with-logging=syslog
+ --with-logfac=auth
+ --with-editor=/usr/bin/vi
+ --with-env-editor
+ --enable-zlib=builtin
+ --disable-nls
+ --with-sendmail=/usr/sbin/sendmail
+ $configure_opts"
+ PPVARS="${PPVARS}${PPVARS+$space}aix_freeware=true"
+ ;;
+ *)
+ # For Solaris, add project support and use let configure choose zlib.
+ # For all others, use the builtin zlib and disable NLS support.
+ case "$osversion" in
+ sol*)
+ configure_opts="${configure_opts}${configure_opts+$tab}--with-project"
+
+ if [ $osrelease -ge 11 ]; then
+ configure_opts="${configure_opts}${configure_opts+$tab}--with-bsm-audit"
+ fi
+ ;;
+ *)
+ configure_opts="${configure_opts}${configure_opts+$tab}--enable-zlib=builtin${tab}--disable-nls"
+ ;;
+ esac
+ if test "$flavor" = "ldap"; then
+ configure_opts="${configure_opts}${configure_opts+$tab}--with-ldap"
+ fi
+ # Note, must indent with tabs, not spaces due to IFS trickery
+ configure_opts="
+ --with-insults=disabled
+ --with-logging=syslog
+ --with-logfac=auth
+ --with-editor=/usr/bin/vim:/usr/bin/vi:/bin/vi
+ --with-env-editor
+ $configure_opts"
+ ;;
+esac
+
+# The postinstall script will create tmpfiles.d/sudo.conf for us
+configure_opts="${configure_opts}${configure_opts+$tab}--disable-tmpfiles.d"
+
+# Remove spaces from IFS when setting $@ so that passprompt may include them
+OIFS="$IFS"
+IFS=" $nl"
+set -- $configure_opts $extra_opts
+IFS="$OIFS"
+if [ -r Makefile ]; then
+ ${MAKE} $make_opts distclean
+fi
+$top_srcdir/configure "$@" || exit 1
+${MAKE} $make_opts && ${MAKE} $make_opts PPFLAGS="$PPFLAGS" PPVARS="$PPVARS" package
+test $debug -eq 0 && rm -rf destdir
diff --git a/pathnames.h.in b/pathnames.h.in
new file mode 100644
index 0000000..31db3a4
--- /dev/null
+++ b/pathnames.h.in
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 1996, 1998, 1999, 2001, 2004, 2005, 2007-2014
+ * Todd C. Miller <Todd.Miller@sudo.ws>.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * Pathnames to programs and files used by sudo.
+ */
+
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+#endif /* HAVE_PATHS_H */
+
+#ifdef HAVE_MAILLOCK_H
+# include <maillock.h>
+#endif /* HAVE_MAILLOCK_H */
+
+#ifndef _PATH_DEV
+# define _PATH_DEV "/dev/"
+#endif /* _PATH_DEV */
+
+#ifndef _PATH_TTY
+# define _PATH_TTY _PATH_DEV "tty"
+#endif /* _PATH_TTY */
+
+#ifndef _PATH_DEVNULL
+# define _PATH_DEVNULL _PATH_DEV "null"
+#endif /* _PATH_DEVNULL */
+
+#ifndef _PATH_DEFPATH
+# define _PATH_DEFPATH "/usr/bin:/bin"
+#endif /* _PATH_DEFPATH */
+
+#ifndef _PATH_STDPATH
+# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin"
+#endif /* _PATH_STDPATH */
+
+#ifndef _PATH_ENVIRONMENT
+# define _PATH_ENVIRONMENT "/etc/environment"
+#endif /* _PATH_ENVIRONMENT */
+
+/*
+ * NOTE: _PATH_SUDO_CONF is usually overridden by the Makefile.
+ */
+#ifndef _PATH_SUDO_CONF
+# define _PATH_SUDO_CONF "/etc/sudo.conf"
+#endif /* _PATH_SUDO_CONF */
+
+/*
+ * NOTE: _PATH_SUDOERS is usually overridden by the Makefile.
+ */
+#ifndef _PATH_SUDOERS
+# define _PATH_SUDOERS "/etc/sudoers"
+#endif /* _PATH_SUDOERS */
+
+/*
+ * NOTE: _PATH_CVTSUDOERS_CONF is usually overridden by the Makefile.
+ */
+#ifndef _PATH_CVTSUDOERS_CONF
+# define _PATH_CVTSUDOERS_CONF "/etc/cvtsudoers.conf"
+#endif /* _PATH_CVTSUDOERS_CONF */
+
+/*
+ * The following paths are controlled via the configure script.
+ */
+
+/*
+ * Where to store the time stamp files. Defaults to /var/run/sudo/ts,
+ * /var/db/sudo/ts, /var/lib/sudo/ts, /var/adm/sudo/ts or /usr/adm/sudo/ts
+ * depending on what exists on the system.
+ */
+#ifndef _PATH_SUDO_TIMEDIR
+# undef _PATH_SUDO_TIMEDIR
+#endif /* _PATH_SUDO_TIMEDIR */
+
+/*
+ * Where to store the lecture status files. Defaults to /var/db/sudo/lectured,
+ * /var/lib/sudo/lectured, /var/adm/sudo/lectured or /usr/adm/sudo/lectured
+ * depending on what exists on the system.
+ */
+#ifndef _PATH_SUDO_LECTURE_DIR
+# undef _PATH_SUDO_LECTURE_DIR
+#endif /* _PATH_SUDO_LECTURE_DIR */
+
+/*
+ * Where to put the I/O log files. Defaults to /var/log/sudo-io,
+ * /var/adm/sudo-io or /usr/adm/sudo-io depending on what exists.
+ */
+#ifndef _PATH_SUDO_IO_LOGDIR
+# undef _PATH_SUDO_IO_LOGDIR
+#endif /* _PATH_SUDO_IO_LOGDIR */
+
+/*
+ * Where to put the sudo log file when logging to a file. Defaults to
+ * /var/log/sudo.log if /var/log exists, else /var/adm/sudo.log.
+ */
+#ifndef _PATH_SUDO_LOGFILE
+# undef _PATH_SUDO_LOGFILE
+#endif /* _PATH_SUDO_LOGFILE */
+
+#ifndef _PATH_SUDO_SENDMAIL
+# undef _PATH_SUDO_SENDMAIL
+#endif /* _PATH_SUDO_SENDMAIL */
+
+#ifndef _PATH_SUDO_NOEXEC
+# undef _PATH_SUDO_NOEXEC
+#endif /* _PATH_SUDO_NOEXEC */
+
+#ifndef _PATH_SUDO_ASKPASS
+# undef _PATH_SUDO_ASKPASS
+#endif /* _PATH_SUDO_ASKPASS */
+
+#ifndef _PATH_SUDO_PLUGIN_DIR
+# undef _PATH_SUDO_PLUGIN_DIR
+#endif /* _PATH_SUDO_PLUGIN_DIR */
+
+#ifndef _PATH_SUDO_DEVSEARCH
+# undef _PATH_SUDO_DEVSEARCH
+#endif /* _PATH_SUDO_DEVSEARCH */
+
+#ifndef _PATH_VI
+# undef _PATH_VI
+#endif /* _PATH_VI */
+
+#ifndef _PATH_MV
+# undef _PATH_MV
+#endif /* _PATH_MV */
+
+#ifndef _PATH_BSHELL
+# undef _PATH_BSHELL
+#endif /* _PATH_BSHELL */
+
+#ifndef _PATH_TMP
+# define _PATH_TMP "/tmp/"
+#endif /* _PATH_TMP */
+
+#ifndef _PATH_VARTMP
+# define _PATH_VARTMP "/var/tmp/"
+#endif /* _PATH_VARTMP */
+
+#ifndef _PATH_USRTMP
+# define _PATH_USRTMP "/usr/tmp/"
+#endif /* _PATH_USRTMP */
+
+#ifndef _PATH_MAILDIR
+# undef _PATH_MAILDIR
+#endif /* _PATH_MAILDIR */
+
+#ifndef _PATH_UTMP
+# undef _PATH_UTMP
+#endif /* _PATH_UTMP */
+
+#ifndef _PATH_SUDO_SESH
+# undef _PATH_SUDO_SESH
+#endif /* _PATH_SUDO_SESH */
+
+#ifndef _PATH_LDAP_CONF
+# undef _PATH_LDAP_CONF
+#endif /* _PATH_LDAP_CONF */
+
+#ifndef _PATH_LDAP_SECRET
+# undef _PATH_LDAP_SECRET
+#endif /* _PATH_LDAP_SECRET */
+
+#ifndef _PATH_SSSD_CONF
+# undef _PATH_SSSD_CONF
+#endif /* _PATH_SSSD_CONF */
+
+#ifndef _PATH_SSSD_LIB
+# undef _PATH_SSSD_LIB
+#endif /* _PATH_SSSD_LIB */
+
+#ifndef _PATH_NSSWITCH_CONF
+# undef _PATH_NSSWITCH_CONF
+#endif /* _PATH_NSSWITCH_CONF */
+
+#ifndef _PATH_NETSVC_CONF
+# undef _PATH_NETSVC_CONF
+#endif /* _PATH_NETSVC_CONF */
+
+#ifndef _PATH_ZONEINFO
+# undef _PATH_ZONEINFO
+#endif /* _PATH_ZONEINFO */
+
+/* On AIX, _PATH_BSHELL in paths.h is /usr/bin/bsh but we want /usr/bin/sh */
+#ifndef _PATH_SUDO_BSHELL
+# if defined(_AIX) && defined(HAVE_PATHS_H)
+# define _PATH_SUDO_BSHELL "/usr/bin/sh"
+# else
+# define _PATH_SUDO_BSHELL _PATH_BSHELL
+# endif
+#endif /* _PATH_SUDO_BSHELL */
diff --git a/plugins/group_file/Makefile.in b/plugins/group_file/Makefile.in
new file mode 100644
index 0000000..b148fa9
--- /dev/null
+++ b/plugins/group_file/Makefile.in
@@ -0,0 +1,212 @@
+#
+# Copyright (c) 2010-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# @configure_input@
+#
+
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+devdir = @devdir@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+incdir = $(top_srcdir)/include
+cross_compiling = @CROSS_COMPILING@
+
+# Compiler & tools to use
+CC = @CC@
+LIBTOOL = @LIBTOOL@
+SED = @SED@
+AWK = @AWK@
+
+# Our install program supports extra flags...
+INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
+INSTALL_OWNER = -o $(install_uid) -g $(install_gid)
+INSTALL_BACKUP = @INSTALL_BACKUP@
+
+# Libraries
+LT_LIBS = $(top_builddir)/lib/util/libsudo_util.la
+LIBS = $(LT_LIBS)
+
+# C preprocessor flags
+CPPFLAGS = -I$(incdir) -I$(top_builddir) -I$(top_srcdir) @CPPFLAGS@
+
+# Usually -O and/or -g
+CFLAGS = @CFLAGS@
+
+# Flags to pass to the link stage
+LDFLAGS = @LDFLAGS@
+LT_LDFLAGS = @LT_LDFLAGS@ @LT_LDEXPORTS@
+
+# Flags to pass to libtool
+LTFLAGS = --tag=disable-static
+
+# Address sanitizer flags
+ASAN_CFLAGS = @ASAN_CFLAGS@
+ASAN_LDFLAGS = @ASAN_LDFLAGS@
+
+# PIE flags
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+
+# Stack smashing protection flags
+SSP_CFLAGS = @SSP_CFLAGS@
+SSP_LDFLAGS = @SSP_LDFLAGS@
+
+# cppcheck options, usually set in the top-level Makefile
+CPPCHECK_OPTS = -q --force --enable=warning,performance,portability --suppress=constStatement --error-exitcode=1 --inline-suppr -Dva_copy=va_copy -U__cplusplus -UQUAD_MAX -UQUAD_MIN -UUQUAD_MAX -U_POSIX_HOST_NAME_MAX -U_POSIX_PATH_MAX -U__NBBY -DNSIG=64
+
+# splint options, usually set in the top-level Makefile
+SPLINT_OPTS = -D__restrict= -checks
+
+# PVS-studio options
+PVS_CFG = $(top_srcdir)/PVS-Studio.cfg
+PVS_IGNORE = 'V707,V011,V002,V536'
+PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE)
+
+# Where to install things...
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+localstatedir = @localstatedir@
+plugindir = @PLUGINDIR@
+
+# File mode and map file to use for shared libraries/objects
+shlib_enable = @SHLIB_ENABLE@
+shlib_mode = @SHLIB_MODE@
+shlib_exp = $(srcdir)/group_file.exp
+shlib_map = group_file.map
+shlib_opt = group_file.opt
+
+# User and group ids the installed files should be "owned" by
+install_uid = 0
+install_gid = 0
+
+#### End of system configuration section. ####
+
+SHELL = @SHELL@
+
+OBJS = group_file.lo getgrent.lo
+
+IOBJS = $(OBJS:.lo=.i)
+
+POBJS = $(IOBJS:.i=.plog)
+
+LIBOBJDIR = $(top_builddir)/@ac_config_libobj_dir@/
+
+VERSION = @PACKAGE_VERSION@
+
+all: group_file.la
+
+Makefile: $(srcdir)/Makefile.in
+ cd $(top_builddir) && ./config.status --file plugins/group_file/Makefile
+
+.SUFFIXES: .c .h .i .lo .plog
+
+.c.lo:
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $<
+
+.c.i:
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+
+.i.plog:
+ ifile=$<; rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $${ifile%i}c --i-file $< --output-file $@
+
+$(shlib_map): $(shlib_exp)
+ @$(AWK) 'BEGIN { print "{\n\tglobal:" } { print "\t\t"$$0";" } END { print "\tlocal:\n\t\t*;\n};" }' $(shlib_exp) > $@
+
+$(shlib_opt): $(shlib_exp)
+ @$(SED) 's/^/+e /' $(shlib_exp) > $@
+
+group_file.la: $(OBJS) $(LT_LIBS) @LT_LDDEP@
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LDFLAGS) $(ASAN_LDFLAGS) $(SSP_LDFLAGS) $(LT_LDFLAGS) -o $@ $(OBJS) $(LIBS) -module -avoid-version -rpath $(plugindir) -shrext .so
+
+pre-install:
+
+install: install-plugin
+
+install-dirs:
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(plugindir)
+
+install-binaries:
+
+install-includes:
+
+install-doc:
+
+install-plugin: install-dirs group_file.la
+ if [ X"$(shlib_enable)" = X"yes" ]; then \
+ INSTALL_BACKUP='$(INSTALL_BACKUP)' $(LIBTOOL) $(LTFLAGS) --mode=install $(INSTALL) $(INSTALL_OWNER) -m $(shlib_mode) group_file.la $(DESTDIR)$(plugindir); \
+ fi
+
+uninstall:
+ -$(LIBTOOL) $(LTFLAGS) --mode=uninstall rm -f $(DESTDIR)$(plugindir)/group_file.la
+ -test -z "$(INSTALL_BACKUP)" || \
+ rm -f $(DESTDIR)$(plugindir)/group_file.so$(INSTALL_BACKUP)
+
+splint:
+ splint $(SPLINT_OPTS) -I$(incdir) -I$(top_builddir) -I$(top_srcdir) $(srcdir)/*.c
+
+cppcheck:
+ cppcheck $(CPPCHECK_OPTS) -I$(incdir) -I$(top_builddir) -I$(top_srcdir) $(srcdir)/*.c
+
+pvs-log-files: $(POBJS)
+
+pvs-studio: $(POBJS)
+ plog-converter $(PVS_LOG_OPTS) $(POBJS)
+
+check:
+
+clean:
+ -$(LIBTOOL) $(LTFLAGS) --mode=clean rm -f *.lo *.o *.la *.a *.i *.plog \
+ stamp-* core *.core core.*
+
+mostlyclean: clean
+
+distclean: clean
+ -rm -rf Makefile .libs $(shlib_map) $(shlib_opt)
+
+clobber: distclean
+
+realclean: distclean
+ rm -f TAGS tags
+
+cleandir: realclean
+
+# Autogenerated dependencies, do not modify
+getgrent.lo: $(srcdir)/getgrent.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getgrent.c
+getgrent.i: $(srcdir)/getgrent.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+getgrent.plog: getgrent.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getgrent.c --i-file $< --output-file $@
+group_file.lo: $(srcdir)/group_file.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_plugin.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/group_file.c
+group_file.i: $(srcdir)/group_file.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_plugin.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+group_file.plog: group_file.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/group_file.c --i-file $< --output-file $@
diff --git a/plugins/group_file/getgrent.c b/plugins/group_file/getgrent.c
new file mode 100644
index 0000000..bcfd17f
--- /dev/null
+++ b/plugins/group_file/getgrent.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2005,2008,2010-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+/*
+ * Trivial replacements for the libc getgr{uid,nam}() routines.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <fcntl.h>
+#include <limits.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+
+#undef GRMEM_MAX
+#define GRMEM_MAX 200
+
+static FILE *grf;
+static const char *grfile = "/etc/group";
+static int gr_stayopen;
+
+void mysetgrfile(const char *);
+void mysetgrent(void);
+void myendgrent(void);
+struct group *mygetgrent(void);
+struct group *mygetgrnam(const char *);
+struct group *mygetgrgid(gid_t);
+
+void
+mysetgrfile(const char *file)
+{
+ grfile = file;
+ if (grf != NULL)
+ myendgrent();
+}
+
+void
+mysetgrent(void)
+{
+ if (grf == NULL) {
+ grf = fopen(grfile, "r");
+ if (grf != NULL)
+ (void)fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
+ } else {
+ rewind(grf);
+ }
+ gr_stayopen = 1;
+}
+
+void
+myendgrent(void)
+{
+ if (grf != NULL) {
+ fclose(grf);
+ grf = NULL;
+ }
+ gr_stayopen = 0;
+}
+
+struct group *
+mygetgrent(void)
+{
+ static struct group gr;
+ static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
+ size_t len;
+ id_t id;
+ char *cp, *colon;
+ const char *errstr;
+ int n;
+
+next_entry:
+ if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
+ return NULL;
+
+ memset(&gr, 0, sizeof(gr));
+ if ((colon = strchr(cp = colon, ':')) == NULL)
+ goto next_entry;
+ *colon++ = '\0';
+ gr.gr_name = cp;
+ if ((colon = strchr(cp = colon, ':')) == NULL)
+ goto next_entry;
+ *colon++ = '\0';
+ gr.gr_passwd = cp;
+ if ((colon = strchr(cp = colon, ':')) == NULL)
+ goto next_entry;
+ *colon++ = '\0';
+ id = sudo_strtoid(cp, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ goto next_entry;
+ gr.gr_gid = (gid_t)id;
+ len = strlen(colon);
+ if (len > 0 && colon[len - 1] == '\n')
+ colon[len - 1] = '\0';
+ if (*colon != '\0') {
+ char *last;
+
+ gr.gr_mem = gr_mem;
+ cp = strtok_r(colon, ",", &last);
+ for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
+ gr.gr_mem[n] = cp;
+ cp = strtok_r(NULL, ",", &last);
+ }
+ gr.gr_mem[n++] = NULL;
+ } else
+ gr.gr_mem = NULL;
+ return &gr;
+}
+
+struct group *
+mygetgrnam(const char *name)
+{
+ struct group *gr;
+
+ if (grf == NULL) {
+ if ((grf = fopen(grfile, "r")) == NULL)
+ return NULL;
+ (void)fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
+ } else {
+ rewind(grf);
+ }
+ while ((gr = mygetgrent()) != NULL) {
+ if (strcmp(gr->gr_name, name) == 0)
+ break;
+ }
+ if (!gr_stayopen) {
+ fclose(grf);
+ grf = NULL;
+ }
+ return gr;
+}
+
+struct group *
+mygetgrgid(gid_t gid)
+{
+ struct group *gr;
+
+ if (grf == NULL) {
+ if ((grf = fopen(grfile, "r")) == NULL)
+ return NULL;
+ (void)fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
+ } else {
+ rewind(grf);
+ }
+ while ((gr = mygetgrent()) != NULL) {
+ if (gr->gr_gid == gid)
+ break;
+ }
+ if (!gr_stayopen) {
+ fclose(grf);
+ grf = NULL;
+ }
+ return gr;
+}
diff --git a/plugins/group_file/group_file.c b/plugins/group_file/group_file.c
new file mode 100644
index 0000000..f7621b3
--- /dev/null
+++ b/plugins/group_file/group_file.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2010-2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <grp.h>
+#include <pwd.h>
+
+#include "sudo_plugin.h"
+#include "sudo_compat.h"
+
+/*
+ * Sample sudoers group plugin that uses an extra group file with the
+ * same format as /etc/group.
+ */
+
+static sudo_printf_t sudo_log;
+
+extern void mysetgrfile(const char *);
+extern void mysetgrent(void);
+extern void myendgrent(void);
+extern struct group *mygetgrnam(const char *);
+
+static int
+sample_init(int version, sudo_printf_t sudo_printf, char *const argv[])
+{
+ struct stat sb;
+
+ sudo_log = sudo_printf;
+
+ if (SUDO_API_VERSION_GET_MAJOR(version) != GROUP_API_VERSION_MAJOR) {
+ sudo_log(SUDO_CONV_ERROR_MSG,
+ "group_file: incompatible major version %d, expected %d\n",
+ SUDO_API_VERSION_GET_MAJOR(version),
+ GROUP_API_VERSION_MAJOR);
+ return -1;
+ }
+
+ /* Sanity check the specified group file. */
+ if (argv == NULL || argv[0] == NULL) {
+ sudo_log(SUDO_CONV_ERROR_MSG,
+ "group_file: path to group file not specified\n");
+ return -1;
+ }
+ if (stat(argv[0], &sb) != 0) {
+ sudo_log(SUDO_CONV_ERROR_MSG,
+ "group_file: %s: %s\n", argv[0], strerror(errno));
+ return -1;
+ }
+ if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
+ sudo_log(SUDO_CONV_ERROR_MSG,
+ "%s must be only be writable by owner\n", argv[0]);
+ return -1;
+ }
+
+ mysetgrfile(argv[0]);
+ mysetgrent();
+
+ return true;
+}
+
+static void
+sample_cleanup(void)
+{
+ myendgrent();
+}
+
+/*
+ * Returns true if "user" is a member of "group", else false.
+ */
+static int
+sample_query(const char *user, const char *group, const struct passwd *pwd)
+{
+ struct group *grp;
+ char **member;
+
+ grp = mygetgrnam(group);
+ if (grp != NULL && grp->gr_mem != NULL) {
+ for (member = grp->gr_mem; *member != NULL; member++) {
+ if (strcasecmp(user, *member) == 0)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+__dso_public struct sudoers_group_plugin group_plugin = {
+ GROUP_API_VERSION,
+ sample_init,
+ sample_cleanup,
+ sample_query
+};
diff --git a/plugins/group_file/group_file.exp b/plugins/group_file/group_file.exp
new file mode 100644
index 0000000..a859d6c
--- /dev/null
+++ b/plugins/group_file/group_file.exp
@@ -0,0 +1 @@
+group_plugin
diff --git a/plugins/group_file/plugin_test.c b/plugins/group_file/plugin_test.c
new file mode 100644
index 0000000..129264a
--- /dev/null
+++ b/plugins/group_file/plugin_test.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2010-2013 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <limits.h>
+#include <pwd.h>
+
+#include "sudo_plugin.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+/*
+ * Simple driver to test sudoer group plugins.
+ * usage: plugin_test [-p "plugin.so plugin_args ..."] user:group ...
+ */
+
+static void *group_handle;
+static struct sudoers_group_plugin *group_plugin;
+
+static int
+plugin_printf(int msg_type, const char *fmt, ...)
+{
+ va_list ap;
+ FILE *fp;
+
+ switch (msg_type) {
+ case SUDO_CONV_INFO_MSG:
+ fp = stdout;
+ break;
+ case SUDO_CONV_ERROR_MSG:
+ fp = stderr;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ va_start(ap, fmt);
+ vfprintf(fp, fmt, ap);
+ va_end(ap);
+
+ return 0;
+}
+
+/*
+ * Load the specified plugin and run its init function.
+ * Returns -1 if unable to open the plugin, else it returns
+ * the value from the plugin's init function.
+ */
+static int
+group_plugin_load(char *plugin_info)
+{
+ char *args, path[PATH_MAX], savedch;
+ char **argv = NULL;
+ int rc;
+
+ /*
+ * Fill in .so path and split out args (if any).
+ */
+ if ((args = strpbrk(plugin_info, " \t")) != NULL) {
+ savedch = *args;
+ *args = '\0';
+ }
+ strncpy(path, plugin_info, sizeof(path) - 1);
+ path[sizeof(path) - 1] = '\0';
+ if (args != NULL)
+ *args++ = savedch;
+
+ /* Open plugin and map in symbol. */
+ group_handle = dlopen(path, RTLD_LAZY);
+ if (!group_handle) {
+ fprintf(stderr, "unable to dlopen %s: %s\n", path, dlerror());
+ return -1;
+ }
+ group_plugin = dlsym(group_handle, "group_plugin");
+ if (group_plugin == NULL) {
+ fprintf(stderr, "unable to find symbol \"group_plugin\" in %s\n", path);
+ return -1;
+ }
+
+ if (SUDO_API_VERSION_GET_MAJOR(group_plugin->version) != GROUP_API_VERSION_MAJOR) {
+ fprintf(stderr,
+ "%s: incompatible group plugin major version %d, expected %d\n",
+ path, SUDO_API_VERSION_GET_MAJOR(group_plugin->version),
+ GROUP_API_VERSION_MAJOR);
+ return -1;
+ }
+
+ /*
+ * Split args into a vector if specified.
+ */
+ if (args != NULL) {
+ int ac = 0, wasblank = 1;
+ char *cp;
+
+ for (cp = args; *cp != '\0'; cp++) {
+ if (isblank((unsigned char)*cp)) {
+ wasblank = 1;
+ } else if (wasblank) {
+ wasblank = 0;
+ ac++;
+ }
+ }
+ if (ac != 0) {
+ char *last;
+
+ argv = malloc(ac * sizeof(char *));
+ if (argv == NULL) {
+ perror(NULL);
+ return -1;
+ }
+ ac = 0;
+ for ((cp = strtok_r(args, " \t", &last)); cp != NULL; (cp = strtok_r(NULL, " \t", &last)))
+ argv[ac++] = cp;
+ }
+ }
+
+ rc = (group_plugin->init)(GROUP_API_VERSION, plugin_printf, argv);
+
+ free(argv);
+
+ return rc;
+}
+
+static void
+group_plugin_unload(void)
+{
+ (group_plugin->cleanup)();
+ dlclose(group_handle);
+ group_handle = NULL;
+}
+
+static int
+group_plugin_query(const char *user, const char *group,
+ const struct passwd *pwd)
+{
+ return (group_plugin->query)(user, group, pwd);
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ "usage: plugin_test [-p \"plugin.so plugin_args ...\"] user:group ...\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ch, i, found;
+ char *plugin = "group_file.so";
+ char *user, *group;
+ struct passwd *pwd;
+
+ while ((ch = getopt(argc, argv, "p:")) != -1) {
+ switch (ch) {
+ case 'p':
+ plugin = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1)
+ usage();
+
+ if (group_plugin_load(plugin) != 1) {
+ fprintf(stderr, "unable to load plugin: %s\n", plugin);
+ exit(1);
+ }
+
+ for (i = 0; argv[i] != NULL; i++) {
+ user = argv[i];
+ group = strchr(argv[i], ':');
+ if (group == NULL)
+ continue;
+ *group++ = '\0';
+ pwd = getpwnam(user);
+ found = group_plugin_query(user, group, pwd);
+ printf("user %s %s in group %s\n", user, found ? "is" : "NOT ", group);
+ }
+ group_plugin_unload();
+
+ exit(0);
+}
+
diff --git a/plugins/sample/Makefile.in b/plugins/sample/Makefile.in
new file mode 100644
index 0000000..34a66b1
--- /dev/null
+++ b/plugins/sample/Makefile.in
@@ -0,0 +1,199 @@
+#
+# Copyright (c) 2011-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# @configure_input@
+#
+
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+devdir = @devdir@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+incdir = $(top_srcdir)/include
+cross_compiling = @CROSS_COMPILING@
+
+# Compiler & tools to use
+CC = @CC@
+LIBTOOL = @LIBTOOL@
+SED = @SED@
+AWK = @AWK@
+
+# Our install program supports extra flags...
+INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
+INSTALL_OWNER = -o $(install_uid) -g $(install_gid)
+INSTALL_BACKUP = @INSTALL_BACKUP@
+
+# Libraries
+LIBS = $(top_builddir)/lib/util/libsudo_util.la
+
+# C preprocessor flags
+CPPFLAGS = -I$(incdir) -I$(top_builddir) -I$(top_srcdir) @CPPFLAGS@
+
+# Usually -O and/or -g
+CFLAGS = @CFLAGS@
+
+# Flags to pass to the link stage
+LDFLAGS = @LDFLAGS@
+LT_LDFLAGS = @LT_LDFLAGS@ @LT_LDEXPORTS@
+
+# Flags to pass to libtool
+LTFLAGS = --tag=disable-static
+
+# Address sanitizer flags
+ASAN_CFLAGS = @ASAN_CFLAGS@
+ASAN_LDFLAGS = @ASAN_LDFLAGS@
+
+# PIE flags
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+
+# Stack smashing protection flags
+SSP_CFLAGS = @SSP_CFLAGS@
+SSP_LDFLAGS = @SSP_LDFLAGS@
+
+# cppcheck options, usually set in the top-level Makefile
+CPPCHECK_OPTS = -q --force --enable=warning,performance,portability --suppress=constStatement --error-exitcode=1 --inline-suppr -Dva_copy=va_copy -U__cplusplus -UQUAD_MAX -UQUAD_MIN -UUQUAD_MAX -U_POSIX_HOST_NAME_MAX -U_POSIX_PATH_MAX -U__NBBY -DNSIG=64
+
+# splint options, usually set in the top-level Makefile
+SPLINT_OPTS = -D__restrict= -checks
+
+# PVS-studio options
+PVS_CFG = $(top_srcdir)/PVS-Studio.cfg
+PVS_IGNORE = 'V707,V011,V002,V536'
+PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE)
+
+# Where to install things...
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+localstatedir = @localstatedir@
+plugindir = @PLUGINDIR@
+
+# File mode and map file to use for shared libraries/objects
+shlib_enable = @SHLIB_ENABLE@
+shlib_mode = @SHLIB_MODE@
+shlib_exp = $(srcdir)/sample_plugin.exp
+shlib_map = sample_plugin.map
+shlib_opt = sample_plugin.opt
+
+# User and group ids the installed files should be "owned" by
+install_uid = 0
+install_gid = 0
+
+#### End of system configuration section. ####
+
+SHELL = @SHELL@
+
+OBJS = sample_plugin.lo
+
+LIBOBJDIR = $(top_builddir)/@ac_config_libobj_dir@/
+
+VERSION = @PACKAGE_VERSION@
+
+all: sample_plugin.la
+
+Makefile: $(srcdir)/Makefile.in
+ cd $(top_builddir) && ./config.status --file plugins/sample/Makefile
+
+.SUFFIXES: .c .h .i .lo .plog
+
+.c.lo:
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $<
+
+.c.i:
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+
+.i.plog:
+ ifile=$<; rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $${ifile%i}c --i-file $< --output-file $@
+
+$(shlib_map): $(shlib_exp)
+ @$(AWK) 'BEGIN { print "{\n\tglobal:" } { print "\t\t"$$0";" } END { print "\tlocal:\n\t\t*;\n};" }' $(shlib_exp) > $@
+
+$(shlib_opt): $(shlib_exp)
+ @$(SED) 's/^/+e /' $(shlib_exp) > $@
+
+sample_plugin.la: $(OBJS) @LT_LDDEP@
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LDFLAGS) $(ASAN_LDFLAGS) $(SSP_LDFLAGS) $(LT_LDFLAGS) -o $@ $(OBJS) $(LIBS) -module -avoid-version -rpath $(plugindir) -shrext .so
+
+pre-install:
+
+install: install-plugin
+
+install-dirs:
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(plugindir)
+
+install-binaries:
+
+install-includes:
+
+install-doc:
+
+install-plugin: install-dirs sample_plugin.la
+ if [ X"$(shlib_enable)" = X"yes" ]; then \
+ INSTALL_BACKUP='$(INSTALL_BACKUP)' $(LIBTOOL) $(LTFLAGS) --mode=install $(INSTALL) $(INSTALL_OWNER) -m $(shlib_mode) sample_plugin.la $(DESTDIR)$(plugindir); \
+ fi
+
+uninstall:
+ -$(LIBTOOL) $(LTFLAGS) --mode=uninstall rm -f $(DESTDIR)$(plugindir)/sample_plugin.la
+ -test -z "$(INSTALL_BACKUP)" || \
+ rm -f $(DESTDIR)$(plugindir)/sample_plugin.so$(INSTALL_BACKUP)
+
+splint:
+ splint $(SPLINT_OPTS) -I$(incdir) -I$(top_builddir) -I$(top_srcdir) $(srcdir)/*.c
+
+cppcheck:
+ cppcheck $(CPPCHECK_OPTS) -I$(incdir) -I$(top_builddir) -I$(top_srcdir) $(srcdir)/*.c
+
+pvs-log-files: $(POBJS)
+
+pvs-studio: $(POBJS)
+ plog-converter $(PVS_LOG_OPTS) $(POBJS)
+
+check:
+
+clean:
+ -$(LIBTOOL) $(LTFLAGS) --mode=clean rm -f *.lo *.o *.la *.a *.i *.plog \
+ stamp-* core *.core core.*
+
+mostlyclean: clean
+
+distclean: clean
+ -rm -rf Makefile .libs $(shlib_map) $(shlib_opt)
+
+clobber: distclean
+
+realclean: distclean
+ rm -f TAGS tags
+
+cleandir: realclean
+
+# Autogenerated dependencies, do not modify
+sample_plugin.lo: $(srcdir)/sample_plugin.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sample_plugin.c
+sample_plugin.i: $(srcdir)/sample_plugin.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sample_plugin.plog: sample_plugin.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sample_plugin.c --i-file $< --output-file $@
diff --git a/plugins/sample/README b/plugins/sample/README
new file mode 100644
index 0000000..45c2b78
--- /dev/null
+++ b/plugins/sample/README
@@ -0,0 +1,23 @@
+This is a sample sudo policy plugin. See the sudo_plugin manual for
+information on writing your own plugin.
+
+The sample policy plugin is not built or installed by default. To
+build and install the plugin, change to the plugins/sample directory
+and run "make". It can be installed by running "make install" as
+the superuser from the same directory.
+
+To actually use the sample plugin, you'll need to modify the
+/etc/sudo.conf file. Caution: you should not make changes to
+/etc/sudo.conf without also having a root shell open repair things
+in case of an error. To enable the plugin, first comment out any
+existing policy Plugin line in /etc/sudo.conf, for example:
+
+ Plugin sudoers_policy sudoers.so
+
+Then add a line for the sample plugin:
+
+ Plugin sample_policy sample_plugin.so
+
+You may need to create /etc/sudo.conf if it does not already exist.
+
+Note that you may only have a single policy plugin defined.
diff --git a/plugins/sample/sample_plugin.c b/plugins/sample/sample_plugin.c
new file mode 100644
index 0000000..7baaa31
--- /dev/null
+++ b/plugins/sample/sample_plugin.c
@@ -0,0 +1,500 @@
+/*
+ * Copyright (c) 2010-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <grp.h>
+#include <pwd.h>
+#include <stdarg.h>
+
+#include <pathnames.h>
+#include "sudo_compat.h"
+#include "sudo_plugin.h"
+#include "sudo_util.h"
+
+/*
+ * Sample plugin module that allows any user who knows the password
+ * ("test") to run any command as root. Since there is no credential
+ * caching the validate and invalidate functions are NULL.
+ */
+
+#ifdef __TANDEM
+# define ROOT_UID 65535
+#else
+# define ROOT_UID 0
+#endif
+
+static struct plugin_state {
+ char **envp;
+ char * const *settings;
+ char * const *user_info;
+} plugin_state;
+static sudo_conv_t sudo_conv;
+static sudo_printf_t sudo_log;
+static FILE *input, *output;
+static uid_t runas_uid = ROOT_UID;
+static gid_t runas_gid = -1;
+static int use_sudoedit = false;
+
+/*
+ * Plugin policy open function.
+ */
+static int
+policy_open(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t sudo_printf, char * const settings[],
+ char * const user_info[], char * const user_env[], char * const args[])
+{
+ char * const *ui;
+ struct passwd *pw;
+ const char *runas_user = NULL;
+ struct group *gr;
+ const char *runas_group = NULL;
+
+ if (!sudo_conv)
+ sudo_conv = conversation;
+ if (!sudo_log)
+ sudo_log = sudo_printf;
+
+ if (SUDO_API_VERSION_GET_MAJOR(version) != SUDO_API_VERSION_MAJOR) {
+ sudo_log(SUDO_CONV_ERROR_MSG,
+ "the sample plugin requires API version %d.x\n",
+ SUDO_API_VERSION_MAJOR);
+ return -1;
+ }
+
+ /* Only allow commands to be run as root. */
+ for (ui = settings; *ui != NULL; ui++) {
+ if (strncmp(*ui, "runas_user=", sizeof("runas_user=") - 1) == 0) {
+ runas_user = *ui + sizeof("runas_user=") - 1;
+ }
+ if (strncmp(*ui, "runas_group=", sizeof("runas_group=") - 1) == 0) {
+ runas_group = *ui + sizeof("runas_group=") - 1;
+ }
+ if (strncmp(*ui, "progname=", sizeof("progname=") - 1) == 0) {
+ initprogname(*ui + sizeof("progname=") - 1);
+ }
+ /* Check to see if sudo was called as sudoedit or with -e flag. */
+ if (strncmp(*ui, "sudoedit=", sizeof("sudoedit=") - 1) == 0) {
+ if (strcasecmp(*ui + sizeof("sudoedit=") - 1, "true") == 0)
+ use_sudoedit = true;
+ }
+ /* This plugin doesn't support running sudo with no arguments. */
+ if (strncmp(*ui, "implied_shell=", sizeof("implied_shell=") - 1) == 0) {
+ if (strcasecmp(*ui + sizeof("implied_shell=") - 1, "true") == 0)
+ return -2; /* usage error */
+ }
+ }
+ if (runas_user != NULL) {
+ if ((pw = getpwnam(runas_user)) == NULL) {
+ sudo_log(SUDO_CONV_ERROR_MSG, "unknown user %s\n", runas_user);
+ return 0;
+ }
+ runas_uid = pw->pw_uid;
+ }
+ if (runas_group != NULL) {
+ if ((gr = getgrnam(runas_group)) == NULL) {
+ sudo_log(SUDO_CONV_ERROR_MSG, "unknown group %s\n", runas_group);
+ return 0;
+ }
+ runas_gid = gr->gr_gid;
+ }
+
+ /* Plugin state. */
+ plugin_state.envp = (char **)user_env;
+ plugin_state.settings = settings;
+ plugin_state.user_info = user_info;
+
+ return 1;
+}
+
+static char *
+find_in_path(char *command, char **envp)
+{
+ struct stat sb;
+ char *path, *path0, **ep, *cp;
+ char pathbuf[PATH_MAX], *qualified = NULL;
+
+ if (strchr(command, '/') != NULL)
+ return command;
+
+ path = _PATH_DEFPATH;
+ for (ep = plugin_state.envp; *ep != NULL; ep++) {
+ if (strncmp(*ep, "PATH=", 5) == 0) {
+ path = *ep + 5;
+ break;
+ }
+ }
+ path = path0 = strdup(path);
+ do {
+ if ((cp = strchr(path, ':')))
+ *cp = '\0';
+ snprintf(pathbuf, sizeof(pathbuf), "%s/%s", *path ? path : ".",
+ command);
+ if (stat(pathbuf, &sb) == 0) {
+ if (S_ISREG(sb.st_mode) && (sb.st_mode & 0000111)) {
+ qualified = pathbuf;
+ break;
+ }
+ }
+ path = cp + 1;
+ } while (cp != NULL);
+ free(path0);
+ return qualified ? strdup(qualified) : NULL;
+}
+
+static int
+check_passwd(void)
+{
+ struct sudo_conv_message msg;
+ struct sudo_conv_reply repl;
+
+ /* Prompt user for password via conversation function. */
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_type = SUDO_CONV_PROMPT_ECHO_OFF;
+ msg.msg = "Password: ";
+ memset(&repl, 0, sizeof(repl));
+ sudo_conv(1, &msg, &repl, NULL);
+ if (repl.reply == NULL) {
+ sudo_log(SUDO_CONV_ERROR_MSG, "missing password\n");
+ return false;
+ }
+ if (strcmp(repl.reply, "test") != 0) {
+ sudo_log(SUDO_CONV_ERROR_MSG, "incorrect password\n");
+ return false;
+ }
+ return true;
+}
+
+static char **
+build_command_info(const char *command)
+{
+ static char **command_info;
+ int i = 0;
+
+ /* Setup command info. */
+ command_info = calloc(32, sizeof(char *));
+ if (command_info == NULL)
+ return NULL;
+ if ((command_info[i++] = sudo_new_key_val("command", command)) == NULL ||
+ asprintf(&command_info[i++], "runas_euid=%ld", (long)runas_uid) == -1 ||
+ asprintf(&command_info[i++], "runas_uid=%ld", (long)runas_uid) == -1) {
+ return NULL;
+ }
+ if (runas_gid != (gid_t)-1) {
+ if (asprintf(&command_info[i++], "runas_gid=%ld", (long)runas_gid) == -1 ||
+ asprintf(&command_info[i++], "runas_egid=%ld", (long)runas_gid) == -1) {
+ return NULL;
+ }
+ }
+ if (use_sudoedit) {
+ command_info[i] = strdup("sudoedit=true");
+ if (command_info[i++] == NULL)
+ return NULL;
+ }
+#ifdef USE_TIMEOUT
+ command_info[i++] = "timeout=30";
+#endif
+ return command_info;
+}
+
+static char *
+find_editor(int nfiles, char * const files[], char **argv_out[])
+{
+ char *cp, *last, **ep, **nargv, *editor, *editor_path;
+ int ac, i, nargc, wasblank;
+
+ /* Lookup EDITOR in user's environment. */
+ editor = _PATH_VI;
+ for (ep = plugin_state.envp; *ep != NULL; ep++) {
+ if (strncmp(*ep, "EDITOR=", 7) == 0) {
+ editor = *ep + 7;
+ break;
+ }
+ }
+ editor = strdup(editor);
+ if (editor == NULL) {
+ sudo_log(SUDO_CONV_ERROR_MSG, "unable to allocate memory\n");
+ return NULL;
+ }
+
+ /*
+ * Split editor into an argument vector; editor is reused (do not free).
+ * The EDITOR environment variables may contain command
+ * line args so look for those and alloc space for them too.
+ */
+ nargc = 1;
+ for (wasblank = 0, cp = editor; *cp != '\0'; cp++) {
+ if (isblank((unsigned char) *cp))
+ wasblank = 1;
+ else if (wasblank) {
+ wasblank = 0;
+ nargc++;
+ }
+ }
+ /* If we can't find the editor in the user's PATH, give up. */
+ cp = strtok_r(editor, " \t", &last);
+ if (cp == NULL ||
+ (editor_path = find_in_path(editor, plugin_state.envp)) == NULL) {
+ free(editor);
+ return NULL;
+ }
+ if (editor_path != editor)
+ free(editor);
+ nargv = malloc((nargc + 1 + nfiles + 1) * sizeof(char *));
+ if (nargv == NULL) {
+ sudo_log(SUDO_CONV_ERROR_MSG, "unable to allocate memory\n");
+ free(editor_path);
+ return NULL;
+ }
+ for (ac = 0; cp != NULL && ac < nargc; ac++) {
+ nargv[ac] = cp;
+ cp = strtok_r(NULL, " \t", &last);
+ }
+ nargv[ac++] = "--";
+ for (i = 0; i < nfiles; )
+ nargv[ac++] = files[i++];
+ nargv[ac] = NULL;
+
+ *argv_out = nargv;
+ return editor_path;
+}
+
+/*
+ * Plugin policy check function.
+ * Simple example that prompts for a password, hard-coded to "test".
+ */
+static int
+policy_check(int argc, char * const argv[],
+ char *env_add[], char **command_info_out[],
+ char **argv_out[], char **user_env_out[])
+{
+ char *command;
+
+ if (!argc || argv[0] == NULL) {
+ sudo_log(SUDO_CONV_ERROR_MSG, "no command specified\n");
+ return false;
+ }
+
+ if (!check_passwd())
+ return false;
+
+ command = find_in_path(argv[0], plugin_state.envp);
+ if (command == NULL) {
+ sudo_log(SUDO_CONV_ERROR_MSG, "%s: command not found\n", argv[0]);
+ return false;
+ }
+
+ /* If "sudo vi" is run, auto-convert to sudoedit. */
+ if (strcmp(command, _PATH_VI) == 0)
+ use_sudoedit = true;
+
+ if (use_sudoedit) {
+ /* Rebuild argv using editor */
+ free(command);
+ command = find_editor(argc - 1, argv + 1, argv_out);
+ if (command == NULL) {
+ sudo_log(SUDO_CONV_ERROR_MSG, "unable to find valid editor\n");
+ return -1;
+ }
+ use_sudoedit = true;
+ } else {
+ /* No changes needd to argv */
+ *argv_out = (char **)argv;
+ }
+
+ /* No changes to envp */
+ *user_env_out = plugin_state.envp;
+
+ /* Setup command info. */
+ *command_info_out = build_command_info(command);
+ free(command);
+ if (*command_info_out == NULL) {
+ sudo_log(SUDO_CONV_ERROR_MSG, "out of memory\n");
+ return -1;
+ }
+
+ return true;
+}
+
+static int
+policy_list(int argc, char * const argv[], int verbose, const char *list_user)
+{
+ /*
+ * List user's capabilities.
+ */
+ sudo_log(SUDO_CONV_INFO_MSG, "Validated users may run any command\n");
+ return true;
+}
+
+static int
+policy_version(int verbose)
+{
+ sudo_log(SUDO_CONV_INFO_MSG, "Sample policy plugin version %s\n", PACKAGE_VERSION);
+ return true;
+}
+
+static void
+policy_close(int exit_status, int error)
+{
+ /*
+ * The policy might log the command exit status here.
+ * In this example, we just print a message.
+ */
+ if (error) {
+ sudo_log(SUDO_CONV_ERROR_MSG, "Command error: %s\n", strerror(error));
+ } else {
+ if (WIFEXITED(exit_status)) {
+ sudo_log(SUDO_CONV_INFO_MSG, "Command exited with status %d\n",
+ WEXITSTATUS(exit_status));
+ } else if (WIFSIGNALED(exit_status)) {
+ sudo_log(SUDO_CONV_INFO_MSG, "Command killed by signal %d\n",
+ WTERMSIG(exit_status));
+ }
+ }
+}
+
+static int
+io_open(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t sudo_printf, char * const settings[],
+ char * const user_info[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[], char * const args[])
+{
+ int fd;
+ char path[PATH_MAX];
+
+ if (!sudo_conv)
+ sudo_conv = conversation;
+ if (!sudo_log)
+ sudo_log = sudo_printf;
+
+ /* Open input and output files. */
+ snprintf(path, sizeof(path), "/var/tmp/sample-%u.output",
+ (unsigned int)getpid());
+ fd = open(path, O_WRONLY|O_CREAT|O_EXCL, 0644);
+ if (fd == -1)
+ return false;
+ output = fdopen(fd, "w");
+
+ snprintf(path, sizeof(path), "/var/tmp/sample-%u.input",
+ (unsigned int)getpid());
+ fd = open(path, O_WRONLY|O_CREAT|O_EXCL, 0644);
+ if (fd == -1)
+ return false;
+ input = fdopen(fd, "w");
+
+ return true;
+}
+
+static void
+io_close(int exit_status, int error)
+{
+ fclose(input);
+ fclose(output);
+}
+
+static int
+io_version(int verbose)
+{
+ sudo_log(SUDO_CONV_INFO_MSG, "Sample I/O plugin version %s\n",
+ PACKAGE_VERSION);
+ return true;
+}
+
+static int
+io_log_input(const char *buf, unsigned int len)
+{
+ ignore_result(fwrite(buf, len, 1, input));
+ return true;
+}
+
+static int
+io_log_output(const char *buf, unsigned int len)
+{
+ const char *cp, *ep;
+ bool ret = true;
+
+ ignore_result(fwrite(buf, len, 1, output));
+ /*
+ * If we find the string "honk!" in the buffer, reject it.
+ * In practice we'd want to be able to detect the word
+ * broken across two buffers.
+ */
+ for (cp = buf, ep = buf + len; cp < ep; cp++) {
+ if (cp + 5 < ep && memcmp(cp, "honk!", 5) == 0) {
+ ret = false;
+ break;
+ }
+ }
+ return ret;
+}
+
+__dso_public struct policy_plugin sample_policy = {
+ SUDO_POLICY_PLUGIN,
+ SUDO_API_VERSION,
+ policy_open,
+ policy_close,
+ policy_version,
+ policy_check,
+ policy_list,
+ NULL, /* validate */
+ NULL, /* invalidate */
+ NULL, /* init_session */
+ NULL, /* register_hooks */
+ NULL /* deregister_hooks */
+};
+
+/*
+ * Note: This plugin does not differentiate between tty and pipe I/O.
+ * It all gets logged to the same file.
+ */
+__dso_public struct io_plugin sample_io = {
+ SUDO_IO_PLUGIN,
+ SUDO_API_VERSION,
+ io_open,
+ io_close,
+ io_version,
+ io_log_input, /* tty input */
+ io_log_output, /* tty output */
+ io_log_input, /* command stdin if not tty */
+ io_log_output, /* command stdout if not tty */
+ io_log_output /* command stderr if not tty */
+};
diff --git a/plugins/sample/sample_plugin.exp b/plugins/sample/sample_plugin.exp
new file mode 100644
index 0000000..9f85094
--- /dev/null
+++ b/plugins/sample/sample_plugin.exp
@@ -0,0 +1,2 @@
+sample_policy
+sample_io
diff --git a/plugins/sudoers/Makefile.in b/plugins/sudoers/Makefile.in
new file mode 100644
index 0000000..e3f6bb5
--- /dev/null
+++ b/plugins/sudoers/Makefile.in
@@ -0,0 +1,2559 @@
+#
+# Copyright (c) 1996, 1998-2005, 2007-2018
+# Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Sponsored in part by the Defense Advanced Research Projects
+# Agency (DARPA) and Air Force Research Laboratory, Air Force
+# Materiel Command, USAF, under agreement number F39502-99-1-0512.
+#
+# @configure_input@
+#
+
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+devdir = @devdir@
+authdir = $(srcdir)/auth
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+incdir = $(top_srcdir)/include
+docdir = @docdir@
+libdir = @libdir@
+rundir = @rundir@
+vardir = @vardir@
+cross_compiling = @CROSS_COMPILING@
+
+# Compiler & tools to use
+CC = @CC@
+LIBTOOL = @LIBTOOL@
+FLEX = @FLEX@
+YACC = @YACC@
+SED = @SED@
+AWK = @AWK@
+PERL = perl
+
+# Our install program supports extra flags...
+INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
+INSTALL_OWNER = -o $(install_uid) -g $(install_gid)
+INSTALL_BACKUP = @INSTALL_BACKUP@
+
+# Libraries
+LT_LIBS = $(top_builddir)/lib/util/libsudo_util.la
+LIBS = $(LT_LIBS)
+NET_LIBS = @NET_LIBS@
+SUDOERS_LIBS = @SUDOERS_LIBS@ @AFS_LIBS@ @GETGROUPS_LIB@ $(LIBS) $(NET_LIBS) @ZLIB@
+REPLAY_LIBS = @REPLAY_LIBS@ @ZLIB@
+VISUDO_LIBS = $(NET_LIBS)
+CVTSUDOERS_LIBS = $(NET_LIBS)
+TESTSUDOERS_LIBS = $(NET_LIBS)
+
+# C preprocessor defines
+CPPDEFS = -DLIBDIR=\"$(libdir)\" -DLOCALEDIR=\"$(localedir)\" \
+ -D_PATH_SUDOERS=\"$(sudoersdir)/sudoers\" \
+ -D_PATH_CVTSUDOERS_CONF=\"$(sysconfdir)/cvtsudoers.conf\" \
+ -DSUDOERS_UID=$(sudoers_uid) -DSUDOERS_GID=$(sudoers_gid) \
+ -DSUDOERS_MODE=$(sudoers_mode)
+
+# C preprocessor flags
+CPPFLAGS = -I$(incdir) -I$(top_builddir) -I$(devdir) -I$(srcdir) \
+ -I$(top_srcdir) $(CPPDEFS) @CPPFLAGS@
+
+# Usually -O and/or -g
+CFLAGS = @CFLAGS@
+
+# Flags to pass to the link stage
+LDFLAGS = @LDFLAGS@
+LT_LDFLAGS = @SUDOERS_LDFLAGS@ @LT_LDFLAGS@ @LT_LDEXPORTS@
+
+# Flags to pass to libtool
+LTFLAGS =
+
+# Address sanitizer flags
+ASAN_CFLAGS = @ASAN_CFLAGS@
+ASAN_LDFLAGS = @ASAN_LDFLAGS@
+
+# PIE flags
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+
+# Stack smashing protection flags
+SSP_CFLAGS = @SSP_CFLAGS@
+SSP_LDFLAGS = @SSP_LDFLAGS@
+
+# cppcheck options, usually set in the top-level Makefile
+CPPCHECK_OPTS = -q --force --enable=warning,performance,portability --suppress=constStatement --error-exitcode=1 --inline-suppr -Dva_copy=va_copy -U__cplusplus -UQUAD_MAX -UQUAD_MIN -UUQUAD_MAX -U_POSIX_HOST_NAME_MAX -U_POSIX_PATH_MAX -U__NBBY -DNSIG=64
+
+# splint options, usually set in the top-level Makefile
+SPLINT_OPTS = -D__restrict= -checks
+
+# PVS-studio options
+PVS_CFG = $(top_srcdir)/PVS-Studio.cfg
+PVS_IGNORE = 'V707,V011,V002,V536'
+PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE)
+
+# Where to install things...
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+
+# File mode and map file to use for shared libraries/objects
+shlib_enable = @SHLIB_ENABLE@
+shlib_mode = @SHLIB_MODE@
+shlib_exp = $(srcdir)/sudoers.exp
+shlib_map = sudoers.map
+shlib_opt = sudoers.opt
+
+# Directory in which to install the sudoers plugin
+plugindir = @PLUGINDIR@
+
+# Directory in which to install the sudoers file
+sudoersdir = $(sysconfdir)
+
+# User and group ids the installed files should be "owned" by
+install_uid = 0
+install_gid = 0
+
+# User, group, and mode the sudoers file should be "owned" by (configure)
+sudoers_uid = @SUDOERS_UID@
+sudoers_gid = @SUDOERS_GID@
+sudoers_mode = @SUDOERS_MODE@
+
+# Set to non-empty for development mode
+DEVEL = @DEVEL@
+
+#### End of system configuration section. ####
+
+SHELL = @SHELL@
+
+PROGS = sudoers.la visudo sudoreplay cvtsudoers testsudoers
+
+TEST_PROGS = check_addr check_base64 check_digest check_env_pattern check_fill \
+ check_gentime check_hexchar check_iolog_path check_iolog_plugin \
+ check_iolog_util check_wrap check_starttime @SUDOERS_TEST_PROGS@
+
+AUTH_OBJS = sudo_auth.lo @AUTH_OBJS@
+
+LIBPARSESUDOERS_OBJS = alias.lo audit.lo base64.lo defaults.lo digestname.lo \
+ filedigest.lo gentime.lo gmtoff.lo gram.lo hexchar.lo \
+ match.lo match_addr.lo pwutil.lo pwutil_impl.lo \
+ rcstr.lo redblack.lo sudoers_debug.lo timeout.lo \
+ timestr.lo toke.lo toke_util.lo
+
+LIBPARSESUDOERS_IOBJS = $(LIBPARSESUDOERS_OBJS:.lo=.i) passwd.i
+
+SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo editor.lo env.lo \
+ env_pattern.lo file.lo find_path.lo fmtsudoers.lo gc.lo \
+ goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
+ iolog_path.lo locale.lo logging.lo logwrap.lo mkdir_parents.lo \
+ parse.lo policy.lo prompt.lo set_perms.lo starttime.lo \
+ sudo_nss.lo sudoers.lo timestamp.lo @SUDOERS_OBJS@
+
+SUDOERS_IOBJS = $(SUDOERS_OBJS:.lo=.i)
+
+VISUDO_OBJS = editor.lo find_path.lo goodpath.lo locale.lo stubs.o \
+ sudo_printf.o visudo.o
+
+VISUDO_IOBJS = sudo_printf.i visudo.i
+
+CVTSUDOERS_OBJS = cvtsudoers.o cvtsudoers_json.o cvtsudoers_ldif.o \
+ cvtsudoers_pwutil.o fmtsudoers.lo locale.lo parse_ldif.o \
+ strlist.o stubs.o sudo_printf.o ldap_util.lo
+
+CVTSUDOERS_IOBJS = cvtsudoers.i cvtsudoers_json.i cvtsudoers_ldif.i \
+ cvtsudoers_pwutil.i strlist.i
+
+REPLAY_OBJS = getdate.o sudoreplay.o iolog_util.o
+
+REPLAY_IOBJS = $(REPLAY_OBJS:.o=.i)
+
+TEST_OBJS = fmtsudoers.lo group_plugin.lo interfaces.lo ldap_util.lo \
+ locale.lo net_ifs.o parse_ldif.o strlist.o sudo_printf.o \
+ testsudoers.o tsgetgrpw.o
+
+IOBJS = $(LIBPARSESUDOERS_IOBJS) $(SUDOERS_IOBJS) $(VISUDO_IOBJS) \
+ $(CVTSUDOERS_IOBJS) $(REPLAY_IOBJS)
+
+POBJS = $(IOBJS:.i=.plog)
+
+TSDUMP_OBJS = tsdump.o sudoers_debug.lo locale.lo
+
+CHECK_ADDR_OBJS = check_addr.o interfaces.lo match_addr.lo sudoers_debug.lo \
+ sudo_printf.o
+
+CHECK_BASE64_OBJS = check_base64.o base64.lo sudoers_debug.lo
+
+CHECK_DIGEST_OBJS = check_digest.o filedigest.lo digestname.lo sudoers_debug.lo
+
+CHECK_ENV_MATCH_OBJS = check_env_pattern.o env_pattern.lo sudoers_debug.lo
+
+CHECK_FILL_OBJS = check_fill.o hexchar.lo toke_util.lo sudoers_debug.lo
+
+CHECK_GENTIME_OBJS = check_gentime.o gentime.lo gmtoff.lo sudoers_debug.lo
+
+CHECK_HEXCHAR_OBJS = check_hexchar.o hexchar.lo sudoers_debug.lo
+
+CHECK_IOLOG_PATH_OBJS = check_iolog_path.o iolog_path.lo locale.lo \
+ pwutil.lo pwutil_impl.lo redblack.lo sudoers_debug.lo
+
+CHECK_IOLOG_PLUGIN_OBJS = check_iolog_plugin.o iolog.lo iolog_path.lo \
+ iolog_util.o locale.lo mkdir_parents.lo pwutil.lo \
+ pwutil_impl.lo redblack.lo sudoers_debug.lo
+
+CHECK_IOLOG_UTIL_OBJS = check_iolog_util.o iolog_util.o locale.lo \
+ sudoers_debug.lo
+
+CHECK_SYMBOLS_OBJS = check_symbols.o
+
+CHECK_STARTTIME_OBJS = check_starttime.o starttime.lo sudoers_debug.lo
+
+CHECK_WRAP_OBJS = check_wrap.o logwrap.lo sudoers_debug.lo
+
+VERSION = @PACKAGE_VERSION@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+
+all: $(PROGS)
+
+.SUFFIXES: .c .h .i .l .lo .o .plog .y
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $<
+
+.c.lo:
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $<
+
+.c.i:
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+
+.i.plog:
+ ifile=$<; rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $${ifile%i}c --i-file $< --output-file $@
+
+$(shlib_map): $(shlib_exp)
+ @$(AWK) 'BEGIN { print "{\n\tglobal:" } { print "\t\t"$$0";" } END { print "\tlocal:\n\t\t*;\n};" }' $(shlib_exp) > $@
+
+$(shlib_opt): $(shlib_exp)
+ @$(SED) 's/^/+e /' $(shlib_exp) > $@
+
+# Prevent default rules from building .c files from .l and .y files
+.l.c:
+ @true
+
+.y.c:
+ @true
+
+Makefile: $(srcdir)/Makefile.in
+ cd $(top_builddir) && ./config.status --file plugins/sudoers/Makefile
+
+libparsesudoers.la: $(LIBPARSESUDOERS_OBJS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(LIBPARSESUDOERS_OBJS) -no-install
+
+sudoers.la: $(SUDOERS_OBJS) $(LT_LIBS) libparsesudoers.la @LT_LDDEP@
+ case "$(LT_LDFLAGS)" in \
+ *-no-install*) \
+ $(LIBTOOL) $(LTFLAGS) @LT_STATIC@ --mode=link $(CC) $(LDFLAGS) $(LT_LDFLAGS) -o $@ $(SUDOERS_OBJS) libparsesudoers.la $(SUDOERS_LIBS) -module;; \
+ *) \
+ $(LIBTOOL) $(LTFLAGS) @LT_STATIC@ --mode=link $(CC) $(LDFLAGS) $(ASAN_LDFLAGS) $(SSP_LDFLAGS) $(LT_LDFLAGS) -o $@ $(SUDOERS_OBJS) libparsesudoers.la $(SUDOERS_LIBS) -module -avoid-version -rpath $(plugindir) -shrext .so;; \
+ esac
+
+visudo: libparsesudoers.la $(VISUDO_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(VISUDO_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) libparsesudoers.la $(LIBS) $(VISUDO_LIBS)
+
+cvtsudoers: libparsesudoers.la $(CVTSUDOERS_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CVTSUDOERS_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) libparsesudoers.la $(LIBS) $(CVTSUDOERS_LIBS)
+
+sudoreplay: timestr.lo $(REPLAY_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(REPLAY_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) timestr.lo $(LIBS) $(REPLAY_LIBS)
+
+testsudoers: libparsesudoers.la $(TEST_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(TEST_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) libparsesudoers.la $(LIBS) $(TESTSUDOERS_LIBS)
+
+tsdump: $(TSDUMP_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(TSDUMP_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
+
+check_addr: $(CHECK_ADDR_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_ADDR_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS) $(NET_LIBS)
+
+check_base64: $(CHECK_BASE64_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_BASE64_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
+
+check_digest: $(CHECK_DIGEST_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_DIGEST_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
+
+check_env_pattern: $(CHECK_ENV_MATCH_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_ENV_MATCH_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
+
+check_fill: $(CHECK_FILL_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_FILL_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
+
+check_gentime: $(CHECK_GENTIME_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_GENTIME_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
+
+check_hexchar: $(CHECK_HEXCHAR_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_HEXCHAR_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
+
+check_iolog_path: $(CHECK_IOLOG_PATH_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_IOLOG_PATH_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
+
+check_iolog_plugin: $(CHECK_IOLOG_PLUGIN_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_IOLOG_PLUGIN_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS) @ZLIB@
+
+check_iolog_util: $(CHECK_IOLOG_UTIL_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_IOLOG_UTIL_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS) @ZLIB@
+
+check_starttime: $(CHECK_STARTTIME_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_STARTTIME_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
+
+# We need to link check_symbols with -lpthread on HP-UX since LDAP uses threads
+check_symbols: $(CHECK_SYMBOLS_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_SYMBOLS_OBJS) $(CHECK_SYMBOLS_LDFLAGS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS) @SUDO_LIBS@
+
+check_wrap: $(CHECK_WRAP_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_WRAP_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
+
+GENERATED = gram.h gram.c toke.c def_data.c def_data.h getdate.c
+
+prologue:
+ echo "/*" > $@
+ echo " * This is an open source non-commercial project. Dear PVS-Studio, please check it." >> $@
+ echo " * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com" >> $@
+ echo " */" >> $@
+ echo "" >> $@
+ echo "#include <config.h>" >> $@
+
+$(devdir)/gram.c $(devdir)/gram.h: $(srcdir)/gram.y prologue
+ @if [ -n "$(DEVEL)" ]; then \
+ if test "$(srcdir)" = "."; then \
+ gram_y="gram.y"; \
+ else \
+ gram_y="$(srcdir)/gram.y"; \
+ fi; \
+ cmd='$(YACC) -d -p sudoers '"$$gram_y"'; cp prologue $(devdir)/gram.c; $(SED) "s/^\\(#line .*\\) \"y\\.tab\\.c\"/\1 \"gram.c\"/" y.tab.c >> $(devdir)/gram.c; rm -f y.tab.c; mv -f y.tab.h $(devdir)/gram.h'; \
+ echo "$$cmd"; eval $$cmd; \
+ fi
+
+$(devdir)/toke.c: $(srcdir)/toke.l prologue
+ @if [ -n "$(DEVEL)" ]; then \
+ if test "$(srcdir)" = "."; then \
+ toke_l="toke.l"; \
+ else \
+ toke_l="$(srcdir)/toke.l"; \
+ fi; \
+ cmd='$(FLEX) '"$$toke_l"'; cp prologue $(devdir)/toke.c; $(SED) "s/^\\(#line .*\\) \"lex\\.sudoers\\.c\"/\1 \"toke.c\"/" lex.sudoers.c >> $(devdir)/toke.c; rm -f lex.sudoers.c'; \
+ echo "$$cmd"; eval $$cmd; \
+ fi
+
+$(devdir)/getdate.c: $(srcdir)/getdate.y prologue
+ @if [ -n "$(DEVEL)" ]; then \
+ echo "expect 10 shift/reduce conflicts"; \
+ if test "$(srcdir)" = "."; then \
+ getdate_y="getdate.y"; \
+ else \
+ getdate_y="$(srcdir)/getdate.y"; \
+ fi; \
+ cmd='$(YACC) '"$$getdate_y"'; cp prologue $(devdir)/getdate.c; $(SED) "s/^\\(#line .*\\) \"y\\.tab\\.c\"/\1 \"getdate.c\"/" y.tab.c >> $(devdir)/getdate.c; rm -f y.tab.c'; \
+ echo "$$cmd"; eval $$cmd; \
+ fi
+
+$(devdir)/def_data.c $(devdir)/def_data.h: $(srcdir)/def_data.in
+ @if [ -n "$(DEVEL)" ]; then \
+ cmd='$(PERL) $(srcdir)/mkdefaults -o $(devdir)/def_data $(srcdir)/def_data.in'; \
+ echo "$$cmd"; eval $$cmd; \
+ fi
+
+sudoers: $(srcdir)/sudoers.in
+ cd $(top_builddir) && $(SHELL) config.status --file=plugins/sudoers/$@
+
+pre-install:
+ @if test X"$(cross_compiling)" != X"yes" -a -r $(DESTDIR)$(sudoersdir)/sudoers; then \
+ echo "Checking existing sudoers file for syntax errors."; \
+ ./visudo -c -f $(DESTDIR)$(sudoersdir)/sudoers; \
+ fi
+
+install: install-plugin install-binaries install-sudoers install-doc
+
+install-dirs:
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(plugindir) \
+ $(DESTDIR)$(sbindir) $(DESTDIR)$(bindir) \
+ $(DESTDIR)$(sudoersdir) $(DESTDIR)$(docdir) \
+ `echo $(DESTDIR)$(rundir)|$(SED) 's,/[^/]*$$,,'` \
+ `echo $(DESTDIR)$(vardir)|$(SED) 's,/[^/]*$$,,'`
+ $(INSTALL) -d $(INSTALL_OWNER) -m 0711 $(DESTDIR)$(rundir)
+ $(INSTALL) -d $(INSTALL_OWNER) -m 0711 $(DESTDIR)$(vardir)
+ $(INSTALL) -d $(INSTALL_OWNER) -m 0700 $(DESTDIR)$(vardir)/lectured
+
+install-binaries: cvtsudoers sudoreplay visudo install-dirs
+ INSTALL_BACKUP='$(INSTALL_BACKUP)' $(LIBTOOL) $(LTFLAGS) --mode=install $(INSTALL) $(INSTALL_OWNER) -m 0755 cvtsudoers $(DESTDIR)$(bindir)/cvtsudoers
+ INSTALL_BACKUP='$(INSTALL_BACKUP)' $(LIBTOOL) $(LTFLAGS) --mode=install $(INSTALL) $(INSTALL_OWNER) -m 0755 sudoreplay $(DESTDIR)$(bindir)/sudoreplay
+ INSTALL_BACKUP='$(INSTALL_BACKUP)' $(LIBTOOL) $(LTFLAGS) --mode=install $(INSTALL) $(INSTALL_OWNER) -m 0755 visudo $(DESTDIR)$(sbindir)/visudo
+
+install-includes:
+
+install-doc:
+
+install-plugin: sudoers.la install-dirs
+ case "$(LT_LDFLAGS)" in \
+ *-no-install*) ;; \
+ *) if [ X"$(shlib_enable)" = X"yes" ]; then \
+ INSTALL_BACKUP='$(INSTALL_BACKUP)' $(LIBTOOL) $(LTFLAGS) --mode=install $(INSTALL) $(INSTALL_OWNER) -m $(shlib_mode) sudoers.la $(DESTDIR)$(plugindir); \
+ fi;; \
+ esac
+
+install-sudoers: install-dirs
+ $(INSTALL) -d $(INSTALL_OWNER) -m 0750 $(DESTDIR)$(sudoersdir)/sudoers.d
+ $(INSTALL) $(INSTALL_OWNER) -m $(sudoers_mode) sudoers $(DESTDIR)$(sudoersdir)/sudoers.dist
+ test -r $(DESTDIR)$(sudoersdir)/sudoers || \
+ cp -p $(DESTDIR)$(sudoersdir)/sudoers.dist $(DESTDIR)$(sudoersdir)/sudoers
+
+uninstall:
+ -$(LIBTOOL) $(LTFLAGS) --mode=uninstall rm -f $(DESTDIR)$(plugindir)/sudoers.la
+ -rm -f $(DESTDIR)$(bindir)/cvtsudoers \
+ $(DESTDIR)$(bindir)/sudoreplay
+ $(DESTDIR)$(sbindir)/visudo
+ -test -z "$(INSTALL_BACKUP)" || \
+ $(DESTDIR)$(bindir)/cvtsudoers$(INSTALL_BACKUP) \
+ $(DESTDIR)$(bindir)/sudoreplay$(INSTALL_BACKUP) \
+ $(DESTDIR)$(sbindir)/visudo$(INSTALL_BACKUP) \
+ $(DESTDIR)$(plugindir)/sudoers.so$(INSTALL_BACKUP)
+ -cmp $(DESTDIR)$(sudoersdir)/sudoers $(DESTDIR)$(sudoersdir)/sudoers.dist >/dev/null && \
+ rm -f $(DESTDIR)$(sudoersdir)/sudoers
+ -rm -f $(DESTDIR)$(sudoersdir)/sudoers.dist
+
+splint:
+ splint $(SPLINT_OPTS) -I$(incdir) -I$(top_builddir) -I$(devdir) -I$(srcdir) -I$(top_srcdir) $(srcdir)/*.c $(srcdir)/auth/*.c
+
+cppcheck:
+ cppcheck $(CPPCHECK_OPTS) -I$(incdir) -I$(top_builddir) -I$(devdir) -I$(srcdir) -I$(top_srcdir) $(srcdir)/*.c $(srcdir)/auth/*.c
+
+pvs-log-files: $(POBJS)
+
+pvs-studio: $(POBJS)
+ plog-converter $(PVS_LOG_OPTS) $(POBJS)
+
+check: $(TEST_PROGS) visudo testsudoers cvtsudoers
+ @if test X"$(cross_compiling)" != X"yes"; then \
+ LC_ALL=C; export LC_ALL; \
+ unset LANG || LANG=; \
+ rval=0; \
+ mkdir -p regress/parser; \
+ ./check_addr $(srcdir)/regress/parser/check_addr.in || rval=`expr $$rval + $$?`; \
+ ./check_base64 || rval=`expr $$rval + $$?`; \
+ if test -f check_digest; then \
+ ./check_digest > regress/parser/check_digest.out; \
+ diff regress/parser/check_digest.out $(srcdir)/regress/parser/check_digest.out.ok || rval=`expr $$rval + $$?`; \
+ fi; \
+ ./check_env_pattern $(srcdir)/regress/env_match/data || rval=`expr $$rval + $$?`; \
+ ./check_fill || rval=`expr $$rval + $$?`; \
+ ./check_gentime || rval=`expr $$rval + $$?`; \
+ ./check_hexchar || rval=`expr $$rval + $$?`; \
+ ./check_iolog_path $(srcdir)/regress/iolog_path/data || rval=`expr $$rval + $$?`; \
+ ./check_iolog_plugin $(srcdir)/regress/iolog_plugin/iolog || rval=`expr $$rval + $$?`; \
+ ./check_iolog_util || rval=`expr $$rval + $$?`; \
+ ./check_starttime || rval=`expr $$rval + $$?`; \
+ if test -f check_symbols; then \
+ ./check_symbols .libs/sudoers.so $(shlib_exp) || rval=`expr $$rval + $$?`; \
+ fi; \
+ mkdir -p regress/logging; \
+ ./check_wrap $(srcdir)/regress/logging/check_wrap.in > regress/logging/check_wrap.out; \
+ diff regress/logging/check_wrap.out $(srcdir)/regress/logging/check_wrap.out.ok || rval=`expr $$rval + $$?`; \
+ passed=0; failed=0; total=0; \
+ mkdir -p regress/sudoers; \
+ dir=sudoers; \
+ for t in $(srcdir)/regress/$$dir/*.in; do \
+ base=`basename $$t .in`; \
+ out="regress/sudoers/$${base}.out"; \
+ toke="regress/sudoers/$${base}.toke"; \
+ json="regress/sudoers/$${base}.json"; \
+ ldif="regress/sudoers/$${base}.ldif"; \
+ sudo="regress/sudoers/$${base}.sudo"; \
+ ldif2sudo="regress/sudoers/$${base}.ldif2sudo"; \
+ if test -s $$json.ok; then \
+ ASAN_OPTIONS=; \
+ else \
+ ASAN_OPTIONS=detect_leaks=0; \
+ fi; \
+ ASAN_OPTIONS=$$ASAN_OPTIONS \
+ ./testsudoers -dt <$$t >$$out 2>$$toke || true; \
+ if cmp $$out $(srcdir)/$$out.ok >/dev/null; then \
+ passed=`expr $$passed + 1`; \
+ echo "$$dir/$$base (parse): OK"; \
+ else \
+ failed=`expr $$failed + 1`; \
+ echo "$$dir/$$base (parse): FAIL"; \
+ diff $$out $(srcdir)/$$out.ok || true; \
+ fi; \
+ total=`expr $$total + 1`; \
+ if cmp $$toke $(srcdir)/$$toke.ok >/dev/null; then \
+ passed=`expr $$passed + 1`; \
+ echo "$$dir/$$base (toke): OK"; \
+ else \
+ failed=`expr $$failed + 1`; \
+ echo "$$dir/$$base (toke): FAIL"; \
+ diff $$toke $(srcdir)/$$toke.ok || true; \
+ fi; \
+ total=`expr $$total + 1`; \
+ ./cvtsudoers -c "" -f json $$t >$$json 2>/dev/null || true; \
+ total=`expr $$total + 1`; \
+ if cmp $$json $(srcdir)/$$json.ok >/dev/null; then \
+ passed=`expr $$passed + 1`; \
+ echo "$$dir/$$base (json): OK"; \
+ else \
+ failed=`expr $$failed + 1`; \
+ echo "$$dir/$$base (json): FAIL"; \
+ diff $$json $(srcdir)/$$json.ok || true; \
+ fi; \
+ SUDOERS_BASE="ou=SUDOers,dc=sudo,dc=ws" \
+ ./cvtsudoers -c "" -f ldif < $$t >$$ldif 2>/dev/null || true; \
+ total=`expr $$total + 1`; \
+ if cmp $$ldif $(srcdir)/$$ldif.ok >/dev/null; then \
+ passed=`expr $$passed + 1`; \
+ echo "$$dir/$$base (ldif): OK"; \
+ else \
+ failed=`expr $$failed + 1`; \
+ echo "$$dir/$$base: (ldif) FAIL"; \
+ diff $$ldif $(srcdir)/$$ldif.ok || true; \
+ fi; \
+ ./cvtsudoers -c "" -f sudoers $$t >$$sudo 2>/dev/null || true; \
+ total=`expr $$total + 1`; \
+ if ./visudo -qcf $$sudo; then \
+ passed=`expr $$passed + 1`; \
+ echo "$$dir/$$base (reparse): OK"; \
+ else \
+ failed=`expr $$failed + 1`; \
+ echo "$$dir/$$base: (reparse) FAIL"; \
+ ./visudo -cf $$sudo || true; \
+ fi; \
+ if test -s $(srcdir)/$$ldif.ok; then \
+ ./cvtsudoers -c "" -i ldif -f sudoers $(srcdir)/$$ldif.ok >$$ldif2sudo || true; \
+ total=`expr $$total + 1`; \
+ if cmp $$ldif2sudo $(srcdir)/$$ldif2sudo.ok >/dev/null; then \
+ passed=`expr $$passed + 1`; \
+ echo "$$dir/$$base (ldif2sudo): OK"; \
+ else \
+ failed=`expr $$failed + 1`; \
+ echo "$$dir/$$base: (ldif2sudo) FAIL"; \
+ diff $$ldif $(srcdir)/$$ldif.ok || true; \
+ fi; \
+ fi; \
+ done; \
+ echo "$$dir: $$passed/$$total tests passed; $$failed/$$total tests failed"; \
+ if test $$failed -ne 0; then \
+ rval=`expr $$rval + $$failed`; \
+ fi; \
+ for dir in testsudoers visudo cvtsudoers; do \
+ mkdir -p regress/$$dir; \
+ passed=0; failed=0; total=0; \
+ for t in $(srcdir)/regress/$$dir/*.sh; do \
+ base=`basename $$t .sh`; \
+ out="regress/$$dir/$${base}.out"; \
+ err="regress/$$dir/$${base}.err"; \
+ TESTDIR=$(srcdir)/regress/$$dir \
+ $(SHELL) $$t >$$out 2>$$err; \
+ if cmp $$out $(srcdir)/$$out.ok >/dev/null; then \
+ passed=`expr $$passed + 1`; \
+ echo "$$dir/$$base: OK"; \
+ else \
+ failed=`expr $$failed + 1`; \
+ echo "$$dir/$$base: FAIL"; \
+ diff $$out $(srcdir)/$$out.ok || true; \
+ fi; \
+ total=`expr $$total + 1`; \
+ if test -s $(srcdir)/$$err.ok; then \
+ if cmp $$err $(srcdir)/$$err.ok >/dev/null; then \
+ passed=`expr $$passed + 1`; \
+ echo "$$dir/$$base (stderr): OK"; \
+ else \
+ failed=`expr $$failed + 1`; \
+ echo "$$dir/$$base (stderr): FAIL"; \
+ diff $$err $(srcdir)/$$err.ok || true; \
+ fi; \
+ total=`expr $$total + 1`; \
+ elif test -s $$err; then \
+ failed=`expr $$failed + 1`; \
+ echo "$$dir/$$base (stderr): FAIL"; \
+ cat $$err 1>&2; \
+ fi; \
+ done; \
+ echo "$$dir: $$passed/$$total tests passed; $$failed/$$total tests failed"; \
+ if test $$failed -ne 0; then \
+ rval=`expr $$rval + $$failed`; \
+ fi; \
+ done; \
+ exit $$rval; \
+ fi
+
+clean:
+ -$(LIBTOOL) $(LTFLAGS) --mode=clean rm -f $(PROGS) $(TEST_PROGS) \
+ *.lo *.o *.la *.a *.i *.plog stamp-* core *.core core.* \
+ prologue regress/*/*.out regress/*/*.toke regress/*/*.err \
+ regress/*/*.json regress/*/*.ldif regress/*/*.sudo
+
+mostlyclean: clean
+
+distclean: clean
+ -rm -rf Makefile sudoers sudoers.lo .libs $(shlib_map) $(shlib_opt)
+ @if [ -n "$(DEVEL)" -a "$(devdir)" != "$(srcdir)" ]; then \
+ cmd='rm -rf $(GENERATED)'; \
+ echo "$$cmd"; eval $$cmd; \
+ fi
+
+clobber: distclean
+
+realclean: distclean
+ rm -f TAGS tags
+
+cleandir: realclean
+
+# Autogenerated dependencies, do not modify
+afs.lo: $(authdir)/afs.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(authdir)/afs.c
+afs.i: $(authdir)/afs.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+afs.plog: afs.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/afs.c --i-file $< --output-file $@
+aix_auth.lo: $(authdir)/aix_auth.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(authdir)/aix_auth.c
+aix_auth.i: $(authdir)/aix_auth.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+aix_auth.plog: aix_auth.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/aix_auth.c --i-file $< --output-file $@
+alias.lo: $(srcdir)/alias.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/redblack.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/alias.c
+alias.i: $(srcdir)/alias.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/redblack.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+alias.plog: alias.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/alias.c --i-file $< --output-file $@
+audit.lo: $(srcdir)/audit.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/bsm_audit.h $(srcdir)/defaults.h $(srcdir)/linux_audit.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/solaris_audit.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/audit.c
+audit.i: $(srcdir)/audit.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/bsm_audit.h $(srcdir)/defaults.h $(srcdir)/linux_audit.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/solaris_audit.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+audit.plog: audit.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/audit.c --i-file $< --output-file $@
+base64.lo: $(srcdir)/base64.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/base64.c
+base64.i: $(srcdir)/base64.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+base64.plog: base64.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/base64.c --i-file $< --output-file $@
+boottime.lo: $(srcdir)/boottime.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/boottime.c
+boottime.i: $(srcdir)/boottime.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+boottime.plog: boottime.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/boottime.c --i-file $< --output-file $@
+bsdauth.lo: $(authdir)/bsdauth.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(authdir)/bsdauth.c
+bsdauth.i: $(authdir)/bsdauth.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+bsdauth.plog: bsdauth.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/bsdauth.c --i-file $< --output-file $@
+bsm_audit.lo: $(srcdir)/bsm_audit.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/bsm_audit.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/bsm_audit.c
+bsm_audit.i: $(srcdir)/bsm_audit.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/bsm_audit.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+bsm_audit.plog: bsm_audit.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/bsm_audit.c --i-file $< --output-file $@
+check.lo: $(srcdir)/check.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/check.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/check.c
+check.i: $(srcdir)/check.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/check.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check.plog: check.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/check.c --i-file $< --output-file $@
+check_addr.o: $(srcdir)/regress/parser/check_addr.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/interfaces.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/parser/check_addr.c
+check_addr.i: $(srcdir)/regress/parser/check_addr.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/interfaces.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_addr.plog: check_addr.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/parser/check_addr.c --i-file $< --output-file $@
+check_base64.o: $(srcdir)/regress/parser/check_base64.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/parser/check_base64.c
+check_base64.i: $(srcdir)/regress/parser/check_base64.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_base64.plog: check_base64.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/parser/check_base64.c --i-file $< --output-file $@
+check_digest.o: $(srcdir)/regress/parser/check_digest.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/parse.h \
+ $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/parser/check_digest.c
+check_digest.i: $(srcdir)/regress/parser/check_digest.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/parse.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_digest.plog: check_digest.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/parser/check_digest.c --i-file $< --output-file $@
+check_env_pattern.o: $(srcdir)/regress/env_match/check_env_pattern.c \
+ $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/env_match/check_env_pattern.c
+check_env_pattern.i: $(srcdir)/regress/env_match/check_env_pattern.c \
+ $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_env_pattern.plog: check_env_pattern.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/env_match/check_env_pattern.c --i-file $< --output-file $@
+check_fill.o: $(srcdir)/regress/parser/check_fill.c $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/parse.h $(srcdir)/toke.h \
+ $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/parser/check_fill.c
+check_fill.i: $(srcdir)/regress/parser/check_fill.c $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/parse.h $(srcdir)/toke.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_fill.plog: check_fill.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/parser/check_fill.c --i-file $< --output-file $@
+check_gentime.o: $(srcdir)/regress/parser/check_gentime.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/parse.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/parser/check_gentime.c
+check_gentime.i: $(srcdir)/regress/parser/check_gentime.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/parse.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_gentime.plog: check_gentime.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/parser/check_gentime.c --i-file $< --output-file $@
+check_hexchar.o: $(srcdir)/regress/parser/check_hexchar.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/parser/check_hexchar.c
+check_hexchar.i: $(srcdir)/regress/parser/check_hexchar.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_hexchar.plog: check_hexchar.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/parser/check_hexchar.c --i-file $< --output-file $@
+check_iolog_path.o: $(srcdir)/regress/iolog_path/check_iolog_path.c \
+ $(devdir)/def_data.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/iolog_path/check_iolog_path.c
+check_iolog_path.i: $(srcdir)/regress/iolog_path/check_iolog_path.c \
+ $(devdir)/def_data.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_iolog_path.plog: check_iolog_path.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/iolog_path/check_iolog_path.c --i-file $< --output-file $@
+check_iolog_plugin.o: $(srcdir)/regress/iolog_plugin/check_iolog_plugin.c \
+ $(devdir)/def_data.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/iolog.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/iolog_plugin/check_iolog_plugin.c
+check_iolog_plugin.i: $(srcdir)/regress/iolog_plugin/check_iolog_plugin.c \
+ $(devdir)/def_data.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/iolog.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_iolog_plugin.plog: check_iolog_plugin.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/iolog_plugin/check_iolog_plugin.c --i-file $< --output-file $@
+check_iolog_util.o: $(srcdir)/regress/iolog_util/check_iolog_util.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(srcdir)/iolog.h $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/iolog_util/check_iolog_util.c
+check_iolog_util.i: $(srcdir)/regress/iolog_util/check_iolog_util.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(srcdir)/iolog.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_iolog_util.plog: check_iolog_util.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/iolog_util/check_iolog_util.c --i-file $< --output-file $@
+check_starttime.o: $(srcdir)/regress/starttime/check_starttime.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(srcdir)/check.h $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/starttime/check_starttime.c
+check_starttime.i: $(srcdir)/regress/starttime/check_starttime.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(srcdir)/check.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_starttime.plog: check_starttime.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/starttime/check_starttime.c --i-file $< --output-file $@
+check_symbols.o: $(srcdir)/regress/check_symbols/check_symbols.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_dso.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/check_symbols/check_symbols.c
+check_symbols.i: $(srcdir)/regress/check_symbols/check_symbols.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_dso.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_symbols.plog: check_symbols.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/check_symbols/check_symbols.c --i-file $< --output-file $@
+check_wrap.o: $(srcdir)/regress/logging/check_wrap.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/logging/check_wrap.c
+check_wrap.i: $(srcdir)/regress/logging/check_wrap.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_wrap.plog: check_wrap.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/logging/check_wrap.c --i-file $< --output-file $@
+cvtsudoers.o: $(srcdir)/cvtsudoers.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/getopt.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/cvtsudoers.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/redblack.h $(srcdir)/strlist.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(srcdir)/sudoers_version.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/cvtsudoers.c
+cvtsudoers.i: $(srcdir)/cvtsudoers.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/getopt.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/cvtsudoers.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/redblack.h $(srcdir)/strlist.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(srcdir)/sudoers_version.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+cvtsudoers.plog: cvtsudoers.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/cvtsudoers.c --i-file $< --output-file $@
+cvtsudoers_json.o: $(srcdir)/cvtsudoers_json.c $(devdir)/def_data.h \
+ $(devdir)/gram.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/cvtsudoers.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/strlist.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/cvtsudoers_json.c
+cvtsudoers_json.i: $(srcdir)/cvtsudoers_json.c $(devdir)/def_data.h \
+ $(devdir)/gram.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/cvtsudoers.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/strlist.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+cvtsudoers_json.plog: cvtsudoers_json.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/cvtsudoers_json.c --i-file $< --output-file $@
+cvtsudoers_ldif.o: $(srcdir)/cvtsudoers_ldif.c $(devdir)/def_data.h \
+ $(devdir)/gram.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/cvtsudoers.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/redblack.h $(srcdir)/strlist.h \
+ $(srcdir)/sudo_ldap.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/cvtsudoers_ldif.c
+cvtsudoers_ldif.i: $(srcdir)/cvtsudoers_ldif.c $(devdir)/def_data.h \
+ $(devdir)/gram.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/cvtsudoers.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/redblack.h $(srcdir)/strlist.h \
+ $(srcdir)/sudo_ldap.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+cvtsudoers_ldif.plog: cvtsudoers_ldif.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/cvtsudoers_ldif.c --i-file $< --output-file $@
+cvtsudoers_pwutil.o: $(srcdir)/cvtsudoers_pwutil.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/cvtsudoers.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/pwutil.h $(srcdir)/strlist.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/cvtsudoers_pwutil.c
+cvtsudoers_pwutil.i: $(srcdir)/cvtsudoers_pwutil.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/cvtsudoers.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/pwutil.h $(srcdir)/strlist.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+cvtsudoers_pwutil.plog: cvtsudoers_pwutil.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/cvtsudoers_pwutil.c --i-file $< --output-file $@
+dce.lo: $(authdir)/dce.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(authdir)/dce.c
+dce.i: $(authdir)/dce.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+dce.plog: dce.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/dce.c --i-file $< --output-file $@
+defaults.lo: $(srcdir)/defaults.c $(devdir)/def_data.c $(devdir)/def_data.h \
+ $(devdir)/gram.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/defaults.c
+defaults.i: $(srcdir)/defaults.c $(devdir)/def_data.c $(devdir)/def_data.h \
+ $(devdir)/gram.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+defaults.plog: defaults.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/defaults.c --i-file $< --output-file $@
+digestname.lo: $(srcdir)/digestname.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_queue.h \
+ $(srcdir)/parse.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/digestname.c
+digestname.i: $(srcdir)/digestname.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_queue.h \
+ $(srcdir)/parse.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+digestname.plog: digestname.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/digestname.c --i-file $< --output-file $@
+editor.lo: $(srcdir)/editor.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/editor.c
+editor.i: $(srcdir)/editor.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+editor.plog: editor.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/editor.c --i-file $< --output-file $@
+env.lo: $(srcdir)/env.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/env.c
+env.i: $(srcdir)/env.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+env.plog: env.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/env.c --i-file $< --output-file $@
+env_pattern.lo: $(srcdir)/env_pattern.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/env_pattern.c
+env_pattern.i: $(srcdir)/env_pattern.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+env_pattern.plog: env_pattern.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/env_pattern.c --i-file $< --output-file $@
+file.lo: $(srcdir)/file.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/file.c
+file.i: $(srcdir)/file.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+file.plog: file.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/file.c --i-file $< --output-file $@
+filedigest.lo: $(srcdir)/filedigest.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/filedigest.c
+filedigest.i: $(srcdir)/filedigest.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+filedigest.plog: filedigest.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/filedigest.c --i-file $< --output-file $@
+find_path.lo: $(srcdir)/find_path.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/find_path.c
+find_path.i: $(srcdir)/find_path.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+find_path.plog: find_path.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/find_path.c --i-file $< --output-file $@
+fmtsudoers.lo: $(srcdir)/fmtsudoers.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_lbuf.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/fmtsudoers.c
+fmtsudoers.i: $(srcdir)/fmtsudoers.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_lbuf.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+fmtsudoers.plog: fmtsudoers.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/fmtsudoers.c --i-file $< --output-file $@
+fwtk.lo: $(authdir)/fwtk.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(authdir)/fwtk.c
+fwtk.i: $(authdir)/fwtk.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+fwtk.plog: fwtk.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/fwtk.c --i-file $< --output-file $@
+gc.lo: $(srcdir)/gc.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/gc.c
+gc.i: $(srcdir)/gc.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+gc.plog: gc.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/gc.c --i-file $< --output-file $@
+gentime.lo: $(srcdir)/gentime.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(srcdir)/parse.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/gentime.c
+gentime.i: $(srcdir)/gentime.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(srcdir)/parse.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+gentime.plog: gentime.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/gentime.c --i-file $< --output-file $@
+getdate.o: $(devdir)/getdate.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(devdir)/getdate.c
+getdate.i: $(devdir)/getdate.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+getdate.plog: getdate.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(devdir)/getdate.c --i-file $< --output-file $@
+getspwuid.lo: $(srcdir)/getspwuid.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getspwuid.c
+getspwuid.i: $(srcdir)/getspwuid.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+getspwuid.plog: getspwuid.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getspwuid.c --i-file $< --output-file $@
+gmtoff.lo: $(srcdir)/gmtoff.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(srcdir)/parse.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/gmtoff.c
+gmtoff.i: $(srcdir)/gmtoff.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(srcdir)/parse.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+gmtoff.plog: gmtoff.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/gmtoff.c --i-file $< --output-file $@
+goodpath.lo: $(srcdir)/goodpath.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/goodpath.c
+goodpath.i: $(srcdir)/goodpath.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+goodpath.plog: goodpath.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/goodpath.c --i-file $< --output-file $@
+gram.lo: $(devdir)/gram.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h $(srcdir)/toke.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(devdir)/gram.c
+gram.i: $(devdir)/gram.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h $(srcdir)/toke.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+gram.plog: gram.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(devdir)/gram.c --i-file $< --output-file $@
+group_plugin.lo: $(srcdir)/group_plugin.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_dso.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/group_plugin.c
+group_plugin.i: $(srcdir)/group_plugin.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_dso.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+group_plugin.plog: group_plugin.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/group_plugin.c --i-file $< --output-file $@
+hexchar.lo: $(srcdir)/hexchar.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/hexchar.c
+hexchar.i: $(srcdir)/hexchar.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+hexchar.plog: hexchar.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/hexchar.c --i-file $< --output-file $@
+interfaces.lo: $(srcdir)/interfaces.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/interfaces.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/interfaces.c
+interfaces.i: $(srcdir)/interfaces.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/interfaces.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+interfaces.plog: interfaces.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/interfaces.c --i-file $< --output-file $@
+iolog.lo: $(srcdir)/iolog.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/iolog.h $(srcdir)/iolog_files.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/iolog.c
+iolog.i: $(srcdir)/iolog.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/iolog.h $(srcdir)/iolog_files.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+iolog.plog: iolog.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/iolog.c --i-file $< --output-file $@
+iolog_path.lo: $(srcdir)/iolog_path.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/iolog_path.c
+iolog_path.i: $(srcdir)/iolog_path.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+iolog_path.plog: iolog_path.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/iolog_path.c --i-file $< --output-file $@
+iolog_util.o: $(srcdir)/iolog_util.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/iolog.h \
+ $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/iolog_util.c
+iolog_util.i: $(srcdir)/iolog_util.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/iolog.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+iolog_util.plog: iolog_util.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/iolog_util.c --i-file $< --output-file $@
+kerb5.lo: $(authdir)/kerb5.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(authdir)/kerb5.c
+kerb5.i: $(authdir)/kerb5.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+kerb5.plog: kerb5.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/kerb5.c --i-file $< --output-file $@
+ldap.lo: $(srcdir)/ldap.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_dso.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_ldap.h $(srcdir)/sudo_ldap_conf.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/ldap.c
+ldap.i: $(srcdir)/ldap.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_dso.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_ldap.h $(srcdir)/sudo_ldap_conf.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+ldap.plog: ldap.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/ldap.c --i-file $< --output-file $@
+ldap_conf.lo: $(srcdir)/ldap_conf.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_lbuf.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_ldap.h $(srcdir)/sudo_ldap_conf.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/ldap_conf.c
+ldap_conf.i: $(srcdir)/ldap_conf.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_lbuf.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_ldap.h $(srcdir)/sudo_ldap_conf.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+ldap_conf.plog: ldap_conf.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/ldap_conf.c --i-file $< --output-file $@
+ldap_util.lo: $(srcdir)/ldap_util.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/interfaces.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_ldap.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/ldap_util.c
+ldap_util.i: $(srcdir)/ldap_util.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_digest.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/interfaces.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_ldap.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+ldap_util.plog: ldap_util.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/ldap_util.c --i-file $< --output-file $@
+linux_audit.lo: $(srcdir)/linux_audit.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/linux_audit.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/linux_audit.c
+linux_audit.i: $(srcdir)/linux_audit.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/linux_audit.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+linux_audit.plog: linux_audit.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/linux_audit.c --i-file $< --output-file $@
+locale.lo: $(srcdir)/locale.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_queue.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/locale.c
+locale.i: $(srcdir)/locale.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_queue.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+locale.plog: locale.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/locale.c --i-file $< --output-file $@
+logging.lo: $(srcdir)/logging.c $(devdir)/def_data.h \
+ $(incdir)/compat/getaddrinfo.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/logging.c
+logging.i: $(srcdir)/logging.c $(devdir)/def_data.h \
+ $(incdir)/compat/getaddrinfo.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+logging.plog: logging.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/logging.c --i-file $< --output-file $@
+logwrap.lo: $(srcdir)/logwrap.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/logwrap.c
+logwrap.i: $(srcdir)/logwrap.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+logwrap.plog: logwrap.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/logwrap.c --i-file $< --output-file $@
+match.lo: $(srcdir)/match.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/fnmatch.h $(incdir)/compat/glob.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/match.c
+match.i: $(srcdir)/match.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/fnmatch.h $(incdir)/compat/glob.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+match.plog: match.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/match.c --i-file $< --output-file $@
+match_addr.lo: $(srcdir)/match_addr.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/interfaces.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/match_addr.c
+match_addr.i: $(srcdir)/match_addr.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/interfaces.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+match_addr.plog: match_addr.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/match_addr.c --i-file $< --output-file $@
+mkdir_parents.lo: $(srcdir)/mkdir_parents.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/mkdir_parents.c
+mkdir_parents.i: $(srcdir)/mkdir_parents.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+mkdir_parents.plog: mkdir_parents.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/mkdir_parents.c --i-file $< --output-file $@
+net_ifs.o: $(top_srcdir)/src/net_ifs.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(top_srcdir)/src/net_ifs.c
+net_ifs.i: $(top_srcdir)/src/net_ifs.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+net_ifs.plog: net_ifs.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(top_srcdir)/src/net_ifs.c --i-file $< --output-file $@
+pam.lo: $(authdir)/pam.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(authdir)/pam.c
+pam.i: $(authdir)/pam.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+pam.plog: pam.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/pam.c --i-file $< --output-file $@
+parse.lo: $(srcdir)/parse.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/parse.c
+parse.i: $(srcdir)/parse.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+parse.plog: parse.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/parse.c --i-file $< --output-file $@
+parse_ldif.o: $(srcdir)/parse_ldif.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/redblack.h $(srcdir)/strlist.h \
+ $(srcdir)/sudo_ldap.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/parse_ldif.c
+parse_ldif.i: $(srcdir)/parse_ldif.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/redblack.h $(srcdir)/strlist.h \
+ $(srcdir)/sudo_ldap.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+parse_ldif.plog: parse_ldif.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/parse_ldif.c --i-file $< --output-file $@
+passwd.lo: $(authdir)/passwd.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(authdir)/passwd.c
+passwd.i: $(authdir)/passwd.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+passwd.plog: passwd.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/passwd.c --i-file $< --output-file $@
+policy.lo: $(srcdir)/policy.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/interfaces.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(srcdir)/sudoers_version.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/policy.c
+policy.i: $(srcdir)/policy.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/interfaces.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(srcdir)/sudoers_version.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+policy.plog: policy.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/policy.c --i-file $< --output-file $@
+prompt.lo: $(srcdir)/prompt.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/prompt.c
+prompt.i: $(srcdir)/prompt.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+prompt.plog: prompt.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/prompt.c --i-file $< --output-file $@
+pwutil.lo: $(srcdir)/pwutil.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/pwutil.h \
+ $(srcdir)/redblack.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/pwutil.c
+pwutil.i: $(srcdir)/pwutil.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/pwutil.h \
+ $(srcdir)/redblack.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+pwutil.plog: pwutil.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/pwutil.c --i-file $< --output-file $@
+pwutil_impl.lo: $(srcdir)/pwutil_impl.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/pwutil.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/pwutil_impl.c
+pwutil_impl.i: $(srcdir)/pwutil_impl.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/pwutil.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+pwutil_impl.plog: pwutil_impl.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/pwutil_impl.c --i-file $< --output-file $@
+rcstr.lo: $(srcdir)/rcstr.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/rcstr.c
+rcstr.i: $(srcdir)/rcstr.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+rcstr.plog: rcstr.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/rcstr.c --i-file $< --output-file $@
+redblack.lo: $(srcdir)/redblack.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/redblack.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/redblack.c
+redblack.i: $(srcdir)/redblack.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/redblack.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+redblack.plog: redblack.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/redblack.c --i-file $< --output-file $@
+rfc1938.lo: $(authdir)/rfc1938.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(authdir)/rfc1938.c
+rfc1938.i: $(authdir)/rfc1938.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+rfc1938.plog: rfc1938.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/rfc1938.c --i-file $< --output-file $@
+secureware.lo: $(authdir)/secureware.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(authdir)/secureware.c
+secureware.i: $(authdir)/secureware.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+secureware.plog: secureware.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/secureware.c --i-file $< --output-file $@
+securid5.lo: $(authdir)/securid5.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(authdir)/securid5.c
+securid5.i: $(authdir)/securid5.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+securid5.plog: securid5.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/securid5.c --i-file $< --output-file $@
+set_perms.lo: $(srcdir)/set_perms.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/set_perms.c
+set_perms.i: $(srcdir)/set_perms.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+set_perms.plog: set_perms.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/set_perms.c --i-file $< --output-file $@
+sia.lo: $(authdir)/sia.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(authdir)/sia.c
+sia.i: $(authdir)/sia.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sia.plog: sia.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/sia.c --i-file $< --output-file $@
+solaris_audit.lo: $(srcdir)/solaris_audit.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/solaris_audit.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/solaris_audit.c
+solaris_audit.i: $(srcdir)/solaris_audit.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/solaris_audit.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+solaris_audit.plog: solaris_audit.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/solaris_audit.c --i-file $< --output-file $@
+sssd.lo: $(srcdir)/sssd.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_dso.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_ldap.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sssd.c
+sssd.i: $(srcdir)/sssd.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_dso.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_ldap.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sssd.plog: sssd.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sssd.c --i-file $< --output-file $@
+starttime.lo: $(srcdir)/starttime.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/check.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/starttime.c
+starttime.i: $(srcdir)/starttime.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/check.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+starttime.plog: starttime.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/starttime.c --i-file $< --output-file $@
+strlist.o: $(srcdir)/strlist.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/strlist.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strlist.c
+strlist.i: $(srcdir)/strlist.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/strlist.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+strlist.plog: strlist.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/strlist.c --i-file $< --output-file $@
+stubs.o: $(srcdir)/stubs.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/interfaces.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/stubs.c
+stubs.i: $(srcdir)/stubs.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/interfaces.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+stubs.plog: stubs.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/stubs.c --i-file $< --output-file $@
+sudo_auth.lo: $(authdir)/sudo_auth.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_rand.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/ins_2001.h $(srcdir)/ins_classic.h \
+ $(srcdir)/ins_csops.h $(srcdir)/ins_goons.h \
+ $(srcdir)/ins_python.h $(srcdir)/insults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(authdir)/sudo_auth.c
+sudo_auth.i: $(authdir)/sudo_auth.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_rand.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/ins_2001.h $(srcdir)/ins_classic.h \
+ $(srcdir)/ins_csops.h $(srcdir)/ins_goons.h \
+ $(srcdir)/ins_python.h $(srcdir)/insults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sudo_auth.plog: sudo_auth.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/sudo_auth.c --i-file $< --output-file $@
+sudo_nss.lo: $(srcdir)/sudo_nss.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_lbuf.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sudo_nss.c
+sudo_nss.i: $(srcdir)/sudo_nss.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_lbuf.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sudo_nss.plog: sudo_nss.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudo_nss.c --i-file $< --output-file $@
+sudo_printf.o: $(srcdir)/sudo_printf.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sudo_printf.c
+sudo_printf.i: $(srcdir)/sudo_printf.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sudo_printf.plog: sudo_printf.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudo_printf.c --i-file $< --output-file $@
+sudoers.lo: $(srcdir)/sudoers.c $(devdir)/def_data.h \
+ $(incdir)/compat/getaddrinfo.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/auth/sudo_auth.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sudoers.c
+sudoers.i: $(srcdir)/sudoers.c $(devdir)/def_data.h \
+ $(incdir)/compat/getaddrinfo.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/auth/sudo_auth.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sudoers.plog: sudoers.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudoers.c --i-file $< --output-file $@
+sudoers_debug.lo: $(srcdir)/sudoers_debug.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sudoers_debug.c
+sudoers_debug.i: $(srcdir)/sudoers_debug.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sudoers_debug.plog: sudoers_debug.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudoers_debug.c --i-file $< --output-file $@
+sudoreplay.o: $(srcdir)/sudoreplay.c $(incdir)/compat/getopt.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_event.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/iolog.h \
+ $(srcdir)/iolog_files.h $(srcdir)/logging.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sudoreplay.c
+sudoreplay.i: $(srcdir)/sudoreplay.c $(incdir)/compat/getopt.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_event.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/iolog.h \
+ $(srcdir)/iolog_files.h $(srcdir)/logging.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sudoreplay.plog: sudoreplay.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudoreplay.c --i-file $< --output-file $@
+testsudoers.o: $(srcdir)/testsudoers.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_lbuf.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/interfaces.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(srcdir)/tsgetgrpw.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/testsudoers.c
+testsudoers.i: $(srcdir)/testsudoers.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_lbuf.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/interfaces.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(srcdir)/tsgetgrpw.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+testsudoers.plog: testsudoers.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/testsudoers.c --i-file $< --output-file $@
+timeout.lo: $(srcdir)/timeout.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(srcdir)/parse.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/timeout.c
+timeout.i: $(srcdir)/timeout.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(srcdir)/parse.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+timeout.plog: timeout.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/timeout.c --i-file $< --output-file $@
+timestamp.lo: $(srcdir)/timestamp.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/check.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/timestamp.c
+timestamp.i: $(srcdir)/timestamp.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/check.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+timestamp.plog: timestamp.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/timestamp.c --i-file $< --output-file $@
+timestr.lo: $(srcdir)/timestr.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(srcdir)/parse.h $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/timestr.c
+timestr.i: $(srcdir)/timestr.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_queue.h $(srcdir)/parse.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+timestr.plog: timestr.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/timestr.c --i-file $< --output-file $@
+toke.lo: $(devdir)/toke.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_digest.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(srcdir)/toke.h $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(devdir)/toke.c
+toke.i: $(devdir)/toke.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_digest.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(srcdir)/toke.h $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+toke.plog: toke.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(devdir)/toke.c --i-file $< --output-file $@
+toke_util.lo: $(srcdir)/toke_util.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(srcdir)/toke.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/toke_util.c
+toke_util.i: $(srcdir)/toke_util.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(srcdir)/toke.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+toke_util.plog: toke_util.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/toke_util.c --i-file $< --output-file $@
+tsdump.o: $(srcdir)/tsdump.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/check.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/tsdump.c
+tsdump.i: $(srcdir)/tsdump.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/check.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+tsdump.plog: tsdump.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/tsdump.c --i-file $< --output-file $@
+tsgetgrpw.o: $(srcdir)/tsgetgrpw.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(srcdir)/tsgetgrpw.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/tsgetgrpw.c
+tsgetgrpw.i: $(srcdir)/tsgetgrpw.c $(devdir)/def_data.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(srcdir)/tsgetgrpw.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+tsgetgrpw.plog: tsgetgrpw.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/tsgetgrpw.c --i-file $< --output-file $@
+visudo.o: $(srcdir)/visudo.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/getopt.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/interfaces.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/redblack.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(srcdir)/sudoers_version.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/visudo.c
+visudo.i: $(srcdir)/visudo.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/getopt.h $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/interfaces.h $(srcdir)/logging.h \
+ $(srcdir)/parse.h $(srcdir)/redblack.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(srcdir)/sudoers_version.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+visudo.plog: visudo.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/visudo.c --i-file $< --output-file $@
diff --git a/plugins/sudoers/alias.c b/plugins/sudoers/alias.c
new file mode 100644
index 0000000..a5b4573
--- /dev/null
+++ b/plugins/sudoers/alias.c
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2004-2005, 2007-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRING_H */
+#include <unistd.h>
+#include <errno.h>
+
+#include "sudoers.h"
+#include "redblack.h"
+#include <gram.h>
+
+/*
+ * Comparison function for the red-black tree.
+ * Aliases are sorted by name with the type used as a tie-breaker.
+ */
+static int
+alias_compare(const void *v1, const void *v2)
+{
+ const struct alias *a1 = (const struct alias *)v1;
+ const struct alias *a2 = (const struct alias *)v2;
+ int res;
+ debug_decl(alias_compare, SUDOERS_DEBUG_ALIAS)
+
+ if (a1 == NULL)
+ res = -1;
+ else if (a2 == NULL)
+ res = 1;
+ else if ((res = strcmp(a1->name, a2->name)) == 0)
+ res = a1->type - a2->type;
+ debug_return_int(res);
+}
+
+/*
+ * Search the tree for an alias with the specified name and type.
+ * Returns a pointer to the alias structure or NULL if not found.
+ * Caller is responsible for calling alias_put() on the returned
+ * alias to mark it as unused.
+ */
+struct alias *
+alias_get(struct sudoers_parse_tree *parse_tree, const char *name, int type)
+{
+ struct alias key;
+ struct rbnode *node;
+ struct alias *a = NULL;
+ debug_decl(alias_get, SUDOERS_DEBUG_ALIAS)
+
+ if (parse_tree->aliases == NULL)
+ debug_return_ptr(NULL);
+
+ key.name = (char *)name;
+ key.type = type;
+ if ((node = rbfind(parse_tree->aliases, &key)) != NULL) {
+ /*
+ * Check whether this alias is already in use.
+ * If so, we've detected a loop. If not, set the flag,
+ * which the caller should clear with a call to alias_put().
+ */
+ a = node->data;
+ if (a->used) {
+ errno = ELOOP;
+ debug_return_ptr(NULL);
+ }
+ a->used = true;
+ } else {
+ errno = ENOENT;
+ }
+ debug_return_ptr(a);
+}
+
+/*
+ * Clear the "used" flag in an alias once the caller is done with it.
+ */
+void
+alias_put(struct alias *a)
+{
+ debug_decl(alias_put, SUDOERS_DEBUG_ALIAS)
+ a->used = false;
+ debug_return;
+}
+
+/*
+ * Add an alias to the aliases redblack tree.
+ * Note that "file" must be a reference-counted string.
+ * Returns NULL on success and an error string on failure.
+ */
+const char *
+alias_add(struct sudoers_parse_tree *parse_tree, char *name, int type,
+ char *file, int lineno, struct member *members)
+{
+ static char errbuf[512];
+ struct alias *a;
+ debug_decl(alias_add, SUDOERS_DEBUG_ALIAS)
+
+ if (parse_tree->aliases == NULL) {
+ if ((parse_tree->aliases = alloc_aliases()) == NULL) {
+ strlcpy(errbuf, N_("unable to allocate memory"), sizeof(errbuf));
+ debug_return_str(errbuf);
+ }
+ }
+
+ a = calloc(1, sizeof(*a));
+ if (a == NULL) {
+ strlcpy(errbuf, N_("unable to allocate memory"), sizeof(errbuf));
+ debug_return_str(errbuf);
+ }
+ a->name = name;
+ a->type = type;
+ /* a->used = false; */
+ a->file = rcstr_addref(file);
+ a->lineno = lineno;
+ HLTQ_TO_TAILQ(&a->members, members, entries);
+ switch (rbinsert(parse_tree->aliases, a, NULL)) {
+ case 1:
+ snprintf(errbuf, sizeof(errbuf), N_("Alias \"%s\" already defined"),
+ name);
+ alias_free(a);
+ debug_return_str(errbuf);
+ case -1:
+ strlcpy(errbuf, N_("unable to allocate memory"), sizeof(errbuf));
+ alias_free(a);
+ debug_return_str(errbuf);
+ }
+ debug_return_str(NULL);
+}
+
+/*
+ * Closure to adapt 2-arg rbapply() to 3-arg alias_apply().
+ */
+struct alias_apply_closure {
+ struct sudoers_parse_tree *parse_tree;
+ int (*func)(struct sudoers_parse_tree *, struct alias *, void *);
+ void *cookie;
+};
+
+/* Adapt rbapply() to alias_apply() calling convention. */
+static int
+alias_apply_func(void *v1, void *v2)
+{
+ struct alias *a = v1;
+ struct alias_apply_closure *closure = v2;
+
+ return closure->func(closure->parse_tree, a, closure->cookie);
+}
+
+/*
+ * Apply a function to each alias entry and pass in a cookie.
+ */
+void
+alias_apply(struct sudoers_parse_tree *parse_tree,
+ int (*func)(struct sudoers_parse_tree *, struct alias *, void *),
+ void *cookie)
+{
+ struct alias_apply_closure closure;
+ debug_decl(alias_apply, SUDOERS_DEBUG_ALIAS)
+
+ if (parse_tree->aliases != NULL) {
+ closure.parse_tree = parse_tree;
+ closure.func = func;
+ closure.cookie = cookie;
+ rbapply(parse_tree->aliases, alias_apply_func, &closure, inorder);
+ }
+
+ debug_return;
+}
+
+/*
+ * Returns true if there are no aliases in the parse_tree, else false.
+ */
+bool
+no_aliases(struct sudoers_parse_tree *parse_tree)
+{
+ debug_decl(no_aliases, SUDOERS_DEBUG_ALIAS)
+ debug_return_bool(parse_tree->aliases == NULL ||
+ rbisempty(parse_tree->aliases));
+}
+
+/*
+ * Free memory used by an alias struct and its members.
+ */
+void
+alias_free(void *v)
+{
+ struct alias *a = (struct alias *)v;
+ debug_decl(alias_free, SUDOERS_DEBUG_ALIAS)
+
+ if (a != NULL) {
+ free(a->name);
+ rcstr_delref(a->file);
+ free_members(&a->members);
+ free(a);
+ }
+
+ debug_return;
+}
+
+/*
+ * Find the named alias, remove it from the tree and return it.
+ */
+struct alias *
+alias_remove(struct sudoers_parse_tree *parse_tree, char *name, int type)
+{
+ struct rbnode *node;
+ struct alias key;
+ debug_decl(alias_remove, SUDOERS_DEBUG_ALIAS)
+
+ if (parse_tree->aliases != NULL) {
+ key.name = name;
+ key.type = type;
+ if ((node = rbfind(parse_tree->aliases, &key)) != NULL)
+ debug_return_ptr(rbdelete(parse_tree->aliases, node));
+ }
+ errno = ENOENT;
+ debug_return_ptr(NULL);
+}
+
+struct rbtree *
+alloc_aliases(void)
+{
+ debug_decl(alloc_aliases, SUDOERS_DEBUG_ALIAS)
+
+ debug_return_ptr(rbcreate(alias_compare));
+}
+
+void
+free_aliases(struct rbtree *aliases)
+{
+ debug_decl(free_aliases, SUDOERS_DEBUG_ALIAS)
+
+ if (aliases != NULL)
+ rbdestroy(aliases, alias_free);
+}
+
+const char *
+alias_type_to_string(int alias_type)
+{
+ return alias_type == HOSTALIAS ? "Host_Alias" :
+ alias_type == CMNDALIAS ? "Cmnd_Alias" :
+ alias_type == USERALIAS ? "User_Alias" :
+ alias_type == RUNASALIAS ? "Runas_Alias" :
+ "Invalid_Alias";
+}
+
+/*
+ * Remove the alias of the specified type as well as any other aliases
+ * referenced by that alias. Stores removed aliases in a freelist.
+ */
+static bool
+alias_remove_recursive(struct sudoers_parse_tree *parse_tree, char *name,
+ int type, struct rbtree *freelist)
+{
+ struct member *m;
+ struct alias *a;
+ bool ret = true;
+ debug_decl(alias_remove_recursive, SUDOERS_DEBUG_ALIAS)
+
+ if ((a = alias_remove(parse_tree, name, type)) != NULL) {
+ TAILQ_FOREACH(m, &a->members, entries) {
+ if (m->type == ALIAS) {
+ if (!alias_remove_recursive(parse_tree, m->name, type, freelist))
+ ret = false;
+ }
+ }
+ if (rbinsert(freelist, a, NULL) != 0)
+ ret = false;
+ }
+ debug_return_bool(ret);
+}
+
+static int
+alias_find_used_members(struct sudoers_parse_tree *parse_tree,
+ struct member_list *members, int atype, struct rbtree *used_aliases)
+{
+ struct member *m;
+ int errors = 0;
+ debug_decl(alias_find_used_members, SUDOERS_DEBUG_ALIAS)
+
+ if (members != NULL) {
+ TAILQ_FOREACH(m, members, entries) {
+ if (m->type != ALIAS)
+ continue;
+ if (!alias_remove_recursive(parse_tree, m->name, atype, used_aliases))
+ errors++;
+ }
+ }
+
+ debug_return_int(errors);
+}
+
+/*
+ * Move all aliases referenced by userspecs to used_aliases.
+ */
+bool
+alias_find_used(struct sudoers_parse_tree *parse_tree, struct rbtree *used_aliases)
+{
+ struct privilege *priv;
+ struct userspec *us;
+ struct cmndspec *cs;
+ struct defaults *d;
+ struct member *m;
+ int errors = 0;
+ debug_decl(alias_find_used, SUDOERS_DEBUG_ALIAS)
+
+ /* Move referenced aliases to used_aliases. */
+ TAILQ_FOREACH(us, &parse_tree->userspecs, entries) {
+ errors += alias_find_used_members(parse_tree, &us->users,
+ USERALIAS, used_aliases);
+ TAILQ_FOREACH(priv, &us->privileges, entries) {
+ errors += alias_find_used_members(parse_tree, &priv->hostlist,
+ HOSTALIAS, used_aliases);
+ TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
+ errors += alias_find_used_members(parse_tree, cs->runasuserlist,
+ RUNASALIAS, used_aliases);
+ errors += alias_find_used_members(parse_tree, cs->runasgrouplist,
+ RUNASALIAS, used_aliases);
+ if ((m = cs->cmnd)->type == ALIAS) {
+ if (!alias_remove_recursive(parse_tree, m->name, CMNDALIAS,
+ used_aliases))
+ errors++;
+ }
+ }
+ }
+ }
+ TAILQ_FOREACH(d, &parse_tree->defaults, entries) {
+ switch (d->type) {
+ case DEFAULTS_HOST:
+ errors += alias_find_used_members(parse_tree, d->binding,
+ HOSTALIAS, used_aliases);
+ break;
+ case DEFAULTS_USER:
+ errors += alias_find_used_members(parse_tree, d->binding,
+ USERALIAS, used_aliases);
+ break;
+ case DEFAULTS_RUNAS:
+ errors += alias_find_used_members(parse_tree, d->binding,
+ RUNASALIAS, used_aliases);
+ break;
+ case DEFAULTS_CMND:
+ errors += alias_find_used_members(parse_tree, d->binding,
+ CMNDALIAS, used_aliases);
+ break;
+ default:
+ break;
+ }
+ }
+
+ debug_return_int(errors ? false : true);
+}
diff --git a/plugins/sudoers/audit.c b/plugins/sudoers/audit.c
new file mode 100644
index 0000000..1b802c3
--- /dev/null
+++ b/plugins/sudoers/audit.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2009-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sudoers.h"
+
+#ifdef HAVE_BSM_AUDIT
+# include "bsm_audit.h"
+#endif
+#ifdef HAVE_LINUX_AUDIT
+# include "linux_audit.h"
+#endif
+#ifdef HAVE_SOLARIS_AUDIT
+# include "solaris_audit.h"
+#endif
+
+int
+audit_success(int argc, char *argv[])
+{
+ int rc = 0;
+ debug_decl(audit_success, SUDOERS_DEBUG_AUDIT)
+
+ if (argv != NULL) {
+#ifdef HAVE_BSM_AUDIT
+ if (bsm_audit_success(argv) == -1)
+ rc = -1;
+#endif
+#ifdef HAVE_LINUX_AUDIT
+ if (linux_audit_command(argv, 1) == -1)
+ rc = -1;
+#endif
+#ifdef HAVE_SOLARIS_AUDIT
+ if (solaris_audit_success(argc, argv) == -1)
+ rc = -1;
+#endif
+ }
+
+ debug_return_int(rc);
+}
+
+int
+audit_failure(int argc, char *argv[], char const *const fmt, ...)
+{
+ int rc = 0;
+ debug_decl(audit_success, SUDOERS_DEBUG_AUDIT)
+
+#if defined(HAVE_BSM_AUDIT) || defined(HAVE_LINUX_AUDIT)
+ if (argv != NULL) {
+ va_list ap;
+ int oldlocale;
+
+ /* Audit error messages should be in the sudoers locale. */
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+
+#ifdef HAVE_BSM_AUDIT
+ va_start(ap, fmt);
+ if (bsm_audit_failure(argv, _(fmt), ap) == -1)
+ rc = -1;
+ va_end(ap);
+#endif
+#ifdef HAVE_LINUX_AUDIT
+ va_start(ap, fmt);
+ if (linux_audit_command(argv, 0) == -1)
+ rc = -1;
+ va_end(ap);
+#endif
+#ifdef HAVE_SOLARIS_AUDIT
+ va_start(ap, fmt);
+ if (solaris_audit_failure(argc, argv, _(fmt), ap) == -1)
+ rc = -1;
+ va_end(ap);
+#endif
+
+ sudoers_setlocale(oldlocale, NULL);
+ }
+#endif /* HAVE_BSM_AUDIT || HAVE_LINUX_AUDIT */
+
+ debug_return_int(rc);
+}
diff --git a/plugins/sudoers/auth/API b/plugins/sudoers/auth/API
new file mode 100644
index 0000000..901cc88
--- /dev/null
+++ b/plugins/sudoers/auth/API
@@ -0,0 +1,135 @@
+NOTE: the Sudo auth API is subject to change
+
+Purpose: to provide a simple API for authentication methods that
+ encapsulates things nicely without turning into a maze
+ of #ifdef's
+
+The sudo_auth struct looks like this:
+
+typedef struct sudo_auth {
+ int flags; /* various flags, see below */
+ int status; /* status from verify routine */
+ char *name; /* name of the method in string form */
+ void *data; /* method-specific data pointer */
+
+ int (*init)(struct passwd *pw, sudo_auth *auth);
+ int (*setup)(struct passwd *pw, char **prompt, sudo_auth *auth);
+ int (*verify)(struct passwd *pw, char *p, sudo_auth *auth, struct sudo_conv_callback *callback);
+ int (*approval)(struct passwd *pw, sudo_auth *auth);
+ int (*cleanup)(struct passwd *pw, sudo_auth *auth);
+ int (*begin_session)(struct passwd *pw, char **user_env[], struct sudo_auth *auth);
+ int (*end_session)(struct passwd *pw, struct sudo_auth *auth);
+} sudo_auth;
+
+The variables in the struct are as follows:
+ flags Bitwise binary flags, see below.
+
+ status Contains the return value from the last run of
+ the "verify" function. Starts out as AUTH_FAILURE.
+
+ name The name of the authentication method as a C string.
+
+ data A pointer to method-specific data. This is passed to
+ all the functions of an auth method and is usually
+ initialized in the "init" or "setup" routines.
+
+Possible values of sudo_auth.flags:
+ FLAG_DISABLED Set if an "init" or "setup" function fails.
+
+ FLAG_STANDALONE If set, this indicates that the method must
+ be the only auth method configured, and that
+ it will prompt for the password itself.
+
+ FLAG_ONEANDONLY If set, this indicates that the method is the
+ only one in use. Can be used by auth functions
+ to determine whether to return a fatal or nonfatal
+ error.
+
+The member functions can return the following values:
+ AUTH_SUCCESS Function succeeded. For a ``verify'' function
+ this means the user correctly authenticated.
+
+ AUTH_FAILURE Function failed. If this is an ``init'' or
+ ``setup'' routine, the auth method will be
+ marked as !configured.
+
+ AUTH_FATAL A fatal error occurred. The routine should have
+ written an error message to stderr and optionally
+ sent mail to the administrator.
+ When verify_user() gets AUTH_FATAL from an auth
+ function it does an exit(1).
+
+The functions in the struct are as follows:
+
+ int init(struct passwd *pw, sudo_auth *auth)
+ Function to do any one-time initialization for the auth
+ method. All of the "init" functions are run before anything
+ else.
+
+ int setup(struct passwd *pw, char **prompt, sudo_auth *auth)
+ Function to do method-specific setup. All the "setup"
+ routines are run before any of the "verify" routines. A
+ pointer to the prompt string may be used to add method-specific
+ info to the prompt.
+
+ int verify(struct passwd *pw, char *p, sudo_auth *auth, struct sudo_conv_callback *callback)
+ Function to do user verification for this auth method. For
+ standalone auth methods ``p'' is the prompt string. For
+ normal auth methods, ``p'' is the password the user entered.
+ The callback should be passed to auth_getpass() to allow sudoers
+ to unlock the ticket file when sudo is suspended.
+ Note that standalone auth methods are responsible for
+ rerading the password themselves.
+
+ int approval(struct passwd *pw, struct sudo_auth *auth)
+ Function to perform account management and approval *after*
+ the user has authenticated successfully. This function may
+ check for expired accounts, perform time of day restrictions, etc.
+ For PAM, this calls pam_acct_mgmt(). For BSD auth, it calls
+ auth_approval().
+
+ int cleanup(struct passwd *pw, sudo_auth *auth)
+ Function to do per-auth method cleanup. This is only run
+ at the end of the authentication process, after the user
+ has completely failed or succeeded to authenticate.
+ The ``auth->status'' variable contains the result of the
+ last authentication attempt which may be interesting.
+
+ int begin_session(struct passwd *pw, char **user_env[], struct sudo_auth *auth)
+ Function to begin a user session. This is used for session handling
+ in PAM and SIA.
+
+ int end_session(struct passwd *pw, struct sudo_auth *auth)
+ Function to end a user session. This is used for session handling
+ in PAM and SIA.
+
+A note about standalone methods. Some authentication methods can't
+coexist with any others. This may be because they encapsulate other
+methods (pam, sia) or because they have a special way of interacting
+with the user (securid).
+
+Adding a new authentication method:
+
+Each method should live in its own file. Add prototypes for the functions
+in sudo_auth.h.
+
+Add the method to the ``auth_switch'' in sudo_auth.c. Note that
+standalone methods must go first. If ``fooauth'' is a normal auth
+method, its entry would look like:
+
+#ifdef HAVE_FOOAUTH
+AUTH_ENTRY("foo", 0, foo_init, foo_setup, foo_verify,
+ foo_cleanup, foo_begin_session, foo_end_session)
+#endif
+
+If this is a standalone method, it would be:
+
+#ifdef HAVE_FOOAUTH
+AUTH_ENTRY("foo", FLAG_STANDALONE, foo_init, foo_setup, foo_verify,
+ foo_cleanup, foo_begin_session, foo_end_session)
+#endif
+
+If the method needs to run as the user, not root, add FLAG_USER to
+the second argument in the AUTH_ENTRY line. If you don't have an
+init/setup/cleanup/begin/end routine, just use a NULL for that
+field.
diff --git a/plugins/sudoers/auth/afs.c b/plugins/sudoers/auth/afs.c
new file mode 100644
index 0000000..fa40e05
--- /dev/null
+++ b/plugins/sudoers/auth/afs.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1999, 2001-2005, 2007, 2010-2012, 2014-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_AFS
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRING_H */
+#include <unistd.h>
+#include <pwd.h>
+
+#include <afs/stds.h>
+#include <afs/kautils.h>
+
+#include "sudoers.h"
+#include "sudo_auth.h"
+
+int
+sudo_afs_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback)
+{
+ struct ktc_encryptionKey afs_key;
+ struct ktc_token afs_token;
+ debug_decl(sudo_afs_verify, SUDOERS_DEBUG_AUTH)
+
+ /* Try to just check the password */
+ ka_StringToKey(pass, NULL, &afs_key);
+ if (ka_GetAdminToken(pw->pw_name, /* name */
+ NULL, /* instance */
+ NULL, /* realm */
+ &afs_key, /* key (contains password) */
+ 0, /* lifetime */
+ &afs_token, /* token */
+ 0) == 0) /* new */
+ debug_return_int(AUTH_SUCCESS);
+
+ /* Fall back on old method XXX - needed? */
+ setpag();
+ if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION+KA_USERAUTH_DOSETPAG,
+ pw->pw_name, /* name */
+ NULL, /* instance */
+ NULL, /* realm */
+ pass, /* password */
+ 0, /* lifetime */
+ NULL, /* expiration ptr (unused) */
+ 0, /* spare */
+ NULL) == 0) /* reason */
+ debug_return_int(AUTH_SUCCESS);
+
+ debug_return_int(AUTH_FAILURE);
+}
+
+#endif HAVE_AFS
diff --git a/plugins/sudoers/auth/aix_auth.c b/plugins/sudoers/auth/aix_auth.c
new file mode 100644
index 0000000..b4dc052
--- /dev/null
+++ b/plugins/sudoers/auth/aix_auth.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 1999-2005, 2007-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_AIXAUTH
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRING_H */
+#include <unistd.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <usersec.h>
+
+#include "sudoers.h"
+#include "sudo_auth.h"
+
+/*
+ * For a description of the AIX authentication API, see
+ * http://publib16.boulder.ibm.com/doc_link/en_US/a_doc_lib/libs/basetrf1/authenticate.htm
+ */
+
+#ifdef HAVE_PAM
+# define AIX_AUTH_UNKNOWN 0
+# define AIX_AUTH_STD 1
+# define AIX_AUTH_PAM 2
+
+static int
+sudo_aix_authtype(void)
+{
+ size_t linesize = 0;
+ ssize_t len;
+ char *cp, *line = NULL;
+ bool in_stanza = false;
+ int authtype = AIX_AUTH_UNKNOWN;
+ FILE *fp;
+ debug_decl(sudo_aix_authtype, SUDOERS_DEBUG_AUTH)
+
+ if ((fp = fopen("/etc/security/login.cfg", "r")) != NULL) {
+ while (authtype == AIX_AUTH_UNKNOWN && (len = getline(&line, &linesize, fp)) != -1) {
+ /* First remove comments. */
+ if ((cp = strchr(line, '#')) != NULL) {
+ *cp = '\0';
+ len = (ssize_t)(cp - line);
+ }
+
+ /* Next remove trailing newlines and whitespace. */
+ while (len > 0 && isspace((unsigned char)line[len - 1]))
+ line[--len] = '\0';
+
+ /* Skip blank lines. */
+ if (len == 0)
+ continue;
+
+ /* Match start of the usw stanza. */
+ if (!in_stanza) {
+ if (strncmp(line, "usw:", 4) == 0)
+ in_stanza = true;
+ continue;
+ }
+
+ /* Check for end of the usw stanza. */
+ if (!isblank((unsigned char)line[0])) {
+ in_stanza = false;
+ break;
+ }
+
+ /* Skip leading blanks. */
+ cp = line;
+ do {
+ cp++;
+ } while (isblank((unsigned char)*cp));
+
+ /* Match "auth_type = (PAM_AUTH|STD_AUTH)". */
+ if (strncmp(cp, "auth_type", 9) != 0)
+ continue;
+ cp += 9;
+ while (isblank((unsigned char)*cp))
+ cp++;
+ if (*cp++ != '=')
+ continue;
+ while (isblank((unsigned char)*cp))
+ cp++;
+ if (strcmp(cp, "PAM_AUTH") == 0)
+ authtype = AIX_AUTH_PAM;
+ else if (strcmp(cp, "STD_AUTH") == 0)
+ authtype = AIX_AUTH_STD;
+ }
+ free(line);
+ fclose(fp);
+ }
+
+ debug_return_int(authtype);
+}
+#endif /* HAVE_PAM */
+
+int
+sudo_aix_init(struct passwd *pw, sudo_auth *auth)
+{
+ debug_decl(sudo_aix_init, SUDOERS_DEBUG_AUTH)
+
+#ifdef HAVE_PAM
+ /* Check auth_type in /etc/security/login.cfg. */
+ if (sudo_aix_authtype() == AIX_AUTH_PAM) {
+ if (sudo_pam_init_quiet(pw, auth) == AUTH_SUCCESS) {
+ /* Fail AIX authentication so we can use PAM instead. */
+ debug_return_int(AUTH_FAILURE);
+ }
+ }
+#endif
+ debug_return_int(AUTH_SUCCESS);
+}
+
+int
+sudo_aix_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback)
+{
+ char *pass, *message = NULL;
+ int result = 1, reenter = 0;
+ int ret = AUTH_SUCCESS;
+ debug_decl(sudo_aix_verify, SUDOERS_DEBUG_AUTH)
+
+ do {
+ pass = auth_getpass(prompt, SUDO_CONV_PROMPT_ECHO_OFF, callback);
+ if (pass == NULL)
+ break;
+ free(message);
+ message = NULL;
+ result = authenticate(pw->pw_name, pass, &reenter, &message);
+ memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
+ free(pass);
+ prompt = message;
+ } while (reenter);
+
+ if (result != 0) {
+ /* Display error message, if any. */
+ if (message != NULL) {
+ struct sudo_conv_message msg;
+ struct sudo_conv_reply repl;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_type = SUDO_CONV_ERROR_MSG;
+ msg.msg = message;
+ memset(&repl, 0, sizeof(repl));
+ sudo_conv(1, &msg, &repl, NULL);
+ }
+ ret = pass ? AUTH_FAILURE : AUTH_INTR;
+ }
+ free(message);
+ debug_return_int(ret);
+}
+
+int
+sudo_aix_cleanup(struct passwd *pw, sudo_auth *auth)
+{
+ debug_decl(sudo_aix_cleanup, SUDOERS_DEBUG_AUTH)
+
+ /* Unset AUTHSTATE as it may not be correct for the runas user. */
+ if (sudo_unsetenv("AUTHSTATE") == -1)
+ debug_return_int(AUTH_FAILURE);
+
+ debug_return_int(AUTH_SUCCESS);
+}
+
+#endif /* HAVE_AIXAUTH */
diff --git a/plugins/sudoers/auth/bsdauth.c b/plugins/sudoers/auth/bsdauth.c
new file mode 100644
index 0000000..7357214
--- /dev/null
+++ b/plugins/sudoers/auth/bsdauth.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2000-2005, 2007-2008, 2010-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_BSD_AUTH_H
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRING_H */
+#include <unistd.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <signal.h>
+
+#include <login_cap.h>
+#include <bsd_auth.h>
+
+#include "sudoers.h"
+#include "sudo_auth.h"
+
+# ifndef LOGIN_DEFROOTCLASS
+# define LOGIN_DEFROOTCLASS "daemon"
+# endif
+
+struct bsdauth_state {
+ auth_session_t *as;
+ login_cap_t *lc;
+};
+
+int
+bsdauth_init(struct passwd *pw, sudo_auth *auth)
+{
+ static struct bsdauth_state state;
+ debug_decl(bsdauth_init, SUDOERS_DEBUG_AUTH)
+
+ /* Get login class based on auth user, which may not be invoking user. */
+ if (pw->pw_class && *pw->pw_class)
+ state.lc = login_getclass(pw->pw_class);
+ else
+ state.lc = login_getclass(pw->pw_uid ? LOGIN_DEFCLASS : LOGIN_DEFROOTCLASS);
+ if (state.lc == NULL) {
+ log_warning(0,
+ N_("unable to get login class for user %s"), pw->pw_name);
+ debug_return_int(AUTH_FATAL);
+ }
+
+ if ((state.as = auth_open()) == NULL) {
+ log_warning(0, N_("unable to begin bsd authentication"));
+ login_close(state.lc);
+ debug_return_int(AUTH_FATAL);
+ }
+
+ /* XXX - maybe sanity check the auth style earlier? */
+ login_style = login_getstyle(state.lc, login_style, "auth-sudo");
+ if (login_style == NULL) {
+ log_warningx(0, N_("invalid authentication type"));
+ auth_close(state.as);
+ login_close(state.lc);
+ debug_return_int(AUTH_FATAL);
+ }
+
+ if (auth_setitem(state.as, AUTHV_STYLE, login_style) < 0 ||
+ auth_setitem(state.as, AUTHV_NAME, pw->pw_name) < 0 ||
+ auth_setitem(state.as, AUTHV_CLASS, login_class) < 0) {
+ log_warningx(0, N_("unable to initialize BSD authentication"));
+ auth_close(state.as);
+ login_close(state.lc);
+ debug_return_int(AUTH_FATAL);
+ }
+
+ auth->data = (void *) &state;
+ debug_return_int(AUTH_SUCCESS);
+}
+
+int
+bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback)
+{
+ char *pass;
+ char *s;
+ size_t len;
+ int authok = 0;
+ struct sigaction sa, osa;
+ auth_session_t *as = ((struct bsdauth_state *) auth->data)->as;
+ debug_decl(bsdauth_verify, SUDOERS_DEBUG_AUTH)
+
+ /* save old signal handler */
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = SIG_DFL;
+ (void) sigaction(SIGCHLD, &sa, &osa);
+
+ /*
+ * If there is a challenge then print that instead of the normal
+ * prompt. If the user just hits return we prompt again with echo
+ * turned on, which is useful for challenge/response things like
+ * S/Key.
+ */
+ if ((s = auth_challenge(as)) == NULL) {
+ pass = auth_getpass(prompt, SUDO_CONV_PROMPT_ECHO_OFF, callback);
+ } else {
+ pass = auth_getpass(s, SUDO_CONV_PROMPT_ECHO_OFF, callback);
+ if (pass && *pass == '\0') {
+ if ((prompt = strrchr(s, '\n')))
+ prompt++;
+ else
+ prompt = s;
+
+ /*
+ * Append '[echo on]' to the last line of the challenge and
+ * reprompt with echo turned on.
+ */
+ len = strlen(prompt) - 1;
+ while (isspace(prompt[len]) || prompt[len] == ':')
+ prompt[len--] = '\0';
+ if (asprintf(&s, "%s [echo on]: ", prompt) == -1) {
+ log_warningx(0, N_("unable to allocate memory"));
+ debug_return_int(AUTH_FATAL);
+ }
+ free(pass);
+ pass = auth_getpass(s, SUDO_CONV_PROMPT_ECHO_ON, callback);
+ free(s);
+ }
+ }
+
+ if (pass) {
+ authok = auth_userresponse(as, pass, 1);
+ memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
+ free(pass);
+ }
+
+ /* restore old signal handler */
+ (void) sigaction(SIGCHLD, &osa, NULL);
+
+ if (authok)
+ debug_return_int(AUTH_SUCCESS);
+
+ if (!pass)
+ debug_return_int(AUTH_INTR);
+
+ if ((s = auth_getvalue(as, "errormsg")) != NULL)
+ log_warningx(0, "%s", s);
+ debug_return_int(AUTH_FAILURE);
+}
+
+int
+bsdauth_approval(struct passwd *pw, sudo_auth *auth, bool exempt)
+{
+ struct bsdauth_state *state = auth->data;
+ debug_decl(bsdauth_approval, SUDOERS_DEBUG_AUTH)
+
+ if (auth_approval(state->as, state->lc, pw->pw_name, "auth-sudo") == 0) {
+ if (auth_getstate(state->as) & AUTH_EXPIRED)
+ log_warningx(0, "%s", N_("your account has expired"));
+ else
+ log_warningx(0, "%s", N_("approval failed"));
+ debug_return_int(AUTH_FAILURE);
+ }
+ debug_return_int(AUTH_SUCCESS);
+}
+
+int
+bsdauth_cleanup(struct passwd *pw, sudo_auth *auth)
+{
+ struct bsdauth_state *state = auth->data;
+ debug_decl(bsdauth_cleanup, SUDOERS_DEBUG_AUTH)
+
+ if (state != NULL) {
+ auth_close(state->as);
+ login_close(state->lc);
+ }
+
+ debug_return_int(AUTH_SUCCESS);
+}
+
+#endif /* HAVE_BSD_AUTH_H */
diff --git a/plugins/sudoers/auth/dce.c b/plugins/sudoers/auth/dce.c
new file mode 100644
index 0000000..0afe8c6
--- /dev/null
+++ b/plugins/sudoers/auth/dce.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2010-2012, 2014-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+/*
+ * The code below basically comes from the examples supplied on
+ * the OSF DCE 1.0.3 manpages for the sec_login routines, with
+ * enough additional polishing to make the routine work with the
+ * rest of sudo.
+ *
+ * This code is known to work on HP 700 and 800 series systems
+ * running HP-UX 9.X and 10.X, with either HP's version 1.2.1 of DCE.
+ * (aka, OSF DCE 1.0.3) or with HP's version 1.4 of DCE (aka, OSF
+ * DCE 1.1).
+ */
+
+#include <config.h>
+
+#ifdef HAVE_DCE
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRING_H */
+#include <unistd.h>
+#include <pwd.h>
+
+#include <dce/rpc.h>
+#include <dce/sec_login.h>
+#include <dce/dce_error.h> /* required to call dce_error_inq_text routine */
+
+#include "sudoers.h"
+#include "sudo_auth.h"
+
+static int check_dce_status(error_status_t, char *);
+
+int
+sudo_dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth, struct sudo_conv_callback *callback)
+{
+ struct passwd temp_pw;
+ sec_passwd_rec_t password_rec;
+ sec_login_handle_t login_context;
+ boolean32 reset_passwd;
+ sec_login_auth_src_t auth_src;
+ error_status_t status;
+ debug_decl(sudo_dce_verify, SUDOERS_DEBUG_AUTH)
+
+ /*
+ * Create the local context of the DCE principal necessary
+ * to perform authenticated network operations. The network
+ * identity set up by this operation cannot be used until it
+ * is validated via sec_login_validate_identity().
+ */
+ if (sec_login_setup_identity((unsigned_char_p_t) pw->pw_name,
+ sec_login_no_flags, &login_context, &status)) {
+
+ if (check_dce_status(status, "sec_login_setup_identity(1):"))
+ debug_return_int(AUTH_FAILURE);
+
+ password_rec.key.key_type = sec_passwd_plain;
+ password_rec.key.tagged_union.plain = (idl_char *) plain_pw;
+ password_rec.pepper = NULL;
+ password_rec.version_number = sec_passwd_c_version_none;
+
+ /* Validate the login context with the password */
+ if (sec_login_validate_identity(login_context, &password_rec,
+ &reset_passwd, &auth_src, &status)) {
+
+ if (check_dce_status(status, "sec_login_validate_identity(1):"))
+ debug_return_int(AUTH_FAILURE);
+
+ /*
+ * Certify that the DCE Security Server used to set
+ * up and validate a login context is legitimate. Makes
+ * sure that we didn't get spoofed by another DCE server.
+ */
+ if (!sec_login_certify_identity(login_context, &status)) {
+ sudo_printf(SUDO_CONV_ERROR_MSG,
+ "Whoa! Bogus authentication server!\n");
+ (void) check_dce_status(status,"sec_login_certify_identity(1):");
+ debug_return_int(AUTH_FAILURE);
+ }
+ if (check_dce_status(status, "sec_login_certify_identity(2):"))
+ debug_return_int(AUTH_FAILURE);
+
+ /*
+ * Sets the network credentials to those specified
+ * by the now validated login context.
+ */
+ sec_login_set_context(login_context, &status);
+ if (check_dce_status(status, "sec_login_set_context:"))
+ debug_return_int(AUTH_FAILURE);
+
+ /*
+ * Oops, your credentials were no good. Possibly
+ * caused by clock times out of adjustment between
+ * DCE client and DCE security server...
+ */
+ if (auth_src != sec_login_auth_src_network) {
+ sudo_printf(SUDO_CONV_ERROR_MSG,
+ "You have no network credentials.\n");
+ debug_return_int(AUTH_FAILURE);
+ }
+ /* Check if the password has aged and is thus no good */
+ if (reset_passwd) {
+ sudo_printf(SUDO_CONV_ERROR_MSG,
+ "Your DCE password needs resetting.\n");
+ debug_return_int(AUTH_FAILURE);
+ }
+
+ /*
+ * We should be a valid user by this point. Pull the
+ * user's password structure from the DCE security
+ * server just to make sure. If we get it with no
+ * problems, then we really are legitimate...
+ */
+ sec_login_get_pwent(login_context, (sec_login_passwd_t) &temp_pw,
+ &status);
+ if (check_dce_status(status, "sec_login_get_pwent:"))
+ debug_return_int(AUTH_FAILURE);
+
+ /*
+ * If we get to here, then the pwent above properly fetched
+ * the password structure from the DCE registry, so the user
+ * must be valid. We don't really care what the user's
+ * registry password is, just that the user could be
+ * validated. In fact, if we tried to compare the local
+ * password to the DCE entry at this point, the operation
+ * would fail if the hidden password feature is turned on,
+ * because the password field would contain an asterisk.
+ * Also go ahead and destroy the user's DCE login context
+ * before we leave here (and don't bother checking the
+ * status), in order to clean up credentials files in
+ * /opt/dcelocal/var/security/creds. By doing this, we are
+ * assuming that the user will not need DCE authentication
+ * later in the program, only local authentication. If this
+ * is not true, then the login_context will have to be
+ * returned to the calling program, and the context purged
+ * somewhere later in the program.
+ */
+ sec_login_purge_context(&login_context, &status);
+ debug_return_int(AUTH_SUCCESS);
+ } else {
+ if(check_dce_status(status, "sec_login_validate_identity(2):"))
+ debug_return_int(AUTH_FAILURE);
+ sec_login_purge_context(&login_context, &status);
+ if(check_dce_status(status, "sec_login_purge_context:"))
+ debug_return_int(AUTH_FAILURE);
+ }
+ }
+ (void) check_dce_status(status, "sec_login_setup_identity(2):");
+ debug_return_int(AUTH_FAILURE);
+}
+
+/* Returns 0 for DCE "ok" status, 1 otherwise */
+static int
+check_dce_status(error_status_t input_status, char *comment)
+{
+ int error_stat;
+ unsigned char error_string[dce_c_error_string_len];
+ debug_decl(check_dce_status, SUDOERS_DEBUG_AUTH)
+
+ if (input_status == rpc_s_ok)
+ debug_return_int(0);
+ dce_error_inq_text(input_status, error_string, &error_stat);
+ sudo_printf(SUDO_CONV_ERROR_MSG, "%s %s\n", comment, error_string);
+ debug_return_int(1);
+}
+
+#endif /* HAVE_DCE */
diff --git a/plugins/sudoers/auth/fwtk.c b/plugins/sudoers/auth/fwtk.c
new file mode 100644
index 0000000..36f7cd8
--- /dev/null
+++ b/plugins/sudoers/auth/fwtk.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 1999-2005, 2008, 2010-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_FWTK
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRING_H */
+#include <unistd.h>
+#include <pwd.h>
+
+#include <auth.h>
+#include <firewall.h>
+
+#include "sudoers.h"
+#include "sudo_auth.h"
+
+int
+sudo_fwtk_init(struct passwd *pw, sudo_auth *auth)
+{
+ static Cfg *confp; /* Configuration entry struct */
+ char resp[128]; /* Response from the server */
+ debug_decl(sudo_fwtk_init, SUDOERS_DEBUG_AUTH)
+
+ if ((confp = cfg_read("sudo")) == (Cfg *)-1) {
+ sudo_warnx(U_("unable to read fwtk config"));
+ debug_return_int(AUTH_FATAL);
+ }
+
+ if (auth_open(confp)) {
+ sudo_warnx(U_("unable to connect to authentication server"));
+ debug_return_int(AUTH_FATAL);
+ }
+
+ /* Get welcome message from auth server */
+ if (auth_recv(resp, sizeof(resp))) {
+ sudo_warnx(U_("lost connection to authentication server"));
+ debug_return_int(AUTH_FATAL);
+ }
+ if (strncmp(resp, "Authsrv ready", 13) != 0) {
+ sudo_warnx(U_("authentication server error:\n%s"), resp);
+ debug_return_int(AUTH_FATAL);
+ }
+
+ debug_return_int(AUTH_SUCCESS);
+}
+
+int
+sudo_fwtk_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback)
+{
+ char *pass; /* Password from the user */
+ char buf[SUDO_CONV_REPL_MAX + 12]; /* General prupose buffer */
+ char resp[128]; /* Response from the server */
+ int error;
+ debug_decl(sudo_fwtk_verify, SUDOERS_DEBUG_AUTH)
+
+ /* Send username to authentication server. */
+ (void) snprintf(buf, sizeof(buf), "authorize %s 'sudo'", pw->pw_name);
+restart:
+ if (auth_send(buf) || auth_recv(resp, sizeof(resp))) {
+ sudo_warnx(U_("lost connection to authentication server"));
+ debug_return_int(AUTH_FATAL);
+ }
+
+ /* Get the password/response from the user. */
+ if (strncmp(resp, "challenge ", 10) == 0) {
+ (void) snprintf(buf, sizeof(buf), "%s\nResponse: ", &resp[10]);
+ pass = auth_getpass(buf, SUDO_CONV_PROMPT_ECHO_OFF, callback);
+ if (pass && *pass == '\0') {
+ free(pass);
+ pass = auth_getpass("Response [echo on]: ",
+ SUDO_CONV_PROMPT_ECHO_ON, callback);
+ }
+ } else if (strncmp(resp, "chalnecho ", 10) == 0) {
+ pass = auth_getpass(&resp[10], SUDO_CONV_PROMPT_ECHO_OFF, callback);
+ } else if (strncmp(resp, "password", 8) == 0) {
+ pass = auth_getpass(prompt, SUDO_CONV_PROMPT_ECHO_OFF, callback);
+ } else if (strncmp(resp, "display ", 8) == 0) {
+ sudo_printf(SUDO_CONV_INFO_MSG, "%s\n", &resp[8]);
+ strlcpy(buf, "response dummy", sizeof(buf));
+ goto restart;
+ } else {
+ sudo_warnx("%s", resp);
+ debug_return_int(AUTH_FATAL);
+ }
+ if (!pass) { /* ^C or error */
+ debug_return_int(AUTH_INTR);
+ }
+
+ /* Send the user's response to the server */
+ (void) snprintf(buf, sizeof(buf), "response '%s'", pass);
+ if (auth_send(buf) || auth_recv(resp, sizeof(resp))) {
+ sudo_warnx(U_("lost connection to authentication server"));
+ error = AUTH_FATAL;
+ goto done;
+ }
+
+ if (strncmp(resp, "ok", 2) == 0) {
+ error = AUTH_SUCCESS;
+ goto done;
+ }
+
+ /* Main loop prints "Permission Denied" or insult. */
+ if (strcmp(resp, "Permission Denied.") != 0)
+ sudo_warnx("%s", resp);
+ error = AUTH_FAILURE;
+done:
+ memset_s(buf, sizeof(buf), 0, sizeof(buf));
+ memset_s(pass, SUDO_PASS_MAX, 0, strlen(pass));
+ free(pass);
+ debug_return_int(error);
+}
+
+int
+sudo_fwtk_cleanup(struct passwd *pw, sudo_auth *auth)
+{
+ debug_decl(sudo_fwtk_cleanup, SUDOERS_DEBUG_AUTH)
+
+ auth_close();
+ debug_return_int(AUTH_SUCCESS);
+}
+
+#endif /* HAVE_FWTK */
diff --git a/plugins/sudoers/auth/kerb5.c b/plugins/sudoers/auth/kerb5.c
new file mode 100644
index 0000000..247981c
--- /dev/null
+++ b/plugins/sudoers/auth/kerb5.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 1999-2005, 2007-2008, 2010-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_KERB5
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRING_H */
+#include <unistd.h>
+#include <pwd.h>
+#include <krb5.h>
+#ifdef HAVE_HEIMDAL
+#include <com_err.h>
+#endif
+
+#include "sudoers.h"
+#include "sudo_auth.h"
+
+#ifdef HAVE_HEIMDAL
+# define extract_name(c, p) krb5_principal_get_comp_string(c, p, 1)
+# define krb5_free_data_contents(c, d) krb5_data_free(d)
+#else
+# define extract_name(c, p) (krb5_princ_component(c, p, 1)->data)
+#endif
+
+#ifndef HAVE_KRB5_VERIFY_USER
+static int verify_krb_v5_tgt(krb5_context, krb5_creds *, char *);
+#endif
+static struct _sudo_krb5_data {
+ krb5_context sudo_context;
+ krb5_principal princ;
+ krb5_ccache ccache;
+} sudo_krb5_data = { NULL, NULL, NULL };
+typedef struct _sudo_krb5_data *sudo_krb5_datap;
+
+#ifdef SUDO_KRB5_INSTANCE
+static const char *sudo_krb5_instance = SUDO_KRB5_INSTANCE;
+#else
+static const char *sudo_krb5_instance = NULL;
+#endif
+
+#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
+static krb5_error_code
+krb5_get_init_creds_opt_alloc(krb5_context context,
+ krb5_get_init_creds_opt **opts)
+{
+ *opts = malloc(sizeof(krb5_get_init_creds_opt));
+ if (*opts == NULL)
+ return KRB5_CC_NOMEM;
+ krb5_get_init_creds_opt_init(*opts);
+ return 0;
+}
+
+static void
+krb5_get_init_creds_opt_free(krb5_get_init_creds_opt *opts)
+{
+ free(opts);
+}
+#endif
+
+int
+sudo_krb5_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
+{
+ static char *krb5_prompt;
+ debug_decl(sudo_krb5_init, SUDOERS_DEBUG_AUTH)
+
+ if (krb5_prompt == NULL) {
+ krb5_context sudo_context;
+ krb5_principal princ;
+ char *pname;
+ krb5_error_code error;
+
+ sudo_context = ((sudo_krb5_datap) auth->data)->sudo_context;
+ princ = ((sudo_krb5_datap) auth->data)->princ;
+
+ /*
+ * Really, we need to tell the caller not to prompt for password. The
+ * API does not currently provide this unless the auth is standalone.
+ */
+ if ((error = krb5_unparse_name(sudo_context, princ, &pname))) {
+ log_warningx(0,
+ N_("%s: unable to convert principal to string ('%s'): %s"),
+ auth->name, pw->pw_name, error_message(error));
+ debug_return_int(AUTH_FAILURE);
+ }
+
+ /* Only rewrite prompt if user didn't specify their own. */
+ /*if (!strcmp(prompt, PASSPROMPT)) { */
+ if (asprintf(&krb5_prompt, "Password for %s: ", pname) == -1) {
+ log_warningx(0, N_("unable to allocate memory"));
+ free(pname);
+ debug_return_int(AUTH_FATAL);
+ }
+ /*}*/
+ free(pname);
+ }
+ *promptp = krb5_prompt;
+
+ debug_return_int(AUTH_SUCCESS);
+}
+
+int
+sudo_krb5_init(struct passwd *pw, sudo_auth *auth)
+{
+ krb5_context sudo_context;
+ krb5_error_code error;
+ char cache_name[64], *pname = pw->pw_name;
+ debug_decl(sudo_krb5_init, SUDOERS_DEBUG_AUTH)
+
+ auth->data = (void *) &sudo_krb5_data; /* Stash all our data here */
+
+ if (sudo_krb5_instance != NULL) {
+ int len = asprintf(&pname, "%s%s%s", pw->pw_name,
+ sudo_krb5_instance[0] != '/' ? "/" : "", sudo_krb5_instance);
+ if (len == -1) {
+ log_warningx(0, N_("unable to allocate memory"));
+ debug_return_int(AUTH_FATAL);
+ }
+ }
+
+#ifdef HAVE_KRB5_INIT_SECURE_CONTEXT
+ error = krb5_init_secure_context(&(sudo_krb5_data.sudo_context));
+#else
+ error = krb5_init_context(&(sudo_krb5_data.sudo_context));
+#endif
+ if (error)
+ goto done;
+ sudo_context = sudo_krb5_data.sudo_context;
+
+ error = krb5_parse_name(sudo_context, pname, &(sudo_krb5_data.princ));
+ if (error) {
+ log_warningx(0, N_("%s: unable to parse '%s': %s"), auth->name, pname,
+ error_message(error));
+ goto done;
+ }
+
+ (void) snprintf(cache_name, sizeof(cache_name), "MEMORY:sudocc_%ld",
+ (long) getpid());
+ if ((error = krb5_cc_resolve(sudo_context, cache_name,
+ &(sudo_krb5_data.ccache)))) {
+ log_warningx(0, N_("%s: unable to resolve credential cache: %s"),
+ auth->name, error_message(error));
+ goto done;
+ }
+
+done:
+ if (sudo_krb5_instance != NULL)
+ free(pname);
+ debug_return_int(error ? AUTH_FAILURE : AUTH_SUCCESS);
+}
+
+#ifdef HAVE_KRB5_VERIFY_USER
+int
+sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback)
+{
+ krb5_context sudo_context;
+ krb5_principal princ;
+ krb5_ccache ccache;
+ krb5_error_code error;
+ debug_decl(sudo_krb5_verify, SUDOERS_DEBUG_AUTH)
+
+ sudo_context = ((sudo_krb5_datap) auth->data)->sudo_context;
+ princ = ((sudo_krb5_datap) auth->data)->princ;
+ ccache = ((sudo_krb5_datap) auth->data)->ccache;
+
+ error = krb5_verify_user(sudo_context, princ, ccache, pass, 1, NULL);
+ debug_return_int(error ? AUTH_FAILURE : AUTH_SUCCESS);
+}
+#else
+int
+sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback)
+{
+ krb5_context sudo_context;
+ krb5_principal princ;
+ krb5_creds credbuf, *creds = NULL;
+ krb5_ccache ccache;
+ krb5_error_code error;
+ krb5_get_init_creds_opt *opts = NULL;
+ debug_decl(sudo_krb5_verify, SUDOERS_DEBUG_AUTH)
+
+ sudo_context = ((sudo_krb5_datap) auth->data)->sudo_context;
+ princ = ((sudo_krb5_datap) auth->data)->princ;
+ ccache = ((sudo_krb5_datap) auth->data)->ccache;
+
+ /* Set default flags based on the local config file. */
+ error = krb5_get_init_creds_opt_alloc(sudo_context, &opts);
+ if (error) {
+ log_warningx(0, N_("%s: unable to allocate options: %s"), auth->name,
+ error_message(error));
+ goto done;
+ }
+#ifdef HAVE_HEIMDAL
+ krb5_get_init_creds_opt_set_default_flags(sudo_context, NULL,
+ krb5_principal_get_realm(sudo_context, princ), opts);
+#endif
+
+ /* Note that we always obtain a new TGT to verify the user */
+ if ((error = krb5_get_init_creds_password(sudo_context, &credbuf, princ,
+ pass, krb5_prompter_posix,
+ NULL, 0, NULL, opts))) {
+ /* Don't print error if just a bad password */
+ if (error != KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+ log_warningx(0, N_("%s: unable to get credentials: %s"),
+ auth->name, error_message(error));
+ }
+ goto done;
+ }
+ creds = &credbuf;
+
+ /* Verify the TGT to prevent spoof attacks. */
+ if ((error = verify_krb_v5_tgt(sudo_context, creds, auth->name)))
+ goto done;
+
+ /* Store credential in cache. */
+ if ((error = krb5_cc_initialize(sudo_context, ccache, princ))) {
+ log_warningx(0, N_("%s: unable to initialize credential cache: %s"),
+ auth->name, error_message(error));
+ } else if ((error = krb5_cc_store_cred(sudo_context, ccache, creds))) {
+ log_warningx(0, N_("%s: unable to store credential in cache: %s"),
+ auth->name, error_message(error));
+ }
+
+done:
+ if (opts) {
+#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_TWO_ARGS
+ krb5_get_init_creds_opt_free(sudo_context, opts);
+#else
+ krb5_get_init_creds_opt_free(opts);
+#endif
+ }
+ if (creds)
+ krb5_free_cred_contents(sudo_context, creds);
+ debug_return_int(error ? AUTH_FAILURE : AUTH_SUCCESS);
+}
+#endif
+
+int
+sudo_krb5_cleanup(struct passwd *pw, sudo_auth *auth)
+{
+ krb5_context sudo_context;
+ krb5_principal princ;
+ krb5_ccache ccache;
+ debug_decl(sudo_krb5_cleanup, SUDOERS_DEBUG_AUTH)
+
+ sudo_context = ((sudo_krb5_datap) auth->data)->sudo_context;
+ princ = ((sudo_krb5_datap) auth->data)->princ;
+ ccache = ((sudo_krb5_datap) auth->data)->ccache;
+
+ if (sudo_context) {
+ if (ccache)
+ krb5_cc_destroy(sudo_context, ccache);
+ if (princ)
+ krb5_free_principal(sudo_context, princ);
+ krb5_free_context(sudo_context);
+ }
+
+ debug_return_int(AUTH_SUCCESS);
+}
+
+#ifndef HAVE_KRB5_VERIFY_USER
+/*
+ * Verify the Kerberos ticket-granting ticket just retrieved for the
+ * user. If the Kerberos server doesn't respond, assume the user is
+ * trying to fake us out (since we DID just get a TGT from what is
+ * supposedly our KDC).
+ *
+ * Returns 0 for successful authentication, non-zero for failure.
+ */
+static int
+verify_krb_v5_tgt(krb5_context sudo_context, krb5_creds *cred, char *auth_name)
+{
+ krb5_error_code error;
+ krb5_principal server;
+ krb5_verify_init_creds_opt vopt;
+ debug_decl(verify_krb_v5_tgt, SUDOERS_DEBUG_AUTH)
+
+ /*
+ * Get the server principal for the local host.
+ * (Use defaults of "host" and canonicalized local name.)
+ */
+ if ((error = krb5_sname_to_principal(sudo_context, NULL, NULL,
+ KRB5_NT_SRV_HST, &server))) {
+ log_warningx(0, N_("%s: unable to get host principal: %s"), auth_name,
+ error_message(error));
+ debug_return_int(-1);
+ }
+
+ /* Initialize verify opts and set secure mode */
+ krb5_verify_init_creds_opt_init(&vopt);
+ krb5_verify_init_creds_opt_set_ap_req_nofail(&vopt, 1);
+
+ /* verify the Kerberos ticket-granting ticket we just retrieved */
+ error = krb5_verify_init_creds(sudo_context, cred, server, NULL,
+ NULL, &vopt);
+ krb5_free_principal(sudo_context, server);
+ if (error) {
+ log_warningx(0, N_("%s: Cannot verify TGT! Possible attack!: %s"),
+ auth_name, error_message(error));
+ }
+ debug_return_int(error);
+}
+#endif
+
+#endif /* HAVE_KERB5 */
diff --git a/plugins/sudoers/auth/pam.c b/plugins/sudoers/auth/pam.c
new file mode 100644
index 0000000..129e4fe
--- /dev/null
+++ b/plugins/sudoers/auth/pam.c
@@ -0,0 +1,616 @@
+/*
+ * Copyright (c) 1999-2005, 2007-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_PAM
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <pwd.h>
+#include <errno.h>
+
+#ifdef HAVE_PAM_PAM_APPL_H
+# include <pam/pam_appl.h>
+#else
+# include <security/pam_appl.h>
+#endif
+
+#ifdef HAVE_LIBINTL_H
+# if defined(__LINUX_PAM__)
+# define PAM_TEXT_DOMAIN "Linux-PAM"
+# elif defined(__sun__)
+# define PAM_TEXT_DOMAIN "SUNW_OST_SYSOSPAM"
+# endif
+#endif
+
+/* We don't want to translate the strings in the calls to dgt(). */
+#ifdef PAM_TEXT_DOMAIN
+# define dgt(d, t) dgettext(d, t)
+#endif
+
+#include "sudoers.h"
+#include "sudo_auth.h"
+
+/* Only OpenPAM and Linux PAM use const qualifiers. */
+#ifdef PAM_SUN_CODEBASE
+# define PAM_CONST
+#else
+# define PAM_CONST const
+#endif
+
+/* Ambiguity in spec: is it an array of pointers or a pointer to an array? */
+#ifdef PAM_SUN_CODEBASE
+# define PAM_MSG_GET(msg, n) (*(msg) + (n))
+#else
+# define PAM_MSG_GET(msg, n) ((msg)[(n)])
+#endif
+
+#ifndef PAM_DATA_SILENT
+#define PAM_DATA_SILENT 0
+#endif
+
+static int converse(int, PAM_CONST struct pam_message **,
+ struct pam_response **, void *);
+static struct sudo_conv_callback *conv_callback;
+static struct pam_conv pam_conv = { converse, &conv_callback };
+static char *def_prompt = PASSPROMPT;
+static bool getpass_error;
+static pam_handle_t *pamh;
+
+static int
+sudo_pam_init2(struct passwd *pw, sudo_auth *auth, bool quiet)
+{
+ static int pam_status = PAM_SUCCESS;
+ int rc;
+ debug_decl(sudo_pam_init, SUDOERS_DEBUG_AUTH)
+
+ /* Stash pointer to last pam status. */
+ auth->data = &pam_status;
+
+#ifdef _AIX
+ if (pamh != NULL) {
+ /* Already initialized (may happen with AIX). */
+ debug_return_int(AUTH_SUCCESS);
+ }
+#endif /* _AIX */
+
+ /* Initial PAM setup */
+ pam_status = pam_start(ISSET(sudo_mode, MODE_LOGIN_SHELL) ?
+ def_pam_login_service : def_pam_service, pw->pw_name, &pam_conv, &pamh);
+ if (pam_status != PAM_SUCCESS) {
+ if (!quiet)
+ log_warning(0, N_("unable to initialize PAM"));
+ debug_return_int(AUTH_FATAL);
+ }
+
+ /*
+ * Set PAM_RUSER to the invoking user (the "from" user).
+ * We set PAM_RHOST to avoid a bug in Solaris 7 and below.
+ */
+ rc = pam_set_item(pamh, PAM_RUSER, user_name);
+ if (rc != PAM_SUCCESS) {
+ const char *errstr = pam_strerror(pamh, rc);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "pam_set_item(pamh, PAM_RUSER, %s): %s", user_name,
+ errstr ? errstr : "unknown error");
+ }
+#ifdef __sun__
+ rc = pam_set_item(pamh, PAM_RHOST, user_host);
+ if (rc != PAM_SUCCESS) {
+ const char *errstr = pam_strerror(pamh, rc);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "pam_set_item(pamh, PAM_RHOST, %s): %s", user_host,
+ errstr ? errstr : "unknown error");
+ }
+#endif
+
+ /*
+ * Some versions of pam_lastlog have a bug that
+ * will cause a crash if PAM_TTY is not set so if
+ * there is no tty, set PAM_TTY to the empty string.
+ */
+ rc = pam_set_item(pamh, PAM_TTY, user_ttypath ? user_ttypath : "");
+ if (rc != PAM_SUCCESS) {
+ const char *errstr = pam_strerror(pamh, rc);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "pam_set_item(pamh, PAM_TTY, %s): %s",
+ user_ttypath ? user_ttypath : "", errstr ? errstr : "unknown error");
+ }
+
+ /*
+ * If PAM session and setcred support is disabled we don't
+ * need to keep a sudo process around to close the session.
+ */
+ if (!def_pam_session && !def_pam_setcred)
+ auth->end_session = NULL;
+
+ debug_return_int(AUTH_SUCCESS);
+}
+
+int
+sudo_pam_init(struct passwd *pw, sudo_auth *auth)
+{
+ return sudo_pam_init2(pw, auth, false);
+}
+
+#ifdef _AIX
+int
+sudo_pam_init_quiet(struct passwd *pw, sudo_auth *auth)
+{
+ return sudo_pam_init2(pw, auth, true);
+}
+#endif /* _AIX */
+
+int
+sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback)
+{
+ const char *s;
+ int *pam_status = (int *) auth->data;
+ debug_decl(sudo_pam_verify, SUDOERS_DEBUG_AUTH)
+
+ def_prompt = prompt; /* for converse */
+ getpass_error = false; /* set by converse if user presses ^C */
+ conv_callback = callback; /* passed to conversation function */
+
+ /* PAM_SILENT prevents the authentication service from generating output. */
+ *pam_status = pam_authenticate(pamh, PAM_SILENT);
+ if (getpass_error) {
+ /* error or ^C from tgetpass() */
+ debug_return_int(AUTH_INTR);
+ }
+ switch (*pam_status) {
+ case PAM_SUCCESS:
+ debug_return_int(AUTH_SUCCESS);
+ case PAM_AUTH_ERR:
+ case PAM_AUTHINFO_UNAVAIL:
+ case PAM_MAXTRIES:
+ case PAM_PERM_DENIED:
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
+ "pam_authenticate: %d", *pam_status);
+ debug_return_int(AUTH_FAILURE);
+ default:
+ if ((s = pam_strerror(pamh, *pam_status)) != NULL)
+ log_warningx(0, N_("PAM authentication error: %s"), s);
+ debug_return_int(AUTH_FATAL);
+ }
+}
+
+int
+sudo_pam_approval(struct passwd *pw, sudo_auth *auth, bool exempt)
+{
+ const char *s;
+ int rc, status = AUTH_SUCCESS;
+ int *pam_status = (int *) auth->data;
+ debug_decl(sudo_pam_approval, SUDOERS_DEBUG_AUTH)
+
+ rc = pam_acct_mgmt(pamh, PAM_SILENT);
+ switch (rc) {
+ case PAM_SUCCESS:
+ break;
+ case PAM_AUTH_ERR:
+ log_warningx(0, N_("account validation failure, "
+ "is your account locked?"));
+ status = AUTH_FATAL;
+ break;
+ case PAM_NEW_AUTHTOK_REQD:
+ /* Ignore if user is exempt from password restrictions. */
+ if (exempt) {
+ rc = *pam_status;
+ break;
+ }
+ /* New password required, try to change it. */
+ log_warningx(0, N_("Account or password is "
+ "expired, reset your password and try again"));
+ rc = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+ if (rc == PAM_SUCCESS)
+ break;
+ if ((s = pam_strerror(pamh, rc)) == NULL)
+ s = "unknown error";
+ log_warningx(0,
+ N_("unable to change expired password: %s"), s);
+ status = AUTH_FAILURE;
+ break;
+ case PAM_AUTHTOK_EXPIRED:
+ /* Ignore if user is exempt from password restrictions. */
+ if (exempt) {
+ rc = *pam_status;
+ break;
+ }
+ /* Password expired, cannot be updated by user. */
+ log_warningx(0,
+ N_("Password expired, contact your system administrator"));
+ status = AUTH_FATAL;
+ break;
+ case PAM_ACCT_EXPIRED:
+ log_warningx(0,
+ N_("Account expired or PAM config lacks an \"account\" "
+ "section for sudo, contact your system administrator"));
+ status = AUTH_FATAL;
+ break;
+ case PAM_AUTHINFO_UNAVAIL:
+ case PAM_MAXTRIES:
+ case PAM_PERM_DENIED:
+ s = pam_strerror(pamh, rc);
+ log_warningx(0, N_("PAM account management error: %s"),
+ s ? s : "unknown error");
+ status = AUTH_FAILURE;
+ break;
+ default:
+ s = pam_strerror(pamh, rc);
+ log_warningx(0, N_("PAM account management error: %s"),
+ s ? s : "unknown error");
+ status = AUTH_FATAL;
+ break;
+ }
+ *pam_status = rc;
+ debug_return_int(status);
+}
+
+int
+sudo_pam_cleanup(struct passwd *pw, sudo_auth *auth)
+{
+ int *pam_status = (int *) auth->data;
+ debug_decl(sudo_pam_cleanup, SUDOERS_DEBUG_AUTH)
+
+ /* If successful, we can't close the session until sudo_pam_end_session() */
+ if (*pam_status != PAM_SUCCESS || auth->end_session == NULL) {
+ *pam_status = pam_end(pamh, *pam_status | PAM_DATA_SILENT);
+ pamh = NULL;
+ }
+ debug_return_int(*pam_status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE);
+}
+
+int
+sudo_pam_begin_session(struct passwd *pw, char **user_envp[], sudo_auth *auth)
+{
+ int rc, status = AUTH_SUCCESS;
+ int *pam_status = (int *) auth->data;
+ const char *errstr;
+ debug_decl(sudo_pam_begin_session, SUDOERS_DEBUG_AUTH)
+
+ /*
+ * If there is no valid user we cannot open a PAM session.
+ * This is not an error as sudo can run commands with arbitrary
+ * uids, it just means we are done from a session management standpoint.
+ */
+ if (pw == NULL) {
+ if (pamh != NULL) {
+ rc = pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT);
+ if (rc != PAM_SUCCESS) {
+ errstr = pam_strerror(pamh, rc);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "pam_end: %s", errstr ? errstr : "unknown error");
+ }
+ pamh = NULL;
+ }
+ goto done;
+ }
+
+ /*
+ * Update PAM_USER to reference the user we are running the command
+ * as, as opposed to the user we authenticated as.
+ */
+ rc = pam_set_item(pamh, PAM_USER, pw->pw_name);
+ if (rc != PAM_SUCCESS) {
+ errstr = pam_strerror(pamh, rc);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "pam_set_item(pamh, PAM_USER, %s): %s", pw->pw_name,
+ errstr ? errstr : "unknown error");
+ }
+
+ /*
+ * Reinitialize credentials when changing the user.
+ * We don't worry about a failure from pam_setcred() since with
+ * stacked PAM auth modules a failure from one module may override
+ * PAM_SUCCESS from another. For example, given a non-local user,
+ * pam_unix will fail but pam_ldap or pam_sss may succeed, but if
+ * pam_unix is first in the stack, pam_setcred() will fail.
+ */
+ if (def_pam_setcred) {
+ rc = pam_setcred(pamh, PAM_REINITIALIZE_CRED);
+ if (rc != PAM_SUCCESS) {
+ errstr = pam_strerror(pamh, rc);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "pam_setcred: %s", errstr ? errstr : "unknown error");
+ }
+ }
+
+ if (def_pam_session) {
+ /*
+ * We use PAM_SILENT to prevent pam_lastlog from printing last login
+ * information except when explicitly running a shell.
+ */
+ const bool silent = !ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL);
+ rc = pam_open_session(pamh, silent ? PAM_SILENT : 0);
+ switch (rc) {
+ case PAM_SUCCESS:
+ break;
+ case PAM_SESSION_ERR:
+ /* Treat PAM_SESSION_ERR as a non-fatal error. */
+ errstr = pam_strerror(pamh, rc);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "pam_open_session: %s", errstr ? errstr : "unknown error");
+ /* Avoid closing session that was not opened. */
+ def_pam_session = false;
+ break;
+ default:
+ /* Unexpected session failure, treat as fatal error. */
+ *pam_status = rc;
+ errstr = pam_strerror(pamh, *pam_status);
+ log_warningx(0, N_("%s: %s"), "pam_open_session",
+ errstr ? errstr : "unknown error");
+ rc = pam_end(pamh, *pam_status | PAM_DATA_SILENT);
+ if (rc != PAM_SUCCESS) {
+ errstr = pam_strerror(pamh, rc);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "pam_end: %s", errstr ? errstr : "unknown error");
+ }
+ pamh = NULL;
+ status = AUTH_FATAL;
+ goto done;
+ }
+ }
+
+#ifdef HAVE_PAM_GETENVLIST
+ /*
+ * Update environment based on what is stored in pamh.
+ * If no authentication is done we will only have environment
+ * variables if pam_env is called via session.
+ */
+ if (user_envp != NULL) {
+ char **pam_envp = pam_getenvlist(pamh);
+ if (pam_envp != NULL) {
+ /* Merge pam env with user env. */
+ if (!env_init(*user_envp) || !env_merge(pam_envp))
+ status = AUTH_FATAL;
+ *user_envp = env_get();
+ (void)env_init(NULL);
+ free(pam_envp);
+ /* XXX - we leak any duplicates that were in pam_envp */
+ }
+ }
+#endif /* HAVE_PAM_GETENVLIST */
+
+done:
+ debug_return_int(status);
+}
+
+int
+sudo_pam_end_session(struct passwd *pw, sudo_auth *auth)
+{
+ int rc, status = AUTH_SUCCESS;
+ debug_decl(sudo_pam_end_session, SUDOERS_DEBUG_AUTH)
+
+ if (pamh != NULL) {
+ /*
+ * Update PAM_USER to reference the user we are running the command
+ * as, as opposed to the user we authenticated as.
+ * XXX - still needed now that session init is in parent?
+ */
+ rc = pam_set_item(pamh, PAM_USER, pw->pw_name);
+ if (rc != PAM_SUCCESS) {
+ const char *errstr = pam_strerror(pamh, rc);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "pam_set_item(pamh, PAM_USER, %s): %s", pw->pw_name,
+ errstr ? errstr : "unknown error");
+ }
+ if (def_pam_session) {
+ rc = pam_close_session(pamh, PAM_SILENT);
+ if (rc != PAM_SUCCESS) {
+ const char *errstr = pam_strerror(pamh, rc);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "pam_close_session: %s", errstr ? errstr : "unknown error");
+ }
+ }
+ if (def_pam_setcred) {
+ rc = pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT);
+ if (rc != PAM_SUCCESS) {
+ const char *errstr = pam_strerror(pamh, rc);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "pam_setcred: %s", errstr ? errstr : "unknown error");
+ }
+ }
+ rc = pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT);
+ if (rc != PAM_SUCCESS) {
+ const char *errstr = pam_strerror(pamh, rc);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "pam_end: %s", errstr ? errstr : "unknown error");
+ status = AUTH_FATAL;
+ }
+ pamh = NULL;
+ }
+
+ debug_return_int(status);
+}
+
+#define PROMPT_IS_PASSWORD(_p) \
+ (strncmp((_p), "Password:", 9) == 0 && \
+ ((_p)[9] == '\0' || ((_p)[9] == ' ' && (_p)[10] == '\0')))
+
+#ifdef PAM_TEXT_DOMAIN
+# define PAM_PROMPT_IS_PASSWORD(_p) \
+ (strcmp((_p), dgt(PAM_TEXT_DOMAIN, "Password:")) == 0 || \
+ strcmp((_p), dgt(PAM_TEXT_DOMAIN, "Password: ")) == 0 || \
+ PROMPT_IS_PASSWORD(_p))
+#else
+# define PAM_PROMPT_IS_PASSWORD(_p) PROMPT_IS_PASSWORD(_p)
+#endif /* PAM_TEXT_DOMAIN */
+
+/*
+ * We use the PAM prompt in preference to sudo's as long
+ * as passprompt_override is not set and:
+ * a) the (translated) sudo prompt matches /^Password: ?/
+ * or:
+ * b) the PAM prompt itself *doesn't* match /^Password: ?/
+ * or /^username's Password: ?/
+ *
+ * The intent is to use the PAM prompt for things like
+ * challenge-response, otherwise use sudo's prompt.
+ * There may also be cases where a localized translation
+ * of "Password: " exists for PAM but not for sudo.
+ */
+static bool
+use_pam_prompt(const char *pam_prompt)
+{
+ size_t user_len;
+ debug_decl(use_pam_prompt, SUDOERS_DEBUG_AUTH)
+
+ /* Always use sudo prompt if passprompt_override is set. */
+ if (def_passprompt_override)
+ debug_return_bool(false);
+
+ /* If sudo prompt matches "^Password: ?$", use PAM prompt. */
+ if (PROMPT_IS_PASSWORD(def_prompt))
+ debug_return_bool(true);
+
+ /* If PAM prompt matches "^Password: ?$", use sudo prompt. */
+ if (PAM_PROMPT_IS_PASSWORD(pam_prompt))
+ debug_return_bool(false);
+
+ /*
+ * Some PAM modules use "^username's Password: ?$" instead of
+ * "^Password: ?" so check for that too.
+ */
+ user_len = strlen(user_name);
+ if (strncmp(pam_prompt, user_name, user_len) == 0) {
+ const char *cp = pam_prompt + user_len;
+ if (strncmp(cp, "'s Password:", 12) == 0 &&
+ (cp[12] == '\0' || (cp[12] == ' ' && cp[13] == '\0')))
+ debug_return_bool(false);
+ }
+
+ /* Otherwise, use the PAM prompt. */
+ debug_return_bool(true);
+}
+
+/*
+ * ``Conversation function'' for PAM <-> human interaction.
+ */
+static int
+converse(int num_msg, PAM_CONST struct pam_message **msg,
+ struct pam_response **reply_out, void *vcallback)
+{
+ struct sudo_conv_callback *callback = NULL;
+ struct pam_response *reply;
+ const char *prompt;
+ char *pass;
+ int n, type;
+ int ret = PAM_SUCCESS;
+ debug_decl(converse, SUDOERS_DEBUG_AUTH)
+
+ if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "invalid number of PAM messages: %d", num_msg);
+ debug_return_int(PAM_CONV_ERR);
+ }
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "number of PAM messages: %d", num_msg);
+
+ if ((reply = calloc(num_msg, sizeof(struct pam_response))) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(PAM_BUF_ERR);
+ }
+ *reply_out = reply;
+
+ if (vcallback != NULL)
+ callback = *((struct sudo_conv_callback **)vcallback);
+
+ for (n = 0; n < num_msg; n++) {
+ PAM_CONST struct pam_message *pm = PAM_MSG_GET(msg, n);
+
+ type = SUDO_CONV_PROMPT_ECHO_OFF;
+ switch (pm->msg_style) {
+ case PAM_PROMPT_ECHO_ON:
+ type = SUDO_CONV_PROMPT_ECHO_ON;
+ /* FALLTHROUGH */
+ case PAM_PROMPT_ECHO_OFF:
+ /* Error out if the last password read was interrupted. */
+ if (getpass_error)
+ goto done;
+
+ /* Choose either the sudo prompt or the PAM one. */
+ prompt = use_pam_prompt(pm->msg) ? pm->msg : def_prompt;
+
+ /* Read the password unless interrupted. */
+ pass = auth_getpass(prompt, type, callback);
+ if (pass == NULL) {
+ /* Error (or ^C) reading password, don't try again. */
+ getpass_error = true;
+ ret = PAM_CONV_ERR;
+ goto done;
+ }
+ if (strlen(pass) >= PAM_MAX_RESP_SIZE) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "password longer than %d", PAM_MAX_RESP_SIZE);
+ ret = PAM_CONV_ERR;
+ memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
+ goto done;
+ }
+ reply[n].resp = pass; /* auth_getpass() malloc's a copy */
+ break;
+ case PAM_TEXT_INFO:
+ if (pm->msg != NULL)
+ sudo_printf(SUDO_CONV_INFO_MSG, "%s\n", pm->msg);
+ break;
+ case PAM_ERROR_MSG:
+ if (pm->msg != NULL)
+ sudo_printf(SUDO_CONV_ERROR_MSG, "%s\n", pm->msg);
+ break;
+ default:
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unsupported message style: %d", pm->msg_style);
+ ret = PAM_CONV_ERR;
+ goto done;
+ }
+ }
+
+done:
+ if (ret != PAM_SUCCESS) {
+ /* Zero and free allocated memory and return an error. */
+ for (n = 0; n < num_msg; n++) {
+ struct pam_response *pr = &reply[n];
+
+ if (pr->resp != NULL) {
+ memset_s(pr->resp, SUDO_CONV_REPL_MAX, 0, strlen(pr->resp));
+ free(pr->resp);
+ pr->resp = NULL;
+ }
+ }
+ free(reply);
+ *reply_out = NULL;
+ }
+ debug_return_int(ret);
+}
+
+#endif /* HAVE_PAM */
diff --git a/plugins/sudoers/auth/passwd.c b/plugins/sudoers/auth/passwd.c
new file mode 100644
index 0000000..e7093ab
--- /dev/null
+++ b/plugins/sudoers/auth/passwd.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1999-2005, 2010-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <pwd.h>
+
+#include "sudoers.h"
+#include "sudo_auth.h"
+
+#define DESLEN 13
+#define HAS_AGEINFO(p, l) (l == 18 && p[DESLEN] == ',')
+
+int
+sudo_passwd_init(struct passwd *pw, sudo_auth *auth)
+{
+ debug_decl(sudo_passwd_init, SUDOERS_DEBUG_AUTH)
+
+#ifdef HAVE_SKEYACCESS
+ if (skeyaccess(pw, user_tty, NULL, NULL) == 0)
+ debug_return_int(AUTH_FAILURE);
+#endif
+ sudo_setspent();
+ auth->data = sudo_getepw(pw);
+ sudo_endspent();
+ debug_return_int(auth->data ? AUTH_SUCCESS : AUTH_FATAL);
+}
+
+int
+sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback)
+{
+ char sav, *epass;
+ char *pw_epasswd = auth->data;
+ size_t pw_len;
+ int matched = 0;
+ debug_decl(sudo_passwd_verify, SUDOERS_DEBUG_AUTH)
+
+ /* An empty plain-text password must match an empty encrypted password. */
+ if (pass[0] == '\0')
+ debug_return_int(pw_epasswd[0] ? AUTH_FAILURE : AUTH_SUCCESS);
+
+ /*
+ * Truncate to 8 chars if standard DES since not all crypt()'s do this.
+ * If this turns out not to be safe we will have to use OS #ifdef's (sigh).
+ */
+ sav = pass[8];
+ pw_len = strlen(pw_epasswd);
+ if (pw_len == DESLEN || HAS_AGEINFO(pw_epasswd, pw_len))
+ pass[8] = '\0';
+
+ /*
+ * Normal UN*X password check.
+ * HP-UX may add aging info (separated by a ',') at the end so
+ * only compare the first DESLEN characters in that case.
+ */
+ epass = (char *) crypt(pass, pw_epasswd);
+ pass[8] = sav;
+ if (epass != NULL) {
+ if (HAS_AGEINFO(pw_epasswd, pw_len) && strlen(epass) == DESLEN)
+ matched = !strncmp(pw_epasswd, epass, DESLEN);
+ else
+ matched = !strcmp(pw_epasswd, epass);
+ }
+
+ debug_return_int(matched ? AUTH_SUCCESS : AUTH_FAILURE);
+}
+
+int
+sudo_passwd_cleanup(pw, auth)
+ struct passwd *pw;
+ sudo_auth *auth;
+{
+ char *pw_epasswd = auth->data;
+ debug_decl(sudo_passwd_cleanup, SUDOERS_DEBUG_AUTH)
+
+ if (pw_epasswd != NULL) {
+ memset_s(pw_epasswd, SUDO_CONV_REPL_MAX, 0, strlen(pw_epasswd));
+ free(pw_epasswd);
+ }
+ debug_return_int(AUTH_SUCCESS);
+}
diff --git a/plugins/sudoers/auth/rfc1938.c b/plugins/sudoers/auth/rfc1938.c
new file mode 100644
index 0000000..2a5a55b
--- /dev/null
+++ b/plugins/sudoers/auth/rfc1938.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 1994-1996, 1998-2005, 2010-2012, 2014-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#if defined(HAVE_SKEY) || defined(HAVE_OPIE)
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <pwd.h>
+
+#if defined(HAVE_SKEY)
+# include <skey.h>
+# define RFC1938 skey
+# ifdef HAVE_RFC1938_SKEYCHALLENGE
+# define rfc1938challenge(a,b,c,d) skeychallenge((a),(b),(c),(d))
+# else
+# define rfc1938challenge(a,b,c,d) skeychallenge((a),(b),(c))
+# endif
+# define rfc1938verify(a,b) skeyverify((a),(b))
+#elif defined(HAVE_OPIE)
+# include <opie.h>
+# define RFC1938 opie
+# define rfc1938challenge(a,b,c,d) opiechallenge((a),(b),(c))
+# define rfc1938verify(a,b) opieverify((a),(b))
+#endif
+
+#include "sudoers.h"
+#include "sudo_auth.h"
+
+int
+sudo_rfc1938_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
+{
+ char challenge[256];
+ size_t challenge_len;
+ static char *orig_prompt = NULL, *new_prompt = NULL;
+ static size_t op_len, np_size;
+ static struct RFC1938 rfc1938;
+ debug_decl(sudo_rfc1938_setup, SUDOERS_DEBUG_AUTH)
+
+ /* Stash a pointer to the rfc1938 struct if we have not initialized */
+ if (!auth->data)
+ auth->data = &rfc1938;
+
+ /* Save the original prompt */
+ if (orig_prompt == NULL) {
+ orig_prompt = *promptp;
+ op_len = strlen(orig_prompt);
+
+ /* Ignore trailing colon (we will add our own) */
+ if (orig_prompt[op_len - 1] == ':')
+ op_len--;
+ else if (op_len >= 2 && orig_prompt[op_len - 1] == ' '
+ && orig_prompt[op_len - 2] == ':')
+ op_len -= 2;
+ }
+
+#ifdef HAVE_SKEY
+ /* Close old stream */
+ if (rfc1938.keyfile)
+ (void) fclose(rfc1938.keyfile);
+#endif
+
+ /*
+ * Look up the user and get the rfc1938 challenge.
+ * If the user is not in the OTP db, only post a fatal error if
+ * we are running alone (since they may just use a normal passwd).
+ */
+ if (rfc1938challenge(&rfc1938, pw->pw_name, challenge, sizeof(challenge))) {
+ if (IS_ONEANDONLY(auth)) {
+ sudo_warnx(U_("you do not exist in the %s database"), auth->name);
+ debug_return_int(AUTH_FATAL);
+ } else {
+ debug_return_int(AUTH_FAILURE);
+ }
+ }
+
+ /* Get space for new prompt with embedded challenge */
+ challenge_len = strlen(challenge);
+ if (np_size < op_len + challenge_len + 7) {
+ char *p = realloc(new_prompt, op_len + challenge_len + 7);
+ if (p == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(AUTH_FATAL);
+ }
+ np_size = op_len + challenge_len + 7;
+ new_prompt = p;
+ }
+
+ if (def_long_otp_prompt)
+ (void) snprintf(new_prompt, np_size, "%s\n%s", challenge, orig_prompt);
+ else
+ (void) snprintf(new_prompt, np_size, "%.*s [ %s ]:", (int)op_len,
+ orig_prompt, challenge);
+
+ *promptp = new_prompt;
+ debug_return_int(AUTH_SUCCESS);
+}
+
+int
+sudo_rfc1938_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback)
+{
+ debug_decl(sudo_rfc1938_verify, SUDOERS_DEBUG_AUTH)
+
+ if (rfc1938verify((struct RFC1938 *) auth->data, pass) == 0)
+ debug_return_int(AUTH_SUCCESS);
+ else
+ debug_return_int(AUTH_FAILURE);
+}
+
+#endif /* HAVE_SKEY || HAVE_OPIE */
diff --git a/plugins/sudoers/auth/secureware.c b/plugins/sudoers/auth/secureware.c
new file mode 100644
index 0000000..dc60002
--- /dev/null
+++ b/plugins/sudoers/auth/secureware.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1998-2005, 2010-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_GETPRPWNAM
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <pwd.h>
+#ifdef __hpux
+# undef MAXINT
+# include <hpsecurity.h>
+#else
+# include <sys/security.h>
+#endif /* __hpux */
+#include <prot.h>
+
+#include "sudoers.h"
+#include "sudo_auth.h"
+
+#ifdef __alpha
+extern int crypt_type;
+#endif
+
+int
+sudo_secureware_init(struct passwd *pw, sudo_auth *auth)
+{
+ debug_decl(sudo_secureware_init, SUDOERS_DEBUG_AUTH)
+
+#ifdef __alpha
+ if (crypt_type == INT_MAX)
+ debug_return_int(AUTH_FAILURE); /* no shadow */
+#endif
+
+ sudo_setspent();
+ auth->data = sudo_getepw(pw);
+ sudo_endspent();
+ debug_return_int(auth->data ? AUTH_SUCCESS : AUTH_FATAL);
+}
+
+int
+sudo_secureware_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback)
+{
+ char *pw_epasswd = auth->data;
+ char *epass = NULL;
+ debug_decl(sudo_secureware_verify, SUDOERS_DEBUG_AUTH)
+
+ /* An empty plain-text password must match an empty encrypted password. */
+ if (pass[0] == '\0')
+ debug_return_int(pw_epasswd[0] ? AUTH_FAILURE : AUTH_SUCCESS);
+
+#if defined(__alpha)
+# ifdef HAVE_DISPCRYPT
+ epass = dispcrypt(pass, pw_epasswd, crypt_type);
+# else
+ if (crypt_type == AUTH_CRYPT_BIGCRYPT)
+ epass = bigcrypt(pass, pw_epasswd);
+ else if (crypt_type == AUTH_CRYPT_CRYPT16)
+ epass = crypt(pass, pw_epasswd);
+# endif /* HAVE_DISPCRYPT */
+#elif defined(HAVE_BIGCRYPT)
+ epass = bigcrypt(pass, pw_epasswd);
+#endif /* __alpha */
+
+ if (epass != NULL && strcmp(pw_epasswd, epass) == 0)
+ debug_return_int(AUTH_SUCCESS);
+ debug_return_int(AUTH_FAILURE);
+}
+
+int
+sudo_secureware_cleanup(pw, auth)
+ struct passwd *pw;
+ sudo_auth *auth;
+{
+ char *pw_epasswd = auth->data;
+ debug_decl(sudo_secureware_cleanup, SUDOERS_DEBUG_AUTH)
+
+ if (pw_epasswd != NULL) {
+ memset_s(pw_epasswd, SUDO_CONV_REPL_MAX, 0, strlen(pw_epasswd));
+ free(pw_epasswd);
+ }
+ debug_return_int(AUTH_SUCCESS);
+}
+
+#endif /* HAVE_GETPRPWNAM */
diff --git a/plugins/sudoers/auth/securid5.c b/plugins/sudoers/auth/securid5.c
new file mode 100644
index 0000000..ca75c56
--- /dev/null
+++ b/plugins/sudoers/auth/securid5.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 1999-2005, 2007, 2010-2012, 2014-2016
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ * Copyright (c) 2002 Michael Stroucken <michael@stroucken.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_SECURID
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <pwd.h>
+
+/* Needed for SecurID v5.0 Authentication on UNIX */
+#define UNIX 1
+#include <acexport.h>
+#include <sdacmvls.h>
+
+#include "sudoers.h"
+#include "sudo_auth.h"
+
+/*
+ * securid_init - Initialises communications with ACE server
+ * Arguments in:
+ * pw - UNUSED
+ * auth - sudo authentication structure
+ *
+ * Results out:
+ * auth - auth->data contains pointer to new SecurID handle
+ * return code - Fatal if initialization unsuccessful, otherwise
+ * success.
+ */
+int
+sudo_securid_init(struct passwd *pw, sudo_auth *auth)
+{
+ static SDI_HANDLE sd_dat; /* SecurID handle */
+ debug_decl(sudo_securid_init, SUDOERS_DEBUG_AUTH)
+
+ auth->data = (void *) &sd_dat; /* For method-specific data */
+
+ /* Start communications */
+ if (AceInitialize() != SD_FALSE)
+ debug_return_int(AUTH_SUCCESS);
+
+ sudo_warnx(U_("failed to initialise the ACE API library"));
+ debug_return_int(AUTH_FATAL);
+}
+
+/*
+ * securid_setup - Initialises a SecurID transaction and locks out other
+ * ACE servers
+ *
+ * Arguments in:
+ * pw - struct passwd for username
+ * promptp - UNUSED
+ * auth - sudo authentication structure for SecurID handle
+ *
+ * Results out:
+ * return code - Success if transaction started correctly, fatal
+ * otherwise
+ */
+int
+sudo_securid_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
+{
+ SDI_HANDLE *sd = (SDI_HANDLE *) auth->data;
+ int retval;
+ debug_decl(sudo_securid_setup, SUDOERS_DEBUG_AUTH)
+
+ /* Re-initialize SecurID every time. */
+ if (SD_Init(sd) != ACM_OK) {
+ sudo_warnx(U_("unable to contact the SecurID server"));
+ debug_return_int(AUTH_FATAL);
+ }
+
+ /* Lock new PIN code */
+ retval = SD_Lock(*sd, pw->pw_name);
+
+ switch (retval) {
+ case ACM_OK:
+ sudo_warnx(U_("User ID locked for SecurID Authentication"));
+ debug_return_int(AUTH_SUCCESS);
+
+ case ACE_UNDEFINED_USERNAME:
+ sudo_warnx(U_("invalid username length for SecurID"));
+ debug_return_int(AUTH_FATAL);
+
+ case ACE_ERR_INVALID_HANDLE:
+ sudo_warnx(U_("invalid Authentication Handle for SecurID"));
+ debug_return_int(AUTH_FATAL);
+
+ case ACM_ACCESS_DENIED:
+ sudo_warnx(U_("SecurID communication failed"));
+ debug_return_int(AUTH_FATAL);
+
+ default:
+ sudo_warnx(U_("unknown SecurID error"));
+ debug_return_int(AUTH_FATAL);
+ }
+}
+
+/*
+ * securid_verify - Authenticates user and handles ACE responses
+ *
+ * Arguments in:
+ * pw - struct passwd for username
+ * pass - UNUSED
+ * auth - sudo authentication structure for SecurID handle
+ *
+ * Results out:
+ * return code - Success on successful authentication, failure on
+ * incorrect authentication, fatal on errors
+ */
+int
+sudo_securid_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback)
+{
+ SDI_HANDLE *sd = (SDI_HANDLE *) auth->data;
+ int ret;
+ debug_decl(sudo_securid_verify, SUDOERS_DEBUG_AUTH)
+
+ pass = auth_getpass("Enter your PASSCODE: ", SUDO_CONV_PROMPT_ECHO_OFF,
+ callback);
+
+ /* Have ACE verify password */
+ switch (SD_Check(*sd, pass, pw->pw_name)) {
+ case ACM_OK:
+ ret = AUTH_SUCESS;
+ break;
+
+ case ACE_UNDEFINED_PASSCODE:
+ sudo_warnx(U_("invalid passcode length for SecurID"));
+ ret = AUTH_FATAL;
+ break;
+
+ case ACE_UNDEFINED_USERNAME:
+ sudo_warnx(U_("invalid username length for SecurID"));
+ ret = AUTH_FATAL;
+ break;
+
+ case ACE_ERR_INVALID_HANDLE:
+ sudo_warnx(U_("invalid Authentication Handle for SecurID"));
+ ret = AUTH_FATAL;
+ break;
+
+ case ACM_ACCESS_DENIED:
+ ret = AUTH_FAILURE;
+ break;
+
+ case ACM_NEXT_CODE_REQUIRED:
+ /* Sometimes (when current token close to expire?)
+ ACE challenges for the next token displayed
+ (entered without the PIN) */
+ if (pass != NULL) {
+ memset_s(pass, SUDO_PASS_MAX, 0, strlen(pass));
+ free(pass);
+ }
+ pass = auth_getpass("\
+!!! ATTENTION !!!\n\
+Wait for the token code to change, \n\
+then enter the new token code.\n", \
+ SUDO_CONV_PROMPT_ECHO_OFF, callback);
+
+ if (SD_Next(*sd, pass) == ACM_OK) {
+ ret = AUTH_SUCCESS;
+ break;
+ }
+
+ ret = AUTH_FAILURE;
+ break;
+
+ case ACM_NEW_PIN_REQUIRED:
+ /*
+ * This user's SecurID has not been activated yet,
+ * or the pin has been reset
+ */
+ /* XXX - Is setting up a new PIN within sudo's scope? */
+ SD_Pin(*sd, "");
+ sudo_printf(SUDO_CONV_ERROR_MSG,
+ "Your SecurID access has not yet been set up.\n");
+ sudo_printf(SUDO_CONV_ERROR_MSG,
+ "Please set up a PIN before you try to authenticate.\n");
+ ret = AUTH_FATAL;
+ break;
+
+ default:
+ sudo_warnx(U_("unknown SecurID error"));
+ ret = AUTH_FATAL;
+ break;
+ }
+
+ /* Free resources */
+ SD_Close(*sd);
+
+ if (pass != NULL) {
+ memset_s(pass, SUDO_PASS_MAX, 0, strlen(pass));
+ free(pass);
+ }
+
+ /* Return stored state to calling process */
+ debug_return_int(ret);
+}
+
+#endif /* HAVE_SECURID */
diff --git a/plugins/sudoers/auth/sia.c b/plugins/sudoers/auth/sia.c
new file mode 100644
index 0000000..8e74de8
--- /dev/null
+++ b/plugins/sudoers/auth/sia.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 1999-2005, 2007, 2010-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_SIA_SES_INIT
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <pwd.h>
+#include <signal.h>
+#include <siad.h>
+
+#include "sudoers.h"
+#include "sudo_auth.h"
+
+static char **sudo_argv;
+static int sudo_argc;
+
+int
+sudo_sia_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
+{
+ SIAENTITY *siah;
+ int i;
+ debug_decl(sudo_sia_setup, SUDOERS_DEBUG_AUTH)
+
+ /* Rebuild argv for sia_ses_init() */
+ sudo_argc = NewArgc + 1;
+ sudo_argv = reallocarray(NULL, sudo_argc + 1, sizeof(char *));
+ if (sudo_argv == NULL) {
+ log_warningx(0, N_("unable to allocate memory"));
+ debug_return_int(AUTH_FATAL);
+ }
+ sudo_argv[0] = "sudo";
+ for (i = 0; i < NewArgc; i++)
+ sudo_argv[i + 1] = NewArgv[i];
+ sudo_argv[sudo_argc] = NULL;
+
+ /* We don't let SIA prompt the user for input. */
+ if (sia_ses_init(&siah, sudo_argc, sudo_argv, NULL, pw->pw_name, user_ttypath, 0, NULL) != SIASUCCESS) {
+ log_warning(0, N_("unable to initialize SIA session"));
+ debug_return_int(AUTH_FATAL);
+ }
+
+ auth->data = siah;
+ debug_return_int(AUTH_SUCCESS);
+}
+
+int
+sudo_sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth,
+ struct sudo_conv_callback *callback)
+{
+ SIAENTITY *siah = auth->data;
+ char *pass;
+ int rc;
+ debug_decl(sudo_sia_verify, SUDOERS_DEBUG_AUTH)
+
+ /* Get password, return AUTH_INTR if we got ^C */
+ pass = auth_getpass(prompt, SUDO_CONV_PROMPT_ECHO_OFF, callback);
+ if (pass == NULL)
+ debug_return_int(AUTH_INTR);
+
+ /* Check password and zero out plaintext copy. */
+ rc = sia_ses_authent(NULL, pass, siah);
+ memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
+ free(pass);
+
+ if (rc == SIASUCCESS)
+ debug_return_int(AUTH_SUCCESS);
+ if (ISSET(rc, SIASTOP))
+ debug_return_int(AUTH_FATAL);
+ debug_return_int(AUTH_FAILURE);
+}
+
+int
+sudo_sia_cleanup(struct passwd *pw, sudo_auth *auth)
+{
+ SIAENTITY *siah = auth->data;
+ debug_decl(sudo_sia_cleanup, SUDOERS_DEBUG_AUTH)
+
+ (void) sia_ses_release(&siah);
+ auth->data = NULL;
+ free(sudo_argv);
+ debug_return_int(AUTH_SUCCESS);
+}
+
+int
+sudo_sia_begin_session(struct passwd *pw, char **user_envp[], sudo_auth *auth)
+{
+ SIAENTITY *siah;
+ int status = AUTH_FATAL;
+ debug_decl(sudo_sia_begin_session, SUDOERS_DEBUG_AUTH)
+
+ /* Re-init sia for the target user's session. */
+ if (sia_ses_init(&siah, NewArgc, NewArgv, NULL, pw->pw_name, user_ttypath, 0, NULL) != SIASUCCESS) {
+ log_warning(0, N_("unable to initialize SIA session"));
+ goto done;
+ }
+
+ if (sia_make_entity_pwd(pw, siah) != SIASUCCESS) {
+ sudo_warn("sia_make_entity_pwd");
+ goto done;
+ }
+
+ status = AUTH_FAILURE; /* no more fatal errors. */
+
+ siah->authtype = SIA_A_NONE;
+ if (sia_ses_estab(sia_collect_trm, siah) != SIASUCCESS) {
+ sudo_warn("sia_ses_estab");
+ goto done;
+ }
+
+ if (sia_ses_launch(sia_collect_trm, siah) != SIASUCCESS) {
+ sudo_warn("sia_ses_launch");
+ goto done;
+ }
+
+ status = AUTH_SUCCESS;
+
+done:
+ (void) sia_ses_release(&siah);
+ debug_return_int(status);
+}
+
+#endif /* HAVE_SIA_SES_INIT */
diff --git a/plugins/sudoers/auth/sudo_auth.c b/plugins/sudoers/auth/sudo_auth.c
new file mode 100644
index 0000000..be70f93
--- /dev/null
+++ b/plugins/sudoers/auth/sudo_auth.c
@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 1999-2005, 2008-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <pwd.h>
+#include <time.h>
+#include <signal.h>
+
+#include "sudoers.h"
+#include "sudo_auth.h"
+#include "insults.h"
+
+static sudo_auth auth_switch[] = {
+/* Standalone entries first */
+#ifdef HAVE_AIXAUTH
+ AUTH_ENTRY("aixauth", FLAG_STANDALONE, sudo_aix_init, NULL, sudo_aix_verify, NULL, sudo_aix_cleanup, NULL, NULL)
+#endif
+#ifdef HAVE_PAM
+ AUTH_ENTRY("pam", FLAG_STANDALONE, sudo_pam_init, NULL, sudo_pam_verify, sudo_pam_approval, sudo_pam_cleanup, sudo_pam_begin_session, sudo_pam_end_session)
+#endif
+#ifdef HAVE_SECURID
+ AUTH_ENTRY("SecurId", FLAG_STANDALONE, sudo_securid_init, sudo_securid_setup, sudo_securid_verify, NULL, NULL, NULL, NULL)
+#endif
+#ifdef HAVE_SIA_SES_INIT
+ AUTH_ENTRY("sia", FLAG_STANDALONE, NULL, sudo_sia_setup, sudo_sia_verify, NULL, sudo_sia_cleanup, sudo_sia_begin_session, NULL)
+#endif
+#ifdef HAVE_FWTK
+ AUTH_ENTRY("fwtk", FLAG_STANDALONE, sudo_fwtk_init, NULL, sudo_fwtk_verify, NULL, sudo_fwtk_cleanup, NULL, NULL)
+#endif
+#ifdef HAVE_BSD_AUTH_H
+ AUTH_ENTRY("bsdauth", FLAG_STANDALONE, bsdauth_init, NULL, bsdauth_verify, bsdauth_approval, bsdauth_cleanup, NULL, NULL)
+#endif
+
+/* Non-standalone entries */
+#ifndef WITHOUT_PASSWD
+ AUTH_ENTRY("passwd", 0, sudo_passwd_init, NULL, sudo_passwd_verify, NULL, sudo_passwd_cleanup, NULL, NULL)
+#endif
+#if defined(HAVE_GETPRPWNAM) && !defined(WITHOUT_PASSWD)
+ AUTH_ENTRY("secureware", 0, sudo_secureware_init, NULL, sudo_secureware_verify, NULL, sudo_secureware_cleanup, NULL, NULL)
+#endif
+#ifdef HAVE_AFS
+ AUTH_ENTRY("afs", 0, NULL, NULL, sudo_afs_verify, NULL, NULL, NULL, NULL)
+#endif
+#ifdef HAVE_DCE
+ AUTH_ENTRY("dce", 0, NULL, NULL, sudo_dce_verify, NULL, NULL, NULL, NULL)
+#endif
+#ifdef HAVE_KERB5
+ AUTH_ENTRY("kerb5", 0, sudo_krb5_init, sudo_krb5_setup, sudo_krb5_verify, NULL, sudo_krb5_cleanup, NULL, NULL)
+#endif
+#ifdef HAVE_SKEY
+ AUTH_ENTRY("S/Key", 0, NULL, sudo_rfc1938_setup, sudo_rfc1938_verify, NULL, NULL, NULL, NULL)
+#endif
+#ifdef HAVE_OPIE
+ AUTH_ENTRY("OPIE", 0, NULL, sudo_rfc1938_setup, sudo_rfc1938_verify, NULL, NULL, NULL, NULL)
+#endif
+ AUTH_ENTRY(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
+};
+
+static bool standalone;
+
+/*
+ * Initialize sudoers authentication method(s).
+ * Returns 0 on success and -1 on error.
+ */
+int
+sudo_auth_init(struct passwd *pw)
+{
+ sudo_auth *auth;
+ int status = AUTH_SUCCESS;
+ debug_decl(sudo_auth_init, SUDOERS_DEBUG_AUTH)
+
+ if (auth_switch[0].name == NULL)
+ debug_return_int(0);
+
+ /* Initialize auth methods and unconfigure the method if necessary. */
+ for (auth = auth_switch; auth->name; auth++) {
+ if (auth->init && !IS_DISABLED(auth)) {
+ /* Disable if it failed to init unless there was a fatal error. */
+ status = (auth->init)(pw, auth);
+ if (status == AUTH_FAILURE)
+ SET(auth->flags, FLAG_DISABLED);
+ else if (status == AUTH_FATAL)
+ break; /* assume error msg already printed */
+ }
+ }
+
+ /*
+ * Make sure we haven't mixed standalone and shared auth methods.
+ * If there are multiple standalone methods, only use the first one.
+ */
+ if ((standalone = IS_STANDALONE(&auth_switch[0]))) {
+ bool found = false;
+ for (auth = auth_switch; auth->name; auth++) {
+ if (IS_DISABLED(auth))
+ continue;
+ if (!IS_STANDALONE(auth)) {
+ audit_failure(NewArgc, NewArgv,
+ N_("invalid authentication methods"));
+ log_warningx(SLOG_SEND_MAIL,
+ N_("Invalid authentication methods compiled into sudo! "
+ "You may not mix standalone and non-standalone authentication."));
+ debug_return_int(-1);
+ }
+ if (!found) {
+ /* Found first standalone method. */
+ found = true;
+ continue;
+ }
+ /* Disable other standalone methods. */
+ SET(auth->flags, FLAG_DISABLED);
+ }
+ }
+
+ /* Set FLAG_ONEANDONLY if there is only one auth method. */
+ for (auth = auth_switch; auth->name; auth++) {
+ /* Find first enabled auth method. */
+ if (!IS_DISABLED(auth)) {
+ sudo_auth *first = auth;
+ /* Check for others. */
+ for (; auth->name; auth++) {
+ if (!IS_DISABLED(auth))
+ break;
+ }
+ if (auth->name == NULL)
+ SET(first->flags, FLAG_ONEANDONLY);
+ break;
+ }
+ }
+
+ debug_return_int(status == AUTH_FATAL ? -1 : 0);
+}
+
+/*
+ * Cleanup all authentication approval methods.
+ * Returns true on success, false on failure and -1 on error.
+ */
+int
+sudo_auth_approval(struct passwd *pw, int validated, bool exempt)
+{
+ sudo_auth *auth;
+ debug_decl(sudo_auth_approval, SUDOERS_DEBUG_AUTH)
+
+ /* Call approval routines. */
+ for (auth = auth_switch; auth->name; auth++) {
+ if (auth->approval && !IS_DISABLED(auth)) {
+ int status = (auth->approval)(pw, auth, exempt);
+ if (status != AUTH_SUCCESS) {
+ /* Assume error msg already printed. */
+ log_auth_failure(validated, 0);
+ debug_return_int(status == AUTH_FAILURE ? false : -1);
+ }
+ }
+ }
+ debug_return_int(true);
+}
+
+/*
+ * Cleanup all authentication methods.
+ * Returns 0 on success and -1 on error.
+ */
+int
+sudo_auth_cleanup(struct passwd *pw)
+{
+ sudo_auth *auth;
+ debug_decl(sudo_auth_cleanup, SUDOERS_DEBUG_AUTH)
+
+ /* Call cleanup routines. */
+ for (auth = auth_switch; auth->name; auth++) {
+ if (auth->cleanup && !IS_DISABLED(auth)) {
+ int status = (auth->cleanup)(pw, auth);
+ if (status == AUTH_FATAL) {
+ /* Assume error msg already printed. */
+ debug_return_int(-1);
+ }
+ }
+ }
+ debug_return_int(0);
+}
+
+static void
+pass_warn(void)
+{
+ const char *warning = def_badpass_message;
+ debug_decl(pass_warn, SUDOERS_DEBUG_AUTH)
+
+#ifdef INSULT
+ if (def_insults)
+ warning = INSULT;
+#endif
+ sudo_printf(SUDO_CONV_ERROR_MSG, "%s\n", warning);
+
+ debug_return;
+}
+
+static bool
+user_interrupted(void)
+{
+ sigset_t mask;
+
+ return (sigpending(&mask) == 0 &&
+ (sigismember(&mask, SIGINT) || sigismember(&mask, SIGQUIT)));
+}
+
+/*
+ * Verify the specified user.
+ * Returns true if verified, false if not or -1 on error.
+ */
+int
+verify_user(struct passwd *pw, char *prompt, int validated,
+ struct sudo_conv_callback *callback)
+{
+ unsigned int ntries;
+ int ret, status, success = AUTH_FAILURE;
+ sudo_auth *auth;
+ sigset_t mask, omask;
+ struct sigaction sa, saved_sigtstp;
+ debug_decl(verify_user, SUDOERS_DEBUG_AUTH)
+
+ /* Make sure we have at least one auth method. */
+ if (auth_switch[0].name == NULL) {
+ audit_failure(NewArgc, NewArgv, N_("no authentication methods"));
+ log_warningx(SLOG_SEND_MAIL,
+ N_("There are no authentication methods compiled into sudo! "
+ "If you want to turn off authentication, use the "
+ "--disable-authentication configure option."));
+ debug_return_int(-1);
+ }
+
+ /* Enable suspend during password entry. */
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = SIG_DFL;
+ (void) sigaction(SIGTSTP, &sa, &saved_sigtstp);
+
+ /*
+ * We treat authentication as a critical section and block
+ * keyboard-generated signals such as SIGINT and SIGQUIT
+ * which might otherwise interrupt a sleep(3).
+ * They are temporarily unblocked by auth_getpass().
+ */
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGQUIT);
+ (void) sigprocmask(SIG_BLOCK, &mask, &omask);
+
+ for (ntries = 0; ntries < def_passwd_tries; ntries++) {
+ int num_methods = 0;
+ char *pass = NULL;
+
+ /* If user attempted to interrupt password verify, quit now. */
+ if (user_interrupted())
+ goto done;
+
+ if (ntries != 0)
+ pass_warn();
+
+ /* Do any per-method setup and unconfigure the method if needed */
+ for (auth = auth_switch; auth->name; auth++) {
+ if (IS_DISABLED(auth))
+ continue;
+ num_methods++;
+ if (auth->setup != NULL) {
+ status = (auth->setup)(pw, &prompt, auth);
+ if (status == AUTH_FAILURE)
+ SET(auth->flags, FLAG_DISABLED);
+ else if (status == AUTH_FATAL || user_interrupted())
+ goto done; /* assume error msg already printed */
+ }
+ }
+ if (num_methods == 0) {
+ audit_failure(NewArgc, NewArgv, N_("no authentication methods"));
+ log_warningx(SLOG_SEND_MAIL,
+ N_("Unable to initialize authentication methods."));
+ debug_return_int(-1);
+ }
+
+ /* Get the password unless the auth function will do it for us */
+ if (!standalone) {
+ pass = auth_getpass(prompt, SUDO_CONV_PROMPT_ECHO_OFF, callback);
+ if (pass == NULL)
+ break;
+ }
+
+ /* Call authentication functions. */
+ for (auth = auth_switch; auth->name; auth++) {
+ if (IS_DISABLED(auth))
+ continue;
+
+ success = auth->status =
+ (auth->verify)(pw, standalone ? prompt : pass, auth, callback);
+ if (success != AUTH_FAILURE)
+ break;
+ }
+ if (pass != NULL) {
+ memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
+ free(pass);
+ }
+
+ if (success != AUTH_FAILURE)
+ goto done;
+ }
+
+done:
+ /* Restore signal handlers and signal mask. */
+ (void) sigaction(SIGTSTP, &saved_sigtstp, NULL);
+ (void) sigprocmask(SIG_SETMASK, &omask, NULL);
+
+ switch (success) {
+ case AUTH_SUCCESS:
+ ret = true;
+ break;
+ case AUTH_INTR:
+ case AUTH_FAILURE:
+ if (ntries != 0)
+ validated |= FLAG_BAD_PASSWORD;
+ log_auth_failure(validated, ntries);
+ ret = false;
+ break;
+ case AUTH_FATAL:
+ default:
+ log_auth_failure(validated, 0);
+ ret = -1;
+ break;
+ }
+
+ debug_return_int(ret);
+}
+
+/*
+ * Call authentication method begin session hooks.
+ * Returns 1 on success and -1 on error.
+ */
+int
+sudo_auth_begin_session(struct passwd *pw, char **user_env[])
+{
+ sudo_auth *auth;
+ debug_decl(sudo_auth_begin_session, SUDOERS_DEBUG_AUTH)
+
+ for (auth = auth_switch; auth->name; auth++) {
+ if (auth->begin_session && !IS_DISABLED(auth)) {
+ int status = (auth->begin_session)(pw, user_env, auth);
+ if (status != AUTH_SUCCESS) {
+ /* Assume error msg already printed. */
+ debug_return_int(-1);
+ }
+ }
+ }
+ debug_return_int(1);
+}
+
+bool
+sudo_auth_needs_end_session(void)
+{
+ sudo_auth *auth;
+ bool needed = false;
+ debug_decl(sudo_auth_needs_end_session, SUDOERS_DEBUG_AUTH)
+
+ for (auth = auth_switch; auth->name; auth++) {
+ if (auth->end_session && !IS_DISABLED(auth)) {
+ needed = true;
+ break;
+ }
+ }
+ debug_return_bool(needed);
+}
+
+/*
+ * Call authentication method end session hooks.
+ * Returns 1 on success and -1 on error.
+ */
+int
+sudo_auth_end_session(struct passwd *pw)
+{
+ sudo_auth *auth;
+ int status;
+ debug_decl(sudo_auth_end_session, SUDOERS_DEBUG_AUTH)
+
+ for (auth = auth_switch; auth->name; auth++) {
+ if (auth->end_session && !IS_DISABLED(auth)) {
+ status = (auth->end_session)(pw, auth);
+ if (status == AUTH_FATAL) {
+ /* Assume error msg already printed. */
+ debug_return_int(-1);
+ }
+ }
+ }
+ debug_return_int(1);
+}
+
+/*
+ * Prompts the user for a password using the conversation function.
+ * Returns the plaintext password or NULL.
+ * The user is responsible for freeing the returned value.
+ */
+char *
+auth_getpass(const char *prompt, int type, struct sudo_conv_callback *callback)
+{
+ struct sudo_conv_message msg;
+ struct sudo_conv_reply repl;
+ sigset_t mask, omask;
+ debug_decl(auth_getpass, SUDOERS_DEBUG_AUTH)
+
+ /* Mask user input if pwfeedback set and echo is off. */
+ if (type == SUDO_CONV_PROMPT_ECHO_OFF && def_pwfeedback)
+ type = SUDO_CONV_PROMPT_MASK;
+
+ /* If visiblepw set, do not error out if there is no tty. */
+ if (def_visiblepw)
+ type |= SUDO_CONV_PROMPT_ECHO_OK;
+
+ /* Unblock SIGINT and SIGQUIT during password entry. */
+ /* XXX - do in tgetpass() itself instead? */
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGQUIT);
+ (void) sigprocmask(SIG_UNBLOCK, &mask, &omask);
+
+ /* Call conversation function. */
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_type = type;
+ msg.timeout = def_passwd_timeout.tv_sec;
+ msg.msg = prompt;
+ memset(&repl, 0, sizeof(repl));
+ sudo_conv(1, &msg, &repl, callback);
+ /* XXX - check for ENOTTY? */
+
+ /* Restore previous signal mask. */
+ (void) sigprocmask(SIG_SETMASK, &omask, NULL);
+
+ debug_return_str_masked(repl.reply);
+}
+
+void
+dump_auth_methods(void)
+{
+ sudo_auth *auth;
+ debug_decl(dump_auth_methods, SUDOERS_DEBUG_AUTH)
+
+ sudo_printf(SUDO_CONV_INFO_MSG, _("Authentication methods:"));
+ for (auth = auth_switch; auth->name; auth++)
+ sudo_printf(SUDO_CONV_INFO_MSG, " '%s'", auth->name);
+ sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+
+ debug_return;
+}
diff --git a/plugins/sudoers/auth/sudo_auth.h b/plugins/sudoers/auth/sudo_auth.h
new file mode 100644
index 0000000..9ae69cd
--- /dev/null
+++ b/plugins/sudoers/auth/sudo_auth.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1999-2005, 2007-2016, 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_AUTH_H
+#define SUDO_AUTH_H
+
+/* Auth function return values. */
+#define AUTH_SUCCESS 0
+#define AUTH_FAILURE 1
+#define AUTH_INTR 2
+#define AUTH_FATAL 3
+
+typedef struct sudo_auth {
+ int flags; /* various flags, see below */
+ int status; /* status from verify routine */
+ char *name; /* name of the method as a string */
+ void *data; /* method-specific data pointer */
+ int (*init)(struct passwd *pw, struct sudo_auth *auth);
+ int (*setup)(struct passwd *pw, char **prompt, struct sudo_auth *auth);
+ int (*verify)(struct passwd *pw, char *p, struct sudo_auth *auth, struct sudo_conv_callback *callback);
+ int (*approval)(struct passwd *pw, struct sudo_auth *auth, bool exempt);
+ int (*cleanup)(struct passwd *pw, struct sudo_auth *auth);
+ int (*begin_session)(struct passwd *pw, char **user_env[], struct sudo_auth *auth);
+ int (*end_session)(struct passwd *pw, struct sudo_auth *auth);
+} sudo_auth;
+
+/* Values for sudo_auth.flags. */
+#define FLAG_DISABLED 0x02 /* method disabled */
+#define FLAG_STANDALONE 0x04 /* standalone auth method */
+#define FLAG_ONEANDONLY 0x08 /* one and only auth method */
+
+/* Shortcuts for using the flags above. */
+#define IS_DISABLED(x) ((x)->flags & FLAG_DISABLED)
+#define IS_STANDALONE(x) ((x)->flags & FLAG_STANDALONE)
+#define IS_ONEANDONLY(x) ((x)->flags & FLAG_ONEANDONLY)
+
+/* Like tgetpass() but uses conversation function */
+char *auth_getpass(const char *prompt, int type, struct sudo_conv_callback *callback);
+
+/* Pointer to conversation function to use with auth_getpass(). */
+extern sudo_conv_t sudo_conv;
+
+/* Prototypes for standalone methods */
+int bsdauth_init(struct passwd *pw, sudo_auth *auth);
+int bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback);
+int bsdauth_approval(struct passwd *pw, sudo_auth *auth, bool exempt);
+int bsdauth_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_aix_init(struct passwd *pw, sudo_auth *auth);
+int sudo_aix_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
+int sudo_aix_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_fwtk_init(struct passwd *pw, sudo_auth *auth);
+int sudo_fwtk_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback);
+int sudo_fwtk_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_pam_init(struct passwd *pw, sudo_auth *auth);
+int sudo_pam_init_quiet(struct passwd *pw, sudo_auth *auth);
+int sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback);
+int sudo_pam_approval(struct passwd *pw, sudo_auth *auth, bool exempt);
+int sudo_pam_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_pam_begin_session(struct passwd *pw, char **user_env[], sudo_auth *auth);
+int sudo_pam_end_session(struct passwd *pw, sudo_auth *auth);
+int sudo_securid_init(struct passwd *pw, sudo_auth *auth);
+int sudo_securid_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
+int sudo_securid_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
+int sudo_sia_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
+int sudo_sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback);
+int sudo_sia_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_sia_begin_session(struct passwd *pw, char **user_env[], sudo_auth *auth);
+
+/* Prototypes for normal methods */
+int sudo_afs_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
+int sudo_dce_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
+int sudo_krb5_init(struct passwd *pw, sudo_auth *auth);
+int sudo_krb5_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
+int sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
+int sudo_krb5_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_passwd_init(struct passwd *pw, sudo_auth *auth);
+int sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
+int sudo_passwd_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_rfc1938_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
+int sudo_rfc1938_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
+int sudo_secureware_init(struct passwd *pw, sudo_auth *auth);
+int sudo_secureware_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
+int sudo_secureware_cleanup(struct passwd *pw, sudo_auth *auth);
+
+/* Fields: name, flags, init, setup, verify, approval, cleanup, begin_sess, end_sess */
+#define AUTH_ENTRY(n, f, i, s, v, a, c, b, e) \
+ { (f), AUTH_FAILURE, (n), NULL, (i), (s), (v), (a), (c) , (b), (e) },
+
+#endif /* SUDO_AUTH_H */
diff --git a/plugins/sudoers/base64.c b/plugins/sudoers/base64.c
new file mode 100644
index 0000000..af170e3
--- /dev/null
+++ b/plugins/sudoers/base64.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2013-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "sudoers.h"
+
+/*
+ * Derived from code with the following declaration:
+ * PUBLIC DOMAIN - Jon Mayo - November 13, 2003
+ */
+
+static const unsigned char base64dec_tab[256]= {
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
+ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+};
+
+/*
+ * Decode a NUL-terminated string in base64 format and store the
+ * result in dst.
+ */
+size_t
+base64_decode(const char *in, unsigned char *out, size_t out_size)
+{
+ unsigned char *out_end = out + out_size;
+ const unsigned char *out0 = out;
+ unsigned int rem, v;
+ debug_decl(base64_decode, SUDOERS_DEBUG_MATCH)
+
+ for (v = 0, rem = 0; *in != '\0' && *in != '='; in++) {
+ unsigned char ch = base64dec_tab[(unsigned char)*in];
+ if (ch == 255)
+ debug_return_size_t((size_t)-1);
+ v = (v << 6) | ch;
+ rem += 6;
+ if (rem >= 8) {
+ rem -= 8;
+ if (out >= out_end)
+ debug_return_size_t((size_t)-1);
+ *out++ = (v >> rem) & 0xff;
+ }
+ }
+ if (rem >= 8) {
+ if (out >= out_end)
+ debug_return_size_t((size_t)-1);
+ *out++ = (v >> rem) & 0xff;
+ }
+ debug_return_size_t((size_t)(out - out0));
+}
+
+static const unsigned char base64enc_tab[64] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+size_t
+base64_encode(const unsigned char *in, size_t in_len, char *out, size_t out_len)
+{
+ size_t ii, io;
+ unsigned int rem, v;
+ debug_decl(base64_encode, SUDOERS_DEBUG_MATCH)
+
+ for (io = 0, ii = 0, v = 0, rem = 0; ii < in_len; ii++) {
+ unsigned char ch = in[ii];
+ v = (v << 8) | ch;
+ rem += 8;
+ while (rem >= 6) {
+ rem -= 6;
+ if (io >= out_len)
+ debug_return_size_t((size_t)-1); /* truncation is failure */
+ out[io++] = base64enc_tab[(v >> rem) & 63];
+ }
+ }
+ if (rem != 0) {
+ v <<= (6 - rem);
+ if (io >= out_len)
+ debug_return_size_t((size_t)-1); /* truncation is failure */
+ out[io++] = base64enc_tab[v&63];
+ }
+ while (io & 3) {
+ if (io >= out_len)
+ debug_return_size_t((size_t)-1); /* truncation is failure */
+ out[io++] = '=';
+ }
+ if (io >= out_len)
+ debug_return_size_t((size_t)-1); /* no room for NUL terminator */
+ out[io] = '\0';
+ debug_return_size_t(io);
+}
diff --git a/plugins/sudoers/boottime.c b/plugins/sudoers/boottime.c
new file mode 100644
index 0000000..ff409ae
--- /dev/null
+++ b/plugins/sudoers/boottime.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2009-2015, 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <errno.h>
+#include <limits.h>
+#include <time.h>
+#ifndef __linux__
+# if defined(HAVE_SYSCTL) && defined(KERN_BOOTTIME)
+# include <sys/sysctl.h>
+# elif defined(HAVE_GETUTXID)
+# include <utmpx.h>
+# elif defined(HAVE_GETUTID)
+# include <utmp.h>
+# endif
+#endif /* !__linux__ */
+
+#include "sudoers.h"
+
+/*
+ * Fill in a struct timespec with the time the system booted.
+ * Returns 1 on success and 0 on failure.
+ */
+
+#if defined(__linux__)
+bool
+get_boottime(struct timespec *ts)
+{
+ char *line = NULL;
+ size_t linesize = 0;
+ bool found = false;
+ long long llval;
+ ssize_t len;
+ FILE *fp;
+ debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)
+
+ /* read btime from /proc/stat */
+ fp = fopen("/proc/stat", "r");
+ if (fp != NULL) {
+ while ((len = getline(&line, &linesize, fp)) != -1) {
+ if (strncmp(line, "btime ", 6) == 0) {
+ if (line[len - 1] == '\n')
+ line[len - 1] = '\0';
+ llval = strtonum(line + 6, 1, LLONG_MAX, NULL);
+ if (llval > 0) {
+ ts->tv_sec = (time_t)llval;
+ ts->tv_nsec = 0;
+ found = true;
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "found btime in /proc/stat: %lld", llval);
+ break;
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "invalid btime in /proc/stat: %s", line);
+ }
+ }
+ }
+ fclose(fp);
+ free(line);
+ }
+
+ debug_return_bool(found);
+}
+
+#elif defined(HAVE_SYSCTL) && defined(KERN_BOOTTIME)
+
+bool
+get_boottime(struct timespec *ts)
+{
+ size_t size;
+ int mib[2];
+ struct timeval tv;
+ debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_BOOTTIME;
+ size = sizeof(tv);
+ if (sysctl(mib, 2, &tv, &size, NULL, 0) != -1) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "KERN_BOOTTIME: %lld, %ld", (long long)tv.tv_sec, (long)tv.tv_usec);
+ TIMEVAL_TO_TIMESPEC(&tv, ts);
+ debug_return_bool(true);
+ }
+
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "KERN_BOOTTIME: %s", strerror(errno));
+ debug_return_bool(false);
+}
+
+#elif defined(HAVE_GETUTXID)
+
+bool
+get_boottime(struct timespec *ts)
+{
+ struct utmpx *ut, key;
+ debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)
+
+ memset(&key, 0, sizeof(key));
+ key.ut_type = BOOT_TIME;
+ setutxent();
+ if ((ut = getutxid(&key)) != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "BOOT_TIME: %lld, %ld", (long long)ut->ut_tv.tv_sec,
+ (long)ut->ut_tv.tv_usec);
+ TIMEVAL_TO_TIMESPEC(&ut->ut_tv, ts);
+ }
+ endutxent();
+ debug_return_bool(ut != NULL);
+}
+
+#elif defined(HAVE_GETUTID)
+
+bool
+get_boottime(struct timespec *ts)
+{
+ struct utmp *ut, key;
+ debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)
+
+ memset(&key, 0, sizeof(key));
+ key.ut_type = BOOT_TIME;
+ setutent();
+ if ((ut = getutid(&key)) != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "BOOT_TIME: %lld", (long long)ut->ut_time);
+ ts->tv_sec = ut->ut_time;
+ ts->tv_nsec = 0;
+ }
+ endutent();
+ debug_return_bool(ut != NULL);
+}
+
+#else
+
+bool
+get_boottime(struct timespec *ts)
+{
+ debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)
+ debug_return_bool(false);
+}
+#endif
diff --git a/plugins/sudoers/bsm_audit.c b/plugins/sudoers/bsm_audit.c
new file mode 100644
index 0000000..c0a8de4
--- /dev/null
+++ b/plugins/sudoers/bsm_audit.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2009-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ * Copyright (c) 2009 Christian S.J. Peron
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_BSM_AUDIT
+
+#include <sys/types.h>
+
+#include <bsm/audit.h>
+#include <bsm/libbsm.h>
+#include <bsm/audit_uevents.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <pwd.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "sudoers.h"
+#include "bsm_audit.h"
+
+/*
+ * Solaris auditon() returns EINVAL if BSM audit not configured.
+ * OpenBSM returns ENOSYS for unimplemented options.
+ */
+#ifdef __sun
+# define AUDIT_NOT_CONFIGURED EINVAL
+#else
+# define AUDIT_NOT_CONFIGURED ENOSYS
+#endif
+
+#ifdef __FreeBSD__
+# define BSM_AUDIT_COMPAT
+#endif
+
+static au_event_t sudo_audit_event = AUE_sudo;
+
+static int
+audit_sudo_selected(int sorf)
+{
+ auditinfo_addr_t ainfo_addr;
+ struct au_mask *mask;
+ int rc;
+ debug_decl(audit_sudo_selected, SUDOERS_DEBUG_AUDIT)
+
+ if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) {
+#ifdef BSM_AUDIT_COMPAT
+ if (errno == ENOSYS) {
+ auditinfo_t ainfo;
+
+ /* Fall back to older BSM API. */
+ if (getaudit(&ainfo) < 0) {
+ sudo_warn("getaudit");
+ debug_return_int(-1);
+ }
+ mask = &ainfo.ai_mask;
+ } else
+#endif /* BSM_AUDIT_COMPAT */
+ {
+ sudo_warn("getaudit_addr");
+ debug_return_int(-1);
+ }
+ } else {
+ mask = &ainfo_addr.ai_mask;
+ }
+ rc = au_preselect(sudo_audit_event, mask, sorf, AU_PRS_REREAD);
+ if (rc == -1) {
+#if defined(__APPLE__) && defined(AUE_DARWIN_sudo)
+ /*
+ * Mac OS X 10.10 au_preselect() only accepts AUE_DARWIN_sudo.
+ */
+ sudo_audit_event = AUE_DARWIN_sudo;
+ rc = au_preselect(sudo_audit_event, mask, sorf, AU_PRS_REREAD);
+ if (rc == -1)
+#endif
+
+ sudo_warn("au_preselect");
+ }
+ debug_return_int(rc);
+}
+
+/*
+ * Returns 0 on success or -1 on error.
+ */
+int
+bsm_audit_success(char *exec_args[])
+{
+ auditinfo_addr_t ainfo_addr;
+ token_t *tok;
+ au_id_t auid;
+ long au_cond;
+ int aufd, selected;
+ pid_t pid;
+ debug_decl(bsm_audit_success, SUDOERS_DEBUG_AUDIT)
+
+ /*
+ * If we are not auditing, don't cut an audit record; just return.
+ */
+ if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) {
+ if (errno == AUDIT_NOT_CONFIGURED)
+ debug_return_int(0);
+ sudo_warn(U_("Could not determine audit condition"));
+ debug_return_int(-1);
+ }
+ if (au_cond == AUC_NOAUDIT)
+ debug_return_int(0);
+ /*
+ * Check to see if the preselection masks are interested in seeing
+ * this event.
+ */
+ selected = audit_sudo_selected(AU_PRS_SUCCESS);
+ if (selected != 1)
+ debug_return_int(!selected ? 0 : -1);
+ if (getauid(&auid) < 0) {
+ sudo_warn("getauid");
+ debug_return_int(-1);
+ }
+ if ((aufd = au_open()) == -1) {
+ sudo_warn("au_open");
+ debug_return_int(-1);
+ }
+ pid = getpid();
+ if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) {
+ tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
+ getuid(), pid, pid, &ainfo_addr.ai_termid);
+#ifdef BSM_AUDIT_COMPAT
+ } else if (errno == ENOSYS) {
+ auditinfo_t ainfo;
+
+ /*
+ * NB: We should probably watch out for ERANGE here.
+ */
+ if (getaudit(&ainfo) < 0) {
+ sudo_warn("getaudit");
+ debug_return_int(-1);
+ }
+ tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
+ getuid(), pid, pid, &ainfo.ai_termid);
+#endif /* BSM_AUDIT_COMPAT */
+ } else {
+ sudo_warn("getaudit_addr");
+ debug_return_int(-1);
+ }
+ if (tok == NULL) {
+ sudo_warn("au_to_subject");
+ debug_return_int(-1);
+ }
+ au_write(aufd, tok);
+ tok = au_to_exec_args(exec_args);
+ if (tok == NULL) {
+ sudo_warn("au_to_exec_args");
+ debug_return_int(-1);
+ }
+ au_write(aufd, tok);
+ tok = au_to_return32(0, 0);
+ if (tok == NULL) {
+ sudo_warn("au_to_return32");
+ debug_return_int(-1);
+ }
+ au_write(aufd, tok);
+#ifdef HAVE_AU_CLOSE_SOLARIS11
+ if (au_close(aufd, 1, sudo_audit_event, 0) == -1)
+#else
+ if (au_close(aufd, 1, sudo_audit_event) == -1)
+#endif
+ {
+ sudo_warn(U_("unable to commit audit record"));
+ debug_return_int(-1);
+ }
+ debug_return_int(0);
+}
+
+/*
+ * Returns 0 on success or -1 on error.
+ */
+int
+bsm_audit_failure(char *exec_args[], char const *const fmt, va_list ap)
+{
+ auditinfo_addr_t ainfo_addr;
+ char text[256];
+ token_t *tok;
+ long au_cond;
+ au_id_t auid;
+ pid_t pid;
+ int aufd;
+ debug_decl(bsm_audit_success, SUDOERS_DEBUG_AUDIT)
+
+ /*
+ * If we are not auditing, don't cut an audit record; just return.
+ */
+ if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) {
+ if (errno == AUDIT_NOT_CONFIGURED)
+ debug_return_int(0);
+ sudo_warn(U_("Could not determine audit condition"));
+ debug_return_int(-1);
+ }
+ if (au_cond == AUC_NOAUDIT)
+ debug_return_int(0);
+ if (!audit_sudo_selected(AU_PRS_FAILURE))
+ debug_return_int(0);
+ if (getauid(&auid) < 0) {
+ sudo_warn("getauid");
+ debug_return_int(-1);
+ }
+ if ((aufd = au_open()) == -1) {
+ sudo_warn("au_open");
+ debug_return_int(-1);
+ }
+ pid = getpid();
+ if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) {
+ tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
+ getuid(), pid, pid, &ainfo_addr.ai_termid);
+#ifdef BSM_AUDIT_COMPAT
+ } else if (errno == ENOSYS) {
+ auditinfo_t ainfo;
+
+ if (getaudit(&ainfo) < 0) {
+ sudo_warn("getaudit");
+ debug_return_int(-1);
+ }
+ tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
+ getuid(), pid, pid, &ainfo.ai_termid);
+#endif /* BSM_AUDIT_COMPAT */
+ } else {
+ sudo_warn("getaudit_addr");
+ debug_return_int(-1);
+ }
+ if (tok == NULL) {
+ sudo_warn("au_to_subject");
+ debug_return_int(-1);
+ }
+ au_write(aufd, tok);
+ tok = au_to_exec_args(exec_args);
+ if (tok == NULL) {
+ sudo_warn("au_to_exec_args");
+ debug_return_int(-1);
+ }
+ au_write(aufd, tok);
+ (void) vsnprintf(text, sizeof(text), fmt, ap);
+ tok = au_to_text(text);
+ if (tok == NULL) {
+ sudo_warn("au_to_text");
+ debug_return_int(-1);
+ }
+ au_write(aufd, tok);
+ tok = au_to_return32(EPERM, 1);
+ if (tok == NULL) {
+ sudo_warn("au_to_return32");
+ debug_return_int(-1);
+ }
+ au_write(aufd, tok);
+#ifdef HAVE_AU_CLOSE_SOLARIS11
+ if (au_close(aufd, 1, sudo_audit_event, PAD_FAILURE) == -1)
+#else
+ if (au_close(aufd, 1, sudo_audit_event) == -1)
+#endif
+ {
+ sudo_warn(U_("unable to commit audit record"));
+ debug_return_int(-1);
+ }
+ debug_return_int(0);
+}
+
+#endif /* HAVE_BSM_AUDIT */
diff --git a/plugins/sudoers/bsm_audit.h b/plugins/sudoers/bsm_audit.h
new file mode 100644
index 0000000..21d6185
--- /dev/null
+++ b/plugins/sudoers/bsm_audit.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2009-2010, 2013-2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ * Copyright (c) 2009 Christian S.J. Peron
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_BSM_AUDIT_H
+#define SUDOERS_BSM_AUDIT_H
+
+int bsm_audit_success(char *argv[]);
+int bsm_audit_failure(char *argv[], char const * const, va_list);
+
+#endif /* SUDOERS_BSM_AUDIT_H */
diff --git a/plugins/sudoers/check.c b/plugins/sudoers/check.c
new file mode 100644
index 0000000..92f859c
--- /dev/null
+++ b/plugins/sudoers/check.c
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 1993-1996,1998-2005, 2007-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "sudoers.h"
+#include "check.h"
+
+static bool display_lecture(int);
+static struct passwd *get_authpw(int);
+
+struct getpass_closure {
+ void *cookie;
+ struct passwd *auth_pw;
+};
+
+/*
+ * Called when getpass is suspended so we can drop the lock.
+ */
+static int
+getpass_suspend(int signo, void *vclosure)
+{
+ struct getpass_closure *closure = vclosure;
+
+ timestamp_close(closure->cookie);
+ closure->cookie = NULL;
+ return 0;
+}
+
+/*
+ * Called when getpass is resumed so we can reacquire the lock.
+ */
+static int
+getpass_resume(int signo, void *vclosure)
+{
+ struct getpass_closure *closure = vclosure;
+
+ closure->cookie = timestamp_open(user_name, user_sid);
+ if (closure->cookie == NULL)
+ return -1;
+ if (!timestamp_lock(closure->cookie, closure->auth_pw))
+ return -1;
+ return 0;
+}
+
+/*
+ * Returns true if the user successfully authenticates, false if not
+ * or -1 on fatal error.
+ */
+static int
+check_user_interactive(int validated, int mode, struct passwd *auth_pw)
+{
+ struct sudo_conv_callback cb, *callback = NULL;
+ struct getpass_closure closure;
+ int status = TS_ERROR;
+ int ret = -1;
+ char *prompt;
+ bool lectured;
+ debug_decl(check_user_interactive, SUDOERS_DEBUG_AUTH)
+
+ /* Setup closure for getpass_{suspend,resume} */
+ closure.auth_pw = auth_pw;
+ closure.cookie = NULL;
+ sudo_pw_addref(closure.auth_pw);
+
+ /* Open, lock and read time stamp file if we are using it. */
+ if (!ISSET(mode, MODE_IGNORE_TICKET)) {
+ /* Open time stamp file and check its status. */
+ closure.cookie = timestamp_open(user_name, user_sid);
+ if (timestamp_lock(closure.cookie, closure.auth_pw))
+ status = timestamp_status(closure.cookie, closure.auth_pw);
+
+ /* Construct callback for getpass function. */
+ memset(&cb, 0, sizeof(cb));
+ cb.version = SUDO_CONV_CALLBACK_VERSION;
+ cb.closure = &closure;
+ cb.on_suspend = getpass_suspend;
+ cb.on_resume = getpass_resume;
+ callback = &cb;
+ }
+
+ switch (status) {
+ case TS_FATAL:
+ /* Fatal error (usually setuid failure), unsafe to proceed. */
+ goto done;
+
+ case TS_CURRENT:
+ /* Time stamp file is valid and current. */
+ if (!ISSET(validated, FLAG_CHECK_USER)) {
+ ret = true;
+ break;
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: check user flag overrides time stamp", __func__);
+ /* FALLTHROUGH */
+
+ default:
+ /* Bail out if we are non-interactive and a password is required */
+ if (ISSET(mode, MODE_NONINTERACTIVE)) {
+ validated |= FLAG_NON_INTERACTIVE;
+ log_auth_failure(validated, 0);
+ goto done;
+ }
+
+ /* XXX - should not lecture if askpass helper is being used. */
+ lectured = display_lecture(status);
+
+ /* Expand any escapes in the prompt. */
+ prompt = expand_prompt(user_prompt ? user_prompt : def_passprompt,
+ closure.auth_pw->pw_name);
+ if (prompt == NULL)
+ goto done;
+
+ ret = verify_user(closure.auth_pw, prompt, validated, callback);
+ if (ret == true && lectured)
+ (void)set_lectured(); /* lecture error not fatal */
+ free(prompt);
+ break;
+ }
+
+ /*
+ * Only update time stamp if user was validated.
+ * Failure to update the time stamp is not a fatal error.
+ */
+ if (ret == true && ISSET(validated, VALIDATE_SUCCESS) && status != TS_ERROR)
+ (void)timestamp_update(closure.cookie, closure.auth_pw);
+done:
+ if (closure.cookie != NULL)
+ timestamp_close(closure.cookie);
+ sudo_pw_delref(closure.auth_pw);
+
+ debug_return_int(ret);
+}
+
+/*
+ * Returns true if the user successfully authenticates, false if not
+ * or -1 on error.
+ */
+int
+check_user(int validated, int mode)
+{
+ struct passwd *auth_pw;
+ int ret = -1;
+ bool exempt = false;
+ debug_decl(check_user, SUDOERS_DEBUG_AUTH)
+
+ /*
+ * Init authentication system regardless of whether we need a password.
+ * Required for proper PAM session support.
+ */
+ if ((auth_pw = get_authpw(mode)) == NULL)
+ goto done;
+ if (sudo_auth_init(auth_pw) == -1)
+ goto done;
+
+ /*
+ * Don't prompt for the root passwd or if the user is exempt.
+ * If the user is not changing uid/gid, no need for a password.
+ */
+ if (!def_authenticate || user_is_exempt()) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %s", __func__,
+ !def_authenticate ? "authentication disabled" :
+ "user exempt from authentication");
+ exempt = true;
+ ret = true;
+ goto done;
+ }
+ if (user_uid == 0 || (user_uid == runas_pw->pw_uid &&
+ (!runas_gr || user_in_group(sudo_user.pw, runas_gr->gr_name)))) {
+#ifdef HAVE_SELINUX
+ if (user_role == NULL && user_type == NULL)
+#endif
+#ifdef HAVE_PRIV_SET
+ if (runas_privs == NULL && runas_limitprivs == NULL)
+#endif
+ {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: user running command as self", __func__);
+ ret = true;
+ goto done;
+ }
+ }
+
+ ret = check_user_interactive(validated, mode, auth_pw);
+
+done:
+ if (ret == true) {
+ /* The approval function may disallow a user post-authentication. */
+ ret = sudo_auth_approval(auth_pw, validated, exempt);
+ }
+ sudo_auth_cleanup(auth_pw);
+ sudo_pw_delref(auth_pw);
+
+ debug_return_int(ret);
+}
+
+/*
+ * Display sudo lecture (standard or custom).
+ * Returns true if the user was lectured, else false.
+ */
+static bool
+display_lecture(int status)
+{
+ FILE *fp;
+ char buf[BUFSIZ];
+ ssize_t nread;
+ struct sudo_conv_message msg;
+ struct sudo_conv_reply repl;
+ debug_decl(lecture, SUDOERS_DEBUG_AUTH)
+
+ if (def_lecture == never ||
+ (def_lecture == once && already_lectured(status)))
+ debug_return_bool(false);
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&repl, 0, sizeof(repl));
+
+ if (def_lecture_file && (fp = fopen(def_lecture_file, "r")) != NULL) {
+ while ((nread = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) != 0) {
+ buf[nread] = '\0';
+ msg.msg_type = SUDO_CONV_ERROR_MSG;
+ msg.msg = buf;
+ sudo_conv(1, &msg, &repl, NULL);
+ }
+ fclose(fp);
+ } else {
+ msg.msg_type = SUDO_CONV_ERROR_MSG;
+ msg.msg = _("\n"
+ "We trust you have received the usual lecture from the local System\n"
+ "Administrator. It usually boils down to these three things:\n\n"
+ " #1) Respect the privacy of others.\n"
+ " #2) Think before you type.\n"
+ " #3) With great power comes great responsibility.\n\n");
+ sudo_conv(1, &msg, &repl, NULL);
+ }
+ debug_return_bool(true);
+}
+
+/*
+ * Checks if the user is exempt from supplying a password.
+ */
+bool
+user_is_exempt(void)
+{
+ bool ret = false;
+ debug_decl(user_is_exempt, SUDOERS_DEBUG_AUTH)
+
+ if (def_exempt_group)
+ ret = user_in_group(sudo_user.pw, def_exempt_group);
+ debug_return_bool(ret);
+}
+
+/*
+ * Get passwd entry for the user we are going to authenticate as.
+ * By default, this is the user invoking sudo. In the most common
+ * case, this matches sudo_user.pw or runas_pw.
+ */
+static struct passwd *
+get_authpw(int mode)
+{
+ struct passwd *pw = NULL;
+ debug_decl(get_authpw, SUDOERS_DEBUG_AUTH)
+
+ if (ISSET(mode, (MODE_CHECK|MODE_LIST))) {
+ /* In list mode we always prompt for the user's password. */
+ sudo_pw_addref(sudo_user.pw);
+ pw = sudo_user.pw;
+ } else {
+ if (def_rootpw) {
+ if ((pw = sudo_getpwuid(ROOT_UID)) == NULL) {
+ log_warningx(SLOG_SEND_MAIL, N_("unknown uid: %u"), ROOT_UID);
+ }
+ } else if (def_runaspw) {
+ if ((pw = sudo_getpwnam(def_runas_default)) == NULL) {
+ log_warningx(SLOG_SEND_MAIL,
+ N_("unknown user: %s"), def_runas_default);
+ }
+ } else if (def_targetpw) {
+ if (runas_pw->pw_name == NULL) {
+ /* This should never be NULL as we fake up the passwd struct */
+ log_warningx(SLOG_RAW_MSG, N_("unknown uid: %u"),
+ (unsigned int) runas_pw->pw_uid);
+ } else {
+ sudo_pw_addref(runas_pw);
+ pw = runas_pw;
+ }
+ } else {
+ sudo_pw_addref(sudo_user.pw);
+ pw = sudo_user.pw;
+ }
+ }
+
+ debug_return_ptr(pw);
+}
diff --git a/plugins/sudoers/check.h b/plugins/sudoers/check.h
new file mode 100644
index 0000000..11013c8
--- /dev/null
+++ b/plugins/sudoers/check.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1993-1996,1998-2005, 2007-2014
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#ifndef SUDOERS_CHECK_H
+#define SUDOERS_CHECK_H
+
+/* Status codes for timestamp_status() */
+#define TS_CURRENT 0
+#define TS_OLD 1
+#define TS_MISSING 2
+#define TS_ERROR 3
+#define TS_FATAL 4
+
+/*
+ * Time stamps are now stored in a single file which contains multiple
+ * records. Each record starts with a 16-bit version number and a 16-bit
+ * record size. Multiple record types can coexist in the same file.
+ */
+#define TS_VERSION 2
+
+/* Time stamp entry types */
+#define TS_GLOBAL 0x01 /* not restricted by tty or ppid */
+#define TS_TTY 0x02 /* restricted by tty */
+#define TS_PPID 0x03 /* restricted by ppid */
+#define TS_LOCKEXCL 0x04 /* special lock record */
+
+/* Time stamp flags */
+#define TS_DISABLED 0x01 /* entry disabled */
+#define TS_ANYUID 0x02 /* ignore uid, only valid in the key */
+
+struct timestamp_entry_v1 {
+ unsigned short version; /* version number */
+ unsigned short size; /* entry size */
+ unsigned short type; /* TS_GLOBAL, TS_TTY, TS_PPID */
+ unsigned short flags; /* TS_DISABLED, TS_ANYUID */
+ uid_t auth_uid; /* uid to authenticate as */
+ pid_t sid; /* session ID associated with tty/ppid */
+ struct timespec ts; /* time stamp (CLOCK_MONOTONIC) */
+ union {
+ dev_t ttydev; /* tty device number */
+ pid_t ppid; /* parent pid */
+ } u;
+};
+
+struct timestamp_entry {
+ unsigned short version; /* version number */
+ unsigned short size; /* entry size */
+ unsigned short type; /* TS_GLOBAL, TS_TTY, TS_PPID */
+ unsigned short flags; /* TS_DISABLED, TS_ANYUID */
+ uid_t auth_uid; /* uid to authenticate as */
+ pid_t sid; /* session ID associated with tty/ppid */
+ struct timespec start_time; /* session/ppid start time */
+ struct timespec ts; /* time stamp (CLOCK_MONOTONIC) */
+ union {
+ dev_t ttydev; /* tty device number */
+ pid_t ppid; /* parent pid */
+ } u;
+};
+
+void *timestamp_open(const char *user, pid_t sid);
+void timestamp_close(void *vcookie);
+bool timestamp_lock(void *vcookie, struct passwd *pw);
+bool timestamp_update(void *vcookie, struct passwd *pw);
+int timestamp_status(void *vcookie, struct passwd *pw);
+int get_starttime(pid_t pid, struct timespec *starttime);
+bool already_lectured(int status);
+int set_lectured(void);
+
+#endif /* SUDOERS_CHECK_H */
diff --git a/plugins/sudoers/cvtsudoers.c b/plugins/sudoers/cvtsudoers.c
new file mode 100644
index 0000000..0221314
--- /dev/null
+++ b/plugins/sudoers/cvtsudoers.c
@@ -0,0 +1,1334 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+/*
+ * Convert from the sudoers file format to LDIF or JSON format.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <unistd.h>
+
+#include "sudoers.h"
+#include "sudoers_version.h"
+#include "sudo_conf.h"
+#include "sudo_lbuf.h"
+#include "redblack.h"
+#include "cvtsudoers.h"
+#include <gram.h>
+
+#ifdef HAVE_GETOPT_LONG
+# include <getopt.h>
+# else
+# include "compat/getopt.h"
+#endif /* HAVE_GETOPT_LONG */
+
+/*
+ * Globals
+ */
+struct cvtsudoers_filter *filters;
+struct sudo_user sudo_user;
+struct passwd *list_pw;
+static const char short_opts[] = "b:c:d:ef:hi:I:m:Mo:O:pP:s:V";
+static struct option long_opts[] = {
+ { "base", required_argument, NULL, 'b' },
+ { "config", required_argument, NULL, 'c' },
+ { "defaults", required_argument, NULL, 'd' },
+ { "expand-aliases", no_argument, NULL, 'e' },
+ { "output-format", required_argument, NULL, 'f' },
+ { "help", no_argument, NULL, 'h' },
+ { "input-format", required_argument, NULL, 'i' },
+ { "increment", required_argument, NULL, 'I' },
+ { "match", required_argument, NULL, 'm' },
+ { "match-local", no_argument, NULL, 'M' },
+ { "prune-matches", no_argument, NULL, 'p' },
+ { "padding", required_argument, NULL, 'P' },
+ { "order-start", required_argument, NULL, 'O' },
+ { "output", required_argument, NULL, 'o' },
+ { "suppress", required_argument, NULL, 's' },
+ { "version", no_argument, NULL, 'V' },
+ { NULL, no_argument, NULL, '\0' },
+};
+
+__dso_public int main(int argc, char *argv[]);
+static void help(void) __attribute__((__noreturn__));
+static void usage(int);
+static bool convert_sudoers_sudoers(struct sudoers_parse_tree *parse_tree, const char *output_file, struct cvtsudoers_config *conf);
+static bool parse_sudoers(const char *input_file, struct cvtsudoers_config *conf);
+static bool parse_ldif(struct sudoers_parse_tree *parse_tree, const char *input_file, struct cvtsudoers_config *conf);
+static bool cvtsudoers_parse_filter(char *expression);
+static struct cvtsudoers_config *cvtsudoers_conf_read(const char *conf_file);
+static void cvtsudoers_conf_free(struct cvtsudoers_config *conf);
+static int cvtsudoers_parse_defaults(char *expression);
+static int cvtsudoers_parse_suppression(char *expression);
+static void filter_userspecs(struct sudoers_parse_tree *parse_tree, struct cvtsudoers_config *conf);
+static void filter_defaults(struct sudoers_parse_tree *parse_tree, struct cvtsudoers_config *conf);
+static void alias_remove_unused(struct sudoers_parse_tree *parse_tree);
+static void alias_prune(struct sudoers_parse_tree *parse_tree, struct cvtsudoers_config *conf);
+
+int
+main(int argc, char *argv[])
+{
+ int ch, exitcode = EXIT_FAILURE;
+ enum sudoers_formats output_format = format_ldif;
+ enum sudoers_formats input_format = format_sudoers;
+ struct cvtsudoers_config *conf = NULL;
+ bool match_local = false;
+ const char *input_file = "-";
+ const char *output_file = "-";
+ const char *conf_file = _PATH_CVTSUDOERS_CONF;
+ const char *errstr;
+ debug_decl(main, SUDOERS_DEBUG_MAIN)
+
+#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
+ {
+ extern char *malloc_options;
+ malloc_options = "S";
+ }
+#endif
+
+ initprogname(argc > 0 ? argv[0] : "cvtsudoers");
+ if (!sudoers_initlocale(setlocale(LC_ALL, ""), def_sudoers_locale))
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sudo_warn_set_locale_func(sudoers_warn_setlocale);
+ bindtextdomain("sudoers", LOCALEDIR);
+ textdomain("sudoers");
+
+ /* Read debug and plugin sections of sudo.conf. */
+ if (sudo_conf_read(NULL, SUDO_CONF_DEBUG|SUDO_CONF_PLUGINS) == -1)
+ goto done;
+
+ /* Initialize the debug subsystem. */
+ if (!sudoers_debug_register(getprogname(), sudo_conf_debug_files(getprogname())))
+ goto done;
+
+ /* Check for --config option first (no getopt warnings). */
+ opterr = 0;
+ while ((ch = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
+ switch (ch) {
+ case 'c':
+ conf_file = optarg;
+ break;
+ }
+ }
+
+ /* Read conf file. */
+ conf = cvtsudoers_conf_read(conf_file);
+
+ /*
+ * Reset getopt and handle the rest of the arguments.
+ */
+ opterr = 1;
+ optind = 1;
+#ifdef HAVE_OPTRESET
+ optreset = 1;
+#endif
+ while ((ch = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
+ switch (ch) {
+ case 'b':
+ free(conf->sudoers_base);
+ conf->sudoers_base = strdup(optarg);
+ if (conf->sudoers_base == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ break;
+ case 'c':
+ /* handled above */
+ break;
+ case 'd':
+ conf->defstr = optarg;
+ break;
+ case 'e':
+ conf->expand_aliases = true;
+ break;
+ case 'f':
+ free(conf->output_format);
+ conf->output_format = strdup(optarg);
+ if (conf->output_format == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ break;
+ case 'h':
+ help();
+ break;
+ case 'i':
+ free(conf->input_format);
+ conf->input_format = strdup(optarg);
+ if (conf->input_format == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ break;
+ case 'I':
+ conf->order_increment = sudo_strtonum(optarg, 1, UINT_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("order increment: %s: %s"), optarg, U_(errstr));
+ usage(1);
+ }
+ break;
+ case 'm':
+ conf->filter = optarg;
+ break;
+ case 'M':
+ match_local = true;
+ break;
+ case 'o':
+ output_file = optarg;
+ break;
+ case 'O':
+ conf->sudo_order = sudo_strtonum(optarg, 0, UINT_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("starting order: %s: %s"), optarg, U_(errstr));
+ usage(1);
+ }
+ break;
+ case 'p':
+ conf->prune_matches = true;
+ break;
+ case 'P':
+ conf->order_padding = sudo_strtonum(optarg, 1, UINT_MAX, &errstr);
+ if (errstr != NULL ) {
+ sudo_warnx(U_("order padding: %s: %s"), optarg, U_(errstr));
+ usage(1);
+ }
+ break;
+ case 's':
+ conf->supstr = optarg;
+ break;
+ case 'V':
+ (void) printf(_("%s version %s\n"), getprogname(),
+ PACKAGE_VERSION);
+ (void) printf(_("%s grammar version %d\n"), getprogname(),
+ SUDOERS_GRAMMAR_VERSION);
+ exitcode = EXIT_SUCCESS;
+ goto done;
+ default:
+ usage(1);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (conf->input_format != NULL) {
+ if (strcasecmp(conf->input_format, "ldif") == 0) {
+ input_format = format_ldif;
+ } else if (strcasecmp(conf->input_format, "sudoers") == 0) {
+ input_format = format_sudoers;
+ } else {
+ sudo_warnx(U_("unsupported input format %s"), conf->input_format);
+ usage(1);
+ }
+ }
+ if (conf->output_format != NULL) {
+ if (strcasecmp(conf->output_format, "json") == 0) {
+ output_format = format_json;
+ conf->store_options = true;
+ } else if (strcasecmp(conf->output_format, "ldif") == 0) {
+ output_format = format_ldif;
+ conf->store_options = true;
+ } else if (strcasecmp(conf->output_format, "sudoers") == 0) {
+ output_format = format_sudoers;
+ conf->store_options = false;
+ } else {
+ sudo_warnx(U_("unsupported output format %s"), conf->output_format);
+ usage(1);
+ }
+ }
+ if (conf->filter != NULL) {
+ /* We always expand aliases when filtering (may change in future). */
+ if (!cvtsudoers_parse_filter(conf->filter))
+ usage(1);
+ }
+ if (conf->defstr != NULL) {
+ conf->defaults = cvtsudoers_parse_defaults(conf->defstr);
+ if (conf->defaults == -1)
+ usage(1);
+ }
+ if (conf->supstr != NULL) {
+ conf->suppress = cvtsudoers_parse_suppression(conf->supstr);
+ if (conf->suppress == -1)
+ usage(1);
+ }
+
+ /* Apply padding to sudo_order if present. */
+ if (conf->sudo_order != 0 && conf->order_padding != 0) {
+ unsigned int multiplier = 1;
+
+ do {
+ multiplier *= 10;
+ } while (--conf->order_padding != 0);
+ conf->sudo_order *= multiplier;
+ conf->order_max = conf->sudo_order + (multiplier - 1);
+ conf->order_padding = multiplier;
+ }
+
+ /* If no base DN specified, check SUDOERS_BASE. */
+ if (conf->sudoers_base == NULL) {
+ conf->sudoers_base = getenv("SUDOERS_BASE");
+ if (conf->sudoers_base != NULL && *conf->sudoers_base != '\0') {
+ if ((conf->sudoers_base = strdup(conf->sudoers_base)) == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ }
+ }
+
+ /* Input file (defaults to stdin). */
+ if (argc > 0) {
+ if (argc > 1)
+ usage(1);
+ input_file = argv[0];
+ }
+
+ if (strcmp(input_file, "-") != 0) {
+ if (strcmp(input_file, output_file) == 0) {
+ sudo_fatalx(U_("%s: input and output files must be different"),
+ input_file);
+ }
+ }
+
+ /* Set pwutil backend to use the filter data. */
+ if (conf->filter != NULL && !match_local) {
+ sudo_pwutil_set_backend(cvtsudoers_make_pwitem, cvtsudoers_make_gritem,
+ cvtsudoers_make_gidlist_item, cvtsudoers_make_grlist_item);
+ }
+
+ /* We may need the hostname to resolve %h escapes in include files. */
+ get_hostname();
+
+ /* Setup defaults data structures. */
+ if (!init_defaults())
+ sudo_fatalx(U_("unable to initialize sudoers default values"));
+
+ switch (input_format) {
+ case format_ldif:
+ if (!parse_ldif(&parsed_policy, input_file, conf))
+ goto done;
+ break;
+ case format_sudoers:
+ if (!parse_sudoers(input_file, conf))
+ goto done;
+ break;
+ default:
+ sudo_fatalx("error: unhandled input %d", input_format);
+ }
+
+ /* Apply filters. */
+ filter_userspecs(&parsed_policy, conf);
+ filter_defaults(&parsed_policy, conf);
+ if (filters != NULL) {
+ alias_remove_unused(&parsed_policy);
+ if (conf->prune_matches && conf->expand_aliases)
+ alias_prune(&parsed_policy, conf);
+ }
+
+ switch (output_format) {
+ case format_json:
+ exitcode = !convert_sudoers_json(&parsed_policy, output_file, conf);
+ break;
+ case format_ldif:
+ exitcode = !convert_sudoers_ldif(&parsed_policy, output_file, conf);
+ break;
+ case format_sudoers:
+ exitcode = !convert_sudoers_sudoers(&parsed_policy, output_file, conf);
+ break;
+ default:
+ sudo_fatalx("error: unhandled output format %d", output_format);
+ }
+
+done:
+ cvtsudoers_conf_free(conf);
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);
+ return exitcode;
+}
+
+/*
+ * cvtsudoers configuration data.
+ */
+static struct cvtsudoers_config cvtsudoers_config = INITIAL_CONFIG;
+static struct cvtsudoers_conf_table cvtsudoers_conf_vars[] = {
+ { "order_start", CONF_UINT, &cvtsudoers_config.sudo_order },
+ { "order_increment", CONF_UINT, &cvtsudoers_config.order_increment },
+ { "order_padding", CONF_UINT, &cvtsudoers_config.order_padding },
+ { "sudoers_base", CONF_STR, &cvtsudoers_config.sudoers_base },
+ { "input_format", CONF_STR, &cvtsudoers_config.input_format },
+ { "output_format", CONF_STR, &cvtsudoers_config.output_format },
+ { "match", CONF_STR, &cvtsudoers_config.filter },
+ { "defaults", CONF_STR, &cvtsudoers_config.defstr },
+ { "suppress", CONF_STR, &cvtsudoers_config.supstr },
+ { "expand_aliases", CONF_BOOL, &cvtsudoers_config.expand_aliases },
+ { "prune_matches", CONF_BOOL, &cvtsudoers_config.prune_matches }
+};
+
+/*
+ * Look up keyword in config table.
+ * Returns true if found, else false.
+ */
+static bool
+cvtsudoers_parse_keyword(const char *conf_file, const char *keyword,
+ const char *value, struct cvtsudoers_conf_table *table)
+{
+ struct cvtsudoers_conf_table *cur;
+ const char *errstr;
+ debug_decl(sudo_ldap_parse_keyword, SUDOERS_DEBUG_UTIL)
+
+ /* Look up keyword in config tables */
+ for (cur = table; cur->conf_str != NULL; cur++) {
+ if (strcasecmp(keyword, cur->conf_str) == 0) {
+ switch (cur->type) {
+ case CONF_BOOL:
+ *(bool *)(cur->valp) = sudo_strtobool(value) == true;
+ break;
+ case CONF_UINT:
+ {
+ unsigned int uval =
+ strtonum(value, 0, UINT_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("%s: %s: %s: %s"),
+ conf_file, keyword, value, U_(errstr));
+ continue;
+ }
+ *(unsigned int *)(cur->valp) = uval;
+ }
+ break;
+ case CONF_STR:
+ {
+ char *cp = strdup(value);
+ if (cp == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ free(*(char **)(cur->valp));
+ *(char **)(cur->valp) = cp;
+ break;
+ }
+ }
+ debug_return_bool(true);
+ }
+ }
+ debug_return_bool(false);
+}
+
+static struct cvtsudoers_config *
+cvtsudoers_conf_read(const char *conf_file)
+{
+ char *line = NULL;
+ size_t linesize = 0;
+ FILE *fp;
+ debug_decl(cvtsudoers_conf_read, SUDOERS_DEBUG_UTIL)
+
+ if ((fp = fopen(conf_file, "r")) == NULL)
+ debug_return_ptr(&cvtsudoers_config);
+
+ while (sudo_parseln(&line, &linesize, NULL, fp, 0) != -1) {
+ char *cp, *keyword, *value;
+
+ if (*line == '\0')
+ continue; /* skip empty line */
+
+ /* Parse keyword = value */
+ keyword = line;
+ if ((cp = strchr(line, '=')) == NULL)
+ continue;
+ value = cp-- + 1;
+
+ /* Trim whitespace after keyword. */
+ while (cp != line && isblank((unsigned char)cp[-1]))
+ cp--;
+ *cp = '\0';
+
+ /* Trim whitespace before value. */
+ while (isblank((unsigned char)*value))
+ value++;
+
+ /* Look up keyword in config tables */
+ if (!cvtsudoers_parse_keyword(conf_file, keyword, value, cvtsudoers_conf_vars))
+ sudo_warnx(U_("%s: unknown key word: %s"), conf_file, keyword);
+ }
+ free(line);
+ fclose(fp);
+
+ debug_return_ptr(&cvtsudoers_config);
+}
+
+static void
+cvtsudoers_conf_free(struct cvtsudoers_config *conf)
+{
+ debug_decl(cvtsudoers_conf_free, SUDOERS_DEBUG_UTIL)
+
+ if (conf != NULL) {
+ free(conf->sudoers_base);
+ free(conf->input_format);
+ free(conf->output_format);
+ conf->sudoers_base = NULL;
+ conf->input_format = NULL;
+ conf->output_format = NULL;
+ }
+
+ debug_return;
+}
+
+static int
+cvtsudoers_parse_defaults(char *expression)
+{
+ char *last, *cp = expression;
+ int flags = 0;
+ debug_decl(cvtsudoers_parse_defaults, SUDOERS_DEBUG_UTIL)
+
+ for ((cp = strtok_r(cp, ",", &last)); cp != NULL; (cp = strtok_r(NULL, ",", &last))) {
+ if (strcasecmp(cp, "all") == 0) {
+ SET(flags, CVT_DEFAULTS_ALL);
+ } else if (strcasecmp(cp, "global") == 0) {
+ SET(flags, CVT_DEFAULTS_GLOBAL);
+ } else if (strcasecmp(cp, "user") == 0) {
+ SET(flags, CVT_DEFAULTS_USER);
+ } else if (strcasecmp(cp, "runas") == 0) {
+ SET(flags, CVT_DEFAULTS_RUNAS);
+ } else if (strcasecmp(cp, "host") == 0) {
+ SET(flags, CVT_DEFAULTS_HOST);
+ } else if (strcasecmp(cp, "command") == 0) {
+ SET(flags, CVT_DEFAULTS_CMND);
+ } else {
+ sudo_warnx(U_("invalid defaults type: %s"), cp);
+ debug_return_int(-1);
+ }
+ }
+
+ debug_return_int(flags);
+}
+
+static int
+cvtsudoers_parse_suppression(char *expression)
+{
+ char *last, *cp = expression;
+ int flags = 0;
+ debug_decl(cvtsudoers_parse_suppression, SUDOERS_DEBUG_UTIL)
+
+ for ((cp = strtok_r(cp, ",", &last)); cp != NULL; (cp = strtok_r(NULL, ",", &last))) {
+ if (strcasecmp(cp, "defaults") == 0) {
+ SET(flags, SUPPRESS_DEFAULTS);
+ } else if (strcasecmp(cp, "aliases") == 0) {
+ SET(flags, SUPPRESS_ALIASES);
+ } else if (strcasecmp(cp, "privileges") == 0 || strcasecmp(cp, "privs") == 0) {
+ SET(flags, SUPPRESS_PRIVS);
+ } else {
+ sudo_warnx(U_("invalid suppression type: %s"), cp);
+ debug_return_int(-1);
+ }
+ }
+
+ debug_return_int(flags);
+}
+
+static bool
+cvtsudoers_parse_filter(char *expression)
+{
+ char *last, *cp = expression;
+ debug_decl(cvtsudoers_parse_filter, SUDOERS_DEBUG_UTIL)
+
+ if (filters == NULL) {
+ if ((filters = malloc(sizeof(*filters))) == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ STAILQ_INIT(&filters->users);
+ STAILQ_INIT(&filters->groups);
+ STAILQ_INIT(&filters->hosts);
+ }
+
+ for ((cp = strtok_r(cp, ",", &last)); cp != NULL; (cp = strtok_r(NULL, ",", &last))) {
+ /*
+ * Filter expression:
+ * user=foo,group=bar,host=baz
+ */
+ char *keyword;
+ struct sudoers_string *s;
+
+ if ((s = malloc(sizeof(*s))) == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+
+ /* Parse keyword = value */
+ keyword = cp;
+ if ((cp = strchr(cp, '=')) == NULL) {
+ sudo_warnx(U_("invalid filter: %s"), keyword);;
+ free(s);
+ debug_return_bool(false);
+ }
+ *cp++ = '\0';
+ s->str = cp;
+
+ if (strcmp(keyword, "user") == 0 ){
+ STAILQ_INSERT_TAIL(&filters->users, s, entries);
+ } else if (strcmp(keyword, "group") == 0 ){
+ STAILQ_INSERT_TAIL(&filters->groups, s, entries);
+ } else if (strcmp(keyword, "host") == 0 ){
+ STAILQ_INSERT_TAIL(&filters->hosts, s, entries);
+ } else {
+ sudo_warnx(U_("invalid filter: %s"), keyword);;
+ free(s);
+ debug_return_bool(false);
+ }
+ }
+
+ debug_return_bool(true);
+}
+
+static bool
+parse_ldif(struct sudoers_parse_tree *parse_tree, const char *input_file,
+ struct cvtsudoers_config *conf)
+{
+ FILE *fp = stdin;
+ debug_decl(parse_ldif, SUDOERS_DEBUG_UTIL)
+
+ /* Open LDIF file and parse it. */
+ if (strcmp(input_file, "-") != 0) {
+ if ((fp = fopen(input_file, "r")) == NULL)
+ sudo_fatal(U_("unable to open %s"), input_file);
+ }
+
+ debug_return_bool(sudoers_parse_ldif(parse_tree, fp, conf->sudoers_base,
+ conf->store_options));
+}
+
+static bool
+parse_sudoers(const char *input_file, struct cvtsudoers_config *conf)
+{
+ debug_decl(parse_sudoers, SUDOERS_DEBUG_UTIL)
+
+ /* Open sudoers file and parse it. */
+ if (strcmp(input_file, "-") == 0) {
+ sudoersin = stdin;
+ input_file = "stdin";
+ } else if ((sudoersin = fopen(input_file, "r")) == NULL)
+ sudo_fatal(U_("unable to open %s"), input_file);
+ init_parser(input_file, false);
+ if (sudoersparse() && !parse_error) {
+ sudo_warnx(U_("failed to parse %s file, unknown error"), input_file);
+ parse_error = true;
+ rcstr_delref(errorfile);
+ if ((errorfile = rcstr_dup(input_file)) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ }
+ if (parse_error) {
+ if (errorlineno != -1)
+ sudo_warnx(U_("parse error in %s near line %d\n"),
+ errorfile, errorlineno);
+ else if (errorfile != NULL)
+ sudo_warnx(U_("parse error in %s\n"), errorfile);
+ debug_return_bool(false);
+ }
+ debug_return_bool(true);
+}
+
+FILE *
+open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
+{
+ return fopen(sudoers, "r");
+}
+
+static bool
+userlist_matches_filter(struct sudoers_parse_tree *parse_tree,
+ struct member_list *users, struct cvtsudoers_config *conf)
+{
+ struct sudoers_string *s;
+ struct member *m, *next;
+ bool ret = false;
+ debug_decl(userlist_matches_filter, SUDOERS_DEBUG_UTIL)
+
+ if (filters == NULL ||
+ (STAILQ_EMPTY(&filters->users) && STAILQ_EMPTY(&filters->groups)))
+ debug_return_bool(true);
+
+ TAILQ_FOREACH_REVERSE_SAFE(m, users, member_list, entries, next) {
+ bool matched = false;
+
+ if (STAILQ_EMPTY(&filters->users)) {
+ struct passwd pw;
+
+ /*
+ * Only groups in filter, make a dummy user so userlist_matches()
+ * can do its thing.
+ */
+ memset(&pw, 0, sizeof(pw));
+ pw.pw_name = "_nobody";
+ pw.pw_uid = (uid_t)-1;
+ pw.pw_gid = (gid_t)-1;
+
+ if (user_matches(parse_tree, &pw, m) == true)
+ matched = true;
+ } else {
+ STAILQ_FOREACH(s, &filters->users, entries) {
+ struct passwd *pw = NULL;
+
+ /* An upper case filter entry may be a User_Alias */
+ /* XXX - doesn't handle nested aliases */
+ if (m->type == ALIAS && !conf->expand_aliases) {
+ if (strcmp(m->name, s->str) == 0) {
+ matched = true;
+ break;
+ }
+ }
+
+ if (s->str[0] == '#') {
+ const char *errstr;
+ uid_t uid = sudo_strtoid(s->str + 1, NULL, NULL, &errstr);
+ if (errstr == NULL)
+ pw = sudo_getpwuid(uid);
+ }
+ if (pw == NULL)
+ pw = sudo_getpwnam(s->str);
+ if (pw == NULL)
+ continue;
+
+ if (user_matches(parse_tree, pw, m) == true)
+ matched = true;
+ sudo_pw_delref(pw);
+
+ /* Only need one user in the filter to match. */
+ if (matched)
+ break;
+ }
+ }
+
+ if (matched) {
+ ret = true;
+ } else if (conf->prune_matches) {
+ TAILQ_REMOVE(users, m, entries);
+ free_member(m);
+ }
+ }
+
+ debug_return_bool(ret);
+}
+
+static bool
+hostlist_matches_filter(struct sudoers_parse_tree *parse_tree,
+ struct member_list *hostlist, struct cvtsudoers_config *conf)
+{
+ struct sudoers_string *s;
+ struct member *m, *next;
+ char *lhost, *shost;
+ bool ret = false;
+ char **shosts;
+ int n = 0;
+ debug_decl(hostlist_matches_filter, SUDOERS_DEBUG_UTIL)
+
+ if (filters == NULL || STAILQ_EMPTY(&filters->hosts))
+ debug_return_bool(true);
+
+ /* Create an array of short host names. */
+ STAILQ_FOREACH(s, &filters->hosts, entries) {
+ n++;
+ }
+ shosts = reallocarray(NULL, n, sizeof(char *));
+ if (shosts == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ n = 0;
+ STAILQ_FOREACH(s, &filters->hosts, entries) {
+ lhost = s->str;
+ if ((shost = strchr(lhost, '.')) != NULL) {
+ shost = strndup(lhost, (size_t)(shost - lhost));
+ if (shost == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ } else {
+ shost = lhost;
+ }
+ shosts[n++] = shost;
+ }
+
+ TAILQ_FOREACH_REVERSE_SAFE(m, hostlist, member_list, entries, next) {
+ bool matched = false;
+ n = 0;
+ STAILQ_FOREACH(s, &filters->hosts, entries) {
+ lhost = s->str;
+ shost = shosts[n++];
+
+ /* An upper case filter entry may be a Host_Alias */
+ /* XXX - doesn't handle nested aliases */
+ if (m->type == ALIAS && !conf->expand_aliases) {
+ if (strcmp(m->name, s->str) == 0) {
+ matched = true;
+ break;
+ }
+ }
+
+ /* Only need one host in the filter to match. */
+ /* XXX - can't use netgroup_tuple with NULL pw */
+ if (host_matches(parse_tree, NULL, lhost, shost, m) == true) {
+ matched = true;
+ break;
+ }
+ }
+
+ if (matched) {
+ ret = true;
+ } else if (conf->prune_matches) {
+ TAILQ_REMOVE(hostlist, m, entries);
+ free_member(m);
+ }
+ }
+
+ /* Free shosts array and its contents. */
+ n = 0;
+ STAILQ_FOREACH(s, &filters->hosts, entries) {
+ lhost = s->str;
+ shost = shosts[n++];
+ if (shost != lhost)
+ free(shost);
+ }
+ free(shosts);
+
+ debug_return_bool(ret == true);
+}
+
+/*
+ * Display Defaults entries
+ */
+static bool
+print_defaults_sudoers(struct sudoers_parse_tree *parse_tree,
+ struct sudo_lbuf *lbuf, bool expand_aliases)
+{
+ struct defaults *def, *next;
+ debug_decl(print_defaults_sudoers, SUDOERS_DEBUG_UTIL)
+
+ TAILQ_FOREACH_SAFE(def, &parse_tree->defaults, entries, next) {
+ sudoers_format_default_line(lbuf, parse_tree, def, &next,
+ expand_aliases);
+ }
+
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+static int
+print_alias_sudoers(struct sudoers_parse_tree *parse_tree, struct alias *a,
+ void *v)
+{
+ struct sudo_lbuf *lbuf = v;
+ struct member *m;
+ debug_decl(print_alias_sudoers, SUDOERS_DEBUG_UTIL)
+
+ sudo_lbuf_append(lbuf, "%s %s = ", alias_type_to_string(a->type),
+ a->name);
+ TAILQ_FOREACH(m, &a->members, entries) {
+ if (m != TAILQ_FIRST(&a->members))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, parse_tree, m, NULL, UNSPEC);
+ }
+ sudo_lbuf_append(lbuf, "\n");
+
+ debug_return_int(sudo_lbuf_error(lbuf) ? -1 : 0);
+}
+
+/*
+ * Display aliases
+ */
+static bool
+print_aliases_sudoers(struct sudoers_parse_tree *parse_tree,
+ struct sudo_lbuf *lbuf)
+{
+ debug_decl(print_aliases_sudoers, SUDOERS_DEBUG_UTIL)
+
+ alias_apply(parse_tree, print_alias_sudoers, lbuf);
+
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+static FILE *output_fp; /* global for convert_sudoers_output */
+
+static int
+convert_sudoers_output(const char *buf)
+{
+ return fputs(buf, output_fp);
+}
+
+/*
+ * Apply filters to userspecs, removing non-matching entries.
+ */
+static void
+filter_userspecs(struct sudoers_parse_tree *parse_tree,
+ struct cvtsudoers_config *conf)
+{
+ struct userspec *us, *next_us;
+ struct privilege *priv, *next_priv;
+ debug_decl(filter_userspecs, SUDOERS_DEBUG_UTIL)
+
+ if (filters == NULL)
+ debug_return;
+
+ /*
+ * Does not currently prune out non-matching entries in the user or
+ * host lists. It acts more like a grep than a true filter.
+ * In the future, we may want to add a prune option.
+ */
+ TAILQ_FOREACH_SAFE(us, &parse_tree->userspecs, entries, next_us) {
+ if (!userlist_matches_filter(parse_tree, &us->users, conf)) {
+ TAILQ_REMOVE(&parse_tree->userspecs, us, entries);
+ free_userspec(us);
+ continue;
+ }
+ TAILQ_FOREACH_SAFE(priv, &us->privileges, entries, next_priv) {
+ if (!hostlist_matches_filter(parse_tree, &priv->hostlist, conf)) {
+ TAILQ_REMOVE(&us->privileges, priv, entries);
+ free_privilege(priv);
+ }
+ }
+ if (TAILQ_EMPTY(&us->privileges)) {
+ TAILQ_REMOVE(&parse_tree->userspecs, us, entries);
+ free_userspec(us);
+ continue;
+ }
+ }
+ debug_return;
+}
+
+/*
+ * Check whether the alias described by "alias_name" is the same
+ * as "name" or includes an alias called "name".
+ * Returns true if matched, else false.
+ */
+static bool
+alias_matches(struct sudoers_parse_tree *parse_tree, const char *name,
+ const char *alias_name, int alias_type)
+{
+ struct alias *a;
+ struct member *m;
+ bool ret = false;
+ debug_decl(alias_matches, SUDOERS_DEBUG_ALIAS)
+
+ if (strcmp(name, alias_name) == 0)
+ debug_return_bool(true);
+
+ a = alias_get(parse_tree, alias_name, alias_type);
+ if (a != NULL) {
+ TAILQ_FOREACH(m, &a->members, entries) {
+ if (m->type != ALIAS)
+ continue;
+ if (alias_matches(parse_tree, name, m->name, alias_type)) {
+ ret = true;
+ break;
+ }
+ }
+ alias_put(a);
+ }
+
+ debug_return_bool(ret);
+}
+
+/*
+ * Check whether userspecs uses the aliases in the specified member lists.
+ * If used, they are removed (and freed) from the list.
+ * This does *not* check Defaults for used aliases, only userspecs.
+ */
+static void
+alias_used_by_userspecs(struct sudoers_parse_tree *parse_tree,
+ struct member_list *user_aliases, struct member_list *runas_aliases,
+ struct member_list *host_aliases, struct member_list *cmnd_aliases)
+{
+ struct privilege *priv, *priv_next;
+ struct userspec *us, *us_next;
+ struct cmndspec *cs, *cs_next;
+ struct member *m, *m_next;
+ struct member *am, *am_next;
+ debug_decl(alias_used_by_userspecs, SUDOERS_DEBUG_ALIAS)
+
+ /* Iterate over the policy, checking for aliases. */
+ TAILQ_FOREACH_SAFE(us, &parse_tree->userspecs, entries, us_next) {
+ TAILQ_FOREACH_SAFE(m, &us->users, entries, m_next) {
+ if (m->type == ALIAS) {
+ /* If alias is used, remove from user_aliases and free. */
+ TAILQ_FOREACH_SAFE(am, user_aliases, entries, am_next) {
+ if (alias_matches(parse_tree, am->name, m->name, USERALIAS)) {
+ TAILQ_REMOVE(user_aliases, am, entries);
+ free_member(am);
+ }
+ }
+ }
+ }
+ TAILQ_FOREACH_SAFE(priv, &us->privileges, entries, priv_next) {
+ TAILQ_FOREACH(m, &priv->hostlist, entries) {
+ if (m->type == ALIAS) {
+ /* If alias is used, remove from host_aliases and free. */
+ TAILQ_FOREACH_SAFE(am, host_aliases, entries, am_next) {
+ if (alias_matches(parse_tree, am->name, m->name, HOSTALIAS)) {
+ TAILQ_REMOVE(host_aliases, am, entries);
+ free_member(am);
+ }
+ }
+ }
+ }
+ TAILQ_FOREACH_SAFE(cs, &priv->cmndlist, entries, cs_next) {
+ if (cs->runasuserlist != NULL) {
+ TAILQ_FOREACH_SAFE(m, cs->runasuserlist, entries, m_next) {
+ if (m->type == ALIAS) {
+ /* If alias is used, remove from runas_aliases and free. */
+ TAILQ_FOREACH_SAFE(am, runas_aliases, entries, am_next) {
+ if (alias_matches(parse_tree, am->name, m->name, RUNASALIAS)) {
+ TAILQ_REMOVE(runas_aliases, am, entries);
+ free_member(am);
+ }
+ }
+ }
+ }
+ }
+ if (cs->runasgrouplist != NULL) {
+ TAILQ_FOREACH_SAFE(m, cs->runasgrouplist, entries, m_next) {
+ if (m->type == ALIAS) {
+ /* If alias is used, remove from runas_aliases and free. */
+ TAILQ_FOREACH_SAFE(am, runas_aliases, entries, am_next) {
+ if (alias_matches(parse_tree, am->name, m->name, RUNASALIAS)) {
+ TAILQ_REMOVE(runas_aliases, am, entries);
+ free_member(am);
+ }
+ }
+ }
+ }
+ }
+ if ((m = cs->cmnd)->type == ALIAS) {
+ /* If alias is used, remove from cmnd_aliases and free. */
+ TAILQ_FOREACH_SAFE(am, cmnd_aliases, entries, am_next) {
+ if (alias_matches(parse_tree, am->name, m->name, CMNDALIAS)) {
+ TAILQ_REMOVE(cmnd_aliases, am, entries);
+ free_member(am);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ debug_return;
+}
+
+/*
+ * Apply filters to host/user-based Defaults, removing non-matching entries.
+ */
+static void
+filter_defaults(struct sudoers_parse_tree *parse_tree,
+ struct cvtsudoers_config *conf)
+{
+ struct member_list user_aliases = TAILQ_HEAD_INITIALIZER(user_aliases);
+ struct member_list runas_aliases = TAILQ_HEAD_INITIALIZER(runas_aliases);
+ struct member_list host_aliases = TAILQ_HEAD_INITIALIZER(host_aliases);
+ struct member_list cmnd_aliases = TAILQ_HEAD_INITIALIZER(cmnd_aliases);
+ struct member_list *prev_binding = NULL;
+ struct defaults *def, *def_next;
+ struct member *m, *m_next;
+ struct alias *a;
+ int alias_type;
+ debug_decl(filter_defaults, SUDOERS_DEBUG_DEFAULTS)
+
+ if (filters == NULL && conf->defaults == CVT_DEFAULTS_ALL)
+ debug_return;
+
+ TAILQ_FOREACH_SAFE(def, &parse_tree->defaults, entries, def_next) {
+ bool keep = true;
+
+ switch (def->type) {
+ case DEFAULTS:
+ if (!ISSET(conf->defaults, CVT_DEFAULTS_GLOBAL))
+ keep = false;
+ alias_type = UNSPEC;
+ break;
+ case DEFAULTS_USER:
+ if (!ISSET(conf->defaults, CVT_DEFAULTS_USER) ||
+ !userlist_matches_filter(parse_tree, def->binding, conf))
+ keep = false;
+ alias_type = USERALIAS;
+ break;
+ case DEFAULTS_RUNAS:
+ if (!ISSET(conf->defaults, CVT_DEFAULTS_RUNAS))
+ keep = false;
+ alias_type = RUNASALIAS;
+ break;
+ case DEFAULTS_HOST:
+ if (!ISSET(conf->defaults, CVT_DEFAULTS_HOST) ||
+ !hostlist_matches_filter(parse_tree, def->binding, conf))
+ keep = false;
+ alias_type = HOSTALIAS;
+ break;
+ case DEFAULTS_CMND:
+ if (!ISSET(conf->defaults, CVT_DEFAULTS_CMND))
+ keep = false;
+ alias_type = CMNDALIAS;
+ break;
+ default:
+ sudo_fatalx_nodebug("unexpected defaults type %d", def->type);
+ break;
+ }
+
+ if (!keep) {
+ /* Look for aliases used by the binding. */
+ /* XXX - move to function */
+ if (alias_type != UNSPEC && def->binding != prev_binding) {
+ TAILQ_FOREACH_SAFE(m, def->binding, entries, m_next) {
+ if (m->type == ALIAS) {
+ TAILQ_REMOVE(def->binding, m, entries);
+ switch (alias_type) {
+ case USERALIAS:
+ TAILQ_INSERT_TAIL(&user_aliases, m, entries);
+ break;
+ case RUNASALIAS:
+ TAILQ_INSERT_TAIL(&runas_aliases, m, entries);
+ break;
+ case HOSTALIAS:
+ TAILQ_INSERT_TAIL(&host_aliases, m, entries);
+ break;
+ case CMNDALIAS:
+ TAILQ_INSERT_TAIL(&cmnd_aliases, m, entries);
+ break;
+ default:
+ sudo_fatalx_nodebug("unexpected alias type %d",
+ alias_type);
+ break;
+ }
+ }
+ }
+ }
+ TAILQ_REMOVE(&parse_tree->defaults, def, entries);
+ free_default(def, &prev_binding);
+ if (prev_binding != NULL) {
+ /* Remove and free Defaults that share the same binding. */
+ while (def_next != NULL && def_next->binding == prev_binding) {
+ def = def_next;
+ def_next = TAILQ_NEXT(def, entries);
+ TAILQ_REMOVE(&parse_tree->defaults, def, entries);
+ free_default(def, &prev_binding);
+ }
+ }
+ } else {
+ prev_binding = def->binding;
+ }
+ }
+
+ /* Remove now-unreferenced aliases. */
+ alias_used_by_userspecs(parse_tree, &user_aliases, &runas_aliases,
+ &host_aliases, &cmnd_aliases);
+ TAILQ_FOREACH_SAFE(m, &user_aliases, entries, m_next) {
+ a = alias_remove(parse_tree, m->name, USERALIAS);
+ alias_free(a);
+ free_member(m);
+ }
+ TAILQ_FOREACH_SAFE(m, &runas_aliases, entries, m_next) {
+ a = alias_remove(parse_tree, m->name, RUNASALIAS);
+ alias_free(a);
+ free_member(m);
+ }
+ TAILQ_FOREACH_SAFE(m, &host_aliases, entries, m_next) {
+ a = alias_remove(parse_tree, m->name, HOSTALIAS);
+ alias_free(a);
+ free_member(m);
+ }
+ TAILQ_FOREACH_SAFE(m, &cmnd_aliases, entries, m_next) {
+ a = alias_remove(parse_tree, m->name, CMNDALIAS);
+ alias_free(a);
+ free_member(m);
+ }
+
+ debug_return;
+}
+
+/*
+ * Remove unreferenced aliases.
+ */
+static void
+alias_remove_unused(struct sudoers_parse_tree *parse_tree)
+{
+ struct rbtree *used_aliases;
+ debug_decl(alias_remove_unused, SUDOERS_DEBUG_ALIAS)
+
+ used_aliases = alloc_aliases();
+ if (used_aliases == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+ /* Move all referenced aliases to used_aliases. */
+ if (!alias_find_used(parse_tree, used_aliases))
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+ /* Only unreferenced aliases are left, swap and free the unused ones. */
+ free_aliases(parse_tree->aliases);
+ parse_tree->aliases = used_aliases;
+
+ debug_return;
+}
+
+/*
+ * Prune out non-matching entries from user and host aliases.
+ */
+static int
+alias_prune_helper(struct sudoers_parse_tree *parse_tree, struct alias *a,
+ void *v)
+{
+ struct cvtsudoers_config *conf = v;
+
+ /* XXX - misue of these functions */
+ switch (a->type) {
+ case USERALIAS:
+ userlist_matches_filter(parse_tree, &a->members, conf);
+ break;
+ case HOSTALIAS:
+ hostlist_matches_filter(parse_tree, &a->members, conf);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * Prune out non-matching entries from within aliases.
+ */
+static void
+alias_prune(struct sudoers_parse_tree *parse_tree,
+ struct cvtsudoers_config *conf)
+{
+ debug_decl(alias_prune, SUDOERS_DEBUG_ALIAS)
+
+ alias_apply(parse_tree, alias_prune_helper, conf);
+
+ debug_return;
+}
+
+/*
+ * Convert back to sudoers.
+ */
+static bool
+convert_sudoers_sudoers(struct sudoers_parse_tree *parse_tree,
+ const char *output_file, struct cvtsudoers_config *conf)
+{
+ bool ret = true;
+ struct sudo_lbuf lbuf;
+ debug_decl(convert_sudoers_sudoers, SUDOERS_DEBUG_UTIL)
+
+ if (strcmp(output_file, "-") == 0) {
+ output_fp = stdout;
+ } else {
+ if ((output_fp = fopen(output_file, "w")) == NULL)
+ sudo_fatal(U_("unable to open %s"), output_file);
+ }
+
+ /* Wrap lines at 80 columns with a 4 character indent. */
+ sudo_lbuf_init(&lbuf, convert_sudoers_output, 4, "\\", 80);
+
+ /* Print Defaults */
+ if (!ISSET(conf->suppress, SUPPRESS_DEFAULTS)) {
+ if (!print_defaults_sudoers(parse_tree, &lbuf, conf->expand_aliases))
+ goto done;
+ if (lbuf.len > 0) {
+ sudo_lbuf_print(&lbuf);
+ sudo_lbuf_append(&lbuf, "\n");
+ }
+ }
+
+ /* Print Aliases */
+ if (!conf->expand_aliases && !ISSET(conf->suppress, SUPPRESS_ALIASES)) {
+ if (!print_aliases_sudoers(parse_tree, &lbuf))
+ goto done;
+ if (lbuf.len > 1) {
+ sudo_lbuf_print(&lbuf);
+ sudo_lbuf_append(&lbuf, "\n");
+ }
+ }
+
+ /* Print User_Specs, separated by blank lines. */
+ if (!ISSET(conf->suppress, SUPPRESS_PRIVS)) {
+ if (!sudoers_format_userspecs(&lbuf, parse_tree, "\n",
+ conf->expand_aliases, true)) {
+ goto done;
+ }
+ if (lbuf.len > 1) {
+ sudo_lbuf_print(&lbuf);
+ }
+ }
+
+done:
+ if (sudo_lbuf_error(&lbuf)) {
+ if (errno == ENOMEM)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ ret = false;
+ }
+ sudo_lbuf_destroy(&lbuf);
+
+ (void)fflush(output_fp);
+ if (ferror(output_fp)) {
+ sudo_warn(U_("unable to write to %s"), output_file);
+ ret = false;
+ }
+ if (output_fp != stdout)
+ fclose(output_fp);
+
+ debug_return_bool(ret);
+}
+
+static void
+usage(int fatal)
+{
+ (void) fprintf(fatal ? stderr : stdout, "usage: %s [-ehMpV] [-b dn] "
+ "[-c conf_file ] [-d deftypes] [-f output_format] [-i input_format] "
+ "[-I increment] [-m filter] [-o output_file] [-O start_point] "
+ "[-P padding] [-s sections] [input_file]\n", getprogname());
+ if (fatal)
+ exit(1);
+}
+
+static void
+help(void)
+{
+ (void) printf(_("%s - convert between sudoers file formats\n\n"), getprogname());
+ usage(0);
+ (void) puts(_("\nOptions:\n"
+ " -b, --base=dn the base DN for sudo LDAP queries\n"
+ " -c, --config=conf_file the path to the configuration file\n"
+ " -d, --defaults=deftypes only convert Defaults of the specified types\n"
+ " -e, --expand-aliases expand aliases when converting\n"
+ " -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+ " -i, --input-format=format set input format: LDIF or sudoers\n"
+ " -I, --increment=num amount to increase each sudoOrder by\n"
+ " -h, --help display help message and exit\n"
+ " -m, --match=filter only convert entries that match the filter\n"
+ " -M, --match-local match filter uses passwd and group databases\n"
+ " -o, --output=output_file write converted sudoers to output_file\n"
+ " -O, --order-start=num starting point for first sudoOrder\n"
+ " -p, --prune-matches prune non-matching users, groups and hosts\n"
+ " -P, --padding=num base padding for sudoOrder increment\n"
+ " -s, --suppress=sections suppress output of certain sections\n"
+ " -V, --version display version information and exit"));
+ exit(0);
+}
diff --git a/plugins/sudoers/cvtsudoers.h b/plugins/sudoers/cvtsudoers.h
new file mode 100644
index 0000000..b93474b
--- /dev/null
+++ b/plugins/sudoers/cvtsudoers.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_CVTSUDOERS_H
+#define SUDOERS_CVTSUDOERS_H
+
+#include "strlist.h"
+
+/* Supported input/output formats. */
+enum sudoers_formats {
+ format_json,
+ format_ldif,
+ format_sudoers
+};
+
+/* Flags for cvtsudoers_config.defaults */
+#define CVT_DEFAULTS_GLOBAL 0x01
+#define CVT_DEFAULTS_USER 0x02
+#define CVT_DEFAULTS_RUNAS 0x04
+#define CVT_DEFAULTS_HOST 0x08
+#define CVT_DEFAULTS_CMND 0x10
+#define CVT_DEFAULTS_ALL 0xff
+
+/* Flags for cvtsudoers_config.suppress */
+#define SUPPRESS_DEFAULTS 0x01
+#define SUPPRESS_ALIASES 0x02
+#define SUPPRESS_PRIVS 0x04
+
+/* cvtsudoers.conf settings */
+struct cvtsudoers_config {
+ unsigned int sudo_order;
+ unsigned int order_increment;
+ unsigned int order_padding;
+ unsigned int order_max;
+ short defaults;
+ short suppress;
+ bool expand_aliases;
+ bool store_options;
+ bool prune_matches;
+ char *sudoers_base;
+ char *input_format;
+ char *output_format;
+ char *filter;
+ char *defstr;
+ char *supstr;
+};
+
+/* Initial config settings for above. */
+#define INITIAL_CONFIG { 1, 1, 0, 0, CVT_DEFAULTS_ALL, 0, false, true, false }
+
+#define CONF_BOOL 0
+#define CONF_UINT 1
+#define CONF_STR 2
+
+struct cvtsudoers_conf_table {
+ const char *conf_str; /* config file string */
+ int type; /* CONF_BOOL, CONF_UINT, CONF_STR */
+ void *valp; /* pointer into cvtsudoers_config */
+};
+
+struct cvtsudoers_filter {
+ struct sudoers_str_list users;
+ struct sudoers_str_list groups;
+ struct sudoers_str_list hosts;
+};
+
+/* cvtsudoers.c */
+extern struct cvtsudoers_filter *filters;
+
+/* cvtsudoers_json.c */
+bool convert_sudoers_json(struct sudoers_parse_tree *parse_tree, const char *output_file, struct cvtsudoers_config *conf);
+
+/* cvtsudoers_ldif.c */
+bool convert_sudoers_ldif(struct sudoers_parse_tree *parse_tree, const char *output_file, struct cvtsudoers_config *conf);
+
+/* cvtsudoers_pwutil.c */
+struct cache_item *cvtsudoers_make_pwitem(uid_t uid, const char *name);
+struct cache_item *cvtsudoers_make_gritem(gid_t gid, const char *name);
+struct cache_item *cvtsudoers_make_gidlist_item(const struct passwd *pw, char * const *unused1, unsigned int type);
+struct cache_item *cvtsudoers_make_grlist_item(const struct passwd *pw, char * const *unused1);
+
+/* stubs.c */
+void get_hostname(void);
+
+#endif /* SUDOERS_CVTSUDOERS_H */
diff --git a/plugins/sudoers/cvtsudoers_json.c b/plugins/sudoers/cvtsudoers_json.c
new file mode 100644
index 0000000..5fbef1c
--- /dev/null
+++ b/plugins/sudoers/cvtsudoers_json.c
@@ -0,0 +1,1161 @@
+/*
+ * Copyright (c) 2013-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <stdarg.h>
+#include <time.h>
+#include <ctype.h>
+
+#include "sudoers.h"
+#include "cvtsudoers.h"
+#include <gram.h>
+
+/*
+ * JSON values may be of the following types.
+ */
+enum json_value_type {
+ JSON_STRING,
+ JSON_ID,
+ JSON_NUMBER,
+ JSON_OBJECT,
+ JSON_ARRAY,
+ JSON_BOOL,
+ JSON_NULL
+};
+
+/*
+ * JSON value suitable for printing.
+ * Note: this does not support object or array values.
+ */
+struct json_value {
+ enum json_value_type type;
+ union {
+ char *string;
+ int number;
+ id_t id;
+ bool boolean;
+ } u;
+};
+
+/*
+ * Closure used to store state when iterating over all aliases.
+ */
+struct json_alias_closure {
+ FILE *fp;
+ const char *title;
+ unsigned int count;
+ int alias_type;
+ int indent;
+ bool need_comma;
+};
+
+/*
+ * Type values used to disambiguate the generic WORD and ALIAS types.
+ */
+enum word_type {
+ TYPE_COMMAND,
+ TYPE_HOSTNAME,
+ TYPE_RUNASGROUP,
+ TYPE_RUNASUSER,
+ TYPE_USERNAME
+};
+
+/*
+ * Print "indent" number of blank characters.
+ */
+static void
+print_indent(FILE *fp, int indent)
+{
+ while (indent--)
+ putc(' ', fp);
+}
+
+/*
+ * Print a JSON string, escaping special characters.
+ * Does not support unicode escapes.
+ */
+static void
+print_string_json_unquoted(FILE *fp, const char *str)
+{
+ char ch;
+
+ while ((ch = *str++) != '\0') {
+ switch (ch) {
+ case '"':
+ case '\\':
+ putc('\\', fp);
+ break;
+ case '\b':
+ ch = 'b';
+ putc('\\', fp);
+ break;
+ case '\f':
+ ch = 'f';
+ putc('\\', fp);
+ break;
+ case '\n':
+ ch = 'n';
+ putc('\\', fp);
+ break;
+ case '\r':
+ ch = 'r';
+ putc('\\', fp);
+ break;
+ case '\t':
+ ch = 't';
+ putc('\\', fp);
+ break;
+ }
+ putc(ch, fp);
+ }
+}
+
+/*
+ * Print a quoted JSON string, escaping special characters.
+ * Does not support unicode escapes.
+ */
+static void
+print_string_json(FILE *fp, const char *str)
+{
+ putc('\"', fp);
+ print_string_json_unquoted(fp, str);
+ putc('\"', fp);
+}
+
+/*
+ * Print a JSON name: value pair with proper quoting and escaping.
+ */
+static void
+print_pair_json(FILE *fp, const char *pre, const char *name,
+ const struct json_value *value, const char *post, int indent)
+{
+ debug_decl(print_pair_json, SUDOERS_DEBUG_UTIL)
+
+ print_indent(fp, indent);
+
+ /* prefix */
+ if (pre != NULL)
+ fputs(pre, fp);
+
+ /* name */
+ print_string_json(fp, name);
+ putc(':', fp);
+ putc(' ', fp);
+
+ /* value */
+ switch (value->type) {
+ case JSON_STRING:
+ print_string_json(fp, value->u.string);
+ break;
+ case JSON_ID:
+ fprintf(fp, "%u", (unsigned int)value->u.id);
+ break;
+ case JSON_NUMBER:
+ fprintf(fp, "%d", value->u.number);
+ break;
+ case JSON_NULL:
+ fputs("null", fp);
+ break;
+ case JSON_BOOL:
+ fputs(value->u.boolean ? "true" : "false", fp);
+ break;
+ case JSON_OBJECT:
+ sudo_fatalx("internal error: can't print JSON_OBJECT");
+ break;
+ case JSON_ARRAY:
+ sudo_fatalx("internal error: can't print JSON_ARRAY");
+ break;
+ }
+
+ /* postfix */
+ if (post != NULL)
+ fputs(post, fp);
+
+ debug_return;
+}
+
+/*
+ * Print a JSON string with optional prefix and postfix to fp.
+ * Strings are not quoted but are escaped as per the JSON spec.
+ */
+static void
+printstr_json(FILE *fp, const char *pre, const char *str, const char *post,
+ int indent)
+{
+ debug_decl(printstr_json, SUDOERS_DEBUG_UTIL)
+
+ print_indent(fp, indent);
+ if (pre != NULL)
+ fputs(pre, fp);
+ if (str != NULL) {
+ print_string_json_unquoted(fp, str);
+ }
+ if (post != NULL)
+ fputs(post, fp);
+ debug_return;
+}
+
+/*
+ * Print sudo command member in JSON format, with specified indentation.
+ * If last_one is false, a comma will be printed before the newline
+ * that closes the object.
+ */
+static void
+print_command_json(FILE *fp, const char *name, int type, bool negated, int indent, bool last_one)
+{
+ struct sudo_command *c = (struct sudo_command *)name;
+ struct json_value value;
+ const char *digest_name;
+ debug_decl(print_command_json, SUDOERS_DEBUG_UTIL)
+
+ printstr_json(fp, "{", NULL, NULL, indent);
+ if (negated || c->digest != NULL) {
+ putc('\n', fp);
+ indent += 4;
+ } else {
+ putc(' ', fp);
+ indent = 0;
+ }
+
+ /* Print command with optional command line args. */
+ if (c->args != NULL) {
+ printstr_json(fp, "\"", "command", "\": ", indent);
+ printstr_json(fp, "\"", c->cmnd, " ", 0);
+ printstr_json(fp, NULL, c->args, "\"", 0);
+ } else {
+ value.type = JSON_STRING;
+ value.u.string = c->cmnd;
+ print_pair_json(fp, NULL, "command", &value, NULL, indent);
+ }
+
+ /* Optional digest. */
+ if (c->digest != NULL) {
+ fputs(",\n", fp);
+ digest_name = digest_type_to_name(c->digest->digest_type);
+ value.type = JSON_STRING;
+ value.u.string = c->digest->digest_str;
+ print_pair_json(fp, NULL, digest_name, &value, NULL, indent);
+ }
+
+ /* Command may be negated. */
+ if (negated) {
+ fputs(",\n", fp);
+ value.type = JSON_BOOL;
+ value.u.boolean = true;
+ print_pair_json(fp, NULL, "negated", &value, NULL, indent);
+ }
+
+ if (indent != 0) {
+ indent -= 4;
+ putc('\n', fp);
+ print_indent(fp, indent);
+ } else {
+ putc(' ', fp);
+ }
+ putc('}', fp);
+ if (!last_one)
+ putc(',', fp);
+ putc('\n', fp);
+
+ debug_return;
+}
+
+/*
+ * Map an alias type to enum word_type.
+ */
+static enum word_type
+alias_to_word_type(int alias_type)
+{
+ switch (alias_type) {
+ case CMNDALIAS:
+ return TYPE_COMMAND;
+ case HOSTALIAS:
+ return TYPE_HOSTNAME;
+ case RUNASALIAS:
+ return TYPE_RUNASUSER;
+ case USERALIAS:
+ return TYPE_USERNAME;
+ default:
+ sudo_fatalx_nodebug("unexpected alias type %d", alias_type);
+ }
+}
+
+/*
+ * Map a Defaults type to enum word_type.
+ */
+static enum word_type
+defaults_to_word_type(int defaults_type)
+{
+ switch (defaults_type) {
+ case DEFAULTS_CMND:
+ return TYPE_COMMAND;
+ case DEFAULTS_HOST:
+ return TYPE_HOSTNAME;
+ case DEFAULTS_RUNAS:
+ return TYPE_RUNASUSER;
+ case DEFAULTS_USER:
+ return TYPE_USERNAME;
+ default:
+ sudo_fatalx_nodebug("unexpected defaults type %d", defaults_type);
+ }
+}
+
+/*
+ * Print struct member in JSON format, with specified indentation.
+ * If last_one is false, a comma will be printed before the newline
+ * that closes the object.
+ */
+static void
+print_member_json_int(FILE *fp, struct sudoers_parse_tree *parse_tree,
+ char *name, int type, bool negated, enum word_type word_type,
+ bool last_one, int indent, bool expand_aliases)
+{
+ struct json_value value;
+ const char *typestr = NULL;
+ const char *errstr;
+ int alias_type = UNSPEC;
+ id_t id;
+ debug_decl(print_member_json_int, SUDOERS_DEBUG_UTIL)
+
+ /* Most of the time we print a string. */
+ value.type = JSON_STRING;
+ if (name != NULL) {
+ value.u.string = name;
+ } else {
+ switch (type) {
+ case ALL:
+ value.u.string = "ALL";
+ break;
+ case MYSELF:
+ value.u.string = "";
+ break;
+ default:
+ sudo_fatalx("missing member name for type %d", type);
+ }
+ }
+
+ switch (type) {
+ case USERGROUP:
+ value.u.string++; /* skip leading '%' */
+ if (*value.u.string == ':') {
+ value.u.string++;
+ typestr = "nonunixgroup";
+ if (*value.u.string == '#') {
+ id = sudo_strtoid(value.u.string + 1, NULL, NULL, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx("internal error: non-Unix group ID %s: \"%s\"",
+ errstr, value.u.string + 1);
+ } else {
+ value.type = JSON_ID;
+ value.u.id = id;
+ typestr = "nonunixgid";
+ }
+ }
+ } else {
+ typestr = "usergroup";
+ if (*value.u.string == '#') {
+ id = sudo_strtoid(value.u.string + 1, NULL, NULL, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx("internal error: group ID %s: \"%s\"",
+ errstr, value.u.string + 1);
+ } else {
+ value.type = JSON_ID;
+ value.u.id = id;
+ typestr = "usergid";
+ }
+ }
+ }
+ break;
+ case NETGROUP:
+ typestr = "netgroup";
+ value.u.string++; /* skip leading '+' */
+ break;
+ case NTWKADDR:
+ typestr = "networkaddr";
+ break;
+ case COMMAND:
+ print_command_json(fp, name, type, negated, indent, last_one);
+ debug_return;
+ case ALL:
+ case MYSELF:
+ case WORD:
+ switch (word_type) {
+ case TYPE_COMMAND:
+ typestr = "command";
+ break;
+ case TYPE_HOSTNAME:
+ typestr = "hostname";
+ break;
+ case TYPE_RUNASGROUP:
+ typestr = "usergroup";
+ break;
+ case TYPE_RUNASUSER:
+ case TYPE_USERNAME:
+ typestr = "username";
+ if (*value.u.string == '#') {
+ id = sudo_strtoid(value.u.string + 1, NULL, NULL, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx("internal error: user ID %s: \"%s\"",
+ errstr, name);
+ } else {
+ value.type = JSON_ID;
+ value.u.id = id;
+ typestr = "userid";
+ }
+ }
+ break;
+ default:
+ sudo_fatalx("unexpected word type %d", word_type);
+ }
+ break;
+ case ALIAS:
+ switch (word_type) {
+ case TYPE_COMMAND:
+ if (expand_aliases) {
+ alias_type = CMNDALIAS;
+ } else {
+ typestr = "cmndalias";
+ }
+ break;
+ case TYPE_HOSTNAME:
+ if (expand_aliases) {
+ alias_type = HOSTALIAS;
+ } else {
+ typestr = "hostalias";
+ }
+ break;
+ case TYPE_RUNASGROUP:
+ case TYPE_RUNASUSER:
+ if (expand_aliases) {
+ alias_type = RUNASALIAS;
+ } else {
+ typestr = "runasalias";
+ }
+ break;
+ case TYPE_USERNAME:
+ if (expand_aliases) {
+ alias_type = USERALIAS;
+ } else {
+ typestr = "useralias";
+ }
+ break;
+ default:
+ sudo_fatalx("unexpected word type %d", word_type);
+ }
+ break;
+ default:
+ sudo_fatalx("unexpected member type %d", type);
+ }
+
+ if (expand_aliases && type == ALIAS) {
+ struct alias *a;
+ struct member *m;
+
+ /* Print each member of the alias. */
+ if ((a = alias_get(parse_tree, value.u.string, alias_type)) != NULL) {
+ TAILQ_FOREACH(m, &a->members, entries) {
+ print_member_json_int(fp, parse_tree, m->name, m->type,
+ negated ? !m->negated : m->negated,
+ alias_to_word_type(alias_type),
+ last_one && TAILQ_NEXT(m, entries) == NULL, indent, true);
+ }
+ alias_put(a);
+ }
+ } else {
+ if (negated) {
+ print_indent(fp, indent);
+ fputs("{\n", fp);
+ indent += 4;
+ print_pair_json(fp, NULL, typestr, &value, ",\n", indent);
+ value.type = JSON_BOOL;
+ value.u.boolean = true;
+ print_pair_json(fp, NULL, "negated", &value, "\n", indent);
+ indent -= 4;
+ print_indent(fp, indent);
+ putc('}', fp);
+ } else {
+ print_pair_json(fp, "{ ", typestr, &value, " }", indent);
+ }
+
+ if (!last_one)
+ putc(',', fp);
+ putc('\n', fp);
+ }
+
+ debug_return;
+}
+
+static void
+print_member_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
+ struct member *m, enum word_type word_type, bool last_one,
+ int indent, bool expand_aliases)
+{
+ print_member_json_int(fp, parse_tree, m->name, m->type, m->negated,
+ word_type, last_one, indent, expand_aliases);
+}
+
+/*
+ * Callback for alias_apply() to print an alias entry if it matches
+ * the type specified in the closure.
+ */
+static int
+print_alias_json(struct sudoers_parse_tree *parse_tree, struct alias *a, void *v)
+{
+ struct json_alias_closure *closure = v;
+ struct member *m;
+ debug_decl(print_alias_json, SUDOERS_DEBUG_UTIL)
+
+ if (a->type != closure->alias_type)
+ debug_return_int(0);
+
+ /* Open the aliases object or close the last entry, then open new one. */
+ if (closure->count++ == 0) {
+ fprintf(closure->fp, "%s\n%*s\"%s\": {\n",
+ closure->need_comma ? "," : "", closure->indent, "",
+ closure->title);
+ closure->indent += 4;
+ } else {
+ fprintf(closure->fp, "%*s],\n", closure->indent, "");
+ }
+ printstr_json(closure->fp, "\"", a->name, "\": [\n", closure->indent);
+
+ closure->indent += 4;
+ TAILQ_FOREACH(m, &a->members, entries) {
+ print_member_json(closure->fp, parse_tree, m,
+ alias_to_word_type(closure->alias_type),
+ TAILQ_NEXT(m, entries) == NULL, closure->indent, false);
+ }
+ closure->indent -= 4;
+ debug_return_int(0);
+}
+
+/*
+ * Print the binding for a Defaults entry of the specified type.
+ */
+static void
+print_binding_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
+ struct member_list *binding, int type, int indent, bool expand_aliases)
+{
+ struct member *m;
+ debug_decl(print_binding_json, SUDOERS_DEBUG_UTIL)
+
+ if (TAILQ_EMPTY(binding))
+ debug_return;
+
+ fprintf(fp, "%*s\"Binding\": [\n", indent, "");
+ indent += 4;
+
+ /* Print each member object in binding. */
+ TAILQ_FOREACH(m, binding, entries) {
+ print_member_json(fp, parse_tree, m, defaults_to_word_type(type),
+ TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
+ }
+
+ indent -= 4;
+ fprintf(fp, "%*s],\n", indent, "");
+
+ debug_return;
+}
+
+/*
+ * Print a Defaults list JSON format.
+ */
+static void
+print_defaults_list_json(FILE *fp, struct defaults *def, int indent)
+{
+ char savech, *start, *end = def->val;
+ struct json_value value;
+ debug_decl(print_defaults_list_json, SUDOERS_DEBUG_UTIL)
+
+ fprintf(fp, "%*s{\n", indent, "");
+ indent += 4;
+ value.type = JSON_STRING;
+ switch (def->op) {
+ case '+':
+ value.u.string = "list_add";
+ break;
+ case '-':
+ value.u.string = "list_remove";
+ break;
+ case true:
+ value.u.string = "list_assign";
+ break;
+ default:
+ sudo_warnx("internal error: unexpected list op %d", def->op);
+ value.u.string = "unsupported";
+ break;
+ }
+ print_pair_json(fp, NULL, "operation", &value, ",\n", indent);
+ printstr_json(fp, "\"", def->var, "\": [\n", indent);
+ indent += 4;
+ print_indent(fp, indent);
+ /* Split value into multiple space-separated words. */
+ do {
+ /* Remove leading blanks, must have a non-empty string. */
+ for (start = end; isblank((unsigned char)*start); start++)
+ continue;
+ if (*start == '\0')
+ break;
+
+ /* Find the end and print it. */
+ for (end = start; *end && !isblank((unsigned char)*end); end++)
+ continue;
+ savech = *end;
+ *end = '\0';
+ print_string_json(fp, start);
+ if (savech != '\0')
+ putc(',', fp);
+ *end = savech;
+ } while (*end++ != '\0');
+ putc('\n', fp);
+ indent -= 4;
+ fprintf(fp, "%*s]\n", indent, "");
+ indent -= 4;
+ fprintf(fp, "%*s}", indent, "");
+
+ debug_return;
+}
+
+static int
+get_defaults_type(struct defaults *def)
+{
+ struct sudo_defs_types *cur;
+
+ /* Look up def in table to find its type. */
+ for (cur = sudo_defs_table; cur->name; cur++) {
+ if (strcmp(def->var, cur->name) == 0)
+ return cur->type;
+ }
+ return -1;
+}
+
+/*
+ * Export all Defaults in JSON format.
+ */
+static bool
+print_defaults_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
+ int indent, bool expand_aliases, bool need_comma)
+{
+ struct json_value value;
+ struct defaults *def, *next;
+ int type;
+ debug_decl(print_defaults_json, SUDOERS_DEBUG_UTIL)
+
+ if (TAILQ_EMPTY(&parse_tree->defaults))
+ debug_return_bool(need_comma);
+
+ fprintf(fp, "%s\n%*s\"Defaults\": [\n", need_comma ? "," : "", indent, "");
+ indent += 4;
+
+ TAILQ_FOREACH_SAFE(def, &parse_tree->defaults, entries, next) {
+ type = get_defaults_type(def);
+ if (type == -1) {
+ sudo_warnx(U_("unknown defaults entry \"%s\""), def->var);
+ /* XXX - just pass it through as a string anyway? */
+ continue;
+ }
+
+ /* Found it, print object container and binding (if any). */
+ fprintf(fp, "%*s{\n", indent, "");
+ indent += 4;
+ print_binding_json(fp, parse_tree, def->binding, def->type,
+ indent, expand_aliases);
+
+ /* Validation checks. */
+ /* XXX - validate values in addition to names? */
+
+ /* Print options, merging ones with the same binding. */
+ fprintf(fp, "%*s\"Options\": [\n", indent, "");
+ indent += 4;
+ for (;;) {
+ next = TAILQ_NEXT(def, entries);
+ /* XXX - need to update cur too */
+ if ((type & T_MASK) == T_FLAG || def->val == NULL) {
+ value.type = JSON_BOOL;
+ value.u.boolean = def->op;
+ print_pair_json(fp, "{ ", def->var, &value, " }", indent);
+ } else if ((type & T_MASK) == T_LIST) {
+ print_defaults_list_json(fp, def, indent);
+ } else {
+ value.type = JSON_STRING;
+ value.u.string = def->val;
+ print_pair_json(fp, "{ ", def->var, &value, " }", indent);
+ }
+ if (next == NULL || def->binding != next->binding)
+ break;
+ def = next;
+ type = get_defaults_type(def);
+ if (type == -1) {
+ sudo_warnx(U_("unknown defaults entry \"%s\""), def->var);
+ /* XXX - just pass it through as a string anyway? */
+ break;
+ }
+ fputs(",\n", fp);
+ }
+ putc('\n', fp);
+ indent -= 4;
+ print_indent(fp, indent);
+ fputs("]\n", fp);
+ indent -= 4;
+ print_indent(fp, indent);
+ fprintf(fp, "}%s\n", next != NULL ? "," : "");
+ }
+
+ /* Close Defaults array; comma (if any) & newline will be printer later. */
+ indent -= 4;
+ print_indent(fp, indent);
+ fputs("]", fp);
+
+ debug_return_bool(true);
+}
+
+/*
+ * Export all aliases of the specified type in JSON format.
+ * Iterates through the entire aliases tree.
+ */
+static bool
+print_aliases_by_type_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
+ int alias_type, const char *title, int indent, bool need_comma)
+{
+ struct json_alias_closure closure;
+ debug_decl(print_aliases_by_type_json, SUDOERS_DEBUG_UTIL)
+
+ closure.fp = fp;
+ closure.indent = indent;
+ closure.count = 0;
+ closure.alias_type = alias_type;
+ closure.title = title;
+ closure.need_comma = need_comma;
+ alias_apply(parse_tree, print_alias_json, &closure);
+ if (closure.count != 0) {
+ print_indent(fp, closure.indent);
+ fputs("]\n", fp);
+ closure.indent -= 4;
+ print_indent(fp, closure.indent);
+ putc('}', fp);
+ need_comma = true;
+ }
+
+ debug_return_bool(need_comma);
+}
+
+/*
+ * Export all aliases in JSON format.
+ */
+static bool
+print_aliases_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
+ int indent, bool need_comma)
+{
+ debug_decl(print_aliases_json, SUDOERS_DEBUG_UTIL)
+
+ need_comma = print_aliases_by_type_json(fp, parse_tree, USERALIAS,
+ "User_Aliases", indent, need_comma);
+ need_comma = print_aliases_by_type_json(fp, parse_tree, RUNASALIAS,
+ "Runas_Aliases", indent, need_comma);
+ need_comma = print_aliases_by_type_json(fp, parse_tree, HOSTALIAS,
+ "Host_Aliases", indent, need_comma);
+ need_comma = print_aliases_by_type_json(fp, parse_tree, CMNDALIAS,
+ "Command_Aliases", indent, need_comma);
+
+ debug_return_bool(need_comma);
+}
+
+/*
+ * Print a Cmnd_Spec in JSON format at the specified indent level.
+ * A pointer to the next Cmnd_Spec is passed in to make it possible to
+ * merge adjacent entries that are identical in all but the command.
+ */
+static void
+print_cmndspec_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
+ struct cmndspec *cs, struct cmndspec **nextp,
+ struct defaults_list *options, bool expand_aliases, int indent)
+{
+ struct cmndspec *next = *nextp;
+ struct json_value value;
+ struct defaults *def;
+ struct member *m;
+ struct tm *tp;
+ bool last_one;
+ char timebuf[sizeof("20120727121554Z")];
+ debug_decl(print_cmndspec_json, SUDOERS_DEBUG_UTIL)
+
+ /* Open Cmnd_Spec object. */
+ fprintf(fp, "%*s{\n", indent, "");
+ indent += 4;
+
+ /* Print runasuserlist */
+ if (cs->runasuserlist != NULL) {
+ fprintf(fp, "%*s\"runasusers\": [\n", indent, "");
+ indent += 4;
+ TAILQ_FOREACH(m, cs->runasuserlist, entries) {
+ print_member_json(fp, parse_tree, m, TYPE_RUNASUSER,
+ TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
+ }
+ indent -= 4;
+ fprintf(fp, "%*s],\n", indent, "");
+ }
+
+ /* Print runasgrouplist */
+ if (cs->runasgrouplist != NULL) {
+ fprintf(fp, "%*s\"runasgroups\": [\n", indent, "");
+ indent += 4;
+ TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
+ print_member_json(fp, parse_tree, m, TYPE_RUNASGROUP,
+ TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
+ }
+ indent -= 4;
+ fprintf(fp, "%*s],\n", indent, "");
+ }
+
+ /* Print options and tags */
+ if (cs->timeout > 0 || cs->notbefore != UNSPEC || cs->notafter != UNSPEC ||
+ TAGS_SET(cs->tags) || !TAILQ_EMPTY(options)) {
+ struct cmndtag tag = cs->tags;
+ const char *prefix = "\n";
+
+ fprintf(fp, "%*s\"Options\": [", indent, "");
+ indent += 4;
+ if (cs->timeout > 0) {
+ value.type = JSON_NUMBER;
+ value.u.number = cs->timeout;
+ fputs(prefix, fp);
+ print_pair_json(fp, "{ ", "command_timeout", &value, " }", indent);
+ prefix = ",\n";
+ }
+ if (cs->notbefore != UNSPEC) {
+ if ((tp = gmtime(&cs->notbefore)) == NULL) {
+ sudo_warn(U_("unable to get GMT time"));
+ } else {
+ if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tp) == 0) {
+ sudo_warnx(U_("unable to format timestamp"));
+ } else {
+ value.type = JSON_STRING;
+ value.u.string = timebuf;
+ fputs(prefix, fp);
+ print_pair_json(fp, "{ ", "notbefore", &value, " }", indent);
+ prefix = ",\n";
+ }
+ }
+ }
+ if (cs->notafter != UNSPEC) {
+ if ((tp = gmtime(&cs->notafter)) == NULL) {
+ sudo_warn(U_("unable to get GMT time"));
+ } else {
+ if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tp) == 0) {
+ sudo_warnx(U_("unable to format timestamp"));
+ } else {
+ value.type = JSON_STRING;
+ value.u.string = timebuf;
+ fputs(prefix, fp);
+ print_pair_json(fp, "{ ", "notafter", &value, " }", indent);
+ prefix = ",\n";
+ }
+ }
+ }
+ if (tag.nopasswd != UNSPEC) {
+ value.type = JSON_BOOL;
+ value.u.boolean = !tag.nopasswd;
+ fputs(prefix, fp);
+ print_pair_json(fp, "{ ", "authenticate", &value, " }", indent);
+ prefix = ",\n";
+ }
+ if (tag.noexec != UNSPEC) {
+ value.type = JSON_BOOL;
+ value.u.boolean = tag.noexec;
+ fputs(prefix, fp);
+ print_pair_json(fp, "{ ", "noexec", &value, " }", indent);
+ prefix = ",\n";
+ }
+ if (tag.send_mail != UNSPEC) {
+ value.type = JSON_BOOL;
+ value.u.boolean = tag.send_mail;
+ fputs(prefix, fp);
+ print_pair_json(fp, "{ ", "send_mail", &value, " }", indent);
+ prefix = ",\n";
+ }
+ if (tag.setenv != UNSPEC) {
+ value.type = JSON_BOOL;
+ value.u.boolean = tag.setenv;
+ fputs(prefix, fp);
+ print_pair_json(fp, "{ ", "setenv", &value, " }", indent);
+ prefix = ",\n";
+ }
+ if (tag.follow != UNSPEC) {
+ value.type = JSON_BOOL;
+ value.u.boolean = tag.follow;
+ fputs(prefix, fp);
+ print_pair_json(fp, "{ ", "sudoedit_follow", &value, " }", indent);
+ prefix = ",\n";
+ }
+ if (tag.log_input != UNSPEC) {
+ value.type = JSON_BOOL;
+ value.u.boolean = tag.log_input;
+ fputs(prefix, fp);
+ print_pair_json(fp, "{ ", "log_input", &value, " }", indent);
+ prefix = ",\n";
+ }
+ if (tag.log_output != UNSPEC) {
+ value.type = JSON_BOOL;
+ value.u.boolean = tag.log_output;
+ fputs(prefix, fp);
+ print_pair_json(fp, "{ ", "log_output", &value, " }", indent);
+ prefix = ",\n";
+ }
+ TAILQ_FOREACH(def, options, entries) {
+ int type = get_defaults_type(def);
+ if (type == -1) {
+ sudo_warnx(U_("unknown defaults entry \"%s\""), def->var);
+ /* XXX - just pass it through as a string anyway? */
+ continue;
+ }
+ fputs(prefix, fp);
+ if ((type & T_MASK) == T_FLAG || def->val == NULL) {
+ value.type = JSON_BOOL;
+ value.u.boolean = def->op;
+ print_pair_json(fp, "{ ", def->var, &value, " }", indent);
+ } else if ((type & T_MASK) == T_LIST) {
+ print_defaults_list_json(fp, def, indent);
+ } else {
+ value.type = JSON_STRING;
+ value.u.string = def->val;
+ print_pair_json(fp, "{ ", def->var, &value, " }", indent);
+ }
+ prefix = ",\n";
+ }
+ putc('\n', fp);
+ indent -= 4;
+ fprintf(fp, "%*s],\n", indent, "");
+ }
+
+#ifdef HAVE_SELINUX
+ /* Print SELinux role/type */
+ if (cs->role != NULL && cs->type != NULL) {
+ fprintf(fp, "%*s\"SELinux_Spec\": [\n", indent, "");
+ indent += 4;
+ value.type = JSON_STRING;
+ value.u.string = cs->role;
+ print_pair_json(fp, NULL, "role", &value, ",\n", indent);
+ value.u.string = cs->type;
+ print_pair_json(fp, NULL, "type", &value, "\n", indent);
+ indent -= 4;
+ fprintf(fp, "%*s],\n", indent, "");
+ }
+#endif /* HAVE_SELINUX */
+
+#ifdef HAVE_PRIV_SET
+ /* Print Solaris privs/limitprivs */
+ if (cs->privs != NULL || cs->limitprivs != NULL) {
+ fprintf(fp, "%*s\"Solaris_Priv_Spec\": [\n", indent, "");
+ indent += 4;
+ value.type = JSON_STRING;
+ if (cs->privs != NULL) {
+ value.u.string = cs->privs;
+ print_pair_json(fp, NULL, "privs", &value,
+ cs->limitprivs != NULL ? ",\n" : "\n", indent);
+ }
+ if (cs->limitprivs != NULL) {
+ value.u.string = cs->limitprivs;
+ print_pair_json(fp, NULL, "limitprivs", &value, "\n", indent);
+ }
+ indent -= 4;
+ fprintf(fp, "%*s],\n", indent, "");
+ }
+#endif /* HAVE_PRIV_SET */
+
+ /*
+ * Merge adjacent commands with matching tags, runas, SELinux
+ * role/type and Solaris priv settings.
+ */
+ fprintf(fp, "%*s\"Commands\": [\n", indent, "");
+ indent += 4;
+ for (;;) {
+ /* Does the next entry differ only in the command itself? */
+ /* XXX - move into a function that returns bool */
+ last_one = next == NULL ||
+ RUNAS_CHANGED(cs, next) || TAGS_CHANGED(cs->tags, next->tags)
+#ifdef HAVE_PRIV_SET
+ || cs->privs != next->privs || cs->limitprivs != next->limitprivs
+#endif /* HAVE_PRIV_SET */
+#ifdef HAVE_SELINUX
+ || cs->role != next->role || cs->type != next->type
+#endif /* HAVE_SELINUX */
+ ;
+
+ print_member_json(fp, parse_tree, cs->cmnd, TYPE_COMMAND,
+ last_one, indent, expand_aliases);
+ if (last_one)
+ break;
+ cs = next;
+ next = TAILQ_NEXT(cs, entries);
+ }
+ indent -= 4;
+ fprintf(fp, "%*s]\n", indent, "");
+
+ /* Close Cmnd_Spec object. */
+ indent -= 4;
+ fprintf(fp, "%*s}%s\n", indent, "", TAILQ_NEXT(cs, entries) != NULL ? "," : "");
+
+ *nextp = next;
+
+ debug_return;
+}
+
+/*
+ * Print a User_Spec in JSON format at the specified indent level.
+ */
+static void
+print_userspec_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
+ struct userspec *us, int indent, bool expand_aliases)
+{
+ struct privilege *priv;
+ struct member *m;
+ struct cmndspec *cs, *next;
+ debug_decl(print_userspec_json, SUDOERS_DEBUG_UTIL)
+
+ /*
+ * Each userspec struct may contain multiple privileges for
+ * a user. We export each privilege as a separate User_Spec
+ * object for simplicity's sake.
+ */
+ TAILQ_FOREACH(priv, &us->privileges, entries) {
+ /* Open User_Spec object. */
+ fprintf(fp, "%*s{\n", indent, "");
+ indent += 4;
+
+ /* Print users list. */
+ fprintf(fp, "%*s\"User_List\": [\n", indent, "");
+ indent += 4;
+ TAILQ_FOREACH(m, &us->users, entries) {
+ print_member_json(fp, parse_tree, m, TYPE_USERNAME,
+ TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
+ }
+ indent -= 4;
+ fprintf(fp, "%*s],\n", indent, "");
+
+ /* Print hosts list. */
+ fprintf(fp, "%*s\"Host_List\": [\n", indent, "");
+ indent += 4;
+ TAILQ_FOREACH(m, &priv->hostlist, entries) {
+ print_member_json(fp, parse_tree, m, TYPE_HOSTNAME,
+ TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
+ }
+ indent -= 4;
+ fprintf(fp, "%*s],\n", indent, "");
+
+ /* Print commands. */
+ fprintf(fp, "%*s\"Cmnd_Specs\": [\n", indent, "");
+ indent += 4;
+ TAILQ_FOREACH_SAFE(cs, &priv->cmndlist, entries, next) {
+ print_cmndspec_json(fp, parse_tree, cs, &next, &priv->defaults,
+ expand_aliases, indent);
+ }
+ indent -= 4;
+ fprintf(fp, "%*s]\n", indent, "");
+
+ /* Close User_Spec object. */
+ indent -= 4;
+ fprintf(fp, "%*s}%s\n", indent, "", TAILQ_NEXT(priv, entries) != NULL ||
+ TAILQ_NEXT(us, entries) != NULL ? "," : "");
+ }
+
+ debug_return;
+}
+
+static bool
+print_userspecs_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
+ int indent, bool expand_aliases, bool need_comma)
+{
+ struct userspec *us;
+ debug_decl(print_userspecs_json, SUDOERS_DEBUG_UTIL)
+
+ if (TAILQ_EMPTY(&parse_tree->userspecs))
+ debug_return_bool(need_comma);
+
+ fprintf(fp, "%s\n%*s\"User_Specs\": [\n", need_comma ? "," : "", indent, "");
+ indent += 4;
+ TAILQ_FOREACH(us, &parse_tree->userspecs, entries) {
+ print_userspec_json(fp, parse_tree, us, indent, expand_aliases);
+ }
+ indent -= 4;
+ fprintf(fp, "%*s]", indent, "");
+
+ debug_return_bool(true);
+}
+
+/*
+ * Export the parsed sudoers file in JSON format.
+ */
+bool
+convert_sudoers_json(struct sudoers_parse_tree *parse_tree,
+ const char *output_file, struct cvtsudoers_config *conf)
+{
+ bool ret = true, need_comma = false;
+ const int indent = 4;
+ FILE *output_fp = stdout;
+ debug_decl(convert_sudoers_json, SUDOERS_DEBUG_UTIL)
+
+ if (strcmp(output_file, "-") != 0) {
+ if ((output_fp = fopen(output_file, "w")) == NULL)
+ sudo_fatal(U_("unable to open %s"), output_file);
+ }
+
+ /* Open JSON output. */
+ putc('{', output_fp);
+
+ /* Dump Defaults in JSON format. */
+ if (!ISSET(conf->suppress, SUPPRESS_DEFAULTS)) {
+ need_comma = print_defaults_json(output_fp, parse_tree, indent,
+ conf->expand_aliases, need_comma);
+ }
+
+ /* Dump Aliases in JSON format. */
+ if (!conf->expand_aliases && !ISSET(conf->suppress, SUPPRESS_ALIASES)) {
+ need_comma = print_aliases_json(output_fp, parse_tree, indent,
+ need_comma);
+ }
+
+ /* Dump User_Specs in JSON format. */
+ if (!ISSET(conf->suppress, SUPPRESS_PRIVS)) {
+ print_userspecs_json(output_fp, parse_tree, indent,
+ conf->expand_aliases, need_comma);
+ }
+
+ /* Close JSON output. */
+ fputs("\n}\n", output_fp);
+ (void)fflush(output_fp);
+ if (ferror(output_fp))
+ ret = false;
+ if (output_fp != stdout)
+ fclose(output_fp);
+
+ debug_return_bool(ret);
+}
diff --git a/plugins/sudoers/cvtsudoers_ldif.c b/plugins/sudoers/cvtsudoers_ldif.c
new file mode 100644
index 0000000..0f43a5a
--- /dev/null
+++ b/plugins/sudoers/cvtsudoers_ldif.c
@@ -0,0 +1,665 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <stdarg.h>
+
+#include "sudoers.h"
+#include "sudo_ldap.h"
+#include "redblack.h"
+#include "cvtsudoers.h"
+#include "sudo_lbuf.h"
+#include <gram.h>
+
+struct seen_user {
+ const char *name;
+ unsigned long count;
+};
+
+static struct rbtree *seen_users;
+
+static int
+seen_user_compare(const void *aa, const void *bb)
+{
+ const struct seen_user *a = aa;
+ const struct seen_user *b = bb;
+
+ return strcasecmp(a->name, b->name);
+}
+
+static void
+seen_user_free(void *v)
+{
+ struct seen_user *su = v;
+
+ free((void *)su->name);
+ free(su);
+}
+
+static bool
+safe_string(const char *str)
+{
+ unsigned int ch = *str++;
+ debug_decl(safe_string, SUDOERS_DEBUG_UTIL)
+
+ /* Initial char must be <= 127 and not LF, CR, SPACE, ':', '<' */
+ switch (ch) {
+ case '\0':
+ debug_return_bool(true);
+ case '\n':
+ case '\r':
+ case ' ':
+ case ':':
+ case '<':
+ debug_return_bool(false);
+ default:
+ if (ch > 127)
+ debug_return_bool(false);
+ }
+
+ /* Any value <= 127 decimal except NUL, LF, and CR is safe */
+ while ((ch = *str++) != '\0') {
+ if (ch > 127 || ch == '\n' || ch == '\r')
+ debug_return_bool(false);
+ }
+
+ debug_return_bool(true);
+}
+
+static bool
+print_attribute_ldif(FILE *fp, const char *name, const char *value)
+{
+ const unsigned char *uvalue = (unsigned char *)value;
+ char *encoded = NULL;
+ size_t esize;
+ debug_decl(print_attribute_ldif, SUDOERS_DEBUG_UTIL)
+
+ if (!safe_string(value)) {
+ const size_t vlen = strlen(value);
+ esize = ((vlen + 2) / 3 * 4) + 1;
+ if ((encoded = malloc(esize)) == NULL)
+ debug_return_bool(false);
+ if (base64_encode(uvalue, vlen, encoded, esize) == (size_t)-1) {
+ free(encoded);
+ debug_return_bool(false);
+ }
+ fprintf(fp, "%s:: %s\n", name, encoded);
+ free(encoded);
+ } else if (*value != '\0') {
+ fprintf(fp, "%s: %s\n", name, value);
+ } else {
+ fprintf(fp, "%s:\n", name);
+ }
+
+ debug_return_bool(true);
+}
+
+/*
+ * Print sudoOptions from a defaults_list.
+ */
+static bool
+print_options_ldif(FILE *fp, struct defaults_list *options)
+{
+ struct defaults *opt;
+ char *attr_val;
+ int len;
+ debug_decl(print_options_ldif, SUDOERS_DEBUG_UTIL)
+
+ TAILQ_FOREACH(opt, options, entries) {
+ if (opt->type != DEFAULTS)
+ continue; /* don't support bound defaults */
+
+ if (opt->val != NULL) {
+ /* There is no need to double quote values here. */
+ len = asprintf(&attr_val, "%s%s%s", opt->var,
+ opt->op == '+' ? "+=" : opt->op == '-' ? "-=" : "=", opt->val);
+ } else {
+ /* Boolean flag. */
+ len = asprintf(&attr_val, "%s%s",
+ opt->op == false ? "!" : "", opt->var);
+ }
+ if (len == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ print_attribute_ldif(fp, "sudoOption", attr_val);
+ free(attr_val);
+ }
+
+ debug_return_bool(!ferror(fp));
+}
+
+/*
+ * Print global Defaults in a single sudoRole object.
+ */
+static bool
+print_global_defaults_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
+ const char *base)
+{
+ unsigned int count = 0;
+ struct sudo_lbuf lbuf;
+ struct defaults *opt;
+ char *dn;
+ debug_decl(print_global_defaults_ldif, SUDOERS_DEBUG_UTIL)
+
+ sudo_lbuf_init(&lbuf, NULL, 0, NULL, 80);
+
+ TAILQ_FOREACH(opt, &parse_tree->defaults, entries) {
+ /* Skip bound Defaults (unsupported). */
+ if (opt->type == DEFAULTS) {
+ count++;
+ } else {
+ lbuf.len = 0;
+ sudo_lbuf_append(&lbuf, "# ");
+ sudoers_format_default_line(&lbuf, parse_tree, opt, false, true);
+ fprintf(fp, "# Unable to translate %s:%d\n%s\n",
+ opt->file, opt->lineno, lbuf.buf);
+ }
+ }
+ sudo_lbuf_destroy(&lbuf);
+
+ if (count == 0)
+ debug_return_bool(true);
+
+ if (asprintf(&dn, "cn=defaults,%s", base) == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ print_attribute_ldif(fp, "dn", dn);
+ free(dn);
+ print_attribute_ldif(fp, "objectClass", "top");
+ print_attribute_ldif(fp, "objectClass", "sudoRole");
+ print_attribute_ldif(fp, "cn", "defaults");
+ print_attribute_ldif(fp, "description", "Default sudoOption's go here");
+
+ print_options_ldif(fp, &parse_tree->defaults);
+ putc('\n', fp);
+
+ debug_return_bool(!ferror(fp));
+}
+
+/*
+ * Print struct member in LDIF format as the specified attribute.
+ * See print_member_int() in parse.c.
+ */
+static void
+print_member_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree, char *name,
+ int type, bool negated, int alias_type, const char *attr_name)
+{
+ struct alias *a;
+ struct member *m;
+ struct sudo_command *c;
+ char *attr_val;
+ int len;
+ debug_decl(print_member_ldif, SUDOERS_DEBUG_UTIL)
+
+ switch (type) {
+ case ALL:
+ print_attribute_ldif(fp, attr_name, negated ? "!ALL" : "ALL");
+ break;
+ case MYSELF:
+ /* Only valid for sudoRunasUser */
+ print_attribute_ldif(fp, attr_name, "");
+ break;
+ case COMMAND:
+ c = (struct sudo_command *)name;
+ len = asprintf(&attr_val, "%s%s%s%s%s%s%s%s",
+ c->digest ? digest_type_to_name(c->digest->digest_type) : "",
+ c->digest ? ":" : "", c->digest ? c->digest->digest_str : "",
+ c->digest ? " " : "", negated ? "!" : "", c->cmnd,
+ c->args ? " " : "", c->args ? c->args : "");
+ if (len == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ print_attribute_ldif(fp, attr_name, attr_val);
+ free(attr_val);
+ break;
+ case ALIAS:
+ if ((a = alias_get(parse_tree, name, alias_type)) != NULL) {
+ TAILQ_FOREACH(m, &a->members, entries) {
+ print_member_ldif(fp, parse_tree, m->name, m->type,
+ negated ? !m->negated : m->negated, alias_type, attr_name);
+ }
+ alias_put(a);
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ len = asprintf(&attr_val, "%s%s", negated ? "!" : "", name);
+ if (len == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ print_attribute_ldif(fp, attr_name, attr_val);
+ free(attr_val);
+ break;
+ }
+
+ debug_return;
+}
+
+/*
+ * Print a Cmnd_Spec in LDIF format.
+ * A pointer to the next Cmnd_Spec is passed in to make it possible to
+ * merge adjacent entries that are identical in all but the command.
+ */
+static void
+print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
+ struct cmndspec *cs, struct cmndspec **nextp, struct defaults_list *options)
+{
+ struct cmndspec *next = *nextp;
+ struct member *m;
+ struct tm *tp;
+ bool last_one;
+ char timebuf[sizeof("20120727121554Z")];
+ debug_decl(print_cmndspec_ldif, SUDOERS_DEBUG_UTIL)
+
+ /* Print runasuserlist as sudoRunAsUser attributes */
+ if (cs->runasuserlist != NULL) {
+ TAILQ_FOREACH(m, cs->runasuserlist, entries) {
+ print_member_ldif(fp, parse_tree, m->name, m->type, m->negated,
+ RUNASALIAS, "sudoRunAsUser");
+ }
+ }
+
+ /* Print runasgrouplist as sudoRunAsGroup attributes */
+ if (cs->runasgrouplist != NULL) {
+ TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
+ print_member_ldif(fp, parse_tree, m->name, m->type, m->negated,
+ RUNASALIAS, "sudoRunAsGroup");
+ }
+ }
+
+ /* Print sudoNotBefore and sudoNotAfter attributes */
+ if (cs->notbefore != UNSPEC) {
+ if ((tp = gmtime(&cs->notbefore)) == NULL) {
+ sudo_warn(U_("unable to get GMT time"));
+ } else {
+ if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tp) == 0) {
+ sudo_warnx(U_("unable to format timestamp"));
+ } else {
+ print_attribute_ldif(fp, "sudoNotBefore", timebuf);
+ }
+ }
+ }
+ if (cs->notafter != UNSPEC) {
+ if ((tp = gmtime(&cs->notafter)) == NULL) {
+ sudo_warn(U_("unable to get GMT time"));
+ } else {
+ if (strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tp) == 0) {
+ sudo_warnx(U_("unable to format timestamp"));
+ } else {
+ print_attribute_ldif(fp, "sudoNotAfter", timebuf);
+ }
+ }
+ }
+
+ /* Print timeout as a sudoOption. */
+ if (cs->timeout > 0) {
+ char *attr_val;
+ if (asprintf(&attr_val, "command_timeout=%d", cs->timeout) == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ print_attribute_ldif(fp, "sudoOption", attr_val);
+ free(attr_val);
+ }
+
+ /* Print tags as sudoOption attributes */
+ if (TAGS_SET(cs->tags)) {
+ struct cmndtag tag = cs->tags;
+
+ if (tag.nopasswd != UNSPEC) {
+ print_attribute_ldif(fp, "sudoOption",
+ tag.nopasswd ? "!authenticate" : "authenticate");
+ }
+ if (tag.noexec != UNSPEC) {
+ print_attribute_ldif(fp, "sudoOption",
+ tag.noexec ? "noexec" : "!noexec");
+ }
+ if (tag.send_mail != UNSPEC) {
+ if (tag.send_mail) {
+ print_attribute_ldif(fp, "sudoOption", "mail_all_cmnds");
+ } else {
+ print_attribute_ldif(fp, "sudoOption", "!mail_all_cmnds");
+ print_attribute_ldif(fp, "sudoOption", "!mail_always");
+ print_attribute_ldif(fp, "sudoOption", "!mail_no_perms");
+ }
+ }
+ if (tag.setenv != UNSPEC && tag.setenv != IMPLIED) {
+ print_attribute_ldif(fp, "sudoOption",
+ tag.setenv ? "setenv" : "!setenv");
+ }
+ if (tag.follow != UNSPEC) {
+ print_attribute_ldif(fp, "sudoOption",
+ tag.follow ? "sudoedit_follow" : "!sudoedit_follow");
+ }
+ if (tag.log_input != UNSPEC) {
+ print_attribute_ldif(fp, "sudoOption",
+ tag.log_input ? "log_input" : "!log_input");
+ }
+ if (tag.log_output != UNSPEC) {
+ print_attribute_ldif(fp, "sudoOption",
+ tag.log_output ? "log_output" : "!log_output");
+ }
+ }
+ print_options_ldif(fp, options);
+
+#ifdef HAVE_SELINUX
+ /* Print SELinux role/type */
+ if (cs->role != NULL && cs->type != NULL) {
+ char *attr_val;
+ int len;
+
+ len = asprintf(&attr_val, "role=%s", cs->role);
+ if (len == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ print_attribute_ldif(fp, "sudoOption", attr_val);
+ free(attr_val);
+
+ len = asprintf(&attr_val, "type=%s", cs->type);
+ if (len == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ print_attribute_ldif(fp, "sudoOption", attr_val);
+ free(attr_val);
+ }
+#endif /* HAVE_SELINUX */
+
+#ifdef HAVE_PRIV_SET
+ /* Print Solaris privs/limitprivs */
+ if (cs->privs != NULL || cs->limitprivs != NULL) {
+ char *attr_val;
+ int len;
+
+ if (cs->privs != NULL) {
+ len = asprintf(&attr_val, "privs=%s", cs->privs);
+ if (len == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ print_attribute_ldif(fp, "sudoOption", attr_val);
+ free(attr_val);
+ }
+ if (cs->limitprivs != NULL) {
+ len = asprintf(&attr_val, "limitprivs=%s", cs->limitprivs);
+ if (len == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ print_attribute_ldif(fp, "sudoOption", attr_val);
+ free(attr_val);
+ }
+ }
+#endif /* HAVE_PRIV_SET */
+
+ /*
+ * Merge adjacent commands with matching tags, runas, SELinux
+ * role/type and Solaris priv settings.
+ */
+ for (;;) {
+ /* Does the next entry differ only in the command itself? */
+ /* XXX - move into a function that returns bool */
+ /* XXX - TAG_SET does not account for implied SETENV */
+ last_one = next == NULL ||
+ RUNAS_CHANGED(cs, next) || TAGS_CHANGED(cs->tags, next->tags)
+#ifdef HAVE_PRIV_SET
+ || cs->privs != next->privs || cs->limitprivs != next->limitprivs
+#endif /* HAVE_PRIV_SET */
+#ifdef HAVE_SELINUX
+ || cs->role != next->role || cs->type != next->type
+#endif /* HAVE_SELINUX */
+ ;
+
+ print_member_ldif(fp, parse_tree, cs->cmnd->name, cs->cmnd->type,
+ cs->cmnd->negated, CMNDALIAS, "sudoCommand");
+ if (last_one)
+ break;
+ cs = next;
+ next = TAILQ_NEXT(cs, entries);
+ }
+
+ *nextp = next;
+
+ debug_return;
+}
+
+/*
+ * Convert user name to cn, avoiding duplicates and quoting as needed.
+ * See http://www.faqs.org/rfcs/rfc2253.html
+ */
+static char *
+user_to_cn(const char *user)
+{
+ struct seen_user key, *su = NULL;
+ struct rbnode *node;
+ const char *src;
+ char *cn, *dst;
+ size_t size;
+ debug_decl(user_to_cn, SUDOERS_DEBUG_UTIL)
+
+ /* Allocate as much as we could possibly need. */
+ size = (2 * strlen(user)) + 64 + 1;
+ if ((cn = malloc(size)) == NULL)
+ goto bad;
+
+ /*
+ * Increment the number of times we have seen this user.
+ */
+ key.name = user;
+ node = rbfind(seen_users, &key);
+ if (node != NULL) {
+ su = node->data;
+ } else {
+ if ((su = malloc(sizeof(*su))) == NULL)
+ goto bad;
+ su->count = 0;
+ if ((su->name = strdup(user)) == NULL)
+ goto bad;
+ if (rbinsert(seen_users, su, NULL) != 0)
+ goto bad;
+ }
+
+ /* Build cn, quoting special chars as needed (we allocated 2 x len). */
+ for (src = user, dst = cn; *src != '\0'; src++) {
+ switch (*src) {
+ case ',':
+ case '+':
+ case '"':
+ case '\\':
+ case '<':
+ case '>':
+ case '#':
+ case ';':
+ *dst++ = '\\'; /* always escape */
+ break;
+ case ' ':
+ if (src == user || src[1] == '\0')
+ *dst++ = '\\'; /* only escape at beginning or end of string */
+ break;
+ default:
+ break;
+ }
+ *dst++ = *src;
+ }
+ *dst = '\0';
+
+ /* Append count if there are duplicate users (cn must be unique). */
+ if (su->count != 0) {
+ size -= (size_t)(dst - cn);
+ if ((size_t)snprintf(dst, size, "_%lu", su->count) >= size) {
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ goto bad;
+ }
+ }
+ su->count++;
+
+ debug_return_str(cn);
+bad:
+ if (su != NULL && su->count == 0)
+ seen_user_free(su);
+ free(cn);
+ debug_return_str(NULL);
+}
+
+/*
+ * Print a single User_Spec.
+ */
+static bool
+print_userspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
+ struct userspec *us, struct cvtsudoers_config *conf)
+{
+ struct privilege *priv;
+ struct member *m;
+ struct cmndspec *cs, *next;
+ debug_decl(print_userspec_ldif, SUDOERS_DEBUG_UTIL)
+
+ /*
+ * Each userspec struct may contain multiple privileges for
+ * the user. We export each privilege as a separate sudoRole
+ * object for simplicity's sake.
+ */
+ TAILQ_FOREACH(priv, &us->privileges, entries) {
+ TAILQ_FOREACH_SAFE(cs, &priv->cmndlist, entries, next) {
+ const char *base = conf->sudoers_base;
+ char *cn, *dn;
+
+ /*
+ * Increment the number of times we have seen this user.
+ * If more than one user is listed, just use the first one.
+ */
+ m = TAILQ_FIRST(&us->users);
+ cn = user_to_cn(m->type == ALL ? "ALL" : m->name);
+ if (cn == NULL || asprintf(&dn, "cn=%s,%s", cn, base) == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+
+ print_attribute_ldif(fp, "dn", dn);
+ print_attribute_ldif(fp, "objectClass", "top");
+ print_attribute_ldif(fp, "objectClass", "sudoRole");
+ print_attribute_ldif(fp, "cn", cn);
+ free(cn);
+ free(dn);
+
+ TAILQ_FOREACH(m, &us->users, entries) {
+ print_member_ldif(fp, parse_tree, m->name, m->type, m->negated,
+ USERALIAS, "sudoUser");
+ }
+
+ TAILQ_FOREACH(m, &priv->hostlist, entries) {
+ print_member_ldif(fp, parse_tree, m->name, m->type, m->negated,
+ HOSTALIAS, "sudoHost");
+ }
+
+ print_cmndspec_ldif(fp, parse_tree, cs, &next, &priv->defaults);
+
+ if (conf->sudo_order != 0) {
+ char numbuf[(((sizeof(conf->sudo_order) * 8) + 2) / 3) + 2];
+ if (conf->order_max != 0 && conf->sudo_order > conf->order_max) {
+ sudo_fatalx(U_("too many sudoers entries, maximum %u"),
+ conf->order_padding);
+ }
+ (void)snprintf(numbuf, sizeof(numbuf), "%u", conf->sudo_order);
+ print_attribute_ldif(fp, "sudoOrder", numbuf);
+ putc('\n', fp);
+ conf->sudo_order += conf->order_increment;
+ }
+ }
+ }
+
+ debug_return_bool(!ferror(fp));
+}
+
+/*
+ * Print User_Specs.
+ */
+static bool
+print_userspecs_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
+ struct cvtsudoers_config *conf)
+{
+ struct userspec *us;
+ debug_decl(print_userspecs_ldif, SUDOERS_DEBUG_UTIL)
+
+ TAILQ_FOREACH(us, &parse_tree->userspecs, entries) {
+ if (!print_userspec_ldif(fp, parse_tree, us, conf))
+ debug_return_bool(false);
+ }
+ debug_return_bool(true);
+}
+
+/*
+ * Export the parsed sudoers file in LDIF format.
+ */
+bool
+convert_sudoers_ldif(struct sudoers_parse_tree *parse_tree,
+ const char *output_file, struct cvtsudoers_config *conf)
+{
+ bool ret = true;
+ FILE *output_fp = stdout;
+ debug_decl(convert_sudoers_ldif, SUDOERS_DEBUG_UTIL)
+
+ if (conf->sudoers_base == NULL) {
+ sudo_fatalx(U_("the SUDOERS_BASE environment variable is not set and the -b option was not specified."));
+ }
+
+ if (output_file != NULL && strcmp(output_file, "-") != 0) {
+ if ((output_fp = fopen(output_file, "w")) == NULL)
+ sudo_fatal(U_("unable to open %s"), output_file);
+ }
+
+ /* Create a dictionary of already-seen users. */
+ seen_users = rbcreate(seen_user_compare);
+
+ /* Dump global Defaults in LDIF format. */
+ if (!ISSET(conf->suppress, SUPPRESS_DEFAULTS))
+ print_global_defaults_ldif(output_fp, parse_tree, conf->sudoers_base);
+
+ /* Dump User_Specs in LDIF format, expanding Aliases. */
+ if (!ISSET(conf->suppress, SUPPRESS_PRIVS))
+ print_userspecs_ldif(output_fp, parse_tree, conf);
+
+ /* Clean up. */
+ rbdestroy(seen_users, seen_user_free);
+
+ (void)fflush(output_fp);
+ if (ferror(output_fp))
+ ret = false;
+ if (output_fp != stdout)
+ fclose(output_fp);
+
+ debug_return_bool(ret);
+}
diff --git a/plugins/sudoers/cvtsudoers_pwutil.c b/plugins/sudoers/cvtsudoers_pwutil.c
new file mode 100644
index 0000000..49715a3
--- /dev/null
+++ b/plugins/sudoers/cvtsudoers_pwutil.c
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "sudoers.h"
+#include "cvtsudoers.h"
+#include "pwutil.h"
+
+#ifndef LOGIN_NAME_MAX
+# ifdef _POSIX_LOGIN_NAME_MAX
+# define LOGIN_NAME_MAX _POSIX_LOGIN_NAME_MAX
+# else
+# define LOGIN_NAME_MAX 9
+# endif
+#endif /* LOGIN_NAME_MAX */
+
+#define FIELD_SIZE(src, name, size) \
+do { \
+ if ((src)->name) { \
+ size = strlen((src)->name) + 1; \
+ total += size; \
+ } \
+} while (0)
+
+#define FIELD_COPY(src, dst, name, size) \
+do { \
+ if ((src)->name) { \
+ memcpy(cp, (src)->name, size); \
+ (dst)->name = cp; \
+ cp += size; \
+ } \
+} while (0)
+
+/*
+ * Dynamically allocate space for a struct item plus the key and data
+ * elements. If name is non-NULL it is used as the key, else the
+ * uid is the key. Fills in datum from the users filter.
+ * Returns NULL on calloc error or unknown name/id, setting errno
+ * to ENOMEM or ENOENT respectively.
+ */
+struct cache_item *
+cvtsudoers_make_pwitem(uid_t uid, const char *name)
+{
+ char *cp, uidstr[MAX_UID_T_LEN + 2];
+ size_t nsize, psize, csize, gsize, dsize, ssize, total;
+ struct cache_item_pw *pwitem;
+ struct passwd pw, *newpw;
+ struct sudoers_string *s = NULL;
+ debug_decl(sudo_make_pwitem, SUDOERS_DEBUG_NSS)
+
+ /* Look up name or uid in filter list. */
+ if (name != NULL) {
+ STAILQ_FOREACH(s, &filters->users, entries) {
+ if (strcasecmp(name, s->str) == 0) {
+ uid = (uid_t)-1;
+ break;
+ }
+ }
+ } else {
+ STAILQ_FOREACH(s, &filters->users, entries) {
+ const char *errstr;
+ uid_t filter_uid;
+
+ if (s->str[0] != '#')
+ continue;
+
+ filter_uid = sudo_strtoid(s->str + 1, NULL, NULL, &errstr);
+ if (errstr == NULL) {
+ if (uid != filter_uid)
+ continue;
+ snprintf(uidstr, sizeof(uidstr), "#%u", (unsigned int)uid);
+ break;
+ }
+ }
+ }
+ if (s == NULL) {
+ errno = ENOENT;
+ debug_return_ptr(NULL);
+ }
+
+ /* Fake up a passwd struct. */
+ memset(&pw, 0, sizeof(pw));
+ pw.pw_name = name ? s->str : uidstr;
+ pw.pw_passwd = "*";
+ pw.pw_uid = uid;
+ pw.pw_gid = (gid_t)-1;
+ pw.pw_shell = _PATH_BSHELL;
+ pw.pw_dir = "/";
+
+ /* Allocate in one big chunk for easy freeing. */
+ nsize = psize = csize = gsize = dsize = ssize = 0;
+ total = sizeof(*pwitem);
+ FIELD_SIZE(&pw, pw_name, nsize);
+ FIELD_SIZE(&pw, pw_passwd, psize);
+#ifdef HAVE_LOGIN_CAP_H
+ FIELD_SIZE(&pw, pw_class, csize);
+#endif
+ FIELD_SIZE(&pw, pw_gecos, gsize);
+ FIELD_SIZE(&pw, pw_dir, dsize);
+ FIELD_SIZE(&pw, pw_shell, ssize);
+ if (name != NULL)
+ total += strlen(name) + 1;
+
+ /* Allocate space for struct item, struct passwd and the strings. */
+ if ((pwitem = calloc(1, total)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+ newpw = &pwitem->pw;
+
+ /*
+ * Copy in passwd contents and make strings relative to space
+ * at the end of the struct.
+ */
+ memcpy(newpw, &pw, sizeof(pw));
+ cp = (char *)(pwitem + 1);
+ FIELD_COPY(&pw, newpw, pw_name, nsize);
+ FIELD_COPY(&pw, newpw, pw_passwd, psize);
+#ifdef HAVE_LOGIN_CAP_H
+ FIELD_COPY(&pw, newpw, pw_class, csize);
+#endif
+ FIELD_COPY(&pw, newpw, pw_gecos, gsize);
+ FIELD_COPY(&pw, newpw, pw_dir, dsize);
+ FIELD_COPY(&pw, newpw, pw_shell, ssize);
+
+ /* Set key and datum. */
+ if (name != NULL) {
+ memcpy(cp, name, strlen(name) + 1);
+ pwitem->cache.k.name = cp;
+ } else {
+ pwitem->cache.k.uid = pw.pw_uid;
+ }
+ pwitem->cache.d.pw = newpw;
+ pwitem->cache.refcnt = 1;
+
+ debug_return_ptr(&pwitem->cache);
+}
+
+/*
+ * Dynamically allocate space for a struct item plus the key and data
+ * elements. If name is non-NULL it is used as the key, else the
+ * gid is the key. Fills in datum from the groups filter.
+ * Returns NULL on calloc error or unknown name/id, setting errno
+ * to ENOMEM or ENOENT respectively.
+ */
+struct cache_item *
+cvtsudoers_make_gritem(gid_t gid, const char *name)
+{
+ char *cp, gidstr[MAX_UID_T_LEN + 2];
+ size_t nsize, psize, nmem, total, len;
+ struct cache_item_gr *gritem;
+ struct group gr, *newgr;
+ struct sudoers_string *s = NULL;
+ debug_decl(sudo_make_gritem, SUDOERS_DEBUG_NSS)
+
+ /* Look up name or gid in filter list. */
+ if (name != NULL) {
+ STAILQ_FOREACH(s, &filters->groups, entries) {
+ if (strcasecmp(name, s->str) == 0) {
+ gid = (gid_t)-1;
+ break;
+ }
+ }
+ } else {
+ STAILQ_FOREACH(s, &filters->groups, entries) {
+ const char *errstr;
+ gid_t filter_gid;
+
+ if (s->str[0] != '#')
+ continue;
+
+ filter_gid = sudo_strtoid(s->str + 1, NULL, NULL, &errstr);
+ if (errstr == NULL) {
+ if (gid != filter_gid)
+ continue;
+ snprintf(gidstr, sizeof(gidstr), "#%u", (unsigned int)gid);
+ break;
+ }
+ }
+ }
+ if (s == NULL) {
+ errno = ENOENT;
+ debug_return_ptr(NULL);
+ }
+
+ /* Fake up a group struct with all filter users as members. */
+ memset(&gr, 0, sizeof(gr));
+ gr.gr_name = name ? s->str : gidstr;
+ gr.gr_gid = gid;
+
+ /* Allocate in one big chunk for easy freeing. */
+ nsize = psize = nmem = 0;
+ total = sizeof(*gritem);
+ FIELD_SIZE(&gr, gr_name, nsize);
+ FIELD_SIZE(&gr, gr_passwd, psize);
+ if (!STAILQ_EMPTY(&filters->users)) {
+ STAILQ_FOREACH(s, &filters->users, entries) {
+ total += strlen(s->str) + 1;
+ nmem++;
+ }
+ total += sizeof(char *) * nmem;
+ }
+ if (name != NULL)
+ total += strlen(name) + 1;
+
+ if ((gritem = calloc(1, total)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+
+ /*
+ * Copy in group contents and make strings relative to space
+ * at the end of the buffer. Note that gr_mem must come
+ * immediately after struct group to guarantee proper alignment.
+ */
+ newgr = &gritem->gr;
+ memcpy(newgr, &gr, sizeof(gr));
+ cp = (char *)(gritem + 1);
+ if (nmem != 0) {
+ newgr->gr_mem = (char **)cp;
+ cp += sizeof(char *) * nmem;
+ nmem = 0;
+ STAILQ_FOREACH(s, &filters->users, entries) {
+ len = strlen(s->str) + 1;
+ memcpy(cp, s->str, len);
+ newgr->gr_mem[nmem++] = cp;
+ cp += len;
+ }
+ newgr->gr_mem[nmem] = NULL;
+ }
+ FIELD_COPY(&gr, newgr, gr_passwd, psize);
+ FIELD_COPY(&gr, newgr, gr_name, nsize);
+
+ /* Set key and datum. */
+ if (name != NULL) {
+ memcpy(cp, name, strlen(name) + 1);
+ gritem->cache.k.name = cp;
+ } else {
+ gritem->cache.k.gid = gr.gr_gid;
+ }
+ gritem->cache.d.gr = newgr;
+ gritem->cache.refcnt = 1;
+
+ debug_return_ptr(&gritem->cache);
+}
+
+static struct cache_item_gidlist *gidlist_item;
+
+/*
+ * Dynamically allocate space for a struct item plus the key and data
+ * elements. Fills in datum from the groups filter.
+ */
+struct cache_item *
+cvtsudoers_make_gidlist_item(const struct passwd *pw, char * const *unused1,
+ unsigned int type)
+{
+ char *cp;
+ size_t nsize, total;
+ struct cache_item_gidlist *glitem;
+ struct sudoers_string *s;
+ struct gid_list *gidlist;
+ GETGROUPS_T *gids = NULL;
+ int i, ngids = 0;
+ debug_decl(sudo_make_gidlist_item, SUDOERS_DEBUG_NSS)
+
+ /*
+ * There's only a single gid list.
+ */
+ if (gidlist_item != NULL) {
+ gidlist_item->cache.refcnt++;
+ debug_return_ptr(&gidlist_item->cache);
+ }
+
+ /* Count number of possible gids in the filter. */
+ STAILQ_FOREACH(s, &filters->groups, entries) {
+ if (s->str[0] == '#')
+ ngids++;
+ }
+
+ /* Allocate gids[] array and fill it with parsed gids. */
+ if (ngids != 0) {
+ gids = reallocarray(NULL, ngids, sizeof(GETGROUPS_T));
+ if (gids == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+ ngids = 0;
+ STAILQ_FOREACH(s, &filters->groups, entries) {
+ if (s->str[0] == '#') {
+ const char *errstr;
+ gid_t gid = sudo_strtoid(s->str + 1, NULL, NULL, &errstr);
+ if (errstr == NULL) {
+ /* Valid gid. */
+ gids[ngids++] = gid;
+ }
+ }
+ }
+ }
+ if (ngids == 0) {
+ free(gids);
+ errno = ENOENT;
+ debug_return_ptr(NULL);
+ }
+
+ /* Allocate in one big chunk for easy freeing. */
+ nsize = strlen(pw->pw_name) + 1;
+ total = sizeof(*glitem) + nsize;
+ total += sizeof(gid_t *) * ngids;
+
+ if ((glitem = calloc(1, total)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ free(gids);
+ debug_return_ptr(NULL);
+ }
+
+ /*
+ * Copy in group list and make pointers relative to space
+ * at the end of the buffer. Note that the groups array must come
+ * immediately after struct group to guarantee proper alignment.
+ */
+ gidlist = &glitem->gidlist;
+ cp = (char *)(glitem + 1);
+ gidlist->gids = (gid_t *)cp;
+ cp += sizeof(gid_t) * ngids;
+
+ /* Set key and datum. */
+ memcpy(cp, pw->pw_name, nsize);
+ glitem->cache.k.name = cp;
+ glitem->cache.d.gidlist = gidlist;
+ glitem->cache.refcnt = 1;
+ glitem->cache.type = type;
+
+ /*
+ * Store group IDs.
+ */
+ for (i = 0; i < ngids; i++)
+ gidlist->gids[i] = gids[i];
+ gidlist->ngids = ngids;
+ free(gids);
+
+ debug_return_ptr(&glitem->cache);
+}
+
+static struct cache_item_gidlist *grlist_item;
+
+/*
+ * Dynamically allocate space for a struct item plus the key and data
+ * elements. Fills in group names from the groups filter.
+ */
+struct cache_item *
+cvtsudoers_make_grlist_item(const struct passwd *pw, char * const *unused1)
+{
+ char *cp;
+ size_t nsize, ngroups, total, len;
+ struct cache_item_grlist *grlitem;
+ struct sudoers_string *s;
+ struct group_list *grlist;
+ int groupname_len;
+ debug_decl(sudo_make_grlist_item, SUDOERS_DEBUG_NSS)
+
+ /*
+ * There's only a single group list.
+ */
+ if (grlist_item != NULL) {
+ grlist_item->cache.refcnt++;
+ debug_return_ptr(&grlist_item->cache);
+ }
+
+ /* Count number of groups in the filter. */
+ ngroups = 0;
+ STAILQ_FOREACH(s, &filters->groups, entries) {
+ ngroups++;
+ }
+
+#ifdef _SC_LOGIN_NAME_MAX
+ groupname_len = MAX((int)sysconf(_SC_LOGIN_NAME_MAX), 32);
+#else
+ groupname_len = MAX(LOGIN_NAME_MAX, 32);
+#endif
+
+ /* Allocate in one big chunk for easy freeing. */
+ nsize = strlen(pw->pw_name) + 1;
+ total = sizeof(*grlitem) + nsize;
+ total += groupname_len * ngroups;
+
+again:
+ if ((grlitem = calloc(1, total)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+
+ /*
+ * Copy in group list and make pointers relative to space
+ * at the end of the buffer. Note that the groups array must come
+ * immediately after struct group to guarantee proper alignment.
+ */
+ grlist = &grlitem->grlist;
+ cp = (char *)(grlitem + 1);
+ grlist->groups = (char **)cp;
+ cp += sizeof(char *) * ngroups;
+
+ /* Set key and datum. */
+ memcpy(cp, pw->pw_name, nsize);
+ grlitem->cache.k.name = cp;
+ grlitem->cache.d.grlist = grlist;
+ grlitem->cache.refcnt = 1;
+ cp += nsize;
+
+ /*
+ * Copy groups from filter.
+ */
+ ngroups = 0;
+ STAILQ_FOREACH(s, &filters->groups, entries) {
+ if (s->str[0] == '#') {
+ const char *errstr;
+ sudo_strtoid(s->str + 1, NULL, NULL, &errstr);
+ if (errstr == NULL) {
+ /* Group ID not name, ignore it. */
+ continue;
+ }
+ }
+ len = strlen(s->str) + 1;
+ if (cp - (char *)grlitem + len > total) {
+ total += len + groupname_len;
+ free(grlitem);
+ goto again;
+ }
+ memcpy(cp, s->str, len);
+ grlist->groups[ngroups++] = cp;
+ cp += len;
+ }
+ grlist->ngroups = ngroups;
+
+ debug_return_ptr(&grlitem->cache);
+}
diff --git a/plugins/sudoers/def_data.c b/plugins/sudoers/def_data.c
new file mode 100644
index 0000000..07e3433
--- /dev/null
+++ b/plugins/sudoers/def_data.c
@@ -0,0 +1,499 @@
+static struct def_values def_data_lecture[] = {
+ { "never", never },
+ { "once", once },
+ { "always", always },
+ { NULL, 0 },
+};
+
+static struct def_values def_data_listpw[] = {
+ { "never", never },
+ { "any", any },
+ { "all", all },
+ { "always", always },
+ { NULL, 0 },
+};
+
+static struct def_values def_data_verifypw[] = {
+ { "never", never },
+ { "all", all },
+ { "any", any },
+ { "always", always },
+ { NULL, 0 },
+};
+
+static struct def_values def_data_fdexec[] = {
+ { "never", never },
+ { "digest_only", digest_only },
+ { "always", always },
+ { NULL, 0 },
+};
+
+static struct def_values def_data_timestamp_type[] = {
+ { "global", global },
+ { "ppid", ppid },
+ { "tty", tty },
+ { "kernel", kernel },
+ { NULL, 0 },
+};
+
+struct sudo_defs_types sudo_defs_table[] = {
+ {
+ "syslog", T_LOGFAC|T_BOOL,
+ N_("Syslog facility if syslog is being used for logging: %s"),
+ NULL,
+ }, {
+ "syslog_goodpri", T_LOGPRI|T_BOOL,
+ N_("Syslog priority to use when user authenticates successfully: %s"),
+ NULL,
+ }, {
+ "syslog_badpri", T_LOGPRI|T_BOOL,
+ N_("Syslog priority to use when user authenticates unsuccessfully: %s"),
+ NULL,
+ }, {
+ "long_otp_prompt", T_FLAG,
+ N_("Put OTP prompt on its own line"),
+ NULL,
+ }, {
+ "ignore_dot", T_FLAG,
+ N_("Ignore '.' in $PATH"),
+ NULL,
+ }, {
+ "mail_always", T_FLAG,
+ N_("Always send mail when sudo is run"),
+ NULL,
+ }, {
+ "mail_badpass", T_FLAG,
+ N_("Send mail if user authentication fails"),
+ NULL,
+ }, {
+ "mail_no_user", T_FLAG,
+ N_("Send mail if the user is not in sudoers"),
+ NULL,
+ }, {
+ "mail_no_host", T_FLAG,
+ N_("Send mail if the user is not in sudoers for this host"),
+ NULL,
+ }, {
+ "mail_no_perms", T_FLAG,
+ N_("Send mail if the user is not allowed to run a command"),
+ NULL,
+ }, {
+ "mail_all_cmnds", T_FLAG,
+ N_("Send mail if the user tries to run a command"),
+ NULL,
+ }, {
+ "tty_tickets", T_FLAG,
+ N_("Use a separate timestamp for each user/tty combo"),
+ NULL,
+ }, {
+ "lecture", T_TUPLE|T_BOOL,
+ N_("Lecture user the first time they run sudo"),
+ def_data_lecture,
+ }, {
+ "lecture_file", T_STR|T_PATH|T_BOOL,
+ N_("File containing the sudo lecture: %s"),
+ NULL,
+ }, {
+ "authenticate", T_FLAG,
+ N_("Require users to authenticate by default"),
+ NULL,
+ }, {
+ "root_sudo", T_FLAG,
+ N_("Root may run sudo"),
+ NULL,
+ }, {
+ "log_host", T_FLAG,
+ N_("Log the hostname in the (non-syslog) log file"),
+ NULL,
+ }, {
+ "log_year", T_FLAG,
+ N_("Log the year in the (non-syslog) log file"),
+ NULL,
+ }, {
+ "shell_noargs", T_FLAG,
+ N_("If sudo is invoked with no arguments, start a shell"),
+ NULL,
+ }, {
+ "set_home", T_FLAG,
+ N_("Set $HOME to the target user when starting a shell with -s"),
+ NULL,
+ }, {
+ "always_set_home", T_FLAG,
+ N_("Always set $HOME to the target user's home directory"),
+ NULL,
+ }, {
+ "path_info", T_FLAG,
+ N_("Allow some information gathering to give useful error messages"),
+ NULL,
+ }, {
+ "fqdn", T_FLAG,
+ N_("Require fully-qualified hostnames in the sudoers file"),
+ NULL,
+ }, {
+ "insults", T_FLAG,
+ N_("Insult the user when they enter an incorrect password"),
+ NULL,
+ }, {
+ "requiretty", T_FLAG,
+ N_("Only allow the user to run sudo if they have a tty"),
+ NULL,
+ }, {
+ "env_editor", T_FLAG,
+ N_("Visudo will honor the EDITOR environment variable"),
+ NULL,
+ }, {
+ "rootpw", T_FLAG,
+ N_("Prompt for root's password, not the users's"),
+ NULL,
+ }, {
+ "runaspw", T_FLAG,
+ N_("Prompt for the runas_default user's password, not the users's"),
+ NULL,
+ }, {
+ "targetpw", T_FLAG,
+ N_("Prompt for the target user's password, not the users's"),
+ NULL,
+ }, {
+ "use_loginclass", T_FLAG,
+ N_("Apply defaults in the target user's login class if there is one"),
+ NULL,
+ }, {
+ "set_logname", T_FLAG,
+ N_("Set the LOGNAME and USER environment variables"),
+ NULL,
+ }, {
+ "stay_setuid", T_FLAG,
+ N_("Only set the effective uid to the target user, not the real uid"),
+ NULL,
+ }, {
+ "preserve_groups", T_FLAG,
+ N_("Don't initialize the group vector to that of the target user"),
+ NULL,
+ }, {
+ "loglinelen", T_UINT|T_BOOL,
+ N_("Length at which to wrap log file lines (0 for no wrap): %u"),
+ NULL,
+ }, {
+ "timestamp_timeout", T_TIMESPEC|T_BOOL,
+ N_("Authentication timestamp timeout: %.1f minutes"),
+ NULL,
+ }, {
+ "passwd_timeout", T_TIMESPEC|T_BOOL,
+ N_("Password prompt timeout: %.1f minutes"),
+ NULL,
+ }, {
+ "passwd_tries", T_UINT,
+ N_("Number of tries to enter a password: %u"),
+ NULL,
+ }, {
+ "umask", T_MODE|T_BOOL,
+ N_("Umask to use or 0777 to use user's: 0%o"),
+ NULL,
+ }, {
+ "logfile", T_STR|T_BOOL|T_PATH,
+ N_("Path to log file: %s"),
+ NULL,
+ }, {
+ "mailerpath", T_STR|T_BOOL|T_PATH,
+ N_("Path to mail program: %s"),
+ NULL,
+ }, {
+ "mailerflags", T_STR|T_BOOL,
+ N_("Flags for mail program: %s"),
+ NULL,
+ }, {
+ "mailto", T_STR|T_BOOL,
+ N_("Address to send mail to: %s"),
+ NULL,
+ }, {
+ "mailfrom", T_STR|T_BOOL,
+ N_("Address to send mail from: %s"),
+ NULL,
+ }, {
+ "mailsub", T_STR,
+ N_("Subject line for mail messages: %s"),
+ NULL,
+ }, {
+ "badpass_message", T_STR,
+ N_("Incorrect password message: %s"),
+ NULL,
+ }, {
+ "lecture_status_dir", T_STR|T_PATH,
+ N_("Path to lecture status dir: %s"),
+ NULL,
+ }, {
+ "timestampdir", T_STR|T_PATH,
+ N_("Path to authentication timestamp dir: %s"),
+ NULL,
+ }, {
+ "timestampowner", T_STR,
+ N_("Owner of the authentication timestamp dir: %s"),
+ NULL,
+ }, {
+ "exempt_group", T_STR|T_BOOL,
+ N_("Users in this group are exempt from password and PATH requirements: %s"),
+ NULL,
+ }, {
+ "passprompt", T_STR,
+ N_("Default password prompt: %s"),
+ NULL,
+ }, {
+ "passprompt_override", T_FLAG,
+ N_("If set, passprompt will override system prompt in all cases."),
+ NULL,
+ }, {
+ "runas_default", T_STR,
+ N_("Default user to run commands as: %s"),
+ NULL,
+ }, {
+ "secure_path", T_STR|T_BOOL,
+ N_("Value to override user's $PATH with: %s"),
+ NULL,
+ }, {
+ "editor", T_STR|T_PATH,
+ N_("Path to the editor for use by visudo: %s"),
+ NULL,
+ }, {
+ "listpw", T_TUPLE|T_BOOL,
+ N_("When to require a password for 'list' pseudocommand: %s"),
+ def_data_listpw,
+ }, {
+ "verifypw", T_TUPLE|T_BOOL,
+ N_("When to require a password for 'verify' pseudocommand: %s"),
+ def_data_verifypw,
+ }, {
+ "noexec", T_FLAG,
+ N_("Preload the dummy exec functions contained in the sudo_noexec library"),
+ NULL,
+ }, {
+ "ignore_local_sudoers", T_FLAG,
+ N_("If LDAP directory is up, do we ignore local sudoers file"),
+ NULL,
+ }, {
+ "closefrom", T_INT,
+ N_("File descriptors >= %d will be closed before executing a command"),
+ NULL,
+ }, {
+ "closefrom_override", T_FLAG,
+ N_("If set, users may override the value of `closefrom' with the -C option"),
+ NULL,
+ }, {
+ "setenv", T_FLAG,
+ N_("Allow users to set arbitrary environment variables"),
+ NULL,
+ }, {
+ "env_reset", T_FLAG,
+ N_("Reset the environment to a default set of variables"),
+ NULL,
+ }, {
+ "env_check", T_LIST|T_BOOL,
+ N_("Environment variables to check for sanity:"),
+ NULL,
+ }, {
+ "env_delete", T_LIST|T_BOOL,
+ N_("Environment variables to remove:"),
+ NULL,
+ }, {
+ "env_keep", T_LIST|T_BOOL,
+ N_("Environment variables to preserve:"),
+ NULL,
+ }, {
+ "role", T_STR,
+ N_("SELinux role to use in the new security context: %s"),
+ NULL,
+ }, {
+ "type", T_STR,
+ N_("SELinux type to use in the new security context: %s"),
+ NULL,
+ }, {
+ "env_file", T_STR|T_PATH|T_BOOL,
+ N_("Path to the sudo-specific environment file: %s"),
+ NULL,
+ }, {
+ "restricted_env_file", T_STR|T_PATH|T_BOOL,
+ N_("Path to the restricted sudo-specific environment file: %s"),
+ NULL,
+ }, {
+ "sudoers_locale", T_STR,
+ N_("Locale to use while parsing sudoers: %s"),
+ NULL,
+ }, {
+ "visiblepw", T_FLAG,
+ N_("Allow sudo to prompt for a password even if it would be visible"),
+ NULL,
+ }, {
+ "pwfeedback", T_FLAG,
+ N_("Provide visual feedback at the password prompt when there is user input"),
+ NULL,
+ }, {
+ "fast_glob", T_FLAG,
+ N_("Use faster globbing that is less accurate but does not access the filesystem"),
+ NULL,
+ }, {
+ "umask_override", T_FLAG,
+ N_("The umask specified in sudoers will override the user's, even if it is more permissive"),
+ NULL,
+ }, {
+ "log_input", T_FLAG,
+ N_("Log user's input for the command being run"),
+ NULL,
+ }, {
+ "log_output", T_FLAG,
+ N_("Log the output of the command being run"),
+ NULL,
+ }, {
+ "compress_io", T_FLAG,
+ N_("Compress I/O logs using zlib"),
+ NULL,
+ }, {
+ "use_pty", T_FLAG,
+ N_("Always run commands in a pseudo-tty"),
+ NULL,
+ }, {
+ "group_plugin", T_STR,
+ N_("Plugin for non-Unix group support: %s"),
+ NULL,
+ }, {
+ "iolog_dir", T_STR|T_PATH,
+ N_("Directory in which to store input/output logs: %s"),
+ NULL,
+ }, {
+ "iolog_file", T_STR,
+ N_("File in which to store the input/output log: %s"),
+ NULL,
+ }, {
+ "set_utmp", T_FLAG,
+ N_("Add an entry to the utmp/utmpx file when allocating a pty"),
+ NULL,
+ }, {
+ "utmp_runas", T_FLAG,
+ N_("Set the user in utmp to the runas user, not the invoking user"),
+ NULL,
+ }, {
+ "privs", T_STR,
+ N_("Set of permitted privileges: %s"),
+ NULL,
+ }, {
+ "limitprivs", T_STR,
+ N_("Set of limit privileges: %s"),
+ NULL,
+ }, {
+ "exec_background", T_FLAG,
+ N_("Run commands on a pty in the background"),
+ NULL,
+ }, {
+ "pam_service", T_STR,
+ N_("PAM service name to use: %s"),
+ NULL,
+ }, {
+ "pam_login_service", T_STR,
+ N_("PAM service name to use for login shells: %s"),
+ NULL,
+ }, {
+ "pam_setcred", T_FLAG,
+ N_("Attempt to establish PAM credentials for the target user"),
+ NULL,
+ }, {
+ "pam_session", T_FLAG,
+ N_("Create a new PAM session for the command to run in"),
+ NULL,
+ }, {
+ "maxseq", T_UINT,
+ N_("Maximum I/O log sequence number: %u"),
+ NULL,
+ }, {
+ "use_netgroups", T_FLAG,
+ N_("Enable sudoers netgroup support"),
+ NULL,
+ }, {
+ "sudoedit_checkdir", T_FLAG,
+ N_("Check parent directories for writability when editing files with sudoedit"),
+ NULL,
+ }, {
+ "sudoedit_follow", T_FLAG,
+ N_("Follow symbolic links when editing files with sudoedit"),
+ NULL,
+ }, {
+ "always_query_group_plugin", T_FLAG,
+ N_("Query the group plugin for unknown system groups"),
+ NULL,
+ }, {
+ "netgroup_tuple", T_FLAG,
+ N_("Match netgroups based on the entire tuple: user, host and domain"),
+ NULL,
+ }, {
+ "ignore_audit_errors", T_FLAG,
+ N_("Allow commands to be run even if sudo cannot write to the audit log"),
+ NULL,
+ }, {
+ "ignore_iolog_errors", T_FLAG,
+ N_("Allow commands to be run even if sudo cannot write to the I/O log"),
+ NULL,
+ }, {
+ "ignore_logfile_errors", T_FLAG,
+ N_("Allow commands to be run even if sudo cannot write to the log file"),
+ NULL,
+ }, {
+ "match_group_by_gid", T_FLAG,
+ N_("Resolve groups in sudoers and match on the group ID, not the name"),
+ NULL,
+ }, {
+ "syslog_maxlen", T_UINT,
+ N_("Log entries larger than this value will be split into multiple syslog messages: %u"),
+ NULL,
+ }, {
+ "iolog_user", T_STR|T_BOOL,
+ N_("User that will own the I/O log files: %s"),
+ NULL,
+ }, {
+ "iolog_group", T_STR|T_BOOL,
+ N_("Group that will own the I/O log files: %s"),
+ NULL,
+ }, {
+ "iolog_mode", T_MODE,
+ N_("File mode to use for the I/O log files: 0%o"),
+ NULL,
+ }, {
+ "fdexec", T_TUPLE|T_BOOL,
+ N_("Execute commands by file descriptor instead of by path: %s"),
+ def_data_fdexec,
+ }, {
+ "ignore_unknown_defaults", T_FLAG,
+ N_("Ignore unknown Defaults entries in sudoers instead of producing a warning"),
+ NULL,
+ }, {
+ "command_timeout", T_TIMEOUT|T_BOOL,
+ N_("Time in seconds after which the command will be terminated: %u"),
+ NULL,
+ }, {
+ "user_command_timeouts", T_FLAG,
+ N_("Allow the user to specify a timeout on the command line"),
+ NULL,
+ }, {
+ "iolog_flush", T_FLAG,
+ N_("Flush I/O log data to disk immediately instead of buffering it"),
+ NULL,
+ }, {
+ "syslog_pid", T_FLAG,
+ N_("Include the process ID when logging via syslog"),
+ NULL,
+ }, {
+ "timestamp_type", T_TUPLE,
+ N_("Type of authentication timestamp record: %s"),
+ def_data_timestamp_type,
+ }, {
+ "authfail_message", T_STR,
+ N_("Authentication failure message: %s"),
+ NULL,
+ }, {
+ "case_insensitive_user", T_FLAG,
+ N_("Ignore case when matching user names"),
+ NULL,
+ }, {
+ "case_insensitive_group", T_FLAG,
+ N_("Ignore case when matching group names"),
+ NULL,
+ }, {
+ NULL, 0, NULL
+ }
+};
diff --git a/plugins/sudoers/def_data.h b/plugins/sudoers/def_data.h
new file mode 100644
index 0000000..65f10c3
--- /dev/null
+++ b/plugins/sudoers/def_data.h
@@ -0,0 +1,241 @@
+#define I_SYSLOG 0
+#define def_syslog (sudo_defs_table[I_SYSLOG].sd_un.ival)
+#define I_SYSLOG_GOODPRI 1
+#define def_syslog_goodpri (sudo_defs_table[I_SYSLOG_GOODPRI].sd_un.ival)
+#define I_SYSLOG_BADPRI 2
+#define def_syslog_badpri (sudo_defs_table[I_SYSLOG_BADPRI].sd_un.ival)
+#define I_LONG_OTP_PROMPT 3
+#define def_long_otp_prompt (sudo_defs_table[I_LONG_OTP_PROMPT].sd_un.flag)
+#define I_IGNORE_DOT 4
+#define def_ignore_dot (sudo_defs_table[I_IGNORE_DOT].sd_un.flag)
+#define I_MAIL_ALWAYS 5
+#define def_mail_always (sudo_defs_table[I_MAIL_ALWAYS].sd_un.flag)
+#define I_MAIL_BADPASS 6
+#define def_mail_badpass (sudo_defs_table[I_MAIL_BADPASS].sd_un.flag)
+#define I_MAIL_NO_USER 7
+#define def_mail_no_user (sudo_defs_table[I_MAIL_NO_USER].sd_un.flag)
+#define I_MAIL_NO_HOST 8
+#define def_mail_no_host (sudo_defs_table[I_MAIL_NO_HOST].sd_un.flag)
+#define I_MAIL_NO_PERMS 9
+#define def_mail_no_perms (sudo_defs_table[I_MAIL_NO_PERMS].sd_un.flag)
+#define I_MAIL_ALL_CMNDS 10
+#define def_mail_all_cmnds (sudo_defs_table[I_MAIL_ALL_CMNDS].sd_un.flag)
+#define I_TTY_TICKETS 11
+#define def_tty_tickets (sudo_defs_table[I_TTY_TICKETS].sd_un.flag)
+#define I_LECTURE 12
+#define def_lecture (sudo_defs_table[I_LECTURE].sd_un.tuple)
+#define I_LECTURE_FILE 13
+#define def_lecture_file (sudo_defs_table[I_LECTURE_FILE].sd_un.str)
+#define I_AUTHENTICATE 14
+#define def_authenticate (sudo_defs_table[I_AUTHENTICATE].sd_un.flag)
+#define I_ROOT_SUDO 15
+#define def_root_sudo (sudo_defs_table[I_ROOT_SUDO].sd_un.flag)
+#define I_LOG_HOST 16
+#define def_log_host (sudo_defs_table[I_LOG_HOST].sd_un.flag)
+#define I_LOG_YEAR 17
+#define def_log_year (sudo_defs_table[I_LOG_YEAR].sd_un.flag)
+#define I_SHELL_NOARGS 18
+#define def_shell_noargs (sudo_defs_table[I_SHELL_NOARGS].sd_un.flag)
+#define I_SET_HOME 19
+#define def_set_home (sudo_defs_table[I_SET_HOME].sd_un.flag)
+#define I_ALWAYS_SET_HOME 20
+#define def_always_set_home (sudo_defs_table[I_ALWAYS_SET_HOME].sd_un.flag)
+#define I_PATH_INFO 21
+#define def_path_info (sudo_defs_table[I_PATH_INFO].sd_un.flag)
+#define I_FQDN 22
+#define def_fqdn (sudo_defs_table[I_FQDN].sd_un.flag)
+#define I_INSULTS 23
+#define def_insults (sudo_defs_table[I_INSULTS].sd_un.flag)
+#define I_REQUIRETTY 24
+#define def_requiretty (sudo_defs_table[I_REQUIRETTY].sd_un.flag)
+#define I_ENV_EDITOR 25
+#define def_env_editor (sudo_defs_table[I_ENV_EDITOR].sd_un.flag)
+#define I_ROOTPW 26
+#define def_rootpw (sudo_defs_table[I_ROOTPW].sd_un.flag)
+#define I_RUNASPW 27
+#define def_runaspw (sudo_defs_table[I_RUNASPW].sd_un.flag)
+#define I_TARGETPW 28
+#define def_targetpw (sudo_defs_table[I_TARGETPW].sd_un.flag)
+#define I_USE_LOGINCLASS 29
+#define def_use_loginclass (sudo_defs_table[I_USE_LOGINCLASS].sd_un.flag)
+#define I_SET_LOGNAME 30
+#define def_set_logname (sudo_defs_table[I_SET_LOGNAME].sd_un.flag)
+#define I_STAY_SETUID 31
+#define def_stay_setuid (sudo_defs_table[I_STAY_SETUID].sd_un.flag)
+#define I_PRESERVE_GROUPS 32
+#define def_preserve_groups (sudo_defs_table[I_PRESERVE_GROUPS].sd_un.flag)
+#define I_LOGLINELEN 33
+#define def_loglinelen (sudo_defs_table[I_LOGLINELEN].sd_un.uival)
+#define I_TIMESTAMP_TIMEOUT 34
+#define def_timestamp_timeout (sudo_defs_table[I_TIMESTAMP_TIMEOUT].sd_un.tspec)
+#define I_PASSWD_TIMEOUT 35
+#define def_passwd_timeout (sudo_defs_table[I_PASSWD_TIMEOUT].sd_un.tspec)
+#define I_PASSWD_TRIES 36
+#define def_passwd_tries (sudo_defs_table[I_PASSWD_TRIES].sd_un.uival)
+#define I_UMASK 37
+#define def_umask (sudo_defs_table[I_UMASK].sd_un.mode)
+#define I_LOGFILE 38
+#define def_logfile (sudo_defs_table[I_LOGFILE].sd_un.str)
+#define I_MAILERPATH 39
+#define def_mailerpath (sudo_defs_table[I_MAILERPATH].sd_un.str)
+#define I_MAILERFLAGS 40
+#define def_mailerflags (sudo_defs_table[I_MAILERFLAGS].sd_un.str)
+#define I_MAILTO 41
+#define def_mailto (sudo_defs_table[I_MAILTO].sd_un.str)
+#define I_MAILFROM 42
+#define def_mailfrom (sudo_defs_table[I_MAILFROM].sd_un.str)
+#define I_MAILSUB 43
+#define def_mailsub (sudo_defs_table[I_MAILSUB].sd_un.str)
+#define I_BADPASS_MESSAGE 44
+#define def_badpass_message (sudo_defs_table[I_BADPASS_MESSAGE].sd_un.str)
+#define I_LECTURE_STATUS_DIR 45
+#define def_lecture_status_dir (sudo_defs_table[I_LECTURE_STATUS_DIR].sd_un.str)
+#define I_TIMESTAMPDIR 46
+#define def_timestampdir (sudo_defs_table[I_TIMESTAMPDIR].sd_un.str)
+#define I_TIMESTAMPOWNER 47
+#define def_timestampowner (sudo_defs_table[I_TIMESTAMPOWNER].sd_un.str)
+#define I_EXEMPT_GROUP 48
+#define def_exempt_group (sudo_defs_table[I_EXEMPT_GROUP].sd_un.str)
+#define I_PASSPROMPT 49
+#define def_passprompt (sudo_defs_table[I_PASSPROMPT].sd_un.str)
+#define I_PASSPROMPT_OVERRIDE 50
+#define def_passprompt_override (sudo_defs_table[I_PASSPROMPT_OVERRIDE].sd_un.flag)
+#define I_RUNAS_DEFAULT 51
+#define def_runas_default (sudo_defs_table[I_RUNAS_DEFAULT].sd_un.str)
+#define I_SECURE_PATH 52
+#define def_secure_path (sudo_defs_table[I_SECURE_PATH].sd_un.str)
+#define I_EDITOR 53
+#define def_editor (sudo_defs_table[I_EDITOR].sd_un.str)
+#define I_LISTPW 54
+#define def_listpw (sudo_defs_table[I_LISTPW].sd_un.tuple)
+#define I_VERIFYPW 55
+#define def_verifypw (sudo_defs_table[I_VERIFYPW].sd_un.tuple)
+#define I_NOEXEC 56
+#define def_noexec (sudo_defs_table[I_NOEXEC].sd_un.flag)
+#define I_IGNORE_LOCAL_SUDOERS 57
+#define def_ignore_local_sudoers (sudo_defs_table[I_IGNORE_LOCAL_SUDOERS].sd_un.flag)
+#define I_CLOSEFROM 58
+#define def_closefrom (sudo_defs_table[I_CLOSEFROM].sd_un.ival)
+#define I_CLOSEFROM_OVERRIDE 59
+#define def_closefrom_override (sudo_defs_table[I_CLOSEFROM_OVERRIDE].sd_un.flag)
+#define I_SETENV 60
+#define def_setenv (sudo_defs_table[I_SETENV].sd_un.flag)
+#define I_ENV_RESET 61
+#define def_env_reset (sudo_defs_table[I_ENV_RESET].sd_un.flag)
+#define I_ENV_CHECK 62
+#define def_env_check (sudo_defs_table[I_ENV_CHECK].sd_un.list)
+#define I_ENV_DELETE 63
+#define def_env_delete (sudo_defs_table[I_ENV_DELETE].sd_un.list)
+#define I_ENV_KEEP 64
+#define def_env_keep (sudo_defs_table[I_ENV_KEEP].sd_un.list)
+#define I_ROLE 65
+#define def_role (sudo_defs_table[I_ROLE].sd_un.str)
+#define I_TYPE 66
+#define def_type (sudo_defs_table[I_TYPE].sd_un.str)
+#define I_ENV_FILE 67
+#define def_env_file (sudo_defs_table[I_ENV_FILE].sd_un.str)
+#define I_RESTRICTED_ENV_FILE 68
+#define def_restricted_env_file (sudo_defs_table[I_RESTRICTED_ENV_FILE].sd_un.str)
+#define I_SUDOERS_LOCALE 69
+#define def_sudoers_locale (sudo_defs_table[I_SUDOERS_LOCALE].sd_un.str)
+#define I_VISIBLEPW 70
+#define def_visiblepw (sudo_defs_table[I_VISIBLEPW].sd_un.flag)
+#define I_PWFEEDBACK 71
+#define def_pwfeedback (sudo_defs_table[I_PWFEEDBACK].sd_un.flag)
+#define I_FAST_GLOB 72
+#define def_fast_glob (sudo_defs_table[I_FAST_GLOB].sd_un.flag)
+#define I_UMASK_OVERRIDE 73
+#define def_umask_override (sudo_defs_table[I_UMASK_OVERRIDE].sd_un.flag)
+#define I_LOG_INPUT 74
+#define def_log_input (sudo_defs_table[I_LOG_INPUT].sd_un.flag)
+#define I_LOG_OUTPUT 75
+#define def_log_output (sudo_defs_table[I_LOG_OUTPUT].sd_un.flag)
+#define I_COMPRESS_IO 76
+#define def_compress_io (sudo_defs_table[I_COMPRESS_IO].sd_un.flag)
+#define I_USE_PTY 77
+#define def_use_pty (sudo_defs_table[I_USE_PTY].sd_un.flag)
+#define I_GROUP_PLUGIN 78
+#define def_group_plugin (sudo_defs_table[I_GROUP_PLUGIN].sd_un.str)
+#define I_IOLOG_DIR 79
+#define def_iolog_dir (sudo_defs_table[I_IOLOG_DIR].sd_un.str)
+#define I_IOLOG_FILE 80
+#define def_iolog_file (sudo_defs_table[I_IOLOG_FILE].sd_un.str)
+#define I_SET_UTMP 81
+#define def_set_utmp (sudo_defs_table[I_SET_UTMP].sd_un.flag)
+#define I_UTMP_RUNAS 82
+#define def_utmp_runas (sudo_defs_table[I_UTMP_RUNAS].sd_un.flag)
+#define I_PRIVS 83
+#define def_privs (sudo_defs_table[I_PRIVS].sd_un.str)
+#define I_LIMITPRIVS 84
+#define def_limitprivs (sudo_defs_table[I_LIMITPRIVS].sd_un.str)
+#define I_EXEC_BACKGROUND 85
+#define def_exec_background (sudo_defs_table[I_EXEC_BACKGROUND].sd_un.flag)
+#define I_PAM_SERVICE 86
+#define def_pam_service (sudo_defs_table[I_PAM_SERVICE].sd_un.str)
+#define I_PAM_LOGIN_SERVICE 87
+#define def_pam_login_service (sudo_defs_table[I_PAM_LOGIN_SERVICE].sd_un.str)
+#define I_PAM_SETCRED 88
+#define def_pam_setcred (sudo_defs_table[I_PAM_SETCRED].sd_un.flag)
+#define I_PAM_SESSION 89
+#define def_pam_session (sudo_defs_table[I_PAM_SESSION].sd_un.flag)
+#define I_MAXSEQ 90
+#define def_maxseq (sudo_defs_table[I_MAXSEQ].sd_un.uival)
+#define I_USE_NETGROUPS 91
+#define def_use_netgroups (sudo_defs_table[I_USE_NETGROUPS].sd_un.flag)
+#define I_SUDOEDIT_CHECKDIR 92
+#define def_sudoedit_checkdir (sudo_defs_table[I_SUDOEDIT_CHECKDIR].sd_un.flag)
+#define I_SUDOEDIT_FOLLOW 93
+#define def_sudoedit_follow (sudo_defs_table[I_SUDOEDIT_FOLLOW].sd_un.flag)
+#define I_ALWAYS_QUERY_GROUP_PLUGIN 94
+#define def_always_query_group_plugin (sudo_defs_table[I_ALWAYS_QUERY_GROUP_PLUGIN].sd_un.flag)
+#define I_NETGROUP_TUPLE 95
+#define def_netgroup_tuple (sudo_defs_table[I_NETGROUP_TUPLE].sd_un.flag)
+#define I_IGNORE_AUDIT_ERRORS 96
+#define def_ignore_audit_errors (sudo_defs_table[I_IGNORE_AUDIT_ERRORS].sd_un.flag)
+#define I_IGNORE_IOLOG_ERRORS 97
+#define def_ignore_iolog_errors (sudo_defs_table[I_IGNORE_IOLOG_ERRORS].sd_un.flag)
+#define I_IGNORE_LOGFILE_ERRORS 98
+#define def_ignore_logfile_errors (sudo_defs_table[I_IGNORE_LOGFILE_ERRORS].sd_un.flag)
+#define I_MATCH_GROUP_BY_GID 99
+#define def_match_group_by_gid (sudo_defs_table[I_MATCH_GROUP_BY_GID].sd_un.flag)
+#define I_SYSLOG_MAXLEN 100
+#define def_syslog_maxlen (sudo_defs_table[I_SYSLOG_MAXLEN].sd_un.uival)
+#define I_IOLOG_USER 101
+#define def_iolog_user (sudo_defs_table[I_IOLOG_USER].sd_un.str)
+#define I_IOLOG_GROUP 102
+#define def_iolog_group (sudo_defs_table[I_IOLOG_GROUP].sd_un.str)
+#define I_IOLOG_MODE 103
+#define def_iolog_mode (sudo_defs_table[I_IOLOG_MODE].sd_un.mode)
+#define I_FDEXEC 104
+#define def_fdexec (sudo_defs_table[I_FDEXEC].sd_un.tuple)
+#define I_IGNORE_UNKNOWN_DEFAULTS 105
+#define def_ignore_unknown_defaults (sudo_defs_table[I_IGNORE_UNKNOWN_DEFAULTS].sd_un.flag)
+#define I_COMMAND_TIMEOUT 106
+#define def_command_timeout (sudo_defs_table[I_COMMAND_TIMEOUT].sd_un.ival)
+#define I_USER_COMMAND_TIMEOUTS 107
+#define def_user_command_timeouts (sudo_defs_table[I_USER_COMMAND_TIMEOUTS].sd_un.flag)
+#define I_IOLOG_FLUSH 108
+#define def_iolog_flush (sudo_defs_table[I_IOLOG_FLUSH].sd_un.flag)
+#define I_SYSLOG_PID 109
+#define def_syslog_pid (sudo_defs_table[I_SYSLOG_PID].sd_un.flag)
+#define I_TIMESTAMP_TYPE 110
+#define def_timestamp_type (sudo_defs_table[I_TIMESTAMP_TYPE].sd_un.tuple)
+#define I_AUTHFAIL_MESSAGE 111
+#define def_authfail_message (sudo_defs_table[I_AUTHFAIL_MESSAGE].sd_un.str)
+#define I_CASE_INSENSITIVE_USER 112
+#define def_case_insensitive_user (sudo_defs_table[I_CASE_INSENSITIVE_USER].sd_un.flag)
+#define I_CASE_INSENSITIVE_GROUP 113
+#define def_case_insensitive_group (sudo_defs_table[I_CASE_INSENSITIVE_GROUP].sd_un.flag)
+
+enum def_tuple {
+ never,
+ once,
+ always,
+ any,
+ all,
+ digest_only,
+ global,
+ ppid,
+ tty,
+ kernel
+};
diff --git a/plugins/sudoers/def_data.in b/plugins/sudoers/def_data.in
new file mode 100644
index 0000000..99d4360
--- /dev/null
+++ b/plugins/sudoers/def_data.in
@@ -0,0 +1,359 @@
+#
+# Format:
+#
+# var_name
+# TYPE
+# description (or NULL)
+# array of struct def_values if TYPE == T_TUPLE
+#
+# NOTE: for tuples that can be used in a boolean context the first
+# value corresponds to boolean FALSE and the second to TRUE.
+#
+
+syslog
+ T_LOGFAC|T_BOOL
+ "Syslog facility if syslog is being used for logging: %s"
+syslog_goodpri
+ T_LOGPRI|T_BOOL
+ "Syslog priority to use when user authenticates successfully: %s"
+syslog_badpri
+ T_LOGPRI|T_BOOL
+ "Syslog priority to use when user authenticates unsuccessfully: %s"
+long_otp_prompt
+ T_FLAG
+ "Put OTP prompt on its own line"
+ignore_dot
+ T_FLAG
+ "Ignore '.' in $PATH"
+mail_always
+ T_FLAG
+ "Always send mail when sudo is run"
+mail_badpass
+ T_FLAG
+ "Send mail if user authentication fails"
+mail_no_user
+ T_FLAG
+ "Send mail if the user is not in sudoers"
+mail_no_host
+ T_FLAG
+ "Send mail if the user is not in sudoers for this host"
+mail_no_perms
+ T_FLAG
+ "Send mail if the user is not allowed to run a command"
+mail_all_cmnds
+ T_FLAG
+ "Send mail if the user tries to run a command"
+tty_tickets
+ T_FLAG
+ "Use a separate timestamp for each user/tty combo"
+lecture
+ T_TUPLE|T_BOOL
+ "Lecture user the first time they run sudo"
+ never once always
+lecture_file
+ T_STR|T_PATH|T_BOOL
+ "File containing the sudo lecture: %s"
+authenticate
+ T_FLAG
+ "Require users to authenticate by default"
+root_sudo
+ T_FLAG
+ "Root may run sudo"
+log_host
+ T_FLAG
+ "Log the hostname in the (non-syslog) log file"
+log_year
+ T_FLAG
+ "Log the year in the (non-syslog) log file"
+shell_noargs
+ T_FLAG
+ "If sudo is invoked with no arguments, start a shell"
+set_home
+ T_FLAG
+ "Set $HOME to the target user when starting a shell with -s"
+always_set_home
+ T_FLAG
+ "Always set $HOME to the target user's home directory"
+path_info
+ T_FLAG
+ "Allow some information gathering to give useful error messages"
+fqdn
+ T_FLAG
+ "Require fully-qualified hostnames in the sudoers file"
+insults
+ T_FLAG
+ "Insult the user when they enter an incorrect password"
+requiretty
+ T_FLAG
+ "Only allow the user to run sudo if they have a tty"
+env_editor
+ T_FLAG
+ "Visudo will honor the EDITOR environment variable"
+rootpw
+ T_FLAG
+ "Prompt for root's password, not the users's"
+runaspw
+ T_FLAG
+ "Prompt for the runas_default user's password, not the users's"
+targetpw
+ T_FLAG
+ "Prompt for the target user's password, not the users's"
+use_loginclass
+ T_FLAG
+ "Apply defaults in the target user's login class if there is one"
+set_logname
+ T_FLAG
+ "Set the LOGNAME and USER environment variables"
+stay_setuid
+ T_FLAG
+ "Only set the effective uid to the target user, not the real uid"
+preserve_groups
+ T_FLAG
+ "Don't initialize the group vector to that of the target user"
+loglinelen
+ T_UINT|T_BOOL
+ "Length at which to wrap log file lines (0 for no wrap): %u"
+timestamp_timeout
+ T_TIMESPEC|T_BOOL
+ "Authentication timestamp timeout: %.1f minutes"
+passwd_timeout
+ T_TIMESPEC|T_BOOL
+ "Password prompt timeout: %.1f minutes"
+passwd_tries
+ T_UINT
+ "Number of tries to enter a password: %u"
+umask
+ T_MODE|T_BOOL
+ "Umask to use or 0777 to use user's: 0%o"
+logfile
+ T_STR|T_BOOL|T_PATH
+ "Path to log file: %s"
+mailerpath
+ T_STR|T_BOOL|T_PATH
+ "Path to mail program: %s"
+mailerflags
+ T_STR|T_BOOL
+ "Flags for mail program: %s"
+mailto
+ T_STR|T_BOOL
+ "Address to send mail to: %s"
+mailfrom
+ T_STR|T_BOOL
+ "Address to send mail from: %s"
+mailsub
+ T_STR
+ "Subject line for mail messages: %s"
+badpass_message
+ T_STR
+ "Incorrect password message: %s"
+lecture_status_dir
+ T_STR|T_PATH
+ "Path to lecture status dir: %s"
+timestampdir
+ T_STR|T_PATH
+ "Path to authentication timestamp dir: %s"
+timestampowner
+ T_STR
+ "Owner of the authentication timestamp dir: %s"
+exempt_group
+ T_STR|T_BOOL
+ "Users in this group are exempt from password and PATH requirements: %s"
+passprompt
+ T_STR
+ "Default password prompt: %s"
+passprompt_override
+ T_FLAG
+ "If set, passprompt will override system prompt in all cases."
+runas_default
+ T_STR
+ "Default user to run commands as: %s"
+secure_path
+ T_STR|T_BOOL
+ "Value to override user's $PATH with: %s"
+editor
+ T_STR|T_PATH
+ "Path to the editor for use by visudo: %s"
+listpw
+ T_TUPLE|T_BOOL
+ "When to require a password for 'list' pseudocommand: %s"
+ never any all always
+verifypw
+ T_TUPLE|T_BOOL
+ "When to require a password for 'verify' pseudocommand: %s"
+ never all any always
+noexec
+ T_FLAG
+ "Preload the dummy exec functions contained in the sudo_noexec library"
+ignore_local_sudoers
+ T_FLAG
+ "If LDAP directory is up, do we ignore local sudoers file"
+closefrom
+ T_INT
+ "File descriptors >= %d will be closed before executing a command"
+closefrom_override
+ T_FLAG
+ "If set, users may override the value of `closefrom' with the -C option"
+setenv
+ T_FLAG
+ "Allow users to set arbitrary environment variables"
+env_reset
+ T_FLAG
+ "Reset the environment to a default set of variables"
+env_check
+ T_LIST|T_BOOL
+ "Environment variables to check for sanity:"
+env_delete
+ T_LIST|T_BOOL
+ "Environment variables to remove:"
+env_keep
+ T_LIST|T_BOOL
+ "Environment variables to preserve:"
+role
+ T_STR
+ "SELinux role to use in the new security context: %s"
+type
+ T_STR
+ "SELinux type to use in the new security context: %s"
+env_file
+ T_STR|T_PATH|T_BOOL
+ "Path to the sudo-specific environment file: %s"
+restricted_env_file
+ T_STR|T_PATH|T_BOOL
+ "Path to the restricted sudo-specific environment file: %s"
+sudoers_locale
+ T_STR
+ "Locale to use while parsing sudoers: %s"
+visiblepw
+ T_FLAG
+ "Allow sudo to prompt for a password even if it would be visible"
+pwfeedback
+ T_FLAG
+ "Provide visual feedback at the password prompt when there is user input"
+fast_glob
+ T_FLAG
+ "Use faster globbing that is less accurate but does not access the filesystem"
+umask_override
+ T_FLAG
+ "The umask specified in sudoers will override the user's, even if it is more permissive"
+log_input
+ T_FLAG
+ "Log user's input for the command being run"
+log_output
+ T_FLAG
+ "Log the output of the command being run"
+compress_io
+ T_FLAG
+ "Compress I/O logs using zlib"
+use_pty
+ T_FLAG
+ "Always run commands in a pseudo-tty"
+group_plugin
+ T_STR
+ "Plugin for non-Unix group support: %s"
+iolog_dir
+ T_STR|T_PATH
+ "Directory in which to store input/output logs: %s"
+iolog_file
+ T_STR
+ "File in which to store the input/output log: %s"
+set_utmp
+ T_FLAG
+ "Add an entry to the utmp/utmpx file when allocating a pty"
+utmp_runas
+ T_FLAG
+ "Set the user in utmp to the runas user, not the invoking user"
+privs
+ T_STR
+ "Set of permitted privileges: %s"
+limitprivs
+ T_STR
+ "Set of limit privileges: %s"
+exec_background
+ T_FLAG
+ "Run commands on a pty in the background"
+pam_service
+ T_STR
+ "PAM service name to use: %s"
+pam_login_service
+ T_STR
+ "PAM service name to use for login shells: %s"
+pam_setcred
+ T_FLAG
+ "Attempt to establish PAM credentials for the target user"
+pam_session
+ T_FLAG
+ "Create a new PAM session for the command to run in"
+maxseq
+ T_UINT
+ "Maximum I/O log sequence number: %u"
+use_netgroups
+ T_FLAG
+ "Enable sudoers netgroup support"
+sudoedit_checkdir
+ T_FLAG
+ "Check parent directories for writability when editing files with sudoedit"
+sudoedit_follow
+ T_FLAG
+ "Follow symbolic links when editing files with sudoedit"
+always_query_group_plugin
+ T_FLAG
+ "Query the group plugin for unknown system groups"
+netgroup_tuple
+ T_FLAG
+ "Match netgroups based on the entire tuple: user, host and domain"
+ignore_audit_errors
+ T_FLAG
+ "Allow commands to be run even if sudo cannot write to the audit log"
+ignore_iolog_errors
+ T_FLAG
+ "Allow commands to be run even if sudo cannot write to the I/O log"
+ignore_logfile_errors
+ T_FLAG
+ "Allow commands to be run even if sudo cannot write to the log file"
+match_group_by_gid
+ T_FLAG
+ "Resolve groups in sudoers and match on the group ID, not the name"
+syslog_maxlen
+ T_UINT
+ "Log entries larger than this value will be split into multiple syslog messages: %u"
+iolog_user
+ T_STR|T_BOOL
+ "User that will own the I/O log files: %s"
+iolog_group
+ T_STR|T_BOOL
+ "Group that will own the I/O log files: %s"
+iolog_mode
+ T_MODE
+ "File mode to use for the I/O log files: 0%o"
+fdexec
+ T_TUPLE|T_BOOL
+ "Execute commands by file descriptor instead of by path: %s"
+ never digest_only always
+ignore_unknown_defaults
+ T_FLAG
+ "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+command_timeout
+ T_TIMEOUT|T_BOOL
+ "Time in seconds after which the command will be terminated: %u"
+user_command_timeouts
+ T_FLAG
+ "Allow the user to specify a timeout on the command line"
+iolog_flush
+ T_FLAG
+ "Flush I/O log data to disk immediately instead of buffering it"
+syslog_pid
+ T_FLAG
+ "Include the process ID when logging via syslog"
+timestamp_type
+ T_TUPLE
+ "Type of authentication timestamp record: %s"
+ global ppid tty kernel
+authfail_message
+ T_STR
+ "Authentication failure message: %s"
+case_insensitive_user
+ T_FLAG
+ "Ignore case when matching user names"
+case_insensitive_group
+ T_FLAG
+ "Ignore case when matching group names"
diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c
new file mode 100644
index 0000000..4c8c262
--- /dev/null
+++ b/plugins/sudoers/defaults.c
@@ -0,0 +1,1132 @@
+/*
+ * Copyright (c) 1999-2005, 2007-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <pwd.h>
+#include <ctype.h>
+#include <syslog.h>
+
+#include "sudoers.h"
+#include <gram.h>
+
+/*
+ * For converting between syslog numbers and strings.
+ */
+struct strmap {
+ char *name;
+ int num;
+};
+
+static struct strmap facilities[] = {
+#ifdef LOG_AUTHPRIV
+ { "authpriv", LOG_AUTHPRIV },
+#endif
+ { "auth", LOG_AUTH },
+ { "daemon", LOG_DAEMON },
+ { "user", LOG_USER },
+ { "local0", LOG_LOCAL0 },
+ { "local1", LOG_LOCAL1 },
+ { "local2", LOG_LOCAL2 },
+ { "local3", LOG_LOCAL3 },
+ { "local4", LOG_LOCAL4 },
+ { "local5", LOG_LOCAL5 },
+ { "local6", LOG_LOCAL6 },
+ { "local7", LOG_LOCAL7 },
+ { NULL, -1 }
+};
+
+static struct strmap priorities[] = {
+ { "alert", LOG_ALERT },
+ { "crit", LOG_CRIT },
+ { "debug", LOG_DEBUG },
+ { "emerg", LOG_EMERG },
+ { "err", LOG_ERR },
+ { "info", LOG_INFO },
+ { "notice", LOG_NOTICE },
+ { "warning", LOG_WARNING },
+ { "none", -1 },
+ { NULL, -1 }
+};
+
+static struct early_default early_defaults[] = {
+ { I_IGNORE_UNKNOWN_DEFAULTS },
+#ifdef FQDN
+ { I_FQDN, true },
+#else
+ { I_FQDN },
+#endif
+ { I_MATCH_GROUP_BY_GID },
+ { I_GROUP_PLUGIN },
+ { I_RUNAS_DEFAULT },
+ { I_SUDOERS_LOCALE },
+ { -1 }
+};
+
+/*
+ * Local prototypes.
+ */
+static bool store_int(const char *str, union sudo_defs_val *sd_un);
+static bool store_list(const char *str, union sudo_defs_val *sd_un, int op);
+static bool store_mode(const char *str, union sudo_defs_val *sd_un);
+static int store_str(const char *str, union sudo_defs_val *sd_un);
+static bool store_syslogfac(const char *str, union sudo_defs_val *sd_un);
+static bool store_syslogpri(const char *str, union sudo_defs_val *sd_un);
+static bool store_timeout(const char *str, union sudo_defs_val *sd_un);
+static bool store_tuple(const char *str, union sudo_defs_val *sd_un, struct def_values *tuple_vals);
+static bool store_uint(const char *str, union sudo_defs_val *sd_un);
+static bool store_timespec(const char *str, union sudo_defs_val *sd_un);
+static bool list_op(const char *str, size_t, union sudo_defs_val *sd_un, enum list_ops op);
+static const char *logfac2str(int);
+static const char *logpri2str(int);
+
+/*
+ * Table describing compile-time and run-time options.
+ */
+#include <def_data.c>
+
+/*
+ * Print version and configure info.
+ */
+void
+dump_defaults(void)
+{
+ struct sudo_defs_types *cur;
+ struct list_member *item;
+ struct def_values *def;
+ char *desc;
+ debug_decl(dump_defaults, SUDOERS_DEBUG_DEFAULTS)
+
+ for (cur = sudo_defs_table; cur->name; cur++) {
+ if (cur->desc) {
+ desc = _(cur->desc);
+ switch (cur->type & T_MASK) {
+ case T_FLAG:
+ if (cur->sd_un.flag)
+ sudo_printf(SUDO_CONV_INFO_MSG, "%s\n", desc);
+ break;
+ case T_STR:
+ if (cur->sd_un.str) {
+ sudo_printf(SUDO_CONV_INFO_MSG, desc, cur->sd_un.str);
+ sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+ }
+ break;
+ case T_LOGFAC:
+ if (cur->sd_un.ival) {
+ sudo_printf(SUDO_CONV_INFO_MSG, desc,
+ logfac2str(cur->sd_un.ival));
+ sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+ }
+ break;
+ case T_LOGPRI:
+ if (cur->sd_un.ival) {
+ sudo_printf(SUDO_CONV_INFO_MSG, desc,
+ logpri2str(cur->sd_un.ival));
+ sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+ }
+ break;
+ case T_INT:
+ sudo_printf(SUDO_CONV_INFO_MSG, desc, cur->sd_un.ival);
+ sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+ break;
+ case T_UINT:
+ sudo_printf(SUDO_CONV_INFO_MSG, desc, cur->sd_un.uival);
+ sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+ break;
+ case T_TIMESPEC: {
+ /* display timespec in minutes as a double */
+ double d = cur->sd_un.tspec.tv_sec +
+ (cur->sd_un.tspec.tv_nsec / 1000000000.0);
+ sudo_printf(SUDO_CONV_INFO_MSG, desc, d / 60.0);
+ sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+ break;
+ }
+ case T_MODE:
+ sudo_printf(SUDO_CONV_INFO_MSG, desc, cur->sd_un.mode);
+ sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+ break;
+ case T_LIST:
+ if (!SLIST_EMPTY(&cur->sd_un.list)) {
+ sudo_printf(SUDO_CONV_INFO_MSG, "%s\n", desc);
+ SLIST_FOREACH(item, &cur->sd_un.list, entries) {
+ sudo_printf(SUDO_CONV_INFO_MSG,
+ "\t%s\n", item->value);
+ }
+ }
+ break;
+ case T_TIMEOUT:
+ if (cur->sd_un.ival) {
+ sudo_printf(SUDO_CONV_INFO_MSG, desc,
+ cur->sd_un.ival);
+ sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+ }
+ break;
+ case T_TUPLE:
+ for (def = cur->values; def->sval; def++) {
+ if (cur->sd_un.tuple == def->nval) {
+ sudo_printf(SUDO_CONV_INFO_MSG, desc, def->sval);
+ break;
+ }
+ }
+ sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+ break;
+ }
+ }
+ }
+ debug_return;
+}
+
+/*
+ * Find the index of the specified Defaults name in sudo_defs_table[]
+ * On success, returns the matching index or -1 on failure.
+ */
+static int
+find_default(const char *name, const char *file, int lineno, bool quiet)
+{
+ int i;
+ debug_decl(find_default, SUDOERS_DEBUG_DEFAULTS)
+
+ for (i = 0; sudo_defs_table[i].name != NULL; i++) {
+ if (strcmp(name, sudo_defs_table[i].name) == 0)
+ debug_return_int(i);
+ }
+ if (!quiet && !def_ignore_unknown_defaults) {
+ if (lineno > 0) {
+ sudo_warnx(U_("%s:%d unknown defaults entry \"%s\""),
+ file, lineno, name);
+ } else {
+ sudo_warnx(U_("%s: unknown defaults entry \"%s\""),
+ file, name);
+ }
+ }
+ debug_return_int(-1);
+}
+
+/*
+ * Parse a defaults entry, storing the parsed entry in sd_un.
+ * Returns true on success or false on failure.
+ */
+static bool
+parse_default_entry(struct sudo_defs_types *def, const char *val, int op,
+ union sudo_defs_val *sd_un, const char *file, int lineno, bool quiet)
+{
+ int rc;
+ debug_decl(parse_default_entry, SUDOERS_DEBUG_DEFAULTS)
+
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %s:%d %s=%s op=%d",
+ __func__, file, lineno, def->name, val ? val : "", op);
+
+ /*
+ * If no value specified, the boolean flag must be set for non-flags.
+ * Only flags and tuples support boolean "true".
+ */
+ if (val == NULL) {
+ switch (def->type & T_MASK) {
+ case T_FLAG:
+ break;
+ case T_TUPLE:
+ if (ISSET(def->type, T_BOOL))
+ break;
+ /* FALLTHROUGH */
+ case T_LOGFAC:
+ if (op == true) {
+ /* Use default syslog facility if none specified. */
+ val = LOGFAC;
+ }
+ break;
+ default:
+ if (!ISSET(def->type, T_BOOL) || op != false) {
+ if (!quiet) {
+ if (lineno > 0) {
+ sudo_warnx(U_("%s:%d no value specified for \"%s\""),
+ file, lineno, def->name);
+ } else {
+ sudo_warnx(U_("%s: no value specified for \"%s\""),
+ file, def->name);
+ }
+ }
+ debug_return_bool(false);
+ }
+ }
+ }
+
+ switch (def->type & T_MASK) {
+ case T_LOGFAC:
+ rc = store_syslogfac(val, sd_un);
+ break;
+ case T_LOGPRI:
+ rc = store_syslogpri(val, sd_un);
+ break;
+ case T_STR:
+ if (ISSET(def->type, T_PATH) && val != NULL && *val != '/') {
+ if (!quiet) {
+ if (lineno > 0) {
+ sudo_warnx(U_("%s:%d values for \"%s\" must start with a '/'"),
+ file, lineno, def->name);
+ } else {
+ sudo_warnx(U_("%s: values for \"%s\" must start with a '/'"),
+ file, def->name);
+ }
+ }
+ rc = -1;
+ break;
+ }
+ rc = store_str(val, sd_un);
+ break;
+ case T_INT:
+ rc = store_int(val, sd_un);
+ break;
+ case T_UINT:
+ rc = store_uint(val, sd_un);
+ break;
+ case T_MODE:
+ rc = store_mode(val, sd_un);
+ break;
+ case T_FLAG:
+ if (val != NULL) {
+ if (!quiet) {
+ if (lineno > 0) {
+ sudo_warnx(U_("%s:%d option \"%s\" does not take a value"),
+ file, lineno, def->name);
+ } else {
+ sudo_warnx(U_("%s: option \"%s\" does not take a value"),
+ file, def->name);
+ }
+ }
+ rc = -1;
+ break;
+ }
+ sd_un->flag = op;
+ rc = true;
+ break;
+ case T_LIST:
+ rc = store_list(val, sd_un, op);
+ break;
+ case T_TIMEOUT:
+ rc = store_timeout(val, sd_un);
+ break;
+ case T_TUPLE:
+ rc = store_tuple(val, sd_un, def->values);
+ break;
+ case T_TIMESPEC:
+ rc = store_timespec(val, sd_un);
+ break;
+ default:
+ if (!quiet) {
+ if (lineno > 0) {
+ sudo_warnx(U_("%s:%d invalid Defaults type 0x%x for option \"%s\""),
+ file, lineno, def->type, def->name);
+ } else {
+ sudo_warnx(U_("%s: invalid Defaults type 0x%x for option \"%s\""),
+ file, def->type, def->name);
+ }
+ }
+ rc = -1;
+ break;
+ }
+ if (rc == false) {
+ if (!quiet) {
+ if (lineno > 0) {
+ sudo_warnx(U_("%s:%d value \"%s\" is invalid for option \"%s\""),
+ file, lineno, val, def->name);
+ } else {
+ sudo_warnx(U_("%s: value \"%s\" is invalid for option \"%s\""),
+ file, val, def->name);
+ }
+ }
+ }
+
+ debug_return_bool(rc == true);
+}
+
+struct early_default *
+is_early_default(const char *name)
+{
+ struct early_default *early;
+ debug_decl(is_early_default, SUDOERS_DEBUG_DEFAULTS)
+
+ for (early = early_defaults; early->idx != -1; early++) {
+ if (strcmp(name, sudo_defs_table[early->idx].name) == 0)
+ debug_return_ptr(early);
+ }
+ debug_return_ptr(NULL);
+}
+
+static bool
+run_callback(struct sudo_defs_types *def)
+{
+ debug_decl(run_callback, SUDOERS_DEBUG_DEFAULTS)
+
+ if (def->callback == NULL)
+ debug_return_bool(true);
+ debug_return_bool(def->callback(&def->sd_un));
+}
+
+/*
+ * Sets/clears an entry in the defaults structure.
+ * Runs the callback if present on success.
+ */
+bool
+set_default(const char *var, const char *val, int op, const char *file,
+ int lineno, bool quiet)
+{
+ int idx;
+ debug_decl(set_default, SUDOERS_DEBUG_DEFAULTS)
+
+ idx = find_default(var, file, lineno, quiet);
+ if (idx != -1) {
+ /* Set parsed value in sudo_defs_table and run callback (if any). */
+ struct sudo_defs_types *def = &sudo_defs_table[idx];
+ if (parse_default_entry(def, val, op, &def->sd_un, file, lineno, quiet))
+ debug_return_bool(run_callback(def));
+ }
+ debug_return_bool(false);
+}
+
+/*
+ * Like set_default() but stores the matching default value
+ * and does not run callbacks.
+ */
+bool
+set_early_default(const char *var, const char *val, int op, const char *file,
+ int lineno, bool quiet, struct early_default *early)
+{
+ int idx;
+ debug_decl(set_early_default, SUDOERS_DEBUG_DEFAULTS)
+
+ idx = find_default(var, file, lineno, quiet);
+ if (idx != -1) {
+ /* Set parsed value in sudo_defs_table but defer callback (if any). */
+ struct sudo_defs_types *def = &sudo_defs_table[idx];
+ if (parse_default_entry(def, val, op, &def->sd_un, file, lineno, quiet)) {
+ early->run_callback = true;
+ debug_return_bool(true);
+ }
+ }
+ debug_return_bool(false);
+}
+
+/*
+ * Run callbacks for early defaults.
+ */
+bool
+run_early_defaults(void)
+{
+ struct early_default *early;
+ bool ret = true;
+ debug_decl(run_early_defaults, SUDOERS_DEBUG_DEFAULTS)
+
+ for (early = early_defaults; early->idx != -1; early++) {
+ if (early->run_callback) {
+ if (!run_callback(&sudo_defs_table[early->idx]))
+ ret = false;
+ early->run_callback = false;
+ }
+ }
+ debug_return_bool(ret);
+}
+
+static void
+free_defs_val(int type, union sudo_defs_val *sd_un)
+{
+ switch (type & T_MASK) {
+ case T_STR:
+ free(sd_un->str);
+ break;
+ case T_LIST:
+ (void)list_op(NULL, 0, sd_un, freeall);
+ break;
+ }
+ memset(sd_un, 0, sizeof(*sd_un));
+}
+
+/*
+ * Set default options to compiled-in values.
+ * Any of these may be overridden at runtime by a "Defaults" file.
+ */
+bool
+init_defaults(void)
+{
+ static int firsttime = 1;
+ struct sudo_defs_types *def;
+ debug_decl(init_defaults, SUDOERS_DEBUG_DEFAULTS)
+
+ /* Clear any old settings. */
+ if (!firsttime) {
+ for (def = sudo_defs_table; def->name != NULL; def++)
+ free_defs_val(def->type, &def->sd_un);
+ }
+
+ /* First initialize the flags. */
+#ifdef LONG_OTP_PROMPT
+ def_long_otp_prompt = true;
+#endif
+#ifdef IGNORE_DOT_PATH
+ def_ignore_dot = true;
+#endif
+#ifdef ALWAYS_SEND_MAIL
+ def_mail_always = true;
+#endif
+#ifdef SEND_MAIL_WHEN_NO_USER
+ def_mail_no_user = true;
+#endif
+#ifdef SEND_MAIL_WHEN_NO_HOST
+ def_mail_no_host = true;
+#endif
+#ifdef SEND_MAIL_WHEN_NOT_OK
+ def_mail_no_perms = true;
+#endif
+#ifndef NO_LECTURE
+ def_lecture = once;
+#endif
+#ifndef NO_AUTHENTICATION
+ def_authenticate = true;
+#endif
+#ifndef NO_ROOT_SUDO
+ def_root_sudo = true;
+#endif
+#ifdef HOST_IN_LOG
+ def_log_host = true;
+#endif
+#ifdef SHELL_IF_NO_ARGS
+ def_shell_noargs = true;
+#endif
+#ifdef SHELL_SETS_HOME
+ def_set_home = true;
+#endif
+#ifndef DONT_LEAK_PATH_INFO
+ def_path_info = true;
+#endif
+#ifdef USE_INSULTS
+ def_insults = true;
+#endif
+#ifdef FQDN
+ def_fqdn = true;
+#endif
+#ifdef ENV_EDITOR
+ def_env_editor = true;
+#endif
+#ifdef UMASK_OVERRIDE
+ def_umask_override = true;
+#endif
+ def_timestamp_type = TIMESTAMP_TYPE;
+ if ((def_iolog_file = strdup("%{seq}")) == NULL)
+ goto oom;
+ if ((def_iolog_dir = strdup(_PATH_SUDO_IO_LOGDIR)) == NULL)
+ goto oom;
+ if ((def_sudoers_locale = strdup("C")) == NULL)
+ goto oom;
+ def_env_reset = ENV_RESET;
+ def_set_logname = true;
+ def_closefrom = STDERR_FILENO + 1;
+ if ((def_pam_service = strdup("sudo")) == NULL)
+ goto oom;
+#ifdef HAVE_PAM_LOGIN
+ if ((def_pam_login_service = strdup("sudo-i")) == NULL)
+ goto oom;
+#else
+ if ((def_pam_login_service = strdup("sudo")) == NULL)
+ goto oom;
+#endif
+#ifdef NO_PAM_SESSION
+ def_pam_session = false;
+#else
+ def_pam_session = true;
+#endif
+#ifdef HAVE_INNETGR
+ def_use_netgroups = true;
+#endif
+ def_netgroup_tuple = false;
+ def_sudoedit_checkdir = true;
+ def_iolog_mode = S_IRUSR|S_IWUSR;
+ def_fdexec = digest_only;
+
+ /* Syslog options need special care since they both strings and ints */
+#if (LOGGING & SLOG_SYSLOG)
+ (void) store_syslogfac(LOGFAC, &sudo_defs_table[I_SYSLOG].sd_un);
+ (void) store_syslogpri(PRI_SUCCESS, &sudo_defs_table[I_SYSLOG_GOODPRI].sd_un);
+ (void) store_syslogpri(PRI_FAILURE, &sudo_defs_table[I_SYSLOG_BADPRI].sd_un);
+#endif
+
+ /* Password flags also have a string and integer component. */
+ (void) store_tuple("any", &sudo_defs_table[I_LISTPW].sd_un, sudo_defs_table[I_LISTPW].values);
+ (void) store_tuple("all", &sudo_defs_table[I_VERIFYPW].sd_un, sudo_defs_table[I_VERIFYPW].values);
+
+ /* Then initialize the int-like things. */
+#ifdef SUDO_UMASK
+ def_umask = SUDO_UMASK;
+#else
+ def_umask = ACCESSPERMS;
+#endif
+ def_loglinelen = MAXLOGFILELEN;
+ def_timestamp_timeout.tv_sec = TIMEOUT * 60;
+ def_passwd_timeout.tv_sec = PASSWORD_TIMEOUT * 60;
+ def_passwd_tries = TRIES_FOR_PASSWORD;
+#ifdef HAVE_ZLIB_H
+ def_compress_io = true;
+#endif
+ def_ignore_audit_errors = true;
+ def_ignore_iolog_errors = false;
+ def_ignore_logfile_errors = true;
+
+ /* Now do the strings */
+ if ((def_mailto = strdup(MAILTO)) == NULL)
+ goto oom;
+ if ((def_mailsub = strdup(N_(MAILSUBJECT))) == NULL)
+ goto oom;
+ if ((def_badpass_message = strdup(_(INCORRECT_PASSWORD))) == NULL)
+ goto oom;
+ if ((def_lecture_status_dir = strdup(_PATH_SUDO_LECTURE_DIR)) == NULL)
+ goto oom;
+ if ((def_timestampdir = strdup(_PATH_SUDO_TIMEDIR)) == NULL)
+ goto oom;
+ if ((def_passprompt = strdup(_(PASSPROMPT))) == NULL)
+ goto oom;
+ if ((def_runas_default = strdup(RUNAS_DEFAULT)) == NULL)
+ goto oom;
+#ifdef _PATH_SUDO_SENDMAIL
+ if ((def_mailerpath = strdup(_PATH_SUDO_SENDMAIL)) == NULL)
+ goto oom;
+ if ((def_mailerflags = strdup("-t")) == NULL)
+ goto oom;
+#endif
+#if (LOGGING & SLOG_FILE)
+ if ((def_logfile = strdup(_PATH_SUDO_LOGFILE)) == NULL)
+ goto oom;
+#endif
+#ifdef EXEMPTGROUP
+ if ((def_exempt_group = strdup(EXEMPTGROUP)) == NULL)
+ goto oom;
+#endif
+#ifdef SECURE_PATH
+ if ((def_secure_path = strdup(SECURE_PATH)) == NULL)
+ goto oom;
+#endif
+ if ((def_editor = strdup(EDITOR)) == NULL)
+ goto oom;
+ def_set_utmp = true;
+ def_pam_setcred = true;
+ def_syslog_maxlen = MAXSYSLOGLEN;
+ def_case_insensitive_user = true;
+ def_case_insensitive_group = true;
+
+ /* Reset the locale. */
+ if (!firsttime) {
+ if (!sudoers_initlocale(NULL, def_sudoers_locale))
+ goto oom;
+ }
+
+ /* Finally do the lists (currently just environment tables). */
+ if (!init_envtables())
+ goto oom;
+
+ firsttime = 0;
+
+ debug_return_bool(true);
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_bool(false);
+}
+
+/*
+ * Check whether a defaults entry matches the specified type.
+ * Returns true if it matches, else false.
+ */
+static bool
+default_type_matches(struct defaults *d, int what)
+{
+ debug_decl(default_type_matches, SUDOERS_DEBUG_DEFAULTS)
+
+ switch (d->type) {
+ case DEFAULTS:
+ if (ISSET(what, SETDEF_GENERIC))
+ debug_return_bool(true);
+ break;
+ case DEFAULTS_USER:
+ if (ISSET(what, SETDEF_USER))
+ debug_return_bool(true);
+ break;
+ case DEFAULTS_RUNAS:
+ if (ISSET(what, SETDEF_RUNAS))
+ debug_return_bool(true);
+ break;
+ case DEFAULTS_HOST:
+ if (ISSET(what, SETDEF_HOST))
+ debug_return_bool(true);
+ break;
+ case DEFAULTS_CMND:
+ if (ISSET(what, SETDEF_CMND))
+ debug_return_bool(true);
+ break;
+ }
+ debug_return_bool(false);
+}
+
+/*
+ * Check whether a defaults entry's binding matches.
+ * Returns true if it matches, else false.
+ */
+static bool
+default_binding_matches(struct sudoers_parse_tree *parse_tree,
+ struct defaults *d, int what)
+{
+ debug_decl(default_binding_matches, SUDOERS_DEBUG_DEFAULTS)
+
+ switch (d->type) {
+ case DEFAULTS:
+ debug_return_bool(true);
+ break;
+ case DEFAULTS_USER:
+ if (userlist_matches(parse_tree, sudo_user.pw, d->binding) == ALLOW)
+ debug_return_bool(true);
+ break;
+ case DEFAULTS_RUNAS:
+ if (runaslist_matches(parse_tree, d->binding, NULL, NULL, NULL) == ALLOW)
+ debug_return_bool(true);
+ break;
+ case DEFAULTS_HOST:
+ if (hostlist_matches(parse_tree, sudo_user.pw, d->binding) == ALLOW)
+ debug_return_bool(true);
+ break;
+ case DEFAULTS_CMND:
+ if (cmndlist_matches(parse_tree, d->binding) == ALLOW)
+ debug_return_bool(true);
+ break;
+ }
+ debug_return_bool(false);
+}
+
+/*
+ * Update the global defaults based on the given defaults list.
+ * Pass in an OR'd list of which default types to update.
+ */
+bool
+update_defaults(struct sudoers_parse_tree *parse_tree,
+ struct defaults_list *defs, int what, bool quiet)
+{
+ struct defaults *d;
+ bool ret = true;
+ debug_decl(update_defaults, SUDOERS_DEBUG_DEFAULTS)
+
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "what: 0x%02x", what);
+
+ /* If no defaults list specified, use the global one in the parse tree. */
+ if (defs == NULL)
+ defs = &parse_tree->defaults;
+
+ /*
+ * First apply Defaults values marked as early.
+ */
+ TAILQ_FOREACH(d, defs, entries) {
+ struct early_default *early = is_early_default(d->var);
+ if (early == NULL)
+ continue;
+
+ /* Defaults type and binding must match. */
+ if (!default_type_matches(d, what) ||
+ !default_binding_matches(parse_tree, d, what))
+ continue;
+
+ /* Copy the value to sudo_defs_table and mark as early. */
+ if (!set_early_default(d->var, d->val, d->op, d->file, d->lineno,
+ quiet, early))
+ ret = false;
+ }
+ /* Run callbacks for early defaults (if any) */
+ if (!run_early_defaults())
+ ret = false;
+
+ /*
+ * Then set the rest of the defaults.
+ */
+ TAILQ_FOREACH(d, defs, entries) {
+ /* Skip Defaults marked as early, we already did them. */
+ if (is_early_default(d->var))
+ continue;
+
+ /* Defaults type and binding must match. */
+ if (!default_type_matches(d, what) ||
+ !default_binding_matches(parse_tree, d, what))
+ continue;
+
+ /* Copy the value to sudo_defs_table and run callback (if any) */
+ if (!set_default(d->var, d->val, d->op, d->file, d->lineno, quiet))
+ ret = false;
+ }
+ debug_return_bool(ret);
+}
+
+/*
+ * Check all defaults entries without actually setting them.
+ */
+bool
+check_defaults(struct sudoers_parse_tree *parse_tree, bool quiet)
+{
+ struct defaults *d;
+ bool ret = true;
+ int idx;
+ debug_decl(check_defaults, SUDOERS_DEBUG_DEFAULTS)
+
+ TAILQ_FOREACH(d, &parse_tree->defaults, entries) {
+ idx = find_default(d->var, d->file, d->lineno, quiet);
+ if (idx != -1) {
+ struct sudo_defs_types *def = &sudo_defs_table[idx];
+ union sudo_defs_val sd_un;
+ memset(&sd_un, 0, sizeof(sd_un));
+ if (parse_default_entry(def, d->val, d->op, &sd_un, d->file,
+ d->lineno, quiet)) {
+ free_defs_val(def->type, &sd_un);
+ continue;
+ }
+ }
+ /* There was an error in the entry, flag it. */
+ d->error = true;
+ ret = false;
+ }
+ debug_return_bool(ret);
+}
+
+static bool
+store_int(const char *str, union sudo_defs_val *sd_un)
+{
+ const char *errstr;
+ int i;
+ debug_decl(store_int, SUDOERS_DEBUG_DEFAULTS)
+
+ if (str == NULL) {
+ sd_un->ival = 0;
+ } else {
+ i = strtonum(str, INT_MIN, INT_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: %s", str, errstr);
+ debug_return_bool(false);
+ }
+ sd_un->ival = i;
+ }
+ debug_return_bool(true);
+}
+
+static bool
+store_uint(const char *str, union sudo_defs_val *sd_un)
+{
+ const char *errstr;
+ unsigned int u;
+ debug_decl(store_uint, SUDOERS_DEBUG_DEFAULTS)
+
+ if (str == NULL) {
+ sd_un->uival = 0;
+ } else {
+ u = strtonum(str, 0, UINT_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: %s", str, errstr);
+ debug_return_bool(false);
+ }
+ sd_un->uival = u;
+ }
+ debug_return_bool(true);
+}
+
+static bool
+store_timespec(const char *str, union sudo_defs_val *sd_un)
+{
+ struct timespec ts;
+ char sign = '+';
+ int i;
+ debug_decl(store_timespec, SUDOERS_DEBUG_DEFAULTS)
+
+ sudo_timespecclear(&ts);
+ if (str != NULL) {
+ /* Convert from minutes to timespec. */
+ if (*str == '+' || *str == '-')
+ sign = *str++;
+ while (*str != '\0' && *str != '.') {
+ if (!isdigit((unsigned char)*str))
+ debug_return_bool(false); /* invalid number */
+ if (ts.tv_sec > TIME_T_MAX / 10)
+ debug_return_bool(false); /* overflow */
+ ts.tv_sec *= 10;
+ ts.tv_sec += *str++ - '0';
+ }
+ if (*str++ == '.') {
+ /* Convert optional fractional component to nanosecs. */
+ for (i = 100000000; i > 0; i /= 10) {
+ if (*str == '\0')
+ break;
+ if (!isdigit((unsigned char)*str))
+ debug_return_bool(false); /* invalid number */
+ ts.tv_nsec += i * (*str++ - '0');
+ }
+ }
+ /* Convert from minutes to seconds. */
+ if (ts.tv_sec > TIME_T_MAX / 60)
+ debug_return_bool(false); /* overflow */
+ ts.tv_sec *= 60;
+ ts.tv_nsec *= 60;
+ while (ts.tv_nsec >= 1000000000) {
+ ts.tv_sec++;
+ ts.tv_nsec -= 1000000000;
+ }
+ }
+ if (sign == '-') {
+ sd_un->tspec.tv_sec = -ts.tv_sec;
+ sd_un->tspec.tv_nsec = -ts.tv_nsec;
+ } else {
+ sd_un->tspec.tv_sec = ts.tv_sec;
+ sd_un->tspec.tv_nsec = ts.tv_nsec;
+ }
+ debug_return_bool(true);
+}
+
+static bool
+store_tuple(const char *str, union sudo_defs_val *sd_un,
+ struct def_values *tuple_vals)
+{
+ struct def_values *v;
+ debug_decl(store_tuple, SUDOERS_DEBUG_DEFAULTS)
+
+ /*
+ * Look up tuple value by name to find enum def_tuple value.
+ * For negation to work the first element of enum def_tuple
+ * must be equivalent to boolean false.
+ */
+ if (str == NULL) {
+ sd_un->ival = 0;
+ } else {
+ for (v = tuple_vals; v->sval != NULL; v++) {
+ if (strcmp(v->sval, str) == 0) {
+ sd_un->tuple = v->nval;
+ break;
+ }
+ }
+ if (v->sval == NULL)
+ debug_return_bool(false);
+ }
+ debug_return_bool(true);
+}
+
+static int
+store_str(const char *str, union sudo_defs_val *sd_un)
+{
+ debug_decl(store_str, SUDOERS_DEBUG_DEFAULTS)
+
+ free(sd_un->str);
+ if (str == NULL) {
+ sd_un->str = NULL;
+ } else {
+ if ((sd_un->str = strdup(str)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+ }
+ debug_return_int(true);
+}
+
+static bool
+store_list(const char *str, union sudo_defs_val *sd_un, int op)
+{
+ debug_decl(store_list, SUDOERS_DEBUG_DEFAULTS)
+
+ /* Remove all old members. */
+ if (op == false || op == true)
+ (void)list_op(NULL, 0, sd_un, freeall);
+
+ /* Split str into multiple space-separated words and act on each one. */
+ if (str != NULL) {
+ const char *cp, *ep;
+ const char *end = str + strlen(str);
+ const enum list_ops lop = op == '-' ? delete : add;
+
+ for (cp = sudo_strsplit(str, end, " \t", &ep); cp != NULL;
+ cp = sudo_strsplit(NULL, end, " \t", &ep)) {
+ if (!list_op(cp, ep - cp, sd_un, lop))
+ debug_return_bool(false);
+ }
+ }
+ debug_return_bool(true);
+}
+
+static bool
+store_syslogfac(const char *str, union sudo_defs_val *sd_un)
+{
+ struct strmap *fac;
+ debug_decl(store_syslogfac, SUDOERS_DEBUG_DEFAULTS)
+
+ if (str == NULL) {
+ sd_un->ival = false;
+ debug_return_bool(true);
+ }
+ for (fac = facilities; fac->name != NULL; fac++) {
+ if (strcmp(str, fac->name) == 0) {
+ sd_un->ival = fac->num;
+ debug_return_bool(true);
+ }
+ }
+ debug_return_bool(false); /* not found */
+}
+
+static const char *
+logfac2str(int n)
+{
+ struct strmap *fac;
+ debug_decl(logfac2str, SUDOERS_DEBUG_DEFAULTS)
+
+ for (fac = facilities; fac->name && fac->num != n; fac++)
+ continue;
+ debug_return_const_str(fac->name);
+}
+
+static bool
+store_syslogpri(const char *str, union sudo_defs_val *sd_un)
+{
+ struct strmap *pri;
+ debug_decl(store_syslogpri, SUDOERS_DEBUG_DEFAULTS)
+
+ if (str == NULL) {
+ sd_un->ival = -1;
+ debug_return_bool(true);
+ }
+ for (pri = priorities; pri->name != NULL; pri++) {
+ if (strcmp(str, pri->name) == 0) {
+ sd_un->ival = pri->num;
+ debug_return_bool(true);
+ }
+ }
+ debug_return_bool(false); /* not found */
+}
+
+static const char *
+logpri2str(int n)
+{
+ struct strmap *pri;
+ debug_decl(logpri2str, SUDOERS_DEBUG_DEFAULTS)
+
+ for (pri = priorities; pri->name != NULL; pri++) {
+ if (pri->num == n)
+ debug_return_const_str(pri->name);
+ }
+ debug_return_const_str("unknown");
+}
+
+static bool
+store_mode(const char *str, union sudo_defs_val *sd_un)
+{
+ mode_t mode;
+ const char *errstr;
+ debug_decl(store_mode, SUDOERS_DEBUG_DEFAULTS)
+
+ if (str == NULL) {
+ sd_un->mode = ACCESSPERMS;
+ } else {
+ mode = sudo_strtomode(str, &errstr);
+ if (errstr != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s is %s", str, errstr);
+ debug_return_bool(false);
+ }
+ sd_un->mode = mode;
+ }
+ debug_return_bool(true);
+}
+
+static bool
+store_timeout(const char *str, union sudo_defs_val *sd_un)
+{
+ debug_decl(store_mode, SUDOERS_DEBUG_DEFAULTS)
+
+ if (str == NULL) {
+ sd_un->ival = 0;
+ } else {
+ int seconds = parse_timeout(str);
+ if (seconds == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "%s", str);
+ debug_return_bool(false);
+ }
+ sd_un->ival = seconds;
+ }
+ debug_return_bool(true);
+}
+
+static bool
+list_op(const char *str, size_t len, union sudo_defs_val *sd_un,
+ enum list_ops op)
+{
+ struct list_member *cur, *prev = NULL;
+ debug_decl(list_op, SUDOERS_DEBUG_DEFAULTS)
+
+ if (op == freeall) {
+ while ((cur = SLIST_FIRST(&sd_un->list)) != NULL) {
+ SLIST_REMOVE_HEAD(&sd_un->list, entries);
+ free(cur->value);
+ free(cur);
+ }
+ debug_return_bool(true);
+ }
+
+ SLIST_FOREACH(cur, &sd_un->list, entries) {
+ if ((strncmp(cur->value, str, len) == 0 && cur->value[len] == '\0')) {
+
+ if (op == add)
+ debug_return_bool(true); /* already exists */
+
+ /* Delete node */
+ if (prev == NULL)
+ SLIST_REMOVE_HEAD(&sd_un->list, entries);
+ else
+ SLIST_REMOVE_AFTER(prev, entries);
+ free(cur->value);
+ free(cur);
+ break;
+ }
+ prev = cur;
+ }
+
+ /* Add new node to the head of the list. */
+ if (op == add) {
+ cur = calloc(1, sizeof(struct list_member));
+ if (cur == NULL || (cur->value = strndup(str, len)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ free(cur);
+ debug_return_bool(false);
+ }
+ SLIST_INSERT_HEAD(&sd_un->list, cur, entries);
+ }
+ debug_return_bool(true);
+}
diff --git a/plugins/sudoers/defaults.h b/plugins/sudoers/defaults.h
new file mode 100644
index 0000000..4b2db16
--- /dev/null
+++ b/plugins/sudoers/defaults.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 1999-2005, 2008-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#ifndef SUDOERS_DEFAULTS_H
+#define SUDOERS_DEFAULTS_H
+
+#include <time.h>
+#include <def_data.h>
+
+struct list_member {
+ SLIST_ENTRY(list_member) entries;
+ char *value;
+};
+
+SLIST_HEAD(list_members, list_member);
+
+enum list_ops {
+ add,
+ delete,
+ freeall
+};
+
+/* Mapping of tuple string value to enum def_tuple. */
+struct def_values {
+ char *sval; /* string value */
+ enum def_tuple nval;/* numeric value */
+};
+
+union sudo_defs_val {
+ int flag;
+ int ival;
+ unsigned int uival;
+ enum def_tuple tuple;
+ char *str;
+ mode_t mode;
+ struct timespec tspec;
+ struct list_members list;
+};
+
+/*
+ * Structure describing compile-time and run-time options.
+ */
+struct sudo_defs_types {
+ char *name;
+ int type;
+ char *desc;
+ struct def_values *values;
+ bool (*callback)(const union sudo_defs_val *);
+ union sudo_defs_val sd_un;
+};
+
+/*
+ * Defaults values to apply before others.
+ */
+struct early_default {
+ short idx;
+ short run_callback;
+};
+
+/*
+ * Four types of defaults: strings, integers, and flags.
+ * Also, T_INT, T_TIMESPEC or T_STR may be ANDed with T_BOOL to indicate that
+ * a value is not required. Flags are boolean by nature...
+ */
+#undef T_INT
+#define T_INT 0x001
+#undef T_UINT
+#define T_UINT 0x002
+#undef T_STR
+#define T_STR 0x003
+#undef T_FLAG
+#define T_FLAG 0x004
+#undef T_MODE
+#define T_MODE 0x005
+#undef T_LIST
+#define T_LIST 0x006
+#undef T_LOGFAC
+#define T_LOGFAC 0x007
+#undef T_LOGPRI
+#define T_LOGPRI 0x008
+#undef T_TUPLE
+#define T_TUPLE 0x009
+#undef T_TIMESPEC
+#define T_TIMESPEC 0x010
+#undef T_TIMEOUT
+#define T_TIMEOUT 0x020
+#undef T_MASK
+#define T_MASK 0x0FF
+#undef T_BOOL
+#define T_BOOL 0x100
+#undef T_PATH
+#define T_PATH 0x200
+
+/*
+ * Argument to update_defaults()
+ */
+#define SETDEF_GENERIC 0x01
+#define SETDEF_HOST 0x02
+#define SETDEF_USER 0x04
+#define SETDEF_RUNAS 0x08
+#define SETDEF_CMND 0x10
+#define SETDEF_ALL (SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER|SETDEF_RUNAS|SETDEF_CMND)
+
+/*
+ * Prototypes
+ */
+struct defaults_list;
+struct sudoers_parse_tree;
+void dump_default(void);
+bool init_defaults(void);
+struct early_default *is_early_default(const char *name);
+bool run_early_defaults(void);
+bool set_early_default(const char *var, const char *val, int op, const char *file, int lineno, bool quiet, struct early_default *early);
+bool set_default(const char *var, const char *val, int op, const char *file, int lineno, bool quiet);
+bool update_defaults(struct sudoers_parse_tree *parse_tree, struct defaults_list *defs, int what, bool quiet);
+bool check_defaults(struct sudoers_parse_tree *parse_tree, bool quiet);
+
+extern struct sudo_defs_types sudo_defs_table[];
+
+#endif /* SUDOERS_DEFAULTS_H */
diff --git a/plugins/sudoers/digestname.c b/plugins/sudoers/digestname.c
new file mode 100644
index 0000000..a078ede
--- /dev/null
+++ b/plugins/sudoers/digestname.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#include "sudo_compat.h"
+#include "sudo_digest.h"
+#include "sudoers_debug.h"
+#include "parse.h"
+
+const char *
+digest_type_to_name(int digest_type)
+{
+ const char *digest_name;
+ debug_decl(digest_type_to_name, SUDOERS_DEBUG_UTIL)
+
+ switch (digest_type) {
+ case SUDO_DIGEST_SHA224:
+ digest_name = "sha224";
+ break;
+ case SUDO_DIGEST_SHA256:
+ digest_name = "sha256";
+ break;
+ case SUDO_DIGEST_SHA384:
+ digest_name = "sha384";
+ break;
+ case SUDO_DIGEST_SHA512:
+ digest_name = "sha512";
+ break;
+ default:
+ digest_name = "unknown digest";
+ break;
+ }
+ debug_return_const_str(digest_name);
+}
diff --git a/plugins/sudoers/editor.c b/plugins/sudoers/editor.c
new file mode 100644
index 0000000..ec8e7b0
--- /dev/null
+++ b/plugins/sudoers/editor.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2010-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+
+#include "sudoers.h"
+
+/*
+ * Search for the specified editor in the user's PATH, checking
+ * the result against whitelist if non-NULL. An argument vector
+ * suitable for execve() is allocated and stored in argv_out.
+ * If nfiles is non-zero, files[] is added to the end of argv_out.
+ *
+ * Returns the path to be executed on success, else NULL.
+ * The caller is responsible for freeing the returned editor path
+ * as well as the argument vector.
+ */
+static char *
+resolve_editor(const char *ed, size_t edlen, int nfiles, char **files,
+ int *argc_out, char ***argv_out, char * const *whitelist)
+{
+ char **nargv, *editor, *editor_path = NULL;
+ const char *cp, *ep, *tmp;
+ const char *edend = ed + edlen;
+ struct stat user_editor_sb;
+ int nargc;
+ debug_decl(resolve_editor, SUDOERS_DEBUG_UTIL)
+
+ /*
+ * Split editor into an argument vector, including files to edit.
+ * The EDITOR and VISUAL environment variables may contain command
+ * line args so look for those and alloc space for them too.
+ */
+ cp = sudo_strsplit(ed, edend, " \t", &ep);
+ if (cp == NULL)
+ debug_return_str(NULL);
+ editor = strndup(cp, (size_t)(ep - cp));
+ if (editor == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_str(NULL);
+ }
+
+ /* If we can't find the editor in the user's PATH, give up. */
+ if (find_path(editor, &editor_path, &user_editor_sb, getenv("PATH"), 0, whitelist) != FOUND) {
+ free(editor);
+ errno = ENOENT;
+ debug_return_str(NULL);
+ }
+
+ /* Count rest of arguments and allocate editor argv. */
+ for (nargc = 1, tmp = ep; sudo_strsplit(NULL, edend, " \t", &tmp) != NULL; )
+ nargc++;
+ if (nfiles != 0)
+ nargc += nfiles + 1;
+ nargv = reallocarray(NULL, nargc + 1, sizeof(char *));
+ if (nargv == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ free(editor);
+ free(editor_path);
+ debug_return_str(NULL);
+ }
+
+ /* Fill in editor argv (assumes files[] is NULL-terminated). */
+ nargv[0] = editor;
+ for (nargc = 1; (cp = sudo_strsplit(NULL, edend, " \t", &ep)) != NULL; nargc++) {
+ nargv[nargc] = strndup(cp, (size_t)(ep - cp));
+ if (nargv[nargc] == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ free(editor_path);
+ while (nargc--)
+ free(nargv[nargc]);
+ free(nargv);
+ debug_return_str(NULL);
+ }
+ }
+ if (nfiles != 0) {
+ nargv[nargc++] = "--";
+ while (nfiles--)
+ nargv[nargc++] = *files++;
+ }
+ nargv[nargc] = NULL;
+
+ *argc_out = nargc;
+ *argv_out = nargv;
+ debug_return_str(editor_path);
+}
+
+/*
+ * Determine which editor to use based on the SUDO_EDITOR, VISUAL and
+ * EDITOR environment variables as well as the editor path in sudoers.
+ * If env_error is true, an editor environment variable that cannot be
+ * resolved is an error.
+ *
+ * Returns the path to be executed on success, else NULL.
+ * The caller is responsible for freeing the returned editor path
+ * as well as the argument vector.
+ */
+char *
+find_editor(int nfiles, char **files, int *argc_out, char ***argv_out,
+ char * const *whitelist, const char **env_editor, bool env_error)
+{
+ char *ev[3], *editor_path = NULL;
+ unsigned int i;
+ debug_decl(find_editor, SUDOERS_DEBUG_UTIL)
+
+ /*
+ * If any of SUDO_EDITOR, VISUAL or EDITOR are set, choose the first one.
+ */
+ *env_editor = NULL;
+ ev[0] = "SUDO_EDITOR";
+ ev[1] = "VISUAL";
+ ev[2] = "EDITOR";
+ for (i = 0; i < nitems(ev); i++) {
+ char *editor = getenv(ev[i]);
+
+ if (editor != NULL && *editor != '\0') {
+ *env_editor = editor;
+ editor_path = resolve_editor(editor, strlen(editor),
+ nfiles, files, argc_out, argv_out, whitelist);
+ if (editor_path != NULL)
+ break;
+ if (errno != ENOENT)
+ debug_return_str(NULL);
+ }
+ }
+ if (editor_path == NULL) {
+ const char *def_editor_end = def_editor + strlen(def_editor);
+ const char *cp, *ep;
+
+ if (env_error && *env_editor != NULL) {
+ /* User-specified editor could not be found. */
+ debug_return_str(NULL);
+ }
+
+ /* def_editor could be a path, split it up, avoiding strtok() */
+ for (cp = sudo_strsplit(def_editor, def_editor_end, ":", &ep);
+ cp != NULL; cp = sudo_strsplit(NULL, def_editor_end, ":", &ep)) {
+ editor_path = resolve_editor(cp, (size_t)(ep - cp), nfiles,
+ files, argc_out, argv_out, whitelist);
+ if (editor_path != NULL)
+ break;
+ if (errno != ENOENT)
+ debug_return_str(NULL);
+ }
+ }
+
+ debug_return_str(editor_path);
+}
diff --git a/plugins/sudoers/env.c b/plugins/sudoers/env.c
new file mode 100644
index 0000000..0aee73f
--- /dev/null
+++ b/plugins/sudoers/env.c
@@ -0,0 +1,1389 @@
+/*
+ * Copyright (c) 2000-2005, 2007-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#ifdef HAVE_LOGIN_CAP_H
+# include <login_cap.h>
+# ifndef LOGIN_SETENV
+# define LOGIN_SETENV 0
+# endif
+#endif /* HAVE_LOGIN_CAP_H */
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <pwd.h>
+
+#include "sudoers.h"
+
+/*
+ * Flags used in rebuild_env()
+ */
+#undef DID_TERM
+#define DID_TERM 0x00000001
+#undef DID_PATH
+#define DID_PATH 0x00000002
+#undef DID_HOME
+#define DID_HOME 0x00000004
+#undef DID_SHELL
+#define DID_SHELL 0x00000008
+#undef DID_LOGNAME
+#define DID_LOGNAME 0x00000010
+#undef DID_USER
+#define DID_USER 0x00000020
+#undef DID_LOGIN
+#define DID_LOGIN 0x00000040
+#undef DID_MAIL
+#define DID_MAIL 0x00000080
+#undef DID_MAX
+#define DID_MAX 0x0000ffff
+
+#undef KEPT_TERM
+#define KEPT_TERM 0x00010000
+#undef KEPT_PATH
+#define KEPT_PATH 0x00020000
+#undef KEPT_HOME
+#define KEPT_HOME 0x00040000
+#undef KEPT_SHELL
+#define KEPT_SHELL 0x00080000
+#undef KEPT_LOGNAME
+#define KEPT_LOGNAME 0x00100000
+#undef KEPT_USER
+#define KEPT_USER 0x00200000
+#undef KEPT_LOGIN
+#define KEPT_LOGIN 0x00400000
+#undef KEPT_MAIL
+#define KEPT_MAIL 0x00800000
+#undef KEPT_MAX
+#define KEPT_MAX 0xffff0000
+
+/*
+ * AIX sets the LOGIN environment variable too.
+ */
+#ifdef _AIX
+# define KEPT_USER_VARIABLES (KEPT_LOGIN|KEPT_LOGNAME|KEPT_USER)
+#else
+# define KEPT_USER_VARIABLES (KEPT_LOGNAME|KEPT_USER)
+#endif
+
+struct environment {
+ char **envp; /* pointer to the new environment */
+ char **old_envp; /* pointer the old environment we allocated */
+ size_t env_size; /* size of new_environ in char **'s */
+ size_t env_len; /* number of slots used, not counting NULL */
+};
+
+/*
+ * Copy of the sudo-managed environment.
+ */
+static struct environment env;
+
+/*
+ * Default table of "bad" variables to remove from the environment.
+ * XXX - how to omit TERMCAP if it starts with '/'?
+ */
+static const char *initial_badenv_table[] = {
+ "IFS",
+ "CDPATH",
+ "LOCALDOMAIN",
+ "RES_OPTIONS",
+ "HOSTALIASES",
+ "NLSPATH",
+ "PATH_LOCALE",
+ "LD_*",
+ "_RLD*",
+#ifdef __hpux
+ "SHLIB_PATH",
+#endif /* __hpux */
+#ifdef _AIX
+ "LDR_*",
+ "LIBPATH",
+ "AUTHSTATE",
+#endif
+#ifdef __APPLE__
+ "DYLD_*",
+#endif
+#ifdef HAVE_KERB5
+ "KRB5_CONFIG*",
+ "KRB5_KTNAME",
+#endif /* HAVE_KERB5 */
+#ifdef HAVE_SECURID
+ "VAR_ACE",
+ "USR_ACE",
+ "DLC_ACE",
+#endif /* HAVE_SECURID */
+ "TERMINFO", /* terminfo, exclusive path to terminfo files */
+ "TERMINFO_DIRS", /* terminfo, path(s) to terminfo files */
+ "TERMPATH", /* termcap, path(s) to termcap files */
+ "TERMCAP", /* XXX - only if it starts with '/' */
+ "ENV", /* ksh, file to source before script runs */
+ "BASH_ENV", /* bash, file to source before script runs */
+ "PS4", /* bash, prefix for lines in xtrace mode */
+ "GLOBIGNORE", /* bash, globbing patterns to ignore */
+ "BASHOPTS", /* bash, initial "shopt -s" options */
+ "SHELLOPTS", /* bash, initial "set -o" options */
+ "JAVA_TOOL_OPTIONS", /* java, extra command line options */
+ "PERLIO_DEBUG ", /* perl, debugging output file */
+ "PERLLIB", /* perl, search path for modules/includes */
+ "PERL5LIB", /* perl 5, search path for modules/includes */
+ "PERL5OPT", /* perl 5, extra command line options */
+ "PERL5DB", /* perl 5, command used to load debugger */
+ "FPATH", /* ksh, search path for functions */
+ "NULLCMD", /* zsh, command for null file redirection */
+ "READNULLCMD", /* zsh, command for null file redirection */
+ "ZDOTDIR", /* zsh, search path for dot files */
+ "TMPPREFIX", /* zsh, prefix for temporary files */
+ "PYTHONHOME", /* python, module search path */
+ "PYTHONPATH", /* python, search path */
+ "PYTHONINSPECT", /* python, allow inspection */
+ "PYTHONUSERBASE", /* python, per user site-packages directory */
+ "RUBYLIB", /* ruby, library load path */
+ "RUBYOPT", /* ruby, extra command line options */
+ "*=()*", /* bash functions */
+ NULL
+};
+
+/*
+ * Default table of variables to check for '%' and '/' characters.
+ */
+static const char *initial_checkenv_table[] = {
+ "COLORTERM",
+ "LANG",
+ "LANGUAGE",
+ "LC_*",
+ "LINGUAS",
+ "TERM",
+ "TZ",
+ NULL
+};
+
+/*
+ * Default table of variables to preserve in the environment.
+ */
+static const char *initial_keepenv_table[] = {
+ "COLORS",
+ "DISPLAY",
+ "HOSTNAME",
+ "KRB5CCNAME",
+ "LS_COLORS",
+ "PATH",
+ "PS1",
+ "PS2",
+ "XAUTHORITY",
+ "XAUTHORIZATION",
+ NULL
+};
+
+/*
+ * Initialize env based on envp.
+ */
+bool
+env_init(char * const envp[])
+{
+ char * const *ep;
+ size_t len;
+ debug_decl(env_init, SUDOERS_DEBUG_ENV)
+
+ if (envp == NULL) {
+ /* Free the old envp we allocated, if any. */
+ free(env.old_envp);
+
+ /* Reset to initial state but keep a pointer to what we allocated. */
+ env.old_envp = env.envp;
+ env.envp = NULL;
+ env.env_size = 0;
+ env.env_len = 0;
+ } else {
+ /* Make private copy of envp. */
+ for (ep = envp; *ep != NULL; ep++)
+ continue;
+ len = (size_t)(ep - envp);
+
+ env.env_len = len;
+ env.env_size = len + 1 + 128;
+ env.envp = reallocarray(NULL, env.env_size, sizeof(char *));
+ if (env.envp == NULL) {
+ env.env_size = 0;
+ env.env_len = 0;
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+#ifdef ENV_DEBUG
+ memset(env.envp, 0, env.env_size * sizeof(char *));
+#endif
+ memcpy(env.envp, envp, len * sizeof(char *));
+ env.envp[len] = NULL;
+
+ /* Free the old envp we allocated, if any. */
+ free(env.old_envp);
+ env.old_envp = NULL;
+ }
+
+ debug_return_bool(true);
+}
+
+/*
+ * Getter for private copy of the environment.
+ */
+char **
+env_get(void)
+{
+ return env.envp;
+}
+
+/*
+ * Swap the old and new copies of the environment.
+ */
+bool
+env_swap_old(void)
+{
+ char **old_envp;
+
+ if (env.old_envp == NULL)
+ return false;
+ old_envp = env.old_envp;
+ env.old_envp = env.envp;
+ env.envp = old_envp;
+ return true;
+}
+
+/*
+ * Similar to putenv(3) but operates on sudo's private copy of the
+ * environment (not environ) and it always overwrites. The dupcheck param
+ * determines whether we need to verify that the variable is not already set.
+ * Will only overwrite an existing variable if overwrite is set.
+ * Does not include warnings or debugging to avoid recursive calls.
+ */
+static int
+sudo_putenv_nodebug(char *str, bool dupcheck, bool overwrite)
+{
+ char **ep;
+ size_t len;
+ bool found = false;
+
+ /* Make sure there is room for the new entry plus a NULL. */
+ if (env.env_size > 2 && env.env_len > env.env_size - 2) {
+ char **nenvp;
+ size_t nsize;
+
+ if (env.env_size > SIZE_MAX - 128) {
+ sudo_warnx_nodebug(U_("internal error, %s overflow"),
+ "sudo_putenv_nodebug");
+ errno = EOVERFLOW;
+ return -1;
+ }
+ nsize = env.env_size + 128;
+ if (nsize > SIZE_MAX / sizeof(char *)) {
+ sudo_warnx_nodebug(U_("internal error, %s overflow"),
+ "sudo_putenv_nodebug");
+ errno = EOVERFLOW;
+ return -1;
+ }
+ nenvp = reallocarray(env.envp, nsize, sizeof(char *));
+ if (nenvp == NULL)
+ return -1;
+ env.envp = nenvp;
+ env.env_size = nsize;
+#ifdef ENV_DEBUG
+ memset(env.envp + env.env_len, 0,
+ (env.env_size - env.env_len) * sizeof(char *));
+#endif
+ }
+
+#ifdef ENV_DEBUG
+ if (env.envp[env.env_len] != NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+#endif
+
+ if (dupcheck) {
+ len = (strchr(str, '=') - str) + 1;
+ for (ep = env.envp; *ep != NULL; ep++) {
+ if (strncmp(str, *ep, len) == 0) {
+ if (overwrite)
+ *ep = str;
+ found = true;
+ break;
+ }
+ }
+ /* Prune out extra instances of the variable we just overwrote. */
+ if (found && overwrite) {
+ while (*++ep != NULL) {
+ if (strncmp(str, *ep, len) == 0) {
+ char **cur = ep;
+ while ((*cur = *(cur + 1)) != NULL)
+ cur++;
+ ep--;
+ }
+ }
+ env.env_len = ep - env.envp;
+ }
+ }
+
+ if (!found) {
+ ep = env.envp + env.env_len;
+ env.env_len++;
+ *ep++ = str;
+ *ep = NULL;
+ }
+ return 0;
+}
+
+/*
+ * Similar to putenv(3) but operates on sudo's private copy of the
+ * environment (not environ) and it always overwrites. The dupcheck param
+ * determines whether we need to verify that the variable is not already set.
+ * Will only overwrite an existing variable if overwrite is set.
+ */
+static int
+sudo_putenv(char *str, bool dupcheck, bool overwrite)
+{
+ int ret;
+ debug_decl(sudo_putenv, SUDOERS_DEBUG_ENV)
+
+ sudo_debug_printf(SUDO_DEBUG_INFO, "sudo_putenv: %s", str);
+
+ ret = sudo_putenv_nodebug(str, dupcheck, overwrite);
+ if (ret == -1) {
+#ifdef ENV_DEBUG
+ if (env.envp[env.env_len] != NULL)
+ sudo_warnx(U_("sudo_putenv: corrupted envp, length mismatch"));
+#endif
+ }
+ debug_return_int(ret);
+}
+
+/*
+ * Similar to setenv(3) but operates on a private copy of the environment.
+ * The dupcheck param determines whether we need to verify that the variable
+ * is not already set.
+ */
+static int
+sudo_setenv2(const char *var, const char *val, bool dupcheck, bool overwrite)
+{
+ char *estring;
+ size_t esize;
+ int ret = -1;
+ debug_decl(sudo_setenv2, SUDOERS_DEBUG_ENV)
+
+ esize = strlen(var) + 1 + strlen(val) + 1;
+ if ((estring = malloc(esize)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_int(-1);
+ }
+
+ /* Build environment string and insert it. */
+ if (strlcpy(estring, var, esize) >= esize ||
+ strlcat(estring, "=", esize) >= esize ||
+ strlcat(estring, val, esize) >= esize) {
+
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ errno = EOVERFLOW;
+ } else {
+ ret = sudo_putenv(estring, dupcheck, overwrite);
+ }
+ if (ret == -1)
+ free(estring);
+ else
+ sudoers_gc_add(GC_PTR, estring);
+ debug_return_int(ret);
+}
+
+/*
+ * Similar to setenv(3) but operates on a private copy of the environment.
+ */
+int
+sudo_setenv(const char *var, const char *val, int overwrite)
+{
+ return sudo_setenv2(var, val, true, (bool)overwrite);
+}
+
+/*
+ * Similar to setenv(3) but operates on a private copy of the environment.
+ * Does not include warnings or debugging to avoid recursive calls.
+ */
+static int
+sudo_setenv_nodebug(const char *var, const char *val, int overwrite)
+{
+ char *ep, *estring = NULL;
+ const char *cp;
+ size_t esize;
+ int ret = -1;
+
+ if (var == NULL || *var == '\0') {
+ errno = EINVAL;
+ goto done;
+ }
+
+ /*
+ * POSIX says a var name with '=' is an error but BSD
+ * just ignores the '=' and anything after it.
+ */
+ for (cp = var; *cp && *cp != '='; cp++)
+ continue;
+ esize = (size_t)(cp - var) + 2;
+ if (val) {
+ esize += strlen(val); /* glibc treats a NULL val as "" */
+ }
+
+ /* Allocate and fill in estring. */
+ if ((estring = ep = malloc(esize)) == NULL)
+ goto done;
+ for (cp = var; *cp && *cp != '='; cp++)
+ *ep++ = *cp;
+ *ep++ = '=';
+ if (val) {
+ for (cp = val; *cp; cp++)
+ *ep++ = *cp;
+ }
+ *ep = '\0';
+
+ ret = sudo_putenv_nodebug(estring, true, overwrite);
+done:
+ if (ret == -1)
+ free(estring);
+ else
+ sudoers_gc_add(GC_PTR, estring);
+ return ret;
+}
+
+/*
+ * Similar to unsetenv(3) but operates on a private copy of the environment.
+ * Does not include warnings or debugging to avoid recursive calls.
+ */
+static int
+sudo_unsetenv_nodebug(const char *var)
+{
+ char **ep = env.envp;
+ size_t len;
+
+ if (ep == NULL || var == NULL || *var == '\0' || strchr(var, '=') != NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ len = strlen(var);
+ while (*ep != NULL) {
+ if (strncmp(var, *ep, len) == 0 && (*ep)[len] == '=') {
+ /* Found it; shift remainder + NULL over by one. */
+ char **cur = ep;
+ while ((*cur = *(cur + 1)) != NULL)
+ cur++;
+ env.env_len--;
+ /* Keep going, could be multiple instances of the var. */
+ } else {
+ ep++;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Similar to unsetenv(3) but operates on a private copy of the environment.
+ */
+int
+sudo_unsetenv(const char *name)
+{
+ int ret;
+ debug_decl(sudo_unsetenv, SUDOERS_DEBUG_ENV)
+
+ sudo_debug_printf(SUDO_DEBUG_INFO, "sudo_unsetenv: %s", name);
+
+ ret = sudo_unsetenv_nodebug(name);
+
+ debug_return_int(ret);
+}
+
+/*
+ * Similar to getenv(3) but operates on a private copy of the environment.
+ * Does not include warnings or debugging to avoid recursive calls.
+ */
+static char *
+sudo_getenv_nodebug(const char *name)
+{
+ char **ep, *val = NULL;
+ size_t namelen = 0;
+
+ if (env.env_len != 0) {
+ /* For BSD compatibility, treat '=' in name like end of string. */
+ while (name[namelen] != '\0' && name[namelen] != '=')
+ namelen++;
+ for (ep = env.envp; *ep != NULL; ep++) {
+ if (strncmp(*ep, name, namelen) == 0 && (*ep)[namelen] == '=') {
+ val = *ep + namelen + 1;
+ break;
+ }
+ }
+ }
+ return val;
+}
+
+/*
+ * Similar to getenv(3) but operates on a private copy of the environment.
+ */
+char *
+sudo_getenv(const char *name)
+{
+ char *val;
+ debug_decl(sudo_getenv, SUDOERS_DEBUG_ENV)
+
+ sudo_debug_printf(SUDO_DEBUG_INFO, "sudo_getenv: %s", name);
+
+ val = sudo_getenv_nodebug(name);
+
+ debug_return_str(val);
+}
+
+/*
+ * Check for var against patterns in the specified environment list.
+ * Returns true if the variable was found, else false.
+ */
+static bool
+matches_env_list(const char *var, struct list_members *list, bool *full_match)
+{
+ struct list_member *cur;
+ bool is_logname = false;
+ debug_decl(matches_env_list, SUDOERS_DEBUG_ENV)
+
+ switch (*var) {
+ case 'L':
+ if (strncmp(var, "LOGNAME=", 8) == 0)
+ is_logname = true;
+#ifdef _AIX
+ else if (strncmp(var, "LOGIN=", 6) == 0)
+ is_logname = true;
+#endif
+ break;
+ case 'U':
+ if (strncmp(var, "USER=", 5) == 0)
+ is_logname = true;
+ break;
+ }
+
+ if (is_logname) {
+ /*
+ * We treat LOGIN, LOGNAME and USER specially.
+ * If one is preserved/deleted we want to preserve/delete them all.
+ */
+ SLIST_FOREACH(cur, list, entries) {
+ if (matches_env_pattern(cur->value, "LOGNAME", full_match) ||
+#ifdef _AIX
+ matches_env_pattern(cur->value, "LOGIN", full_match) ||
+#endif
+ matches_env_pattern(cur->value, "USER", full_match))
+ debug_return_bool(true);
+ }
+ } else {
+ SLIST_FOREACH(cur, list, entries) {
+ if (matches_env_pattern(cur->value, var, full_match))
+ debug_return_bool(true);
+ }
+ }
+ debug_return_bool(false);
+}
+
+/*
+ * Check the env_delete blacklist.
+ * Returns true if the variable was found, else false.
+ */
+static bool
+matches_env_delete(const char *var)
+{
+ bool full_match; /* unused */
+ debug_decl(matches_env_delete, SUDOERS_DEBUG_ENV)
+
+ /* Skip anything listed in env_delete. */
+ debug_return_bool(matches_env_list(var, &def_env_delete, &full_match));
+}
+
+/*
+ * Sanity-check the TZ environment variable.
+ * On many systems it is possible to set this to a pathname.
+ */
+static bool
+tz_is_sane(const char *tzval)
+{
+ const char *cp;
+ char lastch;
+ debug_decl(tz_is_sane, SUDOERS_DEBUG_ENV)
+
+ /* tzcode treats a value beginning with a ':' as a path. */
+ if (tzval[0] == ':')
+ tzval++;
+
+ /* Reject fully-qualified TZ that doesn't being with the zoneinfo dir. */
+ if (tzval[0] == '/') {
+#ifdef _PATH_ZONEINFO
+ if (strncmp(tzval, _PATH_ZONEINFO, sizeof(_PATH_ZONEINFO) - 1) != 0 ||
+ tzval[sizeof(_PATH_ZONEINFO) - 1] != '/')
+ debug_return_bool(false);
+#else
+ /* Assume the worst. */
+ debug_return_bool(false);
+#endif
+ }
+
+ /*
+ * Make sure TZ only contains printable non-space characters
+ * and does not contain a '..' path element.
+ */
+ lastch = '/';
+ for (cp = tzval; *cp != '\0'; cp++) {
+ if (isspace((unsigned char)*cp) || !isprint((unsigned char)*cp))
+ debug_return_bool(false);
+ if (lastch == '/' && cp[0] == '.' && cp[1] == '.' &&
+ (cp[2] == '/' || cp[2] == '\0'))
+ debug_return_bool(false);
+ lastch = *cp;
+ }
+
+ /* Reject extra long TZ values (even if not a path). */
+ if ((size_t)(cp - tzval) >= PATH_MAX)
+ debug_return_bool(false);
+
+ debug_return_bool(true);
+}
+
+/*
+ * Apply the env_check list.
+ * Returns true if the variable is allowed, false if denied
+ * or -1 if no match.
+ */
+static int
+matches_env_check(const char *var, bool *full_match)
+{
+ int keepit = -1;
+ debug_decl(matches_env_check, SUDOERS_DEBUG_ENV)
+
+ /* Skip anything listed in env_check that includes '/' or '%'. */
+ if (matches_env_list(var, &def_env_check, full_match)) {
+ if (strncmp(var, "TZ=", 3) == 0) {
+ /* Special case for TZ */
+ keepit = tz_is_sane(var + 3);
+ } else {
+ const char *val = strchr(var, '=');
+ if (val != NULL)
+ keepit = !strpbrk(++val, "/%");
+ }
+ }
+ debug_return_int(keepit);
+}
+
+/*
+ * Check the env_keep list.
+ * Returns true if the variable is allowed else false.
+ */
+static bool
+matches_env_keep(const char *var, bool *full_match)
+{
+ bool keepit = false;
+ debug_decl(matches_env_keep, SUDOERS_DEBUG_ENV)
+
+ /* Preserve SHELL variable for "sudo -s". */
+ if (ISSET(sudo_mode, MODE_SHELL) && strncmp(var, "SHELL=", 6) == 0) {
+ keepit = true;
+ } else if (matches_env_list(var, &def_env_keep, full_match)) {
+ keepit = true;
+ }
+ debug_return_bool(keepit);
+}
+
+/*
+ * Look up var in the env_delete and env_check.
+ * Returns true if we should delete the variable, else false.
+ */
+static bool
+env_should_delete(const char *var)
+{
+ int delete_it;
+ bool full_match = false;
+ debug_decl(env_should_delete, SUDOERS_DEBUG_ENV);
+
+ delete_it = matches_env_delete(var);
+ if (!delete_it)
+ delete_it = matches_env_check(var, &full_match) == false;
+
+ sudo_debug_printf(SUDO_DEBUG_INFO, "delete %s: %s",
+ var, delete_it ? "YES" : "NO");
+ debug_return_bool(delete_it);
+}
+
+/*
+ * Lookup var in the env_check and env_keep lists.
+ * Returns true if the variable is allowed else false.
+ */
+static bool
+env_should_keep(const char *var)
+{
+ int keepit;
+ bool full_match = false;
+ const char *cp;
+ debug_decl(env_should_keep, SUDOERS_DEBUG_ENV)
+
+ keepit = matches_env_check(var, &full_match);
+ if (keepit == -1)
+ keepit = matches_env_keep(var, &full_match);
+
+ /* Skip bash functions unless we matched on the value as well as name. */
+ if (keepit && !full_match) {
+ if ((cp = strchr(var, '=')) != NULL) {
+ if (strncmp(cp, "=() ", 4) == 0)
+ keepit = false;
+ }
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO, "keep %s: %s",
+ var, keepit == true ? "YES" : "NO");
+ debug_return_bool(keepit == true);
+}
+
+#ifdef HAVE_PAM
+/*
+ * Merge another environment with our private copy.
+ * Only overwrite an existing variable if it is not
+ * being preserved from the user's environment.
+ * Returns true on success or false on failure.
+ */
+bool
+env_merge(char * const envp[])
+{
+ char * const *ep;
+ bool ret = true;
+ debug_decl(env_merge, SUDOERS_DEBUG_ENV)
+
+ for (ep = envp; *ep != NULL; ep++) {
+ /* XXX - avoid checking value here, should only check name */
+ bool overwrite = def_env_reset ? !env_should_keep(*ep) : env_should_delete(*ep);
+ if (sudo_putenv(*ep, true, overwrite) == -1) {
+ /* XXX cannot undo on failure */
+ ret = false;
+ break;
+ }
+ }
+ debug_return_bool(ret);
+}
+#endif /* HAVE_PAM */
+
+static void
+env_update_didvar(const char *ep, unsigned int *didvar)
+{
+ switch (*ep) {
+ case 'H':
+ if (strncmp(ep, "HOME=", 5) == 0)
+ SET(*didvar, DID_HOME);
+ break;
+ case 'L':
+#ifdef _AIX
+ if (strncmp(ep, "LOGIN=", 8) == 0)
+ SET(*didvar, DID_LOGIN);
+#endif
+ if (strncmp(ep, "LOGNAME=", 8) == 0)
+ SET(*didvar, DID_LOGNAME);
+ break;
+ case 'M':
+ if (strncmp(ep, "MAIL=", 5) == 0)
+ SET(*didvar, DID_MAIL);
+ break;
+ case 'P':
+ if (strncmp(ep, "PATH=", 5) == 0)
+ SET(*didvar, DID_PATH);
+ break;
+ case 'S':
+ if (strncmp(ep, "SHELL=", 6) == 0)
+ SET(*didvar, DID_SHELL);
+ break;
+ case 'T':
+ if (strncmp(ep, "TERM=", 5) == 0)
+ SET(*didvar, DID_TERM);
+ break;
+ case 'U':
+ if (strncmp(ep, "USER=", 5) == 0)
+ SET(*didvar, DID_USER);
+ break;
+ }
+}
+
+#define CHECK_PUTENV(a, b, c) do { \
+ if (sudo_putenv((a), (b), (c)) == -1) \
+ goto bad; \
+} while (0)
+
+#define CHECK_SETENV2(a, b, c, d) do { \
+ if (sudo_setenv2((a), (b), (c), (d)) == -1) \
+ goto bad; \
+} while (0)
+
+/*
+ * Build a new environment and ether clear potentially dangerous
+ * variables from the old one or start with a clean slate.
+ * Also adds sudo-specific variables (SUDO_*).
+ * Returns true on success or false on failure.
+ */
+bool
+rebuild_env(void)
+{
+ char **ep, *cp, *ps1;
+ char idbuf[MAX_UID_T_LEN + 1];
+ unsigned int didvar;
+ bool reset_home = false;
+ debug_decl(rebuild_env, SUDOERS_DEBUG_ENV)
+
+ /*
+ * Either clean out the environment or reset to a safe default.
+ */
+ ps1 = NULL;
+ didvar = 0;
+ env.env_len = 0;
+ env.env_size = 128;
+ free(env.old_envp);
+ env.old_envp = env.envp;
+ env.envp = reallocarray(NULL, env.env_size, sizeof(char *));
+ if (env.envp == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ env.env_size = 0;
+ goto bad;
+ }
+#ifdef ENV_DEBUG
+ memset(env.envp, 0, env.env_size * sizeof(char *));
+#else
+ env.envp[0] = NULL;
+#endif
+
+ /* Reset HOME based on target user if configured to. */
+ if (ISSET(sudo_mode, MODE_RUN)) {
+ if (def_always_set_home ||
+ ISSET(sudo_mode, MODE_RESET_HOME | MODE_LOGIN_SHELL) ||
+ (ISSET(sudo_mode, MODE_SHELL) && def_set_home))
+ reset_home = true;
+ }
+
+ if (def_env_reset || ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
+ /*
+ * If starting with a fresh environment, initialize it based on
+ * /etc/environment or login.conf. For "sudo -i" we want those
+ * variables to override the invoking user's environment, so we
+ * defer reading them until later.
+ */
+ if (!ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
+#ifdef HAVE_LOGIN_CAP_H
+ /* Insert login class environment variables. */
+ if (login_class) {
+ login_cap_t *lc = login_getclass(login_class);
+ if (lc != NULL) {
+ setusercontext(lc, runas_pw, runas_pw->pw_uid,
+ LOGIN_SETPATH|LOGIN_SETENV);
+ login_close(lc);
+ }
+ }
+#endif /* HAVE_LOGIN_CAP_H */
+#if defined(_AIX) || (defined(__linux__) && !defined(HAVE_PAM))
+ /* Insert system-wide environment variables. */
+ read_env_file(_PATH_ENVIRONMENT, true, false);
+#endif
+ for (ep = env.envp; *ep; ep++)
+ env_update_didvar(*ep, &didvar);
+ }
+
+ /* Pull in vars we want to keep from the old environment. */
+ for (ep = env.old_envp; *ep; ep++) {
+ bool keepit;
+
+ /*
+ * Look up the variable in the env_check and env_keep lists.
+ */
+ keepit = env_should_keep(*ep);
+
+ /*
+ * Do SUDO_PS1 -> PS1 conversion.
+ * This must happen *after* env_should_keep() is called.
+ */
+ if (strncmp(*ep, "SUDO_PS1=", 9) == 0)
+ ps1 = *ep + 5;
+
+ if (keepit) {
+ /* Preserve variable. */
+ CHECK_PUTENV(*ep, true, false);
+ env_update_didvar(*ep, &didvar);
+ }
+ }
+ didvar |= didvar << 16; /* convert DID_* to KEPT_* */
+
+ /*
+ * Add in defaults. In -i mode these come from the runas user,
+ * otherwise they may be from the user's environment (depends
+ * on sudoers options).
+ */
+ if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
+ CHECK_SETENV2("SHELL", runas_pw->pw_shell,
+ ISSET(didvar, DID_SHELL), true);
+#ifdef _AIX
+ CHECK_SETENV2("LOGIN", runas_pw->pw_name,
+ ISSET(didvar, DID_LOGIN), true);
+#endif
+ CHECK_SETENV2("LOGNAME", runas_pw->pw_name,
+ ISSET(didvar, DID_LOGNAME), true);
+ CHECK_SETENV2("USER", runas_pw->pw_name,
+ ISSET(didvar, DID_USER), true);
+ } else {
+ /* We will set LOGNAME later in the def_set_logname case. */
+ if (!def_set_logname) {
+#ifdef _AIX
+ if (!ISSET(didvar, DID_LOGIN))
+ CHECK_SETENV2("LOGIN", user_name, false, true);
+#endif
+ if (!ISSET(didvar, DID_LOGNAME))
+ CHECK_SETENV2("LOGNAME", user_name, false, true);
+ if (!ISSET(didvar, DID_USER))
+ CHECK_SETENV2("USER", user_name, false, true);
+ }
+ }
+
+ /* If we didn't keep HOME, reset it based on target user. */
+ if (!ISSET(didvar, KEPT_HOME))
+ reset_home = true;
+
+ /*
+ * Set MAIL to target user in -i mode or if MAIL is not preserved
+ * from user's environment.
+ */
+ if (ISSET(sudo_mode, MODE_LOGIN_SHELL) || !ISSET(didvar, KEPT_MAIL)) {
+ if (_PATH_MAILDIR[sizeof(_PATH_MAILDIR) - 2] == '/') {
+ if (asprintf(&cp, "MAIL=%s%s", _PATH_MAILDIR, runas_pw->pw_name) == -1)
+ goto bad;
+ } else {
+ if (asprintf(&cp, "MAIL=%s/%s", _PATH_MAILDIR, runas_pw->pw_name) == -1)
+ goto bad;
+ }
+ if (sudo_putenv(cp, ISSET(didvar, DID_MAIL), true) == -1) {
+ free(cp);
+ goto bad;
+ }
+ sudoers_gc_add(GC_PTR, cp);
+ }
+ } else {
+ /*
+ * Copy environ entries as long as they don't match env_delete or
+ * env_check.
+ */
+ for (ep = env.old_envp; *ep; ep++) {
+ /* Add variable unless it matches a black list. */
+ if (!env_should_delete(*ep)) {
+ if (strncmp(*ep, "SUDO_PS1=", 9) == 0)
+ ps1 = *ep + 5;
+ else if (strncmp(*ep, "SHELL=", 6) == 0)
+ SET(didvar, DID_SHELL);
+ else if (strncmp(*ep, "PATH=", 5) == 0)
+ SET(didvar, DID_PATH);
+ else if (strncmp(*ep, "TERM=", 5) == 0)
+ SET(didvar, DID_TERM);
+ CHECK_PUTENV(*ep, true, false);
+ }
+ }
+ }
+ /* Replace the PATH envariable with a secure one? */
+ if (def_secure_path && !user_is_exempt()) {
+ CHECK_SETENV2("PATH", def_secure_path, true, true);
+ SET(didvar, DID_PATH);
+ }
+
+ /*
+ * Set LOGIN, LOGNAME, and USER to target if "set_logname" is not
+ * disabled. We skip this if we are running a login shell (because
+ * they have already been set).
+ */
+ if (def_set_logname && !ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
+ if ((didvar & KEPT_USER_VARIABLES) == 0) {
+ /* Nothing preserved, set them all. */
+#ifdef _AIX
+ CHECK_SETENV2("LOGIN", runas_pw->pw_name, true, true);
+#endif
+ CHECK_SETENV2("LOGNAME", runas_pw->pw_name, true, true);
+ CHECK_SETENV2("USER", runas_pw->pw_name, true, true);
+ } else if ((didvar & KEPT_USER_VARIABLES) != KEPT_USER_VARIABLES) {
+ /*
+ * Preserved some of LOGIN, LOGNAME, USER but not all.
+ * Make the unset ones match so we don't end up with some
+ * set to the invoking user and others set to the runas user.
+ */
+ if (ISSET(didvar, KEPT_LOGNAME))
+ cp = sudo_getenv("LOGNAME");
+#ifdef _AIX
+ else if (ISSET(didvar, KEPT_LOGIN))
+ cp = sudo_getenv("LOGIN");
+#endif
+ else if (ISSET(didvar, KEPT_USER))
+ cp = sudo_getenv("USER");
+ else
+ cp = NULL;
+ if (cp != NULL) {
+#ifdef _AIX
+ if (!ISSET(didvar, KEPT_LOGIN))
+ CHECK_SETENV2("LOGIN", cp, true, true);
+#endif
+ if (!ISSET(didvar, KEPT_LOGNAME))
+ CHECK_SETENV2("LOGNAME", cp, true, true);
+ if (!ISSET(didvar, KEPT_USER))
+ CHECK_SETENV2("USER", cp, true, true);
+ }
+ }
+ }
+
+ /* Set $HOME to target user if not preserving user's value. */
+ if (reset_home)
+ CHECK_SETENV2("HOME", runas_pw->pw_dir, true, true);
+
+ /* Provide default values for $SHELL, $TERM and $PATH if not set. */
+ if (!ISSET(didvar, DID_SHELL))
+ CHECK_SETENV2("SHELL", runas_pw->pw_shell, false, false);
+ if (!ISSET(didvar, DID_TERM))
+ CHECK_PUTENV("TERM=unknown", false, false);
+ if (!ISSET(didvar, DID_PATH))
+ CHECK_SETENV2("PATH", _PATH_STDPATH, false, true);
+
+ /* Set PS1 if SUDO_PS1 is set. */
+ if (ps1 != NULL)
+ CHECK_PUTENV(ps1, true, true);
+
+ /* Add the SUDO_COMMAND envariable (cmnd + args). */
+ if (user_args) {
+ if (asprintf(&cp, "SUDO_COMMAND=%s %s", user_cmnd, user_args) == -1)
+ goto bad;
+ if (sudo_putenv(cp, true, true) == -1) {
+ free(cp);
+ goto bad;
+ }
+ sudoers_gc_add(GC_PTR, cp);
+ } else {
+ CHECK_SETENV2("SUDO_COMMAND", user_cmnd, true, true);
+ }
+
+ /* Add the SUDO_USER, SUDO_UID, SUDO_GID environment variables. */
+ CHECK_SETENV2("SUDO_USER", user_name, true, true);
+ snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int) user_uid);
+ CHECK_SETENV2("SUDO_UID", idbuf, true, true);
+ snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int) user_gid);
+ CHECK_SETENV2("SUDO_GID", idbuf, true, true);
+
+ debug_return_bool(true);
+
+bad:
+ sudo_warn(U_("unable to rebuild the environment"));
+ debug_return_bool(false);
+}
+
+/*
+ * Insert all environment variables in envp into the private copy
+ * of the environment.
+ * Returns true on success or false on failure.
+ */
+bool
+insert_env_vars(char * const envp[])
+{
+ char * const *ep;
+ bool ret = true;
+ debug_decl(insert_env_vars, SUDOERS_DEBUG_ENV)
+
+ /* Add user-specified environment variables. */
+ if (envp != NULL) {
+ for (ep = envp; *ep != NULL; ep++) {
+ /* XXX - no undo on failure */
+ if (sudo_putenv(*ep, true, true) == -1) {
+ ret = false;
+ break;
+ }
+ }
+ }
+ debug_return_bool(ret);
+}
+
+/*
+ * Validate the list of environment variables passed in on the command
+ * line against env_delete, env_check, and env_keep.
+ * Calls log_warning() if any specified variables are not allowed.
+ * Returns true if allowed, else false.
+ */
+bool
+validate_env_vars(char * const env_vars[])
+{
+ char * const *ep;
+ char *eq, errbuf[4096];
+ bool okvar, ret = true;
+ debug_decl(validate_env_vars, SUDOERS_DEBUG_ENV)
+
+ if (env_vars == NULL)
+ debug_return_bool(true); /* nothing to do */
+
+ /* Add user-specified environment variables. */
+ errbuf[0] = '\0';
+ for (ep = env_vars; *ep != NULL; ep++) {
+ if (def_secure_path && !user_is_exempt() &&
+ strncmp(*ep, "PATH=", 5) == 0) {
+ okvar = false;
+ } else if (def_env_reset) {
+ okvar = env_should_keep(*ep);
+ } else {
+ okvar = !env_should_delete(*ep);
+ }
+ if (okvar == false) {
+ /* Not allowed, add to error string, allocating as needed. */
+ if ((eq = strchr(*ep, '=')) != NULL)
+ *eq = '\0';
+ if (errbuf[0] != '\0')
+ (void)strlcat(errbuf, ", ", sizeof(errbuf));
+ if (strlcat(errbuf, *ep, sizeof(errbuf)) >= sizeof(errbuf)) {
+ errbuf[sizeof(errbuf) - 4] = '\0';
+ (void)strlcat(errbuf, "...", sizeof(errbuf));
+ }
+ if (eq != NULL)
+ *eq = '=';
+ }
+ }
+ if (errbuf[0] != '\0') {
+ /* XXX - audit? */
+ log_warningx(0,
+ N_("sorry, you are not allowed to set the following environment variables: %s"), errbuf);
+ ret = false;
+ }
+ debug_return_bool(ret);
+}
+
+/*
+ * Read in /etc/environment ala AIX and Linux.
+ * Lines may be in either of three formats:
+ * NAME=VALUE
+ * NAME="VALUE"
+ * NAME='VALUE'
+ * with an optional "export" prefix so the shell can source the file.
+ * Invalid lines, blank lines, or lines consisting solely of a comment
+ * character are skipped.
+ */
+bool
+read_env_file(const char *path, bool overwrite, bool restricted)
+{
+ FILE *fp;
+ bool ret = true;
+ char *cp, *var, *val, *line = NULL;
+ size_t var_len, val_len, linesize = 0;
+ debug_decl(read_env_file, SUDOERS_DEBUG_ENV)
+
+ if ((fp = fopen(path, "r")) == NULL) {
+ if (errno != ENOENT)
+ ret = false;
+ debug_return_bool(ret);
+ }
+
+ while (sudo_parseln(&line, &linesize, NULL, fp, PARSELN_CONT_IGN) != -1) {
+ /* Skip blank or comment lines */
+ if (*(var = line) == '\0')
+ continue;
+
+ /* Skip optional "export " */
+ if (strncmp(var, "export", 6) == 0 && isspace((unsigned char) var[6])) {
+ var += 7;
+ while (isspace((unsigned char) *var)) {
+ var++;
+ }
+ }
+
+ /* Must be of the form name=["']value['"] */
+ for (val = var; *val != '\0' && *val != '='; val++)
+ continue;
+ if (var == val || *val != '=')
+ continue;
+ var_len = (size_t)(val - var);
+ val_len = strlen(++val);
+
+ /*
+ * If the env file is restricted, apply env_check and env_keep
+ * when env_reset is set or env_delete when it is not.
+ */
+ if (restricted) {
+ if (def_env_reset ? !env_should_keep(var) : env_should_delete(var))
+ continue;
+ }
+
+ /* Strip leading and trailing single/double quotes */
+ if ((val[0] == '\'' || val[0] == '\"') && val[0] == val[val_len - 1]) {
+ val[val_len - 1] = '\0';
+ val++;
+ val_len -= 2;
+ }
+
+ if ((cp = malloc(var_len + 1 + val_len + 1)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ /* XXX - no undo on failure */
+ ret = false;
+ break;
+ }
+ memcpy(cp, var, var_len + 1); /* includes '=' */
+ memcpy(cp + var_len + 1, val, val_len + 1); /* includes NUL */
+
+ sudoers_gc_add(GC_PTR, cp);
+ if (sudo_putenv(cp, true, overwrite) == -1) {
+ /* XXX - no undo on failure */
+ ret = false;
+ break;
+ }
+ }
+ free(line);
+ fclose(fp);
+
+ debug_return_bool(ret);
+}
+
+bool
+init_envtables(void)
+{
+ struct list_member *cur;
+ const char **p;
+ debug_decl(init_envtables, SUDOERS_DEBUG_ENV)
+
+ /* Fill in the "env_delete" list. */
+ for (p = initial_badenv_table; *p; p++) {
+ cur = calloc(1, sizeof(struct list_member));
+ if (cur == NULL || (cur->value = strdup(*p)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ free(cur);
+ debug_return_bool(false);
+ }
+ SLIST_INSERT_HEAD(&def_env_delete, cur, entries);
+ }
+
+ /* Fill in the "env_check" list. */
+ for (p = initial_checkenv_table; *p; p++) {
+ cur = calloc(1, sizeof(struct list_member));
+ if (cur == NULL || (cur->value = strdup(*p)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ free(cur);
+ debug_return_bool(false);
+ }
+ SLIST_INSERT_HEAD(&def_env_check, cur, entries);
+ }
+
+ /* Fill in the "env_keep" list. */
+ for (p = initial_keepenv_table; *p; p++) {
+ cur = calloc(1, sizeof(struct list_member));
+ if (cur == NULL || (cur->value = strdup(*p)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ free(cur);
+ debug_return_bool(false);
+ }
+ SLIST_INSERT_HEAD(&def_env_keep, cur, entries);
+ }
+ debug_return_bool(true);
+}
+
+int
+sudoers_hook_getenv(const char *name, char **value, void *closure)
+{
+ static bool in_progress = false; /* avoid recursion */
+
+ if (in_progress || env.envp == NULL)
+ return SUDO_HOOK_RET_NEXT;
+
+ in_progress = true;
+
+ /* Hack to make GNU gettext() find the sudoers locale when needed. */
+ if (*name == 'L' && sudoers_getlocale() == SUDOERS_LOCALE_SUDOERS) {
+ if (strcmp(name, "LANGUAGE") == 0 || strcmp(name, "LANG") == 0) {
+ *value = NULL;
+ goto done;
+ }
+ if (strcmp(name, "LC_ALL") == 0 || strcmp(name, "LC_MESSAGES") == 0) {
+ *value = def_sudoers_locale;
+ goto done;
+ }
+ }
+
+ *value = sudo_getenv_nodebug(name);
+done:
+ in_progress = false;
+ return SUDO_HOOK_RET_STOP;
+}
+
+int
+sudoers_hook_putenv(char *string, void *closure)
+{
+ static bool in_progress = false; /* avoid recursion */
+
+ if (in_progress || env.envp == NULL)
+ return SUDO_HOOK_RET_NEXT;
+
+ in_progress = true;
+ sudo_putenv_nodebug(string, true, true);
+ in_progress = false;
+ return SUDO_HOOK_RET_STOP;
+}
+
+int
+sudoers_hook_setenv(const char *name, const char *value, int overwrite, void *closure)
+{
+ static bool in_progress = false; /* avoid recursion */
+
+ if (in_progress || env.envp == NULL)
+ return SUDO_HOOK_RET_NEXT;
+
+ in_progress = true;
+ sudo_setenv_nodebug(name, value, overwrite);
+ in_progress = false;
+ return SUDO_HOOK_RET_STOP;
+}
+
+int
+sudoers_hook_unsetenv(const char *name, void *closure)
+{
+ static bool in_progress = false; /* avoid recursion */
+
+ if (in_progress || env.envp == NULL)
+ return SUDO_HOOK_RET_NEXT;
+
+ in_progress = true;
+ sudo_unsetenv_nodebug(name);
+ in_progress = false;
+ return SUDO_HOOK_RET_STOP;
+}
diff --git a/plugins/sudoers/env_pattern.c b/plugins/sudoers/env_pattern.c
new file mode 100644
index 0000000..a74515b
--- /dev/null
+++ b/plugins/sudoers/env_pattern.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "sudoers.h"
+
+/* extern for regress tests */
+bool
+matches_env_pattern(const char *pattern, const char *var, bool *full_match)
+{
+ size_t len, sep_pos;
+ bool iswild = false, match = false;
+ bool saw_sep = false;
+ const char *cp;
+ debug_decl(matches_env_pattern, SUDOERS_DEBUG_ENV)
+
+ /* Locate position of the '=' separator in var=value. */
+ sep_pos = strcspn(var, "=");
+
+ /* Locate '*' wildcard and compute len. */
+ for (cp = pattern; *cp != '\0'; cp++) {
+ if (*cp == '*') {
+ iswild = true;
+ break;
+ }
+ }
+ len = (size_t)(cp - pattern);
+
+ if (iswild) {
+ /* Match up to the '*' wildcard. */
+ if (strncmp(pattern, var, len) == 0) {
+ while (*cp != '\0') {
+ if (*cp == '*') {
+ /* Collapse sequential '*'s */
+ do {
+ cp++;
+ } while (*cp == '*');
+ /* A '*' at the end of a pattern matches anything. */
+ if (*cp == '\0') {
+ match = true;
+ break;
+ }
+ /* Keep track of whether we matched an equal sign. */
+ if (*cp == '=')
+ saw_sep = true;
+ /* Look for first match of text after the '*' */
+ while ((saw_sep || len != sep_pos) &&
+ var[len] != '\0' && var[len] != *cp)
+ len++;
+ }
+ if (var[len] != *cp)
+ break;
+ cp++;
+ len++;
+ }
+ if (*cp == '\0' && (len == sep_pos || var[len] == '\0'))
+ match = true;
+ }
+ } else {
+ if (strncmp(pattern, var, len) == 0 &&
+ (len == sep_pos || var[len] == '\0')) {
+ match = true;
+ }
+ }
+ if (match)
+ *full_match = len > sep_pos + 1;
+ debug_return_bool(match);
+}
diff --git a/plugins/sudoers/file.c b/plugins/sudoers/file.c
new file mode 100644
index 0000000..a8b02b3
--- /dev/null
+++ b/plugins/sudoers/file.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2004-2005, 2007-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <ctype.h>
+#include <grp.h>
+#include <pwd.h>
+#include <time.h>
+
+#include "sudoers.h"
+#include "parse.h"
+#include "sudo_lbuf.h"
+#include <gram.h>
+
+struct sudo_file_handle {
+ FILE *fp;
+ struct sudoers_parse_tree parse_tree;
+};
+
+static int
+sudo_file_close(struct sudo_nss *nss)
+{
+ debug_decl(sudo_file_close, SUDOERS_DEBUG_NSS)
+ struct sudo_file_handle *handle = nss->handle;
+
+ if (handle != NULL) {
+ fclose(handle->fp);
+ sudoersin = NULL;
+
+ free_parse_tree(&handle->parse_tree);
+ free(handle);
+ nss->handle = NULL;
+ }
+
+ debug_return_int(0);
+}
+
+static int
+sudo_file_open(struct sudo_nss *nss)
+{
+ debug_decl(sudo_file_open, SUDOERS_DEBUG_NSS)
+ struct sudo_file_handle *handle;
+
+ if (def_ignore_local_sudoers)
+ debug_return_int(-1);
+
+ if (nss->handle != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "%s: called with non-NULL handle %p", __func__, nss->handle);
+ sudo_file_close(nss);
+ }
+
+ handle = malloc(sizeof(*handle));
+ if (handle != NULL) {
+ handle->fp = open_sudoers(sudoers_file, false, NULL);
+ if (handle->fp != NULL) {
+ init_parse_tree(&handle->parse_tree);
+ } else {
+ free(handle);
+ handle = NULL;
+ }
+ }
+ nss->handle = handle;
+ debug_return_int(nss->handle ? 0 : -1);
+}
+
+/*
+ * Parse and return the specified sudoers file.
+ */
+static struct sudoers_parse_tree *
+sudo_file_parse(struct sudo_nss *nss)
+{
+ debug_decl(sudo_file_close, SUDOERS_DEBUG_NSS)
+ struct sudo_file_handle *handle = nss->handle;
+
+ if (handle == NULL || handle->fp == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "%s: called with NULL %s",
+ __func__, handle ? "file pointer" : "handle");
+ debug_return_ptr(NULL);
+ }
+
+ sudoersin = handle->fp;
+ if (sudoersparse() != 0 || parse_error) {
+ if (errorlineno != -1) {
+ log_warningx(SLOG_SEND_MAIL, N_("parse error in %s near line %d"),
+ errorfile, errorlineno);
+ } else {
+ log_warningx(SLOG_SEND_MAIL, N_("parse error in %s"), errorfile);
+ }
+ debug_return_ptr(NULL);
+ }
+
+ /* Move parsed sudoers policy to nss handle. */
+ reparent_parse_tree(&handle->parse_tree);
+
+ debug_return_ptr(&handle->parse_tree);
+}
+
+/*
+ * No need for explicit sudoers queries, the parse function handled it.
+ */
+static int
+sudo_file_query(struct sudo_nss *nss, struct passwd *pw)
+{
+ debug_decl(sudo_file_query, SUDOERS_DEBUG_NSS)
+ debug_return_int(0);
+}
+
+/*
+ * No need to get defaults for sudoers file, the parse function handled it.
+ */
+static int
+sudo_file_getdefs(struct sudo_nss *nss)
+{
+ debug_decl(sudo_file_getdefs, SUDOERS_DEBUG_NSS)
+ debug_return_int(0);
+}
+
+/* sudo_nss implementation */
+struct sudo_nss sudo_nss_file = {
+ { NULL, NULL },
+ sudo_file_open,
+ sudo_file_close,
+ sudo_file_parse,
+ sudo_file_query,
+ sudo_file_getdefs
+};
diff --git a/plugins/sudoers/filedigest.c b/plugins/sudoers/filedigest.c
new file mode 100644
index 0000000..764e35e
--- /dev/null
+++ b/plugins/sudoers/filedigest.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2013-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "sudoers.h"
+#include "sudo_digest.h"
+
+unsigned char *
+sudo_filedigest(int fd, const char *file, int digest_type, size_t *digest_len)
+{
+ unsigned char *file_digest = NULL;
+ unsigned char buf[32 * 1024];
+ struct sudo_digest *dig = NULL;
+ FILE *fp = NULL;
+ size_t nread;
+ int fd2;
+ debug_decl(sudo_filedigest, SUDOERS_DEBUG_UTIL)
+
+ *digest_len = sudo_digest_getlen(digest_type);
+ if (*digest_len == (size_t)-1) {
+ sudo_warnx(U_("unsupported digest type %d for %s"), digest_type, file);
+ goto bad;
+ }
+
+ if ((dig = sudo_digest_alloc(digest_type)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto bad;
+ }
+
+ if ((fd2 = dup(fd)) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "unable to dup %s: %s",
+ file, strerror(errno));
+ goto bad;
+ }
+ if ((fp = fdopen(fd2, "r")) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "unable to fdopen %s: %s",
+ file, strerror(errno));
+ close(fd2);
+ goto bad;
+ }
+ if ((file_digest = malloc(*digest_len)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto bad;
+ }
+
+ while ((nread = fread(buf, 1, sizeof(buf), fp)) != 0) {
+ sudo_digest_update(dig, buf, nread);
+ }
+ if (ferror(fp)) {
+ sudo_warnx(U_("%s: read error"), file);
+ goto bad;
+ }
+ sudo_digest_final(dig, file_digest);
+ sudo_digest_free(dig);
+ fclose(fp);
+
+ debug_return_ptr(file_digest);
+bad:
+ sudo_digest_free(dig);
+ free(file_digest);
+ if (fp != NULL)
+ fclose(fp);
+ debug_return_ptr(NULL);
+}
diff --git a/plugins/sudoers/find_path.c b/plugins/sudoers/find_path.c
new file mode 100644
index 0000000..70b9218
--- /dev/null
+++ b/plugins/sudoers/find_path.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2010-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+
+#include "sudoers.h"
+
+/*
+ * Check the given command against the specified whitelist (NULL-terminated).
+ * On success, rewrites cmnd based on the whitelist and returns true.
+ * On failure, returns false.
+ */
+static bool
+cmnd_allowed(char *cmnd, size_t cmnd_size, struct stat *cmnd_sbp,
+ char * const *whitelist)
+{
+ const char *cmnd_base;
+ char * const *wl;
+ debug_decl(cmnd_allowed, SUDOERS_DEBUG_UTIL)
+
+ if (!sudo_goodpath(cmnd, cmnd_sbp))
+ debug_return_bool(false);
+
+ if (whitelist == NULL)
+ debug_return_bool(true); /* nothing to check */
+
+ /* We compare the base names to avoid excessive stat()ing. */
+ if ((cmnd_base = strrchr(cmnd, '/')) == NULL)
+ debug_return_bool(false); /* can't happen */
+ cmnd_base++;
+
+ for (wl = whitelist; *wl != NULL; wl++) {
+ struct stat sb;
+ const char *base;
+
+ if ((base = strrchr(*wl, '/')) == NULL)
+ continue; /* XXX - warn? */
+ base++;
+
+ if (strcmp(cmnd_base, base) != 0)
+ continue;
+
+ if (sudo_goodpath(*wl, &sb) &&
+ sb.st_dev == cmnd_sbp->st_dev && sb.st_ino == cmnd_sbp->st_ino) {
+ /* Overwrite cmnd with safe version from whitelist. */
+ if (strlcpy(cmnd, *wl, cmnd_size) < cmnd_size)
+ return true;
+ debug_return_bool(true);
+ }
+ }
+ debug_return_bool(false);
+}
+
+/*
+ * This function finds the full pathname for a command and
+ * stores it in a statically allocated array, filling in a pointer
+ * to the array. Returns FOUND if the command was found, NOT_FOUND
+ * if it was not found, or NOT_FOUND_DOT if it would have been found
+ * but it is in '.' and IGNORE_DOT is set.
+ * The caller is responsible for freeing the output file.
+ */
+int
+find_path(const char *infile, char **outfile, struct stat *sbp,
+ const char *path, int ignore_dot, char * const *whitelist)
+{
+ char command[PATH_MAX];
+ const char *cp, *ep, *pathend;
+ bool found = false;
+ bool checkdot = false;
+ int len;
+ debug_decl(find_path, SUDOERS_DEBUG_UTIL)
+
+ /*
+ * If we were given a fully qualified or relative path
+ * there is no need to look at $PATH.
+ */
+ if (strchr(infile, '/') != NULL) {
+ if (strlcpy(command, infile, sizeof(command)) >= sizeof(command)) {
+ errno = ENAMETOOLONG;
+ debug_return_int(NOT_FOUND_ERROR);
+ }
+ found = cmnd_allowed(command, sizeof(command), sbp, whitelist);
+ goto done;
+ }
+
+ if (path == NULL)
+ debug_return_int(NOT_FOUND);
+
+ pathend = path + strlen(path);
+ for (cp = sudo_strsplit(path, pathend, ":", &ep); cp != NULL;
+ cp = sudo_strsplit(NULL, pathend, ":", &ep)) {
+
+ /*
+ * Search current dir last if it is in PATH.
+ * This will miss sneaky things like using './' or './/' (XXX)
+ */
+ if (cp == ep || (*cp == '.' && cp + 1 == ep)) {
+ checkdot = 1;
+ continue;
+ }
+
+ /*
+ * Resolve the path and exit the loop if found.
+ */
+ len = snprintf(command, sizeof(command), "%.*s/%s",
+ (int)(ep - cp), cp, infile);
+ if (len <= 0 || (size_t)len >= sizeof(command)) {
+ errno = ENAMETOOLONG;
+ debug_return_int(NOT_FOUND_ERROR);
+ }
+ found = cmnd_allowed(command, sizeof(command), sbp, whitelist);
+ if (found)
+ break;
+ }
+
+ /*
+ * Check current dir if dot was in the PATH
+ */
+ if (!found && checkdot) {
+ len = snprintf(command, sizeof(command), "./%s", infile);
+ if (len <= 0 || (size_t)len >= sizeof(command)) {
+ errno = ENAMETOOLONG;
+ debug_return_int(NOT_FOUND_ERROR);
+ }
+ found = cmnd_allowed(command, sizeof(command), sbp, whitelist);
+ if (found && ignore_dot)
+ debug_return_int(NOT_FOUND_DOT);
+ }
+
+done:
+ if (found) {
+ if ((*outfile = strdup(command)) == NULL)
+ debug_return_int(NOT_FOUND_ERROR);
+ debug_return_int(FOUND);
+ }
+ debug_return_int(NOT_FOUND);
+}
diff --git a/plugins/sudoers/fmtsudoers.c b/plugins/sudoers/fmtsudoers.c
new file mode 100644
index 0000000..8c73f9c
--- /dev/null
+++ b/plugins/sudoers/fmtsudoers.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 2004-2005, 2007-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <time.h>
+
+#include "sudoers.h"
+#include "sudo_lbuf.h"
+#include <gram.h>
+
+/*
+ * Write the contents of a struct member to the lbuf.
+ * If alias_type is not UNSPEC, expand aliases using that type with
+ * the specified separator (which must not be NULL in the UNSPEC case).
+ */
+static bool
+sudoers_format_member_int(struct sudo_lbuf *lbuf,
+ struct sudoers_parse_tree *parse_tree, char *name, int type, bool negated,
+ const char *separator, int alias_type)
+{
+ struct alias *a;
+ struct member *m;
+ struct sudo_command *c;
+ debug_decl(sudoers_format_member_int, SUDOERS_DEBUG_UTIL)
+
+ switch (type) {
+ case ALL:
+ sudo_lbuf_append(lbuf, "%sALL", negated ? "!" : "");
+ break;
+ case MYSELF:
+ sudo_lbuf_append(lbuf, "%s%s", negated ? "!" : "",
+ user_name ? user_name : "");
+ break;
+ case COMMAND:
+ c = (struct sudo_command *) name;
+ if (c->digest != NULL) {
+ sudo_lbuf_append(lbuf, "%s:%s ",
+ digest_type_to_name(c->digest->digest_type),
+ c->digest->digest_str);
+ }
+ if (negated)
+ sudo_lbuf_append(lbuf, "!");
+ sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED" \t", "%s", c->cmnd);
+ if (c->args) {
+ sudo_lbuf_append(lbuf, " ");
+ sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", c->args);
+ }
+ break;
+ case USERGROUP:
+ /* Special case for %#gid, %:non-unix-group, %:#non-unix-gid */
+ if (strpbrk(name, " \t") == NULL) {
+ if (*++name == ':') {
+ name++;
+ sudo_lbuf_append(lbuf, "%s", "%:");
+ } else {
+ sudo_lbuf_append(lbuf, "%s", "%");
+ }
+ }
+ goto print_word;
+ case ALIAS:
+ if (alias_type != UNSPEC) {
+ if ((a = alias_get(parse_tree, name, alias_type)) != NULL) {
+ TAILQ_FOREACH(m, &a->members, entries) {
+ if (m != TAILQ_FIRST(&a->members))
+ sudo_lbuf_append(lbuf, "%s", separator);
+ sudoers_format_member_int(lbuf, parse_tree, m->name,
+ m->type, negated ? !m->negated : m->negated,
+ separator, alias_type);
+ }
+ alias_put(a);
+ break;
+ }
+ }
+ /* FALLTHROUGH */
+ default:
+ print_word:
+ /* Do not quote UID/GID, all others get quoted. */
+ if (name[0] == '#' &&
+ name[strspn(name + 1, "0123456789") + 1] == '\0') {
+ sudo_lbuf_append(lbuf, "%s%s", negated ? "!" : "", name);
+ } else {
+ if (strpbrk(name, " \t") != NULL) {
+ sudo_lbuf_append(lbuf, "%s\"", negated ? "!" : "");
+ sudo_lbuf_append_quoted(lbuf, "\"", "%s", name);
+ sudo_lbuf_append(lbuf, "\"");
+ } else {
+ sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s%s",
+ negated ? "!" : "", name);
+ }
+ }
+ break;
+ }
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+bool
+sudoers_format_member(struct sudo_lbuf *lbuf,
+ struct sudoers_parse_tree *parse_tree, struct member *m,
+ const char *separator, int alias_type)
+{
+ return sudoers_format_member_int(lbuf, parse_tree, m->name, m->type,
+ m->negated, separator, alias_type);
+}
+
+/*
+ * Store a defaults entry as a command tag.
+ */
+bool
+sudoers_defaults_to_tags(const char *var, const char *val, int op,
+ struct cmndtag *tags)
+{
+ bool ret = true;
+ debug_decl(sudoers_defaults_to_tags, SUDOERS_DEBUG_UTIL)
+
+ if (op == true || op == false) {
+ if (strcmp(var, "authenticate") == 0) {
+ tags->nopasswd = op == false;
+ } else if (strcmp(var, "sudoedit_follow") == 0) {
+ tags->follow = op == true;
+ } else if (strcmp(var, "log_input") == 0) {
+ tags->log_input = op == true;
+ } else if (strcmp(var, "log_output") == 0) {
+ tags->log_output = op == true;
+ } else if (strcmp(var, "noexec") == 0) {
+ tags->noexec = op == true;
+ } else if (strcmp(var, "setenv") == 0) {
+ tags->setenv = op == true;
+ } else if (strcmp(var, "mail_all_cmnds") == 0 ||
+ strcmp(var, "mail_always") == 0 ||
+ strcmp(var, "mail_no_perms") == 0) {
+ tags->send_mail = op == true;
+ } else {
+ ret = false;
+ }
+ } else {
+ ret = false;
+ }
+ debug_return_bool(ret);
+}
+
+/*
+ * Convert a defaults list to command tags.
+ */
+bool
+sudoers_defaults_list_to_tags(struct defaults_list *defs, struct cmndtag *tags)
+{
+ bool ret = true;
+ struct defaults *d;
+ debug_decl(sudoers_defaults_list_to_tags, SUDOERS_DEBUG_UTIL)
+
+ TAGS_INIT(*tags);
+ if (defs != NULL) {
+ TAILQ_FOREACH(d, defs, entries) {
+ if (!sudoers_defaults_to_tags(d->var, d->val, d->op, tags)) {
+ if (d->val != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_WARN,
+ "unable to convert defaults to tag: %s%s%s", d->var,
+ d->op == '+' ? "+=" : d->op == '-' ? "-=" : "=", d->val);
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_WARN,
+ "unable to convert defaults to tag: %s%s%s",
+ d->op == false ? "!" : "", d->var, "");
+ }
+ ret = false;
+ }
+ }
+ }
+ debug_return_bool(ret);
+}
+
+#define FIELD_CHANGED(ocs, ncs, fld) \
+ ((ocs) == NULL || (ncs)->fld != (ocs)->fld)
+
+#define TAG_CHANGED(ocs, ncs, t, tt) \
+ (TAG_SET((t).tt) && FIELD_CHANGED(ocs, ncs, tags.tt))
+
+/*
+ * Write a cmndspec to lbuf in sudoers format.
+ */
+bool
+sudoers_format_cmndspec(struct sudo_lbuf *lbuf,
+ struct sudoers_parse_tree *parse_tree, struct cmndspec *cs,
+ struct cmndspec *prev_cs, struct cmndtag tags, bool expand_aliases)
+{
+ debug_decl(sudoers_format_cmndspec, SUDOERS_DEBUG_UTIL)
+
+ /* Merge privilege-level tags with cmndspec tags. */
+ TAGS_MERGE(tags, cs->tags);
+
+#ifdef HAVE_PRIV_SET
+ if (cs->privs != NULL && FIELD_CHANGED(prev_cs, cs, privs))
+ sudo_lbuf_append(lbuf, "PRIVS=\"%s\" ", cs->privs);
+ if (cs->limitprivs != NULL && FIELD_CHANGED(prev_cs, cs, limitprivs))
+ sudo_lbuf_append(lbuf, "LIMITPRIVS=\"%s\" ", cs->limitprivs);
+#endif /* HAVE_PRIV_SET */
+#ifdef HAVE_SELINUX
+ if (cs->role != NULL && FIELD_CHANGED(prev_cs, cs, role))
+ sudo_lbuf_append(lbuf, "ROLE=%s ", cs->role);
+ if (cs->type != NULL && FIELD_CHANGED(prev_cs, cs, type))
+ sudo_lbuf_append(lbuf, "TYPE=%s ", cs->type);
+#endif /* HAVE_SELINUX */
+ if (cs->timeout > 0 && FIELD_CHANGED(prev_cs, cs, timeout)) {
+ char numbuf[(((sizeof(int) * 8) + 2) / 3) + 2];
+ snprintf(numbuf, sizeof(numbuf), "%d", cs->timeout);
+ sudo_lbuf_append(lbuf, "TIMEOUT=%s ", numbuf);
+ }
+ if (cs->notbefore != UNSPEC && FIELD_CHANGED(prev_cs, cs, notbefore)) {
+ char buf[sizeof("CCYYMMDDHHMMSSZ")];
+ struct tm *tm = gmtime(&cs->notbefore);
+ snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ sudo_lbuf_append(lbuf, "NOTBEFORE=%s ", buf);
+ }
+ if (cs->notafter != UNSPEC && FIELD_CHANGED(prev_cs, cs, notafter)) {
+ char buf[sizeof("CCYYMMDDHHMMSSZ")];
+ struct tm *tm = gmtime(&cs->notafter);
+ snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ sudo_lbuf_append(lbuf, "NOTAFTER=%s ", buf);
+ }
+ if (TAG_CHANGED(prev_cs, cs, tags, setenv))
+ sudo_lbuf_append(lbuf, tags.setenv ? "SETENV: " : "NOSETENV: ");
+ if (TAG_CHANGED(prev_cs, cs, tags, noexec))
+ sudo_lbuf_append(lbuf, tags.noexec ? "NOEXEC: " : "EXEC: ");
+ if (TAG_CHANGED(prev_cs, cs, tags, nopasswd))
+ sudo_lbuf_append(lbuf, tags.nopasswd ? "NOPASSWD: " : "PASSWD: ");
+ if (TAG_CHANGED(prev_cs, cs, tags, log_input))
+ sudo_lbuf_append(lbuf, tags.log_input ? "LOG_INPUT: " : "NOLOG_INPUT: ");
+ if (TAG_CHANGED(prev_cs, cs, tags, log_output))
+ sudo_lbuf_append(lbuf, tags.log_output ? "LOG_OUTPUT: " : "NOLOG_OUTPUT: ");
+ if (TAG_CHANGED(prev_cs, cs, tags, send_mail))
+ sudo_lbuf_append(lbuf, tags.send_mail ? "MAIL: " : "NOMAIL: ");
+ if (TAG_CHANGED(prev_cs, cs, tags, follow))
+ sudo_lbuf_append(lbuf, tags.follow ? "FOLLOW: " : "NOFOLLOW: ");
+ sudoers_format_member(lbuf, parse_tree, cs->cmnd, ", ",
+ expand_aliases ? CMNDALIAS : UNSPEC);
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+/*
+ * Write a privilege to lbuf in sudoers format.
+ */
+bool
+sudoers_format_privilege(struct sudo_lbuf *lbuf,
+ struct sudoers_parse_tree *parse_tree, struct privilege *priv,
+ bool expand_aliases)
+{
+ struct cmndspec *cs, *prev_cs;
+ struct cmndtag tags;
+ struct member *m;
+ debug_decl(sudoers_format_privilege, SUDOERS_DEBUG_UTIL)
+
+ /* Convert per-privilege defaults to tags. */
+ sudoers_defaults_list_to_tags(&priv->defaults, &tags);
+
+ /* Print hosts list. */
+ TAILQ_FOREACH(m, &priv->hostlist, entries) {
+ if (m != TAILQ_FIRST(&priv->hostlist))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, parse_tree, m, ", ",
+ expand_aliases ? HOSTALIAS : UNSPEC);
+ }
+
+ /* Print commands. */
+ sudo_lbuf_append(lbuf, " = ");
+ prev_cs = NULL;
+ TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
+ if (prev_cs == NULL || RUNAS_CHANGED(cs, prev_cs)) {
+ if (cs != TAILQ_FIRST(&priv->cmndlist))
+ sudo_lbuf_append(lbuf, ", ");
+ if (cs->runasuserlist != NULL || cs->runasgrouplist != NULL)
+ sudo_lbuf_append(lbuf, "(");
+ if (cs->runasuserlist != NULL) {
+ TAILQ_FOREACH(m, cs->runasuserlist, entries) {
+ if (m != TAILQ_FIRST(cs->runasuserlist))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, parse_tree, m, ", ",
+ expand_aliases ? RUNASALIAS : UNSPEC);
+ }
+ }
+ if (cs->runasgrouplist != NULL) {
+ sudo_lbuf_append(lbuf, " : ");
+ TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
+ if (m != TAILQ_FIRST(cs->runasgrouplist))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, parse_tree, m, ", ",
+ expand_aliases ? RUNASALIAS : UNSPEC);
+ }
+ }
+ if (cs->runasuserlist != NULL || cs->runasgrouplist != NULL)
+ sudo_lbuf_append(lbuf, ") ");
+ } else if (cs != TAILQ_FIRST(&priv->cmndlist)) {
+ sudo_lbuf_append(lbuf, ", ");
+ }
+ sudoers_format_cmndspec(lbuf, parse_tree, cs, prev_cs, tags,
+ expand_aliases);
+ prev_cs = cs;
+ }
+
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+/*
+ * Write a userspec to lbuf in sudoers format.
+ */
+bool
+sudoers_format_userspec(struct sudo_lbuf *lbuf,
+ struct sudoers_parse_tree *parse_tree,
+ struct userspec *us, bool expand_aliases)
+{
+ struct privilege *priv;
+ struct sudoers_comment *comment;
+ struct member *m;
+ debug_decl(sudoers_format_userspec, SUDOERS_DEBUG_UTIL)
+
+ /* Print comments (if any). */
+ STAILQ_FOREACH(comment, &us->comments, entries) {
+ sudo_lbuf_append(lbuf, "# %s\n", comment->str);
+ }
+
+ /* Print users list. */
+ TAILQ_FOREACH(m, &us->users, entries) {
+ if (m != TAILQ_FIRST(&us->users))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, parse_tree, m, ", ",
+ expand_aliases ? USERALIAS : UNSPEC);
+ }
+
+ TAILQ_FOREACH(priv, &us->privileges, entries) {
+ if (priv != TAILQ_FIRST(&us->privileges))
+ sudo_lbuf_append(lbuf, " : ");
+ else
+ sudo_lbuf_append(lbuf, " ");
+ if (!sudoers_format_privilege(lbuf, parse_tree, priv, expand_aliases))
+ break;
+ }
+ sudo_lbuf_append(lbuf, "\n");
+
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+/*
+ * Write a userspec_list to lbuf in sudoers format.
+ */
+bool
+sudoers_format_userspecs(struct sudo_lbuf *lbuf,
+ struct sudoers_parse_tree *parse_tree, const char *separator,
+ bool expand_aliases, bool flush)
+{
+ struct userspec *us;
+ debug_decl(sudoers_format_userspecs, SUDOERS_DEBUG_UTIL)
+
+ TAILQ_FOREACH(us, &parse_tree->userspecs, entries) {
+ if (separator != NULL && us != TAILQ_FIRST(&parse_tree->userspecs))
+ sudo_lbuf_append(lbuf, "%s", separator);
+ if (!sudoers_format_userspec(lbuf, parse_tree, us, expand_aliases))
+ break;
+ sudo_lbuf_print(lbuf);
+ }
+
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+/*
+ * Format and append a defaults entry to the specified lbuf.
+ */
+bool
+sudoers_format_default(struct sudo_lbuf *lbuf, struct defaults *d)
+{
+ debug_decl(sudoers_format_default, SUDOERS_DEBUG_UTIL)
+
+ if (d->val != NULL) {
+ sudo_lbuf_append(lbuf, "%s%s", d->var,
+ d->op == '+' ? "+=" : d->op == '-' ? "-=" : "=");
+ if (strpbrk(d->val, " \t") != NULL) {
+ sudo_lbuf_append(lbuf, "\"");
+ sudo_lbuf_append_quoted(lbuf, "\"", "%s", d->val);
+ sudo_lbuf_append(lbuf, "\"");
+ } else
+ sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", d->val);
+ } else {
+ sudo_lbuf_append(lbuf, "%s%s", d->op == false ? "!" : "", d->var);
+ }
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+/*
+ * Format and append a defaults line to the specified lbuf.
+ * If next, is specified, it must point to the next defaults
+ * entry in the list; this is used to print multiple defaults
+ * entries with the same binding on a single line.
+ */
+bool
+sudoers_format_default_line( struct sudo_lbuf *lbuf,
+ struct sudoers_parse_tree *parse_tree, struct defaults *d,
+ struct defaults **next, bool expand_aliases)
+{
+ struct member *m;
+ int alias_type;
+ debug_decl(sudoers_format_default_line, SUDOERS_DEBUG_UTIL)
+
+ /* Print Defaults type and binding (if present) */
+ switch (d->type) {
+ case DEFAULTS_HOST:
+ sudo_lbuf_append(lbuf, "Defaults@");
+ alias_type = expand_aliases ? HOSTALIAS : UNSPEC;
+ break;
+ case DEFAULTS_USER:
+ sudo_lbuf_append(lbuf, "Defaults:");
+ alias_type = expand_aliases ? USERALIAS : UNSPEC;
+ break;
+ case DEFAULTS_RUNAS:
+ sudo_lbuf_append(lbuf, "Defaults>");
+ alias_type = expand_aliases ? RUNASALIAS : UNSPEC;
+ break;
+ case DEFAULTS_CMND:
+ sudo_lbuf_append(lbuf, "Defaults!");
+ alias_type = expand_aliases ? CMNDALIAS : UNSPEC;
+ break;
+ default:
+ sudo_lbuf_append(lbuf, "Defaults");
+ alias_type = UNSPEC;
+ break;
+ }
+ TAILQ_FOREACH(m, d->binding, entries) {
+ if (m != TAILQ_FIRST(d->binding))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, parse_tree, m, ", ", alias_type);
+ }
+
+ sudo_lbuf_append(lbuf, " ");
+ sudoers_format_default(lbuf, d);
+
+ if (next != NULL) {
+ /* Merge Defaults with the same binding, there may be multiple. */
+ struct defaults *n;
+ while ((n = TAILQ_NEXT(d, entries)) && d->binding == n->binding) {
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_default(lbuf, n);
+ d = n;
+ }
+ *next = n;
+ }
+ sudo_lbuf_append(lbuf, "\n");
+
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
diff --git a/plugins/sudoers/gc.c b/plugins/sudoers/gc.c
new file mode 100644
index 0000000..1c14b71
--- /dev/null
+++ b/plugins/sudoers/gc.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sudoers.h"
+
+struct sudoers_gc_entry {
+ SLIST_ENTRY(sudoers_gc_entry) entries;
+ enum sudoers_gc_types type;
+ union {
+ char **vec;
+ void *ptr;
+ } u;
+};
+SLIST_HEAD(sudoers_gc_list, sudoers_gc_entry);
+#ifdef NO_LEAKS
+static struct sudoers_gc_list sudoers_gc_list =
+ SLIST_HEAD_INITIALIZER(sudoers_gc_list);
+#endif
+
+bool
+sudoers_gc_add(enum sudoers_gc_types type, void *v)
+{
+#ifdef NO_LEAKS
+ struct sudoers_gc_entry *gc;
+ debug_decl(sudoers_gc_add, SUDOERS_DEBUG_UTIL)
+
+ if (v == NULL)
+ debug_return_bool(false);
+
+ gc = calloc(1, sizeof(*gc));
+ if (gc == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ switch (type) {
+ case GC_PTR:
+ gc->u.ptr = v;
+ break;
+ case GC_VECTOR:
+ gc->u.vec = v;
+ break;
+ default:
+ free(gc);
+ sudo_warnx("unexpected garbage type %d", type);
+ debug_return_bool(false);
+ }
+ gc->type = type;
+ SLIST_INSERT_HEAD(&sudoers_gc_list, gc, entries);
+ debug_return_bool(true);
+#else
+ return true;
+#endif /* NO_LEAKS */
+}
+
+bool
+sudoers_gc_remove(enum sudoers_gc_types type, void *v)
+{
+#ifdef NO_LEAKS
+ struct sudoers_gc_entry *gc, *prev = NULL;
+ debug_decl(sudoers_gc_remove, SUDOERS_DEBUG_UTIL)
+
+ SLIST_FOREACH(gc, &sudoers_gc_list, entries) {
+ switch (gc->type) {
+ case GC_PTR:
+ if (gc->u.ptr == v)
+ goto found;
+ break;
+ case GC_VECTOR:
+ if (gc->u.vec == v)
+ goto found;
+ break;
+ default:
+ sudo_warnx("unexpected garbage type %d in %p", gc->type, gc);
+ }
+ prev = gc;
+ }
+ return false;
+found:
+ if (prev == NULL)
+ SLIST_REMOVE_HEAD(&sudoers_gc_list, entries);
+ else
+ SLIST_REMOVE_AFTER(prev, entries);
+ return true;
+#else
+ return false;
+#endif /* NO_LEAKS */
+}
+
+#ifdef NO_LEAKS
+static void
+sudoers_gc_run(void)
+{
+ struct sudoers_gc_entry *gc;
+ char **cur;
+ debug_decl(sudoers_gc_run, SUDOERS_DEBUG_UTIL)
+
+ /* Collect garbage. */
+ while ((gc = SLIST_FIRST(&sudoers_gc_list))) {
+ SLIST_REMOVE_HEAD(&sudoers_gc_list, entries);
+ switch (gc->type) {
+ case GC_PTR:
+ free(gc->u.ptr);
+ free(gc);
+ break;
+ case GC_VECTOR:
+ for (cur = gc->u.vec; *cur != NULL; cur++)
+ free(*cur);
+ free(gc->u.vec);
+ free(gc);
+ break;
+ default:
+ sudo_warnx("unexpected garbage type %d", gc->type);
+ }
+ }
+
+ debug_return;
+}
+#endif /* NO_LEAKS */
+
+void
+sudoers_gc_init(void)
+{
+#ifdef NO_LEAKS
+ atexit(sudoers_gc_run);
+#endif
+}
diff --git a/plugins/sudoers/gentime.c b/plugins/sudoers/gentime.c
new file mode 100644
index 0000000..eea4595
--- /dev/null
+++ b/plugins/sudoers/gentime.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <ctype.h>
+#include <time.h>
+
+#include "sudo_compat.h"
+#include "sudoers_debug.h"
+#include "parse.h"
+
+/*
+ * Parse a timestamp in Generalized Time format as per RFC4517.
+ * E.g. yyyymmddHHMMSS.FZ or yyyymmddHHMMSS.F[+-]TZOFF
+ * where minutes, seconds and fraction are optional.
+ * Returns the time in Unix time format or -1 on error.
+ */
+time_t
+parse_gentime(const char *timestr)
+{
+ char tcopy[sizeof("yyyymmddHHMMSS.F")];
+ const char *cp;
+ time_t result;
+ struct tm tm;
+ size_t len;
+ int items, tzoff = 0;
+ bool islocal = false;
+ debug_decl(parse_gentime, SUDOERS_DEBUG_PARSER)
+
+ /* Make a copy of the time without time zone for easy parsing. */
+ len = strspn(timestr, "0123456789.,");
+ if (len >= sizeof(tcopy)) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to parse general time string %s", timestr);
+ debug_return_time_t(-1);
+ }
+ memcpy(tcopy, timestr, len);
+ tcopy[len] = '\0';
+
+ /* Parse general time, ignoring the timezone for now. */
+ memset(&tm, 0, sizeof(tm));
+ items = sscanf(tcopy, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon,
+ &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
+ if (items == EOF || items < 4) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "only parsed %d items in general time string %s", items, timestr);
+ debug_return_time_t(-1);
+ }
+ cp = timestr + ((items + 1) * 2);
+
+ /* Parse optional fractional hours/minute/second if present. */
+ if ((cp[0] == '.' || cp[0] == ',') && isdigit((unsigned char)cp[1])) {
+ int frac = cp[1] - '0';
+ switch (items) {
+ case 4:
+ /* convert fractional hour -> minutes */
+ tm.tm_min += 60 / 10 * frac;
+ break;
+ case 5:
+ /* convert fractional minute -> seconds */
+ tm.tm_sec += 60 / 10 * frac;
+ break;
+ case 6:
+ /* ignore fractional second */
+ break;
+ }
+ cp += 2; /* skip over radix and fraction */
+ }
+
+ switch (*cp) {
+ case '-':
+ case '+': {
+ int hour = 0, min = 0;
+
+ /* No DST */
+ tm.tm_isdst = 0;
+ /* parse time zone offset */
+ items = sscanf(cp + 1, "%2d%2d", &hour, &min);
+ if (items == EOF || items < 1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to parse time zone offset in %s, items %d",
+ timestr, items);
+ debug_return_time_t(-1);
+ }
+ if (*cp == '-')
+ tzoff = -((hour * 60) + min) * 60;
+ else
+ tzoff = ((hour * 60) + min) * 60;
+ cp += 1 + (items * 2);
+ break;
+ }
+ case 'Z':
+ /* GMT/UTC, no DST */
+ tm.tm_isdst = 0;
+ cp++;
+ break;
+ case '\0':
+ /* no zone specified, use local time */
+ tm.tm_isdst = -1;
+ islocal = true;
+ break;
+ default:
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to parse general time string %s", timestr);
+ debug_return_time_t(-1);
+ }
+ if (*cp != '\0') {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "trailing garbage in general time string %s", timestr);
+ debug_return_time_t(-1);
+ }
+
+ /* Adjust from Generalized Time to struct tm */
+ tm.tm_year -= 1900;
+ tm.tm_mon--;
+
+ result = mktime(&tm);
+ if (result != -1) {
+ if (!islocal) {
+ /* Not local time, convert to GMT */
+ result += get_gmtoff(&result);
+ /* Adjust time based on supplied GMT offset. */
+ result -= tzoff;
+ }
+ }
+
+ debug_return_time_t(result);
+}
diff --git a/plugins/sudoers/getdate.c b/plugins/sudoers/getdate.c
new file mode 100644
index 0000000..a625d04
--- /dev/null
+++ b/plugins/sudoers/getdate.c
@@ -0,0 +1,1582 @@
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#define YYBYACC 1
+#define YYMAJOR 1
+#define YYMINOR 9
+#define YYLEX yylex()
+#define YYEMPTY -1
+#define yyclearin (yychar=(YYEMPTY))
+#define yyerrok (yyerrflag=0)
+#define YYRECOVERING() (yyerrflag!=0)
+#define YYPREFIX "yy"
+#line 2 "getdate.y"
+/*
+** Originally written by Steven M. Bellovin <smb@research.att.com> while
+** at the University of North Carolina at Chapel Hill. Later tweaked by
+** a couple of people on Usenet. Completely overhauled by Rich $alz
+** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
+**
+** This grammar has 10 shift/reduce conflicts.
+**
+** This code is in the public domain and has no copyright.
+*/
+/* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
+/* SUPPRESS 288 on yyerrlab *//* Label unused */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#include <time.h>
+#include <limits.h>
+#include <ctype.h>
+
+#include "sudo_compat.h"
+
+
+#define EPOCH 1970
+#define HOUR(x) ((time_t)(x) * 60)
+#define SECSPERDAY (24L * 60L * 60L)
+
+
+/*
+** An entry in the lexical lookup table.
+*/
+typedef struct _TABLE {
+ char *name;
+ int type;
+ time_t value;
+} TABLE;
+
+
+/*
+** Daylight-savings mode: on, off, or not yet known.
+*/
+typedef enum _DSTMODE {
+ DSTon, DSToff, DSTmaybe
+} DSTMODE;
+
+/*
+** Meridian: am, pm, or 24-hour style.
+*/
+typedef enum _MERIDIAN {
+ MERam, MERpm, MER24
+} MERIDIAN;
+
+
+/*
+** Global variables. We could get rid of most of these by using a good
+** union as the yacc stack. (This routine was originally written before
+** yacc had the %union construct.) Maybe someday; right now we only use
+** the %union very rarely.
+*/
+static char *yyInput;
+static DSTMODE yyDSTmode;
+static time_t yyDayOrdinal;
+static time_t yyDayNumber;
+static int yyHaveDate;
+static int yyHaveDay;
+static int yyHaveRel;
+static int yyHaveTime;
+static int yyHaveZone;
+static time_t yyTimezone;
+static time_t yyDay;
+static time_t yyHour;
+static time_t yyMinutes;
+static time_t yyMonth;
+static time_t yySeconds;
+static time_t yyYear;
+static MERIDIAN yyMeridian;
+static time_t yyRelMonth;
+static time_t yyRelSeconds;
+
+static int yyerror(const char *s);
+static int yylex(void);
+ int yyparse(void);
+
+#line 100 "getdate.y"
+#ifndef YYSTYPE_DEFINED
+#define YYSTYPE_DEFINED
+typedef union {
+ time_t Number;
+ enum _MERIDIAN Meridian;
+} YYSTYPE;
+#endif /* YYSTYPE_DEFINED */
+#line 118 "getdate.c"
+#define tAGO 257
+#define tDAY 258
+#define tDAYZONE 259
+#define tID 260
+#define tMERIDIAN 261
+#define tMINUTE_UNIT 262
+#define tMONTH 263
+#define tMONTH_UNIT 264
+#define tSEC_UNIT 265
+#define tSNUMBER 266
+#define tUNUMBER 267
+#define tZONE 268
+#define tDST 269
+#define YYERRCODE 256
+#if defined(__cplusplus) || defined(__STDC__)
+const short yylhs[] =
+#else
+short yylhs[] =
+#endif
+ { -1,
+ 0, 0, 2, 2, 2, 2, 2, 2, 3, 3,
+ 3, 3, 3, 4, 4, 4, 6, 6, 6, 5,
+ 5, 5, 5, 5, 5, 5, 5, 7, 7, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 8, 1,
+ 1,
+};
+#if defined(__cplusplus) || defined(__STDC__)
+const short yylen[] =
+#else
+short yylen[] =
+#endif
+ { 2,
+ 0, 2, 1, 1, 1, 1, 1, 1, 2, 4,
+ 4, 6, 6, 1, 1, 2, 1, 2, 2, 3,
+ 5, 3, 3, 2, 4, 2, 3, 2, 1, 2,
+ 2, 1, 2, 2, 1, 2, 2, 1, 1, 0,
+ 1,
+};
+#if defined(__cplusplus) || defined(__STDC__)
+const short yydefred[] =
+#else
+short yydefred[] =
+#endif
+ { 1,
+ 0, 0, 15, 32, 0, 38, 35, 0, 0, 0,
+ 2, 3, 4, 5, 6, 7, 8, 0, 18, 0,
+ 31, 36, 33, 19, 9, 30, 0, 37, 34, 0,
+ 0, 0, 16, 28, 0, 23, 27, 22, 0, 0,
+ 25, 41, 11, 0, 10, 0, 0, 21, 13, 12,
+};
+#if defined(__cplusplus) || defined(__STDC__)
+const short yydgoto[] =
+#else
+short yydgoto[] =
+#endif
+ { 1,
+ 45, 11, 12, 13, 14, 15, 16, 17, 18,
+};
+#if defined(__cplusplus) || defined(__STDC__)
+const short yysindex[] =
+#else
+short yysindex[] =
+#endif
+ { 0,
+ -249, -38, 0, 0, -260, 0, 0, -240, -47, -248,
+ 0, 0, 0, 0, 0, 0, 0, -237, 0, -18,
+ 0, 0, 0, 0, 0, 0, -262, 0, 0, -239,
+ -238, -236, 0, 0, -235, 0, 0, 0, -56, -19,
+ 0, 0, 0, -234, 0, -232, -258, 0, 0, 0,};
+#if defined(__cplusplus) || defined(__STDC__)
+const short yyrindex[] =
+#else
+short yyrindex[] =
+#endif
+ { 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 69, 12,
+ 0, 0, 0, 0, 0, 0, 0, 23, 0, 34,
+ 0, 0, 0, 0, 0, 0, 67, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 56, 45,
+ 0, 0, 0, 0, 0, 0, 56, 0, 0, 0,};
+#if defined(__cplusplus) || defined(__STDC__)
+const short yygindex[] =
+#else
+short yygindex[] =
+#endif
+ { 0,
+ -17, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+#define YYTABLESIZE 337
+#if defined(__cplusplus) || defined(__STDC__)
+const short yytable[] =
+#else
+short yytable[] =
+#endif
+ { 32,
+ 17, 44, 42, 36, 37, 19, 20, 49, 2, 3,
+ 31, 14, 4, 5, 6, 7, 8, 9, 10, 34,
+ 33, 21, 29, 22, 23, 35, 38, 46, 39, 50,
+ 40, 41, 47, 24, 48, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 20, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 40, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 26, 0, 39, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 42, 0, 0, 0, 0, 43,
+ 24, 0, 0, 25, 26, 27, 28, 29, 30, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 17, 17,
+ 0, 0, 17, 17, 17, 17, 17, 17, 17, 14,
+ 14, 0, 0, 14, 14, 14, 14, 14, 14, 14,
+ 29, 29, 0, 0, 29, 29, 29, 29, 29, 29,
+ 29, 24, 24, 0, 0, 24, 24, 24, 24, 24,
+ 24, 24, 20, 20, 0, 0, 20, 20, 20, 20,
+ 20, 20, 20, 40, 40, 0, 0, 40, 40, 40,
+ 40, 0, 40, 40, 26, 26, 0, 39, 26, 26,
+ 26, 26, 0, 0, 26, 39, 39,
+};
+#if defined(__cplusplus) || defined(__STDC__)
+const short yycheck[] =
+#else
+short yycheck[] =
+#endif
+ { 47,
+ 0, 58, 261, 266, 267, 44, 267, 266, 258, 259,
+ 58, 0, 262, 263, 264, 265, 266, 267, 268, 257,
+ 269, 262, 0, 264, 265, 44, 266, 47, 267, 47,
+ 267, 267, 267, 0, 267, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 0, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 0, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 0, -1, 0, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 261, -1, -1, -1, -1, 266,
+ 258, -1, -1, 261, 262, 263, 264, 265, 266, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 258, 259,
+ -1, -1, 262, 263, 264, 265, 266, 267, 268, 258,
+ 259, -1, -1, 262, 263, 264, 265, 266, 267, 268,
+ 258, 259, -1, -1, 262, 263, 264, 265, 266, 267,
+ 268, 258, 259, -1, -1, 262, 263, 264, 265, 266,
+ 267, 268, 258, 259, -1, -1, 262, 263, 264, 265,
+ 266, 267, 268, 258, 259, -1, -1, 262, 263, 264,
+ 265, -1, 267, 268, 258, 259, -1, 259, 262, 263,
+ 264, 265, -1, -1, 268, 267, 268,
+};
+#define YYFINAL 1
+#ifndef YYDEBUG
+#define YYDEBUG 0
+#endif
+#define YYMAXTOKEN 269
+#if YYDEBUG
+#if defined(__cplusplus) || defined(__STDC__)
+const char * const yyname[] =
+#else
+char *yyname[] =
+#endif
+ {
+"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,"','",0,0,"'/'",0,0,0,0,0,0,0,0,0,0,"':'",0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"tAGO","tDAY",
+"tDAYZONE","tID","tMERIDIAN","tMINUTE_UNIT","tMONTH","tMONTH_UNIT","tSEC_UNIT",
+"tSNUMBER","tUNUMBER","tZONE","tDST",
+};
+#if defined(__cplusplus) || defined(__STDC__)
+const char * const yyrule[] =
+#else
+char *yyrule[] =
+#endif
+ {"$accept : spec",
+"spec :",
+"spec : spec item",
+"item : time",
+"item : zone",
+"item : date",
+"item : day",
+"item : rel",
+"item : number",
+"time : tUNUMBER tMERIDIAN",
+"time : tUNUMBER ':' tUNUMBER o_merid",
+"time : tUNUMBER ':' tUNUMBER tSNUMBER",
+"time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid",
+"time : tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER",
+"zone : tZONE",
+"zone : tDAYZONE",
+"zone : tZONE tDST",
+"day : tDAY",
+"day : tDAY ','",
+"day : tUNUMBER tDAY",
+"date : tUNUMBER '/' tUNUMBER",
+"date : tUNUMBER '/' tUNUMBER '/' tUNUMBER",
+"date : tUNUMBER tSNUMBER tSNUMBER",
+"date : tUNUMBER tMONTH tSNUMBER",
+"date : tMONTH tUNUMBER",
+"date : tMONTH tUNUMBER ',' tUNUMBER",
+"date : tUNUMBER tMONTH",
+"date : tUNUMBER tMONTH tUNUMBER",
+"rel : relunit tAGO",
+"rel : relunit",
+"relunit : tUNUMBER tMINUTE_UNIT",
+"relunit : tSNUMBER tMINUTE_UNIT",
+"relunit : tMINUTE_UNIT",
+"relunit : tSNUMBER tSEC_UNIT",
+"relunit : tUNUMBER tSEC_UNIT",
+"relunit : tSEC_UNIT",
+"relunit : tSNUMBER tMONTH_UNIT",
+"relunit : tUNUMBER tMONTH_UNIT",
+"relunit : tMONTH_UNIT",
+"number : tUNUMBER",
+"o_merid :",
+"o_merid : tMERIDIAN",
+};
+#endif
+#ifdef YYSTACKSIZE
+#undef YYMAXDEPTH
+#define YYMAXDEPTH YYSTACKSIZE
+#else
+#ifdef YYMAXDEPTH
+#define YYSTACKSIZE YYMAXDEPTH
+#else
+#define YYSTACKSIZE 10000
+#define YYMAXDEPTH 10000
+#endif
+#endif
+#define YYINITSTACKSIZE 200
+/* LINTUSED */
+int yydebug;
+int yynerrs;
+int yyerrflag;
+int yychar;
+short *yyssp;
+YYSTYPE *yyvsp;
+YYSTYPE yyval;
+YYSTYPE yylval;
+short *yyss;
+short *yysslim;
+YYSTYPE *yyvs;
+unsigned int yystacksize;
+int yyparse(void);
+#line 319 "getdate.y"
+
+/* Month and day table. */
+static TABLE const MonthDayTable[] = {
+ { "january", tMONTH, 1 },
+ { "february", tMONTH, 2 },
+ { "march", tMONTH, 3 },
+ { "april", tMONTH, 4 },
+ { "may", tMONTH, 5 },
+ { "june", tMONTH, 6 },
+ { "july", tMONTH, 7 },
+ { "august", tMONTH, 8 },
+ { "september", tMONTH, 9 },
+ { "sept", tMONTH, 9 },
+ { "october", tMONTH, 10 },
+ { "november", tMONTH, 11 },
+ { "december", tMONTH, 12 },
+ { "sunday", tDAY, 0 },
+ { "monday", tDAY, 1 },
+ { "tuesday", tDAY, 2 },
+ { "tues", tDAY, 2 },
+ { "wednesday", tDAY, 3 },
+ { "wednes", tDAY, 3 },
+ { "thursday", tDAY, 4 },
+ { "thur", tDAY, 4 },
+ { "thurs", tDAY, 4 },
+ { "friday", tDAY, 5 },
+ { "saturday", tDAY, 6 },
+ { NULL }
+};
+
+/* Time units table. */
+static TABLE const UnitsTable[] = {
+ { "year", tMONTH_UNIT, 12 },
+ { "month", tMONTH_UNIT, 1 },
+ { "fortnight", tMINUTE_UNIT, 14 * 24 * 60 },
+ { "week", tMINUTE_UNIT, 7 * 24 * 60 },
+ { "day", tMINUTE_UNIT, 1 * 24 * 60 },
+ { "hour", tMINUTE_UNIT, 60 },
+ { "minute", tMINUTE_UNIT, 1 },
+ { "min", tMINUTE_UNIT, 1 },
+ { "second", tSEC_UNIT, 1 },
+ { "sec", tSEC_UNIT, 1 },
+ { NULL }
+};
+
+/* Assorted relative-time words. */
+static TABLE const OtherTable[] = {
+ { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
+ { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
+ { "today", tMINUTE_UNIT, 0 },
+ { "now", tMINUTE_UNIT, 0 },
+ { "last", tUNUMBER, -1 },
+ { "this", tUNUMBER, 0 },
+ { "next", tUNUMBER, 2 },
+ { "first", tUNUMBER, 1 },
+/* { "second", tUNUMBER, 2 }, */
+ { "third", tUNUMBER, 3 },
+ { "fourth", tUNUMBER, 4 },
+ { "fifth", tUNUMBER, 5 },
+ { "sixth", tUNUMBER, 6 },
+ { "seventh", tUNUMBER, 7 },
+ { "eighth", tUNUMBER, 8 },
+ { "ninth", tUNUMBER, 9 },
+ { "tenth", tUNUMBER, 10 },
+ { "eleventh", tUNUMBER, 11 },
+ { "twelfth", tUNUMBER, 12 },
+ { "ago", tAGO, 1 },
+ { NULL }
+};
+
+/* The timezone table. */
+/* Some of these are commented out because a time_t can't store a float. */
+static TABLE const TimezoneTable[] = {
+ { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */
+ { "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */
+ { "utc", tZONE, HOUR( 0) },
+ { "wet", tZONE, HOUR( 0) }, /* Western European */
+ { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */
+ { "wat", tZONE, HOUR( 1) }, /* West Africa */
+ { "at", tZONE, HOUR( 2) }, /* Azores */
+#if 0
+ /* For completeness. BST is also British Summer, and GST is
+ * also Guam Standard. */
+ { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */
+ { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */
+#endif
+#if 0
+ { "nft", tZONE, HOUR(3.5) }, /* Newfoundland */
+ { "nst", tZONE, HOUR(3.5) }, /* Newfoundland Standard */
+ { "ndt", tDAYZONE, HOUR(3.5) }, /* Newfoundland Daylight */
+#endif
+ { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */
+ { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */
+ { "est", tZONE, HOUR( 5) }, /* Eastern Standard */
+ { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */
+ { "cst", tZONE, HOUR( 6) }, /* Central Standard */
+ { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */
+ { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */
+ { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */
+ { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */
+ { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */
+ { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */
+ { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */
+ { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */
+ { "hdt", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */
+ { "cat", tZONE, HOUR(10) }, /* Central Alaska */
+ { "ahst", tZONE, HOUR(10) }, /* Alaska-Hawaii Standard */
+ { "nt", tZONE, HOUR(11) }, /* Nome */
+ { "idlw", tZONE, HOUR(12) }, /* International Date Line West */
+ { "cet", tZONE, -HOUR(1) }, /* Central European */
+ { "met", tZONE, -HOUR(1) }, /* Middle European */
+ { "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */
+ { "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */
+ { "swt", tZONE, -HOUR(1) }, /* Swedish Winter */
+ { "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */
+ { "fwt", tZONE, -HOUR(1) }, /* French Winter */
+ { "fst", tDAYZONE, -HOUR(1) }, /* French Summer */
+ { "eet", tZONE, -HOUR(2) }, /* Eastern Europe, USSR Zone 1 */
+ { "bt", tZONE, -HOUR(3) }, /* Baghdad, USSR Zone 2 */
+#if 0
+ { "it", tZONE, -HOUR(3.5) },/* Iran */
+#endif
+ { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */
+ { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */
+#if 0
+ { "ist", tZONE, -HOUR(5.5) },/* Indian Standard */
+#endif
+ { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */
+#if 0
+ /* For completeness. NST is also Newfoundland Stanard, and SST is
+ * also Swedish Summer. */
+ { "nst", tZONE, -HOUR(6.5) },/* North Sumatra */
+ { "sst", tZONE, -HOUR(7) }, /* South Sumatra, USSR Zone 6 */
+#endif /* 0 */
+ { "wast", tZONE, -HOUR(7) }, /* West Australian Standard */
+ { "wadt", tDAYZONE, -HOUR(7) }, /* West Australian Daylight */
+#if 0
+ { "jt", tZONE, -HOUR(7.5) },/* Java (3pm in Cronusland!) */
+#endif
+ { "cct", tZONE, -HOUR(8) }, /* China Coast, USSR Zone 7 */
+ { "jst", tZONE, -HOUR(9) }, /* Japan Standard, USSR Zone 8 */
+#if 0
+ { "cast", tZONE, -HOUR(9.5) },/* Central Australian Standard */
+ { "cadt", tDAYZONE, -HOUR(9.5) },/* Central Australian Daylight */
+#endif
+ { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */
+ { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */
+ { "gst", tZONE, -HOUR(10) }, /* Guam Standard, USSR Zone 9 */
+ { "nzt", tZONE, -HOUR(12) }, /* New Zealand */
+ { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */
+ { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */
+ { "idle", tZONE, -HOUR(12) }, /* International Date Line East */
+ { NULL }
+};
+
+/* Military timezone table. */
+static TABLE const MilitaryTable[] = {
+ { "a", tZONE, HOUR( 1) },
+ { "b", tZONE, HOUR( 2) },
+ { "c", tZONE, HOUR( 3) },
+ { "d", tZONE, HOUR( 4) },
+ { "e", tZONE, HOUR( 5) },
+ { "f", tZONE, HOUR( 6) },
+ { "g", tZONE, HOUR( 7) },
+ { "h", tZONE, HOUR( 8) },
+ { "i", tZONE, HOUR( 9) },
+ { "k", tZONE, HOUR( 10) },
+ { "l", tZONE, HOUR( 11) },
+ { "m", tZONE, HOUR( 12) },
+ { "n", tZONE, HOUR(- 1) },
+ { "o", tZONE, HOUR(- 2) },
+ { "p", tZONE, HOUR(- 3) },
+ { "q", tZONE, HOUR(- 4) },
+ { "r", tZONE, HOUR(- 5) },
+ { "s", tZONE, HOUR(- 6) },
+ { "t", tZONE, HOUR(- 7) },
+ { "u", tZONE, HOUR(- 8) },
+ { "v", tZONE, HOUR(- 9) },
+ { "w", tZONE, HOUR(-10) },
+ { "x", tZONE, HOUR(-11) },
+ { "y", tZONE, HOUR(-12) },
+ { "z", tZONE, HOUR( 0) },
+ { NULL }
+};
+
+
+
+
+/* ARGSUSED */
+static int
+yyerror(const char *s)
+{
+ return 0;
+}
+
+
+static time_t
+ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian)
+{
+ if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
+ return -1;
+ switch (Meridian) {
+ case MER24:
+ if (Hours < 0 || Hours > 23)
+ return -1;
+ return (Hours * 60L + Minutes) * 60L + Seconds;
+ case MERam:
+ if (Hours < 1 || Hours > 12)
+ return -1;
+ if (Hours == 12)
+ Hours = 0;
+ return (Hours * 60L + Minutes) * 60L + Seconds;
+ case MERpm:
+ if (Hours < 1 || Hours > 12)
+ return -1;
+ if (Hours == 12)
+ Hours = 0;
+ return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
+ default:
+ abort ();
+ }
+ /* NOTREACHED */
+}
+
+
+/* Year is either
+ * A negative number, which means to use its absolute value (why?)
+ * A number from 0 to 99, which means a year from 1900 to 1999, or
+ * The actual year (>=100). */
+static time_t
+Convert(time_t Month, time_t Day, time_t Year, time_t Hours, time_t Minutes,
+ time_t Seconds, MERIDIAN Meridian, DSTMODE DSTmode)
+{
+ static int DaysInMonth[12] = {
+ 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+ };
+ struct tm *tm;
+ time_t tod;
+ time_t Julian;
+ int i;
+
+ if (Year < 0)
+ Year = -Year;
+ if (Year < 69)
+ Year += 2000;
+ else if (Year < 100) {
+ Year += 1900;
+ if (Year < EPOCH)
+ Year += 100;
+ }
+ DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
+ ? 29 : 28;
+ /* 32-bit time_t cannot represent years past 2038 */
+ if (Year < EPOCH || (sizeof(time_t) == sizeof(int) && Year > 2038)
+ || Month < 1 || Month > 12
+ /* Lint fluff: "conversion from long may lose accuracy" */
+ || Day < 1 || Day > DaysInMonth[(int)--Month])
+ return -1;
+
+ for (Julian = Day - 1, i = 0; i < Month; i++)
+ Julian += DaysInMonth[i];
+ for (i = EPOCH; i < Year; i++)
+ Julian += 365 + (i % 4 == 0);
+ Julian *= SECSPERDAY;
+ Julian += yyTimezone * 60L;
+ if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
+ return -1;
+ Julian += tod;
+ if (DSTmode == DSTon
+ || (DSTmode == DSTmaybe && (tm = localtime(&Julian)) && tm->tm_isdst))
+ Julian -= 60 * 60;
+ return Julian;
+}
+
+
+static time_t
+DSTcorrect(time_t Start, time_t Future)
+{
+ struct tm *start_tm;
+ struct tm *future_tm;
+ time_t StartDay;
+ time_t FutureDay;
+
+ start_tm = localtime(&Start);
+ future_tm = localtime(&Future);
+ if (!start_tm || !future_tm)
+ return -1;
+
+ StartDay = (start_tm->tm_hour + 1) % 24;
+ FutureDay = (future_tm->tm_hour + 1) % 24;
+ return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
+}
+
+
+static time_t
+RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber)
+{
+ struct tm *tm;
+ time_t now;
+
+ now = Start;
+ if (!(tm = localtime(&now)))
+ return -1;
+ now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
+ now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
+ return DSTcorrect(Start, now);
+}
+
+
+static time_t
+RelativeMonth(time_t Start, time_t RelMonth)
+{
+ struct tm *tm;
+ time_t Month;
+ time_t Year;
+
+ if (RelMonth == 0)
+ return 0;
+ if (!(tm = localtime(&Start)))
+ return -1;
+ Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
+ Year = Month / 12;
+ Month = Month % 12 + 1;
+ return DSTcorrect(Start,
+ Convert(Month, (time_t)tm->tm_mday, Year,
+ (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
+ MER24, DSTmaybe));
+}
+
+
+static int
+LookupWord(char *buff)
+{
+ char *p;
+ char *q;
+ const TABLE *tp;
+ int i;
+ int abbrev;
+
+ /* Make it lowercase. */
+ for (p = buff; *p; p++)
+ if (isupper((unsigned char)*p))
+ *p = tolower((unsigned char)*p);
+
+ if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
+ yylval.Meridian = MERam;
+ return tMERIDIAN;
+ }
+ if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
+ yylval.Meridian = MERpm;
+ return tMERIDIAN;
+ }
+
+ /* See if we have an abbreviation for a month. */
+ if (strlen(buff) == 3)
+ abbrev = 1;
+ else if (strlen(buff) == 4 && buff[3] == '.') {
+ abbrev = 1;
+ buff[3] = '\0';
+ }
+ else
+ abbrev = 0;
+
+ for (tp = MonthDayTable; tp->name; tp++) {
+ if (abbrev) {
+ if (strncmp(buff, tp->name, 3) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ }
+ else if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ }
+
+ for (tp = TimezoneTable; tp->name; tp++)
+ if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ if (strcmp(buff, "dst") == 0)
+ return tDST;
+
+ for (tp = UnitsTable; tp->name; tp++)
+ if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ /* Strip off any plural and try the units table again. */
+ i = strlen(buff) - 1;
+ if (buff[i] == 's') {
+ buff[i] = '\0';
+ for (tp = UnitsTable; tp->name; tp++)
+ if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ buff[i] = 's'; /* Put back for "this" in OtherTable. */
+ }
+
+ for (tp = OtherTable; tp->name; tp++)
+ if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ /* Military timezones. */
+ if (buff[1] == '\0' && isalpha((unsigned char)*buff)) {
+ for (tp = MilitaryTable; tp->name; tp++)
+ if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ }
+
+ /* Drop out any periods and try the timezone table again. */
+ for (i = 0, p = q = buff; *q; q++)
+ if (*q != '.')
+ *p++ = *q;
+ else
+ i++;
+ *p = '\0';
+ if (i)
+ for (tp = TimezoneTable; tp->name; tp++)
+ if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ return tID;
+}
+
+
+static int
+yylex(void)
+{
+ char c;
+ char *p;
+ char buff[20];
+ int Count;
+ int sign;
+
+ for ( ; ; ) {
+ while (isspace((unsigned char)*yyInput))
+ yyInput++;
+
+ if (isdigit((unsigned char)(c = *yyInput)) || c == '-' || c == '+') {
+ if (c == '-' || c == '+') {
+ sign = c == '-' ? -1 : 1;
+ if (!isdigit((unsigned char)*++yyInput))
+ /* skip the '-' sign */
+ continue;
+ }
+ else
+ sign = 0;
+ for (yylval.Number = 0; isdigit((unsigned char)(c = *yyInput++)); )
+ yylval.Number = 10 * yylval.Number + c - '0';
+ yyInput--;
+ if (sign < 0)
+ yylval.Number = -yylval.Number;
+ return sign ? tSNUMBER : tUNUMBER;
+ }
+ if (isalpha((unsigned char)c)) {
+ for (p = buff; isalpha((unsigned char)(c = *yyInput++)) || c == '.'; )
+ if (p < &buff[sizeof buff - 1])
+ *p++ = c;
+ *p = '\0';
+ yyInput--;
+ return LookupWord(buff);
+ }
+ if (c != '(')
+ return *yyInput++;
+ Count = 0;
+ do {
+ c = *yyInput++;
+ if (c == '\0')
+ return c;
+ if (c == '(')
+ Count++;
+ else if (c == ')')
+ Count--;
+ } while (Count > 0);
+ }
+}
+
+#define TM_YEAR_ORIGIN 1900
+
+/* Yield A - B, measured in seconds. */
+static long
+difftm(struct tm *a, struct tm *b)
+{
+ int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
+ int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
+ int days = (
+ /* difference in day of year */
+ a->tm_yday - b->tm_yday
+ /* + intervening leap days */
+ + ((ay >> 2) - (by >> 2))
+ - (ay/100 - by/100)
+ + ((ay/100 >> 2) - (by/100 >> 2))
+ /* + difference in years * 365 */
+ + (long)(ay-by) * 365
+ );
+ return (60*(60*(24*days + (a->tm_hour - b->tm_hour))
+ + (a->tm_min - b->tm_min))
+ + (a->tm_sec - b->tm_sec));
+}
+
+time_t
+get_date(char *p)
+{
+ struct tm *tm, *gmt, gmtbuf;
+ time_t Start;
+ time_t tod;
+ time_t now;
+ time_t timezone;
+
+ yyInput = p;
+ (void)time (&now);
+
+ gmt = gmtime (&now);
+ if (gmt != NULL)
+ {
+ /* Make a copy, in case localtime modifies *tm (I think
+ that comment now applies to *gmt, but I am too
+ lazy to dig into how gmtime and locatime allocate the
+ structures they return pointers to). */
+ gmtbuf = *gmt;
+ gmt = &gmtbuf;
+ }
+
+ if (! (tm = localtime (&now)))
+ return -1;
+
+ if (gmt != NULL)
+ timezone = difftm (gmt, tm) / 60;
+ else
+ /* We are on a system like VMS, where the system clock is
+ in local time and the system has no concept of timezones.
+ Hopefully we can fake this out (for the case in which the
+ user specifies no timezone) by just saying the timezone
+ is zero. */
+ timezone = 0;
+
+ if(tm->tm_isdst)
+ timezone += 60;
+
+ yyYear = tm->tm_year + 1900;
+ yyMonth = tm->tm_mon + 1;
+ yyDay = tm->tm_mday;
+ yyTimezone = timezone;
+ yyDSTmode = DSTmaybe;
+ yyHour = 0;
+ yyMinutes = 0;
+ yySeconds = 0;
+ yyMeridian = MER24;
+ yyRelSeconds = 0;
+ yyRelMonth = 0;
+ yyHaveDate = 0;
+ yyHaveDay = 0;
+ yyHaveRel = 0;
+ yyHaveTime = 0;
+ yyHaveZone = 0;
+
+ if (yyparse()
+ || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
+ return -1;
+
+ if (yyHaveDate || yyHaveTime || yyHaveDay) {
+ Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
+ yyMeridian, yyDSTmode);
+ if (Start < 0)
+ return -1;
+ }
+ else {
+ Start = now;
+ if (!yyHaveRel)
+ Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec;
+ }
+
+ Start += yyRelSeconds;
+ Start += RelativeMonth(Start, yyRelMonth);
+
+ if (yyHaveDay && !yyHaveDate) {
+ tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
+ Start += tod;
+ }
+
+ /* Have to do *something* with a legitimate -1 so it's distinguishable
+ * from the error return value. (Alternately could set errno on error.) */
+ return Start == -1 ? 0 : Start;
+}
+
+
+#ifdef TEST
+
+/* ARGSUSED */
+int
+main(int argc, char *argv[])
+{
+ char buff[128];
+ time_t d;
+
+ (void)printf("Enter date, or blank line to exit.\n\t> ");
+ (void)fflush(stdout);
+ while (fgets(buff, sizeof(buff), stdin) && buff[0]) {
+ d = get_date(buff);
+ if (d == -1)
+ (void)printf("Bad format - couldn't convert.\n");
+ else
+ (void)printf("%s", ctime(&d));
+ (void)printf("\t> ");
+ (void)fflush(stdout);
+ }
+ exit(0);
+ /* NOTREACHED */
+}
+#endif /* TEST */
+#line 957 "getdate.c"
+/* allocate initial stack or double stack size, up to YYMAXDEPTH */
+#if defined(__cplusplus) || defined(__STDC__)
+static int yygrowstack(void)
+#else
+static int yygrowstack()
+#endif
+{
+ unsigned int newsize;
+ long sslen;
+ short *newss;
+ YYSTYPE *newvs;
+
+ if ((newsize = yystacksize) == 0)
+ newsize = YYINITSTACKSIZE;
+ else if (newsize >= YYMAXDEPTH)
+ return -1;
+ else if ((newsize *= 2) > YYMAXDEPTH)
+ newsize = YYMAXDEPTH;
+#ifdef SIZE_MAX
+#define YY_SIZE_MAX SIZE_MAX
+#else
+#ifdef __STDC__
+#define YY_SIZE_MAX 0xffffffffU
+#else
+#define YY_SIZE_MAX (unsigned int)0xffffffff
+#endif
+#endif
+ if (YY_SIZE_MAX / newsize < sizeof *newss)
+ goto bail;
+ sslen = yyssp - yyss;
+ newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
+ (short *)malloc(newsize * sizeof *newss); /* overflow check above */
+ if (newss == NULL)
+ goto bail;
+ yyss = newss;
+ yyssp = newss + sslen;
+ newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
+ (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
+ if (newvs == NULL)
+ goto bail;
+ yyvs = newvs;
+ yyvsp = newvs + sslen;
+ yystacksize = newsize;
+ yysslim = yyss + newsize - 1;
+ return 0;
+bail:
+ if (yyss)
+ free(yyss);
+ if (yyvs)
+ free(yyvs);
+ yyss = yyssp = NULL;
+ yyvs = yyvsp = NULL;
+ yystacksize = 0;
+ return -1;
+}
+
+#define YYABORT goto yyabort
+#define YYREJECT goto yyabort
+#define YYACCEPT goto yyaccept
+#define YYERROR goto yyerrlab
+int
+#if defined(__cplusplus) || defined(__STDC__)
+yyparse(void)
+#else
+yyparse()
+#endif
+{
+ int yym, yyn, yystate;
+#if YYDEBUG
+#if defined(__cplusplus) || defined(__STDC__)
+ const char *yys;
+#else /* !(defined(__cplusplus) || defined(__STDC__)) */
+ char *yys;
+#endif /* !(defined(__cplusplus) || defined(__STDC__)) */
+
+ if ((yys = getenv("YYDEBUG")))
+ {
+ yyn = *yys;
+ if (yyn >= '0' && yyn <= '9')
+ yydebug = yyn - '0';
+ }
+#endif /* YYDEBUG */
+
+ yynerrs = 0;
+ yyerrflag = 0;
+ yychar = (-1);
+
+ if (yyss == NULL && yygrowstack()) goto yyoverflow;
+ yyssp = yyss;
+ yyvsp = yyvs;
+ *yyssp = yystate = 0;
+
+yyloop:
+ if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ }
+ if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, shifting to state %d\n",
+ YYPREFIX, yystate, yytable[yyn]);
+#endif
+ if (yyssp >= yysslim && yygrowstack())
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ yychar = (-1);
+ if (yyerrflag > 0) --yyerrflag;
+ goto yyloop;
+ }
+ if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+ yyn = yytable[yyn];
+ goto yyreduce;
+ }
+ if (yyerrflag) goto yyinrecovery;
+#if defined(__GNUC__)
+ goto yynewerror;
+#endif
+yynewerror:
+ yyerror("syntax error");
+#if defined(__GNUC__)
+ goto yyerrlab;
+#endif
+yyerrlab:
+ ++yynerrs;
+yyinrecovery:
+ if (yyerrflag < 3)
+ {
+ yyerrflag = 3;
+ for (;;)
+ {
+ if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, error recovery shifting\
+ to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
+#endif
+ if (yyssp >= yysslim && yygrowstack())
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ goto yyloop;
+ }
+ else
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: error recovery discarding state %d\n",
+ YYPREFIX, *yyssp);
+#endif
+ if (yyssp <= yyss) goto yyabort;
+ --yyssp;
+ --yyvsp;
+ }
+ }
+ }
+ else
+ {
+ if (yychar == 0) goto yyabort;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ yychar = (-1);
+ goto yyloop;
+ }
+yyreduce:
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, reducing by rule %d (%s)\n",
+ YYPREFIX, yystate, yyn, yyrule[yyn]);
+#endif
+ yym = yylen[yyn];
+ if (yym)
+ yyval = yyvsp[1-yym];
+ else
+ memset(&yyval, 0, sizeof yyval);
+ switch (yyn)
+ {
+case 3:
+#line 118 "getdate.y"
+{
+ yyHaveTime++;
+ }
+break;
+case 4:
+#line 121 "getdate.y"
+{
+ yyHaveZone++;
+ }
+break;
+case 5:
+#line 124 "getdate.y"
+{
+ yyHaveDate++;
+ }
+break;
+case 6:
+#line 127 "getdate.y"
+{
+ yyHaveDay++;
+ }
+break;
+case 7:
+#line 130 "getdate.y"
+{
+ yyHaveRel++;
+ }
+break;
+case 9:
+#line 136 "getdate.y"
+{
+ yyHour = yyvsp[-1].Number;
+ yyMinutes = 0;
+ yySeconds = 0;
+ yyMeridian = yyvsp[0].Meridian;
+ }
+break;
+case 10:
+#line 142 "getdate.y"
+{
+ yyHour = yyvsp[-3].Number;
+ yyMinutes = yyvsp[-1].Number;
+ yySeconds = 0;
+ yyMeridian = yyvsp[0].Meridian;
+ }
+break;
+case 11:
+#line 148 "getdate.y"
+{
+ yyHour = yyvsp[-3].Number;
+ yyMinutes = yyvsp[-1].Number;
+ yyMeridian = MER24;
+ yyDSTmode = DSToff;
+ yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
+ }
+break;
+case 12:
+#line 155 "getdate.y"
+{
+ yyHour = yyvsp[-5].Number;
+ yyMinutes = yyvsp[-3].Number;
+ yySeconds = yyvsp[-1].Number;
+ yyMeridian = yyvsp[0].Meridian;
+ }
+break;
+case 13:
+#line 161 "getdate.y"
+{
+ yyHour = yyvsp[-5].Number;
+ yyMinutes = yyvsp[-3].Number;
+ yySeconds = yyvsp[-1].Number;
+ yyMeridian = MER24;
+ yyDSTmode = DSToff;
+ yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
+ }
+break;
+case 14:
+#line 171 "getdate.y"
+{
+ yyTimezone = yyvsp[0].Number;
+ yyDSTmode = DSToff;
+ }
+break;
+case 15:
+#line 175 "getdate.y"
+{
+ yyTimezone = yyvsp[0].Number;
+ yyDSTmode = DSTon;
+ }
+break;
+case 16:
+#line 180 "getdate.y"
+{
+ yyTimezone = yyvsp[-1].Number;
+ yyDSTmode = DSTon;
+ }
+break;
+case 17:
+#line 186 "getdate.y"
+{
+ yyDayOrdinal = 1;
+ yyDayNumber = yyvsp[0].Number;
+ }
+break;
+case 18:
+#line 190 "getdate.y"
+{
+ yyDayOrdinal = 1;
+ yyDayNumber = yyvsp[-1].Number;
+ }
+break;
+case 19:
+#line 194 "getdate.y"
+{
+ yyDayOrdinal = yyvsp[-1].Number;
+ yyDayNumber = yyvsp[0].Number;
+ }
+break;
+case 20:
+#line 200 "getdate.y"
+{
+ yyMonth = yyvsp[-2].Number;
+ yyDay = yyvsp[0].Number;
+ }
+break;
+case 21:
+#line 204 "getdate.y"
+{
+ if (yyvsp[-4].Number >= 100) {
+ yyYear = yyvsp[-4].Number;
+ yyMonth = yyvsp[-2].Number;
+ yyDay = yyvsp[0].Number;
+ } else {
+ yyMonth = yyvsp[-4].Number;
+ yyDay = yyvsp[-2].Number;
+ yyYear = yyvsp[0].Number;
+ }
+ }
+break;
+case 22:
+#line 215 "getdate.y"
+{
+ /* ISO 8601 format. yyyy-mm-dd. */
+ yyYear = yyvsp[-2].Number;
+ yyMonth = -yyvsp[-1].Number;
+ yyDay = -yyvsp[0].Number;
+ }
+break;
+case 23:
+#line 221 "getdate.y"
+{
+ /* e.g. 17-JUN-1992. */
+ yyDay = yyvsp[-2].Number;
+ yyMonth = yyvsp[-1].Number;
+ yyYear = -yyvsp[0].Number;
+ }
+break;
+case 24:
+#line 227 "getdate.y"
+{
+ yyMonth = yyvsp[-1].Number;
+ yyDay = yyvsp[0].Number;
+ }
+break;
+case 25:
+#line 231 "getdate.y"
+{
+ yyMonth = yyvsp[-3].Number;
+ yyDay = yyvsp[-2].Number;
+ yyYear = yyvsp[0].Number;
+ }
+break;
+case 26:
+#line 236 "getdate.y"
+{
+ yyMonth = yyvsp[0].Number;
+ yyDay = yyvsp[-1].Number;
+ }
+break;
+case 27:
+#line 240 "getdate.y"
+{
+ yyMonth = yyvsp[-1].Number;
+ yyDay = yyvsp[-2].Number;
+ yyYear = yyvsp[0].Number;
+ }
+break;
+case 28:
+#line 247 "getdate.y"
+{
+ yyRelSeconds = -yyRelSeconds;
+ yyRelMonth = -yyRelMonth;
+ }
+break;
+case 30:
+#line 254 "getdate.y"
+{
+ yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
+ }
+break;
+case 31:
+#line 257 "getdate.y"
+{
+ yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
+ }
+break;
+case 32:
+#line 260 "getdate.y"
+{
+ yyRelSeconds += yyvsp[0].Number * 60L;
+ }
+break;
+case 33:
+#line 263 "getdate.y"
+{
+ yyRelSeconds += yyvsp[-1].Number;
+ }
+break;
+case 34:
+#line 266 "getdate.y"
+{
+ yyRelSeconds += yyvsp[-1].Number;
+ }
+break;
+case 35:
+#line 269 "getdate.y"
+{
+ yyRelSeconds++;
+ }
+break;
+case 36:
+#line 272 "getdate.y"
+{
+ yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
+ }
+break;
+case 37:
+#line 275 "getdate.y"
+{
+ yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
+ }
+break;
+case 38:
+#line 278 "getdate.y"
+{
+ yyRelMonth += yyvsp[0].Number;
+ }
+break;
+case 39:
+#line 283 "getdate.y"
+{
+ if (yyHaveTime && yyHaveDate && !yyHaveRel)
+ yyYear = yyvsp[0].Number;
+ else {
+ if(yyvsp[0].Number>10000) {
+ yyHaveDate++;
+ yyDay= (yyvsp[0].Number)%100;
+ yyMonth= (yyvsp[0].Number/100)%100;
+ yyYear = yyvsp[0].Number/10000;
+ }
+ else {
+ yyHaveTime++;
+ if (yyvsp[0].Number < 100) {
+ yyHour = yyvsp[0].Number;
+ yyMinutes = 0;
+ }
+ else {
+ yyHour = yyvsp[0].Number / 100;
+ yyMinutes = yyvsp[0].Number % 100;
+ }
+ yySeconds = 0;
+ yyMeridian = MER24;
+ }
+ }
+ }
+break;
+case 40:
+#line 310 "getdate.y"
+{
+ yyval.Meridian = MER24;
+ }
+break;
+case 41:
+#line 313 "getdate.y"
+{
+ yyval.Meridian = yyvsp[0].Meridian;
+ }
+break;
+#line 1455 "getdate.c"
+ }
+ yyssp -= yym;
+ yystate = *yyssp;
+ yyvsp -= yym;
+ yym = yylhs[yyn];
+ if (yystate == 0 && yym == 0)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state 0 to\
+ state %d\n", YYPREFIX, YYFINAL);
+#endif
+ yystate = YYFINAL;
+ *++yyssp = YYFINAL;
+ *++yyvsp = yyval;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, YYFINAL, yychar, yys);
+ }
+#endif
+ }
+ if (yychar == 0) goto yyaccept;
+ goto yyloop;
+ }
+ if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
+ yystate = yytable[yyn];
+ else
+ yystate = yydgoto[yym];
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state %d \
+to state %d\n", YYPREFIX, *yyssp, yystate);
+#endif
+ if (yyssp >= yysslim && yygrowstack())
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate;
+ *++yyvsp = yyval;
+ goto yyloop;
+yyoverflow:
+ yyerror("yacc stack overflow");
+yyabort:
+ if (yyss)
+ free(yyss);
+ if (yyvs)
+ free(yyvs);
+ yyss = yyssp = NULL;
+ yyvs = yyvsp = NULL;
+ yystacksize = 0;
+ return (1);
+yyaccept:
+ if (yyss)
+ free(yyss);
+ if (yyvs)
+ free(yyvs);
+ yyss = yyssp = NULL;
+ yyvs = yyvsp = NULL;
+ yystacksize = 0;
+ return (0);
+}
diff --git a/plugins/sudoers/getdate.y b/plugins/sudoers/getdate.y
new file mode 100644
index 0000000..e23ef8d
--- /dev/null
+++ b/plugins/sudoers/getdate.y
@@ -0,0 +1,939 @@
+%{
+/*
+** Originally written by Steven M. Bellovin <smb@research.att.com> while
+** at the University of North Carolina at Chapel Hill. Later tweaked by
+** a couple of people on Usenet. Completely overhauled by Rich $alz
+** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
+**
+** This grammar has 10 shift/reduce conflicts.
+**
+** This code is in the public domain and has no copyright.
+*/
+/* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
+/* SUPPRESS 288 on yyerrlab *//* Label unused */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#include <time.h>
+#include <limits.h>
+#include <ctype.h>
+
+#include "sudo_compat.h"
+
+
+#define EPOCH 1970
+#define HOUR(x) ((time_t)(x) * 60)
+#define SECSPERDAY (24L * 60L * 60L)
+
+
+/*
+** An entry in the lexical lookup table.
+*/
+typedef struct _TABLE {
+ char *name;
+ int type;
+ time_t value;
+} TABLE;
+
+
+/*
+** Daylight-savings mode: on, off, or not yet known.
+*/
+typedef enum _DSTMODE {
+ DSTon, DSToff, DSTmaybe
+} DSTMODE;
+
+/*
+** Meridian: am, pm, or 24-hour style.
+*/
+typedef enum _MERIDIAN {
+ MERam, MERpm, MER24
+} MERIDIAN;
+
+
+/*
+** Global variables. We could get rid of most of these by using a good
+** union as the yacc stack. (This routine was originally written before
+** yacc had the %union construct.) Maybe someday; right now we only use
+** the %union very rarely.
+*/
+static char *yyInput;
+static DSTMODE yyDSTmode;
+static time_t yyDayOrdinal;
+static time_t yyDayNumber;
+static int yyHaveDate;
+static int yyHaveDay;
+static int yyHaveRel;
+static int yyHaveTime;
+static int yyHaveZone;
+static time_t yyTimezone;
+static time_t yyDay;
+static time_t yyHour;
+static time_t yyMinutes;
+static time_t yyMonth;
+static time_t yySeconds;
+static time_t yyYear;
+static MERIDIAN yyMeridian;
+static time_t yyRelMonth;
+static time_t yyRelSeconds;
+
+static int yyerror(const char *s);
+static int yylex(void);
+ int yyparse(void);
+
+%}
+
+%union {
+ time_t Number;
+ enum _MERIDIAN Meridian;
+}
+
+%token tAGO tDAY tDAYZONE tID tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
+%token tSEC_UNIT tSNUMBER tUNUMBER tZONE tDST
+
+%type <Number> tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT
+%type <Number> tSEC_UNIT tSNUMBER tUNUMBER tZONE
+%type <Meridian> tMERIDIAN o_merid
+
+%%
+
+spec : /* NULL */
+ | spec item
+ ;
+
+item : time {
+ yyHaveTime++;
+ }
+ | zone {
+ yyHaveZone++;
+ }
+ | date {
+ yyHaveDate++;
+ }
+ | day {
+ yyHaveDay++;
+ }
+ | rel {
+ yyHaveRel++;
+ }
+ | number
+ ;
+
+time : tUNUMBER tMERIDIAN {
+ yyHour = $1;
+ yyMinutes = 0;
+ yySeconds = 0;
+ yyMeridian = $2;
+ }
+ | tUNUMBER ':' tUNUMBER o_merid {
+ yyHour = $1;
+ yyMinutes = $3;
+ yySeconds = 0;
+ yyMeridian = $4;
+ }
+ | tUNUMBER ':' tUNUMBER tSNUMBER {
+ yyHour = $1;
+ yyMinutes = $3;
+ yyMeridian = MER24;
+ yyDSTmode = DSToff;
+ yyTimezone = - ($4 % 100 + ($4 / 100) * 60);
+ }
+ | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
+ yyHour = $1;
+ yyMinutes = $3;
+ yySeconds = $5;
+ yyMeridian = $6;
+ }
+ | tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER {
+ yyHour = $1;
+ yyMinutes = $3;
+ yySeconds = $5;
+ yyMeridian = MER24;
+ yyDSTmode = DSToff;
+ yyTimezone = - ($6 % 100 + ($6 / 100) * 60);
+ }
+ ;
+
+zone : tZONE {
+ yyTimezone = $1;
+ yyDSTmode = DSToff;
+ }
+ | tDAYZONE {
+ yyTimezone = $1;
+ yyDSTmode = DSTon;
+ }
+ |
+ tZONE tDST {
+ yyTimezone = $1;
+ yyDSTmode = DSTon;
+ }
+ ;
+
+day : tDAY {
+ yyDayOrdinal = 1;
+ yyDayNumber = $1;
+ }
+ | tDAY ',' {
+ yyDayOrdinal = 1;
+ yyDayNumber = $1;
+ }
+ | tUNUMBER tDAY {
+ yyDayOrdinal = $1;
+ yyDayNumber = $2;
+ }
+ ;
+
+date : tUNUMBER '/' tUNUMBER {
+ yyMonth = $1;
+ yyDay = $3;
+ }
+ | tUNUMBER '/' tUNUMBER '/' tUNUMBER {
+ if ($1 >= 100) {
+ yyYear = $1;
+ yyMonth = $3;
+ yyDay = $5;
+ } else {
+ yyMonth = $1;
+ yyDay = $3;
+ yyYear = $5;
+ }
+ }
+ | tUNUMBER tSNUMBER tSNUMBER {
+ /* ISO 8601 format. yyyy-mm-dd. */
+ yyYear = $1;
+ yyMonth = -$2;
+ yyDay = -$3;
+ }
+ | tUNUMBER tMONTH tSNUMBER {
+ /* e.g. 17-JUN-1992. */
+ yyDay = $1;
+ yyMonth = $2;
+ yyYear = -$3;
+ }
+ | tMONTH tUNUMBER {
+ yyMonth = $1;
+ yyDay = $2;
+ }
+ | tMONTH tUNUMBER ',' tUNUMBER {
+ yyMonth = $1;
+ yyDay = $2;
+ yyYear = $4;
+ }
+ | tUNUMBER tMONTH {
+ yyMonth = $2;
+ yyDay = $1;
+ }
+ | tUNUMBER tMONTH tUNUMBER {
+ yyMonth = $2;
+ yyDay = $1;
+ yyYear = $3;
+ }
+ ;
+
+rel : relunit tAGO {
+ yyRelSeconds = -yyRelSeconds;
+ yyRelMonth = -yyRelMonth;
+ }
+ | relunit
+ ;
+
+relunit : tUNUMBER tMINUTE_UNIT {
+ yyRelSeconds += $1 * $2 * 60L;
+ }
+ | tSNUMBER tMINUTE_UNIT {
+ yyRelSeconds += $1 * $2 * 60L;
+ }
+ | tMINUTE_UNIT {
+ yyRelSeconds += $1 * 60L;
+ }
+ | tSNUMBER tSEC_UNIT {
+ yyRelSeconds += $1;
+ }
+ | tUNUMBER tSEC_UNIT {
+ yyRelSeconds += $1;
+ }
+ | tSEC_UNIT {
+ yyRelSeconds++;
+ }
+ | tSNUMBER tMONTH_UNIT {
+ yyRelMonth += $1 * $2;
+ }
+ | tUNUMBER tMONTH_UNIT {
+ yyRelMonth += $1 * $2;
+ }
+ | tMONTH_UNIT {
+ yyRelMonth += $1;
+ }
+ ;
+
+number : tUNUMBER {
+ if (yyHaveTime && yyHaveDate && !yyHaveRel)
+ yyYear = $1;
+ else {
+ if($1>10000) {
+ yyHaveDate++;
+ yyDay= ($1)%100;
+ yyMonth= ($1/100)%100;
+ yyYear = $1/10000;
+ }
+ else {
+ yyHaveTime++;
+ if ($1 < 100) {
+ yyHour = $1;
+ yyMinutes = 0;
+ }
+ else {
+ yyHour = $1 / 100;
+ yyMinutes = $1 % 100;
+ }
+ yySeconds = 0;
+ yyMeridian = MER24;
+ }
+ }
+ }
+ ;
+
+o_merid : /* NULL */ {
+ $$ = MER24;
+ }
+ | tMERIDIAN {
+ $$ = $1;
+ }
+ ;
+
+%%
+
+/* Month and day table. */
+static TABLE const MonthDayTable[] = {
+ { "january", tMONTH, 1 },
+ { "february", tMONTH, 2 },
+ { "march", tMONTH, 3 },
+ { "april", tMONTH, 4 },
+ { "may", tMONTH, 5 },
+ { "june", tMONTH, 6 },
+ { "july", tMONTH, 7 },
+ { "august", tMONTH, 8 },
+ { "september", tMONTH, 9 },
+ { "sept", tMONTH, 9 },
+ { "october", tMONTH, 10 },
+ { "november", tMONTH, 11 },
+ { "december", tMONTH, 12 },
+ { "sunday", tDAY, 0 },
+ { "monday", tDAY, 1 },
+ { "tuesday", tDAY, 2 },
+ { "tues", tDAY, 2 },
+ { "wednesday", tDAY, 3 },
+ { "wednes", tDAY, 3 },
+ { "thursday", tDAY, 4 },
+ { "thur", tDAY, 4 },
+ { "thurs", tDAY, 4 },
+ { "friday", tDAY, 5 },
+ { "saturday", tDAY, 6 },
+ { NULL }
+};
+
+/* Time units table. */
+static TABLE const UnitsTable[] = {
+ { "year", tMONTH_UNIT, 12 },
+ { "month", tMONTH_UNIT, 1 },
+ { "fortnight", tMINUTE_UNIT, 14 * 24 * 60 },
+ { "week", tMINUTE_UNIT, 7 * 24 * 60 },
+ { "day", tMINUTE_UNIT, 1 * 24 * 60 },
+ { "hour", tMINUTE_UNIT, 60 },
+ { "minute", tMINUTE_UNIT, 1 },
+ { "min", tMINUTE_UNIT, 1 },
+ { "second", tSEC_UNIT, 1 },
+ { "sec", tSEC_UNIT, 1 },
+ { NULL }
+};
+
+/* Assorted relative-time words. */
+static TABLE const OtherTable[] = {
+ { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
+ { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
+ { "today", tMINUTE_UNIT, 0 },
+ { "now", tMINUTE_UNIT, 0 },
+ { "last", tUNUMBER, -1 },
+ { "this", tUNUMBER, 0 },
+ { "next", tUNUMBER, 2 },
+ { "first", tUNUMBER, 1 },
+/* { "second", tUNUMBER, 2 }, */
+ { "third", tUNUMBER, 3 },
+ { "fourth", tUNUMBER, 4 },
+ { "fifth", tUNUMBER, 5 },
+ { "sixth", tUNUMBER, 6 },
+ { "seventh", tUNUMBER, 7 },
+ { "eighth", tUNUMBER, 8 },
+ { "ninth", tUNUMBER, 9 },
+ { "tenth", tUNUMBER, 10 },
+ { "eleventh", tUNUMBER, 11 },
+ { "twelfth", tUNUMBER, 12 },
+ { "ago", tAGO, 1 },
+ { NULL }
+};
+
+/* The timezone table. */
+/* Some of these are commented out because a time_t can't store a float. */
+static TABLE const TimezoneTable[] = {
+ { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */
+ { "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */
+ { "utc", tZONE, HOUR( 0) },
+ { "wet", tZONE, HOUR( 0) }, /* Western European */
+ { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */
+ { "wat", tZONE, HOUR( 1) }, /* West Africa */
+ { "at", tZONE, HOUR( 2) }, /* Azores */
+#if 0
+ /* For completeness. BST is also British Summer, and GST is
+ * also Guam Standard. */
+ { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */
+ { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */
+#endif
+#if 0
+ { "nft", tZONE, HOUR(3.5) }, /* Newfoundland */
+ { "nst", tZONE, HOUR(3.5) }, /* Newfoundland Standard */
+ { "ndt", tDAYZONE, HOUR(3.5) }, /* Newfoundland Daylight */
+#endif
+ { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */
+ { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */
+ { "est", tZONE, HOUR( 5) }, /* Eastern Standard */
+ { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */
+ { "cst", tZONE, HOUR( 6) }, /* Central Standard */
+ { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */
+ { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */
+ { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */
+ { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */
+ { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */
+ { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */
+ { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */
+ { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */
+ { "hdt", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */
+ { "cat", tZONE, HOUR(10) }, /* Central Alaska */
+ { "ahst", tZONE, HOUR(10) }, /* Alaska-Hawaii Standard */
+ { "nt", tZONE, HOUR(11) }, /* Nome */
+ { "idlw", tZONE, HOUR(12) }, /* International Date Line West */
+ { "cet", tZONE, -HOUR(1) }, /* Central European */
+ { "met", tZONE, -HOUR(1) }, /* Middle European */
+ { "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */
+ { "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */
+ { "swt", tZONE, -HOUR(1) }, /* Swedish Winter */
+ { "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */
+ { "fwt", tZONE, -HOUR(1) }, /* French Winter */
+ { "fst", tDAYZONE, -HOUR(1) }, /* French Summer */
+ { "eet", tZONE, -HOUR(2) }, /* Eastern Europe, USSR Zone 1 */
+ { "bt", tZONE, -HOUR(3) }, /* Baghdad, USSR Zone 2 */
+#if 0
+ { "it", tZONE, -HOUR(3.5) },/* Iran */
+#endif
+ { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */
+ { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */
+#if 0
+ { "ist", tZONE, -HOUR(5.5) },/* Indian Standard */
+#endif
+ { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */
+#if 0
+ /* For completeness. NST is also Newfoundland Stanard, and SST is
+ * also Swedish Summer. */
+ { "nst", tZONE, -HOUR(6.5) },/* North Sumatra */
+ { "sst", tZONE, -HOUR(7) }, /* South Sumatra, USSR Zone 6 */
+#endif /* 0 */
+ { "wast", tZONE, -HOUR(7) }, /* West Australian Standard */
+ { "wadt", tDAYZONE, -HOUR(7) }, /* West Australian Daylight */
+#if 0
+ { "jt", tZONE, -HOUR(7.5) },/* Java (3pm in Cronusland!) */
+#endif
+ { "cct", tZONE, -HOUR(8) }, /* China Coast, USSR Zone 7 */
+ { "jst", tZONE, -HOUR(9) }, /* Japan Standard, USSR Zone 8 */
+#if 0
+ { "cast", tZONE, -HOUR(9.5) },/* Central Australian Standard */
+ { "cadt", tDAYZONE, -HOUR(9.5) },/* Central Australian Daylight */
+#endif
+ { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */
+ { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */
+ { "gst", tZONE, -HOUR(10) }, /* Guam Standard, USSR Zone 9 */
+ { "nzt", tZONE, -HOUR(12) }, /* New Zealand */
+ { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */
+ { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */
+ { "idle", tZONE, -HOUR(12) }, /* International Date Line East */
+ { NULL }
+};
+
+/* Military timezone table. */
+static TABLE const MilitaryTable[] = {
+ { "a", tZONE, HOUR( 1) },
+ { "b", tZONE, HOUR( 2) },
+ { "c", tZONE, HOUR( 3) },
+ { "d", tZONE, HOUR( 4) },
+ { "e", tZONE, HOUR( 5) },
+ { "f", tZONE, HOUR( 6) },
+ { "g", tZONE, HOUR( 7) },
+ { "h", tZONE, HOUR( 8) },
+ { "i", tZONE, HOUR( 9) },
+ { "k", tZONE, HOUR( 10) },
+ { "l", tZONE, HOUR( 11) },
+ { "m", tZONE, HOUR( 12) },
+ { "n", tZONE, HOUR(- 1) },
+ { "o", tZONE, HOUR(- 2) },
+ { "p", tZONE, HOUR(- 3) },
+ { "q", tZONE, HOUR(- 4) },
+ { "r", tZONE, HOUR(- 5) },
+ { "s", tZONE, HOUR(- 6) },
+ { "t", tZONE, HOUR(- 7) },
+ { "u", tZONE, HOUR(- 8) },
+ { "v", tZONE, HOUR(- 9) },
+ { "w", tZONE, HOUR(-10) },
+ { "x", tZONE, HOUR(-11) },
+ { "y", tZONE, HOUR(-12) },
+ { "z", tZONE, HOUR( 0) },
+ { NULL }
+};
+
+
+
+
+/* ARGSUSED */
+static int
+yyerror(const char *s)
+{
+ return 0;
+}
+
+
+static time_t
+ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian)
+{
+ if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
+ return -1;
+ switch (Meridian) {
+ case MER24:
+ if (Hours < 0 || Hours > 23)
+ return -1;
+ return (Hours * 60L + Minutes) * 60L + Seconds;
+ case MERam:
+ if (Hours < 1 || Hours > 12)
+ return -1;
+ if (Hours == 12)
+ Hours = 0;
+ return (Hours * 60L + Minutes) * 60L + Seconds;
+ case MERpm:
+ if (Hours < 1 || Hours > 12)
+ return -1;
+ if (Hours == 12)
+ Hours = 0;
+ return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
+ default:
+ abort ();
+ }
+ /* NOTREACHED */
+}
+
+
+/* Year is either
+ * A negative number, which means to use its absolute value (why?)
+ * A number from 0 to 99, which means a year from 1900 to 1999, or
+ * The actual year (>=100). */
+static time_t
+Convert(time_t Month, time_t Day, time_t Year, time_t Hours, time_t Minutes,
+ time_t Seconds, MERIDIAN Meridian, DSTMODE DSTmode)
+{
+ static int DaysInMonth[12] = {
+ 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+ };
+ struct tm *tm;
+ time_t tod;
+ time_t Julian;
+ int i;
+
+ if (Year < 0)
+ Year = -Year;
+ if (Year < 69)
+ Year += 2000;
+ else if (Year < 100) {
+ Year += 1900;
+ if (Year < EPOCH)
+ Year += 100;
+ }
+ DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
+ ? 29 : 28;
+ /* 32-bit time_t cannot represent years past 2038 */
+ if (Year < EPOCH || (sizeof(time_t) == sizeof(int) && Year > 2038)
+ || Month < 1 || Month > 12
+ /* Lint fluff: "conversion from long may lose accuracy" */
+ || Day < 1 || Day > DaysInMonth[(int)--Month])
+ return -1;
+
+ for (Julian = Day - 1, i = 0; i < Month; i++)
+ Julian += DaysInMonth[i];
+ for (i = EPOCH; i < Year; i++)
+ Julian += 365 + (i % 4 == 0);
+ Julian *= SECSPERDAY;
+ Julian += yyTimezone * 60L;
+ if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
+ return -1;
+ Julian += tod;
+ if (DSTmode == DSTon
+ || (DSTmode == DSTmaybe && (tm = localtime(&Julian)) && tm->tm_isdst))
+ Julian -= 60 * 60;
+ return Julian;
+}
+
+
+static time_t
+DSTcorrect(time_t Start, time_t Future)
+{
+ struct tm *start_tm;
+ struct tm *future_tm;
+ time_t StartDay;
+ time_t FutureDay;
+
+ start_tm = localtime(&Start);
+ future_tm = localtime(&Future);
+ if (!start_tm || !future_tm)
+ return -1;
+
+ StartDay = (start_tm->tm_hour + 1) % 24;
+ FutureDay = (future_tm->tm_hour + 1) % 24;
+ return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
+}
+
+
+static time_t
+RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber)
+{
+ struct tm *tm;
+ time_t now;
+
+ now = Start;
+ if (!(tm = localtime(&now)))
+ return -1;
+ now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
+ now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
+ return DSTcorrect(Start, now);
+}
+
+
+static time_t
+RelativeMonth(time_t Start, time_t RelMonth)
+{
+ struct tm *tm;
+ time_t Month;
+ time_t Year;
+
+ if (RelMonth == 0)
+ return 0;
+ if (!(tm = localtime(&Start)))
+ return -1;
+ Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
+ Year = Month / 12;
+ Month = Month % 12 + 1;
+ return DSTcorrect(Start,
+ Convert(Month, (time_t)tm->tm_mday, Year,
+ (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
+ MER24, DSTmaybe));
+}
+
+
+static int
+LookupWord(char *buff)
+{
+ char *p;
+ char *q;
+ const TABLE *tp;
+ int i;
+ int abbrev;
+
+ /* Make it lowercase. */
+ for (p = buff; *p; p++)
+ if (isupper((unsigned char)*p))
+ *p = tolower((unsigned char)*p);
+
+ if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
+ yylval.Meridian = MERam;
+ return tMERIDIAN;
+ }
+ if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
+ yylval.Meridian = MERpm;
+ return tMERIDIAN;
+ }
+
+ /* See if we have an abbreviation for a month. */
+ if (strlen(buff) == 3)
+ abbrev = 1;
+ else if (strlen(buff) == 4 && buff[3] == '.') {
+ abbrev = 1;
+ buff[3] = '\0';
+ }
+ else
+ abbrev = 0;
+
+ for (tp = MonthDayTable; tp->name; tp++) {
+ if (abbrev) {
+ if (strncmp(buff, tp->name, 3) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ }
+ else if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ }
+
+ for (tp = TimezoneTable; tp->name; tp++)
+ if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ if (strcmp(buff, "dst") == 0)
+ return tDST;
+
+ for (tp = UnitsTable; tp->name; tp++)
+ if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ /* Strip off any plural and try the units table again. */
+ i = strlen(buff) - 1;
+ if (buff[i] == 's') {
+ buff[i] = '\0';
+ for (tp = UnitsTable; tp->name; tp++)
+ if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ buff[i] = 's'; /* Put back for "this" in OtherTable. */
+ }
+
+ for (tp = OtherTable; tp->name; tp++)
+ if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ /* Military timezones. */
+ if (buff[1] == '\0' && isalpha((unsigned char)*buff)) {
+ for (tp = MilitaryTable; tp->name; tp++)
+ if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+ }
+
+ /* Drop out any periods and try the timezone table again. */
+ for (i = 0, p = q = buff; *q; q++)
+ if (*q != '.')
+ *p++ = *q;
+ else
+ i++;
+ *p = '\0';
+ if (i)
+ for (tp = TimezoneTable; tp->name; tp++)
+ if (strcmp(buff, tp->name) == 0) {
+ yylval.Number = tp->value;
+ return tp->type;
+ }
+
+ return tID;
+}
+
+
+static int
+yylex(void)
+{
+ char c;
+ char *p;
+ char buff[20];
+ int Count;
+ int sign;
+
+ for ( ; ; ) {
+ while (isspace((unsigned char)*yyInput))
+ yyInput++;
+
+ if (isdigit((unsigned char)(c = *yyInput)) || c == '-' || c == '+') {
+ if (c == '-' || c == '+') {
+ sign = c == '-' ? -1 : 1;
+ if (!isdigit((unsigned char)*++yyInput))
+ /* skip the '-' sign */
+ continue;
+ }
+ else
+ sign = 0;
+ for (yylval.Number = 0; isdigit((unsigned char)(c = *yyInput++)); )
+ yylval.Number = 10 * yylval.Number + c - '0';
+ yyInput--;
+ if (sign < 0)
+ yylval.Number = -yylval.Number;
+ return sign ? tSNUMBER : tUNUMBER;
+ }
+ if (isalpha((unsigned char)c)) {
+ for (p = buff; isalpha((unsigned char)(c = *yyInput++)) || c == '.'; )
+ if (p < &buff[sizeof buff - 1])
+ *p++ = c;
+ *p = '\0';
+ yyInput--;
+ return LookupWord(buff);
+ }
+ if (c != '(')
+ return *yyInput++;
+ Count = 0;
+ do {
+ c = *yyInput++;
+ if (c == '\0')
+ return c;
+ if (c == '(')
+ Count++;
+ else if (c == ')')
+ Count--;
+ } while (Count > 0);
+ }
+}
+
+#define TM_YEAR_ORIGIN 1900
+
+/* Yield A - B, measured in seconds. */
+static long
+difftm(struct tm *a, struct tm *b)
+{
+ int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
+ int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
+ int days = (
+ /* difference in day of year */
+ a->tm_yday - b->tm_yday
+ /* + intervening leap days */
+ + ((ay >> 2) - (by >> 2))
+ - (ay/100 - by/100)
+ + ((ay/100 >> 2) - (by/100 >> 2))
+ /* + difference in years * 365 */
+ + (long)(ay-by) * 365
+ );
+ return (60*(60*(24*days + (a->tm_hour - b->tm_hour))
+ + (a->tm_min - b->tm_min))
+ + (a->tm_sec - b->tm_sec));
+}
+
+time_t
+get_date(char *p)
+{
+ struct tm *tm, *gmt, gmtbuf;
+ time_t Start;
+ time_t tod;
+ time_t now;
+ time_t timezone;
+
+ yyInput = p;
+ (void)time (&now);
+
+ gmt = gmtime (&now);
+ if (gmt != NULL)
+ {
+ /* Make a copy, in case localtime modifies *tm (I think
+ that comment now applies to *gmt, but I am too
+ lazy to dig into how gmtime and locatime allocate the
+ structures they return pointers to). */
+ gmtbuf = *gmt;
+ gmt = &gmtbuf;
+ }
+
+ if (! (tm = localtime (&now)))
+ return -1;
+
+ if (gmt != NULL)
+ timezone = difftm (gmt, tm) / 60;
+ else
+ /* We are on a system like VMS, where the system clock is
+ in local time and the system has no concept of timezones.
+ Hopefully we can fake this out (for the case in which the
+ user specifies no timezone) by just saying the timezone
+ is zero. */
+ timezone = 0;
+
+ if(tm->tm_isdst)
+ timezone += 60;
+
+ yyYear = tm->tm_year + 1900;
+ yyMonth = tm->tm_mon + 1;
+ yyDay = tm->tm_mday;
+ yyTimezone = timezone;
+ yyDSTmode = DSTmaybe;
+ yyHour = 0;
+ yyMinutes = 0;
+ yySeconds = 0;
+ yyMeridian = MER24;
+ yyRelSeconds = 0;
+ yyRelMonth = 0;
+ yyHaveDate = 0;
+ yyHaveDay = 0;
+ yyHaveRel = 0;
+ yyHaveTime = 0;
+ yyHaveZone = 0;
+
+ if (yyparse()
+ || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
+ return -1;
+
+ if (yyHaveDate || yyHaveTime || yyHaveDay) {
+ Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
+ yyMeridian, yyDSTmode);
+ if (Start < 0)
+ return -1;
+ }
+ else {
+ Start = now;
+ if (!yyHaveRel)
+ Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec;
+ }
+
+ Start += yyRelSeconds;
+ Start += RelativeMonth(Start, yyRelMonth);
+
+ if (yyHaveDay && !yyHaveDate) {
+ tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
+ Start += tod;
+ }
+
+ /* Have to do *something* with a legitimate -1 so it's distinguishable
+ * from the error return value. (Alternately could set errno on error.) */
+ return Start == -1 ? 0 : Start;
+}
+
+
+#ifdef TEST
+
+/* ARGSUSED */
+int
+main(int argc, char *argv[])
+{
+ char buff[128];
+ time_t d;
+
+ (void)printf("Enter date, or blank line to exit.\n\t> ");
+ (void)fflush(stdout);
+ while (fgets(buff, sizeof(buff), stdin) && buff[0]) {
+ d = get_date(buff);
+ if (d == -1)
+ (void)printf("Bad format - couldn't convert.\n");
+ else
+ (void)printf("%s", ctime(&d));
+ (void)printf("\t> ");
+ (void)fflush(stdout);
+ }
+ exit(0);
+ /* NOTREACHED */
+}
+#endif /* TEST */
diff --git a/plugins/sudoers/getspwuid.c b/plugins/sudoers/getspwuid.c
new file mode 100644
index 0000000..da77769
--- /dev/null
+++ b/plugins/sudoers/getspwuid.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2010-2012, 2014-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#ifdef HAVE_GETSPNAM
+# include <shadow.h>
+#endif /* HAVE_GETSPNAM */
+#ifdef HAVE_GETPRPWNAM
+# ifdef __hpux
+# undef MAXINT
+# include <hpsecurity.h>
+# else
+# include <sys/security.h>
+# endif /* __hpux */
+# include <prot.h>
+#endif /* HAVE_GETPRPWNAM */
+
+#include "sudoers.h"
+
+/*
+ * Exported for auth/secureware.c
+ */
+#if defined(HAVE_GETPRPWNAM) && defined(__alpha)
+int crypt_type = INT_MAX;
+#endif /* HAVE_GETPRPWNAM && __alpha */
+
+/*
+ * Return a copy of the encrypted password for the user described by pw.
+ * If shadow passwords are in use, look in the shadow file.
+ */
+char *
+sudo_getepw(const struct passwd *pw)
+{
+ char *epw = NULL;
+ debug_decl(sudo_getepw, SUDOERS_DEBUG_AUTH)
+
+ /* If there is a function to check for shadow enabled, use it... */
+#ifdef HAVE_ISCOMSEC
+ if (!iscomsec())
+ goto done;
+#endif /* HAVE_ISCOMSEC */
+
+#ifdef HAVE_GETPWNAM_SHADOW
+ {
+ struct passwd *spw;
+
+ if ((spw = getpwnam_shadow(pw->pw_name)) != NULL)
+ epw = spw->pw_passwd;
+ }
+#endif /* HAVE_GETPWNAM_SHADOW */
+#ifdef HAVE_GETPRPWNAM
+ {
+ struct pr_passwd *spw;
+
+ if ((spw = getprpwnam(pw->pw_name)) && spw->ufld.fd_encrypt) {
+# ifdef __alpha
+ crypt_type = spw->ufld.fd_oldcrypt;
+# endif /* __alpha */
+ epw = spw->ufld.fd_encrypt;
+ }
+ }
+#endif /* HAVE_GETPRPWNAM */
+#ifdef HAVE_GETSPNAM
+ {
+ struct spwd *spw;
+
+ if ((spw = getspnam(pw->pw_name)) && spw->sp_pwdp)
+ epw = spw->sp_pwdp;
+ }
+#endif /* HAVE_GETSPNAM */
+
+#if defined(HAVE_ISCOMSEC)
+done:
+#endif
+ /* If no shadow password, fall back on regular password. */
+ debug_return_str(strdup(epw ? epw : pw->pw_passwd));
+}
+
+void
+sudo_setspent(void)
+{
+ debug_decl(sudo_setspent, SUDOERS_DEBUG_AUTH)
+
+#ifdef HAVE_GETPRPWNAM
+ setprpwent();
+#endif
+#ifdef HAVE_GETSPNAM
+ setspent();
+#endif
+ debug_return;
+}
+
+void
+sudo_endspent(void)
+{
+ debug_decl(sudo_endspent, SUDOERS_DEBUG_AUTH)
+
+#ifdef HAVE_GETPRPWNAM
+ endprpwent();
+#endif
+#ifdef HAVE_GETSPNAM
+ endspent();
+#endif
+ debug_return;
+}
diff --git a/plugins/sudoers/gmtoff.c b/plugins/sudoers/gmtoff.c
new file mode 100644
index 0000000..2e62d9f
--- /dev/null
+++ b/plugins/sudoers/gmtoff.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "sudo_compat.h"
+#include "sudoers_debug.h"
+#include "parse.h"
+
+/*
+ * Returns the offset from GMT in seconds (algorithm taken from sendmail).
+ * Warning: clobbers the static storage used by localtime() and gmtime().
+ */
+#ifdef HAVE_STRUCT_TM_TM_GMTOFF
+long
+get_gmtoff(time_t *clock)
+{
+ struct tm *local;
+
+ local = localtime(clock);
+ return local->tm_gmtoff;
+}
+#else
+long
+get_gmtoff(time_t *clock)
+{
+ struct tm *gm, gmt, *local;
+ long offset;
+
+ if ((gm = gmtime(clock)) == NULL)
+ return 0;
+ gmt = *gm;
+ if ((local = localtime(clock)) == NULL)
+ return 0;
+
+ offset = (local->tm_sec - gmt.tm_sec) +
+ ((local->tm_min - gmt.tm_min) * 60) +
+ ((local->tm_hour - gmt.tm_hour) * 3600);
+
+ /* Timezone may cause year rollover to happen on a different day. */
+ if (local->tm_year < gmt.tm_year)
+ offset -= 24 * 3600;
+ else if (local->tm_year > gmt.tm_year)
+ offset -= 24 * 3600;
+ else if (local->tm_yday < gmt.tm_yday)
+ offset -= 24 * 3600;
+ else if (local->tm_yday > gmt.tm_yday)
+ offset += 24 * 3600;
+
+ return offset;
+}
+#endif /* HAVE_TM_GMTOFF */
diff --git a/plugins/sudoers/goodpath.c b/plugins/sudoers/goodpath.c
new file mode 100644
index 0000000..a570e48
--- /dev/null
+++ b/plugins/sudoers/goodpath.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2010-2012, 2014-2016
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+
+#include "sudoers.h"
+
+/*
+ * Verify that path is a normal file and executable by root.
+ */
+bool
+sudo_goodpath(const char *path, struct stat *sbp)
+{
+ bool ret = false;
+ debug_decl(sudo_goodpath, SUDOERS_DEBUG_UTIL)
+
+ if (path != NULL) {
+ struct stat sb;
+
+ if (sbp == NULL)
+ sbp = &sb;
+
+ if (stat(path, sbp) == 0) {
+ /* Make sure path describes an executable regular file. */
+ if (S_ISREG(sbp->st_mode) && ISSET(sbp->st_mode, S_IXUSR|S_IXGRP|S_IXOTH))
+ ret = true;
+ else
+ errno = EACCES;
+ }
+ }
+
+ debug_return_bool(ret);
+}
diff --git a/plugins/sudoers/gram.c b/plugins/sudoers/gram.c
new file mode 100644
index 0000000..fff971b
--- /dev/null
+++ b/plugins/sudoers/gram.c
@@ -0,0 +1,2300 @@
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#define YYBYACC 1
+#define YYMAJOR 1
+#define YYMINOR 9
+#define YYLEX yylex()
+#define YYEMPTY -1
+#define yyclearin (yychar=(YYEMPTY))
+#define yyerrok (yyerrflag=0)
+#define YYRECOVERING() (yyerrflag!=0)
+#define yyparse sudoersparse
+#define yylex sudoerslex
+#define yyerror sudoerserror
+#define yychar sudoerschar
+#define yyval sudoersval
+#define yylval sudoerslval
+#define yydebug sudoersdebug
+#define yynerrs sudoersnerrs
+#define yyerrflag sudoerserrflag
+#define yyss sudoersss
+#define yysslim sudoerssslim
+#define yyssp sudoersssp
+#define yyvs sudoersvs
+#define yyvsp sudoersvsp
+#define yystacksize sudoersstacksize
+#define yylhs sudoerslhs
+#define yylen sudoerslen
+#define yydefred sudoersdefred
+#define yydgoto sudoersdgoto
+#define yysindex sudoerssindex
+#define yyrindex sudoersrindex
+#define yygindex sudoersgindex
+#define yytable sudoerstable
+#define yycheck sudoerscheck
+#define yyname sudoersname
+#define yyrule sudoersrule
+#define YYPREFIX "sudoers"
+#line 2 "gram.y"
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2013, 2014-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
+# include <alloca.h>
+#endif /* YYBISON && HAVE_ALLOCA_H && !__GNUC__ */
+#include <errno.h>
+
+#include "sudoers.h"
+#include "sudo_digest.h"
+#include "toke.h"
+
+/* If we last saw a newline the entry is on the preceding line. */
+#define this_lineno (last_token == COMMENT ? sudolineno - 1 : sudolineno)
+
+/*
+ * Globals
+ */
+bool sudoers_warnings = true;
+bool parse_error = false;
+int errorlineno = -1;
+char *errorfile = NULL;
+
+struct sudoers_parse_tree parsed_policy = {
+ TAILQ_HEAD_INITIALIZER(parsed_policy.userspecs),
+ TAILQ_HEAD_INITIALIZER(parsed_policy.defaults),
+ NULL /* aliases */
+};
+
+/*
+ * Local protoypes
+ */
+static void init_options(struct command_options *opts);
+static bool add_defaults(int, struct member *, struct defaults *);
+static bool add_userspec(struct member *, struct privilege *);
+static struct defaults *new_default(char *, char *, short);
+static struct member *new_member(char *, int);
+static struct command_digest *new_digest(int, char *);
+#line 78 "gram.y"
+#ifndef YYSTYPE_DEFINED
+#define YYSTYPE_DEFINED
+typedef union {
+ struct cmndspec *cmndspec;
+ struct defaults *defaults;
+ struct member *member;
+ struct runascontainer *runas;
+ struct privilege *privilege;
+ struct command_digest *digest;
+ struct sudo_command command;
+ struct command_options options;
+ struct cmndtag tag;
+ char *string;
+ int tok;
+} YYSTYPE;
+#endif /* YYSTYPE_DEFINED */
+#line 131 "gram.c"
+#define COMMAND 257
+#define ALIAS 258
+#define DEFVAR 259
+#define NTWKADDR 260
+#define NETGROUP 261
+#define USERGROUP 262
+#define WORD 263
+#define DIGEST 264
+#define DEFAULTS 265
+#define DEFAULTS_HOST 266
+#define DEFAULTS_USER 267
+#define DEFAULTS_RUNAS 268
+#define DEFAULTS_CMND 269
+#define NOPASSWD 270
+#define PASSWD 271
+#define NOEXEC 272
+#define EXEC 273
+#define SETENV 274
+#define NOSETENV 275
+#define LOG_INPUT 276
+#define NOLOG_INPUT 277
+#define LOG_OUTPUT 278
+#define NOLOG_OUTPUT 279
+#define MAIL 280
+#define NOMAIL 281
+#define FOLLOW 282
+#define NOFOLLOW 283
+#define ALL 284
+#define COMMENT 285
+#define HOSTALIAS 286
+#define CMNDALIAS 287
+#define USERALIAS 288
+#define RUNASALIAS 289
+#define ERROR 290
+#define TYPE 291
+#define ROLE 292
+#define PRIVS 293
+#define LIMITPRIVS 294
+#define CMND_TIMEOUT 295
+#define NOTBEFORE 296
+#define NOTAFTER 297
+#define MYSELF 298
+#define SHA224_TOK 299
+#define SHA256_TOK 300
+#define SHA384_TOK 301
+#define SHA512_TOK 302
+#define YYERRCODE 256
+#if defined(__cplusplus) || defined(__STDC__)
+const short sudoerslhs[] =
+#else
+short sudoerslhs[] =
+#endif
+ { -1,
+ 0, 0, 32, 32, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 4, 4, 3, 3,
+ 3, 3, 3, 21, 21, 20, 11, 11, 9, 9,
+ 9, 9, 9, 2, 2, 1, 31, 31, 31, 31,
+ 7, 7, 6, 6, 28, 29, 30, 24, 25, 26,
+ 27, 18, 18, 19, 19, 19, 19, 19, 23, 23,
+ 23, 23, 23, 23, 23, 23, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 5, 5, 5, 35, 35, 38, 10, 10, 36,
+ 36, 39, 8, 8, 37, 37, 40, 34, 34, 41,
+ 14, 14, 12, 12, 13, 13, 13, 13, 13, 17,
+ 17, 15, 15, 16, 16, 16,
+};
+#if defined(__cplusplus) || defined(__STDC__)
+const short sudoerslen[] =
+#else
+short sudoerslen[] =
+#endif
+ { 2,
+ 0, 1, 1, 2, 1, 2, 2, 2, 2, 2,
+ 2, 2, 3, 3, 3, 3, 1, 3, 1, 2,
+ 3, 3, 3, 1, 3, 3, 1, 2, 1, 1,
+ 1, 1, 1, 1, 3, 4, 3, 3, 3, 3,
+ 1, 2, 1, 2, 3, 3, 3, 3, 3, 3,
+ 3, 0, 3, 0, 1, 3, 2, 1, 0, 2,
+ 2, 2, 2, 2, 2, 2, 0, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 1, 1, 1, 1, 3, 3, 1, 3, 1,
+ 3, 3, 1, 3, 1, 3, 3, 1, 3, 3,
+ 1, 3, 1, 2, 1, 1, 1, 1, 1, 1,
+ 3, 1, 2, 1, 1, 1,
+};
+#if defined(__cplusplus) || defined(__STDC__)
+const short sudoersdefred[] =
+#else
+short sudoersdefred[] =
+#endif
+ { 0,
+ 0, 105, 107, 108, 109, 0, 0, 0, 0, 0,
+ 106, 5, 0, 0, 0, 0, 0, 0, 101, 103,
+ 0, 0, 3, 6, 0, 0, 17, 0, 29, 32,
+ 31, 33, 30, 0, 27, 0, 88, 0, 0, 84,
+ 83, 82, 0, 0, 0, 0, 0, 43, 41, 93,
+ 0, 0, 0, 0, 85, 0, 0, 90, 0, 0,
+ 98, 0, 0, 95, 104, 0, 0, 24, 0, 4,
+ 0, 0, 0, 20, 0, 28, 0, 0, 0, 0,
+ 44, 0, 0, 0, 0, 0, 0, 42, 0, 0,
+ 0, 0, 0, 0, 0, 0, 102, 0, 0, 21,
+ 22, 23, 18, 89, 37, 38, 39, 40, 94, 0,
+ 86, 0, 91, 0, 99, 0, 96, 0, 34, 0,
+ 59, 25, 0, 0, 0, 0, 0, 114, 116, 115,
+ 0, 110, 112, 0, 0, 53, 35, 0, 0, 0,
+ 0, 0, 0, 0, 0, 63, 64, 65, 66, 62,
+ 60, 61, 113, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 68, 69, 70, 71, 72, 73, 74, 75,
+ 76, 77, 80, 81, 78, 79, 36, 111, 49, 48,
+ 50, 51, 45, 46, 47,
+};
+#if defined(__cplusplus) || defined(__STDC__)
+const short sudoersdgoto[] =
+#else
+short sudoersdgoto[] =
+#endif
+ { 18,
+ 119, 120, 27, 28, 48, 49, 50, 51, 35, 67,
+ 37, 19, 20, 21, 132, 133, 134, 121, 125, 68,
+ 69, 145, 127, 146, 147, 148, 149, 150, 151, 152,
+ 52, 22, 23, 60, 54, 57, 63, 55, 58, 64,
+ 61,
+};
+#if defined(__cplusplus) || defined(__STDC__)
+const short sudoerssindex[] =
+#else
+short sudoerssindex[] =
+#endif
+ { 512,
+ -272, 0, 0, 0, 0, -23, 227, -19, -19, -5,
+ 0, 0, -239, -236, -234, -232, -231, 0, 0, 0,
+ -33, 512, 0, 0, -3, -220, 0, 3, 0, 0,
+ 0, 0, 0, -225, 0, -28, 0, -24, -24, 0,
+ 0, 0, -240, -15, -8, 2, 4, 0, 0, 0,
+ -21, -12, -9, 6, 0, 7, 12, 0, 10, 14,
+ 0, 13, 25, 0, 0, -19, -36, 0, 26, 0,
+ -208, -202, -198, 0, -23, 0, 227, 3, 3, 3,
+ 0, -179, -178, -174, -173, -5, 3, 0, 227, -239,
+ -5, -236, -19, -234, -19, -232, 0, 52, 227, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,
+ 0, 51, 0, 54, 0, 54, 0, -29, 0, 55,
+ 0, 0, 289, -7, 59, 52, -216, 0, 0, 0,
+ -217, 0, 0, 57, 289, 0, 0, 32, 41, 42,
+ 43, 44, 45, 47, 450, 0, 0, 0, 0, 0,
+ 0, 0, 0, 289, 57, -154, -153, -150, -149, -148,
+ -147, -146, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,};
+#if defined(__cplusplus) || defined(__STDC__)
+const short sudoersrindex[] =
+#else
+short sudoersrindex[] =
+#endif
+ { 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 119, 0, 0, 1, 0, 0, 145, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 159, 0, 0, 193, 0, 0, 207,
+ 0, 0, 241, 0, 0, 0, 0, 0, 275, 0,
+ 0, 0, 0, 0, 0, 0, 0, 309, 323, 357,
+ 0, 0, 0, 0, 0, 0, 371, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 404, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 49, 0, 63, 0, 97, 0, 79, 0, 111,
+ 0, 0, 81, 82, 0, 404, 483, 0, 0, 0,
+ 0, 0, 0, 83, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 84, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,};
+#if defined(__cplusplus) || defined(__STDC__)
+const short sudoersgindex[] =
+#else
+short sudoersgindex[] =
+#endif
+ { 0,
+ 5, 0, 53, 18, 86, 74, -79, 36, 98, -1,
+ 56, 68, 120, -6, -18, 8, 11, 0, 0, 39,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 113, 0, 0, 0, 0, 58, 48, 46,
+ 60,
+};
+#define YYTABLESIZE 801
+#if defined(__cplusplus) || defined(__STDC__)
+const short sudoerstable[] =
+#else
+short sudoerstable[] =
+#endif
+ { 34,
+ 19, 38, 39, 17, 26, 36, 109, 77, 26, 26,
+ 66, 26, 24, 17, 87, 77, 40, 41, 53, 66,
+ 43, 56, 86, 59, 98, 62, 2, 43, 123, 3,
+ 4, 5, 29, 19, 30, 31, 66, 32, 74, 72,
+ 128, 73, 82, 42, 19, 129, 75, 87, 92, 83,
+ 135, 89, 11, 78, 100, 79, 80, 71, 33, 84,
+ 101, 85, 100, 90, 102, 177, 130, 91, 87, 92,
+ 93, 94, 87, 95, 138, 139, 140, 141, 142, 143,
+ 144, 92, 96, 99, 105, 106, 114, 110, 116, 107,
+ 108, 118, 156, 77, 86, 100, 97, 66, 126, 136,
+ 154, 157, 158, 159, 160, 161, 92, 162, 179, 180,
+ 26, 124, 181, 182, 183, 184, 185, 1, 2, 54,
+ 100, 58, 55, 57, 56, 88, 112, 103, 81, 97,
+ 137, 76, 104, 97, 70, 178, 65, 122, 153, 113,
+ 0, 117, 0, 26, 12, 155, 0, 111, 0, 0,
+ 0, 0, 0, 115, 97, 0, 0, 0, 9, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 26, 0,
+ 0, 0, 0, 0, 0, 0, 0, 12, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 9, 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 29, 10, 30, 31, 2, 32,
+ 25, 3, 4, 5, 25, 25, 0, 25, 2, 8,
+ 11, 3, 4, 5, 40, 41, 0, 0, 0, 0,
+ 33, 40, 41, 0, 11, 0, 19, 0, 19, 34,
+ 0, 19, 19, 19, 11, 19, 19, 19, 19, 19,
+ 87, 42, 87, 11, 7, 87, 87, 87, 42, 87,
+ 87, 87, 87, 87, 19, 19, 19, 19, 19, 19,
+ 0, 0, 0, 44, 45, 46, 47, 0, 87, 87,
+ 87, 87, 87, 87, 92, 0, 92, 7, 15, 92,
+ 92, 92, 0, 92, 92, 92, 92, 92, 100, 0,
+ 100, 131, 13, 100, 100, 100, 0, 100, 100, 100,
+ 100, 100, 92, 92, 92, 92, 92, 92, 0, 0,
+ 0, 15, 0, 0, 0, 0, 100, 100, 100, 100,
+ 100, 100, 97, 0, 97, 13, 14, 97, 97, 97,
+ 0, 97, 97, 97, 97, 97, 26, 0, 26, 0,
+ 16, 26, 26, 26, 0, 26, 26, 26, 26, 26,
+ 97, 97, 97, 97, 97, 97, 0, 0, 0, 14,
+ 0, 0, 0, 0, 26, 26, 26, 26, 26, 26,
+ 12, 0, 12, 16, 0, 12, 12, 12, 0, 12,
+ 12, 12, 12, 12, 9, 0, 9, 0, 0, 9,
+ 9, 9, 0, 9, 9, 9, 9, 9, 12, 12,
+ 12, 12, 12, 12, 0, 0, 52, 0, 0, 0,
+ 0, 0, 9, 9, 9, 9, 9, 9, 10, 0,
+ 10, 0, 0, 10, 10, 10, 0, 10, 10, 10,
+ 10, 10, 8, 0, 8, 0, 0, 8, 8, 8,
+ 0, 8, 8, 8, 8, 8, 10, 10, 10, 10,
+ 10, 10, 43, 0, 29, 0, 30, 31, 0, 32,
+ 8, 8, 8, 8, 8, 8, 11, 0, 11, 0,
+ 0, 11, 11, 11, 0, 11, 11, 11, 11, 11,
+ 33, 0, 0, 0, 0, 67, 0, 0, 0, 0,
+ 0, 0, 0, 0, 11, 11, 11, 11, 11, 11,
+ 7, 0, 7, 0, 0, 7, 7, 7, 0, 7,
+ 7, 7, 7, 7, 17, 0, 128, 0, 0, 0,
+ 0, 129, 0, 0, 0, 0, 0, 0, 7, 7,
+ 7, 7, 7, 7, 15, 0, 15, 0, 0, 15,
+ 15, 15, 130, 15, 15, 15, 15, 15, 13, 0,
+ 13, 0, 0, 13, 13, 13, 0, 13, 13, 13,
+ 13, 13, 15, 15, 15, 15, 15, 15, 0, 0,
+ 0, 0, 0, 0, 0, 0, 13, 13, 13, 13,
+ 13, 13, 14, 0, 14, 0, 0, 14, 14, 14,
+ 0, 14, 14, 14, 14, 14, 16, 0, 16, 0,
+ 0, 16, 16, 16, 0, 16, 16, 16, 16, 16,
+ 14, 14, 14, 14, 14, 14, 0, 0, 0, 0,
+ 0, 0, 0, 0, 16, 16, 16, 16, 16, 16,
+ 52, 52, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 0, 0,
+ 0, 0, 0, 0, 52, 52, 52, 52, 52, 52,
+ 52, 0, 52, 52, 52, 52, 40, 41, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 163,
+ 164, 165, 166, 167, 168, 169, 170, 171, 172, 173,
+ 174, 175, 176, 42, 0, 0, 0, 0, 0, 67,
+ 67, 0, 0, 0, 0, 0, 0, 0, 44, 45,
+ 46, 47, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 1, 0, 2,
+ 0, 0, 3, 4, 5, 0, 6, 7, 8, 9,
+ 10, 67, 67, 67, 67, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 11, 12, 13, 14, 15,
+ 16,
+};
+#if defined(__cplusplus) || defined(__STDC__)
+const short sudoerscheck[] =
+#else
+short sudoerscheck[] =
+#endif
+ { 33,
+ 0, 8, 9, 33, 33, 7, 86, 44, 33, 33,
+ 44, 33, 285, 33, 0, 44, 257, 258, 258, 44,
+ 33, 258, 44, 258, 61, 258, 258, 33, 58, 261,
+ 262, 263, 258, 33, 260, 261, 44, 263, 259, 43,
+ 258, 45, 58, 284, 44, 263, 44, 33, 0, 58,
+ 58, 61, 284, 36, 263, 38, 39, 61, 284, 58,
+ 263, 58, 0, 58, 263, 145, 284, 61, 51, 58,
+ 61, 58, 58, 61, 291, 292, 293, 294, 295, 296,
+ 297, 33, 58, 58, 264, 264, 93, 89, 95, 264,
+ 264, 40, 61, 44, 44, 33, 0, 44, 44, 41,
+ 44, 61, 61, 61, 61, 61, 58, 61, 263, 263,
+ 0, 118, 263, 263, 263, 263, 263, 0, 0, 41,
+ 58, 41, 41, 41, 41, 52, 91, 75, 43, 33,
+ 126, 34, 77, 66, 22, 154, 17, 99, 131, 92,
+ -1, 96, -1, 33, 0, 135, -1, 90, -1, -1,
+ -1, -1, -1, 94, 58, -1, -1, -1, 0, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 58, -1,
+ -1, -1, -1, -1, -1, -1, -1, 33, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 33, 0, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 0, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 258, 33, 260, 261, 258, 263,
+ 259, 261, 262, 263, 259, 259, -1, 259, 258, 33,
+ 0, 261, 262, 263, 257, 258, -1, -1, -1, -1,
+ 284, 257, 258, -1, 284, -1, 256, -1, 258, 33,
+ -1, 261, 262, 263, 284, 265, 266, 267, 268, 269,
+ 256, 284, 258, 33, 0, 261, 262, 263, 284, 265,
+ 266, 267, 268, 269, 284, 285, 286, 287, 288, 289,
+ -1, -1, -1, 299, 300, 301, 302, -1, 284, 285,
+ 286, 287, 288, 289, 256, -1, 258, 33, 0, 261,
+ 262, 263, -1, 265, 266, 267, 268, 269, 256, -1,
+ 258, 33, 0, 261, 262, 263, -1, 265, 266, 267,
+ 268, 269, 284, 285, 286, 287, 288, 289, -1, -1,
+ -1, 33, -1, -1, -1, -1, 284, 285, 286, 287,
+ 288, 289, 256, -1, 258, 33, 0, 261, 262, 263,
+ -1, 265, 266, 267, 268, 269, 256, -1, 258, -1,
+ 0, 261, 262, 263, -1, 265, 266, 267, 268, 269,
+ 284, 285, 286, 287, 288, 289, -1, -1, -1, 33,
+ -1, -1, -1, -1, 284, 285, 286, 287, 288, 289,
+ 256, -1, 258, 33, -1, 261, 262, 263, -1, 265,
+ 266, 267, 268, 269, 256, -1, 258, -1, -1, 261,
+ 262, 263, -1, 265, 266, 267, 268, 269, 284, 285,
+ 286, 287, 288, 289, -1, -1, 33, -1, -1, -1,
+ -1, -1, 284, 285, 286, 287, 288, 289, 256, -1,
+ 258, -1, -1, 261, 262, 263, -1, 265, 266, 267,
+ 268, 269, 256, -1, 258, -1, -1, 261, 262, 263,
+ -1, 265, 266, 267, 268, 269, 284, 285, 286, 287,
+ 288, 289, 33, -1, 258, -1, 260, 261, -1, 263,
+ 284, 285, 286, 287, 288, 289, 256, -1, 258, -1,
+ -1, 261, 262, 263, -1, 265, 266, 267, 268, 269,
+ 284, -1, -1, -1, -1, 33, -1, -1, -1, -1,
+ -1, -1, -1, -1, 284, 285, 286, 287, 288, 289,
+ 256, -1, 258, -1, -1, 261, 262, 263, -1, 265,
+ 266, 267, 268, 269, 33, -1, 258, -1, -1, -1,
+ -1, 263, -1, -1, -1, -1, -1, -1, 284, 285,
+ 286, 287, 288, 289, 256, -1, 258, -1, -1, 261,
+ 262, 263, 284, 265, 266, 267, 268, 269, 256, -1,
+ 258, -1, -1, 261, 262, 263, -1, 265, 266, 267,
+ 268, 269, 284, 285, 286, 287, 288, 289, -1, -1,
+ -1, -1, -1, -1, -1, -1, 284, 285, 286, 287,
+ 288, 289, 256, -1, 258, -1, -1, 261, 262, 263,
+ -1, 265, 266, 267, 268, 269, 256, -1, 258, -1,
+ -1, 261, 262, 263, -1, 265, 266, 267, 268, 269,
+ 284, 285, 286, 287, 288, 289, -1, -1, -1, -1,
+ -1, -1, -1, -1, 284, 285, 286, 287, 288, 289,
+ 257, 258, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 270, 271, 272, 273, 274, 275, 276,
+ 277, 278, 279, 280, 281, 282, 283, 284, -1, -1,
+ -1, -1, -1, -1, 291, 292, 293, 294, 295, 296,
+ 297, -1, 299, 300, 301, 302, 257, 258, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 270,
+ 271, 272, 273, 274, 275, 276, 277, 278, 279, 280,
+ 281, 282, 283, 284, -1, -1, -1, -1, -1, 257,
+ 258, -1, -1, -1, -1, -1, -1, -1, 299, 300,
+ 301, 302, 270, 271, 272, 273, 274, 275, 276, 277,
+ 278, 279, 280, 281, 282, 283, 284, 256, -1, 258,
+ -1, -1, 261, 262, 263, -1, 265, 266, 267, 268,
+ 269, 299, 300, 301, 302, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 284, 285, 286, 287, 288,
+ 289,
+};
+#define YYFINAL 18
+#ifndef YYDEBUG
+#define YYDEBUG 0
+#endif
+#define YYMAXTOKEN 302
+#if YYDEBUG
+#if defined(__cplusplus) || defined(__STDC__)
+const char * const sudoersname[] =
+#else
+char *sudoersname[] =
+#endif
+ {
+"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+"'!'",0,0,0,0,0,0,"'('","')'",0,"'+'","','","'-'",0,0,0,0,0,0,0,0,0,0,0,0,"':'",
+0,0,"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+"COMMAND","ALIAS","DEFVAR","NTWKADDR","NETGROUP","USERGROUP","WORD","DIGEST",
+"DEFAULTS","DEFAULTS_HOST","DEFAULTS_USER","DEFAULTS_RUNAS","DEFAULTS_CMND",
+"NOPASSWD","PASSWD","NOEXEC","EXEC","SETENV","NOSETENV","LOG_INPUT",
+"NOLOG_INPUT","LOG_OUTPUT","NOLOG_OUTPUT","MAIL","NOMAIL","FOLLOW","NOFOLLOW",
+"ALL","COMMENT","HOSTALIAS","CMNDALIAS","USERALIAS","RUNASALIAS","ERROR","TYPE",
+"ROLE","PRIVS","LIMITPRIVS","CMND_TIMEOUT","NOTBEFORE","NOTAFTER","MYSELF",
+"SHA224_TOK","SHA256_TOK","SHA384_TOK","SHA512_TOK",
+};
+#if defined(__cplusplus) || defined(__STDC__)
+const char * const sudoersrule[] =
+#else
+char *sudoersrule[] =
+#endif
+ {"$accept : file",
+"file :",
+"file : line",
+"line : entry",
+"line : line entry",
+"entry : COMMENT",
+"entry : error COMMENT",
+"entry : userlist privileges",
+"entry : USERALIAS useraliases",
+"entry : HOSTALIAS hostaliases",
+"entry : CMNDALIAS cmndaliases",
+"entry : RUNASALIAS runasaliases",
+"entry : DEFAULTS defaults_list",
+"entry : DEFAULTS_USER userlist defaults_list",
+"entry : DEFAULTS_RUNAS userlist defaults_list",
+"entry : DEFAULTS_HOST hostlist defaults_list",
+"entry : DEFAULTS_CMND cmndlist defaults_list",
+"defaults_list : defaults_entry",
+"defaults_list : defaults_list ',' defaults_entry",
+"defaults_entry : DEFVAR",
+"defaults_entry : '!' DEFVAR",
+"defaults_entry : DEFVAR '=' WORD",
+"defaults_entry : DEFVAR '+' WORD",
+"defaults_entry : DEFVAR '-' WORD",
+"privileges : privilege",
+"privileges : privileges ':' privilege",
+"privilege : hostlist '=' cmndspeclist",
+"ophost : host",
+"ophost : '!' host",
+"host : ALIAS",
+"host : ALL",
+"host : NETGROUP",
+"host : NTWKADDR",
+"host : WORD",
+"cmndspeclist : cmndspec",
+"cmndspeclist : cmndspeclist ',' cmndspec",
+"cmndspec : runasspec options cmndtag digcmnd",
+"digest : SHA224_TOK ':' DIGEST",
+"digest : SHA256_TOK ':' DIGEST",
+"digest : SHA384_TOK ':' DIGEST",
+"digest : SHA512_TOK ':' DIGEST",
+"digcmnd : opcmnd",
+"digcmnd : digest opcmnd",
+"opcmnd : cmnd",
+"opcmnd : '!' cmnd",
+"timeoutspec : CMND_TIMEOUT '=' WORD",
+"notbeforespec : NOTBEFORE '=' WORD",
+"notafterspec : NOTAFTER '=' WORD",
+"rolespec : ROLE '=' WORD",
+"typespec : TYPE '=' WORD",
+"privsspec : PRIVS '=' WORD",
+"limitprivsspec : LIMITPRIVS '=' WORD",
+"runasspec :",
+"runasspec : '(' runaslist ')'",
+"runaslist :",
+"runaslist : userlist",
+"runaslist : userlist ':' grouplist",
+"runaslist : ':' grouplist",
+"runaslist : ':'",
+"options :",
+"options : options notbeforespec",
+"options : options notafterspec",
+"options : options timeoutspec",
+"options : options rolespec",
+"options : options typespec",
+"options : options privsspec",
+"options : options limitprivsspec",
+"cmndtag :",
+"cmndtag : cmndtag NOPASSWD",
+"cmndtag : cmndtag PASSWD",
+"cmndtag : cmndtag NOEXEC",
+"cmndtag : cmndtag EXEC",
+"cmndtag : cmndtag SETENV",
+"cmndtag : cmndtag NOSETENV",
+"cmndtag : cmndtag LOG_INPUT",
+"cmndtag : cmndtag NOLOG_INPUT",
+"cmndtag : cmndtag LOG_OUTPUT",
+"cmndtag : cmndtag NOLOG_OUTPUT",
+"cmndtag : cmndtag FOLLOW",
+"cmndtag : cmndtag NOFOLLOW",
+"cmndtag : cmndtag MAIL",
+"cmndtag : cmndtag NOMAIL",
+"cmnd : ALL",
+"cmnd : ALIAS",
+"cmnd : COMMAND",
+"hostaliases : hostalias",
+"hostaliases : hostaliases ':' hostalias",
+"hostalias : ALIAS '=' hostlist",
+"hostlist : ophost",
+"hostlist : hostlist ',' ophost",
+"cmndaliases : cmndalias",
+"cmndaliases : cmndaliases ':' cmndalias",
+"cmndalias : ALIAS '=' cmndlist",
+"cmndlist : digcmnd",
+"cmndlist : cmndlist ',' digcmnd",
+"runasaliases : runasalias",
+"runasaliases : runasaliases ':' runasalias",
+"runasalias : ALIAS '=' userlist",
+"useraliases : useralias",
+"useraliases : useraliases ':' useralias",
+"useralias : ALIAS '=' userlist",
+"userlist : opuser",
+"userlist : userlist ',' opuser",
+"opuser : user",
+"opuser : '!' user",
+"user : ALIAS",
+"user : ALL",
+"user : NETGROUP",
+"user : USERGROUP",
+"user : WORD",
+"grouplist : opgroup",
+"grouplist : grouplist ',' opgroup",
+"opgroup : group",
+"opgroup : '!' group",
+"group : ALIAS",
+"group : ALL",
+"group : WORD",
+};
+#endif
+#ifdef YYSTACKSIZE
+#undef YYMAXDEPTH
+#define YYMAXDEPTH YYSTACKSIZE
+#else
+#ifdef YYMAXDEPTH
+#define YYSTACKSIZE YYMAXDEPTH
+#else
+#define YYSTACKSIZE 10000
+#define YYMAXDEPTH 10000
+#endif
+#endif
+#define YYINITSTACKSIZE 200
+/* LINTUSED */
+int yydebug;
+int yynerrs;
+int yyerrflag;
+int yychar;
+short *yyssp;
+YYSTYPE *yyvsp;
+YYSTYPE yyval;
+YYSTYPE yylval;
+short *yyss;
+short *yysslim;
+YYSTYPE *yyvs;
+unsigned int yystacksize;
+int yyparse(void);
+#line 904 "gram.y"
+void
+sudoerserror(const char *s)
+{
+ debug_decl(sudoerserror, SUDOERS_DEBUG_PARSER)
+
+ /* Save the line the first error occurred on. */
+ if (errorlineno == -1) {
+ errorlineno = this_lineno;
+ rcstr_delref(errorfile);
+ errorfile = rcstr_addref(sudoers);
+ }
+ if (sudoers_warnings && s != NULL) {
+ LEXTRACE("<*> ");
+#ifndef TRACELEXER
+ if (trace_print == NULL || trace_print == sudoers_trace_print) {
+ const char fmt[] = ">>> %s: %s near line %d <<<\n";
+ int oldlocale;
+
+ /* Warnings are displayed in the user's locale. */
+ sudoers_setlocale(SUDOERS_LOCALE_USER, &oldlocale);
+ sudo_printf(SUDO_CONV_ERROR_MSG, _(fmt), sudoers, _(s), this_lineno);
+ sudoers_setlocale(oldlocale, NULL);
+ }
+#endif
+ }
+ parse_error = true;
+ debug_return;
+}
+
+static struct defaults *
+new_default(char *var, char *val, short op)
+{
+ struct defaults *d;
+ debug_decl(new_default, SUDOERS_DEBUG_PARSER)
+
+ if ((d = calloc(1, sizeof(struct defaults))) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+
+ d->var = var;
+ d->val = val;
+ /* d->type = 0; */
+ d->op = op;
+ /* d->binding = NULL */
+ d->lineno = this_lineno;
+ d->file = rcstr_addref(sudoers);
+ HLTQ_INIT(d, entries);
+
+ debug_return_ptr(d);
+}
+
+static struct member *
+new_member(char *name, int type)
+{
+ struct member *m;
+ debug_decl(new_member, SUDOERS_DEBUG_PARSER)
+
+ if ((m = calloc(1, sizeof(struct member))) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+
+ m->name = name;
+ m->type = type;
+ HLTQ_INIT(m, entries);
+
+ debug_return_ptr(m);
+}
+
+static struct command_digest *
+new_digest(int digest_type, char *digest_str)
+{
+ struct command_digest *digest;
+ debug_decl(new_digest, SUDOERS_DEBUG_PARSER)
+
+ if ((digest = malloc(sizeof(*digest))) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+
+ digest->digest_type = digest_type;
+ digest->digest_str = digest_str;
+ if (digest->digest_str == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ free(digest);
+ digest = NULL;
+ }
+
+ debug_return_ptr(digest);
+}
+
+/*
+ * Add a list of defaults structures to the defaults list.
+ * The binding, if non-NULL, specifies a list of hosts, users, or
+ * runas users the entries apply to (specified by the type).
+ */
+static bool
+add_defaults(int type, struct member *bmem, struct defaults *defs)
+{
+ struct defaults *d, *next;
+ struct member_list *binding;
+ bool ret = true;
+ debug_decl(add_defaults, SUDOERS_DEBUG_PARSER)
+
+ if (defs != NULL) {
+ /*
+ * We use a single binding for each entry in defs.
+ */
+ if ((binding = malloc(sizeof(*binding))) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ sudoerserror(N_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ if (bmem != NULL)
+ HLTQ_TO_TAILQ(binding, bmem, entries);
+ else
+ TAILQ_INIT(binding);
+
+ /*
+ * Set type and binding (who it applies to) for new entries.
+ * Then add to the global defaults list.
+ */
+ HLTQ_FOREACH_SAFE(d, defs, entries, next) {
+ d->type = type;
+ d->binding = binding;
+ TAILQ_INSERT_TAIL(&parsed_policy.defaults, d, entries);
+ }
+ }
+
+ debug_return_bool(ret);
+}
+
+/*
+ * Allocate a new struct userspec, populate it, and insert it at the
+ * end of the userspecs list.
+ */
+static bool
+add_userspec(struct member *members, struct privilege *privs)
+{
+ struct userspec *u;
+ debug_decl(add_userspec, SUDOERS_DEBUG_PARSER)
+
+ if ((u = calloc(1, sizeof(*u))) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_bool(false);
+ }
+ u->lineno = this_lineno;
+ u->file = rcstr_addref(sudoers);
+ HLTQ_TO_TAILQ(&u->users, members, entries);
+ HLTQ_TO_TAILQ(&u->privileges, privs, entries);
+ STAILQ_INIT(&u->comments);
+ TAILQ_INSERT_TAIL(&parsed_policy.userspecs, u, entries);
+
+ debug_return_bool(true);
+}
+
+/*
+ * Free a member struct and its contents.
+ */
+void
+free_member(struct member *m)
+{
+ debug_decl(free_member, SUDOERS_DEBUG_PARSER)
+
+ if (m->type == COMMAND) {
+ struct sudo_command *c = (struct sudo_command *)m->name;
+ free(c->cmnd);
+ free(c->args);
+ if (c->digest != NULL) {
+ free(c->digest->digest_str);
+ free(c->digest);
+ }
+ }
+ free(m->name);
+ free(m);
+
+ debug_return;
+}
+
+/*
+ * Free a tailq of members but not the struct member_list container itself.
+ */
+void
+free_members(struct member_list *members)
+{
+ struct member *m;
+ debug_decl(free_members, SUDOERS_DEBUG_PARSER)
+
+ while ((m = TAILQ_FIRST(members)) != NULL) {
+ TAILQ_REMOVE(members, m, entries);
+ free_member(m);
+ }
+
+ debug_return;
+}
+
+void
+free_defaults(struct defaults_list *defs)
+{
+ struct member_list *prev_binding = NULL;
+ struct defaults *def;
+ debug_decl(free_defaults, SUDOERS_DEBUG_PARSER)
+
+ while ((def = TAILQ_FIRST(defs)) != NULL) {
+ TAILQ_REMOVE(defs, def, entries);
+ free_default(def, &prev_binding);
+ }
+
+ debug_return;
+}
+
+void
+free_default(struct defaults *def, struct member_list **binding)
+{
+ debug_decl(free_default, SUDOERS_DEBUG_PARSER)
+
+ if (def->binding != *binding) {
+ *binding = def->binding;
+ if (def->binding != NULL) {
+ free_members(def->binding);
+ free(def->binding);
+ }
+ }
+ rcstr_delref(def->file);
+ free(def->var);
+ free(def->val);
+ free(def);
+
+ debug_return;
+}
+
+void
+free_privilege(struct privilege *priv)
+{
+ struct member_list *runasuserlist = NULL, *runasgrouplist = NULL;
+ struct member_list *prev_binding = NULL;
+ struct cmndspec *cs;
+ struct defaults *def;
+#ifdef HAVE_SELINUX
+ char *role = NULL, *type = NULL;
+#endif /* HAVE_SELINUX */
+#ifdef HAVE_PRIV_SET
+ char *privs = NULL, *limitprivs = NULL;
+#endif /* HAVE_PRIV_SET */
+ debug_decl(free_privilege, SUDOERS_DEBUG_PARSER)
+
+ free(priv->ldap_role);
+ free_members(&priv->hostlist);
+ while ((cs = TAILQ_FIRST(&priv->cmndlist)) != NULL) {
+ TAILQ_REMOVE(&priv->cmndlist, cs, entries);
+#ifdef HAVE_SELINUX
+ /* Only free the first instance of a role/type. */
+ if (cs->role != role) {
+ role = cs->role;
+ free(cs->role);
+ }
+ if (cs->type != type) {
+ type = cs->type;
+ free(cs->type);
+ }
+#endif /* HAVE_SELINUX */
+#ifdef HAVE_PRIV_SET
+ /* Only free the first instance of privs/limitprivs. */
+ if (cs->privs != privs) {
+ privs = cs->privs;
+ free(cs->privs);
+ }
+ if (cs->limitprivs != limitprivs) {
+ limitprivs = cs->limitprivs;
+ free(cs->limitprivs);
+ }
+#endif /* HAVE_PRIV_SET */
+ /* Only free the first instance of runas user/group lists. */
+ if (cs->runasuserlist && cs->runasuserlist != runasuserlist) {
+ runasuserlist = cs->runasuserlist;
+ free_members(runasuserlist);
+ free(runasuserlist);
+ }
+ if (cs->runasgrouplist && cs->runasgrouplist != runasgrouplist) {
+ runasgrouplist = cs->runasgrouplist;
+ free_members(runasgrouplist);
+ free(runasgrouplist);
+ }
+ free_member(cs->cmnd);
+ free(cs);
+ }
+ while ((def = TAILQ_FIRST(&priv->defaults)) != NULL) {
+ TAILQ_REMOVE(&priv->defaults, def, entries);
+ free_default(def, &prev_binding);
+ }
+ free(priv);
+
+ debug_return;
+}
+
+void
+free_userspecs(struct userspec_list *usl)
+{
+ struct userspec *us;
+ debug_decl(free_userspecs, SUDOERS_DEBUG_PARSER)
+
+ while ((us = TAILQ_FIRST(usl)) != NULL) {
+ TAILQ_REMOVE(usl, us, entries);
+ free_userspec(us);
+ }
+
+ debug_return;
+}
+
+void
+free_userspec(struct userspec *us)
+{
+ struct privilege *priv;
+ struct sudoers_comment *comment;
+ debug_decl(free_userspec, SUDOERS_DEBUG_PARSER)
+
+ free_members(&us->users);
+ while ((priv = TAILQ_FIRST(&us->privileges)) != NULL) {
+ TAILQ_REMOVE(&us->privileges, priv, entries);
+ free_privilege(priv);
+ }
+ while ((comment = STAILQ_FIRST(&us->comments)) != NULL) {
+ STAILQ_REMOVE_HEAD(&us->comments, entries);
+ free(comment->str);
+ free(comment);
+ }
+ rcstr_delref(us->file);
+ free(us);
+
+ debug_return;
+}
+
+/*
+ * Initialized a sudoers parse tree.
+ */
+void
+init_parse_tree(struct sudoers_parse_tree *parse_tree)
+{
+ TAILQ_INIT(&parse_tree->userspecs);
+ TAILQ_INIT(&parse_tree->defaults);
+ parse_tree->aliases = NULL;
+}
+
+/*
+ * Move the contents of parsed_policy to new_tree.
+ */
+void
+reparent_parse_tree(struct sudoers_parse_tree *new_tree)
+{
+ TAILQ_CONCAT(&new_tree->userspecs, &parsed_policy.userspecs, entries);
+ TAILQ_CONCAT(&new_tree->defaults, &parsed_policy.defaults, entries);
+ new_tree->aliases = parsed_policy.aliases;
+ parsed_policy.aliases = NULL;
+}
+
+/*
+ * Free the contents of a sudoers parse tree and initialize it.
+ */
+void
+free_parse_tree(struct sudoers_parse_tree *parse_tree)
+{
+ free_userspecs(&parse_tree->userspecs);
+ free_defaults(&parse_tree->defaults);
+ free_aliases(parse_tree->aliases);
+ parse_tree->aliases = NULL;
+}
+
+/*
+ * Free up space used by data structures from a previous parser run and sets
+ * the current sudoers file to path.
+ */
+bool
+init_parser(const char *path, bool quiet)
+{
+ bool ret = true;
+ debug_decl(init_parser, SUDOERS_DEBUG_PARSER)
+
+ free_parse_tree(&parsed_policy);
+ init_lexer();
+
+ rcstr_delref(sudoers);
+ if (path != NULL) {
+ if ((sudoers = rcstr_dup(path)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ ret = false;
+ }
+ } else {
+ sudoers = NULL;
+ }
+
+ parse_error = false;
+ errorlineno = -1;
+ rcstr_delref(errorfile);
+ errorfile = NULL;
+ sudoers_warnings = !quiet;
+
+ debug_return_bool(ret);
+}
+
+/*
+ * Initialize all options in a cmndspec.
+ */
+static void
+init_options(struct command_options *opts)
+{
+ opts->notbefore = UNSPEC;
+ opts->notafter = UNSPEC;
+ opts->timeout = UNSPEC;
+#ifdef HAVE_SELINUX
+ opts->role = NULL;
+ opts->type = NULL;
+#endif
+#ifdef HAVE_PRIV_SET
+ opts->privs = NULL;
+ opts->limitprivs = NULL;
+#endif
+}
+#line 1044 "gram.c"
+/* allocate initial stack or double stack size, up to YYMAXDEPTH */
+#if defined(__cplusplus) || defined(__STDC__)
+static int yygrowstack(void)
+#else
+static int yygrowstack()
+#endif
+{
+ unsigned int newsize;
+ long sslen;
+ short *newss;
+ YYSTYPE *newvs;
+
+ if ((newsize = yystacksize) == 0)
+ newsize = YYINITSTACKSIZE;
+ else if (newsize >= YYMAXDEPTH)
+ return -1;
+ else if ((newsize *= 2) > YYMAXDEPTH)
+ newsize = YYMAXDEPTH;
+#ifdef SIZE_MAX
+#define YY_SIZE_MAX SIZE_MAX
+#else
+#ifdef __STDC__
+#define YY_SIZE_MAX 0xffffffffU
+#else
+#define YY_SIZE_MAX (unsigned int)0xffffffff
+#endif
+#endif
+ if (YY_SIZE_MAX / newsize < sizeof *newss)
+ goto bail;
+ sslen = yyssp - yyss;
+ newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
+ (short *)malloc(newsize * sizeof *newss); /* overflow check above */
+ if (newss == NULL)
+ goto bail;
+ yyss = newss;
+ yyssp = newss + sslen;
+ newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
+ (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
+ if (newvs == NULL)
+ goto bail;
+ yyvs = newvs;
+ yyvsp = newvs + sslen;
+ yystacksize = newsize;
+ yysslim = yyss + newsize - 1;
+ return 0;
+bail:
+ if (yyss)
+ free(yyss);
+ if (yyvs)
+ free(yyvs);
+ yyss = yyssp = NULL;
+ yyvs = yyvsp = NULL;
+ yystacksize = 0;
+ return -1;
+}
+
+#define YYABORT goto yyabort
+#define YYREJECT goto yyabort
+#define YYACCEPT goto yyaccept
+#define YYERROR goto yyerrlab
+int
+#if defined(__cplusplus) || defined(__STDC__)
+yyparse(void)
+#else
+yyparse()
+#endif
+{
+ int yym, yyn, yystate;
+#if YYDEBUG
+#if defined(__cplusplus) || defined(__STDC__)
+ const char *yys;
+#else /* !(defined(__cplusplus) || defined(__STDC__)) */
+ char *yys;
+#endif /* !(defined(__cplusplus) || defined(__STDC__)) */
+
+ if ((yys = getenv("YYDEBUG")))
+ {
+ yyn = *yys;
+ if (yyn >= '0' && yyn <= '9')
+ yydebug = yyn - '0';
+ }
+#endif /* YYDEBUG */
+
+ yynerrs = 0;
+ yyerrflag = 0;
+ yychar = (-1);
+
+ if (yyss == NULL && yygrowstack()) goto yyoverflow;
+ yyssp = yyss;
+ yyvsp = yyvs;
+ *yyssp = yystate = 0;
+
+yyloop:
+ if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ }
+ if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, shifting to state %d\n",
+ YYPREFIX, yystate, yytable[yyn]);
+#endif
+ if (yyssp >= yysslim && yygrowstack())
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ yychar = (-1);
+ if (yyerrflag > 0) --yyerrflag;
+ goto yyloop;
+ }
+ if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+ yyn = yytable[yyn];
+ goto yyreduce;
+ }
+ if (yyerrflag) goto yyinrecovery;
+#if defined(__GNUC__)
+ goto yynewerror;
+#endif
+yynewerror:
+ yyerror("syntax error");
+#if defined(__GNUC__)
+ goto yyerrlab;
+#endif
+yyerrlab:
+ ++yynerrs;
+yyinrecovery:
+ if (yyerrflag < 3)
+ {
+ yyerrflag = 3;
+ for (;;)
+ {
+ if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, error recovery shifting\
+ to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
+#endif
+ if (yyssp >= yysslim && yygrowstack())
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ goto yyloop;
+ }
+ else
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: error recovery discarding state %d\n",
+ YYPREFIX, *yyssp);
+#endif
+ if (yyssp <= yyss) goto yyabort;
+ --yyssp;
+ --yyvsp;
+ }
+ }
+ }
+ else
+ {
+ if (yychar == 0) goto yyabort;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ yychar = (-1);
+ goto yyloop;
+ }
+yyreduce:
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, reducing by rule %d (%s)\n",
+ YYPREFIX, yystate, yyn, yyrule[yyn]);
+#endif
+ yym = yylen[yyn];
+ if (yym)
+ yyval = yyvsp[1-yym];
+ else
+ memset(&yyval, 0, sizeof yyval);
+ switch (yyn)
+ {
+case 1:
+#line 176 "gram.y"
+{ ; }
+break;
+case 5:
+#line 184 "gram.y"
+{
+ ;
+ }
+break;
+case 6:
+#line 187 "gram.y"
+{
+ yyerrok;
+ }
+break;
+case 7:
+#line 190 "gram.y"
+{
+ if (!add_userspec(yyvsp[-1].member, yyvsp[0].privilege)) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 8:
+#line 196 "gram.y"
+{
+ ;
+ }
+break;
+case 9:
+#line 199 "gram.y"
+{
+ ;
+ }
+break;
+case 10:
+#line 202 "gram.y"
+{
+ ;
+ }
+break;
+case 11:
+#line 205 "gram.y"
+{
+ ;
+ }
+break;
+case 12:
+#line 208 "gram.y"
+{
+ if (!add_defaults(DEFAULTS, NULL, yyvsp[0].defaults))
+ YYERROR;
+ }
+break;
+case 13:
+#line 212 "gram.y"
+{
+ if (!add_defaults(DEFAULTS_USER, yyvsp[-1].member, yyvsp[0].defaults))
+ YYERROR;
+ }
+break;
+case 14:
+#line 216 "gram.y"
+{
+ if (!add_defaults(DEFAULTS_RUNAS, yyvsp[-1].member, yyvsp[0].defaults))
+ YYERROR;
+ }
+break;
+case 15:
+#line 220 "gram.y"
+{
+ if (!add_defaults(DEFAULTS_HOST, yyvsp[-1].member, yyvsp[0].defaults))
+ YYERROR;
+ }
+break;
+case 16:
+#line 224 "gram.y"
+{
+ if (!add_defaults(DEFAULTS_CMND, yyvsp[-1].member, yyvsp[0].defaults))
+ YYERROR;
+ }
+break;
+case 18:
+#line 231 "gram.y"
+{
+ HLTQ_CONCAT(yyvsp[-2].defaults, yyvsp[0].defaults, entries);
+ yyval.defaults = yyvsp[-2].defaults;
+ }
+break;
+case 19:
+#line 237 "gram.y"
+{
+ yyval.defaults = new_default(yyvsp[0].string, NULL, true);
+ if (yyval.defaults == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 20:
+#line 244 "gram.y"
+{
+ yyval.defaults = new_default(yyvsp[0].string, NULL, false);
+ if (yyval.defaults == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 21:
+#line 251 "gram.y"
+{
+ yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, true);
+ if (yyval.defaults == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 22:
+#line 258 "gram.y"
+{
+ yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '+');
+ if (yyval.defaults == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 23:
+#line 265 "gram.y"
+{
+ yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '-');
+ if (yyval.defaults == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 25:
+#line 275 "gram.y"
+{
+ HLTQ_CONCAT(yyvsp[-2].privilege, yyvsp[0].privilege, entries);
+ yyval.privilege = yyvsp[-2].privilege;
+ }
+break;
+case 26:
+#line 281 "gram.y"
+{
+ struct privilege *p = calloc(1, sizeof(*p));
+ if (p == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ TAILQ_INIT(&p->defaults);
+ HLTQ_TO_TAILQ(&p->hostlist, yyvsp[-2].member, entries);
+ HLTQ_TO_TAILQ(&p->cmndlist, yyvsp[0].cmndspec, entries);
+ HLTQ_INIT(p, entries);
+ yyval.privilege = p;
+ }
+break;
+case 27:
+#line 295 "gram.y"
+{
+ yyval.member = yyvsp[0].member;
+ yyval.member->negated = false;
+ }
+break;
+case 28:
+#line 299 "gram.y"
+{
+ yyval.member = yyvsp[0].member;
+ yyval.member->negated = true;
+ }
+break;
+case 29:
+#line 305 "gram.y"
+{
+ yyval.member = new_member(yyvsp[0].string, ALIAS);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 30:
+#line 312 "gram.y"
+{
+ yyval.member = new_member(NULL, ALL);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 31:
+#line 319 "gram.y"
+{
+ yyval.member = new_member(yyvsp[0].string, NETGROUP);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 32:
+#line 326 "gram.y"
+{
+ yyval.member = new_member(yyvsp[0].string, NTWKADDR);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 33:
+#line 333 "gram.y"
+{
+ yyval.member = new_member(yyvsp[0].string, WORD);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 35:
+#line 343 "gram.y"
+{
+ struct cmndspec *prev;
+ prev = HLTQ_LAST(yyvsp[-2].cmndspec, cmndspec, entries);
+ HLTQ_CONCAT(yyvsp[-2].cmndspec, yyvsp[0].cmndspec, entries);
+#ifdef HAVE_SELINUX
+ /* propagate role and type */
+ if (yyvsp[0].cmndspec->role == NULL && yyvsp[0].cmndspec->type == NULL) {
+ yyvsp[0].cmndspec->role = prev->role;
+ yyvsp[0].cmndspec->type = prev->type;
+ }
+#endif /* HAVE_SELINUX */
+#ifdef HAVE_PRIV_SET
+ /* propagate privs & limitprivs */
+ if (yyvsp[0].cmndspec->privs == NULL && yyvsp[0].cmndspec->limitprivs == NULL) {
+ yyvsp[0].cmndspec->privs = prev->privs;
+ yyvsp[0].cmndspec->limitprivs = prev->limitprivs;
+ }
+#endif /* HAVE_PRIV_SET */
+ /* propagate command time restrictions */
+ if (yyvsp[0].cmndspec->notbefore == UNSPEC)
+ yyvsp[0].cmndspec->notbefore = prev->notbefore;
+ if (yyvsp[0].cmndspec->notafter == UNSPEC)
+ yyvsp[0].cmndspec->notafter = prev->notafter;
+ /* propagate command timeout */
+ if (yyvsp[0].cmndspec->timeout == UNSPEC)
+ yyvsp[0].cmndspec->timeout = prev->timeout;
+ /* propagate tags and runas list */
+ if (yyvsp[0].cmndspec->tags.nopasswd == UNSPEC)
+ yyvsp[0].cmndspec->tags.nopasswd = prev->tags.nopasswd;
+ if (yyvsp[0].cmndspec->tags.noexec == UNSPEC)
+ yyvsp[0].cmndspec->tags.noexec = prev->tags.noexec;
+ if (yyvsp[0].cmndspec->tags.setenv == UNSPEC &&
+ prev->tags.setenv != IMPLIED)
+ yyvsp[0].cmndspec->tags.setenv = prev->tags.setenv;
+ if (yyvsp[0].cmndspec->tags.log_input == UNSPEC)
+ yyvsp[0].cmndspec->tags.log_input = prev->tags.log_input;
+ if (yyvsp[0].cmndspec->tags.log_output == UNSPEC)
+ yyvsp[0].cmndspec->tags.log_output = prev->tags.log_output;
+ if (yyvsp[0].cmndspec->tags.send_mail == UNSPEC)
+ yyvsp[0].cmndspec->tags.send_mail = prev->tags.send_mail;
+ if (yyvsp[0].cmndspec->tags.follow == UNSPEC)
+ yyvsp[0].cmndspec->tags.follow = prev->tags.follow;
+ if ((yyvsp[0].cmndspec->runasuserlist == NULL &&
+ yyvsp[0].cmndspec->runasgrouplist == NULL) &&
+ (prev->runasuserlist != NULL ||
+ prev->runasgrouplist != NULL)) {
+ yyvsp[0].cmndspec->runasuserlist = prev->runasuserlist;
+ yyvsp[0].cmndspec->runasgrouplist = prev->runasgrouplist;
+ }
+ yyval.cmndspec = yyvsp[-2].cmndspec;
+ }
+break;
+case 36:
+#line 396 "gram.y"
+{
+ struct cmndspec *cs = calloc(1, sizeof(*cs));
+ if (cs == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ if (yyvsp[-3].runas != NULL) {
+ if (yyvsp[-3].runas->runasusers != NULL) {
+ cs->runasuserlist =
+ malloc(sizeof(*cs->runasuserlist));
+ if (cs->runasuserlist == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ HLTQ_TO_TAILQ(cs->runasuserlist,
+ yyvsp[-3].runas->runasusers, entries);
+ }
+ if (yyvsp[-3].runas->runasgroups != NULL) {
+ cs->runasgrouplist =
+ malloc(sizeof(*cs->runasgrouplist));
+ if (cs->runasgrouplist == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ HLTQ_TO_TAILQ(cs->runasgrouplist,
+ yyvsp[-3].runas->runasgroups, entries);
+ }
+ free(yyvsp[-3].runas);
+ }
+#ifdef HAVE_SELINUX
+ cs->role = yyvsp[-2].options.role;
+ cs->type = yyvsp[-2].options.type;
+#endif
+#ifdef HAVE_PRIV_SET
+ cs->privs = yyvsp[-2].options.privs;
+ cs->limitprivs = yyvsp[-2].options.limitprivs;
+#endif
+ cs->notbefore = yyvsp[-2].options.notbefore;
+ cs->notafter = yyvsp[-2].options.notafter;
+ cs->timeout = yyvsp[-2].options.timeout;
+ cs->tags = yyvsp[-1].tag;
+ cs->cmnd = yyvsp[0].member;
+ HLTQ_INIT(cs, entries);
+ /* sudo "ALL" implies the SETENV tag */
+ if (cs->cmnd->type == ALL && !cs->cmnd->negated &&
+ cs->tags.setenv == UNSPEC)
+ cs->tags.setenv = IMPLIED;
+ yyval.cmndspec = cs;
+ }
+break;
+case 37:
+#line 447 "gram.y"
+{
+ yyval.digest = new_digest(SUDO_DIGEST_SHA224, yyvsp[0].string);
+ if (yyval.digest == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 38:
+#line 454 "gram.y"
+{
+ yyval.digest = new_digest(SUDO_DIGEST_SHA256, yyvsp[0].string);
+ if (yyval.digest == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 39:
+#line 461 "gram.y"
+{
+ yyval.digest = new_digest(SUDO_DIGEST_SHA384, yyvsp[0].string);
+ if (yyval.digest == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 40:
+#line 468 "gram.y"
+{
+ yyval.digest = new_digest(SUDO_DIGEST_SHA512, yyvsp[0].string);
+ if (yyval.digest == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 41:
+#line 477 "gram.y"
+{
+ yyval.member = yyvsp[0].member;
+ }
+break;
+case 42:
+#line 480 "gram.y"
+{
+ if (yyvsp[0].member->type != COMMAND) {
+ sudoerserror(N_("a digest requires a path name"));
+ YYERROR;
+ }
+ /* XXX - yuck */
+ ((struct sudo_command *) yyvsp[0].member->name)->digest = yyvsp[-1].digest;
+ yyval.member = yyvsp[0].member;
+ }
+break;
+case 43:
+#line 491 "gram.y"
+{
+ yyval.member = yyvsp[0].member;
+ yyval.member->negated = false;
+ }
+break;
+case 44:
+#line 495 "gram.y"
+{
+ yyval.member = yyvsp[0].member;
+ yyval.member->negated = true;
+ }
+break;
+case 45:
+#line 501 "gram.y"
+{
+ yyval.string = yyvsp[0].string;
+ }
+break;
+case 46:
+#line 506 "gram.y"
+{
+ yyval.string = yyvsp[0].string;
+ }
+break;
+case 47:
+#line 510 "gram.y"
+{
+ yyval.string = yyvsp[0].string;
+ }
+break;
+case 48:
+#line 515 "gram.y"
+{
+ yyval.string = yyvsp[0].string;
+ }
+break;
+case 49:
+#line 520 "gram.y"
+{
+ yyval.string = yyvsp[0].string;
+ }
+break;
+case 50:
+#line 525 "gram.y"
+{
+ yyval.string = yyvsp[0].string;
+ }
+break;
+case 51:
+#line 529 "gram.y"
+{
+ yyval.string = yyvsp[0].string;
+ }
+break;
+case 52:
+#line 534 "gram.y"
+{
+ yyval.runas = NULL;
+ }
+break;
+case 53:
+#line 537 "gram.y"
+{
+ yyval.runas = yyvsp[-1].runas;
+ }
+break;
+case 54:
+#line 542 "gram.y"
+{
+ yyval.runas = calloc(1, sizeof(struct runascontainer));
+ if (yyval.runas != NULL) {
+ yyval.runas->runasusers = new_member(NULL, MYSELF);
+ /* $$->runasgroups = NULL; */
+ if (yyval.runas->runasusers == NULL) {
+ free(yyval.runas);
+ yyval.runas = NULL;
+ }
+ }
+ if (yyval.runas == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 55:
+#line 557 "gram.y"
+{
+ yyval.runas = calloc(1, sizeof(struct runascontainer));
+ if (yyval.runas == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ yyval.runas->runasusers = yyvsp[0].member;
+ /* $$->runasgroups = NULL; */
+ }
+break;
+case 56:
+#line 566 "gram.y"
+{
+ yyval.runas = calloc(1, sizeof(struct runascontainer));
+ if (yyval.runas == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ yyval.runas->runasusers = yyvsp[-2].member;
+ yyval.runas->runasgroups = yyvsp[0].member;
+ }
+break;
+case 57:
+#line 575 "gram.y"
+{
+ yyval.runas = calloc(1, sizeof(struct runascontainer));
+ if (yyval.runas == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ /* $$->runasusers = NULL; */
+ yyval.runas->runasgroups = yyvsp[0].member;
+ }
+break;
+case 58:
+#line 584 "gram.y"
+{
+ yyval.runas = calloc(1, sizeof(struct runascontainer));
+ if (yyval.runas != NULL) {
+ yyval.runas->runasusers = new_member(NULL, MYSELF);
+ /* $$->runasgroups = NULL; */
+ if (yyval.runas->runasusers == NULL) {
+ free(yyval.runas);
+ yyval.runas = NULL;
+ }
+ }
+ if (yyval.runas == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 59:
+#line 601 "gram.y"
+{
+ init_options(&yyval.options);
+ }
+break;
+case 60:
+#line 604 "gram.y"
+{
+ yyval.options.notbefore = parse_gentime(yyvsp[0].string);
+ free(yyvsp[0].string);
+ if (yyval.options.notbefore == -1) {
+ sudoerserror(N_("invalid notbefore value"));
+ YYERROR;
+ }
+ }
+break;
+case 61:
+#line 612 "gram.y"
+{
+ yyval.options.notafter = parse_gentime(yyvsp[0].string);
+ free(yyvsp[0].string);
+ if (yyval.options.notafter == -1) {
+ sudoerserror(N_("invalid notafter value"));
+ YYERROR;
+ }
+ }
+break;
+case 62:
+#line 620 "gram.y"
+{
+ yyval.options.timeout = parse_timeout(yyvsp[0].string);
+ free(yyvsp[0].string);
+ if (yyval.options.timeout == -1) {
+ if (errno == ERANGE)
+ sudoerserror(N_("timeout value too large"));
+ else
+ sudoerserror(N_("invalid timeout value"));
+ YYERROR;
+ }
+ }
+break;
+case 63:
+#line 631 "gram.y"
+{
+#ifdef HAVE_SELINUX
+ free(yyval.options.role);
+ yyval.options.role = yyvsp[0].string;
+#endif
+ }
+break;
+case 64:
+#line 637 "gram.y"
+{
+#ifdef HAVE_SELINUX
+ free(yyval.options.type);
+ yyval.options.type = yyvsp[0].string;
+#endif
+ }
+break;
+case 65:
+#line 643 "gram.y"
+{
+#ifdef HAVE_PRIV_SET
+ free(yyval.options.privs);
+ yyval.options.privs = yyvsp[0].string;
+#endif
+ }
+break;
+case 66:
+#line 649 "gram.y"
+{
+#ifdef HAVE_PRIV_SET
+ free(yyval.options.limitprivs);
+ yyval.options.limitprivs = yyvsp[0].string;
+#endif
+ }
+break;
+case 67:
+#line 657 "gram.y"
+{
+ TAGS_INIT(yyval.tag);
+ }
+break;
+case 68:
+#line 660 "gram.y"
+{
+ yyval.tag.nopasswd = true;
+ }
+break;
+case 69:
+#line 663 "gram.y"
+{
+ yyval.tag.nopasswd = false;
+ }
+break;
+case 70:
+#line 666 "gram.y"
+{
+ yyval.tag.noexec = true;
+ }
+break;
+case 71:
+#line 669 "gram.y"
+{
+ yyval.tag.noexec = false;
+ }
+break;
+case 72:
+#line 672 "gram.y"
+{
+ yyval.tag.setenv = true;
+ }
+break;
+case 73:
+#line 675 "gram.y"
+{
+ yyval.tag.setenv = false;
+ }
+break;
+case 74:
+#line 678 "gram.y"
+{
+ yyval.tag.log_input = true;
+ }
+break;
+case 75:
+#line 681 "gram.y"
+{
+ yyval.tag.log_input = false;
+ }
+break;
+case 76:
+#line 684 "gram.y"
+{
+ yyval.tag.log_output = true;
+ }
+break;
+case 77:
+#line 687 "gram.y"
+{
+ yyval.tag.log_output = false;
+ }
+break;
+case 78:
+#line 690 "gram.y"
+{
+ yyval.tag.follow = true;
+ }
+break;
+case 79:
+#line 693 "gram.y"
+{
+ yyval.tag.follow = false;
+ }
+break;
+case 80:
+#line 696 "gram.y"
+{
+ yyval.tag.send_mail = true;
+ }
+break;
+case 81:
+#line 699 "gram.y"
+{
+ yyval.tag.send_mail = false;
+ }
+break;
+case 82:
+#line 704 "gram.y"
+{
+ yyval.member = new_member(NULL, ALL);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 83:
+#line 711 "gram.y"
+{
+ yyval.member = new_member(yyvsp[0].string, ALIAS);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 84:
+#line 718 "gram.y"
+{
+ struct sudo_command *c = calloc(1, sizeof(*c));
+ if (c == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ c->cmnd = yyvsp[0].command.cmnd;
+ c->args = yyvsp[0].command.args;
+ yyval.member = new_member((char *)c, COMMAND);
+ if (yyval.member == NULL) {
+ free(c);
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 87:
+#line 739 "gram.y"
+{
+ const char *s;
+ s = alias_add(&parsed_policy, yyvsp[-2].string, HOSTALIAS,
+ sudoers, this_lineno, yyvsp[0].member);
+ if (s != NULL) {
+ sudoerserror(s);
+ YYERROR;
+ }
+ }
+break;
+case 89:
+#line 751 "gram.y"
+{
+ HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
+ yyval.member = yyvsp[-2].member;
+ }
+break;
+case 92:
+#line 761 "gram.y"
+{
+ const char *s;
+ s = alias_add(&parsed_policy, yyvsp[-2].string, CMNDALIAS,
+ sudoers, this_lineno, yyvsp[0].member);
+ if (s != NULL) {
+ sudoerserror(s);
+ YYERROR;
+ }
+ }
+break;
+case 94:
+#line 773 "gram.y"
+{
+ HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
+ yyval.member = yyvsp[-2].member;
+ }
+break;
+case 97:
+#line 783 "gram.y"
+{
+ const char *s;
+ s = alias_add(&parsed_policy, yyvsp[-2].string, RUNASALIAS,
+ sudoers, this_lineno, yyvsp[0].member);
+ if (s != NULL) {
+ sudoerserror(s);
+ YYERROR;
+ }
+ }
+break;
+case 100:
+#line 798 "gram.y"
+{
+ const char *s;
+ s = alias_add(&parsed_policy, yyvsp[-2].string, USERALIAS,
+ sudoers, this_lineno, yyvsp[0].member);
+ if (s != NULL) {
+ sudoerserror(s);
+ YYERROR;
+ }
+ }
+break;
+case 102:
+#line 810 "gram.y"
+{
+ HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
+ yyval.member = yyvsp[-2].member;
+ }
+break;
+case 103:
+#line 816 "gram.y"
+{
+ yyval.member = yyvsp[0].member;
+ yyval.member->negated = false;
+ }
+break;
+case 104:
+#line 820 "gram.y"
+{
+ yyval.member = yyvsp[0].member;
+ yyval.member->negated = true;
+ }
+break;
+case 105:
+#line 826 "gram.y"
+{
+ yyval.member = new_member(yyvsp[0].string, ALIAS);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 106:
+#line 833 "gram.y"
+{
+ yyval.member = new_member(NULL, ALL);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 107:
+#line 840 "gram.y"
+{
+ yyval.member = new_member(yyvsp[0].string, NETGROUP);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 108:
+#line 847 "gram.y"
+{
+ yyval.member = new_member(yyvsp[0].string, USERGROUP);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 109:
+#line 854 "gram.y"
+{
+ yyval.member = new_member(yyvsp[0].string, WORD);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 111:
+#line 864 "gram.y"
+{
+ HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
+ yyval.member = yyvsp[-2].member;
+ }
+break;
+case 112:
+#line 870 "gram.y"
+{
+ yyval.member = yyvsp[0].member;
+ yyval.member->negated = false;
+ }
+break;
+case 113:
+#line 874 "gram.y"
+{
+ yyval.member = yyvsp[0].member;
+ yyval.member->negated = true;
+ }
+break;
+case 114:
+#line 880 "gram.y"
+{
+ yyval.member = new_member(yyvsp[0].string, ALIAS);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 115:
+#line 887 "gram.y"
+{
+ yyval.member = new_member(NULL, ALL);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+case 116:
+#line 894 "gram.y"
+{
+ yyval.member = new_member(yyvsp[0].string, WORD);
+ if (yyval.member == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+break;
+#line 2173 "gram.c"
+ }
+ yyssp -= yym;
+ yystate = *yyssp;
+ yyvsp -= yym;
+ yym = yylhs[yyn];
+ if (yystate == 0 && yym == 0)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state 0 to\
+ state %d\n", YYPREFIX, YYFINAL);
+#endif
+ yystate = YYFINAL;
+ *++yyssp = YYFINAL;
+ *++yyvsp = yyval;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, YYFINAL, yychar, yys);
+ }
+#endif
+ }
+ if (yychar == 0) goto yyaccept;
+ goto yyloop;
+ }
+ if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
+ yystate = yytable[yyn];
+ else
+ yystate = yydgoto[yym];
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state %d \
+to state %d\n", YYPREFIX, *yyssp, yystate);
+#endif
+ if (yyssp >= yysslim && yygrowstack())
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate;
+ *++yyvsp = yyval;
+ goto yyloop;
+yyoverflow:
+ yyerror("yacc stack overflow");
+yyabort:
+ if (yyss)
+ free(yyss);
+ if (yyvs)
+ free(yyvs);
+ yyss = yyssp = NULL;
+ yyvs = yyvsp = NULL;
+ yystacksize = 0;
+ return (1);
+yyaccept:
+ if (yyss)
+ free(yyss);
+ if (yyvs)
+ free(yyvs);
+ yyss = yyssp = NULL;
+ yyvs = yyvsp = NULL;
+ yystacksize = 0;
+ return (0);
+}
diff --git a/plugins/sudoers/gram.h b/plugins/sudoers/gram.h
new file mode 100644
index 0000000..c53f97a
--- /dev/null
+++ b/plugins/sudoers/gram.h
@@ -0,0 +1,63 @@
+#define COMMAND 257
+#define ALIAS 258
+#define DEFVAR 259
+#define NTWKADDR 260
+#define NETGROUP 261
+#define USERGROUP 262
+#define WORD 263
+#define DIGEST 264
+#define DEFAULTS 265
+#define DEFAULTS_HOST 266
+#define DEFAULTS_USER 267
+#define DEFAULTS_RUNAS 268
+#define DEFAULTS_CMND 269
+#define NOPASSWD 270
+#define PASSWD 271
+#define NOEXEC 272
+#define EXEC 273
+#define SETENV 274
+#define NOSETENV 275
+#define LOG_INPUT 276
+#define NOLOG_INPUT 277
+#define LOG_OUTPUT 278
+#define NOLOG_OUTPUT 279
+#define MAIL 280
+#define NOMAIL 281
+#define FOLLOW 282
+#define NOFOLLOW 283
+#define ALL 284
+#define COMMENT 285
+#define HOSTALIAS 286
+#define CMNDALIAS 287
+#define USERALIAS 288
+#define RUNASALIAS 289
+#define ERROR 290
+#define TYPE 291
+#define ROLE 292
+#define PRIVS 293
+#define LIMITPRIVS 294
+#define CMND_TIMEOUT 295
+#define NOTBEFORE 296
+#define NOTAFTER 297
+#define MYSELF 298
+#define SHA224_TOK 299
+#define SHA256_TOK 300
+#define SHA384_TOK 301
+#define SHA512_TOK 302
+#ifndef YYSTYPE_DEFINED
+#define YYSTYPE_DEFINED
+typedef union {
+ struct cmndspec *cmndspec;
+ struct defaults *defaults;
+ struct member *member;
+ struct runascontainer *runas;
+ struct privilege *privilege;
+ struct command_digest *digest;
+ struct sudo_command command;
+ struct command_options options;
+ struct cmndtag tag;
+ char *string;
+ int tok;
+} YYSTYPE;
+#endif /* YYSTYPE_DEFINED */
+extern YYSTYPE sudoerslval;
diff --git a/plugins/sudoers/gram.y b/plugins/sudoers/gram.y
new file mode 100644
index 0000000..0665ce9
--- /dev/null
+++ b/plugins/sudoers/gram.y
@@ -0,0 +1,1327 @@
+%{
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2013, 2014-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
+# include <alloca.h>
+#endif /* YYBISON && HAVE_ALLOCA_H && !__GNUC__ */
+#include <errno.h>
+
+#include "sudoers.h"
+#include "sudo_digest.h"
+#include "toke.h"
+
+/* If we last saw a newline the entry is on the preceding line. */
+#define this_lineno (last_token == COMMENT ? sudolineno - 1 : sudolineno)
+
+/*
+ * Globals
+ */
+bool sudoers_warnings = true;
+bool parse_error = false;
+int errorlineno = -1;
+char *errorfile = NULL;
+
+struct sudoers_parse_tree parsed_policy = {
+ TAILQ_HEAD_INITIALIZER(parsed_policy.userspecs),
+ TAILQ_HEAD_INITIALIZER(parsed_policy.defaults),
+ NULL /* aliases */
+};
+
+/*
+ * Local protoypes
+ */
+static void init_options(struct command_options *opts);
+static bool add_defaults(int, struct member *, struct defaults *);
+static bool add_userspec(struct member *, struct privilege *);
+static struct defaults *new_default(char *, char *, short);
+static struct member *new_member(char *, int);
+static struct command_digest *new_digest(int, char *);
+%}
+
+%union {
+ struct cmndspec *cmndspec;
+ struct defaults *defaults;
+ struct member *member;
+ struct runascontainer *runas;
+ struct privilege *privilege;
+ struct command_digest *digest;
+ struct sudo_command command;
+ struct command_options options;
+ struct cmndtag tag;
+ char *string;
+ int tok;
+}
+
+%start file /* special start symbol */
+%token <command> COMMAND /* absolute pathname w/ optional args */
+%token <string> ALIAS /* an UPPERCASE alias name */
+%token <string> DEFVAR /* a Defaults variable name */
+%token <string> NTWKADDR /* ipv4 or ipv6 address */
+%token <string> NETGROUP /* a netgroup (+NAME) */
+%token <string> USERGROUP /* a usergroup (%NAME) */
+%token <string> WORD /* a word */
+%token <string> DIGEST /* a SHA-2 digest */
+%token <tok> DEFAULTS /* Defaults entry */
+%token <tok> DEFAULTS_HOST /* Host-specific defaults entry */
+%token <tok> DEFAULTS_USER /* User-specific defaults entry */
+%token <tok> DEFAULTS_RUNAS /* Runas-specific defaults entry */
+%token <tok> DEFAULTS_CMND /* Command-specific defaults entry */
+%token <tok> NOPASSWD /* no passwd req for command */
+%token <tok> PASSWD /* passwd req for command (default) */
+%token <tok> NOEXEC /* preload dummy execve() for cmnd */
+%token <tok> EXEC /* don't preload dummy execve() */
+%token <tok> SETENV /* user may set environment for cmnd */
+%token <tok> NOSETENV /* user may not set environment */
+%token <tok> LOG_INPUT /* log user's cmnd input */
+%token <tok> NOLOG_INPUT /* don't log user's cmnd input */
+%token <tok> LOG_OUTPUT /* log cmnd output */
+%token <tok> NOLOG_OUTPUT /* don't log cmnd output */
+%token <tok> MAIL /* mail log message */
+%token <tok> NOMAIL /* don't mail log message */
+%token <tok> FOLLOW /* follow symbolic links */
+%token <tok> NOFOLLOW /* don't follow symbolic links */
+%token <tok> ALL /* ALL keyword */
+%token <tok> COMMENT /* comment and/or carriage return */
+%token <tok> HOSTALIAS /* Host_Alias keyword */
+%token <tok> CMNDALIAS /* Cmnd_Alias keyword */
+%token <tok> USERALIAS /* User_Alias keyword */
+%token <tok> RUNASALIAS /* Runas_Alias keyword */
+%token <tok> ':' '=' ',' '!' '+' '-' /* union member tokens */
+%token <tok> '(' ')' /* runas tokens */
+%token <tok> ERROR
+%token <tok> TYPE /* SELinux type */
+%token <tok> ROLE /* SELinux role */
+%token <tok> PRIVS /* Solaris privileges */
+%token <tok> LIMITPRIVS /* Solaris limit privileges */
+%token <tok> CMND_TIMEOUT /* command timeout */
+%token <tok> NOTBEFORE /* time restriction */
+%token <tok> NOTAFTER /* time restriction */
+%token <tok> MYSELF /* run as myself, not another user */
+%token <tok> SHA224_TOK /* sha224 token */
+%token <tok> SHA256_TOK /* sha256 token */
+%token <tok> SHA384_TOK /* sha384 token */
+%token <tok> SHA512_TOK /* sha512 token */
+
+%type <cmndspec> cmndspec
+%type <cmndspec> cmndspeclist
+%type <defaults> defaults_entry
+%type <defaults> defaults_list
+%type <member> cmnd
+%type <member> opcmnd
+%type <member> digcmnd
+%type <member> cmndlist
+%type <member> host
+%type <member> hostlist
+%type <member> ophost
+%type <member> opuser
+%type <member> user
+%type <member> userlist
+%type <member> opgroup
+%type <member> group
+%type <member> grouplist
+%type <runas> runasspec
+%type <runas> runaslist
+%type <privilege> privilege
+%type <privilege> privileges
+%type <tag> cmndtag
+%type <options> options
+%type <string> rolespec
+%type <string> typespec
+%type <string> privsspec
+%type <string> limitprivsspec
+%type <string> timeoutspec
+%type <string> notbeforespec
+%type <string> notafterspec
+%type <digest> digest
+
+%%
+
+file : { ; }
+ | line
+ ;
+
+line : entry
+ | line entry
+ ;
+
+entry : COMMENT {
+ ;
+ }
+ | error COMMENT {
+ yyerrok;
+ }
+ | userlist privileges {
+ if (!add_userspec($1, $2)) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | USERALIAS useraliases {
+ ;
+ }
+ | HOSTALIAS hostaliases {
+ ;
+ }
+ | CMNDALIAS cmndaliases {
+ ;
+ }
+ | RUNASALIAS runasaliases {
+ ;
+ }
+ | DEFAULTS defaults_list {
+ if (!add_defaults(DEFAULTS, NULL, $2))
+ YYERROR;
+ }
+ | DEFAULTS_USER userlist defaults_list {
+ if (!add_defaults(DEFAULTS_USER, $2, $3))
+ YYERROR;
+ }
+ | DEFAULTS_RUNAS userlist defaults_list {
+ if (!add_defaults(DEFAULTS_RUNAS, $2, $3))
+ YYERROR;
+ }
+ | DEFAULTS_HOST hostlist defaults_list {
+ if (!add_defaults(DEFAULTS_HOST, $2, $3))
+ YYERROR;
+ }
+ | DEFAULTS_CMND cmndlist defaults_list {
+ if (!add_defaults(DEFAULTS_CMND, $2, $3))
+ YYERROR;
+ }
+ ;
+
+defaults_list : defaults_entry
+ | defaults_list ',' defaults_entry {
+ HLTQ_CONCAT($1, $3, entries);
+ $$ = $1;
+ }
+ ;
+
+defaults_entry : DEFVAR {
+ $$ = new_default($1, NULL, true);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | '!' DEFVAR {
+ $$ = new_default($2, NULL, false);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | DEFVAR '=' WORD {
+ $$ = new_default($1, $3, true);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | DEFVAR '+' WORD {
+ $$ = new_default($1, $3, '+');
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | DEFVAR '-' WORD {
+ $$ = new_default($1, $3, '-');
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ ;
+
+privileges : privilege
+ | privileges ':' privilege {
+ HLTQ_CONCAT($1, $3, entries);
+ $$ = $1;
+ }
+ ;
+
+privilege : hostlist '=' cmndspeclist {
+ struct privilege *p = calloc(1, sizeof(*p));
+ if (p == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ TAILQ_INIT(&p->defaults);
+ HLTQ_TO_TAILQ(&p->hostlist, $1, entries);
+ HLTQ_TO_TAILQ(&p->cmndlist, $3, entries);
+ HLTQ_INIT(p, entries);
+ $$ = p;
+ }
+ ;
+
+ophost : host {
+ $$ = $1;
+ $$->negated = false;
+ }
+ | '!' host {
+ $$ = $2;
+ $$->negated = true;
+ }
+ ;
+
+host : ALIAS {
+ $$ = new_member($1, ALIAS);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | ALL {
+ $$ = new_member(NULL, ALL);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | NETGROUP {
+ $$ = new_member($1, NETGROUP);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | NTWKADDR {
+ $$ = new_member($1, NTWKADDR);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | WORD {
+ $$ = new_member($1, WORD);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ ;
+
+cmndspeclist : cmndspec
+ | cmndspeclist ',' cmndspec {
+ struct cmndspec *prev;
+ prev = HLTQ_LAST($1, cmndspec, entries);
+ HLTQ_CONCAT($1, $3, entries);
+#ifdef HAVE_SELINUX
+ /* propagate role and type */
+ if ($3->role == NULL && $3->type == NULL) {
+ $3->role = prev->role;
+ $3->type = prev->type;
+ }
+#endif /* HAVE_SELINUX */
+#ifdef HAVE_PRIV_SET
+ /* propagate privs & limitprivs */
+ if ($3->privs == NULL && $3->limitprivs == NULL) {
+ $3->privs = prev->privs;
+ $3->limitprivs = prev->limitprivs;
+ }
+#endif /* HAVE_PRIV_SET */
+ /* propagate command time restrictions */
+ if ($3->notbefore == UNSPEC)
+ $3->notbefore = prev->notbefore;
+ if ($3->notafter == UNSPEC)
+ $3->notafter = prev->notafter;
+ /* propagate command timeout */
+ if ($3->timeout == UNSPEC)
+ $3->timeout = prev->timeout;
+ /* propagate tags and runas list */
+ if ($3->tags.nopasswd == UNSPEC)
+ $3->tags.nopasswd = prev->tags.nopasswd;
+ if ($3->tags.noexec == UNSPEC)
+ $3->tags.noexec = prev->tags.noexec;
+ if ($3->tags.setenv == UNSPEC &&
+ prev->tags.setenv != IMPLIED)
+ $3->tags.setenv = prev->tags.setenv;
+ if ($3->tags.log_input == UNSPEC)
+ $3->tags.log_input = prev->tags.log_input;
+ if ($3->tags.log_output == UNSPEC)
+ $3->tags.log_output = prev->tags.log_output;
+ if ($3->tags.send_mail == UNSPEC)
+ $3->tags.send_mail = prev->tags.send_mail;
+ if ($3->tags.follow == UNSPEC)
+ $3->tags.follow = prev->tags.follow;
+ if (($3->runasuserlist == NULL &&
+ $3->runasgrouplist == NULL) &&
+ (prev->runasuserlist != NULL ||
+ prev->runasgrouplist != NULL)) {
+ $3->runasuserlist = prev->runasuserlist;
+ $3->runasgrouplist = prev->runasgrouplist;
+ }
+ $$ = $1;
+ }
+ ;
+
+cmndspec : runasspec options cmndtag digcmnd {
+ struct cmndspec *cs = calloc(1, sizeof(*cs));
+ if (cs == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ if ($1 != NULL) {
+ if ($1->runasusers != NULL) {
+ cs->runasuserlist =
+ malloc(sizeof(*cs->runasuserlist));
+ if (cs->runasuserlist == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ HLTQ_TO_TAILQ(cs->runasuserlist,
+ $1->runasusers, entries);
+ }
+ if ($1->runasgroups != NULL) {
+ cs->runasgrouplist =
+ malloc(sizeof(*cs->runasgrouplist));
+ if (cs->runasgrouplist == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ HLTQ_TO_TAILQ(cs->runasgrouplist,
+ $1->runasgroups, entries);
+ }
+ free($1);
+ }
+#ifdef HAVE_SELINUX
+ cs->role = $2.role;
+ cs->type = $2.type;
+#endif
+#ifdef HAVE_PRIV_SET
+ cs->privs = $2.privs;
+ cs->limitprivs = $2.limitprivs;
+#endif
+ cs->notbefore = $2.notbefore;
+ cs->notafter = $2.notafter;
+ cs->timeout = $2.timeout;
+ cs->tags = $3;
+ cs->cmnd = $4;
+ HLTQ_INIT(cs, entries);
+ /* sudo "ALL" implies the SETENV tag */
+ if (cs->cmnd->type == ALL && !cs->cmnd->negated &&
+ cs->tags.setenv == UNSPEC)
+ cs->tags.setenv = IMPLIED;
+ $$ = cs;
+ }
+ ;
+
+digest : SHA224_TOK ':' DIGEST {
+ $$ = new_digest(SUDO_DIGEST_SHA224, $3);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | SHA256_TOK ':' DIGEST {
+ $$ = new_digest(SUDO_DIGEST_SHA256, $3);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | SHA384_TOK ':' DIGEST {
+ $$ = new_digest(SUDO_DIGEST_SHA384, $3);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | SHA512_TOK ':' DIGEST {
+ $$ = new_digest(SUDO_DIGEST_SHA512, $3);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ ;
+
+digcmnd : opcmnd {
+ $$ = $1;
+ }
+ | digest opcmnd {
+ if ($2->type != COMMAND) {
+ sudoerserror(N_("a digest requires a path name"));
+ YYERROR;
+ }
+ /* XXX - yuck */
+ ((struct sudo_command *) $2->name)->digest = $1;
+ $$ = $2;
+ }
+ ;
+
+opcmnd : cmnd {
+ $$ = $1;
+ $$->negated = false;
+ }
+ | '!' cmnd {
+ $$ = $2;
+ $$->negated = true;
+ }
+ ;
+
+timeoutspec : CMND_TIMEOUT '=' WORD {
+ $$ = $3;
+ }
+ ;
+
+notbeforespec : NOTBEFORE '=' WORD {
+ $$ = $3;
+ }
+
+notafterspec : NOTAFTER '=' WORD {
+ $$ = $3;
+ }
+ ;
+
+rolespec : ROLE '=' WORD {
+ $$ = $3;
+ }
+ ;
+
+typespec : TYPE '=' WORD {
+ $$ = $3;
+ }
+ ;
+
+privsspec : PRIVS '=' WORD {
+ $$ = $3;
+ }
+ ;
+limitprivsspec : LIMITPRIVS '=' WORD {
+ $$ = $3;
+ }
+ ;
+
+runasspec : /* empty */ {
+ $$ = NULL;
+ }
+ | '(' runaslist ')' {
+ $$ = $2;
+ }
+ ;
+
+runaslist : /* empty */ {
+ $$ = calloc(1, sizeof(struct runascontainer));
+ if ($$ != NULL) {
+ $$->runasusers = new_member(NULL, MYSELF);
+ /* $$->runasgroups = NULL; */
+ if ($$->runasusers == NULL) {
+ free($$);
+ $$ = NULL;
+ }
+ }
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | userlist {
+ $$ = calloc(1, sizeof(struct runascontainer));
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ $$->runasusers = $1;
+ /* $$->runasgroups = NULL; */
+ }
+ | userlist ':' grouplist {
+ $$ = calloc(1, sizeof(struct runascontainer));
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ $$->runasusers = $1;
+ $$->runasgroups = $3;
+ }
+ | ':' grouplist {
+ $$ = calloc(1, sizeof(struct runascontainer));
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ /* $$->runasusers = NULL; */
+ $$->runasgroups = $2;
+ }
+ | ':' {
+ $$ = calloc(1, sizeof(struct runascontainer));
+ if ($$ != NULL) {
+ $$->runasusers = new_member(NULL, MYSELF);
+ /* $$->runasgroups = NULL; */
+ if ($$->runasusers == NULL) {
+ free($$);
+ $$ = NULL;
+ }
+ }
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ ;
+
+options : /* empty */ {
+ init_options(&$$);
+ }
+ | options notbeforespec {
+ $$.notbefore = parse_gentime($2);
+ free($2);
+ if ($$.notbefore == -1) {
+ sudoerserror(N_("invalid notbefore value"));
+ YYERROR;
+ }
+ }
+ | options notafterspec {
+ $$.notafter = parse_gentime($2);
+ free($2);
+ if ($$.notafter == -1) {
+ sudoerserror(N_("invalid notafter value"));
+ YYERROR;
+ }
+ }
+ | options timeoutspec {
+ $$.timeout = parse_timeout($2);
+ free($2);
+ if ($$.timeout == -1) {
+ if (errno == ERANGE)
+ sudoerserror(N_("timeout value too large"));
+ else
+ sudoerserror(N_("invalid timeout value"));
+ YYERROR;
+ }
+ }
+ | options rolespec {
+#ifdef HAVE_SELINUX
+ free($$.role);
+ $$.role = $2;
+#endif
+ }
+ | options typespec {
+#ifdef HAVE_SELINUX
+ free($$.type);
+ $$.type = $2;
+#endif
+ }
+ | options privsspec {
+#ifdef HAVE_PRIV_SET
+ free($$.privs);
+ $$.privs = $2;
+#endif
+ }
+ | options limitprivsspec {
+#ifdef HAVE_PRIV_SET
+ free($$.limitprivs);
+ $$.limitprivs = $2;
+#endif
+ }
+ ;
+
+cmndtag : /* empty */ {
+ TAGS_INIT($$);
+ }
+ | cmndtag NOPASSWD {
+ $$.nopasswd = true;
+ }
+ | cmndtag PASSWD {
+ $$.nopasswd = false;
+ }
+ | cmndtag NOEXEC {
+ $$.noexec = true;
+ }
+ | cmndtag EXEC {
+ $$.noexec = false;
+ }
+ | cmndtag SETENV {
+ $$.setenv = true;
+ }
+ | cmndtag NOSETENV {
+ $$.setenv = false;
+ }
+ | cmndtag LOG_INPUT {
+ $$.log_input = true;
+ }
+ | cmndtag NOLOG_INPUT {
+ $$.log_input = false;
+ }
+ | cmndtag LOG_OUTPUT {
+ $$.log_output = true;
+ }
+ | cmndtag NOLOG_OUTPUT {
+ $$.log_output = false;
+ }
+ | cmndtag FOLLOW {
+ $$.follow = true;
+ }
+ | cmndtag NOFOLLOW {
+ $$.follow = false;
+ }
+ | cmndtag MAIL {
+ $$.send_mail = true;
+ }
+ | cmndtag NOMAIL {
+ $$.send_mail = false;
+ }
+ ;
+
+cmnd : ALL {
+ $$ = new_member(NULL, ALL);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | ALIAS {
+ $$ = new_member($1, ALIAS);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | COMMAND {
+ struct sudo_command *c = calloc(1, sizeof(*c));
+ if (c == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ c->cmnd = $1.cmnd;
+ c->args = $1.args;
+ $$ = new_member((char *)c, COMMAND);
+ if ($$ == NULL) {
+ free(c);
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ ;
+
+hostaliases : hostalias
+ | hostaliases ':' hostalias
+ ;
+
+hostalias : ALIAS '=' hostlist {
+ const char *s;
+ s = alias_add(&parsed_policy, $1, HOSTALIAS,
+ sudoers, this_lineno, $3);
+ if (s != NULL) {
+ sudoerserror(s);
+ YYERROR;
+ }
+ }
+ ;
+
+hostlist : ophost
+ | hostlist ',' ophost {
+ HLTQ_CONCAT($1, $3, entries);
+ $$ = $1;
+ }
+ ;
+
+cmndaliases : cmndalias
+ | cmndaliases ':' cmndalias
+ ;
+
+cmndalias : ALIAS '=' cmndlist {
+ const char *s;
+ s = alias_add(&parsed_policy, $1, CMNDALIAS,
+ sudoers, this_lineno, $3);
+ if (s != NULL) {
+ sudoerserror(s);
+ YYERROR;
+ }
+ }
+ ;
+
+cmndlist : digcmnd
+ | cmndlist ',' digcmnd {
+ HLTQ_CONCAT($1, $3, entries);
+ $$ = $1;
+ }
+ ;
+
+runasaliases : runasalias
+ | runasaliases ':' runasalias
+ ;
+
+runasalias : ALIAS '=' userlist {
+ const char *s;
+ s = alias_add(&parsed_policy, $1, RUNASALIAS,
+ sudoers, this_lineno, $3);
+ if (s != NULL) {
+ sudoerserror(s);
+ YYERROR;
+ }
+ }
+ ;
+
+useraliases : useralias
+ | useraliases ':' useralias
+ ;
+
+useralias : ALIAS '=' userlist {
+ const char *s;
+ s = alias_add(&parsed_policy, $1, USERALIAS,
+ sudoers, this_lineno, $3);
+ if (s != NULL) {
+ sudoerserror(s);
+ YYERROR;
+ }
+ }
+ ;
+
+userlist : opuser
+ | userlist ',' opuser {
+ HLTQ_CONCAT($1, $3, entries);
+ $$ = $1;
+ }
+ ;
+
+opuser : user {
+ $$ = $1;
+ $$->negated = false;
+ }
+ | '!' user {
+ $$ = $2;
+ $$->negated = true;
+ }
+ ;
+
+user : ALIAS {
+ $$ = new_member($1, ALIAS);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | ALL {
+ $$ = new_member(NULL, ALL);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | NETGROUP {
+ $$ = new_member($1, NETGROUP);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | USERGROUP {
+ $$ = new_member($1, USERGROUP);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | WORD {
+ $$ = new_member($1, WORD);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ ;
+
+grouplist : opgroup
+ | grouplist ',' opgroup {
+ HLTQ_CONCAT($1, $3, entries);
+ $$ = $1;
+ }
+ ;
+
+opgroup : group {
+ $$ = $1;
+ $$->negated = false;
+ }
+ | '!' group {
+ $$ = $2;
+ $$->negated = true;
+ }
+ ;
+
+group : ALIAS {
+ $$ = new_member($1, ALIAS);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | ALL {
+ $$ = new_member(NULL, ALL);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ | WORD {
+ $$ = new_member($1, WORD);
+ if ($$ == NULL) {
+ sudoerserror(N_("unable to allocate memory"));
+ YYERROR;
+ }
+ }
+ ;
+
+%%
+void
+sudoerserror(const char *s)
+{
+ debug_decl(sudoerserror, SUDOERS_DEBUG_PARSER)
+
+ /* Save the line the first error occurred on. */
+ if (errorlineno == -1) {
+ errorlineno = this_lineno;
+ rcstr_delref(errorfile);
+ errorfile = rcstr_addref(sudoers);
+ }
+ if (sudoers_warnings && s != NULL) {
+ LEXTRACE("<*> ");
+#ifndef TRACELEXER
+ if (trace_print == NULL || trace_print == sudoers_trace_print) {
+ const char fmt[] = ">>> %s: %s near line %d <<<\n";
+ int oldlocale;
+
+ /* Warnings are displayed in the user's locale. */
+ sudoers_setlocale(SUDOERS_LOCALE_USER, &oldlocale);
+ sudo_printf(SUDO_CONV_ERROR_MSG, _(fmt), sudoers, _(s), this_lineno);
+ sudoers_setlocale(oldlocale, NULL);
+ }
+#endif
+ }
+ parse_error = true;
+ debug_return;
+}
+
+static struct defaults *
+new_default(char *var, char *val, short op)
+{
+ struct defaults *d;
+ debug_decl(new_default, SUDOERS_DEBUG_PARSER)
+
+ if ((d = calloc(1, sizeof(struct defaults))) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+
+ d->var = var;
+ d->val = val;
+ /* d->type = 0; */
+ d->op = op;
+ /* d->binding = NULL */
+ d->lineno = this_lineno;
+ d->file = rcstr_addref(sudoers);
+ HLTQ_INIT(d, entries);
+
+ debug_return_ptr(d);
+}
+
+static struct member *
+new_member(char *name, int type)
+{
+ struct member *m;
+ debug_decl(new_member, SUDOERS_DEBUG_PARSER)
+
+ if ((m = calloc(1, sizeof(struct member))) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+
+ m->name = name;
+ m->type = type;
+ HLTQ_INIT(m, entries);
+
+ debug_return_ptr(m);
+}
+
+static struct command_digest *
+new_digest(int digest_type, char *digest_str)
+{
+ struct command_digest *digest;
+ debug_decl(new_digest, SUDOERS_DEBUG_PARSER)
+
+ if ((digest = malloc(sizeof(*digest))) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+
+ digest->digest_type = digest_type;
+ digest->digest_str = digest_str;
+ if (digest->digest_str == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ free(digest);
+ digest = NULL;
+ }
+
+ debug_return_ptr(digest);
+}
+
+/*
+ * Add a list of defaults structures to the defaults list.
+ * The binding, if non-NULL, specifies a list of hosts, users, or
+ * runas users the entries apply to (specified by the type).
+ */
+static bool
+add_defaults(int type, struct member *bmem, struct defaults *defs)
+{
+ struct defaults *d, *next;
+ struct member_list *binding;
+ bool ret = true;
+ debug_decl(add_defaults, SUDOERS_DEBUG_PARSER)
+
+ if (defs != NULL) {
+ /*
+ * We use a single binding for each entry in defs.
+ */
+ if ((binding = malloc(sizeof(*binding))) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ sudoerserror(N_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ if (bmem != NULL)
+ HLTQ_TO_TAILQ(binding, bmem, entries);
+ else
+ TAILQ_INIT(binding);
+
+ /*
+ * Set type and binding (who it applies to) for new entries.
+ * Then add to the global defaults list.
+ */
+ HLTQ_FOREACH_SAFE(d, defs, entries, next) {
+ d->type = type;
+ d->binding = binding;
+ TAILQ_INSERT_TAIL(&parsed_policy.defaults, d, entries);
+ }
+ }
+
+ debug_return_bool(ret);
+}
+
+/*
+ * Allocate a new struct userspec, populate it, and insert it at the
+ * end of the userspecs list.
+ */
+static bool
+add_userspec(struct member *members, struct privilege *privs)
+{
+ struct userspec *u;
+ debug_decl(add_userspec, SUDOERS_DEBUG_PARSER)
+
+ if ((u = calloc(1, sizeof(*u))) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_bool(false);
+ }
+ u->lineno = this_lineno;
+ u->file = rcstr_addref(sudoers);
+ HLTQ_TO_TAILQ(&u->users, members, entries);
+ HLTQ_TO_TAILQ(&u->privileges, privs, entries);
+ STAILQ_INIT(&u->comments);
+ TAILQ_INSERT_TAIL(&parsed_policy.userspecs, u, entries);
+
+ debug_return_bool(true);
+}
+
+/*
+ * Free a member struct and its contents.
+ */
+void
+free_member(struct member *m)
+{
+ debug_decl(free_member, SUDOERS_DEBUG_PARSER)
+
+ if (m->type == COMMAND) {
+ struct sudo_command *c = (struct sudo_command *)m->name;
+ free(c->cmnd);
+ free(c->args);
+ if (c->digest != NULL) {
+ free(c->digest->digest_str);
+ free(c->digest);
+ }
+ }
+ free(m->name);
+ free(m);
+
+ debug_return;
+}
+
+/*
+ * Free a tailq of members but not the struct member_list container itself.
+ */
+void
+free_members(struct member_list *members)
+{
+ struct member *m;
+ debug_decl(free_members, SUDOERS_DEBUG_PARSER)
+
+ while ((m = TAILQ_FIRST(members)) != NULL) {
+ TAILQ_REMOVE(members, m, entries);
+ free_member(m);
+ }
+
+ debug_return;
+}
+
+void
+free_defaults(struct defaults_list *defs)
+{
+ struct member_list *prev_binding = NULL;
+ struct defaults *def;
+ debug_decl(free_defaults, SUDOERS_DEBUG_PARSER)
+
+ while ((def = TAILQ_FIRST(defs)) != NULL) {
+ TAILQ_REMOVE(defs, def, entries);
+ free_default(def, &prev_binding);
+ }
+
+ debug_return;
+}
+
+void
+free_default(struct defaults *def, struct member_list **binding)
+{
+ debug_decl(free_default, SUDOERS_DEBUG_PARSER)
+
+ if (def->binding != *binding) {
+ *binding = def->binding;
+ if (def->binding != NULL) {
+ free_members(def->binding);
+ free(def->binding);
+ }
+ }
+ rcstr_delref(def->file);
+ free(def->var);
+ free(def->val);
+ free(def);
+
+ debug_return;
+}
+
+void
+free_privilege(struct privilege *priv)
+{
+ struct member_list *runasuserlist = NULL, *runasgrouplist = NULL;
+ struct member_list *prev_binding = NULL;
+ struct cmndspec *cs;
+ struct defaults *def;
+#ifdef HAVE_SELINUX
+ char *role = NULL, *type = NULL;
+#endif /* HAVE_SELINUX */
+#ifdef HAVE_PRIV_SET
+ char *privs = NULL, *limitprivs = NULL;
+#endif /* HAVE_PRIV_SET */
+ debug_decl(free_privilege, SUDOERS_DEBUG_PARSER)
+
+ free(priv->ldap_role);
+ free_members(&priv->hostlist);
+ while ((cs = TAILQ_FIRST(&priv->cmndlist)) != NULL) {
+ TAILQ_REMOVE(&priv->cmndlist, cs, entries);
+#ifdef HAVE_SELINUX
+ /* Only free the first instance of a role/type. */
+ if (cs->role != role) {
+ role = cs->role;
+ free(cs->role);
+ }
+ if (cs->type != type) {
+ type = cs->type;
+ free(cs->type);
+ }
+#endif /* HAVE_SELINUX */
+#ifdef HAVE_PRIV_SET
+ /* Only free the first instance of privs/limitprivs. */
+ if (cs->privs != privs) {
+ privs = cs->privs;
+ free(cs->privs);
+ }
+ if (cs->limitprivs != limitprivs) {
+ limitprivs = cs->limitprivs;
+ free(cs->limitprivs);
+ }
+#endif /* HAVE_PRIV_SET */
+ /* Only free the first instance of runas user/group lists. */
+ if (cs->runasuserlist && cs->runasuserlist != runasuserlist) {
+ runasuserlist = cs->runasuserlist;
+ free_members(runasuserlist);
+ free(runasuserlist);
+ }
+ if (cs->runasgrouplist && cs->runasgrouplist != runasgrouplist) {
+ runasgrouplist = cs->runasgrouplist;
+ free_members(runasgrouplist);
+ free(runasgrouplist);
+ }
+ free_member(cs->cmnd);
+ free(cs);
+ }
+ while ((def = TAILQ_FIRST(&priv->defaults)) != NULL) {
+ TAILQ_REMOVE(&priv->defaults, def, entries);
+ free_default(def, &prev_binding);
+ }
+ free(priv);
+
+ debug_return;
+}
+
+void
+free_userspecs(struct userspec_list *usl)
+{
+ struct userspec *us;
+ debug_decl(free_userspecs, SUDOERS_DEBUG_PARSER)
+
+ while ((us = TAILQ_FIRST(usl)) != NULL) {
+ TAILQ_REMOVE(usl, us, entries);
+ free_userspec(us);
+ }
+
+ debug_return;
+}
+
+void
+free_userspec(struct userspec *us)
+{
+ struct privilege *priv;
+ struct sudoers_comment *comment;
+ debug_decl(free_userspec, SUDOERS_DEBUG_PARSER)
+
+ free_members(&us->users);
+ while ((priv = TAILQ_FIRST(&us->privileges)) != NULL) {
+ TAILQ_REMOVE(&us->privileges, priv, entries);
+ free_privilege(priv);
+ }
+ while ((comment = STAILQ_FIRST(&us->comments)) != NULL) {
+ STAILQ_REMOVE_HEAD(&us->comments, entries);
+ free(comment->str);
+ free(comment);
+ }
+ rcstr_delref(us->file);
+ free(us);
+
+ debug_return;
+}
+
+/*
+ * Initialized a sudoers parse tree.
+ */
+void
+init_parse_tree(struct sudoers_parse_tree *parse_tree)
+{
+ TAILQ_INIT(&parse_tree->userspecs);
+ TAILQ_INIT(&parse_tree->defaults);
+ parse_tree->aliases = NULL;
+}
+
+/*
+ * Move the contents of parsed_policy to new_tree.
+ */
+void
+reparent_parse_tree(struct sudoers_parse_tree *new_tree)
+{
+ TAILQ_CONCAT(&new_tree->userspecs, &parsed_policy.userspecs, entries);
+ TAILQ_CONCAT(&new_tree->defaults, &parsed_policy.defaults, entries);
+ new_tree->aliases = parsed_policy.aliases;
+ parsed_policy.aliases = NULL;
+}
+
+/*
+ * Free the contents of a sudoers parse tree and initialize it.
+ */
+void
+free_parse_tree(struct sudoers_parse_tree *parse_tree)
+{
+ free_userspecs(&parse_tree->userspecs);
+ free_defaults(&parse_tree->defaults);
+ free_aliases(parse_tree->aliases);
+ parse_tree->aliases = NULL;
+}
+
+/*
+ * Free up space used by data structures from a previous parser run and sets
+ * the current sudoers file to path.
+ */
+bool
+init_parser(const char *path, bool quiet)
+{
+ bool ret = true;
+ debug_decl(init_parser, SUDOERS_DEBUG_PARSER)
+
+ free_parse_tree(&parsed_policy);
+ init_lexer();
+
+ rcstr_delref(sudoers);
+ if (path != NULL) {
+ if ((sudoers = rcstr_dup(path)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ ret = false;
+ }
+ } else {
+ sudoers = NULL;
+ }
+
+ parse_error = false;
+ errorlineno = -1;
+ rcstr_delref(errorfile);
+ errorfile = NULL;
+ sudoers_warnings = !quiet;
+
+ debug_return_bool(ret);
+}
+
+/*
+ * Initialize all options in a cmndspec.
+ */
+static void
+init_options(struct command_options *opts)
+{
+ opts->notbefore = UNSPEC;
+ opts->notafter = UNSPEC;
+ opts->timeout = UNSPEC;
+#ifdef HAVE_SELINUX
+ opts->role = NULL;
+ opts->type = NULL;
+#endif
+#ifdef HAVE_PRIV_SET
+ opts->privs = NULL;
+ opts->limitprivs = NULL;
+#endif
+}
diff --git a/plugins/sudoers/group_plugin.c b/plugins/sudoers/group_plugin.c
new file mode 100644
index 0000000..21d6510
--- /dev/null
+++ b/plugins/sudoers/group_plugin.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2010-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <time.h>
+#include <ctype.h>
+#include <errno.h>
+#include <pwd.h>
+
+#include "sudoers.h"
+#include "sudo_dso.h"
+
+#if defined(HAVE_DLOPEN) || defined(HAVE_SHL_LOAD)
+
+static void *group_handle;
+static struct sudoers_group_plugin *group_plugin;
+const char *path_plugin_dir = _PATH_SUDO_PLUGIN_DIR;
+
+/*
+ * Load the specified plugin and run its init function.
+ * Returns -1 if unable to open the plugin, else it returns
+ * the value from the plugin's init function.
+ */
+int
+group_plugin_load(char *plugin_info)
+{
+ struct stat sb;
+ char *args, path[PATH_MAX];
+ char **argv = NULL;
+ int len, rc = -1;
+ debug_decl(group_plugin_load, SUDOERS_DEBUG_UTIL)
+
+ /*
+ * Fill in .so path and split out args (if any).
+ */
+ if ((args = strpbrk(plugin_info, " \t")) != NULL) {
+ len = snprintf(path, sizeof(path), "%s%.*s",
+ (*plugin_info != '/') ? path_plugin_dir : "",
+ (int)(args - plugin_info), plugin_info);
+ args++;
+ } else {
+ len = snprintf(path, sizeof(path), "%s%s",
+ (*plugin_info != '/') ? path_plugin_dir : "", plugin_info);
+ }
+ if (len <= 0 || (size_t)len >= sizeof(path)) {
+ errno = ENAMETOOLONG;
+ sudo_warn("%s%s",
+ (*plugin_info != '/') ? path_plugin_dir : "", plugin_info);
+ goto done;
+ }
+
+ /* Sanity check plugin path. */
+ if (stat(path, &sb) != 0) {
+ sudo_warn("%s", path);
+ goto done;
+ }
+ if (sb.st_uid != ROOT_UID) {
+ sudo_warnx(U_("%s must be owned by uid %d"), path, ROOT_UID);
+ goto done;
+ }
+ if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
+ sudo_warnx(U_("%s must only be writable by owner"), path);
+ goto done;
+ }
+
+ /* Open plugin and map in symbol. */
+ group_handle = sudo_dso_load(path, SUDO_DSO_LAZY|SUDO_DSO_GLOBAL);
+ if (!group_handle) {
+ const char *errstr = sudo_dso_strerror();
+ sudo_warnx(U_("unable to load %s: %s"), path,
+ errstr ? errstr : "unknown error");
+ goto done;
+ }
+ group_plugin = sudo_dso_findsym(group_handle, "group_plugin");
+ if (group_plugin == NULL) {
+ sudo_warnx(U_("unable to find symbol \"group_plugin\" in %s"), path);
+ goto done;
+ }
+
+ if (SUDO_API_VERSION_GET_MAJOR(group_plugin->version) != GROUP_API_VERSION_MAJOR) {
+ sudo_warnx(U_("%s: incompatible group plugin major version %d, expected %d"),
+ path, SUDO_API_VERSION_GET_MAJOR(group_plugin->version),
+ GROUP_API_VERSION_MAJOR);
+ goto done;
+ }
+
+ /*
+ * Split args into a vector if specified.
+ */
+ if (args != NULL) {
+ int ac = 0;
+ bool wasblank = true;
+ char *cp, *last;
+
+ for (cp = args; *cp != '\0'; cp++) {
+ if (isblank((unsigned char)*cp)) {
+ wasblank = true;
+ } else if (wasblank) {
+ wasblank = false;
+ ac++;
+ }
+ }
+ if (ac != 0) {
+ argv = reallocarray(NULL, ac, sizeof(char *));
+ if (argv == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ ac = 0;
+ for ((cp = strtok_r(args, " \t", &last)); cp != NULL; (cp = strtok_r(NULL, " \t", &last)))
+ argv[ac++] = cp;
+ }
+ }
+
+ rc = (group_plugin->init)(GROUP_API_VERSION, sudo_printf, argv);
+
+done:
+ free(argv);
+
+ if (rc != true) {
+ if (group_handle != NULL) {
+ sudo_dso_unload(group_handle);
+ group_handle = NULL;
+ group_plugin = NULL;
+ }
+ }
+
+ debug_return_int(rc);
+}
+
+void
+group_plugin_unload(void)
+{
+ debug_decl(group_plugin_unload, SUDOERS_DEBUG_UTIL)
+
+ if (group_plugin != NULL) {
+ (group_plugin->cleanup)();
+ group_plugin = NULL;
+ }
+ if (group_handle != NULL) {
+ sudo_dso_unload(group_handle);
+ group_handle = NULL;
+ }
+ debug_return;
+}
+
+int
+group_plugin_query(const char *user, const char *group,
+ const struct passwd *pwd)
+{
+ debug_decl(group_plugin_query, SUDOERS_DEBUG_UTIL)
+
+ if (group_plugin == NULL)
+ debug_return_int(false);
+ debug_return_int((group_plugin->query)(user, group, pwd));
+}
+
+#else /* !HAVE_DLOPEN && !HAVE_SHL_LOAD */
+
+/*
+ * No loadable shared object support.
+ */
+
+int
+group_plugin_load(char *plugin_info)
+{
+ debug_decl(group_plugin_load, SUDOERS_DEBUG_UTIL)
+ debug_return_int(false);
+}
+
+void
+group_plugin_unload(void)
+{
+ debug_decl(group_plugin_unload, SUDOERS_DEBUG_UTIL)
+ debug_return;
+}
+
+int
+group_plugin_query(const char *user, const char *group,
+ const struct passwd *pwd)
+{
+ debug_decl(group_plugin_query, SUDOERS_DEBUG_UTIL)
+ debug_return_int(false);
+}
+
+#endif /* HAVE_DLOPEN || HAVE_SHL_LOAD */
+
+/*
+ * Group plugin sudoers callback.
+ */
+bool
+cb_group_plugin(const union sudo_defs_val *sd_un)
+{
+ bool rc = true;
+ debug_decl(cb_group_plugin, SUDOERS_DEBUG_PLUGIN)
+
+ /* Unload any existing group plugin before loading a new one. */
+ group_plugin_unload();
+ if (sd_un->str != NULL)
+ rc = group_plugin_load(sd_un->str);
+ debug_return_bool(rc);
+}
diff --git a/plugins/sudoers/hexchar.c b/plugins/sudoers/hexchar.c
new file mode 100644
index 0000000..1813b66
--- /dev/null
+++ b/plugins/sudoers/hexchar.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2013-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#include "sudoers.h"
+
+/*
+ * Converts a two-byte hex string to decimal.
+ * Returns the decimal value or -1 for invalid input.
+ */
+int
+hexchar(const char *s)
+{
+ unsigned char result[2];
+ int i;
+ debug_decl(hexchar, SUDOERS_DEBUG_UTIL)
+
+ for (i = 0; i < 2; i++) {
+ switch (s[i]) {
+ case '0':
+ result[i] = 0;
+ break;
+ case '1':
+ result[i] = 1;
+ break;
+ case '2':
+ result[i] = 2;
+ break;
+ case '3':
+ result[i] = 3;
+ break;
+ case '4':
+ result[i] = 4;
+ break;
+ case '5':
+ result[i] = 5;
+ break;
+ case '6':
+ result[i] = 6;
+ break;
+ case '7':
+ result[i] = 7;
+ break;
+ case '8':
+ result[i] = 8;
+ break;
+ case '9':
+ result[i] = 9;
+ break;
+ case 'A':
+ case 'a':
+ result[i] = 10;
+ break;
+ case 'B':
+ case 'b':
+ result[i] = 11;
+ break;
+ case 'C':
+ case 'c':
+ result[i] = 12;
+ break;
+ case 'D':
+ case 'd':
+ result[i] = 13;
+ break;
+ case 'E':
+ case 'e':
+ result[i] = 14;
+ break;
+ case 'F':
+ case 'f':
+ result[i] = 15;
+ break;
+ default:
+ /* Invalid input. */
+ debug_return_int(-1);
+ }
+ }
+ debug_return_int((result[0] << 4) | result[1]);
+}
diff --git a/plugins/sudoers/ins_2001.h b/plugins/sudoers/ins_2001.h
new file mode 100644
index 0000000..c6ad6ff
--- /dev/null
+++ b/plugins/sudoers/ins_2001.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_INS_2001_H
+#define SUDOERS_INS_2001_H
+
+ /*
+ * HAL insults (paraphrased) from 2001.
+ */
+
+ "Just what do you think you're doing Dave?",
+ "It can only be attributed to human error.",
+ "That's something I cannot allow to happen.",
+ "My mind is going. I can feel it.",
+ "Sorry about this, I know it's a bit silly.",
+ "Take a stress pill and think things over.",
+ "This mission is too important for me to allow you to jeopardize it.",
+ "I feel much better now.",
+
+#endif /* SUDOERS_INS_2001_H */
diff --git a/plugins/sudoers/ins_classic.h b/plugins/sudoers/ins_classic.h
new file mode 100644
index 0000000..2448151
--- /dev/null
+++ b/plugins/sudoers/ins_classic.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_INS_CLASSIC_H
+#define SUDOERS_INS_CLASSIC_H
+
+ /*
+ * Insults from the original sudo(8).
+ */
+
+ "Wrong! You cheating scum!",
+#ifndef OFFENSIVE_INSULTS
+ "And you call yourself a Rocket Scientist!",
+#else
+ "No soap, honkie-lips.",
+#endif
+ "Where did you learn to type?",
+ "Are you on drugs?",
+ "My pet ferret can type better than you!",
+ "You type like i drive.",
+ "Do you think like you type?",
+ "Your mind just hasn't been the same since the electro-shock, has it?",
+
+#endif /* SUDOERS_INS_CLASSIC_H */
diff --git a/plugins/sudoers/ins_csops.h b/plugins/sudoers/ins_csops.h
new file mode 100644
index 0000000..45c5dd3
--- /dev/null
+++ b/plugins/sudoers/ins_csops.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1996, 1998, 1999, 2004
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_INS_CSOPS_H
+#define SUDOERS_INS_CSOPS_H
+
+ /*
+ * CSOps insults (may be site dependent).
+ */
+
+ "Maybe if you used more than just two fingers...",
+ "BOB says: You seem to have forgotten your passwd, enter another!",
+ "stty: unknown mode: doofus",
+ "I can't hear you -- I'm using the scrambler.",
+ "The more you drive -- the dumber you get.",
+#ifdef PC_INSULTS
+ "Listen, broccoli brains, I don't have time to listen to this trash.",
+#else
+ "Listen, burrito brains, I don't have time to listen to this trash.",
+#endif
+ "I've seen penguins that can type better than that.",
+ "Have you considered trying to match wits with a rutabaga?",
+ "You speak an infinite deal of nothing",
+
+#endif /* SUDOERS_INS_CSOPS_H */
diff --git a/plugins/sudoers/ins_goons.h b/plugins/sudoers/ins_goons.h
new file mode 100644
index 0000000..5ed5e31
--- /dev/null
+++ b/plugins/sudoers/ins_goons.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_INS_GOONS_H
+#define SUDOERS_INS_GOONS_H
+
+ /*
+ * Insults from the "Goon Show."
+ */
+
+ "You silly, twisted boy you.",
+ "He has fallen in the water!",
+ "We'll all be murdered in our beds!",
+ "You can't come in. Our tiger has got flu",
+ "I don't wish to know that.",
+ "What, what, what, what, what, what, what, what, what, what?",
+ "You can't get the wood, you know.",
+ "You'll starve!",
+ "... and it used to be so popular...",
+ "Pauses for audience applause, not a sausage",
+ "Hold it up to the light --- not a brain in sight!",
+ "Have a gorilla...",
+ "There must be cure for it!",
+ "There's a lot of it about, you know.",
+ "You do that again and see what happens...",
+ "Ying Tong Iddle I Po",
+ "Harm can come to a young lad like that!",
+ "And with that remarks folks, the case of the Crown vs yourself was proven.",
+ "Speak English you fool --- there are no subtitles in this scene.",
+ "You gotta go owwwww!",
+ "I have been called worse.",
+ "It's only your word against mine.",
+ "I think ... err ... I think ... I think I'll go home",
+
+#endif /* SUDOERS_INS_GOONS_H */
diff --git a/plugins/sudoers/ins_python.h b/plugins/sudoers/ins_python.h
new file mode 100644
index 0000000..28f53d2
--- /dev/null
+++ b/plugins/sudoers/ins_python.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_INS_PYTHON_H
+#define SUDOERS_INS_PYTHON_H
+
+ /*
+ * Insults from "Monty Python's Flying Circus" and family.
+ */
+
+ "That is no basis for supreme executive power!",
+ "You empty-headed animal food trough wiper!",
+ "I fart in your general direction!",
+ "Your mother was a hamster and your father smelt of elderberries!",
+ "You must cut down the mightiest tree in the forest... with... a herring!",
+ "I wave my private parts at your aunties!",
+ "He's not the Messiah, he's a very naughty boy!",
+ "I wish to make a complaint.",
+ "When you're walking home tonight, and some homicidal maniac comes after you with a bunch of loganberries, don't come crying to me!",
+ "This man, he doesn't know when he's beaten! He doesn't know when he's winning, either. He has no... sort of... sensory apparatus...",
+ "There's nothing wrong with you that an expensive operation can't prolong.",
+ "I'm very sorry, but I'm not allowed to argue unless you've paid.",
+
+#endif /* SUDOERS_INS_PYTHON_H */
diff --git a/plugins/sudoers/insults.h b/plugins/sudoers/insults.h
new file mode 100644
index 0000000..cc08023
--- /dev/null
+++ b/plugins/sudoers/insults.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1994-1996, 1998-1999, 2004
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_INSULTS_H
+#define SUDOERS_INSULTS_H
+
+#if defined(HAL_INSULTS) || defined(GOONS_INSULTS) || defined(CLASSIC_INSULTS) || defined(CSOPS_INSULTS) || defined(PYTHON_INSULTS)
+
+#include "sudo_rand.h"
+
+/*
+ * Use one or more set of insults as determined by configure
+ */
+
+char *insults[] = {
+
+# ifdef HAL_INSULTS
+# include "ins_2001.h"
+# endif
+
+# ifdef GOONS_INSULTS
+# include "ins_goons.h"
+# endif
+
+# ifdef CLASSIC_INSULTS
+# include "ins_classic.h"
+# endif
+
+# ifdef CSOPS_INSULTS
+# include "ins_csops.h"
+# endif
+
+# ifdef PYTHON_INSULTS
+# include "ins_python.h"
+# endif
+
+ NULL
+
+};
+
+/*
+ * How may I insult you? Let me count the ways...
+ */
+#define NOFINSULTS (nitems(insults) - 1)
+
+/*
+ * return a pseudo-random insult.
+ */
+#define INSULT (insults[arc4random_uniform(NOFINSULTS)])
+
+#endif /* HAL_INSULTS || GOONS_INSULTS || CLASSIC_INSULTS || CSOPS_INSULTS || PYTHON_INSULTS */
+
+#endif /* SUDOERS_INSULTS_H */
diff --git a/plugins/sudoers/interfaces.c b/plugins/sudoers/interfaces.c
new file mode 100644
index 0000000..bd65366
--- /dev/null
+++ b/plugins/sudoers/interfaces.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2010-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#ifdef NEED_RESOLV_H
+# include <arpa/nameser.h>
+# include <resolv.h>
+#endif /* NEED_RESOLV_H */
+#include <netdb.h>
+#include <errno.h>
+
+#include "sudoers.h"
+#include "interfaces.h"
+
+#ifndef INADDR_NONE
+# define INADDR_NONE ((unsigned int)-1)
+#endif
+
+static struct interface_list interfaces = SLIST_HEAD_INITIALIZER(interfaces);
+
+/*
+ * Parse a space-delimited list of IP address/netmask pairs and
+ * store in a list of interface structures. Returns true on
+ * success and false on parse error or memory allocation error.
+ */
+bool
+set_interfaces(const char *ai)
+{
+ char *addrinfo, *addr, *mask, *last;
+ struct interface *ifp;
+ bool ret = false;
+ debug_decl(set_interfaces, SUDOERS_DEBUG_NETIF)
+
+ if ((addrinfo = strdup(ai)) == NULL)
+ debug_return_bool(false);
+ for (addr = strtok_r(addrinfo, " \t", &last); addr != NULL; addr = strtok_r(NULL, " \t", &last)) {
+ /* Separate addr and mask. */
+ if ((mask = strchr(addr, '/')) == NULL)
+ continue;
+ *mask++ = '\0';
+
+ /* Parse addr and store in list. */
+ if ((ifp = calloc(1, sizeof(*ifp))) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ if (strchr(addr, ':')) {
+ /* IPv6 */
+#ifdef HAVE_STRUCT_IN6_ADDR
+ ifp->family = AF_INET6;
+ if (inet_pton(AF_INET6, addr, &ifp->addr.ip6) != 1) {
+ sudo_warnx(U_("unable to parse IP address \"%s\""), addr);
+ free(ifp);
+ goto done;
+ }
+ if (inet_pton(AF_INET6, mask, &ifp->netmask.ip6) != 1) {
+ sudo_warnx(U_("unable to parse netmask \"%s\""), mask);
+ free(ifp);
+ goto done;
+ }
+#else
+ free(ifp);
+ continue;
+#endif
+ } else {
+ /* IPv4 */
+ ifp->family = AF_INET;
+ if (inet_pton(AF_INET, addr, &ifp->addr.ip4) != 1) {
+ sudo_warnx(U_("unable to parse IP address \"%s\""), addr);
+ free(ifp);
+ goto done;
+ }
+ if (inet_pton(AF_INET, mask, &ifp->netmask.ip4) != 1) {
+ sudo_warnx(U_("unable to parse netmask \"%s\""), mask);
+ free(ifp);
+ goto done;
+ }
+ }
+ SLIST_INSERT_HEAD(&interfaces, ifp, entries);
+ }
+ ret = true;
+
+done:
+ free(addrinfo);
+ debug_return_bool(ret);
+}
+
+struct interface_list *
+get_interfaces(void)
+{
+ return &interfaces;
+}
+
+void
+dump_interfaces(const char *ai)
+{
+ const char *cp, *ep;
+ const char *ai_end = ai + strlen(ai);
+ debug_decl(set_interfaces, SUDOERS_DEBUG_NETIF)
+
+ sudo_printf(SUDO_CONV_INFO_MSG,
+ _("Local IP address and netmask pairs:\n"));
+ cp = sudo_strsplit(ai, ai_end, " \t", &ep);
+ while (cp != NULL) {
+ sudo_printf(SUDO_CONV_INFO_MSG, "\t%.*s\n", (int)(ep - cp), cp);
+ cp = sudo_strsplit(NULL, ai_end, " \t", &ep);
+ }
+
+ debug_return;
+}
diff --git a/plugins/sudoers/interfaces.h b/plugins/sudoers/interfaces.h
new file mode 100644
index 0000000..73e55b4
--- /dev/null
+++ b/plugins/sudoers/interfaces.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2007, 2010-2013
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#ifndef SUDOERS_INTERFACES_H
+#define SUDOERS_INTERFACES_H
+
+/*
+ * Union to hold either strucr in_addr or in6_add
+ */
+union sudo_in_addr_un {
+ struct in_addr ip4;
+#ifdef HAVE_STRUCT_IN6_ADDR
+ struct in6_addr ip6;
+#endif
+};
+
+/*
+ * IP address and netmask pairs for checking against local interfaces.
+ */
+struct interface {
+ SLIST_ENTRY(interface) entries;
+ unsigned int family; /* AF_INET or AF_INET6 */
+ union sudo_in_addr_un addr;
+ union sudo_in_addr_un netmask;
+};
+
+SLIST_HEAD(interface_list, interface);
+
+/*
+ * Prototypes for external functions.
+ */
+int get_net_ifs(char **addrinfo);
+void dump_interfaces(const char *);
+bool set_interfaces(const char *);
+struct interface_list *get_interfaces(void);
+
+#endif /* SUDOERS_INTERFACES_H */
diff --git a/plugins/sudoers/iolog.c b/plugins/sudoers/iolog.c
new file mode 100644
index 0000000..b746c61
--- /dev/null
+++ b/plugins/sudoers/iolog.c
@@ -0,0 +1,1292 @@
+/*
+ * Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "sudoers.h"
+#include "iolog.h"
+#include "iolog_files.h"
+
+/* XXX - separate sudoers.h and iolog.h? */
+#undef runas_pw
+#undef runas_gr
+
+struct iolog_details {
+ const char *cwd;
+ const char *tty;
+ const char *user;
+ const char *command;
+ const char *iolog_path;
+ struct passwd *runas_pw;
+ struct group *runas_gr;
+ int lines;
+ int cols;
+ bool ignore_iolog_errors;
+};
+
+static struct iolog_details iolog_details;
+static bool iolog_compress = false;
+static bool warned = false;
+static struct timespec last_time;
+static unsigned int sessid_max = SESSID_MAX;
+static mode_t iolog_filemode = S_IRUSR|S_IWUSR;
+static mode_t iolog_dirmode = S_IRWXU;
+static bool iolog_gid_set;
+
+/* shared with set_perms.c */
+uid_t iolog_uid = ROOT_UID;
+gid_t iolog_gid = ROOT_GID;
+
+/* sudoers_io is declared at the end of this file. */
+extern __dso_public struct io_plugin sudoers_io;
+
+/*
+ * Create directory and any parent directories as needed.
+ */
+static bool
+io_mkdirs(char *path)
+{
+ struct stat sb;
+ bool ok, uid_changed = false;
+ debug_decl(io_mkdirs, SUDOERS_DEBUG_UTIL)
+
+ ok = stat(path, &sb) == 0;
+ if (!ok && errno == EACCES) {
+ /* Try again as the I/O log owner (for NFS). */
+ if (set_perms(PERM_IOLOG)) {
+ ok = stat(path, &sb) == 0;
+ if (!restore_perms())
+ ok = false;
+ }
+ }
+ if (ok) {
+ if (S_ISDIR(sb.st_mode)) {
+ if (sb.st_uid != iolog_uid || sb.st_gid != iolog_gid) {
+ if (chown(path, iolog_uid, iolog_gid) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to chown %d:%d %s", __func__,
+ (int)iolog_uid, (int)iolog_gid, path);
+ }
+ }
+ if ((sb.st_mode & ALLPERMS) != iolog_dirmode) {
+ if (chmod(path, iolog_dirmode) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to chmod 0%o %s", __func__,
+ (int)iolog_dirmode, path);
+ }
+ }
+ } else {
+ sudo_warnx(U_("%s exists but is not a directory (0%o)"),
+ path, (unsigned int) sb.st_mode);
+ ok = false;
+ }
+ goto done;
+ }
+
+ ok = sudo_mkdir_parents(path, iolog_uid, iolog_gid, iolog_dirmode, true);
+ if (!ok && errno == EACCES) {
+ /* Try again as the I/O log owner (for NFS). */
+ uid_changed = set_perms(PERM_IOLOG);
+ ok = sudo_mkdir_parents(path, -1, -1, iolog_dirmode, false);
+ }
+ if (ok) {
+ /* Create final path component. */
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "mkdir %s, mode 0%o", path, (unsigned int) iolog_dirmode);
+ ok = mkdir(path, iolog_dirmode) == 0 || errno == EEXIST;
+ if (!ok) {
+ if (errno == EACCES && !uid_changed) {
+ /* Try again as the I/O log owner (for NFS). */
+ uid_changed = set_perms(PERM_IOLOG);
+ ok = mkdir(path, iolog_dirmode) == 0 || errno == EEXIST;
+ }
+ if (!ok)
+ sudo_warn(U_("unable to mkdir %s"), path);
+ } else {
+ if (chown(path, iolog_uid, iolog_gid) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to chown %d:%d %s", __func__,
+ (int)iolog_uid, (int)iolog_gid, path);
+ }
+ }
+ }
+ if (uid_changed) {
+ if (!restore_perms())
+ ok = false;
+ }
+done:
+ debug_return_bool(ok);
+}
+
+/*
+ * Create temporary directory and any parent directories as needed.
+ */
+static bool
+io_mkdtemp(char *path)
+{
+ bool ok, uid_changed = false;
+ debug_decl(io_mkdtemp, SUDOERS_DEBUG_UTIL)
+
+ ok = sudo_mkdir_parents(path, iolog_uid, iolog_gid, iolog_dirmode, true);
+ if (!ok && errno == EACCES) {
+ /* Try again as the I/O log owner (for NFS). */
+ uid_changed = set_perms(PERM_IOLOG);
+ ok = sudo_mkdir_parents(path, -1, -1, iolog_dirmode, false);
+ }
+ if (ok) {
+ /* Create final path component. */
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "mkdtemp %s", path);
+ /* We cannot retry mkdtemp() so always use PERM_IOLOG */
+ if (!uid_changed)
+ uid_changed = set_perms(PERM_IOLOG);
+ if (mkdtemp(path) == NULL) {
+ sudo_warn(U_("unable to mkdir %s"), path);
+ ok = false;
+ } else {
+ if (chmod(path, iolog_dirmode) != 0) {
+ sudo_warn(U_("unable to change mode of %s to 0%o"),
+ path, (unsigned int)iolog_dirmode);
+ }
+ }
+ }
+
+ if (uid_changed) {
+ if (!restore_perms())
+ ok = false;
+ }
+ debug_return_bool(ok);
+}
+
+/*
+ * Set max session ID (aka sequence number)
+ */
+static bool
+io_set_max_sessid(const char *maxval)
+{
+ const char *errstr;
+ unsigned int value;
+ debug_decl(io_set_max_sessid, SUDOERS_DEBUG_UTIL)
+
+ value = strtonum(maxval, 0, SESSID_MAX, &errstr);
+ if (errstr != NULL) {
+ if (errno != ERANGE) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "bad maxseq: %s: %s", maxval, errstr);
+ debug_return_bool(false);
+ }
+ /* Out of range, clamp to SESSID_MAX as documented. */
+ value = SESSID_MAX;
+ }
+ sessid_max = value;
+ debug_return_bool(true);
+}
+
+/*
+ * Sudoers callback for maxseq Defaults setting.
+ */
+bool
+cb_maxseq(const union sudo_defs_val *sd_un)
+{
+ debug_decl(cb_maxseq, SUDOERS_DEBUG_UTIL)
+
+ /* Clamp value to SESSID_MAX as documented. */
+ sessid_max = sd_un->uival < SESSID_MAX ? sd_un->uival : SESSID_MAX;
+ debug_return_bool(true);
+}
+
+/*
+ * Look up I/O log user ID from user name. Sets iolog_uid.
+ * Also sets iolog_gid if iolog_group not specified.
+ */
+static bool
+iolog_set_user(const char *name)
+{
+ struct passwd *pw;
+ debug_decl(iolog_set_user, SUDOERS_DEBUG_UTIL)
+
+ if (name != NULL) {
+ pw = sudo_getpwnam(name);
+ if (pw != NULL) {
+ iolog_uid = pw->pw_uid;
+ if (!iolog_gid_set)
+ iolog_gid = pw->pw_gid;
+ sudo_pw_delref(pw);
+ } else {
+ log_warningx(SLOG_SEND_MAIL,
+ N_("unknown user: %s"), name);
+ }
+ } else {
+ /* Reset to default. */
+ iolog_uid = ROOT_UID;
+ if (!iolog_gid_set)
+ iolog_gid = ROOT_GID;
+ }
+
+ debug_return_bool(true);
+}
+
+/*
+ * Sudoers callback for iolog_user Defaults setting.
+ */
+bool
+cb_iolog_user(const union sudo_defs_val *sd_un)
+{
+ return iolog_set_user(sd_un->str);
+}
+
+/*
+ * Look up I/O log group ID from group name.
+ * Sets iolog_gid.
+ */
+static bool
+iolog_set_group(const char *name)
+{
+ struct group *gr;
+ debug_decl(iolog_set_group, SUDOERS_DEBUG_UTIL)
+
+ if (name != NULL) {
+ gr = sudo_getgrnam(name);
+ if (gr != NULL) {
+ iolog_gid = gr->gr_gid;
+ iolog_gid_set = true;
+ sudo_gr_delref(gr);
+ } else {
+ log_warningx(SLOG_SEND_MAIL,
+ N_("unknown group: %s"), name);
+ }
+ } else {
+ /* Reset to default. */
+ iolog_gid = ROOT_GID;
+ iolog_gid_set = false;
+ }
+
+ debug_return_bool(true);
+}
+
+/*
+ * Look up I/O log group ID from group name.
+ */
+bool
+cb_iolog_group(const union sudo_defs_val *sd_un)
+{
+ return iolog_set_group(sd_un->str);
+}
+
+/*
+ * Set iolog_filemode and iolog_dirmode.
+ */
+static bool
+iolog_set_mode(mode_t mode)
+{
+ debug_decl(iolog_set_mode, SUDOERS_DEBUG_UTIL)
+
+ /* I/O log files must be readable and writable by owner. */
+ iolog_filemode = S_IRUSR|S_IWUSR;
+
+ /* Add in group and other read/write if specified. */
+ iolog_filemode |= mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+
+ /* For directory mode, add execute bits as needed. */
+ iolog_dirmode = iolog_filemode | S_IXUSR;
+ if (iolog_dirmode & (S_IRGRP|S_IWGRP))
+ iolog_dirmode |= S_IXGRP;
+ if (iolog_dirmode & (S_IROTH|S_IWOTH))
+ iolog_dirmode |= S_IXOTH;
+
+ debug_return_bool(true);
+}
+
+/*
+ * Sudoers callback for iolog_mode Defaults setting.
+ */
+bool
+cb_iolog_mode(const union sudo_defs_val *sd_un)
+{
+ return iolog_set_mode(sd_un->mode);
+}
+
+/*
+ * Wrapper for open(2) that retries with PERM_IOLOG if open(2)
+ * returns EACCES.
+ */
+static int
+io_open(const char *path, int flags, mode_t perm)
+{
+ int fd;
+ debug_decl(io_open, SUDOERS_DEBUG_UTIL)
+
+ fd = open(path, flags, perm);
+ if (fd == -1 && errno == EACCES) {
+ /* Try again as the I/O log owner (for NFS). */
+ if (set_perms(PERM_IOLOG)) {
+ fd = open(path, flags, perm);
+ if (!restore_perms()) {
+ /* restore_perms() warns on error. */
+ if (fd != -1) {
+ close(fd);
+ fd = -1;
+ }
+ }
+ }
+ }
+ debug_return_int(fd);
+}
+
+/*
+ * Read the on-disk sequence number, set sessid to the next
+ * number, and update the on-disk copy.
+ * Uses file locking to avoid sequence number collisions.
+ */
+bool
+io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
+{
+ struct stat sb;
+ char buf[32], *ep;
+ int i, len, fd = -1;
+ unsigned long id = 0;
+ mode_t omask;
+ ssize_t nread;
+ bool ret = false;
+ char pathbuf[PATH_MAX];
+ static const char b36char[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ debug_decl(io_nextid, SUDOERS_DEBUG_UTIL)
+
+ /* umask must not be more restrictive than the file modes. */
+ omask = umask(ACCESSPERMS & ~(iolog_filemode|iolog_dirmode));
+
+ /*
+ * Create I/O log directory if it doesn't already exist.
+ */
+ if (!io_mkdirs(iolog_dir))
+ goto done;
+
+ /*
+ * Open sequence file
+ */
+ len = snprintf(pathbuf, sizeof(pathbuf), "%s/seq", iolog_dir);
+ if (len <= 0 || (size_t)len >= sizeof(pathbuf)) {
+ errno = ENAMETOOLONG;
+ log_warning(SLOG_SEND_MAIL, "%s/seq", pathbuf);
+ goto done;
+ }
+ fd = io_open(pathbuf, O_RDWR|O_CREAT, iolog_filemode);
+ if (fd == -1) {
+ log_warning(SLOG_SEND_MAIL, N_("unable to open %s"), pathbuf);
+ goto done;
+ }
+ sudo_lock_file(fd, SUDO_LOCK);
+ if (fchown(fd, iolog_uid, iolog_gid) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to fchown %d:%d %s", __func__,
+ (int)iolog_uid, (int)iolog_gid, pathbuf);
+ }
+
+ /*
+ * If there is no seq file in iolog_dir and a fallback dir was
+ * specified, look for seq in the fallback dir. This is to work
+ * around a bug in sudo 1.8.5 and older where iolog_dir was not
+ * expanded before the sequence number was updated.
+ */
+ if (iolog_dir_fallback != NULL && fstat(fd, &sb) == 0 && sb.st_size == 0) {
+ char fallback[PATH_MAX];
+
+ len = snprintf(fallback, sizeof(fallback), "%s/seq",
+ iolog_dir_fallback);
+ if (len > 0 && (size_t)len < sizeof(fallback)) {
+ int fd2 = io_open(fallback, O_RDWR|O_CREAT, iolog_filemode);
+ if (fd2 != -1) {
+ if (fchown(fd2, iolog_uid, iolog_gid) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to fchown %d:%d %s", __func__,
+ (int)iolog_uid, (int)iolog_gid, fallback);
+ }
+ nread = read(fd2, buf, sizeof(buf) - 1);
+ if (nread > 0) {
+ if (buf[nread - 1] == '\n')
+ nread--;
+ buf[nread] = '\0';
+ id = strtoul(buf, &ep, 36);
+ if (ep == buf || *ep != '\0' || id >= sessid_max) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: bad sequence number: %s", fallback, buf);
+ id = 0;
+ }
+ }
+ close(fd2);
+ }
+ }
+ }
+
+ /* Read current seq number (base 36). */
+ if (id == 0) {
+ nread = read(fd, buf, sizeof(buf) - 1);
+ if (nread != 0) {
+ if (nread == -1) {
+ log_warning(SLOG_SEND_MAIL, N_("unable to read %s"), pathbuf);
+ goto done;
+ }
+ if (buf[nread - 1] == '\n')
+ nread--;
+ buf[nread] = '\0';
+ id = strtoul(buf, &ep, 36);
+ if (ep == buf || *ep != '\0' || id >= sessid_max) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: bad sequence number: %s", pathbuf, buf);
+ id = 0;
+ }
+ }
+ }
+ id++;
+
+ /*
+ * Convert id to a string and stash in sessid.
+ * Note that that least significant digits go at the end of the string.
+ */
+ for (i = 5; i >= 0; i--) {
+ buf[i] = b36char[id % 36];
+ id /= 36;
+ }
+ buf[6] = '\n';
+
+ /* Stash id for logging purposes. */
+ memcpy(sessid, buf, 6);
+ sessid[6] = '\0';
+
+ /* Rewind and overwrite old seq file, including the NUL byte. */
+#ifdef HAVE_PWRITE
+ if (pwrite(fd, buf, 7, 0) != 7) {
+#else
+ if (lseek(fd, 0, SEEK_SET) == -1 || write(fd, buf, 7) != 7) {
+#endif
+ log_warning(SLOG_SEND_MAIL, N_("unable to write to %s"), pathbuf);
+ warned = true;
+ goto done;
+ }
+ ret = true;
+
+done:
+ umask(omask);
+ if (fd != -1)
+ close(fd);
+ debug_return_bool(ret);
+}
+
+/*
+ * Copy iolog_path to pathbuf and create the directory and any intermediate
+ * directories. If iolog_path ends in 'XXXXXX', use mkdtemp().
+ * Returns SIZE_MAX on error.
+ */
+static size_t
+mkdir_iopath(const char *iolog_path, char *pathbuf, size_t pathsize)
+{
+ size_t len;
+ bool ok;
+ debug_decl(mkdir_iopath, SUDOERS_DEBUG_UTIL)
+
+ len = strlcpy(pathbuf, iolog_path, pathsize);
+ if (len >= pathsize) {
+ errno = ENAMETOOLONG;
+ log_warning(SLOG_SEND_MAIL, "%s", iolog_path);
+ debug_return_size_t((size_t)-1);
+ }
+
+ /*
+ * Create path and intermediate subdirs as needed.
+ * If path ends in at least 6 Xs (ala POSIX mktemp), use mkdtemp().
+ * Sets iolog_gid (if it is not already set) as a side effect.
+ */
+ if (len >= 6 && strcmp(&pathbuf[len - 6], "XXXXXX") == 0)
+ ok = io_mkdtemp(pathbuf);
+ else
+ ok = io_mkdirs(pathbuf);
+
+ debug_return_size_t(ok ? len : (size_t)-1);
+}
+
+/*
+ * Append suffix to pathbuf after len chars and open the resulting file.
+ * Note that the size of pathbuf is assumed to be PATH_MAX.
+ * Uses zlib if docompress is true.
+ * Stores the open file handle which has the close-on-exec flag set.
+ */
+static bool
+open_io_fd(char *pathbuf, size_t len, struct io_log_file *iol, bool docompress)
+{
+ debug_decl(open_io_fd, SUDOERS_DEBUG_UTIL)
+
+ pathbuf[len] = '\0';
+ strlcat(pathbuf, iol->suffix, PATH_MAX);
+ if (iol->enabled) {
+ int fd = io_open(pathbuf, O_CREAT|O_TRUNC|O_WRONLY, iolog_filemode);
+ if (fd != -1) {
+ if (fchown(fd, iolog_uid, iolog_gid) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to fchown %d:%d %s", __func__,
+ (int)iolog_uid, (int)iolog_gid, pathbuf);
+ }
+ (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
+#ifdef HAVE_ZLIB_H
+ if (docompress)
+ iol->fd.g = gzdopen(fd, "w");
+ else
+#endif
+ iol->fd.f = fdopen(fd, "w");
+ if (iol->fd.v == NULL) {
+ close(fd);
+ fd = -1;
+ }
+ }
+ if (fd == -1) {
+ log_warning(SLOG_SEND_MAIL, N_("unable to create %s"), pathbuf);
+ debug_return_bool(false);
+ }
+ } else {
+ /* Remove old log file if we recycled sequence numbers. */
+ unlink(pathbuf);
+ }
+ debug_return_bool(true);
+}
+
+/*
+ * Pull out I/O log related data from user_info and command_info arrays.
+ * Returns true if I/O logging is enabled, else false.
+ */
+static bool
+iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
+ char * const command_info[])
+{
+ const char *runas_uid_str = "0", *runas_euid_str = NULL;
+ const char *runas_gid_str = "0", *runas_egid_str = NULL;
+ const char *errstr;
+ char idbuf[MAX_UID_T_LEN + 2];
+ char * const *cur;
+ id_t id;
+ uid_t runas_uid = 0;
+ gid_t runas_gid = 0;
+ debug_decl(iolog_deserialize_info, SUDOERS_DEBUG_UTIL)
+
+ details->lines = 24;
+ details->cols = 80;
+
+ for (cur = user_info; *cur != NULL; cur++) {
+ switch (**cur) {
+ case 'c':
+ if (strncmp(*cur, "cols=", sizeof("cols=") - 1) == 0) {
+ int n = strtonum(*cur + sizeof("cols=") - 1, 1, INT_MAX, NULL);
+ if (n > 0)
+ details->cols = n;
+ continue;
+ }
+ if (strncmp(*cur, "cwd=", sizeof("cwd=") - 1) == 0) {
+ details->cwd = *cur + sizeof("cwd=") - 1;
+ continue;
+ }
+ break;
+ case 'l':
+ if (strncmp(*cur, "lines=", sizeof("lines=") - 1) == 0) {
+ int n = strtonum(*cur + sizeof("lines=") - 1, 1, INT_MAX, NULL);
+ if (n > 0)
+ details->lines = n;
+ continue;
+ }
+ break;
+ case 't':
+ if (strncmp(*cur, "tty=", sizeof("tty=") - 1) == 0) {
+ details->tty = *cur + sizeof("tty=") - 1;
+ continue;
+ }
+ break;
+ case 'u':
+ if (strncmp(*cur, "user=", sizeof("user=") - 1) == 0) {
+ details->user = *cur + sizeof("user=") - 1;
+ continue;
+ }
+ break;
+ }
+ }
+
+ for (cur = command_info; *cur != NULL; cur++) {
+ switch (**cur) {
+ case 'c':
+ if (strncmp(*cur, "command=", sizeof("command=") - 1) == 0) {
+ details->command = *cur + sizeof("command=") - 1;
+ continue;
+ }
+ break;
+ case 'i':
+ if (strncmp(*cur, "ignore_iolog_errors=", sizeof("ignore_iolog_errors=") - 1) == 0) {
+ if (sudo_strtobool(*cur + sizeof("ignore_iolog_errors=") - 1) == true)
+ details->ignore_iolog_errors = true;
+ continue;
+ }
+ if (strncmp(*cur, "iolog_path=", sizeof("iolog_path=") - 1) == 0) {
+ details->iolog_path = *cur + sizeof("iolog_path=") - 1;
+ continue;
+ }
+ if (strncmp(*cur, "iolog_stdin=", sizeof("iolog_stdin=") - 1) == 0) {
+ if (sudo_strtobool(*cur + sizeof("iolog_stdin=") - 1) == true)
+ io_log_files[IOFD_STDIN].enabled = true;
+ continue;
+ }
+ if (strncmp(*cur, "iolog_stdout=", sizeof("iolog_stdout=") - 1) == 0) {
+ if (sudo_strtobool(*cur + sizeof("iolog_stdout=") - 1) == true)
+ io_log_files[IOFD_STDOUT].enabled = true;
+ continue;
+ }
+ if (strncmp(*cur, "iolog_stderr=", sizeof("iolog_stderr=") - 1) == 0) {
+ if (sudo_strtobool(*cur + sizeof("iolog_stderr=") - 1) == true)
+ io_log_files[IOFD_STDERR].enabled = true;
+ continue;
+ }
+ if (strncmp(*cur, "iolog_ttyin=", sizeof("iolog_ttyin=") - 1) == 0) {
+ if (sudo_strtobool(*cur + sizeof("iolog_ttyin=") - 1) == true)
+ io_log_files[IOFD_TTYIN].enabled = true;
+ continue;
+ }
+ if (strncmp(*cur, "iolog_ttyout=", sizeof("iolog_ttyout=") - 1) == 0) {
+ if (sudo_strtobool(*cur + sizeof("iolog_ttyout=") - 1) == true)
+ io_log_files[IOFD_TTYOUT].enabled = true;
+ continue;
+ }
+ if (strncmp(*cur, "iolog_compress=", sizeof("iolog_compress=") - 1) == 0) {
+ if (sudo_strtobool(*cur + sizeof("iolog_compress=") - 1) == true)
+ iolog_compress = true; /* must be global */
+ continue;
+ }
+ if (strncmp(*cur, "iolog_mode=", sizeof("iolog_mode=") - 1) == 0) {
+ mode_t mode = sudo_strtomode(*cur + sizeof("iolog_mode=") - 1, &errstr);
+ if (errstr == NULL)
+ iolog_set_mode(mode);
+ continue;
+ }
+ if (strncmp(*cur, "iolog_group=", sizeof("iolog_group=") - 1) == 0) {
+ iolog_set_group(*cur + sizeof("iolog_group=") - 1);
+ continue;
+ }
+ if (strncmp(*cur, "iolog_user=", sizeof("iolog_user=") - 1) == 0) {
+ iolog_set_user(*cur + sizeof("iolog_user=") - 1);
+ continue;
+ }
+ break;
+ case 'm':
+ if (strncmp(*cur, "maxseq=", sizeof("maxseq=") - 1) == 0) {
+ io_set_max_sessid(*cur + sizeof("maxseq=") - 1);
+ continue;
+ }
+ break;
+ case 'r':
+ if (strncmp(*cur, "runas_gid=", sizeof("runas_gid=") - 1) == 0) {
+ runas_gid_str = *cur + sizeof("runas_gid=") - 1;
+ continue;
+ }
+ if (strncmp(*cur, "runas_egid=", sizeof("runas_egid=") - 1) == 0) {
+ runas_egid_str = *cur + sizeof("runas_egid=") - 1;
+ continue;
+ }
+ if (strncmp(*cur, "runas_uid=", sizeof("runas_uid=") - 1) == 0) {
+ runas_uid_str = *cur + sizeof("runas_uid=") - 1;
+ continue;
+ }
+ if (strncmp(*cur, "runas_euid=", sizeof("runas_euid=") - 1) == 0) {
+ runas_euid_str = *cur + sizeof("runas_euid=") - 1;
+ continue;
+ }
+ break;
+ }
+ }
+
+ /*
+ * Lookup runas user and group, preferring effective over real uid/gid.
+ */
+ if (runas_euid_str != NULL)
+ runas_uid_str = runas_euid_str;
+ if (runas_uid_str != NULL) {
+ id = sudo_strtoid(runas_uid_str, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ sudo_warnx("runas uid %s: %s", runas_uid_str, U_(errstr));
+ else
+ runas_uid = (uid_t)id;
+ }
+ if (runas_egid_str != NULL)
+ runas_gid_str = runas_egid_str;
+ if (runas_gid_str != NULL) {
+ id = sudo_strtoid(runas_gid_str, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ sudo_warnx("runas gid %s: %s", runas_gid_str, U_(errstr));
+ else
+ runas_gid = (gid_t)id;
+ }
+
+ details->runas_pw = sudo_getpwuid(runas_uid);
+ if (details->runas_pw == NULL) {
+ idbuf[0] = '#';
+ strlcpy(&idbuf[1], runas_uid_str, sizeof(idbuf) - 1);
+ details->runas_pw = sudo_fakepwnam(idbuf, runas_gid);
+ }
+
+ if (runas_gid != details->runas_pw->pw_gid) {
+ details->runas_gr = sudo_getgrgid(runas_gid);
+ if (details->runas_gr == NULL) {
+ idbuf[0] = '#';
+ strlcpy(&idbuf[1], runas_gid_str, sizeof(idbuf) - 1);
+ details->runas_gr = sudo_fakegrnam(idbuf);
+ }
+ }
+ debug_return_bool(
+ io_log_files[IOFD_STDIN].enabled || io_log_files[IOFD_STDOUT].enabled ||
+ io_log_files[IOFD_STDERR].enabled || io_log_files[IOFD_TTYIN].enabled ||
+ io_log_files[IOFD_TTYOUT].enabled);
+}
+
+/*
+ * Write the "/log" file that contains the user and command info.
+ * This file is not compressed.
+ */
+static bool
+write_info_log(char *pathbuf, size_t len, struct iolog_details *details,
+ char * const argv[])
+{
+ time_t now;
+ char * const *av;
+ FILE *fp;
+ int fd;
+ bool ret = true;
+ debug_decl(write_info_log, SUDOERS_DEBUG_UTIL)
+
+ pathbuf[len] = '\0';
+ strlcat(pathbuf, "/log", PATH_MAX);
+ fd = io_open(pathbuf, O_CREAT|O_TRUNC|O_WRONLY, iolog_filemode);
+ if (fd == -1 || (fp = fdopen(fd, "w")) == NULL) {
+ log_warning(SLOG_SEND_MAIL, N_("unable to create %s"), pathbuf);
+ debug_return_bool(false);
+ }
+ if (fchown(fd, iolog_uid, iolog_gid) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to fchown %d:%d %s", __func__,
+ (int)iolog_uid, (int)iolog_gid, pathbuf);
+ }
+
+ fprintf(fp, "%lld:%s:%s:%s:%s:%d:%d\n%s\n%s", (long long)time(&now),
+ details->user ? details->user : "unknown", details->runas_pw->pw_name,
+ details->runas_gr ? details->runas_gr->gr_name : "",
+ details->tty ? details->tty : "unknown", details->lines, details->cols,
+ details->cwd ? details->cwd : "unknown",
+ details->command ? details->command : "unknown");
+ for (av = argv + 1; *av != NULL; av++) {
+ fputc(' ', fp);
+ fputs(*av, fp);
+ }
+ fputc('\n', fp);
+ fflush(fp);
+ if (ferror(fp)) {
+ log_warning(SLOG_SEND_MAIL,
+ N_("unable to write to I/O log file: %s"), strerror(errno));
+ warned = true;
+ ret = false;
+ }
+ fclose(fp);
+ debug_return_bool(ret);
+}
+
+#ifdef HAVE_ZLIB_H
+static const char *
+gzstrerror(gzFile file)
+{
+ int errnum;
+
+ return gzerror(file, &errnum);
+}
+#endif /* HAVE_ZLIB_H */
+
+/*
+ * Write to an I/O log, compressing if iolog_compress is enabled.
+ * If def_iolog_flush is true, flush the buffer immediately.
+ */
+static const char *
+iolog_write(union io_fd ifd, const void *buf, unsigned int len)
+{
+ const char *errstr = NULL;
+ debug_decl(iolog_write, SUDOERS_DEBUG_PLUGIN)
+
+#ifdef HAVE_ZLIB_H
+ if (iolog_compress) {
+ if (gzwrite(ifd.g, (const voidp)buf, len) != (int)len) {
+ errstr = gzstrerror(ifd.g);
+ goto done;
+ }
+ if (def_iolog_flush) {
+ if (gzflush(ifd.g, Z_SYNC_FLUSH) != Z_OK) {
+ errstr = gzstrerror(ifd.g);
+ goto done;
+ }
+ }
+ } else
+#endif
+ {
+ if (fwrite(buf, 1, len, ifd.f) != len) {
+ errstr = strerror(errno);
+ goto done;
+ }
+ if (def_iolog_flush) {
+ if (fflush(ifd.f) != 0) {
+ errstr = strerror(errno);
+ goto done;
+ }
+ }
+ }
+
+done:
+ debug_return_const_str(errstr);
+}
+
+static int
+sudoers_io_open(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[], char * const args[])
+{
+ struct sudo_conf_debug_file_list debug_files = TAILQ_HEAD_INITIALIZER(debug_files);
+ char pathbuf[PATH_MAX], sessid[7];
+ char *tofree = NULL;
+ char * const *cur;
+ const char *cp, *plugin_path = NULL;
+ size_t len;
+ mode_t omask;
+ int i, ret = -1;
+ debug_decl(sudoers_io_open, SUDOERS_DEBUG_PLUGIN)
+
+ sudo_conv = conversation;
+ sudo_printf = plugin_printf;
+
+ /* If we have no command (because -V was specified) just return. */
+ if (argc == 0)
+ debug_return_int(true);
+
+ bindtextdomain("sudoers", LOCALEDIR);
+
+ /* Initialize the debug subsystem. */
+ for (cur = settings; (cp = *cur) != NULL; cur++) {
+ if (strncmp(cp, "debug_flags=", sizeof("debug_flags=") - 1) == 0) {
+ cp += sizeof("debug_flags=") - 1;
+ if (!sudoers_debug_parse_flags(&debug_files, cp))
+ debug_return_int(-1);
+ continue;
+ }
+ if (strncmp(cp, "plugin_path=", sizeof("plugin_path=") - 1) == 0) {
+ plugin_path = cp + sizeof("plugin_path=") - 1;
+ continue;
+ }
+ }
+
+ /* umask must not be more restrictive than the file modes. */
+ omask = umask(ACCESSPERMS & ~(iolog_filemode|iolog_dirmode));
+
+ if (!sudoers_debug_register(plugin_path, &debug_files)) {
+ ret = -1;
+ goto done;
+ }
+
+ /*
+ * Pull iolog settings out of command_info.
+ */
+ if (!iolog_deserialize_info(&iolog_details, user_info, command_info)) {
+ ret = false;
+ goto done;
+ }
+
+ /* If no I/O log path defined we need to figure it out ourselves. */
+ if (iolog_details.iolog_path == NULL) {
+ /* Get next session ID and convert it into a path. */
+ tofree = malloc(sizeof(_PATH_SUDO_IO_LOGDIR) + sizeof(sessid) + 2);
+ if (tofree == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ memcpy(tofree, _PATH_SUDO_IO_LOGDIR, sizeof(_PATH_SUDO_IO_LOGDIR));
+ if (!io_nextid(tofree, NULL, sessid)) {
+ ret = false;
+ goto done;
+ }
+ snprintf(tofree + sizeof(_PATH_SUDO_IO_LOGDIR), sizeof(sessid) + 2,
+ "%c%c/%c%c/%c%c", sessid[0], sessid[1], sessid[2], sessid[3],
+ sessid[4], sessid[5]);
+ iolog_details.iolog_path = tofree;
+ }
+
+ /*
+ * Make local copy of I/O log path and create it, along with any
+ * intermediate subdirs. Calls mkdtemp() if iolog_path ends in XXXXXX.
+ */
+ len = mkdir_iopath(iolog_details.iolog_path, pathbuf, sizeof(pathbuf));
+ if (len >= sizeof(pathbuf))
+ goto done;
+
+ /* Write log file with user and command details. */
+ if (!write_info_log(pathbuf, len, &iolog_details, argv))
+ goto done;
+
+ /* Create the timing and I/O log files. */
+ for (i = 0; i < IOFD_MAX; i++) {
+ if (!open_io_fd(pathbuf, len, &io_log_files[i], iolog_compress))
+ goto done;
+ }
+
+ /*
+ * Clear I/O log function pointers for disabled log functions.
+ */
+ if (!io_log_files[IOFD_STDIN].enabled)
+ sudoers_io.log_stdin = NULL;
+ if (!io_log_files[IOFD_STDOUT].enabled)
+ sudoers_io.log_stdout = NULL;
+ if (!io_log_files[IOFD_STDERR].enabled)
+ sudoers_io.log_stderr = NULL;
+ if (!io_log_files[IOFD_TTYIN].enabled)
+ sudoers_io.log_ttyin = NULL;
+ if (!io_log_files[IOFD_TTYOUT].enabled)
+ sudoers_io.log_ttyout = NULL;
+
+ if (sudo_gettime_awake(&last_time) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to get time of day", __func__);
+ goto done;
+ }
+
+ ret = true;
+
+done:
+ umask(omask);
+ free(tofree);
+ if (iolog_details.runas_pw)
+ sudo_pw_delref(iolog_details.runas_pw);
+ if (iolog_details.runas_gr)
+ sudo_gr_delref(iolog_details.runas_gr);
+ sudo_freepwcache();
+ sudo_freegrcache();
+
+ /* Ignore errors if they occur if the policy says so. */
+ if (ret == -1 && iolog_details.ignore_iolog_errors)
+ ret = 0;
+
+ debug_return_int(ret);
+}
+
+static void
+sudoers_io_close(int exit_status, int error)
+{
+ const char *errstr = NULL;
+ int i;
+ debug_decl(sudoers_io_close, SUDOERS_DEBUG_PLUGIN)
+
+ for (i = 0; i < IOFD_MAX; i++) {
+ if (io_log_files[i].fd.v == NULL)
+ continue;
+#ifdef HAVE_ZLIB_H
+ if (iolog_compress) {
+ int errnum;
+
+ if (gzclose(io_log_files[i].fd.g) != Z_OK)
+ errstr = gzerror(io_log_files[i].fd.g, &errnum);
+ } else
+#endif
+ if (fclose(io_log_files[i].fd.f) != 0)
+ errstr = strerror(errno);
+ }
+
+ if (errstr != NULL && !warned) {
+ /* Only warn about I/O log file errors once. */
+ log_warning(SLOG_SEND_MAIL,
+ N_("unable to write to I/O log file: %s"), errstr);
+ warned = true;
+ }
+
+ sudoers_debug_deregister();
+
+ return;
+}
+
+static int
+sudoers_io_version(int verbose)
+{
+ debug_decl(sudoers_io_version, SUDOERS_DEBUG_PLUGIN)
+
+ sudo_printf(SUDO_CONV_INFO_MSG, "Sudoers I/O plugin version %s\n",
+ PACKAGE_VERSION);
+
+ debug_return_int(true);
+}
+
+/*
+ * Generic I/O logging function. Called by the I/O logging entry points.
+ * Returns 1 on success and -1 on error.
+ */
+static int
+sudoers_io_log(union io_fd ifd, const char *buf, unsigned int len, int event)
+{
+ struct timespec now, delay;
+ char tbuf[1024];
+ const char *errstr = NULL;
+ int ret = -1;
+ debug_decl(sudoers_io_log, SUDOERS_DEBUG_PLUGIN)
+
+ if (ifd.v == NULL) {
+ sudo_warnx(U_("%s: internal error, I/O log file for event %d not open"),
+ __func__, event);
+ debug_return_int(-1);
+ }
+
+ if (sudo_gettime_awake(&now) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to get time of day", __func__);
+ errstr = strerror(errno);
+ goto bad;
+ }
+
+ /* Write I/O log file entry. */
+ errstr = iolog_write(ifd, buf, len);
+ if (errstr != NULL)
+ goto done;
+
+ /* Write timing file entry. */
+ sudo_timespecsub(&now, &last_time, &delay);
+ len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %lld.%09ld %u\n",
+ event, (long long)delay.tv_sec, delay.tv_nsec, len);
+ if (len >= sizeof(tbuf)) {
+ /* Not actually possible due to the size of tbuf[]. */
+ errstr = strerror(EOVERFLOW);
+ goto done;
+ }
+ errstr = iolog_write(io_log_files[IOFD_TIMING].fd, tbuf, len);
+ if (errstr != NULL)
+ goto done;
+
+ /* Success. */
+ ret = 1;
+
+done:
+ last_time.tv_sec = now.tv_sec;
+ last_time.tv_nsec = now.tv_nsec;
+
+bad:
+ if (ret == -1) {
+ if (errstr != NULL && !warned) {
+ /* Only warn about I/O log file errors once. */
+ log_warning(SLOG_SEND_MAIL,
+ N_("unable to write to I/O log file: %s"), errstr);
+ warned = true;
+ }
+
+ /* Ignore errors if they occur if the policy says so. */
+ if (iolog_details.ignore_iolog_errors)
+ ret = 1;
+ }
+
+ debug_return_int(ret);
+}
+
+static int
+sudoers_io_log_stdin(const char *buf, unsigned int len)
+{
+ const union io_fd ifd = io_log_files[IOFD_STDIN].fd;
+
+ return sudoers_io_log(ifd, buf, len, IO_EVENT_STDIN);
+}
+
+static int
+sudoers_io_log_stdout(const char *buf, unsigned int len)
+{
+ const union io_fd ifd = io_log_files[IOFD_STDOUT].fd;
+
+ return sudoers_io_log(ifd, buf, len, IO_EVENT_STDOUT);
+}
+
+static int
+sudoers_io_log_stderr(const char *buf, unsigned int len)
+{
+ const union io_fd ifd = io_log_files[IOFD_STDERR].fd;
+
+ return sudoers_io_log(ifd, buf, len, IO_EVENT_STDERR);
+}
+
+static int
+sudoers_io_log_ttyin(const char *buf, unsigned int len)
+{
+ const union io_fd ifd = io_log_files[IOFD_TTYIN].fd;
+
+ return sudoers_io_log(ifd, buf, len, IO_EVENT_TTYIN);
+}
+
+static int
+sudoers_io_log_ttyout(const char *buf, unsigned int len)
+{
+ const union io_fd ifd = io_log_files[IOFD_TTYOUT].fd;
+
+ return sudoers_io_log(ifd, buf, len, IO_EVENT_TTYOUT);
+}
+
+static int
+sudoers_io_change_winsize(unsigned int lines, unsigned int cols)
+{
+ struct timespec now, delay;
+ unsigned int len;
+ char tbuf[1024];
+ const char *errstr = NULL;
+ int ret = -1;
+ debug_decl(sudoers_io_change_winsize, SUDOERS_DEBUG_PLUGIN)
+
+ if (sudo_gettime_awake(&now) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to get time of day", __func__);
+ errstr = strerror(errno);
+ goto bad;
+ }
+
+ /* Write window change event to the timing file. */
+ sudo_timespecsub(&now, &last_time, &delay);
+ len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %lld.%09ld %u %u\n",
+ IO_EVENT_WINSIZE, (long long)delay.tv_sec, delay.tv_nsec, lines, cols);
+ if (len >= sizeof(tbuf)) {
+ /* Not actually possible due to the size of tbuf[]. */
+ errstr = strerror(EOVERFLOW);
+ goto done;
+ }
+ errstr = iolog_write(io_log_files[IOFD_TIMING].fd, tbuf, len);
+ if (errstr != NULL)
+ goto done;
+
+ /* Success. */
+ ret = 1;
+
+done:
+ last_time.tv_sec = now.tv_sec;
+ last_time.tv_nsec = now.tv_nsec;
+
+bad:
+ if (ret == -1) {
+ if (errstr != NULL && !warned) {
+ /* Only warn about I/O log file errors once. */
+ log_warning(SLOG_SEND_MAIL,
+ N_("unable to write to I/O log file: %s"), errstr);
+ warned = true;
+ }
+
+ /* Ignore errors if they occur if the policy says so. */
+ if (iolog_details.ignore_iolog_errors)
+ ret = 1;
+ }
+
+ debug_return_int(ret);
+}
+
+static int
+sudoers_io_suspend(int signo)
+{
+ struct timespec now, delay;
+ unsigned int len;
+ char tbuf[1024];
+ const char *errstr = NULL;
+ int ret = -1;
+ debug_decl(sudoers_io_suspend, SUDOERS_DEBUG_PLUGIN)
+
+ if (signo <= 0) {
+ sudo_warnx(U_("%s: internal error, invalid signal %d"),
+ __func__, signo);
+ debug_return_int(-1);
+ }
+
+ if (sudo_gettime_awake(&now) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to get time of day", __func__);
+ errstr = strerror(errno);
+ goto bad;
+ }
+
+ /* Write suspend event to the timing file. */
+ sudo_timespecsub(&now, &last_time, &delay);
+ len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %lld.%09ld %d\n",
+ IO_EVENT_SUSPEND, (long long)delay.tv_sec, delay.tv_nsec, signo);
+ if (len >= sizeof(tbuf)) {
+ /* Not actually possible due to the size of tbuf[]. */
+ errstr = strerror(EOVERFLOW);
+ goto done;
+ }
+ errstr = iolog_write(io_log_files[IOFD_TIMING].fd, tbuf, len);
+ if (errstr != NULL)
+ goto done;
+
+ /* Success. */
+ ret = 1;
+
+done:
+ last_time.tv_sec = now.tv_sec;
+ last_time.tv_nsec = now.tv_nsec;
+
+bad:
+ if (ret == -1) {
+ if (errstr != NULL && !warned) {
+ /* Only warn about I/O log file errors once. */
+ log_warning(SLOG_SEND_MAIL,
+ N_("unable to write to I/O log file: %s"), errstr);
+ warned = true;
+ }
+
+ /* Ignore errors if they occur if the policy says so. */
+ if (iolog_details.ignore_iolog_errors)
+ ret = 1;
+ }
+
+ debug_return_int(ret);
+}
+
+__dso_public struct io_plugin sudoers_io = {
+ SUDO_IO_PLUGIN,
+ SUDO_API_VERSION,
+ sudoers_io_open,
+ sudoers_io_close,
+ sudoers_io_version,
+ sudoers_io_log_ttyin,
+ sudoers_io_log_ttyout,
+ sudoers_io_log_stdin,
+ sudoers_io_log_stdout,
+ sudoers_io_log_stderr,
+ NULL, /* register_hooks */
+ NULL, /* deregister_hooks */
+ sudoers_io_change_winsize,
+ sudoers_io_suspend
+};
diff --git a/plugins/sudoers/iolog.h b/plugins/sudoers/iolog.h
new file mode 100644
index 0000000..d803a15
--- /dev/null
+++ b/plugins/sudoers/iolog.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_IOLOG_H
+#define SUDOERS_IOLOG_H
+
+#ifdef HAVE_ZLIB_H
+# include <zlib.h> /* for gzFile */
+#endif
+
+/*
+ * I/O log event types as stored as the first field in the timing file.
+ * Changing existing values will result in incompatible I/O log files.
+ */
+#define IO_EVENT_STDIN 0
+#define IO_EVENT_STDOUT 1
+#define IO_EVENT_STDERR 2
+#define IO_EVENT_TTYIN 3
+#define IO_EVENT_TTYOUT 4
+#define IO_EVENT_WINSIZE 5
+#define IO_EVENT_TTYOUT_1_8_7 6
+#define IO_EVENT_SUSPEND 7
+#define IO_EVENT_COUNT 8
+
+/* Default maximum session ID */
+#define SESSID_MAX 2176782336U
+
+union io_fd {
+ FILE *f;
+#ifdef HAVE_ZLIB_H
+ gzFile g;
+#endif
+ void *v;
+};
+
+/*
+ * Info present in the I/O log file
+ */
+struct log_info {
+ char *cwd;
+ char *user;
+ char *runas_user;
+ char *runas_group;
+ char *tty;
+ char *cmd;
+ time_t tstamp;
+ int rows;
+ int cols;
+};
+
+struct timing_closure {
+ const char *decimal;
+ struct timespec *max_delay;
+ union io_fd fd;
+ int event;
+ union {
+ struct {
+ int rows;
+ int cols;
+ } winsize;
+ size_t nbytes; // XXX
+ int signo;
+ } u;
+};
+
+/* iolog_util.c */
+bool parse_timing(const char *buf, struct timespec *delay, struct timing_closure *timing);
+char *parse_delay(const char *cp, struct timespec *delay, const char *decimal_point);
+struct log_info *parse_logfile(const char *logfile);
+void free_log_info(struct log_info *li);
+void adjust_delay(struct timespec *delay, struct timespec *max_delay, double scale_factor);
+
+#endif /* SUDOERS_IOLOG_H */
diff --git a/plugins/sudoers/iolog_files.h b/plugins/sudoers/iolog_files.h
new file mode 100644
index 0000000..889c20b
--- /dev/null
+++ b/plugins/sudoers/iolog_files.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_IOLOG_FILES_H
+#define SUDOERS_IOLOG_FILES_H
+
+/*
+ * Indexes into io_log_files[]
+ */
+#define IOFD_STDIN 0
+#define IOFD_STDOUT 1
+#define IOFD_STDERR 2
+#define IOFD_TTYIN 3
+#define IOFD_TTYOUT 4
+#define IOFD_TIMING 5
+#define IOFD_MAX 6
+
+struct io_log_file {
+ bool enabled;
+ const char *suffix;
+ union io_fd fd;
+};
+
+static struct io_log_file io_log_files[] = {
+ { false, "/stdin" }, /* IOFD_STDIN */
+ { false, "/stdout" }, /* IOFD_STDOUT */
+ { false, "/stderr" }, /* IOFD_STDERR */
+ { false, "/ttyin" }, /* IOFD_TTYIN */
+ { false, "/ttyout" }, /* IOFD_TTYOUT */
+ { true, "/timing" }, /* IOFD_TIMING */
+ { false, NULL } /* IOFD_MAX */
+};
+
+#endif /* SUDOERS_IOLOG_H */
diff --git a/plugins/sudoers/iolog_path.c b/plugins/sudoers/iolog_path.c
new file mode 100644
index 0000000..7cdc6ed
--- /dev/null
+++ b/plugins/sudoers/iolog_path.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2011-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <pwd.h>
+#include <grp.h>
+#include <time.h>
+
+#include "sudoers.h"
+
+struct path_escape {
+ const char *name;
+ size_t (*copy_fn)(char *, size_t, char *);
+};
+
+static size_t
+fill_seq(char *str, size_t strsize, char *logdir)
+{
+#ifdef SUDOERS_NO_SEQ
+ debug_decl(fill_seq, SUDOERS_DEBUG_UTIL)
+ debug_return_size_t(strlcpy(str, "%{seq}", strsize));
+#else
+ static char sessid[7];
+ int len;
+ debug_decl(fill_seq, SUDOERS_DEBUG_UTIL)
+
+ if (sessid[0] == '\0') {
+ if (!io_nextid(logdir, def_iolog_dir, sessid))
+ debug_return_size_t((size_t)-1);
+ }
+
+ /* Path is of the form /var/log/sudo-io/00/00/01. */
+ len = snprintf(str, strsize, "%c%c/%c%c/%c%c", sessid[0],
+ sessid[1], sessid[2], sessid[3], sessid[4], sessid[5]);
+ if (len < 0)
+ debug_return_size_t(strsize); /* handle non-standard snprintf() */
+ debug_return_size_t(len);
+#endif /* SUDOERS_NO_SEQ */
+}
+
+static size_t
+fill_user(char *str, size_t strsize, char *unused)
+{
+ debug_decl(fill_user, SUDOERS_DEBUG_UTIL)
+ debug_return_size_t(strlcpy(str, user_name, strsize));
+}
+
+static size_t
+fill_group(char *str, size_t strsize, char *unused)
+{
+ struct group *grp;
+ size_t len;
+ debug_decl(fill_group, SUDOERS_DEBUG_UTIL)
+
+ if ((grp = sudo_getgrgid(user_gid)) != NULL) {
+ len = strlcpy(str, grp->gr_name, strsize);
+ sudo_gr_delref(grp);
+ } else {
+ len = strlen(str);
+ len = snprintf(str + len, strsize - len, "#%u",
+ (unsigned int) user_gid);
+ }
+ debug_return_size_t(len);
+}
+
+static size_t
+fill_runas_user(char *str, size_t strsize, char *unused)
+{
+ debug_decl(fill_runas_user, SUDOERS_DEBUG_UTIL)
+ debug_return_size_t(strlcpy(str, runas_pw->pw_name, strsize));
+}
+
+static size_t
+fill_runas_group(char *str, size_t strsize, char *unused)
+{
+ struct group *grp;
+ size_t len;
+ debug_decl(fill_runas_group, SUDOERS_DEBUG_UTIL)
+
+ if (runas_gr != NULL) {
+ len = strlcpy(str, runas_gr->gr_name, strsize);
+ } else {
+ if ((grp = sudo_getgrgid(runas_pw->pw_gid)) != NULL) {
+ len = strlcpy(str, grp->gr_name, strsize);
+ sudo_gr_delref(grp);
+ } else {
+ len = strlen(str);
+ len = snprintf(str + len, strsize - len, "#%u",
+ (unsigned int) runas_pw->pw_gid);
+ }
+ }
+ debug_return_size_t(len);
+}
+
+static size_t
+fill_hostname(char *str, size_t strsize, char *unused)
+{
+ debug_decl(fill_hostname, SUDOERS_DEBUG_UTIL)
+ debug_return_size_t(strlcpy(str, user_shost, strsize));
+}
+
+static size_t
+fill_command(char *str, size_t strsize, char *unused)
+{
+ debug_decl(fill_command, SUDOERS_DEBUG_UTIL)
+ debug_return_size_t(strlcpy(str, user_base, strsize));
+}
+
+/* Note: "seq" must be first in the list. */
+static struct path_escape io_path_escapes[] = {
+ { "seq", fill_seq },
+ { "user", fill_user },
+ { "group", fill_group },
+ { "runas_user", fill_runas_user },
+ { "runas_group", fill_runas_group },
+ { "hostname", fill_hostname },
+ { "command", fill_command },
+ { NULL, NULL }
+};
+
+/*
+ * Concatenate dir + file, expanding any escape sequences.
+ * Returns the concatenated path and sets slashp point to
+ * the path separator between the expanded dir and file.
+ */
+char *
+expand_iolog_path(const char *prefix, const char *dir, const char *file,
+ char **slashp)
+{
+ size_t len, prelen = 0;
+ char *dst, *dst0, *path, *pathend, tmpbuf[PATH_MAX];
+ char *slash = NULL;
+ const char *endbrace, *src = dir;
+ struct path_escape *escapes = NULL;
+ int pass, oldlocale;
+ bool strfit;
+ debug_decl(expand_iolog_path, SUDOERS_DEBUG_UTIL)
+
+ /* Expanded path must be <= PATH_MAX */
+ if (prefix != NULL)
+ prelen = strlen(prefix);
+ path = malloc(prelen + PATH_MAX);
+ if (path == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto bad;
+ }
+ *path = '\0';
+ pathend = path + prelen + PATH_MAX;
+ dst = path;
+
+ /* Copy prefix, if present. */
+ if (prefix != NULL) {
+ memcpy(path, prefix, prelen);
+ dst += prelen;
+ *dst = '\0';
+ }
+
+ /* Trim leading slashes from file component. */
+ while (*file == '/')
+ file++;
+
+ for (pass = 0; pass < 3; pass++) {
+ strfit = false;
+ switch (pass) {
+ case 0:
+ src = dir;
+ escapes = io_path_escapes + 1; /* skip "%{seq}" */
+ break;
+ case 1:
+ /* Trim trailing slashes from dir component. */
+ while (dst > path + prelen + 1 && dst[-1] == '/')
+ dst--;
+ /* The NUL will be replaced with a '/' at the end. */
+ if (dst + 1 >= pathend)
+ goto bad;
+ slash = dst++;
+ continue;
+ case 2:
+ src = file;
+ escapes = io_path_escapes;
+ break;
+ }
+ dst0 = dst;
+ for (; *src != '\0'; src++) {
+ if (src[0] == '%') {
+ if (src[1] == '{') {
+ endbrace = strchr(src + 2, '}');
+ if (endbrace != NULL) {
+ struct path_escape *esc;
+ len = (size_t)(endbrace - src - 2);
+ for (esc = escapes; esc->name != NULL; esc++) {
+ if (strncmp(src + 2, esc->name, len) == 0 &&
+ esc->name[len] == '\0')
+ break;
+ }
+ if (esc->name != NULL) {
+ len = esc->copy_fn(dst, (size_t)(pathend - dst),
+ path + prelen);
+ if (len >= (size_t)(pathend - dst))
+ goto bad;
+ dst += len;
+ src = endbrace;
+ continue;
+ }
+ }
+ } else if (src[1] == '%') {
+ /* Collapse %% -> % */
+ src++;
+ } else {
+ /* May need strftime() */
+ strfit = 1;
+ }
+ }
+ /* Need at least 2 chars, including the NUL terminator. */
+ if (dst + 1 >= pathend)
+ goto bad;
+ *dst++ = *src;
+ }
+ *dst = '\0';
+
+ /* Expand strftime escapes as needed. */
+ if (strfit) {
+ time_t now;
+ struct tm *timeptr;
+
+ time(&now);
+ if ((timeptr = localtime(&now)) == NULL)
+ goto bad;
+
+ /* Use sudoers locale for strftime() */
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+
+ /* We only call strftime() on the current part of the buffer. */
+ tmpbuf[sizeof(tmpbuf) - 1] = '\0';
+ len = strftime(tmpbuf, sizeof(tmpbuf), dst0, timeptr);
+
+ /* Restore old locale. */
+ sudoers_setlocale(oldlocale, NULL);
+
+ if (len == 0 || tmpbuf[sizeof(tmpbuf) - 1] != '\0')
+ goto bad; /* strftime() failed, buf too small? */
+
+ if (len >= (size_t)(pathend - dst0))
+ goto bad; /* expanded buffer too big to fit. */
+ memcpy(dst0, tmpbuf, len);
+ dst = dst0 + len;
+ *dst = '\0';
+ }
+ }
+ if (slash != NULL)
+ *slash = '/';
+ if (slashp != NULL)
+ *slashp = slash;
+
+ debug_return_str(path);
+bad:
+ free(path);
+ debug_return_str(NULL);
+}
diff --git a/plugins/sudoers/iolog_util.c b/plugins/sudoers/iolog_util.c
new file mode 100644
index 0000000..f22ca62
--- /dev/null
+++ b/plugins/sudoers/iolog_util.c
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <time.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+#include "iolog.h"
+
+static int timing_event_adj;
+
+struct log_info *
+parse_logfile(const char *logfile)
+{
+ FILE *fp;
+ char *buf = NULL, *cp, *ep;
+ const char *errstr;
+ size_t bufsize = 0, cwdsize = 0, cmdsize = 0;
+ struct log_info *li = NULL;
+ debug_decl(parse_logfile, SUDO_DEBUG_UTIL)
+
+ fp = fopen(logfile, "r");
+ if (fp == NULL) {
+ sudo_warn(U_("unable to open %s"), logfile);
+ goto bad;
+ }
+
+ /*
+ * ID file has three lines:
+ * 1) a log info line
+ * 2) cwd
+ * 3) command with args
+ */
+ if ((li = calloc(1, sizeof(*li))) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (getline(&buf, &bufsize, fp) == -1 ||
+ getline(&li->cwd, &cwdsize, fp) == -1 ||
+ getline(&li->cmd, &cmdsize, fp) == -1) {
+ sudo_warn(U_("%s: invalid log file"), logfile);
+ goto bad;
+ }
+
+ /* Strip the newline from the cwd and command. */
+ li->cwd[strcspn(li->cwd, "\n")] = '\0';
+ li->cmd[strcspn(li->cmd, "\n")] = '\0';
+
+ /*
+ * Crack the log line (rows and cols not present in old versions).
+ * timestamp:user:runas_user:runas_group:tty:rows:cols
+ * XXX - probably better to use strtok and switch on the state.
+ */
+ buf[strcspn(buf, "\n")] = '\0';
+ cp = buf;
+
+ /* timestamp */
+ if ((ep = strchr(cp, ':')) == NULL) {
+ sudo_warn(U_("%s: time stamp field is missing"), logfile);
+ goto bad;
+ }
+ *ep = '\0';
+ li->tstamp = strtonum(cp, 0, TIME_T_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_warn(U_("%s: time stamp %s: %s"), logfile, cp, errstr);
+ goto bad;
+ }
+
+ /* user */
+ cp = ep + 1;
+ if ((ep = strchr(cp, ':')) == NULL) {
+ sudo_warn(U_("%s: user field is missing"), logfile);
+ goto bad;
+ }
+ if ((li->user = strndup(cp, (size_t)(ep - cp))) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+ /* runas user */
+ cp = ep + 1;
+ if ((ep = strchr(cp, ':')) == NULL) {
+ sudo_warn(U_("%s: runas user field is missing"), logfile);
+ goto bad;
+ }
+ if ((li->runas_user = strndup(cp, (size_t)(ep - cp))) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+ /* runas group */
+ cp = ep + 1;
+ if ((ep = strchr(cp, ':')) == NULL) {
+ sudo_warn(U_("%s: runas group field is missing"), logfile);
+ goto bad;
+ }
+ if (cp != ep) {
+ if ((li->runas_group = strndup(cp, (size_t)(ep - cp))) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ }
+
+ /* tty, followed by optional rows + columns */
+ cp = ep + 1;
+ if ((ep = strchr(cp, ':')) == NULL) {
+ /* just the tty */
+ if ((li->tty = strdup(cp)) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ } else {
+ /* tty followed by rows + columns */
+ if ((li->tty = strndup(cp, (size_t)(ep - cp))) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ cp = ep + 1;
+ /* need to NULL out separator to use strtonum() */
+ if ((ep = strchr(cp, ':')) != NULL) {
+ *ep = '\0';
+ }
+ li->rows = strtonum(cp, 1, INT_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: tty rows %s: %s", logfile, cp, errstr);
+ }
+ if (ep != NULL) {
+ cp = ep + 1;
+ li->cols = strtonum(cp, 1, INT_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: tty cols %s: %s", logfile, cp, errstr);
+ }
+ }
+ }
+ fclose(fp);
+ free(buf);
+ debug_return_ptr(li);
+
+bad:
+ if (fp != NULL)
+ fclose(fp);
+ free(buf);
+ free_log_info(li);
+ debug_return_ptr(NULL);
+}
+
+void
+adjust_delay(struct timespec *delay, struct timespec *max_delay,
+ double scale_factor)
+{
+ double seconds;
+ debug_decl(adjust_delay, SUDO_DEBUG_UTIL)
+
+ if (scale_factor != 1.0) {
+ /* Order is important: we don't want to double the remainder. */
+ seconds = (double)delay->tv_sec / scale_factor;
+ delay->tv_sec = (time_t)seconds;
+ delay->tv_nsec /= scale_factor;
+ delay->tv_nsec += (seconds - delay->tv_sec) * 1000000000;
+ while (delay->tv_nsec >= 1000000000) {
+ delay->tv_sec++;
+ delay->tv_nsec -= 1000000000;
+ }
+ }
+
+ /* Clamp to max delay. */
+ if (max_delay != NULL) {
+ if (sudo_timespeccmp(delay, max_delay, >)) {
+ delay->tv_sec = max_delay->tv_sec;
+ delay->tv_nsec = max_delay->tv_nsec;
+ }
+ }
+
+ debug_return;
+}
+
+/*
+ * Parse the delay as seconds and nanoseconds: %lld.%09ld
+ * Sudo used to write this as a double, but since timing data is logged
+ * in the C locale this may not match the current locale.
+ */
+char *
+parse_delay(const char *cp, struct timespec *delay, const char *decimal_point)
+{
+ char numbuf[(((sizeof(long long) * 8) + 2) / 3) + 2];
+ const char *errstr, *ep;
+ long long llval;
+ size_t len;
+ debug_decl(parse_delay, SUDO_DEBUG_UTIL)
+
+ /* Parse seconds (whole number portion). */
+ for (ep = cp; isdigit((unsigned char)*ep); ep++)
+ continue;
+ len = (size_t)(ep - cp);
+ if (len >= sizeof(numbuf)) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: number of seconds is too large", cp);
+ debug_return_ptr(NULL);
+ }
+ memcpy(numbuf, cp, len);
+ numbuf[len] = '\0';
+ delay->tv_sec = strtonum(numbuf, 0, TIME_T_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: number of seconds is %s", numbuf, errstr);
+ debug_return_ptr(NULL);
+ }
+
+ /* Radix may be in user's locale for sudo < 1.7.4 so accept that too. */
+ if (*ep != '.' && *ep != *decimal_point) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "invalid characters after seconds: %s", ep);
+ debug_return_ptr(NULL);
+ }
+ cp = ep + 1;
+
+ /* Parse fractional part, we may read more precision than we can store. */
+ for (ep = cp; isdigit((unsigned char)*ep); ep++)
+ continue;
+ len = (size_t)(ep - cp);
+ if (len >= sizeof(numbuf)) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: number of nanoseconds is too large", cp);
+ debug_return_ptr(NULL);
+ }
+ memcpy(numbuf, cp, len);
+ numbuf[len] = '\0';
+ llval = strtonum(numbuf, 0, LLONG_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: number of nanoseconds is %s", numbuf, errstr);
+ debug_return_ptr(NULL);
+ }
+
+ /* Adjust fractional part to nanosecond precision. */
+ if (len < 9) {
+ /* Convert to nanosecond precision. */
+ do {
+ llval *= 10;
+ } while (++len < 9);
+ } else if (len > 9) {
+ /* Clamp to nanoseconds. */
+ do {
+ llval /= 10;
+ } while (--len > 9);
+ }
+ delay->tv_nsec = (long)llval;
+
+ /* Advance to the next field. */
+ while (isspace((unsigned char)*ep))
+ ep++;
+
+ debug_return_str((char *)ep);
+}
+
+/*
+ * Parse a timing line, which is formatted as:
+ * IO_EVENT_TTYOUT sleep_time num_bytes
+ * IO_EVENT_WINSIZE sleep_time rows cols
+ * IO_EVENT_SUSPEND sleep_time signo
+ * Where type is IO_EVENT_*, sleep_time is the number of seconds to sleep
+ * before writing the data and num_bytes is the number of bytes to output.
+ * Returns true on success and false on failure.
+ */
+bool
+parse_timing(const char *buf, struct timespec *delay,
+ struct timing_closure *timing)
+{
+ unsigned long ulval;
+ char *cp, *ep;
+ debug_decl(parse_timing, SUDO_DEBUG_UTIL)
+
+ /* Clear fd. */
+ timing->fd.v = NULL;
+
+ /* Parse event type. */
+ ulval = strtoul(buf, &ep, 10);
+ if (ep == buf || !isspace((unsigned char) *ep))
+ goto bad;
+ if (ulval >= IO_EVENT_COUNT)
+ goto bad;
+ if (ulval == IO_EVENT_TTYOUT_1_8_7) {
+ /* work around a bug in timing files generated by sudo 1.8.7 */
+ timing_event_adj = 2;
+ }
+ timing->event = (int)ulval - timing_event_adj;
+ for (cp = ep + 1; isspace((unsigned char) *cp); cp++)
+ continue;
+
+ /* Parse delay, returns the next field or NULL on error. */
+ if ((cp = parse_delay(cp, delay, timing->decimal)) == NULL)
+ goto bad;
+
+ switch (timing->event) {
+ case IO_EVENT_SUSPEND:
+ ulval = strtoul(cp, &ep, 10);
+ if (ep == cp || *ep != '\0')
+ goto bad;
+ if (ulval > INT_MAX)
+ goto bad;
+ timing->u.signo = (int)ulval;
+ break;
+ case IO_EVENT_WINSIZE:
+ ulval = strtoul(cp, &ep, 10);
+ if (ep == cp || !isspace((unsigned char) *ep))
+ goto bad;
+ if (ulval > INT_MAX)
+ goto bad;
+ timing->u.winsize.rows = (int)ulval;
+ for (cp = ep + 1; isspace((unsigned char) *cp); cp++)
+ continue;
+
+ ulval = strtoul(cp, &ep, 10);
+ if (ep == cp || *ep != '\0')
+ goto bad;
+ if (ulval > INT_MAX)
+ goto bad;
+ timing->u.winsize.cols = (int)ulval;
+ break;
+ default:
+ errno = 0;
+ ulval = strtoul(cp, &ep, 10);
+ if (ep == cp || *ep != '\0')
+ goto bad;
+ /* Note: assumes SIZE_MAX == ULONG_MAX */
+ if (errno == ERANGE && ulval == ULONG_MAX)
+ goto bad;
+ timing->u.nbytes = (size_t)ulval;
+ break;
+ }
+
+ debug_return_bool(true);
+bad:
+ debug_return_bool(false);
+}
+
+void
+free_log_info(struct log_info *li)
+{
+ if (li != NULL) {
+ free(li->cwd);
+ free(li->user);
+ free(li->runas_user);
+ free(li->runas_group);
+ free(li->tty);
+ free(li->cmd);
+ free(li);
+ }
+}
diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c
new file mode 100644
index 0000000..bc2baec
--- /dev/null
+++ b/plugins/sudoers/ldap.c
@@ -0,0 +1,2050 @@
+/*
+ * Copyright (c) 2003-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * This code is derived from software contributed by Aaron Spangler.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <time.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
+#ifdef HAVE_LBER_H
+# include <lber.h>
+#endif
+#include <ldap.h>
+#if defined(HAVE_LDAP_SSL_H)
+# include <ldap_ssl.h>
+#elif defined(HAVE_MPS_LDAP_SSL_H)
+# include <mps/ldap_ssl.h>
+#endif
+#ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S
+# ifdef HAVE_SASL_SASL_H
+# include <sasl/sasl.h>
+# else
+# include <sasl.h>
+# endif
+#endif /* HAVE_LDAP_SASL_INTERACTIVE_BIND_S */
+
+#include "sudoers.h"
+#include "gram.h"
+#include "sudo_lbuf.h"
+#include "sudo_ldap.h"
+#include "sudo_ldap_conf.h"
+#include "sudo_dso.h"
+
+#ifndef LDAP_OPT_RESULT_CODE
+# define LDAP_OPT_RESULT_CODE LDAP_OPT_ERROR_NUMBER
+#endif
+
+#ifndef LDAP_OPT_SUCCESS
+# define LDAP_OPT_SUCCESS LDAP_SUCCESS
+#endif
+
+#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && !defined(LDAP_SASL_QUIET)
+# define LDAP_SASL_QUIET 0
+#endif
+
+#ifndef HAVE_LDAP_UNBIND_EXT_S
+#define ldap_unbind_ext_s(a, b, c) ldap_unbind_s(a)
+#endif
+
+#ifndef HAVE_LDAP_SEARCH_EXT_S
+# ifdef HAVE_LDAP_SEARCH_ST
+# define ldap_search_ext_s(a, b, c, d, e, f, g, h, i, j, k) \
+ ldap_search_st(a, b, c, d, e, f, i, k)
+# else
+# define ldap_search_ext_s(a, b, c, d, e, f, g, h, i, j, k) \
+ ldap_search_s(a, b, c, d, e, f, k)
+# endif
+#endif
+
+#define LDAP_FOREACH(var, ld, res) \
+ for ((var) = ldap_first_entry((ld), (res)); \
+ (var) != NULL; \
+ (var) = ldap_next_entry((ld), (var)))
+
+/* The TIMEFILTER_LENGTH is the length of the filter when timed entries
+ are used. The length is computed as follows:
+ 81 for the filter itself
+ + 2 * 17 for the now timestamp
+*/
+#define TIMEFILTER_LENGTH 115
+
+/*
+ * The ldap_search structure implements a linked list of ldap and
+ * search result pointers, which allows us to remove them after
+ * all search results have been combined in memory.
+ */
+struct ldap_search_result {
+ STAILQ_ENTRY(ldap_search_result) entries;
+ LDAP *ldap;
+ LDAPMessage *searchresult;
+};
+STAILQ_HEAD(ldap_search_list, ldap_search_result);
+
+/*
+ * The ldap_entry_wrapper structure is used to implement sorted result entries.
+ * A double is used for the order to allow for insertion of new entries
+ * without having to renumber everything.
+ * Note: there is no standard floating point type in LDAP.
+ * As a result, some LDAP servers will only allow an integer.
+ */
+struct ldap_entry_wrapper {
+ LDAPMessage *entry;
+ double order;
+};
+
+/*
+ * The ldap_result structure contains the list of matching searches as
+ * well as an array of all result entries sorted by the sudoOrder attribute.
+ */
+struct ldap_result {
+ struct ldap_search_list searches;
+ struct ldap_entry_wrapper *entries;
+ unsigned int allocated_entries;
+ unsigned int nentries;
+};
+#define ALLOCATION_INCREMENT 100
+
+/*
+ * The ldap_netgroup structure implements a singly-linked tail queue of
+ * netgroups a user is a member of when querying netgroups directly.
+ */
+struct ldap_netgroup {
+ STAILQ_ENTRY(ldap_netgroup) entries;
+ char *name;
+};
+STAILQ_HEAD(ldap_netgroup_list, ldap_netgroup);
+
+/*
+ * LDAP sudo_nss handle.
+ * We store the connection to the LDAP server and the passwd struct of the
+ * user the last query was performed for.
+ */
+struct sudo_ldap_handle {
+ LDAP *ld;
+ struct passwd *pw;
+ struct sudoers_parse_tree parse_tree;
+};
+
+#ifdef HAVE_LDAP_INITIALIZE
+static char *
+sudo_ldap_join_uri(struct ldap_config_str_list *uri_list)
+{
+ struct ldap_config_str *uri;
+ size_t len = 0;
+ char *buf = NULL;
+ debug_decl(sudo_ldap_join_uri, SUDOERS_DEBUG_LDAP)
+
+ STAILQ_FOREACH(uri, uri_list, entries) {
+ if (ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS) {
+ if (strncasecmp(uri->val, "ldaps://", 8) == 0) {
+ sudo_warnx(U_("starttls not supported when using ldaps"));
+ ldap_conf.ssl_mode = SUDO_LDAP_SSL;
+ }
+ }
+ len += strlen(uri->val) + 1;
+ }
+ if (len == 0 || (buf = malloc(len)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ } else {
+ char *cp = buf;
+
+ STAILQ_FOREACH(uri, uri_list, entries) {
+ cp += strlcpy(cp, uri->val, len - (cp - buf));
+ *cp++ = ' ';
+ }
+ cp[-1] = '\0';
+ }
+ debug_return_str(buf);
+}
+#endif /* HAVE_LDAP_INITIALIZE */
+
+/*
+ * Wrapper for ldap_create() or ldap_init() that handles
+ * SSL/TLS initialization as well.
+ * Returns LDAP_SUCCESS on success, else non-zero.
+ */
+static int
+sudo_ldap_init(LDAP **ldp, const char *host, int port)
+{
+ LDAP *ld;
+ int ret = LDAP_CONNECT_ERROR;
+ debug_decl(sudo_ldap_init, SUDOERS_DEBUG_LDAP)
+
+#ifdef HAVE_LDAPSSL_INIT
+ if (ldap_conf.ssl_mode != SUDO_LDAP_CLEAR) {
+ const int defsecure = ldap_conf.ssl_mode == SUDO_LDAP_SSL;
+ DPRINTF2("ldapssl_clientauth_init(%s, %s)",
+ ldap_conf.tls_certfile ? ldap_conf.tls_certfile : "NULL",
+ ldap_conf.tls_keyfile ? ldap_conf.tls_keyfile : "NULL");
+ ret = ldapssl_clientauth_init(ldap_conf.tls_certfile, NULL,
+ ldap_conf.tls_keyfile != NULL, ldap_conf.tls_keyfile, NULL);
+ /*
+ * Starting with version 5.0, Mozilla-derived LDAP SDKs require
+ * the cert and key paths to be a directory, not a file.
+ * If the user specified a file and it fails, try the parent dir.
+ */
+ if (ret != LDAP_SUCCESS) {
+ bool retry = false;
+ if (ldap_conf.tls_certfile != NULL) {
+ char *cp = strrchr(ldap_conf.tls_certfile, '/');
+ if (cp != NULL && strncmp(cp + 1, "cert", 4) == 0) {
+ *cp = '\0';
+ retry = true;
+ }
+ }
+ if (ldap_conf.tls_keyfile != NULL) {
+ char *cp = strrchr(ldap_conf.tls_keyfile, '/');
+ if (cp != NULL && strncmp(cp + 1, "key", 3) == 0) {
+ *cp = '\0';
+ retry = true;
+ }
+ }
+ if (retry) {
+ DPRINTF2("retry ldapssl_clientauth_init(%s, %s)",
+ ldap_conf.tls_certfile ? ldap_conf.tls_certfile : "NULL",
+ ldap_conf.tls_keyfile ? ldap_conf.tls_keyfile : "NULL");
+ ret = ldapssl_clientauth_init(ldap_conf.tls_certfile, NULL,
+ ldap_conf.tls_keyfile != NULL, ldap_conf.tls_keyfile, NULL);
+ }
+ }
+ if (ret != LDAP_SUCCESS) {
+ sudo_warnx(U_("unable to initialize SSL cert and key db: %s"),
+ ldapssl_err2string(ret));
+ if (ldap_conf.tls_certfile == NULL)
+ sudo_warnx(U_("you must set TLS_CERT in %s to use SSL"),
+ path_ldap_conf);
+ goto done;
+ }
+
+ DPRINTF2("ldapssl_init(%s, %d, %d)", host, port, defsecure);
+ if ((ld = ldapssl_init(host, port, defsecure)) != NULL)
+ ret = LDAP_SUCCESS;
+ } else
+#elif defined(HAVE_LDAP_SSL_INIT) && defined(HAVE_LDAP_SSL_CLIENT_INIT)
+ if (ldap_conf.ssl_mode == SUDO_LDAP_SSL) {
+ int sslrc;
+ ret = ldap_ssl_client_init(ldap_conf.tls_keyfile, ldap_conf.tls_keypw,
+ 0, &sslrc);
+ if (ret != LDAP_SUCCESS) {
+ sudo_warnx("ldap_ssl_client_init(): %s (SSL reason code %d)",
+ ldap_err2string(ret), sslrc);
+ goto done;
+ }
+ DPRINTF2("ldap_ssl_init(%s, %d, NULL)", host, port);
+ if ((ld = ldap_ssl_init((char *)host, port, NULL)) != NULL)
+ ret = LDAP_SUCCESS;
+ } else
+#endif
+ {
+#ifdef HAVE_LDAP_CREATE
+ DPRINTF2("ldap_create()");
+ if ((ret = ldap_create(&ld)) != LDAP_SUCCESS)
+ goto done;
+ DPRINTF2("ldap_set_option(LDAP_OPT_HOST_NAME, %s)", host);
+ ret = ldap_set_option(ld, LDAP_OPT_HOST_NAME, host);
+#else
+ DPRINTF2("ldap_init(%s, %d)", host, port);
+ if ((ld = ldap_init((char *)host, port)) == NULL)
+ goto done;
+ ret = LDAP_SUCCESS;
+#endif
+ }
+
+ *ldp = ld;
+done:
+ debug_return_int(ret);
+}
+
+/*
+ * Wrapper for ldap_get_values_len() that fills in the response code
+ * on error.
+ */
+static struct berval **
+sudo_ldap_get_values_len(LDAP *ld, LDAPMessage *entry, char *attr, int *rc)
+{
+ struct berval **bval;
+
+ bval = ldap_get_values_len(ld, entry, attr);
+ if (bval == NULL) {
+ int optrc = ldap_get_option(ld, LDAP_OPT_RESULT_CODE, rc);
+ if (optrc != LDAP_OPT_SUCCESS)
+ *rc = optrc;
+ } else {
+ *rc = LDAP_SUCCESS;
+ }
+ return bval;
+}
+
+/*
+ * Walk through search results and return true if we have a matching
+ * non-Unix group (including netgroups), else false.
+ */
+static int
+sudo_ldap_check_non_unix_group(LDAP *ld, LDAPMessage *entry, struct passwd *pw)
+{
+ struct berval **bv, **p;
+ bool ret = false;
+ char *val;
+ int rc;
+ debug_decl(sudo_ldap_check_non_unix_group, SUDOERS_DEBUG_LDAP)
+
+ if (!entry)
+ debug_return_bool(ret);
+
+ /* get the values from the entry */
+ bv = sudo_ldap_get_values_len(ld, entry, "sudoUser", &rc);
+ if (bv == NULL) {
+ if (rc == LDAP_NO_MEMORY)
+ debug_return_int(-1);
+ debug_return_bool(false);
+ }
+
+ /* walk through values */
+ for (p = bv; *p != NULL && !ret; p++) {
+ val = (*p)->bv_val;
+ if (*val == '+') {
+ if (netgr_matches(val, def_netgroup_tuple ? user_runhost : NULL,
+ def_netgroup_tuple ? user_srunhost : NULL, pw->pw_name))
+ ret = true;
+ DPRINTF2("ldap sudoUser netgroup '%s' ... %s", val,
+ ret ? "MATCH!" : "not");
+ } else {
+ if (group_plugin_query(pw->pw_name, val + 2, pw))
+ ret = true;
+ DPRINTF2("ldap sudoUser non-Unix group '%s' ... %s", val,
+ ret ? "MATCH!" : "not");
+ }
+ }
+
+ ldap_value_free_len(bv); /* cleanup */
+
+ debug_return_bool(ret);
+}
+
+/*
+ * Extract the dn from an entry and return the first rdn from it.
+ */
+static char *
+sudo_ldap_get_first_rdn(LDAP *ld, LDAPMessage *entry)
+{
+#ifdef HAVE_LDAP_STR2DN
+ char *dn, *rdn = NULL;
+ LDAPDN tmpDN;
+ debug_decl(sudo_ldap_get_first_rdn, SUDOERS_DEBUG_LDAP)
+
+ if ((dn = ldap_get_dn(ld, entry)) == NULL)
+ debug_return_str(NULL);
+ if (ldap_str2dn(dn, &tmpDN, LDAP_DN_FORMAT_LDAP) == LDAP_SUCCESS) {
+ ldap_rdn2str(tmpDN[0], &rdn, LDAP_DN_FORMAT_UFN);
+ ldap_dnfree(tmpDN);
+ }
+ ldap_memfree(dn);
+ debug_return_str(rdn);
+#else
+ char *dn, **edn;
+ debug_decl(sudo_ldap_get_first_rdn, SUDOERS_DEBUG_LDAP)
+
+ if ((dn = ldap_get_dn(ld, entry)) == NULL)
+ debug_return_str(NULL);
+ edn = ldap_explode_dn(dn, 1);
+ ldap_memfree(dn);
+ debug_return_str(edn ? edn[0] : NULL);
+#endif
+}
+
+/*
+ * Read sudoOption and fill in the defaults list.
+ * This is used to parse the cn=defaults entry.
+ */
+static bool
+sudo_ldap_parse_options(LDAP *ld, LDAPMessage *entry, struct defaults_list *defs)
+{
+ struct berval **bv, **p;
+ char *cn, *cp, *source = NULL;
+ bool ret = false;
+ int rc;
+ debug_decl(sudo_ldap_parse_options, SUDOERS_DEBUG_LDAP)
+
+ bv = sudo_ldap_get_values_len(ld, entry, "sudoOption", &rc);
+ if (bv == NULL) {
+ if (rc == LDAP_NO_MEMORY)
+ debug_return_bool(false);
+ debug_return_bool(true);
+ }
+
+ /* Use sudoRole in place of file name in defaults. */
+ cn = sudo_ldap_get_first_rdn(ld, entry);
+ if (asprintf(&cp, "sudoRole %s", cn ? cn : "UNKNOWN") == -1) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ if ((source = rcstr_dup(cp)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ free(cp);
+ goto done;
+ }
+
+ /* Walk through options, appending to defs. */
+ for (p = bv; *p != NULL; p++) {
+ char *var, *val;
+ int op;
+
+ op = sudo_ldap_parse_option((*p)->bv_val, &var, &val);
+ if (!sudo_ldap_add_default(var, val, op, source, defs)) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ }
+
+ ret = true;
+
+done:
+ rcstr_delref(source);
+ if (cn)
+ ldap_memfree(cn);
+ ldap_value_free_len(bv);
+
+ debug_return_bool(ret);
+}
+
+/*
+ * Build an LDAP timefilter.
+ *
+ * Stores a filter in the buffer that makes sure only entries
+ * are selected that have a sudoNotBefore in the past and a
+ * sudoNotAfter in the future, i.e. a filter of the following
+ * structure (spaced out a little more for better readability:
+ *
+ * (&
+ * (|
+ * (!(sudoNotAfter=*))
+ * (sudoNotAfter>__now__)
+ * )
+ * (|
+ * (!(sudoNotBefore=*))
+ * (sudoNotBefore<__now__)
+ * )
+ * )
+ *
+ * If either the sudoNotAfter or sudoNotBefore attributes are missing,
+ * no time restriction shall be imposed.
+ */
+static bool
+sudo_ldap_timefilter(char *buffer, size_t buffersize)
+{
+ struct tm *tp;
+ time_t now;
+ char timebuffer[sizeof("20120727121554.0Z")];
+ int len = -1;
+ debug_decl(sudo_ldap_timefilter, SUDOERS_DEBUG_LDAP)
+
+ /* Make sure we have a formatted timestamp for __now__. */
+ time(&now);
+ if ((tp = gmtime(&now)) == NULL) {
+ sudo_warn(U_("unable to get GMT time"));
+ goto done;
+ }
+
+ /* Format the timestamp according to the RFC. */
+ if (strftime(timebuffer, sizeof(timebuffer), "%Y%m%d%H%M%S.0Z", tp) == 0) {
+ sudo_warnx(U_("unable to format timestamp"));
+ goto done;
+ }
+
+ /* Build filter. */
+ len = snprintf(buffer, buffersize, "(&(|(!(sudoNotAfter=*))(sudoNotAfter>=%s))(|(!(sudoNotBefore=*))(sudoNotBefore<=%s)))",
+ timebuffer, timebuffer);
+ if (len <= 0 || (size_t)len >= buffersize) {
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ errno = EOVERFLOW;
+ len = -1;
+ }
+
+done:
+ debug_return_bool(len != -1);
+}
+
+/*
+ * Builds up a filter to search for default settings
+ */
+static char *
+sudo_ldap_build_default_filter(void)
+{
+ char *filt;
+ debug_decl(sudo_ldap_build_default_filter, SUDOERS_DEBUG_LDAP)
+
+ if (!ldap_conf.search_filter)
+ debug_return_str(strdup("cn=defaults"));
+
+ if (asprintf(&filt, "(&%s(cn=defaults))", ldap_conf.search_filter) == -1)
+ debug_return_str(NULL);
+
+ debug_return_str(filt);
+}
+
+/*
+ * Determine length of query value after escaping characters
+ * as per RFC 4515.
+ */
+static size_t
+sudo_ldap_value_len(const char *value)
+{
+ const char *s;
+ size_t len = 0;
+
+ for (s = value; *s != '\0'; s++) {
+ switch (*s) {
+ case '\\':
+ case '(':
+ case ')':
+ case '*':
+ len += 2;
+ break;
+ }
+ }
+ len += (size_t)(s - value);
+ return len;
+}
+
+/*
+ * Like strlcat() but escapes characters as per RFC 4515.
+ */
+static size_t
+sudo_ldap_value_cat(char *dst, const char *src, size_t size)
+{
+ char *d = dst;
+ const char *s = src;
+ size_t n = size;
+ size_t dlen;
+
+ /* Find the end of dst and adjust bytes left but don't go past end */
+ while (n-- != 0 && *d != '\0')
+ d++;
+ dlen = d - dst;
+ n = size - dlen;
+
+ if (n == 0)
+ return dlen + strlen(s);
+ while (*s != '\0') {
+ switch (*s) {
+ case '\\':
+ if (n < 3)
+ goto done;
+ *d++ = '\\';
+ *d++ = '5';
+ *d++ = 'c';
+ n -= 3;
+ break;
+ case '(':
+ if (n < 3)
+ goto done;
+ *d++ = '\\';
+ *d++ = '2';
+ *d++ = '8';
+ n -= 3;
+ break;
+ case ')':
+ if (n < 3)
+ goto done;
+ *d++ = '\\';
+ *d++ = '2';
+ *d++ = '9';
+ n -= 3;
+ break;
+ case '*':
+ if (n < 3)
+ goto done;
+ *d++ = '\\';
+ *d++ = '2';
+ *d++ = 'a';
+ n -= 3;
+ break;
+ default:
+ if (n < 1)
+ goto done;
+ *d++ = *s;
+ n--;
+ break;
+ }
+ s++;
+ }
+done:
+ *d = '\0';
+ while (*s != '\0')
+ s++;
+ return dlen + (s - src); /* count does not include NUL */
+}
+
+/*
+ * Like strdup() but escapes characters as per RFC 4515.
+ */
+static char *
+sudo_ldap_value_dup(const char *src)
+{
+ char *dst;
+ size_t size;
+
+ size = sudo_ldap_value_len(src) + 1;
+ dst = malloc(size);
+ if (dst == NULL)
+ return NULL;
+
+ *dst = '\0';
+ if (sudo_ldap_value_cat(dst, src, size) >= size) {
+ /* Should not be possible... */
+ free(dst);
+ dst = NULL;
+ }
+ return dst;
+}
+
+/*
+ * Check the netgroups list beginning at "start" for nesting.
+ * Parent nodes with a memberNisNetgroup that match one of the
+ * netgroups are added to the list and checked for further nesting.
+ * Return true on success or false if there was an internal overflow.
+ */
+static bool
+sudo_netgroup_lookup_nested(LDAP *ld, char *base, struct timeval *timeout,
+ struct ldap_netgroup_list *netgroups, struct ldap_netgroup *start)
+{
+ LDAPMessage *entry, *result;
+ size_t filt_len;
+ char *filt;
+ int rc;
+ debug_decl(sudo_netgroup_lookup_nested, SUDOERS_DEBUG_LDAP);
+
+ DPRINTF1("Checking for nested netgroups from netgroup_base '%s'", base);
+ do {
+ struct ldap_netgroup *ng, *old_tail;
+
+ result = NULL;
+ old_tail = STAILQ_LAST(netgroups, ldap_netgroup, entries);
+ filt_len = strlen(ldap_conf.netgroup_search_filter) + 7;
+ for (ng = start; ng != NULL; ng = STAILQ_NEXT(ng, entries)) {
+ filt_len += sudo_ldap_value_len(ng->name) + 20;
+ }
+ if ((filt = malloc(filt_len)) == NULL)
+ goto oom;
+ CHECK_STRLCPY(filt, "(&", filt_len);
+ CHECK_STRLCAT(filt, ldap_conf.netgroup_search_filter, filt_len);
+ CHECK_STRLCAT(filt, "(|", filt_len);
+ for (ng = start; ng != NULL; ng = STAILQ_NEXT(ng, entries)) {
+ CHECK_STRLCAT(filt, "(memberNisNetgroup=", filt_len);
+ CHECK_LDAP_VCAT(filt, ng->name, filt_len);
+ CHECK_STRLCAT(filt, ")", filt_len);
+ }
+ CHECK_STRLCAT(filt, "))", filt_len);
+ DPRINTF1("ldap netgroup search filter: '%s'", filt);
+ rc = ldap_search_ext_s(ld, base, LDAP_SCOPE_SUBTREE, filt,
+ NULL, 0, NULL, NULL, timeout, 0, &result);
+ free(filt);
+ if (rc == LDAP_SUCCESS) {
+ LDAP_FOREACH(entry, ld, result) {
+ struct berval **bv;
+
+ bv = sudo_ldap_get_values_len(ld, entry, "cn", &rc);
+ if (bv == NULL) {
+ if (rc == LDAP_NO_MEMORY)
+ goto oom;
+ } else {
+ /* Don't add a netgroup twice. */
+ STAILQ_FOREACH(ng, netgroups, entries) {
+ /* Assumes only one cn per entry. */
+ if (strcasecmp(ng->name, (*bv)->bv_val) == 0)
+ break;
+ }
+ if (ng == NULL) {
+ ng = malloc(sizeof(*ng));
+ if (ng == NULL ||
+ (ng->name = strdup((*bv)->bv_val)) == NULL) {
+ free(ng);
+ ldap_value_free_len(bv);
+ goto oom;
+ }
+#ifdef __clang_analyzer__
+ /* clang analyzer false positive */
+ if (__builtin_expect(netgroups->stqh_last == NULL, 0))
+ __builtin_trap();
+#endif
+ STAILQ_INSERT_TAIL(netgroups, ng, entries);
+ DPRINTF1("Found new netgroup %s for %s", ng->name, base);
+ }
+ ldap_value_free_len(bv);
+ }
+ }
+ }
+ ldap_msgfree(result);
+
+ /* Check for nested netgroups in what we added. */
+ start = old_tail ? STAILQ_NEXT(old_tail, entries) : STAILQ_FIRST(netgroups);
+ } while (start != NULL);
+
+ debug_return_bool(true);
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ ldap_msgfree(result);
+ debug_return_bool(false);
+overflow:
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ free(filt);
+ debug_return_bool(false);
+}
+
+/*
+ * Look up netgroups that the specified user is a member of.
+ * Appends new entries to the netgroups list.
+ * Return true on success or false if there was an internal overflow.
+ */
+static bool
+sudo_netgroup_lookup(LDAP *ld, struct passwd *pw,
+ struct ldap_netgroup_list *netgroups)
+{
+ struct ldap_config_str *base;
+ struct ldap_netgroup *ng, *old_tail;
+ struct timeval tv, *tvp = NULL;
+ LDAPMessage *entry, *result = NULL;
+ const char *domain;
+ char *escaped_domain = NULL, *escaped_user = NULL;
+ char *escaped_host = NULL, *escaped_shost = NULL, *filt = NULL;
+ int filt_len, rc;
+ bool ret = false;
+ debug_decl(sudo_netgroup_lookup, SUDOERS_DEBUG_LDAP);
+
+ if (ldap_conf.timeout > 0) {
+ tv.tv_sec = ldap_conf.timeout;
+ tv.tv_usec = 0;
+ tvp = &tv;
+ }
+
+ /* Use NIS domain if set, else wildcard match. */
+ domain = sudo_getdomainname();
+
+ /* Escape the domain, host names, and user name per RFC 4515. */
+ if (domain != NULL) {
+ if ((escaped_domain = sudo_ldap_value_dup(domain)) == NULL)
+ goto oom;
+ }
+ if ((escaped_user = sudo_ldap_value_dup(pw->pw_name)) == NULL)
+ goto oom;
+ if (def_netgroup_tuple) {
+ escaped_host = sudo_ldap_value_dup(user_runhost);
+ if (user_runhost == user_srunhost)
+ escaped_shost = escaped_host;
+ else
+ escaped_shost = sudo_ldap_value_dup(user_srunhost);
+ if (escaped_host == NULL || escaped_shost == NULL)
+ goto oom;
+ }
+
+ /* Build query, using NIS domain if it is set. */
+ if (domain != NULL) {
+ if (escaped_host != escaped_shost) {
+ filt_len = asprintf(&filt, "(&%s(|"
+ "(nisNetgroupTriple=\\28,%s,%s\\29)"
+ "(nisNetgroupTriple=\\28%s,%s,%s\\29)"
+ "(nisNetgroupTriple=\\28%s,%s,%s\\29)"
+ "(nisNetgroupTriple=\\28,%s,\\29)"
+ "(nisNetgroupTriple=\\28%s,%s,\\29)"
+ "(nisNetgroupTriple=\\28%s,%s,\\29)))",
+ ldap_conf.netgroup_search_filter, escaped_user, escaped_domain,
+ escaped_shost, escaped_user, escaped_domain,
+ escaped_host, escaped_user, escaped_domain, escaped_user,
+ escaped_shost, escaped_user, escaped_host, escaped_user);
+ } else if (escaped_shost != NULL) {
+ filt_len = asprintf(&filt, "(&%s(|"
+ "(nisNetgroupTriple=\\28,%s,%s\\29)"
+ "(nisNetgroupTriple=\\28%s,%s,%s\\29)"
+ "(nisNetgroupTriple=\\28,%s,\\29)"
+ "(nisNetgroupTriple=\\28%s,%s,\\29)))",
+ ldap_conf.netgroup_search_filter, escaped_user, escaped_domain,
+ escaped_shost, escaped_user, escaped_domain,
+ escaped_user, escaped_shost, escaped_user);
+ } else {
+ filt_len = asprintf(&filt, "(&%s(|"
+ "(nisNetgroupTriple=\\28*,%s,%s\\29)"
+ "(nisNetgroupTriple=\\28*,%s,\\29)))",
+ ldap_conf.netgroup_search_filter, escaped_user, escaped_domain,
+ escaped_user);
+ }
+ } else {
+ if (escaped_host != escaped_shost) {
+ filt_len = asprintf(&filt, "(&%s(|"
+ "(nisNetgroupTriple=\\28,%s,*\\29)"
+ "(nisNetgroupTriple=\\28%s,%s,*\\29)"
+ "(nisNetgroupTriple=\\28%s,%s,*\\29)))",
+ ldap_conf.netgroup_search_filter, escaped_user,
+ escaped_shost, escaped_user, escaped_host, escaped_user);
+ } else if (escaped_shost != NULL) {
+ filt_len = asprintf(&filt, "(&%s(|"
+ "(nisNetgroupTriple=\\28,%s,*\\29)"
+ "(nisNetgroupTriple=\\28%s,%s,*\\29)))",
+ ldap_conf.netgroup_search_filter, escaped_user,
+ escaped_shost, escaped_user);
+ } else {
+ filt_len = asprintf(&filt,
+ "(&%s(|(nisNetgroupTriple=\\28*,%s,*\\29)))",
+ ldap_conf.netgroup_search_filter, escaped_user);
+ }
+ }
+ if (filt_len == -1)
+ goto oom;
+ DPRINTF1("ldap netgroup search filter: '%s'", filt);
+
+ STAILQ_FOREACH(base, &ldap_conf.netgroup_base, entries) {
+ DPRINTF1("searching from netgroup_base '%s'", base->val);
+ rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, filt,
+ NULL, 0, NULL, NULL, tvp, 0, &result);
+ if (rc != LDAP_SUCCESS) {
+ DPRINTF1("ldap netgroup search failed: %s", ldap_err2string(rc));
+ ldap_msgfree(result);
+ result = NULL;
+ continue;
+ }
+
+ old_tail = STAILQ_LAST(netgroups, ldap_netgroup, entries);
+ LDAP_FOREACH(entry, ld, result) {
+ struct berval **bv;
+
+ bv = sudo_ldap_get_values_len(ld, entry, "cn", &rc);
+ if (bv == NULL) {
+ if (rc == LDAP_NO_MEMORY)
+ goto oom;
+ } else {
+ /* Don't add a netgroup twice. */
+ STAILQ_FOREACH(ng, netgroups, entries) {
+ /* Assumes only one cn per entry. */
+ if (strcasecmp(ng->name, (*bv)->bv_val) == 0)
+ break;
+ }
+ if (ng == NULL) {
+ ng = malloc(sizeof(*ng));
+ if (ng == NULL ||
+ (ng->name = strdup((*bv)->bv_val)) == NULL) {
+ free(ng);
+ ldap_value_free_len(bv);
+ goto oom;
+ }
+ STAILQ_INSERT_TAIL(netgroups, ng, entries);
+ DPRINTF1("Found new netgroup %s for %s", ng->name,
+ base->val);
+ }
+ ldap_value_free_len(bv);
+ }
+ }
+ ldap_msgfree(result);
+ result = NULL;
+
+ /* Check for nested netgroups in what we added. */
+ ng = old_tail ? STAILQ_NEXT(old_tail, entries) : STAILQ_FIRST(netgroups);
+ if (ng != NULL) {
+ if (!sudo_netgroup_lookup_nested(ld, base->val, tvp, netgroups, ng))
+ goto done;
+ }
+ }
+ ret = true;
+ goto done;
+
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+done:
+ free(escaped_domain);
+ free(escaped_user);
+ free(escaped_host);
+ if (escaped_host != escaped_shost)
+ free(escaped_shost);
+ free(filt);
+ ldap_msgfree(result);
+ debug_return_bool(ret);
+}
+
+/*
+ * Builds up a filter to check against LDAP.
+ */
+static char *
+sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
+{
+ char *buf, timebuffer[TIMEFILTER_LENGTH + 1], gidbuf[MAX_UID_T_LEN + 1];
+ struct ldap_netgroup_list netgroups;
+ struct ldap_netgroup *ng = NULL;
+ struct gid_list *gidlist;
+ struct group_list *grlist;
+ struct group *grp;
+ size_t sz = 0;
+ int i;
+ debug_decl(sudo_ldap_build_pass1, SUDOERS_DEBUG_LDAP)
+
+ STAILQ_INIT(&netgroups);
+
+ /* If there is a filter, allocate space for the global AND. */
+ if (ldap_conf.timed || ldap_conf.search_filter)
+ sz += 3;
+
+ /* Add LDAP search filter if present. */
+ if (ldap_conf.search_filter)
+ sz += strlen(ldap_conf.search_filter);
+
+ /* Then add (|(sudoUser=USERNAME)(sudoUser=ALL)) + NUL */
+ sz += 29 + sudo_ldap_value_len(pw->pw_name);
+
+ /* Add space for primary and supplementary groups and gids */
+ if ((grp = sudo_getgrgid(pw->pw_gid)) != NULL) {
+ sz += 12 + sudo_ldap_value_len(grp->gr_name);
+ }
+ sz += 13 + MAX_UID_T_LEN;
+ if ((grlist = sudo_get_grlist(pw)) != NULL) {
+ for (i = 0; i < grlist->ngroups; i++) {
+ if (grp != NULL && strcasecmp(grlist->groups[i], grp->gr_name) == 0)
+ continue;
+ sz += 12 + sudo_ldap_value_len(grlist->groups[i]);
+ }
+ }
+ if ((gidlist = sudo_get_gidlist(pw, ENTRY_TYPE_ANY)) != NULL) {
+ for (i = 0; i < gidlist->ngids; i++) {
+ if (pw->pw_gid == gidlist->gids[i])
+ continue;
+ sz += 13 + MAX_UID_T_LEN;
+ }
+ }
+
+ /* Add space for user netgroups if netgroup_base specified. */
+ if (!STAILQ_EMPTY(&ldap_conf.netgroup_base)) {
+ DPRINTF1("Looking up netgroups for %s", pw->pw_name);
+ if (sudo_netgroup_lookup(ld, pw, &netgroups)) {
+ STAILQ_FOREACH(ng, &netgroups, entries) {
+ sz += 14 + strlen(ng->name);
+ }
+ } else {
+ /* sudo_netgroup_lookup() failed, clean up. */
+ while ((ng = STAILQ_FIRST(&netgroups)) != NULL) {
+ STAILQ_REMOVE_HEAD(&netgroups, entries);
+ free(ng->name);
+ free(ng);
+ }
+ }
+ }
+
+ /* If timed, add space for time limits. */
+ if (ldap_conf.timed)
+ sz += TIMEFILTER_LENGTH;
+ if ((buf = malloc(sz)) == NULL)
+ goto bad;
+ *buf = '\0';
+
+ /*
+ * If timed or using a search filter, start a global AND clause to
+ * contain the search filter, search criteria, and time restriction.
+ */
+ if (ldap_conf.timed || ldap_conf.search_filter)
+ CHECK_STRLCPY(buf, "(&", sz);
+
+ if (ldap_conf.search_filter)
+ CHECK_STRLCAT(buf, ldap_conf.search_filter, sz);
+
+ /* Global OR + sudoUser=user_name filter */
+ CHECK_STRLCAT(buf, "(|(sudoUser=", sz);
+ CHECK_LDAP_VCAT(buf, pw->pw_name, sz);
+ CHECK_STRLCAT(buf, ")", sz);
+
+ /* Append primary group and gid */
+ if (grp != NULL) {
+ CHECK_STRLCAT(buf, "(sudoUser=%", sz);
+ CHECK_LDAP_VCAT(buf, grp->gr_name, sz);
+ CHECK_STRLCAT(buf, ")", sz);
+ }
+ (void) snprintf(gidbuf, sizeof(gidbuf), "%u", (unsigned int)pw->pw_gid);
+ CHECK_STRLCAT(buf, "(sudoUser=%#", sz);
+ CHECK_STRLCAT(buf, gidbuf, sz);
+ CHECK_STRLCAT(buf, ")", sz);
+
+ /* Append supplementary groups and gids */
+ if (grlist != NULL) {
+ for (i = 0; i < grlist->ngroups; i++) {
+ if (grp != NULL && strcasecmp(grlist->groups[i], grp->gr_name) == 0)
+ continue;
+ CHECK_STRLCAT(buf, "(sudoUser=%", sz);
+ CHECK_LDAP_VCAT(buf, grlist->groups[i], sz);
+ CHECK_STRLCAT(buf, ")", sz);
+ }
+ }
+ if (gidlist != NULL) {
+ for (i = 0; i < gidlist->ngids; i++) {
+ if (pw->pw_gid == gidlist->gids[i])
+ continue;
+ (void) snprintf(gidbuf, sizeof(gidbuf), "%u",
+ (unsigned int)gidlist->gids[i]);
+ CHECK_STRLCAT(buf, "(sudoUser=%#", sz);
+ CHECK_STRLCAT(buf, gidbuf, sz);
+ CHECK_STRLCAT(buf, ")", sz);
+ }
+ }
+
+ /* Done with groups. */
+ if (gidlist != NULL)
+ sudo_gidlist_delref(gidlist);
+ if (grlist != NULL)
+ sudo_grlist_delref(grlist);
+ if (grp != NULL)
+ sudo_gr_delref(grp);
+
+ /* Add netgroups (if any), freeing the list as we go. */
+ while ((ng = STAILQ_FIRST(&netgroups)) != NULL) {
+ STAILQ_REMOVE_HEAD(&netgroups, entries);
+ CHECK_STRLCAT(buf, "(sudoUser=+", sz);
+ CHECK_LDAP_VCAT(buf, ng->name, sz);
+ CHECK_STRLCAT(buf, ")", sz);
+ free(ng->name);
+ free(ng);
+ }
+
+ /* Add ALL to list and end the global OR. */
+ CHECK_STRLCAT(buf, "(sudoUser=ALL)", sz);
+
+ /* Add the time restriction, or simply end the global OR. */
+ if (ldap_conf.timed) {
+ CHECK_STRLCAT(buf, ")", sz); /* closes the global OR */
+ if (!sudo_ldap_timefilter(timebuffer, sizeof(timebuffer)))
+ goto bad;
+ CHECK_STRLCAT(buf, timebuffer, sz);
+ } else if (ldap_conf.search_filter) {
+ CHECK_STRLCAT(buf, ")", sz); /* closes the global OR */
+ }
+ CHECK_STRLCAT(buf, ")", sz); /* closes the global OR or the global AND */
+
+ debug_return_str(buf);
+overflow:
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ if (ng != NULL) {
+ /* Overflow while traversing netgroups. */
+ free(ng->name);
+ free(ng);
+ }
+ errno = EOVERFLOW;
+bad:
+ while ((ng = STAILQ_FIRST(&netgroups)) != NULL) {
+ STAILQ_REMOVE_HEAD(&netgroups, entries);
+ free(ng->name);
+ free(ng);
+ }
+ free(buf);
+ debug_return_str(NULL);
+}
+
+/*
+ * Builds up a filter to check against non-Unix group
+ * entries in LDAP, including netgroups.
+ */
+static char *
+sudo_ldap_build_pass2(void)
+{
+ char *filt, timebuffer[TIMEFILTER_LENGTH + 1];
+ bool query_netgroups = def_use_netgroups;
+ int len;
+ debug_decl(sudo_ldap_build_pass2, SUDOERS_DEBUG_LDAP)
+
+ /* No need to query netgroups if using netgroup_base. */
+ if (!STAILQ_EMPTY(&ldap_conf.netgroup_base))
+ query_netgroups = false;
+
+ /* Short circuit if no netgroups and no non-Unix groups. */
+ if (!query_netgroups && !def_group_plugin) {
+ errno = ENOENT;
+ debug_return_str(NULL);
+ }
+
+ if (ldap_conf.timed) {
+ if (!sudo_ldap_timefilter(timebuffer, sizeof(timebuffer)))
+ debug_return_str(NULL);
+ }
+
+ /*
+ * Match all sudoUsers beginning with '+' or '%:'.
+ * If a search filter or time restriction is specified,
+ * those get ANDed in to the expression.
+ */
+ if (query_netgroups && def_group_plugin) {
+ len = asprintf(&filt, "%s%s(|(sudoUser=+*)(sudoUser=%%:*))%s%s",
+ (ldap_conf.timed || ldap_conf.search_filter) ? "(&" : "",
+ ldap_conf.search_filter ? ldap_conf.search_filter : "",
+ ldap_conf.timed ? timebuffer : "",
+ (ldap_conf.timed || ldap_conf.search_filter) ? ")" : "");
+ } else {
+ len = asprintf(&filt, "(&%s(sudoUser=*)(sudoUser=%s*)%s)",
+ ldap_conf.search_filter ? ldap_conf.search_filter : "",
+ query_netgroups ? "+" : "%:",
+ ldap_conf.timed ? timebuffer : "");
+ }
+ if (len == -1)
+ filt = NULL;
+
+ debug_return_str(filt);
+}
+
+static char *
+berval_iter(void **vp)
+{
+ struct berval **bv = *vp;
+
+ *vp = bv + 1;
+ return *bv ? (*bv)->bv_val : NULL;
+}
+
+static bool
+ldap_to_sudoers(LDAP *ld, struct ldap_result *lres,
+ struct userspec_list *ldap_userspecs)
+{
+ struct userspec *us;
+ struct member *m;
+ unsigned int i;
+ int rc;
+ debug_decl(ldap_to_sudoers, SUDOERS_DEBUG_LDAP)
+
+ /* We only have a single userspec */
+ if ((us = calloc(1, sizeof(*us))) == NULL)
+ goto oom;
+ TAILQ_INIT(&us->users);
+ TAILQ_INIT(&us->privileges);
+ STAILQ_INIT(&us->comments);
+ TAILQ_INSERT_TAIL(ldap_userspecs, us, entries);
+
+ /* The user has already matched, use ALL as wildcard. */
+ if ((m = calloc(1, sizeof(*m))) == NULL)
+ goto oom;
+ m->type = ALL;
+ TAILQ_INSERT_TAIL(&us->users, m, entries);
+
+ /* Treat each sudoRole as a separate privilege. */
+ for (i = 0; i < lres->nentries; i++) {
+ LDAPMessage *entry = lres->entries[i].entry;
+ struct berval **cmnds = NULL, **hosts = NULL;
+ struct berval **runasusers = NULL, **runasgroups = NULL;
+ struct berval **opts = NULL, **notbefore = NULL, **notafter = NULL;
+ struct privilege *priv = NULL;
+ char *cn = NULL;
+
+ /* Ignore sudoRole without sudoCommand. */
+ cmnds = sudo_ldap_get_values_len(ld, entry, "sudoCommand", &rc);
+ if (cmnds == NULL) {
+ if (rc == LDAP_NO_MEMORY)
+ goto cleanup;
+ continue;
+ }
+
+ /* Get the entry's dn for long format printing. */
+ if ((cn = sudo_ldap_get_first_rdn(ld, entry)) == NULL)
+ goto cleanup;
+
+ /* Get sudoHost */
+ hosts = sudo_ldap_get_values_len(ld, entry, "sudoHost", &rc);
+ if (rc == LDAP_NO_MEMORY)
+ goto cleanup;
+
+ /* Get sudoRunAsUser / sudoRunAsGroup */
+ runasusers = sudo_ldap_get_values_len(ld, entry, "sudoRunAsUser", &rc);
+ if (runasusers == NULL) {
+ if (rc != LDAP_NO_MEMORY)
+ runasusers = sudo_ldap_get_values_len(ld, entry, "sudoRunAs", &rc);
+ if (rc == LDAP_NO_MEMORY)
+ goto cleanup;
+ }
+ runasgroups = sudo_ldap_get_values_len(ld, entry, "sudoRunAsGroup", &rc);
+ if (rc == LDAP_NO_MEMORY)
+ goto cleanup;
+
+ /* Get sudoNotBefore / sudoNotAfter */
+ notbefore = sudo_ldap_get_values_len(ld, entry, "sudoNotBefore", &rc);
+ if (rc == LDAP_NO_MEMORY)
+ goto cleanup;
+ notafter = sudo_ldap_get_values_len(ld, entry, "sudoNotAfter", &rc);
+ if (rc == LDAP_NO_MEMORY)
+ goto cleanup;
+
+ /* Parse sudoOptions. */
+ opts = sudo_ldap_get_values_len(ld, entry, "sudoOption", &rc);
+ if (rc == LDAP_NO_MEMORY)
+ goto cleanup;
+
+ priv = sudo_ldap_role_to_priv(cn, hosts, runasusers, runasgroups,
+ cmnds, opts, notbefore ? notbefore[0]->bv_val : NULL,
+ notafter ? notafter[0]->bv_val : NULL, false, true, berval_iter);
+
+ cleanup:
+ if (cn != NULL)
+ ldap_memfree(cn);
+ if (cmnds != NULL)
+ ldap_value_free_len(cmnds);
+ if (hosts != NULL)
+ ldap_value_free_len(hosts);
+ if (runasusers != NULL)
+ ldap_value_free_len(runasusers);
+ if (runasgroups != NULL)
+ ldap_value_free_len(runasgroups);
+ if (opts != NULL)
+ ldap_value_free_len(opts);
+ if (notbefore != NULL)
+ ldap_value_free_len(notbefore);
+ if (notafter != NULL)
+ ldap_value_free_len(notafter);
+
+ if (priv == NULL)
+ goto oom;
+ TAILQ_INSERT_TAIL(&us->privileges, priv, entries);
+ }
+
+ debug_return_bool(true);
+
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ free_userspecs(ldap_userspecs);
+ debug_return_bool(false);
+}
+
+#ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S
+typedef unsigned int (*sudo_gss_krb5_ccache_name_t)(unsigned int *minor_status, const char *name, const char **old_name);
+static sudo_gss_krb5_ccache_name_t sudo_gss_krb5_ccache_name;
+
+static int
+sudo_set_krb5_ccache_name(const char *name, const char **old_name)
+{
+ int ret = 0;
+ unsigned int junk;
+ static bool initialized;
+ debug_decl(sudo_set_krb5_ccache_name, SUDOERS_DEBUG_LDAP)
+
+ if (!initialized) {
+ sudo_gss_krb5_ccache_name = (sudo_gss_krb5_ccache_name_t)
+ sudo_dso_findsym(SUDO_DSO_DEFAULT, "gss_krb5_ccache_name");
+ initialized = true;
+ }
+
+ /*
+ * Try to use gss_krb5_ccache_name() if possible.
+ * We also need to set KRB5CCNAME since some LDAP libs may not use
+ * gss_krb5_ccache_name().
+ */
+ if (sudo_gss_krb5_ccache_name != NULL) {
+ ret = sudo_gss_krb5_ccache_name(&junk, name, old_name);
+ } else {
+ /* No gss_krb5_ccache_name(), fall back on KRB5CCNAME. */
+ if (old_name != NULL)
+ *old_name = sudo_getenv("KRB5CCNAME");
+ }
+ if (name != NULL && *name != '\0') {
+ if (sudo_setenv("KRB5CCNAME", name, true) == -1)
+ ret = -1;
+ } else {
+ if (sudo_unsetenv("KRB5CCNAME") == -1)
+ ret = -1;
+ }
+
+ debug_return_int(ret);
+}
+
+/*
+ * Make a copy of the credential cache file specified by KRB5CCNAME
+ * which must be readable by the user. The resulting cache file
+ * is root-owned and will be removed after authenticating via SASL.
+ */
+static char *
+sudo_krb5_copy_cc_file(const char *old_ccname)
+{
+ int nfd, ofd = -1;
+ ssize_t nread, nwritten = -1;
+ static char new_ccname[sizeof(_PATH_TMP) + sizeof("sudocc_XXXXXXXX") - 1];
+ char buf[10240], *ret = NULL;
+ debug_decl(sudo_krb5_copy_cc_file, SUDOERS_DEBUG_LDAP)
+
+ old_ccname = sudo_krb5_ccname_path(old_ccname);
+ if (old_ccname != NULL) {
+ /* Open credential cache as user to prevent stolen creds. */
+ if (!set_perms(PERM_USER))
+ goto done;
+ ofd = open(old_ccname, O_RDONLY|O_NONBLOCK);
+ if (!restore_perms())
+ goto done;
+
+ if (ofd != -1) {
+ (void) fcntl(ofd, F_SETFL, 0);
+ if (sudo_lock_file(ofd, SUDO_LOCK)) {
+ snprintf(new_ccname, sizeof(new_ccname), "%s%s",
+ _PATH_TMP, "sudocc_XXXXXXXX");
+ nfd = mkstemp(new_ccname);
+ if (nfd != -1) {
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "copy ccache %s -> %s", old_ccname, new_ccname);
+ while ((nread = read(ofd, buf, sizeof(buf))) > 0) {
+ ssize_t off = 0;
+ do {
+ nwritten = write(nfd, buf + off, nread - off);
+ if (nwritten == -1) {
+ sudo_warn("error writing to %s", new_ccname);
+ goto write_error;
+ }
+ off += nwritten;
+ } while (off < nread);
+ }
+ if (nread == -1)
+ sudo_warn("unable to read %s", new_ccname);
+write_error:
+ close(nfd);
+ if (nread != -1 && nwritten != -1) {
+ ret = new_ccname; /* success! */
+ } else {
+ unlink(new_ccname); /* failed */
+ }
+ } else {
+ sudo_warn("unable to create temp file %s", new_ccname);
+ }
+ }
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "unable to open %s", old_ccname);
+ }
+ }
+done:
+ if (ofd != -1)
+ close(ofd);
+ debug_return_str(ret);
+}
+
+static int
+sudo_ldap_sasl_interact(LDAP *ld, unsigned int flags, void *_auth_id,
+ void *_interact)
+{
+ char *auth_id = (char *)_auth_id;
+ sasl_interact_t *interact = (sasl_interact_t *)_interact;
+ int ret = LDAP_SUCCESS;
+ debug_decl(sudo_ldap_sasl_interact, SUDOERS_DEBUG_LDAP)
+
+ for (; interact->id != SASL_CB_LIST_END; interact++) {
+ if (interact->id != SASL_CB_USER) {
+ sudo_warnx("sudo_ldap_sasl_interact: unexpected interact id %lu",
+ interact->id);
+ ret = LDAP_PARAM_ERROR;
+ break;
+ }
+
+ if (auth_id != NULL)
+ interact->result = auth_id;
+ else if (interact->defresult != NULL)
+ interact->result = interact->defresult;
+ else
+ interact->result = "";
+
+ interact->len = strlen(interact->result);
+#if SASL_VERSION_MAJOR < 2
+ interact->result = strdup(interact->result);
+ if (interact->result == NULL) {
+ ret = LDAP_NO_MEMORY;
+ break;
+ }
+#endif /* SASL_VERSION_MAJOR < 2 */
+ DPRINTF2("sudo_ldap_sasl_interact: SASL_CB_USER %s",
+ (const char *)interact->result);
+ }
+ debug_return_int(ret);
+}
+#endif /* HAVE_LDAP_SASL_INTERACTIVE_BIND_S */
+
+/*
+ * Create a new sudo_ldap_result structure.
+ */
+static struct ldap_result *
+sudo_ldap_result_alloc(void)
+{
+ struct ldap_result *result;
+ debug_decl(sudo_ldap_result_alloc, SUDOERS_DEBUG_LDAP)
+
+ result = calloc(1, sizeof(*result));
+ if (result != NULL)
+ STAILQ_INIT(&result->searches);
+
+ debug_return_ptr(result);
+}
+
+/*
+ * Free the ldap result structure
+ */
+static void
+sudo_ldap_result_free(struct ldap_result *lres)
+{
+ struct ldap_search_result *s;
+ debug_decl(sudo_ldap_result_free, SUDOERS_DEBUG_LDAP)
+
+ if (lres != NULL) {
+ if (lres->nentries) {
+ free(lres->entries);
+ lres->entries = NULL;
+ }
+ while ((s = STAILQ_FIRST(&lres->searches)) != NULL) {
+ STAILQ_REMOVE_HEAD(&lres->searches, entries);
+ ldap_msgfree(s->searchresult);
+ free(s);
+ }
+ free(lres);
+ }
+ debug_return;
+}
+
+/*
+ * Add a search result to the ldap_result structure.
+ */
+static struct ldap_search_result *
+sudo_ldap_result_add_search(struct ldap_result *lres, LDAP *ldap,
+ LDAPMessage *searchresult)
+{
+ struct ldap_search_result *news;
+ debug_decl(sudo_ldap_result_add_search, SUDOERS_DEBUG_LDAP)
+
+ /* Create new entry and add it to the end of the chain. */
+ news = calloc(1, sizeof(*news));
+ if (news != NULL) {
+ news->ldap = ldap;
+ news->searchresult = searchresult;
+ STAILQ_INSERT_TAIL(&lres->searches, news, entries);
+ }
+
+ debug_return_ptr(news);
+}
+
+/*
+ * Connect to the LDAP server specified by ld.
+ * Returns LDAP_SUCCESS on success, else non-zero.
+ */
+static int
+sudo_ldap_bind_s(LDAP *ld)
+{
+ int ret;
+ debug_decl(sudo_ldap_bind_s, SUDOERS_DEBUG_LDAP)
+
+#ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S
+ if (ldap_conf.rootuse_sasl == true ||
+ (ldap_conf.rootuse_sasl != false && ldap_conf.use_sasl == true)) {
+ const char *old_ccname = NULL;
+ const char *new_ccname = ldap_conf.krb5_ccname;
+ const char *tmp_ccname = NULL;
+ void *auth_id = ldap_conf.rootsasl_auth_id ?
+ ldap_conf.rootsasl_auth_id : ldap_conf.sasl_auth_id;
+ int rc;
+
+ /* Make temp copy of the user's credential cache as needed. */
+ if (ldap_conf.krb5_ccname == NULL && user_ccname != NULL) {
+ new_ccname = tmp_ccname = sudo_krb5_copy_cc_file(user_ccname);
+ if (tmp_ccname == NULL) {
+ /* XXX - fatal error */
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "unable to copy user ccache %s", user_ccname);
+ }
+ }
+
+ if (new_ccname != NULL) {
+ rc = sudo_set_krb5_ccache_name(new_ccname, &old_ccname);
+ if (rc == 0) {
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "set ccache name %s -> %s",
+ old_ccname ? old_ccname : "(none)", new_ccname);
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
+ "sudo_set_krb5_ccache_name() failed: %d", rc);
+ }
+ }
+ ret = ldap_sasl_interactive_bind_s(ld, ldap_conf.binddn,
+ ldap_conf.sasl_mech, NULL, NULL, LDAP_SASL_QUIET,
+ sudo_ldap_sasl_interact, auth_id);
+ if (new_ccname != NULL) {
+ rc = sudo_set_krb5_ccache_name(old_ccname ? old_ccname : "", NULL);
+ if (rc == 0) {
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "restore ccache name %s -> %s", new_ccname,
+ old_ccname ? old_ccname : "(none)");
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
+ "sudo_set_krb5_ccache_name() failed: %d", rc);
+ }
+ /* Remove temporary copy of user's credential cache. */
+ if (tmp_ccname != NULL)
+ unlink(tmp_ccname);
+ }
+ if (ret != LDAP_SUCCESS) {
+ sudo_warnx("ldap_sasl_interactive_bind_s(): %s",
+ ldap_err2string(ret));
+ goto done;
+ }
+ DPRINTF1("ldap_sasl_interactive_bind_s() ok");
+ } else
+#endif /* HAVE_LDAP_SASL_INTERACTIVE_BIND_S */
+#ifdef HAVE_LDAP_SASL_BIND_S
+ {
+ struct berval bv;
+
+ bv.bv_val = ldap_conf.bindpw ? ldap_conf.bindpw : "";
+ bv.bv_len = strlen(bv.bv_val);
+
+ ret = ldap_sasl_bind_s(ld, ldap_conf.binddn, LDAP_SASL_SIMPLE, &bv,
+ NULL, NULL, NULL);
+ if (ret != LDAP_SUCCESS) {
+ sudo_warnx("ldap_sasl_bind_s(): %s", ldap_err2string(ret));
+ goto done;
+ }
+ DPRINTF1("ldap_sasl_bind_s() ok");
+ }
+#else
+ {
+ ret = ldap_simple_bind_s(ld, ldap_conf.binddn, ldap_conf.bindpw);
+ if (ret != LDAP_SUCCESS) {
+ sudo_warnx("ldap_simple_bind_s(): %s", ldap_err2string(ret));
+ goto done;
+ }
+ DPRINTF1("ldap_simple_bind_s() ok");
+ }
+#endif
+done:
+ debug_return_int(ret);
+}
+
+/*
+ * Shut down the LDAP connection.
+ */
+static int
+sudo_ldap_close(struct sudo_nss *nss)
+{
+ struct sudo_ldap_handle *handle = nss->handle;
+ debug_decl(sudo_ldap_close, SUDOERS_DEBUG_LDAP)
+
+ if (handle != NULL) {
+ /* Unbind and close the LDAP connection. */
+ if (handle->ld != NULL) {
+ ldap_unbind_ext_s(handle->ld, NULL, NULL);
+ handle->ld = NULL;
+ }
+
+ /* Free the handle container. */
+ if (handle->pw != NULL)
+ sudo_pw_delref(handle->pw);
+ free_parse_tree(&handle->parse_tree);
+ free(handle);
+ nss->handle = NULL;
+ }
+ debug_return_int(0);
+}
+
+/*
+ * Open a connection to the LDAP server.
+ * Returns 0 on success and non-zero on failure.
+ */
+static int
+sudo_ldap_open(struct sudo_nss *nss)
+{
+ LDAP *ld;
+ int rc = -1;
+ bool ldapnoinit = false;
+ struct sudo_ldap_handle *handle;
+ debug_decl(sudo_ldap_open, SUDOERS_DEBUG_LDAP)
+
+ if (nss->handle != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "%s: called with non-NULL handle %p", __func__, nss->handle);
+ sudo_ldap_close(nss);
+ }
+
+ if (!sudo_ldap_read_config())
+ goto done;
+
+ /* Prevent reading of user ldaprc and system defaults. */
+ if (sudo_getenv("LDAPNOINIT") == NULL) {
+ if (sudo_setenv("LDAPNOINIT", "1", true) == 0)
+ ldapnoinit = true;
+ }
+
+ /* Set global LDAP options */
+ if (sudo_ldap_set_options_global() != LDAP_SUCCESS)
+ goto done;
+
+ /* Connect to LDAP server */
+#ifdef HAVE_LDAP_INITIALIZE
+ if (!STAILQ_EMPTY(&ldap_conf.uri)) {
+ char *buf = sudo_ldap_join_uri(&ldap_conf.uri);
+ if (buf == NULL)
+ goto done;
+ DPRINTF2("ldap_initialize(ld, %s)", buf);
+ rc = ldap_initialize(&ld, buf);
+ free(buf);
+ } else
+#endif
+ rc = sudo_ldap_init(&ld, ldap_conf.host, ldap_conf.port);
+ if (rc != LDAP_SUCCESS) {
+ sudo_warnx(U_("unable to initialize LDAP: %s"), ldap_err2string(rc));
+ goto done;
+ }
+
+ /* Set LDAP per-connection options */
+ rc = sudo_ldap_set_options_conn(ld);
+ if (rc != LDAP_SUCCESS)
+ goto done;
+
+ if (ldapnoinit)
+ (void) sudo_unsetenv("LDAPNOINIT");
+
+ if (ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS) {
+#if defined(HAVE_LDAP_START_TLS_S)
+ rc = ldap_start_tls_s(ld, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ sudo_warnx("ldap_start_tls_s(): %s", ldap_err2string(rc));
+ goto done;
+ }
+ DPRINTF1("ldap_start_tls_s() ok");
+#elif defined(HAVE_LDAP_SSL_CLIENT_INIT) && defined(HAVE_LDAP_START_TLS_S_NP)
+ int sslrc;
+ rc = ldap_ssl_client_init(ldap_conf.tls_keyfile, ldap_conf.tls_keypw,
+ 0, &sslrc);
+ if (rc != LDAP_SUCCESS) {
+ sudo_warnx("ldap_ssl_client_init(): %s (SSL reason code %d)",
+ ldap_err2string(rc), sslrc);
+ goto done;
+ }
+ rc = ldap_start_tls_s_np(ld, NULL);
+ if (rc != LDAP_SUCCESS) {
+ sudo_warnx("ldap_start_tls_s_np(): %s", ldap_err2string(rc));
+ goto done;
+ }
+ DPRINTF1("ldap_start_tls_s_np() ok");
+#else
+ sudo_warnx(U_("start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"));
+#endif /* !HAVE_LDAP_START_TLS_S && !HAVE_LDAP_START_TLS_S_NP */
+ }
+
+ /* Actually connect */
+ rc = sudo_ldap_bind_s(ld);
+ if (rc != LDAP_SUCCESS)
+ goto done;
+
+ /* Create a handle container. */
+ handle = calloc(1, sizeof(struct sudo_ldap_handle));
+ if (handle == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ rc = -1;
+ goto done;
+ }
+ handle->ld = ld;
+ /* handle->pw = NULL; */
+ init_parse_tree(&handle->parse_tree);
+ nss->handle = handle;
+
+done:
+ debug_return_int(rc == LDAP_SUCCESS ? 0 : -1);
+}
+
+static int
+sudo_ldap_getdefs(struct sudo_nss *nss)
+{
+ struct sudo_ldap_handle *handle = nss->handle;
+ struct timeval tv, *tvp = NULL;
+ struct ldap_config_str *base;
+ LDAPMessage *entry, *result = NULL;
+ char *filt = NULL;
+ int rc, ret = -1;
+ static bool cached;
+ debug_decl(sudo_ldap_getdefs, SUDOERS_DEBUG_LDAP)
+
+ if (handle == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "%s: called with NULL handle", __func__);
+ debug_return_int(-1);
+ }
+
+ /* Use cached result if present. */
+ if (cached)
+ debug_return_int(0);
+
+ filt = sudo_ldap_build_default_filter();
+ if (filt == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+ DPRINTF1("Looking for cn=defaults: %s", filt);
+
+ STAILQ_FOREACH(base, &ldap_conf.base, entries) {
+ LDAP *ld = handle->ld;
+
+ if (ldap_conf.timeout > 0) {
+ tv.tv_sec = ldap_conf.timeout;
+ tv.tv_usec = 0;
+ tvp = &tv;
+ }
+ ldap_msgfree(result);
+ result = NULL;
+ rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE,
+ filt, NULL, 0, NULL, NULL, tvp, 0, &result);
+ if (rc == LDAP_SUCCESS && (entry = ldap_first_entry(ld, result))) {
+ DPRINTF1("found:%s", ldap_get_dn(ld, entry));
+ if (!sudo_ldap_parse_options(ld, entry, &handle->parse_tree.defaults))
+ goto done;
+ } else {
+ DPRINTF1("no default options found in %s", base->val);
+ }
+ }
+ cached = true;
+ ret = 0;
+
+done:
+ ldap_msgfree(result);
+ free(filt);
+
+ debug_return_int(ret);
+}
+
+/*
+ * Comparison function for ldap_entry_wrapper structures, ascending order.
+ * This should match role_order_cmp() in parse_ldif.c.
+ */
+static int
+ldap_entry_compare(const void *a, const void *b)
+{
+ const struct ldap_entry_wrapper *aw = a;
+ const struct ldap_entry_wrapper *bw = b;
+ debug_decl(ldap_entry_compare, SUDOERS_DEBUG_LDAP)
+
+ debug_return_int(aw->order < bw->order ? -1 :
+ (aw->order > bw->order ? 1 : 0));
+}
+
+/*
+ * Return the last entry in the list of searches, usually the
+ * one currently being used to add entries.
+ */
+static struct ldap_search_result *
+sudo_ldap_result_last_search(struct ldap_result *lres)
+{
+ debug_decl(sudo_ldap_result_last_search, SUDOERS_DEBUG_LDAP)
+
+ debug_return_ptr(STAILQ_LAST(&lres->searches, ldap_search_result, entries));
+}
+
+/*
+ * Add an entry to the result structure.
+ */
+static struct ldap_entry_wrapper *
+sudo_ldap_result_add_entry(struct ldap_result *lres, LDAPMessage *entry)
+{
+ struct ldap_search_result *last;
+ struct berval **bv;
+ double order = 0.0;
+ char *ep;
+ int rc;
+ debug_decl(sudo_ldap_result_add_entry, SUDOERS_DEBUG_LDAP)
+
+ /* Determine whether the entry has the sudoOrder attribute. */
+ last = sudo_ldap_result_last_search(lres);
+ if (last != NULL) {
+ bv = sudo_ldap_get_values_len(last->ldap, entry, "sudoOrder", &rc);
+ if (rc == LDAP_NO_MEMORY) {
+ /* XXX - return error */
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ } else {
+ if (ldap_count_values_len(bv) > 0) {
+ /* Get the value of this attribute, 0 if not present. */
+ DPRINTF2("order attribute raw: %s", (*bv)->bv_val);
+ order = strtod((*bv)->bv_val, &ep);
+ if (ep == (*bv)->bv_val || *ep != '\0') {
+ sudo_warnx(U_("invalid sudoOrder attribute: %s"),
+ (*bv)->bv_val);
+ order = 0.0;
+ }
+ DPRINTF2("order attribute: %f", order);
+ }
+ ldap_value_free_len(bv);
+ }
+ }
+
+ /*
+ * Enlarge the array of entry wrappers as needed, preallocating blocks
+ * of 100 entries to save on allocation time.
+ */
+ if (++lres->nentries > lres->allocated_entries) {
+ int allocated_entries = lres->allocated_entries + ALLOCATION_INCREMENT;
+ struct ldap_entry_wrapper *entries = reallocarray(lres->entries,
+ allocated_entries, sizeof(lres->entries[0]));
+ if (entries == NULL)
+ debug_return_ptr(NULL);
+ lres->allocated_entries = allocated_entries;
+ lres->entries = entries;
+ }
+
+ /* Fill in the new entry and return it. */
+ lres->entries[lres->nentries - 1].entry = entry;
+ lres->entries[lres->nentries - 1].order = order;
+
+ debug_return_ptr(&lres->entries[lres->nentries - 1]);
+}
+
+/*
+ * Perform the LDAP query for the user. The caller is responsible for
+ * freeing the result with sudo_ldap_result_free().
+ */
+static struct ldap_result *
+sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw)
+{
+ struct sudo_ldap_handle *handle = nss->handle;
+ struct ldap_config_str *base;
+ struct ldap_result *lres;
+ struct timeval tv, *tvp = NULL;
+ LDAPMessage *entry, *result;
+ LDAP *ld = handle->ld;
+ char *filt = NULL;
+ int pass, rc;
+ debug_decl(sudo_ldap_result_get, SUDOERS_DEBUG_LDAP)
+
+ /*
+ * Okay - time to search for anything that matches this user
+ * Lets limit it to only two queries of the LDAP server
+ *
+ * The first pass will look by the username, groups, and
+ * the keyword ALL. We will then inspect the results that
+ * came back from the query. We don't need to inspect the
+ * sudoUser in this pass since the LDAP server already scanned
+ * it for us.
+ *
+ * The second pass will return all the entries that contain non-
+ * Unix groups, including netgroups. Then we take the non-Unix
+ * groups returned and try to match them against the username.
+ *
+ * Since we have to sort the possible entries before we make a
+ * decision, we perform the queries and store all of the results in
+ * an ldap_result object. The results are then sorted by sudoOrder.
+ */
+ lres = sudo_ldap_result_alloc();
+ if (lres == NULL)
+ goto oom;
+ for (pass = 0; pass < 2; pass++) {
+ filt = pass ? sudo_ldap_build_pass2() : sudo_ldap_build_pass1(ld, pw);
+ if (filt != NULL) {
+ DPRINTF1("ldap search '%s'", filt);
+ STAILQ_FOREACH(base, &ldap_conf.base, entries) {
+ DPRINTF1("searching from base '%s'",
+ base->val);
+ if (ldap_conf.timeout > 0) {
+ tv.tv_sec = ldap_conf.timeout;
+ tv.tv_usec = 0;
+ tvp = &tv;
+ }
+ result = NULL;
+ rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, filt,
+ NULL, 0, NULL, NULL, tvp, 0, &result);
+ if (rc != LDAP_SUCCESS) {
+ DPRINTF1("ldap search pass %d failed: %s", pass + 1,
+ ldap_err2string(rc));
+ continue;
+ }
+
+ /* Add the search result to list of search results. */
+ DPRINTF1("adding search result");
+ if (sudo_ldap_result_add_search(lres, ld, result) == NULL)
+ goto oom;
+ LDAP_FOREACH(entry, ld, result) {
+ if (pass != 0) {
+ /* Check non-unix group in 2nd pass. */
+ switch (sudo_ldap_check_non_unix_group(ld, entry, pw)) {
+ case -1:
+ goto oom;
+ case false:
+ continue;
+ default:
+ break;
+ }
+ }
+ if (sudo_ldap_result_add_entry(lres, entry) == NULL)
+ goto oom;
+ }
+ DPRINTF1("result now has %d entries", lres->nentries);
+ }
+ free(filt);
+ filt = NULL;
+ } else if (errno != ENOENT) {
+ /* Out of memory? */
+ goto oom;
+ }
+ }
+
+ /* Sort the entries by the sudoOrder attribute. */
+ if (lres->nentries != 0) {
+ DPRINTF1("sorting remaining %d entries", lres->nentries);
+ qsort(lres->entries, lres->nentries, sizeof(lres->entries[0]),
+ ldap_entry_compare);
+ }
+
+ debug_return_ptr(lres);
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ free(filt);
+ sudo_ldap_result_free(lres);
+ debug_return_ptr(NULL);
+}
+
+/*
+ * Perform LDAP query for user and host and convert to sudoers
+ * parse tree.
+ */
+static int
+sudo_ldap_query(struct sudo_nss *nss, struct passwd *pw)
+{
+ struct sudo_ldap_handle *handle = nss->handle;
+ struct ldap_result *lres = NULL;
+ int ret = -1;
+ debug_decl(sudo_ldap_query, SUDOERS_DEBUG_LDAP)
+
+ if (handle == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "%s: called with NULL handle", __func__);
+ debug_return_int(-1);
+ }
+
+ /* Use cached result if it matches pw. */
+ if (handle->pw != NULL) {
+ if (pw == handle->pw) {
+ ret = 0;
+ goto done;
+ }
+ sudo_pw_delref(handle->pw);
+ handle->pw = NULL;
+ }
+
+ /* Free old userspecs, if any. */
+ free_userspecs(&handle->parse_tree.userspecs);
+
+ DPRINTF1("%s: ldap search user %s, host %s", __func__, pw->pw_name,
+ user_runhost);
+ if ((lres = sudo_ldap_result_get(nss, pw)) == NULL)
+ goto done;
+
+ /* Convert to sudoers parse tree. */
+ if (!ldap_to_sudoers(handle->ld, lres, &handle->parse_tree.userspecs))
+ goto done;
+
+ /* Stash a ref to the passwd struct in the handle. */
+ sudo_pw_addref(pw);
+ handle->pw = pw;
+
+ ret = 0;
+
+done:
+ /* Cleanup. */
+ sudo_ldap_result_free(lres);
+ if (ret == -1)
+ free_userspecs(&handle->parse_tree.userspecs);
+ debug_return_int(ret);
+}
+
+/*
+ * Return the initialized (but empty) sudoers parse tree.
+ * The contents will be populated by the getdefs() and query() functions.
+ */
+static struct sudoers_parse_tree *
+sudo_ldap_parse(struct sudo_nss *nss)
+{
+ struct sudo_ldap_handle *handle = nss->handle;
+ debug_decl(sudo_ldap_parse, SUDOERS_DEBUG_LDAP)
+
+ if (handle == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "%s: called with NULL handle", __func__);
+ debug_return_ptr(NULL);
+ }
+
+ debug_return_ptr(&handle->parse_tree);
+}
+
+#if 0
+/*
+ * Create an ldap_result from an LDAP search result.
+ *
+ * This function is currently not used anywhere, it is left here as
+ * an example of how to use the cached searches.
+ */
+static struct ldap_result *
+sudo_ldap_result_from_search(LDAP *ldap, LDAPMessage *searchresult)
+{
+ struct ldap_search_result *last;
+ struct ldap_result *result;
+ LDAPMessage *entry;
+
+ /*
+ * An ldap_result is built from several search results, which are
+ * organized in a list. The head of the list is maintained in the
+ * ldap_result structure, together with the wrappers that point
+ * to individual entries, this has to be initialized first.
+ */
+ result = sudo_ldap_result_alloc();
+ if (result == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_ptr(NULL);
+ }
+
+ /*
+ * Build a new list node for the search result, this creates the
+ * list node.
+ */
+ last = sudo_ldap_result_add_search(result, ldap, searchresult);
+
+ /*
+ * Now add each entry in the search result to the array of of entries
+ * in the ldap_result object.
+ */
+ LDAP_FOREACH(entry, last->ldap, last->searchresult) {
+ if (sudo_ldap_result_add_entry(result, entry) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sudo_ldap_result_free(result);
+ result = NULL;
+ break;
+ }
+ }
+ DPRINTF1("sudo_ldap_result_from_search: %d entries found",
+ result ? result->nentries : -1);
+ return result;
+}
+#endif
+
+/* sudo_nss implementation */
+struct sudo_nss sudo_nss_ldap = {
+ { NULL, NULL },
+ sudo_ldap_open,
+ sudo_ldap_close,
+ sudo_ldap_parse,
+ sudo_ldap_query,
+ sudo_ldap_getdefs
+};
diff --git a/plugins/sudoers/ldap_conf.c b/plugins/sudoers/ldap_conf.c
new file mode 100644
index 0000000..06591d4
--- /dev/null
+++ b/plugins/sudoers/ldap_conf.c
@@ -0,0 +1,934 @@
+/*
+ * Copyright (c) 2003-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * This code is derived from software contributed by Aaron Spangler.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <time.h>
+#include <ctype.h>
+#include <fcntl.h>
+#ifdef HAVE_LBER_H
+# include <lber.h>
+#endif
+#include <ldap.h>
+#if defined(HAVE_LDAP_SSL_H)
+# include <ldap_ssl.h>
+#elif defined(HAVE_MPS_LDAP_SSL_H)
+# include <mps/ldap_ssl.h>
+#endif
+
+#include "sudoers.h"
+#include "sudo_lbuf.h"
+#include "sudo_ldap.h"
+#include "sudo_ldap_conf.h"
+
+/* Older Netscape LDAP SDKs don't prototype ldapssl_set_strength() */
+#if defined(HAVE_LDAPSSL_SET_STRENGTH) && !defined(HAVE_LDAP_SSL_H) && !defined(HAVE_MPS_LDAP_SSL_H)
+extern int ldapssl_set_strength(LDAP *ldap, int strength);
+#endif
+
+#if !defined(LDAP_OPT_NETWORK_TIMEOUT) && defined(LDAP_OPT_CONNECT_TIMEOUT)
+# define LDAP_OPT_NETWORK_TIMEOUT LDAP_OPT_CONNECT_TIMEOUT
+#endif
+
+#ifndef LDAP_OPT_SUCCESS
+# define LDAP_OPT_SUCCESS LDAP_SUCCESS
+#endif
+
+#ifndef LDAPS_PORT
+# define LDAPS_PORT 636
+#endif
+
+/* Default search filter. */
+#define DEFAULT_SEARCH_FILTER "(objectClass=sudoRole)"
+
+/* Default netgroup search filter. */
+#define DEFAULT_NETGROUP_SEARCH_FILTER "(objectClass=nisNetgroup)"
+
+/* LDAP configuration structure */
+struct ldap_config ldap_conf;
+
+static struct ldap_config_table ldap_conf_global[] = {
+ { "sudoers_debug", CONF_INT, -1, &ldap_conf.debug },
+ { "host", CONF_STR, -1, &ldap_conf.host },
+ { "port", CONF_INT, -1, &ldap_conf.port },
+ { "ssl", CONF_STR, -1, &ldap_conf.ssl },
+ { "sslpath", CONF_STR, -1, &ldap_conf.tls_certfile },
+ { "uri", CONF_LIST_STR, -1, &ldap_conf.uri },
+#ifdef LDAP_OPT_DEBUG_LEVEL
+ { "debug", CONF_INT, LDAP_OPT_DEBUG_LEVEL, &ldap_conf.ldap_debug },
+#endif
+#ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
+ { "tls_checkpeer", CONF_BOOL, LDAP_OPT_X_TLS_REQUIRE_CERT,
+ &ldap_conf.tls_checkpeer },
+ { "tls_reqcert", CONF_REQCERT_VAL, LDAP_OPT_X_TLS_REQUIRE_CERT,
+ &ldap_conf.tls_reqcert },
+#else
+ { "tls_checkpeer", CONF_BOOL, -1, &ldap_conf.tls_checkpeer },
+#endif
+#ifdef LDAP_OPT_X_TLS_CACERTFILE
+ { "tls_cacertfile", CONF_STR, LDAP_OPT_X_TLS_CACERTFILE,
+ &ldap_conf.tls_cacertfile },
+ { "tls_cacert", CONF_STR, LDAP_OPT_X_TLS_CACERTFILE,
+ &ldap_conf.tls_cacertfile },
+#endif
+#ifdef LDAP_OPT_X_TLS_CACERTDIR
+ { "tls_cacertdir", CONF_STR, LDAP_OPT_X_TLS_CACERTDIR,
+ &ldap_conf.tls_cacertdir },
+#endif
+#ifdef LDAP_OPT_X_TLS_RANDOM_FILE
+ { "tls_randfile", CONF_STR, LDAP_OPT_X_TLS_RANDOM_FILE,
+ &ldap_conf.tls_random_file },
+#endif
+#ifdef LDAP_OPT_X_TLS_CIPHER_SUITE
+ { "tls_ciphers", CONF_STR, LDAP_OPT_X_TLS_CIPHER_SUITE,
+ &ldap_conf.tls_cipher_suite },
+#elif defined(LDAP_OPT_SSL_CIPHER)
+ { "tls_ciphers", CONF_STR, LDAP_OPT_SSL_CIPHER,
+ &ldap_conf.tls_cipher_suite },
+#endif
+#ifdef LDAP_OPT_X_TLS_CERTFILE
+ { "tls_cert", CONF_STR, LDAP_OPT_X_TLS_CERTFILE,
+ &ldap_conf.tls_certfile },
+#else
+ { "tls_cert", CONF_STR, -1, &ldap_conf.tls_certfile },
+#endif
+#ifdef LDAP_OPT_X_TLS_KEYFILE
+ { "tls_key", CONF_STR, LDAP_OPT_X_TLS_KEYFILE,
+ &ldap_conf.tls_keyfile },
+#else
+ { "tls_key", CONF_STR, -1, &ldap_conf.tls_keyfile },
+#endif
+#ifdef HAVE_LDAP_SSL_CLIENT_INIT
+ { "tls_keypw", CONF_STR, -1, &ldap_conf.tls_keypw },
+#endif
+ { "binddn", CONF_STR, -1, &ldap_conf.binddn },
+ { "bindpw", CONF_STR, -1, &ldap_conf.bindpw },
+ { "rootbinddn", CONF_STR, -1, &ldap_conf.rootbinddn },
+ { "sudoers_base", CONF_LIST_STR, -1, &ldap_conf.base },
+ { "sudoers_timed", CONF_BOOL, -1, &ldap_conf.timed },
+ { "sudoers_search_filter", CONF_STR, -1, &ldap_conf.search_filter },
+ { "netgroup_base", CONF_LIST_STR, -1, &ldap_conf.netgroup_base },
+ { "netgroup_search_filter", CONF_STR, -1, &ldap_conf.netgroup_search_filter },
+#ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S
+ { "use_sasl", CONF_BOOL, -1, &ldap_conf.use_sasl },
+ { "sasl_mech", CONF_STR, -1, &ldap_conf.sasl_mech },
+ { "sasl_auth_id", CONF_STR, -1, &ldap_conf.sasl_auth_id },
+ { "rootuse_sasl", CONF_BOOL, -1, &ldap_conf.rootuse_sasl },
+ { "rootsasl_auth_id", CONF_STR, -1, &ldap_conf.rootsasl_auth_id },
+ { "krb5_ccname", CONF_STR, -1, &ldap_conf.krb5_ccname },
+#endif /* HAVE_LDAP_SASL_INTERACTIVE_BIND_S */
+ { NULL }
+};
+
+static struct ldap_config_table ldap_conf_conn[] = {
+#ifdef LDAP_OPT_PROTOCOL_VERSION
+ { "ldap_version", CONF_INT, LDAP_OPT_PROTOCOL_VERSION,
+ &ldap_conf.version },
+#endif
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+ { "bind_timelimit", CONF_INT, -1 /* needs timeval, set manually */,
+ &ldap_conf.bind_timelimit },
+ { "network_timeout", CONF_INT, -1 /* needs timeval, set manually */,
+ &ldap_conf.bind_timelimit },
+#elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
+ { "bind_timelimit", CONF_INT, LDAP_X_OPT_CONNECT_TIMEOUT,
+ &ldap_conf.bind_timelimit },
+ { "network_timeout", CONF_INT, LDAP_X_OPT_CONNECT_TIMEOUT,
+ &ldap_conf.bind_timelimit },
+#endif
+ { "timelimit", CONF_INT, LDAP_OPT_TIMELIMIT, &ldap_conf.timelimit },
+#ifdef LDAP_OPT_TIMEOUT
+ { "timeout", CONF_INT, -1 /* needs timeval, set manually */,
+ &ldap_conf.timeout },
+#endif
+#ifdef LDAP_OPT_DEREF
+ { "deref", CONF_DEREF_VAL, LDAP_OPT_DEREF, &ldap_conf.deref },
+#endif
+#ifdef LDAP_OPT_X_SASL_SECPROPS
+ { "sasl_secprops", CONF_STR, LDAP_OPT_X_SASL_SECPROPS,
+ &ldap_conf.sasl_secprops },
+#endif
+ { NULL }
+};
+
+#ifdef HAVE_LDAP_CREATE
+/*
+ * Rebuild the hosts list and include a specific port for each host.
+ * ldap_create() does not take a default port parameter so we must
+ * append one if we want something other than LDAP_PORT.
+ */
+static bool
+sudo_ldap_conf_add_ports(void)
+{
+ char *host, *last, *port, defport[13];
+ char hostbuf[LINE_MAX * 2];
+ int len;
+ debug_decl(sudo_ldap_conf_add_ports, SUDOERS_DEBUG_LDAP)
+
+ hostbuf[0] = '\0';
+ len = snprintf(defport, sizeof(defport), ":%d", ldap_conf.port);
+ if (len <= 0 || (size_t)len >= sizeof(defport)) {
+ sudo_warnx(U_("sudo_ldap_conf_add_ports: port too large"));
+ debug_return_bool(false);
+ }
+
+ for ((host = strtok_r(ldap_conf.host, " \t", &last)); host; (host = strtok_r(NULL, " \t", &last))) {
+ if (hostbuf[0] != '\0')
+ CHECK_STRLCAT(hostbuf, " ", sizeof(hostbuf));
+ CHECK_STRLCAT(hostbuf, host, sizeof(hostbuf));
+
+ /* Append port if there is not one already. */
+ if ((port = strrchr(host, ':')) == NULL ||
+ !isdigit((unsigned char)port[1])) {
+ CHECK_STRLCAT(hostbuf, defport, sizeof(hostbuf));
+ }
+ }
+
+ free(ldap_conf.host);
+ if ((ldap_conf.host = strdup(hostbuf)) == NULL)
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_bool(ldap_conf.host != NULL);
+
+overflow:
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ debug_return_bool(false);
+}
+#endif
+
+#ifndef HAVE_LDAP_INITIALIZE
+/*
+ * For each uri, convert to host:port pairs. For ldaps:// enable SSL
+ * Accepts: uris of the form ldap:/// or ldap://hostname:portnum/
+ * where the trailing slash is optional.
+ * Returns LDAP_SUCCESS on success, else non-zero.
+ */
+static int
+sudo_ldap_parse_uri(const struct ldap_config_str_list *uri_list)
+{
+ const struct ldap_config_str *entry;
+ char *buf, hostbuf[LINE_MAX];
+ int nldap = 0, nldaps = 0;
+ int ret = -1;
+ debug_decl(sudo_ldap_parse_uri, SUDOERS_DEBUG_LDAP)
+
+ hostbuf[0] = '\0';
+ STAILQ_FOREACH(entry, uri_list, entries) {
+ char *cp, *host, *last, *port, *uri;
+
+ buf = strdup(entry->val);
+ if (buf == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ for ((uri = strtok_r(buf, " \t", &last)); uri != NULL; (uri = strtok_r(NULL, " \t", &last))) {
+ if (strncasecmp(uri, "ldap://", 7) == 0) {
+ nldap++;
+ host = uri + 7;
+ } else if (strncasecmp(uri, "ldaps://", 8) == 0) {
+ nldaps++;
+ host = uri + 8;
+ } else {
+ sudo_warnx(U_("unsupported LDAP uri type: %s"), uri);
+ goto done;
+ }
+
+ /* trim optional trailing slash */
+ if ((cp = strrchr(host, '/')) != NULL && cp[1] == '\0') {
+ *cp = '\0';
+ }
+
+ if (hostbuf[0] != '\0')
+ CHECK_STRLCAT(hostbuf, " ", sizeof(hostbuf));
+
+ if (*host == '\0')
+ host = "localhost"; /* no host specified, use localhost */
+
+ CHECK_STRLCAT(hostbuf, host, sizeof(hostbuf));
+
+ /* If using SSL and no port specified, add port 636 */
+ if (nldaps) {
+ if ((port = strrchr(host, ':')) == NULL ||
+ !isdigit((unsigned char)port[1]))
+ CHECK_STRLCAT(hostbuf, ":636", sizeof(hostbuf));
+ }
+ }
+
+ if (nldaps != 0) {
+ if (nldap != 0) {
+ sudo_warnx(U_("unable to mix ldap and ldaps URIs"));
+ goto done;
+ }
+ if (ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS)
+ sudo_warnx(U_("starttls not supported when using ldaps"));
+ ldap_conf.ssl_mode = SUDO_LDAP_SSL;
+ }
+ free(buf);
+ }
+ buf = NULL;
+
+ /* Store parsed URI(s) in host for ldap_create() or ldap_init(). */
+ free(ldap_conf.host);
+ if ((ldap_conf.host = strdup(hostbuf)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+
+ ret = LDAP_SUCCESS;
+
+done:
+ free(buf);
+ debug_return_int(ret);
+
+overflow:
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ free(buf);
+ debug_return_int(-1);
+}
+#endif /* HAVE_LDAP_INITIALIZE */
+
+/*
+ * Decode a secret if it is base64 encoded, else return NULL.
+ */
+static char *
+sudo_ldap_decode_secret(const char *secret)
+{
+ unsigned char *result = NULL;
+ size_t len, reslen;
+ debug_decl(sudo_ldap_decode_secret, SUDOERS_DEBUG_LDAP)
+
+ if (strncasecmp(secret, "base64:", sizeof("base64:") - 1) == 0) {
+ /*
+ * Decode a base64 secret. The decoded length is 3/4 the encoded
+ * length but padding may be missing so round up to a multiple of 4.
+ */
+ secret += sizeof("base64:") - 1;
+ reslen = ((strlen(secret) + 3) / 4 * 3);
+ result = malloc(reslen + 1);
+ if (result == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ } else {
+ len = base64_decode(secret, result, reslen);
+ if (len == (size_t)-1) {
+ free(result);
+ result = NULL;
+ } else {
+ result[len] = '\0';
+ }
+ }
+ }
+ debug_return_str((char *)result);
+}
+
+static void
+sudo_ldap_read_secret(const char *path)
+{
+ FILE *fp;
+ char *line = NULL;
+ size_t linesize = 0;
+ ssize_t len;
+ debug_decl(sudo_ldap_read_secret, SUDOERS_DEBUG_LDAP)
+
+ if ((fp = fopen(path_ldap_secret, "r")) != NULL) {
+ len = getline(&line, &linesize, fp);
+ if (len != -1) {
+ /* trim newline */
+ while (len > 0 && line[len - 1] == '\n')
+ line[--len] = '\0';
+ /* copy to bindpw and binddn */
+ free(ldap_conf.bindpw);
+ ldap_conf.bindpw = sudo_ldap_decode_secret(line);
+ if (ldap_conf.bindpw == NULL) {
+ /* not base64 encoded, use directly */
+ ldap_conf.bindpw = line;
+ line = NULL;
+ }
+ free(ldap_conf.binddn);
+ ldap_conf.binddn = ldap_conf.rootbinddn;
+ ldap_conf.rootbinddn = NULL;
+ }
+ fclose(fp);
+ free(line);
+ }
+ debug_return;
+}
+
+/*
+ * Look up keyword in config tables.
+ * Returns true if found, else false.
+ */
+static bool
+sudo_ldap_parse_keyword(const char *keyword, const char *value,
+ struct ldap_config_table *table)
+{
+ struct ldap_config_table *cur;
+ const char *errstr;
+ debug_decl(sudo_ldap_parse_keyword, SUDOERS_DEBUG_LDAP)
+
+ /* Look up keyword in config tables */
+ for (cur = table; cur->conf_str != NULL; cur++) {
+ if (strcasecmp(keyword, cur->conf_str) == 0) {
+ switch (cur->type) {
+ case CONF_DEREF_VAL:
+ if (strcasecmp(value, "searching") == 0)
+ *(int *)(cur->valp) = LDAP_DEREF_SEARCHING;
+ else if (strcasecmp(value, "finding") == 0)
+ *(int *)(cur->valp) = LDAP_DEREF_FINDING;
+ else if (strcasecmp(value, "always") == 0)
+ *(int *)(cur->valp) = LDAP_DEREF_ALWAYS;
+ else
+ *(int *)(cur->valp) = LDAP_DEREF_NEVER;
+ break;
+ case CONF_REQCERT_VAL:
+#ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
+ if (strcasecmp(value, "never") == 0)
+ *(int *)(cur->valp) = LDAP_OPT_X_TLS_NEVER;
+ else if (strcasecmp(value, "allow") == 0)
+ *(int *)(cur->valp) = LDAP_OPT_X_TLS_ALLOW;
+ else if (strcasecmp(value, "try") == 0)
+ *(int *)(cur->valp) = LDAP_OPT_X_TLS_TRY;
+ else if (strcasecmp(value, "hard") == 0)
+ *(int *)(cur->valp) = LDAP_OPT_X_TLS_HARD;
+ else if (strcasecmp(value, "demand") == 0)
+ *(int *)(cur->valp) = LDAP_OPT_X_TLS_DEMAND;
+#endif /* LDAP_OPT_X_TLS_REQUIRE_CERT */
+ break;
+ case CONF_BOOL:
+ *(int *)(cur->valp) = sudo_strtobool(value) == true;
+ break;
+ case CONF_INT:
+ *(int *)(cur->valp) = strtonum(value, INT_MIN, INT_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("%s: %s: %s: %s"),
+ path_ldap_conf, keyword, value, U_(errstr));
+ }
+ break;
+ case CONF_STR:
+ {
+ char *cp = NULL;
+
+ free(*(char **)(cur->valp));
+ if (*value && (cp = strdup(value)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ *(char **)(cur->valp) = cp;
+ break;
+ }
+ case CONF_LIST_STR:
+ {
+ struct ldap_config_str_list *head;
+ struct ldap_config_str *str;
+ size_t len = strlen(value);
+
+ if (len > 0) {
+ head = (struct ldap_config_str_list *)cur->valp;
+ if ((str = malloc(sizeof(*str) + len)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ memcpy(str->val, value, len + 1);
+ STAILQ_INSERT_TAIL(head, str, entries);
+ }
+ }
+ break;
+ }
+ debug_return_bool(true);
+ }
+ }
+ debug_return_bool(false);
+}
+
+#ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S
+const char *
+sudo_krb5_ccname_path(const char *old_ccname)
+{
+ const char *ccname = old_ccname;
+ debug_decl(sudo_krb5_ccname_path, SUDOERS_DEBUG_LDAP)
+
+ /* Strip off leading FILE: or WRFILE: prefix. */
+ switch (ccname[0]) {
+ case 'F':
+ case 'f':
+ if (strncasecmp(ccname, "FILE:", 5) == 0)
+ ccname += 5;
+ break;
+ case 'W':
+ case 'w':
+ if (strncasecmp(ccname, "WRFILE:", 7) == 0)
+ ccname += 7;
+ break;
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "ccache %s -> %s", old_ccname, ccname);
+
+ /* Credential cache must be a fully-qualified path name. */
+ debug_return_const_str(*ccname == '/' ? ccname : NULL);
+}
+
+static bool
+sudo_check_krb5_ccname(const char *ccname)
+{
+ int fd = -1;
+ const char *ccname_path;
+ debug_decl(sudo_check_krb5_ccname, SUDOERS_DEBUG_LDAP)
+
+ /* Strip off prefix to get path name. */
+ ccname_path = sudo_krb5_ccname_path(ccname);
+ if (ccname_path == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
+ "unsupported krb5 credential cache path: %s", ccname);
+ debug_return_bool(false);
+ }
+ /* Make sure credential cache is fully-qualified and exists. */
+ fd = open(ccname_path, O_RDONLY|O_NONBLOCK, 0);
+ if (fd == -1) {
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
+ "unable to open krb5 credential cache: %s", ccname_path);
+ debug_return_bool(false);
+ }
+ close(fd);
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "using krb5 credential cache: %s", ccname_path);
+ debug_return_bool(true);
+}
+#endif /* HAVE_LDAP_SASL_INTERACTIVE_BIND_S */
+
+bool
+sudo_ldap_read_config(void)
+{
+ char *cp, *keyword, *value, *line = NULL;
+ struct ldap_config_str *conf_str;
+ size_t linesize = 0;
+ FILE *fp;
+ debug_decl(sudo_ldap_read_config, SUDOERS_DEBUG_LDAP)
+
+ /* defaults */
+ ldap_conf.version = 3;
+ ldap_conf.port = -1;
+ ldap_conf.tls_checkpeer = -1;
+ ldap_conf.tls_reqcert = -1;
+ ldap_conf.timelimit = -1;
+ ldap_conf.timeout = -1;
+ ldap_conf.bind_timelimit = -1;
+ ldap_conf.use_sasl = -1;
+ ldap_conf.rootuse_sasl = -1;
+ ldap_conf.deref = -1;
+ ldap_conf.search_filter = strdup(DEFAULT_SEARCH_FILTER);
+ ldap_conf.netgroup_search_filter = strdup(DEFAULT_NETGROUP_SEARCH_FILTER);
+ STAILQ_INIT(&ldap_conf.uri);
+ STAILQ_INIT(&ldap_conf.base);
+ STAILQ_INIT(&ldap_conf.netgroup_base);
+
+ if (ldap_conf.search_filter == NULL || ldap_conf.netgroup_search_filter == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+
+ if ((fp = fopen(path_ldap_conf, "r")) == NULL)
+ debug_return_bool(false);
+
+ while (sudo_parseln(&line, &linesize, NULL, fp, PARSELN_COMM_BOL|PARSELN_CONT_IGN) != -1) {
+ if (*line == '\0')
+ continue; /* skip empty line */
+
+ /* split into keyword and value */
+ keyword = cp = line;
+ while (*cp && !isblank((unsigned char) *cp))
+ cp++;
+ if (*cp)
+ *cp++ = '\0'; /* terminate keyword */
+
+ /* skip whitespace before value */
+ while (isblank((unsigned char) *cp))
+ cp++;
+ value = cp;
+
+ /* Look up keyword in config tables */
+ if (!sudo_ldap_parse_keyword(keyword, value, ldap_conf_global))
+ sudo_ldap_parse_keyword(keyword, value, ldap_conf_conn);
+ }
+ free(line);
+ fclose(fp);
+
+ if (!ldap_conf.host) {
+ ldap_conf.host = strdup("localhost");
+ if (ldap_conf.host == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ }
+
+ DPRINTF1("LDAP Config Summary");
+ DPRINTF1("===================");
+ if (!STAILQ_EMPTY(&ldap_conf.uri)) {
+ STAILQ_FOREACH(conf_str, &ldap_conf.uri, entries) {
+ DPRINTF1("uri %s", conf_str->val);
+ }
+ } else {
+ DPRINTF1("host %s",
+ ldap_conf.host ? ldap_conf.host : "(NONE)");
+ DPRINTF1("port %d", ldap_conf.port);
+ }
+ DPRINTF1("ldap_version %d", ldap_conf.version);
+
+ if (!STAILQ_EMPTY(&ldap_conf.base)) {
+ STAILQ_FOREACH(conf_str, &ldap_conf.base, entries) {
+ DPRINTF1("sudoers_base %s", conf_str->val);
+ }
+ } else {
+ DPRINTF1("sudoers_base %s", "(NONE: LDAP disabled)");
+ }
+ if (ldap_conf.search_filter) {
+ DPRINTF1("search_filter %s", ldap_conf.search_filter);
+ }
+ if (!STAILQ_EMPTY(&ldap_conf.netgroup_base)) {
+ STAILQ_FOREACH(conf_str, &ldap_conf.netgroup_base, entries) {
+ DPRINTF1("netgroup_base %s", conf_str->val);
+ }
+ } else {
+ DPRINTF1("netgroup_base %s", "(NONE: will use nsswitch)");
+ }
+ if (ldap_conf.netgroup_search_filter) {
+ DPRINTF1("netgroup_search_filter %s", ldap_conf.netgroup_search_filter);
+ }
+ DPRINTF1("binddn %s",
+ ldap_conf.binddn ? ldap_conf.binddn : "(anonymous)");
+ DPRINTF1("bindpw %s",
+ ldap_conf.bindpw ? ldap_conf.bindpw : "(anonymous)");
+ if (ldap_conf.bind_timelimit > 0) {
+ DPRINTF1("bind_timelimit %d", ldap_conf.bind_timelimit);
+ }
+ if (ldap_conf.timelimit > 0) {
+ DPRINTF1("timelimit %d", ldap_conf.timelimit);
+ }
+ if (ldap_conf.deref != -1) {
+ DPRINTF1("deref %d", ldap_conf.deref);
+ }
+ DPRINTF1("ssl %s", ldap_conf.ssl ? ldap_conf.ssl : "(no)");
+ if (ldap_conf.tls_checkpeer != -1) {
+ DPRINTF1("tls_checkpeer %s",
+ ldap_conf.tls_checkpeer ? "(yes)" : "(no)");
+ }
+#ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
+ if (ldap_conf.tls_reqcert != -1) {
+ DPRINTF1("tls_reqcert %s",
+ ldap_conf.tls_reqcert == LDAP_OPT_X_TLS_NEVER ? "hard" :
+ ldap_conf.tls_reqcert == LDAP_OPT_X_TLS_ALLOW ? "allow" :
+ ldap_conf.tls_reqcert == LDAP_OPT_X_TLS_TRY ? "try" :
+ ldap_conf.tls_reqcert == LDAP_OPT_X_TLS_HARD ? "hard" :
+ ldap_conf.tls_reqcert == LDAP_OPT_X_TLS_DEMAND ? "demand" :
+ "unknown");
+ }
+#endif /* LDAP_OPT_X_TLS_REQUIRE_CERT */
+ if (ldap_conf.tls_cacertfile != NULL) {
+ DPRINTF1("tls_cacertfile %s", ldap_conf.tls_cacertfile);
+ }
+ if (ldap_conf.tls_cacertdir != NULL) {
+ DPRINTF1("tls_cacertdir %s", ldap_conf.tls_cacertdir);
+ }
+ if (ldap_conf.tls_random_file != NULL) {
+ DPRINTF1("tls_random_file %s", ldap_conf.tls_random_file);
+ }
+ if (ldap_conf.tls_cipher_suite != NULL) {
+ DPRINTF1("tls_cipher_suite %s", ldap_conf.tls_cipher_suite);
+ }
+ if (ldap_conf.tls_certfile != NULL) {
+ DPRINTF1("tls_certfile %s", ldap_conf.tls_certfile);
+ }
+ if (ldap_conf.tls_keyfile != NULL) {
+ DPRINTF1("tls_keyfile %s", ldap_conf.tls_keyfile);
+ }
+#ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S
+ if (ldap_conf.use_sasl != -1) {
+ if (ldap_conf.sasl_mech == NULL) {
+ /* Default mechanism is GSSAPI. */
+ ldap_conf.sasl_mech = strdup("GSSAPI");
+ if (ldap_conf.sasl_mech == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ }
+ DPRINTF1("use_sasl %s", ldap_conf.use_sasl ? "yes" : "no");
+ DPRINTF1("sasl_mech %s", ldap_conf.sasl_mech);
+ DPRINTF1("sasl_auth_id %s",
+ ldap_conf.sasl_auth_id ? ldap_conf.sasl_auth_id : "(NONE)");
+ DPRINTF1("rootuse_sasl %d",
+ ldap_conf.rootuse_sasl);
+ DPRINTF1("rootsasl_auth_id %s",
+ ldap_conf.rootsasl_auth_id ? ldap_conf.rootsasl_auth_id : "(NONE)");
+ DPRINTF1("sasl_secprops %s",
+ ldap_conf.sasl_secprops ? ldap_conf.sasl_secprops : "(NONE)");
+ DPRINTF1("krb5_ccname %s",
+ ldap_conf.krb5_ccname ? ldap_conf.krb5_ccname : "(NONE)");
+ }
+#endif
+ DPRINTF1("===================");
+
+ if (STAILQ_EMPTY(&ldap_conf.base))
+ debug_return_bool(false); /* if no base is defined, ignore LDAP */
+
+ if (ldap_conf.bind_timelimit > 0)
+ ldap_conf.bind_timelimit *= 1000; /* convert to ms */
+
+ /*
+ * Interpret SSL option
+ */
+ if (ldap_conf.ssl != NULL) {
+ if (strcasecmp(ldap_conf.ssl, "start_tls") == 0)
+ ldap_conf.ssl_mode = SUDO_LDAP_STARTTLS;
+ else if (sudo_strtobool(ldap_conf.ssl) == true)
+ ldap_conf.ssl_mode = SUDO_LDAP_SSL;
+ }
+
+#if defined(HAVE_LDAPSSL_SET_STRENGTH) && !defined(LDAP_OPT_X_TLS_REQUIRE_CERT)
+ if (ldap_conf.tls_checkpeer != -1) {
+ ldapssl_set_strength(NULL,
+ ldap_conf.tls_checkpeer ? LDAPSSL_AUTH_CERT : LDAPSSL_AUTH_WEAK);
+ }
+#endif
+
+#ifndef HAVE_LDAP_INITIALIZE
+ /* Convert uri list to host list if no ldap_initialize(). */
+ if (!STAILQ_EMPTY(&ldap_conf.uri)) {
+ struct ldap_config_str *uri;
+
+ if (sudo_ldap_parse_uri(&ldap_conf.uri) != LDAP_SUCCESS)
+ debug_return_bool(false);
+ while ((uri = STAILQ_FIRST(&ldap_conf.uri)) != NULL) {
+ STAILQ_REMOVE_HEAD(&ldap_conf.uri, entries);
+ free(uri);
+ }
+ ldap_conf.port = LDAP_PORT;
+ }
+#endif
+
+ if (STAILQ_EMPTY(&ldap_conf.uri)) {
+ /* Use port 389 for plaintext LDAP and port 636 for SSL LDAP */
+ if (ldap_conf.port < 0)
+ ldap_conf.port =
+ ldap_conf.ssl_mode == SUDO_LDAP_SSL ? LDAPS_PORT : LDAP_PORT;
+
+#ifdef HAVE_LDAP_CREATE
+ /*
+ * Cannot specify port directly to ldap_create(), each host must
+ * include :port to override the default.
+ */
+ if (ldap_conf.port != LDAP_PORT) {
+ if (!sudo_ldap_conf_add_ports())
+ debug_return_bool(false);
+ }
+#endif
+ }
+
+ /* If search filter is not parenthesized, make it so. */
+ if (ldap_conf.search_filter && ldap_conf.search_filter[0] != '(') {
+ size_t len = strlen(ldap_conf.search_filter);
+ cp = ldap_conf.search_filter;
+ ldap_conf.search_filter = malloc(len + 3);
+ if (ldap_conf.search_filter == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ ldap_conf.search_filter[0] = '(';
+ memcpy(ldap_conf.search_filter + 1, cp, len);
+ ldap_conf.search_filter[len + 1] = ')';
+ ldap_conf.search_filter[len + 2] = '\0';
+ free(cp);
+ }
+
+
+ /* If rootbinddn set, read in /etc/ldap.secret if it exists. */
+ if (ldap_conf.rootbinddn) {
+ sudo_ldap_read_secret(path_ldap_secret);
+ } else if (ldap_conf.bindpw) {
+ cp = sudo_ldap_decode_secret(ldap_conf.bindpw);
+ if (cp != NULL) {
+ free(ldap_conf.bindpw);
+ ldap_conf.bindpw = cp;
+ }
+ }
+
+ if (ldap_conf.tls_keypw) {
+ cp = sudo_ldap_decode_secret(ldap_conf.tls_keypw);
+ if (cp != NULL) {
+ free(ldap_conf.tls_keypw);
+ ldap_conf.tls_keypw = cp;
+ }
+ }
+
+#ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S
+ /*
+ * Make sure we can open the file specified by krb5_ccname.
+ */
+ if (ldap_conf.krb5_ccname != NULL) {
+ if (!sudo_check_krb5_ccname(ldap_conf.krb5_ccname))
+ ldap_conf.krb5_ccname = NULL;
+ }
+#endif
+
+ debug_return_bool(true);
+}
+
+/*
+ * Set LDAP options from the specified options table
+ * Returns LDAP_SUCCESS on success, else non-zero.
+ */
+static int
+sudo_ldap_set_options_table(LDAP *ld, struct ldap_config_table *table)
+{
+ struct ldap_config_table *cur;
+ int ival, rc, errors = 0;
+ char *sval;
+ debug_decl(sudo_ldap_set_options_table, SUDOERS_DEBUG_LDAP)
+
+ for (cur = table; cur->conf_str != NULL; cur++) {
+ if (cur->opt_val == -1)
+ continue;
+
+ switch (cur->type) {
+ case CONF_BOOL:
+ case CONF_INT:
+ ival = *(int *)(cur->valp);
+ if (ival >= 0) {
+ DPRINTF1("ldap_set_option: %s -> %d", cur->conf_str, ival);
+ rc = ldap_set_option(ld, cur->opt_val, &ival);
+ if (rc != LDAP_OPT_SUCCESS) {
+ sudo_warnx("ldap_set_option: %s -> %d: %s",
+ cur->conf_str, ival, ldap_err2string(rc));
+ errors++;
+ }
+ }
+ break;
+ case CONF_STR:
+ sval = *(char **)(cur->valp);
+ if (sval != NULL) {
+ DPRINTF1("ldap_set_option: %s -> %s", cur->conf_str, sval);
+ rc = ldap_set_option(ld, cur->opt_val, sval);
+ if (rc != LDAP_OPT_SUCCESS) {
+ sudo_warnx("ldap_set_option: %s -> %s: %s",
+ cur->conf_str, sval, ldap_err2string(rc));
+ errors++;
+ }
+ }
+ break;
+ }
+ }
+ debug_return_int(errors ? -1 : LDAP_SUCCESS);
+}
+
+/*
+ * Set LDAP options based on the global config table.
+ * Returns LDAP_SUCCESS on success, else non-zero.
+ */
+int
+sudo_ldap_set_options_global(void)
+{
+ int ret;
+ debug_decl(sudo_ldap_set_options_global, SUDOERS_DEBUG_LDAP)
+
+ /* Set ber options */
+#ifdef LBER_OPT_DEBUG_LEVEL
+ if (ldap_conf.ldap_debug)
+ ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &ldap_conf.ldap_debug);
+#endif
+
+ /* Parse global LDAP options table. */
+ ret = sudo_ldap_set_options_table(NULL, ldap_conf_global);
+ debug_return_int(ret);
+}
+
+/*
+ * Set LDAP options based on the per-connection config table.
+ * Returns LDAP_SUCCESS on success, else non-zero.
+ */
+int
+sudo_ldap_set_options_conn(LDAP *ld)
+{
+ int rc;
+ debug_decl(sudo_ldap_set_options_conn, SUDOERS_DEBUG_LDAP)
+
+ /* Parse per-connection LDAP options table. */
+ rc = sudo_ldap_set_options_table(ld, ldap_conf_conn);
+ if (rc == -1)
+ debug_return_int(-1);
+
+#ifdef LDAP_OPT_TIMEOUT
+ /* Convert timeout to a timeval */
+ if (ldap_conf.timeout > 0) {
+ struct timeval tv;
+ tv.tv_sec = ldap_conf.timeout;
+ tv.tv_usec = 0;
+ DPRINTF1("ldap_set_option(LDAP_OPT_TIMEOUT, %d)", ldap_conf.timeout);
+ rc = ldap_set_option(ld, LDAP_OPT_TIMEOUT, &tv);
+ if (rc != LDAP_OPT_SUCCESS) {
+ sudo_warnx("ldap_set_option(TIMEOUT, %d): %s",
+ ldap_conf.timeout, ldap_err2string(rc));
+ }
+ }
+#endif
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+ /* Convert bind_timelimit to a timeval */
+ if (ldap_conf.bind_timelimit > 0) {
+ struct timeval tv;
+ tv.tv_sec = ldap_conf.bind_timelimit / 1000;
+ tv.tv_usec = 0;
+ DPRINTF1("ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT, %d)",
+ ldap_conf.bind_timelimit / 1000);
+ rc = ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tv);
+# if !defined(LDAP_OPT_CONNECT_TIMEOUT) || LDAP_VENDOR_VERSION != 510
+ /* Tivoli Directory Server 6.3 libs always return a (bogus) error. */
+ if (rc != LDAP_OPT_SUCCESS) {
+ sudo_warnx("ldap_set_option(NETWORK_TIMEOUT, %d): %s",
+ ldap_conf.bind_timelimit / 1000, ldap_err2string(rc));
+ }
+# endif
+ }
+#endif
+
+#if defined(LDAP_OPT_X_TLS) && !defined(HAVE_LDAPSSL_INIT)
+ if (ldap_conf.ssl_mode == SUDO_LDAP_SSL) {
+ int val = LDAP_OPT_X_TLS_HARD;
+ DPRINTF1("ldap_set_option(LDAP_OPT_X_TLS, LDAP_OPT_X_TLS_HARD)");
+ rc = ldap_set_option(ld, LDAP_OPT_X_TLS, &val);
+ if (rc != LDAP_SUCCESS) {
+ sudo_warnx("ldap_set_option(LDAP_OPT_X_TLS, LDAP_OPT_X_TLS_HARD): %s",
+ ldap_err2string(rc));
+ debug_return_int(-1);
+ }
+ }
+#endif
+ debug_return_int(LDAP_SUCCESS);
+}
diff --git a/plugins/sudoers/ldap_util.c b/plugins/sudoers/ldap_util.c
new file mode 100644
index 0000000..9b8f69e
--- /dev/null
+++ b/plugins/sudoers/ldap_util.c
@@ -0,0 +1,581 @@
+/*
+ * Copyright (c) 2013, 2016, 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * This code is derived from software contributed by Aaron Spangler.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <ctype.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "sudoers.h"
+#include "interfaces.h"
+#include "gram.h"
+#include "sudo_lbuf.h"
+#include "sudo_ldap.h"
+#include "sudo_digest.h"
+
+/*
+ * Returns true if the string pointed to by valp begins with an
+ * odd number of '!' characters. Intervening blanks are ignored.
+ * Stores the address of the string after '!' removal in valp.
+ */
+bool
+sudo_ldap_is_negated(char **valp)
+{
+ char *val = *valp;
+ bool ret = false;
+ debug_decl(sudo_ldap_is_negated, SUDOERS_DEBUG_LDAP)
+
+ while (*val == '!') {
+ ret = !ret;
+ do {
+ val++;
+ } while (isblank((unsigned char)*val));
+ }
+ *valp = val;
+ debug_return_bool(ret);
+}
+
+/*
+ * Parse an option string into a defaults structure.
+ * The members of def are pointers into optstr (which is modified).
+ */
+int
+sudo_ldap_parse_option(char *optstr, char **varp, char **valp)
+{
+ char *cp, *val = NULL;
+ char *var = optstr;
+ int op;
+ debug_decl(sudo_ldap_parse_option, SUDOERS_DEBUG_LDAP)
+
+ /* check for equals sign past first char */
+ cp = strchr(var, '=');
+ if (cp > var) {
+ val = cp + 1;
+ op = cp[-1]; /* peek for += or -= cases */
+ if (op == '+' || op == '-') {
+ /* case var+=val or var-=val */
+ cp--;
+ } else {
+ /* case var=val */
+ op = true;
+ }
+ /* Trim whitespace between var and operator. */
+ while (cp > var && isblank((unsigned char)cp[-1]))
+ cp--;
+ /* Truncate variable name. */
+ *cp = '\0';
+ /* Trim leading whitespace from val. */
+ while (isblank((unsigned char)*val))
+ val++;
+ /* Strip double quotes if present. */
+ if (*val == '"') {
+ char *ep = val + strlen(val);
+ if (ep != val && ep[-1] == '"') {
+ val++;
+ ep[-1] = '\0';
+ }
+ }
+ } else {
+ /* Boolean value, either true or false. */
+ op = sudo_ldap_is_negated(&var) ? false : true;
+ }
+ *varp = var;
+ *valp = val;
+
+ debug_return_int(op);
+}
+
+/*
+ * Convert an array of user/group names to a member list.
+ * The caller is responsible for freeing the returned struct member_list.
+ */
+static struct member_list *
+array_to_member_list(void *a, sudo_ldap_iter_t iter)
+{
+ struct member_list negated_members =
+ TAILQ_HEAD_INITIALIZER(negated_members);
+ struct member_list *members;
+ struct member *m;
+ char *val;
+ debug_decl(bv_to_member_list, SUDOERS_DEBUG_LDAP)
+
+ if ((members = calloc(1, sizeof(*members))) == NULL)
+ return NULL;
+ TAILQ_INIT(members);
+
+ while ((val = iter(&a)) != NULL) {
+ if ((m = calloc(1, sizeof(*m))) == NULL)
+ goto bad;
+ m->negated = sudo_ldap_is_negated(&val);
+
+ switch (val[0]) {
+ case '\0':
+ /* Empty RunAsUser means run as the invoking user. */
+ m->type = MYSELF;
+ break;
+ case '+':
+ m->type = NETGROUP;
+ m->name = strdup(val);
+ if (m->name == NULL) {
+ free(m);
+ goto bad;
+ }
+ break;
+ case '%':
+ m->type = USERGROUP;
+ m->name = strdup(val);
+ if (m->name == NULL) {
+ free(m);
+ goto bad;
+ }
+ break;
+ case 'A':
+ if (strcmp(val, "ALL") == 0) {
+ m->type = ALL;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ m->type = WORD;
+ m->name = strdup(val);
+ if (m->name == NULL) {
+ free(m);
+ goto bad;
+ }
+ break;
+ }
+ if (m->negated)
+ TAILQ_INSERT_TAIL(&negated_members, m, entries);
+ else
+ TAILQ_INSERT_TAIL(members, m, entries);
+ }
+
+ /* Negated members take precedence so we insert them at the end. */
+ TAILQ_CONCAT(members, &negated_members, entries);
+ debug_return_ptr(members);
+bad:
+ free_members(&negated_members);
+ free_members(members);
+ free(members);
+ debug_return_ptr(NULL);
+}
+
+static bool
+is_address(char *host)
+{
+ union sudo_in_addr_un addr;
+ bool ret = false;
+ char *slash;
+ debug_decl(is_address, SUDOERS_DEBUG_LDAP)
+
+ /* Check for mask, not currently parsed. */
+ if ((slash = strchr(host, '/')) != NULL)
+ *slash = '\0';
+
+ if (inet_pton(AF_INET, host, &addr.ip4) == 1)
+ ret = true;
+#ifdef HAVE_STRUCT_IN6_ADDR
+ else if (inet_pton(AF_INET6, host, &addr.ip6) == 1)
+ ret = true;
+#endif
+
+ if (slash != NULL)
+ *slash = '/';
+
+ debug_return_bool(ret);
+}
+
+static struct member *
+host_to_member(char *host)
+{
+ struct member *m;
+ debug_decl(host_to_member, SUDOERS_DEBUG_LDAP)
+
+ if ((m = calloc(1, sizeof(*m))) == NULL)
+ goto oom;
+ m->negated = sudo_ldap_is_negated(&host);
+ m->name = strdup(host);
+ if (m->name == NULL)
+ goto oom;
+ switch (*host) {
+ case '+':
+ m->type = NETGROUP;
+ break;
+ case 'A':
+ if (strcmp(host, "ALL") == 0) {
+ m->type = ALL;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ if (is_address(host)) {
+ m->type = NTWKADDR;
+ } else {
+ m->type = WORD;
+ }
+ break;
+ }
+
+ debug_return_ptr(m);
+oom:
+ free(m);
+ debug_return_ptr(NULL);
+}
+
+bool
+sudo_ldap_add_default(const char *var, const char *val, int op,
+ char *source, struct defaults_list *defs)
+{
+ struct defaults *def;
+ debug_decl(sudo_ldap_add_default, SUDOERS_DEBUG_LDAP)
+
+ if ((def = calloc(1, sizeof(*def))) == NULL)
+ goto oom;
+
+ def->type = DEFAULTS;
+ def->op = op;
+ if ((def->var = strdup(var)) == NULL) {
+ goto oom;
+ }
+ if (val != NULL) {
+ if ((def->val = strdup(val)) == NULL)
+ goto oom;
+ }
+ def->file = source;
+ rcstr_addref(source);
+ TAILQ_INSERT_TAIL(defs, def, entries);
+ debug_return_bool(true);
+
+oom:
+ if (def != NULL) {
+ free(def->var);
+ free(def->val);
+ free(def);
+ }
+ debug_return_bool(false);
+}
+
+/*
+ * Convert an LDAP sudoRole to a sudoers privilege.
+ * Pass in struct berval ** for LDAP or char *** for SSSD.
+ */
+struct privilege *
+sudo_ldap_role_to_priv(const char *cn, void *hosts, void *runasusers,
+ void *runasgroups, void *cmnds, void *opts, const char *notbefore,
+ const char *notafter, bool warnings, bool store_options,
+ sudo_ldap_iter_t iter)
+{
+ struct cmndspec_list negated_cmnds = TAILQ_HEAD_INITIALIZER(negated_cmnds);
+ struct member_list negated_hosts = TAILQ_HEAD_INITIALIZER(negated_hosts);
+ struct cmndspec *prev_cmndspec = NULL;
+ struct privilege *priv;
+ struct member *m;
+ char *cmnd;
+ debug_decl(sudo_ldap_role_to_priv, SUDOERS_DEBUG_LDAP)
+
+ if ((priv = calloc(1, sizeof(*priv))) == NULL)
+ goto oom;
+ TAILQ_INIT(&priv->hostlist);
+ TAILQ_INIT(&priv->cmndlist);
+ TAILQ_INIT(&priv->defaults);
+
+ priv->ldap_role = strdup(cn ? cn : "UNKNOWN");
+ if (priv->ldap_role == NULL)
+ goto oom;
+
+ if (hosts == NULL) {
+ /* The host has already matched, use ALL as wildcard. */
+ if ((m = calloc(1, sizeof(*m))) == NULL)
+ goto oom;
+ m->type = ALL;
+ TAILQ_INSERT_TAIL(&priv->hostlist, m, entries);
+ } else {
+ char *host;
+ while ((host = iter(&hosts)) != NULL) {
+ if ((m = host_to_member(host)) == NULL)
+ goto oom;
+ if (m->negated)
+ TAILQ_INSERT_TAIL(&negated_hosts, m, entries);
+ else
+ TAILQ_INSERT_TAIL(&priv->hostlist, m, entries);
+ }
+ /* Negated hosts take precedence so we insert them at the end. */
+ TAILQ_CONCAT(&priv->hostlist, &negated_hosts, entries);
+ }
+
+ /*
+ * Parse sudoCommands and add to cmndlist.
+ */
+ while ((cmnd = iter(&cmnds)) != NULL) {
+ bool negated = sudo_ldap_is_negated(&cmnd);
+ struct sudo_command *c = NULL;
+ struct cmndspec *cmndspec;
+
+ /* Allocate storage upfront. */
+ if ((cmndspec = calloc(1, sizeof(*cmndspec))) == NULL)
+ goto oom;
+ if ((m = calloc(1, sizeof(*m))) == NULL) {
+ free(cmndspec);
+ goto oom;
+ }
+ if (strcmp(cmnd, "ALL") != 0) {
+ if ((c = calloc(1, sizeof(*c))) == NULL) {
+ free(cmndspec);
+ free(m);
+ goto oom;
+ }
+ m->name = (char *)c;
+ }
+
+ /* Negated commands have precedence so insert them at the end. */
+ if (negated)
+ TAILQ_INSERT_TAIL(&negated_cmnds, cmndspec, entries);
+ else
+ TAILQ_INSERT_TAIL(&priv->cmndlist, cmndspec, entries);
+
+ /* Initialize cmndspec */
+ TAGS_INIT(cmndspec->tags);
+ cmndspec->notbefore = UNSPEC;
+ cmndspec->notafter = UNSPEC;
+ cmndspec->timeout = UNSPEC;
+ cmndspec->cmnd = m;
+
+ if (prev_cmndspec != NULL) {
+ /* Inherit values from prior cmndspec (common to the sudoRole). */
+ cmndspec->runasuserlist = prev_cmndspec->runasuserlist;
+ cmndspec->runasgrouplist = prev_cmndspec->runasgrouplist;
+ cmndspec->notbefore = prev_cmndspec->notbefore;
+ cmndspec->notafter = prev_cmndspec->notafter;
+ cmndspec->tags = prev_cmndspec->tags;
+ if (cmndspec->tags.setenv == IMPLIED)
+ cmndspec->tags.setenv = UNSPEC;
+ } else {
+ /* Parse sudoRunAsUser / sudoRunAs */
+ if (runasusers != NULL) {
+ cmndspec->runasuserlist =
+ array_to_member_list(runasusers, iter);
+ if (cmndspec->runasuserlist == NULL)
+ goto oom;
+ }
+
+ /* Parse sudoRunAsGroup */
+ if (runasgroups != NULL) {
+ cmndspec->runasgrouplist =
+ array_to_member_list(runasgroups, iter);
+ if (cmndspec->runasgrouplist == NULL)
+ goto oom;
+ }
+
+ /* Parse sudoNotBefore / sudoNotAfter */
+ if (notbefore != NULL)
+ cmndspec->notbefore = parse_gentime(notbefore);
+ if (notafter != NULL)
+ cmndspec->notafter = parse_gentime(notafter);
+
+ /* Parse sudoOptions. */
+ if (opts != NULL) {
+ char *opt, *source = NULL;
+
+ if (store_options) {
+ /* Use sudoRole in place of file name in defaults. */
+ size_t slen = sizeof("sudoRole") + strlen(priv->ldap_role);
+ if ((source = rcstr_alloc(slen)) == NULL)
+ goto oom;
+ snprintf(source, slen, "sudoRole %s", priv->ldap_role);
+ }
+
+ while ((opt = iter(&opts)) != NULL) {
+ char *var, *val;
+ int op;
+
+ op = sudo_ldap_parse_option(opt, &var, &val);
+ if (strcmp(var, "command_timeout") == 0 && val != NULL) {
+ cmndspec->timeout = parse_timeout(val);
+#ifdef HAVE_SELINUX
+ } else if (strcmp(var, "role") == 0 && val != NULL) {
+ if ((cmndspec->role = strdup(val)) == NULL)
+ break;
+ } else if (strcmp(var, "type") == 0 && val != NULL) {
+ if ((cmndspec->type = strdup(val)) == NULL)
+ break;
+#endif /* HAVE_SELINUX */
+#ifdef HAVE_PRIV_SET
+ } else if (strcmp(var, "privs") == 0 && val != NULL) {
+ if ((cmndspec->privs = strdup(val)) == NULL)
+ break;
+ } else if (strcmp(var, "limitprivs") == 0 && val != NULL) {
+ if ((cmndspec->limitprivs = strdup(val)) == NULL)
+ break;
+#endif /* HAVE_PRIV_SET */
+ } else if (store_options) {
+ if (!sudo_ldap_add_default(var, val, op, source,
+ &priv->defaults)) {
+ break;
+ }
+ } else {
+ /* Convert to tags. */
+ bool converted = sudoers_defaults_to_tags(var, val, op,
+ &cmndspec->tags);
+ if (!converted) {
+ if (warnings) {
+ /* XXX - callback to process unsupported options. */
+ if (val != NULL) {
+ sudo_warnx(U_("unable to convert sudoOption: %s%s%s"), var, op == '+' ? "+=" : op == '-' ? "-=" : "=", val);
+ } else {
+ sudo_warnx(U_("unable to convert sudoOption: %s%s%s"), op == false ? "!" : "", var, "");
+ }
+ }
+ continue;
+ }
+ }
+ }
+ rcstr_delref(source);
+ if (opt != NULL) {
+ /* Defer oom until we drop the ref on source. */
+ goto oom;
+ }
+ }
+
+ /* So we can inherit previous values. */
+ prev_cmndspec = cmndspec;
+ }
+
+ /* Fill in command member now that options have been processed. */
+ m->negated = negated;
+ if (c == NULL) {
+ /* No command name for "ALL" */
+ m->type = ALL;
+ if (cmndspec->tags.setenv == UNSPEC)
+ cmndspec->tags.setenv = IMPLIED;
+ } else {
+ struct command_digest digest;
+ char *args;
+
+ m->type = COMMAND;
+
+ /* Fill in command with optional digest. */
+ if (sudo_ldap_extract_digest(&cmnd, &digest) != NULL) {
+ if ((c->digest = malloc(sizeof(*c->digest))) == NULL)
+ goto oom;
+ *c->digest = digest;
+ }
+ if ((args = strpbrk(cmnd, " \t")) != NULL) {
+ *args++ = '\0';
+ if ((c->args = strdup(args)) == NULL)
+ goto oom;
+ }
+ if ((c->cmnd = strdup(cmnd)) == NULL)
+ goto oom;
+ }
+ }
+ /* Negated commands take precedence so we insert them at the end. */
+ TAILQ_CONCAT(&priv->cmndlist, &negated_cmnds, entries);
+
+ debug_return_ptr(priv);
+
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (priv != NULL) {
+ TAILQ_CONCAT(&priv->cmndlist, &negated_cmnds, entries);
+ free_privilege(priv);
+ }
+ debug_return_ptr(NULL);
+}
+
+/*
+ * If a digest prefix is present, fills in struct command_digest
+ * and returns a pointer to it, updating cmnd to point to the
+ * command after the digest.
+ */
+struct command_digest *
+sudo_ldap_extract_digest(char **cmnd, struct command_digest *digest)
+{
+ char *ep, *cp = *cmnd;
+ int digest_type = SUDO_DIGEST_INVALID;
+ debug_decl(sudo_ldap_check_command, SUDOERS_DEBUG_LDAP)
+
+ /*
+ * Check for and extract a digest prefix, e.g.
+ * sha224:d06a2617c98d377c250edd470fd5e576327748d82915d6e33b5f8db1 /bin/ls
+ */
+ if (cp[0] == 's' && cp[1] == 'h' && cp[2] == 'a') {
+ switch (cp[3]) {
+ case '2':
+ if (cp[4] == '2' && cp[5] == '4')
+ digest_type = SUDO_DIGEST_SHA224;
+ else if (cp[4] == '5' && cp[5] == '6')
+ digest_type = SUDO_DIGEST_SHA256;
+ break;
+ case '3':
+ if (cp[4] == '8' && cp[5] == '4')
+ digest_type = SUDO_DIGEST_SHA384;
+ break;
+ case '5':
+ if (cp[4] == '1' && cp[5] == '2')
+ digest_type = SUDO_DIGEST_SHA512;
+ break;
+ }
+ if (digest_type != SUDO_DIGEST_INVALID) {
+ cp += 6;
+ while (isblank((unsigned char)*cp))
+ cp++;
+ if (*cp == ':') {
+ cp++;
+ while (isblank((unsigned char)*cp))
+ cp++;
+ ep = cp;
+ while (*ep != '\0' && !isblank((unsigned char)*ep))
+ ep++;
+ if (*ep != '\0') {
+ digest->digest_type = digest_type;
+ digest->digest_str = strndup(cp, (size_t)(ep - cp));
+ if (digest->digest_str == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_ptr(NULL);
+ }
+ cp = ep + 1;
+ while (isblank((unsigned char)*cp))
+ cp++;
+ *cmnd = cp;
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s digest %s for %s",
+ digest_type_to_name(digest_type),
+ digest->digest_str, cp);
+ debug_return_ptr(digest);
+ }
+ }
+ }
+ }
+ debug_return_ptr(NULL);
+}
diff --git a/plugins/sudoers/linux_audit.c b/plugins/sudoers/linux_audit.c
new file mode 100644
index 0000000..6ac8be0
--- /dev/null
+++ b/plugins/sudoers/linux_audit.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2010-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_LINUX_AUDIT
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <libaudit.h>
+
+#include "sudoers.h"
+#include "linux_audit.h"
+
+#define AUDIT_NOT_CONFIGURED -2
+
+/*
+ * Open audit connection if possible.
+ * Returns audit fd on success and -1 on failure.
+ */
+static int
+linux_audit_open(void)
+{
+ static int au_fd = -1;
+ debug_decl(linux_audit_open, SUDOERS_DEBUG_AUDIT)
+
+ if (au_fd != -1)
+ debug_return_int(au_fd);
+ au_fd = audit_open();
+ if (au_fd == -1) {
+ /* Kernel may not have audit support. */
+ if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT)
+ au_fd = AUDIT_NOT_CONFIGURED;
+ else
+ sudo_warn(U_("unable to open audit system"));
+ } else {
+ (void)fcntl(au_fd, F_SETFD, FD_CLOEXEC);
+ }
+ debug_return_int(au_fd);
+}
+
+int
+linux_audit_command(char *argv[], int result)
+{
+ int au_fd, rc = -1;
+ char *command, *cp, **av;
+ size_t size, n;
+ debug_decl(linux_audit_command, SUDOERS_DEBUG_AUDIT)
+
+ /* Don't return an error if auditing is not configured. */
+ if ((au_fd = linux_audit_open()) < 0)
+ debug_return_int(au_fd == AUDIT_NOT_CONFIGURED ? 0 : -1);
+
+ /* Convert argv to a flat string. */
+ for (size = 0, av = argv; *av != NULL; av++)
+ size += strlen(*av) + 1;
+ command = malloc(size);
+ if (command == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ for (av = argv, cp = command; *av != NULL; av++) {
+ n = strlcpy(cp, *av, size - (cp - command));
+ if (n >= size - (cp - command)) {
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ goto done;
+ }
+ cp += n;
+ *cp++ = ' ';
+ }
+ *--cp = '\0';
+
+ /* Log command, ignoring ECONNREFUSED on error. */
+ if (audit_log_user_command(au_fd, AUDIT_USER_CMD, command, NULL, result) <= 0) {
+ if (errno != ECONNREFUSED) {
+ sudo_warn(U_("unable to send audit message"));
+ goto done;
+ }
+ }
+
+ rc = 0;
+
+done:
+ free(command);
+
+ debug_return_int(rc);
+}
+
+#endif /* HAVE_LINUX_AUDIT */
diff --git a/plugins/sudoers/linux_audit.h b/plugins/sudoers/linux_audit.h
new file mode 100644
index 0000000..84e55a0
--- /dev/null
+++ b/plugins/sudoers/linux_audit.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2010, 2013 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_LINUX_AUDIT_H
+#define SUDOERS_LINUX_AUDIT_H
+
+int linux_audit_command(char *argv[], int result);
+
+#endif /* SUDOERS_LINUX_AUDIT_H */
diff --git a/plugins/sudoers/locale.c b/plugins/sudoers/locale.c
new file mode 100644
index 0000000..c69fd60
--- /dev/null
+++ b/plugins/sudoers/locale.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2012-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+
+#define DEFAULT_TEXT_DOMAIN "sudoers"
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudoers_debug.h"
+#include "defaults.h"
+#include "logging.h"
+
+static int current_locale = SUDOERS_LOCALE_USER;
+static char *user_locale;
+static char *sudoers_locale;
+
+int
+sudoers_getlocale(void)
+{
+ debug_decl(sudoers_getlocale, SUDOERS_DEBUG_UTIL)
+ debug_return_int(current_locale);
+}
+
+bool
+sudoers_initlocale(const char *ulocale, const char *slocale)
+{
+ debug_decl(sudoers_initlocale, SUDOERS_DEBUG_UTIL)
+
+ if (ulocale != NULL) {
+ free(user_locale);
+ if ((user_locale = strdup(ulocale)) == NULL)
+ debug_return_bool(false);
+ }
+ if (slocale != NULL) {
+ free(sudoers_locale);
+ if ((sudoers_locale = strdup(slocale)) == NULL)
+ debug_return_bool(false);
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: user locale %s, sudoers locale %s",
+ __func__, user_locale, sudoers_locale);
+ debug_return_bool(true);
+}
+
+/*
+ * Set locale to user or sudoers value.
+ * Returns true on success and false on failure,
+ * If prevlocale is non-NULL it will be filled in with the
+ * old SUDOERS_LOCALE_* value.
+ */
+bool
+sudoers_setlocale(int newlocale, int *prevlocale)
+{
+ char *res = NULL;
+ debug_decl(sudoers_setlocale, SUDOERS_DEBUG_UTIL)
+
+ switch (newlocale) {
+ case SUDOERS_LOCALE_USER:
+ if (prevlocale)
+ *prevlocale = current_locale;
+ if (current_locale != SUDOERS_LOCALE_USER) {
+ current_locale = SUDOERS_LOCALE_USER;
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s: setting locale to %s (user)", __func__,
+ user_locale ? user_locale : "");
+ res = setlocale(LC_ALL, user_locale ? user_locale : "");
+ if (res != NULL && user_locale == NULL) {
+ user_locale = setlocale(LC_ALL, NULL);
+ if (user_locale != NULL)
+ user_locale = strdup(user_locale);
+ if (user_locale == NULL)
+ res = NULL;
+ }
+ }
+ break;
+ case SUDOERS_LOCALE_SUDOERS:
+ if (prevlocale)
+ *prevlocale = current_locale;
+ if (current_locale != SUDOERS_LOCALE_SUDOERS) {
+ current_locale = SUDOERS_LOCALE_SUDOERS;
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s: setting locale to %s (sudoers)", __func__,
+ sudoers_locale ? sudoers_locale : "C");
+ res = setlocale(LC_ALL, sudoers_locale ? sudoers_locale : "C");
+ if (res == NULL && sudoers_locale != NULL) {
+ if (strcmp(sudoers_locale, "C") != 0) {
+ free(sudoers_locale);
+ sudoers_locale = strdup("C");
+ if (sudoers_locale != NULL)
+ res = setlocale(LC_ALL, "C");
+ }
+ }
+ }
+ break;
+ }
+ debug_return_bool(res ? true : false);
+}
+
+bool
+sudoers_warn_setlocale(bool restore, int *cookie)
+{
+ debug_decl(sudoers_warn_setlocale, SUDOERS_DEBUG_UTIL)
+
+ if (restore)
+ debug_return_bool(sudoers_setlocale(*cookie, NULL));
+ debug_return_bool(sudoers_setlocale(SUDOERS_LOCALE_USER, cookie));
+}
+
+/*
+ * Callback for sudoers_locale sudoers setting.
+ */
+bool
+sudoers_locale_callback(const union sudo_defs_val *sd_un)
+{
+ debug_decl(sudoers_locale_callback, SUDOERS_DEBUG_UTIL)
+
+ if (sudoers_initlocale(NULL, sd_un->str)) {
+ if (setlocale(LC_ALL, sd_un->str) != NULL)
+ debug_return_bool(true);
+ }
+ debug_return_bool(false);
+}
diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c
new file mode 100644
index 0000000..9562609
--- /dev/null
+++ b/plugins/sudoers/logging.c
@@ -0,0 +1,1044 @@
+/*
+ * Copyright (c) 1994-1996, 1998-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#ifdef __TANDEM
+# include <floss.h>
+#endif
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#ifdef HAVE_NL_LANGINFO
+# include <langinfo.h>
+#endif /* HAVE_NL_LANGINFO */
+#include <netdb.h>
+#include <pwd.h>
+#include <grp.h>
+#include <signal.h>
+#include <time.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <syslog.h>
+
+#include "sudoers.h"
+
+#ifndef HAVE_GETADDRINFO
+# include "compat/getaddrinfo.h"
+#endif
+
+/* Special message for log_warning() so we know to use ngettext() */
+#define INCORRECT_PASSWORD_ATTEMPT ((char *)0x01)
+
+static void do_syslog(int, char *);
+static bool do_logfile(const char *);
+static bool send_mail(const char *fmt, ...);
+static bool should_mail(int);
+static void mysyslog(int, const char *, ...);
+static char *new_logline(const char *, const char *);
+
+#define MAXSYSLOGTRIES 16 /* num of retries for broken syslogs */
+
+/*
+ * We do an openlog(3)/closelog(3) for each message because some
+ * authentication methods (notably PAM) use syslog(3) for their
+ * own nefarious purposes and may call openlog(3) and closelog(3).
+ */
+static void
+mysyslog(int pri, const char *fmt, ...)
+{
+ const int flags = def_syslog_pid ? LOG_PID : 0;
+ va_list ap;
+ debug_decl(mysyslog, SUDOERS_DEBUG_LOGGING)
+
+ openlog("sudo", flags, def_syslog);
+ va_start(ap, fmt);
+ vsyslog(pri, fmt, ap);
+ va_end(ap);
+ closelog();
+ debug_return;
+}
+
+/*
+ * Log a message to syslog, pre-pending the username and splitting the
+ * message into parts if it is longer than syslog_maxlen.
+ */
+static void
+do_syslog(int pri, char *msg)
+{
+ size_t len, maxlen;
+ char *p, *tmp, save;
+ const char *fmt;
+ int oldlocale;
+ debug_decl(do_syslog, SUDOERS_DEBUG_LOGGING)
+
+ /* A priority of -1 corresponds to "none". */
+ if (pri == -1)
+ debug_return;
+
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+
+ /*
+ * Log the full line, breaking into multiple syslog(3) calls if necessary
+ */
+ fmt = _("%8s : %s");
+ maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(user_name));
+ for (p = msg; *p != '\0'; ) {
+ len = strlen(p);
+ if (len > maxlen) {
+ /*
+ * Break up the line into what will fit on one syslog(3) line
+ * Try to avoid breaking words into several lines if possible.
+ */
+ tmp = memrchr(p, ' ', maxlen);
+ if (tmp == NULL)
+ tmp = p + maxlen;
+
+ /* NULL terminate line, but save the char to restore later */
+ save = *tmp;
+ *tmp = '\0';
+
+ mysyslog(pri, fmt, user_name, p);
+
+ *tmp = save; /* restore saved character */
+
+ /* Advance p and eliminate leading whitespace */
+ for (p = tmp; *p == ' '; p++)
+ continue;
+ } else {
+ mysyslog(pri, fmt, user_name, p);
+ p += len;
+ }
+ fmt = _("%8s : (command continued) %s");
+ maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(user_name));
+ }
+
+ sudoers_setlocale(oldlocale, NULL);
+
+ debug_return;
+}
+
+static bool
+do_logfile(const char *msg)
+{
+ static bool warned = false;
+ const char *timestr;
+ int len, oldlocale;
+ bool ret = false;
+ char *full_line;
+ mode_t oldmask;
+ FILE *fp;
+ debug_decl(do_logfile, SUDOERS_DEBUG_LOGGING)
+
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+
+ oldmask = umask(S_IRWXG|S_IRWXO);
+ fp = fopen(def_logfile, "a");
+ (void) umask(oldmask);
+ if (fp == NULL) {
+ if (!warned) {
+ log_warning(SLOG_SEND_MAIL|SLOG_NO_LOG,
+ N_("unable to open log file: %s"), def_logfile);
+ warned = true;
+ }
+ goto done;
+ }
+ if (!sudo_lock_file(fileno(fp), SUDO_LOCK)) {
+ if (!warned) {
+ log_warning(SLOG_SEND_MAIL|SLOG_NO_LOG,
+ N_("unable to lock log file: %s"), def_logfile);
+ warned = true;
+ }
+ goto done;
+ }
+
+ timestr = get_timestr(time(NULL), def_log_year);
+ if (timestr == NULL)
+ timestr = "invalid date";
+ if (def_log_host) {
+ len = asprintf(&full_line, "%s : %s : HOST=%s : %s",
+ timestr, user_name, user_srunhost, msg);
+ } else {
+ len = asprintf(&full_line, "%s : %s : %s",
+ timestr, user_name, msg);
+ }
+ if (len == -1) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ if ((size_t)def_loglinelen < sizeof(LOG_INDENT)) {
+ /* Don't pretty-print long log file lines (hard to grep). */
+ (void) fputs(full_line, fp);
+ (void) fputc('\n', fp);
+ } else {
+ /* Write line with word wrap around def_loglinelen chars. */
+ writeln_wrap(fp, full_line, len, def_loglinelen);
+ }
+ free(full_line);
+ (void) fflush(fp);
+ if (ferror(fp)) {
+ if (!warned) {
+ log_warning(SLOG_SEND_MAIL|SLOG_NO_LOG,
+ N_("unable to write log file: %s"), def_logfile);
+ warned = true;
+ }
+ goto done;
+ }
+ ret = true;
+
+done:
+ if (fp != NULL)
+ (void) fclose(fp);
+ sudoers_setlocale(oldlocale, NULL);
+
+ debug_return_bool(ret);
+}
+
+/*
+ * Log, audit and mail the denial message, optionally informing the user.
+ */
+bool
+log_denial(int status, bool inform_user)
+{
+ const char *message;
+ char *logline;
+ int oldlocale;
+ bool uid_changed, ret = true;
+ debug_decl(log_denial, SUDOERS_DEBUG_LOGGING)
+
+ /* Handle auditing first (audit_failure() handles the locale itself). */
+ if (ISSET(status, FLAG_NO_USER | FLAG_NO_HOST))
+ audit_failure(NewArgc, NewArgv, N_("No user or host"));
+ else
+ audit_failure(NewArgc, NewArgv, N_("validation failure"));
+
+ /* Log and mail messages should be in the sudoers locale. */
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+
+ /* Set error message. */
+ if (ISSET(status, FLAG_NO_USER))
+ message = _("user NOT in sudoers");
+ else if (ISSET(status, FLAG_NO_HOST))
+ message = _("user NOT authorized on host");
+ else
+ message = _("command not allowed");
+
+ logline = new_logline(message, NULL);
+ if (logline == NULL)
+ debug_return_bool(false);
+
+ /* Become root if we are not already. */
+ uid_changed = set_perms(PERM_ROOT);
+
+ if (should_mail(status))
+ send_mail("%s", logline); /* send mail based on status */
+
+ /*
+ * Log via syslog and/or a file.
+ */
+ if (def_syslog)
+ do_syslog(def_syslog_badpri, logline);
+ if (def_logfile && !do_logfile(logline))
+ ret = false;
+
+ if (uid_changed) {
+ if (!restore_perms())
+ ret = false; /* XXX - return -1 instead? */
+ }
+
+ free(logline);
+
+ /* Restore locale. */
+ sudoers_setlocale(oldlocale, NULL);
+
+ /* Inform the user if they failed to authenticate (in their locale). */
+ if (inform_user) {
+ sudoers_setlocale(SUDOERS_LOCALE_USER, &oldlocale);
+
+ if (ISSET(status, FLAG_NO_USER)) {
+ sudo_printf(SUDO_CONV_ERROR_MSG, _("%s is not in the sudoers "
+ "file. This incident will be reported.\n"), user_name);
+ } else if (ISSET(status, FLAG_NO_HOST)) {
+ sudo_printf(SUDO_CONV_ERROR_MSG, _("%s is not allowed to run sudo "
+ "on %s. This incident will be reported.\n"),
+ user_name, user_srunhost);
+ } else if (ISSET(status, FLAG_NO_CHECK)) {
+ sudo_printf(SUDO_CONV_ERROR_MSG, _("Sorry, user %s may not run "
+ "sudo on %s.\n"), user_name, user_srunhost);
+ } else {
+ sudo_printf(SUDO_CONV_ERROR_MSG, _("Sorry, user %s is not allowed "
+ "to execute '%s%s%s' as %s%s%s on %s.\n"),
+ user_name, user_cmnd, user_args ? " " : "",
+ user_args ? user_args : "",
+ list_pw ? list_pw->pw_name : runas_pw ?
+ runas_pw->pw_name : user_name, runas_gr ? ":" : "",
+ runas_gr ? runas_gr->gr_name : "", user_host);
+ }
+ sudoers_setlocale(oldlocale, NULL);
+ }
+ debug_return_bool(ret);
+}
+
+/*
+ * Log and audit that user was not allowed to run the command.
+ */
+bool
+log_failure(int status, int flags)
+{
+ bool ret, inform_user = true;
+ debug_decl(log_failure, SUDOERS_DEBUG_LOGGING)
+
+ /* The user doesn't always get to see the log message (path info). */
+ if (!ISSET(status, FLAG_NO_USER | FLAG_NO_HOST) && def_path_info &&
+ (flags == NOT_FOUND_DOT || flags == NOT_FOUND))
+ inform_user = false;
+ ret = log_denial(status, inform_user);
+
+ if (!inform_user) {
+ /*
+ * We'd like to not leak path info at all here, but that can
+ * *really* confuse the users. To really close the leak we'd
+ * have to say "not allowed to run foo" even when the problem
+ * is just "no foo in path" since the user can trivially set
+ * their path to just contain a single dir.
+ */
+ if (flags == NOT_FOUND)
+ sudo_warnx(U_("%s: command not found"), user_cmnd);
+ else if (flags == NOT_FOUND_DOT)
+ sudo_warnx(U_("ignoring \"%s\" found in '.'\nUse \"sudo ./%s\" if this is the \"%s\" you wish to run."), user_cmnd, user_cmnd, user_cmnd);
+ }
+
+ debug_return_bool(ret);
+}
+
+/*
+ * Log and audit that user was not able to authenticate themselves.
+ */
+bool
+log_auth_failure(int status, unsigned int tries)
+{
+ int flags = 0;
+ bool ret = true;
+ debug_decl(log_auth_failure, SUDOERS_DEBUG_LOGGING)
+
+ /* Handle auditing first. */
+ audit_failure(NewArgc, NewArgv, N_("authentication failure"));
+
+ /*
+ * Do we need to send mail?
+ * We want to avoid sending multiple messages for the same command
+ * so if we are going to send an email about the denial, that takes
+ * precedence.
+ */
+ if (ISSET(status, VALIDATE_SUCCESS)) {
+ /* Command allowed, auth failed; do we need to send mail? */
+ if (def_mail_badpass || def_mail_always)
+ SET(flags, SLOG_SEND_MAIL);
+ } else {
+ /* Command denied, auth failed; make sure we don't send mail twice. */
+ if (def_mail_badpass && !should_mail(status))
+ SET(flags, SLOG_SEND_MAIL);
+ /* Don't log the bad password message, we'll log a denial instead. */
+ SET(flags, SLOG_NO_LOG);
+ }
+
+ /*
+ * If sudoers denied the command we'll log that separately.
+ */
+ if (ISSET(status, FLAG_BAD_PASSWORD))
+ ret = log_warningx(flags, INCORRECT_PASSWORD_ATTEMPT, tries);
+ else if (ISSET(status, FLAG_NON_INTERACTIVE))
+ ret = log_warningx(flags, N_("a password is required"));
+
+ debug_return_bool(ret);
+}
+
+/*
+ * Log and potentially mail the allowed command.
+ */
+bool
+log_allowed(int status)
+{
+ char *logline;
+ int oldlocale;
+ bool uid_changed, ret = true;
+ debug_decl(log_allowed, SUDOERS_DEBUG_LOGGING)
+
+ /* Log and mail messages should be in the sudoers locale. */
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+
+ if ((logline = new_logline(NULL, NULL)) == NULL)
+ debug_return_bool(false);
+
+ /* Become root if we are not already. */
+ uid_changed = set_perms(PERM_ROOT);
+
+ /* XXX - return value */
+ if (should_mail(status))
+ send_mail("%s", logline); /* send mail based on status */
+
+ /*
+ * Log via syslog and/or a file.
+ */
+ if (def_syslog)
+ do_syslog(def_syslog_goodpri, logline);
+ if (def_logfile && !do_logfile(logline))
+ ret = false;
+
+ if (uid_changed) {
+ if (!restore_perms())
+ ret = false; /* XXX - return -1 instead? */
+ }
+
+ free(logline);
+
+ sudoers_setlocale(oldlocale, NULL);
+
+ debug_return_bool(ret);
+}
+
+/*
+ * Format an authentication failure message, using either
+ * authfail_message from sudoers or a locale-specific message.
+ */
+static int
+fmt_authfail_message(char **str, va_list ap)
+{
+ unsigned int tries = va_arg(ap, unsigned int);
+ char *src, *dst0, *dst, *dst_end;
+ size_t size;
+ int len;
+ debug_decl(fmt_authfail_message, SUDOERS_DEBUG_LOGGING)
+
+ if (def_authfail_message == NULL) {
+ debug_return_int(asprintf(str, ngettext("%u incorrect password attempt",
+ "%u incorrect password attempts", tries), tries));
+ }
+
+ src = def_authfail_message;
+ size = strlen(src) + 33;
+ if ((dst0 = dst = malloc(size)) == NULL)
+ debug_return_int(-1);
+ dst_end = dst + size;
+
+ /* Always leave space for the terminating NUL. */
+ while (*src != '\0' && dst + 1 < dst_end) {
+ if (src[0] == '%') {
+ switch (src[1]) {
+ case '%':
+ src++;
+ break;
+ case 'd':
+ len = snprintf(dst, dst_end - dst, "%u", tries);
+ if (len == -1 || len >= (int)(dst_end - dst))
+ goto done;
+ dst += len;
+ src += 2;
+ continue;
+ default:
+ break;
+ }
+ }
+ *dst++ = *src++;
+ }
+done:
+ *dst = '\0';
+
+ *str = dst0;
+#ifdef __clang_analyzer__
+ /* clang analyzer false positive */
+ if (__builtin_expect(dst < dst0, 0))
+ __builtin_trap();
+#endif
+ debug_return_int(dst - dst0);
+}
+
+/*
+ * Perform logging for log_warning()/log_warningx().
+ */
+static bool
+vlog_warning(int flags, int errnum, const char *fmt, va_list ap)
+{
+ int oldlocale;
+ const char *errstr = NULL;
+ char *logline, *message;
+ bool uid_changed, ret = true;
+ va_list ap2;
+ int len;
+ debug_decl(vlog_warning, SUDOERS_DEBUG_LOGGING)
+
+ /* Need extra copy of ap for sudo_vwarn()/sudo_vwarnx() below. */
+ va_copy(ap2, ap);
+
+ /* Log messages should be in the sudoers locale. */
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+
+ /* Expand printf-style format + args (with a special case). */
+ if (fmt == INCORRECT_PASSWORD_ATTEMPT) {
+ len = fmt_authfail_message(&message, ap);
+ } else {
+ len = vasprintf(&message, _(fmt), ap);
+ }
+ if (len == -1) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ ret = false;
+ goto done;
+ }
+
+ if (ISSET(flags, SLOG_USE_ERRNO))
+ errstr = strerror(errnum);
+ else if (ISSET(flags, SLOG_GAI_ERRNO))
+ errstr = gai_strerror(errnum);
+
+ /* Log to debug file. */
+ if (errstr != NULL) {
+ sudo_debug_printf2(NULL, NULL, 0,
+ SUDO_DEBUG_WARN|sudo_debug_subsys, "%s: %s", message, errstr);
+ } else {
+ sudo_debug_printf2(NULL, NULL, 0,
+ SUDO_DEBUG_WARN|sudo_debug_subsys, "%s", message);
+ }
+
+ if (ISSET(flags, SLOG_RAW_MSG)) {
+ logline = message;
+ } else {
+ logline = new_logline(message, errstr);
+ free(message);
+ if (logline == NULL) {
+ ret = false;
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ }
+
+ /* Become root if we are not already. */
+ uid_changed = set_perms(PERM_ROOT);
+
+ /*
+ * Send a copy of the error via mail.
+ * XXX - return value
+ */
+ if (ISSET(flags, SLOG_SEND_MAIL))
+ send_mail("%s", logline);
+
+ /*
+ * Log to syslog and/or a file.
+ */
+ if (!ISSET(flags, SLOG_NO_LOG)) {
+ if (def_syslog)
+ do_syslog(def_syslog_badpri, logline);
+ if (def_logfile && !do_logfile(logline))
+ ret = false;
+ }
+
+ if (uid_changed) {
+ if (!restore_perms())
+ ret = false;
+ }
+
+ free(logline);
+
+ /*
+ * Tell the user (in their locale).
+ */
+ if (!ISSET(flags, SLOG_NO_STDERR)) {
+ sudoers_setlocale(SUDOERS_LOCALE_USER, NULL);
+ if (fmt == INCORRECT_PASSWORD_ATTEMPT) {
+ len = fmt_authfail_message(&message, ap2);
+ if (len == -1) {
+ sudo_warnx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ ret = false;
+ goto done;
+ }
+ sudo_warnx_nodebug("%s", message);
+ free(message);
+ } else {
+ if (ISSET(flags, SLOG_USE_ERRNO)) {
+ errno = errnum;
+ sudo_vwarn_nodebug(_(fmt), ap2);
+ } else if (ISSET(flags, SLOG_GAI_ERRNO)) {
+ sudo_gai_vwarn_nodebug(errnum, _(fmt), ap2);
+ } else
+ sudo_vwarnx_nodebug(_(fmt), ap2);
+ }
+ }
+
+done:
+ va_end(ap2);
+ sudoers_setlocale(oldlocale, NULL);
+
+ debug_return_bool(ret);
+}
+
+bool
+log_warning(int flags, const char *fmt, ...)
+{
+ va_list ap;
+ bool ret;
+ debug_decl(log_warning, SUDOERS_DEBUG_LOGGING)
+
+ /* Log the error. */
+ va_start(ap, fmt);
+ ret = vlog_warning(flags|SLOG_USE_ERRNO, errno, fmt, ap);
+ va_end(ap);
+
+ debug_return_bool(ret);
+}
+
+bool
+log_warningx(int flags, const char *fmt, ...)
+{
+ va_list ap;
+ bool ret;
+ debug_decl(log_warningx, SUDOERS_DEBUG_LOGGING)
+
+ /* Log the error. */
+ va_start(ap, fmt);
+ ret = vlog_warning(flags, 0, fmt, ap);
+ va_end(ap);
+
+ debug_return_bool(ret);
+}
+
+bool
+gai_log_warning(int flags, int errnum, const char *fmt, ...)
+{
+ va_list ap;
+ bool ret;
+ debug_decl(gai_log_warning, SUDOERS_DEBUG_LOGGING)
+
+ /* Log the error. */
+ va_start(ap, fmt);
+ ret = vlog_warning(flags|SLOG_GAI_ERRNO, errnum, fmt, ap);
+ va_end(ap);
+
+ debug_return_bool(ret);
+}
+
+
+#define MAX_MAILFLAGS 63
+
+/*
+ * Send a message to MAILTO user
+ */
+static bool
+send_mail(const char *fmt, ...)
+{
+ FILE *mail;
+ char *p;
+ const char *timestr;
+ int fd, pfd[2], status;
+ pid_t pid, rv;
+ struct stat sb;
+ va_list ap;
+#ifndef NO_ROOT_MAILER
+ static char *root_envp[] = {
+ "HOME=/",
+ "PATH=/usr/bin:/bin:/usr/sbin:/sbin",
+ "LOGNAME=root",
+ "USER=root",
+# ifdef _AIX
+ "LOGIN=root",
+# endif
+ NULL
+ };
+#endif /* NO_ROOT_MAILER */
+ debug_decl(send_mail, SUDOERS_DEBUG_LOGGING)
+
+ /* If mailer is disabled just return. */
+ if (!def_mailerpath || !def_mailto)
+ debug_return_bool(true);
+
+ /* Make sure the mailer exists and is a regular file. */
+ if (stat(def_mailerpath, &sb) != 0 || !S_ISREG(sb.st_mode))
+ debug_return_bool(false);
+
+ /* Fork and return, child will daemonize. */
+ switch (pid = sudo_debug_fork()) {
+ case -1:
+ /* Error. */
+ sudo_warn(U_("unable to fork"));
+ debug_return_bool(false);
+ break;
+ case 0:
+ /* Child. */
+ switch (pid = fork()) {
+ case -1:
+ /* Error. */
+ mysyslog(LOG_ERR, _("unable to fork: %m"));
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to fork: %s",
+ strerror(errno));
+ _exit(1);
+ case 0:
+ /* Grandchild continues below. */
+ break;
+ default:
+ /* Parent will wait for us. */
+ _exit(0);
+ }
+ break;
+ default:
+ /* Parent. */
+ for (;;) {
+ rv = waitpid(pid, &status, 0);
+ if (rv == -1 && errno != EINTR)
+ break;
+ if (rv != -1 && !WIFSTOPPED(status))
+ break;
+ }
+ return true; /* not debug */
+ }
+
+ /* Daemonize - disassociate from session/tty. */
+ if (setsid() == -1)
+ sudo_warn("setsid");
+ if (chdir("/") == -1)
+ sudo_warn("chdir(/)");
+ fd = open(_PATH_DEVNULL, O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ if (fd != -1) {
+ (void) dup2(fd, STDIN_FILENO);
+ (void) dup2(fd, STDOUT_FILENO);
+ (void) dup2(fd, STDERR_FILENO);
+ }
+
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, NULL);
+
+ /* Close fds so we don't leak anything. */
+ closefrom(STDERR_FILENO + 1);
+
+ if (pipe(pfd) == -1) {
+ mysyslog(LOG_ERR, _("unable to open pipe: %m"));
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to open pipe: %s",
+ strerror(errno));
+ sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
+ _exit(1);
+ }
+
+ switch (pid = sudo_debug_fork()) {
+ case -1:
+ /* Error. */
+ mysyslog(LOG_ERR, _("unable to fork: %m"));
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to fork: %s",
+ strerror(errno));
+ sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
+ _exit(1);
+ break;
+ case 0:
+ {
+ char *last, *argv[MAX_MAILFLAGS + 1];
+ char *mflags, *mpath = def_mailerpath;
+ int i;
+
+ /* Child, set stdin to output side of the pipe */
+ if (pfd[0] != STDIN_FILENO) {
+ if (dup2(pfd[0], STDIN_FILENO) == -1) {
+ mysyslog(LOG_ERR, _("unable to dup stdin: %m"));
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "unable to dup stdin: %s", strerror(errno));
+ _exit(127);
+ }
+ (void) close(pfd[0]);
+ }
+ (void) close(pfd[1]);
+
+ /* Build up an argv based on the mailer path and flags */
+ if ((mflags = strdup(def_mailerflags)) == NULL) {
+ mysyslog(LOG_ERR, _("unable to allocate memory"));
+ _exit(127);
+ }
+ if ((argv[0] = strrchr(mpath, '/')))
+ argv[0]++;
+ else
+ argv[0] = mpath;
+
+ i = 1;
+ if ((p = strtok_r(mflags, " \t", &last))) {
+ do {
+ argv[i] = p;
+ } while (++i < MAX_MAILFLAGS && (p = strtok_r(NULL, " \t", &last)));
+ }
+ argv[i] = NULL;
+
+ /*
+ * Depending on the config, either run the mailer as root
+ * (so user cannot kill it) or as the user (for the paranoid).
+ */
+#ifndef NO_ROOT_MAILER
+ (void) set_perms(PERM_ROOT);
+ execve(mpath, argv, root_envp);
+#else
+ (void) set_perms(PERM_FULL_USER);
+ execv(mpath, argv);
+#endif /* NO_ROOT_MAILER */
+ mysyslog(LOG_ERR, _("unable to execute %s: %m"), mpath);
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to execute %s: %s",
+ mpath, strerror(errno));
+ _exit(127);
+ }
+ break;
+ }
+
+ (void) close(pfd[0]);
+ mail = fdopen(pfd[1], "w");
+
+ /* Pipes are all setup, send message. */
+ (void) fprintf(mail, "To: %s\nFrom: %s\nAuto-Submitted: %s\nSubject: ",
+ def_mailto, def_mailfrom ? def_mailfrom : user_name, "auto-generated");
+ for (p = _(def_mailsub); *p; p++) {
+ /* Expand escapes in the subject */
+ if (*p == '%' && *(p+1) != '%') {
+ switch (*(++p)) {
+ case 'h':
+ (void) fputs(user_host, mail);
+ break;
+ case 'u':
+ (void) fputs(user_name, mail);
+ break;
+ default:
+ p--;
+ break;
+ }
+ } else
+ (void) fputc(*p, mail);
+ }
+
+#ifdef HAVE_NL_LANGINFO
+ if (strcmp(def_sudoers_locale, "C") != 0)
+ (void) fprintf(mail, "\nContent-Type: text/plain; charset=\"%s\"\nContent-Transfer-Encoding: 8bit", nl_langinfo(CODESET));
+#endif /* HAVE_NL_LANGINFO */
+
+ if ((timestr = get_timestr(time(NULL), def_log_year)) == NULL)
+ timestr = "invalid date";
+ (void) fprintf(mail, "\n\n%s : %s : %s : ", user_host, timestr, user_name);
+ va_start(ap, fmt);
+ (void) vfprintf(mail, fmt, ap);
+ va_end(ap);
+ fputs("\n\n", mail);
+
+ fclose(mail);
+ for (;;) {
+ rv = waitpid(pid, &status, 0);
+ if (rv == -1 && errno != EINTR)
+ break;
+ if (rv != -1 && !WIFSTOPPED(status))
+ break;
+ }
+ sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
+ _exit(0);
+}
+
+/*
+ * Determine whether we should send mail based on "status" and defaults options.
+ */
+static bool
+should_mail(int status)
+{
+ debug_decl(should_mail, SUDOERS_DEBUG_LOGGING)
+
+ debug_return_bool(def_mail_always || ISSET(status, VALIDATE_ERROR) ||
+ (def_mail_all_cmnds && ISSET(sudo_mode, (MODE_RUN|MODE_EDIT))) ||
+ (def_mail_no_user && ISSET(status, FLAG_NO_USER)) ||
+ (def_mail_no_host && ISSET(status, FLAG_NO_HOST)) ||
+ (def_mail_no_perms && !ISSET(status, VALIDATE_SUCCESS)));
+}
+
+#define LL_TTY_STR "TTY="
+#define LL_CWD_STR "PWD=" /* XXX - should be CWD= */
+#define LL_USER_STR "USER="
+#define LL_GROUP_STR "GROUP="
+#define LL_ENV_STR "ENV="
+#define LL_CMND_STR "COMMAND="
+#define LL_TSID_STR "TSID="
+
+#define IS_SESSID(s) ( \
+ isalnum((unsigned char)(s)[0]) && isalnum((unsigned char)(s)[1]) && \
+ (s)[2] == '/' && \
+ isalnum((unsigned char)(s)[3]) && isalnum((unsigned char)(s)[4]) && \
+ (s)[5] == '/' && \
+ isalnum((unsigned char)(s)[6]) && isalnum((unsigned char)(s)[7]) && \
+ (s)[8] == '\0')
+
+/*
+ * Allocate and fill in a new logline.
+ */
+static char *
+new_logline(const char *message, const char *errstr)
+{
+ char *line = NULL, *evstr = NULL;
+#ifndef SUDOERS_NO_SEQ
+ char sessid[7];
+#endif
+ const char *tsid = NULL;
+ size_t len = 0;
+ debug_decl(new_logline, SUDOERS_DEBUG_LOGGING)
+
+#ifndef SUDOERS_NO_SEQ
+ /* A TSID may be a sudoers-style session ID or a free-form string. */
+ if (sudo_user.iolog_file != NULL) {
+ if (IS_SESSID(sudo_user.iolog_file)) {
+ sessid[0] = sudo_user.iolog_file[0];
+ sessid[1] = sudo_user.iolog_file[1];
+ sessid[2] = sudo_user.iolog_file[3];
+ sessid[3] = sudo_user.iolog_file[4];
+ sessid[4] = sudo_user.iolog_file[6];
+ sessid[5] = sudo_user.iolog_file[7];
+ sessid[6] = '\0';
+ tsid = sessid;
+ } else {
+ tsid = sudo_user.iolog_file;
+ }
+ }
+#endif
+
+ /*
+ * Compute line length
+ */
+ if (message != NULL)
+ len += strlen(message) + 3;
+ if (errstr != NULL)
+ len += strlen(errstr) + 3;
+ len += sizeof(LL_TTY_STR) + 2 + strlen(user_tty);
+ len += sizeof(LL_CWD_STR) + 2 + strlen(user_cwd);
+ if (runas_pw != NULL)
+ len += sizeof(LL_USER_STR) + 2 + strlen(runas_pw->pw_name);
+ if (runas_gr != NULL)
+ len += sizeof(LL_GROUP_STR) + 2 + strlen(runas_gr->gr_name);
+ if (tsid != NULL)
+ len += sizeof(LL_TSID_STR) + 2 + strlen(tsid);
+ if (sudo_user.env_vars != NULL) {
+ size_t evlen = 0;
+ char * const *ep;
+
+ for (ep = sudo_user.env_vars; *ep != NULL; ep++)
+ evlen += strlen(*ep) + 1;
+ if (evlen != 0) {
+ if ((evstr = malloc(evlen)) == NULL)
+ goto oom;
+ evstr[0] = '\0';
+ for (ep = sudo_user.env_vars; *ep != NULL; ep++) {
+ strlcat(evstr, *ep, evlen);
+ strlcat(evstr, " ", evlen); /* NOTE: last one will fail */
+ }
+ len += sizeof(LL_ENV_STR) + 2 + evlen;
+ }
+ }
+ if (user_cmnd != NULL) {
+ /* Note: we log "sudo -l command arg ..." as "list command arg ..." */
+ len += sizeof(LL_CMND_STR) - 1 + strlen(user_cmnd);
+ if (ISSET(sudo_mode, MODE_CHECK))
+ len += sizeof("list ") - 1;
+ if (user_args != NULL)
+ len += strlen(user_args) + 1;
+ }
+
+ /*
+ * Allocate and build up the line.
+ */
+ if ((line = malloc(++len)) == NULL)
+ goto oom;
+ line[0] = '\0';
+
+ if (message != NULL) {
+ if (strlcat(line, message, len) >= len ||
+ strlcat(line, errstr ? " : " : " ; ", len) >= len)
+ goto toobig;
+ }
+ if (errstr != NULL) {
+ if (strlcat(line, errstr, len) >= len ||
+ strlcat(line, " ; ", len) >= len)
+ goto toobig;
+ }
+ if (strlcat(line, LL_TTY_STR, len) >= len ||
+ strlcat(line, user_tty, len) >= len ||
+ strlcat(line, " ; ", len) >= len)
+ goto toobig;
+ if (strlcat(line, LL_CWD_STR, len) >= len ||
+ strlcat(line, user_cwd, len) >= len ||
+ strlcat(line, " ; ", len) >= len)
+ goto toobig;
+ if (runas_pw != NULL) {
+ if (strlcat(line, LL_USER_STR, len) >= len ||
+ strlcat(line, runas_pw->pw_name, len) >= len ||
+ strlcat(line, " ; ", len) >= len)
+ goto toobig;
+ }
+ if (runas_gr != NULL) {
+ if (strlcat(line, LL_GROUP_STR, len) >= len ||
+ strlcat(line, runas_gr->gr_name, len) >= len ||
+ strlcat(line, " ; ", len) >= len)
+ goto toobig;
+ }
+ if (tsid != NULL) {
+ if (strlcat(line, LL_TSID_STR, len) >= len ||
+ strlcat(line, tsid, len) >= len ||
+ strlcat(line, " ; ", len) >= len)
+ goto toobig;
+ }
+ if (evstr != NULL) {
+ if (strlcat(line, LL_ENV_STR, len) >= len ||
+ strlcat(line, evstr, len) >= len ||
+ strlcat(line, " ; ", len) >= len)
+ goto toobig;
+ free(evstr);
+ evstr = NULL;
+ }
+ if (user_cmnd != NULL) {
+ if (strlcat(line, LL_CMND_STR, len) >= len)
+ goto toobig;
+ if (ISSET(sudo_mode, MODE_CHECK) && strlcat(line, "list ", len) >= len)
+ goto toobig;
+ if (strlcat(line, user_cmnd, len) >= len)
+ goto toobig;
+ if (user_args != NULL) {
+ if (strlcat(line, " ", len) >= len ||
+ strlcat(line, user_args, len) >= len)
+ goto toobig;
+ }
+ }
+
+ debug_return_str(line);
+oom:
+ free(evstr);
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_str(NULL);
+toobig:
+ free(evstr);
+ free(line);
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ debug_return_str(NULL);
+}
diff --git a/plugins/sudoers/logging.h b/plugins/sudoers/logging.h
new file mode 100644
index 0000000..c7e99ae
--- /dev/null
+++ b/plugins/sudoers/logging.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1999-2005, 2009-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_LOGGING_H
+#define SUDOERS_LOGGING_H
+
+#ifdef __STDC__
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+/*
+ * Values for sudoers_setlocale()
+ */
+#define SUDOERS_LOCALE_USER 0
+#define SUDOERS_LOCALE_SUDOERS 1
+
+/* Logging types */
+#define SLOG_SYSLOG 0x01
+#define SLOG_FILE 0x02
+#define SLOG_BOTH 0x03
+
+/* Flags for log_warning()/log_warningx() */
+#define SLOG_USE_ERRNO 0x01 /* internal use only */
+#define SLOG_GAI_ERRNO 0x02 /* internal use only */
+#define SLOG_RAW_MSG 0x04 /* do not format msg before logging */
+#define SLOG_SEND_MAIL 0x08 /* log via mail */
+#define SLOG_NO_STDERR 0x10 /* do not log via stderr */
+#define SLOG_NO_LOG 0x20 /* do not log via file or syslog */
+
+/*
+ * Maximum number of characters to log per entry. The syslogger
+ * will log this much, after that, it truncates the log line.
+ * We need this here to make sure that we continue with another
+ * syslog(3) call if the internal buffer is more than 1023 characters.
+ */
+#ifndef MAXSYSLOGLEN
+# define MAXSYSLOGLEN 960
+#endif
+
+/*
+ * Indentation level for file-based logs when word wrap is enabled.
+ */
+#define LOG_INDENT " "
+
+/* XXX - needed for auditing */
+extern int NewArgc;
+extern char **NewArgv;
+
+union sudo_defs_val;
+
+bool sudoers_warn_setlocale(bool restore, int *cookie);
+bool sudoers_setlocale(int newlocale, int *prevlocale);
+int sudoers_getlocale(void);
+int audit_success(int argc, char *argv[]);
+int audit_failure(int argc, char *argv[], char const *const fmt, ...) __printflike(3, 4);
+bool log_allowed(int status);
+bool log_auth_failure(int status, unsigned int tries);
+bool log_denial(int status, bool inform_user);
+bool log_failure(int status, int flags);
+bool log_warning(int flags, const char *fmt, ...) __printflike(2, 3);
+bool log_warningx(int flags, const char *fmt, ...) __printflike(2, 3);
+bool gai_log_warning(int flags, int errnum, const char *fmt, ...) __printflike(3, 4);
+bool sudoers_initlocale(const char *ulocale, const char *slocale);
+bool sudoers_locale_callback(const union sudo_defs_val *);
+int writeln_wrap(FILE *fp, char *line, size_t len, size_t maxlen);
+
+#endif /* SUDOERS_LOGGING_H */
diff --git a/plugins/sudoers/logwrap.c b/plugins/sudoers/logwrap.c
new file mode 100644
index 0000000..b10e465
--- /dev/null
+++ b/plugins/sudoers/logwrap.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2011, 2014-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "sudoers.h"
+
+int
+writeln_wrap(FILE *fp, char *line, size_t linelen, size_t maxlen)
+{
+ char *indent = "";
+ char *beg = line;
+ char *end;
+ int len, outlen = 0;
+ debug_decl(writeln_wrap, SUDOERS_DEBUG_LOGGING)
+
+ /*
+ * Print out line with word wrap around maxlen characters.
+ */
+ while (linelen > maxlen) {
+ end = beg + maxlen;
+ while (end != beg && *end != ' ')
+ end--;
+ if (beg == end) {
+ /* Unable to find word break within maxlen, look beyond. */
+ end = strchr(beg + maxlen, ' ');
+ if (end == NULL)
+ break; /* no word break */
+ }
+ len = fprintf(fp, "%s%.*s\n", indent, (int)(end - beg), beg);
+ if (len < 0)
+ debug_return_int(-1);
+ outlen += len;
+ while (*end == ' ')
+ end++;
+ linelen -= (end - beg);
+ beg = end;
+ if (indent[0] == '\0') {
+ indent = LOG_INDENT;
+ maxlen -= sizeof(LOG_INDENT) - 1;
+ }
+ }
+ /* Print remainder, if any. */
+ if (linelen) {
+ len = fprintf(fp, "%s%s\n", indent, beg);
+ if (len < 0)
+ debug_return_int(-1);
+ outlen += len;
+ }
+
+ debug_return_int(outlen);
+}
diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c
new file mode 100644
index 0000000..7c8e9d8
--- /dev/null
+++ b/plugins/sudoers/match.c
@@ -0,0 +1,1281 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_SYS_SYSTEMINFO_H
+# include <sys/systeminfo.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#include <unistd.h>
+#ifndef SUDOERS_NAME_MATCH
+# ifdef HAVE_GLOB
+# include <glob.h>
+# else
+# include "compat/glob.h"
+# endif /* HAVE_GLOB */
+#endif /* SUDOERS_NAME_MATCH */
+#ifdef HAVE_NETGROUP_H
+# include <netgroup.h>
+#else
+# include <netdb.h>
+#endif /* HAVE_NETGROUP_H */
+#include <dirent.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+
+#include "sudoers.h"
+#include <gram.h>
+
+#ifdef HAVE_FNMATCH
+# include <fnmatch.h>
+#else
+# include "compat/fnmatch.h"
+#endif /* HAVE_FNMATCH */
+
+#if !defined(O_EXEC) && defined(O_PATH)
+# define O_EXEC O_PATH
+#endif
+
+static struct member_list empty = TAILQ_HEAD_INITIALIZER(empty);
+
+static bool command_matches_dir(const char *sudoers_dir, size_t dlen, const struct command_digest *digest);
+#ifndef SUDOERS_NAME_MATCH
+static bool command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args, const struct command_digest *digest);
+#endif
+static bool command_matches_fnmatch(const char *sudoers_cmnd, const char *sudoers_args, const struct command_digest *digest);
+static bool command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const struct command_digest *digest);
+static bool digest_matches(int fd, const char *file, const struct command_digest *digest);
+
+/*
+ * Returns true if string 's' contains meta characters.
+ */
+#define has_meta(s) (strpbrk(s, "\\?*[]") != NULL)
+
+/*
+ * Check whether user described by pw matches member.
+ * Returns ALLOW, DENY or UNSPEC.
+ */
+int
+user_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
+ const struct member *m)
+{
+ struct alias *a;
+ int matched = UNSPEC;
+ debug_decl(user_matches, SUDOERS_DEBUG_MATCH)
+
+ switch (m->type) {
+ case ALL:
+ matched = !m->negated;
+ break;
+ case NETGROUP:
+ if (netgr_matches(m->name,
+ def_netgroup_tuple ? user_runhost : NULL,
+ def_netgroup_tuple ? user_srunhost : NULL, pw->pw_name))
+ matched = !m->negated;
+ break;
+ case USERGROUP:
+ if (usergr_matches(m->name, pw->pw_name, pw))
+ matched = !m->negated;
+ break;
+ case ALIAS:
+ if ((a = alias_get(parse_tree, m->name, USERALIAS)) != NULL) {
+ /* XXX */
+ int rc = userlist_matches(parse_tree, pw, &a->members);
+ if (rc != UNSPEC)
+ matched = m->negated ? !rc : rc;
+ alias_put(a);
+ break;
+ }
+ /* FALLTHROUGH */
+ case WORD:
+ if (userpw_matches(m->name, pw->pw_name, pw))
+ matched = !m->negated;
+ break;
+ }
+ debug_return_int(matched);
+}
+
+/*
+ * Check for user described by pw in a list of members.
+ * Returns ALLOW, DENY or UNSPEC.
+ */
+int
+userlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
+ const struct member_list *list)
+{
+ struct member *m;
+ int matched = UNSPEC;
+ debug_decl(userlist_matches, SUDOERS_DEBUG_MATCH)
+
+ TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
+ if ((matched = user_matches(parse_tree, pw, m)) != UNSPEC)
+ break;
+ }
+ debug_return_int(matched);
+}
+
+struct gid_list *
+runas_getgroups(void)
+{
+ const struct passwd *pw;
+ debug_decl(runas_getgroups, SUDOERS_DEBUG_MATCH)
+
+ if (def_preserve_groups) {
+ sudo_gidlist_addref(user_gid_list);
+ debug_return_ptr(user_gid_list);
+ }
+
+ /* Only use results from a group db query, not the front end. */
+ pw = runas_pw ? runas_pw : sudo_user.pw;
+ debug_return_ptr(sudo_get_gidlist(pw, ENTRY_TYPE_QUERIED));
+}
+
+/*
+ * Check for user described by pw in a list of members.
+ * If both lists are empty compare against def_runas_default.
+ * Returns ALLOW, DENY or UNSPEC.
+ */
+int
+runaslist_matches(struct sudoers_parse_tree *parse_tree,
+ const struct member_list *user_list, const struct member_list *group_list,
+ struct member **matching_user, struct member **matching_group)
+{
+ struct member *m;
+ struct alias *a;
+ int rc;
+ int user_matched = UNSPEC;
+ int group_matched = UNSPEC;
+ debug_decl(runaslist_matches, SUDOERS_DEBUG_MATCH)
+
+ if (ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED) || !ISSET(sudo_user.flags, RUNAS_GROUP_SPECIFIED)) {
+ /* If no runas user or runas group listed in sudoers, use default. */
+ if (user_list == NULL && group_list == NULL) {
+ debug_return_int(userpw_matches(def_runas_default,
+ runas_pw->pw_name, runas_pw));
+ }
+
+ if (user_list != NULL) {
+ TAILQ_FOREACH_REVERSE(m, user_list, member_list, entries) {
+ switch (m->type) {
+ case ALL:
+ user_matched = !m->negated;
+ break;
+ case NETGROUP:
+ if (netgr_matches(m->name,
+ def_netgroup_tuple ? user_runhost : NULL,
+ def_netgroup_tuple ? user_srunhost : NULL,
+ runas_pw->pw_name))
+ user_matched = !m->negated;
+ break;
+ case USERGROUP:
+ if (usergr_matches(m->name, runas_pw->pw_name, runas_pw))
+ user_matched = !m->negated;
+ break;
+ case ALIAS:
+ a = alias_get(parse_tree, m->name, RUNASALIAS);
+ if (a != NULL) {
+ rc = runaslist_matches(parse_tree, &a->members,
+ &empty, matching_user, NULL);
+ if (rc != UNSPEC)
+ user_matched = m->negated ? !rc : rc;
+ alias_put(a);
+ break;
+ }
+ /* FALLTHROUGH */
+ case WORD:
+ if (userpw_matches(m->name, runas_pw->pw_name, runas_pw))
+ user_matched = !m->negated;
+ break;
+ case MYSELF:
+ if (!ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED) ||
+ strcmp(user_name, runas_pw->pw_name) == 0)
+ user_matched = !m->negated;
+ break;
+ }
+ if (user_matched != UNSPEC) {
+ if (matching_user != NULL && m->type != ALIAS)
+ *matching_user = m;
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * Skip checking runas group if none was specified.
+ */
+ if (ISSET(sudo_user.flags, RUNAS_GROUP_SPECIFIED)) {
+ if (user_matched == UNSPEC) {
+ if (strcmp(user_name, runas_pw->pw_name) == 0)
+ user_matched = ALLOW; /* only changing group */
+ }
+ if (group_list != NULL) {
+ TAILQ_FOREACH_REVERSE(m, group_list, member_list, entries) {
+ switch (m->type) {
+ case ALL:
+ group_matched = !m->negated;
+ break;
+ case ALIAS:
+ a = alias_get(parse_tree, m->name, RUNASALIAS);
+ if (a != NULL) {
+ rc = runaslist_matches(parse_tree, &empty,
+ &a->members, NULL, matching_group);
+ if (rc != UNSPEC)
+ group_matched = m->negated ? !rc : rc;
+ alias_put(a);
+ break;
+ }
+ /* FALLTHROUGH */
+ case WORD:
+ if (group_matches(m->name, runas_gr))
+ group_matched = !m->negated;
+ break;
+ }
+ if (group_matched != UNSPEC) {
+ if (matching_group != NULL && m->type != ALIAS)
+ *matching_group = m;
+ break;
+ }
+ }
+ }
+ if (group_matched == UNSPEC) {
+ struct gid_list *runas_groups;
+ /*
+ * The runas group was not explicitly allowed by sudoers.
+ * Check whether it is one of the target user's groups.
+ */
+ if (runas_pw->pw_gid == runas_gr->gr_gid) {
+ group_matched = ALLOW; /* runas group matches passwd db */
+ } else if ((runas_groups = runas_getgroups()) != NULL) {
+ int i;
+
+ for (i = 0; i < runas_groups->ngids; i++) {
+ if (runas_groups->gids[i] == runas_gr->gr_gid) {
+ group_matched = ALLOW; /* matched aux group vector */
+ break;
+ }
+ }
+ sudo_gidlist_delref(runas_groups);
+ }
+ }
+ }
+
+ if (user_matched == DENY || group_matched == DENY)
+ debug_return_int(DENY);
+ if (user_matched == group_matched || runas_gr == NULL)
+ debug_return_int(user_matched);
+ debug_return_int(UNSPEC);
+}
+
+/*
+ * Check for lhost and shost in a list of members.
+ * Returns ALLOW, DENY or UNSPEC.
+ */
+static int
+hostlist_matches_int(struct sudoers_parse_tree *parse_tree,
+ const struct passwd *pw, const char *lhost, const char *shost,
+ const struct member_list *list)
+{
+ struct member *m;
+ int matched = UNSPEC;
+ debug_decl(hostlist_matches, SUDOERS_DEBUG_MATCH)
+
+ TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
+ matched = host_matches(parse_tree, pw, lhost, shost, m);
+ if (matched != UNSPEC)
+ break;
+ }
+ debug_return_int(matched);
+}
+
+/*
+ * Check for user_runhost and user_srunhost in a list of members.
+ * Returns ALLOW, DENY or UNSPEC.
+ */
+int
+hostlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
+ const struct member_list *list)
+{
+ return hostlist_matches_int(parse_tree, pw, user_runhost, user_srunhost, list);
+}
+
+/*
+ * Check whether host or shost matches member.
+ * Returns ALLOW, DENY or UNSPEC.
+ */
+int
+host_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
+ const char *lhost, const char *shost, const struct member *m)
+{
+ struct alias *a;
+ int matched = UNSPEC;
+ debug_decl(host_matches, SUDOERS_DEBUG_MATCH)
+
+ switch (m->type) {
+ case ALL:
+ matched = !m->negated;
+ break;
+ case NETGROUP:
+ if (netgr_matches(m->name, lhost, shost,
+ def_netgroup_tuple ? pw->pw_name : NULL))
+ matched = !m->negated;
+ break;
+ case NTWKADDR:
+ if (addr_matches(m->name))
+ matched = !m->negated;
+ break;
+ case ALIAS:
+ a = alias_get(parse_tree, m->name, HOSTALIAS);
+ if (a != NULL) {
+ /* XXX */
+ int rc = hostlist_matches_int(parse_tree, pw, lhost, shost,
+ &a->members);
+ if (rc != UNSPEC)
+ matched = m->negated ? !rc : rc;
+ alias_put(a);
+ break;
+ }
+ /* FALLTHROUGH */
+ case WORD:
+ if (hostname_matches(shost, lhost, m->name))
+ matched = !m->negated;
+ break;
+ }
+ debug_return_int(matched);
+}
+
+/*
+ * Check for cmnd and args in a list of members.
+ * Returns ALLOW, DENY or UNSPEC.
+ */
+int
+cmndlist_matches(struct sudoers_parse_tree *parse_tree,
+ const struct member_list *list)
+{
+ struct member *m;
+ int matched = UNSPEC;
+ debug_decl(cmndlist_matches, SUDOERS_DEBUG_MATCH)
+
+ TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
+ matched = cmnd_matches(parse_tree, m);
+ if (matched != UNSPEC)
+ break;
+ }
+ debug_return_int(matched);
+}
+
+/*
+ * Check cmnd and args.
+ * Returns ALLOW, DENY or UNSPEC.
+ */
+int
+cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m)
+{
+ struct alias *a;
+ struct sudo_command *c;
+ int rc, matched = UNSPEC;
+ debug_decl(cmnd_matches, SUDOERS_DEBUG_MATCH)
+
+ switch (m->type) {
+ case ALL:
+ matched = !m->negated;
+ break;
+ case ALIAS:
+ a = alias_get(parse_tree, m->name, CMNDALIAS);
+ if (a != NULL) {
+ rc = cmndlist_matches(parse_tree, &a->members);
+ if (rc != UNSPEC)
+ matched = m->negated ? !rc : rc;
+ alias_put(a);
+ }
+ break;
+ case COMMAND:
+ c = (struct sudo_command *)m->name;
+ if (command_matches(c->cmnd, c->args, c->digest))
+ matched = !m->negated;
+ break;
+ }
+ debug_return_int(matched);
+}
+
+static bool
+command_args_match(const char *sudoers_cmnd, const char *sudoers_args)
+{
+ int flags = 0;
+ debug_decl(command_args_match, SUDOERS_DEBUG_MATCH)
+
+ /*
+ * If no args specified in sudoers, any user args are allowed.
+ * If the empty string is specified in sudoers, no user args are allowed.
+ */
+ if (!sudoers_args || (!user_args && !strcmp("\"\"", sudoers_args)))
+ debug_return_bool(true);
+
+ /*
+ * If args are specified in sudoers, they must match the user args.
+ * If running as sudoedit, all args are assumed to be paths.
+ */
+ if (strcmp(sudoers_cmnd, "sudoedit") == 0)
+ flags = FNM_PATHNAME;
+ if (fnmatch(sudoers_args, user_args ? user_args : "", flags) == 0)
+ debug_return_bool(true);
+
+ debug_return_bool(false);
+}
+
+/*
+ * If path doesn't end in /, return true iff cmnd & path name the same inode;
+ * otherwise, return true if user_cmnd names one of the inodes in path.
+ */
+bool
+command_matches(const char *sudoers_cmnd, const char *sudoers_args, const struct command_digest *digest)
+{
+ bool rc = false;
+ debug_decl(command_matches, SUDOERS_DEBUG_MATCH)
+
+ /* Check for pseudo-commands */
+ if (sudoers_cmnd[0] != '/') {
+ /*
+ * Return true if both sudoers_cmnd and user_cmnd are "sudoedit" AND
+ * a) there are no args in sudoers OR
+ * b) there are no args on command line and none req by sudoers OR
+ * c) there are args in sudoers and on command line and they match
+ */
+ if (strcmp(sudoers_cmnd, "sudoedit") == 0 &&
+ strcmp(user_cmnd, "sudoedit") == 0 &&
+ command_args_match(sudoers_cmnd, sudoers_args)) {
+ /* No need to set safe_cmnd since user_cmnd matches sudoers_cmnd */
+ rc = true;
+ }
+ goto done;
+ }
+
+ if (has_meta(sudoers_cmnd)) {
+ /*
+ * If sudoers_cmnd has meta characters in it, we need to
+ * use glob(3) and/or fnmatch(3) to do the matching.
+ */
+#ifdef SUDOERS_NAME_MATCH
+ rc = command_matches_fnmatch(sudoers_cmnd, sudoers_args, digest);
+#else
+ if (def_fast_glob)
+ rc = command_matches_fnmatch(sudoers_cmnd, sudoers_args, digest);
+ else
+ rc = command_matches_glob(sudoers_cmnd, sudoers_args, digest);
+#endif
+ } else {
+ rc = command_matches_normal(sudoers_cmnd, sudoers_args, digest);
+ }
+done:
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "user command \"%s%s%s\" matches sudoers command \"%s%s%s\": %s",
+ user_cmnd, user_args ? " " : "", user_args ? user_args : "",
+ sudoers_cmnd, sudoers_args ? " " : "", sudoers_args ? sudoers_args : "",
+ rc ? "true" : "false");
+ debug_return_bool(rc);
+}
+
+/*
+ * Stat file by fd is possible, else by path.
+ * Returns true on success, else false.
+ */
+static bool
+do_stat(int fd, const char *path, struct stat *sb)
+{
+ debug_decl(do_stat, SUDOERS_DEBUG_MATCH)
+
+ if (fd != -1)
+ debug_return_bool(fstat(fd, sb) == 0);
+ debug_return_bool(stat(path, sb) == 0);
+}
+
+/*
+ * Check whether the fd refers to a shell script with a "#!" shebang.
+ */
+static bool
+is_script(int fd)
+{
+ bool ret = false;
+ char magic[2];
+ debug_decl(is_script, SUDOERS_DEBUG_MATCH)
+
+ if (read(fd, magic, 2) == 2) {
+ if (magic[0] == '#' && magic[1] == '!')
+ ret = true;
+ }
+ if (lseek(fd, (off_t)0, SEEK_SET) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "unable to rewind script fd");
+ }
+ debug_return_int(ret);
+}
+
+/*
+ * Open path if fdexec is enabled or if a digest is present.
+ * Returns false on error, else true.
+ */
+static bool
+open_cmnd(const char *path, const struct command_digest *digest, int *fdp)
+{
+ int fd = -1;
+ debug_decl(open_cmnd, SUDOERS_DEBUG_MATCH)
+
+ /* Only open the file for fdexec or for digest matching. */
+ if (def_fdexec != always && digest == NULL)
+ debug_return_bool(true);
+
+ fd = open(path, O_RDONLY|O_NONBLOCK);
+# ifdef O_EXEC
+ if (fd == -1 && errno == EACCES && digest == NULL) {
+ /* Try again with O_EXEC if no digest is specified. */
+ const int saved_errno = errno;
+ if ((fd = open(path, O_EXEC)) == -1)
+ errno = saved_errno;
+ }
+# endif
+ if (fd == -1)
+ debug_return_bool(false);
+
+ (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
+ *fdp = fd;
+ debug_return_bool(true);
+}
+
+static void
+set_cmnd_fd(int fd)
+{
+ debug_decl(set_cmnd_fd, SUDOERS_DEBUG_MATCH)
+
+ if (cmnd_fd != -1)
+ close(cmnd_fd);
+
+ if (fd != -1) {
+ if (def_fdexec == never) {
+ /* Never use fexedcve() */
+ close(fd);
+ fd = -1;
+ } else if (is_script(fd)) {
+ char fdpath[PATH_MAX];
+ struct stat sb;
+ int flags;
+
+ /* We can only use fexecve() on a script if /dev/fd/N exists. */
+ snprintf(fdpath, sizeof(fdpath), "/dev/fd/%d", fd);
+ if (stat(fdpath, &sb) != 0) {
+ /* Missing /dev/fd file, can't use fexecve(). */
+ close(fd);
+ fd = -1;
+ } else {
+ /*
+ * Shell scripts go through namei twice so we can't have the
+ * close on exec flag set on the fd for fexecve(2).
+ */
+ flags = fcntl(fd, F_GETFD) & ~FD_CLOEXEC;
+ (void)fcntl(fd, F_SETFD, flags);
+ }
+ }
+ }
+
+ cmnd_fd = fd;
+
+ debug_return;
+}
+
+static bool
+command_matches_fnmatch(const char *sudoers_cmnd, const char *sudoers_args,
+ const struct command_digest *digest)
+{
+ struct stat sb; /* XXX - unused */
+ int fd = -1;
+ debug_decl(command_matches_fnmatch, SUDOERS_DEBUG_MATCH)
+
+ /*
+ * Return true if fnmatch(3) succeeds AND
+ * a) there are no args in sudoers OR
+ * b) there are no args on command line and none required by sudoers OR
+ * c) there are args in sudoers and on command line and they match
+ * else return false.
+ */
+ if (fnmatch(sudoers_cmnd, user_cmnd, FNM_PATHNAME) != 0)
+ debug_return_bool(false);
+ if (command_args_match(sudoers_cmnd, sudoers_args)) {
+ /* Open the file for fdexec or for digest matching. */
+ if (!open_cmnd(user_cmnd, digest, &fd))
+ goto bad;
+ if (!do_stat(fd, user_cmnd, &sb))
+ goto bad;
+ /* Check digest of user_cmnd since sudoers_cmnd is a pattern. */
+ if (digest != NULL && !digest_matches(fd, user_cmnd, digest))
+ goto bad;
+ set_cmnd_fd(fd);
+
+ /* No need to set safe_cmnd since user_cmnd matches sudoers_cmnd */
+ debug_return_bool(true);
+bad:
+ if (fd != -1) {
+ close(fd);
+ fd = -1;
+ }
+ debug_return_bool(false);
+ }
+ debug_return_bool(false);
+}
+
+#ifndef SUDOERS_NAME_MATCH
+static bool
+command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
+ const struct command_digest *digest)
+{
+ struct stat sudoers_stat;
+ bool bad_digest = false;
+ char **ap, *base, *cp;
+ int fd = -1;
+ size_t dlen;
+ glob_t gl;
+ debug_decl(command_matches_glob, SUDOERS_DEBUG_MATCH)
+
+ /*
+ * First check to see if we can avoid the call to glob(3).
+ * Short circuit if there are no meta chars in the command itself
+ * and user_base and basename(sudoers_cmnd) don't match.
+ */
+ dlen = strlen(sudoers_cmnd);
+ if (sudoers_cmnd[dlen - 1] != '/') {
+ if ((base = strrchr(sudoers_cmnd, '/')) != NULL) {
+ base++;
+ if (!has_meta(base) && strcmp(user_base, base) != 0)
+ debug_return_bool(false);
+ }
+ }
+ /*
+ * Return true if we find a match in the glob(3) results AND
+ * a) there are no args in sudoers OR
+ * b) there are no args on command line and none required by sudoers OR
+ * c) there are args in sudoers and on command line and they match
+ * else return false.
+ */
+ if (glob(sudoers_cmnd, GLOB_NOSORT, NULL, &gl) != 0 || gl.gl_pathc == 0) {
+ globfree(&gl);
+ debug_return_bool(false);
+ }
+ /* If user_cmnd is fully-qualified, check for an exact match. */
+ if (user_cmnd[0] == '/') {
+ for (ap = gl.gl_pathv; (cp = *ap) != NULL; ap++) {
+ if (fd != -1) {
+ close(fd);
+ fd = -1;
+ }
+ if (strcmp(cp, user_cmnd) != 0)
+ continue;
+ /* Open the file for fdexec or for digest matching. */
+ if (!open_cmnd(cp, digest, &fd))
+ continue;
+ if (!do_stat(fd, cp, &sudoers_stat))
+ continue;
+ if (user_stat == NULL ||
+ (user_stat->st_dev == sudoers_stat.st_dev &&
+ user_stat->st_ino == sudoers_stat.st_ino)) {
+ /* There could be multiple matches, check digest early. */
+ if (digest != NULL && !digest_matches(fd, cp, digest)) {
+ bad_digest = true;
+ continue;
+ }
+ free(safe_cmnd);
+ if ((safe_cmnd = strdup(cp)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ cp = NULL; /* fail closed */
+ }
+ } else {
+ /* Paths match, but st_dev and st_ino are different. */
+ cp = NULL; /* fail closed */
+ }
+ goto done;
+ }
+ }
+ /* No exact match, compare basename, st_dev and st_ino. */
+ if (!bad_digest) {
+ for (ap = gl.gl_pathv; (cp = *ap) != NULL; ap++) {
+ if (fd != -1) {
+ close(fd);
+ fd = -1;
+ }
+
+ /* If it ends in '/' it is a directory spec. */
+ dlen = strlen(cp);
+ if (cp[dlen - 1] == '/') {
+ if (command_matches_dir(cp, dlen, digest))
+ debug_return_bool(true);
+ continue;
+ }
+
+ /* Only proceed if user_base and basename(cp) match */
+ if ((base = strrchr(cp, '/')) != NULL)
+ base++;
+ else
+ base = cp;
+ if (strcmp(user_base, base) != 0)
+ continue;
+
+ /* Open the file for fdexec or for digest matching. */
+ if (!open_cmnd(cp, digest, &fd))
+ continue;
+ if (!do_stat(fd, cp, &sudoers_stat))
+ continue;
+ if (user_stat == NULL ||
+ (user_stat->st_dev == sudoers_stat.st_dev &&
+ user_stat->st_ino == sudoers_stat.st_ino)) {
+ if (digest != NULL && !digest_matches(fd, cp, digest))
+ continue;
+ free(safe_cmnd);
+ if ((safe_cmnd = strdup(cp)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ cp = NULL; /* fail closed */
+ }
+ goto done;
+ }
+ }
+ }
+done:
+ globfree(&gl);
+ if (cp != NULL) {
+ if (command_args_match(sudoers_cmnd, sudoers_args)) {
+ /* safe_cmnd was set above. */
+ set_cmnd_fd(fd);
+ debug_return_bool(true);
+ }
+ }
+ if (fd != -1)
+ close(fd);
+ debug_return_bool(false);
+}
+#endif /* SUDOERS_NAME_MATCH */
+
+#ifdef SUDOERS_NAME_MATCH
+static bool
+command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const struct command_digest *digest)
+{
+ size_t dlen;
+ debug_decl(command_matches_normal, SUDOERS_DEBUG_MATCH)
+
+ dlen = strlen(sudoers_cmnd);
+
+ /* If it ends in '/' it is a directory spec. */
+ if (sudoers_cmnd[dlen - 1] == '/')
+ debug_return_bool(command_matches_dir(sudoers_cmnd, dlen, digest));
+
+ if (strcmp(user_cmnd, sudoers_cmnd) == 0) {
+ if (command_args_match(sudoers_cmnd, sudoers_args)) {
+ /* XXX - check digest */
+ free(safe_cmnd);
+ if ((safe_cmnd = strdup(sudoers_cmnd)) != NULL)
+ debug_return_bool(true);
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ }
+ }
+ debug_return_bool(false);
+}
+#else /* !SUDOERS_NAME_MATCH */
+
+static bool
+digest_matches(int fd, const char *file, const struct command_digest *digest)
+{
+ unsigned char *file_digest = NULL;
+ unsigned char *sudoers_digest = NULL;
+ bool matched = false;
+ size_t digest_len;
+ debug_decl(digest_matches, SUDOERS_DEBUG_MATCH)
+
+ file_digest = sudo_filedigest(fd, file, digest->digest_type, &digest_len);
+ if (lseek(fd, (off_t)0, SEEK_SET) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "unable to rewind digest fd");
+ }
+ if (file_digest == NULL) {
+ /* Warning (if any) printed by sudo_filedigest() */
+ goto done;
+ }
+
+ /* Convert the command digest from ascii to binary. */
+ if ((sudoers_digest = malloc(digest_len)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ if (strlen(digest->digest_str) == digest_len * 2) {
+ /* Convert ascii hex to binary. */
+ unsigned int i;
+ for (i = 0; i < digest_len; i++) {
+ const int h = hexchar(&digest->digest_str[i + i]);
+ if (h == -1)
+ goto bad_format;
+ sudoers_digest[i] = (unsigned char)h;
+ }
+ } else {
+ /* Convert base64 to binary. */
+ size_t len = base64_decode(digest->digest_str, sudoers_digest, digest_len);
+ if (len != digest_len) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "incorrect length for digest, expected %zu, got %zu",
+ digest_len, len);
+ goto bad_format;
+ }
+ }
+
+ if (memcmp(file_digest, sudoers_digest, digest_len) == 0) {
+ matched = true;
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_DIAG|SUDO_DEBUG_LINENO,
+ "%s digest mismatch for %s, expecting %s",
+ digest_type_to_name(digest->digest_type), file, digest->digest_str);
+ }
+ goto done;
+
+bad_format:
+ sudo_warnx(U_("digest for %s (%s) is not in %s form"), file,
+ digest->digest_str, digest_type_to_name(digest->digest_type));
+done:
+ free(sudoers_digest);
+ free(file_digest);
+ debug_return_bool(matched);
+}
+
+static bool
+command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const struct command_digest *digest)
+{
+ struct stat sudoers_stat;
+ const char *base;
+ size_t dlen;
+ int fd = -1;
+ debug_decl(command_matches_normal, SUDOERS_DEBUG_MATCH)
+
+ /* If it ends in '/' it is a directory spec. */
+ dlen = strlen(sudoers_cmnd);
+ if (sudoers_cmnd[dlen - 1] == '/')
+ debug_return_bool(command_matches_dir(sudoers_cmnd, dlen, digest));
+
+ /* Only proceed if user_base and basename(sudoers_cmnd) match */
+ if ((base = strrchr(sudoers_cmnd, '/')) == NULL)
+ base = sudoers_cmnd;
+ else
+ base++;
+ if (strcmp(user_base, base) != 0)
+ debug_return_bool(false);
+
+ /* Open the file for fdexec or for digest matching. */
+ if (!open_cmnd(sudoers_cmnd, digest, &fd))
+ goto bad;
+ if (!do_stat(fd, sudoers_cmnd, &sudoers_stat))
+ goto bad;
+
+ /*
+ * Return true if inode/device matches AND
+ * a) there are no args in sudoers OR
+ * b) there are no args on command line and none req by sudoers OR
+ * c) there are args in sudoers and on command line and they match
+ * d) there is a digest and it matches
+ */
+ if (user_stat != NULL &&
+ (user_stat->st_dev != sudoers_stat.st_dev ||
+ user_stat->st_ino != sudoers_stat.st_ino))
+ goto bad;
+ if (!command_args_match(sudoers_cmnd, sudoers_args))
+ goto bad;
+ if (digest != NULL && !digest_matches(fd, sudoers_cmnd, digest)) {
+ /* XXX - log functions not available but we should log very loudly */
+ goto bad;
+ }
+ free(safe_cmnd);
+ if ((safe_cmnd = strdup(sudoers_cmnd)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto bad;
+ }
+ set_cmnd_fd(fd);
+ debug_return_bool(true);
+bad:
+ if (fd != -1)
+ close(fd);
+ debug_return_bool(false);
+}
+#endif /* SUDOERS_NAME_MATCH */
+
+#ifdef SUDOERS_NAME_MATCH
+/*
+ * Return true if user_cmnd begins with sudoers_dir, else false.
+ * Note that sudoers_dir include the trailing '/'
+ */
+static bool
+command_matches_dir(const char *sudoers_dir, size_t dlen,
+ const struct command_digest *digest)
+{
+ debug_decl(command_matches_dir, SUDOERS_DEBUG_MATCH)
+ /* XXX - check digest */
+ debug_return_bool(strncmp(user_cmnd, sudoers_dir, dlen) == 0);
+}
+#else /* !SUDOERS_NAME_MATCH */
+/*
+ * Return true if user_cmnd names one of the inodes in dir, else false.
+ */
+static bool
+command_matches_dir(const char *sudoers_dir, size_t dlen,
+ const struct command_digest *digest)
+{
+ struct stat sudoers_stat;
+ struct dirent *dent;
+ char buf[PATH_MAX];
+ int fd = -1;
+ DIR *dirp;
+ debug_decl(command_matches_dir, SUDOERS_DEBUG_MATCH)
+
+ /*
+ * Grot through directory entries, looking for user_base.
+ */
+ dirp = opendir(sudoers_dir);
+ if (dirp == NULL)
+ debug_return_bool(false);
+
+ if (strlcpy(buf, sudoers_dir, sizeof(buf)) >= sizeof(buf)) {
+ closedir(dirp);
+ debug_return_bool(false);
+ }
+ while ((dent = readdir(dirp)) != NULL) {
+ if (fd != -1) {
+ close(fd);
+ fd = -1;
+ }
+
+ /* ignore paths > PATH_MAX (XXX - log) */
+ buf[dlen] = '\0';
+ if (strlcat(buf, dent->d_name, sizeof(buf)) >= sizeof(buf))
+ continue;
+
+ /* only stat if basenames are the same */
+ if (strcmp(user_base, dent->d_name) != 0)
+ continue;
+
+ /* Open the file for fdexec or for digest matching. */
+ if (!open_cmnd(buf, digest, &fd))
+ continue;
+ if (!do_stat(fd, buf, &sudoers_stat))
+ continue;
+
+ if (user_stat == NULL ||
+ (user_stat->st_dev == sudoers_stat.st_dev &&
+ user_stat->st_ino == sudoers_stat.st_ino)) {
+ if (digest != NULL && !digest_matches(fd, buf, digest))
+ continue;
+ free(safe_cmnd);
+ if ((safe_cmnd = strdup(buf)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ dent = NULL;
+ }
+ break;
+ }
+ }
+ closedir(dirp);
+
+ if (dent != NULL) {
+ set_cmnd_fd(fd);
+ debug_return_bool(true);
+ }
+ if (fd != -1)
+ close(fd);
+ debug_return_bool(false);
+}
+#endif /* SUDOERS_NAME_MATCH */
+
+/*
+ * Returns true if the hostname matches the pattern, else false
+ */
+bool
+hostname_matches(const char *shost, const char *lhost, const char *pattern)
+{
+ const char *host;
+ bool rc;
+ debug_decl(hostname_matches, SUDOERS_DEBUG_MATCH)
+
+ host = strchr(pattern, '.') != NULL ? lhost : shost;
+ if (has_meta(pattern)) {
+ rc = !fnmatch(pattern, host, FNM_CASEFOLD);
+ } else {
+ rc = !strcasecmp(host, pattern);
+ }
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "host %s matches sudoers pattern %s: %s",
+ host, pattern, rc ? "true" : "false");
+ debug_return_bool(rc);
+}
+
+/*
+ * Returns true if the user/uid from sudoers matches the specified user/uid,
+ * else returns false.
+ */
+bool
+userpw_matches(const char *sudoers_user, const char *user, const struct passwd *pw)
+{
+ const char *errstr;
+ uid_t uid;
+ bool rc;
+ debug_decl(userpw_matches, SUDOERS_DEBUG_MATCH)
+
+ if (pw != NULL && *sudoers_user == '#') {
+ uid = (uid_t) sudo_strtoid(sudoers_user + 1, NULL, NULL, &errstr);
+ if (errstr == NULL && uid == pw->pw_uid) {
+ rc = true;
+ goto done;
+ }
+ }
+ if (def_case_insensitive_user)
+ rc = strcasecmp(sudoers_user, user) == 0;
+ else
+ rc = strcmp(sudoers_user, user) == 0;
+done:
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "user %s matches sudoers user %s: %s",
+ user, sudoers_user, rc ? "true" : "false");
+ debug_return_bool(rc);
+}
+
+/*
+ * Returns true if the group/gid from sudoers matches the specified group/gid,
+ * else returns false.
+ */
+bool
+group_matches(const char *sudoers_group, const struct group *gr)
+{
+ const char *errstr;
+ gid_t gid;
+ bool rc;
+ debug_decl(group_matches, SUDOERS_DEBUG_MATCH)
+
+ if (*sudoers_group == '#') {
+ gid = (gid_t) sudo_strtoid(sudoers_group + 1, NULL, NULL, &errstr);
+ if (errstr == NULL && gid == gr->gr_gid) {
+ rc = true;
+ goto done;
+ }
+ }
+ if (def_case_insensitive_group)
+ rc = strcasecmp(sudoers_group, gr->gr_name) == 0;
+ else
+ rc = strcmp(sudoers_group, gr->gr_name) == 0;
+done:
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "group %s matches sudoers group %s: %s",
+ gr->gr_name, sudoers_group, rc ? "true" : "false");
+ debug_return_bool(rc);
+}
+
+/*
+ * Returns true if the given user belongs to the named group,
+ * else returns false.
+ */
+bool
+usergr_matches(const char *group, const char *user, const struct passwd *pw)
+{
+ bool matched = false;
+ struct passwd *pw0 = NULL;
+ debug_decl(usergr_matches, SUDOERS_DEBUG_MATCH)
+
+ /* Make sure we have a valid usergroup, sudo style */
+ if (*group++ != '%') {
+ sudo_debug_printf(SUDO_DEBUG_DIAG, "user group %s has no leading '%%'",
+ group);
+ goto done;
+ }
+
+ /* Query group plugin for %:name groups. */
+ if (*group == ':' && def_group_plugin) {
+ if (group_plugin_query(user, group + 1, pw) == true)
+ matched = true;
+ goto done;
+ }
+
+ /* Look up user's primary gid in the passwd file. */
+ if (pw == NULL) {
+ if ((pw0 = sudo_getpwnam(user)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_DIAG, "unable to find %s in passwd db",
+ user);
+ goto done;
+ }
+ pw = pw0;
+ }
+
+ if (user_in_group(pw, group)) {
+ matched = true;
+ goto done;
+ }
+
+ /* Query the group plugin for Unix groups too? */
+ if (def_group_plugin && def_always_query_group_plugin) {
+ if (group_plugin_query(user, group, pw) == true) {
+ matched = true;
+ goto done;
+ }
+ }
+
+done:
+ if (pw0 != NULL)
+ sudo_pw_delref(pw0);
+
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "user %s matches group %s: %s", user, group, matched ? "true" : "false");
+ debug_return_bool(matched);
+}
+
+#if defined(HAVE_GETDOMAINNAME) || defined(SI_SRPC_DOMAIN)
+/*
+ * Check the domain for invalid characters.
+ * Linux getdomainname(2) returns (none) if no domain is set.
+ */
+static bool
+valid_domain(const char *domain)
+{
+ const char *cp;
+ debug_decl(valid_domain, SUDOERS_DEBUG_MATCH)
+
+ for (cp = domain; *cp != '\0'; cp++) {
+ /* Check for illegal characters, Linux may use "(none)". */
+ if (*cp == '(' || *cp == ')' || *cp == ',' || *cp == ' ')
+ break;
+ }
+ if (cp == domain || *cp != '\0')
+ debug_return_bool(false);
+ debug_return_bool(true);
+}
+
+/*
+ * Get NIS-style domain name and copy from static storage or NULL if none.
+ */
+const char *
+sudo_getdomainname(void)
+{
+ static char *domain;
+ static bool initialized;
+ debug_decl(sudo_getdomainname, SUDOERS_DEBUG_MATCH)
+
+ if (!initialized) {
+ size_t host_name_max;
+ int rc;
+
+# ifdef _SC_HOST_NAME_MAX
+ host_name_max = (size_t)sysconf(_SC_HOST_NAME_MAX);
+ if (host_name_max == (size_t)-1)
+# endif
+ host_name_max = 255; /* POSIX and historic BSD */
+
+ domain = malloc(host_name_max + 1);
+ if (domain != NULL) {
+ domain[0] = '\0';
+# ifdef SI_SRPC_DOMAIN
+ rc = sysinfo(SI_SRPC_DOMAIN, domain, host_name_max + 1);
+# else
+ rc = getdomainname(domain, host_name_max + 1);
+# endif
+ if (rc == -1 || !valid_domain(domain)) {
+ /* Error or invalid domain name. */
+ free(domain);
+ domain = NULL;
+ }
+ } else {
+ /* XXX - want to pass error back to caller */
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ }
+ initialized = true;
+ }
+ debug_return_str(domain);
+}
+#else
+const char *
+sudo_getdomainname(void)
+{
+ debug_decl(sudo_getdomainname, SUDOERS_DEBUG_MATCH)
+ debug_return_ptr(NULL);
+}
+#endif /* HAVE_GETDOMAINNAME || SI_SRPC_DOMAIN */
+
+/*
+ * Returns true if "host" and "user" belong to the netgroup "netgr",
+ * else return false. Either of "lhost", "shost" or "user" may be NULL
+ * in which case that argument is not checked...
+ */
+bool
+netgr_matches(const char *netgr, const char *lhost, const char *shost, const char *user)
+{
+#ifdef HAVE_INNETGR
+ const char *domain;
+#endif
+ bool rc = false;
+ debug_decl(netgr_matches, SUDOERS_DEBUG_MATCH)
+
+ if (!def_use_netgroups) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "netgroups are disabled");
+ debug_return_bool(false);
+ }
+
+#ifdef HAVE_INNETGR
+ /* make sure we have a valid netgroup, sudo style */
+ if (*netgr++ != '+') {
+ sudo_debug_printf(SUDO_DEBUG_DIAG, "netgroup %s has no leading '+'",
+ netgr);
+ debug_return_bool(false);
+ }
+
+ /* get the domain name (if any) */
+ domain = sudo_getdomainname();
+
+ if (innetgr(netgr, lhost, user, domain))
+ rc = true;
+ else if (lhost != shost && innetgr(netgr, shost, user, domain))
+ rc = true;
+
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "netgroup %s matches (%s|%s, %s, %s): %s", netgr, lhost ? lhost : "",
+ shost ? shost : "", user ? user : "", domain ? domain : "",
+ rc ? "true" : "false");
+#endif /* HAVE_INNETGR */
+
+ debug_return_bool(rc);
+}
diff --git a/plugins/sudoers/match_addr.c b/plugins/sudoers/match_addr.c
new file mode 100644
index 0000000..4310e05
--- /dev/null
+++ b/plugins/sudoers/match_addr.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#ifdef NEED_RESOLV_H
+# include <arpa/nameser.h>
+# include <resolv.h>
+#endif /* NEED_RESOLV_H */
+
+#include "sudoers.h"
+#include "interfaces.h"
+
+static bool
+addr_matches_if(const char *n)
+{
+ union sudo_in_addr_un addr;
+ struct interface *ifp;
+#ifdef HAVE_STRUCT_IN6_ADDR
+ unsigned int j;
+#endif
+ unsigned int family;
+ debug_decl(addr_matches_if, SUDOERS_DEBUG_MATCH)
+
+#ifdef HAVE_STRUCT_IN6_ADDR
+ if (inet_pton(AF_INET6, n, &addr.ip6) == 1) {
+ family = AF_INET6;
+ } else
+#endif /* HAVE_STRUCT_IN6_ADDR */
+ if (inet_pton(AF_INET, n, &addr.ip4) == 1) {
+ family = AF_INET;
+ } else {
+ debug_return_bool(false);
+ }
+
+ SLIST_FOREACH(ifp, get_interfaces(), entries) {
+ if (ifp->family != family)
+ continue;
+ switch (family) {
+ case AF_INET:
+ if (ifp->addr.ip4.s_addr == addr.ip4.s_addr ||
+ (ifp->addr.ip4.s_addr & ifp->netmask.ip4.s_addr)
+ == addr.ip4.s_addr)
+ debug_return_bool(true);
+ break;
+#ifdef HAVE_STRUCT_IN6_ADDR
+ case AF_INET6:
+ if (memcmp(ifp->addr.ip6.s6_addr, addr.ip6.s6_addr,
+ sizeof(addr.ip6.s6_addr)) == 0)
+ debug_return_bool(true);
+ for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) {
+ if ((ifp->addr.ip6.s6_addr[j] & ifp->netmask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j])
+ break;
+ }
+ if (j == sizeof(addr.ip6.s6_addr))
+ debug_return_bool(true);
+ break;
+#endif /* HAVE_STRUCT_IN6_ADDR */
+ }
+ }
+
+ debug_return_bool(false);
+}
+
+static bool
+addr_matches_if_netmask(const char *n, const char *m)
+{
+ unsigned int i;
+ union sudo_in_addr_un addr, mask;
+ struct interface *ifp;
+#ifdef HAVE_STRUCT_IN6_ADDR
+ unsigned int j;
+#endif
+ unsigned int family;
+ const char *errstr;
+ debug_decl(addr_matches_if, SUDOERS_DEBUG_MATCH)
+
+#ifdef HAVE_STRUCT_IN6_ADDR
+ if (inet_pton(AF_INET6, n, &addr.ip6) == 1)
+ family = AF_INET6;
+ else
+#endif /* HAVE_STRUCT_IN6_ADDR */
+ if (inet_pton(AF_INET, n, &addr.ip4) == 1) {
+ family = AF_INET;
+ } else {
+ debug_return_bool(false);
+ }
+
+ if (family == AF_INET) {
+ if (strchr(m, '.')) {
+ if (inet_pton(AF_INET, m, &mask.ip4) != 1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "IPv4 netmask %s: %s", m, "invalid value");
+ debug_return_bool(false);
+ }
+ } else {
+ i = strtonum(m, 1, 32, &errstr);
+ if (errstr != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "IPv4 netmask %s: %s", m, errstr);
+ debug_return_bool(false);
+ }
+ mask.ip4.s_addr = htonl(0xffffffffU << (32 - i));
+ }
+ addr.ip4.s_addr &= mask.ip4.s_addr;
+ }
+#ifdef HAVE_STRUCT_IN6_ADDR
+ else {
+ if (inet_pton(AF_INET6, m, &mask.ip6) != 1) {
+ j = strtonum(m, 1, 128, &errstr);
+ if (errstr != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "IPv6 netmask %s: %s", m, errstr);
+ debug_return_bool(false);
+ }
+ for (i = 0; i < sizeof(addr.ip6.s6_addr); i++) {
+ if (j < i * 8)
+ mask.ip6.s6_addr[i] = 0;
+ else if (i * 8 + 8 <= j)
+ mask.ip6.s6_addr[i] = 0xff;
+ else
+ mask.ip6.s6_addr[i] = 0xff00 >> (j - i * 8);
+ addr.ip6.s6_addr[i] &= mask.ip6.s6_addr[i];
+ }
+ }
+ }
+#endif /* HAVE_STRUCT_IN6_ADDR */
+
+ SLIST_FOREACH(ifp, get_interfaces(), entries) {
+ if (ifp->family != family)
+ continue;
+ switch (family) {
+ case AF_INET:
+ if ((ifp->addr.ip4.s_addr & mask.ip4.s_addr) == addr.ip4.s_addr)
+ debug_return_bool(true);
+ break;
+#ifdef HAVE_STRUCT_IN6_ADDR
+ case AF_INET6:
+ for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) {
+ if ((ifp->addr.ip6.s6_addr[j] & mask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j])
+ break;
+ }
+ if (j == sizeof(addr.ip6.s6_addr))
+ debug_return_bool(true);
+ break;
+#endif /* HAVE_STRUCT_IN6_ADDR */
+ }
+ }
+
+ debug_return_bool(false);
+}
+
+/*
+ * Returns true if "n" is one of our ip addresses or if
+ * "n" is a network that we are on, else returns false.
+ */
+bool
+addr_matches(char *n)
+{
+ char *m;
+ bool rc;
+ debug_decl(addr_matches, SUDOERS_DEBUG_MATCH)
+
+ /* If there's an explicit netmask, use it. */
+ if ((m = strchr(n, '/'))) {
+ *m++ = '\0';
+ rc = addr_matches_if_netmask(n, m);
+ *(m - 1) = '/';
+ } else
+ rc = addr_matches_if(n);
+
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "IP address %s matches local host: %s", n, rc ? "true" : "false");
+ debug_return_bool(rc);
+}
diff --git a/plugins/sudoers/mkdefaults b/plugins/sudoers/mkdefaults
new file mode 100755
index 0000000..885c1b5
--- /dev/null
+++ b/plugins/sudoers/mkdefaults
@@ -0,0 +1,164 @@
+#!/usr/bin/env perl
+#
+# Generate sudo_defs_table and associated defines
+#
+# Input should be formatted thusly:
+#
+# var_name
+# TYPE
+# description (or NULL)
+# array of struct def_values if TYPE == T_TUPLE
+
+use warnings;
+use strict;
+
+my ($header, $cfile, $infile);
+
+# Deal with optional -o (output) argument
+if ($#ARGV > 0 && $ARGV[0] eq "-o") {
+ shift;
+ $header = $cfile = shift;
+ $header .= '.h';
+ $cfile .= '.c';
+}
+die "usage: $0 [input_file]\n" unless $#ARGV == -1 || $#ARGV == 0;
+
+$infile = $ARGV[0] || "def_data.in";
+if (!defined($header)) {
+ $header = $infile;
+ $header =~ s/(\.in)?$/.h/;
+}
+if (!defined($cfile)) {
+ $cfile = $infile;
+ $cfile =~ s/(\.in)?$/.c/;
+}
+
+open(IN, "<$infile") || die "$0: can't open $infile: $!\n";
+open(HEADER, ">$header") || die "$0: can't open $header: $!\n";
+open(CFILE, ">$cfile") || die "$0: can't open $cfile: $!\n";
+
+my $count = 0;
+my @tuple_values = ( "never" );
+my @records = ();
+my ($var, $type, $desc, $values, $callback, $field);
+while (<IN>) {
+ chomp;
+ s/\s*#.*$//;
+ next if /^\s*$/;
+
+ if (/^\S/) {
+ # Store previous record and begin new one
+ $records[$count++] = [$var, $type, $desc, $values, $callback] if defined($var);
+
+ $var = $_;
+ $type = '';
+ $desc = undef;
+ $values = undef;
+ $callback = undef;
+ $field = 0;
+ } else {
+ $field++;
+ s/^\s+//;
+ s/\s+$//;
+ if ($field == 1) {
+ # type
+ $type = $_;
+ } elsif ($field == 2) {
+ # description
+ if ($_ eq "NULL") {
+ $desc = "NULL";
+ } else {
+ # Strip leading and trailing double quote and escape the rest
+ s/^"//;
+ s/"$//;
+ s/"/\\"/g;
+ $desc = "N_(\"$_\")";
+ }
+ } elsif ($field == 3 || $field == 4) {
+ if (s/^\*//) {
+ $callback = $_;
+ } else {
+ die "$0: syntax error near line $.\n" if $type !~ /^T_TUPLE/;
+ $values = [ split ];
+ foreach my $v (@$values) {
+ push(@tuple_values, $v) unless grep(/^$v$/, @tuple_values);
+ }
+ }
+ } else {
+ die "$0: syntax error near line $.\n";
+ }
+ }
+}
+$records[$count++] = [$var, $type, $desc, $values, $callback] if defined($var);
+
+# Print out value arrays
+for (my $i = 0; $i < $count; $i++) {
+ if (defined($records[$i]->[3])) {
+ die "Values list specified for non-tuple\n" unless
+ $records[$i]->[1] =~ /^T_TUPLE/;
+ printf CFILE "static struct def_values def_data_%s[] = {\n",
+ $records[$i]->[0];
+ foreach (@{$records[$i]->[3]}) {
+ print CFILE " { \"$_\", $_ },\n";
+ }
+ print CFILE " { NULL, 0 },\n";
+ print CFILE "};\n\n";
+ }
+}
+
+# Print each record
+print CFILE "struct sudo_defs_types sudo_defs_table[] = {\n {\n";
+for (my $i = 0; $i < $count; $i++) {
+ print_record($records[$i], $i);
+}
+print CFILE "\tNULL, 0, NULL\n }\n};\n";
+
+# Print out def_tuple
+if (@tuple_values) {
+ print HEADER "\nenum def_tuple {\n";
+ for (my $i = 0; $i <= $#tuple_values; $i++) {
+ printf HEADER "\t%s%s\n", $tuple_values[$i],
+ $i != $#tuple_values ? "," : "";
+ }
+ print HEADER "};\n";
+}
+
+close(IN);
+close(HEADER);
+close(CFILE);
+
+exit(0);
+
+sub print_record {
+ my ($rec, $recnum) = @_;
+ my ($i, $v, $defname);
+
+ # each variable gets a macro to access its value
+ $defname = "I_" . uc($rec->[0]);
+ printf HEADER "#define %-23s %d\n", $defname, $recnum;
+ for ($rec->[1]) {
+ if (/^T_INT/) { $v = "ival"; }
+ elsif (/^T_UINT/) { $v = "uival"; }
+ elsif (/^T_STR/) { $v = "str"; }
+ elsif (/^T_FLAG/) { $v = "flag"; }
+ elsif (/^T_MODE/) { $v = "mode"; }
+ elsif (/^T_LIST/) { $v = "list"; }
+ elsif (/^T_LOGFAC/) { $v = "ival"; }
+ elsif (/^T_LOGPRI/) { $v = "ival"; }
+ elsif (/^T_TUPLE/) { $v = "tuple"; }
+ elsif (/^T_TIMESPEC/) { $v = "tspec"; }
+ elsif (/^T_TIMEOUT/) { $v = "ival"; }
+ else { die "$0: unknown defaults type: $_\n"; }
+ }
+ printf HEADER "#define %-23s (sudo_defs_table[$defname].sd_un.${v})\n",
+ "def_$rec->[0]";
+
+ print CFILE "\t\"$rec->[0]\", $rec->[1],\n\t$rec->[2],\n";
+ if (defined($rec->[3])) {
+ printf CFILE "\tdef_data_$rec->[0],\n";
+ } else {
+ printf CFILE "\tNULL,\n";
+ }
+ printf CFILE "\t$rec->[4],\n" if defined($rec->[4]);
+ print CFILE " }, {\n";
+}
diff --git a/plugins/sudoers/mkdir_parents.c b/plugins/sudoers/mkdir_parents.c
new file mode 100644
index 0000000..5fa51ac
--- /dev/null
+++ b/plugins/sudoers/mkdir_parents.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009-2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "sudoers.h"
+
+/*
+ * Create any parent directories needed by path (but not path itself).
+ * Note that path is modified but is restored before it returns.
+ */
+bool
+sudo_mkdir_parents(char *path, uid_t uid, gid_t gid, mode_t mode, bool quiet)
+{
+ struct stat sb;
+ char *slash = path;
+ debug_decl(sudo_mkdir_parents, SUDOERS_DEBUG_UTIL)
+
+ /* cppcheck-suppress nullPointerRedundantCheck */
+ while ((slash = strchr(slash + 1, '/')) != NULL) {
+ *slash = '\0';
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "mkdir %s, mode 0%o, uid %d, gid %d", path, (unsigned int)mode,
+ (int)uid, (int)gid);
+ if (mkdir(path, mode) == 0) {
+ if (uid != (uid_t)-1 && gid != (gid_t)-1) {
+ if (chown(path, uid, gid) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to chown %d:%d %s", __func__,
+ (int)uid, (int)gid, path);
+ }
+ }
+ } else {
+ if (errno != EEXIST) {
+ if (!quiet)
+ sudo_warn(U_("unable to mkdir %s"), path);
+ goto bad;
+ }
+ /* Already exists, make sure it is a directory. */
+ if (stat(path, &sb) != 0) {
+ if (!quiet)
+ sudo_warn(U_("unable to stat %s"), path);
+ goto bad;
+ }
+ if (!S_ISDIR(sb.st_mode)) {
+ if (!quiet)
+ sudo_warnx(U_("%s exists but is not a directory (0%o)"),
+ path, (unsigned int) sb.st_mode);
+ goto bad;
+ }
+ }
+ *slash = '/';
+ }
+
+ debug_return_bool(true);
+bad:
+ /* We must restore the path before we return. */
+ *slash = '/';
+ debug_return_bool(false);
+}
diff --git a/plugins/sudoers/parse.c b/plugins/sudoers/parse.c
new file mode 100644
index 0000000..fb781f5
--- /dev/null
+++ b/plugins/sudoers/parse.c
@@ -0,0 +1,864 @@
+/*
+ * Copyright (c) 2004-2005, 2007-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <ctype.h>
+#include <grp.h>
+#include <pwd.h>
+#include <time.h>
+
+#include "sudoers.h"
+#include "sudo_lbuf.h"
+#include <gram.h>
+
+/*
+ * Look up the user in the sudoers prase tree for pseudo-commands like
+ * list, verify and kill.
+ */
+static int
+sudoers_lookup_pseudo(struct sudo_nss_list *snl, struct passwd *pw,
+ int validated, int pwflag)
+{
+ int match;
+ struct sudo_nss *nss;
+ struct cmndspec *cs;
+ struct privilege *priv;
+ struct userspec *us;
+ struct defaults *def;
+ int nopass;
+ enum def_tuple pwcheck;
+ debug_decl(sudoers_lookup_pseudo, SUDOERS_DEBUG_PARSER)
+
+ pwcheck = (pwflag == -1) ? never : sudo_defs_table[pwflag].sd_un.tuple;
+ nopass = (pwcheck == all) ? true : false;
+
+ if (list_pw == NULL)
+ SET(validated, FLAG_NO_CHECK);
+ CLR(validated, FLAG_NO_USER);
+ CLR(validated, FLAG_NO_HOST);
+ match = DENY;
+ TAILQ_FOREACH(nss, snl, entries) {
+ if (nss->query(nss, pw) == -1) {
+ /* The query function should have printed an error message. */
+ SET(validated, VALIDATE_ERROR);
+ break;
+ }
+ TAILQ_FOREACH(us, &nss->parse_tree->userspecs, entries) {
+ if (userlist_matches(nss->parse_tree, pw, &us->users) != ALLOW)
+ continue;
+ TAILQ_FOREACH(priv, &us->privileges, entries) {
+ int priv_nopass = UNSPEC;
+
+ if (hostlist_matches(nss->parse_tree, pw, &priv->hostlist) != ALLOW)
+ continue;
+ TAILQ_FOREACH(def, &priv->defaults, entries) {
+ if (strcmp(def->var, "authenticate") == 0)
+ priv_nopass = !def->op;
+ }
+ TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
+ if (pwcheck == any) {
+ if (cs->tags.nopasswd == true || priv_nopass == true)
+ nopass = true;
+ } else if (pwcheck == all) {
+ if (cs->tags.nopasswd != true && priv_nopass != true)
+ nopass = false;
+ }
+ if (match == ALLOW)
+ continue;
+ /* Only check the command when listing another user. */
+ if (user_uid == 0 || list_pw == NULL ||
+ user_uid == list_pw->pw_uid ||
+ cmnd_matches(nss->parse_tree, cs->cmnd) == ALLOW)
+ match = ALLOW;
+ }
+ }
+ }
+ }
+ if (match == ALLOW || user_uid == 0) {
+ /* User has an entry for this host. */
+ SET(validated, VALIDATE_SUCCESS);
+ } else if (match == DENY)
+ SET(validated, VALIDATE_FAILURE);
+ if (pwcheck == always && def_authenticate)
+ SET(validated, FLAG_CHECK_USER);
+ else if (nopass == true)
+ def_authenticate = false;
+ debug_return_int(validated);
+}
+
+static int
+sudoers_lookup_check(struct sudo_nss *nss, struct passwd *pw,
+ int *validated, struct cmndspec **matching_cs,
+ struct defaults_list **defs, time_t now)
+{
+ int host_match, runas_match, cmnd_match;
+ struct cmndspec *cs;
+ struct privilege *priv;
+ struct userspec *us;
+ struct member *matching_user;
+ debug_decl(sudoers_lookup_check, SUDOERS_DEBUG_PARSER)
+
+ TAILQ_FOREACH_REVERSE(us, &nss->parse_tree->userspecs, userspec_list, entries) {
+ if (userlist_matches(nss->parse_tree, pw, &us->users) != ALLOW)
+ continue;
+ CLR(*validated, FLAG_NO_USER);
+ TAILQ_FOREACH_REVERSE(priv, &us->privileges, privilege_list, entries) {
+ host_match = hostlist_matches(nss->parse_tree, pw, &priv->hostlist);
+ if (host_match == ALLOW)
+ CLR(*validated, FLAG_NO_HOST);
+ else
+ continue;
+ TAILQ_FOREACH_REVERSE(cs, &priv->cmndlist, cmndspec_list, entries) {
+ if (cs->notbefore != UNSPEC) {
+ if (now < cs->notbefore)
+ continue;
+ }
+ if (cs->notafter != UNSPEC) {
+ if (now > cs->notafter)
+ continue;
+ }
+ matching_user = NULL;
+ runas_match = runaslist_matches(nss->parse_tree,
+ cs->runasuserlist, cs->runasgrouplist, &matching_user,
+ NULL);
+ if (runas_match == ALLOW) {
+ cmnd_match = cmnd_matches(nss->parse_tree, cs->cmnd);
+ if (cmnd_match != UNSPEC) {
+ /*
+ * If user is running command as himself,
+ * set runas_pw = sudo_user.pw.
+ * XXX - hack, want more general solution
+ */
+ if (matching_user && matching_user->type == MYSELF) {
+ sudo_pw_delref(runas_pw);
+ sudo_pw_addref(sudo_user.pw);
+ runas_pw = sudo_user.pw;
+ }
+ *matching_cs = cs;
+ *defs = &priv->defaults;
+ debug_return_int(cmnd_match);
+ }
+ }
+ }
+ }
+ }
+ debug_return_int(UNSPEC);
+}
+
+/*
+ * Apply cmndspec-specific settngs including SELinux role/type,
+ * Solaris privs, and command tags.
+ */
+static bool
+apply_cmndspec(struct cmndspec *cs)
+{
+ debug_decl(apply_cmndspec, SUDOERS_DEBUG_PARSER)
+
+ if (cs != NULL) {
+#ifdef HAVE_SELINUX
+ /* Set role and type if not specified on command line. */
+ if (user_role == NULL) {
+ if (cs->role != NULL) {
+ user_role = strdup(cs->role);
+ if (user_role == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ } else {
+ user_role = def_role;
+ }
+ }
+ if (user_type == NULL) {
+ if (cs->type != NULL) {
+ user_type = strdup(cs->type);
+ if (user_type == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ } else {
+ user_type = def_type;
+ }
+ }
+#endif /* HAVE_SELINUX */
+#ifdef HAVE_PRIV_SET
+ /* Set Solaris privilege sets */
+ if (runas_privs == NULL) {
+ if (cs->privs != NULL) {
+ runas_privs = strdup(cs->privs);
+ if (runas_privs == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ } else {
+ runas_privs = def_privs;
+ }
+ }
+ if (runas_limitprivs == NULL) {
+ if (cs->limitprivs != NULL) {
+ runas_limitprivs = strdup(cs->limitprivs);
+ if (runas_limitprivs == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ } else {
+ runas_limitprivs = def_limitprivs;
+ }
+ }
+#endif /* HAVE_PRIV_SET */
+ if (cs->timeout > 0)
+ def_command_timeout = cs->timeout;
+ if (cs->tags.nopasswd != UNSPEC)
+ def_authenticate = !cs->tags.nopasswd;
+ if (cs->tags.noexec != UNSPEC)
+ def_noexec = cs->tags.noexec;
+ if (cs->tags.setenv != UNSPEC)
+ def_setenv = cs->tags.setenv;
+ if (cs->tags.log_input != UNSPEC)
+ def_log_input = cs->tags.log_input;
+ if (cs->tags.log_output != UNSPEC)
+ def_log_output = cs->tags.log_output;
+ if (cs->tags.send_mail != UNSPEC) {
+ if (cs->tags.send_mail) {
+ def_mail_all_cmnds = true;
+ } else {
+ def_mail_all_cmnds = false;
+ def_mail_always = false;
+ def_mail_no_perms = false;
+ }
+ }
+ if (cs->tags.follow != UNSPEC)
+ def_sudoedit_follow = cs->tags.follow;
+ }
+
+ debug_return_bool(true);
+}
+
+/*
+ * Look up the user in the sudoers prase tree and check to see if they are
+ * allowed to run the specified command on this host as the target user.
+ */
+int
+sudoers_lookup(struct sudo_nss_list *snl, struct passwd *pw, int validated,
+ int pwflag)
+{
+ struct defaults_list *defs = NULL;
+ struct sudoers_parse_tree *parse_tree = NULL;
+ struct cmndspec *cs = NULL;
+ struct sudo_nss *nss;
+ int m, match = UNSPEC;
+ time_t now;
+ debug_decl(sudoers_lookup, SUDOERS_DEBUG_PARSER)
+
+ /*
+ * Special case checking the "validate", "list" and "kill" pseudo-commands.
+ */
+ if (pwflag)
+ debug_return_int(sudoers_lookup_pseudo(snl, pw, validated, pwflag));
+
+ /* Need to be runas user while stat'ing things. */
+ if (!set_perms(PERM_RUNAS))
+ debug_return_int(validated);
+
+ /* Query each sudoers source and check the user. */
+ time(&now);
+ TAILQ_FOREACH(nss, snl, entries) {
+ if (nss->query(nss, pw) == -1) {
+ /* The query function should have printed an error message. */
+ SET(validated, VALIDATE_ERROR);
+ break;
+ }
+
+ m = sudoers_lookup_check(nss, pw, &validated, &cs, &defs, now);
+ if (m != UNSPEC) {
+ match = m;
+ parse_tree = nss->parse_tree;
+ }
+
+ if (!sudo_nss_can_continue(nss, m))
+ break;
+ }
+ if (match != UNSPEC) {
+ if (defs != NULL)
+ update_defaults(parse_tree, defs, SETDEF_GENERIC, false);
+ if (!apply_cmndspec(cs))
+ SET(validated, VALIDATE_ERROR);
+ else if (match == ALLOW)
+ SET(validated, VALIDATE_SUCCESS);
+ else
+ SET(validated, VALIDATE_FAILURE);
+ }
+ if (!restore_perms())
+ SET(validated, VALIDATE_ERROR);
+ debug_return_int(validated);
+}
+
+static int
+display_priv_short(struct sudoers_parse_tree *parse_tree, struct passwd *pw,
+ struct userspec *us, struct sudo_lbuf *lbuf)
+{
+ struct privilege *priv;
+ int nfound = 0;
+ debug_decl(display_priv_short, SUDOERS_DEBUG_PARSER)
+
+ TAILQ_FOREACH(priv, &us->privileges, entries) {
+ struct cmndspec *cs, *prev_cs = NULL;
+ struct cmndtag tags;
+
+ if (hostlist_matches(parse_tree, pw, &priv->hostlist) != ALLOW)
+ continue;
+
+ sudoers_defaults_list_to_tags(&priv->defaults, &tags);
+ TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
+ /* Start a new line if RunAs changes. */
+ if (prev_cs == NULL || RUNAS_CHANGED(cs, prev_cs)) {
+ struct member *m;
+
+ if (cs != TAILQ_FIRST(&priv->cmndlist))
+ sudo_lbuf_append(lbuf, "\n");
+ sudo_lbuf_append(lbuf, " (");
+ if (cs->runasuserlist != NULL) {
+ TAILQ_FOREACH(m, cs->runasuserlist, entries) {
+ if (m != TAILQ_FIRST(cs->runasuserlist))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, parse_tree, m, ", ",
+ RUNASALIAS);
+ }
+ } else if (cs->runasgrouplist == NULL) {
+ sudo_lbuf_append(lbuf, "%s", def_runas_default);
+ } else {
+ sudo_lbuf_append(lbuf, "%s", pw->pw_name);
+ }
+ if (cs->runasgrouplist != NULL) {
+ sudo_lbuf_append(lbuf, " : ");
+ TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
+ if (m != TAILQ_FIRST(cs->runasgrouplist))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, parse_tree, m, ", ",
+ RUNASALIAS);
+ }
+ }
+ sudo_lbuf_append(lbuf, ") ");
+ } else if (cs != TAILQ_FIRST(&priv->cmndlist)) {
+ sudo_lbuf_append(lbuf, ", ");
+ }
+ sudoers_format_cmndspec(lbuf, parse_tree, cs, prev_cs, tags, true);
+ prev_cs = cs;
+ nfound++;
+ }
+ sudo_lbuf_append(lbuf, "\n");
+ }
+ debug_return_int(nfound);
+}
+
+/*
+ * Compare the current cmndspec with the previous one to determine
+ * whether we need to start a new long entry for "sudo -ll".
+ * Returns true if we should start a new long entry, else false.
+ */
+static bool
+new_long_entry(struct cmndspec *cs, struct cmndspec *prev_cs)
+{
+ debug_decl(new_long_entry, SUDOERS_DEBUG_PARSER)
+
+ if (prev_cs == NULL)
+ debug_return_bool(true);
+ if (RUNAS_CHANGED(cs, prev_cs) || TAGS_CHANGED(prev_cs->tags, cs->tags))
+ debug_return_bool(true);
+#ifdef HAVE_PRIV_SET
+ if (cs->privs && (!prev_cs->privs || strcmp(cs->privs, prev_cs->privs) != 0))
+ debug_return_bool(true);
+ if (cs->limitprivs && (!prev_cs->limitprivs || strcmp(cs->limitprivs, prev_cs->limitprivs) != 0))
+ debug_return_bool(true);
+#endif /* HAVE_PRIV_SET */
+#ifdef HAVE_SELINUX
+ if (cs->role && (!prev_cs->role || strcmp(cs->role, prev_cs->role) != 0))
+ debug_return_bool(true);
+ if (cs->type && (!prev_cs->type || strcmp(cs->type, prev_cs->type) != 0))
+ debug_return_bool(true);
+#endif /* HAVE_SELINUX */
+ if (cs->timeout != prev_cs->timeout)
+ debug_return_bool(true);
+ if (cs->notbefore != prev_cs->notbefore)
+ debug_return_bool(true);
+ if (cs->notafter != prev_cs->notafter)
+ debug_return_bool(true);
+ debug_return_bool(false);
+}
+
+static int
+display_priv_long(struct sudoers_parse_tree *parse_tree, struct passwd *pw,
+ struct userspec *us, struct sudo_lbuf *lbuf)
+{
+ struct privilege *priv;
+ int nfound = 0;
+ debug_decl(display_priv_long, SUDOERS_DEBUG_PARSER)
+
+ TAILQ_FOREACH(priv, &us->privileges, entries) {
+ struct cmndspec *cs, *prev_cs;
+
+ if (hostlist_matches(parse_tree, pw, &priv->hostlist) != ALLOW)
+ continue;
+ prev_cs = NULL;
+ TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
+ struct defaults *d;
+ struct member *m;
+
+ if (new_long_entry(cs, prev_cs)) {
+ int olen;
+
+ if (priv->ldap_role != NULL) {
+ sudo_lbuf_append(lbuf, _("\nLDAP Role: %s\n"),
+ priv->ldap_role);
+ } else {
+ sudo_lbuf_append(lbuf, _("\nSudoers entry:\n"));
+ }
+ sudo_lbuf_append(lbuf, _(" RunAsUsers: "));
+ if (cs->runasuserlist != NULL) {
+ TAILQ_FOREACH(m, cs->runasuserlist, entries) {
+ if (m != TAILQ_FIRST(cs->runasuserlist))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, parse_tree, m, ", ",
+ RUNASALIAS);
+ }
+ } else if (cs->runasgrouplist == NULL) {
+ sudo_lbuf_append(lbuf, "%s", def_runas_default);
+ } else {
+ sudo_lbuf_append(lbuf, "%s", pw->pw_name);
+ }
+ sudo_lbuf_append(lbuf, "\n");
+ if (cs->runasgrouplist != NULL) {
+ sudo_lbuf_append(lbuf, _(" RunAsGroups: "));
+ TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
+ if (m != TAILQ_FIRST(cs->runasgrouplist))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, parse_tree, m, ", ",
+ RUNASALIAS);
+ }
+ sudo_lbuf_append(lbuf, "\n");
+ }
+ olen = lbuf->len;
+ sudo_lbuf_append(lbuf, _(" Options: "));
+ TAILQ_FOREACH(d, &priv->defaults, entries) {
+ sudoers_format_default(lbuf, d);
+ sudo_lbuf_append(lbuf, ", ");
+ }
+ if (TAG_SET(cs->tags.setenv))
+ sudo_lbuf_append(lbuf, "%ssetenv, ", cs->tags.setenv ? "" : "!");
+ if (TAG_SET(cs->tags.noexec))
+ sudo_lbuf_append(lbuf, "%snoexec, ", cs->tags.noexec ? "" : "!");
+ if (TAG_SET(cs->tags.nopasswd))
+ sudo_lbuf_append(lbuf, "%sauthenticate, ", cs->tags.nopasswd ? "!" : "");
+ if (TAG_SET(cs->tags.log_input))
+ sudo_lbuf_append(lbuf, "%slog_input, ", cs->tags.log_input ? "" : "!");
+ if (TAG_SET(cs->tags.log_output))
+ sudo_lbuf_append(lbuf, "%slog_output, ", cs->tags.log_output ? "" : "!");
+ if (lbuf->buf[lbuf->len - 2] == ',') {
+ lbuf->len -= 2; /* remove trailing ", " */
+ sudo_lbuf_append(lbuf, "\n");
+ } else {
+ lbuf->len = olen; /* no options */
+ }
+#ifdef HAVE_PRIV_SET
+ if (cs->privs)
+ sudo_lbuf_append(lbuf, " Privs: %s\n", cs->privs);
+ if (cs->limitprivs)
+ sudo_lbuf_append(lbuf, " Limitprivs: %s\n", cs->limitprivs);
+#endif /* HAVE_PRIV_SET */
+#ifdef HAVE_SELINUX
+ if (cs->role)
+ sudo_lbuf_append(lbuf, " Role: %s\n", cs->role);
+ if (cs->type)
+ sudo_lbuf_append(lbuf, " Type: %s\n", cs->type);
+#endif /* HAVE_SELINUX */
+ if (cs->timeout > 0) {
+ char numbuf[(((sizeof(int) * 8) + 2) / 3) + 2];
+ snprintf(numbuf, sizeof(numbuf), "%d", cs->timeout);
+ sudo_lbuf_append(lbuf, " Timeout: %s\n", numbuf);
+ }
+ if (cs->notbefore != UNSPEC) {
+ char buf[sizeof("CCYYMMDDHHMMSSZ")];
+ struct tm *tm = gmtime(&cs->notbefore);
+ snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ sudo_lbuf_append(lbuf, " NotBefore: %s\n", buf);
+ }
+ if (cs->notafter != UNSPEC) {
+ char buf[sizeof("CCYYMMDDHHMMSSZ")];
+ struct tm *tm = gmtime(&cs->notafter);
+ snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ sudo_lbuf_append(lbuf, " NotAfter: %s\n", buf);
+ }
+ sudo_lbuf_append(lbuf, _(" Commands:\n"));
+ }
+ sudo_lbuf_append(lbuf, "\t");
+ sudoers_format_member(lbuf, parse_tree, cs->cmnd, "\n\t",
+ CMNDALIAS);
+ sudo_lbuf_append(lbuf, "\n");
+ prev_cs = cs;
+ nfound++;
+ }
+ }
+ debug_return_int(nfound);
+}
+
+static int
+sudo_display_userspecs(struct sudoers_parse_tree *parse_tree, struct passwd *pw,
+ struct sudo_lbuf *lbuf, bool verbose)
+{
+ struct userspec *us;
+ int nfound = 0;
+ debug_decl(sudo_display_userspecs, SUDOERS_DEBUG_PARSER)
+
+ TAILQ_FOREACH(us, &parse_tree->userspecs, entries) {
+ if (userlist_matches(parse_tree, pw, &us->users) != ALLOW)
+ continue;
+
+ if (verbose)
+ nfound += display_priv_long(parse_tree, pw, us, lbuf);
+ else
+ nfound += display_priv_short(parse_tree, pw, us, lbuf);
+ }
+ if (sudo_lbuf_error(lbuf))
+ debug_return_int(-1);
+ debug_return_int(nfound);
+}
+
+/*
+ * Display matching Defaults entries for the given user on this host.
+ */
+static int
+display_defaults(struct sudoers_parse_tree *parse_tree, struct passwd *pw,
+ struct sudo_lbuf *lbuf)
+{
+ struct defaults *d;
+ char *prefix;
+ int nfound = 0;
+ debug_decl(display_defaults, SUDOERS_DEBUG_PARSER)
+
+ if (lbuf->len == 0 || isspace((unsigned char)lbuf->buf[lbuf->len - 1]))
+ prefix = " ";
+ else
+ prefix = ", ";
+
+ TAILQ_FOREACH(d, &parse_tree->defaults, entries) {
+ switch (d->type) {
+ case DEFAULTS_HOST:
+ if (hostlist_matches(parse_tree, pw, d->binding) != ALLOW)
+ continue;
+ break;
+ case DEFAULTS_USER:
+ if (userlist_matches(parse_tree, pw, d->binding) != ALLOW)
+ continue;
+ break;
+ case DEFAULTS_RUNAS:
+ case DEFAULTS_CMND:
+ continue;
+ }
+ sudo_lbuf_append(lbuf, "%s", prefix);
+ sudoers_format_default(lbuf, d);
+ prefix = ", ";
+ nfound++;
+ }
+ if (sudo_lbuf_error(lbuf))
+ debug_return_int(-1);
+ debug_return_int(nfound);
+}
+
+/*
+ * Display Defaults entries of the given type.
+ */
+static int
+display_bound_defaults_by_type(struct sudoers_parse_tree *parse_tree,
+ int deftype, struct sudo_lbuf *lbuf)
+{
+ struct defaults *d;
+ struct member_list *binding = NULL;
+ struct member *m;
+ char *dsep;
+ int atype, nfound = 0;
+ debug_decl(display_bound_defaults_by_type, SUDOERS_DEBUG_PARSER)
+
+ switch (deftype) {
+ case DEFAULTS_HOST:
+ atype = HOSTALIAS;
+ dsep = "@";
+ break;
+ case DEFAULTS_USER:
+ atype = USERALIAS;
+ dsep = ":";
+ break;
+ case DEFAULTS_RUNAS:
+ atype = RUNASALIAS;
+ dsep = ">";
+ break;
+ case DEFAULTS_CMND:
+ atype = CMNDALIAS;
+ dsep = "!";
+ break;
+ default:
+ debug_return_int(-1);
+ }
+ TAILQ_FOREACH(d, &parse_tree->defaults, entries) {
+ if (d->type != deftype)
+ continue;
+
+ nfound++;
+ if (binding != d->binding) {
+ binding = d->binding;
+ if (nfound != 1)
+ sudo_lbuf_append(lbuf, "\n");
+ sudo_lbuf_append(lbuf, " Defaults%s", dsep);
+ TAILQ_FOREACH(m, binding, entries) {
+ if (m != TAILQ_FIRST(binding))
+ sudo_lbuf_append(lbuf, ",");
+ sudoers_format_member(lbuf, parse_tree, m, ", ", atype);
+ sudo_lbuf_append(lbuf, " ");
+ }
+ } else
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_default(lbuf, d);
+ }
+
+ if (sudo_lbuf_error(lbuf))
+ debug_return_int(-1);
+ debug_return_int(nfound);
+}
+
+/*
+ * Display Defaults entries that are per-runas or per-command
+ */
+static int
+display_bound_defaults(struct sudoers_parse_tree *parse_tree,
+ struct passwd *pw, struct sudo_lbuf *lbuf)
+{
+ int nfound = 0;
+ debug_decl(display_bound_defaults, SUDOERS_DEBUG_PARSER)
+
+ /* XXX - should only print ones that match what the user can do. */
+ nfound += display_bound_defaults_by_type(parse_tree, DEFAULTS_RUNAS, lbuf);
+ nfound += display_bound_defaults_by_type(parse_tree, DEFAULTS_CMND, lbuf);
+
+ if (sudo_lbuf_error(lbuf))
+ debug_return_int(-1);
+ debug_return_int(nfound);
+}
+
+static int
+output(const char *buf)
+{
+ struct sudo_conv_message msg;
+ struct sudo_conv_reply repl;
+ debug_decl(output, SUDOERS_DEBUG_NSS)
+
+ /* Call conversation function */
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_type = SUDO_CONV_INFO_MSG;
+ msg.msg = buf;
+ memset(&repl, 0, sizeof(repl));
+ if (sudo_conv(1, &msg, &repl, NULL) == -1)
+ debug_return_int(0);
+ debug_return_int(strlen(buf));
+}
+
+/*
+ * Print out privileges for the specified user.
+ * Returns true on success or -1 on error.
+ */
+int
+display_privs(struct sudo_nss_list *snl, struct passwd *pw, bool verbose)
+{
+ struct sudo_nss *nss;
+ struct sudo_lbuf def_buf, priv_buf;
+ struct stat sb;
+ int cols, count, olen, n;
+ debug_decl(display_privs, SUDOERS_DEBUG_PARSER)
+
+ cols = sudo_user.cols;
+ if (fstat(STDOUT_FILENO, &sb) == 0 && S_ISFIFO(sb.st_mode))
+ cols = 0;
+ sudo_lbuf_init(&def_buf, output, 4, NULL, cols);
+ sudo_lbuf_init(&priv_buf, output, 8, NULL, cols);
+
+ sudo_lbuf_append(&def_buf, _("Matching Defaults entries for %s on %s:\n"),
+ pw->pw_name, user_srunhost);
+ count = 0;
+ TAILQ_FOREACH(nss, snl, entries) {
+ n = display_defaults(nss->parse_tree, pw, &def_buf);
+ if (n == -1)
+ goto bad;
+ count += n;
+ }
+ if (count != 0) {
+ sudo_lbuf_append(&def_buf, "\n\n");
+ } else {
+ /* Undo Defaults header. */
+ def_buf.len = 0;
+ }
+
+ /* Display Runas and Cmnd-specific defaults. */
+ olen = def_buf.len;
+ sudo_lbuf_append(&def_buf, _("Runas and Command-specific defaults for %s:\n"),
+ pw->pw_name);
+ count = 0;
+ TAILQ_FOREACH(nss, snl, entries) {
+ n = display_bound_defaults(nss->parse_tree, pw, &def_buf);
+ if (n == -1)
+ goto bad;
+ count += n;
+ }
+ if (count != 0) {
+ sudo_lbuf_append(&def_buf, "\n\n");
+ } else {
+ /* Undo Defaults header. */
+ def_buf.len = olen;
+ }
+
+ /* Display privileges from all sources. */
+ sudo_lbuf_append(&priv_buf,
+ _("User %s may run the following commands on %s:\n"),
+ pw->pw_name, user_srunhost);
+ count = 0;
+ TAILQ_FOREACH(nss, snl, entries) {
+ if (nss->query(nss, pw) != -1) {
+ n = sudo_display_userspecs(nss->parse_tree, pw, &priv_buf, verbose);
+ if (n == -1)
+ goto bad;
+ count += n;
+ }
+ }
+ if (count == 0) {
+ def_buf.len = 0;
+ priv_buf.len = 0;
+ sudo_lbuf_append(&priv_buf,
+ _("User %s is not allowed to run sudo on %s.\n"),
+ pw->pw_name, user_shost);
+ }
+ if (sudo_lbuf_error(&def_buf) || sudo_lbuf_error(&priv_buf))
+ goto bad;
+
+ sudo_lbuf_print(&def_buf);
+ sudo_lbuf_print(&priv_buf);
+
+ sudo_lbuf_destroy(&def_buf);
+ sudo_lbuf_destroy(&priv_buf);
+
+ debug_return_int(true);
+bad:
+ sudo_lbuf_destroy(&def_buf);
+ sudo_lbuf_destroy(&priv_buf);
+
+ debug_return_int(-1);
+}
+
+static int
+display_cmnd_check(struct sudoers_parse_tree *parse_tree, struct passwd *pw,
+ time_t now)
+{
+ int host_match, runas_match, cmnd_match;
+ struct cmndspec *cs;
+ struct privilege *priv;
+ struct userspec *us;
+ debug_decl(display_cmnd_check, SUDOERS_DEBUG_PARSER)
+
+ TAILQ_FOREACH_REVERSE(us, &parse_tree->userspecs, userspec_list, entries) {
+ if (userlist_matches(parse_tree, pw, &us->users) != ALLOW)
+ continue;
+ TAILQ_FOREACH_REVERSE(priv, &us->privileges, privilege_list, entries) {
+ host_match = hostlist_matches(parse_tree, pw, &priv->hostlist);
+ if (host_match != ALLOW)
+ continue;
+ TAILQ_FOREACH_REVERSE(cs, &priv->cmndlist, cmndspec_list, entries) {
+ if (cs->notbefore != UNSPEC) {
+ if (now < cs->notbefore)
+ continue;
+ }
+ if (cs->notafter != UNSPEC) {
+ if (now > cs->notafter)
+ continue;
+ }
+ runas_match = runaslist_matches(parse_tree, cs->runasuserlist,
+ cs->runasgrouplist, NULL, NULL);
+ if (runas_match == ALLOW) {
+ cmnd_match = cmnd_matches(parse_tree, cs->cmnd);
+ if (cmnd_match != UNSPEC)
+ debug_return_int(cmnd_match);
+ }
+ }
+ }
+ }
+ debug_return_int(UNSPEC);
+}
+
+/*
+ * Check user_cmnd against sudoers and print the matching entry if the
+ * command is allowed.
+ * Returns true if the command is allowed, false if not or -1 on error.
+ */
+int
+display_cmnd(struct sudo_nss_list *snl, struct passwd *pw)
+{
+ struct sudo_nss *nss;
+ int m, match = UNSPEC;
+ int ret = false;
+ time_t now;
+ debug_decl(display_cmnd, SUDOERS_DEBUG_PARSER)
+
+ /* Iterate over each source, checking for the command. */
+ time(&now);
+ TAILQ_FOREACH(nss, snl, entries) {
+ if (nss->query(nss, pw) == -1) {
+ /* The query function should have printed an error message. */
+ debug_return_int(-1);
+ }
+
+ m = display_cmnd_check(nss->parse_tree, pw, now);
+ if (m != UNSPEC)
+ match = m;
+
+ if (!sudo_nss_can_continue(nss, m))
+ break;
+ }
+ if (match == ALLOW) {
+ const int len = sudo_printf(SUDO_CONV_INFO_MSG, "%s%s%s\n",
+ safe_cmnd, user_args ? " " : "", user_args ? user_args : "");
+ ret = len < 0 ? -1 : true;
+ }
+ debug_return_int(ret);
+}
diff --git a/plugins/sudoers/parse.h b/plugins/sudoers/parse.h
new file mode 100644
index 0000000..7dcbdca
--- /dev/null
+++ b/plugins/sudoers/parse.h
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 1996, 1998-2000, 2004, 2007-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_PARSE_H
+#define SUDOERS_PARSE_H
+
+/* Characters that must be quoted in sudoers */
+#define SUDOERS_QUOTED ":\\,=#\""
+
+#undef UNSPEC
+#define UNSPEC -1
+#undef DENY
+#define DENY 0
+#undef ALLOW
+#define ALLOW 1
+#undef IMPLIED
+#define IMPLIED 2
+
+/*
+ * Initialize all tags to UNSPEC.
+ */
+#define TAGS_INIT(t) do { \
+ (t).follow = UNSPEC; \
+ (t).log_input = UNSPEC; \
+ (t).log_output = UNSPEC; \
+ (t).noexec = UNSPEC; \
+ (t).nopasswd = UNSPEC; \
+ (t).send_mail = UNSPEC; \
+ (t).setenv = UNSPEC; \
+} while (0)
+
+/*
+ * Copy any tags set in t2 into t, overriding the value in t.
+ */
+#define TAGS_MERGE(t, t2) do { \
+ if ((t2).follow != UNSPEC) \
+ (t).follow = (t2).follow; \
+ if ((t2).log_input != UNSPEC) \
+ (t).log_input = (t2).log_input; \
+ if ((t2).log_output != UNSPEC) \
+ (t).log_output = (t2).log_output; \
+ if ((t2).noexec != UNSPEC) \
+ (t).noexec = (t2).noexec; \
+ if ((t2).nopasswd != UNSPEC) \
+ (t).nopasswd = (t2).nopasswd; \
+ if ((t2).send_mail != UNSPEC) \
+ (t).send_mail = (t2).send_mail; \
+ if ((t2).setenv != UNSPEC) \
+ (t).setenv = (t2).setenv; \
+} while (0)
+
+/*
+ * Returns true if any tag are not UNSPEC, else false.
+ */
+#define TAGS_SET(t) \
+ ((t).follow != UNSPEC || (t).log_input != UNSPEC || \
+ (t).log_output != UNSPEC || (t).noexec != UNSPEC || \
+ (t).nopasswd != UNSPEC || (t).send_mail != UNSPEC || \
+ (t).setenv != UNSPEC)
+
+/*
+ * Returns true if the specified tag is not UNSPEC or IMPLIED, else false.
+ */
+#define TAG_SET(tt) \
+ ((tt) != UNSPEC && (tt) != IMPLIED)
+
+/*
+ * Returns true if any tags set in nt differ between ot and nt, else false.
+ */
+#define TAGS_CHANGED(ot, nt) \
+ ((TAG_SET((nt).follow) && (nt).follow != (ot).follow) || \
+ (TAG_SET((nt).log_input) && (nt).log_input != (ot).log_input) || \
+ (TAG_SET((nt).log_output) && (nt).log_output != (ot).log_output) || \
+ (TAG_SET((nt).noexec) && (nt).noexec != (ot).noexec) || \
+ (TAG_SET((nt).nopasswd) && (nt).nopasswd != (ot).nopasswd) || \
+ (TAG_SET((nt).setenv) && (nt).setenv != (ot).setenv) || \
+ (TAG_SET((nt).send_mail) && (nt).send_mail != (ot).send_mail))
+
+/*
+ * Returns true if the runas user and group lists match, else false.
+ */
+#define RUNAS_CHANGED(cs1, cs2) \
+ ((cs1)->runasuserlist != (cs2)->runasuserlist || \
+ (cs1)->runasgrouplist != (cs2)->runasgrouplist)
+
+struct command_digest {
+ unsigned int digest_type;
+ char *digest_str;
+};
+
+/*
+ * A command with option args and digest.
+ * XXX - merge into struct member
+ */
+struct sudo_command {
+ char *cmnd;
+ char *args;
+ struct command_digest *digest;
+};
+
+/*
+ * Tags associated with a command.
+ * Possible values: true, false, IMPLIED, UNSPEC.
+ */
+struct cmndtag {
+ signed int nopasswd: 3;
+ signed int noexec: 3;
+ signed int setenv: 3;
+ signed int log_input: 3;
+ signed int log_output: 3;
+ signed int send_mail: 3;
+ signed int follow: 3;
+};
+
+/*
+ * Per-command option container struct.
+ */
+struct command_options {
+ time_t notbefore; /* time restriction */
+ time_t notafter; /* time restriction */
+ int timeout; /* command timeout */
+#ifdef HAVE_SELINUX
+ char *role, *type; /* SELinux role and type */
+#endif
+#ifdef HAVE_PRIV_SET
+ char *privs, *limitprivs; /* Solaris privilege sets */
+#endif
+};
+
+/*
+ * The parsed sudoers file is stored as a collection of linked lists,
+ * modelled after the yacc grammar.
+ *
+ * Other than the alias struct, which is stored in a red-black tree,
+ * the data structure used is a doubly-linked tail queue. While sudoers
+ * is being parsed, a headless tail queue is used where the first entry
+ * acts as the head and the prev pointer does double duty as the tail pointer.
+ * This makes it possible to trivally append sub-lists. In addition, the prev
+ * pointer is always valid (even if it points to itself). Unlike a circle
+ * queue, the next pointer of the last entry is NULL and does not point back
+ * to the head. When the tail queue is finalized, it is converted to a
+ * normal BSD tail queue.
+ */
+
+/*
+ * Tail queue list head structure.
+ */
+TAILQ_HEAD(defaults_list, defaults);
+TAILQ_HEAD(userspec_list, userspec);
+TAILQ_HEAD(member_list, member);
+TAILQ_HEAD(privilege_list, privilege);
+TAILQ_HEAD(cmndspec_list, cmndspec);
+STAILQ_HEAD(comment_list, sudoers_comment);
+
+/*
+ * Structure describing a user specification and list thereof.
+ */
+struct userspec {
+ TAILQ_ENTRY(userspec) entries;
+ struct member_list users; /* list of users */
+ struct privilege_list privileges; /* list of privileges */
+ struct comment_list comments; /* optional comments */
+ int lineno;
+ char *file;
+};
+
+/*
+ * Structure describing a privilege specification.
+ */
+struct privilege {
+ TAILQ_ENTRY(privilege) entries;
+ char *ldap_role; /* LDAP sudoRole */
+ struct member_list hostlist; /* list of hosts */
+ struct cmndspec_list cmndlist; /* list of Cmnd_Specs */
+ struct defaults_list defaults; /* list of sudoOptions */
+};
+
+/*
+ * Structure describing a linked list of Cmnd_Specs.
+ * XXX - include struct command_options instad of its contents inline
+ */
+struct cmndspec {
+ TAILQ_ENTRY(cmndspec) entries;
+ struct member_list *runasuserlist; /* list of runas users */
+ struct member_list *runasgrouplist; /* list of runas groups */
+ struct member *cmnd; /* command to allow/deny */
+ struct cmndtag tags; /* tag specificaion */
+ int timeout; /* command timeout */
+ time_t notbefore; /* time restriction */
+ time_t notafter; /* time restriction */
+#ifdef HAVE_SELINUX
+ char *role, *type; /* SELinux role and type */
+#endif
+#ifdef HAVE_PRIV_SET
+ char *privs, *limitprivs; /* Solaris privilege sets */
+#endif
+};
+
+/*
+ * Generic structure to hold users, hosts, commands.
+ */
+struct member {
+ TAILQ_ENTRY(member) entries;
+ char *name; /* member name */
+ short type; /* type (see gram.h) */
+ short negated; /* negated via '!'? */
+};
+
+struct runascontainer {
+ struct member *runasusers;
+ struct member *runasgroups;
+};
+
+struct sudoers_comment {
+ STAILQ_ENTRY(sudoers_comment) entries;
+ char *str;
+};
+
+/*
+ * Generic structure to hold {User,Host,Runas,Cmnd}_Alias
+ * Aliases are stored in a red-black tree, sorted by name and type.
+ */
+struct alias {
+ char *name; /* alias name */
+ unsigned short type; /* {USER,HOST,RUNAS,CMND}ALIAS */
+ short used; /* "used" flag for cycle detection */
+ int lineno; /* line number of alias entry */
+ char *file; /* file the alias entry was in */
+ struct member_list members; /* list of alias members */
+};
+
+/*
+ * Structure describing a Defaults entry in sudoers.
+ */
+struct defaults {
+ TAILQ_ENTRY(defaults) entries;
+ char *var; /* variable name */
+ char *val; /* variable value */
+ struct member_list *binding; /* user/host/runas binding */
+ char *file; /* file Defaults entry was in */
+ short type; /* DEFAULTS{,_USER,_RUNAS,_HOST} */
+ char op; /* true, false, '+', '-' */
+ char error; /* parse error flag */
+ int lineno; /* line number of Defaults entry */
+};
+
+/*
+ * Parsed sudoers policy.
+ */
+struct sudoers_parse_tree {
+ struct userspec_list userspecs;
+ struct defaults_list defaults;
+ struct rbtree *aliases;
+};
+
+/* alias.c */
+struct rbtree *alloc_aliases(void);
+void free_aliases(struct rbtree *aliases);
+bool no_aliases(struct sudoers_parse_tree *parse_tree);
+const char *alias_add(struct sudoers_parse_tree *parse_tree, char *name, int type, char *file, int lineno, struct member *members);
+const char *alias_type_to_string(int alias_type);
+struct alias *alias_get(struct sudoers_parse_tree *parse_tree, const char *name, int type);
+struct alias *alias_remove(struct sudoers_parse_tree *parse_tree, char *name, int type);
+bool alias_find_used(struct sudoers_parse_tree *parse_tree, struct rbtree *used_aliases);
+void alias_apply(struct sudoers_parse_tree *parse_tree, int (*func)(struct sudoers_parse_tree *, struct alias *, void *), void *cookie);
+void alias_free(void *a);
+void alias_put(struct alias *a);
+
+/* gram.c */
+extern struct sudoers_parse_tree parsed_policy;
+bool init_parser(const char *path, bool quiet);
+void free_member(struct member *m);
+void free_members(struct member_list *members);
+void free_privilege(struct privilege *priv);
+void free_userspec(struct userspec *us);
+void free_userspecs(struct userspec_list *usl);
+void free_default(struct defaults *def, struct member_list **binding);
+void free_defaults(struct defaults_list *defs);
+void init_parse_tree(struct sudoers_parse_tree *parse_tree);
+void free_parse_tree(struct sudoers_parse_tree *parse_tree);
+void reparent_parse_tree(struct sudoers_parse_tree *new_tree);
+
+/* match_addr.c */
+bool addr_matches(char *n);
+
+/* match.c */
+struct group;
+struct passwd;
+bool command_matches(const char *sudoers_cmnd, const char *sudoers_args, const struct command_digest *digest);
+bool group_matches(const char *sudoers_group, const struct group *gr);
+bool hostname_matches(const char *shost, const char *lhost, const char *pattern);
+bool netgr_matches(const char *netgr, const char *lhost, const char *shost, const char *user);
+bool usergr_matches(const char *group, const char *user, const struct passwd *pw);
+bool userpw_matches(const char *sudoers_user, const char *user, const struct passwd *pw);
+int cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m);
+int cmndlist_matches(struct sudoers_parse_tree *parse_tree, const struct member_list *list);
+int host_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, const char *host, const char *shost, const struct member *m);
+int hostlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, const struct member_list *list);
+int runaslist_matches(struct sudoers_parse_tree *parse_tree, const struct member_list *user_list, const struct member_list *group_list, struct member **matching_user, struct member **matching_group);
+int user_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, const struct member *m);
+int userlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, const struct member_list *list);
+const char *sudo_getdomainname(void);
+struct gid_list *runas_getgroups(void);
+
+/* toke.c */
+void init_lexer(void);
+
+/* hexchar.c */
+int hexchar(const char *s);
+
+/* base64.c */
+size_t base64_decode(const char *str, unsigned char *dst, size_t dsize);
+size_t base64_encode(const unsigned char *in, size_t in_len, char *out, size_t out_len);
+
+/* timeout.c */
+int parse_timeout(const char *timestr);
+
+/* gmtoff.c */
+long get_gmtoff(time_t *clock);
+
+/* gentime.c */
+time_t parse_gentime(const char *expstr);
+
+/* filedigest.c */
+unsigned char *sudo_filedigest(int fd, const char *file, int digest_type, size_t *digest_len);
+
+/* digestname.c */
+const char *digest_type_to_name(int digest_type);
+
+/* parse.c */
+struct sudo_nss_list;
+int sudoers_lookup(struct sudo_nss_list *snl, struct passwd *pw, int validated, int pwflag);
+int display_privs(struct sudo_nss_list *snl, struct passwd *pw, bool verbose);
+int display_cmnd(struct sudo_nss_list *snl, struct passwd *pw);
+
+/* parse_ldif.c */
+bool sudoers_parse_ldif(struct sudoers_parse_tree *parse_tree, FILE *fp, const char *sudoers_base, bool store_options);
+
+/* fmtsudoers.c */
+struct sudo_lbuf;
+bool sudoers_format_cmndspec(struct sudo_lbuf *lbuf, struct sudoers_parse_tree *parse_tree, struct cmndspec *cs, struct cmndspec *prev_cs, struct cmndtag tags, bool expand_aliases);
+bool sudoers_format_default(struct sudo_lbuf *lbuf, struct defaults *d);
+bool sudoers_format_default_line(struct sudo_lbuf *lbuf, struct sudoers_parse_tree *parse_tree, struct defaults *d, struct defaults **next, bool expand_aliases);
+bool sudoers_format_member(struct sudo_lbuf *lbuf, struct sudoers_parse_tree *parse_tree, struct member *m, const char *separator, int alias_type);
+bool sudoers_format_privilege(struct sudo_lbuf *lbuf, struct sudoers_parse_tree *parse_tree, struct privilege *priv, bool expand_aliases);
+bool sudoers_format_userspec(struct sudo_lbuf *lbuf, struct sudoers_parse_tree *parse_tree, struct userspec *us, bool expand_aliases);
+bool sudoers_format_userspecs(struct sudo_lbuf *lbuf, struct sudoers_parse_tree *parse_tree, const char *separator, bool expand_aliases, bool flush);
+bool sudoers_defaults_to_tags(const char *var, const char *val, int op, struct cmndtag *tags);
+bool sudoers_defaults_list_to_tags(struct defaults_list *defs, struct cmndtag *tags);
+
+#endif /* SUDOERS_PARSE_H */
diff --git a/plugins/sudoers/parse_ldif.c b/plugins/sudoers/parse_ldif.c
new file mode 100644
index 0000000..9635ea8
--- /dev/null
+++ b/plugins/sudoers/parse_ldif.c
@@ -0,0 +1,774 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "sudoers.h"
+#include "sudo_ldap.h"
+#include "redblack.h"
+#include "strlist.h"
+#include <gram.h>
+
+struct sudo_role {
+ STAILQ_ENTRY(sudo_role) entries;
+ char *cn;
+ char *notbefore;
+ char *notafter;
+ double order;
+ struct sudoers_str_list *cmnds;
+ struct sudoers_str_list *hosts;
+ struct sudoers_str_list *users;
+ struct sudoers_str_list *runasusers;
+ struct sudoers_str_list *runasgroups;
+ struct sudoers_str_list *options;
+};
+STAILQ_HEAD(sudo_role_list, sudo_role);
+
+static void
+sudo_role_free(struct sudo_role *role)
+{
+ debug_decl(sudo_role_free, SUDOERS_DEBUG_UTIL)
+
+ if (role != NULL) {
+ free(role->cn);
+ free(role->notbefore);
+ free(role->notafter);
+ str_list_free(role->cmnds);
+ str_list_free(role->hosts);
+ str_list_free(role->users);
+ str_list_free(role->runasusers);
+ str_list_free(role->runasgroups);
+ str_list_free(role->options);
+ free(role);
+ }
+
+ debug_return;
+}
+
+static struct sudo_role *
+sudo_role_alloc(void)
+{
+ struct sudo_role *role;
+ debug_decl(sudo_role_alloc, SUDOERS_DEBUG_UTIL)
+
+ role = calloc(1, sizeof(*role));
+ if (role != NULL) {
+ role->cmnds = str_list_alloc();
+ role->hosts = str_list_alloc();
+ role->users = str_list_alloc();
+ role->runasusers = str_list_alloc();
+ role->runasgroups = str_list_alloc();
+ role->options = str_list_alloc();
+ if (role->cmnds == NULL || role->hosts == NULL ||
+ role->users == NULL || role->runasusers == NULL ||
+ role->runasgroups == NULL || role->options == NULL) {
+ sudo_role_free(role);
+ role = NULL;
+ }
+ }
+
+ debug_return_ptr(role);
+}
+
+/*
+ * Parse an LDIF attribute, including base64 support.
+ * See http://www.faqs.org/rfcs/rfc2849.html
+ */
+static char *
+ldif_parse_attribute(char *str)
+{
+ bool encoded = false;
+ char *attr, *ep;
+ size_t len;
+ debug_decl(ldif_parse_attribute, SUDOERS_DEBUG_UTIL)
+
+ /* Check for foo:: base64str. */
+ if (*str == ':') {
+ encoded = true;
+ str++;
+ }
+
+ /* Trim leading and trailing space. */
+ while (*str == ' ')
+ str++;
+
+ ep = str + strlen(str);
+ while (ep > str && ep[-1] == ' ') {
+ ep--;
+ /* Don't trim escaped trailing space if not base64. */
+ if (!encoded && ep != str && ep[-1] == '\\')
+ break;
+ *ep = '\0';
+ }
+
+ attr = str;
+ if (encoded) {
+ /*
+ * Decode base64 inline and add NUL-terminator.
+ * The copy allows us to provide a useful message on error.
+ */
+ char *copy = strdup(str);
+ if (copy == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ len = base64_decode(copy, (unsigned char *)attr, strlen(attr));
+ if (len == (size_t)-1) {
+ sudo_warnx(U_("ignoring invalid attribute value: %s"), copy);
+ free(copy);
+ debug_return_str(NULL);
+ }
+ attr[len] = '\0';
+ free(copy);
+ }
+
+ debug_return_str(attr);
+}
+
+/*
+ * Allocate a struct sudoers_string, store str in it and
+ * insert into the specified strlist.
+ */
+static void
+ldif_store_string(const char *str, struct sudoers_str_list *strlist, bool sorted)
+{
+ struct sudoers_string *ls;
+ debug_decl(ldif_store_string, SUDOERS_DEBUG_UTIL)
+
+ if ((ls = sudoers_string_alloc(str)) == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ if (!sorted) {
+ STAILQ_INSERT_TAIL(strlist, ls, entries);
+ } else {
+ struct sudoers_string *prev, *next;
+
+ /* Insertion sort, list is small. */
+ prev = STAILQ_FIRST(strlist);
+ if (prev == NULL || strcasecmp(str, prev->str) <= 0) {
+ STAILQ_INSERT_HEAD(strlist, ls, entries);
+ } else {
+ while ((next = STAILQ_NEXT(prev, entries)) != NULL) {
+ if (strcasecmp(str, next->str) <= 0)
+ break;
+ prev = next;
+ }
+ STAILQ_INSERT_AFTER(strlist, prev, ls, entries);
+ }
+ }
+
+ debug_return;
+}
+
+/*
+ * Iterator for sudo_ldap_role_to_priv().
+ * Takes a pointer to a struct sudoers_string *.
+ * Returns the string or NULL if we've reached the end.
+ */
+static char *
+sudoers_string_iter(void **vp)
+{
+ struct sudoers_string *ls = *vp;
+
+ if (ls == NULL)
+ return NULL;
+
+ *vp = STAILQ_NEXT(ls, entries);
+
+ return ls->str;
+}
+
+static int
+role_order_cmp(const void *va, const void *vb)
+{
+ const struct sudo_role *a = *(const struct sudo_role **)va;
+ const struct sudo_role *b = *(const struct sudo_role **)vb;
+ debug_decl(role_order_cmp, SUDOERS_DEBUG_LDAP)
+
+ debug_return_int(a->order < b->order ? -1 :
+ (a->order > b->order ? 1 : 0));
+}
+
+/*
+ * Parse list of sudoOption and store in the parse tree's defaults list.
+ */
+static void
+ldif_store_options(struct sudoers_parse_tree *parse_tree,
+ struct sudoers_str_list *options)
+{
+ struct defaults *d;
+ struct sudoers_string *ls;
+ char *var, *val;
+ debug_decl(ldif_store_options, SUDOERS_DEBUG_UTIL)
+
+ STAILQ_FOREACH(ls, options, entries) {
+ if ((d = calloc(1, sizeof(*d))) == NULL ||
+ (d->binding = malloc(sizeof(*d->binding))) == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ TAILQ_INIT(d->binding);
+ d->type = DEFAULTS;
+ d->op = sudo_ldap_parse_option(ls->str, &var, &val);
+ if ((d->var = strdup(var)) == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ if (val != NULL) {
+ if ((d->val = strdup(val)) == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ }
+ TAILQ_INSERT_TAIL(&parse_tree->defaults, d, entries);
+ }
+ debug_return;
+}
+
+static int
+str_list_cmp(const void *aa, const void *bb)
+{
+ const struct sudoers_str_list *a = aa;
+ const struct sudoers_str_list *b = bb;
+ const struct sudoers_string *lsa = STAILQ_FIRST(a);
+ const struct sudoers_string *lsb = STAILQ_FIRST(b);
+ int ret;
+
+ while (lsa != NULL && lsb != NULL) {
+ if ((ret = strcmp(lsa->str, lsb->str)) != 0)
+ return ret;
+ lsa = STAILQ_NEXT(lsa, entries);
+ lsb = STAILQ_NEXT(lsb, entries);
+ }
+ return lsa == lsb ? 0 : (lsa == NULL ? -1 : 1);
+}
+
+static int
+str_list_cache(struct rbtree *cache, struct sudoers_str_list **strlistp)
+{
+ struct sudoers_str_list *strlist = *strlistp;
+ struct rbnode *node;
+ int ret;
+ debug_decl(str_list_cache, SUDOERS_DEBUG_UTIL)
+
+ ret = rbinsert(cache, strlist, &node);
+ switch (ret) {
+ case 0:
+ /* new entry, take a ref for the cache */
+ strlist->refcnt++;
+ break;
+ case 1:
+ /* already exists, use existing and take a ref. */
+ str_list_free(strlist);
+ strlist = node->data;
+ strlist->refcnt++;
+ *strlistp = strlist;
+ break;
+ }
+ debug_return_int(ret);
+}
+
+/*
+ * Convert a sudoRole to sudoers format and store in the parse tree.
+ */
+static void
+role_to_sudoers(struct sudoers_parse_tree *parse_tree, struct sudo_role *role,
+ bool store_options, bool reuse_userspec, bool reuse_privilege,
+ bool reuse_runas)
+{
+ struct privilege *priv;
+ struct sudoers_string *ls;
+ struct userspec *us;
+ struct member *m;
+ debug_decl(role_to_sudoers, SUDOERS_DEBUG_UTIL)
+
+ /*
+ * TODO: use cn to create a UserAlias if multiple users in it?
+ */
+
+ if (reuse_userspec) {
+ /* Re-use the previous userspec */
+ us = TAILQ_LAST(&parse_tree->userspecs, userspec_list);
+ } else {
+ /* Allocate a new userspec and fill in the user list. */
+ if ((us = calloc(1, sizeof(*us))) == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ TAILQ_INIT(&us->privileges);
+ TAILQ_INIT(&us->users);
+ STAILQ_INIT(&us->comments);
+
+ STAILQ_FOREACH(ls, role->users, entries) {
+ char *user = ls->str;
+
+ if ((m = calloc(1, sizeof(*m))) == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ m->negated = sudo_ldap_is_negated(&user);
+ m->name = strdup(user);
+ if (m->name == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ if (strcmp(user, "ALL") == 0) {
+ m->type = ALL;
+ } else if (*user == '+') {
+ m->type = NETGROUP;
+ } else if (*user == '%') {
+ m->type = USERGROUP;
+ } else {
+ m->type = WORD;
+ }
+ TAILQ_INSERT_TAIL(&us->users, m, entries);
+ }
+ }
+
+ /* Add source role as a comment. */
+ if (role->cn != NULL) {
+ struct sudoers_comment *comment = NULL;
+ if (reuse_userspec) {
+ /* Try to re-use comment too. */
+ STAILQ_FOREACH(comment, &us->comments, entries) {
+ if (strncmp(comment->str, "sudoRole ", 9) == 0) {
+ char *tmpstr;
+ if (asprintf(&tmpstr, "%s, %s", comment->str, role->cn) == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ free(comment->str);
+ comment->str = tmpstr;
+ break;
+ }
+ }
+ }
+ if (comment == NULL) {
+ /* Create a new comment. */
+ if ((comment = malloc(sizeof(*comment))) == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ if (asprintf(&comment->str, "sudoRole %s", role->cn) == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ STAILQ_INSERT_TAIL(&us->comments, comment, entries);
+ }
+ }
+
+ /* Convert role to sudoers privilege. */
+ priv = sudo_ldap_role_to_priv(role->cn, STAILQ_FIRST(role->hosts),
+ STAILQ_FIRST(role->runasusers), STAILQ_FIRST(role->runasgroups),
+ STAILQ_FIRST(role->cmnds), STAILQ_FIRST(role->options),
+ role->notbefore, role->notafter, true, store_options,
+ sudoers_string_iter);
+ if (priv == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+
+ if (reuse_privilege) {
+ /* Hostspec unchanged, append cmndlist to previous privilege. */
+ struct privilege *prev_priv = TAILQ_LAST(&us->privileges, privilege_list);
+ if (reuse_runas) {
+ /* Runas users and groups same if as in previous privilege. */
+ struct member_list *runasuserlist =
+ TAILQ_FIRST(&prev_priv->cmndlist)->runasuserlist;
+ struct member_list *runasgrouplist =
+ TAILQ_FIRST(&prev_priv->cmndlist)->runasgrouplist;
+ struct cmndspec *cmndspec = TAILQ_FIRST(&priv->cmndlist);
+
+ /* Free duplicate runas lists. */
+ if (cmndspec->runasuserlist != NULL) {
+ free_members(cmndspec->runasuserlist);
+ free(cmndspec->runasuserlist);
+ }
+ if (cmndspec->runasgrouplist != NULL) {
+ free_members(cmndspec->runasgrouplist);
+ free(cmndspec->runasgrouplist);
+ }
+
+ /* Update cmndspec with previous runas lists. */
+ TAILQ_FOREACH(cmndspec, &priv->cmndlist, entries) {
+ cmndspec->runasuserlist = runasuserlist;
+ cmndspec->runasgrouplist = runasgrouplist;
+ }
+ }
+ TAILQ_CONCAT(&prev_priv->cmndlist, &priv->cmndlist, entries);
+ free_privilege(priv);
+ } else {
+ TAILQ_INSERT_TAIL(&us->privileges, priv, entries);
+ }
+
+ /* Add finished userspec to the list if new. */
+ if (!reuse_userspec)
+ TAILQ_INSERT_TAIL(&parse_tree->userspecs, us, entries);
+
+ debug_return;
+}
+
+/*
+ * Convert the list of sudoRoles to sudoers format and store in the parse tree.
+ */
+static void
+ldif_to_sudoers(struct sudoers_parse_tree *parse_tree,
+ struct sudo_role_list *roles, unsigned int numroles, bool store_options)
+{
+ struct sudo_role **role_array, *role = NULL;
+ unsigned int n;
+ debug_decl(ldif_to_sudoers, SUDOERS_DEBUG_UTIL)
+
+ /* Convert from list of roles to array and sort by order. */
+ role_array = reallocarray(NULL, numroles + 1, sizeof(*role_array));
+ for (n = 0; n < numroles; n++) {
+ if ((role = STAILQ_FIRST(roles)) == NULL)
+ break; /* cannot happen */
+ STAILQ_REMOVE_HEAD(roles, entries);
+ role_array[n] = role;
+ }
+ role_array[n] = NULL;
+ qsort(role_array, numroles, sizeof(*role_array), role_order_cmp);
+
+ /*
+ * Iterate over roles in sorted order, converting to sudoers.
+ */
+ for (n = 0; n < numroles; n++) {
+ bool reuse_userspec = false;
+ bool reuse_privilege = false;
+ bool reuse_runas = false;
+
+ role = role_array[n];
+
+ /* Check whether we can reuse the previous user and host specs */
+ if (n > 0 && role->users == role_array[n - 1]->users) {
+ reuse_userspec = true;
+
+ /*
+ * Since options are stored per-privilege we can't
+ * append to the previous privilege's cmndlist if
+ * we are storing options.
+ */
+ if (!store_options) {
+ if (role->hosts == role_array[n - 1]->hosts) {
+ reuse_privilege = true;
+
+ /* Reuse runasusers and runasgroups if possible. */
+ if (role->runasusers == role_array[n - 1]->runasusers &&
+ role->runasgroups == role_array[n - 1]->runasgroups)
+ reuse_runas = true;
+ }
+ }
+ }
+
+ role_to_sudoers(parse_tree, role, store_options, reuse_userspec,
+ reuse_privilege, reuse_runas);
+ }
+
+ /* Clean up. */
+ for (n = 0; n < numroles; n++)
+ sudo_role_free(role_array[n]);
+ free(role_array);
+
+ debug_return;
+}
+
+/*
+ * Given a cn with possible quoted characters, return a copy of
+ * the cn with quote characters ('\\') removed.
+ * The caller is responsible for freeing the returned string.
+ */
+static
+char *unquote_cn(const char *src)
+{
+ char *dst, *new_cn;
+ size_t len;
+ debug_decl(unquote_cn, SUDOERS_DEBUG_UTIL)
+
+ len = strlen(src);
+ if ((new_cn = malloc(len + 1)) == NULL)
+ debug_return_str(NULL);
+
+ for (dst = new_cn; *src != '\0';) {
+ if (src[0] == '\\' && src[1] != '\0')
+ src++;
+ *dst++ = *src++;
+ }
+ *dst = '\0';
+
+ debug_return_str(new_cn);
+}
+
+/*
+ * Parse a sudoers file in LDIF format, https://tools.ietf.org/html/rfc2849
+ * Parsed sudoRole objects are stored in the specified parse_tree which
+ * must already be initialized.
+ */
+bool
+sudoers_parse_ldif(struct sudoers_parse_tree *parse_tree,
+ FILE *fp, const char *sudoers_base, bool store_options)
+{
+ struct sudo_role_list roles = STAILQ_HEAD_INITIALIZER(roles);
+ struct sudo_role *role = NULL;
+ struct rbtree *usercache, *groupcache, *hostcache;
+ unsigned numroles = 0;
+ bool in_role = false;
+ size_t linesize = 0;
+ char *attr, *line = NULL, *savedline = NULL;
+ ssize_t savedlen = 0;
+ bool mismatch = false;
+ debug_decl(sudoers_parse_ldif, SUDOERS_DEBUG_UTIL)
+
+ /* Free old contents of the parse tree (if any). */
+ free_parse_tree(parse_tree);
+
+ /*
+ * We cache user, group and host lists to make it eay to detect when there
+ * are identical lists (simple pointer compare). This makes it possible
+ * to merge multiplpe sudoRole objects into a single UserSpec and/or
+ * Privilege. The lists are sorted since LDAP order is arbitrary.
+ */
+ usercache = rbcreate(str_list_cmp);
+ groupcache = rbcreate(str_list_cmp);
+ hostcache = rbcreate(str_list_cmp);
+ if (usercache == NULL || groupcache == NULL || hostcache == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+ /* Read through input, parsing into sudo_roles and global defaults. */
+ for (;;) {
+ int ch;
+ ssize_t len = getline(&line, &linesize, fp);
+
+ /* Trim trailing return or newline. */
+ while (len > 0 && (line[len - 1] == '\r' || line[len - 1] == '\n'))
+ line[--len] = '\0';
+
+ /* Blank line or EOF terminates an entry. */
+ if (len <= 0) {
+ if (in_role) {
+ if (role->cn != NULL && strcmp(role->cn, "defaults") == 0) {
+ ldif_store_options(parse_tree, role->options);
+ sudo_role_free(role);
+ } else if (STAILQ_EMPTY(role->users) ||
+ STAILQ_EMPTY(role->hosts) || STAILQ_EMPTY(role->cmnds)) {
+ /* Incomplete role. */
+ sudo_warnx(U_("ignoring incomplete sudoRole: cn: %s"),
+ role->cn ? role->cn : "UNKNOWN");
+ sudo_role_free(role);
+ } else {
+ /* Cache users, hosts, runasusers and runasgroups. */
+ if (str_list_cache(usercache, &role->users) == -1 ||
+ str_list_cache(hostcache, &role->hosts) == -1 ||
+ str_list_cache(usercache, &role->runasusers) == -1 ||
+ str_list_cache(groupcache, &role->runasgroups) == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+
+ /* Store finished role. */
+ STAILQ_INSERT_TAIL(&roles, role, entries);
+ numroles++;
+ }
+ role = NULL;
+ in_role = false;
+ }
+ if (len == -1) {
+ /* EOF */
+ break;
+ }
+ mismatch = false;
+ continue;
+ }
+
+ if (savedline != NULL) {
+ char *tmp;
+
+ /* Append to saved line. */
+ linesize = savedlen + len + 1;
+ if ((tmp = realloc(savedline, linesize)) == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ memcpy(tmp + savedlen, line, len + 1);
+ free(line);
+ line = tmp;
+ savedline = NULL;
+ } else {
+ /* Skip comment lines or records that don't match the base. */
+ if (*line == '#' || mismatch)
+ continue;
+ }
+
+ /* Check for folded line */
+ if ((ch = getc(fp)) == ' ') {
+ /* folded line, append to the saved portion. */
+ savedlen = len;
+ savedline = line;
+ line = NULL;
+ linesize = 0;
+ continue;
+ } else {
+ /* not folded, push back ch */
+ ungetc(ch, fp);
+ }
+
+ /* Parse dn and objectClass. */
+ if (strncasecmp(line, "dn:", 3) == 0) {
+ /* Compare dn to base, if specified. */
+ if (sudoers_base != NULL) {
+ attr = ldif_parse_attribute(line + 3);
+ if (attr == NULL) {
+ /* invalid attribute */
+ mismatch = true;
+ continue;
+ }
+ /* Skip over cn if present. */
+ if (strncasecmp(attr, "cn=", 3) == 0) {
+ for (attr += 3; *attr != '\0'; attr++) {
+ /* Handle escaped ',' chars. */
+ if (*attr == '\\')
+ attr++;
+ if (*attr == ',') {
+ attr++;
+ break;
+ }
+ }
+ }
+ if (strcasecmp(attr, sudoers_base) != 0) {
+ /* Doesn't match base, skip the rest of it. */
+ mismatch = true;
+ continue;
+ }
+ }
+ } else if (strncmp(line, "objectClass:", 12) == 0) {
+ attr = ldif_parse_attribute(line + 12);
+ if (attr != NULL && strcmp(attr, "sudoRole") == 0) {
+ /* Allocate new role as needed. */
+ if (role == NULL) {
+ if ((role = sudo_role_alloc()) == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ }
+ in_role = true;
+ }
+ }
+
+ /* Not in a sudoRole, keep reading. */
+ if (!in_role)
+ continue;
+
+ /* Part of a sudoRole, parse it. */
+ if (strncmp(line, "cn:", 3) == 0) {
+ attr = ldif_parse_attribute(line + 3);
+ if (attr != NULL) {
+ free(role->cn);
+ role->cn = unquote_cn(attr);
+ if (role->cn == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ }
+ } else if (strncmp(line, "sudoUser:", 9) == 0) {
+ attr = ldif_parse_attribute(line + 9);
+ if (attr != NULL)
+ ldif_store_string(attr, role->users, true);
+ } else if (strncmp(line, "sudoHost:", 9) == 0) {
+ attr = ldif_parse_attribute(line + 9);
+ if (attr != NULL)
+ ldif_store_string(attr, role->hosts, true);
+ } else if (strncmp(line, "sudoRunAs:", 10) == 0) {
+ attr = ldif_parse_attribute(line + 10);
+ if (attr != NULL)
+ ldif_store_string(attr, role->runasusers, true);
+ } else if (strncmp(line, "sudoRunAsUser:", 14) == 0) {
+ attr = ldif_parse_attribute(line + 14);
+ if (attr != NULL)
+ ldif_store_string(attr, role->runasusers, true);
+ } else if (strncmp(line, "sudoRunAsGroup:", 15) == 0) {
+ attr = ldif_parse_attribute(line + 15);
+ if (attr != NULL)
+ ldif_store_string(attr, role->runasgroups, true);
+ } else if (strncmp(line, "sudoCommand:", 12) == 0) {
+ attr = ldif_parse_attribute(line + 12);
+ if (attr != NULL)
+ ldif_store_string(attr, role->cmnds, false);
+ } else if (strncmp(line, "sudoOption:", 11) == 0) {
+ attr = ldif_parse_attribute(line + 11);
+ if (attr != NULL)
+ ldif_store_string(attr, role->options, false);
+ } else if (strncmp(line, "sudoOrder:", 10) == 0) {
+ char *ep;
+ attr = ldif_parse_attribute(line + 10);
+ if (attr != NULL) {
+ role->order = strtod(attr, &ep);
+ if (ep == attr || *ep != '\0')
+ sudo_warnx(U_("invalid sudoOrder attribute: %s"), attr);
+ }
+ } else if (strncmp(line, "sudoNotBefore:", 14) == 0) {
+ attr = ldif_parse_attribute(line + 14);
+ if (attr != NULL) {
+ free(role->notbefore);
+ role->notbefore = strdup(attr);
+ if (role->notbefore == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ }
+ } else if (strncmp(line, "sudoNotAfter:", 13) == 0) {
+ attr = ldif_parse_attribute(line + 13);
+ if (attr != NULL) {
+ free(role->notafter);
+ role->notafter = strdup(attr);
+ if (role->notafter == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ }
+ }
+ }
+ sudo_role_free(role);
+ free(line);
+
+ /* Convert from roles to sudoers data structures. */
+ ldif_to_sudoers(parse_tree, &roles, numroles, store_options);
+
+ /* Clean up. */
+ rbdestroy(usercache, str_list_free);
+ rbdestroy(groupcache, str_list_free);
+ rbdestroy(hostcache, str_list_free);
+
+ if (fp != stdin)
+ fclose(fp);
+
+ debug_return_bool(true);
+}
diff --git a/plugins/sudoers/po/README b/plugins/sudoers/po/README
new file mode 100644
index 0000000..ff9b845
--- /dev/null
+++ b/plugins/sudoers/po/README
@@ -0,0 +1,14 @@
+NLS Translations for sudo are coordinated through the Translation
+Project, at http://translationproject.org/
+
+If you would like to contribute a translation for sudo, please join
+a translation team at the Translation Project instead of contributing
+a po file directly. This will avoid duplicated work if there is
+already a translation in progress. If you would like to become a
+member of a translation team, please follow the instructions at
+http://translationproject.org/html/translators.html
+
+The messages in sudo are split into two domains: sudo and sudoers.
+The former is used by the sudo front-end and utility functions.
+The latter is used by the sudoers policy and I/O logging plug-ins
+as well as the sudoers-specific commands visudo and sudoreplay.
diff --git a/plugins/sudoers/po/ca.mo b/plugins/sudoers/po/ca.mo
new file mode 100644
index 0000000..c6cf548
--- /dev/null
+++ b/plugins/sudoers/po/ca.mo
Binary files differ
diff --git a/plugins/sudoers/po/ca.po b/plugins/sudoers/po/ca.po
new file mode 100644
index 0000000..bfa425f
--- /dev/null
+++ b/plugins/sudoers/po/ca.po
@@ -0,0 +1,2081 @@
+# Portable object template file for the sudoers plugin
+# This file is put in the public domain.
+# Walter Garcia-Fontes <walter.garcia@upf.edu>, 2016.
+#
+# Glossari
+#
+# principal - Es refereix a "Principals may represent users, network hosts, or network services. A principal that corresponds to a network host is called a host principal", s'ha traduït com a "principal".
+# tty - el terminal, això prové de l'acrònim en anglès per a teletip (tty) i ara s'usa per a un terminal obert on es pot entrar informació
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.19b2\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2016-12-03 19:24-0700\n"
+"PO-Revision-Date: 2016-12-29 17:28+0100\n"
+"Last-Translator: Walter Garcia-Fontes <walter.garcia@upf.edu>\n"
+"Language-Team: Catalan <ca@dodds.net>\n"
+"Language: ca\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "error de sintaxi"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "contrasenya de %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] contrasenya per a %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Contrasenya: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** Informació de SEGURETAT per a %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Ho sentim, proveu un altre cop."
+
+#: gram.y:186 gram.y:234 gram.y:241 gram.y:248 gram.y:255 gram.y:262
+#: gram.y:278 gram.y:301 gram.y:308 gram.y:315 gram.y:322 gram.y:329
+#: gram.y:384 gram.y:392 gram.y:402 gram.y:432 gram.y:439 gram.y:446
+#: gram.y:453 gram.y:565 gram.y:572 gram.y:581 gram.y:590 gram.y:607
+#: gram.y:663 gram.y:670 gram.y:677 gram.y:685 gram.y:781 gram.y:788
+#: gram.y:795 gram.y:802 gram.y:809 gram.y:835 gram.y:842 gram.y:849
+#: gram.y:972 gram.y:1148 gram.y:1155 plugins/sudoers/alias.c:124
+#: plugins/sudoers/alias.c:139 plugins/sudoers/auth/bsdauth.c:141
+#: plugins/sudoers/auth/kerb5.c:119 plugins/sudoers/auth/kerb5.c:145
+#: plugins/sudoers/auth/pam.c:443 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/auth/sia.c:59 plugins/sudoers/defaults.c:618
+#: plugins/sudoers/defaults.c:873 plugins/sudoers/defaults.c:1025
+#: plugins/sudoers/editor.c:64 plugins/sudoers/editor.c:82
+#: plugins/sudoers/editor.c:93 plugins/sudoers/env.c:234
+#: plugins/sudoers/gc.c:52 plugins/sudoers/group_plugin.c:134
+#: plugins/sudoers/interfaces.c:71 plugins/sudoers/iolog.c:805
+#: plugins/sudoers/iolog_path.c:167 plugins/sudoers/ldap.c:447
+#: plugins/sudoers/ldap.c:478 plugins/sudoers/ldap.c:530
+#: plugins/sudoers/ldap.c:563 plugins/sudoers/ldap.c:961
+#: plugins/sudoers/ldap.c:1157 plugins/sudoers/ldap.c:1168
+#: plugins/sudoers/ldap.c:1184 plugins/sudoers/ldap.c:1471
+#: plugins/sudoers/ldap.c:1631 plugins/sudoers/ldap.c:1713
+#: plugins/sudoers/ldap.c:1853 plugins/sudoers/ldap.c:1877
+#: plugins/sudoers/ldap.c:1966 plugins/sudoers/ldap.c:1981
+#: plugins/sudoers/ldap.c:2077 plugins/sudoers/ldap.c:2110
+#: plugins/sudoers/ldap.c:2263 plugins/sudoers/ldap.c:2360
+#: plugins/sudoers/ldap.c:3178 plugins/sudoers/ldap.c:3210
+#: plugins/sudoers/ldap.c:3519 plugins/sudoers/ldap.c:3547
+#: plugins/sudoers/ldap.c:3563 plugins/sudoers/ldap.c:3653
+#: plugins/sudoers/ldap.c:3669 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:188 plugins/sudoers/logging.c:450
+#: plugins/sudoers/logging.c:471 plugins/sudoers/logging.c:683
+#: plugins/sudoers/logging.c:941 plugins/sudoers/match.c:501
+#: plugins/sudoers/match.c:535 plugins/sudoers/match.c:572
+#: plugins/sudoers/match.c:770 plugins/sudoers/match.c:828
+#: plugins/sudoers/parse.c:236 plugins/sudoers/parse.c:248
+#: plugins/sudoers/parse.c:263 plugins/sudoers/parse.c:275
+#: plugins/sudoers/policy.c:405 plugins/sudoers/policy.c:632
+#: plugins/sudoers/prompt.c:93 plugins/sudoers/pwutil.c:139
+#: plugins/sudoers/pwutil.c:210 plugins/sudoers/pwutil.c:286
+#: plugins/sudoers/pwutil.c:457 plugins/sudoers/pwutil.c:522
+#: plugins/sudoers/pwutil.c:591 plugins/sudoers/pwutil.c:749
+#: plugins/sudoers/pwutil.c:806 plugins/sudoers/pwutil.c:851
+#: plugins/sudoers/pwutil.c:908 plugins/sudoers/sssd.c:162
+#: plugins/sudoers/sssd.c:194 plugins/sudoers/sssd.c:237
+#: plugins/sudoers/sssd.c:244 plugins/sudoers/sssd.c:280
+#: plugins/sudoers/sssd.c:390 plugins/sudoers/sssd.c:462
+#: plugins/sudoers/sssd.c:1053 plugins/sudoers/sssd.c:1234
+#: plugins/sudoers/sssd.c:1248 plugins/sudoers/sssd.c:1264
+#: plugins/sudoers/sudoers.c:261 plugins/sudoers/sudoers.c:271
+#: plugins/sudoers/sudoers.c:279 plugins/sudoers/sudoers.c:363
+#: plugins/sudoers/sudoers.c:660 plugins/sudoers/sudoers.c:775
+#: plugins/sudoers/sudoers.c:819 plugins/sudoers/sudoers_debug.c:107
+#: plugins/sudoers/sudoreplay.c:517 plugins/sudoers/sudoreplay.c:716
+#: plugins/sudoers/sudoreplay.c:828 plugins/sudoers/sudoreplay.c:868
+#: plugins/sudoers/sudoreplay.c:877 plugins/sudoers/sudoreplay.c:887
+#: plugins/sudoers/sudoreplay.c:895 plugins/sudoers/sudoreplay.c:899
+#: plugins/sudoers/sudoreplay.c:1055 plugins/sudoers/sudoreplay.c:1059
+#: plugins/sudoers/testsudoers.c:130 plugins/sudoers/testsudoers.c:216
+#: plugins/sudoers/testsudoers.c:233 plugins/sudoers/timestamp.c:374
+#: plugins/sudoers/timestamp.c:418 plugins/sudoers/timestamp.c:834
+#: plugins/sudoers/toke_util.c:56 plugins/sudoers/toke_util.c:109
+#: plugins/sudoers/toke_util.c:146 plugins/sudoers/visudo.c:152
+#: plugins/sudoers/visudo.c:309 plugins/sudoers/visudo.c:315
+#: plugins/sudoers/visudo.c:446 plugins/sudoers/visudo.c:624
+#: plugins/sudoers/visudo.c:964 plugins/sudoers/visudo.c:1030
+#: plugins/sudoers/visudo.c:1074 plugins/sudoers/visudo.c:1171
+#: plugins/sudoers/visudo_json.c:1035 toke.l:832 toke.l:932 toke.l:1090
+msgid "unable to allocate memory"
+msgstr "no es pot assignar memòria"
+
+#: gram.y:464
+msgid "a digest requires a path name"
+msgstr "au un resum li cal un nom de camí"
+
+#: gram.y:1148 gram.y:1155 plugins/sudoers/auth/pam.c:320
+#: plugins/sudoers/auth/pam.c:443 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/defaults.c:618 plugins/sudoers/defaults.c:873
+#: plugins/sudoers/defaults.c:1025 plugins/sudoers/editor.c:64
+#: plugins/sudoers/editor.c:82 plugins/sudoers/editor.c:93
+#: plugins/sudoers/env.c:234 plugins/sudoers/gc.c:52
+#: plugins/sudoers/group_plugin.c:134 plugins/sudoers/interfaces.c:71
+#: plugins/sudoers/iolog.c:805 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:447 plugins/sudoers/ldap.c:478
+#: plugins/sudoers/ldap.c:530 plugins/sudoers/ldap.c:563
+#: plugins/sudoers/ldap.c:961 plugins/sudoers/ldap.c:1157
+#: plugins/sudoers/ldap.c:1168 plugins/sudoers/ldap.c:1184
+#: plugins/sudoers/ldap.c:1471 plugins/sudoers/ldap.c:1631
+#: plugins/sudoers/ldap.c:1713 plugins/sudoers/ldap.c:1853
+#: plugins/sudoers/ldap.c:1877 plugins/sudoers/ldap.c:1966
+#: plugins/sudoers/ldap.c:1981 plugins/sudoers/ldap.c:2077
+#: plugins/sudoers/ldap.c:2110 plugins/sudoers/ldap.c:2263
+#: plugins/sudoers/ldap.c:2360 plugins/sudoers/ldap.c:3178
+#: plugins/sudoers/ldap.c:3210 plugins/sudoers/ldap.c:3519
+#: plugins/sudoers/ldap.c:3546 plugins/sudoers/ldap.c:3562
+#: plugins/sudoers/ldap.c:3653 plugins/sudoers/ldap.c:3669
+#: plugins/sudoers/linux_audit.c:76 plugins/sudoers/logging.c:188
+#: plugins/sudoers/logging.c:450 plugins/sudoers/logging.c:471
+#: plugins/sudoers/logging.c:941 plugins/sudoers/match.c:500
+#: plugins/sudoers/match.c:534 plugins/sudoers/match.c:572
+#: plugins/sudoers/match.c:770 plugins/sudoers/match.c:827
+#: plugins/sudoers/parse.c:236 plugins/sudoers/parse.c:248
+#: plugins/sudoers/parse.c:263 plugins/sudoers/parse.c:275
+#: plugins/sudoers/policy.c:97 plugins/sudoers/policy.c:106
+#: plugins/sudoers/policy.c:115 plugins/sudoers/policy.c:139
+#: plugins/sudoers/policy.c:250 plugins/sudoers/policy.c:278
+#: plugins/sudoers/policy.c:287 plugins/sudoers/policy.c:326
+#: plugins/sudoers/policy.c:336 plugins/sudoers/policy.c:345
+#: plugins/sudoers/policy.c:354 plugins/sudoers/policy.c:405
+#: plugins/sudoers/policy.c:632 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/pwutil.c:139 plugins/sudoers/pwutil.c:210
+#: plugins/sudoers/pwutil.c:286 plugins/sudoers/pwutil.c:457
+#: plugins/sudoers/pwutil.c:522 plugins/sudoers/pwutil.c:591
+#: plugins/sudoers/pwutil.c:749 plugins/sudoers/pwutil.c:806
+#: plugins/sudoers/pwutil.c:851 plugins/sudoers/pwutil.c:908
+#: plugins/sudoers/set_perms.c:356 plugins/sudoers/set_perms.c:695
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1350
+#: plugins/sudoers/set_perms.c:1514 plugins/sudoers/sssd.c:162
+#: plugins/sudoers/sssd.c:194 plugins/sudoers/sssd.c:237
+#: plugins/sudoers/sssd.c:244 plugins/sudoers/sssd.c:280
+#: plugins/sudoers/sssd.c:390 plugins/sudoers/sssd.c:462
+#: plugins/sudoers/sssd.c:1053 plugins/sudoers/sssd.c:1233
+#: plugins/sudoers/sssd.c:1248 plugins/sudoers/sssd.c:1264
+#: plugins/sudoers/sudoers.c:261 plugins/sudoers/sudoers.c:271
+#: plugins/sudoers/sudoers.c:279 plugins/sudoers/sudoers.c:363
+#: plugins/sudoers/sudoers.c:660 plugins/sudoers/sudoers.c:775
+#: plugins/sudoers/sudoers.c:819 plugins/sudoers/sudoers_debug.c:106
+#: plugins/sudoers/sudoreplay.c:517 plugins/sudoers/sudoreplay.c:716
+#: plugins/sudoers/sudoreplay.c:828 plugins/sudoers/sudoreplay.c:868
+#: plugins/sudoers/sudoreplay.c:877 plugins/sudoers/sudoreplay.c:887
+#: plugins/sudoers/sudoreplay.c:895 plugins/sudoers/sudoreplay.c:899
+#: plugins/sudoers/sudoreplay.c:1055 plugins/sudoers/sudoreplay.c:1059
+#: plugins/sudoers/testsudoers.c:130 plugins/sudoers/testsudoers.c:216
+#: plugins/sudoers/testsudoers.c:233 plugins/sudoers/timestamp.c:374
+#: plugins/sudoers/timestamp.c:418 plugins/sudoers/timestamp.c:834
+#: plugins/sudoers/toke_util.c:56 plugins/sudoers/toke_util.c:109
+#: plugins/sudoers/toke_util.c:146 plugins/sudoers/visudo.c:152
+#: plugins/sudoers/visudo.c:309 plugins/sudoers/visudo.c:315
+#: plugins/sudoers/visudo.c:446 plugins/sudoers/visudo.c:624
+#: plugins/sudoers/visudo.c:964 plugins/sudoers/visudo.c:1030
+#: plugins/sudoers/visudo.c:1074 plugins/sudoers/visudo.c:1171
+#: plugins/sudoers/visudo_json.c:1035 toke.l:832 toke.l:932 toke.l:1090
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:135
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "L'àlies «%s» ja està definit"
+
+#: plugins/sudoers/auth/bsdauth.c:68
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "no s'ha pogut obtenir la classe d'inici de sessió per a l'usuari %s"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+msgid "unable to begin bsd authentication"
+msgstr "no s'ha pogut iniciar l'autenticació bsd"
+
+#: plugins/sudoers/auth/bsdauth.c:81
+msgid "invalid authentication type"
+msgstr "tipus no vàlida d'autenticació"
+
+#: plugins/sudoers/auth/bsdauth.c:90
+msgid "unable to initialize BSD authentication"
+msgstr "no s'ha pogut inicialitzar l'autenticació BSD"
+
+#: plugins/sudoers/auth/fwtk.c:52
+msgid "unable to read fwtk config"
+msgstr "no s'ha pogut llegir la configuració fwtk"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to connect to authentication server"
+msgstr "no s'ha pogut connectar al servidor d'autenticació"
+
+#: plugins/sudoers/auth/fwtk.c:63 plugins/sudoers/auth/fwtk.c:87
+#: plugins/sudoers/auth/fwtk.c:121
+msgid "lost connection to authentication server"
+msgstr "s'ha perdut la connexió al servidor d'autenticació"
+
+#: plugins/sudoers/auth/fwtk.c:67
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"error de servidor d'autenticació:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:111
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: no s'ha pogut convertir el principal a la cadena de caràcters ('%s'): %s"
+
+#: plugins/sudoers/auth/kerb5.c:161
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: no s'ha pogut analitzar '%s': %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: no s'ha pogut resoldre el cau de credencials : %s"
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: no s'han pogut assignar les opcions: %s"
+
+#: plugins/sudoers/auth/kerb5.c:232
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: no s'ha pogut obtenir les credencials: %s"
+
+#: plugins/sudoers/auth/kerb5.c:245
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: no s'ha pogut inicialitzar el cau de credencials: %s"
+
+#: plugins/sudoers/auth/kerb5.c:248
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: no s'ha pogut emmagatzemar la credencial al cau: %s"
+
+#: plugins/sudoers/auth/kerb5.c:312
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: no s'ha pogut obtenir el principal de l'amfitrió: %s"
+
+#: plugins/sudoers/auth/kerb5.c:326
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: No s'ha pogut verificar TGT! Possible atac!: %s"
+
+#: plugins/sudoers/auth/pam.c:108
+msgid "unable to initialize PAM"
+msgstr "No s'ha pogut inicialitzar PAM"
+
+#: plugins/sudoers/auth/pam.c:194
+msgid "account validation failure, is your account locked?"
+msgstr "fallada de validació de compte, està bloquejat el vostre compte?"
+
+#: plugins/sudoers/auth/pam.c:198
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Ha expirat el compte o la contrasenya, restabliu la vostra contrasenya i proveu un altre cop"
+
+#: plugins/sudoers/auth/pam.c:206
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "no s'ha pogut canviar la contrasenya expirada: %s"
+
+#: plugins/sudoers/auth/pam.c:211
+msgid "Password expired, contact your system administrator"
+msgstr "Ha expirat la contrasenya, contacteu el vostre administrador de sistema"
+
+#: plugins/sudoers/auth/pam.c:215
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Ha expirat el compte o la configuració PAM no té una secció \"compte\" per a sudo, contacteu el vostre administrador de sistema"
+
+#: plugins/sudoers/auth/pam.c:229
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Error d'autenticació PAM: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:97 plugins/sudoers/visudo.c:226
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "no existiu a la base de dades %s"
+
+#: plugins/sudoers/auth/securid5.c:73
+msgid "failed to initialise the ACE API library"
+msgstr "ha fallat la inicialització de la biblioteca ACE API"
+
+#: plugins/sudoers/auth/securid5.c:99
+msgid "unable to contact the SecurID server"
+msgstr "no s'ha pogut contactar el servidor SecurID"
+
+#: plugins/sudoers/auth/securid5.c:108
+msgid "User ID locked for SecurID Authentication"
+msgstr "L'ID de l'usuari esta bloquejat per a Autenticació SecurID"
+
+#: plugins/sudoers/auth/securid5.c:112 plugins/sudoers/auth/securid5.c:163
+msgid "invalid username length for SecurID"
+msgstr "nom d'usuari no vàlid per a SecurID"
+
+#: plugins/sudoers/auth/securid5.c:116 plugins/sudoers/auth/securid5.c:168
+msgid "invalid Authentication Handle for SecurID"
+msgstr "Mànec d'Autenticació no vàlid per a SecurID"
+
+#: plugins/sudoers/auth/securid5.c:120
+msgid "SecurID communication failed"
+msgstr "Ha fallat la comunicació SecurID"
+
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:213
+msgid "unknown SecurID error"
+msgstr "error desconegut de SecurID"
+
+#: plugins/sudoers/auth/securid5.c:158
+msgid "invalid passcode length for SecurID"
+msgstr "longitud no vàlida de contrasenya per a SecurID"
+
+#: plugins/sudoers/auth/sia.c:69 plugins/sudoers/auth/sia.c:125
+msgid "unable to initialize SIA session"
+msgstr "no s'ha pogut inicialitzar la sessió SIA"
+
+#: plugins/sudoers/auth/sudo_auth.c:126
+msgid "invalid authentication methods"
+msgstr "mètodes no vàlids d'autenticació"
+
+#: plugins/sudoers/auth/sudo_auth.c:128
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Mètodes no vàlids d'autenticació compilats dins del sudo! No podeu barrejar l'autenticació independent i no independent."
+
+#: plugins/sudoers/auth/sudo_auth.c:224 plugins/sudoers/auth/sudo_auth.c:274
+msgid "no authentication methods"
+msgstr "no hi ha mètodes d'autenticació"
+
+#: plugins/sudoers/auth/sudo_auth.c:226
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "No hi ha mètodes d'autenticació compilats dins del sudo! Si voleu deshabilitar l'autenticació, useu l'opció de configuració --disable-authentication"
+
+#: plugins/sudoers/auth/sudo_auth.c:276
+msgid "Unable to initialize authentication methods."
+msgstr "No s'han pogut inicialitzar els mètodes d'autenticació."
+
+#: plugins/sudoers/auth/sudo_auth.c:441
+msgid "Authentication methods:"
+msgstr "Mètodes d'autenticació:"
+
+#: plugins/sudoers/bsm_audit.c:111 plugins/sudoers/bsm_audit.c:200
+msgid "Could not determine audit condition"
+msgstr "No s'ha pogut determinar la condició d'auditoria"
+
+#: plugins/sudoers/bsm_audit.c:172 plugins/sudoers/bsm_audit.c:260
+msgid "unable to commit audit record"
+msgstr "no s'ha pogut validar el registre d'auditoria"
+
+#: plugins/sudoers/check.c:252
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Confiem que heu rebut la llissó habitual de l'Administrador del\n"
+"Sistema. Generalment es resumeix en aquestes tres coses:\n"
+"\n"
+" #1) Respecteu la privacitat dels altres.\n"
+" #2) Penseu abans d'escriure.\n"
+" #3) Tenir molt de poder està associat amb tenir molta responsabilitat.\n"
+"\n"
+
+#: plugins/sudoers/check.c:295 plugins/sudoers/check.c:305
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:738
+#, c-format
+msgid "unknown uid: %u"
+msgstr "uid desconegut: %u"
+
+#: plugins/sudoers/check.c:300 plugins/sudoers/iolog.c:235
+#: plugins/sudoers/policy.c:805 plugins/sudoers/sudoers.c:1127
+#: plugins/sudoers/testsudoers.c:207 plugins/sudoers/testsudoers.c:365
+#, c-format
+msgid "unknown user: %s"
+msgstr "usuari desconegut: %s"
+
+#: plugins/sudoers/def_data.c:27
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Eina syslog si s'està usant syslog per als registres: %s"
+
+#: plugins/sudoers/def_data.c:31
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Prioritat de syslog a usar quan l'usuari s'autentica amb èxit: %s"
+
+#: plugins/sudoers/def_data.c:35
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Prioritat de syslog a usar quan l'usuari no té èxit a autenticar- %s"
+
+#: plugins/sudoers/def_data.c:39
+msgid "Put OTP prompt on its own line"
+msgstr "Poseu la pregunta OTP a la seva pròpia línia"
+
+#: plugins/sudoers/def_data.c:43
+msgid "Ignore '.' in $PATH"
+msgstr "Ignoreu '.' al $PATH"
+
+#: plugins/sudoers/def_data.c:47
+msgid "Always send mail when sudo is run"
+msgstr "Envia sempre correu electrònic quan s'executi sudo"
+
+#: plugins/sudoers/def_data.c:51
+msgid "Send mail if user authentication fails"
+msgstr "Envia correu electrònic si falla l'autenticació de l'usuari"
+
+#: plugins/sudoers/def_data.c:55
+msgid "Send mail if the user is not in sudoers"
+msgstr "Envia correu electrònic si l'usuari no està als sudoers"
+
+#: plugins/sudoers/def_data.c:59
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Envia el correu electrònic si l'usuari no està als sudoers per a aquesta amfitrió"
+
+#: plugins/sudoers/def_data.c:63
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Envia correu electrònic si l'usuari no té permís per executar aquesta ordre"
+
+#: plugins/sudoers/def_data.c:67
+msgid "Send mail if the user tries to run a command"
+msgstr "Envia correu electrònic si l'usuari intenta executar una ordre"
+
+#: plugins/sudoers/def_data.c:71
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Usa una marca horària separada per a cada combinació usuari/terminal"
+
+#: plugins/sudoers/def_data.c:75
+msgid "Lecture user the first time they run sudo"
+msgstr "Dóna una llissó a l'usuari cada cop que executi sudo"
+
+#: plugins/sudoers/def_data.c:79
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Fitxer que conté la llissó de sudo: %s"
+
+#: plugins/sudoers/def_data.c:83
+msgid "Require users to authenticate by default"
+msgstr "Requereix de forma predeterminada que els usuaris s'autentiquin"
+
+#: plugins/sudoers/def_data.c:87
+msgid "Root may run sudo"
+msgstr "L'usuari primari pot executar sudo"
+
+#: plugins/sudoers/def_data.c:91
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Registra el nom del sistema amfitrió al fitxer de registre (que no és syslog)"
+
+#: plugins/sudoers/def_data.c:95
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Registra l'any al fitxer de registre (que no és syslog)"
+
+#: plugins/sudoers/def_data.c:99
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Si sudo s'invoca sense arguments, inicia un intèrpret d'ordres"
+
+#: plugins/sudoers/def_data.c:103
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Estableix $HOME per a l'usuari destí quan s'inicia un d'ordres amb -s"
+
+#: plugins/sudoers/def_data.c:107
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Estableix sempre $HOME al directori de l'usuari destí"
+
+#: plugins/sudoers/def_data.c:111
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Permet recollir alguna informació per donar missatges d'error útils"
+
+#: plugins/sudoers/def_data.c:115
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Requereix noms de sistema amfitrió qualificats completament al sudoers"
+
+#: plugins/sudoers/def_data.c:119
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Insulta a l'usuari quen entri una contrasenya incorrecta"
+
+#: plugins/sudoers/def_data.c:123
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Permet a l'usuari executar sudo únicament si té un terminal"
+
+#: plugins/sudoers/def_data.c:127
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo tindrà en compte la variable d'entorn EDITOR"
+
+#: plugins/sudoers/def_data.c:131
+msgid "Prompt for root's password, not the users's"
+msgstr "Pregunta per la contrasenya de l'usuari primari, no la de l'usuari normal"
+
+#: plugins/sudoers/def_data.c:135
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Pregunta per la contrasenya de l'usuari runas_default, no la de l'usuari normal"
+
+#: plugins/sudoers/def_data.c:139
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Pregunta per la contrasenya de l'usuari destí, no la de l'usuari normal"
+
+#: plugins/sudoers/def_data.c:143
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Aplica els paràmetres predeterminats a la classe d'inici de sessió de l'usuari destí si hi ha una"
+
+#: plugins/sudoers/def_data.c:147
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Estableix les variables d'entorn LOGNAME i USER"
+
+#: plugins/sudoers/def_data.c:151
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Estableix únicament l'uid efectiu de l'usuari destí, no l'uid real"
+
+#: plugins/sudoers/def_data.c:155
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "No inicialitzis el vector de grup perquè coincideixi amb el de l'usuari destí"
+
+#: plugins/sudoers/def_data.c:159
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "longitud a la qual ajustar les línies del fitxer de registres (0 per a no ajustar): %u"
+
+#: plugins/sudoers/def_data.c:163
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Temps màxim d'espera per a la marca horària de l'autenticació: %.1f minuts"
+
+#: plugins/sudoers/def_data.c:167
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Temps màxim d'espera per a la pregunta de la contrasenya: %.1f minuts"
+
+#: plugins/sudoers/def_data.c:171
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Nombre de intents per entrar una contrasenya: %u"
+
+#: plugins/sudoers/def_data.c:175
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Umask a usar o 0777 per usar la de l'usuari: 0%o"
+
+#: plugins/sudoers/def_data.c:179
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Camí al fitxer de registre: %s"
+
+#: plugins/sudoers/def_data.c:183
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Camí al programa de correu electrònic: %s"
+
+#: plugins/sudoers/def_data.c:187
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Indicadors per al programa de correu electrònic: %s"
+
+#: plugins/sudoers/def_data.c:191
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Adreça per enviar correu electrònic: %s"
+
+#: plugins/sudoers/def_data.c:195
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Adreça per enviar correu electrònic des de: %s"
+
+#: plugins/sudoers/def_data.c:199
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Línia d'assumpte per als missatges de correu electrònic: %s"
+
+#: plugins/sudoers/def_data.c:203
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Missatge de contrasenya incorrecta: %s"
+
+#: plugins/sudoers/def_data.c:207
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Camí al directori d'estat de la llissó: %s"
+
+#: plugins/sudoers/def_data.c:211
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Camí del directori de marques horàries d'autenticació: %s"
+
+#: plugins/sudoers/def_data.c:215
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Propietari del directori de marques horàries d'autenticació: %s"
+
+#: plugins/sudoers/def_data.c:219
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Els usuaris d'aquest grup estan exempts dels requeriments contrasenya i PATH: %s"
+
+#: plugins/sudoers/def_data.c:223
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Pregunta predeterminada de contrasenya: %s"
+
+#: plugins/sudoers/def_data.c:227
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Si està establert, la pregunta de contrasenya primarà sobre la pregunta del sistema en tots els casos."
+
+#: plugins/sudoers/def_data.c:231
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Usuari predeterminat per executar ordres com a: %s"
+
+#: plugins/sudoers/def_data.c:235
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Valor per anul·lar el $PATH de l'usuari amb: %s"
+
+#: plugins/sudoers/def_data.c:239
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Camí a l'editor a usar per visudo: %s"
+
+#: plugins/sudoers/def_data.c:243
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Quan requerir una contrasenya per a la pseudo-ordre 'list': %s"
+
+#: plugins/sudoers/def_data.c:247
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Quan requerir una contrasenya per a la pseudo-ordre 'verify': %s"
+
+#: plugins/sudoers/def_data.c:251
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Pre-carrega les funcions dummy exex contingudes a la biblioteca sudo_noexec"
+
+#: plugins/sudoers/def_data.c:255
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Si el directori LDAP està actiu, ignorem el fitxer local sudoers?"
+
+#: plugins/sudoers/def_data.c:259
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Els descriptors de fitxer >= %d es tancaran abans d'executar una ordre"
+
+#: plugins/sudoers/def_data.c:263
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Si està establert, els usuaris podran anul·lar el valor de `closeform' amb l'opció -C"
+
+#: plugins/sudoers/def_data.c:267
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Permet als usuaris fixar variables arbitràries d'entorn"
+
+#: plugins/sudoers/def_data.c:271
+msgid "Reset the environment to a default set of variables"
+msgstr "Restableix l'entorn a un conjunt predeterminat de variables"
+
+#: plugins/sudoers/def_data.c:275
+msgid "Environment variables to check for sanity:"
+msgstr "Les variables d'entorn per comprovar la validesa:"
+
+#: plugins/sudoers/def_data.c:279
+msgid "Environment variables to remove:"
+msgstr "Variables d'entorn a suprimir:"
+
+#: plugins/sudoers/def_data.c:283
+msgid "Environment variables to preserve:"
+msgstr "Variables d'entorn a preservar:"
+
+#: plugins/sudoers/def_data.c:287
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Rol SELinux a usar al nou context de seguretat: %s"
+
+#: plugins/sudoers/def_data.c:291
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Tipus SELinux a usar al nou context de seguretat: %s"
+
+#: plugins/sudoers/def_data.c:295
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Camí al fitxer d'entorn sudo-específic: %s"
+
+#: plugins/sudoers/def_data.c:299
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Configuració local a usar quan s'estan analitzant els sudoers: %s"
+
+#: plugins/sudoers/def_data.c:303
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Permet a sudo preguntar per una contrasenya tot i que pugui ser visible"
+
+#: plugins/sudoers/def_data.c:307
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Proveeix retroalimentació a la pregunta de contrasenya quan hi ha una entrada per l'usuari"
+
+#: plugins/sudoers/def_data.c:311
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Usa una expansió que és menys precisa però no accedeix el sistema de fitxers"
+
+#: plugins/sudoers/def_data.c:315
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "Els permisos umask als sudoers anul·larà els permisos de l'usuari, tot i que siguin més permissius"
+
+#: plugins/sudoers/def_data.c:319
+msgid "Log user's input for the command being run"
+msgstr "Registra l'entrada feta per l'usuari per a l'ordre que s'està executant"
+
+#: plugins/sudoers/def_data.c:323
+msgid "Log the output of the command being run"
+msgstr "Registra la sortida de l'ordre que s'està executant"
+
+#: plugins/sudoers/def_data.c:327
+msgid "Compress I/O logs using zlib"
+msgstr "Comprimeix els registres d'entrada/sortida usant zlib"
+
+#: plugins/sudoers/def_data.c:331
+msgid "Always run commands in a pseudo-tty"
+msgstr "Executa sempre les ordres en un pseudo-terminal"
+
+#: plugins/sudoers/def_data.c:335
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Connector per a suport de grup no Unix: %s"
+
+#: plugins/sudoers/def_data.c:339
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Directori on arxivar els registres entrada/sortida: %s"
+
+#: plugins/sudoers/def_data.c:343
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Fitxer on arxivar el registre entrada/sortida: %s"
+
+#: plugins/sudoers/def_data.c:347
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Afegeix una entrada al fitxer utmp/utmpx quan s'estigui assignant un pty"
+
+#: plugins/sudoers/def_data.c:351
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Estableix l'usuari a utmp perquè sigui l'usuari runas, no l'usuari invocant"
+
+#: plugins/sudoers/def_data.c:355
+msgid "Set of permitted privileges"
+msgstr "Conjunt de privilegis permesos"
+
+#: plugins/sudoers/def_data.c:359
+msgid "Set of limit privileges"
+msgstr "Conjunt de privilegis límit"
+
+#: plugins/sudoers/def_data.c:363
+msgid "Run commands on a pty in the background"
+msgstr "Executa les ordres a un pseudo-terminal (pty) al fons"
+
+#: plugins/sudoers/def_data.c:367
+msgid "PAM service name to use"
+msgstr "Nom del servei PAM a usar"
+
+#: plugins/sudoers/def_data.c:371
+msgid "PAM service name to use for login shells"
+msgstr "Nom del servei PAM a usar per a intèrprets d'ordres d'inici de sessió"
+
+#: plugins/sudoers/def_data.c:375
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Intent d'establir credencials PAM per a l'usuari destí"
+
+#: plugins/sudoers/def_data.c:379
+msgid "Create a new PAM session for the command to run in"
+msgstr "Crea una nova sessió PAM on s'executi l'ordre"
+
+#: plugins/sudoers/def_data.c:383
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Número màxim de seqüència de registre d'entrada/sortida: %u"
+
+#: plugins/sudoers/def_data.c:387
+msgid "Enable sudoers netgroup support"
+msgstr "Habilita el suport de netgroup dels sudoers"
+
+#: plugins/sudoers/def_data.c:391
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Comprova que el directori pare tingui permisos d'escriptura quan s'estiguin editant fitxers amb sudoedit"
+
+#: plugins/sudoers/def_data.c:395
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Segueix els enllaços simbòlics quan s'estiguin editant fitxers amb sudoedit"
+
+#: plugins/sudoers/def_data.c:399
+msgid "Query the group plugin for unknown system groups"
+msgstr "Consulta al connector de grups per grups desconeguts de sistema"
+
+#: plugins/sudoers/def_data.c:403
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Fes concordar els grups de xarxa en base al conjunt sencer: usuari, amfitrió i domini"
+
+#: plugins/sudoers/def_data.c:407
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Permet que s'executin les ordres tot i que sudo no pot escriure al registre d'auditoria"
+
+#: plugins/sudoers/def_data.c:411
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Permet que s'executin les ordres tot i que sudo no pot escriure al registre d'entrada/sortida"
+
+#: plugins/sudoers/def_data.c:415
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Permet que s'executin les ordres tot i que sudo no pot escriure al fitxer de registre"
+
+#: plugins/sudoers/def_data.c:419
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Resol els grups a sudoers i fes concordar amb l'identificador de grup, no el nom"
+
+#: plugins/sudoers/def_data.c:423
+msgid "Log entries larger than this value will be split into multiple syslog messages"
+msgstr "Les entrades de registre més grans que aquest valor es dividiran en múltiples missatges de syslog"
+
+#: plugins/sudoers/def_data.c:427
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "L'usuari que serà el propietari dels fitxers d'entrada/sortida: %s"
+
+#: plugins/sudoers/def_data.c:431
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "El grup que serà el propietari dels fitxers de registre d'entrada/sortida: %s"
+
+#: plugins/sudoers/def_data.c:435
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Mode de fitxer a usar per als fitxers de registre d'entrada/sortida: 0%o"
+
+#: plugins/sudoers/defaults.c:211
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d entrada «%s» desconeguda de paràmetres predeterminats"
+
+#: plugins/sudoers/defaults.c:214
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: entrada «%s» desconeguda de paràmetres predeterminats"
+
+#: plugins/sudoers/defaults.c:237
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d no s'ha especificat un valor per a «%s»"
+
+#: plugins/sudoers/defaults.c:240
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: no s'ha especificat un valor per a «%s»"
+
+#: plugins/sudoers/defaults.c:259
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d els valors per a «%s» han de començar amb un «/»"
+
+#: plugins/sudoers/defaults.c:262
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: els valors per a «%s» han de començar amb un «/»"
+
+#: plugins/sudoers/defaults.c:287
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d l'opció «%s» no pren un valor"
+
+#: plugins/sudoers/defaults.c:290
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: l'opció «%s» no pren un valor"
+
+#: plugins/sudoers/defaults.c:309
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d tipus de paràmetres predeterminats 0x%x per a l'opció «%s»"
+
+#: plugins/sudoers/defaults.c:312
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: tipus 0x%x no vàlid de paràmetres predeterminats per a l'opció «%s»"
+
+#: plugins/sudoers/defaults.c:322
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d el valor «%s» no és vàlid per a l'opció «%s»"
+
+#: plugins/sudoers/defaults.c:325
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: el valor «%s» no és vàlid per a l'opció «%s»"
+
+#: plugins/sudoers/env.c:296 plugins/sudoers/env.c:303
+#: plugins/sudoers/env.c:408 plugins/sudoers/ldap.c:451
+#: plugins/sudoers/ldap.c:541 plugins/sudoers/ldap.c:1253
+#: plugins/sudoers/ldap.c:1475 plugins/sudoers/ldap.c:1801
+#: plugins/sudoers/linux_audit.c:82 plugins/sudoers/logging.c:946
+#: plugins/sudoers/policy.c:523 plugins/sudoers/policy.c:533
+#: plugins/sudoers/prompt.c:161 plugins/sudoers/sudoers.c:841
+#: plugins/sudoers/testsudoers.c:237 plugins/sudoers/toke_util.c:158
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "error intern, desbordament de %s"
+
+#: plugins/sudoers/env.c:377
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: envp corrupte, discordança de longitud"
+
+#: plugins/sudoers/env.c:1082
+msgid "unable to rebuild the environment"
+msgstr "no s'ha pogut reconstruir l'entorn"
+
+#: plugins/sudoers/env.c:1156
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "ho sentim, no teniu permís d'establir les següents variables d'entorn: %s"
+
+#: plugins/sudoers/group_plugin.c:86
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s ha de ser propietat de l'uid %d"
+
+#: plugins/sudoers/group_plugin.c:90
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s ha de ser modificable sols pel seu propietari"
+
+#: plugins/sudoers/group_plugin.c:98 plugins/sudoers/sssd.c:398
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "no s'ha pogut carregar %s: %s"
+
+#: plugins/sudoers/group_plugin.c:104
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "no s'ha pogut trobar el símbol \"group_plugin\" a %s"
+
+#: plugins/sudoers/group_plugin.c:109
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: connector incompatible de group versió principal %d, s'esperava %d"
+
+#: plugins/sudoers/interfaces.c:79 plugins/sudoers/interfaces.c:96
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "no s'ha pogut analitzar l'adreça IP «%s»"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "no s'ha pogut analitzar la màscara de xarxa «%s»"
+
+#: plugins/sudoers/interfaces.c:129
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Adreça local IP i parelles netmask:\n"
+
+#: plugins/sudoers/iolog.c:99 plugins/sudoers/mkdir_parents.c:78
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s existeix però no és un directori (0%o)"
+
+#: plugins/sudoers/iolog.c:126 plugins/sudoers/iolog.c:170
+#: plugins/sudoers/mkdir_parents.c:65 plugins/sudoers/timestamp.c:167
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "no s'ha pogut mkdir %s"
+
+#: plugins/sudoers/iolog.c:269 plugins/sudoers/sudoers.c:1158
+#: plugins/sudoers/testsudoers.c:389
+#, c-format
+msgid "unknown group: %s"
+msgstr "grup desconegut: %s"
+
+#: plugins/sudoers/iolog.c:356 plugins/sudoers/sudoers.c:897
+#: plugins/sudoers/sudoreplay.c:304 plugins/sudoers/sudoreplay.c:817
+#: plugins/sudoers/sudoreplay.c:1021 plugins/sudoers/timestamp.c:383
+#: plugins/sudoers/visudo.c:951 plugins/sudoers/visudo_json.c:1011
+#: plugins/sudoers/visudo_json.c:1024
+#, c-format
+msgid "unable to open %s"
+msgstr "no s'ha pogut obrir %s"
+
+#: plugins/sudoers/iolog.c:399 plugins/sudoers/sudoers.c:901
+#: plugins/sudoers/sudoreplay.c:1132
+#, c-format
+msgid "unable to read %s"
+msgstr "no s'ha pogut llegir %s"
+
+#: plugins/sudoers/iolog.c:435 plugins/sudoers/sudoreplay.c:598
+#: plugins/sudoers/timestamp.c:282 plugins/sudoers/timestamp.c:285
+#, c-format
+msgid "unable to write to %s"
+msgstr "no s'ha pogut escriure a %s"
+
+#: plugins/sudoers/iolog.c:509 plugins/sudoers/iolog.c:727
+#, c-format
+msgid "unable to create %s"
+msgstr "no s'ha pogut crear %s"
+
+#: plugins/sudoers/iolog.c:895 plugins/sudoers/iolog.c:976
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "no s'ha pogut escriure al fitxer de registre d'entrada/sortida: %s"
+
+#: plugins/sudoers/iolog.c:927
+#, c-format
+msgid "%s: internal error, file index %d not open"
+msgstr "%s: error intern, l'índex %d de fitxers no està obert"
+
+#: plugins/sudoers/ldap.c:429
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: el port és massa gran"
+
+#: plugins/sudoers/ldap.c:489
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "tipus d'uri LDAP no suportat: %s"
+
+#: plugins/sudoers/ldap.c:516
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "no s'han pogut barrejar el ldap i els ldaps URIs "
+
+#: plugins/sudoers/ldap.c:520 plugins/sudoers/ldap.c:556
+msgid "starttls not supported when using ldaps"
+msgstr "starttls no suportat quan s'està usant ldaps"
+
+#: plugins/sudoers/ldap.c:627
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "no s'ha pogut inicialitzar el certificat SSL i la clau db: %s"
+
+#: plugins/sudoers/ldap.c:630
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "heu d'establir TLS_CERT a %s per usar SSL"
+
+#: plugins/sudoers/ldap.c:1239
+msgid "unable to get GMT time"
+msgstr "no s'ha pogut obtenir l'hora GMT"
+
+#: plugins/sudoers/ldap.c:1245
+msgid "unable to format timestamp"
+msgstr "no s'ha pogut donar format a la marca horària"
+
+#: plugins/sudoers/ldap.c:1956
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/ldap.c:2504
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"Rol LDAP: %s\n"
+
+#: plugins/sudoers/ldap.c:2506
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"Rol LDAP: DESCONEGUT\n"
+
+#: plugins/sudoers/ldap.c:2562
+#, c-format
+msgid " Order: %s\n"
+msgstr " Ordre: %s\n"
+
+#: plugins/sudoers/ldap.c:2570 plugins/sudoers/parse.c:556
+#: plugins/sudoers/sssd.c:1626
+#, c-format
+msgid " Commands:\n"
+msgstr " Ordres:\n"
+
+#: plugins/sudoers/ldap.c:3130
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "no s'ha pogut inicialitzar LDAP: %s"
+
+#: plugins/sudoers/ldap.c:3166
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "s'ha especificat start_tls però les biblioteques LDAP no donen suport a ldap_start_tls_s() o ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:3415
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "atribut sudoOrder no vàlid: %s"
+
+#: plugins/sudoers/linux_audit.c:52
+msgid "unable to open audit system"
+msgstr "no s'ha pogut obrir el sistema d'auditoria"
+
+#: plugins/sudoers/linux_audit.c:93
+msgid "unable to send audit message"
+msgstr "no s'ha pogut enviar el missatge d'auditoria"
+
+#: plugins/sudoers/logging.c:106
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:134
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (ordre continuada) %s"
+
+#: plugins/sudoers/logging.c:163
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "no s'ha pogut obrir el fitxer de registre: %s"
+
+#: plugins/sudoers/logging.c:171
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "no s'ha pogut bloquejar el fitxer de registre: %s"
+
+#: plugins/sudoers/logging.c:204
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "no s'ha pogut escriure el fitxer de registre: %s"
+
+#: plugins/sudoers/logging.c:233
+msgid "No user or host"
+msgstr "No hi ha usuari o amfitrió"
+
+#: plugins/sudoers/logging.c:235
+msgid "validation failure"
+msgstr "ha fallat la validació"
+
+#: plugins/sudoers/logging.c:242
+msgid "user NOT in sudoers"
+msgstr "l'usuari NO ESTÀ als sudoers"
+
+#: plugins/sudoers/logging.c:244
+msgid "user NOT authorized on host"
+msgstr "l'usuari NO està autoritzat a l'amfitrió"
+
+#: plugins/sudoers/logging.c:246
+msgid "command not allowed"
+msgstr "ordre no permesa"
+
+#: plugins/sudoers/logging.c:281
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s no està al fitxer sudoers. S'informarà d'aquest incident.\n"
+
+#: plugins/sudoers/logging.c:284
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s no té permís per executar sudo a %s. S'informarà d'aquest incident.\n"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Ho sentim, l'usuari %s no pot executar sudo a %s.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Ho sentim, l'usuari %s no pot executar '%s%s%s' com a %s%s%s a %s.\n"
+
+#: plugins/sudoers/logging.c:328 plugins/sudoers/sudoers.c:468
+#: plugins/sudoers/sudoers.c:470 plugins/sudoers/sudoers.c:472
+#: plugins/sudoers/sudoers.c:474 plugins/sudoers/sudoers.c:1247
+#: plugins/sudoers/sudoers.c:1249
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: no s'ha trobar l'ordre"
+
+#: plugins/sudoers/logging.c:330 plugins/sudoers/sudoers.c:464
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"s'ignorarà «%s» trobat a «.»\n"
+"Useu «sudo ./%s» si aquest és el «%s» que voleu executar."
+
+#: plugins/sudoers/logging.c:347
+msgid "authentication failure"
+msgstr "ha fallat l'autenticació"
+
+#: plugins/sudoers/logging.c:373
+msgid "a password is required"
+msgstr "es requereix una contrasenya"
+
+#: plugins/sudoers/logging.c:444 plugins/sudoers/logging.c:510
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u intent incorrecte de contrasenya"
+msgstr[1] "%u intents incorrectes de contrasenya"
+
+#: plugins/sudoers/logging.c:597
+msgid "unable to fork"
+msgstr "no es pot bifurcar"
+
+#: plugins/sudoers/logging.c:605 plugins/sudoers/logging.c:657
+#, c-format
+msgid "unable to fork: %m"
+msgstr "no est pot bifurcar: %m"
+
+#: plugins/sudoers/logging.c:647
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "no es pot obrir la canonada: %m"
+
+#: plugins/sudoers/logging.c:672
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "no es pot duplicar l'entrada estàndard: %m"
+
+#: plugins/sudoers/logging.c:710
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "no es pot executar %s: %m"
+
+#: plugins/sudoers/match.c:644
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "tipus de resum no suportat %d per a %s"
+
+#: plugins/sudoers/match.c:685
+#, c-format
+msgid "%s: read error"
+msgstr "%s: error de lectura"
+
+#: plugins/sudoers/match.c:720
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "digest per a %s (%s) no està en forma %s"
+
+#: plugins/sudoers/mkdir_parents.c:72 plugins/sudoers/sudoers.c:912
+#: plugins/sudoers/visudo.c:439 plugins/sudoers/visudo.c:715
+#, c-format
+msgid "unable to stat %s"
+msgstr "no s'ha pogut accedir %s"
+
+#: plugins/sudoers/parse.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "error d'anàlisi a %s a prop de la línia %d"
+
+#: plugins/sudoers/parse.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "error d'anàlisi a la línia %s"
+
+#: plugins/sudoers/parse.c:503
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Entrada de sudoers:\n"
+
+#: plugins/sudoers/parse.c:504
+#, c-format
+msgid " RunAsUsers: "
+msgstr " RunAsUsers: "
+
+#: plugins/sudoers/parse.c:518
+#, c-format
+msgid " RunAsGroups: "
+msgstr " RunAsGroups: "
+
+#: plugins/sudoers/parse.c:527
+#, c-format
+msgid " Options: "
+msgstr " Opcions: "
+
+#: plugins/sudoers/policy.c:240 plugins/sudoers/testsudoers.c:260
+msgid "unable to parse network address list"
+msgstr "no s'ha pogut analitzar la llista d'adreces de xarxa"
+
+#: plugins/sudoers/policy.c:690 plugins/sudoers/visudo.c:889
+#, c-format
+msgid "unable to execute %s"
+msgstr "no s'ha pogut executar %s"
+
+#: plugins/sudoers/policy.c:823
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Versió del connector de política de sudoers %s\n"
+
+#: plugins/sudoers/policy.c:825
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Versió de gramàtica del fitxer sudoers %d\n"
+
+#: plugins/sudoers/policy.c:829
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Camí del sudoers: %s\n"
+
+#: plugins/sudoers/policy.c:832
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "camí del nsswitch: %s\n"
+
+#: plugins/sudoers/policy.c:834
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "camí de ldap.conf: %s\n"
+
+#: plugins/sudoers/policy.c:835
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "camí del ldap.secret: %s\n"
+
+#: plugins/sudoers/policy.c:868
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "no s'ha pogut registrar el lligam de tipus %d (versió %d.%d)"
+
+#: plugins/sudoers/pwutil.c:162 plugins/sudoers/pwutil.c:180
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "no s'ha pogut posar al cau l'uid %u, s'ha exhaurit la memòria"
+
+#: plugins/sudoers/pwutil.c:174
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "no s'ha pogut posar l'uid %u al cau, ja existeix"
+
+#: plugins/sudoers/pwutil.c:234 plugins/sudoers/pwutil.c:251
+#: plugins/sudoers/pwutil.c:313 plugins/sudoers/pwutil.c:358
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "no s'ha pogut posar l'usuari %s, s'ha exhaurit la memòria"
+
+#: plugins/sudoers/pwutil.c:246
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "no s'ha pogut posar l'usuari %s al cau, ja existeix"
+
+#: plugins/sudoers/pwutil.c:474 plugins/sudoers/pwutil.c:492
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "no s'ha pogut posar el gid %u al cau, s'ha exhaurit la memòria"
+
+#: plugins/sudoers/pwutil.c:486
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "no s'ha pogut posar el gid %u al cau, ja existeix"
+
+#: plugins/sudoers/pwutil.c:540 plugins/sudoers/pwutil.c:557
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:646
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "no s'ha pogut posar el grup %s al cau, s'ha exhaurit"
+
+#: plugins/sudoers/pwutil.c:552
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "no s'ha pogut posar el grup %s al cau, ja existeix"
+
+#: plugins/sudoers/pwutil.c:772 plugins/sudoers/pwutil.c:824
+#: plugins/sudoers/pwutil.c:874 plugins/sudoers/pwutil.c:926
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "no s'ha pogut la llista de grups al cau per a %s, ja existeix"
+
+#: plugins/sudoers/pwutil.c:778 plugins/sudoers/pwutil.c:829
+#: plugins/sudoers/pwutil.c:880 plugins/sudoers/pwutil.c:931
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "no s'ha pogut la llista de grups al cau per a %s, s'ha exhaurit la memòria"
+
+#: plugins/sudoers/pwutil.c:818
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "no s'han pogut analitzar els grups per a %s"
+
+#: plugins/sudoers/pwutil.c:920
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "no s'han pogut analitzar els identificadors de grups per a %s"
+
+#: plugins/sudoers/set_perms.c:113 plugins/sudoers/set_perms.c:438
+#: plugins/sudoers/set_perms.c:841 plugins/sudoers/set_perms.c:1138
+#: plugins/sudoers/set_perms.c:1430
+msgid "perm stack overflow"
+msgstr "desbordament de la pila de permisos"
+
+#: plugins/sudoers/set_perms.c:121 plugins/sudoers/set_perms.c:369
+#: plugins/sudoers/set_perms.c:446 plugins/sudoers/set_perms.c:708
+#: plugins/sudoers/set_perms.c:849 plugins/sudoers/set_perms.c:1067
+#: plugins/sudoers/set_perms.c:1146 plugins/sudoers/set_perms.c:1363
+#: plugins/sudoers/set_perms.c:1438 plugins/sudoers/set_perms.c:1527
+msgid "perm stack underflow"
+msgstr "subdesbordament de la pila de permisos"
+
+#: plugins/sudoers/set_perms.c:180 plugins/sudoers/set_perms.c:492
+#: plugins/sudoers/set_perms.c:1197 plugins/sudoers/set_perms.c:1470
+msgid "unable to change to root gid"
+msgstr "no s'ha pogut canvir el gid de l'usuari primari"
+
+#: plugins/sudoers/set_perms.c:269 plugins/sudoers/set_perms.c:589
+#: plugins/sudoers/set_perms.c:978 plugins/sudoers/set_perms.c:1274
+msgid "unable to change to runas gid"
+msgstr "no s'ha pogut canviar el gid runas"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:594
+#: plugins/sudoers/set_perms.c:983 plugins/sudoers/set_perms.c:1279
+msgid "unable to set runas group vector"
+msgstr "no s'ha pogut configurar el vector de grup runas"
+
+#: plugins/sudoers/set_perms.c:285 plugins/sudoers/set_perms.c:605
+#: plugins/sudoers/set_perms.c:992 plugins/sudoers/set_perms.c:1288
+msgid "unable to change to runas uid"
+msgstr "no s'ha pogut canviar l'uid runas"
+
+#: plugins/sudoers/set_perms.c:303 plugins/sudoers/set_perms.c:623
+#: plugins/sudoers/set_perms.c:1008 plugins/sudoers/set_perms.c:1304
+msgid "unable to change to sudoers gid"
+msgstr "no s'ha pogut canvir el gid del sudoers"
+
+#: plugins/sudoers/set_perms.c:356 plugins/sudoers/set_perms.c:695
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1350
+#: plugins/sudoers/set_perms.c:1514
+msgid "too many processes"
+msgstr "massa processos"
+
+#: plugins/sudoers/solaris_audit.c:51
+msgid "unable to get current working directory"
+msgstr "no s'ha pogut obtenir el directori actual de treball"
+
+#: plugins/sudoers/solaris_audit.c:59
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "camí truncat d'auditoria use_cmd: %s"
+
+#: plugins/sudoers/solaris_audit.c:66
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "camí truncat d'auditoria argv[0]: %s"
+
+#: plugins/sudoers/solaris_audit.c:115
+msgid "audit_failure message too long"
+msgstr "missatge audit_failure massa llarg"
+
+#: plugins/sudoers/sssd.c:400
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "no s'ha pogut inicialitzar la font del SSS. Està el SSSD instal·lat al vostre sistema?"
+
+#: plugins/sudoers/sssd.c:408 plugins/sudoers/sssd.c:417
+#: plugins/sudoers/sssd.c:426 plugins/sudoers/sssd.c:435
+#: plugins/sudoers/sssd.c:444
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "no s'ha pogut trobar el símbol \"%s\" a %s"
+
+#: plugins/sudoers/sssd.c:1541
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: %s\n"
+msgstr ""
+"\n"
+"Rol SSDD: %s\n"
+
+#: plugins/sudoers/sssd.c:1546
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"Rol SSSD: DESCONEGUT\n"
+
+#: plugins/sudoers/sudo_nss.c:290
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Entrades predeterminades concordants per a %s a %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:308
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Runas i valors predeterminats específics d'ordres per a %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:326
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "L'usuari %s pot executar les ordres següents a %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:339
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "L'usuari %s no té permisos per executar sudo a %s.\n"
+
+#: plugins/sudoers/sudoers.c:166 plugins/sudoers/testsudoers.c:246
+#: plugins/sudoers/visudo.c:232 plugins/sudoers/visudo.c:612
+#: plugins/sudoers/visudo.c:955
+msgid "unable to initialize sudoers default values"
+msgstr "no s'han pogut inicialitzar el valors predeterminats dels sudoers"
+
+#: plugins/sudoers/sudoers.c:196 plugins/sudoers/sudoers.c:859
+msgid "problem with defaults entries"
+msgstr "hi ha un problema amb les entrades predeterminades"
+
+#: plugins/sudoers/sudoers.c:203
+msgid "no valid sudoers sources found, quitting"
+msgstr "no s'han trobat fonts vàlides de sudoers, se sortirà"
+
+#: plugins/sudoers/sudoers.c:242
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "el fitxer sudoers especifica que l'usuari primar no pot executar sudo"
+
+#: plugins/sudoers/sudoers.c:299
+msgid "you are not permitted to use the -C option"
+msgstr "no teniu permisos per usar l'opció -C"
+
+#: plugins/sudoers/sudoers.c:387
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "propietari de la marca horària (%s): No existeix aquest usuari"
+
+#: plugins/sudoers/sudoers.c:401
+msgid "no tty"
+msgstr "no hi ha una terminal"
+
+#: plugins/sudoers/sudoers.c:402
+msgid "sorry, you must have a tty to run sudo"
+msgstr "ho sentim, heu de tenir una terminal per executar sudo"
+
+#: plugins/sudoers/sudoers.c:463
+msgid "command in current directory"
+msgstr "ordre al directori actual"
+
+#: plugins/sudoers/sudoers.c:483
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "ho sentim, no teniu permisos per preserver l'entorn"
+
+#: plugins/sudoers/sudoers.c:804
+msgid "command too long"
+msgstr "ordre massa llarga"
+
+#: plugins/sudoers/sudoers.c:916
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s no és un fitxer regular"
+
+#: plugins/sudoers/sudoers.c:920 plugins/sudoers/timestamp.c:209 toke.l:952
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s és propietat de l'uid %u, hauria de ser %u"
+
+#: plugins/sudoers/sudoers.c:924 toke.l:957
+#, c-format
+msgid "%s is world writable"
+msgstr "%s te permís universal d'escriptura"
+
+#: plugins/sudoers/sudoers.c:928 toke.l:960
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s és propietat del gid %u, hauria de ser %u"
+
+#: plugins/sudoers/sudoers.c:961
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "sols l'usuari primari pot usar «-c %s»"
+
+#: plugins/sudoers/sudoers.c:980
+#, c-format
+msgid "unknown login class: %s"
+msgstr "classe desconeguda d'inici de sessió: %s"
+
+#: plugins/sudoers/sudoers.c:1063 plugins/sudoers/sudoers.c:1091
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "no s'ha pogut resoldre l'amfitrió %s"
+
+#: plugins/sudoers/sudoreplay.c:236
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "opció no vàlida de filtre: %s"
+
+#: plugins/sudoers/sudoreplay.c:249
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "espera màxima no vàlida: %s"
+
+#: plugins/sudoers/sudoreplay.c:255
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "factor no vàlid de velocitat: %s"
+
+#: plugins/sudoers/sudoreplay.c:258 plugins/sudoers/visudo.c:185
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s versió %s\n"
+
+#: plugins/sudoers/sudoreplay.c:290
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/sincronització: %s"
+
+#: plugins/sudoers/sudoreplay.c:296
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/sincronització: %s"
+
+#: plugins/sudoers/sudoreplay.c:312
+#, c-format
+msgid "Replaying sudo session: %s\n"
+msgstr "S'està tornant a reproduir la sessió sudo: %s\n"
+
+#: plugins/sudoers/sudoreplay.c:318
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Advertiment: el vostre terminal és massa petit per reproduir apropiadament el registre.\n"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "La geometria del registre és %d x %d, la geometria del vostre terminal és %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:410
+msgid "unable to set tty to raw mode"
+msgstr "no s'ha pogut configurar el terminal a mode de dades en brut"
+
+#: plugins/sudoers/sudoreplay.c:439
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "línia no vàlida de fitxer de sincronització: %s"
+
+#: plugins/sudoers/sudoreplay.c:659 plugins/sudoers/sudoreplay.c:684
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "expressió ambigua \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:706
+msgid "unmatched ')' in expression"
+msgstr "')' sense concordança a l'expressió"
+
+#: plugins/sudoers/sudoreplay.c:710
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "terme desconegut de cerca \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:725
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s requereix un argument"
+
+#: plugins/sudoers/sudoreplay.c:728 plugins/sudoers/sudoreplay.c:1108
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "expressió regular no vàlida: %s"
+
+#: plugins/sudoers/sudoreplay.c:732
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "no s'ha pogut analitzar la data \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:741
+msgid "unmatched '(' in expression"
+msgstr "'(' sense concordança a l'expressió"
+
+#: plugins/sudoers/sudoreplay.c:743
+msgid "illegal trailing \"or\""
+msgstr "\"or\" final il·legal"
+
+#: plugins/sudoers/sudoreplay.c:745
+msgid "illegal trailing \"!\""
+msgstr "\"!\" final il·legal"
+
+#: plugins/sudoers/sudoreplay.c:794
+#, c-format
+msgid "unknown search type %d"
+msgstr "tipus desconegut de cerca %d"
+
+#: plugins/sudoers/sudoreplay.c:832
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: fitxer no vàlid de registre"
+
+#: plugins/sudoers/sudoreplay.c:850
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: no hi ha el camp de marca horària "
+
+#: plugins/sudoers/sudoreplay.c:857
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: marca horària %s: %s"
+
+#: plugins/sudoers/sudoreplay.c:864
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: no hi ha el camp d'usuari runas"
+
+#: plugins/sudoers/sudoreplay.c:873
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: no hi ha el camp del grup runas"
+
+#: plugins/sudoers/sudoreplay.c:882
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: no es troba el camp del grup runas"
+
+#: plugins/sudoers/sudoreplay.c:1245
+#, c-format
+msgid "usage: %s [-h] [-d dir] [-m num] [-s num] ID\n"
+msgstr "ús: %s [-h] [-d dir] [-m num] [-s num] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1248
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "usage: %s [-h] [-d dir] -l [cerca l'expressió]\n"
+
+#: plugins/sudoers/sudoreplay.c:1257
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - reprodueix els registres de la sessió sudo\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1259
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Opcions:\n"
+" -d, --directori=dir especifiqueu el directori per als registres de la sessió\n"
+" -f, --filter=filtre especifiqueu quin(s) tipus d'entrada/sortida mostrar\n"
+" -h, --help mostra el missatge d'ajuda i surt\n"
+" -l, --list mostra una llista dels IDs de les sessions\n"
+" disponibles, amb expressions opcionals\n"
+" -m, --max-wait=num nombre màxim de segons a esperar entre esdeveniments\n"
+" -s, --speed=num accelera o alenteix la sortida\n"
+" -V, --version mostra la versió d'informació i surt"
+
+#: plugins/sudoers/testsudoers.c:328
+msgid "\thost unmatched"
+msgstr "\tamfitrió sense concordança"
+
+#: plugins/sudoers/testsudoers.c:331
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Ordre permesa"
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Ordre denegada"
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Ordre sense concordança"
+
+#: plugins/sudoers/timestamp.c:217
+#, c-format
+msgid "%s is group writable"
+msgstr "%s és modificable pel grup"
+
+#: plugins/sudoers/timestamp.c:293
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "no s'ha pogut truncar el fitxer de marca horària a %lld bytes"
+
+#: plugins/sudoers/timestamp.c:738 plugins/sudoers/timestamp.c:805
+#: plugins/sudoers/visudo.c:500 plugins/sudoers/visudo.c:506
+msgid "unable to read the clock"
+msgstr "no s'ha pogut llegir el rellotge"
+
+#: plugins/sudoers/timestamp.c:752
+msgid "ignoring time stamp from the future"
+msgstr "s'ignorarà la marca horària del futur"
+
+#: plugins/sudoers/timestamp.c:764
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "la marca horària està massa lluny en el futur: %20.20s"
+
+#: plugins/sudoers/timestamp.c:859
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "no s'ha pogut bloquejar el fitxer de marca horària %s"
+
+#: plugins/sudoers/timestamp.c:903 plugins/sudoers/timestamp.c:923
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "el camí de l'estat de la llissó és massa llarg: %s/%s"
+
+#: plugins/sudoers/visudo.c:187
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s versió de la gramàtica %d\n"
+
+#: plugins/sudoers/visudo.c:265 plugins/sudoers/visudo.c:665
+#, c-format
+msgid "press return to edit %s: "
+msgstr "prem la tecla d'introducció per editar %s: "
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "l'editor especificat (%s) no existeix"
+
+#: plugins/sudoers/visudo.c:349
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "no s'ha trobat un editor (el camí de l'editor = %s)"
+
+#: plugins/sudoers/visudo.c:459 plugins/sudoers/visudo.c:467
+msgid "write error"
+msgstr "error d'escriptura"
+
+#: plugins/sudoers/visudo.c:513
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "no s'ha pogut accedir al fitxer temporal (%s), no s'ha modificat %s"
+
+#: plugins/sudoers/visudo.c:520
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "fitxer temporal amb longitud nul·la (%s), no s'ha modificat %s"
+
+#: plugins/sudoers/visudo.c:526
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "l'editor (%s) ha fallat, no s'ha modificat %s"
+
+#: plugins/sudoers/visudo.c:548
+#, c-format
+msgid "%s unchanged"
+msgstr "no s'ha modificat %s"
+
+#: plugins/sudoers/visudo.c:607
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "no s'ha pogut reobrir el fitxer temporal (%s), no s'ha modificat %s"
+
+#: plugins/sudoers/visudo.c:619
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "no s'ha pogut analitzar el fitxer temporal (%s), error desconegut"
+
+#: plugins/sudoers/visudo.c:656
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "error intern, no s'ha pogut trobar %s a la llista!"
+
+#: plugins/sudoers/visudo.c:717 plugins/sudoers/visudo.c:726
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "no s'ha pogut establir (uid, gid) de %s a (%u, %u)"
+
+#: plugins/sudoers/visudo.c:721 plugins/sudoers/visudo.c:731
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "no s'ha pogut canviar el mode de %s a 0%o"
+
+#: plugins/sudoers/visudo.c:748
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s i %s no estan al mateix sistema de fitxers, s'usarà mv per reanomenar"
+
+#: plugins/sudoers/visudo.c:762
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "l'ordre ha fallat: '%s %s %s', no s'ha modificat %s"
+
+#: plugins/sudoers/visudo.c:772
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "error quan s'estava reanomenant %s, no s'ha modificat %s"
+
+#: plugins/sudoers/visudo.c:834
+msgid "What now? "
+msgstr "Què fem ara? "
+
+#: plugins/sudoers/visudo.c:848
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Les opcions són:\n"
+" (e)dita el fitxer sudoers un altre cop\n"
+" (x) surt sense desar els canvis al fitxer sudoers\n"
+" (Q) surt i desa el canvis el fitxer sudoers (PERILL!)\n"
+
+#: plugins/sudoers/visudo.c:894
+#, c-format
+msgid "unable to run %s"
+msgstr "no s'ha pogut executar %s"
+
+#: plugins/sudoers/visudo.c:924
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: propietari incorrecte (uid, gid) hauria de ser (%uk, %u)\n"
+
+#: plugins/sudoers/visudo.c:931
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: permisos dolents, hauria de ser mode 0%o\n"
+
+#: plugins/sudoers/visudo.c:960 plugins/sudoers/visudo_json.c:1031
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "no s'ha pogut analitzar el fitxer %s, error desconegut"
+
+#: plugins/sudoers/visudo.c:976 plugins/sudoers/visudo_json.c:1042
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "error d'anàlisi a %s a prop de la línia %d\n"
+
+#: plugins/sudoers/visudo.c:979 plugins/sudoers/visudo_json.c:1045
+#, c-format
+msgid "parse error in %s\n"
+msgstr "error d'anàlisi a %s\n"
+
+#: plugins/sudoers/visudo.c:987 plugins/sudoers/visudo.c:994
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: s'analitzat correctament\n"
+
+#: plugins/sudoers/visudo.c:1041
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s està ocupat, proveu un altre cop més tard"
+
+#: plugins/sudoers/visudo.c:1137
+#, c-format
+msgid "%s:%d cycle in %s \"%s\""
+msgstr "%s:%d cicle a %s «%s»"
+
+#: plugins/sudoers/visudo.c:1140
+#, c-format
+msgid "%s:%d %s \"%s\" referenced but not defined"
+msgstr "%s:%d %s «%s» s'ha referenciat però no s'ha definit "
+
+#: plugins/sudoers/visudo.c:1292
+#, c-format
+msgid "%s:%d unused %s \"%s\""
+msgstr "%s:%d sense usar %s «%s»"
+
+#: plugins/sudoers/visudo.c:1403
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - edita amb seguretat el fitxer sudoers\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1405
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+" -x, --export=output_file write sudoers in JSON format to output_file"
+msgstr ""
+"\n"
+"Opcions:\n"
+" -c, --check mode de sols verificació\n"
+" -f, --file=sudoers especifiqueu la ubicació del fitxer sudoers\n"
+" -h, --help mostra el missatge d'ajuda i surt\n"
+" -q, --quiet missatges d'error de sintaxi menys informatius (silenciós)\n"
+" -s, --strict verificació estricta de la sintaxi\n"
+" -V, --version mostra la informació de la versió i surt\n"
+" -x, --export=output_file escriu el fitxer sudoers en format JSON a output_file"
+
+#: plugins/sudoers/visudo_json.c:632 plugins/sudoers/visudo_json.c:667
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "entrada «%s» desconeguda de paràmetres predeterminats"
+
+#: plugins/sudoers/visudo_json.c:1017
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: els fitxers d'entrada i de sortida han de ser diferents"
+
+#: toke.l:926
+msgid "too many levels of includes"
+msgstr "massa nivells d'inclusions"
+
+#~ msgid "Warning: cycle in %s `%s'"
+#~ msgstr "Advertiment: cicle a %s `%s'"
+
+#~ msgid "Warning: %s `%s' referenced but not defined"
+#~ msgstr "Advertiment: s'ha referenciat però no s'ha definit %s `%s'"
+
+#~ msgid "Warning: unused %s `%s'"
+#~ msgstr "Advertiment: %s `%s' sense usar"
+
+#~ msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+#~ msgstr "sudo_ldap_conf_add_ports: s'ha exhaurit l'espai quan s'estava expandint hostbuf"
+
+#~ msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+#~ msgstr "sudo_ldap_parse_uri: s'ha exhaurit l'espai construint hostbuf"
+
+#~ msgid "sudo_ldap_build_pass1 allocation mismatch"
+#~ msgstr "discordança d'assignació de sudo_ldap_build_pass1"
+
+#~ msgid "timestamp path too long: %s/%s"
+#~ msgstr "el camí de la marca horària és massa llarg: %s/%s"
+
+#~ msgid "unable to stat editor (%s)"
+#~ msgstr "no s'ha pogut accedir l'editor (%s)"
+
+#~ msgid "internal error: insufficient space for log line"
+#~ msgstr "error intern: espai insuficient per a la línia de registre"
+
+#~ msgid "fill_args: buffer overflow"
+#~ msgstr "fill_args: desbordament de la memòria intermèdia"
diff --git a/plugins/sudoers/po/cs.mo b/plugins/sudoers/po/cs.mo
new file mode 100644
index 0000000..7b96570
--- /dev/null
+++ b/plugins/sudoers/po/cs.mo
Binary files differ
diff --git a/plugins/sudoers/po/cs.po b/plugins/sudoers/po/cs.po
new file mode 100644
index 0000000..300776d
--- /dev/null
+++ b/plugins/sudoers/po/cs.po
@@ -0,0 +1,2412 @@
+# Czech translation for sudo.
+# This file is distributed under the same license as the sudo package.
+# Todd C. Miller <Todd.Miller@courtesan.com>, 2011-2013
+# Petr Pisar <petr.pisar@atlas.cz>, 2013, 2014, 2015, 2016, 2017, 2018.
+#
+# (AIX) registry → (AIXový) registr
+# timestamp → časové údaje
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-31 19:22+01:00\n"
+"Last-Translator: Petr Pisar <petr.pisar@atlas.cz>\n"
+"Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"
+"Language: cs\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "chyba syntaxe"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "Heslo pro %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] heslo pro %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Heslo: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** BEZPEČNOSTNÍ hlášení o %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Je nám líto, zkuste to znovu."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336
+#: gram.y:399 gram.y:407 gram.y:417 gram.y:450 gram.y:457 gram.y:464
+#: gram.y:471 gram.y:553 gram.y:560 gram.y:569 gram.y:578 gram.y:595
+#: gram.y:707 gram.y:714 gram.y:721 gram.y:729 gram.y:829 gram.y:836
+#: gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890 gram.y:897
+#: gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:195 plugins/sudoers/logging.c:511
+#: plugins/sudoers/logging.c:532 plugins/sudoers/logging.c:573
+#: plugins/sudoers/logging.c:752 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr "nelze alokovat paměť"
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr "kontrolní součet vyžaduje název cesty"
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr "neplatná hodnota notbefore (začátek platnosti)"
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr "neplatná hodnota notafter (konec platnosti)"
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr "hodnota časového limitu je příliš velká"
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr "neplatná hodnota časového limitu"
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:354 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:511 plugins/sudoers/logging.c:532
+#: plugins/sudoers/logging.c:572 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:724 plugins/sudoers/match.c:771
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1008
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Alias „%s“ je již definován"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "nelze získat přihlašovací třídu uživatele %s"
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr "nelze zahájit BSD autentizaci"
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr "neplatný druh autentizace"
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr "nelze inicializovat BSD autentizaci"
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr "vašemu účtu skončila platnost"
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr "schválení selhalo"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr "nelze načíst konfiguraci FWTK"
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr "k autentizačnímu serveru se nelze připojit"
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr "spojení k autentizačnímu serveru ztraceno"
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"chyba autentizačního serveru:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: principála nelze převést na řetězec („%s“): %s"
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: „%s“ nelze rozebrat: %s"
+
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: nelze najít keš s pověřeními: %s"
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: nelze alokovat volby: %s"
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: nelze získat pověření: %s"
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: nelze inicializovat keš s pověřeními: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: pověření nelze uložit do keše: %s"
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: nelze získat principála stroje: %s"
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: TGT nelze ověřit! Podezření na útok!: %s"
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr "PAM nelze inicializovat"
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Chyba autentizace PAM: %s"
+
+#: plugins/sudoers/auth/pam.c:221
+msgid "account validation failure, is your account locked?"
+msgstr "ověření účtu selhalo, není váš účet zamknutý?"
+
+#: plugins/sudoers/auth/pam.c:229
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Účtu nebo heslu vypršela platnost, nastavte si nové heslo a zkuste to znovu"
+
+#: plugins/sudoers/auth/pam.c:238
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "prošlé heslo nelze změnit: %s"
+
+#: plugins/sudoers/auth/pam.c:246
+msgid "Password expired, contact your system administrator"
+msgstr "Heslu vypršela platnost, kontaktujte správce svého systému"
+
+#: plugins/sudoers/auth/pam.c:250
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Účtu vypršela platnost nebo v konfiguraci PAM pro sudo chybí sekce „account“. Kontaktujte správce svého systému"
+
+#: plugins/sudoers/auth/pam.c:257 plugins/sudoers/auth/pam.c:262
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "Chyba správy účtů PAM: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:232
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "v databázi %s neexistujete"
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr "inicializace knihovny ACE selhala"
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr "nelze kontaktovat server SecurID"
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr "ID uživatele je pro autentizaci SecurID uzamčeno"
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr "neplatná délka uživatelského jména pro SecurID"
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr "neplatný deskriptor autentizace pro SecurID"
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr "komunikace se SecurID selhala"
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr "neznámá chyba SecurID"
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr "neplatná délka kódu pro SecurID"
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr "nelze inicializovat relaci SIA"
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr "neplatné autentizační metody"
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Sudo bylo sestaveno s neplatnými autentizačními metodami! Nesmíte míchat samostatnou a nesamostatnou autentizaci."
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr "žádné autentizační metody"
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Sudo bylo sestaveno bez autentizačních metod! Chcete-li vypnout autentizaci, použijte při sestavování přepínač --disable-autentizaci."
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr "Nelze inicializovat metody autentizace."
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr "Autentizační metody:"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr "Nebylo možné určit podmínku pro audit"
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr "auditní zprávu nelze odeslat"
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Věříme, že jste od správce místního systému obdrželi obvyklé školení.\n"
+"Obvykle se jedná o tyto tři věci:\n"
+"\n"
+" 1. Respektujte soukromí druhých.\n"
+" 2. Přemýšlejte, než začnete psát.\n"
+" 3. S velkými právy přichází velká zodpovědnost.\n"
+"\n"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr "neznámé UID: %u"
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1136
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr "neznámý uživatel: %s"
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "přírůstek pořadí: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "počáteční pořadí: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr "odsazení pořadí: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s verze %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "verze gramatiky %s je %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr "nepodporovaný formát vstupu %s"
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr "nepodporovaný formát výstupu %s"
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: vstupní a výstupní soubory se musí lišit"
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:238
+#: plugins/sudoers/visudo.c:594 plugins/sudoers/visudo.c:917
+msgid "unable to initialize sudoers default values"
+msgstr "nelze inicializovat výchozí hodnoty sudoers"
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: neznámé klíčové slovo: %s"
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "neplatný druh položky defaults: %s"
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "neplatný druh potlačení: %s"
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr "neplatný filtr: %s"
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:913
+#, c-format
+msgid "unable to open %s"
+msgstr "nelze otevřít %s"
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:922
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "rozbor souboru %s se nezdařil, neznámá chyba"
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:939
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "chyba při rozboru %s kolem řádku %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:942
+#, c-format
+msgid "parse error in %s\n"
+msgstr "chyba při rozboru %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr "do %s nelze zapsat"
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s – převádí mezí formáty souboru sudoers\n"
+"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Přepínače:\n"
+" -b, --base=dn base DN pro ldapové dotazy suda\n"
+" -d, --defaults=druhydef převede pouze Defaults zadaných druhů\n"
+" -e, --expand-aliases při převodu expanduje aliasy\n"
+" -f, --output-format=formát nastaví formát výstupu: JSON, LDIF nebo sudoers\n"
+" -i, --input-format=formát nastaví formát vstupu: LDIF nebo sudoers\n"
+" -I, --increment=číslo množství, o které zvýšit každou definici sudoOrder\n"
+" -h, --help zobrazí zprávu s nápovědou a skončí\n"
+" -m, --match=filtr převede pouze položky, které odpovídají filtru\n"
+" -M, --match-local porovnávací filtr použije databáze passwd a group\n"
+" -o, --output=výstupní_soubor\n"
+" zapíše převedený sudoers to výstupního_souboru\n"
+" -O, --order-start=číslo počáteční bod pro první sudoOrder\n"
+" -p, --prune-matches odstraní neodpovídající uživatele, skupiny a stroje\n"
+" -P, --padding=číslo základní odsazení přírůstku sudoOrder\n"
+" -s, --suppress=oddíl potlačí výstup jistých oddílů\n"
+" -V, --version zobrazí údaje o verzi a skončí"
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "neznámá položka defaults „%s“"
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr "nelze získat čas GMT"
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr "nelze naformátovat časový údaj"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1015 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "vnitřní chyba, přetečení %s"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr "příliš mnoho záznamů sudoers, maximum je %u"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "proměnná prostředí SUDOERS_BASE není nastavená a přepínač -b nebyl zadán."
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Obor systémového protokolu, je-li syslog použit pro protokolování: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Priorita systémového protokolu, která se použije při úspěšné autentizaci uživatele: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Priorita systémového protokolu, která se použije při neúspěšné autentizaci: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "Dotaz na jednorázový kód bude na vlastním řádku"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "Ignoruje „.“ v PATH"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "Vždy, když se použije sudo, odešle e-mail"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "Odešle e-mail, když autentizace uživatele selže"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "Odešle e-mail, pokud uživatel není v sudoers"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Odešle e-mail, když uživatel není v sudoers uveden pro tento stroj"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Odešle e-mail, když uživatel nemá dovoleno spustit příkaz"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "Odešle e-mail, když uživatel zkusí spustit příkaz"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Pro každou kombinaci uživatele a TTY použije samostatný časovač"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "Před prvním použitím sudo proškolí uživatele"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Soubor obsahující školení k sudo: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "Standardně vyžaduje, aby se uživatelé autentizovali"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "Root může spustit sudo"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Do (nesyslogového) protokolu zaznamenává název stroje"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Do (nesyslogového) protokolu zaznamenává rok"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Je-li sudo zavoláno bez argumentů, spustí shell"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Nastaví HOME na cílového uživatele, když se pouští shell s -s"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Vždy nastaví HOME na domovský adresář cílového uživatele"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Dovolí sběr některých údajů za účelem užitečných chybových zpráv"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Vyžaduje v souboru sudoers plně kvalifikované názvy strojů"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Urazí uživatele, pokud zadá chybné heslo"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Dovolí uživateli spustit sudo, pouze když má TTY"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo bude dodržovat proměnou prostředí EDITOR"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "Ptá se heslo roota, ne na heslo uživatele"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Ptá se na heslo runas_default uživatele, ne na heslo uživatele"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Ptá se na heslo cílového uživatele, ne na heslo uživatele"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Použije výchozí nastavení v přihlašovací třídě cílového uživatele, existuje-li"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Nastaví proměnné prostředí LOGNAME a USER"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Nastaví pouze efektivní UID na cílového uživatele, nikoliv reálné UID"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Neinicializuje vektor skupin na vektor cílového uživatele"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Délka zlomu řádků v protokolu (0 pro nezalamování): %u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Limit na časové údaje autentizace: %.1f min"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Limit na výzvu k heslu: %.1f min"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Počet pokusů na zadání hesla: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Umask nebo 0777 pro hodnotu uživatele: 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Cesta k souboru s protokolem: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Cesta k poštovnímu programu: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Přepínače pro poštovní program: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Adresa, kam zasílat poštu: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Adrese, ze které zasílat poštu: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Řádek s předmětem pro poštovní zprávy: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Zpráva při chybném hesle: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Cesta k adresáři se stavy lekcí: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Cesta k adresáři s časovými údaji autentizace: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Vlastník adresáře s časovými údaji autentizace: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Uživatelé v této skupině jsou vyjmuti z požadavků na heslo na PATH: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Výchozí výzva pro heslo: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Je-li nastaveno, passprompt přebije systémovou výzvu ve všech případech."
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Výchozí uživatel, pro kterým spouštět příkazy: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Hodnota, kterou přebít PATH uživatele: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Cesta k editoru pro potřeby visudo: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Kdy vyžadovat heslo pro pseudopříkaz „list“: %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Kdy vyžadovat heslo pro pseudopříkaz „verify“: %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Přednačíst prázdné spouštěcí funkce obsažené v knihovně sudo_noexec"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Pokud je adresář LDAP dostupný, ignorovat místní soubor sudoers"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Souborové deskriptory >= %d budou před spuštěním příkazu uzavřeny"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Je-li nastaveno, uživatelé mohou přebít hodnotu „closefrom“ přepínačem -C"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Dovolit uživatelům nastavit libovolné proměnné prostředí"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "Vrátit prostředí do výchozí množiny proměnných"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "Proměnné prostředí kontrolované na logičnost:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "Proměnné prostředí, které se mají odstranit:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "Proměnné prostředí, které se mají zachovat:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Selinuxový role, která se použije v novém bezpečnostním kontextu: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Selinuxový typ, který se použije v novém bezpečnostním kontextu: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Cesta k souboru s prostředím určeném pro sudo: %s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Cesta k souboru s omezeným prostředím určeném pro sudo: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Národní prostředí, které se použije pro rozbor sudoers: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Dovolit sudu ptát se na heslo, i kdyby bylo čitelné"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Indikovat vstup uživatele při dotazu na heslo"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Použit rychlejší expanzi globů, která je méně přesná, ale nepřistupuje k souborovému systému"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "Umask zadaná v sudoers přebije uživatelovu, i když je volnější"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "Zaznamenávat vstup uživatele pro spouštěný příkaz"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "Zaznamenávat výstup spouštěného příkazu"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "Komprimovat protokoly o vstupu/výstupu pomocí zlib"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "Vždy spouštět příkazy v pseudoTTY"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Modul pro podporu neunixových skupin: %s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Adresář, kam ukládat protokoly o vstupu/výstupu: %s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Soubor, do kterého ukládat protokol o vstupu/výstupu: %s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Při alokaci PTY přidat záznam do souboru utmp/utmpx"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Do utmp zapisovat runas uživatele, nikoliv uživatele volajícího"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Množina povolujících práv: %s"
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Množina omezujících práv: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "Spouštět příkazy v PTY na pozadí"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "Použít tuto službu PAM: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "Název služby PAM, který se použije pro přihlašovací shelly: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Pokusit se získat pověření PAM pro cílového uživatele"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "Vytvořit pro spouštěný příkaz novou relaci PAM"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Maximální pořadové číslo protokolu o vstupu/výstupu: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "Zapnout v sudoers podporu netgroup"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Kontrolovat nadřazené adresáře na možnost zápisu při úpravě souborů pomocí sudoedit"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Následovat symbolické odkazy při úpravě souborů pomocí sudoedit"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "Dotazovat se modulu pro skupiny na neznámé systémové skupiny"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Porovnávat netgroups na celou n-tici: uživatel, stroj a doména"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Dovolit spuštění příkazu, i když sudo nemůže zapsat do auditního protokolu"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Dovolit spuštění příkazu, i když sudo nemůže zapsat do I/O protokolu"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Dovolit spuštění příkazu, i když sudo nemůže zapsat do souboru s protokolem"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Překládat skupiny v sudoers a hledat shodu na ID skupiny, ne na jméně"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Položky protokolu větší než tato hodnota budou rozděleny do více zpráv syslogu: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Uživatel, který bude vlastnit soubory s I/O protokolem: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Skupina, která bude vlastnit soubory s I/O protokolem: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Přístupová práva k souboru s I/O protokolem: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Spustit příkazy podle deskriptoru souboru namísto podle cesty: %s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Ignorovat neznámé položky Defaults v sudoers namísto vypisování varování"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Čas v sekundách, po kterém bude příkaz ukončen: %u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Povolit uživateli zadat časový limit na příkazovém řádku"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Zapisovat log na disk ihned namísto po větších částech"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "Při protokolování přes syslog zahrnout ID procesu"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Druh záznamu s časovým údajem autentizace: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "Zpráva o selhání autentizace: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "Ignorovat velikost znaků při porovnávání jmen uživatelů"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "Ignorovat velikost znaků při porovnávání názvů skupin"
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d neznámá položka defaults „%s“"
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: neznámá položka defaults „%s“"
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d u „%s“ nebyla zadána žádná hodnota"
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: u „%s“ nebyla zadána žádná hodnota"
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d hodnoty u „%s“ musí začínat na „/“"
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: hodnoty u „%s“ musí začínat na „/“"
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d volba „%s“ nebere hodnotu"
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: volba „%s“ nebere hodnotu"
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d neplatný typ Defaults 0x%x u volby „%s“"
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: neplatný typ Defaults 0x%x u volby „%s“"
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d hodnota „%s“ je pro volbu „%s“ neplatná"
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: hodnota „%s“ je pro volbu „%s“ neplatná"
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: poškozené pole envp, délka nesouhlasí"
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr "prostředí nelze znovu sestavit"
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "je nám líto, ale nemáte dovoleno nastavovat následující proměnné prostředí: %s"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "chyba rozboru v %s kolem řádku %d"
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "chyba rozboru v %s"
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "nepodporovaný druh kontrolního součtu %d pro %s"
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr "%s: chyba při čtení"
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s musí být vlastněn UID %d"
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s smí být zapisovatelný jen pro vlastníka"
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "nelze zavést %s: %s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "v %s nelze nalézt symbol „group_plugin“"
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: nekompatibilní hlavní verze modulu pro skupiny %d, očekávána %d"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "nelze rozebrat IP adresu „%s“"
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "nelze rozebrat síťovou masku „%s“"
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Pár místní IP adresy a masky sítě:\n"
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s existuje, ale nejedná se o adresář (0%o)"
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "nelze vytvořit adresář %s"
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:723
+#: plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "nelze změnit práva %s na 0%o"
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1167
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr "neznámá skupina: %s"
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr "%s nelze číst"
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr "%s nelze vytvořit"
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "nelze zapsat do souboru s I/O protokolem: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr "%s: vnitřní chyba, soubor s I/O protokolem pro událost %d není otevřen"
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr "%s: vnitřní chyba, neplatný signál %d"
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: neplatný soubor s protokolem"
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: chybí položka s časovým údajem"
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: čas %s: %s"
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: chybí položka s uživatelem"
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: chybí položka s runas uživatelem"
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s chybí položka s runas skupinou"
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr "při použití ldaps není starttls podporováno"
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "nelze inicializovat certifikát SSL a databázi klíčů: %s"
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "pro SSL musíte v %s nastavit TLS_CERT"
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "LDAP nelze inicializovat: %s"
+
+#: plugins/sudoers/ldap.c:1648
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls uvedeno, ale knihovna LDAP nepodporuje ldap_start_tls_s_np() ani ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "neplatný atribut sudoOrder: %s"
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: port je příliš velký"
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "nepodporovaný typ ldapového URI: %s"
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "nelze míchat URI ldap a ldaps"
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "nelze převést sudoOption: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "nelze otevřít auditní systém"
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr "nelze odeslat auditní zprávu"
+
+#: plugins/sudoers/logging.c:113
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:141
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (příkaz pokračuje) %s"
+
+#: plugins/sudoers/logging.c:170
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "nelze otevřít soubor protokolu: %s"
+
+#: plugins/sudoers/logging.c:178
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "nelze zamknout soubor protokolu: %s"
+
+#: plugins/sudoers/logging.c:211
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "nelze zapsat soubor protokolu: %s"
+
+#: plugins/sudoers/logging.c:240
+msgid "No user or host"
+msgstr "Žádný uživatel nebo stroj"
+
+#: plugins/sudoers/logging.c:242
+msgid "validation failure"
+msgstr "selhání ověření"
+
+#: plugins/sudoers/logging.c:249
+msgid "user NOT in sudoers"
+msgstr "uživatel NENÍ v sudoers"
+
+#: plugins/sudoers/logging.c:251
+msgid "user NOT authorized on host"
+msgstr "uživatel NENÍ na stroji autorizován"
+
+#: plugins/sudoers/logging.c:253
+msgid "command not allowed"
+msgstr "příkaz nedovolen"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s není v souboru sudoers. Tento událost bude ohlášena.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s nemá dovoleno spouštět sudo na %s. Tato událost bude ohlášena.\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Je nám líto, uživatel %s nesmí spouštět sudo na %s.\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Je nám líto, uživatel %s nemá dovoleno spouštět „%s%s%s“ jako %s%s%s na %s.\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: příkaz nenalezen"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"ignoruje se „%s“ nalezený v „.“\n"
+"Použijte „sudo ./%s„, je-li toto „%s“', který chcete spustit."
+
+#: plugins/sudoers/logging.c:354
+msgid "authentication failure"
+msgstr "selhání autentizace"
+
+#: plugins/sudoers/logging.c:380
+msgid "a password is required"
+msgstr "je vyžadováno heslo"
+
+#: plugins/sudoers/logging.c:443
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u chybný pokus zadat heslo"
+msgstr[1] "%u chybné pokusy zadat heslo"
+msgstr[2] "%u chybných pokusů zadat heslo"
+
+#: plugins/sudoers/logging.c:666
+msgid "unable to fork"
+msgstr "nelze vytvořit proces"
+
+#: plugins/sudoers/logging.c:674 plugins/sudoers/logging.c:726
+#, c-format
+msgid "unable to fork: %m"
+msgstr "nelze vytvořit proces: %m"
+
+#: plugins/sudoers/logging.c:716
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "nelze otevřít rouru: %m"
+
+#: plugins/sudoers/logging.c:741
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "nelze zdvojit standardní vstup: %m"
+
+#: plugins/sudoers/logging.c:779
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "nelze spustit %s: %m"
+
+#: plugins/sudoers/match.c:874
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "součet pro %s (%s) nemá tvar %s"
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:421 plugins/sudoers/visudo.c:717
+#, c-format
+msgid "unable to stat %s"
+msgstr "nelze zjistit údaje o %s"
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"Role LDAP: %s\n"
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Položka v sudoers:\n"
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr " RunAsUsers: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr " RunAsGroups: "
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr " Volby: "
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr " Příkazy:\n"
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Odpovídající položky Defaults pro %s na %s:\n"
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Výchozí hodnoty Runas a Command pro %s:\n"
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Uživatel %s smí spustit následující příkazy na %s:\n"
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Uživatel %s nemá dovoleno spustit sudo na %s.\n"
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "neplatná hodnota hodnota atributu se ignoruje: %s"
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "neúplná definice sudoRole se ignoruje: cn: %s"
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "neplatné %.*s nenastaveno vnějším rozhraním sudo"
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr "nelze rozebrat seznam síťových adres"
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr "uživatelské jméno nenastaveno vnějším rozhraním sudo"
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr "ID uživatele nenastaveno vnějším rozhraním sudo"
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr "ID skupiny nenastaveno vnějším rozhraním sudo"
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr "název počítače nenastaven vnějším rozhraním sudo"
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:220
+#: plugins/sudoers/visudo.c:851
+#, c-format
+msgid "unable to execute %s"
+msgstr "nelze vykonat %s"
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Verze modulu s politikami sudoers je %s\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Verze gramatiky souboru sudoers je %d\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Cesta sudoers: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "cesta k nsswitch: %s\n"
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "cesta k ldap.conf: %s\n"
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "cesta k ldap.secret: %s\n"
+
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "nelze zaregistrovat háček typu %d (verze %d.%d)"
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "nelze zapamatovat si UID %u, nedostatek paměti"
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "nelze zapamatovat si UID %u, již existuje"
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "nelze zapamatovat si uživatele %s, nedostatek paměti"
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "nelze zapamatovat si uživatele %s, již existuje"
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "nelze zapamatovat si GID %u, nedostatek paměti"
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "nelze zapamatovat si GID %u, již existuje"
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "nelze zapamatovat si skupinu %s, nedostatek paměti"
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "nelze zapamatovat si skupinu %s, již existuje"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "nelze zapamatovat si seznam skupin pro %s, již existuje"
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "nelze zapamatovat si seznam skupin pro %s, nedostatek paměti"
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "nelze rozebrat skupiny pro %s"
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "nelze rozebrat čísla GID pro %s"
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr "přetečení zásobníku oprávnění"
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr "podtečení zásobníku oprávnění"
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr "nelze přepnout GID na root"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr "nelze přepnout na běhové GID"
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr "nelze nastavit vektor běhových skupin"
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr "nelze přepnout na běhové UID"
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr "nelze přepnout na GID sudoers"
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr "příliš mnoho procesů"
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr "současný pracovní adresář nelze zjistit"
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "zkrácená auditní cesta user_cmnd: %s"
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "zkrácená auditní cesta argv[0]: %s"
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr "zpráva audit_failure je příliš dlouhá"
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "nelze inicializovat zdroj SSS. Je SSSD nainstalován na vašem stroji?"
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "nelze nalézt symbol „%s“ v %s"
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr "problém s položkami defaults"
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr "nenalezeny žádné platné zdroje sudoers, končí se"
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers udává, že root nemá dovoleno použít sudo"
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr "nemáte dovoleno použít přepínač -C"
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "vlastník časového údaje (%s): Takový uživatel neexistuje"
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr "žádné TTY"
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr "je nám líto, ale pro spuštění sudo musíte mít TTY"
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr "příkaz v aktuálním adresáři"
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "je nám líto, ale nastavit časový limit nemáte dovoleno"
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "je nám líto, ale zachovat prostředí nemáte dovoleno"
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr "příkaz je příliš dlouhý"
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s není běžný soubor"
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s je vlastněn UID %u, měl by být vlastněn %u"
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr "%s je zapisovatelný pro všechny"
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s je vlastněn GID %u, mělo by být %u"
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "pouze root může použít „-c %s“"
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr "neznáma přihlašovací třída: %s"
+
+#: plugins/sudoers/sudoers.c:1069 plugins/sudoers/sudoers.c:1083
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "nelze přeložit název stroje %s"
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "neplatná volba filtru: %s"
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "neplatná maximální doba čekání: %s"
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "neplatný násobek rychlosti: %s"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/časování: %s"
+
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/časování: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Přehrává se relace sudo: %s"
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr "událost nelze přidat do fronty"
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr "TTY nelze nastavit do přímého režimu"
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Pozor: váš terminál je příliš malý pro správné zobrazení záznamu.\n"
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Rozměry záznamu jsou %d × %d, váš terminál má rozměry %d × %d."
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Přehrávání skončilo, pro obnovení terminálu stiskněte libovolnou klávesu."
+
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "neplatný řádek s časovacím souborem: %s"
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "nejednoznačný výraz „%s“"
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr "ve výrazu neodpovídá „)“"
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "neznámý vyhledávací výraz „%s“"
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s vyžaduje argument"
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "neplatný regulární výraz: %s"
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "datum „%s“ se nepodařilo rozebrat"
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr "ve výrazu neodpovídá „(“"
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr "zakázané zakončení „or“"
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr "zakázané zakončení „!“"
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr "neznámý vyhledávácí typ %d"
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr "použití: %s [-hnRS] [-d adresář] [-m číslo] [-s číslo] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "použití: %s [-h] [-d adresář] -l [vyhledávací_výraz]\n"
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s – přehraje záznam relace sudo\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Přepínače:\n"
+" -d, --directory=adresář\n"
+" určuje adresář pro záznamy relace\n"
+" -f, --filter=filtr určuje, které druhy I/O se mají zobrazit\n"
+" -h, --help zobrazí nápovědu a skončí\n"
+" -l, --list vypíše seznam ID dostupných relací, s volitelným výrazem\n"
+" -m, --max-wait=číslo čeká maximálně počet sekund mezi událostmi\n"
+" -S, --suspend-wait čeká pokud byl příkaz pozastaven\n"
+" -s, --speed=číslo zrychlí nebo zpomalí výstup\n"
+" -V, --version zobrazí údaje o verzi a skončí"
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr "\tstroj se neshoduje"
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Příkaz povolen"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Příkaz odepřen"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Příkaz se neshoduje"
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr "%s je zapisovatelný pro skupinu"
+
+# TODO: pluralize
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "nelze zkrátit soubor s časovými údaji na %lld bajtů"
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:482 plugins/sudoers/visudo.c:488
+msgid "unable to read the clock"
+msgstr "nelze přečíst hodiny"
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr "časový údaj z budoucnosti se ignoruje"
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "časový údaj ukazuje příliš do budoucna: %20.20s"
+
+# TODO: pluralize
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "soubor s časovými údaji %s nelze zamknout"
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "cesta ke stavům lekce je příliš dlouhý: %s/%s"
+
+#: plugins/sudoers/visudo.c:216
+msgid "the -x option will be removed in a future release"
+msgstr "přepínač -x bude v příštím vydání odstraněn"
+
+#: plugins/sudoers/visudo.c:217
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "prosím, zvažte použití nástroje cvtsudoers"
+
+#: plugins/sudoers/visudo.c:268 plugins/sudoers/visudo.c:650
+#, c-format
+msgid "press return to edit %s: "
+msgstr "pro úpravu %s stiskněte enter: "
+
+#: plugins/sudoers/visudo.c:329
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "zadaný editor (%s) neexistuje"
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "žádný editor nenalezen (cesta k editoru = %s)"
+
+#: plugins/sudoers/visudo.c:441 plugins/sudoers/visudo.c:449
+msgid "write error"
+msgstr "chyba zápisu"
+
+#: plugins/sudoers/visudo.c:495
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "nelze získat údaje o dočasném souboru (%s), %s nezměněno"
+
+#: plugins/sudoers/visudo.c:502
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "dočasný soubor o nulové velikosti (%s), %s nezměněno"
+
+#: plugins/sudoers/visudo.c:508
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "editor (%s) selhal, %s nezměněno"
+
+#: plugins/sudoers/visudo.c:530
+#, c-format
+msgid "%s unchanged"
+msgstr "%s nezměněno"
+
+#: plugins/sudoers/visudo.c:589
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "nelze znovu otevřít dočasný soubor (%s), %s nezměněno."
+
+#: plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "nebylo možné rozebrat dočasný soubor (%s), neznámá chyba"
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "vnitřní chyba, v seznamu nelze nalézt %s!"
+
+#: plugins/sudoers/visudo.c:719 plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "nelze nastavit (UID, GID) %s na (%u, %u)"
+
+#: plugins/sudoers/visudo.c:751
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s a %s se nenachází na jednom souborovém systému, pro přejmenování se použije mv"
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "příkaz selhal: „'%s %s %s“, %s nezměněno"
+
+#: plugins/sudoers/visudo.c:775
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "chyba při přejmenování %s, %s nezměněno"
+
+#: plugins/sudoers/visudo.c:796
+msgid "What now? "
+msgstr "Co teď? "
+
+#: plugins/sudoers/visudo.c:810
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Možnosti jsou:\n"
+" (e) upravit soubor sudoers znovu\n"
+" (x) skončit bez uložení změn do souboru sudoers\n"
+" (Q) skončit a uložit změny do souboru sudoers (NEBEZPEČNÉ!)\n"
+
+#: plugins/sudoers/visudo.c:856
+#, c-format
+msgid "unable to run %s"
+msgstr "nelze spustit %s"
+
+#: plugins/sudoers/visudo.c:886
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: chybný vlastník (UID, GID), měl by být (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: chybná práva, měla by být 0%o\n"
+
+#: plugins/sudoers/visudo.c:950 plugins/sudoers/visudo.c:957
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: rozbor úspěšný\n"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s je zaneprázdněn, zkuste to později"
+
+#: plugins/sudoers/visudo.c:979
+#, c-format
+msgid "unable to lock %s"
+msgstr "%s nelze uzamknout"
+
+# The code indeed checks for non-localized "y" character.
+#: plugins/sudoers/visudo.c:980
+msgid "Edit anyway? [y/N]"
+msgstr "Přesto upravit? [y/N]"
+
+#: plugins/sudoers/visudo.c:1064
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Chyba: %s:%d: smyčka v %s „%s“"
+
+#: plugins/sudoers/visudo.c:1065
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Pozor: %s:%d: smyčka v %s „%s“"
+
+#: plugins/sudoers/visudo.c:1069
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Chyba: %s:%d: %s „%s“ použit, ale nedefinován"
+
+#: plugins/sudoers/visudo.c:1070
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Pozor: %s:%d: %s „%s“ použit, ale nedefinován"
+
+#: plugins/sudoers/visudo.c:1161
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Pozor> %s:%d nepoužitý %s „%s“"
+
+#: plugins/sudoers/visudo.c:1276
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s – bezpečně upraví soubor sudoers\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1278
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"Přepínače:\n"
+" -c, --check pouze kontroluje\n"
+" -f, --file=sudoers\n"
+" určuje umístění souboru sudoers\n"
+" -h, --help zobrazí nápovědu a skončí\n"
+" -q, --quiet méně upovídaná (stručnější) hlášení chyb syntaxe\n"
+" -s, --strict přísná kontrola syntaxe\n"
+" -V, --version zobrazí údaje o verzi a skončí\n"
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr "příliš mnoho úrovní zanoření"
+
+#~ msgid ""
+#~ "\n"
+#~ "LDAP Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Role LDAP: NEZNÁMÁ\n"
+
+#~ msgid " Order: %s\n"
+#~ msgstr " Pořadí: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: %s\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Role SSSD: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Role SSSD: NEZNÁMÁ\n"
+
+#~ msgid "Warning: cycle in %s `%s'"
+#~ msgstr "Pozor: smyčka v %s „%s“"
+
+#~ msgid "Warning: %s `%s' referenced but not defined"
+#~ msgstr "Pozor: %s „%s“ použit, ale nedefinován"
+
+#~ msgid "Warning: unused %s `%s'"
+#~ msgstr "Pozor: nepožitý %s „%s“"
+
+#~ msgid "unable allocate memory"
+#~ msgstr "nelze alokovat paměť"
+
+#~ msgid "timestamp path too long: %s/%s"
+#~ msgstr "cesta k časovým údajům je příliš dlouhá: %s/%s"
+
+#~ msgid "unable to stat editor (%s)"
+#~ msgstr "nelze zjisti údaje o editoru (%s)"
+
+#~ msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+#~ msgstr "sudo_ldap_conf_add_ports: nedostatek místa na rozšíření hostbuf"
+
+#~ msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+#~ msgstr "sudo_ldap_parse_uri: nedostatek místo pro vytvoření hostbuf"
+
+#~ msgid "sudo_ldap_build_pass1 allocation mismatch"
+#~ msgstr "nesouhlasí alokace sudo_ldap_build_pass1"
+
+#~ msgid "internal error: insufficient space for log line"
+#~ msgstr "vnitřní chyba: nedostatek místa pro řádek protokolu"
+
+#~ msgid "fill_args: buffer overflow"
+#~ msgstr "fill_args: přetečení bufferu"
diff --git a/plugins/sudoers/po/da.mo b/plugins/sudoers/po/da.mo
new file mode 100644
index 0000000..c185751
--- /dev/null
+++ b/plugins/sudoers/po/da.mo
Binary files differ
diff --git a/plugins/sudoers/po/da.po b/plugins/sudoers/po/da.po
new file mode 100644
index 0000000..c1cb6f4
--- /dev/null
+++ b/plugins/sudoers/po/da.po
@@ -0,0 +1,2344 @@
+# Danish translation of sudoers.
+# This file is put in the public domain.
+# Joe Hansen <joedalton2@yahoo.dk>, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018.
+#
+# audit -> overvågning
+# dummy -> attrap
+# epoch -> epoke
+# execute -> udføre (run -> kør)
+# overflow -> overløb
+# principal -> værtshovedstol
+# runas -> runas ? (eller måske bedre med kør som. den er valgt indtil videre)
+# stat -> stat
+# timeout -> tidsudløb (eller ventetid, er dog lidt noget andet)
+#
+# der bliver brugt masser af forskellige citationstegn i den her ('' \" \" ``,
+# nogle gange også tre styk). De er alle lavet med »« på dansk.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.24b2\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-07-31 07:13-0600\n"
+"PO-Revision-Date: 2018-08-12 07:48+0200\n"
+"Last-Translator: joe Hansen <joedalton2@yahoo.dk>\n"
+"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
+"Language: da\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.8.11\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "syntaksfejl"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "%ps adgangskode: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] adgangskode for %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Adgangskode: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** SIKKERHEDSINFORMATION for %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Beklager, prøv igen."
+
+#: gram.y:194 gram.y:242 gram.y:249 gram.y:256 gram.y:263 gram.y:270
+#: gram.y:286 gram.y:310 gram.y:317 gram.y:324 gram.y:331 gram.y:338
+#: gram.y:401 gram.y:409 gram.y:419 gram.y:452 gram.y:459 gram.y:466
+#: gram.y:473 gram.y:555 gram.y:562 gram.y:571 gram.y:580 gram.y:597
+#: gram.y:709 gram.y:716 gram.y:723 gram.y:731 gram.y:831 gram.y:838
+#: gram.y:845 gram.y:852 gram.y:859 gram.y:885 gram.y:892 gram.y:899
+#: gram.y:1022 gram.y:1296 plugins/sudoers/alias.c:122
+#: plugins/sudoers/alias.c:129 plugins/sudoers/alias.c:145
+#: plugins/sudoers/auth/bsdauth.c:141 plugins/sudoers/auth/kerb5.c:119
+#: plugins/sudoers/auth/kerb5.c:145 plugins/sudoers/auth/pam.c:519
+#: plugins/sudoers/auth/rfc1938.c:109 plugins/sudoers/auth/sia.c:59
+#: plugins/sudoers/cvtsudoers.c:116 plugins/sudoers/cvtsudoers.c:157
+#: plugins/sudoers/cvtsudoers.c:174 plugins/sudoers/cvtsudoers.c:185
+#: plugins/sudoers/cvtsudoers.c:278 plugins/sudoers/cvtsudoers.c:405
+#: plugins/sudoers/cvtsudoers.c:538 plugins/sudoers/cvtsudoers.c:555
+#: plugins/sudoers/cvtsudoers.c:660 plugins/sudoers/cvtsudoers.c:773
+#: plugins/sudoers/cvtsudoers.c:781 plugins/sudoers/cvtsudoers.c:1186
+#: plugins/sudoers/cvtsudoers.c:1190 plugins/sudoers/cvtsudoers.c:1290
+#: plugins/sudoers/cvtsudoers_ldif.c:147 plugins/sudoers/cvtsudoers_ldif.c:189
+#: plugins/sudoers/cvtsudoers_ldif.c:236 plugins/sudoers/cvtsudoers_ldif.c:255
+#: plugins/sudoers/cvtsudoers_ldif.c:325 plugins/sudoers/cvtsudoers_ldif.c:380
+#: plugins/sudoers/cvtsudoers_ldif.c:388 plugins/sudoers/cvtsudoers_ldif.c:405
+#: plugins/sudoers/cvtsudoers_ldif.c:414 plugins/sudoers/cvtsudoers_ldif.c:560
+#: plugins/sudoers/cvtsudoers_ldif.c:753 plugins/sudoers/cvtsudoers_ldif.c:780
+#: plugins/sudoers/cvtsudoers_ldif.c:848 plugins/sudoers/cvtsudoers_ldif.c:855
+#: plugins/sudoers/cvtsudoers_ldif.c:860 plugins/sudoers/cvtsudoers_ldif.c:936
+#: plugins/sudoers/cvtsudoers_ldif.c:947 plugins/sudoers/cvtsudoers_ldif.c:953
+#: plugins/sudoers/cvtsudoers_ldif.c:978 plugins/sudoers/cvtsudoers_ldif.c:990
+#: plugins/sudoers/cvtsudoers_ldif.c:994
+#: plugins/sudoers/cvtsudoers_ldif.c:1008
+#: plugins/sudoers/cvtsudoers_ldif.c:1176
+#: plugins/sudoers/cvtsudoers_ldif.c:1208
+#: plugins/sudoers/cvtsudoers_ldif.c:1233
+#: plugins/sudoers/cvtsudoers_ldif.c:1262
+#: plugins/sudoers/cvtsudoers_ldif.c:1312
+#: plugins/sudoers/cvtsudoers_ldif.c:1358
+#: plugins/sudoers/cvtsudoers_ldif.c:1368 plugins/sudoers/defaults.c:656
+#: plugins/sudoers/defaults.c:952 plugins/sudoers/defaults.c:1123
+#: plugins/sudoers/editor.c:65 plugins/sudoers/editor.c:83
+#: plugins/sudoers/editor.c:94 plugins/sudoers/env.c:233
+#: plugins/sudoers/filedigest.c:61 plugins/sudoers/filedigest.c:77
+#: plugins/sudoers/gc.c:52 plugins/sudoers/group_plugin.c:131
+#: plugins/sudoers/interfaces.c:71 plugins/sudoers/iolog.c:938
+#: plugins/sudoers/iolog_path.c:167 plugins/sudoers/ldap.c:177
+#: plugins/sudoers/ldap.c:408 plugins/sudoers/ldap.c:412
+#: plugins/sudoers/ldap.c:424 plugins/sudoers/ldap.c:715
+#: plugins/sudoers/ldap.c:879 plugins/sudoers/ldap.c:1228
+#: plugins/sudoers/ldap.c:1654 plugins/sudoers/ldap.c:1691
+#: plugins/sudoers/ldap.c:1771 plugins/sudoers/ldap.c:1906
+#: plugins/sudoers/ldap.c:2007 plugins/sudoers/ldap.c:2023
+#: plugins/sudoers/ldap_conf.c:214 plugins/sudoers/ldap_conf.c:245
+#: plugins/sudoers/ldap_conf.c:297 plugins/sudoers/ldap_conf.c:333
+#: plugins/sudoers/ldap_conf.c:422 plugins/sudoers/ldap_conf.c:437
+#: plugins/sudoers/ldap_conf.c:533 plugins/sudoers/ldap_conf.c:566
+#: plugins/sudoers/ldap_conf.c:647 plugins/sudoers/ldap_conf.c:729
+#: plugins/sudoers/ldap_util.c:519 plugins/sudoers/ldap_util.c:575
+#: plugins/sudoers/linux_audit.c:76 plugins/sudoers/logging.c:190
+#: plugins/sudoers/logging.c:506 plugins/sudoers/logging.c:527
+#: plugins/sudoers/logging.c:568 plugins/sudoers/logging.c:745
+#: plugins/sudoers/logging.c:1003 plugins/sudoers/match.c:693
+#: plugins/sudoers/match.c:740 plugins/sudoers/match.c:781
+#: plugins/sudoers/match.c:809 plugins/sudoers/match.c:897
+#: plugins/sudoers/match.c:977 plugins/sudoers/parse.c:192
+#: plugins/sudoers/parse.c:204 plugins/sudoers/parse.c:219
+#: plugins/sudoers/parse.c:231 plugins/sudoers/policy.c:497
+#: plugins/sudoers/policy.c:739 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/pwutil.c:191 plugins/sudoers/pwutil.c:263
+#: plugins/sudoers/pwutil.c:340 plugins/sudoers/pwutil.c:514
+#: plugins/sudoers/pwutil.c:580 plugins/sudoers/pwutil.c:650
+#: plugins/sudoers/pwutil.c:808 plugins/sudoers/pwutil.c:865
+#: plugins/sudoers/pwutil.c:910 plugins/sudoers/pwutil.c:968
+#: plugins/sudoers/sssd.c:147 plugins/sudoers/sssd.c:387
+#: plugins/sudoers/sssd.c:450 plugins/sudoers/sssd.c:494
+#: plugins/sudoers/sssd.c:541 plugins/sudoers/sssd.c:732
+#: plugins/sudoers/stubs.c:96 plugins/sudoers/stubs.c:104
+#: plugins/sudoers/sudoers.c:265 plugins/sudoers/sudoers.c:275
+#: plugins/sudoers/sudoers.c:283 plugins/sudoers/sudoers.c:325
+#: plugins/sudoers/sudoers.c:648 plugins/sudoers/sudoers.c:774
+#: plugins/sudoers/sudoers.c:818 plugins/sudoers/sudoers.c:1092
+#: plugins/sudoers/sudoers_debug.c:107 plugins/sudoers/sudoreplay.c:1265
+#: plugins/sudoers/sudoreplay.c:1377 plugins/sudoers/sudoreplay.c:1417
+#: plugins/sudoers/sudoreplay.c:1426 plugins/sudoers/sudoreplay.c:1436
+#: plugins/sudoers/sudoreplay.c:1444 plugins/sudoers/sudoreplay.c:1448
+#: plugins/sudoers/sudoreplay.c:1604 plugins/sudoers/sudoreplay.c:1608
+#: plugins/sudoers/testsudoers.c:125 plugins/sudoers/testsudoers.c:215
+#: plugins/sudoers/testsudoers.c:232 plugins/sudoers/testsudoers.c:554
+#: plugins/sudoers/timestamp.c:401 plugins/sudoers/timestamp.c:445
+#: plugins/sudoers/timestamp.c:923 plugins/sudoers/toke_util.c:55
+#: plugins/sudoers/toke_util.c:108 plugins/sudoers/toke_util.c:145
+#: plugins/sudoers/tsdump.c:125 plugins/sudoers/visudo.c:145
+#: plugins/sudoers/visudo.c:307 plugins/sudoers/visudo.c:313
+#: plugins/sudoers/visudo.c:423 plugins/sudoers/visudo.c:601
+#: plugins/sudoers/visudo.c:920 plugins/sudoers/visudo.c:987
+#: plugins/sudoers/visudo.c:1076 toke.l:847 toke.l:948 toke.l:1105
+msgid "unable to allocate memory"
+msgstr "kan ikke tildele hukommelse"
+
+#: gram.y:484
+msgid "a digest requires a path name"
+msgstr "et sammendrag kræver et stinavn"
+
+#: gram.y:610
+msgid "invalid notbefore value"
+msgstr "ugyldig notbefore-værdi"
+
+#: gram.y:618
+msgid "invalid notafter value"
+msgstr "ugyldig notafter-værdi"
+
+#: gram.y:627 plugins/sudoers/policy.c:313
+msgid "timeout value too large"
+msgstr "værdi for tidsudløb er for stor"
+
+#: gram.y:629 plugins/sudoers/policy.c:315
+msgid "invalid timeout value"
+msgstr "ugyldig værdi for tidsudløb"
+
+#: gram.y:1296 plugins/sudoers/auth/pam.c:349 plugins/sudoers/auth/pam.c:519
+#: plugins/sudoers/auth/rfc1938.c:109 plugins/sudoers/cvtsudoers.c:116
+#: plugins/sudoers/cvtsudoers.c:156 plugins/sudoers/cvtsudoers.c:173
+#: plugins/sudoers/cvtsudoers.c:184 plugins/sudoers/cvtsudoers.c:277
+#: plugins/sudoers/cvtsudoers.c:404 plugins/sudoers/cvtsudoers.c:537
+#: plugins/sudoers/cvtsudoers.c:554 plugins/sudoers/cvtsudoers.c:660
+#: plugins/sudoers/cvtsudoers.c:773 plugins/sudoers/cvtsudoers.c:780
+#: plugins/sudoers/cvtsudoers.c:1186 plugins/sudoers/cvtsudoers.c:1190
+#: plugins/sudoers/cvtsudoers.c:1290 plugins/sudoers/cvtsudoers_ldif.c:146
+#: plugins/sudoers/cvtsudoers_ldif.c:188 plugins/sudoers/cvtsudoers_ldif.c:235
+#: plugins/sudoers/cvtsudoers_ldif.c:254 plugins/sudoers/cvtsudoers_ldif.c:324
+#: plugins/sudoers/cvtsudoers_ldif.c:379 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:404 plugins/sudoers/cvtsudoers_ldif.c:413
+#: plugins/sudoers/cvtsudoers_ldif.c:559 plugins/sudoers/cvtsudoers_ldif.c:752
+#: plugins/sudoers/cvtsudoers_ldif.c:779 plugins/sudoers/cvtsudoers_ldif.c:847
+#: plugins/sudoers/cvtsudoers_ldif.c:854 plugins/sudoers/cvtsudoers_ldif.c:859
+#: plugins/sudoers/cvtsudoers_ldif.c:935 plugins/sudoers/cvtsudoers_ldif.c:946
+#: plugins/sudoers/cvtsudoers_ldif.c:952 plugins/sudoers/cvtsudoers_ldif.c:977
+#: plugins/sudoers/cvtsudoers_ldif.c:989 plugins/sudoers/cvtsudoers_ldif.c:993
+#: plugins/sudoers/cvtsudoers_ldif.c:1007
+#: plugins/sudoers/cvtsudoers_ldif.c:1176
+#: plugins/sudoers/cvtsudoers_ldif.c:1207
+#: plugins/sudoers/cvtsudoers_ldif.c:1232
+#: plugins/sudoers/cvtsudoers_ldif.c:1261
+#: plugins/sudoers/cvtsudoers_ldif.c:1311
+#: plugins/sudoers/cvtsudoers_ldif.c:1357
+#: plugins/sudoers/cvtsudoers_ldif.c:1367 plugins/sudoers/defaults.c:656
+#: plugins/sudoers/defaults.c:952 plugins/sudoers/defaults.c:1123
+#: plugins/sudoers/editor.c:65 plugins/sudoers/editor.c:83
+#: plugins/sudoers/editor.c:94 plugins/sudoers/env.c:233
+#: plugins/sudoers/filedigest.c:61 plugins/sudoers/filedigest.c:77
+#: plugins/sudoers/gc.c:52 plugins/sudoers/group_plugin.c:131
+#: plugins/sudoers/interfaces.c:71 plugins/sudoers/iolog.c:938
+#: plugins/sudoers/iolog_path.c:167 plugins/sudoers/ldap.c:177
+#: plugins/sudoers/ldap.c:408 plugins/sudoers/ldap.c:412
+#: plugins/sudoers/ldap.c:424 plugins/sudoers/ldap.c:715
+#: plugins/sudoers/ldap.c:879 plugins/sudoers/ldap.c:1228
+#: plugins/sudoers/ldap.c:1654 plugins/sudoers/ldap.c:1691
+#: plugins/sudoers/ldap.c:1771 plugins/sudoers/ldap.c:1906
+#: plugins/sudoers/ldap.c:2007 plugins/sudoers/ldap.c:2023
+#: plugins/sudoers/ldap_conf.c:214 plugins/sudoers/ldap_conf.c:245
+#: plugins/sudoers/ldap_conf.c:297 plugins/sudoers/ldap_conf.c:333
+#: plugins/sudoers/ldap_conf.c:422 plugins/sudoers/ldap_conf.c:437
+#: plugins/sudoers/ldap_conf.c:533 plugins/sudoers/ldap_conf.c:566
+#: plugins/sudoers/ldap_conf.c:646 plugins/sudoers/ldap_conf.c:729
+#: plugins/sudoers/ldap_util.c:519 plugins/sudoers/ldap_util.c:575
+#: plugins/sudoers/linux_audit.c:76 plugins/sudoers/logging.c:190
+#: plugins/sudoers/logging.c:506 plugins/sudoers/logging.c:527
+#: plugins/sudoers/logging.c:567 plugins/sudoers/logging.c:1003
+#: plugins/sudoers/match.c:692 plugins/sudoers/match.c:739
+#: plugins/sudoers/match.c:781 plugins/sudoers/match.c:809
+#: plugins/sudoers/match.c:897 plugins/sudoers/match.c:976
+#: plugins/sudoers/parse.c:191 plugins/sudoers/parse.c:203
+#: plugins/sudoers/parse.c:218 plugins/sudoers/parse.c:230
+#: plugins/sudoers/policy.c:127 plugins/sudoers/policy.c:136
+#: plugins/sudoers/policy.c:145 plugins/sudoers/policy.c:171
+#: plugins/sudoers/policy.c:298 plugins/sudoers/policy.c:313
+#: plugins/sudoers/policy.c:315 plugins/sudoers/policy.c:341
+#: plugins/sudoers/policy.c:351 plugins/sudoers/policy.c:395
+#: plugins/sudoers/policy.c:405 plugins/sudoers/policy.c:414
+#: plugins/sudoers/policy.c:423 plugins/sudoers/policy.c:497
+#: plugins/sudoers/policy.c:739 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/pwutil.c:191 plugins/sudoers/pwutil.c:263
+#: plugins/sudoers/pwutil.c:340 plugins/sudoers/pwutil.c:514
+#: plugins/sudoers/pwutil.c:580 plugins/sudoers/pwutil.c:650
+#: plugins/sudoers/pwutil.c:808 plugins/sudoers/pwutil.c:865
+#: plugins/sudoers/pwutil.c:910 plugins/sudoers/pwutil.c:968
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1476
+#: plugins/sudoers/set_perms.c:1641 plugins/sudoers/sssd.c:146
+#: plugins/sudoers/sssd.c:387 plugins/sudoers/sssd.c:450
+#: plugins/sudoers/sssd.c:494 plugins/sudoers/sssd.c:541
+#: plugins/sudoers/sssd.c:732 plugins/sudoers/stubs.c:96
+#: plugins/sudoers/stubs.c:104 plugins/sudoers/sudoers.c:265
+#: plugins/sudoers/sudoers.c:275 plugins/sudoers/sudoers.c:283
+#: plugins/sudoers/sudoers.c:325 plugins/sudoers/sudoers.c:648
+#: plugins/sudoers/sudoers.c:774 plugins/sudoers/sudoers.c:818
+#: plugins/sudoers/sudoers.c:1092 plugins/sudoers/sudoers_debug.c:106
+#: plugins/sudoers/sudoreplay.c:1265 plugins/sudoers/sudoreplay.c:1377
+#: plugins/sudoers/sudoreplay.c:1417 plugins/sudoers/sudoreplay.c:1426
+#: plugins/sudoers/sudoreplay.c:1436 plugins/sudoers/sudoreplay.c:1444
+#: plugins/sudoers/sudoreplay.c:1448 plugins/sudoers/sudoreplay.c:1604
+#: plugins/sudoers/sudoreplay.c:1608 plugins/sudoers/testsudoers.c:125
+#: plugins/sudoers/testsudoers.c:215 plugins/sudoers/testsudoers.c:232
+#: plugins/sudoers/testsudoers.c:554 plugins/sudoers/timestamp.c:401
+#: plugins/sudoers/timestamp.c:445 plugins/sudoers/timestamp.c:923
+#: plugins/sudoers/toke_util.c:55 plugins/sudoers/toke_util.c:108
+#: plugins/sudoers/toke_util.c:145 plugins/sudoers/tsdump.c:125
+#: plugins/sudoers/visudo.c:145 plugins/sudoers/visudo.c:307
+#: plugins/sudoers/visudo.c:313 plugins/sudoers/visudo.c:423
+#: plugins/sudoers/visudo.c:601 plugins/sudoers/visudo.c:920
+#: plugins/sudoers/visudo.c:987 plugins/sudoers/visudo.c:1076 toke.l:847
+#: toke.l:948 toke.l:1105
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:140
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Alias »%s« er allerede defineret"
+
+#: plugins/sudoers/auth/bsdauth.c:68
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "kan ikke hente logindklasse for bruger %s"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+msgid "unable to begin bsd authentication"
+msgstr "kan ikke starte bsd-godkendelse"
+
+#: plugins/sudoers/auth/bsdauth.c:81
+msgid "invalid authentication type"
+msgstr "ugyldig godkendelsestype"
+
+#: plugins/sudoers/auth/bsdauth.c:90
+msgid "unable to initialize BSD authentication"
+msgstr "kan ikke initialisere BSD-godkendelse"
+
+#: plugins/sudoers/auth/bsdauth.c:178
+msgid "your account has expired"
+msgstr "din konto er udløbet"
+
+#: plugins/sudoers/auth/bsdauth.c:180
+msgid "approval failed"
+msgstr "godkendelse mislykkedes"
+
+#: plugins/sudoers/auth/fwtk.c:52
+msgid "unable to read fwtk config"
+msgstr "kan ikke læse fwtk-konfiguration"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to connect to authentication server"
+msgstr "kan ikke forbinde til godkendelsesserver"
+
+#: plugins/sudoers/auth/fwtk.c:63 plugins/sudoers/auth/fwtk.c:87
+#: plugins/sudoers/auth/fwtk.c:119
+msgid "lost connection to authentication server"
+msgstr "mistede forbindelsen til godkendelseserveren"
+
+#: plugins/sudoers/auth/fwtk.c:67
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"godkendelsesserverfejl:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:111
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: Kan ikke konvertere værtshovedstol til streng (»%s«): %s"
+
+#: plugins/sudoers/auth/kerb5.c:161
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: Kan ikke fortolke »%s«: %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: Kan ikke slå akkreditivmellemlager op: %s"
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: Kan ikke allokere tilvalg: %s"
+
+#: plugins/sudoers/auth/kerb5.c:232
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: Kan ikke indhente akkreditiver: %s"
+
+#: plugins/sudoers/auth/kerb5.c:245
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: Kan ikke initialisere akkreditivmellemlager: %s"
+
+#: plugins/sudoers/auth/kerb5.c:248
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: Kan ikke gemme akkreditiver i mellemlager: %s"
+
+#: plugins/sudoers/auth/kerb5.c:312
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: Kan ikke indhente værtshovedstol: %s"
+
+#: plugins/sudoers/auth/kerb5.c:326
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Kan ikke verifiere TGT! Muligt angreb!: %s"
+
+#: plugins/sudoers/auth/pam.c:108
+msgid "unable to initialize PAM"
+msgstr "kan ikke initialisere PAM"
+
+#: plugins/sudoers/auth/pam.c:199
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "PAM-godkendelsesserverfejl: %s"
+
+#: plugins/sudoers/auth/pam.c:216
+msgid "account validation failure, is your account locked?"
+msgstr "valideringsfejl for konto, er din konto låst?"
+
+#: plugins/sudoers/auth/pam.c:224
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Konto eller adgangskoder er udløbet, nulstil din adgangskode og forsøg igen"
+
+#: plugins/sudoers/auth/pam.c:233
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "kan ikke ændre udløbet adgangskode: %s"
+
+#: plugins/sudoers/auth/pam.c:241
+msgid "Password expired, contact your system administrator"
+msgstr "Adgangskode udløbet, kontakt din systemadministrator"
+
+#: plugins/sudoers/auth/pam.c:245
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Konto udløbet eller PAM-konfiguration mangler et »kontoafsnit« for sudo. Kontakt din systemadministrator"
+
+#: plugins/sudoers/auth/pam.c:252 plugins/sudoers/auth/pam.c:257
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "PAM-kontohåndteringsfejl: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:97 plugins/sudoers/visudo.c:227
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "du findes ikke i %s-databasen"
+
+#: plugins/sudoers/auth/securid5.c:73
+msgid "failed to initialise the ACE API library"
+msgstr "kunne ikke initialisere ACE API-biblioteket"
+
+#: plugins/sudoers/auth/securid5.c:99
+msgid "unable to contact the SecurID server"
+msgstr "kan ikke kontakte SecurID-serveren"
+
+#: plugins/sudoers/auth/securid5.c:108
+msgid "User ID locked for SecurID Authentication"
+msgstr "Bruger-ID låst for SecurID-godkendelse"
+
+#: plugins/sudoers/auth/securid5.c:112 plugins/sudoers/auth/securid5.c:163
+msgid "invalid username length for SecurID"
+msgstr "ugyldigt brugernavnslængde for SecurID"
+
+#: plugins/sudoers/auth/securid5.c:116 plugins/sudoers/auth/securid5.c:168
+msgid "invalid Authentication Handle for SecurID"
+msgstr "ugyldigt godkendelseshåndtag for SecurID"
+
+#: plugins/sudoers/auth/securid5.c:120
+msgid "SecurID communication failed"
+msgstr "SecurID-kommunikation fejlede"
+
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:213
+msgid "unknown SecurID error"
+msgstr "ukendt SecurID-fejl"
+
+#: plugins/sudoers/auth/securid5.c:158
+msgid "invalid passcode length for SecurID"
+msgstr "ugyldig adgangskodelængde for SecurID"
+
+#: plugins/sudoers/auth/sia.c:69 plugins/sudoers/auth/sia.c:124
+msgid "unable to initialize SIA session"
+msgstr "kan ikke initialisere SIA-session"
+
+#: plugins/sudoers/auth/sudo_auth.c:131
+msgid "invalid authentication methods"
+msgstr "ugyldige godkendelsesmetoder"
+
+#: plugins/sudoers/auth/sudo_auth.c:133
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Ugyldige godkendelsesmetoder kompileret ind i sudo! Du kan ikke blande uafhængig og ikkeuafhængig godkendelse."
+
+#: plugins/sudoers/auth/sudo_auth.c:254 plugins/sudoers/auth/sudo_auth.c:304
+msgid "no authentication methods"
+msgstr "ingen godkendelsesmetoder"
+
+#: plugins/sudoers/auth/sudo_auth.c:256
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Der er ingen godkendelsesmetoder kompileret ind i sudo! Hvis du ønsker at fravælge godkendelse så brug konfigurationstilvalget --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:306
+msgid "Unable to initialize authentication methods."
+msgstr "Kan ikke initialisere godkendelsesmetoder."
+
+#: plugins/sudoers/auth/sudo_auth.c:472
+msgid "Authentication methods:"
+msgstr "Godkendelsesmetoder:"
+
+#: plugins/sudoers/bsm_audit.c:120 plugins/sudoers/bsm_audit.c:211
+msgid "Could not determine audit condition"
+msgstr "Kunne ikke bestemme overvågningsbetingelse"
+
+#: plugins/sudoers/bsm_audit.c:183 plugins/sudoers/bsm_audit.c:273
+msgid "unable to commit audit record"
+msgstr "kan ikke indsende overvågningspost"
+
+#: plugins/sudoers/check.c:262
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Vi stoler på, at du har modtaget den gængse advarsel fra den lokale\n"
+"systemadministrator. Det drejer sig normalt om følgende tre ting:\n"
+"\n"
+" #1) Respekter andres privatliv.\n"
+" #2) Tænk før du taster.\n"
+" #3) Med stor magt følger stort ansvar.\n"
+"\n"
+
+#: plugins/sudoers/check.c:305 plugins/sudoers/check.c:315
+#: plugins/sudoers/sudoers.c:691 plugins/sudoers/sudoers.c:736
+#: plugins/sudoers/tsdump.c:121
+#, c-format
+msgid "unknown uid: %u"
+msgstr "ukendt uid: %u"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/iolog.c:257
+#: plugins/sudoers/policy.c:912 plugins/sudoers/sudoers.c:1131
+#: plugins/sudoers/testsudoers.c:206 plugins/sudoers/testsudoers.c:366
+#, c-format
+msgid "unknown user: %s"
+msgstr "ukendt bruger: %s"
+
+#: plugins/sudoers/cvtsudoers.c:191
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "rækkefølgeforøgelse: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:207
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "startrækkefølge: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:218 plugins/sudoers/sudoreplay.c:310
+#: plugins/sudoers/visudo.c:177
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s version %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:220 plugins/sudoers/visudo.c:179
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s grammatikversion %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:237
+#, c-format
+msgid "unsupported input format %s"
+msgstr "ej understøttet inddataformat %s"
+
+#: plugins/sudoers/cvtsudoers.c:252
+#, c-format
+msgid "unsupported output format %s"
+msgstr "ej understøttet uddataformat %s"
+
+#: plugins/sudoers/cvtsudoers.c:292
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: inddata- og uddatafiler skal være forskellige"
+
+#: plugins/sudoers/cvtsudoers.c:308 plugins/sudoers/sudoers.c:168
+#: plugins/sudoers/testsudoers.c:245 plugins/sudoers/visudo.c:233
+#: plugins/sudoers/visudo.c:589 plugins/sudoers/visudo.c:911
+msgid "unable to initialize sudoers default values"
+msgstr "kan ikke initialisere sudoers' standardværdier"
+
+#: plugins/sudoers/cvtsudoers.c:393 plugins/sudoers/ldap_conf.c:412
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:452
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: ukendt nøgleord: %s"
+
+#: plugins/sudoers/cvtsudoers.c:498
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "ugyldig type for standarder: %s"
+
+#: plugins/sudoers/cvtsudoers.c:521
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "ugyldig undertrykkelsestype: %s"
+
+#: plugins/sudoers/cvtsudoers.c:561 plugins/sudoers/cvtsudoers.c:575
+#, c-format
+msgid "invalid filter: %s"
+msgstr "ugyldigt filter: %s"
+
+#: plugins/sudoers/cvtsudoers.c:653 plugins/sudoers/cvtsudoers.c:1250
+#: plugins/sudoers/cvtsudoers_json.c:1113
+#: plugins/sudoers/cvtsudoers_ldif.c:627
+#: plugins/sudoers/cvtsudoers_ldif.c:1163 plugins/sudoers/iolog.c:415
+#: plugins/sudoers/sudoers.c:898 plugins/sudoers/sudoreplay.c:356
+#: plugins/sudoers/sudoreplay.c:1366 plugins/sudoers/sudoreplay.c:1570
+#: plugins/sudoers/timestamp.c:410 plugins/sudoers/tsdump.c:130
+#: plugins/sudoers/visudo.c:907
+#, c-format
+msgid "unable to open %s"
+msgstr "kan ikke åbne %s"
+
+#: plugins/sudoers/cvtsudoers.c:656 plugins/sudoers/visudo.c:916
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "kunne ikke fortolke %s-fil, ukendt fejl"
+
+#: plugins/sudoers/cvtsudoers.c:664 plugins/sudoers/visudo.c:933
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "fortolkningsfejl i %s nær linje %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:667 plugins/sudoers/visudo.c:936
+#, c-format
+msgid "parse error in %s\n"
+msgstr "fortolkningsfejl i %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:1297 plugins/sudoers/iolog.c:502
+#: plugins/sudoers/sudoreplay.c:1135 plugins/sudoers/timestamp.c:294
+#: plugins/sudoers/timestamp.c:297
+#, c-format
+msgid "unable to write to %s"
+msgstr "kan ikke skrive til %s"
+
+#: plugins/sudoers/cvtsudoers.c:1320
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s - konverter mellem sudoers-filformater\n"
+"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1322
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Tilvalg:\n"
+" -b, --base=dn base-DN'en for sudo LDAP-forespørgsler\n"
+" -d, --defaults=deftyper konverter kun Standarder for angivne typer\n"
+" -e, --expand-aliases udvid aliasser under konvertering\n"
+" -f, --output-format=format angiv uddataformat: JSON, LDIF eller sudoers\n"
+" -i, --input-format=format angiv inddataformat: LDIF eller sudoers\n"
+" -I, --increment=num mængde at øge hver sudoOrder med\n"
+" -h, --help vis denne hjælpetekst og afslut\n"
+" -m, --match=filter konverter kun poster som matcher filteret\n"
+" -M, --match-local matchfilter bruger passwd og gruppedatabaser\n"
+" -o, --output=uddatafil skriv konverteret sudoers til uddatafil\n"
+" -O, --order-start=num startpunkt for første sudoOrder\n"
+" -p, --prune-matches trim ikkematchende brugere, grupper og værter\n"
+" -s, --suppress=sektioner undertryk uddata for bestemte sektioner\n"
+" -V, --version vis information om version og afslut"
+
+#: plugins/sudoers/cvtsudoers_json.c:673 plugins/sudoers/cvtsudoers_json.c:708
+#: plugins/sudoers/cvtsudoers_json.c:924
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "ukendt indgang »%s« for standarder"
+
+#: plugins/sudoers/cvtsudoers_json.c:844 plugins/sudoers/cvtsudoers_json.c:859
+#: plugins/sudoers/cvtsudoers_ldif.c:299 plugins/sudoers/cvtsudoers_ldif.c:310
+#: plugins/sudoers/ldap.c:474
+msgid "unable to get GMT time"
+msgstr "kan ikke indhente GMT-tid"
+
+#: plugins/sudoers/cvtsudoers_json.c:847 plugins/sudoers/cvtsudoers_json.c:862
+#: plugins/sudoers/cvtsudoers_ldif.c:302 plugins/sudoers/cvtsudoers_ldif.c:313
+#: plugins/sudoers/ldap.c:480
+msgid "unable to format timestamp"
+msgstr "kan ikke formatere tidsstempel"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:517 plugins/sudoers/env.c:295
+#: plugins/sudoers/env.c:302 plugins/sudoers/env.c:407
+#: plugins/sudoers/ldap.c:488 plugins/sudoers/ldap.c:719
+#: plugins/sudoers/ldap.c:1046 plugins/sudoers/ldap_conf.c:218
+#: plugins/sudoers/ldap_conf.c:308 plugins/sudoers/linux_audit.c:82
+#: plugins/sudoers/logging.c:1008 plugins/sudoers/policy.c:618
+#: plugins/sudoers/policy.c:628 plugins/sudoers/prompt.c:161
+#: plugins/sudoers/sudoers.c:840 plugins/sudoers/testsudoers.c:236
+#: plugins/sudoers/toke_util.c:157
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "intern fejl, %s-overløb"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:622
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "miljøvariablen SUDOERS_BASE er ikke angivet og tilvalget -b var ikke angivet."
+
+#: plugins/sudoers/cvtsudoers_ldif.c:757
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "ignorerer ugyldig attributværdi: %s"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:1197
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "ignorerer ufuldstændig sudoRole: cn: %s"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:1349 plugins/sudoers/ldap.c:1778
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "ugyldig sudoOrder-attribut: %s"
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Syslog-facilitet hvis syslog bruges til logning: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Syslog-prioritet at bruge når brugergodkendelser går igennem: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Syslog-prioritet at bruge når brugergodkendelser ikke går igennem: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "Placer OTP-prompter på deres egen linje"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "Ignorer ».« i $PATH"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "Send altid post når sudo køres"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "Send post hvis brugergodkendelse fejler"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "Send post hvis brugeren ikke er i suoders"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Send post hvis brugeren ikke er i sudoers for denne vært"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Send post hvis brugeren ikke har tilladelse til at køre en kommando"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "Send post hvis brugeren forsøger at køre en kommando"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Brug et separat tidsstempel for hver bruger/tty-kombination"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "Undervis brugere den første gang de kører sudo"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Fil indeholdende sudo-undervisningen: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "Kræv som standard at brugere skal godkendes"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "Root kan køre sudo"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Log værtsnavnet i logfilen (non-syslog)"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Log året i logfilen (non-syslog)"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Hvis sudo er startet op uden argumenter så start en skal"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Angiv $HOME for målbrugeren når der startes en skal med -s"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Angiv altid $HOME for målbrugerens hjemmemappe"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Tillad lidt informationsindsamling for at lave brugbare fejlbeskeder"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Kræv fuldkvalificerede værtsnavne i sudoersfilen"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Fornærm brugeren når de indtaster en forkert adgangskode"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Tillad kun brugeren at køre sudo hvis de har en tty"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo vil overholde EDITOR-miljøvariablen"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "Spørg om adgangskoden for root, ikke brugerens"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Spørg om brugerens kør som_standard adgangskode, ikke brugernes"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Spørg om målbrugerens adgangskode, ikke brugernes"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Brug standarder i målbrugerens logindklasse hvis der er en"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Angiv LOGNAME- og USER-miljøvariablerne"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Angiv kun den effektive uid til målbrugeren, ikke den reelle uid"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Initialiser ikke gruppevektoren til målbrugerens"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Længde hvor logfillinjer skal ombrydes (0 for ingen ombrydning): %u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Tidsudløb for godkendelsestidsstempel: %.1f minutter"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Tidsudløb for adgangskodeprompt: %.1f minutter"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Antal forsøg for indtastning af adgangskode: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Umask at bruge eller 0777 for at bruge brugers: 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Sti til logfil: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Stil til postprogram: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Flag for postprogram: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Adresse at sende post til: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Adresse at sende post fra: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Emnelinje for postbeskeder: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Ugyldig adgangskodebesked: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Sti til undervisningsstatusmappen: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Sti til mappe for godkendelsestidsstempel: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Ejer af mappen for godkendelsestidsstempel: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Brugere i denne gruppe er undtaget fra adgangskode og STI-krav: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Standard for adgangskodeprompt: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Hvis angivet vil adgangsprompt overskrive systemprompt i alle tilfælde."
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Standardbruger at køre kommandoer som: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Værdi at overskrive brugers $PATH med: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Sti til redigeringsprogrammet for brug af visudo: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Hvornår der skal kræves en adgangskode for »list« pseudokommando: %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Hvornår der skal kræves en adgangskode for »verify« pseudokommando: %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Præindlæs attrap-udførelsesfunktioner indeholdt i biblioteket sudo_noexec"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Hvis LDAP-mappe er sat op, ignorer vi så lokal sudoersfil"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Filbeskrivelser >= %d vil blive lukket før udførelse af en kommando"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Hvis angivet kan brugere overskrive værdien af »closeform« med tilvalget -C"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Tillad at brugere kan angive arbitrære miljøvariabler"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "Nulstil miljøet til et standardsæt af variabler"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "Miljøvariabler at indstillingskontrollere:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "Miljøvariabler at fjerne:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "Miljøvariabler at bevare:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "SELinux-rolle at bruge i den nye sikkerhedskontekst: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "SELinux-type at bruge i den nye sikkerhedskontekst: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Sti til den sudo-specifikke miljøfil: %s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Sti til det begrænsede sudo-specifikke miljøfil: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Sprog at bruge under fortolkning af sudoers: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Tillad at sudo spørger om en adgangskode selv om den vil være synlig"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Tilbyd visuel tilbagemeldning ved adgangskodeprompten når der er brugerinddata"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Brug hurtigere globbing som er mindre præcis, men som ikke tilgår filsystemet"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "Umask'en angivet i sudoers vil overskrive brugerens, også selv om den er mere tilladende"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "Log brugers inddata for kommandoen der bliver kørt"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "Log uddata for kommandoen der bliver kørt"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "Komprimer I/O-log med brug af zlib"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "Kør altid kommandoer i en pseudo-tty"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Udvidelsesmodul for ikke-Unix-gruppeunderstøttelse: %s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Mappe at gemme inddata-/uddatalogge i: %s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Fil at gemme inddata-/uddatalog i: %s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Tilføjer et punkt til utmp/utmpx-filen når der allokeres en pty"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Angiv brugeren i utmp til brugeren kør som, ikke den opstartende bruger"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Sæt af tilladte privilegier: %s"
+
+# Det skal forstås som et sæt af grænseprivilegier
+# https://www.sudo.ws/man/1.8.21/sudoers.man.html (se limitprivs)
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Sæt af grænseprivilegier: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "Kør kommandoer på en pty i baggrunden"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "PAM-tjenestenavn der skal bruges: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "PAM-tjenestenavn der skal bruges for logindskaller: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Forsøg på at etablere PAM-akkreditiver for målbrugeren"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "Opret en ny PAM-session som kommandoen kan køre i"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Maksimalt I/O-logsekvenstal: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "Aktiver sudoers netgroup-understøttelse"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Kontroller overmappers skriverettigheder ved redigering af filer med sudoedit"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Følg symbolske henvisninger når filer redigeres med sudoedit"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "Forespørg gruppe-udvidelsesmodulet for ukendte systemgrupper"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Sammenlign netgrupper baseret på hele tuplen: bruger, vært og domæne"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Tillader at kommandoer køres, selv om sudo ikke kan skrive til revisionsloggen"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Tillader at kommandoer køres, selv om sudo ikke kan skrive til I/O-loggen"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Tillader at kommandoer køres, selv om sudo ikke kan skrive til logfilen"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Slå grupper op i sudoers og match efter gruppe-id, ikke navnet"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Logposter større end denne værdi vil blive opdelt i flere syslogbeskeder: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Bruger som vil eje I/O-logfilerne: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Gruppe som vil eje I/O-logfilerne: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Filtilstand der skal bruges for I/O-logfilerne: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Kør kommandoer efter fildeskriptor i stedet for efter sti: %s"
+
+# Defaults-punkter/indgange", vil jeg tro
+# Vil mene at det er en overskrift i konfigurationsfilen eller lignende
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Ignorer ukendte Defaults-punkter i sudoere i stedet for at give en advarsel"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Tid i sekunder hvorefter kommandoen vil blive afsluttet: %u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Tillad at brugeren angiver et tidsudløb på kommandolinjen"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Tøm I/O-logdata til disken med det samme i stedet for at mellemlagre den"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "Inkluder proces-id'et når der logges via syslog"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Elementtype for godkendelsestidsstempel: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "godkendelsesfejlbesked: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "Ignorer store/små bogstaver når brugernavne matches"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "Ignorer store/små bogstaver når gruppenavne matches"
+
+#: plugins/sudoers/defaults.c:224
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d ukendt indgang »%s« for standarder"
+
+#: plugins/sudoers/defaults.c:227
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: ukendt indgang »%s« for standarder"
+
+#: plugins/sudoers/defaults.c:270
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d ingen værdi angivet for »%s«"
+
+#: plugins/sudoers/defaults.c:273
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: ingen værdi angivet for »%s«"
+
+#: plugins/sudoers/defaults.c:293
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d værdier for »%s« skal begynde med en »/«"
+
+#: plugins/sudoers/defaults.c:296
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: værdier for »%s« skal begynde med en »/«"
+
+#: plugins/sudoers/defaults.c:318
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d indstillingen »%s« kan ikke modtage en værdi"
+
+#: plugins/sudoers/defaults.c:321
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: indstillingen »%s« kan ikke modtage en værdi"
+
+#: plugins/sudoers/defaults.c:346
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d ugyldig standardtype 0x%x for tilvalget »%s«"
+
+#: plugins/sudoers/defaults.c:349
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: ugyldig standardtype 0x%x for tilvalget »%s«"
+
+#: plugins/sudoers/defaults.c:359
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d værdien »%s« er ugyldig for tilvalget »%s«"
+
+#: plugins/sudoers/defaults.c:362
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: værdien »%s« er ugyldig for tilvalget »%s«"
+
+#: plugins/sudoers/env.c:376
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: ødelagt envp, forskellig længde"
+
+#: plugins/sudoers/env.c:1055
+msgid "unable to rebuild the environment"
+msgstr "kan ikke genopbygge miljøet"
+
+#: plugins/sudoers/env.c:1129
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "beklager, du har ikke tilladelse til at angive de følgende miljøvariabler: %s"
+
+#: plugins/sudoers/file.c:111
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "fortolkningsfejl i %s nær linje %d"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s"
+msgstr "fortolkningsfejl i %s"
+
+#: plugins/sudoers/filedigest.c:56
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "ej understøttet sammendragstype %d for %s"
+
+#: plugins/sudoers/filedigest.c:85
+#, c-format
+msgid "%s: read error"
+msgstr "%s: læsefejl"
+
+#: plugins/sudoers/group_plugin.c:83
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s skal være ejet af uid %d"
+
+#: plugins/sudoers/group_plugin.c:87
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s skal være skrivbar af ejer"
+
+#: plugins/sudoers/group_plugin.c:95 plugins/sudoers/sssd.c:550
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "kan ikke indlæse %s: %s"
+
+#: plugins/sudoers/group_plugin.c:101
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "kan ikke finde symbol »group_plugin« i %s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: inkompatibel gruppeudvidelsesmodul for hovedversion %d, forventede %d"
+
+#: plugins/sudoers/interfaces.c:79 plugins/sudoers/interfaces.c:96
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "kan ikke fortolke IP-adressen »%s«"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "kan ikke fortolke netmasken »%s«"
+
+#: plugins/sudoers/interfaces.c:129
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Lokal IP-adresse og netmaskepar:\n"
+
+#: plugins/sudoers/iolog.c:119 plugins/sudoers/mkdir_parents.c:75
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s findes men er ikke en mappe (0%o)"
+
+#: plugins/sudoers/iolog.c:144 plugins/sudoers/iolog.c:184
+#: plugins/sudoers/mkdir_parents.c:64 plugins/sudoers/timestamp.c:174
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "kan ikke mkdir %s"
+
+#: plugins/sudoers/iolog.c:188 plugins/sudoers/visudo.c:718
+#: plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "kan ikke ændre tilstand på %s til 0%o"
+
+#: plugins/sudoers/iolog.c:296 plugins/sudoers/sudoers.c:1162
+#: plugins/sudoers/testsudoers.c:390
+#, c-format
+msgid "unknown group: %s"
+msgstr "ukendt gruppe: %s"
+
+#: plugins/sudoers/iolog.c:466 plugins/sudoers/sudoers.c:902
+#: plugins/sudoers/sudoreplay.c:868 plugins/sudoers/sudoreplay.c:1681
+#: plugins/sudoers/tsdump.c:140
+#, c-format
+msgid "unable to read %s"
+msgstr "kan ikke læse %s"
+
+#: plugins/sudoers/iolog.c:581 plugins/sudoers/iolog.c:800
+#, c-format
+msgid "unable to create %s"
+msgstr "kan ikke oprette %s"
+
+#: plugins/sudoers/iolog.c:1032 plugins/sudoers/iolog.c:1107
+#: plugins/sudoers/iolog.c:1188
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "kan ikke skrive til I/O-logfilen: %s"
+
+#: plugins/sudoers/iolog.c:1066
+#, c-format
+msgid "%s: internal error, file index %d not open"
+msgstr "%s: intern fejl, filindekset %d er ikke åbent"
+
+#: plugins/sudoers/ldap.c:170 plugins/sudoers/ldap_conf.c:287
+msgid "starttls not supported when using ldaps"
+msgstr "starttls er ikke understøttet, når der bruges ldaps"
+
+#: plugins/sudoers/ldap.c:241
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "kan ikke initialisere SSL-cert og key db: %s"
+
+#: plugins/sudoers/ldap.c:244
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "du skal angive at TLS_CERT i %s skal bruge SSL"
+
+#: plugins/sudoers/ldap.c:1606
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "kan ikke initialisere LDAP: %s"
+
+#: plugins/sudoers/ldap.c:1642
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls angivet men LDAP libs understøtter ikke ldap_start_tls_s() eller ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap_conf.c:196
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: port for stor"
+
+#: plugins/sudoers/ldap_conf.c:256
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "ikkeunderstøttet LDAP uri-type: %s"
+
+#: plugins/sudoers/ldap_conf.c:283
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "kan ikke blande ldap og ldaps URI'er"
+
+#: plugins/sudoers/ldap_util.c:470 plugins/sudoers/ldap_util.c:472
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "kan ikke konvertere sudoOption: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:52
+msgid "unable to open audit system"
+msgstr "kan ikke åbne overvågningssystem"
+
+#: plugins/sudoers/linux_audit.c:93
+msgid "unable to send audit message"
+msgstr "kan ikke sende overvågningsbesked"
+
+#: plugins/sudoers/logging.c:108
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:136
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s: (kommando fortsat) %s"
+
+#: plugins/sudoers/logging.c:165
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "kan ikke åbne logfilen: %s"
+
+#: plugins/sudoers/logging.c:173
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "kan ikke låse logfilen: %s"
+
+#: plugins/sudoers/logging.c:206
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "kan ikke skrive til logfilen: %s"
+
+#: plugins/sudoers/logging.c:235
+msgid "No user or host"
+msgstr "Ingen bruger eller vært"
+
+#: plugins/sudoers/logging.c:237
+msgid "validation failure"
+msgstr "valideringsfejl"
+
+#: plugins/sudoers/logging.c:244
+msgid "user NOT in sudoers"
+msgstr "bruger IKKE i sudoers"
+
+#: plugins/sudoers/logging.c:246
+msgid "user NOT authorized on host"
+msgstr "bruger IKKE autoriseret på vært"
+
+#: plugins/sudoers/logging.c:248
+msgid "command not allowed"
+msgstr "kommando ikke tilladt"
+
+#: plugins/sudoers/logging.c:283
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s er ikke sudoersfilen. Denne handling vil blive rapporteret.\n"
+
+#: plugins/sudoers/logging.c:286
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s har ikke tilladelse til at køre sudo på %s. Denne handling vil blive rapporteret.\n"
+
+#: plugins/sudoers/logging.c:290
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Beklager. Bruger %s må ikke køre sudo på %s.\n"
+
+#: plugins/sudoers/logging.c:293
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Beklager. Bruger %s har ikke tilladelse til at køre »%s%s%s« som %s%s%s på %s.\n"
+
+#: plugins/sudoers/logging.c:330 plugins/sudoers/sudoers.c:433
+#: plugins/sudoers/sudoers.c:435 plugins/sudoers/sudoers.c:437
+#: plugins/sudoers/sudoers.c:439 plugins/sudoers/sudoers.c:594
+#: plugins/sudoers/sudoers.c:596
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: Kommando ikke fundet"
+
+#: plugins/sudoers/logging.c:332 plugins/sudoers/sudoers.c:429
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"ignorerer »%s« fundet i ».«\n"
+"Brug »sudo ./%s«, hvis dette er den »%s«, du ønsker at køre."
+
+#: plugins/sudoers/logging.c:349
+msgid "authentication failure"
+msgstr "godkendelsesfejl"
+
+#: plugins/sudoers/logging.c:375
+msgid "a password is required"
+msgstr "der kræves en adgangskode"
+
+#: plugins/sudoers/logging.c:438
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u ukorrekt adgangskodeforsøg"
+msgstr[1] "%u ukorrekte adgangskodeforsøg"
+
+#: plugins/sudoers/logging.c:659
+msgid "unable to fork"
+msgstr "kan ikke forgrene"
+
+#: plugins/sudoers/logging.c:667 plugins/sudoers/logging.c:719
+#, c-format
+msgid "unable to fork: %m"
+msgstr "kan ikke forgrene: %m"
+
+#: plugins/sudoers/logging.c:709
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "kan ikke åbne datakanal: %m"
+
+#: plugins/sudoers/logging.c:734
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "kan ikke dup stdin: %m"
+
+#: plugins/sudoers/logging.c:772
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "kan ikke køre %s: %m"
+
+#: plugins/sudoers/match.c:842
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "sammendrag for %s (%s) er ikke i %s-form"
+
+#: plugins/sudoers/mkdir_parents.c:70 plugins/sudoers/sudoers.c:913
+#: plugins/sudoers/visudo.c:416 plugins/sudoers/visudo.c:712
+#, c-format
+msgid "unable to stat %s"
+msgstr "kan ikke stat %s"
+
+#: plugins/sudoers/parse.c:434
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"LDAP-rolle: %s\n"
+
+#: plugins/sudoers/parse.c:437
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Sudoers-punkt:\n"
+
+#: plugins/sudoers/parse.c:439
+#, c-format
+msgid " RunAsUsers: "
+msgstr " KørSomBrugere: "
+
+#: plugins/sudoers/parse.c:454
+#, c-format
+msgid " RunAsGroups: "
+msgstr " KørSomGrupper: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " Options: "
+msgstr " Tilvalg: "
+
+#: plugins/sudoers/parse.c:518
+#, c-format
+msgid " Commands:\n"
+msgstr " Kommandoer:\n"
+
+#: plugins/sudoers/parse.c:709
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Matchende standardpunkter for %s på %s:\n"
+
+#: plugins/sudoers/parse.c:727
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Kør som og kommandospecifikke standarder for %s:\n"
+
+#: plugins/sudoers/parse.c:745
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Bruger %s må køre de følgende kommandoer på %s:\n"
+
+#: plugins/sudoers/parse.c:760
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Bruger %s har ikke tilladelse til at køre sudo på %s.\n"
+
+#: plugins/sudoers/policy.c:83 plugins/sudoers/policy.c:109
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "ugyldig %.*s angivet af sudo-brugerfladen"
+
+#: plugins/sudoers/policy.c:288 plugins/sudoers/testsudoers.c:259
+msgid "unable to parse network address list"
+msgstr "kan ikke fortolke netværksadresseliste"
+
+#: plugins/sudoers/policy.c:432
+msgid "user name not set by sudo front-end"
+msgstr "brugernavn er ikke angivet af sudo-brugerfladen"
+
+#: plugins/sudoers/policy.c:436
+msgid "user ID not set by sudo front-end"
+msgstr "bruger-id er ikke angivet af sudo-brugerfladen"
+
+#: plugins/sudoers/policy.c:440
+msgid "group ID not set by sudo front-end"
+msgstr "gruppe-id er ikke angivet af sudo-brugerfladen"
+
+#: plugins/sudoers/policy.c:444
+msgid "host name not set by sudo front-end"
+msgstr "værtsnavn er ikke angivet af sudo-brugerfladen"
+
+#: plugins/sudoers/policy.c:797 plugins/sudoers/visudo.c:215
+#: plugins/sudoers/visudo.c:845
+#, c-format
+msgid "unable to execute %s"
+msgstr "kan ikke udføre %s"
+
+#: plugins/sudoers/policy.c:930
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Udvidelsesmodulversion %s for sudoerspolitik\n"
+
+#: plugins/sudoers/policy.c:932
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Grammatikversion %d for sudoersfil\n"
+
+#: plugins/sudoers/policy.c:936
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Sudoers-sti: %s\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "nsswitch-sti: %s\n"
+
+#: plugins/sudoers/policy.c:941
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "ldap.conf-sti: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "ldap.secret-sti: %s\n"
+
+# lidt i tvivl om hvad hook er her, så har beholdt den uoversat
+# Er OK. Er enig med hensyn til hook, skal nok forstås som
+# fastgøringspunkt, men lyder for bøvlet
+#: plugins/sudoers/policy.c:975
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "kan ikke registrere »hook« af typen %d (version %d.%d)"
+
+#: plugins/sudoers/pwutil.c:214 plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "kan ikke cache uid %u, ikke nok hukommelse"
+
+#: plugins/sudoers/pwutil.c:227
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "kan ikke cache uid %u, findes allerede"
+
+#: plugins/sudoers/pwutil.c:287 plugins/sudoers/pwutil.c:305
+#: plugins/sudoers/pwutil.c:367 plugins/sudoers/pwutil.c:412
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "kan ikke cache bruger %s, ikke nok hukommelse"
+
+#: plugins/sudoers/pwutil.c:300
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "kan ikke cache bruger %s, findes allerede"
+
+#: plugins/sudoers/pwutil.c:531 plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "kan ikke cache gid %u, ikke nok hukommelse"
+
+#: plugins/sudoers/pwutil.c:544
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "kan ikke cache gid %u, findes allerede"
+
+#: plugins/sudoers/pwutil.c:598 plugins/sudoers/pwutil.c:616
+#: plugins/sudoers/pwutil.c:663 plugins/sudoers/pwutil.c:705
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "kan ikke cache gruppe %s, ikke nok hukommelse"
+
+#: plugins/sudoers/pwutil.c:611
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "kan ikke cache gruppe %s, findes allerede"
+
+#: plugins/sudoers/pwutil.c:831 plugins/sudoers/pwutil.c:883
+#: plugins/sudoers/pwutil.c:934 plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "kan ikke cache gruppeliste for %s, findes allerede"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:888
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:992
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "kan ikke cache gruppeliste for %s, ikke nok hukommelse"
+
+#: plugins/sudoers/pwutil.c:877
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "kan ikke fortolke grupper for %s"
+
+#: plugins/sudoers/pwutil.c:981
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "kan ikke fortolke gid'er for %s"
+
+#: plugins/sudoers/set_perms.c:113 plugins/sudoers/set_perms.c:469
+#: plugins/sudoers/set_perms.c:912 plugins/sudoers/set_perms.c:1239
+#: plugins/sudoers/set_perms.c:1556
+msgid "perm stack overflow"
+msgstr "permanent stakoverløb"
+
+#: plugins/sudoers/set_perms.c:121 plugins/sudoers/set_perms.c:400
+#: plugins/sudoers/set_perms.c:477 plugins/sudoers/set_perms.c:779
+#: plugins/sudoers/set_perms.c:920 plugins/sudoers/set_perms.c:1163
+#: plugins/sudoers/set_perms.c:1247 plugins/sudoers/set_perms.c:1489
+#: plugins/sudoers/set_perms.c:1564 plugins/sudoers/set_perms.c:1654
+msgid "perm stack underflow"
+msgstr "permanent stakunderløb"
+
+#: plugins/sudoers/set_perms.c:180 plugins/sudoers/set_perms.c:523
+#: plugins/sudoers/set_perms.c:1298 plugins/sudoers/set_perms.c:1596
+msgid "unable to change to root gid"
+msgstr "kan ikke ændre til root gid"
+
+#: plugins/sudoers/set_perms.c:269 plugins/sudoers/set_perms.c:620
+#: plugins/sudoers/set_perms.c:1049 plugins/sudoers/set_perms.c:1375
+msgid "unable to change to runas gid"
+msgstr "kan ikke ændre til kør som gid"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to set runas group vector"
+msgstr "kan ikke angive kør som gruppevektor"
+
+#: plugins/sudoers/set_perms.c:285 plugins/sudoers/set_perms.c:636
+#: plugins/sudoers/set_perms.c:1063 plugins/sudoers/set_perms.c:1389
+msgid "unable to change to runas uid"
+msgstr "kan ikke ændre til kør som uid"
+
+#: plugins/sudoers/set_perms.c:303 plugins/sudoers/set_perms.c:654
+#: plugins/sudoers/set_perms.c:1079 plugins/sudoers/set_perms.c:1405
+msgid "unable to change to sudoers gid"
+msgstr "kan ikke ændre til sudoers gid"
+
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1476
+#: plugins/sudoers/set_perms.c:1641
+msgid "too many processes"
+msgstr "for mange processer"
+
+#: plugins/sudoers/solaris_audit.c:51
+msgid "unable to get current working directory"
+msgstr "kan ikke hente nuværende arbejdsmappe"
+
+#: plugins/sudoers/solaris_audit.c:59
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "afkortet revisionssti user_cmnd: %s"
+
+#: plugins/sudoers/solaris_audit.c:66
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "afkortet revisionssti argv[0]: %s"
+
+#: plugins/sudoers/solaris_audit.c:115
+msgid "audit_failure message too long"
+msgstr "audit_failure-besked er for lang"
+
+#: plugins/sudoers/sssd.c:552
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "kan ikke initialisere SSS-kilde. Er SSSD installeret på din maskine?"
+
+#: plugins/sudoers/sssd.c:560 plugins/sudoers/sssd.c:569
+#: plugins/sudoers/sssd.c:578 plugins/sudoers/sssd.c:587
+#: plugins/sudoers/sssd.c:596
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "kan ikke finde symbol »%s« i %s"
+
+#: plugins/sudoers/sudoers.c:204 plugins/sudoers/sudoers.c:859
+msgid "problem with defaults entries"
+msgstr "problem med standardpunkter"
+
+#: plugins/sudoers/sudoers.c:208
+msgid "no valid sudoers sources found, quitting"
+msgstr "ingen gyldige sudoerskilder fundet, afslutter"
+
+#: plugins/sudoers/sudoers.c:246
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers angiver at administrator (root) ikke har tilladelse til sudo"
+
+#: plugins/sudoers/sudoers.c:303
+msgid "you are not permitted to use the -C option"
+msgstr "du har ikke tilladelse til at bruge tilvalget -C"
+
+#: plugins/sudoers/sudoers.c:350
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "tidsstempelejer (%s): Ingen sådan bruger"
+
+#: plugins/sudoers/sudoers.c:365
+msgid "no tty"
+msgstr "ingen tty"
+
+#: plugins/sudoers/sudoers.c:366
+msgid "sorry, you must have a tty to run sudo"
+msgstr "beklager, du skal bruge en tty for at køre sudo"
+
+#: plugins/sudoers/sudoers.c:428
+msgid "command in current directory"
+msgstr "kommando i aktuel mappe"
+
+#: plugins/sudoers/sudoers.c:447
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "beklager, men du har ikke tilladelse til at angive tidsudløb for kommando"
+
+#: plugins/sudoers/sudoers.c:455
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "beklager, men du har ikke tilladelse til at bevare miljøet"
+
+#: plugins/sudoers/sudoers.c:803
+msgid "command too long"
+msgstr "kommando er for lang"
+
+#: plugins/sudoers/sudoers.c:917
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s er ikke en regulær fil"
+
+#: plugins/sudoers/sudoers.c:921 plugins/sudoers/timestamp.c:221 toke.l:968
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s er ejet af uid %u, bør være %u"
+
+#: plugins/sudoers/sudoers.c:925 toke.l:973
+#, c-format
+msgid "%s is world writable"
+msgstr "%s er skrivbar for alle"
+
+#: plugins/sudoers/sudoers.c:929 toke.l:976
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s er eget af gid %u, bør være %u"
+
+#: plugins/sudoers/sudoers.c:962
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "kun administrator (root) kan bruge »-c %s«"
+
+#: plugins/sudoers/sudoers.c:981
+#, c-format
+msgid "unknown login class: %s"
+msgstr "ukendt logindklasse: %s"
+
+#: plugins/sudoers/sudoers.c:1064 plugins/sudoers/sudoers.c:1078
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "kan ikke slå vært %s op"
+
+#: plugins/sudoers/sudoreplay.c:274
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "ugyldigt filtertilvalg: %s"
+
+#: plugins/sudoers/sudoreplay.c:287
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "ugyldig maks ventetid: %s"
+
+#: plugins/sudoers/sudoreplay.c:307
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "ugyldig hastighedsfaktor: %s"
+
+#: plugins/sudoers/sudoreplay.c:342
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/timing: %s"
+
+#: plugins/sudoers/sudoreplay.c:348
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/timing: %s"
+
+#: plugins/sudoers/sudoreplay.c:364
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Genafspiller sudosession: %s"
+
+#: plugins/sudoers/sudoreplay.c:562 plugins/sudoers/sudoreplay.c:609
+#: plugins/sudoers/sudoreplay.c:816 plugins/sudoers/sudoreplay.c:906
+#: plugins/sudoers/sudoreplay.c:985 plugins/sudoers/sudoreplay.c:1000
+#: plugins/sudoers/sudoreplay.c:1007 plugins/sudoers/sudoreplay.c:1014
+#: plugins/sudoers/sudoreplay.c:1021 plugins/sudoers/sudoreplay.c:1028
+#: plugins/sudoers/sudoreplay.c:1174
+msgid "unable to add event to queue"
+msgstr "kan ikke tilføje hændelse til køen"
+
+#: plugins/sudoers/sudoreplay.c:677
+msgid "unable to set tty to raw mode"
+msgstr "kan ikke angive tty til rå (raw) tilstand"
+
+#: plugins/sudoers/sudoreplay.c:728
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Advarsel: Din terminal er for lille til korrekt at afspille loggen.\n"
+
+#: plugins/sudoers/sudoreplay.c:729
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Loggeometri er %d x %d, din terminals geometri er %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:757
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Genafspilning er afsluttet. Tryk på en tast for at gendanne terminalen."
+
+#: plugins/sudoers/sudoreplay.c:790
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "ugyldig timingfillinje: %s"
+
+#: plugins/sudoers/sudoreplay.c:1208 plugins/sudoers/sudoreplay.c:1233
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "tvetydigt udtryk »%s«"
+
+#: plugins/sudoers/sudoreplay.c:1255
+msgid "unmatched ')' in expression"
+msgstr "manglende »)« i udtryk"
+
+#: plugins/sudoers/sudoreplay.c:1259
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "ukendt søgeterm »%s«"
+
+#: plugins/sudoers/sudoreplay.c:1274
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s kræver et argument"
+
+#: plugins/sudoers/sudoreplay.c:1277 plugins/sudoers/sudoreplay.c:1657
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "ugyldigt regulært udtryk: %s"
+
+#: plugins/sudoers/sudoreplay.c:1281
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "kunne ikke fortolke dato »%s«"
+
+#: plugins/sudoers/sudoreplay.c:1290
+msgid "unmatched '(' in expression"
+msgstr "mangler »(« i udtryk"
+
+#: plugins/sudoers/sudoreplay.c:1292
+msgid "illegal trailing \"or\""
+msgstr "ugyldig kæde »or« (eller)"
+
+#: plugins/sudoers/sudoreplay.c:1294
+msgid "illegal trailing \"!\""
+msgstr "ugyldig kæde »!«"
+
+#: plugins/sudoers/sudoreplay.c:1343
+#, c-format
+msgid "unknown search type %d"
+msgstr "ukendt søgeterm %d"
+
+#: plugins/sudoers/sudoreplay.c:1381
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: Ugyldig logfil"
+
+#: plugins/sudoers/sudoreplay.c:1399
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: Tidsstempelfelt mangler"
+
+#: plugins/sudoers/sudoreplay.c:1406
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: Tidsstempel %s: %s"
+
+#: plugins/sudoers/sudoreplay.c:1413
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: Brugerfelt mangler"
+
+#: plugins/sudoers/sudoreplay.c:1422
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: runas-brugerfelt mangler"
+
+#: plugins/sudoers/sudoreplay.c:1431
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: runas-gruppefelt mangler"
+
+#: plugins/sudoers/sudoreplay.c:1837
+#, c-format
+msgid "usage: %s [-hnR] [-d dir] [-m num] [-s num] ID\n"
+msgstr "brug: %s [-hnR] [-d mappe] [-m num] [-s num] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1840
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "brug: %s [-h] [-d mappe] -l [søgeudtryk]\n"
+
+#: plugins/sudoers/sudoreplay.c:1849
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - genafspil sudosessionslogge\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1851
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Tilvalg:\n"
+" -d, --directory=dir angiv mappe for sessionslogge\n"
+" -f, --filter=filter angiv hvilken I/O-type at vise\n"
+" -h, --help vis denne hjælpetekst og afslut\n"
+" -l, --list vis tilgængelige sessions-ID'er med valgfrit udtryk\n"
+" -m, --max-wait=num maks antal sekunder at vente mellem hændelser\n"
+" -s, --speed=num øg eller sænk uddata\n"
+" -V, --version vis versionsinformation og afslut"
+
+#: plugins/sudoers/testsudoers.c:328
+msgid "\thost unmatched"
+msgstr "\thost matchede ikke"
+
+#: plugins/sudoers/testsudoers.c:331
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Kommando tilladt"
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Kommando nægtet"
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Kommando ikke matchet"
+
+#: plugins/sudoers/timestamp.c:229
+#, c-format
+msgid "%s is group writable"
+msgstr "%s er gruppe-skrivbar"
+
+#: plugins/sudoers/timestamp.c:305
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "kan ikke afkorte tidsstempelfil til %lld byte"
+
+#: plugins/sudoers/timestamp.c:792 plugins/sudoers/timestamp.c:884
+#: plugins/sudoers/visudo.c:477 plugins/sudoers/visudo.c:483
+msgid "unable to read the clock"
+msgstr "kan ikke læse uret"
+
+#: plugins/sudoers/timestamp.c:803
+msgid "ignoring time stamp from the future"
+msgstr "ignorerer tidsstempel fra fremtiden"
+
+#: plugins/sudoers/timestamp.c:826
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "tidsstempel for langt ude i fremtiden: %20.20s"
+
+#: plugins/sudoers/timestamp.c:948
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "kan ikke låse tidsstempelfilen %s"
+
+#: plugins/sudoers/timestamp.c:992 plugins/sudoers/timestamp.c:1012
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "undervisningsstatussti er for lang: %s/%s"
+
+#: plugins/sudoers/visudo.c:211
+msgid "the -x option will be removed in a future release"
+msgstr "tilvalget -x vil blive fjernet i fremtidige udgivelser"
+
+#: plugins/sudoers/visudo.c:212
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "overvej i stedet for at bruge redskabet cvtsudoers"
+
+#: plugins/sudoers/visudo.c:263 plugins/sudoers/visudo.c:645
+#, c-format
+msgid "press return to edit %s: "
+msgstr "tryk retur for at redigere %s: "
+
+#: plugins/sudoers/visudo.c:324
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "angivet redigeringsprogram (%s) findes ikke"
+
+#: plugins/sudoers/visudo.c:326
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "intet redigeringsprogram fundet (sti for redigeringsprogram = %s)"
+
+#: plugins/sudoers/visudo.c:436 plugins/sudoers/visudo.c:444
+msgid "write error"
+msgstr "skrivefejl"
+
+#: plugins/sudoers/visudo.c:490
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "kan ikke stat midlertidig fil (%s), %s unchanged"
+
+#: plugins/sudoers/visudo.c:497
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "midlertidig fil med nullængde (%s), %s uændret"
+
+#: plugins/sudoers/visudo.c:503
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "redigeringsprogram (%s) fejlede, %s uændret"
+
+#: plugins/sudoers/visudo.c:525
+#, c-format
+msgid "%s unchanged"
+msgstr "%s uændret"
+
+#: plugins/sudoers/visudo.c:584
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "kan ikke genåbne midlertidig fil (%s), %s uændrede."
+
+#: plugins/sudoers/visudo.c:596
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "kan ikke fortolke midlertidig fil (%s), ukendt fejl"
+
+#: plugins/sudoers/visudo.c:634
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "intern fejl, kan ikke finde %s på listen!"
+
+#: plugins/sudoers/visudo.c:714 plugins/sudoers/visudo.c:723
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "kan ikke angive (uid, gid) af %s til (%u, %u)"
+
+#: plugins/sudoers/visudo.c:745
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s og %s er ikke på det samme filsystem, bruger mv til at omdøbe"
+
+#: plugins/sudoers/visudo.c:759
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "kommando fejlede: »%s %s %s«, %s uændret"
+
+#: plugins/sudoers/visudo.c:769
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "fejl under omdøbing af %s, %s uændret"
+
+#: plugins/sudoers/visudo.c:790
+msgid "What now? "
+msgstr "Hvad nu? "
+
+#: plugins/sudoers/visudo.c:804
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Tilvalg er:\n"
+" r(e)diger sudoersfil igen\n"
+" afslut(x) uden at gemme ændringer til sudoersfil\n"
+" afslut(Q) og gem ændringer til sudoersfil (FARLIGT!)\n"
+
+#: plugins/sudoers/visudo.c:850
+#, c-format
+msgid "unable to run %s"
+msgstr "kan ikke køre %s"
+
+#: plugins/sudoers/visudo.c:880
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: forkert ejer (uid, gid) bør være (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:887
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: ugyldige rettigheder, bør være tilstand 0%o\n"
+
+#: plugins/sudoers/visudo.c:944 plugins/sudoers/visudo.c:951
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: fortolket o.k.\n"
+
+#: plugins/sudoers/visudo.c:998
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s travl, forsøg igen senere"
+
+#: plugins/sudoers/visudo.c:1038
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Fejl: %s:%d: cyklus i %s »%s«"
+
+#: plugins/sudoers/visudo.c:1039
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Advarsel: %s:%d: cyklus i %s »%s«"
+
+#: plugins/sudoers/visudo.c:1043
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Fejl: %s:%d %s »%s« refereret men ikke defineret"
+
+#: plugins/sudoers/visudo.c:1044
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Advarsel: %s:%d %s »%s« refereret men ikke defineret"
+
+# (ental)
+#: plugins/sudoers/visudo.c:1137
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Advarsel: %s:%d ubrugt %s »%s«"
+
+#: plugins/sudoers/visudo.c:1252
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - rediger sikkert sudoersfilen\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1254
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"Tilvalg:\n"
+" -c, --check kun kontroltilstand\n"
+" -f, --file=file angiv filplacering for sudoers\n"
+" -h, --help vis denne hjælpetekst og afslut\n"
+" -q, --quiet mindre uddybende (stille) beskeder for syntaksfejl\n"
+" -s, --strict streng syntakskontrol\n"
+" -V, --version vis information om version og afslut\n"
+
+#: toke.l:942
+msgid "too many levels of includes"
+msgstr "for mange niveauer af includes (inkluderinger)"
diff --git a/plugins/sudoers/po/de.mo b/plugins/sudoers/po/de.mo
new file mode 100644
index 0000000..ae6278d
--- /dev/null
+++ b/plugins/sudoers/po/de.mo
Binary files differ
diff --git a/plugins/sudoers/po/de.po b/plugins/sudoers/po/de.po
new file mode 100644
index 0000000..67b23ea
--- /dev/null
+++ b/plugins/sudoers/po/de.po
@@ -0,0 +1,2357 @@
+# Portable object template file for the sudoers plugin
+# This file is put in the public domain.
+# Todd C. Miller <Todd.Miller@courtesan.com>, 2011-2013
+# Hendrik Knackstedt <hendrik.knackstedt@t-online.de>, 2013
+# Mario Blättermann <mario.blaettermann@gmail.com>, 2015.
+# Jochen Hein <jochen@jochen.org>, 2001-2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-11-02 22:41+0100\n"
+"Last-Translator: Jochen Hein <jochen@jochen.org>\n"
+"Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
+"Language: German\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "Syntax-Fehler"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "%p's Passwort: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] Passwort für %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Passwort: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** Sicherheits-Information für %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Das hat nicht funktioniert, bitte nochmal probieren."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336
+#: gram.y:399 gram.y:407 gram.y:417 gram.y:450 gram.y:457 gram.y:464
+#: gram.y:471 gram.y:553 gram.y:560 gram.y:569 gram.y:578 gram.y:595
+#: gram.y:707 gram.y:714 gram.y:721 gram.y:729 gram.y:829 gram.y:836
+#: gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890 gram.y:897
+#: gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:195 plugins/sudoers/logging.c:511
+#: plugins/sudoers/logging.c:532 plugins/sudoers/logging.c:573
+#: plugins/sudoers/logging.c:752 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr "Es kann kein Speicher mehr alloziert werden"
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr "Eine Prüfsumme erfordert einen Pfadnamen"
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr "ungültiger Wert für »notbefore«"
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr "ungültiger Wert für »notafter«"
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr "Wert für Timeout ist zu groß"
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr "ungültiger Wert für Timeout"
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:354 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:511 plugins/sudoers/logging.c:532
+#: plugins/sudoers/logging.c:572 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:724 plugins/sudoers/match.c:771
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1008
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Alias »%s« ist bereits definiert"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "Die Anmeldeklasse des Benutzers »%s« kann nicht gelesen werden"
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr "Die BSD-Authentifizierung kann nicht begonnen werden"
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr "Ungültiger Authentifizierungstyp"
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr "Die BSD-Authentifizierung kann nicht begonnen werden"
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr "Ihr Account ist abgelaufen"
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr "Genehmigung fehlgeschlagen"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr "Die fwtk-Konfiguration kann nicht gelesen werden"
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr "Verbindung zum Authentifizierungsserver kann nicht aufgebaut werden"
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr "Verbindung zum Authentisierungsserver verloren"
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"Fehler des Authentifizierungsservers:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: Principal kann nicht in eine Zeichenkette umgewandelt werden (»%s«): %s"
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: »%s« kann nicht ausgewertet werden: %s"
+
+# XXX check source?
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: Anmeldedaten-Zwischenspeicher kann nicht aufgelöst werden: %s"
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: Optionen können nicht zugewiesen werden: %s"
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: Anmeldedaten können nicht bekommen werden: %s"
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: Anmeldedaten-Zwischenspeicher kann nicht initialisiert werden: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: Anmeldedaten können nicht im Zwischenspeicher abgelegt werden: %s"
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: Rechner-Principal kann nicht bekommen werden: %s"
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: TGT kann nicht verifiziert werden! Möglicher Angriff!: %s"
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr "PAM kann nicht initialisiert werden"
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Fehler bei der PAM-Authentifizierung: %s"
+
+#: plugins/sudoers/auth/pam.c:221
+msgid "account validation failure, is your account locked?"
+msgstr "Fehler bei der Validierung des Kontos, ist das Konto gesperrt?"
+
+#: plugins/sudoers/auth/pam.c:229
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Konto oder Passwort ist abgelaufen, bitte Passwort zurücksetzen und nochmal probieren"
+
+#: plugins/sudoers/auth/pam.c:238
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "Das abgelaufene Passwort kann nicht geändert werden: %s«"
+
+#: plugins/sudoers/auth/pam.c:246
+msgid "Password expired, contact your system administrator"
+msgstr "Das Passwort ist abgelaufen, bitte wenden Sie sich an den Systemadministrator"
+
+#: plugins/sudoers/auth/pam.c:250
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Das Konto ist abgelaufen oder in der PAM-Konfiguration fehlt der »account«-Abschnitt für sudo. Bitte wenden Sie sich an den Systemadministrator"
+
+#: plugins/sudoers/auth/pam.c:257 plugins/sudoers/auth/pam.c:262
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "Fehler beim PAM-Account-Management: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:232
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "Der Benutzer existiert in der %s-Datenbank nicht"
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr "Die ACE-API-Bibliothek konnte nicht initialisiert werden"
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr "SecurID-Server kann nicht erreicht werden"
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr "Benutzer-ID ist für SecurID-Authentifizierung gesperrt"
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr "Ungültige Länge des Benutzernamens für SecurID"
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr "Ungültiges Authentifizierungs-Handle für SecurID"
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr "SecurID-Kommunikation fehlgeschlagen"
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr "Unbekannter SecurID-Fehler"
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr "Ungültige Länge des Passcodes für SecurID"
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr "Die SIA-Sitzung kann nicht initialisiert werden"
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr "Ungültige Authentifizierungsmethoden"
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Ungültige Authentifizierungsmethoden sind in sudo einkompiliert! Standalone- und Nicht-Standalone-Authentifizierung können nicht zusammen verwendet werden."
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr "Keine Authentifizierungsmethoden"
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Es sind keine Authentifizierungsmethoden in sudo einkompiliert! Wenn Sie die Authentifizierung wirklich abschalten wollen, verwenden Sie bitte die configure-Option »--disable-authentication«."
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr "Die Authentifizierungsmethoden können nicht initialisiert werden."
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr "Authentifizierungsmethoden:"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr "Der Audit-Zustand kann nicht bestimmt werden"
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr "Audit-Satz kann nicht auf Platte geschrieben werden"
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Wir gehen davon aus, dass der lokale Systemadministrator Ihnen die\n"
+"Regeln erklärt hat. Normalerweise läuft es auf drei Regeln hinaus:\n"
+"\n"
+" #1) Respektieren Sie die Privatsphäre anderer.\n"
+" #2) Denken Sie nach, bevor Sie tippen.\n"
+" #3) Mit großer Macht kommt große Verantwortung.\n"
+"\n"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr "Unbekannte Benutzer-ID: %u"
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1136
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr "Unbekannter Benutzer: %s"
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "Schrittgröße: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "Start der Folge: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr "Auffüllen der Folge: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s Version %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s-Grammatik Version %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr "Nicht unterstütztes Eingabeformat %s"
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr "Nicht unterstütztes Ausgabeformat %s"
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: Eingabe- und Ausgabedatei müssen unterschiedlich sein"
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:238
+#: plugins/sudoers/visudo.c:594 plugins/sudoers/visudo.c:917
+msgid "unable to initialize sudoers default values"
+msgstr "Standardwerte für sudoers können nicht initialisiert werden"
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: unbekanntes Schlüsselwort: %s"
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "Ungültiger Standardtyp: %s"
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "ungültiger suppression Typ: %s"
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr "Ungültiger Filter: %s"
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:913
+#, c-format
+msgid "unable to open %s"
+msgstr "Die Datei »%s« kann nicht geöffnet werden"
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:922
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "Analyse der Datei %s gescheitert, unbekannter Fehler"
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:939
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "Analysefehler in %s nahe Zeile %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:942
+#, c-format
+msgid "parse error in %s\n"
+msgstr "Analysefehler in %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr "In die Datei »%s« kann nicht geschrieben werden"
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s – zwischen sudoers Dateiformaten konvertieren\n"
+"\n"
+
+# XXX
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Optionen:\n"
+" -b, --base=dn Der Basis DN für sudo LDAP Abfragen\n"
+" -d, --defaults=deftypes Konvertiere nur Defaults von spezifischen Typen\n"
+" -e, --expand-aliases Expandiere Aliase beim Konvertieren\n"
+" -f, --output-format=format Ausgabeformat: JSON, LDIF oder sudoers\n"
+" -i, --input-format=format Eingabeformat: LDIF oder sudoers\n"
+" -I, --increment=num Größe der Schrittweite für sudoOrder\n"
+" -h, --help Zeige diese Hilfe an und Ende\n"
+" -m, --match=filter Konvertiere nur Einträge die zum Filter passen\n"
+" -M, --match-local Filter verwendet passwd und group Databank\n"
+" -o, --output=output_file Schreibe die konvertiere sudoers in die Ausgabe-Datei\n"
+" -P, --padding=num Auffüllen der sudoOrder Folge\n"
+" -O, --order-start=num Start für die erste sudoOrder\n"
+" -p, --prune-matches nicht passende Benutzer, Gruppen und Hosts nicht ausgeben\n"
+" -s, --suppress=sections Unterdrücke Ausgabe von bestimmten Abschnitten\n"
+" -V, --version Zeige Versionsinformationen an und Ende"
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "unbekannter defaults-Eintrag »%s«"
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr "Die GMT-Zeit kann nicht bekommen werden"
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr "Der Zeitstempel kann nicht formatiert werden"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1015 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "Interner Fehler, %s-Überlauf"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr "Zu viele sudoers Einträge, Maximum ist %u"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "Die Umgebunsvariable SUDOERS_BASE ist nicht gesetzt und die Option -b ist nicht angegeben."
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Syslog Facility, wenn syslog für Protokollierung verwendet wird: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Syslog-Priorität, wenn sich der Benutzer erfolgreich authentifiziert: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Syslog-Priorität, wenn sich der Benutzer nicht erfolgreich authentifiziert: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "Die OTP-Eingabeaufforderung (One-Time-Passwords) in eine eigene Zeile schreiben"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "».« in $PATH ignorieren"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "Immer eine Mail senden, wenn sudo gestartet wird"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "Eine Mail senden, wenn die Authentifizierung des Benutzers fehlschlägt"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "Eine Mail senden, wenn der Benutzer nicht in der sudoers-Datei steht"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Eine Mail senden, wenn der Benutzer nicht in der sudoers-Datei für diesen Rechner steht"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Eine Mail senden, wenn der Benutzer nicht berechtigt ist, einen Befehl auszuführen"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "Eine Mail senden, wenn der Benutzer versucht, einen Befehl auszuführen"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Getrennte Zeitstempel für jede Benutzer/tty-Kombination verwenden"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "Den Benutzer beim ersten Aufruf von sudo belehren"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Datei mit der sudo-Belehrung: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "Standardmäßig muss sich der Benutzer authentifizieren"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "Root darf sudo verwenden"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Den Hostnamen in der (nicht-syslog-)Protokolldatei speichern"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Das Jahr in der (nicht-syslog-)Protokolldatei speichern"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Eine Shell starten, wenn sudo ohne Parameter aufgerufen wird"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Die Umgebungsvariable $HOME beim Starten einer Shell mit »-s« setzen"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Immer die Variable $HOME auf das Home-Verzeichnis des Ziel-Benutzers setzen"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Informationssammlung für nützliche Fehlermeldungen erlauben"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Vollständige Hostnamen in der sudoers-Datei erfordern"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "»Beschimpfung« bei Eingabe eines falschen Passwortes"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Der Benutzer darf sudo nur aufrufen, wenn ein tty vorhanden ist"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo beachtet die Umgebungsvariable »EDITOR«"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "Nach dem root-Passwort fragen, nicht nach dem Passwort des Benutzers"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Nach dem Passwort des Benutzers »runas_default« fragen, nicht nach dem Passwort des aufrufenden Benutzers"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Nach dem Passwort des Ziel-Benutzers fragen, nicht nach dem Passwort des aufrufenden Benutzers"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Standards auf die Anmeldeklasse des Zielbenutzers anwenden, falls diese vorhanden ist"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Die Umgebungsvariablen »LOGNAME« und »USER« setzen"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Nur die effektive UID auf den Ziel-Benutzer setzen, nicht die reale UID"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Die sekundären Gruppen nicht auf die Gruppen des Ziel-Benutzers setzen"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Zeilenlänge der Protokolldatei für Zeilenumbruch (0 für keinen Zeilenumbruch): %u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Zeitlimit für den Authentifizierungszeitstempel: %.1f Minuten"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Zeitlimit bei der Eingabe des Passwortes: %.1f Minuten"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Anzahl Versuche zur Eingabe des Passwortes: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Zu verwendende Umask oder 0777, um die Umask des Benutzers zu verwenden: 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Pfad zur Protokolldatei: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Pfad zum Mail-Programm: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Parameter für das Mail-Programm: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Mail-Adresse des Empfängers: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Mail-Adresse des Absenders: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Betreffzeile für Mails: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Meldung bei Eingabe eines falschen Passwortes: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Verzeichnis für den Belehrungsstatus: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Pfad zum Authentifizierungszeitstempel-Verzeichnis: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Besitzer des Authentifizierungszeitstempelverzeichnisses: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Benutzer in dieser Gruppe sind von Passwort- und PATH-Anforderungen ausgenommen: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Standard-Eingabeaufforderung für das Passwort: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Überschreibt in allen Fällen bei der Passwortabfrage die Systemabfrage, falls gesetzt."
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Standardbenutzer, unter dem die Befehle ausgeführt werden: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Wert, mit dem der Inhalt von $PATH des Benutzers überschrieben werden soll: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Pfad zum Editor, den visudo verwenden soll: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Wann soll ein Passwort für den Pseudobefehl »list« erforderlich sein: %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Wann soll ein Passwort für den Pseudobefehl »verify« erforderlich sein: %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Die Dummy-exec-Funktion aus der Bibliothek sudo_noexec vorladen"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Wenn das LDAP-Verzeichnis erreichbar ist, wird die lokale sudoers-Datei ignoriert?"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Datei-Deskriptoren >= %d werden geschlossen, bevor ein Befehl ausgeführt wird"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Benutzer können den Wert für »closeform« mit der der Option -C überschreiben, wenn diese Option gesetzt ist."
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Benutzern das Setzen beliebiger Umgebungsvariablen erlauben"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "Die Umgebung auf einen Standardsatz an Variablen zurücksetzen"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "Folgende Umgebungsvariablen prüfen:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "Folgende Umgebungsvariablen löschen:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "Folgende Umgebungsvariablen bewahren:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Im neuen Security-Kontext von SELinux wird diese Rolle verwendet: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Im neuen Security-Kontext von SELinux wird dieser Typ verwendet: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Pfad zur sudo-spezifischen »environment«-Datei: %s"
+
+# XXX
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Pfad zur eingeschränkten sudo »environment«-Datei: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Beim Auswerten der sudoers-Datei wird diese Locale verwendet: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "sudo erlauben, nach einem Passwort zu fragen, auch wenn das Passwort sichtbar wird"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Sichtbare Rückmeldung bei der Passworteingabeaufforderung, wenn der Benutzer etwas eingibt"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Schnelleren Musterabgleich verwenden, der zwar ungenauer ist, aber nicht auf das Dateisystem zugreift"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "Die umask in sudoers überschreibt die umask des Benutzers, selbst wenn diese mehr Berechtigungen zulässt"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "Benutzereingaben für den ausgeführten Befehl protokollieren"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "Die Ausgabe des ausgeführten Befehls protokollieren"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "Ein-/Ausgabe-Protokolle mittels zlib protokollieren"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "Befehle immer in einem Pseudo-TTY ausführen"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Plugin für Unterstützung von Nicht-Unix-Gruppen: %s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Verzeichnis zur Speicherung der Ein-/Ausgabe-Protokolle: %s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Datei zur Speicherung der Ein-/Ausgabe-Protokolle: %s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Einen Eintrag in die utmp/utmpx-Datei einfügen, wenn ein Pseudo-TTY erzeugt wird"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Für den Eintrag in der utmp-Datei den runas-Benutzer verwenden, nicht den aufrufenden Benutzer"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Menge der erlaubten Privilegien: %s"
+
+# XXX einschränkenden?
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Menge der eingeschränkten Privilegien: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "Befehle mit einem Pseudo-TTY im Hintergrund starten"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "Verwendeter PAM-Service-Name: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "PAM-Service-Namen für Anmelde-Shells: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Versuchen, die PAM-Anmeldedaten für den Ziel-Benutzer zu bekommen"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "Eine neue PAM-Sitzung erzeugen, um den Befehl auszuführen"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Maximale Sequenznummer des Ein-/Ausgabe-Protokolls: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "Unterstützung für netgroups in sudoers aktivieren"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Prüfe die übergeordneten Verzeichnisse auf Schreibbarkeit beim Editieren von Dateien mit »sudoedit«"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Folge symbolischen Links beim Editieren von Dateien mit sudoedit"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "Frage das Group-Plugin nach unbekannten System-Gruppen"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Prüfe die Netgroup-Zuordnung aufgrund des gesamten Tupels: Benutzer, Host und Domain"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Erlaubt das Ausführen von Kommandos, auch wenn kein Audit-Log geschrieben werden kann"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Erlaubt das Ausführen von Kommandos, auch wenn kein I/O-Log geschrieben werden kann"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Erlaubt das Ausführen von Kommandos, auch wenn kein Log geschrieben werden kann"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Beim Auflösen von Gruppen in der sudoers nach der Guppen-ID suchen, nicht nach dem Gruppenname"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Log-Einträge größer als dieser Wert werden auf mehrere Syslog Einträge verteilt: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Eigentümer der I/O Logdateien: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Gruppe der I/O Logdateien: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Dateimode der I/O Logdatei: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Führe Kommandos mit Hilfe eines Dateideskriptors anstelle des Pfades aus: %s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Ignoriere unbekannte Default-Einträge in der Datei »sudoers« anstatt eine Warnung auszugeben"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Laufzeit in Sekunde, nach der das Kommando abgebrochen wird: %u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Erlaube dem Benutzer per Kommandozeile einen Timeout anzugeben"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Schreibe Log-Daten direkt ohne zu puffern"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "Protokolliere auch die Prozess-ID beim Schreiben ins Systemlog"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Typ des Authentifizierungszeitstempelprotokolls: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "Fehler bei der Authentifizierung: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "Ignoriere Groß-/Kleinschreibung beim Matchen von Benutzernamen"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "Ignoriere Groß-/Kleinschreibung beim Matchen von Gruppennamen"
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d unbekannter defaults-Eintrag »%s«"
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: unbekannter defaults-Eintrag »%s«"
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d Kein Wert für »%s« angegeben"
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: Kein Wert für »%s« angegeben"
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d Werte für »%s« müssen mit einem »/« beginnen"
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: Werte für »%s« müssen mit einem »/« beginnen"
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d Die Option »%s« wird ohne Wert verwendet"
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: Die Option »%s« wird ohne Wert verwendet"
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d Ungültiger »Defaults« Typ 0x%x für Option »%s«"
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: Ungültiger »Defaults« Typ 0x%x für Option »%s«"
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d Der Wert »%s« ist für die Option »%s« ungültig"
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: Der Wert »%s« ist für die Option »%s« ungültig"
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: envp ist beschädigt, die Längen passen nicht"
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr "Das Environment kann nicht neu erstellt werden"
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "Leider dürfen die folgenden Umgebungsvariablen nicht gesetzt werden: %s"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "Syntax-Fehler in %s bei der Zeile %d"
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "Syntax-Fehler in %s"
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "Prüfsummentyp %d wird für %s nicht unterstützt"
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr "%s: Fehler beim Lesen"
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s muss der uid %d gehören"
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s darf nur für den Eigentümer der Datei schreibbar sein"
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "Laden von %s fehlgeschlagen: %s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "Das Symbol »group_plugin« kann in %s nicht gefunden werden"
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: Die Major-Version %d des Group-Plugins ist inkompatibel, erwartet wird %d"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "»%s« ist keine gültige IP-Adresse"
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "»%s« ist keine gültige Netzmaske"
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Lokale IP-Adresse und Netzmaske:\n"
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s existiert, aber ist kein Verzeichnis (0%o)"
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "Das Verzeichnis »%s« kann nicht erstellt werden"
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:723
+#: plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "Ändern des Modus von %s auf 0%o gescheitert"
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1167
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr "Unbekannte Gruppe: %s"
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr "Die Datei »%s« kann nicht gelesen werden"
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr "Die Datei »%s« kann nicht erstellt werden"
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "In die I/O Logdatei kann nicht geschrieben werden: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr "%s: Interner Fehler, Logdatei für Event %d nicht geöffnet!"
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr "%s: Interner Fehler, ungültiges Signal %d"
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: ungültige Protokolldatei"
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: Das Feld für den Zeitstempel fehlt"
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: Zeitstempel %s: %s"
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: Das Benutzerfeld fehlt"
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: Das Feld für den »runas«-Benutzer fehlt"
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: Das Feld für die »runas«-Gruppe fehlt"
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr "starttls wird für ldaps nicht unterstützt"
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "Die Zertifikat- und Schlüsseldatenbank für SSL kann nicht initialisiert werden: %s"
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "In der Datei »%s« muss »TLS_CERT« angegeben sein, um SSL zu nutzen"
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "LDAP kann nicht initialisiert werden: %s"
+
+#: plugins/sudoers/ldap.c:1648
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls ist angegeben, aber die LDAP-Bibliotheken unterstützen ldap_start_tls_s() und ldap_start_tls_s_np() nicht"
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "Ungültiges »sudoOrder« Attribut: %s"
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: Port ist zu groß"
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "LDAP-Adresstyp wird nicht unterstützt: %s"
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "ldap- und ldaps-Adressen können nicht zusammen verwendet werden"
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "sudoOption kann nicht konvertiert werden: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "Das Audit-System kann nicht geöffnet werden"
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr "Die Audit-Nachricht kann nicht gesendet werden"
+
+#: plugins/sudoers/logging.c:113
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:141
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (Befehl fortgesetzt) %s"
+
+#: plugins/sudoers/logging.c:170
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "Die Protokolldatei kann nicht geöffnet werden: %s"
+
+#: plugins/sudoers/logging.c:178
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "Die Sperrdatei kann nicht geöffnet werden: %s"
+
+#: plugins/sudoers/logging.c:211
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "In die Logdatei kann nicht geschrieben werden: %s"
+
+#: plugins/sudoers/logging.c:240
+msgid "No user or host"
+msgstr "Kein Benutzer oder Rechner angegeben"
+
+#: plugins/sudoers/logging.c:242
+msgid "validation failure"
+msgstr "Fehler bei der Validierung"
+
+#: plugins/sudoers/logging.c:249
+msgid "user NOT in sudoers"
+msgstr "Der Benutzer ist NICHT in der sudoers-Datei enthalten"
+
+#: plugins/sudoers/logging.c:251
+msgid "user NOT authorized on host"
+msgstr "Der Benutzer ist NICHT auf dem Rechner autorisiert"
+
+#: plugins/sudoers/logging.c:253
+msgid "command not allowed"
+msgstr "Der Befehl ist nicht erlaubt"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s ist nicht in der sudoers-Datei. Dieser Vorfall wird gemeldet.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s darf sudo für %s nicht verwenden. Dieser Vorfall wird gemeldet.\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Leider darf der Benutzer %s sudo für %s nicht verwenden.\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Leider darf der Benutzer %s »%s%s%s« als %s%s%s auf %s nicht ausführen.\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: Befehl nicht gefunden"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"Im aktuellen Verzeichnis ».« gefundenes »%s« wird ignoriert.\n"
+"Verwenden Sie »sudo ./%s«, wenn dies der gewünschte Befehl »%s« ist."
+
+#: plugins/sudoers/logging.c:354
+msgid "authentication failure"
+msgstr "Fehler bei der Authentifizierung"
+
+#: plugins/sudoers/logging.c:380
+msgid "a password is required"
+msgstr "Ein Passwort ist notwendig"
+
+#: plugins/sudoers/logging.c:443
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u Fehlversuch bei der Passwort-Eingabe"
+msgstr[1] "%u Fehlversuche bei der Passwort-Eingabe"
+
+#: plugins/sudoers/logging.c:666
+msgid "unable to fork"
+msgstr "Fehler bei fork()"
+
+#: plugins/sudoers/logging.c:674 plugins/sudoers/logging.c:726
+#, c-format
+msgid "unable to fork: %m"
+msgstr "Fehler bei fork(): %m"
+
+#: plugins/sudoers/logging.c:716
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "Die Pipe kann nicht geöffnet werden: %m"
+
+#: plugins/sudoers/logging.c:741
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "Die Standardeingabe kann nicht dupliziert werden: %m"
+
+#: plugins/sudoers/logging.c:779
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "%s kann nicht ausgeführt werden: %m"
+
+#: plugins/sudoers/match.c:874
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "Prüfsumme für %s (%s) ist nicht in der Form %s"
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:421 plugins/sudoers/visudo.c:717
+#, c-format
+msgid "unable to stat %s"
+msgstr "stat konnte nicht auf %s angewendet werden"
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"LDAP-Rolle: %s\n"
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Sudoers-Eintrag:\n"
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr " RunAsUsers: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr " RunAsGroups: "
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr " Optionen: "
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr " Befehle:\n"
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Passende Defaults-Einträge für %s auf %s:\n"
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Runas und befehlsspezifische Standardwerte für %s:\n"
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Der Benutzer %s darf die folgenden Befehle auf %s ausführen:\n"
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Der Benutzer %s darf sudo auf dem Rechner %s nicht ausführen.\n"
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "ignoriere ungültigen Attribut-Wert: %s"
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "ignoriere die unvollständige sudoRole: cn: %s"
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "ungültige Option »%.*s« durch das sudo-Frontend angegeben"
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr "Die Netzwerkadressliste kann nicht eingelesen werden"
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr "Benutzername nicht durch das sudo-Frontend angegeben"
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr "User-ID nicht durch das sudo-Frontend angegeben"
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr "Gruppen-ID nicht durch das sudo-Frontend angegeben"
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr "Hostname nicht durch das sudo-Frontend angegeben"
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:220
+#: plugins/sudoers/visudo.c:851
+#, c-format
+msgid "unable to execute %s"
+msgstr "%s kann nicht ausgeführt werden"
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Sudoers-Policy-Plugin Version %s\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Sudoers-Datei-Grammatik-Version %d\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Sudoers-Pfad: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "nsswitch-Pfad: %s\n"
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "ldap.conf-Pfad: %s\n"
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "ldap.secret-Pfad: %s\n"
+
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "Der Hook vom Typ %d kann nicht registriert werden (Version %d.%d)"
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "Die Benutzer-ID %u kann nicht zwischengespeichert werden, kein Speicher verfügbar"
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "Die Benutzer-ID %u kann nicht zwischengespeichert werden, sie existiert bereits"
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "Der Benutzer %s kann nicht in den Zwischenspeicher aufgenommen werden, kein Speicher verfügbar"
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "Der Benutzer %s kann nicht in den Zwischenspeicher aufgenommen werden, er existiert bereits"
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "Die Gruppen-ID %u kann nicht in den Zwischenspeicher aufgenommen werden, kein Speicher verfügbar"
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "Die Gruppen-ID %u kann nicht in den Zwischenspeicher aufgenommen werden, sie existiert bereits"
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "Die Gruppe %s kann nicht in den Zwischenspeicher aufgenommen werden, kein Speicher verfügbar"
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "Die Gruppe %s kann nicht in den Zwischenspeicher aufgenommen werden, sie existiert bereits"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "Die Gruppen-Liste für %s kann nicht in den Zwischenspeicher aufgenommen werden, sie existiert bereits"
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "Die Gruppen-Liste für %s kann nicht in den Zwischenspeicher aufgenommen werden, kein Speicher verfügbar"
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "Die Gruppen für %s können nicht eingelesen werden"
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "Die Gruppen für %s können nicht geparst werden"
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr "Stack-Überlauf der Zugriffsrechte"
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr "Stack-Bereichsunterschreitung der Zugriffsrechte"
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr "Wechsel zur root-GID ist nicht möglich"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr "Wechsel zur runas-UID ist nicht möglich"
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr "Die runas-Gruppen können nicht gesetzt werden"
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr "Wechsel zur runas-GID ist nicht möglich"
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr "Wechsel zur sudoers-GID ist nicht möglich"
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr "Zu viele Prozesse"
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr "Das aktuelle Arbeitsverzeichnis kann nicht bestimmt werden"
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "Audit-Pfad user_cmnd abgeschnitten: %s"
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "Audit-Pfad argv[0] abgeschnitten: %s"
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr "audit_failure-Meldung ist zu lang"
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "Die SSS-Quelle kann nicht initialisiert werden. Ist SSSD auf dem Rechner installiert?"
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "Das Symbol »%s« kann in %s nicht gefunden werden"
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr "Problem mit den Standard-Einträgen"
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr "Keine gültige sudoers-Quelle gefunden, Programmende"
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers gibt an, dass root sudo nicht verwenden darf"
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr "Sie dürfen die Option -C nicht verwenden"
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "Zeitstempelbesitzer (%s): Benutzer existiert nicht"
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr "Kein tty"
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr "Sie müssen ein TTY haben, um sudo zu verwenden"
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr "Befehl ist im aktuellen Verzeichnis"
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "Sie dürfen keinen Timeout angeben"
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "Sie dürfen das Environment nicht erhalten"
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr "Der Befehl ist zu lang"
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s ist keine reguläre Datei"
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s gehört UID %u, sollte UID %u gehören"
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr "%s ist für alle beschreibbar (world writable)"
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s gehört GID %u, sollte allerdings %u gehören"
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "Nur root kann »-c %s« verwenden"
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr "Unbekannte Anmeldeklasse: %s"
+
+#: plugins/sudoers/sudoers.c:1069 plugins/sudoers/sudoers.c:1083
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "Hostname %s kann nicht aufgelöst werden"
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "Ungültige Filteroption: %s"
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "Ungültige maximale Wartezeit: %s"
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "Ungültiger Geschwindigkeitsfaktor: %s"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/Zeit: %s"
+
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/Zeit: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Sudo-Sitzung wird abgespielt: %s"
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr "Event kann nicht zur Warteschlange hinzugefügt werden"
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr "TTY konnte nicht in den Raw-Modus versetzt werden"
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr ""
+"Warnung: Ihr Terminal ist zu klein, um das Protokoll korrekt\n"
+"wiederzugeben.\n"
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Protokollgeometrie ist %d x %d, die Geometrie Ihres Terminals ist %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Wiedergabe beendet, eine Taste drücken um das Terminal wiederherzustellen."
+
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "Ungültige Zeitdateizeile: %s"
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "Mehrdeutiger Ausdruck »%s«"
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr "»)« ohne öffnende Klammer im Ausdruck"
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "Unbekannter Suchbegriff »%s«"
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s erfordert ein Argument"
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "ungültiger regulärer Ausdruck: %s"
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "Datum »%s« konnte nicht analysiert werden"
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr "»(« ohne schließende Klammer im Ausdruck"
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr "Ungültiges nachgestelltes »or«"
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr "Ungültiges nachgestelltes »!«"
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr "Unbekannter Suchtyp %d"
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr "Aufruf: %s [-hnRS] [-d Verzeichnis] [-m Max_Wartezeit] [-s Geschwindigkeitsfaktor] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "Aufruf: %s [-h] [-d Verzeichnis] -l [Suchausdruck]\n"
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s – sudo-Sitzungsprotokolle abspielen\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Optionen:\n"
+" -d, --directory=Verzeichnis gibt ein Verzeichnis für Sitzungsprotokolle an\n"
+" -f, --filter=Filter gibt an, welcher E/A-Typ angezeigt werden soll\n"
+" -h, --help zeigt einen Hilfetext an und beendet\n"
+" das Programm\n"
+" -l, --list zeigt verfügbare Sitzungs-IDs an, die mit dem\n"
+" Ausdruck übereinstimmen\n"
+" -m, --max-wait=Zahl gibt die maximale Wartezeit zwischen Ereignissen\n"
+" in Sekunden an\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=Zahl beschleunigt oder verlangsamt die Wiedergabe\n"
+" -V, --version zeigt Versionsinformationen an und beendet\n"
+" das Programm"
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr "\tHost stimmt nicht überein"
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Befehl erlaubt"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Befehl verweigert"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Befehl nicht erkannt"
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr "%s ist für die Gruppe beschreibbar"
+
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "Die Zeitstempeldatei kann nicht auf %lld Bytes abgeschnitten werden"
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:482 plugins/sudoers/visudo.c:488
+msgid "unable to read the clock"
+msgstr "Die Uhrzeit kann nicht ausgelesen werden"
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr "Zeitstempel aus der Zukunft wird ignoriert"
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "Zeitstempel ist zu weit in der Zukunft: %20.20s"
+
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "Die Zeitstempeldatei »%s« kann nicht gesperrt werden"
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "Pfad zur Belehrung ist zu lang: %s/%s"
+
+#: plugins/sudoers/visudo.c:216
+msgid "the -x option will be removed in a future release"
+msgstr "Die Option »-x» wird in einer zukünftigen Version entfernt"
+
+#: plugins/sudoers/visudo.c:217
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "Bitte verwenden Sie stattdessen das Programm »cvtsudoers«"
+
+#: plugins/sudoers/visudo.c:268 plugins/sudoers/visudo.c:650
+#, c-format
+msgid "press return to edit %s: "
+msgstr "Drücken Sie die Eingabetaste, um %s zu bearbeiten: "
+
+#: plugins/sudoers/visudo.c:329
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "Der angegebene Editor (%s) ist nicht vorhanden"
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "Kein Editor gefunden (Pfad zum Editor = %s)"
+
+#: plugins/sudoers/visudo.c:441 plugins/sudoers/visudo.c:449
+msgid "write error"
+msgstr "Schreibfehler"
+
+#: plugins/sudoers/visudo.c:495
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "Anwenden von stat auf die temporäre Datei (%s) gescheitert, %s ist unverändert"
+
+#: plugins/sudoers/visudo.c:502
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "Leere temporäre Datei (%s), %s ist unverändert"
+
+#: plugins/sudoers/visudo.c:508
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "Editor-Aufruf (%s) ist gescheitert, %s ist unverändert"
+
+#: plugins/sudoers/visudo.c:530
+#, c-format
+msgid "%s unchanged"
+msgstr "%s unverändert"
+
+#: plugins/sudoers/visudo.c:589
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "Erneutes Öffnen der temporären Datei (%s) gescheitert, %s ist unverändert."
+
+#: plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "Analyse der temporären Datei (%s) gescheitert, unbekannter Fehler"
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "Interner Fehler, %s in der Liste nicht gefunden!"
+
+#: plugins/sudoers/visudo.c:719 plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "Festlegen von (uid, gid) von %s auf (%u, %u) gescheitert"
+
+#: plugins/sudoers/visudo.c:751
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s und %s befinden sich nicht im gleichen Dateisystem, werden mit mv umbenannt"
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "Befehl gescheitert: »%s %s %s«, %s unverändert"
+
+#: plugins/sudoers/visudo.c:775
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "Fehler beim Umbenennen von %s, %s unverändert"
+
+#: plugins/sudoers/visudo.c:796
+msgid "What now? "
+msgstr "Was jetzt? "
+
+#: plugins/sudoers/visudo.c:810
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Optionen sind:\n"
+" sudoers-Datei (e)rneut bearbeiten\n"
+" Beenden, ohne die Änderungen an der sudoers-Datei zu speichern (mit x)\n"
+" Beenden und Änderungen an der sudoers-Datei speichern (mit Q, VORSICHT!)\n"
+
+#: plugins/sudoers/visudo.c:856
+#, c-format
+msgid "unable to run %s"
+msgstr "%s konnte nicht ausgeführt werden"
+
+#: plugins/sudoers/visudo.c:886
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: Falsche Besitzer-(uid, gid), sollte (%u, %u) sein\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: Falsche Zugriffsrechte, sollte Modus 0%o sein\n"
+
+#: plugins/sudoers/visudo.c:950 plugins/sudoers/visudo.c:957
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: Analyse OK\n"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s ist in Verwendung, versuchen Sie es später erneut"
+
+#: plugins/sudoers/visudo.c:979
+#, c-format
+msgid "unable to lock %s"
+msgstr "Die Datei »%s« kann nicht gesperrt werden"
+
+# XXX
+#: plugins/sudoers/visudo.c:980
+msgid "Edit anyway? [y/N]"
+msgstr "Trotzdem ändern? [y/N]"
+
+#: plugins/sudoers/visudo.c:1064
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Fehler: %s:%d Zyklus in %s »%s«"
+
+#: plugins/sudoers/visudo.c:1065
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Warnung: %s:%d Zyklus in %s »%s«"
+
+#: plugins/sudoers/visudo.c:1069
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Fehler: %s:%d %s »%s« wird verwendet, ist aber nicht definiert"
+
+#: plugins/sudoers/visudo.c:1070
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Warnung: %s:%d %s »%s« wird verwendet, ist aber nicht definiert"
+
+#: plugins/sudoers/visudo.c:1161
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Warnung: %s:%d nicht verwendet: %s »%s«"
+
+#: plugins/sudoers/visudo.c:1276
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s – Die sudoers-Datei sicher bearbeiten\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1278
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"Optionen:\n"
+" -c, --check nur den Prüf-Modus verwenden\n"
+" -f, --file=sudoers gibt den Namen der sudoers Datei an\n"
+" -h, --help diese Hilfe anzeigen und beenden\n"
+" -q, --quiet weniger ausführliche Syntaxfehler-Meldungen\n"
+" -s, --strict strikte Syntax-Prüfung\n"
+" -V, --version Versionsinformation anzeigen und beenden\n"
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr "Zu viele geschachtelte include-Einträge"
diff --git a/plugins/sudoers/po/el.mo b/plugins/sudoers/po/el.mo
new file mode 100644
index 0000000..aad70c3
--- /dev/null
+++ b/plugins/sudoers/po/el.mo
Binary files differ
diff --git a/plugins/sudoers/po/el.po b/plugins/sudoers/po/el.po
new file mode 100644
index 0000000..781bb8e
--- /dev/null
+++ b/plugins/sudoers/po/el.po
@@ -0,0 +1,1718 @@
+# Translation of sudoers to Greek
+# Todd C. Miller &lt;Todd.Miller@courtesan.com&gt;, 2011-2013
+# This file is distributed under the same license as the sudo package.
+# Dimitris Spingos (Δημήτρης Σπίγγος) <dmtrs32@gmail.com>, 2014.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers-1.8.10b3\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2014-02-07 15:13-0700\n"
+"PO-Revision-Date: 2014-06-04 08:01+0300\n"
+"Last-Translator: Dimitris Spingos (Δημήτρης Σπίγγος) <dmtrs32@gmail.com>\n"
+"Language-Team: Greek <team@lists.gnome.gr>\n"
+"Language: el\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Virtaal 0.7.0\n"
+
+#: confstr.sh:2
+msgid "Password:"
+msgstr "Κωδικός πρόσβασης:"
+
+#: confstr.sh:3
+msgid "*** SECURITY information for %h ***"
+msgstr "*** Πληροφορίες ΑΣΦΑΛΕΙΑΣ για το %h ***"
+
+#: confstr.sh:4
+msgid "Sorry, try again."
+msgstr "Συγνώμη, δοκιμάστε ξανά."
+
+#: plugins/sudoers/alias.c:136
+#, c-format
+msgid "Alias `%s' already defined"
+msgstr "Έχει ήδη οριστεί το ψευδώνυμο `%s'"
+
+#: plugins/sudoers/auth/bsdauth.c:75
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "αδύνατη η λήψη κλάσης σύνδεσης για τον χρήστη %s"
+
+#: plugins/sudoers/auth/bsdauth.c:81
+msgid "unable to begin bsd authentication"
+msgstr "αδύνατη η έναρξη της πιστοποίησης bsd"
+
+#: plugins/sudoers/auth/bsdauth.c:89
+msgid "invalid authentication type"
+msgstr "άκυρος τύπος πιστοποίησης"
+
+#: plugins/sudoers/auth/bsdauth.c:98
+msgid "unable to initialize BSD authentication"
+msgstr "αδύνατη η αρχικοποίηση της πιστοποίησης BSD"
+
+#: plugins/sudoers/auth/fwtk.c:59
+msgid "unable to read fwtk config"
+msgstr "αδύνατη η ανάγνωση του fwtk config"
+
+#: plugins/sudoers/auth/fwtk.c:64
+msgid "unable to connect to authentication server"
+msgstr "αδύνατη η σύνδεση με τον εξυπηρετητή πιστοποίησης"
+
+#: plugins/sudoers/auth/fwtk.c:70 plugins/sudoers/auth/fwtk.c:94
+#: plugins/sudoers/auth/fwtk.c:127
+msgid "lost connection to authentication server"
+msgstr "απώλεια σύνδεσης με τον εξυπηρετητή πιστοποίησης"
+
+#: plugins/sudoers/auth/fwtk.c:74
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"σφάλμα εξυπηρετητή πιστοποίησης:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:116
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: αδύνατη η μετατροπή της αρχής ασφάλειας σε συμβολοσειρά ('%s'): %s"
+
+#: plugins/sudoers/auth/kerb5.c:159
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: αδύνατη η ανάλυση του '%s': %s"
+
+#: plugins/sudoers/auth/kerb5.c:169
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: αδύνατη η επίλυση κρυφής μνήμης διαπιστευτήριων: %s"
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: αδύνατη η κατανομή επιλογών: %s"
+
+#: plugins/sudoers/auth/kerb5.c:233
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: αδύνατη η λήψη διαπιστευτηρίων: %s"
+
+#: plugins/sudoers/auth/kerb5.c:246
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: αδύνατη η αρχικοποίηση κρυφής μνήμης διαπιστευτηρίων: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: αδύνατη η αποθήκευση διαπιστευτηρίων στην κρυφή μνήμη: %s"
+
+#: plugins/sudoers/auth/kerb5.c:315
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: αδύνατη η λήψη αρχής ασφάλειας του οικοδεσπότη: %s"
+
+#: plugins/sudoers/auth/kerb5.c:330
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Αδύνατη η επιβεβαίωση TGT! Πιθανή επίθεση!: %s"
+
+#: plugins/sudoers/auth/pam.c:98
+msgid "unable to initialize PAM"
+msgstr "αδύνατη η αρχικοποίηση του PAM"
+
+#: plugins/sudoers/auth/pam.c:149
+msgid "account validation failure, is your account locked?"
+msgstr "αποτυχία επικύρωσης λογαριασμού, είναι κλειδωμένος ο λογαριασμός σας;"
+
+#: plugins/sudoers/auth/pam.c:153
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Ο λογαριασμός ή ο κωδικός πρόσβασης έχει λήξει, επαναφέρτε τον κωδικό πρόσβασής σας και ξαναδοκιμάστε"
+
+#: plugins/sudoers/auth/pam.c:161
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "αδύνατη η αλλαγή του ληγμένου κωδικού πρόσβασης: %s"
+
+#: plugins/sudoers/auth/pam.c:166
+msgid "Password expired, contact your system administrator"
+msgstr "Ο κωδικός πρόσβασης έχει λήξει, επικοινωνήστε με τον διαχειριστή του συστήματος"
+
+#: plugins/sudoers/auth/pam.c:170
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Ο λογαριασμός έχει λήξει ή το PAM config στερείται μιας ενότητας \"λογαριασμού\" για sudo, επικοινωνήστε με τον διαχειριστή του συστήματός σας"
+
+#: plugins/sudoers/auth/pam.c:187
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Σφάλμα πιστοποίησης PAM: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:103 plugins/sudoers/visudo.c:222
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "δεν υπάρχετε στη βάση δεδομένων %s"
+
+#: plugins/sudoers/auth/securid5.c:80
+msgid "failed to initialise the ACE API library"
+msgstr "αποτυχία αρχικοποίησης της βιβλιοθήκης ACE API"
+
+#: plugins/sudoers/auth/securid5.c:106
+msgid "unable to contact the SecurID server"
+msgstr "αδύνατη η επικοινωνία με τον εξυπηρετητή SecurID"
+
+#: plugins/sudoers/auth/securid5.c:115
+msgid "User ID locked for SecurID Authentication"
+msgstr "Το αναγνωριστικό του χρήστη για πιστοποίηση SecurID είναι κλειδωμένο"
+
+#: plugins/sudoers/auth/securid5.c:119 plugins/sudoers/auth/securid5.c:170
+msgid "invalid username length for SecurID"
+msgstr "άκυρο μήκος ονόματος χρήστη για SecurID"
+
+#: plugins/sudoers/auth/securid5.c:123 plugins/sudoers/auth/securid5.c:175
+msgid "invalid Authentication Handle for SecurID"
+msgstr "άκυρη διαχείριση πιστοποίησης για SecurID"
+
+#: plugins/sudoers/auth/securid5.c:127
+msgid "SecurID communication failed"
+msgstr "αποτυχία επικοινωνίας SecurID"
+
+#: plugins/sudoers/auth/securid5.c:131 plugins/sudoers/auth/securid5.c:214
+msgid "unknown SecurID error"
+msgstr "άγνωστο σφάλμα SecurID"
+
+#: plugins/sudoers/auth/securid5.c:165
+msgid "invalid passcode length for SecurID"
+msgstr "άκυρο μήκος κωδικού περάσματος για το SecurID"
+
+#: plugins/sudoers/auth/sia.c:108
+msgid "unable to initialize SIA session"
+msgstr "αδύνατη η αρχικοποίηση της συνεδρίας SIA"
+
+#: plugins/sudoers/auth/sudo_auth.c:119
+msgid "invalid authentication methods"
+msgstr "άκυρες μέθοδοι πιστοποίησης"
+
+#: plugins/sudoers/auth/sudo_auth.c:120
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Άκυρες μεταγλωττισμένες μέθοδοι πιστοποίησης στο sudo! Δεν μπορείτε να αναμίξετε αυτόνομη και μη αυτόνομη πιστοποίηση."
+
+#: plugins/sudoers/auth/sudo_auth.c:203
+msgid "no authentication methods"
+msgstr "δεν υπάρχουν μέθοδοι πιστοποίησης"
+
+#: plugins/sudoers/auth/sudo_auth.c:205
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Δεν υπάρχουν μεταγλωττισμένες μέθοδοι πιστοποίησης στο sudo! Αν θέλετε να απενεργοποιήσετε την πιστοποίηση, χρησιμοποιήστε την επιλογή ρύθμισης --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:389
+msgid "Authentication methods:"
+msgstr "Μέθοδοι πιστοποίησης:"
+
+#: plugins/sudoers/bsm_audit.c:91 plugins/sudoers/bsm_audit.c:158
+msgid "Could not determine audit condition"
+msgstr "Αδυναμία εντοπισμού συνθήκης ελέγχου"
+
+#: plugins/sudoers/bsm_audit.c:134 plugins/sudoers/bsm_audit.c:199
+msgid "unable to commit audit record"
+msgstr "αδύνατη η υποβολή εγγραφής ελέγχου"
+
+#: plugins/sudoers/check.c:189
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Εμπιστευόμαστε ότι έχετε δεχτεί τις συνηθισμένες οδηγίες από τον\n"
+"διαχειριστή του τοπικού συστήματος. Συνήθως συμπυκνώνεται σε τρία πράγματα:\n"
+"\n"
+" #1) Σεβασμός της ιδιωτικότητας των άλλων.\n"
+" #2) Σκεφτείτε πριν πληκτρολογήσετε.\n"
+" #3) Η μεγάλη ισχύς συνυπάρχει με τη μεγάλη ευθύνη.\n"
+"\n"
+
+#: plugins/sudoers/check.c:232 plugins/sudoers/check.c:238
+#: plugins/sudoers/sudoers.c:562 plugins/sudoers/sudoers.c:588
+#, c-format
+msgid "unknown uid: %u"
+msgstr "άγνωστο uid: %u"
+
+#: plugins/sudoers/check.c:235 plugins/sudoers/policy.c:657
+#: plugins/sudoers/sudoers.c:850 plugins/sudoers/testsudoers.c:211
+#: plugins/sudoers/testsudoers.c:363
+#, c-format
+msgid "unknown user: %s"
+msgstr "άγνωστος χρήστης: %s"
+
+#: plugins/sudoers/def_data.c:27
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Ευκολία Syslog αν το syslog χρησιμοποιείται για καταγραφή: %s"
+
+#: plugins/sudoers/def_data.c:31
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Προτεραιότητα χρήσης Syslog, όταν ο χρήστης πιστοποιείται επιτυχώς: %s"
+
+#: plugins/sudoers/def_data.c:35
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Προτεραιότητα χρήσης Syslog, όταν ο χρήστης πιστοποιείται ανεπιτυχώς: %s"
+
+#: plugins/sudoers/def_data.c:39
+msgid "Put OTP prompt on its own line"
+msgstr "Τοποθέτηση της προτροπής OTP στη δική της γραμμή"
+
+#: plugins/sudoers/def_data.c:43
+msgid "Ignore '.' in $PATH"
+msgstr "Παράβλεψη '.' στο $PATH"
+
+#: plugins/sudoers/def_data.c:47
+msgid "Always send mail when sudo is run"
+msgstr "Να στέλνετε πάντα μήνυμα όταν εκτελείται το sudo"
+
+#: plugins/sudoers/def_data.c:51
+msgid "Send mail if user authentication fails"
+msgstr "Να στέλνετε μήνυμα αν η πιστοποίηση χρήστη αποτύχει"
+
+#: plugins/sudoers/def_data.c:55
+msgid "Send mail if the user is not in sudoers"
+msgstr "Να στέλνετε μήνυμα αν ο χρήστης δεν είναι στους χρήστες sudo"
+
+#: plugins/sudoers/def_data.c:59
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Να στέλνετε μήνυμα αν ο χρήστης δεν είναι στους χρήστες sudo για αυτόν τον οικοδεσπότη"
+
+#: plugins/sudoers/def_data.c:63
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Να στέλνετε μήνυμα αν ο χρήστης δεν επιτρέπεται να εκτελέσει μια εντολή"
+
+#: plugins/sudoers/def_data.c:67
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Να χρησιμοποιείται ξεχωριστή χρονική σήμανση για κάθε χρήστη/σύνθετο tty"
+
+#: plugins/sudoers/def_data.c:71
+msgid "Lecture user the first time they run sudo"
+msgstr "Να δίνονται οδηγίες στον χρήστη την πρώτη φορά που εκτελεί sudo"
+
+#: plugins/sudoers/def_data.c:75
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Το αρχείο που περιέχει τις οδηγίες sudo: %s"
+
+#: plugins/sudoers/def_data.c:79
+msgid "Require users to authenticate by default"
+msgstr "Να απαιτείται από τους χρήστες να πιστοποιούνται από προεπιλογή"
+
+#: plugins/sudoers/def_data.c:83
+msgid "Root may run sudo"
+msgstr "Ο υπερχρήστης μπορεί να εκτελεί sudo"
+
+#: plugins/sudoers/def_data.c:87
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Καταγραφή του ονόματος οικοδεσπότη στο αρχείο καταγραφής (non-syslog)"
+
+#: plugins/sudoers/def_data.c:91
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Καταγραφή του έτους στο αρχείο καταγραφής (non-syslog)"
+
+#: plugins/sudoers/def_data.c:95
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Αν το sudo κλήθηκε χωρίς ορίσματα, να αρχίσει ένα κέλυφος"
+
+#: plugins/sudoers/def_data.c:99
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Ορίστε το $HOME του προοριζόμενου χρήστη όταν ξεκινάτε ένα κέλυφος με -s"
+
+#: plugins/sudoers/def_data.c:103
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Να ορίζεται πάντα το $HOME στον προσωπικό κατάλογο του προοριζόμενου χρήστη"
+
+#: plugins/sudoers/def_data.c:107
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Να επιτρέπεται η συγκέντρωση κάποιων πληροφοριών για να δίνονται χρήσιμα μηνύματα σφαλμάτων"
+
+#: plugins/sudoers/def_data.c:111
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Να απαιτούνται πλήρως χαρακτηρισμένα ονόματα οικοδεσπότη στο αρχείο χρηστών sudo"
+
+#: plugins/sudoers/def_data.c:115
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Να ειδοποιείται ο χρήστης όταν εισάγει έναν εσφαλμένο κωδικό πρόσβασης"
+
+#: plugins/sudoers/def_data.c:119
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Να επιτρέπεται στον χρήστη να εκτελεί sudo μόνο αν έχει ένα tty"
+
+#: plugins/sudoers/def_data.c:123
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Το Visudo θα σεβαστεί τη μεταβλητή περιβάλλοντος του EDITOR"
+
+#: plugins/sudoers/def_data.c:127
+msgid "Prompt for root's password, not the users's"
+msgstr "Να ζητιέται ο κωδικός πρόσβασης του υπερχρήστη, όχι του χρήστη"
+
+#: plugins/sudoers/def_data.c:131
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Να ζητιέται ο κωδικός πρόσβασης των χρηστών runas_default, όχι των χρηστών"
+
+#: plugins/sudoers/def_data.c:135
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Να ζητιέται ο κωδικός πρόσβασης του προοριζόμενου χρήστη, όχι των χρηστών"
+
+#: plugins/sudoers/def_data.c:139
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Να εφαρμόζονται οι προεπιλογές στην κλάση σύνδεσης του προοριζόμενου χρήστη αν υπάρχει κάποιες"
+
+#: plugins/sudoers/def_data.c:143
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Να ορίζονται οι μεταβλητές περιβάλλοντος LOGNAME και USER"
+
+#: plugins/sudoers/def_data.c:147
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Να ορίζεται μόνο το ενεργό uid του προοριζόμενου χρήστη, όχι το πραγματικό uid"
+
+#: plugins/sudoers/def_data.c:151
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Να μην αρχικοποιείται το διάνυσμα ομάδας σε αυτό του προοριζόμενου χρήστη"
+
+#: plugins/sudoers/def_data.c:155
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Το μήκος στο οποίο θα αναδιπλώνονται οι γραμμές του αρχείου καταγραφής (0 για χωρίς αναδίπλωση): %u"
+
+#: plugins/sudoers/def_data.c:159
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Όριο χρόνου χρονικής σήμανσης πιστοποίησης: %.1f λεπτά"
+
+#: plugins/sudoers/def_data.c:163
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Όριο χρόνου προτροπής κωδικού πρόσβασης: %.1f λεπτά"
+
+#: plugins/sudoers/def_data.c:167
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Αριθμός προσπαθειών για να εισάγετε έναν κωδικό πρόσβασης: %u"
+
+#: plugins/sudoers/def_data.c:171
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Χρησιμοποιήστε umask ή 0777 για να χρησιμοποιήσετε του χρήστη: 0%o"
+
+#: plugins/sudoers/def_data.c:175
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Διαδρομή για το αρχείο καταγραφής: %s"
+
+#: plugins/sudoers/def_data.c:179
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Διαδρομή για το πρόγραμμα αλληλογραφίας: %s"
+
+#: plugins/sudoers/def_data.c:183
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Σημαίες για το πρόγραμμα αλληλογραφίας: %s"
+
+#: plugins/sudoers/def_data.c:187
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Διεύθυνση αποστολής αλληλογραφίας προς: %s"
+
+#: plugins/sudoers/def_data.c:191
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Διεύθυνση λήψης αλληλογραφίας από: %s"
+
+#: plugins/sudoers/def_data.c:195
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Γραμμή θέματος για μηνύματα αλληλογραφίας: %s"
+
+#: plugins/sudoers/def_data.c:199
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Εσφαλμένο μήνυμα κωδικού πρόσβασης: %s"
+
+#: plugins/sudoers/def_data.c:203
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Διαδρομή για τον κατάλογο κατάστασης οδηγιών: %s"
+
+#: plugins/sudoers/def_data.c:207
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Διαδρομή για τον κατάλογο χρονικής σήμανσης πιστοποίησης: %s"
+
+#: plugins/sudoers/def_data.c:211
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Κάτοχος καταλόγου χρονικής σήμανσης πιστοποίησης: %s"
+
+#: plugins/sudoers/def_data.c:215
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Οι χρήστες αυτής της ομάδας εξαιρούνται από τον κωδικό πρόσβασης και της απαιτήσεις PATH: %s"
+
+#: plugins/sudoers/def_data.c:219
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Προτροπή προεπιλεγμένου κωδικού πρόσβασης: %s"
+
+#: plugins/sudoers/def_data.c:223
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Αν οριστεί, η προτροπή περάσματος θα αντικαταστήσει την προτροπή συστήματος σε όλες τις περιπτώσεις."
+
+#: plugins/sudoers/def_data.c:227
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Προεπιλεγμένος χρήστης για να εκτελεί εντολές ως: %s"
+
+#: plugins/sudoers/def_data.c:231
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Τιμή που θα αντικαθιστά τη $PATH χρήστη με: %s"
+
+#: plugins/sudoers/def_data.c:235
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Διαδρομή για τον επεξεργαστή για χρήση από το visudo: %s"
+
+#: plugins/sudoers/def_data.c:239
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Πότε θα απαιτείται κωδικός πρόσβασης για τον 'κατάλογο' ψευδοεντολών: %s"
+
+#: plugins/sudoers/def_data.c:243
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Πότε θα απαιτείται κωδικός πρόσβασης για 'επιβεβαίωση' ψευδοεντολής: %s"
+
+#: plugins/sudoers/def_data.c:247
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Να προφορτώνονται οι εικονικές συναρτήσεις εκτέλεσης στη βιβλιοθήκη sudo_noexec"
+
+#: plugins/sudoers/def_data.c:251
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Αν ο κατάλογος LDAP είναι ανεβασμένος, παραβλέπουμε το τοπικό αρχείο χρηστών sudo."
+
+#: plugins/sudoers/def_data.c:255
+#, fuzzy, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Οι περιγραφείς αρχείων &gt;= %d να είναι κλειστοί πριν την εκτέλεση μιας εντολής"
+
+#: plugins/sudoers/def_data.c:259
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Αν οριστεί, οι χρήστες μπορούν να αντικαθιστούν την τιμή του `closefrom' με την επιλογή -C"
+
+#: plugins/sudoers/def_data.c:263
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Να επιτρέπεται στους χρήστες να ορίζουν ελεύθερες μεταβλητές περιβάλλοντος"
+
+#: plugins/sudoers/def_data.c:267
+msgid "Reset the environment to a default set of variables"
+msgstr "Να επαναρρυθμίζεται το περιβάλλον σε ένα προεπιλεγμένο σύνολο μεταβλητών"
+
+#: plugins/sudoers/def_data.c:271
+msgid "Environment variables to check for sanity:"
+msgstr "Οι μεταβλητές περιβάλλοντος που θα ελέγχονται για ακεραιότητα:"
+
+#: plugins/sudoers/def_data.c:275
+msgid "Environment variables to remove:"
+msgstr "Οι μεταβλητές περιβάλλοντος προς αφαίρεση:"
+
+#: plugins/sudoers/def_data.c:279
+msgid "Environment variables to preserve:"
+msgstr "Οι μεταβλητές περιβάλλοντος για διατήρηση:"
+
+#: plugins/sudoers/def_data.c:283
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Ο ρόλος του SELinux που θα χρησιμοποιηθεί στο νέο περιεχόμενο ασφάλειας: %s"
+
+#: plugins/sudoers/def_data.c:287
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Ο τύπος SELinux που θα χρησιμοποιηθεί στο νέο περιεχόμενο ασφάλειας: %s"
+
+#: plugins/sudoers/def_data.c:291
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Η διαδρομή προς το αρχείο περιβάλλοντος που είναι ειδικό για sudo: %s"
+
+#: plugins/sudoers/def_data.c:295
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Οι τοπικές ρυθμίσεις που θα χρησιμοποιηθούν κατά την ανάλυση των χρηστών sudo: %s"
+
+#: plugins/sudoers/def_data.c:299
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Να επιτρέπεται στο sudo να ζητά κωδικό πρόσβασης ακόμα κι αν θα είναι ορατό"
+
+#: plugins/sudoers/def_data.c:303
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Να παρέχεται οπτική ανάδραση στην προτροπή κωδικού πρόσβασης όταν υπάρχει είσοδος χρήστη"
+
+#: plugins/sudoers/def_data.c:307
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Να χρησιμοποιείται γρηγορότερη επέκταση (globbing) που είναι λιγότερο ακριβές, αλλά δεν έχει πρόσβαση στο σύστημα αρχείων"
+
+#: plugins/sudoers/def_data.c:311
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "Η umask που ορίστηκε στους χρήστες sudo θα αντικαταστήσει αυτή του χρήστη, ακόμα κι αν δίνει περισσότερα δικαιώματα."
+
+#: plugins/sudoers/def_data.c:315
+msgid "Log user's input for the command being run"
+msgstr "Να καταγράφεται η είσοδος χρήστη για την εκτελούμενη εντολή"
+
+#: plugins/sudoers/def_data.c:319
+msgid "Log the output of the command being run"
+msgstr "Να καταγράφεται η έξοδος της εκτελούμενης εντολής"
+
+#: plugins/sudoers/def_data.c:323
+msgid "Compress I/O logs using zlib"
+msgstr "Συμπίεση καταγραφών εισόδου/εξόδου χρησιμοποιώντας το zlib"
+
+#: plugins/sudoers/def_data.c:327
+msgid "Always run commands in a pseudo-tty"
+msgstr "Να εκτελούνται πάντα εντολές σε ψευδο-tty"
+
+#: plugins/sudoers/def_data.c:331
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Πρόσθετο για υποστήριξη ομάδας μη Γιούνιξ: %s"
+
+#: plugins/sudoers/def_data.c:335
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Κατάλογος στον οποίο αποθηκεύονται οι καταγραφές εισόδου/εξόδου: %s"
+
+#: plugins/sudoers/def_data.c:339
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Αρχείο στο οποίο θα αποθηκεύεται η καταγραφή εισόδου/εξόδου: %s"
+
+#: plugins/sudoers/def_data.c:343
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Να προστίθεται μια καταχώριση στο αρχείο utmp/utmpx κατά την εκχώρηση ενός pty"
+
+#: plugins/sudoers/def_data.c:347
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Να ορίζεται ο χρήστης στο utmp στον χρήστη runas, να μην καλείται ο χρήστης"
+
+#: plugins/sudoers/def_data.c:351
+msgid "Set of permitted privileges"
+msgstr "Να ορίζονται τα επιτρεπόμενα δικαιώματα"
+
+#: plugins/sudoers/def_data.c:355
+msgid "Set of limit privileges"
+msgstr "Να ορίζονται τα δικαιώματα ορίου"
+
+#: plugins/sudoers/def_data.c:359
+msgid "Run commands on a pty in the background"
+msgstr "Να εκτελούνται εντολές σε ένα pty στο παρασκήνιο"
+
+#: plugins/sudoers/def_data.c:363
+msgid "PAM service name to use"
+msgstr "Το όνομα υπηρεσίας PAM που θα χρησιμοποιηθεί"
+
+#: plugins/sudoers/def_data.c:367
+msgid "PAM service name to use for login shells"
+msgstr "Το όνομα υπηρεσίας PAM που θα χρησιμοποιηθεί για κελύφη σύνδεσης"
+
+#: plugins/sudoers/def_data.c:371
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Να γίνεται προσπάθεια δημιουργίας διαπιστευτηρίων για τον προοριζόμενο χρήστη"
+
+#: plugins/sudoers/def_data.c:375
+msgid "Create a new PAM session for the command to run in"
+msgstr "Να δημιουργείται μια νέα συνεδρία PAM για την εκτελούμενη εντολή"
+
+#: plugins/sudoers/def_data.c:379
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Μέγιστος αριθμός αλληλουχίας καταγραφών εισόδου/εξόδου: %u"
+
+#: plugins/sudoers/def_data.c:383
+msgid "Enable sudoers netgroup support"
+msgstr "Να ενεργοποιείται η υποστήριξη ομάδας δικτύου στους χρήστες sudo"
+
+#: plugins/sudoers/defaults.c:210 plugins/sudoers/defaults.c:600
+#: plugins/sudoers/visudo_json.c:611 plugins/sudoers/visudo_json.c:647
+#, c-format
+msgid "unknown defaults entry `%s'"
+msgstr "άγνωστες προεπιλογές καταχώρισης `%s'"
+
+#: plugins/sudoers/defaults.c:218 plugins/sudoers/defaults.c:228
+#: plugins/sudoers/defaults.c:248 plugins/sudoers/defaults.c:261
+#: plugins/sudoers/defaults.c:274 plugins/sudoers/defaults.c:287
+#: plugins/sudoers/defaults.c:300 plugins/sudoers/defaults.c:320
+#: plugins/sudoers/defaults.c:330
+#, c-format
+msgid "value `%s' is invalid for option `%s'"
+msgstr "η τιμή `%s' είναι άκυρη για την επιλογή `%s'"
+
+#: plugins/sudoers/defaults.c:221 plugins/sudoers/defaults.c:231
+#: plugins/sudoers/defaults.c:239 plugins/sudoers/defaults.c:256
+#: plugins/sudoers/defaults.c:269 plugins/sudoers/defaults.c:282
+#: plugins/sudoers/defaults.c:295 plugins/sudoers/defaults.c:315
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "no value specified for `%s'"
+msgstr "δεν ορίστηκε τιμή για το `%s'"
+
+#: plugins/sudoers/defaults.c:244
+#, c-format
+msgid "values for `%s' must start with a '/'"
+msgstr "οι τιμές για το `%s' πρέπει να αρχίζουν με ένα '/'"
+
+#: plugins/sudoers/defaults.c:306
+#, c-format
+msgid "option `%s' does not take a value"
+msgstr "η επιλογή `%s' δεν παίρνει τιμή"
+
+#: plugins/sudoers/env.c:288 plugins/sudoers/env.c:293
+#: plugins/sudoers/env.c:395 plugins/sudoers/linux_audit.c:82
+#: plugins/sudoers/policy.c:442 plugins/sudoers/policy.c:449
+#: plugins/sudoers/prompt.c:171 plugins/sudoers/sudoers.c:656
+#: plugins/sudoers/testsudoers.c:241
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "εσωτερικό σφάλμα, υπερχείλιση του %s"
+
+#: plugins/sudoers/env.c:367
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: αλλοιωμένο envp, ασυμφωνία μήκους"
+
+#: plugins/sudoers/env.c:1014
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "συγνώμη, δεν σας επιτρέπετε να ορίσετε τις παρακάτω μεταβλητές περιβάλλοντος: %s"
+
+#: plugins/sudoers/group_plugin.c:94
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "το %s πρέπει να κατέχεται από το uid %d"
+
+#: plugins/sudoers/group_plugin.c:98
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "το %s πρέπει να είναι εγγράψιμο μόνο από τον κάτοχο"
+
+#: plugins/sudoers/group_plugin.c:105 plugins/sudoers/sssd.c:251
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "αδύνατη η φόρτωση του %s: %s"
+
+#: plugins/sudoers/group_plugin.c:110
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "αδύνατη η εύρεση συμβόλου \"group_plugin\" στο %s"
+
+#: plugins/sudoers/group_plugin.c:115
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: ασύμβατη μεγάλη έκδοση %d του προσθέτου ομάδας, αναμενόταν %d"
+
+#: plugins/sudoers/interfaces.c:116
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Ζεύγη τοπικής διεύθυνσης IP και μάσκας δικτύου:\n"
+
+#: plugins/sudoers/iolog.c:99 plugins/sudoers/iolog.c:112
+#: plugins/sudoers/timestamp.c:227
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "το %s υπάρχει, αλλά δεν είναι κατάλογος (0%o)"
+
+#: plugins/sudoers/iolog.c:109 plugins/sudoers/iolog.c:123
+#: plugins/sudoers/iolog.c:127 plugins/sudoers/timestamp.c:221
+#: plugins/sudoers/timestamp.c:242
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "αδύνατο το mkdir %s"
+
+#: plugins/sudoers/iolog.c:190 plugins/sudoers/sudoers.c:710
+#: plugins/sudoers/sudoreplay.c:342 plugins/sudoers/sudoreplay.c:813
+#: plugins/sudoers/sudoreplay.c:1010 plugins/sudoers/timestamp.c:345
+#: plugins/sudoers/visudo.c:823 plugins/sudoers/visudo_json.c:995
+#: plugins/sudoers/visudo_json.c:1001
+#, c-format
+msgid "unable to open %s"
+msgstr "αδύνατο το άνοιγμα του %s"
+
+#: plugins/sudoers/iolog.c:229 plugins/sudoers/sudoers.c:713
+#: plugins/sudoers/sudoreplay.c:1117
+#, c-format
+msgid "unable to read %s"
+msgstr "αδύνατη η ανάγνωση του %s"
+
+#: plugins/sudoers/iolog.c:259 plugins/sudoers/sudoreplay.c:582
+#: plugins/sudoers/timestamp.c:184
+#, c-format
+msgid "unable to write to %s"
+msgstr "αδύνατη η εγγραφή σε %s"
+
+#: plugins/sudoers/iolog.c:319 plugins/sudoers/iolog.c:512
+#, c-format
+msgid "unable to create %s"
+msgstr "αδύνατη η δημιουργία του %s"
+
+#: plugins/sudoers/ldap.c:406
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: υπερβολικά μεγάλη θύρα"
+
+#: plugins/sudoers/ldap.c:429
+msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+msgstr "sudo_ldap_conf_add_ports: εκτός χώρου επέκτασης hostbuf"
+
+#: plugins/sudoers/ldap.c:461
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "ανυποστήρικτος τύπος LDAP uri: %s"
+
+#: plugins/sudoers/ldap.c:492
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "αδύνατη η ανάμιξη URIs ldap και ldaps"
+
+#: plugins/sudoers/ldap.c:496 plugins/sudoers/ldap.c:528
+msgid "starttls not supported when using ldaps"
+msgstr "το starttls δεν υποστηρίζεται όταν χρησιμοποιείται το ldaps"
+
+#: plugins/sudoers/ldap.c:514
+msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+msgstr "sudo_ldap_parse_uri: εκτός χώρου δόμησης του hostbuf"
+
+#: plugins/sudoers/ldap.c:595
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "αδύνατη η αρχικοποίηση των cert SSL και db κλειδιών: %s"
+
+#: plugins/sudoers/ldap.c:598
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "πρέπει να ορίσετε το TLS_CERT σε %s για να χρησιμοποιήσετε το SSL"
+
+#: plugins/sudoers/ldap.c:1089
+msgid "unable to get GMT time"
+msgstr "αδύνατη η λήψη χρόνου GMT"
+
+#: plugins/sudoers/ldap.c:1095
+msgid "unable to format timestamp"
+msgstr "αδύνατη η μορφοποίηση της χρονικής σήμανσης"
+
+#: plugins/sudoers/ldap.c:1103
+msgid "unable to build time filter"
+msgstr "αδύνατη η δόμηση φίλτρου χρόνου"
+
+#: plugins/sudoers/ldap.c:1322
+msgid "sudo_ldap_build_pass1 allocation mismatch"
+msgstr "ασυμφωνία κατανομής sudo_ldap_build_pass1"
+
+#: plugins/sudoers/ldap.c:1433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/ldap.c:1909
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"Ρόλος LDAP: %s\n"
+
+#: plugins/sudoers/ldap.c:1911
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"Ρόλος LDAP: ΑΓΝΩΣΤΟΣ\n"
+
+#: plugins/sudoers/ldap.c:1958
+#, c-format
+msgid " Order: %s\n"
+msgstr " Σειρά: %s\n"
+
+#: plugins/sudoers/ldap.c:1966 plugins/sudoers/parse.c:504
+#: plugins/sudoers/sssd.c:1295
+#, c-format
+msgid " Commands:\n"
+msgstr " Εντολές:\n"
+
+#: plugins/sudoers/ldap.c:2509
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "αδύνατη η αρχικοποίηση του LDAP: %s"
+
+#: plugins/sudoers/ldap.c:2551
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "ορίστηκε το start_tls, αλλά οι βιβλιοθήκες LDAP υποστηρίζουν ldap_start_tls_s() ή ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:2784
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "άκυρο γνώρισμα sudoOrder: %s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "αδύνατο το άνοιγμα συστήματος ελέγχου"
+
+#: plugins/sudoers/linux_audit.c:93
+msgid "unable to send audit message"
+msgstr "αδύνατη η αποστολή μηνύματος ελέγχου"
+
+#: plugins/sudoers/logging.c:136
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:164
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (συνεχιζόμενη εντολή) %s"
+
+#: plugins/sudoers/logging.c:189
+#, c-format
+msgid "unable to open log file: %s: %s"
+msgstr "αδύνατο το άνοιγμα αρχείου καταγραφής: %s: %s"
+
+#: plugins/sudoers/logging.c:192
+#, c-format
+msgid "unable to lock log file: %s: %s"
+msgstr "αδύνατο το κλείδωμα αρχείου καταγραφής: %s: %s"
+
+#: plugins/sudoers/logging.c:243
+msgid "No user or host"
+msgstr "Χωρίς χρήστη ή οικοδεσπότη"
+
+#: plugins/sudoers/logging.c:245
+msgid "validation failure"
+msgstr "αποτυχία επικύρωσης"
+
+#: plugins/sudoers/logging.c:252
+msgid "user NOT in sudoers"
+msgstr "ο χρήστης ΔΕΝ είναι στους sudo"
+
+#: plugins/sudoers/logging.c:254
+msgid "user NOT authorized on host"
+msgstr "ο χρήστης ΔΕΝ εξουσιοδοτήθηκε στον οικοδεσπότη"
+
+#: plugins/sudoers/logging.c:256
+msgid "command not allowed"
+msgstr "μη επιτρεπόμενη εντολή"
+
+#: plugins/sudoers/logging.c:286
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "το %s δεν είναι στο αρχείο χρηστών sudo. Αυτό το συμβάν θα αναφερθεί.\n"
+
+#: plugins/sudoers/logging.c:289
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "ο %s δεν επιτρέπεται να εκτελέσει sudo στο %s. Αυτό το συμβάν θα αναφερθεί.\n"
+
+#: plugins/sudoers/logging.c:293
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Συγνώμη, ο χρήστης %s δεν μπορεί να εκτελέσει sudo στο %s.\n"
+
+#: plugins/sudoers/logging.c:296
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Συγνώμη, ο χρήστης %s δεν επιτρέπεται να εκτελέσει '%s%s%s' ως %s%s%s στο %s.\n"
+
+#: plugins/sudoers/logging.c:333 plugins/sudoers/sudoers.c:382
+#: plugins/sudoers/sudoers.c:383 plugins/sudoers/sudoers.c:385
+#: plugins/sudoers/sudoers.c:386 plugins/sudoers/sudoers.c:1017
+#: plugins/sudoers/sudoers.c:1018
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: δεν βρέθηκε η εντολή"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:378
+#, c-format
+msgid ""
+"ignoring `%s' found in '.'\n"
+"Use `sudo ./%s' if this is the `%s' you wish to run."
+msgstr ""
+"παραβλέπεται το `%s' που βρέθηκε στο '.'\n"
+"Χρησιμοποιήστε `sudo ./%s' αν αυτό είναι το `%s' που θέλετε να εκτελέσετε."
+
+#: plugins/sudoers/logging.c:351
+msgid "authentication failure"
+msgstr "αποτυχία πιστοποίησης"
+
+#: plugins/sudoers/logging.c:377
+msgid "a password is required"
+msgstr "απαιτείται κωδικός πρόσβασης"
+
+#: plugins/sudoers/logging.c:441 plugins/sudoers/logging.c:495
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u ανεπιτυχής προσπάθεια κωδικού πρόσβασης"
+msgstr[1] "%u ανεπιτυχείς προσπάθειες κωδικού πρόσβασης"
+
+#: plugins/sudoers/logging.c:581
+msgid "unable to fork"
+msgstr "αδύνατη η διακλάδωση"
+
+#: plugins/sudoers/logging.c:588 plugins/sudoers/logging.c:644
+#, c-format
+msgid "unable to fork: %m"
+msgstr "αδύνατη η διακλάδωση: %m"
+
+#: plugins/sudoers/logging.c:634
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "αδύνατο το άνοιγμα της διοχέτευσης: %m"
+
+#: plugins/sudoers/logging.c:659
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "αδύνατο να dup στην τυπική είσοδο: %m"
+
+#: plugins/sudoers/logging.c:694
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "αδύνατη η εκτέλεση %s: %m"
+
+#: plugins/sudoers/logging.c:914
+msgid "internal error: insufficient space for log line"
+msgstr "εσωτερικό σφάλμα: ανεπαρκής χώρος για γραμμή καταγραφής"
+
+#: plugins/sudoers/match.c:617
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "ανυποστήρικτος τύπος αφομοίωσης %d για %s"
+
+#: plugins/sudoers/match.c:647
+#, c-format
+msgid "%s: read error"
+msgstr "%s: σφάλμα ανάγνωσης"
+
+#: plugins/sudoers/match.c:661
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "η αφομοίωση για το %s (%s) δεν είναι στη μορφή %s"
+
+#: plugins/sudoers/parse.c:115
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "σφάλμα ανάλυσης στο %s κοντά στη γραμμή %d"
+
+#: plugins/sudoers/parse.c:118
+#, c-format
+msgid "parse error in %s"
+msgstr "ανάλυση σφάλματος για %s"
+
+#: plugins/sudoers/parse.c:451
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Καταχώριση χρηστών sudo:\n"
+
+#: plugins/sudoers/parse.c:452
+#, c-format
+msgid " RunAsUsers: "
+msgstr " RunAsUsers: "
+
+#: plugins/sudoers/parse.c:466
+#, c-format
+msgid " RunAsGroups: "
+msgstr " RunAsGroups: "
+
+#: plugins/sudoers/parse.c:475
+#, c-format
+msgid " Options: "
+msgstr " Επιλογές: "
+
+#: plugins/sudoers/policy.c:109 plugins/sudoers/policy.c:116
+#: plugins/sudoers/policy.c:123 plugins/sudoers/policy.c:145
+#: plugins/sudoers/policy.c:259 plugins/sudoers/policy.c:277
+#: plugins/sudoers/policy.c:284 plugins/sudoers/policy.c:312
+#: plugins/sudoers/policy.c:320 plugins/sudoers/policy.c:327
+#: plugins/sudoers/set_perms.c:363 plugins/sudoers/set_perms.c:702
+#: plugins/sudoers/set_perms.c:1061 plugins/sudoers/set_perms.c:1357
+#: plugins/sudoers/set_perms.c:1525
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/policy.c:539 plugins/sudoers/visudo.c:764
+#, c-format
+msgid "unable to execute %s"
+msgstr "Αδύνατη η εκτέλεση του %s."
+
+#: plugins/sudoers/policy.c:681
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Η έκδοση προσθέτου πολιτικής χρηστών sudo %s\n"
+
+#: plugins/sudoers/policy.c:683
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Η έκδοση γραμματικής αρχείου χρηστών sudo %d\n"
+
+#: plugins/sudoers/policy.c:687
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"διαδρομή χρηστών sudo: %s\n"
+
+#: plugins/sudoers/policy.c:690
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "διαδρομή nsswitch: %s\n"
+
+#: plugins/sudoers/policy.c:692
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "διαδρομή ldap.conf: %s\n"
+
+#: plugins/sudoers/policy.c:693
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "διαδρομή ldap.secret: %s\n"
+
+#: plugins/sudoers/pwutil.c:148
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "αδύνατη η αποθήκευση του uid %u, υπάρχει ήδη"
+
+#: plugins/sudoers/pwutil.c:190
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "αδύνατη η αποθήκευση του %s χρήστη, υπάρχει ήδη"
+
+#: plugins/sudoers/pwutil.c:393
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "αδύνατη η αποθήκευση του gid %u, υπάρχει ήδη"
+
+#: plugins/sudoers/pwutil.c:429
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "αδύνατη η αποθήκευση ομάδας %s, υπάρχει ήδη"
+
+#: plugins/sudoers/pwutil.c:592 plugins/sudoers/pwutil.c:614
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "αδύνατη η αποθήκευση καταλόγου ομάδας %s, υπάρχει ήδη"
+
+#: plugins/sudoers/pwutil.c:612
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "αδύνατη η ανάλυση ομάδων για %s"
+
+#: plugins/sudoers/set_perms.c:124 plugins/sudoers/set_perms.c:449
+#: plugins/sudoers/set_perms.c:852 plugins/sudoers/set_perms.c:1149
+#: plugins/sudoers/set_perms.c:1441
+msgid "perm stack overflow"
+msgstr "υπερχείλιση στοίβας perm"
+
+#: plugins/sudoers/set_perms.c:132 plugins/sudoers/set_perms.c:457
+#: plugins/sudoers/set_perms.c:860 plugins/sudoers/set_perms.c:1157
+#: plugins/sudoers/set_perms.c:1449
+msgid "perm stack underflow"
+msgstr "υποχείλιση στοίβας perm"
+
+#: plugins/sudoers/set_perms.c:191 plugins/sudoers/set_perms.c:504
+#: plugins/sudoers/set_perms.c:1208 plugins/sudoers/set_perms.c:1481
+msgid "unable to change to root gid"
+msgstr "αδύνατη η αλλαγή σε gid υπερχρήστη"
+
+#: plugins/sudoers/set_perms.c:280 plugins/sudoers/set_perms.c:601
+#: plugins/sudoers/set_perms.c:989 plugins/sudoers/set_perms.c:1285
+msgid "unable to change to runas gid"
+msgstr "αδύνατη η αλλαγή σε gid runas"
+
+#: plugins/sudoers/set_perms.c:292 plugins/sudoers/set_perms.c:613
+#: plugins/sudoers/set_perms.c:999 plugins/sudoers/set_perms.c:1295
+msgid "unable to change to runas uid"
+msgstr "αδύνατη η αλλαγή σε uid runas"
+
+#: plugins/sudoers/set_perms.c:310 plugins/sudoers/set_perms.c:631
+#: plugins/sudoers/set_perms.c:1015 plugins/sudoers/set_perms.c:1311
+msgid "unable to change to sudoers gid"
+msgstr "αδύνατη η αλλαγή σε gid χρηστών sudo"
+
+#: plugins/sudoers/set_perms.c:363 plugins/sudoers/set_perms.c:702
+#: plugins/sudoers/set_perms.c:1061 plugins/sudoers/set_perms.c:1357
+#: plugins/sudoers/set_perms.c:1525
+msgid "too many processes"
+msgstr "υπερβολικά πολλές διεργασίες"
+
+#: plugins/sudoers/set_perms.c:1595
+msgid "unable to set runas group vector"
+msgstr "αδύνατος ο ορισμός διανύσματος ομάδας runas"
+
+#: plugins/sudoers/sssd.c:252
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "αδύνατη η αρχικοποίηση πηγής SSS. Είναι το SSSD εγκατεστημένο στο μηχάνημά σας;"
+
+#: plugins/sudoers/sssd.c:259 plugins/sudoers/sssd.c:267
+#: plugins/sudoers/sssd.c:275 plugins/sudoers/sssd.c:283
+#: plugins/sudoers/sssd.c:291
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "αδύνατη η εύρεση συμβόλου \"%s\" στο %s"
+
+#: plugins/sudoers/sudo_nss.c:283
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Συμφωνία προεπιλεγμένων καταχωρίσεων για %s στο %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:296
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Runas και προεπιλεγμένες ειδικές εντολές για το %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:309
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Ο χρήστης %s μπορεί να εκτελέσει τις παρακάτω εντολές στο %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:318
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Ο χρήστης %s δεν επιτρέπεται να εκτελέσει sudo στο %s.\n"
+
+#: plugins/sudoers/sudoers.c:154 plugins/sudoers/sudoers.c:188
+#: plugins/sudoers/sudoers.c:675
+msgid "problem with defaults entries"
+msgstr "πρόβλημα με τις προεπιλεγμένες καταχωρίσεις"
+
+#: plugins/sudoers/sudoers.c:160
+msgid "no valid sudoers sources found, quitting"
+msgstr "δεν βρέθηκαν έγκυρες πηγές χρηστών sudo, έξοδος"
+
+#: plugins/sudoers/sudoers.c:222
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "οι χρήστες sudo καθορίζουν ότι ο υπερχρήστης δεν επιτρέπεται να εκτελέσει sudo"
+
+#: plugins/sudoers/sudoers.c:261
+msgid "you are not permitted to use the -C option"
+msgstr "δεν επιτρέπετε να χρησιμοποιήσετε την επιλογή -C"
+
+#: plugins/sudoers/sudoers.c:314
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "κάτοχος χρονικής σήμανσης (%s): Δεν υπάρχει τέτοιος χρήστης"
+
+#: plugins/sudoers/sudoers.c:328
+msgid "no tty"
+msgstr "χωρίς tty"
+
+#: plugins/sudoers/sudoers.c:329
+msgid "sorry, you must have a tty to run sudo"
+msgstr "συγνώμη, πρέπει να έχετε ένα tty για να εκτελέσετε sudo"
+
+#: plugins/sudoers/sudoers.c:377
+msgid "command in current directory"
+msgstr "εντολή στο τρέχοντα κατάλογο"
+
+#: plugins/sudoers/sudoers.c:394
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "συγνώμη, δεν σας επιτρέπεται να διατηρήσετε το περιβάλλον"
+
+#: plugins/sudoers/sudoers.c:725 plugins/sudoers/visudo.c:326
+#: plugins/sudoers/visudo.c:590
+#, c-format
+msgid "unable to stat %s"
+msgstr "αδύνατο να εκτελεστεί stat %s"
+
+#: plugins/sudoers/sudoers.c:728
+#, c-format
+msgid "%s is not a regular file"
+msgstr "το %s δεν είναι ένα κανονικό αρχείο"
+
+#: plugins/sudoers/sudoers.c:731 plugins/sudoers/timestamp.c:283 toke.l:923
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "το %s κατέχεται από uid %u, θα έπρεπε να είναι %u"
+
+#: plugins/sudoers/sudoers.c:735 toke.l:930
+#, c-format
+msgid "%s is world writable"
+msgstr "Το %s είναι εγγράψιμο από όλους"
+
+#: plugins/sudoers/sudoers.c:738 toke.l:935
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "το %s κατέχεται από gid %u, θα έπρεπε να είναι %u"
+
+#: plugins/sudoers/sudoers.c:764
+#, c-format
+msgid "only root can use `-c %s'"
+msgstr "μόνο ο υπερχρήστης μπορεί να χρησιμοποιήσει `-c %s'"
+
+#: plugins/sudoers/sudoers.c:781 plugins/sudoers/sudoers.c:783
+#, c-format
+msgid "unknown login class: %s"
+msgstr "άγνωστη κλάση σύνδεσης: %s"
+
+#: plugins/sudoers/sudoers.c:815
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "αδύνατη η επίλυση οικοδεσπότη %s"
+
+#: plugins/sudoers/sudoers.c:878 plugins/sudoers/testsudoers.c:387
+#, c-format
+msgid "unknown group: %s"
+msgstr "άγνωστη ομάδα: %s"
+
+#: plugins/sudoers/sudoreplay.c:274
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "άκυρη επιλογή φίλτρου: %s"
+
+#: plugins/sudoers/sudoreplay.c:287
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "άκυρη μέγιστη αναμονή: %s"
+
+#: plugins/sudoers/sudoreplay.c:293
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "άκυρος συντελεστής ταχύτητας: %s"
+
+#: plugins/sudoers/sudoreplay.c:296 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s έκδοση %s\n"
+
+#: plugins/sudoers/sudoreplay.c:328
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/χρονισμός: %s"
+
+#: plugins/sudoers/sudoreplay.c:334
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/χρονισμός: %s"
+
+#: plugins/sudoers/sudoreplay.c:350
+#, c-format
+msgid "Replaying sudo session: %s\n"
+msgstr "Αναπαράγεται η συνεδρία sudo: %s\n"
+
+#: plugins/sudoers/sudoreplay.c:356
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Προειδοποίηση: το τερματικό σας είναι υπερβολικά μικρό για σωστή επανάληψη του ημερολογίου.\n"
+
+#: plugins/sudoers/sudoreplay.c:357
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Η γεωμετρία του ημερολογίου είναι %d x %d, η γεωμετρία του τερματικού σας είναι %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:412
+msgid "unable to set tty to raw mode"
+msgstr "αδύνατος ο ορισμός σε ακατέργαστη κατάσταση"
+
+#: plugins/sudoers/sudoreplay.c:443
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "άκυρη γραμμή αρχείου χρονισμού: %s"
+
+#: plugins/sudoers/sudoreplay.c:649 plugins/sudoers/sudoreplay.c:674
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "ασαφής παράσταση \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:696
+msgid "unmatched ')' in expression"
+msgstr "ασύμφωνο ')' σε παράσταση"
+
+#: plugins/sudoers/sudoreplay.c:700
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "άγνωστος όρος αναζήτησης \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:714
+#, c-format
+msgid "%s requires an argument"
+msgstr "το %s απαιτεί ένα όρισμα"
+
+#: plugins/sudoers/sudoreplay.c:718 plugins/sudoers/sudoreplay.c:1090
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "άκυρη κανονική έκφραση: %s"
+
+#: plugins/sudoers/sudoreplay.c:724
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "αδύνατη η ανάλυση ημερομηνίας \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:733
+msgid "unmatched '(' in expression"
+msgstr "ασύμφωνο '(' σε παράσταση"
+
+#: plugins/sudoers/sudoreplay.c:735
+msgid "illegal trailing \"or\""
+msgstr "απαράδεκτο τελικό \"or\""
+
+#: plugins/sudoers/sudoreplay.c:737
+msgid "illegal trailing \"!\""
+msgstr "απαράδεκτο τελικό \"!\""
+
+#: plugins/sudoers/sudoreplay.c:790
+#, c-format
+msgid "unknown search type %d"
+msgstr "άγνωστος τύπος αναζήτησης %d"
+
+#: plugins/sudoers/sudoreplay.c:827
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: άκυρο αρχείο ημερολογίου"
+
+#: plugins/sudoers/sudoreplay.c:845
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: το πεδίο σήμανσης χρόνου λείπει"
+
+#: plugins/sudoers/sudoreplay.c:852
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: η σήμανση χρόνου %s: %s"
+
+#: plugins/sudoers/sudoreplay.c:859
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: το πεδίο χρήστη λείπει"
+
+#: plugins/sudoers/sudoreplay.c:867
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: το πεδίο χρήστη runas λείπει"
+
+#: plugins/sudoers/sudoreplay.c:875
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: το πεδίο ομάδας runas λείπει"
+
+#: plugins/sudoers/sudoreplay.c:1230
+#, c-format
+msgid "usage: %s [-h] [-d dir] [-m num] [-s num] ID\n"
+msgstr "χρήση: %s [-h] [-d dir] [-m num] [-s num] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1233
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "χρήση: %s [-h] [-d dir] -l [παράσταση αναζήτησης]\n"
+
+#: plugins/sudoers/sudoreplay.c:1242
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - επανάληψη ημερολογίων συνεδρίας sudo\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1244
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Επιλογές:\n"
+" -d, --directory=κατάλογος καθορισμός καταλόγου για ημερολόγια συνεδρίας\n"
+" -f, --filter=φίλτρο ορισμός ποιοι τύποι εισόδου/εξόδου να εμφανίζονται\n"
+" -h, --help εμφάνιση μηνύματος βοήθειας και έξοδος\n"
+" -l, --list κατάλογος διαθέσιμων αναγνωριστικών συνεδρίας, με προαιρετική παράσταση\n"
+" -m, --max-wait=αριθ μέγιστος αριθμός δευτερολέπτων αναμονής μεταξύ συμβάντων\n"
+" -s, --speed=αριθ επιτάχυνση ή επιβράδυνση εξόδου\n"
+" -V, --version εμφάνιση πληροφοριών έκδοσης και έξοδος"
+
+#: plugins/sudoers/testsudoers.c:326
+msgid "\thost unmatched"
+msgstr " ασύμφωνος οικοδεσπότης"
+
+#: plugins/sudoers/testsudoers.c:329
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Επιτρεπόμενη εντολή"
+
+#: plugins/sudoers/testsudoers.c:330
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Απαγορευμένη εντολή"
+
+#: plugins/sudoers/testsudoers.c:330
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"ασύμφωνη εντολή"
+
+#: plugins/sudoers/timestamp.c:191
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "αδύνατη η περικοπή αρχείου σήμανσης χρόνου σε %lld ψηφιολέξεις"
+
+#: plugins/sudoers/timestamp.c:291
+#, c-format
+msgid "%s is group writable"
+msgstr "το %s είναι εγγράψιμη ομάδα"
+
+#: plugins/sudoers/timestamp.c:311
+#, c-format
+msgid "timestamp path too long: %s/%s"
+msgstr "η διαδρομή χρονικής σήμανσης είναι υπερβολικά μεγάλη: %s/%s"
+
+#: plugins/sudoers/timestamp.c:484
+msgid "ignoring time stamp from the future"
+msgstr "να αγνοείται η χρονική σήμανση στο μέλλον"
+
+#: plugins/sudoers/timestamp.c:496
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "η χρονική σήμανση υπερβολικά μακρινή στο μέλλον: %20.20s"
+
+#: plugins/sudoers/timestamp.c:596 plugins/sudoers/timestamp.c:618
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "η διαδρομή κατάστασης οδηγίας υπερβολικά μεγάλη: %s/%s"
+
+#: plugins/sudoers/toke_util.c:176
+msgid "fill_args: buffer overflow"
+msgstr "fill_args: υπερχείλιση ενδιάμεσης μνήμης"
+
+#: plugins/sudoers/visudo.c:186
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "γραμματική %s έκδοση %d\n"
+
+#: plugins/sudoers/visudo.c:257 plugins/sudoers/visudo.c:543
+#, c-format
+msgid "press return to edit %s: "
+msgstr "πατήστε return για να επεξεργαστείτε το %s: "
+
+#: plugins/sudoers/visudo.c:342 plugins/sudoers/visudo.c:348
+msgid "write error"
+msgstr "σφάλμα εγγραφής"
+
+#: plugins/sudoers/visudo.c:430
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "αδύνατη η εκτέλεση stat προσωρινού αρχείου (%s), το %s δεν άλλαξε"
+
+#: plugins/sudoers/visudo.c:435
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "προσωρινό αρχείο μηδενικού μήκους (%s), το %s αμετάβλητο"
+
+#: plugins/sudoers/visudo.c:441
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "αποτυχία επεξεργασίας του (%s), το %s αμετάβλητο"
+
+#: plugins/sudoers/visudo.c:463
+#, c-format
+msgid "%s unchanged"
+msgstr "αμετάβλητο %s"
+
+#: plugins/sudoers/visudo.c:488
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "αδύνατο το ξαναάνοιγμα του προσωρινού αρχείου (%s), το %s αμετάβλητο"
+
+#: plugins/sudoers/visudo.c:498
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "αδύνατη η ανάλυση του προσωρινού αρχείου (%s), άγνωστο σφάλμα"
+
+#: plugins/sudoers/visudo.c:534
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "εσωτερικό σφάλμα, αδύνατη η εύρεση του %s στον κατάλογο!"
+
+#: plugins/sudoers/visudo.c:592 plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "αδύνατος ο ορισμός (uid, gid) του %s στο (%u, %u)"
+
+#: plugins/sudoers/visudo.c:596 plugins/sudoers/visudo.c:606
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "αδύνατη η αλλαγή κατάστασης του %s στο 0%o"
+
+#: plugins/sudoers/visudo.c:623
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "τα %s και %s δεν έχουν το ίδιο σύστημα αρχείων, χρησιμοποιήστε το mv για μετονομασία"
+
+#: plugins/sudoers/visudo.c:637
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "αποτυχία εντολής: '%s %s %s', το %s αμετάβλητο"
+
+#: plugins/sudoers/visudo.c:647
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "σφάλμα μετονομασίας του %s, το %s αμετάβλητο"
+
+#: plugins/sudoers/visudo.c:709
+msgid "What now? "
+msgstr "Τι να γίνει τώρα; "
+
+#: plugins/sudoers/visudo.c:723
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Οι επιλογές είναι:\n"
+" (e)dit νέα επεξεργασία του αρχείου χρηστών sudo\n"
+" e(x)it έξοδος χωρίς αποθήκευση αλλαγών στο αρχείο χρηστών sudo\n"
+" (Q)uit έξοδος και αποθήκευση αλλαγών στο αρχείο χρηστών sudo (ΚΙΝΔΥΝΟΣ!)\n"
+
+#: plugins/sudoers/visudo.c:771
+#, c-format
+msgid "unable to run %s"
+msgstr "αδύνατη η εκτέλεση του %s"
+
+#: plugins/sudoers/visudo.c:797
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: εσφαλμένος κάτοχος (uid, gid) πρέπει να είναι (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:804
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: εσφαλμένα δικαιώματα, πρέπει να είναι κατάσταση 0%o\n"
+
+#: plugins/sudoers/visudo.c:829 plugins/sudoers/visudo_json.c:1008
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "αποτυχία ανάλυσης αρχείου %s, άγνωστο σφάλμα"
+
+#: plugins/sudoers/visudo.c:845 plugins/sudoers/visudo_json.c:1017
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "ανάλυση σφάλματος στο %s κοντά στη γραμμή %d\n"
+
+#: plugins/sudoers/visudo.c:848 plugins/sudoers/visudo_json.c:1020
+#, c-format
+msgid "parse error in %s\n"
+msgstr "ανάλυση σφάλματος %s\n"
+
+#: plugins/sudoers/visudo.c:856 plugins/sudoers/visudo.c:863
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: επιτυχής ανάλυση\n"
+
+#: plugins/sudoers/visudo.c:909
+#, c-format
+msgid "%s busy, try again later"
+msgstr "το %s είναι απασχολημένο, ξαναδοκιμάστε αργότερα"
+
+#: plugins/sudoers/visudo.c:953
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "ο συγκεκριμένος επεξεργαστής (%s) δεν υπάρχει"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "unable to stat editor (%s)"
+msgstr "αδύνατο να εκτελέσουμε stat στον επεξεργαστή (%s)"
+
+#: plugins/sudoers/visudo.c:1024
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "δεν βρέθηκε κανένας επεξεργαστής (διαδρομή επεξεργαστή = %s)"
+
+#: plugins/sudoers/visudo.c:1117
+#, c-format
+msgid "Error: cycle in %s_Alias `%s'"
+msgstr "Σφάλμα: κύκλος στο %s_Alias `%s'"
+
+#: plugins/sudoers/visudo.c:1118
+#, c-format
+msgid "Warning: cycle in %s_Alias `%s'"
+msgstr "Προειδοποίηση: κύκλος στο %s_Alias `%s'"
+
+#: plugins/sudoers/visudo.c:1124
+#, c-format
+msgid "Error: %s_Alias `%s' referenced but not defined"
+msgstr "Σφάλμα: αναφέρθηκε το %s_Alias `%s', αλλά δεν ορίστηκε"
+
+#: plugins/sudoers/visudo.c:1125
+#, c-format
+msgid "Warning: %s_Alias `%s' referenced but not defined"
+msgstr "Προειδοποίηση: αναφέρθηκε το %s_Alias `%s', αλλά δεν ορίστηκε"
+
+#: plugins/sudoers/visudo.c:1267
+#, c-format
+msgid "%s: unused %s_Alias %s"
+msgstr "%s: αχρησιμοποίητο %s_Alias %s"
+
+#: plugins/sudoers/visudo.c:1329
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - ασφαλής επεξεργασία του αρχείου χρηστών sudo\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1331
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=file specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+" -x, --export=file export sudoers in JSON format"
+msgstr ""
+"\n"
+"Επιλογές:\n"
+" -c, --check κατάσταση μόνο ελέγχου\n"
+" -f, --file=αρχείο καθορισμός θέσης αρχείου χρηστών sudo\n"
+" -h, --help εμφάνιση μηνύματος βοήθειας και έξοδος\n"
+" -q, --quiet λιγότερο αναλυτική (αθόρυβη) σύνταξη μηνυμάτων σφαλμάτων\n"
+" -s, --strict αυστηρός έλεγχος σύνταξης\n"
+" -V, --version εμφάνιση πληροφοριών έκδοσης και έξοδος\n"
+" -x, --export=αρχείο εξαγωγή χρηστών sudo σε μορφή JSON"
+
+#: toke.l:894
+msgid "too many levels of includes"
+msgstr "περιλαμβάνει υπερβολικά πολλά επίπεδα"
diff --git a/plugins/sudoers/po/eo.mo b/plugins/sudoers/po/eo.mo
new file mode 100644
index 0000000..5433dd2
--- /dev/null
+++ b/plugins/sudoers/po/eo.mo
Binary files differ
diff --git a/plugins/sudoers/po/eo.po b/plugins/sudoers/po/eo.po
new file mode 100644
index 0000000..143439e
--- /dev/null
+++ b/plugins/sudoers/po/eo.po
@@ -0,0 +1,2347 @@
+# Esperanto translations for sudo package.
+# This file is put in the public domain.
+# Felipe Castro <fefcas@gmail.com>, 2013, 2014, 2015, 2016, 2017, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.24b2\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-07-31 07:13-0600\n"
+"PO-Revision-Date: 2018-08-06 20:03-0300\n"
+"Last-Translator: Felipe Castro <fefcas@gmail.com>\n"
+"Language-Team: Esperanto <translation-team-eo@lists.sourceforge.net>\n"
+"Language: eo\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.8.7.1\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "sintaksa eraro"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "Pasvorto de %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] pasvorto por %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Pasvorto: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** SEKURECO: informoj por %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Malĝuste. Reprovu."
+
+#: gram.y:194 gram.y:242 gram.y:249 gram.y:256 gram.y:263 gram.y:270
+#: gram.y:286 gram.y:310 gram.y:317 gram.y:324 gram.y:331 gram.y:338
+#: gram.y:401 gram.y:409 gram.y:419 gram.y:452 gram.y:459 gram.y:466
+#: gram.y:473 gram.y:555 gram.y:562 gram.y:571 gram.y:580 gram.y:597
+#: gram.y:709 gram.y:716 gram.y:723 gram.y:731 gram.y:831 gram.y:838
+#: gram.y:845 gram.y:852 gram.y:859 gram.y:885 gram.y:892 gram.y:899
+#: gram.y:1022 gram.y:1296 plugins/sudoers/alias.c:122
+#: plugins/sudoers/alias.c:129 plugins/sudoers/alias.c:145
+#: plugins/sudoers/auth/bsdauth.c:141 plugins/sudoers/auth/kerb5.c:119
+#: plugins/sudoers/auth/kerb5.c:145 plugins/sudoers/auth/pam.c:519
+#: plugins/sudoers/auth/rfc1938.c:109 plugins/sudoers/auth/sia.c:59
+#: plugins/sudoers/cvtsudoers.c:116 plugins/sudoers/cvtsudoers.c:157
+#: plugins/sudoers/cvtsudoers.c:174 plugins/sudoers/cvtsudoers.c:185
+#: plugins/sudoers/cvtsudoers.c:278 plugins/sudoers/cvtsudoers.c:405
+#: plugins/sudoers/cvtsudoers.c:538 plugins/sudoers/cvtsudoers.c:555
+#: plugins/sudoers/cvtsudoers.c:660 plugins/sudoers/cvtsudoers.c:773
+#: plugins/sudoers/cvtsudoers.c:781 plugins/sudoers/cvtsudoers.c:1186
+#: plugins/sudoers/cvtsudoers.c:1190 plugins/sudoers/cvtsudoers.c:1290
+#: plugins/sudoers/cvtsudoers_ldif.c:147 plugins/sudoers/cvtsudoers_ldif.c:189
+#: plugins/sudoers/cvtsudoers_ldif.c:236 plugins/sudoers/cvtsudoers_ldif.c:255
+#: plugins/sudoers/cvtsudoers_ldif.c:325 plugins/sudoers/cvtsudoers_ldif.c:380
+#: plugins/sudoers/cvtsudoers_ldif.c:388 plugins/sudoers/cvtsudoers_ldif.c:405
+#: plugins/sudoers/cvtsudoers_ldif.c:414 plugins/sudoers/cvtsudoers_ldif.c:560
+#: plugins/sudoers/cvtsudoers_ldif.c:753 plugins/sudoers/cvtsudoers_ldif.c:780
+#: plugins/sudoers/cvtsudoers_ldif.c:848 plugins/sudoers/cvtsudoers_ldif.c:855
+#: plugins/sudoers/cvtsudoers_ldif.c:860 plugins/sudoers/cvtsudoers_ldif.c:936
+#: plugins/sudoers/cvtsudoers_ldif.c:947 plugins/sudoers/cvtsudoers_ldif.c:953
+#: plugins/sudoers/cvtsudoers_ldif.c:978 plugins/sudoers/cvtsudoers_ldif.c:990
+#: plugins/sudoers/cvtsudoers_ldif.c:994
+#: plugins/sudoers/cvtsudoers_ldif.c:1008
+#: plugins/sudoers/cvtsudoers_ldif.c:1176
+#: plugins/sudoers/cvtsudoers_ldif.c:1208
+#: plugins/sudoers/cvtsudoers_ldif.c:1233
+#: plugins/sudoers/cvtsudoers_ldif.c:1262
+#: plugins/sudoers/cvtsudoers_ldif.c:1312
+#: plugins/sudoers/cvtsudoers_ldif.c:1358
+#: plugins/sudoers/cvtsudoers_ldif.c:1368 plugins/sudoers/defaults.c:656
+#: plugins/sudoers/defaults.c:952 plugins/sudoers/defaults.c:1123
+#: plugins/sudoers/editor.c:65 plugins/sudoers/editor.c:83
+#: plugins/sudoers/editor.c:94 plugins/sudoers/env.c:233
+#: plugins/sudoers/filedigest.c:61 plugins/sudoers/filedigest.c:77
+#: plugins/sudoers/gc.c:52 plugins/sudoers/group_plugin.c:131
+#: plugins/sudoers/interfaces.c:71 plugins/sudoers/iolog.c:938
+#: plugins/sudoers/iolog_path.c:167 plugins/sudoers/ldap.c:177
+#: plugins/sudoers/ldap.c:408 plugins/sudoers/ldap.c:412
+#: plugins/sudoers/ldap.c:424 plugins/sudoers/ldap.c:715
+#: plugins/sudoers/ldap.c:879 plugins/sudoers/ldap.c:1228
+#: plugins/sudoers/ldap.c:1654 plugins/sudoers/ldap.c:1691
+#: plugins/sudoers/ldap.c:1771 plugins/sudoers/ldap.c:1906
+#: plugins/sudoers/ldap.c:2007 plugins/sudoers/ldap.c:2023
+#: plugins/sudoers/ldap_conf.c:214 plugins/sudoers/ldap_conf.c:245
+#: plugins/sudoers/ldap_conf.c:297 plugins/sudoers/ldap_conf.c:333
+#: plugins/sudoers/ldap_conf.c:422 plugins/sudoers/ldap_conf.c:437
+#: plugins/sudoers/ldap_conf.c:533 plugins/sudoers/ldap_conf.c:566
+#: plugins/sudoers/ldap_conf.c:647 plugins/sudoers/ldap_conf.c:729
+#: plugins/sudoers/ldap_util.c:519 plugins/sudoers/ldap_util.c:575
+#: plugins/sudoers/linux_audit.c:76 plugins/sudoers/logging.c:190
+#: plugins/sudoers/logging.c:506 plugins/sudoers/logging.c:527
+#: plugins/sudoers/logging.c:568 plugins/sudoers/logging.c:745
+#: plugins/sudoers/logging.c:1003 plugins/sudoers/match.c:693
+#: plugins/sudoers/match.c:740 plugins/sudoers/match.c:781
+#: plugins/sudoers/match.c:809 plugins/sudoers/match.c:897
+#: plugins/sudoers/match.c:977 plugins/sudoers/parse.c:192
+#: plugins/sudoers/parse.c:204 plugins/sudoers/parse.c:219
+#: plugins/sudoers/parse.c:231 plugins/sudoers/policy.c:497
+#: plugins/sudoers/policy.c:739 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/pwutil.c:191 plugins/sudoers/pwutil.c:263
+#: plugins/sudoers/pwutil.c:340 plugins/sudoers/pwutil.c:514
+#: plugins/sudoers/pwutil.c:580 plugins/sudoers/pwutil.c:650
+#: plugins/sudoers/pwutil.c:808 plugins/sudoers/pwutil.c:865
+#: plugins/sudoers/pwutil.c:910 plugins/sudoers/pwutil.c:968
+#: plugins/sudoers/sssd.c:147 plugins/sudoers/sssd.c:387
+#: plugins/sudoers/sssd.c:450 plugins/sudoers/sssd.c:494
+#: plugins/sudoers/sssd.c:541 plugins/sudoers/sssd.c:732
+#: plugins/sudoers/stubs.c:96 plugins/sudoers/stubs.c:104
+#: plugins/sudoers/sudoers.c:265 plugins/sudoers/sudoers.c:275
+#: plugins/sudoers/sudoers.c:283 plugins/sudoers/sudoers.c:325
+#: plugins/sudoers/sudoers.c:648 plugins/sudoers/sudoers.c:774
+#: plugins/sudoers/sudoers.c:818 plugins/sudoers/sudoers.c:1092
+#: plugins/sudoers/sudoers_debug.c:107 plugins/sudoers/sudoreplay.c:1265
+#: plugins/sudoers/sudoreplay.c:1377 plugins/sudoers/sudoreplay.c:1417
+#: plugins/sudoers/sudoreplay.c:1426 plugins/sudoers/sudoreplay.c:1436
+#: plugins/sudoers/sudoreplay.c:1444 plugins/sudoers/sudoreplay.c:1448
+#: plugins/sudoers/sudoreplay.c:1604 plugins/sudoers/sudoreplay.c:1608
+#: plugins/sudoers/testsudoers.c:125 plugins/sudoers/testsudoers.c:215
+#: plugins/sudoers/testsudoers.c:232 plugins/sudoers/testsudoers.c:554
+#: plugins/sudoers/timestamp.c:401 plugins/sudoers/timestamp.c:445
+#: plugins/sudoers/timestamp.c:923 plugins/sudoers/toke_util.c:55
+#: plugins/sudoers/toke_util.c:108 plugins/sudoers/toke_util.c:145
+#: plugins/sudoers/tsdump.c:125 plugins/sudoers/visudo.c:145
+#: plugins/sudoers/visudo.c:307 plugins/sudoers/visudo.c:313
+#: plugins/sudoers/visudo.c:423 plugins/sudoers/visudo.c:601
+#: plugins/sudoers/visudo.c:920 plugins/sudoers/visudo.c:987
+#: plugins/sudoers/visudo.c:1076 toke.l:847 toke.l:948 toke.l:1105
+msgid "unable to allocate memory"
+msgstr "ne eblas rezervi memoron"
+
+#: gram.y:484
+msgid "a digest requires a path name"
+msgstr "resumo postulas vojnomon"
+
+#: gram.y:610
+msgid "invalid notbefore value"
+msgstr "malvalida valoro notafter"
+
+#: gram.y:618
+msgid "invalid notafter value"
+msgstr "validiga valoro notafter"
+
+#: gram.y:627 plugins/sudoers/policy.c:313
+msgid "timeout value too large"
+msgstr "eksvalidiĝo-valoro tro grandas"
+
+#: gram.y:629 plugins/sudoers/policy.c:315
+msgid "invalid timeout value"
+msgstr "malvalida eksvalidiĝo-valoro"
+
+#: gram.y:1296 plugins/sudoers/auth/pam.c:349 plugins/sudoers/auth/pam.c:519
+#: plugins/sudoers/auth/rfc1938.c:109 plugins/sudoers/cvtsudoers.c:116
+#: plugins/sudoers/cvtsudoers.c:156 plugins/sudoers/cvtsudoers.c:173
+#: plugins/sudoers/cvtsudoers.c:184 plugins/sudoers/cvtsudoers.c:277
+#: plugins/sudoers/cvtsudoers.c:404 plugins/sudoers/cvtsudoers.c:537
+#: plugins/sudoers/cvtsudoers.c:554 plugins/sudoers/cvtsudoers.c:660
+#: plugins/sudoers/cvtsudoers.c:773 plugins/sudoers/cvtsudoers.c:780
+#: plugins/sudoers/cvtsudoers.c:1186 plugins/sudoers/cvtsudoers.c:1190
+#: plugins/sudoers/cvtsudoers.c:1290 plugins/sudoers/cvtsudoers_ldif.c:146
+#: plugins/sudoers/cvtsudoers_ldif.c:188 plugins/sudoers/cvtsudoers_ldif.c:235
+#: plugins/sudoers/cvtsudoers_ldif.c:254 plugins/sudoers/cvtsudoers_ldif.c:324
+#: plugins/sudoers/cvtsudoers_ldif.c:379 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:404 plugins/sudoers/cvtsudoers_ldif.c:413
+#: plugins/sudoers/cvtsudoers_ldif.c:559 plugins/sudoers/cvtsudoers_ldif.c:752
+#: plugins/sudoers/cvtsudoers_ldif.c:779 plugins/sudoers/cvtsudoers_ldif.c:847
+#: plugins/sudoers/cvtsudoers_ldif.c:854 plugins/sudoers/cvtsudoers_ldif.c:859
+#: plugins/sudoers/cvtsudoers_ldif.c:935 plugins/sudoers/cvtsudoers_ldif.c:946
+#: plugins/sudoers/cvtsudoers_ldif.c:952 plugins/sudoers/cvtsudoers_ldif.c:977
+#: plugins/sudoers/cvtsudoers_ldif.c:989 plugins/sudoers/cvtsudoers_ldif.c:993
+#: plugins/sudoers/cvtsudoers_ldif.c:1007
+#: plugins/sudoers/cvtsudoers_ldif.c:1176
+#: plugins/sudoers/cvtsudoers_ldif.c:1207
+#: plugins/sudoers/cvtsudoers_ldif.c:1232
+#: plugins/sudoers/cvtsudoers_ldif.c:1261
+#: plugins/sudoers/cvtsudoers_ldif.c:1311
+#: plugins/sudoers/cvtsudoers_ldif.c:1357
+#: plugins/sudoers/cvtsudoers_ldif.c:1367 plugins/sudoers/defaults.c:656
+#: plugins/sudoers/defaults.c:952 plugins/sudoers/defaults.c:1123
+#: plugins/sudoers/editor.c:65 plugins/sudoers/editor.c:83
+#: plugins/sudoers/editor.c:94 plugins/sudoers/env.c:233
+#: plugins/sudoers/filedigest.c:61 plugins/sudoers/filedigest.c:77
+#: plugins/sudoers/gc.c:52 plugins/sudoers/group_plugin.c:131
+#: plugins/sudoers/interfaces.c:71 plugins/sudoers/iolog.c:938
+#: plugins/sudoers/iolog_path.c:167 plugins/sudoers/ldap.c:177
+#: plugins/sudoers/ldap.c:408 plugins/sudoers/ldap.c:412
+#: plugins/sudoers/ldap.c:424 plugins/sudoers/ldap.c:715
+#: plugins/sudoers/ldap.c:879 plugins/sudoers/ldap.c:1228
+#: plugins/sudoers/ldap.c:1654 plugins/sudoers/ldap.c:1691
+#: plugins/sudoers/ldap.c:1771 plugins/sudoers/ldap.c:1906
+#: plugins/sudoers/ldap.c:2007 plugins/sudoers/ldap.c:2023
+#: plugins/sudoers/ldap_conf.c:214 plugins/sudoers/ldap_conf.c:245
+#: plugins/sudoers/ldap_conf.c:297 plugins/sudoers/ldap_conf.c:333
+#: plugins/sudoers/ldap_conf.c:422 plugins/sudoers/ldap_conf.c:437
+#: plugins/sudoers/ldap_conf.c:533 plugins/sudoers/ldap_conf.c:566
+#: plugins/sudoers/ldap_conf.c:646 plugins/sudoers/ldap_conf.c:729
+#: plugins/sudoers/ldap_util.c:519 plugins/sudoers/ldap_util.c:575
+#: plugins/sudoers/linux_audit.c:76 plugins/sudoers/logging.c:190
+#: plugins/sudoers/logging.c:506 plugins/sudoers/logging.c:527
+#: plugins/sudoers/logging.c:567 plugins/sudoers/logging.c:1003
+#: plugins/sudoers/match.c:692 plugins/sudoers/match.c:739
+#: plugins/sudoers/match.c:781 plugins/sudoers/match.c:809
+#: plugins/sudoers/match.c:897 plugins/sudoers/match.c:976
+#: plugins/sudoers/parse.c:191 plugins/sudoers/parse.c:203
+#: plugins/sudoers/parse.c:218 plugins/sudoers/parse.c:230
+#: plugins/sudoers/policy.c:127 plugins/sudoers/policy.c:136
+#: plugins/sudoers/policy.c:145 plugins/sudoers/policy.c:171
+#: plugins/sudoers/policy.c:298 plugins/sudoers/policy.c:313
+#: plugins/sudoers/policy.c:315 plugins/sudoers/policy.c:341
+#: plugins/sudoers/policy.c:351 plugins/sudoers/policy.c:395
+#: plugins/sudoers/policy.c:405 plugins/sudoers/policy.c:414
+#: plugins/sudoers/policy.c:423 plugins/sudoers/policy.c:497
+#: plugins/sudoers/policy.c:739 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/pwutil.c:191 plugins/sudoers/pwutil.c:263
+#: plugins/sudoers/pwutil.c:340 plugins/sudoers/pwutil.c:514
+#: plugins/sudoers/pwutil.c:580 plugins/sudoers/pwutil.c:650
+#: plugins/sudoers/pwutil.c:808 plugins/sudoers/pwutil.c:865
+#: plugins/sudoers/pwutil.c:910 plugins/sudoers/pwutil.c:968
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1476
+#: plugins/sudoers/set_perms.c:1641 plugins/sudoers/sssd.c:146
+#: plugins/sudoers/sssd.c:387 plugins/sudoers/sssd.c:450
+#: plugins/sudoers/sssd.c:494 plugins/sudoers/sssd.c:541
+#: plugins/sudoers/sssd.c:732 plugins/sudoers/stubs.c:96
+#: plugins/sudoers/stubs.c:104 plugins/sudoers/sudoers.c:265
+#: plugins/sudoers/sudoers.c:275 plugins/sudoers/sudoers.c:283
+#: plugins/sudoers/sudoers.c:325 plugins/sudoers/sudoers.c:648
+#: plugins/sudoers/sudoers.c:774 plugins/sudoers/sudoers.c:818
+#: plugins/sudoers/sudoers.c:1092 plugins/sudoers/sudoers_debug.c:106
+#: plugins/sudoers/sudoreplay.c:1265 plugins/sudoers/sudoreplay.c:1377
+#: plugins/sudoers/sudoreplay.c:1417 plugins/sudoers/sudoreplay.c:1426
+#: plugins/sudoers/sudoreplay.c:1436 plugins/sudoers/sudoreplay.c:1444
+#: plugins/sudoers/sudoreplay.c:1448 plugins/sudoers/sudoreplay.c:1604
+#: plugins/sudoers/sudoreplay.c:1608 plugins/sudoers/testsudoers.c:125
+#: plugins/sudoers/testsudoers.c:215 plugins/sudoers/testsudoers.c:232
+#: plugins/sudoers/testsudoers.c:554 plugins/sudoers/timestamp.c:401
+#: plugins/sudoers/timestamp.c:445 plugins/sudoers/timestamp.c:923
+#: plugins/sudoers/toke_util.c:55 plugins/sudoers/toke_util.c:108
+#: plugins/sudoers/toke_util.c:145 plugins/sudoers/tsdump.c:125
+#: plugins/sudoers/visudo.c:145 plugins/sudoers/visudo.c:307
+#: plugins/sudoers/visudo.c:313 plugins/sudoers/visudo.c:423
+#: plugins/sudoers/visudo.c:601 plugins/sudoers/visudo.c:920
+#: plugins/sudoers/visudo.c:987 plugins/sudoers/visudo.c:1076 toke.l:847
+#: toke.l:948 toke.l:1105
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:140
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Kromnomo \"%s\" jam ekzistas"
+
+#: plugins/sudoers/auth/bsdauth.c:68
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "ne eblas akiri ensalutan klason por uzanto %s"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+msgid "unable to begin bsd authentication"
+msgstr "ne eblas komenci bsd-aŭtentikigon"
+
+#: plugins/sudoers/auth/bsdauth.c:81
+msgid "invalid authentication type"
+msgstr "malvalida aŭtentikiga tipo"
+
+#: plugins/sudoers/auth/bsdauth.c:90
+msgid "unable to initialize BSD authentication"
+msgstr "ne eblas komenci BSD-aŭtentikigon"
+
+#: plugins/sudoers/auth/bsdauth.c:178
+msgid "your account has expired"
+msgstr "via konto ekzvalidiĝis"
+
+#: plugins/sudoers/auth/bsdauth.c:180
+msgid "approval failed"
+msgstr "aprobo malsukcesis"
+
+#: plugins/sudoers/auth/fwtk.c:52
+msgid "unable to read fwtk config"
+msgstr "ne eblas legi fwtk-agordon"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to connect to authentication server"
+msgstr "ne eblas konektiĝi al aŭtentikiga servilo"
+
+#: plugins/sudoers/auth/fwtk.c:63 plugins/sudoers/auth/fwtk.c:87
+#: plugins/sudoers/auth/fwtk.c:119
+msgid "lost connection to authentication server"
+msgstr "konekto al aŭtentikiga servilo perdita"
+
+#: plugins/sudoers/auth/fwtk.c:67
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"eraro de aŭtentikiga servilo:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:111
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s ne eblas konverti ĉefon al ĉeno ('%s'): %s"
+
+#: plugins/sudoers/auth/kerb5.c:161
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: ne eblas analizi: '%s': %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: ne eblas trovi ccache-on: %s"
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: ne eblas generi elektojn: %s"
+
+#: plugins/sudoers/auth/kerb5.c:232
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: ne eblas akiri atestilojn: %s"
+
+#: plugins/sudoers/auth/kerb5.c:245
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: ne eblas ekigi atestilan kaŝmemoron: %s"
+
+#: plugins/sudoers/auth/kerb5.c:248
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: ne eblas konservi atestilon en kaŝmemoro: %s"
+
+#: plugins/sudoers/auth/kerb5.c:312
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: ne eblas atingi gastiganton ĉefan: %s"
+
+#: plugins/sudoers/auth/kerb5.c:326
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Ne eblas kontroli TGT! Ebla atako!: %s"
+
+#: plugins/sudoers/auth/pam.c:108
+msgid "unable to initialize PAM"
+msgstr "ne eblas ekigi PAM"
+
+#: plugins/sudoers/auth/pam.c:199
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "eraro de aŭtentikiga servilo: %s"
+
+#: plugins/sudoers/auth/pam.c:216
+msgid "account validation failure, is your account locked?"
+msgstr "malsukceso ĉe konta validigo, ĉu via konto estas ŝlosita?"
+
+#: plugins/sudoers/auth/pam.c:224
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Konto aŭ pasvorto eksvalidiĝis, restarigu vian pasvorton kaj reprovu"
+
+#: plugins/sudoers/auth/pam.c:233
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "ne eblas ŝanĝi eksvalidan pasvorton: %s"
+
+#: plugins/sudoers/auth/pam.c:241
+msgid "Password expired, contact your system administrator"
+msgstr "Pasvorto eksvalidiĝis, kontaktu vian sistemestron"
+
+#: plugins/sudoers/auth/pam.c:245
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Konto eksvalidiĝis aŭ PAM-agordon malhavas sekcion \"account\" por sudo, kontaktu vian sistemestron"
+
+#: plugins/sudoers/auth/pam.c:252 plugins/sudoers/auth/pam.c:257
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "eraro de administro de konto PAM: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:97 plugins/sudoers/visudo.c:227
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "vi ne ekzistas en la datumbazo %s"
+
+#: plugins/sudoers/auth/securid5.c:73
+msgid "failed to initialise the ACE API library"
+msgstr "malsukcesis ekigi la bibliotekon de la API ACE"
+
+#: plugins/sudoers/auth/securid5.c:99
+msgid "unable to contact the SecurID server"
+msgstr "ne eblas kontakti la servilon de SecurID"
+
+#: plugins/sudoers/auth/securid5.c:108
+msgid "User ID locked for SecurID Authentication"
+msgstr "Uzanto-identigilo ŝlosita pro Aŭtentikigo SecurID"
+
+#: plugins/sudoers/auth/securid5.c:112 plugins/sudoers/auth/securid5.c:163
+msgid "invalid username length for SecurID"
+msgstr "malvalida salutnoma longo por SecurID"
+
+#: plugins/sudoers/auth/securid5.c:116 plugins/sudoers/auth/securid5.c:168
+msgid "invalid Authentication Handle for SecurID"
+msgstr "malvalida Aŭtentikiga Traktilo por SecurID"
+
+#: plugins/sudoers/auth/securid5.c:120
+msgid "SecurID communication failed"
+msgstr "Komunikiĝo kun SecurID malsukcesis"
+
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:213
+msgid "unknown SecurID error"
+msgstr "nekonata SecurID-eraro"
+
+#: plugins/sudoers/auth/securid5.c:158
+msgid "invalid passcode length for SecurID"
+msgstr "malvalida paskoda longo por SecurID"
+
+#: plugins/sudoers/auth/sia.c:69 plugins/sudoers/auth/sia.c:124
+msgid "unable to initialize SIA session"
+msgstr "ne eblas ekigi SIA-seascon"
+
+#: plugins/sudoers/auth/sudo_auth.c:131
+msgid "invalid authentication methods"
+msgstr "malvalidaj aŭtentikigaj metodoj"
+
+#: plugins/sudoers/auth/sudo_auth.c:133
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Nevalidaj aŭtentikigaj metodoj kompilitaj en sudo! Vi ne rajtas miksi dependan kaj sendependan aŭtentikigon."
+
+#: plugins/sudoers/auth/sudo_auth.c:254 plugins/sudoers/auth/sudo_auth.c:304
+msgid "no authentication methods"
+msgstr "neniu aŭtentikiga metodo"
+
+#: plugins/sudoers/auth/sudo_auth.c:256
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Ekzistas neniaj aŭtentikigaj metodoj kompilitaj en sudo! Se vi volas malŝalti aŭtentikigon, uzu la agordan parametron --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:306
+msgid "Unable to initialize authentication methods."
+msgstr "ne eblas komenci BSD-aŭtentikigajn metodojn."
+
+#: plugins/sudoers/auth/sudo_auth.c:472
+msgid "Authentication methods:"
+msgstr "Aŭtentikigaj metodoj:"
+
+#: plugins/sudoers/bsm_audit.c:120 plugins/sudoers/bsm_audit.c:211
+msgid "Could not determine audit condition"
+msgstr "Ne eblis determini revizian kondiĉon"
+
+#: plugins/sudoers/bsm_audit.c:183 plugins/sudoers/bsm_audit.c:273
+msgid "unable to commit audit record"
+msgstr "ne eblis konservi revizian rikordon"
+
+#: plugins/sudoers/check.c:262
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Ni fidas, ke vi ricevis la kutiman prelegon fare de la sistemestro.\n"
+"Resume memoru la jenajn:\n"
+"\n"
+" #1) Estimu la privatecon de aliaj.\n"
+" #2) Pensu antaŭ ol tajpi.\n"
+" #3) Granda povo devigas grandan responson.\n"
+"\n"
+
+#: plugins/sudoers/check.c:305 plugins/sudoers/check.c:315
+#: plugins/sudoers/sudoers.c:691 plugins/sudoers/sudoers.c:736
+#: plugins/sudoers/tsdump.c:121
+#, c-format
+msgid "unknown uid: %u"
+msgstr "nekonata uid: %u"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/iolog.c:257
+#: plugins/sudoers/policy.c:912 plugins/sudoers/sudoers.c:1131
+#: plugins/sudoers/testsudoers.c:206 plugins/sudoers/testsudoers.c:366
+#, c-format
+msgid "unknown user: %s"
+msgstr "nekonata uzanto: %s"
+
+#: plugins/sudoers/cvtsudoers.c:191
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "alkremento de ordo: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:207
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "komenca ordo: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:218 plugins/sudoers/sudoreplay.c:310
+#: plugins/sudoers/visudo.c:177
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s eldono %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:220 plugins/sudoers/visudo.c:179
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s gramatika eldono %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:237
+#, c-format
+msgid "unsupported input format %s"
+msgstr "nesubtenata enig-formo %s"
+
+#: plugins/sudoers/cvtsudoers.c:252
+#, c-format
+msgid "unsupported output format %s"
+msgstr "nesubtenata elig-formo %s"
+
+#: plugins/sudoers/cvtsudoers.c:292
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: eliga kaj eniga dosieroj devas esti malsamaj"
+
+#: plugins/sudoers/cvtsudoers.c:308 plugins/sudoers/sudoers.c:168
+#: plugins/sudoers/testsudoers.c:245 plugins/sudoers/visudo.c:233
+#: plugins/sudoers/visudo.c:589 plugins/sudoers/visudo.c:911
+msgid "unable to initialize sudoers default values"
+msgstr "%s: ne eblas ekigi aŭtomatajn valorojn de sudoers"
+
+#: plugins/sudoers/cvtsudoers.c:393 plugins/sudoers/ldap_conf.c:412
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:452
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: nekonata ŝlosilvorto: %s"
+
+#: plugins/sudoers/cvtsudoers.c:498
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "malvalida defaŭlto-tipo: %s"
+
+#: plugins/sudoers/cvtsudoers.c:521
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "malvalida demeto-tipo: %s"
+
+#: plugins/sudoers/cvtsudoers.c:561 plugins/sudoers/cvtsudoers.c:575
+#, c-format
+msgid "invalid filter: %s"
+msgstr "malvalida filtro: %s"
+
+#: plugins/sudoers/cvtsudoers.c:653 plugins/sudoers/cvtsudoers.c:1250
+#: plugins/sudoers/cvtsudoers_json.c:1113
+#: plugins/sudoers/cvtsudoers_ldif.c:627
+#: plugins/sudoers/cvtsudoers_ldif.c:1163 plugins/sudoers/iolog.c:415
+#: plugins/sudoers/sudoers.c:898 plugins/sudoers/sudoreplay.c:356
+#: plugins/sudoers/sudoreplay.c:1366 plugins/sudoers/sudoreplay.c:1570
+#: plugins/sudoers/timestamp.c:410 plugins/sudoers/tsdump.c:130
+#: plugins/sudoers/visudo.c:907
+#, c-format
+msgid "unable to open %s"
+msgstr "ne eblas malfermi: %s"
+
+#: plugins/sudoers/cvtsudoers.c:656 plugins/sudoers/visudo.c:916
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "malsukcesis analizi dosieron %s, nekonata eraro"
+
+#: plugins/sudoers/cvtsudoers.c:664 plugins/sudoers/visudo.c:933
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "analiza eraro en %s proksime al linio %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:667 plugins/sudoers/visudo.c:936
+#, c-format
+msgid "parse error in %s\n"
+msgstr "analiza eraro en %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:1297 plugins/sudoers/iolog.c:502
+#: plugins/sudoers/sudoreplay.c:1135 plugins/sudoers/timestamp.c:294
+#: plugins/sudoers/timestamp.c:297
+#, c-format
+msgid "unable to write to %s"
+msgstr "ne eblas skribi al %s"
+
+#: plugins/sudoers/cvtsudoers.c:1320
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s - konverti inter dosierformoj de sudoers\n"
+"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1322
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Modifiloj:\n"
+" -b, --base=dn la baza DN por petoj de sudo LDAP\n"
+" -d, --defaults=deftipoj nur konverti Defaŭltoj el la indikitaj tipoj\n"
+" -e, --expand-aliases disvolvigi kromnomojn dum konverto\n"
+" -f, --output-format=formo difini elig-formon: JSON, LDIF aŭ sudoers\n"
+" -i, --input-format=formo difini enig-formon: LDIF aŭ sudoers\n"
+" -I, --increment=num kiom alkrementi po ĉiu sudoOrder\n"
+" -h, --help montri helpmesaĝo kaj eliri\n"
+" -m, --match=filtro nur konverti enigojn kiuj akordas al la filtro\n"
+" -M, --match-local akordo-filtro uzas datumbazojn de passwd kaj de group\n"
+" -o, --output=elig_dosiero skribi konvertitan sudoers al elig-dosiero\n"
+" -O, --order-start=num ekpunkto por la unua sudoOrder\n"
+" -p, --prune-matches pritondi nekongruantajn uzantojn, grupojn kaj gastigantojn\n"
+" -s, --suppress=sekcioj demeti eligon el kelkaj sekcioj\n"
+" -V, --version montri informon pri versio kaj eliri"
+
+#: plugins/sudoers/cvtsudoers_json.c:673 plugins/sudoers/cvtsudoers_json.c:708
+#: plugins/sudoers/cvtsudoers_json.c:924
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "nekonata ero \"%s\" en defaults"
+
+#: plugins/sudoers/cvtsudoers_json.c:844 plugins/sudoers/cvtsudoers_json.c:859
+#: plugins/sudoers/cvtsudoers_ldif.c:299 plugins/sudoers/cvtsudoers_ldif.c:310
+#: plugins/sudoers/ldap.c:474
+msgid "unable to get GMT time"
+msgstr "ne eblas atingi GMT-tempon"
+
+#: plugins/sudoers/cvtsudoers_json.c:847 plugins/sudoers/cvtsudoers_json.c:862
+#: plugins/sudoers/cvtsudoers_ldif.c:302 plugins/sudoers/cvtsudoers_ldif.c:313
+#: plugins/sudoers/ldap.c:480
+msgid "unable to format timestamp"
+msgstr "ne eblas aranĝi tempo-indikilon"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:517 plugins/sudoers/env.c:295
+#: plugins/sudoers/env.c:302 plugins/sudoers/env.c:407
+#: plugins/sudoers/ldap.c:488 plugins/sudoers/ldap.c:719
+#: plugins/sudoers/ldap.c:1046 plugins/sudoers/ldap_conf.c:218
+#: plugins/sudoers/ldap_conf.c:308 plugins/sudoers/linux_audit.c:82
+#: plugins/sudoers/logging.c:1008 plugins/sudoers/policy.c:618
+#: plugins/sudoers/policy.c:628 plugins/sudoers/prompt.c:161
+#: plugins/sudoers/sudoers.c:840 plugins/sudoers/testsudoers.c:236
+#: plugins/sudoers/toke_util.c:157
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "interna eraro, troo en %s"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:622
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "la medivariablo SUDOERS_BASE ne estas difinita kaj la modifilo -b ne estis indikata."
+
+#: plugins/sudoers/cvtsudoers_ldif.c:757
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "ni preteratentas malvalidan atribut-valoron: %s"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:1197
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "ni preteratentas malkompletan sudoRole: cn: %s"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:1349 plugins/sudoers/ldap.c:1778
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "malvalida atributo de sudoOrder: %s"
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Syslog-trajto se syslog estas uzata por protokoli: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Syslog-prioritato por uzi, kiam uzanto sukcese aŭtentikiĝas: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Syslog-prioritato por uzi kiam uzanto malsukcese aŭtentikigas: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "Meti OTP-demandilon en sia propra linio"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "Ignoro punkton en $PATH"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "Ĉiam sendi retmesaĝon kiam sudo plenumiĝas"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "Sendi retmesaĝon se uzanto-aŭtentikiĝo malsukcesas"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "Sendi retmesaĝon se la uzanto ne estas en sudoers"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Sendi retmesaĝon se la uzanto ne estas en sudors por la gastiganto"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Sendi retmesaĝon se la uzanto ne estas permesata plenumigi komandon"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "Sendi retmesaĝon se la uzanto provi plenumigi komandon"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Uzi apartan tempo-indikilon por ĉiu uzanto/tty-kombino"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "Averti uzanton dum la unua fojo ĝi plenumigas je sudo"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Dosiero havanta la sudo-averton: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "Postulas, ke uzantoj aŭtentikiĝu aŭtomate"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "Ĉefuzanto rajtas plenumigi: sudo"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Protokoli la gastignomon en la (ne syslog) protokolo"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Protokoli la jaron en la (ne syslog) protokolo"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Se sudo estas vokata kun neniuj parametroj, komencu ŝelon"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Valorizi medivariablon $HOME al la cela uzanto dum komenci ŝelon kun -s"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Ĉiam valorizi medivariablon $HOME al la hejma dosierujo de la cela uzanto"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Permesi, ke iu informokolektado por doni utilajn eraromesaĝojn"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Postuli tute kvalifikitajn gastiganto-nomojn en la dosiero sudoers"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Insulti la uzanton, kiam si enmetas malĝustan pasvorton"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Nur permesi, ke uzanto plenumigu sudo-on se si havas tty-on"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo honoru la medivariablon EDITOR"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "Peti la ĉefuzantan pasvorton, ne la uzanto-pasvorton"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Peti la pasvorton de runas_default, ne de la uzanto"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Peti la pasvorton de la cela uzanto, ne la nuna uzanto"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Apliki aŭtomataĵojn en la ensaluta klaso de la cela uzanto, se ĝi ekzistas"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Valorizi la medivariablojn LOGNAME kaj USER"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Nur valorizi la efikan uid-on al la cela uzanto, ne la realan uid-on"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Ne ekigi la grupon vektoron al tio de la cela uzanto"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Longo je kiu linfaldi la protokol-dosieraj linioj (0 por senfalda): %u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Eksvalidiĝo de la aŭtentikiga tempo-indikilo: %.1f minutoj"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Eksvalidiĝo de la pasvortilo: %.1f minutoj"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Nombro da provoj por enmeti pasvorton: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Umask uzi aŭ 07777 por uzi uzanton: 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Vojo al protokolo: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Vojo al retpoŝtilo: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Parametroj por retpoŝtilo: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Retpoŝtadreso adresata: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Retpoŝtadreso adresanta: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Subjekta linio por ĉiuj mesaĝoj: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Neĝusta pasvorta mesaĝo: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Vojo al dosierujo de prelega stato: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Vojo al dosierujo de aŭtentikiga tempo-indikilo: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Estro de la dosierujo de aŭtentikiga tempo-indikilo: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Uzantoj en la grupo en devas plenumi la postulojn de pasvorto kaj PATH: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Defaŭlta pasvorta peto: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Se aktivigita, passprompt superregas sistemajn invitojn ĉiuokaze."
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Defaŭlta uzanto por plenumigi komandojn: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Valoro per kiu superregi la PATH-on de uzanto: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Vojo al la tekstoredaktilo uzota de visudo: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Kiam postuli pasvorton por la pseŭdokomando 'list': %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Kiam postuli pasvorton por la pseŭdokamando 'verify': %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Anstaŭŝargi la falsan exec-funkciojn enhavatajn en la biblioteko sudo_noexec"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Se LDAP-dosierujo estas aktiva, ni ignoru la lokan suders-dosieron"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Dosiero-priskribiloj >= %d fermiĝos antaŭ ol plenumigi komandon"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Se aktiva, uzantoj rajtas superregi la voloron de 'closefrom' per la parametro -C"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Permesi, ke uzantoj valorizu arbitrajn medivariablojn"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "Restarigi la medion al apriora aro da variabloj"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "Medivariabloj por kontroli por sano:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "Medivariabloj por forigi:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "Medivariabloj konservi:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "SELinux-rolo por uzi en la nova sekureca kunteksto: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "SELinux-tipo por uzi en la nova sekureca kunteksto: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Vojo al media dosiero specifa al sudo: %s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Vojo al la neatingebla sudo-specifa medio-dosiero: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Lokaĵaro por uzi dum analizi dosieron sudoers: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Permesi, ke sudo peti pasvorton eĉ se ĝi estus videbla"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Doni vidajn indikojn je la pasvorta enmetanta kiam ekzistas enmeto"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Uzi pli rapida kunigo, kiu estas malpli ĝusta sed ne atingas la dosiersistemon"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "La umask specifa en sudors superregos tio de la uzanto, eĉ se ĝi estas pli permesema"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "Protokoli enmeton de uzanto por la komando, kiun si plenumigas"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "Protokoli la eligon de la komando, kiu estas plenumiĝi"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "Kunpremi eneligaj protokoloj per zlib"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "Ĉiam protokoli komandojn en pseŭda tty"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Kromprogramo por kompreno de ne-uniksaj grupoj: %s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Dosierujo en kiu konservi eneligaj protokoloj: %s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Dosiero en kiu konservi la eneliga protokolo: %s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Aldoni eron al la utmp/utmpx-dosiero dum generi pty-on"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Valorizi uzanton en utmp al la plenumigkiela uzanto, ne la vokanta uzanto"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Aro da permesitaj privilegioj: %s"
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Aro da limigaj privilegioj: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "Plenumigi komandojn en pty en la fono"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "PAM-servonomo uzota: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "PAM-servonomo uzota por ensalutaj ŝeloj: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "ne eblas establi PAM-atestilojn por la cela uzanto"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "Krei novan PAM-seancon en kiu la komando plenumiĝos"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Maksimuma sinsekva numero de la en/eliga protokolo: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "Aktivigi retgrupan regon de sudoers"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Kontroli gepatrajn dosierujojn pri skribeblo dum redakto de dosieroj per sudoedit"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Sekvi simbolajn ligojn dum redakto de dosieroj per sudoedit"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "Informo-mendi la grupan kromprogramon por nekonataj sistem-grupoj"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Kongrui retgrupoj surbaze de entuta n-opo: uzanto, gastiganto kaj domajno"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Permesi ke komandoj estu plenumataj eĉ se sudo ne povas skribi al la ekzamena protokolo"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Permesi ke komandoj estu plenumataj eĉ se sudo ne povas skribi al la eneliga protokolo"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Permesi ke komandoj estu plenumataj eĉ se sudo ne povas skribi al la protokola dosiero"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Solvi grupojn en sudoers kaj kongrui al la grupa ID, ne la nomo"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Protokoleroj pli grandaj ol tiu ĉi valoro estos dividitaj en multoblajn mesaĝojn en syslog: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Uzanto kiu posedos la eneligajn protokol-dosierojn: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Grupo kiu posedos la eneligajn protokol-dosierojn: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Dosier-reĝimo uzota por la eneligaj protokol-dosieroj: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Plenumigi komandojn laŭ dosiernumero anstataŭ laŭ vojo: %s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Ignori nekonatajn erojn Defaults en sudoers anstataŭ prezenti averton"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Tempo laŭ sekundoj pust kiu la komando finiĝos: %u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Permesi al la uzanto specifi eksvalidiĝon per la komandlinio"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Tuj elbufrigi eneligo-protokolajn datumojn en diskon anstataŭ enbufrigi ĝin"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "Inkluzivigi la procezan identigilon dum protokoli per syslog"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Tipo de tempindika rikordo por aŭtentikigo: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "Mesaĝo pri malsukceso dum aŭtentikigo: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "Preteratenti usklecon dum kongruo al uzantnomoj"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "Preteratenti usklecon dum kongruo al grupnomoj"
+
+#: plugins/sudoers/defaults.c:224
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d nekonata ero \"%s\" en defaults"
+
+#: plugins/sudoers/defaults.c:227
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: nekonata ero \"%s\" en defaults"
+
+#: plugins/sudoers/defaults.c:270
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d neniu valoro indikita por \"%s\""
+
+#: plugins/sudoers/defaults.c:273
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: neniu valoro indikita por \"%s\""
+
+#: plugins/sudoers/defaults.c:293
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d valoroj por \"%s\" devas komenciĝi per '/'"
+
+#: plugins/sudoers/defaults.c:296
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: valoroj por \"%s\" devas komenciĝi per '/'"
+
+#: plugins/sudoers/defaults.c:318
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d parametro \"%s\" ne povas havi valoron"
+
+#: plugins/sudoers/defaults.c:321
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: parametro \"%s\" ne povas havi valoron"
+
+#: plugins/sudoers/defaults.c:346
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d malvalida Defaults-tipo 0x%x por parametro \"%s\""
+
+#: plugins/sudoers/defaults.c:349
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: malvalida Defaults-tipo 0x%x por parametro \"%s\""
+
+#: plugins/sudoers/defaults.c:359
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d valoro \"%s\" estas malvalida por parametro \"%s\""
+
+#: plugins/sudoers/defaults.c:362
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: valoro \"%s\" estas malvalida por parametro \"%s\""
+
+#: plugins/sudoers/env.c:376
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: medio tro granda"
+
+#: plugins/sudoers/env.c:1055
+msgid "unable to rebuild the environment"
+msgstr "ne eblas rekonstrui la medion"
+
+#: plugins/sudoers/env.c:1129
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "bedaŭre vi ne estas permesata valorizi la jenajn medivariablojn: %s"
+
+#: plugins/sudoers/file.c:111
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "analiza eraro en %s proksime al linio %d"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s"
+msgstr "analiza eraro en %s"
+
+#: plugins/sudoers/filedigest.c:56
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "nekonata resuma tipo %d por %s"
+
+#: plugins/sudoers/filedigest.c:85
+#, c-format
+msgid "%s: read error"
+msgstr "%s: lega eraro"
+
+#: plugins/sudoers/group_plugin.c:83
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s devas esti estrata de uid %d"
+
+#: plugins/sudoers/group_plugin.c:87
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s devas esti skribebla nur de estro"
+
+#: plugins/sudoers/group_plugin.c:95 plugins/sudoers/sssd.c:550
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "ne eblas ŝarĝi je %s: %s"
+
+#: plugins/sudoers/group_plugin.c:101
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "ne eblas trovi simbolon \"group_plugin\" en %s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: nekongrua grupa kromprogramo: ĉefa eldono %d, atendita %d"
+
+#: plugins/sudoers/interfaces.c:79 plugins/sudoers/interfaces.c:96
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "ne eblas trakti IP-adreson \"%s\""
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "ne eblas trakti retmaskon \"%s\""
+
+#: plugins/sudoers/interfaces.c:129
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Loka IP-adresa kaj retmaska paroj:\n"
+
+#: plugins/sudoers/iolog.c:119 plugins/sudoers/mkdir_parents.c:75
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s ekzistas sed ne dosierujo (0%o)"
+
+#: plugins/sudoers/iolog.c:144 plugins/sudoers/iolog.c:184
+#: plugins/sudoers/mkdir_parents.c:64 plugins/sudoers/timestamp.c:174
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "ne eblas mkdir-i: %s"
+
+#: plugins/sudoers/iolog.c:188 plugins/sudoers/visudo.c:718
+#: plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "ne eblas ŝanĝi reĝimon de %s al 0%o"
+
+#: plugins/sudoers/iolog.c:296 plugins/sudoers/sudoers.c:1162
+#: plugins/sudoers/testsudoers.c:390
+#, c-format
+msgid "unknown group: %s"
+msgstr "nekonata grupo: %s"
+
+#: plugins/sudoers/iolog.c:466 plugins/sudoers/sudoers.c:902
+#: plugins/sudoers/sudoreplay.c:868 plugins/sudoers/sudoreplay.c:1681
+#: plugins/sudoers/tsdump.c:140
+#, c-format
+msgid "unable to read %s"
+msgstr "ne eblas legi %s"
+
+#: plugins/sudoers/iolog.c:581 plugins/sudoers/iolog.c:800
+#, c-format
+msgid "unable to create %s"
+msgstr "ne eblas krei: %s"
+
+#: plugins/sudoers/iolog.c:1032 plugins/sudoers/iolog.c:1107
+#: plugins/sudoers/iolog.c:1188
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "ne eblas skribi al eneliga protokoldosiero: %s"
+
+#: plugins/sudoers/iolog.c:1066
+#, c-format
+msgid "%s: internal error, file index %d not open"
+msgstr "%s: interna eraro, dosiera indekso %d ne estas malferma"
+
+#: plugins/sudoers/ldap.c:170 plugins/sudoers/ldap_conf.c:287
+msgid "starttls not supported when using ldaps"
+msgstr "starttls ne estas regata dum uzo de ldaps"
+
+#: plugins/sudoers/ldap.c:241
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "ne eblas ekigi SSL-asertilon kaj ŝlosilan datumbazon: %s"
+
+#: plugins/sudoers/ldap.c:244
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "TLS_CERT devas havi valoron en %s antaŭ ol SSL uzeblos"
+
+#: plugins/sudoers/ldap.c:1606
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "ne eblas ekigi LDAP-on: %s"
+
+#: plugins/sudoers/ldap.c:1642
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls specifita sed LDAP-bibliotekoj ne havas la funkciojn ldap_start_tls_s() kaj ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap_conf.c:196
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: pordo tro granda"
+
+#: plugins/sudoers/ldap_conf.c:256
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "nekonata retadresa tipo de LDAP: %s"
+
+#: plugins/sudoers/ldap_conf.c:283
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "ne eblas miksi sekurajn kaj nesekurajn retadresojn de LDAP"
+
+#: plugins/sudoers/ldap_util.c:470 plugins/sudoers/ldap_util.c:472
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "ne eblas konverti sudoOption: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:52
+msgid "unable to open audit system"
+msgstr "ne eblas malfermi revizian sistemon"
+
+#: plugins/sudoers/linux_audit.c:93
+msgid "unable to send audit message"
+msgstr "ne eblas sendi revizian mesaĝon"
+
+#: plugins/sudoers/logging.c:108
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s: %s"
+
+#: plugins/sudoers/logging.c:136
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (komando daŭrigis) %s"
+
+#: plugins/sudoers/logging.c:165
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "ne eblas malfermi protokolon: %s"
+
+#: plugins/sudoers/logging.c:173
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "ne eblas ŝlosi protokolon: %s"
+
+#: plugins/sudoers/logging.c:206
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "ne eblas skribi al protokolo: %s"
+
+#: plugins/sudoers/logging.c:235
+msgid "No user or host"
+msgstr "Neniu uzanto aŭ gastiganto"
+
+#: plugins/sudoers/logging.c:237
+msgid "validation failure"
+msgstr "validiga malsukceso"
+
+#: plugins/sudoers/logging.c:244
+msgid "user NOT in sudoers"
+msgstr "uzanto NE estas en sudoers"
+
+#: plugins/sudoers/logging.c:246
+msgid "user NOT authorized on host"
+msgstr "uzanto NE permesata en gastiganto"
+
+#: plugins/sudoers/logging.c:248
+msgid "command not allowed"
+msgstr "komando ne permesata"
+
+#: plugins/sudoers/logging.c:283
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s ne estas en la dosiero sudoers. Ĉi tiu estos raportita.\n"
+
+#: plugins/sudoers/logging.c:286
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s ne estas permesata plenumigi sudo-on en %s. Ĉi tio estos raportita.\n"
+
+#: plugins/sudoers/logging.c:290
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Bedaŭre uzanto %s ne rajtas plenumigi sudo-on en %s.\n"
+
+#: plugins/sudoers/logging.c:293
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Bedaŭre uzanto %s ne rajtas plenumigi '%s%s%s'-on kiel %s%s%s en %s.\n"
+
+#: plugins/sudoers/logging.c:330 plugins/sudoers/sudoers.c:433
+#: plugins/sudoers/sudoers.c:435 plugins/sudoers/sudoers.c:437
+#: plugins/sudoers/sudoers.c:439 plugins/sudoers/sudoers.c:594
+#: plugins/sudoers/sudoers.c:596
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: komando ne trovita"
+
+#: plugins/sudoers/logging.c:332 plugins/sudoers/sudoers.c:429
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"ni malatentas \"%s\" trovita en '.'\n"
+"Uzu \"sudo ./%s\" se tio estas la \"%s\", kiun vi volas plenumigi."
+
+#: plugins/sudoers/logging.c:349
+msgid "authentication failure"
+msgstr "aŭtentiga malsukceso"
+
+#: plugins/sudoers/logging.c:375
+msgid "a password is required"
+msgstr "pasvorto estas bezonata"
+
+#: plugins/sudoers/logging.c:438
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u malĝusta pasvorta provo"
+msgstr[1] "%u malĝustaj pasvortaj provoj"
+
+#: plugins/sudoers/logging.c:659
+msgid "unable to fork"
+msgstr "ne eblas forki"
+
+#: plugins/sudoers/logging.c:667 plugins/sudoers/logging.c:719
+#, c-format
+msgid "unable to fork: %m"
+msgstr "ne eblas forki: %m"
+
+#: plugins/sudoers/logging.c:709
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "ne eblas malfermi tubon: %m"
+
+#: plugins/sudoers/logging.c:734
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "ne eblas kopii enigon: %m"
+
+#: plugins/sudoers/logging.c:772
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "ne eblas plenumigi %s-on: %m"
+
+#: plugins/sudoers/match.c:842
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "resumo por %s (%s) ne estas laŭ la formo %s"
+
+#: plugins/sudoers/mkdir_parents.c:70 plugins/sudoers/sudoers.c:913
+#: plugins/sudoers/visudo.c:416 plugins/sudoers/visudo.c:712
+#, c-format
+msgid "unable to stat %s"
+msgstr "ne eblas stat-i: %s"
+
+#: plugins/sudoers/parse.c:434
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"LDAP-rolo: %s\n"
+
+#: plugins/sudoers/parse.c:437
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Ero en sudoers:\n"
+
+#: plugins/sudoers/parse.c:439
+#, c-format
+msgid " RunAsUsers: "
+msgstr " RunAsUsers: "
+
+#: plugins/sudoers/parse.c:454
+#, c-format
+msgid " RunAsGroups: "
+msgstr " RunAsGroups: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " Options: "
+msgstr " Modifiloj: "
+
+#: plugins/sudoers/parse.c:518
+#, c-format
+msgid " Commands:\n"
+msgstr " Komandoj:\n"
+
+#: plugins/sudoers/parse.c:709
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Kongruantaj eroj de Defaults: %s en %s:\n"
+
+#: plugins/sudoers/parse.c:727
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Plenumigkiela komando-specifaj aŭtomataĵoj por %s:\n"
+
+#: plugins/sudoers/parse.c:745
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Uzanto %s rajtas plenumigi la jenajn komandojn en %s:\n"
+
+#: plugins/sudoers/parse.c:760
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Uzanto %s ne rajtas plenumigi sudo-on en %s.\n"
+
+#: plugins/sudoers/policy.c:83 plugins/sudoers/policy.c:109
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "malvalida %.*s difinita de sudo-fasado"
+
+#: plugins/sudoers/policy.c:288 plugins/sudoers/testsudoers.c:259
+msgid "unable to parse network address list"
+msgstr "ne eblas trakti reto-adresan liston"
+
+#: plugins/sudoers/policy.c:432
+msgid "user name not set by sudo front-end"
+msgstr "uzantnomo ne difinita de sudo-fasado"
+
+#: plugins/sudoers/policy.c:436
+msgid "user ID not set by sudo front-end"
+msgstr "uzanto-ID ne difinita de sudo-fasado"
+
+#: plugins/sudoers/policy.c:440
+msgid "group ID not set by sudo front-end"
+msgstr "grupo-ID ne difinita de sudo-fasado"
+
+#: plugins/sudoers/policy.c:444
+msgid "host name not set by sudo front-end"
+msgstr "gastiganta nomo ne difinita de sudo-fasado"
+
+#: plugins/sudoers/policy.c:797 plugins/sudoers/visudo.c:215
+#: plugins/sudoers/visudo.c:845
+#, c-format
+msgid "unable to execute %s"
+msgstr "ne eblas plenumigi: %s"
+
+#: plugins/sudoers/policy.c:930
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Eldono %s de la konduta kromprogramo\n"
+
+#: plugins/sudoers/policy.c:932
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Eldono %d de la gramatikilo de sudoers\n"
+
+#: plugins/sudoers/policy.c:936
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Vojo de sudoers: %s\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "vojo de nsswitch: %s\n"
+
+#: plugins/sudoers/policy.c:941
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "vojo de ldap.conf: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "vojo de ldap.secret: %s\n"
+
+#: plugins/sudoers/policy.c:975
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "ne eblas registri hokon el tipo %d (versio %d.%d)"
+
+#: plugins/sudoers/pwutil.c:214 plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "ne eblas konservi uid-on %u, memoro plenplena"
+
+#: plugins/sudoers/pwutil.c:227
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "ne eblas konservi uid-on %u, jam ekzistas"
+
+#: plugins/sudoers/pwutil.c:287 plugins/sudoers/pwutil.c:305
+#: plugins/sudoers/pwutil.c:367 plugins/sudoers/pwutil.c:412
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "ne eblas konservi uzanton %s, memoro plenplena"
+
+#: plugins/sudoers/pwutil.c:300
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "ne eblas konservi uzanton %s, jam ekzistas"
+
+#: plugins/sudoers/pwutil.c:531 plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "ne eblas konservi gid-on %u, memoro plenplena"
+
+#: plugins/sudoers/pwutil.c:544
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "ne eblas konservi gid-on %u, jam ekzistas"
+
+#: plugins/sudoers/pwutil.c:598 plugins/sudoers/pwutil.c:616
+#: plugins/sudoers/pwutil.c:663 plugins/sudoers/pwutil.c:705
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "ne eblas konservi grupon %s, memoro plenplena"
+
+#: plugins/sudoers/pwutil.c:611
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "ne eblas konservi grupon %s, jam ekzistas"
+
+#: plugins/sudoers/pwutil.c:831 plugins/sudoers/pwutil.c:883
+#: plugins/sudoers/pwutil.c:934 plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "ne eblas konservi grupan liston por %s, jam ekzistas"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:888
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:992
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "ne eblas konservi grupan liston por %s, memoro plenplena"
+
+#: plugins/sudoers/pwutil.c:877
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "ne eblas trakti grupon en %s"
+
+#: plugins/sudoers/pwutil.c:981
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "ne eblas trakti 'gids' por %s"
+
+#: plugins/sudoers/set_perms.c:113 plugins/sudoers/set_perms.c:469
+#: plugins/sudoers/set_perms.c:912 plugins/sudoers/set_perms.c:1239
+#: plugins/sudoers/set_perms.c:1556
+msgid "perm stack overflow"
+msgstr "permeso-staka troo"
+
+#: plugins/sudoers/set_perms.c:121 plugins/sudoers/set_perms.c:400
+#: plugins/sudoers/set_perms.c:477 plugins/sudoers/set_perms.c:779
+#: plugins/sudoers/set_perms.c:920 plugins/sudoers/set_perms.c:1163
+#: plugins/sudoers/set_perms.c:1247 plugins/sudoers/set_perms.c:1489
+#: plugins/sudoers/set_perms.c:1564 plugins/sudoers/set_perms.c:1654
+msgid "perm stack underflow"
+msgstr "permeso-staka maltroo"
+
+#: plugins/sudoers/set_perms.c:180 plugins/sudoers/set_perms.c:523
+#: plugins/sudoers/set_perms.c:1298 plugins/sudoers/set_perms.c:1596
+msgid "unable to change to root gid"
+msgstr "ne eblas ŝanĝi al radika gid"
+
+#: plugins/sudoers/set_perms.c:269 plugins/sudoers/set_perms.c:620
+#: plugins/sudoers/set_perms.c:1049 plugins/sudoers/set_perms.c:1375
+msgid "unable to change to runas gid"
+msgstr "ne eblas ŝanĝi al plenumigkiela gid"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to set runas group vector"
+msgstr "ne eblas elekti vektoron de plenumigkiela grupo"
+
+#: plugins/sudoers/set_perms.c:285 plugins/sudoers/set_perms.c:636
+#: plugins/sudoers/set_perms.c:1063 plugins/sudoers/set_perms.c:1389
+msgid "unable to change to runas uid"
+msgstr "ne eblas ŝanĝi al plenumigkiela uid"
+
+#: plugins/sudoers/set_perms.c:303 plugins/sudoers/set_perms.c:654
+#: plugins/sudoers/set_perms.c:1079 plugins/sudoers/set_perms.c:1405
+msgid "unable to change to sudoers gid"
+msgstr "ne eblas ŝanĝi al gid de sudo-redaktantoj"
+
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1476
+#: plugins/sudoers/set_perms.c:1641
+msgid "too many processes"
+msgstr "tro da procezoj"
+
+#: plugins/sudoers/solaris_audit.c:51
+msgid "unable to get current working directory"
+msgstr "ne eblas scii la nunan labor-dosierujon"
+
+#: plugins/sudoers/solaris_audit.c:59
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "tranĉita ekzamen-vojo user_cmnd: %s"
+
+#: plugins/sudoers/solaris_audit.c:66
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "tranĉita ekzamen-vojo argv[0]: %s"
+
+#: plugins/sudoers/solaris_audit.c:115
+msgid "audit_failure message too long"
+msgstr "mesaĝo audit_failure (ekzamena fiasko) tro longas"
+
+#: plugins/sudoers/sssd.c:552
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "ne eblas ekigi SSS-fonton. Ĉu SSSD estas instalita en via maŝino?"
+
+#: plugins/sudoers/sssd.c:560 plugins/sudoers/sssd.c:569
+#: plugins/sudoers/sssd.c:578 plugins/sudoers/sssd.c:587
+#: plugins/sudoers/sssd.c:596
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "ne eblas trovi simbolon \"%s\" en %s"
+
+#: plugins/sudoers/sudoers.c:204 plugins/sudoers/sudoers.c:859
+msgid "problem with defaults entries"
+msgstr "problemoj kun aŭtomataj eroj"
+
+#: plugins/sudoers/sudoers.c:208
+msgid "no valid sudoers sources found, quitting"
+msgstr "ne validaj fontotekstoj de sudoers trovita, ĉesiganta"
+
+#: plugins/sudoers/sudoers.c:246
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers specifas, ke ĉefuzanto ne rajtas sudo-i"
+
+#: plugins/sudoers/sudoers.c:303
+msgid "you are not permitted to use the -C option"
+msgstr "vi ne rajtas uzi la parametron -C"
+
+#: plugins/sudoers/sudoers.c:350
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "tempo-indikila posedanto (%s): neniu tia uzanto"
+
+#: plugins/sudoers/sudoers.c:365
+msgid "no tty"
+msgstr "neniu tty"
+
+#: plugins/sudoers/sudoers.c:366
+msgid "sorry, you must have a tty to run sudo"
+msgstr "bedaŭre vi devas havi tty-on por plenumigi sudo-on"
+
+#: plugins/sudoers/sudoers.c:428
+msgid "command in current directory"
+msgstr "komando en nuna dosierujo"
+
+#: plugins/sudoers/sudoers.c:447
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "bedaŭre vi ne rajtas elekti komando-eksvalidiĝo"
+
+#: plugins/sudoers/sudoers.c:455
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "bedaŭre vi ne rajtas konservi la medion"
+
+#: plugins/sudoers/sudoers.c:803
+msgid "command too long"
+msgstr "komando tro longas"
+
+#: plugins/sudoers/sudoers.c:917
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s ne estas normala dosiero"
+
+#: plugins/sudoers/sudoers.c:921 plugins/sudoers/timestamp.c:221 toke.l:968
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s estas estrita de uid %u, devas esti %u"
+
+#: plugins/sudoers/sudoers.c:925 toke.l:973
+#, c-format
+msgid "%s is world writable"
+msgstr "%s estas skribebla de ĉiuj"
+
+#: plugins/sudoers/sudoers.c:929 toke.l:976
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s estas estrita de gid %u, devas esti %u"
+
+#: plugins/sudoers/sudoers.c:962
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "nur ĉefuzanto rajtas uzi \"-c %s\""
+
+#: plugins/sudoers/sudoers.c:981
+#, c-format
+msgid "unknown login class: %s"
+msgstr "nekonata ensaluta klaso: %s"
+
+#: plugins/sudoers/sudoers.c:1064 plugins/sudoers/sudoers.c:1078
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "ne eblas trovi gastiganton %s"
+
+#: plugins/sudoers/sudoreplay.c:274
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "malvalida filtrila elekto: %s"
+
+#: plugins/sudoers/sudoreplay.c:287
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "malvalida maksimuma atendo: %s"
+
+#: plugins/sudoers/sudoreplay.c:307
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "malvalida rapida faktoro: %s"
+
+#: plugins/sudoers/sudoreplay.c:342
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s tempo-registrado: %s"
+
+#: plugins/sudoers/sudoreplay.c:348
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/tempo-registrado: %s"
+
+#: plugins/sudoers/sudoreplay.c:364
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Refaranta sudo-seancon: %s"
+
+#: plugins/sudoers/sudoreplay.c:562 plugins/sudoers/sudoreplay.c:609
+#: plugins/sudoers/sudoreplay.c:816 plugins/sudoers/sudoreplay.c:906
+#: plugins/sudoers/sudoreplay.c:985 plugins/sudoers/sudoreplay.c:1000
+#: plugins/sudoers/sudoreplay.c:1007 plugins/sudoers/sudoreplay.c:1014
+#: plugins/sudoers/sudoreplay.c:1021 plugins/sudoers/sudoreplay.c:1028
+#: plugins/sudoers/sudoreplay.c:1174
+msgid "unable to add event to queue"
+msgstr "ne eblas aldoni eventon al atendovico"
+
+#: plugins/sudoers/sudoreplay.c:677
+msgid "unable to set tty to raw mode"
+msgstr "ne eblas elekti tty-on en nudan reĝimon"
+
+#: plugins/sudoers/sudoreplay.c:728
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Averto: via terminalo estas tro malgranda por konvene reskribi la protokolon.\n"
+
+#: plugins/sudoers/sudoreplay.c:729
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Protokola grando estas %dx%d, sed via terminala grando estas %dx%d."
+
+#: plugins/sudoers/sudoreplay.c:757
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Refarado finita, premu iu ajn klavon por restarigi la terminalon."
+
+#: plugins/sudoers/sudoreplay.c:790
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "malvalida linio en la tempo-registran dosieron: %s"
+
+#: plugins/sudoers/sudoreplay.c:1208 plugins/sudoers/sudoreplay.c:1233
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "ambigua esprimo \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1255
+msgid "unmatched ')' in expression"
+msgstr "esprimo kun ')' sen samnivela '('"
+
+#: plugins/sudoers/sudoreplay.c:1259
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "nekonata serĉaĵo \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1274
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s bezonas parametron"
+
+#: plugins/sudoers/sudoreplay.c:1277 plugins/sudoers/sudoreplay.c:1657
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "malvalida regulesprimo: %s"
+
+#: plugins/sudoers/sudoreplay.c:1281
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "ne eblis analizi daton \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1290
+msgid "unmatched '(' in expression"
+msgstr "esprimo kun '(' sen samnivela ')'"
+
+#: plugins/sudoers/sudoreplay.c:1292
+msgid "illegal trailing \"or\""
+msgstr "malvalida posta \"or\""
+
+#: plugins/sudoers/sudoreplay.c:1294
+msgid "illegal trailing \"!\""
+msgstr "malvalida posta \"!\""
+
+#: plugins/sudoers/sudoreplay.c:1343
+#, c-format
+msgid "unknown search type %d"
+msgstr "nekonata serĉtipo %d"
+
+#: plugins/sudoers/sudoreplay.c:1381
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: malvalida protokolo-dosiero"
+
+#: plugins/sudoers/sudoreplay.c:1399
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: mankas temp-indikila kampo"
+
+#: plugins/sudoers/sudoreplay.c:1406
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: temp-indikilo %s: %s"
+
+#: plugins/sudoers/sudoreplay.c:1413
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: mankas kampo de uzanto"
+
+#: plugins/sudoers/sudoreplay.c:1422
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: mankas kampo de runa uzanto"
+
+#: plugins/sudoers/sudoreplay.c:1431
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: mankas kampo de runa grupo"
+
+#: plugins/sudoers/sudoreplay.c:1837
+#, c-format
+msgid "usage: %s [-hnR] [-d dir] [-m num] [-s num] ID\n"
+msgstr "uzado: %s [-hnR] [-d dosierujo] [-m nombro] [-s nombro] identigilo\n"
+
+#: plugins/sudoers/sudoreplay.c:1840
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "uzado: %s [-h] [-d dosierujo] -l [serĉaĵo]\n"
+
+#: plugins/sudoers/sudoreplay.c:1849
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - refari sudo-seancajn protokolojn\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1851
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Modifiloj:\n"
+" -d ,--directory=dosierujo specifi dosierujon por seancaj protokoloj\n"
+" -f, --filter=filtrilo specifi kiajn eneligajn tipojn por montri\n"
+" -h, --help montri helpan mesaĝon kaj eliri\n"
+" -l, --list listigi haveblajn seancajn identigilojn, kiuj kongruas kun esprimo\n"
+" -m, --max-wait=nombro maksimuma nombro da sekundoj por atendi inter okazoj\n"
+" -s, --speed=nombro rapidigi aŭ malrapidigi eligon\n"
+" -V, --version eligi eldonan informon kaj eliri"
+
+#: plugins/sudoers/testsudoers.c:328
+msgid "\thost unmatched"
+msgstr "\thost sen egalo"
+
+#: plugins/sudoers/testsudoers.c:331
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Komando permesata"
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Komando rifuzata"
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Komando sen egalo"
+
+#: plugins/sudoers/timestamp.c:229
+#, c-format
+msgid "%s is group writable"
+msgstr "%s estas skribebla de la grupo"
+
+#: plugins/sudoers/timestamp.c:305
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "ne eblas mallongigi tempo-indikilan dosieron ĝis %lld bajtoj"
+
+#: plugins/sudoers/timestamp.c:792 plugins/sudoers/timestamp.c:884
+#: plugins/sudoers/visudo.c:477 plugins/sudoers/visudo.c:483
+msgid "unable to read the clock"
+msgstr "ne eblas legi la horloĝon"
+
+#: plugins/sudoers/timestamp.c:803
+msgid "ignoring time stamp from the future"
+msgstr "ignoranta tempo-indikilon el la estonteco"
+
+#: plugins/sudoers/timestamp.c:826
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "tempo-indikilo tro estonte: %20.20s"
+
+#: plugins/sudoers/timestamp.c:948
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "ne eblas ŝlosi tempo-indikilan dosieron %s"
+
+#: plugins/sudoers/timestamp.c:992 plugins/sudoers/timestamp.c:1012
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "vojo de prelega stato tro longas: %s/%s"
+
+#: plugins/sudoers/visudo.c:211
+msgid "the -x option will be removed in a future release"
+msgstr "la domifilo -x estos forigita en posta eldono"
+
+#: plugins/sudoers/visudo.c:212
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "bonvolu konsideri uzi la utilaĵon cvtsudoers anstataŭe"
+
+#: plugins/sudoers/visudo.c:263 plugins/sudoers/visudo.c:645
+#, c-format
+msgid "press return to edit %s: "
+msgstr "premu enen-klavon por redakti %s-on: "
+
+#: plugins/sudoers/visudo.c:324
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "specifita tekstoredaktilo (%s) ne ekzistas"
+
+#: plugins/sudoers/visudo.c:326
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "neniu tekstoredaktilo trovita (vojo = %s)"
+
+#: plugins/sudoers/visudo.c:436 plugins/sudoers/visudo.c:444
+msgid "write error"
+msgstr "skriba eraro"
+
+#: plugins/sudoers/visudo.c:490
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "ne eblas stat-i provizoran dosieron (%s), %s neŝanĝita"
+
+#: plugins/sudoers/visudo.c:497
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "nul-longa provizora dosiero (%s), %s neŝanĝita"
+
+#: plugins/sudoers/visudo.c:503
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "redaktilo (%s) malsukcesis, %s neŝanĝita"
+
+#: plugins/sudoers/visudo.c:525
+#, c-format
+msgid "%s unchanged"
+msgstr "%s neŝanĝita"
+
+#: plugins/sudoers/visudo.c:584
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "ne eblas remalfermi provizoran dosieron (%s), %s neŝanĝita."
+
+#: plugins/sudoers/visudo.c:596
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "ne eblas analizi provizoran dosieron (%s), nekonata eraro"
+
+#: plugins/sudoers/visudo.c:634
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "interna eraro, ne eblas trovi '%s'-on en listo!"
+
+#: plugins/sudoers/visudo.c:714 plugins/sudoers/visudo.c:723
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "ne eblas ŝanĝi (uid, gid) de %s al (%u, %u)"
+
+#: plugins/sudoers/visudo.c:745
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s kaj %s ne estas la sama dosiersistemo, uzanta mv-on por alinomi"
+
+#: plugins/sudoers/visudo.c:759
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "komando malsukcesis: '%s %s %s', %s neŝanĝita"
+
+#: plugins/sudoers/visudo.c:769
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "eraro dum alinomi %s-on; %s neŝanĝita"
+
+#: plugins/sudoers/visudo.c:790
+msgid "What now? "
+msgstr "Kion nun? "
+
+#: plugins/sudoers/visudo.c:804
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Elektoj estas:\n"
+" r(e)dakti refoje sudoers-dosieron\n"
+" x) eliri sen konservi ŝanĝojn al sudoers-dosiero\n"
+" q) Eliri kaj konservi ŝanĝojn al sudoers-dosiero (DANĜERA!)\n"
+
+#: plugins/sudoers/visudo.c:850
+#, c-format
+msgid "unable to run %s"
+msgstr "ne eblas plenumigi: %s"
+
+#: plugins/sudoers/visudo.c:880
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: malĝusta estro (uid, gid) devas esti (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:887
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: misaj permesoj, devas esti reĝimo 0%o\n"
+
+#: plugins/sudoers/visudo.c:944 plugins/sudoers/visudo.c:951
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: analizita senerare\n"
+
+#: plugins/sudoers/visudo.c:998
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s okupata, reprovu pli malfrue"
+
+#: plugins/sudoers/visudo.c:1038
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Eraro: %s:%d ciklo en %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1039
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Averto: %s:%d ciklo en %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1043
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Eraro: %s:%d %s \"%s\" estas referencita sed ne difinita"
+
+#: plugins/sudoers/visudo.c:1044
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Averto: %s:%d %s \"%s\" estas referencita sed ne difinita"
+
+#: plugins/sudoers/visudo.c:1137
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Averto: %s:%d neuzata %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1252
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - sekure redakti la dosieron sudoers\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1254
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"Modifiloj:\n"
+" -c, --check nur kontroli\n"
+" -f, --file=sudoers indiki lokon de la dosiero sudoers\n"
+" -h, --help montri helpan mesaĝon kaj eliri\n"
+" -q, --quit pli silenta pri sintaksaj eraroj\n"
+" -s, --strict severa kontrolado de sintakso\n"
+" -V, --version montri eldonon kaj eliri\n"
+
+#: toke.l:942
+msgid "too many levels of includes"
+msgstr "tro da niveloj de inkluzivaĵoj"
+
+#~ msgid ""
+#~ "\n"
+#~ "LDAP Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "LDAP-rolo: NEKONATA\n"
+
+#~ msgid " Order: %s\n"
+#~ msgstr " Ordo: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: %s\n"
+#~ msgstr ""
+#~ "\n"
+#~ "SSSD-rolo: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "SSSD-rolo: NEKONATA\n"
diff --git a/plugins/sudoers/po/eu.mo b/plugins/sudoers/po/eu.mo
new file mode 100644
index 0000000..9f2ccc4
--- /dev/null
+++ b/plugins/sudoers/po/eu.mo
Binary files differ
diff --git a/plugins/sudoers/po/eu.po b/plugins/sudoers/po/eu.po
new file mode 100644
index 0000000..6fa330e
--- /dev/null
+++ b/plugins/sudoers/po/eu.po
@@ -0,0 +1,1679 @@
+# Basque translation of sudoers.
+# Copyright (C) 2011 Free Software Foundation, Inc.
+# This file is distributed under the same license as the sudo package.
+# Mikel Olasagasti Uranga <mikel@olasagasti.info>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers-1.8.2-rc2\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2011-06-04 18:27-0400\n"
+"PO-Revision-Date: 2011-06-06 19:15+0100\n"
+"Last-Translator: Mikel Olasagasti Uranga <mikel@olasagasti.info>\n"
+"Language-Team: Basque <translation-team-eu@lists.sourceforge.net>\n"
+"Language: \n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: plugins/sudoers/alias.c:122
+#, c-format
+msgid "Alias `%s' already defined"
+msgstr "`%s' alias-a lehendik ere definitua dago"
+
+#: plugins/sudoers/bsm_audit.c:58 plugins/sudoers/bsm_audit.c:61
+#: plugins/sudoers/bsm_audit.c:109 plugins/sudoers/bsm_audit.c:113
+#: plugins/sudoers/bsm_audit.c:163 plugins/sudoers/bsm_audit.c:167
+msgid "getaudit: failed"
+msgstr "getaudit: huts egin du"
+
+#: plugins/sudoers/bsm_audit.c:87 plugins/sudoers/bsm_audit.c:148
+msgid "Could not determine audit condition"
+msgstr "Ezin izan da auditoretza baldintza finkatu"
+
+#: plugins/sudoers/bsm_audit.c:98
+msgid "getauid failed"
+msgstr "getauid-ek huts egin du"
+
+#: plugins/sudoers/bsm_audit.c:100 plugins/sudoers/bsm_audit.c:157
+msgid "au_open: failed"
+msgstr "au_open: huts egin du"
+
+#: plugins/sudoers/bsm_audit.c:115 plugins/sudoers/bsm_audit.c:169
+msgid "au_to_subject: failed"
+msgstr "au_to_subject: huts egin du"
+
+#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:173
+msgid "au_to_exec_args: failed"
+msgstr "au_to_exec_args: huts egin du"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:182
+msgid "au_to_return32: failed"
+msgstr "au_to_return32: huts egin du"
+
+#: plugins/sudoers/bsm_audit.c:126 plugins/sudoers/bsm_audit.c:185
+msgid "unable to commit audit record"
+msgstr "ezin da auditoretza sarrera gorde"
+
+#: plugins/sudoers/bsm_audit.c:155
+msgid "getauid: failed"
+msgstr "getauid: huts egin du"
+
+#: plugins/sudoers/bsm_audit.c:178
+msgid "au_to_text: failed"
+msgstr "au_to_text: huts egin du"
+
+#: plugins/sudoers/check.c:141
+#, c-format
+msgid "sorry, a password is required to run %s"
+msgstr "barkatu, pasahitz bat behar da %s abiarazteko"
+
+#: plugins/sudoers/check.c:225 plugins/sudoers/iolog.c:169
+#: plugins/sudoers/sudoers.c:939 plugins/sudoers/sudoreplay.c:325
+#: plugins/sudoers/sudoreplay.c:334 plugins/sudoers/sudoreplay.c:675
+#: plugins/sudoers/sudoreplay.c:767 plugins/sudoers/visudo.c:700
+#, c-format
+msgid "unable to open %s"
+msgstr "ezin da %s ireki"
+
+#: plugins/sudoers/check.c:229 plugins/sudoers/iolog.c:199
+#, c-format
+msgid "unable to write to %s"
+msgstr "ezin da %s-(e)ra idatzi"
+
+#: plugins/sudoers/check.c:237 plugins/sudoers/check.c:475
+#: plugins/sudoers/check.c:525 plugins/sudoers/iolog.c:122
+#: plugins/sudoers/iolog.c:153
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "ezin da mkdir %s egin"
+
+#: plugins/sudoers/check.c:370
+#, c-format
+msgid "internal error, expand_prompt() overflow"
+msgstr "barne errorea, expand_prompt() overflow"
+
+#: plugins/sudoers/check.c:426
+#, c-format
+msgid "timestamp path too long: %s"
+msgstr ""
+
+#: plugins/sudoers/check.c:454 plugins/sudoers/check.c:498
+#: plugins/sudoers/iolog.c:155
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s existitzen da baina ez da direktorio bat (0%o)"
+
+#: plugins/sudoers/check.c:457 plugins/sudoers/check.c:501
+#: plugins/sudoers/check.c:546
+#, c-format
+msgid "%s owned by uid %u, should be uid %u"
+msgstr "%s-(r)en jabea %u uid-a da, %u uid-a beharko luke"
+
+#: plugins/sudoers/check.c:462 plugins/sudoers/check.c:506
+#, c-format
+msgid "%s writable by non-owner (0%o), should be mode 0700"
+msgstr ""
+
+#: plugins/sudoers/check.c:470 plugins/sudoers/check.c:514
+#: plugins/sudoers/check.c:582 plugins/sudoers/sudoers.c:925
+#: plugins/sudoers/visudo.c:284 plugins/sudoers/visudo.c:500
+#, c-format
+msgid "unable to stat %s"
+msgstr "ezin da stat egin %s-(r)engan"
+
+#: plugins/sudoers/check.c:540
+#, c-format
+msgid "%s exists but is not a regular file (0%o)"
+msgstr ""
+
+#: plugins/sudoers/check.c:552
+#, c-format
+msgid "%s writable by non-owner (0%o), should be mode 0600"
+msgstr ""
+
+#: plugins/sudoers/check.c:606
+#, c-format
+msgid "timestamp too far in the future: %20.20s"
+msgstr ""
+
+#: plugins/sudoers/check.c:652
+#, c-format
+msgid "unable to remove %s (%s), will reset to the epoch"
+msgstr ""
+
+#: plugins/sudoers/check.c:659
+#, c-format
+msgid "unable to reset %s to the epoch"
+msgstr ""
+
+#: plugins/sudoers/check.c:713 plugins/sudoers/check.c:719
+#, c-format
+msgid "unknown uid: %u"
+msgstr "uid ezezaguna: %u"
+
+#: plugins/sudoers/check.c:716 plugins/sudoers/sudoers.c:736
+#: plugins/sudoers/sudoers.c:802 plugins/sudoers/sudoers.c:803
+#: plugins/sudoers/sudoers.c:1056 plugins/sudoers/sudoers.c:1057
+#: plugins/sudoers/testsudoers.c:200 plugins/sudoers/testsudoers.c:330
+#, c-format
+msgid "unknown user: %s"
+msgstr "erabiltzaile ezezaguna: %s"
+
+#: plugins/sudoers/def_data.c:27
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:31
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:35
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:39
+msgid "Put OTP prompt on its own line"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:43
+msgid "Ignore '.' in $PATH"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:47
+msgid "Always send mail when sudo is run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:51
+msgid "Send mail if user authentication fails"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:55
+msgid "Send mail if the user is not in sudoers"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:59
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:63
+msgid "Send mail if the user is not allowed to run a command"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:67
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:71
+msgid "Lecture user the first time they run sudo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:75
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:79
+msgid "Require users to authenticate by default"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:83
+msgid "Root may run sudo"
+msgstr "root-ek sudo abiarizi lezake"
+
+#: plugins/sudoers/def_data.c:87
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:91
+msgid "Log the year in the (non-syslog) log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:95
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:99
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:103
+msgid "Always set $HOME to the target user's home directory"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:107
+msgid "Allow some information gathering to give useful error messages"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:111
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:115
+msgid "Insult the user when they enter an incorrect password"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:119
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:123
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo-k EDITOR ingurune aldagaia erabiliko du"
+
+#: plugins/sudoers/def_data.c:127
+msgid "Prompt for root's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:131
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:135
+msgid "Prompt for the target user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:139
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:143
+msgid "Set the LOGNAME and USER environment variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:147
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:151
+msgid "Don't initialize the group vector to that of the target user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:155
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %d"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:159
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:163
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:167
+#, c-format
+msgid "Number of tries to enter a password: %d"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:171
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:175
+#, c-format
+msgid "Path to log file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:179
+#, c-format
+msgid "Path to mail program: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:183
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:187
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:191
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:195
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:199
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:203
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:207
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:211
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:215
+#, c-format
+msgid "Default password prompt: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:219
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr ""
+
+#: plugins/sudoers/def_data.c:223
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:227
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:231
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:235
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:239
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:243
+msgid "Preload the dummy exec functions contained in 'noexec_file'"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:247
+#, c-format
+msgid "File containing dummy exec functions: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:251
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:255
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:259
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:263
+msgid "Allow users to set arbitrary environment variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:267
+msgid "Reset the environment to a default set of variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:271
+msgid "Environment variables to check for sanity:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:275
+msgid "Environment variables to remove:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:279
+msgid "Environment variables to preserve:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:283
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:287
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:291
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:295
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:299
+msgid "Allow sudo to prompt for a password even if it would be visisble"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:303
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:307
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:311
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:315
+msgid "Log user's input for the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:319
+msgid "Log the output of the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:323
+msgid "Compress I/O logs using zlib"
+msgstr "Trinkotu S/E gertaerak zlib erabiliz"
+
+#: plugins/sudoers/def_data.c:327
+msgid "Always run commands in a pseudo-tty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:331
+msgid "Plugin for non-Unix group support"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:335
+msgid "Directory in which to store input/output logs"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:339
+msgid "File in which to store the input/output log"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:343
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:347
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:197
+msgid ""
+"Available options in a sudoers ``Defaults'' line:\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:204 plugins/sudoers/defaults.c:215
+#, c-format
+msgid "%s: %s\n"
+msgstr "%s: %s\n"
+
+#: plugins/sudoers/defaults.c:211
+#, c-format
+msgid "%s: %.*s\n"
+msgstr "%s: %.*s\n"
+
+#: plugins/sudoers/defaults.c:241
+#, c-format
+msgid "unknown defaults entry `%s'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:249 plugins/sudoers/defaults.c:259
+#: plugins/sudoers/defaults.c:279 plugins/sudoers/defaults.c:292
+#: plugins/sudoers/defaults.c:305 plugins/sudoers/defaults.c:318
+#: plugins/sudoers/defaults.c:331 plugins/sudoers/defaults.c:351
+#: plugins/sudoers/defaults.c:361
+#, c-format
+msgid "value `%s' is invalid for option `%s'"
+msgstr "`%s' balorea baliogabea da `%s' aukerarentzat"
+
+#: plugins/sudoers/defaults.c:252 plugins/sudoers/defaults.c:262
+#: plugins/sudoers/defaults.c:270 plugins/sudoers/defaults.c:287
+#: plugins/sudoers/defaults.c:300 plugins/sudoers/defaults.c:313
+#: plugins/sudoers/defaults.c:326 plugins/sudoers/defaults.c:346
+#: plugins/sudoers/defaults.c:357
+#, c-format
+msgid "no value specified for `%s'"
+msgstr "ez da baliorik ezarri `%s'-(r)entzat"
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "values for `%s' must start with a '/'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:337
+#, c-format
+msgid "option `%s' does not take a value"
+msgstr ""
+
+#: plugins/sudoers/env.c:259
+#, c-format
+msgid "internal error, sudo_setenv() overflow"
+msgstr ""
+
+#: plugins/sudoers/env.c:289
+#, c-format
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr ""
+
+#: plugins/sudoers/env.c:694
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr ""
+
+#: plugins/sudoers/find_path.c:68 plugins/sudoers/find_path.c:107
+#: plugins/sudoers/find_path.c:122 plugins/sudoers/iolog.c:124
+#: plugins/sudoers/sudoers.c:868 toke.l:663 toke.l:814
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: gram.y:103
+#, c-format
+msgid ">>> %s: %s near line %d <<<"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:91
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: plugins/sudoers/group_plugin.c:103
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:107
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:114
+#, c-format
+msgid "unable to dlopen %s: %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:119
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:124
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:109
+msgid "Local IP address and netmask pairs:\n"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:176 plugins/sudoers/sudoers.c:946
+#, c-format
+msgid "unable to read %s"
+msgstr "ezin da %s irakurri"
+
+#: plugins/sudoers/iolog.c:179
+#, c-format
+msgid "invalid sequence number %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:225 plugins/sudoers/iolog.c:228
+#: plugins/sudoers/iolog.c:478 plugins/sudoers/iolog.c:483
+#: plugins/sudoers/iolog.c:489 plugins/sudoers/iolog.c:497
+#: plugins/sudoers/iolog.c:505 plugins/sudoers/iolog.c:513
+#: plugins/sudoers/iolog.c:521
+#, c-format
+msgid "unable to create %s"
+msgstr "ezin da %s sortu"
+
+#: plugins/sudoers/iolog_path.c:245 plugins/sudoers/sudoers.c:361
+#, c-format
+msgid "unable to set locale to \"%s\", using \"C\""
+msgstr ""
+
+#: plugins/sudoers/ldap.c:363
+#, c-format
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: port too large"
+
+#: plugins/sudoers/ldap.c:386
+#, c-format
+msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+msgstr "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+
+#: plugins/sudoers/ldap.c:415
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:444
+#, c-format
+msgid "invalid uri: %s"
+msgstr "baliogabeko uri-a: %s"
+
+#: plugins/sudoers/ldap.c:450
+#, c-format
+msgid "unable to mix ldap and ldaps URIs"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:454
+#, c-format
+msgid "unable to mix ldaps and starttls"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:473
+#, c-format
+msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:536
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:932
+#, c-format
+msgid "unable to get GMT time"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:938
+#, c-format
+msgid "unable to format timestamp"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:946
+#, c-format
+msgid "unable to build time filter"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1044
+#, c-format
+msgid "sudo_ldap_build_pass1 allocation mismatch"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1539
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1541
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1588
+#, c-format
+msgid " Order: %s\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1596
+#, c-format
+msgid " Commands:\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1983
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2014
+#, c-format
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2245
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:55
+#, c-format
+msgid "unable to open audit system"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:79
+#, c-format
+msgid "internal error, linux_audit_command() overflow"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:88
+#, c-format
+msgid "unable to send audit message"
+msgstr ""
+
+#: plugins/sudoers/logging.c:193
+#, c-format
+msgid "unable to open log file: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:196
+#, c-format
+msgid "unable to lock log file: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:295
+msgid "user NOT in sudoers"
+msgstr "erabiltzailea ez dago sudoers-en"
+
+#: plugins/sudoers/logging.c:297
+msgid "user NOT authorized on host"
+msgstr "erabiltzailea ez dago baimendutako ostalarian"
+
+#: plugins/sudoers/logging.c:299
+msgid "command not allowed"
+msgstr "komandua ez dago baimenduta"
+
+#: plugins/sudoers/logging.c:309
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s ez dago sudoers fitxatzegian. Gertaeraren berri emango da.\n"
+
+#: plugins/sudoers/logging.c:312
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s ez dago baimenduta sudo abiarazteko %s-(e)n. Gertaeraren berri emango da.\n"
+
+#: plugins/sudoers/logging.c:316
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Barkatu, %s erabiltzaileak ez luke sudo abiariazi beharko %s-(e)n.\n"
+
+#: plugins/sudoers/logging.c:319
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Barkatu, %s erabiltzaileak ez du '%s%s%s' %s%s%s bezala exekutatzeko baimenik %s-(e)n.\n"
+
+#: plugins/sudoers/logging.c:454
+#, c-format
+msgid "unable to fork"
+msgstr ""
+
+#: plugins/sudoers/logging.c:461 plugins/sudoers/logging.c:518
+#, c-format
+msgid "unable to fork: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:511
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:530
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:564
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:774
+#, c-format
+msgid "internal error: insufficient space for log line"
+msgstr ""
+
+#: plugins/sudoers/parse.c:115
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr ""
+
+#: plugins/sudoers/parse.c:369
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+
+#: plugins/sudoers/parse.c:371
+#, c-format
+msgid " RunAsUsers: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:386
+#, c-format
+msgid " RunAsGroups: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:395
+#, c-format
+msgid ""
+" Commands:\n"
+"\t"
+msgstr ""
+
+#: plugins/sudoers/plugin_error.c:100 plugins/sudoers/plugin_error.c:105
+msgid ": "
+msgstr ": "
+
+#: plugins/sudoers/pwutil.c:244
+#, c-format
+msgid "unable to cache uid %u (%s), already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:252
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:288 plugins/sudoers/pwutil.c:297
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:511
+#, c-format
+msgid "unable to cache gid %u (%s), already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:519
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:548 plugins/sudoers/pwutil.c:557
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:249 plugins/sudoers/set_perms.c:476
+#: plugins/sudoers/set_perms.c:710
+#, c-format
+msgid "unable to change to sudoers gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:514
+#: plugins/sudoers/set_perms.c:748 plugins/sudoers/set_perms.c:882
+msgid "too many processes"
+msgstr "prozesu gehiegi"
+
+#: plugins/sudoers/set_perms.c:943 plugins/sudoers/set_perms.c:959
+msgid "unable to set runas group vector"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:952
+msgid "unable to get runas group vector"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:217
+msgid "unable to reset group vector"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:223
+msgid "unable to get group vector"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:266
+#, c-format
+msgid "Matching Defaults entries for %s on this host:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:279
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:292
+#, c-format
+msgid "User %s may run the following commands on this host:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:302
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:206 plugins/sudoers/sudoers.c:241
+#: plugins/sudoers/sudoers.c:876
+msgid "problem with defaults entries"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:210
+#, c-format
+msgid "no valid sudoers sources found, quitting"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:264
+#, c-format
+msgid "unable to execute %s: %s"
+msgstr "ezin da %s exekutatu: %s"
+
+#: plugins/sudoers/sudoers.c:311
+#, c-format
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:318
+#, c-format
+msgid "you are not permitted to use the -C option"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:407
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "data-zigiluaren jabea (%s): ez dago horrelako erabiltzailerik"
+
+#: plugins/sudoers/sudoers.c:423
+msgid "no tty"
+msgstr "tty gabe"
+
+#: plugins/sudoers/sudoers.c:424
+#, c-format
+msgid "sorry, you must have a tty to run sudo"
+msgstr "barkatu, tty bat behar duzu sudo abiarazteko"
+
+#: plugins/sudoers/sudoers.c:470
+msgid "No user or host"
+msgstr "Ez dago erabiltzaile edo ostalaririk"
+
+#: plugins/sudoers/sudoers.c:484 plugins/sudoers/sudoers.c:505
+#: plugins/sudoers/sudoers.c:506 plugins/sudoers/sudoers.c:1413
+#: plugins/sudoers/sudoers.c:1414
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: komandoa ez da aurkitu"
+
+#: plugins/sudoers/sudoers.c:486 plugins/sudoers/sudoers.c:502
+#, c-format
+msgid ""
+"ignoring `%s' found in '.'\n"
+"Use `sudo ./%s' if this is the `%s' you wish to run."
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:491
+msgid "validation failure"
+msgstr "balidazio hutsegitea"
+
+#: plugins/sudoers/sudoers.c:501
+msgid "command in current directory"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:513
+#, c-format
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:860
+#, c-format
+msgid "internal error, set_cmnd() overflow"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:904
+#, c-format
+msgid "fixed mode on %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:908
+#, c-format
+msgid "set group on %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:911
+#, c-format
+msgid "unable to set group on %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:914
+#, c-format
+msgid "unable to fix mode on %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:927
+#, c-format
+msgid "%s is not a regular file"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:929
+#, c-format
+msgid "%s is mode 0%o, should be 0%o"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:933
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:936
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:980
+#, c-format
+msgid "only root can use `-c %s'"
+msgstr "soilik root-ek erabili dezake `-c %s'"
+
+#: plugins/sudoers/sudoers.c:990
+#, c-format
+msgid "unknown login class: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1024
+#, c-format
+msgid "unable to resolve host %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1076 plugins/sudoers/testsudoers.c:342
+#, c-format
+msgid "unknown group: %s"
+msgstr "talde ezezaguna: %s"
+
+#: plugins/sudoers/sudoers.c:1108
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1110
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1114
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Sudoers-en bidea: %s\n"
+
+#: plugins/sudoers/sudoers.c:1117
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "nsswitch-en bidea: %s\n"
+
+#: plugins/sudoers/sudoers.c:1119
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "ldap.conf-en bidea: %s\n"
+
+#: plugins/sudoers/sudoers.c:1120
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "ldap.secret-en bidea: %s\n"
+
+#: plugins/sudoers/sudoreplay.c:265
+#, c-format
+msgid "invalid filter option: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:278
+#, c-format
+msgid "invalid max wait: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:287 plugins/sudoers/visudo.c:174
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s bertsioa %s\n"
+
+#: plugins/sudoers/sudoreplay.c:310
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:316
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "invalid log file %s"
+msgstr "baliogabeko %s log fitxategia"
+
+#: plugins/sudoers/sudoreplay.c:343
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:369
+#, c-format
+msgid "unable to set tty to raw mode"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:383
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:425
+#, c-format
+msgid "writing to standard output"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:455
+#, c-format
+msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:503 plugins/sudoers/sudoreplay.c:528
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:545
+#, c-format
+msgid "too many parenthesized expressions, max %d"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:556
+#, c-format
+msgid "unmatched ')' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:562
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:576
+#, c-format
+msgid "%s requires an argument"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:580
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:586
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:599
+#, c-format
+msgid "unmatched '(' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:601
+#, c-format
+msgid "illegal trailing \"or\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:603
+#, c-format
+msgid "illegal trailing \"!\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:819
+#, c-format
+msgid "invalid regex: %s"
+msgstr "baliogabeko regex-a: %s"
+
+#: plugins/sudoers/sudoreplay.c:941
+#, c-format
+msgid "usage: %s [-h] [-d directory] [-m max_wait] [-s speed_factor] ID\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:944
+#, c-format
+msgid "usage: %s [-h] [-d directory] -l [search expression]\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:953
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:955
+msgid ""
+"\n"
+"Options:\n"
+" -d directory specify directory for session logs\n"
+" -f filter specify which I/O type to display\n"
+" -h display help message and exit\n"
+" -l [expression] list available session IDs that match expression\n"
+" -m max_wait max number of seconds to wait between events\n"
+" -s speed_factor speed up or slow down output\n"
+" -V display version information and exit"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:228
+#, c-format
+msgid "internal error, init_vars() overflow"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:304
+msgid "\thost unmatched"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:307
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:308
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:308
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+
+#: toke.l:667 toke.l:793 toke.l:818 toke.l:904 plugins/sudoers/toke_util.c:111
+#: plugins/sudoers/toke_util.c:163 plugins/sudoers/toke_util.c:202
+msgid "unable to allocate memory"
+msgstr ""
+
+#: toke.l:786
+msgid "too many levels of includes"
+msgstr "include maila gehiegi"
+
+#: plugins/sudoers/toke_util.c:213
+msgid "fill_args: buffer overflow"
+msgstr "fill_args: buffer overflow"
+
+#: plugins/sudoers/visudo.c:175
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:208 plugins/sudoers/auth/rfc1938.c:103
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "ez zara %s datubasean existitzen"
+
+#: plugins/sudoers/visudo.c:238 plugins/sudoers/visudo.c:470
+#, c-format
+msgid "press return to edit %s: "
+msgstr "sakatu intro %s editatzeko:"
+
+#: plugins/sudoers/visudo.c:300 plugins/sudoers/visudo.c:306
+#, c-format
+msgid "write error"
+msgstr "idazketa errorea"
+
+#: plugins/sudoers/visudo.c:360
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:365
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:371
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:394
+#, c-format
+msgid "%s unchanged"
+msgstr "%s aldatu gabea"
+
+#: plugins/sudoers/visudo.c:418
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr ""
+
+#: plugins/sudoers/visudo.c:428
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:463
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:502 plugins/sudoers/visudo.c:511
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%d, %d)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:506 plugins/sudoers/visudo.c:516
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:533
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:547
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:557
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:617
+msgid "What now? "
+msgstr "Eta orain?"
+
+#: plugins/sudoers/visudo.c:631
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:668
+#, c-format
+msgid "unable to execute %s"
+msgstr "ezin da %s exekutatu"
+
+#: plugins/sudoers/visudo.c:675
+#, c-format
+msgid "unable to run %s"
+msgstr "ezin da %s abiarazi"
+
+#: plugins/sudoers/visudo.c:706
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:718
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:721
+#, c-format
+msgid "parse error in %s\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:723
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:737
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%d, %d)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:744
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:783
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s okupatuta, saiatu berriz beranduago"
+
+#: plugins/sudoers/visudo.c:826
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:849
+#, c-format
+msgid "unable to stat editor (%s)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:897
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:986
+#, c-format
+msgid "Error: cycle in %s_Alias `%s'"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:987
+#, c-format
+msgid "Warning: cycle in %s_Alias `%s'"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:990
+#, c-format
+msgid "Error: %s_Alias `%s' referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:991
+#, c-format
+msgid "Warning: %s_Alias `%s' referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1128
+#, c-format
+msgid "%s: unused %s_Alias %s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1185
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1187
+msgid ""
+"\n"
+"Options:\n"
+" -c check-only mode\n"
+" -f sudoers specify sudoers file location\n"
+" -h display help message and exit\n"
+" -q less verbose (quiet) syntax error messages\n"
+" -s strict syntax checking\n"
+" -V display version information and exit"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:64
+msgid "unable to begin bsd authentication"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:71
+msgid "invalid authentication type"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:79
+msgid "unable to setup authentication"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:59
+#, c-format
+msgid "unable to read fwtk config"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:64
+#, c-format
+msgid "unable to connect to authentication server"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:70 plugins/sudoers/auth/fwtk.c:93
+#: plugins/sudoers/auth/fwtk.c:126
+#, c-format
+msgid "lost connection to authentication server"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:74
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:114
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:127
+#, c-format
+msgid "%s: unable to unparse princ ('%s'): %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:144
+#, c-format
+msgid "%s: unable to resolve ccache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:188
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:204
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to initialize ccache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:221
+#, c-format
+msgid "%s: unable to store cred in ccache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:284
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:299
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:99
+msgid "unable to initialize PAM"
+msgstr "ezin da PAM hasieratu"
+
+#: plugins/sudoers/auth/pam.c:142
+msgid "account validation failure, is your account locked?"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:146
+msgid "Account or password is expired, reset your password and try again"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:153
+#, c-format
+msgid "pam_chauthtok: %s"
+msgstr "pam_chauthtok: %s"
+
+#: plugins/sudoers/auth/pam.c:157
+msgid "Password expired, contact your system administrator"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:161
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:176
+#, c-format
+msgid "pam_authenticate: %s"
+msgstr "pam_authenticate: %s"
+
+#: plugins/sudoers/auth/pam.c:296
+msgid "Password: "
+msgstr "Pasahitza: "
+
+#: plugins/sudoers/auth/pam.c:297
+msgid "Password:"
+msgstr "Pasahitza:"
+
+#: plugins/sudoers/auth/securid.c:82 plugins/sudoers/auth/securid5.c:106
+#, c-format
+msgid "unable to contact the SecurID server"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:81
+#, c-format
+msgid "failed to initialise the ACE API library"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:115
+#, c-format
+msgid "User ID locked for SecurID Authentication"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:119 plugins/sudoers/auth/securid5.c:169
+#, c-format
+msgid "invalid username length for SecurID"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:123 plugins/sudoers/auth/securid5.c:174
+#, c-format
+msgid "invalid Authentication Handle for SecurID"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:127
+#, c-format
+msgid "SecurID communication failed"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:131 plugins/sudoers/auth/securid5.c:213
+#, c-format
+msgid "unknown SecurID error"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:164
+#, c-format
+msgid "invalid passcode length for SecurID"
+msgstr ""
+
+#: plugins/sudoers/auth/sia.c:106
+msgid "unable to initialize SIA session"
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:124
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:134
+msgid "Invalid authentication methods compiled into sudo! You may mix standalone and non-standalone authentication."
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:243
+#, c-format
+msgid "%d incorrect password attempt"
+msgid_plural "%d incorrect password attempts"
+msgstr[0] "pasahitz sartze saiakera oker %d"
+msgstr[1] "%d pasahitz sartze saiakera oker"
+
+#: plugins/sudoers/auth/sudo_auth.c:335
+msgid "Authentication methods:"
+msgstr "Autentikazio metodoak:"
diff --git a/plugins/sudoers/po/fi.mo b/plugins/sudoers/po/fi.mo
new file mode 100644
index 0000000..1811849
--- /dev/null
+++ b/plugins/sudoers/po/fi.mo
Binary files differ
diff --git a/plugins/sudoers/po/fi.po b/plugins/sudoers/po/fi.po
new file mode 100644
index 0000000..3797f6c
--- /dev/null
+++ b/plugins/sudoers/po/fi.po
@@ -0,0 +1,2361 @@
+# Finnish messages for sudoers.
+# This file is put in the public domain.
+# This file is distributed under the same license as the sudo package.
+# Jorma Karvonen <karvonen.jorma@gmail.com>, 2011-2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.21b2\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2017-08-03 10:04-0600\n"
+"PO-Revision-Date: 2017-08-20 16:23+0300\n"
+"Last-Translator: Jorma Karvonen <karvonen.jorma@gmail.com>\n"
+"Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
+"Language: fi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "syntaksivirhe"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "%p:n salasana: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] salasana henkilölle %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Salasana: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** TURVALLISUUS-tietoja kohteelle %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Yritä uudelleen."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:307 gram.y:314 gram.y:321 gram.y:328 gram.y:335
+#: gram.y:398 gram.y:406 gram.y:416 gram.y:449 gram.y:456 gram.y:463
+#: gram.y:470 gram.y:552 gram.y:559 gram.y:568 gram.y:577 gram.y:594
+#: gram.y:706 gram.y:713 gram.y:720 gram.y:728 gram.y:824 gram.y:831
+#: gram.y:838 gram.y:845 gram.y:852 gram.y:878 gram.y:885 gram.y:892
+#: gram.y:1015 gram.y:1195 gram.y:1202 plugins/sudoers/alias.c:124
+#: plugins/sudoers/alias.c:139 plugins/sudoers/auth/bsdauth.c:141
+#: plugins/sudoers/auth/kerb5.c:119 plugins/sudoers/auth/kerb5.c:145
+#: plugins/sudoers/auth/pam.c:486 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/auth/sia.c:59 plugins/sudoers/defaults.c:647
+#: plugins/sudoers/defaults.c:902 plugins/sudoers/defaults.c:1073
+#: plugins/sudoers/editor.c:64 plugins/sudoers/editor.c:82
+#: plugins/sudoers/editor.c:93 plugins/sudoers/env.c:233
+#: plugins/sudoers/filedigest.c:120 plugins/sudoers/filedigest_gcrypt.c:90
+#: plugins/sudoers/filedigest_openssl.c:111 plugins/sudoers/gc.c:52
+#: plugins/sudoers/group_plugin.c:134 plugins/sudoers/interfaces.c:71
+#: plugins/sudoers/iolog.c:941 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:449 plugins/sudoers/ldap.c:480
+#: plugins/sudoers/ldap.c:532 plugins/sudoers/ldap.c:565
+#: plugins/sudoers/ldap.c:963 plugins/sudoers/ldap.c:1157
+#: plugins/sudoers/ldap.c:1168 plugins/sudoers/ldap.c:1184
+#: plugins/sudoers/ldap.c:1476 plugins/sudoers/ldap.c:1636
+#: plugins/sudoers/ldap.c:1718 plugins/sudoers/ldap.c:1858
+#: plugins/sudoers/ldap.c:1882 plugins/sudoers/ldap.c:1971
+#: plugins/sudoers/ldap.c:1986 plugins/sudoers/ldap.c:2082
+#: plugins/sudoers/ldap.c:2115 plugins/sudoers/ldap.c:2196
+#: plugins/sudoers/ldap.c:2278 plugins/sudoers/ldap.c:2375
+#: plugins/sudoers/ldap.c:3209 plugins/sudoers/ldap.c:3241
+#: plugins/sudoers/ldap.c:3550 plugins/sudoers/ldap.c:3578
+#: plugins/sudoers/ldap.c:3594 plugins/sudoers/ldap.c:3684
+#: plugins/sudoers/ldap.c:3700 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:189 plugins/sudoers/logging.c:451
+#: plugins/sudoers/logging.c:472 plugins/sudoers/logging.c:684
+#: plugins/sudoers/logging.c:942 plugins/sudoers/match.c:617
+#: plugins/sudoers/match.c:664 plugins/sudoers/match.c:714
+#: plugins/sudoers/match.c:738 plugins/sudoers/match.c:826
+#: plugins/sudoers/match.c:915 plugins/sudoers/parse.c:248
+#: plugins/sudoers/parse.c:260 plugins/sudoers/parse.c:275
+#: plugins/sudoers/parse.c:287 plugins/sudoers/policy.c:419
+#: plugins/sudoers/policy.c:653 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/pwutil.c:139 plugins/sudoers/pwutil.c:210
+#: plugins/sudoers/pwutil.c:286 plugins/sudoers/pwutil.c:457
+#: plugins/sudoers/pwutil.c:522 plugins/sudoers/pwutil.c:591
+#: plugins/sudoers/pwutil.c:749 plugins/sudoers/pwutil.c:806
+#: plugins/sudoers/pwutil.c:851 plugins/sudoers/pwutil.c:908
+#: plugins/sudoers/sssd.c:162 plugins/sudoers/sssd.c:194
+#: plugins/sudoers/sssd.c:237 plugins/sudoers/sssd.c:244
+#: plugins/sudoers/sssd.c:280 plugins/sudoers/sssd.c:390
+#: plugins/sudoers/sssd.c:459 plugins/sudoers/sssd.c:1057
+#: plugins/sudoers/sssd.c:1236 plugins/sudoers/sssd.c:1250
+#: plugins/sudoers/sssd.c:1266 plugins/sudoers/sudoers.c:263
+#: plugins/sudoers/sudoers.c:273 plugins/sudoers/sudoers.c:281
+#: plugins/sudoers/sudoers.c:365 plugins/sudoers/sudoers.c:681
+#: plugins/sudoers/sudoers.c:806 plugins/sudoers/sudoers.c:850
+#: plugins/sudoers/sudoers.c:1122 plugins/sudoers/sudoers_debug.c:107
+#: plugins/sudoers/sudoreplay.c:1234 plugins/sudoers/sudoreplay.c:1346
+#: plugins/sudoers/sudoreplay.c:1386 plugins/sudoers/sudoreplay.c:1395
+#: plugins/sudoers/sudoreplay.c:1405 plugins/sudoers/sudoreplay.c:1413
+#: plugins/sudoers/sudoreplay.c:1417 plugins/sudoers/sudoreplay.c:1573
+#: plugins/sudoers/sudoreplay.c:1577 plugins/sudoers/testsudoers.c:131
+#: plugins/sudoers/testsudoers.c:217 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/timestamp.c:389 plugins/sudoers/timestamp.c:433
+#: plugins/sudoers/timestamp.c:852 plugins/sudoers/toke_util.c:56
+#: plugins/sudoers/toke_util.c:109 plugins/sudoers/toke_util.c:146
+#: plugins/sudoers/visudo.c:153 plugins/sudoers/visudo.c:309
+#: plugins/sudoers/visudo.c:315 plugins/sudoers/visudo.c:446
+#: plugins/sudoers/visudo.c:624 plugins/sudoers/visudo.c:985
+#: plugins/sudoers/visudo.c:1051 plugins/sudoers/visudo.c:1095
+#: plugins/sudoers/visudo.c:1197 plugins/sudoers/visudo_json.c:1025 toke.l:849
+#: toke.l:949 toke.l:1106
+msgid "unable to allocate memory"
+msgstr "muistin varaaminen epäonnistui"
+
+#: gram.y:481
+msgid "a digest requires a path name"
+msgstr "tiiviste vaatii polkunimen"
+
+#: gram.y:607
+msgid "invalid notbefore value"
+msgstr "virheellinen notbefore-arvo"
+
+#: gram.y:615
+msgid "invalid notafter value"
+msgstr "virheellinen notafter-arvo"
+
+#: gram.y:624 plugins/sudoers/policy.c:266
+msgid "timeout value too large"
+msgstr "aikavalvonta-arvo on liian iso"
+
+#: gram.y:626 plugins/sudoers/policy.c:268
+msgid "invalid timeout value"
+msgstr "virheellinen aikavalvonta-arvo"
+
+#: gram.y:1195 gram.y:1202 plugins/sudoers/auth/pam.c:320
+#: plugins/sudoers/auth/pam.c:486 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/defaults.c:647 plugins/sudoers/defaults.c:902
+#: plugins/sudoers/defaults.c:1073 plugins/sudoers/editor.c:64
+#: plugins/sudoers/editor.c:82 plugins/sudoers/editor.c:93
+#: plugins/sudoers/env.c:233 plugins/sudoers/filedigest.c:120
+#: plugins/sudoers/filedigest_gcrypt.c:72
+#: plugins/sudoers/filedigest_gcrypt.c:90
+#: plugins/sudoers/filedigest_openssl.c:111 plugins/sudoers/gc.c:52
+#: plugins/sudoers/group_plugin.c:134 plugins/sudoers/interfaces.c:71
+#: plugins/sudoers/iolog.c:941 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:449 plugins/sudoers/ldap.c:480
+#: plugins/sudoers/ldap.c:532 plugins/sudoers/ldap.c:565
+#: plugins/sudoers/ldap.c:963 plugins/sudoers/ldap.c:1157
+#: plugins/sudoers/ldap.c:1168 plugins/sudoers/ldap.c:1184
+#: plugins/sudoers/ldap.c:1476 plugins/sudoers/ldap.c:1636
+#: plugins/sudoers/ldap.c:1718 plugins/sudoers/ldap.c:1858
+#: plugins/sudoers/ldap.c:1882 plugins/sudoers/ldap.c:1971
+#: plugins/sudoers/ldap.c:1986 plugins/sudoers/ldap.c:2082
+#: plugins/sudoers/ldap.c:2115 plugins/sudoers/ldap.c:2195
+#: plugins/sudoers/ldap.c:2278 plugins/sudoers/ldap.c:2375
+#: plugins/sudoers/ldap.c:3209 plugins/sudoers/ldap.c:3241
+#: plugins/sudoers/ldap.c:3550 plugins/sudoers/ldap.c:3577
+#: plugins/sudoers/ldap.c:3593 plugins/sudoers/ldap.c:3684
+#: plugins/sudoers/ldap.c:3700 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:189 plugins/sudoers/logging.c:451
+#: plugins/sudoers/logging.c:472 plugins/sudoers/logging.c:942
+#: plugins/sudoers/match.c:616 plugins/sudoers/match.c:663
+#: plugins/sudoers/match.c:714 plugins/sudoers/match.c:738
+#: plugins/sudoers/match.c:826 plugins/sudoers/match.c:914
+#: plugins/sudoers/parse.c:248 plugins/sudoers/parse.c:260
+#: plugins/sudoers/parse.c:275 plugins/sudoers/parse.c:287
+#: plugins/sudoers/policy.c:99 plugins/sudoers/policy.c:108
+#: plugins/sudoers/policy.c:117 plugins/sudoers/policy.c:141
+#: plugins/sudoers/policy.c:252 plugins/sudoers/policy.c:266
+#: plugins/sudoers/policy.c:268 plugins/sudoers/policy.c:292
+#: plugins/sudoers/policy.c:301 plugins/sudoers/policy.c:340
+#: plugins/sudoers/policy.c:350 plugins/sudoers/policy.c:359
+#: plugins/sudoers/policy.c:368 plugins/sudoers/policy.c:419
+#: plugins/sudoers/policy.c:653 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/pwutil.c:139 plugins/sudoers/pwutil.c:210
+#: plugins/sudoers/pwutil.c:286 plugins/sudoers/pwutil.c:457
+#: plugins/sudoers/pwutil.c:522 plugins/sudoers/pwutil.c:591
+#: plugins/sudoers/pwutil.c:749 plugins/sudoers/pwutil.c:806
+#: plugins/sudoers/pwutil.c:851 plugins/sudoers/pwutil.c:908
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1476
+#: plugins/sudoers/set_perms.c:1641 plugins/sudoers/sssd.c:162
+#: plugins/sudoers/sssd.c:194 plugins/sudoers/sssd.c:237
+#: plugins/sudoers/sssd.c:244 plugins/sudoers/sssd.c:280
+#: plugins/sudoers/sssd.c:390 plugins/sudoers/sssd.c:459
+#: plugins/sudoers/sssd.c:1057 plugins/sudoers/sssd.c:1235
+#: plugins/sudoers/sssd.c:1250 plugins/sudoers/sssd.c:1266
+#: plugins/sudoers/sudoers.c:263 plugins/sudoers/sudoers.c:273
+#: plugins/sudoers/sudoers.c:281 plugins/sudoers/sudoers.c:365
+#: plugins/sudoers/sudoers.c:681 plugins/sudoers/sudoers.c:806
+#: plugins/sudoers/sudoers.c:850 plugins/sudoers/sudoers.c:1122
+#: plugins/sudoers/sudoers_debug.c:106 plugins/sudoers/sudoreplay.c:1234
+#: plugins/sudoers/sudoreplay.c:1346 plugins/sudoers/sudoreplay.c:1386
+#: plugins/sudoers/sudoreplay.c:1395 plugins/sudoers/sudoreplay.c:1405
+#: plugins/sudoers/sudoreplay.c:1413 plugins/sudoers/sudoreplay.c:1417
+#: plugins/sudoers/sudoreplay.c:1573 plugins/sudoers/sudoreplay.c:1577
+#: plugins/sudoers/testsudoers.c:131 plugins/sudoers/testsudoers.c:217
+#: plugins/sudoers/testsudoers.c:234 plugins/sudoers/timestamp.c:389
+#: plugins/sudoers/timestamp.c:433 plugins/sudoers/timestamp.c:852
+#: plugins/sudoers/toke_util.c:56 plugins/sudoers/toke_util.c:109
+#: plugins/sudoers/toke_util.c:146 plugins/sudoers/visudo.c:153
+#: plugins/sudoers/visudo.c:309 plugins/sudoers/visudo.c:315
+#: plugins/sudoers/visudo.c:446 plugins/sudoers/visudo.c:624
+#: plugins/sudoers/visudo.c:985 plugins/sudoers/visudo.c:1051
+#: plugins/sudoers/visudo.c:1095 plugins/sudoers/visudo.c:1197
+#: plugins/sudoers/visudo_json.c:1025 toke.l:849 toke.l:949 toke.l:1106
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:135
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Alias \"%s\" on jo määritelty"
+
+#: plugins/sudoers/auth/bsdauth.c:68
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "kirjautumisluokan saaminen käyttäjälle %s epäonnistui"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+msgid "unable to begin bsd authentication"
+msgstr "bsd-todentamisen aloittaminen epäonnistui"
+
+#: plugins/sudoers/auth/bsdauth.c:81
+msgid "invalid authentication type"
+msgstr "virheellinen todennustyyppi"
+
+#: plugins/sudoers/auth/bsdauth.c:90
+msgid "unable to initialize BSD authentication"
+msgstr "BSD-todentamisen alustaminen epäonnistui"
+
+#: plugins/sudoers/auth/fwtk.c:52
+msgid "unable to read fwtk config"
+msgstr "fwtk config -asetuksen lukeminen epäonnistui"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to connect to authentication server"
+msgstr "todentamispalvelimelle yhdistäminen epäonnistui"
+
+#: plugins/sudoers/auth/fwtk.c:63 plugins/sudoers/auth/fwtk.c:87
+#: plugins/sudoers/auth/fwtk.c:121
+msgid "lost connection to authentication server"
+msgstr "kadotettiin yhteys todentamispalvelimelle"
+
+#: plugins/sudoers/auth/fwtk.c:67
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"todentamispalvelinvirhe:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:111
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: valtuutetun (’%s’) muuntaminen merkkijonoksi epäonnistui: %s"
+
+# Ensimmäinen parametri on auth name
+#: plugins/sudoers/auth/kerb5.c:161
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: todentamisnimen ’%s’ jäsentäminen epäonnistui: %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: valtuustietovälimuistin ratkaiseminen epäonnistui: %s"
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: muistin varaaminen valitsimille epäonnistui: %s"
+
+#: plugins/sudoers/auth/kerb5.c:232
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: valtuustietojen hakeminen epäonnistui: %s"
+
+#: plugins/sudoers/auth/kerb5.c:245
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: valtuustietovälimuistin alustaminen epäonnistui: %s"
+
+#: plugins/sudoers/auth/kerb5.c:248
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: valtuustietojen tallentaminen valtuustietovälimuistiin epäonnistui: %s"
+
+#: plugins/sudoers/auth/kerb5.c:312
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: tietokoneen valtuutetun hakeminen epäonnistui: %s"
+
+#: plugins/sudoers/auth/kerb5.c:326
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: TGT-lipun todentaminen epäonnistui! Mahdollinen hyökkäys!: %s"
+
+#: plugins/sudoers/auth/pam.c:108
+msgid "unable to initialize PAM"
+msgstr "PAM:in alustaminen epäonnistui"
+
+#: plugins/sudoers/auth/pam.c:194
+msgid "account validation failure, is your account locked?"
+msgstr "tilikelpuutushäiriö, onko tilisi lukittu?"
+
+#: plugins/sudoers/auth/pam.c:198
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Tili tai salasana on vanhentunut, nollaa salasanasi tai yritä uudelleen"
+
+#: plugins/sudoers/auth/pam.c:206
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "vanhentuneen salasanan vaihtaminen epäonnistui: %s"
+
+#: plugins/sudoers/auth/pam.c:211
+msgid "Password expired, contact your system administrator"
+msgstr "Salasana vanhentunut, ota yhteyttä järjestelmän ylläpitäjään"
+
+#: plugins/sudoers/auth/pam.c:215
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Tili vanhentunut tai PAM-asetuksista puuttuu ”account”-lohko sudo-komennolle, ota yhteyttä järjestelmän ylläpitäjään"
+
+#: plugins/sudoers/auth/pam.c:229
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "PAM-todentamisvirhe: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:97 plugins/sudoers/visudo.c:227
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "ei ole olemassa %s-tietokannassa"
+
+#: plugins/sudoers/auth/securid5.c:73
+msgid "failed to initialise the ACE API library"
+msgstr "ACE API -kirjaston alustaminen epäonnistui"
+
+#: plugins/sudoers/auth/securid5.c:99
+msgid "unable to contact the SecurID server"
+msgstr "yhteyden ottaminen SecurID-palvelimeen epäonnistui"
+
+#: plugins/sudoers/auth/securid5.c:108
+msgid "User ID locked for SecurID Authentication"
+msgstr "Käyttäjätunniste lukittu SecurID-todennukselle"
+
+#: plugins/sudoers/auth/securid5.c:112 plugins/sudoers/auth/securid5.c:163
+msgid "invalid username length for SecurID"
+msgstr "virheellinen käyttäjänimipituus kohteelle SecurID"
+
+#: plugins/sudoers/auth/securid5.c:116 plugins/sudoers/auth/securid5.c:168
+msgid "invalid Authentication Handle for SecurID"
+msgstr "virheellinen todentamiskäsittelijä kohteelle SecurID"
+
+#: plugins/sudoers/auth/securid5.c:120
+msgid "SecurID communication failed"
+msgstr "SecurID-viestintä epäonnistui"
+
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:213
+msgid "unknown SecurID error"
+msgstr "tuntematon SecurID-virhe"
+
+#: plugins/sudoers/auth/securid5.c:158
+msgid "invalid passcode length for SecurID"
+msgstr "virheellinen salasanakoodipituus kohteelle SecurID"
+
+#: plugins/sudoers/auth/sia.c:69 plugins/sudoers/auth/sia.c:125
+msgid "unable to initialize SIA session"
+msgstr "SIA-istunnon alustaminen epäonnistui"
+
+#: plugins/sudoers/auth/sudo_auth.c:126
+msgid "invalid authentication methods"
+msgstr "virheelliset todennusmetodit"
+
+#: plugins/sudoers/auth/sudo_auth.c:128
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Virheellisiä todennusmenetelmiä käännetty sudo-ohjelmaan! Yksittäisiä ja ei-yksittäisiä todennuksia ei voi sekoittaa keskenään."
+
+#: plugins/sudoers/auth/sudo_auth.c:224 plugins/sudoers/auth/sudo_auth.c:274
+msgid "no authentication methods"
+msgstr "ei todennusmenetelmiä:"
+
+#: plugins/sudoers/auth/sudo_auth.c:226
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Sudo-ohjelmaan ei ole käännetty todentamismenelmiä! Jos haluat kääntää pois todentamisen, käytä asetusvalitsinta --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:276
+msgid "Unable to initialize authentication methods."
+msgstr "Todentamismenetelmien alustaminen epäonnistui."
+
+#: plugins/sudoers/auth/sudo_auth.c:441
+msgid "Authentication methods:"
+msgstr "Todennusmenetelmät:"
+
+#: plugins/sudoers/bsm_audit.c:120 plugins/sudoers/bsm_audit.c:211
+msgid "Could not determine audit condition"
+msgstr "Audit-ehdon määrittely epäonnistui"
+
+#: plugins/sudoers/bsm_audit.c:183 plugins/sudoers/bsm_audit.c:273
+msgid "unable to commit audit record"
+msgstr "commit-toiminnon suorittaminen audit-tietueelle epäonnistui"
+
+#: plugins/sudoers/check.c:252
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Luotamme, että olet saanut tavanomaisen saarnan paikalliselta järjestelmän\n"
+"ylläpitäjältä. Yleensä se tiivistyy kolmeen asiaan:\n"
+"\n"
+" #1) Kunnioita muiden yksityisyyttä.\n"
+" #2) Ajattele ennen kuin kirjoitat.\n"
+" #3) Suuren voiman mukana tulee suuri vastuu.\n"
+"\n"
+
+#: plugins/sudoers/check.c:295 plugins/sudoers/check.c:305
+#: plugins/sudoers/sudoers.c:724 plugins/sudoers/sudoers.c:769
+#, c-format
+msgid "unknown uid: %u"
+msgstr "tuntematon uid-käyttäjätunniste: %u"
+
+#: plugins/sudoers/check.c:300 plugins/sudoers/iolog.c:260
+#: plugins/sudoers/policy.c:826 plugins/sudoers/sudoers.c:1161
+#: plugins/sudoers/testsudoers.c:208 plugins/sudoers/testsudoers.c:366
+#, c-format
+msgid "unknown user: %s"
+msgstr "tuntematon käyttäjä: %s"
+
+#: plugins/sudoers/def_data.c:41
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Syslog-apuneuvo, jos syslog-lokia käytetään kirjautumista varten: %s"
+
+#: plugins/sudoers/def_data.c:45
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Käytettävä syslog-prioriteetti, kun käyttäjä todennetaan onnistuneesti: %s"
+
+#: plugins/sudoers/def_data.c:49
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Käytettävä syslog-prioriteetti, kun käyttäjän todennus epäonnistui: %s"
+
+#: plugins/sudoers/def_data.c:53
+msgid "Put OTP prompt on its own line"
+msgstr "Laita OPT-kehote omalle rivilleen"
+
+#: plugins/sudoers/def_data.c:57
+msgid "Ignore '.' in $PATH"
+msgstr "Ohita ’.’ $PATH-asetuksessa"
+
+#: plugins/sudoers/def_data.c:61
+msgid "Always send mail when sudo is run"
+msgstr "Lähetä aina sähkopostia, kun sudo suoritetaan"
+
+#: plugins/sudoers/def_data.c:65
+msgid "Send mail if user authentication fails"
+msgstr "Lähetä sähköpostia, jos käyttäjän todennus epäonnistuu"
+
+#: plugins/sudoers/def_data.c:69
+msgid "Send mail if the user is not in sudoers"
+msgstr "Lähetä sähköpostia, jos käyttäjä ei ole sudoers-määrittelyssä"
+
+#: plugins/sudoers/def_data.c:73
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Lähetä sähköpostia, jos käyttäjä ei ole tällä tietokoneella sudoers-määrittelyssä"
+
+#: plugins/sudoers/def_data.c:77
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Lähetä sähköpostia, jos käyttäjän ei sallita suorittaa komentoa"
+
+#: plugins/sudoers/def_data.c:81
+msgid "Send mail if the user tries to run a command"
+msgstr "Lähetä sähköpostia, jos käyttäjä yrittää suorittaa komennon"
+
+#: plugins/sudoers/def_data.c:85
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Käytä erillistä aikaleimaa jokaiselle käyttäjä/tty -yhdistelmälle"
+
+#: plugins/sudoers/def_data.c:89
+msgid "Lecture user the first time they run sudo"
+msgstr "Saarnaa ensimmäistä kertaa sudo-ohjelmaa käyttävälle"
+
+#: plugins/sudoers/def_data.c:93
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Tiedosto, joka sisältää sudo-saarnan: %s"
+
+#: plugins/sudoers/def_data.c:97
+msgid "Require users to authenticate by default"
+msgstr "Vaadi käyttäjien todennus oletuksena"
+
+#: plugins/sudoers/def_data.c:101
+msgid "Root may run sudo"
+msgstr "Root voi suorittaa sudo-ohjelman"
+
+#: plugins/sudoers/def_data.c:105
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Kirjaa tietokonenimi (ei-syslog)lokitiedostoon"
+
+#: plugins/sudoers/def_data.c:109
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Kirjaa vuosi (ei-syslog)lokitiedostoon"
+
+#: plugins/sudoers/def_data.c:113
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Jos sudo-ohjelmaa kutsutaan ilman argumentteja, käynnistä käyttöjärjestelmäkuori"
+
+#: plugins/sudoers/def_data.c:117
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Aseta $HOME-muuttujaksi kohdekäyttäjä kun käyttöjärjestelmäkuori käynnistetään valitsimella -s"
+
+#: plugins/sudoers/def_data.c:121
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Aseta $HOME-muuttujaksi aina kohdekäyttäjän kotihakemisto"
+
+#: plugins/sudoers/def_data.c:125
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Salli jotain tietojenkeräystä hyödyllisten virheilmoitusten tarjoamiseksi"
+
+#: plugins/sudoers/def_data.c:129
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Vaadi täysin rakennettu tietokonenimi suoders-tiedostossa"
+
+#: plugins/sudoers/def_data.c:133
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Solvaa käyttäjiä, kun he kirjoittavat väärän salasanan"
+
+#: plugins/sudoers/def_data.c:137
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Salli käyttäjien suorittaa sudo-ohjelma vain jos heillä on tty"
+
+#: plugins/sudoers/def_data.c:141
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo noudattaa EDITOR-ympäristömuuttujaa"
+
+#: plugins/sudoers/def_data.c:145
+msgid "Prompt for root's password, not the users's"
+msgstr "Kysy root-käyttäjän salasana, ei käyttäjän"
+
+#: plugins/sudoers/def_data.c:149
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Kysy runas_default-käyttäjän salasana, ei käyttäjän"
+
+#: plugins/sudoers/def_data.c:153
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Kysy kohdekäyttäjän salasana, ei käyttäjän"
+
+#: plugins/sudoers/def_data.c:157
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Käytä oletuksia kohdekäyttäjän kirjautumisluokassa, jos siinä on yhtään"
+
+#: plugins/sudoers/def_data.c:161
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Aseta LOGNAME- ja USER-ympäristömuuttujat"
+
+#: plugins/sudoers/def_data.c:165
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Aseta vain voimassa oleva uid-käyttäjätunniste kohdekäyttäjälle, ei oikeaa uid-tunnistetta"
+
+#: plugins/sudoers/def_data.c:169
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Älä alusta ryhmävektoria kohdekäyttäjän vastaavaan arvoon"
+
+#: plugins/sudoers/def_data.c:173
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Pituus, jossa pitkät lokitiedostorivit jaetaan seuraavalle riville (0 ei jaeta): %u"
+
+#: plugins/sudoers/def_data.c:177
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Todennusaikaleiman aikavalvonta: %.1f minuuttia"
+
+#: plugins/sudoers/def_data.c:181
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Salasanakehotteen aikavalvonta: %.1f minuuttia"
+
+#: plugins/sudoers/def_data.c:185
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Salasanayritysten lukumäärä: %u"
+
+#: plugins/sudoers/def_data.c:189
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Käytettävä umask-määrittely tai 0777 käytettäväksi käyttäjän umask-määrittelyksi: 0%o"
+
+#: plugins/sudoers/def_data.c:193
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Polku lokitiedostoon: %s"
+
+#: plugins/sudoers/def_data.c:197
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Polku sähköpostiohjelmaan: %s"
+
+#: plugins/sudoers/def_data.c:201
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Sähköpostiohjelman liput: %s"
+
+#: plugins/sudoers/def_data.c:205
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Osoite, johon sähköposti lähetetään: %s"
+
+#: plugins/sudoers/def_data.c:209
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Osoite, josta sähköposti lähetetään: %s"
+
+#: plugins/sudoers/def_data.c:213
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Sähköpostiviestin Aihe-rivi: %s"
+
+#: plugins/sudoers/def_data.c:217
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Virheellinen salasanaviesti: %s"
+
+#: plugins/sudoers/def_data.c:221
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Polku luentotilahakemistoon: %s"
+
+#: plugins/sudoers/def_data.c:225
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Polku todennusaikaleimahakemistoon: %s"
+
+#: plugins/sudoers/def_data.c:229
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Todennusaikaleimahakemiston omistaja: %s"
+
+#: plugins/sudoers/def_data.c:233
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Käyttäjät tässä ryhmässä on vapautettu salasana- ja PATH-vaatimuksista: %s"
+
+#: plugins/sudoers/def_data.c:237
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Oletussalasanakehote: %s"
+
+#: plugins/sudoers/def_data.c:241
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Jos asetettu, salasanakehote korvaa järjestelmäkehotteen kaikissa tapauksissa."
+
+# Tämä on tekemisessä runas_default -määrittelyn kanssa
+#: plugins/sudoers/def_data.c:245
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Oletuskäyttäjä suorittaa komennot käyttäjänä: %s"
+
+#: plugins/sudoers/def_data.c:249
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Arvo, jolla korvataan käyttäjän $PATH-asetus: %s"
+
+#: plugins/sudoers/def_data.c:253
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Visudo-editorin käyttämä polku: %s"
+
+#: plugins/sudoers/def_data.c:257
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Kun vaaditaan salasana ’list’-näennäiskomennolle: %s"
+
+#: plugins/sudoers/def_data.c:261
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Kun vaaditaan salasana ’verify’-näennäiskomennolle: %s"
+
+#: plugins/sudoers/def_data.c:265
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Esilataa vale-exec-funktiot, jotka sisältyvät sudo_noexec-kirjastoon"
+
+#: plugins/sudoers/def_data.c:269
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Jos LDAP-hakemisto on ylhäällä, ohitammeko paikallisen sudoers-tiedoston"
+
+#: plugins/sudoers/def_data.c:273
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Tiedostokuvaajat >= %d suljetaan ennen komennon suoritusta"
+
+#: plugins/sudoers/def_data.c:277
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Jos asetettu, käyttäjä voi korvata ’closefrom’-arvon valitsimella -C"
+
+#: plugins/sudoers/def_data.c:281
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Salli käyttäjien asettaa mielivaltaisia ympäristömuuttujia"
+
+#: plugins/sudoers/def_data.c:285
+msgid "Reset the environment to a default set of variables"
+msgstr "Nollaa ympäristö muuttujien oletusjoukoksi"
+
+#: plugins/sudoers/def_data.c:289
+msgid "Environment variables to check for sanity:"
+msgstr "Ympäristömuuttujat, joille tehdään järkevyystarkistus:"
+
+#: plugins/sudoers/def_data.c:293
+msgid "Environment variables to remove:"
+msgstr "Poistettavat ympäristömuuttujat:"
+
+#: plugins/sudoers/def_data.c:297
+msgid "Environment variables to preserve:"
+msgstr "Säilytettävät ympäristömuuttujat:"
+
+#: plugins/sudoers/def_data.c:301
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Uudessa turva-asiayhteydessä käytettävä SELinux-rooli: %s"
+
+#: plugins/sudoers/def_data.c:305
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Uudessa turva-asiayhteydessä käytettävä SELinux-tyyppi: %s"
+
+#: plugins/sudoers/def_data.c:309
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Polku sudo-kohtaiseen ympäristötiedostoon: %s"
+
+#: plugins/sudoers/def_data.c:313
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Polku rajoitettuun sudo-kohtaiseen ympäristötiedostoon: %s"
+
+#: plugins/sudoers/def_data.c:317
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Locale-asetus, jota käytetään sudoers-jäsentämisessä: %s"
+
+#: plugins/sudoers/def_data.c:321
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Salli sudo-ohjelman kysyä salasana vieläpä jos se olisi näkyvä"
+
+#: plugins/sudoers/def_data.c:325
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Tarjoa visuaalista palautetta salasanakehotteelta silloin kun on käyttäjäsyöte"
+
+#: plugins/sudoers/def_data.c:329
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Käyttää nopeampaa jokerimerkkien korvausta, joka on epätarkempi, mutta ei lue tiedostojärjestelmää"
+
+#: plugins/sudoers/def_data.c:333
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "Sudoers umask korvaa käyttäjän umask-määrittelyn, vieläpä jos se on sallivampi"
+
+#: plugins/sudoers/def_data.c:337
+msgid "Log user's input for the command being run"
+msgstr "Kirjaa lokiin käyttäjän syöte suoritettavalle komennolle"
+
+#: plugins/sudoers/def_data.c:341
+msgid "Log the output of the command being run"
+msgstr "Kirjaa lokiin suoritettavan komennon tuloste"
+
+#: plugins/sudoers/def_data.c:345
+msgid "Compress I/O logs using zlib"
+msgstr "Tiivistä siirräntälokit käyttäen zlib-ohjelmaa"
+
+#: plugins/sudoers/def_data.c:349
+msgid "Always run commands in a pseudo-tty"
+msgstr "Suorita aina komennot näennäis-tty:ssä"
+
+#: plugins/sudoers/def_data.c:353
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Lisäosa ei-Unix-ryhmätuelle: %s"
+
+#: plugins/sudoers/def_data.c:357
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Hakemisto, johon tallennetaan syöte-/tulostelokit: %s"
+
+#: plugins/sudoers/def_data.c:361
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Tiedosto, johon tallennetaan syöte-/tulosteloki: %s"
+
+#: plugins/sudoers/def_data.c:365
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Lisää rivi utmp-/utmpx-tiedostoon, kun varataan pty"
+
+#: plugins/sudoers/def_data.c:369
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Aseta käyttäjäksi utmp-tiedostoon suorittava käyttäjä, ei kutsuva käyttäjä"
+
+#: plugins/sudoers/def_data.c:373
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Sallittujen käyttöoikeuksien joukko: %s"
+
+#: plugins/sudoers/def_data.c:377
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Rajoitettujen käyttöoikeuksien joukko: %s"
+
+#: plugins/sudoers/def_data.c:381
+msgid "Run commands on a pty in the background"
+msgstr "Suorita komentoja pty:llä taustalla"
+
+#: plugins/sudoers/def_data.c:385
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "Käytettävä PAM-palvelunimi: %s"
+
+#: plugins/sudoers/def_data.c:389
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "Kirjautumiskomentotulkeille käytettävä PAM-palvelunimi: %s"
+
+#: plugins/sudoers/def_data.c:393
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Yritys perustaa PAM-valtuustiedot kohdekäyttäjälle"
+
+#: plugins/sudoers/def_data.c:397
+msgid "Create a new PAM session for the command to run in"
+msgstr "Luo uusi PAM-istunto suoritettavalle komennolle"
+
+#: plugins/sudoers/def_data.c:401
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Suurin siirräntälokin sarjanumero: %u"
+
+#: plugins/sudoers/def_data.c:405
+msgid "Enable sudoers netgroup support"
+msgstr "Ota käyttöön sudoers-verkkoryhmätuki"
+
+#: plugins/sudoers/def_data.c:409
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Tarkista yläpuolella olevan hakemistojen kirjoituskelpoisuus kun tiedostoja muokataan sudoedit-ohjelmalla"
+
+#: plugins/sudoers/def_data.c:413
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Seuraa symbolisia linkejä kun tiedostoja muokataan sudoedit-ohjelmalla"
+
+#: plugins/sudoers/def_data.c:417
+msgid "Query the group plugin for unknown system groups"
+msgstr "Kysy ryhmälisäosaa tuntemattomille järjestelmäryhmille"
+
+#: plugins/sudoers/def_data.c:421
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Täsmäävät verkkoryhmät perustuen koko monikolle: käyttäjä, tietokone ja verkkotunnus"
+
+#: plugins/sudoers/def_data.c:425
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Salli komentojen suorittaminen silloinkin kun sudo ei kykene kirjoittamaan valvontatarkastuslokiin"
+
+#: plugins/sudoers/def_data.c:429
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Salli komentojen suorittaminen silloinkin kun sudo ei kykene kirjoittamaan siirtolokiin"
+
+#: plugins/sudoers/def_data.c:433
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Salli komentojen suorittaminen silloinkin kun sudo ei kykene kirjoittamaan lokitiedostoon"
+
+#: plugins/sudoers/def_data.c:437
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Ratkaise sudoers-ryhmät ja täsmäytä ryhmätunnisteeseen, ei nimeen"
+
+#: plugins/sudoers/def_data.c:441
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Lokirivit, jotka ovat pitempiä kuin tämä arvo, jaetaan useisiin syslog-viesteihin: %u"
+
+#: plugins/sudoers/def_data.c:445
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Käyttäjä, joka omistaa siirräntälokitiedostot: %s"
+
+#: plugins/sudoers/def_data.c:449
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Ryhmä, joka omistaa siirräntälokitiedostot: %s"
+
+#: plugins/sudoers/def_data.c:453
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Tiedostotila käytettäväksi siirräntälokitiedostoissa: 0%o"
+
+#: plugins/sudoers/def_data.c:457
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Suorita komentoja tiedostokuvaan avulla eikä polun avulla: %s"
+
+#: plugins/sudoers/def_data.c:461
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Ohita tuntemattomat Defaults-rivit sudoers-tiedostossa sen sijaan että tuottaisit varoituksia"
+
+#: plugins/sudoers/def_data.c:465
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Sekuntimäärä, jossa komento päätetään: %u"
+
+#: plugins/sudoers/def_data.c:469
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Salli käyttäjän määritellä aikavalvonta komentorivillä"
+
+#: plugins/sudoers/def_data.c:473
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Tyhjennä siirräntälokitiedot levylle välittömästi sen sijaan että puskuroisit ne"
+
+#: plugins/sudoers/def_data.c:477
+msgid "Include the process ID when logging via syslog"
+msgstr "Sisällytä prosessitunniste, kun kirjataan syslog-tiedostoon"
+
+#: plugins/sudoers/def_data.c:481
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Todennusaikaleimatietueen tyyppi: %s"
+
+#: plugins/sudoers/defaults.c:220
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d tuntematon oletusrivi ”%s”"
+
+#: plugins/sudoers/defaults.c:223
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: tuntematon oletusrivi ”%s”"
+
+# parametrinä on variable
+#: plugins/sudoers/defaults.c:263
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d arvoa ei ole määritelty muuttujalle ”%s”"
+
+# parametrinä on variable
+#: plugins/sudoers/defaults.c:266
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: arvoa ei ole määritelty muuttujalle ”%s”"
+
+# Parametri on muuttuja
+#: plugins/sudoers/defaults.c:286
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d muuttujan ”%s” arvojen on alettava merkillä ’/’"
+
+# Parametri on muuttuja
+#: plugins/sudoers/defaults.c:289
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: muuttujan ”%s” arvojen on alettava merkillä ’/’"
+
+#: plugins/sudoers/defaults.c:314
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d valitsin ”%s” ei ota arvoa"
+
+#: plugins/sudoers/defaults.c:317
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: valitsin ”%s” ei ota arvoa"
+
+#: plugins/sudoers/defaults.c:339
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d virheellinen Defaults-tyyppi 0x%x valitsimelle ”%s”"
+
+#: plugins/sudoers/defaults.c:342
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: virheellinen Defaults-tyyppi 0x%x valitsimelle ”%s”"
+
+#: plugins/sudoers/defaults.c:352
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d arvo ”%s” on virheellinen valitsimelle ”%s”"
+
+#: plugins/sudoers/defaults.c:355
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: arvo ”%s” on virheellinen valitsimelle ”%s”"
+
+#: plugins/sudoers/env.c:295 plugins/sudoers/env.c:302
+#: plugins/sudoers/env.c:407 plugins/sudoers/ldap.c:453
+#: plugins/sudoers/ldap.c:543 plugins/sudoers/ldap.c:1253
+#: plugins/sudoers/ldap.c:1480 plugins/sudoers/ldap.c:1806
+#: plugins/sudoers/linux_audit.c:82 plugins/sudoers/logging.c:947
+#: plugins/sudoers/policy.c:537 plugins/sudoers/policy.c:547
+#: plugins/sudoers/prompt.c:161 plugins/sudoers/sudoers.c:872
+#: plugins/sudoers/testsudoers.c:238 plugins/sudoers/toke_util.c:158
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "sisäinen virhe, %s-ylivuoto"
+
+#: plugins/sudoers/env.c:376
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: rikkoutunut envp, pituus ei täsmää"
+
+#: plugins/sudoers/env.c:1055
+msgid "unable to rebuild the environment"
+msgstr "ympäristön rakentaminen uudelleen epäonnistui"
+
+#: plugins/sudoers/env.c:1129
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "seuraavia ympäristömuuttujia ei ole lupa asettaa: %s"
+
+#: plugins/sudoers/filedigest.c:104 plugins/sudoers/filedigest_gcrypt.c:66
+#: plugins/sudoers/filedigest_openssl.c:95
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "tukematon tiivistetyyppi %d kohteelle %s"
+
+#: plugins/sudoers/filedigest.c:129 plugins/sudoers/filedigest_gcrypt.c:98
+#: plugins/sudoers/filedigest_openssl.c:120
+#, c-format
+msgid "%s: read error"
+msgstr "%s: kirjoitusvirhe"
+
+#: plugins/sudoers/group_plugin.c:86
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s-omistajan on oltava uid %d"
+
+#: plugins/sudoers/group_plugin.c:90
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s on vain omistajan kirjoitettava"
+
+#: plugins/sudoers/group_plugin.c:98 plugins/sudoers/sssd.c:398
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "kohteen %s lataaminen epäonnistui: %s"
+
+# parametrina on path
+#: plugins/sudoers/group_plugin.c:104
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "symbolin ”group_plugin” löytäminen polusta %s epäonnistui"
+
+#: plugins/sudoers/group_plugin.c:109
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: yhteensopimaton ryhmälisäosan major-versio %d, odotettiin %d"
+
+#: plugins/sudoers/interfaces.c:79 plugins/sudoers/interfaces.c:96
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "verkko-osoitteen ”%s” jäsentäminen epäonnistui"
+
+# Parametri on sudoers file
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "verkkopeitteen ”%s” jäsentäminen epäonnistui"
+
+#: plugins/sudoers/interfaces.c:129
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Paikallinen verkko-osoite ja verkkopeiteparit:\n"
+
+#: plugins/sudoers/iolog.c:121 plugins/sudoers/mkdir_parents.c:75
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s on olemassa, mutta ei ole hakemisto (0%o)"
+
+#: plugins/sudoers/iolog.c:146 plugins/sudoers/iolog.c:187
+#: plugins/sudoers/mkdir_parents.c:64 plugins/sudoers/timestamp.c:170
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "käskyn mkdir %s suorittaminen epäonnistui"
+
+#: plugins/sudoers/iolog.c:191 plugins/sudoers/visudo.c:740
+#: plugins/sudoers/visudo.c:750
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "tilan %s vaihtaminen arvoon 0%o epäonnistui"
+
+#: plugins/sudoers/iolog.c:299 plugins/sudoers/sudoers.c:1192
+#: plugins/sudoers/testsudoers.c:390
+#, c-format
+msgid "unknown group: %s"
+msgstr "tuntematon ryhmä: %s"
+
+# Avaamisen kohde voi olla timestamp file, sudoers file tai pathbuf
+#: plugins/sudoers/iolog.c:418 plugins/sudoers/sudoers.c:928
+#: plugins/sudoers/sudoreplay.c:349 plugins/sudoers/sudoreplay.c:1335
+#: plugins/sudoers/sudoreplay.c:1539 plugins/sudoers/timestamp.c:398
+#: plugins/sudoers/visudo.c:972 plugins/sudoers/visudo_json.c:1001
+#: plugins/sudoers/visudo_json.c:1014
+#, c-format
+msgid "unable to open %s"
+msgstr "kohteen %s avaaminen epäonnistui"
+
+# Parametrinä on sudoers-tiedosto tai pathbuf
+#: plugins/sudoers/iolog.c:469 plugins/sudoers/sudoers.c:932
+#: plugins/sudoers/sudoreplay.c:831 plugins/sudoers/sudoreplay.c:1650
+#, c-format
+msgid "unable to read %s"
+msgstr "kohteen %s lukeminen epäonnistui"
+
+# Kirjoittamisen kohde voi olla timestamp file tai pathbuf
+#: plugins/sudoers/iolog.c:505 plugins/sudoers/sudoreplay.c:1104
+#: plugins/sudoers/timestamp.c:290 plugins/sudoers/timestamp.c:293
+#, c-format
+msgid "unable to write to %s"
+msgstr "kohteeseen %s kirjoittaminen epäonnistui"
+
+# Parametrina on pathbuf
+#: plugins/sudoers/iolog.c:584 plugins/sudoers/iolog.c:803
+#, c-format
+msgid "unable to create %s"
+msgstr "hakemistopolun %s luominen epäonnistui"
+
+#: plugins/sudoers/iolog.c:1035 plugins/sudoers/iolog.c:1110
+#: plugins/sudoers/iolog.c:1191
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "siirtolokitiedostoon: %s kirjoittaminen epäonnistui"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, file index %d not open"
+msgstr "%s: sisäinen virhe, tiedostoindeksi %d ei ole avoin"
+
+#: plugins/sudoers/ldap.c:431
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: portti on liian suuri"
+
+# URL on verkko-osoite, loogisesti URI on verkkoresurssi(osoite)
+#: plugins/sudoers/ldap.c:491
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "tukematon LDAP-verkkoresurssin tunnustyyppi: %s"
+
+#: plugins/sudoers/ldap.c:518
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "ldap:n ja ldap-verkkoresurssitunnuksien sekoittaminen epäonnistui"
+
+#: plugins/sudoers/ldap.c:522 plugins/sudoers/ldap.c:558
+msgid "starttls not supported when using ldaps"
+msgstr "starttls ei ole tuettu ldaps-käytössä"
+
+#: plugins/sudoers/ldap.c:629
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "SSL-varmenne- ja -avaintietokannan alustaminen epäonnistui: %s"
+
+#: plugins/sudoers/ldap.c:632
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "kohteessa %s TLS_CERT on asetettava käyttämään SSL:ää"
+
+#: plugins/sudoers/ldap.c:1239
+msgid "unable to get GMT time"
+msgstr "GMT-ajan saaminen epäonnistui"
+
+#: plugins/sudoers/ldap.c:1245
+msgid "unable to format timestamp"
+msgstr "aikaleiman muotoileminen epäonnistui"
+
+#: plugins/sudoers/ldap.c:1961
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/ldap.c:2533
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"LDAP-rooli: %s\n"
+
+#: plugins/sudoers/ldap.c:2535
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"LDAP-rooli: TUNTEMATON\n"
+
+#: plugins/sudoers/ldap.c:2591
+#, c-format
+msgid " Order: %s\n"
+msgstr " Järjestys: %s\n"
+
+#: plugins/sudoers/ldap.c:2599 plugins/sudoers/parse.c:614
+#: plugins/sudoers/sssd.c:1628
+#, c-format
+msgid " Commands:\n"
+msgstr " Komennot:\n"
+
+#: plugins/sudoers/ldap.c:3161
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "kohteen LDAP alustaminen epäonnistui: %s"
+
+#: plugins/sudoers/ldap.c:3197
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls määritelty, mutta LDAP-kirjastot ei tue funktiota ldap_start_tls_s() tai funktiota ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:3446
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "virheellinen sudoOrder-attribuutti: %s"
+
+#: plugins/sudoers/linux_audit.c:52
+msgid "unable to open audit system"
+msgstr "audit-järjestelmän avaaminen epäonnistui"
+
+#: plugins/sudoers/linux_audit.c:93
+msgid "unable to send audit message"
+msgstr "audit-viestin lähettäminen epäonnistui"
+
+#: plugins/sudoers/logging.c:107
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:135
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s: (komento jatkui) %s"
+
+#: plugins/sudoers/logging.c:164
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "lokitiedoston avaaminen epäonnistui: %s"
+
+#: plugins/sudoers/logging.c:172
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "lokitiedoston lukitseminen epäonnistui: %s"
+
+#: plugins/sudoers/logging.c:205
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "lokitiedostoon: %s kirjoittaminen epäonnistui"
+
+#: plugins/sudoers/logging.c:234
+msgid "No user or host"
+msgstr "Ei käyttäjä eikä tietokone"
+
+#: plugins/sudoers/logging.c:236
+msgid "validation failure"
+msgstr "kelpuutushäiriö"
+
+#: plugins/sudoers/logging.c:243
+msgid "user NOT in sudoers"
+msgstr "käyttäjä EI ole sudoers-tiedostossa"
+
+#: plugins/sudoers/logging.c:245
+msgid "user NOT authorized on host"
+msgstr "käyttäjä ei ole varmennettu tietokoneella"
+
+#: plugins/sudoers/logging.c:247
+msgid "command not allowed"
+msgstr "komento ei ole sallittu"
+
+#: plugins/sudoers/logging.c:282
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "käyttäjä %s ei ole sudoers-tiedostossa. Tästä tapahtumasta ilmoitetaan.\n"
+
+#: plugins/sudoers/logging.c:285
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "käyttäjä %s ei saa suorittaa komentoa sudo tietokoneella %s. Tästä tapahtumasta ilmoitetaan.\n"
+
+#: plugins/sudoers/logging.c:289
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Käyttäjä %s ei voi suorittaa komentoa sudo tietokoneella %s.\n"
+
+#: plugins/sudoers/logging.c:292
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Käyttäjän %s ei sallita suorittaa ’%s%s%s’ käyttäjänä %s%s%s tietokoneella %s.\n"
+
+#: plugins/sudoers/logging.c:329 plugins/sudoers/sudoers.c:472
+#: plugins/sudoers/sudoers.c:474 plugins/sudoers/sudoers.c:476
+#: plugins/sudoers/sudoers.c:478 plugins/sudoers/sudoers.c:1297
+#: plugins/sudoers/sudoers.c:1299
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: komentoa ei löytynyt"
+
+#: plugins/sudoers/logging.c:331 plugins/sudoers/sudoers.c:468
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"ohitetaan komento ”%s”, joka löytyi kohteesta ’.’\n"
+"Käytä ”sudo ./%s”, jos tämä on ”%s”-komento, joka halutaan suorittaa."
+
+#: plugins/sudoers/logging.c:348
+msgid "authentication failure"
+msgstr "todentamishäiriö"
+
+#: plugins/sudoers/logging.c:374
+msgid "a password is required"
+msgstr "vaaditaan salasana"
+
+#: plugins/sudoers/logging.c:445 plugins/sudoers/logging.c:511
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u väärä salasana yritetty"
+msgstr[1] "%u väärää salasanaa yritetty"
+
+#: plugins/sudoers/logging.c:598
+msgid "unable to fork"
+msgstr "fork-funktion kutsuminen epäonnistui"
+
+#: plugins/sudoers/logging.c:606 plugins/sudoers/logging.c:658
+#, c-format
+msgid "unable to fork: %m"
+msgstr "fork-funktion kutsuminen epäonnistui: %m"
+
+#: plugins/sudoers/logging.c:648
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "putken avaaminen epäonnistui: %m"
+
+#: plugins/sudoers/logging.c:673
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "funktion dup kutsuminen vakiosyötteellä epäonnistui: %m"
+
+#: plugins/sudoers/logging.c:711
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "käskyn %s suorittaminen epäonnistui: %m"
+
+#: plugins/sudoers/match.c:771
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "tiiviste kohteelle %s (%s) ei ole %s-muodossa"
+
+#: plugins/sudoers/mkdir_parents.c:70 plugins/sudoers/sudoers.c:943
+#: plugins/sudoers/visudo.c:439 plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to stat %s"
+msgstr "funktion stat %s kutsuminen epäonnistui"
+
+#: plugins/sudoers/parse.c:115
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "jäsentämisvirhe tiedostossa %s lähellä riviä %d"
+
+#: plugins/sudoers/parse.c:118
+#, c-format
+msgid "parse error in %s"
+msgstr "jäsentämisvirhe tiedostossa %s"
+
+#: plugins/sudoers/parse.c:540
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Sudoers-rivi:\n"
+
+#: plugins/sudoers/parse.c:541
+#, c-format
+msgid " RunAsUsers: "
+msgstr " SuoritaKäyttäjänä: "
+
+#: plugins/sudoers/parse.c:555
+#, c-format
+msgid " RunAsGroups: "
+msgstr " SuoritaRyhmänä: "
+
+#: plugins/sudoers/parse.c:564
+#, c-format
+msgid " Options: "
+msgstr " Valitsimet: "
+
+#: plugins/sudoers/policy.c:242 plugins/sudoers/testsudoers.c:261
+msgid "unable to parse network address list"
+msgstr "verkko-osoiteluettelon jäsentäminen epäonnistui"
+
+# Parametri on path, mutta saattaa sisältää suoritettavan ohjelman
+#: plugins/sudoers/policy.c:711 plugins/sudoers/visudo.c:910
+#, c-format
+msgid "unable to execute %s"
+msgstr "kohteen %s suorittaminen epäonnistui"
+
+#: plugins/sudoers/policy.c:844
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Sudoers-menettelytapalisäosaversio %s\n"
+
+#: plugins/sudoers/policy.c:846
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Sudoers-tiedostokielioppiversio %d\n"
+
+#: plugins/sudoers/policy.c:850
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Sudoers-polku: %s\n"
+
+#: plugins/sudoers/policy.c:853
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "nsswitch-polku: %s\n"
+
+#: plugins/sudoers/policy.c:855
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "ldap.conf-polku: %s\n"
+
+#: plugins/sudoers/policy.c:856
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "ldap.secret-polku: %s\n"
+
+#: plugins/sudoers/policy.c:889
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "kytkentätyypin %d (version %d.%d) rekisteröiminen epäonnistui"
+
+#: plugins/sudoers/pwutil.c:162 plugins/sudoers/pwutil.c:180
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "käyttäjän uid %u laittaminen välimuistiin epäonnistui, muistia ei riittävästi"
+
+#: plugins/sudoers/pwutil.c:174
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "käyttäjän uid %u laittaminen välimuistiin epäonnistui, käyttäjä on jo siellä"
+
+#: plugins/sudoers/pwutil.c:234 plugins/sudoers/pwutil.c:251
+#: plugins/sudoers/pwutil.c:313 plugins/sudoers/pwutil.c:358
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "käyttäjän %s laittaminen välimuistiin epäonnistui, muistia ei riittävästi"
+
+#: plugins/sudoers/pwutil.c:246
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "käyttäjän %s laittaminen välimuistiin epäonnistui, käyttäjä on jo siellä"
+
+#: plugins/sudoers/pwutil.c:474 plugins/sudoers/pwutil.c:492
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "ryhmän gid %u laittaminen välimuistiin epäonnistui, muistia ei riittävästi"
+
+#: plugins/sudoers/pwutil.c:486
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "ryhmän gid %u laittaminen välimuistiin epäonnistui, ryhmä on jo siellä"
+
+#: plugins/sudoers/pwutil.c:540 plugins/sudoers/pwutil.c:557
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:646
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "ryhmän %s laittaminen välimuistiin epäonnistui, muistia ei riittävästi"
+
+#: plugins/sudoers/pwutil.c:552
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "ryhmän %s laittaminen välimuistiin epäonnistui, ryhmä on jo siellä"
+
+#: plugins/sudoers/pwutil.c:772 plugins/sudoers/pwutil.c:824
+#: plugins/sudoers/pwutil.c:874 plugins/sudoers/pwutil.c:926
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "ryhmäluettelon laittaminen välimuistiin tiedostossa %s epäonnistui, ryhmäluettelo on jo siellä"
+
+#: plugins/sudoers/pwutil.c:778 plugins/sudoers/pwutil.c:829
+#: plugins/sudoers/pwutil.c:880 plugins/sudoers/pwutil.c:931
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "ryhmäluettelon laittaminen välimuistiin tiedostossa %s epäonnistui, muistia ei riittävästi"
+
+# Parametri on sudoers file
+#: plugins/sudoers/pwutil.c:818
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "ryhmien jäsentäminen tiedostossa %s epäonnistui"
+
+# Parametri on sudoers file
+#: plugins/sudoers/pwutil.c:920
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "ryhmätunnisteiden jäsentäminen tiedostolle %s epäonnistui"
+
+#: plugins/sudoers/set_perms.c:113 plugins/sudoers/set_perms.c:469
+#: plugins/sudoers/set_perms.c:912 plugins/sudoers/set_perms.c:1239
+#: plugins/sudoers/set_perms.c:1556
+msgid "perm stack overflow"
+msgstr "käyttöoikeuspinoylivuoto"
+
+#: plugins/sudoers/set_perms.c:121 plugins/sudoers/set_perms.c:400
+#: plugins/sudoers/set_perms.c:477 plugins/sudoers/set_perms.c:779
+#: plugins/sudoers/set_perms.c:920 plugins/sudoers/set_perms.c:1163
+#: plugins/sudoers/set_perms.c:1247 plugins/sudoers/set_perms.c:1489
+#: plugins/sudoers/set_perms.c:1564 plugins/sudoers/set_perms.c:1654
+msgid "perm stack underflow"
+msgstr "käyttöoikeuspinovajaus"
+
+#: plugins/sudoers/set_perms.c:180 plugins/sudoers/set_perms.c:523
+#: plugins/sudoers/set_perms.c:1298 plugins/sudoers/set_perms.c:1596
+msgid "unable to change to root gid"
+msgstr "vaihtaminen root gid -tunnisteeksi epäonnistui"
+
+#: plugins/sudoers/set_perms.c:269 plugins/sudoers/set_perms.c:620
+#: plugins/sudoers/set_perms.c:1049 plugins/sudoers/set_perms.c:1375
+msgid "unable to change to runas gid"
+msgstr "vaihtaminen runas gid -tunnisteeksi epäonnistui"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to set runas group vector"
+msgstr "runas-ryhmävektorin asettaminen epäonnistui"
+
+#: plugins/sudoers/set_perms.c:285 plugins/sudoers/set_perms.c:636
+#: plugins/sudoers/set_perms.c:1063 plugins/sudoers/set_perms.c:1389
+msgid "unable to change to runas uid"
+msgstr "vaihtaminen runas uid -tunnisteeksi epäonnistui"
+
+#: plugins/sudoers/set_perms.c:303 plugins/sudoers/set_perms.c:654
+#: plugins/sudoers/set_perms.c:1079 plugins/sudoers/set_perms.c:1405
+msgid "unable to change to sudoers gid"
+msgstr "vaihtaminen sudoers gid-tunnisteeksi epäonnistui"
+
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1476
+#: plugins/sudoers/set_perms.c:1641
+msgid "too many processes"
+msgstr "liian monta prosessia"
+
+#: plugins/sudoers/solaris_audit.c:51
+msgid "unable to get current working directory"
+msgstr "nykyisen työhakemiston hakeminen epäonnistui"
+
+#: plugins/sudoers/solaris_audit.c:59
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "typistetty audit-polku user_cmnd: %s"
+
+#: plugins/sudoers/solaris_audit.c:66
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "typistetty audit-polku argv[0]: %s"
+
+#: plugins/sudoers/solaris_audit.c:115
+msgid "audit_failure message too long"
+msgstr "audit_failure-viesti on liian pitkä"
+
+#: plugins/sudoers/sssd.c:400
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "lähteen SSS alustaminen epäonnistui. Onko SSSD asennettu tietokoneeseesi?"
+
+# parametrina on path
+#: plugins/sudoers/sssd.c:408 plugins/sudoers/sssd.c:417
+#: plugins/sudoers/sssd.c:426 plugins/sudoers/sssd.c:435
+#: plugins/sudoers/sssd.c:444
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "symbolin ”%s” löytäminen polusta %s epäonnistui"
+
+#: plugins/sudoers/sssd.c:1543
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: %s\n"
+msgstr ""
+"\n"
+"SSSD-rooli: %s\n"
+
+#: plugins/sudoers/sssd.c:1548
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"SSSD-rooli: TUNTEMATON\n"
+
+#: plugins/sudoers/sudo_nss.c:290
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Täsmäävät Defaults-rivit kohteelle %s kohteella %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:308
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Runas- ja Command-kohtaiset oletukset kohteelle %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:326
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Käyttäjä %s voi suorittaa seuraavat komennot kohteella %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:339
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Käyttäjä %s ei saa suorittaa komentoa sudo tietokoneella %s.\n"
+
+#: plugins/sudoers/sudoers.c:168 plugins/sudoers/testsudoers.c:247
+#: plugins/sudoers/visudo.c:233 plugins/sudoers/visudo.c:612
+#: plugins/sudoers/visudo.c:976
+msgid "unable to initialize sudoers default values"
+msgstr "sudoers-oletusarvojen alustaminen epäonnistui"
+
+#: plugins/sudoers/sudoers.c:198 plugins/sudoers/sudoers.c:890
+msgid "problem with defaults entries"
+msgstr "oletusrivien pulma"
+
+#: plugins/sudoers/sudoers.c:205
+msgid "no valid sudoers sources found, quitting"
+msgstr "ei löytynyt kelvollisia sudoers-lähteitä, poistutaan"
+
+#: plugins/sudoers/sudoers.c:244
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers määrittelee, että root ei saa suorittaa sudo-komentoa"
+
+#: plugins/sudoers/sudoers.c:301
+msgid "you are not permitted to use the -C option"
+msgstr "ei käyttöoikeuksia valitsimelle -C"
+
+#: plugins/sudoers/sudoers.c:390
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "aikaleimaomistaja (%s): Tuntematon käyttäjä"
+
+#: plugins/sudoers/sudoers.c:405
+msgid "no tty"
+msgstr "ei tty:tä"
+
+#: plugins/sudoers/sudoers.c:406
+msgid "sorry, you must have a tty to run sudo"
+msgstr "sudo-komennon suorittamiseksi on oltava tty"
+
+#: plugins/sudoers/sudoers.c:467
+msgid "command in current directory"
+msgstr "komento nykyisessä hakemistossa"
+
+#: plugins/sudoers/sudoers.c:486
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "komennon aikavalvonnan asettaminen ei ole sallittua"
+
+#: plugins/sudoers/sudoers.c:494
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "ympäristöä ei ole lupa säilyttää"
+
+#: plugins/sudoers/sudoers.c:835
+msgid "command too long"
+msgstr "komento on liian pitkä"
+
+#: plugins/sudoers/sudoers.c:947
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s ei ole tavallinen tiedosto"
+
+#: plugins/sudoers/sudoers.c:951 plugins/sudoers/timestamp.c:217 toke.l:969
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s on uid %u -käyttäjän omistama, pitäisi olla %u"
+
+#: plugins/sudoers/sudoers.c:955 toke.l:974
+#, c-format
+msgid "%s is world writable"
+msgstr "%s on yleiskirjoitettava"
+
+#: plugins/sudoers/sudoers.c:959 toke.l:977
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s on gid %u -ryhmän omistama, pitäisi olla %u"
+
+#: plugins/sudoers/sudoers.c:992
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "vain root-käyttäjä voi käyttää valitsinta ”-c %s”"
+
+#: plugins/sudoers/sudoers.c:1011
+#, c-format
+msgid "unknown login class: %s"
+msgstr "tuntematon kirjautumisluokka: %s"
+
+#: plugins/sudoers/sudoers.c:1094 plugins/sudoers/sudoers.c:1108
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "tietokoneen %s ratkaiseminen epäonnistui"
+
+#: plugins/sudoers/sudoreplay.c:275
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "virheellinen suodatinvalitsin: %s"
+
+#: plugins/sudoers/sudoreplay.c:288
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "virheellinen enimmäisodotusaika: %s"
+
+#: plugins/sudoers/sudoreplay.c:300
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "virheellinen nopeustekijä: %s"
+
+#: plugins/sudoers/sudoreplay.c:303 plugins/sudoers/visudo.c:186
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s versio %s\n"
+
+#: plugins/sudoers/sudoreplay.c:335
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/ajoitus: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/ajoitus: %s"
+
+#: plugins/sudoers/sudoreplay.c:357
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Toistetaan sudo-istunto: %s"
+
+#: plugins/sudoers/sudoreplay.c:555 plugins/sudoers/sudoreplay.c:602
+#: plugins/sudoers/sudoreplay.c:804 plugins/sudoers/sudoreplay.c:879
+#: plugins/sudoers/sudoreplay.c:958 plugins/sudoers/sudoreplay.c:973
+#: plugins/sudoers/sudoreplay.c:980 plugins/sudoers/sudoreplay.c:987
+#: plugins/sudoers/sudoreplay.c:994 plugins/sudoers/sudoreplay.c:1001
+#: plugins/sudoers/sudoreplay.c:1143
+msgid "unable to add event to queue"
+msgstr "tapahtuman lisääminen jonoon epäonnistui"
+
+#: plugins/sudoers/sudoreplay.c:670
+msgid "unable to set tty to raw mode"
+msgstr "tty:n asettaminen raakatilaan epäonnistui"
+
+#: plugins/sudoers/sudoreplay.c:721
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Varoitus: pääteikkunasi on liian pieni tämän lokin toistamiseksi oikein.\n"
+
+#: plugins/sudoers/sudoreplay.c:722
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Lokigeometria on %d x %d, pääteikkunasi geometria on %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:749
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Toistaminen päättyi, palaa pääteikkunaan painamalla mitä tahansa näppäintä."
+
+#: plugins/sudoers/sudoreplay.c:782
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "virheellinen ajoitustiedostorivi: %s"
+
+#: plugins/sudoers/sudoreplay.c:1177 plugins/sudoers/sudoreplay.c:1202
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "monimerkityksellinen lauseke ”%s”"
+
+#: plugins/sudoers/sudoreplay.c:1224
+msgid "unmatched ')' in expression"
+msgstr "täsmäämätön ’)’ lausekkeessa"
+
+#: plugins/sudoers/sudoreplay.c:1228
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "tuntematon hakutermi ”%s”"
+
+#: plugins/sudoers/sudoreplay.c:1243
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s vaatii argumentin"
+
+#: plugins/sudoers/sudoreplay.c:1246 plugins/sudoers/sudoreplay.c:1626
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "virheellinen säännöllinen lauseke: %s"
+
+#: plugins/sudoers/sudoreplay.c:1250
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "päivämäärän ”%s” jäsentäminen epäonnistui"
+
+#: plugins/sudoers/sudoreplay.c:1259
+msgid "unmatched '(' in expression"
+msgstr "täsmäämätön ’(’ lausekkeessa"
+
+#: plugins/sudoers/sudoreplay.c:1261
+msgid "illegal trailing \"or\""
+msgstr "virheellinen jäljessä oleva ”or”"
+
+#: plugins/sudoers/sudoreplay.c:1263
+msgid "illegal trailing \"!\""
+msgstr "virheellinen jäljessä oleva ”!”"
+
+#: plugins/sudoers/sudoreplay.c:1312
+#, c-format
+msgid "unknown search type %d"
+msgstr "tuntematon hakutyyppi %d"
+
+#: plugins/sudoers/sudoreplay.c:1350
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: virheellinen lokitiedosto"
+
+#: plugins/sudoers/sudoreplay.c:1368
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: aikaleimakenttä puuttuu"
+
+#: plugins/sudoers/sudoreplay.c:1375
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: aikaleima %s: %s"
+
+#: plugins/sudoers/sudoreplay.c:1382
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: käyttäjäkenttä puuttuu"
+
+#: plugins/sudoers/sudoreplay.c:1391
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: suorita käyttäjänä-kenttä puuttuu"
+
+#: plugins/sudoers/sudoreplay.c:1400
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: suorita ryhmänä-kenttä puuttuu"
+
+#: plugins/sudoers/sudoreplay.c:1806
+#, c-format
+msgid "usage: %s [-hnR] [-d dir] [-m num] [-s num] ID\n"
+msgstr "käyttö: %s [-hnR] [-d hakemisto] [-m numero] [-s numero] ID-tunniste\n"
+
+#: plugins/sudoers/sudoreplay.c:1809
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "käyttö: %s [-h] [-d hakemisto] -l [hakulauseke]\n"
+
+#: plugins/sudoers/sudoreplay.c:1818
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - toista sudo-istuntolokit\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1820
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Valitsimet:\n"
+" -d, --directory=hakemisto määrittele istuntolokien hakemisto\n"
+" -f, --filter=suodatin määrittele, mitä siirräntätyyppiä näytetään\n"
+" -h, --help näytä opasteviesti ja poistu\n"
+" -l, --list [lauseke] luettele käytettävissä oleva istuntotunnisteet, jotka täsmäävät lausekkeeseen\n"
+" -m, --max-wait=numero maksimisodotusaika tapahtumien välien enimmäisodotusaika sekunteina\n"
+" -s, --speed=numero nopeustekijä nopeuta tai hidasta tulostusta\n"
+" -V, --version näytä versiotiedot ja poistu"
+
+#: plugins/sudoers/testsudoers.c:329
+msgid "\thost unmatched"
+msgstr "\ttietokone täsmäämätön"
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Komento sallittu"
+
+#: plugins/sudoers/testsudoers.c:333
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Komento kielletty"
+
+#: plugins/sudoers/testsudoers.c:333
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Täsmäämätön komento"
+
+#: plugins/sudoers/timestamp.c:225
+#, c-format
+msgid "%s is group writable"
+msgstr "%s on ryhmäkirjoitettava"
+
+#: plugins/sudoers/timestamp.c:301
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "aikaleimatiedoston typistäminen %lld-tavun kokoiseksi epäonnistui"
+
+#: plugins/sudoers/timestamp.c:756 plugins/sudoers/timestamp.c:823
+#: plugins/sudoers/visudo.c:500 plugins/sudoers/visudo.c:506
+msgid "unable to read the clock"
+msgstr "kellon lukeminen epäonnistui"
+
+#: plugins/sudoers/timestamp.c:770
+msgid "ignoring time stamp from the future"
+msgstr "ohitetaan aikaleima tulevaisuudesta"
+
+#: plugins/sudoers/timestamp.c:782
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "aikaleima liian kaukana tulevaisuudessa: %20.20s"
+
+#: plugins/sudoers/timestamp.c:877
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "aikaleimatiedoston %s lukitseminen epäonnistui"
+
+#: plugins/sudoers/timestamp.c:921 plugins/sudoers/timestamp.c:941
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "luentotilapolku on liian pitkä: %s/%s"
+
+#: plugins/sudoers/visudo.c:188
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s kielioppiversio %d\n"
+
+#: plugins/sudoers/visudo.c:266 plugins/sudoers/visudo.c:667
+#, c-format
+msgid "press return to edit %s: "
+msgstr "muokkaa %s painamalla enter-painiketta: "
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "määritelty editori (%s) ei ole olemassa"
+
+#: plugins/sudoers/visudo.c:349
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "editoria ei löytynyt (editoripolku = %s)"
+
+#: plugins/sudoers/visudo.c:459 plugins/sudoers/visudo.c:467
+msgid "write error"
+msgstr "kirjoitusvirhe"
+
+#: plugins/sudoers/visudo.c:513
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "funktion stat kutsuminen tilapäiselle tiedostolle (%s) epäonnistui, %s ennallaan"
+
+#: plugins/sudoers/visudo.c:520
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "nollapituinen tilapäinen tiedosto (%s), %s ennallaan"
+
+#: plugins/sudoers/visudo.c:526
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "editori (%s) epäonnistui, %s ennallaan"
+
+#: plugins/sudoers/visudo.c:548
+#, c-format
+msgid "%s unchanged"
+msgstr "%s ennallaan"
+
+#: plugins/sudoers/visudo.c:607
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "tilapäisen tiedoston (%s) avaaminen uudelleen epäonnistui, %s ennallaan."
+
+#: plugins/sudoers/visudo.c:619
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "tilapäisen tiedoston (%s) jäsentäminen epäonnistui, tuntematon virhe"
+
+#: plugins/sudoers/visudo.c:656
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "sisäinen virhe, kohteen %s löytäminen luettelosta epäonnistui!"
+
+#: plugins/sudoers/visudo.c:736 plugins/sudoers/visudo.c:745
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "kohteen %s (uid, gid) asettaminen arvoihin (%u, %u) epäonnistui"
+
+#: plugins/sudoers/visudo.c:767
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s ja %s eivät ole samassa tiedostojärjestelmässä, käytetään komentoa mv uudelleennimeämiseen"
+
+#: plugins/sudoers/visudo.c:781
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "komento epäonnistui: ’%s %s %s’, %s ennallaan"
+
+#: plugins/sudoers/visudo.c:791
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "virhe nimettäessä %s uudelleen, %s ennallaan"
+
+#: plugins/sudoers/visudo.c:855
+msgid "What now? "
+msgstr "Mitä nyt?"
+
+#: plugins/sudoers/visudo.c:869
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Valitsimia ovat:\n"
+" (e) muokkaa sudoers-tiedostoa uudelleen\n"
+" (x) poistu tallentamatta sudoers-tiedoston muutoksia\n"
+" (Q) poistu ja tallenna muutokset sudoers-tiedostoon (VAARA!)\n"
+
+# Parametri on path, mutta saattaa sisältää suoritettavan ohjelman
+#: plugins/sudoers/visudo.c:915
+#, c-format
+msgid "unable to run %s"
+msgstr "kohteen %s suorittaminen epäonnistui"
+
+#: plugins/sudoers/visudo.c:945
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: väärä omistaja (uid, gid), pitäisi olla (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:952
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: väärät käyttöoikeudet, pitäisi olla tila 0%o\n"
+
+#: plugins/sudoers/visudo.c:981 plugins/sudoers/visudo_json.c:1021
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "tiedoston %s jäsentäminen epäonnistui, tuntematon virhe"
+
+#: plugins/sudoers/visudo.c:997 plugins/sudoers/visudo_json.c:1032
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "jäsentämisvirhe tiedostossa %s lähellä riviä %d\n"
+
+#: plugins/sudoers/visudo.c:1000 plugins/sudoers/visudo_json.c:1035
+#, c-format
+msgid "parse error in %s\n"
+msgstr "jäsentämisvirhe tiedostossa %s\n"
+
+#: plugins/sudoers/visudo.c:1008 plugins/sudoers/visudo.c:1015
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: jäsentäminen valmis\n"
+
+#: plugins/sudoers/visudo.c:1062
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s varattu, yritä myöhemmin uudelleen"
+
+#: plugins/sudoers/visudo.c:1159
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Virhe: %s:%d jakso kohteessa %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1160
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Varoitus: %s:%d jakso kohteessa %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1164
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Virhe: %s:%d %s \"%s\" uudelleenviitattu, mutta ei määritelty"
+
+#: plugins/sudoers/visudo.c:1165
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Varoitus: %s:%d %s \"%s\" uudelleenviitattu, mutta ei määritelty"
+
+#: plugins/sudoers/visudo.c:1318
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Varoitus: %s:%d käyttämätön %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1433
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - muokkaa sudoers-tiedostoa turvallisesti\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1435
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+" -x, --export=output_file write sudoers in JSON format to output_file"
+msgstr ""
+"\n"
+"Valitsimet:\n"
+" -c, --check vain tarkistus -tila\n"
+" -f, --file=sudoers määrittele sudoers-tiedoston sijainti\n"
+" -h, --help näytä opasteteksti ja poistu\n"
+" -q, --quiet vähemmän laveat (hiljaiset) syntaksivirheviestit\n"
+" -s, --strict tiukka syntaksitarkistus\n"
+" -V, --version näytä versiotiedot ja poistu\n"
+" -x, --export=output_file kirjoita sudoers-tiedosto JSON-muodossa tiedostoon output_file"
+
+#: plugins/sudoers/visudo_json.c:616 plugins/sudoers/visudo_json.c:651
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "tuntematon oletusrivi \"%s\""
+
+#: plugins/sudoers/visudo_json.c:1007
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: syöte- ja tulostetiedostojen on oltava erilaiset"
+
+#: toke.l:943
+msgid "too many levels of includes"
+msgstr "liian monta include-tasoa"
+
+#~ msgid "timestamp path too long: %s/%s"
+#~ msgstr "aikaleimapolku on liian pitkä: %s/%s"
+
+#~ msgid "unable to stat editor (%s)"
+#~ msgstr "funktion stat editor (%s) kutsuminen epäonnistui"
+
+#~ msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+#~ msgstr "sudo_ldap_conf_add_ports: hostbuf-puskuritila loppui"
+
+#~ msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+#~ msgstr "sudo_ldap_parse_uri: hostbuf-puskuritila loppui"
+
+#~ msgid "sudo_ldap_build_pass1 allocation mismatch"
+#~ msgstr "sudo_ldap_build_pass1-varaustäsmäämättömyys"
+
+#~ msgid "Password:"
+#~ msgstr "Salasana:"
+
+#~ msgid "internal error: insufficient space for log line"
+#~ msgstr "sisäinen virhe: riittämättömästi tilaa lokiriville"
+
+#~ msgid "fill_args: buffer overflow"
+#~ msgstr "fill_args: puskuriylivuoto"
+
+#~ msgid "%s: unused %s_Alias %s"
+#~ msgstr "%s: käyttämätön %s_Alias %s"
+
+#~ msgid "%s owned by uid %u, should be uid %u"
+#~ msgstr "%s on uid %u:n omistama, pitäisi olla uid %u:n omistama"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0700"
+#~ msgstr "%s on kirjoitettava ei-omistajalle (0%o), pitäisi olla tila 0700"
+
+#~ msgid "%s exists but is not a regular file (0%o)"
+#~ msgstr "%s on olemassa, mutta ei ole tavallinen tiedosto (0%o)"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0600"
+#~ msgstr "%s on kirjoitettava ei-omistajalle (0%o), pitäisi olla tila 0600"
+
+#~ msgid "unable to remove %s, will reset to the Unix epoch"
+#~ msgstr "kohteen %s poistaminen epäonnistui, nollaa Unix-ajan"
+
+#~ msgid "unable to reset %s to the Unix epoch"
+#~ msgstr "kohteen %s nollaaminen Unix-ajaksi epäonnistui"
+
+#~ msgid "value out of range"
+#~ msgstr "arvo lukualueen ulkopuolella"
+
+#~ msgid ""
+#~ "\n"
+#~ "Options:\n"
+#~ " -c, --check check-only mode\n"
+#~ " -f, --file=file specify sudoers file location\n"
+#~ " -h, --help display help message and exit\n"
+#~ " -q, --quiet less verbose (quiet) syntax error messages\n"
+#~ " -s, --strict strict syntax checking\n"
+#~ " -V, --version display version information and exit -x, --export export sudoers in JSON format"
+#~ msgstr ""
+#~ "\n"
+#~ "Valitsimet:\n"
+#~ " -c, --check vain tarkistus -tila\n"
+#~ " -f, --file=tiedosto määrittele sudoers-tiedoston sijainti\n"
+#~ " -h, --help näytä opasteteksti ja poistu\n"
+#~ " -q, --quiet vähemmän laveat (hiljaiset) syntaksivirheviestit\n"
+#~ " -s, --strict tiukka syntaksitarkistus\n"
+#~ " -V, --version näytä versiotiedot ja poistu -x, --export vie sudoers-tiedosto JSON-muodossa"
+
+#~ msgid "invalid uri: %s"
+#~ msgstr "virheellinen verkkoresurssin tunnus: %s"
+
+#~ msgid "unable to mix ldaps and starttls"
+#~ msgstr "ldap- ja starttl-kohteiden sekoittaminen epäonnistui"
+
+#~ msgid "writing to standard output"
+#~ msgstr "kirjoitetaan vakiotulosteeseen"
+
+#~ msgid "too many parenthesized expressions, max %d"
+#~ msgstr "liian monta sulkumerkillistä lauseketta, enintään %d"
+
+#~ msgid "unable to setup authentication"
+#~ msgstr "asetustodentaminen epäonnistui"
+
+#~ msgid "getaudit: failed"
+#~ msgstr "getaudit: epäonnistui"
+
+#~ msgid "getauid: failed"
+#~ msgstr "getauid: epäonnistui"
+
+#~ msgid "au_open: failed"
+#~ msgstr "au_open: epäonnistui"
+
+#~ msgid "au_to_subject: failed"
+#~ msgstr "au_to_subject: epäonnistui"
+
+#~ msgid "au_to_exec_args: failed"
+#~ msgstr "au_to_exec_args: epäonnistui"
+
+#~ msgid "au_to_return32: failed"
+#~ msgstr "au_to_return32: epäonnistui"
+
+#~ msgid "au_to_text: failed"
+#~ msgstr "au_to_text: epäonnistui"
+
+#~ msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
+#~ msgstr "nanosleep: tv_sec %ld, tv_nsec %ld"
+
+#~ msgid "pam_chauthtok: %s"
+#~ msgstr "pam_chauthtok: %s"
+
+#~ msgid "pam_authenticate: %s"
+#~ msgstr "pam_authenticate: %s"
+
+#~ msgid "getauid failed"
+#~ msgstr "getauid epäonnistui"
+
+#~ msgid "Unable to dlopen %s: %s"
+#~ msgstr "Funktion dlopen %s kutsuminen epäonnistui: %s"
+
+#~ msgid "invalid regex: %s"
+#~ msgstr "virheellinen säännöllinen lauseke: %s"
+
+#~ msgid ">>> %s: %s near line %d <<<"
+#~ msgstr ">>> %s: %s lähellä riviä %d <<<"
+
+#~ msgid "unable to set locale to \"%s\", using \"C\""
+#~ msgstr "locale-asetuksen ”%s” asettaminen epäonnistui, käytetään ”C”"
+
+#~ msgid ""
+#~ " Commands:\n"
+#~ "\t"
+#~ msgstr ""
+#~ " Komennot:\n"
+#~ "\t"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "unable to cache uid %u (%s), already exists"
+#~ msgstr "käyttäjän uid %u (%s) laittaminen välimuistiin epäonnistui, käyttäjä on jo siellä"
+
+#~ msgid "unable to cache gid %u (%s), already exists"
+#~ msgstr "ryhmän gid %u (%s) laittaminen välimuistiin epäonnistui, ryhmä on jo siellä"
+
+#~ msgid "unable to execute %s: %s"
+#~ msgstr "komennon %s suorittaminen epäonnistui: %s"
+
+#~ msgid "internal error, expand_prompt() overflow"
+#~ msgstr "sisäinen virhe, expand_prompt()-ylivuoto"
+
+#~ msgid "internal error, sudo_setenv2() overflow"
+#~ msgstr "sisäinen virhe, sudo_setenv2()-ylivuoto"
+
+#~ msgid "internal error, sudo_setenv() overflow"
+#~ msgstr "sisäinen virhe, sudo_setenv()-ylivuoto"
+
+#~ msgid "internal error, linux_audit_command() overflow"
+#~ msgstr "sisäinen virhe, linux_audit_command()-ylivuoto"
+
+#~ msgid "internal error, runas_groups overflow"
+#~ msgstr "sisäinen virhe, runas_groups-ylivuoto"
+
+#~ msgid "internal error, init_vars() overflow"
+#~ msgstr "sisäinen virhe, init_vars()-ylivuoto"
+
+# Parametri on sudoers file
+#~ msgid "fixed mode on %s"
+#~ msgstr "korjattu tila tiedostossa %s"
+
+# Parametri on suoders file
+#~ msgid "set group on %s"
+#~ msgstr "aseta ryhmä tiedostossa %s"
+
+#~ msgid "unable to fix mode on %s"
+#~ msgstr "tilan korjaaminen tiedostossa %s epäonnistui"
+
+#~ msgid "%s is mode 0%o, should be 0%o"
+#~ msgstr "%s on tila 0%o, pitäisi olla 0%o"
+
+#~ msgid "File containing dummy exec functions: %s"
+#~ msgstr "Tiedosto, joka sisältää vale-exec-funktioita: %s"
+
+#~ msgid ""
+#~ "Available options in a sudoers ``Defaults'' line:\n"
+#~ "\n"
+#~ msgstr ""
+#~ "Käytettävissä olevat valitsimet sudoers ’’Defaults’’ -rivillä:\n"
+#~ "\n"
+
+#~ msgid "%s: %.*s\n"
+#~ msgstr "%s: %.*s\n"
+
+#~ msgid "unable to get runas group vector"
+#~ msgstr "runas-ryhmävektorin hakeminen epäonnistui"
+
+#~ msgid "%s: %s_Alias `%s' references self"
+#~ msgstr "%s: %s_Alias ”%s” viittaa itseensä"
+
+#~ msgid "unable to parse temporary file (%s), unknown error"
+#~ msgstr "tilapäisen tiedoston (%s) jäsentäminen epäonnistui, tuntematon virhe"
diff --git a/plugins/sudoers/po/fr.mo b/plugins/sudoers/po/fr.mo
new file mode 100644
index 0000000..a3a2fee
--- /dev/null
+++ b/plugins/sudoers/po/fr.mo
Binary files differ
diff --git a/plugins/sudoers/po/fr.po b/plugins/sudoers/po/fr.po
new file mode 100644
index 0000000..b17259c
--- /dev/null
+++ b/plugins/sudoers/po/fr.po
@@ -0,0 +1,2048 @@
+# This file is put in the public domain.
+# This file is distributed under the same license as the sudo package.
+#
+# Frédéric Hantrais <fhantrais@gmail.com>, 2014, 2015, 2016.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.15rc3\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2015-10-24 06:26-0600\n"
+"PO-Revision-Date: 2016-02-14 08:17-0500\n"
+"Last-Translator: Frédéric Hantrais <fhantrais@gmail.com>\n"
+"Language-Team: French <traduc@traduc.org>\n"
+"Language: fr\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Generator: Lokalize 1.5\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "erreur de syntaxe"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "Mot de passe de %p : "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] Mot de passe de %p : "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Mot de passe : "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** Informations de sécurité pour %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Désolé, essayez de nouveau."
+
+#: gram.y:183 gram.y:201 gram.y:207 gram.y:213 gram.y:219 gram.y:225
+#: gram.y:241 gram.y:248 gram.y:255 gram.y:262 gram.y:269 gram.y:285
+#: gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336 gram.y:391
+#: gram.y:399 gram.y:409 gram.y:439 gram.y:446 gram.y:453 gram.y:460
+#: gram.y:572 gram.y:579 gram.y:588 gram.y:597 gram.y:614 gram.y:670
+#: gram.y:677 gram.y:684 gram.y:692 gram.y:784 gram.y:791 gram.y:798
+#: gram.y:805 gram.y:812 gram.y:838 gram.y:845 gram.y:852 gram.y:1136
+#: gram.y:1143 plugins/sudoers/alias.c:123 plugins/sudoers/alias.c:136
+#: plugins/sudoers/auth/bsdauth.c:141 plugins/sudoers/auth/kerb5.c:119
+#: plugins/sudoers/auth/kerb5.c:145 plugins/sudoers/auth/pam.c:398
+#: plugins/sudoers/auth/pam.c:449 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/auth/sia.c:59 plugins/sudoers/defaults.c:516
+#: plugins/sudoers/defaults.c:720 plugins/sudoers/defaults.c:880
+#: plugins/sudoers/editor.c:64 plugins/sudoers/editor.c:82
+#: plugins/sudoers/editor.c:92 plugins/sudoers/env.c:233
+#: plugins/sudoers/group_plugin.c:133 plugins/sudoers/iolog.c:586
+#: plugins/sudoers/iolog.c:618 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:446 plugins/sudoers/ldap.c:477
+#: plugins/sudoers/ldap.c:529 plugins/sudoers/ldap.c:562
+#: plugins/sudoers/ldap.c:914 plugins/sudoers/ldap.c:1061
+#: plugins/sudoers/ldap.c:1348 plugins/sudoers/ldap.c:1521
+#: plugins/sudoers/ldap.c:1597 plugins/sudoers/ldap.c:1733
+#: plugins/sudoers/ldap.c:1757 plugins/sudoers/ldap.c:1787
+#: plugins/sudoers/ldap.c:1840 plugins/sudoers/ldap.c:1855
+#: plugins/sudoers/ldap.c:1951 plugins/sudoers/ldap.c:1984
+#: plugins/sudoers/ldap.c:2137 plugins/sudoers/ldap.c:2234
+#: plugins/sudoers/ldap.c:3041 plugins/sudoers/ldap.c:3074
+#: plugins/sudoers/ldap.c:3388 plugins/sudoers/ldap.c:3416
+#: plugins/sudoers/ldap.c:3427 plugins/sudoers/ldap.c:3517
+#: plugins/sudoers/ldap.c:3533 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:188 plugins/sudoers/logging.c:666
+#: plugins/sudoers/logging.c:924 plugins/sudoers/match.c:501
+#: plugins/sudoers/match.c:537 plugins/sudoers/match.c:699
+#: plugins/sudoers/match.c:756 plugins/sudoers/parse.c:235
+#: plugins/sudoers/parse.c:247 plugins/sudoers/parse.c:262
+#: plugins/sudoers/parse.c:274 plugins/sudoers/policy.c:384
+#: plugins/sudoers/policy.c:583 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/sssd.c:160 plugins/sudoers/sssd.c:192
+#: plugins/sudoers/sssd.c:235 plugins/sudoers/sssd.c:242
+#: plugins/sudoers/sssd.c:278 plugins/sudoers/sssd.c:323
+#: plugins/sudoers/sssd.c:917 plugins/sudoers/sssd.c:1050
+#: plugins/sudoers/sudoers.c:159 plugins/sudoers/sudoers.c:294
+#: plugins/sudoers/sudoers.c:304 plugins/sudoers/sudoers.c:312
+#: plugins/sudoers/sudoers.c:365 plugins/sudoers/sudoers.c:663
+#: plugins/sudoers/sudoers.c:749 plugins/sudoers/sudoers.c:793
+#: plugins/sudoers/sudoers_debug.c:107 plugins/sudoers/sudoreplay.c:472
+#: plugins/sudoers/sudoreplay.c:668 plugins/sudoers/sudoreplay.c:780
+#: plugins/sudoers/sudoreplay.c:820 plugins/sudoers/sudoreplay.c:829
+#: plugins/sudoers/sudoreplay.c:839 plugins/sudoers/sudoreplay.c:847
+#: plugins/sudoers/sudoreplay.c:851 plugins/sudoers/sudoreplay.c:1007
+#: plugins/sudoers/sudoreplay.c:1011 plugins/sudoers/testsudoers.c:130
+#: plugins/sudoers/testsudoers.c:188 plugins/sudoers/testsudoers.c:215
+#: plugins/sudoers/testsudoers.c:232 plugins/sudoers/timestamp.c:390
+#: plugins/sudoers/timestamp.c:426 plugins/sudoers/timestamp.c:838
+#: plugins/sudoers/toke_util.c:56 plugins/sudoers/toke_util.c:109
+#: plugins/sudoers/toke_util.c:147 plugins/sudoers/visudo.c:152
+#: plugins/sudoers/visudo.c:213 plugins/sudoers/visudo.c:297
+#: plugins/sudoers/visudo.c:303 plugins/sudoers/visudo.c:433
+#: plugins/sudoers/visudo.c:979 plugins/sudoers/visudo.c:1023
+#: plugins/sudoers/visudo.c:1119 toke.l:785 toke.l:806 toke.l:816 toke.l:924
+#: toke.l:1082
+msgid "unable to allocate memory"
+msgstr "impossible d'allouer la mémoire"
+
+#: gram.y:471
+msgid "a digest requires a path name"
+msgstr "un résumé (digest) nécessite un chemin d'accès"
+
+#: gram.y:1136 gram.y:1143 plugins/sudoers/auth/pam.c:398
+#: plugins/sudoers/auth/pam.c:449 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/defaults.c:516 plugins/sudoers/defaults.c:720
+#: plugins/sudoers/defaults.c:880 plugins/sudoers/editor.c:64
+#: plugins/sudoers/editor.c:82 plugins/sudoers/editor.c:92
+#: plugins/sudoers/env.c:233 plugins/sudoers/group_plugin.c:133
+#: plugins/sudoers/iolog.c:586 plugins/sudoers/iolog.c:618
+#: plugins/sudoers/iolog_path.c:167 plugins/sudoers/ldap.c:446
+#: plugins/sudoers/ldap.c:477 plugins/sudoers/ldap.c:529
+#: plugins/sudoers/ldap.c:562 plugins/sudoers/ldap.c:914
+#: plugins/sudoers/ldap.c:1061 plugins/sudoers/ldap.c:1348
+#: plugins/sudoers/ldap.c:1521 plugins/sudoers/ldap.c:1597
+#: plugins/sudoers/ldap.c:1733 plugins/sudoers/ldap.c:1757
+#: plugins/sudoers/ldap.c:1787 plugins/sudoers/ldap.c:1840
+#: plugins/sudoers/ldap.c:1855 plugins/sudoers/ldap.c:1951
+#: plugins/sudoers/ldap.c:1984 plugins/sudoers/ldap.c:2137
+#: plugins/sudoers/ldap.c:2234 plugins/sudoers/ldap.c:3041
+#: plugins/sudoers/ldap.c:3074 plugins/sudoers/ldap.c:3388
+#: plugins/sudoers/ldap.c:3416 plugins/sudoers/ldap.c:3427
+#: plugins/sudoers/ldap.c:3517 plugins/sudoers/ldap.c:3533
+#: plugins/sudoers/linux_audit.c:76 plugins/sudoers/logging.c:188
+#: plugins/sudoers/logging.c:924 plugins/sudoers/match.c:501
+#: plugins/sudoers/match.c:537 plugins/sudoers/match.c:699
+#: plugins/sudoers/match.c:756 plugins/sudoers/parse.c:235
+#: plugins/sudoers/parse.c:247 plugins/sudoers/parse.c:262
+#: plugins/sudoers/parse.c:274 plugins/sudoers/policy.c:97
+#: plugins/sudoers/policy.c:106 plugins/sudoers/policy.c:115
+#: plugins/sudoers/policy.c:139 plugins/sudoers/policy.c:250
+#: plugins/sudoers/policy.c:271 plugins/sudoers/policy.c:280
+#: plugins/sudoers/policy.c:319 plugins/sudoers/policy.c:329
+#: plugins/sudoers/policy.c:338 plugins/sudoers/policy.c:384
+#: plugins/sudoers/policy.c:583 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/set_perms.c:356 plugins/sudoers/set_perms.c:695
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1350
+#: plugins/sudoers/set_perms.c:1514 plugins/sudoers/sssd.c:160
+#: plugins/sudoers/sssd.c:192 plugins/sudoers/sssd.c:235
+#: plugins/sudoers/sssd.c:242 plugins/sudoers/sssd.c:278
+#: plugins/sudoers/sssd.c:323 plugins/sudoers/sssd.c:917
+#: plugins/sudoers/sssd.c:1050 plugins/sudoers/sudoers.c:159
+#: plugins/sudoers/sudoers.c:294 plugins/sudoers/sudoers.c:304
+#: plugins/sudoers/sudoers.c:312 plugins/sudoers/sudoers.c:365
+#: plugins/sudoers/sudoers.c:663 plugins/sudoers/sudoers.c:749
+#: plugins/sudoers/sudoers.c:793 plugins/sudoers/sudoers_debug.c:106
+#: plugins/sudoers/sudoreplay.c:472 plugins/sudoers/sudoreplay.c:668
+#: plugins/sudoers/sudoreplay.c:780 plugins/sudoers/sudoreplay.c:820
+#: plugins/sudoers/sudoreplay.c:829 plugins/sudoers/sudoreplay.c:839
+#: plugins/sudoers/sudoreplay.c:847 plugins/sudoers/sudoreplay.c:851
+#: plugins/sudoers/sudoreplay.c:1007 plugins/sudoers/sudoreplay.c:1011
+#: plugins/sudoers/testsudoers.c:130 plugins/sudoers/testsudoers.c:188
+#: plugins/sudoers/testsudoers.c:215 plugins/sudoers/testsudoers.c:232
+#: plugins/sudoers/timestamp.c:390 plugins/sudoers/timestamp.c:426
+#: plugins/sudoers/timestamp.c:838 plugins/sudoers/toke_util.c:56
+#: plugins/sudoers/toke_util.c:109 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/visudo.c:152 plugins/sudoers/visudo.c:213
+#: plugins/sudoers/visudo.c:297 plugins/sudoers/visudo.c:303
+#: plugins/sudoers/visudo.c:433 plugins/sudoers/visudo.c:979
+#: plugins/sudoers/visudo.c:1023 plugins/sudoers/visudo.c:1119 toke.l:785
+#: toke.l:806 toke.l:816 toke.l:924 toke.l:1082
+#, c-format
+msgid "%s: %s"
+msgstr "%s : %s"
+
+#: plugins/sudoers/alias.c:132
+#, c-format
+msgid "Alias `%s' already defined"
+msgstr "L'alias « %s » est déjà défini"
+
+#: plugins/sudoers/auth/bsdauth.c:68
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "récupération de la classe de connexion impossible pour l'utilisateur %s"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+msgid "unable to begin bsd authentication"
+msgstr "démarrage de l'authentification bsd impossible"
+
+#: plugins/sudoers/auth/bsdauth.c:81
+msgid "invalid authentication type"
+msgstr "type d'authentification non valide"
+
+#: plugins/sudoers/auth/bsdauth.c:90
+msgid "unable to initialize BSD authentication"
+msgstr "démarrage de l'authentification BSD impossible"
+
+#: plugins/sudoers/auth/fwtk.c:52
+msgid "unable to read fwtk config"
+msgstr "lecture de la configuration fwtk (firewall) impossible"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to connect to authentication server"
+msgstr "connexion au serveur d'authentification impossible"
+
+#: plugins/sudoers/auth/fwtk.c:63 plugins/sudoers/auth/fwtk.c:87
+#: plugins/sudoers/auth/fwtk.c:120
+msgid "lost connection to authentication server"
+msgstr "perte de la connexion au serveur d'authentification"
+
+#: plugins/sudoers/auth/fwtk.c:67
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"erreur du serveur d'authentification :\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:111
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s : conversion de l'identité de l'hôte en chaîne de caractères impossible(« %s ») : %s"
+
+#: plugins/sudoers/auth/kerb5.c:161
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s : analyse grammaticale (parse) de « %s » impossible : %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s : accès au cache des données d'identification impossible : %s"
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s : allocation des options impossible : %s"
+
+#: plugins/sudoers/auth/kerb5.c:232
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s : récupération des données d'identification impossible : %s"
+
+#: plugins/sudoers/auth/kerb5.c:245
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s : initialisation du cache des données d'identification impossible : %s"
+
+#: plugins/sudoers/auth/kerb5.c:248
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s : enregistrement des données d'identification dans le cache impossible : %s"
+
+#: plugins/sudoers/auth/kerb5.c:312
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s : récupération de l'identité kerberos de l'hôte (host \"\"principal) impossible : %s"
+
+#: plugins/sudoers/auth/kerb5.c:326
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s : vérification du ticket TGT impossible ! Il s'agit peut-être d'une attaque ! : %s"
+
+#: plugins/sudoers/auth/pam.c:92
+msgid "unable to initialize PAM"
+msgstr "initialisation du module PAM impossible"
+
+#: plugins/sudoers/auth/pam.c:164
+msgid "account validation failure, is your account locked?"
+msgstr "la validation du compte a échoué, vérifiez que le compte n'est pas verrouillé. "
+
+#: plugins/sudoers/auth/pam.c:168
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Le compte ou le mot de passe a expiré, réinitialisez votre mot de passe puis réessayez de vous connecter"
+
+#: plugins/sudoers/auth/pam.c:176
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "changement du mot de passe expiré impossible : %s"
+
+#: plugins/sudoers/auth/pam.c:181
+msgid "Password expired, contact your system administrator"
+msgstr "Le mot de passe a expiré, contactez votre administrateur système"
+
+#: plugins/sudoers/auth/pam.c:185
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Le compte a expiré, ou la section « account » du module PAM n'est pas renseignée pour sudo, contactez votre administrateur système"
+
+#: plugins/sudoers/auth/pam.c:199
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Erreur du serveur d'authentification PAM : %s"
+
+#: plugins/sudoers/auth/rfc1938.c:97 plugins/sudoers/visudo.c:218
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "votre compte n'existe pas dans la base de données %s"
+
+#: plugins/sudoers/auth/securid5.c:73
+msgid "failed to initialise the ACE API library"
+msgstr "échec de l'initialisation de la bibliothèque d'API ACE"
+
+#: plugins/sudoers/auth/securid5.c:99
+msgid "unable to contact the SecurID server"
+msgstr "le contact avec le serveur SecurID n'a pas pu être établi"
+
+#: plugins/sudoers/auth/securid5.c:108
+msgid "User ID locked for SecurID Authentication"
+msgstr "échec de l'authentification SecurId, l'identifiant de l'utilisateur est verrouillé"
+
+#: plugins/sudoers/auth/securid5.c:112 plugins/sudoers/auth/securid5.c:163
+msgid "invalid username length for SecurID"
+msgstr "la longueur du nom de l'utilisateur n'est pas conforme aux règles fixées pour SecurID"
+
+#: plugins/sudoers/auth/securid5.c:116 plugins/sudoers/auth/securid5.c:168
+msgid "invalid Authentication Handle for SecurID"
+msgstr "le mode de traitement de l'authentification n'est pas accepté par SecurID"
+
+#: plugins/sudoers/auth/securid5.c:120
+msgid "SecurID communication failed"
+msgstr "la communication avec SecurID a échoué"
+
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:207
+msgid "unknown SecurID error"
+msgstr "erreur SecurID non identifiée"
+
+#: plugins/sudoers/auth/securid5.c:158
+msgid "invalid passcode length for SecurID"
+msgstr "la longueur du mot de passe n'est pas conforme aux règles fixées pour SecurID"
+
+#: plugins/sudoers/auth/sia.c:69 plugins/sudoers/auth/sia.c:124
+msgid "unable to initialize SIA session"
+msgstr "initialisation de la session SIA impossible"
+
+#: plugins/sudoers/auth/sudo_auth.c:126
+msgid "invalid authentication methods"
+msgstr "méthodes d'authentification invalides"
+
+#: plugins/sudoers/auth/sudo_auth.c:128
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Méthodes d'authentification non valides compilées dans sudo ! La combinaison d'authentifications autonomes et non-autonomes n'est pas permise."
+
+#: plugins/sudoers/auth/sudo_auth.c:225 plugins/sudoers/auth/sudo_auth.c:274
+msgid "no authentication methods"
+msgstr "Pas de méthodes d'authentification"
+
+#: plugins/sudoers/auth/sudo_auth.c:227
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Aucune méthode d'authentification compilée dans sudo ! Si vous souhaitez désactiver l'authentification, utilisez l'option de configuration --disable-authentication"
+
+#: plugins/sudoers/auth/sudo_auth.c:276
+msgid "Unable to initialize authentication methods."
+msgstr "Initialisation des méthodes d'authentification impossible."
+
+#: plugins/sudoers/auth/sudo_auth.c:435
+msgid "Authentication methods:"
+msgstr "Méthodes d'authentification : "
+
+#: plugins/sudoers/bsm_audit.c:111 plugins/sudoers/bsm_audit.c:200
+msgid "Could not determine audit condition"
+msgstr "Identification de la condition d'audit impossible"
+
+#: plugins/sudoers/bsm_audit.c:172 plugins/sudoers/bsm_audit.c:260
+msgid "unable to commit audit record"
+msgstr "impossible d'enregistrer l'enregistrement d'audit"
+
+#: plugins/sudoers/check.c:252
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Nous espérons que vous avez reçu de votre administrateur système local les consignes traditionnelles. Généralement, elles se concentrent sur ces trois éléments :\n"
+"\n"
+" #1) Respectez la vie privée des autres.\n"
+" #2) Réfléchissez avant d'utiliser le clavier.\n"
+" #3) De grands pouvoirs confèrent de grandes responsabilités.\n"
+"\n"
+
+#: plugins/sudoers/check.c:295 plugins/sudoers/check.c:305
+#: plugins/sudoers/sudoers.c:699 plugins/sudoers/sudoers.c:728
+#, c-format
+msgid "unknown uid: %u"
+msgstr "identifiant utilisateur inconnu : %u"
+
+#: plugins/sudoers/check.c:300 plugins/sudoers/policy.c:755
+#: plugins/sudoers/sudoers.c:1095 plugins/sudoers/testsudoers.c:206
+#: plugins/sudoers/testsudoers.c:361
+#, c-format
+msgid "unknown user: %s"
+msgstr "utilisateur inconnu : %s"
+
+#: plugins/sudoers/def_data.c:27
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Mécanisme syslog (si syslog est utilisé pour la journalisation des événements) : %s "
+
+#: plugins/sudoers/def_data.c:31
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Priorité syslog utilisée lorsque l'authentification de l'utilisateur est réussie : %s"
+
+#: plugins/sudoers/def_data.c:35
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Priorité Syslog utilisée lorsque l'authentification de l'utilisateur a échoué : %s"
+
+#: plugins/sudoers/def_data.c:39
+msgid "Put OTP prompt on its own line"
+msgstr "Présentation de l'invite OTP sur une ligne distincte"
+
+#: plugins/sudoers/def_data.c:43
+msgid "Ignore '.' in $PATH"
+msgstr "Ne pas tenir compte de « . » dans $PATH"
+
+#: plugins/sudoers/def_data.c:47
+msgid "Always send mail when sudo is run"
+msgstr "Envoi d'un courriel à chaque exécution de sudo"
+
+#: plugins/sudoers/def_data.c:51
+msgid "Send mail if user authentication fails"
+msgstr "Envoi d'un courriel lorsqu'une authentification échoue"
+
+#: plugins/sudoers/def_data.c:55
+msgid "Send mail if the user is not in sudoers"
+msgstr "Envoi d'un courriel si l'utilisateur ne figure pas dans sudoers"
+
+#: plugins/sudoers/def_data.c:59
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Envoi d'un courriel si l'utilisateur ne figure pas dans sudoers pour l'hôte sur lequel sudo est exécuté"
+
+#: plugins/sudoers/def_data.c:63
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Envoi d'un courriel si l'utilisateur n'est pas autorisé à exécuter une commande"
+
+#: plugins/sudoers/def_data.c:67
+msgid "Send mail if the user tries to run a command"
+msgstr "Envoi d'un courriel si l'utilisateur tente d'exécuter une commande"
+
+#: plugins/sudoers/def_data.c:71
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Utilisation d'un horodatage distinct pour chaque couple utilisateur/terminal (user/tty)"
+
+#: plugins/sudoers/def_data.c:75
+msgid "Lecture user the first time they run sudo"
+msgstr "Adresse les recommandations d'usage à l'utilisateur lors de la première exécution de sudo"
+
+#: plugins/sudoers/def_data.c:79
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Fichier contenant les recommandations sur l'usage de sudo : %s"
+
+#: plugins/sudoers/def_data.c:83
+msgid "Require users to authenticate by default"
+msgstr "Exige l'authentification de l'utilisateur par défaut"
+
+#: plugins/sudoers/def_data.c:87
+msgid "Root may run sudo"
+msgstr "L'utilisateur root peut exécuter sudo"
+
+#: plugins/sudoers/def_data.c:91
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Consignation du nom de l'hôte dans le fichier de journalisation (qui n'est pas syslog)"
+
+#: plugins/sudoers/def_data.c:95
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Consignation de l'année dans le fichier de journalisation (qui n'est pas syslog)"
+
+#: plugins/sudoers/def_data.c:99
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "démarrage d'un interpréteur de commande lorsque sudo est lancé sans argument"
+
+#: plugins/sudoers/def_data.c:103
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Assignation à $HOME du répertoire de l'utilisateur cible lorsque l'interpréteur de commandes est lancé avec l'option -s"
+
+#: plugins/sudoers/def_data.c:107
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Assignation systématique à $HOME du répertoire personnel de l'utilisateur cible"
+
+#: plugins/sudoers/def_data.c:111
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Autorise la collecte de certaines informations dans le but d'afficher des messages d'erreurs pertinents"
+
+#: plugins/sudoers/def_data.c:115
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Exige l'emploi du nom complet (fully qualified) de l'ordinateur dans le fichier sudoers"
+
+#: plugins/sudoers/def_data.c:119
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Sermonne l'utilisateur lorsqu'un mot de passe incorrect est saisi"
+
+#: plugins/sudoers/def_data.c:123
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Autorise l'utilisateur à exécuter sudo seulement à la condition qu'il dispose d'un terminal tty"
+
+#: plugins/sudoers/def_data.c:127
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo se conformera au contenu de la variable d'environnement EDITOR"
+
+#: plugins/sudoers/def_data.c:131
+msgid "Prompt for root's password, not the users's"
+msgstr "Demande de la saisie du mot de passe de root et non de celui de l'utilisateur"
+
+#: plugins/sudoers/def_data.c:135
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Demande de la saisie du mot de passe runas_default de l'utilisateur et non de son propre mot de passe"
+
+#: plugins/sudoers/def_data.c:139
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Demande de la saisie du mot de passe de l'utilisateur cible et non de celui de l'utilisateur exécutant la commande"
+
+#: plugins/sudoers/def_data.c:143
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Utilisation des paramètres par défaut de la classe de connexion de l'utilisateur cible (lorsqu'elle existe)"
+
+#: plugins/sudoers/def_data.c:147
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Affectation les variables d'environnement LOGNAME et USER"
+
+#: plugins/sudoers/def_data.c:151
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Attribution de l'identifiant utilisateur (UID) effectif à l'utilisateur cible, et non l'identifiant réel."
+
+#: plugins/sudoers/def_data.c:155
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "N'initialise pas le vecteur de groupe avec les valeurs de l'utilisateur cible"
+
+#: plugins/sudoers/def_data.c:159
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Longueur après laquelle intercaler un retour à la ligne (0 indique qu'il n'y a pas de retour à la ligne) : %u"
+
+#: plugins/sudoers/def_data.c:163
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Délai d'expiration de l'horodatage de l'authentification : %.1f minutes"
+
+#: plugins/sudoers/def_data.c:167
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Délai d'expiration de l'invite de saisie de mot de passe : %.1f minutes"
+
+#: plugins/sudoers/def_data.c:171
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Nombre de tentatives de saisie du mot de passe : %u"
+
+#: plugins/sudoers/def_data.c:175
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Umask à utiliser, ou 0777 pour hériter de celui de l'utilisateur : 0%o"
+
+#: plugins/sudoers/def_data.c:179
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Emplacement du fichier de journalisation : %s"
+
+#: plugins/sudoers/def_data.c:183
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Emplacement du programme d'envoi de courriel : %s"
+
+#: plugins/sudoers/def_data.c:187
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Attributs à affecter au programme d'envoi de courriel : %s"
+
+#: plugins/sudoers/def_data.c:191
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Adresse du destinataire des courriels : %s"
+
+#: plugins/sudoers/def_data.c:195
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Adresse de l'expéditeur des courriels : %s"
+
+#: plugins/sudoers/def_data.c:199
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Champ objet des courriels envoyés : %s"
+
+#: plugins/sudoers/def_data.c:203
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Message informant de la saisie d'un mot de passe incorrect : %s"
+
+#: plugins/sudoers/def_data.c:207
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Répertoire contenant l'attestation que l'utilisateur a déjà reçu les recommandations : %s"
+
+#: plugins/sudoers/def_data.c:211
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Répertoire contenant l'horodatage de l'authentification : %s"
+
+#: plugins/sudoers/def_data.c:215
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Propriétaire du répertoire contenant l'horodatage de l'authentification : %s"
+
+#: plugins/sudoers/def_data.c:219
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Les utilisateurs de ce groupe sont affranchis des contraintes relatives au mot de passe et à PATH : %s"
+
+#: plugins/sudoers/def_data.c:223
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Invite de mot de passe par défaut : %s"
+
+#: plugins/sudoers/def_data.c:227
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "S'il est défini, passprompt se substituera toujours à l'invite du système."
+
+#: plugins/sudoers/def_data.c:231
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Utilisateur par défaut avec l'identité duquel exécuter les commandes : %s"
+
+#: plugins/sudoers/def_data.c:235
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Nouvelle valeur prise par la variable $PATH de l'utilisateur : %s"
+
+#: plugins/sudoers/def_data.c:239
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Emplacement de l'éditeur appelé par visudo : %s"
+
+#: plugins/sudoers/def_data.c:243
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Quand demander un mot de passe pour l'usage des pseudo commandes de « list » : %s"
+
+#: plugins/sudoers/def_data.c:247
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Quand demander un mot de passe pour l'utilisation des pseudo commandes de « verify » : %s"
+
+#: plugins/sudoers/def_data.c:251
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Préchargement des fonctions d'exécution « à blanc » contenues dans la bibliothèque sudo_noexec"
+
+#: plugins/sudoers/def_data.c:255
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Si un annuaire LDAP est actif, faut-il tenir compter du fichier sudoers local"
+
+#: plugins/sudoers/def_data.c:259
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Les descripteurs de fichiers >= %d seront fermés avant l'exécution d'une commande"
+
+#: plugins/sudoers/def_data.c:263
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Si elle est définie, les utilisateurs peuvent passer outre la valeur de « closeform » grâce à l'option -C"
+
+#: plugins/sudoers/def_data.c:267
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Autorise les utilisateurs à définir des variables d'environnement arbitraires"
+
+#: plugins/sudoers/def_data.c:271
+msgid "Reset the environment to a default set of variables"
+msgstr "Réinitialise l'environnement à un jeu de variables par défaut"
+
+#: plugins/sudoers/def_data.c:275
+msgid "Environment variables to check for sanity:"
+msgstr "Variables d'environnement à valider pour s'assurer du bon fonctionnement :"
+
+#: plugins/sudoers/def_data.c:279
+msgid "Environment variables to remove:"
+msgstr "Variables d'environnement à supprimer :"
+
+#: plugins/sudoers/def_data.c:283
+msgid "Environment variables to preserve:"
+msgstr "Variables d'environnement à conserver : "
+
+#: plugins/sudoers/def_data.c:287
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Rôle SELinux à utiliser dans le nouveau contexte de sécurité : %s"
+
+#: plugins/sudoers/def_data.c:291
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Type SELinux à utiliser dans le nouveau contexte de sécurité : %s"
+
+#: plugins/sudoers/def_data.c:295
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Emplacement du fichiers d'environnement propre à sudo : %s"
+
+#: plugins/sudoers/def_data.c:299
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Localisation à utiliser lors du traitement de sudoers : %s"
+
+#: plugins/sudoers/def_data.c:303
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Autoriser sudo à demander la saisie d'un mot de passe même lorsque celui-ci sera affiché « en clair »"
+
+#: plugins/sudoers/def_data.c:307
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Afficher un contrôle visuel lors de la saisie du mot de passe"
+
+#: plugins/sudoers/def_data.c:311
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Utilisation du développement rapide des noms de fichiers, qui est moins fiable, mais ne nécessite pas d'accès au système de fichiers"
+
+#: plugins/sudoers/def_data.c:315
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "L'umask indiqué dans sudoers se substituera à celui de l'utilisateur, même s'il est plus permissif"
+
+#: plugins/sudoers/def_data.c:319
+msgid "Log user's input for the command being run"
+msgstr "Consignation des saisies des utilisateur dans le journal pour la commande en cours d'exécution"
+
+#: plugins/sudoers/def_data.c:323
+msgid "Log the output of the command being run"
+msgstr "Consignation du retour de la commande en cours d'exécution dans le journal"
+
+#: plugins/sudoers/def_data.c:327
+msgid "Compress I/O logs using zlib"
+msgstr "Compression des informations renvoyées par les opérations d'E/S avec zlib"
+
+#: plugins/sudoers/def_data.c:331
+msgid "Always run commands in a pseudo-tty"
+msgstr "Exécute toujours les commandes dans un pseudo-terminal (tty)"
+
+#: plugins/sudoers/def_data.c:335
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Greffon pour la prise en charge des groupes non-Unix : %s"
+
+#: plugins/sudoers/def_data.c:339
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Répertoire dans lequel les informations renvoyées par les opérations d'entrée/sortie seront stockées : %s"
+
+#: plugins/sudoers/def_data.c:343
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Fichier dans lequel les informations renvoyées par les opérations d'entrée/sortie seront stockées : %s"
+
+#: plugins/sudoers/def_data.c:347
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Ajout d'une entrée au fichier utmp/utmpx lors de l'allocation d'un pseudo-terminal"
+
+#: plugins/sudoers/def_data.c:351
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Conservation dans utmp du nom de l'utilisateur runas, et non de celui de l'utilisateur appelant sudo"
+
+#: plugins/sudoers/def_data.c:355
+msgid "Set of permitted privileges"
+msgstr "Jeu de privilèges autorisés"
+
+#: plugins/sudoers/def_data.c:359
+msgid "Set of limit privileges"
+msgstr "Jeu de limites autorisées"
+
+#: plugins/sudoers/def_data.c:363
+msgid "Run commands on a pty in the background"
+msgstr "Exécution des commandes sur un pseudo-terminal en tâche de fond."
+
+#: plugins/sudoers/def_data.c:367
+msgid "PAM service name to use"
+msgstr "Nom de service PAM à utiliser"
+
+#: plugins/sudoers/def_data.c:371
+msgid "PAM service name to use for login shells"
+msgstr "Nom de service PAM à utiliser pour les interpréteurs de commandes"
+
+#: plugins/sudoers/def_data.c:375
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Tentative de création des données d'identification PAM pour l'utilisateur cible"
+
+#: plugins/sudoers/def_data.c:379
+msgid "Create a new PAM session for the command to run in"
+msgstr "Création d'une nouvelle session PAM pour la commande à exécuter"
+
+#: plugins/sudoers/def_data.c:383
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Numéro de séquence maximum dans le journal E/S : %u"
+
+#: plugins/sudoers/def_data.c:387
+msgid "Enable sudoers netgroup support"
+msgstr "Activation de la prise en charge de netgroup par sudoers"
+
+#: plugins/sudoers/def_data.c:391
+msgid "Check the parent directory for writability when editing files with sudoedit"
+msgstr "Vérification que les droits du répertoire parent autorisent la modification des fichiers lors de l'édition"
+
+#: plugins/sudoers/def_data.c:395
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Prise en compte des liens symboliques lors de l'édition des fichiers"
+
+#: plugins/sudoers/def_data.c:399
+msgid "Query the group plugin for unknown system groups"
+msgstr "interroge le greffon group pour les groupes système inconnus"
+
+#: plugins/sudoers/defaults.c:199 plugins/sudoers/defaults.c:608
+#: plugins/sudoers/visudo_json.c:633 plugins/sudoers/visudo_json.c:668
+#, c-format
+msgid "unknown defaults entry `%s'"
+msgstr "Entrée par défaut inconnue « %s »"
+
+#: plugins/sudoers/defaults.c:207 plugins/sudoers/defaults.c:217
+#: plugins/sudoers/defaults.c:241 plugins/sudoers/defaults.c:256
+#: plugins/sudoers/defaults.c:269 plugins/sudoers/defaults.c:282
+#: plugins/sudoers/defaults.c:295 plugins/sudoers/defaults.c:315
+#: plugins/sudoers/defaults.c:325
+#, c-format
+msgid "value `%s' is invalid for option `%s'"
+msgstr "la valeur « %s » ne convient pas pour l'option « %s »"
+
+#: plugins/sudoers/defaults.c:210 plugins/sudoers/defaults.c:220
+#: plugins/sudoers/defaults.c:228 plugins/sudoers/defaults.c:251
+#: plugins/sudoers/defaults.c:264 plugins/sudoers/defaults.c:277
+#: plugins/sudoers/defaults.c:290 plugins/sudoers/defaults.c:310
+#: plugins/sudoers/defaults.c:321
+#, c-format
+msgid "no value specified for `%s'"
+msgstr "pas de valeur précisée pour « %s »"
+
+#: plugins/sudoers/defaults.c:233
+#, c-format
+msgid "values for `%s' must start with a '/'"
+msgstr "Les valeurs de « %s » doivent commencer par « / »"
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "option `%s' does not take a value"
+msgstr "l'option « %s » ne prend pas de valeur"
+
+#: plugins/sudoers/env.c:295 plugins/sudoers/env.c:302
+#: plugins/sudoers/env.c:407 plugins/sudoers/ldap.c:450
+#: plugins/sudoers/ldap.c:540 plugins/sudoers/ldap.c:1152
+#: plugins/sudoers/ldap.c:1354 plugins/sudoers/ldap.c:1526
+#: plugins/sudoers/ldap.c:1682 plugins/sudoers/linux_audit.c:82
+#: plugins/sudoers/logging.c:929 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:511 plugins/sudoers/prompt.c:161
+#: plugins/sudoers/sudoers.c:815 plugins/sudoers/testsudoers.c:236
+#: plugins/sudoers/toke_util.c:160
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "erreur interne, dépassement de %s"
+
+#: plugins/sudoers/env.c:376
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv : envp est corrompu, longueur incorrecte"
+
+#: plugins/sudoers/env.c:1076
+msgid "unable to rebuild the environment"
+msgstr "recréation de l'environnement impossible"
+
+#: plugins/sudoers/env.c:1150
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "Désolé, vous n'êtes pas autorisé à définir ces variables d'environnement : %s"
+
+#: plugins/sudoers/group_plugin.c:85
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s doit appartenir à l'utilisateur (uid) %d"
+
+#: plugins/sudoers/group_plugin.c:89
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "Seul le propriétaire doit avoir le droit en écriture sur %s"
+
+#: plugins/sudoers/group_plugin.c:97 plugins/sudoers/sssd.c:331
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "chargement de %s impossible : %s"
+
+#: plugins/sudoers/group_plugin.c:103
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "le symbole « group_plugin » est introuvable dans %s"
+
+#: plugins/sudoers/group_plugin.c:108
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s : la version majeure du greffon group %d est incompatible, la version attendue est %d"
+
+#: plugins/sudoers/interfaces.c:117
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Couples adresse IP locale/netmask :\n"
+
+#: plugins/sudoers/iolog.c:92 plugins/sudoers/iolog.c:110
+#: plugins/sudoers/timestamp.c:169
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s existe mais n'est pas un répertoire (0%o)"
+
+#: plugins/sudoers/iolog.c:103 plugins/sudoers/iolog.c:124
+#: plugins/sudoers/iolog.c:131 plugins/sudoers/timestamp.c:163
+#: plugins/sudoers/timestamp.c:184
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "création du répertoire (mkdir) %s impossible"
+
+#: plugins/sudoers/iolog.c:200 plugins/sudoers/sudoers.c:871
+#: plugins/sudoers/sudoreplay.c:300 plugins/sudoers/sudoreplay.c:769
+#: plugins/sudoers/sudoreplay.c:973 plugins/sudoers/timestamp.c:399
+#: plugins/sudoers/visudo.c:903 plugins/sudoers/visudo_json.c:1012
+#: plugins/sudoers/visudo_json.c:1025
+#, c-format
+msgid "unable to open %s"
+msgstr "ouverture de %s impossible"
+
+#: plugins/sudoers/iolog.c:241 plugins/sudoers/sudoers.c:875
+#: plugins/sudoers/sudoreplay.c:1084
+#, c-format
+msgid "unable to read %s"
+msgstr "lecture de %s impossible"
+
+#: plugins/sudoers/iolog.c:277 plugins/sudoers/sudoreplay.c:550
+#: plugins/sudoers/timestamp.c:298 plugins/sudoers/timestamp.c:301
+#, c-format
+msgid "unable to write to %s"
+msgstr "Écriture impossible dans %s"
+
+#: plugins/sudoers/iolog.c:342 plugins/sudoers/iolog.c:540
+#, c-format
+msgid "unable to create %s"
+msgstr "création de %s impossible"
+
+#: plugins/sudoers/ldap.c:428
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports : valeur de port trop élevée"
+
+#: plugins/sudoers/ldap.c:488
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "Type d'uri LDAP non pris en charge : %s"
+
+#: plugins/sudoers/ldap.c:515
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "fusion des URIs ldap et ldaps impossible"
+
+#: plugins/sudoers/ldap.c:519 plugins/sudoers/ldap.c:555
+msgid "starttls not supported when using ldaps"
+msgstr "starttls n'est pas pris en charge lors de l'utilisation de ldap"
+
+#: plugins/sudoers/ldap.c:626
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "initialisation du certificat SSL et la base de clés impossible : %s"
+
+#: plugins/sudoers/ldap.c:629
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "TLS_CERT doit être défini dans %s pour pouvoir utiliser SSL"
+
+#: plugins/sudoers/ldap.c:1138
+msgid "unable to get GMT time"
+msgstr "récupération de l'heure GMT impossible"
+
+#: plugins/sudoers/ldap.c:1144
+msgid "unable to format timestamp"
+msgstr "impossible de formater l'horodatage"
+
+#: plugins/sudoers/ldap.c:1830
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s : %s : %s : %s"
+
+#: plugins/sudoers/ldap.c:2372
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"Rôle LDAP : %s\n"
+
+#: plugins/sudoers/ldap.c:2374
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"Rôle LDAP : INCONNU\n"
+
+#: plugins/sudoers/ldap.c:2421
+#, c-format
+msgid " Order: %s\n"
+msgstr " Ordre : %s\n"
+
+#: plugins/sudoers/ldap.c:2429 plugins/sudoers/parse.c:555
+#: plugins/sudoers/sssd.c:1417
+#, c-format
+msgid " Commands:\n"
+msgstr " Commandes :\n"
+
+#: plugins/sudoers/ldap.c:2993
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "initialisation de LDAP impossible : %s"
+
+#: plugins/sudoers/ldap.c:3029
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls est sélectionné, mais les bibliothèques LDAP ne gèrent pas ldap_start_tls_s() ou ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:3286
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "attribut sudoOrder invalide : %s"
+
+#: plugins/sudoers/linux_audit.c:52
+msgid "unable to open audit system"
+msgstr "ouverture du fichier d'audit du système impossible"
+
+#: plugins/sudoers/linux_audit.c:93
+msgid "unable to send audit message"
+msgstr "envoi du message d'audit impossible"
+
+#: plugins/sudoers/logging.c:106
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:134
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (suite de la commande) %s"
+
+#: plugins/sudoers/logging.c:159
+#, c-format
+msgid "unable to open log file: %s: %s"
+msgstr "ouverture du fichier de journalisation impossible : %s : %s"
+
+#: plugins/sudoers/logging.c:162
+#, c-format
+msgid "unable to lock log file: %s: %s"
+msgstr "verrouillage du fichier de journalisation impossible : %s : %s"
+
+#: plugins/sudoers/logging.c:211
+msgid "No user or host"
+msgstr "Pas d'utilisateur ou d'hôte"
+
+#: plugins/sudoers/logging.c:213
+msgid "validation failure"
+msgstr "échec de la validation"
+
+#: plugins/sudoers/logging.c:220
+msgid "user NOT in sudoers"
+msgstr "l'utilisateur n'apparaît PAS dans sudoers"
+
+#: plugins/sudoers/logging.c:222
+msgid "user NOT authorized on host"
+msgstr "l'utilisateur n'est PAS autorisé sur cet hôte"
+
+#: plugins/sudoers/logging.c:224
+msgid "command not allowed"
+msgstr "commande non autorisée"
+
+#: plugins/sudoers/logging.c:259
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s n'apparaît pas dans le fichier sudoers. Cet événement sera signalé.\n"
+
+#: plugins/sudoers/logging.c:262
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s n'est pas autorisé à exécuter sudo sur %s. Cet événement sera signalé.\n"
+
+#: plugins/sudoers/logging.c:266
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Désolé, l'utilisateur %s ne peut pas utiliser sudo sur %s.\n"
+
+#: plugins/sudoers/logging.c:269
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Désolé, l'utilisateur %s n'est pas autorisé à exécuter « %s%s%s » en tant que %s%s%s sur %s.\n"
+
+#: plugins/sudoers/logging.c:306 plugins/sudoers/sudoers.c:471
+#: plugins/sudoers/sudoers.c:473 plugins/sudoers/sudoers.c:475
+#: plugins/sudoers/sudoers.c:477 plugins/sudoers/sudoers.c:1222
+#: plugins/sudoers/sudoers.c:1224
+#, c-format
+msgid "%s: command not found"
+msgstr "%s : commande introuvable"
+
+#: plugins/sudoers/logging.c:308 plugins/sudoers/sudoers.c:467
+#, c-format
+msgid ""
+"ignoring `%s' found in '.'\n"
+"Use `sudo ./%s' if this is the `%s' you wish to run."
+msgstr ""
+"« %s » trouvé dans « . » n'a pas été exécuté\n"
+"Utilisez « sudo ./%s » si c'est bien la version de « %s » que vous souhaitez exécuter."
+
+#: plugins/sudoers/logging.c:325
+msgid "authentication failure"
+msgstr "échec de l'authentification"
+
+#: plugins/sudoers/logging.c:351
+msgid "a password is required"
+msgstr "il est nécessaire de saisir un mot de passe"
+
+#: plugins/sudoers/logging.c:422 plugins/sudoers/logging.c:484
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u saisie de mot de passe incorrecte"
+msgstr[1] "%u saisies de mots de passe incorrectes"
+
+#: plugins/sudoers/logging.c:572
+msgid "unable to fork"
+msgstr "création du processus fils impossible"
+
+#: plugins/sudoers/logging.c:580 plugins/sudoers/logging.c:640
+#, c-format
+msgid "unable to fork: %m"
+msgstr "création du processus fils impossible : %m"
+
+#: plugins/sudoers/logging.c:630
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "ouverture du tube impossible : %m"
+
+#: plugins/sudoers/logging.c:655
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "duplication (dup) de stdin impossible : %m"
+
+#: plugins/sudoers/logging.c:693
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "exécution de %s impossible : %m"
+
+#: plugins/sudoers/match.c:606
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "le type résumé (digest type ) %d pour n'est pas autorisé pour %s"
+
+#: plugins/sudoers/match.c:639
+#, c-format
+msgid "%s: read error"
+msgstr "%s : erreur en lecture"
+
+#: plugins/sudoers/match.c:653
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "Le résume (digest) de %s (%s) n'est pas dans le forme %s"
+
+#: plugins/sudoers/parse.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "erreur d'analyse grammaticale dans %s aux environs de la ligne %d"
+
+#: plugins/sudoers/parse.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "erreur d'analyse grammaticale dans %s"
+
+#: plugins/sudoers/parse.c:502
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Entrée sudoers :\n"
+
+#: plugins/sudoers/parse.c:503
+#, c-format
+msgid " RunAsUsers: "
+msgstr " RunAsUsers : "
+
+#: plugins/sudoers/parse.c:517
+#, c-format
+msgid " RunAsGroups: "
+msgstr " RunAsGroups : "
+
+#: plugins/sudoers/parse.c:526
+#, c-format
+msgid " Options: "
+msgstr " Options : "
+
+#: plugins/sudoers/policy.c:240 plugins/sudoers/testsudoers.c:253
+msgid "unable to parse network address list"
+msgstr "analyse grammaticale (parse) des adresses réseau impossible"
+
+#: plugins/sudoers/policy.c:640 plugins/sudoers/visudo.c:840
+#, c-format
+msgid "unable to execute %s"
+msgstr "exécution de %s impossible"
+
+#: plugins/sudoers/policy.c:773
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "La version du greffon de politique de sudoers est %s\n"
+
+#: plugins/sudoers/policy.c:775
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "La version de la grammaire du fichier sudoers est %d\n"
+
+#: plugins/sudoers/policy.c:779
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Chemin d'accès à sudoers : %s\n"
+
+#: plugins/sudoers/policy.c:782
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "chemin d'accès à nsswitch : %s\n"
+
+#: plugins/sudoers/policy.c:784
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "chemin d'accès à ldap_conf : %s\n"
+
+#: plugins/sudoers/policy.c:785
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "chemin d'accès à ldap.secret : %s\n"
+
+#: plugins/sudoers/policy.c:818
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "activation d'un point d'ancrage de type %d (version %d.%d) impossible"
+
+#: plugins/sudoers/pwutil.c:136 plugins/sudoers/pwutil.c:153
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "enregistrement de l'uid %u dans le cache impossible, mémoire insuffisante"
+
+#: plugins/sudoers/pwutil.c:147
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "enregistrement de l'uid %u dans le cache impossible, l'entrée existe déjà"
+
+#: plugins/sudoers/pwutil.c:191 plugins/sudoers/pwutil.c:207
+#: plugins/sudoers/pwutil.c:250 plugins/sudoers/pwutil.c:294
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "enregistrement des informations de l'utilisateur %s dans le cache impossible, mémoire insuffisante"
+
+#: plugins/sudoers/pwutil.c:202
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "enregistrement des informations de l'utilisateur %s dans le cache impossible, l'entrée existe déjà"
+
+#: plugins/sudoers/pwutil.c:427 plugins/sudoers/pwutil.c:444
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "enregistrement du gid %u dans le cache impossible, mémoire insuffisante"
+
+#: plugins/sudoers/pwutil.c:438
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "enregistrement du gid %u dans le cache impossible, l'entrée existe déjà"
+
+#: plugins/sudoers/pwutil.c:476 plugins/sudoers/pwutil.c:492
+#: plugins/sudoers/pwutil.c:524 plugins/sudoers/pwutil.c:565
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "enregistrement du groupe %s dans le cache impossible, mémoire insuffisante"
+
+#: plugins/sudoers/pwutil.c:487
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "enregistrement du groupe %s dans le cache impossible, l'entrée existe déjà"
+
+#: plugins/sudoers/pwutil.c:676 plugins/sudoers/pwutil.c:710
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "enregistrement de la liste de groupe %s dans le cache impossible, l'entrée existe déjà"
+
+#: plugins/sudoers/pwutil.c:682 plugins/sudoers/pwutil.c:715
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "enregistrement de la liste de groupe %s dans le cache impossible, mémoire insuffisante"
+
+#: plugins/sudoers/pwutil.c:705
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "analyse grammaticale (parse) de %s impossible"
+
+#: plugins/sudoers/set_perms.c:113 plugins/sudoers/set_perms.c:438
+#: plugins/sudoers/set_perms.c:841 plugins/sudoers/set_perms.c:1138
+#: plugins/sudoers/set_perms.c:1430
+msgid "perm stack overflow"
+msgstr "débordement de la pile perm"
+
+#: plugins/sudoers/set_perms.c:121 plugins/sudoers/set_perms.c:369
+#: plugins/sudoers/set_perms.c:446 plugins/sudoers/set_perms.c:708
+#: plugins/sudoers/set_perms.c:849 plugins/sudoers/set_perms.c:1067
+#: plugins/sudoers/set_perms.c:1146 plugins/sudoers/set_perms.c:1363
+#: plugins/sudoers/set_perms.c:1438 plugins/sudoers/set_perms.c:1527
+msgid "perm stack underflow"
+msgstr "débordement inférieur de la pile perm"
+
+#: plugins/sudoers/set_perms.c:180 plugins/sudoers/set_perms.c:493
+#: plugins/sudoers/set_perms.c:1197 plugins/sudoers/set_perms.c:1470
+msgid "unable to change to root gid"
+msgstr "changement de l'identificateur de groupe (gid) de root impossible"
+
+#: plugins/sudoers/set_perms.c:269 plugins/sudoers/set_perms.c:590
+#: plugins/sudoers/set_perms.c:978 plugins/sudoers/set_perms.c:1274
+msgid "unable to change to runas gid"
+msgstr "changement du groupe effectif (runas) impossible"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:595
+#: plugins/sudoers/set_perms.c:983 plugins/sudoers/set_perms.c:1279
+msgid "unable to set runas group vector"
+msgstr "positionnement du vecteur du groupe effectif (runas) impossible"
+
+#: plugins/sudoers/set_perms.c:285 plugins/sudoers/set_perms.c:606
+#: plugins/sudoers/set_perms.c:992 plugins/sudoers/set_perms.c:1288
+msgid "unable to change to runas uid"
+msgstr "changement de l'uid effectif (runas) impossible"
+
+#: plugins/sudoers/set_perms.c:303 plugins/sudoers/set_perms.c:624
+#: plugins/sudoers/set_perms.c:1008 plugins/sudoers/set_perms.c:1304
+msgid "unable to change to sudoers gid"
+msgstr "changement du groupe (gid) de sudoers impossible"
+
+#: plugins/sudoers/set_perms.c:356 plugins/sudoers/set_perms.c:695
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1350
+#: plugins/sudoers/set_perms.c:1514
+msgid "too many processes"
+msgstr "trop de processus"
+
+#: plugins/sudoers/solaris_audit.c:51
+msgid "unable to get current working directory"
+msgstr "récupération du répertoire de travail impossible"
+
+#: plugins/sudoers/solaris_audit.c:59
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "le chemin d'accès à l'audit user_cmnd est incomplet : %s"
+
+#: plugins/sudoers/solaris_audit.c:66
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "le chemin d'accès à l'audit argv[0] est incomplet : %s"
+
+#: plugins/sudoers/solaris_audit.c:115
+msgid "audit_failure message too long"
+msgstr "le message audit_failure est trop long"
+
+#: plugins/sudoers/sssd.c:333
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "initialisation de la source SSS impossible. SSSD est-il installé sur cette machine ?"
+
+#: plugins/sudoers/sssd.c:341 plugins/sudoers/sssd.c:350
+#: plugins/sudoers/sssd.c:359 plugins/sudoers/sssd.c:368
+#: plugins/sudoers/sssd.c:377
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "Le symbole « %s » est introuvable dans %s"
+
+#: plugins/sudoers/sudo_nss.c:290
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Entrées par défaut pour %s sur %s :\n"
+
+#: plugins/sudoers/sudo_nss.c:308
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Paramètres par défaut de runas ou d'autres commandes pour %s :\n"
+
+#: plugins/sudoers/sudo_nss.c:326
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "L'utilisateur %s peut utiliser les commandes suivantes sur %s :\n"
+
+#: plugins/sudoers/sudo_nss.c:339
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "L'utilisateur %s n'est pas autorisé à exécuter sudo sur %s.\n"
+
+#: plugins/sudoers/sudoers.c:172 plugins/sudoers/testsudoers.c:245
+#: plugins/sudoers/visudo.c:223 plugins/sudoers/visudo.c:566
+msgid "unable to initialize sudoers default values"
+msgstr "initialisation des valeurs par défaut de sudoers impossible"
+
+#: plugins/sudoers/sudoers.c:197 plugins/sudoers/sudoers.c:239
+#: plugins/sudoers/sudoers.c:833
+msgid "problem with defaults entries"
+msgstr "les entrées par défaut posent un problème"
+
+#: plugins/sudoers/sudoers.c:205
+msgid "no valid sudoers sources found, quitting"
+msgstr "aucune source sudoers valide n'a été trouvée, fin d'exécution"
+
+#: plugins/sudoers/sudoers.c:275
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "il est précisé dans sudoers que root n'est pas autorisé à utiliser sudo"
+
+#: plugins/sudoers/sudoers.c:332
+msgid "you are not permitted to use the -C option"
+msgstr "vous n'êtes pas autorisé à utiliser l'option -C"
+
+#: plugins/sudoers/sudoers.c:396
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "propriétaire du fichier d'horodatage (%s) : utilisateur inconnu"
+
+#: plugins/sudoers/sudoers.c:410
+msgid "no tty"
+msgstr "pas de terminal tty"
+
+#: plugins/sudoers/sudoers.c:411
+msgid "sorry, you must have a tty to run sudo"
+msgstr "désolé, vous devez avoir un terminal tty pour exécuter sudo"
+
+#: plugins/sudoers/sudoers.c:466
+msgid "command in current directory"
+msgstr "commande dans le répertoire courant"
+
+#: plugins/sudoers/sudoers.c:486
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "désolé, vous n'êtes pas autorisé à conserver l'environnement"
+
+#: plugins/sudoers/sudoers.c:778
+msgid "command too long"
+msgstr "commande trop longue"
+
+#: plugins/sudoers/sudoers.c:886 plugins/sudoers/visudo.c:426
+#: plugins/sudoers/visudo.c:666
+#, c-format
+msgid "unable to stat %s"
+msgstr "impossible d'appliquer la fonction stat à %s"
+
+#: plugins/sudoers/sudoers.c:890
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s n'est pas un fichier ordinaire"
+
+#: plugins/sudoers/sudoers.c:894 plugins/sudoers/timestamp.c:225 toke.l:947
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "Le fichier %s a l'utilisateur (uid) %u pour propriétaire, alors qu'il devraitappartenir à %u"
+
+#: plugins/sudoers/sudoers.c:898 toke.l:954
+#, c-format
+msgid "%s is world writable"
+msgstr "Le fichier %s est ouvert en écriture pour tous"
+
+#: plugins/sudoers/sudoers.c:902 toke.l:959
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "Le fichier %s a pour groupe (gid) %u, alors qu'il devrait appartenir au groupe %u"
+
+#: plugins/sudoers/sudoers.c:933
+#, c-format
+msgid "only root can use `-c %s'"
+msgstr "« -c %s » est réservé à l'utilisateur root"
+
+#: plugins/sudoers/sudoers.c:952
+#, c-format
+msgid "unknown login class: %s"
+msgstr "classe de connexion inconnue : %s"
+
+#: plugins/sudoers/sudoers.c:1031 plugins/sudoers/sudoers.c:1059
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "impossible de déterminer le nom de l'hôte %s"
+
+#: plugins/sudoers/sudoers.c:1126 plugins/sudoers/testsudoers.c:385
+#, c-format
+msgid "unknown group: %s"
+msgstr "groupe inconnu : %s"
+
+#: plugins/sudoers/sudoreplay.c:232
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "option du filte invalide : %s"
+
+#: plugins/sudoers/sudoreplay.c:245
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "attente maximum invalide : %s"
+
+#: plugins/sudoers/sudoreplay.c:251
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "facteur de vitesse invalide : %s"
+
+#: plugins/sudoers/sudoreplay.c:254 plugins/sudoers/visudo.c:180
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s version %s\n"
+
+#: plugins/sudoers/sudoreplay.c:286
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/timing : %s"
+
+#: plugins/sudoers/sudoreplay.c:292
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/timing : %s"
+
+#: plugins/sudoers/sudoreplay.c:308
+#, c-format
+msgid "Replaying sudo session: %s\n"
+msgstr "Rejeu de la session sudo : %s\n"
+
+#: plugins/sudoers/sudoreplay.c:314
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Attention : la taille du terminal n'est pas suffisante pour pouvoir rejouer correctement la séquence.\n"
+
+#: plugins/sudoers/sudoreplay.c:315
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "La taille du journal est %d x %d, la taille de votre terminal est %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:368
+msgid "unable to set tty to raw mode"
+msgstr "impossible d'initialiser le terminal tty en mode direct"
+
+#: plugins/sudoers/sudoreplay.c:401
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "entrée invalide dans le fichier de timing : %s"
+
+#: plugins/sudoers/sudoreplay.c:611 plugins/sudoers/sudoreplay.c:636
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "expression ambiguë « %s »"
+
+#: plugins/sudoers/sudoreplay.c:658
+msgid "unmatched ')' in expression"
+msgstr "il manque une parenthèse ouvrante « ( » dans l'expression"
+
+#: plugins/sudoers/sudoreplay.c:662
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "terme de recherche « %s » inconnu"
+
+#: plugins/sudoers/sudoreplay.c:677
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s requiert le passage d'un argument"
+
+#: plugins/sudoers/sudoreplay.c:680 plugins/sudoers/sudoreplay.c:1060
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "expression régulière invalide : %s"
+
+#: plugins/sudoers/sudoreplay.c:684
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "Analyse grammaticale de la date « %s » impossible"
+
+#: plugins/sudoers/sudoreplay.c:693
+msgid "unmatched '(' in expression"
+msgstr "il manque une parenthèse fermante « ) » dans l'expression"
+
+#: plugins/sudoers/sudoreplay.c:695
+msgid "illegal trailing \"or\""
+msgstr "« or » n'est pas autorisé en fin d'expression"
+
+#: plugins/sudoers/sudoreplay.c:697
+msgid "illegal trailing \"!\""
+msgstr "« ! » n'est pas autorisé en fin d'expression"
+
+#: plugins/sudoers/sudoreplay.c:746
+#, c-format
+msgid "unknown search type %d"
+msgstr "type de recherche « %d » inconnu"
+
+#: plugins/sudoers/sudoreplay.c:784
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s : fichier de journalisation incorrect"
+
+#: plugins/sudoers/sudoreplay.c:802
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s : il manque le champ d'horodatage"
+
+#: plugins/sudoers/sudoreplay.c:809
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s : horodatage %s : %s"
+
+#: plugins/sudoers/sudoreplay.c:816
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s : il manque le champ utilisateur"
+
+#: plugins/sudoers/sudoreplay.c:825
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s : il manque le champ précisant l'utilisateur effectif (runas)"
+
+#: plugins/sudoers/sudoreplay.c:834
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s : il manque le champ précisant le groupe effectif (runas)"
+
+#: plugins/sudoers/sudoreplay.c:1197
+#, c-format
+msgid "usage: %s [-h] [-d dir] [-m num] [-s num] ID\n"
+msgstr "Utilisation : %s [-h] [-d répertoire] [-m nombre] [-s nombre] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1200
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "Utilisation : %s [-h] [-d répertoire] -l [expression recherchée ]\n"
+
+#: plugins/sudoers/sudoreplay.c:1209
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - Rejeu du journal de la session sudo\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1211
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Options :\n"
+" -d, --directory=répertoire indique le répertoire à utiliser pour les traces de la session\n"
+" -f, --filter=filtre indique quel type E/S utiliser pour l'affichage\n"
+" -h, --help affiche le message et d'aide, puis termine l'exécution\n"
+" -l, --list liste les identificateurs de sessions disponible, il est possible d'ajouter une expression en paramètre \n"
+" -m, max_wait=valeur nombre maximum de secondes de temporisation entre les événements\n"
+" -s, --speed=valeur accélère ou ralentit l'exécution\n"
+" -V, --version affiche la version du programme, puis termine l'exécution"
+
+#: plugins/sudoers/testsudoers.c:324
+msgid "\thost unmatched"
+msgstr "\tl'hôte n'a pas de correspondance"
+
+#: plugins/sudoers/testsudoers.c:327
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Commande autorisée"
+
+#: plugins/sudoers/testsudoers.c:328
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Commande refusée"
+
+#: plugins/sudoers/testsudoers.c:328
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Commande sans correspondance"
+
+#: plugins/sudoers/timestamp.c:233
+#, c-format
+msgid "%s is group writable"
+msgstr "%s est accessible en écriture pour les membres du groupe"
+
+#: plugins/sudoers/timestamp.c:309
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "impossible de tronquer le fichier d'horodatage de %lld octets"
+
+#: plugins/sudoers/timestamp.c:742 plugins/sudoers/timestamp.c:809
+#: plugins/sudoers/visudo.c:487 plugins/sudoers/visudo.c:493
+msgid "unable to read the clock"
+msgstr "lecture du bloc impossible"
+
+#: plugins/sudoers/timestamp.c:756
+msgid "ignoring time stamp from the future"
+msgstr "un horodatage dans le futur n'a pas été pris en compte"
+
+#: plugins/sudoers/timestamp.c:768
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "l'horodatage est trop avancé dans le temps : %20.20s"
+
+#: plugins/sudoers/timestamp.c:863
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "verrouillage de l'horodatage du fichier %s impossible"
+
+#: plugins/sudoers/timestamp.c:906 plugins/sudoers/timestamp.c:926
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "le chemin d'accès au fichier d'état de la recommandation est trop long : %s/%s"
+
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "Version de la grammaire de %s : %d\n"
+
+#: plugins/sudoers/visudo.c:254 plugins/sudoers/visudo.c:618
+#, c-format
+msgid "press return to edit %s: "
+msgstr "appuyer sur entrée pour afficher %s : "
+
+#: plugins/sudoers/visudo.c:319
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "l'éditeur indiqué (%s) n'existe pas"
+
+#: plugins/sudoers/visudo.c:337
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "aucun éditeur trouvé (chemin d'accès à l'éditeur : %s)"
+
+#: plugins/sudoers/visudo.c:446 plugins/sudoers/visudo.c:454
+msgid "write error"
+msgstr "erreur en écriture"
+
+#: plugins/sudoers/visudo.c:500
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "impossible d'appliquer la fonction stat au fichier temporaire (%s), %s n'a pas été modifié"
+
+#: plugins/sudoers/visudo.c:507
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "fichier temporaire vide (%s), %s n'a pas été modifié"
+
+#: plugins/sudoers/visudo.c:513
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "l'éditeur (%s) a échoué, %s n'a pas été modifié"
+
+#: plugins/sudoers/visudo.c:535
+#, c-format
+msgid "%s unchanged"
+msgstr "%s n'a pas été modifié"
+
+#: plugins/sudoers/visudo.c:561
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "impossible de rouvrir le fichier temporaire (%s), %s n'a pas été modifié."
+
+#: plugins/sudoers/visudo.c:572
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "impossible d'effectuer l'analyse grammaticale du fichier temporaire (%s), erreur inconnue"
+
+#: plugins/sudoers/visudo.c:609
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "erreur interne, impossible de trouver %s dans la liste !"
+
+#: plugins/sudoers/visudo.c:668 plugins/sudoers/visudo.c:677
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "impossible d'affecter (uid, gid) de %s à (%u, %u)"
+
+#: plugins/sudoers/visudo.c:672 plugins/sudoers/visudo.c:682
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "impossible de changer le mode de %s pour lui affecter 0%o"
+
+#: plugins/sudoers/visudo.c:699
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s et %s ne sont pas dans le même système de fichiers, tentative de renommage à l'aide de la commande mv"
+
+#: plugins/sudoers/visudo.c:713
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "la commande a échoué : « %s  %s %s », %s n'a pas été modifié"
+
+#: plugins/sudoers/visudo.c:723
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "erreur lors du renommage de %s, %s n'a pas été modifié"
+
+#: plugins/sudoers/visudo.c:785
+msgid "What now? "
+msgstr "Et maintenant ?"
+
+#: plugins/sudoers/visudo.c:799
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Les options sont :\n"
+" (e)dition du fichier sudoers (de nouveau)\n"
+" e(x)it sans sauvegarde des modifications apportées au fichier sudoers\n"
+" (Q)uitter et sauvegarder les modifications apportées au fichier sudoers (DANGER!)\n"
+
+#: plugins/sudoers/visudo.c:847
+#, c-format
+msgid "unable to run %s"
+msgstr "lancement de %s impossible"
+
+#: plugins/sudoers/visudo.c:877
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s : mauvais utilisateur (uid, gid), celui-ci devrait être (%u,%u)\n"
+
+#: plugins/sudoers/visudo.c:884
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s : mauvais droits d'utilisation, le mode devrait être 0%o\n"
+
+#: plugins/sudoers/visudo.c:909 plugins/sudoers/visudo_json.c:1032
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "échec lors de l'analyse grammaticale de %s, erreur inconnue"
+
+#: plugins/sudoers/visudo.c:925 plugins/sudoers/visudo_json.c:1041
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "erreur lors de l'analyse grammaticale de %s au environs de la ligne %d\n"
+
+#: plugins/sudoers/visudo.c:928 plugins/sudoers/visudo_json.c:1044
+#, c-format
+msgid "parse error in %s\n"
+msgstr "erreur lors de l'analyse grammaticale de %s\n"
+
+#: plugins/sudoers/visudo.c:936 plugins/sudoers/visudo.c:943
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s : analyse grammaticale réussie\n"
+
+#: plugins/sudoers/visudo.c:990
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s n'est pas disponible, réessayez plus tard"
+
+#: plugins/sudoers/visudo.c:1086
+#, c-format
+msgid "Error: cycle in %s `%s'"
+msgstr "Erreur : boucle dans %s « %s »"
+
+#: plugins/sudoers/visudo.c:1087
+#, c-format
+msgid "Warning: cycle in %s `%s'"
+msgstr "Attention : boucle dans %s « %s »"
+
+#: plugins/sudoers/visudo.c:1091
+#, c-format
+msgid "Error: %s `%s' referenced but not defined"
+msgstr "Erreur : il est fait mention de %s « %s » alors qu'il n'a pas été défini"
+
+#: plugins/sudoers/visudo.c:1092
+#, c-format
+msgid "Warning: %s `%s' referenced but not defined"
+msgstr "Attention : il est fait mention de %s « %s » alors qu'il n'a pas été défini"
+
+#: plugins/sudoers/visudo.c:1235
+#, c-format
+msgid "Warning: unused %s `%s'"
+msgstr "Attention : %s « %s » n'est pas utilisé"
+
+#: plugins/sudoers/visudo.c:1348
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - édite le fichier sudoers\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1350
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+" -x, --export=output_file write sudoers in JSON format to output_file"
+msgstr ""
+"\n"
+"Options :\n"
+" -c, --check mode validation\n"
+" -f, --file==fichier précise l'emplacement du fichier sudoers\n"
+" -h, --help affiche le message d'aide, puis met fin à l'exécution\n"
+" -q, --quiet nombre de messages d'erreur de syntaxe réduit (mode silencieux)\n"
+" -s, --strict validation stricte de la syntaxe\n"
+" -V, --version affiche la version, puis met fin à l'exécution -x, --export=fichier_sortie affiche sudoers au format JSON dans le fichier fichier_sortie"
+
+#: plugins/sudoers/visudo_json.c:1018
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s : les fichiers d'entrée et de sortie doivent être différents"
+
+#: toke.l:918
+msgid "too many levels of includes"
+msgstr "nombre de niveaux d'inclusions trop élevé"
+
+#~ msgid "timestamp path too long: %s/%s"
+#~ msgstr "Chemin d'accès au fichier d'horodatage trop long : %s/%s"
+
+#~ msgid "unable to stat editor (%s)"
+#~ msgstr "impossible d'obtenir les stats de l'éditeur (%s)"
+
+#~ msgid "Password:"
+#~ msgstr "Mot de passe :"
+
+#~ msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+#~ msgstr "sudo_ldap_conf_add_ports : espace insuffisant pour étendre hostbuf"
+
+#~ msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+#~ msgstr "sudo_ldap_parse_uri :espace insuffisant pour créer hostbuf"
+
+#~ msgid "sudo_ldap_build_pass1 allocation mismatch"
+#~ msgstr "sudo_ldap_build_pass1 : erreur d'allocation"
+
+#~ msgid "unable to setup authentication"
+#~ msgstr "configuration de l'authentification impossible"
+
+#~ msgid "invalid uri: %s"
+#~ msgstr "uri invalide : %s"
+
+#~ msgid "unable to mix ldaps and starttls"
+#~ msgstr "fusion ldaps et starttls impossible"
+
+#~ msgid "internal error: insufficient space for log line"
+#~ msgstr "erreur interne : espace insuffisant pour la ligne de journalisation"
+
+#~ msgid "value out of range"
+#~ msgstr "valeur hors de limites "
+
+#~ msgid "writing to standard output"
+#~ msgstr "écriture vers la sortie standard"
+
+#~ msgid "too many parenthesized expressions, max %d"
+#~ msgstr "le nombre d'expressions entre parenthèses est trop élevé, le maximum autorisé est %d"
+
+#~ msgid "%s owned by uid %u, should be uid %u"
+#~ msgstr "%s appartient à l'utilisateur identifié par %u, alors qu'il devrait appartenir à l'utilisateur identifié par %u"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0700"
+#~ msgstr "%s peut être modifié par d'autres utilisateur que son propriétaire (0%o), le mode des privilèges devrait être 0700"
+
+#~ msgid "%s exists but is not a regular file (0%o)"
+#~ msgstr "%s existe mais n'est pas un fichier ordinaire (0%o)"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0600"
+#~ msgstr "%s peut être modifié par d'autres utilisateurs que son propriétaire (0%o), le mode des privilèges devrait être 0600"
+
+#~ msgid "unable to remove %s, will reset to the epoch"
+#~ msgstr "suppression de %s impossible, l'horodatage sera réinitialisé à la date courante"
+
+#~ msgid "unable to reset %s to the epoch"
+#~ msgstr "impossible de réinitialiser %s à la date courante"
+
+#~ msgid "fill_args: buffer overflow"
+#~ msgstr "fill_args : débordement du tampon"
+
+#~ msgid "%s: unused %s_Alias %s"
+#~ msgstr "%s : %s_Alias %s n'est pas utilisé"
+
+#~ msgid ">>> %s: %s near line %d <<<"
+#~ msgstr ">>> %s : %s aux environs de la ligne %d <<<"
+
+#~ msgid "pam_chauthtok: %s"
+#~ msgstr "pam_chauthtok : %s"
+
+#~ msgid "pam_authenticate: %s"
+#~ msgstr "pam_authenticate : %s"
+
+#~ msgid "getaudit: failed"
+#~ msgstr "getaudit : échec"
+
+#~ msgid "getauid failed"
+#~ msgstr "échec de getauid"
+
+#~ msgid "au_open: failed"
+#~ msgstr "au_open : échec"
+
+#~ msgid "au_to_subject: failed"
+#~ msgstr "au_to_subject : échec"
+
+#~ msgid "au_to_exec_args: failed"
+#~ msgstr "au_to_exec_args : échec"
+
+#~ msgid "au_to_return32: failed"
+#~ msgstr "au_to_return32 : échec"
+
+#~ msgid "getauid: failed"
+#~ msgstr "getauid : échec"
+
+#~ msgid "au_to_text: failed"
+#~ msgstr "au_to_text : échec"
+
+#~ msgid "unable to set locale to \"%s\", using \"C\""
+#~ msgstr "impossible d'initialiser la localisation à « %s », initialisation à « C »"
+
+#~ msgid ""
+#~ " Commands:\n"
+#~ "\t"
+#~ msgstr ""
+#~ " Commandes :\n"
+#~ "\t"
+
+#~ msgid ": "
+#~ msgstr " : "
+
+#~ msgid "unable to cache uid %u (%s), already exists"
+#~ msgstr "impossible d'enregistrer l'uid %u (%s) dans le cache, l'entrée existe déjà"
+
+#~ msgid "unable to cache gid %u (%s), already exists"
+#~ msgstr "impossible d'enregistrer le gid %u (%s) dans le cache, l'entrée existe déjà"
+
+#~ msgid "Unable to dlopen %s: %s"
+#~ msgstr "impossible d'appliquer dlopen à %s : %s"
+
+#~ msgid "unable to execute %s: %s"
+#~ msgstr "impossible d'exécuter %s : %s"
+
+#~ msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
+#~ msgstr "nanosleep : tv_sec %ld, tv_nsec %ld"
+
+#~ msgid "invalid regex: %s"
+#~ msgstr "Expression régulière invalide : %s"
diff --git a/plugins/sudoers/po/fur.mo b/plugins/sudoers/po/fur.mo
new file mode 100644
index 0000000..5beaa90
--- /dev/null
+++ b/plugins/sudoers/po/fur.mo
Binary files differ
diff --git a/plugins/sudoers/po/fur.po b/plugins/sudoers/po/fur.po
new file mode 100644
index 0000000..4423803
--- /dev/null
+++ b/plugins/sudoers/po/fur.po
@@ -0,0 +1,2119 @@
+# Friulian translations for sudoers package
+# This file is put in the public domain.
+# Fabio Tomat <f.t.public@gmail.com>, 2017
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers-1.8.22b2\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2017-12-18 10:37-0700\n"
+"PO-Revision-Date: 2017-12-24 14:18+0100\n"
+"Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n"
+"Language-Team: Friulian <f.t.public@gmail.com>\n"
+"Language: fur\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 2.0.3\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "erôr di sintassi"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "Password di %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] password par %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Password: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** informazions di SIGURECE par %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Torne prove."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:307 gram.y:314 gram.y:321 gram.y:328 gram.y:335
+#: gram.y:398 gram.y:406 gram.y:416 gram.y:449 gram.y:456 gram.y:463
+#: gram.y:470 gram.y:552 gram.y:559 gram.y:568 gram.y:577 gram.y:594
+#: gram.y:706 gram.y:713 gram.y:720 gram.y:728 gram.y:824 gram.y:831
+#: gram.y:838 gram.y:845 gram.y:852 gram.y:878 gram.y:885 gram.y:892
+#: gram.y:1015 gram.y:1195 gram.y:1202 plugins/sudoers/alias.c:124
+#: plugins/sudoers/alias.c:139 plugins/sudoers/auth/bsdauth.c:141
+#: plugins/sudoers/auth/kerb5.c:119 plugins/sudoers/auth/kerb5.c:145
+#: plugins/sudoers/auth/pam.c:490 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/auth/sia.c:59 plugins/sudoers/defaults.c:651
+#: plugins/sudoers/defaults.c:906 plugins/sudoers/defaults.c:1077
+#: plugins/sudoers/editor.c:64 plugins/sudoers/editor.c:82
+#: plugins/sudoers/editor.c:93 plugins/sudoers/env.c:233
+#: plugins/sudoers/filedigest.c:120 plugins/sudoers/filedigest_gcrypt.c:90
+#: plugins/sudoers/filedigest_openssl.c:111 plugins/sudoers/gc.c:52
+#: plugins/sudoers/group_plugin.c:134 plugins/sudoers/interfaces.c:71
+#: plugins/sudoers/iolog.c:941 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:449 plugins/sudoers/ldap.c:480
+#: plugins/sudoers/ldap.c:532 plugins/sudoers/ldap.c:566
+#: plugins/sudoers/ldap.c:980 plugins/sudoers/ldap.c:1174
+#: plugins/sudoers/ldap.c:1185 plugins/sudoers/ldap.c:1201
+#: plugins/sudoers/ldap.c:1493 plugins/sudoers/ldap.c:1653
+#: plugins/sudoers/ldap.c:1735 plugins/sudoers/ldap.c:1883
+#: plugins/sudoers/ldap.c:1907 plugins/sudoers/ldap.c:1996
+#: plugins/sudoers/ldap.c:2011 plugins/sudoers/ldap.c:2107
+#: plugins/sudoers/ldap.c:2140 plugins/sudoers/ldap.c:2221
+#: plugins/sudoers/ldap.c:2303 plugins/sudoers/ldap.c:2400
+#: plugins/sudoers/ldap.c:3235 plugins/sudoers/ldap.c:3267
+#: plugins/sudoers/ldap.c:3579 plugins/sudoers/ldap.c:3607
+#: plugins/sudoers/ldap.c:3623 plugins/sudoers/ldap.c:3713
+#: plugins/sudoers/ldap.c:3729 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:190 plugins/sudoers/logging.c:501
+#: plugins/sudoers/logging.c:522 plugins/sudoers/logging.c:563
+#: plugins/sudoers/logging.c:740 plugins/sudoers/logging.c:998
+#: plugins/sudoers/match.c:617 plugins/sudoers/match.c:664
+#: plugins/sudoers/match.c:714 plugins/sudoers/match.c:738
+#: plugins/sudoers/match.c:826 plugins/sudoers/match.c:915
+#: plugins/sudoers/parse.c:252 plugins/sudoers/parse.c:264
+#: plugins/sudoers/parse.c:279 plugins/sudoers/parse.c:291
+#: plugins/sudoers/policy.c:498 plugins/sudoers/policy.c:735
+#: plugins/sudoers/prompt.c:93 plugins/sudoers/pwutil.c:165
+#: plugins/sudoers/pwutil.c:236 plugins/sudoers/pwutil.c:312
+#: plugins/sudoers/pwutil.c:486 plugins/sudoers/pwutil.c:551
+#: plugins/sudoers/pwutil.c:620 plugins/sudoers/pwutil.c:778
+#: plugins/sudoers/pwutil.c:835 plugins/sudoers/pwutil.c:880
+#: plugins/sudoers/pwutil.c:938 plugins/sudoers/sssd.c:162
+#: plugins/sudoers/sssd.c:194 plugins/sudoers/sssd.c:237
+#: plugins/sudoers/sssd.c:244 plugins/sudoers/sssd.c:280
+#: plugins/sudoers/sssd.c:353 plugins/sudoers/sssd.c:392
+#: plugins/sudoers/sssd.c:1073 plugins/sudoers/sssd.c:1252
+#: plugins/sudoers/sssd.c:1266 plugins/sudoers/sssd.c:1282
+#: plugins/sudoers/sudoers.c:263 plugins/sudoers/sudoers.c:273
+#: plugins/sudoers/sudoers.c:281 plugins/sudoers/sudoers.c:365
+#: plugins/sudoers/sudoers.c:682 plugins/sudoers/sudoers.c:807
+#: plugins/sudoers/sudoers.c:851 plugins/sudoers/sudoers.c:1123
+#: plugins/sudoers/sudoers_debug.c:107 plugins/sudoers/sudoreplay.c:1254
+#: plugins/sudoers/sudoreplay.c:1366 plugins/sudoers/sudoreplay.c:1406
+#: plugins/sudoers/sudoreplay.c:1415 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/sudoreplay.c:1433 plugins/sudoers/sudoreplay.c:1437
+#: plugins/sudoers/sudoreplay.c:1593 plugins/sudoers/sudoreplay.c:1597
+#: plugins/sudoers/testsudoers.c:131 plugins/sudoers/testsudoers.c:217
+#: plugins/sudoers/testsudoers.c:234 plugins/sudoers/timestamp.c:397
+#: plugins/sudoers/timestamp.c:441 plugins/sudoers/timestamp.c:868
+#: plugins/sudoers/toke_util.c:56 plugins/sudoers/toke_util.c:109
+#: plugins/sudoers/toke_util.c:146 plugins/sudoers/visudo.c:153
+#: plugins/sudoers/visudo.c:309 plugins/sudoers/visudo.c:315
+#: plugins/sudoers/visudo.c:446 plugins/sudoers/visudo.c:624
+#: plugins/sudoers/visudo.c:985 plugins/sudoers/visudo.c:1051
+#: plugins/sudoers/visudo.c:1095 plugins/sudoers/visudo.c:1197
+#: plugins/sudoers/visudo_json.c:1025 toke.l:849 toke.l:949 toke.l:1106
+msgid "unable to allocate memory"
+msgstr "impussibil assegnâ memorie"
+
+#: gram.y:481
+msgid "a digest requires a path name"
+msgstr "un digest al domande un non di percors"
+
+#: gram.y:607
+msgid "invalid notbefore value"
+msgstr ""
+
+#: gram.y:615
+msgid "invalid notafter value"
+msgstr ""
+
+#: gram.y:624 plugins/sudoers/policy.c:314
+msgid "timeout value too large"
+msgstr "valôr di timeout masse larc"
+
+#: gram.y:626 plugins/sudoers/policy.c:316
+msgid "invalid timeout value"
+msgstr "valôr di timeout no valit"
+
+#: gram.y:1195 gram.y:1202 plugins/sudoers/auth/pam.c:320
+#: plugins/sudoers/auth/pam.c:490 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/defaults.c:651 plugins/sudoers/defaults.c:906
+#: plugins/sudoers/defaults.c:1077 plugins/sudoers/editor.c:64
+#: plugins/sudoers/editor.c:82 plugins/sudoers/editor.c:93
+#: plugins/sudoers/env.c:233 plugins/sudoers/filedigest.c:120
+#: plugins/sudoers/filedigest_gcrypt.c:72
+#: plugins/sudoers/filedigest_gcrypt.c:90
+#: plugins/sudoers/filedigest_openssl.c:111 plugins/sudoers/gc.c:52
+#: plugins/sudoers/group_plugin.c:134 plugins/sudoers/interfaces.c:71
+#: plugins/sudoers/iolog.c:941 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:449 plugins/sudoers/ldap.c:480
+#: plugins/sudoers/ldap.c:532 plugins/sudoers/ldap.c:566
+#: plugins/sudoers/ldap.c:980 plugins/sudoers/ldap.c:1174
+#: plugins/sudoers/ldap.c:1185 plugins/sudoers/ldap.c:1201
+#: plugins/sudoers/ldap.c:1493 plugins/sudoers/ldap.c:1653
+#: plugins/sudoers/ldap.c:1735 plugins/sudoers/ldap.c:1883
+#: plugins/sudoers/ldap.c:1907 plugins/sudoers/ldap.c:1996
+#: plugins/sudoers/ldap.c:2011 plugins/sudoers/ldap.c:2107
+#: plugins/sudoers/ldap.c:2140 plugins/sudoers/ldap.c:2220
+#: plugins/sudoers/ldap.c:2303 plugins/sudoers/ldap.c:2400
+#: plugins/sudoers/ldap.c:3235 plugins/sudoers/ldap.c:3267
+#: plugins/sudoers/ldap.c:3579 plugins/sudoers/ldap.c:3606
+#: plugins/sudoers/ldap.c:3622 plugins/sudoers/ldap.c:3713
+#: plugins/sudoers/ldap.c:3729 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:190 plugins/sudoers/logging.c:501
+#: plugins/sudoers/logging.c:522 plugins/sudoers/logging.c:562
+#: plugins/sudoers/logging.c:998 plugins/sudoers/match.c:616
+#: plugins/sudoers/match.c:663 plugins/sudoers/match.c:714
+#: plugins/sudoers/match.c:738 plugins/sudoers/match.c:826
+#: plugins/sudoers/match.c:914 plugins/sudoers/parse.c:252
+#: plugins/sudoers/parse.c:264 plugins/sudoers/parse.c:279
+#: plugins/sudoers/parse.c:291 plugins/sudoers/policy.c:128
+#: plugins/sudoers/policy.c:137 plugins/sudoers/policy.c:146
+#: plugins/sudoers/policy.c:172 plugins/sudoers/policy.c:299
+#: plugins/sudoers/policy.c:314 plugins/sudoers/policy.c:316
+#: plugins/sudoers/policy.c:342 plugins/sudoers/policy.c:352
+#: plugins/sudoers/policy.c:396 plugins/sudoers/policy.c:406
+#: plugins/sudoers/policy.c:415 plugins/sudoers/policy.c:424
+#: plugins/sudoers/policy.c:498 plugins/sudoers/policy.c:735
+#: plugins/sudoers/prompt.c:93 plugins/sudoers/pwutil.c:165
+#: plugins/sudoers/pwutil.c:236 plugins/sudoers/pwutil.c:312
+#: plugins/sudoers/pwutil.c:486 plugins/sudoers/pwutil.c:551
+#: plugins/sudoers/pwutil.c:620 plugins/sudoers/pwutil.c:778
+#: plugins/sudoers/pwutil.c:835 plugins/sudoers/pwutil.c:880
+#: plugins/sudoers/pwutil.c:938 plugins/sudoers/set_perms.c:387
+#: plugins/sudoers/set_perms.c:766 plugins/sudoers/set_perms.c:1150
+#: plugins/sudoers/set_perms.c:1476 plugins/sudoers/set_perms.c:1641
+#: plugins/sudoers/sssd.c:162 plugins/sudoers/sssd.c:194
+#: plugins/sudoers/sssd.c:237 plugins/sudoers/sssd.c:244
+#: plugins/sudoers/sssd.c:280 plugins/sudoers/sssd.c:352
+#: plugins/sudoers/sssd.c:392 plugins/sudoers/sssd.c:1073
+#: plugins/sudoers/sssd.c:1251 plugins/sudoers/sssd.c:1266
+#: plugins/sudoers/sssd.c:1282 plugins/sudoers/sudoers.c:263
+#: plugins/sudoers/sudoers.c:273 plugins/sudoers/sudoers.c:281
+#: plugins/sudoers/sudoers.c:365 plugins/sudoers/sudoers.c:682
+#: plugins/sudoers/sudoers.c:807 plugins/sudoers/sudoers.c:851
+#: plugins/sudoers/sudoers.c:1123 plugins/sudoers/sudoers_debug.c:106
+#: plugins/sudoers/sudoreplay.c:1254 plugins/sudoers/sudoreplay.c:1366
+#: plugins/sudoers/sudoreplay.c:1406 plugins/sudoers/sudoreplay.c:1415
+#: plugins/sudoers/sudoreplay.c:1425 plugins/sudoers/sudoreplay.c:1433
+#: plugins/sudoers/sudoreplay.c:1437 plugins/sudoers/sudoreplay.c:1593
+#: plugins/sudoers/sudoreplay.c:1597 plugins/sudoers/testsudoers.c:131
+#: plugins/sudoers/testsudoers.c:217 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/timestamp.c:397 plugins/sudoers/timestamp.c:441
+#: plugins/sudoers/timestamp.c:868 plugins/sudoers/toke_util.c:56
+#: plugins/sudoers/toke_util.c:109 plugins/sudoers/toke_util.c:146
+#: plugins/sudoers/visudo.c:153 plugins/sudoers/visudo.c:309
+#: plugins/sudoers/visudo.c:315 plugins/sudoers/visudo.c:446
+#: plugins/sudoers/visudo.c:624 plugins/sudoers/visudo.c:985
+#: plugins/sudoers/visudo.c:1051 plugins/sudoers/visudo.c:1095
+#: plugins/sudoers/visudo.c:1197 plugins/sudoers/visudo_json.c:1025 toke.l:849
+#: toke.l:949 toke.l:1106
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:135
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:68
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "impussibil otignî la classe di login pal utent %s"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+msgid "unable to begin bsd authentication"
+msgstr "impussibil tacâ la autenticazion bsd"
+
+#: plugins/sudoers/auth/bsdauth.c:81
+msgid "invalid authentication type"
+msgstr "gjenar di autenticazion no valit"
+
+#: plugins/sudoers/auth/bsdauth.c:90
+msgid "unable to initialize BSD authentication"
+msgstr "impussibil inizializâ la autenticazion BSD"
+
+#: plugins/sudoers/auth/fwtk.c:52
+msgid "unable to read fwtk config"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to connect to authentication server"
+msgstr "impussibil conetisi al servidôr di autenticazion"
+
+#: plugins/sudoers/auth/fwtk.c:63 plugins/sudoers/auth/fwtk.c:87
+#: plugins/sudoers/auth/fwtk.c:121
+msgid "lost connection to authentication server"
+msgstr "conession pierdude al servidôr di autenticazion"
+
+#: plugins/sudoers/auth/fwtk.c:67
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"erôr dal servidôr di autenticazion:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:111
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:161
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: impussibil analizâ '%s': %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: impussibil assegnâ opzions: %s"
+
+#: plugins/sudoers/auth/kerb5.c:232
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: impussibil otignî credenziâls: %s"
+
+#: plugins/sudoers/auth/kerb5.c:245
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:248
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: impussibil archiviâ la credenziâl te cache: %s"
+
+#: plugins/sudoers/auth/kerb5.c:312
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:326
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Impussibil verificâ TGT! Pussibil atac in vore!: %s"
+
+#: plugins/sudoers/auth/pam.c:108
+msgid "unable to initialize PAM"
+msgstr "impussibil inizializâ PAM"
+
+#: plugins/sudoers/auth/pam.c:194
+msgid "account validation failure, is your account locked?"
+msgstr "validazion account falide, isal blocât?"
+
+#: plugins/sudoers/auth/pam.c:198
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Acount o password scjadude, ristabilìs la password e torne prove"
+
+#: plugins/sudoers/auth/pam.c:206
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "impussibil cambiâ la password scjadude: %s"
+
+#: plugins/sudoers/auth/pam.c:211
+msgid "Password expired, contact your system administrator"
+msgstr "Password scjadude, contatâ l'aministradôr di sisteme"
+
+#: plugins/sudoers/auth/pam.c:215
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:229
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Erôr di autenticazion PAM: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:97 plugins/sudoers/visudo.c:227
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "no tu esistis te base di dâts %s"
+
+#: plugins/sudoers/auth/securid5.c:73
+msgid "failed to initialise the ACE API library"
+msgstr "no si è rivâts a inizializâ la librarie API ACE"
+
+#: plugins/sudoers/auth/securid5.c:99
+msgid "unable to contact the SecurID server"
+msgstr "impussibil contatâ il servidôr SecurID"
+
+#: plugins/sudoers/auth/securid5.c:108
+msgid "User ID locked for SecurID Authentication"
+msgstr "ID utent blocât pe autenticazion SecurID"
+
+#: plugins/sudoers/auth/securid5.c:112 plugins/sudoers/auth/securid5.c:163
+msgid "invalid username length for SecurID"
+msgstr "lungjece dal non utent no valide par SecurID"
+
+#: plugins/sudoers/auth/securid5.c:116 plugins/sudoers/auth/securid5.c:168
+msgid "invalid Authentication Handle for SecurID"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:120
+msgid "SecurID communication failed"
+msgstr "Comunicazion SecurID falide"
+
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:213
+msgid "unknown SecurID error"
+msgstr "erôr SecurID no cognossût"
+
+#: plugins/sudoers/auth/securid5.c:158
+msgid "invalid passcode length for SecurID"
+msgstr "lungjece dal passcode no valide par SecurID"
+
+#: plugins/sudoers/auth/sia.c:69 plugins/sudoers/auth/sia.c:125
+msgid "unable to initialize SIA session"
+msgstr "impussibil inizializâ la session SIA"
+
+#: plugins/sudoers/auth/sudo_auth.c:126
+msgid "invalid authentication methods"
+msgstr "metodis di autenticazion no valits"
+
+#: plugins/sudoers/auth/sudo_auth.c:128
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:224 plugins/sudoers/auth/sudo_auth.c:274
+msgid "no authentication methods"
+msgstr "nissun metodi di autenticazion"
+
+#: plugins/sudoers/auth/sudo_auth.c:226
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:276
+msgid "Unable to initialize authentication methods."
+msgstr "Impussibil inizializâ i metodis di autenticazion."
+
+#: plugins/sudoers/auth/sudo_auth.c:441
+msgid "Authentication methods:"
+msgstr "Metodis di autenticazion:"
+
+#: plugins/sudoers/bsm_audit.c:120 plugins/sudoers/bsm_audit.c:211
+msgid "Could not determine audit condition"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:183 plugins/sudoers/bsm_audit.c:273
+msgid "unable to commit audit record"
+msgstr ""
+
+#: plugins/sudoers/check.c:259
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/check.c:302 plugins/sudoers/check.c:312
+#: plugins/sudoers/sudoers.c:725 plugins/sudoers/sudoers.c:770
+#, c-format
+msgid "unknown uid: %u"
+msgstr "uid no cognossût: %u"
+
+#: plugins/sudoers/check.c:307 plugins/sudoers/iolog.c:260
+#: plugins/sudoers/policy.c:908 plugins/sudoers/sudoers.c:1162
+#: plugins/sudoers/testsudoers.c:208 plugins/sudoers/testsudoers.c:366
+#, c-format
+msgid "unknown user: %s"
+msgstr "utent no cognossût: %s"
+
+#: plugins/sudoers/def_data.c:41
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:45
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:49
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:53
+msgid "Put OTP prompt on its own line"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:57
+msgid "Ignore '.' in $PATH"
+msgstr "Ignore '.' in $PATH"
+
+#: plugins/sudoers/def_data.c:61
+msgid "Always send mail when sudo is run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:65
+msgid "Send mail if user authentication fails"
+msgstr "Invie une mail se la autenticazion dal utent e falìs"
+
+#: plugins/sudoers/def_data.c:69
+msgid "Send mail if the user is not in sudoers"
+msgstr "Invie une mail se l'utent nol è tai sudoers"
+
+#: plugins/sudoers/def_data.c:73
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Invie une mail se l'utent nol è tai sudoers par chest host"
+
+#: plugins/sudoers/def_data.c:77
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Invie une mail se l'utent nol pues eseguî un comant"
+
+#: plugins/sudoers/def_data.c:81
+msgid "Send mail if the user tries to run a command"
+msgstr "Invie une mail se l'utent al cîr di eseguî un comant"
+
+#: plugins/sudoers/def_data.c:85
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:89
+msgid "Lecture user the first time they run sudo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:93
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:97
+msgid "Require users to authenticate by default"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:101
+msgid "Root may run sudo"
+msgstr "L'utent root al pues eseguî sudo"
+
+#: plugins/sudoers/def_data.c:105
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Regjistre il non host tal file di regjistri (no-syslog)"
+
+#: plugins/sudoers/def_data.c:109
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Regjistre l'an tal file di regjistri (no-syslog)"
+
+#: plugins/sudoers/def_data.c:113
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:117
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:121
+msgid "Always set $HOME to the target user's home directory"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:125
+msgid "Allow some information gathering to give useful error messages"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:129
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:133
+msgid "Insult the user when they enter an incorrect password"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:137
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:141
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:145
+msgid "Prompt for root's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:149
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:153
+msgid "Prompt for the target user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:157
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:161
+msgid "Set the LOGNAME and USER environment variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:165
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:169
+msgid "Don't initialize the group vector to that of the target user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:173
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:177
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:181
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:185
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:189
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:193
+#, c-format
+msgid "Path to log file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:197
+#, c-format
+msgid "Path to mail program: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:201
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:205
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:209
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:213
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:217
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:221
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:225
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:229
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:233
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:237
+#, c-format
+msgid "Default password prompt: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:241
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr ""
+
+#: plugins/sudoers/def_data.c:245
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:249
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:253
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:257
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:261
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:265
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:269
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:273
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:277
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:281
+msgid "Allow users to set arbitrary environment variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:285
+msgid "Reset the environment to a default set of variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:289
+msgid "Environment variables to check for sanity:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:293
+msgid "Environment variables to remove:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:297
+msgid "Environment variables to preserve:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:301
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:305
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:309
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:313
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:317
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:321
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:325
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:329
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:333
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:337
+msgid "Log user's input for the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:341
+msgid "Log the output of the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:345
+msgid "Compress I/O logs using zlib"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:349
+msgid "Always run commands in a pseudo-tty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:353
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:357
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:361
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:365
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:369
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:373
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:377
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:381
+msgid "Run commands on a pty in the background"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:385
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "Non dal servizi PAM di doprâ: %s"
+
+#: plugins/sudoers/def_data.c:389
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "Non dal servizi PAM di doprâ pes interfacis di acès: %s"
+
+#: plugins/sudoers/def_data.c:393
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Tentatîf di stabilî lis credentziâls PAM pal utent designât"
+
+#: plugins/sudoers/def_data.c:397
+msgid "Create a new PAM session for the command to run in"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:401
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:405
+msgid "Enable sudoers netgroup support"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:409
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:413
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:417
+msgid "Query the group plugin for unknown system groups"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:421
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:425
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:429
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:433
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:437
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:441
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:445
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:449
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:453
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:457
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:461
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:465
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:469
+msgid "Allow the user to specify a timeout on the command line"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:473
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:477
+msgid "Include the process ID when logging via syslog"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:481
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:485
+#, fuzzy, c-format
+#| msgid "Authentication methods:"
+msgid "Authentication failure message: %s"
+msgstr "Metodis di autenticazion:"
+
+#: plugins/sudoers/defaults.c:221
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:224
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:267
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:270
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:290
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:293
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:318
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:321
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:343
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:346
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:356
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:359
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr ""
+
+#: plugins/sudoers/env.c:295 plugins/sudoers/env.c:302
+#: plugins/sudoers/env.c:407 plugins/sudoers/ldap.c:453
+#: plugins/sudoers/ldap.c:543 plugins/sudoers/ldap.c:1270
+#: plugins/sudoers/ldap.c:1497 plugins/sudoers/ldap.c:1822
+#: plugins/sudoers/linux_audit.c:82 plugins/sudoers/logging.c:1003
+#: plugins/sudoers/policy.c:619 plugins/sudoers/policy.c:629
+#: plugins/sudoers/prompt.c:161 plugins/sudoers/sudoers.c:873
+#: plugins/sudoers/testsudoers.c:238 plugins/sudoers/toke_util.c:158
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "erôr interni, %s overflow (stranfât)"
+
+#: plugins/sudoers/env.c:376
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr ""
+
+#: plugins/sudoers/env.c:1055
+msgid "unable to rebuild the environment"
+msgstr ""
+
+#: plugins/sudoers/env.c:1129
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr ""
+
+#: plugins/sudoers/filedigest.c:104 plugins/sudoers/filedigest_gcrypt.c:66
+#: plugins/sudoers/filedigest_openssl.c:95
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr ""
+
+#: plugins/sudoers/filedigest.c:129 plugins/sudoers/filedigest_gcrypt.c:98
+#: plugins/sudoers/filedigest_openssl.c:120
+#, c-format
+msgid "%s: read error"
+msgstr "%s: erôr di leture"
+
+#: plugins/sudoers/group_plugin.c:86
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:90
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:98 plugins/sudoers/sssd.c:400
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "impussibil cjariâ %s: %s"
+
+#: plugins/sudoers/group_plugin.c:104
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:109
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:79 plugins/sudoers/interfaces.c:96
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:129
+msgid "Local IP address and netmask pairs:\n"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:121 plugins/sudoers/mkdir_parents.c:75
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:146 plugins/sudoers/iolog.c:187
+#: plugins/sudoers/mkdir_parents.c:64 plugins/sudoers/timestamp.c:175
+#, c-format
+msgid "unable to mkdir %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:191 plugins/sudoers/visudo.c:740
+#: plugins/sudoers/visudo.c:750
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:299 plugins/sudoers/sudoers.c:1193
+#: plugins/sudoers/testsudoers.c:390
+#, c-format
+msgid "unknown group: %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:418 plugins/sudoers/sudoers.c:929
+#: plugins/sudoers/sudoreplay.c:349 plugins/sudoers/sudoreplay.c:1355
+#: plugins/sudoers/sudoreplay.c:1559 plugins/sudoers/timestamp.c:406
+#: plugins/sudoers/visudo.c:972 plugins/sudoers/visudo_json.c:1001
+#: plugins/sudoers/visudo_json.c:1014
+#, c-format
+msgid "unable to open %s"
+msgstr "impussibil vierzi %s"
+
+#: plugins/sudoers/iolog.c:469 plugins/sudoers/sudoers.c:933
+#: plugins/sudoers/sudoreplay.c:857 plugins/sudoers/sudoreplay.c:1670
+#, c-format
+msgid "unable to read %s"
+msgstr "impussibil lei %s"
+
+#: plugins/sudoers/iolog.c:505 plugins/sudoers/sudoreplay.c:1124
+#: plugins/sudoers/timestamp.c:295 plugins/sudoers/timestamp.c:298
+#, c-format
+msgid "unable to write to %s"
+msgstr "impussibil scrivi su %s"
+
+#: plugins/sudoers/iolog.c:584 plugins/sudoers/iolog.c:803
+#, c-format
+msgid "unable to create %s"
+msgstr "impussibil creâ %s"
+
+#: plugins/sudoers/iolog.c:1035 plugins/sudoers/iolog.c:1110
+#: plugins/sudoers/iolog.c:1191
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "impussibil scrivi sul file di regjistri I/O: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, file index %d not open"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:431
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:491
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:518
+msgid "unable to mix ldap and ldaps URIs"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:522 plugins/sudoers/ldap.c:559
+msgid "starttls not supported when using ldaps"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:630
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:633
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1256
+msgid "unable to get GMT time"
+msgstr "impussibil otignî la ore GMT"
+
+#: plugins/sudoers/ldap.c:1262
+msgid "unable to format timestamp"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1986
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2559
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2561
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2617
+#, c-format
+msgid " Order: %s\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2625 plugins/sudoers/parse.c:618
+#: plugins/sudoers/sssd.c:1647
+#, c-format
+msgid " Commands:\n"
+msgstr " Comants:\n"
+
+#: plugins/sudoers/ldap.c:3187
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "impussibil inizializâ LDAP: %s"
+
+#: plugins/sudoers/ldap.c:3223
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:3475
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:52
+msgid "unable to open audit system"
+msgstr "impussibil vierzi il sisteme di audit"
+
+#: plugins/sudoers/linux_audit.c:93
+msgid "unable to send audit message"
+msgstr "impussibil inviâ il messaç di audit"
+
+#: plugins/sudoers/logging.c:108
+#, c-format
+msgid "%8s : %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:136
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:165
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "impussibil vierzi il file di regjistri: %s"
+
+#: plugins/sudoers/logging.c:173
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "impussibil blocâ il file di regjistri: %s"
+
+#: plugins/sudoers/logging.c:206
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "impussibil scrivi il file di regjistri: %s"
+
+#: plugins/sudoers/logging.c:235
+msgid "No user or host"
+msgstr "Nissun utent o host"
+
+#: plugins/sudoers/logging.c:237
+msgid "validation failure"
+msgstr "validazion falide"
+
+#: plugins/sudoers/logging.c:244
+msgid "user NOT in sudoers"
+msgstr "l'utent NOL è in sudoers"
+
+#: plugins/sudoers/logging.c:246
+msgid "user NOT authorized on host"
+msgstr "l'utent NOL è autorizât sul host"
+
+#: plugins/sudoers/logging.c:248
+msgid "command not allowed"
+msgstr "comant no permetût"
+
+#: plugins/sudoers/logging.c:283
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s nol è tal file sudoers. Chest incident al vignarà segnalât.\n"
+
+#: plugins/sudoers/logging.c:286
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s nol è permetût eseguî sudo su %s. Chest incident al vignarà segnalât.\n"
+
+#: plugins/sudoers/logging.c:290
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Mi displâs, l'utent %s nol pues eseguî sudo su %s.\n"
+
+#: plugins/sudoers/logging.c:293
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:330 plugins/sudoers/sudoers.c:473
+#: plugins/sudoers/sudoers.c:475 plugins/sudoers/sudoers.c:477
+#: plugins/sudoers/sudoers.c:479 plugins/sudoers/sudoers.c:1298
+#: plugins/sudoers/sudoers.c:1300
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: comant no cjatât"
+
+#: plugins/sudoers/logging.c:332 plugins/sudoers/sudoers.c:469
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+
+#: plugins/sudoers/logging.c:349
+msgid "authentication failure"
+msgstr "autenticazion falide"
+
+#: plugins/sudoers/logging.c:375
+msgid "a password is required"
+msgstr "e covente une password"
+
+#: plugins/sudoers/logging.c:438
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] ""
+msgstr[1] ""
+
+#: plugins/sudoers/logging.c:654
+msgid "unable to fork"
+msgstr "impussibil inglovâ (fâ il fork)"
+
+#: plugins/sudoers/logging.c:662 plugins/sudoers/logging.c:714
+#, c-format
+msgid "unable to fork: %m"
+msgstr "impussibil inglovâ (fâ il fork): %m"
+
+#: plugins/sudoers/logging.c:704
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "impussibil vierzi il condot (pipe): %m"
+
+#: plugins/sudoers/logging.c:729
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "impussibil fâ il \"dup\" di \"stdin\": %m"
+
+#: plugins/sudoers/logging.c:767
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "impussibil eseguî %s: %m"
+
+#: plugins/sudoers/match.c:771
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr ""
+
+#: plugins/sudoers/mkdir_parents.c:70 plugins/sudoers/sudoers.c:944
+#: plugins/sudoers/visudo.c:439 plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to stat %s"
+msgstr ""
+
+#: plugins/sudoers/parse.c:115
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr ""
+
+#: plugins/sudoers/parse.c:118
+#, c-format
+msgid "parse error in %s"
+msgstr ""
+
+#: plugins/sudoers/parse.c:544
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+
+#: plugins/sudoers/parse.c:545
+#, c-format
+msgid " RunAsUsers: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:559
+#, c-format
+msgid " RunAsGroups: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:568
+#, c-format
+msgid " Options: "
+msgstr " Opzions: "
+
+#: plugins/sudoers/policy.c:84 plugins/sudoers/policy.c:110
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:289 plugins/sudoers/testsudoers.c:261
+msgid "unable to parse network address list"
+msgstr ""
+
+#: plugins/sudoers/policy.c:433
+msgid "user name not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:437
+msgid "user ID not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:441
+msgid "group ID not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:445
+msgid "host name not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:793 plugins/sudoers/visudo.c:910
+#, c-format
+msgid "unable to execute %s"
+msgstr "impussibil eseguî %s"
+
+#: plugins/sudoers/policy.c:926
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:928
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:932
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Percors di sudoers: %s\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "percors di nsswitch: %s\n"
+
+#: plugins/sudoers/policy.c:937
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "percors di ldap.conf: %s\n"
+
+#: plugins/sudoers/policy.c:938
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "percors di ldap.secret: %s\n"
+
+#: plugins/sudoers/policy.c:971
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:188 plugins/sudoers/pwutil.c:206
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:200
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:260 plugins/sudoers/pwutil.c:277
+#: plugins/sudoers/pwutil.c:339 plugins/sudoers/pwutil.c:384
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:272
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:503 plugins/sudoers/pwutil.c:521
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:515
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:569 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:633 plugins/sudoers/pwutil.c:675
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:581
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:801 plugins/sudoers/pwutil.c:853
+#: plugins/sudoers/pwutil.c:904 plugins/sudoers/pwutil.c:957
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:807 plugins/sudoers/pwutil.c:858
+#: plugins/sudoers/pwutil.c:910 plugins/sudoers/pwutil.c:962
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:847
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:951
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:113 plugins/sudoers/set_perms.c:469
+#: plugins/sudoers/set_perms.c:912 plugins/sudoers/set_perms.c:1239
+#: plugins/sudoers/set_perms.c:1556
+msgid "perm stack overflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:121 plugins/sudoers/set_perms.c:400
+#: plugins/sudoers/set_perms.c:477 plugins/sudoers/set_perms.c:779
+#: plugins/sudoers/set_perms.c:920 plugins/sudoers/set_perms.c:1163
+#: plugins/sudoers/set_perms.c:1247 plugins/sudoers/set_perms.c:1489
+#: plugins/sudoers/set_perms.c:1564 plugins/sudoers/set_perms.c:1654
+msgid "perm stack underflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:180 plugins/sudoers/set_perms.c:523
+#: plugins/sudoers/set_perms.c:1298 plugins/sudoers/set_perms.c:1596
+msgid "unable to change to root gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:269 plugins/sudoers/set_perms.c:620
+#: plugins/sudoers/set_perms.c:1049 plugins/sudoers/set_perms.c:1375
+msgid "unable to change to runas gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to set runas group vector"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:285 plugins/sudoers/set_perms.c:636
+#: plugins/sudoers/set_perms.c:1063 plugins/sudoers/set_perms.c:1389
+msgid "unable to change to runas uid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:303 plugins/sudoers/set_perms.c:654
+#: plugins/sudoers/set_perms.c:1079 plugins/sudoers/set_perms.c:1405
+msgid "unable to change to sudoers gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1476
+#: plugins/sudoers/set_perms.c:1641
+msgid "too many processes"
+msgstr "masse procès"
+
+#: plugins/sudoers/solaris_audit.c:51
+msgid "unable to get current working directory"
+msgstr "impussibil otignî la cartele di vore atuâl"
+
+#: plugins/sudoers/solaris_audit.c:59
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:66
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:115
+msgid "audit_failure message too long"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:402
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:410 plugins/sudoers/sssd.c:419
+#: plugins/sudoers/sssd.c:428 plugins/sudoers/sssd.c:437
+#: plugins/sudoers/sssd.c:446
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:1562
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: %s\n"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:1567
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: UNKNOWN\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:289
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:307
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:325
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "L'utent %s al pues eseguî su %s i comants chi daurman:\n"
+
+#: plugins/sudoers/sudo_nss.c:338
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "L'utent %s nol pues eseguî sudo su %s.\n"
+
+#: plugins/sudoers/sudoers.c:168 plugins/sudoers/testsudoers.c:247
+#: plugins/sudoers/visudo.c:233 plugins/sudoers/visudo.c:612
+#: plugins/sudoers/visudo.c:976
+msgid "unable to initialize sudoers default values"
+msgstr "impussibil inizializâ i valôrs predefinîts di sudoers"
+
+#: plugins/sudoers/sudoers.c:198 plugins/sudoers/sudoers.c:891
+msgid "problem with defaults entries"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:205
+msgid "no valid sudoers sources found, quitting"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:244
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:301
+msgid "you are not permitted to use the -C option"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:390
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:405
+msgid "no tty"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:406
+msgid "sorry, you must have a tty to run sudo"
+msgstr "mi displâs, si scugne vê un tty par eseguî sudo"
+
+#: plugins/sudoers/sudoers.c:468
+msgid "command in current directory"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:487
+msgid "sorry, you are not allowed set a command timeout"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:495
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:836
+msgid "command too long"
+msgstr "comant masse lunc"
+
+#: plugins/sudoers/sudoers.c:948
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s nol è un file regolâr"
+
+#: plugins/sudoers/sudoers.c:952 plugins/sudoers/timestamp.c:222 toke.l:969
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:956 toke.l:974
+#, c-format
+msgid "%s is world writable"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:960 toke.l:977
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:993
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1012
+#, c-format
+msgid "unknown login class: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1095 plugins/sudoers/sudoers.c:1109
+#, c-format
+msgid "unable to resolve host %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:275
+#, c-format
+msgid "invalid filter option: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:288
+#, c-format
+msgid "invalid max wait: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:300
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:303 plugins/sudoers/visudo.c:186
+#, c-format
+msgid "%s version %s\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:335
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:357
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:555 plugins/sudoers/sudoreplay.c:602
+#: plugins/sudoers/sudoreplay.c:805 plugins/sudoers/sudoreplay.c:895
+#: plugins/sudoers/sudoreplay.c:974 plugins/sudoers/sudoreplay.c:989
+#: plugins/sudoers/sudoreplay.c:996 plugins/sudoers/sudoreplay.c:1003
+#: plugins/sudoers/sudoreplay.c:1010 plugins/sudoers/sudoreplay.c:1017
+#: plugins/sudoers/sudoreplay.c:1163
+msgid "unable to add event to queue"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:670
+msgid "unable to set tty to raw mode"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:721
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:722
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:750
+msgid "Replay finished, press any key to restore the terminal."
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:783
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1197 plugins/sudoers/sudoreplay.c:1222
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1244
+msgid "unmatched ')' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1248
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1263
+#, c-format
+msgid "%s requires an argument"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1266 plugins/sudoers/sudoreplay.c:1646
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1270
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1279
+msgid "unmatched '(' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1281
+msgid "illegal trailing \"or\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1283
+msgid "illegal trailing \"!\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1332
+#, c-format
+msgid "unknown search type %d"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1370
+#, c-format
+msgid "%s: invalid log file"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1388
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1395
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1402
+#, c-format
+msgid "%s: user field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1411
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1420
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1826
+#, c-format
+msgid "usage: %s [-hnR] [-d dir] [-m num] [-s num] ID\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1829
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1838
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1840
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:329
+msgid "\thost unmatched"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:333
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:333
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:230
+#, c-format
+msgid "%s is group writable"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:306
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:772 plugins/sudoers/timestamp.c:839
+#: plugins/sudoers/visudo.c:500 plugins/sudoers/visudo.c:506
+msgid "unable to read the clock"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:786
+msgid "ignoring time stamp from the future"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:798
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:893
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:937 plugins/sudoers/timestamp.c:957
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:188
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:266 plugins/sudoers/visudo.c:667
+#, c-format
+msgid "press return to edit %s: "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:349
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:459 plugins/sudoers/visudo.c:467
+msgid "write error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:513
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:520
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:526
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:548
+#, c-format
+msgid "%s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:607
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr ""
+
+#: plugins/sudoers/visudo.c:619
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:656
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:736 plugins/sudoers/visudo.c:745
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:767
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:781
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:791
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:855
+msgid "What now? "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:869
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:915
+#, c-format
+msgid "unable to run %s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:945
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:952
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:981 plugins/sudoers/visudo_json.c:1021
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:997 plugins/sudoers/visudo_json.c:1032
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1000 plugins/sudoers/visudo_json.c:1035
+#, c-format
+msgid "parse error in %s\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1008 plugins/sudoers/visudo.c:1015
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1062
+#, c-format
+msgid "%s busy, try again later"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1159
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1160
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1164
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1165
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1318
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1433
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1435
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+" -x, --export=output_file write sudoers in JSON format to output_file"
+msgstr ""
+
+#: plugins/sudoers/visudo_json.c:616 plugins/sudoers/visudo_json.c:651
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr ""
+
+#: plugins/sudoers/visudo_json.c:1007
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr ""
+
+#: toke.l:943
+msgid "too many levels of includes"
+msgstr ""
diff --git a/plugins/sudoers/po/hr.mo b/plugins/sudoers/po/hr.mo
new file mode 100644
index 0000000..2af8d49
--- /dev/null
+++ b/plugins/sudoers/po/hr.mo
Binary files differ
diff --git a/plugins/sudoers/po/hr.po b/plugins/sudoers/po/hr.po
new file mode 100644
index 0000000..2ce609e
--- /dev/null
+++ b/plugins/sudoers/po/hr.po
@@ -0,0 +1,2518 @@
+# Translation of sudoers to Croatian.
+# This file is put in the public domain.
+#
+# Božidar Putanec <bozidarp@yahoo.com>, 2016, 2017, 2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers-1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-30 13:22-0700\n"
+"Last-Translator: Božidar Putanec <bozidarp@yahoo.com>\n"
+"Language-Team: Croatian <lokalizacija@linux.hr>\n"
+"Language: hr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Generator: Poedit 2.2\n"
+"X-Poedit-Basepath: ../packages/sudo-1.8.23b2\n"
+"X-Poedit-SearchPath-0: .\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "pogreška u sintaksi"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "Lozinka za %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] lozinka za %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Lozinka: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** SIGURNOSNE informacije za %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Pokušajte ponovo."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336
+#: gram.y:399 gram.y:407 gram.y:417 gram.y:450 gram.y:457 gram.y:464
+#: gram.y:471 gram.y:553 gram.y:560 gram.y:569 gram.y:578 gram.y:595
+#: gram.y:707 gram.y:714 gram.y:721 gram.y:729 gram.y:829 gram.y:836
+#: gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890 gram.y:897
+#: gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:195 plugins/sudoers/logging.c:511
+#: plugins/sudoers/logging.c:532 plugins/sudoers/logging.c:573
+#: plugins/sudoers/logging.c:752 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr "nije moguće dodijeliti memoriju"
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr "kontrolni zbroj zahtijeva ime staze"
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr "nevaljana „notbefore“ vrijednost"
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr "nevaljana „notafter“ vrijednost"
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr "vrijednost za istek vremena je prevelika"
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr "nevaljana vrijednost za istek vremena"
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:354 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:511 plugins/sudoers/logging.c:532
+#: plugins/sudoers/logging.c:572 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:724 plugins/sudoers/match.c:771
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1008
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Alias „%s“ je već definirani"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "nije moguće dobiti razred klasu korisnika %s"
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr "nije moguće početi s BSD autentifikacijom"
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr "nevaljana vrsta autentifikacije"
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr "nije moguće inicijalizirati BSD autentifikaciju"
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr "vaš račun nije valjan, istekao je"
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr "odobrenje nije uspjelo"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr "nije moguće pročitati konfiguraciju FWTK"
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr "nije moguće spojiti se na autentifikacijski poslužitelj"
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr "veza s autentifikacijskim poslužiteljem je prekinuta (izgubljena)"
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"greška autentifikacijskoga poslužitelja:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: nije moguće pretvoriti principala u string („%s“): %s"
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: nije moguće raščlaniti „%s“: %s"
+
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: nije moguće naći verifikacijsku predmemoriju: %s"
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: nije moguće dodijeliti opcije: %s"
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: nije moguće dobiti verifikaciju: %s"
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: nije moguće inicijalizirati verifikacijsku predmemoriju: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: nije moguće spremiti verifikaciju u predmemoriju: %s"
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: nije moguće dobiti principala: %s"
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Nije moguće provjeriti TGT! Mogući napad!: %s"
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr "nije moguće inicijalizirati PAM"
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Greška PAM autentifikacije: %s"
+
+#: plugins/sudoers/auth/pam.c:221
+msgid "account validation failure, is your account locked?"
+msgstr "provjera valjanosti računa nije uspjela, je li vaš račun zaključan?"
+
+#: plugins/sudoers/auth/pam.c:229
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Račun ili lozinka su istekli, postavite novu lozinku i pokušajte ponovo"
+
+#: plugins/sudoers/auth/pam.c:238
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "nije moguće promijeniti zastarjelu lozinku: %s"
+
+#: plugins/sudoers/auth/pam.c:246
+msgid "Password expired, contact your system administrator"
+msgstr "Lozinka je istekla, javite se vašem administratoru sustava"
+
+#: plugins/sudoers/auth/pam.c:250
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Račun je istekao ili PAM konfiguracija nema sekciju „account“ za sudo, javite se vašem administratoru sustava"
+
+#: plugins/sudoers/auth/pam.c:257 plugins/sudoers/auth/pam.c:262
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "Pogreška u upravljanju PAM računom: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:232
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "vas nema u %s bazi podataka"
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr "nije uspjelo inicijalizirati ACE API biblioteku"
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr "nije moguće uspostaviti vezu sa SecurID poslužiteljem"
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr "Korisnikov ID je zaključan prilikom SecurID autentifikacije"
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr "nevaljana duljina imena korisnika za SecurID"
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr "nevaljani autentifikacijski token za SecurID"
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr "SecurID komunikacija nije uspjela"
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr "nepoznata SecurID greška"
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr "nevaljana duljina lozinke za SecurID"
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr "nije moguće inicijalizirati SIA sesiju"
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr "nevaljane metode autentifikacije"
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Nevaljane metode autentifikacije su ugrađene u sudo! Ne smijete miješati samostalne i nesamostalne autentifikacije."
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr "nema metoda autentifikacije"
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Metode autentifikacije nisu ugrađene u sudo! Ako želite isključiti autentifikaciju, koristite konfiguracijsku opciju --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr "Nije moguće inicijalizirati metode autentifikacije."
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr "Metode autentifikacije:"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr "Nije bilo moguće odrediti uvjete za reviziju"
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr "revizijski izvještaj nije bilo moguće zapisati na disk"
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Vjerujemo da vam je administrator lokalnog sustava održao uobičajeno\n"
+"predavanje. To se obično svodi na sljedeće tri stvari:\n"
+"\n"
+" #1) Poštujte tuđu privatnost.\n"
+" #2) Mislite prije tipkanja.\n"
+" #3) S velikim moćima dolazi velika odgovornost.\n"
+"\n"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr "nepoznati UID: %u"
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1136
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr "nepoznati korisnik: %s"
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "inkrement redoslijeda (order): %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "početni redoslijed (order): %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr "popuna redoslijeda (order): %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s inačica %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s inačica gramatike %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr "nepodržani ulazni formata %s"
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr "nepodržani izlazni formata %s"
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: ulazna i izlazna datoteka moraju biti različite datoteke"
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:238
+#: plugins/sudoers/visudo.c:594 plugins/sudoers/visudo.c:917
+msgid "unable to initialize sudoers default values"
+msgstr "nije moguće inicijalizirati zadane vrijednosti sudoers"
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: nepoznata ključna riječ: %s"
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "nevaljane zadane vrste: %s"
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "nevaljana vrsta za izostavljanje: %s"
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr "nevaljani filtar: %s"
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:913
+#, c-format
+msgid "unable to open %s"
+msgstr "nije moguće otvoriti %s"
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:922
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "nije uspjelo raščlaniti %s datoteku, nepoznata greška"
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:939
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "greška u raščlambi u %s blizu retka %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:942
+#, c-format
+msgid "parse error in %s\n"
+msgstr "greška u raščlambi u %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr "nije moguće pisati u %s"
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s - pretvara formate sudoers datoteka\n"
+"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Opcije:\n"
+" -b, --base=dn osnovni DN za sudo LDAP upite\n"
+" -d, --defaults=deftypes pretvori samo Defaults od specificiranih deftypes\n"
+" -e, --expand-aliases proširuje aliase kada pretvara\n"
+" -f, --output-format=format izlazni format jedan od: JSON, LDIF ili sudoers\n"
+" -i, --input-format=format ulazni format jedan od: LDIF ili sudoers\n"
+" -I, --increment=num inkrement za num svaki sudoOrder\n"
+" -h, --help pokaže ovu pomoć i završi\n"
+" -m, --match=filter pretvori samo stavke koje podudaraju filter\n"
+" -M, --match-local filter rabi passwd i group baze podataka\n"
+" -o, --output=output_file pretvoreni sudoers zapiše u output_file\n"
+" -O, --order-start=num prvi sudoOrder započinje od num\n"
+" -p, --prune-matches izreže nepodudarne korisnike, grupe i računala\n"
+" -P, --padding=num osnovna popuna za sudoOrder inkrement\n"
+" -s, --suppress=sections izostavi izlaz od sections sekcija\n"
+" -V, --version informira o inačici ovog programa i završi"
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "nepoznati unos defaults „%s“"
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr "nije moguće dobiti GMT vrijeme"
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr "nije moguće oblikovati vremensku oznaku"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1015 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "**interna greška**, %s prelijevanje"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr "previše sudoers grešaka, maksimum je %u"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "varijabla okoline SUDOERS_BASE nije postavljena i -b opcija nije specificirana."
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Alat za bilježenje ako se syslog koristi za pisanje dnevnika: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Pri uspješnoj autentifikaciji korisnika rabi se syslog prioritet: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Pri neuspješnoj autentifikaciji korisnika rabi se syslog prioritet: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "Postavite OTP (One-Time-Password) prompt u zasebni, vlastiti redak"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "Ignorira se „.“ u $PATH"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "Poštu poslati kad god se pokrene sudo"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "Poštu poslati ako autentifikacija korisnika nije uspjela"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "Poštu poslati ako korisnik nije u sudoers"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Poštu poslati ako korisnik nije u sudoers na ovom računalu"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Poštu poslati ako korisnik nema dopuštenje za pokretanje naredbe"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "Poštu poslati ako korisnik pokušava unositi naredbe"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Za svaku kombinaciju korisnik/terminal koristi se zasebna vremenska oznaka"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "Korisnika podučiti prilikom prvog pokretanja sudo"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Datoteka koja sadrži sudo poduku: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "Po zadanim postavkama zahtijeva se autentifikacija korisnika"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "Root smije pokrenuti sudo"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Ime računala zapiše se u (ne-syslog) dnevničku datoteku"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Godina se zapiše u (ne-syslog) dnevničku datoteku"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Ako se sudo pozove bez argumenata, pokrene se ljuska"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Postavlja $HOME na ciljanoga korisnika pri pokretanju ljuske s opcijom -s"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Uvijek postavlja $HOME na osobni direktorij ciljanoga korisnika"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Dopušteno je prikupljanje informacija za ispis korisnih poruka o greškama"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Datoteka sudoers zahtjeva potpuno kvalificirana (fully-qualified) imena računala"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Korisnika izgrditi ako upiše netočnu lozinku"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Korisniku dopustiti pokretanje sudo samo ako ima tty"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo poštuje varijablu okoline EDITOR"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "Zatražiti root lozinku umjesto lozinke korisnika"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Zatražiti lozinku runas_default korisnika a ne lozinku trenutačnoga korisnika"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Zatražiti lozinku ciljanoga korisnika a ne lozinku trenutačnoga korisnika"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Ako postoje, primijeniti zadane vrijednosti iz login klase ciljanoga korisnika"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Postavlja varijable okoline LOGNAME i USER"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Postavlja samo efektivni UID na onaj ciljanoga korisnika umjesto stvarnog UID"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Ne inicijalizirati grupni vektor na onaj od ciljanoga korisnika"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Pozicija na kojoj se prelamaju redci dnevničke datoteke (0, bez prelamanja): %u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Istek vremena za vremensku oznaku autentifikacije: %.1f minuta"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Istek vremena za unos lozinke: %.1f minuta"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Broj pokušaja unosa lozinke: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Umask za korištenje ili 0777 za korisničku: 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Staza do dnevničke datoteke: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Staza do programa pošte: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Zastavice za program pošte: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Adresa na koju se šalje pošta: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Adresa s koje se šalje pošta: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Redak za upis predmeta (subject) poštanskih poruka: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Poruka za netočnu lozinku: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Staza do direktorija s lekcijom: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Staza do direktorija s vremenskim oznakama autentifikacije: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Vlasnik direktorija s vremenskim oznakama autentifikacije: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Korisnici u ovoj grupi su izuzeti od zahtjeva za unos lozinke i PATH: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Zadani zahtjev (prompt) za lozinku: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Ako je postavljen, passprompt će zamijeniti prompt sustava u svim slučajevima."
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Zadani korisnik za pokretanje naredbi: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Vrijednost s kojom se zamijeni korisnikov $PATH: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Staza do uređivača koji će koristiti visudo: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Kada zatražiti lozinku za pseudonaredbu „list“: %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Kada zatražiti lozinku za pseudonaredbu „verify“: %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Prethodno učitati prividne izvršne funkcije sadržane u biblioteci sudo_noexec"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Ako je dostupni LDAP direktorij, zanemaruje li se lokalna sudoers datoteka"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Deskriptori datoteka >= %d biti će zatvoreni prije izvršavanja naredbe"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Ako je postavljena, korisnici mogu zamijeniti vrijednost „closeform“ s opcijom -C"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Korisnici mogu postaviti bilo koje varijable okoline"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "Okolinu vratiti u zadani skup varijabli okoline"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "Varijable okoline čije „zdravlje“ treba ispitati:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "Varijable okoline koje treba ukloniti:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "Varijable okoline koje treba sačuvati:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "SELinux uloga za korištenje u novom sigurnosnom kontekstu: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "SELinux vrsta za korištenje u novom sigurnosnom kontekstu: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Staza do datoteke okoline specifične za sudo: %s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Staza do datoteke okoline s ograničenim pristupom specifične za sudo: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Locale za korištenje pri obradi sudoers: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Dopustiti da sudo zatraži lozinku čak i ako će biti vidljiva"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Vizualno pokazati rezultat nakon unosa lozinke korisnikom"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Rabi se brže i manje precizno podudaranje ali nema dostupa datotečnom sustavu"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "U sudoers specificirani umask zamijeniti će korisnički čak i ako je tolerantniji"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "Urudžbirati korisnikom pokrenute naredbe"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "Urudžbirati izlaz pokrenute naredbe"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "U/I urudžbirane dnevnike komprimirati s programom zlib"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "Naredbe uvijek pokrenuti u pseudo-TTY"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Plugin za podršku za ne-Unix grupe: %s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Direktorij u kojem se spremaju ulazno/izlazni dnevnici: %s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Datoteka u koju se sprema ulazno/izlazni dnevnik: %s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Dodati stavku u utmp/utmpx datoteku pri dodijeli pseudoterminala"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Postaviti korisnika u utmp na runas-korisnika umjesto na pozivatelja"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Skup dopuštenih privilegija: %s"
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Skup limitiranih privilegija: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "Pokrenuti naredbe na pseudoterminalu u pozadini"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "Naziv PAM usluge za upotrebu: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "Naziv PAM usluge za upotrebu za prijavnu ljusku: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Pokušaj da se uspostavi PAM verifikacija za ciljanoga korisnika"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "Kreira novu PAM sesiju za izvršavanje naredbe"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Maksimalni redni broj U/I dnevnika: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "Omogućite podršku mrežnih grupa (netgroup) u sudoers"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Provjerite mogućnost pisanja u naddirektorijima kad se koristi sudoedit za uređivanje"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Slijedi simboličke veze kad se koristi sudoedit za uređivanje datoteka"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "Ispituje plugin grupe za nepoznate sustavske grupe"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Podudaranje mrežnih grupa bazira se na kompletnoj n-torki: korisnik, računalo, domena"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Naredbe je dopušteno izvršiti iako ih sudo ne može upisati u revizijski dnevnik"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Naredbe je dopušteno izvršiti iako ih sudo ne može upisati u U/I dnevnik"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Naredbe je dopušteno izvršiti iako ih sudo ne može upisati u dnevnik"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Razriješi grupe u sudoers i podudari ih po ID grupe umjesto po imenu grupe"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Dnevničke stavke veće od ove vrijednosti podijeliti će se u više syslog poruka: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Korisnik koji će biti vlasnik U/I dnevnika: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Grupa koja će biti vlasnik U/I dnevnika: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Prava pristupa za uporabu za U/I dnevnike: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Izvrši naredbe pomoću deskriptora datoteke umjesto staze: %s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Nepoznati zadani podaci za sudoers se ignoriraju umjesto ispisa upozorenja"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Vrijeme u sekundama nakon kojeg se naredba prekida: %u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Dopustite korisniku da specificira istek vremena na komandnom retku"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "U/I dnevnik ispisivati direktno na disk umjesto preko međuspremnika"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "U syslog dnevnik upisivati i ID procesa"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Vrsta zapisa autentifikacijskih vremenskih oznaka: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "Greška u provjeri autentičnosti: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "Ignorira se veličina slova kad se uspoređuju imena korisnika"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "Ignorira se veličinu slova kada se uspoređuju imena grupa"
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d nepoznata stavka zadanih vrijednosti „%s“"
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: nepoznata stavka zadanih vrijednosti „%s“"
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d nije navedena vrijednost za „%s“"
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: nije navedena vrijednost za „%s“"
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d vrijednost za „%s“ mora početi s „/“"
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: vrijednost za „%s“ mora početi s „/“"
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d opcija „%s“ ne prihvaća vrijednost"
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: opcija „%s“ ne prihvaća vrijednost"
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d nevaljana zadana vrsta 0x%x za opciju „%s“"
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: nevaljana Defaults vrsta 0x%x za opciju „%s“"
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d vrijednost „%s“ nije ispravna za opciju „%s“"
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: vrijednost „%s“ nije ispravna za opciju „%s“"
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: oštećen envp, duljina ne odgovara"
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr "nije moguće obnoviti okolinu"
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "nemate dopuštenje za postavljanje sljedećih varijabli okoline: %s"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "greška u raščlambi u %s blizu retka %d"
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "greška u raščlambi u %s"
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "nepodržana vrsta kontrolnog zbroja %d za %s"
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr "%s: greška čitanja"
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "vlasnik %s mora biti UID %d"
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s mora biti dostupan za pisanje samo vlasniku"
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "nije moguće učitati %s: %s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "nije moguće pronaći simbol „group_plugin“ u %s"
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: nekompatibilna glavna inačica plugin grupe %d, očekivano je %d"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "„%s“ nije valjana IP adresa (nemoguće ju je raščlaniti)"
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "„%s“ nije valjana mrežna maska (nemoguće ju je raščlaniti)"
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Parovi lokalnih IP adresa i mrežnih maski:\n"
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s postoji, ali nije direktorij (0%o)"
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "nije moguće napraviti direktorij %s"
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:723
+#: plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "nije moguće promijeniti mȏd od %s na 0%o"
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1167
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr "nepoznata grupa: %s"
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr "nije moguće pročitati %s"
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr "nije moguće stvoriti %s"
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "nije moguće pisati u U/I dnevnik: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr "%s: interna greška, U/I dnevnička datoteka za događaj %d nije otvorena"
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr "%s: interna greška, nevaljani signal %d"
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: nevaljana dnevnička datoteka"
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: nedostaje polje za vremensku oznaku"
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: vremenska oznaka %s: %s"
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: nedostaje polje za korisnika"
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: nedostaje polje za runas-korisnika"
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: nedostaje polje za runas-grupe"
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr "starttls nije podržan kad se koristi ldaps"
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "nije moguće inicijalizirati SSL certifikat i bazu podataka ključeva: %s"
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "morate postaviti TLS_CERT u %s da koristite SSL"
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "nije moguće inicijalizirati LDAP: %s"
+
+#: plugins/sudoers/ldap.c:1648
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls je specificirani, ali LDAP biblioteke ne podržavaju ldap_start_tls_s() ili ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "nevaljani sudoOrder atribut: %s"
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: port vrijednost je prevelika"
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "nepodržana vrsta adrese LDAP: %s"
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "ne možete zajedno koristiti ldap i ldaps adrese"
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "nije moguće pretvoriti sudoOption: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "nije moguće otvoriti sustav revizije"
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr "nije moguće poslati revizijsku poruku"
+
+#: plugins/sudoers/logging.c:113
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:141
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (naredba se nastavlja) %s"
+
+#: plugins/sudoers/logging.c:170
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "nije moguće otvoriti dnevničku datoteku: %s"
+
+#: plugins/sudoers/logging.c:178
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "nije moguće zaključati dnevničku datoteku: %s"
+
+#: plugins/sudoers/logging.c:211
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "nije moguće pisati u dnevničku datoteku: %s"
+
+#: plugins/sudoers/logging.c:240
+msgid "No user or host"
+msgstr "Nema korisnika ili računala"
+
+#: plugins/sudoers/logging.c:242
+msgid "validation failure"
+msgstr "greška pri provjeri valjanosti"
+
+#: plugins/sudoers/logging.c:249
+msgid "user NOT in sudoers"
+msgstr "korisnik NIJE u sudoers"
+
+# Authentication is about who somebody is.
+# Authorisation is about what they're allowed to do.
+# https://en.wikipedia.org/wiki/AAA_(computer_security)#Authorization
+#: plugins/sudoers/logging.c:251
+msgid "user NOT authorized on host"
+msgstr "korisnik NEMA ovlasti na računalu (nije autoriziran)"
+
+#: plugins/sudoers/logging.c:253
+msgid "command not allowed"
+msgstr "naredba nije dopuštena"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s nije u sudoers datoteci. Ovaj će incident biti prijavljen.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr ""
+"%s nema dopuštenja pokrenuti sudo na %s. Ovaj će incident biti prijavljen.\n"
+"\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Nažalost, korisnik %s ne smije pokrenuti sudo na %s.\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Nažalost, korisniku %s nije dopušteno izvršiti „%s%s%s“ kao %s%s%s na %s.\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: naredba nije pronađena"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"zanemaruje se „%s“ pronađen u „.“\n"
+"Koristite „sudo ./%s“ ako je to „%s“ koji želite pokrenuti."
+
+#: plugins/sudoers/logging.c:354
+msgid "authentication failure"
+msgstr "neuspješna autentifikacija"
+
+#: plugins/sudoers/logging.c:380
+msgid "a password is required"
+msgstr "nužna je lozinka"
+
+#: plugins/sudoers/logging.c:443
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u netočni pokušaj unosa lozinke"
+msgstr[1] "%u netočna pokušaja unosa lozinke"
+msgstr[2] "%u netočnih pokušaja unosa lozinke"
+
+#: plugins/sudoers/logging.c:666
+msgid "unable to fork"
+msgstr "nije moguće stvoriti novi proces (greška u fork())"
+
+#: plugins/sudoers/logging.c:674 plugins/sudoers/logging.c:726
+#, c-format
+msgid "unable to fork: %m"
+msgstr "nije moguće stvoriti novi proces (greška u fork()): %m"
+
+#: plugins/sudoers/logging.c:716
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "nije moguće otvoriti cijev: %m"
+
+#: plugins/sudoers/logging.c:741
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "nije moguće duplicirati stdin: %m"
+
+#: plugins/sudoers/logging.c:779
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "nije moguće izvršiti %s: %m"
+
+#: plugins/sudoers/match.c:874
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "kontrolni zbroj za %s (%s) nije u %s obliku"
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:421 plugins/sudoers/visudo.c:717
+#, c-format
+msgid "unable to stat %s"
+msgstr "nije moguće dobiti status od %s"
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"LDAP uloga: %s\n"
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Sudoers stavka:\n"
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr " RunAsUsers: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr " RunAsGroups: "
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr " Opcije: "
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr " Naredbe:\n"
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Odgovarajući Defaults unosi za %s na %s:\n"
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Runas i Command-specifične zadane vrijednosti za %s:\n"
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Korisnik %s može pokrenuti sljedeće naredbe na %s:\n"
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Korisniku %s nije dopušteno pokrenuti sudo na %s.\n"
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "ignorira se nevaljana vrijednost atributa: %s"
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "ignorira se nekompletni sudoRole: cn: %s"
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "nevaljana opcija %.*s postavljena kroz sudo front-end"
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr "nije moguće pročitati popis mrežnih adresa (nemoguće ih je raščlaniti)"
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr "sudo front-end nije postavio ime korisnika"
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr "sudo front-end nije postavio ID korisnika"
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr "sudo front-end nije postavio ID grupe"
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr "sudo front-end nije postavio ime računala"
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:220
+#: plugins/sudoers/visudo.c:851
+#, c-format
+msgid "unable to execute %s"
+msgstr "nije moguće izvršiti %s"
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Inačica sudoers plugina s pravilima %s\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Inačica sudoers datotečne gramatike %d\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Staza do sudoers: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "nsswitch staza: %s\n"
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "ldap.conf staza: %s\n"
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "ldap.secret staza: %s\n"
+
+# hook: A location in a routine or program in which the programmer can connect or insert other routines for the purpose of debugging or enhancing functionality.
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "nije moguće registrirati rutinu (hook) vrste %d (inačica %d.%d)"
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "nije moguće predmemorirati UID %u jer nema dovoljno memorije"
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "nije moguće predmemorirati UID %u jer već postoji"
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "nije moguće predmemorirati korisnika %s jer nema dovoljno memorije"
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "nije moguće predmemorirati korisnika %s jer već postoji"
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "nije moguće predmemorirati GID %u jer nema dovoljno memorije"
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "nije moguće predmemorirati GID %u jer već postoji"
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "nije moguće predmemorirati grupu %s jer nema dovoljno memorije"
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "nije moguće predmemorirati grupu %s jer već postoji"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "nije moguće predmemorirati popis grupa za %s jer već postoji"
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "nije moguće predmemorirati popis grupa za %s jer nema dovoljno memorije"
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "nije moguće pročitati grupe za %s"
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "nije moguće razabrati GID-ove za %s"
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr "prelijevanje snopa s pravima pristupa"
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr "iscrpljenje snopa s pravima pristupa"
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr "nije moguće promijeniti na GID od root"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr "nije moguće promijeniti na runas GID"
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr "nije moguće postaviti runas grupni vektor"
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr "nije moguće promijeniti na runas UID"
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr "nije moguće promijeniti na sudoers GID"
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr "previše procesa"
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr "nije moguće odrediti trenutačni radni direktorij"
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "skraćena (audit) staza revizije user_cmd: %s"
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "skraćena (audit) staza revizije argv[0]: %s"
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr "audit_failure poruka (revizije) je preduga"
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "nije moguće inicijalizirati SSS izvor. Je li SSSD instaliran na vašem računalu?"
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "nije moguće pronaći simbol „%s“ u %s"
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr "problem sa stavkama defaults"
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr "nisu pronađeni valjani sudoers izvori, kraj rada"
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers specificira da root ne može koristiti sudo"
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr "vama nije dopušteno koristi opciju -C"
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "vlasnik vremenske oznake (%s): Nema takvog korisnika"
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr "nema TTY"
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr "nažalost, da pokrenete sudo morate imati TTY"
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr "naredba u trenutačnom direktoriju"
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "nažalost, vama nije dopušteno postavljanje isteka vremena za naredbu"
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "nažalost, vama nije dopušteno sačuvati okolinu"
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr "naredba je preduga"
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s nije obična datoteka"
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "vlasnik %s je UID %u, a treba biti %u"
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr "%s smije svako mijenjati/pisati"
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "vlasnik %s je GID %u, a treba biti %u"
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "samo root može koristiti „-c %s“"
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr "nepoznata klasa prijave: %s"
+
+#: plugins/sudoers/sudoers.c:1069 plugins/sudoers/sudoers.c:1083
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "nije moguće pronaći računalo %s"
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "nevaljana opcija filtra: %s"
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "nevaljano maksimalno vrijeme čekanja: %s"
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "nevaljani faktor brzine: %s"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/vrijeme: %s"
+
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/vrijeme: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Reproduciranje sudo sesije: %s"
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr "nije moguće dodati događaj u red čekanja"
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr "nije moguće postaviti TTY u direktni mȏd (da ne interpretira posebne znakove)"
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Upozorenje: vaš terminal je premaleni da pravilno reproducira dnevnik.\n"
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Veličina dnevnika je %d x %d, a veličina vašeg terminala %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Reprodukcija je završena -- obnovite terminal pritiskom na bilo koju tipku."
+
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "nevaljani redak u timing datoteci: %s"
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "dvosmisleni izraz „%s“"
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr "nesparena „)“ u izrazu"
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "nepoznati pojam za pretragu „%s“"
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s zahtijeva argument"
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "nevaljani regularni izraz: %s"
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "nije moguće raščlaniti datum „%s“"
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr "nesparena „(“ u izrazu"
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr "nedopušteni zaostali „or“"
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr "nedopušteni zaostali „!“"
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr "nepoznata vrsta za pretragu %d"
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr "uporaba: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "uporaba: %s [-h] [-d direktorij] -l [izraz za pretragu]\n"
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - reproducira dnevnike sudo sesija\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Options:\n"
+" -d, --directory=dir navedite direktorij dir za dnevnike sesija\n"
+" -f, --filter=filter navedite (filter) vrstu/vrste U/I koje treba prikazati\n"
+" -h, --help pokaže ovu pomoć i iziđe\n"
+" -l, --list popis dostupnih ID-ova sjednica koji se podudaraju\n"
+" s neobveznim izrazom za pretragu\n"
+" -m, --max-wait=num čekati ne više od num sekundi između događaja\n"
+" -S, --suspend-wait čeka dok je naredba obustavljena\n"
+" -s, --speed=num ubrza ili uspori reprodukciju\n"
+" -V, --version informira o inačici ovog programa i iziđe"
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr "\tračunalo se ne podudara"
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Naredba je dopuštena"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Naredba nije dopuštena"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Naredba nije prepoznata"
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr "%s članovi grupe mogu mijenjati/pisati"
+
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "nije moguće skratiti datoteku s vremenskim podacima na %lld bajtova"
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:482 plugins/sudoers/visudo.c:488
+msgid "unable to read the clock"
+msgstr "nije moguće pročitati vrijeme (clock)"
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr "ignorira se vremenska oznaka iz budućnosti"
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "vremenska oznaka je predaleko u budućnosti: %20.20s"
+
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "nije moguće zaključati datoteku s vremenskim oznakama %s"
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "staza do lekcije je preduga: %s/%s"
+
+#: plugins/sudoers/visudo.c:216
+msgid "the -x option will be removed in a future release"
+msgstr "opcija -x biti će uklonjena iz buduće inačice"
+
+#: plugins/sudoers/visudo.c:217
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "molimo da umjesto toga pokušate rabiti cvtsudoers uslužni program"
+
+#: plugins/sudoers/visudo.c:268 plugins/sudoers/visudo.c:650
+#, c-format
+msgid "press return to edit %s: "
+msgstr "pritisnite return/enter za redigirati %s: "
+
+#: plugins/sudoers/visudo.c:329
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "navedeni uređivač (%s) ne postoji"
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "nijedan uređivač nije pronađen (editor path = %s)"
+
+#: plugins/sudoers/visudo.c:441 plugins/sudoers/visudo.c:449
+msgid "write error"
+msgstr "greška pisanja"
+
+#: plugins/sudoers/visudo.c:495
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "nije moguće dobiti status privremene datoteke (%s), %s nije promijenjena"
+
+#: plugins/sudoers/visudo.c:502
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "privremena datoteka duljine nula (%s), %s nije promijenjena"
+
+#: plugins/sudoers/visudo.c:508
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "greška uređivač (%s), %s nije promijenjena"
+
+#: plugins/sudoers/visudo.c:530
+#, c-format
+msgid "%s unchanged"
+msgstr "%s nije promijenjeno"
+
+#: plugins/sudoers/visudo.c:589
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "nije moguće ponovo otvoriti privremenu datoteku (%s), %s nije promijenjena."
+
+#: plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "nije moguće raščlaniti privremenu datoteku (%s), nepoznata greška"
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "**interna greška**, nije moguće pronaći %s na popisu!"
+
+#: plugins/sudoers/visudo.c:719 plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "nije moguće postaviti (UID, GID) od %s na (%u, %u)"
+
+#: plugins/sudoers/visudo.c:751
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s i %s nisu na istom datotečnom sustavu, koristi se mv za preimenovanje"
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "naredba nije uspjela: „%s %s %s“, %s nije promijenjena"
+
+#: plugins/sudoers/visudo.c:775
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "greška u preimenovanju %s, %s nije promijenjena"
+
+#: plugins/sudoers/visudo.c:796
+msgid "What now? "
+msgstr "Što sada? "
+
+#: plugins/sudoers/visudo.c:810
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Mogućnosti su:\n"
+" (e) datoteku sudoers ponovno redigirati\n"
+" (x) završiti bez spremanja promjena u datoteku sudoers)\n"
+" (Q) prekinuti i spremiti promjene u datoteku sudoers (OPASNO!)\n"
+
+#: plugins/sudoers/visudo.c:856
+#, c-format
+msgid "unable to run %s"
+msgstr "nije moguće pokrenuti %s"
+
+#: plugins/sudoers/visudo.c:886
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: krivi vlasnik (UID, GID) a treba biti (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: loša prava pristupa, trebala bi biti 0%o\n"
+
+#: plugins/sudoers/visudo.c:950 plugins/sudoers/visudo.c:957
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: raščlamba je uspjela\n"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s je zauzeti, pokušajte ponovo kasnije"
+
+#: plugins/sudoers/visudo.c:979
+#, c-format
+msgid "unable to lock %s"
+msgstr "nije moguće zaključati %s"
+
+#: plugins/sudoers/visudo.c:980
+msgid "Edit anyway? [y/N]"
+msgstr "Ipak redigirati? [y/N]"
+
+#: plugins/sudoers/visudo.c:1064
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Greška: %s:%d ciklus u %s „%s“"
+
+#: plugins/sudoers/visudo.c:1065
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Upozorenje: %s:%d ciklus u %s „%s“"
+
+#: plugins/sudoers/visudo.c:1069
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Greška: %s:%d %s „%s“ se koristi ali nije definirano"
+
+#: plugins/sudoers/visudo.c:1070
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Upozorenje: %s:%d %s „%s“ se koristi ali nije definirano"
+
+#: plugins/sudoers/visudo.c:1161
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Upozorenje: %s:%d neupotrijebljeno %s „%s“"
+
+#: plugins/sudoers/visudo.c:1276
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - sigurno redigira sudoers datoteku\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1278
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"Opcije:\n"
+" -c, --check samo testira sudoers datoteku\n"
+" -f, --file=sudoers navedite alternativnu lokaciju sudoers datoteke\n"
+" -h, --help pokaže ovu pomoć i iziđe\n"
+" -q, --quite manje opširne (tihe) poruke grešaka u sintaksi\n"
+" -s, --strick striktna testira sintaksu sudoers datoteke\n"
+" -V, --version informira o inačici ovog programa i iziđe\n"
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr "previše razina uključivanja"
+
+#~ msgid ""
+#~ "\n"
+#~ "LDAP Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "LDAP uloga: NEPOZNATA\n"
+
+#~ msgid " Order: %s\n"
+#~ msgstr " Redoslijed: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: %s\n"
+#~ msgstr ""
+#~ "\n"
+#~ "SSSD uloga: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "SSSD uloga: NEPOZNATA\n"
+
+#~ msgid "Warning: cycle in %s `%s'"
+#~ msgstr "Upozorenje: ciklus u %s „%s“"
+
+#~ msgid "Warning: %s `%s' referenced but not defined"
+#~ msgstr "Upozorenje: %s „%s“ ima referenciju ali nije definiran"
+
+#~ msgid "Warning: unused %s `%s'"
+#~ msgstr "Upozorenje: %s „%s“ nije upotrebljen"
+
+#~ msgid "Password:"
+#~ msgstr "Lozinka:"
+
+#~ msgid "unable to setup authentication"
+#~ msgstr "ne mogu postaviti provjeru"
+
+#~ msgid "pam_chauthtok: %s"
+#~ msgstr "pam_chauthtok: %s"
+
+#~ msgid "pam_authenticate: %s"
+#~ msgstr "pam_authenticate: %s"
+
+#~ msgid "getaudit: failed"
+#~ msgstr "getaudit: nije uspio"
+
+#~ msgid "getauid failed"
+#~ msgstr "getauid nije uspio"
+
+#~ msgid "au_to_subject: failed"
+#~ msgstr "au_to_subject: nije uspio"
+
+#~ msgid "au_to_exec_args: failed"
+#~ msgstr "au_to_exec_args: nije uspio"
+
+#~ msgid "au_to_return32: failed"
+#~ msgstr "au_to_return32: nije uspio"
+
+#~ msgid "getauid: failed"
+#~ msgstr "getauid: nije uspio"
+
+#~ msgid "au_to_text: failed"
+#~ msgstr "au_to_text: nije uspio"
+
+#~ msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+#~ msgstr "sudo_ldap_conf_add_ports: nema dovoljno prostora za proširenje međuspremnika računala"
+
+#~ msgid "invalid uri: %s"
+#~ msgstr "neispravan uri: %s"
+
+#~ msgid "unable to mix ldaps and starttls"
+#~ msgstr "ne mogu miješati ldaps i starttls"
+
+#~ msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+#~ msgstr "sudo_ldap_parse_uri: nema dovoljno prostora za izgradnju međuspremnika računala"
+
+#~ msgid "sudo_ldap_build_pass1 allocation mismatch"
+#~ msgstr "neodgovarajuća sudo_ldap_build_pass1 alokacija"
+
+#~ msgid "internal error: insufficient space for log line"
+#~ msgstr "interna greška: nema dovoljno prostora za redak dnevnika"
+
+#~ msgid "Unable to dlopen %s: %s"
+#~ msgstr "Ne mogu izvršiti dlopen %s: %s"
+
+#~ msgid "writing to standard output"
+#~ msgstr "ispisujem na standardni izlaz"
+
+#~ msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
+#~ msgstr "nanosleep: tv_sec %ld, tv_nsec %ld"
+
+#~ msgid "too many parenthesized expressions, max %d"
+#~ msgstr "previše izraza u zagradama, najviše %d"
+
+#~ msgid "invalid regex: %s"
+#~ msgstr "neispravni regularni izraz: %s"
+
+#~ msgid "%s owned by uid %u, should be uid %u"
+#~ msgstr "vlasnik %s je uid %u, treba biti uid %u"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0700"
+#~ msgstr "nevlasnici imaju dozvolu za pisanje u %s (0%o), treba biti mod 0700"
+
+#~ msgid "%s exists but is not a regular file (0%o)"
+#~ msgstr "%s postoji, ali nije obična datoteka (0%o)"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0600"
+#~ msgstr "nevlasnici imaju dozvolu za pisanje u %s (0%o), treba biti mod 0600"
+
+#~ msgid "unable to remove %s, will reset to the epoch"
+#~ msgstr "ne mogu ukloniti %s, vratit ću na početnu epohu"
+
+#~ msgid "fill_args: buffer overflow"
+#~ msgstr "fill_args: preljev međuspremnika"
+
+#~ msgid "unable to stat editor (%s)"
+#~ msgstr "ne mogu odrediti stanje uređivača (%s)"
+
+#~ msgid ">>> %s: %s near line %d <<<"
+#~ msgstr ">>> %s: %s kod retka %d <<<"
+
+#~ msgid "unable to set locale to \"%s\", using \"C\""
+#~ msgstr "ne mogu postaviti lokal u „%s”, koristim „C”"
+
+#~ msgid ""
+#~ " Commands:\n"
+#~ "\t"
+#~ msgstr ""
+#~ " Naredbe:\n"
+#~ "\t"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "unable to cache uid %u (%s), already exists"
+#~ msgstr "ne mogu staviti uid %u (%s) u spremnik, već postoji"
+
+#~ msgid "unable to cache gid %u (%s), already exists"
+#~ msgstr "ne mogu staviti gid %u (%s) u spremnik, već postoji"
+
+#~ msgid "unable to execute %s: %s"
+#~ msgstr "ne mogu izvršiti %s: %s"
+
+#~ msgid "internal error, expand_prompt() overflow"
+#~ msgstr "interna greška, expand_prompt() preljev"
+
+#~ msgid "internal error, sudo_setenv2() overflow"
+#~ msgstr "interna greška, sudo_setenv2() preljev"
+
+#~ msgid "internal error, sudo_setenv() overflow"
+#~ msgstr "interna greška, sudo_setenv() preljev"
+
+#~ msgid "internal error, linux_audit_command() overflow"
+#~ msgstr "interna greška, linux_audit_command() preljev"
+
+#~ msgid "internal error, runas_groups overflow"
+#~ msgstr "interna greška, runas_groups preljev"
+
+#~ msgid "internal error, init_vars() overflow"
+#~ msgstr "interna greška, init_vars() preljev"
diff --git a/plugins/sudoers/po/hu.mo b/plugins/sudoers/po/hu.mo
new file mode 100644
index 0000000..9e60420
--- /dev/null
+++ b/plugins/sudoers/po/hu.mo
Binary files differ
diff --git a/plugins/sudoers/po/hu.po b/plugins/sudoers/po/hu.po
new file mode 100644
index 0000000..2e9239e
--- /dev/null
+++ b/plugins/sudoers/po/hu.po
@@ -0,0 +1,2152 @@
+# Hungarian translation for sudoers.
+# Portable object template file for the sudoers plugin
+# This file is put in the public domain.
+#
+# Todd C. Miller <Todd.Miller@courtesan.com>, 2011-2014.
+# Gabor Kelemen <kelemeng@ubuntu.com>, 2015.
+# Balázs Úr <urbalazs@gmail.com>, 2017, 2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.22b2\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2017-12-18 10:37-0700\n"
+"PO-Revision-Date: 2018-01-20 14:06+0100\n"
+"Last-Translator: Balázs Úr <urbalazs@gmail.com>\n"
+"Language-Team: Hungarian <translation-team-hu@lists.sourceforge.net>\n"
+"Language: hu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Lokalize 1.2\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "szintaktikai hiba"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "%p jelszava: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] %p jelszava: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Jelszó: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** BIZTONSÁGI információk erről: %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Elnézést, próbálja újra."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:307 gram.y:314 gram.y:321 gram.y:328 gram.y:335
+#: gram.y:398 gram.y:406 gram.y:416 gram.y:449 gram.y:456 gram.y:463
+#: gram.y:470 gram.y:552 gram.y:559 gram.y:568 gram.y:577 gram.y:594
+#: gram.y:706 gram.y:713 gram.y:720 gram.y:728 gram.y:824 gram.y:831
+#: gram.y:838 gram.y:845 gram.y:852 gram.y:878 gram.y:885 gram.y:892
+#: gram.y:1015 gram.y:1195 gram.y:1202 plugins/sudoers/alias.c:124
+#: plugins/sudoers/alias.c:139 plugins/sudoers/auth/bsdauth.c:141
+#: plugins/sudoers/auth/kerb5.c:119 plugins/sudoers/auth/kerb5.c:145
+#: plugins/sudoers/auth/pam.c:490 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/auth/sia.c:59 plugins/sudoers/defaults.c:651
+#: plugins/sudoers/defaults.c:906 plugins/sudoers/defaults.c:1077
+#: plugins/sudoers/editor.c:64 plugins/sudoers/editor.c:82
+#: plugins/sudoers/editor.c:93 plugins/sudoers/env.c:233
+#: plugins/sudoers/filedigest.c:120 plugins/sudoers/filedigest_gcrypt.c:90
+#: plugins/sudoers/filedigest_openssl.c:111 plugins/sudoers/gc.c:52
+#: plugins/sudoers/group_plugin.c:134 plugins/sudoers/interfaces.c:71
+#: plugins/sudoers/iolog.c:941 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:449 plugins/sudoers/ldap.c:480
+#: plugins/sudoers/ldap.c:532 plugins/sudoers/ldap.c:566
+#: plugins/sudoers/ldap.c:980 plugins/sudoers/ldap.c:1174
+#: plugins/sudoers/ldap.c:1185 plugins/sudoers/ldap.c:1201
+#: plugins/sudoers/ldap.c:1493 plugins/sudoers/ldap.c:1653
+#: plugins/sudoers/ldap.c:1735 plugins/sudoers/ldap.c:1883
+#: plugins/sudoers/ldap.c:1907 plugins/sudoers/ldap.c:1996
+#: plugins/sudoers/ldap.c:2011 plugins/sudoers/ldap.c:2107
+#: plugins/sudoers/ldap.c:2140 plugins/sudoers/ldap.c:2221
+#: plugins/sudoers/ldap.c:2303 plugins/sudoers/ldap.c:2400
+#: plugins/sudoers/ldap.c:3235 plugins/sudoers/ldap.c:3267
+#: plugins/sudoers/ldap.c:3579 plugins/sudoers/ldap.c:3607
+#: plugins/sudoers/ldap.c:3623 plugins/sudoers/ldap.c:3713
+#: plugins/sudoers/ldap.c:3729 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:190 plugins/sudoers/logging.c:501
+#: plugins/sudoers/logging.c:522 plugins/sudoers/logging.c:563
+#: plugins/sudoers/logging.c:740 plugins/sudoers/logging.c:998
+#: plugins/sudoers/match.c:617 plugins/sudoers/match.c:664
+#: plugins/sudoers/match.c:714 plugins/sudoers/match.c:738
+#: plugins/sudoers/match.c:826 plugins/sudoers/match.c:915
+#: plugins/sudoers/parse.c:252 plugins/sudoers/parse.c:264
+#: plugins/sudoers/parse.c:279 plugins/sudoers/parse.c:291
+#: plugins/sudoers/policy.c:498 plugins/sudoers/policy.c:735
+#: plugins/sudoers/prompt.c:93 plugins/sudoers/pwutil.c:165
+#: plugins/sudoers/pwutil.c:236 plugins/sudoers/pwutil.c:312
+#: plugins/sudoers/pwutil.c:486 plugins/sudoers/pwutil.c:551
+#: plugins/sudoers/pwutil.c:620 plugins/sudoers/pwutil.c:778
+#: plugins/sudoers/pwutil.c:835 plugins/sudoers/pwutil.c:880
+#: plugins/sudoers/pwutil.c:938 plugins/sudoers/sssd.c:162
+#: plugins/sudoers/sssd.c:194 plugins/sudoers/sssd.c:237
+#: plugins/sudoers/sssd.c:244 plugins/sudoers/sssd.c:280
+#: plugins/sudoers/sssd.c:353 plugins/sudoers/sssd.c:392
+#: plugins/sudoers/sssd.c:1073 plugins/sudoers/sssd.c:1252
+#: plugins/sudoers/sssd.c:1266 plugins/sudoers/sssd.c:1282
+#: plugins/sudoers/sudoers.c:263 plugins/sudoers/sudoers.c:273
+#: plugins/sudoers/sudoers.c:281 plugins/sudoers/sudoers.c:365
+#: plugins/sudoers/sudoers.c:682 plugins/sudoers/sudoers.c:807
+#: plugins/sudoers/sudoers.c:851 plugins/sudoers/sudoers.c:1123
+#: plugins/sudoers/sudoers_debug.c:107 plugins/sudoers/sudoreplay.c:1254
+#: plugins/sudoers/sudoreplay.c:1366 plugins/sudoers/sudoreplay.c:1406
+#: plugins/sudoers/sudoreplay.c:1415 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/sudoreplay.c:1433 plugins/sudoers/sudoreplay.c:1437
+#: plugins/sudoers/sudoreplay.c:1593 plugins/sudoers/sudoreplay.c:1597
+#: plugins/sudoers/testsudoers.c:131 plugins/sudoers/testsudoers.c:217
+#: plugins/sudoers/testsudoers.c:234 plugins/sudoers/timestamp.c:397
+#: plugins/sudoers/timestamp.c:441 plugins/sudoers/timestamp.c:868
+#: plugins/sudoers/toke_util.c:56 plugins/sudoers/toke_util.c:109
+#: plugins/sudoers/toke_util.c:146 plugins/sudoers/visudo.c:153
+#: plugins/sudoers/visudo.c:309 plugins/sudoers/visudo.c:315
+#: plugins/sudoers/visudo.c:446 plugins/sudoers/visudo.c:624
+#: plugins/sudoers/visudo.c:985 plugins/sudoers/visudo.c:1051
+#: plugins/sudoers/visudo.c:1095 plugins/sudoers/visudo.c:1197
+#: plugins/sudoers/visudo_json.c:1025 toke.l:849 toke.l:949 toke.l:1106
+msgid "unable to allocate memory"
+msgstr "nem foglalható memória"
+
+#: gram.y:481
+msgid "a digest requires a path name"
+msgstr "egy kivonat egy útvonalnevet igényel"
+
+#: gram.y:607
+msgid "invalid notbefore value"
+msgstr "érvénytelen „notbefore” érték"
+
+#: gram.y:615
+msgid "invalid notafter value"
+msgstr "érvénytelen „notafter” érték"
+
+#: gram.y:624 plugins/sudoers/policy.c:314
+msgid "timeout value too large"
+msgstr "az időkorlát értéke túl nagy"
+
+#: gram.y:626 plugins/sudoers/policy.c:316
+msgid "invalid timeout value"
+msgstr "érvénytelen időkorlát érték"
+
+#: gram.y:1195 gram.y:1202 plugins/sudoers/auth/pam.c:320
+#: plugins/sudoers/auth/pam.c:490 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/defaults.c:651 plugins/sudoers/defaults.c:906
+#: plugins/sudoers/defaults.c:1077 plugins/sudoers/editor.c:64
+#: plugins/sudoers/editor.c:82 plugins/sudoers/editor.c:93
+#: plugins/sudoers/env.c:233 plugins/sudoers/filedigest.c:120
+#: plugins/sudoers/filedigest_gcrypt.c:72
+#: plugins/sudoers/filedigest_gcrypt.c:90
+#: plugins/sudoers/filedigest_openssl.c:111 plugins/sudoers/gc.c:52
+#: plugins/sudoers/group_plugin.c:134 plugins/sudoers/interfaces.c:71
+#: plugins/sudoers/iolog.c:941 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:449 plugins/sudoers/ldap.c:480
+#: plugins/sudoers/ldap.c:532 plugins/sudoers/ldap.c:566
+#: plugins/sudoers/ldap.c:980 plugins/sudoers/ldap.c:1174
+#: plugins/sudoers/ldap.c:1185 plugins/sudoers/ldap.c:1201
+#: plugins/sudoers/ldap.c:1493 plugins/sudoers/ldap.c:1653
+#: plugins/sudoers/ldap.c:1735 plugins/sudoers/ldap.c:1883
+#: plugins/sudoers/ldap.c:1907 plugins/sudoers/ldap.c:1996
+#: plugins/sudoers/ldap.c:2011 plugins/sudoers/ldap.c:2107
+#: plugins/sudoers/ldap.c:2140 plugins/sudoers/ldap.c:2220
+#: plugins/sudoers/ldap.c:2303 plugins/sudoers/ldap.c:2400
+#: plugins/sudoers/ldap.c:3235 plugins/sudoers/ldap.c:3267
+#: plugins/sudoers/ldap.c:3579 plugins/sudoers/ldap.c:3606
+#: plugins/sudoers/ldap.c:3622 plugins/sudoers/ldap.c:3713
+#: plugins/sudoers/ldap.c:3729 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:190 plugins/sudoers/logging.c:501
+#: plugins/sudoers/logging.c:522 plugins/sudoers/logging.c:562
+#: plugins/sudoers/logging.c:998 plugins/sudoers/match.c:616
+#: plugins/sudoers/match.c:663 plugins/sudoers/match.c:714
+#: plugins/sudoers/match.c:738 plugins/sudoers/match.c:826
+#: plugins/sudoers/match.c:914 plugins/sudoers/parse.c:252
+#: plugins/sudoers/parse.c:264 plugins/sudoers/parse.c:279
+#: plugins/sudoers/parse.c:291 plugins/sudoers/policy.c:128
+#: plugins/sudoers/policy.c:137 plugins/sudoers/policy.c:146
+#: plugins/sudoers/policy.c:172 plugins/sudoers/policy.c:299
+#: plugins/sudoers/policy.c:314 plugins/sudoers/policy.c:316
+#: plugins/sudoers/policy.c:342 plugins/sudoers/policy.c:352
+#: plugins/sudoers/policy.c:396 plugins/sudoers/policy.c:406
+#: plugins/sudoers/policy.c:415 plugins/sudoers/policy.c:424
+#: plugins/sudoers/policy.c:498 plugins/sudoers/policy.c:735
+#: plugins/sudoers/prompt.c:93 plugins/sudoers/pwutil.c:165
+#: plugins/sudoers/pwutil.c:236 plugins/sudoers/pwutil.c:312
+#: plugins/sudoers/pwutil.c:486 plugins/sudoers/pwutil.c:551
+#: plugins/sudoers/pwutil.c:620 plugins/sudoers/pwutil.c:778
+#: plugins/sudoers/pwutil.c:835 plugins/sudoers/pwutil.c:880
+#: plugins/sudoers/pwutil.c:938 plugins/sudoers/set_perms.c:387
+#: plugins/sudoers/set_perms.c:766 plugins/sudoers/set_perms.c:1150
+#: plugins/sudoers/set_perms.c:1476 plugins/sudoers/set_perms.c:1641
+#: plugins/sudoers/sssd.c:162 plugins/sudoers/sssd.c:194
+#: plugins/sudoers/sssd.c:237 plugins/sudoers/sssd.c:244
+#: plugins/sudoers/sssd.c:280 plugins/sudoers/sssd.c:352
+#: plugins/sudoers/sssd.c:392 plugins/sudoers/sssd.c:1073
+#: plugins/sudoers/sssd.c:1251 plugins/sudoers/sssd.c:1266
+#: plugins/sudoers/sssd.c:1282 plugins/sudoers/sudoers.c:263
+#: plugins/sudoers/sudoers.c:273 plugins/sudoers/sudoers.c:281
+#: plugins/sudoers/sudoers.c:365 plugins/sudoers/sudoers.c:682
+#: plugins/sudoers/sudoers.c:807 plugins/sudoers/sudoers.c:851
+#: plugins/sudoers/sudoers.c:1123 plugins/sudoers/sudoers_debug.c:106
+#: plugins/sudoers/sudoreplay.c:1254 plugins/sudoers/sudoreplay.c:1366
+#: plugins/sudoers/sudoreplay.c:1406 plugins/sudoers/sudoreplay.c:1415
+#: plugins/sudoers/sudoreplay.c:1425 plugins/sudoers/sudoreplay.c:1433
+#: plugins/sudoers/sudoreplay.c:1437 plugins/sudoers/sudoreplay.c:1593
+#: plugins/sudoers/sudoreplay.c:1597 plugins/sudoers/testsudoers.c:131
+#: plugins/sudoers/testsudoers.c:217 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/timestamp.c:397 plugins/sudoers/timestamp.c:441
+#: plugins/sudoers/timestamp.c:868 plugins/sudoers/toke_util.c:56
+#: plugins/sudoers/toke_util.c:109 plugins/sudoers/toke_util.c:146
+#: plugins/sudoers/visudo.c:153 plugins/sudoers/visudo.c:309
+#: plugins/sudoers/visudo.c:315 plugins/sudoers/visudo.c:446
+#: plugins/sudoers/visudo.c:624 plugins/sudoers/visudo.c:985
+#: plugins/sudoers/visudo.c:1051 plugins/sudoers/visudo.c:1095
+#: plugins/sudoers/visudo.c:1197 plugins/sudoers/visudo_json.c:1025 toke.l:849
+#: toke.l:949 toke.l:1106
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:135
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "A(z) „%s” álnév már meg van határozva"
+
+#: plugins/sudoers/auth/bsdauth.c:68
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "a bejelentkezési osztály lekérése sikertelen ennél a felhasználónál: %s"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+msgid "unable to begin bsd authentication"
+msgstr "a BSD hitelesítés elkezdése sikertelen"
+
+#: plugins/sudoers/auth/bsdauth.c:81
+msgid "invalid authentication type"
+msgstr "érvénytelen hitelesítési típus"
+
+#: plugins/sudoers/auth/bsdauth.c:90
+msgid "unable to initialize BSD authentication"
+msgstr "a BSD hitelesítés előkészítése sikertelen"
+
+#: plugins/sudoers/auth/fwtk.c:52
+msgid "unable to read fwtk config"
+msgstr "az fwtk beállítás olvasása sikertelen"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to connect to authentication server"
+msgstr "a hitelesítési kiszolgálóhoz való kapcsolódás sikertelen"
+
+#: plugins/sudoers/auth/fwtk.c:63 plugins/sudoers/auth/fwtk.c:87
+#: plugins/sudoers/auth/fwtk.c:121
+msgid "lost connection to authentication server"
+msgstr "a kapcsolat megszakadt a hitelesítési kiszolgálóval"
+
+#: plugins/sudoers/auth/fwtk.c:67
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"hitelesítési kiszolgáló hiba:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:111
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: az elsődleges átalakítása karakterláncra („%s”) sikertelen: %s"
+
+#: plugins/sudoers/auth/kerb5.c:161
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: „%s” feldolgozása sikertelen: %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: a hitelesítési adatok gyorsítótárának feloldása sikertelen: %s"
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: a kapcsolók lefoglalása sikertelen: %s"
+
+#: plugins/sudoers/auth/kerb5.c:232
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: a hitelesítési adatok lekérése sikertelen: %s"
+
+#: plugins/sudoers/auth/kerb5.c:245
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: a hitelesítési adatok gyorsítótárának előkészítése sikertelen: %s"
+
+#: plugins/sudoers/auth/kerb5.c:248
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: a hitelesítési adatok gyorsítótárban való tárolósa sikertelen: %s"
+
+#: plugins/sudoers/auth/kerb5.c:312
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: az elsődleges gép lekérése sikertelen: %s"
+
+#: plugins/sudoers/auth/kerb5.c:326
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: a TGT nem ellenőrizhető! Lehetséges támadás! %s"
+
+#: plugins/sudoers/auth/pam.c:108
+msgid "unable to initialize PAM"
+msgstr "a PAM előkészítése sikertelen"
+
+#: plugins/sudoers/auth/pam.c:194
+msgid "account validation failure, is your account locked?"
+msgstr "fiókellenőrzési hiba, a fiókja zárolva van?"
+
+#: plugins/sudoers/auth/pam.c:198
+msgid "Account or password is expired, reset your password and try again"
+msgstr "A fiók vagy a jelszó lejárt, állítsa vissza a jelszavát, és próbálja újra"
+
+#: plugins/sudoers/auth/pam.c:206
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "a lejárt jelszó megváltoztatása sikertelen: %s"
+
+#: plugins/sudoers/auth/pam.c:211
+msgid "Password expired, contact your system administrator"
+msgstr "A jelszó lejárt, vegye fel a kapcsolatot a rendszergazdával"
+
+#: plugins/sudoers/auth/pam.c:215
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "A fiók lejárt vagy a PAM beállításból hiányzik egy „account” szakasz a sudo számára, vegye fel a kapcsolatot a rendszergazdával"
+
+#: plugins/sudoers/auth/pam.c:229
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "PAM hitelesítési hiba: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:97 plugins/sudoers/visudo.c:227
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "Ön nem létezik a(z) %s adatbázisban"
+
+#: plugins/sudoers/auth/securid5.c:73
+msgid "failed to initialise the ACE API library"
+msgstr "nem sikerült előkészíteni az ACE API programkönyvtárat"
+
+#: plugins/sudoers/auth/securid5.c:99
+msgid "unable to contact the SecurID server"
+msgstr "a SecurID kiszolgálóhoz való kapcsolódás sikertelen"
+
+#: plugins/sudoers/auth/securid5.c:108
+msgid "User ID locked for SecurID Authentication"
+msgstr "A felhasználó-azonosító zárolva van a SecurID hitelesítéshez"
+
+#: plugins/sudoers/auth/securid5.c:112 plugins/sudoers/auth/securid5.c:163
+msgid "invalid username length for SecurID"
+msgstr "érvénytelen felhasználónév hossz a SecurID-nál"
+
+#: plugins/sudoers/auth/securid5.c:116 plugins/sudoers/auth/securid5.c:168
+msgid "invalid Authentication Handle for SecurID"
+msgstr "érvénytelen hitelesítéskezelés a SecurID-nál"
+
+#: plugins/sudoers/auth/securid5.c:120
+msgid "SecurID communication failed"
+msgstr "a SecurID kommunikáció meghiúsult"
+
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:213
+msgid "unknown SecurID error"
+msgstr "ismeretlen SecurID hiba"
+
+#: plugins/sudoers/auth/securid5.c:158
+msgid "invalid passcode length for SecurID"
+msgstr "érvénytelen jelkód hossz a SecurID-nál"
+
+#: plugins/sudoers/auth/sia.c:69 plugins/sudoers/auth/sia.c:125
+msgid "unable to initialize SIA session"
+msgstr "a SIA munkamenet előkészítése sikertelen"
+
+#: plugins/sudoers/auth/sudo_auth.c:126
+msgid "invalid authentication methods"
+msgstr "érvénytelen hitelesítési módszerek"
+
+#: plugins/sudoers/auth/sudo_auth.c:128
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Érvénytelen hitelesítési módszerek lettek belefordítva a sudo programba! Nem keverheti az önálló és a nem önálló hitelesítéseket."
+
+#: plugins/sudoers/auth/sudo_auth.c:224 plugins/sudoers/auth/sudo_auth.c:274
+msgid "no authentication methods"
+msgstr "nincsenek hitelesítési módszerek"
+
+#: plugins/sudoers/auth/sudo_auth.c:226
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Nincsenek hitelesítési módszerek belefordítva a sudo programba! Ha ki szeretné kapcsolni a hitelesítést, akkor használja a --disable-authentication konfigurációs kapcsolót."
+
+#: plugins/sudoers/auth/sudo_auth.c:276
+msgid "Unable to initialize authentication methods."
+msgstr "A hitelesítési módszerek előkészítése sikertelen."
+
+#: plugins/sudoers/auth/sudo_auth.c:441
+msgid "Authentication methods:"
+msgstr "Hitelesítési módszerek:"
+
+#: plugins/sudoers/bsm_audit.c:120 plugins/sudoers/bsm_audit.c:211
+msgid "Could not determine audit condition"
+msgstr "Nem sikerült meghatározni a felülvizsgálati feltételt"
+
+#: plugins/sudoers/bsm_audit.c:183 plugins/sudoers/bsm_audit.c:273
+msgid "unable to commit audit record"
+msgstr "a felülvizsgálati rekord véglegesítése sikertelen"
+
+#: plugins/sudoers/check.c:259
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Bízunk benne, hogy megkapta a szokásos tudnivalókat a helyi\n"
+"rendszergazdától. Általában a következő három dolog lényeges:\n"
+"\n"
+" #1) Tartsa tiszteletben mások személyiségi jogait.\n"
+" #2) Gondolkodjon gépelés előtt.\n"
+" #3) A nagy erő nagy felelősséggel jár.\n"
+"\n"
+
+#: plugins/sudoers/check.c:302 plugins/sudoers/check.c:312
+#: plugins/sudoers/sudoers.c:725 plugins/sudoers/sudoers.c:770
+#, c-format
+msgid "unknown uid: %u"
+msgstr "ismeretlen uid: %u"
+
+#: plugins/sudoers/check.c:307 plugins/sudoers/iolog.c:260
+#: plugins/sudoers/policy.c:908 plugins/sudoers/sudoers.c:1162
+#: plugins/sudoers/testsudoers.c:208 plugins/sudoers/testsudoers.c:366
+#, c-format
+msgid "unknown user: %s"
+msgstr "ismeretlen felhasználó: %s"
+
+#: plugins/sudoers/def_data.c:41
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Syslog képesség, ha a syslog programot használják naplózáshoz: %s"
+
+#: plugins/sudoers/def_data.c:45
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "A használandó syslog prioritás, amikor a felhasználó sikeresen hitelesíti magát: %s"
+
+#: plugins/sudoers/def_data.c:49
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "A használandó syslog prioritás, amikor a felhasználó sikertelenül hitelesíti magát: %s"
+
+#: plugins/sudoers/def_data.c:53
+msgid "Put OTP prompt on its own line"
+msgstr "Az OTP kérdés elhelyezés a saját sorába"
+
+#: plugins/sudoers/def_data.c:57
+msgid "Ignore '.' in $PATH"
+msgstr "A „.” figyelmen kívül hagyása a $PATH változóban"
+
+#: plugins/sudoers/def_data.c:61
+msgid "Always send mail when sudo is run"
+msgstr "Mindig küldjön levelet, amikor a sudo fut"
+
+#: plugins/sudoers/def_data.c:65
+msgid "Send mail if user authentication fails"
+msgstr "Levél küldése, ha a felhasználó-hitelesítés sikertelen"
+
+#: plugins/sudoers/def_data.c:69
+msgid "Send mail if the user is not in sudoers"
+msgstr "Levél küldése, ha a felhasználó nincs a sudoers fájlban"
+
+#: plugins/sudoers/def_data.c:73
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Levél küldése, ha a felhasználó nincs a sudoers fájlban ennél a gépnél"
+
+#: plugins/sudoers/def_data.c:77
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Levél küldése, ha a felhasználónak nem engedélyezett egy parancs futtatása"
+
+#: plugins/sudoers/def_data.c:81
+msgid "Send mail if the user tries to run a command"
+msgstr "Levél küldése, ha a felhasználó megpróbál egy parancsot futtatni"
+
+#: plugins/sudoers/def_data.c:85
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Különálló időbélyeg használata minden felhasználó/tty párosnál"
+
+#: plugins/sudoers/def_data.c:89
+msgid "Lecture user the first time they run sudo"
+msgstr "Felhasználó oktatása a sudo első alkalommal történő futtatásakor"
+
+#: plugins/sudoers/def_data.c:93
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "A sudo oktatóanyagot tartalmazó fájl: %s"
+
+#: plugins/sudoers/def_data.c:97
+msgid "Require users to authenticate by default"
+msgstr "Felhasználók hitelesítésének megkövetelése alapértelmezetten"
+
+#: plugins/sudoers/def_data.c:101
+msgid "Root may run sudo"
+msgstr "A rendszergazda futtathatja a sudo programot"
+
+#: plugins/sudoers/def_data.c:105
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "A gépnév naplózása a (nem syslog) naplófájlba"
+
+#: plugins/sudoers/def_data.c:109
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Az év naplózása a (nem syslog) naplófájlba"
+
+#: plugins/sudoers/def_data.c:113
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Ha a sudo programot argumentumok nélkül hívják meg, akkor indítson egy parancsértelmezőt"
+
+#: plugins/sudoers/def_data.c:117
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "A $HOME beállítása a célfelhasználóra, amikor a -s kapcsolóval indít egy parancsértelmezőt"
+
+#: plugins/sudoers/def_data.c:121
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Mindig állítsa be a $HOME értékét a célfelhasználó saját könyvtárára"
+
+#: plugins/sudoers/def_data.c:125
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Néhány információ begyűjtésének engedélyezése hasznos hibaüzenetek adásához"
+
+#: plugins/sudoers/def_data.c:129
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Teljes képzésű gépnevek megkövetelése a sudoers fájlban"
+
+#: plugins/sudoers/def_data.c:133
+msgid "Insult the user when they enter an incorrect password"
+msgstr "A felhasználó piszkálása, amikor helytelen jelszót ad meg"
+
+#: plugins/sudoers/def_data.c:137
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Csak akkor engedélyezze a sudo futtatását a felhasználónak, ha rendelkezik tty-nal"
+
+#: plugins/sudoers/def_data.c:141
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "A visudo el fogja fogadni az EDITOR környezeti változót"
+
+#: plugins/sudoers/def_data.c:145
+msgid "Prompt for root's password, not the users's"
+msgstr "A rendszergazda jelszavának bekérése, nem a felhasználóénak"
+
+#: plugins/sudoers/def_data.c:149
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "A runas_default felhasználó jelszavának bekérése, nem a felhasználóénak"
+
+#: plugins/sudoers/def_data.c:153
+msgid "Prompt for the target user's password, not the users's"
+msgstr "A célfelhasználó jelszavának bekérése, nem a felhasználóénak"
+
+#: plugins/sudoers/def_data.c:157
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Alapértelmezések alkalmazása a célfelhasználó bejelentkezési osztályán, ha van ilyen"
+
+#: plugins/sudoers/def_data.c:161
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "A LOGNAME és a USER környezeti változók beállítása"
+
+#: plugins/sudoers/def_data.c:165
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Csak a tényleges uid beállítása a célfelhasználóra, nem a valódi uid értékének"
+
+#: plugins/sudoers/def_data.c:169
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Ne készítse elő a csoportvektort a célfelhasználóéra"
+
+#: plugins/sudoers/def_data.c:173
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "A hossz, amelyre a naplófájl sorait tördelni kell (0 esetén nincs tördelés): %u"
+
+#: plugins/sudoers/def_data.c:177
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Hitelesítési időbélyeg időkorlát: %.1f perc"
+
+#: plugins/sudoers/def_data.c:181
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Jelszóbekérési időkorlát: %.1f perc"
+
+#: plugins/sudoers/def_data.c:185
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Egy jelszómegadás kísérleteinek száma: %u"
+
+#: plugins/sudoers/def_data.c:189
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "A használandó umask vagy 0777 a felhasználóé használatához: 0%o"
+
+#: plugins/sudoers/def_data.c:193
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Útvonal a naplófájlhoz: %s"
+
+#: plugins/sudoers/def_data.c:197
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Útvonal a levelezőprogramhoz: %s"
+
+#: plugins/sudoers/def_data.c:201
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Jelzők a levelezőprogramhoz: %s"
+
+#: plugins/sudoers/def_data.c:205
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "A cím, amelyre a levelet küldeni kell: %s"
+
+#: plugins/sudoers/def_data.c:209
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "A cím, amelyről a levelet küldeni kell: %s"
+
+#: plugins/sudoers/def_data.c:213
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Tárgysor a levél üzeneteihez: %s"
+
+#: plugins/sudoers/def_data.c:217
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Helytelen jelszó üzenet: %s"
+
+#: plugins/sudoers/def_data.c:221
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Útvonal az oktatóanyag állapot könyvtárához: %s"
+
+#: plugins/sudoers/def_data.c:225
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Útvonal a hitelesítési időbélyeg könyvtárához: %s"
+
+#: plugins/sudoers/def_data.c:229
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "A hitelesítési időbélyeg könyvtárának tulajdonosa: %s"
+
+#: plugins/sudoers/def_data.c:233
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Az ebben a csoportban lévő felhasználók mentesülnek a jelszó és PATH követelmények alól: %s"
+
+#: plugins/sudoers/def_data.c:237
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Alapértelmezett jelszóbekérés: %s"
+
+#: plugins/sudoers/def_data.c:241
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Ha be van állítva, akkor a jelszóbekérés minden esetben felül fogja bírálni a rendszer bekéréseit."
+
+#: plugins/sudoers/def_data.c:245
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Alapértelmezett felhasználó a parancsok futtatásához másként: %s"
+
+#: plugins/sudoers/def_data.c:249
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Érték a felhasználó $PATH változójának felülbírálásához ezzel: %s"
+
+#: plugins/sudoers/def_data.c:253
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Útvonal a visudo által használt szerkesztőhöz: %s"
+
+#: plugins/sudoers/def_data.c:257
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Mikor szükséges jelszó a „list” álparancshoz: %s"
+
+#: plugins/sudoers/def_data.c:261
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Mikor szükséges jelszó a „verify” álparancshoz: %s"
+
+#: plugins/sudoers/def_data.c:265
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "A sudo_noexec programkönyvtárban található üres végrehajtási függvények előtöltése"
+
+#: plugins/sudoers/def_data.c:269
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Ha az LDAP könyvtár be van kapcsolva, akkor mellőzzük-e a helyi sodoers fájlt"
+
+#: plugins/sudoers/def_data.c:273
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "A fájlleírók >= %d le lesznek zárva a parancs végrehajtása előtt"
+
+#: plugins/sudoers/def_data.c:277
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Ha be van állítva, akkor a felhasználók felülbírálhatják a „closefrom” értékét a -C kapcsolóval"
+
+#: plugins/sudoers/def_data.c:281
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Lehetővé teszi a felhasználóknak tetszőleges környezeti változók beállítását"
+
+#: plugins/sudoers/def_data.c:285
+msgid "Reset the environment to a default set of variables"
+msgstr "A környezet visszaállítása egy alapértelmezett változókészletre"
+
+#: plugins/sudoers/def_data.c:289
+msgid "Environment variables to check for sanity:"
+msgstr "Környezeti változók az épség ellenőrzéséhez:"
+
+#: plugins/sudoers/def_data.c:293
+msgid "Environment variables to remove:"
+msgstr "Eltávolítandó környezeti változók:"
+
+#: plugins/sudoers/def_data.c:297
+msgid "Environment variables to preserve:"
+msgstr "Megőrzendő környezeti változók:"
+
+#: plugins/sudoers/def_data.c:301
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Az új biztonsági környezetben használandó SELinux szerep: %s"
+
+#: plugins/sudoers/def_data.c:305
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Az új biztonsági környezetben használandó SELinux típus: %s"
+
+#: plugins/sudoers/def_data.c:309
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Útvonal a sudo specifikus környezeti fájlhoz: %s"
+
+#: plugins/sudoers/def_data.c:313
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Útvonal a korlátozott sudo specifikus környezeti fájlhoz: %s"
+
+#: plugins/sudoers/def_data.c:317
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "A sudoers feldolgozásakor használandó területi beállítás: %s"
+
+#: plugins/sudoers/def_data.c:321
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Lehetővé tenni a sudo számára egy jelszó bekérését akkor is, ha látható lesz"
+
+#: plugins/sudoers/def_data.c:325
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Látható visszajelzés nyújtása a jelszóbekérésnél, amikor felhasználói bevitel van"
+
+#: plugins/sudoers/def_data.c:329
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Gyorsabb mintaillesztés használata, ami kevésbé pontos, de nem fér hozzá a fájlrendszerhez"
+
+#: plugins/sudoers/def_data.c:333
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "A sudoers fájlban megadott umask felül fogja bírálni a felhasználóét akkor is, ha az engedékenyebb"
+
+#: plugins/sudoers/def_data.c:337
+msgid "Log user's input for the command being run"
+msgstr "A futtatott parancs felhasználói bevitelének naplózása"
+
+#: plugins/sudoers/def_data.c:341
+msgid "Log the output of the command being run"
+msgstr "A futtatott parancs kimenetének naplózása"
+
+#: plugins/sudoers/def_data.c:345
+msgid "Compress I/O logs using zlib"
+msgstr "I/O naplók tömörítése zlib használatával"
+
+#: plugins/sudoers/def_data.c:349
+msgid "Always run commands in a pseudo-tty"
+msgstr "A parancsokat mindig egy ál-tty-ban futtassa"
+
+#: plugins/sudoers/def_data.c:353
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Bővítmény a nem Unix csoport támogatáshoz: %s"
+
+#: plugins/sudoers/def_data.c:357
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "A könyvtár, amelyben a bemeneti/kimeneti naplók tárolva lesznek: %s"
+
+#: plugins/sudoers/def_data.c:361
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "A fájl, amelyben a bemeneti/kimeneti napló tárolva lesz: %s"
+
+#: plugins/sudoers/def_data.c:365
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Bejegyzés hozzáadása az utmp/utmpx fájlhoz egy pty lefoglalásakor"
+
+#: plugins/sudoers/def_data.c:369
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Az utmp-ben lévő felhasználó beállítása a runas felhasználóra, nem a meghívó felhasználóra"
+
+#: plugins/sudoers/def_data.c:373
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Engedélyezett jogosultságok halmaza: %s"
+
+#: plugins/sudoers/def_data.c:377
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Korlátozott jogosultságok halmaza: %s"
+
+#: plugins/sudoers/def_data.c:381
+msgid "Run commands on a pty in the background"
+msgstr "Parancsok futtatása egy pty-on a háttérben"
+
+#: plugins/sudoers/def_data.c:385
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "A használandó PAM szolgáltatás neve: %s"
+
+#: plugins/sudoers/def_data.c:389
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "A bejelentkezési parancsértelmezőkhöz használandó PAM szolgáltatás neve: %s"
+
+#: plugins/sudoers/def_data.c:393
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "PAM hitelesítési adatok kiépítésének kísérlete a célfelhasználónál"
+
+#: plugins/sudoers/def_data.c:397
+msgid "Create a new PAM session for the command to run in"
+msgstr "Új PAM munkamenet létrehozása annál a parancsnál, amelyben fut"
+
+#: plugins/sudoers/def_data.c:401
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Legnagyobb I/O napló sorozatszáma: %u"
+
+#: plugins/sudoers/def_data.c:405
+msgid "Enable sudoers netgroup support"
+msgstr "A sudoers netgroup támogatásának engedélyezése"
+
+#: plugins/sudoers/def_data.c:409
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "A szülőkönyvtárak írhatóságának ellenőrzése a sudoedit programmal történő fájlszerkesztéskor"
+
+#: plugins/sudoers/def_data.c:413
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Szimbolikus linkek követése a sudoedit programmal történő fájlszerkesztéskor"
+
+#: plugins/sudoers/def_data.c:417
+msgid "Query the group plugin for unknown system groups"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:421
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:425
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:429
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:433
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:437
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:441
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:445
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:449
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:453
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:457
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:461
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:465
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:469
+msgid "Allow the user to specify a timeout on the command line"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:473
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:477
+msgid "Include the process ID when logging via syslog"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:481
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:485
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:221
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:224
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:267
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:270
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:290
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:293
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:318
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:321
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:343
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:346
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:356
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:359
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr ""
+
+#: plugins/sudoers/env.c:295 plugins/sudoers/env.c:302
+#: plugins/sudoers/env.c:407 plugins/sudoers/ldap.c:453
+#: plugins/sudoers/ldap.c:543 plugins/sudoers/ldap.c:1270
+#: plugins/sudoers/ldap.c:1497 plugins/sudoers/ldap.c:1822
+#: plugins/sudoers/linux_audit.c:82 plugins/sudoers/logging.c:1003
+#: plugins/sudoers/policy.c:619 plugins/sudoers/policy.c:629
+#: plugins/sudoers/prompt.c:161 plugins/sudoers/sudoers.c:873
+#: plugins/sudoers/testsudoers.c:238 plugins/sudoers/toke_util.c:158
+#, c-format
+msgid "internal error, %s overflow"
+msgstr ""
+
+#: plugins/sudoers/env.c:376
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr ""
+
+#: plugins/sudoers/env.c:1055
+msgid "unable to rebuild the environment"
+msgstr ""
+
+#: plugins/sudoers/env.c:1129
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr ""
+
+#: plugins/sudoers/filedigest.c:104 plugins/sudoers/filedigest_gcrypt.c:66
+#: plugins/sudoers/filedigest_openssl.c:95
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr ""
+
+#: plugins/sudoers/filedigest.c:129 plugins/sudoers/filedigest_gcrypt.c:98
+#: plugins/sudoers/filedigest_openssl.c:120
+#, c-format
+msgid "%s: read error"
+msgstr "%s: olvasási hiba"
+
+#: plugins/sudoers/group_plugin.c:86
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s a(z) %d uid tulajdona kell legyen"
+
+#: plugins/sudoers/group_plugin.c:90
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s csak a tulajdonos által írható lehet"
+
+#: plugins/sudoers/group_plugin.c:98 plugins/sudoers/sssd.c:400
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "a(z) %s nem tölthető be: %s"
+
+#: plugins/sudoers/group_plugin.c:104
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "nem található a „group_plugin” szimbólum ebben: %s"
+
+#: plugins/sudoers/group_plugin.c:109
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:79 plugins/sudoers/interfaces.c:96
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:129
+msgid "Local IP address and netmask pairs:\n"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:121 plugins/sudoers/mkdir_parents.c:75
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:146 plugins/sudoers/iolog.c:187
+#: plugins/sudoers/mkdir_parents.c:64 plugins/sudoers/timestamp.c:175
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "%s könyvtár létrehozása sikertelen"
+
+#: plugins/sudoers/iolog.c:191 plugins/sudoers/visudo.c:740
+#: plugins/sudoers/visudo.c:750
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "nem lehet a(z) %s módját megváltoztatni erre: 0%o"
+
+#: plugins/sudoers/iolog.c:299 plugins/sudoers/sudoers.c:1193
+#: plugins/sudoers/testsudoers.c:390
+#, c-format
+msgid "unknown group: %s"
+msgstr "ismeretlen csoport: %s"
+
+#: plugins/sudoers/iolog.c:418 plugins/sudoers/sudoers.c:929
+#: plugins/sudoers/sudoreplay.c:349 plugins/sudoers/sudoreplay.c:1355
+#: plugins/sudoers/sudoreplay.c:1559 plugins/sudoers/timestamp.c:406
+#: plugins/sudoers/visudo.c:972 plugins/sudoers/visudo_json.c:1001
+#: plugins/sudoers/visudo_json.c:1014
+#, c-format
+msgid "unable to open %s"
+msgstr "%s nem nyitható meg"
+
+#: plugins/sudoers/iolog.c:469 plugins/sudoers/sudoers.c:933
+#: plugins/sudoers/sudoreplay.c:857 plugins/sudoers/sudoreplay.c:1670
+#, c-format
+msgid "unable to read %s"
+msgstr "%s nem olvasható"
+
+#: plugins/sudoers/iolog.c:505 plugins/sudoers/sudoreplay.c:1124
+#: plugins/sudoers/timestamp.c:295 plugins/sudoers/timestamp.c:298
+#, c-format
+msgid "unable to write to %s"
+msgstr "az írás sikertelen ebbe: %s"
+
+#: plugins/sudoers/iolog.c:584 plugins/sudoers/iolog.c:803
+#, c-format
+msgid "unable to create %s"
+msgstr "%s létrehozása sikertelen"
+
+#: plugins/sudoers/iolog.c:1035 plugins/sudoers/iolog.c:1110
+#: plugins/sudoers/iolog.c:1191
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, file index %d not open"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:431
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:491
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:518
+msgid "unable to mix ldap and ldaps URIs"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:522 plugins/sudoers/ldap.c:559
+msgid "starttls not supported when using ldaps"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:630
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:633
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1256
+msgid "unable to get GMT time"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1262
+msgid "unable to format timestamp"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1986
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2559
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2561
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2617
+#, c-format
+msgid " Order: %s\n"
+msgstr " Sorrend: %s\n"
+
+#: plugins/sudoers/ldap.c:2625 plugins/sudoers/parse.c:618
+#: plugins/sudoers/sssd.c:1647
+#, c-format
+msgid " Commands:\n"
+msgstr " Parancsok:\n"
+
+#: plugins/sudoers/ldap.c:3187
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:3223
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:3475
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:52
+msgid "unable to open audit system"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:93
+msgid "unable to send audit message"
+msgstr ""
+
+#: plugins/sudoers/logging.c:108
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:136
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (parancs folytatása) %s"
+
+#: plugins/sudoers/logging.c:165
+#, c-format
+msgid "unable to open log file: %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:173
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:206
+#, c-format
+msgid "unable to write log file: %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:235
+msgid "No user or host"
+msgstr "Nem felhasználó vagy gép"
+
+#: plugins/sudoers/logging.c:237
+msgid "validation failure"
+msgstr "érvényesítési hiba"
+
+#: plugins/sudoers/logging.c:244
+msgid "user NOT in sudoers"
+msgstr "a felhasználó NINCS a sudoers-ben"
+
+#: plugins/sudoers/logging.c:246
+msgid "user NOT authorized on host"
+msgstr "a felhasználó NINCS felhatalmazva a gépen"
+
+#: plugins/sudoers/logging.c:248
+msgid "command not allowed"
+msgstr "a parancs nem engedélyezett"
+
+#: plugins/sudoers/logging.c:283
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s nincs a sudoers fájlban. Ez az eset jelentésre kerül.\n"
+
+#: plugins/sudoers/logging.c:286
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s nem futtathatja a sudo-t ezen: %s. Ez az eset jelentésre kerül.\n"
+
+#: plugins/sudoers/logging.c:290
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Elnézést, %s felhasználó nem futtathatja a sudo-t ezen: %s.\n"
+
+#: plugins/sudoers/logging.c:293
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:330 plugins/sudoers/sudoers.c:473
+#: plugins/sudoers/sudoers.c:475 plugins/sudoers/sudoers.c:477
+#: plugins/sudoers/sudoers.c:479 plugins/sudoers/sudoers.c:1298
+#: plugins/sudoers/sudoers.c:1300
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: parancs nem található"
+
+#: plugins/sudoers/logging.c:332 plugins/sudoers/sudoers.c:469
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+
+#: plugins/sudoers/logging.c:349
+msgid "authentication failure"
+msgstr "hitelesítési hiba"
+
+#: plugins/sudoers/logging.c:375
+msgid "a password is required"
+msgstr "jelszó szükséges"
+
+#: plugins/sudoers/logging.c:438
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u helytelen jelszópróbálkozás"
+msgstr[1] "%u helytelen jelszópróbálkozás"
+
+#: plugins/sudoers/logging.c:654
+msgid "unable to fork"
+msgstr ""
+
+#: plugins/sudoers/logging.c:662 plugins/sudoers/logging.c:714
+#, c-format
+msgid "unable to fork: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:704
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:729
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:767
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr ""
+
+#: plugins/sudoers/match.c:771
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr ""
+
+#: plugins/sudoers/mkdir_parents.c:70 plugins/sudoers/sudoers.c:944
+#: plugins/sudoers/visudo.c:439 plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to stat %s"
+msgstr "%s nem érhető el"
+
+#: plugins/sudoers/parse.c:115
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr ""
+
+#: plugins/sudoers/parse.c:118
+#, c-format
+msgid "parse error in %s"
+msgstr ""
+
+#: plugins/sudoers/parse.c:544
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+
+#: plugins/sudoers/parse.c:545
+#, c-format
+msgid " RunAsUsers: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:559
+#, c-format
+msgid " RunAsGroups: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:568
+#, c-format
+msgid " Options: "
+msgstr ""
+
+#: plugins/sudoers/policy.c:84 plugins/sudoers/policy.c:110
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:289 plugins/sudoers/testsudoers.c:261
+msgid "unable to parse network address list"
+msgstr ""
+
+#: plugins/sudoers/policy.c:433
+msgid "user name not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:437
+msgid "user ID not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:441
+msgid "group ID not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:445
+msgid "host name not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:793 plugins/sudoers/visudo.c:910
+#, c-format
+msgid "unable to execute %s"
+msgstr "%s nem hajtható végre"
+
+#: plugins/sudoers/policy.c:926
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:928
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:932
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:937
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:938
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:971
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:188 plugins/sudoers/pwutil.c:206
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:200
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:260 plugins/sudoers/pwutil.c:277
+#: plugins/sudoers/pwutil.c:339 plugins/sudoers/pwutil.c:384
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:272
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:503 plugins/sudoers/pwutil.c:521
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:515
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:569 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:633 plugins/sudoers/pwutil.c:675
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:581
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:801 plugins/sudoers/pwutil.c:853
+#: plugins/sudoers/pwutil.c:904 plugins/sudoers/pwutil.c:957
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:807 plugins/sudoers/pwutil.c:858
+#: plugins/sudoers/pwutil.c:910 plugins/sudoers/pwutil.c:962
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:847
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:951
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:113 plugins/sudoers/set_perms.c:469
+#: plugins/sudoers/set_perms.c:912 plugins/sudoers/set_perms.c:1239
+#: plugins/sudoers/set_perms.c:1556
+msgid "perm stack overflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:121 plugins/sudoers/set_perms.c:400
+#: plugins/sudoers/set_perms.c:477 plugins/sudoers/set_perms.c:779
+#: plugins/sudoers/set_perms.c:920 plugins/sudoers/set_perms.c:1163
+#: plugins/sudoers/set_perms.c:1247 plugins/sudoers/set_perms.c:1489
+#: plugins/sudoers/set_perms.c:1564 plugins/sudoers/set_perms.c:1654
+msgid "perm stack underflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:180 plugins/sudoers/set_perms.c:523
+#: plugins/sudoers/set_perms.c:1298 plugins/sudoers/set_perms.c:1596
+msgid "unable to change to root gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:269 plugins/sudoers/set_perms.c:620
+#: plugins/sudoers/set_perms.c:1049 plugins/sudoers/set_perms.c:1375
+msgid "unable to change to runas gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to set runas group vector"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:285 plugins/sudoers/set_perms.c:636
+#: plugins/sudoers/set_perms.c:1063 plugins/sudoers/set_perms.c:1389
+msgid "unable to change to runas uid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:303 plugins/sudoers/set_perms.c:654
+#: plugins/sudoers/set_perms.c:1079 plugins/sudoers/set_perms.c:1405
+msgid "unable to change to sudoers gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1476
+#: plugins/sudoers/set_perms.c:1641
+msgid "too many processes"
+msgstr "túl sok folyamat"
+
+#: plugins/sudoers/solaris_audit.c:51
+msgid "unable to get current working directory"
+msgstr "az aktuális munkakönyvtár lekérése meghiúsult"
+
+#: plugins/sudoers/solaris_audit.c:59
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:66
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:115
+msgid "audit_failure message too long"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:402
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:410 plugins/sudoers/sssd.c:419
+#: plugins/sudoers/sssd.c:428 plugins/sudoers/sssd.c:437
+#: plugins/sudoers/sssd.c:446
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:1562
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: %s\n"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:1567
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: UNKNOWN\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:289
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:307
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:325
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:338
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:168 plugins/sudoers/testsudoers.c:247
+#: plugins/sudoers/visudo.c:233 plugins/sudoers/visudo.c:612
+#: plugins/sudoers/visudo.c:976
+msgid "unable to initialize sudoers default values"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:198 plugins/sudoers/sudoers.c:891
+msgid "problem with defaults entries"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:205
+msgid "no valid sudoers sources found, quitting"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:244
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:301
+msgid "you are not permitted to use the -C option"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:390
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:405
+msgid "no tty"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:406
+msgid "sorry, you must have a tty to run sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:468
+msgid "command in current directory"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:487
+msgid "sorry, you are not allowed set a command timeout"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:495
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:836
+msgid "command too long"
+msgstr "a parancs túl hosszú"
+
+#: plugins/sudoers/sudoers.c:948
+#, c-format
+msgid "%s is not a regular file"
+msgstr "a(z) %s nem egy szabályos fájl"
+
+#: plugins/sudoers/sudoers.c:952 plugins/sudoers/timestamp.c:222 toke.l:969
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s a(z) %u uid tulajdona, ennek kellene lennie: %u"
+
+#: plugins/sudoers/sudoers.c:956 toke.l:974
+#, c-format
+msgid "%s is world writable"
+msgstr "%s bárki számára írható"
+
+#: plugins/sudoers/sudoers.c:960 toke.l:977
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s a(z) %u gid tulajdona, ennek kellene lennie: %u"
+
+#: plugins/sudoers/sudoers.c:993
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1012
+#, c-format
+msgid "unknown login class: %s"
+msgstr "ismeretlen bejelentkezési osztály: %s"
+
+#: plugins/sudoers/sudoers.c:1095 plugins/sudoers/sudoers.c:1109
+#, c-format
+msgid "unable to resolve host %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:275
+#, c-format
+msgid "invalid filter option: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:288
+#, c-format
+msgid "invalid max wait: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:300
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:303 plugins/sudoers/visudo.c:186
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s: %s verzió\n"
+
+#: plugins/sudoers/sudoreplay.c:335
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:357
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:555 plugins/sudoers/sudoreplay.c:602
+#: plugins/sudoers/sudoreplay.c:805 plugins/sudoers/sudoreplay.c:895
+#: plugins/sudoers/sudoreplay.c:974 plugins/sudoers/sudoreplay.c:989
+#: plugins/sudoers/sudoreplay.c:996 plugins/sudoers/sudoreplay.c:1003
+#: plugins/sudoers/sudoreplay.c:1010 plugins/sudoers/sudoreplay.c:1017
+#: plugins/sudoers/sudoreplay.c:1163
+msgid "unable to add event to queue"
+msgstr "az esemény hozzáadása a sorhoz sikertelen"
+
+#: plugins/sudoers/sudoreplay.c:670
+msgid "unable to set tty to raw mode"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:721
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:722
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:750
+msgid "Replay finished, press any key to restore the terminal."
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:783
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1197 plugins/sudoers/sudoreplay.c:1222
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1244
+msgid "unmatched ')' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1248
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1263
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s egy argumentumot igényel"
+
+#: plugins/sudoers/sudoreplay.c:1266 plugins/sudoers/sudoreplay.c:1646
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "érvénytelen reguláris kifejezés: %s"
+
+#: plugins/sudoers/sudoreplay.c:1270
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1279
+msgid "unmatched '(' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1281
+msgid "illegal trailing \"or\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1283
+msgid "illegal trailing \"!\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1332
+#, c-format
+msgid "unknown search type %d"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1370
+#, c-format
+msgid "%s: invalid log file"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1388
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1395
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1402
+#, c-format
+msgid "%s: user field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1411
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1420
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1826
+#, c-format
+msgid "usage: %s [-hnR] [-d dir] [-m num] [-s num] ID\n"
+msgstr "használat: %s [-hnR] [-d kvt] [-m szám] [-s szám] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1829
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "használat: %s [-h] [-d kvt] -l [keresőkifejezés]\n"
+
+#: plugins/sudoers/sudoreplay.c:1838
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - sudo munkamenetek naplójának újrajátszása\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1840
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Beállítások:\n"
+" -d, --directory=kvt munkamenet-naplók könyvtárának megadása\n"
+" -f, --filter=szűrő megjelenítendő I/O típusok megadása\n"
+" -h, --help súgóüzenet megjelenítése és kilépés\n"
+" -l, --list elérhető munkamenet-azonosítók listája, elhagyható\n"
+" kifejezéssel\n"
+" -m, --max-wait=szám események közti várakozás legfeljebb ennyi másodpercig\n"
+" -s, --speed=szám kimenet felgyorsítása vagy lelassítása\n"
+" -V, --version verzióinformációk kiírása és kilépés"
+
+#: plugins/sudoers/testsudoers.c:329
+msgid "\thost unmatched"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:333
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:333
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:230
+#, c-format
+msgid "%s is group writable"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:306
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:772 plugins/sudoers/timestamp.c:839
+#: plugins/sudoers/visudo.c:500 plugins/sudoers/visudo.c:506
+msgid "unable to read the clock"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:786
+msgid "ignoring time stamp from the future"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:798
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:893
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:937 plugins/sudoers/timestamp.c:957
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:188
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:266 plugins/sudoers/visudo.c:667
+#, c-format
+msgid "press return to edit %s: "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:349
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:459 plugins/sudoers/visudo.c:467
+msgid "write error"
+msgstr "íráshiba"
+
+#: plugins/sudoers/visudo.c:513
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:520
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:526
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:548
+#, c-format
+msgid "%s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:607
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr ""
+
+#: plugins/sudoers/visudo.c:619
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:656
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:736 plugins/sudoers/visudo.c:745
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:767
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:781
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:791
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:855
+msgid "What now? "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:869
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:915
+#, c-format
+msgid "unable to run %s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:945
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:952
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:981 plugins/sudoers/visudo_json.c:1021
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:997 plugins/sudoers/visudo_json.c:1032
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1000 plugins/sudoers/visudo_json.c:1035
+#, c-format
+msgid "parse error in %s\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1008 plugins/sudoers/visudo.c:1015
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1062
+#, c-format
+msgid "%s busy, try again later"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1159
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1160
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1164
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1165
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1318
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1433
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - a sudoers fájl biztonságos szerkesztése\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1435
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+" -x, --export=output_file write sudoers in JSON format to output_file"
+msgstr ""
+"\n"
+"Kapcsolók:\n"
+" -c, --check csak ellenőrzés mód\n"
+" -f, --file=sudoers a sudoers fájl helyének megadása\n"
+" -h, --help súgóüzenet megjelenítése és kilépés\n"
+" -q, --quiet kevésbé részletes (csendes) szintaktikai hiba\n"
+" üzenetek\n"
+" -s, --strict szigorú szintaxis-ellenőrzés\n"
+" -V, --version verzióinformációk kiírása és kilépés\n"
+" -x, --export=KIMENETIFÁJL a sudoers kiírása JSON formátumban a\n"
+" KIMENETIFÁJLBA"
+
+#: plugins/sudoers/visudo_json.c:616 plugins/sudoers/visudo_json.c:651
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr ""
+
+#: plugins/sudoers/visudo_json.c:1007
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr ""
+
+#: toke.l:943
+msgid "too many levels of includes"
+msgstr ""
diff --git a/plugins/sudoers/po/it.mo b/plugins/sudoers/po/it.mo
new file mode 100644
index 0000000..4db50a8
--- /dev/null
+++ b/plugins/sudoers/po/it.mo
Binary files differ
diff --git a/plugins/sudoers/po/it.po b/plugins/sudoers/po/it.po
new file mode 100644
index 0000000..41c5dc6
--- /dev/null
+++ b/plugins/sudoers/po/it.po
@@ -0,0 +1,2345 @@
+# Italian translations for sudoers package
+# This file is put in the public domain.
+# Milo Casagrande <milo@milo.name>, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers-1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-31 11:12+0100\n"
+"Last-Translator: Milo Casagrande <milo@milo.name>\n"
+"Language-Team: Italian <tp@lists.linux.it>\n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 2.1.1\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "errore di sintassi"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "password di %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] password di %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Password: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** Informazioni di SICUREZZA per %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Riprovare."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336
+#: gram.y:399 gram.y:407 gram.y:417 gram.y:450 gram.y:457 gram.y:464
+#: gram.y:471 gram.y:553 gram.y:560 gram.y:569 gram.y:578 gram.y:595
+#: gram.y:707 gram.y:714 gram.y:721 gram.y:729 gram.y:829 gram.y:836
+#: gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890 gram.y:897
+#: gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:195 plugins/sudoers/logging.c:511
+#: plugins/sudoers/logging.c:532 plugins/sudoers/logging.c:573
+#: plugins/sudoers/logging.c:752 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr "impossibile allocare memoria"
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr "un digest richiede il nome di percorso"
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr "valore notbefore non valido"
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr "valore notafter non valido"
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr "valore timeout troppo grande"
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr "valore timeout non valido"
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:354 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:511 plugins/sudoers/logging.c:532
+#: plugins/sudoers/logging.c:572 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:724 plugins/sudoers/match.c:771
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1008
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Alias \"%s\" già definito"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "impossibile ottenere la classe di login per l'utente %s"
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr "impossibile iniziare l'autenticazione bsd"
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr "tipo di autenticazione non valida"
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr "impossibile iniziare l'autenticazione BSD"
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr "il proprio account è scaduto"
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr "approvazione non riuscita"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr "impossibile leggere la configurazione fwtk"
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr "impossibile connettersi al server di autenticazione"
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr "connessione al server di autenticazione persa"
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"errore del server di autenticazione:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: impossibile convertire il principal in stringa (\"%s\"): %s"
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: impossibile analizzare \"%s\": %s"
+
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: impossibile risolvere la cache delle credenziali: %s"
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: impossibile allocare le opzioni: %s"
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: impossibile ottenere le credenziali: %s"
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: impossibile inizializzare la cache delle credenziali: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: impossibile memorizzare le credenziali nella cache: %s"
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: impossibile ottenere il principal dell'host: %s"
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: impossibile verificare TGT. Possibile attacco in corso: %s"
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr "impossibile inizializzare PAM"
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Errore autenticazione PAM: %s"
+
+#: plugins/sudoers/auth/pam.c:221
+msgid "account validation failure, is your account locked?"
+msgstr "validazione dell'account non riuscita: forse è bloccato?"
+
+#: plugins/sudoers/auth/pam.c:229
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Account o password scaduto: reimpostare la password e provare nuovamente"
+
+#: plugins/sudoers/auth/pam.c:238
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "impossibile modificare la password scaduta: %s"
+
+#: plugins/sudoers/auth/pam.c:246
+msgid "Password expired, contact your system administrator"
+msgstr "Password scaduta, contattare l'amministratore di sistema"
+
+#: plugins/sudoers/auth/pam.c:250
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Account scaduto o alla configurazione PAM manca una sezione \"account\" per sudo: contattare l'amministratore di sistema"
+
+#: plugins/sudoers/auth/pam.c:257 plugins/sudoers/auth/pam.c:262
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "Errore gestione account PAM: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:232
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "l'utente attuale non esiste nel database %s"
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr "inizializzazione della libreria API ACE non riuscita"
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr "impossibile contattare il server SecurID"
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr "ID utente bloccato per l'autenticazione SecurID"
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr "lunghezza del nome utente per SecurID non valida"
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr "gestore di autenticazione per SecurID non valido"
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr "Comunicazione SecurID non riuscita"
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr "errore sconosciuto di SecurID"
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr "lunghezza del passcode per SecurID errata"
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr "impossibile inizializzare la sessione SIA"
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr "metodi di autenticazione non validi"
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Metodi di autenticazione non validi compilati all'interno di sudo. Non è possibile usare assieme autenticazione standalone e non-standalone."
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr "nessun metodo di autenticazione"
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Non ci sono metodi di autenticazione compilati all'interno di sudo. Per disabilitare l'autenticazione, usare l'opzione di configurazione --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr "Impossibile inizializzare i metodi di autenticazione."
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr "Metodi di autenticazione:"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr "Impossibile determinare la condizione di audit"
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr "impossibile inviare il record di audit"
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Questa lezione dovrebbe essere stata impartita dall'amministratore\n"
+"di sistema locale. Solitamente equivale a:\n"
+"\n"
+" #1) Rispettare la privacy degli altri\n"
+" #2) Pensare prima di digitare\n"
+" #3) Da grandi poteri derivano grandi responsabilità\n"
+"\n"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr "uid sconosciuto: %u"
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1136
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr "utente sconosciuto: %s"
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "ordine di incremento: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "ordine di partenza: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr "ordine di riempimento: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s versione %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s versione grammaticale %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr "formato di input %s non supportato"
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr "formato di output %s non supportato"
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: i file di input e output devono essere diversi"
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:238
+#: plugins/sudoers/visudo.c:594 plugins/sudoers/visudo.c:917
+msgid "unable to initialize sudoers default values"
+msgstr "impossibile inizializzare i valori predefiniti di sudoers"
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: chiave sconosciuta: %s"
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "tipo di defaults non valido: %s"
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "tipo di occultamento non valido: %s"
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr "filtro non valido: %s"
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:913
+#, c-format
+msgid "unable to open %s"
+msgstr "impossibile aprire %s"
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:922
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "analisi del file %s non riuscita, errore sconosciuto"
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:939
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "errore di analisi in %s vicino alla riga %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:942
+#, c-format
+msgid "parse error in %s\n"
+msgstr "errore di analisi in %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr "impossibile scrivere su %s"
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s - Converte tra formati del file sudoers\n"
+"\n"
+"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Opzioni:\n"
+" -b, --base=dn Il DN base per le ricerche LDAP\n"
+" -d, --defaults=tipidef Converte Defaults solo dei tipi indicati\n"
+" -e, --expand-aliases Espande gli alias nella conversione\n"
+" -f, --output-format=formato Imposta il formato di output: JSON, LDIF o sudoers\n"
+" -i, --input-format=format Imposta il formato di input: LDIF o sudoers\n"
+" -I, --increment=num Di quanto incrementare il valore sudoOrder\n"
+" -h, --help Mostra il messaggio di aiuto ed esce\n"
+" -m, --match=filtro Converte le voci che corrispondo al filtro\n"
+" -M, --match-local Il filtro usa i dati da passwd e group\n"
+" -o, --output=file_output Scrive il file convertito su file_output\n"
+" -O, --order-start=num Punto di partenza del primo sudoOrder\n"
+" -p, --prune-matches Elimina utenti, gruppi e host che non corrispondono\n"
+" -P, --padding=num Riempimento base per incrementi di sudoOrder\n"
+" -s, --suppress=sezioni Disabilita l'output per alcune sezioni\n"
+" -V, --version Visualizza la versione ed esce"
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "voce Defaults \"%s\" sconosciuta"
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr "impossibile ottenere l'ora GMT"
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr "impossibile formattare la marcatura temporale"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1015 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "errore interno, overflow di %s"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr "troppe voci sudoers, massimo %u"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "la variabile d'ambiente SUDOERS_BASE non è impostata e non è stata specificata l'opzione -b."
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Infrastruttura syslog se syslog viene utilizzato per le registrazioni: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Priorità di syslog se l'utente si identifica con successo: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Priorità di syslog se l'utente non si identifica con successo: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "Mette il prompt OTP su una riga a parte"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "Ignora \".\" in $PATH"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "Invia sempre una email quando viene eseguito sudo"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "Invia una email se l'autenticazione utente non riesce"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "Invia una email se l'utente non è tra i sudoers"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Invia una email se l'utente non è tra i sudoers per questo host"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Invia una email se l'utente non è abilitato a eseguire un comando"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "Invia una email se l'utente tenta di eseguire un comando"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Usa una marcatura temporale diversa per ogni combinazione utente/tty"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "Aiuta gli utenti alla prima esecuzione di sudo"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "File contenente la lezione su sudo: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "Richiede in modo predefinito l'autenticazione degli utenti"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "Root può eseguire sudo"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Registra il nome host nel file di registro (non-syslog)"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Registra l'anno nel file di registro (non-syslog)"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Se sudo viene lanciato senza alcun argomento, avvia una shell"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Imposta $HOME all'utente definito quando viene avviata una shell con -s"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Imposta sempre $HOME alla directory home dell'utente definito"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Consente la raccolta di alcune informazioni per dare messaggi di errore utili"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Richiede nomi host completi nel file sudoers"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Apostrofa l'utente quando inserisce una password errata"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Consente all'utente di seguire sudo solo se dispone di un tty"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "visudo utilizzerà il valore definito nella variabile EDITOR"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "Chiede la password di root, non quella dell'utente"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Chiede la password dell'utente runas_default, non quella dell'utente"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Chiede la password dell'utente definito, non quella dell'invocante"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Applica i Defaults nella classe di login dell'utente definito, se presente"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Imposta le variabili d'ambiente LOGNAME e USER"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Imposta lo uid effettivo all'utente definito, non lo uid reale"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Non inizializza il vettore di gruppo con quello dell'utente definito"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Lunghezza a cui andare a capo nei file di registro (0 per non andare a capo): %u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Timeout marcatura temporale di autenticazione: %.1f minuti"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Timeout per inserimento password: %.1f minuti"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Numero di tentativi per l'inserimento della password: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "umask da utilizzare o 0777 per utilizzare quella dell'utente: 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Percorso al file di registro: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Percorso al programma email: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Flag per il programma email: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Indirizzo a cui mandare l'email: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Indirizzo da cui mandare l'email: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Oggetto dell'email: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Messaggio password errata: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Percorso directory di stato della lezione: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Percorso directory con la marcatura temporale di autenticazione: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Proprietario directory con la marcatura temporale di autenticazione: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Agli utenti di questo gruppo non sono richiesti password e PATH: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Prompt predefinito per la password: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Se impostato, passprompt scavalcherà sempre il prompt di sistema."
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Utente predefinito con cui eseguire i comandi: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Valore con cui sovrascrivere la variabile $PATH dell'utente: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Percorso all'editor per visudo: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Quando richiedere una password per il pseudo-comando \"list\": %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Quando richiedere una password per il pseudo-comando \"verify\": %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Pre-carica le funzioni exec dummy contenute nella libreria sudo_noexec"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Se LDAP è funzionante, viene ignorato il file sudoers locale"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "I descrittori di file >= %d verranno chiusi prima dell'esecuzione di un comando"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Se impostata, gli utenti possono sovrascrivere il valore di \"closefrom\" con l'opzione -C"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Consente agli utenti di impostare variabili d'ambiente"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "Reimposta l'ambiente con le variabili predefinite"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "Variabile d'ambienti da validare:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "Variabili d'ambiente da rimuovere:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "Variabili d'ambiente da preservare:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Ruolo SELinux da usare nel nuovo contesto di sicurezza: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Tipologia di SELinux da usare nel nuovo contesto di sicurezza: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Percorso al file d'ambiente specifico di sudo: %s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Percorso al file d'ambiente riservato specifico di sudo: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Localizzazione da usare durante l'analisi del file sudoers: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Abilita sudo a chiedere una password anche se sarebbe visibile"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Fornisce riscontro visibile al prompt della password nel caso di input utente"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Usa glob più veloce e meno preciso, ma non accede al file system"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "La umask definita in sudoers scavalca quella dell'utente, anche se è più permissiva"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "Registra l'input dell'utente per il comando in esecuzione"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "Registra l'output del comando in esecuzione"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "Comprime i registri utilizzando zlib"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "Esegue sempre i comandi in uno pseudo-tty"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Plugin per supporto ai gruppi non-Unix: %s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Directory in cui salvare i registri di I/O: %s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "File in cui salvare il registro I/O: %s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Aggiunge una voce al file utmp/utmpx quando viene allocato un pty"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Imposta l'utente in utmp all'utente runas, non l'utente invocante"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Insieme di privilegi concessi: %s"
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Insieme di privilegi non concessi: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "Esegue i comandi in un pty in background"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "Nome del servizio PAM da usare: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "Nome del servizio PAM da usare per le shell di login: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Tentativo di stabilire le credenziali PAM per l'utente finale"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "Crea una nuova sessione PAM in cui eseguire il comando"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Numero massimo di sequenze I/O di registro: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "Abilita support netgroup in sudoers"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Controlla le directory superiori per accesso in scrittura durante le modifiche con sudoedit"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Segue i collegamenti simbolici durante le modifiche con sudoedit"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "Interroga il plugin dei gruppi per gruppi di sistema sconosciuti"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Corrispondenza gruppi di rete con tutti i valori: utente, host e dominio"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Consente di eseguire i comandi anche se sudo non può scrivere sul registro di controllo"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Consente di eseguire i comandi anche se sudo non può scrivere sul registro di I/O"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Consente di eseguire i comandi anche se sudo non può scrivere sul file di registro"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Gestisce i gruppi attraverso sudoers ed esegue la corrispondenza sull'ID del gruppo, non sul nome"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Voci di registro più grandi di questo valore vengono divise su più messaggi: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Utente proprietario dei file di registro di I/O: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Gruppo proprietario dei file di registro di I/O: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Modalità dei file di registro di I/O: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Esegue comandi in base al descrittore del file e non sul percorso: %s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Ignora le voci Defaults sconosciute nel file sudoers invece di inviare un avviso"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Tempo in secondi dopo il quale il comando viene terminato: %u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Consente all'utente di specificare un timeout attraverso la riga di comando"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Scrive immediatamente i dati I/O del registro sul disco invece di tenerli in memoria"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "Include l'ID del processo quando viene usato syslog"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Tipo di marcatura temporale di autenticazione: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "Messaggio di autenticazione non riuscita: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "Ignora maiuscole/minuscole nella corrispondenza coi nomi utente"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "Ignora maiuscole/minuscole nella corrispondenza coi gruppi"
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d voce Defaults \"%s\" sconosciuta"
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: voce Defaults \"%s\" sconosciuta"
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d nessun valore specificato per \"%s\""
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: nessun valore specificato per \"%s\""
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d i valori per \"%s\" devono iniziare con un carattere \"/\""
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: i valori per \"%s\" devono iniziare con un carattere \"/\""
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d l'opzione \"%s\" non accetta un valore"
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: l'opzione \"%s\" non accetta un valore"
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d tipo Defaults 0x%x non valido per l'opzione \"%s\""
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: tipo Defaults 0x%x non valido per l'opzione \"%s\""
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d il valore \"%s\" non è valido per l'opzione \"%s\""
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: il valore \"%s\" non è valido per l'opzione \"%s\""
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: envp danneggiato, discordanza nella lunghezza"
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr "impossibile ricostruire l’ambiente"
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "permessi non sufficienti per impostare le seguenti variabili d'ambiente: %s"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "errore di analisi in %s vicino alla riga %d"
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "errore di analisi in %s"
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "tipo di digest %d non supportato per %s"
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr "%s: errore di lettura"
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s deve essere di proprietà dello uid %d"
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s deve essere scrivibile solo dal proprietario"
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "impossibile caricare %s: %s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "impossibile trovare il simbolo \"group_plugin\" in %s"
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: version major %d del plugin per il gruppo non compatibile, atteso %d"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "impossibile analizzare l'indirizzo IP \"%s\""
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "impossibile analizzare la maschera di rete \"%s\""
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Coppia indirizzo IP locale e maschera di rete:\n"
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s esiste, ma non è una directory (0%o)"
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "impossibile creare la directory %s"
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:723
+#: plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "impossibile modificare la modalità di %s a 0%o"
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1167
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr "gruppo sconosciuto: %s"
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr "impossibile leggere %s"
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr "impossibile creare %s"
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "impossibile scrivere sul file di registro di I/O: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr "%s: errore interno, file registro IO per l'evento %d non aperto"
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr "%s: errore interno, segnale %d non valido"
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: file di registro non valido"
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: manca il campo della marcatura temporale"
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: marcatura temporale %s: %s"
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: manca il campo utente"
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: manca il campo utente di runas"
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: manca il campo gruppo di runas"
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr "starttls non supportato quando viene utilizzato ldaps"
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "impossibile inizializzare il certificato SSL e il database delle chiavi: %s"
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "è necessario impostare TLS_CERT in %s per usare SSL"
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "impossibile inizializzare LDAP: %s"
+
+#: plugins/sudoers/ldap.c:1648
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "specificato start_tls ma le librerie LDAP non supportano ldap_start_tls_s() o ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "attributo sudoOrder non valido: %s"
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: porta troppo grande"
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "tipologia di uri LDAP non supportata: %s"
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "impossibile utilizzare URI ldap e ldaps assieme"
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "impossibile convertire sudoOption: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "impossibile aprire il sistema di audit"
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr "impossibile inviare il messaggio di audit"
+
+#: plugins/sudoers/logging.c:113
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:141
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (comando continuato) %s"
+
+#: plugins/sudoers/logging.c:170
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "impossibile aprire il file di registro: %s"
+
+#: plugins/sudoers/logging.c:178
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "impossibile impostare il blocco sul file di registro: %s"
+
+#: plugins/sudoers/logging.c:211
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "impossibile scrivere sul file di registro: %s"
+
+#: plugins/sudoers/logging.c:240
+msgid "No user or host"
+msgstr "Nessun utente o host"
+
+#: plugins/sudoers/logging.c:242
+msgid "validation failure"
+msgstr "validazione non riuscita"
+
+#: plugins/sudoers/logging.c:249
+msgid "user NOT in sudoers"
+msgstr "utente non tra i sudoers"
+
+#: plugins/sudoers/logging.c:251
+msgid "user NOT authorized on host"
+msgstr "utente non autorizzato sull'host"
+
+#: plugins/sudoers/logging.c:253
+msgid "command not allowed"
+msgstr "comando non consentito"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s non è nel file sudoers. Questo evento verrà segnalato.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "A %s non è consentito eseguire sudo su %s. Questo evento verrà segnalato.\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "L'utente %s non può eseguire sudo su %s.\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "All'utente %s non è consentito eseguire \"%s%s%s\" come %s%s%s su %s.\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: comando non trovato"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"viene ignorato \"%s\" trovato in \".\"\n"
+"Usare \"sudo ./%s\" per eseguire \"%s\"."
+
+#: plugins/sudoers/logging.c:354
+msgid "authentication failure"
+msgstr "autenticazione non riuscita"
+
+#: plugins/sudoers/logging.c:380
+msgid "a password is required"
+msgstr "è necessaria una password"
+
+#: plugins/sudoers/logging.c:443
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u tentativo di immissione password non corretto"
+msgstr[1] "%u tentativi di immissione password non corretti"
+
+#: plugins/sudoers/logging.c:666
+msgid "unable to fork"
+msgstr "impossibile eseguire fork"
+
+#: plugins/sudoers/logging.c:674 plugins/sudoers/logging.c:726
+#, c-format
+msgid "unable to fork: %m"
+msgstr "impossibile eseguire fork: %m"
+
+#: plugins/sudoers/logging.c:716
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "impossibile aprire una pipe: %m"
+
+#: plugins/sudoers/logging.c:741
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "impossibile eseguire dup sullo stdin: %m"
+
+#: plugins/sudoers/logging.c:779
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "impossibile eseguire %s: %m"
+
+#: plugins/sudoers/match.c:874
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "il digest per %s (%s) non è nella forma %s"
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:421 plugins/sudoers/visudo.c:717
+#, c-format
+msgid "unable to stat %s"
+msgstr "impossibile eseguire stat su %s"
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"Ruolo LDAP: %s\n"
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Voce sudoers:\n"
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr " RunAsUsers: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr " RunAsGroups: "
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr " Opzioni: "
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr " Comandi:\n"
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Corrispondenza voci Defaults per %s su %s:\n"
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Valori predefiniti per Runas e Command per %s:\n"
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "L'utente %s può eseguire i seguenti comandi su %s:\n"
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "L'utente %s non è abilitato all'esecuzione di sudo su %s.\n"
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "valore attributo non valido ignorato: %s"
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "ignorato sudoRole non completo: cn: %s"
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "%.*s non valido impostato dal front-end sudo"
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr "impossibile analizzare l'elenco degli indirizzi di rete"
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr "nome utente non impostato dal front-end sudo"
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr "ID utente non impostato dal front-end sudo"
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr "ID gruppo non impostato dal front-end sudo"
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr "nome dell'host non impostato dal front-end sudo"
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:220
+#: plugins/sudoers/visudo.c:851
+#, c-format
+msgid "unable to execute %s"
+msgstr "impossibile eseguire %s"
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Versione %s del plugin della politica sudoers\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Versione %d della grammatica del file sudoers\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Percorso sudoers: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "percorso nsswitch: %s\n"
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "percorso ldap.conf: %s\n"
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "percorso ldap.secret: %s\n"
+
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "impossibile registrare un hook di tipo %d (versione %d.%d)"
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "impossibile memorizzare in cache lo uid %u, memoria esaurita"
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "impossibile memorizzare in cache lo uid %u, esiste già"
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "impossibile memorizzare in cache l'utente %s, memoria esaurita"
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "impossibile memorizzare in cache l'utente %s, esiste già"
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "impossibile memorizzare in cache il gid %u, memoria esaurita"
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "impossibile memorizzare in cache il gid %u, esiste già"
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "impossibile memorizzare in cache il gruppo %s, memoria esaurita"
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "impossibile memorizzare in cache il gruppo %s, esiste già"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "impossibile memorizzare in cache l'elenco di gruppo %s, esiste già"
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "impossibile memorizzare in cache l'elenco di gruppo %s, memoria esaurita"
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "impossibile analizzare i gruppi per %s"
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "impossibile analizzare i gid per %s"
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr "overflow dello stack perm"
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr "underflow dello stack perm"
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr "impossibile passare al gid root"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr "impossibile passare al gid runas"
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr "impossibile impostare il vettore di gruppo per runas"
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr "impossibile passare allo uid runas"
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr "impossibile passare al gid sudoers"
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr "troppi processi"
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr "impossibile ottenere la directory di lavoro corrente"
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "percorso audit user_cmnd troncato: %s"
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "percorso audit argv[0] troncato: %s"
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr "messaggio audit_failure troppo lungo"
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "impossibile inizializzare la sorgente SSS. È stato installato SSSD?"
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "impossibile trovare il simbolo \"%s\" in %s"
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr "problema con le voci Defaults"
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr "nessuna sorgente valida di sudoers trovata, uscita"
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers indica che a root non è consentito usare sudo"
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr "utente non abilitato all'uso dell'opzione -C"
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "proprietario marcatura temporale (%s): utente inesistente"
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr "nessun tty"
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr "è necessario disporre di un tty per eseguire sudo"
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr "comando nella directory corrente"
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "non è consentito impostare un timeout per i comandi"
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "non è consentito preservare l'ambiente"
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr "comando troppo lungo"
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s non è un file regolare"
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s è di proprietà dello uid %u, dovrebbe essere %u"
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr "%s è scrivibile da tutti"
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s è di proprietà del gid %u, dovrebbe essere %u"
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "solo root può usare \"-c %s\""
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr "classe di login sconosciuta: %s"
+
+#: plugins/sudoers/sudoers.c:1069 plugins/sudoers/sudoers.c:1083
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "impossibile risolvere l'host %s"
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "opzione di filtro non valida: %s"
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "attesa massima non valida: %s"
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "fattore di velocità non valido: %s"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/timing: %s"
+
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/timing: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Riproduzione della sessione sudo: %s"
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr "impossibile aggiungere l'evento alla coda"
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr "impossibile impostare il terminale in modalità raw"
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Attenzione: il terminale è troppo piccolo per riprodurre correttamente il registro.\n"
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "La geometria del registro è %dx%d, quella del terminale è %dx%d."
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Riproduzione terminata. Premere un tasto per ripristinare il terminale."
+
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "riga di timing del file non valida: %s"
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "espressione \"%s\" ambigua"
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr "carattere \")\" nell'espressione non corrisposto"
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "termine di ricerca \"%s\" sconosciuto"
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s richiede un argomento"
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "espressione regolare non valida: %s"
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "impossibile analizzare la data \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr "carattere \"(\" nell'espressione non corrisposto"
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr "\"or\" finale non consentito"
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr "carattere \"!\" finale non consentito"
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr "tipo di ricerca %d sconosciuto"
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr "uso: %s [-hnRS] [-d DIR] [-m NUM] [-s NUM] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "uso: %s [-h] [-d DIR] -l [ESPRESSIONE DI RICERCA]\n"
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - Riproduce i registri di sessione di sudo\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Opzioni:\n"
+" -d, --directory=DIR Specifica la directory per i registri di sessione\n"
+" -f, --filter=FILTRO Specifica il tipo di I/O da mostrare\n"
+" -h, --help Visualizza il messaggio di aiuto ed esce\n"
+" -l, --list Elenca gli ID di sessione disponibili corrispondenti\n"
+" -m, --max-wait=NUME Secondi da attendere tra gli eventi\n"
+" -S, --suspend-wait Attende mentre il comando è sospeso\n"
+" -s, --speed=NUME Velocizza o rallenta l'output\n"
+" -V, --version Visualizza la versione ed esce"
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr "\thost non corrispondente"
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Comando consentito"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Comando negato"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Comando non corrispondente"
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr "%s è scrivibile da tutti"
+
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "impossibile troncare il file della marcatura temporale a %lld byte"
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:482 plugins/sudoers/visudo.c:488
+msgid "unable to read the clock"
+msgstr "impossibile leggere l'orologio"
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr "marcatura temporale dal futuro ignorata"
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "marcatura temporale troppo avanti nel tempo: %20.20s"
+
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "impossibile bloccare il file della marcatura temporale %s"
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "percorso marcatura temporale troppo lungo: %s %s"
+
+#: plugins/sudoers/visudo.c:216
+msgid "the -x option will be removed in a future release"
+msgstr "l'opzione -x verrà rimossa in una prossima versione"
+
+#: plugins/sudoers/visudo.c:217
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "utilizzare lo strumento cvtsudoers al suo posto"
+
+#: plugins/sudoers/visudo.c:268 plugins/sudoers/visudo.c:650
+#, c-format
+msgid "press return to edit %s: "
+msgstr "premere Invio per modificare %s: "
+
+#: plugins/sudoers/visudo.c:329
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "l'editor specificato (%s) non esiste"
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "nessun editor trovato (percorso dell'editor = %s)"
+
+#: plugins/sudoers/visudo.c:441 plugins/sudoers/visudo.c:449
+msgid "write error"
+msgstr "errore di scrittura"
+
+#: plugins/sudoers/visudo.c:495
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "impossibile eseguire stat sul file temporaneo (%s), %s non modificato"
+
+#: plugins/sudoers/visudo.c:502
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "file temporaneo di lunghezza pari a zero (%s), %s non modificato"
+
+#: plugins/sudoers/visudo.c:508
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "editor (%s) non riuscito, %s non modificato"
+
+#: plugins/sudoers/visudo.c:530
+#, c-format
+msgid "%s unchanged"
+msgstr "%s non modificato"
+
+#: plugins/sudoers/visudo.c:589
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "impossibile riaprire il file temporaneo (%s), %s non modificato."
+
+#: plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "impossibile analizzare il file temporaneo (%s), errore sconosciuto"
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "errore interno, impossibile trovare %s nell'elenco."
+
+#: plugins/sudoers/visudo.c:719 plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "impossibile impostare (uid, gid) di %s a (%u, %u)"
+
+#: plugins/sudoers/visudo.c:751
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s e %s non sono sullo stesso file system, viene usato \"mv\" per rinominare"
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "comando non riuscito: \"%s %s %s\", %s non modificato"
+
+#: plugins/sudoers/visudo.c:775
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "errore nel rinominare %s, %s non è stato modificato"
+
+#: plugins/sudoers/visudo.c:796
+msgid "What now? "
+msgstr "Che fare ora? "
+
+#: plugins/sudoers/visudo.c:810
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Le opzioni sono:\n"
+" (e) Modifica nuovamente il file sudoers\n"
+" (x) Esce senza salvare le modifiche al file sudoers\n"
+" (Q) Esce e salva le modifiche al file sudoers (pericoloso)\n"
+
+#: plugins/sudoers/visudo.c:856
+#, c-format
+msgid "unable to run %s"
+msgstr "impossibile avviare %s"
+
+#: plugins/sudoers/visudo.c:886
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: proprietario errato (uid, gid), dovrebbe essere (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: permessi errati, dovrebbe avere modalità 0%o\n"
+
+#: plugins/sudoers/visudo.c:950 plugins/sudoers/visudo.c:957
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: analisi effettuata correttamente\n"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s occupato, riprovare"
+
+#: plugins/sudoers/visudo.c:979
+#, c-format
+msgid "unable to lock %s"
+msgstr "impossibile bloccare %s"
+
+#: plugins/sudoers/visudo.c:980
+msgid "Edit anyway? [y/N]"
+msgstr "Modificare comunque? [y/N]"
+
+#: plugins/sudoers/visudo.c:1064
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Errore: %s:%d ciclo in %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1065
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Attenzione: %s:%d ciclo in %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1069
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Attenzione: %1$s:%2$d riferimento a \"%4$s\" %3$s, ma non definito"
+
+#: plugins/sudoers/visudo.c:1070
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Attenzione: %1$s:%2$d riferimento a \"%4$s\" %3$s, ma non definito"
+
+#: plugins/sudoers/visudo.c:1161
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Attenzione %s:%d inutilizzato %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1276
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr "%s - Modifica in sicurezza il file sudoers\n"
+
+#: plugins/sudoers/visudo.c:1278
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"Opzioni:\n"
+" -c, --check Modalità solo verifica\n"
+" -f, --file=sudoers Specifica la posizione del file sudoers\n"
+" -h, --help Visualizza il messaggio di aiuto ed esce\n"
+" -q, --quiet Messaggi di errore meno prolissi\n"
+" -s, --strict Verifica precisa della sintassi\n"
+" -V, --version Visualizza la versione ed esce\n"
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr "troppi livelli di inclusioni"
diff --git a/plugins/sudoers/po/ja.mo b/plugins/sudoers/po/ja.mo
new file mode 100644
index 0000000..decf1cb
--- /dev/null
+++ b/plugins/sudoers/po/ja.mo
Binary files differ
diff --git a/plugins/sudoers/po/ja.po b/plugins/sudoers/po/ja.po
new file mode 100644
index 0000000..10a6fd3
--- /dev/null
+++ b/plugins/sudoers/po/ja.po
@@ -0,0 +1,2525 @@
+# Japanese messages for sudoers
+# This file is put in the public domain.
+# Yasuaki Taniguchi <yasuakit@gmail.com>, 2011.
+# Takeshi Hamasaki <hmatrjp@users.sourceforge.jp>, 2012, 2015, 2016, 2017, 2018
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-12-09 19:18+0900\n"
+"Last-Translator: Takeshi Hamasaki <hmatrjp@users.sourceforge.jp>\n"
+"Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Poedit-Basepath: sudo-1.8.23b2\n"
+"X-Generator: Poedit 2.1.1\n"
+"X-Poedit-SearchPath-0: .\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "構文エラー"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "%p のパスワード:"
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] %p のパスワード:"
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "パスワード: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** %h のセキュリティ情報 ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "残念、また試してください。"
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336
+#: gram.y:399 gram.y:407 gram.y:417 gram.y:450 gram.y:457 gram.y:464
+#: gram.y:471 gram.y:553 gram.y:560 gram.y:569 gram.y:578 gram.y:595
+#: gram.y:707 gram.y:714 gram.y:721 gram.y:729 gram.y:829 gram.y:836
+#: gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890 gram.y:897
+#: gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:195 plugins/sudoers/logging.c:511
+#: plugins/sudoers/logging.c:532 plugins/sudoers/logging.c:573
+#: plugins/sudoers/logging.c:752 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr "メモリ割り当てを行えませんでした"
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr "認証方式にはパスが必要です"
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr "notbefore の値が無効です"
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr "notafter の値が無効です"
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr "制限時間の値が大き過ぎます"
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr "時間制限値が無効です"
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:354 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:511 plugins/sudoers/logging.c:532
+#: plugins/sudoers/logging.c:572 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:724 plugins/sudoers/match.c:771
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1008
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "別名 \"%s\" はすでに定義されています"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "ユーザー%s のログインクラスを得ることができません"
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr "BSD 認証を開始できません"
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr "無効な認証タイプです"
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr "BSD 認証を開始できません"
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr "あなたのアカウントの有効期限が切れています"
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr "認証に失敗しました"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr "fwtk 設定を読み込めません"
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr "認証サーバーに接続できません"
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr "認証サーバーへの接続が失われました"
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"認証サーバーエラーです:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: プリンシパルを文字列('%s')に変換できません: %s"
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: '%s' を構文解析できません: %s"
+
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: 資格情報キャッシュ を解決できません: %s"
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: オプションを設定できません: %s"
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: 資格情報を取得できません: %s"
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: 資格情報キャッシュ を初期化できません: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: 資格情報をキャッシュできません: %s"
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: ホストプリンシパルを取得できません: %s"
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: TGT を検証できません! おそらく攻撃です!: %s"
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr "PAM を初期化できません"
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "PAM 認証エラーです: %s"
+
+#: plugins/sudoers/auth/pam.c:221
+msgid "account validation failure, is your account locked?"
+msgstr "アカウントの有効性検証に失敗しました。あなたのアカウントはロックされていませんか?"
+
+#: plugins/sudoers/auth/pam.c:229
+msgid "Account or password is expired, reset your password and try again"
+msgstr "アカウントまたはパスワードが期限切れです。パスワードをリセットして再試行してください"
+
+#: plugins/sudoers/auth/pam.c:238
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "期限の切れたパスワードを変更できません: %s"
+
+#: plugins/sudoers/auth/pam.c:246
+msgid "Password expired, contact your system administrator"
+msgstr "パスワードが期限切れです。システム管理者に連絡してください"
+
+#: plugins/sudoers/auth/pam.c:250
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "アカウントの期限切れ、または sudo 用の PAM 設定に \"account\" セクションがありません。システム管理者に連絡してください"
+
+#: plugins/sudoers/auth/pam.c:257 plugins/sudoers/auth/pam.c:262
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "PAM アカウント管理エラーです: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:232
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "あなたは %s データベース内に存在しません"
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr "ACE API ライブラリの初期化に失敗しました"
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr "SecurID サーバーに接続できません"
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr "SecurID 認証のユーザーIDがロックされています"
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr "SecurID 用のユーザー名の長さが無効です"
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr "SecurID 用の認証ハンドルが無効です"
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr "SecurID 通信に失敗しました"
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr "不明な SecurID エラーです"
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr "SecurID 用のパスコード長が無効です"
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr "SIA セッションを初期化できません"
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr "無効な認証方法"
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "無効な認証方法が sudo のコンパイル時に組み込まれています! スタンドアローンと非スタンドアローン認証を混在させてはいけません。"
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr "認証方法がありません"
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "認証方法が sudo のコンパイル時に組み込まれていません! 認証を無効にする場合には、configure オプションで --disable-authentication を指定してください。"
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr "認証方法を初期化できません。"
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr "認証方法:"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr "監査条件を決定できませんでした"
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr "監査レコードをコミットできません"
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"あなたはシステム管理者から通常の講習を受けたはずです。\n"
+"これは通常、以下の3点に要約されます:\n"
+"\n"
+" #1) 他人のプライバシーを尊重すること。\n"
+" #2) タイプする前に考えること。\n"
+" #3) 大いなる力には大いなる責任が伴うこと。\n"
+"\n"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr "不明なユーザーID (uid) です: %u"
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1136
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr "不明なユーザーです: %s"
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "order の増分: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "開始の order: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr "order の増分: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s バージョン %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s 文法バージョン %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr "サポートされてない入力形式です %s"
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr "サポートされてない出力形式です %s"
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: 入力ファイルと出力ファイルは別である必要があります"
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:238
+#: plugins/sudoers/visudo.c:594 plugins/sudoers/visudo.c:917
+msgid "unable to initialize sudoers default values"
+msgstr "sudoers のデフォルト値を初期化できません"
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: 不明なキーワードです: %s"
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "無効なデフォルトの指定です: %s"
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "無効な抑制の指定です: %s"
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr "無効なフィルターです: %s"
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:913
+#, c-format
+msgid "unable to open %s"
+msgstr "%s を開けません"
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:922
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "%s ファイルの構文解析に失敗しました。不明なエラーです"
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:939
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "%s 内 %d 行付近で構文解析エラーが発生しました\n"
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:942
+#, c-format
+msgid "parse error in %s\n"
+msgstr "%s 内で構文解析エラーが発生しました\n"
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr "%s へ書き込むことができません"
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s - sudoers ファイル形式間での変換を行う\n"
+"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"オプション:\n"
+" -b, --base=dn sudo の LDAP クエリ のベース DN\n"
+" -d, --defaults=deftypes 指定した形式の Defaults のみを変換する\n"
+" -e, --expand-aliases 変換する時にエイリアスを展開する\n"
+" -f, --output-format=format 出力の書式: JSON, LDIF または sudoers\n"
+" -i, --input-format=format 入力の書式: LDIF または sudoers\n"
+" -I, --increment=num それぞれの sudoOrder の増分\n"
+" -h, --help ヘルプメッセージを表示して終了する\n"
+" -m, --match=filter filter にマッチするエントリのみを変換する\n"
+" -M, --match-local フィルタは passwd および group データベースを使用する\n"
+" -o, --output=output_file 変換された sudoers を output_file に出力する\n"
+" -O, --order-start=num 最初の sudoOrder の開始点\n"
+" -p, --prune-matches マッチしないユーザー、グループ、ホストを取り除く\n"
+" -P, --padding=num base padding for sudoOrder の増分\n"
+" -s, --suppress=sections いくつかのセクションの出力を抑制する\n"
+" -V, --version バージョン情報を表示して終了する"
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "不明なデフォルト項目 \"%s\" です"
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr "GMT 時刻を取得できません"
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr "タイムスタンプを書式整形できません"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1015 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "内部エラー、%s がオーバーフローしました"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr "sudoers の項目が多すぎます、最大は %u です。"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "SUDOERS_BASE 環境変数が設定されておらず -b オプションも指定されていません。"
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "ログ記録時に syslog を使用する場合の syslog facility: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "ログ記録時に syslog を使用する場合の syslog priority: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "ユーザー認証に失敗したと時に使用される syslog priority: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "ワンタイムパスワード入力要求をそれのみの行に表示します"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "$PATH 内にある '.' を無視します"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "sudo を実行した時に、常にメールを送信します"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "ユーザー認証に失敗した場合にメールを送信します"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "ユーザー他 sudoers 内に存在しない場合にメールを送信します"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "ユーザーがこのホスト用の sudoers 内に存在しない場合にメールを送信します"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "ユーザーが許可されていないコマンドを実行しようとした場合にメールを送信します"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "ユーザーがマンドを実行しようとした場合にメールを送信します"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "ユーザー/tty の組み合わせごとに分離したタイムスタンプを使用します"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "ユーザーが最初に sudo を実行した時に講義を行う"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "sudo の講義が含まれているファイル: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "デフォルトでユーザーが認証されていることを必要とします"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "root が sudo を実行するかもしれません"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr " ログファイル (syslog 以外) に記録する時にホスト名を含めます"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "ログファイル (syslog 以外) に記録する時に年情報を含めます"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "sudo を引数無しで起動した場合、シェルを開始します"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "シェルを -s で開始した時に $HOME を変更後のユーザーのホームディレクトリに設定します"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "$HOME を常に変更後のユーザーのホームディレクトリに設定します"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "役に立つエラーメッセージを表示するためにいくつかの情報を収集することを許可します"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "sudoers ファイルに完全修飾ホスト名 (FQDN) を要求します"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "間違ったパスワードを入力した時にユーザーを侮辱します"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "tty がある場合のみ sudo の実行を許可します"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "visudo が EDITOR 環境変数を尊重して使用します"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "ユーザーのパスワードではなく、root のパスワードの入力を要求します"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "ユーザーのパスワードではなく、 runas_default ユーザーのパスワードの入力を要求します"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "現在のユーザーのパスワードではなく、変更先ユーザーのパスワードの入力を要求します"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "変更先ユーザーのログインクラスのデフォルトが存在する場合は、デフォルトを適用します"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "LOGNAME および USER 環境変数を設定します"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "実効ユーザーIDのみ変更先ユーザーの UID に設定し、実ユーザーIDは変更しない"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "グループベクトルを変更先ユーザーの値で初期化しない"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "ログファイルの行頭から改行までの長さ (0 の場合は改行しない): %u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "認証タイムスタンプのタイムアウト値: %.1f 分"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "パスワード入力要求のタイムアウト値: %.1f 分"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "パスワード入力の試行回数: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "使用する umask 値 (0777 の場合はユーザーの設定値を使用します): 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "ログファイルのパス: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "メールプログラムのパス: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "メールプログラムの引数フラグ: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "メールの送信先アドレス: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "メールの送信元アドレス: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "メールの件名 (Subject) 行: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "パスワードを間違った時のメッセージ: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "受講状況ディレクトリのパス: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "認証タイムスタンプディレクトリのパス: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "認証タイムスタンプディレクトリの所有者: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "パスワード入力と PATH の要求が免除されるグループに属するユーザー: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "パスワード入力要求時に表示される文字列: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "設定した場合、すべての場合において passprompt がシステムの入力要求表示を上書きします"
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "コマンドを実行するデフォルトの変更先ユーザー: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "ユーザーの $PATH を上書きする時の値: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "visudo で使用されるエディターのパス: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "'list' 疑似コマンド使用するためにパスワードを要求される時: %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "'verify' 疑似コマンドを使用するためにパスワードを要求される時: %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "sudo_noexec ライブラリに含まれるダミーの exec 関数群を事前ロードします"
+
+# do はたぶん強調の do
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "LDAP ディレクトリが実行中の場合、ローカルの sudoers ファイルを無視します"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "%d 以上の値をもつファイル記述子をコマンド実行前に閉じます"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "設定した場合、ユーザーが `closefrom' の値を -C オプションで上書きするかもしれません"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "ユーザーが任意の環境変数を設定することを許可します"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "環境変数の集合をデフォルトに設定します"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "正当性の確認を行う環境変数:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "削除する環境変数:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "保護する環境変数:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "新しいセキュリティコンテキスト内で使用する SELinux の役割: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "新しいセキュリティコンテキスト内で使用する SELinux のタイプ: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "sudo 固有の環境ファイルのパス: %s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "制限付きsudo 固有の環境ファイルのパス: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "sudoers を構文解析する時に使用するロケール: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "パスワードが表示されてしまう状態であっても sudo がパスワード入力を要求することを許可します"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "パスワード入力要求でユーザーの入力があった時に、視覚的なフィードバックを提供します"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "ファイルシステムにアクセスしないがより正確では無い、素早い一致確認処理を行います"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "sudoers で指定した umask 値でユーザーの umask 値を上書きします (ユーザーの umask 値より緩い場合でも)"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "コマンドを実行した時のユーザー入力をログに記録します"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "コマンドを実行した時の出力をログに記録します"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "I/O ログを zlib を使用して圧縮します"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "常に疑似 tty 内でコマンドを実行します"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "UNIX 以外のグループをサポートするためのプラグインです:%s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "入出力 (I/O) ログを保存するディレクトリです:%s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "入出力 (I/O) ログを保存するファイルです:%s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "pty を割り当てた時に utmp/utmpx ファイルに記録を加えます"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "utmp に記録するユーザーを、実行したユーザーではなく、変更後のユーザーにします"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "許容される権限の集合: %s"
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "制限される権限の集合: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "コマンドを pty でバックグラウンドで実行する"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "利用する PAM サービス名: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "ログインシェルで利用する PAM サービス名: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "ターゲットユーザーの PAM 資格情報による認証を試みる"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "実行するコマンドのために新しい PAM セッションを生成する"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "I/O ログシーケンス番号の最大値: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "sudoers のネットグループサポートを有効にする"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "ファイルを sudoedit で編集するときに親ディレクトリが書き込み可能か確かめる"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "ファイルを sudoedit で編集するときにシンボリックリンクを追う"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "不明なシステムグループについて、グループプラグインに問い合わせる"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "ネットグループについて、すべてのタプル(ユーザー、ホスト、ドメイン)を基に判定する"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "監査ログファイルへの書き込みができなくても、コマンドの実行を許可する"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "I/O ログファイルへの書き込みができなくても、コマンドの実行を許可する"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "ログファイルへの書き込みができなくても、コマンドの実行を許可する"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "グループの照合を sudoers の中で行い、グループ名でなくグループIDを用いる"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "ログエントリーがこの値より長くなると、複数の syslog メッセージに分割されます: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "I/O ログの所有者となるユーザー: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "I/O ログの所有者となるグループ: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "I/O ログのファイルモード: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "コマンドの実行時にパスでなくファイル記述子を使う: %s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "sudoers の中の未知の Defaults エントリーを無視し、警告を出さない"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "コマンドが中断されるまでの経過時間を秒で指定する: %u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "ユーザーがコマンド実行の制限時間をコマンドラインで指定できるようにする"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "I/O ログのデータをバッファせずに、即ディスクにフラッシュする"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "syslog へのログ記録時にプロセスIDを含める"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "認証タイムスタンプのタイプ: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "認証失敗メッセージ: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "ユーザー名の検索で大文字小文字を同一視する"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "グループ名の検索で大文字小文字を同一視する"
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d 不明なデフォルト項目 \"%s\" です"
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: 不明なデフォルト項目 \"%s\" です"
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d \"%s\" に値が指定されていません"
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: \"%s\" に値が指定されていません"
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d \"%s\" の値は '/' で開始しなければいけません"
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: \"%s\" の値は '/' で開始しなければいけません"
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d オプション \"%s\" は値をとりません"
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: オプション \"%s\" は値をとりません"
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d 0x%x はオプション \"%s\" のデフォルトタイプとして無効です"
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: 0x%x はオプション \"%s\" のデフォルトタイプとして無効です"
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d \"%s\" はオプション \"%s\" の値としては無効です"
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: \"%s\" はオプション \"%s\" の値としては無効です"
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: envp が破損しています。長さが合いません"
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr "環境を再構築できません"
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "残念ですが、あなたは次の環境変数を設定することを許可されていません: %s"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "%s 内 %d 行付近で構文解析エラーが発生しました"
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "%s 内で構文解析エラーが発生しました"
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "サポートされてない 認証方式 %d です: %s"
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr "%s: 読み込みエラー"
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s の所有者は uid %d でなければいけません"
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s は所有者のみ書き込み可能でなければいけません"
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "%s をロードできません: %su"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "%s 内にシンボル \"group_plugin\" がありません"
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: 互換性のないグループプラグインメジャーバージョン %d です。予期されるのは %d です"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "IPアドレス \"%s\" を解析できません"
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "ネットマスク \"%s\" を解析できません"
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr "ローカル IP アドレスとネットマスクの組:\n"
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s が存在しますがディレクトリではありません (0%o)"
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "ディレクトリ %s を作成できません"
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:723
+#: plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "%s のアクセス権限のモードを 0%o に変更できません"
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1167
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr "不明なグループです: %s"
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr "%s を読み込めません"
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr "%s を作成できません"
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "%s へ I/O ログを書き込むことができません"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr "%s: 内部エラー、I/O イベント %d のログファイルを開けません"
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr "%s: 内部エラー、無効なシグナル %d"
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: 無効なログファイルのパス"
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: タイムスタンプのフィールドがありません"
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: タイムスタンプ %s: %s"
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: ユーザー名フィールドがありません"
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: runasユーザー名フィールドがありません"
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: runasグループ名フィールドがありません"
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr "starttls は ldaps を使用時にはサポートされていません"
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "SSL 証明書と鍵データベースを初期化できません: %s"
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "SSL を使用するためには %s の中の TLS_CERT を設定する必要があります"
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "LDAP を初期化できません: %s"
+
+#: plugins/sudoers/ldap.c:1648
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls が指定されていますが、LDAP ライブラリが ldap_start_tls_s() または ldap_start_tls_s_np() をサポートしていません"
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "無効な sudoOrder 属性です: %s"
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: ポートが大きすぎます"
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "サポートされてない LDAP URI タイプです: %s"
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "ldap と ldaps の URI を混ぜて使用できません"
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "sudoOption を変換できません: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "監査システムを開くことができません"
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr "監査メッセージを送ることができません"
+
+#: plugins/sudoers/logging.c:113
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:141
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (コマンド継続中) %s"
+
+#: plugins/sudoers/logging.c:170
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "ログファイルを開けません: %s"
+
+#: plugins/sudoers/logging.c:178
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "ログファイルをロックできません: %s"
+
+#: plugins/sudoers/logging.c:211
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "%s へログを書き込むことができません"
+
+#: plugins/sudoers/logging.c:240
+msgid "No user or host"
+msgstr "ユーザーまたはホストがありません"
+
+#: plugins/sudoers/logging.c:242
+msgid "validation failure"
+msgstr "検証に失敗しました"
+
+#: plugins/sudoers/logging.c:249
+msgid "user NOT in sudoers"
+msgstr "ユーザーが sudoers 内にありません"
+
+#: plugins/sudoers/logging.c:251
+msgid "user NOT authorized on host"
+msgstr "ホスト上でユーザーが認証されていません"
+
+#: plugins/sudoers/logging.c:253
+msgid "command not allowed"
+msgstr "コマンドが許可されていません"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s は sudoers ファイル内にありません。この事象は記録・報告されます。\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s は %s 上で sudo を実行することを許可されていません。この事象は記録・報告されます。\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "残念ですが、ユーザー %s は %s 上で sudo を実行できません。\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "残念ですが、ユーザー %s は'%s%s%s' を %s%s%s として %s 上で実行することは許可されていません。\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: コマンドが見つかりません"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"'.' 内で見つかった \"%1$s\" を無視します\n"
+"この \"%3$s\" を実行したい場合は \"sudo ./%2$s\" を使用してください。"
+
+#: plugins/sudoers/logging.c:354
+msgid "authentication failure"
+msgstr "認証失敗"
+
+#: plugins/sudoers/logging.c:380
+msgid "a password is required"
+msgstr "パスワードが必要です"
+
+#: plugins/sudoers/logging.c:443
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u 回パスワード試行を間違えました"
+
+#: plugins/sudoers/logging.c:666
+msgid "unable to fork"
+msgstr "fork できません"
+
+#: plugins/sudoers/logging.c:674 plugins/sudoers/logging.c:726
+#, c-format
+msgid "unable to fork: %m"
+msgstr "fork できません: %m"
+
+#: plugins/sudoers/logging.c:716
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "パイプを開けません: %m"
+
+#: plugins/sudoers/logging.c:741
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "標準入力を複製できません: %m"
+
+#: plugins/sudoers/logging.c:779
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "%s を実行できません: %m"
+
+#: plugins/sudoers/match.c:874
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "%s (%s) の認証方式は %s 形式ではありません"
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:421 plugins/sudoers/visudo.c:717
+#, c-format
+msgid "unable to stat %s"
+msgstr "%s の状態取得 (stat) ができません"
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"LDAP 役割: %s\n"
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"sudoers 項目:\n"
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr " RunAsUsers: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr " RunAsGroups: "
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr " オプション: "
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr " コマンド:\n"
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "既定値のエントリと照合中 (ユーザー名 %s) (ホスト名 %s):\n"
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "ユーザー %s 用の Runas およびコマンド特有のデフォルト:\n"
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "ユーザー %s は %s 上で コマンドを実行できます\n"
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "ユーザー %s は %s 上で sudo を実行することを許可されていません。\n"
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "無効な属性値を無視します: %s"
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "不完全な sudoRole: cn: %s を無視します"
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "無効な %.*s が sudo のフロントエンドで設定されています"
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr "ネットワークのアドレスリストを解析できません"
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr "ユーザー名が sudo のフロントエンドで設定されていません"
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr "ユーザーIDが sudo のフロントエンドで設定されていません"
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr "グループIDが sudo のフロントエンドで設定されていません"
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr "ホスト名が sudo のフロントエンドで設定されていません"
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:220
+#: plugins/sudoers/visudo.c:851
+#, c-format
+msgid "unable to execute %s"
+msgstr "%s を実行できません"
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "sudoers ポリシープラグイン バージョン %s\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "sudoers ファイル文法バージョン %d\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"sudoers のパス: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "nsswitch のパス: %s\n"
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "ldap.conf のパス: %s\n"
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "ldap.secret のパス: %s\n"
+
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "タイプ %d のフックを登録できません (バージョン %d.%d)"
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "ユーザーID %u をキャッシュできません。メモリ不足です。"
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "ユーザーID %u をキャッシュできません。すでに存在します"
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "ユーザー %s をキャッシュできません。メモリ不足です。"
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "ユーザー %s をキャッシュできません。すでに存在します"
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "グループID %u をキャッシュできません。メモリ不足です。"
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "グループID %u をキャッシュできません。すでに存在します"
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "グループ %s をキャッシュできません。メモリ不足です。"
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "グループ %s をキャッシュできません。すでに存在します"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "グループリスト %s をキャッシュできません。すでに存在します"
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "グループリスト %s をキャッシュできません。メモリ不足です。"
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "%s のグループを解析できません"
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "%s のグループIDを解析できません"
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr "perm スタックがオーバーフローしました"
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr "perm スタックがアンダーフローしました"
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr "root のグループIDへ変更できません"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr "実行するためのグループIDに変更できません"
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr "グループベクトルを実行するためのものに変更できません"
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr "実行するためのユーザーIDに変更できません"
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr "sudoers のグループIDへ変更できません"
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr "プロセスが多すぎます"
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr "カレントディレクトリを取得できません"
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "検証の対象とする長さを切り詰めました user_cmnd: %s"
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "検証の対象とする長さを切り詰めました argv[0]: %s"
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr "audit_failure のメッセージが長すぎます"
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "SSS のソースを初期化できません。SSSD はあなたのマシンにインストールされていますか?"
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "シンボル \"%s\" が %s 内にありません"
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr "デフォルト項目で問題が発生しました"
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr "有効な sudoers のソースが見つかりません。終了します"
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers の指定により root が sudo を使用することは禁止されています"
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr "-C オプションを使用することは許可されていません"
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "タイムスタンプの所有者 (%s): そのようなユーザーはありません"
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr "tty がありません"
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr "残念ですが、sudo を実行するには tty が必要です"
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr "コマンドがカレントディレクトリにあります"
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "残念ですが、あなたはコマンド実行の制限時間を設定することを許可されていません。"
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "残念ですが、あなたは環境変数を保存することを許可されていません。"
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr "コマンド名が長すぎます"
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s は通常ファイルではありません"
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s はユーザーID %u によって所有されています。これは %u であるべきです"
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr "%s は誰でも書き込み可能です"
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s のグループIDは %u になっています。これは %u であるべきです"
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "root のみ \"-c %s\" を使用できます"
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr "不明なログインクラスです: %s"
+
+#: plugins/sudoers/sudoers.c:1069 plugins/sudoers/sudoers.c:1083
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "ホスト %s の名前解決ができません"
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "無効なフィルターオプションです: %s"
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "無効な最大待機時間です: %s"
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "無効な speed_factor の値です: %s"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/タイミング: %s"
+
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/タイミング: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "再生する sudo セッション: %s"
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr "イベントをキューに追加できません"
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr "tty を raw モードに設定できません"
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "警告: ログをきちんとリプレイするには端末が小さすぎます。\n"
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "ログの大きさは %d x %d で、端末の大きさは %d x %d です。"
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "再生が終了しました、何かキーを押すと端末を回復します。"
+
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "無効なタイミングファイルの行です: %s"
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "曖昧な式 \"%s です\""
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr "式内で ')' が不一致です"
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "不明な検索語 \"%s\" です"
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s は引数が必要です"
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "無効な正規表現です: %s"
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "日付 \"%s\" を構文解析できませんでした"
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr "式内で '(' が不一致です"
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr "末尾に \"or\" を配置できません"
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr "末尾に \"!\" を配置できません"
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr "未知の検索タイプ %d"
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr "使用法: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "使用法: %s [-h] [-d dir] -l [search expression]\n"
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - sudo セッションログをリプレイします\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"オプション:\n"
+" -d, --directory=dir セッションログのディレクトリを指定する\n"
+" -f, --filter=filter 表示する I/O タイプを指定する\n"
+" -h, --help ヘルプメッセージを表示して終了する\n"
+" -l, --list[=expr] 使用可能なセッションIDを一覧表示する、オプションで条件 expr を指定可能\n"
+" -m, --max-wait=num イベント間の待ち時間の最大秒数を指定する\n"
+" -S, --suspend-wait コマンドがサスペンドされている間、待機する\n"
+" -s, --speed=num 出力速度を速くする、または遅くする\n"
+" -V, --version バージョン情報を表示して終了する"
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr "\tホストが一致しません"
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"コマンドが許可されました"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"コマンドが拒否されました"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"コマンドが一致しませんでした"
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr "%s はグループのメンバーによる書き込みが可能です"
+
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "タイムスタンプファイルを %lld バイトに切り詰めることができません"
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:482 plugins/sudoers/visudo.c:488
+msgid "unable to read the clock"
+msgstr "時刻を読み込むことができません"
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr "未来の時刻のタイムスタンプを無視します"
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "タイムスタンプが遠すぎる将来になっています: %20.20s"
+
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "タイムスタンプファイル %s をロックすることができません"
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "受講状況格納パスが長すぎます: %s/%s"
+
+#: plugins/sudoers/visudo.c:216
+msgid "the -x option will be removed in a future release"
+msgstr "-x オプションは将来のリリースでは削除されます"
+
+#: plugins/sudoers/visudo.c:217
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "cvtsudoers ユーティリティーを代わりに使用することを検討してください"
+
+#: plugins/sudoers/visudo.c:268 plugins/sudoers/visudo.c:650
+#, c-format
+msgid "press return to edit %s: "
+msgstr "%s を編集するためにリターンを押してください: "
+
+#: plugins/sudoers/visudo.c:329
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "指定したエディター (%s) が存在しません"
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "エディターが見つかりません (エディターのパス = %s)"
+
+#: plugins/sudoers/visudo.c:441 plugins/sudoers/visudo.c:449
+msgid "write error"
+msgstr "書き込みエラーです"
+
+#: plugins/sudoers/visudo.c:495
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "一時ファイル (%s) の状態取得 (stat) ができません。%s は変更されません"
+
+#: plugins/sudoers/visudo.c:502
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "一時ファイル (%s) の大きさが 0 です。%s は変更されません"
+
+#: plugins/sudoers/visudo.c:508
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "エディター (%s) が異常終了しました。%s は変更されません"
+
+#: plugins/sudoers/visudo.c:530
+#, c-format
+msgid "%s unchanged"
+msgstr "%s は変更されません"
+
+#: plugins/sudoers/visudo.c:589
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "一時ファイル (%s) を再度開くことができません。%s は変更されません。"
+
+#: plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "一時ファイル (%s) の構文解析ができません。不明なエラーです"
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "内部エラー、リスト内に %s が見つかりません!"
+
+#: plugins/sudoers/visudo.c:719 plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "%s の (ユーザーID, グループID) を (%u, %u) に設定できません"
+
+#: plugins/sudoers/visudo.c:751
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s と %s は同じファイルシステム上にありません。名前を変更するために mv を使用しています"
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "コマンドの失敗です: '%s %s %s'。%s は変更されません"
+
+#: plugins/sudoers/visudo.c:775
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "%s の名前変更に失敗しました。%s は変更されません"
+
+#: plugins/sudoers/visudo.c:796
+msgid "What now? "
+msgstr "次は何でしょうか? "
+
+#: plugins/sudoers/visudo.c:810
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"オプション:\n"
+" e -- sudoers ファイルを再度編集します\n"
+" x -- sudoers ファイルへの変更を保存せずに終了します\n"
+" Q -- sudoers ファイルへの変更を保存して終了します (*危険です!*)\n"
+
+#: plugins/sudoers/visudo.c:856
+#, c-format
+msgid "unable to run %s"
+msgstr "%s を実行できません"
+
+#: plugins/sudoers/visudo.c:886
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: 所有権に誤りがあります。(ユーザーID, グループID) は (%u, %u) であるべきです\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: アクセス権限に誤りがあります。モードは 0%o であるべきです\n"
+
+#: plugins/sudoers/visudo.c:950 plugins/sudoers/visudo.c:957
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: 正しく構文解析されました\n"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s がビジー状態です。後で再試行してください"
+
+#: plugins/sudoers/visudo.c:979
+#, c-format
+msgid "unable to lock %s"
+msgstr "%s をロックできません"
+
+#: plugins/sudoers/visudo.c:980
+msgid "Edit anyway? [y/N]"
+msgstr "それでも編集しますか? [y/N]"
+
+#: plugins/sudoers/visudo.c:1064
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "エラー: %s:%d %s のエイリアス \"%s\" で定義が循環しています"
+
+#: plugins/sudoers/visudo.c:1065
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "警告: %s:%d %s のエイリアス \"%s\" で定義が循環しています"
+
+#: plugins/sudoers/visudo.c:1069
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "エラー: %s:%d %s \"%s\" は参照されているのに定義されていません"
+
+#: plugins/sudoers/visudo.c:1070
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "警告: %s:%d %s \"%s\" は参照されているのに定義されていません"
+
+#: plugins/sudoers/visudo.c:1161
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "警告: %s:%d エイリアス %s として \"%s\" は使用されていません"
+
+#: plugins/sudoers/visudo.c:1276
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - sudoers ファイルを安全に編集する\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1278
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"オプション:\n"
+" -c, --check 検査のみを行う\n"
+" -f, --file=sudoers sudoers ファイルの位置を指定する\n"
+" -h, --help ヘルプメッセージを表示して終了する\n"
+" -q, --quiet 文法エラーメッセージをより少なく (静かに) する\n"
+" -s, --strict 厳密な文法検査を行う\n"
+" -V, --version バージョン情報を表示して終了する\n"
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr "インクルードの階層が大きすぎます"
+
+#~ msgid ""
+#~ "\n"
+#~ "LDAP Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "LDAP 役割: 不明\n"
+
+#~ msgid " Order: %s\n"
+#~ msgstr " Order: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: %s\n"
+#~ msgstr ""
+#~ "\n"
+#~ "SSSD 役割: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "SSSD 役割: 不明\n"
+
+#~ msgid "Warning: cycle in %s `%s'"
+#~ msgstr "警告: 循環を発見 %s `%s'"
+
+#~ msgid "Warning: %s `%s' referenced but not defined"
+#~ msgstr "警告: %s `%s' は参照されていますが定義されていません"
+
+#~ msgid "Warning: unused %s `%s'"
+#~ msgstr "警告: 使われていません %s `%s'"
+
+#~ msgid "timestamp path too long: %s/%s"
+#~ msgstr "タイムスタンプのパスが長過ぎます: %s/%s"
+
+#~ msgid "unable to stat editor (%s)"
+#~ msgstr "エディター (%s) の状態取得 (stat) ができません"
+
+#~ msgid ">>> %s: %s near line %d <<<"
+#~ msgstr ">>> %s: %s (%d行付近) <<<"
+
+#~ msgid "pam_chauthtok: %s"
+#~ msgstr "pam_chauthtok: %s"
+
+#~ msgid "pam_authenticate: %s"
+#~ msgstr "pam_authenticate: %s"
+
+#~ msgid "Password:"
+#~ msgstr "パスワード:"
+
+#~ msgid "getaudit: failed"
+#~ msgstr "getaudit: 失敗しました"
+
+#~ msgid "getauid failed"
+#~ msgstr "getauid に失敗しました"
+
+#~ msgid "au_to_subject: failed"
+#~ msgstr "au_to_subject: 失敗しました"
+
+#~ msgid "au_to_exec_args: failed"
+#~ msgstr "au_to_exec_args: 失敗しました"
+
+#~ msgid "au_to_return32: failed"
+#~ msgstr "au_to_return32: 失敗しました"
+
+#~ msgid "getauid: failed"
+#~ msgstr "getauid: 失敗しました"
+
+#~ msgid "au_to_text: failed"
+#~ msgstr "au_to_text: 失敗しました"
+
+#~ msgid "%s owned by uid %u, should be uid %u"
+#~ msgstr "%s はユーザーID (uid) %u によって所有されています。これはユーザーID %u であるべきです"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0700"
+#~ msgstr "%s は所有者以外でも書き込み可能 (0%o) です。アクセス権限のモードは 0700 であるべきです"
+
+#~ msgid "%s exists but is not a regular file (0%o)"
+#~ msgstr "%s が存在しますが通常ファイル (0%o) ではありません"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0600"
+#~ msgstr "%s は所有者以外でも書き込み可能 (0%o) です。アクセス権限のモードは 0600 であるべきです"
+
+#~ msgid "unable to remove %s (%s), will reset to the epoch"
+#~ msgstr "%s (%s) を削除できません。エポックにリセットします"
+
+#~ msgid "unable to set locale to \"%s\", using \"C\""
+#~ msgstr "ロケールを \"%s\" に設定できません。 \"C\" を使用します"
+
+#~ msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+#~ msgstr "sudo_ldap_conf_add_ports: hostbuf を拡張中にメモリ空間が不足しました"
+
+#~ msgid "invalid uri: %s"
+#~ msgstr "無効な URI です: %s"
+
+#~ msgid "unable to mix ldaps and starttls"
+#~ msgstr "ldaps と starttls を混ぜて使用できません"
+
+#~ msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+#~ msgstr "sudo_ldap_parse_uri: hostbuf を構築中にメモリ空間が不足しました"
+
+#~ msgid "sudo_ldap_build_pass1 allocation mismatch"
+#~ msgstr "sudo_ldap_build_pass1 配置が一致しません"
+
+#~ msgid "internal error: insufficient space for log line"
+#~ msgstr "内部エラー: ログの行に十分な空間がありません"
+
+#~ msgid ""
+#~ " Commands:\n"
+#~ "\t"
+#~ msgstr ""
+#~ " コマンド:\n"
+#~ "\t"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "unable to cache uid %u (%s), already exists"
+#~ msgstr "ユーザーID %u (%s) をキャッシュできません。すでに存在します"
+
+#~ msgid "unable to cache gid %u (%s), already exists"
+#~ msgstr "グループID %u (%s) をキャッシュできません。すでに存在します"
+
+#~ msgid "Unable to dlopen %s: %s"
+#~ msgstr "dlopen %s を行うことができません: %s"
+
+#~ msgid "unable to execute %s: %s"
+#~ msgstr "%s を実行できません: %s"
+
+#~ msgid "writing to standard output"
+#~ msgstr "標準出力に書き込んでいます"
+
+#~ msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
+#~ msgstr "nanosleep: tv_sec %ld, tv_nsec %ld"
+
+#~ msgid "too many parenthesized expressions, max %d"
+#~ msgstr "式内の小括弧のくくりが多すぎます。最大は %d です。"
+
+#~ msgid "invalid regex: %s"
+#~ msgstr "無効な正規表現です: %s"
+
+#~ msgid "fill_args: buffer overflow"
+#~ msgstr "fill_args: バッファオーバーフローが発生しました"
+
+#~ msgid "internal error, expand_prompt() overflow"
+#~ msgstr "内部エラー、expand_prompt() がオーバーフローしました"
+
+#~ msgid "internal error, sudo_setenv2() overflow"
+#~ msgstr "内部エラー、 sudo_setenv2() がオーバーフローしました"
+
+#~ msgid "internal error, sudo_setenv() overflow"
+#~ msgstr "内部エラー、 sudo_setenv() がオーバーフローしました"
+
+#~ msgid "internal error, linux_audit_command() overflow"
+#~ msgstr "内部エラー、linux_audit_command() がオーバーフローしました"
+
+#~ msgid "internal error, runas_groups overflow"
+#~ msgstr "内部エラー、runas_groups がオーバーフローしました"
+
+#~ msgid "internal error, init_vars() overflow"
+#~ msgstr "内部エラー、init_vars() がオーバーフローしました"
+
+#~ msgid "fixed mode on %s"
+#~ msgstr "%s のアクセス権限のモードを修正しました"
+
+#~ msgid "set group on %s"
+#~ msgstr "%s のグループを設定しました"
+
+#~ msgid "unable to fix mode on %s"
+#~ msgstr "%s のアクセス権限のモードを修正できません"
+
+#~ msgid "%s is mode 0%o, should be 0%o"
+#~ msgstr "%s のアクセス権限のモードは 0%o です。これは 0%o であるべきです"
+
+#~ msgid "File containing dummy exec functions: %s"
+#~ msgstr "偽の exec 関数が含まれるファイル: %s"
diff --git a/plugins/sudoers/po/ko.mo b/plugins/sudoers/po/ko.mo
new file mode 100644
index 0000000..cd3bce1
--- /dev/null
+++ b/plugins/sudoers/po/ko.mo
Binary files differ
diff --git a/plugins/sudoers/po/ko.po b/plugins/sudoers/po/ko.po
new file mode 100644
index 0000000..5f7839e
--- /dev/null
+++ b/plugins/sudoers/po/ko.po
@@ -0,0 +1,2122 @@
+# Korean translation for the sudoers plugin
+# This file is distributed under the same license as the sudo package.
+# Todd C. Miller <Todd.Miller@courtesan.com>, 2011-2015
+# Seong-ho Cho <darkcircle.0426@gmail.com>, 2016, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.20b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2017-03-24 15:36-0600\n"
+"PO-Revision-Date: 2017-06-06 17:14+0900\n"
+"Last-Translator: Seong-ho Cho <darkcircle.0426@gmail.com>\n"
+"Language-Team: Korean <translation-team-ko@googlegroups.com>\n"
+"Language: ko\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Poedit 1.8.7\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "문법 오류"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "%p의 암호: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] %p의 암호: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "암호:"
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** %h 보안 알림 ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "죄송합니다만, 다시 시도하십시오."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:307 gram.y:314 gram.y:321 gram.y:328 gram.y:335
+#: gram.y:398 gram.y:406 gram.y:416 gram.y:449 gram.y:456 gram.y:463
+#: gram.y:470 gram.y:552 gram.y:559 gram.y:568 gram.y:577 gram.y:594
+#: gram.y:706 gram.y:713 gram.y:720 gram.y:728 gram.y:824 gram.y:831
+#: gram.y:838 gram.y:845 gram.y:852 gram.y:878 gram.y:885 gram.y:892
+#: gram.y:1015 gram.y:1195 gram.y:1202 plugins/sudoers/alias.c:124
+#: plugins/sudoers/alias.c:139 plugins/sudoers/auth/bsdauth.c:141
+#: plugins/sudoers/auth/kerb5.c:119 plugins/sudoers/auth/kerb5.c:145
+#: plugins/sudoers/auth/pam.c:443 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/auth/sia.c:59 plugins/sudoers/defaults.c:631
+#: plugins/sudoers/defaults.c:886 plugins/sudoers/defaults.c:1057
+#: plugins/sudoers/editor.c:64 plugins/sudoers/editor.c:82
+#: plugins/sudoers/editor.c:93 plugins/sudoers/env.c:234
+#: plugins/sudoers/filedigest.c:120 plugins/sudoers/filedigest_gcrypt.c:90
+#: plugins/sudoers/filedigest_openssl.c:111 plugins/sudoers/gc.c:52
+#: plugins/sudoers/group_plugin.c:134 plugins/sudoers/interfaces.c:71
+#: plugins/sudoers/iolog.c:909 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:449 plugins/sudoers/ldap.c:480
+#: plugins/sudoers/ldap.c:532 plugins/sudoers/ldap.c:565
+#: plugins/sudoers/ldap.c:963 plugins/sudoers/ldap.c:1157
+#: plugins/sudoers/ldap.c:1168 plugins/sudoers/ldap.c:1184
+#: plugins/sudoers/ldap.c:1471 plugins/sudoers/ldap.c:1631
+#: plugins/sudoers/ldap.c:1713 plugins/sudoers/ldap.c:1853
+#: plugins/sudoers/ldap.c:1877 plugins/sudoers/ldap.c:1966
+#: plugins/sudoers/ldap.c:1981 plugins/sudoers/ldap.c:2077
+#: plugins/sudoers/ldap.c:2110 plugins/sudoers/ldap.c:2191
+#: plugins/sudoers/ldap.c:2273 plugins/sudoers/ldap.c:2370
+#: plugins/sudoers/ldap.c:3203 plugins/sudoers/ldap.c:3235
+#: plugins/sudoers/ldap.c:3544 plugins/sudoers/ldap.c:3572
+#: plugins/sudoers/ldap.c:3588 plugins/sudoers/ldap.c:3678
+#: plugins/sudoers/ldap.c:3694 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:188 plugins/sudoers/logging.c:450
+#: plugins/sudoers/logging.c:471 plugins/sudoers/logging.c:683
+#: plugins/sudoers/logging.c:941 plugins/sudoers/match.c:617
+#: plugins/sudoers/match.c:664 plugins/sudoers/match.c:714
+#: plugins/sudoers/match.c:738 plugins/sudoers/match.c:826
+#: plugins/sudoers/match.c:915 plugins/sudoers/parse.c:248
+#: plugins/sudoers/parse.c:260 plugins/sudoers/parse.c:275
+#: plugins/sudoers/parse.c:287 plugins/sudoers/policy.c:418
+#: plugins/sudoers/policy.c:652 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/pwutil.c:139 plugins/sudoers/pwutil.c:210
+#: plugins/sudoers/pwutil.c:286 plugins/sudoers/pwutil.c:457
+#: plugins/sudoers/pwutil.c:522 plugins/sudoers/pwutil.c:591
+#: plugins/sudoers/pwutil.c:749 plugins/sudoers/pwutil.c:806
+#: plugins/sudoers/pwutil.c:851 plugins/sudoers/pwutil.c:908
+#: plugins/sudoers/sssd.c:162 plugins/sudoers/sssd.c:194
+#: plugins/sudoers/sssd.c:237 plugins/sudoers/sssd.c:244
+#: plugins/sudoers/sssd.c:280 plugins/sudoers/sssd.c:390
+#: plugins/sudoers/sssd.c:462 plugins/sudoers/sssd.c:1054
+#: plugins/sudoers/sssd.c:1233 plugins/sudoers/sssd.c:1247
+#: plugins/sudoers/sssd.c:1263 plugins/sudoers/sudoers.c:262
+#: plugins/sudoers/sudoers.c:272 plugins/sudoers/sudoers.c:280
+#: plugins/sudoers/sudoers.c:364 plugins/sudoers/sudoers.c:680
+#: plugins/sudoers/sudoers.c:795 plugins/sudoers/sudoers.c:839
+#: plugins/sudoers/sudoers_debug.c:107 plugins/sudoers/sudoreplay.c:517
+#: plugins/sudoers/sudoreplay.c:716 plugins/sudoers/sudoreplay.c:828
+#: plugins/sudoers/sudoreplay.c:868 plugins/sudoers/sudoreplay.c:877
+#: plugins/sudoers/sudoreplay.c:887 plugins/sudoers/sudoreplay.c:895
+#: plugins/sudoers/sudoreplay.c:899 plugins/sudoers/sudoreplay.c:1055
+#: plugins/sudoers/sudoreplay.c:1059 plugins/sudoers/testsudoers.c:131
+#: plugins/sudoers/testsudoers.c:217 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/timestamp.c:378 plugins/sudoers/timestamp.c:422
+#: plugins/sudoers/timestamp.c:838 plugins/sudoers/toke_util.c:56
+#: plugins/sudoers/toke_util.c:109 plugins/sudoers/toke_util.c:146
+#: plugins/sudoers/visudo.c:153 plugins/sudoers/visudo.c:310
+#: plugins/sudoers/visudo.c:316 plugins/sudoers/visudo.c:447
+#: plugins/sudoers/visudo.c:625 plugins/sudoers/visudo.c:967
+#: plugins/sudoers/visudo.c:1033 plugins/sudoers/visudo.c:1077
+#: plugins/sudoers/visudo.c:1179 plugins/sudoers/visudo_json.c:1025 toke.l:849
+#: toke.l:949 toke.l:1106
+msgid "unable to allocate memory"
+msgstr "메모리를 할당할 수 없습니다"
+
+#: gram.y:481
+msgid "a digest requires a path name"
+msgstr "다이제스트에 경로 이름이 필요합니다"
+
+#: gram.y:607
+msgid "invalid notbefore value"
+msgstr "잘못된 notbefore 값"
+
+#: gram.y:615
+msgid "invalid notafter value"
+msgstr "잘못된 notafter 값"
+
+#: gram.y:624 plugins/sudoers/policy.c:265
+msgid "timeout value too large"
+msgstr "제한 시간 값이 너무 큽니다"
+
+#: gram.y:626 plugins/sudoers/policy.c:267
+msgid "invalid timeout value"
+msgstr "잘못된 제한 시간 값"
+
+#: gram.y:1195 gram.y:1202 plugins/sudoers/auth/pam.c:320
+#: plugins/sudoers/auth/pam.c:443 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/defaults.c:631 plugins/sudoers/defaults.c:886
+#: plugins/sudoers/defaults.c:1057 plugins/sudoers/editor.c:64
+#: plugins/sudoers/editor.c:82 plugins/sudoers/editor.c:93
+#: plugins/sudoers/env.c:234 plugins/sudoers/filedigest.c:120
+#: plugins/sudoers/filedigest_gcrypt.c:72
+#: plugins/sudoers/filedigest_gcrypt.c:90
+#: plugins/sudoers/filedigest_openssl.c:111 plugins/sudoers/gc.c:52
+#: plugins/sudoers/group_plugin.c:134 plugins/sudoers/interfaces.c:71
+#: plugins/sudoers/iolog.c:909 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:449 plugins/sudoers/ldap.c:480
+#: plugins/sudoers/ldap.c:532 plugins/sudoers/ldap.c:565
+#: plugins/sudoers/ldap.c:963 plugins/sudoers/ldap.c:1157
+#: plugins/sudoers/ldap.c:1168 plugins/sudoers/ldap.c:1184
+#: plugins/sudoers/ldap.c:1471 plugins/sudoers/ldap.c:1631
+#: plugins/sudoers/ldap.c:1713 plugins/sudoers/ldap.c:1853
+#: plugins/sudoers/ldap.c:1877 plugins/sudoers/ldap.c:1966
+#: plugins/sudoers/ldap.c:1981 plugins/sudoers/ldap.c:2077
+#: plugins/sudoers/ldap.c:2110 plugins/sudoers/ldap.c:2190
+#: plugins/sudoers/ldap.c:2273 plugins/sudoers/ldap.c:2370
+#: plugins/sudoers/ldap.c:3203 plugins/sudoers/ldap.c:3235
+#: plugins/sudoers/ldap.c:3544 plugins/sudoers/ldap.c:3571
+#: plugins/sudoers/ldap.c:3587 plugins/sudoers/ldap.c:3678
+#: plugins/sudoers/ldap.c:3694 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:188 plugins/sudoers/logging.c:450
+#: plugins/sudoers/logging.c:471 plugins/sudoers/logging.c:941
+#: plugins/sudoers/match.c:616 plugins/sudoers/match.c:663
+#: plugins/sudoers/match.c:714 plugins/sudoers/match.c:738
+#: plugins/sudoers/match.c:826 plugins/sudoers/match.c:914
+#: plugins/sudoers/parse.c:248 plugins/sudoers/parse.c:260
+#: plugins/sudoers/parse.c:275 plugins/sudoers/parse.c:287
+#: plugins/sudoers/policy.c:98 plugins/sudoers/policy.c:107
+#: plugins/sudoers/policy.c:116 plugins/sudoers/policy.c:140
+#: plugins/sudoers/policy.c:251 plugins/sudoers/policy.c:265
+#: plugins/sudoers/policy.c:267 plugins/sudoers/policy.c:291
+#: plugins/sudoers/policy.c:300 plugins/sudoers/policy.c:339
+#: plugins/sudoers/policy.c:349 plugins/sudoers/policy.c:358
+#: plugins/sudoers/policy.c:367 plugins/sudoers/policy.c:418
+#: plugins/sudoers/policy.c:652 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/pwutil.c:139 plugins/sudoers/pwutil.c:210
+#: plugins/sudoers/pwutil.c:286 plugins/sudoers/pwutil.c:457
+#: plugins/sudoers/pwutil.c:522 plugins/sudoers/pwutil.c:591
+#: plugins/sudoers/pwutil.c:749 plugins/sudoers/pwutil.c:806
+#: plugins/sudoers/pwutil.c:851 plugins/sudoers/pwutil.c:908
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1471
+#: plugins/sudoers/set_perms.c:1636 plugins/sudoers/sssd.c:162
+#: plugins/sudoers/sssd.c:194 plugins/sudoers/sssd.c:237
+#: plugins/sudoers/sssd.c:244 plugins/sudoers/sssd.c:280
+#: plugins/sudoers/sssd.c:390 plugins/sudoers/sssd.c:462
+#: plugins/sudoers/sssd.c:1054 plugins/sudoers/sssd.c:1232
+#: plugins/sudoers/sssd.c:1247 plugins/sudoers/sssd.c:1263
+#: plugins/sudoers/sudoers.c:262 plugins/sudoers/sudoers.c:272
+#: plugins/sudoers/sudoers.c:280 plugins/sudoers/sudoers.c:364
+#: plugins/sudoers/sudoers.c:680 plugins/sudoers/sudoers.c:795
+#: plugins/sudoers/sudoers.c:839 plugins/sudoers/sudoers_debug.c:106
+#: plugins/sudoers/sudoreplay.c:517 plugins/sudoers/sudoreplay.c:716
+#: plugins/sudoers/sudoreplay.c:828 plugins/sudoers/sudoreplay.c:868
+#: plugins/sudoers/sudoreplay.c:877 plugins/sudoers/sudoreplay.c:887
+#: plugins/sudoers/sudoreplay.c:895 plugins/sudoers/sudoreplay.c:899
+#: plugins/sudoers/sudoreplay.c:1055 plugins/sudoers/sudoreplay.c:1059
+#: plugins/sudoers/testsudoers.c:131 plugins/sudoers/testsudoers.c:217
+#: plugins/sudoers/testsudoers.c:234 plugins/sudoers/timestamp.c:378
+#: plugins/sudoers/timestamp.c:422 plugins/sudoers/timestamp.c:838
+#: plugins/sudoers/toke_util.c:56 plugins/sudoers/toke_util.c:109
+#: plugins/sudoers/toke_util.c:146 plugins/sudoers/visudo.c:153
+#: plugins/sudoers/visudo.c:310 plugins/sudoers/visudo.c:316
+#: plugins/sudoers/visudo.c:447 plugins/sudoers/visudo.c:625
+#: plugins/sudoers/visudo.c:967 plugins/sudoers/visudo.c:1033
+#: plugins/sudoers/visudo.c:1077 plugins/sudoers/visudo.c:1179
+#: plugins/sudoers/visudo_json.c:1025 toke.l:849 toke.l:949 toke.l:1106
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:135
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "\"%s\" 별칭을 이미 정의했습니다"
+
+#: plugins/sudoers/auth/bsdauth.c:68
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "%s 사용자의 로그인 클래스를 가져올 수 없습니다"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+msgid "unable to begin bsd authentication"
+msgstr "BSD 인증을 시작할 수 없습니다"
+
+#: plugins/sudoers/auth/bsdauth.c:81
+msgid "invalid authentication type"
+msgstr "잘못된 인증 형식입니다"
+
+#: plugins/sudoers/auth/bsdauth.c:90
+msgid "unable to initialize BSD authentication"
+msgstr "BSD 인증을 초기화할 수 없습니다"
+
+#: plugins/sudoers/auth/fwtk.c:52
+msgid "unable to read fwtk config"
+msgstr "fwtk 설정을 읽을 수 없습니다"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to connect to authentication server"
+msgstr "인증 서버에 연결할 수 없습니다"
+
+#: plugins/sudoers/auth/fwtk.c:63 plugins/sudoers/auth/fwtk.c:87
+#: plugins/sudoers/auth/fwtk.c:121
+msgid "lost connection to authentication server"
+msgstr "인증 서버의 연결이 끊어졌습니다"
+
+#: plugins/sudoers/auth/fwtk.c:67
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"인증 서버 오류:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:111
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: 본인 정보를 문자열('%s')로 변환할 수 없습니다: %s"
+
+#: plugins/sudoers/auth/kerb5.c:161
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: '%s'을(를) 해석할 수 없습니다: %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: 자격 정보 캐시를 해석할 수 없습니다: %s"
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: 옵션을 할당할 수 없습니다: %s"
+
+#: plugins/sudoers/auth/kerb5.c:232
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: 자격 정보를 가져올 수 없습니다: %s"
+
+#: plugins/sudoers/auth/kerb5.c:245
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: 자격 정보 캐시를 초기화할 수 없습니다: %s"
+
+#: plugins/sudoers/auth/kerb5.c:248
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: 캐시에 자격 정보를 저장할 수 없습니다: %s"
+
+#: plugins/sudoers/auth/kerb5.c:312
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: 호스트 정보를 가져올 수 없습니다: %s"
+
+#: plugins/sudoers/auth/kerb5.c:326
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: TGT를 검증할 수 없습니다! 공격 가능성이 있습니다!: %s"
+
+#: plugins/sudoers/auth/pam.c:108
+msgid "unable to initialize PAM"
+msgstr "PAM을 초기화할 수 없습니다"
+
+#: plugins/sudoers/auth/pam.c:194
+msgid "account validation failure, is your account locked?"
+msgstr "계정 검증 실패, 계정이 잠겼습니까?"
+
+#: plugins/sudoers/auth/pam.c:198
+msgid "Account or password is expired, reset your password and try again"
+msgstr "계정 또는 암호 기한이 지났습니다. 암호를 다시 설정한 후 시도하십시오"
+
+#: plugins/sudoers/auth/pam.c:206
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "기한이 지난 암호를 바꿀 수 없습니다: %s"
+
+#: plugins/sudoers/auth/pam.c:211
+msgid "Password expired, contact your system administrator"
+msgstr "암호 기한이 지났습니다. 시스템 관리자에게 문의하십시오"
+
+#: plugins/sudoers/auth/pam.c:215
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "계정 기한이 지났거나 PAM 설정에 sudo에서 확인할 \"account\" 섹션이 빠졌습니다. 시스템 관리자에게 문의하십시오."
+
+#: plugins/sudoers/auth/pam.c:229
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "PAM 인증 오류: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:97 plugins/sudoers/visudo.c:227
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "%s 데이터베이스에 없습니다"
+
+#: plugins/sudoers/auth/securid5.c:73
+msgid "failed to initialise the ACE API library"
+msgstr "ACE API 라이브러리 초기화에 실패했습니다"
+
+#: plugins/sudoers/auth/securid5.c:99
+msgid "unable to contact the SecurID server"
+msgstr "SecurID 서버에 연결할 수 없습니다"
+
+#: plugins/sudoers/auth/securid5.c:108
+msgid "User ID locked for SecurID Authentication"
+msgstr "SecurID 인증 과정에 사용자 ID가 잠겼습니다"
+
+#: plugins/sudoers/auth/securid5.c:112 plugins/sudoers/auth/securid5.c:163
+msgid "invalid username length for SecurID"
+msgstr "SecurID용 사용자 이름 길이가 잘못되었습니다"
+
+#: plugins/sudoers/auth/securid5.c:116 plugins/sudoers/auth/securid5.c:168
+msgid "invalid Authentication Handle for SecurID"
+msgstr "SecurID용 인증 핸들이 잘못되었습니다"
+
+#: plugins/sudoers/auth/securid5.c:120
+msgid "SecurID communication failed"
+msgstr "SecurID 통신에 실패했습니다"
+
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:213
+msgid "unknown SecurID error"
+msgstr "알 수 없는 SecurID 오류"
+
+#: plugins/sudoers/auth/securid5.c:158
+msgid "invalid passcode length for SecurID"
+msgstr "SecurID용 암호 길이가 잘못되었습니다"
+
+#: plugins/sudoers/auth/sia.c:69 plugins/sudoers/auth/sia.c:125
+msgid "unable to initialize SIA session"
+msgstr "SIA 세션을 초기화할 수 없습니다"
+
+#: plugins/sudoers/auth/sudo_auth.c:126
+msgid "invalid authentication methods"
+msgstr "잘못된 인증 방식"
+
+#: plugins/sudoers/auth/sudo_auth.c:128
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "sudo에 컴파일한 인증 방식이 잘못됐습니다! 독립-비독립 인증 방식을 혼합하여 활용하면 안됩니다."
+
+#: plugins/sudoers/auth/sudo_auth.c:224 plugins/sudoers/auth/sudo_auth.c:274
+msgid "no authentication methods"
+msgstr "인증 방식 없음"
+
+#: plugins/sudoers/auth/sudo_auth.c:226
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "sudo에 컴파일한 인증 방식이 없습니다! 인증 기능을 끄려면 --disable-authentication 설정 옵션을 사용하십시오."
+
+#: plugins/sudoers/auth/sudo_auth.c:276
+msgid "Unable to initialize authentication methods."
+msgstr "인증 방식을 초기화할 수 없습니다."
+
+#: plugins/sudoers/auth/sudo_auth.c:441
+msgid "Authentication methods:"
+msgstr "인증 방식:"
+
+#: plugins/sudoers/bsm_audit.c:111 plugins/sudoers/bsm_audit.c:200
+msgid "Could not determine audit condition"
+msgstr "감사 상태를 결정할 수 없습니다"
+
+#: plugins/sudoers/bsm_audit.c:172 plugins/sudoers/bsm_audit.c:260
+msgid "unable to commit audit record"
+msgstr "감사 레코드를 제출할 수 없습니다"
+
+#: plugins/sudoers/check.c:252
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"로컬 시스템 관리자에게 일반적인 지침을 받았으리라 믿습니다.\n"
+"보통 세가지로 요약합니다:\n"
+"\n"
+" #1) 타인의 사생활을 존중하십시오.\n"
+" #2) 입력하기 전에 한 번 더 생각하십시오.\n"
+" #3) 막강한 힘에는 상당한 책임이 뒤따릅니다.\n"
+"\n"
+
+#: plugins/sudoers/check.c:295 plugins/sudoers/check.c:305
+#: plugins/sudoers/sudoers.c:716 plugins/sudoers/sudoers.c:758
+#, c-format
+msgid "unknown uid: %u"
+msgstr "알 수 없는 uid: %u"
+
+#: plugins/sudoers/check.c:300 plugins/sudoers/iolog.c:246
+#: plugins/sudoers/policy.c:825 plugins/sudoers/sudoers.c:1147
+#: plugins/sudoers/testsudoers.c:208 plugins/sudoers/testsudoers.c:366
+#, c-format
+msgid "unknown user: %s"
+msgstr "알 수 없는 사용자: %s"
+
+#: plugins/sudoers/def_data.c:34
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "syslog를 기록 목적으로 활용할 때의 syslog 기능: %s"
+
+#: plugins/sudoers/def_data.c:38
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "사용자 인증에 성공했을 때 사용할 syslog 우선 순위: %s"
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "사용자 인증에 실패했을 때 사용할 syslog 우선 순위: %s"
+
+#: plugins/sudoers/def_data.c:46
+msgid "Put OTP prompt on its own line"
+msgstr "일회용 암호 입력 프롬프트를 자체 줄에 표시"
+
+#: plugins/sudoers/def_data.c:50
+msgid "Ignore '.' in $PATH"
+msgstr "$PATH의 '.'은 무시합니다"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Always send mail when sudo is run"
+msgstr "sudo를 실행할 때 항상 메일을 보냄"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Send mail if user authentication fails"
+msgstr "사용자가 인증에 실패했을 때 메일을 보냄"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Send mail if the user is not in sudoers"
+msgstr "사용자가 sudoer가 아닐 때 메일을 보냄"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "사용자가 이 호스트의 sudoer가 아닐 때 메일을 보냄"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "사용자가 명령을 실행하도록 허용하지 않았을 때 메일을 보냄"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user tries to run a command"
+msgstr "사용자가 명령 실행을 시도했을 때 메일을 보냄"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "각 사용자/tty에 타임스탬프를 따로 사용"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Lecture user the first time they run sudo"
+msgstr "sudo를 처음 실행할 때 사용자에게 지침 안내"
+
+#: plugins/sudoers/def_data.c:86
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "sudo 지침 안내가 들어있는 파일: %s"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Require users to authenticate by default"
+msgstr "기본적으로 사용자 인증 필요"
+
+#: plugins/sudoers/def_data.c:94
+msgid "Root may run sudo"
+msgstr "루트 사용자의 sudo 실행"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "로그(비 syslog) 파일에 호스트 이름 기록"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Log the year in the (non-syslog) log file"
+msgstr "로그(비 syslog) 파일에 연도 기록"
+
+#: plugins/sudoers/def_data.c:106
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "sudo에 인자를 넣어 실행하지 않으면 셸 시작"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "-s 옵션으로 셸을 시작할 때 $HOME을 대상 사용자로 설정"
+
+#: plugins/sudoers/def_data.c:114
+msgid "Always set $HOME to the target user's home directory"
+msgstr "항상 $HOME을 대상 사용자의 내 폴더로 설정"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Allow some information gathering to give useful error messages"
+msgstr "쓸만한 오류 메시지를 제공할 목적으로 일부 정보 수집 허용"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "sudoers 파일에 완전한 형태를 갖춘 호스트 이름 필요"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Insult the user when they enter an incorrect password"
+msgstr "올바르지 않은 암호를 입력했을 때 사용자 놀리기"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "tty를 보유한 사용자만 sudo 실행 허용"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "EDITOR 환경 변수 대신 visudo 사용"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Prompt for root's password, not the users's"
+msgstr "사용자 암호가 아닌 루트 암호 요구"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "사용자 암호가 아닌 runas_default 사용자 암호 요구"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for the target user's password, not the users's"
+msgstr "사용자 암호가 아닌 대상 사용자 암호 요구"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "대상 사용자 로그인 클래스가 있다면 기본값 적용"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "LOGNAME 및 USER 환경 변수 설정"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "실제 uid가 아닌 대상 사용자에게 유효한 uid 설정"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "대상 사용자의 그룹 벡터 초기화 안함"
+
+#: plugins/sudoers/def_data.c:166
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "로그 파일 줄을 바꿀 줄의 한계 길이(0 값은 줄 바꿈 안함): %u"
+
+#: plugins/sudoers/def_data.c:170
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "인증 타임스탬프 제한 시간: %.1f분"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "암호 요구 제한시간: %.1f분"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "암호 입력 시도 횟수: %u"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "사용자가 활용할 umask 또는 0777: 0%o"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Path to log file: %s"
+msgstr "로그 파일 경로: %s"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "메일 프로그램 경로: %s"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "메일 프로그램 플래그: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "메일을 보낼 주소: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "메일을 보내려는 주소: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "메일 메시지 제목 줄: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "올바르지 않은 암호 메시지: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "지침 상태 디렉터리 경로: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "인증 타임스탬프 디렉터리 경로: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "인증 타임스탬프 디렉터리 소유자: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "암호와 PATH 변수 요구를 하지 않을 이 그룹의 사용자: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "기본 암호 프롬프트: %s"
+
+#: plugins/sudoers/def_data.c:234
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "설정하면 모든 경우의 시스템 프롬프트 대신 이 암호 프롬프트를 사용합니다."
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "명령을 실행할 기본 사용자: %s"
+
+#: plugins/sudoers/def_data.c:242
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "사용자의 $PATH를 대신할 값: %s"
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "visudo에서 사용할 편집기 경로: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "'list' 유사 명령 실행시 암호가 필요할 때: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "'verify' 유사 명령 실행시 암호가 필요할 때: %s"
+
+#: plugins/sudoers/def_data.c:258
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "sudo_noexec 라이브러리에 있는 모조 exec 함수 미리 불러오기"
+
+#: plugins/sudoers/def_data.c:262
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "LDAP 디렉터리가 동작 중이라면 로컬 sudoers 파일을 무시합니다"
+
+#: plugins/sudoers/def_data.c:266
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "%d보다 큰 파일 서술자는 명령을 실행하기 전에 닫습니다"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "이 값을 설정하면 -C 옵션으로 `closefrom' 값을 대신 사용합니다"
+
+#: plugins/sudoers/def_data.c:274
+msgid "Allow users to set arbitrary environment variables"
+msgstr "사용자가 환경 변수 값을 임의대로 설정할 수 있게 합니다"
+
+#: plugins/sudoers/def_data.c:278
+msgid "Reset the environment to a default set of variables"
+msgstr "변수 기본 설정 값으로 환경 초기화"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Environment variables to check for sanity:"
+msgstr "무결성 검사할 환경 변수:"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Environment variables to remove:"
+msgstr "제거할 환경 변수:"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to preserve:"
+msgstr "유지할 환경 변수:"
+
+#: plugins/sudoers/def_data.c:294
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "새 보안 컨텍스트에 사용할 SELinux 역할: %s"
+
+#: plugins/sudoers/def_data.c:298
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "새 보안 컨텍스트에 사용할 SELinux 형식: %s"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "sudo용 환경 파일 경로: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "sudo 전용 환경 파일 경로: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "sudoers 파일을 해석할 때 사용할 로캘: %s"
+
+#: plugins/sudoers/def_data.c:314
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "암호가 나타나더라도 sudo에서 암호 입력 요구 허용"
+
+#: plugins/sudoers/def_data.c:318
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "사용자 입력이 있을 때 암호 프롬프트에서 시각 반응 처리"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "덜 정확하지만 파일 시스템에 접근하지 않는 빠른 비교 검사 사용"
+
+#: plugins/sudoers/def_data.c:326
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "sudoers에 지정한 umask 값이 관대한 권한이라 하더라도 사용자의 umask 값으로 적용"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Log user's input for the command being run"
+msgstr "실행 명령에 대한 사용자 입력 기록"
+
+#: plugins/sudoers/def_data.c:334
+msgid "Log the output of the command being run"
+msgstr "실행 명령에 대한 출력 기록"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Compress I/O logs using zlib"
+msgstr "zlib로 입출력 로그 압축"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Always run commands in a pseudo-tty"
+msgstr "항상 명령을 유사 tty에서 실행"
+
+#: plugins/sudoers/def_data.c:346
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "비 유닉스 그룹을 지원하는 플러그인: %s"
+
+#: plugins/sudoers/def_data.c:350
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "입출력 로그를 저장할 디렉터리: %s"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "입출력 로그를 저장할 파일: %s"
+
+#: plugins/sudoers/def_data.c:358
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "pty를 할당할 때 utmp/utmpx 파일에 항목 추가"
+
+#: plugins/sudoers/def_data.c:362
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "utmp의 사용자를 실제 실행 사용자가 아닌 대리 실행 사용자로 설정"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Set of permitted privileges"
+msgstr "권한 허용 설정"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set of limit privileges"
+msgstr "권한 제한 설정"
+
+#: plugins/sudoers/def_data.c:374
+msgid "Run commands on a pty in the background"
+msgstr "백그라운드의 pty에서 명령 실행"
+
+#: plugins/sudoers/def_data.c:378
+msgid "PAM service name to use"
+msgstr "사용할 PAM 서비스 이름"
+
+#: plugins/sudoers/def_data.c:382
+msgid "PAM service name to use for login shells"
+msgstr "로그인 셸에서 사용할 PAM 서비스 이름"
+
+#: plugins/sudoers/def_data.c:386
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "대상 사용자의 PAM 인증 처리 시도"
+
+#: plugins/sudoers/def_data.c:390
+msgid "Create a new PAM session for the command to run in"
+msgstr "실행할 명령에 새 PAM 세션을 만듭니다"
+
+#: plugins/sudoers/def_data.c:394
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "최대 입출력 로그 순차 번호: %u"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Enable sudoers netgroup support"
+msgstr "sudoers에 네트워크 그룹 지원 활성화"
+
+#: plugins/sudoers/def_data.c:402
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "sudoedit로 파일을 편집할 때 상위 디렉터리 기록 가능 여부 확인"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "sudoedit로 파일을 편집할 때 심볼릭 링크 따라감"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Query the group plugin for unknown system groups"
+msgstr "알 수 없는 시스템 그룹에 그룹 플러그인 요청"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "user, host, domain 전체 튜플을 기반으로 네트워크 그룹 비교"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "sudo에서 감시 로그를 기록할 수 없을 경우에도 명령 실행 허용"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "sudo에서 입출력 로그를 기록할 수 없을 경우에도 명령 실행 허용"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "sudo에서 로그 파일에 기록할 수 없을 경우에도 명령 실행 허용"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "sudoers의 그룹을 해석하고 그룹 이름이 아닌 ID와 비교"
+
+#: plugins/sudoers/def_data.c:434
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "이 값보다 큰 로그 항목은 다수의 syslog 메시지로 나눕니다: %u"
+
+#: plugins/sudoers/def_data.c:438
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "입출력 로그 파일을 소유할 사용자: %s"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "입출력 로그 파일을 소유할 그룹: %s"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "입출력 로그 파일에 사용할 파일 모드: 0%o"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "경로가 아닌 파일 서술자로 명령어 실행: %s"
+
+#: plugins/sudoers/def_data.c:454
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "경고를 출력하는 대신 sudoers에서 알 수 없는 기본 항목을 무시"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "명령 처리가 끝난 후의 초 단위 시간: %u"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "사용자가 명령행에서 제한 시간을 지정하도록 허용"
+
+#: plugins/sudoers/def_data.c:466
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "입출력 로그 데이터를 버퍼링하는 대신 즉시 디스크로 플러싱"
+
+#: plugins/sudoers/defaults.c:220
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d 알 수 없는 \"%s\" 기본 항목"
+
+#: plugins/sudoers/defaults.c:223
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: 알 수 없는 \"%s\" 기본 항목"
+
+#: plugins/sudoers/defaults.c:246
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d \"%s\"에 지정한 값이 없습니다"
+
+#: plugins/sudoers/defaults.c:249
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: \"%s\"에 지정한 값이 없습니다"
+
+#: plugins/sudoers/defaults.c:268
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d \"%s\" 값은 '/' 문자로 시작해야합니다"
+
+#: plugins/sudoers/defaults.c:271
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: \"%s\" 값은 '/' 문자로 시작해야합니다"
+
+#: plugins/sudoers/defaults.c:296
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d \"%s\" 옵션에 값이 없습니다"
+
+#: plugins/sudoers/defaults.c:299
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: \"%s\" 옵션에 값이 없습니다"
+
+#: plugins/sudoers/defaults.c:321
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%1$s:%2$d \"%4$s\" 옵션의 잘못된 기본 형식 0x%3$x"
+
+#: plugins/sudoers/defaults.c:324
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%1$s: \"%3$s\" 옵션의 잘못된 기본 형식 0x%2$x"
+
+#: plugins/sudoers/defaults.c:334
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d \"%s\" 값은 \"%s\" 옵션에 맞지 않습니다"
+
+#: plugins/sudoers/defaults.c:337
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: \"%s\" 값은 \"%s\" 옵션에 맞지 않습니다"
+
+#: plugins/sudoers/env.c:296 plugins/sudoers/env.c:303
+#: plugins/sudoers/env.c:408 plugins/sudoers/ldap.c:453
+#: plugins/sudoers/ldap.c:543 plugins/sudoers/ldap.c:1253
+#: plugins/sudoers/ldap.c:1475 plugins/sudoers/ldap.c:1801
+#: plugins/sudoers/linux_audit.c:82 plugins/sudoers/logging.c:946
+#: plugins/sudoers/policy.c:536 plugins/sudoers/policy.c:546
+#: plugins/sudoers/prompt.c:161 plugins/sudoers/sudoers.c:861
+#: plugins/sudoers/testsudoers.c:238 plugins/sudoers/toke_util.c:158
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "내부 오류. %s 오버플로우"
+
+#: plugins/sudoers/env.c:377
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: envp가 깨졌습니다. 길이가 일치하지 않습니다"
+
+#: plugins/sudoers/env.c:1083
+msgid "unable to rebuild the environment"
+msgstr "환경 구성을 다시 갖출 수 없습니다"
+
+#: plugins/sudoers/env.c:1157
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "죄송하지만 다음 환경 변수를 설정하도록 허가받지 않았습니다: %s"
+
+#: plugins/sudoers/filedigest.c:104 plugins/sudoers/filedigest_gcrypt.c:66
+#: plugins/sudoers/filedigest_openssl.c:95
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "%2$s에서 지원하지 않는 다이제스트 형식 %1$d"
+
+#: plugins/sudoers/filedigest.c:129 plugins/sudoers/filedigest_gcrypt.c:98
+#: plugins/sudoers/filedigest_openssl.c:120
+#, c-format
+msgid "%s: read error"
+msgstr "%s: 읽기 오류"
+
+#: plugins/sudoers/group_plugin.c:86
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s은(는) %d uid가 소유해야 합니다"
+
+#: plugins/sudoers/group_plugin.c:90
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s은(는) 소유자만 쓸 수 있습니다"
+
+#: plugins/sudoers/group_plugin.c:98 plugins/sudoers/sssd.c:398
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "%s을(를) 불러올 수 없습니다: %s"
+
+#: plugins/sudoers/group_plugin.c:104
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "%s에서 \"group_plugin\" 심볼을 찾을 수 없습니다"
+
+#: plugins/sudoers/group_plugin.c:109
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: 호환되지 않는 그룹 플러그인 주 버전 %d입니다. %d이(가) 필요합니다."
+
+#: plugins/sudoers/interfaces.c:79 plugins/sudoers/interfaces.c:96
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "\"%s\" IP 주소를 해석할 수 없습니다"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "\"%s\" 네트워크 마스크 주소를 해석할 수 없습니다"
+
+#: plugins/sudoers/interfaces.c:129
+msgid "Local IP address and netmask pairs:\n"
+msgstr "로컬 IP 주소 및 넷마스크 쌍:\n"
+
+#: plugins/sudoers/iolog.c:111 plugins/sudoers/mkdir_parents.c:70
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s이(가) 있지만 디렉터리가 아닙니다(0%o)"
+
+#: plugins/sudoers/iolog.c:136 plugins/sudoers/iolog.c:173
+#: plugins/sudoers/mkdir_parents.c:59 plugins/sudoers/timestamp.c:170
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "mkdir %s 명령을 실행할 수 없습니다"
+
+#: plugins/sudoers/iolog.c:177 plugins/sudoers/visudo.c:722
+#: plugins/sudoers/visudo.c:732
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "%s 모드를 0%o 값으로 바꿀 수 없습니다"
+
+#: plugins/sudoers/iolog.c:285 plugins/sudoers/sudoers.c:1178
+#: plugins/sudoers/testsudoers.c:390
+#, c-format
+msgid "unknown group: %s"
+msgstr "잘못된 그룹: %s"
+
+#: plugins/sudoers/iolog.c:383 plugins/sudoers/sudoers.c:917
+#: plugins/sudoers/sudoreplay.c:304 plugins/sudoers/sudoreplay.c:817
+#: plugins/sudoers/sudoreplay.c:1021 plugins/sudoers/timestamp.c:387
+#: plugins/sudoers/visudo.c:954 plugins/sudoers/visudo_json.c:1001
+#: plugins/sudoers/visudo_json.c:1014
+#, c-format
+msgid "unable to open %s"
+msgstr "%s을(를) 열 수 없습니다"
+
+#: plugins/sudoers/iolog.c:433 plugins/sudoers/sudoers.c:921
+#: plugins/sudoers/sudoreplay.c:1132
+#, c-format
+msgid "unable to read %s"
+msgstr "%s을(를) 읽을 수 없습니다"
+
+#: plugins/sudoers/iolog.c:469 plugins/sudoers/sudoreplay.c:598
+#: plugins/sudoers/timestamp.c:286 plugins/sudoers/timestamp.c:289
+#, c-format
+msgid "unable to write to %s"
+msgstr "%s에 기록할 수 없습니다"
+
+#: plugins/sudoers/iolog.c:550 plugins/sudoers/iolog.c:775
+#, c-format
+msgid "unable to create %s"
+msgstr "%s을(를) 만들 수 없습니다"
+
+#: plugins/sudoers/iolog.c:1000 plugins/sudoers/iolog.c:1070
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "입출력 로그에 기록할 수 없습니다: %s"
+
+#: plugins/sudoers/iolog.c:1034
+#, c-format
+msgid "%s: internal error, file index %d not open"
+msgstr "%s: 내부 오류. 파일 인덱스 %d을(를) 열지 않았습니다"
+
+#: plugins/sudoers/ldap.c:431
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: 포트 값이 너무 큽니다"
+
+#: plugins/sudoers/ldap.c:491
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "지원하지 않는 LDAP URI 형식: %s"
+
+#: plugins/sudoers/ldap.c:518
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "ldap 및 ldaps URI를 함께 사용할 수 없습니다"
+
+#: plugins/sudoers/ldap.c:522 plugins/sudoers/ldap.c:558
+msgid "starttls not supported when using ldaps"
+msgstr "ldaps를 사용할 때 starttls를 지원하지 않습니다"
+
+#: plugins/sudoers/ldap.c:629
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "SSL 인증서 및 키 DB를 초기화할 수 없습니다: %s"
+
+#: plugins/sudoers/ldap.c:632
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "SSL을 사용하려면 %s에서 TLS_CERT를 설정해야 합니다"
+
+#: plugins/sudoers/ldap.c:1239
+msgid "unable to get GMT time"
+msgstr "GMT 시간을 가져올 수 없습니다"
+
+#: plugins/sudoers/ldap.c:1245
+msgid "unable to format timestamp"
+msgstr "타임스탬프를 형식에 맞출 수 없습니다"
+
+#: plugins/sudoers/ldap.c:1956
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/ldap.c:2528
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"LDAP 역할: %s\n"
+
+#: plugins/sudoers/ldap.c:2530
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"LDAP 역할: 알 수 없음\n"
+
+#: plugins/sudoers/ldap.c:2586
+#, c-format
+msgid " Order: %s\n"
+msgstr " 순서: %s\n"
+
+#: plugins/sudoers/ldap.c:2594 plugins/sudoers/parse.c:614
+#: plugins/sudoers/sssd.c:1625
+#, c-format
+msgid " Commands:\n"
+msgstr " 명령:\n"
+
+#: plugins/sudoers/ldap.c:3155
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "LDAP를 초기화할 수 없습니다: %s"
+
+#: plugins/sudoers/ldap.c:3191
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls를 지정했지만 LDAP 라이브러리에서 ldap_start_tls_s() 또는 ldap_start_tls_s_np() 함수를 지원하지 않습니다"
+
+#: plugins/sudoers/ldap.c:3440
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "잘못된 sudoOrder 속성: %s"
+
+#: plugins/sudoers/linux_audit.c:52
+msgid "unable to open audit system"
+msgstr "감시 시스템을 열 수 없습니다"
+
+#: plugins/sudoers/linux_audit.c:93
+msgid "unable to send audit message"
+msgstr "감시 메시지를 보낼 수 없습니다"
+
+#: plugins/sudoers/logging.c:106
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:134
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (명령 계속 실행) %s"
+
+#: plugins/sudoers/logging.c:163
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "로그 파일을 열 수 없습니다: %s"
+
+#: plugins/sudoers/logging.c:171
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "로그 파일을 잠글 수 없습니다: %s"
+
+#: plugins/sudoers/logging.c:204
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "로그 파일에 기록할 수 없습니다: %s"
+
+#: plugins/sudoers/logging.c:233
+msgid "No user or host"
+msgstr "사용자 또는 호스트 없음"
+
+#: plugins/sudoers/logging.c:235
+msgid "validation failure"
+msgstr "검증 실패"
+
+#: plugins/sudoers/logging.c:242
+msgid "user NOT in sudoers"
+msgstr "사용자가 sudoers에 없습니다"
+
+#: plugins/sudoers/logging.c:244
+msgid "user NOT authorized on host"
+msgstr "사용자가 호스트에서 인증하지 않았습니다"
+
+#: plugins/sudoers/logging.c:246
+msgid "command not allowed"
+msgstr "명령을 허용하지 않았습니다"
+
+#: plugins/sudoers/logging.c:281
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s은(는) sudoers 설정 파일에 없습니다. 이 시도를 보고합니다.\n"
+
+#: plugins/sudoers/logging.c:284
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s은(는) %s에서 sudo를 실행하도록 허가받지 않았습니다. 이 시도를 보고합니다.\n"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "죄송하지만, %s 사용자는 %s에서 sudo를 실행하면 안됩니다.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "죄송하지만 %1$s 사용자는 '%2$s%3$s%4$s'을(를) %8$s의 %5$s%6$s%7$s(으)로 실행하도록 허가받지 않았습니다.\n"
+
+#: plugins/sudoers/logging.c:328 plugins/sudoers/sudoers.c:471
+#: plugins/sudoers/sudoers.c:473 plugins/sudoers/sudoers.c:475
+#: plugins/sudoers/sudoers.c:477 plugins/sudoers/sudoers.c:1267
+#: plugins/sudoers/sudoers.c:1269
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: 명령이 없습니다"
+
+#: plugins/sudoers/logging.c:330 plugins/sudoers/sudoers.c:467
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"'.'에 무시 중인 \"%1$s\" 요소가 있습니다.\n"
+"\"%3$s\" 명령을 실행하려면, \"sudo ./%2$s\" 명령을 사용하십시오."
+
+#: plugins/sudoers/logging.c:347
+msgid "authentication failure"
+msgstr "인증 실패"
+
+#: plugins/sudoers/logging.c:373
+msgid "a password is required"
+msgstr "암호가 필요합니다"
+
+#: plugins/sudoers/logging.c:444 plugins/sudoers/logging.c:510
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "잘못된 암호 입력 시도 %u번"
+
+#: plugins/sudoers/logging.c:597
+msgid "unable to fork"
+msgstr "포킹할 수 없습니다"
+
+#: plugins/sudoers/logging.c:605 plugins/sudoers/logging.c:657
+#, c-format
+msgid "unable to fork: %m"
+msgstr "포킹할 수 없습니다: %m"
+
+#: plugins/sudoers/logging.c:647
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "파이프를 열 수 없습니다: %m"
+
+#: plugins/sudoers/logging.c:672
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "표준 입력을 복제할 수 없습니다: %m"
+
+#: plugins/sudoers/logging.c:710
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "%s을(를) 실행할 수 없습니다: %m"
+
+#: plugins/sudoers/match.c:771
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "%s 다이제스트(%s)는 %s 형식이 아닙니다"
+
+#: plugins/sudoers/mkdir_parents.c:65 plugins/sudoers/sudoers.c:932
+#: plugins/sudoers/visudo.c:440 plugins/sudoers/visudo.c:716
+#, c-format
+msgid "unable to stat %s"
+msgstr "%s의 상태를 가져올 수 없습니다"
+
+#: plugins/sudoers/parse.c:115
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "%s %d번째 줄에서 해석 오류"
+
+#: plugins/sudoers/parse.c:118
+#, c-format
+msgid "parse error in %s"
+msgstr "%s 해석 오류"
+
+#: plugins/sudoers/parse.c:540
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Sudoers 항목:\n"
+
+#: plugins/sudoers/parse.c:541
+#, c-format
+msgid " RunAsUsers: "
+msgstr " 실행 사용자: "
+
+#: plugins/sudoers/parse.c:555
+#, c-format
+msgid " RunAsGroups: "
+msgstr " 실행 그룹: "
+
+#: plugins/sudoers/parse.c:564
+#, c-format
+msgid " Options: "
+msgstr " 옵션: "
+
+#: plugins/sudoers/policy.c:241 plugins/sudoers/testsudoers.c:261
+msgid "unable to parse network address list"
+msgstr "네트워크 주소 목록을 해석할 수 없습니다"
+
+#: plugins/sudoers/policy.c:710 plugins/sudoers/visudo.c:892
+#, c-format
+msgid "unable to execute %s"
+msgstr "%s을(를) 실행할 수 없습니다"
+
+#: plugins/sudoers/policy.c:843
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Sudoers 정책 플러그인 버전 %s\n"
+
+#: plugins/sudoers/policy.c:845
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Sudoers 파일 문법 버전 %d\n"
+
+#: plugins/sudoers/policy.c:849
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Sudoers 경로: %s\n"
+
+#: plugins/sudoers/policy.c:852
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "nsswitch 경로: %s\n"
+
+#: plugins/sudoers/policy.c:854
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "ldap.conf 경로: %s\n"
+
+#: plugins/sudoers/policy.c:855
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "ldap.secret 경로: %s\n"
+
+#: plugins/sudoers/policy.c:888
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "%d 형식의 후크를 등록할 수 없습니다(버전 %d.%d)"
+
+#: plugins/sudoers/pwutil.c:162 plugins/sudoers/pwutil.c:180
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "%u uid를 캐시에 적재할 수 없습니다. 메모리가 부족합니다."
+
+#: plugins/sudoers/pwutil.c:174
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "%u uid를 캐시에 적재할 수 없습니다. 이미 존재합니다."
+
+#: plugins/sudoers/pwutil.c:234 plugins/sudoers/pwutil.c:251
+#: plugins/sudoers/pwutil.c:313 plugins/sudoers/pwutil.c:358
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "%s 사용자를 캐시에 적재할 수 없습니다. 메모리가 부족합니다."
+
+#: plugins/sudoers/pwutil.c:246
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "%s 사용자를 캐시에 적재할 수 없습니다. 이미 존재합니다."
+
+#: plugins/sudoers/pwutil.c:474 plugins/sudoers/pwutil.c:492
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "%u gid를 캐시에 적재할 수 없습니다. 메모리가 부족합니다."
+
+#: plugins/sudoers/pwutil.c:486
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "%u gid를 캐시에 적재할 수 없습니다. 이미 존재합니다."
+
+#: plugins/sudoers/pwutil.c:540 plugins/sudoers/pwutil.c:557
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:646
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "%s 그룹을 캐시에 적재할 수 없습니다. 메모리가 부족합니다."
+
+#: plugins/sudoers/pwutil.c:552
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "%s 그룹을 캐시에 적재할 수 없습니다. 이미 존재합니다."
+
+#: plugins/sudoers/pwutil.c:772 plugins/sudoers/pwutil.c:824
+#: plugins/sudoers/pwutil.c:874 plugins/sudoers/pwutil.c:926
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "%s 그룹 목록을 캐시에 적재할 수 없습니다. 이미 존재합니다."
+
+#: plugins/sudoers/pwutil.c:778 plugins/sudoers/pwutil.c:829
+#: plugins/sudoers/pwutil.c:880 plugins/sudoers/pwutil.c:931
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "%s 그룹 목록을 캐시에 적재할 수 없습니다. 메모리가 부족합니다."
+
+#: plugins/sudoers/pwutil.c:818
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "%s 그룹을 해석할 수 없습니다"
+
+#: plugins/sudoers/pwutil.c:920
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "%s 그룹 ID를 해석할 수 없습니다"
+
+#: plugins/sudoers/set_perms.c:113 plugins/sudoers/set_perms.c:469
+#: plugins/sudoers/set_perms.c:912 plugins/sudoers/set_perms.c:1234
+#: plugins/sudoers/set_perms.c:1551
+msgid "perm stack overflow"
+msgstr "perm 스택 오버플로우"
+
+#: plugins/sudoers/set_perms.c:121 plugins/sudoers/set_perms.c:400
+#: plugins/sudoers/set_perms.c:477 plugins/sudoers/set_perms.c:779
+#: plugins/sudoers/set_perms.c:920 plugins/sudoers/set_perms.c:1163
+#: plugins/sudoers/set_perms.c:1242 plugins/sudoers/set_perms.c:1484
+#: plugins/sudoers/set_perms.c:1559 plugins/sudoers/set_perms.c:1649
+msgid "perm stack underflow"
+msgstr "parm 스택 언더플로우"
+
+#: plugins/sudoers/set_perms.c:180 plugins/sudoers/set_perms.c:523
+#: plugins/sudoers/set_perms.c:1293 plugins/sudoers/set_perms.c:1591
+msgid "unable to change to root gid"
+msgstr "루트 gid로 바꿀 수 없습니다"
+
+#: plugins/sudoers/set_perms.c:269 plugins/sudoers/set_perms.c:620
+#: plugins/sudoers/set_perms.c:1049 plugins/sudoers/set_perms.c:1370
+msgid "unable to change to runas gid"
+msgstr "실행 gid로 바꿀 수 없습니다"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1375
+msgid "unable to set runas group vector"
+msgstr "실행 그룹 벡터를 설정할 수 없습니다"
+
+#: plugins/sudoers/set_perms.c:285 plugins/sudoers/set_perms.c:636
+#: plugins/sudoers/set_perms.c:1063 plugins/sudoers/set_perms.c:1384
+msgid "unable to change to runas uid"
+msgstr "실행 uid로 바꿀 수 없습니다"
+
+#: plugins/sudoers/set_perms.c:303 plugins/sudoers/set_perms.c:654
+#: plugins/sudoers/set_perms.c:1079 plugins/sudoers/set_perms.c:1400
+msgid "unable to change to sudoers gid"
+msgstr "sudoers gid로 바꿀 수 없습니다"
+
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1471
+#: plugins/sudoers/set_perms.c:1636
+msgid "too many processes"
+msgstr "동작 중인 프로세스가 너무 많습니다"
+
+#: plugins/sudoers/solaris_audit.c:51
+msgid "unable to get current working directory"
+msgstr "현재 작업 디렉터리를 가져올 수 없습니다"
+
+#: plugins/sudoers/solaris_audit.c:59
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "user_cmnd 감사 경로가 잘렸습니다: %s"
+
+#: plugins/sudoers/solaris_audit.c:66
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "argv[0] 감사 경로가 잘렸습니다: %s"
+
+#: plugins/sudoers/solaris_audit.c:115
+msgid "audit_failure message too long"
+msgstr "audit_failure 메시지가 너무 깁니다"
+
+#: plugins/sudoers/sssd.c:400
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "SSS 소스를 초기화할 수 없습니다. 머신에 SSSD를 설치했습니까?"
+
+#: plugins/sudoers/sssd.c:408 plugins/sudoers/sssd.c:417
+#: plugins/sudoers/sssd.c:426 plugins/sudoers/sssd.c:435
+#: plugins/sudoers/sssd.c:444
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "%2$s에서 \"%1$s\" 심볼을 찾을 수 없습니다"
+
+#: plugins/sudoers/sssd.c:1540
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: %s\n"
+msgstr ""
+"\n"
+"SSSD 역할: %s\n"
+
+#: plugins/sudoers/sssd.c:1545
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"SSSD 역할: 알 수 없음\n"
+
+#: plugins/sudoers/sudo_nss.c:290
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "%2$s에서 %1$s에 일치하는 기본 항목:\n"
+
+#: plugins/sudoers/sudo_nss.c:308
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "%s의 실행 권한 및 명령별 기본 값:\n"
+
+#: plugins/sudoers/sudo_nss.c:326
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "%s 사용자는 %s에서 다음 명령을 실행해야 합니다:\n"
+
+#: plugins/sudoers/sudo_nss.c:339
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "%s 사용자는 %s에서 sudo를 실행하도록 허가받지 않았습니다.\n"
+
+#: plugins/sudoers/sudoers.c:167 plugins/sudoers/testsudoers.c:247
+#: plugins/sudoers/visudo.c:233 plugins/sudoers/visudo.c:613
+#: plugins/sudoers/visudo.c:958
+msgid "unable to initialize sudoers default values"
+msgstr "sudoers 기본 값을 초기화할 수 없습니다"
+
+#: plugins/sudoers/sudoers.c:197 plugins/sudoers/sudoers.c:879
+msgid "problem with defaults entries"
+msgstr "기본 항목에 문제 발생"
+
+#: plugins/sudoers/sudoers.c:204
+msgid "no valid sudoers sources found, quitting"
+msgstr "올바른 sudoers 설정 원본이 없습니다. 나갑니다."
+
+#: plugins/sudoers/sudoers.c:243
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers에서 root가 sudo를 실행하지 못하게 지정했습니다"
+
+#: plugins/sudoers/sudoers.c:300
+msgid "you are not permitted to use the -C option"
+msgstr "-C 옵션 사용을 허가받지 않았습니다"
+
+#: plugins/sudoers/sudoers.c:389
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "타임스탬프 소유자(%s): 사용자 없음"
+
+#: plugins/sudoers/sudoers.c:404
+msgid "no tty"
+msgstr "tty 없음"
+
+#: plugins/sudoers/sudoers.c:405
+msgid "sorry, you must have a tty to run sudo"
+msgstr "죄송하지만 sudo를 실행하려면 tty를 확보해야합니다"
+
+#: plugins/sudoers/sudoers.c:466
+msgid "command in current directory"
+msgstr "현재 디렉터리의 명령"
+
+#: plugins/sudoers/sudoers.c:485
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "죄송하지만, 명령 처리 제한 시간을 설정할 수 없습니다"
+
+#: plugins/sudoers/sudoers.c:493
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "죄송하지만 이 환경 상태를 유지하도록 허가받지 않았습니다"
+
+#: plugins/sudoers/sudoers.c:824
+msgid "command too long"
+msgstr "명령이 너무 깁니다"
+
+#: plugins/sudoers/sudoers.c:936
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s은(는) 일반 파일이 아닙니다"
+
+#: plugins/sudoers/sudoers.c:940 plugins/sudoers/timestamp.c:213 toke.l:969
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s은(는) %u uid가 소유했지만, %u uid가 소유해야합니다"
+
+#: plugins/sudoers/sudoers.c:944 toke.l:974
+#, c-format
+msgid "%s is world writable"
+msgstr "%s에 모두가 기록할 수 있습니다"
+
+#: plugins/sudoers/sudoers.c:948 toke.l:977
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s은(는) %u gid가 소유했지만, %u gid가 소유해야합니다"
+
+#: plugins/sudoers/sudoers.c:981
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "루트만 \"-c %s\" 옵션을 사용할 수 있습니다"
+
+#: plugins/sudoers/sudoers.c:1000
+#, c-format
+msgid "unknown login class: %s"
+msgstr "알 수 없는 로그인 클래스: %s"
+
+#: plugins/sudoers/sudoers.c:1083 plugins/sudoers/sudoers.c:1111
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "%s 호스트를 해석할 수 없습니다"
+
+#: plugins/sudoers/sudoreplay.c:236
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "잘못된 필터 옵션: %s"
+
+#: plugins/sudoers/sudoreplay.c:249
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "잘못된 최대 대기 시간 값: %s"
+
+#: plugins/sudoers/sudoreplay.c:255
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "잘못된 속도 인수: %s"
+
+#: plugins/sudoers/sudoreplay.c:258 plugins/sudoers/visudo.c:186
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s 버전 %s\n"
+
+#: plugins/sudoers/sudoreplay.c:290
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/타이밍: %s"
+
+#: plugins/sudoers/sudoreplay.c:296
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/타이밍: %s"
+
+#: plugins/sudoers/sudoreplay.c:312
+#, c-format
+msgid "Replaying sudo session: %s\n"
+msgstr "sudo 세션 재현 중: %s\n"
+
+#: plugins/sudoers/sudoreplay.c:318
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "경고: 터미널 화면이 로그를 올바르게 나타내기에 너무 작습니다.\n"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "로그 화면 크기는 %d x %d 이지만, 터미널 화면 크기는 %d x %d 입니다."
+
+#: plugins/sudoers/sudoreplay.c:410
+msgid "unable to set tty to raw mode"
+msgstr "RAW 모드로 tty를 설정할 수 없습니다"
+
+#: plugins/sudoers/sudoreplay.c:439
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "잘못된 타이밍 파일 행: %s"
+
+#: plugins/sudoers/sudoreplay.c:659 plugins/sudoers/sudoreplay.c:684
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "모호한 식 \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:706
+msgid "unmatched ')' in expression"
+msgstr "수식에 일치하지 않는 ')'"
+
+#: plugins/sudoers/sudoreplay.c:710
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "알 수 없는 검색어 \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:725
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s에 인자가 필요합니다"
+
+#: plugins/sudoers/sudoreplay.c:728 plugins/sudoers/sudoreplay.c:1108
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "잘못된 정규 표현식: %s"
+
+#: plugins/sudoers/sudoreplay.c:732
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "\"%s\" 날짜를 해석할 수 없습니다"
+
+#: plugins/sudoers/sudoreplay.c:741
+msgid "unmatched '(' in expression"
+msgstr "수식에 일치하지 않는 '('"
+
+#: plugins/sudoers/sudoreplay.c:743
+msgid "illegal trailing \"or\""
+msgstr "잘못된 후위 연산자 \"or\""
+
+#: plugins/sudoers/sudoreplay.c:745
+msgid "illegal trailing \"!\""
+msgstr "잘못된 후위 문자 \"!\""
+
+#: plugins/sudoers/sudoreplay.c:794
+#, c-format
+msgid "unknown search type %d"
+msgstr "알 수 없는 검색 형식 %d"
+
+#: plugins/sudoers/sudoreplay.c:832
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: 잘못된 로그 파일"
+
+#: plugins/sudoers/sudoreplay.c:850
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: 타임스탬프 필드가 빠졌습니다"
+
+#: plugins/sudoers/sudoreplay.c:857
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: %s 타임스탬프: %s"
+
+#: plugins/sudoers/sudoreplay.c:864
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: 사용자 필드가 빠졌습니다"
+
+#: plugins/sudoers/sudoreplay.c:873
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: 실행 사용자 필드가 빠졌습니다"
+
+#: plugins/sudoers/sudoreplay.c:882
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: 실행 그룹 필드가 빠졌습니다"
+
+#: plugins/sudoers/sudoreplay.c:1245
+#, c-format
+msgid "usage: %s [-h] [-d dir] [-m num] [-s num] ID\n"
+msgstr "사용법: %s [-h] [-d <디렉터리>] [-m <숫자>] [-s <숫자>] <ID>\n"
+
+#: plugins/sudoers/sudoreplay.c:1248
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "사용법: %s [-h] [-d <디렉터리>] -l [<검색식>]\n"
+
+#: plugins/sudoers/sudoreplay.c:1257
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - sudo 세션 로그를 보여줍니다\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1259
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"옵션:\n"
+" -d, --directory=dir 세션 로그 디렉터리를 지정합니다\n"
+" -f, --filter=filter 화면에 나타낼 입출력 형식을 지정합니다\n"
+" -h, --help 도움말 메시지를 나타낸 후 빠져나갑니다\n"
+" -l, --list 유효한 세션 ID 및 추가 표현식을 보여줍니다\n"
+" -m, --max-wait=num 이벤트 처리간 초단위 최대 대기 시간\n"
+" -s, --speed=num 출력 속도를 올리거나 내립니다\n"
+" -V, --version 버전 정보를 나타낸 후 빠져나갑니다"
+
+#: plugins/sudoers/testsudoers.c:329
+msgid "\thost unmatched"
+msgstr "\t호스트가 일치하지 않습니다"
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"명령 허용함"
+
+#: plugins/sudoers/testsudoers.c:333
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"명령 거부함"
+
+#: plugins/sudoers/testsudoers.c:333
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"명령이 일치하지 않음"
+
+#: plugins/sudoers/timestamp.c:221
+#, c-format
+msgid "%s is group writable"
+msgstr "%s은(는) 그룹이 기록할 수 있습니다"
+
+#: plugins/sudoers/timestamp.c:297
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "타임스탬프 파일을 %lld 바이트로 자를 수 없습니다"
+
+#: plugins/sudoers/timestamp.c:742 plugins/sudoers/timestamp.c:809
+#: plugins/sudoers/visudo.c:501 plugins/sudoers/visudo.c:507
+msgid "unable to read the clock"
+msgstr "클록을 읽을 수 없습니다"
+
+#: plugins/sudoers/timestamp.c:756
+msgid "ignoring time stamp from the future"
+msgstr "미래 타임스탬프 값 무시"
+
+#: plugins/sudoers/timestamp.c:768
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "타임스탬프 값이 미래 값으로 너무 밀려있습니다: %20.20s"
+
+#: plugins/sudoers/timestamp.c:863
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "%s 타임스탬프 파일을 잠글 수 없습니다"
+
+#: plugins/sudoers/timestamp.c:907 plugins/sudoers/timestamp.c:927
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "지침 상태 경로가 너무 깁니다: %s/%s"
+
+#: plugins/sudoers/visudo.c:188
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s 문법 버전 %d\n"
+
+#: plugins/sudoers/visudo.c:266 plugins/sudoers/visudo.c:666
+#, c-format
+msgid "press return to edit %s: "
+msgstr "%s을(를) 편집하려면 return 키를 누르십시오:"
+
+#: plugins/sudoers/visudo.c:332
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "지정 편집기(%s)가 없습니다"
+
+#: plugins/sudoers/visudo.c:350
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "편집기가 없습니다(편집기 경로 = %s)"
+
+#: plugins/sudoers/visudo.c:460 plugins/sudoers/visudo.c:468
+msgid "write error"
+msgstr "쓰기 오류"
+
+#: plugins/sudoers/visudo.c:514
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "임시 파일 상태를 가져올 수 없습니다(%s). %s을(를) 바꾸지 않았습니다"
+
+#: plugins/sudoers/visudo.c:521
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "임시 파일 길이가 0입니다(%s). %s을(를) 바꾸지 않았습니다"
+
+#: plugins/sudoers/visudo.c:527
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "편집기(%s) 실패. %s을(를) 바꾸지 않았습니다."
+
+#: plugins/sudoers/visudo.c:549
+#, c-format
+msgid "%s unchanged"
+msgstr "%s 바꾸지 않음"
+
+#: plugins/sudoers/visudo.c:608
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "임시 파일(%s)을 다시 열 수 없습니다. %s을(를) 바꾸지 않았습니다."
+
+#: plugins/sudoers/visudo.c:620
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "임시 파일(%s)을 해석할 수 없습니다. 알 수 없는 오류."
+
+#: plugins/sudoers/visudo.c:657
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "내부 오류. %s을(를) 목록에서 찾을 수 없습니다!"
+
+#: plugins/sudoers/visudo.c:718 plugins/sudoers/visudo.c:727
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "%s의 uid/gid를 %u/%u 값으로 설정할 수 없습니다"
+
+#: plugins/sudoers/visudo.c:749
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s 및 %s은(는) 동일한 파일 시스템에 없습니다. mv 명령으로 이름을 바꿉니다"
+
+#: plugins/sudoers/visudo.c:763
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "명령 실행 실패: '%s %s %s', %s을(를) 바꾸지 않았습니다"
+
+#: plugins/sudoers/visudo.c:773
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "%s 이름 바꾸기 오류. %s을(를) 바꾸지 않았습니다"
+
+#: plugins/sudoers/visudo.c:837
+msgid "What now? "
+msgstr "어떻게 하시겠습니까?"
+
+#: plugins/sudoers/visudo.c:851
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"사용할 수 있는 옵션:\n"
+" sudoers 파일을 다시 편집합니다(E)\n"
+" sudoers 파일을 바꾼 상태에서 저장하지 않고 나갑니다(X)\n"
+" sudoers 파일을 바꾼 상태에서 저장하고 끝냅니다(Q)\n"
+
+#: plugins/sudoers/visudo.c:897
+#, c-format
+msgid "unable to run %s"
+msgstr "%s을(를) 실행할 수 없음"
+
+#: plugins/sudoers/visudo.c:927
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: 잘못된 소유자 uid/gid를 %u/%u 값으로 설정해야 합니다\n"
+
+#: plugins/sudoers/visudo.c:934
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: 잘못된 권한입니다. 0%o 모드 값을 설정해야 합니다\n"
+
+#: plugins/sudoers/visudo.c:963 plugins/sudoers/visudo_json.c:1021
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "%s 파일 해석에 실패했습니다. 알 수 없는 오류."
+
+#: plugins/sudoers/visudo.c:979 plugins/sudoers/visudo_json.c:1032
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "%s %d번째 줄 인근 해석 오류\n"
+
+#: plugins/sudoers/visudo.c:982 plugins/sudoers/visudo_json.c:1035
+#, c-format
+msgid "parse error in %s\n"
+msgstr "%s 해석 오류\n"
+
+#: plugins/sudoers/visudo.c:990 plugins/sudoers/visudo.c:997
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: 해석 성공\n"
+
+#: plugins/sudoers/visudo.c:1044
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s을(를) 사용중입니다. 나중에 다시 시도하십시오"
+
+#: plugins/sudoers/visudo.c:1141
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "오류: %3$s \"%4$s\"의 %1$s:%2$d사이클"
+
+#: plugins/sudoers/visudo.c:1142
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "경고: %3$s \"%4$s\"의 %1$s:%2$d사이클"
+
+#: plugins/sudoers/visudo.c:1146
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "오류: %s: %d %s \"%s\"을(를) 참조했지만 정의하지 않았습니다"
+
+#: plugins/sudoers/visudo.c:1147
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "경고: %s: %d %s \"%s\"을(를) 참조했지만 정의하지 않았습니다"
+
+#: plugins/sudoers/visudo.c:1300
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "경고: %s:%d 사용하지 않는 %s \"%s\"이(가) 있습니다"
+
+#: plugins/sudoers/visudo.c:1412
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - sudoers 파일을 안전하게 편집합니다\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1414
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+" -x, --export=output_file write sudoers in JSON format to output_file"
+msgstr ""
+"\n"
+"옵션:\n"
+" -c, --check 확인 전용 모드\n"
+" -f, --file=sudoers sudoers 파일 위치 지정\n"
+" -h, --help 도움말 메시지를 나타낸 후 빠져나갑니다\n"
+" -q, --quiet 자세한 문법 오류 메시지를 줄입니다(없앰)\n"
+" -s, --strict 엄격한 문법 검사 시행\n"
+" -V, --version 버전 정보를 나타낸 후 빠져나갑니다\n"
+" -x, --export=output_file sudoers 파일을 JSON 형식으로 output_file에 기록"
+
+#: plugins/sudoers/visudo_json.c:616 plugins/sudoers/visudo_json.c:651
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "알 수 없는 \"%s\" 기본 항목"
+
+#: plugins/sudoers/visudo_json.c:1007
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: 입출력 파일은 달라야합니다"
+
+#: toke.l:943
+msgid "too many levels of includes"
+msgstr "포함 레벨이 너무 많습니다"
+
+#~ msgid "Warning: cycle in %s `%s'"
+#~ msgstr "경고: %s의 사이클 `%s'"
+
+#~ msgid "Warning: %s `%s' referenced but not defined"
+#~ msgstr "경고: %s `%s'을(를) 참조했지만 정의하지 않았습니다"
diff --git a/plugins/sudoers/po/lt.mo b/plugins/sudoers/po/lt.mo
new file mode 100644
index 0000000..380ae50
--- /dev/null
+++ b/plugins/sudoers/po/lt.mo
Binary files differ
diff --git a/plugins/sudoers/po/lt.po b/plugins/sudoers/po/lt.po
new file mode 100644
index 0000000..8db0e29
--- /dev/null
+++ b/plugins/sudoers/po/lt.po
@@ -0,0 +1,1682 @@
+# SOME DESCRIPTIVE TITLE.
+# This file is put in the public domain.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+# Algimantas Margevičius <margevicius.algimantas@gmail.com>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.4rc1\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2012-02-06 15:48-0500\n"
+"PO-Revision-Date: 2012-02-25 11:56+0200\n"
+"Last-Translator: Algimantas Margevičius <margevicius.algimantas@gmail.com>\n"
+"Language-Team: Lithuanian <komp_lt@konferencijos.lt>\n"
+"Language: lt\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
+
+#: plugins/sudoers/alias.c:125
+#, c-format
+msgid "Alias `%s' already defined"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:61 plugins/sudoers/bsm_audit.c:64
+#: plugins/sudoers/bsm_audit.c:113 plugins/sudoers/bsm_audit.c:117
+#: plugins/sudoers/bsm_audit.c:169 plugins/sudoers/bsm_audit.c:173
+msgid "getaudit: failed"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:91 plugins/sudoers/bsm_audit.c:154
+msgid "Could not determine audit condition"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:102
+msgid "getauid failed"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:104 plugins/sudoers/bsm_audit.c:163
+msgid "au_open: failed"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:175
+msgid "au_to_subject: failed"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:179
+msgid "au_to_exec_args: failed"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:127 plugins/sudoers/bsm_audit.c:188
+msgid "au_to_return32: failed"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:130 plugins/sudoers/bsm_audit.c:191
+msgid "unable to commit audit record"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:161
+msgid "getauid: failed"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:184
+msgid "au_to_text: failed"
+msgstr ""
+
+#: plugins/sudoers/check.c:158
+#, c-format
+msgid "sorry, a password is required to run %s"
+msgstr ""
+
+#: plugins/sudoers/check.c:249 plugins/sudoers/iolog.c:172
+#: plugins/sudoers/sudoers.c:992 plugins/sudoers/sudoreplay.c:348
+#: plugins/sudoers/sudoreplay.c:357 plugins/sudoers/sudoreplay.c:703
+#: plugins/sudoers/sudoreplay.c:797 plugins/sudoers/visudo.c:790
+#, c-format
+msgid "unable to open %s"
+msgstr ""
+
+#: plugins/sudoers/check.c:253 plugins/sudoers/iolog.c:202
+#, c-format
+msgid "unable to write to %s"
+msgstr ""
+
+#: plugins/sudoers/check.c:261 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:556 plugins/sudoers/iolog.c:123
+#: plugins/sudoers/iolog.c:156
+#, c-format
+msgid "unable to mkdir %s"
+msgstr ""
+
+#: plugins/sudoers/check.c:396
+#, c-format
+msgid "internal error, expand_prompt() overflow"
+msgstr ""
+
+#: plugins/sudoers/check.c:456
+#, c-format
+msgid "timestamp path too long: %s"
+msgstr ""
+
+#: plugins/sudoers/check.c:485 plugins/sudoers/check.c:529
+#: plugins/sudoers/iolog.c:158
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr ""
+
+#: plugins/sudoers/check.c:488 plugins/sudoers/check.c:532
+#: plugins/sudoers/check.c:577
+#, c-format
+msgid "%s owned by uid %u, should be uid %u"
+msgstr ""
+
+#: plugins/sudoers/check.c:493 plugins/sudoers/check.c:537
+#, c-format
+msgid "%s writable by non-owner (0%o), should be mode 0700"
+msgstr ""
+
+#: plugins/sudoers/check.c:501 plugins/sudoers/check.c:545
+#: plugins/sudoers/check.c:613 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:582
+#, c-format
+msgid "unable to stat %s"
+msgstr ""
+
+#: plugins/sudoers/check.c:571
+#, c-format
+msgid "%s exists but is not a regular file (0%o)"
+msgstr ""
+
+#: plugins/sudoers/check.c:583
+#, c-format
+msgid "%s writable by non-owner (0%o), should be mode 0600"
+msgstr ""
+
+#: plugins/sudoers/check.c:637
+#, c-format
+msgid "timestamp too far in the future: %20.20s"
+msgstr ""
+
+#: plugins/sudoers/check.c:684
+#, c-format
+msgid "unable to remove %s (%s), will reset to the epoch"
+msgstr ""
+
+#: plugins/sudoers/check.c:692
+#, c-format
+msgid "unable to reset %s to the epoch"
+msgstr ""
+
+#: plugins/sudoers/check.c:752 plugins/sudoers/check.c:758
+#: plugins/sudoers/sudoers.c:829 plugins/sudoers/sudoers.c:833
+#, c-format
+msgid "unknown uid: %u"
+msgstr ""
+
+#: plugins/sudoers/check.c:755 plugins/sudoers/sudoers.c:770
+#: plugins/sudoers/sudoers.c:1108 plugins/sudoers/testsudoers.c:218
+#: plugins/sudoers/testsudoers.c:362
+#, c-format
+msgid "unknown user: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:27
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:31
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:35
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:39
+msgid "Put OTP prompt on its own line"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:43
+msgid "Ignore '.' in $PATH"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:47
+msgid "Always send mail when sudo is run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:51
+msgid "Send mail if user authentication fails"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:55
+msgid "Send mail if the user is not in sudoers"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:59
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:63
+msgid "Send mail if the user is not allowed to run a command"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:67
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:71
+msgid "Lecture user the first time they run sudo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:75
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:79
+msgid "Require users to authenticate by default"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:83
+msgid "Root may run sudo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:87
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:91
+msgid "Log the year in the (non-syslog) log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:95
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:99
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:103
+msgid "Always set $HOME to the target user's home directory"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:107
+msgid "Allow some information gathering to give useful error messages"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:111
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:115
+msgid "Insult the user when they enter an incorrect password"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:119
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:123
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:127
+msgid "Prompt for root's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:131
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:135
+msgid "Prompt for the target user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:139
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:143
+msgid "Set the LOGNAME and USER environment variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:147
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:151
+msgid "Don't initialize the group vector to that of the target user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:155
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %d"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:159
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:163
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:167
+#, c-format
+msgid "Number of tries to enter a password: %d"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:171
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:175
+#, c-format
+msgid "Path to log file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:179
+#, c-format
+msgid "Path to mail program: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:183
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:187
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:191
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:195
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:199
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:203
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:207
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:211
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:215
+#, c-format
+msgid "Default password prompt: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:219
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr ""
+
+#: plugins/sudoers/def_data.c:223
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:227
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:231
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:235
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:239
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:243
+msgid "Preload the dummy exec functions contained in \"_PATH_SUDO_NOEXEC"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:247
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:251
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:255
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:259
+msgid "Allow users to set arbitrary environment variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:263
+msgid "Reset the environment to a default set of variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:267
+msgid "Environment variables to check for sanity:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:271
+msgid "Environment variables to remove:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:275
+msgid "Environment variables to preserve:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:279
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:283
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:287
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:291
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:295
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:299
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:303
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:307
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:311
+msgid "Log user's input for the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:315
+msgid "Log the output of the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:319
+msgid "Compress I/O logs using zlib"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:323
+msgid "Always run commands in a pseudo-tty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:327
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:331
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:335
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:339
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:343
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:208
+#, c-format
+msgid "unknown defaults entry `%s'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
+#: plugins/sudoers/defaults.c:246 plugins/sudoers/defaults.c:259
+#: plugins/sudoers/defaults.c:272 plugins/sudoers/defaults.c:285
+#: plugins/sudoers/defaults.c:298 plugins/sudoers/defaults.c:318
+#: plugins/sudoers/defaults.c:328
+#, c-format
+msgid "value `%s' is invalid for option `%s'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:219 plugins/sudoers/defaults.c:229
+#: plugins/sudoers/defaults.c:237 plugins/sudoers/defaults.c:254
+#: plugins/sudoers/defaults.c:267 plugins/sudoers/defaults.c:280
+#: plugins/sudoers/defaults.c:293 plugins/sudoers/defaults.c:313
+#: plugins/sudoers/defaults.c:324
+#, c-format
+msgid "no value specified for `%s'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:242
+#, c-format
+msgid "values for `%s' must start with a '/'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:304
+#, c-format
+msgid "option `%s' does not take a value"
+msgstr ""
+
+#: plugins/sudoers/env.c:258
+#, c-format
+msgid "internal error, sudo_setenv() overflow"
+msgstr ""
+
+#: plugins/sudoers/env.c:291
+#, c-format
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr ""
+
+#: plugins/sudoers/env.c:710
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr ""
+
+#: plugins/sudoers/find_path.c:69 plugins/sudoers/find_path.c:108
+#: plugins/sudoers/find_path.c:123 plugins/sudoers/iolog.c:125
+#: plugins/sudoers/sudoers.c:923 toke.l:668 toke.l:823
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: gram.y:110
+#, c-format
+msgid ">>> %s: %s near line %d <<<"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:91
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: plugins/sudoers/group_plugin.c:103
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s turi priklausyti uid %d"
+
+#: plugins/sudoers/group_plugin.c:107
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s turi būti įrašomas tik savininkui"
+
+#: plugins/sudoers/group_plugin.c:114
+#, c-format
+msgid "unable to dlopen %s: %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:119
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:124
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:112
+msgid "Local IP address and netmask pairs:\n"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:179 plugins/sudoers/sudoers.c:999
+#, c-format
+msgid "unable to read %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:182
+#, c-format
+msgid "invalid sequence number %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:231 plugins/sudoers/iolog.c:234
+#: plugins/sudoers/iolog.c:499 plugins/sudoers/iolog.c:504
+#: plugins/sudoers/iolog.c:510 plugins/sudoers/iolog.c:518
+#: plugins/sudoers/iolog.c:526 plugins/sudoers/iolog.c:534
+#: plugins/sudoers/iolog.c:542
+#, c-format
+msgid "unable to create %s"
+msgstr ""
+
+#: plugins/sudoers/iolog_path.c:256 plugins/sudoers/sudoers.c:362
+#, c-format
+msgid "unable to set locale to \"%s\", using \"C\""
+msgstr ""
+
+#: plugins/sudoers/ldap.c:374
+#, c-format
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:397
+#, c-format
+msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:427
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:456
+#, c-format
+msgid "invalid uri: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:462
+#, c-format
+msgid "unable to mix ldap and ldaps URIs"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:466
+#, c-format
+msgid "unable to mix ldaps and starttls"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:485
+#, c-format
+msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:550
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:958
+#, c-format
+msgid "unable to get GMT time"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:964
+#, c-format
+msgid "unable to format timestamp"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:972
+#, c-format
+msgid "unable to build time filter"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1185
+#, c-format
+msgid "sudo_ldap_build_pass1 allocation mismatch"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1705
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1707
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1754
+#, c-format
+msgid " Order: %s\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1762
+#, c-format
+msgid " Commands:\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2161
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2192
+#, c-format
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2428
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:57
+#, c-format
+msgid "unable to open audit system"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:82
+#, c-format
+msgid "internal error, linux_audit_command() overflow"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:91
+#, c-format
+msgid "unable to send audit message"
+msgstr ""
+
+#: plugins/sudoers/logging.c:198
+#, c-format
+msgid "unable to open log file: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:201
+#, c-format
+msgid "unable to lock log file: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:256
+msgid "user NOT in sudoers"
+msgstr ""
+
+#: plugins/sudoers/logging.c:258
+msgid "user NOT authorized on host"
+msgstr ""
+
+#: plugins/sudoers/logging.c:260
+msgid "command not allowed"
+msgstr ""
+
+#: plugins/sudoers/logging.c:270
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s nėra „sudoers“ faile. Apie šį įvykį bus pranešta.\n"
+
+#: plugins/sudoers/logging.c:273
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s neleidžiama vykdyti „sudo“ kompiuteryje %s. Apie šį įvykį bus pranešta.\n"
+
+#: plugins/sudoers/logging.c:277
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Deja, naudotojas %s negali vykdyti „sudo“ kompiuteryje %s.\n"
+
+#: plugins/sudoers/logging.c:280
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Deja, naudotojui %s neleidžiama vykdyti „%s%s%s“ kaip %s%s%s kompiuteryje %s.\n"
+
+#: plugins/sudoers/logging.c:420
+#, c-format
+msgid "unable to fork"
+msgstr ""
+
+#: plugins/sudoers/logging.c:427 plugins/sudoers/logging.c:489
+#, c-format
+msgid "unable to fork: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:479
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:504
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:540
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:755
+#, c-format
+msgid "internal error: insufficient space for log line"
+msgstr ""
+
+#: plugins/sudoers/parse.c:123
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr ""
+
+#: plugins/sudoers/parse.c:126
+#, c-format
+msgid "parse error in %s"
+msgstr ""
+
+#: plugins/sudoers/parse.c:389
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+
+#: plugins/sudoers/parse.c:391
+#, c-format
+msgid " RunAsUsers: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:406
+#, c-format
+msgid " RunAsGroups: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:415
+#, c-format
+msgid ""
+" Commands:\n"
+"\t"
+msgstr ""
+
+#: plugins/sudoers/plugin_error.c:100 plugins/sudoers/plugin_error.c:105
+msgid ": "
+msgstr ": "
+
+#: plugins/sudoers/pwutil.c:260
+#, c-format
+msgid "unable to cache uid %u (%s), already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:268
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:305 plugins/sudoers/pwutil.c:314
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:655
+#, c-format
+msgid "unable to cache gid %u (%s), already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:663
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:693 plugins/sudoers/pwutil.c:702
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:114 plugins/sudoers/set_perms.c:365
+#: plugins/sudoers/set_perms.c:601 plugins/sudoers/set_perms.c:837
+msgid "perm stack overflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:122 plugins/sudoers/set_perms.c:373
+#: plugins/sudoers/set_perms.c:609 plugins/sudoers/set_perms.c:845
+msgid "perm stack underflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:228 plugins/sudoers/set_perms.c:466
+#: plugins/sudoers/set_perms.c:706
+msgid "unable to change to runas gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:236 plugins/sudoers/set_perms.c:473
+#: plugins/sudoers/set_perms.c:713
+msgid "unable to change to runas uid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:250 plugins/sudoers/set_perms.c:486
+#: plugins/sudoers/set_perms.c:726
+#, c-format
+msgid "unable to change to sudoers gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:291 plugins/sudoers/set_perms.c:524
+#: plugins/sudoers/set_perms.c:764 plugins/sudoers/set_perms.c:906
+msgid "too many processes"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:970
+msgid "unable to set runas group vector"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:243
+#, c-format
+msgid "Matching Defaults entries for %s on this host:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:256
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:269
+#, c-format
+msgid "User %s may run the following commands on this host:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:279
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Naudotojui %s neleidžiama vykdyti „sudo“ kompiuteryje %s.\n"
+
+#: plugins/sudoers/sudoers.c:201 plugins/sudoers/sudoers.c:232
+#: plugins/sudoers/sudoers.c:931
+msgid "problem with defaults entries"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:205
+#, c-format
+msgid "no valid sudoers sources found, quitting"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:257
+#, c-format
+msgid "unable to execute %s: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:311
+#, c-format
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:318
+#, c-format
+msgid "you are not permitted to use the -C option"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:408
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:424
+msgid "no tty"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:425
+#, c-format
+msgid "sorry, you must have a tty to run sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:464
+msgid "No user or host"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:478 plugins/sudoers/sudoers.c:499
+#: plugins/sudoers/sudoers.c:500 plugins/sudoers/sudoers.c:1509
+#: plugins/sudoers/sudoers.c:1510
+#, c-format
+msgid "%s: command not found"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:480 plugins/sudoers/sudoers.c:496
+#, c-format
+msgid ""
+"ignoring `%s' found in '.'\n"
+"Use `sudo ./%s' if this is the `%s' you wish to run."
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:485
+msgid "validation failure"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:495
+msgid "command in current directory"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:507
+#, c-format
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:657 plugins/sudoers/sudoers.c:664
+#, c-format
+msgid "internal error, runas_groups overflow"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:914
+#, c-format
+msgid "internal error, set_cmnd() overflow"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:957
+#, c-format
+msgid "fixed mode on %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:961
+#, c-format
+msgid "set group on %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:964
+#, c-format
+msgid "unable to set group on %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "unable to fix mode on %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:980
+#, c-format
+msgid "%s is not a regular file"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:982
+#, c-format
+msgid "%s is mode 0%o, should be 0%o"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s priklauso uid %u, nors turėtų %u"
+
+#: plugins/sudoers/sudoers.c:989
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s priklauso gid %u, nors turėtų %u"
+
+#: plugins/sudoers/sudoers.c:1038
+#, c-format
+msgid "only root can use `-c %s'"
+msgstr "„-c %s“ gali naudoti tik „root“ naudotojas"
+
+#: plugins/sudoers/sudoers.c:1049
+#, c-format
+msgid "unknown login class: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1077
+#, c-format
+msgid "unable to resolve host %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1129 plugins/sudoers/testsudoers.c:380
+#, c-format
+msgid "unknown group: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1178
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1180
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1184
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1187
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1189
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1190
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:286
+#, c-format
+msgid "invalid filter option: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:299
+#, c-format
+msgid "invalid max wait: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:305
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:308 plugins/sudoers/visudo.c:187
+#, c-format
+msgid "%s version %s\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:333
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:339
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:364
+#, c-format
+msgid "invalid log file %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:366
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:392
+#, c-format
+msgid "unable to set tty to raw mode"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:406
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:448
+#, c-format
+msgid "writing to standard output"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:480
+#, c-format
+msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:529 plugins/sudoers/sudoreplay.c:554
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:571
+#, c-format
+msgid "too many parenthesized expressions, max %d"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:582
+#, c-format
+msgid "unmatched ')' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:588
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:602
+#, c-format
+msgid "%s requires an argument"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:606
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:612
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:625
+#, c-format
+msgid "unmatched '(' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:627
+#, c-format
+msgid "illegal trailing \"or\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:629
+#, c-format
+msgid "illegal trailing \"!\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:851
+#, c-format
+msgid "invalid regex: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:976
+#, c-format
+msgid "usage: %s [-h] [-d directory] [-m max_wait] [-s speed_factor] ID\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:979
+#, c-format
+msgid "usage: %s [-h] [-d directory] -l [search expression]\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:988
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:990
+msgid ""
+"\n"
+"Options:\n"
+" -d directory specify directory for session logs\n"
+" -f filter specify which I/O type to display\n"
+" -h display help message and exit\n"
+" -l [expression] list available session IDs that match expression\n"
+" -m max_wait max number of seconds to wait between events\n"
+" -s speed_factor speed up or slow down output\n"
+" -V display version information and exit"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:246
+#, c-format
+msgid "internal error, init_vars() overflow"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:331
+msgid "\thost unmatched"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:334
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:335
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:335
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+
+#: toke.l:672 toke.l:802 toke.l:827 toke.l:923 plugins/sudoers/toke_util.c:113
+#: plugins/sudoers/toke_util.c:167 plugins/sudoers/toke_util.c:207
+msgid "unable to allocate memory"
+msgstr ""
+
+#: toke.l:795
+msgid "too many levels of includes"
+msgstr ""
+
+#: plugins/sudoers/toke_util.c:218
+msgid "fill_args: buffer overflow"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:188
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:221 plugins/sudoers/auth/rfc1938.c:104
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:253 plugins/sudoers/visudo.c:539
+#, c-format
+msgid "press return to edit %s: "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:336 plugins/sudoers/visudo.c:342
+#, c-format
+msgid "write error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:424
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:429
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:435
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:458
+#, c-format
+msgid "%s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:484
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr ""
+
+#: plugins/sudoers/visudo.c:494
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:532
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:584 plugins/sudoers/visudo.c:593
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:588 plugins/sudoers/visudo.c:598
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:615
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:629
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:702
+msgid "What now? "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:716
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:757
+#, c-format
+msgid "unable to execute %s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:764
+#, c-format
+msgid "unable to run %s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:796
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:808
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:811
+#, c-format
+msgid "parse error in %s\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:814 plugins/sudoers/visudo.c:816
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:826
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:833
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:880
+#, c-format
+msgid "%s busy, try again later"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:924
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:947
+#, c-format
+msgid "unable to stat editor (%s)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:995
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1089
+#, c-format
+msgid "Error: cycle in %s_Alias `%s'"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1090
+#, c-format
+msgid "Warning: cycle in %s_Alias `%s'"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1093
+#, c-format
+msgid "Error: %s_Alias `%s' referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1094
+#, c-format
+msgid "Warning: %s_Alias `%s' referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1229
+#, c-format
+msgid "%s: unused %s_Alias %s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1286
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1288
+msgid ""
+"\n"
+"Options:\n"
+" -c check-only mode\n"
+" -f sudoers specify sudoers file location\n"
+" -h display help message and exit\n"
+" -q less verbose (quiet) syntax error messages\n"
+" -s strict syntax checking\n"
+" -V display version information and exit"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:78
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:84
+msgid "unable to begin bsd authentication"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:92
+msgid "invalid authentication type"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:101
+msgid "unable to setup authentication"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:60
+#, c-format
+msgid "unable to read fwtk config"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:65
+#, c-format
+msgid "unable to connect to authentication server"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:71 plugins/sudoers/auth/fwtk.c:95
+#: plugins/sudoers/auth/fwtk.c:128
+#, c-format
+msgid "lost connection to authentication server"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:75
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:117
+#, c-format
+msgid "%s: unable to unparse princ ('%s'): %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:160
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:170
+#, c-format
+msgid "%s: unable to resolve ccache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:218
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize ccache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:251
+#, c-format
+msgid "%s: unable to store cred in ccache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:316
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:331
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:100
+msgid "unable to initialize PAM"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:144
+msgid "account validation failure, is your account locked?"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:148
+msgid "Account or password is expired, reset your password and try again"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:155
+#, c-format
+msgid "pam_chauthtok: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:159
+msgid "Password expired, contact your system administrator"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:163
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:178
+#, c-format
+msgid "pam_authenticate: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:306
+msgid "Password: "
+msgstr "Slaptažodis: "
+
+#: plugins/sudoers/auth/pam.c:307
+msgid "Password:"
+msgstr "Slaptažodis:"
+
+#: plugins/sudoers/auth/securid5.c:81
+#, c-format
+msgid "failed to initialise the ACE API library"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:107
+#, c-format
+msgid "unable to contact the SecurID server"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:116
+#, c-format
+msgid "User ID locked for SecurID Authentication"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:120 plugins/sudoers/auth/securid5.c:171
+#, c-format
+msgid "invalid username length for SecurID"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:176
+#, c-format
+msgid "invalid Authentication Handle for SecurID"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:128
+#, c-format
+msgid "SecurID communication failed"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:132 plugins/sudoers/auth/securid5.c:215
+#, c-format
+msgid "unknown SecurID error"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:166
+#, c-format
+msgid "invalid passcode length for SecurID"
+msgstr ""
+
+#: plugins/sudoers/auth/sia.c:109
+msgid "unable to initialize SIA session"
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:117
+msgid "Invalid authentication methods compiled into sudo! You may mix standalone and non-standalone authentication."
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:199
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:271
+#, c-format
+msgid "%d incorrect password attempt"
+msgid_plural "%d incorrect password attempts"
+msgstr[0] ""
+msgstr[1] ""
+
+#: plugins/sudoers/auth/sudo_auth.c:374
+msgid "Authentication methods:"
+msgstr ""
diff --git a/plugins/sudoers/po/nb.mo b/plugins/sudoers/po/nb.mo
new file mode 100644
index 0000000..6b5a288
--- /dev/null
+++ b/plugins/sudoers/po/nb.mo
Binary files differ
diff --git a/plugins/sudoers/po/nb.po b/plugins/sudoers/po/nb.po
new file mode 100644
index 0000000..d045bd9
--- /dev/null
+++ b/plugins/sudoers/po/nb.po
@@ -0,0 +1,2404 @@
+# Norwegian bokmål translation of sudoers.
+# This file is distributed under the same license as the sudo package.
+# Copyright (C) 2017 Free Software Foundation, Inc.
+# Todd C. Miller <Todd.Miller@courtesan.com>, 2011-2013.
+# Åka Sikrom <a4@hush.com>, 2014-2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers-1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-30 08:49+0100\n"
+"Last-Translator: Åka Sikrom <a4@hush.com>\n"
+"Language-Team: Norwegian Bokmaal <i18n-nb@lister.ping.uio.no>\n"
+"Language: nb\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.8.7.1\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "syntaksfeil"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "passord for %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] passord for %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Passord:"
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** SIKKERHETSinformasjon om %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Feil. Prøv igjen."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336
+#: gram.y:399 gram.y:407 gram.y:417 gram.y:450 gram.y:457 gram.y:464
+#: gram.y:471 gram.y:553 gram.y:560 gram.y:569 gram.y:578 gram.y:595
+#: gram.y:707 gram.y:714 gram.y:721 gram.y:729 gram.y:829 gram.y:836
+#: gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890 gram.y:897
+#: gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:195 plugins/sudoers/logging.c:511
+#: plugins/sudoers/logging.c:532 plugins/sudoers/logging.c:573
+#: plugins/sudoers/logging.c:752 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr "klarte ikke å tildele minne"
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr "kontrollsummering krever at du velger et stinavn"
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr "ugyldig «notbefore»-verdi"
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr "ugyldig «notafter»-verdi"
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr "for langt tidsavbrudd"
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr "ugyldig tidsavbrudd"
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:354 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:511 plugins/sudoers/logging.c:532
+#: plugins/sudoers/logging.c:572 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:724 plugins/sudoers/match.c:771
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1008
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Alias «%s» er allerede definert"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "klarte ikke å hente innloggingsklasse for brukeren %s"
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr "klarte ikke å starte bsd-autentisering"
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr "ugyldig autentiseringstype"
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr "klarte ikke å starte opp BSD-autentisering"
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr "kontoen din er utgått"
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr "godkjenning mislyktes"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr "klarte ikke å lese fwtk-innstillinger"
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr "klarte ikke å koble til autentiseringstjener"
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr "tilkobling til autentiseringstjener ble brutt"
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"det oppstod en feil med autentiseringstjener:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: klarte ikke å konvertere fullmaktsgiver til streng («%s»). %s"
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: klarte ikke å tolke «%s». %s"
+
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: klarte ikke å slå opp i akkreditiv-hurtiglager. %s"
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: klarte ikke å tildele innstillinger. %s"
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: klarte ikke å hente akkreditiver. %s"
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: klarte ikke å starte opp akkreditiv-hurtiglager. %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: klarte ikke å lagre akkreditiv i hurtiglager. %s"
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: klarte ikke å hente vertens fullmaktsgiver. %s"
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Klarte ikke å bekrefte TGT! Dette kan være et tegn på at du er under angrep! %s"
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr "klarte ikke å starte opp PAM"
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Feil ved PAM-autentisering. %s"
+
+#: plugins/sudoers/auth/pam.c:221
+msgid "account validation failure, is your account locked?"
+msgstr "det oppstod en feil ved validering av brukerkonto. Er kontoen din sperret?"
+
+#: plugins/sudoers/auth/pam.c:229
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Kontoen eller passordet er utgått. Tilbakestill passordet ditt og prøv igjen"
+
+#: plugins/sudoers/auth/pam.c:238
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "klarte ikke å endre et utgått passord. %s"
+
+#: plugins/sudoers/auth/pam.c:246
+msgid "Password expired, contact your system administrator"
+msgstr "Passordet er utgått. Kontakt systemadministratoren"
+
+#: plugins/sudoers/auth/pam.c:250
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Kontoen er utgått, eller PAM-innstillingene mangler en «account»-del for sudo. Kontakt systemadministratoren"
+
+#: plugins/sudoers/auth/pam.c:257 plugins/sudoers/auth/pam.c:262
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "Feil med PAM-kontohåndtering: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:232
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "du finnes ikke i %s-databasen"
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr "klarte ikke å starte opp ACE API-biblioteket"
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr "klarte ikke å kontakte SecurID-tjener"
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr "Bruker-ID-en er sperret fra SecurID-autentisering"
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr "lengden på brukernavnet er ugyldig for SecurID"
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr "ugyldig autentiseringshåndtak for SecurID"
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr "Det oppstod en feil under kommunikasjon med SecurID"
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr "ukjent SecurID-feil"
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr "kodelengden er ugyldig for SecurID"
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr "kalrte ikke å starte opp SIA-økt"
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr "ugyldige autentiseringsmetoder"
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Din installasjon av sudo har ugyldige autentiseringsmetoder! Du kan ikke blande selvgående og tjeneravhengige autentiseringsmetoder."
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr "fant ingen autentiseringsmetoder"
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Din installasjon av sudo har ingen autentiseringsmetoder tilgjengelig! Bruk valget «--disable-authentication» hvis du vil skru av autentisering."
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr "Klarte ikke å starte opp autentiseringsmetoder."
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr "Autentiseringsmetoder:"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr "Klarte ikke å finne revisjonsstatus"
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr "klarte ikke å kjøre revisjonsoppføring"
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Vi går ut i fra at systemadministrator har gitt deg en\n"
+"typisk moralpreken om det du gjør. Det koker som regel ned til tre ting:\n"
+"\n"
+" #1) Ha respekt for andres privatliv og personvern.\n"
+" #2) Tenk før du skriver.\n"
+" #3) Makt medfører plikt og ansvar.\n"
+"\n"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr "uid-en «%u» er ukjent"
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1136
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr "brukeren %s er ukjent"
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "økning: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "begynnende rekkefølge: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr "sorteringsutfylling: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s versjon %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s gramatikkversjon %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr "inndata-format %s støttes ikke"
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr "utdata-format %s støttes ikke"
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: inndata- og utdatafiler må være ulike"
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:238
+#: plugins/sudoers/visudo.c:594 plugins/sudoers/visudo.c:917
+msgid "unable to initialize sudoers default values"
+msgstr "klarte ikke å laste inn standardverdier for sudoers"
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: nøkkelord %s er ukjent"
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "%s er en ukjent forvalgtype"
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "%s er en ukjent utelatelsestype"
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr "%s er et ugyldig filter"
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:913
+#, c-format
+msgid "unable to open %s"
+msgstr "klarte ikke å åpne %s"
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:922
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "klarte ikke å tolke %s. Ukjent feil"
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:939
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "tolkefeil i %s ved linje %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:942
+#, c-format
+msgid "parse error in %s\n"
+msgstr "tolkefeil i %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr "klarte ikke å skrive til %s"
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s - konverter mellom «sudoers»-filformater\n"
+"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Valg:\n"
+" -b, --base=dn base-domenenavn for sudo LDAP-forespørsler\n"
+" -d, --defaults=deftypes bare konverter standardverdier av valgte typer\n"
+" -e, --expand-aliases utvid aliaser ved konvertering\n"
+" -f, --output-format=format velg utdata-format («JSON», «LDIF» eller «sudoers»)\n"
+" -i, --input-format=format velg inndata-format («LDIF» eller «sudoers»)\n"
+" -I, --increment=tall mengde som hver sudoOrder skal økes med\n"
+" -h, --help vis hjelpetekst og avslutt\n"
+" -m, --match=filter bare konverter oppføringer som samsvarer med valgt filter\n"
+" -M, --match-local filtrer på passwd- og group-databaser\n"
+" -o, --output=utdatafile lagre konvertert sudoers i valgt utdatafil\n"
+" -O, --order-start=num startpunkt for første sudoOrder\n"
+" -p, --prune-matches fjern brukere, grupper og vertsnavn som ikke samsvarer\n"
+" -P, --padding=num grunnutfylling for sudoOrder-økning\n"
+" -s, --suppress=områder fjern utdata for valgte områder\n"
+" -V, --version vis versjonsinfo og avslutt"
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "forvalg «%s» er ukjent"
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr "klarte ikke å hente GMT-tid"
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr "klarte ikke å formatere tidsstempel"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1015 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "intern feil: %s er full"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr "sudoers inneholder for mange linjer. Maksgrense er %u"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "miljøvariabel «SUDOERS_BASE» er tom, og «-b» er ikke valgt."
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Syslog-plassering, hvis syslog brukes til loggføring: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Syslog-prioritet når brukeren har autentisert seg: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Syslog-prioritet når brukeren ikke har klart å autentisere seg: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "Legg OTP-ledetekst på egen linje"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "Ignorer «.» i $PATH"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "Send alltid e-post når noen kjører sudo"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "Send e-post hvis en bruker mislykkes i å autentisere seg"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "Send e-post hvis bruker ikke finnes i sudoers-fil"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Send e-post hvis brukeren ikke finnes i sudoers-fil for denne verten"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Send e-post hvis brukeren ikke har lov til å kjøre en kommando"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "Send e-post hvis brukeren prøver å kjøre en kommando"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Bruk separat tidsstempel for hver kombinasjon av bruker og tty"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "Gi brukere en moralpreken første gang de kjører sudo"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Fil som inneholder sudo-moralpreken: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "Krev at brukere skal autentisere seg som standard"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "Rotbruker kan kjøre sudo"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Ta med vertsnavn i loggfil (ikke syslog)"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Ta med år i loggfil (ikke syslog)"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Start et skall hvis sudo kjøres uten argumenter"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Velg målbrukers $HOME når et skall startes med «-s»"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Bruk alltid målbrukers hjemmemappe som $HOME"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Tillat informasjonsinnhenting for å gjøre feilmeldingene nyttige"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Krev fullstendige vertsnavn i sudoers-fil"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Send brukere en fornærmelsestekst når de oppgir feil passord"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Bare tillat brukere å kjøre sudo hvis de bruker en tty"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo tar hensyn til miljøvariabelen EDITOR"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "Spør etter rotbrukers passord, i stedet for eget passord"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Spør etter passord for «runas_default» i stedet for eget passord"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Spør etter målbrukers passord, i stedet for eget passord"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Bruk standardverdier i målbrukers innloggingsklasse, hvis den finnes"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Gi verdier til miljøvariablene «LOGNAME» og «USER»"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Velg målbrukers uid som effektiv uid, i stedet for faktisk uid"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Ikke last inn målbrukers gruppevektor"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Hvilken lengde linjer i loggfiler skal pakkes ned til (bruk 0 for å deaktivere pakking): %u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Tidsavbrudd for autentiseringstidsstempel: %.1f minutter"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Tidsavbrudd for passordetterspørsel: %.1f minutter"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Antall forsøk på å skrive inn passord: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "U-maske som skal brukes, eller 0777 for å bruke egen maske: 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Sti til loggfil: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Sti til e-postprogram: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Valg for e-postprogram: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Hvilken adresse det skal sendes e-post til: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Hvilken adresse e-posten skal sendes fra: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Emnelinje i e-postmeldinger: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Melding om feil passord: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Sti til mappe for moralpreken-status: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Sti til mappe for autentiseringstidsstempel: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Eieren av mappa for autentiseringstidsstempel: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Brukerne i denne gruppa fritas fra passord- og PATH-krav: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Standard passord-ledetekst: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Hvis dette er valgt, blir system-ledetekst alltid overstyrt av passord-ledetekst."
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Standardbruker for kjøring av kommandoer: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Verdi som overstyrer brukerspesifikk $PATH: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Filsti til tekstbehandler som visudo skal bruke: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Når pseudokommandoen «list» skal kreve passord: %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Når pseudokommandoen «verify» skal kreve passord: %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Last inn prøvekjøringsfunksjonene som ligger i biblioteket «sudo_noexec»"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Om lokal sudoers-fil skal ignoreres når en LDAP er aktiv"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Fildeskriptorne >= %d lukkes før en kommando blir kjørt"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Hvis dette er valgt, har brukerne mulighet til å overstyre «closefrom»-verdien med valget «-C»"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Tillat brukere å velge arbitrære miljøvariabler"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "Tilbakestill brukermiljøet til et sett med standardvariabler"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "Miljøvariabler som skal kontrolleres:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "Miljøvariabler som skal fjernes:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "Miljøvariabler som skal beholdes:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "SELinux-rolle som skal brukes i ny sikkerhetskontekst: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "SELinux-type som skal brukes i ny sikkerhetskontekst: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Sti til sudo-spesifikk miljøfil: %s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Sti til sudo-spesifikk miljøfil: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Regioninnstilling som skal brukes når «sudoers» tolkes: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Tillat sudo å spørre etter et passord som - hvis skrevet inn - blir synlig på skjermen"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Gi visuell respons når brukere skriver inn passord"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Bruk raskere joker-søking som er mindre presis (og som ikke søker i filsystemet)"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "U-masker som er valgt i sudoers overstyrer brukermasker, selv hvis sudoers åpner for mer tilgang enn brukermaska"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "Loggfør bruker-inndata i kommandoen som kjøres"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "Loggfør utskrift fra kommandoen som kjøres"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "Komprimer inn- og utdatalogger ved bruk av «zlib»"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "Kjør alltid kommandoer i en pseudo-tty"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Støttetillegg for grupper som ikke er Unix-grupper: %s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Mappe hvor inn- og utdatalogger skal lagres: %s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Fil hvor inn- og utdatalogger skal lagres: %s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Legg til en oppføring i utmp-/utmpx-fil ved tildeling av pty"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Kjør kommandoer som utmp-bruker, i stedet for brukeren som skriver inn kommando"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Tillatte privilegier: %s"
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Begrensningsprivilegier: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "Kjør kommandoer på en pty i bakgrunnen"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "PAM-tjenestenavn som skal brukes: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "PAM-tjenestenavn som skal brukes til innloggingsskall: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Prøv å sette opp PAM-akkreditiver for målbruker"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "Lag en ny PAM-økt som kommandoen kjøres i"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Høyeste tillatte sekvensnummer i inn-/utdatalogg: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "Slå på støtte for sudoers-nettgruppe"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Kontroller skrivetillatelse til foreldermapper ved redigering av filer med sudoedit"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Følg symbolske lenker ved redigering av filer med sudoedit"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "Spør gruppetillegget om ukjente systemgrupper"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Kontroller nettgrupper basert på både bruker, vert og domene"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Tillat kjøring av kommandoer selv om sudo ikke klarer å skrive til revisjonslogg"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Tillat kjøring av kommandoer selv om sudo ikke klarer å skrive til I/O-logg"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Tillat kjøring av kommandoer selv om sudo ikke klarer å skrive til loggfil"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Slå opp grupper i sudoers på gruppe-ID i stedet for gruppenavn"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Loggoppføringer som er større enn dette blir delt opp i flere syslog-meldinger: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Bruker som skal eie I/O-loggfiler: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Gruppe som skal eie I/O-loggfiler: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Filmodus for I/O-loggfiler: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Kjør kommandoer med fildeskriptor i stedet for sti: %s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Ignorer ukjente standardverdier i sudoers i stedet for å vise advarsel"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "TIdsavbrudd for kommando: %u sekunder"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "La bruker velge tidsavbrudd via kommandolinje"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Tøm inn- og utdata direkte til disk i stedet for å mellomlagre"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "Ta med prosess-ID ved bruk av syslog"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Type autentiseringstidsstempel: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "Feilmelding ved autentisering: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "Ignorer små/store bokstaver i brukernavn"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "Ignorer små/store bokstaver i gruppenavn"
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s: %d «%s» er en ukjent standardoppføring"
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: «%s» er en ukjent standardoppføring"
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s: %d «%s» har ingen verdi"
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: «%s» har ingen verdi"
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d verdier av «%s» må begynne med «/»"
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: verdier av «%s» må begynne med «/»"
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d «%s» kan ikke ha en verdi"
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: «%s» kan ikke ha en verdi"
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d Defaults-type 0x%x for valget «%s» er ugyldig"
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: Defaults-type 0x%x for valget «%s» er ugyldig"
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d «%s» er en ugyldig verdi for valget «%s»"
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: verdien «%s» er ugyldig valget «%s»"
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: envp er korrupt (lengde samsvarer ikke)"
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr "klarte ikke å bygge opp miljøet på nytt"
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "du har ikke tillatelse til å bestemme følgende miljøvariabler: %s"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "tolkningsfeil i %s ved linje %d"
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "tolkningsfeil i %s"
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "behandlingstype %d for %s støttes ikke"
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr "%s: lesefeil"
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s må eies av uid %d"
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s kan ikke gi skrivetillatelse til andre enn eieren"
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "klarte ikke å laste inn %s. %s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "fant ikke symbolet «group_plugin» i %s"
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: versjon %d av gruppetillegget passer ikke (forventet versjon %d)"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "klarte ikke å tolke IP-adresse «%s»"
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "klarte ikke å tolke nettverksmaske «%s»"
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Lokale par av IP-adresser og nettverksmasker:\n"
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s finnes, men er ikke en mappe (0%o)"
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "klarte ikke å utføre mkdir %s"
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:723
+#: plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "klarte ikke å endre %s modus til 0%o"
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1167
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr "%s er en ukjent gruppe"
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr "klarte ikke å lese %s"
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr "klarte ikke å opprette %s"
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "klarte ikke å skrive til I/O-loggfil: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr "%s: intern feil. Inn-/ut-loggfil for hendelse %d er ikke åpen"
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr "%s: intern feil. Signal %d er ugyldig"
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: ugyldig loggfil"
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: tidsstempel-felt mangler"
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: tidsstempel %s: %s"
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: brukerfelt mangler"
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: «kjør som bruker»-felt mangler"
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: «kjør som gruppe»-felt mangler"
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr "starttls støttes ikke når du bruker ldaps"
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "klarte ikke å starte opp database for SSL-sertifikater og -nøkler. %s"
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "du må velge TLS_CERT i %s for å bruke SSL"
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "klarte ikke å starte opp LDAP. %s"
+
+#: plugins/sudoers/ldap.c:1648
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls er valgt, men LDAP-bibliotekene støtter hverken «ldap_start_tls_s()» eller «ldap_start_tls_s_np()»"
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "«%s» er en ugyldig sudoOrder-attributt"
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: portnummeret er for stort"
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "LDAP-ens adressetype %s støttes ikke"
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "du kan ikke blande ldap- og ldaps-nettadresser"
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "klarte ikke å konvertere sudoOption: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "klarte ikke å åpne revisjonssystemet"
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr "klarte ikke å sende revisjonsmelding"
+
+#: plugins/sudoers/logging.c:113
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:141
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (kommando fortsetter) %s"
+
+#: plugins/sudoers/logging.c:170
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "klarte ikke å åpne loggfil: %s"
+
+#: plugins/sudoers/logging.c:178
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "klarte ikke å låse loggfil: %s"
+
+#: plugins/sudoers/logging.c:211
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "klarte ikke å skrive loggfil: %s"
+
+#: plugins/sudoers/logging.c:240
+msgid "No user or host"
+msgstr "Ingen bruker eller vert"
+
+#: plugins/sudoers/logging.c:242
+msgid "validation failure"
+msgstr "feil ved gyldighetssjekk"
+
+#: plugins/sudoers/logging.c:249
+msgid "user NOT in sudoers"
+msgstr "brukeren er IKKE i sudoers"
+
+#: plugins/sudoers/logging.c:251
+msgid "user NOT authorized on host"
+msgstr "brukeren er IKKE autorisert på verten"
+
+#: plugins/sudoers/logging.c:253
+msgid "command not allowed"
+msgstr "denne kommandoen tillates ikke"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s finnes ikke i sudoers-fil. Denne hendelsen blir rapportert.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s has ikke tillatelse til å kjøre sudo på %s. Denne hendelsen blir rapportert.\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Brukeren %s kan ikke kjøre sudo på %s.\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Brukeren %s har ikke tillatelse til å kjøre «%s%s%s» som %s%s%s på %s.\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: fant ikke kommando"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"ignorerer «%s» i «.».\n"
+"Bruk «sudo ./%s» hvis dette er «%s»-programmet du prøver å kjøre."
+
+#: plugins/sudoers/logging.c:354
+msgid "authentication failure"
+msgstr "feil ved autentisering"
+
+#: plugins/sudoers/logging.c:380
+msgid "a password is required"
+msgstr "du må oppgi et passord"
+
+#: plugins/sudoers/logging.c:443
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u mislykket passordforsøk"
+msgstr[1] "%u mislykkede passordforsøk"
+
+#: plugins/sudoers/logging.c:666
+msgid "unable to fork"
+msgstr "klarte ikke å kopiere prosess"
+
+#: plugins/sudoers/logging.c:674 plugins/sudoers/logging.c:726
+#, c-format
+msgid "unable to fork: %m"
+msgstr "klarte ikke å kopiere prosess. %m"
+
+#: plugins/sudoers/logging.c:716
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "klarte ikke å åpne datarør. %m"
+
+#: plugins/sudoers/logging.c:741
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "klarte ikke å duplisere standard innkanal. %m"
+
+#: plugins/sudoers/logging.c:779
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "klarte ikke å kjøre %s. %m"
+
+#: plugins/sudoers/match.c:874
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "behandlingen for %s (%s) er ikke i %s-skjemaet"
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:421 plugins/sudoers/visudo.c:717
+#, c-format
+msgid "unable to stat %s"
+msgstr "klarte ikke å lage statistikk av %s"
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"LDAP-rolle: %s\n"
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Oppføring i sudoers:\n"
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr " Kjør som-brukere: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr " Kjør som-grupper: "
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr " Valg: "
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr " Kommandoer:\n"
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Standardoppføringer som gjelder for %s på %s:\n"
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Kjør-som- og kommandospesifikke standardoppføringer for %s:\n"
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Brukeren %s kan kjøre følgende kommandoer på %s:\n"
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Brukeren %s har ikke tillatelse til å kjøre sudo på %s.\n"
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "ignorerer ugyldig attributtverdi: %s"
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "ignorerer ufullstendig sudoRole: cn: %s"
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "ugyldig %.*s fra sudo-grenseflate"
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr "klarte ikke å tolke nettverksadresse-liste"
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr "sudo-grenseflate har ikke angitt brukernavn"
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr "sudo-grenseflate har ikke angitt bruker-ID"
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr "sudo-grenseflate har ikke angitt gruppe-ID"
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr "sudo-grenseflate har ikke angitt vertsnavn"
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:220
+#: plugins/sudoers/visudo.c:851
+#, c-format
+msgid "unable to execute %s"
+msgstr "klarte ikke å kjøre %s"
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Sudoers regeltillegg versjon %s\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Sudoers-grammatikkversjon %d\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Sti til «sudoers»-fil: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "Sti til «nsswitch»: %s\n"
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "Sti til «ldap.conf»: %s\n"
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "Stil til «ldap.secret»: %s\n"
+
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "klarte ikke å tildele krok av typen %d (versjon %d.%d)"
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "klarte ikke å hurtiglagre uid %u. Minnet er fullt"
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "klarte ikke å hurtiglagre uid %u. Uid-en eksisterer allerede"
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "klarte ikke å hurtiglagre brukeren %s. Minnet er fullt"
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "klarte ikke å hurtiglagre brukeren %s. Brukeren eksisterer allerede"
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "klarte ikke å hurtiglagre gid %u. Minnet er fullt"
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "klarte ikke å hurtiglagre gid %u. Gid-en eksisterer allerede"
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "klarte ikke å hurtiglagre gruppa %s. Minnet er fullt"
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "klarte ikke å hurtiglagre gruppa %s. Gruppa eksisterer allerede"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "klarte ikke å hurtiglagre liste over %s. Lista eksisterer allerede"
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "klarte ikke å hurtiglagre liste over %s. Minnet er fullt"
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "klarte ikke å tolke grupper for %s"
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "klarte ikke å tolke gid-er for %s"
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr "perm-stabelen er full"
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr "perm-stabelen er tom"
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr "klarte ikke å endre gid til rotbruker"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr "klarte ikke å endre til kjør som-gid"
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr "klarte ikke å velge «kjør som»-gruppevektor"
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr "klarte ikke å endre uid til «kjør som»-bruker"
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr "klarte ikke å endre gid til sudoers"
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr "for mange prosesser"
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr "klarte ikke å hente gjeldende arbeidsmappe"
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "forkortet revisjonssti «user_cmnd»: %s"
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "forkortet revisjonssti «argv[0]»: %s"
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr "audit_failure-meldinga er for lang"
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "klarte ikke å starte opp SSS-kilde. Har du installert SSSD på maskinen?"
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "fant ikke symbolet «%s» i %s"
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr "det har oppstått et problem med én eller flere standardoppføringer"
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr "fant ingen gyldig sudoers-kilde. Avslutter."
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers-fil tillater ikke rotbruker å kjøre sudo"
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr "du har ikke tillatelse til å bruke valget «-C»"
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "eier («%s») av tidsstempel finnes ikke"
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr "ingen tty"
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr "du må ha en tty for å kunne kjøre sudo"
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr "kommando i gjeldende mappe"
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "du har ikke tillatelse til å velge tidsavbrudd for kommandoer"
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "du har ikke tillatelse til å beholde brukermiljøet"
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr "kommandoen er for lang"
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s er ikke en vanlig fil"
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s eies av uid %u, som skulle vært %u"
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr "%s kan overskrives av alle"
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s eies av gid %u, som skulle vært %u"
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "du må være rotbruker for å velge «-c %s»"
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr "innloggingsklasse %s er ukjent"
+
+#: plugins/sudoers/sudoers.c:1069 plugins/sudoers/sudoers.c:1083
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "klarte ikke å slå opp vertsnavn %s"
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "%s er et ugyldig filtervalg"
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "%s er ugyldig maksimal ventetid"
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "%s er en ugyldig hastighetsfaktor"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/tidsberegning: %s"
+
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/tidsberegning: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Spiller av sudo-økt i reprise: %s"
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr "klarte ikke å legge hendelse i kø"
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr "klarte ikke å velge råmodus for tty"
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Advarsel: terminalen din er for liten for å spille av loggen skikkelig.\n"
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Loggens størrelse er %d x %d, mens terminalstørrelsen din er %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Sudo-reprise ferdig. Trykk på en knapp for å gå tilbake til terminal."
+
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "linja for tidsberegningsfil er ugyldig: %s"
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "uttrykket «%s» er flertydig"
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr "fant ingenting som samsvarer med deluttrykket «)»"
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "«%s» er et ukjent søkevalg"
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s krever at du bruker et argument"
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "%s er et ugyldig regulært uttrykk"
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "klarte ikke å tolke datoen «%s»"
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr "uttrykkets «(» samsvarer ikke"
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr "du kan ikke avslutte med «or»"
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr "du kan ikke avslutte med «!»"
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr "«%d» er en ukjent søketype"
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr "bruk: %s [-hnRS] [-d mappe] [-m tall] [-s tall] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "bruk: %s [-h] [-d dir] -l [søkeuttrykk]\n"
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - spill av sudo-øktlogg\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Valg:\n"
+" -d, --directory=dir velg øktlogg-mappe\n"
+" -f, --filter=filter velg hvilke(n) inn- og utdatatype(r) som skal vises\n"
+" -h, --help vis hjelpetekst og avslutt\n"
+" -l, --list vis tilgjengelige ID-er, med valgfritt uttrykk\n"
+" -m, --max-wait=num maskimal ventetid mellom hendelser (i sekunder)\n"
+" -S, --suspend-wait vent mens kommando er på pause\n"
+" -s, --speed=num øk eller senk utskriftshastigheten\n"
+" -V, --version vis versjon og avslutt"
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr "\tvert samsvarer ikke"
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Kommando tillatt"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Kommandoen tillates ikke"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Kommandoen samsvarer ikke"
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr "%s kan overskrives av gruppa den tilhører"
+
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "klarte ikke å korte ned tidsstempel-fil til %lld byte"
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:482 plugins/sudoers/visudo.c:488
+msgid "unable to read the clock"
+msgstr "klarte ikke å lese klokka"
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr "tidsstempel for fremtidig tidspunkt blir ignorert"
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "tidsstempelet er for langt inn i fremtiden: %20.20s"
+
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "klarte ikke å låse tidsstempel-fil %s"
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "filsti for moralpreken-status («%s/%s») er for lang"
+
+#: plugins/sudoers/visudo.c:216
+msgid "the -x option will be removed in a future release"
+msgstr "valget «-x» blir fjernet i en fremtidig versjon"
+
+#: plugins/sudoers/visudo.c:217
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "bruk verktøyet cvtsudoers i stedet"
+
+#: plugins/sudoers/visudo.c:268 plugins/sudoers/visudo.c:650
+#, c-format
+msgid "press return to edit %s: "
+msgstr "trykk linjeskift for å redigere %s: "
+
+#: plugins/sudoers/visudo.c:329
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "finner ikke valgt redigeringsprogram (%s)"
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "fant ingen redigeringsprogram («editor»-sti = %s)"
+
+#: plugins/sudoers/visudo.c:441 plugins/sudoers/visudo.c:449
+msgid "write error"
+msgstr "skrivefeil"
+
+#: plugins/sudoers/visudo.c:495
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "klarte ikke å undersøke midlertidig fil (%s). %s er ikke endret"
+
+#: plugins/sudoers/visudo.c:502
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "midlertidig fil (%s) er tom. %s er ikke endret"
+
+#: plugins/sudoers/visudo.c:508
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "noe gikk galt med behandleren (%s). %s er ikke endret"
+
+#: plugins/sudoers/visudo.c:530
+#, c-format
+msgid "%s unchanged"
+msgstr "%s er ikke endret"
+
+#: plugins/sudoers/visudo.c:589
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "klarte ikke å åpne midlertidig fil (%s) på nytt. %s er ikke endret"
+
+#: plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "klarte ikke å tolke midlertidig fil (%s). Ukjent feil"
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "intern feil: fant ikke %s i lista!"
+
+#: plugins/sudoers/visudo.c:719 plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "klarte ikke å endre uid og gid for %s til (%u, %u)"
+
+#: plugins/sudoers/visudo.c:751
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s og %s er ikke på samme filsystem. Bruker «mv» til å gi nye navn"
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "kommando mislyktes. «%s %s %s». %s er ikke endret"
+
+#: plugins/sudoers/visudo.c:775
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "klarte ikke å gi %s nytt navn. %s er ikke endret"
+
+#: plugins/sudoers/visudo.c:796
+msgid "What now? "
+msgstr "Hva nå? "
+
+#: plugins/sudoers/visudo.c:810
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Du har følgende valgmuligheter:\n"
+" (e) rediger sudoers-fil på nytt\n"
+" (x) avslutt uten å lagre endringer i sudoers-fil\n"
+" (Q) avslutt og lagre endringene i sudoers-fil (FARLIG!)\n"
+
+#: plugins/sudoers/visudo.c:856
+#, c-format
+msgid "unable to run %s"
+msgstr "klarte ikke å kjøre %s"
+
+#: plugins/sudoers/visudo.c:886
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: feil eier. uid og gid skulle vært «%u, %u»\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: feil tillatelsesmodus. Skulle vært modus 0%o\n"
+
+#: plugins/sudoers/visudo.c:950 plugins/sudoers/visudo.c:957
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: lest og tolket OK\n"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s er opptatt. Prøv igjen senere"
+
+#: plugins/sudoers/visudo.c:979
+#, c-format
+msgid "unable to lock %s"
+msgstr "klarte ikke å låse %s"
+
+#: plugins/sudoers/visudo.c:980
+msgid "Edit anyway? [y/N]"
+msgstr "Vil du redigere likevel [j/N]"
+
+#: plugins/sudoers/visudo.c:1064
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Feil: %s:%d sløyfe i %s «%s»"
+
+#: plugins/sudoers/visudo.c:1065
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Advarsel: %s:%d sløyfe i %s «%s»"
+
+#: plugins/sudoers/visudo.c:1069
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Feil: %s:%d referanse til %s «%s», som ikke er definert"
+
+#: plugins/sudoers/visudo.c:1070
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Advarsel: %s:%d referanse til %s «%s», som ikke er definert"
+
+#: plugins/sudoers/visudo.c:1161
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Advarsel: %s:%d %s «%s» står ubrukt"
+
+#: plugins/sudoers/visudo.c:1276
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - rediger sudoers-fil på en trygg måte\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1278
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"Valg:\n"
+" -c, --check undersøkelsesmodus\n"
+" -f, --file=sudoers oppgi hvor sudoers-fila ligger\n"
+" -h, --help vis denne hjelpeteksten og avslutt\n"
+" -q, --quiet mindre detaljerte meldinger om syntaksfeil\n"
+" -s, --strict streng syntakskontroll\n"
+" -V, --version vis versjon og avslutt\n"
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr "du har for mange nivåer av inkluderte filer"
+
+#~ msgid ""
+#~ "\n"
+#~ "LDAP Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "LDAP-role: UKJENT\n"
+
+#~ msgid " Order: %s\n"
+#~ msgstr " Sorter: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: %s\n"
+#~ msgstr ""
+#~ "\n"
+#~ "SSSD-rolle: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "SSSD-rolle: UKJENT\n"
+
+#~ msgid "Warning: cycle in %s `%s'"
+#~ msgstr "Advarsel: sløyfe i %s «%s»"
+
+#~ msgid "Warning: %s `%s' referenced but not defined"
+#~ msgstr "Advarsel: det refereres til %s «%s», som ikke er definert"
+
+#~ msgid "Warning: unused %s `%s'"
+#~ msgstr "Advarsel: %s «%s» er ubrukt"
+
+#~ msgid "unable allocate memory"
+#~ msgstr "klarte ikke å tildele minne"
+
+#~ msgid "timestamp path too long: %s/%s"
+#~ msgstr "filstien «%s/%s» for tidsstempel er for lang"
+
+#~ msgid "unable to stat editor (%s)"
+#~ msgstr "klarte ikke å undersøke redigeringsprogrammet (%s)"
+
+#~ msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+#~ msgstr "sudo_ldap_conf_add_ports: ikke nok lagringsplass for å utvide vertens hurtiglager"
+
+#~ msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+#~ msgstr "sudo_ldap_parse_uri: ikke nok lagringsplass til å bygge opp vertens hurtiglager"
+
+#~ msgid "sudo_ldap_build_pass1 allocation mismatch"
+#~ msgstr "sudo_ldap_build_pass1 samsvar ikke ved tildeling"
+
+#~ msgid "internal error: insufficient space for log line"
+#~ msgstr "intern feil: logglinje mangler plass"
+
+#~ msgid "fill_args: buffer overflow"
+#~ msgstr "fill_args: hurtiglageret er fullt"
diff --git a/plugins/sudoers/po/nl.mo b/plugins/sudoers/po/nl.mo
new file mode 100644
index 0000000..c40147a
--- /dev/null
+++ b/plugins/sudoers/po/nl.mo
Binary files differ
diff --git a/plugins/sudoers/po/nl.po b/plugins/sudoers/po/nl.po
new file mode 100644
index 0000000..3ea66a0
--- /dev/null
+++ b/plugins/sudoers/po/nl.po
@@ -0,0 +1,2282 @@
+# Dutch translation for sudoers.
+# This file is distributed under the same license as the sudo package.
+# P. Hamming <peterhamming@gmail.com>, 2013.
+# Benno Schulenberg <vertaling@coevern.nl>, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.22b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2017-12-01 15:42-0700\n"
+"PO-Revision-Date: 2017-12-05 21:44+0100\n"
+"Last-Translator: Benno Schulenberg <vertaling@coevern.nl>\n"
+"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
+"Language: nl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Poedit 2.0.4\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "invoerfout"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "%p's wachtwoord: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] wachtwoord voor %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Wachtwoord: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** VEILIGHEIDSinformatie voor %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Sorry, probeer het opnieuw."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:307 gram.y:314 gram.y:321 gram.y:328 gram.y:335
+#: gram.y:398 gram.y:406 gram.y:416 gram.y:449 gram.y:456 gram.y:463
+#: gram.y:470 gram.y:552 gram.y:559 gram.y:568 gram.y:577 gram.y:594
+#: gram.y:706 gram.y:713 gram.y:720 gram.y:728 gram.y:824 gram.y:831
+#: gram.y:838 gram.y:845 gram.y:852 gram.y:878 gram.y:885 gram.y:892
+#: gram.y:1015 gram.y:1195 gram.y:1202 plugins/sudoers/alias.c:124
+#: plugins/sudoers/alias.c:139 plugins/sudoers/auth/bsdauth.c:141
+#: plugins/sudoers/auth/kerb5.c:119 plugins/sudoers/auth/kerb5.c:145
+#: plugins/sudoers/auth/pam.c:490 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/auth/sia.c:59 plugins/sudoers/defaults.c:650
+#: plugins/sudoers/defaults.c:905 plugins/sudoers/defaults.c:1076
+#: plugins/sudoers/editor.c:64 plugins/sudoers/editor.c:82
+#: plugins/sudoers/editor.c:93 plugins/sudoers/env.c:233
+#: plugins/sudoers/filedigest.c:120 plugins/sudoers/filedigest_gcrypt.c:90
+#: plugins/sudoers/filedigest_openssl.c:111 plugins/sudoers/gc.c:52
+#: plugins/sudoers/group_plugin.c:134 plugins/sudoers/interfaces.c:71
+#: plugins/sudoers/iolog.c:941 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:449 plugins/sudoers/ldap.c:480
+#: plugins/sudoers/ldap.c:532 plugins/sudoers/ldap.c:566
+#: plugins/sudoers/ldap.c:974 plugins/sudoers/ldap.c:1168
+#: plugins/sudoers/ldap.c:1179 plugins/sudoers/ldap.c:1195
+#: plugins/sudoers/ldap.c:1487 plugins/sudoers/ldap.c:1647
+#: plugins/sudoers/ldap.c:1729 plugins/sudoers/ldap.c:1877
+#: plugins/sudoers/ldap.c:1901 plugins/sudoers/ldap.c:1990
+#: plugins/sudoers/ldap.c:2005 plugins/sudoers/ldap.c:2101
+#: plugins/sudoers/ldap.c:2134 plugins/sudoers/ldap.c:2215
+#: plugins/sudoers/ldap.c:2297 plugins/sudoers/ldap.c:2394
+#: plugins/sudoers/ldap.c:3228 plugins/sudoers/ldap.c:3260
+#: plugins/sudoers/ldap.c:3572 plugins/sudoers/ldap.c:3600
+#: plugins/sudoers/ldap.c:3616 plugins/sudoers/ldap.c:3706
+#: plugins/sudoers/ldap.c:3722 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:189 plugins/sudoers/logging.c:451
+#: plugins/sudoers/logging.c:472 plugins/sudoers/logging.c:684
+#: plugins/sudoers/logging.c:942 plugins/sudoers/match.c:617
+#: plugins/sudoers/match.c:664 plugins/sudoers/match.c:714
+#: plugins/sudoers/match.c:738 plugins/sudoers/match.c:826
+#: plugins/sudoers/match.c:915 plugins/sudoers/parse.c:252
+#: plugins/sudoers/parse.c:264 plugins/sudoers/parse.c:279
+#: plugins/sudoers/parse.c:291 plugins/sudoers/policy.c:441
+#: plugins/sudoers/policy.c:678 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/pwutil.c:165 plugins/sudoers/pwutil.c:236
+#: plugins/sudoers/pwutil.c:312 plugins/sudoers/pwutil.c:486
+#: plugins/sudoers/pwutil.c:551 plugins/sudoers/pwutil.c:620
+#: plugins/sudoers/pwutil.c:778 plugins/sudoers/pwutil.c:835
+#: plugins/sudoers/pwutil.c:880 plugins/sudoers/pwutil.c:938
+#: plugins/sudoers/sssd.c:162 plugins/sudoers/sssd.c:194
+#: plugins/sudoers/sssd.c:237 plugins/sudoers/sssd.c:244
+#: plugins/sudoers/sssd.c:280 plugins/sudoers/sssd.c:353
+#: plugins/sudoers/sssd.c:392 plugins/sudoers/sssd.c:1067
+#: plugins/sudoers/sssd.c:1246 plugins/sudoers/sssd.c:1260
+#: plugins/sudoers/sssd.c:1276 plugins/sudoers/sudoers.c:263
+#: plugins/sudoers/sudoers.c:273 plugins/sudoers/sudoers.c:281
+#: plugins/sudoers/sudoers.c:365 plugins/sudoers/sudoers.c:682
+#: plugins/sudoers/sudoers.c:807 plugins/sudoers/sudoers.c:851
+#: plugins/sudoers/sudoers.c:1123 plugins/sudoers/sudoers_debug.c:107
+#: plugins/sudoers/sudoreplay.c:1253 plugins/sudoers/sudoreplay.c:1365
+#: plugins/sudoers/sudoreplay.c:1405 plugins/sudoers/sudoreplay.c:1414
+#: plugins/sudoers/sudoreplay.c:1424 plugins/sudoers/sudoreplay.c:1432
+#: plugins/sudoers/sudoreplay.c:1436 plugins/sudoers/sudoreplay.c:1592
+#: plugins/sudoers/sudoreplay.c:1596 plugins/sudoers/testsudoers.c:131
+#: plugins/sudoers/testsudoers.c:217 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/timestamp.c:389 plugins/sudoers/timestamp.c:433
+#: plugins/sudoers/timestamp.c:852 plugins/sudoers/toke_util.c:56
+#: plugins/sudoers/toke_util.c:109 plugins/sudoers/toke_util.c:146
+#: plugins/sudoers/visudo.c:153 plugins/sudoers/visudo.c:309
+#: plugins/sudoers/visudo.c:315 plugins/sudoers/visudo.c:446
+#: plugins/sudoers/visudo.c:624 plugins/sudoers/visudo.c:985
+#: plugins/sudoers/visudo.c:1051 plugins/sudoers/visudo.c:1095
+#: plugins/sudoers/visudo.c:1197 plugins/sudoers/visudo_json.c:1025 toke.l:849
+#: toke.l:949 toke.l:1106
+msgid "unable to allocate memory"
+msgstr "kan geen geheugen reserveren"
+
+#: gram.y:481
+msgid "a digest requires a path name"
+msgstr "een digest vereist een padnaam"
+
+#: gram.y:607
+msgid "invalid notbefore value"
+msgstr "ongeldige 'notbefore'-waarde"
+
+#: gram.y:615
+msgid "invalid notafter value"
+msgstr "ongeldige 'notafter'-waarde"
+
+#: gram.y:624 plugins/sudoers/policy.c:267
+msgid "timeout value too large"
+msgstr ""
+
+#: gram.y:626 plugins/sudoers/policy.c:269
+msgid "invalid timeout value"
+msgstr ""
+
+#: gram.y:1195 gram.y:1202 plugins/sudoers/auth/pam.c:320
+#: plugins/sudoers/auth/pam.c:490 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/defaults.c:650 plugins/sudoers/defaults.c:905
+#: plugins/sudoers/defaults.c:1076 plugins/sudoers/editor.c:64
+#: plugins/sudoers/editor.c:82 plugins/sudoers/editor.c:93
+#: plugins/sudoers/env.c:233 plugins/sudoers/filedigest.c:120
+#: plugins/sudoers/filedigest_gcrypt.c:72
+#: plugins/sudoers/filedigest_gcrypt.c:90
+#: plugins/sudoers/filedigest_openssl.c:111 plugins/sudoers/gc.c:52
+#: plugins/sudoers/group_plugin.c:134 plugins/sudoers/interfaces.c:71
+#: plugins/sudoers/iolog.c:941 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:449 plugins/sudoers/ldap.c:480
+#: plugins/sudoers/ldap.c:532 plugins/sudoers/ldap.c:566
+#: plugins/sudoers/ldap.c:974 plugins/sudoers/ldap.c:1168
+#: plugins/sudoers/ldap.c:1179 plugins/sudoers/ldap.c:1195
+#: plugins/sudoers/ldap.c:1487 plugins/sudoers/ldap.c:1647
+#: plugins/sudoers/ldap.c:1729 plugins/sudoers/ldap.c:1877
+#: plugins/sudoers/ldap.c:1901 plugins/sudoers/ldap.c:1990
+#: plugins/sudoers/ldap.c:2005 plugins/sudoers/ldap.c:2101
+#: plugins/sudoers/ldap.c:2134 plugins/sudoers/ldap.c:2214
+#: plugins/sudoers/ldap.c:2297 plugins/sudoers/ldap.c:2394
+#: plugins/sudoers/ldap.c:3228 plugins/sudoers/ldap.c:3260
+#: plugins/sudoers/ldap.c:3572 plugins/sudoers/ldap.c:3599
+#: plugins/sudoers/ldap.c:3615 plugins/sudoers/ldap.c:3706
+#: plugins/sudoers/ldap.c:3722 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:189 plugins/sudoers/logging.c:451
+#: plugins/sudoers/logging.c:472 plugins/sudoers/logging.c:942
+#: plugins/sudoers/match.c:616 plugins/sudoers/match.c:663
+#: plugins/sudoers/match.c:714 plugins/sudoers/match.c:738
+#: plugins/sudoers/match.c:826 plugins/sudoers/match.c:914
+#: plugins/sudoers/parse.c:252 plugins/sudoers/parse.c:264
+#: plugins/sudoers/parse.c:279 plugins/sudoers/parse.c:291
+#: plugins/sudoers/policy.c:100 plugins/sudoers/policy.c:109
+#: plugins/sudoers/policy.c:118 plugins/sudoers/policy.c:142
+#: plugins/sudoers/policy.c:253 plugins/sudoers/policy.c:267
+#: plugins/sudoers/policy.c:269 plugins/sudoers/policy.c:293
+#: plugins/sudoers/policy.c:303 plugins/sudoers/policy.c:343
+#: plugins/sudoers/policy.c:353 plugins/sudoers/policy.c:362
+#: plugins/sudoers/policy.c:371 plugins/sudoers/policy.c:441
+#: plugins/sudoers/policy.c:678 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/pwutil.c:165 plugins/sudoers/pwutil.c:236
+#: plugins/sudoers/pwutil.c:312 plugins/sudoers/pwutil.c:486
+#: plugins/sudoers/pwutil.c:551 plugins/sudoers/pwutil.c:620
+#: plugins/sudoers/pwutil.c:778 plugins/sudoers/pwutil.c:835
+#: plugins/sudoers/pwutil.c:880 plugins/sudoers/pwutil.c:938
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1476
+#: plugins/sudoers/set_perms.c:1641 plugins/sudoers/sssd.c:162
+#: plugins/sudoers/sssd.c:194 plugins/sudoers/sssd.c:237
+#: plugins/sudoers/sssd.c:244 plugins/sudoers/sssd.c:280
+#: plugins/sudoers/sssd.c:352 plugins/sudoers/sssd.c:392
+#: plugins/sudoers/sssd.c:1067 plugins/sudoers/sssd.c:1245
+#: plugins/sudoers/sssd.c:1260 plugins/sudoers/sssd.c:1276
+#: plugins/sudoers/sudoers.c:263 plugins/sudoers/sudoers.c:273
+#: plugins/sudoers/sudoers.c:281 plugins/sudoers/sudoers.c:365
+#: plugins/sudoers/sudoers.c:682 plugins/sudoers/sudoers.c:807
+#: plugins/sudoers/sudoers.c:851 plugins/sudoers/sudoers.c:1123
+#: plugins/sudoers/sudoers_debug.c:106 plugins/sudoers/sudoreplay.c:1253
+#: plugins/sudoers/sudoreplay.c:1365 plugins/sudoers/sudoreplay.c:1405
+#: plugins/sudoers/sudoreplay.c:1414 plugins/sudoers/sudoreplay.c:1424
+#: plugins/sudoers/sudoreplay.c:1432 plugins/sudoers/sudoreplay.c:1436
+#: plugins/sudoers/sudoreplay.c:1592 plugins/sudoers/sudoreplay.c:1596
+#: plugins/sudoers/testsudoers.c:131 plugins/sudoers/testsudoers.c:217
+#: plugins/sudoers/testsudoers.c:234 plugins/sudoers/timestamp.c:389
+#: plugins/sudoers/timestamp.c:433 plugins/sudoers/timestamp.c:852
+#: plugins/sudoers/toke_util.c:56 plugins/sudoers/toke_util.c:109
+#: plugins/sudoers/toke_util.c:146 plugins/sudoers/visudo.c:153
+#: plugins/sudoers/visudo.c:309 plugins/sudoers/visudo.c:315
+#: plugins/sudoers/visudo.c:446 plugins/sudoers/visudo.c:624
+#: plugins/sudoers/visudo.c:985 plugins/sudoers/visudo.c:1051
+#: plugins/sudoers/visudo.c:1095 plugins/sudoers/visudo.c:1197
+#: plugins/sudoers/visudo_json.c:1025 toke.l:849 toke.l:949 toke.l:1106
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:135
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Alias \"%s\" is al gedefinieerd"
+
+#: plugins/sudoers/auth/bsdauth.c:68
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "kan de loginklasse voor gebruiker %s niet verkrijgen"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+msgid "unable to begin bsd authentication"
+msgstr "kan de bsd-aanmelding niet starten"
+
+#: plugins/sudoers/auth/bsdauth.c:81
+msgid "invalid authentication type"
+msgstr "ongeldig type verificatie"
+
+#: plugins/sudoers/auth/bsdauth.c:90
+msgid "unable to initialize BSD authentication"
+msgstr "kan de bsd-aanmelding niet initialiseren"
+
+#: plugins/sudoers/auth/fwtk.c:52
+msgid "unable to read fwtk config"
+msgstr "kan fwtk-configuratie niet lezen"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to connect to authentication server"
+msgstr "kan niet verbinden met aanmeldingsserver"
+
+#: plugins/sudoers/auth/fwtk.c:63 plugins/sudoers/auth/fwtk.c:87
+#: plugins/sudoers/auth/fwtk.c:121
+msgid "lost connection to authentication server"
+msgstr "verbinding met aanmeldingsserver verloren"
+
+#: plugins/sudoers/auth/fwtk.c:67
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"aanmeldingsserverfout:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:111
+#, fuzzy, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: kan opdrachtgever niet converteren naar een string ('%s'): %s"
+
+#: plugins/sudoers/auth/kerb5.c:161
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: kan '%s' niet ontleden: %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: kan cache voor aanmeldingsgegevens niet vinden: %s"
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: kan opties niet reserveren: %s"
+
+#: plugins/sudoers/auth/kerb5.c:232
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: kan aanmeldingsgegevens niet verkrijgen: %s"
+
+#: plugins/sudoers/auth/kerb5.c:245
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: kan cache voor aanmeldingsgegevens niet initialiseren: %s"
+
+#: plugins/sudoers/auth/kerb5.c:248
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: kan aanmeldingsgegeven niet opslaan in cache: %s"
+
+#: plugins/sudoers/auth/kerb5.c:312
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: kan belangrijkste server niet vinden: %s"
+
+#: plugins/sudoers/auth/kerb5.c:326
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Kan TGT niet verifieren! U bent mogelijk aangevallen!: %s"
+
+#: plugins/sudoers/auth/pam.c:108
+msgid "unable to initialize PAM"
+msgstr "kan PAM niet initialiseren"
+
+#: plugins/sudoers/auth/pam.c:194
+msgid "account validation failure, is your account locked?"
+msgstr "fout bij valideren van account, is uw account geblokkeerd?"
+
+#: plugins/sudoers/auth/pam.c:198
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Account of wachtwoord is verlopen, stel uw wachtwoord opnieuw in en probeer het opnieuw"
+
+#: plugins/sudoers/auth/pam.c:206
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "kan verlopen wachtwoord niet wijzigen: %s"
+
+#: plugins/sudoers/auth/pam.c:211
+msgid "Password expired, contact your system administrator"
+msgstr "Wachtwoord is verlopen, neem contact op met uw systeembeheerder"
+
+#: plugins/sudoers/auth/pam.c:215
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Account is verlopen of PAM-configuratie heeft geen \"account\"-gedeelte voor sudo, neem contact op met uw systeembeheerder"
+
+#: plugins/sudoers/auth/pam.c:229
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "fout in PAM-aanmelding: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:97 plugins/sudoers/visudo.c:227
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "u bestaat niet in de %s-database"
+
+#: plugins/sudoers/auth/securid5.c:73
+msgid "failed to initialise the ACE API library"
+msgstr "initialiseren van de ACE API-bibliotheek is mislukt"
+
+#: plugins/sudoers/auth/securid5.c:99
+msgid "unable to contact the SecurID server"
+msgstr "kan geen contact krijgen met de SecurID-server"
+
+#: plugins/sudoers/auth/securid5.c:108
+msgid "User ID locked for SecurID Authentication"
+msgstr "Gebruikers-ID is geblokkeerd voor SecurID-verificatie"
+
+#: plugins/sudoers/auth/securid5.c:112 plugins/sudoers/auth/securid5.c:163
+msgid "invalid username length for SecurID"
+msgstr "ongeldige gebruikersnaamlengte voor SecurID"
+
+#: plugins/sudoers/auth/securid5.c:116 plugins/sudoers/auth/securid5.c:168
+msgid "invalid Authentication Handle for SecurID"
+msgstr "kan verificatie voor SecurID op deze manier niet afhandelen"
+
+#: plugins/sudoers/auth/securid5.c:120
+msgid "SecurID communication failed"
+msgstr "SecurID-communicatie is mislukt"
+
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:213
+msgid "unknown SecurID error"
+msgstr "onbekende SecurID-fout"
+
+#: plugins/sudoers/auth/securid5.c:158
+msgid "invalid passcode length for SecurID"
+msgstr "ongeldige lengte van passcode voor SecurID"
+
+#: plugins/sudoers/auth/sia.c:69 plugins/sudoers/auth/sia.c:125
+msgid "unable to initialize SIA session"
+msgstr "kan SIA-sessie niet initialiseren"
+
+#: plugins/sudoers/auth/sudo_auth.c:126
+msgid "invalid authentication methods"
+msgstr "ongeldige verificatiemethoden"
+
+#: plugins/sudoers/auth/sudo_auth.c:128
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Er zijn ongeldige verificatiemethoden in sudo gecompileerd! U kunt geen zelfstandige en niet-zelfstandige verificatiemethoden door elkaar gebruiken."
+
+#: plugins/sudoers/auth/sudo_auth.c:224 plugins/sudoers/auth/sudo_auth.c:274
+msgid "no authentication methods"
+msgstr "geen verificatiemethoden"
+
+#: plugins/sudoers/auth/sudo_auth.c:226
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Er zijn geen verificatie-methoden in sudo gecompileerd! Als u verificatie wilt uitschakelen, dient u de --disable-authentication configuratie-optie te gebruiken."
+
+#: plugins/sudoers/auth/sudo_auth.c:276
+msgid "Unable to initialize authentication methods."
+msgstr "Kon verificatiemethoden niet starten."
+
+#: plugins/sudoers/auth/sudo_auth.c:441
+msgid "Authentication methods:"
+msgstr "Verificatie-methoden:"
+
+#: plugins/sudoers/bsm_audit.c:120 plugins/sudoers/bsm_audit.c:211
+msgid "Could not determine audit condition"
+msgstr "Kan voorwaarden voor controle niet bepalen"
+
+#: plugins/sudoers/bsm_audit.c:183 plugins/sudoers/bsm_audit.c:273
+msgid "unable to commit audit record"
+msgstr "kan controlestructuur niet opbouwen"
+
+#: plugins/sudoers/check.c:259
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Als het goed is hebt u de gebruikelijke informatie ontvangen van uw\n"
+"systeembeheerder. Gewoonlijk komt het neer op de volgende drie punten:\n"
+"\n"
+" 1. Respecteer de privacy van anderen.\n"
+" 2. Denk na voordat u iets doet.\n"
+" 3. Veel mogelijkheden betekent veel verantwoordelijkheid.\n"
+"\n"
+
+#: plugins/sudoers/check.c:302 plugins/sudoers/check.c:312
+#: plugins/sudoers/sudoers.c:725 plugins/sudoers/sudoers.c:770
+#, c-format
+msgid "unknown uid: %u"
+msgstr "onbekend gebruikersnummer: %u"
+
+#: plugins/sudoers/check.c:307 plugins/sudoers/iolog.c:260
+#: plugins/sudoers/policy.c:851 plugins/sudoers/sudoers.c:1162
+#: plugins/sudoers/testsudoers.c:208 plugins/sudoers/testsudoers.c:366
+#, c-format
+msgid "unknown user: %s"
+msgstr "onbekende gebruiker: %s"
+
+#: plugins/sudoers/def_data.c:41
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Syslog-voorziening als syslog wordt gebruikt voor loggen: %s"
+
+#: plugins/sudoers/def_data.c:45
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Syslog-prioriteit wanneer aanmelden van gebruiker gelukt is: %s"
+
+#: plugins/sudoers/def_data.c:49
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Syslog-prioriteit wanneer aanmelden van gebruiker niet gelukt is: %s"
+
+#: plugins/sudoers/def_data.c:53
+msgid "Put OTP prompt on its own line"
+msgstr "Geef OTP-prompt een eigen regel"
+
+#: plugins/sudoers/def_data.c:57
+msgid "Ignore '.' in $PATH"
+msgstr "Negeer '.' in $PATH"
+
+#: plugins/sudoers/def_data.c:61
+msgid "Always send mail when sudo is run"
+msgstr "Stuur altijd een mail wanneer sudo is gebruikt"
+
+#: plugins/sudoers/def_data.c:65
+msgid "Send mail if user authentication fails"
+msgstr "Stuur een mail wanneer aanmelden van gebruiker mislukt"
+
+#: plugins/sudoers/def_data.c:69
+msgid "Send mail if the user is not in sudoers"
+msgstr "Stuur een mail als de gebruiker niet in sudoers staat"
+
+#: plugins/sudoers/def_data.c:73
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Stuur een mail als de gebruiker niet voor deze computer in sudoers staat"
+
+#: plugins/sudoers/def_data.c:77
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Stuur een mail als de gebruiker een opdracht niet mag gebruiken"
+
+#: plugins/sudoers/def_data.c:81
+msgid "Send mail if the user tries to run a command"
+msgstr "Stuur een mail als de gebruiker een opdracht probeert te gebruiken"
+
+#: plugins/sudoers/def_data.c:85
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Gebruik een verschillende tijd voor elke gebruiker/terminal-combinatie"
+
+#: plugins/sudoers/def_data.c:89
+msgid "Lecture user the first time they run sudo"
+msgstr "Instrueer gebruikers de eerste keer dat ze sudo gebruiken"
+
+#: plugins/sudoers/def_data.c:93
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Bestand met de sudo-instructies: %s"
+
+#: plugins/sudoers/def_data.c:97
+msgid "Require users to authenticate by default"
+msgstr "Standaard is verificatie van gebruikers vereist"
+
+#: plugins/sudoers/def_data.c:101
+msgid "Root may run sudo"
+msgstr "Root mag sudo gebruiken"
+
+#: plugins/sudoers/def_data.c:105
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Log de computernaam in het (niet-syslog) logbestand"
+
+#: plugins/sudoers/def_data.c:109
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Log het jaar in het (niet-syslog) logbestand"
+
+#: plugins/sudoers/def_data.c:113
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Start een shell als sudo wordt aangeroepen zonder argumenten"
+
+#: plugins/sudoers/def_data.c:117
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Stel $HOME in op de doelgebruiker wanneer een shell wordt gestart met -s"
+
+#: plugins/sudoers/def_data.c:121
+msgid "Always set $HOME to the target user's home directory"
+msgstr "$HOME altijd instellen op de persoonlijke map van de doelgebruiker"
+
+#: plugins/sudoers/def_data.c:125
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Sta verzamelen van informatie toe om bruikbare foutberichten te geven"
+
+#: plugins/sudoers/def_data.c:129
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Vereis volledig-gekwalificeerde computernamen (fqdn) in het sudoers-bestand"
+
+#: plugins/sudoers/def_data.c:133
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Beledig de gebruiker wanneer ze een verkeerd wachtwoord invoeren"
+
+#: plugins/sudoers/def_data.c:137
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Gebruiker alleen toestaan sudo te gebruiken wanneer deze een terminal heeft"
+
+#: plugins/sudoers/def_data.c:141
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo zal de EDITOR omgevingsvariabele in acht nemen"
+
+#: plugins/sudoers/def_data.c:145
+msgid "Prompt for root's password, not the users's"
+msgstr "Vraag naar wachtwoord van root, niet van de gebruiker"
+
+#: plugins/sudoers/def_data.c:149
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Vraag naar wachtwoord van runas_default gebruiker, niet van huidige gebruiker"
+
+#: plugins/sudoers/def_data.c:153
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Vraag naar wachtwoord van doelgebruiker, niet van huidige gebruiker"
+
+#: plugins/sudoers/def_data.c:157
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Pas de standaardinstellingen van de doelgebruikers inlogklasse toe wanneer deze bestaat"
+
+#: plugins/sudoers/def_data.c:161
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Stel de LOGNAME en USER omgevingsvariabelen in"
+
+#: plugins/sudoers/def_data.c:165
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Stel het effectieve gebruikersnummer van de doelgebuiker in, niet het werkelijke gebruikersnummer"
+
+#: plugins/sudoers/def_data.c:169
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "De groepsvector niet initialiseren naar die van de doelgebruiker"
+
+#: plugins/sudoers/def_data.c:173
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Breek regels in logbestanden af op (0 voor niet afbreken): %u"
+
+#: plugins/sudoers/def_data.c:177
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Aanmeldtijd timeout: %.1f minuten"
+
+#: plugins/sudoers/def_data.c:181
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Wachtwoordprompt timeout: %.1f minuten"
+
+#: plugins/sudoers/def_data.c:185
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Aantal pogingen om een wachtwoord in te voeren: %u"
+
+#: plugins/sudoers/def_data.c:189
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Te gebruiken umask of 0777 om die van gebruiker te gebruiken: 0%o"
+
+#: plugins/sudoers/def_data.c:193
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Pad naar logbestand: %s"
+
+#: plugins/sudoers/def_data.c:197
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Pad naar mailprogramma: %s"
+
+#: plugins/sudoers/def_data.c:201
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Opties voor mailprogramma: %s"
+
+#: plugins/sudoers/def_data.c:205
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Adres waarnaar mail wordt verzonden: %s"
+
+#: plugins/sudoers/def_data.c:209
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Afzenderadres: %s"
+
+#: plugins/sudoers/def_data.c:213
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Onderwerp voor mails: %s"
+
+#: plugins/sudoers/def_data.c:217
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Boodschap voor verkeerd wachtwoord: %s"
+
+#: plugins/sudoers/def_data.c:221
+#, fuzzy, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Pad naar aanmeld-tijdmap: %s"
+
+#: plugins/sudoers/def_data.c:225
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Pad naar aanmeld-tijdmap: %s"
+
+#: plugins/sudoers/def_data.c:229
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Eigenaar van aanmeld-tijdmap: %s"
+
+#: plugins/sudoers/def_data.c:233
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Gebruikers in deze groep zijn uitgezonderd van de wachtwoord- en PATH-vereisten: %s"
+
+#: plugins/sudoers/def_data.c:237
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Standaard wachtwoordprompt: %s"
+
+#: plugins/sudoers/def_data.c:241
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Indien ingesteld, zal de wachtwoordprompt altijd de systeemprompt vervangen."
+
+#: plugins/sudoers/def_data.c:245
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Standaardgebruiker om opdrachten uit te voeren: %s"
+
+#: plugins/sudoers/def_data.c:249
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Waarde waarmee $PATH van gebruiker wordt vervangen: %s"
+
+#: plugins/sudoers/def_data.c:253
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Pad naar de editor bij gebruik van visudo: %s"
+
+#: plugins/sudoers/def_data.c:257
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Wanneer een wachtwoord noodzakelijk is voor 'list'-pseudopdracht: %s"
+
+#: plugins/sudoers/def_data.c:261
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Wanneer een wachtwoord noodzakelijk is voor 'verify'-pseudopdracht: %s"
+
+#: plugins/sudoers/def_data.c:265
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Laadt vooraf de dummy uitvoerfuncties uit de sudo_noexec-bibliotheek"
+
+#: plugins/sudoers/def_data.c:269
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Als de LDAP-map beschikbaar is, wordt het lokale sudoersbestand genegeerd?"
+
+#: plugins/sudoers/def_data.c:273
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Bestandsdescriptors >= %d zullen worden gesloten vóór het uitvoeren van een opdracht"
+
+#: plugins/sudoers/def_data.c:277
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Indien ingesteld, mogen gebruikers de waarde van 'closefrom' vervangen met de optie -C"
+
+#: plugins/sudoers/def_data.c:281
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Gebruikers toestaan willekeurige omgevingsvariabelen in te stellen"
+
+#: plugins/sudoers/def_data.c:285
+msgid "Reset the environment to a default set of variables"
+msgstr "Stel de omgevingsvariablen in op een standaard set"
+
+#: plugins/sudoers/def_data.c:289
+msgid "Environment variables to check for sanity:"
+msgstr "Op \"gezondheid\" te controleren omgevingsvariabelen:"
+
+#: plugins/sudoers/def_data.c:293
+msgid "Environment variables to remove:"
+msgstr "Te verwijderen omgevingsvariabelen:"
+
+#: plugins/sudoers/def_data.c:297
+msgid "Environment variables to preserve:"
+msgstr "Te behouden omgevingsvariabelen:"
+
+#: plugins/sudoers/def_data.c:301
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "SELinux role om in de nieuwe beveiligingscontext te gebruiken: %s"
+
+#: plugins/sudoers/def_data.c:305
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "SELinux type om in de nieuwe beveiligingscontext te gebruiken: %s"
+
+#: plugins/sudoers/def_data.c:309
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Pad naar het omgevingsbestand voor sudo: %s"
+
+#: plugins/sudoers/def_data.c:313
+#, fuzzy, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Pad naar het omgevingsbestand voor sudo: %s"
+
+#: plugins/sudoers/def_data.c:317
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Te gebruiken taalregio bij ontleden van sudoers: %s"
+
+#: plugins/sudoers/def_data.c:321
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Sta sudo toe ook te vragen naar een wachtwoord wanneer dit zichtbaar zou worden"
+
+#: plugins/sudoers/def_data.c:325
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Zorg voor zichtbare terugkoppeling op de wachtwoordprompt wanneer er gebruikersinvoer is"
+
+#: plugins/sudoers/def_data.c:329
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Gebruik snellere expansie van jokertekens. Dit is minder nauwkeurig, maar maakt geen gebruik van het bestandsysteem"
+
+#: plugins/sudoers/def_data.c:333
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "De umask die is opgegeven in het sudoersbestand zal die van de gebruiker vervangen, ook wanneer deze meer toestaat"
+
+#: plugins/sudoers/def_data.c:337
+msgid "Log user's input for the command being run"
+msgstr "Log gebruikersinvoer voor de uitgevoerde opdracht"
+
+#: plugins/sudoers/def_data.c:341
+msgid "Log the output of the command being run"
+msgstr "Log uitvoer voor de uitgevoerde opdracht"
+
+#: plugins/sudoers/def_data.c:345
+msgid "Compress I/O logs using zlib"
+msgstr "Comprimeer in-/uitvoerlogs met zlib"
+
+#: plugins/sudoers/def_data.c:349
+msgid "Always run commands in a pseudo-tty"
+msgstr "Voer opdrachten altijd uit in een pseudo-terminal"
+
+#: plugins/sudoers/def_data.c:353
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Plugin voor ondersteuning van niet-Unixgroepen: %s"
+
+#: plugins/sudoers/def_data.c:357
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Map waarin in-/uitvoerlogs moeten worden opgeslagen: %s"
+
+#: plugins/sudoers/def_data.c:361
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Bestand waarin in-/uitvoerlogs moeten worden opgeslagen: %s"
+
+#: plugins/sudoers/def_data.c:365
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Voeg een item toe aan het utmp/utmpx-bestand wanneer een virtuele terminal wordt gereserveerd"
+
+#: plugins/sudoers/def_data.c:369
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Stel in utmp de gebruiker in op de runas-gebruiker, niet op de aanroepende gebruiker"
+
+#: plugins/sudoers/def_data.c:373
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Set van toegestane privileges: %s"
+
+#: plugins/sudoers/def_data.c:377
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Set van beperkende privileges: %s"
+
+#: plugins/sudoers/def_data.c:381
+msgid "Run commands on a pty in the background"
+msgstr "Draai opdrachten op een virtuele terminal op de achtergrond."
+
+#: plugins/sudoers/def_data.c:385
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "te gebruiken naam van PAM-service: %s"
+
+#: plugins/sudoers/def_data.c:389
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "te gebruiken naam van PAM-service voor inlog-shells: %s"
+
+#: plugins/sudoers/def_data.c:393
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Probeer PAM-aanmeldgegevens voor doelgebruiker te verkrijgen"
+
+#: plugins/sudoers/def_data.c:397
+msgid "Create a new PAM session for the command to run in"
+msgstr "Maak een nieuwe PAM-sessie om de opdracht in uit te voeren"
+
+#: plugins/sudoers/def_data.c:401
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Maximaal in-/uitvoerlog volgnummer: %u"
+
+#: plugins/sudoers/def_data.c:405
+msgid "Enable sudoers netgroup support"
+msgstr "Ondersteuning voor sudoers-netgroup inschakelen"
+
+#: plugins/sudoers/def_data.c:409
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:413
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:417
+msgid "Query the group plugin for unknown system groups"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:421
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:425
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:429
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:433
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:437
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:441
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:445
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:449
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:453
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:457
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:461
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:465
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:469
+msgid "Allow the user to specify a timeout on the command line"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:473
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:477
+msgid "Include the process ID when logging via syslog"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:481
+#, fuzzy, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Eigenaar van aanmeld-tijdmap: %s"
+
+#: plugins/sudoers/defaults.c:220
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d onbekend standaarditem \"%s\""
+
+#: plugins/sudoers/defaults.c:223
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: onbekend standaarditem \"%s\""
+
+#: plugins/sudoers/defaults.c:266
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d geen waarde opgegeven voor \"%s\""
+
+#: plugins/sudoers/defaults.c:269
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: geen waarde opgegeven voor \"%s\""
+
+#: plugins/sudoers/defaults.c:289
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d waarden voor \"%s\" moeten beginnen met een '/'"
+
+#: plugins/sudoers/defaults.c:292
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: waarden voor \"%s\" moeten beginnen met een '/'"
+
+#: plugins/sudoers/defaults.c:317
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d optie '%s' accepteert geen waarde"
+
+#: plugins/sudoers/defaults.c:320
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: optie '%s' accepteert geen waarde"
+
+#: plugins/sudoers/defaults.c:342
+#, fuzzy, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "ongeldige filteroptie: %s"
+
+#: plugins/sudoers/defaults.c:345
+#, fuzzy, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "ongeldige filteroptie: %s"
+
+#: plugins/sudoers/defaults.c:355
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d waarde \"%s\" is ongeldig voor optie '%s'"
+
+#: plugins/sudoers/defaults.c:358
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: waarde \"%s\" is ongeldig voor optie '%s'"
+
+#: plugins/sudoers/env.c:295 plugins/sudoers/env.c:302
+#: plugins/sudoers/env.c:407 plugins/sudoers/ldap.c:453
+#: plugins/sudoers/ldap.c:543 plugins/sudoers/ldap.c:1264
+#: plugins/sudoers/ldap.c:1491 plugins/sudoers/ldap.c:1816
+#: plugins/sudoers/linux_audit.c:82 plugins/sudoers/logging.c:947
+#: plugins/sudoers/policy.c:562 plugins/sudoers/policy.c:572
+#: plugins/sudoers/prompt.c:161 plugins/sudoers/sudoers.c:873
+#: plugins/sudoers/testsudoers.c:238 plugins/sudoers/toke_util.c:158
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "interne fout, %s overflow"
+
+#: plugins/sudoers/env.c:376
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: envp bevat fouten, verkeerde lengte"
+
+#: plugins/sudoers/env.c:1055
+msgid "unable to rebuild the environment"
+msgstr "kan omgeving niet opnieuw opbouwen"
+
+#: plugins/sudoers/env.c:1129
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "sorry, u mag de volgende omgevingsvariabelen niet instellen: %s"
+
+#: plugins/sudoers/filedigest.c:104 plugins/sudoers/filedigest_gcrypt.c:66
+#: plugins/sudoers/filedigest_openssl.c:95
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "niet-ondersteund type controlegetal %d voor %s"
+
+#: plugins/sudoers/filedigest.c:129 plugins/sudoers/filedigest_gcrypt.c:98
+#: plugins/sudoers/filedigest_openssl.c:120
+#, c-format
+msgid "%s: read error"
+msgstr "%s: leesfout"
+
+#: plugins/sudoers/group_plugin.c:86
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s moet eigendom zijn van gebruikersnummer %d"
+
+#: plugins/sudoers/group_plugin.c:90
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s mag enkel schrijfbaar zijn voor eigenaar"
+
+#: plugins/sudoers/group_plugin.c:98 plugins/sudoers/sssd.c:400
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "kan %s niet laden: %s"
+
+#: plugins/sudoers/group_plugin.c:104
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "kan symbool \"group_plugin\" niet vinden in %s"
+
+#: plugins/sudoers/group_plugin.c:109
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: incompatibele groepplugin hoofdversie %d, verwacht wordt %d"
+
+#: plugins/sudoers/interfaces.c:79 plugins/sudoers/interfaces.c:96
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "kan IP-adres \"%s\" niet ontleden"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "kan netmasker \"%s\" niet ontleden"
+
+#: plugins/sudoers/interfaces.c:129
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Combinaties van lokale IP-adressen en netwerkmaskers:\n"
+
+#: plugins/sudoers/iolog.c:121 plugins/sudoers/mkdir_parents.c:75
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s bestaat al, maar is geen map (0%o)"
+
+#: plugins/sudoers/iolog.c:146 plugins/sudoers/iolog.c:187
+#: plugins/sudoers/mkdir_parents.c:64 plugins/sudoers/timestamp.c:170
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "mkdir %s: aanmaken mislukt"
+
+#: plugins/sudoers/iolog.c:191 plugins/sudoers/visudo.c:740
+#: plugins/sudoers/visudo.c:750
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "kan modus van %s niet wijzigen naar 0%o"
+
+#: plugins/sudoers/iolog.c:299 plugins/sudoers/sudoers.c:1193
+#: plugins/sudoers/testsudoers.c:390
+#, c-format
+msgid "unknown group: %s"
+msgstr "onbekende groep: %s"
+
+#: plugins/sudoers/iolog.c:418 plugins/sudoers/sudoers.c:929
+#: plugins/sudoers/sudoreplay.c:349 plugins/sudoers/sudoreplay.c:1354
+#: plugins/sudoers/sudoreplay.c:1558 plugins/sudoers/timestamp.c:398
+#: plugins/sudoers/visudo.c:972 plugins/sudoers/visudo_json.c:1001
+#: plugins/sudoers/visudo_json.c:1014
+#, c-format
+msgid "unable to open %s"
+msgstr "kan %s niet openen"
+
+#: plugins/sudoers/iolog.c:469 plugins/sudoers/sudoers.c:933
+#: plugins/sudoers/sudoreplay.c:856 plugins/sudoers/sudoreplay.c:1669
+#, c-format
+msgid "unable to read %s"
+msgstr "kan %s niet lezen"
+
+#: plugins/sudoers/iolog.c:505 plugins/sudoers/sudoreplay.c:1123
+#: plugins/sudoers/timestamp.c:290 plugins/sudoers/timestamp.c:293
+#, c-format
+msgid "unable to write to %s"
+msgstr "kan %s niet schrijven"
+
+#: plugins/sudoers/iolog.c:584 plugins/sudoers/iolog.c:803
+#, c-format
+msgid "unable to create %s"
+msgstr "kan %s niet aanmaken"
+
+#: plugins/sudoers/iolog.c:1035 plugins/sudoers/iolog.c:1110
+#: plugins/sudoers/iolog.c:1191
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "kan niet schrijven naar in-/uitvoerlogbestand: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, fuzzy, c-format
+msgid "%s: internal error, file index %d not open"
+msgstr "interne fout, kan %s niet in de lijst vinden!"
+
+#: plugins/sudoers/ldap.c:431
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: poort te groot"
+
+#: plugins/sudoers/ldap.c:491
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "niet-ondersteund LDAP uri type: %s"
+
+#: plugins/sudoers/ldap.c:518
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "kan ldap en ldaps URIs niet door elkaar gebruiken"
+
+#: plugins/sudoers/ldap.c:522 plugins/sudoers/ldap.c:559
+msgid "starttls not supported when using ldaps"
+msgstr "starttls wordt niet ondersteund in combinatie met ldaps"
+
+#: plugins/sudoers/ldap.c:630
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "kan SSL cert en key db niet initialiseren: %s"
+
+#: plugins/sudoers/ldap.c:633
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "u moet TLS_CERT in %s instellen om SSL te gebruiken"
+
+#: plugins/sudoers/ldap.c:1250
+msgid "unable to get GMT time"
+msgstr "kan GMT-tijd niet verkrijgen"
+
+#: plugins/sudoers/ldap.c:1256
+msgid "unable to format timestamp"
+msgstr "kan tijd niet juist opmaken"
+
+#: plugins/sudoers/ldap.c:1980
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/ldap.c:2552
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"LDAP Role: %s\n"
+
+#: plugins/sudoers/ldap.c:2554
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+
+#: plugins/sudoers/ldap.c:2610
+#, c-format
+msgid " Order: %s\n"
+msgstr " Volgorde: %s\n"
+
+#: plugins/sudoers/ldap.c:2618 plugins/sudoers/parse.c:618
+#: plugins/sudoers/sssd.c:1641
+#, c-format
+msgid " Commands:\n"
+msgstr " Opdrachten:\n"
+
+#: plugins/sudoers/ldap.c:3180
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "kan LDAP niet initialiseren: %s"
+
+#: plugins/sudoers/ldap.c:3216
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls opgegeven maar LDAP bibliotheken ondersteunen geen ldap_start_tls_s() of ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:3468
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "ongeldig sudoOrder kenmerk: %s"
+
+#: plugins/sudoers/linux_audit.c:52
+msgid "unable to open audit system"
+msgstr "kan controlesysteem niet openen"
+
+#: plugins/sudoers/linux_audit.c:93
+msgid "unable to send audit message"
+msgstr "kan controleboodschap niet verzenden"
+
+#: plugins/sudoers/logging.c:107
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:135
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (opdracht voortgezet) %s"
+
+#: plugins/sudoers/logging.c:164
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "kan logbestand niet openen: %s"
+
+#: plugins/sudoers/logging.c:172
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "kan logbestand niet vergrendelen: %s"
+
+#: plugins/sudoers/logging.c:205
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "kan logbestand niet schrijven: %s"
+
+#: plugins/sudoers/logging.c:234
+msgid "No user or host"
+msgstr "Geen gebruiker of computer"
+
+#: plugins/sudoers/logging.c:236
+msgid "validation failure"
+msgstr "geldigheidsfout"
+
+#: plugins/sudoers/logging.c:243
+msgid "user NOT in sudoers"
+msgstr "gebruiker NIET in sudoers"
+
+#: plugins/sudoers/logging.c:245
+msgid "user NOT authorized on host"
+msgstr "gebruiker NIET aangemeld op computer"
+
+#: plugins/sudoers/logging.c:247
+msgid "command not allowed"
+msgstr "opdracht is niet toegestaan"
+
+#: plugins/sudoers/logging.c:282
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s zit niet in het sudoersbestand. Dit incident zal worden gerapporteerd.\n"
+
+#: plugins/sudoers/logging.c:285
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s heeft niet het recht om sudo te gebruiken op %s. Dit incident zal worden gerapporteerd.\n"
+
+#: plugins/sudoers/logging.c:289
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Sorry, gebruiker %s mag sudo niet gebruiken op %s.\n"
+
+#: plugins/sudoers/logging.c:292
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Sorry, gebruiker %s mag '%s%s%s' niet uitvoeren als %s%s%s op %s.\n"
+
+#: plugins/sudoers/logging.c:329 plugins/sudoers/sudoers.c:473
+#: plugins/sudoers/sudoers.c:475 plugins/sudoers/sudoers.c:477
+#: plugins/sudoers/sudoers.c:479 plugins/sudoers/sudoers.c:1298
+#: plugins/sudoers/sudoers.c:1300
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: opdracht niet gevonden"
+
+#: plugins/sudoers/logging.c:331 plugins/sudoers/sudoers.c:469
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"\"%s\" gevonden in '.' wordt genegeerd.\n"
+"Gebruik 'sudo ./%s' als dit de '%s' die u wilt uitvoeren."
+
+#: plugins/sudoers/logging.c:348
+msgid "authentication failure"
+msgstr "aanmeldingsfout"
+
+#: plugins/sudoers/logging.c:374
+msgid "a password is required"
+msgstr "een wachtwoord is verplicht"
+
+#: plugins/sudoers/logging.c:445 plugins/sudoers/logging.c:511
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u verkeerde wachtwoordpoging"
+msgstr[1] "%u verkeerde wachtwoordpogingen"
+
+#: plugins/sudoers/logging.c:598
+msgid "unable to fork"
+msgstr "kan niet afsplitsen"
+
+#: plugins/sudoers/logging.c:606 plugins/sudoers/logging.c:658
+#, c-format
+msgid "unable to fork: %m"
+msgstr "kan niet afsplitsen: %m"
+
+#: plugins/sudoers/logging.c:648
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "kan pipe niet openen: %m"
+
+#: plugins/sudoers/logging.c:673
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "kan stdin niet klonen: %m"
+
+#: plugins/sudoers/logging.c:711
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "kan %s niet uitvoeren: %m"
+
+#: plugins/sudoers/match.c:771
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "controlegetal voor %s (%s) is niet in de %s-vorm"
+
+#: plugins/sudoers/mkdir_parents.c:70 plugins/sudoers/sudoers.c:944
+#: plugins/sudoers/visudo.c:439 plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to stat %s"
+msgstr "kan stat op %s niet uitvoeren"
+
+#: plugins/sudoers/parse.c:115
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "ontleedfout in %s bij regel %d"
+
+#: plugins/sudoers/parse.c:118
+#, c-format
+msgid "parse error in %s"
+msgstr "ontleedfout in %s"
+
+#: plugins/sudoers/parse.c:544
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Sudoers-item:\n"
+
+#: plugins/sudoers/parse.c:545
+#, c-format
+msgid " RunAsUsers: "
+msgstr " RunAsUsers: "
+
+#: plugins/sudoers/parse.c:559
+#, c-format
+msgid " RunAsGroups: "
+msgstr " RunAsGroups: "
+
+#: plugins/sudoers/parse.c:568
+#, c-format
+msgid " Options: "
+msgstr " Opties: "
+
+#: plugins/sudoers/policy.c:243 plugins/sudoers/testsudoers.c:261
+msgid "unable to parse network address list"
+msgstr "kan netwerkadressenlijst niet ontleden"
+
+#: plugins/sudoers/policy.c:380
+msgid "user name not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:384
+msgid "user ID not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:388
+msgid "group ID not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:392
+msgid "host name not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:736 plugins/sudoers/visudo.c:910
+#, c-format
+msgid "unable to execute %s"
+msgstr "kan %s niet uitvoeren"
+
+#: plugins/sudoers/policy.c:869
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Sudoers-beleidsplugin versie %s\n"
+
+#: plugins/sudoers/policy.c:871
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Versie van sudoers-bestandsgrammatica %d\n"
+
+#: plugins/sudoers/policy.c:875
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Sudoers-pad: %s\n"
+
+#: plugins/sudoers/policy.c:878
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "nsswitch-pad: %s\n"
+
+#: plugins/sudoers/policy.c:880
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "ldap.conf-pad: %s\n"
+
+#: plugins/sudoers/policy.c:881
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "ldap.secret-pad: %s\n"
+
+#: plugins/sudoers/policy.c:914
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:188 plugins/sudoers/pwutil.c:206
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "kan gebruikersnummer %u niet bufferen, onvoldoende geheugen"
+
+#: plugins/sudoers/pwutil.c:200
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "kan gebruikersnummer %u niet bufferen, bestaat reeds"
+
+#: plugins/sudoers/pwutil.c:260 plugins/sudoers/pwutil.c:277
+#: plugins/sudoers/pwutil.c:339 plugins/sudoers/pwutil.c:384
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "kan gebruiker %s niet bufferen, onvoldoende geheugen"
+
+#: plugins/sudoers/pwutil.c:272
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "kan gebruiker %s niet bufferen, bestaat reeds"
+
+#: plugins/sudoers/pwutil.c:503 plugins/sudoers/pwutil.c:521
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "kan groepsnummer %u niet bufferen, onvoldoende geheugen"
+
+#: plugins/sudoers/pwutil.c:515
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "kan groepsnummer %u niet bufferen, bestaat reeds"
+
+#: plugins/sudoers/pwutil.c:569 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:633 plugins/sudoers/pwutil.c:675
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "kan groep %s niet bufferen, onvoldoende geheugen"
+
+#: plugins/sudoers/pwutil.c:581
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "kan groep %s niet bufferen, bestaat reeds"
+
+#: plugins/sudoers/pwutil.c:801 plugins/sudoers/pwutil.c:853
+#: plugins/sudoers/pwutil.c:904 plugins/sudoers/pwutil.c:957
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "kan groepslijst voor %s niet bufferen, bestaat reeds"
+
+#: plugins/sudoers/pwutil.c:807 plugins/sudoers/pwutil.c:858
+#: plugins/sudoers/pwutil.c:910 plugins/sudoers/pwutil.c:962
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "kan groepslijst voor %s niet bufferen, onvoldoende geheugen"
+
+#: plugins/sudoers/pwutil.c:847
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "kan groepen voor %s niet ontleden"
+
+#: plugins/sudoers/pwutil.c:951
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "kan groepsnummers voor %s niet ontleden"
+
+#: plugins/sudoers/set_perms.c:113 plugins/sudoers/set_perms.c:469
+#: plugins/sudoers/set_perms.c:912 plugins/sudoers/set_perms.c:1239
+#: plugins/sudoers/set_perms.c:1556
+msgid "perm stack overflow"
+msgstr "overloop van rechtenstapel"
+
+#: plugins/sudoers/set_perms.c:121 plugins/sudoers/set_perms.c:400
+#: plugins/sudoers/set_perms.c:477 plugins/sudoers/set_perms.c:779
+#: plugins/sudoers/set_perms.c:920 plugins/sudoers/set_perms.c:1163
+#: plugins/sudoers/set_perms.c:1247 plugins/sudoers/set_perms.c:1489
+#: plugins/sudoers/set_perms.c:1564 plugins/sudoers/set_perms.c:1654
+msgid "perm stack underflow"
+msgstr "onderloop van rechtenstapel"
+
+#: plugins/sudoers/set_perms.c:180 plugins/sudoers/set_perms.c:523
+#: plugins/sudoers/set_perms.c:1298 plugins/sudoers/set_perms.c:1596
+msgid "unable to change to root gid"
+msgstr "kan niet wijzigen naar rootgroepsnummer"
+
+#: plugins/sudoers/set_perms.c:269 plugins/sudoers/set_perms.c:620
+#: plugins/sudoers/set_perms.c:1049 plugins/sudoers/set_perms.c:1375
+msgid "unable to change to runas gid"
+msgstr "kan niet wijzigen naar runas-groepsnummer"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to set runas group vector"
+msgstr "kan runas-groepsvector niet instellen"
+
+#: plugins/sudoers/set_perms.c:285 plugins/sudoers/set_perms.c:636
+#: plugins/sudoers/set_perms.c:1063 plugins/sudoers/set_perms.c:1389
+msgid "unable to change to runas uid"
+msgstr "kan niet wijzigen naar runas-gebruikersnummer"
+
+#: plugins/sudoers/set_perms.c:303 plugins/sudoers/set_perms.c:654
+#: plugins/sudoers/set_perms.c:1079 plugins/sudoers/set_perms.c:1405
+msgid "unable to change to sudoers gid"
+msgstr "kan niet wijzigen naar sudoers-groepsnummer"
+
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1476
+#: plugins/sudoers/set_perms.c:1641
+msgid "too many processes"
+msgstr "te veel processen"
+
+#: plugins/sudoers/solaris_audit.c:51
+msgid "unable to get current working directory"
+msgstr "kan huidige werkmap niet achterhalen"
+
+#: plugins/sudoers/solaris_audit.c:59
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:66
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:115
+msgid "audit_failure message too long"
+msgstr "boodschap voor audit_failure is te lang"
+
+#: plugins/sudoers/sssd.c:402
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "Kan SSS-bron niet initialiseren. Is SSSD op uw machine geinstalleerd?"
+
+#: plugins/sudoers/sssd.c:410 plugins/sudoers/sssd.c:419
+#: plugins/sudoers/sssd.c:428 plugins/sudoers/sssd.c:437
+#: plugins/sudoers/sssd.c:446
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "kan symbool \"%s\" niet vinden in %s"
+
+#: plugins/sudoers/sssd.c:1556
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: %s\n"
+msgstr ""
+"\n"
+"SSSD Role: %s\n"
+
+#: plugins/sudoers/sssd.c:1561
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"SSSD Role: UNKNOWN\n"
+
+#: plugins/sudoers/sudo_nss.c:289
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Overeenkomende standaarditems voor %s op %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:307
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Runas en opdrachtspecifieke standaarden voor %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:325
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Gebruiker %s mag de volgende opdrachten uitvoeren op %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:338
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Gebruiker %s mag geen sudo gebruiken op %s.\n"
+
+#: plugins/sudoers/sudoers.c:168 plugins/sudoers/testsudoers.c:247
+#: plugins/sudoers/visudo.c:233 plugins/sudoers/visudo.c:612
+#: plugins/sudoers/visudo.c:976
+msgid "unable to initialize sudoers default values"
+msgstr "kan sudoers-standaardwaarden niet initialiseren"
+
+#: plugins/sudoers/sudoers.c:198 plugins/sudoers/sudoers.c:891
+msgid "problem with defaults entries"
+msgstr "probleem met standaarditems"
+
+#: plugins/sudoers/sudoers.c:205
+msgid "no valid sudoers sources found, quitting"
+msgstr "geen geldige sudoers-bronnen gevonden, afsluiten"
+
+#: plugins/sudoers/sudoers.c:244
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers geeft aan dat root geen sudo mag gebruiken"
+
+#: plugins/sudoers/sudoers.c:301
+msgid "you are not permitted to use the -C option"
+msgstr "u heeft niet de rechten om de optie -C te gebruiken"
+
+#: plugins/sudoers/sudoers.c:390
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "tijd-eigenaar (%s): Gebruiker bestaat niet"
+
+#: plugins/sudoers/sudoers.c:405
+msgid "no tty"
+msgstr "geen terminal"
+
+#: plugins/sudoers/sudoers.c:406
+msgid "sorry, you must have a tty to run sudo"
+msgstr "sorry, u moet een terminal hebben om sudo te gebruiken"
+
+#: plugins/sudoers/sudoers.c:468
+msgid "command in current directory"
+msgstr "opdracht in huidige map"
+
+#: plugins/sudoers/sudoers.c:487
+#, fuzzy
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "sorry, u mag de omgeving niet behouden"
+
+#: plugins/sudoers/sudoers.c:495
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "sorry, u mag de omgeving niet behouden"
+
+#: plugins/sudoers/sudoers.c:836
+msgid "command too long"
+msgstr "opdracht is te lang"
+
+#: plugins/sudoers/sudoers.c:948
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s in geen regulier bestand"
+
+#: plugins/sudoers/sudoers.c:952 plugins/sudoers/timestamp.c:217 toke.l:969
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s is eigendom van gebruikersnummer %u, zou %u moeten zijn"
+
+#: plugins/sudoers/sudoers.c:956 toke.l:974
+#, c-format
+msgid "%s is world writable"
+msgstr "%s kan door iedereen worden geschreven"
+
+#: plugins/sudoers/sudoers.c:960 toke.l:977
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s is eigendom van groepsnummer %u, zou %u moeten zijn"
+
+#: plugins/sudoers/sudoers.c:993
+#, fuzzy, c-format
+msgid "only root can use \"-c %s\""
+msgstr "alleen root kan '-c %s' gebruiken"
+
+#: plugins/sudoers/sudoers.c:1012
+#, c-format
+msgid "unknown login class: %s"
+msgstr "onbekende loginklasse: %s"
+
+#: plugins/sudoers/sudoers.c:1095 plugins/sudoers/sudoers.c:1109
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "kan computernaam %s niet herleiden"
+
+#: plugins/sudoers/sudoreplay.c:275
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "ongeldige filteroptie: %s"
+
+#: plugins/sudoers/sudoreplay.c:288
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "ongeldige maximale wachttijd: %s"
+
+#: plugins/sudoers/sudoreplay.c:300
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "ongeldige snelheidsfactor: %s"
+
+#: plugins/sudoers/sudoreplay.c:303 plugins/sudoers/visudo.c:186
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s versie %s\n"
+
+#: plugins/sudoers/sudoreplay.c:335
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/timing: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/timing: %s"
+
+#: plugins/sudoers/sudoreplay.c:357
+#, fuzzy, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Bekijken van sudo sessie: %s\n"
+
+#: plugins/sudoers/sudoreplay.c:555 plugins/sudoers/sudoreplay.c:602
+#: plugins/sudoers/sudoreplay.c:804 plugins/sudoers/sudoreplay.c:894
+#: plugins/sudoers/sudoreplay.c:973 plugins/sudoers/sudoreplay.c:988
+#: plugins/sudoers/sudoreplay.c:995 plugins/sudoers/sudoreplay.c:1002
+#: plugins/sudoers/sudoreplay.c:1009 plugins/sudoers/sudoreplay.c:1016
+#: plugins/sudoers/sudoreplay.c:1162
+msgid "unable to add event to queue"
+msgstr "kan gebeurtenis niet aan wachtrij toevoegen"
+
+#: plugins/sudoers/sudoreplay.c:670
+msgid "unable to set tty to raw mode"
+msgstr "kan terminal niet instellen op rauwe modus"
+
+#: plugins/sudoers/sudoreplay.c:721
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Waarschuwing: uw terminal is te klein om de log goed op te bekijken.\n"
+
+#: plugins/sudoers/sudoreplay.c:722
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Logverhouding is %d x %d, de verhouding van uw terminal is %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:749
+msgid "Replay finished, press any key to restore the terminal."
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:782
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "ongeldige timingsbestandregel: %s"
+
+#: plugins/sudoers/sudoreplay.c:1196 plugins/sudoers/sudoreplay.c:1221
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "dubbelzinnige expressie \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1243
+msgid "unmatched ')' in expression"
+msgstr "ongepaarde ')' in expressie"
+
+#: plugins/sudoers/sudoreplay.c:1247
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "onbekende zoekterm \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1262
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s vereist een argument"
+
+#: plugins/sudoers/sudoreplay.c:1265 plugins/sudoers/sudoreplay.c:1645
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "ongeldige reguliere expressie: %s"
+
+#: plugins/sudoers/sudoreplay.c:1269
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "kan datum niet ontleden \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1278
+msgid "unmatched '(' in expression"
+msgstr "ongepaarde '(' in expressie"
+
+#: plugins/sudoers/sudoreplay.c:1280
+msgid "illegal trailing \"or\""
+msgstr "ongeldige afsluitende \"or\""
+
+#: plugins/sudoers/sudoreplay.c:1282
+msgid "illegal trailing \"!\""
+msgstr "ongeldige afsluitende \"!\""
+
+#: plugins/sudoers/sudoreplay.c:1331
+#, c-format
+msgid "unknown search type %d"
+msgstr "onbekend zoektype %d"
+
+#: plugins/sudoers/sudoreplay.c:1369
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: ongeldig logbestand"
+
+#: plugins/sudoers/sudoreplay.c:1387
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: tijdveld ontbreekt"
+
+#: plugins/sudoers/sudoreplay.c:1394
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: tijdstempel %s: %s"
+
+#: plugins/sudoers/sudoreplay.c:1401
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: gebruikersveld ontbreekt"
+
+#: plugins/sudoers/sudoreplay.c:1410
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: runas-gebuikersveld ontbreekt"
+
+#: plugins/sudoers/sudoreplay.c:1419
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: runas-groepveld ontbreekt"
+
+#: plugins/sudoers/sudoreplay.c:1825
+#, c-format
+msgid "usage: %s [-hnR] [-d dir] [-m num] [-s num] ID\n"
+msgstr "Gebruik: %s [-hnR] [-d map] [-m wachttijd] [-s snelheidsfactor] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1828
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "Gebruik: %s [-h] [-d map] -l [zoek-expressie]\n"
+
+#: plugins/sudoers/sudoreplay.c:1837
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - sudo sessielogs bekijken\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1839
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Opties:\n"
+" -d, --directory=map map voor sessielogs opgeven\n"
+" -f, --filter=filter opgeven welk type in-/uitvoer moet worden weergegeven\n"
+" -h, --help geef help weer (dit bericht) en sluit af\n"
+" -l, --list [expressie] som beschikbare sessienummers\n"
+" die overeenkomen met de expressie op\n"
+" -m, --max-wait=num wacht tussen gebeurtenissen maximaal m seconden\n"
+" -s, --speed=num snelheid van uitvoer verhogen of verlagen\n"
+" -V, --version geef versieinformatie weer en sluit af"
+
+#: plugins/sudoers/testsudoers.c:329
+msgid "\thost unmatched"
+msgstr "\tcomputer komt niet overeen"
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Opdracht toegestaan"
+
+#: plugins/sudoers/testsudoers.c:333
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Opdracht niet toegestaan"
+
+#: plugins/sudoers/testsudoers.c:333
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Opdracht komt niet overeen"
+
+#: plugins/sudoers/timestamp.c:225
+#, c-format
+msgid "%s is group writable"
+msgstr "%s kan door groep worden gewijzigd"
+
+#: plugins/sudoers/timestamp.c:301
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "kan tijdstempelbestand niet inkorten naar %lld bytes"
+
+#: plugins/sudoers/timestamp.c:756 plugins/sudoers/timestamp.c:823
+#: plugins/sudoers/visudo.c:500 plugins/sudoers/visudo.c:506
+msgid "unable to read the clock"
+msgstr "kan de klok niet lezen"
+
+#: plugins/sudoers/timestamp.c:770
+msgid "ignoring time stamp from the future"
+msgstr "tijdstempel uit de toekomst wordt genegeerd"
+
+#: plugins/sudoers/timestamp.c:782
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "tijd is te ver in de toekomst: %20.20s"
+
+#: plugins/sudoers/timestamp.c:877
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "kan tijdstempelbestand %s niet vergrendelen"
+
+#: plugins/sudoers/timestamp.c:921 plugins/sudoers/timestamp.c:941
+#, fuzzy, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "tijd voor pad te lang: %s"
+
+#: plugins/sudoers/visudo.c:188
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s grammaticaversie %d\n"
+
+#: plugins/sudoers/visudo.c:266 plugins/sudoers/visudo.c:667
+#, c-format
+msgid "press return to edit %s: "
+msgstr "Druk op Enter om %s te bewerken: "
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "opgegeven editor (%s) bestaat niet"
+
+#: plugins/sudoers/visudo.c:349
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "geen editor gevonden (editorpad = %s)"
+
+#: plugins/sudoers/visudo.c:459 plugins/sudoers/visudo.c:467
+msgid "write error"
+msgstr "schrijffout"
+
+#: plugins/sudoers/visudo.c:513
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "kan status van tijdelijk bestand (%s) niet vaststellen, %s ongewijzigd"
+
+#: plugins/sudoers/visudo.c:520
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "tijdelijk bestand (%s) leeg, %s ongewijzigd"
+
+#: plugins/sudoers/visudo.c:526
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "editor (%s) is mislukt, %s ongewijzigd"
+
+#: plugins/sudoers/visudo.c:548
+#, c-format
+msgid "%s unchanged"
+msgstr "%s ongewijzigd"
+
+#: plugins/sudoers/visudo.c:607
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "kan tijdelijk bestand (%s) niet openen, %s ongewijzigd."
+
+#: plugins/sudoers/visudo.c:619
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "kan tijdelijke bestand (%s) niet ontleden, onbekende fout"
+
+#: plugins/sudoers/visudo.c:656
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "interne fout, kan %s niet in de lijst vinden!"
+
+#: plugins/sudoers/visudo.c:736 plugins/sudoers/visudo.c:745
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "kan %s niet wijzigen (gebruikers- of groepsnummer) naar (%u, %u)"
+
+#: plugins/sudoers/visudo.c:767
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s en %s niet op hetzelfde bestandssyteem, gebuikt mv om te hernoemen"
+
+#: plugins/sudoers/visudo.c:781
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "opdracht mislukt: '%s %s %s', %s ongewijzigd"
+
+#: plugins/sudoers/visudo.c:791
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "fout bij hernoemen %s, %s ongewijzigd"
+
+#: plugins/sudoers/visudo.c:855
+msgid "What now? "
+msgstr "Wat nu? "
+
+#: plugins/sudoers/visudo.c:869
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Opties zijn:\n"
+" (e)dit sudoers bestand opnieuw\n"
+" e(x)it zonder de wijzigingen op te slaan\n"
+" (Q)uit en sla wijziging op in het sudoers bestand (GEVAAR!)\n"
+
+#: plugins/sudoers/visudo.c:915
+#, c-format
+msgid "unable to run %s"
+msgstr "kan %s niet uitvoeren"
+
+#: plugins/sudoers/visudo.c:945
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: verkeerde eigenaar (gebruikers-, groepsnummer) zou moeten zijn (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:952
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: verkeerde toegangsrechten, zou modus 0%o moeten zijn\n"
+
+#: plugins/sudoers/visudo.c:981 plugins/sudoers/visudo_json.c:1021
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "kan %s-bestand niet ontleden, onbekende fout"
+
+#: plugins/sudoers/visudo.c:997 plugins/sudoers/visudo_json.c:1032
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "fout bij ontleden van %s bij regel %d\n"
+
+#: plugins/sudoers/visudo.c:1000 plugins/sudoers/visudo_json.c:1035
+#, c-format
+msgid "parse error in %s\n"
+msgstr "fout bij ontleden van %s\n"
+
+#: plugins/sudoers/visudo.c:1008 plugins/sudoers/visudo.c:1015
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: ontleden is geslaagd\n"
+
+#: plugins/sudoers/visudo.c:1062
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s bezig, probeer het later opnieuw"
+
+#: plugins/sudoers/visudo.c:1159
+#, fuzzy, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Fout: cyclus in %s '%s'"
+
+#: plugins/sudoers/visudo.c:1160
+#, fuzzy, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Waarschuwing: cyclus in %s '%s'"
+
+#: plugins/sudoers/visudo.c:1164
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Fout: %s:%d %s \"%s\" wordt naar verwezen, maar is niet gedefinieerd"
+
+#: plugins/sudoers/visudo.c:1165
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Waarschuwing: %s:%d %s \"%s\" wordt naar verwezen, maar is niet gedefinieerd"
+
+#: plugins/sudoers/visudo.c:1318
+#, fuzzy, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Waarschuwing: %s '%s' wordt niet gebruikt"
+
+#: plugins/sudoers/visudo.c:1433
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - bewerk het sudoersbestand voorzichtig\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1435
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+" -x, --export=output_file write sudoers in JSON format to output_file"
+msgstr ""
+"\n"
+"Opties:\n"
+" -c, --check alleen lezen modus\n"
+" -f, --file=bestand geef lokatie van sudoersbestand op\n"
+" -h, --help geef help weer (dit bericht) en sluit af\n"
+" -q, --quiet minder uitgebreide syntactische fout berichten\n"
+" -s, --strict stricte controle van syntaxis\n"
+" -V, --verion geef versieinformatie weer en sluit af"
+
+#: plugins/sudoers/visudo_json.c:616 plugins/sudoers/visudo_json.c:651
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "onbekend standaarditem '%s'"
+
+#: plugins/sudoers/visudo_json.c:1007
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: in- en uitvoerbestanden moeten verschillen"
+
+#: toke.l:943
+msgid "too many levels of includes"
+msgstr "te veel niveaus van insluitingen"
+
+#~ msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+#~ msgstr "sudo_ldap_conf_add_ports: ruimte ontoereikend bij uitbreiden hostbuf"
+
+#~ msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+#~ msgstr "sudo_ldap_parse_uri: ruimte ontoereikend bij bouwen van hostbuf"
+
+#~ msgid "sudo_ldap_build_pass1 allocation mismatch"
+#~ msgstr "sudo_ldap_build_pass1 reserveren mislukt"
+
+#~ msgid "timestamp path too long: %s/%s"
+#~ msgstr "tijd voor pad te lang: %s/%s"
+
+#~ msgid "unable to stat editor (%s)"
+#~ msgstr "kan status van editor (%s) niet verkrijgen"
+
+#~ msgid "Password:"
+#~ msgstr "Wachtwoord:"
+
+#~ msgid "unable to setup authentication"
+#~ msgstr "kan verificatie niet instellen"
+
+#~ msgid "invalid uri: %s"
+#~ msgstr "ongeldige uri: %s"
+
+#~ msgid "unable to mix ldaps and starttls"
+#~ msgstr "kan ldaps en starttls niet door elkaar gebruiken"
+
+#~ msgid "internal error: insufficient space for log line"
+#~ msgstr "interne fout: onvoldoende ruimte voor logregel"
+
+#~ msgid "value out of range"
+#~ msgstr "waarde buiten bereik"
+
+#~ msgid "writing to standard output"
+#~ msgstr "naar standaarduitvoer schrijven"
+
+#~ msgid "too many parenthesized expressions, max %d"
+#~ msgstr "te veel geneste expressies, maximum %d"
+
+#~ msgid "%s owned by uid %u, should be uid %u"
+#~ msgstr "%s is van gebruikersnummer %u, zou gebruikersnummer %u moeten zijn"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0700"
+#~ msgstr "%s kan geschreven worden door niet-eigenaar (0%o), zou ingesteld moeten zijn op 0700"
+
+#~ msgid "%s exists but is not a regular file (0%o)"
+#~ msgstr "%s bestaat maar is geen normaal bestand (0%o)"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0600"
+#~ msgstr "%s kan geschreven worden bij niet-eigenaar (0%o), zou ingesteld moeten zijn op 0600"
+
+#~ msgid "unable to remove %s, will reset to the epoch"
+#~ msgstr "kan %s niet verwijderen, wordt geherinitialiseerd op de epoch"
+
+#~ msgid "fill_args: buffer overflow"
+#~ msgstr "fill_args: stapeloverloop"
+
+#~ msgid "%s: unused %s_Alias %s"
+#~ msgstr "%s: ongebruikte %s_Alias %s"
+
+#~ msgid ">>> %s: %s near line %d <<<"
+#~ msgstr ">>> %s: %s bij regel %d <<<"
+
+#~ msgid "pam_chauthtok: %s"
+#~ msgstr "pam_chauthtok: %s"
+
+#~ msgid "pam_authenticate: %s"
+#~ msgstr "pam_authenticate: %s"
+
+#~ msgid "getaudit: failed"
+#~ msgstr "getaudit: mislukt"
+
+#~ msgid "getauid failed"
+#~ msgstr "getauid mislukt"
+
+#~ msgid "au_open: failed"
+#~ msgstr "au_open: mislukt"
+
+#~ msgid "au_to_subject: failed"
+#~ msgstr "au_to_subject: mislukt"
+
+#~ msgid "au_to_exec_args: failed"
+#~ msgstr "au_to_exec_args: mislukt"
+
+#~ msgid "au_to_return32: failed"
+#~ msgstr "au_to_return32: mislukt"
+
+#~ msgid "getauid: failed"
+#~ msgstr "getauid: failed"
+
+#~ msgid "au_to_text: failed"
+#~ msgstr "au_to_text: failed"
+
+#~ msgid "unable to set locale to \"%s\", using \"C\""
+#~ msgstr "kan taaldefinitie niet instellen op \"%s\", gebruikt wordt \"C\""
+
+#~ msgid ""
+#~ " Commands:\n"
+#~ "\t"
+#~ msgstr ""
+#~ " Opdrachten:\n"
+#~ "\t"
+
+#~ msgid "unable to cache uid %u (%s), already exists"
+#~ msgstr "kan gebruikersnummer %u niet bufferen (%s), bestaat reeds"
+
+#~ msgid "unable to cache gid %u (%s), already exists"
+#~ msgstr "kan groepsnummer %u niet bufferen (%s), bestaat reeds"
+
+#~ msgid "Unable to dlopen %s: %s"
+#~ msgstr "Kan niet dlopen %s: %s"
+
+#~ msgid "unable to execute %s: %s"
+#~ msgstr "kan %s niet uitvoeren: %s"
+
+#~ msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
+#~ msgstr "nanosleep: tv_sec %ld, tv_nsec %ld"
+
+#~ msgid "invalid regex: %s"
+#~ msgstr "ongeldige reguliere expressie: %s"
diff --git a/plugins/sudoers/po/pl.mo b/plugins/sudoers/po/pl.mo
new file mode 100644
index 0000000..a8aae55
--- /dev/null
+++ b/plugins/sudoers/po/pl.mo
Binary files differ
diff --git a/plugins/sudoers/po/pl.po b/plugins/sudoers/po/pl.po
new file mode 100644
index 0000000..b722afc
--- /dev/null
+++ b/plugins/sudoers/po/pl.po
@@ -0,0 +1,2346 @@
+# Polish translation for sudo/sudoers.
+# This file is put in the public domain.
+# Jakub Bogusz <qboosh@pld-linux.org>, 2011-2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-29 20:15+0100\n"
+"Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
+"Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "błąd składni"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "Hasło użytkownika %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] hasło użytkownika %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Hasło: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** informacje dotyczące BEZPIECZEŃSTWA dla %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Niestety, proszę spróbować ponownie."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336
+#: gram.y:399 gram.y:407 gram.y:417 gram.y:450 gram.y:457 gram.y:464
+#: gram.y:471 gram.y:553 gram.y:560 gram.y:569 gram.y:578 gram.y:595
+#: gram.y:707 gram.y:714 gram.y:721 gram.y:729 gram.y:829 gram.y:836
+#: gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890 gram.y:897
+#: gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:195 plugins/sudoers/logging.c:511
+#: plugins/sudoers/logging.c:532 plugins/sudoers/logging.c:573
+#: plugins/sudoers/logging.c:752 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr "nie udało się przydzielić pamięci"
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr "skrót wymaga nazwy pliku"
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr "błędna wartość notbefore"
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr "błędna wartość notafter"
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr "wartość limitu czasu zbyt duża"
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr "błędna wartość limitu czasu"
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:354 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:511 plugins/sudoers/logging.c:532
+#: plugins/sudoers/logging.c:572 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:724 plugins/sudoers/match.c:771
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1008
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Alias \"%s\" jest już zdefiniowany"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "nie udało się uzyskać klasy logowania dla użytkownika %s"
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr "nie udało się rozpocząć uwierzytelnienia BSD"
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr "błędny rodzaj uwierzytelnienia"
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr "nie udało się zainicjować uwierzytelnienia BSD"
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr "konto wygasło"
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr "zezwolenie nie powiodło się"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr "nie udało się odczytać konfiguracji fwtk"
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr "nie udało się połączyć z serwerem uwierzytelniającym"
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr "utracono połączenie z serwerem uwierzytelniającym"
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"błąd serwera uwierzytelniającego:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: nie udało się przekształcić nazwy principal do łańcucha ('%s'): %s"
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: nie udało się przeanalizować '%s': %s"
+
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: nie udało się rozwiązać pamięci podręcznej danych uwierzytelniających: %s"
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: nie udało się przydzielić opcji: %s"
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: nie udało się pobrać danych uwierzytelniających: %s"
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: nie udało się zainicjować pamięci podręcznej danych uwierzytelniających: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: nie udało się zapisać danych uwierzytelniających w pamięci podręcznej: %s"
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: nie udało się pobrać nazwy principal dla hosta: %s"
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Nie można zweryfikować TGT! Możliwy atak!: %s"
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr "nie udało się zainicjować PAM"
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Błąd uwierzytelniania PAM: %s"
+
+#: plugins/sudoers/auth/pam.c:221
+msgid "account validation failure, is your account locked?"
+msgstr "błąd kontroli poprawności konta - konto zablokowane?"
+
+#: plugins/sudoers/auth/pam.c:229
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Konto lub hasło wygasło, należy ustawić ponownie hasło i spróbować jeszcze raz"
+
+#: plugins/sudoers/auth/pam.c:238
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "nie udało się zmienić przedawnionego hasła: %s"
+
+#: plugins/sudoers/auth/pam.c:246
+msgid "Password expired, contact your system administrator"
+msgstr "Hasło wygasło, proszę skontaktować się z administratorem systemu"
+
+#: plugins/sudoers/auth/pam.c:250
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Konto wygasło lub w konfiguracji PAM brak sekcji \"account\" dla sudo, proszę skontaktować się z administratorem systemu"
+
+#: plugins/sudoers/auth/pam.c:257 plugins/sudoers/auth/pam.c:262
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "Błąd zarządzania kontem PAM: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:232
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "nie istniejesz w bazie danych %s"
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr "nie udało się zainicjować biblioteki ACE API"
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr "nie udało się połączyć z serwerem SecurID"
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr "ID użytkownika zablokowany dla uwierzytelnienia SecurID"
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr "błędna długość nazwy użytkownika dla SecurID"
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr "błędny uchwyt uwierzytelnienia dla SecurID"
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr "błąd komunikacji SecurID"
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr "nieznany błąd SecurID"
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr "błędna długość hasła dla SecurID"
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr "nie udało się zainicjować sesji SIA"
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr "błędne metody uwierzytelniania"
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "W sudo wkompilowano błędne metody uwierzytelniania! Nie można mieszać samodzielnych i niesamodzielnych sposobów uwierzytelniania."
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr "brak metod uwierzytelniania"
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "W sudo nie wkompilowano żadnych metod uwierzytelniania! Aby wyłączyć uwierzytelnianie, proszę użyć opcji konfiguracyjnej --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr "Nie udało się zainicjować metod uwierzytelniania."
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr "Metody uwierzytelniania:"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr "Nie udało się określić warunku audytowego"
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr "nie udało się zatwierdzić rekordu audytowego"
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Ufamy, że lokalny administrator udzielił odpowiedniego szkolenia.\n"
+"Zwykle sprowadza się ono do tych trzech rzeczy:\n"
+"\n"
+" 1) należy respektować prywatność innych,\n"
+" 2) należy myśleć przed pisaniem,\n"
+" 3) z dużą władzą wiąże się duża odpowiedzialność.\n"
+"\n"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr "nieznany uid: %u"
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1136
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr "nieznany użytkownik: %s"
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "zwiększenie rangi: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "początkowa ranga: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr "wyrównanie rangi: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s wersja %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s, wersja gramatyki %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr "nieobsługiwany format wejścia %s"
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr "nieobsługiwany format wyjścia %s"
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: pliki wejściowy i wyjściowy muszą być różne"
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:238
+#: plugins/sudoers/visudo.c:594 plugins/sudoers/visudo.c:917
+msgid "unable to initialize sudoers default values"
+msgstr "nie udało się zainicjować wartości domyślnych sudoers"
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: nieznane słowo kluczowe: %s"
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "błędny typ wartości domyślnej: %s"
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "błędny typ ograniczenia: %s"
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr "błędny filtr: %s"
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:913
+#, c-format
+msgid "unable to open %s"
+msgstr "nie udało się otworzyć %s"
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:922
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "nie udało się przeanalizować pliku %s, nieznany błąd"
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:939
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "błąd składni w %s w okolicy linii %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:942
+#, c-format
+msgid "parse error in %s\n"
+msgstr "błąd składni w %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr "nie udało się zapisać do %s"
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s - konwersja między formatami pliku sudoers\n"
+"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Opcje:\n"
+" -b. --base=dn podstawowe DN do zapytań LDAP z sudo\n"
+" -d, --defaults=typy konwersja Defaults tylko określonych typów\n"
+" -e, --expand-aliases rozwinięcie aliasów w trakcie konwersji\n"
+" -f, --output-format=format format wyjścia: JSON, LDIF lub sudoers\n"
+" -i, --input-format=format format wejścia: LDIF lub sudoers\n"
+" -I, --increment=liczba liczba, o jaką ma być zwiększane każde sudoOrder\n"
+" -h, --help wyświetlenie pomocy i zakończenie\n"
+" -m, --match=filtr konwersja tylko wpisów pasujących do filtra\n"
+" -M, --match-local filtr dopasowania używający baz passwd i group\n"
+" -o, --output=plik zapis skonwertowanego sudoers do pliku wyjciowego\n"
+" -O, --order-start=liczba początkowa wartość pierwszego sudoOrder\n"
+" -p, --prune-matches czyszczenie nie pasujących użytkowników, grup,\n"
+" hostów\n"
+" -P, --padding=num bazowe wyrównanie dla kroku sudoOrder\n"
+" -s, --suppress=sekcje pominięcie wyjścia z podanych sekcji\n"
+" -V, --version wyświetlenie informacji o wersji i zakończenie"
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "nieznany wpis domyślny \"%s\""
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr "nie udało się pobrać czasu GMT"
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr "nie udało się sformatować znacznika czasu"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1015 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "błąd wewnętrzny, przepełnienie %s"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr "zbyt dużo wpisów sudoers, maksimum to %u"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "zmienna środowiskowa SUDOERS_BASE nie jest ustawiona i nie podano opcji -b."
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Rodzaj komunikatu sysloga, jeśli syslog jest używany: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Priorytet komunikatu sysloga w przypadku udanego uwierzytelnienia: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Priorytet komunikatu sysloga w przypadku nieudanego uwierzytelnienia: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "Umieszczenie zachęty OTP we własnej linii"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "Ignorowanie '.' w $PATH"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "Wysyłanie listu zawsze przy uruchomieniu sudo"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "Wysyłanie listu przy błędnym uwierzytelnieniu"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "Wysyłanie listu jeśli użytkownik nie jest w sudoers"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Wysyłanie listu jeśli użytkownik nie jest w sudoers dla tego hosta"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Wysyłanie listu jeśli użytkownik nie ma prawa do uruchomienia polecenia"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "Wysyłanie listu jeśli użytkownik próbuje uruchomić polecenie"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Użycie osobnego znacznika czasu dla każdej pary użytkownik/tty"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "Poinstruowanie użytkownika przy pierwszym uruchomieniu sudo"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Plik zawierający instrukcję do sudo: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "Domyślne wymaganie uwierzytelnienia przez użytkowników"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "Możliwość uruchamiania sudo przez roota"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Logowanie nazwy hosta w pliku logu (niesyslogowym)"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Logowanie roku w pliku logu (niesyslogowym)"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Uruchomienie powłoki przy wywołaniu sudo bez argumentów"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Ustawianie $HOME na katalog użytkownika docelowego przy uruchamianiu powłoki z -s"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Ustawianie $HOME zawsze na katalog domowy użytkownika docelowego"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Zezwolenie na zbieranie niektórych informacji do przydatnych komunikatów błędów"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Wymaganie pełnych nazw hostów w pliku sudoers"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Lżenie użytkownika po podaniu błędnego hasła"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Możliwość uruchamiania sudo tylko z poziomu terminala"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Honorowanie zmiennej środowiskowej EDITOR przez visudo"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "Pytanie o hasło roota zamiast hasła użytkownika"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Pytanie o hasło użytkownika runas_default zamiast uruchamiającego"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Pytanie o hasło użytkownika docelowego zamiast uruchamiającego"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Użycie ustawień domyślnych z klasy logowania użytkownika docelowego (jeśli są)"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Ustawianie zmiennych środowiskowych LOGNAME i USER"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Ustawianie na użytkownika docelowego tylko efektywnego uid-a, nie rzeczywistego uid-a"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Pomijanie inicjalizacji wektora grup na grupy użytkownika docelowego"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Długość, na której zawijać linie logu (0 bez zawijania): %u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Limit czasu znacznika uwierzytelniania (w minutach): %.1f"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Limit czasu pytania o hasło (w minutach): %.1f"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Liczba prób wpisania hasła: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Wartość umask lub 0777, aby użyć wartości użytkownika: 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Ścieżka do pliku logu: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Ścieżka do programu mail: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Flagi dla programu mail: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Adres, na który mają być wysyłane listy: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Adres, z którego mają być wysyłane listy: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Temat wysyłanych listów: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Komunikat o błędnym haśle: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Ścieżka katalogu stanu instrukcji: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Ścieżka katalogu znaczników czasu uwierzytelniania: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Właściciel katalogu znaczników czasu uwierzytelniania: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Grupa, której użytkownicy są zwolnieni z wymagań dot. haseł i PATH: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Domyślne pytanie o hasło: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Czy passprompt ma być używane zamiast systemowego zapytania we wszystkich przypadkach"
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Domyślny użytkownik do uruchamiania poleceń: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Wartość do podstawienia za $PATH użytkownika: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Ścieżka do edytora, który ma być używany przez visudo: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Kiedy ma być wymagane hasło dla pseudopolecenia 'list': %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Kiedy ma być wymagane hasło dla pseudopolecenia 'verify': %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Wczytanie pustych funkcji exec zawartych w bibliotece sudo_noexec"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Jeśli istnieje katalog LDAP, czy ignorować lokalny plik sudoers"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Deskryptory plików >= %d będą zamykane przed uruchomieniem polecenia"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Czy użytkownicy mogą zmieniać wartość `closefrom' opcją -C"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Zezwolenie użytkownikom na ustawianie dowolnych zmiennych środowiskowych"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "Wyczyszczenie środowiska do domyślnego zbioru zmiennych"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "Zmienne środowiskowe do sprawdzania poprawności:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "Zmienne środowiskowe do usunięcia:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "Zmienne środowiskowe do zachowania:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Rola SELinuksa do używania w nowym kontekście bezpieczeństwa: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Typ SELinuksa do używania w nowym kontekście bezpieczeństwa: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Ścieżka do pliku środowiska specyficznego dla sudo: %s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Ścieżka do pliku ograniczonego środowiska specyficznego dla sudo: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Lokalizacja, jak ma być używana przy analizie pliku sudoers: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Zezwolenie sudo na pytanie o hasło nawet gdyby miało być widoczne"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Uwidocznienie wprowadzania hasła przez użytkownika w miarę wpisywania"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Użycie szybszych masek (glob) - mniej dokładnych, ale nie odwołujących się do systemu plików"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "Wartość umask podana w sudoers ma zastąpić wartość użytkownika, nawet jeśli pozwala na więcej"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "Logowanie wejścia użytkownika dla uruchamianych poleceń"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "Logowanie wyjścia z uruchamianych poleceń"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "Kompresja logów we/wy przy użyciu zliba"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "Uruchamianie poleceń zawsze na pseudoterminalu"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Wtyczka do obsługi grup nieuniksowych: %s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Katalog do zapisu logów wejścia/wyjścia: %s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Plik do zapisu logu wejścia/wyjścia: %s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Dodawanie wpisu do pliku utmp/utmpx przy przydzielaniu pty"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Ustawianie użytkownika w utmp jako docelowego, nie wywołującego"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Zbiór dozwolonych uprawnień: %s"
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Zbiór ograniczonych uprawnień: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "Uruchomienie poleceń na pseudoterminalu w tle"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "Nazwa usługi PAM do użycia: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "Nazwa usługi PAM do użycia dla powłok logowania: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Próba ustanowienia danych uwierzytelniających PAM dla użytkownika docelowego"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "Utworzenie nowej sesji PAM dla uruchamianego polecenia"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Maksymalny numer sekwencji logu we/wy: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "Włączenie obsługi grup sieciowych w sudoers"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Sprawdzanie katalogów nadrzędnych pod kątem możliwości zapisu przy edycji plików programem sudoedit"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Podążanie za dowiązaniami symbolicznymi przy edycji programem sudoedit"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "Odpytanie wtyczki group pod kątem nieznanych grup systemowych"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Dopasowanie grup sieciowych w oparciu o całą krotkę: użytkownik, host i domena"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Zezwolenie na uruchamianie poleceń nawet jeśli sudo nie może pisać do logu audytowego"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Zezwolenie na uruchamianie poleceń nawet jeśli sudo nie może pisać do logu we/wy"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Zezwolenie na uruchamianie poleceń nawet jeśli sudo nie może pisać do pliku logu"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Rozwiązanie grup z sudoers i dopasowywanie po ID grupy zamiast nazwy"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Wpisy logu większe niż ta wartość będą dzielone na wiele wiadomości sysloga: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Użytkownik, który będzie właścicielem plików logu we/wy: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Grupa, która będzie właścicielem plików logu we/wy: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Uprawnienia dla plików logu we/wy: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Uruchomienie poleceń poprzez deskryptor pliku zamiast ścieżki: %s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Ignorowanie nieznanych wpisów Defaults w sudoers zamiast ostrzeżenia"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Czas w sekundach, po którym polecenie będzie kończone: %u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Zezwolenie użytkownikowi na określenie limitu czasu z linii poleceń"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Natychmiastowy zrzut danych logu we/wy na dysk zamiast buforowania"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "Dołączanie identyfikatora procesu przy logowaniu przez syslog"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Rodzaj rekordu znacznika czasu uwierzytelniania: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "Komunikat błędu uwierzytelnienia: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "Ignorowanie wielkości liter przy dopasowywaniu nazw użytkownika"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "Ignorowanie wielkości liter przy dopasowywaniu nazw grup"
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d: nieznany wpis domyślny \"%s\""
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: nieznany wpis domyślny \"%s\""
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d: nie podano wartości dla \"%s\""
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: nie podano wartości dla \"%s\""
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d: wartości \"%s\" muszą zaczynać się od '/'"
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: wartości \"%s\" muszą zaczynać się od '/'"
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d: opcja \"%s\" nie przyjmuje wartości"
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: opcja \"%s\" nie przyjmuje wartości"
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d: błędny typ Defaults 0x%x dla opcji \"%s\""
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: błędny typ Defaults 0x%x dla opcji \"%s\""
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d: błędna wartość \"%s\" dla opcji \"%s\""
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: błędna wartość \"%s\" dla opcji \"%s\""
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: uszkodzone envp, niezgodność długości"
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr "nie udało się przebudować środowiska"
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "niestety nie jest dozwolone ustawianie następujących zmiennych środowiskowych: %s"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "błąd składni w %s w okolicy linii %d"
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "błąd składni w %s"
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "nieobsługiwany typ skrótu %d dla %s"
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr "%s: błąd odczytu"
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "właścicielem %s musi być uid %d"
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "prawo zapisu do %s może mieć tylko właściciel"
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "nie udało się załadować %s: %s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "nie udało się odnaleźć symbolu \"group_plugin\" w %s"
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: niezgodna główna wersja wtyczki grup %d, oczekiwano %d"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "nie udało się przeanalizować adresu IP \"%s\""
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "nie udało się przeanalizować maski sieciowej \"%s\""
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Pary lokalnych adresów IP i masek:\n"
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s istnieje, ale nie jest katalogiem (0%o)"
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "nie udało się wykonać mkdir %s"
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:723
+#: plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "nie udało się zmienić uprawnień %s na 0%o"
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1167
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr "nieznana grupa: %s"
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr "nie udało się odczytać %s"
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr "nie udało się utworzyć %s"
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "nie udało się zapisać do pliku logu we/wy: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr "%s: błąd wewnętrzny, plik logu we/wy dla zdarzenia %d nie jest otwarty"
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr "%s: błąd wewnętrzny, błędny sygnał %d"
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: błędny plik logu"
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: brak pola znacznika czasu"
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: znacznik czasu %s: %s"
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: brak pola z użytkownikiem"
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: brak pola z użytkownikiem runas"
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: brak pola z grupą runas"
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr "brak obsługi starttls w przypadku użycia ldaps"
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "nie udało się zainicjować bazy certyfikatów i kluczy SSL: %s"
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "aby używać SSL, trzeba ustawić TLS_CERT w %s"
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "nie udało się zainicjować LDAP: %s"
+
+#: plugins/sudoers/ldap.c:1648
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "wybrano start_tls, ale biblioteki LDAP nie obsługują ldap_start_tls_s() ani ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "błędny atrybut sudoOrder: %s"
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: port zbyt duży"
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "nieobsługiwany rodzaj URI LDAP: %s"
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "nie można mieszać URI ldap i ldaps"
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "nie można skonwertować sudoOption: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "nie udało się otworzyć systemu audytowego"
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr "nie udało się wysłać komunikatu audytowego"
+
+#: plugins/sudoers/logging.c:113
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:141
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (kontynuacja polecenia) %s"
+
+#: plugins/sudoers/logging.c:170
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "nie udało się otworzyć pliku logu: %s"
+
+#: plugins/sudoers/logging.c:178
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "nie udało się zablokować pliku logu: %s"
+
+#: plugins/sudoers/logging.c:211
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "nie udało się zapisać pliku logu: %s"
+
+#: plugins/sudoers/logging.c:240
+msgid "No user or host"
+msgstr "Brak użytkownika lub hosta"
+
+#: plugins/sudoers/logging.c:242
+msgid "validation failure"
+msgstr "błąd kontroli poprawności"
+
+#: plugins/sudoers/logging.c:249
+msgid "user NOT in sudoers"
+msgstr "użytkownik NIE występuje w sudoers"
+
+#: plugins/sudoers/logging.c:251
+msgid "user NOT authorized on host"
+msgstr "użytkownik NIE jest autoryzowany na hoście"
+
+#: plugins/sudoers/logging.c:253
+msgid "command not allowed"
+msgstr "polecenie niedozwolone"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s nie występuje w pliku sudoers. Ten incydent zostanie zgłoszony.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s nie ma uprawnień do uruchamiania sudo na %s. Ten incydent zostanie zgłoszony.\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Niestety użytkownik %s nie może uruchamiać sudo na %s.\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Niestety użytkownik %s nie ma uprawnień do uruchamiania '%s%s%s' jako %s%s%s na %s.\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: nie znaleziono polecenia"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"zignorowano plik \"%s\" znaleziony w '.'\n"
+"Proszę użyć \"sudo ./%s\", jeśli to \"%s\" ma być uruchomiony."
+
+#: plugins/sudoers/logging.c:354
+msgid "authentication failure"
+msgstr "błąd uwierzytelniania"
+
+#: plugins/sudoers/logging.c:380
+msgid "a password is required"
+msgstr "wymagane jest hasło"
+
+#: plugins/sudoers/logging.c:443
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u błędna próba wprowadzenia hasła"
+msgstr[1] "%u błędne próby wprowadzenia hasła"
+msgstr[2] "%u błędnych prób wprowadzenia hasła"
+
+#: plugins/sudoers/logging.c:666
+msgid "unable to fork"
+msgstr "nie udało się wykonać fork"
+
+#: plugins/sudoers/logging.c:674 plugins/sudoers/logging.c:726
+#, c-format
+msgid "unable to fork: %m"
+msgstr "nie udało się wykonać fork: %m"
+
+#: plugins/sudoers/logging.c:716
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "nie udało się otworzyć potoku: %m"
+
+#: plugins/sudoers/logging.c:741
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "nie udało się wykonać dup na stdin: %m"
+
+#: plugins/sudoers/logging.c:779
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "nie udało się wywołać %s: %m"
+
+#: plugins/sudoers/match.c:874
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "skrót dla %s (%s) nie jest w postaci %s"
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:421 plugins/sudoers/visudo.c:717
+#, c-format
+msgid "unable to stat %s"
+msgstr "nie udało się wykonać stat na %s"
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"Rola LDAP: %s\n"
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Wpis sudoers:\n"
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr " Jako użytkownicy: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr " Jako grupy: "
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr " Opcje: "
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr " Polecenia:\n"
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Pasujące wpisy Defaults dla %s na %s:\n"
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Wartości specyficzne dla Runas i Command dla %s:\n"
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Użytkownik %s może uruchamiać na %s następujące polecenia:\n"
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Użytkownik %s nie ma uprawnień do uruchamiania sudo na %s.\n"
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "zignorowano błędną wartość atrybutu: %s"
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "zignorowano niekompletne sudoRole: cn: %s"
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "błędna wartość %.*s ustawiona przez frontend sudo"
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr "nie udało się przeanalizować listy adresów sieciowych"
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr "nazwa użytkownika nie ustawiona przez frontend sudo"
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr "ID użytkownika nie ustawiony przez frontend sudo"
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr "ID grupy nie ustawiony przez frontend sudo"
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr "nazwa hosta nie ustawiona przez frontend sudo"
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:220
+#: plugins/sudoers/visudo.c:851
+#, c-format
+msgid "unable to execute %s"
+msgstr "nie udało się wywołać %s"
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Wersja wtyczki polityki sudoers %s\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Wersja gramatyki pliku sudoers %d\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Ścieżka do sudoers: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "ścieżka do nsswitch: %s\n"
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "ścieżka do ldap.conf: %s\n"
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "ścieżka do ldap.secret: %s\n"
+
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "nie udało się zarejestrować uchwytu typu %d (wersja %d.%d)"
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "nie udało się zapamiętać uid-a %u, brak pamięci"
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "nie udało się zapamiętać uid-a %u, już istnieje"
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "nie udało się zapamiętać użytkownika %s, brak pamięci"
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "nie udało się zapamiętać użytkownika %s, już istnieje"
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "nie udało się zapamiętać gid-a %u, brak pamięci"
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "nie udało się zapamiętać gid-a %u, już istnieje"
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "nie udało się zapamiętać grupy %s, brak pamięci"
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "nie udało się zapamiętać grupy %s, już istnieje"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "nie udało się zapamiętać listy grup dla %s, już istnieje"
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "nie udało się zapamiętać listy grup dla %s, brak pamięci"
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "nie udało się przeanalizować grup dla %s"
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "nie udało się przeanalizować gidów dla %s"
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr "przepełnienie stosu uprawnień"
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr "niedopełnienie stosu uprawnień"
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr "nie udało się zmienić na gid roota"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr "nie udało się zmienić na docelowy gid"
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr "nie udało się ustawić wektora grup docelowych"
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr "nie udało się zmienić na docelowy uid"
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr "nie udało się zmienić na gid sudoers"
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr "zbyt dużo procesów"
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr "nie udało się pobrać bieżącego katalogu roboczego"
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "ucięta ścieżka audytu user_cmnd: %s"
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "ucięta ścieżka audytu argv[0]: %s"
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr "komunikat audit_failure zbyt długi"
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "nie udało się zainicjować źródła SSS. Czy SSSD jest zainstalowany na tej maszynie?"
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "nie udało się odnaleźć symbolu \"%s\" w %s"
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr "problem z wpisami domyślnymi"
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr "nie znaleziono poprawnych źródeł sudoers, zakończenie"
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "wg sudoers root nie ma prawa używać sudo"
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr "brak uprawnień do używania opcji -C"
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "właściciel znacznika czasu (%s): nie ma takiego użytkownika"
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr "brak tty"
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr "niestety do uruchomienia sudo konieczny jest tty"
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr "polecenie w bieżącym katalogu"
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "niestety brak uprawnień do ustawienia limitu czasu polecenia"
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "niestety brak uprawnień do zachowania środowiska"
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr "polecenie zbyt długie"
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s nie jest zwykłym plikiem"
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "właścicielem %s jest uid %u, powinien być %u"
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr "%s jest zapisywalny dla świata"
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "właścicielem %s jest gid %u, powinien być %u"
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "tylko root może używać \"-c %s\""
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr "nieznana klasa logowania: %s"
+
+#: plugins/sudoers/sudoers.c:1069 plugins/sudoers/sudoers.c:1083
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "nie udało się rozwiązać nazwy hosta %s"
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "błędna opcja filtra: %s"
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "błędny maksymalny czas oczekiwania: %s"
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "błędny współczynnik szybkości: %s"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/czas: %s"
+
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/czas: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Odtwarzanie sesji sudo: %s"
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr "nie udało się dodać zdarzenia do kolejki"
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr "nie udało się przestawić tty w tryb surowy"
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Uwaga: ten terminal jest za mały, aby właściwie odtworzyć log.\n"
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Geometria logu to %d x %d, geometria terminala to %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Odtwarzanie zakończone, proszę nacisnąć dowolny klawisz, aby odzyskać terminal."
+
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "błędna linia pliku czasu: %s"
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "niejednoznaczne wyrażenie \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr "niesparowany ')' w wyrażeniu"
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "nieznany warunek wyszukiwania \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s wymaga argumentu"
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "błędne wyrażenie regularne: %s"
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "nie udało się przeanalizować daty \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr "niesparowany '(' w wyrażeniu"
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr "niedozwolone kończące \"or\""
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr "niedozwolony kończący \"!\""
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr "nieznany typ wyszukiwania %d"
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr "Składnia: %s [-hnRS] [-d katalog] [-m liczba] [-s wsp_szybkości] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "Składnia: %s [-h] [-d katalog] -l [wyrażenie wyszukiwania]\n"
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - odtwarzanie logów sesji sudo\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Opcje:\n"
+" -d, --directory=kat podanie katalogu na logi sesji\n"
+" -f, --filter=filtr określenie rodzaju we/wy do wyświetlania\n"
+" -h, --help wyświetlenie opisu i zakończenie\n"
+" -l, --list lista dostępnych ID sesji pasujących do wyrażenia\n"
+" -m, --max-wait=ile maksymalna liczba sekund oczekiwania między zdarzeniami\n"
+" -S, --suspend-wait oczekiwanie w czasie zawieszenia polecenia\n"
+" -s, --speed=ile przyspieszenie lub spowolnienie wyjścia\n"
+" -V, --version wyświetlenie informacji o wersji i zakończenie"
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr "\thost nie znaleziony"
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Polecenie dozwolone"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Polecenie niedozwolone"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Polecenie nie znalezione"
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr "%s jest zapisywalny dla groupy"
+
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "nie udało się uciąć pliku znacznika czasu do długości %lld"
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:482 plugins/sudoers/visudo.c:488
+msgid "unable to read the clock"
+msgstr "nie udało się odczytać zegara"
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr "znacznik czasu zbyt daleko w przyszłości"
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "znacznik czasu zbyt daleko w przyszłości: %20.20s"
+
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "nie udało się zablokować pliku znacznika czasu %s"
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "ścieżka stanu instrukcji zbyt długa: %s/%s"
+
+#: plugins/sudoers/visudo.c:216
+msgid "the -x option will be removed in a future release"
+msgstr "opcja -x będzie usunięta w kolejnej wersji"
+
+#: plugins/sudoers/visudo.c:217
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "należy rozważyć użycie zamiast niej narzędzia cvtsudoers"
+
+#: plugins/sudoers/visudo.c:268 plugins/sudoers/visudo.c:650
+#, c-format
+msgid "press return to edit %s: "
+msgstr "wciśnięcie return przejdzie do edycji %s: "
+
+#: plugins/sudoers/visudo.c:329
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "podany edytor (%s) nie istnieje"
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "nie znaleziono edytora (ścieżka = %s)"
+
+#: plugins/sudoers/visudo.c:441 plugins/sudoers/visudo.c:449
+msgid "write error"
+msgstr "błąd zapisu"
+
+#: plugins/sudoers/visudo.c:495
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "nie udało się wykonać stat na pliku tymczasowym (%s), %s nie zmieniony"
+
+#: plugins/sudoers/visudo.c:502
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "plik tymczasowy (%s) zerowej długości, %s nie zmieniony"
+
+#: plugins/sudoers/visudo.c:508
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "błąd edytora (%s), %s nie zmieniony"
+
+#: plugins/sudoers/visudo.c:530
+#, c-format
+msgid "%s unchanged"
+msgstr "%s nie zmieniony"
+
+#: plugins/sudoers/visudo.c:589
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "nie udało się ponownie otworzyć pliku tymczasowego (%s), %s nie zmieniony."
+
+#: plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "nie udało się przeanalizować pliku tymczasowego (%s), nieznany błąd"
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "błąd wewnętrzny, nie znaleziono %s na liście!"
+
+#: plugins/sudoers/visudo.c:719 plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "nie udało się ustawić (uid, gid) %s na (%u, %u)"
+
+#: plugins/sudoers/visudo.c:751
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s i %s nie są na tym samym systemie plików, użycie mv do zmiany nazwy"
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "polecenie nie powiodło się: '%s %s %s', %s nie zmieniony"
+
+#: plugins/sudoers/visudo.c:775
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "błąd podczas zmiany nazwy %s, %s nie zmieniony"
+
+#: plugins/sudoers/visudo.c:796
+msgid "What now? "
+msgstr "Co teraz? "
+
+#: plugins/sudoers/visudo.c:810
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Możliwe opcje:\n"
+" (e) ponowna edycja pliku sudoers\n"
+" (x) wyjście bez zapisu zmian do pliku sudoers\n"
+" (Q) wyjście i zapisanie zmian w pliku sudoers (NIEBEZPIECZNE!)\n"
+
+#: plugins/sudoers/visudo.c:856
+#, c-format
+msgid "unable to run %s"
+msgstr "nie udało się uruchomić %s"
+
+#: plugins/sudoers/visudo.c:886
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: błędny właściciel, (uid, gid) powinny wynosić (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: błędne uprawnienia, powinny być 0%o\n"
+
+#: plugins/sudoers/visudo.c:950 plugins/sudoers/visudo.c:957
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: składnia poprawna\n"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s zajęty, proszę spróbować później"
+
+#: plugins/sudoers/visudo.c:979
+#, c-format
+msgid "unable to lock %s"
+msgstr "nie udało się zablokować %s"
+
+#: plugins/sudoers/visudo.c:980
+msgid "Edit anyway? [y/N]"
+msgstr "Modyfikować mimo to? [y/N]"
+
+#: plugins/sudoers/visudo.c:1064
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Błąd: %s:%d: cykl w %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1065
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Uwaga: %s:%d: cykl w %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1069
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Błąd: %s:%d: %s \"%s\" użyty, ale nie zdefiniowany"
+
+#: plugins/sudoers/visudo.c:1070
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Uwaga: %s:%d: %s \"%s\" użyty, ale nie zdefiniowany"
+
+#: plugins/sudoers/visudo.c:1161
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Uwaga: %s:%d: nie użyty %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1276
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - bezpieczna edycja pliku sudoers\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1278
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"Opcje:\n"
+" -c, --check tryb wyłącznie sprawdzający\n"
+" -f, --file=sudoers określenie położenia pliku sudoers\n"
+" -h, --help wyświetlenie opisu i zakończenie\n"
+" -q, --quiet mniej obszerne komunikaty o błędach składni\n"
+" -s, --strict ścisłe sprawdzanie składni\n"
+" -V, --version wyświetlenie informacji o wersji i zakończenie\n"
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr "za dużo poziomów include"
diff --git a/plugins/sudoers/po/pt.mo b/plugins/sudoers/po/pt.mo
new file mode 100644
index 0000000..d79335a
--- /dev/null
+++ b/plugins/sudoers/po/pt.mo
Binary files differ
diff --git a/plugins/sudoers/po/pt.po b/plugins/sudoers/po/pt.po
new file mode 100644
index 0000000..ad9d397
--- /dev/null
+++ b/plugins/sudoers/po/pt.po
@@ -0,0 +1,2347 @@
+# Portuguese (Portugal) translation for the sudoers package.
+# Copyright (C) 2018 Free Software Foundation, Inc.
+# This file is distributed under the same license as the sudo package.
+# Todd C. Miller <Todd.Miller@sudo.ws>, 2011-2018
+# Pedro Albuquerque <palbuquerque73@gmail.com>, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-11-06 17:23+0000\n"
+"Last-Translator: Pedro Albuquerque <palbuquerque73@gmail.com>\n"
+"Language-Team: Portuguese <translation-team-pt@lists.sourceforge.net>\n"
+"Language: pt\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Gtranslator 2.91.7\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "erro de sintaxe"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "senha de %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] senha para %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Senha: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** Informação de SEGURANÇA para %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Enganou-se, tente de novo."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336
+#: gram.y:399 gram.y:407 gram.y:417 gram.y:450 gram.y:457 gram.y:464
+#: gram.y:471 gram.y:553 gram.y:560 gram.y:569 gram.y:578 gram.y:595
+#: gram.y:707 gram.y:714 gram.y:721 gram.y:729 gram.y:829 gram.y:836
+#: gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890 gram.y:897
+#: gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:195 plugins/sudoers/logging.c:511
+#: plugins/sudoers/logging.c:532 plugins/sudoers/logging.c:573
+#: plugins/sudoers/logging.c:752 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr "impossível alocar memória"
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr "um resumo requer um nome de caminho"
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr "valor notbefore inválido"
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr "valor notafter inválido"
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr "valor de inacção muito grande"
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr "valor de inacção inválido"
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:354 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:511 plugins/sudoers/logging.c:532
+#: plugins/sudoers/logging.c:572 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:724 plugins/sudoers/match.c:771
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1008
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Aliás \"%s\" já definido"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "impossível obter classe de sessão para o utilizador %s"
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr "impossível iniciar autenticação bsd"
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr "tipo de autenticação inválido"
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr "impossível inicializar autenticação BSD"
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr "a sua conta expirou"
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr "aprovação falhou"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr "impossível ler fwtk config"
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr "impossível ligar ao servidor de autenticação"
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr "ligação ao servidor de autenticação perdida"
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"erro no servidor de autenticação:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: impossível converter principal para cadeia (\"%s\"): %s"
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: impossível analisar \"%s\": %s"
+
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: impossível resolver cache de credenciais: %s"
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: impossível alocar opções: %s"
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: impossível obter credentiais: %s"
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: impossível inicializar a cache de credenciais: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: impossível armazenar a credencial em cache: %s"
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: impossível obter o principal do anfitrião: %s"
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Impossível verificar TGT! Possível ataque!: %s"
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr "impossível inicializar PAM"
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "erro de autenticação PAM: %s"
+
+#: plugins/sudoers/auth/pam.c:221
+msgid "account validation failure, is your account locked?"
+msgstr "falha na validação de conta, tem a conta trancada?"
+
+#: plugins/sudoers/auth/pam.c:229
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Conta ou senha expiradas, reponha a sua senha e tente novamente"
+
+#: plugins/sudoers/auth/pam.c:238
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "impossível alterar senha expirada: %s"
+
+#: plugins/sudoers/auth/pam.c:246
+msgid "Password expired, contact your system administrator"
+msgstr "Senha expirada, contacte o administrador do sistema"
+
+#: plugins/sudoers/auth/pam.c:250
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Conta expirada ou configuração PAM sem secção \"account\" para sudo, contacte o administrador do sistema"
+
+#: plugins/sudoers/auth/pam.c:257 plugins/sudoers/auth/pam.c:262
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "Erro de gestão de conta PAM: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:232
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "utilizador não existente na base de dados %s"
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr "falha ao inicializar a biblioteca ACE API"
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr "impossível contactar o servidor SecurID"
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr "ID de utilizador bloqueada para autenticação SecurID"
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr "tamanho de nome de utilizador inválido para SecurID"
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr "gestão de autenticação inválida para SecurID"
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr "falha na comunicação SecurID"
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr "erro SecurID desconhecido"
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr "tamanho de senha inválido para SecurID"
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr "impossível inicializar sessão SIA"
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr "métodos de autenticação inválidos"
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Métodos de autenticação inválidos compilados com sudo! Não pode misturar autenticação independente com outra."
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr "sem métodos de autenticação"
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Não há métodos de autenticação compilados com sudo! Se pretende desligar a autenticação. use a opção de configuração --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr "Impossível inicializar métodos de autenticaçao."
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr "Métodos de autenticação:"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr "Impossível determinar condição de auditoria"
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr "impossível submeter registo de auditoria"
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Acreditamos que recebeu a lição de moral do administrador de\n"
+"sistema local. Normalmente resume-se a estes três pontos:\n"
+"\n"
+" 1) respeite a privacidade dos outros;\n"
+" 2) pense antes de escrever;\n"
+" 3) lembre-se que com grande poder vem grande responsabilidade.\n"
+"\n"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr "uid desconhecida: %u"
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1136
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr "utilizador desconhecido: %s"
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "incremento de ordem: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "ordem inicial: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr "espaço de ordem: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s versão %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s versão gramatical %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr "formato de entrada %s não suportado"
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr "formato de saída %s não suportado"
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: os ficheiros de entrada e saída têm de ser diferentes"
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:238
+#: plugins/sudoers/visudo.c:594 plugins/sudoers/visudo.c:917
+msgid "unable to initialize sudoers default values"
+msgstr "impossível inicializar valores predefinidos de sudoers"
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: palavra-chave desconhecida: %s"
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "tipo de predefinições inválido: %s"
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "tipo de supressão inválido: %s"
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr "filtro inválido: %s"
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:913
+#, c-format
+msgid "unable to open %s"
+msgstr "impossível abrir %s"
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:922
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "falha ao analisar o ficheiro %s, erro desconhecido"
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:939
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "erro de análise em %s, perto da linha %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:942
+#, c-format
+msgid "parse error in %s\n"
+msgstr "erro de análise em %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr "impossível escrever em %s"
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s - converte entre formatos de ficheiros sudoers\n"
+"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Opções:\n"
+" -b, --base=dn o DN base para consultas sudo LDAP\n"
+" -d, --defaults=tipopred só converte predefinições do tipo especificado\n"
+" -e, --expand-alias expande aliás ao converter\n"
+" -f, --output-format=formato define o formato de saída: JSON, LDIF ou sudoers\n"
+" -i, --input-format=formato define o formato de entrada: LDIF ou sudoers\n"
+" -I, --increment=número valor a incrementar cada sudoOrder\n"
+" -h, --help mostra a ajuda e sai\n"
+" -m, --match=filtro só converte entradas que cumpram o filtro\n"
+" -M, --match-local filtro de comparação usa bases de dados de senha e grupo\n"
+" -o, --output=fich_saída escreve sudoers convertidos em fich_saída\n"
+" -O, --order-start=número ponto inicial para o primeiro sudoOrder\n"
+" -p, --prune-matches poda utilizadores, grupos e anfitriões não-correspondentes\n"
+" -P, --padding=num espaço base para incremento sudoOrder\n"
+" -s, --suppress=secções suprime saída de certas secções\n"
+" -V, --version mostra informação da versão e sai"
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "entrada de predefinições \"%s\" desconhecida"
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr "impossível obter hora GMT"
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr "impossível formatar datação"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1015 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "erro interno, transporte %s"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr "demasiadas entradas sudoers, máximo %u"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "a variável de ambiente SUDOERS_BASE não está definida e a opção -b não foi especificada."
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Facilidade syslog se syslog estiver a ser usado para início de sessão: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Prioridade syslog a usar quando o utilizador se autentica com sucesso: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Prioridade syslog a usar quando o utilizador não se autentica com sucesso: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "Põe o prompt OPT na sua própria linha"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "Ignora \".\" em $PATH"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "Envia sempre correio quando executa sudo"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "Envia correio se a autenticação do utilizador falhar"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "Envia correio se o utilizador não estiver em sudoers"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Envia correio se o utilizador não estiver em sudoers neste anfitrião"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Envia correio se o utilizador não puder executar um comando"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "Envia correio se o utilizador tentar executar um comando"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Usa uma datação separada para cada par utilizador/tty"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "Avisar o utilizador a primeira vez que executa sudo"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Ficheiro com a lição de moral sudo: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "Requer autenticação dos utilizadores por predefinição"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "Root pode executar sudo"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Regista o nome de anfitrião no diário (não-syslog)"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Regista o ano no diário (não-syslog)"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Se sudo for chamado sem argumentos, iniciar uma shel"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Definir $HOME para o utilizador alvo ao iniciar uma shell com -s"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Definir $HOME sempre como a pasta home do utilizador alvo"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Permite a recolha de alguma informação para dar mensagens de erro úteis"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Requer nomes de anfitrião completamente qualificados no ficheiro sudoers"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Insulta o utilizador quando se engana na senha"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Permitir ao utilizador a execução de sudo só se tiver tty"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo honra a variável de ambiente EDITOR"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "Pedir senha root, não a do utilizador"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Pedir a senha de utilizador runas_default, não a do utilizador"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Pedir a senha do utilizador alvo, não a do utilizador"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Aplica predefinições à classe de sessão do utilizador alvo, se existir"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Define as variáveis de ambiente LOGNAME e USER"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Definir a uid efectiva só para o utilizador alvo, não a uid real"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Não inicializar o vector de grupo para o do utilizador alvo"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Tamanho máximo de linhas longas do diário (0 para não quebrar): %u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Expiração da datação de autenticação: %.1f minutos"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Expiração do pedido de senha: %.1f minutos"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Número de tentativas de inserção de senha: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Umask a usar ou 0777 para usar a do utilizador: 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Caminho para o ficheiro de diário: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Caminho para o programa de correio: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Bandeiras para o programa de correio: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Endereço para onde enviar o correio: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Endereço de onde enviar o correio: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Linha de assunto para as mensagens: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Mensagem de senha incorrecta: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Caminho para a pasta de estado da lição de moral: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Caminho para a pasta de datação de autenticação: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Dono da pasta de datação de autenticação: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Utilizadores deste grupo estão dispensados de usar senhas e necessidades de PATH: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Pedido de senha predefinido: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Se definido, o pedido de senha sobrepõe-se ao prompt do sistema em qualquer caso."
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Utilizador predefinido para executar comandos: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Valor a sobrepor a $PATH: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Caminho para o editor a usar com visudo: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Quando pedir uma senha para o pseudo-comando \"list\": %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Quando pedir uma senha para o pseudo-comando \"verify\": %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Pré-carregar as funções dummy exec contidas na biblioteca sudo_noexec"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Se a pasta LDAP está em cima, ignoramos o ficheiro sudoers"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Descritores de ficheiro >= %d será fechado antes de executar um comando"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Se definido, os utilizadores podem sobrepor o valor de \"closefrom\" com a opção -C"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Permite aos utilizadores definir variáveis de ambiente arbitrárias"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "Repor o ambiente num conjunto predefinido de variáveis"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "Variáveis de ambiente para verificar a sanidade:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "Variáveis de ambiente para remover:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "Variáveis de ambiente para preservar:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Papel SELinux a usar no novo contexto de segurança: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Tipo SELinux a usar no novo contexto de segurança: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Caminho para o ficheiro de ambiente específico do sudo: %s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Caminho para o ficheiro restrito de ambiente específico do sudo: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Idioma a usar ao analisar sudoers: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Permite ao sudo pedir uma senha mesmo que fique visível"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Fornece resposta visual no pedido de senha quando há entrada do utilizador"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Usa globbing mais rápido e menos preciso, mas não acede ao sistema de ficheiros"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "A umask especificada no sudoers sobrepõe-se à do utilizador, mesmo que seja mais permissiva"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "Regista as entradas do utilizador para o comando em execução"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "Regista a saída do comando em execução"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "Comprime diários de E/S com zlib"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "Executa sempre os comandos num pseudo-tty"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Extensão para suporte de grupo não-Unix: %s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Pasta onde armazenar os diários de entrada/saída: %s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Ficheiro onde armazenar o diário de entrada/saída: %s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Adiciona uma entrada ao ficheiro utmp/utmpx ao alocar um pty"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Define o utilizador em utmp como utilizador runas mestre, não como utilizador chamador"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Conjunto de privilégios permitidos: %s"
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Conjunto de privilégios limite: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "Executa comandos num pty em 2º plano"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "Nome de serviço PAM a usar: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "Nome de serviço PAM a usar para shells de sessão: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Tenta estabelecer credenciais PAM para o utilizador alvo"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "Cria uma nova sessão PAM onde o comando será executado"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Número de sequência máximo do diário de E/S: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "Activa o suporte a sudoers netgroup"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Verifica se as pastas-mãe se podem escrever ao editar ficheiros com sudoedit"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Segue ligações simbólicas ao editar ficheiros com sudoedit"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "Consulta a extensão de grupo para grupos de sistema desconhecidos"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Compara netgroups baseado em todo o conjunto: utilizador, anfitrião e domínio"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Permite executar comandos mesmo que o sudo não possa escrever no diário de auditoria"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Permite executar comandos mesmo que o sudo não possa escrever no diário de E/S"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Permite executar comandos mesmo que o sudo não possa escrever no diário"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Resolve grupos no sudoers e compara a ID de grupo, não o nome"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Entradas de diário maiores que este valor serão divididas em múltiplas mensagens de syslog: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Utilizador que será dono dos ficheiros de E/S: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Grupo que será dono dos ficheiros de E/S: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Modo de ficheiro a usar para os ficheiros de E/S: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Executa comandos por descritor de ficheiro em vez de por caminho: %s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Ignora entradas Defaults desconhecidas no sudoers, em vez de produzir um aviso"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Tempo em segundos após o qual cada comando será terminado: %u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Permite ao utilizador especificar um tempo de inacção na linha de comandos"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Despejar dados de E/S para o disco imediatamente, em vez de usar um buffer"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "Incluir a ID de processo ao registar via syslog"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Tipo de registo de datação de autenticação: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "Mensagem de falha na autenticação: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "Ignorar maiúsculas ao comparar nomes de utilizadores"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "Ignorar maiúsculas ao comparar nomes de grupos"
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d entrada defaults desconhecida \"%s\""
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s entrada defaults desconhecida \"%s\""
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d sem valor especificado para \"%s\""
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s sem valor especificado para \"%s\""
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d valores para \"%s\" têm de começar com \"/\""
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s valores para \"%s\" têm de começar com \"/\""
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d opção \"%s\" não recebe valores"
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s opção \"%s\" não recebe valores"
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d tipo Defaults 0x%x inválido para a opção \"%s\""
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s tipo Defaults 0x%x inválido para a opção \"%s\""
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d valor \"%s\" é inválido para a opção \"%s\""
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s valor \"%s\" é inválido para a opção \"%s\""
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: envp corrompido, tamanho trocado"
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr "impossível reconstruir o ambiente"
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "desculpe, não tem permissão para definir as seguintes variáveis de ambiente: %s"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "erro de análise em %s perto da linha %d"
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "erro de análise em %s"
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "tipo de resumo %d não suportado para %s"
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr "%s: erro de leitura"
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s tem de ser propriedade de uid %d"
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s só pode ter permissão de escrita para o dono"
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "impossível carregar %s: %s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "impossível encontrar o símbolo \"group_plugin\" em %s"
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: versão principal de extensão de grupo %d incompatível, esperada %d"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "impossível analisar endereço IP \"%s\""
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "impossível analisar netmask \"%s\""
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Pares endereço IP local e netmask:\n"
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s existe mas não é uma pasta (0%o)"
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "impossível criar pasta %s"
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:723
+#: plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "impossível alterar o modo de %s para 0%o"
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1167
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr "grupo desconhecido: %s"
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr "impossível ler %s"
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr "impossível criar %s"
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "impossível escrever no ficheiro de E/S: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr "%s: erro interno, ficheiro de diário E/S do evento %d não aberto"
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr "%s: erro interno, sinal inválido %d"
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: ficheiro de diário inválido"
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: campo de datação em falta"
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: datação %s: %s"
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: campo de utilizador em falta"
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: campo de utilizador runas em falta"
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: campo de grupo runas em falta"
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr "starttls não suportado quando usa ldaps"
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "impossível inicializar certificado SSL e db de chave: %s"
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "tem de definir TLS_CERT em %s para usar SSL"
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "impossível inicializar LDAP: %s"
+
+#: plugins/sudoers/ldap.c:1648
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls especificado mas LDAP libs não suporta ldap_start_tls_s() ou ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "atributo sudoOrder inválido: %s"
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: porta muito grande"
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "tipo de uri LDAP não suportado: %s"
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "impossível misturar URIs ldap e ldaps"
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "impossível converter sudoOption: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "impossível abrir o sistema de auditoria"
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr "impossível enviar mensagem de auditoria"
+
+#: plugins/sudoers/logging.c:113
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:141
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (comando continuado) %s"
+
+#: plugins/sudoers/logging.c:170
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "impossível abrir o diário: %s"
+
+#: plugins/sudoers/logging.c:178
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "impossível bloquear o diário: %s"
+
+#: plugins/sudoers/logging.c:211
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "impossível escrever o diário: %s"
+
+#: plugins/sudoers/logging.c:240
+msgid "No user or host"
+msgstr "Sem utilizador ou anfitrião"
+
+#: plugins/sudoers/logging.c:242
+msgid "validation failure"
+msgstr "falha de validação"
+
+#: plugins/sudoers/logging.c:249
+msgid "user NOT in sudoers"
+msgstr "utilizador NÃO está no sudores"
+
+#: plugins/sudoers/logging.c:251
+msgid "user NOT authorized on host"
+msgstr "utilizador NÃO autorizado no anfitrião"
+
+#: plugins/sudoers/logging.c:253
+msgid "command not allowed"
+msgstr "comando não permitido"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s não está no ficheiro sudoers. O incidente será reportado.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s não tem permissão para executar sudo em %s. O incidente será reportado.\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Desculpe, %s não pode executar sudo em %s.\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Desculpe, %s não tem permissão para executar \"%s%s%s\" como %s%s%s em %s.\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: comando não encontrado"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"a ignorar \"%s\" encontrado em \".\"\n"
+"Use \"sudo ./%s\" se este é o \"%s\" que deseja executar."
+
+#: plugins/sudoers/logging.c:354
+msgid "authentication failure"
+msgstr "falha de autenticação"
+
+#: plugins/sudoers/logging.c:380
+msgid "a password is required"
+msgstr "é necessária uma senha"
+
+#: plugins/sudoers/logging.c:443
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u tentativa incorrecta"
+msgstr[1] "%u tentativas incorrectas"
+
+#: plugins/sudoers/logging.c:666
+msgid "unable to fork"
+msgstr "impossível bifurcar"
+
+#: plugins/sudoers/logging.c:674 plugins/sudoers/logging.c:726
+#, c-format
+msgid "unable to fork: %m"
+msgstr "impossível bifurcar: %m"
+
+#: plugins/sudoers/logging.c:716
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "impossível abrir túnel: %m"
+
+#: plugins/sudoers/logging.c:741
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "impossível duplicar stdin: %m"
+
+#: plugins/sudoers/logging.c:779
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "impossível executar %s: %m"
+
+#: plugins/sudoers/match.c:874
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "resumo para %s (%s) não está na forma %s"
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:421 plugins/sudoers/visudo.c:717
+#, c-format
+msgid "unable to stat %s"
+msgstr "impossível obter informações de %s"
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"Papel LDAP: %s\n"
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Entrada sudoers:\n"
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr " RunAsUsers: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr " RunAsGroups: "
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr " Opções: "
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr " Comandos:\n"
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Entradas Defaults correspondentes para %s em %s:\n"
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Predefinições Runas específicas de comandos para %s:\n"
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "O utilizador %s pode executar os seguintes comandos em %s:\n"
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "O utilizador %s não tem permissão para executar sudo em %s.\n"
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "a ignorar valor de atributo inválido: %s"
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "a ignorar sudoRole incompleto: cn: %s"
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "%.*s inválido definido pelo front-end do sudo"
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr "impossível analisar a lista de endereços da rede"
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr "nome de utilizador não definido pelo front-end do sudo"
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr "ID de utilizador não definida pelo front-end do sudo"
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr "ID de grupo não definida pelo front-end do sudo"
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr "Nome de anfitrião não definido pelo front-end do sudo"
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:220
+#: plugins/sudoers/visudo.c:851
+#, c-format
+msgid "unable to execute %s"
+msgstr "impossível executar %s"
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Extensão de política sudoers versão %s\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Gramática do ficheiro sudoers versão %d\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Caminho do sudoers: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "caminho nsswitch: %s\n"
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "caminho do ldap.conf: %s\n"
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "caminho do ldap.secret: %s\n"
+
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "impossível registar hook do tipo %d (versão %d.%d)"
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "impossível guardar uid %u, sem memória"
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "impossível guardar uid %u, já existe"
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "impossível guardar utilizador %s, sem memória"
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "impossível guardar utilizador %s, já existe"
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "impossível guardar gid %u, sem memória"
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "impossível guardar gid %u, já existe"
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "impossível guardar grupo %s, sem memória"
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "impossível guardar grupo %s, já existe"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "impossível guardar lista de grupo para %s, já existe"
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "impossível guardar lista de grupo para %s, sem memória"
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "impossível analisar grupos para %s"
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "impossível analisar gids para %s"
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr "transporte de pilha perm"
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr "importe de pilha perm"
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr "impossível mudar para gid root"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr "impossível mudar para gid runas"
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr "impossível definir vector de grupo runas"
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr "impossível mudar para uid runas"
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr "impossível mudar para gid sudoers"
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr "demasiados processos"
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr "impossível obter a pasta de trabalho actual"
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "caminho de auditoria truncado user_cmnd: %s"
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "caminho de auditoria truncado argv[0]: %s"
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr "mensagem audit_failure muito longa"
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "impossível inicializar fonte SSS. Tem o SSSD instalado?"
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "impossível encontrar símbolo \"%s\" em %s"
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr "problema com entradas defaults"
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr "sme fontes sudoers válidas, a sair"
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers especifica que root não tem permissão para sudo"
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr "não tem permissão para usar a opção -C"
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "dono da datação (%s): utilizador inexistente"
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr "sem tty"
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr "desculpe, tem de ter um tty para executar sudo"
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr "comando na pasta actual"
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "desculpe, não tem permissão para definir um tempo de inacção"
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "desculpe, não tem permissão para preservar o ambiente"
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr "comando muito longo"
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s não é um ficheiro normal"
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s é propriedade de uid %u, deveria ser %u"
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr "%s é escrito universalmente"
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s é propriedade de gid %u, deveria ser %u"
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "só root pode usar \"-c %s\""
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr "classe de sessão desconhecida: %s"
+
+#: plugins/sudoers/sudoers.c:1069 plugins/sudoers/sudoers.c:1083
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "impossível resolver o anfitrião %s"
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "opção de filtro inválida: %s"
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "espera máxima inválida: %s"
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "factor de velocidade inválido: %s"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/temporização: %s"
+
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/temporização: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "A reproduzir sessão sudo: %s"
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr "impossível adicionar evento à fila"
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr "impossível definir tty para modo raw"
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Aviso: o seu terminal é muito pequeno para reproduzir correctamente o diário.\n"
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "A geometria do diário é %d x %d, o seu terminal é %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Reprodução terminada, prima qualquer tecla para restaurar o terminal."
+
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "linha de ficheiro de temporização inválida : %s"
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "expressão ambígua \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr "\")\" sem par em expressão"
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "termo de procura \"%s\" desconhecido"
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s requer um argumento"
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "expressão regular inválida: %s"
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "impossível analisar a data \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr "\"(\" sem par em expressão"
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr "\"or\" final ilegal"
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr "\"!\" final ilegal"
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr "tipo de procura %d desconhecido"
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr "uso: %s [-hnRS] [-d pasta] [-m núm] [-s núm] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "uso: %s [-h] [-d pasta] -l [expressão de procura]\n"
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - reproduz os diários de sessão sudo\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Opções:\n"
+" -d, --directory=pasta especifica a pasta para diários de sessão\n"
+" -f, --filter=filtro especifica os tipos de E/S a mostrar\n"
+" -h, --help mostra a ajuda e sai\n"
+" -l, --list lista as IDs de sessão disponíveis, com expressão opcional\n"
+" -m, --max-wait=número número máximo de segundos a aguardar entre eventos\n"
+" -S, --suspend-wait espera enquanto o comando foi suspenso\n"
+" -s, --speed=número acelera ou trava a saída\n"
+" -V, --version mostra informação da versão e sai"
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr "\thost sem correspondência"
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Comando permitido"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Comando negado"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Comando sem correspondência"
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr "%s é escrito pelo grupo"
+
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "impossível truncar o ficheiro de datação para %lld bytes"
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:482 plugins/sudoers/visudo.c:488
+msgid "unable to read the clock"
+msgstr "impossível ler o relógio"
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr "a ignorar datação do futuro"
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "datação demasiado no futuro: %20.20s"
+
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "impossível bloquear ficheiro de datação %s"
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "caminho do estado da lição de moral muito longo: %s/%s"
+
+#: plugins/sudoers/visudo.c:216
+msgid "the -x option will be removed in a future release"
+msgstr "a opção -x será removida numa futura versão"
+
+#: plugins/sudoers/visudo.c:217
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "por favor, considere usar antes o utilitário cvtsudoers"
+
+#: plugins/sudoers/visudo.c:268 plugins/sudoers/visudo.c:650
+#, c-format
+msgid "press return to edit %s: "
+msgstr "prima Enter para editar %s: "
+
+#: plugins/sudoers/visudo.c:329
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "o editor especificado (%s) não existe"
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "sem editor (caminho do editor = %s)"
+
+#: plugins/sudoers/visudo.c:441 plugins/sudoers/visudo.c:449
+msgid "write error"
+msgstr "erro de escrita"
+
+#: plugins/sudoers/visudo.c:495
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "impossível obter informação do ficheiro temporário (%s), %s inalterado"
+
+#: plugins/sudoers/visudo.c:502
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "ficheiro temporário de tamanho zero (%s), %s inalterado"
+
+#: plugins/sudoers/visudo.c:508
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "falha no editor (%s), %s inalterado"
+
+#: plugins/sudoers/visudo.c:530
+#, c-format
+msgid "%s unchanged"
+msgstr "%s inalterado"
+
+#: plugins/sudoers/visudo.c:589
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "impossível reabrir o ficheiro temporário (%s), %s inalterado."
+
+#: plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "impossível analisar o ficheiro temporário (%s), erro desconhecido"
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "erro interno, impossível encontrar %s na lista!"
+
+#: plugins/sudoers/visudo.c:719 plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "impossível definir (uid, gid) de %s para (%u, %u)"
+
+#: plugins/sudoers/visudo.c:751
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s e %s em sistemas de ficheiros diferentes, a usar mv para renomear"
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "falha no comando: \"%s %s %s\", %s inalterado"
+
+#: plugins/sudoers/visudo.c:775
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "erro ao renomear %s, %s inalterado"
+
+#: plugins/sudoers/visudo.c:796
+msgid "What now? "
+msgstr "E agora?"
+
+#: plugins/sudoers/visudo.c:810
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"As opções são:\n"
+" (e) editar o ficheiro sudoers de novo\n"
+" (x) sair sem gravar as alterações ao ficheiro sudoers\n"
+" (Q) sair e gravar as alterações ao ficheiro sudoers (PERIGO!)\n"
+
+#: plugins/sudoers/visudo.c:856
+#, c-format
+msgid "unable to run %s"
+msgstr "impossível executar %s"
+
+#: plugins/sudoers/visudo.c:886
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: dono errrado (uid, gid), deveria ser (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: permissões erradas, devia ser modo 0%o\n"
+
+#: plugins/sudoers/visudo.c:950 plugins/sudoers/visudo.c:957
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: análise com sucesso\n"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s ocupado, tente mais tarde"
+
+#: plugins/sudoers/visudo.c:979
+#, c-format
+msgid "unable to lock %s"
+msgstr "impossível bloquear %s"
+
+#: plugins/sudoers/visudo.c:980
+msgid "Edit anyway? [y/N]"
+msgstr "Editar mesmo assim ? [y/N]"
+
+#: plugins/sudoers/visudo.c:1064
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Erro: %s:%d ciclo em %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1065
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Aviso: %s:%d ciclo em %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1069
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Erro: %s:%d %s \"%s\" referenciado mas não definido"
+
+#: plugins/sudoers/visudo.c:1070
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Aviso: %s:%d %s \"%s\" referenciado mas não definido"
+
+#: plugins/sudoers/visudo.c:1161
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Aviso: %s:%d não usado %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1276
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - editar com segurança o ficheiro sudoers\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1278
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"Opções:\n"
+" -c, --check modo só de verificação\n"
+" -f, --file=sudoers especifica a localização do ficheiro sudoers\n"
+" -h, --help mostra a ajuda e sai\n"
+" -q, --quiet mensagens de erro de sintaxe menos verbosas (silêncio)\n"
+" -s, --strict verificação de sintaxe estrita\n"
+" -V, --version mostra informação da versão e sai\n"
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr "demasiados níveis de includes"
diff --git a/plugins/sudoers/po/pt_BR.mo b/plugins/sudoers/po/pt_BR.mo
new file mode 100644
index 0000000..82df1ff
--- /dev/null
+++ b/plugins/sudoers/po/pt_BR.mo
Binary files differ
diff --git a/plugins/sudoers/po/pt_BR.po b/plugins/sudoers/po/pt_BR.po
new file mode 100644
index 0000000..6872879
--- /dev/null
+++ b/plugins/sudoers/po/pt_BR.po
@@ -0,0 +1,2485 @@
+# Brazilian Portuguese translation of sudoers.
+# Traduções em português brasileiro para o pacote sudoers
+# Copyright (C) 2018 Free Software Foundation, Inc.
+# This file is distributed under the same license as the sudo package.
+# Rafael Fontenelle <rafaelff@gnome.org>, 2013-2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-29 16:20-0200\n"
+"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
+"Language-Team: Brazilian Portuguese <ldpbr-translation@lists.sourceforge.net>\n"
+"Language: pt_BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Generator: Virtaal 1.0.0-beta1\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "erro de sintaxe"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "senha do %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] senha para %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Senha: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** Informação de SEGURANÇA para %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Sinto muito, tente novamente."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336
+#: gram.y:399 gram.y:407 gram.y:417 gram.y:450 gram.y:457 gram.y:464
+#: gram.y:471 gram.y:553 gram.y:560 gram.y:569 gram.y:578 gram.y:595
+#: gram.y:707 gram.y:714 gram.y:721 gram.y:729 gram.y:829 gram.y:836
+#: gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890 gram.y:897
+#: gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:195 plugins/sudoers/logging.c:511
+#: plugins/sudoers/logging.c:532 plugins/sudoers/logging.c:573
+#: plugins/sudoers/logging.c:752 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr "não foi possível alocar memória"
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr "um digest requer um nome de caminho"
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr "valor de notbefore inválido"
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr "falha de notafter inválido"
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr "valor de timeout grande demais"
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr "valor de timeout inválido"
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:354 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:511 plugins/sudoers/logging.c:532
+#: plugins/sudoers/logging.c:572 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:724 plugins/sudoers/match.c:771
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1008
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Alias \"%s\" já definido"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "não foi possível obter classe de login para o usuário %s"
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr "não foi possível iniciar autenticação BSD"
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr "tipo de autenticação inválida"
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr "não foi possível inicializar autenticação BSD"
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr "sua conta expirou"
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr "aprovação falhou"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr "não foi possível ler configuração de fwtk"
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr "não foi possível conectar ao servidor de autenticação"
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr "conexão perdida com o servidor de autenticação"
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"erro no servidor de autenticação:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: não foi possível converter principal para string (\"%s\"): %s"
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: não foi possível analisar \"%s\": %s"
+
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: não foi possível resolver cache de credenciais: %s"
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: não foi possível alocar opções: %s"
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: não foi possível obter credenciais: %s"
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: não foi possível inicializar cache de credenciais: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: não foi possível armazenar credenciais no cache: %s"
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: não foi possível obter principal da máquina: %s"
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Não foi possível verificar TGT! Possivelmente um ataque!: %s"
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr "não foi possível inicializar PAM"
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Erro de autenticação PAM: %s"
+
+#: plugins/sudoers/auth/pam.c:221
+msgid "account validation failure, is your account locked?"
+msgstr "falha de verificação da conta; sua conta está travada?"
+
+#: plugins/sudoers/auth/pam.c:229
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Conta ou senha expirou; redefina sua senha e tente novamente"
+
+#: plugins/sudoers/auth/pam.c:238
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "não foi possível alterar a senha expirada: %s"
+
+#: plugins/sudoers/auth/pam.c:246
+msgid "Password expired, contact your system administrator"
+msgstr "Senha expirou; entre em contato com o administrador do seu sistema"
+
+#: plugins/sudoers/auth/pam.c:250
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Conta expirou ou a configuração do PAM não possui uma seção \"account\" para sudo; contate o administrador do seu sistema"
+
+#: plugins/sudoers/auth/pam.c:257 plugins/sudoers/auth/pam.c:262
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "erro de gerenciamento de conta PAM: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:232
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "você não existe no banco de dados de %s"
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr "falha ao inicializar a biblioteca API ACE"
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr "não foi possível contatar o servidor de SecurID"
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr "ID de usuário travado pela autenticação SecurID"
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr "comprimento de nome de usuário inválido para SecurID"
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr "manipulação inválida de autenticação para SecurID"
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr "falha de comunicação de SecurID"
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr "erro de SecurID desconhecido"
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr "comprimento de senha inválida para SecurID"
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr "não foi possível inicializar a sessão SIA"
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr "métodos de autenticação inválidos"
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Métodos de autenticação inválidos compilado no sudo! Você não pode misturar autenticação autônoma com não-autônoma."
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr "nenhum método de autenticação"
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Não há métodos de autenticação compilados no sudo! Se você quiser desligar a autenticação, use a opção de configuração --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr "Não foi possível inicializar métodos de autenticação."
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr "Métodos de autenticação:"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr "Não foi possível determinar a condição de auditoria"
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr "não foi possível enviar o registro de auditoria"
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Presumimos que você recebeu as instruções de sempre do administrador\n"
+"de sistema local. Basicamente, resume-se a estas três coisas:\n"
+"\n"
+" #1) Respeite a privacidade dos outros.\n"
+" #2) Pense antes de digitar.\n"
+" #3) Com grandes poderes vêm grandes responsabilidades.\n"
+"\n"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr "uid desconhecido: %u"
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1136
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr "usuário desconhecido: %s"
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "incremento de ordem: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "ordem inicial: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr "preenchimento de ordem: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s versão %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "gramática de %s versão %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr "formato de entrada sem suporte %s"
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr "formato de saída sem suporte %s"
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: arquivos de entrada e saída devem ser diferentes"
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:238
+#: plugins/sudoers/visudo.c:594 plugins/sudoers/visudo.c:917
+msgid "unable to initialize sudoers default values"
+msgstr "não foi possível inicializar valores padrões do sudoers"
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: palavra-chave desconhecida: %s"
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "tipo de defaults inválido: %s"
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "tipo de supressão inválida: %s"
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr "filtro inválido: %s"
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:913
+#, c-format
+msgid "unable to open %s"
+msgstr "não foi possível abrir %s"
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:922
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "falha em analisar o arquivo %s, erro desconhecido"
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:939
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "erro de análise em %s perto da linha %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:942
+#, c-format
+msgid "parse error in %s\n"
+msgstr "erro de análise em \"%s\"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr "não foi possível gravar em %s"
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s - converte entre formatos de arquivo sudoers\n"
+"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Opções:\n"
+" -b, --base=dn o DN base para consultas LDAP do sudo\n"
+" -d, --defaults=tiposdeft só converte Defaults dos tipos especificados\n"
+" -e, --expand-aliases expande aliases ao converter\n"
+" -f, --output-format=formato define formato de saída: JSON, LDIF ou sudoers\n"
+" -i, --input-format=formato define formato de entrada: LDIF ou sudoers\n"
+" -I, --increment=núm quantidade para incrementar cada sudoOrder por\n"
+" -h, --help exibe a mensagem de ajuda e sai\n"
+" -m, --match=filtro só converte entradas que corresponde ao filtro\n"
+" -M, --match-local filtro de correspondência usa bancos de dados\n"
+" passwd e group\n"
+" -o, --output=arquivo_saída escreve sudoers convertido para arquivo_saída\n"
+" -O, --order-start=núm ponto inicial para o primeiro sudoOrder\n"
+" -p, --prune-matches suprime usuários/grupos/hosts não correspondentes\n"
+" -P, --padding=núm preenchimento base para incremento de sudoOrder\n"
+" -s, --suppress=seções suprime a saída de certas seções\n"
+" -V, --version exibe informações de versão e sai"
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "entrada padrão \"%s\" desconhecido"
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr "não foi possível obter o horário GMT"
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr "não é possível formatar marca de tempo"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1015 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "erro interno, estouro de pilha de %s"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr "entradas de sudoers demais, máximo %u"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "a variável de ambiente SUDOERS_BASE não está definida e a opção -b não foi especificada."
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Facilidade do syslog, se syslog estiver sendo usado para registrar logs: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Prioridade do syslog para usar quando um usuário autenticar com sucesso: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Prioridade do syslog para usar quando um usuário não usuário autenticar com sucesso: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "Colocar prompt OTP na sua própria linha"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "Ignorar \".\" no $PATH"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "Sempre envia correio quando sudo for executado"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "Envia correio se a autenticação de um usuário falhar"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "Envia correio se o usuário não estiver no sudoers"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Envia correio se o usuário não estiver no sudoers desta máquina"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Envia correio se o usuário não tiver permissão para executar um comando"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "Envia correio se o usuário tentar executar um comando"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Usa uma marca de tempo separada para cada combo usuário/tty"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "Instrui o usuário na primeira vez que ele executar sudo"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Arquivo contendo as instruções do sudo: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "Exige que os usuários se autentiquem, por padrão"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "Root pode executar sudo"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Registra o nome da máquina no arquivo de log (não-syslog)"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Registra o ano no arquivo de log (não-syslog)"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Se sudo for chamado sem argumentos, inicia um shell"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Define $HOME com o usuário alvo ao iniciar um shell com -s"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Sempre define $HOME para a pasta pessoal do usuário alvo"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Permite juntar algumas informações para fornecer mensagens de erro úteis"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Exige nomes de máquina completos (FQDN) no arquivo sudoers"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Insulta o usuário quando ele digitar uma senha incorreta"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Permite que o usuário execute sudo apenas se ele tiver um tty"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo vai honrar a variável de ambiente EDITOR"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "Pede a senha do root, e não a do usuário"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Pede a senha do usuário runas_default, e não a do usuário"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Pede a senha do usuário alvo, e não a do usuário"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Aplica o padrão na classe de login do usuário alvo, se houver alguma"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Define as variáveis de ambiente LOGNAME e USER"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Define o uid efetivo apenas para o usuário alvo, e não o uid real"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Não inicializa o vetor de grupos para aquele usuário alvo"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Comprimento da quebra de linha do arquivo de log (0 para sem quebra): %u"
+
+# "Limite de tempo da marca de tempo de autenticação" ficaria estranho, então utilizei "... expira em"
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Marca de tempo de autenticação expira em: %.1f minutos"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Pedido de senha expira em: %.1f minutos"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Número de tentativas para digitar senha: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Umask a ser usada ou 0777 para usar do usuário: 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Caminho para o arquivo de log: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Caminho para o programa de correio: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Opções para o programa de correio: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Endereço para onde enviar correio: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Endereço de onde enviar correio: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Linha do assunto para as mensagens de correio: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Mensagem de senha incorreta: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Caminho para o diretório de status de instruções: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Caminho para diretório de marca de tempo de autenticação: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Dono do diretório de marca de tempo de autenticação: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Usuários neste grupo estão eximidos da exigência de senha e PATH: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Pedido de senha padrão: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Se definido, o pedido de senha vai sobrescrever o do sistema em todos os casos."
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Usuário padrão para se executar comandos: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Valor para sobrescrever o $PATH do usuário: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Caminho do editor a ser usado pelo visudo: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Quando exigir uma senha para o pseudo-comando \"list\": %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Quando exigir uma senha para o pseudo-comando \"verify\": %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Pré-carrega as funções de exec de teste contidas na biblioteca sudo_noexec"
+
+# ideia da frase original: se acontecer algo, se deve ou não ignorar. Traduzi reorganizando a frase com a finalidade de manter a ideia original. -- Rafael
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Estando o diretório LDAP disponível, se devemos ignorar o arquivo sudoers local"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Descritores, de arquivos, >= %d serão fechados antes de executar um comando"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Se definido, usuários podem sobrescrever o valor de \"closefrom\" com a opção -C"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Permite que usuários definam variáveis de ambiente arbitrárias"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "Redefine o ambiente para um conjunto padrão de variáveis"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "Variáveis de ambiente nas quais deve-se verificar sanidade:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "Variáveis de ambiente para remover:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "Variáveis de ambiente para preservar:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Papel SELinux para usar no novo contexto de segurança: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Tipo SELinux para usar no novo contexto de segurança: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Caminho do arquivo de ambiente específico do sudo: %s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Caminho do arquivo restrito de ambiente específico do sudo: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Localização para usar ao analisar o sudoers: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Permite ao sudo solicitar uma senha mesmo se ele estiver visível"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Fornece feedback visual na solicitação de senha quando houver entrada do usuário"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Usa um englobamento mais rápido que é menos preciso, mas não acessa o sistema de arquivos"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "O umask especificado no sudoers vai sobrescrever o do usuário, mesmo se ele foi mais permissivo"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "Registra no log a entrada do usuário para o comando sendo executado"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "Registra no log a saída do comando sendo executado"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "Comprime logs I/O usando zlib"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "Sempre executa comandos em um pseudo-tty"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Plug-in para suporte a grupo não-Unix: %s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Diretório no qual devem ser armazenados os logs de entrada/saída: %s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Arquivo no qual deve ser armazenado o log de entrada/saída: %s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Adiciona uma entrada ao arquivo utmp/utmpx ao alocar um pty"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Define o usuário em utmp como usuário a ser executado como, e não o usuário a ser chamado"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Conjunto de privilégios permitidos: %s"
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Conjunto de privilégios limitados: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "Executa comandos em um pty em plano de fundo"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "Nome do serviço PAM para usar: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "Nome do serviço PAM para usar para shells de login: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Tenta estabelecer as credenciais PAM para o usuário alvo"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "Cria uma nova sessão PAM para o comando ser executado nela"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Número máximo de sequência de log de E/S: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "Habilita suporte a netgroup no sudoers"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Verifica diretórios pai para capacidade de gravação ao editar arquivos com sudoedit"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Segue links simbólicos ao editar arquivos com sudoedit"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "Consulta o plug-in de grupo por grupos de sistema desconhecidos"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Compara netgroups baseada em toda tupla: usuário, máquina e domínio"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Permite comandos serem executados mesmo se sudo não puder escrever em logs de auditoria"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Permite comandos serem executados mesmo se sudo não puder escrever em logs de E/S"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Permite comandos serem executados mesmo se sudo não puder escrever no arquivo de log"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Resolve grupos no sudoers e corresponde ao ID de grupo, e não o nome"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Entradas de log maiores que este valor serão divididos em múltiplas mensagens de syslog: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Usuário que será dono dos arquivos de log de E/S: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Grupo que será dono dos arquivos de log de E/S: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Modo de arquivo usado para os arquivos de log de E/S: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Executa comandos pelo descritor de arquivo em vez de pelo caminho: %s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Ignora entradas desconhecidas de Defaults no sudoers em vez de produzir um aviso"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Tempo em segundos após o qual o comando será terminado: %u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Permite o usuário especificar um tempo limite na linha de comando"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Descarrega os dados de log de E/S para o disco imediatamente em vez de armazenar no buffer"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "Inclui o ID de processo ao registrar log via syslog"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Tipo de registro de marca de tempo de autenticação: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "Mensagem de falha de autenticação: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "Ignora maiúsculo/minúsculo ao corresponder nomes de usuário"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "Ignora maiúsculo/minúsculo ao corresponder nomes de grupo"
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d entrada padrão \"%s\" desconhecida"
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: entrada padrão \"%s\" desconhecida"
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d nenhum valor especificado para \"%s\""
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: nenhum valor especificado para \"%s\""
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d valores para \"%s\" devem iniciar com um \"/\""
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: valores para \"%s\" devem iniciar com um \"/\""
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d opção \"%s\" não leva um valor"
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: opção \"%s\" não leva um valor"
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d Tipo de padrões 0x%x inválido para a opção \"%s\""
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: Tipo de padrões 0x%x inválido para a opção \"%s\""
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d valor \"%s\" é inválido para a opção \"%s\""
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: valor \"%s\" é inválido para a opção \"%s\""
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: envp corrompido, cumprimento não confere"
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr "não foi possível recompilar o ambiente"
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "sinto muito, você não tem permissão para definir as seguintes variáveis de ambiente: %s"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "erro de análise em %s próximo à linha %d"
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "erro de análise em %s"
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "tipo de digest %d sem suporte para %s"
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr "%s: erro de leitura"
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s deve ter como dono o uid %d"
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s deve ser gravável apenas pelo dono"
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "não foi possível carregar %s: %s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "não foi possível localizar um símbolo \"group_plugin\" %s"
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: versão maior do plug-in de grupo %d incompatível, esperava %d"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "não foi possível analisar o endereço IP \"%s\""
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "não foi possível analisar a máscara de rede \"%s\""
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Par de endereço IP e máscara de rede locais:\n"
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s existe, mas não é um diretório (0%o)"
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "não foi possível fazer mkdir %s"
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:723
+#: plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "não foi possível alterar modo de %s para 0%o"
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1167
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr "grupo desconhecido %s"
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr "não foi possível ler %s"
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr "não foi possível criar %s"
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "não foi possível gravar no arquivo de log de E/S: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr "%s: erro interno, o arquivo de log de E/S para evento %d não está aberto"
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr "%s: erro interno, sinal inválido %d"
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: arquivo de log inválido"
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: campo de marca de tempo está faltando"
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: marca de tempo %s: %s"
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: campo de usuário está faltando"
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: campo de usuário, a ser executado como, está faltando"
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: campo de grupo, a ser executado como, está faltando"
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr "sem suporte a starttls ao usar ldaps"
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "não foi possível inicializar bando de dados de chaves e certificados SSL: %s"
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "você deve definir TLS_CERT em %s para usar SSL"
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "não foi possível inicializar LDAP: %s"
+
+#: plugins/sudoers/ldap.c:1648
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls especificado, mas bibliotecas LDAP não possuem suporte a ldap_start_tls_s() ou ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "atributo sudoOrder inválido: %s"
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: porta muito grande"
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "tipo de uri LDAP sem suporte: %s"
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "não foi possível misturar ldap e ldaps URIs"
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "não foi possível converter sudoOption: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "não foi possível abrir o sistema de auditoria"
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr "não foi possível enviar mensagem de auditoria"
+
+#: plugins/sudoers/logging.c:113
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:141
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (comando continuado) %s"
+
+#: plugins/sudoers/logging.c:170
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "não foi possível abrir o arquivo de log: %s"
+
+#: plugins/sudoers/logging.c:178
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "não foi possível travar o arquivo de log: %s"
+
+#: plugins/sudoers/logging.c:211
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "não foi possível gravar no arquivo de log: %s"
+
+#: plugins/sudoers/logging.c:240
+msgid "No user or host"
+msgstr "nenhum usuário ou máquina"
+
+#: plugins/sudoers/logging.c:242
+msgid "validation failure"
+msgstr "falha de validação"
+
+#: plugins/sudoers/logging.c:249
+msgid "user NOT in sudoers"
+msgstr "usuário NÃO ESTÁ no sudoers"
+
+#: plugins/sudoers/logging.c:251
+msgid "user NOT authorized on host"
+msgstr "usuário NÃO ESTÁ autorizado na máquina"
+
+#: plugins/sudoers/logging.c:253
+msgid "command not allowed"
+msgstr "comando não permitido"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s não está no arquivo sudoers. Este incidente será relatado.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s não tem permissão para executar sudo em %s. Este incidente será relatado.\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Sinto muito, usuário %s não pode executar sudo em %s.\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Sinto muito, usuário %s não tem permissão para executar \"%s%s%s\" como %s%s%s em %s.\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: comando não encontrado"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"ignorando \"%s\" encontrado em \".\"\n"
+"Use \"sudo ./%s\" se isto é o \"%s\" que você deseja executar."
+
+#: plugins/sudoers/logging.c:354
+msgid "authentication failure"
+msgstr "falha de autenticação"
+
+#: plugins/sudoers/logging.c:380
+msgid "a password is required"
+msgstr "uma senha é necessária"
+
+#: plugins/sudoers/logging.c:443
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u tentativa de senha incorreta"
+msgstr[1] "%u tentativas de senha incorreta"
+
+#: plugins/sudoers/logging.c:666
+msgid "unable to fork"
+msgstr "não foi possível fazer fork"
+
+#: plugins/sudoers/logging.c:674 plugins/sudoers/logging.c:726
+#, c-format
+msgid "unable to fork: %m"
+msgstr "não foi possível fazer fork: %m"
+
+#: plugins/sudoers/logging.c:716
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "não foi possível abrir um redirecionamento (pipe): %m"
+
+#: plugins/sudoers/logging.c:741
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "não foi possível fazer dup da entrada padrão: %m"
+
+#: plugins/sudoers/logging.c:779
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "não foi possível executar %s: %m"
+
+#: plugins/sudoers/match.c:874
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "digest de %s (%s) não está na forma %s"
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:421 plugins/sudoers/visudo.c:717
+#, c-format
+msgid "unable to stat %s"
+msgstr "não foi possível obter o estado de %s"
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"Papel LDAP: %s\n"
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Entradas no sudoers:\n"
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr " UsuáriosRunAs: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr " GruposRunAs: "
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr " Opções: "
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr " Comandos:\n"
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Entradas de Defaults correspondentes a %s em %s:\n"
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Padrões específicos de comandos e \"runas\" de %s:\n"
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Usuário %s pode executar os seguintes comandos em %s:\n"
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Usuário %s não tem permissão para executar sudo em %s.\n"
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "ignorando valor de atributo inválido: %s"
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "ignorando sudoRole incompleto: cn: %s"
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "%.*s inválido definido pelo front-end do sudo"
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr "não foi possível analisar a lista de endereços de rede"
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr "nome de usuário não definido pelo front-end do sudo"
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr "ID de usuário não definido pelo front-end do sudo"
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr "ID de grupo não definido pelo front-end do sudo"
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr "nome da máquina não definido pelo front-end do sudo"
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:220
+#: plugins/sudoers/visudo.c:851
+#, c-format
+msgid "unable to execute %s"
+msgstr "não foi possível executar %s"
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Versão de plug-in de política do sudoers %s\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Versão de gramática de arquivo do sudoers %d\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Caminho do sudoers: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "caminho do nsswitch: %s\n"
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "caminho do ldap.conf: %s\n"
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "caminho do ldap.secret: %s\n"
+
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "não foi possível registrar hook do tipo %d (versão %d.%d)"
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "não foi possível fazer cache de uid %u, memória insuficiente"
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "não foi possível fazer cache de uid %u, já existe"
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "não foi possível fazer cache de usuário %s, memória insuficiente"
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "não foi possível fazer cache de usuário %s, já existe"
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "não foi possível fazer cache de gid %u, memória insuficiente"
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "não foi possível fazer cache de gid %u, já existe"
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "não foi possível fazer cache de grupo %s, memória insuficiente"
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "não foi possível fazer cache de grupo %s, já existe"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "não foi possível fazer cache da lista de grupos de %s, já existe"
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "não foi possível fazer cache da lista de grupos de %s, memória insuficiente"
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "não foi possível analisar grupos de %s"
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "não foi possível analisar os gids de %s"
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr "estouro da pilha de permissões"
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr "esvaziamento da pilha de permissões"
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr "não foi possível alterar gid de root"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr "não foi possível alterar para gid de \"runas\""
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr "não foi possível definir vetor de grupo de \"runas\""
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr "não foi possível alterar para uid de \"runas\""
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr "não foi possível alterar para gid de sudoers"
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr "processos demais"
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr "não foi possível definir diretório de trabalho atual"
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "caminho de auditoria truncado user_cmnd: %s"
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "caminho de auditoria truncado argv[0]: %s"
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr "mensagem de audit_failure muito grande"
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "não foi possível inicializar a fonte SSS. SSSD está instalado em sua máquina?"
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "não foi possível localizar símbolo \"%s\" em %s"
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr "problema com o entradas padrão"
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr "nenhuma fonte de sudoers válida encontrada; saindo"
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers especifica que o root não tem permissão para usar sudo"
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr "você não tem permissão para usar a opção -C"
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "dono da marca de tempo (%s): Usuário inexistente"
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr "nenhum tty"
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr "sinto muito, você deve ter um tty para executar sudo"
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr "comando no diretório atual"
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "sinto muito, você não tem permissão para definir um tempo limite de comando"
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "sinto muito, você não tem permissão para preservar o ambiente"
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr "comando muito grande"
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s não é um arquivo comum"
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s tem como dono o uid %u, deveria ser %u"
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr "%s é gravável globalmente"
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s tem como dono o gid %u, deveria ser %u"
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "apenas o root pode usar \"-c %s\""
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr "classe de login desconhecida: %s"
+
+#: plugins/sudoers/sudoers.c:1069 plugins/sudoers/sudoers.c:1083
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "não foi possível resolver máquina %s"
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "opção de filtro inválida: %s"
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "espera máxima inválida: %s"
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "fator de velocidade inválido: %s"
+
+# timing é o nome do arquivo gerado pelo sudo; não traduzir.
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/timing: %s"
+
+# timing é o nome do arquivo gerado pelo sudo; não traduzir.
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/timing: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Reproduzindo sessão de sudo: %s"
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr "não foi possível adicionar evento para a fila"
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr "não foi possível definir o tty para modo raw"
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Aviso: seu terminal é muito pequeno para reproduzir adequadamente o log.\n"
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Geometria do log é %d x %d; geometria do seu terminal é %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Reprodução finalizada, pressione qualquer tecla para restaurar o terminal."
+
+# timing é o nome do arquivo gerado pelo sudo; não traduzir.
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "linha inválida no arquivo timing: %s"
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "expressão ambígua \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr "\")\" não coincidente na expressão"
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "termo de pesquisa desconhecido \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s requer um argumento"
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "expressão regular inválida: %s"
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "não foi possível analisar a data \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr "\"(\" sem correspondente na expressão"
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr "fim de linha ilegal com \"or\""
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr "fim de linha ilegal com \"!\""
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr "tipo de pesquisa desconhecido %d"
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr "uso: %s [-hnRS] [-d diretório] [-m número] [-s número] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "uso: %s [-h] [-d diretório] -l [expressão de pesquisa]\n"
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - reproduz logs de sessão do sudo\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Opções:\n"
+" -d, --directory=dir especifica o diretório dos logs de sessão\n"
+" -f, --filter=filtro especifica qual o tipo de E/S para exibir\n"
+" -h, --help exibe mensagem de ajuda e sai\n"
+" -l, --list lista IDs de sessão disponíveis, podendo ser filtrado\n"
+" com uso opcional de expressão regular\n"
+" -m, --max-wait=núm número máximo, em segundos, de espera entre eventos\n"
+" -S, --suspend-wait aguarda enquanto o comando estava suspenso\n"
+" -s, --speed=número aumenta ou diminui a velocidade da saída\n"
+" -V, --version exibe a informação da versão e sai"
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr "\tmáquina sem correspondente"
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Comando permitido"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Comando negado"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Comando sem correspondente"
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr "%s é gravável pelo grupo"
+
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "não foi possível truncar o arquivo de marca de tempo para %lld bytes"
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:482 plugins/sudoers/visudo.c:488
+msgid "unable to read the clock"
+msgstr "não foi possível ler do relógio"
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr "ignorado marca de tempo no futuro"
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "marca de tempo muito a frente no futuro: %20.20s"
+
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "não foi possível travar o arquivo de marca de tempo %s"
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "caminho de status de instruções muito longo: %s/%s"
+
+#: plugins/sudoers/visudo.c:216
+msgid "the -x option will be removed in a future release"
+msgstr "a opção -x será removida em um lançamento futuro"
+
+#: plugins/sudoers/visudo.c:217
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "por favor, em vez disso, considere usar o utilitário cvtsudoers"
+
+#: plugins/sudoers/visudo.c:268 plugins/sudoers/visudo.c:650
+#, c-format
+msgid "press return to edit %s: "
+msgstr "pressione enter para editar %s: "
+
+#: plugins/sudoers/visudo.c:329
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "editor especificado (%s) não existe"
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "nenhum editor encontrado (caminho do editor = %s)"
+
+#: plugins/sudoers/visudo.c:441 plugins/sudoers/visudo.c:449
+msgid "write error"
+msgstr "erro de escrita"
+
+#: plugins/sudoers/visudo.c:495
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "não foi possível obter estado de arquivo temporário (%s), %s sem alteração"
+
+#: plugins/sudoers/visudo.c:502
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "arquivo de temporário (%s) com comprimento zero, %s sem alteração"
+
+#: plugins/sudoers/visudo.c:508
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "editor (%s) falhou, %s sem alteração"
+
+#: plugins/sudoers/visudo.c:530
+#, c-format
+msgid "%s unchanged"
+msgstr "%s sem alteração"
+
+#: plugins/sudoers/visudo.c:589
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "não foi possível reabrir arquivo temporário (%s), %s sem alteração."
+
+#: plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "não foi possível analisar arquivo temporário (%s), erro desconhecido"
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "erro interno, não foi possível localizar %s na lista!"
+
+#: plugins/sudoers/visudo.c:719 plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "não foi possível definir (uid, gid) de %s para (%u, %u)"
+
+#: plugins/sudoers/visudo.c:751
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s e %s não estão no mesmo sistema de arquivos, usando mv para renomear"
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "comando \"%s %s %s\" falhou, %s sem alteração"
+
+#: plugins/sudoers/visudo.c:775
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "erro ao renomear %s, %s sem alteração"
+
+#: plugins/sudoers/visudo.c:796
+msgid "What now? "
+msgstr "Agora o que? "
+
+#: plugins/sudoers/visudo.c:810
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Opções são:\n"
+" (e)dit - editar arquivos sudoers novamente\n"
+" e(x)it - sair sem salvar alterações no arquivo sudoers\n"
+" (Q)uit - sair e salvar alterações no arquivo sudoers (PERIGO!)\n"
+
+#: plugins/sudoers/visudo.c:856
+#, c-format
+msgid "unable to run %s"
+msgstr "não foi possível executar %s"
+
+#: plugins/sudoers/visudo.c:886
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: dono (uid, gid) incorreto; deveria ser (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: permissões incorretas; deveria estar no modo 0%o\n"
+
+#: plugins/sudoers/visudo.c:950 plugins/sudoers/visudo.c:957
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: análise OK\n"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s ocupado, tente novamente"
+
+#: plugins/sudoers/visudo.c:979
+#, c-format
+msgid "unable to lock %s"
+msgstr "não foi possível travar %s"
+
+#: plugins/sudoers/visudo.c:980
+msgid "Edit anyway? [y/N]"
+msgstr "Editar mesmo assim? [y/N]"
+
+#: plugins/sudoers/visudo.c:1064
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Erro: %s:%d ciclo em %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1065
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Aviso: %s:%d ciclo em %s \"%s\""
+
+#: plugins/sudoers/visudo.c:1069
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Erro: %s:%d %s \"%s\" referenciado, mas não definido"
+
+#: plugins/sudoers/visudo.c:1070
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Aviso: %s:%d %s \"%s\" referenciado, mas não definido"
+
+#: plugins/sudoers/visudo.c:1161
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Aviso: %s:%d %s não usado \"%s\""
+
+#: plugins/sudoers/visudo.c:1276
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - edita o arquivo sudoers com segurança\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1278
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"Opções:\n"
+" -c, --check modo de verificação, apenas\n"
+" -f, --file=sudoers especifica localização do arquivo sudoers\n"
+" -h, --help exibe uma mensagem de ajuda e sai\n"
+" -q, --quiet mensagens de erro de sintaxe menos detalhada\n"
+" -s, --strict verificação rigorosa de sintaxe\n"
+" -V, --version exibe a informação da versão e sai\n"
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr "níveis de inclusões demais"
+
+#~ msgid ""
+#~ "\n"
+#~ "LDAP Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Papel LDAP: DESCONHECIDO\n"
+
+#~ msgid " Order: %s\n"
+#~ msgstr " Ordem: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: %s\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Papel SSSD: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Papel SSSD: DESCONHECIDO\n"
+
+#~ msgid "Warning: cycle in %s `%s'"
+#~ msgstr "Aviso: ciclo em %s \"%s\""
+
+#~ msgid "Warning: %s `%s' referenced but not defined"
+#~ msgstr "Aviso: %s \"%s\" referenciado, mas não definido"
+
+#~ msgid "Warning: unused %s `%s'"
+#~ msgstr "Aviso: %s não usado \"%s\""
+
+#~ msgid "timestamp path too long: %s/%s"
+#~ msgstr "caminho de marca de tempo muito longo: %s/%s"
+
+#~ msgid "unable to stat editor (%s)"
+#~ msgstr "não foi possível obter estado do editor (%s)"
+
+# Mantive, pois hostbuf é uma variável do plugins/sudoers/ldap.c
+#~ msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+#~ msgstr "sudo_ldap_conf_add_ports: sem espaço para expansão de hostbuf"
+
+# Mantive, pois hostbuf é uma variável do plugins/sudoers/ldap.c
+#~ msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+#~ msgstr "sudo_ldap_parse_uri: sem espaço na construção de hostbuf"
+
+#~ msgid "sudo_ldap_build_pass1 allocation mismatch"
+#~ msgstr "alocação de sudo_ldap_build_pass1 não confere"
+
+#~ msgid "Password:"
+#~ msgstr "Senha:"
+
+#~ msgid "internal error: insufficient space for log line"
+#~ msgstr "erro interno: espaço insuficiente para linha de log"
+
+#~ msgid "fill_args: buffer overflow"
+#~ msgstr "fill_args: estouro de buffer"
+
+#~ msgid "%s owned by uid %u, should be uid %u"
+#~ msgstr "%s tem como dono o uid %u, deveria ser uid %u"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0700"
+#~ msgstr "%s gravável por não-dono (0%o); deveria estar no modo 0700"
+
+#~ msgid "%s exists but is not a regular file (0%o)"
+#~ msgstr "%s existe, mas não é um arquivo comum (0%o)"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0600"
+#~ msgstr "%s gravável por não-dono (0%o); deveria estar no modo 0600"
+
+#~ msgid "unable to remove %s, will reset to the Unix epoch"
+#~ msgstr "não foi possível remover %s, redefinindo para como estava no Unix"
+
+#~ msgid "unable to reset %s to the Unix epoch"
+#~ msgstr "não foi possível redefinir %s para como estava no Unix"
+
+#~ msgid "value out of range"
+#~ msgstr "valor fora da faixa"
+
+#~ msgid "invalid uri: %s"
+#~ msgstr "uri inválida: %s"
+
+#~ msgid "unable to mix ldaps and starttls"
+#~ msgstr "não foi possível misturar ldaps e starttls"
+
+#~ msgid "writing to standard output"
+#~ msgstr "escrevendo para saída padrão"
+
+#~ msgid "too many parenthesized expressions, max %d"
+#~ msgstr "parênteses de expressões demais, máximo %d"
+
+#~ msgid "unable to setup authentication"
+#~ msgstr "não foi possível configurar autenticação"
+
+#~ msgid "getaudit: failed"
+#~ msgstr "getaudit: falhou"
+
+#~ msgid "getauid: failed"
+#~ msgstr "getauid: falhou"
+
+#~ msgid "au_to_subject: failed"
+#~ msgstr "au_to_subject: falhou"
+
+#~ msgid "au_to_exec_args: failed"
+#~ msgstr "au_to_exec_args: falhou"
+
+#~ msgid "au_to_return32: failed"
+#~ msgstr "au_to_return32: falhou"
+
+#~ msgid "au_to_text: failed"
+#~ msgstr "au_to_text: falhou"
+
+#~ msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
+#~ msgstr "nanosleep: tv_sec %ld, tv_nsec %ld"
+
+#~ msgid "pam_chauthtok: %s"
+#~ msgstr "pam_chauthtok: %s"
+
+#~ msgid "pam_authenticate: %s"
+#~ msgstr "pam_authenticate: %s"
+
+#~ msgid "getauid failed"
+#~ msgstr "getauid falhou"
+
+#, fuzzy
+#~ msgid "Unable to dlopen %s: %s"
+#~ msgstr "não foi possível fazer dlopen %s: %s"
+
+#~ msgid "invalid regex: %s"
+#~ msgstr "expressão regular inválida: %s"
diff --git a/plugins/sudoers/po/ru.mo b/plugins/sudoers/po/ru.mo
new file mode 100644
index 0000000..aff51ce
--- /dev/null
+++ b/plugins/sudoers/po/ru.mo
Binary files differ
diff --git a/plugins/sudoers/po/ru.po b/plugins/sudoers/po/ru.po
new file mode 100644
index 0000000..64a42d2
--- /dev/null
+++ b/plugins/sudoers/po/ru.po
@@ -0,0 +1,1868 @@
+# Transation of sudoers messages to Russian.
+# This file is put in the public domain.
+# This file is distributed under the same license as the sudo package.
+#
+# Artem Vorotnikov <artem@vorotnikov.me>, 2015.
+# Pavel Maryanov <acid@jack.kiev.ua>, 2015.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.14b2\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2015-07-03 07:09-0600\n"
+"PO-Revision-Date: 2015-09-10 19:15+0300\n"
+"Last-Translator: Pavel Maryanov <acid@jack.kiev.ua>\n"
+"Language-Team: Russian <gnu@d07.ru>\n"
+"Language: ru\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Generator: Poedit 1.8.4\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "ошибка синтаксиса"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "пароль %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] пароль для %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Пароль: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** Данные БЕЗОПАСНОСТИ для %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Попробуйте ещё раз."
+
+#: gram.y:181 gram.y:199 gram.y:205 gram.y:211 gram.y:217 gram.y:223
+#: gram.y:239 gram.y:246 gram.y:253 gram.y:260 gram.y:267 gram.y:283
+#: gram.y:306 gram.y:313 gram.y:320 gram.y:327 gram.y:334 gram.y:387
+#: gram.y:395 gram.y:405 gram.y:435 gram.y:442 gram.y:449 gram.y:456
+#: gram.y:568 gram.y:575 gram.y:584 gram.y:593 gram.y:610 gram.y:661
+#: gram.y:668 gram.y:675 gram.y:683 gram.y:775 gram.y:782 gram.y:789
+#: gram.y:796 gram.y:803 gram.y:829 gram.y:836 gram.y:843 gram.y:1110
+#: gram.y:1117 plugins/sudoers/alias.c:123 plugins/sudoers/alias.c:136
+#: plugins/sudoers/auth/bsdauth.c:141 plugins/sudoers/auth/kerb5.c:119
+#: plugins/sudoers/auth/kerb5.c:145 plugins/sudoers/auth/pam.c:371
+#: plugins/sudoers/auth/rfc1938.c:109 plugins/sudoers/auth/sia.c:110
+#: plugins/sudoers/defaults.c:516 plugins/sudoers/defaults.c:720
+#: plugins/sudoers/defaults.c:880 plugins/sudoers/editor.c:64
+#: plugins/sudoers/editor.c:82 plugins/sudoers/editor.c:92
+#: plugins/sudoers/env.c:233 plugins/sudoers/group_plugin.c:131
+#: plugins/sudoers/iolog.c:582 plugins/sudoers/iolog.c:614
+#: plugins/sudoers/iolog_path.c:167 plugins/sudoers/ldap.c:446
+#: plugins/sudoers/ldap.c:477 plugins/sudoers/ldap.c:529
+#: plugins/sudoers/ldap.c:562 plugins/sudoers/ldap.c:914
+#: plugins/sudoers/ldap.c:1060 plugins/sudoers/ldap.c:1339
+#: plugins/sudoers/ldap.c:1512 plugins/sudoers/ldap.c:1588
+#: plugins/sudoers/ldap.c:1724 plugins/sudoers/ldap.c:1748
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1831
+#: plugins/sudoers/ldap.c:1846 plugins/sudoers/ldap.c:1942
+#: plugins/sudoers/ldap.c:1975 plugins/sudoers/ldap.c:2128
+#: plugins/sudoers/ldap.c:2225 plugins/sudoers/ldap.c:3028
+#: plugins/sudoers/ldap.c:3061 plugins/sudoers/ldap.c:3375
+#: plugins/sudoers/ldap.c:3403 plugins/sudoers/ldap.c:3414
+#: plugins/sudoers/ldap.c:3504 plugins/sudoers/ldap.c:3520
+#: plugins/sudoers/linux_audit.c:76 plugins/sudoers/logging.c:188
+#: plugins/sudoers/logging.c:662 plugins/sudoers/logging.c:916
+#: plugins/sudoers/match.c:501 plugins/sudoers/match.c:537
+#: plugins/sudoers/match.c:695 plugins/sudoers/match.c:752
+#: plugins/sudoers/parse.c:235 plugins/sudoers/parse.c:247
+#: plugins/sudoers/parse.c:262 plugins/sudoers/parse.c:274
+#: plugins/sudoers/policy.c:384 plugins/sudoers/policy.c:575
+#: plugins/sudoers/prompt.c:93 plugins/sudoers/sssd.c:160
+#: plugins/sudoers/sssd.c:192 plugins/sudoers/sssd.c:198
+#: plugins/sudoers/sssd.c:236 plugins/sudoers/sssd.c:243
+#: plugins/sudoers/sssd.c:279 plugins/sudoers/sssd.c:324
+#: plugins/sudoers/sssd.c:916 plugins/sudoers/sssd.c:1049
+#: plugins/sudoers/sudoers.c:159 plugins/sudoers/sudoers.c:294
+#: plugins/sudoers/sudoers.c:304 plugins/sudoers/sudoers.c:312
+#: plugins/sudoers/sudoers.c:365 plugins/sudoers/sudoers.c:663
+#: plugins/sudoers/sudoers.c:749 plugins/sudoers/sudoers.c:793
+#: plugins/sudoers/sudoers_debug.c:107 plugins/sudoers/sudoreplay.c:471
+#: plugins/sudoers/sudoreplay.c:667 plugins/sudoers/sudoreplay.c:779
+#: plugins/sudoers/sudoreplay.c:819 plugins/sudoers/sudoreplay.c:828
+#: plugins/sudoers/sudoreplay.c:838 plugins/sudoers/sudoreplay.c:846
+#: plugins/sudoers/sudoreplay.c:850 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1010 plugins/sudoers/testsudoers.c:130
+#: plugins/sudoers/testsudoers.c:187 plugins/sudoers/testsudoers.c:214
+#: plugins/sudoers/testsudoers.c:231 plugins/sudoers/visudo.c:155
+#: plugins/sudoers/visudo.c:215 plugins/sudoers/visudo.c:299
+#: plugins/sudoers/visudo.c:305 plugins/sudoers/visudo.c:435
+#: plugins/sudoers/visudo.c:971 plugins/sudoers/visudo.c:1015
+#: plugins/sudoers/visudo.c:1111
+msgid "unable to allocate memory"
+msgstr "не удаётся выделить память"
+
+#: gram.y:467
+msgid "a digest requires a path name"
+msgstr "для дайджеста нужно указать полный путь"
+
+#: gram.y:1110 gram.y:1117 plugins/sudoers/auth/pam.c:371
+#: plugins/sudoers/auth/rfc1938.c:109 plugins/sudoers/defaults.c:516
+#: plugins/sudoers/defaults.c:720 plugins/sudoers/defaults.c:880
+#: plugins/sudoers/editor.c:64 plugins/sudoers/editor.c:82
+#: plugins/sudoers/editor.c:92 plugins/sudoers/env.c:233
+#: plugins/sudoers/group_plugin.c:131 plugins/sudoers/iolog.c:582
+#: plugins/sudoers/iolog.c:614 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:446 plugins/sudoers/ldap.c:477
+#: plugins/sudoers/ldap.c:529 plugins/sudoers/ldap.c:562
+#: plugins/sudoers/ldap.c:914 plugins/sudoers/ldap.c:1060
+#: plugins/sudoers/ldap.c:1339 plugins/sudoers/ldap.c:1512
+#: plugins/sudoers/ldap.c:1588 plugins/sudoers/ldap.c:1724
+#: plugins/sudoers/ldap.c:1748 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1831 plugins/sudoers/ldap.c:1846
+#: plugins/sudoers/ldap.c:1942 plugins/sudoers/ldap.c:1975
+#: plugins/sudoers/ldap.c:2128 plugins/sudoers/ldap.c:2225
+#: plugins/sudoers/ldap.c:3028 plugins/sudoers/ldap.c:3061
+#: plugins/sudoers/ldap.c:3375 plugins/sudoers/ldap.c:3403
+#: plugins/sudoers/ldap.c:3414 plugins/sudoers/ldap.c:3504
+#: plugins/sudoers/ldap.c:3520 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:188 plugins/sudoers/logging.c:916
+#: plugins/sudoers/match.c:501 plugins/sudoers/match.c:537
+#: plugins/sudoers/match.c:695 plugins/sudoers/match.c:752
+#: plugins/sudoers/parse.c:235 plugins/sudoers/parse.c:247
+#: plugins/sudoers/parse.c:262 plugins/sudoers/parse.c:274
+#: plugins/sudoers/policy.c:97 plugins/sudoers/policy.c:106
+#: plugins/sudoers/policy.c:115 plugins/sudoers/policy.c:139
+#: plugins/sudoers/policy.c:250 plugins/sudoers/policy.c:271
+#: plugins/sudoers/policy.c:280 plugins/sudoers/policy.c:319
+#: plugins/sudoers/policy.c:329 plugins/sudoers/policy.c:338
+#: plugins/sudoers/policy.c:384 plugins/sudoers/policy.c:575
+#: plugins/sudoers/prompt.c:93 plugins/sudoers/set_perms.c:356
+#: plugins/sudoers/set_perms.c:695 plugins/sudoers/set_perms.c:1054
+#: plugins/sudoers/set_perms.c:1350 plugins/sudoers/set_perms.c:1514
+#: plugins/sudoers/sssd.c:160 plugins/sudoers/sssd.c:192
+#: plugins/sudoers/sssd.c:198 plugins/sudoers/sssd.c:236
+#: plugins/sudoers/sssd.c:243 plugins/sudoers/sssd.c:279
+#: plugins/sudoers/sssd.c:324 plugins/sudoers/sssd.c:916
+#: plugins/sudoers/sssd.c:1049 plugins/sudoers/sudoers.c:159
+#: plugins/sudoers/sudoers.c:294 plugins/sudoers/sudoers.c:304
+#: plugins/sudoers/sudoers.c:312 plugins/sudoers/sudoers.c:365
+#: plugins/sudoers/sudoers.c:663 plugins/sudoers/sudoers.c:749
+#: plugins/sudoers/sudoers.c:793 plugins/sudoers/sudoers_debug.c:106
+#: plugins/sudoers/sudoreplay.c:471 plugins/sudoers/sudoreplay.c:667
+#: plugins/sudoers/sudoreplay.c:779 plugins/sudoers/sudoreplay.c:819
+#: plugins/sudoers/sudoreplay.c:828 plugins/sudoers/sudoreplay.c:838
+#: plugins/sudoers/sudoreplay.c:846 plugins/sudoers/sudoreplay.c:850
+#: plugins/sudoers/sudoreplay.c:1006 plugins/sudoers/sudoreplay.c:1010
+#: plugins/sudoers/testsudoers.c:130 plugins/sudoers/testsudoers.c:187
+#: plugins/sudoers/testsudoers.c:214 plugins/sudoers/testsudoers.c:231
+#: plugins/sudoers/visudo.c:155 plugins/sudoers/visudo.c:215
+#: plugins/sudoers/visudo.c:299 plugins/sudoers/visudo.c:305
+#: plugins/sudoers/visudo.c:435 plugins/sudoers/visudo.c:971
+#: plugins/sudoers/visudo.c:1015 plugins/sudoers/visudo.c:1111
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:132
+#, c-format
+msgid "Alias `%s' already defined"
+msgstr "Псевдоним «%s» уже определён"
+
+#: plugins/sudoers/auth/bsdauth.c:68
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "не удаётся получить класс логина для пользователя %s"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+msgid "unable to begin bsd authentication"
+msgstr "не удаётся начать BSD-аутентификацию"
+
+#: plugins/sudoers/auth/bsdauth.c:81
+msgid "invalid authentication type"
+msgstr "некорректный тип аутентификации"
+
+#: plugins/sudoers/auth/bsdauth.c:90
+msgid "unable to initialize BSD authentication"
+msgstr "не удаётся запустить BSD-аутентификацию"
+
+#: plugins/sudoers/auth/fwtk.c:52
+msgid "unable to read fwtk config"
+msgstr "не удаётся прочитать конфигурацию ftwk"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to connect to authentication server"
+msgstr "не удаётся связаться с сервером аутентификации"
+
+#: plugins/sudoers/auth/fwtk.c:63 plugins/sudoers/auth/fwtk.c:87
+#: plugins/sudoers/auth/fwtk.c:120
+msgid "lost connection to authentication server"
+msgstr "потеряно соединение с сервером аутентификации"
+
+#: plugins/sudoers/auth/fwtk.c:67
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"ошибка сервера аутентификации:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:111
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: не удаётся преобразовать принципал в строку ('%s'): %s"
+
+#: plugins/sudoers/auth/kerb5.c:161
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: не удаётся прочитать '%s': %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: не удаётся разрешить кэш учётных данных: %s"
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: не удаётся выделить параметры: %s"
+
+#: plugins/sudoers/auth/kerb5.c:232
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: не удаётся получить учётные данные: %s"
+
+#: plugins/sudoers/auth/kerb5.c:245
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: не удаётся инициализировать кэш учётных данных: %s"
+
+#: plugins/sudoers/auth/kerb5.c:248
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: не удаётся сохранить учётные данные в кэше: %s"
+
+#: plugins/sudoers/auth/kerb5.c:312
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: не удаётся получить принципал хоста: %s"
+
+#: plugins/sudoers/auth/kerb5.c:326
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Не удаётся проверить TGT. Нас атакуют?!: %s"
+
+#: plugins/sudoers/auth/pam.c:90
+msgid "unable to initialize PAM"
+msgstr "не удаётся инициализировать PAM"
+
+#: plugins/sudoers/auth/pam.c:146
+msgid "account validation failure, is your account locked?"
+msgstr "ошибка проверки учётной записи. Она заблокирована?"
+
+#: plugins/sudoers/auth/pam.c:150
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Учётные данные устарели. Сбросьте пароль и попробуйте ещё раз"
+
+#: plugins/sudoers/auth/pam.c:158
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "не удаётся сменить устаревший пароль: %s"
+
+#: plugins/sudoers/auth/pam.c:163
+msgid "Password expired, contact your system administrator"
+msgstr "Пароль устарел. Обратитесь к системному администратору"
+
+#: plugins/sudoers/auth/pam.c:167
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Срок действия учётной записи истёк или в настройках PAM нет раздела «account» для sudo. Обратитесь к системному администратору"
+
+#: plugins/sudoers/auth/pam.c:179
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Ошибка PAM-аутентификации: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:97 plugins/sudoers/visudo.c:220
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "Вы не существуете в базе данных %s"
+
+#: plugins/sudoers/auth/securid5.c:73
+msgid "failed to initialise the ACE API library"
+msgstr "не удалось инициализировать библиотеку API для ACE"
+
+#: plugins/sudoers/auth/securid5.c:99
+msgid "unable to contact the SecurID server"
+msgstr "не удалось связаться с сервером SecurID"
+
+#: plugins/sudoers/auth/securid5.c:108
+msgid "User ID locked for SecurID Authentication"
+msgstr "ID пользователя заблокирован для аутентификации SecurID"
+
+#: plugins/sudoers/auth/securid5.c:112 plugins/sudoers/auth/securid5.c:163
+msgid "invalid username length for SecurID"
+msgstr "недопустимая длина имени пользователя для SecurID"
+
+#: plugins/sudoers/auth/securid5.c:116 plugins/sudoers/auth/securid5.c:168
+msgid "invalid Authentication Handle for SecurID"
+msgstr "недопустимый обработчик аутентификации для SecurID"
+
+#: plugins/sudoers/auth/securid5.c:120
+msgid "SecurID communication failed"
+msgstr "ошибка связи с SecurID"
+
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:207
+msgid "unknown SecurID error"
+msgstr "неизвестная ошибка SecurID"
+
+#: plugins/sudoers/auth/securid5.c:158
+msgid "invalid passcode length for SecurID"
+msgstr "недопустимая длина пароля для SecurID"
+
+#: plugins/sudoers/auth/sia.c:120
+msgid "unable to initialize SIA session"
+msgstr "не удаётся инициализировать сеанс SIA"
+
+#: plugins/sudoers/auth/sudo_auth.c:126
+msgid "invalid authentication methods"
+msgstr "недопустимые методы аутентификации"
+
+#: plugins/sudoers/auth/sudo_auth.c:128
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "sudo скомпилирован с неверными методами аутентификации! Нельзя смешивать зависимую и независимую аутентификацию."
+
+#: plugins/sudoers/auth/sudo_auth.c:224 plugins/sudoers/auth/sudo_auth.c:273
+msgid "no authentication methods"
+msgstr "методы аутентификации отсутствуют"
+
+#: plugins/sudoers/auth/sudo_auth.c:226
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "sudo скомпилирован без методов аутентификации! Если нужно отключить аутентификацию, используйте параметр --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:275
+msgid "Unable to initialize authentication methods."
+msgstr "Не удаётся инициализировать методы аутентификации."
+
+#: plugins/sudoers/auth/sudo_auth.c:433
+msgid "Authentication methods:"
+msgstr "Методы аутентификации:"
+
+#: plugins/sudoers/bsm_audit.c:111 plugins/sudoers/bsm_audit.c:200
+msgid "Could not determine audit condition"
+msgstr "Не удалось определить состояние аудита"
+
+#: plugins/sudoers/bsm_audit.c:172 plugins/sudoers/bsm_audit.c:260
+msgid "unable to commit audit record"
+msgstr "не удаётся отправить запись аудита"
+
+#: plugins/sudoers/check.c:200
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Мы полагаем, что ваш системный администратор изложил вам основы\n"
+"безопасности. Как правило, всё сводится к трём следующим правилам:\n"
+"\n"
+" №1) Уважайте частную жизнь других.\n"
+" №2) Думайте, прежде что-то вводить.\n"
+" №3) С большой властью приходит большая ответственность.\n"
+"\n"
+
+#: plugins/sudoers/check.c:243 plugins/sudoers/check.c:253
+#: plugins/sudoers/sudoers.c:699 plugins/sudoers/sudoers.c:728
+#, c-format
+msgid "unknown uid: %u"
+msgstr "неизвестный uid: %u"
+
+#: plugins/sudoers/check.c:248 plugins/sudoers/policy.c:747
+#: plugins/sudoers/sudoers.c:1095 plugins/sudoers/testsudoers.c:205
+#: plugins/sudoers/testsudoers.c:360
+#, c-format
+msgid "unknown user: %s"
+msgstr "неизвестный пользователь: %s"
+
+#: plugins/sudoers/def_data.c:27
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:31
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:35
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:39
+msgid "Put OTP prompt on its own line"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:43
+msgid "Ignore '.' in $PATH"
+msgstr "Игнорировать '.' в переменной $PATH"
+
+#: plugins/sudoers/def_data.c:47
+msgid "Always send mail when sudo is run"
+msgstr "Отправлять письмо при каждом запуске sudo"
+
+#: plugins/sudoers/def_data.c:51
+msgid "Send mail if user authentication fails"
+msgstr "Отправлять письмо при ошибке аутентификации"
+
+#: plugins/sudoers/def_data.c:55
+msgid "Send mail if the user is not in sudoers"
+msgstr "Отправлять письмо, если пользователя нет в группе sudoers"
+
+#: plugins/sudoers/def_data.c:59
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Отправлять письмо, если пользователя нет в группе sudoers для данного компьютера"
+
+#: plugins/sudoers/def_data.c:63
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Отправлять письмо, если пользователю не разрешено выполнять команду"
+
+#: plugins/sudoers/def_data.c:67
+msgid "Send mail if the user tries to run a command"
+msgstr "Отправлять письмо, если пользователь пытается выполнить команду"
+
+#: plugins/sudoers/def_data.c:71
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:75
+msgid "Lecture user the first time they run sudo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:79
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:83
+msgid "Require users to authenticate by default"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:87
+msgid "Root may run sudo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:91
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:95
+msgid "Log the year in the (non-syslog) log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:99
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:103
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:107
+msgid "Always set $HOME to the target user's home directory"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:111
+msgid "Allow some information gathering to give useful error messages"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:115
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:119
+msgid "Insult the user when they enter an incorrect password"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:123
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:127
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:131
+msgid "Prompt for root's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:135
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:139
+msgid "Prompt for the target user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:143
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:147
+msgid "Set the LOGNAME and USER environment variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:151
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:155
+msgid "Don't initialize the group vector to that of the target user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:159
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:163
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:167
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:171
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:175
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:179
+#, c-format
+msgid "Path to log file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:183
+#, c-format
+msgid "Path to mail program: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:187
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:191
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:195
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:199
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:203
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:207
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:211
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:215
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:219
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:223
+#, c-format
+msgid "Default password prompt: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:227
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr ""
+
+#: plugins/sudoers/def_data.c:231
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:235
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:239
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:243
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:247
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:251
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:255
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:259
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:263
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:267
+msgid "Allow users to set arbitrary environment variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:271
+msgid "Reset the environment to a default set of variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:275
+msgid "Environment variables to check for sanity:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:279
+msgid "Environment variables to remove:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:283
+msgid "Environment variables to preserve:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:287
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:291
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:295
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:299
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:303
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:307
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:311
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:315
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:319
+msgid "Log user's input for the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:323
+msgid "Log the output of the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:327
+msgid "Compress I/O logs using zlib"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:331
+msgid "Always run commands in a pseudo-tty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:335
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:339
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:343
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:347
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:351
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:355
+msgid "Set of permitted privileges"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:359
+msgid "Set of limit privileges"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:363
+msgid "Run commands on a pty in the background"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:367
+msgid "PAM service name to use"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:371
+msgid "PAM service name to use for login shells"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:375
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:379
+msgid "Create a new PAM session for the command to run in"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:383
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:387
+msgid "Enable sudoers netgroup support"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:199 plugins/sudoers/defaults.c:608
+#: plugins/sudoers/visudo_json.c:633 plugins/sudoers/visudo_json.c:668
+#, c-format
+msgid "unknown defaults entry `%s'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:207 plugins/sudoers/defaults.c:217
+#: plugins/sudoers/defaults.c:241 plugins/sudoers/defaults.c:256
+#: plugins/sudoers/defaults.c:269 plugins/sudoers/defaults.c:282
+#: plugins/sudoers/defaults.c:295 plugins/sudoers/defaults.c:315
+#: plugins/sudoers/defaults.c:325
+#, c-format
+msgid "value `%s' is invalid for option `%s'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:210 plugins/sudoers/defaults.c:220
+#: plugins/sudoers/defaults.c:228 plugins/sudoers/defaults.c:251
+#: plugins/sudoers/defaults.c:264 plugins/sudoers/defaults.c:277
+#: plugins/sudoers/defaults.c:290 plugins/sudoers/defaults.c:310
+#: plugins/sudoers/defaults.c:321
+#, c-format
+msgid "no value specified for `%s'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:233
+#, c-format
+msgid "values for `%s' must start with a '/'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "option `%s' does not take a value"
+msgstr ""
+
+#: plugins/sudoers/env.c:295 plugins/sudoers/env.c:302
+#: plugins/sudoers/env.c:404 plugins/sudoers/ldap.c:450
+#: plugins/sudoers/ldap.c:540 plugins/sudoers/ldap.c:1143
+#: plugins/sudoers/ldap.c:1345 plugins/sudoers/ldap.c:1517
+#: plugins/sudoers/ldap.c:1673 plugins/sudoers/linux_audit.c:82
+#: plugins/sudoers/logging.c:921 plugins/sudoers/policy.c:494
+#: plugins/sudoers/policy.c:503 plugins/sudoers/prompt.c:161
+#: plugins/sudoers/sudoers.c:815 plugins/sudoers/testsudoers.c:235
+#: plugins/sudoers/toke_util.c:160
+#, c-format
+msgid "internal error, %s overflow"
+msgstr ""
+
+#: plugins/sudoers/env.c:376
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr ""
+
+#: plugins/sudoers/env.c:1047
+msgid "unable to rebuild the environment"
+msgstr "не удаётся перестроить среду"
+
+#: plugins/sudoers/env.c:1121
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:85
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:89
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:96 plugins/sudoers/sssd.c:331
+#, c-format
+msgid "unable to load %s: %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:101
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:110
+msgid "Local IP address and netmask pairs:\n"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:92 plugins/sudoers/iolog.c:110
+#: plugins/sudoers/timestamp.c:218
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:103 plugins/sudoers/iolog.c:124
+#: plugins/sudoers/iolog.c:131 plugins/sudoers/timestamp.c:212
+#: plugins/sudoers/timestamp.c:233
+#, c-format
+msgid "unable to mkdir %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:200 plugins/sudoers/sudoers.c:871
+#: plugins/sudoers/sudoreplay.c:302 plugins/sudoers/sudoreplay.c:768
+#: plugins/sudoers/sudoreplay.c:972 plugins/sudoers/timestamp.c:370
+#: plugins/sudoers/visudo.c:895 plugins/sudoers/visudo_json.c:1026
+#: plugins/sudoers/visudo_json.c:1039
+#, c-format
+msgid "unable to open %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:241 plugins/sudoers/sudoers.c:875
+#: plugins/sudoers/sudoreplay.c:1083
+#, c-format
+msgid "unable to read %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:273 plugins/sudoers/sudoreplay.c:549
+#: plugins/sudoers/timestamp.c:171 plugins/sudoers/timestamp.c:174
+#, c-format
+msgid "unable to write to %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:338 plugins/sudoers/iolog.c:536
+#, c-format
+msgid "unable to create %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:428
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:488
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:515
+msgid "unable to mix ldap and ldaps URIs"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:519 plugins/sudoers/ldap.c:555
+msgid "starttls not supported when using ldaps"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:626
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:629
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1129
+msgid "unable to get GMT time"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1135
+msgid "unable to format timestamp"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1821
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2360
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"Роль LDAP: %s\n"
+
+#: plugins/sudoers/ldap.c:2362
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"Роль LDAP: НЕИЗВЕСТНО\n"
+
+#: plugins/sudoers/ldap.c:2409
+#, c-format
+msgid " Order: %s\n"
+msgstr " Порядок: %s\n"
+
+#: plugins/sudoers/ldap.c:2417 plugins/sudoers/parse.c:573
+#: plugins/sudoers/sssd.c:1408
+#, c-format
+msgid " Commands:\n"
+msgstr " Команды:\n"
+
+#: plugins/sudoers/ldap.c:2980
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "не удаётся инициализировать LDAP: %s"
+
+#: plugins/sudoers/ldap.c:3016
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "указано start_tls, но библиотеки LDAP не поддерживают ldap_start_tls_s() или ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:3273
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "недопустимый атрибут sudoOrder: %s"
+
+#: plugins/sudoers/linux_audit.c:52
+msgid "unable to open audit system"
+msgstr "не удаётся открыть систему аудита"
+
+#: plugins/sudoers/linux_audit.c:93
+msgid "unable to send audit message"
+msgstr "не удаётся отправить сообщение аудита"
+
+#: plugins/sudoers/logging.c:106
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:134
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (выполнение команды продолжено) %s"
+
+#: plugins/sudoers/logging.c:159
+#, c-format
+msgid "unable to open log file: %s: %s"
+msgstr "не удаётся открыть файл журнала: %s: %s"
+
+#: plugins/sudoers/logging.c:162
+#, c-format
+msgid "unable to lock log file: %s: %s"
+msgstr "не удаётся заблокировать файл журнала: %s: %s"
+
+#: plugins/sudoers/logging.c:211
+msgid "No user or host"
+msgstr ""
+
+#: plugins/sudoers/logging.c:213
+msgid "validation failure"
+msgstr ""
+
+#: plugins/sudoers/logging.c:220
+msgid "user NOT in sudoers"
+msgstr ""
+
+#: plugins/sudoers/logging.c:222
+msgid "user NOT authorized on host"
+msgstr ""
+
+#: plugins/sudoers/logging.c:224
+msgid "command not allowed"
+msgstr ""
+
+#: plugins/sudoers/logging.c:259
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:262
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:266
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:269
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:306 plugins/sudoers/sudoers.c:471
+#: plugins/sudoers/sudoers.c:473 plugins/sudoers/sudoers.c:475
+#: plugins/sudoers/sudoers.c:477 plugins/sudoers/sudoers.c:1220
+#: plugins/sudoers/sudoers.c:1222
+#, c-format
+msgid "%s: command not found"
+msgstr ""
+
+#: plugins/sudoers/logging.c:308 plugins/sudoers/sudoers.c:467
+#, c-format
+msgid ""
+"ignoring `%s' found in '.'\n"
+"Use `sudo ./%s' if this is the `%s' you wish to run."
+msgstr ""
+
+#: plugins/sudoers/logging.c:325
+msgid "authentication failure"
+msgstr ""
+
+#: plugins/sudoers/logging.c:351
+msgid "a password is required"
+msgstr ""
+
+#: plugins/sudoers/logging.c:422 plugins/sudoers/logging.c:484
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#: plugins/sudoers/logging.c:572
+msgid "unable to fork"
+msgstr ""
+
+#: plugins/sudoers/logging.c:580 plugins/sudoers/logging.c:636
+#, c-format
+msgid "unable to fork: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:626
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:651
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:689
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr ""
+
+#: plugins/sudoers/match.c:606
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr ""
+
+#: plugins/sudoers/match.c:635
+#, c-format
+msgid "%s: read error"
+msgstr ""
+
+#: plugins/sudoers/match.c:649
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr ""
+
+#: plugins/sudoers/parse.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr ""
+
+#: plugins/sudoers/parse.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr ""
+
+#: plugins/sudoers/parse.c:520
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+
+#: plugins/sudoers/parse.c:521
+#, c-format
+msgid " RunAsUsers: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:535
+#, c-format
+msgid " RunAsGroups: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:544
+#, c-format
+msgid " Options: "
+msgstr ""
+
+#: plugins/sudoers/policy.c:240 plugins/sudoers/testsudoers.c:252
+msgid "unable to parse network address list"
+msgstr ""
+
+#: plugins/sudoers/policy.c:632 plugins/sudoers/visudo.c:836
+#, c-format
+msgid "unable to execute %s"
+msgstr ""
+
+#: plugins/sudoers/policy.c:765
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:767
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:771
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:774
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:776
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:777
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:810
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:136 plugins/sudoers/pwutil.c:153
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:147
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:191 plugins/sudoers/pwutil.c:207
+#: plugins/sudoers/pwutil.c:250 plugins/sudoers/pwutil.c:294
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:202
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:427 plugins/sudoers/pwutil.c:444
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:438
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:476 plugins/sudoers/pwutil.c:492
+#: plugins/sudoers/pwutil.c:524 plugins/sudoers/pwutil.c:565
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:487
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:676 plugins/sudoers/pwutil.c:710
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:682 plugins/sudoers/pwutil.c:715
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:705
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:113 plugins/sudoers/set_perms.c:438
+#: plugins/sudoers/set_perms.c:841 plugins/sudoers/set_perms.c:1138
+#: plugins/sudoers/set_perms.c:1430
+msgid "perm stack overflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:121 plugins/sudoers/set_perms.c:369
+#: plugins/sudoers/set_perms.c:446 plugins/sudoers/set_perms.c:708
+#: plugins/sudoers/set_perms.c:849 plugins/sudoers/set_perms.c:1067
+#: plugins/sudoers/set_perms.c:1146 plugins/sudoers/set_perms.c:1363
+#: plugins/sudoers/set_perms.c:1438 plugins/sudoers/set_perms.c:1527
+msgid "perm stack underflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:180 plugins/sudoers/set_perms.c:493
+#: plugins/sudoers/set_perms.c:1197 plugins/sudoers/set_perms.c:1470
+msgid "unable to change to root gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:269 plugins/sudoers/set_perms.c:590
+#: plugins/sudoers/set_perms.c:978 plugins/sudoers/set_perms.c:1274
+msgid "unable to change to runas gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:595
+#: plugins/sudoers/set_perms.c:983 plugins/sudoers/set_perms.c:1279
+msgid "unable to set runas group vector"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:285 plugins/sudoers/set_perms.c:606
+#: plugins/sudoers/set_perms.c:992 plugins/sudoers/set_perms.c:1288
+msgid "unable to change to runas uid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:303 plugins/sudoers/set_perms.c:624
+#: plugins/sudoers/set_perms.c:1008 plugins/sudoers/set_perms.c:1304
+msgid "unable to change to sudoers gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:356 plugins/sudoers/set_perms.c:695
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1350
+#: plugins/sudoers/set_perms.c:1514
+msgid "too many processes"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:51
+msgid "unable to get current working directory"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:59
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:66
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:115
+msgid "audit_failure message too long"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:332
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:340 plugins/sudoers/sssd.c:349
+#: plugins/sudoers/sssd.c:358 plugins/sudoers/sssd.c:367
+#: plugins/sudoers/sssd.c:376
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:290
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:308
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:326
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:339
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:172 plugins/sudoers/testsudoers.c:244
+#: plugins/sudoers/visudo.c:225 plugins/sudoers/visudo.c:562
+msgid "unable to initialize sudoers default values"
+msgstr "не удаётся инициализировать значения по умолчанию для sudoers"
+
+#: plugins/sudoers/sudoers.c:197 plugins/sudoers/sudoers.c:239
+#: plugins/sudoers/sudoers.c:833
+msgid "problem with defaults entries"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:205
+msgid "no valid sudoers sources found, quitting"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:275
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:332
+msgid "you are not permitted to use the -C option"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:396
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:410
+msgid "no tty"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:411
+msgid "sorry, you must have a tty to run sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:466
+msgid "command in current directory"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:486
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:778
+msgid "command too long"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:886 plugins/sudoers/visudo.c:428
+#: plugins/sudoers/visudo.c:662
+#, c-format
+msgid "unable to stat %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:890
+#, c-format
+msgid "%s is not a regular file"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:894 plugins/sudoers/timestamp.c:274 toke.l:933
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:898 toke.l:940
+#, c-format
+msgid "%s is world writable"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:902 toke.l:945
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:933
+#, c-format
+msgid "only root can use `-c %s'"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:952
+#, c-format
+msgid "unknown login class: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1031 plugins/sudoers/sudoers.c:1059
+#, c-format
+msgid "unable to resolve host %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1126 plugins/sudoers/testsudoers.c:384
+#, c-format
+msgid "unknown group: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:234
+#, c-format
+msgid "invalid filter option: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:247
+#, c-format
+msgid "invalid max wait: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:253
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:256 plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:288
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:294
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:310
+#, c-format
+msgid "Replaying sudo session: %s\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:316
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:317
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:369
+msgid "unable to set tty to raw mode"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:400
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:610 plugins/sudoers/sudoreplay.c:635
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:657
+msgid "unmatched ')' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:661
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:676
+#, c-format
+msgid "%s requires an argument"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:679 plugins/sudoers/sudoreplay.c:1059
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:683
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:692
+msgid "unmatched '(' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:694
+msgid "illegal trailing \"or\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:696
+msgid "illegal trailing \"!\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:745
+#, c-format
+msgid "unknown search type %d"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:783
+#, c-format
+msgid "%s: invalid log file"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:801
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:808
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:815
+#, c-format
+msgid "%s: user field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:824
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:833
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1196
+#, c-format
+msgid "usage: %s [-h] [-d dir] [-m num] [-s num] ID\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1199
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1208
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1210
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:323
+msgid "\thost unmatched"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:326
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:327
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:327
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:182
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:282
+#, c-format
+msgid "%s is group writable"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:303
+#, c-format
+msgid "timestamp path too long: %s/%s"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:362 plugins/sudoers/timestamp.c:446
+#: plugins/sudoers/visudo.c:483 plugins/sudoers/visudo.c:489
+msgid "unable to read the clock"
+msgstr "не удаётся прочитать часы"
+
+#: plugins/sudoers/timestamp.c:516
+msgid "ignoring time stamp from the future"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:528
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:638 plugins/sudoers/timestamp.c:658
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:256 plugins/sudoers/visudo.c:614
+#, c-format
+msgid "press return to edit %s: "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:321
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:337
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:445 plugins/sudoers/visudo.c:451
+msgid "write error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:496
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:503
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:509
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:531
+#, c-format
+msgid "%s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:557
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr ""
+
+#: plugins/sudoers/visudo.c:568
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:605
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:664 plugins/sudoers/visudo.c:673
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:668 plugins/sudoers/visudo.c:678
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:695
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:709
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:719
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:781
+msgid "What now? "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:795
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:843
+#, c-format
+msgid "unable to run %s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:869
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:876
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:901 plugins/sudoers/visudo_json.c:1046
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:917 plugins/sudoers/visudo_json.c:1055
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:920 plugins/sudoers/visudo_json.c:1058
+#, c-format
+msgid "parse error in %s\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:928 plugins/sudoers/visudo.c:935
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:982
+#, c-format
+msgid "%s busy, try again later"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1078
+#, c-format
+msgid "Error: cycle in %s `%s'"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1079
+#, c-format
+msgid "Warning: cycle in %s `%s'"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1083
+#, c-format
+msgid "Error: %s `%s' referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1084
+#, c-format
+msgid "Warning: %s `%s' referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1227
+#, c-format
+msgid "Warning: unused %s `%s'"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1340
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1342
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+" -x, --export=output_file write sudoers in JSON format to output_file"
+msgstr ""
+
+#: plugins/sudoers/visudo_json.c:1032
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr ""
+
+#: toke.l:904
+msgid "too many levels of includes"
+msgstr "слишком много уровней включения"
diff --git a/plugins/sudoers/po/sk.mo b/plugins/sudoers/po/sk.mo
new file mode 100644
index 0000000..069bd12
--- /dev/null
+++ b/plugins/sudoers/po/sk.mo
Binary files differ
diff --git a/plugins/sudoers/po/sk.po b/plugins/sudoers/po/sk.po
new file mode 100644
index 0000000..396072f
--- /dev/null
+++ b/plugins/sudoers/po/sk.po
@@ -0,0 +1,1892 @@
+# Portable object template file for the sudoers plugin
+# This file is put in the public domain.
+# Todd C. Miller <Todd.Miller@courtesan.com>, 2011-2015
+# Dušan Kazik <prescott66@gmail.com>, 2015
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.15b1\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2015-09-10 14:28-0600\n"
+"PO-Revision-Date: 2015-10-05 13:26+0200\n"
+"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
+"Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
+"Language: sk\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+"X-Generator: Poedit 1.8.5\n"
+"X-Poedit-Basepath: .\n"
+"X-Poedit-SearchPath-0: .\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "chyba syntaxe"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "Heslo používateľa %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] heslo pre používateľa %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Heslo: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** BEZPEČNOSTNÉ informácie pre %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Prepáčte, skúste to znovu."
+
+#: gram.y:183 gram.y:201 gram.y:207 gram.y:213 gram.y:219 gram.y:225
+#: gram.y:241 gram.y:248 gram.y:255 gram.y:262 gram.y:269 gram.y:285
+#: gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336 gram.y:391
+#: gram.y:399 gram.y:409 gram.y:439 gram.y:446 gram.y:453 gram.y:460
+#: gram.y:572 gram.y:579 gram.y:588 gram.y:597 gram.y:614 gram.y:670
+#: gram.y:677 gram.y:684 gram.y:692 gram.y:784 gram.y:791 gram.y:798
+#: gram.y:805 gram.y:812 gram.y:838 gram.y:845 gram.y:852 gram.y:1136
+#: gram.y:1143 plugins/sudoers/alias.c:123 plugins/sudoers/alias.c:136
+#: plugins/sudoers/auth/bsdauth.c:141 plugins/sudoers/auth/kerb5.c:119
+#: plugins/sudoers/auth/kerb5.c:145 plugins/sudoers/auth/pam.c:397
+#: plugins/sudoers/auth/pam.c:445 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/auth/sia.c:110 plugins/sudoers/defaults.c:516
+#: plugins/sudoers/defaults.c:720 plugins/sudoers/defaults.c:880
+#: plugins/sudoers/editor.c:64 plugins/sudoers/editor.c:82
+#: plugins/sudoers/editor.c:92 plugins/sudoers/env.c:233
+#: plugins/sudoers/group_plugin.c:133 plugins/sudoers/iolog.c:586
+#: plugins/sudoers/iolog.c:618 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:446 plugins/sudoers/ldap.c:477
+#: plugins/sudoers/ldap.c:529 plugins/sudoers/ldap.c:562
+#: plugins/sudoers/ldap.c:914 plugins/sudoers/ldap.c:1061
+#: plugins/sudoers/ldap.c:1348 plugins/sudoers/ldap.c:1521
+#: plugins/sudoers/ldap.c:1597 plugins/sudoers/ldap.c:1733
+#: plugins/sudoers/ldap.c:1757 plugins/sudoers/ldap.c:1787
+#: plugins/sudoers/ldap.c:1840 plugins/sudoers/ldap.c:1855
+#: plugins/sudoers/ldap.c:1951 plugins/sudoers/ldap.c:1984
+#: plugins/sudoers/ldap.c:2137 plugins/sudoers/ldap.c:2234
+#: plugins/sudoers/ldap.c:3041 plugins/sudoers/ldap.c:3074
+#: plugins/sudoers/ldap.c:3388 plugins/sudoers/ldap.c:3416
+#: plugins/sudoers/ldap.c:3427 plugins/sudoers/ldap.c:3517
+#: plugins/sudoers/ldap.c:3533 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:188 plugins/sudoers/logging.c:662
+#: plugins/sudoers/logging.c:916 plugins/sudoers/match.c:501
+#: plugins/sudoers/match.c:537 plugins/sudoers/match.c:699
+#: plugins/sudoers/match.c:756 plugins/sudoers/parse.c:235
+#: plugins/sudoers/parse.c:247 plugins/sudoers/parse.c:262
+#: plugins/sudoers/parse.c:274 plugins/sudoers/policy.c:384
+#: plugins/sudoers/policy.c:579 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/sssd.c:160 plugins/sudoers/sssd.c:192
+#: plugins/sudoers/sssd.c:235 plugins/sudoers/sssd.c:242
+#: plugins/sudoers/sssd.c:278 plugins/sudoers/sssd.c:323
+#: plugins/sudoers/sssd.c:917 plugins/sudoers/sssd.c:1050
+#: plugins/sudoers/sudoers.c:159 plugins/sudoers/sudoers.c:294
+#: plugins/sudoers/sudoers.c:304 plugins/sudoers/sudoers.c:312
+#: plugins/sudoers/sudoers.c:365 plugins/sudoers/sudoers.c:663
+#: plugins/sudoers/sudoers.c:749 plugins/sudoers/sudoers.c:793
+#: plugins/sudoers/sudoers_debug.c:107 plugins/sudoers/sudoreplay.c:472
+#: plugins/sudoers/sudoreplay.c:668 plugins/sudoers/sudoreplay.c:780
+#: plugins/sudoers/sudoreplay.c:820 plugins/sudoers/sudoreplay.c:829
+#: plugins/sudoers/sudoreplay.c:839 plugins/sudoers/sudoreplay.c:847
+#: plugins/sudoers/sudoreplay.c:851 plugins/sudoers/sudoreplay.c:1007
+#: plugins/sudoers/sudoreplay.c:1011 plugins/sudoers/testsudoers.c:130
+#: plugins/sudoers/testsudoers.c:188 plugins/sudoers/testsudoers.c:215
+#: plugins/sudoers/testsudoers.c:232 plugins/sudoers/timestamp.c:390
+#: plugins/sudoers/timestamp.c:426 plugins/sudoers/timestamp.c:838
+#: plugins/sudoers/toke_util.c:56 plugins/sudoers/toke_util.c:109
+#: plugins/sudoers/toke_util.c:147 plugins/sudoers/visudo.c:152
+#: plugins/sudoers/visudo.c:213 plugins/sudoers/visudo.c:297
+#: plugins/sudoers/visudo.c:303 plugins/sudoers/visudo.c:433
+#: plugins/sudoers/visudo.c:974 plugins/sudoers/visudo.c:1018
+#: plugins/sudoers/visudo.c:1114 toke.l:785 toke.l:806 toke.l:816 toke.l:924
+#: toke.l:1082
+msgid "unable to allocate memory"
+msgstr "nie je možné alokovať pamäť"
+
+#: gram.y:471
+msgid "a digest requires a path name"
+msgstr ""
+
+#: gram.y:1136 gram.y:1143 plugins/sudoers/auth/pam.c:397
+#: plugins/sudoers/auth/pam.c:445 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/defaults.c:516 plugins/sudoers/defaults.c:720
+#: plugins/sudoers/defaults.c:880 plugins/sudoers/editor.c:64
+#: plugins/sudoers/editor.c:82 plugins/sudoers/editor.c:92
+#: plugins/sudoers/env.c:233 plugins/sudoers/group_plugin.c:133
+#: plugins/sudoers/iolog.c:586 plugins/sudoers/iolog.c:618
+#: plugins/sudoers/iolog_path.c:167 plugins/sudoers/ldap.c:446
+#: plugins/sudoers/ldap.c:477 plugins/sudoers/ldap.c:529
+#: plugins/sudoers/ldap.c:562 plugins/sudoers/ldap.c:914
+#: plugins/sudoers/ldap.c:1061 plugins/sudoers/ldap.c:1348
+#: plugins/sudoers/ldap.c:1521 plugins/sudoers/ldap.c:1597
+#: plugins/sudoers/ldap.c:1733 plugins/sudoers/ldap.c:1757
+#: plugins/sudoers/ldap.c:1787 plugins/sudoers/ldap.c:1840
+#: plugins/sudoers/ldap.c:1855 plugins/sudoers/ldap.c:1951
+#: plugins/sudoers/ldap.c:1984 plugins/sudoers/ldap.c:2137
+#: plugins/sudoers/ldap.c:2234 plugins/sudoers/ldap.c:3041
+#: plugins/sudoers/ldap.c:3074 plugins/sudoers/ldap.c:3388
+#: plugins/sudoers/ldap.c:3416 plugins/sudoers/ldap.c:3427
+#: plugins/sudoers/ldap.c:3517 plugins/sudoers/ldap.c:3533
+#: plugins/sudoers/linux_audit.c:76 plugins/sudoers/logging.c:188
+#: plugins/sudoers/logging.c:916 plugins/sudoers/match.c:501
+#: plugins/sudoers/match.c:537 plugins/sudoers/match.c:699
+#: plugins/sudoers/match.c:756 plugins/sudoers/parse.c:235
+#: plugins/sudoers/parse.c:247 plugins/sudoers/parse.c:262
+#: plugins/sudoers/parse.c:274 plugins/sudoers/policy.c:97
+#: plugins/sudoers/policy.c:106 plugins/sudoers/policy.c:115
+#: plugins/sudoers/policy.c:139 plugins/sudoers/policy.c:250
+#: plugins/sudoers/policy.c:271 plugins/sudoers/policy.c:280
+#: plugins/sudoers/policy.c:319 plugins/sudoers/policy.c:329
+#: plugins/sudoers/policy.c:338 plugins/sudoers/policy.c:384
+#: plugins/sudoers/policy.c:579 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/set_perms.c:356 plugins/sudoers/set_perms.c:695
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1350
+#: plugins/sudoers/set_perms.c:1514 plugins/sudoers/sssd.c:160
+#: plugins/sudoers/sssd.c:192 plugins/sudoers/sssd.c:235
+#: plugins/sudoers/sssd.c:242 plugins/sudoers/sssd.c:278
+#: plugins/sudoers/sssd.c:323 plugins/sudoers/sssd.c:917
+#: plugins/sudoers/sssd.c:1050 plugins/sudoers/sudoers.c:159
+#: plugins/sudoers/sudoers.c:294 plugins/sudoers/sudoers.c:304
+#: plugins/sudoers/sudoers.c:312 plugins/sudoers/sudoers.c:365
+#: plugins/sudoers/sudoers.c:663 plugins/sudoers/sudoers.c:749
+#: plugins/sudoers/sudoers.c:793 plugins/sudoers/sudoers_debug.c:106
+#: plugins/sudoers/sudoreplay.c:472 plugins/sudoers/sudoreplay.c:668
+#: plugins/sudoers/sudoreplay.c:780 plugins/sudoers/sudoreplay.c:820
+#: plugins/sudoers/sudoreplay.c:829 plugins/sudoers/sudoreplay.c:839
+#: plugins/sudoers/sudoreplay.c:847 plugins/sudoers/sudoreplay.c:851
+#: plugins/sudoers/sudoreplay.c:1007 plugins/sudoers/sudoreplay.c:1011
+#: plugins/sudoers/testsudoers.c:130 plugins/sudoers/testsudoers.c:188
+#: plugins/sudoers/testsudoers.c:215 plugins/sudoers/testsudoers.c:232
+#: plugins/sudoers/timestamp.c:390 plugins/sudoers/timestamp.c:426
+#: plugins/sudoers/timestamp.c:838 plugins/sudoers/toke_util.c:56
+#: plugins/sudoers/toke_util.c:109 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/visudo.c:152 plugins/sudoers/visudo.c:213
+#: plugins/sudoers/visudo.c:297 plugins/sudoers/visudo.c:303
+#: plugins/sudoers/visudo.c:433 plugins/sudoers/visudo.c:974
+#: plugins/sudoers/visudo.c:1018 plugins/sudoers/visudo.c:1114 toke.l:785
+#: toke.l:806 toke.l:816 toke.l:924 toke.l:1082
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:132
+#, c-format
+msgid "Alias `%s' already defined"
+msgstr "Alias „%s“ už je definovaný"
+
+#: plugins/sudoers/auth/bsdauth.c:68
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:73
+msgid "unable to begin bsd authentication"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:81
+msgid "invalid authentication type"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:90
+msgid "unable to initialize BSD authentication"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:52
+msgid "unable to read fwtk config"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to connect to authentication server"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:63 plugins/sudoers/auth/fwtk.c:87
+#: plugins/sudoers/auth/fwtk.c:120
+msgid "lost connection to authentication server"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:67
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:111
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:161
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:170
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:232
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:245
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:248
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:312
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:326
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:92
+msgid "unable to initialize PAM"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:164
+msgid "account validation failure, is your account locked?"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:168
+msgid "Account or password is expired, reset your password and try again"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:176
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:181
+msgid "Password expired, contact your system administrator"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:185
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:199
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/rfc1938.c:97 plugins/sudoers/visudo.c:218
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:73
+msgid "failed to initialise the ACE API library"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:99
+msgid "unable to contact the SecurID server"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:108
+msgid "User ID locked for SecurID Authentication"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:112 plugins/sudoers/auth/securid5.c:163
+msgid "invalid username length for SecurID"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:116 plugins/sudoers/auth/securid5.c:168
+msgid "invalid Authentication Handle for SecurID"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:120
+msgid "SecurID communication failed"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:207
+msgid "unknown SecurID error"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:158
+msgid "invalid passcode length for SecurID"
+msgstr ""
+
+#: plugins/sudoers/auth/sia.c:120
+msgid "unable to initialize SIA session"
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:126
+msgid "invalid authentication methods"
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:128
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:225 plugins/sudoers/auth/sudo_auth.c:274
+msgid "no authentication methods"
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:227
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:276
+msgid "Unable to initialize authentication methods."
+msgstr "Nie je možné inicializovať spôsoby overenia totožnosti."
+
+#: plugins/sudoers/auth/sudo_auth.c:435
+msgid "Authentication methods:"
+msgstr "Spôsoby overenia totožnosti:"
+
+#: plugins/sudoers/bsm_audit.c:111 plugins/sudoers/bsm_audit.c:200
+msgid "Could not determine audit condition"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:172 plugins/sudoers/bsm_audit.c:260
+msgid "unable to commit audit record"
+msgstr ""
+
+#: plugins/sudoers/check.c:250
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Veríme, že ste boli poučený miestnym správcom systému.\n"
+"Dodržiavajte tieto tri zásady:\n"
+"\n"
+" 1.) Rešpektujte súkromie iných.\n"
+" 2.) Premýšľajte pred tým, než niečo napíšete.\n"
+" 3.) S veľkou mocou prichádza veľká zodpovednosť.\n"
+"\n"
+
+#: plugins/sudoers/check.c:293 plugins/sudoers/check.c:303
+#: plugins/sudoers/sudoers.c:699 plugins/sudoers/sudoers.c:728
+#, c-format
+msgid "unknown uid: %u"
+msgstr ""
+
+#: plugins/sudoers/check.c:298 plugins/sudoers/policy.c:751
+#: plugins/sudoers/sudoers.c:1095 plugins/sudoers/testsudoers.c:206
+#: plugins/sudoers/testsudoers.c:361
+#, c-format
+msgid "unknown user: %s"
+msgstr "neznámy používateľ: %s"
+
+#: plugins/sudoers/def_data.c:27
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:31
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:35
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:39
+msgid "Put OTP prompt on its own line"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:43
+msgid "Ignore '.' in $PATH"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:47
+msgid "Always send mail when sudo is run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:51
+msgid "Send mail if user authentication fails"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:55
+msgid "Send mail if the user is not in sudoers"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:59
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:63
+msgid "Send mail if the user is not allowed to run a command"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:67
+msgid "Send mail if the user tries to run a command"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:71
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:75
+msgid "Lecture user the first time they run sudo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:79
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:83
+msgid "Require users to authenticate by default"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:87
+msgid "Root may run sudo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:91
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:95
+msgid "Log the year in the (non-syslog) log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:99
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:103
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:107
+msgid "Always set $HOME to the target user's home directory"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:111
+msgid "Allow some information gathering to give useful error messages"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:115
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:119
+msgid "Insult the user when they enter an incorrect password"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:123
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:127
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:131
+msgid "Prompt for root's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:135
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:139
+msgid "Prompt for the target user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:143
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:147
+msgid "Set the LOGNAME and USER environment variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:151
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:155
+msgid "Don't initialize the group vector to that of the target user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:159
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:163
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:167
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:171
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:175
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:179
+#, c-format
+msgid "Path to log file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:183
+#, c-format
+msgid "Path to mail program: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:187
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:191
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:195
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:199
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:203
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:207
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:211
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:215
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:219
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:223
+#, c-format
+msgid "Default password prompt: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:227
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr ""
+
+#: plugins/sudoers/def_data.c:231
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:235
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:239
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:243
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:247
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:251
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:255
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:259
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:263
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:267
+msgid "Allow users to set arbitrary environment variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:271
+msgid "Reset the environment to a default set of variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:275
+msgid "Environment variables to check for sanity:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:279
+msgid "Environment variables to remove:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:283
+msgid "Environment variables to preserve:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:287
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:291
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:295
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:299
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:303
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:307
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:311
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:315
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:319
+msgid "Log user's input for the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:323
+msgid "Log the output of the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:327
+msgid "Compress I/O logs using zlib"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:331
+msgid "Always run commands in a pseudo-tty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:335
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:339
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:343
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:347
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:351
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:355
+msgid "Set of permitted privileges"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:359
+msgid "Set of limit privileges"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:363
+msgid "Run commands on a pty in the background"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:367
+msgid "PAM service name to use"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:371
+msgid "PAM service name to use for login shells"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:375
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:379
+msgid "Create a new PAM session for the command to run in"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:383
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:387
+msgid "Enable sudoers netgroup support"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:391
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:199 plugins/sudoers/defaults.c:608
+#: plugins/sudoers/visudo_json.c:633 plugins/sudoers/visudo_json.c:668
+#, c-format
+msgid "unknown defaults entry `%s'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:207 plugins/sudoers/defaults.c:217
+#: plugins/sudoers/defaults.c:241 plugins/sudoers/defaults.c:256
+#: plugins/sudoers/defaults.c:269 plugins/sudoers/defaults.c:282
+#: plugins/sudoers/defaults.c:295 plugins/sudoers/defaults.c:315
+#: plugins/sudoers/defaults.c:325
+#, c-format
+msgid "value `%s' is invalid for option `%s'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:210 plugins/sudoers/defaults.c:220
+#: plugins/sudoers/defaults.c:228 plugins/sudoers/defaults.c:251
+#: plugins/sudoers/defaults.c:264 plugins/sudoers/defaults.c:277
+#: plugins/sudoers/defaults.c:290 plugins/sudoers/defaults.c:310
+#: plugins/sudoers/defaults.c:321
+#, c-format
+msgid "no value specified for `%s'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:233
+#, c-format
+msgid "values for `%s' must start with a '/'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "option `%s' does not take a value"
+msgstr ""
+
+#: plugins/sudoers/env.c:295 plugins/sudoers/env.c:302
+#: plugins/sudoers/env.c:407 plugins/sudoers/ldap.c:450
+#: plugins/sudoers/ldap.c:540 plugins/sudoers/ldap.c:1152
+#: plugins/sudoers/ldap.c:1354 plugins/sudoers/ldap.c:1526
+#: plugins/sudoers/ldap.c:1682 plugins/sudoers/linux_audit.c:82
+#: plugins/sudoers/logging.c:921 plugins/sudoers/policy.c:498
+#: plugins/sudoers/policy.c:507 plugins/sudoers/prompt.c:161
+#: plugins/sudoers/sudoers.c:815 plugins/sudoers/testsudoers.c:236
+#: plugins/sudoers/toke_util.c:160
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "vnútorná chyba, %s pretečenie"
+
+#: plugins/sudoers/env.c:376
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr ""
+
+#: plugins/sudoers/env.c:1052
+msgid "unable to rebuild the environment"
+msgstr ""
+
+#: plugins/sudoers/env.c:1126
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:85
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s musí byť vlastnený identifikátorom uid %d"
+
+#: plugins/sudoers/group_plugin.c:89
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:97 plugins/sudoers/sssd.c:331
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "nie je možné načítať %s:%s"
+
+#: plugins/sudoers/group_plugin.c:103
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:108
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:117
+msgid "Local IP address and netmask pairs:\n"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:92 plugins/sudoers/iolog.c:110
+#: plugins/sudoers/timestamp.c:169
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:103 plugins/sudoers/iolog.c:124
+#: plugins/sudoers/iolog.c:131 plugins/sudoers/timestamp.c:163
+#: plugins/sudoers/timestamp.c:184
+#, c-format
+msgid "unable to mkdir %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:200 plugins/sudoers/sudoers.c:871
+#: plugins/sudoers/sudoreplay.c:300 plugins/sudoers/sudoreplay.c:769
+#: plugins/sudoers/sudoreplay.c:973 plugins/sudoers/timestamp.c:399
+#: plugins/sudoers/visudo.c:898 plugins/sudoers/visudo_json.c:1012
+#: plugins/sudoers/visudo_json.c:1025
+#, c-format
+msgid "unable to open %s"
+msgstr "nie je možné otvoriť %s"
+
+#: plugins/sudoers/iolog.c:241 plugins/sudoers/sudoers.c:875
+#: plugins/sudoers/sudoreplay.c:1084
+#, c-format
+msgid "unable to read %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:277 plugins/sudoers/sudoreplay.c:550
+#: plugins/sudoers/timestamp.c:298 plugins/sudoers/timestamp.c:301
+#, c-format
+msgid "unable to write to %s"
+msgstr "nie je možné zapísať do %s"
+
+#: plugins/sudoers/iolog.c:342 plugins/sudoers/iolog.c:540
+#, c-format
+msgid "unable to create %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:428
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:488
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:515
+msgid "unable to mix ldap and ldaps URIs"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:519 plugins/sudoers/ldap.c:555
+msgid "starttls not supported when using ldaps"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:626
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:629
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1138
+msgid "unable to get GMT time"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1144
+msgid "unable to format timestamp"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1830
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2372
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2374
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2421
+#, c-format
+msgid " Order: %s\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2429 plugins/sudoers/parse.c:555
+#: plugins/sudoers/sssd.c:1417
+#, c-format
+msgid " Commands:\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2993
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:3029
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:3286
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:52
+msgid "unable to open audit system"
+msgstr "nie je možné otvoriť systém auditu"
+
+#: plugins/sudoers/linux_audit.c:93
+msgid "unable to send audit message"
+msgstr "nie je možné odoslať správu auditu"
+
+#: plugins/sudoers/logging.c:106
+#, c-format
+msgid "%8s : %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:134
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:159
+#, c-format
+msgid "unable to open log file: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:162
+#, c-format
+msgid "unable to lock log file: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:211
+msgid "No user or host"
+msgstr ""
+
+#: plugins/sudoers/logging.c:213
+msgid "validation failure"
+msgstr ""
+
+#: plugins/sudoers/logging.c:220
+msgid "user NOT in sudoers"
+msgstr ""
+
+#: plugins/sudoers/logging.c:222
+msgid "user NOT authorized on host"
+msgstr ""
+
+#: plugins/sudoers/logging.c:224
+msgid "command not allowed"
+msgstr ""
+
+#: plugins/sudoers/logging.c:259
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:262
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:266
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:269
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:306 plugins/sudoers/sudoers.c:471
+#: plugins/sudoers/sudoers.c:473 plugins/sudoers/sudoers.c:475
+#: plugins/sudoers/sudoers.c:477 plugins/sudoers/sudoers.c:1222
+#: plugins/sudoers/sudoers.c:1224
+#, c-format
+msgid "%s: command not found"
+msgstr ""
+
+#: plugins/sudoers/logging.c:308 plugins/sudoers/sudoers.c:467
+#, c-format
+msgid ""
+"ignoring `%s' found in '.'\n"
+"Use `sudo ./%s' if this is the `%s' you wish to run."
+msgstr ""
+
+#: plugins/sudoers/logging.c:325
+msgid "authentication failure"
+msgstr ""
+
+#: plugins/sudoers/logging.c:351
+msgid "a password is required"
+msgstr ""
+
+#: plugins/sudoers/logging.c:422 plugins/sudoers/logging.c:484
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#: plugins/sudoers/logging.c:572
+msgid "unable to fork"
+msgstr ""
+
+#: plugins/sudoers/logging.c:580 plugins/sudoers/logging.c:636
+#, c-format
+msgid "unable to fork: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:626
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:651
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:689
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr ""
+
+#: plugins/sudoers/match.c:606
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr ""
+
+#: plugins/sudoers/match.c:639
+#, c-format
+msgid "%s: read error"
+msgstr ""
+
+#: plugins/sudoers/match.c:653
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr ""
+
+#: plugins/sudoers/parse.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr ""
+
+#: plugins/sudoers/parse.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr ""
+
+#: plugins/sudoers/parse.c:502
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+
+#: plugins/sudoers/parse.c:503
+#, c-format
+msgid " RunAsUsers: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:517
+#, c-format
+msgid " RunAsGroups: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:526
+#, c-format
+msgid " Options: "
+msgstr ""
+
+#: plugins/sudoers/policy.c:240 plugins/sudoers/testsudoers.c:253
+msgid "unable to parse network address list"
+msgstr ""
+
+#: plugins/sudoers/policy.c:636 plugins/sudoers/visudo.c:839
+#, c-format
+msgid "unable to execute %s"
+msgstr "nie je možné vykonať %s"
+
+#: plugins/sudoers/policy.c:769
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:771
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:775
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:778
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:780
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:781
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:814
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:136 plugins/sudoers/pwutil.c:153
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:147
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:191 plugins/sudoers/pwutil.c:207
+#: plugins/sudoers/pwutil.c:250 plugins/sudoers/pwutil.c:294
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:202
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:427 plugins/sudoers/pwutil.c:444
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:438
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:476 plugins/sudoers/pwutil.c:492
+#: plugins/sudoers/pwutil.c:524 plugins/sudoers/pwutil.c:565
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:487
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:676 plugins/sudoers/pwutil.c:710
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:682 plugins/sudoers/pwutil.c:715
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:705
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:113 plugins/sudoers/set_perms.c:438
+#: plugins/sudoers/set_perms.c:841 plugins/sudoers/set_perms.c:1138
+#: plugins/sudoers/set_perms.c:1430
+msgid "perm stack overflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:121 plugins/sudoers/set_perms.c:369
+#: plugins/sudoers/set_perms.c:446 plugins/sudoers/set_perms.c:708
+#: plugins/sudoers/set_perms.c:849 plugins/sudoers/set_perms.c:1067
+#: plugins/sudoers/set_perms.c:1146 plugins/sudoers/set_perms.c:1363
+#: plugins/sudoers/set_perms.c:1438 plugins/sudoers/set_perms.c:1527
+msgid "perm stack underflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:180 plugins/sudoers/set_perms.c:493
+#: plugins/sudoers/set_perms.c:1197 plugins/sudoers/set_perms.c:1470
+msgid "unable to change to root gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:269 plugins/sudoers/set_perms.c:590
+#: plugins/sudoers/set_perms.c:978 plugins/sudoers/set_perms.c:1274
+msgid "unable to change to runas gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:595
+#: plugins/sudoers/set_perms.c:983 plugins/sudoers/set_perms.c:1279
+msgid "unable to set runas group vector"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:285 plugins/sudoers/set_perms.c:606
+#: plugins/sudoers/set_perms.c:992 plugins/sudoers/set_perms.c:1288
+msgid "unable to change to runas uid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:303 plugins/sudoers/set_perms.c:624
+#: plugins/sudoers/set_perms.c:1008 plugins/sudoers/set_perms.c:1304
+msgid "unable to change to sudoers gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:356 plugins/sudoers/set_perms.c:695
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1350
+#: plugins/sudoers/set_perms.c:1514
+msgid "too many processes"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:51
+msgid "unable to get current working directory"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:59
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:66
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:115
+msgid "audit_failure message too long"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:333
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:341 plugins/sudoers/sssd.c:350
+#: plugins/sudoers/sssd.c:359 plugins/sudoers/sssd.c:368
+#: plugins/sudoers/sssd.c:377
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:290
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:308
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:326
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:339
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:172 plugins/sudoers/testsudoers.c:245
+#: plugins/sudoers/visudo.c:223 plugins/sudoers/visudo.c:565
+msgid "unable to initialize sudoers default values"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:197 plugins/sudoers/sudoers.c:239
+#: plugins/sudoers/sudoers.c:833
+msgid "problem with defaults entries"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:205
+msgid "no valid sudoers sources found, quitting"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:275
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:332
+msgid "you are not permitted to use the -C option"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:396
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:410
+msgid "no tty"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:411
+msgid "sorry, you must have a tty to run sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:466
+msgid "command in current directory"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:486
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:778
+msgid "command too long"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:886 plugins/sudoers/visudo.c:426
+#: plugins/sudoers/visudo.c:665
+#, c-format
+msgid "unable to stat %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:890
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s nie je regulárny súbor"
+
+#: plugins/sudoers/sudoers.c:894 plugins/sudoers/timestamp.c:225 toke.l:947
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s je vlastnený identifikátorom uid %u a mal by byť vlastnený %u"
+
+#: plugins/sudoers/sudoers.c:898 toke.l:954
+#, c-format
+msgid "%s is world writable"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:902 toke.l:959
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:933
+#, c-format
+msgid "only root can use `-c %s'"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:952
+#, c-format
+msgid "unknown login class: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1031 plugins/sudoers/sudoers.c:1059
+#, c-format
+msgid "unable to resolve host %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1126 plugins/sudoers/testsudoers.c:385
+#, c-format
+msgid "unknown group: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:232
+#, c-format
+msgid "invalid filter option: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:245
+#, c-format
+msgid "invalid max wait: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:251
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:254 plugins/sudoers/visudo.c:180
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s verzia %s\n"
+
+#: plugins/sudoers/sudoreplay.c:286
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:292
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:308
+#, c-format
+msgid "Replaying sudo session: %s\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:314
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:315
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:368
+msgid "unable to set tty to raw mode"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:401
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:611 plugins/sudoers/sudoreplay.c:636
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:658
+msgid "unmatched ')' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:662
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:677
+#, c-format
+msgid "%s requires an argument"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:680 plugins/sudoers/sudoreplay.c:1060
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:684
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:693
+msgid "unmatched '(' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:695
+msgid "illegal trailing \"or\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:697
+msgid "illegal trailing \"!\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:746
+#, c-format
+msgid "unknown search type %d"
+msgstr "neznámy typ vyhľadávania %d"
+
+#: plugins/sudoers/sudoreplay.c:784
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: neplatný súbor záznamu"
+
+#: plugins/sudoers/sudoreplay.c:802
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: chýba pole časovej značky"
+
+#: plugins/sudoers/sudoreplay.c:809
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: časová značka %s: %s"
+
+#: plugins/sudoers/sudoreplay.c:816
+#, c-format
+msgid "%s: user field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:825
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:834
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1197
+#, c-format
+msgid "usage: %s [-h] [-d dir] [-m num] [-s num] ID\n"
+msgstr "použitie: %s [-h] [-d adresár] [-m číslo] [-s číslo] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1200
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "použitie: %s [-h] [-d adresár] -l [hľadaný výraz]\n"
+
+#: plugins/sudoers/sudoreplay.c:1209
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1211
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Voľby:\n"
+" -d, --directory=adresárr určí adresár pre záznamy relácie\n"
+" -f, --filter=filter určuje, ktoré vstupno-výstupné typy sa majú zorbaziť\n"
+" -h, --help zorbazí správu pomocníka a skončí\n"
+" -l, --list vypíše identifikátory dostupných relácií, s voliteľným výrazom\n"
+" -m, --max-wait=číslo maximálny počet sekúnd čakania medzi udalosťami\n"
+" -s, --speed=číslo zrýchli alebo spomalí výstup\n"
+" -V, --version zobrazí informácie o verzii a skončí"
+
+#: plugins/sudoers/testsudoers.c:324
+msgid "\thost unmatched"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:327
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Príkaz povolený"
+
+#: plugins/sudoers/testsudoers.c:328
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Príkaz odmietnutý"
+
+#: plugins/sudoers/testsudoers.c:328
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Príkaz nevyhovujúci"
+
+#: plugins/sudoers/timestamp.c:233
+#, c-format
+msgid "%s is group writable"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:309
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:742 plugins/sudoers/timestamp.c:809
+#: plugins/sudoers/visudo.c:486 plugins/sudoers/visudo.c:492
+msgid "unable to read the clock"
+msgstr "nie je možné čítať hodiny"
+
+#: plugins/sudoers/timestamp.c:756
+msgid "ignoring time stamp from the future"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:768
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:863
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:906 plugins/sudoers/timestamp.c:926
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:254 plugins/sudoers/visudo.c:617
+#, c-format
+msgid "press return to edit %s: "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:319
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:337
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:446 plugins/sudoers/visudo.c:454
+msgid "write error"
+msgstr "chyba zápisu"
+
+#: plugins/sudoers/visudo.c:499
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:506
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:512
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:534
+#, c-format
+msgid "%s unchanged"
+msgstr "%s nezmenený"
+
+#: plugins/sudoers/visudo.c:560
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr ""
+
+#: plugins/sudoers/visudo.c:571
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:608
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:667 plugins/sudoers/visudo.c:676
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:671 plugins/sudoers/visudo.c:681
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:698
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:712
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:722
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:784
+msgid "What now? "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:798
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:846
+#, c-format
+msgid "unable to run %s"
+msgstr "nie je možné spustiť %s"
+
+#: plugins/sudoers/visudo.c:872
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:879
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:904 plugins/sudoers/visudo_json.c:1032
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:920 plugins/sudoers/visudo_json.c:1041
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:923 plugins/sudoers/visudo_json.c:1044
+#, c-format
+msgid "parse error in %s\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:931 plugins/sudoers/visudo.c:938
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:985
+#, c-format
+msgid "%s busy, try again later"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1081
+#, c-format
+msgid "Error: cycle in %s `%s'"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1082
+#, c-format
+msgid "Warning: cycle in %s `%s'"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1086
+#, c-format
+msgid "Error: %s `%s' referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1087
+#, c-format
+msgid "Warning: %s `%s' referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1230
+#, c-format
+msgid "Warning: unused %s `%s'"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1343
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - bezpečne upraví súbor sudoers\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1345
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+" -x, --export=output_file write sudoers in JSON format to output_file"
+msgstr ""
+
+#: plugins/sudoers/visudo_json.c:1018
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr ""
+
+#: toke.l:918
+msgid "too many levels of includes"
+msgstr ""
diff --git a/plugins/sudoers/po/sl.mo b/plugins/sudoers/po/sl.mo
new file mode 100644
index 0000000..3b19398
--- /dev/null
+++ b/plugins/sudoers/po/sl.mo
Binary files differ
diff --git a/plugins/sudoers/po/sl.po b/plugins/sudoers/po/sl.po
new file mode 100644
index 0000000..55d6733
--- /dev/null
+++ b/plugins/sudoers/po/sl.po
@@ -0,0 +1,1758 @@
+# Slovenian translation of sudo.
+# This file is put in the public domain.
+# This file is distributed under the same license as the sudo package.
+#
+# Damir Jerovšek <damir.jerovsek@gmail.com>, 2012.
+# Klemen Košir <klemen.kosir@gmx.com>, 2012 - 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.7b1\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2013-04-02 10:40-0400\n"
+"PO-Revision-Date: 2013-04-06 09:44+0100\n"
+"Last-Translator: Klemen Košir <klemen913@gmail.com>\n"
+"Language-Team: Slovenian <translation-team-sl@lists.sourceforge.net>\n"
+"Language: sl\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n%100==4 ? 3 : 0);\n"
+"X-Generator: Poedit 1.5.5\n"
+
+#: confstr.sh:2 plugins/sudoers/auth/pam.c:340
+msgid "Password:"
+msgstr "Geslo:"
+
+#: confstr.sh:3
+msgid "*** SECURITY information for %h ***"
+msgstr "*** Varnostni podatki za %h ***"
+
+#: confstr.sh:4
+msgid "Sorry, try again."
+msgstr "Prosimo, poskusite znova."
+
+#: plugins/sudoers/alias.c:124
+#, c-format
+msgid "Alias `%s' already defined"
+msgstr "Vzdevek `%s' je že določen"
+
+#: plugins/sudoers/auth/bsdauth.c:77
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "prijavnega razreda uporabnika %s ni mogoče pridobiti"
+
+#: plugins/sudoers/auth/bsdauth.c:83
+msgid "unable to begin bsd authentication"
+msgstr "ni mogoče začeti overitve bsd"
+
+#: plugins/sudoers/auth/bsdauth.c:91
+msgid "invalid authentication type"
+msgstr "neveljavna vrsta overitve"
+
+#: plugins/sudoers/auth/bsdauth.c:100
+msgid "unable to setup authentication"
+msgstr "ni mogoče nastaviti overitve"
+
+#: plugins/sudoers/auth/fwtk.c:59
+#, c-format
+msgid "unable to read fwtk config"
+msgstr "ni mogoče brati nastavitev fwtk"
+
+#: plugins/sudoers/auth/fwtk.c:64
+#, c-format
+msgid "unable to connect to authentication server"
+msgstr "ni se mogoče povezati s strežnikom overitve"
+
+#: plugins/sudoers/auth/fwtk.c:70 plugins/sudoers/auth/fwtk.c:94
+#: plugins/sudoers/auth/fwtk.c:127
+#, c-format
+msgid "lost connection to authentication server"
+msgstr "povezava s strežnikom overitve je bila izgubljena"
+
+#: plugins/sudoers/auth/fwtk.c:74
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"napaka strežnika overitve:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:116
+#, c-format
+msgid "%s: unable to unparse princ ('%s'): %s"
+msgstr "%s: ni mogoče odrazčleniti princ ('%s'): %s"
+
+#: plugins/sudoers/auth/kerb5.c:159
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: ni mogoče razčleniti '%s': %s"
+
+#: plugins/sudoers/auth/kerb5.c:169
+#, c-format
+msgid "%s: unable to resolve ccache: %s"
+msgstr "%s: ni mogoče razrešiti ccache: %s"
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: ni mogoče dodeliti možnosti: %s"
+
+#: plugins/sudoers/auth/kerb5.c:233
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: ni mogoče dobiti poverila: %s"
+
+#: plugins/sudoers/auth/kerb5.c:246
+#, c-format
+msgid "%s: unable to initialize ccache: %s"
+msgstr "%s: ni mogoče začeti ccache: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store cred in ccache: %s"
+msgstr "%s: ni mogoče shraniti cred v ccache: %s"
+
+#: plugins/sudoers/auth/kerb5.c:315
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: ni mogoče pridobiti predstojnika gostitve: %s"
+
+#: plugins/sudoers/auth/kerb5.c:330
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: ni mogoče preveriti TGT! Možen napad!: %s"
+
+#: plugins/sudoers/auth/pam.c:100
+msgid "unable to initialize PAM"
+msgstr "ni mogoče začeti PAM"
+
+#: plugins/sudoers/auth/pam.c:145
+msgid "account validation failure, is your account locked?"
+msgstr "potrditev veljavnosti računa je spodletela, je vaš račun zaklenjen?"
+
+#: plugins/sudoers/auth/pam.c:149
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Geslo ali račun je potekel, ponastavite svoje geslo in poskusite znova"
+
+#: plugins/sudoers/auth/pam.c:156
+#, c-format
+msgid "pam_chauthtok: %s"
+msgstr "pam_chauthtok: %s"
+
+#: plugins/sudoers/auth/pam.c:160
+msgid "Password expired, contact your system administrator"
+msgstr "Veljavnost gesla je potekla. Stopite v stik s svojim sistemskim skrbnikom"
+
+#: plugins/sudoers/auth/pam.c:164
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Račun je potekel ali pa nastavitvam PAM primanjkuje odsek \"account\" za sudo, obrnite se na sistemskega skrbnika"
+
+#: plugins/sudoers/auth/pam.c:181
+#, c-format
+msgid "pam_authenticate: %s"
+msgstr "pam_authenticate: %s"
+
+#: plugins/sudoers/auth/pam.c:339
+msgid "Password: "
+msgstr "Geslo: "
+
+#: plugins/sudoers/auth/rfc1938.c:103 plugins/sudoers/visudo.c:212
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "ne obstajate v podatkovni zbirki %s"
+
+#: plugins/sudoers/auth/securid5.c:80
+#, c-format
+msgid "failed to initialise the ACE API library"
+msgstr "začenjanje knjižnice ACE API je spodletelo"
+
+#: plugins/sudoers/auth/securid5.c:106
+#, c-format
+msgid "unable to contact the SecurID server"
+msgstr "ni mogoče navezati stika s strežnikom SecurID"
+
+#: plugins/sudoers/auth/securid5.c:115
+#, c-format
+msgid "User ID locked for SecurID Authentication"
+msgstr "ID uporabnika je zaklenjen zaradi overitve SecurID"
+
+#: plugins/sudoers/auth/securid5.c:119 plugins/sudoers/auth/securid5.c:170
+#, c-format
+msgid "invalid username length for SecurID"
+msgstr "neveljavna dolžina imena uporabnika za SecurID"
+
+#: plugins/sudoers/auth/securid5.c:123 plugins/sudoers/auth/securid5.c:175
+#, c-format
+msgid "invalid Authentication Handle for SecurID"
+msgstr "neveljavna ročica overitve za SecurID"
+
+#: plugins/sudoers/auth/securid5.c:127
+#, c-format
+msgid "SecurID communication failed"
+msgstr "sporazumevanje SecurID je spodletelo"
+
+#: plugins/sudoers/auth/securid5.c:131 plugins/sudoers/auth/securid5.c:214
+#, c-format
+msgid "unknown SecurID error"
+msgstr "neznana napaka SecurID"
+
+#: plugins/sudoers/auth/securid5.c:165
+#, c-format
+msgid "invalid passcode length for SecurID"
+msgstr "neveljavna dolžina gesla za SecurID"
+
+#: plugins/sudoers/auth/sia.c:108
+msgid "unable to initialize SIA session"
+msgstr "ni mogoče začeti seje SIA"
+
+#: plugins/sudoers/auth/sudo_auth.c:119
+msgid "invalid authentication methods"
+msgstr "neveljavni načini overitve"
+
+#: plugins/sudoers/auth/sudo_auth.c:120
+msgid "Invalid authentication methods compiled into sudo! You may mix standalone and non-standalone authentication."
+msgstr "Neveljavni načini overitve so kodno prevedeni v sudo! Mešate lahko samostojno in nesamostojno overjanje."
+
+#: plugins/sudoers/auth/sudo_auth.c:203
+msgid "no authentication methods"
+msgstr "ni načinov overjanja"
+
+#: plugins/sudoers/auth/sudo_auth.c:205
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Ni načinov overitve, kodno prevedenih v sudo! Če želite izklopiti overjanje, uporabite nastavitveno možnost --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:389
+msgid "Authentication methods:"
+msgstr "Načini overjanja:"
+
+#: plugins/sudoers/bsm_audit.c:60 plugins/sudoers/bsm_audit.c:63
+#: plugins/sudoers/bsm_audit.c:112 plugins/sudoers/bsm_audit.c:116
+#: plugins/sudoers/bsm_audit.c:168 plugins/sudoers/bsm_audit.c:172
+#, c-format
+msgid "getaudit: failed"
+msgstr "getaudit: spodletelo"
+
+#: plugins/sudoers/bsm_audit.c:90 plugins/sudoers/bsm_audit.c:153
+#, c-format
+msgid "Could not determine audit condition"
+msgstr "Pogoja presoje varnosti ni bilo mogoče določiti"
+
+#: plugins/sudoers/bsm_audit.c:101
+#, c-format
+msgid "getauid failed"
+msgstr "getauid je spodletel"
+
+#: plugins/sudoers/bsm_audit.c:103 plugins/sudoers/bsm_audit.c:162
+#, c-format
+msgid "au_open: failed"
+msgstr "au_open: spodletelo"
+
+#: plugins/sudoers/bsm_audit.c:118 plugins/sudoers/bsm_audit.c:174
+#, c-format
+msgid "au_to_subject: failed"
+msgstr "au_to_subject: spodletelo"
+
+#: plugins/sudoers/bsm_audit.c:122 plugins/sudoers/bsm_audit.c:178
+#, c-format
+msgid "au_to_exec_args: failed"
+msgstr "au_to_exec_args: spodletelo"
+
+#: plugins/sudoers/bsm_audit.c:126 plugins/sudoers/bsm_audit.c:187
+#, c-format
+msgid "au_to_return32: failed"
+msgstr "au_to_return32: spodletelo"
+
+#: plugins/sudoers/bsm_audit.c:129 plugins/sudoers/bsm_audit.c:190
+#, c-format
+msgid "unable to commit audit record"
+msgstr "ni bilo mogoče uveljaviti zapisa presoje varnosti"
+
+#: plugins/sudoers/bsm_audit.c:160
+#, c-format
+msgid "getauid: failed"
+msgstr "getauid: spodletelo"
+
+#: plugins/sudoers/bsm_audit.c:183
+#, c-format
+msgid "au_to_text: failed"
+msgstr "au_to_text: spodletelo"
+
+#: plugins/sudoers/check.c:174
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Verjetno vam je skrbnik sistemov že pridigal o varnosti,\n"
+"vendar si vseeno zapomnite naslednja pravila:\n"
+"\n"
+" #1) Spoštujte zasebnost drugih.\n"
+" #2) Premislite, preden izvedete ukaze.\n"
+" #3) Velika moč prinaša veliko odgovornost.\n"
+"\n"
+
+#: plugins/sudoers/check.c:212 plugins/sudoers/check.c:218
+#: plugins/sudoers/sudoers.c:562 plugins/sudoers/sudoers.c:566
+#, c-format
+msgid "unknown uid: %u"
+msgstr "neznan ID uporabnika: %u"
+
+#: plugins/sudoers/check.c:215 plugins/sudoers/policy.c:635
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:215
+#: plugins/sudoers/testsudoers.c:359
+#, c-format
+msgid "unknown user: %s"
+msgstr "neznan uporabnik: %s"
+
+#: plugins/sudoers/def_data.c:27
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Pripomoček syslog, če se syslog uporablja za beleženje: %s"
+
+#: plugins/sudoers/def_data.c:31
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Prednost syslog, ko se uporabnik uspešno overi: %s"
+
+#: plugins/sudoers/def_data.c:35
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Prednost syslog, ko se uporabnik ne overi uspešno: %s"
+
+#: plugins/sudoers/def_data.c:39
+msgid "Put OTP prompt on its own line"
+msgstr "postavi poziv OTP v svojo vrstico"
+
+#: plugins/sudoers/def_data.c:43
+msgid "Ignore '.' in $PATH"
+msgstr "Prezri '.' v $PATH"
+
+#: plugins/sudoers/def_data.c:47
+msgid "Always send mail when sudo is run"
+msgstr "Vedno pošlji pošto, kadar se zažene sudo"
+
+#: plugins/sudoers/def_data.c:51
+msgid "Send mail if user authentication fails"
+msgstr "Pošlji pošto, če overitev uporabnika spodleti"
+
+#: plugins/sudoers/def_data.c:55
+msgid "Send mail if the user is not in sudoers"
+msgstr "Pošlji pošto, če uporabnik ni v sudoers"
+
+#: plugins/sudoers/def_data.c:59
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Pošlji pošto, če uporabnik ni v sudoers za tega gostitelja"
+
+#: plugins/sudoers/def_data.c:63
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Pošlji pošto, če uporabniku ni dovoljeno zagnati ukaza"
+
+#: plugins/sudoers/def_data.c:67
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Uporabi ločen časovni žig za vsako kombinacijo uporabnik/tty"
+
+#: plugins/sudoers/def_data.c:71
+msgid "Lecture user the first time they run sudo"
+msgstr "Poduči uporabnika, ko prvič zažene sudo"
+
+#: plugins/sudoers/def_data.c:75
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Datoteka, ki vsebuje poduk sudo: %s"
+
+#: plugins/sudoers/def_data.c:79
+msgid "Require users to authenticate by default"
+msgstr "Privzeto zahtevaj od uporabnikov, da se overijo"
+
+#: plugins/sudoers/def_data.c:83
+msgid "Root may run sudo"
+msgstr "Skrbnik lahko zažene sudo"
+
+#: plugins/sudoers/def_data.c:87
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Beleži ime gostitelja v datoteko dnevnika (ne v sistemski dnevnik)"
+
+#: plugins/sudoers/def_data.c:91
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Beleži leto v (ne-syslog) dnevniško datoteko"
+
+#: plugins/sudoers/def_data.c:95
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Če je sudo poklican brez argumentov, začni lupino"
+
+#: plugins/sudoers/def_data.c:99
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Postavi $HOME ciljnemu uporabniku, kadar se začne lupina s -s"
+
+#: plugins/sudoers/def_data.c:103
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Vedno postavi $HOME domači mapi ciljnega uporabnika"
+
+#: plugins/sudoers/def_data.c:107
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Dovoli zbrati nekaj podrobnosti za uporabna sporočila napak"
+
+#: plugins/sudoers/def_data.c:111
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Zahtevaj povsem uvrščena imena gostiteljev v datoteki sudoers"
+
+#: plugins/sudoers/def_data.c:115
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Užali uporabnika, ko vnese nepravilno geslo"
+
+#: plugins/sudoers/def_data.c:119
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Dovoli uporabniku zagnati sudo samo v primeru, če imajo tty"
+
+#: plugins/sudoers/def_data.c:123
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo bo spoštoval spremenljivko okolja UREJEVALNIKA"
+
+#: plugins/sudoers/def_data.c:127
+msgid "Prompt for root's password, not the users's"
+msgstr "Pozovi za geslo skrbnika, ne uporabnika"
+
+#: plugins/sudoers/def_data.c:131
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Pozovi za geslo uporabnika runas_default namesto uporabnikovega gesla"
+
+#: plugins/sudoers/def_data.c:135
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Pozovi za geslo ciljnega uporabnika namesto uporabnikovega"
+
+#: plugins/sudoers/def_data.c:139
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Uveljavi privzete vrednosti v ciljnem uporabniškem razredu prijave, če le ta obstaja"
+
+#: plugins/sudoers/def_data.c:143
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Nastavi spremenljivke okolja LOGNAME in USER"
+
+#: plugins/sudoers/def_data.c:147
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Nastavi samo dejanski ID uporabnika ciljnemu uporabniku, ne resničnega ID-ja"
+
+#: plugins/sudoers/def_data.c:151
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Ne začenjaj vektorja skupine ciljnega uporabnika"
+
+#: plugins/sudoers/def_data.c:155
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %d"
+msgstr "Dolžina, pri kateri se naj prelomijo vrstice datotek beleženja (0 za brez lomljenja):% d"
+
+#: plugins/sudoers/def_data.c:159
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Časovni potek overitve časovnega žiga: %.1f minut"
+
+#: plugins/sudoers/def_data.c:163
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Zakasnitev poziva gesla: %.1f minut"
+
+#: plugins/sudoers/def_data.c:167
+#, c-format
+msgid "Number of tries to enter a password: %d"
+msgstr "Število poskusov vnosa gesla: %d"
+
+#: plugins/sudoers/def_data.c:171
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Uporabniška maska, ki bo uporabljena ali 0777 za uporabo uporabnikove: 0%o"
+
+#: plugins/sudoers/def_data.c:175
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Pot do datoteke beleženja: %s"
+
+#: plugins/sudoers/def_data.c:179
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Pot do programa pošte: %s"
+
+#: plugins/sudoers/def_data.c:183
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Zastavice za program pošte: %s"
+
+#: plugins/sudoers/def_data.c:187
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Naslov prejemnika pošte: %s"
+
+#: plugins/sudoers/def_data.c:191
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Naslov pošiljatelja pošte: %s"
+
+#: plugins/sudoers/def_data.c:195
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Vrstica zadeve za poštna sporočila: %s"
+
+#: plugins/sudoers/def_data.c:199
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Nepravilno sporočilo gesla: %s"
+
+#: plugins/sudoers/def_data.c:203
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Pot do mape časovnega žiga overitve: %s"
+
+#: plugins/sudoers/def_data.c:207
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Lastnik mape časovnega žiga overitve: %s"
+
+#: plugins/sudoers/def_data.c:211
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Uporabnikov v tej skupini zahteve gesla in PATH ne omejujejo: %s"
+
+#: plugins/sudoers/def_data.c:215
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Privzeti poziv gesla: %s"
+
+#: plugins/sudoers/def_data.c:219
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Če je poziv gesla nastavljen, bo prepisal sistemski poziv v vseh primerih."
+
+#: plugins/sudoers/def_data.c:223
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Privzet uporabnik za izvajanje ukazov kot: %s"
+
+#: plugins/sudoers/def_data.c:227
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Vrednost, s katerim se bo prepisal $PATH uporabnika: %s"
+
+#: plugins/sudoers/def_data.c:231
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Pot do urejevalnika za uporabo z visudo: %s"
+
+#: plugins/sudoers/def_data.c:235
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Kdaj naj bo zahtevano geslo za psevdoukaz 'list': %s"
+
+#: plugins/sudoers/def_data.c:239
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Kdaj naj bo zahtevano geslo za psevdoukaz 'verify': %s"
+
+#: plugins/sudoers/def_data.c:243
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Prednaloži preizkusne funkcije, shranjene v knjižnici sudo_noexec"
+
+#: plugins/sudoers/def_data.c:247
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Če je mapa LDAP na voljo, bodo krajevne datoteke sudoers prezrte"
+
+#: plugins/sudoers/def_data.c:251
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Opisniki datotek >= %d bodo končani pred izvedbo ukaza"
+
+#: plugins/sudoers/def_data.c:255
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Če je nastavljeno, lahko uporabniki prepišejo vrednost `closefrom' z možnostjo -C"
+
+#: plugins/sudoers/def_data.c:259
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Dovoli uporabnikom nastavljanje poljubnih spremenljivk okolja"
+
+#: plugins/sudoers/def_data.c:263
+msgid "Reset the environment to a default set of variables"
+msgstr "Ponastavi okolje na privzet nabor spremenljivk"
+
+#: plugins/sudoers/def_data.c:267
+msgid "Environment variables to check for sanity:"
+msgstr "Spremenljivke okolja, ki bodo preverjene za smiselnost:"
+
+#: plugins/sudoers/def_data.c:271
+msgid "Environment variables to remove:"
+msgstr "Spremenljivke okolja za odstranitev:"
+
+#: plugins/sudoers/def_data.c:275
+msgid "Environment variables to preserve:"
+msgstr "Spremenljivke okolja za ohranitev:"
+
+#: plugins/sudoers/def_data.c:279
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Vloga SELinux za uporabo v novi vsebini varnosti: %s"
+
+#: plugins/sudoers/def_data.c:283
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Vrsta SELinux za uporabo v novi vsebini varnosti: %s"
+
+#: plugins/sudoers/def_data.c:287
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Pot do določene sudo datoteke okolja: %s"
+
+#: plugins/sudoers/def_data.c:291
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Jezikovna oznaka za uporabo pri razčlenjevanju sudoers: %s"
+
+#: plugins/sudoers/def_data.c:295
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Dovoli programu sudo, da vpraša za geslo, čeprav bi bilo le-to vidno"
+
+#: plugins/sudoers/def_data.c:299
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Zagotovi viden odziv ob vnosu gesla ob vnosu uporabnika"
+
+#: plugins/sudoers/def_data.c:303
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Uporabi hitrejše razširjanje imen poti, ki je manj natančno, vendar ne dostopa do datotečnega sistema"
+
+#: plugins/sudoers/def_data.c:307
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "Uporabniška maska v sudoers bo prepisala uporabnikovo tudi, če je bolj premisivna"
+
+#: plugins/sudoers/def_data.c:311
+msgid "Log user's input for the command being run"
+msgstr "Beleži vnos uporabnika za ukaz, ki se izvaja"
+
+#: plugins/sudoers/def_data.c:315
+msgid "Log the output of the command being run"
+msgstr "Beleži izpis ukaza, ki se izvaja"
+
+#: plugins/sudoers/def_data.c:319
+msgid "Compress I/O logs using zlib"
+msgstr "Stisni dnevnike I/O s pomočjo zlib"
+
+#: plugins/sudoers/def_data.c:323
+msgid "Always run commands in a pseudo-tty"
+msgstr "Vedno zaženi ukaze v psevdo-tty"
+
+#: plugins/sudoers/def_data.c:327
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Vstavek za podporo skupinam, ki niso del Unixa: %s"
+
+#: plugins/sudoers/def_data.c:331
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Mapa, v kateri bodo shranjeni dnevniki vnosov/izpisov: %s"
+
+#: plugins/sudoers/def_data.c:335
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Datoteka, v kateri bo shranjen dnevnik vnosov/izpisov: %s"
+
+#: plugins/sudoers/def_data.c:339
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Dodaj vstop datoteki utmp/utmpx, kadar se dodeljuje pty"
+
+#: plugins/sudoers/def_data.c:343
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Nastavi uporabnika v utmp uporabniku runas, ne poklicanemu uporabniku"
+
+#: plugins/sudoers/def_data.c:347
+msgid "Set of permitted privileges"
+msgstr "Niz omogočenih dovoljenj"
+
+#: plugins/sudoers/def_data.c:351
+msgid "Set of limit privileges"
+msgstr "Niz omejenih dovoljenj"
+
+#: plugins/sudoers/def_data.c:355
+msgid "Run commands on a pty in the background"
+msgstr "Zaženi ukaze v terminalu v ozadju"
+
+#: plugins/sudoers/def_data.c:359
+msgid "Create a new PAM session for the command to run in"
+msgstr "Ustvari sejo PAM, v kateri se bodo ukazi izvajali"
+
+#: plugins/sudoers/def_data.c:363
+msgid "Maximum I/O log sequence number"
+msgstr "Največja zaporedna številka dnevnika I/O"
+
+#: plugins/sudoers/defaults.c:207 plugins/sudoers/defaults.c:587
+#, c-format
+msgid "unknown defaults entry `%s'"
+msgstr "neznan privzet vnos `%s'"
+
+#: plugins/sudoers/defaults.c:215 plugins/sudoers/defaults.c:225
+#: plugins/sudoers/defaults.c:245 plugins/sudoers/defaults.c:258
+#: plugins/sudoers/defaults.c:271 plugins/sudoers/defaults.c:284
+#: plugins/sudoers/defaults.c:297 plugins/sudoers/defaults.c:317
+#: plugins/sudoers/defaults.c:327
+#, c-format
+msgid "value `%s' is invalid for option `%s'"
+msgstr "vrednost `%s' je neveljavna za možnost `%s'"
+
+#: plugins/sudoers/defaults.c:218 plugins/sudoers/defaults.c:228
+#: plugins/sudoers/defaults.c:236 plugins/sudoers/defaults.c:253
+#: plugins/sudoers/defaults.c:266 plugins/sudoers/defaults.c:279
+#: plugins/sudoers/defaults.c:292 plugins/sudoers/defaults.c:312
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "no value specified for `%s'"
+msgstr "za `%s' ni določena nobena vrednost"
+
+#: plugins/sudoers/defaults.c:241
+#, c-format
+msgid "values for `%s' must start with a '/'"
+msgstr "vrednosti za `%s' se morajo začeti s '/'"
+
+#: plugins/sudoers/defaults.c:303
+#, c-format
+msgid "option `%s' does not take a value"
+msgstr "možnost `%s' ne sprejme vrednosti"
+
+#: plugins/sudoers/env.c:288 plugins/sudoers/env.c:293
+#: plugins/sudoers/env.c:395 plugins/sudoers/linux_audit.c:82
+#: plugins/sudoers/policy.c:420 plugins/sudoers/policy.c:427
+#: plugins/sudoers/prompt.c:171 plugins/sudoers/sudoers.c:654
+#: plugins/sudoers/testsudoers.c:243
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "notranja napaka, prekoračitev funkcije %s"
+
+#: plugins/sudoers/env.c:367
+#, c-format
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: pokvarjen envp, neujemanje dolžine"
+
+#: plugins/sudoers/env.c:1012
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "nimate dovoljenj nastavljati naslednjih spremenljivk okolja: %s"
+
+#: plugins/sudoers/group_plugin.c:102
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s mora biti v lasti ID-ja uporabnika %d"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s mora biti zapisljiv samo za lastnika"
+
+#: plugins/sudoers/group_plugin.c:113
+#, c-format
+msgid "unable to dlopen %s: %s"
+msgstr "ni mogoče uporabiti dlopen %s: %s"
+
+#: plugins/sudoers/group_plugin.c:118
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "ni mogoče najti simbola \"group_plugin\" v %s"
+
+#: plugins/sudoers/group_plugin.c:123
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: nezdružljiva večja različica vstavka skupin %d, pričakovana %d"
+
+#: plugins/sudoers/interfaces.c:119
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Pari krajevnih naslovov IP in omrežnih mask:\n"
+
+#: plugins/sudoers/iolog.c:131 plugins/sudoers/iolog.c:144
+#: plugins/sudoers/timestamp.c:199 plugins/sudoers/timestamp.c:243
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s že obstaja, toda ni mapa (0%o)"
+
+#: plugins/sudoers/iolog.c:141 plugins/sudoers/iolog.c:155
+#: plugins/sudoers/iolog.c:159 plugins/sudoers/timestamp.c:164
+#: plugins/sudoers/timestamp.c:220 plugins/sudoers/timestamp.c:270
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "ustvarjenje mape %s z mkdir ni mogoče"
+
+#: plugins/sudoers/iolog.c:217 plugins/sudoers/sudoers.c:708
+#: plugins/sudoers/sudoreplay.c:354 plugins/sudoers/sudoreplay.c:815
+#: plugins/sudoers/sudoreplay.c:978 plugins/sudoers/timestamp.c:154
+#: plugins/sudoers/visudo.c:809
+#, c-format
+msgid "unable to open %s"
+msgstr "ni mogoče odpreti %s"
+
+#: plugins/sudoers/iolog.c:250 plugins/sudoers/sudoers.c:711
+#, c-format
+msgid "unable to read %s"
+msgstr "ni mogoče brati %s"
+
+#: plugins/sudoers/iolog.c:274 plugins/sudoers/timestamp.c:158
+#, c-format
+msgid "unable to write to %s"
+msgstr "ni mogoče pisati v %s"
+
+#: plugins/sudoers/iolog.c:334
+#, c-format
+msgid "unable to create %s"
+msgstr "ni mogoče ustvariti %s"
+
+#: plugins/sudoers/ldap.c:385
+#, c-format
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: vrednost vrat je prevelika"
+
+#: plugins/sudoers/ldap.c:408
+#, c-format
+msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+msgstr "sudo_ldap_conf_add_ports: med razširjanjem hostbuf je zmanjkalo prostora"
+
+#: plugins/sudoers/ldap.c:438
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "nepodprta vrsta uri-ja LDAP: %s"
+
+#: plugins/sudoers/ldap.c:467
+#, c-format
+msgid "invalid uri: %s"
+msgstr "neveljaven uri: %s"
+
+#: plugins/sudoers/ldap.c:473
+#, c-format
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "ni mogoče mešati URI-jev ldap in ldaps"
+
+#: plugins/sudoers/ldap.c:477
+#, c-format
+msgid "unable to mix ldaps and starttls"
+msgstr "ni mogoče mešati ldaps in starttls"
+
+#: plugins/sudoers/ldap.c:496
+#, c-format
+msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+msgstr "sudo_ldap_parse_uri: med izgradnjo hostbuf je zmanjkalo prostora"
+
+#: plugins/sudoers/ldap.c:570
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "ni mogoče začenjati potrdila SSL in ključa db: %s"
+
+#: plugins/sudoers/ldap.c:573
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "za uporabo SSL-ja morate nastaviti TSL_CERT v datoteki %s"
+
+#: plugins/sudoers/ldap.c:996
+#, c-format
+msgid "unable to get GMT time"
+msgstr "ni mogoče dobiti časa GMT"
+
+#: plugins/sudoers/ldap.c:1002
+#, c-format
+msgid "unable to format timestamp"
+msgstr "ni mogoče oblikovati časovnega žiga"
+
+#: plugins/sudoers/ldap.c:1010
+#, c-format
+msgid "unable to build time filter"
+msgstr "ni mogoče izgraditi časovnega filtra"
+
+#: plugins/sudoers/ldap.c:1229
+#, c-format
+msgid "sudo_ldap_build_pass1 allocation mismatch"
+msgstr "sudo_ldap_build_pass1 neujemanje dodelitve"
+
+#: plugins/sudoers/ldap.c:1776
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"Vloga LDAP: %s\n"
+
+#: plugins/sudoers/ldap.c:1778
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"Vloga LDAP: NEZNANA\n"
+
+#: plugins/sudoers/ldap.c:1825
+#, c-format
+msgid " Order: %s\n"
+msgstr " Vrstni red: %s\n"
+
+#: plugins/sudoers/ldap.c:1833 plugins/sudoers/parse.c:515
+#: plugins/sudoers/sssd.c:1173
+#, c-format
+msgid " Commands:\n"
+msgstr " Ukazi:\n"
+
+#: plugins/sudoers/ldap.c:2255
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "ni mogoče začeti LDAP: %s"
+
+#: plugins/sudoers/ldap.c:2289
+#, c-format
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls je določen, toda knjižnice LDAP ne podpirajo ldap_start_tls_s() ali ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:2525
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "neveljaven atribut sudoOrder: %s"
+
+#: plugins/sudoers/linux_audit.c:57
+#, c-format
+msgid "unable to open audit system"
+msgstr "ni mogoče odpreti nadzornega sistema"
+
+#: plugins/sudoers/linux_audit.c:93
+#, c-format
+msgid "unable to send audit message"
+msgstr "ni mogoče poslati nadzornega sporočila"
+
+#: plugins/sudoers/logging.c:140
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:168
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (ukaz) %s"
+
+#: plugins/sudoers/logging.c:194
+#, c-format
+msgid "unable to open log file: %s: %s"
+msgstr "ni mogoče odpreti datoteke dnevnika: %s: %s"
+
+#: plugins/sudoers/logging.c:197
+#, c-format
+msgid "unable to lock log file: %s: %s"
+msgstr "ni mogoče zakleniti datoteke dnevnika: %s: %s"
+
+#: plugins/sudoers/logging.c:245
+msgid "No user or host"
+msgstr "Brez uporabnika ali gostitelja"
+
+#: plugins/sudoers/logging.c:247
+msgid "validation failure"
+msgstr "potrjevanje veljavnosti ni uspelo"
+
+#: plugins/sudoers/logging.c:254
+msgid "user NOT in sudoers"
+msgstr "uporabnika NI v sudoers"
+
+#: plugins/sudoers/logging.c:256
+msgid "user NOT authorized on host"
+msgstr "uporabnik NI pooblaščen na gostitelju"
+
+#: plugins/sudoers/logging.c:258
+msgid "command not allowed"
+msgstr "ukaz ni dovoljen"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s ni v datoteki sudoers. Ta dogodek bo zabeležen.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s nima dovoljenj za izvajanje sudo na %s. Ta dogodek bo zabeležen.\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Uporabnik %s ne sme izvajati sudo na %s.\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Uporabnik %s ne sme zagnati '%s%s%s' kot %s%s%s na %s.\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:383
+#: plugins/sudoers/sudoers.c:384 plugins/sudoers/sudoers.c:386
+#: plugins/sudoers/sudoers.c:387 plugins/sudoers/sudoers.c:1001
+#: plugins/sudoers/sudoers.c:1002
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: ukaza ni bilo mogoče najti"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:379
+#, c-format
+msgid ""
+"ignoring `%s' found in '.'\n"
+"Use `sudo ./%s' if this is the `%s' you wish to run."
+msgstr ""
+"prezrtje `%s', najdenega v '.'\n"
+"Uporabite `sudo ./%s', če je to `%s', ki ga želite zagnati."
+
+#: plugins/sudoers/logging.c:353
+msgid "authentication failure"
+msgstr "napaka overitve"
+
+#: plugins/sudoers/logging.c:379
+msgid "a password is required"
+msgstr "zahtevano je geslo"
+
+#: plugins/sudoers/logging.c:443 plugins/sudoers/logging.c:487
+#, c-format
+msgid "%d incorrect password attempt"
+msgid_plural "%d incorrect password attempts"
+msgstr[0] "%d nepravilnih poskusov vnosa gesla"
+msgstr[1] "%d nepravilen poskus vnosa gesla"
+msgstr[2] "%d nepravilna poskusa vnosa gesla"
+msgstr[3] "%d nepravilni poskusi vnosa gesla"
+
+#: plugins/sudoers/logging.c:566
+#, c-format
+msgid "unable to fork"
+msgstr "ni mogoče razvejiti"
+
+#: plugins/sudoers/logging.c:573 plugins/sudoers/logging.c:629
+#, c-format
+msgid "unable to fork: %m"
+msgstr "ni mogoče razvejiti: %m"
+
+#: plugins/sudoers/logging.c:619
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "ni mogoče odpreti cevi: %m"
+
+#: plugins/sudoers/logging.c:644
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "ni mogoče podvojiti stdin: %m"
+
+#: plugins/sudoers/logging.c:680
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "ni mogoče izvesti %s: %m"
+
+#: plugins/sudoers/logging.c:899
+#, c-format
+msgid "internal error: insufficient space for log line"
+msgstr "notranja napaka: premalo prostora za vrstico dnevnika"
+
+#: plugins/sudoers/parse.c:124
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "napaka razčlenjevanja v %s blizu vrstice %d"
+
+#: plugins/sudoers/parse.c:127
+#, c-format
+msgid "parse error in %s"
+msgstr "napaka med razčlenjevanjem datoteke %s"
+
+#: plugins/sudoers/parse.c:462
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Vnos sudoers:\n"
+
+#: plugins/sudoers/parse.c:463
+#, c-format
+msgid " RunAsUsers: "
+msgstr " ZaženiKotUporabniki: "
+
+#: plugins/sudoers/parse.c:477
+#, c-format
+msgid " RunAsGroups: "
+msgstr " ZaženiKotSkupine: "
+
+#: plugins/sudoers/parse.c:486
+#, c-format
+msgid " Options: "
+msgstr " Možnosti: "
+
+#: plugins/sudoers/policy.c:517 plugins/sudoers/visudo.c:750
+#, c-format
+msgid "unable to execute %s"
+msgstr "ni mogoče izvršiti %s"
+
+#: plugins/sudoers/policy.c:659
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Vstavek pravilnika sudoers različica %s\n"
+
+#: plugins/sudoers/policy.c:661
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Datoteka slovnice sudoers različica %d\n"
+
+#: plugins/sudoers/policy.c:665
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Pot sudoers: %s\n"
+
+#: plugins/sudoers/policy.c:668
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "pot nsswitch: %s\n"
+
+#: plugins/sudoers/policy.c:670
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "pot ldap.conf: %s\n"
+
+#: plugins/sudoers/policy.c:671
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "pot ldap.secret: %s\n"
+
+#: plugins/sudoers/pwutil.c:148
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "ni mogoče predpomniti ID-ja uporabnika %u, že obstaja"
+
+#: plugins/sudoers/pwutil.c:190
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "ni mogoče predpomniti uporabnika %s, že obstaja"
+
+#: plugins/sudoers/pwutil.c:374
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "ni mogoče predpomniti ID-ja skupine %u, že obstaja"
+
+#: plugins/sudoers/pwutil.c:410
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "ni mogoče predpomniti skupine %s, že obstaja"
+
+#: plugins/sudoers/pwutil.c:564 plugins/sudoers/pwutil.c:586
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "seznama skupina za %s ni mogoče predpomniti, saj že obstaja"
+
+#: plugins/sudoers/pwutil.c:584
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "skupin za %s ni mogoče razčleniti"
+
+#: plugins/sudoers/set_perms.c:122 plugins/sudoers/set_perms.c:445
+#: plugins/sudoers/set_perms.c:846 plugins/sudoers/set_perms.c:1141
+#: plugins/sudoers/set_perms.c:1431
+msgid "perm stack overflow"
+msgstr "prekoračitev trajnega sklada"
+
+#: plugins/sudoers/set_perms.c:130 plugins/sudoers/set_perms.c:453
+#: plugins/sudoers/set_perms.c:854 plugins/sudoers/set_perms.c:1149
+#: plugins/sudoers/set_perms.c:1439
+msgid "perm stack underflow"
+msgstr "prekoračitev spodnje meje trajnega sklada"
+
+#: plugins/sudoers/set_perms.c:189 plugins/sudoers/set_perms.c:500
+#: plugins/sudoers/set_perms.c:1200 plugins/sudoers/set_perms.c:1471
+msgid "unable to change to root gid"
+msgstr "številke skupine skrbnika ni mogoče spremeniti"
+
+#: plugins/sudoers/set_perms.c:278 plugins/sudoers/set_perms.c:597
+#: plugins/sudoers/set_perms.c:983 plugins/sudoers/set_perms.c:1277
+msgid "unable to change to runas gid"
+msgstr "ni mogoče spremeniti v ID-ja skupine runas"
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:609
+#: plugins/sudoers/set_perms.c:993 plugins/sudoers/set_perms.c:1287
+msgid "unable to change to runas uid"
+msgstr "ni mogoče spremeniti v ID-ja uporabnika runas"
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:627
+#: plugins/sudoers/set_perms.c:1009 plugins/sudoers/set_perms.c:1303
+msgid "unable to change to sudoers gid"
+msgstr "ni mogoče spremeniti ID-ja skupine sudoers"
+
+#: plugins/sudoers/set_perms.c:361 plugins/sudoers/set_perms.c:698
+#: plugins/sudoers/set_perms.c:1055 plugins/sudoers/set_perms.c:1349
+#: plugins/sudoers/set_perms.c:1515
+msgid "too many processes"
+msgstr "preveč opravil"
+
+#: plugins/sudoers/set_perms.c:1583
+msgid "unable to set runas group vector"
+msgstr "ni mogoče nastaviti vektorja skupine runas"
+
+#: plugins/sudoers/sssd.c:256
+#, c-format
+msgid "Unable to dlopen %s: %s"
+msgstr "ni mogoče uporabiti dlopen %s: %s"
+
+#: plugins/sudoers/sssd.c:257
+#, c-format
+msgid "Unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "Vira SSS ni mogoče zagnati. Ali je SSSD pravilno nameščen?"
+
+#: plugins/sudoers/sssd.c:263 plugins/sudoers/sssd.c:271
+#: plugins/sudoers/sssd.c:278 plugins/sudoers/sssd.c:285
+#: plugins/sudoers/sssd.c:292
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "simbola \"%s\" ni mogoče najti v %s"
+
+#: plugins/sudoers/sudo_nss.c:283
+#, c-format
+msgid "Matching Defaults entries for %s on this host:\n"
+msgstr "Ujemajoči vpisi privzetih vrednosti za %s na tem gostitelju:\n"
+
+#: plugins/sudoers/sudo_nss.c:296
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Runas in ukazno določene privzete vrednosti za %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:309
+#, c-format
+msgid "User %s may run the following commands on this host:\n"
+msgstr "Na tem gostitelju lahko uporabnik %s zažene naslednje ukaze:\n"
+
+#: plugins/sudoers/sudo_nss.c:318
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Uporabniku %s ni dovoljeno zagnati sudo na %s.\n"
+
+#: plugins/sudoers/sudoers.c:159 plugins/sudoers/sudoers.c:193
+#: plugins/sudoers/sudoers.c:673
+msgid "problem with defaults entries"
+msgstr "težave z vnosi privzetih vrednosti"
+
+#: plugins/sudoers/sudoers.c:165
+#, c-format
+msgid "no valid sudoers sources found, quitting"
+msgstr "najdenih niso bili nobeni veljavni viri sudoers, končanje"
+
+#: plugins/sudoers/sudoers.c:227
+#, c-format
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers določa, da skrbniku ni dovoljeno uporabiti sudo"
+
+#: plugins/sudoers/sudoers.c:234
+#, c-format
+msgid "you are not permitted to use the -C option"
+msgstr "ni vam dovoljeno uporabiti možnosti -C"
+
+#: plugins/sudoers/sudoers.c:315
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "lastnik časovnega žiga (%s): ni takšnega uporabnika"
+
+#: plugins/sudoers/sudoers.c:329
+msgid "no tty"
+msgstr "brez tty"
+
+#: plugins/sudoers/sudoers.c:330
+#, c-format
+msgid "sorry, you must have a tty to run sudo"
+msgstr "za izvajanje sudo morate imeti tty"
+
+#: plugins/sudoers/sudoers.c:378
+msgid "command in current directory"
+msgstr "ukaz v trenutni mapi"
+
+#: plugins/sudoers/sudoers.c:395
+#, c-format
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "nimate dovoljenj za ohranjanje okolja"
+
+#: plugins/sudoers/sudoers.c:723 plugins/sudoers/timestamp.c:215
+#: plugins/sudoers/timestamp.c:259 plugins/sudoers/timestamp.c:327
+#: plugins/sudoers/visudo.c:310 plugins/sudoers/visudo.c:576
+#, c-format
+msgid "unable to stat %s"
+msgstr "stanja %s ni mogoče dobiti"
+
+#: plugins/sudoers/sudoers.c:726
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s ni običajna datoteka"
+
+#: plugins/sudoers/sudoers.c:729 toke.l:842
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s je v lasti ID-ja uporabnika %u, moral bi biti %u"
+
+#: plugins/sudoers/sudoers.c:733 toke.l:849
+#, c-format
+msgid "%s is world writable"
+msgstr "v datoteko %s lahko zapisujejo vsi uporabniki"
+
+#: plugins/sudoers/sudoers.c:736 toke.l:854
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s je v lasti ID-ja skupine %u, moral bi biti %u"
+
+#: plugins/sudoers/sudoers.c:763
+#, c-format
+msgid "only root can use `-c %s'"
+msgstr "samo skrbnik lahko uporabi `-c %s'"
+
+#: plugins/sudoers/sudoers.c:780 plugins/sudoers/sudoers.c:782
+#, c-format
+msgid "unknown login class: %s"
+msgstr "neznan razred prijave: %s"
+
+#: plugins/sudoers/sudoers.c:814
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "ni mogoče razrešiti gostitelja %s"
+
+#: plugins/sudoers/sudoers.c:866 plugins/sudoers/testsudoers.c:377
+#, c-format
+msgid "unknown group: %s"
+msgstr "neznana skupina: %s"
+
+#: plugins/sudoers/sudoreplay.c:292
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "neveljavna možnost filtra: %s"
+
+#: plugins/sudoers/sudoreplay.c:305
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "neveljavna zgornja meja čakanja: %s"
+
+#: plugins/sudoers/sudoreplay.c:311
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "neveljaven dejavnik hitrosti: %s"
+
+#: plugins/sudoers/sudoreplay.c:314 plugins/sudoers/visudo.c:179
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s različica %s\n"
+
+#: plugins/sudoers/sudoreplay.c:339
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/časovna uskladitev: %s"
+
+#: plugins/sudoers/sudoreplay.c:345
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/časovna uskladitev: %s"
+
+#: plugins/sudoers/sudoreplay.c:363
+#, c-format
+msgid "Replaying sudo session: %s\n"
+msgstr "Izpisovanje dnevnika seje sudo: %s\n"
+
+#: plugins/sudoers/sudoreplay.c:369
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Opozorilo: terminal je premajhen za pravilno izpisovanje dnevnika.\n"
+
+#: plugins/sudoers/sudoreplay.c:370
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Geometrija dnevnika je %d x %d, medtem ko je geometrija terminala %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:400
+#, c-format
+msgid "unable to set tty to raw mode"
+msgstr "ni mogoče nastaviti tty na surov način"
+
+#: plugins/sudoers/sudoreplay.c:416
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "neveljavna vrstica datoteke časovne uskladitve: %s"
+
+#: plugins/sudoers/sudoreplay.c:499
+#, c-format
+msgid "writing to standard output"
+msgstr "pisanje na standardni izhod"
+
+#: plugins/sudoers/sudoreplay.c:528
+#, c-format
+msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
+msgstr "nanosleep: tv_sec %ld, tv_nsec %ld"
+
+#: plugins/sudoers/sudoreplay.c:641 plugins/sudoers/sudoreplay.c:666
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "dvoumen izraz \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:683
+#, c-format
+msgid "too many parenthesized expressions, max %d"
+msgstr "preveč izrazov z oklepaji, največje število %d"
+
+#: plugins/sudoers/sudoreplay.c:694
+#, c-format
+msgid "unmatched ')' in expression"
+msgstr "v izrazu je neujemajoč ')'"
+
+#: plugins/sudoers/sudoreplay.c:700
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "naznan iskalni izraz \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:714
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s zahteva argument"
+
+#: plugins/sudoers/sudoreplay.c:718
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "neveljaven logični izraz: %s"
+
+#: plugins/sudoers/sudoreplay.c:724
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "ni mogoče razčleniti datuma \"%s\""
+
+#: plugins/sudoers/sudoreplay.c:737
+#, c-format
+msgid "unmatched '(' in expression"
+msgstr "v izrazu je neujemajoč '('"
+
+#: plugins/sudoers/sudoreplay.c:739
+#, c-format
+msgid "illegal trailing \"or\""
+msgstr "neveljaven zaključni \"or\""
+
+#: plugins/sudoers/sudoreplay.c:741
+#, c-format
+msgid "illegal trailing \"!\""
+msgstr "neveljaven zaključni \"!\""
+
+#: plugins/sudoers/sudoreplay.c:1058
+#, c-format
+msgid "invalid regex: %s"
+msgstr "neveljavni logični izraz: %s"
+
+#: plugins/sudoers/sudoreplay.c:1182
+#, c-format
+msgid "usage: %s [-h] [-d directory] [-m max_wait] [-s speed_factor] ID\n"
+msgstr "uporaba: %s [-h] [-d mapa] [-m zg_meja_čakanja] [-s faktor_hitrosti] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1185
+#, c-format
+msgid "usage: %s [-h] [-d directory] -l [search expression]\n"
+msgstr "uporaba: %s [-h] [-d mapa] -l [iskalni izraz]\n"
+
+#: plugins/sudoers/sudoreplay.c:1194
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - ponovno predvajaj dnevnike sej sudo\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1196
+msgid ""
+"\n"
+"Options:\n"
+" -d directory specify directory for session logs\n"
+" -f filter specify which I/O type to display\n"
+" -h display help message and exit\n"
+" -l [expression] list available session IDs that match expression\n"
+" -m max_wait max number of seconds to wait between events\n"
+" -s speed_factor speed up or slow down output\n"
+" -V display version information and exit"
+msgstr ""
+"\n"
+"Možnosti:\n"
+" -d mapa določi mapo za dnevnike sej\n"
+" -f filter navedi, katera vrsta I/O se naj prikaže \n"
+" -h prikaži sporočilo pomoči in končaj\n"
+" -l [izraz] navedi razpoložljive ID-je sej, ki se ujemajo z izrazom\n"
+" -m zg_meja_čakanja največje število sekund za čakanje med dogodki\n"
+" -s faktor_hitrosti pospeši ali upočasni izhod\n"
+" -V prikaži podrobnosti o različici in končaj"
+
+#: plugins/sudoers/testsudoers.c:328
+msgid "\thost unmatched"
+msgstr "\tgostitelj se ne ujema"
+
+#: plugins/sudoers/testsudoers.c:331
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Ukaz je dovoljen"
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Ukaz je bil zavrnjen"
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Ukaz se ne ujema"
+
+#: plugins/sudoers/timestamp.c:128
+#, c-format
+msgid "timestamp path too long: %s"
+msgstr "pot časovnega žiga je predolga : %s"
+
+#: plugins/sudoers/timestamp.c:202 plugins/sudoers/timestamp.c:246
+#: plugins/sudoers/timestamp.c:291
+#, c-format
+msgid "%s owned by uid %u, should be uid %u"
+msgstr "%s je v lasti ID-ja uporabnika %u, moral bi biti ID uporabnika %u"
+
+#: plugins/sudoers/timestamp.c:207 plugins/sudoers/timestamp.c:251
+#, c-format
+msgid "%s writable by non-owner (0%o), should be mode 0700"
+msgstr "%s je zapisljiv za ne-lastnika (0%o), moral bi biti način 0700"
+
+#: plugins/sudoers/timestamp.c:285
+#, c-format
+msgid "%s exists but is not a regular file (0%o)"
+msgstr "%s obstaja, toda ni običajna datoteka (0%o)"
+
+#: plugins/sudoers/timestamp.c:297
+#, c-format
+msgid "%s writable by non-owner (0%o), should be mode 0600"
+msgstr "%s je zapisljiv za ne-lastnika (0%o), moral bi biti način 0600"
+
+#: plugins/sudoers/timestamp.c:352
+#, c-format
+msgid "timestamp too far in the future: %20.20s"
+msgstr "časovni žig je predaleč v prihodnosti: %20.20s"
+
+#: plugins/sudoers/timestamp.c:406
+#, c-format
+msgid "unable to remove %s, will reset to the epoch"
+msgstr "%s ni mogoče odstraniti"
+
+#: plugins/sudoers/timestamp.c:413
+#, c-format
+msgid "unable to reset %s to the epoch"
+msgstr "%s ni mogoče ponastaviti na epoho"
+
+#: plugins/sudoers/toke_util.c:221
+#, c-format
+msgid "fill_args: buffer overflow"
+msgstr "fill_args: prekoračitev medpomnilnika"
+
+#: plugins/sudoers/visudo.c:180
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s različica slovnice %d\n"
+
+#: plugins/sudoers/visudo.c:243 plugins/sudoers/visudo.c:533
+#, c-format
+msgid "press return to edit %s: "
+msgstr "za urejanje %s pritisnite return: "
+
+#: plugins/sudoers/visudo.c:326 plugins/sudoers/visudo.c:332
+#, c-format
+msgid "write error"
+msgstr "napaka med pisanjem"
+
+#: plugins/sudoers/visudo.c:414
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "ni mogoče začeti začasne datoteke (%s), %s nepsremenjeno"
+
+#: plugins/sudoers/visudo.c:419
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "začasna datoteka brez dolžine (%s), %s nespremenjena"
+
+#: plugins/sudoers/visudo.c:425
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "urejevalnik (%s) je spodletel, %s nespremenjen"
+
+#: plugins/sudoers/visudo.c:448
+#, c-format
+msgid "%s unchanged"
+msgstr "%s nespremenjeno"
+
+#: plugins/sudoers/visudo.c:477
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "ni mogoče ponovno odpreti začasne datoteke (%s), %s je nespremenjen."
+
+#: plugins/sudoers/visudo.c:487
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "ni mogoče razčleniti začasne datoteke (%s), neznana napaka"
+
+#: plugins/sudoers/visudo.c:526
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "notranja napaka, na seznamu ni mogoče najti %s!"
+
+#: plugins/sudoers/visudo.c:578 plugins/sudoers/visudo.c:587
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "ni mogoče nastaviti (ID uporabnika, ID skupine) od %s do (%u, %u)"
+
+#: plugins/sudoers/visudo.c:582 plugins/sudoers/visudo.c:592
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "ni mogoče spremeniti načina iz %s na 0%o"
+
+#: plugins/sudoers/visudo.c:609
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s in %s nista na enakem datotečnem sistemu, uporaba mv za preimenovanje"
+
+#: plugins/sudoers/visudo.c:623
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "ukaz je spodletel: '%s %s %s', %s nespremenjen"
+
+#: plugins/sudoers/visudo.c:633
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "napaka med preimenovanjem %s, %s nespremenjen"
+
+#: plugins/sudoers/visudo.c:695
+msgid "What now? "
+msgstr "Kaj pa zdaj? "
+
+#: plugins/sudoers/visudo.c:709
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Možnosti so:\n"
+" (e)ponovno uredi datoteko sudoers\n"
+" (x)končaj brez shranjevanja sprememb v datoteko sudoers\n"
+" (Q)končaj in shrani spremembe v datoteko sudoers (NEVARNOST!)\n"
+
+#: plugins/sudoers/visudo.c:757
+#, c-format
+msgid "unable to run %s"
+msgstr "ni mogoče zagnati %s"
+
+#: plugins/sudoers/visudo.c:783
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: napačen lastnik (ID uporabnika, ID skupine) moralo bi biti (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:790
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: slaba dovoljenja, moral bi biti način 0%o\n"
+
+#: plugins/sudoers/visudo.c:815
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "razčlenjevanje datoteke %s je spodletelo, neznana napaka"
+
+#: plugins/sudoers/visudo.c:831
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "napaka razčlenjevanja v %s blizu vrstice %d\n"
+
+#: plugins/sudoers/visudo.c:834
+#, c-format
+msgid "parse error in %s\n"
+msgstr "napaka razčlenjevanja v %s\n"
+
+#: plugins/sudoers/visudo.c:841 plugins/sudoers/visudo.c:846
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: uspešno razčlenjeno\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s zaseden, poskusite ponovno pozneje"
+
+#: plugins/sudoers/visudo.c:937
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "določen urejevalnik (%s) se ne konča"
+
+#: plugins/sudoers/visudo.c:960
+#, c-format
+msgid "unable to stat editor (%s)"
+msgstr "ni mogoče začeti urejevalnika (%s)"
+
+#: plugins/sudoers/visudo.c:1008
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "najdenega ni nobenega urejevalnika (pot urejevalnika = %s)"
+
+#: plugins/sudoers/visudo.c:1100
+#, c-format
+msgid "Error: cycle in %s_Alias `%s'"
+msgstr "Napaka: kroženje v %s_Alias `%s'"
+
+#: plugins/sudoers/visudo.c:1101
+#, c-format
+msgid "Warning: cycle in %s_Alias `%s'"
+msgstr "Opozorilo: kroženje v %s_Alias `%s'"
+
+#: plugins/sudoers/visudo.c:1104
+#, c-format
+msgid "Error: %s_Alias `%s' referenced but not defined"
+msgstr "Napaka: %s_Alias `%s' sklicevan, toda ne določen"
+
+#: plugins/sudoers/visudo.c:1105
+#, c-format
+msgid "Warning: %s_Alias `%s' referenced but not defined"
+msgstr "Warning: %s_Alias `%s' sklicevan, toda ne določen"
+
+#: plugins/sudoers/visudo.c:1240
+#, c-format
+msgid "%s: unused %s_Alias %s"
+msgstr "%s: neuporabljen %s_Alias %s"
+
+#: plugins/sudoers/visudo.c:1302
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - varno uredi datoteko sudoers\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1304
+msgid ""
+"\n"
+"Options:\n"
+" -c check-only mode\n"
+" -f sudoers specify sudoers file location\n"
+" -h display help message and exit\n"
+" -q less verbose (quiet) syntax error messages\n"
+" -s strict syntax checking\n"
+" -V display version information and exit"
+msgstr ""
+"\n"
+"Možnosti:\n"
+" -c način samo preverjanja\n"
+" -f sudoers določi mesto datoteke sudoers\n"
+" -h prikaži sporočilo pomoči in končaj\n"
+" -q manj podroben izpis (tih) sporočil skladenjskih napak\n"
+" -s strogo preverjanje skladnje\n"
+" -V prikaži podrobnosti različice in končaj"
+
+#: toke.l:815
+msgid "too many levels of includes"
+msgstr "preveč stopenj vključitev"
diff --git a/plugins/sudoers/po/sr.mo b/plugins/sudoers/po/sr.mo
new file mode 100644
index 0000000..a40c725
--- /dev/null
+++ b/plugins/sudoers/po/sr.mo
Binary files differ
diff --git a/plugins/sudoers/po/sr.po b/plugins/sudoers/po/sr.po
new file mode 100644
index 0000000..f3f71d5
--- /dev/null
+++ b/plugins/sudoers/po/sr.po
@@ -0,0 +1,2172 @@
+# Serbian translation for sudoers.
+# This file is put in the public domain.
+# Мирослав Николић <miroslavnikolic@rocketmail.com>, 2014—2017.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers-1.8.21b2\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2017-08-03 10:04-0600\n"
+"PO-Revision-Date: 2017-08-06 14:50+0200\n"
+"Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
+"Language-Team: Serbian <(nothing)>\n"
+"Language: sr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "грешка синтаксе"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "Лозинка корисника %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[судо] лозинка за корисника %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Лозинка: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** информације БЕЗБЕДНОСТИ за %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Извините, покушајте поново."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:307 gram.y:314 gram.y:321 gram.y:328 gram.y:335
+#: gram.y:398 gram.y:406 gram.y:416 gram.y:449 gram.y:456 gram.y:463
+#: gram.y:470 gram.y:552 gram.y:559 gram.y:568 gram.y:577 gram.y:594
+#: gram.y:706 gram.y:713 gram.y:720 gram.y:728 gram.y:824 gram.y:831
+#: gram.y:838 gram.y:845 gram.y:852 gram.y:878 gram.y:885 gram.y:892
+#: gram.y:1015 gram.y:1195 gram.y:1202 plugins/sudoers/alias.c:124
+#: plugins/sudoers/alias.c:139 plugins/sudoers/auth/bsdauth.c:141
+#: plugins/sudoers/auth/kerb5.c:119 plugins/sudoers/auth/kerb5.c:145
+#: plugins/sudoers/auth/pam.c:486 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/auth/sia.c:59 plugins/sudoers/defaults.c:647
+#: plugins/sudoers/defaults.c:902 plugins/sudoers/defaults.c:1073
+#: plugins/sudoers/editor.c:64 plugins/sudoers/editor.c:82
+#: plugins/sudoers/editor.c:93 plugins/sudoers/env.c:233
+#: plugins/sudoers/filedigest.c:120 plugins/sudoers/filedigest_gcrypt.c:90
+#: plugins/sudoers/filedigest_openssl.c:111 plugins/sudoers/gc.c:52
+#: plugins/sudoers/group_plugin.c:134 plugins/sudoers/interfaces.c:71
+#: plugins/sudoers/iolog.c:941 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:449 plugins/sudoers/ldap.c:480
+#: plugins/sudoers/ldap.c:532 plugins/sudoers/ldap.c:565
+#: plugins/sudoers/ldap.c:963 plugins/sudoers/ldap.c:1157
+#: plugins/sudoers/ldap.c:1168 plugins/sudoers/ldap.c:1184
+#: plugins/sudoers/ldap.c:1476 plugins/sudoers/ldap.c:1636
+#: plugins/sudoers/ldap.c:1718 plugins/sudoers/ldap.c:1858
+#: plugins/sudoers/ldap.c:1882 plugins/sudoers/ldap.c:1971
+#: plugins/sudoers/ldap.c:1986 plugins/sudoers/ldap.c:2082
+#: plugins/sudoers/ldap.c:2115 plugins/sudoers/ldap.c:2196
+#: plugins/sudoers/ldap.c:2278 plugins/sudoers/ldap.c:2375
+#: plugins/sudoers/ldap.c:3209 plugins/sudoers/ldap.c:3241
+#: plugins/sudoers/ldap.c:3550 plugins/sudoers/ldap.c:3578
+#: plugins/sudoers/ldap.c:3594 plugins/sudoers/ldap.c:3684
+#: plugins/sudoers/ldap.c:3700 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:189 plugins/sudoers/logging.c:451
+#: plugins/sudoers/logging.c:472 plugins/sudoers/logging.c:684
+#: plugins/sudoers/logging.c:942 plugins/sudoers/match.c:617
+#: plugins/sudoers/match.c:664 plugins/sudoers/match.c:714
+#: plugins/sudoers/match.c:738 plugins/sudoers/match.c:826
+#: plugins/sudoers/match.c:915 plugins/sudoers/parse.c:248
+#: plugins/sudoers/parse.c:260 plugins/sudoers/parse.c:275
+#: plugins/sudoers/parse.c:287 plugins/sudoers/policy.c:419
+#: plugins/sudoers/policy.c:653 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/pwutil.c:139 plugins/sudoers/pwutil.c:210
+#: plugins/sudoers/pwutil.c:286 plugins/sudoers/pwutil.c:457
+#: plugins/sudoers/pwutil.c:522 plugins/sudoers/pwutil.c:591
+#: plugins/sudoers/pwutil.c:749 plugins/sudoers/pwutil.c:806
+#: plugins/sudoers/pwutil.c:851 plugins/sudoers/pwutil.c:908
+#: plugins/sudoers/sssd.c:162 plugins/sudoers/sssd.c:194
+#: plugins/sudoers/sssd.c:237 plugins/sudoers/sssd.c:244
+#: plugins/sudoers/sssd.c:280 plugins/sudoers/sssd.c:390
+#: plugins/sudoers/sssd.c:459 plugins/sudoers/sssd.c:1057
+#: plugins/sudoers/sssd.c:1236 plugins/sudoers/sssd.c:1250
+#: plugins/sudoers/sssd.c:1266 plugins/sudoers/sudoers.c:263
+#: plugins/sudoers/sudoers.c:273 plugins/sudoers/sudoers.c:281
+#: plugins/sudoers/sudoers.c:365 plugins/sudoers/sudoers.c:681
+#: plugins/sudoers/sudoers.c:806 plugins/sudoers/sudoers.c:850
+#: plugins/sudoers/sudoers.c:1122 plugins/sudoers/sudoers_debug.c:107
+#: plugins/sudoers/sudoreplay.c:1234 plugins/sudoers/sudoreplay.c:1346
+#: plugins/sudoers/sudoreplay.c:1386 plugins/sudoers/sudoreplay.c:1395
+#: plugins/sudoers/sudoreplay.c:1405 plugins/sudoers/sudoreplay.c:1413
+#: plugins/sudoers/sudoreplay.c:1417 plugins/sudoers/sudoreplay.c:1573
+#: plugins/sudoers/sudoreplay.c:1577 plugins/sudoers/testsudoers.c:131
+#: plugins/sudoers/testsudoers.c:217 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/timestamp.c:389 plugins/sudoers/timestamp.c:433
+#: plugins/sudoers/timestamp.c:852 plugins/sudoers/toke_util.c:56
+#: plugins/sudoers/toke_util.c:109 plugins/sudoers/toke_util.c:146
+#: plugins/sudoers/visudo.c:153 plugins/sudoers/visudo.c:309
+#: plugins/sudoers/visudo.c:315 plugins/sudoers/visudo.c:446
+#: plugins/sudoers/visudo.c:624 plugins/sudoers/visudo.c:985
+#: plugins/sudoers/visudo.c:1051 plugins/sudoers/visudo.c:1095
+#: plugins/sudoers/visudo.c:1197 plugins/sudoers/visudo_json.c:1025 toke.l:849
+#: toke.l:949 toke.l:1106
+msgid "unable to allocate memory"
+msgstr "не могу да доделим меморију"
+
+#: gram.y:481
+msgid "a digest requires a path name"
+msgstr "зборник захтева назив путање"
+
+#: gram.y:607
+msgid "invalid notbefore value"
+msgstr "неисправна вредност не-пре"
+
+#: gram.y:615
+msgid "invalid notafter value"
+msgstr "неисправна вредност не-после"
+
+#: gram.y:624 plugins/sudoers/policy.c:266
+msgid "timeout value too large"
+msgstr "вредност временског истека је превелика"
+
+#: gram.y:626 plugins/sudoers/policy.c:268
+msgid "invalid timeout value"
+msgstr "неисправна вредност временског ограничења"
+
+#: gram.y:1195 gram.y:1202 plugins/sudoers/auth/pam.c:320
+#: plugins/sudoers/auth/pam.c:486 plugins/sudoers/auth/rfc1938.c:109
+#: plugins/sudoers/defaults.c:647 plugins/sudoers/defaults.c:902
+#: plugins/sudoers/defaults.c:1073 plugins/sudoers/editor.c:64
+#: plugins/sudoers/editor.c:82 plugins/sudoers/editor.c:93
+#: plugins/sudoers/env.c:233 plugins/sudoers/filedigest.c:120
+#: plugins/sudoers/filedigest_gcrypt.c:72
+#: plugins/sudoers/filedigest_gcrypt.c:90
+#: plugins/sudoers/filedigest_openssl.c:111 plugins/sudoers/gc.c:52
+#: plugins/sudoers/group_plugin.c:134 plugins/sudoers/interfaces.c:71
+#: plugins/sudoers/iolog.c:941 plugins/sudoers/iolog_path.c:167
+#: plugins/sudoers/ldap.c:449 plugins/sudoers/ldap.c:480
+#: plugins/sudoers/ldap.c:532 plugins/sudoers/ldap.c:565
+#: plugins/sudoers/ldap.c:963 plugins/sudoers/ldap.c:1157
+#: plugins/sudoers/ldap.c:1168 plugins/sudoers/ldap.c:1184
+#: plugins/sudoers/ldap.c:1476 plugins/sudoers/ldap.c:1636
+#: plugins/sudoers/ldap.c:1718 plugins/sudoers/ldap.c:1858
+#: plugins/sudoers/ldap.c:1882 plugins/sudoers/ldap.c:1971
+#: plugins/sudoers/ldap.c:1986 plugins/sudoers/ldap.c:2082
+#: plugins/sudoers/ldap.c:2115 plugins/sudoers/ldap.c:2195
+#: plugins/sudoers/ldap.c:2278 plugins/sudoers/ldap.c:2375
+#: plugins/sudoers/ldap.c:3209 plugins/sudoers/ldap.c:3241
+#: plugins/sudoers/ldap.c:3550 plugins/sudoers/ldap.c:3577
+#: plugins/sudoers/ldap.c:3593 plugins/sudoers/ldap.c:3684
+#: plugins/sudoers/ldap.c:3700 plugins/sudoers/linux_audit.c:76
+#: plugins/sudoers/logging.c:189 plugins/sudoers/logging.c:451
+#: plugins/sudoers/logging.c:472 plugins/sudoers/logging.c:942
+#: plugins/sudoers/match.c:616 plugins/sudoers/match.c:663
+#: plugins/sudoers/match.c:714 plugins/sudoers/match.c:738
+#: plugins/sudoers/match.c:826 plugins/sudoers/match.c:914
+#: plugins/sudoers/parse.c:248 plugins/sudoers/parse.c:260
+#: plugins/sudoers/parse.c:275 plugins/sudoers/parse.c:287
+#: plugins/sudoers/policy.c:99 plugins/sudoers/policy.c:108
+#: plugins/sudoers/policy.c:117 plugins/sudoers/policy.c:141
+#: plugins/sudoers/policy.c:252 plugins/sudoers/policy.c:266
+#: plugins/sudoers/policy.c:268 plugins/sudoers/policy.c:292
+#: plugins/sudoers/policy.c:301 plugins/sudoers/policy.c:340
+#: plugins/sudoers/policy.c:350 plugins/sudoers/policy.c:359
+#: plugins/sudoers/policy.c:368 plugins/sudoers/policy.c:419
+#: plugins/sudoers/policy.c:653 plugins/sudoers/prompt.c:93
+#: plugins/sudoers/pwutil.c:139 plugins/sudoers/pwutil.c:210
+#: plugins/sudoers/pwutil.c:286 plugins/sudoers/pwutil.c:457
+#: plugins/sudoers/pwutil.c:522 plugins/sudoers/pwutil.c:591
+#: plugins/sudoers/pwutil.c:749 plugins/sudoers/pwutil.c:806
+#: plugins/sudoers/pwutil.c:851 plugins/sudoers/pwutil.c:908
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1476
+#: plugins/sudoers/set_perms.c:1641 plugins/sudoers/sssd.c:162
+#: plugins/sudoers/sssd.c:194 plugins/sudoers/sssd.c:237
+#: plugins/sudoers/sssd.c:244 plugins/sudoers/sssd.c:280
+#: plugins/sudoers/sssd.c:390 plugins/sudoers/sssd.c:459
+#: plugins/sudoers/sssd.c:1057 plugins/sudoers/sssd.c:1235
+#: plugins/sudoers/sssd.c:1250 plugins/sudoers/sssd.c:1266
+#: plugins/sudoers/sudoers.c:263 plugins/sudoers/sudoers.c:273
+#: plugins/sudoers/sudoers.c:281 plugins/sudoers/sudoers.c:365
+#: plugins/sudoers/sudoers.c:681 plugins/sudoers/sudoers.c:806
+#: plugins/sudoers/sudoers.c:850 plugins/sudoers/sudoers.c:1122
+#: plugins/sudoers/sudoers_debug.c:106 plugins/sudoers/sudoreplay.c:1234
+#: plugins/sudoers/sudoreplay.c:1346 plugins/sudoers/sudoreplay.c:1386
+#: plugins/sudoers/sudoreplay.c:1395 plugins/sudoers/sudoreplay.c:1405
+#: plugins/sudoers/sudoreplay.c:1413 plugins/sudoers/sudoreplay.c:1417
+#: plugins/sudoers/sudoreplay.c:1573 plugins/sudoers/sudoreplay.c:1577
+#: plugins/sudoers/testsudoers.c:131 plugins/sudoers/testsudoers.c:217
+#: plugins/sudoers/testsudoers.c:234 plugins/sudoers/timestamp.c:389
+#: plugins/sudoers/timestamp.c:433 plugins/sudoers/timestamp.c:852
+#: plugins/sudoers/toke_util.c:56 plugins/sudoers/toke_util.c:109
+#: plugins/sudoers/toke_util.c:146 plugins/sudoers/visudo.c:153
+#: plugins/sudoers/visudo.c:309 plugins/sudoers/visudo.c:315
+#: plugins/sudoers/visudo.c:446 plugins/sudoers/visudo.c:624
+#: plugins/sudoers/visudo.c:985 plugins/sudoers/visudo.c:1051
+#: plugins/sudoers/visudo.c:1095 plugins/sudoers/visudo.c:1197
+#: plugins/sudoers/visudo_json.c:1025 toke.l:849 toke.l:949 toke.l:1106
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:135
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Псеудоним „%s“ је већ одређен"
+
+#: plugins/sudoers/auth/bsdauth.c:68
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "не могу да добавим разред пријаве за корисника „%s“"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+msgid "unable to begin bsd authentication"
+msgstr "не могу да почнем бсд потврђивање идентитета"
+
+#: plugins/sudoers/auth/bsdauth.c:81
+msgid "invalid authentication type"
+msgstr "неисправна врста потврђивање идентитета"
+
+#: plugins/sudoers/auth/bsdauth.c:90
+msgid "unable to initialize BSD authentication"
+msgstr "не могу да покренем БСД потврђивање идентитета"
+
+#: plugins/sudoers/auth/fwtk.c:52
+msgid "unable to read fwtk config"
+msgstr "не могу да читам „fwtk“ подешавања"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to connect to authentication server"
+msgstr "не могу да се повежем на сервер потврђивања идентитета"
+
+#: plugins/sudoers/auth/fwtk.c:63 plugins/sudoers/auth/fwtk.c:87
+#: plugins/sudoers/auth/fwtk.c:121
+msgid "lost connection to authentication server"
+msgstr "изгубио сам везу са сервером потврђивања идентитета"
+
+#: plugins/sudoers/auth/fwtk.c:67
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"грешка сервера потврђивања идентитета:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:111
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: не могу да претворим главника у ниску („%s“): %s"
+
+#: plugins/sudoers/auth/kerb5.c:161
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: не могу да обрадим „%s“: %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: не могу да решим оставу пуномоћства: %s"
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: не могу да доделим опције: %s"
+
+#: plugins/sudoers/auth/kerb5.c:232
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: не могу да добавим пуномоћства: %s"
+
+#: plugins/sudoers/auth/kerb5.c:245
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: не могу да покренем оставу пуномоћства: %s"
+
+#: plugins/sudoers/auth/kerb5.c:248
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: не могу да сместим пуномоћства у оставу: %s"
+
+#: plugins/sudoers/auth/kerb5.c:312
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: не могу да добавим главника домаћина: %s"
+
+#: plugins/sudoers/auth/kerb5.c:326
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Не могу потврдити ТГТ! Могући напад!: %s"
+
+#: plugins/sudoers/auth/pam.c:108
+msgid "unable to initialize PAM"
+msgstr "не могу да покренем ПАМ"
+
+#: plugins/sudoers/auth/pam.c:194
+msgid "account validation failure, is your account locked?"
+msgstr "неуспех провере налога, да ли је ваш налог закључан?"
+
+#: plugins/sudoers/auth/pam.c:198
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Налог или лозинка је истекла, поново поставите лозинку и покушајте поново"
+
+#: plugins/sudoers/auth/pam.c:206
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "не могу да изменим истеклу лозинку: %s"
+
+#: plugins/sudoers/auth/pam.c:211
+msgid "Password expired, contact your system administrator"
+msgstr "Лозинка је истекла, обратите се администратору система"
+
+#: plugins/sudoers/auth/pam.c:215
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Налог је истекао или ПАМ подешавањима недостаје одељак „налог“ за судо, обратите се администратору система"
+
+#: plugins/sudoers/auth/pam.c:229
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Грешка ПАМ потврђивања идентитета: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:97 plugins/sudoers/visudo.c:227
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "ви не постојите у бази подтака „%s“"
+
+#: plugins/sudoers/auth/securid5.c:73
+msgid "failed to initialise the ACE API library"
+msgstr "нисам успео да покренем АЦЕ АПИ библиотеку"
+
+#: plugins/sudoers/auth/securid5.c:99
+msgid "unable to contact the SecurID server"
+msgstr "не могу да ступим у везу са сервером безбеднног ИБ-а"
+
+#: plugins/sudoers/auth/securid5.c:108
+msgid "User ID locked for SecurID Authentication"
+msgstr "ИБ корисника је закључан за потврђивање идентитета безбедног ИБ-а"
+
+#: plugins/sudoers/auth/securid5.c:112 plugins/sudoers/auth/securid5.c:163
+msgid "invalid username length for SecurID"
+msgstr "неисправна дужина корисничког имена за безбедни ИБ"
+
+#: plugins/sudoers/auth/securid5.c:116 plugins/sudoers/auth/securid5.c:168
+msgid "invalid Authentication Handle for SecurID"
+msgstr "неисправна ручка потврђивања идентитета за безбедни ИБ"
+
+#: plugins/sudoers/auth/securid5.c:120
+msgid "SecurID communication failed"
+msgstr "Није успело комуницирање безбедног ИБ-а"
+
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:213
+msgid "unknown SecurID error"
+msgstr "непозната грешка безбедног ИБ-а"
+
+#: plugins/sudoers/auth/securid5.c:158
+msgid "invalid passcode length for SecurID"
+msgstr "неисправна дужина пропусне шифре за безбедни ИБ"
+
+#: plugins/sudoers/auth/sia.c:69 plugins/sudoers/auth/sia.c:125
+msgid "unable to initialize SIA session"
+msgstr "не могу да покренем СИА сесију"
+
+#: plugins/sudoers/auth/sudo_auth.c:126
+msgid "invalid authentication methods"
+msgstr "неисправни начини потврђивања идентитета"
+
+#: plugins/sudoers/auth/sudo_auth.c:128
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Неисправни начини потврђивања идентитета су преведени у судоу! Не можете мешати самостално и несамостално потврђивање идентитета."
+
+#: plugins/sudoers/auth/sudo_auth.c:224 plugins/sudoers/auth/sudo_auth.c:274
+msgid "no authentication methods"
+msgstr "нема начина потврђивања идентитета"
+
+#: plugins/sudoers/auth/sudo_auth.c:226
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Нема начина потврђивања идентитета преведених у судоу! Ако желите да искључите потврђивање идентитета, користите „--disable-authentication“."
+
+#: plugins/sudoers/auth/sudo_auth.c:276
+msgid "Unable to initialize authentication methods."
+msgstr "Не могу да покренем методе потврђивања идентитета."
+
+#: plugins/sudoers/auth/sudo_auth.c:441
+msgid "Authentication methods:"
+msgstr "Начини потврђивања идентитета:"
+
+#: plugins/sudoers/bsm_audit.c:120 plugins/sudoers/bsm_audit.c:211
+msgid "Could not determine audit condition"
+msgstr "Не могу да утврдим услов прегледа"
+
+#: plugins/sudoers/bsm_audit.c:183 plugins/sudoers/bsm_audit.c:273
+msgid "unable to commit audit record"
+msgstr "не могу да предам снимак прегледа"
+
+#: plugins/sudoers/check.c:252
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Верујемо да вам је администратор система објаснио неке ствари.\n"
+"Обично се своде на следеће три:\n"
+"\n"
+" #1) Поштујте приватност других.\n"
+" #2) Размислите пре куцања.\n"
+" #3) Са великом моћи долази и велика одговорност.\n"
+"\n"
+
+#: plugins/sudoers/check.c:295 plugins/sudoers/check.c:305
+#: plugins/sudoers/sudoers.c:724 plugins/sudoers/sudoers.c:769
+#, c-format
+msgid "unknown uid: %u"
+msgstr "непознат јиб: %u"
+
+#: plugins/sudoers/check.c:300 plugins/sudoers/iolog.c:260
+#: plugins/sudoers/policy.c:826 plugins/sudoers/sudoers.c:1161
+#: plugins/sudoers/testsudoers.c:208 plugins/sudoers/testsudoers.c:366
+#, c-format
+msgid "unknown user: %s"
+msgstr "непознат корисник: %s"
+
+#: plugins/sudoers/def_data.c:41
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Помоћник сисдневника ако је сисдневник коришћен за пријављивање: %s"
+
+#: plugins/sudoers/def_data.c:45
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Приоритет системског дневника за коришћење када корисник успешно потврди идентитет: %s"
+
+#: plugins/sudoers/def_data.c:49
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Приоритет системског дневника за коришћење када корисник неуспешно потврди идентитет: %s"
+
+#: plugins/sudoers/def_data.c:53
+msgid "Put OTP prompt on its own line"
+msgstr "Поставља ОТП упит на свом реду"
+
+#: plugins/sudoers/def_data.c:57
+msgid "Ignore '.' in $PATH"
+msgstr "Занемарује . у $ПУТАЊИ"
+
+#: plugins/sudoers/def_data.c:61
+msgid "Always send mail when sudo is run"
+msgstr "Увек шаље пошту када је судо покренут"
+
+#: plugins/sudoers/def_data.c:65
+msgid "Send mail if user authentication fails"
+msgstr "Пошаљи поруку ако потврђивање идентитета корисника не успе"
+
+#: plugins/sudoers/def_data.c:69
+msgid "Send mail if the user is not in sudoers"
+msgstr "Пошаљи поруку ако корисник није у судоерсу"
+
+#: plugins/sudoers/def_data.c:73
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Пошаљи поруку ако корисник није у судоерсу за овог домаћина"
+
+#: plugins/sudoers/def_data.c:77
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Пошаљи поруку ако кориснику није дозвољено да покрене наредбу"
+
+#: plugins/sudoers/def_data.c:81
+msgid "Send mail if the user tries to run a command"
+msgstr "Пошаљи поруку ако корисник покуша да покрене наредбу"
+
+#: plugins/sudoers/def_data.c:85
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Користи одвојене временске ознаке за сваку комбинацију корисник/конзола"
+
+#: plugins/sudoers/def_data.c:89
+msgid "Lecture user the first time they run sudo"
+msgstr "Подучава корисника када први пут покрену судо"
+
+#: plugins/sudoers/def_data.c:93
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Датотека садржи судо обучавања: %s"
+
+#: plugins/sudoers/def_data.c:97
+msgid "Require users to authenticate by default"
+msgstr "Захтева да корисници потврде идентитет по основи"
+
+#: plugins/sudoers/def_data.c:101
+msgid "Root may run sudo"
+msgstr "Администратор може да покрене судо"
+
+#: plugins/sudoers/def_data.c:105
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Бележи назив домаћина у (не-сисдневник) датотеци дневника"
+
+#: plugins/sudoers/def_data.c:109
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Бележи годину у (не-сисдневник) датотеци дневника"
+
+#: plugins/sudoers/def_data.c:113
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Ако је судо призван без аргумената, покреће шкољку"
+
+#: plugins/sudoers/def_data.c:117
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Подешава $HOME на крајњег корисника када покреће шкољку са „-s“"
+
+#: plugins/sudoers/def_data.c:121
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Увек подешава $HOME на циљни лични директоријум корисника"
+
+#: plugins/sudoers/def_data.c:125
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Дозвољава прикупљање неких података да би дао корисне поруке грешака"
+
+#: plugins/sudoers/def_data.c:129
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Захтева потпуно одређене називе домаћина у датотеци судоерса"
+
+#: plugins/sudoers/def_data.c:133
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Вређа корисника када унесе нетачну лозинку"
+
+#: plugins/sudoers/def_data.c:137
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Дозвољава кориснику да покрене судо само ако има конзолу"
+
+#: plugins/sudoers/def_data.c:141
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Висудо ће поштовати променљиву окружења УРЕЂИВАЧА"
+
+#: plugins/sudoers/def_data.c:145
+msgid "Prompt for root's password, not the users's"
+msgstr "Тражи администраторову лозинку, а не корисника"
+
+#: plugins/sudoers/def_data.c:149
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Тражи корисникову лозинку покреникао_основни, а не корисника"
+
+#: plugins/sudoers/def_data.c:153
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Тражи корисникову лозинку мете, а не корисника"
+
+#: plugins/sudoers/def_data.c:157
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Примењује основности у циљни кориснички разред пријављивања ако постоји"
+
+#: plugins/sudoers/def_data.c:161
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Подешава променљиве окружења НАЗИВДНЕВНИКА и КОРИСНИК"
+
+#: plugins/sudoers/def_data.c:165
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Подешава само ефективни јиб на крајњег корисника, а не стваран јиб"
+
+#: plugins/sudoers/def_data.c:169
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Не покреће вектор групе ка оном крајњег корисника"
+
+#: plugins/sudoers/def_data.c:173
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Дужина за преламање редова у датотеци дневника (0 — без преламања): %u"
+
+#: plugins/sudoers/def_data.c:177
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Време истека временске ознаке потврђивања идентитета: %.1f минута"
+
+#: plugins/sudoers/def_data.c:181
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Време истека упита лозинке: %.1f минута"
+
+#: plugins/sudoers/def_data.c:185
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Број покушаја за уношење лозинке: %u"
+
+#: plugins/sudoers/def_data.c:189
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Умаска за коришћење или 0777 за коришћење корисника: 0%o"
+
+#: plugins/sudoers/def_data.c:193
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Путања до датотеке дневника: %s"
+
+#: plugins/sudoers/def_data.c:197
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Путања до програма поште: %s"
+
+#: plugins/sudoers/def_data.c:201
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Опције за програм поште: %s"
+
+#: plugins/sudoers/def_data.c:205
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Адреса на коју послати поруку: %s"
+
+#: plugins/sudoers/def_data.c:209
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Адреса са које послати поруку: %s"
+
+#: plugins/sudoers/def_data.c:213
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Ред теме за поруке поште: %s"
+
+#: plugins/sudoers/def_data.c:217
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Порука нетачне лозинке: %s"
+
+#: plugins/sudoers/def_data.c:221
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Путања до директоријума стања обучавања: %s"
+
+#: plugins/sudoers/def_data.c:225
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Путања до директоријума временске ознаке потврђивања идентитета: %s"
+
+#: plugins/sudoers/def_data.c:229
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Власник директоријума временске ознаке потврђивања идентитета: %s"
+
+#: plugins/sudoers/def_data.c:233
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Корисницима у овој групи се не захтева лозинка и ПУТАЊА: %s"
+
+#: plugins/sudoers/def_data.c:237
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Основни упит лозинке: %s"
+
+#: plugins/sudoers/def_data.c:241
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Ако је подешено, упит лозинке ће преписати системски упит у свим случајевима."
+
+#: plugins/sudoers/def_data.c:245
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Основни корисник за покретање наредби као: %s"
+
+#: plugins/sudoers/def_data.c:249
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Вредност за преписивање корисничке $ПУТАЊЕ са: %s"
+
+#: plugins/sudoers/def_data.c:253
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Путања до уређивача кога ће да користи висудо: %s"
+
+#: plugins/sudoers/def_data.c:257
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Када да затражи лозинку за псеудонаредбу „list“: %s"
+
+#: plugins/sudoers/def_data.c:261
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Када да затражи лозинку за псеудонаредбу „verify“: %s"
+
+#: plugins/sudoers/def_data.c:265
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Унапред учитава лажне функције извршавања које се налазе у библиотеци „sudo_noexec“"
+
+#: plugins/sudoers/def_data.c:269
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Ако је ЛДАП директоријум изнет, да ли занемарујемо месну датотеку судоерса"
+
+#: plugins/sudoers/def_data.c:273
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Описници датотека >= %d ће бити затворени пре извршавања наредбе"
+
+#: plugins/sudoers/def_data.c:277
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Ако је подешено, корисници могу да препишу вредност „closefrom“ са опцијом „-C“"
+
+#: plugins/sudoers/def_data.c:281
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Дозвољава корисницима да подесе произвољне променљиве окружења"
+
+#: plugins/sudoers/def_data.c:285
+msgid "Reset the environment to a default set of variables"
+msgstr "Враћа окружење на основни скуп променљивих"
+
+#: plugins/sudoers/def_data.c:289
+msgid "Environment variables to check for sanity:"
+msgstr "Променљиве окружења за проверу исправности:"
+
+#: plugins/sudoers/def_data.c:293
+msgid "Environment variables to remove:"
+msgstr "Променљиве окружења за уклањање:"
+
+#: plugins/sudoers/def_data.c:297
+msgid "Environment variables to preserve:"
+msgstr "Променљиве окружења за очување:"
+
+#: plugins/sudoers/def_data.c:301
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "СЕЛинукс улога за употребу у новом контексту безбедности: %s"
+
+#: plugins/sudoers/def_data.c:305
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "СЕЛинукс врста за употребу у новом контексту безбедности: %s"
+
+#: plugins/sudoers/def_data.c:309
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Путања до судо-посебне датотеке окружења: %s"
+
+#: plugins/sudoers/def_data.c:313
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Путања до ограничене судо-посебне датотеке окружења: %s"
+
+#: plugins/sudoers/def_data.c:317
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Језк за коришћење при обради судоерса: %s"
+
+#: plugins/sudoers/def_data.c:321
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Дозвољава да судо тражи лозинку чак и ако би била видљива"
+
+#: plugins/sudoers/def_data.c:325
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Обезбеђује видну повратну поруку при тражењу лозинке када постоји унос корисника"
+
+#: plugins/sudoers/def_data.c:329
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Користи брже упоређивање које је мање тачно али не приступа систему датотека"
+
+#: plugins/sudoers/def_data.c:333
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "Умаска наведена у судоерсима ће преписати корисникову, чак и ако има већа овлашћења"
+
+#: plugins/sudoers/def_data.c:337
+msgid "Log user's input for the command being run"
+msgstr "Бележи корисников улаз за покренуту наредбу"
+
+#: plugins/sudoers/def_data.c:341
+msgid "Log the output of the command being run"
+msgstr "Бележи излаз покренуте наредбе"
+
+#: plugins/sudoers/def_data.c:345
+msgid "Compress I/O logs using zlib"
+msgstr "Пакује У/И дневнике користећи злиб"
+
+#: plugins/sudoers/def_data.c:349
+msgid "Always run commands in a pseudo-tty"
+msgstr "Увек покреће наредбе у привидној конзоли"
+
+#: plugins/sudoers/def_data.c:353
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Прикључак за подршку не-Јуникс групе: %s"
+
+#: plugins/sudoers/def_data.c:357
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Директоријум за смештај улазних/излазних дневника: %s"
+
+#: plugins/sudoers/def_data.c:361
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Датотека за смештај улазно/излазног дневника: %s"
+
+#: plugins/sudoers/def_data.c:365
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Додаје унос у датотеку „utmp/utmpx“ када додељује „pty“"
+
+#: plugins/sudoers/def_data.c:369
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Подешава корисника у „utmp“-у на корисника покрени-као, не призивајући корисника"
+
+#: plugins/sudoers/def_data.c:373
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Скуп допуштених повластица: %s"
+
+#: plugins/sudoers/def_data.c:377
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Скуп повластица ограничења: %s"
+
+#: plugins/sudoers/def_data.c:381
+msgid "Run commands on a pty in the background"
+msgstr "Покреће наредбе у позадини на назовитерминалу"
+
+#: plugins/sudoers/def_data.c:385
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "Назив ПАМ услуге за коришћење: %s"
+
+#: plugins/sudoers/def_data.c:389
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "Назив ПАМ услуге за шкољке пријављивања: %s"
+
+#: plugins/sudoers/def_data.c:393
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Покушава да успостави ПАМ пуномоћства за циљног корисника"
+
+#: plugins/sudoers/def_data.c:397
+msgid "Create a new PAM session for the command to run in"
+msgstr "Прави нову ПАМ сесију за покретање наредбе"
+
+#: plugins/sudoers/def_data.c:401
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Највећи број низа У/И дневника: %u"
+
+#: plugins/sudoers/def_data.c:405
+msgid "Enable sudoers netgroup support"
+msgstr "Укључује подршку нетгрупе судоерса"
+
+#: plugins/sudoers/def_data.c:409
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Проверава родитељски директоријум за уписивошћу када уређује датотеке са „sudoedit“"
+
+#: plugins/sudoers/def_data.c:413
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Прати симболичке везе када уређује датотеке са „sudoedit“"
+
+#: plugins/sudoers/def_data.c:417
+msgid "Query the group plugin for unknown system groups"
+msgstr "Пропитује прикључак групе за непознатим групама система"
+
+#: plugins/sudoers/def_data.c:421
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Упоређује мрежне групе на основу читавог слога: корисник, домаћин и домен"
+
+#: plugins/sudoers/def_data.c:425
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Допушта покретање наредби чак и ако судо не може да пише у дневник прегледа"
+
+#: plugins/sudoers/def_data.c:429
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Допушта покретање наредби чак и ако судо не може да пише у дневник У/И"
+
+#: plugins/sudoers/def_data.c:433
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Допушта покретање наредби чак и ако судо не може да пише у датотеку дневника"
+
+#: plugins/sudoers/def_data.c:437
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Решава групе у судоерсима и упоређује ИД групе, а не назив"
+
+#: plugins/sudoers/def_data.c:441
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Уноси дневника већи од ове вредности биће подељени на више порука системског дневника: %u"
+
+#: plugins/sudoers/def_data.c:445
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Корисник који ће поседовати датотеке дневника У/И: %s"
+
+#: plugins/sudoers/def_data.c:449
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Група која ће поседовати датотеке дневника У/И: %s"
+
+#: plugins/sudoers/def_data.c:453
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Режим датотеке за коришћење за датотеке дневника У/И: 0%o"
+
+#: plugins/sudoers/def_data.c:457
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Извршава наредбе описником датотеке уместо путањом: %s"
+
+#: plugins/sudoers/def_data.c:461
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Занемарује непознате уносе основности у судоерсу уместо да даје упозорење"
+
+#: plugins/sudoers/def_data.c:465
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Време у секундама након ког ће наредба бити окончана: %u"
+
+#: plugins/sudoers/def_data.c:469
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Допушта кориснику да наведе време на линији наредби"
+
+#: plugins/sudoers/def_data.c:473
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Пребацује У/И податке дневника на диск одмах уместо да га смешта у међумеморију"
+
+#: plugins/sudoers/def_data.c:477
+msgid "Include the process ID when logging via syslog"
+msgstr "Укључује ИБ процеса приликом пријављивања путем дневника система"
+
+#: plugins/sudoers/def_data.c:481
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Врста временске ознаке потврђивања идентитета: %s"
+
+#: plugins/sudoers/defaults.c:220
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d непознат унос основности „%s“"
+
+#: plugins/sudoers/defaults.c:223
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: непознат унос основности „%s“"
+
+#: plugins/sudoers/defaults.c:263
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d није наведена вредност за „%s“"
+
+#: plugins/sudoers/defaults.c:266
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: није наведена вредност за „%s“"
+
+#: plugins/sudoers/defaults.c:286
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d вредност за „%s“ мора да почиње /"
+
+#: plugins/sudoers/defaults.c:289
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: вредност за „%s“ мора да почиње /"
+
+#: plugins/sudoers/defaults.c:314
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d опција „%s“ не узима вредност"
+
+#: plugins/sudoers/defaults.c:317
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: опција „%s“ не узима вредност"
+
+#: plugins/sudoers/defaults.c:339
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d неисправна врста основности 0x%x за опцију „%s“"
+
+#: plugins/sudoers/defaults.c:342
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: неисправна врста основности 0x%x за опцију „%s“"
+
+#: plugins/sudoers/defaults.c:352
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d вредност „%s“ је неисправна за опцију „%s“"
+
+#: plugins/sudoers/defaults.c:355
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: вредност „%s“ је неисправна за опцију „%s“"
+
+#: plugins/sudoers/env.c:295 plugins/sudoers/env.c:302
+#: plugins/sudoers/env.c:407 plugins/sudoers/ldap.c:453
+#: plugins/sudoers/ldap.c:543 plugins/sudoers/ldap.c:1253
+#: plugins/sudoers/ldap.c:1480 plugins/sudoers/ldap.c:1806
+#: plugins/sudoers/linux_audit.c:82 plugins/sudoers/logging.c:947
+#: plugins/sudoers/policy.c:537 plugins/sudoers/policy.c:547
+#: plugins/sudoers/prompt.c:161 plugins/sudoers/sudoers.c:872
+#: plugins/sudoers/testsudoers.c:238 plugins/sudoers/toke_util.c:158
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "унутрашња грешка, прекорачење „%s“"
+
+#: plugins/sudoers/env.c:376
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: оштећено стави окружење, дужине не одговарају"
+
+#: plugins/sudoers/env.c:1055
+msgid "unable to rebuild the environment"
+msgstr "не могу поново да изградим окружење"
+
+#: plugins/sudoers/env.c:1129
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "извините, није вам дозвољено да подесите следеће променљиве окружења: %s"
+
+#: plugins/sudoers/filedigest.c:104 plugins/sudoers/filedigest_gcrypt.c:66
+#: plugins/sudoers/filedigest_openssl.c:95
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "неподржана врста прихватања потврђивања иднтитета „%d“ за „%s“"
+
+#: plugins/sudoers/filedigest.c:129 plugins/sudoers/filedigest_gcrypt.c:98
+#: plugins/sudoers/filedigest_openssl.c:120
+#, c-format
+msgid "%s: read error"
+msgstr "%s: грешка читања"
+
+#: plugins/sudoers/group_plugin.c:86
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "„%s“ мора бити у власништву јиб-а %d"
+
+#: plugins/sudoers/group_plugin.c:90
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "Само корисник може да пише у „%s“"
+
+#: plugins/sudoers/group_plugin.c:98 plugins/sudoers/sssd.c:398
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "не могу да учитам %s: %s"
+
+#: plugins/sudoers/group_plugin.c:104
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "не могу да нађем симбол „group_plugin“ у „%s“"
+
+#: plugins/sudoers/group_plugin.c:109
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: несагласно веће издање прикључка групе %d, очекивано је %d"
+
+#: plugins/sudoers/interfaces.c:79 plugins/sudoers/interfaces.c:96
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "не могу да обрадим ИП адресу „%s“"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "не могу да обрадим мрежну маску „%s“"
+
+#: plugins/sudoers/interfaces.c:129
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Месна ИП адреса и парови мрежне маске:\n"
+
+#: plugins/sudoers/iolog.c:121 plugins/sudoers/mkdir_parents.c:75
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s постоји али није директоријум (0%o)"
+
+#: plugins/sudoers/iolog.c:146 plugins/sudoers/iolog.c:187
+#: plugins/sudoers/mkdir_parents.c:64 plugins/sudoers/timestamp.c:170
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "не могу да направим директоријум „%s“"
+
+#: plugins/sudoers/iolog.c:191 plugins/sudoers/visudo.c:740
+#: plugins/sudoers/visudo.c:750
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "не могу да променим режим „%s“ на 0%o"
+
+#: plugins/sudoers/iolog.c:299 plugins/sudoers/sudoers.c:1192
+#: plugins/sudoers/testsudoers.c:390
+#, c-format
+msgid "unknown group: %s"
+msgstr "непозната група: %s"
+
+#: plugins/sudoers/iolog.c:418 plugins/sudoers/sudoers.c:928
+#: plugins/sudoers/sudoreplay.c:349 plugins/sudoers/sudoreplay.c:1335
+#: plugins/sudoers/sudoreplay.c:1539 plugins/sudoers/timestamp.c:398
+#: plugins/sudoers/visudo.c:972 plugins/sudoers/visudo_json.c:1001
+#: plugins/sudoers/visudo_json.c:1014
+#, c-format
+msgid "unable to open %s"
+msgstr "не могу да отворим „%s“"
+
+#: plugins/sudoers/iolog.c:469 plugins/sudoers/sudoers.c:932
+#: plugins/sudoers/sudoreplay.c:831 plugins/sudoers/sudoreplay.c:1650
+#, c-format
+msgid "unable to read %s"
+msgstr "не могу да прочитам „%s“"
+
+#: plugins/sudoers/iolog.c:505 plugins/sudoers/sudoreplay.c:1104
+#: plugins/sudoers/timestamp.c:290 plugins/sudoers/timestamp.c:293
+#, c-format
+msgid "unable to write to %s"
+msgstr "не могу да пишем у „%s“"
+
+#: plugins/sudoers/iolog.c:584 plugins/sudoers/iolog.c:803
+#, c-format
+msgid "unable to create %s"
+msgstr "не могу да направим „%s“"
+
+#: plugins/sudoers/iolog.c:1035 plugins/sudoers/iolog.c:1110
+#: plugins/sudoers/iolog.c:1191
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "не могу да пишем у датотеку дневника У/И: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, file index %d not open"
+msgstr "%s: унутрашња грешка, индекс датотеке %d није отворен"
+
+#: plugins/sudoers/ldap.c:431
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: прикључник је превелик"
+
+#: plugins/sudoers/ldap.c:491
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "неподржана врста ЛДАП путање: %s"
+
+#: plugins/sudoers/ldap.c:518
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "не могу да помешам лдап и лдапс путање"
+
+#: plugins/sudoers/ldap.c:522 plugins/sudoers/ldap.c:558
+msgid "starttls not supported when using ldaps"
+msgstr "старттлс није подржано када се користи лдапс"
+
+#: plugins/sudoers/ldap.c:629
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "не могу да покренем ССЛ уверење и бп кључа: %s"
+
+#: plugins/sudoers/ldap.c:632
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "морате да подесите „TLS_CERT“ у „%s“ да користите ССЛ"
+
+#: plugins/sudoers/ldap.c:1239
+msgid "unable to get GMT time"
+msgstr "не могу да добавим ГМТ време"
+
+#: plugins/sudoers/ldap.c:1245
+msgid "unable to format timestamp"
+msgstr "не могу да обликујем временску ознаку"
+
+#: plugins/sudoers/ldap.c:1961
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/ldap.c:2533
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"ЛДАП улога: %s\n"
+
+#: plugins/sudoers/ldap.c:2535
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"ЛДАП улога: НЕПОЗНАТО\n"
+
+#: plugins/sudoers/ldap.c:2591
+#, c-format
+msgid " Order: %s\n"
+msgstr " Поредак: %s\n"
+
+#: plugins/sudoers/ldap.c:2599 plugins/sudoers/parse.c:614
+#: plugins/sudoers/sssd.c:1628
+#, c-format
+msgid " Commands:\n"
+msgstr " Наредбе:\n"
+
+#: plugins/sudoers/ldap.c:3161
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "не могу да покренем ЛДАП: %s"
+
+#: plugins/sudoers/ldap.c:3197
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "„start_tls“ је наведено али ЛДАП библиотеке не подржавају „ldap_start_tls_s()“ или „ldap_start_tls_s_np()“"
+
+#: plugins/sudoers/ldap.c:3446
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "неисправна особина „sudoOrder“: %s"
+
+#: plugins/sudoers/linux_audit.c:52
+msgid "unable to open audit system"
+msgstr "не могу да отворим систем прегледа"
+
+#: plugins/sudoers/linux_audit.c:93
+msgid "unable to send audit message"
+msgstr "не могу да пошаљем поруку прегледа"
+
+#: plugins/sudoers/logging.c:107
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:135
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (наредба је настављена) %s"
+
+#: plugins/sudoers/logging.c:164
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "не могу да отворим датотеку дневника: %s"
+
+#: plugins/sudoers/logging.c:172
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "не могу да закључам датотеку дневника: %s"
+
+#: plugins/sudoers/logging.c:205
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "не могу да запишем датотеку дневника: %s"
+
+#: plugins/sudoers/logging.c:234
+msgid "No user or host"
+msgstr "Нема корисника или домаћина"
+
+#: plugins/sudoers/logging.c:236
+msgid "validation failure"
+msgstr "неуспех потврђивања"
+
+#: plugins/sudoers/logging.c:243
+msgid "user NOT in sudoers"
+msgstr "корисник НИЈЕ у судоерсу"
+
+#: plugins/sudoers/logging.c:245
+msgid "user NOT authorized on host"
+msgstr "корисник НИЈЕ овлашћен на домаћину"
+
+#: plugins/sudoers/logging.c:247
+msgid "command not allowed"
+msgstr "наредба није допуштена"
+
+#: plugins/sudoers/logging.c:282
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "„%s“ се не налази у датотеци судоерса. О овом инциденту ће бити поднет извештај.\n"
+
+#: plugins/sudoers/logging.c:285
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "„%s“ нема права да покрене судо над „%s“. О овом инциденту ће бити поднет извештај.\n"
+
+#: plugins/sudoers/logging.c:289
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Извините, корисник %s не може покренути судо на %s.\n"
+
+#: plugins/sudoers/logging.c:292
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Извините, кориснику %s није дозвољено да изврши „%s%s%s“ као %s%s%s на %s.\n"
+
+#: plugins/sudoers/logging.c:329 plugins/sudoers/sudoers.c:472
+#: plugins/sudoers/sudoers.c:474 plugins/sudoers/sudoers.c:476
+#: plugins/sudoers/sudoers.c:478 plugins/sudoers/sudoers.c:1297
+#: plugins/sudoers/sudoers.c:1299
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: нема такве наредбе"
+
+#: plugins/sudoers/logging.c:331 plugins/sudoers/sudoers.c:468
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"занемарујем „%s“ пронађено у „.“\n"
+"Користите „sudo ./%s“ ако је то „%s“ које желите да покренете."
+
+#: plugins/sudoers/logging.c:348
+msgid "authentication failure"
+msgstr "потврђивање идентитета није успело"
+
+#: plugins/sudoers/logging.c:374
+msgid "a password is required"
+msgstr "потребна је лозинка"
+
+#: plugins/sudoers/logging.c:445 plugins/sudoers/logging.c:511
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u покушај нетачне лозинке"
+msgstr[1] "%u покушаја нетачне лозинке"
+msgstr[2] "%u покушаја нетачне лозинке"
+
+#: plugins/sudoers/logging.c:598
+msgid "unable to fork"
+msgstr "не могу да исцепим"
+
+#: plugins/sudoers/logging.c:606 plugins/sudoers/logging.c:658
+#, c-format
+msgid "unable to fork: %m"
+msgstr "не могу да исцепим: %m"
+
+#: plugins/sudoers/logging.c:648
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "не могу да отворим спојку: %m"
+
+#: plugins/sudoers/logging.c:673
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "не могу да удвостручим стандардни улаз: %m"
+
+#: plugins/sudoers/logging.c:711
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "не могу да извршим „%s“: %m"
+
+#: plugins/sudoers/match.c:771
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "приказ за %s (%s) није у %s облику"
+
+#: plugins/sudoers/mkdir_parents.c:70 plugins/sudoers/sudoers.c:943
+#: plugins/sudoers/visudo.c:439 plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to stat %s"
+msgstr "не могу да добијем податке о „%s“"
+
+#: plugins/sudoers/parse.c:115
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "грешка обраде у %s близу реда %d"
+
+#: plugins/sudoers/parse.c:118
+#, c-format
+msgid "parse error in %s"
+msgstr "грешка обраде у %s"
+
+#: plugins/sudoers/parse.c:540
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Унос судоерса:\n"
+
+#: plugins/sudoers/parse.c:541
+#, c-format
+msgid " RunAsUsers: "
+msgstr " „Покрени-као“ корисници: "
+
+#: plugins/sudoers/parse.c:555
+#, c-format
+msgid " RunAsGroups: "
+msgstr " „Покрени-као“ групе: "
+
+#: plugins/sudoers/parse.c:564
+#, c-format
+msgid " Options: "
+msgstr " Опције: "
+
+#: plugins/sudoers/policy.c:242 plugins/sudoers/testsudoers.c:261
+msgid "unable to parse network address list"
+msgstr "не могу да обрадим списак адреса мреже"
+
+#: plugins/sudoers/policy.c:711 plugins/sudoers/visudo.c:910
+#, c-format
+msgid "unable to execute %s"
+msgstr "не могу да извршим „%s“"
+
+#: plugins/sudoers/policy.c:844
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Издање %s прикључка политике судоерса\n"
+
+#: plugins/sudoers/policy.c:846
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Граматика датотеке судоерса издање %d\n"
+
+#: plugins/sudoers/policy.c:850
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Путања судоерса: %s\n"
+
+#: plugins/sudoers/policy.c:853
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "путања нс-прекидача: %s\n"
+
+#: plugins/sudoers/policy.c:855
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "путања лдап.подешавања: %s\n"
+
+#: plugins/sudoers/policy.c:856
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "путања лдап.тајне: %s\n"
+
+#: plugins/sudoers/policy.c:889
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "немогу да региструјем прикачку врсте „%d“ (издање %d.%d)"
+
+#: plugins/sudoers/pwutil.c:162 plugins/sudoers/pwutil.c:180
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "не могу да сместим у оставу јиб „%u“, нема више меморије"
+
+#: plugins/sudoers/pwutil.c:174
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "не могу да сместим у оставу јиб „%u“, већ постоји"
+
+#: plugins/sudoers/pwutil.c:234 plugins/sudoers/pwutil.c:251
+#: plugins/sudoers/pwutil.c:313 plugins/sudoers/pwutil.c:358
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "не могу да сместим у оставу корисника „%s“, нема више меморије"
+
+#: plugins/sudoers/pwutil.c:246
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "не могу да сместим у оставу корисника „%s“, већ постоји"
+
+#: plugins/sudoers/pwutil.c:474 plugins/sudoers/pwutil.c:492
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "не могу да сместим у оставу гиб „%u“, нема више меморије"
+
+#: plugins/sudoers/pwutil.c:486
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "не могу да сместим у оставу гиб „%u“, већ постоји"
+
+#: plugins/sudoers/pwutil.c:540 plugins/sudoers/pwutil.c:557
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:646
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "не могу да сместим у оставу групу „%s“, нема више меморије"
+
+#: plugins/sudoers/pwutil.c:552
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "не могу да сместим у оставу групу „%s“, већ постоји"
+
+#: plugins/sudoers/pwutil.c:772 plugins/sudoers/pwutil.c:824
+#: plugins/sudoers/pwutil.c:874 plugins/sudoers/pwutil.c:926
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "не могу да сместим у оставу списак групе за „%s“, већ постоји"
+
+#: plugins/sudoers/pwutil.c:778 plugins/sudoers/pwutil.c:829
+#: plugins/sudoers/pwutil.c:880 plugins/sudoers/pwutil.c:931
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "не могу да сместим у оставу списак групе за „%s“, нема више меморије"
+
+#: plugins/sudoers/pwutil.c:818
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "не могу да обрадим групе за „%s“"
+
+#: plugins/sudoers/pwutil.c:920
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "не могу да обрадим гид-ове за „%s“"
+
+#: plugins/sudoers/set_perms.c:113 plugins/sudoers/set_perms.c:469
+#: plugins/sudoers/set_perms.c:912 plugins/sudoers/set_perms.c:1239
+#: plugins/sudoers/set_perms.c:1556
+msgid "perm stack overflow"
+msgstr "стално прекорачење спремника"
+
+#: plugins/sudoers/set_perms.c:121 plugins/sudoers/set_perms.c:400
+#: plugins/sudoers/set_perms.c:477 plugins/sudoers/set_perms.c:779
+#: plugins/sudoers/set_perms.c:920 plugins/sudoers/set_perms.c:1163
+#: plugins/sudoers/set_perms.c:1247 plugins/sudoers/set_perms.c:1489
+#: plugins/sudoers/set_perms.c:1564 plugins/sudoers/set_perms.c:1654
+msgid "perm stack underflow"
+msgstr "стално поткорачење спремника"
+
+#: plugins/sudoers/set_perms.c:180 plugins/sudoers/set_perms.c:523
+#: plugins/sudoers/set_perms.c:1298 plugins/sudoers/set_perms.c:1596
+msgid "unable to change to root gid"
+msgstr "не могу да пређем на гиб администратора"
+
+#: plugins/sudoers/set_perms.c:269 plugins/sudoers/set_perms.c:620
+#: plugins/sudoers/set_perms.c:1049 plugins/sudoers/set_perms.c:1375
+msgid "unable to change to runas gid"
+msgstr "не могу да пређем на гиб покреникао"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to set runas group vector"
+msgstr "не могу да подесим вектор „покрени-као група“"
+
+#: plugins/sudoers/set_perms.c:285 plugins/sudoers/set_perms.c:636
+#: plugins/sudoers/set_perms.c:1063 plugins/sudoers/set_perms.c:1389
+msgid "unable to change to runas uid"
+msgstr "не могу да пређем на јиб покреникао"
+
+#: plugins/sudoers/set_perms.c:303 plugins/sudoers/set_perms.c:654
+#: plugins/sudoers/set_perms.c:1079 plugins/sudoers/set_perms.c:1405
+msgid "unable to change to sudoers gid"
+msgstr "не могу да пређем на гиб судоерса"
+
+#: plugins/sudoers/set_perms.c:387 plugins/sudoers/set_perms.c:766
+#: plugins/sudoers/set_perms.c:1150 plugins/sudoers/set_perms.c:1476
+#: plugins/sudoers/set_perms.c:1641
+msgid "too many processes"
+msgstr "превише процеса"
+
+#: plugins/sudoers/solaris_audit.c:51
+msgid "unable to get current working directory"
+msgstr "не могу да добавим тренутни радни директоријум"
+
+#: plugins/sudoers/solaris_audit.c:59
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "корисничка_наредба скраћене путање прегледа: %s"
+
+#: plugins/sudoers/solaris_audit.c:66
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "„argv[0]“ скраћене путање прегледа: %s"
+
+#: plugins/sudoers/solaris_audit.c:115
+msgid "audit_failure message too long"
+msgstr "порука неуспеха прегледа је предуга"
+
+#: plugins/sudoers/sssd.c:400
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "не могу да покренем ССС извор. Да ли је СССД инсталиран на вашем рачунару?"
+
+#: plugins/sudoers/sssd.c:408 plugins/sudoers/sssd.c:417
+#: plugins/sudoers/sssd.c:426 plugins/sudoers/sssd.c:435
+#: plugins/sudoers/sssd.c:444
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "не могу да нађем симбол „%s“ у „%s“"
+
+#: plugins/sudoers/sssd.c:1543
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: %s\n"
+msgstr ""
+"\n"
+"СССД улога: %s\n"
+
+#: plugins/sudoers/sssd.c:1548
+#, c-format
+msgid ""
+"\n"
+"SSSD Role: UNKNOWN\n"
+msgstr ""
+"\n"
+"СССД улога: НЕПОЗНАТО\n"
+
+#: plugins/sudoers/sudo_nss.c:290
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Упоређује уносе основности за „%s“ на %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:308
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Покрени-као и Наредбено-посебне основности за „%s“:\n"
+
+#: plugins/sudoers/sudo_nss.c:326
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Корисник „%s“ може да покреће следеће наредбе на %s:\n"
+
+#: plugins/sudoers/sudo_nss.c:339
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Корисник „%s“ нема права да покрене судо над „%s“.\n"
+
+#: plugins/sudoers/sudoers.c:168 plugins/sudoers/testsudoers.c:247
+#: plugins/sudoers/visudo.c:233 plugins/sudoers/visudo.c:612
+#: plugins/sudoers/visudo.c:976
+msgid "unable to initialize sudoers default values"
+msgstr "не могу да покренем основне вредности судоерса"
+
+#: plugins/sudoers/sudoers.c:198 plugins/sudoers/sudoers.c:890
+msgid "problem with defaults entries"
+msgstr "неприлике са основним уносима"
+
+#: plugins/sudoers/sudoers.c:205
+msgid "no valid sudoers sources found, quitting"
+msgstr "нисам пронашао исправне изворе судоерса, прекидам"
+
+#: plugins/sudoers/sudoers.c:244
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "судоерси наводе да администратор није дозвољен у судоу"
+
+#: plugins/sudoers/sudoers.c:301
+msgid "you are not permitted to use the -C option"
+msgstr "није вам допуштено да користите опцију „-C“"
+
+#: plugins/sudoers/sudoers.c:390
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "власник временске ознаке (%s): нема таквог корисника"
+
+#: plugins/sudoers/sudoers.c:405
+msgid "no tty"
+msgstr "нема конзоле"
+
+#: plugins/sudoers/sudoers.c:406
+msgid "sorry, you must have a tty to run sudo"
+msgstr "извините, морате имати конзолу да покренете судо"
+
+#: plugins/sudoers/sudoers.c:467
+msgid "command in current directory"
+msgstr "наредба у текућем директоријуму"
+
+#: plugins/sudoers/sudoers.c:486
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "извините, није вам дозвољено да подесите време истека наредбе"
+
+#: plugins/sudoers/sudoers.c:494
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "извините, није вам дозвољено да сачувате окружење"
+
+#: plugins/sudoers/sudoers.c:835
+msgid "command too long"
+msgstr "наредба је предуга"
+
+#: plugins/sudoers/sudoers.c:947
+#, c-format
+msgid "%s is not a regular file"
+msgstr "„%s“ није обична датотека"
+
+#: plugins/sudoers/sudoers.c:951 plugins/sudoers/timestamp.c:217 toke.l:969
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s је у власништву уиб-а %u, а треба бити %u"
+
+#: plugins/sudoers/sudoers.c:955 toke.l:974
+#, c-format
+msgid "%s is world writable"
+msgstr "Сви могу да пишу у „%s“"
+
+#: plugins/sudoers/sudoers.c:959 toke.l:977
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s је у власништву уиб-а %u, а треба бити %u"
+
+#: plugins/sudoers/sudoers.c:992
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "само администратор може да користи „-c %s“"
+
+#: plugins/sudoers/sudoers.c:1011
+#, c-format
+msgid "unknown login class: %s"
+msgstr "непознат разред пријављивања: %s"
+
+#: plugins/sudoers/sudoers.c:1094 plugins/sudoers/sudoers.c:1108
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "не могу да решим домаћина „%s“"
+
+#: plugins/sudoers/sudoreplay.c:275
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "неисправна опција пропусника: %s"
+
+#: plugins/sudoers/sudoreplay.c:288
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "неисправно најдуже чекање: %s"
+
+#: plugins/sudoers/sudoreplay.c:300
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "неисправан чинилац брзине: %s"
+
+#: plugins/sudoers/sudoreplay.c:303 plugins/sudoers/visudo.c:186
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s издање %s\n"
+
+#: plugins/sudoers/sudoreplay.c:335
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/временисање: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/временисање: %s"
+
+#: plugins/sudoers/sudoreplay.c:357
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Понављам сесију судоа: %s"
+
+#: plugins/sudoers/sudoreplay.c:555 plugins/sudoers/sudoreplay.c:602
+#: plugins/sudoers/sudoreplay.c:804 plugins/sudoers/sudoreplay.c:879
+#: plugins/sudoers/sudoreplay.c:958 plugins/sudoers/sudoreplay.c:973
+#: plugins/sudoers/sudoreplay.c:980 plugins/sudoers/sudoreplay.c:987
+#: plugins/sudoers/sudoreplay.c:994 plugins/sudoers/sudoreplay.c:1001
+#: plugins/sudoers/sudoreplay.c:1143
+msgid "unable to add event to queue"
+msgstr "не могу да додам догађај у ред"
+
+#: plugins/sudoers/sudoreplay.c:670
+msgid "unable to set tty to raw mode"
+msgstr "не могу да подесим конзолу на сирови режим"
+
+#: plugins/sudoers/sudoreplay.c:721
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Упозорење: ваш терминал је премали да би исправно приказао дневник.\n"
+
+#: plugins/sudoers/sudoreplay.c:722
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Геометрија дневника је %d x %d, а геометрија терминала је %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:749
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Одговор је завршен, притисните неки тастер да повратите терминал."
+
+#: plugins/sudoers/sudoreplay.c:782
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "неисправан ред датотеке временисања: %s"
+
+#: plugins/sudoers/sudoreplay.c:1177 plugins/sudoers/sudoreplay.c:1202
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "нејасан израз „%s“"
+
+#: plugins/sudoers/sudoreplay.c:1224
+msgid "unmatched ')' in expression"
+msgstr "непоклопљена ) у изразу"
+
+#: plugins/sudoers/sudoreplay.c:1228
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "непознат појам претраге „%s“"
+
+#: plugins/sudoers/sudoreplay.c:1243
+#, c-format
+msgid "%s requires an argument"
+msgstr "„%s“ захтева аргумент"
+
+#: plugins/sudoers/sudoreplay.c:1246 plugins/sudoers/sudoreplay.c:1626
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "неисправан регуларан израз: %s"
+
+#: plugins/sudoers/sudoreplay.c:1250
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "не могу да обрадим датум „%s“"
+
+#: plugins/sudoers/sudoreplay.c:1259
+msgid "unmatched '(' in expression"
+msgstr "непоклопљена ( у изразу"
+
+#: plugins/sudoers/sudoreplay.c:1261
+msgid "illegal trailing \"or\""
+msgstr "недозвољено пратеће „или“"
+
+#: plugins/sudoers/sudoreplay.c:1263
+msgid "illegal trailing \"!\""
+msgstr "недозвољени пратећи „!“"
+
+#: plugins/sudoers/sudoreplay.c:1312
+#, c-format
+msgid "unknown search type %d"
+msgstr "непозната врста претраге „%d“"
+
+#: plugins/sudoers/sudoreplay.c:1350
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: неисправна датотека дневника"
+
+#: plugins/sudoers/sudoreplay.c:1368
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: недостаје поље временске ознаке"
+
+#: plugins/sudoers/sudoreplay.c:1375
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: временска ознака %s: %s"
+
+#: plugins/sudoers/sudoreplay.c:1382
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: недостаје поље корисника"
+
+#: plugins/sudoers/sudoreplay.c:1391
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: недостаје поље „покрени-као корисник“"
+
+#: plugins/sudoers/sudoreplay.c:1400
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: недостаје поље „покрени-као група“"
+
+#: plugins/sudoers/sudoreplay.c:1806
+#, c-format
+msgid "usage: %s [-hnR] [-d dir] [-m num] [-s num] ID\n"
+msgstr "употреба: %s [-hnR] [-d дир] [-m број] [-s број] ИБ\n"
+
+#: plugins/sudoers/sudoreplay.c:1809
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "употреба: %s [-h] [-d дир] -l [израз претраге]\n"
+
+#: plugins/sudoers/sudoreplay.c:1818
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s — понавља дневнике сесије судоа\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1820
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Опције:\n"
+" -d, --directory=дир наводи директоријум за дневнике сесије\n"
+" -f, --filter=пропусник наводи У/И врсту(е) за приказивање\n"
+" -h, --help приказује поруку помоћи и излази\n"
+" -l, --list исписује доступне ИБ-ове сесије, са изборним изразом\n"
+" -m, --max-wait=број највећи број секунди за чекање између догађаја\n"
+" -s, --speed=број убрзава или успорава излаз\n"
+" -V, --version приказује податке о издању и излази"
+
+#: plugins/sudoers/testsudoers.c:329
+msgid "\thost unmatched"
+msgstr "\tдомаћин није поклопљен"
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Наредба је допуштена"
+
+#: plugins/sudoers/testsudoers.c:333
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Наредба је одбијена"
+
+#: plugins/sudoers/testsudoers.c:333
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Наредба није поклопљена"
+
+#: plugins/sudoers/timestamp.c:225
+#, c-format
+msgid "%s is group writable"
+msgstr "Група може да пише у „%s“"
+
+#: plugins/sudoers/timestamp.c:301
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "не могу да скратим датотеку временске ознаке на %lld бајта"
+
+#: plugins/sudoers/timestamp.c:756 plugins/sudoers/timestamp.c:823
+#: plugins/sudoers/visudo.c:500 plugins/sudoers/visudo.c:506
+msgid "unable to read the clock"
+msgstr "не могу да прочитам сат"
+
+#: plugins/sudoers/timestamp.c:770
+msgid "ignoring time stamp from the future"
+msgstr "занемарујем временску ознаку из будућности"
+
+#: plugins/sudoers/timestamp.c:782
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "временска ознака је превише у будућности: %20.20s"
+
+#: plugins/sudoers/timestamp.c:877
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "не могу да закључам датотеку временске ознаке „%s“"
+
+#: plugins/sudoers/timestamp.c:921 plugins/sudoers/timestamp.c:941
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "путања стања обучавања је предуга: %s/%s"
+
+#: plugins/sudoers/visudo.c:188
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s граматика издање %d\n"
+
+#: plugins/sudoers/visudo.c:266 plugins/sudoers/visudo.c:667
+#, c-format
+msgid "press return to edit %s: "
+msgstr "притисните „унеси“ да уредите „%s“: "
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "наведени уређивач (%s) не постоји"
+
+#: plugins/sudoers/visudo.c:349
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "нисам пронашао уређивача (путања уређивача = %s)"
+
+#: plugins/sudoers/visudo.c:459 plugins/sudoers/visudo.c:467
+msgid "write error"
+msgstr "грешка писања"
+
+#: plugins/sudoers/visudo.c:513
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "не могу да добавим податке привремене датотеке (%s), %s је неизмењено"
+
+#: plugins/sudoers/visudo.c:520
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "привремена датотека нулте дужине (%s), %s је неизмењено"
+
+#: plugins/sudoers/visudo.c:526
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "уређивач (%s) није успео, %s је неизмењено"
+
+#: plugins/sudoers/visudo.c:548
+#, c-format
+msgid "%s unchanged"
+msgstr "„%s“ је неизмењено"
+
+#: plugins/sudoers/visudo.c:607
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "не могу поново да отворим привремену датотеку (%s), %s је неизмењено."
+
+#: plugins/sudoers/visudo.c:619
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "не могу да обрадим привремену датотеку (%s), непозната грешка"
+
+#: plugins/sudoers/visudo.c:656
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "унутрашња грешка, не могу да пронађем „%s“ на списку!"
+
+#: plugins/sudoers/visudo.c:736 plugins/sudoers/visudo.c:745
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "не могу да подесим (јиб, гиб) за %s на (%u, %u)"
+
+#: plugins/sudoers/visudo.c:767
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "„%s“ и „%s“ нису на истом систему датотека, користим „mv“ за преименовање"
+
+#: plugins/sudoers/visudo.c:781
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "наредба није успела: „%s %s %s“, %s је неизмењено"
+
+#: plugins/sudoers/visudo.c:791
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "грешка преименовања „%s“, %s је неизмењено"
+
+#: plugins/sudoers/visudo.c:855
+msgid "What now? "
+msgstr "Шта сада? "
+
+#: plugins/sudoers/visudo.c:869
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Опције су:\n"
+" e — опет уређује датотеку судоерса\n"
+" x — излази без чувања измена у датотеци судоерса\n"
+" Q — прекида и чува измене у датотеци судоерса (ОПАСНО!)\n"
+
+#: plugins/sudoers/visudo.c:915
+#, c-format
+msgid "unable to run %s"
+msgstr "не могу да покренем %s"
+
+#: plugins/sudoers/visudo.c:945
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: погрешан власник (јиб, гиб) треба бити (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:952
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: лоша овлашћења, требају бити у режиму 0%o\n"
+
+#: plugins/sudoers/visudo.c:981 plugins/sudoers/visudo_json.c:1021
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "нисам успео да обрадим %s датотеку, непозната грешка"
+
+#: plugins/sudoers/visudo.c:997 plugins/sudoers/visudo_json.c:1032
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "грешка обраде у %s близу реда %d\n"
+
+#: plugins/sudoers/visudo.c:1000 plugins/sudoers/visudo_json.c:1035
+#, c-format
+msgid "parse error in %s\n"
+msgstr "грешка обраде у %s\n"
+
+#: plugins/sudoers/visudo.c:1008 plugins/sudoers/visudo.c:1015
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: успешно је обрађено\n"
+
+#: plugins/sudoers/visudo.c:1062
+#, c-format
+msgid "%s busy, try again later"
+msgstr "„%s“ је заузет, покушајте касније"
+
+#: plugins/sudoers/visudo.c:1159
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Грешка: %s:%d циклус у „%s“ „%s“"
+
+#: plugins/sudoers/visudo.c:1160
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Упозорење: %s:%d циклус у „%s“ „%s“"
+
+#: plugins/sudoers/visudo.c:1164
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Грешка: %s:%d упута за „%s“ „%s“ постоји али није одређена"
+
+#: plugins/sudoers/visudo.c:1165
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Упозорење: %s:%d упута за „%s“ „%s“ постоји али није одређена"
+
+#: plugins/sudoers/visudo.c:1318
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Упозорење: %s:%d некоришћено „%s“ „%s“"
+
+#: plugins/sudoers/visudo.c:1433
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s — безбедно уређује датотеку судоерса\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1435
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+" -x, --export=output_file write sudoers in JSON format to output_file"
+msgstr ""
+"\n"
+"Опције:\n"
+" -c, --check режим само провере\n"
+" -f, --file=судоерс наводи место датотеке судоерса\n"
+" -h, --help приказује поруку помоћи и излази\n"
+" -q, --quiet мање опширне (тихе) поруке грешке синтаксе\n"
+" -s, --strict строга провера синтаксе\n"
+" -V, --version приказује податке о издању и излази\n"
+" -x, --export=изл._датотека извози судоерсе у ЈСОН запису"
+
+#: plugins/sudoers/visudo_json.c:616 plugins/sudoers/visudo_json.c:651
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "непознат унос основности „%s“"
+
+#: plugins/sudoers/visudo_json.c:1007
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: улазна датотека треба да се разликује од излазне"
+
+#: toke.l:943
+msgid "too many levels of includes"
+msgstr "превише нивоа укључивања"
+
+#~ msgid "Warning: cycle in %s `%s'"
+#~ msgstr "Упозорење: циклус у „%s“ „%s“"
+
+#~ msgid "Warning: %s `%s' referenced but not defined"
+#~ msgstr "Упозорење: упута за „%s“ „%s“ постоји али није одређена"
+
+#~ msgid "Warning: unused %s `%s'"
+#~ msgstr "Упозорење: некоришћено „%s“ „%s“"
+
+#~ msgid "timestamp path too long: %s/%s"
+#~ msgstr "путања временске ознаке је предуга: %s/%s"
+
+#~ msgid "unable to stat editor (%s)"
+#~ msgstr "не могу да добавим податке уређивача (%s)"
+
+#~ msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+#~ msgstr "sudo_ldap_conf_add_ports: нестаде простора проширујући међумеморију домаћина"
+
+#~ msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+#~ msgstr "sudo_ldap_parse_uri: нестаде простора изграђујући међумеморију домаћина"
+
+#~ msgid "sudo_ldap_build_pass1 allocation mismatch"
+#~ msgstr "не поклапа се додела „sudo_ldap_build_pass1“"
+
+#~ msgid "internal error: insufficient space for log line"
+#~ msgstr "унутрашња грешка: недовољно простора за ред дневника"
+
+#~ msgid "fill_args: buffer overflow"
+#~ msgstr "fill_args: прекорачење међумеморије"
diff --git a/plugins/sudoers/po/sudoers.pot b/plugins/sudoers/po/sudoers.pot
new file mode 100644
index 0000000..d0dc297
--- /dev/null
+++ b/plugins/sudoers/po/sudoers.pot
@@ -0,0 +1,2296 @@
+# Portable object template file for the sudoers plugin
+# This file is put in the public domain.
+# Todd C. Miller <Todd.Miller@sudo.ws>, 2011-2018
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.27\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2019-01-03 13:24-0700\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr ""
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr ""
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr ""
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr ""
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr ""
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr ""
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268 gram.y:284
+#: gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336 gram.y:399 gram.y:407
+#: gram.y:417 gram.y:450 gram.y:457 gram.y:464 gram.y:471 gram.y:553 gram.y:560
+#: gram.y:569 gram.y:578 gram.y:595 gram.y:707 gram.y:714 gram.y:721 gram.y:729
+#: gram.y:829 gram.y:836 gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890
+#: gram.y:897 gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:536
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:200 plugins/sudoers/logging.c:517
+#: plugins/sudoers/logging.c:543 plugins/sudoers/logging.c:584
+#: plugins/sudoers/logging.c:781 plugins/sudoers/logging.c:1037
+#: plugins/sudoers/match.c:726 plugins/sudoers/match.c:773
+#: plugins/sudoers/match.c:814 plugins/sudoers/match.c:842
+#: plugins/sudoers/match.c:930 plugins/sudoers/match.c:1010
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1099
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:326 plugins/sudoers/visudo.c:332
+#: plugins/sudoers/visudo.c:442 plugins/sudoers/visudo.c:620
+#: plugins/sudoers/visudo.c:940 plugins/sudoers/visudo.c:1027
+#: plugins/sudoers/visudo.c:1116 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr ""
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr ""
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr ""
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr ""
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr ""
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr ""
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:366 plugins/sudoers/auth/pam.c:536
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:200
+#: plugins/sudoers/logging.c:517 plugins/sudoers/logging.c:543
+#: plugins/sudoers/logging.c:583 plugins/sudoers/logging.c:1037
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:814 plugins/sudoers/match.c:842
+#: plugins/sudoers/match.c:930 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1099
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:326 plugins/sudoers/visudo.c:332
+#: plugins/sudoers/visudo.c:442 plugins/sudoers/visudo.c:620
+#: plugins/sudoers/visudo.c:940 plugins/sudoers/visudo.c:1027
+#: plugins/sudoers/visudo.c:1116 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr ""
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr ""
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:222
+msgid "account validation failure, is your account locked?"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:233
+msgid "Account or password is expired, reset your password and try again"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:241
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:252
+msgid "Password expired, contact your system administrator"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:257
+msgid ""
+"Account expired or PAM config lacks an \"account\" section for sudo, contact "
+"your system administrator"
+msgstr ""
+
+#: plugins/sudoers/auth/pam.c:265 plugins/sudoers/auth/pam.c:271
+#, c-format
+msgid "PAM account management error: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:246
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr ""
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr ""
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid ""
+"Invalid authentication methods compiled into sudo! You may not mix "
+"standalone and non-standalone authentication."
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid ""
+"There are no authentication methods compiled into sudo! If you want to turn "
+"off authentication, use the --disable-authentication configure option."
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr ""
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr ""
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr ""
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr ""
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1138
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:252
+#: plugins/sudoers/visudo.c:608 plugins/sudoers/visudo.c:931
+msgid "unable to initialize sudoers default values"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:927
+#, c-format
+msgid "unable to open %s"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:936
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:953
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:956
+#, c-format
+msgid "parse error in %s\n"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -c, --config=conf_file the path to the configuration file\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1042 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr ""
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid ""
+"the SUDOERS_BASE environment variable is not set and the -b option was not "
+"specified."
+msgstr ""
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr ""
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:330
+msgid ""
+"Use faster globbing that is less accurate but does not access the filesystem"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:334
+msgid ""
+"The umask specified in sudoers will override the user's, even if it is more "
+"permissive"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:410
+msgid ""
+"Check parent directories for writability when editing files with sudoedit"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid ""
+"Log entries larger than this value will be split into multiple syslog "
+"messages: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:462
+msgid ""
+"Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr ""
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr ""
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr ""
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr ""
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid ""
+"sorry, you are not allowed to set the following environment variables: %s"
+msgstr ""
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr ""
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr ""
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr ""
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:737
+#: plugins/sudoers/visudo.c:748
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1169
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr ""
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr ""
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr ""
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr ""
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr ""
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr ""
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1648
+msgid ""
+"start_tls specified but LDAP libs do not support ldap_start_tls_s() or "
+"ldap_start_tls_s_np()"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr ""
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr ""
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr ""
+
+#: plugins/sudoers/logging.c:118
+#, c-format
+msgid "%8s : %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:146
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:175
+#, c-format
+msgid "unable to open log file: %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:183
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:216
+#, c-format
+msgid "unable to write log file: %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:245
+msgid "No user or host"
+msgstr ""
+
+#: plugins/sudoers/logging.c:247
+msgid "validation failure"
+msgstr ""
+
+#: plugins/sudoers/logging.c:254
+msgid "user NOT in sudoers"
+msgstr ""
+
+#: plugins/sudoers/logging.c:256
+msgid "user NOT authorized on host"
+msgstr ""
+
+#: plugins/sudoers/logging.c:258
+msgid "command not allowed"
+msgstr ""
+
+#: plugins/sudoers/logging.c:293
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:296
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:300
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:303
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/logging.c:340 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr ""
+
+#: plugins/sudoers/logging.c:342 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+
+#: plugins/sudoers/logging.c:359
+msgid "authentication failure"
+msgstr ""
+
+#: plugins/sudoers/logging.c:385
+msgid "a password is required"
+msgstr ""
+
+#: plugins/sudoers/logging.c:448
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] ""
+msgstr[1] ""
+
+#: plugins/sudoers/logging.c:695
+msgid "unable to fork"
+msgstr ""
+
+#: plugins/sudoers/logging.c:703 plugins/sudoers/logging.c:755
+#, c-format
+msgid "unable to fork: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:745
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:770
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:808
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr ""
+
+#: plugins/sudoers/match.c:875
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr ""
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:435 plugins/sudoers/visudo.c:731
+#, c-format
+msgid "unable to stat %s"
+msgstr ""
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr ""
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr ""
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr ""
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr ""
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr ""
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr ""
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr ""
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr ""
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:234
+#: plugins/sudoers/visudo.c:865
+#, c-format
+msgid "unable to execute %s"
+msgstr ""
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr ""
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:1071 plugins/sudoers/sudoers.c:1085
+#, c-format
+msgid "unable to resolve host %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional "
+"expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -n, --non-interactive no prompts, session is sent to the standard output\n"
+" -R, --no-resize do not attempt to re-size the terminal\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:496 plugins/sudoers/visudo.c:502
+msgid "unable to read the clock"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:230
+msgid "the -x option will be removed in a future release"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:231
+msgid "please consider using the cvtsudoers utility instead"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:282 plugins/sudoers/visudo.c:664
+#, c-format
+msgid "press return to edit %s: "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:343
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:345
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:455 plugins/sudoers/visudo.c:463
+msgid "write error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:509
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:516
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:522
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:544
+#, c-format
+msgid "%s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:603
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr ""
+
+#: plugins/sudoers/visudo.c:615
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:653
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:733 plugins/sudoers/visudo.c:742
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:779
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:789
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:810
+msgid "What now? "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:824
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:870
+#, c-format
+msgid "unable to run %s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:900
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:907
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:964 plugins/sudoers/visudo.c:971
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:990
+#, c-format
+msgid "%s busy, try again later"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:993
+#, c-format
+msgid "unable to lock %s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:994
+msgid "Edit anyway? [y/N]"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1078
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1079
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1083
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1084
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1175
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1290
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1292
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr ""
diff --git a/plugins/sudoers/po/sv.mo b/plugins/sudoers/po/sv.mo
new file mode 100644
index 0000000..9fed092
--- /dev/null
+++ b/plugins/sudoers/po/sv.mo
Binary files differ
diff --git a/plugins/sudoers/po/sv.po b/plugins/sudoers/po/sv.po
new file mode 100644
index 0000000..ce4772d
--- /dev/null
+++ b/plugins/sudoers/po/sv.po
@@ -0,0 +1,2475 @@
+# Swedish translation for sudoers.
+# Copyright © 2012, 2016, 2017, 2018 Free Software Foundation, Inc.
+# This file is put in the public domain.
+# Daniel Nylander <po@danielnylander.se>, 2012.
+# Sebastian Rasmussen <sebras@gmail.com>, 2016, 2017, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-30 02:23+0100\n"
+"Last-Translator: Sebastian Rasmussen <sebras@gmail.com>\n"
+"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
+"Language: sv\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 2.2\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "syntaxfel"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "lösenord för %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] lösenord för %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Lösenord: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** SÄKERHETSINFORMATION för %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Försök igen."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336
+#: gram.y:399 gram.y:407 gram.y:417 gram.y:450 gram.y:457 gram.y:464
+#: gram.y:471 gram.y:553 gram.y:560 gram.y:569 gram.y:578 gram.y:595
+#: gram.y:707 gram.y:714 gram.y:721 gram.y:729 gram.y:829 gram.y:836
+#: gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890 gram.y:897
+#: gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:195 plugins/sudoers/logging.c:511
+#: plugins/sudoers/logging.c:532 plugins/sudoers/logging.c:573
+#: plugins/sudoers/logging.c:752 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr "kunde inte allokera minne"
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr "en kontrollsumma kräver ett sökvägsnamn"
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr "ogiltigt notbefore-värde"
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr "ogiltigt notafter-värde"
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr "tidsgränsvärde för stort"
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr "ogiltigt värde för tidsgräns"
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:354 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:511 plugins/sudoers/logging.c:532
+#: plugins/sudoers/logging.c:572 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:724 plugins/sudoers/match.c:771
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1008
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Aliaset ”%s” är redan definierat"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "kunde inte få inloggningsklass för användaren %s"
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr "kan inte påbörja bsd-autentisering"
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr "ogiltig autentiseringstyp"
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr "kunde inte initiera BSD-autentisering"
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr "ditt konto har gått ut"
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr "godkännande misslyckades"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr "kan inte läsa fwtk-konfiguration"
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr "kunde inte ansluta till autentiseringsservern"
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr "förlorade kontakten med autentiseringsservern"
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"fel i autentiseringsservern:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: kunde inte konvertera principal till sträng (”%s”): %s"
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: kunde inte tolka ”%s”: %s"
+
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: kunde inte slå upp inloggningsuppgiftscache: %s"
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: kunde inte allokera flaggor: %s"
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: kan inte hämta inloggningsuppgifter: %s"
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: kunde inte initiera inloggningsuppgiftscache: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: kunde inte lagra inloggningsuppgifter i cache: %s"
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: kan inte hämta principal för värd: %s"
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Kan inte verifiera TGT! Möjlig attack!: %s"
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr "kunde inte initiera PAM"
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "PAM-autentiseringsfel: %s"
+
+#: plugins/sudoers/auth/pam.c:221
+msgid "account validation failure, is your account locked?"
+msgstr "kontovalidering misslyckades. Är ditt konto låst?"
+
+#: plugins/sudoers/auth/pam.c:229
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Kontot eller lösenordet har gått ut. Återställ ditt lösenord och försök igen"
+
+#: plugins/sudoers/auth/pam.c:238
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "kunde inte ändra utgånget lösenord: %s"
+
+#: plugins/sudoers/auth/pam.c:246
+msgid "Password expired, contact your system administrator"
+msgstr "Lösenordet har gått ut. Kontakta din systemadministratör"
+
+#: plugins/sudoers/auth/pam.c:250
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Konto utgånget eller så saknar PAM-konfigurationen ett ”account”-avsnitt för sudo, kontakta din systemadministratör"
+
+#: plugins/sudoers/auth/pam.c:257 plugins/sudoers/auth/pam.c:262
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "Fel vid hantering av PAM-konto: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:232
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "du finns inte i %s-databasen"
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr "misslyckades med att initiera ACE API-biblioteket"
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr "kunde inte kontakta SecurID-servern"
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr "Användar-ID låst för SecurID-autentisering"
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr "ogiltig längd för användarnamn för SecurID"
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr "ogiltigt autentiseringshandtag för SecurID"
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr "SecurID-kommunikation misslyckades"
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr "okänt SecurID-fel"
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr "ogiltig lösenordslängd för SecurID"
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr "kunde inte initiera SIA-session"
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr "ogiltiga autentiseringsmetoder"
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Ogiltiga autentiseringsmetoder inkompilerade i sudo! Du får inte blanda fristående och icke-fristående autentisering."
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr "inga autentiseringsmetoder"
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Det finns inga autentiseringsmetoder inbyggda i sudo! Om du vill inaktivera autentisering, använd konfigurationsflaggan --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr "Kunde inte initiera autentiseringsmetoder."
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr "Autentiseringsmetoder:"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr "Kunde inte fastställa granskningsvillkor"
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr "kunde inte bekräfta granskningsberättelse"
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Vi litar på att du har fått den vanliga lektionen från den lokala system-\n"
+"administratören. Den kan vanligtvis reduceras till dessa tre saker:\n"
+"\n"
+" #1) Respektera andras integritet.\n"
+" #2) Tänk innan du skriver.\n"
+" #3) Med stor makt kommer ett stort ansvar.\n"
+"\n"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr "okänt uid: %u"
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1136
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr "okänd användare: %s"
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "ordningsinkrement: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "startordning: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr "ordningsutfyllnad: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s version %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s grammatikversion %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr "inmatningsformat %s stöds inte"
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr "umatningsformat %s stöds inte"
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: in- och utmatningsfiler måste vara olika"
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:238
+#: plugins/sudoers/visudo.c:594 plugins/sudoers/visudo.c:917
+msgid "unable to initialize sudoers default values"
+msgstr "kunde inte initiera sudoers standardvärden"
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: okänt nyckelord: %s"
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "ogiltig standardtyp: %s"
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "ogiltig undertryckningstyp: %s"
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr "ogiltigt filter: %s"
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:913
+#, c-format
+msgid "unable to open %s"
+msgstr "kunde inte öppna %s"
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:922
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "misslyckades med att tolka %s-filen, okänt fel"
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:939
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "tolkningsfel i %s nära rad %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:942
+#, c-format
+msgid "parse error in %s\n"
+msgstr "tolkningsfel i %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr "kunde inte skriva till %s"
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s - konvertera mellan sudoers filformat\n"
+"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Flaggor:\n"
+" -b, --base=dn DN-bas för sudo LDAP-förfrågningar\n"
+" -d, --defaults=stdtyper konvertera endast Standard av de angivna typerna\n"
+" -e, --expand-aliases expandera alias under konvertering\n"
+" -f, --output-format=format ställ in utmatningsformat: JSON, LDIF eller sudoers\n"
+" -i, --input-format=format ställ in inmatningsformat: LDIF eller sudoers\n"
+" -I, --increment=ant antal att öka varje sudoOrder med\n"
+" -h, --help visa hjälpmeddelande och avslut\n"
+" -m, --match=filter konvertera endast poster som matchar filtret\n"
+" -M, --match-local filtermatchning använder passwd och gruppdatabaser\n"
+" -o, --output=utmatningsfil skriv konverterad sudoers till utmatningsfil\n"
+" -O, --order-start=ant startpunkt för första sudoOrder\n"
+" -p, --prune-matches skala bort användare, grupper och värdar som inte matchar\n"
+" -P, --padding=num basutfyllnad för sudoOrder-inkrement\n"
+" -s, --suppress=avsnitt undertryck utmatning av vissa avsnitt\n"
+" -V, --version visa versionsinformation och avsluta"
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "okänd standardpost ”%s”"
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr "kunde inte få GMT-tid"
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr "kunde inte formatera tidsstämpel"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1015 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "internt fel, %s spill"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr "för många sudoers-poster, maximalt %u"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "miljövariabeln SUDOERS_BASE är inte satt och flaggan -b angavs inte."
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Syslog-facilitet om syslog används för loggning: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Syslog-prioritet att använda när användaren lyckas med autentisering: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Syslog-prioritet att använda när användaren misslyckas med autentisering: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "Lägg OTP-prompt på en egen rad"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "Ignorera ”.” i $PATH"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "Skicka alltid e-post när sudo körs"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "Skicka e-post om användarens autentisering misslyckas"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "Skicka e-post om användaren inte finns med i sudoers"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Skicka e-post om användaren inte finns med i sudoers för denna värddator"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Skicka e-post om användaren inte tillåts att köra ett kommando"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "Skicka e-post om användaren försöker köra ett kommando"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Använd en separat tidsstämpel för varje användar-/tty-kombination"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "Lär upp användaren första gången de kör sudo"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Fil som innehåller sudo-lektion: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "Kräv att användare autentiseras som standard"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "Root får köra sudo"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Logga värdnamnet i (den icke syslog-baserade) loggfilen"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Logga året i (den icke syslog-baserade) loggfilen"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Om sudo startas utan argument, starta ett skal"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Ställ in $HOME till målanvändaren när ett skal startas med -s"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Ställ alltid in $HOME till målanvändarens hemkatalog"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Tillåt viss informationsinsamling för att ge meningsfulla felmeddelanden"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Kräv fullständiga värdnamn i sudoers-filen"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Förolämpa användaren när de anger ett felaktigt lösenord"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Tillåt bara användare att köra sudo om de har en tty"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo kommer att respektera miljövariabeln EDITOR"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "Fråga efter root-lösenordet, inte användarens"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Fråga efter runas_default-användarens lösenord, inte användarens"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Fråga efter målanvändarens lösenord, inte användarens"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Tillämpa standardvärden i målanvändarens inloggningsklass om det finns en"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Ställ in miljövariablerna LOGNAME och USER"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Sätt bara det effektiva uid:t till målanvändaren, inte till det riktiga uid:t"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Initiera inte gruppvektorn till den från målanvändaren"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Längden vid vilken långa loggfilsrader radbryts (0 för att inte radbryta): %u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Tidsgräns för autentiseringstidsstämpel: %.1f minuter"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Tidsgräns för lösenordsprompt: %.1f minuter"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Antal försök att ange ett lösenord: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Umask att använda eller 0777 för att använda användarens: 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Sökväg till loggfil: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Sökväg till e-postprogram: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Flaggor för e-postprogram: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Adress att skicka e-post till: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Adress att skicka e-post från: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Ämnesrad för e-postmeddelanden: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Meddelande vid felaktigt lösenord: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Sökväg till lektionsstatuskatalog: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Sökväg till katalog för autentiseringstidsstämplar: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Ägare av katalogen för autentiseringstidsstämplar: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Användare i denna grupp är undantagna från lösenords- och SÖKVÄGs-kraven: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Standard lösenordsprompt: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Om inställt kommer passprompt att åsidosätta systemprompten i varje fall."
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Standardanvändaren att köra kommandon som: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Värde att åsidosätta användarens $PATH med: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Sökväg till textredigerare för användning av visudo: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "När ett lösenord ska krävas för pseudokommandot ”list”: %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "När lösenord ska krävas för pseudokommandot ”verify”: %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Förinläs attrapp-exec-funktioner som finns i biblioteket sudo_noexec"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Om LDAP-registret är uppe, ignorerar vi den lokala sudoers-filen"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Fildeskriptorer >= %d kommer att stängas innan ett kommando exekveras"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Om inställt kan användare åsidosätta värdet ”closefrom” med flaggan -C"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Låt användare ställa in godtyckliga miljövariabler"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "Återställ miljön till standarduppsättningen av variabler"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "Miljövariabler att kontrollera:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "Miljövariabler att ta bort:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "Miljövariabler att behålla:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "SELinux-roll att använda i den nya säkerhetskontexten: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "SELinux-typ att använda i den nya säkerhetskontexten: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Sökväg till den sudo-specifika miljöfilen: %s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Sökväg till den begränsade sudo-specifika miljöfilen: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Lokalanpassning att använda vid tolkning av sudoers: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Tillåt sudo att fråga efter ett lösenord även om det skulle vara synligt"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Ge visuell återkoppling vid lösenordsprompten när det finns användarinmatad data"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Använd snabbare matchning som är mindre exakt men inte använder filsystemet"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "Umasken angiven i sudoers kommer att åsidosätta användarens, även om den är mer tillåtande"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "Logga användarens inmatning för kommandot som körs"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "Logga utmatningen för kommandot som körs"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "Komprimera I/O-loggar med hjälp av zlib"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "Kör alltid kommandon i en pseudo-tty"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Insticksmodul för stöd för icke-Unix-grupper: %s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Katalog i vilken in-/utmatningsloggar lagras: %s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Fil i vilken in-/utmatningsloggar lagras: %s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Lägg till en post till utmp/utmpx-filen när en pty allokeras"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Sätt användaren i utmp till runas-användaren, inte användaren som anropar"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Uppsättning tillåtna rättigheter: %s"
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Uppsättning av begränsningsrättigheter: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "Kör kommandon i en pty i bakgrunden"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "PAM-tjänstnamn att använda: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "PAM-tjänstnamn att använda för inloggningsskal: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Försök att etablera PAM-inloggningsuppgifter för målanvändaren"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "Skapa en ny PAM-session för kommandot att köra i"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Största sekvensnummer i I/O-logg: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "Aktivera sudoers nätgruppsstöd"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Kontrollera överordnade kataloger för skrivbarhet när filer redigeras med sudoedit"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Följ symboliska länkar när filer redigeras med sudoedit"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "Fråga gruppinsticksmodulen efter okända systemgrupper"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Matcha nätgrupper baserat på hela tupeln: användare, värd och domän"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Tillåt kommandon att köras även om sudo inte kan skriva till granskningsloggen"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Tillåt kommandon att köras även om sudo inte kan skriva I/O-loggen"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Tillåt kommandon att köras även om sudo inte kan skriva till loggfilen"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Gör namnupplösning för grupper i sudoers och matcha efter grupp-ID, inte namnet"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Loggposter större än detta värde kommer att delas upp i flera syslog-meddelanden: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Användare som kommer att äga I/O-loggfilerna: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Grupp som kommer att äga I/O-loggfilerna: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Filrättigheter att använda för I/O-loggfilerna: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Exekvera kommandon efter fildeskriptor istället för efter sökväg: %s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Hoppa över okända Defaults-poster i sudoers istället för att skriva ut en varning"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Tid i sekunder efter vilka kommandot kommer att avslutas: %u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Tillåt användaren att ange en tidsgräns på kommandoraden"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Spola ut I/O-loggdata till disk omedelbart istället för att buffra det"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "Inkludera process-ID:t vid loggning via syslog"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Typ av post för autentiseringstidsstämplar: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "Autentiseringsfelsmeddelande: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "Matcha användarnamn skiftlägesokänsligt"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "Matcha gruppnamn skiftlägesokänsligt"
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d okänd standardpost ”%s”"
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: okänd standardpost ”%s”"
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d inget värde angivet för ”%s”"
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: inget värde angivet för ”%s”"
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d värden för ”%s” måste börja med ett ”/”"
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: värden för ”%s” måste börja med ett ”/”"
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d flaggan ”%s” tar inte emot något värde"
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: flaggan ”%s” tar inte emot något värde"
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d ogiltig standardtyp 0x%x för flagga ”%s”"
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: ogiltig standardtyp 0x%x för flagga ”%s”"
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d värdet ”%s” är ogiltigt för flaggan ”%s”"
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: värdet ”%s” är ogiltigt för flaggan ”%s”"
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: trasig envp, längd stämmer inte"
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr "kan inte återuppbygga miljön"
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "du får inte lov att ställa in följande miljövariabler: %s"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "tolkningsfel i %s nära rad %d"
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "tolkningsfel i %s"
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "typ %d av kontrollsumma stöds inte för %s"
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr "%s: läsfel"
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s måste ägas av uid %d"
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s får endast vara skrivbar av ägaren"
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "kan inte läsa in %s: %s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "kunde inte hitta symbolen ”group_plugin” i %s"
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: inkompatibel gruppinsticksmodul huvudversion %d, förväntade %d"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "kan inte tolka IP-adress ”%s”"
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "kan inte tolka nätmask ”%s”"
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Lokala IP-adress- och nätmaskpar:\n"
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s finns men är inte en katalog (0%o)"
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "kunde inte skapa katalogen %s"
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:723
+#: plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "kan inte ändra läge för %s till 0%o"
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1167
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr "okänd grupp: %s"
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr "kunde inte läsa %s"
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr "kunde inte skapa %s"
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "kunde inte skriva till I/O-loggfil: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr "%s: internt fel, I/O-loggfil för event %d inte öppen"
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr "%s: internt fel, ogiltig signal %d"
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: ogiltig loggfil"
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: tidsstämpelfält saknas"
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: tidsstämpel %s: %s"
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: användarfältet saknas"
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: runas-användarfältet saknas"
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: runas-gruppfältet saknas"
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr "starttls stöds inte när ldaps används"
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "kan inte initiera SSL-certifikat och nyckeldatabas: %s"
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "du måste ställa in TLS_CERT i %s för att använda SSL"
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "kunde inte initiera LDAP: %s"
+
+#: plugins/sudoers/ldap.c:1648
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls angivet men LDAP-bibliotek har inte stöd för ldap_start_tls_s() eller ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "ogiltigt sudoOrder-attribut: %s"
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: port är för stor"
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "LDAP-uri-typ stöds ej: %s"
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "kan inte blanda ldap- och ldaps-URI:er"
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "kunde inte konvertera sudoOption: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "kan inte öppna granskningssystem"
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr "kan inte skicka granskningsmeddelande"
+
+#: plugins/sudoers/logging.c:113
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:141
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (kommando fortsätter) %s"
+
+#: plugins/sudoers/logging.c:170
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "kunde inte öppna loggfil: %s"
+
+#: plugins/sudoers/logging.c:178
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "kunde inte låsa loggfil: %s"
+
+#: plugins/sudoers/logging.c:211
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "kunde inte skriva till loggfil: %s"
+
+#: plugins/sudoers/logging.c:240
+msgid "No user or host"
+msgstr "Ingen användare eller värddator"
+
+#: plugins/sudoers/logging.c:242
+msgid "validation failure"
+msgstr "valideringsfel"
+
+#: plugins/sudoers/logging.c:249
+msgid "user NOT in sudoers"
+msgstr "användare finns INTE i sudoers"
+
+#: plugins/sudoers/logging.c:251
+msgid "user NOT authorized on host"
+msgstr "användaren är INTE auktoriserad på värddatorn"
+
+#: plugins/sudoers/logging.c:253
+msgid "command not allowed"
+msgstr "kommandot tillåts inte"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s finns inte i filen sudoers. Denna incident kommer att rapporteras.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s tillåts inte att köra sudo på %s. Denna incident kommer att rapporteras.\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Tyvärr, användaren %s får inte köra sudo på %s.\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Tyvärr, användaren %s tillåts inte att köra ”%s%s%s” som %s%s%s på %s.\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: kommandot hittades inte"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"ignorerar ”%s” som hittades i ”.”\n"
+"Använd ”sudo ./%s” om detta är den ”%s” som du vill köra."
+
+#: plugins/sudoers/logging.c:354
+msgid "authentication failure"
+msgstr "autentiseringsfel"
+
+#: plugins/sudoers/logging.c:380
+msgid "a password is required"
+msgstr "ett lösenord krävs"
+
+#: plugins/sudoers/logging.c:443
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u felaktigt lösenordsförsök"
+msgstr[1] "%u felaktiga lösenordsförsök"
+
+#: plugins/sudoers/logging.c:666
+msgid "unable to fork"
+msgstr "kunde inte grena process"
+
+#: plugins/sudoers/logging.c:674 plugins/sudoers/logging.c:726
+#, c-format
+msgid "unable to fork: %m"
+msgstr "kunde inte grena process: %m"
+
+#: plugins/sudoers/logging.c:716
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "kunde inte öppna rör: %m"
+
+#: plugins/sudoers/logging.c:741
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "kan inte duplicera stdin: %m"
+
+#: plugins/sudoers/logging.c:779
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "kunde inte köra %s: %m"
+
+#: plugins/sudoers/match.c:874
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "kontrollsumma för %s (%s) är inte på %s-form"
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:421 plugins/sudoers/visudo.c:717
+#, c-format
+msgid "unable to stat %s"
+msgstr "kunde inte ta status på %s"
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"LDAP-roll: %s\n"
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Sudoers-post:\n"
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr " KörSomAnvändare: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr " KörSomGrupper: "
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr " Flaggor: "
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr " Kommandon:\n"
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Matchande standardposter för %s på %s:\n"
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Runas- och kommando-specifika standardvärden för %s:\n"
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Användare %s får köra följande kommandon på %s:\n"
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Användaren %s tillåts inte att köra sudo på %s.\n"
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "ignorerar ogiltigt attributvärde: %s"
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "hoppar över ofullständig sudoRole: cn: %s"
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "ogiltigt %.*s inställt av sudo-framände"
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr "kan inte tolka nätverksadresslista"
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr "användarnamn inte inställt av sudo-framände"
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr "användar-ID inte inställt av sudo-framände"
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr "grupp-ID inte inställt av sudo-framände"
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr "värdnamn inte inställt av sudo-framände"
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:220
+#: plugins/sudoers/visudo.c:851
+#, c-format
+msgid "unable to execute %s"
+msgstr "kunde inte köra %s"
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Sudoers policyinsticksmodul version %s\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Sudoers-filgrammatik version %d\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Sökväg till sudoers: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "Sökväg till nsswitch: %s\n"
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "Sökväg till ldap.conf: %s\n"
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "Sökväg till ldap.secret: %s\n"
+
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "kan inte registrera krok av typ %d (version %d.%d)"
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "kan inte cacha uid %u, slut på minne"
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "kan inte cacha uid %u, finns redan"
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "kan inte cacha användare %s, slut på minne"
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "kan inte cacha användare %s, finns redan"
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "kan inte cacha gid %u, slut på minne"
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "kan inte cacha gid %u, finns redan"
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "kan inte cacha grupp %s, slut på minne"
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "kan inte cacha grupp %s, finns redan"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "kan inte cacha grupplista för %s, finns redan"
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "kan inte cacha grupplista för %s, slut på minne"
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "kan inte tolka grupper för %s"
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "kan inte tolka gids för %s"
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr "perm-stackspill"
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr "perm-stackunderspill"
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr "kan inte ändra till root-gid"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr "kan inte ändra till runas-gid"
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr "kan inte ställa in gruppvektor för runas"
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr "kan inte ändra till runas-uid"
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr "kan inte ändra till sudoers-gid"
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr "för många processer"
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr "kan inte hämta aktuell arbetskatalog"
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "trunkerad granskningssökväg user_cmnd: %s"
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "trunkerad granskningssökväg argv[0]: %s"
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr "audit_failure-meddelande för långt"
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "kan inte initiera SSS-källa. Är SSSD installerat på din maskin?"
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "kan inte hitta symbol ”%s” i %s"
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr "problem med standardposter"
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr "inga giltiga sudoers-källor hittades, avslutar"
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers anger att root inte tillåts att använda sudo"
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr "du tillåts inte att använda flaggan -C"
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "tidsstämpelägare (%s): Det finns ingen sådan användare"
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr "ingen tty"
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr "tyvärr, du måste ha en tty för att köra sudo"
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr "kommando i aktuell katalog"
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "tyvärr, du tillåts inte att ställa in en tidsgräns för kommandon"
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "tyvärr, du tillåts inte att behålla miljövariabler"
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr "kommandot för långt"
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s är inte en vanlig fil"
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s ägs av uid %u, ska vara %u"
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr "%s är skrivbar för alla"
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s ägs av gid %u, ska vara %u"
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "endast root kan använda ”-c %s”"
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr "okänd inloggningsklass: %s"
+
+#: plugins/sudoers/sudoers.c:1069 plugins/sudoers/sudoers.c:1083
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "kunde inte slå upp värddatorn %s"
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "ogiltig filterflagga: %s"
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "ogiltig största väntan: %s"
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "ogiltig hastighetsfaktor: %s"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/tidsmätning: %s"
+
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/tidsmätning: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Spelar upp sudo-session: %s"
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr "kan inte lägga till händelse till kö"
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr "kan inte ställa in tty i råläge"
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Varning: din terminal är för liten för att korrekt spela upp loggen.\n"
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Logg-geometri är %d x %d, din terminals geometri är %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Uppspelning avslutad, tryck på en tangent för att återställa terminalen."
+
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "ogiltig rad i tidsmätningsfil: %s"
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "tvetydigt uttryck ”%s”"
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr "omatchat ”)” i uttryck"
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "okänt sökvillkor ”%s”"
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s kräver ett argument"
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "ogiltigt reguljärt uttryck: %s"
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "kunde inte tolka datumet ”%s”"
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr "omatchat ”(” i uttryck"
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr "ogiltigt avslutande ”or”"
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr "ogiltigt efterföljande ”!”"
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr "okänd söktyp %d"
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr "användning: %s [-hnRS] [-d kat] [-m num] [-s num] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "användning: %s [-h] [-d kat] -l [sökuttryck]\n"
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - spela upp loggar från sudo-session\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Flaggor:\n"
+" -d, --directory=kat ange katalog för sessionsloggar\n"
+" -f, --filter=filter ange vilka I/O-typer som ska visas\n"
+" -h, --help visa hjälptext och avsluta\n"
+" -l, --list lista tillgängliga sessions-ID:n, med valfritt uttryck\n"
+" -m, --max-wait=num största antal sekunder att vänta mellan händelser\n"
+" -S, --suspend-wait vänta medan kommandot var i viloläge\n"
+" -s, --speed=num påskynda eller fördröj utmatning\n"
+" -V, --version visa versionsinformation och avsluta"
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr "\tvärd omatchad"
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Kommandot tillåts"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Kommandot nekades"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Kommando omatchat"
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr "%s är skrivbar för gruppen"
+
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "kunde inte trunkera tidsstämpelfil till %lld byte"
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:482 plugins/sudoers/visudo.c:488
+msgid "unable to read the clock"
+msgstr "kunde inte läsa klockan"
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr "ignorerar tidsstämpel från framtiden"
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "tidsstämpel är för långt in i framtiden: %20.20s"
+
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "kunde inte låsa tidsstämpelfil %s"
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "sökväg för lektionsstatus för lång: %s/%s"
+
+#: plugins/sudoers/visudo.c:216
+msgid "the -x option will be removed in a future release"
+msgstr "flaggan -x kommer att tas bort i en framtida version"
+
+#: plugins/sudoers/visudo.c:217
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "överväg att använda verktyget cvtsudoers istället"
+
+#: plugins/sudoers/visudo.c:268 plugins/sudoers/visudo.c:650
+#, c-format
+msgid "press return to edit %s: "
+msgstr "tryck på retur för att redigera %s: "
+
+#: plugins/sudoers/visudo.c:329
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "angiven redigerare (%s) finns inte"
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "ingen textredigerare hittad (sökväg för textredigerare = %s)"
+
+#: plugins/sudoers/visudo.c:441 plugins/sudoers/visudo.c:449
+msgid "write error"
+msgstr "skrivfel"
+
+#: plugins/sudoers/visudo.c:495
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "kan inte hämta filinformation för temporärfil (%s), %s oförändrad"
+
+# sebras: not an exact translation, but I think it captures the meaning of the original text.
+#: plugins/sudoers/visudo.c:502
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "temporärfil tom (%s), %s oförändrad"
+
+#: plugins/sudoers/visudo.c:508
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "redigeraren (%s) misslyckades, %s är oförändrad"
+
+#: plugins/sudoers/visudo.c:530
+#, c-format
+msgid "%s unchanged"
+msgstr "%s oförändrad"
+
+#: plugins/sudoers/visudo.c:589
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "kunde inte återöppna temporärfil (%s), %s är oförändrad."
+
+#: plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "kunde inte tolka temporärfil (%s), okänt fel"
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "internt fel, kunde inte hitta %s i listan!"
+
+#: plugins/sudoers/visudo.c:719 plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "kunde inte ställa in (uid, gid) för %s till (%u, %u)"
+
+#: plugins/sudoers/visudo.c:751
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s och %s finns inte på samma filsystem, använder mv för att byta namn"
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "kommandot misslyckades: ”%s %s %s”, %s är oförändrad"
+
+#: plugins/sudoers/visudo.c:775
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "fel vid namnbyte för %s, %s är oförändrad"
+
+#: plugins/sudoers/visudo.c:796
+msgid "What now? "
+msgstr "Nu då? "
+
+#: plugins/sudoers/visudo.c:810
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Alternativen är:\n"
+" r(e)digera sudoers-filen igen\n"
+" avsluta (x) utan att spara ändringar i sudoers-filen\n"
+" Avsluta (Q) och spara ändringar i sudoers-filen (FARLIGT!)\n"
+
+#: plugins/sudoers/visudo.c:856
+#, c-format
+msgid "unable to run %s"
+msgstr "kunde inte köra %s"
+
+#: plugins/sudoers/visudo.c:886
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: felaktig ägare (uid, gid) ska vara (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: felaktiga rättigheter, bör vara läge 0%o\n"
+
+#: plugins/sudoers/visudo.c:950 plugins/sudoers/visudo.c:957
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: tolkad OK\n"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s är upptagen, försök igen senare"
+
+#: plugins/sudoers/visudo.c:979
+#, c-format
+msgid "unable to lock %s"
+msgstr "kunde inte låsa %s"
+
+#: plugins/sudoers/visudo.c:980
+msgid "Edit anyway? [y/N]"
+msgstr "Redigera ändå? [y/N]"
+
+#: plugins/sudoers/visudo.c:1064
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Fel: %s:%d cykel i %s ”%s”"
+
+#: plugins/sudoers/visudo.c:1065
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Varning: %s:%d cykel i %s ”%s”"
+
+#: plugins/sudoers/visudo.c:1069
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Fel: %s:%d %s ”%s” refererad till men inte definierad"
+
+#: plugins/sudoers/visudo.c:1070
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Varning: %s:%d %s ”%s” refererad till men inte definierad"
+
+#: plugins/sudoers/visudo.c:1161
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Varning: %s:%d oanvänd %s ”%s”"
+
+#: plugins/sudoers/visudo.c:1276
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - redigera sudoers-filen på ett säkert sätt\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1278
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"Flaggor:\n"
+" -c, --check genomför endast kontroller\n"
+" -f, --file=sudoers ange plats för sudoers-filen\n"
+" -h, --help visa hjälptext och avsluta\n"
+" -q, --quiet mindre utförliga (tysta) syntaxfelmeddelanden\n"
+" -s, --strict strikt syntaxkontroll\n"
+" -V, --version visa versionsinformation och avsluta\n"
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr "för många nivåer av inkluderingar"
+
+#~ msgid ""
+#~ "\n"
+#~ "LDAP Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "LDAP-roll: OKÄND\n"
+
+#~ msgid " Order: %s\n"
+#~ msgstr " Ordning: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: %s\n"
+#~ msgstr ""
+#~ "\n"
+#~ "SSSD-roll: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "SSSD-roll: OKÄND\n"
+
+#~ msgid "Warning: cycle in %s `%s'"
+#~ msgstr "Varning: cykel i %s ”%s”"
+
+#~ msgid "Warning: %s `%s' referenced but not defined"
+#~ msgstr "Varning: %s ”%s” refererad till men inte definierad"
+
+#~ msgid "getaudit: failed"
+#~ msgstr "getaudit: misslyckades"
+
+#~ msgid "getauid failed"
+#~ msgstr "getauid misslyckades"
+
+#~ msgid "au_to_subject: failed"
+#~ msgstr "au_to_subject: misslyckades"
+
+#~ msgid "au_to_exec_args: failed"
+#~ msgstr "au_to_exec_args: misslyckades"
+
+#~ msgid "au_to_return32: failed"
+#~ msgstr "au_to_return32: misslyckades"
+
+#~ msgid "getauid: failed"
+#~ msgstr "getauid: misslyckades"
+
+#~ msgid "au_to_text: failed"
+#~ msgstr "au_to_text: misslyckades"
+
+#~ msgid "internal error, expand_prompt() overflow"
+#~ msgstr "internt fel, stackspill i expand_prompt()"
+
+#~ msgid "%s owned by uid %u, should be uid %u"
+#~ msgstr "%s ägs av uid %u, ska vara uid %u"
+
+#~ msgid "%s exists but is not a regular file (0%o)"
+#~ msgstr "%s finns men är inte en vanlig fil (0%o)"
+
+#~ msgid "internal error, sudo_setenv2() overflow"
+#~ msgstr "internt fel, stackspill i sudo_setenv2()"
+
+#~ msgid "internal error, sudo_setenv() overflow"
+#~ msgstr "internt fel, stackspill i sudo_setenv()"
+
+#~ msgid ">>> %s: %s near line %d <<<"
+#~ msgstr ">>> %s: %s nära rad %d <<<"
+
+#~ msgid "unable to set locale to \"%s\", using \"C\""
+#~ msgstr "kunde inte ställa in lokalanpassning till \"%s\", använder \"C\""
+
+#~ msgid "invalid uri: %s"
+#~ msgstr "ogiltig uri: %s"
+
+#~ msgid "unable to mix ldaps and starttls"
+#~ msgstr "kunde inte blanda ldaps och starttls"
+
+#~ msgid "internal error, linux_audit_command() overflow"
+#~ msgstr "internt fel, stackspill i linux_audit_command()"
+
+#~ msgid "internal error: insufficient space for log line"
+#~ msgstr "internt fel: otillräckligt utrymme för loggrad"
+
+#~ msgid ""
+#~ " Commands:\n"
+#~ "\t"
+#~ msgstr ""
+#~ " Kommandon:\n"
+#~ "\t"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "unable to cache uid %u (%s), already exists"
+#~ msgstr "kunde inte mellanlagra uid %u (%s), finns redan"
+
+#~ msgid "unable to cache gid %u (%s), already exists"
+#~ msgstr "kunde inte mellanlagra gid %u (%s), finns redan"
+
+#~ msgid "unable to execute %s: %s"
+#~ msgstr "kunde inte köra %s: %s"
+
+#~ msgid "internal error, runas_groups overflow"
+#~ msgstr "internt fel, stackspill i runas_groups"
+
+#~ msgid "writing to standard output"
+#~ msgstr "skriver till standard ut"
+
+#~ msgid "invalid regex: %s"
+#~ msgstr "ogiltigt reguljärt uttryck: %s"
+
+#~ msgid "internal error, init_vars() overflow"
+#~ msgstr "internt fel, stackspill i init_vars()"
+
+#~ msgid "fill_args: buffer overflow"
+#~ msgstr "fill_args: buffertöverflöde"
+
+#~ msgid "pam_chauthtok: %s"
+#~ msgstr "pam_chauthtok: %s"
+
+#~ msgid "pam_authenticate: %s"
+#~ msgstr "pam_authenticate: %s"
+
+#~ msgid "Password:"
+#~ msgstr "Lösenord:"
diff --git a/plugins/sudoers/po/tr.mo b/plugins/sudoers/po/tr.mo
new file mode 100644
index 0000000..1440e90
--- /dev/null
+++ b/plugins/sudoers/po/tr.mo
Binary files differ
diff --git a/plugins/sudoers/po/tr.po b/plugins/sudoers/po/tr.po
new file mode 100644
index 0000000..a7b94d3
--- /dev/null
+++ b/plugins/sudoers/po/tr.po
@@ -0,0 +1,1721 @@
+# Turkish translations for sudoers package
+# This file is put in the public domain.
+# Todd C. Miller <Todd.Miller@courtesan.com>, 2011-2013
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.7b2\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2013-04-17 15:52-0400\n"
+"PO-Revision-Date: 2013-04-27 23:41+0200\n"
+"Last-Translator: Özgür Sarıer <ozgursarier1011601115@gmail.com>\n"
+"Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"
+"Language: tr\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.5.5\n"
+
+#: confstr.sh:2
+msgid "Password:"
+msgstr "Parola:"
+
+#: confstr.sh:3
+msgid "*** SECURITY information for %h ***"
+msgstr "*** %h için GÜVENLİK bilgisi ***"
+
+#: confstr.sh:4
+msgid "Sorry, try again."
+msgstr "Üzgünüm, yeniden deneyin."
+
+#: plugins/sudoers/alias.c:124
+#, c-format
+msgid "Alias `%s' already defined"
+msgstr "Takma ad `%s' önceden tanımlanmış"
+
+#: plugins/sudoers/auth/bsdauth.c:77
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "kullanıcı %s için oturum açma sınıfı elde edilemedi"
+
+#: plugins/sudoers/auth/bsdauth.c:83
+msgid "unable to begin bsd authentication"
+msgstr "bsd kimlik doğrulama işlemine başlanılamadı"
+
+#: plugins/sudoers/auth/bsdauth.c:91
+msgid "invalid authentication type"
+msgstr "geçersiz kimlik doğrulama türü"
+
+#: plugins/sudoers/auth/bsdauth.c:100
+msgid "unable to setup authentication"
+msgstr "kimlik doğrulama gerçekleştirilemedi"
+
+#: plugins/sudoers/auth/fwtk.c:59
+#, c-format
+msgid "unable to read fwtk config"
+msgstr "fwtk yapılandırması okunamadı"
+
+#: plugins/sudoers/auth/fwtk.c:64
+#, c-format
+msgid "unable to connect to authentication server"
+msgstr "kimlik doğrulama sunucusuna bağlanılamadı"
+
+#: plugins/sudoers/auth/fwtk.c:70 plugins/sudoers/auth/fwtk.c:94
+#: plugins/sudoers/auth/fwtk.c:127
+#, c-format
+msgid "lost connection to authentication server"
+msgstr "kimlik doğrulama sunucusunda bağlantı kaybı"
+
+#: plugins/sudoers/auth/fwtk.c:74
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"kimlik doğrulama sunucusu hatası:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:116
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:159
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: ayrıştırılamayan öge '%s': %s"
+
+#: plugins/sudoers/auth/kerb5.c:169
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: kimlik bilgisi önbelleği çözülemedi: %s"
+
+#: plugins/sudoers/auth/kerb5.c:217
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: seçenekler ayrılamadı: %s"
+
+#: plugins/sudoers/auth/kerb5.c:233
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: kimlik bilgileri elde edilemedi: %s"
+
+#: plugins/sudoers/auth/kerb5.c:246
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: kimlik bilgisi önbelleği hazırlanamadı: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: kimlik bilgisi önbellekte saklanamadı: %s"
+
+#: plugins/sudoers/auth/kerb5.c:315
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr ""
+
+#: plugins/sudoers/auth/kerb5.c:330
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: TGT doğrulanamadı! Muhtemel saldırı!: %s"
+
+#: plugins/sudoers/auth/pam.c:105
+msgid "unable to initialize PAM"
+msgstr "PAM başlatılamadı"
+
+#: plugins/sudoers/auth/pam.c:150
+msgid "account validation failure, is your account locked?"
+msgstr "hesap geçerliliği teyit edilemedi, hesabınız kilitli mi?"
+
+#: plugins/sudoers/auth/pam.c:154
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Hesabın veya hesap parolasının süresi dolmuş, parolanızı sıfırlayınız ve yeniden deneyiniz"
+
+#: plugins/sudoers/auth/pam.c:162
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "zaman aşımına uğramış parola değiştirilemedi: %s"
+
+#: plugins/sudoers/auth/pam.c:167
+msgid "Password expired, contact your system administrator"
+msgstr "Parola geçerlilik süresi dolmuş, sistem yöneticinizle temasa geçiniz"
+
+#: plugins/sudoers/auth/pam.c:171
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Hesap geçerlilik süresi dolmuş veya sudo için PAM yapılandırması bir \"account\" bölümünden yoksun, sistem yöneticinizle temasa geçiniz"
+
+#: plugins/sudoers/auth/pam.c:188
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "PAM kimlik doğrulama hatası: %s"
+
+#: plugins/sudoers/auth/pam.c:247
+#, c-format
+msgid "unable to establish credentials: %s"
+msgstr "kimlik bilgileri oluşturulamadı: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:103 plugins/sudoers/visudo.c:212
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "%s veritabanında bulunmuyorsunuz"
+
+#: plugins/sudoers/auth/securid5.c:80
+#, c-format
+msgid "failed to initialise the ACE API library"
+msgstr "ACE API kütüphanesinin hazırlanması başarısız oldu"
+
+#: plugins/sudoers/auth/securid5.c:106
+#, c-format
+msgid "unable to contact the SecurID server"
+msgstr "SecurID sunucusuyla bağlantı kurulamadı"
+
+#: plugins/sudoers/auth/securid5.c:115
+#, c-format
+msgid "User ID locked for SecurID Authentication"
+msgstr "Kullanıcı Kimliği(User ID), SecurID Kimlik Doğrulaması için kilitli"
+
+#: plugins/sudoers/auth/securid5.c:119 plugins/sudoers/auth/securid5.c:170
+#, c-format
+msgid "invalid username length for SecurID"
+msgstr "SecurID için geçersiz kullanıcı adı uzunluğu"
+
+#: plugins/sudoers/auth/securid5.c:123 plugins/sudoers/auth/securid5.c:175
+#, c-format
+msgid "invalid Authentication Handle for SecurID"
+msgstr "SecurID için geçersiz Kimlik Doğrulama İşleyicisi"
+
+#: plugins/sudoers/auth/securid5.c:127
+#, c-format
+msgid "SecurID communication failed"
+msgstr "SecurID iletişimi başarısız oldu"
+
+#: plugins/sudoers/auth/securid5.c:131 plugins/sudoers/auth/securid5.c:214
+#, c-format
+msgid "unknown SecurID error"
+msgstr "bilinmeyen SecurID hatası"
+
+#: plugins/sudoers/auth/securid5.c:165
+#, c-format
+msgid "invalid passcode length for SecurID"
+msgstr "SecurID için geçersiz şifre uzunluğu"
+
+#: plugins/sudoers/auth/sia.c:108
+msgid "unable to initialize SIA session"
+msgstr "SIA oturumu başlatılamadı"
+
+#: plugins/sudoers/auth/sudo_auth.c:119
+msgid "invalid authentication methods"
+msgstr "geçersiz kimlik doğrulama yöntemleri"
+
+#: plugins/sudoers/auth/sudo_auth.c:120
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Sudo içinde geçersiz kimlik doğrulama yöntemleri derlenmiş! Bağımsız ve bağımsız olmayan kimlik doğrulama yöntemlerini karma bir şekilde kullanamayabilirsiniz."
+
+#: plugins/sudoers/auth/sudo_auth.c:203
+msgid "no authentication methods"
+msgstr "kimlik doğrulama yöntemleri yok"
+
+#: plugins/sudoers/auth/sudo_auth.c:205
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Sudo içinde herhangi bir kimlik doğrulama yöntemi derlenmemiş! Kimlik doğrulamayı kapatmak isterseniz, --disable-authentication seçeneğini kullanınız."
+
+#: plugins/sudoers/auth/sudo_auth.c:389
+msgid "Authentication methods:"
+msgstr "Kimlik doğrulama yöntemleri:"
+
+#: plugins/sudoers/bsm_audit.c:60 plugins/sudoers/bsm_audit.c:63
+#: plugins/sudoers/bsm_audit.c:112 plugins/sudoers/bsm_audit.c:116
+#: plugins/sudoers/bsm_audit.c:168 plugins/sudoers/bsm_audit.c:172
+#, c-format
+msgid "getaudit: failed"
+msgstr "getaudit: işlem başarısız"
+
+#: plugins/sudoers/bsm_audit.c:90 plugins/sudoers/bsm_audit.c:153
+#, c-format
+msgid "Could not determine audit condition"
+msgstr "Denetim durumu belirlenemedi"
+
+#: plugins/sudoers/bsm_audit.c:101 plugins/sudoers/bsm_audit.c:160
+#, c-format
+msgid "getauid: failed"
+msgstr "getauid: işlem başarısız"
+
+#: plugins/sudoers/bsm_audit.c:103 plugins/sudoers/bsm_audit.c:162
+#, c-format
+msgid "au_open: failed"
+msgstr "au_open: işlem başarısız"
+
+#: plugins/sudoers/bsm_audit.c:118 plugins/sudoers/bsm_audit.c:174
+#, c-format
+msgid "au_to_subject: failed"
+msgstr "au_to_subject: işlem başarısız"
+
+#: plugins/sudoers/bsm_audit.c:122 plugins/sudoers/bsm_audit.c:178
+#, c-format
+msgid "au_to_exec_args: failed"
+msgstr "au_to_exec_args: işlem başarısız"
+
+#: plugins/sudoers/bsm_audit.c:126 plugins/sudoers/bsm_audit.c:187
+#, c-format
+msgid "au_to_return32: failed"
+msgstr "au_to_return32: işlem başarısız"
+
+#: plugins/sudoers/bsm_audit.c:129 plugins/sudoers/bsm_audit.c:190
+#, c-format
+msgid "unable to commit audit record"
+msgstr "denetim kaydı işlenemiyor"
+
+#: plugins/sudoers/bsm_audit.c:183
+#, c-format
+msgid "au_to_text: failed"
+msgstr "au_to_text: işlem başarısız"
+
+#: plugins/sudoers/check.c:189
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Yerel Sistem Yöneticisinden olağan öğütleri aldığınıza güveniyoruz.\n"
+"Bunları genellikle aşağıdaki üç şeyle özetleyebiliriz:\n"
+"\n"
+" #1) Diğer kişilerin özel hayatına saygı gösterin.\n"
+" #2) Bir yazmadan önce iki kere düşünün.\n"
+" #3) Büyük gücün büyük bir sorumluluk getirdiğini unutmayın.\n"
+"\n"
+
+#: plugins/sudoers/check.c:227 plugins/sudoers/check.c:233
+#: plugins/sudoers/sudoers.c:562 plugins/sudoers/sudoers.c:566
+#, c-format
+msgid "unknown uid: %u"
+msgstr "bilinmeyen uid: %u"
+
+#: plugins/sudoers/check.c:230 plugins/sudoers/policy.c:635
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:215
+#: plugins/sudoers/testsudoers.c:359
+#, c-format
+msgid "unknown user: %s"
+msgstr "bilinmeyen kullanıcı: %s"
+
+#: plugins/sudoers/def_data.c:27
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:31
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:35
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:39
+msgid "Put OTP prompt on its own line"
+msgstr "OTP güdüsünü kendi satırına yerleştir"
+
+#: plugins/sudoers/def_data.c:43
+msgid "Ignore '.' in $PATH"
+msgstr "$PATH içindeki '.' ögesini yoksay"
+
+#: plugins/sudoers/def_data.c:47
+msgid "Always send mail when sudo is run"
+msgstr "Sudonun çalıştırıldığı her zaman e-posta gönder"
+
+#: plugins/sudoers/def_data.c:51
+msgid "Send mail if user authentication fails"
+msgstr "Kullanıcı kimlik doğrulaması başarısız olursa e-posta gönder"
+
+#: plugins/sudoers/def_data.c:55
+msgid "Send mail if the user is not in sudoers"
+msgstr "Kullanıcı sudoers içinde değilse e-posta gönder"
+
+#: plugins/sudoers/def_data.c:59
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Kullanıcı bu makinedeki sudoers içinde değilse e-posta gönder"
+
+#: plugins/sudoers/def_data.c:63
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Kullanıcının bir komut çalıştırmasına izin verilmiyor ise e-posta gönder"
+
+#: plugins/sudoers/def_data.c:67
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Her kullanıcı/tty birleşik girişi için ayrı bir zaman damgası kullan"
+
+#: plugins/sudoers/def_data.c:71
+msgid "Lecture user the first time they run sudo"
+msgstr "Sudoyu ilk defa çalıştırdıkları zaman kullanıcıya gerekli öğütleri ver"
+
+#: plugins/sudoers/def_data.c:75
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Dosya sudo öğüdü içeriyor: %s"
+
+#: plugins/sudoers/def_data.c:79
+msgid "Require users to authenticate by default"
+msgstr "Öntanımlı olarak kullanıcıların kimlik doğrulaması gerekmektedir"
+
+#: plugins/sudoers/def_data.c:83
+msgid "Root may run sudo"
+msgstr "Kök kullanıcı (root) sudoyu çalıştırabilir"
+
+#: plugins/sudoers/def_data.c:87
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:91
+msgid "Log the year in the (non-syslog) log file"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:95
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Eğer sudo herhangi bir bağımsız değişkenle uyandırılmazsa, bir kabuk başlat"
+
+#: plugins/sudoers/def_data.c:99
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Kabuğu -s ile başlatırken $HOME çevre değişkenini hedef kullanıcıya ata"
+
+#: plugins/sudoers/def_data.c:103
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Her zaman $HOME çevre değişkenini hedef kullanıcının ev dizinine ata"
+
+#: plugins/sudoers/def_data.c:107
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Yararlı hata iletilerinin verilmesi için bazı bilgilerin toplanmasına izin ver"
+
+#: plugins/sudoers/def_data.c:111
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Sudoers dosyası içerisinde tam nitelikli ana makine adlarının olması gerekmektedir"
+
+#: plugins/sudoers/def_data.c:115
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Hatalı parola girdikleri zaman kullanıcıyı aşağıla"
+
+#: plugins/sudoers/def_data.c:119
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Ancak bir tty sahibi iseler kullanıcıya sudoyu çalıştırma izni ver"
+
+#: plugins/sudoers/def_data.c:123
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo EDITOR çevre değişkeninin gereğini şerefle yerine getirecektir."
+
+#: plugins/sudoers/def_data.c:127
+msgid "Prompt for root's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:131
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:135
+msgid "Prompt for the target user's password, not the users's"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:139
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Eğer bir tane varsa hedef kullanıcı oturum açma sınıfında öntanımlıları uygula"
+
+#: plugins/sudoers/def_data.c:143
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "LOGNAME ve USER çevre değişkenlerini ata"
+
+#: plugins/sudoers/def_data.c:147
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:151
+msgid "Don't initialize the group vector to that of the target user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:155
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %d"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:159
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:163
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:167
+#, c-format
+msgid "Number of tries to enter a password: %d"
+msgstr "Bir parola girişinde deneme sayısı: %d"
+
+#: plugins/sudoers/def_data.c:171
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:175
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Günlük kütüğü yolu: %s"
+
+#: plugins/sudoers/def_data.c:179
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "E-posta programı yolu: %s"
+
+#: plugins/sudoers/def_data.c:183
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "E-posta programı için bayraklar: %s"
+
+#: plugins/sudoers/def_data.c:187
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:191
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:195
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "E-posta iletileri için konu satırı: %s"
+
+#: plugins/sudoers/def_data.c:199
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Hatalı parola iletisi: %s"
+
+#: plugins/sudoers/def_data.c:203
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Kimlik doğrulama zaman damgası dizininin yolu: %s"
+
+#: plugins/sudoers/def_data.c:207
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Kimlik doğrulama zaman damgası dizininin sahibi: %s"
+
+#: plugins/sudoers/def_data.c:211
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:215
+#, c-format
+msgid "Default password prompt: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:219
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr ""
+
+#: plugins/sudoers/def_data.c:223
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:227
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:231
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Visudo tarafından kullanılacak düzenleyici yolu: %s"
+
+#: plugins/sudoers/def_data.c:235
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:239
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:243
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Sudo_noexec kütüphanesinin içerdiği taklit exec işlevlerini önyükle"
+
+#: plugins/sudoers/def_data.c:247
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "LDAP dizini kullanılabilir durumda ise, yerel sudoers dosyalarını yok sayalım mı"
+
+#: plugins/sudoers/def_data.c:251
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:255
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:259
+msgid "Allow users to set arbitrary environment variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:263
+msgid "Reset the environment to a default set of variables"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:267
+msgid "Environment variables to check for sanity:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:271
+msgid "Environment variables to remove:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:275
+msgid "Environment variables to preserve:"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:279
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:283
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:287
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:291
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:295
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:299
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:303
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:307
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:311
+msgid "Log user's input for the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:315
+msgid "Log the output of the command being run"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:319
+msgid "Compress I/O logs using zlib"
+msgstr "I/O günlüklerini zlib kullanarak sıkıştır"
+
+#: plugins/sudoers/def_data.c:323
+msgid "Always run commands in a pseudo-tty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:327
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:331
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:335
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:339
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:343
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:347
+msgid "Set of permitted privileges"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:351
+msgid "Set of limit privileges"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:355
+msgid "Run commands on a pty in the background"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:359
+msgid "Create a new PAM session for the command to run in"
+msgstr ""
+
+#: plugins/sudoers/def_data.c:363
+msgid "Maximum I/O log sequence number"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:207 plugins/sudoers/defaults.c:587
+#, c-format
+msgid "unknown defaults entry `%s'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:215 plugins/sudoers/defaults.c:225
+#: plugins/sudoers/defaults.c:245 plugins/sudoers/defaults.c:258
+#: plugins/sudoers/defaults.c:271 plugins/sudoers/defaults.c:284
+#: plugins/sudoers/defaults.c:297 plugins/sudoers/defaults.c:317
+#: plugins/sudoers/defaults.c:327
+#, c-format
+msgid "value `%s' is invalid for option `%s'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:218 plugins/sudoers/defaults.c:228
+#: plugins/sudoers/defaults.c:236 plugins/sudoers/defaults.c:253
+#: plugins/sudoers/defaults.c:266 plugins/sudoers/defaults.c:279
+#: plugins/sudoers/defaults.c:292 plugins/sudoers/defaults.c:312
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "no value specified for `%s'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:241
+#, c-format
+msgid "values for `%s' must start with a '/'"
+msgstr ""
+
+#: plugins/sudoers/defaults.c:303
+#, c-format
+msgid "option `%s' does not take a value"
+msgstr ""
+
+#: plugins/sudoers/env.c:288 plugins/sudoers/env.c:293
+#: plugins/sudoers/env.c:395 plugins/sudoers/linux_audit.c:82
+#: plugins/sudoers/policy.c:420 plugins/sudoers/policy.c:427
+#: plugins/sudoers/prompt.c:171 plugins/sudoers/sudoers.c:654
+#: plugins/sudoers/testsudoers.c:243
+#, c-format
+msgid "internal error, %s overflow"
+msgstr ""
+
+#: plugins/sudoers/env.c:367
+#, c-format
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr ""
+
+#: plugins/sudoers/env.c:1012
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:102
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:113 plugins/sudoers/sssd.c:256
+#, c-format
+msgid "unable to dlopen %s: %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:118
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr ""
+
+#: plugins/sudoers/group_plugin.c:123
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr ""
+
+#: plugins/sudoers/interfaces.c:119
+msgid "Local IP address and netmask pairs:\n"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:131 plugins/sudoers/iolog.c:144
+#: plugins/sudoers/timestamp.c:200 plugins/sudoers/timestamp.c:244
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:141 plugins/sudoers/iolog.c:155
+#: plugins/sudoers/iolog.c:159 plugins/sudoers/timestamp.c:165
+#: plugins/sudoers/timestamp.c:221 plugins/sudoers/timestamp.c:271
+#, c-format
+msgid "unable to mkdir %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:217 plugins/sudoers/sudoers.c:708
+#: plugins/sudoers/sudoreplay.c:354 plugins/sudoers/sudoreplay.c:815
+#: plugins/sudoers/sudoreplay.c:978 plugins/sudoers/timestamp.c:155
+#: plugins/sudoers/visudo.c:809
+#, c-format
+msgid "unable to open %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:250 plugins/sudoers/sudoers.c:711
+#, c-format
+msgid "unable to read %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:274 plugins/sudoers/timestamp.c:159
+#, c-format
+msgid "unable to write to %s"
+msgstr ""
+
+#: plugins/sudoers/iolog.c:334
+#, c-format
+msgid "unable to create %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:385
+#, c-format
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:408
+#, c-format
+msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:438
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:467
+#, c-format
+msgid "invalid uri: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:473
+#, c-format
+msgid "unable to mix ldap and ldaps URIs"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:477
+#, c-format
+msgid "unable to mix ldaps and starttls"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:496
+#, c-format
+msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:570
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:573
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1062
+#, c-format
+msgid "unable to get GMT time"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1068
+#, c-format
+msgid "unable to format timestamp"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1076
+#, c-format
+msgid "unable to build time filter"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1295
+#, c-format
+msgid "sudo_ldap_build_pass1 allocation mismatch"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1842
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1844
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: UNKNOWN\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1891
+#, c-format
+msgid " Order: %s\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:1899 plugins/sudoers/parse.c:515
+#: plugins/sudoers/sssd.c:1242
+#, c-format
+msgid " Commands:\n"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2321
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2355
+#, c-format
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr ""
+
+#: plugins/sudoers/ldap.c:2591
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:57
+#, c-format
+msgid "unable to open audit system"
+msgstr ""
+
+#: plugins/sudoers/linux_audit.c:93
+#, c-format
+msgid "unable to send audit message"
+msgstr ""
+
+#: plugins/sudoers/logging.c:140
+#, c-format
+msgid "%8s : %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:168
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr ""
+
+#: plugins/sudoers/logging.c:194
+#, c-format
+msgid "unable to open log file: %s: %s"
+msgstr "günlük kütüğü açılamadı: %s: %s"
+
+#: plugins/sudoers/logging.c:197
+#, c-format
+msgid "unable to lock log file: %s: %s"
+msgstr "günlük kütüğü kilitlenemedi: %s: %s"
+
+#: plugins/sudoers/logging.c:245
+msgid "No user or host"
+msgstr "Kullanıcı veya ana makine yok"
+
+#: plugins/sudoers/logging.c:247
+msgid "validation failure"
+msgstr "doğrulama başarısız"
+
+#: plugins/sudoers/logging.c:254
+msgid "user NOT in sudoers"
+msgstr "kullancı sudoers içinde DEĞİL"
+
+#: plugins/sudoers/logging.c:256
+msgid "user NOT authorized on host"
+msgstr "kullanıcı ana makine üzerinde yetkili DEĞİL"
+
+#: plugins/sudoers/logging.c:258
+msgid "command not allowed"
+msgstr "komuta izin verilmiyor"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s sudoers dosyası içinde değil. Bu olay rapor edilecek.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s, %s üzerinde sudoyu çalıştırma iznine sahip değil. Bu olay rapor edilecek.\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Üzgünüm, %s kullanıcısı %s üzerinde sudoyu çalıştıramayabilir.\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Üzgünüm, %s kullanıcısı '%s%s%s' komutunu %s%s%s olarak %s üzerinde çalıştırma iznine sahip değil.\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:383
+#: plugins/sudoers/sudoers.c:384 plugins/sudoers/sudoers.c:386
+#: plugins/sudoers/sudoers.c:387 plugins/sudoers/sudoers.c:1001
+#: plugins/sudoers/sudoers.c:1002
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: komut bulunamadı"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:379
+#, c-format
+msgid ""
+"ignoring `%s' found in '.'\n"
+"Use `sudo ./%s' if this is the `%s' you wish to run."
+msgstr ""
+
+#: plugins/sudoers/logging.c:353
+msgid "authentication failure"
+msgstr ""
+
+#: plugins/sudoers/logging.c:379
+msgid "a password is required"
+msgstr ""
+
+#: plugins/sudoers/logging.c:443 plugins/sudoers/logging.c:487
+#, c-format
+msgid "%d incorrect password attempt"
+msgid_plural "%d incorrect password attempts"
+msgstr[0] ""
+msgstr[1] ""
+
+#: plugins/sudoers/logging.c:566
+#, c-format
+msgid "unable to fork"
+msgstr ""
+
+#: plugins/sudoers/logging.c:573 plugins/sudoers/logging.c:629
+#, c-format
+msgid "unable to fork: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:619
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:644
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:680
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr ""
+
+#: plugins/sudoers/logging.c:899
+#, c-format
+msgid "internal error: insufficient space for log line"
+msgstr ""
+
+#: plugins/sudoers/match.c:631
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr ""
+
+#: plugins/sudoers/match.c:661
+#, c-format
+msgid "%s: read error"
+msgstr ""
+
+#: plugins/sudoers/match.c:670
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr ""
+
+#: plugins/sudoers/parse.c:124
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr ""
+
+#: plugins/sudoers/parse.c:127
+#, c-format
+msgid "parse error in %s"
+msgstr ""
+
+#: plugins/sudoers/parse.c:462
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+
+#: plugins/sudoers/parse.c:463
+#, c-format
+msgid " RunAsUsers: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:477
+#, c-format
+msgid " RunAsGroups: "
+msgstr ""
+
+#: plugins/sudoers/parse.c:486
+#, c-format
+msgid " Options: "
+msgstr ""
+
+#: plugins/sudoers/policy.c:517 plugins/sudoers/visudo.c:750
+#, c-format
+msgid "unable to execute %s"
+msgstr ""
+
+#: plugins/sudoers/policy.c:659
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:661
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:665
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:668
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:670
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/policy.c:671
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:148
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:190
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:374
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:410
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:564 plugins/sudoers/pwutil.c:586
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr ""
+
+#: plugins/sudoers/pwutil.c:584
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:122 plugins/sudoers/set_perms.c:445
+#: plugins/sudoers/set_perms.c:846 plugins/sudoers/set_perms.c:1141
+#: plugins/sudoers/set_perms.c:1431
+msgid "perm stack overflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:130 plugins/sudoers/set_perms.c:453
+#: plugins/sudoers/set_perms.c:854 plugins/sudoers/set_perms.c:1149
+#: plugins/sudoers/set_perms.c:1439
+msgid "perm stack underflow"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:189 plugins/sudoers/set_perms.c:500
+#: plugins/sudoers/set_perms.c:1200 plugins/sudoers/set_perms.c:1471
+msgid "unable to change to root gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:278 plugins/sudoers/set_perms.c:597
+#: plugins/sudoers/set_perms.c:983 plugins/sudoers/set_perms.c:1277
+msgid "unable to change to runas gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:609
+#: plugins/sudoers/set_perms.c:993 plugins/sudoers/set_perms.c:1287
+msgid "unable to change to runas uid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:627
+#: plugins/sudoers/set_perms.c:1009 plugins/sudoers/set_perms.c:1303
+msgid "unable to change to sudoers gid"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:361 plugins/sudoers/set_perms.c:698
+#: plugins/sudoers/set_perms.c:1055 plugins/sudoers/set_perms.c:1349
+#: plugins/sudoers/set_perms.c:1515
+msgid "too many processes"
+msgstr ""
+
+#: plugins/sudoers/set_perms.c:1583
+msgid "unable to set runas group vector"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:257
+#, c-format
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr ""
+
+#: plugins/sudoers/sssd.c:263 plugins/sudoers/sssd.c:271
+#: plugins/sudoers/sssd.c:278 plugins/sudoers/sssd.c:285
+#: plugins/sudoers/sssd.c:292
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:283
+#, c-format
+msgid "Matching Defaults entries for %s on this host:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:296
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:309
+#, c-format
+msgid "User %s may run the following commands on this host:\n"
+msgstr ""
+
+#: plugins/sudoers/sudo_nss.c:318
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:159 plugins/sudoers/sudoers.c:193
+#: plugins/sudoers/sudoers.c:673
+msgid "problem with defaults entries"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:165
+#, c-format
+msgid "no valid sudoers sources found, quitting"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:227
+#, c-format
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:234
+#, c-format
+msgid "you are not permitted to use the -C option"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:315
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:329
+msgid "no tty"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:330
+#, c-format
+msgid "sorry, you must have a tty to run sudo"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:378
+msgid "command in current directory"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:395
+#, c-format
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:723 plugins/sudoers/timestamp.c:216
+#: plugins/sudoers/timestamp.c:260 plugins/sudoers/timestamp.c:328
+#: plugins/sudoers/visudo.c:310 plugins/sudoers/visudo.c:576
+#, c-format
+msgid "unable to stat %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:726
+#, c-format
+msgid "%s is not a regular file"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:729 toke.l:913
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:733 toke.l:920
+#, c-format
+msgid "%s is world writable"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:736 toke.l:925
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:763
+#, c-format
+msgid "only root can use `-c %s'"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:780 plugins/sudoers/sudoers.c:782
+#, c-format
+msgid "unknown login class: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:814
+#, c-format
+msgid "unable to resolve host %s"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:866 plugins/sudoers/testsudoers.c:377
+#, c-format
+msgid "unknown group: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:292
+#, c-format
+msgid "invalid filter option: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:305
+#, c-format
+msgid "invalid max wait: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:311
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:314 plugins/sudoers/visudo.c:179
+#, c-format
+msgid "%s version %s\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:339
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:345
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:363
+#, c-format
+msgid "Replaying sudo session: %s\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:369
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:370
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:400
+#, c-format
+msgid "unable to set tty to raw mode"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:416
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:499
+#, c-format
+msgid "writing to standard output"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:528
+#, c-format
+msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:641 plugins/sudoers/sudoreplay.c:666
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:683
+#, c-format
+msgid "too many parenthesized expressions, max %d"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:694
+#, c-format
+msgid "unmatched ')' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:700
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:714
+#, c-format
+msgid "%s requires an argument"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:718 plugins/sudoers/sudoreplay.c:1058
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:724
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:737
+#, c-format
+msgid "unmatched '(' in expression"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:739
+#, c-format
+msgid "illegal trailing \"or\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:741
+#, c-format
+msgid "illegal trailing \"!\""
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1182
+#, c-format
+msgid "usage: %s [-h] [-d directory] [-m max_wait] [-s speed_factor] ID\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1185
+#, c-format
+msgid "usage: %s [-h] [-d directory] -l [search expression]\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1194
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/sudoreplay.c:1196
+msgid ""
+"\n"
+"Options:\n"
+" -d directory specify directory for session logs\n"
+" -f filter specify which I/O type to display\n"
+" -h display help message and exit\n"
+" -l [expression] list available session IDs that match expression\n"
+" -m max_wait max number of seconds to wait between events\n"
+" -s speed_factor speed up or slow down output\n"
+" -V display version information and exit"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:328
+msgid "\thost unmatched"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:331
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+
+#: plugins/sudoers/testsudoers.c:332
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:129
+#, c-format
+msgid "timestamp path too long: %s"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:203 plugins/sudoers/timestamp.c:247
+#: plugins/sudoers/timestamp.c:292
+#, c-format
+msgid "%s owned by uid %u, should be uid %u"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:208 plugins/sudoers/timestamp.c:252
+#, c-format
+msgid "%s writable by non-owner (0%o), should be mode 0700"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:286
+#, c-format
+msgid "%s exists but is not a regular file (0%o)"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:298
+#, c-format
+msgid "%s writable by non-owner (0%o), should be mode 0600"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:353
+#, c-format
+msgid "timestamp too far in the future: %20.20s"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:407
+#, c-format
+msgid "unable to remove %s, will reset to the epoch"
+msgstr ""
+
+#: plugins/sudoers/timestamp.c:414
+#, c-format
+msgid "unable to reset %s to the epoch"
+msgstr ""
+
+#: plugins/sudoers/toke_util.c:176
+#, c-format
+msgid "fill_args: buffer overflow"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:180
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:243 plugins/sudoers/visudo.c:533
+#, c-format
+msgid "press return to edit %s: "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:326 plugins/sudoers/visudo.c:332
+#, c-format
+msgid "write error"
+msgstr "yazma hatası"
+
+#: plugins/sudoers/visudo.c:414
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:419
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:425
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:448
+#, c-format
+msgid "%s unchanged"
+msgstr "%s değişmemiş"
+
+#: plugins/sudoers/visudo.c:477
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "geçici dosya (%s) yeniden açılamadı, %s değişmemiş."
+
+#: plugins/sudoers/visudo.c:487
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:526
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:578 plugins/sudoers/visudo.c:587
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:582 plugins/sudoers/visudo.c:592
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:609
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:623
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:633
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:695
+msgid "What now? "
+msgstr ""
+
+#: plugins/sudoers/visudo.c:709
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:757
+#, c-format
+msgid "unable to run %s"
+msgstr "%s çalıştırılamadı"
+
+#: plugins/sudoers/visudo.c:783
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:790
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:815
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "%s dosyasının ayrıştırılması başarısız oldu, bilinmeyen hata"
+
+#: plugins/sudoers/visudo.c:831
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "%s içindeki %d satırı yakınında ayrıştırma hatası\n"
+
+#: plugins/sudoers/visudo.c:834
+#, c-format
+msgid "parse error in %s\n"
+msgstr "%s içinde ayrıştırma hatası\n"
+
+#: plugins/sudoers/visudo.c:841 plugins/sudoers/visudo.c:846
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: ayrıştırma TAMAM\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s meşgul, daha sonra tekrar deneyin"
+
+#: plugins/sudoers/visudo.c:937
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "belirtilen düzenleyici (%s) yok"
+
+#: plugins/sudoers/visudo.c:960
+#, c-format
+msgid "unable to stat editor (%s)"
+msgstr "düzenleyici (%s) başlatılamadı"
+
+#: plugins/sudoers/visudo.c:1008
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "hiçbir düzenleyici bulunamadı (düzenleyici yolu = %s)"
+
+#: plugins/sudoers/visudo.c:1100
+#, c-format
+msgid "Error: cycle in %s_Alias `%s'"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1101
+#, c-format
+msgid "Warning: cycle in %s_Alias `%s'"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1104
+#, c-format
+msgid "Error: %s_Alias `%s' referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1105
+#, c-format
+msgid "Warning: %s_Alias `%s' referenced but not defined"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1240
+#, c-format
+msgid "%s: unused %s_Alias %s"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1302
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+
+#: plugins/sudoers/visudo.c:1304
+msgid ""
+"\n"
+"Options:\n"
+" -c check-only mode\n"
+" -f sudoers specify sudoers file location\n"
+" -h display help message and exit\n"
+" -q less verbose (quiet) syntax error messages\n"
+" -s strict syntax checking\n"
+" -V display version information and exit"
+msgstr ""
+"\n"
+"Seçenekler:\n"
+" -c sadece denetim kipi\n"
+" -f sudoers sudoers dosyasının konumu\n"
+" -h yardım iletisini görüntüle ve çık\n"
+" -q daha az ayrıntılı (sessiz=quiet) sözdizim hata iletileri\n"
+" -s sıkı sözdizim denetimi\n"
+" -V sürüm bilgisini görüntüle ve çık"
+
+#: toke.l:886
+msgid "too many levels of includes"
+msgstr ""
diff --git a/plugins/sudoers/po/uk.mo b/plugins/sudoers/po/uk.mo
new file mode 100644
index 0000000..f8acd08
--- /dev/null
+++ b/plugins/sudoers/po/uk.mo
Binary files differ
diff --git a/plugins/sudoers/po/uk.po b/plugins/sudoers/po/uk.po
new file mode 100644
index 0000000..4610c19
--- /dev/null
+++ b/plugins/sudoers/po/uk.po
@@ -0,0 +1,2347 @@
+# Ukrainian translation for sudoers.
+# This file is put in the public domain.
+#
+# Yuri Chornoivan <yurchor@ukr.net>, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-29 21:04+0200\n"
+"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
+"Language-Team: Ukrainian <translation-team-uk@lists.sourceforge.net>\n"
+"Language: uk\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Generator: Lokalize 2.0\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "синтаксична помилка"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "Пароль %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] пароль до %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Пароль: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** Дані щодо ЗАХИСТУ %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Вибачте, повторіть спробу."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336
+#: gram.y:399 gram.y:407 gram.y:417 gram.y:450 gram.y:457 gram.y:464
+#: gram.y:471 gram.y:553 gram.y:560 gram.y:569 gram.y:578 gram.y:595
+#: gram.y:707 gram.y:714 gram.y:721 gram.y:729 gram.y:829 gram.y:836
+#: gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890 gram.y:897
+#: gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:195 plugins/sudoers/logging.c:511
+#: plugins/sudoers/logging.c:532 plugins/sudoers/logging.c:573
+#: plugins/sudoers/logging.c:752 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr "не вдалося отримати потрібний об’єм пам’яті"
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr "для контрольної суми слід вказати шлях"
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr "некоректне значення notbefore"
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr "некоректне значення notafter"
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr "значення часу очікування є надто великим"
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr "некоректне значення часу очікування"
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:354 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:511 plugins/sudoers/logging.c:532
+#: plugins/sudoers/logging.c:572 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:724 plugins/sudoers/match.c:771
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1008
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Замінник «%s» вже визначено"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "не вдалося отримати клас входу до системи для користувача %s"
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr "не вдалося розпочати розпізнавання за BSD"
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr "некоректний тип розпізнавання"
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr "не вдалося ініціалізувати розпізнавання за BSD"
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr "термін дії вашого облікового запису вичерпано"
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr "не вдалося підтвердити"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr "не вдалося прочитати налаштування fwtk"
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr "не вдалося встановити з’єднання з сервером розпізнавання"
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr "втрачено зв’язок з сервером розпізнавання"
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"помилка сервера розпізнавання:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: не вдалося перетворити реєстраційний запис на рядок («%s»): %s"
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: не вдалося обробити «%s»: %s"
+
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: не вдалося визначити кеш реєстраційних даних: %s"
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: не вдалося розмістити параметри: %s"
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: не вдалося отримати реєстраційні дані: %s"
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: не вдалося ініціалізувати кеш реєстраційних даних: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: не вдалося зберегти реєстраційні дані у кеші: %s"
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: не вдалося отримати реєстраційний запис вузла: %s"
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: спроба перевірки TGT зазнала невдачі! Ймовірно, вас атаковано: %s"
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr "не вдалося ініціалізувати PAM"
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "Помилка розпізнавання PAM: %s"
+
+#: plugins/sudoers/auth/pam.c:221
+msgid "account validation failure, is your account locked?"
+msgstr "помилка під час спроби перевірки облікового запису. Ваш обліковий запис заблоковано?"
+
+#: plugins/sudoers/auth/pam.c:229
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Строк дії облікового запису або пароля збіг, визначте новий пароль і повторіть спробу"
+
+#: plugins/sudoers/auth/pam.c:238
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "не вдалося змінити пароль, строк дії якого завершився: %s"
+
+#: plugins/sudoers/auth/pam.c:246
+msgid "Password expired, contact your system administrator"
+msgstr "Строк дії пароля збіг, зверніться до адміністратора вашої системи щодо поновлення пароля"
+
+#: plugins/sudoers/auth/pam.c:250
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Строк дії облікового запису збіг або у файлі налаштувань PAM немає розділу \"account\" для sudo. Повідомте про це адміністратора вашої системи."
+
+#: plugins/sudoers/auth/pam.c:257 plugins/sudoers/auth/pam.c:262
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "Помилка керування обліковими записами PAM: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:232
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "вас немає у базі даних %s"
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr "не вдалося ініціалізувати бібліотеку програмного інтерфейсу до ACE"
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr "не вдалося встановити зв’язок з сервером SecurID"
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr "Ідентифікатор користувача заблоковано для розпізнавання SecurID"
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr "некоректна довжина імені користувача для SecurID"
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr "некоректний дескриптор розпізнавання для SecurID"
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr "спроба обміну даними з SecurID зазнала невдачі"
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr "невідома помилка SecurID"
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr "некоректна довжина коду пароля для SecurID"
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr "не вдалося ініціалізувати сеанс SIA"
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr "некоректні способи розпізнавання"
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "sudo зібрано з підтримкою некоректних способів розпізнавання! Не можна змішувати власні і зовнішні способи розпізнавання."
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr "немає способів розпізнавання"
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "sudo зібрано без можливостей з взаємодії з інструментами розпізнавання! Якщо ви хочете вимкнути розпізнавання, скористайтеся параметром налаштування --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr "Не вдалося ініціалізувати методи розпізнавання."
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr "Способи розпізнавання:"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr "Не вдалося визначити умови аудита"
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr "не вдалося надіслати запис аудита"
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Ми сподіваємося, що ви отримали належні настанови від адміністратора\n"
+"локальної системи. Зазвичай, подібні настанови зводяться до такого:\n"
+"\n"
+" #1) Поважайте конфіденційність даних інших користувачів.\n"
+" #2) Обдумайте свої дії, перш ніж виконувати їх.\n"
+" #3) Користування широкими правами розширює сферу відповідальності.\n"
+"\n"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr "невідоме значення uid: %u"
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1136
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr "невідомий користувач: %s"
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "збільшення порядку: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "початковий порядок: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr "доповнення порядку: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s, версія %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "Граматична перевірка %s, версія %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr "непідтримуваний формат вхідних даних, %s"
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr "непідтримуваний формат виведення, %s"
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: файли вхідних і вихідних даних мають бути різними файлами"
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:238
+#: plugins/sudoers/visudo.c:594 plugins/sudoers/visudo.c:917
+msgid "unable to initialize sudoers default values"
+msgstr "не вдалося ініціалізувати типові значення sudoers"
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: невідоме ключове слово: %s"
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "некоректний тип типових значень: %s"
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "некоректний тип придушення: %s"
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr "некоректний фільтр: %s"
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:913
+#, c-format
+msgid "unable to open %s"
+msgstr "не вдалося відкрити %s"
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:922
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "не вдалося обробити файл %s, невідома помилка"
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:939
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "помилка обробки у %s поблизу рядка %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:942
+#, c-format
+msgid "parse error in %s\n"
+msgstr "помилка обробки у %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr "не вдалося виконати запис до %s"
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s — перетворення форматів файлів sudoers\n"
+"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Параметри:\n"
+" -b, --base=dn базовий DN для запитів sudo до LDAP\n"
+" -d, --defaults=типи перетворювати лише записи Defaults вказаних типів\n"
+" -e, --expand-aliases розгортати псевдоніми під час перетворення\n"
+" -f, --output-format=формат встановити формат виведення: JSON, LDIF або sudoers\n"
+" -i, --input-format=формат встановити формат вхідних даних: LDIF або sudoers\n"
+" -I, --increment=число число, на яке слід збільшувати sudoOrder\n"
+" -h, --help вивести довідкове повідомлення і завершити роботу\n"
+" -m, --match=фільтр перетворювати лише записи, які відповідають фільтру\n"
+" -M, --match-local встановлювати відповідність фільтра за базами даних passwd та груп\n"
+" -o, --output=файл_результатів записати перетворені дані sudoers до файла файл_результатів\n"
+" -O, --order-start=число початкова точка для першого sudoOrder\n"
+" -p, --prune-matches вилучити невідповідні записи користувачів, груп і вузлів\n"
+" -P, --padding=число доповнення основи для нарощування sudoOrder\n"
+" -s, --suppress=розділи придушити виведення певних розділів\n"
+" -V, --version вивести дані щодо версії і завершити роботу"
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "невідомий запис типових параметрів «%s»"
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr "не вдалося отримати гринвіцький час"
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr "не вдалося виконати форматування часового штампа"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1015 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "внутрішня помилка, переповнення %s"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr "забагато записів sudoers, максимальна кількість — %u"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "не встановлено значення змінної середовища SUDOERS_BASE і не вказано параметра -b."
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Інструмент ведення журналу, якщо використано syslog: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Пріоритетність, яка використовуватиметься у syslog для успішних розпізнавань: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Пріоритетність, яка використовуватиметься у syslog для неуспішних розпізнавань: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "Розташовувати запит щодо OTP у окремому рядку"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "Ігнорувати «.» у $PATH"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "Завжди надсилати листа, коли викликано sudo"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "Надсилати листа, якщо користувачу не вдалося пройти розпізнавання"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "Надсилати листа, якщо користувача немає серед sudoers"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Надсилати листа, якщо користувача немає у списку sudoers цього вузла"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Надсилати листа, якщо користувачеві заборонено виконувати команду"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "Надсилати листа, якщо користувач намагається віддати команду"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Окремий часовий штамп для кожної комбінації користувач/tty"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "Показувати настанови користувачеві під час першого запуску sudo"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "Файл з настановами щодо sudo: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "Типово, вимагати розпізнавання"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "Root може виконувати sudo"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Записувати назву вузла до файла журналу (не syslog)"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Записувати рік до файла журналу (не syslog)"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Якщо sudo викликано без параметрів, запускати командну оболонку"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Встановлювати $HOME відповідно до вказаного користувача для запуску оболонки з -s"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Завжди встановлювати значенням $HOME домашній каталог вказаного користувача"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Дозволити збирання даних з метою формування зрозумілих повідомлень про помилки"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "У файлі sudoers слід вказати повні назви вузлів"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Знущатися з користувача, якщо введено помилковий пароль"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Дозволяти користувачеві виконувати sudo, лише якщо з ним пов’язано tty"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo зважатимwill honor the EDITOR environment variable"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "Надсилати запит на пароль root, а не користувача"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Надсилати запит щодо пароля runas_default, але пароля самого користувача"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Надсилати запит щодо пароля потрібного користувача, але пароля самого користувача"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Застосовувати типові параметри у класі вказаного користувача, якщо такий клас є"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Встановити значення змінних середовища LOGNAME і USER"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Встановлювати для потрібного користувача ефективний uid, а не справжній uid"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Не ініціалізувати вектор групи відповідно до вказаного користувача"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Позиція, на якій слід переносити рядки файла журналу (0 — без перенесення): %u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Час очікування на часовий штамп розпізнавання: %.1f хвилина"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Час очікування на введення пароля: %.1f хвилина"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Кількість спроб введення пароля: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Потрібне значення umask або 0777 для користувачевого: 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Шлях до файла журналу: %s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Шлях до програми ел. пошти: %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Параметри програми ел. пошти: %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Адреса, на яку надсилатимуться листи: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Адреса, з якої надсилатимуться листи: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Тема листів: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Повідомлення про помилковий пароль: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Шлях до каталогу стану отримання настанов: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Шлях до каталогу часових штампів розпізнавання: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Власник каталогу часових штампів розпізнавання: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Користувачів цієї групи звільнено від потреби у введенні пароля і PATH: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Типовий запит пароля: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Якщо встановлено, запит щодо паролю замінюватиме запит системи."
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Типовий користувач для запуску команд: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Значення для заміни $PATH користувача: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Шлях до редактора, який використовуватиме visudo: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Умови запиту пароля для псевдокоманди «list»: %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Умови запиту пароля для псевдокоманди «verify»: %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Попередньо завантажувати фіктивні функції виконання з бібліотеки sudo_noexec"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Чи слід ігнорувати локальний файл sudoers, якщо є доступ до каталогу LDAP"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Дескриптори файлів >= %d буде закрито перед виконанням команди"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Якщо встановлено, користувачі можуть перевизначати значення «closefrom» за допомогою параметра -C"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Дозволити користувачам встановлювати значення довільних змінних середовища"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "Відновити типовий набір змінних середовища"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "Змінні середовища, коректність яких слід перевіряти:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "Змінні середовища, які слід вилучити:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "Змінні середовища, які слід зберегти:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Роль SELinux, яку слід використати у новому контексті захисту: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Тип SELinux, який слід використати у новому контексті захисту: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Шлях до специфічного для sudo файла середовища: %s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Шлях до специфічного для sudo файла середовища з обмеженим доступом: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Локаль, яку слід використати під час обробки sudoers: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Дозволити sudo надсилати запит щодо пароля, навіть якщо цей пароль буде видимим"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Супроводжувати введення користувачем пароля показом замінників символів пароля"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Швидше встановлення відповідності, менш точне, але без доступу до файлової системи"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "Значення umask, вказане у sudoers, перевизначатиме значення користувача, навіть якщо це значення відкриває ширший доступ"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "Записувати дані, вказані користувачем під час виконання команди"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "Записувати дані, виведені командою під час виконання"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "Стискати журнали за допомогою zlib"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "Завжди запускати команди у псевдо-tty"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Додаток для підтримки не-Unix груп: %s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Каталог, у якому слід зберігати журнали введення/виведення: %s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Файл, у якому слід зберігати журнал введення/виведення даних: %s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Додати запис до файла utmp/utmpx під час розміщення pty"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Встановити користувача у utmp у значення користувача, від імені якого виконується команда"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Набір дозвільних прав доступу: %s"
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Набір обмежувальних прав доступу: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "Виконувати команди у pty у фоновому режимі"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "Назва служби PAM, якою слід скористатися: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "Назва служби PAM, якою слід скористатися для оболонок входу до системи: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Спробувати встановити реєстраційні дані PAM для користувача, від імені якого виконуватимуться дії"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "Створити сеанс PAM для виконання команди"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Максимальний номер у послідовності журналу введення-виведення: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "Увімкнути підтримку мережевих груп у sudoers"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Перевіряти можливість запису до батьківського каталогу під час редагування фалів за допомогою sudoedit"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Переходити за символічними посиланнями під час редагування файлів за допомогою sudoedit"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "Надсилати запит до додатка груп щодо невідомих груп системи"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Встановлювати відповідність мережевим групам за усім кортежем даних: користувачем, вузлом і доменом"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Дозволити виконання команд, навіть якщо sudo не може здійснювати запис до журналу аудиту"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Дозволити виконання команд, навіть якщо sudo не може здійснювати запис до журналу введення-виведення"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Дозволити виконання команд, навіть якщо sudo не може здійснювати запис до файла журналу"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Визначати групи у sudoers і встановлювати відповідність не назві, а ідентифікатору групи"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Записи журналу, які виявляться довшими за це значення, буде поділено на декілька повідомлень журналу системи: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Користувач, який буде власником усіх файлів журналу введення-виведення: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Група, яка буде власником усіх файлів журналу введення-виведення: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Режим доступу до файлів, яким слід скористатися для файлів журналу введення-виведення: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Виконати команди за дескриптором файла замість виконання за шляхом: %s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Ігнорувати невідомі записи Defaults у sudoers замість показу попередження"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Час у секундах, який має минути, щоб команду буде перервано: %u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Надати змогу користувачеві встановлювати час очікування у командному рядку"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Скидати дані журналу введення-виведення на диск негайно, без буферизації"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "Включати ідентифікатор процесу до журналів syslog"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Тип запису часової позначки розпізнавання: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "Повідомлення про помилку розпізнавання: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "Ігнорувати регістр символів при пошуку імен користувачів"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "Ігнорувати регістр символів при пошуку назв груп"
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d невідомий запис типових параметрів, «%s»"
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: невідомий запис типових параметрів, «%s»"
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d не вказано значення для «%s»"
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: не вказано значення для «%s»"
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d значення для «%s» має починатися з «/»"
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: значення для «%s» має починатися з «/»"
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d параметру «%s» не потрібно передавати значення"
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: параметру «%s» не потрібно передавати значення"
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d некоректний тип Defaults, 0x%x, для параметра «%s»"
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: некоректний тип Defaults, 0x%x, для параметра «%s»"
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d значення «%s» є некоректним для параметра «%s»"
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: значення «%s» є некоректним для параметра «%s»"
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: помилкове значення envp, невідповідність довжин"
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr "не вдалося перебудувати середовище"
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "вибачте, вам не дозволено встановлювати такі змінні середовища: %s"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "помилка обробки у %s поблизу рядка %d"
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "помилка обробки у %s"
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "непідтримуваний тип контрольної суми, %d, для %s"
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr "%s: помилка читання"
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s має належати користувачеві з uid %d"
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s має бути доступним до запису лише для власника"
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "не вдалося завантажити %s: %s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "не вдалося знайти символ «group_plugin» у %s"
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: несумісна основна версія додатка обробки груп %d, мало бути — %d"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "не вдалося обробити IP-адресу «%s»"
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "не вдалося обробити маску мережі «%s»"
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Пари локальних IP-адрес і масок мережі:\n"
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s існує, але не є каталогом (0%o)"
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "не вдалося створити каталог %s"
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:723
+#: plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "не вдалося змінити режим доступу до %s на значення 0%o"
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1167
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr "невідома група: %s"
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr "не вдалося прочитати %s"
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr "не вдалося створити %s"
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "не вдалося здійснити запис до файла журналу введення-виведення: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr "%s: внутрішня помилка, файл журналу введення-виведення для події %d не відкрито"
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr "%s: внутрішня помилка, некоректний сигнал %d"
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: некоректний файл журналу"
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: не вказано даних щодо часової позначки"
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: часова позначка %s: %s"
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: не вказано даних щодо користувача"
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: не вказано даних щодо користувача, від імені якого відбуватиметься виконання"
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: не вказано даних щодо групи, від імені якої відбуватиметься виконання"
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr "підтримки starttls, якщо використовується ldaps, не передбачено"
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "не вдалося ініціалізувати базу даних сертифікатів і ключів SSL: %s"
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "щоб скористатися SSL, вам слід встановити для TLS_CERT значення %s"
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "не вдалося ініціалізувати LDAP: %s"
+
+#: plugins/sudoers/ldap.c:1648
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls вказано, але у бібліотеках LDAP не передбачено підтримки ldap_start_tls_s() або ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "некоректний атрибут sudoOrder: %s"
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: занадто великий номер порту"
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "непідтримуваний тип адреси LDAP: %s"
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "не можна використовувати суміш з адрес ldap і ldaps"
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "не вдалося перетворити запис sudoOption: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "не вдалося відкрити систему аудита"
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr "не вдалося надіслати повідомлення аудита"
+
+#: plugins/sudoers/logging.c:113
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:141
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (команда продовжується) %s"
+
+#: plugins/sudoers/logging.c:170
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "не вдалося відкрити файл журналу: %s"
+
+#: plugins/sudoers/logging.c:178
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "не вдалося заблокувати файл журналу: %s"
+
+#: plugins/sudoers/logging.c:211
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "не вдалося виконати запис до файла журналу: %s"
+
+#: plugins/sudoers/logging.c:240
+msgid "No user or host"
+msgstr "Немає користувача або вузла"
+
+#: plugins/sudoers/logging.c:242
+msgid "validation failure"
+msgstr "помилка під час спроби перевірки"
+
+#: plugins/sudoers/logging.c:249
+msgid "user NOT in sudoers"
+msgstr "користувача немає у списку sudoers"
+
+#: plugins/sudoers/logging.c:251
+msgid "user NOT authorized on host"
+msgstr "користувача не уповноважено на дії на вузлі"
+
+#: plugins/sudoers/logging.c:253
+msgid "command not allowed"
+msgstr "виконання команди заборонено"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s немає у файлі sudoers. Запис про подію додано до звіту.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s заборонено виконувати sudo на %s. Запис про подію додано до звіту.\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Вибачте, користувач %s не має права виконувати sudo на %s.\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Вибачте, користувач %s не має права виконувати «%s%s%s» від імені %s%s%s на %s.\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: команду не знайдено"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"пропущено «%s» знайдений у «.»\n"
+"Скористайтеся командою «sudo ./%s», якщо вам потрібно виконати саме «%s»."
+
+#: plugins/sudoers/logging.c:354
+msgid "authentication failure"
+msgstr "помилка під час спроби розпізнавання"
+
+#: plugins/sudoers/logging.c:380
+msgid "a password is required"
+msgstr "слід вказати пароль"
+
+#: plugins/sudoers/logging.c:443
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u невдала спроба введення пароля"
+msgstr[1] "%u невдалих спроби введення пароля"
+msgstr[2] "%u невдалих спроб введення пароля"
+msgstr[3] "одна невдала спроба введення пароля"
+
+#: plugins/sudoers/logging.c:666
+msgid "unable to fork"
+msgstr "не вдалося створити відгалуження"
+
+#: plugins/sudoers/logging.c:674 plugins/sudoers/logging.c:726
+#, c-format
+msgid "unable to fork: %m"
+msgstr "не вдалося створити відгалуження: %m"
+
+#: plugins/sudoers/logging.c:716
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "не вдалося відкрити канал: %m"
+
+#: plugins/sudoers/logging.c:741
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "не вдалося здублювати stdin: %m"
+
+#: plugins/sudoers/logging.c:779
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "не вдалося виконати %s: %m"
+
+#: plugins/sudoers/match.c:874
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "контрольну суму для %s (%s) подано не у формі %s"
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:421 plugins/sudoers/visudo.c:717
+#, c-format
+msgid "unable to stat %s"
+msgstr "не вдалося виконати stat для %s"
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"Роль LDAP: %s\n"
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Запис sudoers:\n"
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr " Користувачі для запуску: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr " Групи для запуску: "
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr " Параметри: "
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr " Команди:\n"
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Відповідність записів Defaults для %s на %s:\n"
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Типові значення для запуску від імені і команд для %s:\n"
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Користувач %s має право виконувати на %s такі команди:\n"
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Користувач %s не має права виконувати sudo на %s.\n"
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "ігноруємо некоректне значення атрибута: %s"
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "ігноруємо неповний запис sudoRole: cn: %s"
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "оболонкою sudo встановлено некоректне значення параметра %.*s"
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr "не вдалося обробити список мережевих адрес"
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr "ім'я користувача не встановлено за допомогою оболонки sudo"
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr "ідентифікатор користувача не встановлено за допомогою оболонки sudo"
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr "ідентифікатор групи не встановлено за допомогою оболонки sudo"
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr "назву вузла не встановлено за допомогою оболонки sudo"
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:220
+#: plugins/sudoers/visudo.c:851
+#, c-format
+msgid "unable to execute %s"
+msgstr "не вдалося виконати %s"
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Додаток правил sudoers версії %s\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Граматична перевірка файла sudoers версії %d\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Шлях до sudoers: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "Шлях до nsswitch: %s\n"
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "Шлях до ldap.conf: %s\n"
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "Шлях до ldap.secret: %s\n"
+
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "неможливо зареєструвати процедуру перехоплення типу %d (версія %d.%d)"
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "не вдалося кешувати uid %u, не вистачає пам’яті"
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "не вдалося кешувати uid %u, запис вже існує"
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "не вдалося кешувати користувача %s, не вистачає пам’яті"
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "не вдалося кешувати користувача %s, запис вже існує"
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "не вдалося кешувати gid %u, не вистачає пам’яті"
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "не вдалося кешувати gid %u, запис вже існує"
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "не вдалося кешувати групу %s, не вистачає пам’яті"
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "не вдалося кешувати групу %s, запис вже існує"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "не вдалося кешувати список груп %s, запис вже існує"
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "не вдалося кешувати список груп %s, не вистачає пам’яті"
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "не вдалося обробити записи груп %s"
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "не вдалося обробити записи ідентифікаторів груп %s"
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr "переповнення стека доступу"
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr "вичерпання стека доступу"
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr "не вдалося змінити ідентифікатор групи (gid) root"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr "не вдалося змінити gid на runas"
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr "не вдалося встановити вектор групи виконання"
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr "не вдалося змінити uid на runas"
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr "не вдалося змінити gid на sudoers"
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr "забагато процесів"
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr "не вдалося отримати поточний робочий каталог"
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "обрізаний шлях аудиту user_cmnd: %s"
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "обрізаний шлях аудиту argv[0]: %s"
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr "повідомлення audit_failure є надто довгим"
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "Не вдалося ініціалізувати джерело SSS. Чи встановлено у вашій системі SSSD?"
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "не вдалося знайти символ «%s» у %s"
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr "проблема з типовими записами"
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr "не знайдено коректних джерел даних sudoers, завершення роботи"
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers вказує, що sudo не можна користуватися для виконання команд від root"
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr "вам не дозволено використовувати параметр -C"
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "власник часового штампа (%s): не знайдено користувача з таким іменем"
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr "немає tty"
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr "вибачте, для виконання sudo вашому користувачеві потрібен tty"
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr "команда у поточному каталозі"
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "вибачте, вам не дозволено встановлювати час очікування на виконання команди"
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "вибачте, вам не дозволено зберігати середовище"
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr "надто довга команда"
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s не є звичайним файлом"
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s належить uid %u, має належати %u"
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr "Запис до «%s» можливий для довільного користувача"
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s належить gid %u, має належати %u"
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "використовувати «-c %s» може лише root"
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr "невідомий клас входу: %s"
+
+#: plugins/sudoers/sudoers.c:1069 plugins/sudoers/sudoers.c:1083
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "не вдалося визначити адресу вузла %s"
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "некоректний параметр фільтрування: %s"
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "некоректне значення макс. очікування: %s"
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "некоректний коефіцієнт швидкості: %s"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/timing: %s"
+
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/timing: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Відтворення сеансу sudo: %s"
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr "не вдалося додати подію до черги обробки"
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr "не вдалося перевести tty у режим без обробки даних"
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Попередження: розміри вашого термінала є замалими для належного показу журналу.\n"
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Встановлено формат журналу %d x %d, тоді як формат термінала — %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Відтворення завершено, натисніть будь-яку клавішу, щоб повернутися до термінала."
+
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "некоректний рядок у файлі timing: %s"
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "неоднозначний вираз «%s»"
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr "зайва дужка, «)», у виразі"
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "невідомий ключ пошуку «%s»"
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s потребує визначення аргументу"
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "некоректний формальний вираз: %s"
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "не вдалося обробити дату «%s»"
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr "зайва дужка, «(», у виразі"
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr "помилкове завершальне «or»"
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr "помилкове завершальне «!»"
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr "невідомий тип пошуку %d"
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr "користування: %s [-hnRS] [-d каталог] [-m число] [-s число] ідентифікатор\n"
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "використання: %s [-h] [-d каталог] -l [вираз для пошуку]\n"
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s — відтворення журналів сеансів sudo\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Параметри:\n"
+" -d, --directory=каталог вказати каталог для журналів сеансу\n"
+" -f, --filter=фільтр вказати, який тип вводу-виводу слід показувати\n"
+" -h, --help показати довідкове повідомлення і завершити роботу\n"
+" -l, --list показати список можливих ідентифікаторів сеансів, відповідних до виразу\n"
+" -m, --max-wait=макс_очік максимальний час (у секундах) очікування між подіями\n"
+" -S, --suspend-wait очікувати, доки виконання команди призупинено\n"
+" -s, --speed=коеф_швидк коефіцієнт прискорення або сповільнення виводу даних\n"
+" -V, --version показати дані щодо версії і завершити роботу"
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr "\tвідповідника вузла не знайдено"
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Команду дозволено"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Команду заборонено"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Не знайдено відповідника команди"
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr "%s доступний до запису учасниками групи"
+
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "не вдалося обрізати файл часової позначки до %lld байтів"
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:482 plugins/sudoers/visudo.c:488
+msgid "unable to read the clock"
+msgstr "не вдалося прочитати час на годиннику"
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr "ігноруємо часову позначку з майбутнього"
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "занадто далека часова позначка у майбутньому: %20.20s"
+
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "не вдалося заблокувати файл часової позначки %s"
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "шлях до даних щодо стану отримання настанов є занадто довгим: %s/%s"
+
+#: plugins/sudoers/visudo.c:216
+msgid "the -x option will be removed in a future release"
+msgstr "параметр -x буде вилучено у наступному випуску"
+
+#: plugins/sudoers/visudo.c:217
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "будь ласка, скористайтеся замість нього програмою cvtsudoers"
+
+#: plugins/sudoers/visudo.c:268 plugins/sudoers/visudo.c:650
+#, c-format
+msgid "press return to edit %s: "
+msgstr "натисніть Enter для редагування %s: "
+
+#: plugins/sudoers/visudo.c:329
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "вказаного редактора (%s) не існує"
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "не знайдено жодного редактора (шлях до редактора = %s)"
+
+#: plugins/sudoers/visudo.c:441 plugins/sudoers/visudo.c:449
+msgid "write error"
+msgstr "помилка запису"
+
+#: plugins/sudoers/visudo.c:495
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "не вдалося обробити stat файл тимчасових даних (%s), %s не змінено"
+
+#: plugins/sudoers/visudo.c:502
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "файл тимчасових даних має нульовий об’єм (%s), %s не змінено"
+
+#: plugins/sudoers/visudo.c:508
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "помилка редактора (%s), %s не змінено"
+
+#: plugins/sudoers/visudo.c:530
+#, c-format
+msgid "%s unchanged"
+msgstr "%s не змінено"
+
+#: plugins/sudoers/visudo.c:589
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "не вдалося повторно відкрити файл тимчасових даних (%s), %s не змінено."
+
+#: plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "не вдалося обробити файл тимчасових даних (%s), невідома помилка"
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "внутрішня помилка, не вдалося знайти %s у списку!"
+
+#: plugins/sudoers/visudo.c:719 plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "не вдалося встановити (uid, gid) %s у значення (%u, %u)"
+
+#: plugins/sudoers/visudo.c:751
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s і %s не перебувають у одній файловій системі, використовуємо mv для перейменування"
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "помилка команди: «%s %s %s», %s не змінено"
+
+#: plugins/sudoers/visudo.c:775
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "помилка перейменування %s, %s не змінено"
+
+#: plugins/sudoers/visudo.c:796
+msgid "What now? "
+msgstr "А зараз що? "
+
+#: plugins/sudoers/visudo.c:810
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Параметри:\n"
+" (e) — повторне редагування файла sudoers\n"
+" (x) — вийти без внесення змін до файла sudoers\n"
+" (Q) — вийти зі збереженням файла sudoers (НЕБЕЗПЕЧНО!)\n"
+
+#: plugins/sudoers/visudo.c:856
+#, c-format
+msgid "unable to run %s"
+msgstr "не вдалося виконати %s"
+
+#: plugins/sudoers/visudo.c:886
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: помилковий власник (uid, gid), має бути (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: помилкові права доступу, режим доступу має бути 0%o\n"
+
+#: plugins/sudoers/visudo.c:950 plugins/sudoers/visudo.c:957
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: вдала обробка\n"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s зайнято, повторіть спробу пізніше"
+
+#: plugins/sudoers/visudo.c:979
+#, c-format
+msgid "unable to lock %s"
+msgstr "не вдалося заблокувати %s"
+
+#: plugins/sudoers/visudo.c:980
+msgid "Edit anyway? [y/N]"
+msgstr "Редагувати попри усе? [y/N]"
+
+#: plugins/sudoers/visudo.c:1064
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Помилка: %s:%d цикл у %s «%s»"
+
+#: plugins/sudoers/visudo.c:1065
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Попередження: %s:%d цикл у %s «%s»"
+
+#: plugins/sudoers/visudo.c:1069
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Помилка: виявлено посилання %s:%d %s «%s», яке не визначено"
+
+#: plugins/sudoers/visudo.c:1070
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Попередження: виявлено посилання %s:%d %s «%s», яке не визначено"
+
+#: plugins/sudoers/visudo.c:1161
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Попердження: %s:%d не використано %s «%s»"
+
+#: plugins/sudoers/visudo.c:1276
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s — безпечне редагування файла sudoers\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1278
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"Параметри:\n"
+" -c, --check режим лише перевірки\n"
+" -f, --file=файл вказати розташування файла sudoers\n"
+" -h, --help показати довідкове повідомлення і завершити роботу\n"
+" -q, --quiet стислі повідомлення щодо синтаксичних помилок\n"
+" -s, --strict строга перевірка синтаксису\n"
+" -V, --version показати дані щодо версії і завершити роботу\n"
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr "занадто високий рівень вкладеності"
diff --git a/plugins/sudoers/po/vi.mo b/plugins/sudoers/po/vi.mo
new file mode 100644
index 0000000..8a1de6a
--- /dev/null
+++ b/plugins/sudoers/po/vi.mo
Binary files differ
diff --git a/plugins/sudoers/po/vi.po b/plugins/sudoers/po/vi.po
new file mode 100644
index 0000000..0cc0095
--- /dev/null
+++ b/plugins/sudoers/po/vi.po
@@ -0,0 +1,2502 @@
+# Vietnamese translation for sudo.
+# Bản dịch tiếng Việt dành cho sudo.
+# This file is put in the public domain.
+# Trần Ngọc Quân <vnwildman@gmail.com>, 2012-2014, 2015, 2016, 2017, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-11-01 14:10+0700\n"
+"Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
+"Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
+"Language: vi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Language-Team-Website: <http://translationproject.org/team/vi.html>\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+"X-Generator: Gtranslator 2.91.7\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "lỗi cú pháp"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "Mật khẩu của %p: "
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] mật khẩu dành cho %p: "
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "Mật khẩu: "
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** Thông tin AN NINH cho %h ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "Rất tiếc, hãy thử lại."
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336
+#: gram.y:399 gram.y:407 gram.y:417 gram.y:450 gram.y:457 gram.y:464
+#: gram.y:471 gram.y:553 gram.y:560 gram.y:569 gram.y:578 gram.y:595
+#: gram.y:707 gram.y:714 gram.y:721 gram.y:729 gram.y:829 gram.y:836
+#: gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890 gram.y:897
+#: gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:195 plugins/sudoers/logging.c:511
+#: plugins/sudoers/logging.c:532 plugins/sudoers/logging.c:573
+#: plugins/sudoers/logging.c:752 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr "không thể cấp phát bộ nhớ"
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr "tóm lược yêu cầu một đối số là tên đường dẫn"
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr "giá trị notbefore không hợp lệ"
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr "giá trị notafter không hợp lệ"
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr "giá trị timeout quá lớn"
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr "giá trị timeout không hợp lệ"
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:354 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:511 plugins/sudoers/logging.c:532
+#: plugins/sudoers/logging.c:572 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:724 plugins/sudoers/match.c:771
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1008
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "Bí danh “%s” đã được định nghĩa rồi"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "không thể lấy lớp đăng nhập cho tài khoản %s"
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr "không thể khởi chạy xác thực kiểu bsd"
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr "kiểu xác thực không hợp lệ"
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr "không thể khởi tạo xác thực kiểu BSD"
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr "tài khoản bạn đã hết hiệu lực"
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr "gặp lỗi khi chấp thuận"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr "không thể đọc cấu hình fwtk"
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr "không thể kết nối tới máy chủ xác thực"
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr "mất kết nối đến máy phục vụ xác thực"
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"lỗi máy phục vụ xác thực:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s: không thể chuyển đổi người ủy nhiệm sang chuỗi (“%s”): %s"
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: không thể phân tích “%s”: %s"
+
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s: không thể phân giải bộ nhớ đệm “credential”: %s"
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s: không thể phân bổ các tùy chọn: %s"
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s: không thể lấy giấy ủy nhiệm: %s"
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s: không thể khởi tạo bộ nhớ đệm “credential”: %s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s: không thể cất giữ “credential” trong bộ nhớ tạm: %s"
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s: không thể lấy tên máy chủ chính: %s"
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s: Không thể thẩm tra TGT! Gần như chắc chắn là bị tấn công!: %s"
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr "không thể khởi tạo PAM"
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "lỗi xác thực PAM: %s"
+
+#: plugins/sudoers/auth/pam.c:221
+msgid "account validation failure, is your account locked?"
+msgstr "xác thực tài khoản gặp lỗi nghiêm trọng, có phải tài khoản của bạn đã bị khóa?"
+
+#: plugins/sudoers/auth/pam.c:229
+msgid "Account or password is expired, reset your password and try again"
+msgstr "Mật khẩu hay tài khoản đã hết hạn sử dụng, hãy đặt lại mật khẩu của bạn và thử lại"
+
+#: plugins/sudoers/auth/pam.c:238
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "không thể thay đổi mật khẩu đã hết hạn: %s"
+
+#: plugins/sudoers/auth/pam.c:246
+msgid "Password expired, contact your system administrator"
+msgstr "Mật khẩu đã hết hạn dùng, hãy liên lạc với người quản trị hệ thống của bạn"
+
+#: plugins/sudoers/auth/pam.c:250
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "Tài khoản hết hạn hoặc cấu hình PAM không có phiên “tài khoản” cho sudo, hãy liên hệ với người quản trị hệ thống của bạn"
+
+#: plugins/sudoers/auth/pam.c:257 plugins/sudoers/auth/pam.c:262
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "lỗi quản lý tài khoảnthực PAM: %s"
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:232
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "bạn không tồn tại trong cơ sở dữ liệu %s"
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr "gặp lỗi khi khởi tạo thư viện “ACE API”"
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr "không thể liên lạc được với máy chủ SecurID"
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr "ID người dùng bị khóa với “SecurID Authentication”"
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr "sai chiều dài tên tài khoản cho SecurID"
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr "sai Bộ Tiếp Hợp Xác Thực cho SecurID"
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr "Truyền thông với SecurID gặp lỗi"
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr "không hiểu lỗi SecurID"
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr "sai chiều dài passcode cho SecurID"
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr "không thể khởi tạo phiên SIA"
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr "Phương thức xác thực không hợp lệ"
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "Phương thức xác thực không hợp lệ được biên dịch vào trong sudo! Bạn không thể pha trộn kiểu xác thực giữa standalone và non-standalone"
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr "chưa có phương thức xác thực"
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Ở đây không có phương thức xác thực nào được dịch vào trong sudo! Nếu bạn muốn tắt xác thực, sử dụng tùy chọn cấu hình --disable-authentication"
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr "Không thể khởi tạo phương thức xác thực."
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr "Phương thức xác thực:"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr "Không thể phân giải điều kiện audit"
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr "không thể chuyển giao bản ghi “audit”"
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"Chúng tôi tin rằng bạn đã nhận được bài giảng từ Quản trị Hệ thống\n"
+"nội bộ. Có thể tóm lược chúng lại thành một số điểm quan trọng sau:\n"
+"\n"
+" #1) Tôn trọng sự riêng tư của người khác.\n"
+" #2) Nghĩ trước khi gõ một lệnh.\n"
+" #3) Quyền lực lớn đi kèm với trách nhiệm lớn.\n"
+"\n"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr "không biết mã số người dùng: %u"
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1136
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr "không biết người dùng: %s"
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "gia tăng thứ tự: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "bắt đầu thứ tự: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr "đệm thứ tự: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s phiên bản %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "Ngữ pháp %s phiên bản %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr "không hỗ trợ định dạng đầu vào %s"
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr "không hỗ trợ định dạng đầu ra %s"
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s: các tập tin đầu vào và đầu ra phải khác nhau"
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:238
+#: plugins/sudoers/visudo.c:594 plugins/sudoers/visudo.c:917
+msgid "unable to initialize sudoers default values"
+msgstr "không thể khởi giá trị mặc định sudoers"
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s: %s: %s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s: không biết từ khóa: %s"
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "kiểu mặc định không hợp lệ: %s"
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "kiểu biểu thức không hợp lệ: %s"
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr "bộ lọc không hợp lệ: %s"
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:913
+#, c-format
+msgid "unable to open %s"
+msgstr "không thể mở “%s”"
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:922
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "gặp lỗi khi phân tích tập tin %s, không rõ bị lỗi gì"
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:939
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "lỗi cú pháp trong %s gần dòng %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:942
+#, c-format
+msgid "parse error in %s\n"
+msgstr "lỗi cú pháp trong %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr "không thể ghi vào %s"
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr "%s - chuyển đổi giữa các định dạng các tập tin sudoers\n"
+
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Options:\n"
+" -b, --base=dn DN cơ sở cho sudo truy vấn LDAP\n"
+" -d, --defaults=deftypes chỉ chuyển đổi mặc định của kiểu đã cho\n"
+" -e, --expand-aliases khai triển bí danh khi chuyển đổi\n"
+" -f, --output-format=format đặt định dạng đầu ra: JSON, LDIF hay sudoers\n"
+" -i, --input-format=format đặt định dạng đầu vào: LDIF hoặc sudoers\n"
+" -I, --increment=số tổng gia tăng cho từng sudoOrder\n"
+" -h, --help hiển thị trợ giúp rồi thoát\n"
+" -m, --match=filter chỉ chuyển đổi những hạng mục khớp bộ lọc\n"
+" -M, --match-local khớp lọc sử dụng cơ sở dữ liệu passwd và group người dùng\n"
+" -o, --output=tập_tin_đầu_ra ghi sudoers đã chuyển đổi sang tập_tin_đầu_ra\n"
+" -O, --order-start=số điểm đầu cho sudoOrder đầu tiên\n"
+" -p, --prune-matches cắt bỏ những người dùng, nhóm và máy không khớp mẫu\n"
+" -P, --padding=số đệm cơ sở cho gia tăng sudoOrder\n"
+" -s, --suppress=sections chặn xuất cho từng phần cụ thể\n"
+" -V, --version hiển thị phiên bản rồi thoát"
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "không hiểu mục tin mặc định “%s”"
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr "không thể lấy giờ quốc tế (GMT)"
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr "không thể định dạng dấu-vết-thời-gian"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1015 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "lỗi nội bộ, %s bị tràn"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr "Quá nhiều mục tin sudoers, tối đa là %u"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "biến môi trường SUDOERS_BASE chưa được đặt và tùy chọn chưa được đưa ra."
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "Trang bị Syslog nếu syslog được sử dụng cho việc ghi nhật ký: %s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "Mức ưu tiên Syslog sẽ sử dụng khi người dùng đăng nhập thành công: %s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "Mức ưu tiên Syslog sẽ sử dụng khi người dùng đăng nhập không thành công: %s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "Đặt nhắc OTP (mật khẩu dùng một lần) tại dòng nó sở hữu"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "Bỏ qua “.” trong biến $PATH"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "Luôn gửi thư mỗi khi chạy lệnh sudo"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "Gửi thư nếu xác thực người dùng gặp lỗi"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "Gửi thư nếu người dùng không ở trong sudoers"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "Gửi thư nếu người dùng không có trong sudoers cho máy chủ này"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "Gửi thư nếu người dùng không được phép chạy lệnh nào đó"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "Gửi thư nếu người cố chạy lệnh nào đó"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "Sử dụng dấu vết thời gian riêng rẽ cho từng cặp tkhoản/tty"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "Hướng dẫn người dùng lần đầu tiên họ chạy lệnh sudo"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "TẬP-TIN chứa thuyết trình về “sudo”: %s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "Yêu cầu người dùng chứng thực theo mặc định"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "Siêu người dùng (root) có thể chạy lệnh sudo"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "Ghi nhật ký tên-máy-chủ vào tập tin nhật ký (không dùng syslog)"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "Ghi nhật ký năm vào tập tin nhật ký (không dùng syslog)"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "Nếu lệnh sudo được triệu gọi mà không đưa ra tham số thì khởi chạy hệ vỏ"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "Đặt biến $HOME cho người dùng đích khi sử dụng hệ vỏ (shell) với tùy chọn -s"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "Luôn đặt biến $HOME cho thư mục cá nhân của người dùng đích"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "Cho phép một số thông tin được thu thập để đưa ra các thông tin về lỗi hữu dụng"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "Yêu cầu tên máy chủ dạng đầy đủ trong tập tin sudoers"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "Lăng mạ người dùng khi họ nhập vào mật khẩu sai"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "Chỉ cho phép người dùng chạy lệnh sudo nếu họ có tty"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo sẽ tôn trọng biến môi trường EDITOR"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "Hỏi mật khẩu của siêu người dùng, chứ không phải của người dùng"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "Nhắc mật khẩu của người dùng runas_mặc_định, không phải của người dùng"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "Nhắc mật khẩu của người dùng đích, không phải cái hiện tại"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "Áp dụng mặc định trong lớp đăng nhập người dùng đích nếu ở đây có một"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "Đặt biến môi trường LOGNAME và USER"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "Chỉ đặt uid đang có hiệu lực cho người dùng đích, không sử dụng uid thật"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "Không khởi tạo véc-tơ nhóm cho người dùng đích"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "Độ dài mà tại đó các dòng trong tập tin nhật ký được ngắt dòng (0 là không ngắt dòng): %u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "Thời gian chờ dấu vết thời gian xác thực tối đa: %.1f phút"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "Thời gian chờ nhắc mật khẩu tối đa: %.1f phút"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "Số lần nhập mật khẩu: %u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "Umask để sử dụng hoặc 0777 để sử dụng của người dùng: 0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "Đường dẫn tới tập tin nhật ký: “%s”"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "Đường dẫn tới chương trình gửi thư (mail) %s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "Các cờ dành cho chương trình gửi thư (mail): %s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "Địa chỉ để gửi thư đến: %s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "Địa chỉ dùng để gửi thư từ: %s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "Chủ đề cho thư: %s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "Mật khẩu không đúng: %s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "Đường dẫn đến thư mục trạng thái thuyết trình: %s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "Đường dẫn thư mục dấu vết thời gian xác thực: %s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "Chủ sở hữu đường dẫn thư mục dấu vết thời gian xác thực: %s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "Những tài khoản trong nhóm này được miễn mật khẩu và yêu cầu PATH: %s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "Lời nhắc nhập mật khẩu mặc định: %s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "Nếu được đặt, lời nhắc mật khẩu sẽ đè lên dấu nhắc hệ thống trong mọi trường hợp."
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "Tài khoản mặc định chạy lệnh như là: %s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "Giá trị dùng để ghi đè lên $PATH của người dùng: %s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "Đường dẫn tới trình biên soạn để sử dụng cho lệnh visudo: %s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "Khi được yêu cầu mật khẩu cho “liệt kê” lệnh-giả: %s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "Khi được yêu cầu mật khẩu cho lệnh-giả “verify” (“thẩm tra”): %s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "Tải trước các hàm thi hành giả được chứa trong thư viện sudo_noexec"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "Nếu thư mục LDAP đã bật, chúng tôi sẽ lờ đi tập tin sudoers phải không"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr "Các bộ mô tả tập tin >= %d sẽ bị đóng trước khi chạy một lệnh"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "Nếu được đặt, người dùng có thể ghi đè lên giá trị của “closefrom” bằng tùy chọn -C"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "Cho phép người dùng đặt biến môi trường tùy ý"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "Đặt lại biến môi trường thành giá trị mặc định của chúng"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "Các biến môi trường được kiểm tra xem có đúng mực không:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "Các biến môi trường bị gỡ bỏ:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "Các biến môi trường được giữ lại:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "Vai trò SELinux được dùng trong ngữ cảnh an ninh mới: %s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "Kiểu SELinux được dùng trong ngữ cảnh an ninh mới: %s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "Đường dẫn tới tập tin môi trường đặc-tả-sudo: %s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "Đường dẫn tới tập tin môi trường đặc-tả-sudo-hạn-chế: %s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "Miền địa phương sẽ sử dụng khi phân tích sudoers: %s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Cho phép sudo hỏi mật khẩu thậm chí ngay cả khi nó đã rõ ràng"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "Cung cấp phản hồi ảo lúc nhắc mật khẩu khi đây là đầu nhập người dùng"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "Sử dụng globbing kiểu nhanh hơn mà nó thì kém chính xác hơn nhưng lại không cần truy cập hệ thống tập tin"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "Giá trị umask được chỉ định trong sudoers sẽ ghi đè lên giá trị này của người dùng, thậm chí nó còn dễ dãi hơn"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "Ghi nhật ký kết xuất từ người dùng cho lệnh đang chạy"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "Ghi lại nhật ký kết xuất của lệnh đang chạy"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "Nén nhật ký V/R sử dụng định dạng zlib"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "Luôn chạy lệnh ở tty-giả"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Phần bổ sung cho hỗ trợ nhóm không-Unix: %s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Thư mục mà nó sẽ lưu nhật ký vào/ra: %s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Tập tin mà nó sẽ lưu nhật ký vào/ra: %s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "Thêm một mục vào tập tin utmp/utmpx khi phân bổ một pty"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "Đặt người dùng trong utmp thành người dùng runasr, không phải người dùng gọi"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "Tập hợp các đặc quyền được phép: %s"
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "Tập hợp các quyền bị giới hạn: %s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "Chạy các câu lệnh trên một pty trong nền hệ thống"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "Tên dịch vụ PAM được dùng: %s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "Tên dịch vụ PAM được dùng cho các hệ vỏ đăng nhập: %s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "Thử thiết lập ủy nhiệm PAM cho người dùng đích"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "Tạo một phiên PAM mới để lệnh chạy với nó"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "Số lượng nhật ký I/O tối đa: %u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "Bật hỗ trợ nhóm-mạng “sudoers”"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "Kiểm tra xem các thư mục cha có ghi được hay không khi sửa các tập tin bằng sudoedit"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "Theo các liên kết mềm khi sửa các tập tin bằng sudoedit"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "Truy vấn các phần bổ sung nhóm cho các nhóm hệ thống chưa biết"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "Khớp nhóm mạng trên cơ sở toàn thể bộ dữ liệu : tài khoản, tên máy và tên miền"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "Cho phép các lệnh có thể chạy ngay cả khi sudo không thể ghi vào nhật ký audit"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "Cho phép các lệnh có thể chạy ngay cả khi sudo không thể ghi vào nhật ký V/R"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "Cho phép các lệnh có thể chạy ngay cả khi sudo không thể ghi vào tập tin nhật ký"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "Phân giải các nhóm trong sudoers và khớp dựa trên mã số nhóm, không phải là tên"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "Các mục tin của nhật ký lớn hơn giá trị này sẽ được chia thành nhiều chuỗi syslog nhỏ: %u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "Người mà sẽ sở hữu tập tin nhật ký V/R: %s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "Nhóm mà sẽ sở hữu tập tin nhật ký V/R: %s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "Chế độ tập tin được dùng cho tập tin nhật ký V/R: 0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "Thực thi các lệnh theo bộ mô tả tập tin thay cho đường dẫn: %s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "Bỏ qua các mục tin Mặc định chưa biết trong sudoers thay vì đưa ra cảnh báo"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "Thời gian theo giây sau đó thì lệnh sẽ bị chấm dứt: %u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "Cho phép người dùng chỉ định thời gian chờ dòng lệnh tối đa"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "Đẩy dữ liệu nhật ký V/R lên đĩa ngay lập tức thay vì nhớ đệm nó"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "Bao gồm mã số tiến trình khi ghi nhật ký thông qua syslog"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "Kiểu của bản ghi dấu vết thời gian xác thực: %s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "Thông tin xác thực gặp lỗi nghiêm trọng: %s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "Bỏ qua HOA/thường khi khớp tên người dùng"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "Bỏ qua HOA/thường khi khớp tên nhóm"
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d không hiểu mục tin mặc định “%s”"
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s: không hiểu mục tin mặc định “%s”"
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d chưa chỉ ra giá trị cho “%s”"
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s: chưa chỉ ra giá trị cho “%s”"
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d giá trị cho “%s” phải bắt đầu bằng dấu “/”"
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s: giá trị cho “%s” phải bắt đầu bằng dấu “/”"
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d tùy chọn “%s” không nhận giá trị"
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s: tùy chọn “%s” không nhận giá trị"
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s:%d kiểu Defaults không hợp lệ 0x%x cho tùy chọn “%s”"
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%s: kiểu Defaults không hợp lệ 0x%x cho tùy chọn “%s”"
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%s:%d giá trị “%s” là không hợp lệ đối với tùy chọn “%s”"
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s: giá trị “%s” là không hợp lệ đối với tùy chọn “%s”"
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv: envp sai hỏng, chiều dài không khớp"
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr "không thể xây dựng lại môi trường"
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "rất tiếc, bạn không được phép đặt các biến môi trường sau đây: %1s"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "lỗi phân tích trong %s gần dòng %d"
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "gặp lỗi phân tích trong %s"
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "không hỗ trợ kiểu tóm lược %d dành cho %s"
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr "%s: lỗi đọc"
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s phải được sở hữu bởi uid %d"
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s phải là những thứ chỉ có thể ghi bởi chủ sở hữu"
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "không thể tải %s: %s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "không tìm thấy ký hiệu “group_plugin” trong %s"
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s: phiên bản số lớn phần bổ sung nhóm không tương thích %d, mong đợi %d"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "không thể phân tích địa chỉ IP \"%s\""
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "không thể phân tích mặt nạ mạng \"%s\""
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr "Cặp địa chỉ IP và mặt nạ cục bộ:\n"
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s có tồn tại nhưng nó không phải là một thư mục (0%o)"
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "không thể tạo thư mục “%s”"
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:723
+#: plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "không thể chuyển đổi chế độ của %s thành 0%o"
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1167
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr "không nhận ra nhóm: %s"
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr "không thể đọc %s"
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr "không thể tạo “%s”"
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "không thể ghi vào tập tin nhật ký V/R: %s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr "%s: lỗi bên trong, tập tin nhật ký vào ra cho sự kiện %d chưa được mở"
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr "%s: lỗi bên trong, tín hiệu %d không hợp lệ"
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s: tập tin nhật ký không hợp lệ"
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s: thiếu trường dấu vết thời gian"
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s: dấu vết thời gian “%s”: %s"
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s: thiếu trường tài khoản người dùng"
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s: thiếu trường “runas user” (chạy với tư cách tài khoản này)"
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s: thiếu trường “runas group” (chạy dưới danh nghĩa nhóm này)"
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr "“starttls” chỉ được hỗ trợ khi dùng với “ldaps”"
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "không thể khởi tạo chứng nhận SSL và csdl khóa: %s"
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "bạn phải đặt TLS_CERT trong %s để sử dụng SSL"
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "không thể khởi tạo LDAP: %s"
+
+#: plugins/sudoers/ldap.c:1648
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "start_tls được chỉ ra nhưng thư viện LDAP không hỗ trợ ldap_start_tls_s() hoặc ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "thuộc tính sudoOrder không hợp lệ: %s"
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports: cổng quá lớn"
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "không hỗ trợ kiểu “LDAP uri”: %s"
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "không thể trộn ldap và ldaps URIs"
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "không thể chuyển đổi sudoOption: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "không thể mở hệ thống audit"
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr "không thể gửi thông tin audit"
+
+#: plugins/sudoers/logging.c:113
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s : %s"
+
+#: plugins/sudoers/logging.c:141
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s : (lệnh tiếp tục) %s"
+
+#: plugins/sudoers/logging.c:170
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "không thể mở tập tin nhật ký: %s"
+
+#: plugins/sudoers/logging.c:178
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "không thể khóa tập tin nhật ký: %s"
+
+#: plugins/sudoers/logging.c:211
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "không thể ghi vào tập tin nhật ký: %s"
+
+#: plugins/sudoers/logging.c:240
+msgid "No user or host"
+msgstr "Không có tài khoản hay tên máy chủ"
+
+#: plugins/sudoers/logging.c:242
+msgid "validation failure"
+msgstr "việc phê chuẩn thất bại"
+
+#: plugins/sudoers/logging.c:249
+msgid "user NOT in sudoers"
+msgstr "tài khoản KHÔNG có trong sudoers"
+
+#: plugins/sudoers/logging.c:251
+msgid "user NOT authorized on host"
+msgstr "tài khoản KHÔNG được cho phép sử dụng trên máy chủ"
+
+#: plugins/sudoers/logging.c:253
+msgid "command not allowed"
+msgstr "lệnh không được phép"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s không trong tập tin sudoers. Sự việc này sẽ được báo cáo.\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s không được phép chạy lệnh sudo trên %s. Sự việc này sẽ được báo cáo.\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "Rất tiếc, tài khoản %s không được chạy lệnh sudo trên %s.\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "Rất tiếc, tài khoản %s không được phép thi hành “%s%s%s” như là %s%s%s trên %s.\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr "%s: không tìm thấy lệnh"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"đang bỏ qua “%s” được tìm thấy trong “.”\n"
+"Sử dụng “sudo ./%s” nếu đây là “%s” bạn muốn chạy."
+
+#: plugins/sudoers/logging.c:354
+msgid "authentication failure"
+msgstr "xác thực gặp lỗi nghiêm trọng"
+
+#: plugins/sudoers/logging.c:380
+msgid "a password is required"
+msgstr "bắt buộc phải có mật khẩu"
+
+#: plugins/sudoers/logging.c:443
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "đã sai mật khẩu %u lần"
+
+#: plugins/sudoers/logging.c:666
+msgid "unable to fork"
+msgstr "không thể tạo tiến trình con"
+
+#: plugins/sudoers/logging.c:674 plugins/sudoers/logging.c:726
+#, c-format
+msgid "unable to fork: %m"
+msgstr "không thể tạo tiến trình con: %m"
+
+#: plugins/sudoers/logging.c:716
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "không thể mở ống dẫn lệnh: %m"
+
+#: plugins/sudoers/logging.c:741
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "không thể dup (nhân đôi) stdin: %m"
+
+#: plugins/sudoers/logging.c:779
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "không thể thực thi %s: %m"
+
+#: plugins/sudoers/match.c:874
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "tóm lược cho %s (%s) không ở dạng thức %s"
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:421 plugins/sudoers/visudo.c:717
+#, c-format
+msgid "unable to stat %s"
+msgstr "không thể lấy thống kê %s"
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"Vai trò LDAP: %s\n"
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Mục Sudoers:\n"
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr " ChạyVớiTưCáchNgườiDùng: "
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr " ChạyVớiTưCáchNhóm: "
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr " Tùy chọn: "
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr " Lệnh:\n"
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "Các mục mặc định khớp cho %s trên máy %s:\n"
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "Runas và Đặc-tả-lệnh mặc định cho %s:\n"
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "Người dùng %s có thể chạy những lệnh sau trên máy %s:\n"
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "Tài khoản %s không được phép thi hành sudo trên %s.\n"
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "bỏ qua giá trị thuộc tính không hợp lệ: %s"
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "bỏ qua sudoRole chưa hoàn thiện: cn: %s"
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "%.*s không hợp lệ đặt bởi ứng dụng chạy phía trước sudo"
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr "không thể phân tích danh sách địa chỉ mạng"
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr "tên người dùng không đặt bởi ứng dụng chạy phía trước sudo"
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr "mã số người dùng không đặt bởi ứng dụng chạy phía trước sudo"
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr "mã số nhóm không đặt bởi ứng dụng chạy phía trước sudo"
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr "tên máy không đặt bởi ứng dụng chạy phía trước sudo"
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:220
+#: plugins/sudoers/visudo.c:851
+#, c-format
+msgid "unable to execute %s"
+msgstr "không thể thực thi %s"
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Phiên bản của phần bổ sung chính sách Sudoers %s\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Phiên bản ngữ pháp tập tin Sudoers %d\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Đường dẫn Sudoers: %s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "đường dẫn nsswitch: %s\n"
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "đường dẫn ldap.conf: %s\n"
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "đường dẫn ldap.secret: %s\n"
+
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "không thể đăng ký móc kiểu %d (phiên bản %d.%d)"
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "không thể lưu nhớ tạm uid %u, hết bộ nhớ rồi"
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "không thể lưu nhớ tạm uid %u, đã có sẵn rồi"
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "không thể lưu nhớ tạm tài khoản %s, hết bộ nhớ rồi"
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "không thể lưu nhớ tạm tài khoản %s, đã có sẵn rồi"
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "không thể lưu nhớ tạm gid %u, đã hết bộ nhớ rồi"
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "không thể lưu nhớ tạm gid %u, đã có sẵn rồi"
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "không thể lưu nhớ tạm nhóm %s, đã hết bộ nhớ rồi"
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "không thể lưu nhớ tạm nhóm %s, đã có sẵn rồi"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "không thể lưu nhớ tạm danh sách nhóm cho %s, đã có sẵn rồi"
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "không thể lưu nhớ tạm danh sách nhóm cho %s, đã hết bộ nhớ rồi"
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "không thể phân tích nhóm cho %s"
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "không thể phân tích mã số nhóm cho %s"
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr "ngăn xếp perm bị tràn"
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr "ngăn xếp stack tràn ngầm"
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr "không thể thay đổi mã số nhóm của siêu người dùng root"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr "không thể thay đổi thành runas gid"
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr "không thể đặt véc-tơ nhóm runas"
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr "không thể thay đổi thành runas uid"
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr "không thể thay đổi thành mã số nhóm sudoers"
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr "quá nhiều tiến trình"
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr "không thể lấy thư mục làm việc hiện tại"
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "đã cắt ngắn đường dẫn audit user_cmnd: %s"
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "đã cắt ngắn đường dẫn audit argv[0]: %s"
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr "thông điệp audit_failure quá dài"
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "không thể khởi tạo nguồn SSS. SSSD đã được cài đặt trên máy của bạn chưa vậy?"
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "không thể tìm thấy ký hiệu “%s” trong %s"
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr "trục trặc với các mục mặc định"
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr "không có người dùng hợp lệ nào được tìm thấy, đang thoát ra"
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers đã ghi rõ là siêu người dùng (root) không được phép chạy sudo"
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr "bạn không được phép sử dụng tùy chọn -C"
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "người sở hữu dấu vết thời gian (%s): Không có người dùng nào như vậy"
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr "không có tty"
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr "rất tiếc, bạn phải có tty mới có thể chạy sudo"
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr "lệnh trong thư mục hiện hành"
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "rất tiếc, bạn không được phép đặt thời gian chờ lệnh tối đa"
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "rất tiếc, bạn không được phép giữ lại môi trường"
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr "lệnh quá dài"
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s không phải tập tin thường"
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s được sở hữu bởi người dùng mang mã số %u, nên là %u"
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr "%s ai ghi cũng được"
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s được sở hữu bởi nhóm mang mã số %u, nên là %u"
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "chỉ có siêu người dùng (root) mới có thể sử dụng “-c %s”"
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr "không rõ lớp đăng nhập: %s"
+
+#: plugins/sudoers/sudoers.c:1069 plugins/sudoers/sudoers.c:1083
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "không thể phân giải địa chỉ của máy %s"
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "tùy chọn lọc không hợp lệ: %s"
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "thời gian chờ tối đa không hợp lệ: %s"
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "sai hệ số nhân tốc độ: %s"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/thời-gian: %s"
+
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/thời-gian: %s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "Đang chạy lại phiên sudo: %s"
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr "không thể thêm sự kiện vào hàng đợi"
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr "không thể đặt thiết bị tty chế độ thô (raw)"
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "Cảnh báo: thiết bị cuối quá nhỏ để có thể chạy nhật ký một cách đúng đắn.\n"
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "Định dạng của nhật ký là %d x %d, định dạng của thiết bị cuối là %d x %d."
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "Trình diễn lại đã kết thúc, vui lòng bấm một phím bất kỳ để hoàn lại thiết bị cuối."
+
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "sai dòng ghi thời gian trong tập tin: %s"
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "biểu thức không rõ ràng “%s”"
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr "thiếu “)” trong biểu thức"
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "không hiểu giới hạn tìm kiếm “%s”"
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s yêu cầu một đối số"
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "biểu thức chính quy không hợp lệ: %s"
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "không thể phân tích ngày tháng “%s”"
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr "thiếu “(” trong biểu thức"
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr "thừa “or” ở cuối"
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr "thừa “!” ở cuối"
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr "không hiểu kiểu tìm kiếm “%d”"
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr "cách dùng: %s [-hnRS] [-d thư-mục] [-m số] [-s số] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "cách dùng: %s [-h] [-d th.mục] -l [biểu thức tìm kiếm]\n"
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - chạy lại nhật ký phiên sudo\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"Tùy chọn:\n"
+" -d, --directory=th.mục chỉ định thư mục cho nhật ký phiên\n"
+" -f, --filter=bộ-lọc chỉ định kiểu V/R để hiển thị\n"
+" -h, --help hiển thị thông tin trợ giúp rồi thoát\n"
+" -l, --list liệt kê ID phiên sẵn có, với biểu thức tùy chọn\n"
+" -m, --max-wait=sô số giây tối đa sẽ chờ giữa hai sự kiện\n"
+" -S, --suspend-wait chờ trong khi lệnh bị treo\n"
+" -s, --speed=số tăng hoặc giảm tốc độ kết xuất\n"
+" -V, --version hiển thị thông tin về phiên bản rồi thoát"
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr "\tmáy chủ không khớp"
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"Lệnh được phép"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"Lệnh bị cấm"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"Lệnh không khớp"
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr "%s là người cùng nhóm được ghi"
+
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "không thể cắt ngắn tập tin dấu-vết-thời-gian thành %lld byte"
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:482 plugins/sudoers/visudo.c:488
+msgid "unable to read the clock"
+msgstr "không thể đọc khóa"
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr "bỏ qua dấu vết thời gian nằm ở thì tương lai"
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "dấu vết thời gian nằm ở thì tương lai: %20.20s"
+
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "không thể khóa tập tin dấu-vết-thời-gian %s"
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "đường dẫn đến thư mục thuyết trình quá dài: %s/%s"
+
+#: plugins/sudoers/visudo.c:216
+msgid "the -x option will be removed in a future release"
+msgstr "tùy chọn -x sẽ bị xóa bỏ trong tương lai"
+
+#: plugins/sudoers/visudo.c:217
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "vui lòng cân nhắc sử dụng tiện ích cvtsudoers để thay thế"
+
+#: plugins/sudoers/visudo.c:268 plugins/sudoers/visudo.c:650
+#, c-format
+msgid "press return to edit %s: "
+msgstr "bấm phím <Enter> để trở về chỉnh sửa %s:"
+
+#: plugins/sudoers/visudo.c:329
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "trình biên soạn đã chỉ ra (%s) không tồn tại"
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "không tìm thấy trình biên soạn (đường dẫn của nó = %s)"
+
+#: plugins/sudoers/visudo.c:441 plugins/sudoers/visudo.c:449
+msgid "write error"
+msgstr "lỗi ghi"
+
+#: plugins/sudoers/visudo.c:495
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "không thể lấy thống kê tập tin tạm (%s), %s không thay đổi gì."
+
+#: plugins/sudoers/visudo.c:502
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "tập tin tạm (%s) có kích cỡ bằng không, %s không thay đổi gì"
+
+#: plugins/sudoers/visudo.c:508
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "trình biên soạn (%s) gặp lỗi, %s không thay đổi gì"
+
+#: plugins/sudoers/visudo.c:530
+#, c-format
+msgid "%s unchanged"
+msgstr "%s không thay đổi"
+
+#: plugins/sudoers/visudo.c:589
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "không thể mở lại tập tin tạm (%s), %s không thay đổi gì."
+
+#: plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "không thể phân tích tập tin tạm (%s), lỗi chưa được biết"
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "lỗi hệ thống, không thể tìm thấy %s trong danh sách!"
+
+#: plugins/sudoers/visudo.c:719 plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "không thể đặt (uid, gid) của %s thành (%u, %u)"
+
+#: plugins/sudoers/visudo.c:751
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s và %s không ở trên cùng một hệ thống tập tin, sử dụng lệnh mv để đổi tên"
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "thực hiện lệnh gặp lỗi: “%s %s %s”, %s không thay đổi"
+
+#: plugins/sudoers/visudo.c:775
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "gặp lỗi khi đổi tên %s, %s không thay đổi"
+
+#: plugins/sudoers/visudo.c:796
+msgid "What now? "
+msgstr "Vậy làm gì bây giờ? "
+
+#: plugins/sudoers/visudo.c:810
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"Các tùy chọn là:\n"
+" (e) sửa lại tập tin sudoers\n"
+" (x) thoát ra mà không ghi lại tập tin sudoerse\n"
+" (q) thoát ra và ghi lại tập tin sudoers (NGUY HIỂM!)\n"
+
+#: plugins/sudoers/visudo.c:856
+#, c-format
+msgid "unable to run %s"
+msgstr "không thể chạy %s"
+
+#: plugins/sudoers/visudo.c:886
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s: sai sở hữu (uid, gid) đáng lẽ là (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s: phân quyền sai, phải ở chế độ 0%o\n"
+
+#: plugins/sudoers/visudo.c:950 plugins/sudoers/visudo.c:957
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s: vượt qua kiểm duyệt\n"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s đang bận, hãy thử lại sau"
+
+#: plugins/sudoers/visudo.c:979
+#, c-format
+msgid "unable to lock %s"
+msgstr "không thể khóa %s"
+
+#: plugins/sudoers/visudo.c:980
+msgid "Edit anyway? [y/N]"
+msgstr "Vẫn sửa? (có/KHÔNG) [y/N]"
+
+#: plugins/sudoers/visudo.c:1064
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "Lỗi: %s:%d bị quẩn tròn trong %s “%s”"
+
+#: plugins/sudoers/visudo.c:1065
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "Cảnh báo: %s:%d bị quẩn tròn trong %s “%s”"
+
+#: plugins/sudoers/visudo.c:1069
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Lỗi: %s:%d %s “%s” được tham chiếu nhưng chưa được định nghĩa"
+
+#: plugins/sudoers/visudo.c:1070
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "Cảnh báo: %s:%d %s “%s” được tham chiếu nhưng chưa được định nghĩa"
+
+#: plugins/sudoers/visudo.c:1161
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "Cảnh báo: %s:%d không dùng %s “%s”"
+
+#: plugins/sudoers/visudo.c:1276
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - sửa tập tin sudoers một cách an toàn\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1278
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"Các tùy chọn:\n"
+" -c, --check chế độ chỉ kiểm tra\n"
+" -f, --file=tập-tin chỉ định vị trí tập tin sudoers\n"
+" -h, --help hiển thị thông tin trợ giúp rồi thoát\n"
+" -q, --quiet tối thiểu hóa các thông tin (quiet: im lặng)\n"
+" -s, --strict kiểm tra cú pháp ngặt nghèo\n"
+" -V, --version hiển thị thông tin về phiên bản rồi thoát\n"
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr "quá nhiều cấp bao gồm (include)"
+
+#~ msgid ""
+#~ "\n"
+#~ "LDAP Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Vai trò LDAP: KHÔNG HIỂU\n"
+
+#~ msgid " Order: %s\n"
+#~ msgstr " Thứ tự: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: %s\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Vai trò SSSD: %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Vai trò SSSD: KHÔNG HIỂU\n"
+
+#~ msgid "Warning: cycle in %s `%s'"
+#~ msgstr "Cảnh báo: quẩn tròn trong %s “%s”"
+
+#~ msgid "Warning: %s `%s' referenced but not defined"
+#~ msgstr "Cảnh báo: %s “%s” được tham chiếu nhưng chưa được định nghĩa"
+
+#~ msgid "Warning: unused %s `%s'"
+#~ msgstr "Cảnh báo: chưa được dùng %s “%s”"
+
+#~ msgid "unable allocate memory"
+#~ msgstr "không thể cấp phát bộ nhớ"
+
+#~ msgid "timestamp path too long: %s/%s"
+#~ msgstr "đường dẫn dấu vết thời gian quá dài: %s/%s"
+
+#~ msgid "unable to stat editor (%s)"
+#~ msgstr "không thể lấy thống kê trình biên soạn (%s)"
+
+#~ msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+#~ msgstr "sudo_ldap_conf_add_ports: hết bộ nhớ để mở rộng hostbuf"
+
+#~ msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+#~ msgstr "sudo_ldap_parse_uri: hết bộ nhớ để biên dịch “hostbuf”"
+
+#~ msgid "sudo_ldap_build_pass1 allocation mismatch"
+#~ msgstr "sudo_ldap_build_pass1 phân bổ không khớp"
+
+#~ msgid "Password:"
+#~ msgstr "Mật khẩu:"
+
+#~ msgid "internal error: insufficient space for log line"
+#~ msgstr "lỗi nội bộ: thiếu khoảng trống cho dòng ghi nhật ký"
+
+#~ msgid "fill_args: buffer overflow"
+#~ msgstr "fill_args: bộ đệm bị tràn"
+
+#~ msgid "%s owned by uid %u, should be uid %u"
+#~ msgstr "%s được sở hữu bởi uid %u, nên là %u"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0700"
+#~ msgstr "%s có thể được ghi bởi người không sở hữu nó (0%o), cần đặt chế độ 0700"
+
+#~ msgid "%s exists but is not a regular file (0%o)"
+#~ msgstr "%s đã sẵn có nhưng không phải là một tập tin bình thường (0%o)"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0600"
+#~ msgstr "%s có thể được ghi bởi người không sở hữu nó (0%o), cần đặt chế độ 0600"
+
+#~ msgid "unable to remove %s, will reset to the Unix epoch"
+#~ msgstr "không thể gỡ bỏ %s, sẽ đặt lại thành thời điểm bắt đầu kiểu Unix"
+
+#~ msgid "unable to reset %s to the Unix epoch"
+#~ msgstr "không thể đặt lại %s thành thời điểm bắt đầu kiểu Unix"
+
+#~ msgid "value out of range"
+#~ msgstr "giá trị nằm ngoài phạm vi"
+
+#~ msgid "invalid uri: %s"
+#~ msgstr "URI không hợp lệ: %s"
+
+#~ msgid "unable to mix ldaps and starttls"
+#~ msgstr "không thể trộn ldaps và starttls"
+
+#~ msgid "writing to standard output"
+#~ msgstr "ghi vào đầu ra tiêu chuẩn"
+
+#~ msgid "too many parenthesized expressions, max %d"
+#~ msgstr "có quá nhiều biểu thức trong dấu ngoặc đơn, tối đa là %d"
+
+#~ msgid "unable to setup authentication"
+#~ msgstr "không thể cài đặt xác thực"
+
+#~ msgid "getaudit: failed"
+#~ msgstr "getaudit: gặp lỗi"
+
+#~ msgid "getauid: failed"
+#~ msgstr "getauid: gặp lỗi"
+
+#~ msgid "au_to_subject: failed"
+#~ msgstr "au_to_subject: gặp lỗi"
+
+#~ msgid "au_to_exec_args: failed"
+#~ msgstr "au_to_exec_args: gặp lỗi"
+
+#~ msgid "au_to_return32: failed"
+#~ msgstr "au_to_return32: gặp lỗi"
+
+#~ msgid "au_to_text: failed"
+#~ msgstr "au_to_text: gặp lỗi"
+
+#~ msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
+#~ msgstr "nanosleep: tv_sec %ld, tv_nsec %ld"
+
+#~ msgid "pam_chauthtok: %s"
+#~ msgstr "pam_chauthtok: %s"
+
+#~ msgid "pam_authenticate: %s"
+#~ msgstr "pam_authenticate: %s"
+
+#~ msgid "getauid failed"
+#~ msgstr "getauid gặp lỗi"
+
+#~ msgid "Unable to dlopen %s: %s"
+#~ msgstr "Không thể dlopen %s: %s"
+
+#~ msgid "invalid regex: %s"
+#~ msgstr "biểu thức chính quy không hợp lệ: %s"
+
+#~ msgid ">>> %s: %s near line %d <<<"
+#~ msgstr ">>> %s: %s gần dòng %d <<<"
+
+#~ msgid "unable to set locale to \"%s\", using \"C\""
+#~ msgstr "không thể đặt địa phương thành “%s”, sẽ dùng “C”"
+
+#~ msgid ""
+#~ " Commands:\n"
+#~ "\t"
+#~ msgstr ""
+#~ " Lệnh:\n"
+#~ "\t"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "unable to cache uid %u (%s), already exists"
+#~ msgstr "không thể lưu nhớ tạm uid %u (%s), đã có sẵn rồi"
+
+#~ msgid "unable to cache gid %u (%s), already exists"
+#~ msgstr "không thể lưu nhớ tạm gid %u (%s), đã có sẵn rồi"
+
+#~ msgid "unable to execute %s: %s"
+#~ msgstr "không thể thực thi %s: %s"
diff --git a/plugins/sudoers/po/zh_CN.mo b/plugins/sudoers/po/zh_CN.mo
new file mode 100644
index 0000000..73a44ed
--- /dev/null
+++ b/plugins/sudoers/po/zh_CN.mo
Binary files differ
diff --git a/plugins/sudoers/po/zh_CN.po b/plugins/sudoers/po/zh_CN.po
new file mode 100644
index 0000000..cad59f9
--- /dev/null
+++ b/plugins/sudoers/po/zh_CN.po
@@ -0,0 +1,2549 @@
+# Chinese simplified translation for sudoers.
+# This file is put in the public domain.
+# Wylmer Wang <wantinghard@gmail.com>, 2011-2018
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudoers 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-11-05 09:13+0800\n"
+"Last-Translator: Wylmer Wang <wantinghard@gmail.com>\n"
+"Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: confstr.sh:1
+msgid "syntax error"
+msgstr "语法错误"
+
+#: confstr.sh:2
+msgid "%p's password: "
+msgstr "%p 的密码:"
+
+#: confstr.sh:3
+msgid "[sudo] password for %p: "
+msgstr "[sudo] %p 的密码:"
+
+#: confstr.sh:4
+msgid "Password: "
+msgstr "密码:"
+
+#: confstr.sh:5
+msgid "*** SECURITY information for %h ***"
+msgstr "*** %h 安全信息 ***"
+
+#: confstr.sh:6
+msgid "Sorry, try again."
+msgstr "对不起,请重试。"
+
+#: gram.y:192 gram.y:240 gram.y:247 gram.y:254 gram.y:261 gram.y:268
+#: gram.y:284 gram.y:308 gram.y:315 gram.y:322 gram.y:329 gram.y:336
+#: gram.y:399 gram.y:407 gram.y:417 gram.y:450 gram.y:457 gram.y:464
+#: gram.y:471 gram.y:553 gram.y:560 gram.y:569 gram.y:578 gram.y:595
+#: gram.y:707 gram.y:714 gram.y:721 gram.y:729 gram.y:829 gram.y:836
+#: gram.y:843 gram.y:850 gram.y:857 gram.y:883 gram.y:890 gram.y:897
+#: gram.y:1020 gram.y:1294 plugins/sudoers/alias.c:130
+#: plugins/sudoers/alias.c:137 plugins/sudoers/alias.c:153
+#: plugins/sudoers/auth/bsdauth.c:146 plugins/sudoers/auth/kerb5.c:121
+#: plugins/sudoers/auth/kerb5.c:147 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/auth/sia.c:62
+#: plugins/sudoers/cvtsudoers.c:123 plugins/sudoers/cvtsudoers.c:164
+#: plugins/sudoers/cvtsudoers.c:181 plugins/sudoers/cvtsudoers.c:192
+#: plugins/sudoers/cvtsudoers.c:304 plugins/sudoers/cvtsudoers.c:432
+#: plugins/sudoers/cvtsudoers.c:565 plugins/sudoers/cvtsudoers.c:582
+#: plugins/sudoers/cvtsudoers.c:645 plugins/sudoers/cvtsudoers.c:760
+#: plugins/sudoers/cvtsudoers.c:768 plugins/sudoers/cvtsudoers.c:1178
+#: plugins/sudoers/cvtsudoers.c:1182 plugins/sudoers/cvtsudoers.c:1284
+#: plugins/sudoers/cvtsudoers_ldif.c:152 plugins/sudoers/cvtsudoers_ldif.c:195
+#: plugins/sudoers/cvtsudoers_ldif.c:242 plugins/sudoers/cvtsudoers_ldif.c:261
+#: plugins/sudoers/cvtsudoers_ldif.c:332 plugins/sudoers/cvtsudoers_ldif.c:387
+#: plugins/sudoers/cvtsudoers_ldif.c:395 plugins/sudoers/cvtsudoers_ldif.c:412
+#: plugins/sudoers/cvtsudoers_ldif.c:421 plugins/sudoers/cvtsudoers_ldif.c:568
+#: plugins/sudoers/defaults.c:661 plugins/sudoers/defaults.c:954
+#: plugins/sudoers/defaults.c:1125 plugins/sudoers/editor.c:70
+#: plugins/sudoers/editor.c:88 plugins/sudoers/editor.c:99
+#: plugins/sudoers/env.c:247 plugins/sudoers/filedigest.c:64
+#: plugins/sudoers/filedigest.c:80 plugins/sudoers/gc.c:57
+#: plugins/sudoers/group_plugin.c:136 plugins/sudoers/interfaces.c:76
+#: plugins/sudoers/iolog.c:939 plugins/sudoers/iolog_path.c:172
+#: plugins/sudoers/iolog_util.c:83 plugins/sudoers/iolog_util.c:122
+#: plugins/sudoers/iolog_util.c:131 plugins/sudoers/iolog_util.c:141
+#: plugins/sudoers/iolog_util.c:149 plugins/sudoers/iolog_util.c:153
+#: plugins/sudoers/ldap.c:183 plugins/sudoers/ldap.c:414
+#: plugins/sudoers/ldap.c:418 plugins/sudoers/ldap.c:430
+#: plugins/sudoers/ldap.c:721 plugins/sudoers/ldap.c:885
+#: plugins/sudoers/ldap.c:1233 plugins/sudoers/ldap.c:1660
+#: plugins/sudoers/ldap.c:1697 plugins/sudoers/ldap.c:1778
+#: plugins/sudoers/ldap.c:1913 plugins/sudoers/ldap.c:2014
+#: plugins/sudoers/ldap.c:2030 plugins/sudoers/ldap_conf.c:221
+#: plugins/sudoers/ldap_conf.c:252 plugins/sudoers/ldap_conf.c:304
+#: plugins/sudoers/ldap_conf.c:340 plugins/sudoers/ldap_conf.c:443
+#: plugins/sudoers/ldap_conf.c:458 plugins/sudoers/ldap_conf.c:555
+#: plugins/sudoers/ldap_conf.c:588 plugins/sudoers/ldap_conf.c:680
+#: plugins/sudoers/ldap_conf.c:762 plugins/sudoers/ldap_util.c:508
+#: plugins/sudoers/ldap_util.c:564 plugins/sudoers/linux_audit.c:81
+#: plugins/sudoers/logging.c:195 plugins/sudoers/logging.c:511
+#: plugins/sudoers/logging.c:532 plugins/sudoers/logging.c:573
+#: plugins/sudoers/logging.c:752 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:725 plugins/sudoers/match.c:772
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1009
+#: plugins/sudoers/parse.c:195 plugins/sudoers/parse.c:207
+#: plugins/sudoers/parse.c:222 plugins/sudoers/parse.c:234
+#: plugins/sudoers/parse_ldif.c:141 plugins/sudoers/parse_ldif.c:168
+#: plugins/sudoers/parse_ldif.c:237 plugins/sudoers/parse_ldif.c:244
+#: plugins/sudoers/parse_ldif.c:249 plugins/sudoers/parse_ldif.c:325
+#: plugins/sudoers/parse_ldif.c:336 plugins/sudoers/parse_ldif.c:342
+#: plugins/sudoers/parse_ldif.c:367 plugins/sudoers/parse_ldif.c:379
+#: plugins/sudoers/parse_ldif.c:383 plugins/sudoers/parse_ldif.c:397
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:594
+#: plugins/sudoers/parse_ldif.c:619 plugins/sudoers/parse_ldif.c:679
+#: plugins/sudoers/parse_ldif.c:698 plugins/sudoers/parse_ldif.c:744
+#: plugins/sudoers/parse_ldif.c:754 plugins/sudoers/policy.c:502
+#: plugins/sudoers/policy.c:744 plugins/sudoers/prompt.c:98
+#: plugins/sudoers/pwutil.c:197 plugins/sudoers/pwutil.c:269
+#: plugins/sudoers/pwutil.c:346 plugins/sudoers/pwutil.c:520
+#: plugins/sudoers/pwutil.c:586 plugins/sudoers/pwutil.c:656
+#: plugins/sudoers/pwutil.c:814 plugins/sudoers/pwutil.c:871
+#: plugins/sudoers/pwutil.c:916 plugins/sudoers/pwutil.c:974
+#: plugins/sudoers/sssd.c:152 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:112 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+msgid "unable to allocate memory"
+msgstr "无法分配内存"
+
+#: gram.y:482
+msgid "a digest requires a path name"
+msgstr "摘要需要路径参数"
+
+#: gram.y:608
+msgid "invalid notbefore value"
+msgstr "无效的 notbefore 值"
+
+#: gram.y:616
+msgid "invalid notafter value"
+msgstr "无效的 notafter 值"
+
+#: gram.y:625 plugins/sudoers/policy.c:318
+msgid "timeout value too large"
+msgstr "超时值过大"
+
+#: gram.y:627 plugins/sudoers/policy.c:320
+msgid "invalid timeout value"
+msgstr "无效的超时值"
+
+#: gram.y:1294 plugins/sudoers/auth/pam.c:354 plugins/sudoers/auth/pam.c:524
+#: plugins/sudoers/auth/rfc1938.c:114 plugins/sudoers/cvtsudoers.c:123
+#: plugins/sudoers/cvtsudoers.c:163 plugins/sudoers/cvtsudoers.c:180
+#: plugins/sudoers/cvtsudoers.c:191 plugins/sudoers/cvtsudoers.c:303
+#: plugins/sudoers/cvtsudoers.c:431 plugins/sudoers/cvtsudoers.c:564
+#: plugins/sudoers/cvtsudoers.c:581 plugins/sudoers/cvtsudoers.c:645
+#: plugins/sudoers/cvtsudoers.c:760 plugins/sudoers/cvtsudoers.c:767
+#: plugins/sudoers/cvtsudoers.c:1178 plugins/sudoers/cvtsudoers.c:1182
+#: plugins/sudoers/cvtsudoers.c:1284 plugins/sudoers/cvtsudoers_ldif.c:151
+#: plugins/sudoers/cvtsudoers_ldif.c:194 plugins/sudoers/cvtsudoers_ldif.c:241
+#: plugins/sudoers/cvtsudoers_ldif.c:260 plugins/sudoers/cvtsudoers_ldif.c:331
+#: plugins/sudoers/cvtsudoers_ldif.c:386 plugins/sudoers/cvtsudoers_ldif.c:394
+#: plugins/sudoers/cvtsudoers_ldif.c:411 plugins/sudoers/cvtsudoers_ldif.c:420
+#: plugins/sudoers/cvtsudoers_ldif.c:567 plugins/sudoers/defaults.c:661
+#: plugins/sudoers/defaults.c:954 plugins/sudoers/defaults.c:1125
+#: plugins/sudoers/editor.c:70 plugins/sudoers/editor.c:88
+#: plugins/sudoers/editor.c:99 plugins/sudoers/env.c:247
+#: plugins/sudoers/filedigest.c:64 plugins/sudoers/filedigest.c:80
+#: plugins/sudoers/gc.c:57 plugins/sudoers/group_plugin.c:136
+#: plugins/sudoers/interfaces.c:76 plugins/sudoers/iolog.c:939
+#: plugins/sudoers/iolog_path.c:172 plugins/sudoers/iolog_util.c:83
+#: plugins/sudoers/iolog_util.c:122 plugins/sudoers/iolog_util.c:131
+#: plugins/sudoers/iolog_util.c:141 plugins/sudoers/iolog_util.c:149
+#: plugins/sudoers/iolog_util.c:153 plugins/sudoers/ldap.c:183
+#: plugins/sudoers/ldap.c:414 plugins/sudoers/ldap.c:418
+#: plugins/sudoers/ldap.c:430 plugins/sudoers/ldap.c:721
+#: plugins/sudoers/ldap.c:885 plugins/sudoers/ldap.c:1233
+#: plugins/sudoers/ldap.c:1660 plugins/sudoers/ldap.c:1697
+#: plugins/sudoers/ldap.c:1778 plugins/sudoers/ldap.c:1913
+#: plugins/sudoers/ldap.c:2014 plugins/sudoers/ldap.c:2030
+#: plugins/sudoers/ldap_conf.c:221 plugins/sudoers/ldap_conf.c:252
+#: plugins/sudoers/ldap_conf.c:304 plugins/sudoers/ldap_conf.c:340
+#: plugins/sudoers/ldap_conf.c:443 plugins/sudoers/ldap_conf.c:458
+#: plugins/sudoers/ldap_conf.c:555 plugins/sudoers/ldap_conf.c:588
+#: plugins/sudoers/ldap_conf.c:679 plugins/sudoers/ldap_conf.c:762
+#: plugins/sudoers/ldap_util.c:508 plugins/sudoers/ldap_util.c:564
+#: plugins/sudoers/linux_audit.c:81 plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:511 plugins/sudoers/logging.c:532
+#: plugins/sudoers/logging.c:572 plugins/sudoers/logging.c:1010
+#: plugins/sudoers/match.c:724 plugins/sudoers/match.c:771
+#: plugins/sudoers/match.c:813 plugins/sudoers/match.c:841
+#: plugins/sudoers/match.c:929 plugins/sudoers/match.c:1008
+#: plugins/sudoers/parse.c:194 plugins/sudoers/parse.c:206
+#: plugins/sudoers/parse.c:221 plugins/sudoers/parse.c:233
+#: plugins/sudoers/parse_ldif.c:140 plugins/sudoers/parse_ldif.c:167
+#: plugins/sudoers/parse_ldif.c:236 plugins/sudoers/parse_ldif.c:243
+#: plugins/sudoers/parse_ldif.c:248 plugins/sudoers/parse_ldif.c:324
+#: plugins/sudoers/parse_ldif.c:335 plugins/sudoers/parse_ldif.c:341
+#: plugins/sudoers/parse_ldif.c:366 plugins/sudoers/parse_ldif.c:378
+#: plugins/sudoers/parse_ldif.c:382 plugins/sudoers/parse_ldif.c:396
+#: plugins/sudoers/parse_ldif.c:564 plugins/sudoers/parse_ldif.c:593
+#: plugins/sudoers/parse_ldif.c:618 plugins/sudoers/parse_ldif.c:678
+#: plugins/sudoers/parse_ldif.c:697 plugins/sudoers/parse_ldif.c:743
+#: plugins/sudoers/parse_ldif.c:753 plugins/sudoers/policy.c:132
+#: plugins/sudoers/policy.c:141 plugins/sudoers/policy.c:150
+#: plugins/sudoers/policy.c:176 plugins/sudoers/policy.c:303
+#: plugins/sudoers/policy.c:318 plugins/sudoers/policy.c:320
+#: plugins/sudoers/policy.c:346 plugins/sudoers/policy.c:356
+#: plugins/sudoers/policy.c:400 plugins/sudoers/policy.c:410
+#: plugins/sudoers/policy.c:419 plugins/sudoers/policy.c:428
+#: plugins/sudoers/policy.c:502 plugins/sudoers/policy.c:744
+#: plugins/sudoers/prompt.c:98 plugins/sudoers/pwutil.c:197
+#: plugins/sudoers/pwutil.c:269 plugins/sudoers/pwutil.c:346
+#: plugins/sudoers/pwutil.c:520 plugins/sudoers/pwutil.c:586
+#: plugins/sudoers/pwutil.c:656 plugins/sudoers/pwutil.c:814
+#: plugins/sudoers/pwutil.c:871 plugins/sudoers/pwutil.c:916
+#: plugins/sudoers/pwutil.c:974 plugins/sudoers/set_perms.c:392
+#: plugins/sudoers/set_perms.c:771 plugins/sudoers/set_perms.c:1155
+#: plugins/sudoers/set_perms.c:1481 plugins/sudoers/set_perms.c:1646
+#: plugins/sudoers/sssd.c:151 plugins/sudoers/sssd.c:398
+#: plugins/sudoers/sssd.c:461 plugins/sudoers/sssd.c:505
+#: plugins/sudoers/sssd.c:552 plugins/sudoers/sssd.c:743
+#: plugins/sudoers/stubs.c:101 plugins/sudoers/stubs.c:109
+#: plugins/sudoers/sudoers.c:269 plugins/sudoers/sudoers.c:279
+#: plugins/sudoers/sudoers.c:288 plugins/sudoers/sudoers.c:330
+#: plugins/sudoers/sudoers.c:653 plugins/sudoers/sudoers.c:779
+#: plugins/sudoers/sudoers.c:823 plugins/sudoers/sudoers.c:1097
+#: plugins/sudoers/sudoers_debug.c:111 plugins/sudoers/sudoreplay.c:579
+#: plugins/sudoers/sudoreplay.c:582 plugins/sudoers/sudoreplay.c:1259
+#: plugins/sudoers/sudoreplay.c:1459 plugins/sudoers/sudoreplay.c:1463
+#: plugins/sudoers/testsudoers.c:134 plugins/sudoers/testsudoers.c:234
+#: plugins/sudoers/testsudoers.c:251 plugins/sudoers/testsudoers.c:585
+#: plugins/sudoers/timestamp.c:437 plugins/sudoers/timestamp.c:481
+#: plugins/sudoers/timestamp.c:958 plugins/sudoers/toke_util.c:57
+#: plugins/sudoers/toke_util.c:110 plugins/sudoers/toke_util.c:147
+#: plugins/sudoers/tsdump.c:128 plugins/sudoers/visudo.c:150
+#: plugins/sudoers/visudo.c:312 plugins/sudoers/visudo.c:318
+#: plugins/sudoers/visudo.c:428 plugins/sudoers/visudo.c:606
+#: plugins/sudoers/visudo.c:926 plugins/sudoers/visudo.c:1013
+#: plugins/sudoers/visudo.c:1102 toke.l:844 toke.l:945 toke.l:1102
+#, c-format
+msgid "%s: %s"
+msgstr "%s:%s"
+
+#: plugins/sudoers/alias.c:148
+#, c-format
+msgid "Alias \"%s\" already defined"
+msgstr "别名“%s”已定义过"
+
+#: plugins/sudoers/auth/bsdauth.c:73
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "无法获取用户 %s 的登录类别(login class)"
+
+#: plugins/sudoers/auth/bsdauth.c:78
+msgid "unable to begin bsd authentication"
+msgstr "无法开始 bsd 认证"
+
+#: plugins/sudoers/auth/bsdauth.c:86
+msgid "invalid authentication type"
+msgstr "无效的认证类型"
+
+#: plugins/sudoers/auth/bsdauth.c:95
+msgid "unable to initialize BSD authentication"
+msgstr "无法初始化 bsd 认证"
+
+#: plugins/sudoers/auth/bsdauth.c:183
+msgid "your account has expired"
+msgstr "您的账户已过期"
+
+#: plugins/sudoers/auth/bsdauth.c:185
+msgid "approval failed"
+msgstr "批准失败"
+
+#: plugins/sudoers/auth/fwtk.c:57
+msgid "unable to read fwtk config"
+msgstr "无法读取 fwtk 配置"
+
+#: plugins/sudoers/auth/fwtk.c:62
+msgid "unable to connect to authentication server"
+msgstr "无法连接到认证服务器"
+
+#: plugins/sudoers/auth/fwtk.c:68 plugins/sudoers/auth/fwtk.c:92
+#: plugins/sudoers/auth/fwtk.c:124
+msgid "lost connection to authentication server"
+msgstr "丢失了到认证服务器的连接"
+
+#: plugins/sudoers/auth/fwtk.c:72
+#, c-format
+msgid ""
+"authentication server error:\n"
+"%s"
+msgstr ""
+"认证服务器错误:\n"
+"%s"
+
+#: plugins/sudoers/auth/kerb5.c:113
+#, c-format
+msgid "%s: unable to convert principal to string ('%s'): %s"
+msgstr "%s:无法将主体(principal)转换为字符串(“%s”):%s"
+
+#: plugins/sudoers/auth/kerb5.c:163
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s:无法解析“%s”:%s"
+
+#: plugins/sudoers/auth/kerb5.c:172
+#, c-format
+msgid "%s: unable to resolve credential cache: %s"
+msgstr "%s:无法解析凭据缓存:%s"
+
+#: plugins/sudoers/auth/kerb5.c:219
+#, c-format
+msgid "%s: unable to allocate options: %s"
+msgstr "%s:无法分配选项:%s"
+
+#: plugins/sudoers/auth/kerb5.c:234
+#, c-format
+msgid "%s: unable to get credentials: %s"
+msgstr "%s:无法获取凭据:%s"
+
+#: plugins/sudoers/auth/kerb5.c:247
+#, c-format
+msgid "%s: unable to initialize credential cache: %s"
+msgstr "%s:无法初始化凭据缓存:%s"
+
+#: plugins/sudoers/auth/kerb5.c:250
+#, c-format
+msgid "%s: unable to store credential in cache: %s"
+msgstr "%s:无法在缓存中储存凭据:%s"
+
+#: plugins/sudoers/auth/kerb5.c:314
+#, c-format
+msgid "%s: unable to get host principal: %s"
+msgstr "%s:无法获取主机主体(principal):%s"
+
+#: plugins/sudoers/auth/kerb5.c:328
+#, c-format
+msgid "%s: Cannot verify TGT! Possible attack!: %s"
+msgstr "%s:无法验证目标!可能遭到了攻击!:%s"
+
+#: plugins/sudoers/auth/pam.c:113
+msgid "unable to initialize PAM"
+msgstr "无法初始化 PAM"
+
+#: plugins/sudoers/auth/pam.c:204
+#, c-format
+msgid "PAM authentication error: %s"
+msgstr "PAM 认证出错:%s"
+
+#: plugins/sudoers/auth/pam.c:221
+msgid "account validation failure, is your account locked?"
+msgstr "账户验证失败,您的账户是不是上锁了?"
+
+#: plugins/sudoers/auth/pam.c:229
+msgid "Account or password is expired, reset your password and try again"
+msgstr "账户或密码过期,重置您的密码并重试"
+
+#: plugins/sudoers/auth/pam.c:238
+#, c-format
+msgid "unable to change expired password: %s"
+msgstr "无法更改过期的密码:%s"
+
+#: plugins/sudoers/auth/pam.c:246
+msgid "Password expired, contact your system administrator"
+msgstr "密码过期,联系您的系统管理员"
+
+#: plugins/sudoers/auth/pam.c:250
+msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
+msgstr "账户过期,或 PAM 配置缺少 sudo 使用的“account”节,联系您的系统管理员"
+
+#: plugins/sudoers/auth/pam.c:257 plugins/sudoers/auth/pam.c:262
+#, c-format
+msgid "PAM account management error: %s"
+msgstr "PAM 账户管理出错:%s"
+
+#: plugins/sudoers/auth/rfc1938.c:102 plugins/sudoers/visudo.c:232
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "%s 数据库中没有您"
+
+#: plugins/sudoers/auth/securid5.c:75
+msgid "failed to initialise the ACE API library"
+msgstr "初始化 ACE API 库失败"
+
+#: plugins/sudoers/auth/securid5.c:101
+msgid "unable to contact the SecurID server"
+msgstr "无法联络 SecurID 服务器"
+
+#: plugins/sudoers/auth/securid5.c:110
+msgid "User ID locked for SecurID Authentication"
+msgstr "为进行 SecurID 认证,已锁定用户 ID"
+
+#: plugins/sudoers/auth/securid5.c:114 plugins/sudoers/auth/securid5.c:165
+msgid "invalid username length for SecurID"
+msgstr "SecurID 的用户名长度无效"
+
+#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:170
+msgid "invalid Authentication Handle for SecurID"
+msgstr "SecurID 的认证句柄无效"
+
+#: plugins/sudoers/auth/securid5.c:122
+msgid "SecurID communication failed"
+msgstr "SecurID 通讯失败"
+
+#: plugins/sudoers/auth/securid5.c:126 plugins/sudoers/auth/securid5.c:215
+msgid "unknown SecurID error"
+msgstr "未知的 SecurID 错误"
+
+#: plugins/sudoers/auth/securid5.c:160
+msgid "invalid passcode length for SecurID"
+msgstr "无效的 SecurID 密码长度"
+
+#: plugins/sudoers/auth/sia.c:72 plugins/sudoers/auth/sia.c:127
+msgid "unable to initialize SIA session"
+msgstr "无法初始化 SIA 会话"
+
+#: plugins/sudoers/auth/sudo_auth.c:136
+msgid "invalid authentication methods"
+msgstr "无效的认证方法"
+
+#: plugins/sudoers/auth/sudo_auth.c:138
+msgid "Invalid authentication methods compiled into sudo! You may not mix standalone and non-standalone authentication."
+msgstr "编译进 sudo 的认证方法无效!您不能混用独立和非独立认证。"
+
+#: plugins/sudoers/auth/sudo_auth.c:259 plugins/sudoers/auth/sudo_auth.c:309
+msgid "no authentication methods"
+msgstr "无认证方法"
+
+#: plugins/sudoers/auth/sudo_auth.c:261
+msgid "There are no authentication methods compiled into sudo! If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "sudo 编译时没有加入任何认证方法!如果您想关闭认证,使用 --disable-authentication 配置选项。"
+
+#: plugins/sudoers/auth/sudo_auth.c:311
+msgid "Unable to initialize authentication methods."
+msgstr "无法初始化认证方法。"
+
+#: plugins/sudoers/auth/sudo_auth.c:477
+msgid "Authentication methods:"
+msgstr "认证方法:"
+
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:215
+msgid "Could not determine audit condition"
+msgstr "无法确定审核条件"
+
+#: plugins/sudoers/bsm_audit.c:188 plugins/sudoers/bsm_audit.c:279
+msgid "unable to commit audit record"
+msgstr "无法提交审核记录"
+
+#: plugins/sudoers/check.c:267
+msgid ""
+"\n"
+"We trust you have received the usual lecture from the local System\n"
+"Administrator. It usually boils down to these three things:\n"
+"\n"
+" #1) Respect the privacy of others.\n"
+" #2) Think before you type.\n"
+" #3) With great power comes great responsibility.\n"
+"\n"
+msgstr ""
+"\n"
+"我们信任您已经从系统管理员那里了解了日常注意事项。\n"
+"总结起来无外乎这三点:\n"
+"\n"
+" #1) 尊重别人的隐私。\n"
+" #2) 输入前要先考虑(后果和风险)。\n"
+" #3) 权力越大,责任越大。\n"
+"\n"
+
+#: plugins/sudoers/check.c:310 plugins/sudoers/check.c:320
+#: plugins/sudoers/sudoers.c:696 plugins/sudoers/sudoers.c:741
+#: plugins/sudoers/tsdump.c:124
+#, c-format
+msgid "unknown uid: %u"
+msgstr "未知的用户 ID:%u"
+
+#: plugins/sudoers/check.c:315 plugins/sudoers/iolog.c:253
+#: plugins/sudoers/policy.c:915 plugins/sudoers/sudoers.c:1136
+#: plugins/sudoers/testsudoers.c:225 plugins/sudoers/testsudoers.c:398
+#, c-format
+msgid "unknown user: %s"
+msgstr "未知用户:%s"
+
+#: plugins/sudoers/cvtsudoers.c:198
+#, c-format
+msgid "order increment: %s: %s"
+msgstr "顺序增量:%s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:214
+#, c-format
+msgid "starting order: %s: %s"
+msgstr "起始顺序:%s:%s"
+
+#: plugins/sudoers/cvtsudoers.c:224
+#, c-format
+msgid "order padding: %s: %s"
+msgstr "顺序填充:%s: %s"
+
+#: plugins/sudoers/cvtsudoers.c:232 plugins/sudoers/sudoreplay.c:287
+#: plugins/sudoers/visudo.c:182
+#, c-format
+msgid "%s version %s\n"
+msgstr "%s 版本 %s\n"
+
+#: plugins/sudoers/cvtsudoers.c:234 plugins/sudoers/visudo.c:184
+#, c-format
+msgid "%s grammar version %d\n"
+msgstr "%s 语法版本 %d\n"
+
+#: plugins/sudoers/cvtsudoers.c:251 plugins/sudoers/testsudoers.c:173
+#, c-format
+msgid "unsupported input format %s"
+msgstr "不支持的输入格式 %s"
+
+#: plugins/sudoers/cvtsudoers.c:266
+#, c-format
+msgid "unsupported output format %s"
+msgstr "不支持的输出格式 %s"
+
+#: plugins/sudoers/cvtsudoers.c:318
+#, c-format
+msgid "%s: input and output files must be different"
+msgstr "%s:输入和输出文件不能相同"
+
+#: plugins/sudoers/cvtsudoers.c:334 plugins/sudoers/sudoers.c:172
+#: plugins/sudoers/testsudoers.c:264 plugins/sudoers/visudo.c:238
+#: plugins/sudoers/visudo.c:594 plugins/sudoers/visudo.c:917
+msgid "unable to initialize sudoers default values"
+msgstr "无法初始化 sudoers 默认值"
+
+#: plugins/sudoers/cvtsudoers.c:420 plugins/sudoers/ldap_conf.c:433
+#, c-format
+msgid "%s: %s: %s: %s"
+msgstr "%s:%s:%s:%s"
+
+#: plugins/sudoers/cvtsudoers.c:479
+#, c-format
+msgid "%s: unknown key word: %s"
+msgstr "%s:未知的关键词:%s"
+
+#: plugins/sudoers/cvtsudoers.c:525
+#, c-format
+msgid "invalid defaults type: %s"
+msgstr "无效的默认值类型:%s"
+
+#: plugins/sudoers/cvtsudoers.c:548
+#, c-format
+msgid "invalid suppression type: %s"
+msgstr "无效的压缩类型:%s"
+
+#: plugins/sudoers/cvtsudoers.c:588 plugins/sudoers/cvtsudoers.c:602
+#, c-format
+msgid "invalid filter: %s"
+msgstr "无效的过滤器:%s"
+
+#: plugins/sudoers/cvtsudoers.c:621 plugins/sudoers/cvtsudoers.c:638
+#: plugins/sudoers/cvtsudoers.c:1244 plugins/sudoers/cvtsudoers_json.c:1128
+#: plugins/sudoers/cvtsudoers_ldif.c:641 plugins/sudoers/iolog.c:411
+#: plugins/sudoers/iolog_util.c:72 plugins/sudoers/sudoers.c:903
+#: plugins/sudoers/sudoreplay.c:333 plugins/sudoers/sudoreplay.c:1425
+#: plugins/sudoers/timestamp.c:446 plugins/sudoers/tsdump.c:133
+#: plugins/sudoers/visudo.c:913
+#, c-format
+msgid "unable to open %s"
+msgstr "无法打开 %s"
+
+#: plugins/sudoers/cvtsudoers.c:641 plugins/sudoers/visudo.c:922
+#, c-format
+msgid "failed to parse %s file, unknown error"
+msgstr "解析 %s 文件失败,未知错误"
+
+#: plugins/sudoers/cvtsudoers.c:649 plugins/sudoers/visudo.c:939
+#, c-format
+msgid "parse error in %s near line %d\n"
+msgstr "%s 中第 %d 行附近出现解析错误\n"
+
+#: plugins/sudoers/cvtsudoers.c:652 plugins/sudoers/visudo.c:942
+#, c-format
+msgid "parse error in %s\n"
+msgstr "%s 中出现解析错误\n"
+
+#: plugins/sudoers/cvtsudoers.c:1291 plugins/sudoers/iolog.c:498
+#: plugins/sudoers/sudoreplay.c:1129 plugins/sudoers/timestamp.c:330
+#: plugins/sudoers/timestamp.c:333
+#, c-format
+msgid "unable to write to %s"
+msgstr "无法写入 %s"
+
+#: plugins/sudoers/cvtsudoers.c:1314
+#, c-format
+msgid ""
+"%s - convert between sudoers file formats\n"
+"\n"
+msgstr ""
+"%s - 转换 sudoers 文件格式\n"
+"\n"
+
+#: plugins/sudoers/cvtsudoers.c:1316
+msgid ""
+"\n"
+"Options:\n"
+" -b, --base=dn the base DN for sudo LDAP queries\n"
+" -d, --defaults=deftypes only convert Defaults of the specified types\n"
+" -e, --expand-aliases expand aliases when converting\n"
+" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+" -i, --input-format=format set input format: LDIF or sudoers\n"
+" -I, --increment=num amount to increase each sudoOrder by\n"
+" -h, --help display help message and exit\n"
+" -m, --match=filter only convert entries that match the filter\n"
+" -M, --match-local match filter uses passwd and group databases\n"
+" -o, --output=output_file write converted sudoers to output_file\n"
+" -O, --order-start=num starting point for first sudoOrder\n"
+" -p, --prune-matches prune non-matching users, groups and hosts\n"
+" -P, --padding=num base padding for sudoOrder increment\n"
+" -s, --suppress=sections suppress output of certain sections\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"选项:\n"
+" -b, --base=dn 用于 sudo LDAP 查询的基础 DN\n"
+" -d, --defaults=deftypes 只转换指定类型的默认值\n"
+" -e, --expand-aliases 在转换时展开别名\n"
+" -f, --output-format=format 设置输出格式:JSON、LDIF 或 sudoers\n"
+" -i, --input-format=format 设置输入格式:LDIF 或 sudoers\n"
+" -I, --increment=num 每个 sudoOrder 的增加量\n"
+" -h, --help 显示帮助消息并退出\n"
+" -m, --match=filter 只转换与过滤器匹配的条目\n"
+" -M, --match-local 让匹配过滤器使用 passwd 和 group 数据库\n"
+" -o, --output=output_file 将转换后的 sudoers 写入 output_file\n"
+" -O, --order-start=num 第一个 sudoOrder 的起点\n"
+" -p, --prune-matches 清理不匹配的用户、组和主机\n"
+" -P, --padding=num sudoOrder 的增加基数\n"
+" -s, --suppress=sections 压缩某些部分的输出\n"
+" -V, --version 显示版本信息并退出"
+
+#: plugins/sudoers/cvtsudoers_json.c:682 plugins/sudoers/cvtsudoers_json.c:718
+#: plugins/sudoers/cvtsudoers_json.c:936
+#, c-format
+msgid "unknown defaults entry \"%s\""
+msgstr "未知的默认条目“%s”"
+
+#: plugins/sudoers/cvtsudoers_json.c:856 plugins/sudoers/cvtsudoers_json.c:871
+#: plugins/sudoers/cvtsudoers_ldif.c:306 plugins/sudoers/cvtsudoers_ldif.c:317
+#: plugins/sudoers/ldap.c:480
+msgid "unable to get GMT time"
+msgstr "无法获取 GMT 时间"
+
+#: plugins/sudoers/cvtsudoers_json.c:859 plugins/sudoers/cvtsudoers_json.c:874
+#: plugins/sudoers/cvtsudoers_ldif.c:309 plugins/sudoers/cvtsudoers_ldif.c:320
+#: plugins/sudoers/ldap.c:486
+msgid "unable to format timestamp"
+msgstr "无法格式化时间戳"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:524 plugins/sudoers/env.c:309
+#: plugins/sudoers/env.c:316 plugins/sudoers/env.c:421
+#: plugins/sudoers/ldap.c:494 plugins/sudoers/ldap.c:725
+#: plugins/sudoers/ldap.c:1052 plugins/sudoers/ldap_conf.c:225
+#: plugins/sudoers/ldap_conf.c:315 plugins/sudoers/linux_audit.c:87
+#: plugins/sudoers/logging.c:1015 plugins/sudoers/policy.c:623
+#: plugins/sudoers/policy.c:633 plugins/sudoers/prompt.c:166
+#: plugins/sudoers/sudoers.c:845 plugins/sudoers/testsudoers.c:255
+#: plugins/sudoers/toke_util.c:159
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "内部错误,%s 溢出"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:593
+#, c-format
+msgid "too many sudoers entries, maximum %u"
+msgstr "sudoers 条目过多,最多为 %u"
+
+#: plugins/sudoers/cvtsudoers_ldif.c:636
+msgid "the SUDOERS_BASE environment variable is not set and the -b option was not specified."
+msgstr "没有设置 SUDOERS_BASE 环境变量,并且没有指定 -b 选项。"
+
+#: plugins/sudoers/def_data.c:42
+#, c-format
+msgid "Syslog facility if syslog is being used for logging: %s"
+msgstr "若使用了 syslog,用于记录日志的 syslog 设施:%s"
+
+#: plugins/sudoers/def_data.c:46
+#, c-format
+msgid "Syslog priority to use when user authenticates successfully: %s"
+msgstr "用户认证成功时使用的 syslog 优先级:%s"
+
+#: plugins/sudoers/def_data.c:50
+#, c-format
+msgid "Syslog priority to use when user authenticates unsuccessfully: %s"
+msgstr "用户认证不成功时使用的 syslog 优先级:%s"
+
+#: plugins/sudoers/def_data.c:54
+msgid "Put OTP prompt on its own line"
+msgstr "将 OPT 提示放在独自的行中"
+
+#: plugins/sudoers/def_data.c:58
+msgid "Ignore '.' in $PATH"
+msgstr "忽略 $PATH 中的“.”"
+
+#: plugins/sudoers/def_data.c:62
+msgid "Always send mail when sudo is run"
+msgstr "在运行 sudo 时总是发送邮件"
+
+#: plugins/sudoers/def_data.c:66
+msgid "Send mail if user authentication fails"
+msgstr "在用户认证失败时发送邮件"
+
+#: plugins/sudoers/def_data.c:70
+msgid "Send mail if the user is not in sudoers"
+msgstr "在用户不在 sudoers 列表中时发送邮件"
+
+#: plugins/sudoers/def_data.c:74
+msgid "Send mail if the user is not in sudoers for this host"
+msgstr "在用户不在此主机的 sudoers 列表中时发送邮件"
+
+#: plugins/sudoers/def_data.c:78
+msgid "Send mail if the user is not allowed to run a command"
+msgstr "在用户不允许执行某个命令时发送邮件"
+
+#: plugins/sudoers/def_data.c:82
+msgid "Send mail if the user tries to run a command"
+msgstr "在用户尝试执行某个命令时发送邮件"
+
+#: plugins/sudoers/def_data.c:86
+msgid "Use a separate timestamp for each user/tty combo"
+msgstr "对每个用户/终端组合使用独立的时间戳"
+
+#: plugins/sudoers/def_data.c:90
+msgid "Lecture user the first time they run sudo"
+msgstr "在用户第一次运行 sudo 时向他致辞"
+
+#: plugins/sudoers/def_data.c:94
+#, c-format
+msgid "File containing the sudo lecture: %s"
+msgstr "包含 sudo 致辞的文件:%s"
+
+#: plugins/sudoers/def_data.c:98
+msgid "Require users to authenticate by default"
+msgstr "默认要求用户认证"
+
+#: plugins/sudoers/def_data.c:102
+msgid "Root may run sudo"
+msgstr "root 可以运行 sudo"
+
+#: plugins/sudoers/def_data.c:106
+msgid "Log the hostname in the (non-syslog) log file"
+msgstr "将主机名记录在(非 syslog)的日志文件中"
+
+#: plugins/sudoers/def_data.c:110
+msgid "Log the year in the (non-syslog) log file"
+msgstr "将年份记录在(非 syslog)的日志文件中"
+
+#: plugins/sudoers/def_data.c:114
+msgid "If sudo is invoked with no arguments, start a shell"
+msgstr "如果不带参数调用 sudo,启动一个 shell"
+
+#: plugins/sudoers/def_data.c:118
+msgid "Set $HOME to the target user when starting a shell with -s"
+msgstr "若使用 -s 选项启动 shell,将 $HOME 设为目标用户的主目录"
+
+#: plugins/sudoers/def_data.c:122
+msgid "Always set $HOME to the target user's home directory"
+msgstr "总是将 $HOME 设为目标用户的主目录"
+
+#: plugins/sudoers/def_data.c:126
+msgid "Allow some information gathering to give useful error messages"
+msgstr "允许收集一些信息,以提供有用的错误消息"
+
+#: plugins/sudoers/def_data.c:130
+msgid "Require fully-qualified hostnames in the sudoers file"
+msgstr "要求 sudoers 文件中包含完全限定的主机名"
+
+#: plugins/sudoers/def_data.c:134
+msgid "Insult the user when they enter an incorrect password"
+msgstr "在用户输入错误密码时对他们进行(玩笑式的)嘲讽"
+
+#: plugins/sudoers/def_data.c:138
+msgid "Only allow the user to run sudo if they have a tty"
+msgstr "只允许拥有终端的用户执行 sudo"
+
+#: plugins/sudoers/def_data.c:142
+msgid "Visudo will honor the EDITOR environment variable"
+msgstr "Visudo 将优先考虑 EDITOR 环境变量"
+
+#: plugins/sudoers/def_data.c:146
+msgid "Prompt for root's password, not the users's"
+msgstr "询问 root 用户的密码而非用户的密码"
+
+#: plugins/sudoers/def_data.c:150
+msgid "Prompt for the runas_default user's password, not the users's"
+msgstr "询问 runas_default 用户的密码,而非用户密码"
+
+#: plugins/sudoers/def_data.c:154
+msgid "Prompt for the target user's password, not the users's"
+msgstr "询问目标用户的密码,而非用户密码"
+
+#: plugins/sudoers/def_data.c:158
+msgid "Apply defaults in the target user's login class if there is one"
+msgstr "应用目标用户登录类别中的默认设置,如果没有设置的话"
+
+#: plugins/sudoers/def_data.c:162
+msgid "Set the LOGNAME and USER environment variables"
+msgstr "设置 LOGNAME 和 USER 环境变量"
+
+#: plugins/sudoers/def_data.c:166
+msgid "Only set the effective uid to the target user, not the real uid"
+msgstr "只将有效用户 ID 设为目标用户的,而不是实际用户 ID"
+
+#: plugins/sudoers/def_data.c:170
+msgid "Don't initialize the group vector to that of the target user"
+msgstr "不将组向量初始化为目标用户的"
+
+#: plugins/sudoers/def_data.c:174
+#, c-format
+msgid "Length at which to wrap log file lines (0 for no wrap): %u"
+msgstr "日志文件折行的长度(0 则不折行):%u"
+
+#: plugins/sudoers/def_data.c:178
+#, c-format
+msgid "Authentication timestamp timeout: %.1f minutes"
+msgstr "认证时间戳延时:%.1f 分钟"
+
+#: plugins/sudoers/def_data.c:182
+#, c-format
+msgid "Password prompt timeout: %.1f minutes"
+msgstr "密码提示延时:%.1f 分钟"
+
+#: plugins/sudoers/def_data.c:186
+#, c-format
+msgid "Number of tries to enter a password: %u"
+msgstr "输入密码的尝试次数:%u"
+
+#: plugins/sudoers/def_data.c:190
+#, c-format
+msgid "Umask to use or 0777 to use user's: 0%o"
+msgstr "要使用的 umask,或 0777 使用用户的:0%o"
+
+#: plugins/sudoers/def_data.c:194
+#, c-format
+msgid "Path to log file: %s"
+msgstr "日志文件路径:%s"
+
+#: plugins/sudoers/def_data.c:198
+#, c-format
+msgid "Path to mail program: %s"
+msgstr "邮件程序路径:%s"
+
+#: plugins/sudoers/def_data.c:202
+#, c-format
+msgid "Flags for mail program: %s"
+msgstr "邮件程序标志:%s"
+
+#: plugins/sudoers/def_data.c:206
+#, c-format
+msgid "Address to send mail to: %s"
+msgstr "发送邮件的地址:%s"
+
+#: plugins/sudoers/def_data.c:210
+#, c-format
+msgid "Address to send mail from: %s"
+msgstr "接收邮件的地址:%s"
+
+#: plugins/sudoers/def_data.c:214
+#, c-format
+msgid "Subject line for mail messages: %s"
+msgstr "邮件消息的主题行:%s"
+
+#: plugins/sudoers/def_data.c:218
+#, c-format
+msgid "Incorrect password message: %s"
+msgstr "密码错误消息:%s"
+
+#: plugins/sudoers/def_data.c:222
+#, c-format
+msgid "Path to lecture status dir: %s"
+msgstr "致辞(lecture)状态文件夹的路径:%s"
+
+#: plugins/sudoers/def_data.c:226
+#, c-format
+msgid "Path to authentication timestamp dir: %s"
+msgstr "认证时间戳文件夹的路径:%s"
+
+#: plugins/sudoers/def_data.c:230
+#, c-format
+msgid "Owner of the authentication timestamp dir: %s"
+msgstr "认证时间戳的所有者:%s"
+
+#: plugins/sudoers/def_data.c:234
+#, c-format
+msgid "Users in this group are exempt from password and PATH requirements: %s"
+msgstr "此组的用户不要求密码和 PATH:%s"
+
+#: plugins/sudoers/def_data.c:238
+#, c-format
+msgid "Default password prompt: %s"
+msgstr "默认密码提示:%s"
+
+#: plugins/sudoers/def_data.c:242
+msgid "If set, passprompt will override system prompt in all cases."
+msgstr "如果设置,密码提示将覆盖各种情况下的系统提示。"
+
+#: plugins/sudoers/def_data.c:246
+#, c-format
+msgid "Default user to run commands as: %s"
+msgstr "运行命令的默认用户:%s"
+
+#: plugins/sudoers/def_data.c:250
+#, c-format
+msgid "Value to override user's $PATH with: %s"
+msgstr "覆盖用户的 $PATH 变量的值:%s"
+
+#: plugins/sudoers/def_data.c:254
+#, c-format
+msgid "Path to the editor for use by visudo: %s"
+msgstr "visudo 所使用的编辑器的路径:%s"
+
+#: plugins/sudoers/def_data.c:258
+#, c-format
+msgid "When to require a password for 'list' pseudocommand: %s"
+msgstr "何时为“list”伪命令请求密码:%s"
+
+#: plugins/sudoers/def_data.c:262
+#, c-format
+msgid "When to require a password for 'verify' pseudocommand: %s"
+msgstr "何时为“verify”伪命令请求密码:%s"
+
+#: plugins/sudoers/def_data.c:266
+msgid "Preload the dummy exec functions contained in the sudo_noexec library"
+msgstr "预加载“sudo_noexec”库中包含的哑 exec 函数"
+
+#: plugins/sudoers/def_data.c:270
+msgid "If LDAP directory is up, do we ignore local sudoers file"
+msgstr "如果 LDAP 目录有效,是不是忽略本地的 sudoers 文件"
+
+#: plugins/sudoers/def_data.c:274
+#, c-format
+msgid "File descriptors >= %d will be closed before executing a command"
+msgstr ">= %d 的文件描述符将会在执行命令前关闭"
+
+#: plugins/sudoers/def_data.c:278
+msgid "If set, users may override the value of `closefrom' with the -C option"
+msgstr "如果设置,用户可以通过 -C 选项覆盖“closefrom”的值"
+
+#: plugins/sudoers/def_data.c:282
+msgid "Allow users to set arbitrary environment variables"
+msgstr "允许用户设置任意的环境变量"
+
+#: plugins/sudoers/def_data.c:286
+msgid "Reset the environment to a default set of variables"
+msgstr "将环境重设为默认的变量集"
+
+#: plugins/sudoers/def_data.c:290
+msgid "Environment variables to check for sanity:"
+msgstr "要检查完整性的环境变量:"
+
+#: plugins/sudoers/def_data.c:294
+msgid "Environment variables to remove:"
+msgstr "要移除的环境变量:"
+
+#: plugins/sudoers/def_data.c:298
+msgid "Environment variables to preserve:"
+msgstr "要保留的环境变量:"
+
+#: plugins/sudoers/def_data.c:302
+#, c-format
+msgid "SELinux role to use in the new security context: %s"
+msgstr "在新的安全环境中使用的 SELinux 角色:%s"
+
+#: plugins/sudoers/def_data.c:306
+#, c-format
+msgid "SELinux type to use in the new security context: %s"
+msgstr "在新的安全环境中使用的 SELinux 类型:%s"
+
+#: plugins/sudoers/def_data.c:310
+#, c-format
+msgid "Path to the sudo-specific environment file: %s"
+msgstr "sudo 特定环境文件的路径:%s"
+
+#: plugins/sudoers/def_data.c:314
+#, c-format
+msgid "Path to the restricted sudo-specific environment file: %s"
+msgstr "受限的 sudo 特定环境文件的路径:%s"
+
+#: plugins/sudoers/def_data.c:318
+#, c-format
+msgid "Locale to use while parsing sudoers: %s"
+msgstr "解析 sudoers 时使用的区域设置:%s"
+
+#: plugins/sudoers/def_data.c:322
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "允许 sudo 询问密码,即使它不可见"
+
+#: plugins/sudoers/def_data.c:326
+msgid "Provide visual feedback at the password prompt when there is user input"
+msgstr "用户在询问密码窗口输入时提供视觉反馈"
+
+#: plugins/sudoers/def_data.c:330
+msgid "Use faster globbing that is less accurate but does not access the filesystem"
+msgstr "使用不太精确但不访问文件系统的较快通配方法"
+
+#: plugins/sudoers/def_data.c:334
+msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
+msgstr "sudoers 中指定的 umask 会覆盖用户的,即使它允许的权限更多"
+
+#: plugins/sudoers/def_data.c:338
+msgid "Log user's input for the command being run"
+msgstr "记录用户在所执行命令中的输入"
+
+#: plugins/sudoers/def_data.c:342
+msgid "Log the output of the command being run"
+msgstr "记录所执行命令的输出"
+
+#: plugins/sudoers/def_data.c:346
+msgid "Compress I/O logs using zlib"
+msgstr "使用 zlib 压缩 I/O 日志"
+
+#: plugins/sudoers/def_data.c:350
+msgid "Always run commands in a pseudo-tty"
+msgstr "总是在伪终端中运行命令"
+
+#: plugins/sudoers/def_data.c:354
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "用于非 Unix 组支持的插件:%s"
+
+#: plugins/sudoers/def_data.c:358
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "用于保存输入/输出日志的目录:%s"
+
+#: plugins/sudoers/def_data.c:362
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "用于保存输入/输出日志的文件:%s"
+
+#: plugins/sudoers/def_data.c:366
+msgid "Add an entry to the utmp/utmpx file when allocating a pty"
+msgstr "在分配伪终端时向 utmp/utmpx 文件中添加一条记录"
+
+#: plugins/sudoers/def_data.c:370
+msgid "Set the user in utmp to the runas user, not the invoking user"
+msgstr "将 utmp 中的用户设为 runas 用户,而不是调用用户"
+
+#: plugins/sudoers/def_data.c:374
+#, c-format
+msgid "Set of permitted privileges: %s"
+msgstr "允许权限的集合:%s"
+
+#: plugins/sudoers/def_data.c:378
+#, c-format
+msgid "Set of limit privileges: %s"
+msgstr "限制权限的集合:%s"
+
+#: plugins/sudoers/def_data.c:382
+msgid "Run commands on a pty in the background"
+msgstr "在后台的伪终端上运行命令"
+
+#: plugins/sudoers/def_data.c:386
+#, c-format
+msgid "PAM service name to use: %s"
+msgstr "要使用的 PAM 服务名称:%s"
+
+#: plugins/sudoers/def_data.c:390
+#, c-format
+msgid "PAM service name to use for login shells: %s"
+msgstr "用于登录 shell 的 PAM 服务名称:%s"
+
+#: plugins/sudoers/def_data.c:394
+msgid "Attempt to establish PAM credentials for the target user"
+msgstr "尝试为目标用户建立 PAM 凭据"
+
+#: plugins/sudoers/def_data.c:398
+msgid "Create a new PAM session for the command to run in"
+msgstr "创建一个新的 PAM 会话来运行该命令"
+
+#: plugins/sudoers/def_data.c:402
+#, c-format
+msgid "Maximum I/O log sequence number: %u"
+msgstr "最大 I/O 日志序列号:%u"
+
+#: plugins/sudoers/def_data.c:406
+msgid "Enable sudoers netgroup support"
+msgstr "启用 support netgroup 支持"
+
+#: plugins/sudoers/def_data.c:410
+msgid "Check parent directories for writability when editing files with sudoedit"
+msgstr "在使用 sudoedit 编辑文件时检查上级目录是否可写"
+
+#: plugins/sudoers/def_data.c:414
+msgid "Follow symbolic links when editing files with sudoedit"
+msgstr "使用 sudoedit 编辑文件时循符号连接(定位到原文件)"
+
+#: plugins/sudoers/def_data.c:418
+msgid "Query the group plugin for unknown system groups"
+msgstr "通过 组 插件查询未知的系统组"
+
+#: plugins/sudoers/def_data.c:422
+msgid "Match netgroups based on the entire tuple: user, host and domain"
+msgstr "基于整个元组(用户、主机和域)来匹配网络组"
+
+#: plugins/sudoers/def_data.c:426
+msgid "Allow commands to be run even if sudo cannot write to the audit log"
+msgstr "即使 sudo 无法写入审核日志也允许命令运行"
+
+#: plugins/sudoers/def_data.c:430
+msgid "Allow commands to be run even if sudo cannot write to the I/O log"
+msgstr "即使 sudo 无法写入 I/O 日志也允许命令运行"
+
+#: plugins/sudoers/def_data.c:434
+msgid "Allow commands to be run even if sudo cannot write to the log file"
+msgstr "即使 sudo 无法写入日志文件也允许命令允许"
+
+#: plugins/sudoers/def_data.c:438
+msgid "Resolve groups in sudoers and match on the group ID, not the name"
+msgstr "解析 sudoers 中的组并与 组 ID (而不是名字) 匹配"
+
+#: plugins/sudoers/def_data.c:442
+#, c-format
+msgid "Log entries larger than this value will be split into multiple syslog messages: %u"
+msgstr "大于此数值的日志条目会分为多条 syslog 消息:%u"
+
+#: plugins/sudoers/def_data.c:446
+#, c-format
+msgid "User that will own the I/O log files: %s"
+msgstr "将拥有 I/O 日志文件的用户:%s"
+
+#: plugins/sudoers/def_data.c:450
+#, c-format
+msgid "Group that will own the I/O log files: %s"
+msgstr "将拥有 I/O 日志文件的组:%s"
+
+#: plugins/sudoers/def_data.c:454
+#, c-format
+msgid "File mode to use for the I/O log files: 0%o"
+msgstr "I/O 日志文件要使用的文件模式:0%o"
+
+#: plugins/sudoers/def_data.c:458
+#, c-format
+msgid "Execute commands by file descriptor instead of by path: %s"
+msgstr "根据文件描述符执行命令,而非根据路径:%s"
+
+#: plugins/sudoers/def_data.c:462
+msgid "Ignore unknown Defaults entries in sudoers instead of producing a warning"
+msgstr "忽略 sudoers 中未知的 Defaults 条目而非产生警告"
+
+#: plugins/sudoers/def_data.c:466
+#, c-format
+msgid "Time in seconds after which the command will be terminated: %u"
+msgstr "超过指定时间后终止命令(秒):%u"
+
+#: plugins/sudoers/def_data.c:470
+msgid "Allow the user to specify a timeout on the command line"
+msgstr "允许用户在命令行中指定超时时间"
+
+#: plugins/sudoers/def_data.c:474
+msgid "Flush I/O log data to disk immediately instead of buffering it"
+msgstr "立即冲洗(flush) I/O 日志数据而非将其缓存"
+
+#: plugins/sudoers/def_data.c:478
+msgid "Include the process ID when logging via syslog"
+msgstr "通过 syslog 登录时包含进程 ID"
+
+#: plugins/sudoers/def_data.c:482
+#, c-format
+msgid "Type of authentication timestamp record: %s"
+msgstr "认证时间戳记录的类型:%s"
+
+#: plugins/sudoers/def_data.c:486
+#, c-format
+msgid "Authentication failure message: %s"
+msgstr "认证失败消息:%s"
+
+#: plugins/sudoers/def_data.c:490
+msgid "Ignore case when matching user names"
+msgstr "在匹配 用户 名时忽略大小写"
+
+#: plugins/sudoers/def_data.c:494
+msgid "Ignore case when matching group names"
+msgstr "在匹配 组 名时忽略大小写"
+
+#: plugins/sudoers/defaults.c:229
+#, c-format
+msgid "%s:%d unknown defaults entry \"%s\""
+msgstr "%s:%d 未知的默认条目“%s”"
+
+#: plugins/sudoers/defaults.c:232
+#, c-format
+msgid "%s: unknown defaults entry \"%s\""
+msgstr "%s:未知的默认条目“%s”"
+
+#: plugins/sudoers/defaults.c:275
+#, c-format
+msgid "%s:%d no value specified for \"%s\""
+msgstr "%s:%d 没有给“%s”指定值"
+
+#: plugins/sudoers/defaults.c:278
+#, c-format
+msgid "%s: no value specified for \"%s\""
+msgstr "%s:没有给“%s”指定值"
+
+#: plugins/sudoers/defaults.c:298
+#, c-format
+msgid "%s:%d values for \"%s\" must start with a '/'"
+msgstr "%s:%d “%s”的值必须以“/”开头"
+
+#: plugins/sudoers/defaults.c:301
+#, c-format
+msgid "%s: values for \"%s\" must start with a '/'"
+msgstr "%s:“%s”的值必须以“/”开头"
+
+#: plugins/sudoers/defaults.c:323
+#, c-format
+msgid "%s:%d option \"%s\" does not take a value"
+msgstr "%s:%d “%s”选项不带值"
+
+#: plugins/sudoers/defaults.c:326
+#, c-format
+msgid "%s: option \"%s\" does not take a value"
+msgstr "%s:“%s”选项不带值"
+
+#: plugins/sudoers/defaults.c:351
+#, c-format
+msgid "%s:%d invalid Defaults type 0x%x for option \"%s\""
+msgstr "%1$s:%2$d 选项“%4$s”的默认类型 0x%3$x 无效"
+
+#: plugins/sudoers/defaults.c:354
+#, c-format
+msgid "%s: invalid Defaults type 0x%x for option \"%s\""
+msgstr "%1$s:选项“%3$s”的默认类型 0x%2$x 无效"
+
+#: plugins/sudoers/defaults.c:364
+#, c-format
+msgid "%s:%d value \"%s\" is invalid for option \"%s\""
+msgstr "%1$s:%2$d 值“%3$s”对选项“%4$s”无效"
+
+#: plugins/sudoers/defaults.c:367
+#, c-format
+msgid "%s: value \"%s\" is invalid for option \"%s\""
+msgstr "%s:值“%s”对选项“%s”无效"
+
+#: plugins/sudoers/env.c:390
+msgid "sudo_putenv: corrupted envp, length mismatch"
+msgstr "sudo_putenv:envp 损坏,长度不符"
+
+#: plugins/sudoers/env.c:1111
+msgid "unable to rebuild the environment"
+msgstr "无法重建环境"
+
+#: plugins/sudoers/env.c:1185
+#, c-format
+msgid "sorry, you are not allowed to set the following environment variables: %s"
+msgstr "对不起,您无权设置以下环境变量:%s"
+
+#: plugins/sudoers/file.c:114
+#, c-format
+msgid "parse error in %s near line %d"
+msgstr "%s 中第 %d 行附近有解析错误"
+
+#: plugins/sudoers/file.c:117
+#, c-format
+msgid "parse error in %s"
+msgstr "%s 中出现解析错误"
+
+#: plugins/sudoers/filedigest.c:59
+#, c-format
+msgid "unsupported digest type %d for %s"
+msgstr "%2$s 的摘要类型 %1$d 不支持"
+
+#: plugins/sudoers/filedigest.c:88
+#, c-format
+msgid "%s: read error"
+msgstr "%s:写错误"
+
+#: plugins/sudoers/group_plugin.c:88
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s 必须属于用户 ID %d"
+
+#: plugins/sudoers/group_plugin.c:92
+#, c-format
+msgid "%s must only be writable by owner"
+msgstr "%s 必须只对所有者可写"
+
+#: plugins/sudoers/group_plugin.c:100 plugins/sudoers/sssd.c:561
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "无法加载 %s:%s"
+
+#: plugins/sudoers/group_plugin.c:106
+#, c-format
+msgid "unable to find symbol \"group_plugin\" in %s"
+msgstr "无法在 %s 中找到符号“group_plugin”"
+
+#: plugins/sudoers/group_plugin.c:111
+#, c-format
+msgid "%s: incompatible group plugin major version %d, expected %d"
+msgstr "%s:不兼容的组插件主版本号 %d,应为 %d"
+
+#: plugins/sudoers/interfaces.c:84 plugins/sudoers/interfaces.c:101
+#, c-format
+msgid "unable to parse IP address \"%s\""
+msgstr "无法解析 IP 地址列表“%s”"
+
+#: plugins/sudoers/interfaces.c:89 plugins/sudoers/interfaces.c:106
+#, c-format
+msgid "unable to parse netmask \"%s\""
+msgstr "无法解析网络掩码“%s”"
+
+#: plugins/sudoers/interfaces.c:134
+msgid "Local IP address and netmask pairs:\n"
+msgstr "本地 IP 地址和网络掩码对:\n"
+
+#: plugins/sudoers/iolog.c:115 plugins/sudoers/mkdir_parents.c:80
+#, c-format
+msgid "%s exists but is not a directory (0%o)"
+msgstr "%s 存在,但不是目录(0%o)"
+
+#: plugins/sudoers/iolog.c:140 plugins/sudoers/iolog.c:180
+#: plugins/sudoers/mkdir_parents.c:69 plugins/sudoers/timestamp.c:210
+#, c-format
+msgid "unable to mkdir %s"
+msgstr "无法创建目录 %s"
+
+#: plugins/sudoers/iolog.c:184 plugins/sudoers/visudo.c:723
+#: plugins/sudoers/visudo.c:734
+#, c-format
+msgid "unable to change mode of %s to 0%o"
+msgstr "无法将 %s 的模式更改为 0%o"
+
+#: plugins/sudoers/iolog.c:292 plugins/sudoers/sudoers.c:1167
+#: plugins/sudoers/testsudoers.c:422
+#, c-format
+msgid "unknown group: %s"
+msgstr "未知组:%s"
+
+#: plugins/sudoers/iolog.c:462 plugins/sudoers/sudoers.c:907
+#: plugins/sudoers/sudoreplay.c:840 plugins/sudoers/sudoreplay.c:1536
+#: plugins/sudoers/tsdump.c:143
+#, c-format
+msgid "unable to read %s"
+msgstr "无法读取 %s"
+
+#: plugins/sudoers/iolog.c:577 plugins/sudoers/iolog.c:797
+#, c-format
+msgid "unable to create %s"
+msgstr "无法创建 %s"
+
+#: plugins/sudoers/iolog.c:820 plugins/sudoers/iolog.c:1035
+#: plugins/sudoers/iolog.c:1111 plugins/sudoers/iolog.c:1205
+#: plugins/sudoers/iolog.c:1265
+#, c-format
+msgid "unable to write to I/O log file: %s"
+msgstr "无法写入 I/O 日志文件:%s"
+
+#: plugins/sudoers/iolog.c:1069
+#, c-format
+msgid "%s: internal error, I/O log file for event %d not open"
+msgstr "%s:内部错误,事件 %d 的 I/O 日志文件未打开"
+
+#: plugins/sudoers/iolog.c:1228
+#, c-format
+msgid "%s: internal error, invalid signal %d"
+msgstr "%s:内部错误,信号 %d 无效"
+
+#: plugins/sudoers/iolog_util.c:87
+#, c-format
+msgid "%s: invalid log file"
+msgstr "%s:无效的日志文件"
+
+#: plugins/sudoers/iolog_util.c:105
+#, c-format
+msgid "%s: time stamp field is missing"
+msgstr "%s:缺少 时间戳 字段"
+
+#: plugins/sudoers/iolog_util.c:111
+#, c-format
+msgid "%s: time stamp %s: %s"
+msgstr "%s:时间戳 %s:%s"
+
+#: plugins/sudoers/iolog_util.c:118
+#, c-format
+msgid "%s: user field is missing"
+msgstr "%s:缺少 用户 字段"
+
+#: plugins/sudoers/iolog_util.c:127
+#, c-format
+msgid "%s: runas user field is missing"
+msgstr "%s:缺少 runas 用户 字段"
+
+#: plugins/sudoers/iolog_util.c:136
+#, c-format
+msgid "%s: runas group field is missing"
+msgstr "%s:缺少 runas 组 字段"
+
+#: plugins/sudoers/ldap.c:176 plugins/sudoers/ldap_conf.c:294
+msgid "starttls not supported when using ldaps"
+msgstr "使用 ldaps 时不支持 starttls"
+
+#: plugins/sudoers/ldap.c:247
+#, c-format
+msgid "unable to initialize SSL cert and key db: %s"
+msgstr "无法初始化 SSL 证书和密钥数据库:%s"
+
+#: plugins/sudoers/ldap.c:250
+#, c-format
+msgid "you must set TLS_CERT in %s to use SSL"
+msgstr "要使用 SSL,您必须在 %s 中设置 TLS_CERT"
+
+#: plugins/sudoers/ldap.c:1612
+#, c-format
+msgid "unable to initialize LDAP: %s"
+msgstr "无法初始化 LDAP:%s"
+
+#: plugins/sudoers/ldap.c:1648
+msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
+msgstr "指定了 start_tls,但 LDAP 库不支持 ldap_start_tls_s() 或 ldap_start_tls_s_np()"
+
+#: plugins/sudoers/ldap.c:1785 plugins/sudoers/parse_ldif.c:735
+#, c-format
+msgid "invalid sudoOrder attribute: %s"
+msgstr "无效的 sudoOrder 属性:%s"
+
+#: plugins/sudoers/ldap_conf.c:203
+msgid "sudo_ldap_conf_add_ports: port too large"
+msgstr "sudo_ldap_conf_add_ports:端口太大"
+
+#: plugins/sudoers/ldap_conf.c:263
+#, c-format
+msgid "unsupported LDAP uri type: %s"
+msgstr "不支持的 LDAP URI 类型:%s"
+
+#: plugins/sudoers/ldap_conf.c:290
+msgid "unable to mix ldap and ldaps URIs"
+msgstr "无法混合 ldap 和 ldaps URI"
+
+#: plugins/sudoers/ldap_util.c:454 plugins/sudoers/ldap_util.c:456
+#, c-format
+msgid "unable to convert sudoOption: %s%s%s"
+msgstr "无法转换 sudoOption: %s%s%s"
+
+#: plugins/sudoers/linux_audit.c:57
+msgid "unable to open audit system"
+msgstr "无法打开审核系统"
+
+#: plugins/sudoers/linux_audit.c:98
+msgid "unable to send audit message"
+msgstr "无法发送审核消息"
+
+#: plugins/sudoers/logging.c:113
+#, c-format
+msgid "%8s : %s"
+msgstr "%8s:%s"
+
+#: plugins/sudoers/logging.c:141
+#, c-format
+msgid "%8s : (command continued) %s"
+msgstr "%8s:(命令继续执行) %s"
+
+#: plugins/sudoers/logging.c:170
+#, c-format
+msgid "unable to open log file: %s"
+msgstr "无法打开日志文件:%s"
+
+#: plugins/sudoers/logging.c:178
+#, c-format
+msgid "unable to lock log file: %s"
+msgstr "无法锁定日志文件:%s"
+
+#: plugins/sudoers/logging.c:211
+#, c-format
+msgid "unable to write log file: %s"
+msgstr "无法写入日志文件: %s"
+
+#: plugins/sudoers/logging.c:240
+msgid "No user or host"
+msgstr "无用户或主机"
+
+#: plugins/sudoers/logging.c:242
+msgid "validation failure"
+msgstr "校验失败"
+
+#: plugins/sudoers/logging.c:249
+msgid "user NOT in sudoers"
+msgstr "用户不在 sudoers 中"
+
+#: plugins/sudoers/logging.c:251
+msgid "user NOT authorized on host"
+msgstr "用户未获得此主机上的授权"
+
+#: plugins/sudoers/logging.c:253
+msgid "command not allowed"
+msgstr "命令禁止使用"
+
+#: plugins/sudoers/logging.c:288
+#, c-format
+msgid "%s is not in the sudoers file. This incident will be reported.\n"
+msgstr "%s 不在 sudoers 文件中。此事将被报告。\n"
+
+#: plugins/sudoers/logging.c:291
+#, c-format
+msgid "%s is not allowed to run sudo on %s. This incident will be reported.\n"
+msgstr "%s 无权在 %s 上运行 sudo。此事将被报告。\n"
+
+#: plugins/sudoers/logging.c:295
+#, c-format
+msgid "Sorry, user %s may not run sudo on %s.\n"
+msgstr "对不起,用户 %s 不能在 %s 上运行 sudo。\n"
+
+#: plugins/sudoers/logging.c:298
+#, c-format
+msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
+msgstr "对不起,用户 %1$s 无权以 %5$s%6$s%7$s 的身份在 %8$s 上执行 %2$s%3$s%4$s。\n"
+
+#: plugins/sudoers/logging.c:335 plugins/sudoers/sudoers.c:438
+#: plugins/sudoers/sudoers.c:440 plugins/sudoers/sudoers.c:442
+#: plugins/sudoers/sudoers.c:444 plugins/sudoers/sudoers.c:599
+#: plugins/sudoers/sudoers.c:601
+#, c-format
+msgid "%s: command not found"
+msgstr "%s:找不到命令"
+
+#: plugins/sudoers/logging.c:337 plugins/sudoers/sudoers.c:434
+#, c-format
+msgid ""
+"ignoring \"%s\" found in '.'\n"
+"Use \"sudo ./%s\" if this is the \"%s\" you wish to run."
+msgstr ""
+"忽略在“.”中找到的“%s”\n"
+"请使用“sudo ./%s”,如果这是您想运行的“%s”。"
+
+#: plugins/sudoers/logging.c:354
+msgid "authentication failure"
+msgstr "认证失败"
+
+#: plugins/sudoers/logging.c:380
+msgid "a password is required"
+msgstr "需要密码"
+
+#: plugins/sudoers/logging.c:443
+#, c-format
+msgid "%u incorrect password attempt"
+msgid_plural "%u incorrect password attempts"
+msgstr[0] "%u 次错误密码尝试"
+
+#: plugins/sudoers/logging.c:666
+msgid "unable to fork"
+msgstr "无法执行 fork"
+
+#: plugins/sudoers/logging.c:674 plugins/sudoers/logging.c:726
+#, c-format
+msgid "unable to fork: %m"
+msgstr "无法执行 fork:%m"
+
+#: plugins/sudoers/logging.c:716
+#, c-format
+msgid "unable to open pipe: %m"
+msgstr "无法打开管道:%m"
+
+#: plugins/sudoers/logging.c:741
+#, c-format
+msgid "unable to dup stdin: %m"
+msgstr "无法 dup stdin:%m"
+
+#: plugins/sudoers/logging.c:779
+#, c-format
+msgid "unable to execute %s: %m"
+msgstr "无法执行 %s:%m"
+
+#: plugins/sudoers/match.c:874
+#, c-format
+msgid "digest for %s (%s) is not in %s form"
+msgstr "%s(%s) 的摘要不是 %s 形式"
+
+#: plugins/sudoers/mkdir_parents.c:75 plugins/sudoers/sudoers.c:918
+#: plugins/sudoers/visudo.c:421 plugins/sudoers/visudo.c:717
+#, c-format
+msgid "unable to stat %s"
+msgstr "无法 stat %s"
+
+#: plugins/sudoers/parse.c:444
+#, c-format
+msgid ""
+"\n"
+"LDAP Role: %s\n"
+msgstr ""
+"\n"
+"LDAP 角色:%s\n"
+
+#: plugins/sudoers/parse.c:447
+#, c-format
+msgid ""
+"\n"
+"Sudoers entry:\n"
+msgstr ""
+"\n"
+"Sudoers 条目:\n"
+
+#: plugins/sudoers/parse.c:449
+#, c-format
+msgid " RunAsUsers: "
+msgstr " RunAs 用户:"
+
+#: plugins/sudoers/parse.c:464
+#, c-format
+msgid " RunAsGroups: "
+msgstr " RunAs 组:"
+
+#: plugins/sudoers/parse.c:474
+#, c-format
+msgid " Options: "
+msgstr " 选项:"
+
+#: plugins/sudoers/parse.c:528
+#, c-format
+msgid " Commands:\n"
+msgstr " 命令:\n"
+
+#: plugins/sudoers/parse.c:719
+#, c-format
+msgid "Matching Defaults entries for %s on %s:\n"
+msgstr "匹配 %2$s 上 %1$s 的默认条目:\n"
+
+#: plugins/sudoers/parse.c:737
+#, c-format
+msgid "Runas and Command-specific defaults for %s:\n"
+msgstr "%s Runas 和命令特定的默认值:\n"
+
+#: plugins/sudoers/parse.c:755
+#, c-format
+msgid "User %s may run the following commands on %s:\n"
+msgstr "用户 %s 可以在 %s 上运行以下命令:\n"
+
+#: plugins/sudoers/parse.c:770
+#, c-format
+msgid "User %s is not allowed to run sudo on %s.\n"
+msgstr "用户 %s 无权在 %s 上运行 sudo。\n"
+
+#: plugins/sudoers/parse_ldif.c:145
+#, c-format
+msgid "ignoring invalid attribute value: %s"
+msgstr "将忽略无效的属性值:%s"
+
+#: plugins/sudoers/parse_ldif.c:584
+#, c-format
+msgid "ignoring incomplete sudoRole: cn: %s"
+msgstr "将忽略不完整的 sudoRole:cn:%s"
+
+#: plugins/sudoers/policy.c:88 plugins/sudoers/policy.c:114
+#, c-format
+msgid "invalid %.*s set by sudo front-end"
+msgstr "sudo 前端设置了无效的 %.*s"
+
+#: plugins/sudoers/policy.c:293 plugins/sudoers/testsudoers.c:278
+msgid "unable to parse network address list"
+msgstr "无法解析网络地址列表"
+
+#: plugins/sudoers/policy.c:437
+msgid "user name not set by sudo front-end"
+msgstr "用户名未通过 sudo 前端设置"
+
+#: plugins/sudoers/policy.c:441
+msgid "user ID not set by sudo front-end"
+msgstr "用户 ID 未通过 sudo 前端设置"
+
+#: plugins/sudoers/policy.c:445
+msgid "group ID not set by sudo front-end"
+msgstr "组 ID 未通过 sudo 前端设置"
+
+#: plugins/sudoers/policy.c:449
+msgid "host name not set by sudo front-end"
+msgstr "主机名未通过 sudo 前端设置"
+
+#: plugins/sudoers/policy.c:802 plugins/sudoers/visudo.c:220
+#: plugins/sudoers/visudo.c:851
+#, c-format
+msgid "unable to execute %s"
+msgstr "无法执行 %s"
+
+#: plugins/sudoers/policy.c:933
+#, c-format
+msgid "Sudoers policy plugin version %s\n"
+msgstr "Sudoers 策略插件版本 %s\n"
+
+#: plugins/sudoers/policy.c:935
+#, c-format
+msgid "Sudoers file grammar version %d\n"
+msgstr "Sudoers 文件语法版本 %d\n"
+
+#: plugins/sudoers/policy.c:939
+#, c-format
+msgid ""
+"\n"
+"Sudoers path: %s\n"
+msgstr ""
+"\n"
+"Sudoers 路径:%s\n"
+
+#: plugins/sudoers/policy.c:942
+#, c-format
+msgid "nsswitch path: %s\n"
+msgstr "nsswitch 路径:%s\n"
+
+#: plugins/sudoers/policy.c:944
+#, c-format
+msgid "ldap.conf path: %s\n"
+msgstr "ldap.conf 路径:%s\n"
+
+#: plugins/sudoers/policy.c:945
+#, c-format
+msgid "ldap.secret path: %s\n"
+msgstr "ldap.secret 路径:%s\n"
+
+#: plugins/sudoers/policy.c:978
+#, c-format
+msgid "unable to register hook of type %d (version %d.%d)"
+msgstr "无法注册类型为 %d 的钩子(hook)(版本 %d.%d)"
+
+#: plugins/sudoers/pwutil.c:220 plugins/sudoers/pwutil.c:239
+#, c-format
+msgid "unable to cache uid %u, out of memory"
+msgstr "无法缓存用户 ID %u,内存不足"
+
+#: plugins/sudoers/pwutil.c:233
+#, c-format
+msgid "unable to cache uid %u, already exists"
+msgstr "无法缓存用户 ID %u,已存在"
+
+#: plugins/sudoers/pwutil.c:293 plugins/sudoers/pwutil.c:311
+#: plugins/sudoers/pwutil.c:373 plugins/sudoers/pwutil.c:418
+#, c-format
+msgid "unable to cache user %s, out of memory"
+msgstr "无法缓存用户 %s,内存不足"
+
+#: plugins/sudoers/pwutil.c:306
+#, c-format
+msgid "unable to cache user %s, already exists"
+msgstr "无法缓存用户 %s,已存在"
+
+#: plugins/sudoers/pwutil.c:537 plugins/sudoers/pwutil.c:556
+#, c-format
+msgid "unable to cache gid %u, out of memory"
+msgstr "无法缓存组 ID %u,内存不足"
+
+#: plugins/sudoers/pwutil.c:550
+#, c-format
+msgid "unable to cache gid %u, already exists"
+msgstr "无法缓存组 ID %u,已存在"
+
+#: plugins/sudoers/pwutil.c:604 plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:669 plugins/sudoers/pwutil.c:711
+#, c-format
+msgid "unable to cache group %s, out of memory"
+msgstr "无法缓存组 %s,内存不足"
+
+#: plugins/sudoers/pwutil.c:617
+#, c-format
+msgid "unable to cache group %s, already exists"
+msgstr "无法缓存组 %s,已存在"
+
+#: plugins/sudoers/pwutil.c:837 plugins/sudoers/pwutil.c:889
+#: plugins/sudoers/pwutil.c:940 plugins/sudoers/pwutil.c:993
+#, c-format
+msgid "unable to cache group list for %s, already exists"
+msgstr "无法缓存组列表 %s,已存在"
+
+#: plugins/sudoers/pwutil.c:843 plugins/sudoers/pwutil.c:894
+#: plugins/sudoers/pwutil.c:946 plugins/sudoers/pwutil.c:998
+#, c-format
+msgid "unable to cache group list for %s, out of memory"
+msgstr "无法缓存组列表 %s,内存不足"
+
+#: plugins/sudoers/pwutil.c:883
+#, c-format
+msgid "unable to parse groups for %s"
+msgstr "无法对 %s 解析组"
+
+#: plugins/sudoers/pwutil.c:987
+#, c-format
+msgid "unable to parse gids for %s"
+msgstr "无法解析 %s 的组 ID"
+
+#: plugins/sudoers/set_perms.c:118 plugins/sudoers/set_perms.c:474
+#: plugins/sudoers/set_perms.c:917 plugins/sudoers/set_perms.c:1244
+#: plugins/sudoers/set_perms.c:1561
+msgid "perm stack overflow"
+msgstr "权限堆栈上溢"
+
+#: plugins/sudoers/set_perms.c:126 plugins/sudoers/set_perms.c:405
+#: plugins/sudoers/set_perms.c:482 plugins/sudoers/set_perms.c:784
+#: plugins/sudoers/set_perms.c:925 plugins/sudoers/set_perms.c:1168
+#: plugins/sudoers/set_perms.c:1252 plugins/sudoers/set_perms.c:1494
+#: plugins/sudoers/set_perms.c:1569 plugins/sudoers/set_perms.c:1659
+msgid "perm stack underflow"
+msgstr "权限堆栈下溢"
+
+#: plugins/sudoers/set_perms.c:185 plugins/sudoers/set_perms.c:528
+#: plugins/sudoers/set_perms.c:1303 plugins/sudoers/set_perms.c:1601
+msgid "unable to change to root gid"
+msgstr "无法切换为 root 组 ID"
+
+#: plugins/sudoers/set_perms.c:274 plugins/sudoers/set_perms.c:625
+#: plugins/sudoers/set_perms.c:1054 plugins/sudoers/set_perms.c:1380
+msgid "unable to change to runas gid"
+msgstr "无法切换为 runas 组 ID"
+
+#: plugins/sudoers/set_perms.c:279 plugins/sudoers/set_perms.c:630
+#: plugins/sudoers/set_perms.c:1059 plugins/sudoers/set_perms.c:1385
+msgid "unable to set runas group vector"
+msgstr "无法设置 runas 组向量"
+
+#: plugins/sudoers/set_perms.c:290 plugins/sudoers/set_perms.c:641
+#: plugins/sudoers/set_perms.c:1068 plugins/sudoers/set_perms.c:1394
+msgid "unable to change to runas uid"
+msgstr "无法切换为 runas 用户 ID"
+
+#: plugins/sudoers/set_perms.c:308 plugins/sudoers/set_perms.c:659
+#: plugins/sudoers/set_perms.c:1084 plugins/sudoers/set_perms.c:1410
+msgid "unable to change to sudoers gid"
+msgstr "无法切换为 sudoers 组 ID"
+
+#: plugins/sudoers/set_perms.c:392 plugins/sudoers/set_perms.c:771
+#: plugins/sudoers/set_perms.c:1155 plugins/sudoers/set_perms.c:1481
+#: plugins/sudoers/set_perms.c:1646
+msgid "too many processes"
+msgstr "进程过多"
+
+#: plugins/sudoers/solaris_audit.c:56
+msgid "unable to get current working directory"
+msgstr "无法获取当前工作目录"
+
+#: plugins/sudoers/solaris_audit.c:64
+#, c-format
+msgid "truncated audit path user_cmnd: %s"
+msgstr "截断的审核路径 user_cmnd:%s"
+
+#: plugins/sudoers/solaris_audit.c:71
+#, c-format
+msgid "truncated audit path argv[0]: %s"
+msgstr "截断的审核路径 argv[0]:%s"
+
+#: plugins/sudoers/solaris_audit.c:120
+msgid "audit_failure message too long"
+msgstr "audit_failure(审核失败)消息过长"
+
+#: plugins/sudoers/sssd.c:563
+msgid "unable to initialize SSS source. Is SSSD installed on your machine?"
+msgstr "无法初始化 SSS 资源。您的计算机上安装 SSSD 了吗?"
+
+#: plugins/sudoers/sssd.c:571 plugins/sudoers/sssd.c:580
+#: plugins/sudoers/sssd.c:589 plugins/sudoers/sssd.c:598
+#: plugins/sudoers/sssd.c:607
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "无法在 %s 中找到符号“%s”"
+
+#: plugins/sudoers/sudoers.c:208 plugins/sudoers/sudoers.c:864
+msgid "problem with defaults entries"
+msgstr "默认条目有问题"
+
+#: plugins/sudoers/sudoers.c:212
+msgid "no valid sudoers sources found, quitting"
+msgstr "没有找到有效的 sudoers 资源,退出"
+
+#: plugins/sudoers/sudoers.c:250
+msgid "sudoers specifies that root is not allowed to sudo"
+msgstr "sudoers 指定 root 不允许执行 sudo"
+
+#: plugins/sudoers/sudoers.c:308
+msgid "you are not permitted to use the -C option"
+msgstr "您无权使用 -C 选项"
+
+#: plugins/sudoers/sudoers.c:355
+#, c-format
+msgid "timestamp owner (%s): No such user"
+msgstr "时间戳所有者(%s):无此用户"
+
+#: plugins/sudoers/sudoers.c:370
+msgid "no tty"
+msgstr "无终端"
+
+#: plugins/sudoers/sudoers.c:371
+msgid "sorry, you must have a tty to run sudo"
+msgstr "抱歉,您必须拥有一个终端来执行 sudo"
+
+#: plugins/sudoers/sudoers.c:433
+msgid "command in current directory"
+msgstr "当前目录中的命令"
+
+#: plugins/sudoers/sudoers.c:452
+msgid "sorry, you are not allowed set a command timeout"
+msgstr "抱歉,您无权设置超时时间"
+
+#: plugins/sudoers/sudoers.c:460
+msgid "sorry, you are not allowed to preserve the environment"
+msgstr "抱歉,您无权保留环境"
+
+#: plugins/sudoers/sudoers.c:808
+msgid "command too long"
+msgstr "命令过长"
+
+#: plugins/sudoers/sudoers.c:922
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s 不是常规文件"
+
+#: plugins/sudoers/sudoers.c:926 plugins/sudoers/timestamp.c:257 toke.l:965
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s 属于用户 ID %u,应为 %u"
+
+#: plugins/sudoers/sudoers.c:930 toke.l:970
+#, c-format
+msgid "%s is world writable"
+msgstr "%s 可被任何人写"
+
+#: plugins/sudoers/sudoers.c:934 toke.l:973
+#, c-format
+msgid "%s is owned by gid %u, should be %u"
+msgstr "%s 属于组 ID %u,应为 %u"
+
+#: plugins/sudoers/sudoers.c:967
+#, c-format
+msgid "only root can use \"-c %s\""
+msgstr "只有 root 才能使用“-c %s”"
+
+#: plugins/sudoers/sudoers.c:986
+#, c-format
+msgid "unknown login class: %s"
+msgstr "未知的登录类别:%s"
+
+#: plugins/sudoers/sudoers.c:1069 plugins/sudoers/sudoers.c:1083
+#, c-format
+msgid "unable to resolve host %s"
+msgstr "无法解析主机:%s"
+
+#: plugins/sudoers/sudoreplay.c:248
+#, c-format
+msgid "invalid filter option: %s"
+msgstr "无效的过滤器选项:%s"
+
+#: plugins/sudoers/sudoreplay.c:261
+#, c-format
+msgid "invalid max wait: %s"
+msgstr "无效的最大等待:%s"
+
+#: plugins/sudoers/sudoreplay.c:284
+#, c-format
+msgid "invalid speed factor: %s"
+msgstr "无法的速度系数:%s"
+
+#: plugins/sudoers/sudoreplay.c:319
+#, c-format
+msgid "%s/%.2s/%.2s/%.2s/timing: %s"
+msgstr "%s/%.2s/%.2s/%.2s/时序:%s"
+
+#: plugins/sudoers/sudoreplay.c:325
+#, c-format
+msgid "%s/%s/timing: %s"
+msgstr "%s/%s/时序:%s"
+
+#: plugins/sudoers/sudoreplay.c:341
+#, c-format
+msgid "Replaying sudo session: %s"
+msgstr "回放 sudo 会话:%s"
+
+#: plugins/sudoers/sudoreplay.c:539 plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:783 plugins/sudoers/sudoreplay.c:892
+#: plugins/sudoers/sudoreplay.c:977 plugins/sudoers/sudoreplay.c:992
+#: plugins/sudoers/sudoreplay.c:999 plugins/sudoers/sudoreplay.c:1006
+#: plugins/sudoers/sudoreplay.c:1013 plugins/sudoers/sudoreplay.c:1020
+#: plugins/sudoers/sudoreplay.c:1168
+msgid "unable to add event to queue"
+msgstr "无法将事件添加到队列"
+
+#: plugins/sudoers/sudoreplay.c:654
+msgid "unable to set tty to raw mode"
+msgstr "无法将终端设为原始模式"
+
+#: plugins/sudoers/sudoreplay.c:705
+#, c-format
+msgid "Warning: your terminal is too small to properly replay the log.\n"
+msgstr "警告:您的终端尺寸太小,不能正常地回放日志。\n"
+
+#: plugins/sudoers/sudoreplay.c:706
+#, c-format
+msgid "Log geometry is %d x %d, your terminal's geometry is %d x %d."
+msgstr "日志的几何尺寸为 %dx%d,您终端的几何尺寸为 %dx%d。"
+
+#: plugins/sudoers/sudoreplay.c:734
+msgid "Replay finished, press any key to restore the terminal."
+msgstr "回放完成,请按任意键返回终端。"
+
+#: plugins/sudoers/sudoreplay.c:766
+#, c-format
+msgid "invalid timing file line: %s"
+msgstr "无效的时序文件行:%s"
+
+#: plugins/sudoers/sudoreplay.c:1202 plugins/sudoers/sudoreplay.c:1227
+#, c-format
+msgid "ambiguous expression \"%s\""
+msgstr "有歧义的表达式“%s”"
+
+#: plugins/sudoers/sudoreplay.c:1249
+msgid "unmatched ')' in expression"
+msgstr "表达式中的“)”不匹配"
+
+#: plugins/sudoers/sudoreplay.c:1253
+#, c-format
+msgid "unknown search term \"%s\""
+msgstr "未知的搜索词“%s”"
+
+#: plugins/sudoers/sudoreplay.c:1268
+#, c-format
+msgid "%s requires an argument"
+msgstr "%s 需要参数"
+
+#: plugins/sudoers/sudoreplay.c:1271 plugins/sudoers/sudoreplay.c:1512
+#, c-format
+msgid "invalid regular expression: %s"
+msgstr "无效的正则表达式:%s"
+
+#: plugins/sudoers/sudoreplay.c:1275
+#, c-format
+msgid "could not parse date \"%s\""
+msgstr "无法解析日期“%s”"
+
+#: plugins/sudoers/sudoreplay.c:1284
+msgid "unmatched '(' in expression"
+msgstr "表达式中的“(”不匹配"
+
+#: plugins/sudoers/sudoreplay.c:1286
+msgid "illegal trailing \"or\""
+msgstr "非法的结尾字符“or”"
+
+#: plugins/sudoers/sudoreplay.c:1288
+msgid "illegal trailing \"!\""
+msgstr "非法的结尾字符“!”"
+
+#: plugins/sudoers/sudoreplay.c:1338
+#, c-format
+msgid "unknown search type %d"
+msgstr "未知的搜索类型 %d"
+
+#: plugins/sudoers/sudoreplay.c:1605
+#, c-format
+msgid "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"
+msgstr "用法:%s [-hnRS] [-d 目录] [-m 数值] [-s 数值] ID\n"
+
+#: plugins/sudoers/sudoreplay.c:1608
+#, c-format
+msgid "usage: %s [-h] [-d dir] -l [search expression]\n"
+msgstr "用法:%s [-h] [-d 目录] -l [搜索表达式]\n"
+
+#: plugins/sudoers/sudoreplay.c:1617
+#, c-format
+msgid ""
+"%s - replay sudo session logs\n"
+"\n"
+msgstr ""
+"%s - 回放 sudo 会话记录\n"
+"\n"
+
+#: plugins/sudoers/sudoreplay.c:1619
+msgid ""
+"\n"
+"Options:\n"
+" -d, --directory=dir specify directory for session logs\n"
+" -f, --filter=filter specify which I/O type(s) to display\n"
+" -h, --help display help message and exit\n"
+" -l, --list list available session IDs, with optional expression\n"
+" -m, --max-wait=num max number of seconds to wait between events\n"
+" -S, --suspend-wait wait while the command was suspended\n"
+" -s, --speed=num speed up or slow down output\n"
+" -V, --version display version information and exit"
+msgstr ""
+"\n"
+"选项:\n"
+" -d, --directory=目录 指定会话日志目录\n"
+" -f, --filter=过滤器 指定要显示的 I/O 类型\n"
+" -h, --help 显示帮助信息并退出\n"
+" -l, --list 列出可用会话 ID,可加表达式限定\n"
+" -m, --max-wait=数值 事件间等待的最大秒数\n"
+" -S, --suspend-wait 在命令挂起时等待\n"
+" -s, --speed=数值 加速或减慢输出\n"
+" -V, --version 显示版本信息并退出"
+
+#: plugins/sudoers/testsudoers.c:360
+msgid "\thost unmatched"
+msgstr "\t主机不匹配"
+
+#: plugins/sudoers/testsudoers.c:363
+msgid ""
+"\n"
+"Command allowed"
+msgstr ""
+"\n"
+"命令允许"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command denied"
+msgstr ""
+"\n"
+"命令被拒"
+
+#: plugins/sudoers/testsudoers.c:364
+msgid ""
+"\n"
+"Command unmatched"
+msgstr ""
+"\n"
+"命令不匹配"
+
+#: plugins/sudoers/timestamp.c:265
+#, c-format
+msgid "%s is group writable"
+msgstr "%s 可被组写"
+
+#: plugins/sudoers/timestamp.c:341
+#, c-format
+msgid "unable to truncate time stamp file to %lld bytes"
+msgstr "无法将时间戳文件截短为 %lld 字节"
+
+#: plugins/sudoers/timestamp.c:827 plugins/sudoers/timestamp.c:919
+#: plugins/sudoers/visudo.c:482 plugins/sudoers/visudo.c:488
+msgid "unable to read the clock"
+msgstr "无法读取时钟"
+
+#: plugins/sudoers/timestamp.c:838
+msgid "ignoring time stamp from the future"
+msgstr "将忽略超前的时间戳"
+
+#: plugins/sudoers/timestamp.c:861
+#, c-format
+msgid "time stamp too far in the future: %20.20s"
+msgstr "时间戳太超前:%20.20s"
+
+#: plugins/sudoers/timestamp.c:983
+#, c-format
+msgid "unable to lock time stamp file %s"
+msgstr "无法锁定时间戳文件 %s"
+
+#: plugins/sudoers/timestamp.c:1027 plugins/sudoers/timestamp.c:1047
+#, c-format
+msgid "lecture status path too long: %s/%s"
+msgstr "致辞(lecture)状态路径过长:%s/%s"
+
+#: plugins/sudoers/visudo.c:216
+msgid "the -x option will be removed in a future release"
+msgstr "未来版本中 -x 选项会移除"
+
+#: plugins/sudoers/visudo.c:217
+msgid "please consider using the cvtsudoers utility instead"
+msgstr "请考虑换用 cvtsudoers 工具"
+
+#: plugins/sudoers/visudo.c:268 plugins/sudoers/visudo.c:650
+#, c-format
+msgid "press return to edit %s: "
+msgstr "按回车键编辑 %s:"
+
+#: plugins/sudoers/visudo.c:329
+#, c-format
+msgid "specified editor (%s) doesn't exist"
+msgstr "指定的编辑器(%s)不存在"
+
+#: plugins/sudoers/visudo.c:331
+#, c-format
+msgid "no editor found (editor path = %s)"
+msgstr "未找到编辑器(编辑器路径 = %s)"
+
+#: plugins/sudoers/visudo.c:441 plugins/sudoers/visudo.c:449
+msgid "write error"
+msgstr "写错误"
+
+#: plugins/sudoers/visudo.c:495
+#, c-format
+msgid "unable to stat temporary file (%s), %s unchanged"
+msgstr "无法 stat 临时文件(%s),%s 未更改"
+
+#: plugins/sudoers/visudo.c:502
+#, c-format
+msgid "zero length temporary file (%s), %s unchanged"
+msgstr "零长度的临时文件(%s),%s 未更改"
+
+#: plugins/sudoers/visudo.c:508
+#, c-format
+msgid "editor (%s) failed, %s unchanged"
+msgstr "编辑器(%s)失败,%s 未更改"
+
+#: plugins/sudoers/visudo.c:530
+#, c-format
+msgid "%s unchanged"
+msgstr "%s 未更改"
+
+#: plugins/sudoers/visudo.c:589
+#, c-format
+msgid "unable to re-open temporary file (%s), %s unchanged."
+msgstr "无法重新打开临时文件(%s),%s 未更改"
+
+#: plugins/sudoers/visudo.c:601
+#, c-format
+msgid "unabled to parse temporary file (%s), unknown error"
+msgstr "无法解析临时文件(%s),未知错误"
+
+#: plugins/sudoers/visudo.c:639
+#, c-format
+msgid "internal error, unable to find %s in list!"
+msgstr "内部错误,在列表中找不到 %s!"
+
+#: plugins/sudoers/visudo.c:719 plugins/sudoers/visudo.c:728
+#, c-format
+msgid "unable to set (uid, gid) of %s to (%u, %u)"
+msgstr "无法将 %s 的 (uid, gid) 设为 (%u, %u)"
+
+#: plugins/sudoers/visudo.c:751
+#, c-format
+msgid "%s and %s not on the same file system, using mv to rename"
+msgstr "%s 和 %s 不在同一个文件系统,使用 mv 进行重命名"
+
+#: plugins/sudoers/visudo.c:765
+#, c-format
+msgid "command failed: '%s %s %s', %s unchanged"
+msgstr "命令失败:“%s %s %s”,%s 未更改"
+
+#: plugins/sudoers/visudo.c:775
+#, c-format
+msgid "error renaming %s, %s unchanged"
+msgstr "重命名 %s 出错,%s 未更改"
+
+#: plugins/sudoers/visudo.c:796
+msgid "What now? "
+msgstr "现在做什么?"
+
+#: plugins/sudoers/visudo.c:810
+msgid ""
+"Options are:\n"
+" (e)dit sudoers file again\n"
+" e(x)it without saving changes to sudoers file\n"
+" (Q)uit and save changes to sudoers file (DANGER!)\n"
+msgstr ""
+"选项有:\n"
+" 重新编辑 sudoers 文件(e)\n"
+" 退出,不保存对 sudoers 文件的更改(x)\n"
+" 退出并将更改保存到 sudoers 文件(危险!)(Q)\n"
+
+#: plugins/sudoers/visudo.c:856
+#, c-format
+msgid "unable to run %s"
+msgstr "无法运行 %s"
+
+#: plugins/sudoers/visudo.c:886
+#, c-format
+msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
+msgstr "%s:错误的所有者(uid, gid),应为 (%u, %u)\n"
+
+#: plugins/sudoers/visudo.c:893
+#, c-format
+msgid "%s: bad permissions, should be mode 0%o\n"
+msgstr "%s:权限不正确,模式应该是 0%o\n"
+
+#: plugins/sudoers/visudo.c:950 plugins/sudoers/visudo.c:957
+#, c-format
+msgid "%s: parsed OK\n"
+msgstr "%s:解析正确\n"
+
+#: plugins/sudoers/visudo.c:976
+#, c-format
+msgid "%s busy, try again later"
+msgstr "%s 忙,请稍后重试"
+
+#: plugins/sudoers/visudo.c:979
+#, c-format
+msgid "unable to lock %s"
+msgstr "无法锁定 %s"
+
+#: plugins/sudoers/visudo.c:980
+msgid "Edit anyway? [y/N]"
+msgstr "仍然编辑?[y/N]"
+
+#: plugins/sudoers/visudo.c:1064
+#, c-format
+msgid "Error: %s:%d cycle in %s \"%s\""
+msgstr "错误:%s:%d 在 %s “%s”中循环"
+
+#: plugins/sudoers/visudo.c:1065
+#, c-format
+msgid "Warning: %s:%d cycle in %s \"%s\""
+msgstr "警告:%s:%d 在 %s “%s”中循环"
+
+#: plugins/sudoers/visudo.c:1069
+#, c-format
+msgid "Error: %s:%d %s \"%s\" referenced but not defined"
+msgstr "错误:%s:%d 引用了 %s “%s”但尚未定义"
+
+#: plugins/sudoers/visudo.c:1070
+#, c-format
+msgid "Warning: %s:%d %s \"%s\" referenced but not defined"
+msgstr "警告:%s:%d 引用了 %s “%s”但尚未定义"
+
+#: plugins/sudoers/visudo.c:1161
+#, c-format
+msgid "Warning: %s:%d unused %s \"%s\""
+msgstr "警告:%s:%d 未使用的 %s “%s”"
+
+#: plugins/sudoers/visudo.c:1276
+#, c-format
+msgid ""
+"%s - safely edit the sudoers file\n"
+"\n"
+msgstr ""
+"%s - 安全地编辑 sudoers 文件\n"
+"\n"
+
+#: plugins/sudoers/visudo.c:1278
+msgid ""
+"\n"
+"Options:\n"
+" -c, --check check-only mode\n"
+" -f, --file=sudoers specify sudoers file location\n"
+" -h, --help display help message and exit\n"
+" -q, --quiet less verbose (quiet) syntax error messages\n"
+" -s, --strict strict syntax checking\n"
+" -V, --version display version information and exit\n"
+msgstr ""
+"\n"
+"选项:\n"
+" -c, --check 纯检查模式\n"
+" -f, --file=sudoers 指定 sudoers 文件的位置\n"
+" -h, --help 显示帮助信息并退出\n"
+" -q, --quiet 较简略(安静)的语法错误信息\n"
+" -s, --strict 严格语法检查\n"
+" -V, --version 显示版本信息并退出\n"
+
+#: toke.l:939
+msgid "too many levels of includes"
+msgstr "include 嵌套层数过多"
+
+#~ msgid ""
+#~ "\n"
+#~ "LDAP Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "LDAP 角色:未知\n"
+
+#~ msgid " Order: %s\n"
+#~ msgstr " 顺序:%s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: %s\n"
+#~ msgstr ""
+#~ "\n"
+#~ "SSSD 角色:%s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "SSSD Role: UNKNOWN\n"
+#~ msgstr ""
+#~ "\n"
+#~ "SSSD 角色:未知\n"
+
+#~ msgid "Warning: cycle in %s `%s'"
+#~ msgstr "警告:在 %s “%s”中循环"
+
+#~ msgid "Warning: %s `%s' referenced but not defined"
+#~ msgstr "警告:引用了 %s “%s”但尚未定义"
+
+#~ msgid "Warning: unused %s `%s'"
+#~ msgstr "警告:%s “%s”未使用"
+
+#~ msgid "unable allocate memory"
+#~ msgstr "无法分配内存"
+
+#~ msgid "timestamp path too long: %s/%s"
+#~ msgstr "时间戳路径过长:%s/%s"
+
+#~ msgid "unable to stat editor (%s)"
+#~ msgstr "无法 stat 编辑器(%s)"
+
+#~ msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
+#~ msgstr "sudo_ldap_conf_add_ports:扩展主机缓存时空间不足"
+
+#~ msgid "sudo_ldap_parse_uri: out of space building hostbuf"
+#~ msgstr "sudo_ldap_parse_uri:构建主机缓存时空间不足"
+
+#~ msgid "sudo_ldap_build_pass1 allocation mismatch"
+#~ msgstr "sudo_ldap_build_pass1 分配不匹配"
+
+#~ msgid "Password:"
+#~ msgstr "密码:"
+
+#~ msgid "internal error: insufficient space for log line"
+#~ msgstr "内部错误:没有足够的空间存放日志行"
+
+#~ msgid "fill_args: buffer overflow"
+#~ msgstr "fill_args:缓存溢出"
+
+#~ msgid "%s owned by uid %u, should be uid %u"
+#~ msgstr "%s 属于用户 ID %u,应为用户 ID %u"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0700"
+#~ msgstr "%s 对非所有者可写(0%o),模式应该为 0700"
+
+#~ msgid "%s exists but is not a regular file (0%o)"
+#~ msgstr "%s 存在,但不是常规文件(0%o)"
+
+#~ msgid "%s writable by non-owner (0%o), should be mode 0600"
+#~ msgstr "%s 对非所有者可写(0%o),模式应该为 0600"
+
+#~ msgid "unable to remove %s, will reset to the Unix epoch"
+#~ msgstr "无法移除 %s ,将重设为 Unix 戳记"
+
+#~ msgid "unable to reset %s to the Unix epoch"
+#~ msgstr "无法将 %s 重设为 Unix 戳记"
+
+#~ msgid "value out of range"
+#~ msgstr "值超出范围"
+
+#~ msgid "invalid uri: %s"
+#~ msgstr "无效的 URI:%s"
+
+#~ msgid "unable to mix ldaps and starttls"
+#~ msgstr "无法混合 ldaps 和 starttls"
+
+#~ msgid "writing to standard output"
+#~ msgstr "写入标准输出"
+
+#~ msgid "too many parenthesized expressions, max %d"
+#~ msgstr "括号表达式过多,最多 %d"
+
+#~ msgid "unable to setup authentication"
+#~ msgstr "无法设置认证"
+
+#~ msgid "getaudit: failed"
+#~ msgstr "getaudit:失败"
+
+#~ msgid "getauid: failed"
+#~ msgstr "getauid:失败"
+
+#~ msgid "au_to_subject: failed"
+#~ msgstr "au_to_subject:失败"
+
+#~ msgid "au_to_exec_args: failed"
+#~ msgstr "au_to_exec_args:失败"
+
+#~ msgid "au_to_return32: failed"
+#~ msgstr "au_to_return32:失败"
+
+#~ msgid "au_to_text: failed"
+#~ msgstr "au_to_text:失败"
+
+#~ msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
+#~ msgstr "nanosleep:tv_sec %ld,tv_nsec %ld"
+
+#~ msgid "pam_chauthtok: %s"
+#~ msgstr "pam_chauthtok:%s"
+
+#~ msgid "pam_authenticate: %s"
+#~ msgstr "pam_authenticate:%s"
+
+#~ msgid "getauid failed"
+#~ msgstr "getauid 失败"
+
+#~ msgid "Unable to dlopen %s: %s"
+#~ msgstr "无法执行 dlopen %s:%s"
+
+#~ msgid "invalid regex: %s"
+#~ msgstr "无效的正则表达式:%s"
+
+#~ msgid ">>> %s: %s near line %d <<<"
+#~ msgstr ">>> %s:%s 在行 %d 附近<<<"
+
+#~ msgid "unable to set locale to \"%s\", using \"C\""
+#~ msgstr "无法将区域设置为“%s”,将使用“C”"
+
+#~ msgid ""
+#~ " Commands:\n"
+#~ "\t"
+#~ msgstr ""
+#~ " 命令:\n"
+#~ "\t"
+
+#~ msgid ": "
+#~ msgstr ":"
+
+#~ msgid "unable to cache uid %u (%s), already exists"
+#~ msgstr "无法缓存用户 ID %u(%s),已存在"
+
+#~ msgid "unable to cache gid %u (%s), already exists"
+#~ msgstr "无法缓存组 ID %u(%s),已存在"
+
+#~ msgid "unable to execute %s: %s"
+#~ msgstr "无法执行 %s:%s"
+
+#~ msgid "internal error, expand_prompt() overflow"
+#~ msgstr "内部错误,expand_prompt() 溢出"
+
+#~ msgid "internal error, sudo_setenv2() overflow"
+#~ msgstr "内部错误,sudo_setenv2() 溢出"
+
+#~ msgid "internal error, sudo_setenv() overflow"
+#~ msgstr "内部错误,sudo_setenv()溢出"
+
+#~ msgid "internal error, linux_audit_command() overflow"
+#~ msgstr "内部错误,linux_audit_command() 溢出"
+
+#~ msgid "internal error, runas_groups overflow"
+#~ msgstr "内部错误,runas_groups 溢出"
+
+#~ msgid "internal error, init_vars() overflow"
+#~ msgstr "内部错误,init_vars() 溢出"
+
+#~ msgid "fixed mode on %s"
+#~ msgstr "对 %s 修正了模式"
+
+#~ msgid "set group on %s"
+#~ msgstr "对 %s 设置组"
+
+#~ msgid "unable to fix mode on %s"
+#~ msgstr "无法对 %s 修正模式"
+
+#~ msgid "%s is mode 0%o, should be 0%o"
+#~ msgstr "%s 的模式为 0%o,应为 0%o"
+
+#~ msgid "File containing dummy exec functions: %s"
+#~ msgstr "含有哑 exec 函数的文件:%s"
+
+#~ msgid ""
+#~ "Available options in a sudoers ``Defaults'' line:\n"
+#~ "\n"
+#~ msgstr ""
+#~ "sudoers 中“Defaults”行中的可用选项:\n"
+#~ "\n"
+
+#~ msgid "%s: %.*s\n"
+#~ msgstr "%s:%.*s\n"
+
+#~ msgid "unable to get runas group vector"
+#~ msgstr "无法获取 runas 组向量"
+
+#~ msgid "%s: %s_Alias `%s' references self"
+#~ msgstr "%s:%s_Alias “%s”引用了自己"
diff --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c
new file mode 100644
index 0000000..09cf401
--- /dev/null
+++ b/plugins/sudoers/policy.c
@@ -0,0 +1,997 @@
+/*
+ * Copyright (c) 2010-2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+#include <grp.h>
+#include <pwd.h>
+
+#include "sudoers.h"
+#include "sudoers_version.h"
+#include "interfaces.h"
+
+/*
+ * Info passed in from the sudo front-end.
+ */
+struct sudoers_policy_open_info {
+ char * const *settings;
+ char * const *user_info;
+ char * const *plugin_args;
+};
+
+/*
+ * Command execution args to be filled in: argv, envp and command info.
+ */
+struct sudoers_exec_args {
+ char ***argv;
+ char ***envp;
+ char ***info;
+};
+
+static unsigned int sudo_version;
+static const char *interfaces_string;
+sudo_conv_t sudo_conv;
+sudo_printf_t sudo_printf;
+const char *path_ldap_conf = _PATH_LDAP_CONF;
+const char *path_ldap_secret = _PATH_LDAP_SECRET;
+
+extern __dso_public struct policy_plugin sudoers_policy;
+
+#ifdef HAVE_BSD_AUTH_H
+extern char *login_style;
+#endif /* HAVE_BSD_AUTH_H */
+
+static int
+parse_bool(const char *line, int varlen, int *flags, int fval)
+{
+ debug_decl(parse_bool, SUDOERS_DEBUG_PLUGIN)
+
+ switch (sudo_strtobool(line + varlen + 1)) {
+ case true:
+ SET(*flags, fval);
+ debug_return_int(true);
+ case false:
+ CLR(*flags, fval);
+ debug_return_int(false);
+ default:
+ sudo_warn(U_("invalid %.*s set by sudo front-end"),
+ varlen, line);
+ debug_return_int(-1);
+ }
+}
+
+/*
+ * Deserialize args, settings and user_info arrays.
+ * Fills in struct sudo_user and other common sudoers state.
+ */
+int
+sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
+{
+ struct sudoers_policy_open_info *info = v;
+ char * const *cur;
+ const char *p, *errstr, *groups = NULL;
+ const char *remhost = NULL;
+ bool uid_set = false, gid_set = false;
+ int flags = 0;
+ debug_decl(sudoers_policy_deserialize_info, SUDOERS_DEBUG_PLUGIN)
+
+#define MATCHES(s, v) \
+ (strncmp((s), (v), sizeof(v) - 1) == 0)
+
+#define CHECK(s, v) do { \
+ if ((s)[sizeof(v) - 1] == '\0') { \
+ sudo_warn(U_("invalid %.*s set by sudo front-end"), \
+ (int)(sizeof(v) - 2), v); \
+ goto bad; \
+ } \
+} while (0)
+
+ /* Parse sudo.conf plugin args. */
+ if (info->plugin_args != NULL) {
+ for (cur = info->plugin_args; *cur != NULL; cur++) {
+ if (MATCHES(*cur, "sudoers_file=")) {
+ CHECK(*cur, "sudoers_file=");
+ sudoers_file = *cur + sizeof("sudoers_file=") - 1;
+ continue;
+ }
+ if (MATCHES(*cur, "sudoers_uid=")) {
+ p = *cur + sizeof("sudoers_uid=") - 1;
+ sudoers_uid = (uid_t) sudo_strtoid(p, NULL, NULL, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
+ goto bad;
+ }
+ continue;
+ }
+ if (MATCHES(*cur, "sudoers_gid=")) {
+ p = *cur + sizeof("sudoers_gid=") - 1;
+ sudoers_gid = (gid_t) sudo_strtoid(p, NULL, NULL, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
+ goto bad;
+ }
+ continue;
+ }
+ if (MATCHES(*cur, "sudoers_mode=")) {
+ p = *cur + sizeof("sudoers_mode=") - 1;
+ sudoers_mode = sudo_strtomode(p, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
+ goto bad;
+ }
+ continue;
+ }
+ if (MATCHES(*cur, "ldap_conf=")) {
+ CHECK(*cur, "ldap_conf=");
+ path_ldap_conf = *cur + sizeof("ldap_conf=") - 1;
+ continue;
+ }
+ if (MATCHES(*cur, "ldap_secret=")) {
+ CHECK(*cur, "ldap_secret=");
+ path_ldap_secret = *cur + sizeof("ldap_secret=") - 1;
+ continue;
+ }
+ }
+ }
+
+ /* Parse command line settings. */
+ user_closefrom = -1;
+ for (cur = info->settings; *cur != NULL; cur++) {
+ if (MATCHES(*cur, "closefrom=")) {
+ errno = 0;
+ p = *cur + sizeof("closefrom=") - 1;
+ user_closefrom = strtonum(p, 4, INT_MAX, &errstr);
+ if (user_closefrom == 0) {
+ sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
+ goto bad;
+ }
+ continue;
+ }
+ if (MATCHES(*cur, "runas_user=")) {
+ CHECK(*cur, "runas_user=");
+ *runas_user = *cur + sizeof("runas_user=") - 1;
+ sudo_user.flags |= RUNAS_USER_SPECIFIED;
+ continue;
+ }
+ if (MATCHES(*cur, "runas_group=")) {
+ CHECK(*cur, "runas_group=");
+ *runas_group = *cur + sizeof("runas_group=") - 1;
+ sudo_user.flags |= RUNAS_GROUP_SPECIFIED;
+ continue;
+ }
+ if (MATCHES(*cur, "prompt=")) {
+ /* Allow epmpty prompt. */
+ user_prompt = *cur + sizeof("prompt=") - 1;
+ def_passprompt_override = true;
+ continue;
+ }
+ if (MATCHES(*cur, "set_home=")) {
+ if (parse_bool(*cur, sizeof("set_home") - 1, &flags,
+ MODE_RESET_HOME) == -1)
+ goto bad;
+ continue;
+ }
+ if (MATCHES(*cur, "preserve_environment=")) {
+ if (parse_bool(*cur, sizeof("preserve_environment") - 1, &flags,
+ MODE_PRESERVE_ENV) == -1)
+ goto bad;
+ continue;
+ }
+ if (MATCHES(*cur, "run_shell=")) {
+ if (parse_bool(*cur, sizeof("run_shell") -1, &flags,
+ MODE_SHELL) == -1)
+ goto bad;
+ continue;
+ }
+ if (MATCHES(*cur, "login_shell=")) {
+ if (parse_bool(*cur, sizeof("login_shell") - 1, &flags,
+ MODE_LOGIN_SHELL) == -1)
+ goto bad;
+ continue;
+ }
+ if (MATCHES(*cur, "implied_shell=")) {
+ if (parse_bool(*cur, sizeof("implied_shell") - 1, &flags,
+ MODE_IMPLIED_SHELL) == -1)
+ goto bad;
+ continue;
+ }
+ if (MATCHES(*cur, "preserve_groups=")) {
+ if (parse_bool(*cur, sizeof("preserve_groups") - 1, &flags,
+ MODE_PRESERVE_GROUPS) == -1)
+ goto bad;
+ continue;
+ }
+ if (MATCHES(*cur, "ignore_ticket=")) {
+ if (parse_bool(*cur, sizeof("ignore_ticket") -1, &flags,
+ MODE_IGNORE_TICKET) == -1)
+ goto bad;
+ continue;
+ }
+ if (MATCHES(*cur, "noninteractive=")) {
+ if (parse_bool(*cur, sizeof("noninteractive") - 1, &flags,
+ MODE_NONINTERACTIVE) == -1)
+ goto bad;
+ continue;
+ }
+ if (MATCHES(*cur, "sudoedit=")) {
+ if (parse_bool(*cur, sizeof("sudoedit") - 1, &flags,
+ MODE_EDIT) == -1)
+ goto bad;
+ continue;
+ }
+ if (MATCHES(*cur, "login_class=")) {
+ CHECK(*cur, "login_class=");
+ login_class = *cur + sizeof("login_class=") - 1;
+ def_use_loginclass = true;
+ continue;
+ }
+#ifdef HAVE_PRIV_SET
+ if (MATCHES(*cur, "runas_privs=")) {
+ CHECK(*cur, "runas_privs=");
+ def_privs = *cur + sizeof("runas_privs=") - 1;
+ continue;
+ }
+ if (MATCHES(*cur, "runas_limitprivs=")) {
+ CHECK(*cur, "runas_limitprivs=");
+ def_limitprivs = *cur + sizeof("runas_limitprivs=") - 1;
+ continue;
+ }
+#endif /* HAVE_PRIV_SET */
+#ifdef HAVE_SELINUX
+ if (MATCHES(*cur, "selinux_role=")) {
+ CHECK(*cur, "selinux_role=");
+ user_role = *cur + sizeof("selinux_role=") - 1;
+ continue;
+ }
+ if (MATCHES(*cur, "selinux_type=")) {
+ CHECK(*cur, "selinux_type=");
+ user_type = *cur + sizeof("selinux_type=") - 1;
+ continue;
+ }
+#endif /* HAVE_SELINUX */
+#ifdef HAVE_BSD_AUTH_H
+ if (MATCHES(*cur, "bsdauth_type=")) {
+ CHECK(*cur, "login_style=");
+ login_style = *cur + sizeof("bsdauth_type=") - 1;
+ continue;
+ }
+#endif /* HAVE_BSD_AUTH_H */
+ if (MATCHES(*cur, "network_addrs=")) {
+ interfaces_string = *cur + sizeof("network_addrs=") - 1;
+ if (!set_interfaces(interfaces_string)) {
+ sudo_warn(U_("unable to parse network address list"));
+ goto bad;
+ }
+ continue;
+ }
+ if (MATCHES(*cur, "max_groups=")) {
+ errno = 0;
+ p = *cur + sizeof("max_groups=") - 1;
+ sudo_user.max_groups = strtonum(p, 1, INT_MAX, &errstr);
+ if (sudo_user.max_groups == 0) {
+ sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
+ goto bad;
+ }
+ continue;
+ }
+ if (MATCHES(*cur, "remote_host=")) {
+ CHECK(*cur, "remote_host=");
+ remhost = *cur + sizeof("remote_host=") - 1;
+ continue;
+ }
+ if (MATCHES(*cur, "timeout=")) {
+ p = *cur + sizeof("timeout=") - 1;
+ user_timeout = parse_timeout(p);
+ if (user_timeout == -1) {
+ if (errno == ERANGE)
+ sudo_warnx(U_("%s: %s"), p, U_("timeout value too large"));
+ else
+ sudo_warnx(U_("%s: %s"), p, U_("invalid timeout value"));
+ goto bad;
+ }
+ continue;
+ }
+#ifdef ENABLE_SUDO_PLUGIN_API
+ if (MATCHES(*cur, "plugin_dir=")) {
+ CHECK(*cur, "plugin_dir=");
+ path_plugin_dir = *cur + sizeof("plugin_dir=") - 1;
+ continue;
+ }
+#endif
+ }
+
+ user_umask = (mode_t)-1;
+ for (cur = info->user_info; *cur != NULL; cur++) {
+ if (MATCHES(*cur, "user=")) {
+ CHECK(*cur, "user=");
+ if ((user_name = strdup(*cur + sizeof("user=") - 1)) == NULL)
+ goto oom;
+ continue;
+ }
+ if (MATCHES(*cur, "uid=")) {
+ p = *cur + sizeof("uid=") - 1;
+ user_uid = (uid_t) sudo_strtoid(p, NULL, NULL, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
+ goto bad;
+ }
+ uid_set = true;
+ continue;
+ }
+ if (MATCHES(*cur, "gid=")) {
+ p = *cur + sizeof("gid=") - 1;
+ user_gid = (gid_t) sudo_strtoid(p, NULL, NULL, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
+ goto bad;
+ }
+ gid_set = true;
+ continue;
+ }
+ if (MATCHES(*cur, "groups=")) {
+ CHECK(*cur, "groups=");
+ groups = *cur + sizeof("groups=") - 1;
+ continue;
+ }
+ if (MATCHES(*cur, "cwd=")) {
+ CHECK(*cur, "cwd=");
+ if ((user_cwd = strdup(*cur + sizeof("cwd=") - 1)) == NULL)
+ goto oom;
+ continue;
+ }
+ if (MATCHES(*cur, "tty=")) {
+ CHECK(*cur, "tty=");
+ if ((user_ttypath = strdup(*cur + sizeof("tty=") - 1)) == NULL)
+ goto oom;
+ user_tty = user_ttypath;
+ if (strncmp(user_tty, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+ user_tty += sizeof(_PATH_DEV) - 1;
+ continue;
+ }
+ if (MATCHES(*cur, "host=")) {
+ CHECK(*cur, "host=");
+ if ((user_host = strdup(*cur + sizeof("host=") - 1)) == NULL)
+ goto oom;
+ if ((p = strchr(user_host, '.')) != NULL) {
+ user_shost = strndup(user_host, (size_t)(p - user_host));
+ if (user_shost == NULL)
+ goto oom;
+ } else {
+ user_shost = user_host;
+ }
+ continue;
+ }
+ if (MATCHES(*cur, "lines=")) {
+ errno = 0;
+ p = *cur + sizeof("lines=") - 1;
+ sudo_user.lines = strtonum(p, 1, INT_MAX, &errstr);
+ if (sudo_user.lines == 0) {
+ sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
+ goto bad;
+ }
+ continue;
+ }
+ if (MATCHES(*cur, "cols=")) {
+ errno = 0;
+ p = *cur + sizeof("cols=") - 1;
+ sudo_user.cols = strtonum(p, 1, INT_MAX, &errstr);
+ if (sudo_user.cols == 0) {
+ sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
+ goto bad;
+ }
+ continue;
+ }
+ if (MATCHES(*cur, "sid=")) {
+ p = *cur + sizeof("sid=") - 1;
+ user_sid = (pid_t) sudo_strtoid(p, NULL, NULL, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
+ goto bad;
+ }
+ continue;
+ }
+ if (MATCHES(*cur, "umask=")) {
+ p = *cur + sizeof("umask=") - 1;
+ sudo_user.umask = sudo_strtomode(p, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
+ goto bad;
+ }
+ continue;
+ }
+ }
+
+ /* User name, user ID, group ID and host name must be specified. */
+ if (user_name == NULL) {
+ sudo_warnx(U_("user name not set by sudo front-end"));
+ goto bad;
+ }
+ if (!uid_set) {
+ sudo_warnx(U_("user ID not set by sudo front-end"));
+ goto bad;
+ }
+ if (!gid_set) {
+ sudo_warnx(U_("group ID not set by sudo front-end"));
+ goto bad;
+ }
+ if (user_host == NULL) {
+ sudo_warnx(U_("host name not set by sudo front-end"));
+ goto bad;
+ }
+
+ if ((user_runhost = strdup(remhost ? remhost : user_host)) == NULL)
+ goto oom;
+ if ((p = strchr(user_runhost, '.')) != NULL) {
+ user_srunhost = strndup(user_runhost, (size_t)(p - user_runhost));
+ if (user_srunhost == NULL)
+ goto oom;
+ } else {
+ user_srunhost = user_runhost;
+ }
+ if (user_cwd == NULL) {
+ if ((user_cwd = strdup("unknown")) == NULL)
+ goto oom;
+ }
+ if (user_tty == NULL) {
+ if ((user_tty = strdup("unknown")) == NULL)
+ goto oom;
+ /* user_ttypath remains NULL */
+ }
+
+ if (groups != NULL) {
+ /* sudo_parse_gids() will print a warning on error. */
+ user_ngids = sudo_parse_gids(groups, &user_gid, &user_gids);
+ if (user_ngids == -1)
+ goto bad;
+ }
+
+ /* umask is only set in user_info[] for API 1.10 and above. */
+ if (user_umask == (mode_t)-1) {
+ user_umask = umask(0);
+ umask(user_umask);
+ }
+
+ /* Always reset the environment for a login shell. */
+ if (ISSET(flags, MODE_LOGIN_SHELL))
+ def_env_reset = true;
+
+ /* Some systems support fexecve() which we use for digest matches. */
+ cmnd_fd = -1;
+
+ /* Dump settings and user info (XXX - plugin args) */
+ for (cur = info->settings; *cur != NULL; cur++)
+ sudo_debug_printf(SUDO_DEBUG_INFO, "settings: %s", *cur);
+ for (cur = info->user_info; *cur != NULL; cur++)
+ sudo_debug_printf(SUDO_DEBUG_INFO, "user_info: %s", *cur);
+
+#undef MATCHES
+ debug_return_int(flags);
+
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+bad:
+ debug_return_int(MODE_ERROR);
+}
+
+/*
+ * Setup the execution environment.
+ * Builds up the command_info list and sets argv and envp.
+ * Consumes iolog_path if not NULL.
+ * Returns 1 on success and -1 on error.
+ */
+int
+sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
+ char *iolog_path, void *v)
+{
+ struct sudoers_exec_args *exec_args = v;
+ char **command_info;
+ int info_len = 0;
+ debug_decl(sudoers_policy_exec_setup, SUDOERS_DEBUG_PLUGIN)
+
+ /* Increase the length of command_info as needed, it is *not* checked. */
+ command_info = calloc(48, sizeof(char *));
+ if (command_info == NULL)
+ goto oom;
+
+ command_info[info_len] = sudo_new_key_val("command", safe_cmnd);
+ if (command_info[info_len++] == NULL)
+ goto oom;
+ if (def_log_input || def_log_output) {
+ if (iolog_path)
+ command_info[info_len++] = iolog_path; /* now owned */
+ if (def_log_input) {
+ if ((command_info[info_len++] = strdup("iolog_stdin=true")) == NULL)
+ goto oom;
+ if ((command_info[info_len++] = strdup("iolog_ttyin=true")) == NULL)
+ goto oom;
+ }
+ if (def_log_output) {
+ if ((command_info[info_len++] = strdup("iolog_stdout=true")) == NULL)
+ goto oom;
+ if ((command_info[info_len++] = strdup("iolog_stderr=true")) == NULL)
+ goto oom;
+ if ((command_info[info_len++] = strdup("iolog_ttyout=true")) == NULL)
+ goto oom;
+ }
+ if (def_compress_io) {
+ if ((command_info[info_len++] = strdup("iolog_compress=true")) == NULL)
+ goto oom;
+ }
+ if (def_maxseq) {
+ if (asprintf(&command_info[info_len++], "maxseq=%u", def_maxseq) == -1)
+ goto oom;
+ }
+ }
+ if (ISSET(sudo_mode, MODE_EDIT)) {
+ if ((command_info[info_len++] = strdup("sudoedit=true")) == NULL)
+ goto oom;
+ if (!def_sudoedit_checkdir) {
+ if ((command_info[info_len++] = strdup("sudoedit_checkdir=false")) == NULL)
+ goto oom;
+ }
+ if (def_sudoedit_follow) {
+ if ((command_info[info_len++] = strdup("sudoedit_follow=true")) == NULL)
+ goto oom;
+ }
+ }
+ if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
+ /* Set cwd to run user's homedir. */
+ if ((command_info[info_len++] = sudo_new_key_val("cwd", runas_pw->pw_dir)) == NULL)
+ goto oom;
+ }
+ if (def_stay_setuid) {
+ if (asprintf(&command_info[info_len++], "runas_uid=%u",
+ (unsigned int)user_uid) == -1)
+ goto oom;
+ if (asprintf(&command_info[info_len++], "runas_gid=%u",
+ (unsigned int)user_gid) == -1)
+ goto oom;
+ if (asprintf(&command_info[info_len++], "runas_euid=%u",
+ (unsigned int)runas_pw->pw_uid) == -1)
+ goto oom;
+ if (asprintf(&command_info[info_len++], "runas_egid=%u",
+ runas_gr ? (unsigned int)runas_gr->gr_gid :
+ (unsigned int)runas_pw->pw_gid) == -1)
+ goto oom;
+ } else {
+ if (asprintf(&command_info[info_len++], "runas_uid=%u",
+ (unsigned int)runas_pw->pw_uid) == -1)
+ goto oom;
+ if (asprintf(&command_info[info_len++], "runas_gid=%u",
+ runas_gr ? (unsigned int)runas_gr->gr_gid :
+ (unsigned int)runas_pw->pw_gid) == -1)
+ goto oom;
+ }
+ if (def_preserve_groups) {
+ if ((command_info[info_len++] = strdup("preserve_groups=true")) == NULL)
+ goto oom;
+ } else {
+ int i, len;
+ gid_t egid;
+ size_t glsize;
+ char *cp, *gid_list;
+ struct gid_list *gidlist;
+
+ /* Only use results from a group db query, not the front end. */
+ gidlist = sudo_get_gidlist(runas_pw, ENTRY_TYPE_QUERIED);
+
+ /* We reserve an extra spot in the list for the effective gid. */
+ glsize = sizeof("runas_groups=") - 1 +
+ ((gidlist->ngids + 1) * (MAX_UID_T_LEN + 1));
+ gid_list = malloc(glsize);
+ if (gid_list == NULL)
+ goto oom;
+ memcpy(gid_list, "runas_groups=", sizeof("runas_groups=") - 1);
+ cp = gid_list + sizeof("runas_groups=") - 1;
+
+ /* On BSD systems the effective gid is the first group in the list. */
+ egid = runas_gr ? (unsigned int)runas_gr->gr_gid :
+ (unsigned int)runas_pw->pw_gid;
+ len = snprintf(cp, glsize - (cp - gid_list), "%u", (unsigned int)egid);
+ if (len < 0 || (size_t)len >= glsize - (cp - gid_list)) {
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ free(gid_list);
+ goto bad;
+ }
+ cp += len;
+ for (i = 0; i < gidlist->ngids; i++) {
+ if (gidlist->gids[i] != egid) {
+ len = snprintf(cp, glsize - (cp - gid_list), ",%u",
+ (unsigned int) gidlist->gids[i]);
+ if (len < 0 || (size_t)len >= glsize - (cp - gid_list)) {
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ free(gid_list);
+ goto bad;
+ }
+ cp += len;
+ }
+ }
+ command_info[info_len++] = gid_list;
+ sudo_gidlist_delref(gidlist);
+ }
+ if (def_closefrom >= 0) {
+ if (asprintf(&command_info[info_len++], "closefrom=%d", def_closefrom) == -1)
+ goto oom;
+ }
+ if (def_ignore_iolog_errors) {
+ if ((command_info[info_len++] = strdup("ignore_iolog_errors=true")) == NULL)
+ goto oom;
+ }
+ if (def_noexec) {
+ if ((command_info[info_len++] = strdup("noexec=true")) == NULL)
+ goto oom;
+ }
+ if (def_exec_background) {
+ if ((command_info[info_len++] = strdup("exec_background=true")) == NULL)
+ goto oom;
+ }
+ if (def_set_utmp) {
+ if ((command_info[info_len++] = strdup("set_utmp=true")) == NULL)
+ goto oom;
+ }
+ if (def_use_pty) {
+ if ((command_info[info_len++] = strdup("use_pty=true")) == NULL)
+ goto oom;
+ }
+ if (def_utmp_runas) {
+ if ((command_info[info_len++] = sudo_new_key_val("utmp_user", runas_pw->pw_name)) == NULL)
+ goto oom;
+ }
+ if (def_iolog_mode != (S_IRUSR|S_IWUSR)) {
+ if (asprintf(&command_info[info_len++], "iolog_mode=0%o", (unsigned int)def_iolog_mode) == -1)
+ goto oom;
+ }
+ if (def_iolog_user != NULL) {
+ if ((command_info[info_len++] = sudo_new_key_val("iolog_user", def_iolog_user)) == NULL)
+ goto oom;
+ }
+ if (def_iolog_group != NULL) {
+ if ((command_info[info_len++] = sudo_new_key_val("iolog_group", def_iolog_group)) == NULL)
+ goto oom;
+ }
+ if (def_command_timeout > 0 || user_timeout > 0) {
+ int timeout = user_timeout;
+ if (timeout == 0 || def_command_timeout < timeout)
+ timeout = def_command_timeout;
+ if (asprintf(&command_info[info_len++], "timeout=%u", timeout) == -1)
+ goto oom;
+ }
+ if (cmnd_umask != ACCESSPERMS) {
+ if (asprintf(&command_info[info_len++], "umask=0%o", (unsigned int)cmnd_umask) == -1)
+ goto oom;
+ }
+ if (cmnd_fd != -1) {
+ if (sudo_version < SUDO_API_MKVERSION(1, 9)) {
+ /* execfd only supported by plugin API 1.9 and higher */
+ close(cmnd_fd);
+ cmnd_fd = -1;
+ } else {
+ if (asprintf(&command_info[info_len++], "execfd=%d", cmnd_fd) == -1)
+ goto oom;
+ }
+ }
+#ifdef HAVE_LOGIN_CAP_H
+ if (def_use_loginclass) {
+ if ((command_info[info_len++] = sudo_new_key_val("login_class", login_class)) == NULL)
+ goto oom;
+ }
+#endif /* HAVE_LOGIN_CAP_H */
+#ifdef HAVE_SELINUX
+ if (user_role != NULL) {
+ if ((command_info[info_len++] = sudo_new_key_val("selinux_role", user_role)) == NULL)
+ goto oom;
+ }
+ if (user_type != NULL) {
+ if ((command_info[info_len++] = sudo_new_key_val("selinux_type", user_type)) == NULL)
+ goto oom;
+ }
+#endif /* HAVE_SELINUX */
+#ifdef HAVE_PRIV_SET
+ if (runas_privs != NULL) {
+ if ((command_info[info_len++] = sudo_new_key_val("runas_privs", runas_privs)) == NULL)
+ goto oom;
+ }
+ if (runas_limitprivs != NULL) {
+ if ((command_info[info_len++] = sudo_new_key_val("runas_limitprivs", runas_limitprivs)) == NULL)
+ goto oom;
+ }
+#endif /* HAVE_SELINUX */
+
+ /* Free on exit; they are not available in the close function. */
+ sudoers_gc_add(GC_VECTOR, argv);
+ sudoers_gc_add(GC_VECTOR, envp);
+ sudoers_gc_add(GC_VECTOR, command_info);
+
+ /* Fill in exec environment info. */
+ *(exec_args->argv) = argv;
+ *(exec_args->envp) = envp;
+ *(exec_args->info) = command_info;
+
+ debug_return_int(true);
+
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+bad:
+ while (info_len--)
+ free(command_info[info_len]);
+ free(command_info);
+ debug_return_int(-1);
+}
+
+static int
+sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const envp[], char * const args[])
+{
+ struct sudo_conf_debug_file_list debug_files = TAILQ_HEAD_INITIALIZER(debug_files);
+ struct sudoers_policy_open_info info;
+ const char *cp, *plugin_path = NULL;
+ char * const *cur;
+ debug_decl(sudoers_policy_open, SUDOERS_DEBUG_PLUGIN)
+
+ sudo_version = version;
+ sudo_conv = conversation;
+ sudo_printf = plugin_printf;
+
+ /* Plugin args are only specified for API version 1.2 and higher. */
+ if (sudo_version < SUDO_API_MKVERSION(1, 2))
+ args = NULL;
+
+ /* Initialize the debug subsystem. */
+ for (cur = settings; (cp = *cur) != NULL; cur++) {
+ if (strncmp(cp, "debug_flags=", sizeof("debug_flags=") - 1) == 0) {
+ cp += sizeof("debug_flags=") - 1;
+ if (!sudoers_debug_parse_flags(&debug_files, cp))
+ debug_return_int(-1);
+ continue;
+ }
+ if (strncmp(cp, "plugin_path=", sizeof("plugin_path=") - 1) == 0) {
+ plugin_path = cp + sizeof("plugin_path=") - 1;
+ continue;
+ }
+ }
+ if (!sudoers_debug_register(plugin_path, &debug_files))
+ debug_return_int(-1);
+
+ /* Call the sudoers init function. */
+ info.settings = settings;
+ info.user_info = user_info;
+ info.plugin_args = args;
+ debug_return_int(sudoers_policy_init(&info, envp));
+}
+
+static void
+sudoers_policy_close(int exit_status, int error_code)
+{
+ debug_decl(sudoers_policy_close, SUDOERS_DEBUG_PLUGIN)
+
+ /* We do not currently log the exit status. */
+ if (error_code) {
+ errno = error_code;
+ sudo_warn(U_("unable to execute %s"), safe_cmnd);
+ }
+
+ /* Close the session we opened in sudoers_policy_init_session(). */
+ if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT))
+ (void)sudo_auth_end_session(runas_pw);
+
+ /* Deregister the callback for sudo_fatal()/sudo_fatalx(). */
+ sudo_fatal_callback_deregister(sudoers_cleanup);
+
+ /* Free remaining references to password and group entries. */
+ /* XXX - move cleanup to function in sudoers.c */
+ sudo_pw_delref(sudo_user.pw);
+ sudo_user.pw = NULL;
+ sudo_pw_delref(runas_pw);
+ runas_pw = NULL;
+ if (runas_gr != NULL) {
+ sudo_gr_delref(runas_gr);
+ runas_gr = NULL;
+ }
+ if (user_gid_list != NULL) {
+ sudo_gidlist_delref(user_gid_list);
+ user_gid_list = NULL;
+ }
+ free(user_gids);
+ user_gids = NULL;
+
+ sudoers_debug_deregister();
+
+ return;
+}
+
+/*
+ * The init_session function is called before executing the command
+ * and before uid/gid changes occur.
+ * Returns 1 on success, 0 on failure and -1 on error.
+ */
+static int
+sudoers_policy_init_session(struct passwd *pwd, char **user_env[])
+{
+ debug_decl(sudoers_policy_init_session, SUDOERS_DEBUG_PLUGIN)
+
+ /* user_env is only specified for API version 1.2 and higher. */
+ if (sudo_version < SUDO_API_MKVERSION(1, 2))
+ user_env = NULL;
+
+ debug_return_int(sudo_auth_begin_session(pwd, user_env));
+}
+
+static int
+sudoers_policy_check(int argc, char * const argv[], char *env_add[],
+ char **command_infop[], char **argv_out[], char **user_env_out[])
+{
+ struct sudoers_exec_args exec_args;
+ int ret;
+ debug_decl(sudoers_policy_check, SUDOERS_DEBUG_PLUGIN)
+
+ if (!ISSET(sudo_mode, MODE_EDIT))
+ SET(sudo_mode, MODE_RUN);
+
+ exec_args.argv = argv_out;
+ exec_args.envp = user_env_out;
+ exec_args.info = command_infop;
+
+ ret = sudoers_policy_main(argc, argv, 0, env_add, false, &exec_args);
+ if (ret == true && sudo_version >= SUDO_API_MKVERSION(1, 3)) {
+ /* Unset close function if we don't need it to avoid extra process. */
+ if (!def_log_input && !def_log_output && !def_use_pty &&
+ !sudo_auth_needs_end_session())
+ sudoers_policy.close = NULL;
+ }
+ debug_return_int(ret);
+}
+
+static int
+sudoers_policy_validate(void)
+{
+ debug_decl(sudoers_policy_validate, SUDOERS_DEBUG_PLUGIN)
+
+ user_cmnd = "validate";
+ SET(sudo_mode, MODE_VALIDATE);
+
+ debug_return_int(sudoers_policy_main(0, NULL, I_VERIFYPW, NULL, false, NULL));
+}
+
+static void
+sudoers_policy_invalidate(int remove)
+{
+ debug_decl(sudoers_policy_invalidate, SUDOERS_DEBUG_PLUGIN)
+
+ user_cmnd = "kill";
+ /* XXX - plugin API should support a return value for fatal errors. */
+ timestamp_remove(remove);
+ sudoers_cleanup();
+
+ debug_return;
+}
+
+static int
+sudoers_policy_list(int argc, char * const argv[], int verbose,
+ const char *list_user)
+{
+ int ret;
+ debug_decl(sudoers_policy_list, SUDOERS_DEBUG_PLUGIN)
+
+ user_cmnd = "list";
+ if (argc)
+ SET(sudo_mode, MODE_CHECK);
+ else
+ SET(sudo_mode, MODE_LIST);
+ if (list_user) {
+ list_pw = sudo_getpwnam(list_user);
+ if (list_pw == NULL) {
+ sudo_warnx(U_("unknown user: %s"), list_user);
+ debug_return_int(-1);
+ }
+ }
+ ret = sudoers_policy_main(argc, argv, I_LISTPW, NULL, verbose, NULL);
+ if (list_user) {
+ sudo_pw_delref(list_pw);
+ list_pw = NULL;
+ }
+
+ debug_return_int(ret);
+}
+
+static int
+sudoers_policy_version(int verbose)
+{
+ debug_decl(sudoers_policy_version, SUDOERS_DEBUG_PLUGIN)
+
+ sudo_printf(SUDO_CONV_INFO_MSG, _("Sudoers policy plugin version %s\n"),
+ PACKAGE_VERSION);
+ sudo_printf(SUDO_CONV_INFO_MSG, _("Sudoers file grammar version %d\n"),
+ SUDOERS_GRAMMAR_VERSION);
+
+ if (verbose) {
+ sudo_printf(SUDO_CONV_INFO_MSG, _("\nSudoers path: %s\n"), sudoers_file);
+#ifdef HAVE_LDAP
+# ifdef _PATH_NSSWITCH_CONF
+ sudo_printf(SUDO_CONV_INFO_MSG, _("nsswitch path: %s\n"), _PATH_NSSWITCH_CONF);
+# endif
+ sudo_printf(SUDO_CONV_INFO_MSG, _("ldap.conf path: %s\n"), path_ldap_conf);
+ sudo_printf(SUDO_CONV_INFO_MSG, _("ldap.secret path: %s\n"), path_ldap_secret);
+#endif
+ dump_auth_methods();
+ dump_defaults();
+ sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+ if (interfaces_string != NULL) {
+ dump_interfaces(interfaces_string);
+ sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+ }
+ }
+ debug_return_int(true);
+}
+
+static struct sudo_hook sudoers_hooks[] = {
+ { SUDO_HOOK_VERSION, SUDO_HOOK_SETENV, sudoers_hook_setenv, NULL },
+ { SUDO_HOOK_VERSION, SUDO_HOOK_UNSETENV, sudoers_hook_unsetenv, NULL },
+ { SUDO_HOOK_VERSION, SUDO_HOOK_GETENV, sudoers_hook_getenv, NULL },
+ { SUDO_HOOK_VERSION, SUDO_HOOK_PUTENV, sudoers_hook_putenv, NULL },
+ { 0, 0, NULL, NULL }
+};
+
+/*
+ * Register environment function hooks.
+ * Note that we have not registered sudoers with the debug subsystem yet.
+ */
+static void
+sudoers_policy_register_hooks(int version, int (*register_hook)(struct sudo_hook *hook))
+{
+ struct sudo_hook *hook;
+
+ for (hook = sudoers_hooks; hook->hook_fn != NULL; hook++) {
+ if (register_hook(hook) != 0) {
+ sudo_warn_nodebug(
+ U_("unable to register hook of type %d (version %d.%d)"),
+ hook->hook_type, SUDO_API_VERSION_GET_MAJOR(hook->hook_version),
+ SUDO_API_VERSION_GET_MINOR(hook->hook_version));
+ }
+ }
+}
+
+__dso_public struct policy_plugin sudoers_policy = {
+ SUDO_POLICY_PLUGIN,
+ SUDO_API_VERSION,
+ sudoers_policy_open,
+ sudoers_policy_close,
+ sudoers_policy_version,
+ sudoers_policy_check,
+ sudoers_policy_list,
+ sudoers_policy_validate,
+ sudoers_policy_invalidate,
+ sudoers_policy_init_session,
+ sudoers_policy_register_hooks
+};
diff --git a/plugins/sudoers/prompt.c b/plugins/sudoers/prompt.c
new file mode 100644
index 0000000..d79d7d5
--- /dev/null
+++ b/plugins/sudoers/prompt.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 1993-1996,1998-2005, 2007-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <pwd.h>
+#include <grp.h>
+
+#include "sudoers.h"
+
+/*
+ * Expand %h and %u escapes (if present) in the prompt and pass back
+ * the dynamically allocated result.
+ */
+char *
+expand_prompt(const char *old_prompt, const char *auth_user)
+{
+ size_t len, n;
+ int subst;
+ const char *p;
+ char *np, *new_prompt, *endp;
+ debug_decl(expand_prompt, SUDOERS_DEBUG_AUTH)
+
+ /* How much space do we need to malloc for the prompt? */
+ subst = 0;
+ for (p = old_prompt, len = strlen(old_prompt); *p; p++) {
+ if (p[0] =='%') {
+ switch (p[1]) {
+ case 'h':
+ p++;
+ len += strlen(user_shost) - 2;
+ subst = 1;
+ break;
+ case 'H':
+ p++;
+ len += strlen(user_host) - 2;
+ subst = 1;
+ break;
+ case 'p':
+ p++;
+ len += strlen(auth_user) - 2;
+ subst = 1;
+ break;
+ case 'u':
+ p++;
+ len += strlen(user_name) - 2;
+ subst = 1;
+ break;
+ case 'U':
+ p++;
+ len += strlen(runas_pw->pw_name) - 2;
+ subst = 1;
+ break;
+ case '%':
+ p++;
+ len--;
+ subst = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if ((new_prompt = malloc(++len)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_str(NULL);
+ }
+
+ if (subst) {
+ endp = new_prompt + len;
+ for (p = old_prompt, np = new_prompt; *p; p++) {
+ if (p[0] =='%') {
+ switch (p[1]) {
+ case 'h':
+ p++;
+ n = strlcpy(np, user_shost, np - endp);
+ if (n >= (size_t)(np - endp))
+ goto oflow;
+ np += n;
+ continue;
+ case 'H':
+ p++;
+ n = strlcpy(np, user_host, np - endp);
+ if (n >= (size_t)(np - endp))
+ goto oflow;
+ np += n;
+ continue;
+ case 'p':
+ p++;
+ n = strlcpy(np, auth_user, np - endp);
+ if (n >= (size_t)(np - endp))
+ goto oflow;
+ np += n;
+ continue;
+ case 'u':
+ p++;
+ n = strlcpy(np, user_name, np - endp);
+ if (n >= (size_t)(np - endp))
+ goto oflow;
+ np += n;
+ continue;
+ case 'U':
+ p++;
+ n = strlcpy(np, runas_pw->pw_name, np - endp);
+ if (n >= (size_t)(np - endp))
+ goto oflow;
+ np += n;
+ continue;
+ case '%':
+ /* convert %% -> % */
+ p++;
+ break;
+ default:
+ /* no conversion */
+ break;
+ }
+ }
+ *np++ = *p;
+ if (np >= endp)
+ goto oflow;
+ }
+ *np = '\0';
+ } else {
+ /* Nothing to expand. */
+ memcpy(new_prompt, old_prompt, len); /* len includes NUL */
+ }
+
+ debug_return_str(new_prompt);
+
+oflow:
+ /* We pre-allocate enough space, so this should never happen. */
+ free(new_prompt);
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ debug_return_str(NULL);
+}
diff --git a/plugins/sudoers/pwutil.c b/plugins/sudoers/pwutil.c
new file mode 100644
index 0000000..ab60986
--- /dev/null
+++ b/plugins/sudoers/pwutil.c
@@ -0,0 +1,1107 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#ifdef HAVE_SETAUTHDB
+# include <usersec.h>
+#endif /* HAVE_SETAUTHDB */
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "sudoers.h"
+#include "redblack.h"
+#include "pwutil.h"
+
+/*
+ * The passwd and group caches.
+ */
+static struct rbtree *pwcache_byuid, *pwcache_byname;
+static struct rbtree *grcache_bygid, *grcache_byname;
+static struct rbtree *gidlist_cache, *grlist_cache;
+
+static int cmp_pwuid(const void *, const void *);
+static int cmp_pwnam(const void *, const void *);
+static int cmp_grgid(const void *, const void *);
+
+/*
+ * Default functions for building cache items.
+ */
+static sudo_make_pwitem_t make_pwitem = sudo_make_pwitem;
+static sudo_make_gritem_t make_gritem = sudo_make_gritem;
+static sudo_make_gidlist_item_t make_gidlist_item = sudo_make_gidlist_item;
+static sudo_make_grlist_item_t make_grlist_item = sudo_make_grlist_item;
+
+#define cmp_grnam cmp_pwnam
+
+/*
+ * AIX has the concept of authentication registries (files, NIS, LDAP, etc).
+ * This allows you to have separate ID <-> name mappings based on which
+ * authentication registries the user was looked up in.
+ * We store the registry as part of the key and use it when matching.
+ */
+#ifdef HAVE_SETAUTHDB
+# define getauthregistry(u, r) aix_getauthregistry((u), (r))
+#else
+# define getauthregistry(u, r) ((r)[0] = '\0')
+#endif
+
+/*
+ * Change the default pwutil backend functions.
+ * The default functions query the password and group databases.
+ */
+void
+sudo_pwutil_set_backend(sudo_make_pwitem_t pwitem, sudo_make_gritem_t gritem,
+ sudo_make_gidlist_item_t gidlist_item, sudo_make_grlist_item_t grlist_item)
+{
+ debug_decl(sudo_pwutil_set_backend, SUDOERS_DEBUG_NSS)
+
+ make_pwitem = pwitem;
+ make_gritem = gritem;
+ make_gidlist_item = gidlist_item;
+ make_grlist_item = grlist_item;
+
+ debug_return;
+}
+
+/*
+ * Compare by user ID.
+ * v1 is the key to find or data to insert, v2 is in-tree data.
+ */
+static int
+cmp_pwuid(const void *v1, const void *v2)
+{
+ const struct cache_item *ci1 = (const struct cache_item *) v1;
+ const struct cache_item *ci2 = (const struct cache_item *) v2;
+ if (ci1->k.uid == ci2->k.uid)
+ return strcmp(ci1->registry, ci2->registry);
+ if (ci1->k.uid < ci2->k.uid)
+ return -1;
+ return 1;
+}
+
+/*
+ * Compare by user/group name.
+ * v1 is the key to find or data to insert, v2 is in-tree data.
+ */
+static int
+cmp_pwnam(const void *v1, const void *v2)
+{
+ const struct cache_item *ci1 = (const struct cache_item *) v1;
+ const struct cache_item *ci2 = (const struct cache_item *) v2;
+ int ret = strcmp(ci1->k.name, ci2->k.name);
+ if (ret == 0)
+ ret = strcmp(ci1->registry, ci2->registry);
+ return ret;
+}
+
+/*
+ * Compare by user name, taking into account the source type.
+ * Need to differentiate between group IDs received from the front-end
+ * (via getgroups()) and groups IDs queried from the group database.
+ * v1 is the key to find or data to insert, v2 is in-tree data.
+ */
+static int
+cmp_gidlist(const void *v1, const void *v2)
+{
+ const struct cache_item *ci1 = (const struct cache_item *) v1;
+ const struct cache_item *ci2 = (const struct cache_item *) v2;
+ int ret = strcmp(ci1->k.name, ci2->k.name);
+ if (ret == 0) {
+ if (ci1->type == ENTRY_TYPE_ANY || ci1->type == ci2->type)
+ return strcmp(ci1->registry, ci2->registry);
+ if (ci1->type < ci2->type)
+ return -1;
+ return 1;
+ }
+ return ret;
+}
+
+void
+sudo_pw_addref(struct passwd *pw)
+{
+ debug_decl(sudo_pw_addref, SUDOERS_DEBUG_NSS)
+ ptr_to_item(pw)->refcnt++;
+ debug_return;
+}
+
+static void
+sudo_pw_delref_item(void *v)
+{
+ struct cache_item *item = v;
+ debug_decl(sudo_pw_delref_item, SUDOERS_DEBUG_NSS)
+
+ if (--item->refcnt == 0)
+ free(item);
+
+ debug_return;
+}
+
+void
+sudo_pw_delref(struct passwd *pw)
+{
+ debug_decl(sudo_pw_delref, SUDOERS_DEBUG_NSS)
+ sudo_pw_delref_item(ptr_to_item(pw));
+ debug_return;
+}
+
+/*
+ * Get a password entry by uid and allocate space for it.
+ */
+struct passwd *
+sudo_getpwuid(uid_t uid)
+{
+ struct cache_item key, *item;
+ struct rbnode *node;
+ debug_decl(sudo_getpwuid, SUDOERS_DEBUG_NSS)
+
+ if (pwcache_byuid == NULL) {
+ pwcache_byuid = rbcreate(cmp_pwuid);
+ if (pwcache_byuid == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_ptr(NULL);
+ }
+ }
+
+ key.k.uid = uid;
+ getauthregistry(IDtouser(uid), key.registry);
+ if ((node = rbfind(pwcache_byuid, &key)) != NULL) {
+ item = node->data;
+ goto done;
+ }
+ /*
+ * Cache passwd db entry if it exists or a negative response if not.
+ */
+#ifdef HAVE_SETAUTHDB
+ aix_setauthdb(IDtouser(uid), key.registry);
+#endif
+ item = make_pwitem(uid, NULL);
+#ifdef HAVE_SETAUTHDB
+ aix_restoreauthdb();
+#endif
+ if (item == NULL) {
+ if (errno != ENOENT || (item = calloc(1, sizeof(*item))) == NULL) {
+ sudo_warnx(U_("unable to cache uid %u, out of memory"),
+ (unsigned int) uid);
+ /* cppcheck-suppress memleak */
+ debug_return_ptr(NULL);
+ }
+ item->refcnt = 1;
+ item->k.uid = uid;
+ /* item->d.pw = NULL; */
+ }
+ strlcpy(item->registry, key.registry, sizeof(item->registry));
+ switch (rbinsert(pwcache_byuid, item, NULL)) {
+ case 1:
+ /* should not happen */
+ sudo_warnx(U_("unable to cache uid %u, already exists"),
+ (unsigned int) uid);
+ item->refcnt = 0;
+ break;
+ case -1:
+ /* can't cache item, just return it */
+ sudo_warnx(U_("unable to cache uid %u, out of memory"),
+ (unsigned int) uid);
+ item->refcnt = 0;
+ break;
+ }
+done:
+ if (item->refcnt != 0) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s: uid %u [%s] -> user %s [%s] (%s)", __func__,
+ (unsigned int)uid, key.registry,
+ item->d.pw ? item->d.pw->pw_name : "unknown",
+ item->registry, node ? "cache hit" : "cached");
+ }
+ item->refcnt++;
+ debug_return_ptr(item->d.pw);
+}
+
+/*
+ * Get a password entry by name and allocate space for it.
+ */
+struct passwd *
+sudo_getpwnam(const char *name)
+{
+ struct cache_item key, *item;
+ struct rbnode *node;
+ debug_decl(sudo_getpwnam, SUDOERS_DEBUG_NSS)
+
+ if (pwcache_byname == NULL) {
+ pwcache_byname = rbcreate(cmp_pwnam);
+ if (pwcache_byname == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_ptr(NULL);
+ }
+ }
+
+ key.k.name = (char *) name;
+ getauthregistry((char *) name, key.registry);
+ if ((node = rbfind(pwcache_byname, &key)) != NULL) {
+ item = node->data;
+ goto done;
+ }
+ /*
+ * Cache passwd db entry if it exists or a negative response if not.
+ */
+#ifdef HAVE_SETAUTHDB
+ aix_setauthdb((char *) name, key.registry);
+#endif
+ item = make_pwitem((uid_t)-1, name);
+#ifdef HAVE_SETAUTHDB
+ aix_restoreauthdb();
+#endif
+ if (item == NULL) {
+ const size_t len = strlen(name) + 1;
+ if (errno != ENOENT || (item = calloc(1, sizeof(*item) + len)) == NULL) {
+ sudo_warnx(U_("unable to cache user %s, out of memory"), name);
+ /* cppcheck-suppress memleak */
+ debug_return_ptr(NULL);
+ }
+ item->refcnt = 1;
+ item->k.name = (char *) item + sizeof(*item);
+ memcpy(item->k.name, name, len);
+ /* item->d.pw = NULL; */
+ }
+ strlcpy(item->registry, key.registry, sizeof(item->registry));
+ switch (rbinsert(pwcache_byname, item, NULL)) {
+ case 1:
+ /* should not happen */
+ sudo_warnx(U_("unable to cache user %s, already exists"), name);
+ item->refcnt = 0;
+ break;
+ case -1:
+ /* can't cache item, just return it */
+ sudo_warnx(U_("unable to cache user %s, out of memory"), name);
+ item->refcnt = 0;
+ break;
+ }
+done:
+ if (item->refcnt != 0) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s: user %s [%s] -> uid %d [%s] (%s)", __func__, name,
+ key.registry, item->d.pw ? (int)item->d.pw->pw_uid : -1,
+ item->registry, node ? "cache hit" : "cached");
+ }
+ item->refcnt++;
+ debug_return_ptr(item->d.pw);
+}
+
+/*
+ * Take a user, uid, gid, home and shell and return a faked up passwd struct.
+ * If home or shell are NULL default values will be used.
+ */
+struct passwd *
+sudo_mkpwent(const char *user, uid_t uid, gid_t gid, const char *home,
+ const char *shell)
+{
+ struct cache_item_pw *pwitem;
+ struct cache_item *item;
+ struct passwd *pw;
+ size_t len, name_len, home_len, shell_len;
+ int i;
+ debug_decl(sudo_mkpwent, SUDOERS_DEBUG_NSS)
+
+ if (pwcache_byuid == NULL)
+ pwcache_byuid = rbcreate(cmp_pwuid);
+ if (pwcache_byname == NULL)
+ pwcache_byname = rbcreate(cmp_pwnam);
+ if (pwcache_byuid == NULL || pwcache_byname == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_ptr(NULL);
+ }
+
+ /* Optional arguments. */
+ if (home == NULL)
+ home = "/";
+ if (shell == NULL)
+ shell = _PATH_BSHELL;
+
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s: creating and caching passwd struct for %s:%u:%u:%s:%s", __func__,
+ user, (unsigned int)uid, (unsigned int)gid, home, shell);
+
+ name_len = strlen(user);
+ home_len = strlen(home);
+ shell_len = strlen(shell);
+ len = sizeof(*pwitem) + name_len + 1 /* pw_name */ +
+ sizeof("*") /* pw_passwd */ + sizeof("") /* pw_gecos */ +
+ home_len + 1 /* pw_dir */ + shell_len + 1 /* pw_shell */;
+
+ for (i = 0; i < 2; i++) {
+ struct rbtree *pwcache;
+ struct rbnode *node;
+
+ pwitem = calloc(1, len);
+ if (pwitem == NULL) {
+ sudo_warnx(U_("unable to cache user %s, out of memory"), user);
+ debug_return_ptr(NULL);
+ }
+ pw = &pwitem->pw;
+ pw->pw_uid = uid;
+ pw->pw_gid = gid;
+ pw->pw_name = (char *)(pwitem + 1);
+ memcpy(pw->pw_name, user, name_len + 1);
+ pw->pw_passwd = pw->pw_name + name_len + 1;
+ memcpy(pw->pw_passwd, "*", 2);
+ pw->pw_gecos = pw->pw_passwd + 2;
+ pw->pw_gecos[0] = '\0';
+ pw->pw_dir = pw->pw_gecos + 1;
+ memcpy(pw->pw_dir, home, home_len + 1);
+ pw->pw_shell = pw->pw_dir + home_len + 1;
+ memcpy(pw->pw_shell, shell, shell_len + 1);
+
+ item = &pwitem->cache;
+ item->refcnt = 1;
+ item->d.pw = pw;
+ if (i == 0) {
+ /* Store by uid. */
+ item->k.uid = pw->pw_uid;
+ pwcache = pwcache_byuid;
+ } else {
+ /* Store by name. */
+ item->k.name = pw->pw_name;
+ pwcache = pwcache_byname;
+ }
+ getauthregistry(NULL, item->registry);
+ switch (rbinsert(pwcache, item, &node)) {
+ case 1:
+ /* Already exists. */
+ item = node->data;
+ if (item->d.pw == NULL) {
+ /* Negative cache entry, replace with ours. */
+ sudo_pw_delref_item(item);
+ item = node->data = &pwitem->cache;
+ } else {
+ /* Good entry, discard our fake one. */
+ free(pwitem);
+ }
+ break;
+ case -1:
+ /* can't cache item, just return it */
+ sudo_warnx(U_("unable to cache user %s, out of memory"), user);
+ item->refcnt = 0;
+ break;
+ }
+ }
+ item->refcnt++;
+ debug_return_ptr(item->d.pw);
+}
+
+/*
+ * Take a uid in string form "#123" and return a faked up passwd struct.
+ */
+struct passwd *
+sudo_fakepwnam(const char *user, gid_t gid)
+{
+ const char *errstr;
+ uid_t uid;
+ debug_decl(sudo_fakepwnam, SUDOERS_DEBUG_NSS)
+
+ uid = (uid_t) sudo_strtoid(user + 1, NULL, NULL, &errstr);
+ if (errstr != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_DIAG|SUDO_DEBUG_LINENO,
+ "uid %s %s", user, errstr);
+ debug_return_ptr(NULL);
+ }
+ debug_return_ptr(sudo_mkpwent(user, uid, gid, NULL, NULL));
+}
+
+void
+sudo_freepwcache(void)
+{
+ debug_decl(sudo_freepwcache, SUDOERS_DEBUG_NSS)
+
+ if (pwcache_byuid != NULL) {
+ rbdestroy(pwcache_byuid, sudo_pw_delref_item);
+ pwcache_byuid = NULL;
+ }
+ if (pwcache_byname != NULL) {
+ rbdestroy(pwcache_byname, sudo_pw_delref_item);
+ pwcache_byname = NULL;
+ }
+
+ debug_return;
+}
+
+/*
+ * Compare by group ID.
+ * v1 is the key to find or data to insert, v2 is in-tree data.
+ */
+static int
+cmp_grgid(const void *v1, const void *v2)
+{
+ const struct cache_item *ci1 = (const struct cache_item *) v1;
+ const struct cache_item *ci2 = (const struct cache_item *) v2;
+ if (ci1->k.gid == ci2->k.gid)
+ return strcmp(ci1->registry, ci2->registry);
+ if (ci1->k.gid < ci2->k.gid)
+ return -1;
+ return 1;
+}
+
+void
+sudo_gr_addref(struct group *gr)
+{
+ debug_decl(sudo_gr_addref, SUDOERS_DEBUG_NSS)
+ ptr_to_item(gr)->refcnt++;
+ debug_return;
+}
+
+static void
+sudo_gr_delref_item(void *v)
+{
+ struct cache_item *item = v;
+ debug_decl(sudo_gr_delref_item, SUDOERS_DEBUG_NSS)
+
+ if (--item->refcnt == 0)
+ free(item);
+
+ debug_return;
+}
+
+void
+sudo_gr_delref(struct group *gr)
+{
+ debug_decl(sudo_gr_delref, SUDOERS_DEBUG_NSS)
+ sudo_gr_delref_item(ptr_to_item(gr));
+ debug_return;
+}
+
+/*
+ * Get a group entry by gid and allocate space for it.
+ */
+struct group *
+sudo_getgrgid(gid_t gid)
+{
+ struct cache_item key, *item;
+ struct rbnode *node;
+ debug_decl(sudo_getgrgid, SUDOERS_DEBUG_NSS)
+
+ if (grcache_bygid == NULL) {
+ grcache_bygid = rbcreate(cmp_grgid);
+ if (grcache_bygid == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_ptr(NULL);
+ }
+ }
+
+ key.k.gid = gid;
+ getauthregistry(NULL, key.registry);
+ if ((node = rbfind(grcache_bygid, &key)) != NULL) {
+ item = node->data;
+ goto done;
+ }
+ /*
+ * Cache group db entry if it exists or a negative response if not.
+ */
+ item = make_gritem(gid, NULL);
+ if (item == NULL) {
+ if (errno != ENOENT || (item = calloc(1, sizeof(*item))) == NULL) {
+ sudo_warnx(U_("unable to cache gid %u, out of memory"),
+ (unsigned int) gid);
+ /* cppcheck-suppress memleak */
+ debug_return_ptr(NULL);
+ }
+ item->refcnt = 1;
+ item->k.gid = gid;
+ /* item->d.gr = NULL; */
+ }
+ strlcpy(item->registry, key.registry, sizeof(item->registry));
+ switch (rbinsert(grcache_bygid, item, NULL)) {
+ case 1:
+ /* should not happen */
+ sudo_warnx(U_("unable to cache gid %u, already exists"),
+ (unsigned int) gid);
+ item->refcnt = 0;
+ break;
+ case -1:
+ /* can't cache item, just return it */
+ sudo_warnx(U_("unable to cache gid %u, out of memory"),
+ (unsigned int) gid);
+ item->refcnt = 0;
+ break;
+ }
+done:
+ if (item->refcnt != 0) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s: gid %u [%s] -> group %s [%s] (%s)", __func__,
+ (unsigned int)gid, key.registry,
+ item->d.gr ? item->d.gr->gr_name : "unknown",
+ item->registry, node ? "cache hit" : "cached");
+ }
+ item->refcnt++;
+ debug_return_ptr(item->d.gr);
+}
+
+/*
+ * Get a group entry by name and allocate space for it.
+ */
+struct group *
+sudo_getgrnam(const char *name)
+{
+ struct cache_item key, *item;
+ struct rbnode *node;
+ debug_decl(sudo_getgrnam, SUDOERS_DEBUG_NSS)
+
+ if (grcache_byname == NULL) {
+ grcache_byname = rbcreate(cmp_grnam);
+ if (grcache_byname == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_ptr(NULL);
+ }
+ }
+
+ key.k.name = (char *) name;
+ getauthregistry(NULL, key.registry);
+ if ((node = rbfind(grcache_byname, &key)) != NULL) {
+ item = node->data;
+ goto done;
+ }
+ /*
+ * Cache group db entry if it exists or a negative response if not.
+ */
+ item = make_gritem((gid_t)-1, name);
+ if (item == NULL) {
+ const size_t len = strlen(name) + 1;
+ if (errno != ENOENT || (item = calloc(1, sizeof(*item) + len)) == NULL) {
+ sudo_warnx(U_("unable to cache group %s, out of memory"), name);
+ /* cppcheck-suppress memleak */
+ debug_return_ptr(NULL);
+ }
+ item->refcnt = 1;
+ item->k.name = (char *) item + sizeof(*item);
+ memcpy(item->k.name, name, len);
+ /* item->d.gr = NULL; */
+ }
+ strlcpy(item->registry, key.registry, sizeof(item->registry));
+ switch (rbinsert(grcache_byname, item, NULL)) {
+ case 1:
+ /* should not happen */
+ sudo_warnx(U_("unable to cache group %s, already exists"), name);
+ item->refcnt = 0;
+ break;
+ case -1:
+ /* can't cache item, just return it */
+ sudo_warnx(U_("unable to cache group %s, out of memory"), name);
+ item->refcnt = 0;
+ break;
+ }
+done:
+ if (item->refcnt != 0) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s: group %s [%s] -> gid %d [%s] (%s)", __func__, name,
+ key.registry, item->d.gr ? (int)item->d.gr->gr_gid : -1,
+ item->registry, node ? "cache hit" : "cached");
+ }
+ item->refcnt++;
+ debug_return_ptr(item->d.gr);
+}
+
+/*
+ * Take a gid in string form "#123" and return a faked up group struct.
+ */
+struct group *
+sudo_fakegrnam(const char *group)
+{
+ struct cache_item_gr *gritem;
+ struct cache_item *item;
+ const char *errstr;
+ struct group *gr;
+ size_t len, name_len;
+ int i;
+ debug_decl(sudo_fakegrnam, SUDOERS_DEBUG_NSS)
+
+ if (grcache_bygid == NULL)
+ grcache_bygid = rbcreate(cmp_grgid);
+ if (grcache_byname == NULL)
+ grcache_byname = rbcreate(cmp_grnam);
+ if (grcache_bygid == NULL || grcache_byname == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_ptr(NULL);
+ }
+
+ name_len = strlen(group);
+ len = sizeof(*gritem) + name_len + 1;
+
+ for (i = 0; i < 2; i++) {
+ struct rbtree *grcache;
+ struct rbnode *node;
+
+ gritem = calloc(1, len);
+ if (gritem == NULL) {
+ sudo_warnx(U_("unable to cache group %s, out of memory"), group);
+ debug_return_ptr(NULL);
+ }
+ gr = &gritem->gr;
+ gr->gr_gid = (gid_t) sudo_strtoid(group + 1, NULL, NULL, &errstr);
+ gr->gr_name = (char *)(gritem + 1);
+ memcpy(gr->gr_name, group, name_len + 1);
+ if (errstr != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_DIAG|SUDO_DEBUG_LINENO,
+ "gid %s %s", group, errstr);
+ free(gritem);
+ debug_return_ptr(NULL);
+ }
+
+ item = &gritem->cache;
+ item->refcnt = 1;
+ item->d.gr = gr;
+ if (i == 0) {
+ /* Store by gid if it doesn't already exist. */
+ item->k.gid = gr->gr_gid;
+ grcache = grcache_bygid;
+ } else {
+ /* Store by name, overwriting cached version. */
+ gritem->cache.k.name = gr->gr_name;
+ grcache = grcache_byname;
+ }
+ getauthregistry(NULL, item->registry);
+ switch (rbinsert(grcache, item, &node)) {
+ case 1:
+ /* Already exists. */
+ item = node->data;
+ if (item->d.gr == NULL) {
+ /* Negative cache entry, replace with ours. */
+ sudo_gr_delref_item(item);
+ item = node->data = &gritem->cache;
+ } else {
+ /* Good entry, discard our fake one. */
+ free(gritem);
+ }
+ break;
+ case -1:
+ /* can't cache item, just return it */
+ sudo_warnx(U_("unable to cache group %s, out of memory"), group);
+ item->refcnt = 0;
+ break;
+ }
+ }
+ item->refcnt++;
+ debug_return_ptr(item->d.gr);
+}
+
+void
+sudo_gidlist_addref(struct gid_list *gidlist)
+{
+ debug_decl(sudo_gidlist_addref, SUDOERS_DEBUG_NSS)
+ ptr_to_item(gidlist)->refcnt++;
+ debug_return;
+}
+
+static void
+sudo_gidlist_delref_item(void *v)
+{
+ struct cache_item *item = v;
+ debug_decl(sudo_gidlist_delref_item, SUDOERS_DEBUG_NSS)
+
+ if (--item->refcnt == 0)
+ free(item);
+
+ debug_return;
+}
+
+void
+sudo_gidlist_delref(struct gid_list *gidlist)
+{
+ debug_decl(sudo_gidlist_delref, SUDOERS_DEBUG_NSS)
+ sudo_gidlist_delref_item(ptr_to_item(gidlist));
+ debug_return;
+}
+
+void
+sudo_grlist_addref(struct group_list *grlist)
+{
+ debug_decl(sudo_grlist_addref, SUDOERS_DEBUG_NSS)
+ ptr_to_item(grlist)->refcnt++;
+ debug_return;
+}
+
+static void
+sudo_grlist_delref_item(void *v)
+{
+ struct cache_item *item = v;
+ debug_decl(sudo_grlist_delref_item, SUDOERS_DEBUG_NSS)
+
+ if (--item->refcnt == 0)
+ free(item);
+
+ debug_return;
+}
+
+void
+sudo_grlist_delref(struct group_list *grlist)
+{
+ debug_decl(sudo_grlist_delref, SUDOERS_DEBUG_NSS)
+ sudo_grlist_delref_item(ptr_to_item(grlist));
+ debug_return;
+}
+
+void
+sudo_freegrcache(void)
+{
+ debug_decl(sudo_freegrcache, SUDOERS_DEBUG_NSS)
+
+ if (grcache_bygid != NULL) {
+ rbdestroy(grcache_bygid, sudo_gr_delref_item);
+ grcache_bygid = NULL;
+ }
+ if (grcache_byname != NULL) {
+ rbdestroy(grcache_byname, sudo_gr_delref_item);
+ grcache_byname = NULL;
+ }
+ if (grlist_cache != NULL) {
+ rbdestroy(grlist_cache, sudo_grlist_delref_item);
+ grlist_cache = NULL;
+ }
+ if (gidlist_cache != NULL) {
+ rbdestroy(gidlist_cache, sudo_gidlist_delref_item);
+ gidlist_cache = NULL;
+ }
+
+ debug_return;
+}
+
+struct group_list *
+sudo_get_grlist(const struct passwd *pw)
+{
+ struct cache_item key, *item;
+ struct rbnode *node;
+ debug_decl(sudo_get_grlist, SUDOERS_DEBUG_NSS)
+
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: looking up group names for %s",
+ __func__, pw->pw_name);
+
+ if (grlist_cache == NULL) {
+ grlist_cache = rbcreate(cmp_pwnam);
+ if (grlist_cache == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_ptr(NULL);
+ }
+ }
+
+ key.k.name = pw->pw_name;
+ getauthregistry(pw->pw_name, key.registry);
+ if ((node = rbfind(grlist_cache, &key)) != NULL) {
+ item = node->data;
+ goto done;
+ }
+ /*
+ * Cache group db entry if it exists or a negative response if not.
+ */
+ item = make_grlist_item(pw, NULL);
+ if (item == NULL) {
+ /* Out of memory? */
+ debug_return_ptr(NULL);
+ }
+ strlcpy(item->registry, key.registry, sizeof(item->registry));
+ switch (rbinsert(grlist_cache, item, NULL)) {
+ case 1:
+ /* should not happen */
+ sudo_warnx(U_("unable to cache group list for %s, already exists"),
+ pw->pw_name);
+ item->refcnt = 0;
+ break;
+ case -1:
+ /* can't cache item, just return it */
+ sudo_warnx(U_("unable to cache group list for %s, out of memory"),
+ pw->pw_name);
+ item->refcnt = 0;
+ break;
+ }
+ if (item->d.grlist != NULL) {
+ int i;
+ for (i = 0; i < item->d.grlist->ngroups; i++) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s: user %s is a member of group %s", __func__,
+ pw->pw_name, item->d.grlist->groups[i]);
+ }
+ }
+done:
+ item->refcnt++;
+ debug_return_ptr(item->d.grlist);
+}
+
+int
+sudo_set_grlist(struct passwd *pw, char * const *groups)
+{
+ struct cache_item key, *item;
+ struct rbnode *node;
+ debug_decl(sudo_set_grlist, SUDOERS_DEBUG_NSS)
+
+ if (grlist_cache == NULL) {
+ grlist_cache = rbcreate(cmp_pwnam);
+ if (grlist_cache == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+ }
+
+ /*
+ * Cache group db entry if it doesn't already exist
+ */
+ key.k.name = pw->pw_name;
+ getauthregistry(NULL, key.registry);
+ if ((node = rbfind(grlist_cache, &key)) == NULL) {
+ if ((item = make_grlist_item(pw, groups)) == NULL) {
+ sudo_warnx(U_("unable to parse groups for %s"), pw->pw_name);
+ debug_return_int(-1);
+ }
+ strlcpy(item->registry, key.registry, sizeof(item->registry));
+ switch (rbinsert(grlist_cache, item, NULL)) {
+ case 1:
+ sudo_warnx(U_("unable to cache group list for %s, already exists"),
+ pw->pw_name);
+ sudo_grlist_delref_item(item);
+ break;
+ case -1:
+ sudo_warnx(U_("unable to cache group list for %s, out of memory"),
+ pw->pw_name);
+ sudo_grlist_delref_item(item);
+ debug_return_int(-1);
+ }
+ }
+ debug_return_int(0);
+}
+
+struct gid_list *
+sudo_get_gidlist(const struct passwd *pw, unsigned int type)
+{
+ struct cache_item key, *item;
+ struct rbnode *node;
+ debug_decl(sudo_get_gidlist, SUDOERS_DEBUG_NSS)
+
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: looking up group IDs for %s",
+ __func__, pw->pw_name);
+
+ if (gidlist_cache == NULL) {
+ gidlist_cache = rbcreate(cmp_gidlist);
+ if (gidlist_cache == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_ptr(NULL);
+ }
+ }
+
+ key.k.name = pw->pw_name;
+ key.type = type;
+ getauthregistry(pw->pw_name, key.registry);
+ if ((node = rbfind(gidlist_cache, &key)) != NULL) {
+ item = node->data;
+ goto done;
+ }
+ /*
+ * Cache group db entry if it exists or a negative response if not.
+ */
+ item = make_gidlist_item(pw, NULL, type);
+ if (item == NULL) {
+ /* Out of memory? */
+ debug_return_ptr(NULL);
+ }
+ strlcpy(item->registry, key.registry, sizeof(item->registry));
+ switch (rbinsert(gidlist_cache, item, NULL)) {
+ case 1:
+ /* should not happen */
+ sudo_warnx(U_("unable to cache group list for %s, already exists"),
+ pw->pw_name);
+ item->refcnt = 0;
+ break;
+ case -1:
+ /* can't cache item, just return it */
+ sudo_warnx(U_("unable to cache group list for %s, out of memory"),
+ pw->pw_name);
+ item->refcnt = 0;
+ break;
+ }
+ if (item->d.gidlist != NULL) {
+ int i;
+ for (i = 0; i < item->d.gidlist->ngids; i++) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s: user %s has supplementary gid %u", __func__,
+ pw->pw_name, (unsigned int)item->d.gidlist->gids[i]);
+ }
+ }
+done:
+ item->refcnt++;
+ debug_return_ptr(item->d.gidlist);
+}
+
+int
+sudo_set_gidlist(struct passwd *pw, char * const *gids, unsigned int type)
+{
+ struct cache_item key, *item;
+ struct rbnode *node;
+ debug_decl(sudo_set_gidlist, SUDOERS_DEBUG_NSS)
+
+ if (gidlist_cache == NULL) {
+ gidlist_cache = rbcreate(cmp_gidlist);
+ if (gidlist_cache == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+ }
+
+ /*
+ * Cache group db entry if it doesn't already exist
+ */
+ key.k.name = pw->pw_name;
+ key.type = type;
+ getauthregistry(NULL, key.registry);
+ if ((node = rbfind(gidlist_cache, &key)) == NULL) {
+ if ((item = make_gidlist_item(pw, gids, type)) == NULL) {
+ sudo_warnx(U_("unable to parse gids for %s"), pw->pw_name);
+ debug_return_int(-1);
+ }
+ strlcpy(item->registry, key.registry, sizeof(item->registry));
+ switch (rbinsert(gidlist_cache, item, NULL)) {
+ case 1:
+ sudo_warnx(U_("unable to cache group list for %s, already exists"),
+ pw->pw_name);
+ sudo_gidlist_delref_item(item);
+ break;
+ case -1:
+ sudo_warnx(U_("unable to cache group list for %s, out of memory"),
+ pw->pw_name);
+ sudo_gidlist_delref_item(item);
+ debug_return_int(-1);
+ }
+ }
+ debug_return_int(0);
+}
+
+bool
+user_in_group(const struct passwd *pw, const char *group)
+{
+ struct group_list *grlist = NULL;
+ struct gid_list *gidlist = NULL;
+ struct group *grp = NULL;
+ bool matched = false;
+ int i;
+ debug_decl(user_in_group, SUDOERS_DEBUG_NSS)
+
+ /*
+ * If it could be a sudo-style group ID check gids first.
+ */
+ if (group[0] == '#') {
+ const char *errstr;
+ gid_t gid = (gid_t) sudo_strtoid(group + 1, NULL, NULL, &errstr);
+ if (errstr != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_DIAG|SUDO_DEBUG_LINENO,
+ "gid %s %s", group, errstr);
+ } else {
+ if (gid == pw->pw_gid) {
+ matched = true;
+ goto done;
+ }
+ if ((gidlist = sudo_get_gidlist(pw, ENTRY_TYPE_ANY)) != NULL) {
+ for (i = 0; i < gidlist->ngids; i++) {
+ if (gid == gidlist->gids[i]) {
+ matched = true;
+ goto done;
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Next match the group name. By default, sudoers resolves all the user's
+ * group IDs to names and matches by name. If match_group_by_gid is
+ * set, each group is sudoers is resolved and matching is by group ID.
+ */
+ if (def_match_group_by_gid) {
+ gid_t gid;
+
+ /* Look up the ID of the group in sudoers. */
+ if ((grp = sudo_getgrnam(group)) == NULL)
+ goto done;
+ gid = grp->gr_gid;
+
+ /* Check against user's primary (passwd file) group ID. */
+ if (gid == pw->pw_gid) {
+ matched = true;
+ goto done;
+ }
+
+ /* Check the supplementary group vector. */
+ if (gidlist == NULL) {
+ if ((gidlist = sudo_get_gidlist(pw, ENTRY_TYPE_ANY)) != NULL) {
+ for (i = 0; i < gidlist->ngids; i++) {
+ if (gid == gidlist->gids[i]) {
+ matched = true;
+ goto done;
+ }
+ }
+ }
+ }
+ } else if ((grlist = sudo_get_grlist(pw)) != NULL) {
+ int (*compare)(const char *, const char *);
+ if (def_case_insensitive_group)
+ compare = strcasecmp;
+ else
+ compare = strcmp;
+
+ /* Check the supplementary group vector. */
+ for (i = 0; i < grlist->ngroups; i++) {
+ if (compare(group, grlist->groups[i]) == 0) {
+ matched = true;
+ goto done;
+ }
+ }
+
+ /* Check against user's primary (passwd file) group. */
+ if ((grp = sudo_getgrgid(pw->pw_gid)) != NULL) {
+ if (compare(group, grp->gr_name) == 0) {
+ matched = true;
+ goto done;
+ }
+ }
+ }
+
+done:
+ if (grp != NULL)
+ sudo_gr_delref(grp);
+ if (grlist != NULL)
+ sudo_grlist_delref(grlist);
+ if (gidlist != NULL)
+ sudo_gidlist_delref(gidlist);
+
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: user %s %sin group %s",
+ __func__, pw->pw_name, matched ? "" : "NOT ", group);
+ debug_return_bool(matched);
+}
diff --git a/plugins/sudoers/pwutil.h b/plugins/sudoers/pwutil.h
new file mode 100644
index 0000000..7c36e70
--- /dev/null
+++ b/plugins/sudoers/pwutil.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010-2013, 2015-2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_PWUTIL_H
+#define SUDOERS_PWUTIL_H
+
+#define ptr_to_item(p) ((struct cache_item *)((char *)p - offsetof(struct cache_item_##p, p)))
+
+/*
+ * Generic cache element.
+ */
+struct cache_item {
+ unsigned int refcnt;
+ unsigned int type; /* only used for gidlist */
+ char registry[16]; /* AIX-specific, empty otherwise */
+ /* key */
+ union {
+ uid_t uid;
+ gid_t gid;
+ char *name;
+ } k;
+ /* datum */
+ union {
+ struct passwd *pw;
+ struct group *gr;
+ struct group_list *grlist;
+ struct gid_list *gidlist;
+ } d;
+};
+
+/*
+ * Container structs to simpify size and offset calculations and guarantee
+ * proper aligment of struct passwd, group, gid_list and group_list.
+ */
+struct cache_item_pw {
+ struct cache_item cache;
+ struct passwd pw;
+};
+
+struct cache_item_gr {
+ struct cache_item cache;
+ struct group gr;
+};
+
+struct cache_item_grlist {
+ struct cache_item cache;
+ struct group_list grlist;
+ /* actually bigger */
+};
+
+struct cache_item_gidlist {
+ struct cache_item cache;
+ struct gid_list gidlist;
+ /* actually bigger */
+};
+
+struct cache_item *sudo_make_gritem(gid_t gid, const char *group);
+struct cache_item *sudo_make_grlist_item(const struct passwd *pw, char * const *groups);
+struct cache_item *sudo_make_gidlist_item(const struct passwd *pw, char * const *gids, unsigned int type);
+struct cache_item *sudo_make_pwitem(uid_t uid, const char *user);
+
+#endif /* SUDOERS_PWUTIL_H */
diff --git a/plugins/sudoers/pwutil_impl.c b/plugins/sudoers/pwutil_impl.c
new file mode 100644
index 0000000..b6251ff
--- /dev/null
+++ b/plugins/sudoers/pwutil_impl.c
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "sudoers.h"
+#include "pwutil.h"
+
+#ifndef LOGIN_NAME_MAX
+# ifdef _POSIX_LOGIN_NAME_MAX
+# define LOGIN_NAME_MAX _POSIX_LOGIN_NAME_MAX
+# else
+# define LOGIN_NAME_MAX 9
+# endif
+#endif /* LOGIN_NAME_MAX */
+
+#define FIELD_SIZE(src, name, size) \
+do { \
+ if (src->name) { \
+ size = strlen(src->name) + 1; \
+ total += size; \
+ } \
+} while (0)
+
+#define FIELD_COPY(src, dst, name, size) \
+do { \
+ if (src->name) { \
+ memcpy(cp, src->name, size); \
+ dst->name = cp; \
+ cp += size; \
+ } \
+} while (0)
+
+/*
+ * Dynamically allocate space for a struct item plus the key and data
+ * elements. If name is non-NULL it is used as the key, else the
+ * uid is the key. Fills in datum from struct password.
+ * Returns NULL on calloc error or unknown name/id, setting errno
+ * to ENOMEM or ENOENT respectively.
+ */
+struct cache_item *
+sudo_make_pwitem(uid_t uid, const char *name)
+{
+ char *cp;
+ const char *pw_shell;
+ size_t nsize, psize, csize, gsize, dsize, ssize, total;
+ struct cache_item_pw *pwitem;
+ struct passwd *pw, *newpw;
+ debug_decl(sudo_make_pwitem, SUDOERS_DEBUG_NSS)
+
+ /* Look up by name or uid. */
+ pw = name ? getpwnam(name) : getpwuid(uid);
+ if (pw == NULL) {
+ errno = ENOENT;
+ debug_return_ptr(NULL);
+ }
+
+ /* If shell field is empty, expand to _PATH_BSHELL. */
+ pw_shell = (pw->pw_shell == NULL || pw->pw_shell[0] == '\0')
+ ? _PATH_BSHELL : pw->pw_shell;
+
+ /* Allocate in one big chunk for easy freeing. */
+ nsize = psize = csize = gsize = dsize = ssize = 0;
+ total = sizeof(*pwitem);
+ FIELD_SIZE(pw, pw_name, nsize);
+ FIELD_SIZE(pw, pw_passwd, psize);
+#ifdef HAVE_LOGIN_CAP_H
+ FIELD_SIZE(pw, pw_class, csize);
+#endif
+ FIELD_SIZE(pw, pw_gecos, gsize);
+ FIELD_SIZE(pw, pw_dir, dsize);
+ /* Treat shell specially since we expand "" -> _PATH_BSHELL */
+ ssize = strlen(pw_shell) + 1;
+ total += ssize;
+ if (name != NULL)
+ total += strlen(name) + 1;
+
+ /* Allocate space for struct item, struct passwd and the strings. */
+ if ((pwitem = calloc(1, total)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+ newpw = &pwitem->pw;
+
+ /*
+ * Copy in passwd contents and make strings relative to space
+ * at the end of the struct.
+ */
+ memcpy(newpw, pw, sizeof(*pw));
+ cp = (char *)(pwitem + 1);
+ FIELD_COPY(pw, newpw, pw_name, nsize);
+ FIELD_COPY(pw, newpw, pw_passwd, psize);
+#ifdef HAVE_LOGIN_CAP_H
+ FIELD_COPY(pw, newpw, pw_class, csize);
+#endif
+ FIELD_COPY(pw, newpw, pw_gecos, gsize);
+ FIELD_COPY(pw, newpw, pw_dir, dsize);
+ /* Treat shell specially since we expand "" -> _PATH_BSHELL */
+ memcpy(cp, pw_shell, ssize);
+ newpw->pw_shell = cp;
+ cp += ssize;
+
+ /* Set key and datum. */
+ if (name != NULL) {
+ memcpy(cp, name, strlen(name) + 1);
+ pwitem->cache.k.name = cp;
+ } else {
+ pwitem->cache.k.uid = pw->pw_uid;
+ }
+ pwitem->cache.d.pw = newpw;
+ pwitem->cache.refcnt = 1;
+
+ debug_return_ptr(&pwitem->cache);
+}
+
+/*
+ * Dynamically allocate space for a struct item plus the key and data
+ * elements. If name is non-NULL it is used as the key, else the
+ * gid is the key. Fills in datum from struct group.
+ * Returns NULL on calloc error or unknown name/id, setting errno
+ * to ENOMEM or ENOENT respectively.
+ */
+struct cache_item *
+sudo_make_gritem(gid_t gid, const char *name)
+{
+ char *cp;
+ size_t nsize, psize, nmem, total, len;
+ struct cache_item_gr *gritem;
+ struct group *gr, *newgr;
+ debug_decl(sudo_make_gritem, SUDOERS_DEBUG_NSS)
+
+ /* Look up by name or gid. */
+ gr = name ? getgrnam(name) : getgrgid(gid);
+ if (gr == NULL) {
+ errno = ENOENT;
+ debug_return_ptr(NULL);
+ }
+
+ /* Allocate in one big chunk for easy freeing. */
+ nsize = psize = nmem = 0;
+ total = sizeof(*gritem);
+ FIELD_SIZE(gr, gr_name, nsize);
+ FIELD_SIZE(gr, gr_passwd, psize);
+ if (gr->gr_mem) {
+ for (nmem = 0; gr->gr_mem[nmem] != NULL; nmem++)
+ total += strlen(gr->gr_mem[nmem]) + 1;
+ nmem++;
+ total += sizeof(char *) * nmem;
+ }
+ if (name != NULL)
+ total += strlen(name) + 1;
+
+ if ((gritem = calloc(1, total)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+
+ /*
+ * Copy in group contents and make strings relative to space
+ * at the end of the buffer. Note that gr_mem must come
+ * immediately after struct group to guarantee proper alignment.
+ */
+ newgr = &gritem->gr;
+ memcpy(newgr, gr, sizeof(*gr));
+ cp = (char *)(gritem + 1);
+ if (gr->gr_mem) {
+ newgr->gr_mem = (char **)cp;
+ cp += sizeof(char *) * nmem;
+ for (nmem = 0; gr->gr_mem[nmem] != NULL; nmem++) {
+ len = strlen(gr->gr_mem[nmem]) + 1;
+ memcpy(cp, gr->gr_mem[nmem], len);
+ newgr->gr_mem[nmem] = cp;
+ cp += len;
+ }
+ newgr->gr_mem[nmem] = NULL;
+ }
+ FIELD_COPY(gr, newgr, gr_passwd, psize);
+ FIELD_COPY(gr, newgr, gr_name, nsize);
+
+ /* Set key and datum. */
+ if (name != NULL) {
+ memcpy(cp, name, strlen(name) + 1);
+ gritem->cache.k.name = cp;
+ } else {
+ gritem->cache.k.gid = gr->gr_gid;
+ }
+ gritem->cache.d.gr = newgr;
+ gritem->cache.refcnt = 1;
+
+ debug_return_ptr(&gritem->cache);
+}
+
+/*
+ * Dynamically allocate space for a struct item plus the key and data
+ * elements. Fills in datum from user_gids or from sudo_getgrouplist2(3).
+ */
+struct cache_item *
+sudo_make_gidlist_item(const struct passwd *pw, char * const *unused1,
+ unsigned int type)
+{
+ char *cp;
+ size_t nsize, total;
+ struct cache_item_gidlist *glitem;
+ struct gid_list *gidlist;
+ GETGROUPS_T *gids;
+ int i, ngids;
+ debug_decl(sudo_make_gidlist_item, SUDOERS_DEBUG_NSS)
+
+ /* Don't use user_gids if the entry type says we must query the db. */
+ if (type != ENTRY_TYPE_QUERIED && pw == sudo_user.pw && sudo_user.gids != NULL) {
+ gids = user_gids;
+ ngids = user_ngids;
+ user_gids = NULL;
+ user_ngids = 0;
+ type = ENTRY_TYPE_FRONTEND;
+ } else {
+ type = ENTRY_TYPE_QUERIED;
+ if (sudo_user.max_groups > 0) {
+ ngids = sudo_user.max_groups;
+ gids = reallocarray(NULL, ngids, sizeof(GETGROUPS_T));
+ if (gids == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+ (void)sudo_getgrouplist2(pw->pw_name, pw->pw_gid, &gids, &ngids);
+ } else {
+ gids = NULL;
+ if (sudo_getgrouplist2(pw->pw_name, pw->pw_gid, &gids, &ngids) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+ }
+ }
+ if (ngids <= 0) {
+ free(gids);
+ errno = ENOENT;
+ debug_return_ptr(NULL);
+ }
+
+ /* Allocate in one big chunk for easy freeing. */
+ nsize = strlen(pw->pw_name) + 1;
+ total = sizeof(*glitem) + nsize;
+ total += sizeof(gid_t *) * ngids;
+
+ if ((glitem = calloc(1, total)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ free(gids);
+ debug_return_ptr(NULL);
+ }
+
+ /*
+ * Copy in group list and make pointers relative to space
+ * at the end of the buffer. Note that the groups array must come
+ * immediately after struct group to guarantee proper alignment.
+ */
+ gidlist = &glitem->gidlist;
+ cp = (char *)(glitem + 1);
+ gidlist->gids = (gid_t *)cp;
+ cp += sizeof(gid_t) * ngids;
+
+ /* Set key and datum. */
+ memcpy(cp, pw->pw_name, nsize);
+ glitem->cache.k.name = cp;
+ glitem->cache.d.gidlist = gidlist;
+ glitem->cache.refcnt = 1;
+ glitem->cache.type = type;
+
+ /*
+ * Store group IDs.
+ */
+ for (i = 0; i < ngids; i++)
+ gidlist->gids[i] = gids[i];
+ gidlist->ngids = ngids;
+ free(gids);
+
+ debug_return_ptr(&glitem->cache);
+}
+
+/*
+ * Dynamically allocate space for a struct item plus the key and data
+ * elements. Fills in group names from a call to sudo_get_gidlist().
+ */
+struct cache_item *
+sudo_make_grlist_item(const struct passwd *pw, char * const *unused1)
+{
+ char *cp;
+ size_t nsize, ngroups, total, len;
+ struct cache_item_grlist *grlitem;
+ struct group_list *grlist;
+ struct gid_list *gidlist;
+ struct group *grp = NULL;
+ int i, groupname_len;
+ debug_decl(sudo_make_grlist_item, SUDOERS_DEBUG_NSS)
+
+ gidlist = sudo_get_gidlist(pw, ENTRY_TYPE_ANY);
+ if (gidlist == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "no gid list for use %s", pw->pw_name);
+ errno = ENOENT;
+ debug_return_ptr(NULL);
+ }
+
+#ifdef _SC_LOGIN_NAME_MAX
+ groupname_len = MAX((int)sysconf(_SC_LOGIN_NAME_MAX), 32);
+#else
+ groupname_len = MAX(LOGIN_NAME_MAX, 32);
+#endif
+
+ /* Allocate in one big chunk for easy freeing. */
+ nsize = strlen(pw->pw_name) + 1;
+ total = sizeof(*grlitem) + nsize;
+ total += groupname_len * gidlist->ngids;
+
+again:
+ if ((grlitem = calloc(1, total)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ sudo_gidlist_delref(gidlist);
+ debug_return_ptr(NULL);
+ }
+
+ /*
+ * Copy in group list and make pointers relative to space
+ * at the end of the buffer. Note that the groups array must come
+ * immediately after struct group to guarantee proper alignment.
+ */
+ grlist = &grlitem->grlist;
+ cp = (char *)(grlitem + 1);
+ grlist->groups = (char **)cp;
+ cp += sizeof(char *) * gidlist->ngids;
+
+ /* Set key and datum. */
+ memcpy(cp, pw->pw_name, nsize);
+ grlitem->cache.k.name = cp;
+ grlitem->cache.d.grlist = grlist;
+ grlitem->cache.refcnt = 1;
+ cp += nsize;
+
+ /*
+ * Resolve and store group names by ID.
+ */
+#ifdef HAVE_SETAUTHDB
+ if (grp == NULL)
+ aix_setauthdb((char *) pw->pw_name, NULL);
+#endif
+ ngroups = 0;
+ for (i = 0; i < gidlist->ngids; i++) {
+ if ((grp = sudo_getgrgid(gidlist->gids[i])) != NULL) {
+ len = strlen(grp->gr_name) + 1;
+ if (cp - (char *)grlitem + len > total) {
+ total += len + groupname_len;
+ free(grlitem);
+ sudo_gr_delref(grp);
+ goto again;
+ }
+ memcpy(cp, grp->gr_name, len);
+ grlist->groups[ngroups++] = cp;
+ cp += len;
+ sudo_gr_delref(grp);
+ }
+ }
+ grlist->ngroups = ngroups;
+ sudo_gidlist_delref(gidlist);
+
+#ifdef HAVE_SETAUTHDB
+ aix_restoreauthdb();
+#endif
+
+ debug_return_ptr(&grlitem->cache);
+}
diff --git a/plugins/sudoers/rcstr.c b/plugins/sudoers/rcstr.c
new file mode 100644
index 0000000..8ad2d5d
--- /dev/null
+++ b/plugins/sudoers/rcstr.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2016-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "sudoers.h"
+
+/* Trivial reference-counted strings. */
+struct rcstr {
+ int refcnt;
+ char str[1]; /* actually bigger */
+};
+
+/*
+ * Allocate a reference-counted string and copy src to it.
+ * Returns the newly-created string with a refcnt of 1.
+ */
+char *
+rcstr_dup(const char *src)
+{
+ size_t len = strlen(src);
+ char *dst;
+ debug_decl(rcstr_dup, SUDOERS_DEBUG_UTIL)
+
+ dst = rcstr_alloc(len);
+ memcpy(dst, src, len);
+ dst[len] = '\0';
+ debug_return_ptr(dst);
+}
+
+char *
+rcstr_alloc(size_t len)
+{
+ struct rcstr *rcs;
+ debug_decl(rcstr_dup, SUDOERS_DEBUG_UTIL)
+
+ /* Note: sizeof(struct rcstr) includes space for the NUL */
+ rcs = malloc(sizeof(struct rcstr) + len);
+ if (rcs == NULL)
+ return NULL;
+
+ rcs->refcnt = 1;
+ rcs->str[0] = '\0';
+ /* cppcheck-suppress memleak */
+ debug_return_ptr(rcs->str);
+}
+
+char *
+rcstr_addref(const char *s)
+{
+ struct rcstr *rcs;
+ debug_decl(rcstr_dup, SUDOERS_DEBUG_UTIL)
+
+ if (s == NULL)
+ debug_return_ptr(NULL);
+
+ rcs = __containerof((const void *)s, struct rcstr, str);
+ rcs->refcnt++;
+ debug_return_ptr(rcs->str);
+}
+
+void
+rcstr_delref(const char *s)
+{
+ struct rcstr *rcs;
+ debug_decl(rcstr_dup, SUDOERS_DEBUG_UTIL)
+
+ if (s != NULL) {
+ rcs = __containerof((const void *)s, struct rcstr, str);
+ if (--rcs->refcnt == 0) {
+ rcs->str[0] = '\0';
+ free(rcs);
+ }
+ }
+ debug_return;
+}
diff --git a/plugins/sudoers/redblack.c b/plugins/sudoers/redblack.c
new file mode 100644
index 0000000..ef7e8f5
--- /dev/null
+++ b/plugins/sudoers/redblack.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright (c) 2004-2005, 2007, 2009-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+/*
+ * Adapted from the following code written by Emin Martinian:
+ * http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
+ *
+ * Copyright (c) 2001 Emin Martinian
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that neither the name of Emin
+ * Martinian nor the names of any contributors are be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sudoers.h"
+#include "redblack.h"
+
+static void rbrepair(struct rbtree *, struct rbnode *);
+static void rotate_left(struct rbtree *, struct rbnode *);
+static void rotate_right(struct rbtree *, struct rbnode *);
+static void rbdestroy_int(struct rbtree *, struct rbnode *, void (*)(void *));
+
+/*
+ * Red-Black tree, see http://en.wikipedia.org/wiki/Red-black_tree
+ *
+ * A red-black tree is a binary search tree where each node has a color
+ * attribute, the value of which is either red or black. Essentially, it
+ * is just a convenient way to express a 2-3-4 binary search tree where
+ * the color indicates whether the node is part of a 3-node or a 4-node.
+ * In addition to the ordinary requirements imposed on binary search
+ * trees, we make the following additional requirements of any valid
+ * red-black tree:
+ * 1) Every node is either red or black.
+ * 2) The root is black.
+ * 3) All leaves are black.
+ * 4) Both children of each red node are black.
+ * 5) The paths from each leaf up to the root each contain the same
+ * number of black nodes.
+ */
+
+/*
+ * Create a red black tree struct using the specified compare routine.
+ * Allocates and returns the initialized (empty) tree or NULL if
+ * memory cannot be allocated.
+ */
+struct rbtree *
+rbcreate(int (*compar)(const void *, const void*))
+{
+ struct rbtree *tree;
+ debug_decl(rbcreate, SUDOERS_DEBUG_RBTREE)
+
+ if ((tree = malloc(sizeof(*tree))) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+
+ tree->compar = compar;
+
+ /*
+ * We use a self-referencing sentinel node called nil to simplify the
+ * code by avoiding the need to check for NULL pointers.
+ */
+ tree->nil.left = tree->nil.right = tree->nil.parent = &tree->nil;
+ tree->nil.color = black;
+ tree->nil.data = NULL;
+
+ /*
+ * Similarly, the fake root node keeps us from having to worry
+ * about splitting the root.
+ */
+ tree->root.left = tree->root.right = tree->root.parent = &tree->nil;
+ tree->root.color = black;
+ tree->root.data = NULL;
+
+ debug_return_ptr(tree);
+}
+
+/*
+ * Perform a left rotation starting at node.
+ */
+static void
+rotate_left(struct rbtree *tree, struct rbnode *node)
+{
+ struct rbnode *child;
+ debug_decl(rotate_left, SUDOERS_DEBUG_RBTREE)
+
+ child = node->right;
+ node->right = child->left;
+
+ if (child->left != rbnil(tree))
+ child->left->parent = node;
+ child->parent = node->parent;
+
+ if (node == node->parent->left)
+ node->parent->left = child;
+ else
+ node->parent->right = child;
+ child->left = node;
+ node->parent = child;
+
+ debug_return;
+}
+
+/*
+ * Perform a right rotation starting at node.
+ */
+static void
+rotate_right(struct rbtree *tree, struct rbnode *node)
+{
+ struct rbnode *child;
+ debug_decl(rotate_right, SUDOERS_DEBUG_RBTREE)
+
+ child = node->left;
+ node->left = child->right;
+
+ if (child->right != rbnil(tree))
+ child->right->parent = node;
+ child->parent = node->parent;
+
+ if (node == node->parent->left)
+ node->parent->left = child;
+ else
+ node->parent->right = child;
+ child->right = node;
+ node->parent = child;
+
+ debug_return;
+}
+
+/*
+ * Insert data pointer into a redblack tree.
+ * Returns a 0 on success, 1 if a node matching "data" already exists
+ * (filling in "existing" if not NULL), or -1 on malloc() failure.
+ */
+int
+rbinsert(struct rbtree *tree, void *data, struct rbnode **existing)
+{
+ struct rbnode *node = rbfirst(tree);
+ struct rbnode *parent = rbroot(tree);
+ int res;
+ debug_decl(rbinsert, SUDOERS_DEBUG_RBTREE)
+
+ /* Find correct insertion point. */
+ while (node != rbnil(tree)) {
+ parent = node;
+ if ((res = tree->compar(data, node->data)) == 0) {
+ if (existing != NULL)
+ *existing = node;
+ debug_return_int(1);
+ }
+ node = res < 0 ? node->left : node->right;
+ }
+
+ node = malloc(sizeof(*node));
+ if (node == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_int(-1);
+ }
+ node->data = data;
+ node->left = node->right = rbnil(tree);
+ node->parent = parent;
+ if (parent == rbroot(tree) || tree->compar(data, parent->data) < 0)
+ parent->left = node;
+ else
+ parent->right = node;
+ node->color = red;
+
+ /*
+ * If the parent node is black we are all set, if it is red we have
+ * the following possible cases to deal with. We iterate through
+ * the rest of the tree to make sure none of the required properties
+ * is violated.
+ *
+ * 1) The uncle is red. We repaint both the parent and uncle black
+ * and repaint the grandparent node red.
+ *
+ * 2) The uncle is black and the new node is the right child of its
+ * parent, and the parent in turn is the left child of its parent.
+ * We do a left rotation to switch the roles of the parent and
+ * child, relying on further iterations to fixup the old parent.
+ *
+ * 3) The uncle is black and the new node is the left child of its
+ * parent, and the parent in turn is the left child of its parent.
+ * We switch the colors of the parent and grandparent and perform
+ * a right rotation around the grandparent. This makes the former
+ * parent the parent of the new node and the former grandparent.
+ *
+ * Note that because we use a sentinel for the root node we never
+ * need to worry about replacing the root.
+ */
+ while (node->parent->color == red) {
+ struct rbnode *uncle;
+ if (node->parent == node->parent->parent->left) {
+ uncle = node->parent->parent->right;
+ if (uncle->color == red) {
+ node->parent->color = black;
+ uncle->color = black;
+ node->parent->parent->color = red;
+ node = node->parent->parent;
+ } else /* if (uncle->color == black) */ {
+ if (node == node->parent->right) {
+ node = node->parent;
+ rotate_left(tree, node);
+ }
+ node->parent->color = black;
+ node->parent->parent->color = red;
+ rotate_right(tree, node->parent->parent);
+ }
+ } else { /* if (node->parent == node->parent->parent->right) */
+ uncle = node->parent->parent->left;
+ if (uncle->color == red) {
+ node->parent->color = black;
+ uncle->color = black;
+ node->parent->parent->color = red;
+ node = node->parent->parent;
+ } else /* if (uncle->color == black) */ {
+ if (node == node->parent->left) {
+ node = node->parent;
+ rotate_right(tree, node);
+ }
+ node->parent->color = black;
+ node->parent->parent->color = red;
+ rotate_left(tree, node->parent->parent);
+ }
+ }
+ }
+ rbfirst(tree)->color = black; /* first node is always black */
+ debug_return_int(0);
+}
+
+/*
+ * Look for a node matching key in tree.
+ * Returns a pointer to the node if found, else NULL.
+ */
+struct rbnode *
+rbfind(struct rbtree *tree, void *key)
+{
+ struct rbnode *node = rbfirst(tree);
+ int res;
+ debug_decl(rbfind, SUDOERS_DEBUG_RBTREE)
+
+ while (node != rbnil(tree)) {
+ if ((res = tree->compar(key, node->data)) == 0)
+ debug_return_ptr(node);
+ node = res < 0 ? node->left : node->right;
+ }
+ debug_return_ptr(NULL);
+}
+
+/*
+ * Call func() for each node, passing it the node data and a cookie;
+ * If func() returns non-zero for a node, the traversal stops and the
+ * error value is returned. Returns 0 on successful traversal.
+ */
+int
+rbapply_node(struct rbtree *tree, struct rbnode *node,
+ int (*func)(void *, void *), void *cookie, enum rbtraversal order)
+{
+ int error;
+ debug_decl(rbapply_node, SUDOERS_DEBUG_RBTREE)
+
+ if (node != rbnil(tree)) {
+ if (order == preorder)
+ if ((error = func(node->data, cookie)) != 0)
+ debug_return_int(error);
+ if ((error = rbapply_node(tree, node->left, func, cookie, order)) != 0)
+ debug_return_int(error);
+ if (order == inorder)
+ if ((error = func(node->data, cookie)) != 0)
+ debug_return_int(error);
+ if ((error = rbapply_node(tree, node->right, func, cookie, order)) != 0)
+ debug_return_int(error);
+ if (order == postorder)
+ if ((error = func(node->data, cookie)) != 0)
+ debug_return_int(error);
+ }
+ debug_return_int(0);
+}
+
+/*
+ * Returns the successor of node, or nil if there is none.
+ */
+static struct rbnode *
+rbsuccessor(struct rbtree *tree, struct rbnode *node)
+{
+ struct rbnode *succ;
+ debug_decl(rbsuccessor, SUDOERS_DEBUG_RBTREE)
+
+ if ((succ = node->right) != rbnil(tree)) {
+ while (succ->left != rbnil(tree))
+ succ = succ->left;
+ } else {
+ /* No right child, move up until we find it or hit the root */
+ for (succ = node->parent; node == succ->right; succ = succ->parent)
+ node = succ;
+ if (succ == rbroot(tree))
+ succ = rbnil(tree);
+ }
+ debug_return_ptr(succ);
+}
+
+/*
+ * Recursive portion of rbdestroy().
+ */
+static void
+rbdestroy_int(struct rbtree *tree, struct rbnode *node, void (*destroy)(void *))
+{
+ debug_decl(rbdestroy_int, SUDOERS_DEBUG_RBTREE)
+ if (node != rbnil(tree)) {
+ rbdestroy_int(tree, node->left, destroy);
+ rbdestroy_int(tree, node->right, destroy);
+ if (destroy != NULL)
+ destroy(node->data);
+ free(node);
+ }
+ debug_return;
+}
+
+/*
+ * Destroy the specified tree, calling the destructor "destroy"
+ * for each node and then freeing the tree itself.
+ */
+void
+rbdestroy(struct rbtree *tree, void (*destroy)(void *))
+{
+ debug_decl(rbdestroy, SUDOERS_DEBUG_RBTREE)
+ rbdestroy_int(tree, rbfirst(tree), destroy);
+ free(tree);
+ debug_return;
+}
+
+/*
+ * Delete node 'z' from the tree and return its data pointer.
+ */
+void *rbdelete(struct rbtree *tree, struct rbnode *z)
+{
+ struct rbnode *x, *y;
+ void *data = z->data;
+ debug_decl(rbdelete, SUDOERS_DEBUG_RBTREE)
+
+ if (z->left == rbnil(tree) || z->right == rbnil(tree))
+ y = z;
+ else
+ y = rbsuccessor(tree, z);
+ x = (y->left == rbnil(tree)) ? y->right : y->left;
+
+ if ((x->parent = y->parent) == rbroot(tree)) {
+ rbfirst(tree) = x;
+ } else {
+ if (y == y->parent->left)
+ y->parent->left = x;
+ else
+ y->parent->right = x;
+ }
+ if (y->color == black)
+ rbrepair(tree, x);
+ if (y != z) {
+ y->left = z->left;
+ y->right = z->right;
+ y->parent = z->parent;
+ y->color = z->color;
+ z->left->parent = z->right->parent = y;
+ if (z == z->parent->left)
+ z->parent->left = y;
+ else
+ z->parent->right = y;
+ }
+ free(z);
+
+ debug_return_ptr(data);
+}
+
+/*
+ * Repair the tree after a node has been deleted by rotating and repainting
+ * colors to restore the 4 properties inherent in red-black trees.
+ */
+static void
+rbrepair(struct rbtree *tree, struct rbnode *node)
+{
+ struct rbnode *sibling;
+ debug_decl(rbrepair, SUDOERS_DEBUG_RBTREE)
+
+ while (node->color == black && node != rbfirst(tree)) {
+ if (node == node->parent->left) {
+ sibling = node->parent->right;
+ if (sibling->color == red) {
+ sibling->color = black;
+ node->parent->color = red;
+ rotate_left(tree, node->parent);
+ sibling = node->parent->right;
+ }
+ if (sibling->right->color == black && sibling->left->color == black) {
+ sibling->color = red;
+ node = node->parent;
+ } else {
+ if (sibling->right->color == black) {
+ sibling->left->color = black;
+ sibling->color = red;
+ rotate_right(tree, sibling);
+ sibling = node->parent->right;
+ }
+ sibling->color = node->parent->color;
+ node->parent->color = black;
+ sibling->right->color = black;
+ rotate_left(tree, node->parent);
+ node = rbfirst(tree); /* exit loop */
+ }
+ } else { /* if (node == node->parent->right) */
+ sibling = node->parent->left;
+ if (sibling->color == red) {
+ sibling->color = black;
+ node->parent->color = red;
+ rotate_right(tree, node->parent);
+ sibling = node->parent->left;
+ }
+ if (sibling->right->color == black && sibling->left->color == black) {
+ sibling->color = red;
+ node = node->parent;
+ } else {
+ if (sibling->left->color == black) {
+ sibling->right->color = black;
+ sibling->color = red;
+ rotate_left(tree, sibling);
+ sibling = node->parent->left;
+ }
+ sibling->color = node->parent->color;
+ node->parent->color = black;
+ sibling->left->color = black;
+ rotate_right(tree, node->parent);
+ node = rbfirst(tree); /* exit loop */
+ }
+ }
+ }
+ node->color = black;
+
+ debug_return;
+}
diff --git a/plugins/sudoers/redblack.h b/plugins/sudoers/redblack.h
new file mode 100644
index 0000000..2b40636
--- /dev/null
+++ b/plugins/sudoers/redblack.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2004, 2007, 2010, 2013
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_REDBLACK_H
+#define SUDOERS_REDBLACK_H
+
+enum rbcolor {
+ red,
+ black
+};
+
+enum rbtraversal {
+ preorder,
+ inorder,
+ postorder
+};
+
+struct rbnode {
+ struct rbnode *left, *right, *parent;
+ void *data;
+ enum rbcolor color;
+};
+
+struct rbtree {
+ int (*compar)(const void *, const void *);
+ struct rbnode root;
+ struct rbnode nil;
+};
+
+#define rbapply(t, f, c, o) rbapply_node((t), (t)->root.left, (f), (c), (o))
+#define rbisempty(t) ((t)->root.left == &(t)->nil && (t)->root.right == &(t)->nil)
+#define rbfirst(t) ((t)->root.left)
+#define rbroot(t) (&(t)->root)
+#define rbnil(t) (&(t)->nil)
+
+void *rbdelete(struct rbtree *, struct rbnode *);
+int rbapply_node(struct rbtree *, struct rbnode *,
+ int (*)(void *, void *), void *, enum rbtraversal);
+struct rbnode *rbfind(struct rbtree *, void *);
+int rbinsert(struct rbtree *, void *, struct rbnode **);
+struct rbtree *rbcreate(int (*)(const void *, const void *));
+void rbdestroy(struct rbtree *, void (*)(void *));
+
+#endif /* SUDOERS_REDBLACK_H */
diff --git a/plugins/sudoers/regress/check_symbols/check_symbols.c b/plugins/sudoers/regress/check_symbols/check_symbols.c
new file mode 100644
index 0000000..6647609
--- /dev/null
+++ b/plugins/sudoers/regress/check_symbols/check_symbols.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2012-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <errno.h>
+#include <limits.h>
+
+#include "sudo_compat.h"
+#include "sudo_dso.h"
+#include "sudo_util.h"
+#include "sudo_fatal.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s plugin.so symbols_file\n", getprogname());
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ void *handle, *sym;
+ const char *plugin_path;
+ const char *symbols_file;
+ char *cp, line[LINE_MAX];
+ FILE *fp;
+ int ntests = 0, errors = 0;
+
+ initprogname(argc > 0 ? argv[0] : "check_symbols");
+
+ if (argc != 3)
+ usage();
+ plugin_path = argv[1];
+ symbols_file = argv[2];
+
+ handle = sudo_dso_load(plugin_path, SUDO_DSO_LAZY|SUDO_DSO_GLOBAL);
+ if (handle == NULL) {
+ const char *errstr = sudo_dso_strerror();
+ sudo_fatalx_nodebug("unable to load %s: %s", plugin_path,
+ errstr ? errstr : "unknown error");
+ }
+
+ fp = fopen(symbols_file, "r");
+ if (fp == NULL)
+ sudo_fatal_nodebug("unable to open %s", symbols_file);
+
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ ntests++;
+ if ((cp = strchr(line, '\n')) != NULL)
+ *cp = '\0';
+ sym = sudo_dso_findsym(handle, line);
+ if (sym == NULL) {
+ const char *errstr = sudo_dso_strerror();
+ printf("%s: test %d: unable to resolve symbol %s: %s\n",
+ getprogname(), ntests, line, errstr ? errstr : "unknown error");
+ errors++;
+ }
+ }
+
+ /*
+ * Make sure unexported symbols are not available.
+ */
+ ntests++;
+ sym = sudo_dso_findsym(handle, "user_in_group");
+ if (sym != NULL) {
+ printf("%s: test %d: able to resolve local symbol user_in_group\n",
+ getprogname(), ntests);
+ errors++;
+ }
+
+ sudo_dso_unload(handle);
+
+ printf("%s: %d tests run, %d errors, %d%% success rate\n", getprogname(),
+ ntests, errors, (ntests - errors) * 100 / ntests);
+
+ exit(errors);
+}
diff --git a/plugins/sudoers/regress/cvtsudoers/sudoers b/plugins/sudoers/regress/cvtsudoers/sudoers
new file mode 100644
index 0000000..6f66083
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/sudoers
@@ -0,0 +1,126 @@
+#
+# Sample /etc/sudoers file.
+#
+# This file MUST be edited with the 'visudo' command as root.
+#
+# See the sudoers man page for the details on how to write a sudoers file.
+
+##
+# Override built-in defaults
+##
+Defaults syslog=auth
+Defaults>root !set_logname
+Defaults:FULLTIMERS !lecture
+Defaults:millert !authenticate
+Defaults@SERVERS log_year, logfile=/var/log/sudo.log
+Defaults!PAGERS noexec
+
+##
+# User alias specification
+##
+User_Alias FULLTIMERS = millert, mikef, dowdy
+User_Alias PARTTIMERS = bostley, jwfox, crawl
+User_Alias WEBMASTERS = will, wendy, wim
+
+##
+# Runas alias specification
+##
+Runas_Alias OP = root, operator
+Runas_Alias DB = oracle, sybase
+
+##
+# Host alias specification
+##
+Host_Alias SPARC = bigtime, eclipse, moet, anchor:\
+ SGI = grolsch, dandelion, black:\
+ ALPHA = widget, thalamus, foobar:\
+ HPPA = boa, nag, python
+Host_Alias CUNETS = 128.138.0.0/255.255.0.0
+Host_Alias CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0
+Host_Alias SERVERS = master, mail, www, ns
+Host_Alias CDROM = orion, perseus, hercules
+
+##
+# Cmnd alias specification
+##
+Cmnd_Alias DUMPS = /usr/sbin/dump, /usr/sbin/rdump, /usr/sbin/restore, \
+ /usr/sbin/rrestore, /usr/bin/mt, \
+ sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \
+ /home/operator/bin/start_backups
+Cmnd_Alias KILL = /usr/bin/kill, /usr/bin/top
+Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
+Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown
+Cmnd_Alias HALT = /usr/sbin/halt
+Cmnd_Alias REBOOT = /usr/sbin/reboot
+Cmnd_Alias SHELLS = /sbin/sh, /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh, \
+ /usr/local/bin/tcsh, /usr/bin/rsh, \
+ /usr/local/bin/zsh
+Cmnd_Alias SU = /usr/bin/su
+Cmnd_Alias VIPW = /usr/sbin/vipw, /usr/bin/passwd, /usr/bin/chsh, \
+ /usr/bin/chfn
+Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+
+##
+# User specification
+##
+
+# root and users in group wheel can run anything on any machine as any user
+root ALL = (ALL) ALL
+%wheel ALL = (ALL) ALL
+
+# full time sysadmins can run anything on any machine without a password
+FULLTIMERS ALL = NOPASSWD: ALL
+
+# part time sysadmins may run anything but need a password
+PARTTIMERS ALL = ALL
+
+# jack may run anything on machines in CSNETS
+jack CSNETS = ALL
+
+# lisa may run any command on any host in CUNETS (a class B network)
+lisa CUNETS = ALL
+
+# operator may run maintenance commands and anything in /usr/oper/bin/
+operator ALL = DUMPS, KILL, SHUTDOWN, HALT, REBOOT, PRINTING,\
+ sudoedit /etc/printcap, /usr/oper/bin/
+
+# joe may su only to operator
+joe ALL = /usr/bin/su operator
+
+# pete may change passwords for anyone but root on the hp snakes
+pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd *root*
+
+# bob may run anything on the sparc and sgi machines as any user
+# listed in the Runas_Alias "OP" (ie: root and operator)
+bob SPARC = (OP) ALL : SGI = (OP) ALL
+
+# fred can run commands as oracle or sybase without a password
+fred ALL = (DB) NOPASSWD: ALL
+
+# on the alphas, john may su to anyone but root and flags are not allowed
+john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
+
+# jen can run anything on all machines except the ones
+# in the "SERVERS" Host_Alias
+jen ALL, !SERVERS = ALL
+
+# jill can run any commands in the directory /usr/bin/, except for
+# those in the SU and SHELLS aliases.
+jill SERVERS = /usr/bin/, !SU, !SHELLS
+
+# steve can run any command in the directory /usr/local/op_commands/
+# as user operator.
+steve CSNETS = (operator) /usr/local/op_commands/
+
+# matt needs to be able to kill things on his workstation when
+# they get hung.
+matt valkyrie = KILL
+
+# users in the WEBMASTERS User_Alias (will, wendy, and wim)
+# may run any command as user www (which owns the web pages)
+# or simply su to www.
+WEBMASTERS www = (www) ALL, (root) /usr/bin/su www
+
+# anyone can mount/unmount a cd-rom on the machines in the CDROM alias
+ALL CDROM = NOPASSWD: /sbin/umount /CDROM,\
+ /sbin/mount -o nosuid\,nodev /dev/cd0a /CDROM
diff --git a/plugins/sudoers/regress/cvtsudoers/sudoers.defs b/plugins/sudoers/regress/cvtsudoers/sudoers.defs
new file mode 100755
index 0000000..c6bfa93
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/sudoers.defs
@@ -0,0 +1,19 @@
+Defaults syslog=auth
+Defaults>ROOT !set_logname
+Defaults:FULLTIMERS !lecture
+Defaults:millert !authenticate
+Defaults@SERVERS log_year, logfile=/var/log/sudo.log
+Defaults!PAGERS noexec
+
+User_Alias FULLTIMERS = millert, mikef, dowdy
+User_Alias PARTTIMERS = bostley, jwfox, crawl
+
+Host_Alias SERVERS = master, mail, www, ns
+Host_Alias CDROM = orion, perseus, hercules
+
+Cmnd_Alias VIPW = /usr/sbin/vipw, /usr/bin/passwd, /usr/bin/chsh, \
+ /usr/bin/chfn
+Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+
+Runas_Alias ROOT = root, toor
+Runas_Alias OPERATOR = operator, backup
diff --git a/plugins/sudoers/regress/cvtsudoers/test1.out.ok b/plugins/sudoers/regress/cvtsudoers/test1.out.ok
new file mode 100644
index 0000000..da3f555
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test1.out.ok
@@ -0,0 +1,14 @@
+Defaults syslog=auth
+Defaults>root !set_logname
+Defaults:FULLTIMERS !lecture
+Defaults:millert !authenticate
+Defaults!PAGERS noexec
+
+Host_Alias CDROM = orion, perseus, hercules
+User_Alias FULLTIMERS = millert, mikef, dowdy
+Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+
+FULLTIMERS ALL = NOPASSWD: ALL
+
+ALL CDROM = NOPASSWD: /sbin/umount /CDROM, /sbin/mount -o nosuid\,nodev\
+ /dev/cd0a /CDROM
diff --git a/plugins/sudoers/regress/cvtsudoers/test1.sh b/plugins/sudoers/regress/cvtsudoers/test1.sh
new file mode 100755
index 0000000..e2ff3cf
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test1.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test user and host filters
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -m user=millert,host=hercules $TESTDIR/sudoers
+
+exit 0
diff --git a/plugins/sudoers/regress/cvtsudoers/test10.out.ok b/plugins/sudoers/regress/cvtsudoers/test10.out.ok
new file mode 100644
index 0000000..26a05d2
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test10.out.ok
@@ -0,0 +1 @@
+Defaults!PAGERS noexec
diff --git a/plugins/sudoers/regress/cvtsudoers/test10.sh b/plugins/sudoers/regress/cvtsudoers/test10.sh
new file mode 100755
index 0000000..25df83c
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test10.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test command defaults filtering
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -s aliases,privileges -d command $TESTDIR/sudoers
+
+exit 0
diff --git a/plugins/sudoers/regress/cvtsudoers/test11.out.ok b/plugins/sudoers/regress/cvtsudoers/test11.out.ok
new file mode 100644
index 0000000..5c4c4e8
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test11.out.ok
@@ -0,0 +1,7 @@
+Defaults!PAGERS noexec
+
+Host_Alias CDROM = orion, perseus, hercules
+Runas_Alias OPERATOR = operator, backup
+Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+User_Alias PARTTIMERS = bostley, jwfox, crawl
+Cmnd_Alias VIPW = /usr/sbin/vipw, /usr/bin/passwd, /usr/bin/chsh, /usr/bin/chfn
diff --git a/plugins/sudoers/regress/cvtsudoers/test11.sh b/plugins/sudoers/regress/cvtsudoers/test11.sh
new file mode 100755
index 0000000..1466689
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test11.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+#
+# Test that Aliases are removed when filtering by defaults type
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -d command $TESTDIR/sudoers.defs
diff --git a/plugins/sudoers/regress/cvtsudoers/test12.out.ok b/plugins/sudoers/regress/cvtsudoers/test12.out.ok
new file mode 100644
index 0000000..7f2b15e
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test12.out.ok
@@ -0,0 +1,8 @@
+Defaults:FULLTIMERS !lecture
+Defaults:millert !authenticate
+
+Host_Alias CDROM = orion, perseus, hercules
+User_Alias FULLTIMERS = millert, mikef, dowdy
+Runas_Alias OPERATOR = operator, backup
+User_Alias PARTTIMERS = bostley, jwfox, crawl
+Cmnd_Alias VIPW = /usr/sbin/vipw, /usr/bin/passwd, /usr/bin/chsh, /usr/bin/chfn
diff --git a/plugins/sudoers/regress/cvtsudoers/test12.sh b/plugins/sudoers/regress/cvtsudoers/test12.sh
new file mode 100755
index 0000000..ea0f6bc
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test12.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+#
+# Test that Aliases are removed when filtering by defaults type
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -d user $TESTDIR/sudoers.defs
diff --git a/plugins/sudoers/regress/cvtsudoers/test13.out.ok b/plugins/sudoers/regress/cvtsudoers/test13.out.ok
new file mode 100644
index 0000000..791dcba
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test13.out.ok
@@ -0,0 +1,7 @@
+Defaults@SERVERS log_year, logfile=/var/log/sudo.log
+
+Host_Alias CDROM = orion, perseus, hercules
+Runas_Alias OPERATOR = operator, backup
+User_Alias PARTTIMERS = bostley, jwfox, crawl
+Host_Alias SERVERS = master, mail, www, ns
+Cmnd_Alias VIPW = /usr/sbin/vipw, /usr/bin/passwd, /usr/bin/chsh, /usr/bin/chfn
diff --git a/plugins/sudoers/regress/cvtsudoers/test13.sh b/plugins/sudoers/regress/cvtsudoers/test13.sh
new file mode 100755
index 0000000..4dd4750
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test13.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+#
+# Test that Aliases are removed when filtering by defaults type
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -d host $TESTDIR/sudoers.defs
diff --git a/plugins/sudoers/regress/cvtsudoers/test14.out.ok b/plugins/sudoers/regress/cvtsudoers/test14.out.ok
new file mode 100644
index 0000000..3f7710a
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test14.out.ok
@@ -0,0 +1,7 @@
+Defaults>ROOT !set_logname
+
+Host_Alias CDROM = orion, perseus, hercules
+Runas_Alias OPERATOR = operator, backup
+User_Alias PARTTIMERS = bostley, jwfox, crawl
+Runas_Alias ROOT = root, toor
+Cmnd_Alias VIPW = /usr/sbin/vipw, /usr/bin/passwd, /usr/bin/chsh, /usr/bin/chfn
diff --git a/plugins/sudoers/regress/cvtsudoers/test14.sh b/plugins/sudoers/regress/cvtsudoers/test14.sh
new file mode 100755
index 0000000..3f31076
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test14.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+#
+# Test that Aliases are removed when filtering by defaults type
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -d runas $TESTDIR/sudoers.defs
diff --git a/plugins/sudoers/regress/cvtsudoers/test15.out.ok b/plugins/sudoers/regress/cvtsudoers/test15.out.ok
new file mode 100644
index 0000000..5177139
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test15.out.ok
@@ -0,0 +1 @@
+user1 host1, host2, host3 = ALL
diff --git a/plugins/sudoers/regress/cvtsudoers/test15.sh b/plugins/sudoers/regress/cvtsudoers/test15.sh
new file mode 100755
index 0000000..04a2788
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test15.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test filters and pruning
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -p -m user=user1 <<EOF
+user1, user2, user3, %group1 host1, host2, host3 = ALL
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test16.out.ok b/plugins/sudoers/regress/cvtsudoers/test16.out.ok
new file mode 100644
index 0000000..38359b1
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test16.out.ok
@@ -0,0 +1 @@
+user2 host2 = ALL
diff --git a/plugins/sudoers/regress/cvtsudoers/test16.sh b/plugins/sudoers/regress/cvtsudoers/test16.sh
new file mode 100755
index 0000000..712cdeb
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test16.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test filters and pruning
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -p -m user=user2,host=host2 <<EOF
+user1, user2, user3, %group1 host1, host2, host3 = ALL
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test17.out.ok b/plugins/sudoers/regress/cvtsudoers/test17.out.ok
new file mode 100644
index 0000000..d35dd06
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test17.out.ok
@@ -0,0 +1 @@
+%group1 host1 = ALL
diff --git a/plugins/sudoers/regress/cvtsudoers/test17.sh b/plugins/sudoers/regress/cvtsudoers/test17.sh
new file mode 100755
index 0000000..9892de4
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test17.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test filters and pruning
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -p -m group=group1,host=host1 <<EOF
+user1, user2, user3, %group1 host1, host2, host3 = ALL
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test18.out.ok b/plugins/sudoers/regress/cvtsudoers/test18.out.ok
new file mode 100644
index 0000000..3055452
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test18.out.ok
@@ -0,0 +1 @@
+%group1 ALL = ALL
diff --git a/plugins/sudoers/regress/cvtsudoers/test18.sh b/plugins/sudoers/regress/cvtsudoers/test18.sh
new file mode 100755
index 0000000..5ce7c88
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test18.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test filters and pruning
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -p -m group=group1,host=somehost <<EOF
+user1, user2, user3, %group1 ALL = ALL
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test19.out.ok b/plugins/sudoers/regress/cvtsudoers/test19.out.ok
new file mode 100644
index 0000000..a36b949
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test19.out.ok
@@ -0,0 +1,11 @@
+Defaults syslog=auth
+Defaults>root !set_logname
+Defaults:FULLTIMERS !lecture
+Defaults@SERVERS log_year, logfile=/var/log/sudo.log
+Defaults!PAGERS noexec
+
+User_Alias FULLTIMERS = millert, mikef, dowdy
+Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+Host_Alias SERVERS = master, mail, www, ns
+
+FULLTIMERS ALL = NOPASSWD: ALL
diff --git a/plugins/sudoers/regress/cvtsudoers/test19.sh b/plugins/sudoers/regress/cvtsudoers/test19.sh
new file mode 100755
index 0000000..f434f2a
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test19.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+#
+# Test filters and pruning; alias contents don't get pruned
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -p -m user=FULLTIMERS,host=SERVERS $TESTDIR/sudoers
diff --git a/plugins/sudoers/regress/cvtsudoers/test2.out.ok b/plugins/sudoers/regress/cvtsudoers/test2.out.ok
new file mode 100644
index 0000000..d99e0e5
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test2.out.ok
@@ -0,0 +1,10 @@
+Defaults syslog=auth
+Defaults>root !set_logname
+Defaults:millert, mikef, dowdy !lecture
+Defaults:millert !authenticate
+Defaults!/usr/bin/more, /usr/bin/pg, /usr/bin/less noexec
+
+millert, mikef, dowdy ALL = NOPASSWD: ALL
+
+ALL orion, perseus, hercules = NOPASSWD: /sbin/umount /CDROM, /sbin/mount -o\
+ nosuid\,nodev /dev/cd0a /CDROM
diff --git a/plugins/sudoers/regress/cvtsudoers/test2.sh b/plugins/sudoers/regress/cvtsudoers/test2.sh
new file mode 100755
index 0000000..e7f19f6
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test2.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test user and host filters, expanding aliases
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -e -m user=millert,host=hercules $TESTDIR/sudoers
+
+exit 0
diff --git a/plugins/sudoers/regress/cvtsudoers/test20.conf b/plugins/sudoers/regress/cvtsudoers/test20.conf
new file mode 100644
index 0000000..b60725c
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test20.conf
@@ -0,0 +1,6 @@
+defaults = global
+expand_aliases = yes
+input_format = sudoers
+match = user=user2
+output_format = sudoers
+prune_matches = yes
diff --git a/plugins/sudoers/regress/cvtsudoers/test20.out.ok b/plugins/sudoers/regress/cvtsudoers/test20.out.ok
new file mode 100644
index 0000000..79b420b
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test20.out.ok
@@ -0,0 +1 @@
+user2 ALL = /usr/bin/id
diff --git a/plugins/sudoers/regress/cvtsudoers/test20.sh b/plugins/sudoers/regress/cvtsudoers/test20.sh
new file mode 100755
index 0000000..e7214e2
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test20.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+#
+# Test cvtsudoers.conf
+#
+
+exec 2>&1
+./cvtsudoers -c $TESTDIR/test20.conf <<EOF
+Defaults:SOMEUSERS authenticate, timestamp_timeout=0
+User_Alias SOMEUSERS = user1, user2, user3
+
+SOMEUSERS ALL = /usr/bin/id
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test21.conf b/plugins/sudoers/regress/cvtsudoers/test21.conf
new file mode 100644
index 0000000..01fd3a3
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test21.conf
@@ -0,0 +1,8 @@
+defaults = all
+expand_aliases = no
+input_format = sudoers
+order_increment = 10
+order_start = 1000
+output_format = ldif
+sudoers_base = ou=SUDOers,dc=my-domain,dc=com
+suppress = defaults
diff --git a/plugins/sudoers/regress/cvtsudoers/test21.out.ok b/plugins/sudoers/regress/cvtsudoers/test21.out.ok
new file mode 100644
index 0000000..78285f1
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test21.out.ok
@@ -0,0 +1,24 @@
+dn: cn=ALL,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: ALL
+sudoUser: ALL
+sudoHost: ALL
+sudoRunAsUser:
+sudoOption: !authenticate
+sudoCommand: /usr/bin/id
+sudoOrder: 1000
+
+dn: cn=FULLTIMERS,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: FULLTIMERS
+sudoUser: user1
+sudoUser: user2
+sudoUser: user3
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOrder: 1010
+
diff --git a/plugins/sudoers/regress/cvtsudoers/test21.sh b/plugins/sudoers/regress/cvtsudoers/test21.sh
new file mode 100755
index 0000000..66c18b6
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test21.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# Test cvtsudoers.conf
+#
+
+exec 2>&1
+./cvtsudoers -c $TESTDIR/test21.conf <<EOF
+Defaults authenticate, timestamp_timeout=0
+User_Alias FULLTIMERS = user1, user2, user3
+
+ALL ALL = (:) NOPASSWD:/usr/bin/id
+FULLTIMERS ALL = (ALL:ALL) ALL
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test22.out.ok b/plugins/sudoers/regress/cvtsudoers/test22.out.ok
new file mode 100644
index 0000000..d404815
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test22.out.ok
@@ -0,0 +1,31 @@
+dn: cn=defaults,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption: log_output
+
+dn: cn=root,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: root
+sudoUser: root
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoOption: !authenticate
+sudoCommand: ALL
+sudoOrder: 10
+
+dn: cn=%wheel,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %wheel
+sudoUser: %wheel
+sudoHost: +sudo-hosts
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoOption: !authenticate
+sudoCommand: ALL
+sudoOrder: 20
+
diff --git a/plugins/sudoers/regress/cvtsudoers/test22.sh b/plugins/sudoers/regress/cvtsudoers/test22.sh
new file mode 100755
index 0000000..7c75716
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test22.sh
@@ -0,0 +1,72 @@
+#!/bin/sh
+#
+# Test LDAP base filtering.
+#
+
+exec 2>&1
+./cvtsudoers -c "" -i ldif -b "ou=SUDOers,dc=sudo,dc=ws" -I 10 -O 10 <<EOF
+dn: dc=sudo,dc=ws
+objectClass: dcObject
+objectClass: organization
+dc: courtesan
+o: Sudo World Headquarters
+description: Sudo World Headquarters
+
+# Organizational Role for Directory Manager
+dn: cn=Manager,dc=sudo,dc=ws
+objectClass: organizationalRole
+cn: Manager
+description: Directory Manager
+
+# SUDOers, sudo.ws
+dn: ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: organizationalUnit
+description: SUDO Configuration Subtree
+ou: SUDOers
+
+# defaults, SUDOers, sudo.ws
+dn: cn=defaults,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption: log_output
+
+# root, SUDOers, sudo.ws
+dn: cn=root,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: root
+sudoUser: root
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: ALL
+sudoCommand: ALL
+sudoOption: !authenticate
+sudoOrder: 10
+
+# %wheel, SUDOers, sudo.ws
+dn: cn=%wheel,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %wheel
+sudoUser: %wheel
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: +sudo-hosts
+sudoCommand: ALL
+sudoOption: !authenticate
+sudoOrder: 10
+
+# millert, SUDOers, other-domain.com
+dn: cn=millert,ou=SUDOers,dc=other-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: millert
+sudoUser: millert
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: ALL
+sudoOrder: 5
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test23.out.ok b/plugins/sudoers/regress/cvtsudoers/test23.out.ok
new file mode 100644
index 0000000..7fc33c2
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test23.out.ok
@@ -0,0 +1,20 @@
+Defaults logfile=/var/log/sudo
+
+root ALL = (ALL) ALL
+
+%wheel ALL = (ALL) ALL
+
++admins ALL = NOPASSWD: ALL
+
+jack 128.138.204.0/24, 128.138.242.0, 128.138.243.0 = ALL
+
+lisa 128.138.0.0/255.255.0.0 = ALL
+
+operator ALL = /usr/sbin/dump, /usr/sbin/rdump, /usr/sbin/restore,\
+ /usr/sbin/rrestore, /usr/bin/mt,\
+ sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ==\
+ /home/operator/bin/start_backups, /usr/bin/kill, /usr/bin/top,\
+ /usr/sbin/shutdown, /usr/sbin/halt, /usr/sbin/reboot, /usr/sbin/lpc,\
+ /usr/bin/lprm, sudoedit /etc/printcap, /usr/oper/bin/
+
+joe ALL = /usr/bin/su operator
diff --git a/plugins/sudoers/regress/cvtsudoers/test23.sh b/plugins/sudoers/regress/cvtsudoers/test23.sh
new file mode 100755
index 0000000..d5f0439
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test23.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# Test round-tripping of sudoers -> LDIF -> sudoers
+#
+
+exec 2>&1
+./cvtsudoers -c "" -b "ou=SUDOers,dc=sudo,dc=ws" $TESTDIR/test23.out.ok | \
+ ./cvtsudoers -c "" -i LDIF -f sudoers | grep -v '^#'
diff --git a/plugins/sudoers/regress/cvtsudoers/test24.out.ok b/plugins/sudoers/regress/cvtsudoers/test24.out.ok
new file mode 100644
index 0000000..0951767
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test24.out.ok
@@ -0,0 +1,89 @@
+dn: cn=defaults,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption: logfile=/var/log/sudo
+
+dn: cn=root,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: root
+sudoUser: root
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoCommand: ALL
+sudoOrder: 1
+
+dn: cn=%wheel,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %wheel
+sudoUser: %wheel
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoCommand: ALL
+sudoOrder: 2
+
+dn: cn=\+admins,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: \+admins
+sudoUser: +admins
+sudoHost: ALL
+sudoOption: !authenticate
+sudoCommand: ALL
+sudoOrder: 3
+
+dn: cn=jack,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: jack
+sudoUser: jack
+sudoHost: 128.138.204.0/24
+sudoHost: 128.138.242.0
+sudoHost: 128.138.243.0
+sudoCommand: ALL
+sudoOrder: 4
+
+dn: cn=lisa,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: lisa
+sudoUser: lisa
+sudoHost: 128.138.0.0/255.255.0.0
+sudoCommand: ALL
+sudoOrder: 5
+
+dn: cn=operator,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: operator
+sudoUser: operator
+sudoHost: ALL
+sudoCommand: /usr/sbin/dump
+sudoCommand: /usr/sbin/rdump
+sudoCommand: /usr/sbin/restore
+sudoCommand: /usr/sbin/rrestore
+sudoCommand: /usr/bin/mt
+sudoCommand: sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== /home/operator/bin/start_backups
+sudoCommand: /usr/bin/kill
+sudoCommand: /usr/bin/top
+sudoCommand: /usr/sbin/shutdown
+sudoCommand: /usr/sbin/halt
+sudoCommand: /usr/sbin/reboot
+sudoCommand: /usr/sbin/lpc
+sudoCommand: /usr/bin/lprm
+sudoCommand: sudoedit /etc/printcap
+sudoCommand: /usr/oper/bin/
+sudoOrder: 6
+
+dn: cn=joe,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: joe
+sudoUser: joe
+sudoHost: ALL
+sudoCommand: /usr/bin/su operator
+sudoOrder: 7
+
diff --git a/plugins/sudoers/regress/cvtsudoers/test24.sh b/plugins/sudoers/regress/cvtsudoers/test24.sh
new file mode 100755
index 0000000..632502e
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test24.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# Test round-tripping of LDIF -> sudoers -> LDIF
+#
+
+exec 2>&1
+./cvtsudoers -c "" -i LDIF -f sudoers $TESTDIR/test24.out.ok | \
+ ./cvtsudoers -c "" -b "ou=SUDOers,dc=sudo,dc=ws"
diff --git a/plugins/sudoers/regress/cvtsudoers/test25.out.ok b/plugins/sudoers/regress/cvtsudoers/test25.out.ok
new file mode 100644
index 0000000..d404815
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test25.out.ok
@@ -0,0 +1,31 @@
+dn: cn=defaults,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption: log_output
+
+dn: cn=root,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: root
+sudoUser: root
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoOption: !authenticate
+sudoCommand: ALL
+sudoOrder: 10
+
+dn: cn=%wheel,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %wheel
+sudoUser: %wheel
+sudoHost: +sudo-hosts
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoOption: !authenticate
+sudoCommand: ALL
+sudoOrder: 20
+
diff --git a/plugins/sudoers/regress/cvtsudoers/test25.sh b/plugins/sudoers/regress/cvtsudoers/test25.sh
new file mode 100755
index 0000000..4cb8b45
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test25.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# Test LDIF base64 attribute parsing
+#
+
+exec 2>&1
+./cvtsudoers -c "" -i ldif -b "ou=SUDOers,dc=sudo,dc=ws" -I 10 -O 10 <<EOF
+# defaults, SUDOers, sudo.ws
+dn:: Y249ZGVmYXVsdHMsb3U9U1VET2VycyxkYz1zdWRvLGRjPXdz
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption:: bG9nX291dHB1dA==
+
+# root, SUDOers, sudo.ws
+dn:: Y249cm9vdCxvdT1TVURPZXJzLGRjPXN1ZG8sZGM9d3M=
+objectClass: top
+objectClass: sudoRole
+cn: root
+sudoUser: root
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: ALL
+sudoCommand: ALL
+sudoOption: !authenticate
+sudoOrder: 10
+
+# %wheel, SUDOers, sudo.ws
+dn:: Y249JXdoZWVsLG91PVNVRE9lcnMsZGM9c3VkbyxkYz13cw==
+objectClass: top
+objectClass: sudoRole
+cn: %wheel
+sudoUser: %wheel
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: +sudo-hosts
+sudoCommand: ALL
+sudoOption: !authenticate
+sudoOrder: 10
+
+# millert, SUDOers, other-domain.com
+dn:: Y249bWlsbGVydCxvdT1TVURPZXJzLGRjPW90aGVyLWRvbWFpbixkYz1jb20=
+objectClass: top
+objectClass: sudoRole
+cn: millert
+sudoUser: millert
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: ALL
+sudoOrder: 5
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test26.out.ok b/plugins/sudoers/regress/cvtsudoers/test26.out.ok
new file mode 100644
index 0000000..769f392
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test26.out.ok
@@ -0,0 +1,3 @@
+cvtsudoers: ignoring invalid attribute value: bG9nX29@1dHB1dA==
+cvtsudoers: ignoring invalid attribute value: Y249cm9vdCxvdT1TVURPZXJzLGRjPXN1ZG8sZGM9_d3M=
+cvtsudoers: ignoring invalid attribute value: Y249JXdoZWVsLG91PVNVRE9lcnMsZGM9c3VkbyxkYz13cw!==
diff --git a/plugins/sudoers/regress/cvtsudoers/test26.sh b/plugins/sudoers/regress/cvtsudoers/test26.sh
new file mode 100755
index 0000000..b9eecaa
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test26.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# Test LDIF invalid base64 attribute parsing
+#
+
+exec 2>&1
+./cvtsudoers -c "" -i ldif -b "ou=SUDOers,dc=sudo,dc=ws" -I 10 -O 10 <<EOF
+# defaults, SUDOers, sudo.ws
+dn:: Y249ZGVmYXVsdHMsb3U9U1VET2VycyxkYz1zdWRvLGRjPXdz
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption:: bG9nX29@1dHB1dA==
+
+# root, SUDOers, sudo.ws
+dn:: Y249cm9vdCxvdT1TVURPZXJzLGRjPXN1ZG8sZGM9_d3M=
+objectClass: top
+objectClass: sudoRole
+cn: root
+sudoUser: root
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: ALL
+sudoCommand: ALL
+sudoOption: !authenticate
+sudoOrder: 10
+
+# %wheel, SUDOers, sudo.ws
+dn:: Y249JXdoZWVsLG91PVNVRE9lcnMsZGM9c3VkbyxkYz13cw!==
+objectClass: top
+objectClass: sudoRole
+cn: %wheel
+sudoUser: %wheel
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: +sudo-hosts
+sudoCommand: ALL
+sudoOption: !authenticate
+sudoOrder: 10
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test27.out.ok b/plugins/sudoers/regress/cvtsudoers/test27.out.ok
new file mode 100644
index 0000000..ab9c948
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test27.out.ok
@@ -0,0 +1,16 @@
+dn:: Y249ZGVmYXVsdHMsb3U9U1VET2Vyc8KpLGRjPXN1ZG8sZGM9d3M=
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption:: YmFkcGFzc19tZXNzYWdlPUJhZCBwYXNzd29yZMKh
+
+dn:: Y249cm9vdCxvdT1TVURPZXJzwqksZGM9c3VkbyxkYz13cw==
+objectClass: top
+objectClass: sudoRole
+cn: root
+sudoUser: root
+sudoHost: ALL
+sudoCommand: ALL
+sudoOrder: 1
+
diff --git a/plugins/sudoers/regress/cvtsudoers/test27.sh b/plugins/sudoers/regress/cvtsudoers/test27.sh
new file mode 100755
index 0000000..afc29a8
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test27.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+#
+# Test base64 encoding of non-safe strings
+#
+
+exec 2>&1
+./cvtsudoers -c "" -b "ou=SUDOers©,dc=sudo,dc=ws" <<EOF
+Defaults badpass_message="Bad password¡"
+
+root ALL = ALL
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test28.out.ok b/plugins/sudoers/regress/cvtsudoers/test28.out.ok
new file mode 100644
index 0000000..ba19cb9
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test28.out.ok
@@ -0,0 +1,10 @@
+Defaults log_output
+
+# sudoRole millert
+millert ALL = (ALL : ALL) ALL
+
+# sudoRole root
+root ALL = (ALL : ALL) NOPASSWD: ALL
+
+# sudoRole %wheel
+%wheel +sudo-hosts = (ALL : ALL) NOPASSWD: ALL
diff --git a/plugins/sudoers/regress/cvtsudoers/test28.sh b/plugins/sudoers/regress/cvtsudoers/test28.sh
new file mode 100755
index 0000000..73c4a50
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test28.sh
@@ -0,0 +1,73 @@
+#!/bin/sh
+#
+# Test LDAP sudoOrder when converting to sudoers.
+#
+
+exec 2>&1
+./cvtsudoers -c "" -i ldif -f sudoers <<EOF
+dn: dc=sudo,dc=ws
+objectClass: dcObject
+objectClass: organization
+dc: courtesan
+o: Sudo World Headquarters
+description: Sudo World Headquarters
+
+# Organizational Role for Directory Manager
+dn: cn=Manager,dc=sudo,dc=ws
+objectClass: organizationalRole
+cn: Manager
+description: Directory Manager
+
+# SUDOers, sudo.ws
+dn: ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: organizationalUnit
+description: SUDO Configuration Subtree
+ou: SUDOers
+
+# defaults, SUDOers, sudo.ws
+dn: cn=defaults,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption: log_output
+
+# root, SUDOers, sudo.ws
+dn: cn=root,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: root
+sudoUser: root
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: ALL
+sudoCommand: ALL
+sudoOption: !authenticate
+sudoOrder: 10
+
+# %wheel, SUDOers, sudo.ws
+dn: cn=%wheel,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %wheel
+sudoUser: %wheel
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: +sudo-hosts
+sudoCommand: ALL
+sudoOption: !authenticate
+sudoOrder: 20
+
+# millert, SUDOers, sudo.ws
+dn: cn=millert,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: millert
+sudoUser: millert
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: ALL
+sudoCommand: ALL
+sudoOrder: 5
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test29.out.ok b/plugins/sudoers/regress/cvtsudoers/test29.out.ok
new file mode 100644
index 0000000..c168898
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test29.out.ok
@@ -0,0 +1,4 @@
+Defaults log_output
+
+# sudoRole millert, millert2
+millert ALL = (ALL : ALL) ALL, NOPASSWD: ALL
diff --git a/plugins/sudoers/regress/cvtsudoers/test29.sh b/plugins/sudoers/regress/cvtsudoers/test29.sh
new file mode 100755
index 0000000..6f0148c
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test29.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+#
+# Test LDAP sudoOrder when converting to sudoers.
+#
+
+exec 2>&1
+./cvtsudoers -c "" -i ldif -f sudoers <<EOF
+dn: dc=sudo,dc=ws
+objectClass: dcObject
+objectClass: organization
+dc: courtesan
+o: Sudo World Headquarters
+description: Sudo World Headquarters
+
+# Organizational Role for Directory Manager
+dn: cn=Manager,dc=sudo,dc=ws
+objectClass: organizationalRole
+cn: Manager
+description: Directory Manager
+
+# SUDOers, sudo.ws
+dn: ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: organizationalUnit
+description: SUDO Configuration Subtree
+ou: SUDOers
+
+# defaults, SUDOers, sudo.ws
+dn: cn=defaults,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption: log_output
+
+# millert, SUDOers, sudo.ws
+dn: cn=millert,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: millert
+sudoUser: millert
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: ALL
+sudoCommand: ALL
+sudoOrder: 5
+
+# millert2, SUDOers, sudo.ws
+dn: cn=millert2,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: millert2
+sudoUser: millert
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: ALL
+sudoCommand: ALL
+sudoOption: !authenticate
+sudoOrder: 10
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test3.out.ok b/plugins/sudoers/regress/cvtsudoers/test3.out.ok
new file mode 100644
index 0000000..8a37975
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test3.out.ok
@@ -0,0 +1,7 @@
+Defaults syslog=auth
+Defaults>root !set_logname
+Defaults!PAGERS noexec
+
+Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+
+%wheel ALL = (ALL) ALL
diff --git a/plugins/sudoers/regress/cvtsudoers/test3.sh b/plugins/sudoers/regress/cvtsudoers/test3.sh
new file mode 100755
index 0000000..472d252
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test3.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test group and host filters
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -m group=wheel,host=blackhole $TESTDIR/sudoers
+
+exit 0
diff --git a/plugins/sudoers/regress/cvtsudoers/test30.out.ok b/plugins/sudoers/regress/cvtsudoers/test30.out.ok
new file mode 100644
index 0000000..009a54e
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test30.out.ok
@@ -0,0 +1,26 @@
+{
+ "User_Specs": [
+ {
+ "User_List": [
+ { "username": "user1" },
+ { "username": "user2" },
+ { "username": "user3" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Commands": [
+ { "command": "/path/to/cmda" },
+ {
+ "command": "/path/to/cmdb",
+ "negated": true
+ },
+ { "command": "/path/to/cmdc" }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/plugins/sudoers/regress/cvtsudoers/test30.sh b/plugins/sudoers/regress/cvtsudoers/test30.sh
new file mode 100755
index 0000000..80b08a5
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test30.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Test alias expasion when converting to JSON.
+# See https://bugzilla.sudo.ws/show_bug.cgi?id=853
+#
+
+exec 2>&1
+./cvtsudoers -c "" -e -f json <<EOF
+Cmnd_Alias CMDA=/path/to/cmda
+Cmnd_Alias CMDB=/path/to/cmdb
+Cmnd_Alias CMDC=/path/to/cmdc
+User_Alias USERS=user1,user2,user3
+USERS ALL=CMDA,!CMDB,CMDC
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test31.conf b/plugins/sudoers/regress/cvtsudoers/test31.conf
new file mode 100644
index 0000000..345dbfc
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test31.conf
@@ -0,0 +1,9 @@
+defaults = all
+expand_aliases = no
+input_format = sudoers
+order_increment = 5
+order_padding = 2
+order_start = 1000
+output_format = ldif
+sudoers_base = ou=SUDOers,dc=my-domain,dc=com
+suppress = defaults
diff --git a/plugins/sudoers/regress/cvtsudoers/test31.out.ok b/plugins/sudoers/regress/cvtsudoers/test31.out.ok
new file mode 100644
index 0000000..41ffd1b
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test31.out.ok
@@ -0,0 +1,24 @@
+dn: cn=ALL,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: ALL
+sudoUser: ALL
+sudoHost: ALL
+sudoRunAsUser:
+sudoOption: !authenticate
+sudoCommand: /usr/bin/id
+sudoOrder: 100000
+
+dn: cn=FULLTIMERS,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: FULLTIMERS
+sudoUser: user1
+sudoUser: user2
+sudoUser: user3
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOrder: 100005
+
diff --git a/plugins/sudoers/regress/cvtsudoers/test31.sh b/plugins/sudoers/regress/cvtsudoers/test31.sh
new file mode 100644
index 0000000..ad6537c
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test31.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# Test cvtsudoers.conf with padding
+#
+
+exec 2>&1
+./cvtsudoers -c $TESTDIR/test31.conf <<EOF
+Defaults authenticate, timestamp_timeout=0
+User_Alias FULLTIMERS = user1, user2, user3
+
+ALL ALL = (:) NOPASSWD:/usr/bin/id
+FULLTIMERS ALL = (ALL:ALL) ALL
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test32.out.ok b/plugins/sudoers/regress/cvtsudoers/test32.out.ok
new file mode 100644
index 0000000..436b877
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test32.out.ok
@@ -0,0 +1,120 @@
+cvtsudoers: too many sudoers entries, maximum 10
+dn: cn=user0,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: user0
+sudoUser: user0
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOrder: 10000
+
+dn: cn=user1,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: user1
+sudoUser: user1
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOrder: 10001
+
+dn: cn=user2,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: user2
+sudoUser: user2
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOrder: 10002
+
+dn: cn=user3,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: user3
+sudoUser: user3
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOrder: 10003
+
+dn: cn=user4,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: user4
+sudoUser: user4
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOrder: 10004
+
+dn: cn=user5,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: user5
+sudoUser: user5
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOrder: 10005
+
+dn: cn=user6,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: user6
+sudoUser: user6
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOrder: 10006
+
+dn: cn=user7,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: user7
+sudoUser: user7
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOrder: 10007
+
+dn: cn=user8,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: user8
+sudoUser: user8
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOrder: 10008
+
+dn: cn=user9,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: user9
+sudoUser: user9
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
+sudoOrder: 10009
+
+dn: cn=user10,ou=SUDOers,dc=my-domain,dc=com
+objectClass: top
+objectClass: sudoRole
+cn: user10
+sudoUser: user10
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoCommand: ALL
diff --git a/plugins/sudoers/regress/cvtsudoers/test32.sh b/plugins/sudoers/regress/cvtsudoers/test32.sh
new file mode 100644
index 0000000..fe9c065
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test32.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# Test cvtsudoers.conf with invalid padding
+#
+
+exec 2>&1
+./cvtsudoers -c "" -b "ou=SUDOers,dc=my-domain,dc=com" -O 1000 -P 1 <<EOF
+user0 ALL = (ALL:ALL) ALL
+user1 ALL = (ALL:ALL) ALL
+user2 ALL = (ALL:ALL) ALL
+user3 ALL = (ALL:ALL) ALL
+user4 ALL = (ALL:ALL) ALL
+user5 ALL = (ALL:ALL) ALL
+user6 ALL = (ALL:ALL) ALL
+user7 ALL = (ALL:ALL) ALL
+user8 ALL = (ALL:ALL) ALL
+user9 ALL = (ALL:ALL) ALL
+user10 ALL = (ALL:ALL) ALL
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/cvtsudoers/test33.out.ok b/plugins/sudoers/regress/cvtsudoers/test33.out.ok
new file mode 100644
index 0000000..6584701
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test33.out.ok
@@ -0,0 +1,7 @@
+Defaults log_output
+
+# sudoRole root
+root ALL = (ALL : ALL) NOPASSWD: ALL
+
+# sudoRole millert
+millert ALL = (ALL, !bin, !root : ALL, !wheel) ALL
diff --git a/plugins/sudoers/regress/cvtsudoers/test33.sh b/plugins/sudoers/regress/cvtsudoers/test33.sh
new file mode 100755
index 0000000..db8d8d1
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test33.sh
@@ -0,0 +1,61 @@
+#!/bin/sh
+#
+# Test LDAP negated sudoRunAsUser and sudoRunAsGroup converted to sudoers.
+#
+
+exec 2>&1
+./cvtsudoers -c "" -i ldif -f sudoers <<EOF
+dn: dc=sudo,dc=ws
+objectClass: dcObject
+objectClass: organization
+dc: courtesan
+o: Sudo World Headquarters
+description: Sudo World Headquarters
+
+# Organizational Role for Directory Manager
+dn: cn=Manager,dc=sudo,dc=ws
+objectClass: organizationalRole
+cn: Manager
+description: Directory Manager
+
+# SUDOers, sudo.ws
+dn: ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: organizationalUnit
+description: SUDO Configuration Subtree
+ou: SUDOers
+
+# defaults, SUDOers, sudo.ws
+dn: cn=defaults,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption: log_output
+
+# root, SUDOers, sudo.ws
+dn: cn=root,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: root
+sudoUser: root
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: ALL
+sudoCommand: ALL
+sudoOption: !authenticate
+
+# millert, SUDOers, sudo.ws
+dn: cn=millert,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: millert
+sudoUser: millert
+sudoRunAsUser: !bin
+sudoRunAsUser: !root
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoRunAsGroup: !wheel
+sudoHost: ALL
+sudoCommand: ALL
+EOF
diff --git a/plugins/sudoers/regress/cvtsudoers/test4.out.ok b/plugins/sudoers/regress/cvtsudoers/test4.out.ok
new file mode 100644
index 0000000..f8e7d2e
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test4.out.ok
@@ -0,0 +1,5 @@
+Defaults syslog=auth
+Defaults>root !set_logname
+Defaults!/usr/bin/more, /usr/bin/pg, /usr/bin/less noexec
+
+%wheel ALL = (ALL) ALL
diff --git a/plugins/sudoers/regress/cvtsudoers/test4.sh b/plugins/sudoers/regress/cvtsudoers/test4.sh
new file mode 100755
index 0000000..17c2a25
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test4.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test group and host filters, expanding aliases
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -e -m group=wheel,host=blackhole $TESTDIR/sudoers
+
+exit 0
diff --git a/plugins/sudoers/regress/cvtsudoers/test5.out.ok b/plugins/sudoers/regress/cvtsudoers/test5.out.ok
new file mode 100644
index 0000000..d209fdf
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test5.out.ok
@@ -0,0 +1,6 @@
+Defaults syslog=auth
+Defaults>root !set_logname
+Defaults:FULLTIMERS !lecture
+Defaults:millert !authenticate
+Defaults@SERVERS log_year, logfile=/var/log/sudo.log
+Defaults!PAGERS noexec
diff --git a/plugins/sudoers/regress/cvtsudoers/test5.sh b/plugins/sudoers/regress/cvtsudoers/test5.sh
new file mode 100755
index 0000000..1c41772
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test5.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test defaults type filtering
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -s aliases,privileges -d all $TESTDIR/sudoers
+
+exit 0
diff --git a/plugins/sudoers/regress/cvtsudoers/test6.out.ok b/plugins/sudoers/regress/cvtsudoers/test6.out.ok
new file mode 100644
index 0000000..5e65e61
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test6.out.ok
@@ -0,0 +1 @@
+Defaults syslog=auth
diff --git a/plugins/sudoers/regress/cvtsudoers/test6.sh b/plugins/sudoers/regress/cvtsudoers/test6.sh
new file mode 100755
index 0000000..289fad9
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test6.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test global defaults filtering
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -s aliases,privileges -d global $TESTDIR/sudoers
+
+exit 0
diff --git a/plugins/sudoers/regress/cvtsudoers/test7.out.ok b/plugins/sudoers/regress/cvtsudoers/test7.out.ok
new file mode 100644
index 0000000..381de43
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test7.out.ok
@@ -0,0 +1,2 @@
+Defaults:FULLTIMERS !lecture
+Defaults:millert !authenticate
diff --git a/plugins/sudoers/regress/cvtsudoers/test7.sh b/plugins/sudoers/regress/cvtsudoers/test7.sh
new file mode 100755
index 0000000..63af529
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test7.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test user defaults filtering
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -s aliases,privileges -d user $TESTDIR/sudoers
+
+exit 0
diff --git a/plugins/sudoers/regress/cvtsudoers/test8.out.ok b/plugins/sudoers/regress/cvtsudoers/test8.out.ok
new file mode 100644
index 0000000..7079ee0
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test8.out.ok
@@ -0,0 +1 @@
+Defaults>root !set_logname
diff --git a/plugins/sudoers/regress/cvtsudoers/test8.sh b/plugins/sudoers/regress/cvtsudoers/test8.sh
new file mode 100755
index 0000000..785e0b5
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test8.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test runas defaults filtering
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -s aliases,privileges -d runas $TESTDIR/sudoers
+
+exit 0
diff --git a/plugins/sudoers/regress/cvtsudoers/test9.out.ok b/plugins/sudoers/regress/cvtsudoers/test9.out.ok
new file mode 100644
index 0000000..d2a39c4
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test9.out.ok
@@ -0,0 +1 @@
+Defaults@SERVERS log_year, logfile=/var/log/sudo.log
diff --git a/plugins/sudoers/regress/cvtsudoers/test9.sh b/plugins/sudoers/regress/cvtsudoers/test9.sh
new file mode 100755
index 0000000..de64a48
--- /dev/null
+++ b/plugins/sudoers/regress/cvtsudoers/test9.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Test host defaults filtering
+#
+
+exec 2>&1
+./cvtsudoers -c "" -f sudoers -s aliases,privileges -d host $TESTDIR/sudoers
+
+exit 0
diff --git a/plugins/sudoers/regress/env_match/check_env_pattern.c b/plugins/sudoers/regress/env_match/check_env_pattern.c
new file mode 100644
index 0000000..96dc8c5
--- /dev/null
+++ b/plugins/sudoers/regress/env_match/check_env_pattern.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <time.h> /* for sudo_compat.h */
+#include <grp.h> /* for sudo_compat.h */
+
+#include "sudoers.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+int
+main(int argc, char *argv[])
+{
+ FILE *fp = stdin;
+ char pattern[1024], string[1024];
+ int errors = 0, tests = 0, got, want;
+
+ initprogname(argc > 0 ? argv[0] : "check_env_pattern");
+
+ if (argc > 1) {
+ if ((fp = fopen(argv[1], "r")) == NULL) {
+ perror(argv[1]);
+ exit(1);
+ }
+ }
+
+ /*
+ * Read in test file, which is formatted thusly:
+ *
+ * pattern string 1/0
+ *
+ */
+ for (;;) {
+ bool full_match = false;
+
+ got = fscanf(fp, "%s %s %d\n", pattern, string, &want);
+ if (got == EOF)
+ break;
+ if (got == 3) {
+ got = matches_env_pattern(pattern, string, &full_match);
+ if (full_match)
+ got++;
+ if (got != want) {
+ fprintf(stderr,
+ "%s: %s %s: want %d, got %d\n",
+ getprogname(), pattern, string, want, got);
+ errors++;
+ }
+ tests++;
+ }
+ }
+ if (tests != 0) {
+ printf("%s: %d test%s run, %d errors, %d%% success rate\n",
+ getprogname(), tests, tests == 1 ? "" : "s", errors,
+ (tests - errors) * 100 / tests);
+ }
+ exit(errors);
+}
diff --git a/plugins/sudoers/regress/env_match/data b/plugins/sudoers/regress/env_match/data
new file mode 100644
index 0000000..ea28b1b
--- /dev/null
+++ b/plugins/sudoers/regress/env_match/data
@@ -0,0 +1,22 @@
+foo=(){false;} foo=(){false;} 2
+foo foo=(){false;} 1
+foo= foo=(){false;} 0
+foo=* foo=(){false;} 1
+foo=(* foo=(){false;} 2
+foo=()* foo=(){false;} 2
+foo=*()* foo=(){false;} 2
+foo() foo()=a 1
+foo*() foo()=b 1
+foo*()* foo()= 1
+foo()* foo()= 1
+foo* foo()= 1
+fo*o*() foo()= 1
+fo*o*() fooo()== 1
+fo*o*() foooo()= 1
+fo*o*() foooo 0
+MYPATH=*:/mydir:* MYPATH=/dir1/subdir1:/mydir:/dir2:/dir3/subdir2 2
+MYPATH=*:/mydir:** MYPATH=/dir1/subdir1:/mydir:/dir2:/dir3/subdir2 2
+MYPATH=*:/mdir:* MYPATH=/dir1/subdir1:/mydir:/dir2:/dir3/subdir2 0
+a*a*a*a*a*a* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=b 1
+a*a*a*a*a*a*=b* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=b 2
+a*a*a*a*a*a*=* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=c 1
diff --git a/plugins/sudoers/regress/iolog_path/check_iolog_path.c b/plugins/sudoers/regress/iolog_path/check_iolog_path.c
new file mode 100644
index 0000000..69ea767
--- /dev/null
+++ b/plugins/sudoers/regress/iolog_path/check_iolog_path.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2011-2013 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <pwd.h>
+#include <grp.h>
+#include <time.h>
+
+#define SUDO_ERROR_WRAP 0
+
+#include "sudoers.h"
+#include "def_data.c"
+
+struct sudo_user sudo_user;
+struct passwd *list_pw;
+
+static char sessid[7];
+
+__dso_public int main(int argc, char *argv[]);
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s datafile\n", getprogname());
+ exit(1);
+}
+
+static int
+do_check(char *dir_in, char *file_in, char *tdir_out, char *tfile_out)
+{
+ char *path, *slash;
+ char dir_out[4096], file_out[4096];
+ struct tm *timeptr;
+ time_t now;
+ int error = 0;
+
+ /*
+ * Expand any strftime(3) escapes
+ * XXX - want to pass timeptr to expand_iolog_path
+ */
+ time(&now);
+ timeptr = localtime(&now);
+ if (timeptr == NULL)
+ sudo_fatalx("localtime returned NULL");
+ strftime(dir_out, sizeof(dir_out), tdir_out, timeptr);
+ strftime(file_out, sizeof(file_out), tfile_out, timeptr);
+
+ path = expand_iolog_path(NULL, dir_in, file_in, &slash);
+ if (path == NULL)
+ sudo_fatalx("unable to expand I/O log path");
+ *slash = '\0';
+ if (strcmp(path, dir_out) != 0) {
+ sudo_warnx("%s: expected %s, got %s", dir_in, dir_out, path);
+ error = 1;
+ }
+ if (strcmp(slash + 1, file_out) != 0) {
+ sudo_warnx("%s: expected %s, got %s", file_in, file_out, slash + 1);
+ error = 1;
+ }
+ free(path);
+
+ return error;
+}
+
+#define MAX_STATE 12
+
+int
+main(int argc, char *argv[])
+{
+ struct passwd pw, rpw;
+ size_t len;
+ FILE *fp;
+ char line[2048];
+ char *file_in = NULL, *file_out = NULL;
+ char *dir_in = NULL, *dir_out = NULL;
+ const char *errstr;
+ int state = 0;
+ int errors = 0;
+ int tests = 0;
+
+ initprogname(argc > 0 ? argv[0] : "check_iolog_path");
+
+ if (argc != 2)
+ usage();
+
+ fp = fopen(argv[1], "r");
+ if (fp == NULL)
+ sudo_fatalx("unable to open %s", argv[1]);
+
+ memset(&pw, 0, sizeof(pw));
+ memset(&rpw, 0, sizeof(rpw));
+ sudo_user.pw = &pw;
+ sudo_user._runas_pw = &rpw;
+
+ /*
+ * Input consists of 12 lines:
+ * sequence number
+ * user name
+ * user gid
+ * runas user name
+ * runas gid
+ * hostname [short form]
+ * command
+ * dir [with escapes]
+ * file [with escapes]
+ * expanded dir
+ * expanded file
+ * empty line
+ */
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ len = strcspn(line, "\n");
+ line[len] = '\0';
+
+ switch (state) {
+ case 0:
+ strlcpy(sessid, line, sizeof(sessid));
+ break;
+ case 1:
+ if (user_name != NULL)
+ free(user_name);
+ user_name = strdup(line);
+ break;
+ case 2:
+ user_gid = (gid_t)sudo_strtoid(line, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx("group ID %s: %s", line, errstr);
+ break;
+ case 3:
+ if (runas_pw->pw_name != NULL)
+ free(runas_pw->pw_name);
+ runas_pw->pw_name = strdup(line);
+ break;
+ case 4:
+ runas_pw->pw_gid = (gid_t)sudo_strtoid(line, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx("group ID %s: %s", line, errstr);
+ break;
+ case 5:
+ if (user_shost != NULL)
+ free(user_shost);
+ user_shost = strdup(line);
+ break;
+ case 6:
+ if (user_base != NULL)
+ free(user_base);
+ user_base = strdup(line);
+ break;
+ case 7:
+ if (dir_in != NULL)
+ free(dir_in);
+ dir_in = strdup(line);
+ break;
+ case 8:
+ if (file_in != NULL)
+ free(file_in);
+ file_in = strdup(line);
+ break;
+ case 9:
+ if (dir_out != NULL)
+ free(dir_out);
+ dir_out = strdup(line);
+ break;
+ case 10:
+ if (file_out != NULL)
+ free(file_out);
+ file_out = strdup(line);
+ break;
+ case 11:
+ errors += do_check(dir_in, file_in, dir_out, file_out);
+ tests++;
+ break;
+ default:
+ sudo_fatalx("internal error, invalid state %d", state);
+ }
+ state = (state + 1) % MAX_STATE;
+ }
+
+ if (tests != 0) {
+ printf("iolog_path: %d test%s run, %d errors, %d%% success rate\n",
+ tests, tests == 1 ? "" : "s", errors,
+ (tests - errors) * 100 / tests);
+ }
+
+ exit(errors);
+}
+
+bool
+io_nextid(char *iolog_dir, char *fallback, char id[7])
+{
+ memcpy(id, sessid, sizeof(sessid));
+ return true;
+}
diff --git a/plugins/sudoers/regress/iolog_path/data b/plugins/sudoers/regress/iolog_path/data
new file mode 100644
index 0000000..dcc3942
--- /dev/null
+++ b/plugins/sudoers/regress/iolog_path/data
@@ -0,0 +1,96 @@
+000001
+nobody
+1
+root
+0
+somehost
+id
+/var/log/sudo-io
+%%{bogus}
+/var/log/sudo-io
+%%{bogus}
+
+000001
+nobody
+1
+root
+0
+somehost
+id
+/var/log/sudo-io
+%%{seq}
+/var/log/sudo-io
+%%{seq}
+
+000001
+nobody
+1
+root
+0
+somehost
+id
+/var/log/sudo-io
+%{seq}
+/var/log/sudo-io
+00/00/01
+
+000001
+nobody
+1
+root
+0
+somehost
+id
+/var/log/sudo-io/%{user}
+%{seq}
+/var/log/sudo-io/nobody
+00/00/01
+
+000001
+nobody
+1
+root
+0
+somehost
+su
+/var/log/sudo-io/%{user}/%{runas_user}
+%{command}_%Y%m%s_%H%M
+/var/log/sudo-io/nobody/root
+su_%Y%m%s_%H%M
+
+000001
+nobody
+1
+root
+0
+somehost
+su
+/var/log/sudo-io/
+/%{user}/%{runas_user}/%{command}_%Y%m%s_%H%M
+/var/log/sudo-io
+nobody/root/su_%Y%m%s_%H%M
+
+000001
+nobody
+1
+root
+0
+somehost
+su
+/var/log/sudo-io/%d%m%Y
+%{user}/%{runas_user}/%{command}
+/var/log/sudo-io/%d%m%Y
+nobody/root/su
+
+000001
+nobody
+1
+root
+0
+somehost
+su
+////////
+%{user}/%{runas_user}/%{command}
+/
+nobody/root/su
+
diff --git a/plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c b/plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c
new file mode 100644
index 0000000..456ed3c
--- /dev/null
+++ b/plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <errno.h>
+#include <pwd.h>
+#include <time.h>
+#include <unistd.h>
+
+#define SUDO_ERROR_WRAP 0
+
+#include "sudoers.h"
+#include "def_data.c" /* for iolog_path.c */
+#include "sudo_plugin.h"
+#include "iolog.h"
+
+extern struct io_plugin sudoers_io;
+
+struct sudo_user sudo_user;
+struct passwd *list_pw;
+sudo_printf_t sudo_printf;
+sudo_conv_t sudo_conv;
+
+__dso_public int main(int argc, char *argv[], char *envp[]);
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s pathname\n", getprogname());
+ exit(1);
+}
+
+static int
+sudo_printf_int(int msg_type, const char *fmt, ...)
+{
+ va_list ap;
+ int len;
+
+ switch (msg_type) {
+ case SUDO_CONV_INFO_MSG:
+ va_start(ap, fmt);
+ len = vfprintf(stdout, fmt, ap);
+ va_end(ap);
+ break;
+ case SUDO_CONV_ERROR_MSG:
+ va_start(ap, fmt);
+ len = vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ break;
+ default:
+ len = -1;
+ errno = EINVAL;
+ break;
+ }
+
+ return len;
+}
+
+bool
+validate_iolog_info(const char *logfile)
+{
+ time_t now;
+ struct log_info *info;
+
+ time(&now);
+
+ /* Parse log file. */
+ if ((info = parse_logfile(logfile)) == NULL)
+ return false;
+
+ if (strcmp(info->cwd, "/") != 0) {
+ sudo_warnx("bad cwd: want \"/\", got \"%s\"", info->cwd);
+ return false;
+ }
+
+ if (strcmp(info->user, "nobody") != 0) {
+ sudo_warnx("bad user: want \"nobody\" got \"%s\"", info->user);
+ return false;
+ }
+
+ if (strcmp(info->runas_user, "root") != 0) {
+ sudo_warnx("bad runas_user: want \"root\" got \"%s\"", info->runas_user);
+ return false;
+ }
+
+ if (info->runas_group != NULL) {
+ sudo_warnx("bad runas_group: want \"\" got \"%s\"", info->runas_user);
+ return false;
+ }
+
+ if (strcmp(info->tty, "/dev/console") != 0) {
+ sudo_warnx("bad tty: want \"/dev/console\" got \"%s\"", info->tty);
+ return false;
+ }
+
+ if (strcmp(info->cmd, "/usr/bin/id") != 0) {
+ sudo_warnx("bad command: want \"/usr/bin/id\" got \"%s\"", info->cmd);
+ return false;
+ }
+
+ if (info->rows != 24) {
+ sudo_warnx("bad rows: want 24 got %d", info->rows);
+ return false;
+ }
+
+ if (info->cols != 80) {
+ sudo_warnx("bad cols: want 80 got %d", info->cols);
+ return false;
+ }
+
+ if (info->tstamp < now - 10 || info->tstamp > now + 10) {
+ sudo_warnx("bad tstamp: want %lld got %lld", (long long)now,
+ (long long)info->tstamp);
+ return false;
+ }
+
+ free_log_info(info);
+
+ return true;
+}
+
+bool
+validate_timing(FILE *fp, int recno, int type, unsigned int p1, unsigned int p2)
+{
+ struct timing_closure timing;
+ char buf[LINE_MAX];
+ struct timespec delay;
+
+ if (!fgets(buf, sizeof(buf), fp)) {
+ sudo_warn("unable to read timing file");
+ return false;
+ }
+ buf[strcspn(buf, "\n")] = '\0';
+ if (!parse_timing(buf, &delay, &timing)) {
+ sudo_warnx("invalid timing file line: %s", buf);
+ return false;
+ }
+ if (timing.event != type) {
+ sudo_warnx("record %d: want type %d, got type %d", recno, type,
+ timing.event);
+ return false;
+ }
+ if (type == IO_EVENT_WINSIZE) {
+ if (timing.u.winsize.rows != (int)p1) {
+ sudo_warnx("record %d: want %u rows, got %u", recno, p1,
+ timing.u.winsize.rows);
+ return false;
+ }
+ if (timing.u.winsize.cols != (int)p2) {
+ sudo_warnx("record %d: want %u cols, got %u", recno, p2,
+ timing.u.winsize.cols);
+ return false;
+ }
+ } else {
+ if (timing.u.nbytes != p1) {
+ sudo_warnx("record %d: want len %u, got type %zu", recno, p1,
+ timing.u.nbytes);
+ return false;
+ }
+ }
+ if (delay.tv_sec != 0 || delay.tv_nsec > 10000000) {
+ sudo_warnx("record %d: got excessive delay %lld.%09ld", recno,
+ (long long)delay.tv_sec, delay.tv_nsec);
+ return false;
+ }
+
+ return true;
+}
+
+
+/*
+ * Test sudoers I/O log plugin endpoints.
+ */
+void
+test_endpoints(int *ntests, int *nerrors, const char *iolog_dir, char *envp[])
+{
+ int rc, cmnd_argc = 1;
+ char buf[1024], iolog_path[PATH_MAX];
+ char runas_gid[64], runas_uid[64];
+ FILE *fp;
+ char *cmnd_argv[] = {
+ "/usr/bin/id",
+ NULL
+ };
+ char *user_info[] = {
+ "cols=80",
+ "lines=24",
+ "cwd=/",
+ "tty=/dev/console",
+ "user=nobody",
+ NULL
+ };
+ char *command_info[] = {
+ "command=/usr/bin/id",
+ iolog_path,
+ "iolog_stdin=true",
+ "iolog_stdout=true",
+ "iolog_stderr=true",
+ "iolog_ttyin=true",
+ "iolog_ttyout=true",
+ "iolog_compress=false",
+ "iolog_mode=0644",
+ runas_gid,
+ runas_uid,
+ NULL
+ };
+ char *settings[] = {
+ NULL
+ };
+ const char output[] = "uid=0(root) gid=0(wheel)\r\n";
+
+ /* Set runas uid/gid to root. */
+ snprintf(runas_uid, sizeof(runas_uid), "runas_uid=%u",
+ (unsigned int)runas_pw->pw_uid);
+ snprintf(runas_gid, sizeof(runas_gid), "runas_gid=%u",
+ (unsigned int)runas_pw->pw_gid);
+
+ /* Set path to the iolog directory the user passed in. */
+ snprintf(iolog_path, sizeof(iolog_path), "iolog_path=%s", iolog_dir);
+
+ /* Test open endpoint. */
+ rc = sudoers_io.open(SUDO_API_VERSION, NULL, sudo_printf_int, settings,
+ user_info, command_info, cmnd_argc, cmnd_argv, envp, NULL);
+ (*ntests)++;
+ if (rc != 1) {
+ sudo_warnx("I/O log open endpoint failed");
+ (*nerrors)++;
+ return;
+ }
+
+ /* Validate I/O log info file. */
+ (*ntests)++;
+ snprintf(iolog_path, sizeof(iolog_path), "%s/log", iolog_dir);
+ if (!validate_iolog_info(iolog_path))
+ (*nerrors)++;
+
+ /* Test log_ttyout endpoint. */
+ rc = sudoers_io.log_ttyout(output, strlen(output));
+ (*ntests)++;
+ if (rc != 1) {
+ sudo_warnx("I/O log_ttyout endpoint failed");
+ (*nerrors)++;
+ return;
+ }
+
+ /* Test change_winsize endpoint (twice). */
+ rc = sudoers_io.change_winsize(32, 128);
+ (*ntests)++;
+ if (rc != 1) {
+ sudo_warnx("I/O change_winsize endpoint failed");
+ (*nerrors)++;
+ return;
+ }
+ rc = sudoers_io.change_winsize(24, 80);
+ (*ntests)++;
+ if (rc != 1) {
+ sudo_warnx("I/O change_winsize endpoint failed");
+ (*nerrors)++;
+ return;
+ }
+
+ /* Close the plugin. */
+ sudoers_io.close(0, 0);
+
+ /* Validate the timing file. */
+ snprintf(iolog_path, sizeof(iolog_path), "%s/timing", iolog_dir);
+ (*ntests)++;
+ if ((fp = fopen(iolog_path, "r")) == NULL) {
+ sudo_warn("unable to open %s", iolog_path);
+ (*nerrors)++;
+ return;
+ }
+
+ /* Line 1: output of id command. */
+ if (!validate_timing(fp, 1, IO_EVENT_TTYOUT, strlen(output), 0)) {
+ (*nerrors)++;
+ return;
+ }
+
+ /* Line 2: window size change. */
+ if (!validate_timing(fp, 2, IO_EVENT_WINSIZE, 32, 128)) {
+ (*nerrors)++;
+ return;
+ }
+
+ /* Line 3: window size change. */
+ if (!validate_timing(fp, 3, IO_EVENT_WINSIZE, 24, 80)) {
+ (*nerrors)++;
+ return;
+ }
+
+ /* Validate ttyout log file. */
+ snprintf(iolog_path, sizeof(iolog_path), "%s/ttyout", iolog_dir);
+ (*ntests)++;
+ fclose(fp);
+ if ((fp = fopen(iolog_path, "r")) == NULL) {
+ sudo_warn("unable to open %s", iolog_path);
+ (*nerrors)++;
+ return;
+ }
+ if (!fgets(buf, sizeof(buf), fp)) {
+ sudo_warn("unable to read %s", iolog_path);
+ (*nerrors)++;
+ return;
+ }
+ if (strcmp(buf, output) != 0) {
+ sudo_warnx("ttylog mismatch: want \"%s\", got \"%s\"", output, buf);
+ (*nerrors)++;
+ return;
+ }
+}
+
+int
+main(int argc, char *argv[], char *envp[])
+{
+ struct passwd pw, rpw, *tpw;
+ int tests = 0, errors = 0;
+ const char *iolog_dir;
+
+ initprogname(argc > 0 ? argv[0] : "check_iolog_plugin");
+
+ if (argc != 2)
+ usage();
+ iolog_dir = argv[1];
+
+ /* Bare minimum to link. */
+ memset(&pw, 0, sizeof(pw));
+ memset(&rpw, 0, sizeof(rpw));
+ if ((tpw = getpwuid(0)) == NULL) {
+ if ((tpw = getpwnam("root")) == NULL)
+ sudo_fatalx("unable to look up uid 0 or root");
+ }
+ rpw.pw_uid = tpw->pw_uid;
+ rpw.pw_gid = tpw->pw_gid;
+ sudo_user.pw = &pw;
+ sudo_user._runas_pw = &rpw;
+
+ /* Set iolog uid/gid to invoking user. */
+ iolog_uid = geteuid();
+ iolog_gid = getegid();
+
+ test_endpoints(&tests, &errors, iolog_dir, envp);
+
+ if (tests != 0) {
+ printf("check_iolog_plugin: %d test%s run, %d errors, %d%% success rate\n",
+ tests, tests == 1 ? "" : "s", errors,
+ (tests - errors) * 100 / tests);
+ }
+
+ exit(errors);
+}
+
+/* Stub functions */
+
+bool
+set_perms(int perm)
+{
+ return true;
+}
+
+bool
+restore_perms(void)
+{
+ return true;
+}
+
+bool
+log_warning(int flags, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ sudo_vwarn_nodebug(fmt, ap);
+ va_end(ap);
+
+ return true;
+}
+
+bool
+log_warningx(int flags, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ sudo_vwarnx_nodebug(fmt, ap);
+ va_end(ap);
+
+ return true;
+}
diff --git a/plugins/sudoers/regress/iolog_util/check_iolog_util.c b/plugins/sudoers/regress/iolog_util/check_iolog_util.c
new file mode 100644
index 0000000..d9c932d
--- /dev/null
+++ b/plugins/sudoers/regress/iolog_util/check_iolog_util.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <time.h>
+#include <unistd.h>
+
+#define SUDO_ERROR_WRAP 0
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+#include "sudo_fatal.h"
+#include "iolog.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+static struct parse_delay_test {
+ const char *input;
+ const char *next_field;
+ struct timespec expected_delay;
+} parse_delay_tests[] = {
+ { "10.99999999999 X", "X", { 10, 999999999 } }, /* clamp to nsec */
+ { "10.999999999 X", "X", { 10, 999999999 } }, /* nsec */
+ { "10.999999 X", "X", { 10, 999999000 } }, /* usec -> nsec */
+ { "10.000999999 X", "X", { 10, 999999 } },
+ { "10.9 X", "X", { 10, 900000000 } },
+ { "10.0 X", "X", { 10, 0 } }
+};
+
+/*
+ * Test parse_delay()
+ */
+void
+test_parse_delay(int *ntests, int *nerrors)
+{
+ unsigned int i;
+
+ for (i = 0; i < nitems(parse_delay_tests); i++) {
+ struct timespec delay;
+ struct parse_delay_test *test = &parse_delay_tests[i];
+ char *cp = parse_delay(test->input, &delay, ".");
+ if (cp == NULL) {
+ sudo_warnx("%s:%u failed to parse delay: %s", __func__,
+ i, test->input);
+ (*nerrors)++;
+ continue;
+ }
+ if (strcmp(cp, test->next_field) != 0) {
+ sudo_warnx("%s:%u next field (want \"%s\", got \"%s\"", __func__,
+ i, test->next_field, cp);
+ (*nerrors)++;
+ continue;
+ }
+ if (delay.tv_sec != test->expected_delay.tv_sec) {
+ sudo_warnx("%s:%u wrong seconds (want %lld, got %lld)", __func__,
+ i, (long long)test->expected_delay.tv_sec,
+ (long long)delay.tv_sec);
+ (*nerrors)++;
+ continue;
+ }
+ if (delay.tv_nsec != test->expected_delay.tv_nsec) {
+ sudo_warnx("%s:%u wrong nanoseconds (want %ld, got %ld)", __func__,
+ i, test->expected_delay.tv_nsec, delay.tv_nsec);
+ (*nerrors)++;
+ continue;
+ }
+ }
+ (*ntests) += i;
+}
+
+static struct adjust_delay_test {
+ struct timespec in_delay;
+ struct timespec out_delay;
+ struct timespec max_delay;
+ double scale_factor;
+} adjust_delay_tests[] = {
+ { { 10, 300 }, { 10, 300 }, { 0, 0 }, 1.0 },
+ { { 10, 300 }, { 5, 150 }, { 0, 0 }, 2.0 },
+ { { 5, 300 }, { 2, 500000150 }, { 0, 0 }, 2.0 },
+ { { 0, 1000000 }, { 0, 333333 }, { 0, 0 }, 3 },
+ { { 10, 1000000 }, { 3, 333666666 }, { 0, 0 }, 3 },
+ { { 5, 150 }, { 10, 300 }, { 0, 0 }, 0.5 },
+ { { 5, 500000000 }, { 11, 0 }, { 0, 0 }, 0.5 },
+ { { 5, 150 }, { 5, 0 }, { 5, 0 }, 0.5 }
+};
+
+/*
+ * Test adjust_delay()
+ */
+void
+test_adjust_delay(int *ntests, int *nerrors)
+{
+ unsigned int i;
+
+ for (i = 0; i < nitems(adjust_delay_tests); i++) {
+ struct adjust_delay_test *test = &adjust_delay_tests[i];
+
+ adjust_delay(&test->in_delay, sudo_timespecisset(&test->max_delay) ?
+ &test->max_delay : NULL, test->scale_factor);
+ if (!sudo_timespeccmp(&test->in_delay, &test->out_delay, ==)) {
+ sudo_warnx("%s:%u want {%lld, %ld}, got {%lld, %ld}", __func__, i,
+ (long long)test->out_delay.tv_sec, test->out_delay.tv_nsec,
+ (long long)test->in_delay.tv_sec, test->in_delay.tv_nsec);
+ (*nerrors)++;
+ }
+ }
+ (*ntests) += i;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int tests = 0, errors = 0;
+
+ initprogname(argc > 0 ? argv[0] : "check_iolog_util");
+
+ test_parse_delay(&tests, &errors);
+
+ test_adjust_delay(&tests, &errors);
+
+ if (tests != 0) {
+ printf("check_iolog_util: %d test%s run, %d errors, %d%% success rate\n",
+ tests, tests == 1 ? "" : "s", errors,
+ (tests - errors) * 100 / tests);
+ }
+
+ exit(errors);
+}
diff --git a/plugins/sudoers/regress/logging/check_wrap.c b/plugins/sudoers/regress/logging/check_wrap.c
new file mode 100644
index 0000000..cc007ad
--- /dev/null
+++ b/plugins/sudoers/regress/logging/check_wrap.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2011-2013 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <limits.h>
+
+#define SUDO_ERROR_WRAP 0
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_plugin.h"
+#include "sudo_util.h"
+
+extern void writeln_wrap(FILE *fp, char *line, size_t len, size_t maxlen);
+
+__dso_public int main(int argc, char *argv[]);
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s inputfile\n", getprogname());
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ size_t len;
+ FILE *fp;
+ char *line, lines[2][2048];
+ int lineno = 0;
+ int which = 0;
+
+ initprogname(argc > 0 ? argv[0] : "check_wrap");
+
+ if (argc != 2)
+ usage();
+
+ fp = fopen(argv[1], "r");
+ if (fp == NULL)
+ sudo_fatalx("unable to open %s", argv[1]);
+
+ /*
+ * Each test record consists of a log entry on one line and a list of
+ * line lengths to test it with on the next. E.g.
+ *
+ * Jun 30 14:49:51 : millert : TTY=ttypn ; PWD=/usr/src/local/millert/hg/sudo/trunk/plugins/sudoers ; USER=root ; TSID=0004LD ; COMMAND=/usr/local/sbin/visudo
+ * 60-80,40
+ */
+ while ((line = fgets(lines[which], sizeof(lines[which]), fp)) != NULL) {
+ char *cp, *last;
+
+ len = strcspn(line, "\n");
+ line[len] = '\0';
+
+ /* If we read the 2nd line, parse list of line lengths and check. */
+ if (which) {
+ lineno++;
+ for (cp = strtok_r(lines[1], ",", &last); cp != NULL; cp = strtok_r(NULL, ",", &last)) {
+ char *dash;
+ size_t maxlen;
+
+ /* May be either a number or a range. */
+ dash = strchr(cp, '-');
+ if (dash != NULL) {
+ *dash = '\0';
+ len = strtonum(cp, 1, INT_MAX, NULL);
+ maxlen = strtonum(dash + 1, 1, INT_MAX, NULL);
+ } else {
+ len = maxlen = strtonum(cp, 1, INT_MAX, NULL);
+ }
+ if (len == 0 || maxlen == 0)
+ sudo_fatalx("%s: invalid length on line %d\n", argv[1], lineno);
+ while (len <= maxlen) {
+ printf("# word wrap at %d characters\n", (int)len);
+ writeln_wrap(stdout, lines[0], strlen(lines[0]), len);
+ len++;
+ }
+ }
+ }
+ which = !which;
+ }
+
+ exit(0);
+}
diff --git a/plugins/sudoers/regress/logging/check_wrap.in b/plugins/sudoers/regress/logging/check_wrap.in
new file mode 100644
index 0000000..a2d1f08
--- /dev/null
+++ b/plugins/sudoers/regress/logging/check_wrap.in
@@ -0,0 +1,4 @@
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ; PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool list users
+60-80,120,140
+Jun 26 18:00:06 : millert : TTY=ttypm ; PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ; TSID=0004KT ; COMMAND=/bin/rm /root/.bash_profile
+60-80,120,140
diff --git a/plugins/sudoers/regress/logging/check_wrap.out.ok b/plugins/sudoers/regress/logging/check_wrap.out.ok
new file mode 100644
index 0000000..4842443
--- /dev/null
+++ b/plugins/sudoers/regress/logging/check_wrap.out.ok
@@ -0,0 +1,175 @@
+# word wrap at 60 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1
+ ; PWD=/home/tu2sp3-a ; USER=root ;
+ COMMAND=/opt/quest/bin/vastool list users
+# word wrap at 61 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1
+ ; PWD=/home/tu2sp3-a ; USER=root ;
+ COMMAND=/opt/quest/bin/vastool list users
+# word wrap at 62 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ;
+ COMMAND=/opt/quest/bin/vastool list users
+# word wrap at 63 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ;
+ COMMAND=/opt/quest/bin/vastool list users
+# word wrap at 64 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ;
+ COMMAND=/opt/quest/bin/vastool list users
+# word wrap at 65 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ;
+ COMMAND=/opt/quest/bin/vastool list users
+# word wrap at 66 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ;
+ COMMAND=/opt/quest/bin/vastool list users
+# word wrap at 67 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool
+ list users
+# word wrap at 68 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool
+ list users
+# word wrap at 69 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool
+ list users
+# word wrap at 70 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool
+ list users
+# word wrap at 71 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool
+ list users
+# word wrap at 72 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool list
+ users
+# word wrap at 73 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool list
+ users
+# word wrap at 74 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool list
+ users
+# word wrap at 75 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool list
+ users
+# word wrap at 76 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool list
+ users
+# word wrap at 77 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool list
+ users
+# word wrap at 78 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool list users
+# word wrap at 79 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool list users
+# word wrap at 80 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ;
+ PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool list users
+# word wrap at 120 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ; PWD=/home/tu2sp3-a ; USER=root ;
+ COMMAND=/opt/quest/bin/vastool list users
+# word wrap at 140 characters
+Jul 11 11:30:17 : tu2sp3-a : command not allowed ; TTY=pts/1 ; PWD=/home/tu2sp3-a ; USER=root ; COMMAND=/opt/quest/bin/vastool list users
+# word wrap at 60 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ;
+ TSID=0004KT ; COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 61 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ;
+ TSID=0004KT ; COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 62 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ;
+ TSID=0004KT ; COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 63 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ;
+ TSID=0004KT ; COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 64 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ;
+ TSID=0004KT ; COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 65 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ;
+ TSID=0004KT ; COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 66 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ;
+ TSID=0004KT ; COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 67 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ;
+ TSID=0004KT ; COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 68 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ;
+ TSID=0004KT ; COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 69 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ;
+ TSID=0004KT ; COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 70 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ; TSID=0004KT
+ ; COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 71 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ; TSID=0004KT
+ ; COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 72 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ; TSID=0004KT ;
+ COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 73 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ; TSID=0004KT ;
+ COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 74 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ; TSID=0004KT ;
+ COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 75 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ; TSID=0004KT ;
+ COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 76 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ; TSID=0004KT ;
+ COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 77 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ; TSID=0004KT ;
+ COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 78 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ; TSID=0004KT ;
+ COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 79 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ;
+ PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ; TSID=0004KT ;
+ COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 80 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ; PWD=/usr/src/local/millert/hg/sudo/build
+ ; USER=root ; TSID=0004KT ; COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 120 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ; PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ; TSID=0004KT ;
+ COMMAND=/bin/rm /root/.bash_profile
+# word wrap at 140 characters
+Jun 26 18:00:06 : millert : TTY=ttypm ; PWD=/usr/src/local/millert/hg/sudo/build ; USER=root ; TSID=0004KT ; COMMAND=/bin/rm
+ /root/.bash_profile
diff --git a/plugins/sudoers/regress/parser/check_addr.c b/plugins/sudoers/regress/parser/check_addr.c
new file mode 100644
index 0000000..5f67d4d
--- /dev/null
+++ b/plugins/sudoers/regress/parser/check_addr.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2011-2013 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <ctype.h>
+#include <errno.h>
+#include <grp.h>
+#include <pwd.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define SUDO_ERROR_WRAP 0
+
+#include "sudoers.h"
+#include "interfaces.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+static int
+check_addr(char *input)
+{
+ int expected, matched;
+ const char *errstr;
+ size_t len;
+ char *cp;
+
+ while (isspace((unsigned char)*input))
+ input++;
+
+ /* input: "addr[/mask] 1/0" */
+ len = strcspn(input, " \t");
+ cp = input + len;
+ while (isspace((unsigned char)*cp))
+ cp++;
+ expected = strtonum(cp, 0, 1, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx("expecting 0 or 1, got %s", cp);
+ input[len] = '\0';
+
+ matched = addr_matches(input);
+ if (matched != expected) {
+ sudo_warnx("%s %smatched: FAIL", input, matched ? "" : "not ");
+ return 1;
+ }
+ return 0;
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s datafile\n", getprogname());
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ntests = 0, errors = 0;
+ char *cp, line[2048];
+ size_t len;
+ FILE *fp;
+
+ initprogname(argc > 0 ? argv[0] : "check_addr");
+
+ if (argc != 2)
+ usage();
+
+ fp = fopen(argv[1], "r");
+ if (fp == NULL)
+ sudo_fatalx("unable to open %s", argv[1]);
+
+ /*
+ * Input is in the following format. There are two types of
+ * lines: interfaces, which sets the address and mask of the
+ * locally connected ethernet interfaces for the lines that
+ * follow and, address lines that include and address (with
+ * optional netmask) to match, followed by expected match status
+ * (1 or 0). E.g.
+ *
+ * interfaces: addr1/mask addr2/mask ...
+ * address: addr[/mask] 1/0
+ * address: addr[/mask] 1/0
+ * interfaces: addr3/mask addr4/mask ...
+ * address: addr[/mask] 1/0
+ */
+
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ len = strcspn(line, "\n");
+ line[len] = '\0';
+
+ /* Ignore comments */
+ if ((cp = strchr(line, '#')) != NULL)
+ *cp = '\0';
+
+ /* Skip blank lines. */
+ if (line[0] == '\0')
+ continue;
+
+ if (strncmp(line, "interfaces:", sizeof("interfaces:") - 1) == 0) {
+ if (!set_interfaces(line + sizeof("interfaces:") - 1)) {
+ sudo_warn("unable to parse interfaces list");
+ errors++;
+ }
+ } else if (strncmp(line, "address:", sizeof("address:") - 1) == 0) {
+ errors += check_addr(line + sizeof("address:") - 1);
+ ntests++;
+ } else {
+ sudo_warnx("unexpected data line: %s\n", line);
+ continue;
+ }
+ }
+
+ if (ntests != 0) {
+ printf("check_addr: %d tests run, %d errors, %d%% success rate\n",
+ ntests, errors, (ntests - errors) * 100 / ntests);
+ }
+
+ exit(errors);
+}
diff --git a/plugins/sudoers/regress/parser/check_addr.in b/plugins/sudoers/regress/parser/check_addr.in
new file mode 100644
index 0000000..a3c8612
--- /dev/null
+++ b/plugins/sudoers/regress/parser/check_addr.in
@@ -0,0 +1,13 @@
+#
+interfaces: 10.5.54.73/255.255.240.0
+address: 10.5.48.0 1
+address: 10.5.54.0/20 1
+#
+interfaces: 128.138.243.151/255.255.255.0 128.138.241.53/255.255.255.0
+address: 128.138.243.0 1
+address: 128.138.243.0/24 1
+address: 128.138.241.0 1
+address: 128.138.241.0/24 1
+address: 128.138.242.0/24 0
+address: 128.138.0.0 0
+address: 128.138.0.0/16 1
diff --git a/plugins/sudoers/regress/parser/check_base64.c b/plugins/sudoers/regress/parser/check_base64.c
new file mode 100644
index 0000000..a3f28e0
--- /dev/null
+++ b/plugins/sudoers/regress/parser/check_base64.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2013-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+
+#define SUDO_ERROR_WRAP 0
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+
+/* From parse.h */
+extern size_t base64_decode(const char *str, unsigned char *dst, size_t dsize);
+extern size_t base64_encode(const unsigned char *in, size_t in_len, char *out, size_t out_len);
+
+__dso_public int main(int argc, char *argv[]);
+
+static unsigned char bstring1[] = { 0xea, 0xb8, 0xa2, 0x71, 0xef, 0x67, 0xc1, 0xcd, 0x0d, 0xd9, 0xa6, 0xaa, 0xa8, 0x24, 0x77, 0x2a, 0xfc, 0x6f, 0x76, 0x37, 0x1b, 0xed, 0x9e, 0x1a, 0x90, 0x5f, 0xcf, 0xbc, 0x00 };
+
+struct base64_test {
+ const char *ascii;
+ const char *encoded;
+} test_strings[] = {
+ {
+ (char *)bstring1,
+ "6riice9nwc0N2aaqqCR3Kvxvdjcb7Z4akF/PvA=="
+ },
+ {
+ "any carnal pleasure.",
+ "YW55IGNhcm5hbCBwbGVhc3VyZS4="
+ },
+ {
+ "any carnal pleasure",
+ "YW55IGNhcm5hbCBwbGVhc3VyZQ=="
+ },
+ {
+ "any carnal pleasur",
+ "YW55IGNhcm5hbCBwbGVhc3Vy"
+ },
+ {
+ "any carnal pleasu",
+ "YW55IGNhcm5hbCBwbGVhc3U="
+ },
+ {
+ "any carnal pleas",
+ "YW55IGNhcm5hbCBwbGVhcw=="
+ }
+};
+
+int
+main(int argc, char *argv[])
+{
+ int ntests = nitems(test_strings);
+ int i, errors = 0;
+ unsigned char buf[64];
+ size_t len;
+
+ initprogname(argc > 0 ? argv[0] : "check_base64");
+
+ for (i = 0; i < ntests; i++) {
+ /* Test decode. */
+ len = base64_decode(test_strings[i].encoded, buf, sizeof(buf));
+ if (len == (size_t)-1) {
+ fprintf(stderr, "check_base64: failed to decode %s\n",
+ test_strings[i].encoded);
+ errors++;
+ } else {
+ buf[len] = '\0';
+ if (strcmp(test_strings[i].ascii, (char *)buf) != 0) {
+ fprintf(stderr, "check_base64: expected %s, got %s\n",
+ test_strings[i].ascii, buf);
+ errors++;
+ }
+ }
+
+ /* Test encode. */
+ len = base64_encode((unsigned char *)test_strings[i].ascii,
+ strlen(test_strings[i].ascii), (char *)buf, sizeof(buf));
+ if (len == (size_t)-1) {
+ fprintf(stderr, "check_base64: failed to encode %s\n",
+ test_strings[i].ascii);
+ errors++;
+ } else {
+ if (strcmp(test_strings[i].encoded, (char *)buf) != 0) {
+ fprintf(stderr, "check_base64: expected %s, got %s\n",
+ test_strings[i].encoded, buf);
+ errors++;
+ }
+ }
+ }
+ ntests *= 2; /* we test in both directions */
+
+ printf("check_base64: %d tests run, %d errors, %d%% success rate\n",
+ ntests, errors, (ntests - errors) * 100 / ntests);
+ exit(errors);
+}
diff --git a/plugins/sudoers/regress/parser/check_digest.c b/plugins/sudoers/regress/parser/check_digest.c
new file mode 100644
index 0000000..0d49a35
--- /dev/null
+++ b/plugins/sudoers/regress/parser/check_digest.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2013-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+#include <limits.h>
+#include <unistd.h>
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_queue.h"
+#include "sudo_digest.h"
+#include "sudo_util.h"
+#include "parse.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+#define NUM_TESTS 8
+static const char *test_strings[NUM_TESTS] = {
+ "",
+ "a",
+ "abc",
+ "message digest",
+ "abcdefghijklmnopqrstuvwxyz",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "12345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890",
+};
+
+static unsigned char *
+check_digest(int digest_type, const char *buf, size_t buflen, size_t *digest_len)
+{
+ char tfile[] = "digest.XXXXXX";
+ unsigned char *digest = NULL;
+ int tfd;
+
+ /* Write test data to temporary file. */
+ tfd = mkstemp(tfile);
+ if (tfd == -1) {
+ sudo_warn_nodebug("mkstemp");
+ goto done;
+ }
+ if ((size_t)write(tfd, buf, buflen) != buflen) {
+ sudo_warn_nodebug("write");
+ goto done;
+ }
+ lseek(tfd, 0, SEEK_SET);
+
+ /* Get file digest. */
+ digest = sudo_filedigest(tfd, tfile, digest_type, digest_len);
+ if (digest == NULL) {
+ /* Warning (if any) printed by sudo_filedigest() */
+ goto done;
+ }
+done:
+ if (tfd != -1) {
+ close(tfd);
+ unlink(tfile);
+ }
+ return digest;
+}
+
+int
+main(int argc, char *argv[])
+{
+ static const char hex[] = "0123456789abcdef";
+ char buf[1000 * 1000];
+ unsigned char *digest;
+ unsigned int i, j;
+ size_t digest_len;
+ int digest_type;
+
+ initprogname(argc > 0 ? argv[0] : "check_digest");
+
+ for (digest_type = 0; digest_type < SUDO_DIGEST_INVALID; digest_type++) {
+ for (i = 0; i < NUM_TESTS; i++) {
+ digest = check_digest(digest_type, test_strings[i],
+ strlen(test_strings[i]), &digest_len);
+ if (digest != NULL) {
+ printf("%s (\"%s\") = ", digest_type_to_name(digest_type),
+ test_strings[i]);
+ for (j = 0; j < digest_len; j++) {
+ putchar(hex[digest[j] >> 4]);
+ putchar(hex[digest[j] & 0x0f]);
+ }
+ putchar('\n');
+ free(digest);
+ }
+ }
+
+ /* Simulate a string of a million 'a' characters. */
+ memset(buf, 'a', sizeof(buf));
+ digest = check_digest(digest_type, buf, sizeof(buf), &digest_len);
+ if (digest != NULL) {
+ printf("%s (one million 'a' characters) = ",
+ digest_type_to_name(digest_type));
+ for (j = 0; j < digest_len; j++) {
+ putchar(hex[digest[j] >> 4]);
+ putchar(hex[digest[j] & 0x0f]);
+ }
+ putchar('\n');
+ free(digest);
+ }
+ }
+
+ return 0;
+}
diff --git a/plugins/sudoers/regress/parser/check_digest.out.ok b/plugins/sudoers/regress/parser/check_digest.out.ok
new file mode 100644
index 0000000..a353664
--- /dev/null
+++ b/plugins/sudoers/regress/parser/check_digest.out.ok
@@ -0,0 +1,36 @@
+sha224 ("") = d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f
+sha224 ("a") = abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5
+sha224 ("abc") = 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7
+sha224 ("message digest") = 2cb21c83ae2f004de7e81c3c7019cbcb65b71ab656b22d6d0c39b8eb
+sha224 ("abcdefghijklmnopqrstuvwxyz") = 45a5f72c39c5cff2522eb3429799e49e5f44b356ef926bcf390dccc2
+sha224 ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525
+sha224 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = bff72b4fcb7d75e5632900ac5f90d219e05e97a7bde72e740db393d9
+sha224 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = b50aecbe4e9bb0b57bc5f3ae760a8e01db24f203fb3cdcd13148046e
+sha224 (one million 'a' characters) = 20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67
+sha256 ("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+sha256 ("a") = ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb
+sha256 ("abc") = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
+sha256 ("message digest") = f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650
+sha256 ("abcdefghijklmnopqrstuvwxyz") = 71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73
+sha256 ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1
+sha256 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0
+sha256 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e
+sha256 (one million 'a' characters) = cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0
+sha384 ("") = 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b
+sha384 ("a") = 54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31
+sha384 ("abc") = cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7
+sha384 ("message digest") = 473ed35167ec1f5d8e550368a3db39be54639f828868e9454c239fc8b52e3c61dbd0d8b4de1390c256dcbb5d5fd99cd5
+sha384 ("abcdefghijklmnopqrstuvwxyz") = feb67349df3db6f5924815d6c3dc133f091809213731fe5c7b5f4999e463479ff2877f5f2936fa63bb43784b12f3ebb4
+sha384 ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b
+sha384 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = 1761336e3f7cbfe51deb137f026f89e01a448e3b1fafa64039c1464ee8732f11a5341a6f41e0c202294736ed64db1a84
+sha384 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = b12932b0627d1c060942f5447764155655bd4da0c9afa6dd9b9ef53129af1b8fb0195996d2de9ca0df9d821ffee67026
+sha384 (one million 'a' characters) = 9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985
+sha512 ("") = cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
+sha512 ("a") = 1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75
+sha512 ("abc") = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
+sha512 ("message digest") = 107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f3309e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c
+sha512 ("abcdefghijklmnopqrstuvwxyz") = 4dbff86cc2ca1bae1e16468a05cb9881c97f1753bce3619034898faa1aabe429955a1bf8ec483d7421fe3c1646613a59ed5441fb0f321389f77f48a879c7b1f1
+sha512 ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445
+sha512 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = 1e07be23c26a86ea37ea810c8ec7809352515a970e9253c26f536cfc7a9996c45c8370583e0a78fa4a90041d71a4ceab7423f19c71b9d5a3e01249f0bebd5894
+sha512 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 72ec1ef1124a45b047e8b7c75a932195135bb61de24ec0d1914042246e0aec3a2354e093d76f3048b456764346900cb130d2a4fd5dd16abb5e30bcb850dee843
+sha512 (one million 'a' characters) = e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b
diff --git a/plugins/sudoers/regress/parser/check_fill.c b/plugins/sudoers/regress/parser/check_fill.c
new file mode 100644
index 0000000..e0312b6
--- /dev/null
+++ b/plugins/sudoers/regress/parser/check_fill.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2011-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <grp.h>
+#include <pwd.h>
+
+#define SUDO_ERROR_WRAP 0
+
+#include "sudo_compat.h"
+#include "sudo_queue.h"
+#include "parse.h"
+#include "toke.h"
+#include "sudo_plugin.h"
+#include "sudo_util.h"
+#include <gram.h>
+
+__dso_public int main(int argc, char *argv[]);
+
+/*
+ * TODO: test realloc
+ */
+
+YYSTYPE sudoerslval;
+
+struct fill_test {
+ const char *input;
+ const char *output;
+ int len;
+ int addspace;
+};
+
+/*
+ * In "normal" fill, anything can be escaped and hex chars are expanded.
+ */
+static struct fill_test txt_data[] = {
+ { "Embedded\\x20Space", "Embedded Space", 0 },
+ { "\\x20Leading", " Leading", 0 },
+ { "Trailing\\x20", "Trailing ", 0 },
+ { "Multiple\\x20\\x20Spaces", "Multiple Spaces", 0 },
+ { "Hexparse\\x200Check", "Hexparse 0Check", 0 },
+ { "Escaped\\\\Escape", "Escaped\\Escape", 0 },
+ { "LongGroupName", "LongGrou", 8 }
+};
+
+/*
+ * The only escaped chars in a command should be [,:= \t#]
+ * The rest are done by glob() or fnmatch().
+ */
+static struct fill_test cmd_data[] = {
+ { "foo\\,bar", "foo,bar", 0 },
+ { "this\\:that", "this:that", 0 },
+ { "foo\\=bar", "foo=bar", 0 },
+ { "tab\\\tstop", "tab\tstop", 0 },
+ { "not a \\#comment", "not a #comment", 0 }
+};
+
+/*
+ * No escaped characters in command line args.
+ * Arguments get appended.
+ */
+static struct fill_test args_data[] = {
+ { "/", "/", 0, 0 },
+ { "-type", "/ -type", 0, 1 },
+ { "f", "/ -type f", 0, 1 },
+ { "-exec", "/ -type f -exec", 0, 1 },
+ { "ls", "/ -type f -exec ls", 0, 1 },
+ { "{}", "/ -type f -exec ls {}", 0, 1 }
+};
+
+static int
+check_fill(const char *input, int len, int addspace, const char *expect, char **resultp)
+{
+ if (sudoerslval.string != NULL) {
+ free(sudoerslval.string);
+ sudoerslval.string = NULL;
+ }
+ if (!fill(input, len))
+ return -1;
+ *resultp = sudoerslval.string;
+ return !strcmp(sudoerslval.string, expect);
+}
+
+static int
+check_fill_cmnd(const char *input, int len, int addspace, const char *expect, char **resultp)
+{
+ if (sudoerslval.command.cmnd != NULL) {
+ free(sudoerslval.command.cmnd);
+ sudoerslval.command.cmnd = NULL;
+ }
+ if (!fill_cmnd(input, len))
+ return -1;
+ *resultp = sudoerslval.command.cmnd;
+ return !strcmp(sudoerslval.command.cmnd, expect);
+}
+
+static int
+check_fill_args(const char *input, int len, int addspace, const char *expect, char **resultp)
+{
+ /* Must not free old sudoerslval.command.args as gets appended to. */
+ if (!fill_args(input, len, addspace))
+ return -1;
+ *resultp = sudoerslval.command.args;
+ return !strcmp(sudoerslval.command.args, expect);
+}
+
+static int
+do_tests(int (*checker)(const char *, int, int, const char *, char **),
+ struct fill_test *data, size_t ntests)
+{
+ int len, errors = 0;
+ unsigned int i;
+ char *result;
+
+ for (i = 0; i < ntests; i++) {
+ if (data[i].len == 0)
+ len = strlen(data[i].input);
+ else
+ len = data[i].len;
+
+ switch ((*checker)(data[i].input, len, data[i].addspace, data[i].output, &result)) {
+ case 0:
+ /* no match */
+ fprintf(stderr, "Failed parsing %.*s: expected [%s], got [%s]\n",
+ (int)data[i].len, data[i].input, data[i].output, result);
+ errors++;
+ break;
+ case 1:
+ /* match */
+ break;
+ default:
+ /* error */
+ fprintf(stderr, "Failed parsing %.*s: fill function failure\n",
+ (int)data[i].len, data[i].input);
+ errors++;
+ break;
+ }
+ }
+
+ return errors;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ntests, errors = 0;
+
+ initprogname(argc > 0 ? argv[0] : "check_fill");
+
+ errors += do_tests(check_fill, txt_data, nitems(txt_data));
+ errors += do_tests(check_fill_cmnd, cmd_data, nitems(cmd_data));
+ errors += do_tests(check_fill_args, args_data, nitems(args_data));
+
+ ntests = nitems(txt_data) + nitems(cmd_data) + nitems(args_data);
+ printf("%s: %d tests run, %d errors, %d%% success rate\n", getprogname(),
+ ntests, errors, (ntests - errors) * 100 / ntests);
+
+ exit(errors);
+}
+
+/* STUB */
+void
+sudoerserror(const char *s)
+{
+ return;
+}
diff --git a/plugins/sudoers/regress/parser/check_gentime.c b/plugins/sudoers/regress/parser/check_gentime.c
new file mode 100644
index 0000000..957ea4c
--- /dev/null
+++ b/plugins/sudoers/regress/parser/check_gentime.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <time.h>
+
+#define SUDO_ERROR_WRAP 0
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+#include "sudoers_debug.h"
+#include "parse.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+const struct gentime_test {
+ char *gentime;
+ time_t unixtime;
+} tests[] = {
+ { "199412161032ZZ", -1 },
+ { "199412161032Z", 787573920 },
+ { "199412160532-0500", 787573920 },
+ { "199412160532-05000", -1 },
+ { "199412160532", 787573920 }, /* local time is EST */
+ { "20170214083000-0500", 1487079000 },
+ { "201702140830-0500", 1487079000 },
+ { "201702140830", 1487079000 }, /* local time is EST */
+ { "201702140830.3-0500", 1487079018 },
+ { "201702140830,3-0500", 1487079018 },
+ { "20170214083000.5Z", 1487061000 },
+ { "20170214083000,5Z", 1487061000 },
+ { "201702142359.4Z", 1487116764 },
+ { "201702142359,4Z", 1487116764 },
+ { "2017021408.5Z", 1487061000 },
+ { "2017021408,5Z", 1487061000 },
+ { "20170214Z", -1 },
+};
+
+int
+main(int argc, char *argv[])
+{
+ const int ntests = nitems(tests);
+ int i, errors = 0;
+ time_t result;
+
+ initprogname(argc > 0 ? argv[0] : "check_gentime");
+
+ /* Do local time tests in Eastern Standard Time. */
+ putenv("TZ=EST5EST5");
+ tzset();
+
+ for (i = 0; i < ntests; i++) {
+ result = parse_gentime(tests[i].gentime);
+ if (result != tests[i].unixtime) {
+ fprintf(stderr, "check_gentime[%d]: %s: expected %lld, got %lld\n",
+ i, tests[i].gentime,
+ (long long)tests[i].unixtime, (long long)result);
+ errors++;
+ }
+ }
+ printf("check_gentime: %d tests run, %d errors, %d%% success rate\n",
+ ntests, errors, (ntests - errors) * 100 / ntests);
+ exit(errors);
+}
diff --git a/plugins/sudoers/regress/parser/check_hexchar.c b/plugins/sudoers/regress/parser/check_hexchar.c
new file mode 100644
index 0000000..d4f9657
--- /dev/null
+++ b/plugins/sudoers/regress/parser/check_hexchar.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+
+#define SUDO_ERROR_WRAP 0
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+
+int hexchar(const char *s);
+
+__dso_public int main(int argc, char *argv[]);
+
+struct hexchar_test {
+ char hex[3];
+ int value;
+};
+
+int
+main(int argc, char *argv[])
+{
+ struct hexchar_test *test_data;
+ int i, ntests, result, errors = 0;
+ static const char xdigs_lower[] = "0123456789abcdef";
+ static const char xdigs_upper[] = "0123456789ABCDEF";
+
+ initprogname(argc > 0 ? argv[0] : "check_hexchar");
+
+ /* Build up test data. */
+ ntests = 256 + 256 + 3;
+ test_data = calloc(sizeof(*test_data), ntests);
+ for (i = 0; i < 256; i++) {
+ /* lower case */
+ test_data[i].value = i;
+ test_data[i].hex[1] = xdigs_lower[ (i & 0x0f)];
+ test_data[i].hex[0] = xdigs_lower[((i & 0xf0) >> 4)];
+ /* upper case */
+ test_data[i + 256].value = i;
+ test_data[i + 256].hex[1] = xdigs_upper[ (i & 0x0f)];
+ test_data[i + 256].hex[0] = xdigs_upper[((i & 0xf0) >> 4)];
+ }
+ /* Also test invalid data */
+ test_data[ntests - 3].hex[0] = '\0';
+ test_data[ntests - 3].value = -1;
+ strlcpy(test_data[ntests - 2].hex, "AG", sizeof(test_data[ntests - 2].hex));
+ test_data[ntests - 2].value = -1;
+ strlcpy(test_data[ntests - 1].hex, "-1", sizeof(test_data[ntests - 1].hex));
+ test_data[ntests - 1].value = -1;
+
+ for (i = 0; i < ntests; i++) {
+ result = hexchar(test_data[i].hex);
+ if (result != test_data[i].value) {
+ fprintf(stderr, "check_hexchar: expected %d, got %d\n",
+ test_data[i].value, result);
+ errors++;
+ }
+ }
+ printf("check_hexchar: %d tests run, %d errors, %d%% success rate\n",
+ ntests, errors, (ntests - errors) * 100 / ntests);
+ exit(errors);
+}
diff --git a/plugins/sudoers/regress/starttime/check_starttime.c b/plugins/sudoers/regress/starttime/check_starttime.c
new file mode 100644
index 0000000..e858ad3
--- /dev/null
+++ b/plugins/sudoers/regress/starttime/check_starttime.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+#include "sudo_fatal.h"
+#include "check.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+#ifdef __linux__
+static int
+get_now(struct timespec *now)
+{
+ const char *errstr;
+ char buf[1024];
+ time_t seconds;
+ int ret = -1;
+ FILE *fp;
+
+ /* Linux process start time is relative to boot time. */
+ fp = fopen("/proc/stat", "r");
+ if (fp != NULL) {
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ if (strncmp(buf, "btime ", 6) != 0)
+ continue;
+ buf[strcspn(buf, "\n")] = '\0';
+
+ /* Boot time is in seconds since the epoch. */
+ seconds = strtonum(buf + 6, 0, TIME_T_MAX, &errstr);
+ if (errstr != NULL)
+ return -1;
+
+ /* Instead of the real time, "now" is relative to boot time. */
+ if (sudo_gettime_real(now) == -1)
+ return -1;
+ now->tv_sec -= seconds;
+ ret = 0;
+ break;
+ }
+ fclose(fp);
+ }
+ return ret;
+}
+#else
+static int
+get_now(struct timespec *now)
+{
+ /* Process start time is relative to wall clock time. */
+ return sudo_gettime_real(now);
+}
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int ntests = 0, errors = 0;
+ struct timespec now, then, delta;
+ pid_t pids[2];
+ int i;
+
+ initprogname(argc > 0 ? argv[0] : "check_starttime");
+
+ if (get_now(&now) == -1)
+ sudo_fatal_nodebug("unable to get current time");
+
+ pids[0] = getpid();
+ pids[1] = getppid();
+
+ for (i = 0; i < 2; i++) {
+ ntests++;
+ if (get_starttime(pids[i], &then) == -1) {
+ printf("%s: test %d: unable to get start time for pid %d\n",
+ getprogname(), ntests, (int)pids[i]);
+ errors++;
+ }
+ if (i != 0)
+ continue;
+
+ /* Verify our own process start time, allowing for some drift. */
+ ntests++;
+ sudo_timespecsub(&then, &now, &delta);
+ if (delta.tv_sec > 30 || delta.tv_sec < -30) {
+ printf("%s: test %d: unexpected start time for pid %d: %s",
+ getprogname(), ntests, (int)pids[i], ctime(&then.tv_sec));
+ errors++;
+ }
+ }
+
+ printf("%s: %d tests run, %d errors, %d%% success rate\n", getprogname(),
+ ntests, errors, (ntests - errors) * 100 / ntests);
+
+ exit(errors);
+}
diff --git a/plugins/sudoers/regress/sudoers/test1.in b/plugins/sudoers/regress/sudoers/test1.in
new file mode 100644
index 0000000..d87c872
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test1.in
@@ -0,0 +1,12 @@
+#
+# Verify that all command tags are parsed OK.
+# See https://bugzilla.sudo.ws/show_bug.cgi?id=437
+#
+user1 ALL = LOG_INPUT: LOG_OUTPUT: /usr/bin/su -:\
+ ALL = NOLOG_INPUT: NOLOG_OUTPUT: /usr/bin/id
+user2 ALL = NOPASSWD: NOEXEC: SETENV: /usr/bin/vi:\
+ ALL = PASSWD: EXEC: NOSETENV: /usr/bin/echo
+user3 ALL = MAIL: /bin/sh:\
+ ALL = NOMAIL: /usr/bin/id
+user4 ALL = FOLLOW: sudoedit /etc/motd:\
+ ALL = NOFOLLOW: sudoedit /home/*/*
diff --git a/plugins/sudoers/regress/sudoers/test1.json.ok b/plugins/sudoers/regress/sudoers/test1.json.ok
new file mode 100644
index 0000000..9523e4a
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test1.json.ok
@@ -0,0 +1,154 @@
+{
+ "User_Specs": [
+ {
+ "User_List": [
+ { "username": "user1" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "log_input": true },
+ { "log_output": true }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/su -" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user1" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "log_input": false },
+ { "log_output": false }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user2" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "authenticate": false },
+ { "noexec": true },
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/vi" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user2" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "authenticate": true },
+ { "noexec": false },
+ { "setenv": false }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/echo" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user3" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "send_mail": true }
+ ],
+ "Commands": [
+ { "command": "/bin/sh" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user3" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "send_mail": false }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user4" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "sudoedit_follow": true }
+ ],
+ "Commands": [
+ { "command": "sudoedit /etc/motd" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user4" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "sudoedit_follow": false }
+ ],
+ "Commands": [
+ { "command": "sudoedit /home/*/*" }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/plugins/sudoers/regress/sudoers/test1.ldif.ok b/plugins/sudoers/regress/sudoers/test1.ldif.ok
new file mode 100644
index 0000000..7f3fcfc
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test1.ldif.ok
@@ -0,0 +1,88 @@
+dn: cn=user1,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user1
+sudoUser: user1
+sudoHost: ALL
+sudoOption: log_input
+sudoOption: log_output
+sudoCommand: /usr/bin/su -
+sudoOrder: 1
+
+dn: cn=user1_1,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user1_1
+sudoUser: user1
+sudoHost: ALL
+sudoOption: !log_input
+sudoOption: !log_output
+sudoCommand: /usr/bin/id
+sudoOrder: 2
+
+dn: cn=user2,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user2
+sudoUser: user2
+sudoHost: ALL
+sudoOption: !authenticate
+sudoOption: noexec
+sudoOption: setenv
+sudoCommand: /usr/bin/vi
+sudoOrder: 3
+
+dn: cn=user2_1,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user2_1
+sudoUser: user2
+sudoHost: ALL
+sudoOption: authenticate
+sudoOption: !noexec
+sudoOption: !setenv
+sudoCommand: /usr/bin/echo
+sudoOrder: 4
+
+dn: cn=user3,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user3
+sudoUser: user3
+sudoHost: ALL
+sudoOption: mail_all_cmnds
+sudoCommand: /bin/sh
+sudoOrder: 5
+
+dn: cn=user3_1,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user3_1
+sudoUser: user3
+sudoHost: ALL
+sudoOption: !mail_all_cmnds
+sudoOption: !mail_always
+sudoOption: !mail_no_perms
+sudoCommand: /usr/bin/id
+sudoOrder: 6
+
+dn: cn=user4,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user4
+sudoUser: user4
+sudoHost: ALL
+sudoOption: sudoedit_follow
+sudoCommand: sudoedit /etc/motd
+sudoOrder: 7
+
+dn: cn=user4_1,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user4_1
+sudoUser: user4
+sudoHost: ALL
+sudoOption: !sudoedit_follow
+sudoCommand: sudoedit /home/*/*
+sudoOrder: 8
+
diff --git a/plugins/sudoers/regress/sudoers/test1.ldif2sudo.ok b/plugins/sudoers/regress/sudoers/test1.ldif2sudo.ok
new file mode 100644
index 0000000..126fe91
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test1.ldif2sudo.ok
@@ -0,0 +1,13 @@
+# sudoRole user1, user1_1
+user1 ALL = LOG_INPUT: LOG_OUTPUT: /usr/bin/su -, NOLOG_INPUT: NOLOG_OUTPUT:\
+ /usr/bin/id
+
+# sudoRole user2, user2_1
+user2 ALL = SETENV: NOEXEC: NOPASSWD: /usr/bin/vi, NOSETENV: EXEC: PASSWD:\
+ /usr/bin/echo
+
+# sudoRole user3, user3_1
+user3 ALL = MAIL: /bin/sh, NOMAIL: /usr/bin/id
+
+# sudoRole user4, user4_1
+user4 ALL = FOLLOW: sudoedit /etc/motd, NOFOLLOW: sudoedit /home/*/*
diff --git a/plugins/sudoers/regress/sudoers/test1.out.ok b/plugins/sudoers/regress/sudoers/test1.out.ok
new file mode 100644
index 0000000..8693cea
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test1.out.ok
@@ -0,0 +1,6 @@
+Parses OK.
+
+user1 ALL = LOG_INPUT: LOG_OUTPUT: /usr/bin/su - : ALL = NOLOG_INPUT: NOLOG_OUTPUT: /usr/bin/id
+user2 ALL = SETENV: NOEXEC: NOPASSWD: /usr/bin/vi : ALL = NOSETENV: EXEC: PASSWD: /usr/bin/echo
+user3 ALL = MAIL: /bin/sh : ALL = NOMAIL: /usr/bin/id
+user4 ALL = FOLLOW: sudoedit /etc/motd : ALL = NOFOLLOW: sudoedit /home/*/*
diff --git a/plugins/sudoers/regress/sudoers/test1.toke.ok b/plugins/sudoers/regress/sudoers/test1.toke.ok
new file mode 100644
index 0000000..79945dc
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test1.toke.ok
@@ -0,0 +1,8 @@
+#
+#
+#
+#
+WORD(5) ALL = LOG_INPUT LOG_OUTPUT COMMAND ARG : ALL = NOLOG_INPUT NOLOG_OUTPUT COMMAND
+WORD(5) ALL = NOPASSWD NOEXEC SETENV COMMAND : ALL = PASSWD EXEC NOSETENV COMMAND
+WORD(5) ALL = MAIL COMMAND : ALL = NOMAIL COMMAND
+WORD(5) ALL = FOLLOW COMMAND ARG : ALL = NOFOLLOW COMMAND ARG
diff --git a/plugins/sudoers/regress/sudoers/test10.in b/plugins/sudoers/regress/sudoers/test10.in
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test10.in
@@ -0,0 +1 @@
+
diff --git a/plugins/sudoers/regress/sudoers/test10.json.ok b/plugins/sudoers/regress/sudoers/test10.json.ok
new file mode 100644
index 0000000..2c63c08
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test10.json.ok
@@ -0,0 +1,2 @@
+{
+}
diff --git a/plugins/sudoers/regress/sudoers/test10.ldif.ok b/plugins/sudoers/regress/sudoers/test10.ldif.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test10.ldif.ok
diff --git a/plugins/sudoers/regress/sudoers/test10.out.ok b/plugins/sudoers/regress/sudoers/test10.out.ok
new file mode 100644
index 0000000..40c742d
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test10.out.ok
@@ -0,0 +1,2 @@
+Parses OK.
+
diff --git a/plugins/sudoers/regress/sudoers/test10.toke.ok b/plugins/sudoers/regress/sudoers/test10.toke.ok
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test10.toke.ok
@@ -0,0 +1 @@
+
diff --git a/plugins/sudoers/regress/sudoers/test11.in b/plugins/sudoers/regress/sudoers/test11.in
new file mode 100644
index 0000000..5ffba7b
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test11.in
@@ -0,0 +1 @@
+bogus
diff --git a/plugins/sudoers/regress/sudoers/test11.json.ok b/plugins/sudoers/regress/sudoers/test11.json.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test11.json.ok
diff --git a/plugins/sudoers/regress/sudoers/test11.ldif.ok b/plugins/sudoers/regress/sudoers/test11.ldif.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test11.ldif.ok
diff --git a/plugins/sudoers/regress/sudoers/test11.out.ok b/plugins/sudoers/regress/sudoers/test11.out.ok
new file mode 100644
index 0000000..9b2e9d6
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test11.out.ok
@@ -0,0 +1,2 @@
+Parse error in sudoers near line 1.
+
diff --git a/plugins/sudoers/regress/sudoers/test11.toke.ok b/plugins/sudoers/regress/sudoers/test11.toke.ok
new file mode 100644
index 0000000..d57d6c3
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test11.toke.ok
@@ -0,0 +1,2 @@
+WORD(5)
+<*> \ No newline at end of file
diff --git a/plugins/sudoers/regress/sudoers/test12.in b/plugins/sudoers/regress/sudoers/test12.in
new file mode 100644
index 0000000..23bda4a
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test12.in
@@ -0,0 +1 @@
+user ALL = (ALL)
diff --git a/plugins/sudoers/regress/sudoers/test12.json.ok b/plugins/sudoers/regress/sudoers/test12.json.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test12.json.ok
diff --git a/plugins/sudoers/regress/sudoers/test12.ldif.ok b/plugins/sudoers/regress/sudoers/test12.ldif.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test12.ldif.ok
diff --git a/plugins/sudoers/regress/sudoers/test12.out.ok b/plugins/sudoers/regress/sudoers/test12.out.ok
new file mode 100644
index 0000000..9b2e9d6
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test12.out.ok
@@ -0,0 +1,2 @@
+Parse error in sudoers near line 1.
+
diff --git a/plugins/sudoers/regress/sudoers/test12.toke.ok b/plugins/sudoers/regress/sudoers/test12.toke.ok
new file mode 100644
index 0000000..a1995f0
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test12.toke.ok
@@ -0,0 +1,2 @@
+WORD(5) ALL = ( ALL )
+<*> \ No newline at end of file
diff --git a/plugins/sudoers/regress/sudoers/test13.in b/plugins/sudoers/regress/sudoers/test13.in
new file mode 100644
index 0000000..b8002bc
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test13.in
@@ -0,0 +1 @@
+user ALL = (ALL) \ No newline at end of file
diff --git a/plugins/sudoers/regress/sudoers/test13.json.ok b/plugins/sudoers/regress/sudoers/test13.json.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test13.json.ok
diff --git a/plugins/sudoers/regress/sudoers/test13.ldif.ok b/plugins/sudoers/regress/sudoers/test13.ldif.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test13.ldif.ok
diff --git a/plugins/sudoers/regress/sudoers/test13.out.ok b/plugins/sudoers/regress/sudoers/test13.out.ok
new file mode 100644
index 0000000..9b2e9d6
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test13.out.ok
@@ -0,0 +1,2 @@
+Parse error in sudoers near line 1.
+
diff --git a/plugins/sudoers/regress/sudoers/test13.toke.ok b/plugins/sudoers/regress/sudoers/test13.toke.ok
new file mode 100644
index 0000000..e189ffd
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test13.toke.ok
@@ -0,0 +1 @@
+WORD(5) ALL = ( ALL ) <*> \ No newline at end of file
diff --git a/plugins/sudoers/regress/sudoers/test14.in b/plugins/sudoers/regress/sudoers/test14.in
new file mode 100644
index 0000000..05fafda
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test14.in
@@ -0,0 +1,4 @@
+Cmnd_Alias LS = sha224:d06a2617c98d377c250edd470fd5e576327748d82915d6e33b5f8db1 /bin/ls
+Cmnd_Alias SH = sha256:hOtoe/iK6SlGg7w4BfZBBdSsXjUmTJ5+ts51yjh7vkM= /bin/sh
+
+millert ALL = LS, SH, sha512:srzYEQ2aqzm+it3f74opTMkIImZRLxBARVpb0g9RSouJYdLt7DTRMEY4Ry9NyaOiDoUIplpNjqYH0JMYPVdFnw /bin/kill
diff --git a/plugins/sudoers/regress/sudoers/test14.json.ok b/plugins/sudoers/regress/sudoers/test14.json.ok
new file mode 100644
index 0000000..46f8b21
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test14.json.ok
@@ -0,0 +1,38 @@
+{
+ "Command_Aliases": {
+ "LS": [
+ {
+ "command": "/bin/ls",
+ "sha224": "d06a2617c98d377c250edd470fd5e576327748d82915d6e33b5f8db1"
+ }
+ ],
+ "SH": [
+ {
+ "command": "/bin/sh",
+ "sha256": "hOtoe/iK6SlGg7w4BfZBBdSsXjUmTJ5+ts51yjh7vkM="
+ }
+ ]
+ },
+ "User_Specs": [
+ {
+ "User_List": [
+ { "username": "millert" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Commands": [
+ { "cmndalias": "LS" },
+ { "cmndalias": "SH" },
+ {
+ "command": "/bin/kill",
+ "sha512": "srzYEQ2aqzm+it3f74opTMkIImZRLxBARVpb0g9RSouJYdLt7DTRMEY4Ry9NyaOiDoUIplpNjqYH0JMYPVdFnw"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/plugins/sudoers/regress/sudoers/test14.ldif.ok b/plugins/sudoers/regress/sudoers/test14.ldif.ok
new file mode 100644
index 0000000..abb4886
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test14.ldif.ok
@@ -0,0 +1,11 @@
+dn: cn=millert,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: millert
+sudoUser: millert
+sudoHost: ALL
+sudoCommand: sha224:d06a2617c98d377c250edd470fd5e576327748d82915d6e33b5f8db1 /bin/ls
+sudoCommand: sha256:hOtoe/iK6SlGg7w4BfZBBdSsXjUmTJ5+ts51yjh7vkM= /bin/sh
+sudoCommand: sha512:srzYEQ2aqzm+it3f74opTMkIImZRLxBARVpb0g9RSouJYdLt7DTRMEY4Ry9NyaOiDoUIplpNjqYH0JMYPVdFnw /bin/kill
+sudoOrder: 1
+
diff --git a/plugins/sudoers/regress/sudoers/test14.ldif2sudo.ok b/plugins/sudoers/regress/sudoers/test14.ldif2sudo.ok
new file mode 100644
index 0000000..6bc0156
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test14.ldif2sudo.ok
@@ -0,0 +1,5 @@
+# sudoRole millert
+millert ALL = sha224:d06a2617c98d377c250edd470fd5e576327748d82915d6e33b5f8db1\
+ /bin/ls, sha256:hOtoe/iK6SlGg7w4BfZBBdSsXjUmTJ5+ts51yjh7vkM= /bin/sh,\
+ sha512:srzYEQ2aqzm+it3f74opTMkIImZRLxBARVpb0g9RSouJYdLt7DTRMEY4Ry9NyaOiDoUIplpNjqYH0JMYPVdFnw\
+ /bin/kill
diff --git a/plugins/sudoers/regress/sudoers/test14.out.ok b/plugins/sudoers/regress/sudoers/test14.out.ok
new file mode 100644
index 0000000..bfcb661
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test14.out.ok
@@ -0,0 +1,6 @@
+Parses OK.
+
+Cmnd_Alias LS = sha224:d06a2617c98d377c250edd470fd5e576327748d82915d6e33b5f8db1 /bin/ls
+Cmnd_Alias SH = sha256:hOtoe/iK6SlGg7w4BfZBBdSsXjUmTJ5+ts51yjh7vkM= /bin/sh
+
+millert ALL = LS, SH, sha512:srzYEQ2aqzm+it3f74opTMkIImZRLxBARVpb0g9RSouJYdLt7DTRMEY4Ry9NyaOiDoUIplpNjqYH0JMYPVdFnw /bin/kill
diff --git a/plugins/sudoers/regress/sudoers/test14.toke.ok b/plugins/sudoers/regress/sudoers/test14.toke.ok
new file mode 100644
index 0000000..7cb5aea
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test14.toke.ok
@@ -0,0 +1,4 @@
+CMNDALIAS ALIAS = SHA224_TOK : DIGEST COMMAND
+CMNDALIAS ALIAS = SHA256_TOK : DIGEST COMMAND
+
+WORD(5) ALL = ALIAS , ALIAS , SHA512_TOK : DIGEST COMMAND
diff --git a/plugins/sudoers/regress/sudoers/test15.in b/plugins/sudoers/regress/sudoers/test15.in
new file mode 100644
index 0000000..11bcb13
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test15.in
@@ -0,0 +1,2 @@
+# Test parsing of sudoedit rule
+user ALL = sudoedit /etc/motd
diff --git a/plugins/sudoers/regress/sudoers/test15.json.ok b/plugins/sudoers/regress/sudoers/test15.json.ok
new file mode 100644
index 0000000..ff1795a
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test15.json.ok
@@ -0,0 +1,19 @@
+{
+ "User_Specs": [
+ {
+ "User_List": [
+ { "username": "user" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Commands": [
+ { "command": "sudoedit /etc/motd" }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/plugins/sudoers/regress/sudoers/test15.ldif.ok b/plugins/sudoers/regress/sudoers/test15.ldif.ok
new file mode 100644
index 0000000..ac35ba0
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test15.ldif.ok
@@ -0,0 +1,9 @@
+dn: cn=user,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user
+sudoUser: user
+sudoHost: ALL
+sudoCommand: sudoedit /etc/motd
+sudoOrder: 1
+
diff --git a/plugins/sudoers/regress/sudoers/test15.ldif2sudo.ok b/plugins/sudoers/regress/sudoers/test15.ldif2sudo.ok
new file mode 100644
index 0000000..775d59e
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test15.ldif2sudo.ok
@@ -0,0 +1,2 @@
+# sudoRole user
+user ALL = sudoedit /etc/motd
diff --git a/plugins/sudoers/regress/sudoers/test15.out.ok b/plugins/sudoers/regress/sudoers/test15.out.ok
new file mode 100644
index 0000000..fb43c8c
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test15.out.ok
@@ -0,0 +1,3 @@
+Parses OK.
+
+user ALL = sudoedit /etc/motd
diff --git a/plugins/sudoers/regress/sudoers/test15.toke.ok b/plugins/sudoers/regress/sudoers/test15.toke.ok
new file mode 100644
index 0000000..c26de2e
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test15.toke.ok
@@ -0,0 +1,2 @@
+#
+WORD(5) ALL = COMMAND ARG
diff --git a/plugins/sudoers/regress/sudoers/test16.in b/plugins/sudoers/regress/sudoers/test16.in
new file mode 100644
index 0000000..d2a79ea
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test16.in
@@ -0,0 +1,3 @@
+# Test parsing of sudoedit rule in a Cmnd_Alias
+Cmnd_Alias EDIT = sudoedit /etc/motd
+user ALL = EDIT
diff --git a/plugins/sudoers/regress/sudoers/test16.json.ok b/plugins/sudoers/regress/sudoers/test16.json.ok
new file mode 100644
index 0000000..7c42654
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test16.json.ok
@@ -0,0 +1,24 @@
+{
+ "Command_Aliases": {
+ "EDIT": [
+ { "command": "sudoedit /etc/motd" }
+ ]
+ },
+ "User_Specs": [
+ {
+ "User_List": [
+ { "username": "user" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Commands": [
+ { "cmndalias": "EDIT" }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/plugins/sudoers/regress/sudoers/test16.ldif.ok b/plugins/sudoers/regress/sudoers/test16.ldif.ok
new file mode 100644
index 0000000..ac35ba0
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test16.ldif.ok
@@ -0,0 +1,9 @@
+dn: cn=user,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user
+sudoUser: user
+sudoHost: ALL
+sudoCommand: sudoedit /etc/motd
+sudoOrder: 1
+
diff --git a/plugins/sudoers/regress/sudoers/test16.ldif2sudo.ok b/plugins/sudoers/regress/sudoers/test16.ldif2sudo.ok
new file mode 100644
index 0000000..775d59e
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test16.ldif2sudo.ok
@@ -0,0 +1,2 @@
+# sudoRole user
+user ALL = sudoedit /etc/motd
diff --git a/plugins/sudoers/regress/sudoers/test16.out.ok b/plugins/sudoers/regress/sudoers/test16.out.ok
new file mode 100644
index 0000000..f541242
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test16.out.ok
@@ -0,0 +1,5 @@
+Parses OK.
+
+Cmnd_Alias EDIT = sudoedit /etc/motd
+
+user ALL = EDIT
diff --git a/plugins/sudoers/regress/sudoers/test16.toke.ok b/plugins/sudoers/regress/sudoers/test16.toke.ok
new file mode 100644
index 0000000..9b8c41b
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test16.toke.ok
@@ -0,0 +1,3 @@
+#
+CMNDALIAS ALIAS = COMMAND ARG
+WORD(5) ALL = ALIAS
diff --git a/plugins/sudoers/regress/sudoers/test17.in b/plugins/sudoers/regress/sudoers/test17.in
new file mode 100644
index 0000000..37d066c
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test17.in
@@ -0,0 +1,13 @@
+# Test parsing of command_timeout and TIMEOUT syntax
+Defaults command_timeout=2d8h10m59s
+user0 ALL = TIMEOUT=7D4H10M30S /usr/bin/id, /usr/bin/who, TIMEOUT=0 /bin/ls
+user1 ALL = TIMEOUT=7d4h10m30s /usr/bin/id
+user2 ALL = TIMEOUT=4h10m30s /usr/bin/id
+user3 ALL = TIMEOUT=10m30s /usr/bin/id
+user4 ALL = TIMEOUT=14d /usr/bin/id
+user5 ALL = TIMEOUT=5m /usr/bin/id
+user6 ALL = TIMEOUT=30s /usr/bin/id
+user7 ALL = TIMEOUT=45 /usr/bin/id
+user8 ALL = TIMEOUT=7d4h10m30s /usr/bin/id, TIMEOUT=4h10m30s /usr/bin/id, \
+ TIMEOUT=10m30s /usr/bin/id, TIMEOUT=14d /usr/bin/id, \
+ TIMEOUT=5m /usr/bin/id, TIMEOUT=30s /usr/bin/id
diff --git a/plugins/sudoers/regress/sudoers/test17.json.ok b/plugins/sudoers/regress/sudoers/test17.json.ok
new file mode 100644
index 0000000..2f39a37
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test17.json.ok
@@ -0,0 +1,180 @@
+{
+ "Defaults": [
+ {
+ "Options": [
+ { "command_timeout": "2d8h10m59s" }
+ ]
+ }
+ ],
+ "User_Specs": [
+ {
+ "User_List": [
+ { "username": "user0" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "command_timeout": 619830 }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" },
+ { "command": "/usr/bin/who" },
+ { "command": "/bin/ls" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user1" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "command_timeout": 619830 }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user2" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "command_timeout": 15030 }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user3" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "command_timeout": 630 }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user4" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "command_timeout": 1209600 }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user5" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "command_timeout": 300 }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user6" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "command_timeout": 30 }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user7" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "command_timeout": 45 }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user8" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "command_timeout": 619830 }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" },
+ { "command": "/usr/bin/id" },
+ { "command": "/usr/bin/id" },
+ { "command": "/usr/bin/id" },
+ { "command": "/usr/bin/id" },
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/plugins/sudoers/regress/sudoers/test17.ldif.ok b/plugins/sudoers/regress/sudoers/test17.ldif.ok
new file mode 100644
index 0000000..bdc784c
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test17.ldif.ok
@@ -0,0 +1,104 @@
+dn: cn=defaults,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption: command_timeout=2d8h10m59s
+
+dn: cn=user0,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user0
+sudoUser: user0
+sudoHost: ALL
+sudoOption: command_timeout=619830
+sudoCommand: /usr/bin/id
+sudoCommand: /usr/bin/who
+sudoCommand: /bin/ls
+sudoOrder: 1
+
+dn: cn=user1,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user1
+sudoUser: user1
+sudoHost: ALL
+sudoOption: command_timeout=619830
+sudoCommand: /usr/bin/id
+sudoOrder: 2
+
+dn: cn=user2,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user2
+sudoUser: user2
+sudoHost: ALL
+sudoOption: command_timeout=15030
+sudoCommand: /usr/bin/id
+sudoOrder: 3
+
+dn: cn=user3,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user3
+sudoUser: user3
+sudoHost: ALL
+sudoOption: command_timeout=630
+sudoCommand: /usr/bin/id
+sudoOrder: 4
+
+dn: cn=user4,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user4
+sudoUser: user4
+sudoHost: ALL
+sudoOption: command_timeout=1209600
+sudoCommand: /usr/bin/id
+sudoOrder: 5
+
+dn: cn=user5,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user5
+sudoUser: user5
+sudoHost: ALL
+sudoOption: command_timeout=300
+sudoCommand: /usr/bin/id
+sudoOrder: 6
+
+dn: cn=user6,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user6
+sudoUser: user6
+sudoHost: ALL
+sudoOption: command_timeout=30
+sudoCommand: /usr/bin/id
+sudoOrder: 7
+
+dn: cn=user7,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user7
+sudoUser: user7
+sudoHost: ALL
+sudoOption: command_timeout=45
+sudoCommand: /usr/bin/id
+sudoOrder: 8
+
+dn: cn=user8,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user8
+sudoUser: user8
+sudoHost: ALL
+sudoOption: command_timeout=619830
+sudoCommand: /usr/bin/id
+sudoCommand: /usr/bin/id
+sudoCommand: /usr/bin/id
+sudoCommand: /usr/bin/id
+sudoCommand: /usr/bin/id
+sudoCommand: /usr/bin/id
+sudoOrder: 9
+
diff --git a/plugins/sudoers/regress/sudoers/test17.ldif2sudo.ok b/plugins/sudoers/regress/sudoers/test17.ldif2sudo.ok
new file mode 100644
index 0000000..608f52f
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test17.ldif2sudo.ok
@@ -0,0 +1,29 @@
+Defaults command_timeout=2d8h10m59s
+
+# sudoRole user0
+user0 ALL = TIMEOUT=619830 /usr/bin/id, /usr/bin/who, /bin/ls
+
+# sudoRole user1
+user1 ALL = TIMEOUT=619830 /usr/bin/id
+
+# sudoRole user2
+user2 ALL = TIMEOUT=15030 /usr/bin/id
+
+# sudoRole user3
+user3 ALL = TIMEOUT=630 /usr/bin/id
+
+# sudoRole user4
+user4 ALL = TIMEOUT=1209600 /usr/bin/id
+
+# sudoRole user5
+user5 ALL = TIMEOUT=300 /usr/bin/id
+
+# sudoRole user6
+user6 ALL = TIMEOUT=30 /usr/bin/id
+
+# sudoRole user7
+user7 ALL = TIMEOUT=45 /usr/bin/id
+
+# sudoRole user8
+user8 ALL = TIMEOUT=619830 /usr/bin/id, /usr/bin/id, /usr/bin/id, /usr/bin/id,\
+ /usr/bin/id, /usr/bin/id
diff --git a/plugins/sudoers/regress/sudoers/test17.out.ok b/plugins/sudoers/regress/sudoers/test17.out.ok
new file mode 100644
index 0000000..4a2c26d
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test17.out.ok
@@ -0,0 +1,13 @@
+Parses OK.
+
+Defaults command_timeout=2d8h10m59s
+
+user0 ALL = TIMEOUT=619830 /usr/bin/id, /usr/bin/who, /bin/ls
+user1 ALL = TIMEOUT=619830 /usr/bin/id
+user2 ALL = TIMEOUT=15030 /usr/bin/id
+user3 ALL = TIMEOUT=630 /usr/bin/id
+user4 ALL = TIMEOUT=1209600 /usr/bin/id
+user5 ALL = TIMEOUT=300 /usr/bin/id
+user6 ALL = TIMEOUT=30 /usr/bin/id
+user7 ALL = TIMEOUT=45 /usr/bin/id
+user8 ALL = TIMEOUT=619830 /usr/bin/id, TIMEOUT=15030 /usr/bin/id, TIMEOUT=630 /usr/bin/id, TIMEOUT=1209600 /usr/bin/id, TIMEOUT=300 /usr/bin/id, TIMEOUT=30 /usr/bin/id
diff --git a/plugins/sudoers/regress/sudoers/test17.toke.ok b/plugins/sudoers/regress/sudoers/test17.toke.ok
new file mode 100644
index 0000000..17bb5fb
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test17.toke.ok
@@ -0,0 +1,11 @@
+#
+DEFAULTS DEFVAR = WORD(2)
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) COMMAND , COMMAND , CMND_TIMEOUT = WORD(5) COMMAND
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) COMMAND
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) COMMAND
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) COMMAND
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) COMMAND
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) COMMAND
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) COMMAND
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) COMMAND
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) COMMAND , CMND_TIMEOUT = WORD(5) COMMAND , CMND_TIMEOUT = WORD(5) COMMAND , CMND_TIMEOUT = WORD(5) COMMAND , CMND_TIMEOUT = WORD(5) COMMAND , CMND_TIMEOUT = WORD(5) COMMAND
diff --git a/plugins/sudoers/regress/sudoers/test18.in b/plugins/sudoers/regress/sudoers/test18.in
new file mode 100644
index 0000000..8d94ec7
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test18.in
@@ -0,0 +1,8 @@
+# Test command_timeout and TIMEOUT syntax errors
+Defaults command_timeout=2d8h10m59ss
+Defaults:root command_timeout=15f
+user0 ALL = TIMEOUT=7dd4h10m30s /usr/bin/id, /usr/bin/who, TIMEOUT=0 /bin/ls
+user1 ALL = TIMEOUT=7d4h10mm30s /usr/bin/id
+user2 ALL = TIMEOUT=4hg10m30s /usr/bin/id
+user3 ALL = TIMEOUT=10m30ss /usr/bin/id
+user4 ALL = TIMEOUT=14g /usr/bin/id
diff --git a/plugins/sudoers/regress/sudoers/test18.json.ok b/plugins/sudoers/regress/sudoers/test18.json.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test18.json.ok
diff --git a/plugins/sudoers/regress/sudoers/test18.ldif.ok b/plugins/sudoers/regress/sudoers/test18.ldif.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test18.ldif.ok
diff --git a/plugins/sudoers/regress/sudoers/test18.out.ok b/plugins/sudoers/regress/sudoers/test18.out.ok
new file mode 100644
index 0000000..ace1ca6
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test18.out.ok
@@ -0,0 +1,4 @@
+Parse error in sudoers near line 4 (problem with defaults entries).
+
+Defaults command_timeout=2d8h10m59ss
+Defaults:root command_timeout=15f
diff --git a/plugins/sudoers/regress/sudoers/test18.toke.ok b/plugins/sudoers/regress/sudoers/test18.toke.ok
new file mode 100644
index 0000000..05fbaef
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test18.toke.ok
@@ -0,0 +1,10 @@
+#
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS_USER WORD(5) DEFVAR = WORD(2)
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) <*> COMMAND , COMMAND , CMND_TIMEOUT = WORD(5) COMMAND
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) <*> COMMAND
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) <*> COMMAND
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) <*> COMMAND
+WORD(5) ALL = CMND_TIMEOUT = WORD(5) <*> COMMAND
+testsudoers: sudoers:2 value "2d8h10m59ss" is invalid for option "command_timeout"
+testsudoers: sudoers:3 value "15f" is invalid for option "command_timeout"
diff --git a/plugins/sudoers/regress/sudoers/test19.in b/plugins/sudoers/regress/sudoers/test19.in
new file mode 100644
index 0000000..5f637a7
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test19.in
@@ -0,0 +1,12 @@
+# Test parsing of NOTBEFORE and NOTAFTER syntax
+# Local time zone parsing is checked in visudo/test10.sh
+user0 ALL = NOTBEFORE=20170214083000Z NOTAFTER=20170301083000Z /usr/bin/id, /bin/ls
+user1 ALL = NOTBEFORE=201702140830Z /usr/bin/id, NOTAFTER=20170301083000Z /bin/ls
+user2 ALL = NOTBEFORE=201702140830.3Z /usr/bin/id
+user3 ALL = NOTBEFORE=2017021408Z /usr/bin/id
+user4 ALL = NOTBEFORE=2017021408.4Z /usr/bin/id
+user5 ALL = NOTBEFORE=20170214083000.5Z /usr/bin/id
+user6 ALL = NOTBEFORE=20170214083000\,5Z /usr/bin/id
+user7 ALL = NOTBEFORE=20170214033000-0500 /usr/bin/id
+user8 ALL = NOTBEFORE=20170214033000.0-0500 /usr/bin/id
+user9 ALL = NOTBEFORE=20170214033000\,0-0500 /usr/bin/id
diff --git a/plugins/sudoers/regress/sudoers/test19.json.ok b/plugins/sudoers/regress/sudoers/test19.json.ok
new file mode 100644
index 0000000..c9a1bfd
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test19.json.ok
@@ -0,0 +1,187 @@
+{
+ "User_Specs": [
+ {
+ "User_List": [
+ { "username": "user0" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "notbefore": "20170214083000Z" },
+ { "notafter": "20170301083000Z" }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" },
+ { "command": "/bin/ls" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user1" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "notbefore": "20170214083000Z" }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" },
+ { "command": "/bin/ls" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user2" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "notbefore": "20170214083018Z" }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user3" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "notbefore": "20170214080000Z" }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user4" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "notbefore": "20170214082400Z" }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user5" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "notbefore": "20170214083000Z" }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user6" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "notbefore": "20170214083000Z" }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user7" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "notbefore": "20170214083000Z" }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user8" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "notbefore": "20170214083000Z" }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user9" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "notbefore": "20170214083000Z" }
+ ],
+ "Commands": [
+ { "command": "/usr/bin/id" }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/plugins/sudoers/regress/sudoers/test19.ldif.ok b/plugins/sudoers/regress/sudoers/test19.ldif.ok
new file mode 100644
index 0000000..362aa9e
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test19.ldif.ok
@@ -0,0 +1,103 @@
+dn: cn=user0,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user0
+sudoUser: user0
+sudoHost: ALL
+sudoNotBefore: 20170214083000Z
+sudoNotAfter: 20170301083000Z
+sudoCommand: /usr/bin/id
+sudoCommand: /bin/ls
+sudoOrder: 1
+
+dn: cn=user1,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user1
+sudoUser: user1
+sudoHost: ALL
+sudoNotBefore: 20170214083000Z
+sudoCommand: /usr/bin/id
+sudoCommand: /bin/ls
+sudoOrder: 2
+
+dn: cn=user2,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user2
+sudoUser: user2
+sudoHost: ALL
+sudoNotBefore: 20170214083018Z
+sudoCommand: /usr/bin/id
+sudoOrder: 3
+
+dn: cn=user3,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user3
+sudoUser: user3
+sudoHost: ALL
+sudoNotBefore: 20170214080000Z
+sudoCommand: /usr/bin/id
+sudoOrder: 4
+
+dn: cn=user4,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user4
+sudoUser: user4
+sudoHost: ALL
+sudoNotBefore: 20170214082400Z
+sudoCommand: /usr/bin/id
+sudoOrder: 5
+
+dn: cn=user5,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user5
+sudoUser: user5
+sudoHost: ALL
+sudoNotBefore: 20170214083000Z
+sudoCommand: /usr/bin/id
+sudoOrder: 6
+
+dn: cn=user6,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user6
+sudoUser: user6
+sudoHost: ALL
+sudoNotBefore: 20170214083000Z
+sudoCommand: /usr/bin/id
+sudoOrder: 7
+
+dn: cn=user7,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user7
+sudoUser: user7
+sudoHost: ALL
+sudoNotBefore: 20170214083000Z
+sudoCommand: /usr/bin/id
+sudoOrder: 8
+
+dn: cn=user8,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user8
+sudoUser: user8
+sudoHost: ALL
+sudoNotBefore: 20170214083000Z
+sudoCommand: /usr/bin/id
+sudoOrder: 9
+
+dn: cn=user9,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user9
+sudoUser: user9
+sudoHost: ALL
+sudoNotBefore: 20170214083000Z
+sudoCommand: /usr/bin/id
+sudoOrder: 10
+
diff --git a/plugins/sudoers/regress/sudoers/test19.ldif2sudo.ok b/plugins/sudoers/regress/sudoers/test19.ldif2sudo.ok
new file mode 100644
index 0000000..1aef1bc
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test19.ldif2sudo.ok
@@ -0,0 +1,30 @@
+# sudoRole user0
+user0 ALL = NOTBEFORE=20170214083000Z NOTAFTER=20170301083000Z /usr/bin/id,\
+ /bin/ls
+
+# sudoRole user1
+user1 ALL = NOTBEFORE=20170214083000Z /usr/bin/id, /bin/ls
+
+# sudoRole user2
+user2 ALL = NOTBEFORE=20170214083018Z /usr/bin/id
+
+# sudoRole user3
+user3 ALL = NOTBEFORE=20170214080000Z /usr/bin/id
+
+# sudoRole user4
+user4 ALL = NOTBEFORE=20170214082400Z /usr/bin/id
+
+# sudoRole user5
+user5 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
+
+# sudoRole user6
+user6 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
+
+# sudoRole user7
+user7 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
+
+# sudoRole user8
+user8 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
+
+# sudoRole user9
+user9 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
diff --git a/plugins/sudoers/regress/sudoers/test19.out.ok b/plugins/sudoers/regress/sudoers/test19.out.ok
new file mode 100644
index 0000000..8d7974e
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test19.out.ok
@@ -0,0 +1,12 @@
+Parses OK.
+
+user0 ALL = NOTBEFORE=20170214083000Z NOTAFTER=20170301083000Z /usr/bin/id, /bin/ls
+user1 ALL = NOTBEFORE=20170214083000Z /usr/bin/id, NOTAFTER=20170301083000Z /bin/ls
+user2 ALL = NOTBEFORE=20170214083018Z /usr/bin/id
+user3 ALL = NOTBEFORE=20170214080000Z /usr/bin/id
+user4 ALL = NOTBEFORE=20170214082400Z /usr/bin/id
+user5 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
+user6 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
+user7 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
+user8 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
+user9 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
diff --git a/plugins/sudoers/regress/sudoers/test19.toke.ok b/plugins/sudoers/regress/sudoers/test19.toke.ok
new file mode 100644
index 0000000..45c5d27
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test19.toke.ok
@@ -0,0 +1,12 @@
+#
+#
+WORD(5) ALL = NOTBEFORE = WORD(5) NOTAFTER = WORD(5) COMMAND , COMMAND
+WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND , NOTAFTER = WORD(5) COMMAND
+WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
+WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
+WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
+WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
+WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
+WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
+WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
+WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
diff --git a/plugins/sudoers/regress/sudoers/test2.in b/plugins/sudoers/regress/sudoers/test2.in
new file mode 100644
index 0000000..cfdfaa3
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test2.in
@@ -0,0 +1,60 @@
+# Check quoted user name in User_Alias
+User_Alias UA1 = "foo"
+User_Alias UA2 = "foo.bar"
+User_Alias UA3 = "foo\""
+User_Alias UA4 = "foo:bar"
+User_Alias UA5 = "foo:bar\""
+
+# Check quoted group name in User_Alias
+User_Alias UA6 = "%baz"
+User_Alias UA7 = "%baz.biz"
+
+# Check quoted non-Unix group name in User_Alias
+User_Alias UA8 = "%:C/non UNIX 0 c"
+User_Alias UA9 = "%:C/non\'UNIX\'1 c"
+User_Alias UA10 = "%:C/non\"UNIX\"0 c"
+User_Alias UA11 = "%:C/non_UNIX_0 c"
+User_Alias UA12 = "%:C/non\'UNIX_3 c"
+
+# Check quoted user name in Runas_Alias
+Runas_Alias RA1 = "foo"
+Runas_Alias RA2 = "foo\""
+Runas_Alias RA3 = "foo:bar"
+Runas_Alias RA4 = "foo:bar\""
+
+# Check quoted host name in Defaults
+Defaults@"somehost" set_home
+Defaults@"quoted\"" set_home
+
+# Check quoted user name in Defaults
+Defaults:"you" set_home
+Defaults:"us\"" set_home
+Defaults:"%them" set_home
+Defaults:"%: non UNIX 0 c" set_home
+Defaults:"+net" set_home
+
+# Check quoted runas name in Defaults
+Defaults>"someone" set_home
+Defaults>"some one" set_home
+
+# Check quoted command in Defaults
+# XXX - not currently supported
+#Defaults!"/bin/ls -l" set_home
+#Defaults!"/bin/ls -l \"foo\"" set_home
+
+# Check quoted user, runas and host name in Cmnd_Spec
+"foo" "hosta" = ("root") ALL
+"foo.bar" "hostb" = ("root") ALL
+"foo\"" "hostc" = ("root") ALL
+"foo:bar" "hostd" = ("root") ALL
+"foo:bar\"" "hoste" = ("root") ALL
+
+# Check quoted group/netgroup name in Cmnd_Spec
+"%baz" "hosta" = ("root") ALL
+"%baz.biz" "hostb" = ("root") ALL
+"%:C/non UNIX 0 c" "hostc" = ("root") ALL
+"%:C/non\'UNIX\'1 c" "hostd" = ("root") ALL
+"%:C/non\"UNIX\"0 c" "hoste" = ("root") ALL
+"%:C/non_UNIX_0 c" "hostf" = ("root") ALL
+"%:C/non\'UNIX_3 c" "hostg" = ("root") ALL
+"+netgr" "hosth" = ("root") ALL
diff --git a/plugins/sudoers/regress/sudoers/test2.json.ok b/plugins/sudoers/regress/sudoers/test2.json.ok
new file mode 100644
index 0000000..8e6656e
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test2.json.ok
@@ -0,0 +1,403 @@
+{
+ "Defaults": [
+ {
+ "Binding": [
+ { "hostname": "somehost" }
+ ],
+ "Options": [
+ { "set_home": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "hostname": "quoted\"" }
+ ],
+ "Options": [
+ { "set_home": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "username": "you" }
+ ],
+ "Options": [
+ { "set_home": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "username": "us\"" }
+ ],
+ "Options": [
+ { "set_home": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "username": "%them" }
+ ],
+ "Options": [
+ { "set_home": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "username": "%: non UNIX 0 c" }
+ ],
+ "Options": [
+ { "set_home": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "username": "+net" }
+ ],
+ "Options": [
+ { "set_home": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "username": "someone" }
+ ],
+ "Options": [
+ { "set_home": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "username": "some one" }
+ ],
+ "Options": [
+ { "set_home": true }
+ ]
+ }
+ ],
+ "User_Aliases": {
+ "UA1": [
+ { "username": "foo" }
+ ],
+ "UA10": [
+ { "nonunixgroup": "C/non\"UNIX\"0 c" }
+ ],
+ "UA11": [
+ { "nonunixgroup": "C/non_UNIX_0 c" }
+ ],
+ "UA12": [
+ { "nonunixgroup": "C/non\\'UNIX_3 c" }
+ ],
+ "UA2": [
+ { "username": "foo.bar" }
+ ],
+ "UA3": [
+ { "username": "foo\"" }
+ ],
+ "UA4": [
+ { "username": "foo:bar" }
+ ],
+ "UA5": [
+ { "username": "foo:bar\"" }
+ ],
+ "UA6": [
+ { "usergroup": "baz" }
+ ],
+ "UA7": [
+ { "usergroup": "baz.biz" }
+ ],
+ "UA8": [
+ { "nonunixgroup": "C/non UNIX 0 c" }
+ ],
+ "UA9": [
+ { "nonunixgroup": "C/non\\'UNIX\\'1 c" }
+ ]
+ },
+ "Runas_Aliases": {
+ "RA1": [
+ { "username": "foo" }
+ ],
+ "RA2": [
+ { "username": "foo\"" }
+ ],
+ "RA3": [
+ { "username": "foo:bar" }
+ ],
+ "RA4": [
+ { "username": "foo:bar\"" }
+ ]
+ },
+ "User_Specs": [
+ {
+ "User_List": [
+ { "username": "foo" }
+ ],
+ "Host_List": [
+ { "hostname": "hosta" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "root" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "foo.bar" }
+ ],
+ "Host_List": [
+ { "hostname": "hostb" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "root" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "foo\"" }
+ ],
+ "Host_List": [
+ { "hostname": "hostc" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "root" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "foo:bar" }
+ ],
+ "Host_List": [
+ { "hostname": "hostd" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "root" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "foo:bar\"" }
+ ],
+ "Host_List": [
+ { "hostname": "hoste" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "root" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "usergroup": "baz" }
+ ],
+ "Host_List": [
+ { "hostname": "hosta" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "root" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "usergroup": "baz.biz" }
+ ],
+ "Host_List": [
+ { "hostname": "hostb" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "root" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "nonunixgroup": "C/non UNIX 0 c" }
+ ],
+ "Host_List": [
+ { "hostname": "hostc" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "root" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "nonunixgroup": "C/non\\'UNIX\\'1 c" }
+ ],
+ "Host_List": [
+ { "hostname": "hostd" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "root" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "nonunixgroup": "C/non\"UNIX\"0 c" }
+ ],
+ "Host_List": [
+ { "hostname": "hoste" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "root" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "nonunixgroup": "C/non_UNIX_0 c" }
+ ],
+ "Host_List": [
+ { "hostname": "hostf" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "root" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "nonunixgroup": "C/non\\'UNIX_3 c" }
+ ],
+ "Host_List": [
+ { "hostname": "hostg" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "root" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "netgroup": "netgr" }
+ ],
+ "Host_List": [
+ { "hostname": "hosth" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "root" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/plugins/sudoers/regress/sudoers/test2.ldif.ok b/plugins/sudoers/regress/sudoers/test2.ldif.ok
new file mode 100644
index 0000000..a9e7df9
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test2.ldif.ok
@@ -0,0 +1,157 @@
+# Unable to translate stdin:26
+# Defaults@somehost set_home
+
+# Unable to translate stdin:27
+# Defaults@quoted\" set_home
+
+# Unable to translate stdin:30
+# Defaults:you set_home
+
+# Unable to translate stdin:31
+# Defaults:us\" set_home
+
+# Unable to translate stdin:32
+# Defaults:%them set_home
+
+# Unable to translate stdin:33
+# Defaults:"%: non UNIX 0 c" set_home
+
+# Unable to translate stdin:34
+# Defaults:+net set_home
+
+# Unable to translate stdin:37
+# Defaults>someone set_home
+
+# Unable to translate stdin:38
+# Defaults>"some one" set_home
+
+dn: cn=foo,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: foo
+sudoUser: foo
+sudoHost: hosta
+sudoRunAsUser: root
+sudoCommand: ALL
+sudoOrder: 1
+
+dn: cn=foo.bar,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: foo.bar
+sudoUser: foo.bar
+sudoHost: hostb
+sudoRunAsUser: root
+sudoCommand: ALL
+sudoOrder: 2
+
+dn: cn=foo\",ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: foo\"
+sudoUser: foo"
+sudoHost: hostc
+sudoRunAsUser: root
+sudoCommand: ALL
+sudoOrder: 3
+
+dn: cn=foo:bar,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: foo:bar
+sudoUser: foo:bar
+sudoHost: hostd
+sudoRunAsUser: root
+sudoCommand: ALL
+sudoOrder: 4
+
+dn: cn=foo:bar\",ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: foo:bar\"
+sudoUser: foo:bar"
+sudoHost: hoste
+sudoRunAsUser: root
+sudoCommand: ALL
+sudoOrder: 5
+
+dn: cn=%baz,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %baz
+sudoUser: %baz
+sudoHost: hosta
+sudoRunAsUser: root
+sudoCommand: ALL
+sudoOrder: 6
+
+dn: cn=%baz.biz,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %baz.biz
+sudoUser: %baz.biz
+sudoHost: hostb
+sudoRunAsUser: root
+sudoCommand: ALL
+sudoOrder: 7
+
+dn: cn=%:C/non UNIX 0 c,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %:C/non UNIX 0 c
+sudoUser: %:C/non UNIX 0 c
+sudoHost: hostc
+sudoRunAsUser: root
+sudoCommand: ALL
+sudoOrder: 8
+
+dn: cn=%:C/non\\'UNIX\\'1 c,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %:C/non\\'UNIX\\'1 c
+sudoUser: %:C/non\'UNIX\'1 c
+sudoHost: hostd
+sudoRunAsUser: root
+sudoCommand: ALL
+sudoOrder: 9
+
+dn: cn=%:C/non\"UNIX\"0 c,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %:C/non\"UNIX\"0 c
+sudoUser: %:C/non"UNIX"0 c
+sudoHost: hoste
+sudoRunAsUser: root
+sudoCommand: ALL
+sudoOrder: 10
+
+dn: cn=%:C/non_UNIX_0 c,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %:C/non_UNIX_0 c
+sudoUser: %:C/non_UNIX_0 c
+sudoHost: hostf
+sudoRunAsUser: root
+sudoCommand: ALL
+sudoOrder: 11
+
+dn: cn=%:C/non\\'UNIX_3 c,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %:C/non\\'UNIX_3 c
+sudoUser: %:C/non\'UNIX_3 c
+sudoHost: hostg
+sudoRunAsUser: root
+sudoCommand: ALL
+sudoOrder: 12
+
+dn: cn=\+netgr,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: \+netgr
+sudoUser: +netgr
+sudoHost: hosth
+sudoRunAsUser: root
+sudoCommand: ALL
+sudoOrder: 13
+
diff --git a/plugins/sudoers/regress/sudoers/test2.ldif2sudo.ok b/plugins/sudoers/regress/sudoers/test2.ldif2sudo.ok
new file mode 100644
index 0000000..7039523
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test2.ldif2sudo.ok
@@ -0,0 +1,38 @@
+# sudoRole foo
+foo hosta = (root) ALL
+
+# sudoRole foo.bar
+foo.bar hostb = (root) ALL
+
+# sudoRole foo"
+foo\" hostc = (root) ALL
+
+# sudoRole foo:bar
+foo\:bar hostd = (root) ALL
+
+# sudoRole foo:bar"
+foo\:bar\" hoste = (root) ALL
+
+# sudoRole %baz
+%baz hosta = (root) ALL
+
+# sudoRole %baz.biz
+%baz.biz hostb = (root) ALL
+
+# sudoRole %:C/non UNIX 0 c
+"%:C/non UNIX 0 c" hostc = (root) ALL
+
+# sudoRole %:C/non\'UNIX\'1 c
+"%:C/non\'UNIX\'1 c" hostd = (root) ALL
+
+# sudoRole %:C/non"UNIX"0 c
+"%:C/non\"UNIX\"0 c" hoste = (root) ALL
+
+# sudoRole %:C/non_UNIX_0 c
+"%:C/non_UNIX_0 c" hostf = (root) ALL
+
+# sudoRole %:C/non\'UNIX_3 c
+"%:C/non\'UNIX_3 c" hostg = (root) ALL
+
+# sudoRole +netgr
++netgr hosth = (root) ALL
diff --git a/plugins/sudoers/regress/sudoers/test2.out.ok b/plugins/sudoers/regress/sudoers/test2.out.ok
new file mode 100644
index 0000000..be5e8f3
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test2.out.ok
@@ -0,0 +1,42 @@
+Parses OK.
+
+Defaults@somehost set_home
+Defaults@quoted\" set_home
+Defaults:you set_home
+Defaults:us\" set_home
+Defaults:%them set_home
+Defaults:"%: non UNIX 0 c" set_home
+Defaults:+net set_home
+Defaults>someone set_home
+Defaults>"some one" set_home
+
+Runas_Alias RA1 = foo
+Runas_Alias RA2 = foo\"
+Runas_Alias RA3 = foo\:bar
+Runas_Alias RA4 = foo\:bar\"
+User_Alias UA1 = foo
+User_Alias UA10 = "%:C/non\"UNIX\"0 c"
+User_Alias UA11 = "%:C/non_UNIX_0 c"
+User_Alias UA12 = "%:C/non\'UNIX_3 c"
+User_Alias UA2 = foo.bar
+User_Alias UA3 = foo\"
+User_Alias UA4 = foo\:bar
+User_Alias UA5 = foo\:bar\"
+User_Alias UA6 = %baz
+User_Alias UA7 = %baz.biz
+User_Alias UA8 = "%:C/non UNIX 0 c"
+User_Alias UA9 = "%:C/non\'UNIX\'1 c"
+
+foo hosta = (root) ALL
+foo.bar hostb = (root) ALL
+foo\" hostc = (root) ALL
+foo\:bar hostd = (root) ALL
+foo\:bar\" hoste = (root) ALL
+%baz hosta = (root) ALL
+%baz.biz hostb = (root) ALL
+"%:C/non UNIX 0 c" hostc = (root) ALL
+"%:C/non\'UNIX\'1 c" hostd = (root) ALL
+"%:C/non\"UNIX\"0 c" hoste = (root) ALL
+"%:C/non_UNIX_0 c" hostf = (root) ALL
+"%:C/non\'UNIX_3 c" hostg = (root) ALL
++netgr hosth = (root) ALL
diff --git a/plugins/sudoers/regress/sudoers/test2.toke.ok b/plugins/sudoers/regress/sudoers/test2.toke.ok
new file mode 100644
index 0000000..fcd7b73
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test2.toke.ok
@@ -0,0 +1,60 @@
+#
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR WORD(4)
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR WORD(4)
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR WORD(4)
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR WORD(4)
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR WORD(4)
+
+#
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR USERGROUP
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR USERGROUP
+
+#
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR USERGROUP
+USERALIAS ALIAS = BEGINSTR STRBODY BACKSLASH STRBODY BACKSLASH STRBODY ENDSTR USERGROUP
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR USERGROUP
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR USERGROUP
+USERALIAS ALIAS = BEGINSTR STRBODY BACKSLASH STRBODY ENDSTR USERGROUP
+
+#
+RUNASALIAS ALIAS = BEGINSTR STRBODY ENDSTR WORD(4)
+RUNASALIAS ALIAS = BEGINSTR STRBODY ENDSTR WORD(4)
+RUNASALIAS ALIAS = BEGINSTR STRBODY ENDSTR WORD(4)
+RUNASALIAS ALIAS = BEGINSTR STRBODY ENDSTR WORD(4)
+
+#
+DEFAULTS_HOST BEGINSTR STRBODY ENDSTR WORD(4) DEFVAR
+DEFAULTS_HOST BEGINSTR STRBODY ENDSTR WORD(4) DEFVAR
+
+#
+DEFAULTS_USER BEGINSTR STRBODY ENDSTR WORD(4) DEFVAR
+DEFAULTS_USER BEGINSTR STRBODY ENDSTR WORD(4) DEFVAR
+DEFAULTS_USER BEGINSTR STRBODY ENDSTR WORD(4) DEFVAR
+DEFAULTS_USER BEGINSTR STRBODY ENDSTR WORD(4) DEFVAR
+DEFAULTS_USER BEGINSTR STRBODY ENDSTR WORD(4) DEFVAR
+
+#
+DEFAULTS_RUNAS BEGINSTR STRBODY ENDSTR WORD(4) DEFVAR
+DEFAULTS_RUNAS BEGINSTR STRBODY ENDSTR WORD(4) DEFVAR
+
+#
+#
+#
+#
+
+#
+BEGINSTR STRBODY ENDSTR WORD(4) BEGINSTR STRBODY ENDSTR WORD(4) = ( BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
+BEGINSTR STRBODY ENDSTR WORD(4) BEGINSTR STRBODY ENDSTR WORD(4) = ( BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
+BEGINSTR STRBODY ENDSTR WORD(4) BEGINSTR STRBODY ENDSTR WORD(4) = ( BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
+BEGINSTR STRBODY ENDSTR WORD(4) BEGINSTR STRBODY ENDSTR WORD(4) = ( BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
+BEGINSTR STRBODY ENDSTR WORD(4) BEGINSTR STRBODY ENDSTR WORD(4) = ( BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
+
+#
+BEGINSTR STRBODY ENDSTR USERGROUP BEGINSTR STRBODY ENDSTR WORD(4) = ( BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
+BEGINSTR STRBODY ENDSTR USERGROUP BEGINSTR STRBODY ENDSTR WORD(4) = ( BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
+BEGINSTR STRBODY ENDSTR USERGROUP BEGINSTR STRBODY ENDSTR WORD(4) = ( BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
+BEGINSTR STRBODY BACKSLASH STRBODY BACKSLASH STRBODY ENDSTR USERGROUP BEGINSTR STRBODY ENDSTR WORD(4) = ( BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
+BEGINSTR STRBODY ENDSTR USERGROUP BEGINSTR STRBODY ENDSTR WORD(4) = ( BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
+BEGINSTR STRBODY ENDSTR USERGROUP BEGINSTR STRBODY ENDSTR WORD(4) = ( BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
+BEGINSTR STRBODY BACKSLASH STRBODY ENDSTR USERGROUP BEGINSTR STRBODY ENDSTR WORD(4) = ( BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
+BEGINSTR STRBODY ENDSTR NETGROUP BEGINSTR STRBODY ENDSTR WORD(4) = ( BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
diff --git a/plugins/sudoers/regress/sudoers/test20.in b/plugins/sudoers/regress/sudoers/test20.in
new file mode 100644
index 0000000..c24f88a
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test20.in
@@ -0,0 +1,26 @@
+# Test parsing of tuples
+Defaults lecture
+Defaults !lecture
+Defaults lecture=never
+Defaults lecture=once
+Defaults lecture=always
+
+Defaults listpw
+Defaults !listpw
+Defaults listpw=never
+Defaults listpw=any
+Defaults listpw=all
+Defaults listpw=always
+
+Defaults verifypw
+Defaults !verifypw
+Defaults verifypw=never
+Defaults verifypw=any
+Defaults verifypw=all
+Defaults verifypw=always
+
+Defaults fdexec
+Defaults !fdexec
+Defaults fdexec=never
+Defaults fdexec=digest_only
+Defaults fdexec=always
diff --git a/plugins/sudoers/regress/sudoers/test20.json.ok b/plugins/sudoers/regress/sudoers/test20.json.ok
new file mode 100644
index 0000000..f2f1d55
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test20.json.ok
@@ -0,0 +1,114 @@
+{
+ "Defaults": [
+ {
+ "Options": [
+ { "lecture": true }
+ ]
+ },
+ {
+ "Options": [
+ { "lecture": false }
+ ]
+ },
+ {
+ "Options": [
+ { "lecture": "never" }
+ ]
+ },
+ {
+ "Options": [
+ { "lecture": "once" }
+ ]
+ },
+ {
+ "Options": [
+ { "lecture": "always" }
+ ]
+ },
+ {
+ "Options": [
+ { "listpw": true }
+ ]
+ },
+ {
+ "Options": [
+ { "listpw": false }
+ ]
+ },
+ {
+ "Options": [
+ { "listpw": "never" }
+ ]
+ },
+ {
+ "Options": [
+ { "listpw": "any" }
+ ]
+ },
+ {
+ "Options": [
+ { "listpw": "all" }
+ ]
+ },
+ {
+ "Options": [
+ { "listpw": "always" }
+ ]
+ },
+ {
+ "Options": [
+ { "verifypw": true }
+ ]
+ },
+ {
+ "Options": [
+ { "verifypw": false }
+ ]
+ },
+ {
+ "Options": [
+ { "verifypw": "never" }
+ ]
+ },
+ {
+ "Options": [
+ { "verifypw": "any" }
+ ]
+ },
+ {
+ "Options": [
+ { "verifypw": "all" }
+ ]
+ },
+ {
+ "Options": [
+ { "verifypw": "always" }
+ ]
+ },
+ {
+ "Options": [
+ { "fdexec": true }
+ ]
+ },
+ {
+ "Options": [
+ { "fdexec": false }
+ ]
+ },
+ {
+ "Options": [
+ { "fdexec": "never" }
+ ]
+ },
+ {
+ "Options": [
+ { "fdexec": "digest_only" }
+ ]
+ },
+ {
+ "Options": [
+ { "fdexec": "always" }
+ ]
+ }
+ ]
+}
diff --git a/plugins/sudoers/regress/sudoers/test20.ldif.ok b/plugins/sudoers/regress/sudoers/test20.ldif.ok
new file mode 100644
index 0000000..de01cde
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test20.ldif.ok
@@ -0,0 +1,28 @@
+dn: cn=defaults,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption: lecture
+sudoOption: !lecture
+sudoOption: lecture=never
+sudoOption: lecture=once
+sudoOption: lecture=always
+sudoOption: listpw
+sudoOption: !listpw
+sudoOption: listpw=never
+sudoOption: listpw=any
+sudoOption: listpw=all
+sudoOption: listpw=always
+sudoOption: verifypw
+sudoOption: !verifypw
+sudoOption: verifypw=never
+sudoOption: verifypw=any
+sudoOption: verifypw=all
+sudoOption: verifypw=always
+sudoOption: fdexec
+sudoOption: !fdexec
+sudoOption: fdexec=never
+sudoOption: fdexec=digest_only
+sudoOption: fdexec=always
+
diff --git a/plugins/sudoers/regress/sudoers/test20.ldif2sudo.ok b/plugins/sudoers/regress/sudoers/test20.ldif2sudo.ok
new file mode 100644
index 0000000..e1c743c
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test20.ldif2sudo.ok
@@ -0,0 +1,22 @@
+Defaults lecture
+Defaults !lecture
+Defaults lecture=never
+Defaults lecture=once
+Defaults lecture=always
+Defaults listpw
+Defaults !listpw
+Defaults listpw=never
+Defaults listpw=any
+Defaults listpw=all
+Defaults listpw=always
+Defaults verifypw
+Defaults !verifypw
+Defaults verifypw=never
+Defaults verifypw=any
+Defaults verifypw=all
+Defaults verifypw=always
+Defaults fdexec
+Defaults !fdexec
+Defaults fdexec=never
+Defaults fdexec=digest_only
+Defaults fdexec=always
diff --git a/plugins/sudoers/regress/sudoers/test20.out.ok b/plugins/sudoers/regress/sudoers/test20.out.ok
new file mode 100644
index 0000000..882af0d
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test20.out.ok
@@ -0,0 +1,24 @@
+Parses OK.
+
+Defaults lecture
+Defaults !lecture
+Defaults lecture=never
+Defaults lecture=once
+Defaults lecture=always
+Defaults listpw
+Defaults !listpw
+Defaults listpw=never
+Defaults listpw=any
+Defaults listpw=all
+Defaults listpw=always
+Defaults verifypw
+Defaults !verifypw
+Defaults verifypw=never
+Defaults verifypw=any
+Defaults verifypw=all
+Defaults verifypw=always
+Defaults fdexec
+Defaults !fdexec
+Defaults fdexec=never
+Defaults fdexec=digest_only
+Defaults fdexec=always
diff --git a/plugins/sudoers/regress/sudoers/test20.toke.ok b/plugins/sudoers/regress/sudoers/test20.toke.ok
new file mode 100644
index 0000000..1847149
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test20.toke.ok
@@ -0,0 +1,26 @@
+#
+DEFAULTS DEFVAR
+DEFAULTS !DEFVAR
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+
+DEFAULTS DEFVAR
+DEFAULTS !DEFVAR
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+
+DEFAULTS DEFVAR
+DEFAULTS !DEFVAR
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+
+DEFAULTS DEFVAR
+DEFAULTS !DEFVAR
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
diff --git a/plugins/sudoers/regress/sudoers/test21.in b/plugins/sudoers/regress/sudoers/test21.in
new file mode 100644
index 0000000..65416cf
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test21.in
@@ -0,0 +1,36 @@
+# Test parsing of syslog settings
+Defaults syslog
+Defaults !syslog
+Defaults syslog=auth
+Defaults syslog=daemon
+Defaults syslog=user
+Defaults syslog=local0
+Defaults syslog=local1
+Defaults syslog=local2
+Defaults syslog=local3
+Defaults syslog=local4
+Defaults syslog=local5
+Defaults syslog=local6
+Defaults syslog=local7
+
+Defaults !syslog_goodpri
+Defaults syslog_goodpri=alert
+Defaults syslog_goodpri=crit
+Defaults syslog_goodpri=debug
+Defaults syslog_goodpri=emerg
+Defaults syslog_goodpri=err
+Defaults syslog_goodpri=info
+Defaults syslog_goodpri=notice
+Defaults syslog_goodpri=warning
+Defaults syslog_goodpri=none
+
+Defaults !syslog_badpri
+Defaults syslog_badpri=alert
+Defaults syslog_badpri=crit
+Defaults syslog_badpri=debug
+Defaults syslog_badpri=emerg
+Defaults syslog_badpri=err
+Defaults syslog_badpri=info
+Defaults syslog_badpri=notice
+Defaults syslog_badpri=warning
+Defaults syslog_badpri=none
diff --git a/plugins/sudoers/regress/sudoers/test21.json.ok b/plugins/sudoers/regress/sudoers/test21.json.ok
new file mode 100644
index 0000000..7896965
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test21.json.ok
@@ -0,0 +1,169 @@
+{
+ "Defaults": [
+ {
+ "Options": [
+ { "syslog": true }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog": false }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog": "auth" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog": "daemon" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog": "user" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog": "local0" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog": "local1" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog": "local2" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog": "local3" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog": "local4" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog": "local5" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog": "local6" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog": "local7" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_goodpri": false }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_goodpri": "alert" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_goodpri": "crit" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_goodpri": "debug" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_goodpri": "emerg" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_goodpri": "err" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_goodpri": "info" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_goodpri": "notice" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_goodpri": "warning" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_goodpri": "none" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_badpri": false }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_badpri": "alert" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_badpri": "crit" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_badpri": "debug" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_badpri": "emerg" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_badpri": "err" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_badpri": "info" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_badpri": "notice" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_badpri": "warning" }
+ ]
+ },
+ {
+ "Options": [
+ { "syslog_badpri": "none" }
+ ]
+ }
+ ]
+}
diff --git a/plugins/sudoers/regress/sudoers/test21.ldif.ok b/plugins/sudoers/regress/sudoers/test21.ldif.ok
new file mode 100644
index 0000000..b3bede8
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test21.ldif.ok
@@ -0,0 +1,39 @@
+dn: cn=defaults,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption: syslog
+sudoOption: !syslog
+sudoOption: syslog=auth
+sudoOption: syslog=daemon
+sudoOption: syslog=user
+sudoOption: syslog=local0
+sudoOption: syslog=local1
+sudoOption: syslog=local2
+sudoOption: syslog=local3
+sudoOption: syslog=local4
+sudoOption: syslog=local5
+sudoOption: syslog=local6
+sudoOption: syslog=local7
+sudoOption: !syslog_goodpri
+sudoOption: syslog_goodpri=alert
+sudoOption: syslog_goodpri=crit
+sudoOption: syslog_goodpri=debug
+sudoOption: syslog_goodpri=emerg
+sudoOption: syslog_goodpri=err
+sudoOption: syslog_goodpri=info
+sudoOption: syslog_goodpri=notice
+sudoOption: syslog_goodpri=warning
+sudoOption: syslog_goodpri=none
+sudoOption: !syslog_badpri
+sudoOption: syslog_badpri=alert
+sudoOption: syslog_badpri=crit
+sudoOption: syslog_badpri=debug
+sudoOption: syslog_badpri=emerg
+sudoOption: syslog_badpri=err
+sudoOption: syslog_badpri=info
+sudoOption: syslog_badpri=notice
+sudoOption: syslog_badpri=warning
+sudoOption: syslog_badpri=none
+
diff --git a/plugins/sudoers/regress/sudoers/test21.ldif2sudo.ok b/plugins/sudoers/regress/sudoers/test21.ldif2sudo.ok
new file mode 100644
index 0000000..56e09ff
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test21.ldif2sudo.ok
@@ -0,0 +1,33 @@
+Defaults syslog
+Defaults !syslog
+Defaults syslog=auth
+Defaults syslog=daemon
+Defaults syslog=user
+Defaults syslog=local0
+Defaults syslog=local1
+Defaults syslog=local2
+Defaults syslog=local3
+Defaults syslog=local4
+Defaults syslog=local5
+Defaults syslog=local6
+Defaults syslog=local7
+Defaults !syslog_goodpri
+Defaults syslog_goodpri=alert
+Defaults syslog_goodpri=crit
+Defaults syslog_goodpri=debug
+Defaults syslog_goodpri=emerg
+Defaults syslog_goodpri=err
+Defaults syslog_goodpri=info
+Defaults syslog_goodpri=notice
+Defaults syslog_goodpri=warning
+Defaults syslog_goodpri=none
+Defaults !syslog_badpri
+Defaults syslog_badpri=alert
+Defaults syslog_badpri=crit
+Defaults syslog_badpri=debug
+Defaults syslog_badpri=emerg
+Defaults syslog_badpri=err
+Defaults syslog_badpri=info
+Defaults syslog_badpri=notice
+Defaults syslog_badpri=warning
+Defaults syslog_badpri=none
diff --git a/plugins/sudoers/regress/sudoers/test21.out.ok b/plugins/sudoers/regress/sudoers/test21.out.ok
new file mode 100644
index 0000000..630fa6b
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test21.out.ok
@@ -0,0 +1,35 @@
+Parses OK.
+
+Defaults syslog
+Defaults !syslog
+Defaults syslog=auth
+Defaults syslog=daemon
+Defaults syslog=user
+Defaults syslog=local0
+Defaults syslog=local1
+Defaults syslog=local2
+Defaults syslog=local3
+Defaults syslog=local4
+Defaults syslog=local5
+Defaults syslog=local6
+Defaults syslog=local7
+Defaults !syslog_goodpri
+Defaults syslog_goodpri=alert
+Defaults syslog_goodpri=crit
+Defaults syslog_goodpri=debug
+Defaults syslog_goodpri=emerg
+Defaults syslog_goodpri=err
+Defaults syslog_goodpri=info
+Defaults syslog_goodpri=notice
+Defaults syslog_goodpri=warning
+Defaults syslog_goodpri=none
+Defaults !syslog_badpri
+Defaults syslog_badpri=alert
+Defaults syslog_badpri=crit
+Defaults syslog_badpri=debug
+Defaults syslog_badpri=emerg
+Defaults syslog_badpri=err
+Defaults syslog_badpri=info
+Defaults syslog_badpri=notice
+Defaults syslog_badpri=warning
+Defaults syslog_badpri=none
diff --git a/plugins/sudoers/regress/sudoers/test21.toke.ok b/plugins/sudoers/regress/sudoers/test21.toke.ok
new file mode 100644
index 0000000..871584b
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test21.toke.ok
@@ -0,0 +1,36 @@
+#
+DEFAULTS DEFVAR
+DEFAULTS !DEFVAR
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+
+DEFAULTS !DEFVAR
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+
+DEFAULTS !DEFVAR
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
+DEFAULTS DEFVAR = WORD(2)
diff --git a/plugins/sudoers/regress/sudoers/test22.in b/plugins/sudoers/regress/sudoers/test22.in
new file mode 100644
index 0000000..ecf2fd9
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test22.in
@@ -0,0 +1,6 @@
+# Test parsing of empty Runas_List
+
+user1 ALL = ( : ) ALL
+user2 ALL = (:) ALL
+user3 ALL = ( ) ALL
+user4 ALL = () ALL
diff --git a/plugins/sudoers/regress/sudoers/test22.json.ok b/plugins/sudoers/regress/sudoers/test22.json.ok
new file mode 100644
index 0000000..22141a1
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test22.json.ok
@@ -0,0 +1,88 @@
+{
+ "User_Specs": [
+ {
+ "User_List": [
+ { "username": "user1" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user2" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user3" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "username": "user4" }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "username": "" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/plugins/sudoers/regress/sudoers/test22.ldif.ok b/plugins/sudoers/regress/sudoers/test22.ldif.ok
new file mode 100644
index 0000000..14c3df4
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test22.ldif.ok
@@ -0,0 +1,40 @@
+dn: cn=user1,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user1
+sudoUser: user1
+sudoHost: ALL
+sudoRunAsUser:
+sudoCommand: ALL
+sudoOrder: 1
+
+dn: cn=user2,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user2
+sudoUser: user2
+sudoHost: ALL
+sudoRunAsUser:
+sudoCommand: ALL
+sudoOrder: 2
+
+dn: cn=user3,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user3
+sudoUser: user3
+sudoHost: ALL
+sudoRunAsUser:
+sudoCommand: ALL
+sudoOrder: 3
+
+dn: cn=user4,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: user4
+sudoUser: user4
+sudoHost: ALL
+sudoRunAsUser:
+sudoCommand: ALL
+sudoOrder: 4
+
diff --git a/plugins/sudoers/regress/sudoers/test22.ldif2sudo.ok b/plugins/sudoers/regress/sudoers/test22.ldif2sudo.ok
new file mode 100644
index 0000000..e0c98e0
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test22.ldif2sudo.ok
@@ -0,0 +1,11 @@
+# sudoRole user1
+user1 ALL = () ALL
+
+# sudoRole user2
+user2 ALL = () ALL
+
+# sudoRole user3
+user3 ALL = () ALL
+
+# sudoRole user4
+user4 ALL = () ALL
diff --git a/plugins/sudoers/regress/sudoers/test22.out.ok b/plugins/sudoers/regress/sudoers/test22.out.ok
new file mode 100644
index 0000000..ab43a93
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test22.out.ok
@@ -0,0 +1,6 @@
+Parses OK.
+
+user1 ALL = (root) ALL
+user2 ALL = (root) ALL
+user3 ALL = (root) ALL
+user4 ALL = (root) ALL
diff --git a/plugins/sudoers/regress/sudoers/test22.sudo.ok b/plugins/sudoers/regress/sudoers/test22.sudo.ok
new file mode 100644
index 0000000..879e1bd
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test22.sudo.ok
@@ -0,0 +1,7 @@
+user1 ALL = () ALL
+
+user2 ALL = () ALL
+
+user3 ALL = () ALL
+
+user4 ALL = () ALL
diff --git a/plugins/sudoers/regress/sudoers/test22.toke.ok b/plugins/sudoers/regress/sudoers/test22.toke.ok
new file mode 100644
index 0000000..baf395b
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test22.toke.ok
@@ -0,0 +1,6 @@
+#
+
+WORD(5) ALL = ( : ) ALL
+WORD(5) ALL = ( : ) ALL
+WORD(5) ALL = ( ) ALL
+WORD(5) ALL = ( ) ALL
diff --git a/plugins/sudoers/regress/sudoers/test3.in b/plugins/sudoers/regress/sudoers/test3.in
new file mode 100644
index 0000000..82fcd83
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test3.in
@@ -0,0 +1,6 @@
+# Test whitespace in User_List as part of a per-user Defaults entry
+User_Alias FOO = foo, bar
+Defaults:FOO env_reset
+Defaults:foo,bar env_reset
+Defaults:foo,\ bar env_reset
+Defaults:foo, bar env_reset
diff --git a/plugins/sudoers/regress/sudoers/test3.json.ok b/plugins/sudoers/regress/sudoers/test3.json.ok
new file mode 100644
index 0000000..fc69eb1
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test3.json.ok
@@ -0,0 +1,45 @@
+{
+ "Defaults": [
+ {
+ "Binding": [
+ { "useralias": "FOO" }
+ ],
+ "Options": [
+ { "env_reset": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "username": "foo" },
+ { "username": "bar" }
+ ],
+ "Options": [
+ { "env_reset": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "username": "foo" },
+ { "username": " bar" }
+ ],
+ "Options": [
+ { "env_reset": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "username": "foo" },
+ { "username": "bar" }
+ ],
+ "Options": [
+ { "env_reset": true }
+ ]
+ }
+ ],
+ "User_Aliases": {
+ "FOO": [
+ { "username": "foo" },
+ { "username": "bar" }
+ ]
+ }
+}
diff --git a/plugins/sudoers/regress/sudoers/test3.ldif.ok b/plugins/sudoers/regress/sudoers/test3.ldif.ok
new file mode 100644
index 0000000..0aa54be
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test3.ldif.ok
@@ -0,0 +1,12 @@
+# Unable to translate stdin:3
+# Defaults:foo, bar env_reset
+
+# Unable to translate stdin:4
+# Defaults:foo, bar env_reset
+
+# Unable to translate stdin:5
+# Defaults:foo, " bar" env_reset
+
+# Unable to translate stdin:6
+# Defaults:foo, bar env_reset
+
diff --git a/plugins/sudoers/regress/sudoers/test3.ldif2sudo.ok b/plugins/sudoers/regress/sudoers/test3.ldif2sudo.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test3.ldif2sudo.ok
diff --git a/plugins/sudoers/regress/sudoers/test3.out.ok b/plugins/sudoers/regress/sudoers/test3.out.ok
new file mode 100644
index 0000000..566aec1
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test3.out.ok
@@ -0,0 +1,8 @@
+Parses OK.
+
+Defaults:FOO env_reset
+Defaults:foo, bar env_reset
+Defaults:foo, " bar" env_reset
+Defaults:foo, bar env_reset
+
+User_Alias FOO = foo, bar
diff --git a/plugins/sudoers/regress/sudoers/test3.toke.ok b/plugins/sudoers/regress/sudoers/test3.toke.ok
new file mode 100644
index 0000000..49f2e51
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test3.toke.ok
@@ -0,0 +1,6 @@
+#
+USERALIAS ALIAS = WORD(5) , WORD(5)
+DEFAULTS_USER ALIAS DEFVAR
+DEFAULTS_USER WORD(5) , WORD(5) DEFVAR
+DEFAULTS_USER WORD(5) , WORD(5) DEFVAR
+DEFAULTS_USER WORD(5) , WORD(5) DEFVAR
diff --git a/plugins/sudoers/regress/sudoers/test4.in b/plugins/sudoers/regress/sudoers/test4.in
new file mode 100644
index 0000000..b8df454
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test4.in
@@ -0,0 +1,7 @@
+# Test line continuation with anchored matches
+User_Alias FOO = foo \
+: BAR = bar
+
+# This used to pass for sudo < 1.8.1 (though it should not have)
+User_Alias FOO = foo \
+User_Alias BAR = bar
diff --git a/plugins/sudoers/regress/sudoers/test4.json.ok b/plugins/sudoers/regress/sudoers/test4.json.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test4.json.ok
diff --git a/plugins/sudoers/regress/sudoers/test4.ldif.ok b/plugins/sudoers/regress/sudoers/test4.ldif.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test4.ldif.ok
diff --git a/plugins/sudoers/regress/sudoers/test4.out.ok b/plugins/sudoers/regress/sudoers/test4.out.ok
new file mode 100644
index 0000000..3552d3b
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test4.out.ok
@@ -0,0 +1,4 @@
+Parse error in sudoers near line 7.
+
+User_Alias BAR = bar
+User_Alias FOO = foo
diff --git a/plugins/sudoers/regress/sudoers/test4.toke.ok b/plugins/sudoers/regress/sudoers/test4.toke.ok
new file mode 100644
index 0000000..a225792
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test4.toke.ok
@@ -0,0 +1,5 @@
+#
+USERALIAS ALIAS = WORD(5) : ALIAS = WORD(5)
+
+#
+USERALIAS ALIAS = WORD(5) ERROR <*> ALIAS = WORD(5)
diff --git a/plugins/sudoers/regress/sudoers/test5.in b/plugins/sudoers/regress/sudoers/test5.in
new file mode 100644
index 0000000..354f589
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test5.in
@@ -0,0 +1,3 @@
+# Test empty string in User_Alias and Command_Spec
+User_Alias FOO = ""
+"" ALL = ALL
diff --git a/plugins/sudoers/regress/sudoers/test5.json.ok b/plugins/sudoers/regress/sudoers/test5.json.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test5.json.ok
diff --git a/plugins/sudoers/regress/sudoers/test5.ldif.ok b/plugins/sudoers/regress/sudoers/test5.ldif.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test5.ldif.ok
diff --git a/plugins/sudoers/regress/sudoers/test5.out.ok b/plugins/sudoers/regress/sudoers/test5.out.ok
new file mode 100644
index 0000000..3cd2ec8
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test5.out.ok
@@ -0,0 +1,2 @@
+Parse error in sudoers near line 2.
+
diff --git a/plugins/sudoers/regress/sudoers/test5.toke.ok b/plugins/sudoers/regress/sudoers/test5.toke.ok
new file mode 100644
index 0000000..9376455
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test5.toke.ok
@@ -0,0 +1,3 @@
+#
+USERALIAS ALIAS = BEGINSTR ENDSTR ERROR <*>
+BEGINSTR ENDSTR ERROR <*> ALL = ALL
diff --git a/plugins/sudoers/regress/sudoers/test6.in b/plugins/sudoers/regress/sudoers/test6.in
new file mode 100644
index 0000000..e804571
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test6.in
@@ -0,0 +1,15 @@
+# Check that uids work in per-user and per-runas Defaults
+Defaults:#123 set_home
+Defaults>#123 set_home
+Defaults:"#123" set_home
+Defaults>"#123" set_home
+
+# Check that uids work in a Command_Spec
+#0 ALL = ALL
+#0 ALL = (#0 : #0) ALL
+"#0" ALL = ALL
+"#0" ALL = ("#0" : "#0") ALL
+
+# Check that gids work in a Command_Spec
+%#0 ALL = ALL
+"%#0" ALL = ALL
diff --git a/plugins/sudoers/regress/sudoers/test6.json.ok b/plugins/sudoers/regress/sudoers/test6.json.ok
new file mode 100644
index 0000000..be1f80f
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test6.json.ok
@@ -0,0 +1,158 @@
+{
+ "Defaults": [
+ {
+ "Binding": [
+ { "userid": 123 }
+ ],
+ "Options": [
+ { "set_home": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "userid": 123 }
+ ],
+ "Options": [
+ { "set_home": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "userid": 123 }
+ ],
+ "Options": [
+ { "set_home": true }
+ ]
+ },
+ {
+ "Binding": [
+ { "userid": 123 }
+ ],
+ "Options": [
+ { "set_home": true }
+ ]
+ }
+ ],
+ "User_Specs": [
+ {
+ "User_List": [
+ { "userid": 0 }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "userid": 0 }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "userid": 0 }
+ ],
+ "runasgroups": [
+ { "usergroup": "#0" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "userid": 0 }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "userid": 0 }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "runasusers": [
+ { "userid": 0 }
+ ],
+ "runasgroups": [
+ { "usergroup": "#0" }
+ ],
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "usergid": 0 }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ },
+ {
+ "User_List": [
+ { "usergid": 0 }
+ ],
+ "Host_List": [
+ { "hostname": "ALL" }
+ ],
+ "Cmnd_Specs": [
+ {
+ "Options": [
+ { "setenv": true }
+ ],
+ "Commands": [
+ { "command": "ALL" }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/plugins/sudoers/regress/sudoers/test6.ldif.ok b/plugins/sudoers/regress/sudoers/test6.ldif.ok
new file mode 100644
index 0000000..c4e11e4
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test6.ldif.ok
@@ -0,0 +1,70 @@
+# Unable to translate stdin:2
+# Defaults:#123 set_home
+
+# Unable to translate stdin:3
+# Defaults>#123 set_home
+
+# Unable to translate stdin:4
+# Defaults:#123 set_home
+
+# Unable to translate stdin:5
+# Defaults>#123 set_home
+
+dn: cn=\#0,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: \#0
+sudoUser: #0
+sudoHost: ALL
+sudoCommand: ALL
+sudoOrder: 1
+
+dn: cn=\#0_1,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: \#0_1
+sudoUser: #0
+sudoHost: ALL
+sudoRunAsUser: #0
+sudoRunAsGroup: #0
+sudoCommand: ALL
+sudoOrder: 2
+
+dn: cn=\#0_2,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: \#0_2
+sudoUser: #0
+sudoHost: ALL
+sudoCommand: ALL
+sudoOrder: 3
+
+dn: cn=\#0_3,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: \#0_3
+sudoUser: #0
+sudoHost: ALL
+sudoRunAsUser: #0
+sudoRunAsGroup: #0
+sudoCommand: ALL
+sudoOrder: 4
+
+dn: cn=%\#0,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %\#0
+sudoUser: %#0
+sudoHost: ALL
+sudoCommand: ALL
+sudoOrder: 5
+
+dn: cn=%\#0_1,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %\#0_1
+sudoUser: %#0
+sudoHost: ALL
+sudoCommand: ALL
+sudoOrder: 6
+
diff --git a/plugins/sudoers/regress/sudoers/test6.ldif2sudo.ok b/plugins/sudoers/regress/sudoers/test6.ldif2sudo.ok
new file mode 100644
index 0000000..bfe40bb
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test6.ldif2sudo.ok
@@ -0,0 +1,5 @@
+# sudoRole #0, #0_1, #0_2, #0_3
+#0 ALL = ALL, (#0 : #0) ALL, ALL, (#0 : #0) ALL
+
+# sudoRole %#0, %#0_1
+%#0 ALL = ALL, ALL
diff --git a/plugins/sudoers/regress/sudoers/test6.out.ok b/plugins/sudoers/regress/sudoers/test6.out.ok
new file mode 100644
index 0000000..ccc1627
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test6.out.ok
@@ -0,0 +1,13 @@
+Parses OK.
+
+Defaults:#123 set_home
+Defaults>#123 set_home
+Defaults:#123 set_home
+Defaults>#123 set_home
+
+#0 ALL = ALL
+#0 ALL = (#0 : #0) ALL
+#0 ALL = ALL
+#0 ALL = (#0 : #0) ALL
+%#0 ALL = ALL
+%#0 ALL = ALL
diff --git a/plugins/sudoers/regress/sudoers/test6.toke.ok b/plugins/sudoers/regress/sudoers/test6.toke.ok
new file mode 100644
index 0000000..a9c0522
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test6.toke.ok
@@ -0,0 +1,15 @@
+#
+DEFAULTS_USER WORD(5) DEFVAR
+DEFAULTS_RUNAS WORD(5) DEFVAR
+DEFAULTS_USER BEGINSTR STRBODY ENDSTR WORD(4) DEFVAR
+DEFAULTS_RUNAS BEGINSTR STRBODY ENDSTR WORD(4) DEFVAR
+
+#
+WORD(5) ALL = ALL
+WORD(5) ALL = ( WORD(5) : WORD(5) ) ALL
+BEGINSTR STRBODY ENDSTR WORD(4) ALL = ALL
+BEGINSTR STRBODY ENDSTR WORD(4) ALL = ( BEGINSTR STRBODY ENDSTR WORD(4) : BEGINSTR STRBODY ENDSTR WORD(4) ) ALL
+
+#
+USERGROUP ALL = ALL
+BEGINSTR STRBODY ENDSTR USERGROUP ALL = ALL
diff --git a/plugins/sudoers/regress/sudoers/test7.in b/plugins/sudoers/regress/sudoers/test7.in
new file mode 100644
index 0000000..7b241d0
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test7.in
@@ -0,0 +1,7 @@
+# These should all be syntax errors
+User_Alias FOO1 = "%"
+User_Alias FOO2 = "%:"
+User_Alias FOO3 = "+"
+User_Alias FOO4 = %
+User_Alias FOO5 = %:
+User_Alias FOO6 = +
diff --git a/plugins/sudoers/regress/sudoers/test7.json.ok b/plugins/sudoers/regress/sudoers/test7.json.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test7.json.ok
diff --git a/plugins/sudoers/regress/sudoers/test7.ldif.ok b/plugins/sudoers/regress/sudoers/test7.ldif.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test7.ldif.ok
diff --git a/plugins/sudoers/regress/sudoers/test7.out.ok b/plugins/sudoers/regress/sudoers/test7.out.ok
new file mode 100644
index 0000000..3cd2ec8
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test7.out.ok
@@ -0,0 +1,2 @@
+Parse error in sudoers near line 2.
+
diff --git a/plugins/sudoers/regress/sudoers/test7.toke.ok b/plugins/sudoers/regress/sudoers/test7.toke.ok
new file mode 100644
index 0000000..a5bf018
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test7.toke.ok
@@ -0,0 +1,7 @@
+#
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR ERROR <*>
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR ERROR <*>
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR ERROR <*>
+USERALIAS ALIAS = ERROR <*>
+USERALIAS ALIAS = ERROR <*>
+USERALIAS ALIAS = ERROR <*>
diff --git a/plugins/sudoers/regress/sudoers/test8.in b/plugins/sudoers/regress/sudoers/test8.in
new file mode 100644
index 0000000..d25e834
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test8.in
@@ -0,0 +1,8 @@
+# Test quoted strings
+User_Alias UA1 = "xy"
+User_Alias UA2 = "x\
+y"
+User_Alias UA3 = x\"y
+
+# A newline in the middle of a string is an error
+User_Alias UA4 = "x
diff --git a/plugins/sudoers/regress/sudoers/test8.json.ok b/plugins/sudoers/regress/sudoers/test8.json.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test8.json.ok
diff --git a/plugins/sudoers/regress/sudoers/test8.ldif.ok b/plugins/sudoers/regress/sudoers/test8.ldif.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test8.ldif.ok
diff --git a/plugins/sudoers/regress/sudoers/test8.out.ok b/plugins/sudoers/regress/sudoers/test8.out.ok
new file mode 100644
index 0000000..2ae8c6b
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test8.out.ok
@@ -0,0 +1,5 @@
+Parse error in sudoers near line 8.
+
+User_Alias UA1 = xy
+User_Alias UA2 = xy
+User_Alias UA3 = x\"y
diff --git a/plugins/sudoers/regress/sudoers/test8.toke.ok b/plugins/sudoers/regress/sudoers/test8.toke.ok
new file mode 100644
index 0000000..0f7e2a9
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test8.toke.ok
@@ -0,0 +1,7 @@
+#
+USERALIAS ALIAS = BEGINSTR STRBODY ENDSTR WORD(4)
+USERALIAS ALIAS = BEGINSTR STRBODY STRBODY ENDSTR WORD(4)
+USERALIAS ALIAS = WORD(5)
+
+#
+USERALIAS ALIAS = BEGINSTR STRBODY ERROR <*> ERROR \ No newline at end of file
diff --git a/plugins/sudoers/regress/sudoers/test9.in b/plugins/sudoers/regress/sudoers/test9.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test9.in
diff --git a/plugins/sudoers/regress/sudoers/test9.json.ok b/plugins/sudoers/regress/sudoers/test9.json.ok
new file mode 100644
index 0000000..2c63c08
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test9.json.ok
@@ -0,0 +1,2 @@
+{
+}
diff --git a/plugins/sudoers/regress/sudoers/test9.ldif.ok b/plugins/sudoers/regress/sudoers/test9.ldif.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test9.ldif.ok
diff --git a/plugins/sudoers/regress/sudoers/test9.out.ok b/plugins/sudoers/regress/sudoers/test9.out.ok
new file mode 100644
index 0000000..40c742d
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test9.out.ok
@@ -0,0 +1,2 @@
+Parses OK.
+
diff --git a/plugins/sudoers/regress/sudoers/test9.toke.ok b/plugins/sudoers/regress/sudoers/test9.toke.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/sudoers/test9.toke.ok
diff --git a/plugins/sudoers/regress/testsudoers/group b/plugins/sudoers/regress/testsudoers/group
new file mode 100644
index 0000000..e2202d6
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/group
@@ -0,0 +1,15 @@
+wheel:*:0:root
+daemon:*:1:daemon
+kmem:*:2:root
+sys:*:3:root
+tty:*:4:root
+operator:*:5:root
+bin:*:7:
+wsrc:*:9:
+users:*:10:
+auth:*:11:
+games:*:13:
+staff:*:20:root
+guest:*:31:root
+nogroup:*:32766:
+nobody:*:32767:
diff --git a/plugins/sudoers/regress/testsudoers/test1.out.ok b/plugins/sudoers/regress/testsudoers/test1.out.ok
new file mode 100644
index 0000000..f980873
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test1.out.ok
@@ -0,0 +1,8 @@
+Parses OK.
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+
+Command unmatched
diff --git a/plugins/sudoers/regress/testsudoers/test1.sh b/plugins/sudoers/regress/testsudoers/test1.sh
new file mode 100755
index 0000000..fb99a91
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test1.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# Test for NULL dereference with "sudo -g group" when the sudoers rule
+# has no runas user or group listed.
+# This is RedHat bug Bug 667103.
+#
+
+exec 2>&1
+./testsudoers -g bin -P ${TESTDIR}/group root id <<EOF
+root ALL = ALL
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test2.inc b/plugins/sudoers/regress/testsudoers/test2.inc
new file mode 100644
index 0000000..52ca040
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test2.inc
@@ -0,0 +1 @@
+root ALL = ALL
diff --git a/plugins/sudoers/regress/testsudoers/test2.out.ok b/plugins/sudoers/regress/testsudoers/test2.out.ok
new file mode 100644
index 0000000..eabeb20
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test2.out.ok
@@ -0,0 +1,10 @@
+Parses OK.
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test2.sh b/plugins/sudoers/regress/testsudoers/test2.sh
new file mode 100755
index 0000000..d76cfbb
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test2.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# Test #include facility
+#
+
+MYUID=`\ls -ln $TESTDIR/test2.inc | awk '{print $3}'`
+MYGID=`\ls -ln $TESTDIR/test2.inc | awk '{print $4}'`
+exec 2>&1
+./testsudoers -U $MYUID -G $MYGID root id <<EOF
+#include $TESTDIR/test2.inc
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test3.d/root b/plugins/sudoers/regress/testsudoers/test3.d/root
new file mode 100644
index 0000000..52ca040
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test3.d/root
@@ -0,0 +1 @@
+root ALL = ALL
diff --git a/plugins/sudoers/regress/testsudoers/test3.out.ok b/plugins/sudoers/regress/testsudoers/test3.out.ok
new file mode 100644
index 0000000..eabeb20
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test3.out.ok
@@ -0,0 +1,10 @@
+Parses OK.
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test3.sh b/plugins/sudoers/regress/testsudoers/test3.sh
new file mode 100755
index 0000000..c1251b9
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test3.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# Test #include facility
+#
+
+MYUID=`\ls -lnd $TESTDIR/test3.d | awk '{print $3}'`
+MYGID=`\ls -lnd $TESTDIR/test3.d | awk '{print $4}'`
+exec 2>&1
+./testsudoers -U $MYUID -G $MYGID root id <<EOF
+#includedir $TESTDIR/test3.d
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test4.out.ok b/plugins/sudoers/regress/testsudoers/test4.out.ok
new file mode 100644
index 0000000..6b27d71
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test4.out.ok
@@ -0,0 +1,6 @@
+testsudoers: test2.inc should be owned by uid 1
+Parse error in sudoers near line 1.
+
+Entries for user root:
+
+Command unmatched
diff --git a/plugins/sudoers/regress/testsudoers/test4.sh b/plugins/sudoers/regress/testsudoers/test4.sh
new file mode 100755
index 0000000..3eaaa1d
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test4.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Test sudoers owner check
+#
+
+# Avoid warnings about memory leaks when there is a syntax error
+ASAN_OPTIONS=detect_leaks=0; export ASAN_OPTIONS
+
+exec 2>&1
+./testsudoers -U 1 root id <<EOF
+#include $TESTDIR/test2.inc
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test5.out.ok b/plugins/sudoers/regress/testsudoers/test5.out.ok
new file mode 100644
index 0000000..5e319c9
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test5.out.ok
@@ -0,0 +1,12 @@
+testsudoers: test5.inc is world writable
+Parse error in sudoers near line 1.
+
+Entries for user root:
+
+Command unmatched
+testsudoers: test5.inc should be owned by gid 4294967295
+Parse error in sudoers near line 1.
+
+Entries for user root:
+
+Command unmatched
diff --git a/plugins/sudoers/regress/testsudoers/test5.sh b/plugins/sudoers/regress/testsudoers/test5.sh
new file mode 100755
index 0000000..9e690a6
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test5.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Test sudoers file mode check
+#
+
+# Avoid warnings about memory leaks when there is a syntax error
+ASAN_OPTIONS=detect_leaks=0; export ASAN_OPTIONS
+
+# Create test file
+TESTFILE=`pwd`/regress/testsudoers/test5.inc
+cat >$TESTFILE <<EOF
+root ALL = ALL
+EOF
+
+MYUID=`\ls -ln $TESTFILE | awk '{print $3}'`
+MYGID=`\ls -ln $TESTFILE | awk '{print $4}'`
+exec 2>&1
+
+# Test world writable
+chmod 666 $TESTFILE
+./testsudoers -U $MYUID -G $MYGID root id <<EOF
+#include $TESTFILE
+EOF
+
+# Test group writable
+chmod 664 $TESTFILE
+./testsudoers -U $MYUID -G -1 root id <<EOF
+#include $TESTFILE
+EOF
+
+rm -f $TESTFILE
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test6.out.ok b/plugins/sudoers/regress/testsudoers/test6.out.ok
new file mode 100644
index 0000000..eabeb20
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test6.out.ok
@@ -0,0 +1,10 @@
+Parses OK.
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test6.sh b/plugins/sudoers/regress/testsudoers/test6.sh
new file mode 100755
index 0000000..ee9f93d
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test6.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+#
+# Verify sudoers matching by uid.
+#
+
+exec 2>&1
+./testsudoers root id <<EOF
+#0 ALL = ALL
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test7.out.ok b/plugins/sudoers/regress/testsudoers/test7.out.ok
new file mode 100644
index 0000000..eabeb20
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test7.out.ok
@@ -0,0 +1,10 @@
+Parses OK.
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test7.sh b/plugins/sudoers/regress/testsudoers/test7.sh
new file mode 100755
index 0000000..4975245
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test7.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+#
+# Verify sudoers matching by gid.
+#
+
+exec 2>&1
+./testsudoers root id <<EOF
+%#0 ALL = ALL
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/visudo/test1.out.ok b/plugins/sudoers/regress/visudo/test1.out.ok
new file mode 100644
index 0000000..e5c355c
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test1.out.ok
@@ -0,0 +1 @@
+stdin: parsed OK
diff --git a/plugins/sudoers/regress/visudo/test1.sh b/plugins/sudoers/regress/visudo/test1.sh
new file mode 100755
index 0000000..c922e35
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test1.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+#
+# Sudo Bug 519:
+# Visudo in strict mode reports "parse error" even if there is no error
+#
+
+./visudo -csf - <<EOF
+User_Alias FOO = nobody
+FOO ALL=(ALL) NOPASSWD: ALL
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/visudo/test10.out.ok b/plugins/sudoers/regress/visudo/test10.out.ok
new file mode 100644
index 0000000..e5c355c
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test10.out.ok
@@ -0,0 +1 @@
+stdin: parsed OK
diff --git a/plugins/sudoers/regress/visudo/test10.sh b/plugins/sudoers/regress/visudo/test10.sh
new file mode 100755
index 0000000..ea0ca41
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test10.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+#
+# Test parsing of NOTBEFORE/NOTAFTER using local time zone
+#
+
+./visudo -cf - <<-EOF
+ user1 ALL = NOTBEFORE=20151201235900 /usr/bin/id
+ user2 ALL = NOTBEFORE=20151201235900.2 /usr/bin/id
+ user3 ALL = NOTBEFORE=20151201235900\,2 /usr/bin/id
+ user4 ALL = NOTBEFORE=2015120123 /usr/bin/id
+ EOF
diff --git a/plugins/sudoers/regress/visudo/test2.err.ok b/plugins/sudoers/regress/visudo/test2.err.ok
new file mode 100644
index 0000000..38189df
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test2.err.ok
@@ -0,0 +1 @@
+Error: stdin:1 cycle in User_Alias "FOO"
diff --git a/plugins/sudoers/regress/visudo/test2.out.ok b/plugins/sudoers/regress/visudo/test2.out.ok
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test2.out.ok
diff --git a/plugins/sudoers/regress/visudo/test2.sh b/plugins/sudoers/regress/visudo/test2.sh
new file mode 100755
index 0000000..41d3711
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test2.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# Test cycle detection
+# Prior to sudo 1.8.6p5 this resulted in a core dump (stack smash)
+# The names of the aliases (or rather their lexical order) is important.
+#
+
+./visudo -csf - <<EOF
+User_Alias YYY = FOO
+User_Alias XXX = nobody
+User_Alias FOO = XXX, YYY
+FOO ALL = ALL
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/visudo/test3.err.ok b/plugins/sudoers/regress/visudo/test3.err.ok
new file mode 100644
index 0000000..8390f86
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test3.err.ok
@@ -0,0 +1,2 @@
+Warning: stdin:1 unused User_Alias "A"
+Warning: stdin:2 unused User_Alias "B"
diff --git a/plugins/sudoers/regress/visudo/test3.out.ok b/plugins/sudoers/regress/visudo/test3.out.ok
new file mode 100644
index 0000000..e5c355c
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test3.out.ok
@@ -0,0 +1 @@
+stdin: parsed OK
diff --git a/plugins/sudoers/regress/visudo/test3.sh b/plugins/sudoers/regress/visudo/test3.sh
new file mode 100755
index 0000000..b316e9f
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test3.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# Sudo Bug 361:
+# Excerises a bug in the redblack tree code.
+#
+
+./visudo -cf - <<EOF
+User_Alias A=a
+User_Alias B=a
+User_Alias C=a
+User_Alias D=a
+User_Alias E=a
+User_Alias F=a
+User_Alias G=a
+User_Alias H=a
+User_Alias I=a
+User_Alias J=a
+User_Alias K=a
+User_Alias L=a
+User_Alias M=a
+
+C ALL=(ALL) ALL
+E ALL=(ALL) ALL
+J ALL=(ALL) ALL
+D ALL=(ALL) ALL
+L ALL=(ALL) ALL
+H ALL=(ALL) ALL
+F ALL=(ALL) ALL
+G ALL=(ALL) ALL
+M ALL=(ALL) ALL
+K ALL=(ALL) ALL
+I ALL=(ALL) ALL
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/visudo/test4.out.ok b/plugins/sudoers/regress/visudo/test4.out.ok
new file mode 100644
index 0000000..e5c355c
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test4.out.ok
@@ -0,0 +1 @@
+stdin: parsed OK
diff --git a/plugins/sudoers/regress/visudo/test4.sh b/plugins/sudoers/regress/visudo/test4.sh
new file mode 100755
index 0000000..6f66b66
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test4.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Test cycle detection and duplicate entries.
+# Prior to sudo 1.8.7 this resulted in a false positive.
+#
+
+./visudo -csf - <<EOF
+Host_Alias H1 = host1
+Host_Alias H2 = H1, host2
+Host_Alias H3 = H1, H2
+root H3 = ALL
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/visudo/test5.out.ok b/plugins/sudoers/regress/visudo/test5.out.ok
new file mode 100644
index 0000000..e5c355c
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test5.out.ok
@@ -0,0 +1 @@
+stdin: parsed OK
diff --git a/plugins/sudoers/regress/visudo/test5.sh b/plugins/sudoers/regress/visudo/test5.sh
new file mode 100755
index 0000000..29364ea
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test5.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# Test comment on the last line with no newline
+#
+
+printf "# one comment\n#two comments" | ./visudo -csf -
+
+exit 0
diff --git a/plugins/sudoers/regress/visudo/test6.out.ok b/plugins/sudoers/regress/visudo/test6.out.ok
new file mode 100644
index 0000000..e5c355c
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test6.out.ok
@@ -0,0 +1 @@
+stdin: parsed OK
diff --git a/plugins/sudoers/regress/visudo/test6.sh b/plugins/sudoers/regress/visudo/test6.sh
new file mode 100755
index 0000000..596f5a1
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test6.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Verify parsing of Defaults syntax
+#
+
+./visudo -csf - <<EOF
+Defaults syslog=auth
+Defaults>root !set_logname
+Defaults:FULLTIMERS !lecture
+Defaults:millert !authenticate
+Defaults@SERVERS log_year, logfile=/var/log/sudo.log
+Defaults!PAGERS noexec
+
+Defaults env_keep -= "HOME"
+Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
+Defaults env_keep += "MAIL PS1 PS2 QTDIR LANG LC_ADDRESS LC_CTYPE"
+
+User_Alias FULLTIMERS = millert, mikef, dowdy
+
+Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
+
+Host_Alias SERVERS = master, mail, www, ns
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/visudo/test7.out.ok b/plugins/sudoers/regress/visudo/test7.out.ok
new file mode 100644
index 0000000..e5c355c
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test7.out.ok
@@ -0,0 +1 @@
+stdin: parsed OK
diff --git a/plugins/sudoers/regress/visudo/test7.sh b/plugins/sudoers/regress/visudo/test7.sh
new file mode 100755
index 0000000..9f30923
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test7.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# Test sudoers_locale early Defaults
+#
+
+LANG=C; export LANG
+LC_NUMERIC=fr_FR.UTF-8; export LC_NUMERIC
+
+# First check that visudo supports non-C locales
+# Note that older versions of sudo did not set the locale
+# until sudoers was read so this check will fail on them.
+./visudo -csf - >/dev/null 2>&1 <<-EOF
+ Defaults sudoers_locale = fr_FR.UTF-8
+ Defaults passwd_timeout = "2,5"
+ EOF
+
+# Now make sure we can set passwd_timeout to a floating point value
+# using a non-C locale.
+if [ $? -eq 0 ]; then
+ ./visudo -csf - <<-EOF
+ Defaults passwd_timeout = "2,5"
+ Defaults sudoers_locale = fr_FR.UTF-8
+ EOF
+else
+ # No support for LC_NUMERIC?
+ echo "stdin: parsed OK"
+fi
+
+exit 0
diff --git a/plugins/sudoers/regress/visudo/test8.err.ok b/plugins/sudoers/regress/visudo/test8.err.ok
new file mode 100644
index 0000000..e8a2b18
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test8.err.ok
@@ -0,0 +1 @@
+visudo: stdin:1 value "2.5" is invalid for option "passwd_timeout"
diff --git a/plugins/sudoers/regress/visudo/test8.out.ok b/plugins/sudoers/regress/visudo/test8.out.ok
new file mode 100644
index 0000000..16ebc45
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test8.out.ok
@@ -0,0 +1 @@
+parse error in stdin near line 1
diff --git a/plugins/sudoers/regress/visudo/test8.sh b/plugins/sudoers/regress/visudo/test8.sh
new file mode 100755
index 0000000..6674a55
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test8.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# Test sudoers_locale early Defaults
+#
+
+LANG=C; export LANG
+LC_NUMERIC=fr_FR.UTF-8; export LC_NUMERIC
+
+# First check that visudo supports non-C locales
+# Note that older versions of sudo did not set the locale
+# until sudoers was read so this check will fail on them.
+./visudo -csf - >/dev/null 2>&1 <<-EOF
+ Defaults sudoers_locale = fr_FR.UTF-8
+ Defaults passwd_timeout = "2,5"
+ EOF
+
+# Now make sure we can set passwd_timeout to a floating point value
+# using a non-C locale.
+if [ $? -eq 0 ]; then
+ ./visudo -csf - <<-EOF
+ Defaults passwd_timeout = "2.5"
+ Defaults sudoers_locale = fr_FR.UTF-8
+ EOF
+else
+ # No support for LC_NUMERIC?
+ echo "parse error in stdin near line 1"
+ echo 'visudo: stdin:1 value "2.5" is invalid for option "passwd_timeout"' 1>&2
+fi
+
+exit 0
diff --git a/plugins/sudoers/regress/visudo/test9.out.ok b/plugins/sudoers/regress/visudo/test9.out.ok
new file mode 100644
index 0000000..e5c355c
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test9.out.ok
@@ -0,0 +1 @@
+stdin: parsed OK
diff --git a/plugins/sudoers/regress/visudo/test9.sh b/plugins/sudoers/regress/visudo/test9.sh
new file mode 100755
index 0000000..d62fb88
--- /dev/null
+++ b/plugins/sudoers/regress/visudo/test9.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+#
+# Test IP and network address in host-based Defaults statements
+# Bugzilla #766
+#
+
+./visudo -cf - <<-EOF
+ Defaults@127.0.0.1 !authenticate
+ Defaults@10.0.0.0/8 !always_set_home
+ EOF
+
+exit 0
diff --git a/plugins/sudoers/set_perms.c b/plugins/sudoers/set_perms.c
new file mode 100644
index 0000000..5b83488
--- /dev/null
+++ b/plugins/sudoers/set_perms.c
@@ -0,0 +1,1710 @@
+/*
+ * Copyright (c) 1994-1996, 1998-2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#ifdef _AIX
+# include <sys/id.h>
+#endif
+#include <pwd.h>
+#include <errno.h>
+#include <grp.h>
+
+#include "sudoers.h"
+
+/*
+ * Prototypes
+ */
+#if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
+static struct gid_list *runas_setgroups(void);
+#endif
+
+/*
+ * We keep track of the current permisstions and use a stack to restore
+ * the old permissions. A depth of 16 is overkill.
+ */
+struct perm_state {
+ uid_t ruid;
+ uid_t euid;
+#if defined(HAVE_SETRESUID) || defined(ID_SAVED)
+ uid_t suid;
+#endif
+ gid_t rgid;
+ gid_t egid;
+#if defined(HAVE_SETRESUID) || defined(ID_SAVED)
+ gid_t sgid;
+#endif
+ struct gid_list *gidlist;
+};
+
+#define PERM_STACK_MAX 16
+static struct perm_state perm_stack[PERM_STACK_MAX];
+static int perm_stack_depth = 0;
+
+#undef ID
+#define ID(x) (state->x == ostate->x ? (uid_t)-1 : state->x)
+#undef OID
+#define OID(x) (ostate->x == state->x ? (uid_t)-1 : ostate->x)
+
+bool
+rewind_perms(void)
+{
+ debug_decl(rewind_perms, SUDOERS_DEBUG_PERMS)
+
+ if (perm_stack_depth != 0) {
+ while (perm_stack_depth > 1) {
+ if (!restore_perms())
+ debug_return_bool(false);
+ }
+ sudo_gidlist_delref(perm_stack[0].gidlist);
+ }
+
+ debug_return_bool(true);
+}
+
+#if defined(HAVE_SETRESUID)
+
+#define UID_CHANGED (state->ruid != ostate->ruid || state->euid != ostate->euid || state->suid != ostate->suid)
+#define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid || state->sgid != ostate->sgid)
+
+/*
+ * Set real and effective and saved uids and gids based on perm.
+ * We always retain a saved uid of 0 unless we are headed for an exec().
+ * We only flip the effective gid since it only changes for PERM_SUDOERS.
+ * This version of set_perms() works fine with the "stay_setuid" option.
+ */
+bool
+set_perms(int perm)
+{
+ struct perm_state *state, *ostate = NULL;
+ char errbuf[1024];
+ const char *errstr = errbuf;
+ debug_decl(set_perms, SUDOERS_DEBUG_PERMS)
+
+ if (perm_stack_depth == PERM_STACK_MAX) {
+ errstr = N_("perm stack overflow");
+ errno = EINVAL;
+ goto bad;
+ }
+
+ state = &perm_stack[perm_stack_depth];
+ if (perm != PERM_INITIAL) {
+ if (perm_stack_depth == 0) {
+ errstr = N_("perm stack underflow");
+ errno = EINVAL;
+ goto bad;
+ }
+ ostate = &perm_stack[perm_stack_depth - 1];
+ }
+
+ switch (perm) {
+ case PERM_INITIAL:
+ /* Stash initial state */
+#ifdef HAVE_GETRESUID
+ if (getresuid(&state->ruid, &state->euid, &state->suid)) {
+ errstr = "PERM_INITIAL: getresuid";
+ goto bad;
+
+ }
+ if (getresgid(&state->rgid, &state->egid, &state->sgid)) {
+ errstr = "PERM_INITIAL: getresgid";
+ goto bad;
+ }
+#else
+ state->ruid = getuid();
+ state->euid = geteuid();
+ state->suid = state->euid; /* in case we are setuid */
+
+ state->rgid = getgid();
+ state->egid = getegid();
+ state->sgid = state->egid; /* in case we are setgid */
+#endif
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
+ "ruid: %d, euid: %d, suid: %d, rgid: %d, egid: %d, sgid: %d",
+ __func__, (int)state->ruid, (int)state->euid, (int)state->suid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ break;
+
+ case PERM_ROOT:
+ state->ruid = ROOT_UID;
+ state->euid = ROOT_UID;
+ state->suid = ROOT_UID;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_ROOT: setresuid(%d, %d, %d)",
+ (int)ID(ruid), (int)ID(euid), (int)ID(suid));
+ goto bad;
+ }
+ state->rgid = ostate->rgid;
+ state->egid = ROOT_GID;
+ state->sgid = ostate->sgid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: gid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
+ errstr = N_("unable to change to root gid");
+ goto bad;
+ }
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ break;
+
+ case PERM_USER:
+ state->rgid = ostate->rgid;
+ state->egid = user_gid;
+ state->sgid = ostate->sgid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
+ snprintf(errbuf, sizeof(errbuf), "PERM_USER: setresgid(%d, %d, %d)",
+ (int)ID(rgid), (int)ID(egid), (int)ID(sgid));
+ goto bad;
+ }
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
+ errstr = "PERM_USER: setgroups";
+ goto bad;
+ }
+ }
+ state->ruid = user_uid;
+ state->euid = user_uid;
+ state->suid = ROOT_UID;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
+ snprintf(errbuf, sizeof(errbuf), "PERM_USER: setresuid(%d, %d, %d)",
+ (int)ID(ruid), (int)ID(euid), (int)ID(suid));
+ goto bad;
+ }
+ break;
+
+ case PERM_FULL_USER:
+ /* headed for exec() */
+ state->rgid = user_gid;
+ state->egid = user_gid;
+ state->sgid = user_gid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_FULL_USER: setresgid(%d, %d, %d)",
+ (int)ID(rgid), (int)ID(egid), (int)ID(sgid));
+ goto bad;
+ }
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
+ errstr = "PERM_FULL_USER: setgroups";
+ goto bad;
+ }
+ }
+ state->ruid = user_uid;
+ state->euid = user_uid;
+ state->suid = user_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_FULL_USER: setresuid(%d, %d, %d)",
+ (int)ID(ruid), (int)ID(euid), (int)ID(suid));
+ goto bad;
+ }
+ break;
+
+ case PERM_RUNAS:
+ state->rgid = ostate->rgid;
+ state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
+ state->sgid = ostate->sgid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
+ errstr = N_("unable to change to runas gid");
+ goto bad;
+ }
+ state->gidlist = runas_setgroups();
+ if (state->gidlist == NULL) {
+ errstr = N_("unable to set runas group vector");
+ goto bad;
+ }
+ state->ruid = ostate->ruid;
+ state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
+ state->suid = ostate->suid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
+ errstr = N_("unable to change to runas uid");
+ goto bad;
+ }
+ break;
+
+ case PERM_SUDOERS:
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+
+ /* assumes euid == ROOT_UID, ruid == user */
+ state->rgid = ostate->rgid;
+ state->egid = sudoers_gid;
+ state->sgid = ostate->sgid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
+ errstr = N_("unable to change to sudoers gid");
+ goto bad;
+ }
+
+ state->ruid = ROOT_UID;
+ /*
+ * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
+ * we use a non-zero uid in order to avoid NFS lossage.
+ * Using uid 1 is a bit bogus but should work on all OS's.
+ */
+ if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP))
+ state->euid = 1;
+ else
+ state->euid = sudoers_uid;
+ state->suid = ROOT_UID;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_SUDOERS: setresuid(%d, %d, %d)",
+ (int)ID(ruid), (int)ID(euid), (int)ID(suid));
+ goto bad;
+ }
+ break;
+
+ case PERM_TIMESTAMP:
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ state->rgid = ostate->rgid;
+ state->egid = ostate->egid;
+ state->sgid = ostate->sgid;
+ state->ruid = ROOT_UID;
+ state->euid = timestamp_uid;
+ state->suid = ROOT_UID;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_TIMESTAMP: setresuid(%d, %d, %d)",
+ (int)ID(ruid), (int)ID(euid), (int)ID(suid));
+ goto bad;
+ }
+ break;
+
+ case PERM_IOLOG:
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ state->rgid = ostate->rgid;
+ state->egid = iolog_gid;
+ state->sgid = ostate->sgid;
+ state->ruid = ROOT_UID;
+ state->euid = iolog_uid;
+ state->suid = ROOT_UID;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_IOLOG: gid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_IOLOG: setresgid(%d, %d, %d)",
+ (int)ID(rgid), (int)ID(egid), (int)ID(sgid));
+ goto bad;
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_IOLOG: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_IOLOG: setresuid(%d, %d, %d)",
+ (int)ID(ruid), (int)ID(euid), (int)ID(suid));
+ goto bad;
+ }
+ break;
+ }
+
+ perm_stack_depth++;
+ debug_return_bool(true);
+bad:
+ if (errno == EAGAIN)
+ sudo_warnx(U_("%s: %s"), U_(errstr), U_("too many processes"));
+ else
+ sudo_warn("%s", U_(errstr));
+ debug_return_bool(false);
+}
+
+bool
+restore_perms(void)
+{
+ struct perm_state *state, *ostate;
+ debug_decl(restore_perms, SUDOERS_DEBUG_PERMS)
+
+ if (perm_stack_depth < 2) {
+ sudo_warnx(U_("perm stack underflow"));
+ debug_return_bool(true);
+ }
+
+ state = &perm_stack[perm_stack_depth - 1];
+ ostate = &perm_stack[perm_stack_depth - 2];
+ perm_stack_depth--;
+
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d, %d] -> [%d, %d, %d]",
+ __func__, (int)state->ruid, (int)state->euid, (int)state->suid,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d, %d] -> [%d, %d, %d]",
+ __func__, (int)state->rgid, (int)state->egid, (int)state->sgid,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid);
+
+ /* XXX - more cases here where euid != ruid */
+ if (OID(euid) == ROOT_UID) {
+ if (setresuid(-1, ROOT_UID, -1)) {
+ sudo_warn("setresuid() [%d, %d, %d] -> [%d, %d, %d]",
+ (int)state->ruid, (int)state->euid, (int)state->suid,
+ -1, ROOT_UID, -1);
+ goto bad;
+ }
+ }
+ if (setresgid(OID(rgid), OID(egid), OID(sgid))) {
+ sudo_warn("setresgid() [%d, %d, %d] -> [%d, %d, %d]",
+ (int)state->rgid, (int)state->egid, (int)state->sgid,
+ (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
+ goto bad;
+ }
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
+ sudo_warn("setgroups()");
+ goto bad;
+ }
+ }
+ if (setresuid(OID(ruid), OID(euid), OID(suid))) {
+ sudo_warn("setresuid() [%d, %d, %d] -> [%d, %d, %d]",
+ (int)state->ruid, (int)state->euid, (int)state->suid,
+ (int)OID(ruid), (int)OID(euid), (int)OID(suid));
+ goto bad;
+ }
+ sudo_gidlist_delref(state->gidlist);
+ debug_return_bool(true);
+
+bad:
+ debug_return_bool(false);
+}
+
+#elif defined(_AIX) && defined(ID_SAVED)
+
+#define UID_CHANGED (state->ruid != ostate->ruid || state->euid != ostate->euid || state->suid != ostate->suid)
+#define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid || state->sgid != ostate->sgid)
+
+/*
+ * Set real and effective and saved uids and gids based on perm.
+ * We always retain a saved uid of 0 unless we are headed for an exec().
+ * We only flip the effective gid since it only changes for PERM_SUDOERS.
+ * This version of set_perms() works fine with the "stay_setuid" option.
+ */
+bool
+set_perms(int perm)
+{
+ struct perm_state *state, *ostate = NULL;
+ char errbuf[1024];
+ const char *errstr = errbuf;
+ debug_decl(set_perms, SUDOERS_DEBUG_PERMS)
+
+ if (perm_stack_depth == PERM_STACK_MAX) {
+ errstr = N_("perm stack overflow");
+ errno = EINVAL;
+ goto bad;
+ }
+
+ state = &perm_stack[perm_stack_depth];
+ if (perm != PERM_INITIAL) {
+ if (perm_stack_depth == 0) {
+ errstr = N_("perm stack underflow");
+ errno = EINVAL;
+ goto bad;
+ }
+ ostate = &perm_stack[perm_stack_depth - 1];
+ }
+
+ switch (perm) {
+ case PERM_INITIAL:
+ /* Stash initial state */
+ state->ruid = getuidx(ID_REAL);
+ state->euid = getuidx(ID_EFFECTIVE);
+ state->suid = getuidx(ID_SAVED);
+ state->rgid = getgidx(ID_REAL);
+ state->egid = getgidx(ID_EFFECTIVE);
+ state->sgid = getgidx(ID_SAVED);
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
+ "ruid: %d, euid: %d, suid: %d, rgid: %d, egid: %d, sgid: %d",
+ __func__, (int)state->ruid, (int)state->euid, (int)state->suid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ break;
+
+ case PERM_ROOT:
+ state->ruid = ROOT_UID;
+ state->euid = ROOT_UID;
+ state->suid = ROOT_UID;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (UID_CHANGED && setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_ROOT: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
+ ROOT_UID);
+ goto bad;
+ }
+ state->rgid = ostate->rgid;
+ state->egid = ROOT_GID;
+ state->sgid = ostate->sgid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: gid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ if (GID_CHANGED && setgidx(ID_EFFECTIVE, ROOT_GID)) {
+ errstr = N_("unable to change to root gid");
+ goto bad;
+ }
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ break;
+
+ case PERM_USER:
+ state->rgid = ostate->rgid;
+ state->egid = user_gid;
+ state->sgid = ostate->sgid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ if (GID_CHANGED && setgidx(ID_EFFECTIVE, user_gid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_USER: setgidx(ID_EFFECTIVE, %d)", (int)user_gid);
+ goto bad;
+ }
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
+ errstr = "PERM_USER: setgroups";
+ goto bad;
+ }
+ }
+ state->ruid = user_uid;
+ state->euid = user_uid;
+ state->suid = ROOT_UID;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (ostate->euid != ROOT_UID || ostate->suid != ROOT_UID) {
+ if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_USER: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
+ ROOT_UID);
+ goto bad;
+ }
+ }
+ if (setuidx(ID_EFFECTIVE|ID_REAL, user_uid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_USER: setuidx(ID_EFFECTIVE|ID_REAL, %d)", (int)user_uid);
+ goto bad;
+ }
+ break;
+
+ case PERM_FULL_USER:
+ /* headed for exec() */
+ state->rgid = user_gid;
+ state->egid = user_gid;
+ state->sgid = user_gid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ if (GID_CHANGED && setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, user_gid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_FULL_USER: setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
+ (int)user_gid);
+ goto bad;
+ }
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
+ errstr = "PERM_FULL_USER: setgroups";
+ goto bad;
+ }
+ }
+ state->ruid = user_uid;
+ state->euid = user_uid;
+ state->suid = user_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (UID_CHANGED && setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, user_uid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_FULL_USER: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
+ (int)user_uid);
+ goto bad;
+ }
+ break;
+
+ case PERM_RUNAS:
+ state->rgid = ostate->rgid;
+ state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
+ state->sgid = ostate->sgid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ if (GID_CHANGED && setgidx(ID_EFFECTIVE, state->egid)) {
+ errstr = N_("unable to change to runas gid");
+ goto bad;
+ }
+ state->gidlist = runas_setgroups();
+ if (state->gidlist == NULL) {
+ errstr = N_("unable to set runas group vector");
+ goto bad;
+ }
+ state->ruid = ostate->ruid;
+ state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
+ state->suid = ostate->suid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (UID_CHANGED && setuidx(ID_EFFECTIVE, state->euid)) {
+ errstr = N_("unable to change to runas uid");
+ goto bad;
+ }
+ break;
+
+ case PERM_SUDOERS:
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+
+ /* assume euid == ROOT_UID, ruid == user */
+ state->rgid = ostate->rgid;
+ state->egid = sudoers_gid;
+ state->sgid = ostate->sgid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ if (GID_CHANGED && setgidx(ID_EFFECTIVE, sudoers_gid)) {
+ errstr = N_("unable to change to sudoers gid");
+ goto bad;
+ }
+
+ state->ruid = ROOT_UID;
+ /*
+ * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
+ * we use a non-zero uid in order to avoid NFS lossage.
+ * Using uid 1 is a bit bogus but should work on all OS's.
+ */
+ if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP))
+ state->euid = 1;
+ else
+ state->euid = sudoers_uid;
+ state->suid = ROOT_UID;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (UID_CHANGED) {
+ if (ostate->ruid != ROOT_UID || ostate->suid != ROOT_UID) {
+ if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_SUDOERS: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
+ ROOT_UID);
+ goto bad;
+ }
+ }
+ if (setuidx(ID_EFFECTIVE, state->euid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_SUDOERS: setuidx(ID_EFFECTIVE, %d)", (int)sudoers_uid);
+ goto bad;
+ }
+ }
+ break;
+
+ case PERM_TIMESTAMP:
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ state->rgid = ostate->rgid;
+ state->egid = ostate->egid;
+ state->sgid = ostate->sgid;
+ state->ruid = ROOT_UID;
+ state->euid = timestamp_uid;
+ state->suid = ROOT_UID;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (UID_CHANGED) {
+ if (ostate->ruid != ROOT_UID || ostate->suid != ROOT_UID) {
+ if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_TIMESTAMP: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
+ ROOT_UID);
+ goto bad;
+ }
+ }
+ if (setuidx(ID_EFFECTIVE, timestamp_uid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_TIMESTAMP: setuidx(ID_EFFECTIVE, %d)",
+ (int)timestamp_uid);
+ goto bad;
+ }
+ }
+ break;
+
+ case PERM_IOLOG:
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ state->rgid = ostate->rgid;
+ state->egid = iolog_gid;
+ state->sgid = ostate->sgid;
+ state->ruid = ROOT_UID;
+ state->euid = iolog_uid;
+ state->suid = ROOT_UID;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_IOLOG: gid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
+ (int)state->rgid, (int)state->egid, (int)state->sgid);
+ if (GID_CHANGED && setgidx(ID_EFFECTIVE, iolog_gid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_IOLOG: setgidx(ID_EFFECTIVE, %d)", (int)iolog_gid);
+ goto bad;
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_IOLOG: uid: "
+ "[%d, %d, %d] -> [%d, %d, %d]", __func__,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
+ (int)state->ruid, (int)state->euid, (int)state->suid);
+ if (UID_CHANGED) {
+ if (ostate->ruid != ROOT_UID || ostate->suid != ROOT_UID) {
+ if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_IOLOG: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
+ ROOT_UID);
+ goto bad;
+ }
+ }
+ if (setuidx(ID_EFFECTIVE, timestamp_uid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_IOLOG: setuidx(ID_EFFECTIVE, %d)",
+ (int)timestamp_uid);
+ goto bad;
+ }
+ }
+ break;
+ }
+
+ perm_stack_depth++;
+ debug_return_bool(true);
+bad:
+ if (errno == EAGAIN)
+ sudo_warnx(U_("%s: %s"), U_(errstr), U_("too many processes"));
+ else
+ sudo_warn("%s", U_(errstr));
+ debug_return_bool(false);
+}
+
+bool
+restore_perms(void)
+{
+ struct perm_state *state, *ostate;
+ debug_decl(restore_perms, SUDOERS_DEBUG_PERMS)
+
+ if (perm_stack_depth < 2) {
+ sudo_warnx(U_("perm stack underflow"));
+ debug_return_bool(true);
+ }
+
+ state = &perm_stack[perm_stack_depth - 1];
+ ostate = &perm_stack[perm_stack_depth - 2];
+ perm_stack_depth--;
+
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d, %d] -> [%d, %d, %d]",
+ __func__, (int)state->ruid, (int)state->euid, (int)state->suid,
+ (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d, %d] -> [%d, %d, %d]",
+ __func__, (int)state->rgid, (int)state->egid, (int)state->sgid,
+ (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid);
+
+ if (OID(ruid) != (uid_t)-1 || OID(euid) != (uid_t)-1 || OID(suid) != (uid_t)-1) {
+ if (OID(euid) == ROOT_UID) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: setuidx(ID_EFFECTIVE, %d)",
+ __func__, ROOT_UID);
+ if (setuidx(ID_EFFECTIVE, ROOT_UID)) {
+ sudo_warn("setuidx(ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
+ (int)state->ruid, (int)state->euid, (int)state->suid,
+ -1, ROOT_UID, -1);
+ goto bad;
+ }
+ }
+ if (OID(ruid) == OID(euid) && OID(euid) == OID(suid)) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
+ __func__, (int)OID(ruid));
+ if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, OID(ruid))) {
+ sudo_warn("setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED) [%d, %d, %d] -> [%d, %d, %d]",
+ (int)state->ruid, (int)state->euid, (int)state->suid,
+ (int)OID(ruid), (int)OID(euid), (int)OID(suid));
+ goto bad;
+ }
+ } else if (OID(ruid) == (uid_t)-1 && OID(suid) == (uid_t)-1) {
+ /* May have already changed euid to ROOT_UID above. */
+ if (OID(euid) != ROOT_UID) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: setuidx(ID_EFFECTIVE, %d)", __func__, OID(euid));
+ if (setuidx(ID_EFFECTIVE, OID(euid))) {
+ sudo_warn("setuidx(ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
+ (int)state->ruid, (int)state->euid, (int)state->suid,
+ (int)OID(ruid), (int)OID(euid), (int)OID(suid));
+ goto bad;
+ }
+ }
+ } else if (OID(suid) == (uid_t)-1) {
+ /* Cannot set the real uid alone. */
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: setuidx(ID_REAL|ID_EFFECTIVE, %d)", __func__, OID(ruid));
+ if (setuidx(ID_REAL|ID_EFFECTIVE, OID(ruid))) {
+ sudo_warn("setuidx(ID_REAL|ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
+ (int)state->ruid, (int)state->euid, (int)state->suid,
+ (int)OID(ruid), (int)OID(euid), (int)OID(suid));
+ goto bad;
+ }
+ /* Restore the effective euid if it doesn't match the ruid. */
+ if (OID(euid) != OID(ruid)) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: setuidx(ID_EFFECTIVE, %d)", __func__, ostate->euid);
+ if (setuidx(ID_EFFECTIVE, ostate->euid)) {
+ sudo_warn("setuidx(ID_EFFECTIVE, %d)", (int)ostate->euid);
+ goto bad;
+ }
+ }
+ }
+ }
+ if (OID(rgid) != (gid_t)-1 || OID(egid) != (gid_t)-1 || OID(sgid) != (gid_t)-1) {
+ if (OID(rgid) == OID(egid) && OID(egid) == OID(sgid)) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
+ __func__, (int)OID(rgid));
+ if (setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, OID(rgid))) {
+ sudo_warn("setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED) [%d, %d, %d] -> [%d, %d, %d]",
+ (int)state->rgid, (int)state->egid, (int)state->sgid,
+ (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
+ goto bad;
+ }
+ } else if (OID(rgid) == (gid_t)-1 && OID(sgid) == (gid_t)-1) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: setgidx(ID_EFFECTIVE, %d)",
+ __func__, (int)OID(egid));
+ if (setgidx(ID_EFFECTIVE, OID(egid))) {
+ sudo_warn("setgidx(ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
+ (int)state->rgid, (int)state->egid, (int)state->sgid,
+ (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
+ goto bad;
+ }
+ } else if (OID(sgid) == (gid_t)-1) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: setgidx(ID_EFFECTIVE|ID_REAL, %d)", __func__, OID(rgid));
+ if (setgidx(ID_REAL|ID_EFFECTIVE, OID(rgid))) {
+ sudo_warn("setgidx(ID_REAL|ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
+ (int)state->rgid, (int)state->egid, (int)state->sgid,
+ (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
+ goto bad;
+ }
+ }
+ }
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
+ sudo_warn("setgroups()");
+ goto bad;
+ }
+ }
+ sudo_gidlist_delref(state->gidlist);
+ debug_return_bool(true);
+
+bad:
+ debug_return_bool(false);
+}
+
+#elif defined(HAVE_SETREUID)
+
+#define UID_CHANGED (state->ruid != ostate->ruid || state->euid != ostate->euid)
+#define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid)
+
+/*
+ * Set real and effective and saved uids and gids based on perm.
+ * We always retain a saved uid of 0 unless we are headed for an exec().
+ * We only flip the effective gid since it only changes for PERM_SUDOERS.
+ * This version of set_perms() works fine with the "stay_setuid" option.
+ */
+bool
+set_perms(int perm)
+{
+ struct perm_state *state, *ostate = NULL;
+ char errbuf[1024];
+ const char *errstr = errbuf;
+ debug_decl(set_perms, SUDOERS_DEBUG_PERMS)
+
+ if (perm_stack_depth == PERM_STACK_MAX) {
+ errstr = N_("perm stack overflow");
+ errno = EINVAL;
+ goto bad;
+ }
+
+ state = &perm_stack[perm_stack_depth];
+ if (perm != PERM_INITIAL) {
+ if (perm_stack_depth == 0) {
+ errstr = N_("perm stack underflow");
+ errno = EINVAL;
+ goto bad;
+ }
+ ostate = &perm_stack[perm_stack_depth - 1];
+ }
+
+ switch (perm) {
+ case PERM_INITIAL:
+ /* Stash initial state */
+ state->ruid = getuid();
+ state->euid = geteuid();
+ state->rgid = getgid();
+ state->egid = getegid();
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
+ "ruid: %d, euid: %d, rgid: %d, egid: %d", __func__,
+ (int)state->ruid, (int)state->euid,
+ (int)state->rgid, (int)state->egid);
+ break;
+
+ case PERM_ROOT:
+ state->ruid = ROOT_UID;
+ state->euid = ROOT_UID;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, (int)state->ruid, (int)state->euid);
+ /*
+ * setreuid(0, 0) may fail on some systems if euid is not already 0.
+ */
+ if (ostate->euid != ROOT_UID) {
+ if (setreuid(-1, ROOT_UID)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_ROOT: setreuid(-1, %d)", ROOT_UID);
+ goto bad;
+ }
+ }
+ if (ostate->ruid != ROOT_UID) {
+ if (setreuid(ROOT_UID, -1)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_ROOT: setreuid(%d, -1)", ROOT_UID);
+ goto bad;
+ }
+ }
+ state->rgid = ostate->rgid;
+ state->egid = ROOT_GID;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: gid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
+ (int)ostate->egid, (int)state->rgid, (int)state->egid);
+ if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_ROOT: setregid(%d, %d)", (int)ID(rgid), (int)ID(egid));
+ goto bad;
+ }
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ break;
+
+ case PERM_USER:
+ state->rgid = ostate->rgid;
+ state->egid = user_gid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
+ (int)ostate->egid, (int)state->rgid, (int)state->egid);
+ if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_USER: setregid(%d, %d)", (int)ID(rgid), (int)ID(egid));
+ goto bad;
+ }
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
+ errstr = "PERM_USER: setgroups";
+ goto bad;
+ }
+ }
+ state->ruid = ROOT_UID;
+ state->euid = user_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, (int)state->ruid, (int)state->euid);
+ if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_USER: setreuid(%d, %d)", (int)ID(ruid), (int)ID(euid));
+ goto bad;
+ }
+ break;
+
+ case PERM_FULL_USER:
+ /* headed for exec() */
+ state->rgid = user_gid;
+ state->egid = user_gid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
+ (int)ostate->egid, (int)state->rgid, (int)state->egid);
+ if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
+ snprintf(errbuf, sizeof(errbuf), "PERM_FULL_USER: setregid(%d, %d)",
+ (int)ID(rgid), (int)ID(egid));
+ goto bad;
+ }
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
+ errstr = "PERM_FULL_USER: setgroups";
+ goto bad;
+ }
+ }
+ state->ruid = user_uid;
+ state->euid = user_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, (int)state->ruid, (int)state->euid);
+ if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
+ snprintf(errbuf, sizeof(errbuf), "PERM_FULL_USER: setreuid(%d, %d)",
+ (int)ID(ruid), (int)ID(euid));
+ goto bad;
+ }
+ break;
+
+ case PERM_RUNAS:
+ state->rgid = ostate->rgid;
+ state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
+ (int)ostate->egid, (int)state->rgid, (int)state->egid);
+ if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
+ errstr = N_("unable to change to runas gid");
+ goto bad;
+ }
+ state->gidlist = runas_setgroups();
+ if (state->gidlist == NULL) {
+ errstr = N_("unable to set runas group vector");
+ goto bad;
+ }
+ state->ruid = ROOT_UID;
+ state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, (int)state->ruid, (int)state->euid);
+ if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
+ errstr = N_("unable to change to runas uid");
+ goto bad;
+ }
+ break;
+
+ case PERM_SUDOERS:
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+
+ /* assume euid == ROOT_UID, ruid == user */
+ state->rgid = ostate->rgid;
+ state->egid = sudoers_gid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
+ (int)ostate->egid, (int)state->rgid, (int)state->egid);
+ if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
+ errstr = N_("unable to change to sudoers gid");
+ goto bad;
+ }
+
+ state->ruid = ROOT_UID;
+ /*
+ * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
+ * we use a non-zero uid in order to avoid NFS lossage.
+ * Using uid 1 is a bit bogus but should work on all OS's.
+ */
+ if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP))
+ state->euid = 1;
+ else
+ state->euid = sudoers_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, (int)state->ruid, (int)state->euid);
+ if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
+ snprintf(errbuf, sizeof(errbuf), "PERM_SUDOERS: setreuid(%d, %d)",
+ (int)ID(ruid), (int)ID(euid));
+ goto bad;
+ }
+ break;
+
+ case PERM_TIMESTAMP:
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ state->rgid = ostate->rgid;
+ state->egid = ostate->egid;
+ state->ruid = ROOT_UID;
+ state->euid = timestamp_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, (int)state->ruid, (int)state->euid);
+ if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
+ snprintf(errbuf, sizeof(errbuf), "PERM_TIMESTAMP: setreuid(%d, %d)",
+ (int)ID(ruid), (int)ID(euid));
+ goto bad;
+ }
+ break;
+
+ case PERM_IOLOG:
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ state->rgid = ostate->rgid;
+ state->egid = iolog_gid;
+ state->ruid = ROOT_UID;
+ state->euid = iolog_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_IOLOG: gid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
+ (int)ostate->egid, (int)state->rgid, (int)state->egid);
+ if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
+ snprintf(errbuf, sizeof(errbuf), "PERM_IOLOG: setregid(%d, %d)",
+ (int)ID(rgid), (int)ID(egid));
+ goto bad;
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_IOLOG: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, (int)state->ruid, (int)state->euid);
+ if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
+ snprintf(errbuf, sizeof(errbuf), "PERM_IOLOG: setreuid(%d, %d)",
+ (int)ID(ruid), (int)ID(euid));
+ goto bad;
+ }
+ break;
+ }
+
+ perm_stack_depth++;
+ debug_return_bool(true);
+bad:
+ if (errno == EAGAIN)
+ sudo_warnx(U_("%s: %s"), U_(errstr), U_("too many processes"));
+ else
+ sudo_warn("%s", U_(errstr));
+ debug_return_bool(false);
+}
+
+bool
+restore_perms(void)
+{
+ struct perm_state *state, *ostate;
+ debug_decl(restore_perms, SUDOERS_DEBUG_PERMS)
+
+ if (perm_stack_depth < 2) {
+ sudo_warnx(U_("perm stack underflow"));
+ debug_return_bool(true);
+ }
+
+ state = &perm_stack[perm_stack_depth - 1];
+ ostate = &perm_stack[perm_stack_depth - 2];
+ perm_stack_depth--;
+
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d] -> [%d, %d]",
+ __func__, (int)state->ruid, (int)state->euid,
+ (int)ostate->ruid, (int)ostate->euid);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d] -> [%d, %d]",
+ __func__, (int)state->rgid, (int)state->egid,
+ (int)ostate->rgid, (int)ostate->egid);
+
+ /*
+ * When changing euid to ROOT_UID, setreuid() may fail even if
+ * the ruid is ROOT_UID so call setuid() first.
+ */
+ if (OID(euid) == ROOT_UID) {
+ /* setuid() may not set the saved ID unless the euid is ROOT_UID */
+ if (ID(euid) != ROOT_UID) {
+ if (setreuid(-1, ROOT_UID) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "setreuid() [%d, %d] -> [-1, %d)", (int)state->ruid,
+ (int)state->euid, ROOT_UID);
+ }
+ }
+ if (setuid(ROOT_UID)) {
+ sudo_warn("setuid() [%d, %d] -> %d)", (int)state->ruid,
+ (int)state->euid, ROOT_UID);
+ goto bad;
+ }
+ }
+ if (setreuid(OID(ruid), OID(euid))) {
+ sudo_warn("setreuid() [%d, %d] -> [%d, %d]", (int)state->ruid,
+ (int)state->euid, (int)OID(ruid), (int)OID(euid));
+ goto bad;
+ }
+ if (setregid(OID(rgid), OID(egid))) {
+ sudo_warn("setregid() [%d, %d] -> [%d, %d]", (int)state->rgid,
+ (int)state->egid, (int)OID(rgid), (int)OID(egid));
+ goto bad;
+ }
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
+ sudo_warn("setgroups()");
+ goto bad;
+ }
+ }
+ sudo_gidlist_delref(state->gidlist);
+ debug_return_bool(true);
+
+bad:
+ debug_return_bool(false);
+}
+
+#elif defined(HAVE_SETEUID)
+
+#define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid)
+
+/*
+ * Set real and effective uids and gids based on perm.
+ * We always retain a real or effective uid of ROOT_UID unless
+ * we are headed for an exec().
+ * This version of set_perms() works fine with the "stay_setuid" option.
+ */
+bool
+set_perms(int perm)
+{
+ struct perm_state *state, *ostate = NULL;
+ char errbuf[1024];
+ const char *errstr = errbuf;
+ debug_decl(set_perms, SUDOERS_DEBUG_PERMS)
+
+ if (perm_stack_depth == PERM_STACK_MAX) {
+ errstr = N_("perm stack overflow");
+ errno = EINVAL;
+ goto bad;
+ }
+
+ state = &perm_stack[perm_stack_depth];
+ if (perm != PERM_INITIAL) {
+ if (perm_stack_depth == 0) {
+ errstr = N_("perm stack underflow");
+ errno = EINVAL;
+ goto bad;
+ }
+ ostate = &perm_stack[perm_stack_depth - 1];
+ }
+
+ /*
+ * Since we only have setuid() and seteuid() and semantics
+ * for these calls differ on various systems, we set
+ * real and effective uids to ROOT_UID initially to be safe.
+ */
+ if (perm != PERM_INITIAL) {
+ if (ostate->euid != ROOT_UID && seteuid(ROOT_UID)) {
+ snprintf(errbuf, sizeof(errbuf), "set_perms: seteuid(%d)", ROOT_UID);
+ goto bad;
+ }
+ if (ostate->ruid != ROOT_UID && setuid(ROOT_UID)) {
+ snprintf(errbuf, sizeof(errbuf), "set_perms: setuid(%d)", ROOT_UID);
+ goto bad;
+ }
+ }
+
+ switch (perm) {
+ case PERM_INITIAL:
+ /* Stash initial state */
+ state->ruid = getuid();
+ state->euid = geteuid();
+ state->rgid = getgid();
+ state->egid = getegid();
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
+ "ruid: %d, euid: %d, rgid: %d, egid: %d", __func__,
+ (int)state->ruid, (int)state->euid,
+ (int)state->rgid, (int)state->egid);
+ break;
+
+ case PERM_ROOT:
+ /* We already set ruid/euid above. */
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, ROOT_UID, ROOT_UID);
+ state->ruid = ROOT_UID;
+ state->euid = ROOT_UID;
+ state->rgid = ostate->rgid;
+ state->egid = ROOT_GID;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: gid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
+ (int)ostate->egid, ROOT_GID, ROOT_GID);
+ if (GID_CHANGED && setegid(ROOT_GID)) {
+ errstr = N_("unable to change to root gid");
+ goto bad;
+ }
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ break;
+
+ case PERM_USER:
+ state->egid = user_gid;
+ state->rgid = ostate->rgid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
+ (int)ostate->egid, (int)state->rgid, (int)state->egid);
+ if (GID_CHANGED && setegid(user_gid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_USER: setegid(%d)", (int)user_gid);
+ goto bad;
+ }
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
+ errstr = "PERM_USER: setgroups";
+ goto bad;
+ }
+ }
+ state->ruid = ROOT_UID;
+ state->euid = user_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, (int)state->ruid, (int)state->euid);
+ if (seteuid(user_uid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_USER: seteuid(%d)", (int)user_uid);
+ goto bad;
+ }
+ break;
+
+ case PERM_FULL_USER:
+ /* headed for exec() */
+ state->rgid = user_gid;
+ state->egid = user_gid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
+ (int)ostate->egid, (int)state->rgid, (int)state->egid);
+ if (GID_CHANGED && setgid(user_gid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_FULL_USER: setgid(%d)", (int)user_gid);
+ goto bad;
+ }
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
+ errstr = "PERM_FULL_USER: setgroups";
+ goto bad;
+ }
+ }
+ state->ruid = user_uid;
+ state->euid = user_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, (int)state->ruid, (int)state->euid);
+ if (setuid(user_uid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_FULL_USER: setuid(%d)", (int)user_uid);
+ goto bad;
+ }
+ break;
+
+ case PERM_RUNAS:
+ state->rgid = ostate->rgid;
+ state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
+ (int)ostate->egid, (int)state->rgid, (int)state->egid);
+ if (GID_CHANGED && setegid(state->egid)) {
+ errstr = N_("unable to change to runas gid");
+ goto bad;
+ }
+ state->gidlist = runas_setgroups();
+ if (state->gidlist == NULL) {
+ errstr = N_("unable to set runas group vector");
+ goto bad;
+ }
+ state->ruid = ostate->ruid;
+ state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, (int)state->ruid, (int)state->euid);
+ if (seteuid(state->euid)) {
+ errstr = N_("unable to change to runas uid");
+ goto bad;
+ }
+ break;
+
+ case PERM_SUDOERS:
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+
+ /* assume euid == ROOT_UID, ruid == user */
+ state->rgid = ostate->rgid;
+ state->egid = sudoers_gid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
+ (int)ostate->egid, (int)state->rgid, (int)state->egid);
+ if (GID_CHANGED && setegid(sudoers_gid)) {
+ errstr = N_("unable to change to sudoers gid");
+ goto bad;
+ }
+
+ state->ruid = ROOT_UID;
+ /*
+ * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
+ * we use a non-zero uid in order to avoid NFS lossage.
+ * Using uid 1 is a bit bogus but should work on all OS's.
+ */
+ if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP))
+ state->euid = 1;
+ else
+ state->euid = sudoers_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, (int)state->ruid, (int)state->euid);
+ if (seteuid(state->euid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_SUDOERS: seteuid(%d)", (int)state->euid);
+ goto bad;
+ }
+ break;
+
+ case PERM_TIMESTAMP:
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ state->rgid = ostate->rgid;
+ state->egid = ostate->egid;
+ state->ruid = ROOT_UID;
+ state->euid = timestamp_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, (int)state->ruid, (int)state->euid);
+ if (seteuid(timestamp_uid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_TIMESTAMP: seteuid(%d)", (int)timestamp_uid);
+ goto bad;
+ }
+ break;
+
+ case PERM_IOLOG:
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ state->rgid = ostate->rgid;
+ state->egid = iolog_gid;
+ state->ruid = ROOT_UID;
+ state->euid = iolog_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_IOLOG: gid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
+ (int)ostate->egid, (int)state->rgid, (int)state->egid);
+ if (GID_CHANGED && setegid(iolog_gid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_IOLOG: setegid(%d)", (int)iolog_gid);
+ goto bad;
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_IOLOG: uid: "
+ "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
+ (int)ostate->euid, (int)state->ruid, (int)state->euid);
+ if (seteuid(timestamp_uid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_IOLOG: seteuid(%d)", (int)timestamp_uid);
+ goto bad;
+ }
+ break;
+ }
+
+ perm_stack_depth++;
+ debug_return_bool(true);
+bad:
+ if (errno == EAGAIN)
+ sudo_warnx(U_("%s: %s"), U_(errstr), U_("too many processes"));
+ else
+ sudo_warn("%s", U_(errstr));
+ debug_return_bool(false);
+}
+
+bool
+restore_perms(void)
+{
+ struct perm_state *state, *ostate;
+ debug_decl(restore_perms, SUDOERS_DEBUG_PERMS)
+
+ if (perm_stack_depth < 2) {
+ sudo_warnx(U_("perm stack underflow"));
+ debug_return_bool(true);
+ }
+
+ state = &perm_stack[perm_stack_depth - 1];
+ ostate = &perm_stack[perm_stack_depth - 2];
+ perm_stack_depth--;
+
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d] -> [%d, %d]",
+ __func__, (int)state->ruid, (int)state->euid,
+ (int)ostate->ruid, (int)ostate->euid);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d] -> [%d, %d]",
+ __func__, (int)state->rgid, (int)state->egid,
+ (int)ostate->rgid, (int)ostate->egid);
+
+ /*
+ * Since we only have setuid() and seteuid() and semantics
+ * for these calls differ on various systems, we set
+ * real and effective uids to ROOT_UID initially to be safe.
+ */
+ if (seteuid(ROOT_UID)) {
+ sudo_warnx("seteuid() [%d] -> [%d]", (int)state->euid, ROOT_UID);
+ goto bad;
+ }
+ if (setuid(ROOT_UID)) {
+ sudo_warnx("setuid() [%d, %d] -> [%d, %d]", (int)state->ruid, ROOT_UID,
+ ROOT_UID, ROOT_UID);
+ goto bad;
+ }
+
+ if (OID(egid) != (gid_t)-1 && setegid(ostate->egid)) {
+ sudo_warn("setegid(%d)", (int)ostate->egid);
+ goto bad;
+ }
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
+ sudo_warn("setgroups()");
+ goto bad;
+ }
+ }
+ if (OID(euid) != (uid_t)-1 && seteuid(ostate->euid)) {
+ sudo_warn("seteuid(%d)", (int)ostate->euid);
+ goto bad;
+ }
+ sudo_gidlist_delref(state->gidlist);
+ debug_return_bool(true);
+
+bad:
+ debug_return_bool(false);
+}
+
+#else /* !HAVE_SETRESUID && !HAVE_SETREUID && !HAVE_SETEUID */
+
+/*
+ * Set uids and gids based on perm via setuid() and setgid().
+ * NOTE: does not support the "stay_setuid" or timestampowner options.
+ * Also, sudoers_uid and sudoers_gid are not used.
+ */
+bool
+set_perms(int perm)
+{
+ struct perm_state *state, *ostate = NULL;
+ char errbuf[1024];
+ const char *errstr = errbuf;
+ debug_decl(set_perms, SUDOERS_DEBUG_PERMS)
+
+ if (perm_stack_depth == PERM_STACK_MAX) {
+ errstr = N_("perm stack overflow");
+ errno = EINVAL;
+ goto bad;
+ }
+
+ state = &perm_stack[perm_stack_depth];
+ if (perm != PERM_INITIAL) {
+ if (perm_stack_depth == 0) {
+ errstr = N_("perm stack underflow");
+ errno = EINVAL;
+ goto bad;
+ }
+ ostate = &perm_stack[perm_stack_depth - 1];
+ }
+
+ switch (perm) {
+ case PERM_INITIAL:
+ /* Stash initial state */
+ state->ruid = geteuid() == ROOT_UID ? ROOT_UID : getuid();
+ state->rgid = getgid();
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
+ "ruid: %d, rgid: %d", __func__, (int)state->ruid, (int)state->rgid);
+ break;
+
+ case PERM_ROOT:
+ state->ruid = ROOT_UID;
+ state->rgid = ROOT_GID;
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
+ "[%d] -> [%d]", __func__, (int)ostate->ruid, (int)state->ruid);
+ if (setuid(ROOT_UID)) {
+ snprintf(errbuf, sizeof(errbuf), "PERM_ROOT: setuid(%d)", ROOT_UID);
+ goto bad;
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: gid: "
+ "[%d] -> [%d]", __func__, (int)ostate->rgid, (int)state->rgid);
+ if (setgid(ROOT_GID)) {
+ errstr = N_("unable to change to root gid");
+ goto bad;
+ }
+ break;
+
+ case PERM_FULL_USER:
+ state->rgid = user_gid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
+ "[%d] -> [%d]", __func__, (int)ostate->rgid, (int)state->rgid);
+ (void) setgid(user_gid);
+ state->gidlist = user_gid_list;
+ sudo_gidlist_addref(state->gidlist);
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
+ errstr = "PERM_FULL_USER: setgroups";
+ goto bad;
+ }
+ }
+ state->ruid = user_uid;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
+ "[%d] -> [%d]", __func__, (int)ostate->ruid, (int)state->ruid);
+ if (setuid(user_uid)) {
+ snprintf(errbuf, sizeof(errbuf),
+ "PERM_FULL_USER: setuid(%d)", (int)user_uid);
+ goto bad;
+ }
+ break;
+
+ case PERM_USER:
+ case PERM_SUDOERS:
+ case PERM_RUNAS:
+ case PERM_TIMESTAMP:
+ case PERM_IOLOG:
+ /* Unsupported since we can't set euid. */
+ state->ruid = ostate->ruid;
+ state->rgid = ostate->rgid;
+ state->gidlist = ostate->gidlist;
+ sudo_gidlist_addref(state->gidlist);
+ break;
+ }
+
+ perm_stack_depth++;
+ debug_return_bool(true);
+bad:
+ if (errno == EAGAIN)
+ sudo_warnx(U_("%s: %s"), U_(errstr), U_("too many processes"));
+ else
+ sudo_warn("%s", U_(errstr));
+ debug_return_bool(false);
+}
+
+boll
+restore_perms(void)
+{
+ struct perm_state *state, *ostate;
+ debug_decl(restore_perms, SUDOERS_DEBUG_PERMS)
+
+ if (perm_stack_depth < 2) {
+ sudo_warnx(U_("perm stack underflow"));
+ debug_return_bool(true);
+ }
+
+ state = &perm_stack[perm_stack_depth - 1];
+ ostate = &perm_stack[perm_stack_depth - 2];
+ perm_stack_depth--;
+
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d] -> [%d]",
+ __func__, (int)state->ruid, (int)ostate->ruid);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d] -> [%d]",
+ __func__, (int)state->rgid, (int)ostate->rgid);
+
+ if (OID(rgid) != (gid_t)-1 && setgid(ostate->rgid)) {
+ sudo_warn("setgid(%d)", (int)ostate->rgid);
+ goto bad;
+ }
+ if (state->gidlist != ostate->gidlist) {
+ if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
+ sudo_warn("setgroups()");
+ goto bad;
+ }
+ }
+ sudo_gidlist_delref(state->gidlist);
+ if (OID(ruid) != (uid_t)-1 && setuid(ostate->ruid)) {
+ sudo_warn("setuid(%d)", (int)ostate->ruid);
+ goto bad;
+ }
+ debug_return_bool(true);
+
+bad:
+ debug_return_bool(false);
+}
+#endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
+
+#if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
+static struct gid_list *
+runas_setgroups(void)
+{
+ struct gid_list *gidlist;
+ debug_decl(runas_setgroups, SUDOERS_DEBUG_PERMS)
+
+ gidlist = runas_getgroups();
+ if (gidlist != NULL && !def_preserve_groups) {
+ if (sudo_setgroups(gidlist->ngids, gidlist->gids) < 0) {
+ sudo_gidlist_delref(gidlist);
+ gidlist = NULL;
+ }
+ }
+ debug_return_ptr(gidlist);
+}
+#endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
diff --git a/plugins/sudoers/solaris_audit.c b/plugins/sudoers/solaris_audit.c
new file mode 100644
index 0000000..650595a
--- /dev/null
+++ b/plugins/sudoers/solaris_audit.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_SOLARIS_AUDIT
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <bsm/adt.h>
+#include <bsm/adt_event.h>
+
+#include "sudoers.h"
+#include "solaris_audit.h"
+
+static adt_session_data_t *ah; /* audit session handle */
+static adt_event_data_t *event; /* event to be generated */
+static char cwd[PATH_MAX];
+static char cmdpath[PATH_MAX];
+
+static int
+adt_sudo_common(int argc, char *argv[])
+{
+ if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) {
+ log_warning(SLOG_NO_STDERR, "adt_start_session");
+ return -1;
+ }
+ if ((event = adt_alloc_event(ah, ADT_sudo)) == NULL) {
+ log_warning(SLOG_NO_STDERR, "alloc_event");
+ (void) adt_end_session(ah);
+ return -1;
+ }
+ if ((event->adt_sudo.cwdpath = getcwd(cwd, sizeof(cwd))) == NULL) {
+ log_warning(SLOG_NO_STDERR, _("unable to get current working directory"));
+ }
+
+ /* get the real executable name */
+ if (user_cmnd != NULL) {
+ if (strlcpy(cmdpath, (const char *)user_cmnd,
+ sizeof(cmdpath)) >= sizeof(cmdpath)) {
+ log_warningx(SLOG_NO_STDERR,
+ _("truncated audit path user_cmnd: %s"),
+ user_cmnd);
+ }
+ } else {
+ if (strlcpy(cmdpath, (const char *)argv[0],
+ sizeof(cmdpath)) >= sizeof(cmdpath)) {
+ log_warningx(SLOG_NO_STDERR,
+ _("truncated audit path argv[0]: %s"),
+ argv[0]);
+ }
+ }
+
+ event->adt_sudo.cmdpath = cmdpath;
+ event->adt_sudo.argc = argc - 1;
+ event->adt_sudo.argv = &argv[1];
+ event->adt_sudo.envp = env_get();
+
+ return 0;
+}
+
+
+/*
+ * Returns 0 on success or -1 on error.
+ */
+int
+solaris_audit_success(int argc, char *argv[])
+{
+ int rc = -1;
+
+ if (adt_sudo_common(argc, argv) != 0) {
+ return -1;
+ }
+ if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
+ log_warning(SLOG_NO_STDERR, "adt_put_event(ADT_SUCCESS)");
+ } else {
+ rc = 0;
+ }
+ adt_free_event(event);
+ (void) adt_end_session(ah);
+
+ return rc;
+}
+
+/*
+ * Returns 0 on success or -1 on error.
+ */
+int
+solaris_audit_failure(int argc, char *argv[], char const *const fmt, va_list ap)
+{
+ int rc = -1;
+
+ if (adt_sudo_common(argc, argv) != 0) {
+ return -1;
+ }
+ if (vasprintf(&event->adt_sudo.errmsg, fmt, ap) == -1) {
+ log_warning(SLOG_NO_STDERR,
+ _("audit_failure message too long"));
+ }
+ if (adt_put_event(event, ADT_FAILURE, ADT_FAIL_VALUE_PROGRAM) != 0) {
+ log_warning(SLOG_NO_STDERR, "adt_put_event(ADT_FAILURE)");
+ } else {
+ rc = 0;
+ }
+ free(event->adt_sudo.errmsg);
+ adt_free_event(event);
+ (void) adt_end_session(ah);
+
+ return 0;
+}
+
+#endif /* HAVE_SOLARIS_AUDIT */
diff --git a/plugins/sudoers/solaris_audit.h b/plugins/sudoers/solaris_audit.h
new file mode 100644
index 0000000..36a1245
--- /dev/null
+++ b/plugins/sudoers/solaris_audit.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_SOLARIS_AUDIT_H
+#define SUDOERS_SOLARIS_AUDIT_H
+
+int solaris_audit_success(int argc, char *argv[]);
+int solaris_audit_failure(int argc, char *argv[], char const *const fmt, va_list);
+
+#endif /* SUDOERS_SOLARIS_AUDIT_H */
diff --git a/plugins/sudoers/sssd.c b/plugins/sudoers/sssd.c
new file mode 100644
index 0000000..085549f
--- /dev/null
+++ b/plugins/sudoers/sssd.c
@@ -0,0 +1,790 @@
+/*
+ * Copyright (c) 2003-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ * Copyright (c) 2011 Daniel Kopecek <dkopecek@redhat.com>
+ *
+ * This code is derived from software contributed by Aaron Spangler.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_SSSD
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <time.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include <errno.h>
+#include <stdint.h>
+
+#include "sudoers.h"
+#include "gram.h"
+#include "sudo_lbuf.h"
+#include "sudo_ldap.h"
+#include "sudo_dso.h"
+
+/* SSSD <--> SUDO interface - do not change */
+struct sss_sudo_attr {
+ char *name;
+ char **values;
+ unsigned int num_values;
+};
+
+struct sss_sudo_rule {
+ unsigned int num_attrs;
+ struct sss_sudo_attr *attrs;
+};
+
+struct sss_sudo_result {
+ unsigned int num_rules;
+ struct sss_sudo_rule *rules;
+};
+
+typedef int (*sss_sudo_send_recv_t)(uid_t, const char*, const char*,
+ uint32_t*, struct sss_sudo_result**);
+
+typedef int (*sss_sudo_send_recv_defaults_t)(uid_t, const char*, uint32_t*,
+ char**, struct sss_sudo_result**);
+
+typedef void (*sss_sudo_free_result_t)(struct sss_sudo_result*);
+
+typedef int (*sss_sudo_get_values_t)(struct sss_sudo_rule*, const char*,
+ char***);
+
+typedef void (*sss_sudo_free_values_t)(char**);
+
+/* sudo_nss handle */
+struct sudo_sss_handle {
+ char *domainname;
+ char *ipa_host;
+ char *ipa_shost;
+ struct passwd *pw;
+ void *ssslib;
+ struct sudoers_parse_tree parse_tree;
+ sss_sudo_send_recv_t fn_send_recv;
+ sss_sudo_send_recv_defaults_t fn_send_recv_defaults;
+ sss_sudo_free_result_t fn_free_result;
+ sss_sudo_get_values_t fn_get_values;
+ sss_sudo_free_values_t fn_free_values;
+};
+
+static int
+get_ipa_hostname(char **shostp, char **lhostp)
+{
+ size_t linesize = 0;
+ char *lhost = NULL;
+ char *shost = NULL;
+ char *line = NULL;
+ int ret = false;
+ ssize_t len;
+ FILE *fp;
+ debug_decl(get_ipa_hostname, SUDOERS_DEBUG_SSSD)
+
+ fp = fopen(_PATH_SSSD_CONF, "r");
+ if (fp != NULL) {
+ while ((len = getline(&line, &linesize, fp)) != -1) {
+ char *cp = line;
+
+ /* Trim trailing and leading spaces. */
+ while (len > 0 && isspace((unsigned char)line[len - 1]))
+ line[--len] = '\0';
+ while (isspace((unsigned char)*cp))
+ cp++;
+
+ /*
+ * Match ipa_hostname = foo
+ * Note: currently ignores the domain (XXX)
+ */
+ if (strncmp(cp, "ipa_hostname", 12) == 0) {
+ cp += 12;
+ /* Trim " = " after "ipa_hostname" */
+ while (isblank((unsigned char)*cp))
+ cp++;
+ if (*cp++ != '=')
+ continue;
+ while (isblank((unsigned char)*cp))
+ cp++;
+ /* Ignore empty value */
+ if (*cp == '\0')
+ continue;
+ lhost = strdup(cp);
+ if (lhost != NULL && (cp = strchr(lhost, '.')) != NULL) {
+ shost = strndup(lhost, (size_t)(cp - lhost));
+ } else {
+ shost = lhost;
+ }
+ if (shost != NULL && lhost != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "ipa_hostname %s overrides %s", lhost, user_host);
+ *shostp = shost;
+ *lhostp = lhost;
+ ret = true;
+ } else {
+ sudo_warnx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ free(shost);
+ free(lhost);
+ ret = -1;
+ }
+ break;
+ }
+ }
+ fclose(fp);
+ free(line);
+ }
+ debug_return_int(ret);
+}
+
+/*
+ * SSSD doesn't handle netgroups, we have to ensure they are correctly filtered
+ * in sudo. The rules may contain mixed sudoUser specification so we have to
+ * check not only for netgroup membership but also for user and group matches.
+ * Otherwise, a netgroup non-match could override a user/group match.
+ */
+static bool
+sudo_sss_check_user(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
+{
+ const char *host = handle->ipa_host ? handle->ipa_host : user_runhost;
+ const char *shost = handle->ipa_shost ? handle->ipa_shost : user_srunhost;
+ char **val_array;
+ int i, ret = false;
+ debug_decl(sudo_sss_check_user, SUDOERS_DEBUG_SSSD);
+
+ if (rule == NULL)
+ debug_return_bool(false);
+
+ switch (handle->fn_get_values(rule, "sudoUser", &val_array)) {
+ case 0:
+ break;
+ case ENOENT:
+ sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
+ debug_return_bool(false);
+ default:
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "handle->fn_get_values(sudoUser): != 0");
+ debug_return_bool(false);
+ }
+
+ /* Walk through sudoUser values. */
+ for (i = 0; val_array[i] != NULL && !ret; ++i) {
+ const char *val = val_array[i];
+
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val);
+ switch (*val) {
+ case '+':
+ /* Netgroup spec found, check membership. */
+ if (netgr_matches(val, def_netgroup_tuple ? host : NULL,
+ def_netgroup_tuple ? shost : NULL, handle->pw->pw_name)) {
+ ret = true;
+ }
+ break;
+ case '%':
+ /* User group found, check membership. */
+ if (usergr_matches(val, handle->pw->pw_name, handle->pw)) {
+ ret = true;
+ }
+ break;
+ default:
+ /* Not a netgroup or user group. */
+ if (strcmp(val, "ALL") == 0 ||
+ userpw_matches(val, handle->pw->pw_name, handle->pw)) {
+ ret = true;
+ }
+ break;
+ }
+ sudo_debug_printf(SUDO_DEBUG_DIAG,
+ "sssd/ldap sudoUser '%s' ... %s (%s)", val,
+ ret ? "MATCH!" : "not", handle->pw->pw_name);
+ }
+ handle->fn_free_values(val_array);
+ debug_return_bool(ret);
+}
+
+static char *
+val_array_iter(void **vp)
+{
+ char **val_array = *vp;
+
+ *vp = val_array + 1;
+
+ return *val_array;
+}
+
+static bool
+sss_to_sudoers(struct sudo_sss_handle *handle,
+ struct sss_sudo_result *sss_result)
+{
+ struct userspec *us;
+ struct member *m;
+ unsigned int i;
+ debug_decl(sss_to_sudoers, SUDOERS_DEBUG_SSSD)
+
+ /* We only have a single userspec */
+ if ((us = calloc(1, sizeof(*us))) == NULL)
+ goto oom;
+ TAILQ_INIT(&us->users);
+ TAILQ_INIT(&us->privileges);
+ STAILQ_INIT(&us->comments);
+ TAILQ_INSERT_TAIL(&handle->parse_tree.userspecs, us, entries);
+
+ /* We only include rules where the user matches. */
+ if ((m = calloc(1, sizeof(*m))) == NULL)
+ goto oom;
+ m->type = ALL;
+ TAILQ_INSERT_TAIL(&us->users, m, entries);
+
+ /*
+ * Treat each sudoRole as a separate privilege.
+ *
+ * Sssd has already sorted the rules in descending order.
+ * The conversion to a sudoers parse tree requires that entries be
+ * in *ascending* order so we we iterate from last to first.
+ */
+ for (i = sss_result->num_rules; i-- > 0; ) {
+ struct sss_sudo_rule *rule = sss_result->rules + i;
+ char **cmnds, **runasusers = NULL, **runasgroups = NULL;
+ char **opts = NULL, **notbefore = NULL, **notafter = NULL;
+ char **hosts = NULL, **cn_array = NULL, *cn = NULL;
+ struct privilege *priv = NULL;
+
+ /*
+ * We don't know whether a rule was included due to a user/group
+ * match or because it contained a netgroup.
+ */
+ if (!sudo_sss_check_user(handle, rule))
+ continue;
+
+ switch (handle->fn_get_values(rule, "sudoCommand", &cmnds)) {
+ case 0:
+ break;
+ case ENOENT:
+ /* Ignore sudoRole without sudoCommand. */
+ continue;
+ default:
+ goto cleanup;
+ }
+
+ /* Get the entry's dn for long format printing. */
+ switch (handle->fn_get_values(rule, "cn", &cn_array)) {
+ case 0:
+ cn = cn_array[0];
+ break;
+ case ENOENT:
+ break;
+ default:
+ goto cleanup;
+ }
+
+ /* Get sudoHost */
+ switch (handle->fn_get_values(rule, "sudoHost", &hosts)) {
+ case 0:
+ case ENOENT:
+ break;
+ default:
+ goto cleanup;
+ }
+
+ /* Get sudoRunAsUser / sudoRunAs */
+ switch (handle->fn_get_values(rule, "sudoRunAsUser", &runasusers)) {
+ case 0:
+ break;
+ case ENOENT:
+ switch (handle->fn_get_values(rule, "sudoRunAs", &runasusers)) {
+ case 0:
+ case ENOENT:
+ break;
+ default:
+ goto cleanup;
+ }
+ break;
+ default:
+ goto cleanup;
+ }
+
+ /* Get sudoRunAsGroup */
+ switch (handle->fn_get_values(rule, "sudoRunAsGroup", &runasgroups)) {
+ case 0:
+ case ENOENT:
+ break;
+ default:
+ goto cleanup;
+ }
+
+ /* Get sudoNotBefore */
+ switch (handle->fn_get_values(rule, "sudoNotBefore", &notbefore)) {
+ case 0:
+ case ENOENT:
+ break;
+ default:
+ goto cleanup;
+ }
+
+ /* Get sudoNotAfter */
+ switch (handle->fn_get_values(rule, "sudoNotAfter", &notafter)) {
+ case 0:
+ case ENOENT:
+ break;
+ default:
+ goto cleanup;
+ }
+
+ /* Parse sudoOptions. */
+ switch (handle->fn_get_values(rule, "sudoOption", &opts)) {
+ case 0:
+ case ENOENT:
+ break;
+ default:
+ goto cleanup;
+ }
+
+ priv = sudo_ldap_role_to_priv(cn, hosts, runasusers, runasgroups,
+ cmnds, opts, notbefore ? notbefore[0] : NULL,
+ notafter ? notafter[0] : NULL, false, true, val_array_iter);
+
+ cleanup:
+ if (cn_array != NULL)
+ handle->fn_free_values(cn_array);
+ if (cmnds != NULL)
+ handle->fn_free_values(cmnds);
+ if (hosts != NULL)
+ handle->fn_free_values(hosts);
+ if (runasusers != NULL)
+ handle->fn_free_values(runasusers);
+ if (runasgroups != NULL)
+ handle->fn_free_values(runasgroups);
+ if (opts != NULL)
+ handle->fn_free_values(opts);
+ if (notbefore != NULL)
+ handle->fn_free_values(notbefore);
+ if (notafter != NULL)
+ handle->fn_free_values(notafter);
+
+ if (priv == NULL)
+ goto oom;
+ TAILQ_INSERT_TAIL(&us->privileges, priv, entries);
+ }
+
+ debug_return_bool(true);
+
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ free_userspecs(&handle->parse_tree.userspecs);
+ debug_return_bool(false);
+}
+
+static bool
+sudo_sss_parse_options(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule, struct defaults_list *defs)
+{
+ int i;
+ char *source = NULL;
+ bool ret = false;
+ char **val_array = NULL;
+ char **cn_array = NULL;
+ debug_decl(sudo_sss_parse_options, SUDOERS_DEBUG_SSSD);
+
+ if (rule == NULL)
+ debug_return_bool(true);
+
+ switch (handle->fn_get_values(rule, "sudoOption", &val_array)) {
+ case 0:
+ break;
+ case ENOENT:
+ sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
+ debug_return_bool(true);
+ case ENOMEM:
+ goto oom;
+ default:
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "handle->fn_get_values(sudoOption): != 0");
+ debug_return_bool(false);
+ }
+
+ /* Use sudoRole in place of file name in defaults. */
+ if (handle->fn_get_values(rule, "cn", &cn_array) == 0) {
+ if (cn_array[0] != NULL) {
+ char *cp;
+ if (asprintf(&cp, "sudoRole %s", cn_array[0]) == -1)
+ goto oom;
+ source = rcstr_dup(cp);
+ free(cp);
+ if (source == NULL)
+ goto oom;
+ }
+ handle->fn_free_values(cn_array);
+ cn_array = NULL;
+ }
+ if (source == NULL) {
+ if ((source = rcstr_dup("sudoRole UNKNOWN")) == NULL)
+ goto oom;
+ }
+
+ /* Walk through options, appending to defs. */
+ for (i = 0; val_array[i] != NULL; i++) {
+ char *var, *val;
+ int op;
+
+ op = sudo_ldap_parse_option(val_array[i], &var, &val);
+ if (!sudo_ldap_add_default(var, val, op, source, defs))
+ goto oom;
+ }
+ ret = true;
+ goto done;
+
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+done:
+ rcstr_delref(source);
+ handle->fn_free_values(val_array);
+ debug_return_bool(ret);
+}
+
+static struct sss_sudo_result *
+sudo_sss_result_get(struct sudo_nss *nss, struct passwd *pw)
+{
+ struct sudo_sss_handle *handle = nss->handle;
+ struct sss_sudo_result *sss_result = NULL;
+ uint32_t sss_error = 0, rc;
+ debug_decl(sudo_sss_result_get, SUDOERS_DEBUG_SSSD);
+
+ sudo_debug_printf(SUDO_DEBUG_DIAG, " username=%s", pw->pw_name);
+ sudo_debug_printf(SUDO_DEBUG_DIAG, "domainname=%s",
+ handle->domainname ? handle->domainname : "NULL");
+
+ rc = handle->fn_send_recv(pw->pw_uid, pw->pw_name,
+ handle->domainname, &sss_error, &sss_result);
+ switch (rc) {
+ case 0:
+ switch (sss_error) {
+ case 0:
+ if (sss_result != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "Received %u rule(s)",
+ sss_result->num_rules);
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "Internal error: sss_result == NULL && sss_error == 0");
+ debug_return_ptr(NULL);
+ }
+ break;
+ case ENOENT:
+ sudo_debug_printf(SUDO_DEBUG_INFO, "The user was not found in SSSD.");
+ debug_return_ptr(NULL);
+ default:
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "sss_error=%u\n", sss_error);
+ debug_return_ptr(NULL);
+ }
+ break;
+ case ENOMEM:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ /* FALLTHROUGH */
+ default:
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "handle->fn_send_recv: rc=%d", rc);
+ debug_return_ptr(NULL);
+ }
+
+ debug_return_ptr(sss_result);
+}
+
+/* sudo_nss implementation */
+static int
+sudo_sss_close(struct sudo_nss *nss)
+{
+ struct sudo_sss_handle *handle = nss->handle;
+ debug_decl(sudo_sss_close, SUDOERS_DEBUG_SSSD);
+
+ if (handle != NULL) {
+ sudo_dso_unload(handle->ssslib);
+ if (handle->pw != NULL)
+ sudo_pw_delref(handle->pw);
+ free(handle->ipa_host);
+ if (handle->ipa_host != handle->ipa_shost)
+ free(handle->ipa_shost);
+ free_parse_tree(&handle->parse_tree);
+ free(handle);
+ nss->handle = NULL;
+ }
+ debug_return_int(0);
+}
+
+static int
+sudo_sss_open(struct sudo_nss *nss)
+{
+ struct sudo_sss_handle *handle;
+ static const char path[] = _PATH_SSSD_LIB"/libsss_sudo.so";
+ debug_decl(sudo_sss_open, SUDOERS_DEBUG_SSSD);
+
+ if (nss->handle != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "%s: called with non-NULL handle %p", __func__, nss->handle);
+ sudo_sss_close(nss);
+ }
+
+ /* Create a handle container. */
+ handle = calloc(1, sizeof(struct sudo_sss_handle));
+ if (handle == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(ENOMEM);
+ }
+ init_parse_tree(&handle->parse_tree);
+
+ /* Load symbols */
+ handle->ssslib = sudo_dso_load(path, SUDO_DSO_LAZY);
+ if (handle->ssslib == NULL) {
+ const char *errstr = sudo_dso_strerror();
+ sudo_warnx(U_("unable to load %s: %s"), path,
+ errstr ? errstr : "unknown error");
+ sudo_warnx(U_("unable to initialize SSS source. Is SSSD installed on your machine?"));
+ free(handle);
+ debug_return_int(EFAULT);
+ }
+
+ handle->fn_send_recv =
+ sudo_dso_findsym(handle->ssslib, "sss_sudo_send_recv");
+ if (handle->fn_send_recv == NULL) {
+ sudo_warnx(U_("unable to find symbol \"%s\" in %s"), path,
+ "sss_sudo_send_recv");
+ free(handle);
+ debug_return_int(EFAULT);
+ }
+
+ handle->fn_send_recv_defaults =
+ sudo_dso_findsym(handle->ssslib, "sss_sudo_send_recv_defaults");
+ if (handle->fn_send_recv_defaults == NULL) {
+ sudo_warnx(U_("unable to find symbol \"%s\" in %s"), path,
+ "sss_sudo_send_recv_defaults");
+ free(handle);
+ debug_return_int(EFAULT);
+ }
+
+ handle->fn_free_result =
+ sudo_dso_findsym(handle->ssslib, "sss_sudo_free_result");
+ if (handle->fn_free_result == NULL) {
+ sudo_warnx(U_("unable to find symbol \"%s\" in %s"), path,
+ "sss_sudo_free_result");
+ free(handle);
+ debug_return_int(EFAULT);
+ }
+
+ handle->fn_get_values =
+ sudo_dso_findsym(handle->ssslib, "sss_sudo_get_values");
+ if (handle->fn_get_values == NULL) {
+ sudo_warnx(U_("unable to find symbol \"%s\" in %s"), path,
+ "sss_sudo_get_values");
+ free(handle);
+ debug_return_int(EFAULT);
+ }
+
+ handle->fn_free_values =
+ sudo_dso_findsym(handle->ssslib, "sss_sudo_free_values");
+ if (handle->fn_free_values == NULL) {
+ sudo_warnx(U_("unable to find symbol \"%s\" in %s"), path,
+ "sss_sudo_free_values");
+ free(handle);
+ debug_return_int(EFAULT);
+ }
+
+ nss->handle = handle;
+
+ /*
+ * If runhost is the same as the local host, check for ipa_hostname
+ * in sssd.conf and use it in preference to user_runhost.
+ */
+ if (strcasecmp(user_runhost, user_host) == 0) {
+ if (get_ipa_hostname(&handle->ipa_shost, &handle->ipa_host) == -1) {
+ free(handle);
+ debug_return_int(ENOMEM);
+ }
+ }
+
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "handle=%p", handle);
+
+ debug_return_int(0);
+}
+
+/*
+ * Perform query for user and host and convert to sudoers parse tree.
+ */
+static int
+sudo_sss_query(struct sudo_nss *nss, struct passwd *pw)
+{
+ struct sudo_sss_handle *handle = nss->handle;
+ struct sss_sudo_result *sss_result = NULL;
+ int ret = 0;
+ debug_decl(sudo_sss_query, SUDOERS_DEBUG_SSSD);
+
+ if (handle == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "%s: called with NULL handle", __func__);
+ debug_return_int(-1);
+ }
+
+ /* Use cached result if it matches pw. */
+ if (handle->pw != NULL) {
+ if (pw == handle->pw)
+ goto done;
+ sudo_pw_delref(handle->pw);
+ handle->pw = NULL;
+ }
+
+ /* Free old userspecs, if any. */
+ free_userspecs(&handle->parse_tree.userspecs);
+
+ /* Fetch list of sudoRole entries that match user and host. */
+ sss_result = sudo_sss_result_get(nss, pw);
+
+ sudo_debug_printf(SUDO_DEBUG_DIAG,
+ "searching SSSD/LDAP for sudoers entries for user %s, host %s",
+ pw->pw_name, user_runhost);
+
+ /* Stash a ref to the passwd struct in the handle. */
+ sudo_pw_addref(pw);
+ handle->pw = pw;
+
+ /* Convert to sudoers parse tree if the user was found. */
+ if (sss_result != NULL) {
+ if (!sss_to_sudoers(handle, sss_result)) {
+ ret = -1;
+ goto done;
+ }
+ }
+
+done:
+ /* Cleanup */
+ handle->fn_free_result(sss_result);
+ if (ret == -1) {
+ free_userspecs(&handle->parse_tree.userspecs);
+ if (handle->pw != NULL) {
+ sudo_pw_delref(handle->pw);
+ handle->pw = NULL;
+ }
+ }
+
+ sudo_debug_printf(SUDO_DEBUG_DIAG, "Done with LDAP searches");
+
+ debug_return_int(ret);
+}
+
+/*
+ * Return the initialized (but empty) sudoers parse tree.
+ * The contents will be populated by the getdefs() and query() functions.
+ */
+static struct sudoers_parse_tree *
+sudo_sss_parse(struct sudo_nss *nss)
+{
+ struct sudo_sss_handle *handle = nss->handle;
+ debug_decl(sudo_sss_parse, SUDOERS_DEBUG_SSSD);
+
+ if (handle == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "%s: called with NULL handle", __func__);
+ debug_return_ptr(NULL);
+ }
+
+ debug_return_ptr(&handle->parse_tree);
+}
+
+static int
+sudo_sss_getdefs(struct sudo_nss *nss)
+{
+ struct sudo_sss_handle *handle = nss->handle;
+ struct sss_sudo_result *sss_result = NULL;
+ static bool cached;
+ uint32_t sss_error;
+ unsigned int i;
+ int rc;
+ debug_decl(sudo_sss_getdefs, SUDOERS_DEBUG_SSSD);
+
+ if (handle == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "%s: called with NULL handle", __func__);
+ debug_return_int(-1);
+ }
+
+ /* Use cached result if present. */
+ if (cached)
+ debug_return_int(0);
+
+ sudo_debug_printf(SUDO_DEBUG_DIAG, "Looking for cn=defaults");
+
+ /* NOTE: these are global defaults, user ID and name are not used. */
+ rc = handle->fn_send_recv_defaults(sudo_user.pw->pw_uid,
+ sudo_user.pw->pw_name, &sss_error, &handle->domainname, &sss_result);
+ switch (rc) {
+ case 0:
+ break;
+ case ENOMEM:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ /* FALLTHROUGH */
+ default:
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "handle->fn_send_recv_defaults: rc=%d, sss_error=%u", rc, sss_error);
+ debug_return_int(-1);
+ }
+
+ switch (sss_error) {
+ case 0:
+ /* Success */
+ for (i = 0; i < sss_result->num_rules; ++i) {
+ struct sss_sudo_rule *sss_rule = sss_result->rules + i;
+ sudo_debug_printf(SUDO_DEBUG_DIAG,
+ "Parsing cn=defaults, %d/%d", i, sss_result->num_rules);
+ if (!sudo_sss_parse_options(handle, sss_rule,
+ &handle->parse_tree.defaults))
+ goto bad;
+ }
+ break;
+ case ENOENT:
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "No global defaults entry found in SSSD.");
+ break;
+ default:
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "sss_error=%u\n", sss_error);
+ goto bad;
+ }
+ handle->fn_free_result(sss_result);
+ cached = true;
+ debug_return_int(0);
+
+bad:
+ handle->fn_free_result(sss_result);
+ debug_return_int(-1);
+}
+
+/* sudo_nss implementation */
+struct sudo_nss sudo_nss_sss = {
+ { NULL, NULL },
+ sudo_sss_open,
+ sudo_sss_close,
+ sudo_sss_parse,
+ sudo_sss_query,
+ sudo_sss_getdefs
+};
+
+#endif /* HAVE_SSSD */
diff --git a/plugins/sudoers/starttime.c b/plugins/sudoers/starttime.c
new file mode 100644
index 0000000..62ce1d3
--- /dev/null
+++ b/plugins/sudoers/starttime.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2012-2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+/* Large files not supported by procfs.h on Solaris. */
+#if defined(HAVE_STRUCT_PSINFO_PR_TTYDEV)
+# undef _FILE_OFFSET_BITS
+# undef _LARGE_FILES
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#if defined(HAVE_KINFO_PROC_44BSD) || defined (HAVE_KINFO_PROC_OPENBSD) || defined(HAVE_KINFO_PROC2_NETBSD2)
+# include <sys/sysctl.h>
+#elif defined(HAVE_KINFO_PROC_FREEBSD)
+# include <sys/sysctl.h>
+# include <sys/user.h>
+#endif
+#if defined(HAVE_PROCFS_H)
+# include <procfs.h>
+#elif defined(HAVE_SYS_PROCFS_H)
+# include <sys/procfs.h>
+#endif
+#ifdef HAVE_PSTAT_GETPROC
+# include <sys/pstat.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "sudoers.h"
+#include "check.h"
+
+/*
+ * Arguments for sysctl(2) when reading the process start time.
+ */
+#if defined(HAVE_KINFO_PROC2_NETBSD)
+# define SUDO_KERN_PROC KERN_PROC2
+# define sudo_kinfo_proc kinfo_proc2
+# define sudo_kp_namelen 6
+#elif defined(HAVE_KINFO_PROC_OPENBSD)
+# define SUDO_KERN_PROC KERN_PROC
+# define sudo_kinfo_proc kinfo_proc
+# define sudo_kp_namelen 6
+#elif defined(HAVE_KINFO_PROC_FREEBSD) || defined(HAVE_KINFO_PROC_44BSD)
+# define SUDO_KERN_PROC KERN_PROC
+# define sudo_kinfo_proc kinfo_proc
+# define sudo_kp_namelen 4
+#endif
+
+/*
+ * Store start time of the specified process in starttime.
+ */
+
+#if defined(sudo_kinfo_proc)
+int
+get_starttime(pid_t pid, struct timespec *starttime)
+{
+ struct sudo_kinfo_proc *ki_proc = NULL;
+ size_t size = sizeof(*ki_proc);
+ int mib[6], rc;
+ debug_decl(get_starttime, SUDOERS_DEBUG_UTIL)
+
+ /*
+ * Lookup start time for pid via sysctl.
+ */
+ mib[0] = CTL_KERN;
+ mib[1] = SUDO_KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = (int)pid;
+ mib[4] = sizeof(*ki_proc);
+ mib[5] = 1;
+ do {
+ struct sudo_kinfo_proc *kp;
+
+ size += size / 10;
+ if ((kp = realloc(ki_proc, size)) == NULL) {
+ rc = -1;
+ break; /* really out of memory. */
+ }
+ ki_proc = kp;
+ rc = sysctl(mib, sudo_kp_namelen, ki_proc, &size, NULL, 0);
+ } while (rc == -1 && errno == ENOMEM);
+ if (rc != -1) {
+#if defined(HAVE_KINFO_PROC_FREEBSD)
+ /* FreeBSD and Dragonfly */
+ TIMEVAL_TO_TIMESPEC(&ki_proc->ki_start, starttime);
+#elif defined(HAVE_KINFO_PROC_44BSD)
+ /* 4.4BSD and macOS */
+ TIMEVAL_TO_TIMESPEC(&ki_proc->kp_proc.p_starttime, starttime);
+#else
+ /* NetBSD and OpenBSD */
+ starttime->tv_sec = ki_proc->p_ustart_sec;
+ starttime->tv_nsec = ki_proc->p_ustart_usec * 1000;
+#endif
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: start time for %d: { %lld, %ld }", __func__,
+ (int)pid, (long long)starttime->tv_sec, (long)starttime->tv_nsec);
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "unable to get start time for %d via KERN_PROC", (int)pid);
+ }
+ free(ki_proc);
+
+ debug_return_int(rc == -1 ? -1 : 0);
+}
+#elif defined(HAVE_STRUCT_PSINFO_PR_TTYDEV)
+int
+get_starttime(pid_t pid, struct timespec *starttime)
+{
+ struct psinfo psinfo;
+ char path[PATH_MAX];
+ ssize_t nread;
+ int fd, ret = -1;
+ debug_decl(get_starttime, SUDOERS_DEBUG_UTIL)
+
+ /* Determine the start time from pr_start in /proc/pid/psinfo. */
+ snprintf(path, sizeof(path), "/proc/%u/psinfo", (unsigned int)pid);
+ if ((fd = open(path, O_RDONLY, 0)) != -1) {
+ nread = read(fd, &psinfo, sizeof(psinfo));
+ close(fd);
+ if (nread == (ssize_t)sizeof(psinfo)) {
+ starttime->tv_sec = psinfo.pr_start.tv_sec;
+ starttime->tv_nsec = psinfo.pr_start.tv_nsec;
+ ret = 0;
+
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: start time for %d: { %lld, %ld }", __func__, (int)pid,
+ (long long)starttime->tv_sec, (long)starttime->tv_nsec);
+ }
+ }
+
+ if (ret == -1)
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "unable to get start time for %d via %s", (int)pid, path);
+ debug_return_int(ret);
+}
+#elif defined(__linux__)
+int
+get_starttime(pid_t pid, struct timespec *starttime)
+{
+ char path[PATH_MAX];
+ char *cp, buf[1024];
+ ssize_t nread;
+ int ret = -1;
+ int fd = -1;
+ long tps;
+ debug_decl(get_starttime, SUDOERS_DEBUG_UTIL)
+
+ /*
+ * Start time is in ticks per second on Linux.
+ */
+ tps = sysconf(_SC_CLK_TCK);
+ if (tps == -1)
+ goto done;
+
+ /*
+ * Determine the start time from 22nd field in /proc/pid/stat.
+ * Ignore /proc/self/stat if it contains embedded NUL bytes.
+ * XXX - refactor common code with ttyname.c?
+ */
+ snprintf(path, sizeof(path), "/proc/%u/stat", (unsigned int)pid);
+ if ((fd = open(path, O_RDONLY | O_NOFOLLOW)) != -1) {
+ cp = buf;
+ while ((nread = read(fd, cp, buf + sizeof(buf) - cp)) != 0) {
+ if (nread == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ break;
+ }
+ cp += nread;
+ if (cp >= buf + sizeof(buf))
+ break;
+ }
+ if (nread == 0 && memchr(buf, '\0', cp - buf) == NULL) {
+ /*
+ * Field 22 is the start time (%ull).
+ * Since the process name at field 2 "(comm)" may include
+ * whitespace (including newlines), start at the last ')' found.
+ */
+ *cp = '\0';
+ cp = strrchr(buf, ')');
+ if (cp != NULL) {
+ char *ep = cp;
+ int field = 1;
+
+ while (*++ep != '\0') {
+ if (*ep == ' ') {
+ if (++field == 22) {
+ unsigned long long ullval;
+
+ /* Must start with a digit (not negative). */
+ if (!isdigit((unsigned char)*cp)) {
+ errno = EINVAL;
+ goto done;
+ }
+
+ /* starttime is %ul in 2.4 and %ull in >= 2.6 */
+ errno = 0;
+ ullval = strtoull(cp, &ep, 10);
+ if (ep == cp || *ep != ' ') {
+ errno = EINVAL;
+ goto done;
+ }
+ if (errno == ERANGE && ullval == ULLONG_MAX)
+ goto done;
+
+ /* Convert from ticks to timespec */
+ starttime->tv_sec = ullval / tps;
+ starttime->tv_nsec =
+ (ullval % tps) * (1000000000 / tps);
+ ret = 0;
+
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: start time for %d: { %lld, %ld }",
+ __func__, (int)pid,
+ (long long)starttime->tv_sec,
+ (long)starttime->tv_nsec);
+
+ goto done;
+ }
+ cp = ep + 1;
+ }
+ }
+ }
+ }
+ }
+ errno = ENOENT;
+
+done:
+ if (fd != -1)
+ close(fd);
+ if (ret == -1)
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "unable to get start time for %d via %s", (int)pid, path);
+
+ debug_return_int(ret);
+}
+#elif defined(HAVE_PSTAT_GETPROC)
+int
+get_starttime(pid_t pid, struct timespec *starttime)
+{
+ struct pst_status pstat;
+ int rc;
+ debug_decl(get_starttime, SUDOERS_DEBUG_UTIL)
+
+ /*
+ * Determine the start time from pst_start in struct pst_status.
+ * We may get EOVERFLOW if the whole thing doesn't fit but that is OK.
+ */
+ rc = pstat_getproc(&pstat, sizeof(pstat), (size_t)0, (int)pid);
+ if (rc != -1 || errno == EOVERFLOW) {
+ starttime->tv_sec = pstat.pst_start;
+ starttime->tv_nsec = 0;
+
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: start time for %d: { %lld, %ld }", __func__,
+ (int)pid, (long long)starttime->tv_sec, (long)starttime->tv_nsec);
+
+ debug_return_int(0);
+ }
+
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "unable to get start time for %d via pstat_getproc", (int)pid);
+ debug_return_int(-1);
+}
+#else
+int
+get_starttime(pid_t pid, struct timespec *starttime)
+{
+ debug_decl(get_starttime, SUDOERS_DEBUG_UTIL)
+
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
+ "process start time not supported by sudo on this system");
+ debug_return_int(-1);
+}
+#endif
diff --git a/plugins/sudoers/strlist.c b/plugins/sudoers/strlist.c
new file mode 100644
index 0000000..1bb7630
--- /dev/null
+++ b/plugins/sudoers/strlist.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "sudo_compat.h"
+#include "sudo_util.h"
+#include "sudo_queue.h"
+#include "sudoers_debug.h"
+#include "strlist.h"
+
+struct sudoers_string *
+sudoers_string_alloc(const char *s)
+{
+ struct sudoers_string *cs;
+ debug_decl(sudoers_string_alloc, SUDOERS_DEBUG_UTIL)
+
+ if ((cs = malloc(sizeof(*cs))) != NULL) {
+ if ((cs->str = strdup(s)) == NULL) {
+ free(cs);
+ cs = NULL;
+ }
+ }
+
+ debug_return_ptr(cs);
+}
+
+void
+sudoers_string_free(struct sudoers_string *cs)
+{
+ if (cs != NULL) {
+ free(cs->str);
+ free(cs);
+ }
+}
+
+struct sudoers_str_list *
+str_list_alloc(void)
+{
+ struct sudoers_str_list *strlist;
+ debug_decl(str_list_alloc, SUDOERS_DEBUG_UTIL)
+
+ strlist = malloc(sizeof(*strlist));
+ if (strlist != NULL) {
+ STAILQ_INIT(strlist);
+ strlist->refcnt = 1;
+ }
+
+ debug_return_ptr(strlist);
+}
+
+void
+str_list_free(void *v)
+{
+ struct sudoers_str_list *strlist = v;
+ struct sudoers_string *first;
+ debug_decl(str_list_free, SUDOERS_DEBUG_UTIL)
+
+ if (strlist != NULL) {
+ if (--strlist->refcnt == 0) {
+ while ((first = STAILQ_FIRST(strlist)) != NULL) {
+ STAILQ_REMOVE_HEAD(strlist, entries);
+ sudoers_string_free(first);
+ }
+ free(strlist);
+ }
+ }
+ debug_return;
+}
diff --git a/plugins/sudoers/strlist.h b/plugins/sudoers/strlist.h
new file mode 100644
index 0000000..1a0dfc6
--- /dev/null
+++ b/plugins/sudoers/strlist.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_STRLIST_H
+#define SUDOERS_STRLIST_H
+
+/*
+ * Simple string list with optional reference count.
+ */
+struct sudoers_string {
+ STAILQ_ENTRY(sudoers_string) entries;
+ char *str;
+};
+struct sudoers_str_list {
+ struct sudoers_string *stqh_first;
+ struct sudoers_string **stqh_last;
+ unsigned int refcnt;
+};
+
+struct sudoers_str_list *str_list_alloc(void);
+void str_list_free(void *v);
+struct sudoers_string *sudoers_string_alloc(const char *s);
+void sudoers_string_free(struct sudoers_string *ls);
+
+#endif /* SUDOERS_STRLIST_H */
diff --git a/plugins/sudoers/stubs.c b/plugins/sudoers/stubs.c
new file mode 100644
index 0000000..a594b1f
--- /dev/null
+++ b/plugins/sudoers/stubs.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+/*
+ * Stub versions of functions needed by the parser.
+ * Required to link cvtsudoers and visudo.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "sudoers.h"
+#include "interfaces.h"
+
+/* STUB */
+bool
+init_envtables(void)
+{
+ return true;
+}
+
+/* STUB */
+bool
+user_is_exempt(void)
+{
+ return false;
+}
+
+/* STUB */
+void
+sudo_setspent(void)
+{
+ return;
+}
+
+/* STUB */
+void
+sudo_endspent(void)
+{
+ return;
+}
+
+/* STUB */
+int
+group_plugin_query(const char *user, const char *group, const struct passwd *pw)
+{
+ return false;
+}
+
+/* STUB */
+struct interface_list *
+get_interfaces(void)
+{
+ static struct interface_list dummy = SLIST_HEAD_INITIALIZER(interfaces);
+ return &dummy;
+}
+
+/*
+ * Look up the hostname and set user_host and user_shost.
+ */
+void
+get_hostname(void)
+{
+ char *cp;
+ debug_decl(get_hostname, SUDOERS_DEBUG_UTIL)
+
+ if ((user_host = sudo_gethostname()) != NULL) {
+ if ((cp = strchr(user_host, '.'))) {
+ *cp = '\0';
+ if ((user_shost = strdup(user_host)) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ *cp = '.';
+ } else {
+ user_shost = user_host;
+ }
+ } else {
+ user_host = user_shost = strdup("localhost");
+ if (user_host == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ }
+ user_runhost = user_host;
+ user_srunhost = user_shost;
+
+ debug_return;
+}
diff --git a/plugins/sudoers/sudo_ldap.h b/plugins/sudoers/sudo_ldap.h
new file mode 100644
index 0000000..7298ee0
--- /dev/null
+++ b/plugins/sudoers/sudo_ldap.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_LDAP_H
+#define SUDOERS_LDAP_H
+
+/* Iterators used by sudo_ldap_role_to_priv() to handle bervar ** or char ** */
+typedef char * (*sudo_ldap_iter_t)(void **);
+
+/* ldap_util.c */
+bool sudo_ldap_is_negated(char **valp);
+bool sudo_ldap_add_default(const char *var, const char *val, int op, char *source, struct defaults_list *defs);
+int sudo_ldap_parse_option(char *optstr, char **varp, char **valp);
+struct privilege *sudo_ldap_role_to_priv(const char *cn, void *hosts, void *runasusers, void *runasgroups, void *cmnds, void *opts, const char *notbefore, const char *notafter, bool warnings, bool store_options, sudo_ldap_iter_t iter);
+struct command_digest *sudo_ldap_extract_digest(char **cmnd, struct command_digest *digest);
+
+#endif /* SUDOERS_LDAP_H */
diff --git a/plugins/sudoers/sudo_ldap_conf.h b/plugins/sudoers/sudo_ldap_conf.h
new file mode 100644
index 0000000..363ab43
--- /dev/null
+++ b/plugins/sudoers/sudo_ldap_conf.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_LDAP_CONF_H
+#define SUDOERS_LDAP_CONF_H
+
+/* Macros for checking strlcpy/strlcat/sudo_ldap_value_cat return value. */
+#define CHECK_STRLCPY(d, s, l) do { \
+ if (strlcpy((d), (s), (l)) >= (l)) \
+ goto overflow; \
+} while (0)
+#define CHECK_STRLCAT(d, s, l) do { \
+ if (strlcat((d), (s), (l)) >= (l)) \
+ goto overflow; \
+} while (0)
+#define CHECK_LDAP_VCAT(d, s, l) do { \
+ if (sudo_ldap_value_cat((d), (s), (l)) >= (l)) \
+ goto overflow; \
+} while (0)
+
+#if defined(__GNUC__) && __GNUC__ == 2
+# define DPRINTF1(fmt...) do { \
+ sudo_debug_printf(SUDO_DEBUG_DIAG, fmt); \
+ if (ldap_conf.debug >= 1) \
+ sudo_warnx_nodebug(fmt); \
+} while (0)
+# define DPRINTF2(fmt...) do { \
+ sudo_debug_printf(SUDO_DEBUG_INFO, fmt); \
+ if (ldap_conf.debug >= 2) \
+ sudo_warnx_nodebug(fmt); \
+} while (0)
+#else
+# define DPRINTF1(...) do { \
+ sudo_debug_printf(SUDO_DEBUG_DIAG, __VA_ARGS__); \
+ if (ldap_conf.debug >= 1) \
+ sudo_warnx_nodebug(__VA_ARGS__); \
+} while (0)
+# define DPRINTF2(...) do { \
+ sudo_debug_printf(SUDO_DEBUG_INFO, __VA_ARGS__); \
+ if (ldap_conf.debug >= 2) \
+ sudo_warnx_nodebug(__VA_ARGS__); \
+} while (0)
+#endif
+
+#define CONF_BOOL 0
+#define CONF_INT 1
+#define CONF_STR 2
+#define CONF_LIST_STR 4
+#define CONF_DEREF_VAL 5
+#define CONF_REQCERT_VAL 6
+
+#define SUDO_LDAP_CLEAR 0
+#define SUDO_LDAP_SSL 1
+#define SUDO_LDAP_STARTTLS 2
+
+struct ldap_config_table {
+ const char *conf_str; /* config file string */
+ int type; /* CONF_BOOL, CONF_INT, CONF_STR */
+ int opt_val; /* LDAP_OPT_* (or -1 for sudo internal) */
+ void *valp; /* pointer into ldap_conf */
+};
+
+struct ldap_config_str {
+ STAILQ_ENTRY(ldap_config_str) entries;
+ char val[1];
+};
+STAILQ_HEAD(ldap_config_str_list, ldap_config_str);
+
+/* LDAP configuration structure */
+struct ldap_config {
+ int port;
+ int version;
+ int debug;
+ int ldap_debug;
+ int tls_checkpeer;
+ int tls_reqcert;
+ int timelimit;
+ int timeout;
+ int bind_timelimit;
+ int use_sasl;
+ int rootuse_sasl;
+ int ssl_mode;
+ int timed;
+ int deref;
+ char *host;
+ struct ldap_config_str_list uri;
+ char *binddn;
+ char *bindpw;
+ char *rootbinddn;
+ struct ldap_config_str_list base;
+ struct ldap_config_str_list netgroup_base;
+ char *search_filter;
+ char *netgroup_search_filter;
+ char *ssl;
+ char *tls_cacertfile;
+ char *tls_cacertdir;
+ char *tls_random_file;
+ char *tls_cipher_suite;
+ char *tls_certfile;
+ char *tls_keyfile;
+ char *tls_keypw;
+ char *sasl_mech;
+ char *sasl_auth_id;
+ char *rootsasl_auth_id;
+ char *sasl_secprops;
+ char *krb5_ccname;
+};
+
+extern struct ldap_config ldap_conf;
+
+const char *sudo_krb5_ccname_path(const char *old_ccname);
+bool sudo_ldap_read_config(void);
+int sudo_ldap_set_options_global(void);
+int sudo_ldap_set_options_conn(LDAP *ld);
+
+#endif /* SUDOERS_LDAP_CONF_H */
diff --git a/plugins/sudoers/sudo_nss.c b/plugins/sudoers/sudo_nss.c
new file mode 100644
index 0000000..339559a
--- /dev/null
+++ b/plugins/sudoers/sudo_nss.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2007-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <ctype.h>
+
+#include "sudoers.h"
+#include "sudo_lbuf.h"
+
+extern struct sudo_nss sudo_nss_file;
+#ifdef HAVE_LDAP
+extern struct sudo_nss sudo_nss_ldap;
+#endif
+#ifdef HAVE_SSSD
+extern struct sudo_nss sudo_nss_sss;
+#endif
+
+/* Make sure we have not already inserted the nss entry. */
+#define SUDO_NSS_CHECK_UNUSED(nss, tag) \
+ if (nss.entries.tqe_next != NULL || nss.entries.tqe_prev != NULL) { \
+ sudo_warnx("internal error: nsswitch entry \"%s\" already in use", \
+ tag); \
+ continue; \
+ }
+
+#if (defined(HAVE_LDAP) || defined(HAVE_SSSD)) && defined(_PATH_NSSWITCH_CONF)
+/*
+ * Read in /etc/nsswitch.conf
+ * Returns a tail queue of matches.
+ */
+struct sudo_nss_list *
+sudo_read_nss(void)
+{
+ FILE *fp;
+ char *line = NULL;
+ size_t linesize = 0;
+#ifdef HAVE_SSSD
+ bool saw_sss = false;
+#endif
+#ifdef HAVE_LDAP
+ bool saw_ldap = false;
+#endif
+ bool saw_files = false;
+ bool got_match = false;
+ static struct sudo_nss_list snl = TAILQ_HEAD_INITIALIZER(snl);
+ debug_decl(sudo_read_nss, SUDOERS_DEBUG_NSS)
+
+ if ((fp = fopen(_PATH_NSSWITCH_CONF, "r")) == NULL)
+ goto nomatch;
+
+ while (sudo_parseln(&line, &linesize, NULL, fp, 0) != -1) {
+ char *cp, *last;
+
+ /* Skip blank or comment lines */
+ if (*line == '\0')
+ continue;
+
+ /* Look for a line starting with "sudoers:" */
+ if (strncasecmp(line, "sudoers:", 8) != 0)
+ continue;
+
+ /* Parse line */
+ for ((cp = strtok_r(line + 8, " \t", &last)); cp != NULL; (cp = strtok_r(NULL, " \t", &last))) {
+ if (strcasecmp(cp, "files") == 0 && !saw_files) {
+ SUDO_NSS_CHECK_UNUSED(sudo_nss_file, "files");
+ TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries);
+ got_match = saw_files = true;
+#ifdef HAVE_LDAP
+ } else if (strcasecmp(cp, "ldap") == 0 && !saw_ldap) {
+ SUDO_NSS_CHECK_UNUSED(sudo_nss_ldap, "ldap");
+ TAILQ_INSERT_TAIL(&snl, &sudo_nss_ldap, entries);
+ got_match = saw_ldap = true;
+#endif
+#ifdef HAVE_SSSD
+ } else if (strcasecmp(cp, "sss") == 0 && !saw_sss) {
+ SUDO_NSS_CHECK_UNUSED(sudo_nss_sss, "sss");
+ TAILQ_INSERT_TAIL(&snl, &sudo_nss_sss, entries);
+ got_match = saw_sss = true;
+#endif
+ } else if (strcasecmp(cp, "[NOTFOUND=return]") == 0 && got_match) {
+ /* NOTFOUND affects the most recent entry */
+ TAILQ_LAST(&snl, sudo_nss_list)->ret_if_notfound = true;
+ got_match = false;
+ } else if (strcasecmp(cp, "[SUCCESS=return]") == 0 && got_match) {
+ /* SUCCESS affects the most recent entry */
+ TAILQ_LAST(&snl, sudo_nss_list)->ret_if_found = true;
+ got_match = false;
+ } else
+ got_match = false;
+ }
+ /* Only parse the first "sudoers:" line */
+ break;
+ }
+ free(line);
+ fclose(fp);
+
+nomatch:
+ /* Default to files only if no matches */
+ if (TAILQ_EMPTY(&snl))
+ TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries);
+
+ debug_return_ptr(&snl);
+}
+
+#else /* (HAVE_LDAP || HAVE_SSSD) && _PATH_NSSWITCH_CONF */
+
+# if (defined(HAVE_LDAP) || defined(HAVE_SSSD)) && defined(_PATH_NETSVC_CONF)
+
+/*
+ * Read in /etc/netsvc.conf (like nsswitch.conf on AIX)
+ * Returns a tail queue of matches.
+ */
+struct sudo_nss_list *
+sudo_read_nss(void)
+{
+ FILE *fp;
+ char *cp, *ep, *last, *line = NULL;
+ size_t linesize = 0;
+#ifdef HAVE_SSSD
+ bool saw_sss = false;
+#endif
+ bool saw_files = false;
+ bool saw_ldap = false;
+ bool got_match = false;
+ static struct sudo_nss_list snl = TAILQ_HEAD_INITIALIZER(snl);
+ debug_decl(sudo_read_nss, SUDOERS_DEBUG_NSS)
+
+ if ((fp = fopen(_PATH_NETSVC_CONF, "r")) == NULL)
+ goto nomatch;
+
+ while (sudo_parseln(&line, &linesize, NULL, fp, 0) != -1) {
+ /* Skip blank or comment lines */
+ if (*(cp = line) == '\0')
+ continue;
+
+ /* Look for a line starting with "sudoers = " */
+ if (strncasecmp(cp, "sudoers", 7) != 0)
+ continue;
+ cp += 7;
+ while (isspace((unsigned char)*cp))
+ cp++;
+ if (*cp++ != '=')
+ continue;
+
+ /* Parse line */
+ for ((cp = strtok_r(cp, ",", &last)); cp != NULL; (cp = strtok_r(NULL, ",", &last))) {
+ /* Trim leading whitespace. */
+ while (isspace((unsigned char)*cp))
+ cp++;
+
+ if (!saw_files && strncasecmp(cp, "files", 5) == 0 &&
+ (isspace((unsigned char)cp[5]) || cp[5] == '\0')) {
+ TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries);
+ got_match = saw_files = true;
+ ep = &cp[5];
+#ifdef HAVE_LDAP
+ } else if (!saw_ldap && strncasecmp(cp, "ldap", 4) == 0 &&
+ (isspace((unsigned char)cp[4]) || cp[4] == '\0')) {
+ TAILQ_INSERT_TAIL(&snl, &sudo_nss_ldap, entries);
+ got_match = saw_ldap = true;
+ ep = &cp[4];
+#endif
+#ifdef HAVE_SSSD
+ } else if (!saw_sss && strncasecmp(cp, "sss", 3) == 0 &&
+ (isspace((unsigned char)cp[3]) || cp[3] == '\0')) {
+ TAILQ_INSERT_TAIL(&snl, &sudo_nss_sss, entries);
+ got_match = saw_sss = true;
+ ep = &cp[3];
+#endif
+ } else {
+ got_match = false;
+ }
+
+ /* check for = auth qualifier */
+ if (got_match && *ep) {
+ cp = ep;
+ while (isspace((unsigned char)*cp) || *cp == '=')
+ cp++;
+ if (strncasecmp(cp, "auth", 4) == 0 &&
+ (isspace((unsigned char)cp[4]) || cp[4] == '\0')) {
+ TAILQ_LAST(&snl, sudo_nss_list)->ret_if_found = true;
+ }
+ }
+ }
+ /* Only parse the first "sudoers" line */
+ break;
+ }
+ fclose(fp);
+
+nomatch:
+ /* Default to files only if no matches */
+ if (TAILQ_EMPTY(&snl))
+ TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries);
+
+ debug_return_ptr(&snl);
+}
+
+# else /* !_PATH_NETSVC_CONF && !_PATH_NSSWITCH_CONF */
+
+/*
+ * Non-nsswitch.conf version with hard-coded order.
+ */
+struct sudo_nss_list *
+sudo_read_nss(void)
+{
+ static struct sudo_nss_list snl = TAILQ_HEAD_INITIALIZER(snl);
+ debug_decl(sudo_read_nss, SUDOERS_DEBUG_NSS)
+
+# ifdef HAVE_SSSD
+ TAILQ_INSERT_TAIL(&snl, &sudo_nss_sss, entries);
+# endif
+# ifdef HAVE_LDAP
+ TAILQ_INSERT_TAIL(&snl, &sudo_nss_ldap, entries);
+# endif
+ TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries);
+
+ debug_return_ptr(&snl);
+}
+
+# endif /* !HAVE_LDAP || !_PATH_NETSVC_CONF */
+
+#endif /* HAVE_LDAP && _PATH_NSSWITCH_CONF */
+
+bool
+sudo_nss_can_continue(struct sudo_nss *nss, int match)
+{
+ debug_decl(sudo_nss_should_continue, SUDOERS_DEBUG_NSS)
+
+ /* Handle [NOTFOUND=return] */
+ if (nss->ret_if_notfound && match == UNSPEC)
+ debug_return_bool(false);
+
+ /* Handle [SUCCESS=return] */
+ if (nss->ret_if_found && match != UNSPEC)
+ debug_return_bool(false);
+
+ debug_return_bool(true);
+}
diff --git a/plugins/sudoers/sudo_nss.h b/plugins/sudoers/sudo_nss.h
new file mode 100644
index 0000000..e4566f8
--- /dev/null
+++ b/plugins/sudoers/sudo_nss.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2007-2011, 2013-2015, 2017-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_NSS_H
+#define SUDOERS_NSS_H
+
+struct passwd;
+struct userspec_list;
+struct defaults_list;
+
+/* XXX - parse_tree, ret_if_found and ret_if_notfound should be private */
+struct sudo_nss {
+ TAILQ_ENTRY(sudo_nss) entries;
+ int (*open)(struct sudo_nss *nss);
+ int (*close)(struct sudo_nss *nss);
+ struct sudoers_parse_tree *(*parse)(struct sudo_nss *nss);
+ int (*query)(struct sudo_nss *nss, struct passwd *pw);
+ int (*getdefs)(struct sudo_nss *nss);
+ void *handle;
+ struct sudoers_parse_tree *parse_tree;
+ bool ret_if_found;
+ bool ret_if_notfound;
+};
+
+TAILQ_HEAD(sudo_nss_list, sudo_nss);
+
+struct sudo_nss_list *sudo_read_nss(void);
+bool sudo_nss_can_continue(struct sudo_nss *nss, int match);
+
+#endif /* SUDOERS_NSS_H */
diff --git a/plugins/sudoers/sudo_printf.c b/plugins/sudoers/sudo_printf.c
new file mode 100644
index 0000000..e82317f
--- /dev/null
+++ b/plugins/sudoers/sudo_printf.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010-2012 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include "sudo_compat.h"
+#include "sudo_plugin.h"
+#include "sudo_debug.h"
+
+static int
+sudo_printf_int(int msg_type, const char *fmt, ...)
+{
+ va_list ap;
+ int len;
+
+ switch (msg_type) {
+ case SUDO_CONV_INFO_MSG:
+ va_start(ap, fmt);
+ len = vfprintf(stdout, fmt, ap);
+ va_end(ap);
+ break;
+ case SUDO_CONV_ERROR_MSG:
+ va_start(ap, fmt);
+ len = vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ break;
+ default:
+ len = -1;
+ errno = EINVAL;
+ break;
+ }
+
+ return len;
+}
+
+sudo_printf_t sudo_printf = sudo_printf_int;
diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c
new file mode 100644
index 0000000..1267949
--- /dev/null
+++ b/plugins/sudoers/sudoers.c
@@ -0,0 +1,1281 @@
+/*
+ * Copyright (c) 1993-1996, 1998-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#ifdef __TANDEM
+# include <floss.h>
+#endif
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <pwd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <grp.h>
+#include <time.h>
+#include <netdb.h>
+#ifdef HAVE_LOGIN_CAP_H
+# include <login_cap.h>
+# ifndef LOGIN_DEFROOTCLASS
+# define LOGIN_DEFROOTCLASS "daemon"
+# endif
+# ifndef LOGIN_SETENV
+# define LOGIN_SETENV 0
+# endif
+#endif
+#ifdef HAVE_SELINUX
+# include <selinux/selinux.h>
+#endif
+#include <ctype.h>
+
+#include "sudoers.h"
+#include "parse.h"
+#include "auth/sudo_auth.h"
+
+#ifndef HAVE_GETADDRINFO
+# include "compat/getaddrinfo.h"
+#endif
+
+/*
+ * Prototypes
+ */
+static bool cb_fqdn(const union sudo_defs_val *);
+static bool cb_runas_default(const union sudo_defs_val *);
+static bool cb_tty_tickets(const union sudo_defs_val *);
+static int set_cmnd(void);
+static int create_admin_success_flag(void);
+static bool init_vars(char * const *);
+static bool set_loginclass(struct passwd *);
+static bool set_runasgr(const char *, bool);
+static bool set_runaspw(const char *, bool);
+static bool tty_present(void);
+
+/*
+ * Globals
+ */
+struct sudo_user sudo_user;
+struct passwd *list_pw;
+uid_t timestamp_uid;
+gid_t timestamp_gid;
+#ifdef HAVE_BSD_AUTH_H
+char *login_style;
+#endif /* HAVE_BSD_AUTH_H */
+int sudo_mode;
+
+static char *prev_user;
+static char *runas_user;
+static char *runas_group;
+static struct sudo_nss_list *snl;
+
+#ifdef __linux__
+static struct rlimit nproclimit;
+#endif
+
+/* XXX - must be extern for audit bits of sudo_auth.c */
+int NewArgc;
+char **NewArgv;
+
+/*
+ * Unlimit the number of processes since Linux's setuid() will
+ * apply resource limits when changing uid and return EAGAIN if
+ * nproc would be exceeded by the uid switch.
+ */
+static void
+unlimit_nproc(void)
+{
+#ifdef __linux__
+ struct rlimit rl;
+ debug_decl(unlimit_nproc, SUDOERS_DEBUG_UTIL)
+
+ if (getrlimit(RLIMIT_NPROC, &nproclimit) != 0)
+ sudo_warn("getrlimit");
+ rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
+ if (setrlimit(RLIMIT_NPROC, &rl) != 0) {
+ rl.rlim_cur = rl.rlim_max = nproclimit.rlim_max;
+ if (setrlimit(RLIMIT_NPROC, &rl) != 0)
+ sudo_warn("setrlimit");
+ }
+ debug_return;
+#endif /* __linux__ */
+}
+
+/*
+ * Restore saved value of RLIMIT_NPROC.
+ */
+static void
+restore_nproc(void)
+{
+#ifdef __linux__
+ debug_decl(restore_nproc, SUDOERS_DEBUG_UTIL)
+
+ if (setrlimit(RLIMIT_NPROC, &nproclimit) != 0)
+ sudo_warn("setrlimit");
+
+ debug_return;
+#endif /* __linux__ */
+}
+
+int
+sudoers_policy_init(void *info, char * const envp[])
+{
+ struct sudo_nss *nss, *nss_next;
+ int oldlocale, sources = 0;
+ int ret = -1;
+ debug_decl(sudoers_policy_init, SUDOERS_DEBUG_PLUGIN)
+
+ bindtextdomain("sudoers", LOCALEDIR);
+
+ /* Register fatal/fatalx callback. */
+ sudo_fatal_callback_register(sudoers_cleanup);
+
+ /* Initialize environment functions (including replacements). */
+ if (!env_init(envp))
+ debug_return_int(-1);
+
+ /* Setup defaults data structures. */
+ if (!init_defaults()) {
+ sudo_warnx(U_("unable to initialize sudoers default values"));
+ debug_return_int(-1);
+ }
+
+ /* Parse info from front-end. */
+ sudo_mode = sudoers_policy_deserialize_info(info, &runas_user, &runas_group);
+ if (ISSET(sudo_mode, MODE_ERROR))
+ debug_return_int(-1);
+
+ if (!init_vars(envp))
+ debug_return_int(-1);
+
+ /* Parse nsswitch.conf for sudoers order. */
+ snl = sudo_read_nss();
+
+ /* LDAP or NSS may modify the euid so we need to be root for the open. */
+ if (!set_perms(PERM_ROOT))
+ debug_return_int(-1);
+
+ /*
+ * Open and parse sudoers, set global defaults.
+ * Uses the C locale unless another is specified in sudoers.
+ */
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+ sudo_warn_set_locale_func(sudoers_warn_setlocale);
+ init_parser(sudoers_file, false);
+ TAILQ_FOREACH_SAFE(nss, snl, entries, nss_next) {
+ if (nss->open(nss) == -1 || (nss->parse_tree = nss->parse(nss)) == NULL) {
+ TAILQ_REMOVE(snl, nss, entries);
+ continue;
+ }
+
+ sources++;
+ if (nss->getdefs(nss) == -1 || !update_defaults(nss->parse_tree, NULL,
+ SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER|SETDEF_RUNAS, false)) {
+ log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR,
+ N_("problem with defaults entries"));
+ }
+ }
+ if (sources == 0) {
+ sudo_warnx(U_("no valid sudoers sources found, quitting"));
+ goto cleanup;
+ }
+
+ /* Set login class if applicable (after sudoers is parsed). */
+ if (set_loginclass(runas_pw ? runas_pw : sudo_user.pw))
+ ret = true;
+
+cleanup:
+ if (!restore_perms())
+ ret = -1;
+
+ /* Restore user's locale. */
+ sudo_warn_set_locale_func(NULL);
+ sudoers_setlocale(oldlocale, NULL);
+
+ debug_return_int(ret);
+}
+
+int
+sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
+ bool verbose, void *closure)
+{
+ char **edit_argv = NULL;
+ char *iolog_path = NULL;
+ mode_t cmnd_umask = ACCESSPERMS;
+ struct sudo_nss *nss;
+ int cmnd_status = -1, oldlocale, validated;
+ int ret = -1;
+ debug_decl(sudoers_policy_main, SUDOERS_DEBUG_PLUGIN)
+
+ sudo_warn_set_locale_func(sudoers_warn_setlocale);
+
+ unlimit_nproc();
+
+ /* Is root even allowed to run sudo? */
+ if (user_uid == 0 && !def_root_sudo) {
+ /* Not an audit event. */
+ sudo_warnx(U_("sudoers specifies that root is not allowed to sudo"));
+ goto bad;
+ }
+
+ if (!set_perms(PERM_INITIAL))
+ goto bad;
+
+ /* Environment variables specified on the command line. */
+ if (env_add != NULL && env_add[0] != NULL)
+ sudo_user.env_vars = env_add;
+
+ /*
+ * Make a local copy of argc/argv, with special handling
+ * for pseudo-commands and the '-i' option.
+ */
+ if (argc == 0) {
+ NewArgc = 1;
+ NewArgv = reallocarray(NULL, NewArgc + 1, sizeof(char *));
+ if (NewArgv == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ NewArgv[0] = user_cmnd;
+ NewArgv[1] = NULL;
+ } else {
+ /* Must leave an extra slot before NewArgv for bash's --login */
+ NewArgc = argc;
+ NewArgv = reallocarray(NULL, NewArgc + 2, sizeof(char *));
+ if (NewArgv == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ NewArgv++; /* reserve an extra slot for --login */
+ memcpy(NewArgv, argv, argc * sizeof(char *));
+ NewArgv[NewArgc] = NULL;
+ if (ISSET(sudo_mode, MODE_LOGIN_SHELL) && runas_pw != NULL) {
+ NewArgv[0] = strdup(runas_pw->pw_shell);
+ if (NewArgv[0] == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ free(NewArgv);
+ goto done;
+ }
+ }
+ }
+
+ /* If given the -P option, set the "preserve_groups" flag. */
+ if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS))
+ def_preserve_groups = true;
+
+ /* Find command in path and apply per-command Defaults. */
+ cmnd_status = set_cmnd();
+ if (cmnd_status == NOT_FOUND_ERROR)
+ goto done;
+
+ /* Check for -C overriding def_closefrom. */
+ if (user_closefrom >= 0 && user_closefrom != def_closefrom) {
+ if (!def_closefrom_override) {
+ /* XXX - audit? */
+ sudo_warnx(U_("you are not permitted to use the -C option"));
+ goto bad;
+ }
+ def_closefrom = user_closefrom;
+ }
+
+ /*
+ * Check sudoers sources, using the locale specified in sudoers.
+ */
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+ validated = sudoers_lookup(snl, sudo_user.pw, FLAG_NO_USER | FLAG_NO_HOST,
+ pwflag);
+ if (ISSET(validated, VALIDATE_ERROR)) {
+ /* The lookup function should have printed an error. */
+ goto done;
+ }
+
+ /* Restore user's locale. */
+ sudoers_setlocale(oldlocale, NULL);
+
+ if (safe_cmnd == NULL) {
+ if ((safe_cmnd = strdup(user_cmnd)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ }
+
+ /*
+ * Look up the timestamp dir owner if one is specified.
+ */
+ if (def_timestampowner) {
+ struct passwd *pw = NULL;
+
+ if (*def_timestampowner == '#') {
+ const char *errstr;
+ uid_t uid = sudo_strtoid(def_timestampowner + 1, NULL, NULL, &errstr);
+ if (errstr == NULL)
+ pw = sudo_getpwuid(uid);
+ }
+ if (pw == NULL)
+ pw = sudo_getpwnam(def_timestampowner);
+ if (pw != NULL) {
+ timestamp_uid = pw->pw_uid;
+ timestamp_gid = pw->pw_gid;
+ sudo_pw_delref(pw);
+ } else {
+ log_warningx(SLOG_SEND_MAIL,
+ N_("timestamp owner (%s): No such user"), def_timestampowner);
+ timestamp_uid = ROOT_UID;
+ timestamp_gid = ROOT_GID;
+ }
+ }
+
+ /* If no command line args and "shell_noargs" is not set, error out. */
+ if (ISSET(sudo_mode, MODE_IMPLIED_SHELL) && !def_shell_noargs) {
+ /* Not an audit event. */
+ ret = -2; /* usage error */
+ goto done;
+ }
+
+ /* Bail if a tty is required and we don't have one. */
+ if (def_requiretty && !tty_present()) {
+ audit_failure(NewArgc, NewArgv, N_("no tty"));
+ sudo_warnx(U_("sorry, you must have a tty to run sudo"));
+ goto bad;
+ }
+
+ /*
+ * We don't reset the environment for sudoedit or if the user
+ * specified the -E command line flag and they have setenv privs.
+ */
+ if (ISSET(sudo_mode, MODE_EDIT) ||
+ (ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv))
+ def_env_reset = false;
+
+ /* Build a new environment that avoids any nasty bits. */
+ if (!rebuild_env())
+ goto bad;
+
+ /* Require a password if sudoers says so. */
+ switch (check_user(validated, sudo_mode)) {
+ case true:
+ /* user authenticated successfully. */
+ break;
+ case false:
+ /* Note: log_denial() calls audit for us. */
+ if (!ISSET(validated, VALIDATE_SUCCESS)) {
+ /* Only display a denial message if no password was read. */
+ if (!log_denial(validated, def_passwd_tries <= 0))
+ goto done;
+ }
+ goto bad;
+ default:
+ /* some other error, ret is -1. */
+ goto done;
+ }
+
+ /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */
+ /* XXX - causes confusion when root is not listed in sudoers */
+ if (sudo_mode & (MODE_RUN | MODE_EDIT) && prev_user != NULL) {
+ if (user_uid == 0 && strcmp(prev_user, "root") != 0) {
+ struct passwd *pw;
+
+ if ((pw = sudo_getpwnam(prev_user)) != NULL) {
+ if (sudo_user.pw != NULL)
+ sudo_pw_delref(sudo_user.pw);
+ sudo_user.pw = pw;
+ }
+ }
+ }
+
+ /* If the user was not allowed to run the command we are done. */
+ if (!ISSET(validated, VALIDATE_SUCCESS)) {
+ /* Note: log_failure() calls audit for us. */
+ if (!log_failure(validated, cmnd_status))
+ goto done;
+ goto bad;
+ }
+
+ /* Create Ubuntu-style dot file to indicate sudo was successful. */
+ if (create_admin_success_flag() == -1)
+ goto done;
+
+ /* Finally tell the user if the command did not exist. */
+ if (cmnd_status == NOT_FOUND_DOT) {
+ audit_failure(NewArgc, NewArgv, N_("command in current directory"));
+ sudo_warnx(U_("ignoring \"%s\" found in '.'\nUse \"sudo ./%s\" if this is the \"%s\" you wish to run."), user_cmnd, user_cmnd, user_cmnd);
+ goto bad;
+ } else if (cmnd_status == NOT_FOUND) {
+ if (ISSET(sudo_mode, MODE_CHECK)) {
+ audit_failure(NewArgc, NewArgv, N_("%s: command not found"),
+ NewArgv[0]);
+ sudo_warnx(U_("%s: command not found"), NewArgv[0]);
+ } else {
+ audit_failure(NewArgc, NewArgv, N_("%s: command not found"),
+ user_cmnd);
+ sudo_warnx(U_("%s: command not found"), user_cmnd);
+ }
+ goto bad;
+ }
+
+ /* If user specified a timeout make sure sudoers allows it. */
+ if (!def_user_command_timeouts && user_timeout > 0) {
+ /* XXX - audit/log? */
+ sudo_warnx(U_("sorry, you are not allowed set a command timeout"));
+ goto bad;
+ }
+
+ /* If user specified env vars make sure sudoers allows it. */
+ if (ISSET(sudo_mode, MODE_RUN) && !def_setenv) {
+ if (ISSET(sudo_mode, MODE_PRESERVE_ENV)) {
+ /* XXX - audit/log? */
+ sudo_warnx(U_("sorry, you are not allowed to preserve the environment"));
+ goto bad;
+ } else {
+ if (!validate_env_vars(sudo_user.env_vars))
+ goto bad;
+ }
+ }
+
+ if (ISSET(sudo_mode, (MODE_RUN | MODE_EDIT))) {
+ if ((def_log_input || def_log_output) && def_iolog_file && def_iolog_dir) {
+ const char prefix[] = "iolog_path=";
+ iolog_path = expand_iolog_path(prefix, def_iolog_dir,
+ def_iolog_file, &sudo_user.iolog_file);
+ if (iolog_path == NULL) {
+ if (!def_ignore_iolog_errors)
+ goto done;
+ /* Unable to expand I/O log path, disable I/O logging. */
+ def_log_input = false;
+ def_log_output = false;
+ } else {
+ sudo_user.iolog_file++;
+ }
+ }
+ }
+
+ if (!log_allowed(validated) && !def_ignore_logfile_errors)
+ goto bad;
+
+ switch (sudo_mode & MODE_MASK) {
+ case MODE_CHECK:
+ ret = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw);
+ break;
+ case MODE_LIST:
+ ret = display_privs(snl, list_pw ? list_pw : sudo_user.pw, verbose);
+ break;
+ case MODE_VALIDATE:
+ /* Nothing to do. */
+ ret = true;
+ break;
+ case MODE_RUN:
+ case MODE_EDIT:
+ /* ret set by sudoers_policy_exec_setup() below. */
+ break;
+ default:
+ /* Should not happen. */
+ sudo_warnx("internal error, unexpected sudo mode 0x%x", sudo_mode);
+ goto done;
+ }
+
+ /* Cleanup sudoers sources */
+ TAILQ_FOREACH(nss, snl, entries) {
+ nss->close(nss);
+ }
+ if (def_group_plugin)
+ group_plugin_unload();
+ init_parser(NULL, false);
+
+ if (ISSET(sudo_mode, (MODE_VALIDATE|MODE_CHECK|MODE_LIST))) {
+ /* ret already set appropriately */
+ goto done;
+ }
+
+ /*
+ * Set umask based on sudoers.
+ * If user's umask is more restrictive, OR in those bits too
+ * unless umask_override is set.
+ */
+ if (def_umask != ACCESSPERMS) {
+ cmnd_umask = def_umask;
+ if (!def_umask_override)
+ cmnd_umask |= user_umask;
+ }
+
+ if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
+ char *p;
+
+ /* Convert /bin/sh -> -sh so shell knows it is a login shell */
+ if ((p = strrchr(NewArgv[0], '/')) == NULL)
+ p = NewArgv[0];
+ *p = '-';
+ NewArgv[0] = p;
+
+ /*
+ * Newer versions of bash require the --login option to be used
+ * in conjunction with the -c option even if the shell name starts
+ * with a '-'. Unfortunately, bash 1.x uses -login, not --login
+ * so this will cause an error for that.
+ */
+ if (NewArgc > 1 && strcmp(NewArgv[0], "-bash") == 0 &&
+ strcmp(NewArgv[1], "-c") == 0) {
+ /* Use the extra slot before NewArgv so we can store --login. */
+ NewArgv--;
+ NewArgc++;
+ NewArgv[0] = NewArgv[1];
+ NewArgv[1] = "--login";
+ }
+
+#if defined(_AIX) || (defined(__linux__) && !defined(HAVE_PAM))
+ /* Insert system-wide environment variables. */
+ if (!read_env_file(_PATH_ENVIRONMENT, true, false))
+ sudo_warn("%s", _PATH_ENVIRONMENT);
+#endif
+#ifdef HAVE_LOGIN_CAP_H
+ /* Set environment based on login class. */
+ if (login_class) {
+ login_cap_t *lc = login_getclass(login_class);
+ if (lc != NULL) {
+ setusercontext(lc, runas_pw, runas_pw->pw_uid, LOGIN_SETPATH|LOGIN_SETENV);
+ login_close(lc);
+ }
+ }
+#endif /* HAVE_LOGIN_CAP_H */
+ }
+
+ /* Insert system-wide environment variables. */
+ if (def_restricted_env_file) {
+ if (!read_env_file(def_env_file, false, true))
+ sudo_warn("%s", def_restricted_env_file);
+ }
+ if (def_env_file) {
+ if (!read_env_file(def_env_file, false, false))
+ sudo_warn("%s", def_env_file);
+ }
+
+ /* Insert user-specified environment variables. */
+ if (!insert_env_vars(sudo_user.env_vars))
+ goto done;
+
+ /* Note: must call audit before uid change. */
+ if (ISSET(sudo_mode, MODE_EDIT)) {
+ int edit_argc;
+ const char *env_editor;
+
+ free(safe_cmnd);
+ safe_cmnd = find_editor(NewArgc - 1, NewArgv + 1, &edit_argc,
+ &edit_argv, NULL, &env_editor, false);
+ if (safe_cmnd == NULL) {
+ if (errno != ENOENT)
+ goto done;
+ audit_failure(NewArgc, NewArgv, N_("%s: command not found"),
+ env_editor ? env_editor : def_editor);
+ sudo_warnx(U_("%s: command not found"),
+ env_editor ? env_editor : def_editor);
+ goto bad;
+ }
+ if (audit_success(edit_argc, edit_argv) != 0 && !def_ignore_audit_errors)
+ goto done;
+
+ /* We want to run the editor with the unmodified environment. */
+ env_swap_old();
+ } else {
+ if (audit_success(NewArgc, NewArgv) != 0 && !def_ignore_audit_errors)
+ goto done;
+ }
+
+ /* Setup execution environment to pass back to front-end. */
+ ret = sudoers_policy_exec_setup(edit_argv ? edit_argv : NewArgv,
+ env_get(), cmnd_umask, iolog_path, closure);
+
+ /* Zero out stashed copy of environment, it is owned by the front-end. */
+ (void)env_init(NULL);
+
+ goto done;
+
+bad:
+ ret = false;
+
+done:
+ if (!rewind_perms())
+ ret = -1;
+
+ restore_nproc();
+
+ /* Destroy the password and group caches and free the contents. */
+ sudo_freepwcache();
+ sudo_freegrcache();
+
+ sudo_warn_set_locale_func(NULL);
+
+ debug_return_int(ret);
+}
+
+/*
+ * Initialize timezone and fill in sudo_user struct.
+ */
+static bool
+init_vars(char * const envp[])
+{
+ char * const * ep;
+ bool unknown_user = false;
+ debug_decl(init_vars, SUDOERS_DEBUG_PLUGIN)
+
+ if (!sudoers_initlocale(setlocale(LC_ALL, NULL), def_sudoers_locale)) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+
+#define MATCHES(s, v) \
+ (strncmp((s), (v), sizeof(v) - 1) == 0 && (s)[sizeof(v) - 1] != '\0')
+
+ for (ep = envp; *ep; ep++) {
+ switch (**ep) {
+ case 'K':
+ if (MATCHES(*ep, "KRB5CCNAME="))
+ user_ccname = *ep + sizeof("KRB5CCNAME=") - 1;
+ break;
+ case 'P':
+ if (MATCHES(*ep, "PATH="))
+ user_path = *ep + sizeof("PATH=") - 1;
+ break;
+ case 'S':
+ if (MATCHES(*ep, "SUDO_PROMPT=")) {
+ /* Don't override "sudo -p prompt" */
+ if (user_prompt == NULL)
+ user_prompt = *ep + sizeof("SUDO_PROMPT=") - 1;
+ break;
+ }
+ if (MATCHES(*ep, "SUDO_USER="))
+ prev_user = *ep + sizeof("SUDO_USER=") - 1;
+ break;
+ }
+ }
+#undef MATCHES
+
+ /*
+ * Get a local copy of the user's passwd struct and group list if we
+ * don't already have them.
+ */
+ if (sudo_user.pw == NULL) {
+ if ((sudo_user.pw = sudo_getpwnam(user_name)) == NULL) {
+ /*
+ * It is not unusual for users to place "sudo -k" in a .logout
+ * file which can cause sudo to be run during reboot after the
+ * YP/NIS/NIS+/LDAP/etc daemon has died.
+ */
+ if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) {
+ sudo_warnx(U_("unknown uid: %u"), (unsigned int) user_uid);
+ debug_return_bool(false);
+ }
+
+ /* Need to make a fake struct passwd for the call to log_warningx(). */
+ sudo_user.pw = sudo_mkpwent(user_name, user_uid, user_gid, NULL, NULL);
+ unknown_user = true;
+ }
+ }
+ if (user_gid_list == NULL)
+ user_gid_list = sudo_get_gidlist(sudo_user.pw, ENTRY_TYPE_ANY);
+
+ /* Store initialize permissions so we can restore them later. */
+ if (!set_perms(PERM_INITIAL))
+ debug_return_bool(false);
+
+ /* Set fqdn callback. */
+ sudo_defs_table[I_FQDN].callback = cb_fqdn;
+
+ /* Set group_plugin callback. */
+ sudo_defs_table[I_GROUP_PLUGIN].callback = cb_group_plugin;
+
+ /* Set runas callback. */
+ sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;
+
+ /* Set locale callback. */
+ sudo_defs_table[I_SUDOERS_LOCALE].callback = sudoers_locale_callback;
+
+ /* Set maxseq callback. */
+ sudo_defs_table[I_MAXSEQ].callback = cb_maxseq;
+
+ /* Set iolog_user callback. */
+ sudo_defs_table[I_IOLOG_USER].callback = cb_iolog_user;
+
+ /* Set iolog_group callback. */
+ sudo_defs_table[I_IOLOG_GROUP].callback = cb_iolog_group;
+
+ /* Set iolog_mode callback. */
+ sudo_defs_table[I_IOLOG_MODE].callback = cb_iolog_mode;
+
+ /* Set tty_tickets callback. */
+ sudo_defs_table[I_TTY_TICKETS].callback = cb_tty_tickets;
+
+ /* It is now safe to use log_warningx() and set_perms() */
+ if (unknown_user) {
+ log_warningx(SLOG_SEND_MAIL, N_("unknown uid: %u"),
+ (unsigned int) user_uid);
+ debug_return_bool(false);
+ }
+
+ /*
+ * Set runas passwd/group entries based on command line or sudoers.
+ * Note that if runas_group was specified without runas_user we
+ * run the command as the invoking user.
+ */
+ if (runas_group != NULL) {
+ if (!set_runasgr(runas_group, false))
+ debug_return_bool(false);
+ if (!set_runaspw(runas_user ? runas_user : user_name, false))
+ debug_return_bool(false);
+ } else {
+ if (!set_runaspw(runas_user ? runas_user : def_runas_default, false))
+ debug_return_bool(false);
+ }
+
+ debug_return_bool(true);
+}
+
+/*
+ * Fill in user_cmnd, user_args, user_base and user_stat variables
+ * and apply any command-specific defaults entries.
+ */
+static int
+set_cmnd(void)
+{
+ struct sudo_nss *nss;
+ char *path = user_path;
+ int ret = FOUND;
+ debug_decl(set_cmnd, SUDOERS_DEBUG_PLUGIN)
+
+ /* Allocate user_stat for find_path() and match functions. */
+ user_stat = calloc(1, sizeof(struct stat));
+ if (user_stat == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(NOT_FOUND_ERROR);
+ }
+
+ /* Default value for cmnd, overridden below. */
+ if (user_cmnd == NULL)
+ user_cmnd = NewArgv[0];
+
+ if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) {
+ if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) {
+ if (def_secure_path && !user_is_exempt())
+ path = def_secure_path;
+ if (!set_perms(PERM_RUNAS))
+ debug_return_int(-1);
+ ret = find_path(NewArgv[0], &user_cmnd, user_stat, path,
+ def_ignore_dot, NULL);
+ if (!restore_perms())
+ debug_return_int(-1);
+ if (ret == NOT_FOUND) {
+ /* Failed as root, try as invoking user. */
+ if (!set_perms(PERM_USER))
+ debug_return_int(-1);
+ ret = find_path(NewArgv[0], &user_cmnd, user_stat, path,
+ def_ignore_dot, NULL);
+ if (!restore_perms())
+ debug_return_int(-1);
+ }
+ if (ret == NOT_FOUND_ERROR) {
+ if (errno == ENAMETOOLONG)
+ audit_failure(NewArgc, NewArgv, N_("command too long"));
+ log_warning(0, "%s", NewArgv[0]);
+ debug_return_int(ret);
+ }
+ }
+
+ /* set user_args */
+ if (NewArgc > 1) {
+ char *to, *from, **av;
+ size_t size, n;
+
+ /* Alloc and build up user_args. */
+ for (size = 0, av = NewArgv + 1; *av; av++)
+ size += strlen(*av) + 1;
+ if (size == 0 || (user_args = malloc(size)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+ if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) {
+ /*
+ * When running a command via a shell, the sudo front-end
+ * escapes potential meta chars. We unescape non-spaces
+ * for sudoers matching and logging purposes.
+ */
+ for (to = user_args, av = NewArgv + 1; (from = *av); av++) {
+ while (*from) {
+ if (from[0] == '\\' && !isspace((unsigned char)from[1]))
+ from++;
+ *to++ = *from++;
+ }
+ *to++ = ' ';
+ }
+ *--to = '\0';
+ } else {
+ for (to = user_args, av = NewArgv + 1; *av; av++) {
+ n = strlcpy(to, *av, size - (to - user_args));
+ if (n >= size - (to - user_args)) {
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ debug_return_int(-1);
+ }
+ to += n;
+ *to++ = ' ';
+ }
+ *--to = '\0';
+ }
+ }
+ }
+
+ if ((user_base = strrchr(user_cmnd, '/')) != NULL)
+ user_base++;
+ else
+ user_base = user_cmnd;
+
+ TAILQ_FOREACH(nss, snl, entries) {
+ if (!update_defaults(nss->parse_tree, NULL, SETDEF_CMND, false)) {
+ log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR,
+ N_("problem with defaults entries"));
+ }
+ }
+
+ debug_return_int(ret);
+}
+
+/*
+ * Open sudoers and sanity check mode/owner/type.
+ * Returns a handle to the sudoers file or NULL on error.
+ */
+FILE *
+open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
+{
+ struct stat sb;
+ FILE *fp = NULL;
+ debug_decl(open_sudoers, SUDOERS_DEBUG_PLUGIN)
+
+ if (!set_perms(PERM_SUDOERS))
+ debug_return_ptr(NULL);
+
+ switch (sudo_secure_file(sudoers, sudoers_uid, sudoers_gid, &sb)) {
+ case SUDO_PATH_SECURE:
+ /*
+ * If we are expecting sudoers to be group readable by
+ * SUDOERS_GID but it is not, we must open the file as root,
+ * not uid 1.
+ */
+ if (sudoers_uid == ROOT_UID && ISSET(sudoers_mode, S_IRGRP)) {
+ if (!ISSET(sb.st_mode, S_IRGRP) || sb.st_gid != SUDOERS_GID) {
+ if (!restore_perms() || !set_perms(PERM_ROOT))
+ debug_return_ptr(NULL);
+ }
+ }
+ /*
+ * Open sudoers and make sure we can read it so we can present
+ * the user with a reasonable error message (unlike the lexer).
+ */
+ if ((fp = fopen(sudoers, "r")) == NULL) {
+ log_warning(SLOG_SEND_MAIL, N_("unable to open %s"), sudoers);
+ } else {
+ if (sb.st_size != 0 && fgetc(fp) == EOF) {
+ log_warning(SLOG_SEND_MAIL,
+ N_("unable to read %s"), sudoers);
+ fclose(fp);
+ fp = NULL;
+ } else {
+ /* Rewind fp and set close on exec flag. */
+ rewind(fp);
+ (void) fcntl(fileno(fp), F_SETFD, 1);
+ }
+ }
+ break;
+ case SUDO_PATH_MISSING:
+ log_warning(SLOG_SEND_MAIL, N_("unable to stat %s"), sudoers);
+ break;
+ case SUDO_PATH_BAD_TYPE:
+ log_warningx(SLOG_SEND_MAIL,
+ N_("%s is not a regular file"), sudoers);
+ break;
+ case SUDO_PATH_WRONG_OWNER:
+ log_warningx(SLOG_SEND_MAIL,
+ N_("%s is owned by uid %u, should be %u"), sudoers,
+ (unsigned int) sb.st_uid, (unsigned int) sudoers_uid);
+ break;
+ case SUDO_PATH_WORLD_WRITABLE:
+ log_warningx(SLOG_SEND_MAIL, N_("%s is world writable"), sudoers);
+ break;
+ case SUDO_PATH_GROUP_WRITABLE:
+ log_warningx(SLOG_SEND_MAIL,
+ N_("%s is owned by gid %u, should be %u"), sudoers,
+ (unsigned int) sb.st_gid, (unsigned int) sudoers_gid);
+ break;
+ default:
+ /* NOTREACHED */
+ break;
+ }
+
+ if (!restore_perms()) {
+ /* unable to change back to root */
+ if (fp != NULL) {
+ fclose(fp);
+ fp = NULL;
+ }
+ }
+
+ debug_return_ptr(fp);
+}
+
+#ifdef HAVE_LOGIN_CAP_H
+static bool
+set_loginclass(struct passwd *pw)
+{
+ const int errflags = SLOG_RAW_MSG;
+ login_cap_t *lc;
+ bool ret = true;
+ debug_decl(set_loginclass, SUDOERS_DEBUG_PLUGIN)
+
+ if (!def_use_loginclass)
+ goto done;
+
+ if (login_class && strcmp(login_class, "-") != 0) {
+ if (user_uid != 0 && pw->pw_uid != 0) {
+ sudo_warnx(U_("only root can use \"-c %s\""), login_class);
+ ret = false;
+ goto done;
+ }
+ } else {
+ login_class = pw->pw_class;
+ if (!login_class || !*login_class)
+ login_class =
+ (pw->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS;
+ }
+
+ /* Make sure specified login class is valid. */
+ lc = login_getclass(login_class);
+ if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) {
+ /*
+ * Don't make it an error if the user didn't specify the login
+ * class themselves. We do this because if login.conf gets
+ * corrupted we want the admin to be able to use sudo to fix it.
+ */
+ log_warningx(errflags, N_("unknown login class: %s"), login_class);
+ def_use_loginclass = false;
+ if (login_class)
+ ret = false;
+ }
+ login_close(lc);
+done:
+ debug_return_bool(ret);
+}
+#else
+static bool
+set_loginclass(struct passwd *pw)
+{
+ return true;
+}
+#endif /* HAVE_LOGIN_CAP_H */
+
+#ifndef AI_FQDN
+# define AI_FQDN AI_CANONNAME
+#endif
+
+/*
+ * Look up the fully qualified domain name of host.
+ * Use AI_FQDN if available since "canonical" is not always the same as fqdn.
+ * Returns true on success, setting longp and shortp.
+ * Returns false on failure, longp and shortp are unchanged.
+ */
+static int
+resolve_host(const char *host, char **longp, char **shortp)
+{
+ struct addrinfo *res0, hint;
+ char *cp, *lname, *sname;
+ int ret;
+ debug_decl(resolve_host, SUDOERS_DEBUG_PLUGIN)
+
+ memset(&hint, 0, sizeof(hint));
+ hint.ai_family = PF_UNSPEC;
+ hint.ai_flags = AI_FQDN;
+
+ if ((ret = getaddrinfo(host, NULL, &hint, &res0)) != 0)
+ debug_return_int(ret);
+ if ((lname = strdup(res0->ai_canonname)) == NULL) {
+ freeaddrinfo(res0);
+ debug_return_int(EAI_MEMORY);
+ }
+ if ((cp = strchr(lname, '.')) != NULL) {
+ sname = strndup(lname, (size_t)(cp - lname));
+ if (sname == NULL) {
+ free(lname);
+ freeaddrinfo(res0);
+ debug_return_int(EAI_MEMORY);
+ }
+ } else {
+ sname = lname;
+ }
+ freeaddrinfo(res0);
+ *longp = lname;
+ *shortp = sname;
+
+ debug_return_int(0);
+}
+
+/*
+ * Look up the fully qualified domain name of user_host and user_runhost.
+ * Sets user_host, user_shost, user_runhost and user_srunhost.
+ */
+static bool
+cb_fqdn(const union sudo_defs_val *sd_un)
+{
+ bool remote;
+ char *lhost, *shost;
+ debug_decl(cb_fqdn, SUDOERS_DEBUG_PLUGIN)
+
+ /* Nothing to do if fqdn flag is disabled. */
+ if (sd_un != NULL && !sd_un->flag)
+ debug_return_bool(true);
+
+ /* If the -h flag was given we need to resolve both host and runhost. */
+ remote = strcmp(user_runhost, user_host) != 0;
+
+ /* First resolve user_host, setting user_host and user_shost. */
+ if (resolve_host(user_host, &lhost, &shost) != 0) {
+ int rc = resolve_host(user_runhost, &lhost, &shost);
+ if (rc != 0) {
+ gai_log_warning(SLOG_SEND_MAIL|SLOG_RAW_MSG, rc,
+ N_("unable to resolve host %s"), user_host);
+ debug_return_bool(false);
+ }
+ }
+ if (user_shost != user_host)
+ free(user_shost);
+ free(user_host);
+ user_host = lhost;
+ user_shost = shost;
+
+ /* Next resolve user_runhost, setting user_runhost and user_srunhost. */
+ lhost = shost = NULL;
+ if (remote) {
+ if (!resolve_host(user_runhost, &lhost, &shost)) {
+ sudo_warnx(U_("unable to resolve host %s"), user_runhost);
+ }
+ } else {
+ /* Not remote, just use user_host. */
+ if ((lhost = strdup(user_host)) != NULL) {
+ if (user_shost != user_host)
+ shost = strdup(user_shost);
+ else
+ shost = lhost;
+ }
+ if (lhost == NULL || shost == NULL) {
+ free(lhost);
+ if (lhost != shost)
+ free(shost);
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ }
+ if (lhost != NULL && shost != NULL) {
+ if (user_srunhost != user_runhost)
+ free(user_srunhost);
+ free(user_runhost);
+ user_runhost = lhost;
+ user_srunhost = shost;
+ }
+
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "host %s, shost %s, runhost %s, srunhost %s",
+ user_host, user_shost, user_runhost, user_srunhost);
+ debug_return_bool(true);
+}
+
+/*
+ * Get passwd entry for the user we are going to run commands as
+ * and store it in runas_pw. By default, commands run as "root".
+ */
+static bool
+set_runaspw(const char *user, bool quiet)
+{
+ struct passwd *pw = NULL;
+ debug_decl(set_runaspw, SUDOERS_DEBUG_PLUGIN)
+
+ if (*user == '#') {
+ const char *errstr;
+ uid_t uid = sudo_strtoid(user + 1, NULL, NULL, &errstr);
+ if (errstr == NULL) {
+ if ((pw = sudo_getpwuid(uid)) == NULL)
+ pw = sudo_fakepwnam(user, user_gid);
+ }
+ }
+ if (pw == NULL) {
+ if ((pw = sudo_getpwnam(user)) == NULL) {
+ if (!quiet)
+ log_warningx(SLOG_RAW_MSG, N_("unknown user: %s"), user);
+ debug_return_bool(false);
+ }
+ }
+ if (runas_pw != NULL)
+ sudo_pw_delref(runas_pw);
+ runas_pw = pw;
+ debug_return_bool(true);
+}
+
+/*
+ * Get group entry for the group we are going to run commands as
+ * and store it in runas_gr.
+ */
+static bool
+set_runasgr(const char *group, bool quiet)
+{
+ struct group *gr = NULL;
+ debug_decl(set_runasgr, SUDOERS_DEBUG_PLUGIN)
+
+ if (*group == '#') {
+ const char *errstr;
+ gid_t gid = sudo_strtoid(group + 1, NULL, NULL, &errstr);
+ if (errstr == NULL) {
+ if ((gr = sudo_getgrgid(gid)) == NULL)
+ gr = sudo_fakegrnam(group);
+ }
+ }
+ if (gr == NULL) {
+ if ((gr = sudo_getgrnam(group)) == NULL) {
+ if (!quiet)
+ log_warningx(SLOG_RAW_MSG, N_("unknown group: %s"), group);
+ debug_return_bool(false);
+ }
+ }
+ if (runas_gr != NULL)
+ sudo_gr_delref(runas_gr);
+ runas_gr = gr;
+ debug_return_bool(true);
+}
+
+/*
+ * Callback for runas_default sudoers setting.
+ */
+static bool
+cb_runas_default(const union sudo_defs_val *sd_un)
+{
+ debug_decl(cb_runas_default, SUDOERS_DEBUG_PLUGIN)
+
+ /* Only reset runaspw if user didn't specify one. */
+ if (!runas_user && !runas_group)
+ debug_return_bool(set_runaspw(sd_un->str, true));
+ debug_return_bool(true);
+}
+
+/*
+ * Callback for runas_default sudoers setting.
+ */
+static bool
+cb_tty_tickets(const union sudo_defs_val *sd_un)
+{
+ debug_decl(cb_tty_tickets, SUDOERS_DEBUG_PLUGIN)
+
+ /* Convert tty_tickets -> timestamp_type */
+ if (sd_un->flag)
+ def_timestamp_type = tty;
+ else
+ def_timestamp_type = global;
+ debug_return_bool(true);
+}
+
+/*
+ * Cleanup hook for sudo_fatal()/sudo_fatalx()
+ */
+void
+sudoers_cleanup(void)
+{
+ struct sudo_nss *nss;
+ debug_decl(sudoers_cleanup, SUDOERS_DEBUG_PLUGIN)
+
+ if (snl != NULL) {
+ TAILQ_FOREACH(nss, snl, entries) {
+ nss->close(nss);
+ }
+ }
+ if (def_group_plugin)
+ group_plugin_unload();
+ sudo_freepwcache();
+ sudo_freegrcache();
+
+ debug_return;
+}
+
+#ifdef USE_ADMIN_FLAG
+static int
+create_admin_success_flag(void)
+{
+ char flagfile[PATH_MAX];
+ int len, ret = -1;
+ debug_decl(create_admin_success_flag, SUDOERS_DEBUG_PLUGIN)
+
+ /* Check whether the user is in the sudo or admin group. */
+ if (!user_in_group(sudo_user.pw, "sudo") &&
+ !user_in_group(sudo_user.pw, "admin"))
+ debug_return_int(true);
+
+ /* Build path to flag file. */
+ len = snprintf(flagfile, sizeof(flagfile), "%s/.sudo_as_admin_successful",
+ user_dir);
+ if (len <= 0 || (size_t)len >= sizeof(flagfile))
+ debug_return_int(false);
+
+ /* Create admin flag file if it doesn't already exist. */
+ if (set_perms(PERM_USER)) {
+ int fd = open(flagfile, O_CREAT|O_WRONLY|O_NONBLOCK|O_EXCL, 0644);
+ ret = fd != -1 || errno == EEXIST;
+ if (fd != -1)
+ close(fd);
+ if (!restore_perms())
+ ret = -1;
+ }
+ debug_return_int(ret);
+}
+#else /* !USE_ADMIN_FLAG */
+static int
+create_admin_success_flag(void)
+{
+ /* STUB */
+ return true;
+}
+#endif /* USE_ADMIN_FLAG */
+
+static bool
+tty_present(void)
+{
+#if defined(HAVE_KINFO_PROC2_NETBSD) || defined(HAVE_KINFO_PROC_OPENBSD) || defined(HAVE_KINFO_PROC_FREEBSD) || defined(HAVE_KINFO_PROC_44BSD) || defined(HAVE_STRUCT_PSINFO_PR_TTYDEV) || defined(HAVE_PSTAT_GETPROC) || defined(__linux__)
+ return user_ttypath != NULL;
+#else
+ int fd = open(_PATH_TTY, O_RDWR);
+ if (fd != -1)
+ close(fd);
+ return fd != -1;
+#endif
+}
diff --git a/plugins/sudoers/sudoers.exp b/plugins/sudoers/sudoers.exp
new file mode 100644
index 0000000..d52ef1e
--- /dev/null
+++ b/plugins/sudoers/sudoers.exp
@@ -0,0 +1,6 @@
+sudoers_policy
+sudoers_io
+sudo_getgrgid
+sudo_getgrnam
+sudo_gr_addref
+sudo_gr_delref
diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h
new file mode 100644
index 0000000..28dbbb3
--- /dev/null
+++ b/plugins/sudoers/sudoers.h
@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 1993-1996, 1998-2005, 2007-2017
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#ifndef SUDOERS_SUDOERS_H
+#define SUDOERS_SUDOERS_H
+
+#include <limits.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+
+#define DEFAULT_TEXT_DOMAIN "sudoers"
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include <pathnames.h>
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_queue.h"
+#include "defaults.h"
+#include "logging.h"
+#include "parse.h"
+#include "sudo_nss.h"
+#include "sudo_plugin.h"
+#include "sudo_conf.h"
+#include "sudo_util.h"
+#include "sudoers_debug.h"
+
+/*
+ * Supplementary group IDs for a user.
+ */
+struct gid_list {
+ int ngids;
+ GETGROUPS_T *gids;
+};
+
+/*
+ * Supplementary group names for a user.
+ */
+struct group_list {
+ int ngroups;
+ char **groups;
+};
+
+/*
+ * Info pertaining to the invoking user.
+ */
+struct sudo_user {
+ struct passwd *pw;
+ struct passwd *_runas_pw;
+ struct group *_runas_gr;
+ struct stat *cmnd_stat;
+ char *name;
+ char *path;
+ char *tty;
+ char *ttypath;
+ char *host;
+ char *shost;
+ char *runhost;
+ char *srunhost;
+ char *prompt;
+ char *cmnd;
+ char *cmnd_args;
+ char *cmnd_base;
+ char *cmnd_safe;
+ char *class_name;
+ char *krb5_ccname;
+ struct gid_list *gid_list;
+ char * const * env_vars;
+#ifdef HAVE_SELINUX
+ char *role;
+ char *type;
+#endif
+#ifdef HAVE_PRIV_SET
+ char *privs;
+ char *limitprivs;
+#endif
+ const char *cwd;
+ char *iolog_file;
+ GETGROUPS_T *gids;
+ int execfd;
+ int ngids;
+ int closefrom;
+ int lines;
+ int cols;
+ int flags;
+ int max_groups;
+ int timeout;
+ mode_t umask;
+ uid_t uid;
+ uid_t gid;
+ pid_t sid;
+};
+
+/*
+ * sudo_get_gidlist() type values
+ */
+#define ENTRY_TYPE_ANY 0x00
+#define ENTRY_TYPE_QUERIED 0x01
+#define ENTRY_TYPE_FRONTEND 0x02
+
+/*
+ * sudo_user flag values
+ */
+#define RUNAS_USER_SPECIFIED 0x01
+#define RUNAS_GROUP_SPECIFIED 0x02
+
+/*
+ * Return values for sudoers_lookup(), also used as arguments for log_auth()
+ * Note: cannot use '0' as a value here.
+ */
+#define VALIDATE_ERROR 0x001
+#define VALIDATE_SUCCESS 0x002
+#define VALIDATE_FAILURE 0x004
+#define FLAG_CHECK_USER 0x010
+#define FLAG_NO_USER 0x020
+#define FLAG_NO_HOST 0x040
+#define FLAG_NO_CHECK 0x080
+#define FLAG_NON_INTERACTIVE 0x100
+#define FLAG_BAD_PASSWORD 0x200
+
+/*
+ * find_path()/set_cmnd() return values
+ */
+#define FOUND 0
+#define NOT_FOUND 1
+#define NOT_FOUND_DOT 2
+#define NOT_FOUND_ERROR 3
+#define NOT_FOUND_PATH 4
+
+/*
+ * Various modes sudo can be in (based on arguments) in hex
+ */
+#define MODE_RUN 0x00000001
+#define MODE_EDIT 0x00000002
+#define MODE_VALIDATE 0x00000004
+#define MODE_INVALIDATE 0x00000008
+#define MODE_KILL 0x00000010
+#define MODE_VERSION 0x00000020
+#define MODE_HELP 0x00000040
+#define MODE_LIST 0x00000080
+#define MODE_CHECK 0x00000100
+#define MODE_ERROR 0x00000200
+#define MODE_MASK 0x0000ffff
+
+/* Mode flags */
+#define MODE_BACKGROUND 0x00010000 /* XXX - unused */
+#define MODE_SHELL 0x00020000
+#define MODE_LOGIN_SHELL 0x00040000
+#define MODE_IMPLIED_SHELL 0x00080000
+#define MODE_RESET_HOME 0x00100000
+#define MODE_PRESERVE_GROUPS 0x00200000
+#define MODE_PRESERVE_ENV 0x00400000
+#define MODE_NONINTERACTIVE 0x00800000
+#define MODE_IGNORE_TICKET 0x01000000
+
+/*
+ * Used with set_perms()
+ */
+#define PERM_INITIAL 0x00
+#define PERM_ROOT 0x01
+#define PERM_USER 0x02
+#define PERM_FULL_USER 0x03
+#define PERM_SUDOERS 0x04
+#define PERM_RUNAS 0x05
+#define PERM_TIMESTAMP 0x06
+#define PERM_IOLOG 0x07
+
+/*
+ * Shortcuts for sudo_user contents.
+ */
+#define user_name (sudo_user.name)
+#define user_uid (sudo_user.uid)
+#define user_gid (sudo_user.gid)
+#define user_sid (sudo_user.sid)
+#define user_umask (sudo_user.umask)
+#define user_passwd (sudo_user.pw->pw_passwd)
+#define user_dir (sudo_user.pw->pw_dir)
+#define user_gids (sudo_user.gids)
+#define user_ngids (sudo_user.ngids)
+#define user_gid_list (sudo_user.gid_list)
+#define user_tty (sudo_user.tty)
+#define user_ttypath (sudo_user.ttypath)
+#define user_cwd (sudo_user.cwd)
+#define user_cmnd (sudo_user.cmnd)
+#define user_args (sudo_user.cmnd_args)
+#define user_base (sudo_user.cmnd_base)
+#define user_stat (sudo_user.cmnd_stat)
+#define user_path (sudo_user.path)
+#define user_prompt (sudo_user.prompt)
+#define user_host (sudo_user.host)
+#define user_shost (sudo_user.shost)
+#define user_runhost (sudo_user.runhost)
+#define user_srunhost (sudo_user.srunhost)
+#define user_ccname (sudo_user.krb5_ccname)
+#define safe_cmnd (sudo_user.cmnd_safe)
+#define cmnd_fd (sudo_user.execfd)
+#define login_class (sudo_user.class_name)
+#define runas_pw (sudo_user._runas_pw)
+#define runas_gr (sudo_user._runas_gr)
+#define user_role (sudo_user.role)
+#define user_type (sudo_user.type)
+#define user_closefrom (sudo_user.closefrom)
+#define runas_privs (sudo_user.privs)
+#define runas_limitprivs (sudo_user.limitprivs)
+#define user_timeout (sudo_user.timeout)
+
+#ifdef __TANDEM
+# define ROOT_UID 65535
+#else
+# define ROOT_UID 0
+#endif
+#define ROOT_GID 0
+
+struct sudo_lbuf;
+struct passwd;
+struct stat;
+struct timespec;
+
+/*
+ * Function prototypes
+ */
+#define YY_DECL int sudoerslex(void)
+
+/* goodpath.c */
+bool sudo_goodpath(const char *path, struct stat *sbp);
+
+/* findpath.c */
+int find_path(const char *infile, char **outfile, struct stat *sbp,
+ const char *path, int ignore_dot, char * const *whitelist);
+
+/* check.c */
+int check_user(int validate, int mode);
+bool user_is_exempt(void);
+
+/* prompt.c */
+char *expand_prompt(const char *old_prompt, const char *auth_user);
+
+/* timestamp.c */
+int timestamp_remove(bool unlinkit);
+
+/* sudo_auth.c */
+bool sudo_auth_needs_end_session(void);
+int verify_user(struct passwd *pw, char *prompt, int validated, struct sudo_conv_callback *callback);
+int sudo_auth_begin_session(struct passwd *pw, char **user_env[]);
+int sudo_auth_end_session(struct passwd *pw);
+int sudo_auth_init(struct passwd *pw);
+int sudo_auth_approval(struct passwd *pw, int validated, bool exempt);
+int sudo_auth_cleanup(struct passwd *pw);
+
+/* set_perms.c */
+bool rewind_perms(void);
+bool set_perms(int);
+bool restore_perms(void);
+int pam_prep_user(struct passwd *);
+
+/* gram.y */
+int sudoersparse(void);
+extern char *login_style;
+extern char *errorfile;
+extern int errorlineno;
+extern bool parse_error;
+extern bool sudoers_warnings;
+
+/* toke.l */
+YY_DECL;
+extern FILE *sudoersin;
+extern const char *sudoers_file;
+extern char *sudoers;
+extern mode_t sudoers_mode;
+extern uid_t sudoers_uid;
+extern gid_t sudoers_gid;
+extern int sudolineno;
+extern int last_token;
+
+/* defaults.c */
+void dump_defaults(void);
+void dump_auth_methods(void);
+
+/* getspwuid.c */
+char *sudo_getepw(const struct passwd *);
+
+/* pwutil.c */
+typedef struct cache_item * (*sudo_make_pwitem_t)(uid_t uid, const char *user);
+typedef struct cache_item * (*sudo_make_gritem_t)(gid_t gid, const char *group);
+typedef struct cache_item * (*sudo_make_gidlist_item_t)(const struct passwd *pw, char * const *gids, unsigned int type);
+typedef struct cache_item * (*sudo_make_grlist_item_t)(const struct passwd *pw, char * const *groups);
+__dso_public struct group *sudo_getgrgid(gid_t);
+__dso_public struct group *sudo_getgrnam(const char *);
+__dso_public void sudo_gr_addref(struct group *);
+__dso_public void sudo_gr_delref(struct group *);
+bool user_in_group(const struct passwd *, const char *);
+struct group *sudo_fakegrnam(const char *);
+struct gid_list *sudo_get_gidlist(const struct passwd *pw, unsigned int type);
+struct group_list *sudo_get_grlist(const struct passwd *pw);
+struct passwd *sudo_fakepwnam(const char *, gid_t);
+struct passwd *sudo_mkpwent(const char *user, uid_t uid, gid_t gid, const char *home, const char *shell);
+struct passwd *sudo_getpwnam(const char *);
+struct passwd *sudo_getpwuid(uid_t);
+void sudo_endspent(void);
+void sudo_freegrcache(void);
+void sudo_freepwcache(void);
+void sudo_gidlist_addref(struct gid_list *);
+void sudo_gidlist_delref(struct gid_list *);
+void sudo_grlist_addref(struct group_list *);
+void sudo_grlist_delref(struct group_list *);
+void sudo_pw_addref(struct passwd *);
+void sudo_pw_delref(struct passwd *);
+int sudo_set_gidlist(struct passwd *pw, char * const *gids, unsigned int type);
+int sudo_set_grlist(struct passwd *pw, char * const *groups);
+void sudo_pwutil_set_backend(sudo_make_pwitem_t, sudo_make_gritem_t, sudo_make_gidlist_item_t, sudo_make_grlist_item_t);
+void sudo_setspent(void);
+
+/* timestr.c */
+char *get_timestr(time_t, int);
+
+/* boottime.c */
+bool get_boottime(struct timespec *);
+
+/* iolog.c */
+bool io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7]);
+bool cb_maxseq(const union sudo_defs_val *sd_un);
+bool cb_iolog_user(const union sudo_defs_val *sd_un);
+bool cb_iolog_group(const union sudo_defs_val *sd_un);
+bool cb_iolog_mode(const union sudo_defs_val *sd_un);
+extern uid_t iolog_uid;
+extern gid_t iolog_gid;
+
+/* iolog_path.c */
+char *expand_iolog_path(const char *prefix, const char *dir, const char *file,
+ char **slashp);
+
+/* env.c */
+char **env_get(void);
+bool env_merge(char * const envp[]);
+bool env_swap_old(void);
+bool env_init(char * const envp[]);
+bool init_envtables(void);
+bool insert_env_vars(char * const envp[]);
+bool read_env_file(const char *path, bool overwrite, bool restricted);
+bool rebuild_env(void);
+bool validate_env_vars(char * const envp[]);
+int sudo_setenv(const char *var, const char *val, int overwrite);
+int sudo_unsetenv(const char *var);
+char *sudo_getenv(const char *name);
+int sudoers_hook_getenv(const char *name, char **value, void *closure);
+int sudoers_hook_putenv(char *string, void *closure);
+int sudoers_hook_setenv(const char *name, const char *value, int overwrite, void *closure);
+int sudoers_hook_unsetenv(const char *name, void *closure);
+
+/* env_pattern.c */
+bool matches_env_pattern(const char *pattern, const char *var, bool *full_match);
+
+/* sudoers.c */
+FILE *open_sudoers(const char *, bool, bool *);
+int sudoers_policy_init(void *info, char * const envp[]);
+int sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[], bool verbose, void *closure);
+void sudoers_cleanup(void);
+extern struct sudo_user sudo_user;
+extern struct passwd *list_pw;
+extern int sudo_mode;
+extern uid_t timestamp_uid;
+extern gid_t timestamp_gid;
+extern sudo_conv_t sudo_conv;
+extern sudo_printf_t sudo_printf;
+
+/* sudoers_debug.c */
+bool sudoers_debug_parse_flags(struct sudo_conf_debug_file_list *debug_files, const char *entry);
+bool sudoers_debug_register(const char *plugin_path, struct sudo_conf_debug_file_list *debug_files);
+void sudoers_debug_deregister(void);
+
+/* policy.c */
+int sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group);
+int sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask, char *iolog_path, void *v);
+extern const char *path_ldap_conf;
+extern const char *path_ldap_secret;
+
+/* group_plugin.c */
+int group_plugin_load(char *plugin_info);
+void group_plugin_unload(void);
+int group_plugin_query(const char *user, const char *group,
+ const struct passwd *pwd);
+bool cb_group_plugin(const union sudo_defs_val *sd_un);
+extern const char *path_plugin_dir;
+
+/* editor.c */
+char *find_editor(int nfiles, char **files, int *argc_out, char ***argv_out,
+ char * const *whitelist, const char **env_editor, bool env_error);
+
+/* mkdir_parents.c */
+bool sudo_mkdir_parents(char *path, uid_t uid, gid_t gid, mode_t mode, bool quiet);
+
+/* gc.c */
+enum sudoers_gc_types {
+ GC_UNKNOWN,
+ GC_VECTOR,
+ GC_PTR
+};
+bool sudoers_gc_add(enum sudoers_gc_types type, void *ptr);
+bool sudoers_gc_remove(enum sudoers_gc_types type, void *ptr);
+void sudoers_gc_init(void);
+
+/* rcstr.c */
+char *rcstr_dup(const char *src);
+char *rcstr_alloc(size_t len);
+char *rcstr_addref(const char *s);
+void rcstr_delref(const char *s);
+
+#endif /* SUDOERS_SUDOERS_H */
diff --git a/plugins/sudoers/sudoers.in b/plugins/sudoers/sudoers.in
new file mode 100644
index 0000000..6216dfd
--- /dev/null
+++ b/plugins/sudoers/sudoers.in
@@ -0,0 +1,97 @@
+## sudoers file.
+##
+## This file MUST be edited with the 'visudo' command as root.
+## Failure to use 'visudo' may result in syntax or file permission errors
+## that prevent sudo from running.
+##
+## See the sudoers man page for the details on how to write a sudoers file.
+##
+
+##
+## Host alias specification
+##
+## Groups of machines. These may include host names (optionally with wildcards),
+## IP addresses, network numbers or netgroups.
+# Host_Alias WEBSERVERS = www1, www2, www3
+
+##
+## User alias specification
+##
+## Groups of users. These may consist of user names, uids, Unix groups,
+## or netgroups.
+# User_Alias ADMINS = millert, dowdy, mikef
+
+##
+## Cmnd alias specification
+##
+## Groups of commands. Often used to group related commands together.
+# Cmnd_Alias PROCESSES = /usr/bin/nice, /bin/kill, /usr/bin/renice, \
+# /usr/bin/pkill, /usr/bin/top
+# Cmnd_Alias REBOOT = /sbin/halt, /sbin/reboot, /sbin/poweroff
+
+##
+## Defaults specification
+##
+## You may wish to keep some of the following environment variables
+## when running commands via sudo.
+##
+## Locale settings
+# Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET"
+##
+## Run X applications through sudo; HOME is used to find the
+## .Xauthority file. Note that other programs use HOME to find
+## configuration files and this may lead to privilege escalation!
+# Defaults env_keep += "HOME"
+##
+## X11 resource path settings
+# Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH"
+##
+## Desktop path settings
+# Defaults env_keep += "QTDIR KDEDIR"
+##
+## Allow sudo-run commands to inherit the callers' ConsoleKit session
+# Defaults env_keep += "XDG_SESSION_COOKIE"
+##
+## Uncomment to enable special input methods. Care should be taken as
+## this may allow users to subvert the command being run via sudo.
+# Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER"
+##
+## Uncomment to use a hard-coded PATH instead of the user's to find commands
+# Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+##
+## Uncomment to send mail if the user does not enter the correct password.
+# Defaults mail_badpass
+##
+## Uncomment to enable logging of a command's output, except for
+## sudoreplay and reboot. Use sudoreplay to play back logged sessions.
+# Defaults log_output
+# Defaults!/usr/bin/sudoreplay !log_output
+# Defaults!/usr/local/bin/sudoreplay !log_output
+# Defaults!REBOOT !log_output
+
+##
+## Runas alias specification
+##
+
+##
+## User privilege specification
+##
+root ALL=(ALL) ALL
+
+## Uncomment to allow members of group wheel to execute any command
+# %wheel ALL=(ALL) ALL
+
+## Same thing without a password
+# %wheel ALL=(ALL) NOPASSWD: ALL
+
+## Uncomment to allow members of group sudo to execute any command
+# %sudo ALL=(ALL) ALL
+
+## Uncomment to allow any user to run sudo if they know the password
+## of the user they are running the command as (root by default).
+# Defaults targetpw # Ask for the password of the target user
+# ALL ALL=(ALL) ALL # WARNING: only use this together with 'Defaults targetpw'
+
+## Read drop-in files from @sysconfdir@/sudoers.d
+## (the '#' here does not indicate a comment)
+#includedir @sysconfdir@/sudoers.d
diff --git a/plugins/sudoers/sudoers_debug.c b/plugins/sudoers/sudoers_debug.c
new file mode 100644
index 0000000..d09ec12
--- /dev/null
+++ b/plugins/sudoers/sudoers_debug.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2014-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <ctype.h>
+
+#include "sudoers.h"
+
+static int sudoers_debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
+
+static const char *const sudoers_subsystem_names[] = {
+ "alias",
+ "audit",
+ "auth",
+ "defaults",
+ "env",
+ "event",
+ "ldap",
+ "logging",
+ "main",
+ "match",
+ "netif",
+ "nss",
+ "parser",
+ "perms",
+ "plugin",
+ "rbtree",
+ "sssd",
+ "util",
+ NULL
+};
+
+#define NUM_SUBSYSTEMS (nitems(sudoers_subsystem_names) - 1)
+
+/* Subsystem IDs assigned at registration time. */
+unsigned int sudoers_subsystem_ids[NUM_SUBSYSTEMS];
+
+/*
+ * Parse the "filename flags,..." debug_flags entry and insert a new
+ * sudo_debug_file struct into debug_files.
+ */
+bool
+sudoers_debug_parse_flags(struct sudo_conf_debug_file_list *debug_files,
+ const char *entry)
+{
+ struct sudo_debug_file *debug_file;
+ const char *filename, *flags;
+ size_t namelen;
+
+ /* Already initialized? */
+ if (sudoers_debug_instance != SUDO_DEBUG_INSTANCE_INITIALIZER)
+ return true;
+
+ /* Only process new-style debug flags: filename flags,... */
+ filename = entry;
+ if (*filename != '/' || (flags = strpbrk(filename, " \t")) == NULL)
+ return true;
+ namelen = (size_t)(flags - filename);
+ while (isblank((unsigned char)*flags))
+ flags++;
+ if (*flags != '\0') {
+ if ((debug_file = calloc(1, sizeof(*debug_file))) == NULL)
+ goto oom;
+ if ((debug_file->debug_file = strndup(filename, namelen)) == NULL)
+ goto oom;
+ if ((debug_file->debug_flags = strdup(flags)) == NULL)
+ goto oom;
+ TAILQ_INSERT_TAIL(debug_files, debug_file, entries);
+ }
+ return true;
+oom:
+ if (debug_file != NULL) {
+ free(debug_file->debug_file);
+ free(debug_file->debug_flags);
+ free(debug_file);
+ }
+ sudo_warnx_nodebug(U_("%s: %s"), "sudoers_debug_parse_flags",
+ U_("unable to allocate memory"));
+ return false;
+}
+
+/*
+ * Register the specified debug files and program with the
+ * debug subsystem, freeing the debug list when done.
+ * Sets the active debug instance as a side effect.
+ */
+bool
+sudoers_debug_register(const char *program,
+ struct sudo_conf_debug_file_list *debug_files)
+{
+ struct sudo_debug_file *debug_file, *debug_next;
+
+ /* Already initialized? */
+ if (sudoers_debug_instance != SUDO_DEBUG_INSTANCE_INITIALIZER) {
+ sudo_debug_set_active_instance(sudoers_debug_instance);
+ }
+
+ /* Setup debugging if indicated. */
+ if (debug_files != NULL && !TAILQ_EMPTY(debug_files)) {
+ if (program != NULL) {
+ sudoers_debug_instance = sudo_debug_register(program,
+ sudoers_subsystem_names, sudoers_subsystem_ids, debug_files);
+ if (sudoers_debug_instance == SUDO_DEBUG_INSTANCE_ERROR)
+ return false;
+ }
+ TAILQ_FOREACH_SAFE(debug_file, debug_files, entries, debug_next) {
+ TAILQ_REMOVE(debug_files, debug_file, entries);
+ free(debug_file->debug_file);
+ free(debug_file->debug_flags);
+ free(debug_file);
+ }
+ }
+ return true;
+}
+
+/*
+ * Deregister sudoers_debug_instance if it is registered.
+ */
+void
+sudoers_debug_deregister(void)
+{
+ debug_decl(sudoers_debug_deregister, SUDOERS_DEBUG_PLUGIN)
+ if (sudoers_debug_instance != SUDO_DEBUG_INSTANCE_INITIALIZER) {
+ sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
+ sudo_debug_deregister(sudoers_debug_instance);
+ sudoers_debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
+ }
+}
diff --git a/plugins/sudoers/sudoers_debug.h b/plugins/sudoers/sudoers_debug.h
new file mode 100644
index 0000000..7a4df4e
--- /dev/null
+++ b/plugins/sudoers/sudoers_debug.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_DEBUG_H
+#define SUDOERS_DEBUG_H
+
+#include "sudo_debug.h"
+
+/*
+ * Sudoers debug subsystems.
+ * Note that sudoers_subsystem_ids[] is filled in at debug registration time.
+ */
+extern unsigned int sudoers_subsystem_ids[];
+#define SUDOERS_DEBUG_ALIAS (sudoers_subsystem_ids[ 0]) /* sudoers alias functions */
+#define SUDOERS_DEBUG_AUDIT (sudoers_subsystem_ids[ 1]) /* audit */
+#define SUDOERS_DEBUG_AUTH (sudoers_subsystem_ids[ 2]) /* authentication functions */
+#define SUDOERS_DEBUG_DEFAULTS (sudoers_subsystem_ids[ 3]) /* sudoers defaults settings */
+#define SUDOERS_DEBUG_ENV (sudoers_subsystem_ids[ 4]) /* environment handling */
+#define SUDOERS_DEBUG_EVENT (sudoers_subsystem_ids[ 5]) /* event handling */
+#define SUDOERS_DEBUG_LDAP (sudoers_subsystem_ids[ 6]) /* sudoers LDAP */
+#define SUDOERS_DEBUG_LOGGING (sudoers_subsystem_ids[ 7]) /* logging functions */
+#define SUDOERS_DEBUG_MAIN (sudoers_subsystem_ids[ 8]) /* main() */
+#define SUDOERS_DEBUG_MATCH (sudoers_subsystem_ids[ 9]) /* sudoers matching */
+#define SUDOERS_DEBUG_NETIF (sudoers_subsystem_ids[10]) /* network interface functions */
+#define SUDOERS_DEBUG_NSS (sudoers_subsystem_ids[11]) /* network service switch */
+#define SUDOERS_DEBUG_PARSER (sudoers_subsystem_ids[12]) /* sudoers parser */
+#define SUDOERS_DEBUG_PERMS (sudoers_subsystem_ids[13]) /* uid/gid swapping functions */
+#define SUDOERS_DEBUG_PLUGIN (sudoers_subsystem_ids[14]) /* main plugin functions */
+#define SUDOERS_DEBUG_RBTREE (sudoers_subsystem_ids[15]) /* red-black tree functions */
+#define SUDOERS_DEBUG_SSSD (sudoers_subsystem_ids[16]) /* sudoers SSSD */
+#define SUDOERS_DEBUG_UTIL (sudoers_subsystem_ids[17]) /* utility functions */
+
+#endif /* SUDOERS_DEBUG_H */
diff --git a/plugins/sudoers/sudoers_version.h b/plugins/sudoers/sudoers_version.h
new file mode 100644
index 0000000..23bb706
--- /dev/null
+++ b/plugins/sudoers/sudoers_version.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2011-2013, 2015, 2017
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Major sudoers grammar changes are documented here.
+ * Note that minor changes such as added Defaults options are not listed here.
+ *
+ * 1 sudo 1.1
+ * 2 sudo 1.3, adds support specifying a directory instead of a command.
+ * 3 sudo 1.3.2, new parser, Aliases have to be upper case
+ * 4 sudo 1.3.2, adds User_Alias
+ * 5 sudo 1.3.4, netgroup support
+ * 6 sudo 1.3.5, support for escaping special chars
+ * 7 sudo 1.3.7, unix group support
+ * 8 sudo 1.4.1, wildcard support
+ * 9 sudo 1.4.2, double quote support in sudoers command line args
+ * 10 sudo 1.4.3, added NOPASSWD tag
+ * 11 sudo 1.4.3, added Runas_Spec
+ * 12 sudo 1.4.3, wildcards may be used in the pathname
+ * 13 sudo 1.4.3, command args of "" means no args allowed
+ * 14 sudo 1.4.4, '(' in command args no longer are a syntax error.
+ * 15 sudo 1.4.4, '!command' works in the presence of runas user or NOPASSWD.
+ * 16 sudo 1.4.4, all-caps user and host names are now handled properly.
+ * 17 sudo 1.5.0, usernames may now begin with a digit
+ * 18 sudo 1.5.3, adds Runas_Alias
+ * 19 sudo 1.5.7, %group may be used in a Runas_List
+ * 20 sudo 1.6.0, The runas user and NOPASSWD tags are now persistent across entries in a command list. A PASSWD tag has been added to reverse NOPASSWD
+ * 21 sudo 1.6.0, The '!' operator can be used in a Runas_Spec or an *_Alias
+ * 22 sudo 1.6.0, a list of hosts may be used in a Host_Spec
+ * 23 sudo 1.6.0, a list of users may be used in a User_Spec
+ * 24 sudo 1.6.0, It is now possible to escape "special" characters in usernames, hostnames, etc with a backslash.
+ * 25 sudo 1.6.0, Added Defaults run-time settings in sudoers.
+ * 26 sudo 1.6.0, relaxed the regexp for matching user, host, group names.
+ * 27 sudo 1.6.1, #uid is now allowed in a Runas_Alias.
+ * 28 sudo 1.6.2, Wildcards are now allowed in hostnames.
+ * 29 sudo 1.6.3p7, escaped special characters may be included in pathnames.
+ * 30 sudo 1.6.8, added NOEXEC and EXEC tags.
+ * 31 sudo 1.6.9, added SETENV and NOSETENV tags.
+ * 32 sudo 1.6.9p4, support for IPv6 address matching.
+ * 33 sudo 1.7.0, #include support.
+ * 34 sudo 1.7.0, Runas_Group support.
+ * 35 sudo 1.7.0, uid may now be used anywhere a username is valid.
+ * 36 sudo 1.7.2, #includedir support.
+ * 37 sudo 1.7.4, per-command Defaults support.
+ * 38 sudo 1.7.4, added LOG_INPUT/LOG_OUTPUT and NOLOG_INPUT/NOLOG_OUTPUT tags
+ * 39 sudo 1.7.6/1.8.1, White space is now permitted within a User_List in a per-user Defaults definition.
+ * 40 sudo 1.7.6/1.8.1, A group ID is now allowed in a User_List or Runas_List.
+ * 41 sudo 1.7.6/1.8.4, Support for relative paths in #include and #includedir
+ * 42 sudo 1.8.6, Support for empty Runas_List (with or without a colon) to mean the invoking user. Support for Solaris Privilege Sets (PRIVS= and LIMITPRIVS=).
+ * 43 sudo 1.8.7, Support for specifying a digest along with the command.
+ * 44 sudo 1.8.13, added MAIL/NOMAIL tags.
+ * 45 sudo 1.8.15, added FOLLOW/NOFOLLOW tags as well as sudoedit_follow and sudoedit_checkdir Defaults.
+ * 46 sudo 1.8.20, added TIMEOUT, NOTBEFORE and NOTAFTER options.
+ */
+
+#ifndef SUDOERS_VERSION_H
+#define SUDOERS_VERSION_H
+
+#define SUDOERS_GRAMMAR_VERSION 46
+
+#endif /* SUDOERS_VERSION_H */
diff --git a/plugins/sudoers/sudoreplay.c b/plugins/sudoers/sudoreplay.c
new file mode 100644
index 0000000..a447cd0
--- /dev/null
+++ b/plugins/sudoers/sudoreplay.c
@@ -0,0 +1,1641 @@
+/*
+ * Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <time.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <dirent.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+#include <regex.h>
+#include <signal.h>
+#include <time.h>
+
+#include <pathnames.h>
+
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "logging.h"
+#include "iolog.h"
+#include "iolog_files.h"
+#include "sudo_queue.h"
+#include "sudo_plugin.h"
+#include "sudo_conf.h"
+#include "sudo_debug.h"
+#include "sudo_event.h"
+#include "sudo_util.h"
+
+#ifdef HAVE_GETOPT_LONG
+# include <getopt.h>
+# else
+# include "compat/getopt.h"
+#endif /* HAVE_GETOPT_LONG */
+
+struct replay_closure {
+ struct sudo_event_base *evbase;
+ struct sudo_event *delay_ev;
+ struct sudo_event *keyboard_ev;
+ struct sudo_event *output_ev;
+ struct sudo_event *sighup_ev;
+ struct sudo_event *sigint_ev;
+ struct sudo_event *sigquit_ev;
+ struct sudo_event *sigterm_ev;
+ struct sudo_event *sigtstp_ev;
+ struct timing_closure timing;
+ bool interactive;
+ bool suspend_wait;
+ struct io_buffer {
+ unsigned int len; /* buffer length (how much produced) */
+ unsigned int off; /* write position (how much already consumed) */
+ unsigned int toread; /* how much remains to be read */
+ int lastc; /* last char written */
+ char buf[64 * 1024];
+ } iobuf;
+};
+
+/*
+ * Handle expressions like:
+ * ( user millert or user root ) and tty console and command /bin/sh
+ */
+STAILQ_HEAD(search_node_list, search_node);
+struct search_node {
+ STAILQ_ENTRY(search_node) entries;
+#define ST_EXPR 1
+#define ST_TTY 2
+#define ST_USER 3
+#define ST_PATTERN 4
+#define ST_RUNASUSER 5
+#define ST_RUNASGROUP 6
+#define ST_FROMDATE 7
+#define ST_TODATE 8
+#define ST_CWD 9
+ char type;
+ bool negated;
+ bool or;
+ union {
+ regex_t cmdre;
+ time_t tstamp;
+ char *cwd;
+ char *tty;
+ char *user;
+ char *runas_group;
+ char *runas_user;
+ struct search_node_list expr;
+ void *ptr;
+ } u;
+};
+
+static struct search_node_list search_expr = STAILQ_HEAD_INITIALIZER(search_expr);
+
+static double speed_factor = 1.0;
+
+static const char *session_dir = _PATH_SUDO_IO_LOGDIR;
+
+static bool terminal_can_resize, terminal_was_resized;
+
+static int terminal_rows, terminal_cols;
+
+static int ttyfd = -1;
+
+static const char short_opts[] = "d:f:hlm:nRSs:V";
+static struct option long_opts[] = {
+ { "directory", required_argument, NULL, 'd' },
+ { "filter", required_argument, NULL, 'f' },
+ { "help", no_argument, NULL, 'h' },
+ { "list", no_argument, NULL, 'l' },
+ { "max-wait", required_argument, NULL, 'm' },
+ { "non-interactive", no_argument, NULL, 'n' },
+ { "no-resize", no_argument, NULL, 'R' },
+ { "suspend-wait", no_argument, NULL, 'S' },
+ { "speed", required_argument, NULL, 's' },
+ { "version", no_argument, NULL, 'V' },
+ { NULL, no_argument, NULL, '\0' },
+};
+
+/* XXX move to separate header? (currently in sudoers.h) */
+extern char *get_timestr(time_t, int);
+extern time_t get_date(char *);
+
+static int list_sessions(int, char **, const char *, const char *, const char *);
+static int open_io_fd(char *path, int len, struct io_log_file *iol);
+static int parse_expr(struct search_node_list *, char **, bool);
+static void read_keyboard(int fd, int what, void *v);
+static void help(void) __attribute__((__noreturn__));
+static int replay_session(struct timespec *max_wait, const char *decimal, bool interactive, bool suspend_wait);
+static void sudoreplay_cleanup(void);
+static void usage(int);
+static void write_output(int fd, int what, void *v);
+static void restore_terminal_size(void);
+static void setup_terminal(struct log_info *li, bool interactive, bool resize);
+
+#define VALID_ID(s) (isalnum((unsigned char)(s)[0]) && \
+ isalnum((unsigned char)(s)[1]) && isalnum((unsigned char)(s)[2]) && \
+ isalnum((unsigned char)(s)[3]) && isalnum((unsigned char)(s)[4]) && \
+ isalnum((unsigned char)(s)[5]) && (s)[6] == '\0')
+
+#define IS_IDLOG(s) ( \
+ isalnum((unsigned char)(s)[0]) && isalnum((unsigned char)(s)[1]) && \
+ (s)[2] == '/' && \
+ isalnum((unsigned char)(s)[3]) && isalnum((unsigned char)(s)[4]) && \
+ (s)[5] == '/' && \
+ isalnum((unsigned char)(s)[6]) && isalnum((unsigned char)(s)[7]) && \
+ (s)[8] == '/' && (s)[9] == 'l' && (s)[10] == 'o' && (s)[11] == 'g' && \
+ (s)[12] == '\0')
+
+__dso_public int main(int argc, char *argv[]);
+
+int
+main(int argc, char *argv[])
+{
+ int ch, i, plen, exitcode = 0;
+ bool def_filter = true, listonly = false;
+ bool interactive = true, suspend_wait = false, resize = true;
+ const char *decimal, *id, *user = NULL, *pattern = NULL, *tty = NULL;
+ char *cp, *ep, path[PATH_MAX];
+ struct log_info *li;
+ struct timespec max_delay_storage, *max_delay = NULL;
+ double dval;
+ debug_decl(main, SUDO_DEBUG_MAIN)
+
+#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
+ {
+ extern char *malloc_options;
+ malloc_options = "S";
+ }
+#endif
+
+ initprogname(argc > 0 ? argv[0] : "sudoreplay");
+ setlocale(LC_ALL, "");
+ decimal = localeconv()->decimal_point;
+ bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have sudoreplay domain */
+ textdomain("sudoers");
+
+ /* Register fatal/fatalx callback. */
+ sudo_fatal_callback_register(sudoreplay_cleanup);
+
+ /* Read sudo.conf and initialize the debug subsystem. */
+ if (sudo_conf_read(NULL, SUDO_CONF_DEBUG) == -1)
+ exit(EXIT_FAILURE);
+ sudo_debug_register(getprogname(), NULL, NULL,
+ sudo_conf_debug_files(getprogname()));
+
+ while ((ch = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
+ switch (ch) {
+ case 'd':
+ session_dir = optarg;
+ break;
+ case 'f':
+ /* Set the replay filter. */
+ def_filter = false;
+ for (cp = strtok_r(optarg, ",", &ep); cp; cp = strtok_r(NULL, ",", &ep)) {
+ if (strcmp(cp, "stdin") == 0)
+ io_log_files[IOFD_STDIN].enabled = true;
+ else if (strcmp(cp, "stdout") == 0)
+ io_log_files[IOFD_STDOUT].enabled = true;
+ else if (strcmp(cp, "stderr") == 0)
+ io_log_files[IOFD_STDERR].enabled = true;
+ else if (strcmp(cp, "ttyin") == 0)
+ io_log_files[IOFD_TTYIN].enabled = true;
+ else if (strcmp(cp, "ttyout") == 0)
+ io_log_files[IOFD_TTYOUT].enabled = true;
+ else
+ sudo_fatalx(U_("invalid filter option: %s"), optarg);
+ }
+ break;
+ case 'h':
+ help();
+ /* NOTREACHED */
+ case 'l':
+ listonly = true;
+ break;
+ case 'm':
+ errno = 0;
+ dval = strtod(optarg, &ep);
+ if (*ep != '\0' || errno != 0)
+ sudo_fatalx(U_("invalid max wait: %s"), optarg);
+ if (dval <= 0.0) {
+ sudo_timespecclear(&max_delay_storage);
+ } else {
+ max_delay_storage.tv_sec = dval;
+ max_delay_storage.tv_nsec =
+ (dval - max_delay_storage.tv_sec) * 1000000000.0;
+ }
+ max_delay = &max_delay_storage;
+ break;
+ case 'n':
+ interactive = false;
+ break;
+ case 'R':
+ resize = false;
+ break;
+ case 'S':
+ suspend_wait = true;
+ break;
+ case 's':
+ errno = 0;
+ speed_factor = strtod(optarg, &ep);
+ if (*ep != '\0' || errno != 0)
+ sudo_fatalx(U_("invalid speed factor: %s"), optarg);
+ break;
+ case 'V':
+ (void) printf(_("%s version %s\n"), getprogname(), PACKAGE_VERSION);
+ goto done;
+ default:
+ usage(1);
+ /* NOTREACHED */
+ }
+
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (listonly) {
+ exitcode = list_sessions(argc, argv, pattern, user, tty);
+ goto done;
+ }
+
+ if (argc != 1)
+ usage(1);
+
+ /* By default we replay stdout, stderr and ttyout. */
+ if (def_filter) {
+ io_log_files[IOFD_STDOUT].enabled = true;
+ io_log_files[IOFD_STDERR].enabled = true;
+ io_log_files[IOFD_TTYOUT].enabled = true;
+ }
+
+ /* 6 digit ID in base 36, e.g. 01G712AB or free-form name */
+ id = argv[0];
+ if (VALID_ID(id)) {
+ plen = snprintf(path, sizeof(path), "%s/%.2s/%.2s/%.2s/timing",
+ session_dir, id, &id[2], &id[4]);
+ if (plen <= 0 || (size_t)plen >= sizeof(path))
+ sudo_fatalx(U_("%s/%.2s/%.2s/%.2s/timing: %s"), session_dir,
+ id, &id[2], &id[4], strerror(ENAMETOOLONG));
+ } else {
+ plen = snprintf(path, sizeof(path), "%s/%s/timing",
+ session_dir, id);
+ if (plen <= 0 || (size_t)plen >= sizeof(path))
+ sudo_fatalx(U_("%s/%s/timing: %s"), session_dir,
+ id, strerror(ENAMETOOLONG));
+ }
+ plen -= 7;
+
+ /* Open files for replay, applying replay filter for the -f flag. */
+ for (i = 0; i < IOFD_MAX; i++) {
+ if (open_io_fd(path, plen, &io_log_files[i]) == -1)
+ sudo_fatal(U_("unable to open %s"), path);
+ }
+
+ /* Parse log file. */
+ path[plen] = '\0';
+ strlcat(path, "/log", sizeof(path));
+ if ((li = parse_logfile(path)) == NULL)
+ exit(1);
+ printf(_("Replaying sudo session: %s"), li->cmd);
+
+ /* Setup terminal if appropriate. */
+ if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO))
+ interactive = false;
+ setup_terminal(li, interactive, resize);
+ putchar('\r');
+ putchar('\n');
+
+ /* Done with parsed log file. */
+ free_log_info(li);
+ li = NULL;
+
+ /* Replay session corresponding to io_log_files[]. */
+ exitcode = replay_session(max_delay, decimal, interactive, suspend_wait);
+
+ restore_terminal_size();
+ sudo_term_restore(ttyfd, true);
+done:
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);
+ exit(exitcode);
+}
+
+/*
+ * Call gzread() or fread() for the I/O log file in question.
+ * Return 0 for EOF or -1 on error.
+ */
+static ssize_t
+io_log_read(union io_fd ifd, char *buf, size_t nbytes)
+{
+ ssize_t nread;
+ debug_decl(io_log_read, SUDO_DEBUG_UTIL)
+
+ if (nbytes > INT_MAX) {
+ errno = EINVAL;
+ debug_return_ssize_t(-1);
+ }
+#ifdef HAVE_ZLIB_H
+ nread = gzread(ifd.g, buf, nbytes);
+#else
+ nread = (ssize_t)fread(buf, 1, nbytes, ifd.f);
+ if (nread == 0 && ferror(ifd.f))
+ nread = -1;
+#endif
+ debug_return_ssize_t(nread);
+}
+
+static int
+io_log_eof(union io_fd ifd)
+{
+ int ret;
+ debug_decl(io_log_eof, SUDO_DEBUG_UTIL)
+
+#ifdef HAVE_ZLIB_H
+ ret = gzeof(ifd.g);
+#else
+ ret = feof(ifd.f);
+#endif
+ debug_return_int(ret);
+}
+
+static char *
+io_log_gets(union io_fd ifd, char *buf, size_t nbytes)
+{
+ char *str;
+ debug_decl(io_log_gets, SUDO_DEBUG_UTIL)
+
+#ifdef HAVE_ZLIB_H
+ str = gzgets(ifd.g, buf, nbytes);
+#else
+ str = fgets(buf, nbytes, ifd.f);
+#endif
+ debug_return_str(str);
+}
+
+/*
+ * List of terminals that support xterm-like resizing.
+ * This is not an exhaustive list.
+ * For a list of VT100 style escape codes, see:
+ * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#VT100%20Mode
+ */
+struct term_names {
+ const char *name;
+ unsigned int len;
+} compatible_terms[] = {
+ { "Eterm", 5 },
+ { "aterm", 5 },
+ { "dtterm", 6 },
+ { "gnome", 5 },
+ { "konsole", 7 },
+ { "kvt\0", 4 },
+ { "mlterm", 6 },
+ { "rxvt", 4 },
+ { "xterm", 5 },
+ { NULL, 0 }
+};
+
+struct getsize_closure {
+ int nums[2];
+ int nums_depth;
+ int nums_maxdepth;
+ int state;
+ const char *cp;
+ struct sudo_event *ev;
+ struct timespec timeout;
+};
+
+/* getsize states */
+#define INITIAL 0x00
+#define NEW_NUMBER 0x01
+#define NUMBER 0x02
+#define GOTSIZE 0x04
+#define READCHAR 0x10
+
+/*
+ * Callback for reading the terminal size response.
+ * We use an event for this to support timeouts.
+ */
+static void
+getsize_cb(int fd, int what, void *v)
+{
+ struct getsize_closure *gc = v;
+ unsigned char ch = '\0';
+ debug_decl(getsize_cb, SUDO_DEBUG_UTIL)
+
+ for (;;) {
+ if (gc->cp[0] == '\0') {
+ gc->state = GOTSIZE;
+ goto done;
+ }
+ if (ISSET(gc->state, READCHAR)) {
+ ssize_t nread = read(ttyfd, &ch, 1);
+ switch (nread) {
+ case -1:
+ if (errno == EAGAIN)
+ goto another;
+ /* FALLTHROUGH */
+ case 0:
+ goto done;
+ default:
+ CLR(gc->state, READCHAR);
+ break;
+ }
+ }
+ switch (gc->state) {
+ case INITIAL:
+ if (ch == 0233 && gc->cp[0] == '\033') {
+ /* meta escape, equivalent to ESC[ */
+ ch = '[';
+ gc->cp++;
+ }
+ if (gc->cp[0] == '%' && gc->cp[1] == 'd') {
+ gc->state = NEW_NUMBER;
+ continue;
+ }
+ if (gc->cp[0] != ch) {
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
+ "got %d, expected %d", ch, gc->cp[0]);
+ goto done;
+ }
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "got %d", ch);
+ SET(gc->state, READCHAR);
+ gc->cp++;
+ break;
+ case NEW_NUMBER:
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "parsing number");
+ if (!isdigit(ch))
+ goto done;
+ gc->cp += 2;
+ if (gc->nums_depth > gc->nums_maxdepth)
+ goto done;
+ gc->nums[gc->nums_depth] = 0;
+ gc->state = NUMBER;
+ /* FALLTHROUGH */
+ case NUMBER:
+ if (!isdigit(ch)) {
+ /* done with number, reparse ch */
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "number %d (ch %d)", gc->nums[gc->nums_depth], ch);
+ gc->nums_depth++;
+ gc->state = INITIAL;
+ continue;
+ }
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "got %d", ch);
+ if (gc->nums[gc->nums_depth] > INT_MAX / 10)
+ goto done;
+ gc->nums[gc->nums_depth] *= 10;
+ gc->nums[gc->nums_depth] += (ch - '0');
+ SET(gc->state, READCHAR);
+ break;
+ }
+ }
+
+another:
+ if (sudo_ev_add(NULL, gc->ev, &gc->timeout, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+done:
+ debug_return;
+}
+
+
+/*
+ * Get the terminal size using vt100 terminal escapes.
+ */
+static bool
+xterm_get_size(int *new_rows, int *new_cols)
+{
+ struct sudo_event_base *evbase;
+ struct getsize_closure gc;
+ const char getsize_request[] = "\0337\033[r\033[999;999H\033[6n";
+ const char getsize_response[] = "\033[%d;%dR";
+ bool ret = false;
+ debug_decl(xterm_get_size, SUDO_DEBUG_UTIL)
+
+ /* request the terminal's size */
+ if (write(ttyfd, getsize_request, strlen(getsize_request)) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "%s: error writing xterm size request", __func__);
+ goto done;
+ }
+
+ /*
+ * Callback info for reading back the size with a 10 second timeout.
+ * We expect two numbers (rows and cols).
+ */
+ gc.state = INITIAL|READCHAR;
+ gc.nums_depth = 0;
+ gc.nums_maxdepth = 1;
+ gc.cp = getsize_response;
+ gc.timeout.tv_sec = 10;
+ gc.timeout.tv_nsec = 0;
+
+ /* Setup an event for reading the terminal size */
+ evbase = sudo_ev_base_alloc();
+ if (evbase == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ gc.ev = sudo_ev_alloc(ttyfd, SUDO_EV_READ, getsize_cb, &gc);
+ if (gc.ev == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+ /* Read back terminal size response */
+ if (sudo_ev_add(evbase, gc.ev, &gc.timeout, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ sudo_ev_dispatch(evbase);
+
+ if (gc.state == GOTSIZE) {
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "terminal size %d x %x", gc.nums[0], gc.nums[1]);
+ *new_rows = gc.nums[0];
+ *new_cols = gc.nums[1];
+ ret = true;
+ }
+
+ sudo_ev_base_free(evbase);
+ sudo_ev_free(gc.ev);
+
+done:
+ debug_return_bool(ret);
+}
+
+/*
+ * Set the size of the text area to rows and cols.
+ * Depending on the terminal implementation, the window itself may
+ * or may not shrink to a smaller size.
+ */
+static bool
+xterm_set_size(int rows, int cols)
+{
+ const char setsize_fmt[] = "\033[8;%d;%dt";
+ int len, new_rows, new_cols;
+ bool ret = false;
+ char buf[1024];
+ debug_decl(xterm_set_size, SUDO_DEBUG_UTIL)
+
+ /* XXX - save cursor and position restore after resizing */
+ len = snprintf(buf, sizeof(buf), setsize_fmt, rows, cols);
+ if (len < 0 || len >= (int)sizeof(buf)) {
+ /* not possible due to size of buf */
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: internal error, buffer too small?", __func__);
+ goto done;
+ }
+ if (write(ttyfd, buf, strlen(buf)) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "%s: error writing xterm resize request", __func__);
+ goto done;
+ }
+ /* XXX - keyboard input will interfere with this */
+ if (!xterm_get_size(&new_rows, &new_cols))
+ goto done;
+ if (rows == new_rows && cols == new_cols)
+ ret = true;
+
+done:
+ debug_return_bool(ret);
+}
+
+static void
+setup_terminal(struct log_info *li, bool interactive, bool resize)
+{
+ const char *term;
+ debug_decl(check_terminal, SUDO_DEBUG_UTIL)
+
+ fflush(stdout);
+
+ /* Open fd for /dev/tty and set to raw mode. */
+ if (interactive) {
+ ttyfd = open(_PATH_TTY, O_RDWR);
+ while (!sudo_term_raw(ttyfd, 1)) {
+ if (errno != EINTR)
+ sudo_fatal(U_("unable to set tty to raw mode"));
+ kill(getpid(), SIGTTOU);
+ }
+ }
+
+ /* Find terminal size if the session has size info. */
+ if (li->rows == 0 && li->cols == 0) {
+ /* no tty size info, hope for the best... */
+ debug_return;
+ }
+
+ if (resize && ttyfd != -1) {
+ term = getenv("TERM");
+ if (term != NULL && *term != '\0') {
+ struct term_names *tn;
+
+ for (tn = compatible_terms; tn->name != NULL; tn++) {
+ if (strncmp(term, tn->name, tn->len) == 0) {
+ /* xterm-like terminals can resize themselves. */
+ if (xterm_get_size(&terminal_rows, &terminal_cols))
+ terminal_can_resize = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!terminal_can_resize) {
+ /* either not xterm or not interactive */
+ sudo_get_ttysize(&terminal_rows, &terminal_cols);
+ }
+
+ if (li->rows == terminal_rows && li->cols == terminal_cols) {
+ /* nothing to change */
+ debug_return;
+ }
+
+ if (terminal_can_resize) {
+ /* session terminal size is different, try to resize ours */
+ if (xterm_set_size(li->rows, li->cols)) {
+ /* success */
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "resized terminal to %d x %x", li->rows, li->cols);
+ terminal_was_resized = true;
+ debug_return;
+ }
+ /* resize failed, don't try again */
+ terminal_can_resize = false;
+ }
+
+ if (li->rows > terminal_rows || li->cols > terminal_cols) {
+ printf(_("Warning: your terminal is too small to properly replay the log.\n"));
+ printf(_("Log geometry is %d x %d, your terminal's geometry is %d x %d."), li->rows, li->cols, terminal_rows, terminal_cols);
+ }
+ debug_return;
+}
+
+static void
+resize_terminal(int rows, int cols)
+{
+ debug_decl(resize_terminal, SUDO_DEBUG_UTIL)
+
+ if (terminal_can_resize) {
+ if (xterm_set_size(rows, cols))
+ terminal_was_resized = true;
+ else
+ terminal_can_resize = false;
+ }
+
+ debug_return;
+}
+
+static void
+restore_terminal_size(void)
+{
+ debug_decl(restore_terminal, SUDO_DEBUG_UTIL)
+
+ if (terminal_was_resized) {
+ /* We are still in raw mode, hence the carriage return. */
+ putchar('\r');
+ printf(U_("Replay finished, press any key to restore the terminal."));
+ fflush(stdout);
+ (void)getchar();
+ xterm_set_size(terminal_rows, terminal_cols);
+ putchar('\r');
+ putchar('\n');
+ }
+
+ debug_return;
+}
+
+/*
+ * Read the next record from the timing file and schedule a delay
+ * event with the specified timeout.
+ * Return 0 on success, 1 on EOF and -1 on error.
+ */
+static int
+read_timing_record(struct replay_closure *closure)
+{
+ struct timespec timeout;
+ char buf[LINE_MAX];
+ debug_decl(read_timing_record, SUDO_DEBUG_UTIL)
+
+ /* Read next record from timing file. */
+ if (io_log_gets(io_log_files[IOFD_TIMING].fd, buf, sizeof(buf)) == NULL) {
+ /* EOF or error reading timing file, we are done. */
+ debug_return_int(io_log_eof(io_log_files[IOFD_TIMING].fd) ? 1 : -1);
+ }
+
+ /* Parse timing file record. */
+ buf[strcspn(buf, "\n")] = '\0';
+ if (!parse_timing(buf, &timeout, &closure->timing))
+ sudo_fatalx(U_("invalid timing file line: %s"), buf);
+
+ /* Record number bytes to read. */
+ /* XXX - remove timing->nbytes? */
+ if (closure->timing.event != IO_EVENT_WINSIZE &&
+ closure->timing.event != IO_EVENT_SUSPEND) {
+ closure->iobuf.len = 0;
+ closure->iobuf.off = 0;
+ closure->iobuf.lastc = '\0';
+ closure->iobuf.toread = closure->timing.u.nbytes;
+ }
+
+ /* Adjust delay using speed factor and max_delay. */
+ adjust_delay(&timeout, closure->timing.max_delay, speed_factor);
+
+ /* Schedule the delay event. */
+ if (sudo_ev_add(closure->evbase, closure->delay_ev, &timeout, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ debug_return_int(0);
+}
+
+/*
+ * Read next timing record.
+ * Exits the event loop on EOF, breaks out on error.
+ */
+static void
+next_timing_record(struct replay_closure *closure)
+{
+ debug_decl(next_timing_record, SUDO_DEBUG_UTIL)
+
+again:
+ switch (read_timing_record(closure)) {
+ case 0:
+ /* success */
+ if (closure->timing.event == IO_EVENT_SUSPEND &&
+ closure->timing.u.signo == SIGCONT && !closure->suspend_wait) {
+ /* Ignore time spent suspended. */
+ goto again;
+ }
+ break;
+ case 1:
+ /* EOF */
+ sudo_ev_loopexit(closure->evbase);
+ break;
+ default:
+ /* error */
+ sudo_ev_loopbreak(closure->evbase);
+ break;
+ }
+ debug_return;
+}
+
+static bool
+fill_iobuf(struct replay_closure *closure)
+{
+ const size_t space = sizeof(closure->iobuf.buf) - closure->iobuf.len;
+ const struct timing_closure *timing = &closure->timing;
+ debug_decl(fill_iobuf, SUDO_DEBUG_UTIL)
+
+ if (closure->iobuf.toread != 0 && space != 0) {
+ const size_t len =
+ closure->iobuf.toread < space ? closure->iobuf.toread : space;
+ ssize_t nread = io_log_read(timing->fd,
+ closure->iobuf.buf + closure->iobuf.off, len);
+ if (nread <= 0) {
+ if (nread == 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: premature EOF, expected %u bytes",
+ io_log_files[timing->event].suffix, closure->iobuf.toread);
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "%s: read error", io_log_files[timing->event].suffix);
+ }
+ sudo_warnx(U_("unable to read %s"),
+ io_log_files[timing->event].suffix);
+ debug_return_bool(false);
+ }
+ closure->iobuf.toread -= nread;
+ closure->iobuf.len += nread;
+ }
+
+ debug_return_bool(true);
+}
+
+/*
+ * Called when the inter-record delay has expired.
+ * Depending on the record type, either reads the next
+ * record or changes window size.
+ */
+static void
+delay_cb(int fd, int what, void *v)
+{
+ struct replay_closure *closure = v;
+ struct timing_closure *timing = &closure->timing;
+ debug_decl(delay_cb, SUDO_DEBUG_UTIL)
+
+ switch (timing->event) {
+ case IO_EVENT_WINSIZE:
+ resize_terminal(timing->u.winsize.rows, timing->u.winsize.cols);
+ break;
+ case IO_EVENT_STDIN:
+ if (io_log_files[IOFD_STDIN].enabled)
+ timing->fd = io_log_files[IOFD_STDIN].fd;
+ break;
+ case IO_EVENT_STDOUT:
+ if (io_log_files[IOFD_STDOUT].enabled)
+ timing->fd = io_log_files[IOFD_STDOUT].fd;
+ break;
+ case IO_EVENT_STDERR:
+ if (io_log_files[IOFD_STDERR].enabled)
+ timing->fd = io_log_files[IOFD_STDERR].fd;
+ break;
+ case IO_EVENT_TTYIN:
+ if (io_log_files[IOFD_TTYIN].enabled)
+ timing->fd = io_log_files[IOFD_TTYIN].fd;
+ break;
+ case IO_EVENT_TTYOUT:
+ if (io_log_files[IOFD_TTYOUT].enabled)
+ timing->fd = io_log_files[IOFD_TTYOUT].fd;
+ break;
+ }
+
+ if (timing->fd.v != NULL) {
+ /* If the stream is open, enable the write event. */
+ if (sudo_ev_add(closure->evbase, closure->output_ev, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ } else {
+ /* Not replaying, get the next timing record and continue. */
+ next_timing_record(closure);
+ }
+
+ debug_return;
+}
+
+static void
+replay_closure_free(struct replay_closure *closure)
+{
+ /*
+ * Free events and event base, then the closure itself.
+ */
+ sudo_ev_free(closure->delay_ev);
+ sudo_ev_free(closure->keyboard_ev);
+ sudo_ev_free(closure->output_ev);
+ sudo_ev_free(closure->sighup_ev);
+ sudo_ev_free(closure->sigint_ev);
+ sudo_ev_free(closure->sigquit_ev);
+ sudo_ev_free(closure->sigterm_ev);
+ sudo_ev_free(closure->sigtstp_ev);
+ sudo_ev_base_free(closure->evbase);
+ free(closure);
+}
+
+static void
+signal_cb(int signo, int what, void *v)
+{
+ struct replay_closure *closure = v;
+ debug_decl(signal_cb, SUDO_DEBUG_UTIL)
+
+ switch (signo) {
+ case SIGHUP:
+ case SIGINT:
+ case SIGQUIT:
+ case SIGTERM:
+ /* Free the event base and restore signal handlers. */
+ replay_closure_free(closure);
+
+ /* Restore the terminal and die. */
+ sudoreplay_cleanup();
+ kill(getpid(), signo);
+ break;
+ case SIGTSTP:
+ /* Ignore ^Z since we have no way to restore the screen. */
+ break;
+ }
+
+ debug_return;
+}
+
+static struct replay_closure *
+replay_closure_alloc(struct timespec *max_delay, const char *decimal,
+ bool interactive, bool suspend_wait)
+{
+ struct replay_closure *closure;
+ debug_decl(replay_closure_alloc, SUDO_DEBUG_UTIL)
+
+ if ((closure = calloc(1, sizeof(*closure))) == NULL)
+ debug_return_ptr(NULL);
+
+ closure->interactive = interactive;
+ closure->suspend_wait = suspend_wait;
+ closure->timing.max_delay = max_delay;
+ closure->timing.decimal = decimal;
+
+ /*
+ * Setup event base and delay, input and output events.
+ * If interactive, take input from and write to /dev/tty.
+ * If not interactive there is no input event.
+ */
+ closure->evbase = sudo_ev_base_alloc();
+ if (closure->evbase == NULL)
+ goto bad;
+ closure->delay_ev = sudo_ev_alloc(-1, SUDO_EV_TIMEOUT, delay_cb, closure);
+ if (closure->delay_ev == NULL)
+ goto bad;
+ if (interactive) {
+ closure->keyboard_ev = sudo_ev_alloc(ttyfd, SUDO_EV_READ|SUDO_EV_PERSIST,
+ read_keyboard, closure);
+ if (closure->keyboard_ev == NULL)
+ goto bad;
+ if (sudo_ev_add(closure->evbase, closure->keyboard_ev, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ }
+ closure->output_ev = sudo_ev_alloc(interactive ? ttyfd : STDOUT_FILENO,
+ SUDO_EV_WRITE, write_output, closure);
+ if (closure->output_ev == NULL)
+ goto bad;
+
+ /*
+ * Setup signal events, we need to restore the terminal if killed.
+ */
+ closure->sighup_ev = sudo_ev_alloc(SIGHUP, SUDO_EV_SIGNAL, signal_cb,
+ closure);
+ if (closure->sighup_ev == NULL)
+ goto bad;
+ if (sudo_ev_add(closure->evbase, closure->sighup_ev, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ closure->sigint_ev = sudo_ev_alloc(SIGINT, SUDO_EV_SIGNAL, signal_cb,
+ closure);
+ if (closure->sigint_ev == NULL)
+ goto bad;
+ if (sudo_ev_add(closure->evbase, closure->sigint_ev, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ closure->sigquit_ev = sudo_ev_alloc(SIGQUIT, SUDO_EV_SIGNAL, signal_cb,
+ closure);
+ if (closure->sigquit_ev == NULL)
+ goto bad;
+ if (sudo_ev_add(closure->evbase, closure->sigquit_ev, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ closure->sigterm_ev = sudo_ev_alloc(SIGTERM, SUDO_EV_SIGNAL, signal_cb,
+ closure);
+ if (closure->sigterm_ev == NULL)
+ goto bad;
+ if (sudo_ev_add(closure->evbase, closure->sigterm_ev, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ closure->sigtstp_ev = sudo_ev_alloc(SIGTSTP, SUDO_EV_SIGNAL, signal_cb,
+ closure);
+ if (closure->sigtstp_ev == NULL)
+ goto bad;
+ if (sudo_ev_add(closure->evbase, closure->sigtstp_ev, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ debug_return_ptr(closure);
+bad:
+ replay_closure_free(closure);
+ debug_return_ptr(NULL);
+}
+
+static int
+replay_session(struct timespec *max_delay, const char *decimal,
+ bool interactive, bool suspend_wait)
+{
+ struct replay_closure *closure;
+ int ret = 0;
+ debug_decl(replay_session, SUDO_DEBUG_UTIL)
+
+ /* Allocate the delay closure and read the first timing record. */
+ closure = replay_closure_alloc(max_delay, decimal, interactive,
+ suspend_wait);
+ if (read_timing_record(closure) != 0) {
+ ret = 1;
+ goto done;
+ }
+
+ /* Run event loop. */
+ sudo_ev_dispatch(closure->evbase);
+ if (sudo_ev_got_break(closure->evbase))
+ ret = 1;
+
+done:
+ /* Clean up and return. */
+ replay_closure_free(closure);
+ debug_return_int(ret);
+}
+
+static int
+open_io_fd(char *path, int len, struct io_log_file *iol)
+{
+ debug_decl(open_io_fd, SUDO_DEBUG_UTIL)
+
+ if (!iol->enabled)
+ debug_return_int(0);
+
+ path[len] = '\0';
+ strlcat(path, iol->suffix, PATH_MAX);
+#ifdef HAVE_ZLIB_H
+ iol->fd.g = gzopen(path, "r");
+#else
+ iol->fd.f = fopen(path, "r");
+#endif
+ if (iol->fd.v == NULL) {
+ iol->enabled = false;
+ debug_return_int(-1);
+ }
+ debug_return_int(0);
+}
+
+/*
+ * Write the I/O buffer.
+ */
+static void
+write_output(int fd, int what, void *v)
+{
+ struct replay_closure *closure = v;
+ const struct timing_closure *timing = &closure->timing;
+ struct io_buffer *iobuf = &closure->iobuf;
+ unsigned iovcnt = 1;
+ struct iovec iov[2];
+ bool added_cr = false;
+ size_t nbytes, nwritten;
+ debug_decl(write_output, SUDO_DEBUG_UTIL)
+
+ /* Refill iobuf if there is more to read and buf is empty. */
+ if (!fill_iobuf(closure)) {
+ sudo_ev_loopbreak(closure->evbase);
+ debug_return;
+ }
+
+ nbytes = iobuf->len - iobuf->off;
+ iov[0].iov_base = iobuf->buf + iobuf->off;
+ iov[0].iov_len = nbytes;
+
+ if (closure->interactive &&
+ (timing->event == IO_EVENT_STDOUT || timing->event == IO_EVENT_STDERR)) {
+ char *nl;
+
+ /*
+ * We may need to insert a carriage return before the newline.
+ * Note that the carriage return may have already been written.
+ */
+ nl = memchr(iov[0].iov_base, '\n', iov[0].iov_len);
+ if (nl != NULL) {
+ size_t len = (size_t)(nl - (char *)iov[0].iov_base);
+ if ((nl == iov[0].iov_base && iobuf->lastc != '\r') ||
+ (nl != iov[0].iov_base && nl[-1] != '\r')) {
+ iov[0].iov_len = len;
+ iov[1].iov_base = "\r\n";
+ iov[1].iov_len = 2;
+ iovcnt = 2;
+ nbytes = iov[0].iov_len + iov[1].iov_len;
+ added_cr = true;
+ }
+ }
+ }
+
+ nwritten = writev(fd, iov, iovcnt);
+ switch ((ssize_t)nwritten) {
+ case -1:
+ if (errno != EINTR && errno != EAGAIN)
+ sudo_fatal(U_("unable to write to %s"), "stdout");
+ break;
+ case 0:
+ /* Should not happen. */
+ break;
+ default:
+ if (added_cr && nwritten >= nbytes - 1) {
+ /* The last char written was either '\r' or '\n'. */
+ iobuf->lastc = nwritten == nbytes ? '\n' : '\r';
+ } else {
+ /* Stash the last char written. */
+ iobuf->lastc = *((char *)iov[0].iov_base + nwritten);
+ }
+ if (added_cr) {
+ /* Subtract one for the carriage return we added above. */
+ nwritten--;
+ }
+ iobuf->off += nwritten;
+ break;
+ }
+
+ if (iobuf->off == iobuf->len) {
+ /* Write complete, go to next timing entry if possible. */
+ switch (read_timing_record(closure)) {
+ case 0:
+ /* success */
+ break;
+ case 1:
+ /* EOF */
+ sudo_ev_loopexit(closure->evbase);
+ break;
+ default:
+ /* error */
+ sudo_ev_loopbreak(closure->evbase);
+ break;
+ }
+ } else {
+ /* Reschedule event to write remainder. */
+ if (sudo_ev_add(NULL, closure->output_ev, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ }
+ debug_return;
+}
+
+/*
+ * Build expression list from search args
+ */
+static int
+parse_expr(struct search_node_list *head, char *argv[], bool sub_expr)
+{
+ bool or = false, not = false;
+ struct search_node *sn;
+ char type, **av;
+ debug_decl(parse_expr, SUDO_DEBUG_UTIL)
+
+ for (av = argv; *av != NULL; av++) {
+ switch (av[0][0]) {
+ case 'a': /* and (ignore) */
+ if (strncmp(*av, "and", strlen(*av)) != 0)
+ goto bad;
+ continue;
+ case 'o': /* or */
+ if (strncmp(*av, "or", strlen(*av)) != 0)
+ goto bad;
+ or = true;
+ continue;
+ case '!': /* negate */
+ if (av[0][1] != '\0')
+ goto bad;
+ not = true;
+ continue;
+ case 'c': /* cwd or command */
+ if (av[0][1] == '\0')
+ sudo_fatalx(U_("ambiguous expression \"%s\""), *av);
+ if (strncmp(*av, "cwd", strlen(*av)) == 0)
+ type = ST_CWD;
+ else if (strncmp(*av, "command", strlen(*av)) == 0)
+ type = ST_PATTERN;
+ else
+ goto bad;
+ break;
+ case 'f': /* from date */
+ if (strncmp(*av, "fromdate", strlen(*av)) != 0)
+ goto bad;
+ type = ST_FROMDATE;
+ break;
+ case 'g': /* runas group */
+ if (strncmp(*av, "group", strlen(*av)) != 0)
+ goto bad;
+ type = ST_RUNASGROUP;
+ break;
+ case 'r': /* runas user */
+ if (strncmp(*av, "runas", strlen(*av)) != 0)
+ goto bad;
+ type = ST_RUNASUSER;
+ break;
+ case 't': /* tty or to date */
+ if (av[0][1] == '\0')
+ sudo_fatalx(U_("ambiguous expression \"%s\""), *av);
+ if (strncmp(*av, "todate", strlen(*av)) == 0)
+ type = ST_TODATE;
+ else if (strncmp(*av, "tty", strlen(*av)) == 0)
+ type = ST_TTY;
+ else
+ goto bad;
+ break;
+ case 'u': /* user */
+ if (strncmp(*av, "user", strlen(*av)) != 0)
+ goto bad;
+ type = ST_USER;
+ break;
+ case '(': /* start sub-expression */
+ if (av[0][1] != '\0')
+ goto bad;
+ type = ST_EXPR;
+ break;
+ case ')': /* end sub-expression */
+ if (av[0][1] != '\0')
+ goto bad;
+ if (!sub_expr)
+ sudo_fatalx(U_("unmatched ')' in expression"));
+ debug_return_int(av - argv + 1);
+ default:
+ bad:
+ sudo_fatalx(U_("unknown search term \"%s\""), *av);
+ /* NOTREACHED */
+ }
+
+ /* Allocate new search node */
+ if ((sn = calloc(1, sizeof(*sn))) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sn->type = type;
+ sn->or = or;
+ sn->negated = not;
+ if (type == ST_EXPR) {
+ STAILQ_INIT(&sn->u.expr);
+ av += parse_expr(&sn->u.expr, av + 1, true);
+ } else {
+ if (*(++av) == NULL)
+ sudo_fatalx(U_("%s requires an argument"), av[-1]);
+ if (type == ST_PATTERN) {
+ if (regcomp(&sn->u.cmdre, *av, REG_EXTENDED|REG_NOSUB) != 0)
+ sudo_fatalx(U_("invalid regular expression: %s"), *av);
+ } else if (type == ST_TODATE || type == ST_FROMDATE) {
+ sn->u.tstamp = get_date(*av);
+ if (sn->u.tstamp == -1)
+ sudo_fatalx(U_("could not parse date \"%s\""), *av);
+ } else {
+ sn->u.ptr = *av;
+ }
+ }
+ not = or = false; /* reset state */
+ STAILQ_INSERT_TAIL(head, sn, entries);
+ }
+ if (sub_expr)
+ sudo_fatalx(U_("unmatched '(' in expression"));
+ if (or)
+ sudo_fatalx(U_("illegal trailing \"or\""));
+ if (not)
+ sudo_fatalx(U_("illegal trailing \"!\""));
+
+ debug_return_int(av - argv);
+}
+
+static bool
+match_expr(struct search_node_list *head, struct log_info *log, bool last_match)
+{
+ struct search_node *sn;
+ bool res = false, matched = last_match;
+ int rc;
+ debug_decl(match_expr, SUDO_DEBUG_UTIL)
+
+ STAILQ_FOREACH(sn, head, entries) {
+ switch (sn->type) {
+ case ST_EXPR:
+ res = match_expr(&sn->u.expr, log, matched);
+ break;
+ case ST_CWD:
+ res = strcmp(sn->u.cwd, log->cwd) == 0;
+ break;
+ case ST_TTY:
+ res = strcmp(sn->u.tty, log->tty) == 0;
+ break;
+ case ST_RUNASGROUP:
+ if (log->runas_group != NULL)
+ res = strcmp(sn->u.runas_group, log->runas_group) == 0;
+ break;
+ case ST_RUNASUSER:
+ res = strcmp(sn->u.runas_user, log->runas_user) == 0;
+ break;
+ case ST_USER:
+ res = strcmp(sn->u.user, log->user) == 0;
+ break;
+ case ST_PATTERN:
+ rc = regexec(&sn->u.cmdre, log->cmd, 0, NULL, 0);
+ if (rc && rc != REG_NOMATCH) {
+ char buf[BUFSIZ];
+ regerror(rc, &sn->u.cmdre, buf, sizeof(buf));
+ sudo_fatalx("%s", buf);
+ }
+ res = rc == REG_NOMATCH ? 0 : 1;
+ break;
+ case ST_FROMDATE:
+ res = log->tstamp >= sn->u.tstamp;
+ break;
+ case ST_TODATE:
+ res = log->tstamp <= sn->u.tstamp;
+ break;
+ default:
+ sudo_fatalx(U_("unknown search type %d"), sn->type);
+ /* NOTREACHED */
+ }
+ if (sn->negated)
+ res = !res;
+ matched = sn->or ? (res || last_match) : (res && last_match);
+ last_match = matched;
+ }
+ debug_return_bool(matched);
+}
+
+static int
+list_session(char *logfile, regex_t *re, const char *user, const char *tty)
+{
+ char idbuf[7], *idstr, *cp;
+ const char *timestr;
+ struct log_info *li;
+ int ret = -1;
+ debug_decl(list_session, SUDO_DEBUG_UTIL)
+
+ if ((li = parse_logfile(logfile)) == NULL)
+ goto done;
+
+ /* Match on search expression if there is one. */
+ if (!STAILQ_EMPTY(&search_expr) && !match_expr(&search_expr, li, true))
+ goto done;
+
+ /* Convert from /var/log/sudo-sessions/00/00/01/log to 000001 */
+ cp = logfile + strlen(session_dir) + 1;
+ if (IS_IDLOG(cp)) {
+ idbuf[0] = cp[0];
+ idbuf[1] = cp[1];
+ idbuf[2] = cp[3];
+ idbuf[3] = cp[4];
+ idbuf[4] = cp[6];
+ idbuf[5] = cp[7];
+ idbuf[6] = '\0';
+ idstr = idbuf;
+ } else {
+ /* Not an id, just use the iolog_file portion. */
+ cp[strlen(cp) - 4] = '\0';
+ idstr = cp;
+ }
+ /* XXX - print rows + cols? */
+ timestr = get_timestr(li->tstamp, 1);
+ printf("%s : %s : TTY=%s ; CWD=%s ; USER=%s ; ",
+ timestr ? timestr : "invalid date",
+ li->user, li->tty, li->cwd, li->runas_user);
+ if (li->runas_group)
+ printf("GROUP=%s ; ", li->runas_group);
+ printf("TSID=%s ; COMMAND=%s\n", idstr, li->cmd);
+
+ ret = 0;
+
+done:
+ free_log_info(li);
+ debug_return_int(ret);
+}
+
+static int
+session_compare(const void *v1, const void *v2)
+{
+ const char *s1 = *(const char **)v1;
+ const char *s2 = *(const char **)v2;
+ return strcmp(s1, s2);
+}
+
+/* XXX - always returns 0, calls sudo_fatal() on failure */
+static int
+find_sessions(const char *dir, regex_t *re, const char *user, const char *tty)
+{
+ DIR *d;
+ struct dirent *dp;
+ struct stat sb;
+ size_t sdlen, sessions_len = 0, sessions_size = 0;
+ unsigned int i;
+ int len;
+ char pathbuf[PATH_MAX], **sessions = NULL;
+#ifdef HAVE_STRUCT_DIRENT_D_TYPE
+ bool checked_type = true;
+#else
+ const bool checked_type = false;
+#endif
+ debug_decl(find_sessions, SUDO_DEBUG_UTIL)
+
+ d = opendir(dir);
+ if (d == NULL)
+ sudo_fatal(U_("unable to open %s"), dir);
+
+ /* XXX - would be faster to use openat() and relative names */
+ sdlen = strlcpy(pathbuf, dir, sizeof(pathbuf));
+ if (sdlen + 1 >= sizeof(pathbuf)) {
+ errno = ENAMETOOLONG;
+ sudo_fatal("%s/", dir);
+ }
+ pathbuf[sdlen++] = '/';
+ pathbuf[sdlen] = '\0';
+
+ /* Store potential session dirs for sorting. */
+ while ((dp = readdir(d)) != NULL) {
+ /* Skip "." and ".." */
+ if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' ||
+ (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
+ continue;
+#ifdef HAVE_STRUCT_DIRENT_D_TYPE
+ if (checked_type) {
+ if (dp->d_type != DT_DIR) {
+ /* Not all file systems support d_type. */
+ if (dp->d_type != DT_UNKNOWN)
+ continue;
+ checked_type = false;
+ }
+ }
+#endif
+
+ /* Add name to session list. */
+ if (sessions_len + 1 > sessions_size) {
+ if (sessions_size == 0)
+ sessions_size = 36 * 36 / 2;
+ sessions = reallocarray(sessions, sessions_size, 2 * sizeof(char *));
+ if (sessions == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sessions_size *= 2;
+ }
+ if ((sessions[sessions_len] = strdup(dp->d_name)) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sessions_len++;
+ }
+ closedir(d);
+
+ /* Sort and list the sessions. */
+ if (sessions != NULL) {
+ qsort(sessions, sessions_len, sizeof(char *), session_compare);
+ for (i = 0; i < sessions_len; i++) {
+ len = snprintf(&pathbuf[sdlen], sizeof(pathbuf) - sdlen,
+ "%s/log", sessions[i]);
+ if (len <= 0 || (size_t)len >= sizeof(pathbuf) - sdlen) {
+ errno = ENAMETOOLONG;
+ sudo_fatal("%s/%s/log", dir, sessions[i]);
+ }
+ free(sessions[i]);
+
+ /* Check for dir with a log file. */
+ if (lstat(pathbuf, &sb) == 0 && S_ISREG(sb.st_mode)) {
+ list_session(pathbuf, re, user, tty);
+ } else {
+ /* Strip off "/log" and recurse if a dir. */
+ pathbuf[sdlen + len - 4] = '\0';
+ if (checked_type ||
+ (lstat(pathbuf, &sb) == 0 && S_ISDIR(sb.st_mode)))
+ find_sessions(pathbuf, re, user, tty);
+ }
+ }
+ free(sessions);
+ }
+
+ debug_return_int(0);
+}
+
+/* XXX - always returns 0, calls sudo_fatal() on failure */
+static int
+list_sessions(int argc, char **argv, const char *pattern, const char *user,
+ const char *tty)
+{
+ regex_t rebuf, *re = NULL;
+ debug_decl(list_sessions, SUDO_DEBUG_UTIL)
+
+ /* Parse search expression if present */
+ parse_expr(&search_expr, argv, false);
+
+ /* optional regex */
+ if (pattern) {
+ re = &rebuf;
+ if (regcomp(re, pattern, REG_EXTENDED|REG_NOSUB) != 0)
+ sudo_fatalx(U_("invalid regular expression: %s"), pattern);
+ }
+
+ debug_return_int(find_sessions(session_dir, re, user, tty));
+}
+
+/*
+ * Check keyboard for ' ', '<', '>', return
+ * pause, slow, fast, next
+ */
+static void
+read_keyboard(int fd, int what, void *v)
+{
+ struct replay_closure *closure = v;
+ static bool paused = false;
+ struct timespec ts;
+ ssize_t nread;
+ char ch;
+ debug_decl(read_keyboard, SUDO_DEBUG_UTIL)
+
+ nread = read(fd, &ch, 1);
+ switch (nread) {
+ case -1:
+ if (errno != EINTR && errno != EAGAIN)
+ sudo_fatal(U_("unable to read %s"), "stdin");
+ break;
+ case 0:
+ /* Ignore EOF. */
+ break;
+ default:
+ if (paused) {
+ /* Any key will unpause, run the delay callback directly. */
+ paused = false;
+ delay_cb(-1, SUDO_EV_TIMEOUT, closure);
+ debug_return;
+ }
+ switch (ch) {
+ case ' ':
+ paused = true;
+ /* Disable the delay event until we unpause. */
+ sudo_ev_del(closure->evbase, closure->delay_ev);
+ break;
+ case '<':
+ speed_factor /= 2;
+ sudo_ev_get_timeleft(closure->delay_ev, &ts);
+ if (sudo_timespecisset(&ts)) {
+ /* Double remaining timeout. */
+ ts.tv_sec *= 2;
+ ts.tv_nsec *= 2;
+ if (ts.tv_nsec >= 1000000000) {
+ ts.tv_sec++;
+ ts.tv_nsec -= 1000000000;
+ }
+ if (sudo_ev_add(NULL, closure->delay_ev, &ts, false) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "failed to double remaining delay timeout");
+ }
+ }
+ break;
+ case '>':
+ speed_factor *= 2;
+ sudo_ev_get_timeleft(closure->delay_ev, &ts);
+ if (sudo_timespecisset(&ts)) {
+ /* Halve remaining timeout. */
+ if (ts.tv_sec & 1)
+ ts.tv_nsec += 500000000;
+ ts.tv_sec /= 2;
+ ts.tv_nsec /= 2;
+ if (sudo_ev_add(NULL, closure->delay_ev, &ts, false) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "failed to halve remaining delay timeout");
+ }
+ }
+ break;
+ case '\r':
+ case '\n':
+ /* Cancel existing delay, run callback directly. */
+ sudo_ev_del(closure->evbase, closure->delay_ev);
+ delay_cb(-1, SUDO_EV_TIMEOUT, closure);
+ break;
+ default:
+ /* Unknown key, nothing to do. */
+ break;
+ }
+ break;
+ }
+ debug_return;
+}
+
+static void
+usage(int fatal)
+{
+ fprintf(fatal ? stderr : stdout,
+ _("usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"),
+ getprogname());
+ fprintf(fatal ? stderr : stdout,
+ _("usage: %s [-h] [-d dir] -l [search expression]\n"),
+ getprogname());
+ if (fatal)
+ exit(1);
+}
+
+static void
+help(void)
+{
+ (void) printf(_("%s - replay sudo session logs\n\n"), getprogname());
+ usage(0);
+ (void) puts(_("\nOptions:\n"
+ " -d, --directory=dir specify directory for session logs\n"
+ " -f, --filter=filter specify which I/O type(s) to display\n"
+ " -h, --help display help message and exit\n"
+ " -l, --list list available session IDs, with optional expression\n"
+ " -m, --max-wait=num max number of seconds to wait between events\n"
+ " -n, --non-interactive no prompts, session is sent to the standard output\n"
+ " -R, --no-resize do not attempt to re-size the terminal\n"
+ " -S, --suspend-wait wait while the command was suspended\n"
+ " -s, --speed=num speed up or slow down output\n"
+ " -V, --version display version information and exit"));
+ exit(0);
+}
+
+/*
+ * Cleanup hook for sudo_fatal()/sudo_fatalx()
+ */
+static void
+sudoreplay_cleanup(void)
+{
+ restore_terminal_size();
+ sudo_term_restore(ttyfd, false);
+}
diff --git a/plugins/sudoers/testsudoers.c b/plugins/sudoers/testsudoers.c
new file mode 100644
index 0000000..2a97dfc
--- /dev/null
+++ b/plugins/sudoers/testsudoers.c
@@ -0,0 +1,608 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#ifdef HAVE_NETGROUP_H
+# include <netgroup.h>
+#endif /* HAVE_NETGROUP_H */
+#include <time.h>
+#include <ctype.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "tsgetgrpw.h"
+#include "sudoers.h"
+#include "interfaces.h"
+#include "sudo_conf.h"
+#include "sudo_lbuf.h"
+#include <gram.h>
+
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+enum sudoers_formats {
+ format_ldif,
+ format_sudoers
+};
+
+/*
+ * Function Prototypes
+ */
+static void dump_sudoers(struct sudo_lbuf *lbuf);
+static void usage(void) __attribute__((__noreturn__));
+static void set_runaspw(const char *);
+static void set_runasgr(const char *);
+static bool cb_runas_default(const union sudo_defs_val *);
+static int testsudoers_error(const char *msg);
+static int testsudoers_output(const char *buf);
+
+/* tsgetgrpw.c */
+extern void setgrfile(const char *);
+extern void setgrent(void);
+extern void endgrent(void);
+extern struct group *getgrent(void);
+extern struct group *getgrnam(const char *);
+extern struct group *getgrgid(gid_t);
+extern void setpwfile(const char *);
+extern void setpwent(void);
+extern void endpwent(void);
+extern struct passwd *getpwent(void);
+extern struct passwd *getpwnam(const char *);
+extern struct passwd *getpwuid(uid_t);
+
+/* gram.y */
+extern int (*trace_print)(const char *msg);
+
+/*
+ * Globals
+ */
+struct sudo_user sudo_user;
+struct passwd *list_pw;
+static char *runas_group, *runas_user;
+
+#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
+extern char *malloc_options;
+#endif
+#if YYDEBUG
+extern int sudoersdebug;
+#endif
+
+__dso_public int main(int argc, char *argv[]);
+
+int
+main(int argc, char *argv[])
+{
+ enum sudoers_formats input_format = format_sudoers;
+ struct cmndspec *cs;
+ struct privilege *priv;
+ struct userspec *us;
+ char *p, *grfile, *pwfile;
+ const char *errstr;
+ int match, host_match, runas_match, cmnd_match;
+ int ch, dflag, exitcode = EXIT_FAILURE;
+ struct sudo_lbuf lbuf;
+ debug_decl(main, SUDOERS_DEBUG_MAIN)
+
+#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
+ malloc_options = "S";
+#endif
+#if YYDEBUG
+ sudoersdebug = 1;
+#endif
+
+ initprogname(argc > 0 ? argv[0] : "testsudoers");
+
+ if (!sudoers_initlocale(setlocale(LC_ALL, ""), def_sudoers_locale))
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sudo_warn_set_locale_func(sudoers_warn_setlocale);
+ bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have own domain */
+ textdomain("sudoers");
+
+ /* No word wrap on output. */
+ sudo_lbuf_init(&lbuf, testsudoers_output, 0, NULL, 0);
+
+ /* Initialize the debug subsystem. */
+ if (sudo_conf_read(NULL, SUDO_CONF_DEBUG) == -1)
+ goto done;
+ if (!sudoers_debug_register(getprogname(), sudo_conf_debug_files(getprogname())))
+ goto done;
+
+ dflag = 0;
+ grfile = pwfile = NULL;
+ while ((ch = getopt(argc, argv, "dg:G:h:i:P:p:tu:U:")) != -1) {
+ switch (ch) {
+ case 'd':
+ dflag = 1;
+ break;
+ case 'G':
+ sudoers_gid = (gid_t)sudo_strtoid(optarg, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx("group ID %s: %s", optarg, errstr);
+ break;
+ case 'g':
+ runas_group = optarg;
+ SET(sudo_user.flags, RUNAS_GROUP_SPECIFIED);
+ break;
+ case 'h':
+ user_host = optarg;
+ break;
+ case 'i':
+ if (strcasecmp(optarg, "ldif") == 0) {
+ input_format = format_ldif;
+ } else if (strcasecmp(optarg, "sudoers") == 0) {
+ input_format = format_sudoers;
+ } else {
+ sudo_warnx(U_("unsupported input format %s"), optarg);
+ usage();
+ }
+ break;
+ case 'p':
+ pwfile = optarg;
+ break;
+ case 'P':
+ grfile = optarg;
+ break;
+ case 't':
+ trace_print = testsudoers_error;
+ break;
+ case 'U':
+ sudoers_uid = (uid_t)sudo_strtoid(optarg, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx("user ID %s: %s", optarg, errstr);
+ break;
+ case 'u':
+ runas_user = optarg;
+ SET(sudo_user.flags, RUNAS_USER_SPECIFIED);
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ /* Set group/passwd file and init the cache. */
+ if (grfile)
+ setgrfile(grfile);
+ if (pwfile)
+ setpwfile(pwfile);
+
+ if (argc < 2) {
+ if (!dflag)
+ usage();
+ user_name = argc ? *argv++ : "root";
+ user_cmnd = user_base = "true";
+ argc = 0;
+ } else {
+ user_name = *argv++;
+ user_cmnd = *argv++;
+ if ((p = strrchr(user_cmnd, '/')) != NULL)
+ user_base = p + 1;
+ else
+ user_base = user_cmnd;
+ argc -= 2;
+ }
+ if ((sudo_user.pw = sudo_getpwnam(user_name)) == NULL)
+ sudo_fatalx(U_("unknown user: %s"), user_name);
+
+ if (user_host == NULL) {
+ if ((user_host = sudo_gethostname()) == NULL)
+ sudo_fatal("gethostname");
+ }
+ if ((p = strchr(user_host, '.'))) {
+ *p = '\0';
+ if ((user_shost = strdup(user_host)) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ *p = '.';
+ } else {
+ user_shost = user_host;
+ }
+ user_runhost = user_host;
+ user_srunhost = user_shost;
+
+ /* Fill in user_args from argv. */
+ if (argc > 0) {
+ char *to, **from;
+ size_t size, n;
+
+ for (size = 0, from = argv; *from; from++)
+ size += strlen(*from) + 1;
+
+ if ((user_args = malloc(size)) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ for (to = user_args, from = argv; *from; from++) {
+ n = strlcpy(to, *from, size - (to - user_args));
+ if (n >= size - (to - user_args))
+ sudo_fatalx(U_("internal error, %s overflow"), getprogname());
+ to += n;
+ *to++ = ' ';
+ }
+ *--to = '\0';
+ }
+
+ /* Initialize default values. */
+ if (!init_defaults())
+ sudo_fatalx(U_("unable to initialize sudoers default values"));
+
+ /* Set group_plugin callback. */
+ sudo_defs_table[I_GROUP_PLUGIN].callback = cb_group_plugin;
+
+ /* Set runas callback. */
+ sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;
+
+ /* Set locale callback. */
+ sudo_defs_table[I_SUDOERS_LOCALE].callback = sudoers_locale_callback;
+
+ /* Load ip addr/mask for each interface. */
+ if (get_net_ifs(&p) > 0) {
+ if (!set_interfaces(p))
+ sudo_fatal(U_("unable to parse network address list"));
+ }
+
+ /* Allocate space for data structures in the parser. */
+ init_parser("sudoers", false);
+
+ /*
+ * Set runas passwd/group entries based on command line or sudoers.
+ * Note that if runas_group was specified without runas_user we
+ * run the command as the invoking user.
+ */
+ if (runas_group != NULL) {
+ set_runasgr(runas_group);
+ set_runaspw(runas_user ? runas_user : user_name);
+ } else
+ set_runaspw(runas_user ? runas_user : def_runas_default);
+
+ /* Parse the policy file. */
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, NULL);
+ switch (input_format) {
+ case format_ldif:
+ if (!sudoers_parse_ldif(&parsed_policy, stdin, NULL, true))
+ (void) printf("Parse error in LDIF");
+ else
+ (void) fputs("Parses OK", stdout);
+ break;
+ case format_sudoers:
+ if (sudoersparse() != 0 || parse_error) {
+ parse_error = true;
+ if (errorlineno != -1)
+ (void) printf("Parse error in %s near line %d",
+ errorfile, errorlineno);
+ else
+ (void) printf("Parse error in %s", errorfile);
+ } else {
+ (void) fputs("Parses OK", stdout);
+ }
+ break;
+ default:
+ sudo_fatalx("error: unhandled input %d", input_format);
+ }
+
+ if (!update_defaults(&parsed_policy, NULL, SETDEF_ALL, false))
+ (void) fputs(" (problem with defaults entries)", stdout);
+ puts(".");
+
+ if (dflag) {
+ (void) putchar('\n');
+ dump_sudoers(&lbuf);
+ if (argc < 2) {
+ exitcode = parse_error ? 1 : 0;
+ goto done;
+ }
+ }
+
+ /* This loop must match the one in sudo_file_lookup() */
+ printf("\nEntries for user %s:\n", user_name);
+ match = UNSPEC;
+ TAILQ_FOREACH_REVERSE(us, &parsed_policy.userspecs, userspec_list, entries) {
+ if (userlist_matches(&parsed_policy, sudo_user.pw, &us->users) != ALLOW)
+ continue;
+ TAILQ_FOREACH_REVERSE(priv, &us->privileges, privilege_list, entries) {
+ sudo_lbuf_append(&lbuf, "\n");
+ sudoers_format_privilege(&lbuf, &parsed_policy, priv, false);
+ sudo_lbuf_print(&lbuf);
+ host_match = hostlist_matches(&parsed_policy, sudo_user.pw,
+ &priv->hostlist);
+ if (host_match == ALLOW) {
+ puts("\thost matched");
+ TAILQ_FOREACH_REVERSE(cs, &priv->cmndlist, cmndspec_list, entries) {
+ runas_match = runaslist_matches(&parsed_policy,
+ cs->runasuserlist, cs->runasgrouplist, NULL, NULL);
+ if (runas_match == ALLOW) {
+ puts("\trunas matched");
+ cmnd_match = cmnd_matches(&parsed_policy, cs->cmnd);
+ if (cmnd_match != UNSPEC)
+ match = cmnd_match;
+ printf("\tcmnd %s\n", match == ALLOW ? "allowed" :
+ match == DENY ? "denied" : "unmatched");
+ }
+ }
+ } else
+ puts(U_("\thost unmatched"));
+ }
+ }
+ puts(match == ALLOW ? U_("\nCommand allowed") :
+ match == DENY ? U_("\nCommand denied") : U_("\nCommand unmatched"));
+
+ /*
+ * Exit codes:
+ * 0 - parsed OK and command matched.
+ * 1 - parse error
+ * 2 - command not matched
+ * 3 - command denied
+ */
+ exitcode = parse_error ? 1 : (match == ALLOW ? 0 : match + 3);
+done:
+ sudo_lbuf_destroy(&lbuf);
+ sudo_freepwcache();
+ sudo_freegrcache();
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);
+ exit(exitcode);
+}
+
+static void
+set_runaspw(const char *user)
+{
+ struct passwd *pw = NULL;
+ debug_decl(set_runaspw, SUDOERS_DEBUG_UTIL)
+
+ if (*user == '#') {
+ const char *errstr;
+ uid_t uid = sudo_strtoid(user + 1, NULL, NULL, &errstr);
+ if (errstr == NULL) {
+ if ((pw = sudo_getpwuid(uid)) == NULL)
+ pw = sudo_fakepwnam(user, user_gid);
+ }
+ }
+ if (pw == NULL) {
+ if ((pw = sudo_getpwnam(user)) == NULL)
+ sudo_fatalx(U_("unknown user: %s"), user);
+ }
+ if (runas_pw != NULL)
+ sudo_pw_delref(runas_pw);
+ runas_pw = pw;
+ debug_return;
+}
+
+static void
+set_runasgr(const char *group)
+{
+ struct group *gr = NULL;
+ debug_decl(set_runasgr, SUDOERS_DEBUG_UTIL)
+
+ if (*group == '#') {
+ const char *errstr;
+ gid_t gid = sudo_strtoid(group + 1, NULL, NULL, &errstr);
+ if (errstr == NULL) {
+ if ((gr = sudo_getgrgid(gid)) == NULL)
+ gr = sudo_fakegrnam(group);
+ }
+ }
+ if (gr == NULL) {
+ if ((gr = sudo_getgrnam(group)) == NULL)
+ sudo_fatalx(U_("unknown group: %s"), group);
+ }
+ if (runas_gr != NULL)
+ sudo_gr_delref(runas_gr);
+ runas_gr = gr;
+ debug_return;
+}
+
+/*
+ * Callback for runas_default sudoers setting.
+ */
+static bool
+cb_runas_default(const union sudo_defs_val *sd_un)
+{
+ /* Only reset runaspw if user didn't specify one. */
+ if (!runas_user && !runas_group)
+ set_runaspw(sd_un->str);
+ return true;
+}
+
+void
+sudo_setspent(void)
+{
+ return;
+}
+
+void
+sudo_endspent(void)
+{
+ return;
+}
+
+FILE *
+open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
+{
+ struct stat sb;
+ FILE *fp = NULL;
+ char *sudoers_base;
+ debug_decl(open_sudoers, SUDOERS_DEBUG_UTIL)
+
+ sudoers_base = strrchr(sudoers, '/');
+ if (sudoers_base != NULL)
+ sudoers_base++;
+
+ switch (sudo_secure_file(sudoers, sudoers_uid, sudoers_gid, &sb)) {
+ case SUDO_PATH_SECURE:
+ fp = fopen(sudoers, "r");
+ break;
+ case SUDO_PATH_MISSING:
+ sudo_warn("unable to stat %s", sudoers_base);
+ break;
+ case SUDO_PATH_BAD_TYPE:
+ sudo_warnx("%s is not a regular file", sudoers_base);
+ break;
+ case SUDO_PATH_WRONG_OWNER:
+ sudo_warnx("%s should be owned by uid %u",
+ sudoers_base, (unsigned int) sudoers_uid);
+ break;
+ case SUDO_PATH_WORLD_WRITABLE:
+ sudo_warnx("%s is world writable", sudoers_base);
+ break;
+ case SUDO_PATH_GROUP_WRITABLE:
+ sudo_warnx("%s should be owned by gid %u",
+ sudoers_base, (unsigned int) sudoers_gid);
+ break;
+ default:
+ /* NOTREACHED */
+ break;
+ }
+
+ debug_return_ptr(fp);
+}
+
+bool
+init_envtables(void)
+{
+ return(true);
+}
+
+bool
+set_perms(int perm)
+{
+ return true;
+}
+
+bool
+restore_perms(void)
+{
+ return true;
+}
+
+static bool
+print_defaults(struct sudo_lbuf *lbuf)
+{
+ struct defaults *def, *next;
+ debug_decl(print_defaults, SUDOERS_DEBUG_UTIL)
+
+ TAILQ_FOREACH_SAFE(def, &parsed_policy.defaults, entries, next)
+ sudoers_format_default_line(lbuf, &parsed_policy, def, &next, false);
+
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+static int
+print_alias(struct sudoers_parse_tree *parse_tree, struct alias *a, void *v)
+{
+ struct sudo_lbuf *lbuf = v;
+ struct member *m;
+ debug_decl(print_alias, SUDOERS_DEBUG_UTIL)
+
+ sudo_lbuf_append(lbuf, "%s %s = ", alias_type_to_string(a->type),
+ a->name);
+ TAILQ_FOREACH(m, &a->members, entries) {
+ if (m != TAILQ_FIRST(&a->members))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, parse_tree, m, NULL, UNSPEC);
+ }
+ sudo_lbuf_append(lbuf, "\n");
+
+ debug_return_int(sudo_lbuf_error(lbuf) ? -1 : 0);
+}
+
+static bool
+print_aliases(struct sudo_lbuf *lbuf)
+{
+ debug_decl(print_aliases, SUDOERS_DEBUG_UTIL)
+
+ alias_apply(&parsed_policy, print_alias, lbuf);
+
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+static void
+dump_sudoers(struct sudo_lbuf *lbuf)
+{
+ debug_decl(dump_sudoers, SUDOERS_DEBUG_UTIL)
+
+ /* Print Defaults */
+ if (!print_defaults(lbuf))
+ goto done;
+ if (lbuf->len > 0) {
+ sudo_lbuf_print(lbuf);
+ sudo_lbuf_append(lbuf, "\n");
+ }
+
+ /* Print Aliases */
+ if (!print_aliases(lbuf))
+ goto done;
+ if (lbuf->len > 1) {
+ sudo_lbuf_print(lbuf);
+ sudo_lbuf_append(lbuf, "\n");
+ }
+
+ /* Print User_Specs */
+ if (!sudoers_format_userspecs(lbuf, &parsed_policy, NULL, false, true))
+ goto done;
+ if (lbuf->len > 1) {
+ sudo_lbuf_print(lbuf);
+ }
+
+done:
+ if (sudo_lbuf_error(lbuf)) {
+ if (errno == ENOMEM)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ }
+
+ debug_return;
+}
+
+static int
+testsudoers_output(const char *buf)
+{
+ return fputs(buf, stdout);
+}
+
+static int
+testsudoers_error(const char *buf)
+{
+ return fputs(buf, stderr);
+}
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr, "usage: %s [-dt] [-G sudoers_gid] [-g group] [-h host] [-i input_format] [-P grfile] [-p pwfile] [-U sudoers_uid] [-u user] <user> <command> [args]\n", getprogname());
+ exit(1);
+}
diff --git a/plugins/sudoers/timeout.c b/plugins/sudoers/timeout.c
new file mode 100644
index 0000000..3b621e3
--- /dev/null
+++ b/plugins/sudoers/timeout.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+
+#include "sudo_compat.h"
+#include "sudoers_debug.h"
+#include "parse.h"
+
+/*
+ * Parse a command timeout in sudoers in the format 1d2h3m4s
+ * (days, hours, minutes, seconds) or a number of seconds with no suffix.
+ * Returns the number of seconds or -1 on error.
+ */
+int
+parse_timeout(const char *timestr)
+{
+ debug_decl(parse_timeout, SUDOERS_DEBUG_PARSER)
+ const char suffixes[] = "dhms";
+ const char *cp = timestr;
+ int timeout = 0;
+ int idx = 0;
+
+ do {
+ char *ep;
+ char ch;
+ long l;
+
+ /* Parse number, must be present and positive. */
+ errno = 0;
+ l = strtol(cp, &ep, 10);
+ if (ep == cp) {
+ /* missing timeout */
+ errno = EINVAL;
+ debug_return_int(-1);
+ }
+ if (errno == ERANGE || l < 0 || l > INT_MAX)
+ goto overflow;
+
+ /* Find a matching suffix or return an error. */
+ if (*ep != '\0') {
+ ch = tolower((unsigned char)*ep++);
+ while (suffixes[idx] != ch) {
+ if (suffixes[idx] == '\0') {
+ /* parse error */
+ errno = EINVAL;
+ debug_return_int(-1);
+ }
+ idx++;
+ }
+
+ /* Apply suffix. */
+ switch (ch) {
+ case 'd':
+ if (l > INT_MAX / (24 * 60 * 60))
+ goto overflow;
+ l *= 24 * 60 * 60;
+ break;
+ case 'h':
+ if (l > INT_MAX / (60 * 60))
+ goto overflow;
+ l *= 60 * 60;
+ break;
+ case 'm':
+ if (l > INT_MAX / 60)
+ goto overflow;
+ l *= 60;
+ break;
+ }
+ if (l > INT_MAX - timeout)
+ goto overflow;
+ }
+ cp = ep;
+
+ timeout += l;
+ } while (*cp != '\0');
+
+ debug_return_int(timeout);
+overflow:
+ errno = ERANGE;
+ debug_return_int(-1);
+}
diff --git a/plugins/sudoers/timestamp.c b/plugins/sudoers/timestamp.c
new file mode 100644
index 0000000..5930103
--- /dev/null
+++ b/plugins/sudoers/timestamp.c
@@ -0,0 +1,1075 @@
+/*
+ * Copyright (c) 2014-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
+#include <signal.h>
+
+#include "sudoers.h"
+#include "check.h"
+
+#define TIMESTAMP_OPEN_ERROR -1
+#define TIMESTAMP_PERM_ERROR -2
+
+/*
+ * Each user has a single time stamp file that contains multiple records.
+ * Records are locked to ensure that changes are serialized.
+ *
+ * The first record is of type TS_LOCKEXCL and is used to gain exclusive
+ * access to create new records. This is a short-term lock and sudo
+ * should not sleep while holding it (or the user will not be able to sudo).
+ * The TS_LOCKEXCL entry must be unlocked before locking the actual record.
+ */
+
+struct ts_cookie {
+ char *fname;
+ int fd;
+ pid_t sid;
+ bool locked;
+ off_t pos;
+ struct timestamp_entry key;
+};
+
+/*
+ * Returns true if entry matches key, else false.
+ * We don't match on the sid or actual time stamp.
+ */
+static bool
+ts_match_record(struct timestamp_entry *key, struct timestamp_entry *entry,
+ unsigned int recno)
+{
+ debug_decl(ts_match_record, SUDOERS_DEBUG_AUTH)
+
+ if (entry->version != key->version) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s:%u record version mismatch (want %u, got %u)", __func__, recno,
+ key->version, entry->version);
+ debug_return_bool(false);
+ }
+ if (!ISSET(key->flags, TS_ANYUID) && entry->auth_uid != key->auth_uid) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s:%u record uid mismatch (want %u, got %u)", __func__, recno,
+ (unsigned int)key->auth_uid, (unsigned int)entry->auth_uid);
+ debug_return_bool(false);
+ }
+ if (entry->type != key->type) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s:%u record type mismatch (want %u, got %u)", __func__, recno,
+ key->type, entry->type);
+ debug_return_bool(false);
+ }
+ switch (entry->type) {
+ case TS_GLOBAL:
+ /* no ppid or tty to match */
+ break;
+ case TS_PPID:
+ /* verify parent pid */
+ if (entry->u.ppid != key->u.ppid) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s:%u record ppid mismatch (want %d, got %d)", __func__, recno,
+ (int)key->u.ppid, (int)entry->u.ppid);
+ debug_return_bool(false);
+ }
+ if (sudo_timespeccmp(&entry->start_time, &key->start_time, !=)) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s:%u ppid start time mismatch", __func__, recno);
+ debug_return_bool(false);
+ }
+ break;
+ case TS_TTY:
+ if (entry->u.ttydev != key->u.ttydev) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s:%u record tty mismatch (want 0x%x, got 0x%x)", __func__,
+ recno, (unsigned int)key->u.ttydev, (unsigned int)entry->u.ttydev);
+ debug_return_bool(false);
+ }
+ if (sudo_timespeccmp(&entry->start_time, &key->start_time, !=)) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "%s:%u session leader start time mismatch", __func__, recno);
+ debug_return_bool(false);
+ }
+ break;
+ default:
+ /* unknown record type, ignore it */
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
+ "%s:%u unknown time stamp record type %d", __func__, recno,
+ entry->type);
+ debug_return_bool(false);
+ }
+ debug_return_bool(true);
+}
+
+/*
+ * Searches the time stamp file descriptor for a record that matches key.
+ * On success, fills in entry with the matching record and returns true.
+ * On failure, returns false.
+ *
+ * Note that records are searched starting at the current file offset,
+ * which may not be the beginning of the file.
+ */
+static bool
+ts_find_record(int fd, struct timestamp_entry *key, struct timestamp_entry *entry)
+{
+ struct timestamp_entry cur;
+ unsigned int recno = 0;
+ debug_decl(ts_find_record, SUDOERS_DEBUG_AUTH)
+
+ /*
+ * Find a matching record (does not match sid or time stamp value).
+ */
+ while (read(fd, &cur, sizeof(cur)) == sizeof(cur)) {
+ recno++;
+ if (cur.size != sizeof(cur)) {
+ /* wrong size, seek to start of next record */
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "wrong sized record, got %hu, expected %zu",
+ cur.size, sizeof(cur));
+ if (lseek(fd, (off_t)cur.size - (off_t)sizeof(cur), SEEK_CUR) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "unable to seek forward %d",
+ (int)cur.size - (int)sizeof(cur));
+ break;
+ }
+ if (cur.size == 0)
+ break; /* size must be non-zero */
+ continue;
+ }
+ if (ts_match_record(key, &cur, recno)) {
+ memcpy(entry, &cur, sizeof(struct timestamp_entry));
+ debug_return_bool(true);
+ }
+ }
+ debug_return_bool(false);
+}
+
+/*
+ * Create a directory and any missing parent directories with the
+ * specified mode.
+ * Returns true on success.
+ * Returns false on failure and displays a warning to stderr.
+ */
+static bool
+ts_mkdirs(char *path, uid_t owner, gid_t group, mode_t mode,
+ mode_t parent_mode, bool quiet)
+{
+ bool ret;
+ mode_t omask;
+ debug_decl(ts_mkdirs, SUDOERS_DEBUG_AUTH)
+
+ /* umask must not be more restrictive than the file modes. */
+ omask = umask(ACCESSPERMS & ~(mode|parent_mode));
+ ret = sudo_mkdir_parents(path, owner, group, parent_mode, quiet);
+ if (ret) {
+ /* Create final path component. */
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "mkdir %s, mode 0%o, uid %d, gid %d", path, (unsigned int)mode,
+ (int)owner, (int)group);
+ if (mkdir(path, mode) != 0 && errno != EEXIST) {
+ if (!quiet)
+ sudo_warn(U_("unable to mkdir %s"), path);
+ ret = false;
+ } else {
+ if (chown(path, owner, group) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to chown %d:%d %s", __func__,
+ (int)owner, (int)group, path);
+ }
+ }
+ }
+ umask(omask);
+ debug_return_bool(ret);
+}
+
+/*
+ * Check that path is owned by timestamp_uid and not writable by
+ * group or other. If path is missing and make_it is true, create
+ * the directory and its parent dirs.
+ * Returns true on success or false on failure, setting errno.
+ */
+static bool
+ts_secure_dir(char *path, bool make_it, bool quiet)
+{
+ struct stat sb;
+ bool ret = false;
+ debug_decl(ts_secure_dir, SUDOERS_DEBUG_AUTH)
+
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, "checking %s", path);
+ switch (sudo_secure_dir(path, timestamp_uid, -1, &sb)) {
+ case SUDO_PATH_SECURE:
+ ret = true;
+ break;
+ case SUDO_PATH_MISSING:
+ if (make_it && ts_mkdirs(path, timestamp_uid, timestamp_gid, S_IRWXU,
+ S_IRWXU|S_IXGRP|S_IXOTH, quiet)) {
+ ret = true;
+ break;
+ }
+ errno = ENOENT;
+ break;
+ case SUDO_PATH_BAD_TYPE:
+ errno = ENOTDIR;
+ if (!quiet)
+ sudo_warn("%s", path);
+ break;
+ case SUDO_PATH_WRONG_OWNER:
+ if (!quiet) {
+ sudo_warnx(U_("%s is owned by uid %u, should be %u"),
+ path, (unsigned int) sb.st_uid,
+ (unsigned int) timestamp_uid);
+ }
+ errno = EACCES;
+ break;
+ case SUDO_PATH_GROUP_WRITABLE:
+ if (!quiet)
+ sudo_warnx(U_("%s is group writable"), path);
+ errno = EACCES;
+ break;
+ }
+ debug_return_bool(ret);
+}
+
+/*
+ * Open the specified timestamp or lecture file and set the
+ * close on exec flag.
+ * Returns open file descriptor on success.
+ * Returns TIMESTAMP_OPEN_ERROR or TIMESTAMP_PERM_ERROR on error.
+ */
+static int
+ts_open(const char *path, int flags)
+{
+ bool uid_changed = false;
+ int fd;
+ debug_decl(ts_open, SUDOERS_DEBUG_AUTH)
+
+ if (timestamp_uid != 0)
+ uid_changed = set_perms(PERM_TIMESTAMP);
+ fd = open(path, flags, S_IRUSR|S_IWUSR);
+ if (uid_changed && !restore_perms()) {
+ /* Unable to restore permissions, should not happen. */
+ if (fd != -1) {
+ int serrno = errno;
+ close(fd);
+ errno = serrno;
+ fd = TIMESTAMP_PERM_ERROR;
+ }
+ }
+ if (fd >= 0)
+ (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
+
+ debug_return_int(fd);
+}
+
+static ssize_t
+ts_write(int fd, const char *fname, struct timestamp_entry *entry, off_t offset)
+{
+ ssize_t nwritten;
+ off_t old_eof;
+ debug_decl(ts_write, SUDOERS_DEBUG_AUTH)
+
+ if (offset == -1) {
+ old_eof = lseek(fd, 0, SEEK_CUR);
+ nwritten = write(fd, entry, entry->size);
+ } else {
+ old_eof = offset;
+#ifdef HAVE_PWRITE
+ nwritten = pwrite(fd, entry, entry->size, offset);
+#else
+ if (lseek(fd, offset, SEEK_SET) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "unable to seek to %lld", (long long)offset);
+ nwritten = -1;
+ } else {
+ nwritten = write(fd, entry, entry->size);
+ }
+#endif
+ }
+ if ((size_t)nwritten != entry->size) {
+ if (nwritten == -1) {
+ log_warning(SLOG_SEND_MAIL,
+ N_("unable to write to %s"), fname);
+ } else {
+ log_warningx(SLOG_SEND_MAIL,
+ N_("unable to write to %s"), fname);
+ }
+
+ /* Truncate on partial write to be safe (assumes end of file). */
+ if (nwritten > 0) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "short write, truncating partial time stamp record");
+ if (ftruncate(fd, old_eof) != 0) {
+ sudo_warn(U_("unable to truncate time stamp file to %lld bytes"),
+ (long long)old_eof);
+ }
+ }
+ debug_return_ssize_t(-1);
+ }
+ debug_return_ssize_t(nwritten);
+}
+
+/*
+ * Full in struct timestamp_entry with the specified flags
+ * based on auth user pw. Does not set the time stamp.
+ */
+static void
+ts_init_key(struct timestamp_entry *entry, struct passwd *pw, int flags,
+ enum def_tuple ticket_type)
+{
+ struct stat sb;
+ debug_decl(ts_init_key, SUDOERS_DEBUG_AUTH)
+
+ memset(entry, 0, sizeof(*entry));
+ entry->version = TS_VERSION;
+ entry->size = sizeof(*entry);
+ entry->flags = flags;
+ if (pw != NULL) {
+ entry->auth_uid = pw->pw_uid;
+ } else {
+ entry->flags |= TS_ANYUID;
+ }
+ entry->sid = user_sid;
+ switch (ticket_type) {
+ default:
+ /* Unknown time stamp ticket type, treat as tty (should not happen). */
+ sudo_warnx("unknown time stamp ticket type %d", ticket_type);
+ /* FALLTHROUGH */
+ case tty:
+ if (user_ttypath != NULL && stat(user_ttypath, &sb) == 0) {
+ /* tty-based time stamp */
+ entry->type = TS_TTY;
+ entry->u.ttydev = sb.st_rdev;
+ if (entry->sid != -1)
+ get_starttime(entry->sid, &entry->start_time);
+ break;
+ }
+ /* FALLTHROUGH */
+ case kernel:
+ case ppid:
+ /* ppid-based time stamp */
+ entry->type = TS_PPID;
+ entry->u.ppid = getppid();
+ get_starttime(entry->u.ppid, &entry->start_time);
+ break;
+ case global:
+ /* global time stamp */
+ entry->type = TS_GLOBAL;
+ break;
+ }
+
+ debug_return;
+}
+
+static void
+ts_init_key_nonglobal(struct timestamp_entry *entry, struct passwd *pw, int flags)
+{
+ /*
+ * Even if the timestamp type is global or kernel we still want to do
+ * per-tty or per-ppid locking so sudo works predictably in a pipeline.
+ */
+ ts_init_key(entry, pw, flags,
+ def_timestamp_type == ppid ? ppid : tty);
+}
+
+/*
+ * Open the user's time stamp file.
+ * Returns a cookie or NULL on error, does not lock the file.
+ */
+void *
+timestamp_open(const char *user, pid_t sid)
+{
+ struct ts_cookie *cookie;
+ char *fname = NULL;
+ int tries, fd = -1;
+ debug_decl(timestamp_open, SUDOERS_DEBUG_AUTH)
+
+ /* Zero timeout means don't use the time stamp file. */
+ if (!sudo_timespecisset(&def_timestamp_timeout)) {
+ errno = ENOENT;
+ goto bad;
+ }
+
+ /* Sanity check timestamp dir and create if missing. */
+ if (!ts_secure_dir(def_timestampdir, true, false))
+ goto bad;
+
+ /* Open time stamp file. */
+ if (asprintf(&fname, "%s/%s", def_timestampdir, user) == -1) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto bad;
+ }
+ for (tries = 1; ; tries++) {
+ struct stat sb;
+
+ fd = ts_open(fname, O_RDWR|O_CREAT);
+ switch (fd) {
+ case TIMESTAMP_OPEN_ERROR:
+ log_warning(SLOG_SEND_MAIL, N_("unable to open %s"), fname);
+ goto bad;
+ case TIMESTAMP_PERM_ERROR:
+ /* Already logged set_perms/restore_perms error. */
+ goto bad;
+ }
+
+ /* Remove time stamp file if its mtime predates boot time. */
+ if (tries == 1 && fstat(fd, &sb) == 0) {
+ struct timespec boottime, mtime, now;
+
+ if (sudo_gettime_real(&now) == 0 && get_boottime(&boottime)) {
+ /* Ignore a boot time that is in the future. */
+ if (sudo_timespeccmp(&now, &boottime, <)) {
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
+ "ignoring boot time that is in the future");
+ } else {
+ mtim_get(&sb, mtime);
+ if (sudo_timespeccmp(&mtime, &boottime, <)) {
+ /* Time stamp file too old, remove it. */
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
+ "removing time stamp file that predates boot time");
+ close(fd);
+ unlink(fname);
+ continue;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ /* Allocate and fill in cookie to store state. */
+ cookie = malloc(sizeof(*cookie));
+ if (cookie == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto bad;
+ }
+ cookie->fd = fd;
+ cookie->fname = fname;
+ cookie->sid = sid;
+ cookie->pos = -1;
+
+ debug_return_ptr(cookie);
+bad:
+ if (fd != -1)
+ close(fd);
+ free(fname);
+ debug_return_ptr(NULL);
+}
+
+static volatile sig_atomic_t got_signal;
+
+static void
+timestamp_handler(int s)
+{
+ got_signal = s;
+}
+
+/*
+ * Wrapper for sudo_lock_region() that is interruptible.
+ */
+static bool
+timestamp_lock_record(int fd, off_t pos, off_t len)
+{
+ struct sigaction sa, saveint, savequit;
+ sigset_t mask, omask;
+ bool ret;
+ debug_decl(timestamp_lock_record, SUDOERS_DEBUG_AUTH)
+
+ if (pos >= 0 && lseek(fd, pos, SEEK_SET) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "unable to seek to %lld", (long long)pos);
+ debug_return_bool(false);
+ }
+
+ /* Allow SIGINT and SIGQUIT to interrupt a lock. */
+ got_signal = 0;
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0; /* don't restart system calls */
+ sa.sa_handler = timestamp_handler;
+ (void) sigaction(SIGINT, &sa, &saveint);
+ (void) sigaction(SIGQUIT, &sa, &savequit);
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGQUIT);
+ (void) sigprocmask(SIG_UNBLOCK, &mask, &omask);
+
+ ret = sudo_lock_region(fd, SUDO_LOCK, len);
+ if (!ret) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "failed to lock fd %d [%lld, %lld]", fd,
+ (long long)pos, (long long)len);
+ }
+
+ /* Restore the old mask (SIGINT and SIGQUIT blocked) and handlers. */
+ (void) sigprocmask(SIG_SETMASK, &omask, NULL);
+ (void) sigaction(SIGINT, &saveint, NULL);
+ (void) sigaction(SIGQUIT, &savequit, NULL);
+
+ /* Re-deliver the signal that interrupted the lock, if any. */
+ if (!ret && got_signal)
+ kill(getpid(), got_signal);
+
+ debug_return_bool(ret);
+}
+
+static bool
+timestamp_unlock_record(int fd, off_t pos, off_t len)
+{
+ debug_decl(timestamp_unlock_record, SUDOERS_DEBUG_AUTH)
+
+ if (pos >= 0 && lseek(fd, pos, SEEK_SET) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "unable to seek to %lld", (long long)pos);
+ debug_return_bool(false);
+ }
+ debug_return_bool(sudo_lock_region(fd, SUDO_UNLOCK, len));
+}
+
+/*
+ * Seek to the record's position and read it, locking as needed.
+ */
+static ssize_t
+ts_read(struct ts_cookie *cookie, struct timestamp_entry *entry)
+{
+ ssize_t nread = -1;
+ bool should_unlock = false;
+ debug_decl(ts_read, SUDOERS_DEBUG_AUTH)
+
+ /* If the record is not already locked, lock it now. */
+ if (!cookie->locked) {
+ if (!timestamp_lock_record(cookie->fd, cookie->pos, sizeof(*entry)))
+ goto done;
+ should_unlock = true;
+ }
+
+ /* Seek to the record position and read it. */
+#ifdef HAVE_PREAD
+ nread = pread(cookie->fd, entry, sizeof(*entry), cookie->pos);
+#else
+ if (lseek(cookie->fd, cookie->pos, SEEK_SET) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "unable to seek to %lld", (long long)cookie->pos);
+ goto done;
+ }
+ nread = read(cookie->fd, entry, sizeof(*entry));
+#endif
+ if (nread != sizeof(*entry)) {
+ /* short read, should not happen */
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "short read (%zd vs %zu), truncated time stamp file?",
+ nread, sizeof(*entry));
+ goto done;
+ }
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "read %zd byte record at %lld", nread, (long long)cookie->pos);
+
+done:
+ /* If the record was not locked initially, unlock it. */
+ if (should_unlock)
+ timestamp_unlock_record(cookie->fd, cookie->pos, sizeof(*entry));
+
+ debug_return_ssize_t(nread);
+}
+
+/*
+ * Lock a record in the time stamp file for exclusive access.
+ * If the record does not exist, it is created (as disabled).
+ */
+bool
+timestamp_lock(void *vcookie, struct passwd *pw)
+{
+ struct ts_cookie *cookie = vcookie;
+ struct timestamp_entry entry;
+ off_t lock_pos;
+ ssize_t nread;
+ debug_decl(timestamp_lock, SUDOERS_DEBUG_AUTH)
+
+ if (cookie == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "called with a NULL cookie!");
+ debug_return_bool(false);
+ }
+
+ /*
+ * Take a lock on the "write" record (the first record in the file).
+ * This will let us seek for the record or extend as needed
+ * without colliding with anyone else.
+ */
+ if (!timestamp_lock_record(cookie->fd, 0, sizeof(struct timestamp_entry)))
+ debug_return_bool(false);
+
+ /* Make sure the first record is of type TS_LOCKEXCL. */
+ memset(&entry, 0, sizeof(entry));
+ nread = read(cookie->fd, &entry, sizeof(entry));
+ if (nread == 0) {
+ /* New file, add TS_LOCKEXCL record. */
+ entry.version = TS_VERSION;
+ entry.size = sizeof(entry);
+ entry.type = TS_LOCKEXCL;
+ if (ts_write(cookie->fd, cookie->fname, &entry, -1) == -1)
+ debug_return_bool(false);
+ } else if (entry.type != TS_LOCKEXCL) {
+ /* Old sudo record, convert it to TS_LOCKEXCL. */
+ entry.type = TS_LOCKEXCL;
+ memset((char *)&entry + offsetof(struct timestamp_entry, type), 0,
+ nread - offsetof(struct timestamp_entry, type));
+ if (ts_write(cookie->fd, cookie->fname, &entry, 0) == -1)
+ debug_return_bool(false);
+ }
+ if (entry.size != sizeof(entry)) {
+ /* Reset position if the lock record has an unexpected size. */
+ if (lseek(cookie->fd, entry.size, SEEK_SET) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "unable to seek to %lld", (long long)entry.size);
+ debug_return_bool(false);
+ }
+ }
+
+ /* Search for a tty/ppid-based record or append a new one. */
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "searching for %s time stamp record",
+ def_timestamp_type == ppid ? "ppid" : "tty");
+ ts_init_key_nonglobal(&cookie->key, pw, TS_DISABLED);
+ if (ts_find_record(cookie->fd, &cookie->key, &entry)) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "found existing %s time stamp record",
+ def_timestamp_type == ppid ? "ppid" : "tty");
+ lock_pos = lseek(cookie->fd, 0, SEEK_CUR) - (off_t)entry.size;
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "appending new %s time stamp record",
+ def_timestamp_type == ppid ? "ppid" : "tty");
+ lock_pos = lseek(cookie->fd, 0, SEEK_CUR);
+ if (ts_write(cookie->fd, cookie->fname, &cookie->key, -1) == -1)
+ debug_return_bool(false);
+ }
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "%s time stamp position is %lld",
+ def_timestamp_type == ppid ? "ppid" : "tty", (long long)lock_pos);
+
+ if (def_timestamp_type == global) {
+ /*
+ * For global tickets we use a separate record lock that we
+ * cannot hold long-term since it is shared between all ttys.
+ */
+ cookie->locked = false;
+ cookie->key.type = TS_GLOBAL; /* find a global record */
+
+ if (lseek(cookie->fd, 0, SEEK_SET) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "unable to rewind fd");
+ debug_return_bool(false);
+ }
+ if (ts_find_record(cookie->fd, &cookie->key, &entry)) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "found existing global record");
+ cookie->pos = lseek(cookie->fd, 0, SEEK_CUR) - (off_t)entry.size;
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "appending new global record");
+ cookie->pos = lseek(cookie->fd, 0, SEEK_CUR);
+ if (ts_write(cookie->fd, cookie->fname, &cookie->key, -1) == -1)
+ debug_return_bool(false);
+ }
+ } else {
+ /* For tty/ppid tickets the tty lock is the same as the record lock. */
+ cookie->pos = lock_pos;
+ cookie->locked = true;
+ }
+
+ /* Unlock the TS_LOCKEXCL record. */
+ timestamp_unlock_record(cookie->fd, 0, sizeof(struct timestamp_entry));
+
+ /* Lock the per-tty record (may sleep). */
+ if (!timestamp_lock_record(cookie->fd, lock_pos, sizeof(struct timestamp_entry)))
+ debug_return_bool(false);
+
+ debug_return_bool(true);
+}
+
+void
+timestamp_close(void *vcookie)
+{
+ struct ts_cookie *cookie = vcookie;
+ debug_decl(timestamp_close, SUDOERS_DEBUG_AUTH)
+
+ if (cookie != NULL) {
+ close(cookie->fd);
+ free(cookie->fname);
+ free(cookie);
+ }
+
+ debug_return;
+}
+
+/*
+ * Check the time stamp file and directory and return their status.
+ * Called with the file position before the locked record to read.
+ * Returns one of TS_CURRENT, TS_OLD, TS_MISSING, TS_ERROR, TS_FATAL.
+ * Fills in fdp with an open file descriptor positioned at the
+ * appropriate (and locked) record.
+ */
+int
+timestamp_status(void *vcookie, struct passwd *pw)
+{
+ struct ts_cookie *cookie = vcookie;
+ struct timestamp_entry entry;
+ struct timespec diff, now;
+ int status = TS_ERROR; /* assume the worst */
+ ssize_t nread;
+ debug_decl(timestamp_status, SUDOERS_DEBUG_AUTH)
+
+ /* Zero timeout means don't use time stamp files. */
+ if (!sudo_timespecisset(&def_timestamp_timeout)) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "timestamps disabled");
+ status = TS_OLD;
+ goto done;
+ }
+ if (cookie == NULL || cookie->pos < 0) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "NULL cookie or invalid position");
+ status = TS_OLD;
+ goto done;
+ }
+
+#ifdef TIOCCHKVERAUTH
+ if (def_timestamp_type == kernel) {
+ int fd = open(_PATH_TTY, O_RDWR);
+ if (fd != -1) {
+ if (ioctl(fd, TIOCCHKVERAUTH) == 0)
+ status = TS_CURRENT;
+ else
+ status = TS_OLD;
+ close(fd);
+ goto done;
+ }
+ }
+#endif
+
+ /* Read the record at the correct position. */
+ if ((nread = ts_read(cookie, &entry)) != sizeof(entry))
+ goto done;
+
+ /* Make sure what we read matched the expected record. */
+ if (entry.version != TS_VERSION || entry.size != nread) {
+ /* do something else? */
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "invalid time stamp file @ %lld", (long long)cookie->pos);
+ status = TS_OLD;
+ goto done;
+ }
+
+ if (ISSET(entry.flags, TS_DISABLED)) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "time stamp record disabled");
+ status = TS_OLD; /* disabled via sudo -k */
+ goto done;
+ }
+
+ if (entry.type != TS_GLOBAL && entry.sid != cookie->sid) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "time stamp record sid mismatch");
+ status = TS_OLD; /* belongs to different session */
+ goto done;
+ }
+
+ /* Negative timeouts only expire manually (sudo -k). */
+ sudo_timespecclear(&diff);
+ if (sudo_timespeccmp(&def_timestamp_timeout, &diff, <)) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "time stamp record does not expire");
+ status = TS_CURRENT;
+ goto done;
+ }
+
+ /* Compare stored time stamp with current time. */
+ if (sudo_gettime_mono(&now) == -1) {
+ log_warning(0, N_("unable to read the clock"));
+ status = TS_ERROR;
+ goto done;
+ }
+ sudo_timespecsub(&now, &entry.ts, &diff);
+ if (sudo_timespeccmp(&diff, &def_timestamp_timeout, <)) {
+ status = TS_CURRENT;
+#if defined(CLOCK_MONOTONIC) || defined(__MACH__)
+ /* A monotonic clock should never run backwards. */
+ if (diff.tv_sec < 0) {
+ log_warningx(SLOG_SEND_MAIL,
+ N_("ignoring time stamp from the future"));
+ status = TS_OLD;
+ SET(entry.flags, TS_DISABLED);
+ (void)ts_write(cookie->fd, cookie->fname, &entry, cookie->pos);
+ }
+#else
+ /*
+ * Check for bogus (future) time in the stampfile.
+ * If diff / 2 > timeout, someone has been fooling with the clock.
+ */
+ sudo_timespecsub(&entry.ts, &now, &diff);
+ diff.tv_nsec /= 2;
+ if (diff.tv_sec & 1)
+ diff.tv_nsec += 500000000;
+ diff.tv_sec /= 2;
+ while (diff.tv_nsec >= 1000000000) {
+ diff.tv_sec++;
+ diff.tv_nsec -= 1000000000;
+ }
+
+ if (sudo_timespeccmp(&diff, &def_timestamp_timeout, >)) {
+ time_t tv_sec = (time_t)entry.ts.tv_sec;
+ log_warningx(SLOG_SEND_MAIL,
+ N_("time stamp too far in the future: %20.20s"),
+ 4 + ctime(&tv_sec));
+ status = TS_OLD;
+ SET(entry.flags, TS_DISABLED);
+ (void)ts_write(cookie->fd, cookie->fname, &entry, cookie->pos);
+ }
+#endif /* CLOCK_MONOTONIC */
+ } else {
+ status = TS_OLD;
+ }
+
+done:
+ debug_return_int(status);
+}
+
+/*
+ * Update the time on the time stamp file/dir or create it if necessary.
+ * Returns true on success, false on failure or -1 on setuid failure.
+ */
+bool
+timestamp_update(void *vcookie, struct passwd *pw)
+{
+ struct ts_cookie *cookie = vcookie;
+ int ret = false;
+ debug_decl(timestamp_update, SUDOERS_DEBUG_AUTH)
+
+ /* Zero timeout means don't use time stamp files. */
+ if (!sudo_timespecisset(&def_timestamp_timeout)) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "timestamps disabled");
+ goto done;
+ }
+ if (cookie == NULL || cookie->pos < 0) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "NULL cookie or invalid position");
+ goto done;
+ }
+
+#ifdef TIOCSETVERAUTH
+ if (def_timestamp_type == kernel) {
+ int fd = open(_PATH_TTY, O_RDWR);
+ if (fd != -1) {
+ int secs = def_timestamp_timeout.tv_sec;
+ if (secs > 0) {
+ if (secs > 3600)
+ secs = 3600; /* OpenBSD limitation */
+ if (ioctl(fd, TIOCSETVERAUTH, &secs) != 0)
+ sudo_warn("TIOCSETVERAUTH");
+ }
+ close(fd);
+ goto done;
+ }
+ }
+#endif
+
+ /* Update timestamp in key and enable it. */
+ CLR(cookie->key.flags, TS_DISABLED);
+ if (sudo_gettime_mono(&cookie->key.ts) == -1) {
+ log_warning(0, N_("unable to read the clock"));
+ goto done;
+ }
+
+ /* Write out the locked record. */
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "writing %zu byte record at %lld", sizeof(cookie->key),
+ (long long)cookie->pos);
+ if (ts_write(cookie->fd, cookie->fname, &cookie->key, cookie->pos) != -1)
+ ret = true;
+
+done:
+ debug_return_int(ret);
+}
+
+/*
+ * Remove the timestamp entry or file if unlink_it is set.
+ * Returns true on success, false on failure or -1 on setuid failure.
+ * A missing timestamp entry is not considered an error.
+ */
+int
+timestamp_remove(bool unlink_it)
+{
+ struct timestamp_entry key, entry;
+ int fd = -1, ret = true;
+ char *fname = NULL;
+ debug_decl(timestamp_remove, SUDOERS_DEBUG_AUTH)
+
+#ifdef TIOCCLRVERAUTH
+ if (def_timestamp_type == kernel) {
+ fd = open(_PATH_TTY, O_RDWR);
+ if (fd != -1) {
+ ioctl(fd, TIOCCLRVERAUTH);
+ goto done;
+ }
+ }
+#endif
+
+ if (asprintf(&fname, "%s/%s", def_timestampdir, user_name) == -1) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ ret = -1;
+ goto done;
+ }
+
+ /* For "sudo -K" simply unlink the time stamp file. */
+ if (unlink_it) {
+ ret = unlink(fname) ? -1 : true;
+ goto done;
+ }
+
+ /* Open time stamp file and lock it for exclusive access. */
+ fd = ts_open(fname, O_RDWR);
+ switch (fd) {
+ case TIMESTAMP_OPEN_ERROR:
+ if (errno != ENOENT)
+ ret = false;
+ goto done;
+ case TIMESTAMP_PERM_ERROR:
+ /* Already logged set_perms/restore_perms error. */
+ ret = -1;
+ goto done;
+ }
+ /* Lock first record to gain exclusive access. */
+ if (!timestamp_lock_record(fd, -1, sizeof(struct timestamp_entry))) {
+ sudo_warn(U_("unable to lock time stamp file %s"), fname);
+ ret = -1;
+ goto done;
+ }
+
+ /*
+ * Find matching entries and invalidate them.
+ */
+ ts_init_key(&key, NULL, 0, def_timestamp_type);
+ while (ts_find_record(fd, &key, &entry)) {
+ /* Back up and disable the entry. */
+ if (!ISSET(entry.flags, TS_DISABLED)) {
+ SET(entry.flags, TS_DISABLED);
+ if (lseek(fd, 0 - (off_t)sizeof(entry), SEEK_CUR) != -1) {
+ if (ts_write(fd, fname, &entry, -1) == -1)
+ ret = false;
+ }
+ }
+ }
+
+done:
+ if (fd != -1)
+ close(fd);
+ free(fname);
+ debug_return_int(ret);
+}
+
+/*
+ * Returns true if the user has already been lectured.
+ */
+bool
+already_lectured(int unused)
+{
+ char status_file[PATH_MAX];
+ struct stat sb;
+ int len;
+ debug_decl(already_lectured, SUDOERS_DEBUG_AUTH)
+
+ if (ts_secure_dir(def_lecture_status_dir, false, true)) {
+ len = snprintf(status_file, sizeof(status_file), "%s/%s",
+ def_lecture_status_dir, user_name);
+ if (len > 0 && (size_t)len < sizeof(status_file)) {
+ debug_return_bool(stat(status_file, &sb) == 0);
+ }
+ log_warningx(SLOG_SEND_MAIL, N_("lecture status path too long: %s/%s"),
+ def_lecture_status_dir, user_name);
+ }
+ debug_return_bool(false);
+}
+
+/*
+ * Create the lecture status file.
+ * Returns true on success, false on failure or -1 on setuid failure.
+ */
+int
+set_lectured(void)
+{
+ char lecture_status[PATH_MAX];
+ int len, fd, ret = false;
+ debug_decl(set_lectured, SUDOERS_DEBUG_AUTH)
+
+ len = snprintf(lecture_status, sizeof(lecture_status), "%s/%s",
+ def_lecture_status_dir, user_name);
+ if (len <= 0 || (size_t)len >= sizeof(lecture_status)) {
+ log_warningx(SLOG_SEND_MAIL, N_("lecture status path too long: %s/%s"),
+ def_lecture_status_dir, user_name);
+ goto done;
+ }
+
+ /* Sanity check lecture dir and create if missing. */
+ if (!ts_secure_dir(def_lecture_status_dir, true, false))
+ goto done;
+
+ /* Create lecture file. */
+ fd = ts_open(lecture_status, O_WRONLY|O_CREAT|O_EXCL);
+ switch (fd) {
+ case TIMESTAMP_OPEN_ERROR:
+ /* Failed to open, not a fatal error. */
+ break;
+ case TIMESTAMP_PERM_ERROR:
+ /* Already logged set_perms/restore_perms error. */
+ ret = -1;
+ break;
+ default:
+ /* Success. */
+ close(fd);
+ ret = true;
+ break;
+ }
+
+done:
+ debug_return_int(ret);
+}
diff --git a/plugins/sudoers/timestr.c b/plugins/sudoers/timestr.c
new file mode 100644
index 0000000..d94d09c
--- /dev/null
+++ b/plugins/sudoers/timestr.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1999, 2009-2011, 2013-2015, 2017
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "sudo_compat.h"
+#include "sudo_debug.h"
+#include "parse.h"
+
+/*
+ * Return a static buffer with the current date + time.
+ */
+char *
+get_timestr(time_t tstamp, int log_year)
+{
+ static char buf[128];
+ struct tm *timeptr;
+
+ if ((timeptr = localtime(&tstamp)) != NULL) {
+ /* strftime() does not guarantee to NUL-terminate so we must check. */
+ buf[sizeof(buf) - 1] = '\0';
+ if (strftime(buf, sizeof(buf), log_year ? "%h %e %T %Y" : "%h %e %T",
+ timeptr) != 0 && buf[sizeof(buf) - 1] == '\0')
+ return buf;
+ }
+ return NULL;
+}
diff --git a/plugins/sudoers/toke.c b/plugins/sudoers/toke.c
new file mode 100644
index 0000000..d0dd5e3
--- /dev/null
+++ b/plugins/sudoers/toke.c
@@ -0,0 +1,4665 @@
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#line 3 "toke.c"
+
+#define YY_INT_ALIGNED short int
+
+/* $OpenBSD: flex.skl,v 1.16 2017/05/02 19:16:19 millert Exp $ */
+
+/* A lexical scanner generated by flex */
+
+#define yy_create_buffer sudoers_create_buffer
+#define yy_delete_buffer sudoers_delete_buffer
+#define yy_flex_debug sudoers_flex_debug
+#define yy_init_buffer sudoers_init_buffer
+#define yy_flush_buffer sudoers_flush_buffer
+#define yy_load_buffer_state sudoers_load_buffer_state
+#define yy_switch_to_buffer sudoers_switch_to_buffer
+#define yyin sudoersin
+#define yyleng sudoersleng
+#define yylex sudoerslex
+#define yylineno sudoerslineno
+#define yyout sudoersout
+#define yyrestart sudoersrestart
+#define yytext sudoerstext
+#define yywrap sudoerswrap
+#define yyalloc sudoersalloc
+#define yyrealloc sudoersrealloc
+#define yyfree sudoersfree
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 39
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* $OpenBSD: flexint.h,v 1.1 2015/11/19 19:43:40 tedu Exp $ */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE sudoersrestart(sudoersin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t sudoersleng;
+
+extern FILE *sudoersin, *sudoersout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+ #define YY_LINENO_REWIND_TO(ptr)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up sudoerstext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up sudoerstext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ yy_size_t yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via sudoersrestart()), so that the user can continue scanning by
+ * just pointing sudoersin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when sudoerstext is formed. */
+static char yy_hold_char;
+static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */
+yy_size_t sudoersleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow sudoerswrap()'s to do buffer switches
+ * instead of setting up a fresh sudoersin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void sudoersrestart (FILE *input_file );
+void sudoers_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE sudoers_create_buffer (FILE *file,int size );
+void sudoers_delete_buffer (YY_BUFFER_STATE b );
+void sudoers_flush_buffer (YY_BUFFER_STATE b );
+void sudoerspush_buffer_state (YY_BUFFER_STATE new_buffer );
+void sudoerspop_buffer_state (void );
+
+static void sudoersensure_buffer_stack (void );
+static void sudoers_load_buffer_state (void );
+static void sudoers_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER sudoers_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE sudoers_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE sudoers_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE sudoers_scan_bytes (yyconst char *bytes,yy_size_t len );
+
+void *sudoersalloc (yy_size_t );
+void *sudoersrealloc (void *,yy_size_t );
+void sudoersfree (void * );
+
+#define yy_new_buffer sudoers_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ sudoersensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ sudoers_create_buffer(sudoersin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ sudoersensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ sudoers_create_buffer(sudoersin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define sudoerswrap() 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *sudoersin = (FILE *) 0, *sudoersout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int sudoerslineno;
+
+int sudoerslineno = 1;
+
+extern char *sudoerstext;
+#define yytext_ptr sudoerstext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up sudoerstext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ sudoersleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 74
+#define YY_END_OF_BUFFER 75
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[882] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 75, 62, 70, 69, 68, 61,
+ 72, 38, 63, 64, 38, 65, 62, 62, 62, 62,
+ 67, 66, 73, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 53, 53, 73, 62, 62, 70, 72,
+ 53, 53, 53, 53, 53, 2, 73, 1, 62, 53,
+ 53, 53, 62, 17, 16, 17, 16, 16, 73, 72,
+ 73, 3, 9, 8, 9, 4, 9, 5, 73, 13,
+ 13, 13, 11, 12, 73, 19, 19, 18, 18, 18,
+ 19, 18, 18, 18, 18, 19, 19, 19, 19, 19,
+
+ 19, 18, 19, 19, 62, 0, 70, 68, 72, 72,
+ 0, 62, 40, 0, 38, 0, 39, 0, 60, 60,
+ 0, 62, 62, 0, 62, 62, 62, 62, 0, 43,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 53, 53, 62, 71, 62, 62, 70,
+ 0, 0, 0, 0, 0, 72, 62, 62, 62, 62,
+ 62, 2, 1, 0, 1, 54, 54, 0, 53, 62,
+ 17, 17, 15, 14, 15, 0, 0, 3, 9, 0,
+ 6, 7, 9, 9, 13, 0, 13, 13, 0, 10,
+ 40, 0, 0, 39, 19, 19, 0, 19, 0, 0,
+
+ 18, 18, 18, 18, 18, 18, 19, 19, 53, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 72, 72,
+ 0, 40, 62, 62, 62, 62, 62, 0, 0, 43,
+ 43, 53, 45, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 53, 62, 62, 0, 0, 0, 0, 0, 72, 62,
+ 62, 62, 62, 62, 0, 62, 10, 0, 0, 0,
+ 18, 18, 18, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 72, 62,
+ 62, 62, 62, 62, 62, 0, 44, 44, 44, 0,
+
+ 0, 43, 43, 43, 43, 43, 43, 43, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 53, 49, 53, 53, 50, 62, 62,
+ 62, 62, 0, 0, 0, 0, 0, 72, 62, 62,
+ 62, 62, 0, 0, 0, 0, 0, 18, 18, 19,
+ 19, 53, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 62, 62, 62, 0, 0,
+ 44, 44, 44, 0, 43, 43, 0, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 0, 27,
+ 53, 53, 53, 53, 0, 34, 53, 53, 53, 53,
+
+ 53, 53, 53, 53, 53, 51, 53, 53, 62, 62,
+ 62, 62, 62, 0, 0, 0, 72, 62, 62, 62,
+ 0, 0, 0, 18, 18, 19, 53, 53, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 62, 62, 62, 62, 62, 0, 44, 0, 43,
+ 43, 43, 0, 0, 0, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 55, 56, 57, 58, 62, 0, 0,
+ 72, 62, 62, 62, 0, 0, 0, 0, 0, 19,
+
+ 53, 53, 19, 19, 53, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 41, 41, 41, 0, 0,
+ 43, 43, 43, 43, 43, 43, 43, 0, 0, 0,
+ 0, 0, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 0, 36, 53, 53,
+ 53, 0, 26, 53, 53, 53, 0, 35, 53, 53,
+ 53, 53, 0, 25, 0, 28, 46, 62, 0, 0,
+ 72, 62, 62, 62, 41, 41, 41, 53, 53, 19,
+ 53, 53, 19, 19, 19, 62, 41, 41, 41, 41,
+ 0, 43, 0, 43, 43, 43, 43, 43, 43, 43,
+
+ 43, 43, 43, 43, 0, 0, 0, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 53, 53, 53, 53, 53, 53, 53, 53, 48, 53,
+ 59, 0, 0, 72, 62, 22, 54, 0, 41, 41,
+ 41, 41, 53, 53, 19, 53, 53, 19, 19, 19,
+ 42, 42, 42, 42, 43, 0, 0, 0, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 0, 0, 0, 0, 0, 43, 43, 43, 43,
+ 43, 43, 43, 43, 53, 53, 53, 0, 37, 53,
+ 53, 0, 24, 0, 29, 47, 0, 22, 72, 72,
+
+ 62, 0, 62, 42, 42, 42, 42, 53, 53, 53,
+ 53, 62, 62, 42, 42, 42, 42, 0, 0, 0,
+ 0, 0, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 52, 0, 32, 53, 53, 53, 0, 72,
+ 72, 20, 72, 23, 22, 0, 0, 0, 0, 0,
+ 22, 0, 0, 0, 42, 42, 42, 42, 53, 53,
+ 53, 62, 62, 62, 0, 0, 0, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 0, 30, 53, 53, 23,
+
+ 72, 0, 22, 0, 0, 0, 53, 53, 62, 62,
+ 62, 62, 62, 0, 0, 0, 0, 0, 43, 43,
+ 43, 43, 43, 43, 43, 43, 0, 33, 53, 72,
+ 0, 0, 0, 0, 0, 53, 62, 62, 62, 43,
+ 43, 43, 43, 43, 43, 0, 31, 72, 72, 21,
+ 0, 0, 0, 62, 62, 62, 62, 62, 43, 43,
+ 43, 43, 43, 0, 0, 0, 0, 0, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 5, 6, 1, 7, 1, 1, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 1, 1,
+ 27, 28, 10, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 39, 40, 41, 42, 43, 44,
+ 39, 45, 46, 47, 48, 49, 50, 51, 52, 39,
+ 10, 53, 10, 1, 54, 1, 55, 56, 57, 58,
+
+ 59, 60, 61, 62, 63, 61, 61, 64, 65, 66,
+ 67, 61, 61, 68, 69, 70, 71, 61, 61, 61,
+ 61, 61, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[72] =
+ { 0,
+ 1, 2, 3, 4, 5, 6, 1, 7, 7, 1,
+ 8, 9, 10, 11, 12, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 14, 15, 7, 1, 16,
+ 16, 16, 16, 16, 16, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 18, 19, 20, 20, 20, 20, 20, 20,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21
+ } ;
+
+static yyconst flex_int16_t yy_base[999] =
+ { 0,
+ 0, 70, 72, 80, 126, 131, 183, 253, 161, 205,
+ 86, 94, 324, 0, 4976, 4918, 4967, 5585, 4964, 5585,
+ 393, 87, 5585, 5585, 4914, 5585, 172, 405, 174, 185,
+ 4940, 5585, 5585, 465, 4925, 43, 37, 521, 62, 4934,
+ 4913, 76, 4912, 4916, 71, 580, 595, 83, 228, 618,
+ 39, 91, 4881, 30, 4878, 73, 4933, 4943, 439, 4901,
+ 4900, 4895, 89, 0, 5585, 4919, 5585, 0, 620, 679,
+ 108, 0, 4861, 5585, 117, 5585, 129, 5585, 159, 4855,
+ 106, 122, 5585, 166, 209, 656, 710, 754, 261, 203,
+ 812, 862, 4865, 223, 186, 918, 4861, 4872, 4858, 4866,
+
+ 4858, 965, 0, 84, 4834, 650, 4882, 4877, 4877, 5585,
+ 271, 546, 619, 4859, 622, 723, 4818, 848, 952, 4813,
+ 989, 1002, 1040, 4837, 4846, 577, 724, 250, 4833, 249,
+ 1085, 1130, 4811, 4816, 4805, 4801, 4803, 4800, 994, 4789,
+ 4796, 4793, 4784, 4785, 4781, 396, 5585, 178, 125, 1000,
+ 4759, 4763, 4751, 4746, 4747, 231, 354, 386, 159, 379,
+ 245, 439, 4812, 736, 4803, 1038, 4751, 1165, 1042, 247,
+ 0, 4795, 299, 5585, 5585, 946, 399, 0, 4743, 659,
+ 5585, 5585, 4740, 401, 4739, 4767, 403, 404, 431, 4739,
+ 627, 668, 1192, 4683, 1198, 0, 1227, 1255, 1211, 1105,
+
+ 1294, 4719, 1224, 1254, 845, 1344, 1400, 4690, 0, 4695,
+ 4680, 4679, 4675, 1246, 4666, 4664, 4655, 4651, 4705, 4697,
+ 1277, 1314, 1447, 1420, 990, 1487, 4680, 4666, 1532, 427,
+ 1578, 1623, 0, 4658, 4649, 4650, 4633, 4629, 4616, 4594,
+ 4588, 4598, 4597, 4591, 438, 4578, 4570, 4581, 4576, 4573,
+ 4570, 669, 160, 4537, 4535, 4525, 4523, 4527, 546, 397,
+ 4528, 504, 418, 406, 1471, 505, 4580, 4565, 4564, 1670,
+ 1680, 4563, 1725, 0, 4543, 4526, 4511, 4520, 4506, 4511,
+ 4510, 4515, 4514, 4505, 4491, 4502, 687, 4468, 4531, 1770,
+ 534, 0, 0, 1027, 246, 4507, 4506, 1808, 633, 4498,
+
+ 4492, 653, 1468, 1821, 1507, 1115, 1867, 1914, 4490, 603,
+ 4471, 4466, 646, 665, 4478, 4471, 4446, 4443, 4430, 4427,
+ 4438, 4438, 4421, 4424, 0, 4427, 4339, 0, 837, 551,
+ 574, 654, 4323, 4325, 4309, 4323, 4309, 763, 506, 1041,
+ 424, 677, 1552, 4362, 4361, 4360, 1162, 1924, 1969, 781,
+ 4330, 691, 889, 4338, 4331, 4334, 4331, 4322, 4320, 4316,
+ 4323, 830, 4340, 4346, 4303, 2016, 2028, 2040, 4335, 4334,
+ 2050, 4334, 4332, 4331, 4330, 977, 1598, 1054, 1643, 1064,
+ 2063, 0, 1702, 2110, 1745, 1324, 2156, 2203, 970, 5585,
+ 4294, 4299, 4300, 4293, 1010, 5585, 4308, 4299, 4284, 4297,
+
+ 4290, 4301, 4287, 4298, 4299, 0, 4282, 4282, 640, 786,
+ 1034, 986, 709, 4275, 4257, 4237, 641, 520, 1028, 901,
+ 4291, 4289, 2215, 2225, 4276, 4251, 4226, 4143, 4147, 4127,
+ 4101, 4083, 4065, 4065, 4054, 4026, 4043, 4029, 4019, 4009,
+ 3961, 2270, 1000, 2310, 2322, 1655, 3986, 3954, 3941, 3929,
+ 2332, 1142, 3929, 3917, 2379, 1169, 1188, 1192, 1780, 1195,
+ 2391, 0, 1792, 2438, 1841, 1430, 2484, 2531, 2556, 1259,
+ 1450, 1111, 1112, 1224, 1868, 1196, 1452, 1473, 1232, 1535,
+ 1320, 1321, 1427, 3843, 3835, 3828, 3790, 663, 3806, 3753,
+ 394, 1843, 960, 796, 1896, 3790, 3777, 3774, 1565, 1346,
+
+ 3707, 3697, 1371, 3688, 1046, 1512, 3680, 3685, 1514, 1533,
+ 0, 0, 0, 0, 3660, 2613, 1944, 1608, 3651, 3634,
+ 3626, 1989, 2653, 2083, 1713, 2698, 2745, 2130, 3629, 3610,
+ 3603, 1757, 2005, 2168, 2170, 2178, 2245, 2183, 2757, 0,
+ 2282, 2804, 2293, 1954, 2850, 2897, 1534, 5585, 2922, 907,
+ 1128, 1604, 5585, 1178, 1265, 1857, 1605, 5585, 1501, 2157,
+ 1632, 1734, 1683, 5585, 1725, 5585, 3561, 1235, 3534, 3502,
+ 1156, 2147, 1426, 1236, 3545, 3520, 2979, 3452, 3432, 2994,
+ 3433, 3412, 1463, 791, 3381, 3050, 1305, 3089, 0, 1792,
+ 3378, 3377, 2352, 2029, 2411, 2204, 3129, 0, 2460, 3142,
+
+ 2504, 2093, 3187, 3234, 3375, 3345, 3246, 2368, 2520, 2625,
+ 2627, 3319, 2629, 3258, 0, 2642, 3305, 2673, 2140, 3352,
+ 3377, 1433, 898, 1927, 1823, 1603, 2089, 2090, 3263, 2270,
+ 3256, 3242, 3216, 1817, 1671, 2414, 3171, 2718, 3200, 3165,
+ 3070, 2256, 3030, 2974, 3447, 2881, 2850, 1847, 1848, 0,
+ 3505, 2777, 2824, 1736, 2852, 2844, 2836, 3545, 2805, 2311,
+ 2461, 2870, 2638, 3557, 0, 3062, 3570, 3073, 2629, 3615,
+ 3662, 3099, 2797, 2738, 2734, 2685, 2639, 2734, 2886, 985,
+ 1342, 3674, 0, 2789, 1822, 2439, 1861, 1993, 5585, 1379,
+ 1860, 1995, 5585, 1996, 5585, 2695, 2670, 2356, 1819, 1478,
+
+ 2252, 2849, 3125, 2686, 2570, 3686, 2185, 2252, 2464, 2511,
+ 3100, 3696, 1963, 3736, 0, 2356, 1964, 3116, 2554, 2547,
+ 2498, 3165, 2459, 2419, 2994, 3073, 3171, 3143, 3776, 0,
+ 3209, 3789, 3278, 3220, 3834, 3881, 2424, 2371, 3892, 3316,
+ 2264, 1936, 2204, 2418, 5585, 2534, 2115, 2159, 2136, 2160,
+ 2249, 5585, 2416, 2084, 3302, 3352, 3532, 3544, 2104, 2922,
+ 2037, 3720, 3327, 2009, 1982, 1938, 3436, 1889, 2536, 2830,
+ 2831, 3904, 3916, 3928, 1855, 1834, 3940, 1699, 1681, 3235,
+ 3327, 3590, 3353, 3952, 0, 3637, 3965, 3717, 3523, 4012,
+ 1636, 1617, 1590, 3536, 1565, 2724, 5585, 2850, 2273, 5585,
+
+ 2304, 3746, 3756, 1519, 1448, 4024, 2725, 3285, 4036, 2477,
+ 4048, 4060, 3648, 3809, 1307, 1277, 1243, 3602, 1204, 1198,
+ 3506, 1161, 1125, 4072, 0, 2509, 2901, 5585, 3284, 2435,
+ 3854, 1079, 1071, 1030, 3821, 2902, 4084, 4096, 4108, 3985,
+ 4118, 4128, 1005, 0, 768, 3021, 5585, 730, 2480, 5585,
+ 596, 576, 4140, 4152, 2693, 4164, 4176, 3866, 5585, 4186,
+ 4196, 3766, 5585, 4206, 456, 289, 134, 3997, 4216, 4254,
+ 4292, 4226, 4236, 4264, 28, 4330, 4246, 5585, 4302, 4274,
+ 5585, 4383, 4404, 4425, 4446, 4467, 4488, 4509, 4530, 4551,
+ 4560, 2005, 4580, 4601, 2661, 4622, 4643, 4664, 4685, 4706,
+
+ 4727, 4748, 4769, 2479, 4790, 4799, 4807, 4816, 4836, 4857,
+ 4878, 2765, 4899, 4920, 4941, 4962, 4983, 4992, 5011, 5020,
+ 5029, 2348, 2734, 5037, 5045, 5053, 5062, 5070, 5077, 5085,
+ 5093, 5102, 5112, 2885, 2913, 5120, 5128, 5136, 3073, 3203,
+ 5145, 5155, 5175, 3220, 5184, 5192, 3221, 5201, 5211, 5231,
+ 2552, 2994, 5240, 5252, 5261, 5271, 3369, 3370, 5280, 5290,
+ 5299, 5319, 3088, 5328, 5340, 3448, 3520, 5349, 5359, 3534,
+ 5368, 5378, 5398, 5419, 5440, 3631, 3648, 5460, 3732, 5467,
+ 5477, 3158, 3373, 5486, 3115, 5506, 3805, 3849, 5515, 5525,
+ 3850, 3980, 5533, 5543, 5563, 4284, 3981, 4285
+
+ } ;
+
+static yyconst flex_int16_t yy_def[999] =
+ { 0,
+ 881, 1, 1, 1, 882, 882, 883, 883, 884, 884,
+ 885, 885, 881, 13, 881, 886, 881, 881, 881, 881,
+ 887, 888, 881, 881, 889, 881, 890, 886, 28, 28,
+ 891, 881, 881, 881, 34, 34, 34, 34, 38, 38,
+ 38, 38, 38, 38, 38, 886, 28, 886, 881, 887,
+ 34, 34, 38, 38, 38, 881, 892, 881, 893, 38,
+ 38, 38, 886, 894, 881, 894, 881, 894, 881, 887,
+ 881, 895, 896, 881, 896, 881, 896, 881, 897, 898,
+ 898, 898, 881, 881, 899, 900, 901, 881, 88, 88,
+ 88, 881, 92, 92, 92, 92, 96, 96, 96, 96,
+
+ 96, 88, 91, 91, 886, 886, 881, 881, 902, 881,
+ 903, 881, 888, 904, 899, 888, 889, 889, 890, 905,
+ 886, 886, 28, 906, 123, 123, 123, 123, 907, 908,
+ 38, 131, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 886, 881, 886, 886, 881,
+ 881, 881, 881, 881, 881, 902, 886, 123, 886, 886,
+ 886, 881, 881, 881, 881, 909, 910, 886, 132, 886,
+ 911, 911, 881, 881, 881, 903, 881, 912, 913, 913,
+ 881, 881, 913, 913, 914, 881, 914, 914, 881, 881,
+ 899, 899, 899, 915, 916, 91, 915, 917, 881, 881,
+
+ 88, 201, 201, 201, 201, 881, 206, 207, 918, 207,
+ 207, 207, 207, 207, 207, 207, 91, 91, 902, 919,
+ 881, 881, 886, 223, 223, 123, 226, 920, 881, 921,
+ 881, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 886, 886, 881, 881, 881, 881, 881, 902, 886,
+ 226, 886, 886, 886, 881, 886, 881, 922, 923, 881,
+ 91, 271, 206, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 91, 91, 919, 886,
+ 886, 223, 223, 223, 886, 924, 925, 925, 298, 926,
+
+ 925, 927, 231, 881, 304, 304, 881, 304, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 886, 886,
+ 886, 886, 881, 881, 881, 881, 881, 902, 886, 886,
+ 886, 886, 881, 881, 922, 922, 881, 271, 206, 207,
+ 207, 928, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 91, 91, 91, 91, 223, 223, 223, 881, 929,
+ 929, 371, 929, 930, 931, 932, 881, 933, 307, 933,
+ 881, 381, 933, 881, 384, 384, 881, 384, 881, 881,
+ 132, 132, 132, 132, 881, 881, 132, 132, 132, 132,
+
+ 132, 132, 132, 132, 132, 132, 132, 132, 886, 886,
+ 886, 886, 886, 881, 881, 881, 902, 886, 886, 886,
+ 934, 935, 881, 91, 349, 207, 928, 928, 207, 207,
+ 207, 207, 207, 207, 207, 207, 91, 91, 91, 91,
+ 91, 886, 886, 223, 223, 886, 936, 936, 937, 938,
+ 881, 881, 939, 940, 881, 941, 941, 942, 387, 942,
+ 881, 461, 942, 881, 464, 464, 881, 464, 881, 469,
+ 469, 469, 469, 469, 469, 469, 469, 469, 469, 469,
+ 469, 469, 469, 886, 886, 886, 886, 886, 881, 881,
+ 943, 886, 886, 886, 881, 881, 944, 944, 881, 207,
+
+ 928, 928, 207, 207, 928, 207, 207, 207, 207, 207,
+ 91, 91, 91, 91, 91, 886, 516, 516, 881, 945,
+ 946, 451, 881, 523, 523, 881, 523, 881, 881, 947,
+ 947, 881, 881, 948, 948, 949, 467, 949, 881, 539,
+ 949, 881, 542, 542, 881, 542, 881, 881, 881, 549,
+ 549, 881, 881, 549, 549, 549, 881, 881, 549, 549,
+ 549, 549, 881, 881, 881, 881, 549, 886, 881, 881,
+ 950, 886, 886, 886, 951, 952, 881, 953, 953, 881,
+ 953, 953, 580, 580, 954, 886, 886, 886, 588, 588,
+ 881, 955, 881, 956, 526, 956, 956, 597, 956, 881,
+
+ 600, 600, 881, 600, 957, 958, 881, 881, 959, 959,
+ 960, 961, 960, 881, 614, 960, 881, 617, 617, 617,
+ 881, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 886, 881, 881, 962, 886, 886, 886, 881, 881, 963,
+ 963, 881, 964, 964, 881, 964, 964, 645, 645, 965,
+ 886, 651, 651, 651, 881, 966, 967, 881, 968, 968,
+ 969, 603, 969, 969, 664, 969, 881, 667, 667, 881,
+ 667, 881, 881, 970, 970, 881, 881, 971, 971, 972,
+ 972, 972, 682, 972, 621, 621, 621, 881, 881, 621,
+ 621, 881, 881, 881, 881, 621, 881, 881, 973, 962,
+
+ 886, 974, 975, 976, 977, 881, 976, 978, 978, 978,
+ 978, 886, 886, 886, 714, 714, 886, 881, 881, 979,
+ 979, 881, 881, 980, 980, 981, 670, 981, 981, 729,
+ 981, 881, 732, 732, 881, 732, 982, 983, 881, 881,
+ 984, 984, 621, 881, 881, 621, 621, 621, 881, 973,
+ 973, 881, 962, 886, 974, 974, 974, 974, 985, 974,
+ 986, 986, 881, 881, 976, 976, 881, 881, 978, 978,
+ 978, 714, 714, 714, 987, 988, 881, 881, 989, 989,
+ 990, 735, 990, 990, 784, 990, 881, 787, 787, 787,
+ 881, 982, 982, 881, 881, 881, 881, 621, 621, 881,
+
+ 962, 881, 881, 991, 992, 881, 978, 978, 714, 886,
+ 714, 714, 886, 881, 881, 987, 987, 881, 881, 993,
+ 993, 994, 994, 994, 824, 824, 881, 881, 621, 995,
+ 881, 881, 991, 991, 881, 978, 714, 714, 714, 881,
+ 881, 881, 881, 996, 996, 881, 881, 995, 995, 881,
+ 997, 998, 881, 714, 886, 714, 714, 886, 881, 881,
+ 881, 881, 881, 881, 881, 997, 997, 881, 886, 886,
+ 886, 881, 881, 881, 886, 886, 886, 881, 881, 881,
+ 0, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881
+
+ } ;
+
+static yyconst flex_int16_t yy_nxt[5657] =
+ { 0,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 16,
+ 25, 26, 16, 16, 27, 28, 29, 30, 28, 28,
+ 28, 28, 28, 28, 28, 31, 32, 33, 16, 34,
+ 35, 35, 35, 36, 37, 38, 38, 38, 38, 39,
+ 40, 41, 38, 42, 43, 44, 45, 38, 38, 38,
+ 38, 38, 46, 16, 47, 47, 47, 47, 47, 47,
+ 16, 16, 16, 16, 16, 16, 16, 16, 48, 16,
+ 16, 49, 142, 56, 162, 50, 132, 57, 132, 135,
+ 106, 56, 132, 58, 163, 57, 59, 81, 18, 82,
+ 83, 58, 114, 134, 59, 81, 18, 82, 83, 136,
+
+ 160, 51, 52, 157, 137, 140, 53, 187, 144, 177,
+ 147, 60, 115, 61, 54, 62, 38, 55, 38, 60,
+ 141, 61, 145, 62, 38, 188, 38, 17, 65, 66,
+ 132, 67, 17, 65, 66, 106, 67, 67, 84, 116,
+ 63, 106, 67, 181, 148, 217, 84, 864, 63, 158,
+ 148, 67, 68, 149, 218, 182, 67, 68, 186, 170,
+ 184, 147, 17, 18, 19, 74, 70, 189, 190, 180,
+ 185, 75, 76, 77, 186, 120, 120, 106, 69, 120,
+ 120, 180, 253, 69, 17, 18, 19, 78, 70, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126, 126, 120,
+
+ 127, 127, 127, 127, 127, 128, 17, 18, 19, 74,
+ 70, 106, 106, 79, 114, 75, 76, 77, 204, 204,
+ 204, 204, 204, 205, 121, 207, 332, 262, 211, 150,
+ 106, 78, 252, 110, 192, 71, 72, 72, 72, 72,
+ 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
+ 72, 72, 72, 72, 17, 18, 19, 79, 70, 151,
+ 152, 193, 207, 229, 153, 227, 227, 227, 227, 227,
+ 227, 124, 154, 210, 231, 155, 203, 203, 203, 203,
+ 203, 203, 203, 203, 203, 203, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 259, 106, 106, 106,
+
+ 177, 147, 864, 264, 266, 71, 72, 72, 72, 72,
+ 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
+ 72, 72, 72, 72, 33, 17, 18, 19, 33, 33,
+ 85, 23, 24, 33, 86, 26, 33, 33, 87, 88,
+ 89, 90, 88, 88, 88, 88, 88, 88, 88, 31,
+ 91, 33, 33, 92, 93, 93, 93, 94, 95, 96,
+ 96, 96, 96, 97, 98, 99, 96, 100, 96, 101,
+ 96, 96, 96, 96, 96, 96, 71, 33, 102, 102,
+ 102, 102, 102, 102, 103, 103, 103, 103, 103, 103,
+ 103, 103, 104, 103, 103, 110, 110, 177, 147, 105,
+
+ 177, 147, 177, 147, 187, 111, 106, 188, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112, 122, 260,
+ 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
+ 124, 106, 189, 190, 125, 125, 125, 125, 125, 125,
+ 162, 229, 167, 167, 263, 261, 167, 167, 106, 106,
+ 163, 571, 303, 180, 339, 186, 186, 106, 106, 125,
+ 125, 125, 125, 125, 125, 105, 167, 321, 322, 864,
+ 106, 105, 341, 339, 105, 105, 106, 105, 105, 105,
+ 131, 131, 131, 131, 131, 131, 131, 131, 131, 131,
+ 124, 168, 339, 105, 131, 131, 131, 131, 131, 131,
+
+ 132, 132, 132, 132, 133, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 106, 132, 125,
+ 125, 125, 125, 125, 125, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 105, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 881, 290, 110, 492,
+ 132, 132, 132, 132, 132, 132, 106, 106, 106, 418,
+ 132, 112, 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 342, 106, 339, 411, 105, 105, 105, 105, 105,
+ 105, 146, 147, 105, 105, 105, 106, 105, 105, 864,
+ 412, 105, 227, 227, 227, 227, 227, 227, 227, 227,
+
+ 227, 227, 338, 106, 389, 105, 105, 105, 105, 864,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 110, 173, 147, 174, 881, 175, 106, 114, 390, 174,
+ 111, 175, 881, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 110, 881, 175, 175, 881, 373, 373,
+ 373, 105, 881, 105, 105, 105, 194, 105, 105, 484,
+ 179, 105, 194, 179, 179, 194, 395, 229, 194, 194,
+ 179, 116, 175, 114, 193, 105, 105, 105, 303, 193,
+ 156, 110, 196, 393, 194, 179, 329, 330, 394, 331,
+ 396, 176, 106, 881, 881, 881, 881, 881, 881, 881,
+
+ 881, 881, 881, 881, 362, 363, 106, 364, 197, 194,
+ 120, 491, 413, 120, 120, 106, 120, 120, 120, 120,
+ 193, 106, 120, 120, 113, 568, 113, 113, 427, 106,
+ 113, 113, 850, 428, 113, 420, 196, 120, 120, 227,
+ 227, 227, 227, 227, 227, 227, 227, 227, 227, 113,
+ 113, 112, 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 106, 199, 120, 196, 110, 488, 200, 196, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 124,
+ 196, 593, 389, 202, 202, 202, 202, 202, 202, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+
+ 196, 196, 196, 196, 196, 196, 390, 485, 202, 202,
+ 202, 202, 202, 202, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 881, 417, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 881, 106, 649,
+ 207, 196, 196, 196, 196, 196, 196, 437, 106, 117,
+ 438, 117, 117, 117, 409, 117, 117, 410, 574, 117,
+ 272, 272, 272, 272, 272, 272, 196, 196, 196, 196,
+ 196, 196, 196, 117, 117, 117, 196, 206, 206, 206,
+ 206, 206, 206, 206, 206, 206, 206, 124, 196, 106,
+ 395, 206, 206, 206, 206, 206, 206, 207, 207, 207,
+
+ 207, 208, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 396, 209, 202, 202, 202, 202,
+ 202, 202, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 881, 132, 687, 132, 207, 207, 207,
+ 207, 207, 207, 106, 622, 120, 120, 207, 494, 120,
+ 120, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 389, 196, 196, 196, 196, 196, 196, 881, 120,
+ 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
+ 119, 229, 105, 105, 119, 390, 105, 105, 377, 229,
+
+ 119, 150, 303, 487, 121, 293, 293, 293, 293, 293,
+ 294, 395, 106, 442, 119, 119, 105, 223, 224, 225,
+ 223, 223, 223, 223, 223, 223, 223, 239, 240, 573,
+ 782, 151, 152, 241, 242, 396, 153, 243, 106, 244,
+ 245, 167, 167, 831, 154, 167, 167, 155, 105, 105,
+ 105, 105, 106, 486, 106, 226, 226, 226, 226, 226,
+ 226, 226, 226, 226, 226, 167, 124, 377, 229, 226,
+ 226, 226, 226, 226, 226, 239, 240, 881, 229, 379,
+ 106, 241, 242, 581, 831, 243, 106, 244, 582, 379,
+ 168, 493, 831, 106, 226, 226, 226, 226, 226, 226,
+
+ 232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
+ 124, 419, 881, 552, 232, 232, 232, 232, 232, 232,
+ 268, 269, 270, 268, 268, 268, 268, 268, 268, 268,
+ 382, 382, 382, 382, 382, 383, 881, 553, 881, 226,
+ 226, 226, 226, 226, 226, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 881, 229, 551, 110, 132,
+ 132, 132, 132, 132, 132, 132, 166, 303, 105, 105,
+ 166, 623, 105, 105, 593, 343, 166, 344, 344, 344,
+ 344, 344, 344, 229, 105, 105, 105, 105, 105, 105,
+ 166, 166, 105, 191, 379, 191, 191, 557, 194, 191,
+
+ 191, 377, 229, 191, 194, 377, 229, 194, 881, 229,
+ 194, 194, 120, 379, 634, 132, 120, 459, 191, 191,
+ 459, 558, 120, 782, 196, 881, 194, 624, 194, 727,
+ 194, 194, 194, 881, 194, 194, 120, 120, 194, 272,
+ 272, 272, 272, 272, 272, 272, 272, 272, 272, 881,
+ 197, 194, 194, 194, 194, 120, 814, 881, 120, 120,
+ 881, 120, 120, 120, 120, 561, 554, 120, 120, 272,
+ 272, 272, 272, 272, 272, 272, 272, 272, 272, 279,
+ 280, 196, 120, 120, 881, 281, 282, 106, 106, 283,
+ 814, 284, 222, 222, 222, 222, 222, 222, 222, 222,
+
+ 222, 222, 132, 549, 631, 637, 625, 199, 120, 271,
+ 271, 271, 271, 271, 271, 271, 271, 271, 271, 586,
+ 814, 563, 565, 271, 271, 271, 271, 271, 271, 222,
+ 222, 222, 222, 222, 222, 222, 222, 222, 222, 462,
+ 462, 462, 462, 462, 463, 564, 566, 547, 271, 271,
+ 271, 271, 271, 271, 196, 881, 229, 106, 196, 273,
+ 273, 273, 273, 273, 273, 273, 273, 273, 273, 124,
+ 196, 548, 552, 273, 273, 273, 273, 273, 273, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 553, 209, 271, 271,
+
+ 271, 271, 271, 271, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 881, 747, 132, 881, 207,
+ 207, 207, 207, 207, 207, 292, 292, 292, 292, 292,
+ 292, 292, 292, 292, 292, 540, 540, 540, 540, 540,
+ 541, 881, 881, 881, 196, 196, 196, 196, 196, 196,
+ 290, 831, 291, 291, 291, 291, 291, 291, 291, 291,
+ 291, 291, 167, 567, 881, 881, 167, 881, 106, 686,
+ 110, 132, 167, 308, 308, 308, 308, 308, 308, 308,
+ 308, 308, 308, 550, 636, 648, 167, 167, 881, 106,
+
+ 105, 559, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 207, 557, 560, 563, 295, 295, 295, 295,
+ 295, 295, 381, 381, 381, 381, 381, 381, 381, 381,
+ 381, 381, 831, 627, 565, 547, 881, 558, 132, 564,
+ 753, 295, 295, 295, 295, 295, 295, 297, 298, 299,
+ 299, 299, 299, 299, 299, 299, 299, 300, 566, 548,
+ 881, 301, 301, 301, 301, 301, 301, 421, 422, 423,
+ 421, 421, 421, 421, 421, 421, 421, 562, 495, 229,
+ 496, 496, 496, 496, 496, 496, 301, 301, 301, 301,
+ 301, 301, 229, 304, 305, 306, 304, 304, 304, 304,
+
+ 304, 304, 304, 307, 229, 552, 557, 308, 308, 308,
+ 308, 308, 308, 453, 454, 455, 453, 453, 453, 453,
+ 453, 453, 453, 589, 589, 589, 589, 589, 590, 553,
+ 558, 229, 308, 308, 308, 308, 308, 308, 309, 309,
+ 309, 309, 309, 309, 309, 309, 309, 309, 124, 691,
+ 229, 132, 309, 309, 309, 309, 309, 309, 388, 388,
+ 388, 388, 388, 388, 388, 388, 388, 388, 442, 132,
+ 443, 443, 443, 443, 443, 443, 629, 295, 295, 295,
+ 295, 295, 295, 343, 563, 346, 346, 346, 346, 346,
+ 347, 344, 344, 344, 344, 348, 348, 348, 348, 348,
+
+ 348, 348, 348, 348, 348, 124, 727, 106, 564, 348,
+ 348, 348, 348, 348, 348, 377, 229, 457, 457, 457,
+ 457, 457, 457, 106, 662, 701, 565, 379, 598, 598,
+ 598, 598, 598, 599, 348, 348, 348, 348, 348, 348,
+ 349, 349, 349, 349, 349, 349, 349, 349, 349, 349,
+ 566, 717, 717, 717, 349, 349, 349, 349, 349, 349,
+ 461, 461, 461, 461, 461, 461, 461, 461, 461, 461,
+ 528, 132, 529, 529, 529, 529, 529, 529, 630, 348,
+ 348, 348, 348, 348, 348, 366, 367, 368, 366, 366,
+ 366, 366, 366, 366, 366, 468, 468, 468, 468, 468,
+
+ 468, 468, 468, 468, 468, 377, 229, 535, 535, 535,
+ 535, 535, 535, 105, 105, 105, 105, 459, 699, 110,
+ 751, 752, 106, 371, 371, 372, 373, 373, 373, 373,
+ 373, 373, 373, 300, 377, 229, 378, 378, 378, 378,
+ 378, 378, 378, 378, 378, 378, 379, 814, 692, 694,
+ 380, 380, 380, 380, 380, 380, 539, 539, 539, 539,
+ 539, 539, 539, 539, 539, 539, 690, 743, 814, 881,
+ 132, 132, 693, 695, 700, 380, 380, 380, 380, 380,
+ 380, 229, 384, 385, 386, 384, 384, 384, 384, 384,
+ 384, 384, 387, 881, 132, 106, 388, 388, 388, 388,
+
+ 388, 388, 763, 748, 626, 555, 572, 746, 132, 132,
+ 556, 575, 576, 577, 575, 575, 575, 575, 575, 575,
+ 575, 388, 388, 388, 388, 388, 388, 881, 688, 380,
+ 380, 380, 380, 380, 380, 380, 380, 380, 380, 424,
+ 424, 424, 424, 424, 424, 424, 424, 424, 424, 377,
+ 229, 763, 689, 424, 424, 424, 424, 424, 424, 588,
+ 588, 588, 588, 588, 588, 588, 588, 588, 588, 615,
+ 615, 615, 615, 615, 616, 132, 712, 712, 424, 424,
+ 424, 424, 424, 424, 425, 425, 425, 425, 425, 425,
+ 425, 425, 425, 425, 688, 763, 692, 694, 425, 425,
+
+ 425, 425, 425, 425, 527, 527, 527, 527, 527, 527,
+ 527, 527, 527, 527, 112, 106, 106, 112, 689, 229,
+ 693, 695, 763, 424, 424, 424, 424, 424, 424, 442,
+ 379, 443, 443, 443, 443, 443, 443, 443, 443, 443,
+ 443, 442, 593, 444, 444, 444, 444, 444, 444, 444,
+ 444, 444, 444, 442, 595, 445, 445, 445, 445, 445,
+ 446, 443, 443, 443, 443, 448, 448, 448, 448, 448,
+ 448, 448, 448, 448, 448, 300, 377, 229, 457, 457,
+ 457, 457, 457, 457, 457, 457, 457, 457, 379, 762,
+ 692, 694, 456, 456, 456, 456, 456, 456, 597, 597,
+
+ 597, 597, 597, 597, 597, 597, 597, 597, 665, 665,
+ 665, 665, 665, 666, 693, 695, 802, 456, 456, 456,
+ 456, 456, 456, 377, 229, 458, 458, 458, 458, 458,
+ 458, 458, 458, 458, 458, 459, 106, 132, 132, 460,
+ 460, 460, 460, 460, 460, 605, 606, 607, 605, 605,
+ 605, 605, 605, 605, 605, 683, 683, 683, 683, 683,
+ 684, 798, 752, 132, 460, 460, 460, 460, 460, 460,
+ 229, 464, 465, 466, 464, 464, 464, 464, 464, 464,
+ 464, 467, 229, 377, 229, 468, 468, 468, 468, 468,
+ 468, 377, 229, 459, 132, 459, 881, 229, 763, 106,
+
+ 768, 768, 768, 537, 800, 628, 799, 132, 537, 635,
+ 468, 468, 468, 468, 468, 468, 881, 881, 460, 460,
+ 460, 460, 460, 460, 460, 460, 460, 460, 495, 595,
+ 498, 498, 498, 498, 498, 499, 496, 496, 496, 496,
+ 424, 424, 424, 424, 424, 424, 424, 424, 424, 424,
+ 751, 752, 132, 744, 424, 424, 424, 424, 424, 424,
+ 546, 546, 546, 546, 546, 546, 546, 546, 546, 546,
+ 638, 639, 639, 639, 639, 639, 639, 745, 229, 424,
+ 424, 424, 424, 424, 424, 516, 517, 518, 516, 516,
+ 516, 516, 516, 516, 516, 377, 229, 610, 610, 610,
+
+ 610, 610, 610, 696, 106, 830, 110, 537, 614, 614,
+ 614, 614, 614, 614, 614, 614, 614, 614, 132, 829,
+ 754, 132, 106, 442, 593, 443, 443, 443, 443, 443,
+ 443, 443, 443, 443, 443, 442, 595, 443, 443, 443,
+ 443, 443, 443, 443, 443, 443, 443, 523, 524, 525,
+ 523, 523, 523, 523, 523, 523, 523, 526, 344, 702,
+ 344, 527, 527, 527, 527, 527, 527, 656, 657, 658,
+ 656, 656, 656, 656, 656, 656, 656, 105, 105, 105,
+ 105, 702, 229, 702, 702, 229, 527, 527, 527, 527,
+ 527, 527, 528, 459, 531, 531, 531, 531, 531, 532,
+
+ 529, 529, 529, 529, 377, 229, 535, 535, 535, 535,
+ 535, 535, 535, 535, 535, 535, 459, 702, 110, 744,
+ 534, 534, 534, 534, 534, 534, 604, 604, 604, 604,
+ 604, 604, 604, 604, 604, 604, 849, 850, 229, 702,
+ 744, 702, 703, 745, 662, 534, 534, 534, 534, 534,
+ 534, 377, 229, 536, 536, 536, 536, 536, 536, 536,
+ 536, 536, 536, 537, 745, 881, 106, 538, 538, 538,
+ 538, 538, 538, 593, 593, 660, 660, 660, 660, 660,
+ 660, 849, 850, 801, 595, 595, 662, 132, 222, 881,
+ 809, 222, 538, 538, 538, 538, 538, 538, 229, 542,
+
+ 543, 544, 542, 542, 542, 542, 542, 542, 542, 545,
+ 769, 718, 881, 546, 546, 546, 546, 546, 546, 664,
+ 664, 664, 664, 664, 664, 664, 664, 664, 664, 106,
+ 844, 844, 844, 844, 229, 796, 881, 796, 546, 546,
+ 546, 546, 546, 546, 881, 537, 538, 538, 538, 538,
+ 538, 538, 538, 538, 538, 538, 105, 547, 770, 797,
+ 718, 797, 105, 639, 639, 105, 105, 718, 105, 105,
+ 105, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 548, 132, 763, 105, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+
+ 132, 132, 132, 132, 132, 132, 132, 132, 106, 132,
+ 105, 105, 105, 105, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 105, 105, 586, 587, 587,
+ 587, 587, 587, 587, 587, 587, 587, 587, 377, 229,
+ 377, 229, 881, 229, 730, 730, 730, 730, 730, 731,
+ 537, 881, 612, 229, 612, 377, 229, 679, 679, 679,
+ 679, 679, 679, 662, 537, 106, 593, 612, 594, 594,
+ 594, 594, 594, 594, 594, 594, 594, 594, 595, 178,
+ 178, 178, 596, 596, 596, 596, 596, 596, 682, 682,
+ 682, 682, 682, 682, 682, 682, 682, 682, 672, 763,
+
+ 673, 673, 673, 673, 673, 673, 854, 596, 596, 596,
+ 596, 596, 596, 600, 601, 602, 600, 600, 600, 600,
+ 600, 600, 600, 603, 749, 796, 827, 604, 604, 604,
+ 604, 604, 604, 704, 705, 706, 707, 704, 704, 704,
+ 704, 704, 704, 132, 345, 106, 345, 672, 229, 797,
+ 828, 672, 604, 604, 604, 604, 604, 604, 881, 612,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 377, 229, 610, 610, 610, 610, 610, 610, 610, 610,
+ 610, 610, 537, 178, 178, 178, 609, 609, 609, 609,
+ 609, 609, 714, 714, 714, 714, 714, 714, 714, 714,
+
+ 714, 714, 377, 229, 742, 742, 742, 742, 742, 742,
+ 672, 609, 609, 609, 609, 609, 609, 377, 229, 611,
+ 611, 611, 611, 611, 611, 611, 611, 611, 611, 612,
+ 595, 881, 881, 613, 613, 613, 613, 613, 613, 715,
+ 715, 715, 715, 715, 716, 717, 717, 717, 717, 718,
+ 756, 827, 757, 758, 759, 881, 881, 718, 613, 613,
+ 613, 613, 613, 613, 229, 617, 618, 619, 617, 617,
+ 617, 617, 617, 617, 617, 828, 807, 522, 808, 620,
+ 620, 620, 620, 620, 620, 671, 671, 671, 671, 671,
+ 671, 671, 671, 671, 671, 496, 711, 496, 132, 377,
+
+ 229, 760, 827, 846, 620, 620, 620, 620, 620, 620,
+ 881, 612, 613, 613, 613, 613, 613, 613, 613, 613,
+ 613, 613, 105, 497, 710, 497, 828, 847, 105, 755,
+ 755, 105, 105, 755, 105, 105, 105, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 755, 755, 755,
+ 105, 132, 132, 132, 132, 132, 132, 132, 132, 621,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 106, 132, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 638, 641, 641, 641, 641, 641, 642,
+
+ 639, 639, 639, 639, 196, 640, 640, 593, 196, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 662,
+ 196, 709, 846, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 645, 207, 207, 847, 209, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 651, 652, 653, 654, 651,
+ 651, 651, 651, 651, 651, 593, 708, 725, 725, 725,
+ 725, 725, 725, 529, 638, 529, 593, 662, 729, 729,
+ 729, 729, 729, 729, 729, 729, 729, 729, 727, 639,
+
+ 639, 881, 106, 586, 587, 587, 587, 587, 587, 587,
+ 587, 587, 587, 587, 737, 738, 739, 737, 737, 737,
+ 737, 737, 737, 737, 803, 881, 756, 803, 757, 758,
+ 759, 775, 776, 777, 775, 775, 775, 775, 775, 775,
+ 775, 106, 593, 771, 660, 660, 660, 660, 660, 660,
+ 660, 660, 660, 660, 595, 593, 881, 661, 661, 661,
+ 661, 661, 661, 661, 661, 661, 661, 662, 727, 791,
+ 791, 663, 663, 663, 663, 663, 663, 762, 718, 638,
+ 719, 719, 719, 719, 719, 719, 736, 736, 736, 736,
+ 736, 736, 736, 736, 736, 736, 663, 663, 663, 663,
+
+ 663, 663, 667, 668, 669, 667, 667, 667, 667, 667,
+ 667, 667, 670, 530, 638, 530, 671, 671, 671, 671,
+ 671, 671, 593, 106, 780, 780, 780, 780, 780, 780,
+ 496, 529, 496, 529, 727, 785, 785, 785, 785, 785,
+ 786, 671, 671, 671, 671, 671, 671, 881, 593, 663,
+ 663, 663, 663, 663, 663, 663, 663, 663, 663, 672,
+ 727, 675, 675, 675, 675, 675, 676, 673, 673, 673,
+ 673, 377, 229, 679, 679, 679, 679, 679, 679, 679,
+ 679, 679, 679, 612, 698, 846, 881, 678, 678, 678,
+ 678, 678, 678, 784, 784, 784, 784, 784, 784, 784,
+
+ 784, 784, 784, 881, 697, 881, 881, 881, 106, 847,
+ 881, 132, 678, 678, 678, 678, 678, 678, 377, 229,
+ 680, 680, 680, 680, 680, 680, 680, 680, 680, 680,
+ 229, 836, 132, 229, 681, 681, 681, 681, 681, 681,
+ 593, 612, 804, 805, 806, 804, 804, 804, 804, 804,
+ 804, 804, 782, 756, 760, 757, 758, 759, 672, 681,
+ 681, 681, 681, 681, 681, 881, 881, 681, 681, 681,
+ 681, 681, 681, 681, 681, 681, 681, 105, 782, 673,
+ 674, 673, 674, 105, 792, 792, 105, 105, 672, 105,
+ 105, 105, 132, 132, 132, 132, 132, 132, 132, 132,
+
+ 132, 132, 522, 375, 760, 105, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 685, 132, 132, 132, 106,
+ 132, 105, 105, 105, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 105, 105, 105, 688, 763,
+ 650, 764, 764, 764, 764, 764, 764, 196, 719, 647,
+ 719, 196, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 689, 196, 646, 644, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 643,
+
+ 209, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 712, 593,
+ 713, 713, 713, 713, 713, 713, 713, 713, 713, 713,
+ 720, 782, 720, 881, 638, 757, 758, 759, 825, 825,
+ 825, 825, 825, 826, 673, 881, 673, 881, 881, 759,
+ 229, 791, 791, 791, 791, 791, 791, 106, 718, 638,
+ 721, 721, 721, 721, 721, 722, 719, 719, 719, 719,
+ 593, 633, 725, 725, 725, 725, 725, 725, 725, 725,
+ 725, 725, 662, 593, 760, 726, 726, 726, 726, 726,
+ 726, 726, 726, 726, 726, 727, 760, 632, 132, 728,
+
+ 728, 728, 728, 728, 728, 790, 790, 790, 790, 790,
+ 790, 790, 790, 790, 790, 814, 528, 815, 815, 815,
+ 815, 815, 815, 528, 728, 728, 728, 728, 728, 728,
+ 732, 733, 734, 732, 732, 732, 732, 732, 732, 732,
+ 735, 764, 528, 764, 736, 736, 736, 736, 736, 736,
+ 593, 522, 821, 821, 821, 821, 821, 821, 765, 375,
+ 765, 809, 782, 810, 810, 810, 810, 810, 810, 736,
+ 736, 736, 736, 736, 736, 881, 300, 728, 728, 728,
+ 728, 728, 728, 728, 728, 728, 728, 377, 229, 742,
+ 742, 742, 742, 742, 742, 742, 742, 742, 742, 763,
+
+ 106, 766, 766, 766, 766, 766, 767, 768, 768, 768,
+ 768, 772, 773, 774, 772, 772, 772, 772, 772, 772,
+ 772, 761, 585, 761, 761, 761, 584, 761, 761, 583,
+ 580, 761, 824, 824, 824, 824, 824, 824, 824, 824,
+ 824, 824, 719, 579, 719, 761, 761, 761, 106, 712,
+ 578, 713, 713, 713, 713, 713, 713, 713, 713, 713,
+ 713, 803, 803, 803, 803, 803, 803, 803, 803, 803,
+ 803, 803, 803, 803, 803, 803, 803, 803, 803, 803,
+ 803, 859, 859, 859, 859, 859, 859, 495, 106, 593,
+ 495, 780, 780, 780, 780, 780, 780, 780, 780, 780,
+
+ 780, 727, 593, 495, 781, 781, 781, 781, 781, 781,
+ 781, 781, 781, 781, 782, 815, 570, 815, 783, 783,
+ 783, 783, 783, 783, 840, 841, 842, 840, 840, 840,
+ 840, 840, 840, 840, 831, 569, 832, 832, 832, 832,
+ 832, 832, 106, 783, 783, 783, 783, 783, 783, 787,
+ 788, 789, 787, 787, 787, 787, 787, 787, 787, 816,
+ 832, 816, 832, 790, 790, 790, 790, 790, 790, 851,
+ 852, 853, 851, 851, 851, 851, 851, 851, 851, 854,
+ 106, 855, 855, 855, 855, 855, 855, 106, 790, 790,
+ 790, 790, 790, 790, 881, 106, 783, 783, 783, 783,
+
+ 783, 783, 783, 783, 783, 783, 229, 793, 793, 793,
+ 793, 793, 794, 791, 791, 791, 791, 809, 106, 810,
+ 810, 810, 810, 810, 810, 810, 810, 810, 810, 809,
+ 528, 811, 811, 811, 811, 811, 811, 811, 811, 811,
+ 811, 809, 528, 812, 812, 812, 812, 812, 813, 810,
+ 810, 810, 810, 814, 522, 817, 817, 817, 817, 817,
+ 818, 815, 815, 815, 815, 593, 375, 821, 821, 821,
+ 821, 821, 821, 821, 821, 821, 821, 782, 593, 300,
+ 822, 822, 822, 822, 822, 822, 822, 822, 822, 822,
+ 833, 865, 833, 865, 823, 823, 823, 823, 823, 823,
+
+ 859, 859, 859, 859, 859, 859, 859, 859, 859, 859,
+ 864, 300, 865, 865, 865, 865, 865, 865, 515, 823,
+ 823, 823, 823, 823, 823, 881, 514, 823, 823, 823,
+ 823, 823, 823, 823, 823, 823, 823, 831, 513, 834,
+ 834, 834, 834, 834, 835, 832, 832, 832, 832, 105,
+ 512, 837, 838, 839, 837, 837, 837, 837, 837, 837,
+ 837, 809, 511, 810, 810, 810, 810, 810, 810, 810,
+ 810, 810, 810, 809, 510, 810, 810, 810, 810, 810,
+ 810, 810, 810, 810, 810, 593, 509, 845, 845, 845,
+ 845, 845, 845, 845, 845, 845, 845, 854, 508, 855,
+
+ 855, 855, 855, 855, 855, 855, 855, 855, 855, 854,
+ 507, 856, 856, 856, 856, 856, 856, 856, 856, 856,
+ 856, 854, 506, 857, 857, 857, 857, 857, 858, 855,
+ 855, 855, 855, 860, 860, 860, 860, 860, 860, 860,
+ 860, 860, 860, 861, 861, 861, 861, 861, 862, 859,
+ 859, 859, 859, 864, 505, 867, 867, 867, 867, 867,
+ 868, 865, 865, 865, 865, 105, 504, 869, 870, 871,
+ 869, 869, 869, 869, 869, 869, 869, 854, 503, 855,
+ 855, 855, 855, 855, 855, 855, 855, 855, 855, 854,
+ 502, 855, 855, 855, 855, 855, 855, 855, 855, 855,
+
+ 855, 859, 859, 859, 859, 859, 859, 859, 859, 859,
+ 859, 859, 859, 859, 859, 859, 859, 859, 859, 859,
+ 859, 872, 873, 874, 872, 872, 872, 872, 872, 872,
+ 872, 875, 875, 875, 875, 875, 875, 875, 875, 875,
+ 875, 878, 878, 878, 878, 878, 878, 878, 878, 878,
+ 878, 872, 872, 872, 872, 872, 872, 872, 872, 872,
+ 872, 875, 875, 875, 875, 875, 875, 501, 106, 869,
+ 869, 869, 869, 869, 869, 869, 869, 869, 869, 879,
+ 879, 879, 879, 879, 880, 878, 878, 878, 878, 878,
+ 878, 878, 878, 878, 878, 866, 863, 866, 106, 863,
+
+ 500, 881, 495, 863, 495, 414, 106, 876, 876, 876,
+ 876, 876, 877, 875, 875, 875, 875, 878, 878, 878,
+ 878, 878, 878, 878, 878, 878, 878, 490, 489, 483,
+ 482, 481, 480, 479, 478, 477, 476, 475, 474, 473,
+ 472, 471, 470, 469, 106, 875, 875, 875, 875, 875,
+ 875, 875, 875, 875, 875, 451, 375, 300, 447, 300,
+ 130, 441, 440, 439, 436, 435, 434, 433, 432, 431,
+ 430, 429, 426, 343, 343, 343, 414, 416, 414, 415,
+ 414, 408, 106, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+
+ 64, 64, 64, 64, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 105, 407, 406,
+ 405, 404, 403, 402, 105, 401, 105, 105, 105, 105,
+ 400, 399, 105, 105, 105, 105, 105, 105, 109, 109,
+ 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
+
+ 109, 109, 109, 109, 109, 109, 109, 109, 109, 113,
+ 398, 397, 392, 391, 113, 124, 113, 300, 113, 113,
+ 113, 113, 113, 375, 113, 113, 113, 113, 113, 113,
+ 117, 300, 130, 110, 365, 361, 360, 117, 359, 117,
+ 117, 117, 117, 358, 357, 117, 117, 117, 117, 117,
+ 117, 119, 356, 355, 119, 119, 354, 119, 119, 353,
+ 119, 119, 119, 119, 352, 351, 119, 119, 119, 119,
+ 119, 119, 129, 129, 350, 129, 200, 343, 343, 129,
+ 166, 267, 340, 166, 166, 337, 166, 166, 336, 166,
+ 166, 166, 166, 335, 334, 166, 166, 166, 166, 166,
+
+ 166, 171, 333, 328, 171, 171, 327, 171, 171, 326,
+ 171, 171, 171, 171, 325, 171, 171, 171, 324, 171,
+ 171, 171, 179, 323, 320, 179, 319, 318, 179, 179,
+ 317, 179, 179, 179, 179, 179, 316, 179, 179, 179,
+ 179, 179, 179, 183, 183, 183, 183, 183, 183, 183,
+ 183, 183, 183, 183, 183, 183, 183, 183, 183, 183,
+ 183, 183, 183, 183, 185, 185, 315, 185, 314, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 191, 313, 312, 311, 310,
+ 191, 130, 191, 122, 191, 191, 191, 191, 191, 110,
+
+ 191, 191, 191, 191, 191, 191, 195, 110, 288, 287,
+ 286, 285, 278, 195, 277, 195, 195, 195, 195, 276,
+ 195, 195, 195, 195, 195, 195, 195, 198, 275, 274,
+ 198, 198, 881, 198, 198, 197, 198, 198, 198, 198,
+ 267, 198, 198, 198, 198, 198, 198, 198, 219, 219,
+ 219, 219, 219, 219, 219, 219, 219, 219, 219, 219,
+ 219, 219, 219, 219, 219, 219, 219, 219, 219, 220,
+ 220, 185, 220, 220, 220, 220, 220, 220, 220, 220,
+ 220, 220, 220, 220, 220, 220, 220, 220, 220, 220,
+ 120, 186, 180, 120, 120, 180, 120, 120, 172, 120,
+
+ 120, 120, 120, 265, 165, 120, 120, 120, 120, 120,
+ 120, 129, 129, 165, 129, 258, 257, 256, 129, 228,
+ 228, 255, 228, 254, 251, 250, 228, 230, 230, 230,
+ 249, 230, 248, 247, 246, 230, 166, 238, 237, 166,
+ 166, 236, 166, 166, 235, 166, 166, 166, 166, 234,
+ 233, 166, 166, 166, 166, 166, 166, 167, 130, 105,
+ 167, 167, 130, 167, 167, 199, 167, 167, 167, 167,
+ 118, 221, 167, 167, 167, 167, 167, 167, 171, 110,
+ 108, 171, 171, 107, 171, 171, 106, 171, 171, 171,
+ 171, 216, 171, 171, 171, 215, 171, 171, 171, 179,
+
+ 214, 213, 179, 212, 207, 179, 179, 186, 179, 179,
+ 179, 179, 179, 180, 179, 179, 179, 179, 179, 179,
+ 185, 185, 172, 185, 140, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 194, 169, 137, 165, 164, 161, 159, 194, 143,
+ 194, 194, 194, 194, 142, 139, 194, 194, 194, 194,
+ 194, 194, 195, 138, 132, 130, 118, 108, 107, 195,
+ 106, 195, 195, 195, 195, 881, 195, 195, 195, 195,
+ 195, 195, 195, 198, 881, 881, 198, 198, 881, 198,
+ 198, 881, 198, 198, 198, 198, 881, 198, 198, 198,
+
+ 198, 198, 198, 198, 209, 881, 881, 209, 209, 881,
+ 209, 289, 289, 289, 289, 289, 289, 289, 289, 289,
+ 289, 289, 289, 289, 289, 289, 289, 289, 289, 289,
+ 289, 289, 296, 296, 881, 296, 881, 881, 881, 296,
+ 302, 302, 302, 881, 302, 881, 881, 881, 302, 369,
+ 369, 881, 369, 881, 881, 881, 369, 370, 370, 881,
+ 370, 881, 881, 881, 370, 374, 374, 881, 374, 881,
+ 881, 881, 374, 376, 376, 376, 881, 376, 881, 881,
+ 881, 376, 209, 881, 881, 209, 209, 881, 209, 447,
+ 447, 881, 447, 881, 881, 881, 447, 449, 449, 881,
+
+ 449, 881, 881, 881, 449, 450, 450, 881, 450, 881,
+ 881, 881, 450, 452, 452, 452, 881, 452, 881, 881,
+ 881, 452, 456, 456, 456, 456, 881, 456, 881, 881,
+ 881, 456, 519, 519, 881, 519, 881, 881, 881, 519,
+ 520, 520, 881, 520, 881, 881, 881, 520, 521, 521,
+ 881, 521, 881, 881, 881, 521, 533, 533, 533, 881,
+ 533, 881, 881, 881, 533, 534, 534, 534, 534, 881,
+ 534, 881, 881, 881, 534, 219, 219, 219, 219, 219,
+ 219, 219, 219, 219, 219, 219, 219, 219, 219, 219,
+ 219, 219, 219, 219, 219, 219, 591, 591, 881, 591,
+
+ 881, 881, 881, 591, 592, 592, 881, 592, 881, 881,
+ 881, 592, 608, 608, 608, 881, 608, 881, 881, 881,
+ 608, 609, 609, 609, 609, 881, 609, 881, 881, 881,
+ 609, 219, 219, 219, 219, 219, 219, 219, 219, 219,
+ 219, 219, 219, 219, 219, 219, 219, 219, 219, 219,
+ 219, 219, 209, 881, 881, 209, 209, 881, 209, 196,
+ 881, 881, 881, 196, 196, 881, 196, 196, 196, 881,
+ 881, 196, 196, 655, 655, 881, 655, 881, 881, 881,
+ 655, 659, 881, 659, 659, 881, 659, 881, 881, 881,
+ 659, 677, 677, 677, 881, 677, 881, 881, 881, 677,
+
+ 678, 678, 678, 678, 881, 678, 881, 881, 881, 678,
+ 620, 620, 881, 881, 620, 881, 881, 881, 620, 219,
+ 219, 219, 219, 219, 219, 219, 219, 219, 219, 219,
+ 219, 219, 219, 219, 219, 219, 219, 219, 219, 219,
+ 209, 881, 881, 209, 209, 881, 209, 196, 881, 881,
+ 881, 196, 196, 881, 196, 196, 196, 881, 881, 196,
+ 196, 723, 723, 881, 723, 881, 881, 881, 723, 724,
+ 881, 724, 724, 881, 724, 881, 881, 881, 724, 740,
+ 740, 740, 881, 740, 881, 881, 881, 740, 741, 741,
+ 741, 881, 881, 741, 881, 881, 881, 741, 750, 750,
+
+ 750, 750, 750, 750, 750, 750, 750, 750, 750, 750,
+ 750, 750, 750, 750, 750, 750, 750, 750, 750, 755,
+ 755, 881, 755, 755, 755, 881, 755, 881, 755, 755,
+ 755, 755, 881, 881, 755, 755, 755, 755, 755, 755,
+ 761, 761, 881, 761, 761, 761, 881, 761, 881, 761,
+ 761, 761, 761, 881, 881, 761, 761, 761, 761, 761,
+ 761, 209, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 209, 209, 881, 209, 209, 881, 209, 778,
+ 778, 881, 778, 881, 881, 881, 778, 779, 881, 779,
+ 779, 881, 779, 881, 881, 881, 779, 795, 795, 881,
+
+ 881, 795, 881, 881, 881, 795, 761, 881, 881, 881,
+ 881, 881, 881, 761, 881, 761, 761, 761, 761, 881,
+ 881, 761, 761, 761, 761, 761, 761, 819, 819, 881,
+ 819, 881, 881, 881, 819, 820, 881, 820, 820, 881,
+ 820, 881, 881, 881, 820, 843, 843, 881, 843, 881,
+ 881, 881, 843, 844, 881, 844, 881, 881, 844, 881,
+ 881, 881, 844, 848, 848, 848, 848, 848, 848, 848,
+ 848, 848, 848, 848, 848, 848, 848, 848, 848, 848,
+ 848, 848, 848, 848, 15, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881
+ } ;
+
+static yyconst flex_int16_t yy_chk[5657] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 54, 3, 56, 2, 37, 3, 51, 37,
+ 875, 4, 36, 3, 56, 4, 3, 11, 11, 11,
+ 11, 4, 22, 36, 4, 12, 12, 12, 12, 39,
+
+ 54, 2, 2, 51, 39, 42, 2, 81, 45, 71,
+ 71, 3, 22, 3, 2, 3, 3, 2, 3, 4,
+ 42, 4, 45, 4, 4, 82, 4, 5, 5, 5,
+ 52, 5, 6, 6, 6, 48, 6, 5, 11, 22,
+ 3, 63, 6, 75, 48, 104, 12, 867, 4, 52,
+ 63, 5, 5, 48, 104, 77, 6, 6, 81, 63,
+ 79, 79, 9, 9, 9, 9, 9, 84, 84, 75,
+ 84, 9, 9, 9, 82, 27, 27, 149, 5, 27,
+ 27, 77, 149, 6, 7, 7, 7, 9, 7, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 27,
+
+ 30, 30, 30, 30, 30, 30, 10, 10, 10, 10,
+ 10, 159, 253, 9, 85, 10, 10, 10, 90, 90,
+ 90, 90, 90, 90, 27, 95, 253, 159, 95, 49,
+ 148, 10, 148, 156, 85, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 8, 8, 8, 10, 8, 49,
+ 49, 85, 94, 130, 49, 128, 128, 128, 128, 128,
+ 128, 295, 49, 94, 130, 49, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 156, 161, 295, 170,
+
+ 173, 173, 866, 161, 170, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 21, 491, 146, 146, 158,
+
+ 177, 177, 184, 184, 187, 21, 157, 188, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 28, 157,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 160, 189, 189, 28, 28, 28, 28, 28, 28,
+ 162, 230, 59, 59, 160, 158, 59, 59, 146, 260,
+ 162, 491, 230, 184, 260, 187, 188, 28, 264, 28,
+ 28, 28, 28, 28, 28, 34, 59, 245, 245, 865,
+ 263, 34, 263, 264, 34, 34, 341, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 59, 341, 34, 34, 34, 34, 34, 34, 34,
+
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 291, 259, 418,
+ 38, 38, 38, 38, 38, 38, 262, 266, 339, 339,
+ 38, 112, 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 266, 418, 262, 330, 38, 38, 38, 38, 38,
+ 38, 46, 46, 46, 46, 46, 291, 46, 46, 852,
+ 331, 46, 126, 126, 126, 126, 126, 126, 126, 126,
+
+ 126, 126, 259, 330, 310, 46, 46, 46, 47, 851,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 50, 69, 69, 69, 113, 69, 331, 115, 310, 69,
+ 50, 69, 191, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 417, 113, 69, 69, 115, 299, 299,
+ 299, 106, 191, 106, 106, 106, 86, 106, 106, 409,
+ 180, 106, 86, 180, 180, 86, 314, 302, 86, 86,
+ 180, 113, 69, 192, 115, 106, 106, 106, 302, 191,
+ 50, 70, 86, 313, 86, 180, 252, 252, 313, 252,
+ 314, 70, 409, 192, 70, 70, 70, 70, 70, 70,
+
+ 70, 70, 70, 70, 287, 287, 332, 287, 86, 86,
+ 87, 417, 332, 87, 87, 488, 87, 87, 87, 87,
+ 192, 252, 87, 87, 116, 488, 116, 116, 352, 342,
+ 116, 116, 848, 352, 116, 342, 87, 87, 87, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 116,
+ 116, 164, 164, 164, 164, 164, 164, 164, 164, 164,
+ 164, 413, 87, 87, 88, 338, 413, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 845, 350, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+
+ 88, 88, 88, 88, 88, 88, 350, 410, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 91, 338, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 410, 584,
+ 584, 91, 91, 91, 91, 91, 91, 362, 494, 118,
+ 362, 118, 118, 118, 329, 118, 118, 329, 494, 118,
+ 205, 205, 205, 205, 205, 205, 91, 91, 91, 91,
+ 91, 91, 92, 118, 118, 118, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 329,
+ 353, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 353, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 96, 96, 96, 96, 96, 96, 96,
+ 96, 96, 96, 96, 550, 623, 623, 96, 96, 96,
+ 96, 96, 96, 420, 550, 119, 119, 96, 420, 119,
+ 119, 176, 176, 176, 176, 176, 176, 176, 176, 176,
+ 176, 389, 96, 96, 96, 96, 96, 96, 102, 119,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 121, 376, 121, 121, 121, 389, 121, 121, 680, 680,
+
+ 121, 150, 376, 412, 119, 225, 225, 225, 225, 225,
+ 225, 395, 493, 443, 121, 121, 121, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 139, 139, 493,
+ 843, 150, 150, 139, 139, 395, 150, 139, 412, 139,
+ 139, 166, 166, 834, 150, 166, 166, 150, 294, 294,
+ 294, 294, 443, 411, 122, 123, 123, 123, 123, 123,
+ 123, 123, 123, 123, 123, 166, 340, 378, 378, 123,
+ 123, 123, 123, 123, 123, 169, 169, 380, 380, 378,
+ 419, 169, 169, 505, 833, 169, 411, 169, 505, 380,
+ 166, 419, 832, 340, 123, 123, 123, 123, 123, 123,
+
+ 131, 131, 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 340, 472, 473, 131, 131, 131, 131, 131, 131,
+ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ 306, 306, 306, 306, 306, 306, 472, 473, 823, 131,
+ 131, 131, 131, 131, 131, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 452, 472, 571, 132,
+ 132, 132, 132, 132, 132, 551, 168, 452, 168, 168,
+ 168, 551, 168, 168, 822, 347, 168, 347, 347, 347,
+ 347, 347, 347, 456, 132, 132, 132, 132, 132, 132,
+ 168, 168, 168, 193, 456, 193, 193, 476, 195, 193,
+
+ 193, 457, 457, 193, 195, 458, 458, 195, 460, 460,
+ 195, 195, 199, 457, 571, 554, 199, 458, 193, 193,
+ 460, 476, 199, 820, 195, 474, 195, 554, 197, 819,
+ 197, 197, 197, 479, 197, 197, 199, 199, 197, 203,
+ 203, 203, 203, 203, 203, 203, 203, 203, 203, 474,
+ 195, 195, 197, 197, 197, 198, 817, 479, 198, 198,
+ 470, 198, 198, 198, 198, 479, 474, 198, 198, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204, 204, 214,
+ 214, 198, 198, 198, 470, 214, 214, 568, 574, 214,
+ 816, 214, 221, 221, 221, 221, 221, 221, 221, 221,
+
+ 221, 221, 555, 470, 568, 574, 555, 198, 198, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 587,
+ 815, 481, 482, 201, 201, 201, 201, 201, 201, 222,
+ 222, 222, 222, 222, 222, 222, 222, 222, 222, 386,
+ 386, 386, 386, 386, 386, 481, 482, 500, 201, 201,
+ 201, 201, 201, 201, 206, 681, 681, 587, 206, 206,
+ 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
+ 206, 500, 503, 206, 206, 206, 206, 206, 206, 206,
+ 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
+ 206, 206, 206, 206, 206, 206, 503, 206, 206, 206,
+
+ 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
+ 206, 206, 206, 206, 206, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 690, 690, 483, 207,
+ 207, 207, 207, 207, 207, 224, 224, 224, 224, 224,
+ 224, 224, 224, 224, 224, 466, 466, 466, 466, 466,
+ 466, 471, 483, 477, 207, 207, 207, 207, 207, 207,
+ 223, 805, 223, 223, 223, 223, 223, 223, 223, 223,
+ 223, 223, 265, 483, 478, 471, 265, 477, 573, 622,
+ 700, 622, 265, 303, 303, 303, 303, 303, 303, 303,
+ 303, 303, 303, 471, 573, 583, 265, 265, 478, 223,
+
+ 226, 477, 226, 226, 226, 226, 226, 226, 226, 226,
+ 226, 226, 583, 506, 478, 509, 226, 226, 226, 226,
+ 226, 226, 305, 305, 305, 305, 305, 305, 305, 305,
+ 305, 305, 804, 559, 510, 547, 480, 506, 559, 509,
+ 700, 226, 226, 226, 226, 226, 226, 229, 229, 229,
+ 229, 229, 229, 229, 229, 229, 229, 229, 510, 547,
+ 480, 229, 229, 229, 229, 229, 229, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 480, 499, 795,
+ 499, 499, 499, 499, 499, 499, 229, 229, 229, 229,
+ 229, 229, 231, 231, 231, 231, 231, 231, 231, 231,
+
+ 231, 231, 231, 231, 793, 552, 557, 231, 231, 231,
+ 231, 231, 231, 377, 377, 377, 377, 377, 377, 377,
+ 377, 377, 377, 518, 518, 518, 518, 518, 518, 552,
+ 557, 792, 231, 231, 231, 231, 231, 231, 232, 232,
+ 232, 232, 232, 232, 232, 232, 232, 232, 232, 626,
+ 791, 626, 232, 232, 232, 232, 232, 232, 379, 379,
+ 379, 379, 379, 379, 379, 379, 379, 379, 446, 561,
+ 446, 446, 446, 446, 446, 446, 561, 232, 232, 232,
+ 232, 232, 232, 270, 563, 270, 270, 270, 270, 270,
+ 270, 270, 270, 270, 270, 271, 271, 271, 271, 271,
+
+ 271, 271, 271, 271, 271, 271, 779, 446, 563, 271,
+ 271, 271, 271, 271, 271, 383, 383, 383, 383, 383,
+ 383, 383, 383, 635, 778, 635, 565, 383, 525, 525,
+ 525, 525, 525, 525, 271, 271, 271, 271, 271, 271,
+ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273,
+ 565, 654, 654, 654, 273, 273, 273, 273, 273, 273,
+ 385, 385, 385, 385, 385, 385, 385, 385, 385, 385,
+ 532, 562, 532, 532, 532, 532, 532, 532, 562, 273,
+ 273, 273, 273, 273, 273, 290, 290, 290, 290, 290,
+ 290, 290, 290, 290, 290, 459, 459, 459, 459, 459,
+
+ 459, 459, 459, 459, 459, 463, 463, 463, 463, 463,
+ 463, 463, 463, 590, 590, 590, 590, 463, 634, 634,
+ 699, 699, 290, 298, 298, 298, 298, 298, 298, 298,
+ 298, 298, 298, 298, 304, 304, 304, 304, 304, 304,
+ 304, 304, 304, 304, 304, 304, 304, 776, 648, 649,
+ 304, 304, 304, 304, 304, 304, 465, 465, 465, 465,
+ 465, 465, 465, 465, 465, 465, 625, 685, 775, 475,
+ 685, 625, 648, 649, 634, 304, 304, 304, 304, 304,
+ 304, 307, 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 475, 556, 492, 307, 307, 307, 307,
+
+ 307, 307, 768, 691, 556, 475, 492, 687, 691, 687,
+ 475, 495, 495, 495, 495, 495, 495, 495, 495, 495,
+ 495, 307, 307, 307, 307, 307, 307, 308, 624, 308,
+ 308, 308, 308, 308, 308, 308, 308, 308, 308, 348,
+ 348, 348, 348, 348, 348, 348, 348, 348, 348, 742,
+ 742, 766, 624, 348, 348, 348, 348, 348, 348, 517,
+ 517, 517, 517, 517, 517, 517, 517, 517, 517, 544,
+ 544, 544, 544, 544, 544, 624, 713, 717, 348, 348,
+ 348, 348, 348, 348, 349, 349, 349, 349, 349, 349,
+ 349, 349, 349, 349, 688, 765, 692, 694, 349, 349,
+
+ 349, 349, 349, 349, 522, 522, 522, 522, 522, 522,
+ 522, 522, 522, 522, 892, 713, 717, 892, 688, 533,
+ 692, 694, 764, 349, 349, 349, 349, 349, 349, 366,
+ 533, 366, 366, 366, 366, 366, 366, 366, 366, 366,
+ 366, 367, 594, 367, 367, 367, 367, 367, 367, 367,
+ 367, 367, 367, 368, 594, 368, 368, 368, 368, 368,
+ 368, 368, 368, 368, 368, 371, 371, 371, 371, 371,
+ 371, 371, 371, 371, 371, 371, 381, 381, 381, 381,
+ 381, 381, 381, 381, 381, 381, 381, 381, 381, 761,
+ 627, 628, 381, 381, 381, 381, 381, 381, 524, 524,
+
+ 524, 524, 524, 524, 524, 524, 524, 524, 602, 602,
+ 602, 602, 602, 602, 627, 628, 759, 381, 381, 381,
+ 381, 381, 381, 384, 384, 384, 384, 384, 384, 384,
+ 384, 384, 384, 384, 384, 384, 754, 627, 628, 384,
+ 384, 384, 384, 384, 384, 528, 528, 528, 528, 528,
+ 528, 528, 528, 528, 528, 619, 619, 619, 619, 619,
+ 619, 747, 750, 747, 384, 384, 384, 384, 384, 384,
+ 387, 387, 387, 387, 387, 387, 387, 387, 387, 387,
+ 387, 387, 534, 535, 535, 387, 387, 387, 387, 387,
+ 387, 536, 536, 534, 560, 535, 538, 538, 707, 572,
+
+ 707, 707, 707, 536, 749, 560, 748, 748, 538, 572,
+ 387, 387, 387, 387, 387, 387, 388, 596, 388, 388,
+ 388, 388, 388, 388, 388, 388, 388, 388, 423, 596,
+ 423, 423, 423, 423, 423, 423, 423, 423, 423, 423,
+ 424, 424, 424, 424, 424, 424, 424, 424, 424, 424,
+ 751, 751, 743, 708, 424, 424, 424, 424, 424, 424,
+ 537, 537, 537, 537, 537, 537, 537, 537, 537, 537,
+ 642, 642, 642, 642, 642, 642, 642, 708, 741, 424,
+ 424, 424, 424, 424, 424, 442, 442, 442, 442, 442,
+ 442, 442, 442, 442, 442, 541, 541, 541, 541, 541,
+
+ 541, 541, 541, 630, 701, 801, 801, 541, 543, 543,
+ 543, 543, 543, 543, 543, 543, 543, 543, 630, 799,
+ 701, 799, 442, 444, 660, 444, 444, 444, 444, 444,
+ 444, 444, 444, 444, 444, 445, 660, 445, 445, 445,
+ 445, 445, 445, 445, 445, 445, 445, 451, 451, 451,
+ 451, 451, 451, 451, 451, 451, 451, 451, 922, 698,
+ 922, 451, 451, 451, 451, 451, 451, 593, 593, 593,
+ 593, 593, 593, 593, 593, 593, 593, 716, 716, 716,
+ 716, 698, 608, 698, 698, 738, 451, 451, 451, 451,
+ 451, 451, 455, 608, 455, 455, 455, 455, 455, 455,
+
+ 455, 455, 455, 455, 461, 461, 461, 461, 461, 461,
+ 461, 461, 461, 461, 461, 461, 461, 636, 753, 744,
+ 461, 461, 461, 461, 461, 461, 595, 595, 595, 595,
+ 595, 595, 595, 595, 595, 595, 830, 830, 737, 636,
+ 686, 636, 636, 744, 724, 461, 461, 461, 461, 461,
+ 461, 464, 464, 464, 464, 464, 464, 464, 464, 464,
+ 464, 464, 464, 464, 686, 709, 636, 464, 464, 464,
+ 464, 464, 464, 599, 661, 599, 599, 599, 599, 599,
+ 599, 849, 849, 753, 723, 599, 661, 686, 904, 709,
+ 810, 904, 464, 464, 464, 464, 464, 464, 467, 467,
+
+ 467, 467, 467, 467, 467, 467, 467, 467, 467, 467,
+ 709, 721, 710, 467, 467, 467, 467, 467, 467, 601,
+ 601, 601, 601, 601, 601, 601, 601, 601, 601, 810,
+ 826, 826, 826, 826, 609, 746, 710, 769, 467, 467,
+ 467, 467, 467, 467, 468, 609, 468, 468, 468, 468,
+ 468, 468, 468, 468, 468, 468, 469, 469, 710, 746,
+ 720, 769, 469, 951, 951, 469, 469, 719, 469, 469,
+ 469, 469, 469, 469, 469, 469, 469, 469, 469, 469,
+ 469, 469, 746, 705, 469, 469, 469, 469, 469, 469,
+ 469, 469, 469, 469, 469, 469, 469, 469, 469, 469,
+
+ 469, 469, 469, 469, 469, 469, 469, 469, 469, 469,
+ 469, 469, 469, 469, 469, 469, 469, 469, 469, 469,
+ 469, 469, 469, 469, 469, 469, 469, 516, 516, 516,
+ 516, 516, 516, 516, 516, 516, 516, 516, 610, 610,
+ 611, 611, 613, 613, 669, 669, 669, 669, 669, 669,
+ 610, 663, 611, 677, 613, 616, 616, 616, 616, 616,
+ 616, 616, 616, 663, 677, 516, 523, 616, 523, 523,
+ 523, 523, 523, 523, 523, 523, 523, 523, 523, 895,
+ 895, 895, 523, 523, 523, 523, 523, 523, 618, 618,
+ 618, 618, 618, 618, 618, 618, 618, 618, 676, 704,
+
+ 676, 676, 676, 676, 676, 676, 855, 523, 523, 523,
+ 523, 523, 523, 526, 526, 526, 526, 526, 526, 526,
+ 526, 526, 526, 526, 697, 796, 807, 526, 526, 526,
+ 526, 526, 526, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 696, 923, 855, 923, 675, 678, 796,
+ 807, 674, 526, 526, 526, 526, 526, 526, 527, 678,
+ 527, 527, 527, 527, 527, 527, 527, 527, 527, 527,
+ 539, 539, 539, 539, 539, 539, 539, 539, 539, 539,
+ 539, 539, 539, 912, 912, 912, 539, 539, 539, 539,
+ 539, 539, 652, 652, 652, 652, 652, 652, 652, 652,
+
+ 652, 652, 684, 684, 684, 684, 684, 684, 684, 684,
+ 673, 539, 539, 539, 539, 539, 539, 542, 542, 542,
+ 542, 542, 542, 542, 542, 542, 542, 542, 542, 542,
+ 659, 770, 771, 542, 542, 542, 542, 542, 542, 653,
+ 653, 653, 653, 653, 653, 653, 653, 653, 653, 657,
+ 702, 798, 702, 702, 702, 770, 771, 656, 542, 542,
+ 542, 542, 542, 542, 545, 545, 545, 545, 545, 545,
+ 545, 545, 545, 545, 545, 798, 770, 655, 771, 545,
+ 545, 545, 545, 545, 545, 662, 662, 662, 662, 662,
+ 662, 662, 662, 662, 662, 934, 647, 934, 798, 679,
+
+ 679, 702, 827, 836, 545, 545, 545, 545, 545, 545,
+ 546, 679, 546, 546, 546, 546, 546, 546, 546, 546,
+ 546, 546, 549, 935, 646, 935, 827, 836, 549, 760,
+ 760, 549, 549, 760, 549, 549, 549, 549, 549, 549,
+ 549, 549, 549, 549, 549, 549, 549, 760, 760, 760,
+ 549, 549, 549, 549, 549, 549, 549, 549, 549, 549,
+ 549, 549, 549, 549, 549, 549, 549, 549, 549, 549,
+ 549, 549, 549, 549, 549, 549, 549, 549, 549, 549,
+ 549, 549, 549, 549, 549, 549, 549, 549, 549, 549,
+ 549, 549, 549, 577, 577, 577, 577, 577, 577, 577,
+
+ 577, 577, 577, 577, 580, 952, 952, 725, 580, 580,
+ 580, 580, 580, 580, 580, 580, 580, 580, 580, 725,
+ 580, 644, 846, 580, 580, 580, 580, 580, 580, 580,
+ 580, 580, 580, 580, 580, 580, 580, 580, 580, 580,
+ 580, 580, 580, 580, 580, 580, 846, 580, 580, 580,
+ 580, 580, 580, 580, 580, 580, 580, 580, 580, 580,
+ 580, 580, 580, 580, 580, 586, 586, 586, 586, 586,
+ 586, 586, 586, 586, 586, 666, 643, 666, 666, 666,
+ 666, 666, 666, 939, 641, 939, 726, 666, 668, 668,
+ 668, 668, 668, 668, 668, 668, 668, 668, 726, 963,
+
+ 963, 711, 586, 588, 588, 588, 588, 588, 588, 588,
+ 588, 588, 588, 588, 672, 672, 672, 672, 672, 672,
+ 672, 672, 672, 672, 985, 711, 703, 985, 703, 703,
+ 703, 718, 718, 718, 718, 718, 718, 718, 718, 718,
+ 718, 588, 597, 711, 597, 597, 597, 597, 597, 597,
+ 597, 597, 597, 597, 597, 600, 728, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600, 728, 982,
+ 982, 600, 600, 600, 600, 600, 600, 703, 722, 640,
+ 722, 722, 722, 722, 722, 722, 727, 727, 727, 727,
+ 727, 727, 727, 727, 727, 727, 600, 600, 600, 600,
+
+ 600, 600, 603, 603, 603, 603, 603, 603, 603, 603,
+ 603, 603, 603, 940, 639, 940, 603, 603, 603, 603,
+ 603, 603, 731, 637, 731, 731, 731, 731, 731, 731,
+ 944, 947, 944, 947, 731, 734, 734, 734, 734, 734,
+ 734, 603, 603, 603, 603, 603, 603, 604, 780, 604,
+ 604, 604, 604, 604, 604, 604, 604, 604, 604, 607,
+ 780, 607, 607, 607, 607, 607, 607, 607, 607, 607,
+ 607, 614, 614, 614, 614, 614, 614, 614, 614, 614,
+ 614, 614, 614, 614, 633, 829, 808, 614, 614, 614,
+ 614, 614, 614, 733, 733, 733, 733, 733, 733, 733,
+
+ 733, 733, 733, 755, 632, 755, 755, 755, 631, 829,
+ 808, 629, 614, 614, 614, 614, 614, 614, 617, 617,
+ 617, 617, 617, 617, 617, 617, 617, 617, 617, 617,
+ 740, 808, 829, 612, 617, 617, 617, 617, 617, 617,
+ 781, 740, 763, 763, 763, 763, 763, 763, 763, 763,
+ 763, 763, 781, 756, 755, 756, 756, 756, 606, 617,
+ 617, 617, 617, 617, 617, 620, 783, 620, 620, 620,
+ 620, 620, 620, 620, 620, 620, 620, 621, 783, 957,
+ 958, 957, 958, 621, 983, 983, 621, 621, 605, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+
+ 621, 621, 592, 591, 756, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 645, 767,
+ 585, 767, 767, 767, 767, 767, 767, 645, 966, 582,
+ 966, 645, 645, 645, 645, 645, 645, 645, 645, 645,
+ 645, 645, 645, 645, 581, 579, 645, 645, 645, 645,
+ 645, 645, 645, 645, 645, 645, 645, 645, 645, 645,
+ 645, 645, 645, 645, 645, 645, 645, 645, 645, 578,
+
+ 645, 645, 645, 645, 645, 645, 645, 645, 645, 645,
+ 645, 645, 645, 645, 645, 645, 645, 645, 651, 821,
+ 651, 651, 651, 651, 651, 651, 651, 651, 651, 651,
+ 967, 821, 967, 757, 576, 757, 757, 757, 789, 789,
+ 789, 789, 789, 789, 970, 758, 970, 758, 758, 758,
+ 794, 794, 794, 794, 794, 794, 794, 651, 658, 575,
+ 658, 658, 658, 658, 658, 658, 658, 658, 658, 658,
+ 664, 570, 664, 664, 664, 664, 664, 664, 664, 664,
+ 664, 664, 664, 667, 757, 667, 667, 667, 667, 667,
+ 667, 667, 667, 667, 667, 667, 758, 569, 567, 667,
+
+ 667, 667, 667, 667, 667, 782, 782, 782, 782, 782,
+ 782, 782, 782, 782, 782, 818, 531, 818, 818, 818,
+ 818, 818, 818, 530, 667, 667, 667, 667, 667, 667,
+ 670, 670, 670, 670, 670, 670, 670, 670, 670, 670,
+ 670, 976, 529, 976, 670, 670, 670, 670, 670, 670,
+ 786, 521, 786, 786, 786, 786, 786, 786, 977, 520,
+ 977, 813, 786, 813, 813, 813, 813, 813, 813, 670,
+ 670, 670, 670, 670, 670, 671, 519, 671, 671, 671,
+ 671, 671, 671, 671, 671, 671, 671, 682, 682, 682,
+ 682, 682, 682, 682, 682, 682, 682, 682, 682, 706,
+
+ 813, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+ 706, 712, 712, 712, 712, 712, 712, 712, 712, 712,
+ 712, 762, 515, 762, 762, 762, 508, 762, 762, 507,
+ 504, 762, 788, 788, 788, 788, 788, 788, 788, 788,
+ 788, 788, 979, 502, 979, 762, 762, 762, 712, 714,
+ 501, 714, 714, 714, 714, 714, 714, 714, 714, 714,
+ 714, 802, 802, 802, 802, 802, 802, 802, 802, 802,
+ 802, 803, 803, 803, 803, 803, 803, 803, 803, 803,
+ 803, 862, 862, 862, 862, 862, 862, 498, 714, 729,
+ 497, 729, 729, 729, 729, 729, 729, 729, 729, 729,
+
+ 729, 729, 732, 496, 732, 732, 732, 732, 732, 732,
+ 732, 732, 732, 732, 732, 987, 490, 987, 732, 732,
+ 732, 732, 732, 732, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 835, 489, 835, 835, 835, 835,
+ 835, 835, 487, 732, 732, 732, 732, 732, 732, 735,
+ 735, 735, 735, 735, 735, 735, 735, 735, 735, 988,
+ 991, 988, 991, 735, 735, 735, 735, 735, 735, 831,
+ 831, 831, 831, 831, 831, 831, 831, 831, 831, 858,
+ 486, 858, 858, 858, 858, 858, 858, 485, 735, 735,
+ 735, 735, 735, 735, 736, 484, 736, 736, 736, 736,
+
+ 736, 736, 736, 736, 736, 736, 739, 739, 739, 739,
+ 739, 739, 739, 739, 739, 739, 739, 772, 858, 772,
+ 772, 772, 772, 772, 772, 772, 772, 772, 772, 773,
+ 454, 773, 773, 773, 773, 773, 773, 773, 773, 773,
+ 773, 774, 453, 774, 774, 774, 774, 774, 774, 774,
+ 774, 774, 774, 777, 450, 777, 777, 777, 777, 777,
+ 777, 777, 777, 777, 777, 784, 449, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784, 787, 448,
+ 787, 787, 787, 787, 787, 787, 787, 787, 787, 787,
+ 992, 997, 992, 997, 787, 787, 787, 787, 787, 787,
+
+ 840, 840, 840, 840, 840, 840, 840, 840, 840, 840,
+ 868, 447, 868, 868, 868, 868, 868, 868, 441, 787,
+ 787, 787, 787, 787, 787, 790, 440, 790, 790, 790,
+ 790, 790, 790, 790, 790, 790, 790, 806, 439, 806,
+ 806, 806, 806, 806, 806, 806, 806, 806, 806, 809,
+ 438, 809, 809, 809, 809, 809, 809, 809, 809, 809,
+ 809, 811, 437, 811, 811, 811, 811, 811, 811, 811,
+ 811, 811, 811, 812, 436, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 824, 435, 824, 824, 824,
+ 824, 824, 824, 824, 824, 824, 824, 837, 434, 837,
+
+ 837, 837, 837, 837, 837, 837, 837, 837, 837, 838,
+ 433, 838, 838, 838, 838, 838, 838, 838, 838, 838,
+ 838, 839, 432, 839, 839, 839, 839, 839, 839, 839,
+ 839, 839, 839, 841, 841, 841, 841, 841, 841, 841,
+ 841, 841, 841, 842, 842, 842, 842, 842, 842, 842,
+ 842, 842, 842, 853, 431, 853, 853, 853, 853, 853,
+ 853, 853, 853, 853, 853, 854, 430, 854, 854, 854,
+ 854, 854, 854, 854, 854, 854, 854, 856, 429, 856,
+ 856, 856, 856, 856, 856, 856, 856, 856, 856, 857,
+ 428, 857, 857, 857, 857, 857, 857, 857, 857, 857,
+
+ 857, 860, 860, 860, 860, 860, 860, 860, 860, 860,
+ 860, 861, 861, 861, 861, 861, 861, 861, 861, 861,
+ 861, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 869, 869, 869, 869, 869, 869, 869, 869, 869,
+ 869, 872, 872, 872, 872, 872, 872, 872, 872, 872,
+ 872, 873, 873, 873, 873, 873, 873, 873, 873, 873,
+ 873, 877, 877, 877, 877, 877, 877, 427, 869, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870, 870, 874,
+ 874, 874, 874, 874, 874, 874, 874, 874, 874, 880,
+ 880, 880, 880, 880, 880, 998, 996, 998, 877, 996,
+
+ 426, 425, 422, 996, 421, 416, 870, 871, 871, 871,
+ 871, 871, 871, 871, 871, 871, 871, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 415, 414, 408,
+ 407, 405, 404, 403, 402, 401, 400, 399, 398, 397,
+ 394, 393, 392, 391, 871, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 375, 374, 373, 372, 370,
+ 369, 365, 364, 363, 361, 360, 359, 358, 357, 356,
+ 355, 354, 351, 346, 345, 344, 337, 336, 335, 334,
+ 333, 327, 876, 882, 882, 882, 882, 882, 882, 882,
+ 882, 882, 882, 882, 882, 882, 882, 882, 882, 882,
+
+ 882, 882, 882, 882, 883, 883, 883, 883, 883, 883,
+ 883, 883, 883, 883, 883, 883, 883, 883, 883, 883,
+ 883, 883, 883, 883, 883, 884, 884, 884, 884, 884,
+ 884, 884, 884, 884, 884, 884, 884, 884, 884, 884,
+ 884, 884, 884, 884, 884, 884, 885, 885, 885, 885,
+ 885, 885, 885, 885, 885, 885, 885, 885, 885, 885,
+ 885, 885, 885, 885, 885, 885, 885, 886, 326, 324,
+ 323, 322, 321, 320, 886, 319, 886, 886, 886, 886,
+ 318, 317, 886, 886, 886, 886, 886, 886, 887, 887,
+ 887, 887, 887, 887, 887, 887, 887, 887, 887, 887,
+
+ 887, 887, 887, 887, 887, 887, 887, 887, 887, 888,
+ 316, 315, 312, 311, 888, 309, 888, 301, 888, 888,
+ 888, 888, 888, 300, 888, 888, 888, 888, 888, 888,
+ 889, 297, 296, 289, 288, 286, 285, 889, 284, 889,
+ 889, 889, 889, 283, 282, 889, 889, 889, 889, 889,
+ 889, 890, 281, 280, 890, 890, 279, 890, 890, 278,
+ 890, 890, 890, 890, 277, 276, 890, 890, 890, 890,
+ 890, 890, 891, 891, 275, 891, 272, 269, 268, 891,
+ 893, 267, 261, 893, 893, 258, 893, 893, 257, 893,
+ 893, 893, 893, 256, 255, 893, 893, 893, 893, 893,
+
+ 893, 894, 254, 251, 894, 894, 250, 894, 894, 249,
+ 894, 894, 894, 894, 248, 894, 894, 894, 247, 894,
+ 894, 894, 896, 246, 244, 896, 243, 242, 896, 896,
+ 241, 896, 896, 896, 896, 896, 240, 896, 896, 896,
+ 896, 896, 896, 897, 897, 897, 897, 897, 897, 897,
+ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897,
+ 897, 897, 897, 897, 898, 898, 239, 898, 238, 898,
+ 898, 898, 898, 898, 898, 898, 898, 898, 898, 898,
+ 898, 898, 898, 898, 898, 899, 237, 236, 235, 234,
+ 899, 228, 899, 227, 899, 899, 899, 899, 899, 220,
+
+ 899, 899, 899, 899, 899, 899, 900, 219, 218, 217,
+ 216, 215, 213, 900, 212, 900, 900, 900, 900, 211,
+ 900, 900, 900, 900, 900, 900, 900, 901, 210, 208,
+ 901, 901, 202, 901, 901, 194, 901, 901, 901, 901,
+ 190, 901, 901, 901, 901, 901, 901, 901, 902, 902,
+ 902, 902, 902, 902, 902, 902, 902, 902, 902, 902,
+ 902, 902, 902, 902, 902, 902, 902, 902, 902, 903,
+ 903, 186, 903, 903, 903, 903, 903, 903, 903, 903,
+ 903, 903, 903, 903, 903, 903, 903, 903, 903, 903,
+ 905, 185, 183, 905, 905, 179, 905, 905, 172, 905,
+
+ 905, 905, 905, 167, 165, 905, 905, 905, 905, 905,
+ 905, 906, 906, 163, 906, 155, 154, 153, 906, 907,
+ 907, 152, 907, 151, 145, 144, 907, 908, 908, 908,
+ 143, 908, 142, 141, 140, 908, 909, 138, 137, 909,
+ 909, 136, 909, 909, 135, 909, 909, 909, 909, 134,
+ 133, 909, 909, 909, 909, 909, 909, 910, 129, 125,
+ 910, 910, 124, 910, 910, 120, 910, 910, 910, 910,
+ 117, 114, 910, 910, 910, 910, 910, 910, 911, 109,
+ 108, 911, 911, 107, 911, 911, 105, 911, 911, 911,
+ 911, 101, 911, 911, 911, 100, 911, 911, 911, 913,
+
+ 99, 98, 913, 97, 93, 913, 913, 80, 913, 913,
+ 913, 913, 913, 73, 913, 913, 913, 913, 913, 913,
+ 914, 914, 66, 914, 62, 914, 914, 914, 914, 914,
+ 914, 914, 914, 914, 914, 914, 914, 914, 914, 914,
+ 914, 915, 61, 60, 58, 57, 55, 53, 915, 44,
+ 915, 915, 915, 915, 43, 41, 915, 915, 915, 915,
+ 915, 915, 916, 40, 35, 31, 25, 19, 17, 916,
+ 16, 916, 916, 916, 916, 15, 916, 916, 916, 916,
+ 916, 916, 916, 917, 0, 0, 917, 917, 0, 917,
+ 917, 0, 917, 917, 917, 917, 0, 917, 917, 917,
+
+ 917, 917, 917, 917, 918, 0, 0, 918, 918, 0,
+ 918, 919, 919, 919, 919, 919, 919, 919, 919, 919,
+ 919, 919, 919, 919, 919, 919, 919, 919, 919, 919,
+ 919, 919, 920, 920, 0, 920, 0, 0, 0, 920,
+ 921, 921, 921, 0, 921, 0, 0, 0, 921, 924,
+ 924, 0, 924, 0, 0, 0, 924, 925, 925, 0,
+ 925, 0, 0, 0, 925, 926, 926, 0, 926, 0,
+ 0, 0, 926, 927, 927, 927, 0, 927, 0, 0,
+ 0, 927, 928, 0, 0, 928, 928, 0, 928, 929,
+ 929, 0, 929, 0, 0, 0, 929, 930, 930, 0,
+
+ 930, 0, 0, 0, 930, 931, 931, 0, 931, 0,
+ 0, 0, 931, 932, 932, 932, 0, 932, 0, 0,
+ 0, 932, 933, 933, 933, 933, 0, 933, 0, 0,
+ 0, 933, 936, 936, 0, 936, 0, 0, 0, 936,
+ 937, 937, 0, 937, 0, 0, 0, 937, 938, 938,
+ 0, 938, 0, 0, 0, 938, 941, 941, 941, 0,
+ 941, 0, 0, 0, 941, 942, 942, 942, 942, 0,
+ 942, 0, 0, 0, 942, 943, 943, 943, 943, 943,
+ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ 943, 943, 943, 943, 943, 943, 945, 945, 0, 945,
+
+ 0, 0, 0, 945, 946, 946, 0, 946, 0, 0,
+ 0, 946, 948, 948, 948, 0, 948, 0, 0, 0,
+ 948, 949, 949, 949, 949, 0, 949, 0, 0, 0,
+ 949, 950, 950, 950, 950, 950, 950, 950, 950, 950,
+ 950, 950, 950, 950, 950, 950, 950, 950, 950, 950,
+ 950, 950, 953, 0, 0, 953, 953, 0, 953, 954,
+ 0, 0, 0, 954, 954, 0, 954, 954, 954, 0,
+ 0, 954, 954, 955, 955, 0, 955, 0, 0, 0,
+ 955, 956, 0, 956, 956, 0, 956, 0, 0, 0,
+ 956, 959, 959, 959, 0, 959, 0, 0, 0, 959,
+
+ 960, 960, 960, 960, 0, 960, 0, 0, 0, 960,
+ 961, 961, 0, 0, 961, 0, 0, 0, 961, 962,
+ 962, 962, 962, 962, 962, 962, 962, 962, 962, 962,
+ 962, 962, 962, 962, 962, 962, 962, 962, 962, 962,
+ 964, 0, 0, 964, 964, 0, 964, 965, 0, 0,
+ 0, 965, 965, 0, 965, 965, 965, 0, 0, 965,
+ 965, 968, 968, 0, 968, 0, 0, 0, 968, 969,
+ 0, 969, 969, 0, 969, 0, 0, 0, 969, 971,
+ 971, 971, 0, 971, 0, 0, 0, 971, 972, 972,
+ 972, 0, 0, 972, 0, 0, 0, 972, 973, 973,
+
+ 973, 973, 973, 973, 973, 973, 973, 973, 973, 973,
+ 973, 973, 973, 973, 973, 973, 973, 973, 973, 974,
+ 974, 0, 974, 974, 974, 0, 974, 0, 974, 974,
+ 974, 974, 0, 0, 974, 974, 974, 974, 974, 974,
+ 975, 975, 0, 975, 975, 975, 0, 975, 0, 975,
+ 975, 975, 975, 0, 0, 975, 975, 975, 975, 975,
+ 975, 978, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 978, 978, 0, 978, 978, 0, 978, 980,
+ 980, 0, 980, 0, 0, 0, 980, 981, 0, 981,
+ 981, 0, 981, 0, 0, 0, 981, 984, 984, 0,
+
+ 0, 984, 0, 0, 0, 984, 986, 0, 0, 0,
+ 0, 0, 0, 986, 0, 986, 986, 986, 986, 0,
+ 0, 986, 986, 986, 986, 986, 986, 989, 989, 0,
+ 989, 0, 0, 0, 989, 990, 0, 990, 990, 0,
+ 990, 0, 0, 0, 990, 993, 993, 0, 993, 0,
+ 0, 0, 993, 994, 0, 994, 0, 0, 994, 0,
+ 0, 0, 994, 995, 995, 995, 995, 995, 995, 995,
+ 995, 995, 995, 995, 995, 995, 995, 995, 995, 995,
+ 995, 995, 995, 995, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 881, 881, 881, 881, 881
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int sudoers_flex_debug;
+int sudoers_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *sudoerstext;
+#line 1 "toke.l"
+#line 2 "toke.l"
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2017
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+#include <ctype.h>
+#include "sudoers.h"
+#include "toke.h"
+#include <gram.h>
+#include "sudo_digest.h"
+#include "sudo_lbuf.h"
+
+#if defined(HAVE_STRUCT_DIRENT_D_NAMLEN) && HAVE_STRUCT_DIRENT_D_NAMLEN
+# define NAMLEN(dirent) (dirent)->d_namlen
+#else
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#endif
+
+int sudolineno; /* current sudoers line number. */
+int last_token; /* last token that was parsed. */
+char *sudoers; /* sudoers file being parsed. */
+
+/* Default sudoers path, mode and owner (may be set via sudo.conf) */
+const char *sudoers_file = _PATH_SUDOERS;
+mode_t sudoers_mode = SUDOERS_MODE;
+uid_t sudoers_uid = SUDOERS_UID;
+gid_t sudoers_gid = SUDOERS_GID;
+
+static bool continued, sawspace;
+static int prev_state;
+static int digest_type = -1;
+
+static bool push_include_int(char *, bool);
+static bool pop_include(void);
+static char *parse_include_int(const char *, bool);
+
+int (*trace_print)(const char *msg) = sudoers_trace_print;
+
+#define LEXRETURN(n) do { \
+ last_token = (n); \
+ return (n); \
+} while (0)
+
+#define ECHO ignore_result(fwrite(sudoerstext, sudoersleng, 1, sudoersout))
+
+#define parse_include(_p) (parse_include_int((_p), false))
+#define parse_includedir(_p) (parse_include_int((_p), true))
+#define push_include(_p) (push_include_int((_p), false))
+#define push_includedir(_p) (push_include_int((_p), true))
+#define YY_NO_INPUT 1
+
+
+
+
+
+
+#line 2133 "toke.c"
+
+#define INITIAL 0
+#define GOTDEFS 1
+#define GOTCMND 2
+#define STARTDEFS 3
+#define INDEFS 4
+#define INSTR 5
+#define WANTDIGEST 6
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int sudoerslex_destroy (void );
+
+int sudoersget_debug (void );
+
+void sudoersset_debug (int debug_flag );
+
+YY_EXTRA_TYPE sudoersget_extra (void );
+
+void sudoersset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *sudoersget_in (void );
+
+void sudoersset_in (FILE * in_str );
+
+FILE *sudoersget_out (void );
+
+void sudoersset_out (FILE * out_str );
+
+yy_size_t sudoersget_leng (void );
+
+char *sudoersget_text (void );
+
+int sudoersget_lineno (void );
+
+void sudoersset_lineno (int line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int sudoerswrap (void );
+#else
+extern int sudoerswrap (void );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( sudoerstext, sudoersleng, 1, sudoersout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( sudoersin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( sudoersin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, sudoersin))==0 && ferror(sudoersin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(sudoersin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int sudoerslex (void);
+
+#define YY_DECL int sudoerslex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after sudoerstext and sudoersleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ if ( sudoersleng > 0 ) \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+ (sudoerstext[sudoersleng - 1] == '\n'); \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! sudoersin )
+ sudoersin = stdin;
+
+ if ( ! sudoersout )
+ sudoersout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ sudoersensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ sudoers_create_buffer(sudoersin,YY_BUF_SIZE );
+ }
+
+ sudoers_load_buffer_state( );
+ }
+
+ {
+#line 113 "toke.l"
+
+#line 2351 "toke.c"
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of sudoerstext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+ yy_current_state += YY_AT_BOL();
+yy_match:
+ do
+ {
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 882 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 5585 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 114 "toke.l"
+{
+ LEXTRACE(", ");
+ LEXRETURN(',');
+ } /* return ',' */
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 119 "toke.l"
+BEGIN STARTDEFS;
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 121 "toke.l"
+{
+ BEGIN INDEFS;
+ LEXTRACE("DEFVAR ");
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXRETURN(DEFVAR);
+ }
+ YY_BREAK
+
+case 4:
+YY_RULE_SETUP
+#line 130 "toke.l"
+{
+ BEGIN STARTDEFS;
+ LEXTRACE(", ");
+ LEXRETURN(',');
+ } /* return ',' */
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 136 "toke.l"
+{
+ LEXTRACE("= ");
+ LEXRETURN('=');
+ } /* return '=' */
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 141 "toke.l"
+{
+ LEXTRACE("+= ");
+ LEXRETURN('+');
+ } /* return '+' */
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 146 "toke.l"
+{
+ LEXTRACE("-= ");
+ LEXRETURN('-');
+ } /* return '-' */
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 151 "toke.l"
+{
+ LEXTRACE("BEGINSTR ");
+ sudoerslval.string = NULL;
+ prev_state = YY_START;
+ BEGIN INSTR;
+ }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 158 "toke.l"
+{
+ LEXTRACE("WORD(2) ");
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXRETURN(WORD);
+ }
+ YY_BREAK
+
+
+case 10:
+/* rule 10 can match eol */
+YY_RULE_SETUP
+#line 167 "toke.l"
+{
+ /* Line continuation char followed by newline. */
+ sudolineno++;
+ continued = true;
+ }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 173 "toke.l"
+{
+ LEXTRACE("ENDSTR ");
+ BEGIN prev_state;
+
+ if (sudoerslval.string == NULL) {
+ LEXTRACE("ERROR "); /* empty string */
+ LEXRETURN(ERROR);
+ }
+ if (prev_state == INITIAL) {
+ switch (sudoerslval.string[0]) {
+ case '%':
+ if (sudoerslval.string[1] == '\0' ||
+ (sudoerslval.string[1] == ':' &&
+ sudoerslval.string[2] == '\0')) {
+ LEXTRACE("ERROR "); /* empty group */
+ LEXRETURN(ERROR);
+ }
+ LEXTRACE("USERGROUP ");
+ LEXRETURN(USERGROUP);
+ case '+':
+ if (sudoerslval.string[1] == '\0') {
+ LEXTRACE("ERROR "); /* empty netgroup */
+ LEXRETURN(ERROR);
+ }
+ LEXTRACE("NETGROUP ");
+ LEXRETURN(NETGROUP);
+ }
+ }
+ LEXTRACE("WORD(4) ");
+ LEXRETURN(WORD);
+ }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 205 "toke.l"
+{
+ LEXTRACE("BACKSLASH ");
+ if (!append(sudoerstext, sudoersleng))
+ yyterminate();
+ }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 211 "toke.l"
+{
+ LEXTRACE("STRBODY ");
+ if (!append(sudoerstext, sudoersleng))
+ yyterminate();
+ }
+ YY_BREAK
+
+
+case 14:
+YY_RULE_SETUP
+#line 219 "toke.l"
+{
+ /* quoted fnmatch glob char, pass verbatim */
+ LEXTRACE("QUOTEDCHAR ");
+ if (!fill_args(sudoerstext, 2, sawspace))
+ yyterminate();
+ sawspace = false;
+ }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 227 "toke.l"
+{
+ /* quoted sudoers special char, strip backslash */
+ LEXTRACE("QUOTEDCHAR ");
+ if (!fill_args(sudoerstext + 1, 1, sawspace))
+ yyterminate();
+ sawspace = false;
+ }
+ YY_BREAK
+case 16:
+/* rule 16 can match eol */
+YY_RULE_SETUP
+#line 235 "toke.l"
+{
+ BEGIN INITIAL;
+ yyless(0);
+ LEXRETURN(COMMAND);
+ } /* end of command line args */
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 241 "toke.l"
+{
+ LEXTRACE("ARG ");
+ if (!fill_args(sudoerstext, sudoersleng, sawspace))
+ yyterminate();
+ sawspace = false;
+ } /* a command line arg */
+ YY_BREAK
+
+case 18:
+YY_RULE_SETUP
+#line 249 "toke.l"
+{
+ /* Only return DIGEST if the length is correct. */
+ yy_size_t digest_len =
+ sudo_digest_getlen(digest_type);
+ if ((yy_size_t)sudoersleng == digest_len * 2) {
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ BEGIN INITIAL;
+ LEXTRACE("DIGEST ");
+ LEXRETURN(DIGEST);
+ }
+ BEGIN INITIAL;
+ yyless(sudoersleng);
+ } /* hex digest */
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 264 "toke.l"
+{
+ /* Only return DIGEST if the length is correct. */
+ yy_size_t len, digest_len =
+ sudo_digest_getlen(digest_type);
+ if (sudoerstext[sudoersleng - 1] == '=') {
+ /* use padding */
+ len = 4 * ((digest_len + 2) / 3);
+ } else {
+ /* no padding */
+ len = (4 * digest_len + 2) / 3;
+ }
+ if ((yy_size_t)sudoersleng == len) {
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ BEGIN INITIAL;
+ LEXTRACE("DIGEST ");
+ LEXRETURN(DIGEST);
+ }
+ BEGIN INITIAL;
+ yyless(sudoersleng);
+ } /* base64 digest */
+ YY_BREAK
+case 20:
+/* rule 20 can match eol */
+YY_RULE_SETUP
+#line 286 "toke.l"
+{
+ char *path;
+
+ if (continued) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+
+ if ((path = parse_include(sudoerstext)) == NULL)
+ yyterminate();
+
+ LEXTRACE("INCLUDE\n");
+
+ /* Push current buffer and switch to include file */
+ if (!push_include(path))
+ yyterminate();
+ }
+ YY_BREAK
+case 21:
+/* rule 21 can match eol */
+YY_RULE_SETUP
+#line 304 "toke.l"
+{
+ char *path;
+
+ if (continued) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+
+ if ((path = parse_includedir(sudoerstext)) == NULL)
+ yyterminate();
+
+ LEXTRACE("INCLUDEDIR\n");
+
+ /*
+ * Push current buffer and switch to include file,
+ * ignoring missing or empty directories.
+ */
+ if (!push_includedir(path))
+ yyterminate();
+ }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 325 "toke.l"
+{
+ char deftype;
+ int n;
+
+ if (continued) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+
+ for (n = 0; isblank((unsigned char)sudoerstext[n]); n++)
+ continue;
+ n += sizeof("Defaults") - 1;
+ if ((deftype = sudoerstext[n++]) != '\0') {
+ while (isblank((unsigned char)sudoerstext[n]))
+ n++;
+ }
+ BEGIN GOTDEFS;
+ switch (deftype) {
+ case ':':
+ yyless(n);
+ LEXTRACE("DEFAULTS_USER ");
+ LEXRETURN(DEFAULTS_USER);
+ case '>':
+ yyless(n);
+ LEXTRACE("DEFAULTS_RUNAS ");
+ LEXRETURN(DEFAULTS_RUNAS);
+ case '@':
+ yyless(n);
+ LEXTRACE("DEFAULTS_HOST ");
+ LEXRETURN(DEFAULTS_HOST);
+ case '!':
+ yyless(n);
+ LEXTRACE("DEFAULTS_CMND ");
+ LEXRETURN(DEFAULTS_CMND);
+ default:
+ LEXTRACE("DEFAULTS ");
+ LEXRETURN(DEFAULTS);
+ }
+ }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 365 "toke.l"
+{
+ int n;
+
+ if (continued) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+
+ for (n = 0; isblank((unsigned char)sudoerstext[n]); n++)
+ continue;
+ switch (sudoerstext[n]) {
+ case 'H':
+ LEXTRACE("HOSTALIAS ");
+ LEXRETURN(HOSTALIAS);
+ case 'C':
+ LEXTRACE("CMNDALIAS ");
+ LEXRETURN(CMNDALIAS);
+ case 'U':
+ LEXTRACE("USERALIAS ");
+ LEXRETURN(USERALIAS);
+ case 'R':
+ LEXTRACE("RUNASALIAS ");
+ LEXRETURN(RUNASALIAS);
+ }
+ }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 391 "toke.l"
+{
+ /* cmnd does not require passwd for this user */
+ LEXTRACE("NOPASSWD ");
+ LEXRETURN(NOPASSWD);
+ }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 397 "toke.l"
+{
+ /* cmnd requires passwd for this user */
+ LEXTRACE("PASSWD ");
+ LEXRETURN(PASSWD);
+ }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 403 "toke.l"
+{
+ LEXTRACE("NOEXEC ");
+ LEXRETURN(NOEXEC);
+ }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 408 "toke.l"
+{
+ LEXTRACE("EXEC ");
+ LEXRETURN(EXEC);
+ }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 413 "toke.l"
+{
+ LEXTRACE("SETENV ");
+ LEXRETURN(SETENV);
+ }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 418 "toke.l"
+{
+ LEXTRACE("NOSETENV ");
+ LEXRETURN(NOSETENV);
+ }
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 423 "toke.l"
+{
+ LEXTRACE("LOG_OUTPUT ");
+ LEXRETURN(LOG_OUTPUT);
+ }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 428 "toke.l"
+{
+ LEXTRACE("NOLOG_OUTPUT ");
+ LEXRETURN(NOLOG_OUTPUT);
+ }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 433 "toke.l"
+{
+ LEXTRACE("LOG_INPUT ");
+ LEXRETURN(LOG_INPUT);
+ }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 438 "toke.l"
+{
+ LEXTRACE("NOLOG_INPUT ");
+ LEXRETURN(NOLOG_INPUT);
+ }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 443 "toke.l"
+{
+ LEXTRACE("MAIL ");
+ LEXRETURN(MAIL);
+ }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 448 "toke.l"
+{
+ LEXTRACE("NOMAIL ");
+ LEXRETURN(NOMAIL);
+ }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 453 "toke.l"
+{
+ LEXTRACE("FOLLOW ");
+ LEXRETURN(FOLLOW);
+ }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 458 "toke.l"
+{
+ LEXTRACE("NOFOLLOW ");
+ LEXRETURN(NOFOLLOW);
+ }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 463 "toke.l"
+{
+ /* empty group or netgroup */
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 469 "toke.l"
+{
+ /* netgroup */
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("NETGROUP ");
+ LEXRETURN(NETGROUP);
+ }
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 477 "toke.l"
+{
+ /* group */
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("USERGROUP ");
+ LEXRETURN(USERGROUP);
+ }
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 485 "toke.l"
+{
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("NTWKADDR ");
+ LEXRETURN(NTWKADDR);
+ }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 492 "toke.l"
+{
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("NTWKADDR ");
+ LEXRETURN(NTWKADDR);
+ }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 499 "toke.l"
+{
+ if (!ipv6_valid(sudoerstext)) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("NTWKADDR ");
+ LEXRETURN(NTWKADDR);
+ }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 510 "toke.l"
+{
+ if (!ipv6_valid(sudoerstext)) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("NTWKADDR ");
+ LEXRETURN(NTWKADDR);
+ }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 521 "toke.l"
+{
+ LEXTRACE("ALL ");
+ LEXRETURN(ALL);
+
+ }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 527 "toke.l"
+{
+ LEXTRACE("CMND_TIMEOUT ");
+ LEXRETURN(CMND_TIMEOUT);
+ }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 532 "toke.l"
+{
+ LEXTRACE("NOTBEFORE ");
+ LEXRETURN(NOTBEFORE);
+ }
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 537 "toke.l"
+{
+ LEXTRACE("NOTAFTER ");
+ LEXRETURN(NOTAFTER);
+ }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 542 "toke.l"
+{
+#ifdef HAVE_SELINUX
+ LEXTRACE("ROLE ");
+ LEXRETURN(ROLE);
+#else
+ goto got_alias;
+#endif
+ }
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 551 "toke.l"
+{
+#ifdef HAVE_SELINUX
+ LEXTRACE("TYPE ");
+ LEXRETURN(TYPE);
+#else
+ goto got_alias;
+#endif
+ }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 559 "toke.l"
+{
+#ifdef HAVE_PRIV_SET
+ LEXTRACE("PRIVS ");
+ LEXRETURN(PRIVS);
+#else
+ goto got_alias;
+#endif
+ }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 568 "toke.l"
+{
+#ifdef HAVE_PRIV_SET
+ LEXTRACE("LIMITPRIVS ");
+ LEXRETURN(LIMITPRIVS);
+#else
+ goto got_alias;
+#endif
+ }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 577 "toke.l"
+{
+ got_alias:
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("ALIAS ");
+ LEXRETURN(ALIAS);
+ }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 585 "toke.l"
+{
+ /* XXX - no way to specify digest for command */
+ /* no command args allowed for Defaults!/path */
+ if (!fill_cmnd(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("COMMAND ");
+ LEXRETURN(COMMAND);
+ }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 594 "toke.l"
+{
+ digest_type = SUDO_DIGEST_SHA224;
+ BEGIN WANTDIGEST;
+ LEXTRACE("SHA224_TOK ");
+ LEXRETURN(SHA224_TOK);
+ }
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 601 "toke.l"
+{
+ digest_type = SUDO_DIGEST_SHA256;
+ BEGIN WANTDIGEST;
+ LEXTRACE("SHA256_TOK ");
+ LEXRETURN(SHA256_TOK);
+ }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 608 "toke.l"
+{
+ digest_type = SUDO_DIGEST_SHA384;
+ BEGIN WANTDIGEST;
+ LEXTRACE("SHA384_TOK ");
+ LEXRETURN(SHA384_TOK);
+ }
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 615 "toke.l"
+{
+ digest_type = SUDO_DIGEST_SHA512;
+ BEGIN WANTDIGEST;
+ LEXTRACE("SHA512_TOK ");
+ LEXRETURN(SHA512_TOK);
+ }
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 622 "toke.l"
+{
+ BEGIN GOTCMND;
+ LEXTRACE("COMMAND ");
+ if (!fill_cmnd(sudoerstext, sudoersleng))
+ yyterminate();
+ } /* sudo -e */
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 629 "toke.l"
+{
+ /* directories can't have args... */
+ if (sudoerstext[sudoersleng - 1] == '/') {
+ LEXTRACE("COMMAND ");
+ if (!fill_cmnd(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXRETURN(COMMAND);
+ } else {
+ BEGIN GOTCMND;
+ LEXTRACE("COMMAND ");
+ if (!fill_cmnd(sudoerstext, sudoersleng))
+ yyterminate();
+ }
+ } /* a pathname */
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 644 "toke.l"
+{
+ LEXTRACE("BEGINSTR ");
+ sudoerslval.string = NULL;
+ prev_state = YY_START;
+ BEGIN INSTR;
+ }
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 651 "toke.l"
+{
+ /* a word */
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("WORD(5) ");
+ LEXRETURN(WORD);
+ }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 659 "toke.l"
+{
+ LEXTRACE("( ");
+ LEXRETURN('(');
+ }
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 664 "toke.l"
+{
+ LEXTRACE(") ");
+ LEXRETURN(')');
+ }
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 669 "toke.l"
+{
+ LEXTRACE(", ");
+ LEXRETURN(',');
+ } /* return ',' */
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 674 "toke.l"
+{
+ LEXTRACE("= ");
+ LEXRETURN('=');
+ } /* return '=' */
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 679 "toke.l"
+{
+ LEXTRACE(": ");
+ LEXRETURN(':');
+ } /* return ':' */
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 684 "toke.l"
+{
+ if (sudoersleng & 1) {
+ LEXTRACE("!");
+ LEXRETURN('!'); /* return '!' */
+ }
+ }
+ YY_BREAK
+case 69:
+/* rule 69 can match eol */
+YY_RULE_SETUP
+#line 691 "toke.l"
+{
+ if (YY_START == INSTR) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR); /* line break in string */
+ }
+ BEGIN INITIAL;
+ sudolineno++;
+ continued = false;
+ LEXTRACE("\n");
+ LEXRETURN(COMMENT);
+ } /* return newline */
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 703 "toke.l"
+{ /* throw away space/tabs */
+ sawspace = true; /* but remember for fill_args */
+ }
+ YY_BREAK
+case 71:
+/* rule 71 can match eol */
+YY_RULE_SETUP
+#line 707 "toke.l"
+{
+ sawspace = true; /* remember for fill_args */
+ sudolineno++;
+ continued = true;
+ } /* throw away EOL after \ */
+ YY_BREAK
+case 72:
+/* rule 72 can match eol */
+YY_RULE_SETUP
+#line 713 "toke.l"
+{
+ if (sudoerstext[sudoersleng - 1] == '\n') {
+ /* comment ending in a newline */
+ BEGIN INITIAL;
+ sudolineno++;
+ continued = false;
+ } else if (!feof(sudoersin)) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+ LEXTRACE("#\n");
+ LEXRETURN(COMMENT);
+ } /* comment, not uid/gid */
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 727 "toke.l"
+{
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ } /* parse error */
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(GOTDEFS):
+case YY_STATE_EOF(GOTCMND):
+case YY_STATE_EOF(STARTDEFS):
+case YY_STATE_EOF(INDEFS):
+case YY_STATE_EOF(INSTR):
+case YY_STATE_EOF(WANTDIGEST):
+#line 732 "toke.l"
+{
+ if (YY_START != INITIAL) {
+ BEGIN INITIAL;
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+ if (!pop_include())
+ yyterminate();
+ }
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 742 "toke.l"
+ECHO;
+ YY_BREAK
+#line 3277 "toke.c"
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed sudoersin at a new source and called
+ * sudoerslex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = sudoersin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( sudoerswrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * sudoerstext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of user's declarations */
+} /* end of sudoerslex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = (yytext_ptr);
+ int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ yy_size_t num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ yy_size_t new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ sudoersrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ sudoersrestart(sudoersin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) sudoersrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ yy_state_type yy_current_state;
+ char *yy_cp;
+
+ yy_current_state = (yy_start);
+ yy_current_state += YY_AT_BOL();
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 882 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ int yy_is_jam;
+ char *yy_cp = (yy_c_buf_p);
+
+ YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 882 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 881);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ sudoersrestart(sudoersin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( sudoerswrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve sudoerstext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void sudoersrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ sudoersensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ sudoers_create_buffer(sudoersin,YY_BUF_SIZE );
+ }
+
+ sudoers_init_buffer(YY_CURRENT_BUFFER,input_file );
+ sudoers_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void sudoers_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * sudoerspop_buffer_state();
+ * sudoerspush_buffer_state(new_buffer);
+ */
+ sudoersensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ sudoers_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (sudoerswrap()) processing, but the only time this flag
+ * is looked at is after sudoerswrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void sudoers_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ sudoersin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE sudoers_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) sudoersalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in sudoers_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) sudoersalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in sudoers_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ sudoers_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with sudoers_create_buffer()
+ *
+ */
+ void sudoers_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ sudoersfree((void *) b->yy_ch_buf );
+
+ sudoersfree((void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a sudoersrestart() or at EOF.
+ */
+ static void sudoers_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ sudoers_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then sudoers_init_buffer was _probably_
+ * called from sudoersrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void sudoers_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ sudoers_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void sudoerspush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ sudoersensure_buffer_stack();
+
+ /* This block is copied from sudoers_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from sudoers_switch_to_buffer. */
+ sudoers_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void sudoerspop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ sudoers_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ sudoers_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void sudoersensure_buffer_stack (void)
+{
+ yy_size_t num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)sudoersalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in sudoersensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)sudoersrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in sudoersensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE sudoers_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) sudoersalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in sudoers_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ sudoers_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to sudoerslex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * sudoers_scan_bytes() instead.
+ */
+YY_BUFFER_STATE sudoers_scan_string (yyconst char * yystr )
+{
+
+ return sudoers_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to sudoerslex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE sudoers_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ yy_size_t i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) sudoersalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in sudoers_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = sudoers_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in sudoers_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up sudoerstext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ sudoerstext[sudoersleng] = (yy_hold_char); \
+ (yy_c_buf_p) = sudoerstext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ sudoersleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int sudoersget_lineno (void)
+{
+
+ return sudoerslineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *sudoersget_in (void)
+{
+ return sudoersin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *sudoersget_out (void)
+{
+ return sudoersout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+yy_size_t sudoersget_leng (void)
+{
+ return sudoersleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *sudoersget_text (void)
+{
+ return sudoerstext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void sudoersset_lineno (int line_number )
+{
+
+ sudoerslineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see sudoers_switch_to_buffer
+ */
+void sudoersset_in (FILE * in_str )
+{
+ sudoersin = in_str ;
+}
+
+void sudoersset_out (FILE * out_str )
+{
+ sudoersout = out_str ;
+}
+
+int sudoersget_debug (void)
+{
+ return sudoers_flex_debug;
+}
+
+void sudoersset_debug (int bdebug )
+{
+ sudoers_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from sudoerslex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ sudoersin = stdin;
+ sudoersout = stdout;
+#else
+ sudoersin = (FILE *) 0;
+ sudoersout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * sudoerslex_init()
+ */
+ return 0;
+}
+
+/* sudoerslex_destroy is for both reentrant and non-reentrant scanners. */
+int sudoerslex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ sudoers_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ sudoerspop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ sudoersfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * sudoerslex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *sudoersalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *sudoersrealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void sudoersfree (void * ptr )
+{
+ free( (char *) ptr ); /* see sudoersrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 742 "toke.l"
+
+
+struct path_list {
+ SLIST_ENTRY(path_list) entries;
+ char *path;
+};
+
+SLIST_HEAD(path_list_head, path_list);
+
+struct include_stack {
+ YY_BUFFER_STATE bs;
+ char *path;
+ struct path_list_head more; /* more files in case of includedir */
+ int lineno;
+ bool keepopen;
+};
+
+/*
+ * Compare two struct path_list structs in reverse order.
+ */
+static int
+pl_compare(const void *v1, const void *v2)
+{
+ const struct path_list * const *p1 = v1;
+ const struct path_list * const *p2 = v2;
+
+ return strcmp((*p2)->path, (*p1)->path);
+}
+
+/*
+ * Open dirpath and fill in pathsp with an array of regular files
+ * that do not end in '~' or contain a '.'.
+ * Returns the number of files or -1 on error.
+ * If zero files are found, NULL is stored in pathsp.
+ */
+static int
+read_dir_files(const char *dirpath, struct path_list ***pathsp)
+{
+ DIR *dir;
+ int i, count = 0;
+ int max_paths = 32;
+ struct dirent *dent;
+ struct path_list **paths = NULL;
+ debug_decl(read_dir_files, SUDOERS_DEBUG_PARSER)
+
+ dir = opendir(dirpath);
+ if (dir == NULL) {
+ if (errno == ENOENT)
+ goto done;
+ sudo_warn("%s", dirpath);
+ goto bad;
+ }
+ paths = reallocarray(NULL, max_paths, sizeof(*paths));
+ if (paths == NULL)
+ goto oom;
+ while ((dent = readdir(dir)) != NULL) {
+ struct path_list *pl;
+ struct stat sb;
+ size_t len;
+ char *path;
+
+ /* Ignore files that end in '~' or have a '.' in them. */
+ if (dent->d_name[0] == '\0' || dent->d_name[NAMLEN(dent) - 1] == '~'
+ || strchr(dent->d_name, '.') != NULL) {
+ continue;
+ }
+ len = strlen(dirpath) + 1 + NAMLEN(dent);
+ if ((path = rcstr_alloc(len)) == NULL)
+ goto oom;
+ (void)snprintf(path, len + 1, "%s/%s", dirpath, dent->d_name);
+ if (stat(path, &sb) != 0 || !S_ISREG(sb.st_mode)) {
+ rcstr_delref(path);
+ continue;
+ }
+ pl = malloc(sizeof(*pl));
+ if (pl == NULL) {
+ rcstr_delref(path);
+ goto oom;
+ }
+ pl->path = path;
+ if (count >= max_paths) {
+ struct path_list **tmp;
+ max_paths <<= 1;
+ tmp = reallocarray(paths, max_paths, sizeof(*paths));
+ if (tmp == NULL) {
+ rcstr_delref(path);
+ free(pl);
+ goto oom;
+ }
+ paths = tmp;
+ }
+ paths[count++] = pl;
+ }
+ closedir(dir);
+ if (count == 0) {
+ free(paths);
+ paths = NULL;
+ }
+done:
+ *pathsp = paths;
+ debug_return_int(count);
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+bad:
+ sudoerserror(NULL);
+ if (dir != NULL)
+ closedir(dir);
+ for (i = 0; i < count; i++) {
+ rcstr_delref(paths[i]->path);
+ free(paths[i]);
+ }
+ free(paths);
+ debug_return_int(-1);
+}
+
+/*
+ * Push a list of all files in dirpath onto stack.
+ * Returns the number of files or -1 on error.
+ */
+static int
+switch_dir(struct include_stack *stack, char *dirpath)
+{
+ struct path_list **paths = NULL;
+ int count, i;
+ debug_decl(switch_dir, SUDOERS_DEBUG_PARSER)
+
+ count = read_dir_files(dirpath, &paths);
+ if (count > 0) {
+ /* Sort the list as an array in reverse order. */
+ qsort(paths, count, sizeof(*paths), pl_compare);
+
+ /* Build up the list in sorted order. */
+ for (i = 0; i < count; i++) {
+ SLIST_INSERT_HEAD(&stack->more, paths[i], entries);
+ }
+ free(paths);
+ }
+
+ debug_return_int(count);
+}
+
+#define MAX_SUDOERS_DEPTH 128
+#define SUDOERS_STACK_INCREMENT 16
+
+static size_t istacksize, idepth;
+static struct include_stack *istack;
+static bool keepopen;
+
+void
+init_lexer(void)
+{
+ struct path_list *pl;
+ debug_decl(init_lexer, SUDOERS_DEBUG_PARSER)
+
+ while (idepth) {
+ idepth--;
+ while ((pl = SLIST_FIRST(&istack[idepth].more)) != NULL) {
+ SLIST_REMOVE_HEAD(&istack[idepth].more, entries);
+ rcstr_delref(pl->path);
+ free(pl);
+ }
+ rcstr_delref(istack[idepth].path);
+ if (idepth && !istack[idepth].keepopen)
+ fclose(istack[idepth].bs->yy_input_file);
+ sudoers_delete_buffer(istack[idepth].bs);
+ }
+ free(istack);
+ istack = NULL;
+ istacksize = idepth = 0;
+ sudolineno = 1;
+ keepopen = false;
+ sawspace = false;
+ continued = false;
+ digest_type = -1;
+ prev_state = INITIAL;
+
+ debug_return;
+}
+
+/*
+ * Open an include file (or file from a directory), push the old
+ * sudoers file buffer and switch to the new one.
+ * A missing or insecure include dir is simply ignored.
+ * Returns false on error, else true.
+ */
+static bool
+push_include_int(char *path, bool isdir)
+{
+ struct path_list *pl;
+ FILE *fp;
+ debug_decl(push_include_int, SUDOERS_DEBUG_PARSER)
+
+ /* push current state onto stack */
+ if (idepth >= istacksize) {
+ struct include_stack *new_istack;
+
+ if (idepth > MAX_SUDOERS_DEPTH) {
+ sudoerserror(N_("too many levels of includes"));
+ debug_return_bool(false);
+ }
+ istacksize += SUDOERS_STACK_INCREMENT;
+ new_istack = reallocarray(istack, istacksize, sizeof(*istack));
+ if (new_istack == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sudoerserror(NULL);
+ debug_return_bool(false);
+ }
+ istack = new_istack;
+ }
+ SLIST_INIT(&istack[idepth].more);
+ if (isdir) {
+ struct stat sb;
+ int count, status;
+
+ status = sudo_secure_dir(path, sudoers_uid, sudoers_gid, &sb);
+ if (status != SUDO_PATH_SECURE) {
+ if (sudoers_warnings) {
+ switch (status) {
+ case SUDO_PATH_BAD_TYPE:
+ errno = ENOTDIR;
+ sudo_warn("%s", path);
+ break;
+ case SUDO_PATH_WRONG_OWNER:
+ sudo_warnx(U_("%s is owned by uid %u, should be %u"),
+ path, (unsigned int) sb.st_uid,
+ (unsigned int) sudoers_uid);
+ break;
+ case SUDO_PATH_WORLD_WRITABLE:
+ sudo_warnx(U_("%s is world writable"), path);
+ break;
+ case SUDO_PATH_GROUP_WRITABLE:
+ sudo_warnx(U_("%s is owned by gid %u, should be %u"),
+ path, (unsigned int) sb.st_gid,
+ (unsigned int) sudoers_gid);
+ break;
+ default:
+ break;
+ }
+ }
+ /* A missing or insecure include dir is not a fatal error. */
+ debug_return_bool(true);
+ }
+ count = switch_dir(&istack[idepth], path);
+ if (count <= 0) {
+ /* switch_dir() called sudoerserror() for us */
+ rcstr_delref(path);
+ debug_return_bool(count ? false : true);
+ }
+
+ /* Parse the first dir entry we can open, leave the rest for later. */
+ do {
+ rcstr_delref(path);
+ if ((pl = SLIST_FIRST(&istack[idepth].more)) == NULL) {
+ /* Unable to open any files in include dir, not an error. */
+ debug_return_bool(true);
+ }
+ SLIST_REMOVE_HEAD(&istack[idepth].more, entries);
+ path = pl->path;
+ free(pl);
+ } while ((fp = open_sudoers(path, false, &keepopen)) == NULL);
+ } else {
+ if ((fp = open_sudoers(path, true, &keepopen)) == NULL) {
+ /* The error was already printed by open_sudoers() */
+ sudoerserror(NULL);
+ debug_return_bool(false);
+ }
+ }
+ /* Push the old (current) file and open the new one. */
+ istack[idepth].path = sudoers; /* push old path (and its ref) */
+ istack[idepth].bs = YY_CURRENT_BUFFER;
+ istack[idepth].lineno = sudolineno;
+ istack[idepth].keepopen = keepopen;
+ idepth++;
+ sudolineno = 1;
+ sudoers = path;
+ sudoers_switch_to_buffer(sudoers_create_buffer(fp, YY_BUF_SIZE));
+
+ debug_return_bool(true);
+}
+
+/*
+ * Restore the previous sudoers file and buffer, or, in the case
+ * of an includedir, switch to the next file in the dir.
+ * Returns false if there is nothing to pop, else true.
+ */
+static bool
+pop_include(void)
+{
+ struct path_list *pl;
+ FILE *fp;
+ debug_decl(pop_include, SUDOERS_DEBUG_PARSER)
+
+ if (idepth == 0 || YY_CURRENT_BUFFER == NULL)
+ debug_return_bool(false);
+
+ if (!keepopen)
+ fclose(YY_CURRENT_BUFFER->yy_input_file);
+ sudoers_delete_buffer(YY_CURRENT_BUFFER);
+ /* If we are in an include dir, move to the next file. */
+ while ((pl = SLIST_FIRST(&istack[idepth - 1].more)) != NULL) {
+ SLIST_REMOVE_HEAD(&istack[idepth - 1].more, entries);
+ fp = open_sudoers(pl->path, false, &keepopen);
+ if (fp != NULL) {
+ rcstr_delref(sudoers);
+ sudoers = pl->path;
+ sudolineno = 1;
+ sudoers_switch_to_buffer(sudoers_create_buffer(fp, YY_BUF_SIZE));
+ free(pl);
+ break;
+ }
+ /* Unable to open path in include dir, go to next one. */
+ rcstr_delref(pl->path);
+ free(pl);
+ }
+ /* If no path list, just pop the last dir on the stack. */
+ if (pl == NULL) {
+ idepth--;
+ sudoers_switch_to_buffer(istack[idepth].bs);
+ rcstr_delref(sudoers);
+ sudoers = istack[idepth].path;
+ sudolineno = istack[idepth].lineno;
+ keepopen = istack[idepth].keepopen;
+ }
+ debug_return_bool(true);
+}
+
+static char *
+parse_include_int(const char *base, bool isdir)
+{
+ const char *cp, *ep;
+ char *path, *pp;
+ int dirlen = 0, len = 0, subst = 0;
+ size_t shost_len = 0;
+ debug_decl(parse_include, SUDOERS_DEBUG_PARSER)
+
+ /* Pull out path from #include line. */
+ cp = base + (isdir ? sizeof("#includedir") : sizeof("#include"));
+ while (isblank((unsigned char) *cp))
+ cp++;
+ ep = cp;
+ while (*ep != '\0' && !isspace((unsigned char) *ep)) {
+ if (ep[0] == '%' && ep[1] == 'h') {
+ shost_len = strlen(user_shost);
+ len += shost_len - 2;
+ subst = 1;
+ }
+ ep++;
+ }
+
+ /* Relative paths are located in the same dir as the sudoers file. */
+ if (*cp != '/') {
+ char *dirend = strrchr(sudoers, '/');
+ if (dirend != NULL)
+ dirlen = (int)(dirend - sudoers) + 1;
+ }
+
+ /* Make a copy of the fully-qualified path and return it. */
+ len += (int)(ep - cp);
+ path = pp = rcstr_alloc(len + dirlen);
+ if (path == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sudoerserror(NULL);
+ debug_return_str(NULL);
+ }
+ if (dirlen) {
+ memcpy(path, sudoers, dirlen);
+ pp += dirlen;
+ }
+ if (subst) {
+ /* substitute for %h */
+ while (cp < ep) {
+ if (cp[0] == '%' && cp[1] == 'h') {
+ memcpy(pp, user_shost, shost_len);
+ pp += shost_len;
+ cp += 2;
+ continue;
+ }
+ *pp++ = *cp++;
+ }
+ *pp = '\0';
+ } else {
+ memcpy(pp, cp, len);
+ pp[len] = '\0';
+ }
+
+ /* Push any excess characters (e.g. comment, newline) back to the lexer */
+ if (*ep != '\0')
+ yyless((int)(ep - base));
+
+ debug_return_str(path);
+}
+
+#ifdef TRACELEXER
+int
+sudoers_trace_print(const char *msg)
+{
+ return fputs(msg, stderr);
+}
+#else
+int
+sudoers_trace_print(const char *msg)
+{
+ static bool initialized;
+ static struct sudo_lbuf lbuf;
+
+ if (!initialized) {
+ initialized = true;
+ sudo_lbuf_init(&lbuf, NULL, 0, NULL, 0);
+ }
+
+ sudo_lbuf_append(&lbuf, "%s", msg);
+ /* XXX - assumes a final newline */
+ if (strchr(msg, '\n') != NULL)
+ {
+ sudo_debug_printf2(NULL, NULL, 0, SUDOERS_DEBUG_PARSER|SUDO_DEBUG_DEBUG,
+ "%s:%d %s", sudoers, sudolineno, lbuf.buf);
+ lbuf.len = 0;
+ }
+ return 0;
+}
+#endif /* TRACELEXER */
+
diff --git a/plugins/sudoers/toke.h b/plugins/sudoers/toke.h
new file mode 100644
index 0000000..6c75840
--- /dev/null
+++ b/plugins/sudoers/toke.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011-2013, 2015-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_TOKE_H
+#define SUDOERS_TOKE_H
+
+bool append(const char *, size_t);
+bool fill_args(const char *, size_t, int);
+bool fill_cmnd(const char *, size_t);
+bool fill_txt(const char *, size_t, size_t);
+bool ipv6_valid(const char *s);
+int sudoers_trace_print(const char *msg);
+void sudoerserror(const char *);
+
+#ifndef FLEX_SCANNER
+extern int (*trace_print)(const char *msg);
+#endif
+
+#define fill(a, b) fill_txt(a, b, 0)
+
+#define LEXTRACE(msg) do { \
+ if (trace_print != NULL) \
+ (*trace_print)(msg); \
+} while (0);
+
+#endif /* SUDOERS_TOKE_H */
diff --git a/plugins/sudoers/toke.l b/plugins/sudoers/toke.l
new file mode 100644
index 0000000..d275a26
--- /dev/null
+++ b/plugins/sudoers/toke.l
@@ -0,0 +1,1161 @@
+%{
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2017
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+#include <ctype.h>
+#include "sudoers.h"
+#include "toke.h"
+#include <gram.h>
+#include "sudo_digest.h"
+#include "sudo_lbuf.h"
+
+#if defined(HAVE_STRUCT_DIRENT_D_NAMLEN) && HAVE_STRUCT_DIRENT_D_NAMLEN
+# define NAMLEN(dirent) (dirent)->d_namlen
+#else
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#endif
+
+int sudolineno; /* current sudoers line number. */
+int last_token; /* last token that was parsed. */
+char *sudoers; /* sudoers file being parsed. */
+
+/* Default sudoers path, mode and owner (may be set via sudo.conf) */
+const char *sudoers_file = _PATH_SUDOERS;
+mode_t sudoers_mode = SUDOERS_MODE;
+uid_t sudoers_uid = SUDOERS_UID;
+gid_t sudoers_gid = SUDOERS_GID;
+
+static bool continued, sawspace;
+static int prev_state;
+static int digest_type = -1;
+
+static bool push_include_int(char *, bool);
+static bool pop_include(void);
+static char *parse_include_int(const char *, bool);
+
+int (*trace_print)(const char *msg) = sudoers_trace_print;
+
+#define LEXRETURN(n) do { \
+ last_token = (n); \
+ return (n); \
+} while (0)
+
+#define ECHO ignore_result(fwrite(sudoerstext, sudoersleng, 1, sudoersout))
+
+#define parse_include(_p) (parse_include_int((_p), false))
+#define parse_includedir(_p) (parse_include_int((_p), true))
+#define push_include(_p) (push_include_int((_p), false))
+#define push_includedir(_p) (push_include_int((_p), true))
+%}
+
+HEX16 [0-9A-Fa-f]{1,4}
+OCTET (1?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5])
+IPV4ADDR {OCTET}(\.{OCTET}){3}
+IPV6ADDR ({HEX16}?:){2,7}{HEX16}?|({HEX16}?:){2,6}:{IPV4ADDR}
+
+HOSTNAME [[:alnum:]_-]+
+WORD ([^#>!=:,\(\) \t\n\\\"]|\\[^\n])+
+ID #-?[0-9]+
+PATH \/(\\[\,:= \t#]|[^\,:=\\ \t\n#])+
+ENVAR ([^#!=, \t\n\\\"]|\\[^\n])([^#=, \t\n\\\"]|\\[^\n])*
+DEFVAR [a-z_]+
+
+%option noinput
+%option nounput
+%option noyywrap
+%option prefix="sudoers"
+
+%s GOTDEFS
+%x GOTCMND
+%x STARTDEFS
+%x INDEFS
+%x INSTR
+%s WANTDIGEST
+
+%%
+<GOTDEFS>[[:blank:]]*,[[:blank:]]* {
+ LEXTRACE(", ");
+ LEXRETURN(',');
+ } /* return ',' */
+
+<GOTDEFS>[[:blank:]]+ BEGIN STARTDEFS;
+
+<STARTDEFS>{DEFVAR} {
+ BEGIN INDEFS;
+ LEXTRACE("DEFVAR ");
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXRETURN(DEFVAR);
+ }
+
+<INDEFS>{
+ , {
+ BEGIN STARTDEFS;
+ LEXTRACE(", ");
+ LEXRETURN(',');
+ } /* return ',' */
+
+ = {
+ LEXTRACE("= ");
+ LEXRETURN('=');
+ } /* return '=' */
+
+ \+= {
+ LEXTRACE("+= ");
+ LEXRETURN('+');
+ } /* return '+' */
+
+ -= {
+ LEXTRACE("-= ");
+ LEXRETURN('-');
+ } /* return '-' */
+
+ \" {
+ LEXTRACE("BEGINSTR ");
+ sudoerslval.string = NULL;
+ prev_state = YY_START;
+ BEGIN INSTR;
+ }
+
+ {ENVAR} {
+ LEXTRACE("WORD(2) ");
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXRETURN(WORD);
+ }
+}
+
+<INSTR>{
+ \\[[:blank:]]*\n[[:blank:]]* {
+ /* Line continuation char followed by newline. */
+ sudolineno++;
+ continued = true;
+ }
+
+ \" {
+ LEXTRACE("ENDSTR ");
+ BEGIN prev_state;
+
+ if (sudoerslval.string == NULL) {
+ LEXTRACE("ERROR "); /* empty string */
+ LEXRETURN(ERROR);
+ }
+ if (prev_state == INITIAL) {
+ switch (sudoerslval.string[0]) {
+ case '%':
+ if (sudoerslval.string[1] == '\0' ||
+ (sudoerslval.string[1] == ':' &&
+ sudoerslval.string[2] == '\0')) {
+ LEXTRACE("ERROR "); /* empty group */
+ LEXRETURN(ERROR);
+ }
+ LEXTRACE("USERGROUP ");
+ LEXRETURN(USERGROUP);
+ case '+':
+ if (sudoerslval.string[1] == '\0') {
+ LEXTRACE("ERROR "); /* empty netgroup */
+ LEXRETURN(ERROR);
+ }
+ LEXTRACE("NETGROUP ");
+ LEXRETURN(NETGROUP);
+ }
+ }
+ LEXTRACE("WORD(4) ");
+ LEXRETURN(WORD);
+ }
+
+ \\ {
+ LEXTRACE("BACKSLASH ");
+ if (!append(sudoerstext, sudoersleng))
+ yyterminate();
+ }
+
+ ([^\"\n\\]|\\\")+ {
+ LEXTRACE("STRBODY ");
+ if (!append(sudoerstext, sudoersleng))
+ yyterminate();
+ }
+}
+
+<GOTCMND>{
+ \\[\*\?\[\]\!] {
+ /* quoted fnmatch glob char, pass verbatim */
+ LEXTRACE("QUOTEDCHAR ");
+ if (!fill_args(sudoerstext, 2, sawspace))
+ yyterminate();
+ sawspace = false;
+ }
+
+ \\[:\\,= \t#] {
+ /* quoted sudoers special char, strip backslash */
+ LEXTRACE("QUOTEDCHAR ");
+ if (!fill_args(sudoerstext + 1, 1, sawspace))
+ yyterminate();
+ sawspace = false;
+ }
+
+ [#:\,=\n] {
+ BEGIN INITIAL;
+ yyless(0);
+ LEXRETURN(COMMAND);
+ } /* end of command line args */
+
+ [^#\\:, \t\n]+ {
+ LEXTRACE("ARG ");
+ if (!fill_args(sudoerstext, sudoersleng, sawspace))
+ yyterminate();
+ sawspace = false;
+ } /* a command line arg */
+}
+
+<WANTDIGEST>[[:xdigit:]]+ {
+ /* Only return DIGEST if the length is correct. */
+ yy_size_t digest_len =
+ sudo_digest_getlen(digest_type);
+ if ((yy_size_t)sudoersleng == digest_len * 2) {
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ BEGIN INITIAL;
+ LEXTRACE("DIGEST ");
+ LEXRETURN(DIGEST);
+ }
+ BEGIN INITIAL;
+ yyless(sudoersleng);
+ } /* hex digest */
+
+<WANTDIGEST>[A-Za-z0-9\+/=]+ {
+ /* Only return DIGEST if the length is correct. */
+ yy_size_t len, digest_len =
+ sudo_digest_getlen(digest_type);
+ if (sudoerstext[sudoersleng - 1] == '=') {
+ /* use padding */
+ len = 4 * ((digest_len + 2) / 3);
+ } else {
+ /* no padding */
+ len = (4 * digest_len + 2) / 3;
+ }
+ if ((yy_size_t)sudoersleng == len) {
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ BEGIN INITIAL;
+ LEXTRACE("DIGEST ");
+ LEXRETURN(DIGEST);
+ }
+ BEGIN INITIAL;
+ yyless(sudoersleng);
+ } /* base64 digest */
+
+<INITIAL>^#include[[:blank:]]+.*\n {
+ char *path;
+
+ if (continued) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+
+ if ((path = parse_include(sudoerstext)) == NULL)
+ yyterminate();
+
+ LEXTRACE("INCLUDE\n");
+
+ /* Push current buffer and switch to include file */
+ if (!push_include(path))
+ yyterminate();
+ }
+
+<INITIAL>^#includedir[[:blank:]]+.*\n {
+ char *path;
+
+ if (continued) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+
+ if ((path = parse_includedir(sudoerstext)) == NULL)
+ yyterminate();
+
+ LEXTRACE("INCLUDEDIR\n");
+
+ /*
+ * Push current buffer and switch to include file,
+ * ignoring missing or empty directories.
+ */
+ if (!push_includedir(path))
+ yyterminate();
+ }
+
+<INITIAL>^[[:blank:]]*Defaults([:@>\!][[:blank:]]*\!*\"?({ID}|{WORD}))? {
+ char deftype;
+ int n;
+
+ if (continued) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+
+ for (n = 0; isblank((unsigned char)sudoerstext[n]); n++)
+ continue;
+ n += sizeof("Defaults") - 1;
+ if ((deftype = sudoerstext[n++]) != '\0') {
+ while (isblank((unsigned char)sudoerstext[n]))
+ n++;
+ }
+ BEGIN GOTDEFS;
+ switch (deftype) {
+ case ':':
+ yyless(n);
+ LEXTRACE("DEFAULTS_USER ");
+ LEXRETURN(DEFAULTS_USER);
+ case '>':
+ yyless(n);
+ LEXTRACE("DEFAULTS_RUNAS ");
+ LEXRETURN(DEFAULTS_RUNAS);
+ case '@':
+ yyless(n);
+ LEXTRACE("DEFAULTS_HOST ");
+ LEXRETURN(DEFAULTS_HOST);
+ case '!':
+ yyless(n);
+ LEXTRACE("DEFAULTS_CMND ");
+ LEXRETURN(DEFAULTS_CMND);
+ default:
+ LEXTRACE("DEFAULTS ");
+ LEXRETURN(DEFAULTS);
+ }
+ }
+
+<INITIAL>^[[:blank:]]*(Host|Cmnd|User|Runas)_Alias {
+ int n;
+
+ if (continued) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+
+ for (n = 0; isblank((unsigned char)sudoerstext[n]); n++)
+ continue;
+ switch (sudoerstext[n]) {
+ case 'H':
+ LEXTRACE("HOSTALIAS ");
+ LEXRETURN(HOSTALIAS);
+ case 'C':
+ LEXTRACE("CMNDALIAS ");
+ LEXRETURN(CMNDALIAS);
+ case 'U':
+ LEXTRACE("USERALIAS ");
+ LEXRETURN(USERALIAS);
+ case 'R':
+ LEXTRACE("RUNASALIAS ");
+ LEXRETURN(RUNASALIAS);
+ }
+ }
+
+NOPASSWD[[:blank:]]*: {
+ /* cmnd does not require passwd for this user */
+ LEXTRACE("NOPASSWD ");
+ LEXRETURN(NOPASSWD);
+ }
+
+PASSWD[[:blank:]]*: {
+ /* cmnd requires passwd for this user */
+ LEXTRACE("PASSWD ");
+ LEXRETURN(PASSWD);
+ }
+
+NOEXEC[[:blank:]]*: {
+ LEXTRACE("NOEXEC ");
+ LEXRETURN(NOEXEC);
+ }
+
+EXEC[[:blank:]]*: {
+ LEXTRACE("EXEC ");
+ LEXRETURN(EXEC);
+ }
+
+SETENV[[:blank:]]*: {
+ LEXTRACE("SETENV ");
+ LEXRETURN(SETENV);
+ }
+
+NOSETENV[[:blank:]]*: {
+ LEXTRACE("NOSETENV ");
+ LEXRETURN(NOSETENV);
+ }
+
+LOG_OUTPUT[[:blank:]]*: {
+ LEXTRACE("LOG_OUTPUT ");
+ LEXRETURN(LOG_OUTPUT);
+ }
+
+NOLOG_OUTPUT[[:blank:]]*: {
+ LEXTRACE("NOLOG_OUTPUT ");
+ LEXRETURN(NOLOG_OUTPUT);
+ }
+
+LOG_INPUT[[:blank:]]*: {
+ LEXTRACE("LOG_INPUT ");
+ LEXRETURN(LOG_INPUT);
+ }
+
+NOLOG_INPUT[[:blank:]]*: {
+ LEXTRACE("NOLOG_INPUT ");
+ LEXRETURN(NOLOG_INPUT);
+ }
+
+MAIL[[:blank:]]*: {
+ LEXTRACE("MAIL ");
+ LEXRETURN(MAIL);
+ }
+
+NOMAIL[[:blank:]]*: {
+ LEXTRACE("NOMAIL ");
+ LEXRETURN(NOMAIL);
+ }
+
+FOLLOW[[:blank:]]*: {
+ LEXTRACE("FOLLOW ");
+ LEXRETURN(FOLLOW);
+ }
+
+NOFOLLOW[[:blank:]]*: {
+ LEXTRACE("NOFOLLOW ");
+ LEXRETURN(NOFOLLOW);
+ }
+
+<INITIAL,GOTDEFS>(\+|\%|\%:) {
+ /* empty group or netgroup */
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+
+\+{WORD} {
+ /* netgroup */
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("NETGROUP ");
+ LEXRETURN(NETGROUP);
+ }
+
+\%:?({WORD}|{ID}) {
+ /* group */
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("USERGROUP ");
+ LEXRETURN(USERGROUP);
+ }
+
+{IPV4ADDR}(\/{IPV4ADDR})? {
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("NTWKADDR ");
+ LEXRETURN(NTWKADDR);
+ }
+
+{IPV4ADDR}\/([12]?[0-9]|3[0-2]) {
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("NTWKADDR ");
+ LEXRETURN(NTWKADDR);
+ }
+
+{IPV6ADDR}(\/{IPV6ADDR})? {
+ if (!ipv6_valid(sudoerstext)) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("NTWKADDR ");
+ LEXRETURN(NTWKADDR);
+ }
+
+{IPV6ADDR}\/([0-9]|[1-9][0-9]|1[01][0-9]|12[0-8]) {
+ if (!ipv6_valid(sudoerstext)) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("NTWKADDR ");
+ LEXRETURN(NTWKADDR);
+ }
+
+ALL {
+ LEXTRACE("ALL ");
+ LEXRETURN(ALL);
+
+ }
+
+<INITIAL>TIMEOUT {
+ LEXTRACE("CMND_TIMEOUT ");
+ LEXRETURN(CMND_TIMEOUT);
+ }
+
+<INITIAL>NOTBEFORE {
+ LEXTRACE("NOTBEFORE ");
+ LEXRETURN(NOTBEFORE);
+ }
+
+<INITIAL>NOTAFTER {
+ LEXTRACE("NOTAFTER ");
+ LEXRETURN(NOTAFTER);
+ }
+
+<INITIAL>ROLE {
+#ifdef HAVE_SELINUX
+ LEXTRACE("ROLE ");
+ LEXRETURN(ROLE);
+#else
+ goto got_alias;
+#endif
+ }
+
+<INITIAL>TYPE {
+#ifdef HAVE_SELINUX
+ LEXTRACE("TYPE ");
+ LEXRETURN(TYPE);
+#else
+ goto got_alias;
+#endif
+ }
+<INITIAL>PRIVS {
+#ifdef HAVE_PRIV_SET
+ LEXTRACE("PRIVS ");
+ LEXRETURN(PRIVS);
+#else
+ goto got_alias;
+#endif
+ }
+
+<INITIAL>LIMITPRIVS {
+#ifdef HAVE_PRIV_SET
+ LEXTRACE("LIMITPRIVS ");
+ LEXRETURN(LIMITPRIVS);
+#else
+ goto got_alias;
+#endif
+ }
+
+[[:upper:]][[:upper:][:digit:]_]* {
+ got_alias:
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("ALIAS ");
+ LEXRETURN(ALIAS);
+ }
+
+<GOTDEFS>({PATH}|sudoedit) {
+ /* XXX - no way to specify digest for command */
+ /* no command args allowed for Defaults!/path */
+ if (!fill_cmnd(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("COMMAND ");
+ LEXRETURN(COMMAND);
+ }
+
+sha224 {
+ digest_type = SUDO_DIGEST_SHA224;
+ BEGIN WANTDIGEST;
+ LEXTRACE("SHA224_TOK ");
+ LEXRETURN(SHA224_TOK);
+ }
+
+sha256 {
+ digest_type = SUDO_DIGEST_SHA256;
+ BEGIN WANTDIGEST;
+ LEXTRACE("SHA256_TOK ");
+ LEXRETURN(SHA256_TOK);
+ }
+
+sha384 {
+ digest_type = SUDO_DIGEST_SHA384;
+ BEGIN WANTDIGEST;
+ LEXTRACE("SHA384_TOK ");
+ LEXRETURN(SHA384_TOK);
+ }
+
+sha512 {
+ digest_type = SUDO_DIGEST_SHA512;
+ BEGIN WANTDIGEST;
+ LEXTRACE("SHA512_TOK ");
+ LEXRETURN(SHA512_TOK);
+ }
+
+sudoedit {
+ BEGIN GOTCMND;
+ LEXTRACE("COMMAND ");
+ if (!fill_cmnd(sudoerstext, sudoersleng))
+ yyterminate();
+ } /* sudo -e */
+
+{PATH} {
+ /* directories can't have args... */
+ if (sudoerstext[sudoersleng - 1] == '/') {
+ LEXTRACE("COMMAND ");
+ if (!fill_cmnd(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXRETURN(COMMAND);
+ } else {
+ BEGIN GOTCMND;
+ LEXTRACE("COMMAND ");
+ if (!fill_cmnd(sudoerstext, sudoersleng))
+ yyterminate();
+ }
+ } /* a pathname */
+
+<INITIAL,GOTDEFS>\" {
+ LEXTRACE("BEGINSTR ");
+ sudoerslval.string = NULL;
+ prev_state = YY_START;
+ BEGIN INSTR;
+ }
+
+<INITIAL,GOTDEFS>({ID}|{WORD}) {
+ /* a word */
+ if (!fill(sudoerstext, sudoersleng))
+ yyterminate();
+ LEXTRACE("WORD(5) ");
+ LEXRETURN(WORD);
+ }
+
+\( {
+ LEXTRACE("( ");
+ LEXRETURN('(');
+ }
+
+\) {
+ LEXTRACE(") ");
+ LEXRETURN(')');
+ }
+
+, {
+ LEXTRACE(", ");
+ LEXRETURN(',');
+ } /* return ',' */
+
+= {
+ LEXTRACE("= ");
+ LEXRETURN('=');
+ } /* return '=' */
+
+: {
+ LEXTRACE(": ");
+ LEXRETURN(':');
+ } /* return ':' */
+
+<*>!+ {
+ if (sudoersleng & 1) {
+ LEXTRACE("!");
+ LEXRETURN('!'); /* return '!' */
+ }
+ }
+
+<*>\n {
+ if (YY_START == INSTR) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR); /* line break in string */
+ }
+ BEGIN INITIAL;
+ sudolineno++;
+ continued = false;
+ LEXTRACE("\n");
+ LEXRETURN(COMMENT);
+ } /* return newline */
+
+<*>[[:blank:]]+ { /* throw away space/tabs */
+ sawspace = true; /* but remember for fill_args */
+ }
+
+<*>\\[[:blank:]]*\n {
+ sawspace = true; /* remember for fill_args */
+ sudolineno++;
+ continued = true;
+ } /* throw away EOL after \ */
+
+<INITIAL,STARTDEFS,INDEFS>#(-[^\n0-9].*|[^\n0-9-].*)?\n? {
+ if (sudoerstext[sudoersleng - 1] == '\n') {
+ /* comment ending in a newline */
+ BEGIN INITIAL;
+ sudolineno++;
+ continued = false;
+ } else if (!feof(yyin)) {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+ LEXTRACE("#\n");
+ LEXRETURN(COMMENT);
+ } /* comment, not uid/gid */
+
+<*>. {
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ } /* parse error */
+
+<*><<EOF>> {
+ if (YY_START != INITIAL) {
+ BEGIN INITIAL;
+ LEXTRACE("ERROR ");
+ LEXRETURN(ERROR);
+ }
+ if (!pop_include())
+ yyterminate();
+ }
+
+%%
+struct path_list {
+ SLIST_ENTRY(path_list) entries;
+ char *path;
+};
+
+SLIST_HEAD(path_list_head, path_list);
+
+struct include_stack {
+ YY_BUFFER_STATE bs;
+ char *path;
+ struct path_list_head more; /* more files in case of includedir */
+ int lineno;
+ bool keepopen;
+};
+
+/*
+ * Compare two struct path_list structs in reverse order.
+ */
+static int
+pl_compare(const void *v1, const void *v2)
+{
+ const struct path_list * const *p1 = v1;
+ const struct path_list * const *p2 = v2;
+
+ return strcmp((*p2)->path, (*p1)->path);
+}
+
+/*
+ * Open dirpath and fill in pathsp with an array of regular files
+ * that do not end in '~' or contain a '.'.
+ * Returns the number of files or -1 on error.
+ * If zero files are found, NULL is stored in pathsp.
+ */
+static int
+read_dir_files(const char *dirpath, struct path_list ***pathsp)
+{
+ DIR *dir;
+ int i, count = 0;
+ int max_paths = 32;
+ struct dirent *dent;
+ struct path_list **paths = NULL;
+ debug_decl(read_dir_files, SUDOERS_DEBUG_PARSER)
+
+ dir = opendir(dirpath);
+ if (dir == NULL) {
+ if (errno == ENOENT)
+ goto done;
+ sudo_warn("%s", dirpath);
+ goto bad;
+ }
+ paths = reallocarray(NULL, max_paths, sizeof(*paths));
+ if (paths == NULL)
+ goto oom;
+ while ((dent = readdir(dir)) != NULL) {
+ struct path_list *pl;
+ struct stat sb;
+ size_t len;
+ char *path;
+
+ /* Ignore files that end in '~' or have a '.' in them. */
+ if (dent->d_name[0] == '\0' || dent->d_name[NAMLEN(dent) - 1] == '~'
+ || strchr(dent->d_name, '.') != NULL) {
+ continue;
+ }
+ len = strlen(dirpath) + 1 + NAMLEN(dent);
+ if ((path = rcstr_alloc(len)) == NULL)
+ goto oom;
+ (void)snprintf(path, len + 1, "%s/%s", dirpath, dent->d_name);
+ if (stat(path, &sb) != 0 || !S_ISREG(sb.st_mode)) {
+ rcstr_delref(path);
+ continue;
+ }
+ pl = malloc(sizeof(*pl));
+ if (pl == NULL) {
+ rcstr_delref(path);
+ goto oom;
+ }
+ pl->path = path;
+ if (count >= max_paths) {
+ struct path_list **tmp;
+ max_paths <<= 1;
+ tmp = reallocarray(paths, max_paths, sizeof(*paths));
+ if (tmp == NULL) {
+ rcstr_delref(path);
+ free(pl);
+ goto oom;
+ }
+ paths = tmp;
+ }
+ paths[count++] = pl;
+ }
+ closedir(dir);
+ if (count == 0) {
+ free(paths);
+ paths = NULL;
+ }
+done:
+ *pathsp = paths;
+ debug_return_int(count);
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+bad:
+ sudoerserror(NULL);
+ if (dir != NULL)
+ closedir(dir);
+ for (i = 0; i < count; i++) {
+ rcstr_delref(paths[i]->path);
+ free(paths[i]);
+ }
+ free(paths);
+ debug_return_int(-1);
+}
+
+/*
+ * Push a list of all files in dirpath onto stack.
+ * Returns the number of files or -1 on error.
+ */
+static int
+switch_dir(struct include_stack *stack, char *dirpath)
+{
+ struct path_list **paths = NULL;
+ int count, i;
+ debug_decl(switch_dir, SUDOERS_DEBUG_PARSER)
+
+ count = read_dir_files(dirpath, &paths);
+ if (count > 0) {
+ /* Sort the list as an array in reverse order. */
+ qsort(paths, count, sizeof(*paths), pl_compare);
+
+ /* Build up the list in sorted order. */
+ for (i = 0; i < count; i++) {
+ SLIST_INSERT_HEAD(&stack->more, paths[i], entries);
+ }
+ free(paths);
+ }
+
+ debug_return_int(count);
+}
+
+#define MAX_SUDOERS_DEPTH 128
+#define SUDOERS_STACK_INCREMENT 16
+
+static size_t istacksize, idepth;
+static struct include_stack *istack;
+static bool keepopen;
+
+void
+init_lexer(void)
+{
+ struct path_list *pl;
+ debug_decl(init_lexer, SUDOERS_DEBUG_PARSER)
+
+ while (idepth) {
+ idepth--;
+ while ((pl = SLIST_FIRST(&istack[idepth].more)) != NULL) {
+ SLIST_REMOVE_HEAD(&istack[idepth].more, entries);
+ rcstr_delref(pl->path);
+ free(pl);
+ }
+ rcstr_delref(istack[idepth].path);
+ if (idepth && !istack[idepth].keepopen)
+ fclose(istack[idepth].bs->yy_input_file);
+ sudoers_delete_buffer(istack[idepth].bs);
+ }
+ free(istack);
+ istack = NULL;
+ istacksize = idepth = 0;
+ sudolineno = 1;
+ keepopen = false;
+ sawspace = false;
+ continued = false;
+ digest_type = -1;
+ prev_state = INITIAL;
+
+ debug_return;
+}
+
+/*
+ * Open an include file (or file from a directory), push the old
+ * sudoers file buffer and switch to the new one.
+ * A missing or insecure include dir is simply ignored.
+ * Returns false on error, else true.
+ */
+static bool
+push_include_int(char *path, bool isdir)
+{
+ struct path_list *pl;
+ FILE *fp;
+ debug_decl(push_include_int, SUDOERS_DEBUG_PARSER)
+
+ /* push current state onto stack */
+ if (idepth >= istacksize) {
+ struct include_stack *new_istack;
+
+ if (idepth > MAX_SUDOERS_DEPTH) {
+ sudoerserror(N_("too many levels of includes"));
+ debug_return_bool(false);
+ }
+ istacksize += SUDOERS_STACK_INCREMENT;
+ new_istack = reallocarray(istack, istacksize, sizeof(*istack));
+ if (new_istack == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sudoerserror(NULL);
+ debug_return_bool(false);
+ }
+ istack = new_istack;
+ }
+ SLIST_INIT(&istack[idepth].more);
+ if (isdir) {
+ struct stat sb;
+ int count, status;
+
+ status = sudo_secure_dir(path, sudoers_uid, sudoers_gid, &sb);
+ if (status != SUDO_PATH_SECURE) {
+ if (sudoers_warnings) {
+ switch (status) {
+ case SUDO_PATH_BAD_TYPE:
+ errno = ENOTDIR;
+ sudo_warn("%s", path);
+ break;
+ case SUDO_PATH_WRONG_OWNER:
+ sudo_warnx(U_("%s is owned by uid %u, should be %u"),
+ path, (unsigned int) sb.st_uid,
+ (unsigned int) sudoers_uid);
+ break;
+ case SUDO_PATH_WORLD_WRITABLE:
+ sudo_warnx(U_("%s is world writable"), path);
+ break;
+ case SUDO_PATH_GROUP_WRITABLE:
+ sudo_warnx(U_("%s is owned by gid %u, should be %u"),
+ path, (unsigned int) sb.st_gid,
+ (unsigned int) sudoers_gid);
+ break;
+ default:
+ break;
+ }
+ }
+ /* A missing or insecure include dir is not a fatal error. */
+ debug_return_bool(true);
+ }
+ count = switch_dir(&istack[idepth], path);
+ if (count <= 0) {
+ /* switch_dir() called sudoerserror() for us */
+ rcstr_delref(path);
+ debug_return_bool(count ? false : true);
+ }
+
+ /* Parse the first dir entry we can open, leave the rest for later. */
+ do {
+ rcstr_delref(path);
+ if ((pl = SLIST_FIRST(&istack[idepth].more)) == NULL) {
+ /* Unable to open any files in include dir, not an error. */
+ debug_return_bool(true);
+ }
+ SLIST_REMOVE_HEAD(&istack[idepth].more, entries);
+ path = pl->path;
+ free(pl);
+ } while ((fp = open_sudoers(path, false, &keepopen)) == NULL);
+ } else {
+ if ((fp = open_sudoers(path, true, &keepopen)) == NULL) {
+ /* The error was already printed by open_sudoers() */
+ sudoerserror(NULL);
+ debug_return_bool(false);
+ }
+ }
+ /* Push the old (current) file and open the new one. */
+ istack[idepth].path = sudoers; /* push old path (and its ref) */
+ istack[idepth].bs = YY_CURRENT_BUFFER;
+ istack[idepth].lineno = sudolineno;
+ istack[idepth].keepopen = keepopen;
+ idepth++;
+ sudolineno = 1;
+ sudoers = path;
+ sudoers_switch_to_buffer(sudoers_create_buffer(fp, YY_BUF_SIZE));
+
+ debug_return_bool(true);
+}
+
+/*
+ * Restore the previous sudoers file and buffer, or, in the case
+ * of an includedir, switch to the next file in the dir.
+ * Returns false if there is nothing to pop, else true.
+ */
+static bool
+pop_include(void)
+{
+ struct path_list *pl;
+ FILE *fp;
+ debug_decl(pop_include, SUDOERS_DEBUG_PARSER)
+
+ if (idepth == 0 || YY_CURRENT_BUFFER == NULL)
+ debug_return_bool(false);
+
+ if (!keepopen)
+ fclose(YY_CURRENT_BUFFER->yy_input_file);
+ sudoers_delete_buffer(YY_CURRENT_BUFFER);
+ /* If we are in an include dir, move to the next file. */
+ while ((pl = SLIST_FIRST(&istack[idepth - 1].more)) != NULL) {
+ SLIST_REMOVE_HEAD(&istack[idepth - 1].more, entries);
+ fp = open_sudoers(pl->path, false, &keepopen);
+ if (fp != NULL) {
+ rcstr_delref(sudoers);
+ sudoers = pl->path;
+ sudolineno = 1;
+ sudoers_switch_to_buffer(sudoers_create_buffer(fp, YY_BUF_SIZE));
+ free(pl);
+ break;
+ }
+ /* Unable to open path in include dir, go to next one. */
+ rcstr_delref(pl->path);
+ free(pl);
+ }
+ /* If no path list, just pop the last dir on the stack. */
+ if (pl == NULL) {
+ idepth--;
+ sudoers_switch_to_buffer(istack[idepth].bs);
+ rcstr_delref(sudoers);
+ sudoers = istack[idepth].path;
+ sudolineno = istack[idepth].lineno;
+ keepopen = istack[idepth].keepopen;
+ }
+ debug_return_bool(true);
+}
+
+static char *
+parse_include_int(const char *base, bool isdir)
+{
+ const char *cp, *ep;
+ char *path, *pp;
+ int dirlen = 0, len = 0, subst = 0;
+ size_t shost_len = 0;
+ debug_decl(parse_include, SUDOERS_DEBUG_PARSER)
+
+ /* Pull out path from #include line. */
+ cp = base + (isdir ? sizeof("#includedir") : sizeof("#include"));
+ while (isblank((unsigned char) *cp))
+ cp++;
+ ep = cp;
+ while (*ep != '\0' && !isspace((unsigned char) *ep)) {
+ if (ep[0] == '%' && ep[1] == 'h') {
+ shost_len = strlen(user_shost);
+ len += shost_len - 2;
+ subst = 1;
+ }
+ ep++;
+ }
+
+ /* Relative paths are located in the same dir as the sudoers file. */
+ if (*cp != '/') {
+ char *dirend = strrchr(sudoers, '/');
+ if (dirend != NULL)
+ dirlen = (int)(dirend - sudoers) + 1;
+ }
+
+ /* Make a copy of the fully-qualified path and return it. */
+ len += (int)(ep - cp);
+ path = pp = rcstr_alloc(len + dirlen);
+ if (path == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sudoerserror(NULL);
+ debug_return_str(NULL);
+ }
+ if (dirlen) {
+ memcpy(path, sudoers, dirlen);
+ pp += dirlen;
+ }
+ if (subst) {
+ /* substitute for %h */
+ while (cp < ep) {
+ if (cp[0] == '%' && cp[1] == 'h') {
+ memcpy(pp, user_shost, shost_len);
+ pp += shost_len;
+ cp += 2;
+ continue;
+ }
+ *pp++ = *cp++;
+ }
+ *pp = '\0';
+ } else {
+ memcpy(pp, cp, len);
+ pp[len] = '\0';
+ }
+
+ /* Push any excess characters (e.g. comment, newline) back to the lexer */
+ if (*ep != '\0')
+ yyless((int)(ep - base));
+
+ debug_return_str(path);
+}
+
+#ifdef TRACELEXER
+int
+sudoers_trace_print(const char *msg)
+{
+ return fputs(msg, stderr);
+}
+#else
+int
+sudoers_trace_print(const char *msg)
+{
+ static bool initialized;
+ static struct sudo_lbuf lbuf;
+
+ if (!initialized) {
+ initialized = true;
+ sudo_lbuf_init(&lbuf, NULL, 0, NULL, 0);
+ }
+
+ sudo_lbuf_append(&lbuf, "%s", msg);
+ /* XXX - assumes a final newline */
+ if (strchr(msg, '\n') != NULL)
+ {
+ sudo_debug_printf2(NULL, NULL, 0, SUDOERS_DEBUG_PARSER|SUDO_DEBUG_DEBUG,
+ "%s:%d %s", sudoers, sudolineno, lbuf.buf);
+ lbuf.len = 0;
+ }
+ return 0;
+}
+#endif /* TRACELEXER */
diff --git a/plugins/sudoers/toke_util.c b/plugins/sudoers/toke_util.c
new file mode 100644
index 0000000..0c91376
--- /dev/null
+++ b/plugins/sudoers/toke_util.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2016
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+
+#include "sudoers.h"
+#include "toke.h"
+#include <gram.h>
+
+static unsigned int arg_len = 0;
+static unsigned int arg_size = 0;
+
+bool
+fill_txt(const char *src, size_t len, size_t olen)
+{
+ char *dst;
+ int h;
+ debug_decl(fill_txt, SUDOERS_DEBUG_PARSER)
+
+ dst = olen ? realloc(sudoerslval.string, olen + len + 1) : malloc(len + 1);
+ if (dst == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sudoerserror(NULL);
+ debug_return_bool(false);
+ }
+ sudoerslval.string = dst;
+
+ /* Copy the string and collapse any escaped characters. */
+ dst += olen;
+ while (len--) {
+ if (*src == '\\' && len) {
+ if (src[1] == 'x' && len >= 3 && (h = hexchar(src + 2)) != -1) {
+ *dst++ = h;
+ src += 4;
+ len -= 3;
+ } else {
+ src++;
+ len--;
+ *dst++ = *src++;
+ }
+ } else {
+ *dst++ = *src++;
+ }
+ }
+ *dst = '\0';
+ debug_return_bool(true);
+}
+
+bool
+append(const char *src, size_t len)
+{
+ int olen = 0;
+ debug_decl(append, SUDOERS_DEBUG_PARSER)
+
+ if (sudoerslval.string != NULL)
+ olen = strlen(sudoerslval.string);
+
+ debug_return_bool(fill_txt(src, len, olen));
+}
+
+#define SPECIAL(c) \
+ ((c) == ',' || (c) == ':' || (c) == '=' || (c) == ' ' || (c) == '\t' || (c) == '#')
+
+bool
+fill_cmnd(const char *src, size_t len)
+{
+ char *dst;
+ size_t i;
+ debug_decl(fill_cmnd, SUDOERS_DEBUG_PARSER)
+
+ arg_len = arg_size = 0;
+
+ dst = sudoerslval.command.cmnd = malloc(len + 1);
+ if (dst == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sudoerserror(NULL);
+ debug_return_bool(false);
+ }
+ sudoerslval.command.args = NULL;
+
+ /* Copy the string and collapse any escaped sudo-specific characters. */
+ for (i = 0; i < len; i++) {
+ if (src[i] == '\\' && i != len - 1 && SPECIAL(src[i + 1]))
+ *dst++ = src[++i];
+ else
+ *dst++ = src[i];
+ }
+ *dst = '\0';
+
+ debug_return_bool(true);
+}
+
+bool
+fill_args(const char *s, size_t len, int addspace)
+{
+ unsigned int new_len;
+ char *p;
+ debug_decl(fill_args, SUDOERS_DEBUG_PARSER)
+
+ if (arg_size == 0) {
+ addspace = 0;
+ new_len = len;
+ } else
+ new_len = arg_len + len + addspace;
+
+ if (new_len >= arg_size) {
+ /* Allocate in increments of 128 bytes to avoid excessive realloc(). */
+ arg_size = (new_len + 1 + 127) & ~127;
+
+ p = realloc(sudoerslval.command.args, arg_size);
+ if (p == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto bad;
+ } else
+ sudoerslval.command.args = p;
+ }
+
+ /* Efficiently append the arg (with a leading space if needed). */
+ p = sudoerslval.command.args + arg_len;
+ if (addspace)
+ *p++ = ' ';
+ len = arg_size - (p - sudoerslval.command.args);
+ if (strlcpy(p, s, len) >= len) {
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ goto bad;
+ }
+ arg_len = new_len;
+ debug_return_bool(true);
+bad:
+ sudoerserror(NULL);
+ free(sudoerslval.command.args);
+ sudoerslval.command.args = NULL;
+ arg_len = arg_size = 0;
+ debug_return_bool(false);
+}
+
+/*
+ * Check to make sure an IPv6 address does not contain multiple instances
+ * of the string "::". Assumes strlen(s) >= 1.
+ * Returns true if address is valid else false.
+ */
+bool
+ipv6_valid(const char *s)
+{
+ int nmatch = 0;
+ debug_decl(ipv6_valid, SUDOERS_DEBUG_PARSER)
+
+ for (; *s != '\0'; s++) {
+ if (s[0] == ':' && s[1] == ':') {
+ if (++nmatch > 1)
+ break;
+ }
+ if (s[0] == '/')
+ nmatch = 0; /* reset if we hit netmask */
+ }
+
+ debug_return_bool(nmatch <= 1);
+}
diff --git a/plugins/sudoers/tsdump.c b/plugins/sudoers/tsdump.c
new file mode 100644
index 0000000..91a26ce
--- /dev/null
+++ b/plugins/sudoers/tsdump.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "sudoers.h"
+#include "check.h"
+
+struct timestamp_entry_common {
+ unsigned short version; /* version number */
+ unsigned short size; /* entry size */
+ unsigned short type; /* TS_GLOBAL, TS_TTY, TS_PPID */
+ unsigned short flags; /* TS_DISABLED, TS_ANYUID */
+};
+
+union timestamp_entry_storage {
+ struct timestamp_entry_common common;
+ struct timestamp_entry_v1 v1;
+ struct timestamp_entry v2;
+};
+
+__dso_public int main(int argc, char *argv[]);
+
+static void usage(void) __attribute__((__noreturn__));
+static void dump_entry(struct timestamp_entry *entry, off_t pos);
+static bool valid_entry(union timestamp_entry_storage *u, off_t pos);
+static bool convert_entry(union timestamp_entry_storage *record, struct timespec *off);
+
+/*
+ * tsdump: a simple utility to dump the contents of a time stamp file.
+ * Unlock sudo, does not perform any locking of the time stamp file.
+ */
+
+int
+main(int argc, char *argv[])
+{
+ int ch, fd;
+ const char *user = NULL;
+ char *fname = NULL;
+ union timestamp_entry_storage cur;
+ struct timespec now, timediff;
+ debug_decl(main, SUDOERS_DEBUG_MAIN)
+
+#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
+ malloc_options = "S";
+#endif
+
+ initprogname(argc > 0 ? argv[0] : "tsdump");
+
+ bindtextdomain("sudoers", LOCALEDIR);
+ textdomain("sudoers");
+
+ /* Initialize the debug subsystem. */
+ if (sudo_conf_read(NULL, SUDO_CONF_DEBUG) == -1)
+ exit(EXIT_FAILURE);
+ sudoers_debug_register(getprogname(), sudo_conf_debug_files(getprogname()));
+
+ while ((ch = getopt(argc, argv, "f:u:")) != -1) {
+ switch (ch) {
+ case 'f':
+ fname = optarg;
+ break;
+ case 'u':
+ user = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (fname != NULL && user != NULL) {
+ sudo_warnx("the -f and -u flags are mutually exclusive");
+ usage();
+ }
+
+ /* Calculate the difference between real time and mono time. */
+ if (sudo_gettime_real(&now) == -1)
+ sudo_fatal("unable to get current time");
+ if (sudo_gettime_mono(&timediff) == -1)
+ sudo_fatal("unable to read the clock");
+ sudo_timespecsub(&now, &timediff, &timediff);
+
+ if (fname == NULL) {
+ struct passwd *pw;
+
+ if (user == NULL) {
+ if ((pw = getpwuid(geteuid())) == NULL)
+ sudo_fatalx(U_("unknown uid: %u"), (unsigned int)geteuid());
+ user = pw->pw_name;
+ }
+ if (asprintf(&fname, "%s/%s", _PATH_SUDO_TIMEDIR, user) == -1)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ }
+
+ fd = open(fname, O_RDONLY);
+ if (fd == -1)
+ sudo_fatal(U_("unable to open %s"), fname);
+
+ for (;;) {
+ off_t pos = lseek(fd, 0, SEEK_CUR);
+ ssize_t nread;
+ bool valid;
+
+ if ((nread = read(fd, &cur, sizeof(cur))) == 0)
+ break;
+ if (nread == -1)
+ sudo_fatal(U_("unable to read %s"), fname);
+
+ valid = valid_entry(&cur, pos);
+ if (cur.common.size != 0 && cur.common.size != sizeof(cur)) {
+ off_t offset = (off_t)cur.common.size - (off_t)sizeof(cur);
+ if (lseek(fd, offset, SEEK_CUR) == -1)
+ sudo_fatal("unable to seek %d bytes", (int)offset);
+ }
+ if (valid) {
+ /* Convert entry to latest version as needed. */
+ if (!convert_entry(&cur, &timediff))
+ continue;
+ dump_entry(&cur.v2, pos);
+ }
+ }
+
+ return 0;
+}
+
+static bool
+valid_entry(union timestamp_entry_storage *u, off_t pos)
+{
+ struct timestamp_entry *entry = (struct timestamp_entry *)u;
+ debug_decl(valid_entry, SUDOERS_DEBUG_UTIL)
+
+ switch (entry->version) {
+ case 1:
+ if (entry->size != sizeof(struct timestamp_entry_v1)) {
+ printf("wrong sized v1 record @ %lld, got %hu, expected %zu\n",
+ (long long)pos, entry->size, sizeof(struct timestamp_entry_v1));
+ debug_return_bool(false);
+ }
+ break;
+ case 2:
+ if (entry->size != sizeof(struct timestamp_entry)) {
+ printf("wrong sized v2 record @ %lld, got %hu, expected %zu\n",
+ (long long)pos, entry->size, sizeof(struct timestamp_entry));
+ debug_return_bool(false);
+ }
+ break;
+ default:
+ printf("unknown time stamp entry version %d @ %lld\n",
+ (int)entry->version, (long long)pos);
+ debug_return_bool(false);
+ break;
+ }
+ debug_return_bool(true);
+}
+
+static char *
+type2string(int type)
+{
+ static char name[64];
+ debug_decl(type2string, SUDOERS_DEBUG_UTIL)
+
+ switch (type) {
+ case TS_LOCKEXCL:
+ debug_return_str("TS_LOCKEXCL");
+ case TS_GLOBAL:
+ debug_return_str("TS_GLOBAL");
+ case TS_TTY:
+ debug_return_str("TS_TTY");
+ case TS_PPID:
+ debug_return_str("TS_PPID");
+ }
+ snprintf(name, sizeof(name), "UNKNOWN (0x%x)", type);
+ debug_return_str(name);
+}
+
+static void
+print_flags(int flags)
+{
+ bool first = true;
+ debug_decl(print_flags, SUDOERS_DEBUG_UTIL)
+
+ printf("flags: ");
+ if (ISSET(flags, TS_DISABLED)) {
+ printf("%sTS_DISABLED", first ? "" : ", ");
+ CLR(flags, TS_DISABLED);
+ first = false;
+ }
+ if (ISSET(flags, TS_ANYUID)) {
+ /* TS_ANYUID should never appear on disk. */
+ printf("%sTS_ANYUID", first ? "" : ", ");
+ CLR(flags, TS_ANYUID);
+ first = false;
+ }
+ if (flags != 0)
+ printf("%s0x%x", first ? "" : ", ", flags);
+ putchar('\n');
+
+ debug_return;
+}
+
+/*
+ * Convert an older entry to current.
+ * Also adjusts time stamps on Linux to be wallclock time.
+ */
+static bool
+convert_entry(union timestamp_entry_storage *record, struct timespec *off)
+{
+ union timestamp_entry_storage orig;
+ debug_decl(convert_entry, SUDOERS_DEBUG_UTIL)
+
+ if (record->common.version != TS_VERSION) {
+ if (record->common.version != 1) {
+ sudo_warnx("unexpected record version %hu", record->common.version);
+ debug_return_bool(false);
+ }
+
+ /* The first four fields are the same regardless of version. */
+ memcpy(&orig, record, sizeof(union timestamp_entry_storage));
+ record->v2.auth_uid = orig.v1.auth_uid;
+ record->v2.sid = orig.v1.sid;
+ sudo_timespecclear(&record->v2.start_time);
+ record->v2.ts = orig.v1.ts;
+ if (record->common.type == TS_TTY)
+ record->v2.u.ttydev = orig.v1.u.ttydev;
+ else if (record->common.type == TS_PPID)
+ record->v2.u.ppid = orig.v1.u.ppid;
+ else
+ memset(&record->v2.u, 0, sizeof(record->v2.u));
+ }
+
+ /* On Linux, start time is relative to boot time, adjust to real time. */
+#ifdef __linux__
+ if (sudo_timespecisset(&record->v2.start_time))
+ sudo_timespecadd(&record->v2.start_time, off, &record->v2.start_time);
+#endif
+
+ /* Adjust time stamp from mono time to real time. */
+ if (sudo_timespecisset(&record->v2.ts))
+ sudo_timespecadd(&record->v2.ts, off, &record->v2.ts);
+
+ debug_return_bool(true);
+}
+
+static void
+dump_entry(struct timestamp_entry *entry, off_t pos)
+{
+ debug_decl(dump_entry, SUDOERS_DEBUG_UTIL)
+
+ printf("position: %lld\n", (long long)pos);
+ printf("version: %hu\n", entry->version);
+ printf("size: %hu\n", entry->size);
+ printf("type: %s\n", type2string(entry->type));
+ print_flags(entry->flags);
+ printf("auth uid: %d\n", (int)entry->auth_uid);
+ printf("session ID: %d\n", (int)entry->sid);
+ if (sudo_timespecisset(&entry->start_time))
+ printf("start time: %s", ctime(&entry->start_time.tv_sec));
+ if (sudo_timespecisset(&entry->ts))
+ printf("time stamp: %s", ctime(&entry->ts.tv_sec));
+ if (entry->type == TS_TTY) {
+ char tty[PATH_MAX];
+ if (sudo_ttyname_dev(entry->u.ttydev, tty, sizeof(tty)) == NULL)
+ printf("terminal: %d\n", (int)entry->u.ttydev);
+ else
+ printf("terminal: %s\n", tty);
+ } else if (entry->type == TS_PPID) {
+ printf("parent pid: %d\n", (int)entry->u.ppid);
+ }
+ printf("\n");
+
+ debug_return;
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s [-f timestamp_file] | [-u username]\n",
+ getprogname());
+ exit(1);
+}
diff --git a/plugins/sudoers/tsgetgrpw.c b/plugins/sudoers/tsgetgrpw.c
new file mode 100644
index 0000000..a500bdf
--- /dev/null
+++ b/plugins/sudoers/tsgetgrpw.c
@@ -0,0 +1,413 @@
+/*
+ * Copyright (c) 2005, 2008, 2010-2015
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+/*
+ * Trivial replacements for the libc get{gr,pw}{uid,nam}() routines
+ * for use by testsudoers in the sudo test harness.
+ * We need our own since many platforms don't provide set{pw,gr}file().
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "tsgetgrpw.h"
+#include "sudoers.h"
+
+#undef GRMEM_MAX
+#define GRMEM_MAX 200
+
+#ifndef UID_MAX
+# define UID_MAX 0xffffffffU
+#endif
+
+#ifndef GID_MAX
+# define GID_MAX UID_MAX
+#endif
+
+static FILE *pwf;
+static const char *pwfile = "/etc/passwd";
+static int pw_stayopen;
+
+static FILE *grf;
+static const char *grfile = "/etc/group";
+static int gr_stayopen;
+
+void setgrfile(const char *);
+void setgrent(void);
+void endgrent(void);
+struct group *getgrent(void);
+struct group *getgrnam(const char *);
+struct group *getgrgid(gid_t);
+
+void setpwfile(const char *);
+void setpwent(void);
+void endpwent(void);
+struct passwd *getpwent(void);
+struct passwd *getpwnam(const char *);
+struct passwd *getpwuid(uid_t);
+
+void
+setpwfile(const char *file)
+{
+ pwfile = file;
+ if (pwf != NULL)
+ endpwent();
+}
+
+void
+setpwent(void)
+{
+ if (pwf == NULL) {
+ pwf = fopen(pwfile, "r");
+ if (pwf != NULL)
+ (void)fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
+ } else {
+ rewind(pwf);
+ }
+ pw_stayopen = 1;
+}
+
+void
+endpwent(void)
+{
+ if (pwf != NULL) {
+ fclose(pwf);
+ pwf = NULL;
+ }
+ pw_stayopen = 0;
+}
+
+struct passwd *
+getpwent(void)
+{
+ static struct passwd pw;
+ static char pwbuf[LINE_MAX];
+ size_t len;
+ id_t id;
+ char *cp, *colon;
+ const char *errstr;
+
+next_entry:
+ if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL)
+ return NULL;
+
+ memset(&pw, 0, sizeof(pw));
+ if ((colon = strchr(cp = colon, ':')) == NULL)
+ goto next_entry;
+ *colon++ = '\0';
+ pw.pw_name = cp;
+ if ((colon = strchr(cp = colon, ':')) == NULL)
+ goto next_entry;
+ *colon++ = '\0';
+ pw.pw_passwd = cp;
+ if ((colon = strchr(cp = colon, ':')) == NULL)
+ goto next_entry;
+ *colon++ = '\0';
+ id = sudo_strtoid(cp, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ goto next_entry;
+ pw.pw_uid = (uid_t)id;
+ if ((colon = strchr(cp = colon, ':')) == NULL)
+ goto next_entry;
+ *colon++ = '\0';
+ id = sudo_strtoid(cp, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ goto next_entry;
+ pw.pw_gid = (gid_t)id;
+ if ((colon = strchr(cp = colon, ':')) == NULL)
+ goto next_entry;
+ *colon++ = '\0';
+ pw.pw_gecos = cp;
+ if ((colon = strchr(cp = colon, ':')) == NULL)
+ goto next_entry;
+ *colon++ = '\0';
+ pw.pw_dir = cp;
+ pw.pw_shell = colon;
+ len = strlen(colon);
+ if (len > 0 && colon[len - 1] == '\n')
+ colon[len - 1] = '\0';
+ return &pw;
+}
+
+struct passwd *
+getpwnam(const char *name)
+{
+ struct passwd *pw;
+
+ if (pwf == NULL) {
+ if ((pwf = fopen(pwfile, "r")) == NULL)
+ return NULL;
+ (void)fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
+ } else {
+ rewind(pwf);
+ }
+ while ((pw = getpwent()) != NULL) {
+ if (strcmp(pw->pw_name, name) == 0)
+ break;
+ }
+ if (!pw_stayopen) {
+ fclose(pwf);
+ pwf = NULL;
+ }
+ return pw;
+}
+
+struct passwd *
+getpwuid(uid_t uid)
+{
+ struct passwd *pw;
+
+ if (pwf == NULL) {
+ if ((pwf = fopen(pwfile, "r")) == NULL)
+ return NULL;
+ (void)fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
+ } else {
+ rewind(pwf);
+ }
+ while ((pw = getpwent()) != NULL) {
+ if (pw->pw_uid == uid)
+ break;
+ }
+ if (!pw_stayopen) {
+ fclose(pwf);
+ pwf = NULL;
+ }
+ return pw;
+}
+
+void
+setgrfile(const char *file)
+{
+ grfile = file;
+ if (grf != NULL)
+ endgrent();
+}
+
+void
+setgrent(void)
+{
+ if (grf == NULL) {
+ grf = fopen(grfile, "r");
+ if (grf != NULL)
+ (void)fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
+ } else {
+ rewind(grf);
+ }
+ gr_stayopen = 1;
+}
+
+void
+endgrent(void)
+{
+ if (grf != NULL) {
+ fclose(grf);
+ grf = NULL;
+ }
+ gr_stayopen = 0;
+}
+
+struct group *
+getgrent(void)
+{
+ static struct group gr;
+ static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
+ size_t len;
+ id_t id;
+ char *cp, *colon;
+ const char *errstr;
+ int n;
+
+next_entry:
+ if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
+ return NULL;
+
+ memset(&gr, 0, sizeof(gr));
+ if ((colon = strchr(cp = colon, ':')) == NULL)
+ goto next_entry;
+ *colon++ = '\0';
+ gr.gr_name = cp;
+ if ((colon = strchr(cp = colon, ':')) == NULL)
+ goto next_entry;
+ *colon++ = '\0';
+ gr.gr_passwd = cp;
+ if ((colon = strchr(cp = colon, ':')) == NULL)
+ goto next_entry;
+ *colon++ = '\0';
+ id = sudo_strtoid(cp, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ goto next_entry;
+ gr.gr_gid = (gid_t)id;
+ len = strlen(colon);
+ if (len > 0 && colon[len - 1] == '\n')
+ colon[len - 1] = '\0';
+ if (*colon != '\0') {
+ char *last;
+
+ gr.gr_mem = gr_mem;
+ cp = strtok_r(colon, ",", &last);
+ for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
+ gr.gr_mem[n] = cp;
+ cp = strtok_r(NULL, ",", &last);
+ }
+ gr.gr_mem[n++] = NULL;
+ } else
+ gr.gr_mem = NULL;
+ return &gr;
+}
+
+struct group *
+getgrnam(const char *name)
+{
+ struct group *gr;
+
+ if (grf == NULL) {
+ if ((grf = fopen(grfile, "r")) == NULL)
+ return NULL;
+ (void)fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
+ } else {
+ rewind(grf);
+ }
+ while ((gr = getgrent()) != NULL) {
+ if (strcmp(gr->gr_name, name) == 0)
+ break;
+ }
+ if (!gr_stayopen) {
+ fclose(grf);
+ grf = NULL;
+ }
+ return gr;
+}
+
+struct group *
+getgrgid(gid_t gid)
+{
+ struct group *gr;
+
+ if (grf == NULL) {
+ if ((grf = fopen(grfile, "r")) == NULL)
+ return NULL;
+ (void)fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
+ } else {
+ rewind(grf);
+ }
+ while ((gr = getgrent()) != NULL) {
+ if (gr->gr_gid == gid)
+ break;
+ }
+ if (!gr_stayopen) {
+ fclose(grf);
+ grf = NULL;
+ }
+ return gr;
+}
+
+/*
+ * Copied from getgrouplist.c
+ */
+int
+sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid,
+ GETGROUPS_T **groupsp, int *ngroupsp)
+{
+ GETGROUPS_T *groups = *groupsp;
+ int grpsize = *ngroupsp;
+ int i, ngroups = 1;
+ int ret = -1;
+ struct group *grp;
+
+ if (groups == NULL) {
+ /* Dynamically-sized group vector. */
+ grpsize = (int)sysconf(_SC_NGROUPS_MAX);
+ if (grpsize < 0)
+ grpsize = NGROUPS_MAX;
+ groups = reallocarray(NULL, grpsize, 4 * sizeof(*groups));
+ if (groups == NULL)
+ return -1;
+ grpsize <<= 2;
+ } else {
+ /* Static group vector. */
+ if (grpsize < 1)
+ return -1;
+ }
+
+ /* We support BSD semantics where the first element is the base gid */
+ groups[0] = basegid;
+
+ setgrent();
+ while ((grp = getgrent()) != NULL) {
+ if (grp->gr_gid == basegid || grp->gr_mem == NULL)
+ continue;
+
+ for (i = 0; grp->gr_mem[i] != NULL; i++) {
+ if (strcmp(name, grp->gr_mem[i]) == 0)
+ break;
+ }
+ if (grp->gr_mem[i] == NULL)
+ continue; /* user not found */
+
+ /* Only add if it is not the same as an existing gid */
+ for (i = 0; i < ngroups; i++) {
+ if (grp->gr_gid == groups[i])
+ break;
+ }
+ if (i == ngroups) {
+ if (ngroups == grpsize) {
+ GETGROUPS_T *tmp;
+
+ if (*groupsp != NULL) {
+ /* Static group vector. */
+ goto done;
+ }
+ tmp = reallocarray(groups, grpsize, 2 * sizeof(*groups));
+ if (tmp == NULL) {
+ free(groups);
+ groups = NULL;
+ ngroups = 0;
+ goto done;
+ }
+ groups = tmp;
+ grpsize <<= 1;
+ }
+ groups[ngroups++] = grp->gr_gid;
+ }
+ }
+ ret = 0;
+
+done:
+ endgrent();
+ *groupsp = groups;
+ *ngroupsp = ngroups;
+
+ return ret;
+}
diff --git a/plugins/sudoers/tsgetgrpw.h b/plugins/sudoers/tsgetgrpw.h
new file mode 100644
index 0000000..c0e008c
--- /dev/null
+++ b/plugins/sudoers/tsgetgrpw.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Trivial replacements for the libc get{gr,pw}{uid,nam}() routines
+ * for use by testsudoers in the sudo test harness.
+ * We need our own since many platforms don't provide set{pw,gr}file().
+ */
+
+#include <config.h>
+
+/*
+ * Define away the system prototypes so we don't have any conflicts.
+ */
+
+#define setgrfile sys_setgrfile
+#define setgrent sys_setgrent
+#define endgrent sys_endgrent
+#define getgrent sys_getgrent
+#define getgrnam sys_getgrnam
+#define getgrgid sys_getgrgid
+
+#define setpwfile sys_setpwfile
+#define setpwent sys_setpwent
+#define endpwent sys_endpwent
+#define getpwent sys_getpwent
+#define getpwnam sys_getpwnam
+#define getpwuid sys_getpwuid
+
+#include <pwd.h>
+#include <grp.h>
+
+#undef setgrfile
+#undef setgrent
+#undef endgrent
+#undef getgrent
+#undef getgrnam
+#undef getgrgid
+
+void setgrfile(const char *);
+void setgrent(void);
+void endgrent(void);
+struct group *getgrent(void);
+struct group *getgrnam(const char *);
+struct group *getgrgid(gid_t);
+
+#undef setpwfile
+#undef setpwent
+#undef endpwent
+#undef getpwent
+#undef getpwnam
+#undef getpwuid
+
+void setpwfile(const char *);
+void setpwent(void);
+void endpwent(void);
+struct passwd *getpwent(void);
+struct passwd *getpwnam(const char *);
+struct passwd *getpwuid(uid_t);
diff --git a/plugins/sudoers/visudo.c b/plugins/sudoers/visudo.c
new file mode 100644
index 0000000..50dda59
--- /dev/null
+++ b/plugins/sudoers/visudo.c
@@ -0,0 +1,1300 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+/*
+ * Lock the sudoers file for safe editing (ala vipw) and check for parse errors.
+ */
+
+#ifdef __TANDEM
+# include <floss.h>
+#endif
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#ifndef __TANDEM
+# include <sys/file.h>
+#endif
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <grp.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "sudoers.h"
+#include "interfaces.h"
+#include "redblack.h"
+#include "sudoers_version.h"
+#include "sudo_conf.h"
+#include <gram.h>
+
+#ifdef HAVE_GETOPT_LONG
+# include <getopt.h>
+# else
+# include "compat/getopt.h"
+#endif /* HAVE_GETOPT_LONG */
+
+struct sudoersfile {
+ TAILQ_ENTRY(sudoersfile) entries;
+ char *path;
+ char *tpath;
+ bool modified;
+ bool doedit;
+ int fd;
+};
+TAILQ_HEAD(sudoersfile_list, sudoersfile);
+
+/*
+ * Function prototypes
+ */
+static void quit(int);
+static int whatnow(void);
+static int check_aliases(bool strict, bool quiet);
+static char *get_editor(int *editor_argc, char ***editor_argv);
+static bool check_syntax(const char *, bool, bool, bool);
+static bool edit_sudoers(struct sudoersfile *, char *, int, char **, int);
+static bool install_sudoers(struct sudoersfile *, bool);
+static int print_unused(struct sudoers_parse_tree *, struct alias *, void *);
+static bool reparse_sudoers(char *, int, char **, bool, bool);
+static int run_command(char *, char **);
+static void parse_sudoers_options(void);
+static void setup_signals(void);
+static void help(void) __attribute__((__noreturn__));
+static void usage(int);
+static void visudo_cleanup(void);
+
+extern void get_hostname(void);
+extern void sudoersrestart(FILE *);
+
+/*
+ * Globals
+ */
+struct sudo_user sudo_user;
+struct passwd *list_pw;
+static struct sudoersfile_list sudoerslist = TAILQ_HEAD_INITIALIZER(sudoerslist);
+static bool checkonly;
+static const char short_opts[] = "cf:hqsVx:";
+static struct option long_opts[] = {
+ { "check", no_argument, NULL, 'c' },
+ { "export", required_argument, NULL, 'x' },
+ { "file", required_argument, NULL, 'f' },
+ { "help", no_argument, NULL, 'h' },
+ { "quiet", no_argument, NULL, 'q' },
+ { "strict", no_argument, NULL, 's' },
+ { "version", no_argument, NULL, 'V' },
+ { NULL, no_argument, NULL, '\0' },
+};
+
+__dso_public int main(int argc, char *argv[]);
+
+int
+main(int argc, char *argv[])
+{
+ struct sudoersfile *sp;
+ char *editor, **editor_argv;
+ const char *export_path = NULL;
+ int ch, oldlocale, editor_argc, exitcode = 0;
+ bool quiet, strict, fflag;
+ debug_decl(main, SUDOERS_DEBUG_MAIN)
+
+#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
+ {
+ extern char *malloc_options;
+ malloc_options = "S";
+ }
+#endif
+
+ initprogname(argc > 0 ? argv[0] : "visudo");
+ if (!sudoers_initlocale(setlocale(LC_ALL, ""), def_sudoers_locale))
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sudo_warn_set_locale_func(sudoers_warn_setlocale);
+ bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have visudo domain */
+ textdomain("sudoers");
+
+ if (argc < 1)
+ usage(1);
+
+ /* Register fatal/fatalx callback. */
+ sudo_fatal_callback_register(visudo_cleanup);
+
+ /* Set sudoers locale callback. */
+ sudo_defs_table[I_SUDOERS_LOCALE].callback = sudoers_locale_callback;
+
+ /* Read debug and plugin sections of sudo.conf. */
+ if (sudo_conf_read(NULL, SUDO_CONF_DEBUG|SUDO_CONF_PLUGINS) == -1)
+ exit(EXIT_FAILURE);
+
+ /* Initialize the debug subsystem. */
+ if (!sudoers_debug_register(getprogname(), sudo_conf_debug_files(getprogname())))
+ exit(EXIT_FAILURE);
+
+ /* Parse sudoers plugin options, if any. */
+ parse_sudoers_options();
+
+ /*
+ * Arg handling.
+ */
+ checkonly = fflag = quiet = strict = false;
+ while ((ch = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
+ switch (ch) {
+ case 'V':
+ (void) printf(_("%s version %s\n"), getprogname(),
+ PACKAGE_VERSION);
+ (void) printf(_("%s grammar version %d\n"), getprogname(),
+ SUDOERS_GRAMMAR_VERSION);
+ goto done;
+ case 'c':
+ checkonly = true; /* check mode */
+ break;
+ case 'f':
+ sudoers_file = optarg; /* sudoers file path */
+ fflag = true;
+ break;
+ case 'h':
+ help();
+ break;
+ case 's':
+ strict = true; /* strict mode */
+ break;
+ case 'q':
+ quiet = true; /* quiet mode */
+ break;
+ case 'x':
+ export_path = optarg;
+ break;
+ default:
+ usage(1);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ /* Check for optional sudoers file argument. */
+ switch (argc) {
+ case 0:
+ break;
+ case 1:
+ /* Only accept sudoers file if no -f was specified. */
+ if (!fflag) {
+ sudoers_file = *argv;
+ fflag = true;
+ }
+ break;
+ default:
+ usage(1);
+ }
+
+ if (export_path != NULL) {
+ /* Backwards compatibility for the time being. */
+ sudo_warnx(U_("the -x option will be removed in a future release"));
+ sudo_warnx(U_("please consider using the cvtsudoers utility instead"));
+ execlp("cvtsudoers", "cvtsudoers", "-f", "json", "-o", export_path,
+ sudoers_file, (char *)0);
+ sudo_fatal(U_("unable to execute %s"), "cvtsudoers");
+ }
+
+ /* Mock up a fake sudo_user struct. */
+ user_cmnd = user_base = "";
+ if (geteuid() == 0) {
+ const char *user = getenv("SUDO_USER");
+ if (user != NULL && *user != '\0')
+ sudo_user.pw = sudo_getpwnam(user);
+ }
+ if (sudo_user.pw == NULL) {
+ if ((sudo_user.pw = sudo_getpwuid(getuid())) == NULL)
+ sudo_fatalx(U_("you do not exist in the %s database"), "passwd");
+ }
+ get_hostname();
+
+ /* Setup defaults data structures. */
+ if (!init_defaults())
+ sudo_fatalx(U_("unable to initialize sudoers default values"));
+
+ if (checkonly) {
+ exitcode = check_syntax(sudoers_file, quiet, strict, fflag) ? 0 : 1;
+ goto done;
+ }
+
+ /*
+ * Parse the existing sudoers file(s) to highlight any existing
+ * errors and to pull in editor and env_editor conf values.
+ */
+ if ((sudoersin = open_sudoers(sudoers_file, true, NULL)) == NULL)
+ exit(1);
+ init_parser(sudoers_file, quiet);
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+ (void) sudoersparse();
+ (void) update_defaults(&parsed_policy, NULL,
+ SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER, quiet);
+ sudoers_setlocale(oldlocale, NULL);
+
+ editor = get_editor(&editor_argc, &editor_argv);
+
+ /* Install signal handlers to clean up temp files if we are killed. */
+ setup_signals();
+
+ /* Edit the sudoers file(s) */
+ TAILQ_FOREACH(sp, &sudoerslist, entries) {
+ if (!sp->doedit)
+ continue;
+ if (sp != TAILQ_FIRST(&sudoerslist)) {
+ printf(_("press return to edit %s: "), sp->path);
+ while ((ch = getchar()) != EOF && ch != '\n')
+ continue;
+ }
+ edit_sudoers(sp, editor, editor_argc, editor_argv, -1);
+ }
+
+ /*
+ * Check edited files for a parse error, re-edit any that fail
+ * and install the edited files as needed.
+ */
+ if (reparse_sudoers(editor, editor_argc, editor_argv, strict, quiet)) {
+ TAILQ_FOREACH(sp, &sudoerslist, entries) {
+ (void) install_sudoers(sp, fflag);
+ }
+ }
+ free(editor);
+
+done:
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);
+ exit(exitcode);
+}
+
+static char *
+get_editor(int *editor_argc, char ***editor_argv)
+{
+ char *editor_path = NULL, **whitelist = NULL;
+ const char *env_editor;
+ static char *files[] = { "+1", "sudoers" };
+ unsigned int whitelist_len = 0;
+ debug_decl(get_editor, SUDOERS_DEBUG_UTIL)
+
+ /* Build up editor whitelist from def_editor unless env_editor is set. */
+ if (!def_env_editor) {
+ const char *cp, *ep;
+ const char *def_editor_end = def_editor + strlen(def_editor);
+
+ /* Count number of entries in whitelist and split into a list. */
+ for (cp = sudo_strsplit(def_editor, def_editor_end, ":", &ep);
+ cp != NULL; cp = sudo_strsplit(NULL, def_editor_end, ":", &ep)) {
+ whitelist_len++;
+ }
+ whitelist = reallocarray(NULL, whitelist_len + 1, sizeof(char *));
+ if (whitelist == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ whitelist_len = 0;
+ for (cp = sudo_strsplit(def_editor, def_editor_end, ":", &ep);
+ cp != NULL; cp = sudo_strsplit(NULL, def_editor_end, ":", &ep)) {
+ whitelist[whitelist_len] = strndup(cp, (size_t)(ep - cp));
+ if (whitelist[whitelist_len] == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ whitelist_len++;
+ }
+ whitelist[whitelist_len] = NULL;
+ }
+
+ editor_path = find_editor(2, files, editor_argc, editor_argv, whitelist,
+ &env_editor, true);
+ if (editor_path == NULL) {
+ if (def_env_editor && env_editor != NULL) {
+ /* We are honoring $EDITOR so this is a fatal error. */
+ sudo_fatalx(U_("specified editor (%s) doesn't exist"), env_editor);
+ }
+ sudo_fatalx(U_("no editor found (editor path = %s)"), def_editor);
+ }
+
+ if (whitelist != NULL) {
+ while (whitelist_len--)
+ free(whitelist[whitelist_len]);
+ free(whitelist);
+ }
+
+ debug_return_str(editor_path);
+}
+
+/*
+ * List of editors that support the "+lineno" command line syntax.
+ * If an entry starts with '*' the tail end of the string is matched.
+ * No other wild cards are supported.
+ */
+static char *lineno_editors[] = {
+ "ex",
+ "nex",
+ "vi",
+ "nvi",
+ "vim",
+ "elvis",
+ "*macs",
+ "mg",
+ "vile",
+ "jove",
+ "pico",
+ "nano",
+ "ee",
+ "joe",
+ "zile",
+ NULL
+};
+
+/*
+ * Check whether or not the specified editor matched lineno_editors[].
+ * Returns true if yes, false if no.
+ */
+static bool
+editor_supports_plus(const char *editor)
+{
+ const char *editor_base = strrchr(editor, '/');
+ const char *cp;
+ char **av;
+ debug_decl(editor_supports_plus, SUDOERS_DEBUG_UTIL)
+
+ if (editor_base != NULL)
+ editor_base++;
+ else
+ editor_base = editor;
+ if (*editor_base == 'r')
+ editor_base++;
+
+ for (av = lineno_editors; (cp = *av) != NULL; av++) {
+ /* We only handle a leading '*' wildcard. */
+ if (*cp == '*') {
+ size_t blen = strlen(editor_base);
+ size_t clen = strlen(++cp);
+ if (blen >= clen) {
+ if (strcmp(cp, editor_base + blen - clen) == 0)
+ break;
+ }
+ } else if (strcmp(cp, editor_base) == 0)
+ break;
+ }
+ debug_return_bool(cp != NULL);
+}
+
+/*
+ * Edit each sudoers file.
+ * Returns true on success, else false.
+ */
+static bool
+edit_sudoers(struct sudoersfile *sp, char *editor, int editor_argc,
+ char **editor_argv, int lineno)
+{
+ int tfd; /* sudoers temp file descriptor */
+ bool modified; /* was the file modified? */
+ int ac; /* argument count */
+ char linestr[64]; /* string version of lineno */
+ struct timespec ts, times[2]; /* time before and after edit */
+ struct timespec orig_mtim; /* starting mtime of sudoers file */
+ off_t orig_size; /* starting size of sudoers file */
+ struct stat sb; /* stat buffer */
+ bool ret = false; /* return value */
+ debug_decl(edit_sudoers, SUDOERS_DEBUG_UTIL)
+
+ if (fstat(sp->fd, &sb) == -1)
+ sudo_fatal(U_("unable to stat %s"), sp->path);
+ orig_size = sb.st_size;
+ mtim_get(&sb, orig_mtim);
+
+ /* Create the temp file if needed and set timestamp. */
+ if (sp->tpath == NULL) {
+ if (asprintf(&sp->tpath, "%s.tmp", sp->path) == -1)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ tfd = open(sp->tpath, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU|S_IRUSR);
+ if (tfd < 0)
+ sudo_fatal("%s", sp->tpath);
+
+ /* Copy sp->path -> sp->tpath and reset the mtime. */
+ if (orig_size != 0) {
+ char buf[4096], lastch = '\0';
+ ssize_t nread;
+
+ (void) lseek(sp->fd, (off_t)0, SEEK_SET);
+ while ((nread = read(sp->fd, buf, sizeof(buf))) > 0) {
+ if (write(tfd, buf, nread) != nread)
+ sudo_fatal(U_("write error"));
+ lastch = buf[nread - 1];
+ }
+
+ /* Add missing newline at EOF if needed. */
+ if (lastch != '\n') {
+ lastch = '\n';
+ if (write(tfd, &lastch, 1) != 1)
+ sudo_fatal(U_("write error"));
+ }
+ }
+ (void) close(tfd);
+ }
+ times[0].tv_sec = times[1].tv_sec = orig_mtim.tv_sec;
+ times[0].tv_nsec = times[1].tv_nsec = orig_mtim.tv_nsec;
+ (void) utimensat(AT_FDCWD, sp->tpath, times, 0);
+
+ /* Disable +lineno if editor doesn't support it. */
+ if (lineno > 0 && !editor_supports_plus(editor))
+ lineno = -1;
+
+ /*
+ * The last 3 slots in the editor argv are: "-- +1 sudoers"
+ * Replace those placeholders with the real values.
+ */
+ ac = editor_argc - 3;
+ if (lineno > 0) {
+ (void)snprintf(linestr, sizeof(linestr), "+%d", lineno);
+ editor_argv[ac++] = linestr;
+ }
+ editor_argv[ac++] = "--";
+ editor_argv[ac++] = sp->tpath;
+ editor_argv[ac++] = NULL;
+
+ /*
+ * Do the edit:
+ * We cannot check the editor's exit value against 0 since
+ * XPG4 specifies that vi's exit value is a function of the
+ * number of errors during editing (?!?!).
+ */
+ if (sudo_gettime_real(&times[0]) == -1) {
+ sudo_warn(U_("unable to read the clock"));
+ goto done;
+ }
+
+ if (run_command(editor, editor_argv) != -1) {
+ if (sudo_gettime_real(&times[1]) == -1) {
+ sudo_warn(U_("unable to read the clock"));
+ goto done;
+ }
+ /*
+ * Sanity checks.
+ */
+ if (stat(sp->tpath, &sb) < 0) {
+ sudo_warnx(U_("unable to stat temporary file (%s), %s unchanged"),
+ sp->tpath, sp->path);
+ goto done;
+ }
+ if (sb.st_size == 0 && orig_size != 0) {
+ /* Avoid accidental zeroing of main sudoers file. */
+ if (sp == TAILQ_FIRST(&sudoerslist)) {
+ sudo_warnx(U_("zero length temporary file (%s), %s unchanged"),
+ sp->tpath, sp->path);
+ goto done;
+ }
+ }
+ } else {
+ sudo_warnx(U_("editor (%s) failed, %s unchanged"), editor, sp->path);
+ goto done;
+ }
+
+ /* Set modified bit if the user changed the file. */
+ modified = true;
+ mtim_get(&sb, ts);
+ if (orig_size == sb.st_size && sudo_timespeccmp(&orig_mtim, &ts, ==)) {
+ /*
+ * If mtime and size match but the user spent no measurable
+ * time in the editor we can't tell if the file was changed.
+ */
+ if (sudo_timespeccmp(&times[0], &times[1], !=))
+ modified = false;
+ }
+
+ /*
+ * If modified in this edit session, mark as modified.
+ */
+ if (modified)
+ sp->modified = modified;
+ else
+ sudo_warnx(U_("%s unchanged"), sp->tpath);
+
+ ret = true;
+done:
+ debug_return_bool(ret);
+}
+
+/*
+ * Check Defaults and Alias entries.
+ * Sets parse_error on error and errorfile/errorlineno if possible.
+ */
+static void
+check_defaults_and_aliases(bool strict, bool quiet)
+{
+ debug_decl(check_defaults_and_aliases, SUDOERS_DEBUG_UTIL)
+
+ if (!check_defaults(&parsed_policy, quiet)) {
+ struct defaults *d;
+ rcstr_delref(errorfile);
+ errorfile = NULL;
+ errorlineno = -1;
+ /* XXX - should edit all files with errors */
+ TAILQ_FOREACH(d, &parsed_policy.defaults, entries) {
+ if (d->error) {
+ /* Defaults parse error, set errorfile/errorlineno. */
+ errorfile = rcstr_addref(d->file);
+ errorlineno = d->lineno;
+ break;
+ }
+ }
+ parse_error = true;
+ } else if (check_aliases(strict, quiet) != 0) {
+ rcstr_delref(errorfile);
+ errorfile = NULL; /* don't know which file */
+ errorlineno = -1;
+ parse_error = true;
+ }
+ debug_return;
+}
+
+/*
+ * Parse sudoers after editing and re-edit any ones that caused a parse error.
+ */
+static bool
+reparse_sudoers(char *editor, int editor_argc, char **editor_argv,
+ bool strict, bool quiet)
+{
+ struct sudoersfile *sp, *last;
+ FILE *fp;
+ int ch, oldlocale;
+ debug_decl(reparse_sudoers, SUDOERS_DEBUG_UTIL)
+
+ /*
+ * Parse the edited sudoers files and do sanity checking
+ */
+ while ((sp = TAILQ_FIRST(&sudoerslist)) != NULL) {
+ last = TAILQ_LAST(&sudoerslist, sudoersfile_list);
+ fp = fopen(sp->tpath, "r+");
+ if (fp == NULL)
+ sudo_fatalx(U_("unable to re-open temporary file (%s), %s unchanged."),
+ sp->tpath, sp->path);
+
+ /* Clean slate for each parse */
+ if (!init_defaults())
+ sudo_fatalx(U_("unable to initialize sudoers default values"));
+ init_parser(sp->path, quiet);
+
+ /* Parse the sudoers temp file(s) */
+ sudoersrestart(fp);
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+ if (sudoersparse() && !parse_error) {
+ sudo_warnx(U_("unabled to parse temporary file (%s), unknown error"),
+ sp->tpath);
+ parse_error = true;
+ rcstr_delref(errorfile);
+ if ((errorfile = rcstr_dup(sp->path)) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ }
+ fclose(sudoersin);
+ if (!parse_error) {
+ (void) update_defaults(&parsed_policy, NULL,
+ SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER, true);
+ check_defaults_and_aliases(strict, quiet);
+ }
+ sudoers_setlocale(oldlocale, NULL);
+
+ /*
+ * Got an error, prompt the user for what to do now.
+ */
+ if (parse_error) {
+ switch (whatnow()) {
+ case 'Q':
+ parse_error = false; /* ignore parse error */
+ break;
+ case 'x':
+ visudo_cleanup(); /* discard changes */
+ debug_return_bool(false);
+ case 'e':
+ default:
+ /* Edit file with the parse error */
+ TAILQ_FOREACH(sp, &sudoerslist, entries) {
+ if (errorfile == NULL || strcmp(sp->path, errorfile) == 0) {
+ edit_sudoers(sp, editor, editor_argc, editor_argv,
+ errorlineno);
+ if (errorfile != NULL)
+ break;
+ }
+ }
+ if (errorfile != NULL && sp == NULL) {
+ sudo_fatalx(U_("internal error, unable to find %s in list!"),
+ sudoers);
+ }
+ break;
+ }
+ }
+
+ /* If any new #include directives were added, edit them too. */
+ if ((sp = TAILQ_NEXT(last, entries)) != NULL) {
+ bool modified = false;
+ do {
+ printf(_("press return to edit %s: "), sp->path);
+ while ((ch = getchar()) != EOF && ch != '\n')
+ continue;
+ edit_sudoers(sp, editor, editor_argc, editor_argv, -1);
+ if (sp->modified)
+ modified = true;
+ } while ((sp = TAILQ_NEXT(sp, entries)) != NULL);
+
+ /* Reparse sudoers if newly added includes were modified. */
+ if (modified)
+ continue;
+ }
+
+ /* If all sudoers files parsed OK we are done. */
+ if (!parse_error)
+ break;
+ }
+
+ debug_return_bool(true);
+}
+
+/*
+ * Set the owner and mode on a sudoers temp file and
+ * move it into place. Returns true on success, else false.
+ */
+static bool
+install_sudoers(struct sudoersfile *sp, bool oldperms)
+{
+ struct stat sb;
+ bool ret = false;
+ debug_decl(install_sudoers, SUDOERS_DEBUG_UTIL)
+
+ if (sp->tpath == NULL)
+ goto done;
+
+ if (!sp->modified) {
+ /*
+ * No changes but fix owner/mode if needed.
+ */
+ (void) unlink(sp->tpath);
+ if (!oldperms && fstat(sp->fd, &sb) != -1) {
+ if (sb.st_uid != sudoers_uid || sb.st_gid != sudoers_gid) {
+ if (chown(sp->path, sudoers_uid, sudoers_gid) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to chown %d:%d %s", __func__,
+ (int)sudoers_uid, (int)sudoers_gid, sp->path);
+ }
+ }
+ if ((sb.st_mode & ACCESSPERMS) != sudoers_mode) {
+ if (chmod(sp->path, sudoers_mode) != 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to chmod 0%o %s", __func__,
+ (int)sudoers_mode, sp->path);
+ }
+ }
+ }
+ ret = true;
+ goto done;
+ }
+
+ /*
+ * Change mode and ownership of temp file so when
+ * we move it to sp->path things are kosher.
+ */
+ if (oldperms) {
+ /* Use perms of the existing file. */
+ if (fstat(sp->fd, &sb) == -1)
+ sudo_fatal(U_("unable to stat %s"), sp->path);
+ if (chown(sp->tpath, sb.st_uid, sb.st_gid) != 0) {
+ sudo_warn(U_("unable to set (uid, gid) of %s to (%u, %u)"),
+ sp->tpath, (unsigned int)sb.st_uid, (unsigned int)sb.st_gid);
+ }
+ if (chmod(sp->tpath, sb.st_mode & ACCESSPERMS) != 0) {
+ sudo_warn(U_("unable to change mode of %s to 0%o"), sp->tpath,
+ (unsigned int)(sb.st_mode & ACCESSPERMS));
+ }
+ } else {
+ if (chown(sp->tpath, sudoers_uid, sudoers_gid) != 0) {
+ sudo_warn(U_("unable to set (uid, gid) of %s to (%u, %u)"),
+ sp->tpath, (unsigned int)sudoers_uid,
+ (unsigned int)sudoers_gid);
+ goto done;
+ }
+ if (chmod(sp->tpath, sudoers_mode) != 0) {
+ sudo_warn(U_("unable to change mode of %s to 0%o"), sp->tpath,
+ (unsigned int)sudoers_mode);
+ goto done;
+ }
+ }
+
+ /*
+ * Now that sp->tpath is sane (parses ok) it needs to be
+ * rename(2)'d to sp->path. If the rename(2) fails we try using
+ * mv(1) in case sp->tpath and sp->path are on different file systems.
+ */
+ if (rename(sp->tpath, sp->path) == 0) {
+ free(sp->tpath);
+ sp->tpath = NULL;
+ } else {
+ if (errno == EXDEV) {
+ char *av[4];
+ sudo_warnx(U_("%s and %s not on the same file system, using mv to rename"),
+ sp->tpath, sp->path);
+
+ /* Build up argument vector for the command */
+ if ((av[0] = strrchr(_PATH_MV, '/')) != NULL)
+ av[0]++;
+ else
+ av[0] = _PATH_MV;
+ av[1] = sp->tpath;
+ av[2] = sp->path;
+ av[3] = NULL;
+
+ /* And run it... */
+ if (run_command(_PATH_MV, av)) {
+ sudo_warnx(U_("command failed: '%s %s %s', %s unchanged"),
+ _PATH_MV, sp->tpath, sp->path, sp->path);
+ (void) unlink(sp->tpath);
+ free(sp->tpath);
+ sp->tpath = NULL;
+ goto done;
+ }
+ free(sp->tpath);
+ sp->tpath = NULL;
+ } else {
+ sudo_warn(U_("error renaming %s, %s unchanged"), sp->tpath, sp->path);
+ (void) unlink(sp->tpath);
+ goto done;
+ }
+ }
+ ret = true;
+done:
+ debug_return_bool(ret);
+}
+
+/*
+ * Assuming a parse error occurred, prompt the user for what they want
+ * to do now. Returns the first letter of their choice.
+ */
+static int
+whatnow(void)
+{
+ int choice, c;
+ debug_decl(whatnow, SUDOERS_DEBUG_UTIL)
+
+ for (;;) {
+ (void) fputs(_("What now? "), stdout);
+ choice = getchar();
+ for (c = choice; c != '\n' && c != EOF;)
+ c = getchar();
+
+ switch (choice) {
+ case EOF:
+ choice = 'x';
+ /* FALLTHROUGH */
+ case 'e':
+ case 'x':
+ case 'Q':
+ debug_return_int(choice);
+ default:
+ (void) puts(_("Options are:\n"
+ " (e)dit sudoers file again\n"
+ " e(x)it without saving changes to sudoers file\n"
+ " (Q)uit and save changes to sudoers file (DANGER!)\n"));
+ }
+ }
+}
+
+/*
+ * Install signal handlers for visudo.
+ */
+static void
+setup_signals(void)
+{
+ struct sigaction sa;
+ debug_decl(setup_signals, SUDOERS_DEBUG_UTIL)
+
+ /*
+ * Setup signal handlers to cleanup nicely.
+ */
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = quit;
+ (void) sigaction(SIGTERM, &sa, NULL);
+ (void) sigaction(SIGHUP, &sa, NULL);
+ (void) sigaction(SIGINT, &sa, NULL);
+ (void) sigaction(SIGQUIT, &sa, NULL);
+
+ debug_return;
+}
+
+static int
+run_command(char *path, char **argv)
+{
+ int status;
+ pid_t pid, rv;
+ debug_decl(run_command, SUDOERS_DEBUG_UTIL)
+
+ switch (pid = sudo_debug_fork()) {
+ case -1:
+ sudo_fatal(U_("unable to execute %s"), path);
+ break; /* NOTREACHED */
+ case 0:
+ closefrom(STDERR_FILENO + 1);
+ execv(path, argv);
+ sudo_warn(U_("unable to run %s"), path);
+ _exit(127);
+ break; /* NOTREACHED */
+ }
+
+ for (;;) {
+ rv = waitpid(pid, &status, 0);
+ if (rv == -1 && errno != EINTR)
+ break;
+ if (rv != -1 && !WIFSTOPPED(status))
+ break;
+ }
+
+ if (rv != -1)
+ rv = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
+ debug_return_int(rv);
+}
+
+static bool
+check_owner(const char *path, bool quiet)
+{
+ struct stat sb;
+ bool ok = true;
+ debug_decl(check_owner, SUDOERS_DEBUG_UTIL)
+
+ if (stat(path, &sb) == 0) {
+ if (sb.st_uid != sudoers_uid || sb.st_gid != sudoers_gid) {
+ ok = false;
+ if (!quiet) {
+ fprintf(stderr,
+ _("%s: wrong owner (uid, gid) should be (%u, %u)\n"),
+ path, (unsigned int)sudoers_uid, (unsigned int)sudoers_gid);
+ }
+ }
+ if ((sb.st_mode & ALLPERMS) != sudoers_mode) {
+ ok = false;
+ if (!quiet) {
+ fprintf(stderr, _("%s: bad permissions, should be mode 0%o\n"),
+ path, (unsigned int)sudoers_mode);
+ }
+ }
+ }
+ debug_return_bool(ok);
+}
+
+static bool
+check_syntax(const char *sudoers_file, bool quiet, bool strict, bool oldperms)
+{
+ bool ok = false;
+ int oldlocale;
+ debug_decl(check_syntax, SUDOERS_DEBUG_UTIL)
+
+ if (strcmp(sudoers_file, "-") == 0) {
+ sudoersin = stdin;
+ sudoers_file = "stdin";
+ } else if ((sudoersin = fopen(sudoers_file, "r")) == NULL) {
+ if (!quiet)
+ sudo_warn(U_("unable to open %s"), sudoers_file);
+ goto done;
+ }
+ if (!init_defaults())
+ sudo_fatalx(U_("unable to initialize sudoers default values"));
+ init_parser(sudoers_file, quiet);
+ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+ if (sudoersparse() && !parse_error) {
+ if (!quiet)
+ sudo_warnx(U_("failed to parse %s file, unknown error"), sudoers_file);
+ parse_error = true;
+ rcstr_delref(errorfile);
+ if ((errorfile = rcstr_dup(sudoers_file)) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ }
+ if (!parse_error) {
+ (void) update_defaults(&parsed_policy, NULL,
+ SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER, true);
+ check_defaults_and_aliases(strict, quiet);
+ }
+ sudoers_setlocale(oldlocale, NULL);
+ ok = !parse_error;
+
+ if (parse_error) {
+ if (!quiet) {
+ if (errorlineno != -1)
+ (void) printf(_("parse error in %s near line %d\n"),
+ errorfile, errorlineno);
+ else if (errorfile != NULL)
+ (void) printf(_("parse error in %s\n"), errorfile);
+ }
+ } else {
+ struct sudoersfile *sp;
+
+ /* Parsed OK, check mode and owner. */
+ if (oldperms || check_owner(sudoers_file, quiet)) {
+ if (!quiet)
+ (void) printf(_("%s: parsed OK\n"), sudoers_file);
+ } else {
+ ok = false;
+ }
+ TAILQ_FOREACH(sp, &sudoerslist, entries) {
+ if (oldperms || check_owner(sp->path, quiet)) {
+ if (!quiet)
+ (void) printf(_("%s: parsed OK\n"), sp->path);
+ } else {
+ ok = false;
+ }
+ }
+ }
+
+done:
+ debug_return_bool(ok);
+}
+
+static bool
+lock_sudoers(struct sudoersfile *entry)
+{
+ int ch;
+ debug_decl(lock_sudoers, SUDOERS_DEBUG_UTIL)
+
+ if (!sudo_lock_file(entry->fd, SUDO_TLOCK)) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ sudo_warnx(U_("%s busy, try again later"), entry->path);
+ debug_return_bool(false);
+ }
+ sudo_warn(U_("unable to lock %s"), entry->path);
+ (void) fputs(_("Edit anyway? [y/N]"), stdout);
+ ch = getchar();
+ if (tolower(ch) != 'y')
+ debug_return_bool(false);
+ }
+ debug_return_bool(true);
+}
+
+/*
+ * Used to open (and lock) the initial sudoers file and to also open
+ * any subsequent files #included via a callback from the parser.
+ */
+FILE *
+open_sudoers(const char *path, bool doedit, bool *keepopen)
+{
+ struct sudoersfile *entry;
+ FILE *fp;
+ int open_flags;
+ debug_decl(open_sudoers, SUDOERS_DEBUG_UTIL)
+
+ if (checkonly)
+ open_flags = O_RDONLY;
+ else
+ open_flags = O_RDWR | O_CREAT;
+
+ /* Check for existing entry */
+ TAILQ_FOREACH(entry, &sudoerslist, entries) {
+ if (strcmp(path, entry->path) == 0)
+ break;
+ }
+ if (entry == NULL) {
+ entry = calloc(1, sizeof(*entry));
+ if (entry == NULL || (entry->path = strdup(path)) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ /* entry->tpath = NULL; */
+ /* entry->modified = false; */
+ entry->doedit = doedit;
+ entry->fd = open(entry->path, open_flags, sudoers_mode);
+ if (entry->fd == -1) {
+ sudo_warn("%s", entry->path);
+ free(entry);
+ debug_return_ptr(NULL);
+ }
+ if (!checkonly && !lock_sudoers(entry))
+ debug_return_ptr(NULL);
+ if ((fp = fdopen(entry->fd, "r")) == NULL)
+ sudo_fatal("%s", entry->path);
+ TAILQ_INSERT_TAIL(&sudoerslist, entry, entries);
+ } else {
+ /* Already exists, open .tmp version if there is one. */
+ if (entry->tpath != NULL) {
+ if ((fp = fopen(entry->tpath, "r")) == NULL)
+ sudo_fatal("%s", entry->tpath);
+ } else {
+ if ((fp = fdopen(entry->fd, "r")) == NULL)
+ sudo_fatal("%s", entry->path);
+ rewind(fp);
+ }
+ }
+ if (keepopen != NULL)
+ *keepopen = true;
+ debug_return_ptr(fp);
+}
+
+static int
+check_alias(char *name, int type, char *file, int lineno, bool strict, bool quiet)
+{
+ struct member *m;
+ struct alias *a;
+ int errors = 0;
+ debug_decl(check_alias, SUDOERS_DEBUG_ALIAS)
+
+ if ((a = alias_get(&parsed_policy, name, type)) != NULL) {
+ /* check alias contents */
+ TAILQ_FOREACH(m, &a->members, entries) {
+ if (m->type != ALIAS)
+ continue;
+ errors += check_alias(m->name, type, a->file, a->lineno, strict, quiet);
+ }
+ alias_put(a);
+ } else {
+ if (!quiet) {
+ if (errno == ELOOP) {
+ fprintf(stderr, strict ?
+ U_("Error: %s:%d cycle in %s \"%s\"") :
+ U_("Warning: %s:%d cycle in %s \"%s\""),
+ file, lineno, alias_type_to_string(type), name);
+ } else {
+ fprintf(stderr, strict ?
+ U_("Error: %s:%d %s \"%s\" referenced but not defined") :
+ U_("Warning: %s:%d %s \"%s\" referenced but not defined"),
+ file, lineno, alias_type_to_string(type), name);
+ }
+ fputc('\n', stderr);
+ if (strict && errorfile == NULL) {
+ errorfile = rcstr_addref(file);
+ errorlineno = lineno;
+ }
+ }
+ errors++;
+ }
+
+ debug_return_int(errors);
+}
+
+/*
+ * Iterate through the sudoers datastructures looking for undefined
+ * aliases or unused aliases.
+ */
+static int
+check_aliases(bool strict, bool quiet)
+{
+ struct rbtree *used_aliases;
+ struct cmndspec *cs;
+ struct member *m;
+ struct privilege *priv;
+ struct userspec *us;
+ int errors = 0;
+ debug_decl(check_aliases, SUDOERS_DEBUG_ALIAS)
+
+ used_aliases = alloc_aliases();
+ if (used_aliases == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+
+ /* Forward check. */
+ TAILQ_FOREACH(us, &parsed_policy.userspecs, entries) {
+ TAILQ_FOREACH(m, &us->users, entries) {
+ if (m->type == ALIAS) {
+ errors += check_alias(m->name, USERALIAS,
+ us->file, us->lineno, strict, quiet);
+ }
+ }
+ TAILQ_FOREACH(priv, &us->privileges, entries) {
+ TAILQ_FOREACH(m, &priv->hostlist, entries) {
+ if (m->type == ALIAS) {
+ errors += check_alias(m->name, HOSTALIAS,
+ us->file, us->lineno, strict, quiet);
+ }
+ }
+ TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
+ if (cs->runasuserlist != NULL) {
+ TAILQ_FOREACH(m, cs->runasuserlist, entries) {
+ if (m->type == ALIAS) {
+ errors += check_alias(m->name, RUNASALIAS,
+ us->file, us->lineno, strict, quiet);
+ }
+ }
+ }
+ if (cs->runasgrouplist != NULL) {
+ TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
+ if (m->type == ALIAS) {
+ errors += check_alias(m->name, RUNASALIAS,
+ us->file, us->lineno, strict, quiet);
+ }
+ }
+ }
+ if ((m = cs->cmnd)->type == ALIAS) {
+ errors += check_alias(m->name, CMNDALIAS,
+ us->file, us->lineno, strict, quiet);
+ }
+ }
+ }
+ }
+
+ /* Reverse check (destructive) */
+ if (!alias_find_used(&parsed_policy, used_aliases))
+ errors++;
+ free_aliases(used_aliases);
+
+ /* If all aliases were referenced we will have an empty tree. */
+ if (!no_aliases(&parsed_policy) && !quiet)
+ alias_apply(&parsed_policy, print_unused, NULL);
+
+ debug_return_int(strict ? errors : 0);
+}
+
+static int
+print_unused(struct sudoers_parse_tree *parse_tree, struct alias *a, void *v)
+{
+ fprintf(stderr, U_("Warning: %s:%d unused %s \"%s\""),
+ a->file, a->lineno, alias_type_to_string(a->type), a->name);
+ fputc('\n', stderr);
+ return 0;
+}
+
+static void
+parse_sudoers_options(void)
+{
+ struct plugin_info_list *plugins;
+ debug_decl(parse_sudoers_options, SUDOERS_DEBUG_UTIL)
+
+ plugins = sudo_conf_plugins();
+ if (plugins) {
+ struct plugin_info *info;
+
+ TAILQ_FOREACH(info, plugins, entries) {
+ if (strcmp(info->symbol_name, "sudoers_policy") == 0)
+ break;
+ }
+ if (info != NULL && info->options != NULL) {
+ char * const *cur;
+
+#define MATCHES(s, v) \
+ (strncmp((s), (v), sizeof(v) - 1) == 0 && (s)[sizeof(v) - 1] != '\0')
+
+ for (cur = info->options; *cur != NULL; cur++) {
+ const char *errstr, *p;
+ id_t id;
+
+ if (MATCHES(*cur, "sudoers_file=")) {
+ sudoers_file = *cur + sizeof("sudoers_file=") - 1;
+ continue;
+ }
+ if (MATCHES(*cur, "sudoers_uid=")) {
+ p = *cur + sizeof("sudoers_uid=") - 1;
+ id = sudo_strtoid(p, NULL, NULL, &errstr);
+ if (errstr == NULL)
+ sudoers_uid = (uid_t) id;
+ continue;
+ }
+ if (MATCHES(*cur, "sudoers_gid=")) {
+ p = *cur + sizeof("sudoers_gid=") - 1;
+ id = sudo_strtoid(p, NULL, NULL, &errstr);
+ if (errstr == NULL)
+ sudoers_gid = (gid_t) id;
+ continue;
+ }
+ if (MATCHES(*cur, "sudoers_mode=")) {
+ p = *cur + sizeof("sudoers_mode=") - 1;
+ id = (id_t) sudo_strtomode(p, &errstr);
+ if (errstr == NULL)
+ sudoers_mode = (mode_t) id;
+ continue;
+ }
+ }
+#undef MATCHES
+ }
+ }
+ debug_return;
+}
+
+/*
+ * Unlink any sudoers temp files that remain.
+ */
+static void
+visudo_cleanup(void)
+{
+ struct sudoersfile *sp;
+
+ TAILQ_FOREACH(sp, &sudoerslist, entries) {
+ if (sp->tpath != NULL)
+ (void) unlink(sp->tpath);
+ }
+}
+
+/*
+ * Unlink sudoers temp files (if any) and exit.
+ */
+static void
+quit(int signo)
+{
+ struct sudoersfile *sp;
+ struct iovec iov[4];
+
+ TAILQ_FOREACH(sp, &sudoerslist, entries) {
+ if (sp->tpath != NULL)
+ (void) unlink(sp->tpath);
+ }
+
+#define emsg " exiting due to signal: "
+ iov[0].iov_base = (char *)getprogname();
+ iov[0].iov_len = strlen(iov[0].iov_base);
+ iov[1].iov_base = emsg;
+ iov[1].iov_len = sizeof(emsg) - 1;
+ iov[2].iov_base = strsignal(signo);
+ iov[2].iov_len = strlen(iov[2].iov_base);
+ iov[3].iov_base = "\n";
+ iov[3].iov_len = 1;
+ ignore_result(writev(STDERR_FILENO, iov, 4));
+ _exit(signo);
+}
+
+static void
+usage(int fatal)
+{
+ (void) fprintf(fatal ? stderr : stdout,
+ "usage: %s [-chqsV] [[-f] sudoers ]\n", getprogname());
+ if (fatal)
+ exit(1);
+}
+
+static void
+help(void)
+{
+ (void) printf(_("%s - safely edit the sudoers file\n\n"), getprogname());
+ usage(0);
+ (void) puts(_("\nOptions:\n"
+ " -c, --check check-only mode\n"
+ " -f, --file=sudoers specify sudoers file location\n"
+ " -h, --help display help message and exit\n"
+ " -q, --quiet less verbose (quiet) syntax error messages\n"
+ " -s, --strict strict syntax checking\n"
+ " -V, --version display version information and exit\n"));
+ exit(0);
+}
diff --git a/plugins/system_group/Makefile.in b/plugins/system_group/Makefile.in
new file mode 100644
index 0000000..6fbb795
--- /dev/null
+++ b/plugins/system_group/Makefile.in
@@ -0,0 +1,204 @@
+#
+# Copyright (c) 2011-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# @configure_input@
+#
+
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+devdir = @devdir@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+incdir = $(top_srcdir)/include
+cross_compiling = @CROSS_COMPILING@
+
+# Compiler & tools to use
+CC = @CC@
+LIBTOOL = @LIBTOOL@
+SED = @SED@
+AWK = @AWK@
+
+# Our install program supports extra flags...
+INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
+INSTALL_OWNER = -o $(install_uid) -g $(install_gid)
+INSTALL_BACKUP = @INSTALL_BACKUP@
+
+# Libraries
+LT_LIBS = $(top_builddir)/lib/util/libsudo_util.la
+LIBS = $(LT_LIBS)
+
+# C preprocessor flags
+CPPFLAGS = -I$(incdir) -I$(top_builddir) -I$(top_srcdir) @CPPFLAGS@
+
+# Usually -O and/or -g
+CFLAGS = @CFLAGS@
+
+# Flags to pass to the link stage
+LDFLAGS = @LDFLAGS@
+LT_LDFLAGS = @LT_LDFLAGS@ @LT_LDEXPORTS@
+
+# Flags to pass to libtool
+LTFLAGS = --tag=disable-static
+
+# Address sanitizer flags
+ASAN_CFLAGS = @ASAN_CFLAGS@
+ASAN_LDFLAGS = @ASAN_LDFLAGS@
+
+# PIE flags
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+
+# Stack smashing protection flags
+SSP_CFLAGS = @SSP_CFLAGS@
+SSP_LDFLAGS = @SSP_LDFLAGS@
+
+# cppcheck options, usually set in the top-level Makefile
+CPPCHECK_OPTS = -q --force --enable=warning,performance,portability --suppress=constStatement --error-exitcode=1 --inline-suppr -Dva_copy=va_copy -U__cplusplus -UQUAD_MAX -UQUAD_MIN -UUQUAD_MAX -U_POSIX_HOST_NAME_MAX -U_POSIX_PATH_MAX -U__NBBY -DNSIG=64
+
+# splint options, usually set in the top-level Makefile
+SPLINT_OPTS = -D__restrict= -checks
+
+# PVS-studio options
+PVS_CFG = $(top_srcdir)/PVS-Studio.cfg
+PVS_IGNORE = 'V707,V011,V002,V536'
+PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE)
+
+# Where to install things...
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+localstatedir = @localstatedir@
+plugindir = @PLUGINDIR@
+
+# File mode and map file to use for shared libraries/objects
+shlib_enable = @SHLIB_ENABLE@
+shlib_mode = @SHLIB_MODE@
+shlib_exp = $(srcdir)/system_group.exp
+shlib_map = system_group.map
+shlib_opt = system_group.opt
+
+# User and group ids the installed files should be "owned" by
+install_uid = 0
+install_gid = 0
+
+#### End of system configuration section. ####
+
+SHELL = @SHELL@
+
+OBJS = system_group.lo
+
+IOBJS = system_group.i
+
+POBJS = system_group.plog
+
+LIBOBJDIR = $(top_builddir)/@ac_config_libobj_dir@/
+
+VERSION = @PACKAGE_VERSION@
+
+all: system_group.la
+
+Makefile: $(srcdir)/Makefile.in
+ cd $(top_builddir) && ./config.status --file plugins/system_group/Makefile
+
+.SUFFIXES: .c .h .i .lo .plog
+
+.c.lo:
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $<
+
+.c.i:
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+
+.i.plog:
+ ifile=$<; rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $${ifile%i}c --i-file $< --output-file $@
+
+$(shlib_map): $(shlib_exp)
+ @$(AWK) 'BEGIN { print "{\n\tglobal:" } { print "\t\t"$$0";" } END { print "\tlocal:\n\t\t*;\n};" }' $(shlib_exp) > $@
+
+$(shlib_opt): $(shlib_exp)
+ @$(SED) 's/^/+e /' $(shlib_exp) > $@
+
+system_group.la: $(OBJS) $(LT_LIBS) @LT_LDDEP@
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LDFLAGS) $(ASAN_LDFLAGS) $(SSP_LDFLAGS) $(LT_LDFLAGS) -o $@ $(OBJS) $(LIBS) -module -avoid-version -rpath $(plugindir) -shrext .so
+
+pre-install:
+
+install: install-plugin
+
+install-dirs:
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(plugindir)
+
+install-binaries:
+
+install-includes:
+
+install-doc:
+
+install-plugin: install-dirs system_group.la
+ if [ X"$(shlib_enable)" = X"yes" ]; then \
+ INSTALL_BACKUP='$(INSTALL_BACKUP)' $(LIBTOOL) $(LTFLAGS) --mode=install $(INSTALL) $(INSTALL_OWNER) -m $(shlib_mode) system_group.la $(DESTDIR)$(plugindir); \
+ fi
+
+uninstall:
+ -$(LIBTOOL) $(LTFLAGS) --mode=uninstall rm -f $(DESTDIR)$(plugindir)/system_group.la
+ -test -z "$(INSTALL_BACKUP)" || \
+ rm -f $(DESTDIR)$(plugindir)/system_group.so$(INSTALL_BACKUP)
+
+splint:
+ splint $(SPLINT_OPTS) -I$(incdir) -I$(top_builddir) -I$(top_srcdir) $(srcdir)/*.c
+
+cppcheck:
+ cppcheck $(CPPCHECK_OPTS) -I$(incdir) -I$(top_builddir) -I$(top_srcdir) $(srcdir)/*.c
+
+pvs-log-files: $(POBJS)
+
+pvs-studio: $(POBJS)
+ plog-converter $(PVS_LOG_OPTS) $(POBJS)
+
+check:
+
+clean:
+ -$(LIBTOOL) $(LTFLAGS) --mode=clean rm -f *.lo *.o *.la *.a *.i *.plog \
+ stamp-* core *.core core.*
+
+mostlyclean: clean
+
+distclean: clean
+ -rm -rf Makefile .libs $(shlib_map) $(shlib_opt)
+
+clobber: distclean
+
+realclean: distclean
+ rm -f TAGS tags
+
+cleandir: realclean
+
+# Autogenerated dependencies, do not modify
+system_group.lo: $(srcdir)/system_group.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/system_group.c
+system_group.i: $(srcdir)/system_group.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+system_group.plog: system_group.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/system_group.c --i-file $< --output-file $@
diff --git a/plugins/system_group/system_group.c b/plugins/system_group/system_group.c
new file mode 100644
index 0000000..b34dea4
--- /dev/null
+++ b/plugins/system_group/system_group.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2010-2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <grp.h>
+#include <pwd.h>
+
+#include "sudo_compat.h"
+#include "sudo_dso.h"
+#include "sudo_plugin.h"
+#include "sudo_util.h"
+
+/*
+ * Sudoers group plugin that does group name-based lookups using the system
+ * group database functions, similar to how sudo behaved prior to 1.7.3.
+ * This can be used on systems where lookups by group ID are problematic.
+ */
+
+static sudo_printf_t sudo_log;
+
+typedef struct group * (*sysgroup_getgrnam_t)(const char *);
+typedef struct group * (*sysgroup_getgrgid_t)(gid_t);
+typedef void (*sysgroup_gr_delref_t)(struct group *);
+
+static sysgroup_getgrnam_t sysgroup_getgrnam;
+static sysgroup_getgrgid_t sysgroup_getgrgid;
+static sysgroup_gr_delref_t sysgroup_gr_delref;
+static bool need_setent;
+
+static int
+sysgroup_init(int version, sudo_printf_t sudo_printf, char *const argv[])
+{
+ void *handle;
+
+ sudo_log = sudo_printf;
+
+ if (SUDO_API_VERSION_GET_MAJOR(version) != GROUP_API_VERSION_MAJOR) {
+ sudo_log(SUDO_CONV_ERROR_MSG,
+ "sysgroup_group: incompatible major version %d, expected %d\n",
+ SUDO_API_VERSION_GET_MAJOR(version),
+ GROUP_API_VERSION_MAJOR);
+ return -1;
+ }
+
+ /* Share group cache with sudo if possible. */
+ handle = sudo_dso_findsym(SUDO_DSO_DEFAULT, "sudo_getgrnam");
+ if (handle != NULL) {
+ sysgroup_getgrnam = (sysgroup_getgrnam_t)handle;
+ } else {
+ sysgroup_getgrnam = (sysgroup_getgrnam_t)getgrnam;
+ need_setent = true;
+ }
+
+ handle = sudo_dso_findsym(SUDO_DSO_DEFAULT, "sudo_getgrgid");
+ if (handle != NULL) {
+ sysgroup_getgrgid = (sysgroup_getgrgid_t)handle;
+ } else {
+ sysgroup_getgrgid = (sysgroup_getgrgid_t)getgrgid;
+ need_setent = true;
+ }
+
+ handle = sudo_dso_findsym(SUDO_DSO_DEFAULT, "sudo_gr_delref");
+ if (handle != NULL)
+ sysgroup_gr_delref = (sysgroup_gr_delref_t)handle;
+
+ if (need_setent)
+ setgrent();
+
+ return true;
+}
+
+static void
+sysgroup_cleanup(void)
+{
+ if (need_setent)
+ endgrent();
+}
+
+/*
+ * Returns true if "user" is a member of "group", else false.
+ */
+static int
+sysgroup_query(const char *user, const char *group, const struct passwd *pwd)
+{
+ char **member;
+ struct group *grp;
+
+ grp = sysgroup_getgrnam(group);
+ if (grp == NULL && group[0] == '#' && group[1] != '\0') {
+ const char *errstr;
+ gid_t gid = sudo_strtoid(group + 1, NULL, NULL, &errstr);
+ if (errstr == NULL)
+ grp = sysgroup_getgrgid(gid);
+ }
+ if (grp != NULL) {
+ if (grp->gr_mem != NULL) {
+ for (member = grp->gr_mem; *member != NULL; member++) {
+ if (strcasecmp(user, *member) == 0) {
+ if (sysgroup_gr_delref)
+ sysgroup_gr_delref(grp);
+ return true;
+ }
+ }
+ }
+ if (sysgroup_gr_delref)
+ sysgroup_gr_delref(grp);
+ }
+
+ return false;
+}
+
+__dso_public struct sudoers_group_plugin group_plugin = {
+ GROUP_API_VERSION,
+ sysgroup_init,
+ sysgroup_cleanup,
+ sysgroup_query
+};
diff --git a/plugins/system_group/system_group.exp b/plugins/system_group/system_group.exp
new file mode 100644
index 0000000..a859d6c
--- /dev/null
+++ b/plugins/system_group/system_group.exp
@@ -0,0 +1 @@
+group_plugin
diff --git a/po/README b/po/README
new file mode 100644
index 0000000..ff9b845
--- /dev/null
+++ b/po/README
@@ -0,0 +1,14 @@
+NLS Translations for sudo are coordinated through the Translation
+Project, at http://translationproject.org/
+
+If you would like to contribute a translation for sudo, please join
+a translation team at the Translation Project instead of contributing
+a po file directly. This will avoid duplicated work if there is
+already a translation in progress. If you would like to become a
+member of a translation team, please follow the instructions at
+http://translationproject.org/html/translators.html
+
+The messages in sudo are split into two domains: sudo and sudoers.
+The former is used by the sudo front-end and utility functions.
+The latter is used by the sudoers policy and I/O logging plug-ins
+as well as the sudoers-specific commands visudo and sudoreplay.
diff --git a/po/ast.mo b/po/ast.mo
new file mode 100644
index 0000000..07aa322
--- /dev/null
+++ b/po/ast.mo
Binary files differ
diff --git a/po/ast.po b/po/ast.po
new file mode 100644
index 0000000..88ccbe6
--- /dev/null
+++ b/po/ast.po
@@ -0,0 +1,928 @@
+# Asturian translation for sudo
+# Portable object template file for sudo
+# This file is put in the public domain.
+#
+# Todd C. Miller <Todd.Miller@sudo.ws>, 2011-2016.
+# enolp <enolp@softastur.org>, 2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-11-08 21:35+0100\n"
+"Last-Translator: enolp <enolp@softastur.org>\n"
+"Language-Team: Asturian <alministradores@softastur.org>\n"
+"Language: ast\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Lokalize 2.0\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "nun pue abrise userdb"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "nun pue cambiase al rexistru «%s» de %s"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "nun pue restaurase'l rexistru"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "nun pue allugase memoria"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "Señal desconocida"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "valor non válidu"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "el valor ye pergrande"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "el valor ye perpequeñu"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "valor non válidu de Path «%s» en %s, llinia %u"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "valor non válidu pa %s «%s» en %s, llinia %u"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "nun se sofita la fonte de grupos «%s» en %s, llinia %u"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "grupos máximos non válidos «%s» en %s, llinia %u"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "nun pue facese stat a %s"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s nun ye un ficheru regular"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s ye propiedá del UID %u, debería ser %u"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "%s ye escribible por tol mundu"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "%s ye escribible pol grupu"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "nun pue abrise %s"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "desconozse la clas d'aniciu de sesión %s"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "nun pue afitase'l contestu d'usuariu"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "nun pue afitase la prioridá del procesu"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "nun pue camudase root a %s"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "nun pue camudase al UID de runas (%u, %u)"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "nun pue camudase al direutoriu %s"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "nun pue afitase'l remanador pa la señal %d"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "nun pue desaniciase PRIV_PROC_EXEC de PRIV_LIMIT"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "fallu na llectura del socketpair"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "nun s'esperaba la triba de rempuesta en backchannel: %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "nun pue amestase l'eventu a la cola"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "nun pue afitase la TTY controladora"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "nun pue crease la tubería"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "nun pue recibise'l mensaxe del pá"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "nun pue biforcase"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "nun pue executase %s"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "nun pue restaurase la etiqueta de TTY"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "el complementu de polítiques falló l'aniciu de la sesión"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "fallu nel bucle d'eventos"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "nun pue restaurase'l remanador pa la señal %d"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "nun pue allguase la PTY"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "nun puen crease ralures"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "nun pue unviase'l mensaxe pa supervisar el procesu"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "fallu en %s, llinia %d mentanto se cargaba'l complementu «%s»"
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s ser propiedá del UID %d"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s namái ha editalu'l dueñu"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "nun pue cargase %s: %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "nun pue alcontrase'l símbolu «%s» en %s"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "desconozse la triba de política %d alcontrada en %s"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "la versión mayor %d (esperábase la %d) del complementu que s'alcontró en %s ye incompatible"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "inorando'l complementu de polítiques «%s» en %s, llinia %d"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "namái podría especificase un complementu de polítiques"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "inorando'l complementu de polítiques duplicáu «%s» en %s, llinia %d"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "inorando'l complementu d'E/S duplicáu «%s» en %s, llinia %d"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "el complementu de polítiques %s nun inclúi un métodu check_policy"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "fallu internu, sobrecarga de %s"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "nome non válidu de variable d'entornu: %s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "l'argumentu pa -C ha ser un númberu mayor o iguar que 3"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "nun podríes especificar les opciones «-i» y «-s»"
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "nun podríes especificar les opciones «-i» y «-E»"
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "la opción «-E» nun ye válida nel mou edición"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "nun podríes especificar les variables d'entornu nel mou edición"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "la opción «-U» namái podría usase xunto cola opción «-l»"
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "les opciones «-A» y «-S» nun podríen usase xuntes"
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit nun se sofita nesta plataforma"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Namái podría especificase una de les opciones -e, -h, -i, -K, -l, -s, -v ó -V"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - edita ficheros como otru usuariu\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - executa un comandu como otru usuariu\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opciones:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "usa un programa auxiliar pa la introducción de contraseñes"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "usa la triba d'autenticación BSD especificada"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "executa'l comandu en segundu planu"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "zarra tolos descriptores de ficheru >= num"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "executa'l comandu cola clas d'aniciu de sesión BSD especificada"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "caltién l'entornu del usuariu al executar el comandu"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "caltién variables d'entornu específiques"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "edita ficheros en cuentes d'executar un comandu"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "executa'l comandu como nome o ID de grupu especificaos"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "afita la variable HOME al direutoriu d'aniciu del usuariu de destín"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "amuesa esti mensaxe d'ayuda y cola"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "executa'l comandu nel agospiu (si lo sofita'l complementu)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "executa la shell d'aniciu de sesión como l'usuariu de destín. Tamién podría especificase un comandu"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "desanicia dafechu'l ficheru de marques de tiempu"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "invalida'l ficheru de marques de tiempu"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "llista los privilexos del usuariu o comprueba un comandu específicu, úsalu dos vegaes pa un formatu más llargu"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "mou non interactivu, nun va entrugase nada"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "caltién el vector de grupos en cuentes d'afitar el del destín"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "usa la contraseña que s'especificare"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "crea'l contestu de seguranza de SELinux con rol especificáu"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "llee la contraseña de magar la entrada estándar"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "executa la shell como l'usuariu de destín, tamién podría especificase un comandu"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "crea'l contestu de seguranza de SELinux cola triba especificada"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "termina'l comandu tres la llende de tiempu especificada"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "nel mou llista, amuesa los privilexos del usuariu"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "executa'l comandu (o edita'l ficheru) como nome o ID d'usuariu especificaos"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "amuesa la información de la versión y cola"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "anueva la marca de tiempu del usuariu ensin executar un comandu"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "dexa de procesar los argumentos de la llinia de comandos"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "nun pue abrise'l sistema d'auditoría"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "nun pue unviase'l mensaxe d'auditoría"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "nun pue facese fgetfilecon a %s"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s camudó les etiquetes"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "nun pue restaurase'l contestu pa %s"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "nun pue abrise %s, nun va reetiquetase la TTY"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s nun ye un preséu de caráuteres, nun va reetiquetase la TTY"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "nun pue consiguise'l contestu actual de la TTY, nun va reetiquetase la TTY"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "desconozse la clas de seguranza «chr_file», nun va reetiquetase la TTY"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "nun pue consiguise'l contestu nuevu de la TTY, nun va reetiquetase la TTY"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "nun pue afitase un contestu nuevu de TTY"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "has especificar un rol pa la triba %s"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "nun pue consiguise la triba predeterminada del rol %s"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "fallu al afitar el rol nuevu %s"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "fallu al afitar la triba nueva %s"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s nun ta nun contestu válidu"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "fallu al consiguir old_context"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "nun pue determinase'l mou obligatoriu."
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "nun pue afitase'l contestu de TTY a %s"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "nun pue afitase'l contestu d'execución a %s"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "nun pue afitase'l contestu de creación de claves a %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "rique polo menos un argumentu"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "el númberu del descriptor de ficheru nun ye válidu: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "nun pue executase %s como una shell d'aniciu de sesión"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "nun pue guardase'l remanador pa la señal %d"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "algamóse la llende del control de recursos"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "l'usuariu «%s» nun ye miembru del proyeutu «%s»"
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "la xera qu'invoca ye final"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "nun pudo xunise al proyeutu «%s»"
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "nun hai dengún conxuntu de recursos qu'aceute los arreyos predeterminaos del proyeutu «%s»"
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "el conxuntu de recursos especificáu nun esiste pal proyeutu «%s»"
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "nun pue arreyase al conxuntu predetermináu de recursos del proyeutu «%s»"
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "setproject falló pal proyeutu «%s»"
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "alvertencia, falló l'asignación del control de recursos pal proyeutu «%s»"
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Versión %s de Sudo\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Opciones de configuración: %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "fallu fatal, nun puen cargase los complementos"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "nun pue aniciase'l complementu de polítiques"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "el complementu nun devolvió un comandu a executar"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "fallu aniciando'l complementu d'E/S %s"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "nun s'esperaba'l mou de sudo 0x%x"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "nun esistes na base de datos %s"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "nun pue determinase la tty"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s ha ser propiedá del UID %d y tener afitáu'l bit setuid"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "l'UID efeutivu nun ye %d, ¿ta %s nun sistema de ficheros cola opción «nosuid» afitada o nun sistema de ficheros NFS ensin privilexos root?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "l'UID efeutivu nun ye %d, ¿ta sudo instaláu como setuid root?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "nun pudierons afitase les IDs de grupu suplementaries"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "nun pue afitase'l GID efeutivu al GID de runas %u"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "nun pue afitase'l GID al GID de runas %u"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "nun s'esperaba la condición de terminación del fíu: %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "al complementu de polítiques %s fálta-y el métodu «check_policy»"
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "el complementu de polítiques %s nun sofita'l llistar privilexos"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "el complementu de polítiques %s nun sofita la opción -v"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "el complementu de polítiques %s nun sofita les opciones -k/-K"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "nun s'alcontró dengún direutoriu temporal escribible"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "nun pue restaurase'l direutoriu actual de trabayu"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s nun ye un ficheru regular"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: nun se permite la edición d'enllaces simbólicos"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: nun se permite la edición de ficheros nun direutoriu escribible"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s: escritura breve"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s quedó ensin modificar"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "%s nun camudó"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "nun pue escribise en %s"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "el conteníu de la sesión d'edición quedó en %s"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "nun pue lleese'l ficheru temporal"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: fallu internu: númberu estrañu de caminos"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: nun puen crease ficheros temporales"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: desconozse'l fallu %d"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "nun puen copiase los ficheros temporales al so allugamientu orixinal"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "nun puen copiase dalgunos ficheros temporales al so allugamientu orixinal"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "nun pue camudase l'UID a root (%u)"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "fallu del complementu: falta la llista de ficheros de sudoedit"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "nun pue lleese'l reló"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "escosó'l tiempu d'espera de la llectura de la contraseña"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "nun s'apurrió denguna contraseña"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "nun pue lleese la contraseña"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "nun hai denguna TTY presente nin s'especificó dengún programa askpass"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "nun s'especificó dengún programa askpass, tenta d'afitar SUDO_ASKPASS"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "nun pue afitase'l GID a %u"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "nun pue afitase l'UID a %u"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "nun pue executase %s"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "nun pue guardase stdin"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "nun pue facese dup2 a stdin"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "nun pue resaturase stdin"
diff --git a/po/ca.mo b/po/ca.mo
new file mode 100644
index 0000000..c677ee8
--- /dev/null
+++ b/po/ca.mo
Binary files differ
diff --git a/po/ca.po b/po/ca.po
new file mode 100644
index 0000000..ac92101
--- /dev/null
+++ b/po/ca.po
@@ -0,0 +1,896 @@
+# translation of sudo to Catalan
+# This file is put in the public domain.
+# Walter Garcia-Fontes <walter.garcia@upf.edu>, 2016.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.19b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2016-11-21 17:45-0700\n"
+"PO-Revision-Date: 2016-12-29 15:48+0100\n"
+"Last-Translator: Walter Garcia-Fontes <walter.garcia@upf.edu>\n"
+"Language-Team: Catalan <ca@dodds.net>\n"
+"Language: ca\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:172
+msgid "unable to open userdb"
+msgstr "no s'ha pogut obrir userdb"
+
+#: lib/util/aix.c:227
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "no s'ha pogut passar al registre \"%s\" per a %s"
+
+#: lib/util/aix.c:252
+msgid "unable to restore registry"
+msgstr "no s'ha pogut restaurar el registre"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:184 lib/util/sudo_conf.c:270 lib/util/sudo_conf.c:347
+#: lib/util/sudo_conf.c:545 src/conversation.c:75 src/exec.c:867
+#: src/exec_common.c:107 src/exec_common.c:123 src/exec_common.c:132
+#: src/exec_pty.c:692 src/exec_pty.c:700 src/exec_pty.c:1163
+#: src/load_plugins.c:52 src/load_plugins.c:65 src/load_plugins.c:215
+#: src/load_plugins.c:238 src/load_plugins.c:303 src/load_plugins.c:318
+#: src/parse_args.c:180 src/parse_args.c:202 src/parse_args.c:370
+#: src/parse_args.c:466 src/parse_args.c:488 src/preserve_fds.c:47
+#: src/preserve_fds.c:130 src/selinux.c:83 src/selinux.c:292 src/selinux.c:415
+#: src/selinux.c:424 src/sesh.c:115 src/sudo.c:397 src/sudo.c:416
+#: src/sudo.c:480 src/sudo.c:602 src/sudo.c:662 src/sudo.c:672 src/sudo.c:692
+#: src/sudo.c:711 src/sudo.c:720 src/sudo.c:729 src/sudo.c:746 src/sudo.c:787
+#: src/sudo.c:797 src/sudo.c:817 src/sudo.c:1238 src/sudo.c:1259
+#: src/sudo.c:1433 src/sudo.c:1527 src/sudo_edit.c:151 src/sudo_edit.c:775
+#: src/sudo_edit.c:872 src/sudo_edit.c:985 src/sudo_edit.c:1005
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/sudo_conf.c:185
+#: lib/util/sudo_conf.c:270 lib/util/sudo_conf.c:347 lib/util/sudo_conf.c:545
+#: src/conversation.c:76 src/exec.c:867 src/exec_common.c:107
+#: src/exec_common.c:124 src/exec_common.c:133 src/exec_pty.c:692
+#: src/exec_pty.c:700 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:180
+#: src/parse_args.c:202 src/parse_args.c:370 src/parse_args.c:466
+#: src/parse_args.c:488 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:83 src/selinux.c:292 src/selinux.c:415 src/selinux.c:424
+#: src/sesh.c:115 src/sudo.c:397 src/sudo.c:416 src/sudo.c:480 src/sudo.c:602
+#: src/sudo.c:817 src/sudo.c:1238 src/sudo.c:1259 src/sudo.c:1433
+#: src/sudo.c:1527 src/sudo_edit.c:151 src/sudo_edit.c:775 src/sudo_edit.c:872
+#: src/sudo_edit.c:985 src/sudo_edit.c:1005
+msgid "unable to allocate memory"
+msgstr "no s'ha pogut assignar memòria"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "Senyal desconegut"
+
+#: lib/util/strtoid.c:76 lib/util/strtoid.c:104 lib/util/strtomode.c:49
+#: lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "valor no vàlid"
+
+#: lib/util/strtoid.c:83 lib/util/strtoid.c:111 lib/util/strtomode.c:55
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "valor massa gran"
+
+#: lib/util/strtoid.c:89 lib/util/strtomode.c:55 lib/util/strtonum.c:61
+#: lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "valor massa petit"
+
+#: lib/util/sudo_conf.c:203
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "valor Path no vàlid «%s» a %s, línia %u"
+
+#: lib/util/sudo_conf.c:369 lib/util/sudo_conf.c:422
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "valor no vàlid per a %s «%s» a %s, línia %u"
+
+#: lib/util/sudo_conf.c:390
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "font de grup no suportat «%s» a %s, línia %u"
+
+#: lib/util/sudo_conf.c:406
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "grups «%s» max no vàlids a %s, línia %u"
+
+#: lib/util/sudo_conf.c:561
+#, c-format
+msgid "unable to stat %s"
+msgstr "no es pot obrir %s"
+
+#: lib/util/sudo_conf.c:564
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s no és un fitxer regular"
+
+#: lib/util/sudo_conf.c:567
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s és propietat de l'uid %u, hauria de ser %u"
+
+#: lib/util/sudo_conf.c:571
+#, c-format
+msgid "%s is world writable"
+msgstr "%s és escrivible per tothom"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "%s is group writable"
+msgstr "%s és escrivible pel grup"
+
+#: lib/util/sudo_conf.c:584 src/selinux.c:201 src/selinux.c:213 src/sudo.c:366
+#, c-format
+msgid "unable to open %s"
+msgstr "no s'ha pogut obrir %s"
+
+#: src/exec.c:115 src/exec.c:117 src/exec.c:122 src/exec.c:408 src/exec.c:410
+#: src/exec.c:412 src/exec.c:414 src/exec.c:416 src/exec.c:418 src/exec.c:421
+#: src/exec.c:437 src/exec.c:439 src/exec.c:600 src/exec.c:794
+#: src/exec_pty.c:464 src/exec_pty.c:730 src/exec_pty.c:800 src/exec_pty.c:802
+#: src/exec_pty.c:814 src/exec_pty.c:816 src/exec_pty.c:1347
+#: src/exec_pty.c:1349 src/exec_pty.c:1354 src/exec_pty.c:1356
+#: src/exec_pty.c:1370 src/exec_pty.c:1381 src/exec_pty.c:1383
+#: src/exec_pty.c:1385 src/exec_pty.c:1387 src/exec_pty.c:1389
+#: src/exec_pty.c:1391 src/exec_pty.c:1393 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "no es pot establir el gestor per al senyal %d"
+
+#: src/exec.c:127 src/exec_pty.c:846 src/exec_pty.c:1431 src/tgetpass.c:250
+msgid "unable to fork"
+msgstr "no s'ha pogut bifurcar"
+
+#: src/exec.c:303 src/exec.c:311 src/exec.c:872 src/exec_pty.c:585
+#: src/exec_pty.c:590 src/exec_pty.c:660 src/exec_pty.c:667 src/exec_pty.c:954
+#: src/exec_pty.c:964 src/exec_pty.c:1009 src/exec_pty.c:1016
+#: src/exec_pty.c:1041 src/exec_pty.c:1496 src/exec_pty.c:1503
+#: src/exec_pty.c:1510
+msgid "unable to add event to queue"
+msgstr "no s'ha pogut afegir un esdeveniment a la cua"
+
+#: src/exec.c:391
+msgid "unable to create sockets"
+msgstr "no s'ha pogut crear el sòcol"
+
+#: src/exec.c:446
+msgid "policy plugin failed session initialization"
+msgstr "el connector de política ha fallat la inicialització de la sessió"
+
+#: src/exec.c:491
+msgid "error in event loop"
+msgstr "error al bucle d'esdeveniment"
+
+#: src/exec.c:509
+msgid "unable to restore tty label"
+msgstr "no s'ha pogut restaurar l'etiqueta tty"
+
+#: src/exec.c:608 src/exec_pty.c:496 src/signal.c:87
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "no s'ha pogut restaurar el gestor per al senyal %d"
+
+#: src/exec.c:726 src/exec_pty.c:1236
+msgid "error reading from signal pipe"
+msgstr "error en llegir del conducte del senyal"
+
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "no s'ha pogut remoure PRIV_PROC_EXEC de PRIV_LIMIT"
+
+#: src/exec_pty.c:188
+msgid "unable to allocate pty"
+msgstr "no s'ha pogut assignar pty"
+
+#: src/exec_pty.c:774 src/exec_pty.c:783 src/exec_pty.c:791
+#: src/exec_pty.c:1339 src/exec_pty.c:1428 src/signal.c:129 src/tgetpass.c:246
+msgid "unable to create pipe"
+msgstr "no s'ha pogut crear un conducte"
+
+#: src/exec_pty.c:1269
+msgid "error reading from pipe"
+msgstr "error en llegir del conducte"
+
+#: src/exec_pty.c:1296
+msgid "error reading from socketpair"
+msgstr "error en llegir del parell de sòcols"
+
+#: src/exec_pty.c:1305
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "tipus de resposta inesperada al canal posterior: %d"
+
+#: src/exec_pty.c:1407
+msgid "unable to set controlling tty"
+msgstr "no s'ha pogut configurar la tty controladora"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "error a %s, línia %d quan s'estava carregant el connector «%s»"
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s ha de ser propietat de l'uid %d"
+
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s ha de ser escrivible únicament pel propietari"
+
+#: src/load_plugins.c:172
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "no s'ha pogut carregar %s: %s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "no s'ha pogut trobar el símbol «%s» a %s"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "s'ha trobat un tipus desconegut de política %d a %s"
+
+#: src/load_plugins.c:193
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "s'ha trobat una versió major %d incompatible de connector (s'esperava %d) a %s"
+
+#: src/load_plugins.c:202
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "s'ignorarà el connector de política «%s» a %s, línia %d"
+
+#: src/load_plugins.c:204
+msgid "only a single policy plugin may be specified"
+msgstr "sols es pot especificar un únic connector de política"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "s'ignorarà el connector entrada/sortida duplicat «%s» a %s, línia %d"
+
+#: src/load_plugins.c:228
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "s'ignorarà el connector entrada/sortida duplica «%s» a %s, línia %d"
+
+#: src/load_plugins.c:331
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "el connector de política %s no inclou un mètode check_policy"
+
+#: src/net_ifs.c:173 src/net_ifs.c:190 src/net_ifs.c:335 src/sudo.c:475
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "error intern, sobreeiximent de %s"
+
+#: src/parse_args.c:239
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "l'argument per a -C ha de ser un número més gran o igual a 3"
+
+#: src/parse_args.c:406
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "no podeu especificar a l'hora les opcions `-i' i `-s'"
+
+#: src/parse_args.c:410
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "no podeu especificar a l'hora les opcons `-i' i `-E'"
+
+#: src/parse_args.c:420
+msgid "the `-E' option is not valid in edit mode"
+msgstr "l'opció `-E' no és vàlida al mode editar"
+
+#: src/parse_args.c:422
+msgid "you may not specify environment variables in edit mode"
+msgstr "no podeu especificar variables d'entorn al mode editar"
+
+#: src/parse_args.c:430
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "l'opció `-U' sols es pot usar amb l'opció `-l'"
+
+#: src/parse_args.c:434
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "no es poden usar a l'hora les opcions `-A' i `-S'"
+
+#: src/parse_args.c:510
+msgid "sudoedit is not supported on this platform"
+msgstr "aquesta plataforma no dóna suport a sudoedit"
+
+#: src/parse_args.c:583
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Sols es pot especificar una de les opcions -e, -h, -i, -K, -l, -s, -v o -V"
+
+#: src/parse_args.c:597
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - edita fitxers com un altre usuari\n"
+"\n"
+
+#: src/parse_args.c:599
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - executa una ordre com un altre usuari\n"
+"\n"
+
+#: src/parse_args.c:604
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opcions:\n"
+
+#: src/parse_args.c:606
+msgid "use a helper program for password prompting"
+msgstr "usa un programa auxiliar per a la pregunta de la contrasenya"
+
+#: src/parse_args.c:609
+msgid "use specified BSD authentication type"
+msgstr "usa el tipus d'autenticació BSD especificat"
+
+#: src/parse_args.c:612
+msgid "run command in the background"
+msgstr "executa l'ordre en el segon pla"
+
+#: src/parse_args.c:614
+msgid "close all file descriptors >= num"
+msgstr "tanca tots els descriptors de fitxer >= num"
+
+#: src/parse_args.c:617
+msgid "run command with the specified BSD login class"
+msgstr "executa l'ordre amb la classe d'inici de sesssió BSD especificada"
+
+#: src/parse_args.c:620
+msgid "preserve user environment when running command"
+msgstr "preserva l'entorn de l'usuari quan s'executi l'ordre"
+
+#: src/parse_args.c:622
+msgid "edit files instead of running a command"
+msgstr "edita els fitxers en comptes d'executar una ordre"
+
+#: src/parse_args.c:624
+msgid "run command as the specified group name or ID"
+msgstr "executa l'ordre com el nom o ID especificats de grup"
+
+#: src/parse_args.c:626
+msgid "set HOME variable to target user's home dir"
+msgstr "estableix la variable HOME per apuntar al directori de l'usuari"
+
+#: src/parse_args.c:628
+msgid "display help message and exit"
+msgstr "mostra el missatge d'ajuda i surt"
+
+#: src/parse_args.c:630
+msgid "run command on host (if supported by plugin)"
+msgstr "executa l'ordre a l'amfitrió (si està suportat pel connector)"
+
+#: src/parse_args.c:632
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "executa l'intèrpret d'ordres de l'inici de sessió com a usuari de destinació; també es pot especificar una ordre"
+
+#: src/parse_args.c:634
+msgid "remove timestamp file completely"
+msgstr "suprimeix completament el fitxer de marca de temps"
+
+#: src/parse_args.c:636
+msgid "invalidate timestamp file"
+msgstr "fitxer de marca de temps no vàlid"
+
+#: src/parse_args.c:638
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "fes una llista dels privilegis de l'usuari o verifica una ordre específica; usueu-lo dues vegades per a formats més llargs"
+
+#: src/parse_args.c:640
+msgid "non-interactive mode, no prompts are used"
+msgstr "mode no interactiu, no es preguntarà res"
+
+#: src/parse_args.c:642
+msgid "preserve group vector instead of setting to target's"
+msgstr "preserva el vector de grup en comptes d'establir-lo d'acord amb la destinació"
+
+#: src/parse_args.c:644
+msgid "use the specified password prompt"
+msgstr "usa la pregunta específica de contrasenya"
+
+#: src/parse_args.c:647
+msgid "create SELinux security context with specified role"
+msgstr "crea un context de seguretat SELinux amb el rol especificat"
+
+#: src/parse_args.c:650
+msgid "read password from standard input"
+msgstr "llegeix la contrasenya des de l'entrada estàndard"
+
+#: src/parse_args.c:652
+msgid "run shell as the target user; a command may also be specified"
+msgstr "executa l'intèrpret d'ordres com a usuari de destinació; també es pot especificar una ordre"
+
+#: src/parse_args.c:655
+msgid "create SELinux security context with specified type"
+msgstr "crea el context de seguretat SELinux amb el tipus especificat"
+
+#: src/parse_args.c:658
+msgid "in list mode, display privileges for user"
+msgstr "en mode llista, mostra els privilegis per a l'usuari"
+
+#: src/parse_args.c:660
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "executa l'ordre (o edita el fitxer) com el nom o ID especificats d'usuari"
+
+#: src/parse_args.c:662
+msgid "display version information and exit"
+msgstr "mostra la informació de versió i surt"
+
+#: src/parse_args.c:664
+msgid "update user's timestamp without running a command"
+msgstr "actualitza la marca de temps de l'usuari sense executar una ordre"
+
+#: src/parse_args.c:666
+msgid "stop processing command line arguments"
+msgstr "deixa de processar els arguments de línia d'ordres"
+
+#: src/selinux.c:77
+msgid "unable to open audit system"
+msgstr "no s'ha pogut obrir el sistema d'auditoria"
+
+#: src/selinux.c:87
+msgid "unable to send audit message"
+msgstr "no s'ha pogut enviar el missatge d'auditoria"
+
+#: src/selinux.c:115
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "no s'ha pogut fgetfilecon %s"
+
+#: src/selinux.c:120
+#, c-format
+msgid "%s changed labels"
+msgstr "%s ha canviat les etiquetes"
+
+#: src/selinux.c:125
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "no s'ha pogut restaurar el context per a %s"
+
+#: src/selinux.c:165
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "no s'ha pogut obrir %s, no es canviaran les etiquetes per a la tty"
+
+#: src/selinux.c:173
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "no s'ha pogut obtenir el context tty actual, no es canviaran les etiquetes per a la tty"
+
+#: src/selinux.c:180
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "classe de seguretat «char_file» desconeguda, no es canviaran les etiquetes de la tty"
+
+#: src/selinux.c:185
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "no s'ha pogut obtenir el nou context tty, no es canviaran les etiquetes tty"
+
+#: src/selinux.c:192
+msgid "unable to set new tty context"
+msgstr "no s'ha pogut establir el nou context tty"
+
+#: src/selinux.c:256
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "heu d'especificar un rol per al tipus %s"
+
+#: src/selinux.c:262
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "no s'ha pogut obtenir un tipus predeterminat per al rol %s"
+
+#: src/selinux.c:280
+#, c-format
+msgid "failed to set new role %s"
+msgstr "no s'ha pogut establir el nou rol %s"
+
+#: src/selinux.c:284
+#, c-format
+msgid "failed to set new type %s"
+msgstr "no s'ha pogut establir el nou tipus %s"
+
+#: src/selinux.c:296
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s no és un context vàlid"
+
+#: src/selinux.c:331
+msgid "failed to get old_context"
+msgstr "no s'ha pogut obtenir old_context"
+
+#: src/selinux.c:337
+msgid "unable to determine enforcing mode."
+msgstr "no s'ha pogut determinar el mode de fer complir"
+
+#: src/selinux.c:354
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "no s'ha pogut establir el context tty a %s"
+
+#: src/selinux.c:393
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "no s'ha pogut establir el context exec a %s"
+
+#: src/selinux.c:400
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "no s'ha pogut establir el context de creació de clau a %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "es requereix almenys un argument"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "número no vàlid de descriptor de fitxer: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "no s'ha pogut executar %s com a intèrpret d'ordres d'inici de sessió"
+
+#: src/sesh.c:125 src/sudo.c:1297
+#, c-format
+msgid "unable to execute %s"
+msgstr "no s'ha pogut executar %s"
+
+#: src/signal.c:69
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "no s'ha pogut desar el gestorper al senyal %d"
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "s'ha assolit el límit de control de recursos"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "l'usuari \"%s\" no és un membre del projecte \"%s\""
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr "la tasca invocant és final"
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "no es pot fer la incorporació al projecte \"%s\""
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "no hi ha vinculacions predeterminades d'acceptació de conjunt de recursos per al projecte \"%s\""
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "no existeix el conjunt de recursos especifica per al projecte \"%s\""
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "no s'ha pogut vincular al conjunt de recursos predeterminats per al projecte \"%s\""
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "ha fallat setproject per al projecte \"%s\""
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "advertiment, l'assignació de control de recursos ha fallat per al projecte \"%s\""
+
+#: src/sudo.c:212
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Versió de sudo %s\n"
+
+#: src/sudo.c:214
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Opcions de configuració: %s\n"
+
+#: src/sudo.c:222
+msgid "fatal error, unable to load plugins"
+msgstr "error fatal, no s'han pogut carregar els connectors"
+
+#: src/sudo.c:230
+msgid "unable to initialize policy plugin"
+msgstr "no s'ha pogut inicialitzar el connector de polítiques"
+
+#: src/sudo.c:274
+msgid "plugin did not return a command to execute"
+msgstr "el connector no ha retornat una ordre a executar"
+
+#: src/sudo.c:290
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "no se pogut iniciliatzar el connector %s entrada/sortida"
+
+#: src/sudo.c:316
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "mode 0x%x inesperat de sudo"
+
+#: src/sudo.c:460
+msgid "unable to get group vector"
+msgstr "no s'ha pogut obtenir el vector de grup"
+
+#: src/sudo.c:522
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "uid %u desconegut: qui sou?"
+
+#: src/sudo.c:578
+msgid "unable to determine tty"
+msgstr "no s'ha pogut determinar la tty"
+
+#: src/sudo.c:866
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s ha de ser propietat de l'uid %d i tenir el bit setuid establert"
+
+#: src/sudo.c:869
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr ""
+"l'uid efectiu no és %d, és %s a un sistema de fitxers amb l'opció\n"
+"'nosuid' establarta o un sistema de fitxers NFS sense d'usuari primari? "
+
+#: src/sudo.c:875
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "l'uid efectiu no és %d, és el sudo instal·lat com a setuid root?"
+
+#: src/sudo.c:956
+msgid "unable to set supplementary group IDs"
+msgstr "no s'han pogut establir els IDs de grup suplementaris"
+
+#: src/sudo.c:963
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "no s'ha pogut establir el gid efectiu per a runas gid %u"
+
+#: src/sudo.c:969
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "no s'ha pogut establir el gid a runas gid %u"
+
+#: src/sudo.c:1040
+#, c-format
+msgid "unknown login class %s"
+msgstr "classe d'inici de sessió %s desconeguda"
+
+#: src/sudo.c:1053
+msgid "unable to set user context"
+msgstr "no s'ha pogut establir el context d'usuari"
+
+#: src/sudo.c:1069
+msgid "unable to set process priority"
+msgstr "no s'ha pogut establir la prioritat del procés"
+
+#: src/sudo.c:1077
+#, c-format
+msgid "unable to change root to %s"
+msgstr "no s'ha pogut canviar l'usuari primari a %s"
+
+#: src/sudo.c:1090 src/sudo.c:1096 src/sudo.c:1103
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "no s'ha pogut canviar a runas uid (%u, %u)"
+
+#: src/sudo.c:1121
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "no s'ha pogut canviar el directori a %s"
+
+#: src/sudo.c:1179
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "condició de terminació del fill inesperada: %d"
+
+#: src/sudo.c:1325
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "no hi ha el mètode `check_policy' al connector de polítiques %s"
+
+#: src/sudo.c:1343
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "el connector de política %s no dóna suport a llistar privilegis"
+
+#: src/sudo.c:1360
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "el connector de polítiques %s no dóna suport a l'opció -v"
+
+#: src/sudo.c:1375
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "el connector de polítiques %s no dóna suport a les opcions -k/-K"
+
+#: src/sudo_edit.c:181 src/sudo_edit.c:270
+msgid "unable to restore current working directory"
+msgstr "no s'ha pogut restaurar el directori actual de treball"
+
+#: src/sudo_edit.c:577 src/sudo_edit.c:689
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: no és un fitxer regular"
+
+#: src/sudo_edit.c:584
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: no es permet l'edició de enllaços simbòlics"
+
+#: src/sudo_edit.c:587
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: no es permet l'edició de fitxers a un directori amb permís d'escriptura"
+
+#: src/sudo_edit.c:620 src/sudo_edit.c:728
+#, c-format
+msgid "%s: short write"
+msgstr "%s: escriptura breu"
+
+#: src/sudo_edit.c:690
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s s'ha deixat sense modificar"
+
+#: src/sudo_edit.c:703 src/sudo_edit.c:889
+#, c-format
+msgid "%s unchanged"
+msgstr "%s sense canviar"
+
+#: src/sudo_edit.c:717 src/sudo_edit.c:739
+#, c-format
+msgid "unable to write to %s"
+msgstr "no s'ha pogut escriure a %s"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:737 src/sudo_edit.c:740
+#: src/sudo_edit.c:914 src/sudo_edit.c:918
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "els continguts de la sessió d'edició s'han deixat a %s"
+
+#: src/sudo_edit.c:736
+msgid "unable to read temporary file"
+msgstr "no s'ha pogut llegir el fitxer temporal"
+
+#: src/sudo_edit.c:819
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: error intern: nombre imparell de camins"
+
+#: src/sudo_edit.c:821
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: no es poden crear fitxers temporal"
+
+#: src/sudo_edit.c:823 src/sudo_edit.c:921
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: error desconegut %d"
+
+#: src/sudo_edit.c:913
+msgid "unable to copy temporary files back to their original location"
+msgstr "no es poden copiar els fitxers temporals un altre cop a la seva ubicació original"
+
+#: src/sudo_edit.c:917
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "no es poden copiar alguns dels fitxers temporals un altre cop a la seva ubicació original"
+
+#: src/sudo_edit.c:961
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "no s'ha pogut canviar l'uid a l'usuari primari (%u)"
+
+#: src/sudo_edit.c:978
+msgid "plugin error: missing file list for sudoedit"
+msgstr "error de connector: no hi ha la llista de fitxers per a sudoedit"
+
+#: src/sudo_edit.c:1019 src/sudo_edit.c:1032
+msgid "unable to read the clock"
+msgstr "no es pot llegir el rellotge"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr "no hi ha un tty present i no s'ha especificat un programa askpass"
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "no s'ha especificat un programa askpass, proveu d'establir SUDO_ASKPASS"
+
+#: src/tgetpass.c:261
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "no s'ha pogut establir el gid a %u"
+
+#: src/tgetpass.c:265
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "no s'ha pogut establir el uid a %u"
+
+#: src/tgetpass.c:270
+#, c-format
+msgid "unable to run %s"
+msgstr "no s'ha pogut executar %s"
+
+#: src/utmp.c:268
+msgid "unable to save stdin"
+msgstr "no s'ha pogut desar el stdin"
+
+#: src/utmp.c:270
+msgid "unable to dup2 stdin"
+msgstr "no s'ha pogut fer dup2 stdin"
+
+#: src/utmp.c:273
+msgid "unable to restore stdin"
+msgstr "no s'ha pogut restaurar stdin"
+
+#~ msgid "internal error, tried allocate zero bytes"
+#~ msgstr "error intern, s'han intentat assignar zero bytes"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "no s'ha pogut configurar la terminal en mode en brut"
+
+#~ msgid "unable to open socket"
+#~ msgstr "no s'ha pogut obrir el sòcol"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "error intern, s'ha intentat emalloc2(0)"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "error intern, s'ha intentat ecalloc(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "error intern, s'ha intentat erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "error intern, s'ha intentat erealloc3(0)"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "error intern, s'ha intentat erecalloc(0)"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: s'ha detectat un sobreeiximent"
diff --git a/po/cs.mo b/po/cs.mo
new file mode 100644
index 0000000..4cb10e5
--- /dev/null
+++ b/po/cs.mo
Binary files differ
diff --git a/po/cs.po b/po/cs.po
new file mode 100644
index 0000000..3afbf0a
--- /dev/null
+++ b/po/cs.po
@@ -0,0 +1,977 @@
+# Portable object template file for sudo
+# This file is put in the public domain.
+# Todd C. Miller <Todd.Miller@courtesan.com>, 2011-2013
+# Petr Pisar <petr.pisar@atlas.cz>, 2013, 2014, 2015, 2016, 2017, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-31 19:26+01:00\n"
+"Last-Translator: Petr Pisar <petr.pisar@atlas.cz>\n"
+"Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"
+"Language: cs\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "nelze otevřít databázi uživatelů"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "nelze se přepnout do registru „%s“ pro %s"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "registr nelze obnovit"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "nelze alokovat paměť"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "Neznámý signál"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "neplatná hodnota"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "hodnota je příliš velká"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "hodnota je příliš malá"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "neplatná hodnota Path „%s“ v %s, řádek %u"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "neplatná hodnota pro %s „%s“ v %s, řádek %u"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "nepodporovaný zdroj skupin „%s“ v %s, řádek %u"
+
+# This is about maximal GID. English text "max groups" is wrong.
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "neplatné maximum skupin „%s“ v %s, řádek %u"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "nelze získat údaje o %s"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s není obyčejný soubor"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s je vlastněn UID %u, avšak UID by mělo být %u"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "%s je zapisovatelný pro všechny"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "%s je zapisovatelný pro skupinu"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "%s nelze otevřít"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "neznámá přihlašovací třída %s"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "nelze nastavit kontext uživatele"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "nelze nastavit prioritu procesu"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "kořenový adresář nelze změnit na %s"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "nelze změnit UID na (%u, %u)"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "pracovní adresář nelze změnit na %s"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "obsluhu pro signál %d nelze nastavit"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "z PRIV_LIMIT nelze odstranit PRIV_PROC_EXEC"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "chyba při čtení z dvojice socketů"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "neočekávaný druh odpovědi na zpětném kanálu: %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "událost nelze přidat do fronty"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "řídicí terminál nelze nastavit"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "nelze vytvořit rouru"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "od rodiče nelze přijmout zprávu"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "nelze vytvořit potomka"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "%s nelze spustit"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "nelze obnovit značku TTY"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "modul s politikami zrušil inicializaci relace"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "chyba ve smyčce s událostmi"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "nelze obnovit obsluhu signálu %d"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "nelze alokovat PTY"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "nelze vytvořit sockety"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "dohlížejícímu procesu nelze odeslat zprávu"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "chyba v %s na řádku %d při zavádění modulu „%s“"
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s musí být vlastněn UID %d"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s musí být zapisovatelný jen vlastníkem"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "%s nelze zavést: %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "v %s nelze nalézt symbol „%s“"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "v %2$s nalezen neznámý druh politiky %1$d"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "neslučitelná hlavní verze modulu %d (očekáváno %d) nalezena v %s"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "ignoruje se modul politiky „%s“ v %s na řádku %d"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "lze zadat pouze jeden modul s politikou"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "ignoruje je opakovaný modul s politikou „%s“ v %s na řádku %d"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "ignoruje je opakovaný modul vstupu a výstupu „%s“ v %s na řádku %d"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "modul s politikou %s neobsahuje metodu check_policy"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "vnitřní chyba, přetečení v %s"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "neplatný název proměnné prostředí: %s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "argument u -C musí být číslo větší nebo rovno 3"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "nesmíte zadávat přepínače „-i“ a „-s“ spolu"
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "nesmíte zadávat přepínače „-i“ a „-E“ spolu"
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "přepínač „-E“ není platný v režimu úprav"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "v režimu úprav nesmíte zadávat proměnné prostředí"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "přepínač „-U“ smí být použit jen s přepínačem „-l“"
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "přepínače „-A“ a „-S“ smí nesmí být použity spolu"
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "na této platformě není sudoedit podporován"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Smí být zadán pouze jeden z přepínačů -e, -h, -i, -K, -l, -s, -v nebo -V"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s – upraví soubory jako jiný uživatel\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s – vykoná příkaz jako jiný uživatel\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Přepínače:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "dotazuje se na heslo prostřednictvím pomocného programu"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "použije zadaný druh BSD autentizace"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "spustí příkaz na pozadí"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "uzavře všechny deskriptory souboru >= číslu"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "spustí příkaz se zadanou přihlašovací třídou BSD"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "při spuštění příkazu zachová uživatelské prostředí"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "zachová určité proměnné prostředí"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "místo spuštění příkazu upraví soubory"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "spustí příkaz jako skupina určení názvem nebo ID"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "nastaví proměnnou HOME na domovský adresář uživatele"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "zobrazí nápovědu a skončí"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "spustí příkaz na stroji (je-li podporováno modulem)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "spustí přihlašovací shell jako cílový uživatel; příkaz lze rovněž zadat"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "úplně odstraní soubor s časovými údaji"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "zneplatní soubor s časovými údaji"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "vypíše oprávnění uživatele nebo zkontroluje určitý příkaz; pro delší výstup použijte dvakrát"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "neinteraktivní režim, nepoužijí se žádné dotazy"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "zachová vektor skupin namísto nastavení na skupiny cíle"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "použije určený dotaz na heslo"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "vytvoří selinuxový bezpečnostní kontext se zadanou rolí"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "načte heslo ze standardní vstupu"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "spustí shell jako cílový uživatel; příkaz lze rovněž zadat"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "vytvoří selinuxový bezpečnostní kontext se zadaným typem"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "po uplynutí zadaného času ukončí příkaz"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "v režimu výpisu zobrazí oprávnění uživatele"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "spustí příkaz (nebo upraví soubor) jako uživatel určený jménem nebo ID"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "zobrazí údaje o verzi a skončí"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "aktualizuje časové údaje uživatele bez spuštění příkazu"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "přestane zpracovávat argumenty příkazového řádku"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "nelze otevřít auditní systém"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "nelze odeslat auditní zprávu"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "nelze získat kontext souboru %s pomocí fgetfilecon"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s změnilo značky"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "nelze obnovit kontext %s"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "%s nelze otevřít, TTY nebude značka přepsána"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s není znakové zařízení, TTY nebude značka přepsána"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "nelze získat kontext současného TTY, TTY nebude značka přepsána"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "neznámá bezpečnostní třída „chr_file“, TTY nebude značka přepsána"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "nelze získat nový kontext TTY, TTY nebude značka přepsána"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "nelze nastavit nový kontext TTY"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "pro typ %s musíte zadat roli"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "výchozí typ pro roli %s nelze získat"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "nepodařilo se nastavit novou roli %s"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "nepodařilo se nastavit nový typ %s"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s není platný kontext"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "nepodařilo se získat starý kontext"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "nepodařilo se určit režim vynucování SELinuxu."
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "nepodařilo se nastavit kontext TTY na %s"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "nepodařilo se nastavit kontext pro spuštění na %s"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "nepodařilo se nastavit kontext pro vytváření klíčů na %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "je třeba alespoň jeden argument"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "neplatné číslo deskriptoru souboru: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "%s nelze spustit jako přihlašovací shell"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "obsluhu signálu %d nelze uložit"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "omezení z řízení zdrojů bylo dosaženo"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "uživatel „%s“ není členem projektu „%s“"
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "volaná úloha je konečná"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "nebylo možné se připojit k projektu „%s“"
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "pro projekt „%s“ neexistuje žádná množina zdrojů přijímající výchozí vazbu"
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "pro projekt „%s“ neexistuje zadaná množina zdrojů"
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "u projektu „%s“ se nebylo možné navázat na výchozí množinu zdrojů"
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "volání setproject selhalo u projektu „%s“"
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "pozor, nepodařilo se přiřadit řízení zdrojů projektu „%s“"
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo verze %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Přepínače configure: %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "nepřekonatelná chyba, moduly nelze zavést"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "modul s politikami nelze inicializovat"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "modul nevrátil příkaz k provedení"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "chyba při inicializaci vstupně-výstupního modulu %s"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "neočekávaný režim programu sudo 0x%x"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "neexistujete v databázi %s"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "nelze určit terminál"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s musí být vlastněn UID %d a mít nastaven bit setuid"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "efektivní UID není %d, nalézá se %s na souborovém systému s nastavenou volbou „nosuid“ nebo na souborovém systému NFS bez práv roota?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "efektivní UID není %d, je sudo nainstalované jako setuid vlastněné rootem?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "nelze nastavit ID doplňkových skupin"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "efektivní GID nelze nastavit na %u"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "GID nelze nastavit na %u"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "neočekávaný důvod ukončení potomka: %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "modulu s politikami %s chybí metoda „check_policy“"
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "modul s politikami %s nepodporuje získání seznamu oprávnění"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "modul s politikami %s nepodporuje přepínač -v"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "modul s politikami %s nepodporuje přepínače -k/-K"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "nenalezen žádný dočasný adresář, do kterého lze zapisovat"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "současný pracovní adresář nelze obnovit"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: nejedná se o obyčejný soubor"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: úprava symbolických odkazů není dovolena"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: úprava souborů v adresáři, do kterého lze zapisovat, není dovolena"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s: krátký zápis"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s ponechán nezměněn"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "%s nezměněn"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "do %s nelze zapsat"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "obsah relace s úpravami ponechán v %s"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "nelze přečíst dočasný soubor"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: vnitřní chyba: lichý počet cest"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: nelze vytvořit dočasné soubory"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: neznámá chyba %d"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "dočasné soubory nelze zkopírovat zpět na jejich původní místo"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "některé z dočasných souborů nelze zkopírovat zpět na jejich původní místo"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "UID nelze změnit na roota (%u)"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "chyba modulu: programu sudoedit chybí seznam souborů"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "nelze přečíst hodiny"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "při čtení hesla vypršel čas"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "žádné heslo nebylo poskytnuto"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "heslo nelze přečíst"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "chybí terminál a program pro dotazování se na heslo nebyl zadán"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "program pro dotazování se na heslo nebyl zadán, zkuste nastavit SUDO_ASKPASS"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "GID nelze nastavit na %u"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "UID nelze nastavit na %u"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "%s nelze spustit"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "standardní vstup nelze uložit"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "standardní vstup nelze zduplikovat voláním dup2"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "standardní vstup nelze obnovit"
+
+#~ msgid "unable to get group vector"
+#~ msgstr "nelze získat vektor skupin"
+
+#~ msgid "unknown uid %u: who are you?"
+#~ msgstr "neznámé UID %u: kdo jsi?"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "chyba při čtení ze signální roury"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "chyba při čtení z roury"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "terminál nelze přepnout do syrového režimu"
+
+#~ msgid "internal error, tried allocate zero bytes"
+#~ msgstr "vnitřní chyba, pokus alokovat nula bajtů"
+
+#~ msgid "unable to open socket"
+#~ msgstr "nelze otevřít socket"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "vnitřní chyba, pokus o emalloc2(0)"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "vnitřní chyba, pokus o ecalloc(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "vnitřní chyba, pokus o erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "vnitřní chyba, pokus o erealloc3(0)"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "vnitřní chyba, pokus o erecalloc(0)"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: zjištěno přetečení"
+
+#~ msgid "value out of range"
+#~ msgstr "hodnota je mimo rozsah"
+
+#~ msgid "select failed"
+#~ msgstr "volání select selhalo"
diff --git a/po/da.mo b/po/da.mo
new file mode 100644
index 0000000..1875e12
--- /dev/null
+++ b/po/da.mo
Binary files differ
diff --git a/po/da.po b/po/da.po
new file mode 100644
index 0000000..03fa1f1
--- /dev/null
+++ b/po/da.po
@@ -0,0 +1,898 @@
+# Danish translation of sudo.
+# This file is put in the public domain.
+# Joe Hansen <joedalton2@yahoo.dk>, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018.
+#
+# audit -> overvågning
+# overflow -> overløb
+#
+# projekt bruger konsekvent små bogstaver, og så i starten af sætninger, så
+# dette er også valgt på dansk uanset at der er : som efterfølgende normalt
+# ville have stort begyndelsesbogstav på dansk.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.23b3\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-04-05 06:36-0600\n"
+"PO-Revision-Date: 2018-08-14 23:06+0100\n"
+"Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n"
+"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
+"Language: da\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:172
+msgid "unable to open userdb"
+msgstr "kan ikke åbne userdb"
+
+#: lib/util/aix.c:227
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "kan ikke skifte til register »%s« for %s"
+
+#: lib/util/aix.c:252
+msgid "unable to restore registry"
+msgstr "kan ikke gendanne register"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:186 lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349
+#: lib/util/sudo_conf.c:553 src/conversation.c:75 src/exec_common.c:107
+#: src/exec_common.c:123 src/exec_common.c:132 src/exec_monitor.c:168
+#: src/exec_nopty.c:462 src/exec_pty.c:735 src/exec_pty.c:744
+#: src/exec_pty.c:815 src/exec_pty.c:942 src/load_plugins.c:52
+#: src/load_plugins.c:65 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:198 src/parse_args.c:273 src/parse_args.c:559
+#: src/parse_args.c:581 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:112 src/sudo.c:386 src/sudo.c:413 src/sudo.c:494 src/sudo.c:632
+#: src/sudo.c:692 src/sudo.c:702 src/sudo.c:722 src/sudo.c:741 src/sudo.c:750
+#: src/sudo.c:759 src/sudo.c:776 src/sudo.c:817 src/sudo.c:827 src/sudo.c:847
+#: src/sudo.c:1087 src/sudo.c:1108 src/sudo.c:1282 src/sudo.c:1380
+#: src/sudo_edit.c:250 src/sudo_edit.c:775 src/sudo_edit.c:872
+#: src/sudo_edit.c:986 src/sudo_edit.c:1006
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/sudo_conf.c:187
+#: lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349 lib/util/sudo_conf.c:553
+#: src/conversation.c:76 src/exec_common.c:107 src/exec_common.c:124
+#: src/exec_common.c:133 src/exec_pty.c:735 src/exec_pty.c:744
+#: src/exec_pty.c:815 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:199 src/parse_args.c:273 src/parse_args.c:559
+#: src/parse_args.c:581 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:112 src/sudo.c:386 src/sudo.c:413 src/sudo.c:494 src/sudo.c:632
+#: src/sudo.c:847 src/sudo.c:1087 src/sudo.c:1108 src/sudo.c:1282
+#: src/sudo.c:1380 src/sudo_edit.c:250 src/sudo_edit.c:775 src/sudo_edit.c:872
+#: src/sudo_edit.c:986 src/sudo_edit.c:1006
+msgid "unable to allocate memory"
+msgstr "kunne ikke allokere hukommelse"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "ukendt signal"
+
+#: lib/util/strtoid.c:77 lib/util/strtoid.c:124 lib/util/strtoid.c:152
+#: lib/util/strtomode.c:49 lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "ugyldig værdi"
+
+#: lib/util/strtoid.c:84 lib/util/strtoid.c:131 lib/util/strtoid.c:159
+#: lib/util/strtomode.c:55 lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "værdi for stor"
+
+#: lib/util/strtoid.c:86 lib/util/strtoid.c:137 lib/util/strtomode.c:55
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "værdi for lille"
+
+#: lib/util/sudo_conf.c:205
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "ugyldig stiværdi »%s« i %s, linje %u"
+
+#: lib/util/sudo_conf.c:371 lib/util/sudo_conf.c:424
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "ugyldig værdi for %s »%s« i %s, linje %u"
+
+#: lib/util/sudo_conf.c:392
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "ikke understøttet gruppekilde »%s« i %s, linje %u"
+
+#: lib/util/sudo_conf.c:408
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "ugyldigt maks. for grupper »%s« i %s, linje %u"
+
+#: lib/util/sudo_conf.c:569
+#, c-format
+msgid "unable to stat %s"
+msgstr "kan ikke køre stat %s"
+
+#: lib/util/sudo_conf.c:572
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s er ikke en regulær fil"
+
+#: lib/util/sudo_conf.c:575
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s er ejet af uid %u, burde være %u"
+
+#: lib/util/sudo_conf.c:579
+#, c-format
+msgid "%s is world writable"
+msgstr "%s er skrivbar for alle"
+
+#: lib/util/sudo_conf.c:582
+#, c-format
+msgid "%s is group writable"
+msgstr "%s er skrivbar for gruppe"
+
+#: lib/util/sudo_conf.c:592 src/selinux.c:208 src/selinux.c:225 src/sudo.c:354
+#, c-format
+msgid "unable to open %s"
+msgstr "kan ikke åbne %s"
+
+#: src/exec.c:160
+#, c-format
+msgid "unknown login class %s"
+msgstr "ukendt logindklasse %s"
+
+#: src/exec.c:173
+msgid "unable to set user context"
+msgstr "kan ikke angive brugerkontekst"
+
+#: src/exec.c:189
+msgid "unable to set process priority"
+msgstr "kunne ikke angive procesprioritet"
+
+#: src/exec.c:197
+#, c-format
+msgid "unable to change root to %s"
+msgstr "kunne ikke ændre administrator (root) til %s"
+
+#: src/exec.c:210 src/exec.c:216 src/exec.c:223
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "kunne ikke ændre til runas uid (%u, %u)"
+
+#: src/exec.c:241
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "kunne ikke ændre mappe til %s"
+
+#: src/exec.c:340 src/exec_monitor.c:528 src/exec_monitor.c:530
+#: src/exec_nopty.c:520 src/exec_pty.c:483 src/exec_pty.c:1258
+#: src/exec_pty.c:1260 src/signal.c:143 src/signal.c:157
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "kan ikke angive håndtering for signal %d"
+
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "kan ikke fjerne PRIV_PROC_EXEC fra PRIV_LIMIT"
+
+#: src/exec_monitor.c:322
+msgid "error reading from socketpair"
+msgstr "fejl ved læsning fra socketpair"
+
+#: src/exec_monitor.c:334
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "uventet svartype på bagkanal (backchannel): %d"
+
+#: src/exec_monitor.c:425 src/exec_monitor.c:433 src/exec_monitor.c:441
+#: src/exec_monitor.c:448 src/exec_monitor.c:455 src/exec_monitor.c:462
+#: src/exec_monitor.c:469 src/exec_monitor.c:476 src/exec_monitor.c:483
+#: src/exec_monitor.c:490 src/exec_nopty.c:215 src/exec_nopty.c:224
+#: src/exec_nopty.c:231 src/exec_nopty.c:238 src/exec_nopty.c:245
+#: src/exec_nopty.c:252 src/exec_nopty.c:259 src/exec_nopty.c:266
+#: src/exec_nopty.c:273 src/exec_nopty.c:280 src/exec_nopty.c:287
+#: src/exec_nopty.c:294 src/exec_nopty.c:302 src/exec_pty.c:601
+#: src/exec_pty.c:606 src/exec_pty.c:703 src/exec_pty.c:710 src/exec_pty.c:820
+#: src/exec_pty.c:1099 src/exec_pty.c:1108 src/exec_pty.c:1115
+#: src/exec_pty.c:1122 src/exec_pty.c:1129 src/exec_pty.c:1136
+#: src/exec_pty.c:1143 src/exec_pty.c:1150 src/exec_pty.c:1157
+#: src/exec_pty.c:1164 src/exec_pty.c:1171 src/exec_pty.c:1527
+#: src/exec_pty.c:1537 src/exec_pty.c:1582 src/exec_pty.c:1589
+#: src/exec_pty.c:1616
+msgid "unable to add event to queue"
+msgstr "kan ikke tilføje hændelse til kø"
+
+#: src/exec_monitor.c:542
+msgid "unable to set controlling tty"
+msgstr "kunne ikke angive kontrollerende tty"
+
+#: src/exec_monitor.c:550 src/exec_nopty.c:359 src/exec_pty.c:1337
+#: src/exec_pty.c:1358 src/exec_pty.c:1378 src/tgetpass.c:254
+msgid "unable to create pipe"
+msgstr "kunne ikke oprette datakanal (pipe)"
+
+#: src/exec_monitor.c:555 src/exec_nopty.c:377 src/exec_pty.c:1416
+#: src/tgetpass.c:258
+msgid "unable to fork"
+msgstr "kunne ikke forgrene"
+
+#: src/exec_monitor.c:567 src/sesh.c:122 src/sudo.c:1146
+#, c-format
+msgid "unable to execute %s"
+msgstr "kan ikke køre %s"
+
+#: src/exec_monitor.c:650 src/exec_nopty.c:430
+msgid "unable to restore tty label"
+msgstr "kunne ikke gendanne tty-etiket"
+
+#: src/exec_nopty.c:353 src/exec_pty.c:1267
+msgid "policy plugin failed session initialization"
+msgstr "udvidelsesmodul for politik mislykkedes i sessionsinitialisering"
+
+#: src/exec_nopty.c:419 src/exec_pty.c:1485
+msgid "error in event loop"
+msgstr "fejl i hændelsesloop"
+
+#: src/exec_nopty.c:528 src/exec_pty.c:515 src/signal.c:105
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "kan ikke gendanne håndtering for signal %d"
+
+#: src/exec_pty.c:150
+msgid "unable to allocate pty"
+msgstr "kunne ikke allokere pty"
+
+#: src/exec_pty.c:1247
+msgid "unable to create sockets"
+msgstr "kunne ikke oprette sokler"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "fejl i %s, linje %d under indlæsning af udvidelsesmodulet »%s«"
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s skal være ejet af uid %d"
+
+# engelsk fejl be dobbelt?
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s må kun være skrivbar for ejeren"
+
+#: src/load_plugins.c:172
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "kunne ikke indlæse %s: %s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "kunne ikke finde symbol »%s« i %s"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "ukendt politiktype %d fundet i %s"
+
+#: src/load_plugins.c:193
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "inkompatibelt udvidelsesmodul for hovedversion %d (forventede %d) fundet i %s"
+
+#: src/load_plugins.c:202
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "ignorerer politikudvidelsesmodul »%s« i %s, linje %d"
+
+#: src/load_plugins.c:204
+msgid "only a single policy plugin may be specified"
+msgstr "kun et udvidelsesmodul for politik må være angivet"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "ignorerer duplikat politikudvidelsesmodul »%s« i %s, linje %d"
+
+#: src/load_plugins.c:228
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "ignorerer duplikat I/O-udvidelsesmodul »%s« i %s, linje %d"
+
+#: src/load_plugins.c:331
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "politikudvidelsesmodulet %s inkluderer ikke en metode for check_policy"
+
+#: src/net_ifs.c:172 src/net_ifs.c:189 src/net_ifs.c:334 src/sudo.c:489
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "intern fejl, %s-overløb"
+
+#: src/parse_args.c:219
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "ugyldigt miljøvariabelnavn: %s"
+
+#: src/parse_args.c:315
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "argumentet for -C skal være et tal større end eller lig 3"
+
+#: src/parse_args.c:499
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "du kan ikke samtidig angive tilvalgene »-i« og »-s«"
+
+#: src/parse_args.c:503
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "du kan ikke samtidig angive tilvalgende »-i« og »-E«"
+
+#: src/parse_args.c:513
+msgid "the `-E' option is not valid in edit mode"
+msgstr "tilvalget »-E« er ikke gyldigt i redigeringstilstand"
+
+#: src/parse_args.c:515
+msgid "you may not specify environment variables in edit mode"
+msgstr "du må ikke angive miljøvariabler i redigeringstilstand"
+
+#: src/parse_args.c:523
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "tilvalget »-U« må kun bruges med tilvalget »-l«"
+
+#: src/parse_args.c:527
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "tilvalgene »-A« og »-S« må ikke bruges sammen"
+
+#: src/parse_args.c:603
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit er ikke understøttet på denne platform"
+
+#: src/parse_args.c:676
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Kun et af tilvalgene -e, -h, -i, -K, -l, -s, -v eller -V må angives"
+
+#: src/parse_args.c:690
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - rediger filer som en anden bruger\n"
+"\n"
+
+#: src/parse_args.c:692
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - udfør en kommando som en anden bruger\n"
+"\n"
+
+#: src/parse_args.c:697
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Tilvalg:\n"
+
+#: src/parse_args.c:699
+msgid "use a helper program for password prompting"
+msgstr "brug et hjælpeprogram for indhentelse af adgangskode"
+
+#: src/parse_args.c:702
+msgid "use specified BSD authentication type"
+msgstr "brug angivet BSD-godkendelsestype"
+
+#: src/parse_args.c:705
+msgid "run command in the background"
+msgstr "kør kommando i baggrunden"
+
+#: src/parse_args.c:707
+msgid "close all file descriptors >= num"
+msgstr "luk alle filbeskrivelser >= num"
+
+#: src/parse_args.c:710
+msgid "run command with the specified BSD login class"
+msgstr "kør kommando med angivet BSD-logindklasse"
+
+#: src/parse_args.c:713
+msgid "preserve user environment when running command"
+msgstr "bevar brugermiljø når kommando udføres"
+
+#: src/parse_args.c:715
+msgid "preserve specific environment variables"
+msgstr "bevar specifikke miljøvariabler"
+
+#: src/parse_args.c:717
+msgid "edit files instead of running a command"
+msgstr "rediger filer i stedet for at køre en kommando"
+
+#: src/parse_args.c:719
+msgid "run command as the specified group name or ID"
+msgstr "udfør kommando som det angivne gruppenavn eller ID"
+
+#: src/parse_args.c:721
+msgid "set HOME variable to target user's home dir"
+msgstr "angiv HOME-variabel til målbrugers hjemmemappe"
+
+#: src/parse_args.c:723
+msgid "display help message and exit"
+msgstr "vis hjælpetekst og afslut"
+
+#: src/parse_args.c:725
+msgid "run command on host (if supported by plugin)"
+msgstr "kør kommando på vært (hvis understøttet af udvidelsesmodul)"
+
+#: src/parse_args.c:727
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "kør en logindskal som målbrugeren; en kommando kan også angives"
+
+#: src/parse_args.c:729
+msgid "remove timestamp file completely"
+msgstr "fjern tidsstempelfil fuldstændig"
+
+#: src/parse_args.c:731
+msgid "invalidate timestamp file"
+msgstr "ugyldiggør tidsstempelfil"
+
+#: src/parse_args.c:733
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "vis brugers privilegier eller kontroller en specifik kommando; brug to gange for længere format"
+
+#: src/parse_args.c:735
+msgid "non-interactive mode, no prompts are used"
+msgstr "ikkeinteraktiv tilstand, vil ikke spørge bruger"
+
+#: src/parse_args.c:737
+msgid "preserve group vector instead of setting to target's"
+msgstr "bevar gruppevektor i stedet for at sætte til målets"
+
+#: src/parse_args.c:739
+msgid "use the specified password prompt"
+msgstr "brug angivet logind for adgangskode"
+
+#: src/parse_args.c:742
+msgid "create SELinux security context with specified role"
+msgstr "opret SELinux-sikkerhedskontekt med angivet rolle"
+
+#: src/parse_args.c:745
+msgid "read password from standard input"
+msgstr "læs adgangskode fra standardinddata"
+
+#: src/parse_args.c:747
+msgid "run shell as the target user; a command may also be specified"
+msgstr "kør skal som målbruger; en kommando kan også specificeres"
+
+#: src/parse_args.c:750
+msgid "create SELinux security context with specified type"
+msgstr "opret SELinux-sikkerhedskontekt med angivet type"
+
+#: src/parse_args.c:753
+msgid "terminate command after the specified time limit"
+msgstr "afslut kommando efter den angivne tidsbegrænsning"
+
+#: src/parse_args.c:755
+msgid "in list mode, display privileges for user"
+msgstr "i vis-tilstand, vis privilegier for bruger"
+
+#: src/parse_args.c:757
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "kør kommando (eller rediger fil) som angivet brugernavn eller ID"
+
+#: src/parse_args.c:759
+msgid "display version information and exit"
+msgstr "vis versionsinformation og afslut"
+
+#: src/parse_args.c:761
+msgid "update user's timestamp without running a command"
+msgstr "opdater brugers tidsstempel uden at køre en kommando"
+
+#: src/parse_args.c:763
+msgid "stop processing command line arguments"
+msgstr "stop behandling af parametre for kommandolinjen"
+
+#: src/selinux.c:78
+msgid "unable to open audit system"
+msgstr "kunne ikke åbne overvågningssystem"
+
+#: src/selinux.c:88
+msgid "unable to send audit message"
+msgstr "kunne ikke sende overvågningsbesked"
+
+#: src/selinux.c:116
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "kunne ikke fgetfilecon %s"
+
+#: src/selinux.c:121
+#, c-format
+msgid "%s changed labels"
+msgstr "%s ændrede etiketter"
+
+#: src/selinux.c:126
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "kan ikke gendanne kontekst for %s"
+
+#: src/selinux.c:167
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "kan ikke åbne %s, giver ikke ny etiket til tty"
+
+#: src/selinux.c:171 src/selinux.c:212 src/selinux.c:229
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s er ikke en tegnenhed, giver ikke ny etiket til tty"
+
+#: src/selinux.c:180
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "kan ikke indhente aktuel tty-kontekst, giver ikke ny etiket til tty"
+
+#: src/selinux.c:187
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "ukendt sikkerhedsklasse »chr_file«, giver ikke ny etiket til tty"
+
+#: src/selinux.c:192
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "kan ikke indhente ny tty-kontekst, giver ikke nyt etiket til tty"
+
+#: src/selinux.c:199
+msgid "unable to set new tty context"
+msgstr "kan ikke angive ny tty-kontekst"
+
+#: src/selinux.c:273
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "du skal angive en rolle for type %s"
+
+#: src/selinux.c:279
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "kan ikke indhente standardtype for rolle %s"
+
+#: src/selinux.c:297
+#, c-format
+msgid "failed to set new role %s"
+msgstr "kunne ikke angive ny rolle %s"
+
+#: src/selinux.c:301
+#, c-format
+msgid "failed to set new type %s"
+msgstr "kunne ikke angive ny type %s"
+
+#: src/selinux.c:313
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s er ikke en gyldig kontekst"
+
+#: src/selinux.c:348
+msgid "failed to get old_context"
+msgstr "kunne ikke indhente gammel_kontekst (old_context)"
+
+#: src/selinux.c:354
+msgid "unable to determine enforcing mode."
+msgstr "kunne ikke bestemme tilstanden gennemtving (enforcing)."
+
+#: src/selinux.c:371
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "kunne ikke angive tty-kontekst for %s"
+
+#: src/selinux.c:410
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "kunne ikke angive kørselskontekt til %s"
+
+# engelsk: mangler vist lidt info her tast eller nøgle. mon ikke det er nøgle
+#: src/selinux.c:417
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "kunne ikke angive nøgleoprettelseskontekst til %s"
+
+#: src/sesh.c:74
+msgid "requires at least one argument"
+msgstr "kræver mindst et argument"
+
+# eller antal?
+#: src/sesh.c:103
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "ugyldigt filbeskrivelsesnummer: %s"
+
+#: src/sesh.c:117
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "kan ikke køre %s som en indlogningsskal"
+
+#: src/signal.c:83
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "kan ikke gemme håndtering for signal %d"
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "grænse for ressourcekontrol er nået"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "bruger »%s« er ikke medlem af projektet »%s«"
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr "start af opgave er færdig"
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "kunne ikke slutte til projekt »%s«"
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "ingen ressourcekø som accepterer standardbindinger findes for projekt »%s«"
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "angivet ressourcekø findes ikke for projekt »%s«"
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "kunne ikke binde til standardressourcekø for projekt »%s«"
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "setproject fejlede for projekt »%s«"
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "advarsel, ressourcekontroltildeling fejlede for projekt »%s«"
+
+#: src/sudo.c:195
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo version %s\n"
+
+#: src/sudo.c:197
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Konfigurationsindstillinger: %s\n"
+
+#: src/sudo.c:205
+msgid "fatal error, unable to load plugins"
+msgstr "fatal fejl, kan ikke indlæse udvidelsesmoduler"
+
+#: src/sudo.c:213
+msgid "unable to initialize policy plugin"
+msgstr "kan ikke initialisere udvidelsesmodul for politik"
+
+#: src/sudo.c:257
+msgid "plugin did not return a command to execute"
+msgstr "udvidelsesmodul returnerede ikke en kommando til afvikling"
+
+#: src/sudo.c:273
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "fejl under initialisering af I/O-udvidelsesmodulet %s"
+
+#: src/sudo.c:296
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "uventet sudo-tilstand 0x%x"
+
+#: src/sudo.c:474
+msgid "unable to get group vector"
+msgstr "kan ikke indhente gruppevektor"
+
+#: src/sudo.c:552
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "ukendt uid %u: hvem er du?"
+
+#: src/sudo.c:608
+msgid "unable to determine tty"
+msgstr "kunne ikke bestemme tty"
+
+#: src/sudo.c:896
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s skal være ejet af uid %d og have setuid bit angivet"
+
+#: src/sudo.c:899
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "effektiv uid er ikke %d, er %s på et filsystem med indstillingen »nosuid« angivet eller et NFS-filsytsem uden administratorprivilegier (root)?"
+
+#: src/sudo.c:905
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "effektiv uid er ikke %d, er sudo installeret setuid root?"
+
+#: src/sudo.c:958
+msgid "unable to set supplementary group IDs"
+msgstr "kunne ikke angive supplerende gruppe-id'er"
+
+#: src/sudo.c:965
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "kan ikke angive effektiv gid til runas gid %u"
+
+#: src/sudo.c:971
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "kunne ikke angive gid til runas gid %u"
+
+#: src/sudo.c:1028
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "uventet underbetingelse for terminering: %d"
+
+#: src/sudo.c:1174
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "politikudvidelsesmodulet %s mangler i metoden »check_policy«"
+
+#: src/sudo.c:1192
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "politikudvidelsesmodul %s understøter ikke listning af privilegier"
+
+#: src/sudo.c:1209
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "politikudvidelsesmodul %s understøtter ikke tilvalget -v"
+
+#: src/sudo.c:1224
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "politikudvidelsesmodul %s understøtter ikke tilvalget -k/-K"
+
+#: src/sudo_edit.c:213
+msgid "no writable temporary directory found"
+msgstr "ingen skrivbar midlertidig mappe fundet"
+
+#: src/sudo_edit.c:280 src/sudo_edit.c:369
+msgid "unable to restore current working directory"
+msgstr "kan ikke gendanne nuværende arbejdsmappe"
+
+#: src/sudo_edit.c:578 src/sudo_edit.c:690
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: ikke en regulær fil"
+
+#: src/sudo_edit.c:585
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: redigering af symbolske henvisninger er ikke tilladt"
+
+#: src/sudo_edit.c:588
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: redigering af filer i en skrivbar mappe er ikke tilladt"
+
+#: src/sudo_edit.c:621 src/sudo_edit.c:728
+#, c-format
+msgid "%s: short write"
+msgstr "%s: kort skrivning"
+
+#: src/sudo_edit.c:691
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s tilbage uændrede"
+
+#: src/sudo_edit.c:704 src/sudo_edit.c:889
+#, c-format
+msgid "%s unchanged"
+msgstr "%s uændrede"
+
+#: src/sudo_edit.c:717 src/sudo_edit.c:739
+#, c-format
+msgid "unable to write to %s"
+msgstr "kan ikke skrive til %s"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:737 src/sudo_edit.c:740
+#: src/sudo_edit.c:914 src/sudo_edit.c:918
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "indhold fra redigeringssession tilbage i %s"
+
+#: src/sudo_edit.c:736
+msgid "unable to read temporary file"
+msgstr "kan ikke læse midlertidig fil"
+
+#: src/sudo_edit.c:819
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: intern fejl: forkert antal stier"
+
+#: src/sudo_edit.c:821
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: kan ikke oprette midlertidige filer"
+
+#: src/sudo_edit.c:823 src/sudo_edit.c:921
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: ukendt fejl %d"
+
+#: src/sudo_edit.c:913
+msgid "unable to copy temporary files back to their original location"
+msgstr "kan ikke kopiere midlertidige filer tilbage til deres originale placering"
+
+#: src/sudo_edit.c:917
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "kan ikke kopiere nogle af de midlertidige filer tilbage til deres originale placering"
+
+#: src/sudo_edit.c:962
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "kunne ikke ændre uid til root (%u)"
+
+#: src/sudo_edit.c:979
+msgid "plugin error: missing file list for sudoedit"
+msgstr "fejl i udvidelsesmodul: mangler filliste for sudoedit"
+
+#: src/sudo_edit.c:1020 src/sudo_edit.c:1033
+msgid "unable to read the clock"
+msgstr "kunne ikke læse uret"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr "ingen tty til stede og intet askpass-program angivet"
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "intet askpass-program angivet, forsøg at angive SUDO_ASKPASS"
+
+#: src/tgetpass.c:269
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "kan ikke angive gid til %u"
+
+#: src/tgetpass.c:273
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "kan ikke angive uid til %u"
+
+#: src/tgetpass.c:278
+#, c-format
+msgid "unable to run %s"
+msgstr "kan ikke køre %s"
+
+#: src/utmp.c:266
+msgid "unable to save stdin"
+msgstr "kan ikke gemme til stdin"
+
+#: src/utmp.c:268
+msgid "unable to dup2 stdin"
+msgstr "kan ikke dup2 stdin"
+
+#: src/utmp.c:271
+msgid "unable to restore stdin"
+msgstr "kan ikke gendanne stdin"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "fejl under læsning fra signaldatakanal"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "fejl ved læsning fra datakanal"
diff --git a/po/de.mo b/po/de.mo
new file mode 100644
index 0000000..beb151c
--- /dev/null
+++ b/po/de.mo
Binary files differ
diff --git a/po/de.po b/po/de.po
new file mode 100644
index 0000000..104c394
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,881 @@
+# German translation for sudo.
+# This file is distributed under the same license as the sudo package.
+#
+# Jakob Kramer <jakob.kramer@gmx.de>, 2012, 2013, 2014.
+# Mario Blättermann <mario.blaettermann@gmail.com>, 2012, 2014-2017.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.20b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2017-03-09 11:58-0700\n"
+"PO-Revision-Date: 2017-03-26 21:25+0200\n"
+"Last-Translator: Mario Blättermann <mario.blaettermann@gmail.com>\n"
+"Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.8.12\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:172
+msgid "unable to open userdb"
+msgstr "Benutzerdatenbank konnte nicht geöffnet werden"
+
+#: lib/util/aix.c:227
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "Es konnte nicht zur Registrierungsdatenbank »%s« von %s gewechselt werden"
+
+#: lib/util/aix.c:252
+msgid "unable to restore registry"
+msgstr "Registrierungsdatenbank konnte nicht wiederhergestellt werden"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:184 lib/util/sudo_conf.c:270 lib/util/sudo_conf.c:347
+#: lib/util/sudo_conf.c:545 src/conversation.c:75 src/exec_common.c:107
+#: src/exec_common.c:123 src/exec_common.c:132 src/exec_monitor.c:214
+#: src/exec_nopty.c:326 src/exec_pty.c:623 src/exec_pty.c:631
+#: src/exec_pty.c:868 src/load_plugins.c:52 src/load_plugins.c:65
+#: src/load_plugins.c:215 src/load_plugins.c:238 src/load_plugins.c:303
+#: src/load_plugins.c:318 src/parse_args.c:183 src/parse_args.c:205
+#: src/parse_args.c:376 src/parse_args.c:472 src/parse_args.c:494
+#: src/preserve_fds.c:47 src/preserve_fds.c:130 src/selinux.c:83
+#: src/selinux.c:292 src/selinux.c:415 src/selinux.c:424 src/sesh.c:115
+#: src/sudo.c:398 src/sudo.c:423 src/sudo.c:488 src/sudo.c:610 src/sudo.c:670
+#: src/sudo.c:680 src/sudo.c:700 src/sudo.c:719 src/sudo.c:728 src/sudo.c:737
+#: src/sudo.c:754 src/sudo.c:795 src/sudo.c:805 src/sudo.c:825 src/sudo.c:1246
+#: src/sudo.c:1267 src/sudo.c:1441 src/sudo.c:1535 src/sudo_edit.c:151
+#: src/sudo_edit.c:775 src/sudo_edit.c:872 src/sudo_edit.c:985
+#: src/sudo_edit.c:1005
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/sudo_conf.c:185
+#: lib/util/sudo_conf.c:270 lib/util/sudo_conf.c:347 lib/util/sudo_conf.c:545
+#: src/conversation.c:76 src/exec_common.c:107 src/exec_common.c:124
+#: src/exec_common.c:133 src/exec_pty.c:623 src/exec_pty.c:631
+#: src/exec_pty.c:868 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:183
+#: src/parse_args.c:205 src/parse_args.c:376 src/parse_args.c:472
+#: src/parse_args.c:494 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:83 src/selinux.c:292 src/selinux.c:415 src/selinux.c:424
+#: src/sesh.c:115 src/sudo.c:398 src/sudo.c:423 src/sudo.c:488 src/sudo.c:610
+#: src/sudo.c:825 src/sudo.c:1246 src/sudo.c:1267 src/sudo.c:1441
+#: src/sudo.c:1535 src/sudo_edit.c:151 src/sudo_edit.c:775 src/sudo_edit.c:872
+#: src/sudo_edit.c:985 src/sudo_edit.c:1005
+msgid "unable to allocate memory"
+msgstr "Speicher konnte nicht zugewiesen werden"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "Unbekanntes Signal"
+
+#: lib/util/strtoid.c:77 lib/util/strtoid.c:124 lib/util/strtoid.c:152
+#: lib/util/strtomode.c:49 lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "ungültiger Wert"
+
+#: lib/util/strtoid.c:84 lib/util/strtoid.c:131 lib/util/strtoid.c:159
+#: lib/util/strtomode.c:55 lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "Wert zu groß"
+
+#: lib/util/strtoid.c:86 lib/util/strtoid.c:137 lib/util/strtomode.c:55
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "Wert zu klein"
+
+#: lib/util/sudo_conf.c:203
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "Ungültiger Pfad-Wert »%s« in %s, Zeile %u"
+
+#: lib/util/sudo_conf.c:369 lib/util/sudo_conf.c:422
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "Ungültiger Wert für %s »%s« in %s, Zeile %u"
+
+#: lib/util/sudo_conf.c:390
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "Nicht unterstützte Gruppenquelle »%s« in %s, Zeile %u"
+
+#: lib/util/sudo_conf.c:406
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "Ungültige Maximalzahl an Gruppen »%s« in %s, Zeile %u"
+
+#: lib/util/sudo_conf.c:561
+#, c-format
+msgid "unable to stat %s"
+msgstr "stat konnte nicht auf %s angewendet werden"
+
+#: lib/util/sudo_conf.c:564
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s ist keine reguläre Datei"
+
+#: lib/util/sudo_conf.c:567
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s gehört Benutzer mit UID %u, sollte allerdings %u gehören"
+
+#: lib/util/sudo_conf.c:571
+#, c-format
+msgid "%s is world writable"
+msgstr "%s kann von allen verändert werden"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "%s is group writable"
+msgstr "%s kann von der Gruppe verändert werden"
+
+#: lib/util/sudo_conf.c:584 src/selinux.c:201 src/selinux.c:213 src/sudo.c:366
+#, c-format
+msgid "unable to open %s"
+msgstr "%s konnte nicht geöffnet werden"
+
+#: src/exec.c:189 src/exec_monitor.c:504 src/exec_monitor.c:506
+#: src/exec_monitor.c:511 src/exec_monitor.c:513 src/exec_monitor.c:527
+#: src/exec_monitor.c:538 src/exec_monitor.c:540 src/exec_monitor.c:542
+#: src/exec_monitor.c:544 src/exec_monitor.c:546 src/exec_monitor.c:548
+#: src/exec_monitor.c:550 src/exec_nopty.c:191 src/exec_nopty.c:193
+#: src/exec_nopty.c:195 src/exec_nopty.c:197 src/exec_nopty.c:199
+#: src/exec_nopty.c:201 src/exec_nopty.c:203 src/exec_nopty.c:205
+#: src/exec_nopty.c:208 src/exec_nopty.c:222 src/exec_nopty.c:224
+#: src/exec_nopty.c:226 src/exec_nopty.c:384 src/exec_pty.c:427
+#: src/exec_pty.c:661 src/exec_pty.c:1196 src/exec_pty.c:1198
+#: src/exec_pty.c:1200 src/exec_pty.c:1202 src/exec_pty.c:1204
+#: src/exec_pty.c:1206 src/exec_pty.c:1208 src/exec_pty.c:1211
+#: src/exec_pty.c:1219 src/exec_pty.c:1221 src/exec_pty.c:1223
+#: src/exec_pty.c:1231 src/exec_pty.c:1233 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "Handler für Signal %d konnte nicht gesetzt werden"
+
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "PRIV_PROC_EXEC konnte nicht von PRIV_LIMIT entfernt werden"
+
+#: src/exec_monitor.c:277 src/exec_nopty.c:455 src/exec_pty.c:1028
+msgid "error reading from signal pipe"
+msgstr "Fehler beim Lesen der Signal-Pipe"
+
+#: src/exec_monitor.c:363
+msgid "error reading from socketpair"
+msgstr "Fehler beim Lesen des Socket-Paars"
+
+#: src/exec_monitor.c:372
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "Unerwarteter Antworttyp auf Rückmeldungskanal: %d"
+
+#: src/exec_monitor.c:450 src/exec_monitor.c:458 src/exec_monitor.c:466
+#: src/exec_nopty.c:130 src/exec_nopty.c:138 src/exec_pty.c:516
+#: src/exec_pty.c:521 src/exec_pty.c:591 src/exec_pty.c:598 src/exec_pty.c:873
+#: src/exec_pty.c:1129 src/exec_pty.c:1137 src/exec_pty.c:1322
+#: src/exec_pty.c:1332 src/exec_pty.c:1377 src/exec_pty.c:1384
+#: src/exec_pty.c:1409
+msgid "unable to add event to queue"
+msgstr "Ereignis konnte nicht zur Warteschlange hinzugefügt werden"
+
+#: src/exec_monitor.c:496 src/exec_monitor.c:570 src/exec_nopty.c:161
+#: src/exec_pty.c:705 src/exec_pty.c:714 src/exec_pty.c:722 src/signal.c:129
+#: src/tgetpass.c:246
+msgid "unable to create pipe"
+msgstr "Weiterleitung konnte nicht erstellt werden"
+
+#: src/exec_monitor.c:562
+msgid "unable to set controlling tty"
+msgstr "Kontrollierendes TTY konnte nicht gesetzt werden"
+
+#: src/exec_monitor.c:573 src/exec_nopty.c:240 src/exec_pty.c:756
+#: src/tgetpass.c:250
+msgid "unable to fork"
+msgstr "Es konnte nicht geforkt werden"
+
+#: src/exec_monitor.c:654 src/exec_nopty.c:292
+msgid "unable to restore tty label"
+msgstr "TTY-Kennzeichnung konnte nicht wiederhergestellt werden"
+
+#: src/exec_nopty.c:233 src/exec_pty.c:1240
+msgid "policy plugin failed session initialization"
+msgstr "Regelwerks-Plugin konnte Sitzung nicht initialisieren"
+
+#: src/exec_nopty.c:281 src/exec_pty.c:1278
+msgid "error in event loop"
+msgstr "Fehler in Ereignisschleife"
+
+#: src/exec_nopty.c:392 src/exec_pty.c:459 src/signal.c:87
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "Handler für Signal %d konnte nicht wiederhergestellt werden"
+
+#: src/exec_pty.c:133
+msgid "unable to allocate pty"
+msgstr "PTY konnte nicht vergeben werden"
+
+#: src/exec_pty.c:1179
+msgid "unable to create sockets"
+msgstr "Sockets konnten nicht hergestellt werden"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "Fehler in %s, Zeile %d, während Plugin »%s« geladen wurde"
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s muss Benutzer mit UID %d gehören"
+
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s darf nur vom Besitzer beschreibbar sein"
+
+#: src/load_plugins.c:172
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "»%s« konnte nicht geladen werden: %s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "Symbol »%s« konnte in %s nicht gefunden werden"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "Unbekannter Regelwerktyp %d wurde in %s gefunden"
+
+#: src/load_plugins.c:193
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "Inkompatible Hauptversion %d des Regelwerks (%d erwartet) wurde in %s gefunden"
+
+#: src/load_plugins.c:202
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "Regelwerks-Plugin »%s« in %s, Zeile %d, wird ignoriert"
+
+#: src/load_plugins.c:204
+msgid "only a single policy plugin may be specified"
+msgstr "Nur ein einziges Regelwerks-Plugin kann geladen werden"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "Doppelt vorhandenes Regelwerks-Plugin »%s« in %s, Zeile %d, wird ignoriert"
+
+#: src/load_plugins.c:228
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "Doppelt vorhandenes E/A-Plugin »%s« in %s, Zeile %d, wird ignoriert"
+
+#: src/load_plugins.c:331
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "Das Regelwerks-Plugin %s enthält keine check_policy-Methode"
+
+#: src/net_ifs.c:173 src/net_ifs.c:190 src/net_ifs.c:335 src/sudo.c:483
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "Interner Fehler: %s-Überlauf"
+
+#: src/parse_args.c:242
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "Das Argument für -C muss eine Zahl größer oder gleich 3 sein"
+
+#: src/parse_args.c:412
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "Die Optionen »-i« und »-s« können nicht gemeinsam benutzt werden"
+
+#: src/parse_args.c:416
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "Die Optionen »-i« und »-E« können nicht gemeinsam benutzt werden"
+
+#: src/parse_args.c:426
+msgid "the `-E' option is not valid in edit mode"
+msgstr "Die Option »-E« ist im Bearbeiten-Modus ungültig"
+
+#: src/parse_args.c:428
+msgid "you may not specify environment variables in edit mode"
+msgstr "Im Bearbeiten-Modus können keine Umgebungsvariablen gesetzt werden"
+
+#: src/parse_args.c:436
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "Die »-U«-Option kann nur zusammen mit »-l« benutzt werden"
+
+#: src/parse_args.c:440
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "Die Optionen »-A« und »-S« können nicht gemeinsam benutzt werden"
+
+#: src/parse_args.c:516
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit ist auf dieser Plattform nicht verfügbar"
+
+#: src/parse_args.c:589
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Nur eine der Optionen -e, -h, -i, -K, -l, -s, -v oder -V darf angegeben werden"
+
+#: src/parse_args.c:603
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - Dateien als anderer Benutzer verändern\n"
+"\n"
+
+#: src/parse_args.c:605
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - Einen Befehl als anderer Benutzer ausführen\n"
+"\n"
+
+#: src/parse_args.c:610
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Optionen:\n"
+
+#: src/parse_args.c:612
+msgid "use a helper program for password prompting"
+msgstr "Hilfsprogramm zum Eingeben des Passworts verwenden"
+
+#: src/parse_args.c:615
+msgid "use specified BSD authentication type"
+msgstr "Angegebenen BSD-Legitimierungstypen verwenden"
+
+#: src/parse_args.c:618
+msgid "run command in the background"
+msgstr "Befehl im Hintergrund ausführen"
+
+#: src/parse_args.c:620
+msgid "close all file descriptors >= num"
+msgstr "Alle Dateideskriptoren >= num schließen"
+
+#: src/parse_args.c:623
+msgid "run command with the specified BSD login class"
+msgstr "Befehl unter angegebener Login-Klasse ausführen"
+
+#: src/parse_args.c:626
+msgid "preserve user environment when running command"
+msgstr "Benutzerumgebung beim Starten des Befehls beibehalten"
+
+#: src/parse_args.c:628
+msgid "edit files instead of running a command"
+msgstr "Dateien bearbeiten, statt einen Befehl auszuführen"
+
+#: src/parse_args.c:630
+msgid "run command as the specified group name or ID"
+msgstr "Befehl unter angegebenem Gruppennamen oder Gruppen-ID ausführen"
+
+#: src/parse_args.c:632
+msgid "set HOME variable to target user's home dir"
+msgstr "HOME-Variable als Home-Verzeichnis des Zielbenutzers setzen"
+
+#: src/parse_args.c:634
+msgid "display help message and exit"
+msgstr "Hilfe ausgeben und beenden"
+
+#: src/parse_args.c:636
+msgid "run command on host (if supported by plugin)"
+msgstr "Befehl auf entferntem System ausführen (falls vom Plugin unterstützt)"
+
+#: src/parse_args.c:638
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "Anmeldeshell als Zielbenutzer starten; es kann auch ein Befehl angegeben werden"
+
+#: src/parse_args.c:640
+msgid "remove timestamp file completely"
+msgstr "Zeitstempeldateien komplett entfernen"
+
+#: src/parse_args.c:642
+msgid "invalidate timestamp file"
+msgstr "Zeitstempeldatei ungültig machen"
+
+#: src/parse_args.c:644
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "Benutzerrechte aufzählen oder einen bestimmten Befehl testen; für ein längeres Format zweimal angeben"
+
+#: src/parse_args.c:646
+msgid "non-interactive mode, no prompts are used"
+msgstr "Nicht-interaktiver Modus, es werden keine Prompts verwendet"
+
+#: src/parse_args.c:648
+msgid "preserve group vector instead of setting to target's"
+msgstr "Gruppen-Vektor beibehalten, statt auf den des Zielbenutzers zu setzen"
+
+#: src/parse_args.c:650
+msgid "use the specified password prompt"
+msgstr "Angegebenen Passwort-Prompt benutzen"
+
+#: src/parse_args.c:653
+msgid "create SELinux security context with specified role"
+msgstr "SELinux-Sicherheitskontext mit angegebener Funktion erstellen"
+
+#: src/parse_args.c:656
+msgid "read password from standard input"
+msgstr "Passwort von der Standardeingabe lesen"
+
+#: src/parse_args.c:658
+msgid "run shell as the target user; a command may also be specified"
+msgstr "Shell als Zielbenutzer ausführen; es kann auch ein Befehl angegeben werden"
+
+#: src/parse_args.c:661
+msgid "create SELinux security context with specified type"
+msgstr "SELinux-Sicherheitskontext mit angegebenem Typ erstellen"
+
+#: src/parse_args.c:664
+msgid "terminate command after the specified time limit"
+msgstr "Befehlausführung nach der angegebenen Zeitbegrenzung abbrechen"
+
+#: src/parse_args.c:666
+msgid "in list mode, display privileges for user"
+msgstr "im Aufzählungsmodus, Rechte des Benutzers anzeigen"
+
+#: src/parse_args.c:668
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "Befehl oder Datei unter angegebenem Benutzernamen oder Benutzer-ID ausführen bzw. ändern"
+
+#: src/parse_args.c:670
+msgid "display version information and exit"
+msgstr "Versionsinformation anzeigen und beenden"
+
+#: src/parse_args.c:672
+msgid "update user's timestamp without running a command"
+msgstr "Den Zeitstempel des Benutzers erneuern, ohne einen Befehl auszuführen"
+
+#: src/parse_args.c:674
+msgid "stop processing command line arguments"
+msgstr "Aufhören, die Befehlszeilenargumente zu verarbeiten"
+
+#: src/selinux.c:77
+msgid "unable to open audit system"
+msgstr "Das Audit-System konnte nicht geöffnet werden"
+
+#: src/selinux.c:87
+msgid "unable to send audit message"
+msgstr "Die Audit-Nachricht konnte nicht verschickt werden"
+
+#: src/selinux.c:115
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "»fgetfilecon« konnte nicht auf %s angewendet werden"
+
+#: src/selinux.c:120
+#, c-format
+msgid "%s changed labels"
+msgstr "%s änderte die Kennzeichnung"
+
+#: src/selinux.c:125
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "Der Kontext für %s konnte nicht wiederhergestellt werden"
+
+#: src/selinux.c:165
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "%s konnte nicht geöffnet werden, TTY wird nicht neu gekennzeichnet"
+
+#: src/selinux.c:173
+msgid "unable to get current tty context, not relabeling tty"
+msgstr ""
+"Aktueller TTY-Kontext konnte nicht festgestellt werden, TTY wird nicht neu\n"
+"gekennzeichnet."
+
+#: src/selinux.c:180
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "Unbekannte Sicherheitsklasse »chr_file«, TTY wird nicht neu gekennzeichnet."
+
+#: src/selinux.c:185
+msgid "unable to get new tty context, not relabeling tty"
+msgstr ""
+"Neuer TTY-Kontext konnte nicht festgestellt werden, TTY wird nicht neu\n"
+"gekennzeichnet."
+
+#: src/selinux.c:192
+msgid "unable to set new tty context"
+msgstr "Neuer TTY-Kontext konnte nicht festgestellt werden"
+
+#: src/selinux.c:256
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "Für den Typen %s muss eine Funktion angegeben werden"
+
+#: src/selinux.c:262
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "Standardtyp für Funktion %s konnte nicht ermittelt werden"
+
+#: src/selinux.c:280
+#, c-format
+msgid "failed to set new role %s"
+msgstr "Neue Funktion %s konnte nicht festgelegt werden"
+
+#: src/selinux.c:284
+#, c-format
+msgid "failed to set new type %s"
+msgstr "Neuer Typ %s konnte nicht festgelegt werden"
+
+#: src/selinux.c:296
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s ist kein gültiger Kontext"
+
+#: src/selinux.c:331
+msgid "failed to get old_context"
+msgstr "»old_context« konnte nicht wiedergeholt werden"
+
+#: src/selinux.c:337
+msgid "unable to determine enforcing mode."
+msgstr "»Enforcing«-Modus konnte nicht bestimmt werden."
+
+#: src/selinux.c:354
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "TTY-Kontext konnte nicht auf %s gesetzt werden"
+
+#: src/selinux.c:393
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "Ausführungskontext konnte nicht auf »%s« gesetzt werden"
+
+#: src/selinux.c:400
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "Kontext der Schüsselerstellung konnte nicht auf %s festgelegt werden."
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "Benötigt mindestens ein Argument"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "Unzulässige Dateideskriptornummer: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "%s konnte nicht als Anmeldeshell ausgeführt werden"
+
+#: src/sesh.c:125 src/sudo.c:1305
+#, c-format
+msgid "unable to execute %s"
+msgstr "%s konnte nicht ausgeführt werden"
+
+#: src/signal.c:69
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "Handler für Signal %d konnte nicht gespeichert werden"
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "Limit der Ressourcenkontrolle wurde erreicht"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "Benutzer »%s« ist kein Mitglied des Projekts »%s«"
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr "Der aufrufende Prozess ist fertig"
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "Projekt »%s« konnte nicht beigetreten werden"
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "Für Projekt »%s« gibt es keinen Ressourcen-Pool, der die Standardanbindungen unterstützt."
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "Den angegebenen Ressourcen-Pool gibt es für das Projekt »%s« nicht"
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "Es konnte nicht zum Standard-Ressourcen-Pool für Projekt »%s« verbunden werden."
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "»setproject« schlug für Projekt »%s« fehl"
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "Warnung: Ressourcenkontrolle von Projekt »%s« konnte nicht zugewiesen werden"
+
+#: src/sudo.c:212
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo-Version %s\n"
+
+#: src/sudo.c:214
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Optionen für »configure«: %s\n"
+
+#: src/sudo.c:222
+msgid "fatal error, unable to load plugins"
+msgstr "Schwerwiegender Fehler, Plugins konnten nicht geladen werden"
+
+#: src/sudo.c:230
+msgid "unable to initialize policy plugin"
+msgstr "Regelwerks-Plugin konnte nicht initialisiert werden"
+
+#: src/sudo.c:274
+msgid "plugin did not return a command to execute"
+msgstr "Plugin gab keinen auszuführenden Befehl zurück"
+
+#: src/sudo.c:290
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "E/A-Plugin %s konnte nicht initialisiert werden"
+
+#: src/sudo.c:316
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "Unerwarteter sudo-Modus 0x%x"
+
+#: src/sudo.c:468
+msgid "unable to get group vector"
+msgstr "Gruppenvektor konnte nicht geholt werden"
+
+#: src/sudo.c:530
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "Unbekannte UID %u: Wer sind Sie?"
+
+#: src/sudo.c:586
+msgid "unable to determine tty"
+msgstr "TTY konnte nicht ermittelt werden"
+
+#: src/sudo.c:874
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s muss dem Benutzer mit UID %d gehören und das »setuid«-Bit gesetzt haben"
+
+#: src/sudo.c:877
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "Effektive UID ist nicht %d. Liegt %s auf einem Dateisystem mit gesetzter »nosuid«-Option oder auf einem NFS-Dateisystem ohne Root-Rechte?"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "Effektive UID ist nicht %d. Wurde sudo mit »setuid root« installiert?"
+
+#: src/sudo.c:964
+msgid "unable to set supplementary group IDs"
+msgstr "Zusätzliche Gruppenkennungen konnten nicht gesetzt werden"
+
+#: src/sudo.c:971
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "Effektive GID konnte nicht auf »runas«-GID %u gesetzt werden"
+
+#: src/sudo.c:977
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "GID konnte nicht auf »runas«-GID %u gesetzt werden"
+
+#: src/sudo.c:1048
+#, c-format
+msgid "unknown login class %s"
+msgstr "Unbekannte Anmeldungsklasse %s"
+
+#: src/sudo.c:1061
+msgid "unable to set user context"
+msgstr "Benutzerkontext konnte nicht gesetzt werden"
+
+#: src/sudo.c:1077
+msgid "unable to set process priority"
+msgstr "Prozesspriorität konnte nicht gesetzt werden"
+
+#: src/sudo.c:1085
+#, c-format
+msgid "unable to change root to %s"
+msgstr "Wurzelverzeichnis konnte nicht zu %s geändert werden"
+
+#: src/sudo.c:1098 src/sudo.c:1104 src/sudo.c:1111
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "Es konnte nicht zu »runas«-GID gewechselt werden (%u, %u)"
+
+#: src/sudo.c:1129
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "In Verzeichnis »%s« konnte nicht gewechselt werden"
+
+#: src/sudo.c:1187
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "Unerwartete Abbruchbedingung eines Unterprozesses: %d"
+
+#: src/sudo.c:1333
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "Dem Regelwerks-Plugin %s fehlt die »check_policy«-Methode"
+
+#: src/sudo.c:1351
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "Regelwerks-Plugin %s unterstützt das Auflisten von Privilegien nicht"
+
+#: src/sudo.c:1368
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "Regelwerks-Plugin %s unterstützt die Option -v nicht"
+
+#: src/sudo.c:1383
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "Regelwerks-Plugin %s unterstützt die Optionen -k und -K nicht"
+
+#: src/sudo_edit.c:181 src/sudo_edit.c:270
+msgid "unable to restore current working directory"
+msgstr "Aktueller Arbeitsordner konnte nicht wiederhergestellt werden"
+
+#: src/sudo_edit.c:577 src/sudo_edit.c:689
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: Keine reguläre Datei"
+
+#: src/sudo_edit.c:584
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: Bearbeiten symbolischer Links ist nicht erlaubt"
+
+#: src/sudo_edit.c:587
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: Bearbeiten von Dateien in einem beschreibbaren Ordner ist nicht erlaubt"
+
+#: src/sudo_edit.c:620 src/sudo_edit.c:728
+#, c-format
+msgid "%s: short write"
+msgstr "%s: Zu kurzer Schreibvorgang"
+
+#: src/sudo_edit.c:690
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s blieb unverändert"
+
+#: src/sudo_edit.c:703 src/sudo_edit.c:889
+#, c-format
+msgid "%s unchanged"
+msgstr "%s unverändert"
+
+#: src/sudo_edit.c:717 src/sudo_edit.c:739
+#, c-format
+msgid "unable to write to %s"
+msgstr "%s konnte nicht beschrieben werden"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:737 src/sudo_edit.c:740
+#: src/sudo_edit.c:914 src/sudo_edit.c:918
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "Bearbeitungssitzung wurden in %s gelassen"
+
+#: src/sudo_edit.c:736
+msgid "unable to read temporary file"
+msgstr "Temporäre Datei konnte nicht gelesen werden"
+
+#: src/sudo_edit.c:819
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: interner Fehler: seltsame Anzahl an Pfaden"
+
+#: src/sudo_edit.c:821
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: Temporäre Dateien konnten nicht angelegt werden"
+
+#: src/sudo_edit.c:823 src/sudo_edit.c:921
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: unbekannter Fehler %d"
+
+#: src/sudo_edit.c:913
+msgid "unable to copy temporary files back to their original location"
+msgstr "Temporäre Dateien konnten nicht an ihre ursprünglichen Orte zurück kopiert werden"
+
+#: src/sudo_edit.c:917
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "Einige der temporären Dateien konnten nicht an ihre ursprünglichen Orte zurück kopiert werden"
+
+#: src/sudo_edit.c:961
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "UID konnte nicht zu Root (%u) geändert werden"
+
+#: src/sudo_edit.c:978
+msgid "plugin error: missing file list for sudoedit"
+msgstr "Plugin-Fehler: Fehlende Dateiliste für sudoedit"
+
+#: src/sudo_edit.c:1019 src/sudo_edit.c:1032
+msgid "unable to read the clock"
+msgstr "Die Uhr konnte nicht gelesen werden"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr "Kein TTY vorhanden und kein »askpass«-Programm angegeben"
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "Kein »askpass«-Programm angegeben, es wird versucht, SUDO_ASKPASS zu setzen"
+
+#: src/tgetpass.c:261
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "GID konnte nicht als %u festgelegt werden"
+
+#: src/tgetpass.c:265
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "UID konnte nicht als %u festgelegt werden"
+
+#: src/tgetpass.c:270
+#, c-format
+msgid "unable to run %s"
+msgstr "%s konnte nicht ausgeführt werden"
+
+#: src/utmp.c:268
+msgid "unable to save stdin"
+msgstr "Standardeingabe konnte nicht gespeichert werden"
+
+#: src/utmp.c:270
+msgid "unable to dup2 stdin"
+msgstr "dup2 konnte nicht auf die Standardeingabe angewendet werden"
+
+#: src/utmp.c:273
+msgid "unable to restore stdin"
+msgstr "Standardeingabe konnte nicht wiederhergestellt werden"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "Fehler beim Lesen der Pipe"
diff --git a/po/eo.mo b/po/eo.mo
new file mode 100644
index 0000000..5cb71ec
--- /dev/null
+++ b/po/eo.mo
Binary files differ
diff --git a/po/eo.po b/po/eo.po
new file mode 100644
index 0000000..d7a47d7
--- /dev/null
+++ b/po/eo.po
@@ -0,0 +1,953 @@
+# Esperanto translations for sudo package.
+# This file is put in the public domain.
+# Felipe Castro <fefcat@gmail.com>, 2013, 2014, 2015, 2016, 2017, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.23b3\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-04-05 06:36-0600\n"
+"PO-Revision-Date: 2018-06-28 20:36-0300\n"
+"Last-Translator: Felipe Castro <fefcas@gmail.com>\n"
+"Language-Team: Esperanto <translation-team-eo@lists.sourceforge.net>\n"
+"Language: eo\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.5.4\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:172
+msgid "unable to open userdb"
+msgstr "ne eblas malfermi la uzanto-datumbazon"
+
+#: lib/util/aix.c:227
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "ne eblas ŝanĝiĝi al registrejo \"%s\" por %s"
+
+#: lib/util/aix.c:252
+msgid "unable to restore registry"
+msgstr "ne eblas restarigi registrejon"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:186 lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349
+#: lib/util/sudo_conf.c:553 src/conversation.c:75 src/exec_common.c:107
+#: src/exec_common.c:123 src/exec_common.c:132 src/exec_monitor.c:168
+#: src/exec_nopty.c:462 src/exec_pty.c:735 src/exec_pty.c:744
+#: src/exec_pty.c:815 src/exec_pty.c:942 src/load_plugins.c:52
+#: src/load_plugins.c:65 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:198 src/parse_args.c:273 src/parse_args.c:559
+#: src/parse_args.c:581 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:112 src/sudo.c:386 src/sudo.c:413 src/sudo.c:494 src/sudo.c:632
+#: src/sudo.c:692 src/sudo.c:702 src/sudo.c:722 src/sudo.c:741 src/sudo.c:750
+#: src/sudo.c:759 src/sudo.c:776 src/sudo.c:817 src/sudo.c:827 src/sudo.c:847
+#: src/sudo.c:1087 src/sudo.c:1108 src/sudo.c:1282 src/sudo.c:1380
+#: src/sudo_edit.c:250 src/sudo_edit.c:775 src/sudo_edit.c:872
+#: src/sudo_edit.c:986 src/sudo_edit.c:1006
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/sudo_conf.c:187
+#: lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349 lib/util/sudo_conf.c:553
+#: src/conversation.c:76 src/exec_common.c:107 src/exec_common.c:124
+#: src/exec_common.c:133 src/exec_pty.c:735 src/exec_pty.c:744
+#: src/exec_pty.c:815 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:199 src/parse_args.c:273 src/parse_args.c:559
+#: src/parse_args.c:581 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:112 src/sudo.c:386 src/sudo.c:413 src/sudo.c:494 src/sudo.c:632
+#: src/sudo.c:847 src/sudo.c:1087 src/sudo.c:1108 src/sudo.c:1282
+#: src/sudo.c:1380 src/sudo_edit.c:250 src/sudo_edit.c:775 src/sudo_edit.c:872
+#: src/sudo_edit.c:986 src/sudo_edit.c:1006
+msgid "unable to allocate memory"
+msgstr "ne eblas generi memoron"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "Nekonata signalo"
+
+#: lib/util/strtoid.c:77 lib/util/strtoid.c:124 lib/util/strtoid.c:152
+#: lib/util/strtomode.c:49 lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "nevalida valoro"
+
+#: lib/util/strtoid.c:84 lib/util/strtoid.c:131 lib/util/strtoid.c:159
+#: lib/util/strtomode.c:55 lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "valoro tro grandas"
+
+#: lib/util/strtoid.c:86 lib/util/strtoid.c:137 lib/util/strtomode.c:55
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "valoro tro malgrandas"
+
+#: lib/util/sudo_conf.c:205
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "nevalida voja valoro \"%s\" en %s, linio %u"
+
+#: lib/util/sudo_conf.c:371 lib/util/sudo_conf.c:424
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "nevalida valoro por %s \"%s\" en %s, linio %u"
+
+#: lib/util/sudo_conf.c:392
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "nekomprenata grupa fonto \"%s\" en %s, linio %u"
+
+#: lib/util/sudo_conf.c:408
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "nevalidaj maksimumaj grupoj \"%s\" en %s, linio %u"
+
+#: lib/util/sudo_conf.c:569
+#, c-format
+msgid "unable to stat %s"
+msgstr "ne eblas trovi je %s"
+
+#: lib/util/sudo_conf.c:572
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s estas ne regula dosiero"
+
+#: lib/util/sudo_conf.c:575
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s estas estrata de uid %u, devas esti %u"
+
+#: lib/util/sudo_conf.c:579
+#, c-format
+msgid "%s is world writable"
+msgstr "%s estas skribebla de ĉiuj"
+
+#: lib/util/sudo_conf.c:582
+#, c-format
+msgid "%s is group writable"
+msgstr "%s estas skribebla de la tuta grupo"
+
+#: lib/util/sudo_conf.c:592 src/selinux.c:208 src/selinux.c:225 src/sudo.c:354
+#, c-format
+msgid "unable to open %s"
+msgstr "ne eblas malfermi %s"
+
+#: src/exec.c:160
+#, c-format
+msgid "unknown login class %s"
+msgstr "nekonata ensaluta klaso %s"
+
+#: src/exec.c:173
+msgid "unable to set user context"
+msgstr "ne eblas elekti uzanto-kuntekston"
+
+#: src/exec.c:189
+msgid "unable to set process priority"
+msgstr "ne eblas elekti procezan prioritaton"
+
+#: src/exec.c:197
+#, c-format
+msgid "unable to change root to %s"
+msgstr "ne eblas ŝanĝi ĉefuzanton al %s"
+
+#: src/exec.c:210 src/exec.c:216 src/exec.c:223
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "ne eblas ŝanĝi al plenumigkiela uid (%u, %u)"
+
+#: src/exec.c:241
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "ne eblas ŝanĝi dosierujon al %s"
+
+#: src/exec.c:340 src/exec_monitor.c:528 src/exec_monitor.c:530
+#: src/exec_nopty.c:520 src/exec_pty.c:483 src/exec_pty.c:1258
+#: src/exec_pty.c:1260 src/signal.c:143 src/signal.c:157
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "ne eblas difini traktilon por la signalo %d"
+
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "ne eblas forigi PRIV_PROC_EXEC-on de PRIV_LIMIT"
+
+#: src/exec_monitor.c:322
+msgid "error reading from socketpair"
+msgstr "eraro dum legi la konektingan paron"
+
+#: src/exec_monitor.c:334
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "neatendita respondotipo ĉe la postkanalo: %d"
+
+#: src/exec_monitor.c:425 src/exec_monitor.c:433 src/exec_monitor.c:441
+#: src/exec_monitor.c:448 src/exec_monitor.c:455 src/exec_monitor.c:462
+#: src/exec_monitor.c:469 src/exec_monitor.c:476 src/exec_monitor.c:483
+#: src/exec_monitor.c:490 src/exec_nopty.c:215 src/exec_nopty.c:224
+#: src/exec_nopty.c:231 src/exec_nopty.c:238 src/exec_nopty.c:245
+#: src/exec_nopty.c:252 src/exec_nopty.c:259 src/exec_nopty.c:266
+#: src/exec_nopty.c:273 src/exec_nopty.c:280 src/exec_nopty.c:287
+#: src/exec_nopty.c:294 src/exec_nopty.c:302 src/exec_pty.c:601
+#: src/exec_pty.c:606 src/exec_pty.c:703 src/exec_pty.c:710 src/exec_pty.c:820
+#: src/exec_pty.c:1099 src/exec_pty.c:1108 src/exec_pty.c:1115
+#: src/exec_pty.c:1122 src/exec_pty.c:1129 src/exec_pty.c:1136
+#: src/exec_pty.c:1143 src/exec_pty.c:1150 src/exec_pty.c:1157
+#: src/exec_pty.c:1164 src/exec_pty.c:1171 src/exec_pty.c:1527
+#: src/exec_pty.c:1537 src/exec_pty.c:1582 src/exec_pty.c:1589
+#: src/exec_pty.c:1616
+msgid "unable to add event to queue"
+msgstr "ne eblas aldoni al la atendovico eventon"
+
+#: src/exec_monitor.c:542
+msgid "unable to set controlling tty"
+msgstr "ne eblas elekti la regan tty-on"
+
+#: src/exec_monitor.c:550 src/exec_nopty.c:359 src/exec_pty.c:1337
+#: src/exec_pty.c:1358 src/exec_pty.c:1378 src/tgetpass.c:254
+msgid "unable to create pipe"
+msgstr "ne eblas krei tubon"
+
+#: src/exec_monitor.c:555 src/exec_nopty.c:377 src/exec_pty.c:1416
+#: src/tgetpass.c:258
+msgid "unable to fork"
+msgstr "ne eblas forki"
+
+#: src/exec_monitor.c:567 src/sesh.c:122 src/sudo.c:1146
+#, c-format
+msgid "unable to execute %s"
+msgstr "ne eblas plenumigi: %s"
+
+#: src/exec_monitor.c:650 src/exec_nopty.c:430
+msgid "unable to restore tty label"
+msgstr "ne eblis reatingi tty-etikedon"
+
+#: src/exec_nopty.c:353 src/exec_pty.c:1267
+msgid "policy plugin failed session initialization"
+msgstr "konduta kromprogramo fiaskis dum seanca komenciĝo"
+
+#: src/exec_nopty.c:419 src/exec_pty.c:1485
+msgid "error in event loop"
+msgstr "eraro en la eventa iteracio"
+
+#: src/exec_nopty.c:528 src/exec_pty.c:515 src/signal.c:105
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "ne eblas restarigi traktilon por la signalo %d"
+
+#: src/exec_pty.c:150
+msgid "unable to allocate pty"
+msgstr "ne eblis generi pty-on"
+
+#: src/exec_pty.c:1247
+msgid "unable to create sockets"
+msgstr "ne eblas krei konektingojn"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "eraro en %s, linio %d dum ŝargi kromprogramon \"%s\""
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s devas esti estrita de uid %d"
+
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s estas skribebla nur de estro"
+
+#: src/load_plugins.c:172
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "maleblas ŝarĝi je %s: %s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "ne eblas trovi simbolon \"%s\" en %s"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "nekonata konduta tipo %d trovita en %s"
+
+#: src/load_plugins.c:193
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "malkongrua granda versio %d de kromprogramo (atendite %d) trovita en %s"
+
+#: src/load_plugins.c:202
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "ni malatentas kondutan kromprogramon \"%s\" en %s, linio %d"
+
+#: src/load_plugins.c:204
+msgid "only a single policy plugin may be specified"
+msgstr "nur unu konduta kromprogramo povas esti indikata"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "ni malatentas duobligantan kondutan kromprogramon \"%s\" en %s, linio %d"
+
+#: src/load_plugins.c:228
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "ni malatentas duobligitan eneligan kromprogramon \"%s\" en %s, linio %d"
+
+#: src/load_plugins.c:331
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "konduta kromprogramo %s ne inkluzivas la metodon check_policy"
+
+#: src/net_ifs.c:172 src/net_ifs.c:189 src/net_ifs.c:334 src/sudo.c:489
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "interna eraro, superfluo en %s"
+
+#: src/parse_args.c:219
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "malvalida medivariabla nomo: %s"
+
+#: src/parse_args.c:315
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "la parametro de -C devas esti nombron almenaŭ 3"
+
+#: src/parse_args.c:499
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "vi ne rajtas specifi kaj '-i' kaj '-s'"
+
+#: src/parse_args.c:503
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "vi ne rajtas specifi kaj '-i' kaj '-E'"
+
+#: src/parse_args.c:513
+msgid "the `-E' option is not valid in edit mode"
+msgstr "la parametro '-E' ne validas en redakta reĝimo"
+
+#: src/parse_args.c:515
+msgid "you may not specify environment variables in edit mode"
+msgstr "vi ne rajtas specifi medivariablojn en redakta reĝimo"
+
+#: src/parse_args.c:523
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "la parametro '-U' ne validas kun '-l'"
+
+#: src/parse_args.c:527
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "'-A' kaj '-S' ne eblas uziĝi kune"
+
+#: src/parse_args.c:603
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit ne estas havebla en ĉi tiu platformon"
+
+#: src/parse_args.c:676
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Vi rajtas specifi nur unu el -e, -h, -i, -K, -l, -s, -v aŭ -V"
+
+#: src/parse_args.c:690
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - redakti dosierojn kiel alia uzanto\n"
+"\n"
+
+#: src/parse_args.c:692
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - plenumigi komandon kiel alia uzanto\n"
+"\n"
+
+#: src/parse_args.c:697
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Parametroj:\n"
+
+#: src/parse_args.c:699
+msgid "use a helper program for password prompting"
+msgstr "uzi helpoprogrogramon por pasvortilo"
+
+#: src/parse_args.c:702
+msgid "use specified BSD authentication type"
+msgstr "uzi specifitan BSD-konstatan tipon"
+
+#: src/parse_args.c:705
+msgid "run command in the background"
+msgstr "plenumigi komandon fone"
+
+#: src/parse_args.c:707
+msgid "close all file descriptors >= num"
+msgstr "fermi ĉiujn dosierpriskribilojn >= numeron"
+
+#: src/parse_args.c:710
+msgid "run command with the specified BSD login class"
+msgstr "plenumigi komandon per specifita BSD-ensaluta klaso"
+
+#: src/parse_args.c:713
+msgid "preserve user environment when running command"
+msgstr "konservi uzanto-medivariablojn dum plenumigi komandon"
+
+#: src/parse_args.c:715
+msgid "preserve specific environment variables"
+msgstr "konservi specifajn medivariablojn"
+
+#: src/parse_args.c:717
+msgid "edit files instead of running a command"
+msgstr "redakti dosierojn anstataŭ plenumigi komandon"
+
+#: src/parse_args.c:719
+msgid "run command as the specified group name or ID"
+msgstr "plenumigi komandon kiel la specifitan grupnomon aŭ identigilon"
+
+#: src/parse_args.c:721
+msgid "set HOME variable to target user's home dir"
+msgstr "valorizi medivariablon HOME je la hejma dosierujo de la cela uzanto"
+
+#: src/parse_args.c:723
+msgid "display help message and exit"
+msgstr "elmontri helpan mesaĝon kaj eliri"
+
+#: src/parse_args.c:725
+msgid "run command on host (if supported by plugin)"
+msgstr "plenumigi komandon en gastiganto (se permesata de kromprogramo)"
+
+#: src/parse_args.c:727
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "plenumigi ensalutan ŝelon kiel celan uzanton; komando ankaŭ enmeteblas"
+
+#: src/parse_args.c:729
+msgid "remove timestamp file completely"
+msgstr "tute forigi tempo-indikilan dosieron"
+
+#: src/parse_args.c:731
+msgid "invalidate timestamp file"
+msgstr "eksvalidigi tempo-indikilan dosieron"
+
+#: src/parse_args.c:733
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "listigi privilegiojn de la uzanto aŭ kontroli specifan komandon; uzu dufoje por pli longa formato"
+
+#: src/parse_args.c:735
+msgid "non-interactive mode, no prompts are used"
+msgstr "neinteraga reĝimo, ne demandos al uzanto"
+
+#: src/parse_args.c:737
+msgid "preserve group vector instead of setting to target's"
+msgstr "konservi grupan vektoron anstataŭ elekti celan"
+
+#: src/parse_args.c:739
+msgid "use the specified password prompt"
+msgstr "uzi specifitan pasvortilon"
+
+#: src/parse_args.c:742
+msgid "create SELinux security context with specified role"
+msgstr "krei SELinux-sekurecan kuntekston kun specifita rolo"
+
+#: src/parse_args.c:745
+msgid "read password from standard input"
+msgstr "legi pasvorton el norma enigo"
+
+#: src/parse_args.c:747
+msgid "run shell as the target user; a command may also be specified"
+msgstr "plenumigi ŝelon kiel cela uzanto; komando ankaŭ specifebla"
+
+#: src/parse_args.c:750
+msgid "create SELinux security context with specified type"
+msgstr "krei SELinux-sekurecan kuntekston kun specifita rolo"
+
+#: src/parse_args.c:753
+msgid "terminate command after the specified time limit"
+msgstr "finigi la komandon post la specifita tempolimo"
+
+#: src/parse_args.c:755
+msgid "in list mode, display privileges for user"
+msgstr "en lista reĝimo elmontri privilegiojn por uzanto"
+
+#: src/parse_args.c:757
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "plenumigi komandon (aŭ redakti dosieron) kiel specifita uzanto"
+
+#: src/parse_args.c:759
+msgid "display version information and exit"
+msgstr "elmontri eldonan informon kaj eliri"
+
+#: src/parse_args.c:761
+msgid "update user's timestamp without running a command"
+msgstr "ĝisdatigi la tempo-indikilon de la uzanto, sed ne plenumigi komandon"
+
+#: src/parse_args.c:763
+msgid "stop processing command line arguments"
+msgstr "ĉesigi procedi komandliniajn parametrojn"
+
+#: src/selinux.c:78
+msgid "unable to open audit system"
+msgstr "ne eblas malfermi aŭdan sistemon"
+
+#: src/selinux.c:88
+msgid "unable to send audit message"
+msgstr "ne eblas sendi aŭdan mesaĝon"
+
+#: src/selinux.c:116
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "ne eblas voki fgetfilecon %s"
+
+#: src/selinux.c:121
+#, c-format
+msgid "%s changed labels"
+msgstr "%s ŝanĝis etikedojn"
+
+#: src/selinux.c:126
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "ne eblas restarigi kuntekston por %s"
+
+#: src/selinux.c:167
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "ne eblas malfermi %s, ne remarkanta tty-on"
+
+#: src/selinux.c:171 src/selinux.c:212 src/selinux.c:229
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s ne estas signo-aparato, ni ne remarkas tty"
+
+#: src/selinux.c:180
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "ne eblas akiri aktualan tty-kuntekston, ne remarkanta"
+
+#: src/selinux.c:187
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "nekonata sekurecan klason \"chr_file\", ni ne remarkas tty"
+
+#: src/selinux.c:192
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "ne eblas akiri novan tty-kuntekston, ni ne remarkas tty"
+
+#: src/selinux.c:199
+msgid "unable to set new tty context"
+msgstr "ne eblas elekti novan tty-kuntekston"
+
+#: src/selinux.c:273
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "vi devas specifi rolon por tipon %s"
+
+#: src/selinux.c:279
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "ne eblas akiri aŭtomatan tipon por rolo %s"
+
+#: src/selinux.c:297
+#, c-format
+msgid "failed to set new role %s"
+msgstr "malsukcesis elekti novan rolon %s"
+
+#: src/selinux.c:301
+#, c-format
+msgid "failed to set new type %s"
+msgstr "malsukcesis elekti novan tipon %s"
+
+#: src/selinux.c:313
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s ne estas valida kunteksto"
+
+#: src/selinux.c:348
+msgid "failed to get old_context"
+msgstr "malsukcesis je old_context"
+
+#: src/selinux.c:354
+msgid "unable to determine enforcing mode."
+msgstr "ne povas determini eldevigan reĝimon."
+
+#: src/selinux.c:371
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "ne eblas agordi tty-kuntekston al %s"
+
+#: src/selinux.c:410
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "ne eblas elekti exec-kuntekston al %s"
+
+#: src/selinux.c:417
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "ne eblas elekti kuntekston de kreo de ŝlosilo al %s"
+
+#: src/sesh.c:74
+msgid "requires at least one argument"
+msgstr "postulas almenaŭ unu parametron"
+
+#: src/sesh.c:103
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "malvalida dosierpriskribila numero: %s"
+
+#: src/sesh.c:117
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "ne eblas lanĉi %s kiel ensalut-ŝelo"
+
+#: src/signal.c:83
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "ne eblas konservi traktilon por la signalo %d"
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "rimedo-rega limigo estis atingita"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "uzanto \"%s\" ne estas ano de projekto \"%s\""
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr "la voka tasko estas nenuligebla"
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "ne eblis aliĝi al projekto \"%s\""
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "neniu rimedujo akceptanta aŭtomatajn bindaĵojn ekzistas por projekto \"%s\""
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "specifita rimedujo ne ekzistas por projekto \"%s\""
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "ne eblis bindi al aprioran rimedujo por projekto \"%s\""
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "setproject malsukcesis por projekto \"%s\""
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "averto, rimedo-rega asigno malsukcesis por projekto \"%s\""
+
+#: src/sudo.c:195
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo: eldono %s\n"
+
+#: src/sudo.c:197
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Muntaj parametroj: %s\n"
+
+#: src/sudo.c:205
+msgid "fatal error, unable to load plugins"
+msgstr "ĉesiga eraro: ne eblas ŝargi kromprogramojn"
+
+#: src/sudo.c:213
+msgid "unable to initialize policy plugin"
+msgstr "ne eblas komenci konduktan kromprogramon"
+
+#: src/sudo.c:257
+msgid "plugin did not return a command to execute"
+msgstr "kromprogramo ne liveris komandon por plenumi"
+
+#: src/sudo.c:273
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "eraro dum komenci eneligan kromprogramon %s"
+
+#: src/sudo.c:296
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "neatendita sudo-reĝimon 0x%x"
+
+#: src/sudo.c:474
+msgid "unable to get group vector"
+msgstr "ne eblas elekti grupan vektoron"
+
+#: src/sudo.c:552
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "nekonata uid %u: kiu vi estas?"
+
+#: src/sudo.c:608
+msgid "unable to determine tty"
+msgstr "ne eblas determini tty-on"
+
+#: src/sudo.c:896
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s devas esti posedata de uid %d kaj la setuid-bito devas esti markita"
+
+#: src/sudo.c:899
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "efektiva uid ne estas %d; ĉu %s estas en dosiersistemo kun la elekto 'nosuid' aŭ reta dosiersistemo sen ĉefuzanto-privilegioj?"
+
+#: src/sudo.c:905
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "efektiva uid ne estas %d; ĉu sudo estas instalita kiel setuid-radiko?"
+
+#: src/sudo.c:958
+msgid "unable to set supplementary group IDs"
+msgstr "ne eblas elekti suplementajn grupajn identigilojn"
+
+#: src/sudo.c:965
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "ne eblas elekti efikan gid-on al plenumigkiela gid %u"
+
+#: src/sudo.c:971
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "ne eblas elekti gid-on kiel plenumigkielan gid-on %u"
+
+#: src/sudo.c:1028
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "neatendita ido ekzekutiĝis laŭ la kondiĉo: %d"
+
+#: src/sudo.c:1174
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "konduta kromprogramo %s ne inkluzivas la metodon 'check_policy'"
+
+#: src/sudo.c:1192
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "konduta kromprogramo %s ne komprenas listigon de privilegioj"
+
+#: src/sudo.c:1209
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "konduta kromprogramo %s ne komprenas la parametron -v"
+
+#: src/sudo.c:1224
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "konduta kromprogramo %s ne komprenas la parametrojn -k kaj -K"
+
+#: src/sudo_edit.c:213
+msgid "no writable temporary directory found"
+msgstr "neniu skribebla provizora dosierujo estis trovata"
+
+#: src/sudo_edit.c:280 src/sudo_edit.c:369
+msgid "unable to restore current working directory"
+msgstr "ne eblas restarigi nune kurantan dosierujon"
+
+#: src/sudo_edit.c:578 src/sudo_edit.c:690
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: ne regula dosiero"
+
+#: src/sudo_edit.c:585
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: redakto de simbolaj ligoj ne estas permesata"
+
+#: src/sudo_edit.c:588
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: redakto de dosieroj en skribebla dosierujo ne estas permesata"
+
+#: src/sudo_edit.c:621 src/sudo_edit.c:728
+#, c-format
+msgid "%s: short write"
+msgstr "%s: mallonga skribado"
+
+#: src/sudo_edit.c:691
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s restas ne modifita"
+
+#: src/sudo_edit.c:704 src/sudo_edit.c:889
+#, c-format
+msgid "%s unchanged"
+msgstr "%s ne ŝanĝita"
+
+#: src/sudo_edit.c:717 src/sudo_edit.c:739
+#, c-format
+msgid "unable to write to %s"
+msgstr "ne eblas skribi al %s"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:737 src/sudo_edit.c:740
+#: src/sudo_edit.c:914 src/sudo_edit.c:918
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "enhavo de redakta seanco restas en %s"
+
+#: src/sudo_edit.c:736
+msgid "unable to read temporary file"
+msgstr "ne eblas legi provizoran dosieron"
+
+#: src/sudo_edit.c:819
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: interna eraro: malpara nombro da vojoj"
+
+#: src/sudo_edit.c:821
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: ne eblas krei provizorajn dosierojn"
+
+#: src/sudo_edit.c:823 src/sudo_edit.c:921
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: nekonata eraro %d"
+
+#: src/sudo_edit.c:913
+msgid "unable to copy temporary files back to their original location"
+msgstr "ne eblas retrokopii provizorajn dosierojn al ilia originala loko"
+
+#: src/sudo_edit.c:917
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "ne eblas retrokopii kelkajn el la provizoraj dosieroj al ilia originala loko"
+
+#: src/sudo_edit.c:962
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "ne eblas ŝanĝi uid-on al ĉefuzanto (%u)"
+
+#: src/sudo_edit.c:979
+msgid "plugin error: missing file list for sudoedit"
+msgstr "kromprograma eraro: malhavas dosieran liston por sudoedit"
+
+#: src/sudo_edit.c:1020 src/sudo_edit.c:1033
+msgid "unable to read the clock"
+msgstr "ne eblas legi la horloĝon"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr "neniu tty ĉeestas kaj neniu pasvorto-programo specifita"
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "neniu pasvorto-programo specifita, provi valorizi SUDO_ASKPASS-on"
+
+#: src/tgetpass.c:269
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "ne eblas elekti gid-on al %u"
+
+#: src/tgetpass.c:273
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "ne eblas elekti uid-on al %u"
+
+#: src/tgetpass.c:278
+#, c-format
+msgid "unable to run %s"
+msgstr "ne eblas plenumigi: %s"
+
+#: src/utmp.c:266
+msgid "unable to save stdin"
+msgstr "ne eblas konservi enigon"
+
+#: src/utmp.c:268
+msgid "unable to dup2 stdin"
+msgstr "ne eblas kopii al enigo"
+
+#: src/utmp.c:271
+msgid "unable to restore stdin"
+msgstr "ne eblas restarigi enigon"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "eraro dum legi la signalan tubon"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "eraro dum legi el tubo"
+
+#~ msgid "internal error, tried allocate zero bytes"
+#~ msgstr "interna eraro, provo rezervi neniun bajton"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "ne eblas elekti nudan reĝimon ĉe la terminalo"
+
+#~ msgid "unable to open socket"
+#~ msgstr "ne eblas malfermi konektingon"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "interna eraro, provis je emalloc2(0)"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "interna eraro, provis je ecalloc(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "interna eraro, provis je erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "interna eraro, provis je erealloc3(0)"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "interna eraro, provis je erealloc(0)"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: superfluo malkovrita"
+
+#~ msgid "value out of range"
+#~ msgstr "valoro ne en permesata skalo"
+
+#~ msgid "select failed"
+#~ msgstr "elekto malsukcesis"
+
+#~ msgid "list user's available commands\n"
+#~ msgstr "listigi disponeblajn komandojn de uzanto\n"
+
+#~ msgid "run a shell as target user\n"
+#~ msgstr "plenumigi ŝelon kiel cela uzanto\n"
+
+#~ msgid "when listing, list specified user's privileges\n"
+#~ msgstr "dum listigo, listigi privilegiojn de specifita uzanto\n"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "internal error, emalloc2() overflow"
+#~ msgstr "interna eraro, emalloc2() superfluo"
+
+#~ msgid "internal error, erealloc3() overflow"
+#~ msgstr "interna eraro, erealloc3() superfluo"
+
+#~ msgid "%s: at least one policy plugin must be specified"
+#~ msgstr "%s: almenaŭ unu konduku devas esti specifita"
+
+#~ msgid "must be setuid root"
+#~ msgstr "devas esti ĉefuzanto setuid"
diff --git a/po/es.mo b/po/es.mo
new file mode 100644
index 0000000..453a27c
--- /dev/null
+++ b/po/es.mo
Binary files differ
diff --git a/po/es.po b/po/es.po
new file mode 100644
index 0000000..be8a3d8
--- /dev/null
+++ b/po/es.po
@@ -0,0 +1,950 @@
+# traducción al español de sudo.
+# This file is distributed under the same license as the sudo package.
+#
+# Abel Sendón <abelnicolas1976@gmail.com>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.21b2\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2017-08-03 10:04-0600\n"
+"PO-Revision-Date: 2017-08-17 18:05-0300\n"
+"Last-Translator: Abel Sendón <abelnicolas1976@gmail.com>\n"
+"Language-Team: Spanish <es@tp.org.es>\n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"X-Generator: Poedit 1.8.11\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:172
+msgid "unable to open userdb"
+msgstr "no se puede abrir userdb"
+
+#: lib/util/aix.c:227
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "no se puede cambiar al registro \"%s\" para %s"
+
+#: lib/util/aix.c:252
+msgid "unable to restore registry"
+msgstr "no se puede restaurar el registro"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:186 lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349
+#: lib/util/sudo_conf.c:553 src/conversation.c:75 src/exec_common.c:107
+#: src/exec_common.c:123 src/exec_common.c:132 src/exec_monitor.c:167
+#: src/exec_nopty.c:462 src/exec_pty.c:667 src/exec_pty.c:676
+#: src/exec_pty.c:738 src/exec_pty.c:867 src/load_plugins.c:52
+#: src/load_plugins.c:65 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:198 src/parse_args.c:273 src/parse_args.c:540
+#: src/parse_args.c:562 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:115 src/sudo.c:389 src/sudo.c:416 src/sudo.c:481 src/sudo.c:603
+#: src/sudo.c:663 src/sudo.c:673 src/sudo.c:693 src/sudo.c:712 src/sudo.c:721
+#: src/sudo.c:730 src/sudo.c:747 src/sudo.c:788 src/sudo.c:798 src/sudo.c:818
+#: src/sudo.c:1058 src/sudo.c:1079 src/sudo.c:1253 src/sudo.c:1351
+#: src/sudo_edit.c:148 src/sudo_edit.c:771 src/sudo_edit.c:868
+#: src/sudo_edit.c:982 src/sudo_edit.c:1002
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/sudo_conf.c:187
+#: lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349 lib/util/sudo_conf.c:553
+#: src/conversation.c:76 src/exec_common.c:107 src/exec_common.c:124
+#: src/exec_common.c:133 src/exec_pty.c:667 src/exec_pty.c:676
+#: src/exec_pty.c:738 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:199 src/parse_args.c:273 src/parse_args.c:540
+#: src/parse_args.c:562 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:115 src/sudo.c:389 src/sudo.c:416 src/sudo.c:481 src/sudo.c:603
+#: src/sudo.c:818 src/sudo.c:1058 src/sudo.c:1079 src/sudo.c:1253
+#: src/sudo.c:1351 src/sudo_edit.c:148 src/sudo_edit.c:771 src/sudo_edit.c:868
+#: src/sudo_edit.c:982 src/sudo_edit.c:1002
+msgid "unable to allocate memory"
+msgstr "no se puede de asignar memoria"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "Señal desconocida"
+
+#: lib/util/strtoid.c:77 lib/util/strtoid.c:124 lib/util/strtoid.c:152
+#: lib/util/strtomode.c:49 lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "valor inválido"
+
+#: lib/util/strtoid.c:84 lib/util/strtoid.c:131 lib/util/strtoid.c:159
+#: lib/util/strtomode.c:55 lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "valor muy grande"
+
+#: lib/util/strtoid.c:86 lib/util/strtoid.c:137 lib/util/strtomode.c:55
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "valor muy pequeño"
+
+#: lib/util/sudo_conf.c:205
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "valor de ruta inválido \"%s\" en %s, línea %u"
+
+#: lib/util/sudo_conf.c:371 lib/util/sudo_conf.c:424
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "valor inválido para %s \"%s\" en %s, línea %u"
+
+#: lib/util/sudo_conf.c:392
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "fuente de grupo no soportada \"%s\" en %s, línea %u"
+
+#: lib/util/sudo_conf.c:408
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "máximo de grupos inválido \"%s\" en %s, línea %u"
+
+#: lib/util/sudo_conf.c:569
+#, c-format
+msgid "unable to stat %s"
+msgstr "no se puede stat en %s"
+
+#: lib/util/sudo_conf.c:572
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s no es un archivo regular"
+
+#: lib/util/sudo_conf.c:575
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s es adueñado por uid %u, sería %u"
+
+#: lib/util/sudo_conf.c:579
+#, c-format
+msgid "%s is world writable"
+msgstr "%s es escribible por todos"
+
+#: lib/util/sudo_conf.c:582
+#, c-format
+msgid "%s is group writable"
+msgstr "%s es escribible por el grupo"
+
+#: lib/util/sudo_conf.c:592 src/selinux.c:208 src/selinux.c:225 src/sudo.c:357
+#, c-format
+msgid "unable to open %s"
+msgstr "no se pudo abrir %s"
+
+#: src/exec.c:160
+#, c-format
+msgid "unknown login class %s"
+msgstr "clase de inicio de sesión desconocida %s"
+
+#: src/exec.c:173
+msgid "unable to set user context"
+msgstr "no se puede establecer el contexto del usuario"
+
+#: src/exec.c:189
+msgid "unable to set process priority"
+msgstr "no se puede establecer la prioridad de proceso"
+
+#: src/exec.c:197
+#, c-format
+msgid "unable to change root to %s"
+msgstr "no se puede cambiar de root a %s"
+
+#: src/exec.c:210 src/exec.c:216 src/exec.c:223
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "no se puede cambiar a runas uid (%u, %u)"
+
+#: src/exec.c:241
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "no se puede cambiar al directorio %s"
+
+#: src/exec.c:337 src/exec_monitor.c:526 src/exec_monitor.c:528
+#: src/exec_nopty.c:520 src/exec_pty.c:472 src/exec_pty.c:1184
+#: src/exec_pty.c:1186 src/signal.c:139 src/signal.c:153
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "no se puede establecer el manejador para señal %d"
+
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "no se puede remover PRIV_PROC_EXEC desde PRIV_LIMIT"
+
+#: src/exec_monitor.c:326
+msgid "error reading from socketpair"
+msgstr "error leyendo de socketpair"
+
+#: src/exec_monitor.c:338
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "tipo de respuesta inesperada en canales alternos %d"
+
+#: src/exec_monitor.c:423 src/exec_monitor.c:431 src/exec_monitor.c:439
+#: src/exec_monitor.c:446 src/exec_monitor.c:453 src/exec_monitor.c:460
+#: src/exec_monitor.c:467 src/exec_monitor.c:474 src/exec_monitor.c:481
+#: src/exec_monitor.c:488 src/exec_nopty.c:215 src/exec_nopty.c:224
+#: src/exec_nopty.c:231 src/exec_nopty.c:238 src/exec_nopty.c:245
+#: src/exec_nopty.c:252 src/exec_nopty.c:259 src/exec_nopty.c:266
+#: src/exec_nopty.c:273 src/exec_nopty.c:280 src/exec_nopty.c:287
+#: src/exec_nopty.c:294 src/exec_nopty.c:302 src/exec_pty.c:563
+#: src/exec_pty.c:568 src/exec_pty.c:635 src/exec_pty.c:642 src/exec_pty.c:743
+#: src/exec_pty.c:1029 src/exec_pty.c:1038 src/exec_pty.c:1045
+#: src/exec_pty.c:1052 src/exec_pty.c:1059 src/exec_pty.c:1066
+#: src/exec_pty.c:1073 src/exec_pty.c:1080 src/exec_pty.c:1087
+#: src/exec_pty.c:1094 src/exec_pty.c:1101 src/exec_pty.c:1446
+#: src/exec_pty.c:1456 src/exec_pty.c:1501 src/exec_pty.c:1508
+#: src/exec_pty.c:1533
+msgid "unable to add event to queue"
+msgstr "no se puede agregar evento a la cola"
+
+#: src/exec_monitor.c:540
+msgid "unable to set controlling tty"
+msgstr "no se puede establecer el controlador tty"
+
+#: src/exec_monitor.c:548 src/exec_nopty.c:359 src/exec_pty.c:1261
+#: src/exec_pty.c:1280 src/exec_pty.c:1298 src/tgetpass.c:246
+msgid "unable to create pipe"
+msgstr "no se puede crear tubería"
+
+#: src/exec_monitor.c:553 src/exec_nopty.c:377 src/exec_pty.c:1335
+#: src/tgetpass.c:250
+msgid "unable to fork"
+msgstr "no se puede bifurcar"
+
+#: src/exec_monitor.c:639 src/exec_nopty.c:430
+msgid "unable to restore tty label"
+msgstr "no se puede restaurar la etiqueta tty "
+
+#: src/exec_nopty.c:353 src/exec_pty.c:1193
+msgid "policy plugin failed session initialization"
+msgstr "política de plugin falló en la inicialización de sesión "
+
+#: src/exec_nopty.c:419 src/exec_pty.c:1404
+msgid "error in event loop"
+msgstr "error en loop de evento"
+
+#: src/exec_nopty.c:528 src/exec_pty.c:504 src/signal.c:101
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "no se puede restaurar el manejador para señal %d"
+
+#: src/exec_pty.c:143
+msgid "unable to allocate pty"
+msgstr "no se puede asignar pty"
+
+#: src/exec_pty.c:1173
+msgid "unable to create sockets"
+msgstr "no se puede crear sockets"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "error en %s, línea %d mientras se carga el plugin \"%s\""
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s debe ser propiedad del uid %d"
+
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s sólo tener permisos de escritura por el propietario"
+
+#: src/load_plugins.c:172
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "no se puede cargar %s: %s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "no se puede de encontrar el símbolo \"%s\" en %s"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "tipo de política desconocido %d encontrado en %s"
+
+#: src/load_plugins.c:193
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "incompatible la versión principal de la política de plugin %d (se esperaba %d) encontrada in %s"
+
+#: src/load_plugins.c:202
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "Ignorando política de plugin \"%s\" en %s, linea %d"
+
+#: src/load_plugins.c:204
+msgid "only a single policy plugin may be specified"
+msgstr "sólo una política de plugin puede ser especificada"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "Ignorando política de plugin duplicada \"%s\" en %s, línea %d"
+
+#: src/load_plugins.c:228
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "Ignorando E/S de plugin duplicada \"%s\" en %s, linea %d"
+
+#: src/load_plugins.c:331
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "la política del plugin %s no incluye un método check_policy"
+
+#: src/net_ifs.c:173 src/net_ifs.c:190 src/net_ifs.c:335 src/sudo.c:476
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "error interno: desbordamiento de %s"
+
+#: src/parse_args.c:219
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "nombre de variable de entorno inválido: %s"
+
+#: src/parse_args.c:313
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "el argumento -C debe ser un número mayor o igual a 3"
+
+#: src/parse_args.c:480
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "no se deben especificar las opciones '-i' y '-s' simultáneamente"
+
+#: src/parse_args.c:484
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "no se deben especificar las opciones '-i' y '-E' simultáneamente"
+
+#: src/parse_args.c:494
+msgid "the `-E' option is not valid in edit mode"
+msgstr "la opción '-E' no es válida en el modo edición"
+
+#: src/parse_args.c:496
+msgid "you may not specify environment variables in edit mode"
+msgstr "no se debe especificar variables de entorno en el modo edición"
+
+#: src/parse_args.c:504
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "la opción '-U' sólo se puede usar con la opcion '-l'"
+
+#: src/parse_args.c:508
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "las opciones '-A' y '-S' no se pueden utilizar conjuntamente"
+
+#: src/parse_args.c:584
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit no está soportado en ésta plataforma"
+
+#: src/parse_args.c:657
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "puede ser especificada sólo una de las opciones -e, -h, -i, -K, -l, -s, -v o -V"
+
+#: src/parse_args.c:671
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - edita archivos como otro usuario\n"
+"\n"
+
+#: src/parse_args.c:673
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - ejecuta un comando como otro usuario\n"
+"\n"
+
+#: src/parse_args.c:678
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opciones:\n"
+
+#: src/parse_args.c:680
+msgid "use a helper program for password prompting"
+msgstr "utiliza un programa auxiliar para la solicitud de contraseña"
+
+#: src/parse_args.c:683
+msgid "use specified BSD authentication type"
+msgstr "utiliza tipo de autentificación especificado en BSD"
+
+#: src/parse_args.c:686
+msgid "run command in the background"
+msgstr "ejecuta un comando en segundo plano"
+
+#: src/parse_args.c:688
+msgid "close all file descriptors >= num"
+msgstr "cierra todos los descriptores de archivo >= num"
+
+#: src/parse_args.c:691
+msgid "run command with the specified BSD login class"
+msgstr "ejecuta un comando con la clase especificada de inicio de sesión BSD"
+
+#: src/parse_args.c:694
+msgid "preserve user environment when running command"
+msgstr "preserva entorno del usuario cuando está ejecutando un comando"
+
+#: src/parse_args.c:696
+msgid "preserve specific environment variables"
+msgstr "preserva variables de entorno específicas"
+
+#: src/parse_args.c:698
+msgid "edit files instead of running a command"
+msgstr "edita archivos en vez de ejecutar un comando"
+
+#: src/parse_args.c:700
+msgid "run command as the specified group name or ID"
+msgstr "ejecuta un comando como el ID o grupo especificado"
+
+#: src/parse_args.c:702
+msgid "set HOME variable to target user's home dir"
+msgstr "asigna la variable HOME al directorio de inicio del usuario"
+
+#: src/parse_args.c:704
+msgid "display help message and exit"
+msgstr "muestra este mensaje de ayuda y sale"
+
+#: src/parse_args.c:706
+msgid "run command on host (if supported by plugin)"
+msgstr "ejecuta comando en host (si está soportado por plugin)"
+
+#: src/parse_args.c:708
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "ejecuta un intérprete de comandos como un determinado usuario, un comando también puede ser especificado"
+
+#: src/parse_args.c:710
+msgid "remove timestamp file completely"
+msgstr "remueve un archivo de marca completamente"
+
+#: src/parse_args.c:712
+msgid "invalidate timestamp file"
+msgstr "archivo de marca inválido"
+
+#: src/parse_args.c:714
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "lista privilegios de usuario o chequea un comando especifico; usar dos veces para formato extenso"
+
+#: src/parse_args.c:716
+msgid "non-interactive mode, no prompts are used"
+msgstr "modo no-interactivo, no se pedirá usuario"
+
+#: src/parse_args.c:718
+msgid "preserve group vector instead of setting to target's"
+msgstr "preserva el vector de grupos en vez de establecer al objetivo"
+
+#: src/parse_args.c:720
+msgid "use the specified password prompt"
+msgstr "usa la contraseña especificada"
+
+#: src/parse_args.c:723
+msgid "create SELinux security context with specified role"
+msgstr "crea el contexto de seguridad SELinux con la regla especificada"
+
+#: src/parse_args.c:726
+msgid "read password from standard input"
+msgstr "lee la contraseña desde la entrada estandar"
+
+#: src/parse_args.c:728
+msgid "run shell as the target user; a command may also be specified"
+msgstr "ejecuta un intérprete de comandos como un determinado usuario, un comando también puede ser especificado"
+
+#: src/parse_args.c:731
+msgid "create SELinux security context with specified type"
+msgstr "crea el contexto de seguridad SELinux con el tipo especificado"
+
+#: src/parse_args.c:734
+msgid "terminate command after the specified time limit"
+msgstr "termina un comando luego de un límite de tiempo especificado"
+
+#: src/parse_args.c:736
+msgid "in list mode, display privileges for user"
+msgstr "en modo lista, muestra los privilegios para el usuario"
+
+#: src/parse_args.c:738
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "ejecuta un comando (o edita un archivo) como un ID o usuario específico"
+
+#: src/parse_args.c:740
+msgid "display version information and exit"
+msgstr "muestra la información de la versión y sale"
+
+#: src/parse_args.c:742
+msgid "update user's timestamp without running a command"
+msgstr "actualiza la marca del usuario sin ejecutar un comando"
+
+#: src/parse_args.c:744
+msgid "stop processing command line arguments"
+msgstr "detiene el proceso de argumentos de la línea de comandos"
+
+#: src/selinux.c:78
+msgid "unable to open audit system"
+msgstr "no se puede de abrir el sistema de auditoría"
+
+#: src/selinux.c:88
+msgid "unable to send audit message"
+msgstr "no se puede enviar mensaje de auditoría"
+
+#: src/selinux.c:116
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "no se puede fgetfilecon %s"
+
+#: src/selinux.c:121
+#, c-format
+msgid "%s changed labels"
+msgstr "%s etiquetas cambiadas"
+
+#: src/selinux.c:126
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "no se puede restaurar el contexto para %s"
+
+#: src/selinux.c:167
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "no se puede abrir %s, no volver a etiquetar tty"
+
+#: src/selinux.c:171 src/selinux.c:212 src/selinux.c:229
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s no es un dispositivo de caracter, no se reetiqueta tty"
+
+#: src/selinux.c:180
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "no se puede obtener el actual contexto tty, no volver a etiquetar tty"
+
+#: src/selinux.c:187
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "clase de seguridad desconocida \"chr_file\", tty no reetiquetada"
+
+#: src/selinux.c:192
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "no se puede obtener el nuevo contexto tty, no volver a etiquetar tty"
+
+#: src/selinux.c:199
+msgid "unable to set new tty context"
+msgstr "no se puede establecer nuevo contexto tty"
+
+#: src/selinux.c:273
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "se debe especificar una regla por tipo %s"
+
+#: src/selinux.c:279
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "no se puede obtener el tipo de regla predeterminada %s"
+
+#: src/selinux.c:297
+#, c-format
+msgid "failed to set new role %s"
+msgstr "falló al establecer nueva regla %s"
+
+#: src/selinux.c:301
+#, c-format
+msgid "failed to set new type %s"
+msgstr "falló al establecer nuevo tipo %s"
+
+#: src/selinux.c:313
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s no es un contexto válido"
+
+#: src/selinux.c:348
+msgid "failed to get old_context"
+msgstr "falló al obtener old_context"
+
+#: src/selinux.c:354
+msgid "unable to determine enforcing mode."
+msgstr "no se puede determinar el método de forzado"
+
+#: src/selinux.c:371
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "no se puede establecer el contexto tty a %s"
+
+#: src/selinux.c:410
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "no se puede establecer el contexto de ejecución a %s"
+
+#: src/selinux.c:417
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "no se puede establecer la clave de creación de contexto a %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "requiere al menos un argumento"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "número de descriptor de archivo no válido: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "no se puede ejecutar %s como un login"
+
+#: src/sesh.c:125 src/sudo.c:1117
+#, c-format
+msgid "unable to execute %s"
+msgstr "no se puede ejecutar %s"
+
+#: src/signal.c:83
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "no se puede guardar el manejador para la señal %d"
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "el límite de control de recursos ha sido alcanzado"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "el usuario \"%s\" no es miembro del proyecto \"%s\""
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr "la tarea que invoca es definitiva"
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "no podría unirse al proyecto \"%s\""
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "no hay fondo de recursos aceptando las asignaciones existentes para el proyecto \"%s\""
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "el fondo de recursos especificado no existe para el proyecto \"%s\""
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "no se podría enlazar al fondo de recursos predeterminado para el proyecto \"%s\" "
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "configuración del proyecto fallida \"%s\" "
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "aviso, el control de asignación de recursos falló para el proyecto \"%s\""
+
+#: src/sudo.c:198
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo versión %s\n"
+
+#: src/sudo.c:200
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Opciones de configuración: %s\n"
+
+#: src/sudo.c:208
+msgid "fatal error, unable to load plugins"
+msgstr "error fatal, no se puede cargar los plugins"
+
+#: src/sudo.c:216
+msgid "unable to initialize policy plugin"
+msgstr "no se puede inicializar la política de plugin"
+
+#: src/sudo.c:260
+msgid "plugin did not return a command to execute"
+msgstr "el plugin no devolvió un comando para ejecutar"
+
+#: src/sudo.c:276
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "error al inicializar los plugins de E/S %s"
+
+#: src/sudo.c:299
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "inesperado modo sudo 0x%x"
+
+#: src/sudo.c:461
+msgid "unable to get group vector"
+msgstr "no se puede obtener el vector de grupo"
+
+#: src/sudo.c:523
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "uid desconocido %u: quién es usted?"
+
+#: src/sudo.c:579
+msgid "unable to determine tty"
+msgstr "no se puede deterrminar tty"
+
+#: src/sudo.c:867
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s debe ser propiedad del uid %d y tener el bit setuid establecido"
+
+#: src/sudo.c:870
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "el uid no es %d, es %s en un sistema de archivos con la opción 'nosuid' establecida o un sistema de archivos NFS sin privilegios de root?"
+
+#: src/sudo.c:876
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "el uid efectivo no es %d, sudo está instalado con setuid root?"
+
+#: src/sudo.c:929
+msgid "unable to set supplementary group IDs"
+msgstr "no se puede establecer el grupo suplementario de IDs"
+
+#: src/sudo.c:936
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "no se puede establecer el gid efectivo para ejecutar como gid %u"
+
+#: src/sudo.c:942
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "no se puede establecer el gid para ejecutar como gid %u"
+
+#: src/sudo.c:999
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "inesperada terminación de condición hija: %d"
+
+#: src/sudo.c:1145
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "la política del plugin %s no incluye un método `check_policy' "
+
+#: src/sudo.c:1163
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "la política del plugin %s no soporta listado de privilegios"
+
+#: src/sudo.c:1180
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "la política del plugin %s no soporta la opción -v"
+
+#: src/sudo.c:1195
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "la política del plugin %s no soporta las opciones -k/-K"
+
+#: src/sudo_edit.c:178 src/sudo_edit.c:267
+msgid "unable to restore current working directory"
+msgstr "no se puede restaurar el actual directorio de trabajo"
+
+#: src/sudo_edit.c:574 src/sudo_edit.c:686
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: no es un archivo regular"
+
+#: src/sudo_edit.c:581
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: edición de enlaces simbólicos no está permitida"
+
+#: src/sudo_edit.c:584
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: no se permite la edición de archivos en un directorio con permisos de escritura"
+
+#: src/sudo_edit.c:617 src/sudo_edit.c:724
+#, c-format
+msgid "%s: short write"
+msgstr "%s: escritura corta"
+
+#: src/sudo_edit.c:687
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s sin modificar"
+
+#: src/sudo_edit.c:700 src/sudo_edit.c:885
+#, c-format
+msgid "%s unchanged"
+msgstr "%s sin cambios"
+
+#: src/sudo_edit.c:713 src/sudo_edit.c:735
+#, c-format
+msgid "unable to write to %s"
+msgstr "no se puede escribir en %s"
+
+#: src/sudo_edit.c:714 src/sudo_edit.c:733 src/sudo_edit.c:736
+#: src/sudo_edit.c:910 src/sudo_edit.c:914
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "los contenidos de edición de sesión se dejan en %s"
+
+#: src/sudo_edit.c:732
+msgid "unable to read temporary file"
+msgstr "no se puede leer el archivo temporal"
+
+#: src/sudo_edit.c:815
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: error interno: número de rutas impar"
+
+#: src/sudo_edit.c:817
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: no se puede crear archivos temporales"
+
+#: src/sudo_edit.c:819 src/sudo_edit.c:917
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: error desconocido %d"
+
+#: src/sudo_edit.c:909
+msgid "unable to copy temporary files back to their original location"
+msgstr "no se puede copiar los archivos temporales nuevamente a su ubicación original"
+
+#: src/sudo_edit.c:913
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "no se puede copiar algunos de los archivos temporales nuevamente a su ubicación original"
+
+#: src/sudo_edit.c:958
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "no se puede cambiar uid a root (%u)"
+
+#: src/sudo_edit.c:975
+msgid "plugin error: missing file list for sudoedit"
+msgstr "error de plugin: falta la lista de archivos para sudoedit"
+
+#: src/sudo_edit.c:1016 src/sudo_edit.c:1029
+msgid "unable to read the clock"
+msgstr "no se leer el reloj"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr "sin tty presente y no hay programa askpass especificado"
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "no hay programa askpass especificado, intente establecer SUDO_ASKPASS"
+
+#: src/tgetpass.c:261
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "no se puede establecer el gid a %u"
+
+#: src/tgetpass.c:265
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "no se puede establecer el uid a %u"
+
+#: src/tgetpass.c:270
+#, c-format
+msgid "unable to run %s"
+msgstr "no se puede ejecutar %s"
+
+#: src/utmp.c:268
+msgid "unable to save stdin"
+msgstr "no se puede guardar stdin"
+
+#: src/utmp.c:270
+msgid "unable to dup2 stdin"
+msgstr "no se puede hacer dup2 stdin"
+
+#: src/utmp.c:273
+msgid "unable to restore stdin"
+msgstr "no se puede restaurar stdin"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "error al leer desde la tubería de la señal"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "error al leer de la tubería"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "no se puede establecer la terminal en modo directo"
+
+#~ msgid "internal error, tried to emalloc(0)"
+#~ msgstr "error interno: trató emalloc(0)"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "error interno: trató emalloc2(0)"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "error interno: trató ecalloc(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "error interno: trató erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "error interno: trató erealloc3(0)"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "error interno: trató erecalloc(0)"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s:%s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "select failed"
+#~ msgstr "selección fallida"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: desbordamiento detectado"
+
+#~ msgid "unable to open socket"
+#~ msgstr "no se puede de abrir socket"
+
+#~ msgid "list user's available commands\n"
+#~ msgstr "lista los comandos del usuario disponibles\n"
+
+#~ msgid "run a shell as target user\n"
+#~ msgstr "ejecuta un intérprete de comandos como un determinado usuario\n"
+
+#~ msgid "when listing, list specified user's privileges\n"
+#~ msgstr "cuando está listando, lista los privilegios del usuario especificado\n"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "%s: at least one policy plugin must be specified"
+#~ msgstr "%s: debe ser especificada al menos una política de plugin"
+
+#~ msgid "internal error, emalloc2() overflow"
+#~ msgstr "error interno: desbordamiento en emalloc2()"
+
+#~ msgid "internal error, erealloc3() overflow"
+#~ msgstr "error interno: desbordamiento de erealloc3()"
+
+#~ msgid "must be setuid root"
+#~ msgstr "debe ser setuid root"
+
+#~ msgid "the argument to -D must be between 1 and 9 inclusive"
+#~ msgstr "el argumento -D debe estar entre 1 y 9 inclusive"
diff --git a/po/eu.mo b/po/eu.mo
new file mode 100644
index 0000000..3ebaccb
--- /dev/null
+++ b/po/eu.mo
Binary files differ
diff --git a/po/eu.po b/po/eu.po
new file mode 100644
index 0000000..f36b0db
--- /dev/null
+++ b/po/eu.po
@@ -0,0 +1,742 @@
+# Basque translation of sudo.
+# Copyright (C) 2011 Free Software Foundation, Inc.
+# This file is distributed under the same license as the sudo package.
+# Mikel Olasagasti Uranga <mikel@olasagasti.info>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.2rc2\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2011-06-04 18:27-0400\n"
+"PO-Revision-Date: 2011-06-06 18:28+0100\n"
+"Last-Translator: Mikel Olasagasti Uranga <mikel@olasagasti.info>\n"
+"Language-Team: Basque <translation-team-eu@lists.sourceforge.net>\n"
+"Language: eu\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"\n"
+
+#: src/error.c:82 src/error.c:86
+msgid ": "
+msgstr ":"
+
+#: src/exec.c:125 src/exec_pty.c:573 src/exec_pty.c:880 src/tgetpass.c:224
+#, c-format
+msgid "unable to fork"
+msgstr "ezin da fork egin"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to create sockets"
+msgstr "ezin da socketik sortu"
+
+#: src/exec.c:253 src/exec_pty.c:526 src/exec_pty.c:534 src/exec_pty.c:541
+#: src/exec_pty.c:826 src/exec_pty.c:877 src/tgetpass.c:221
+#, c-format
+msgid "unable to create pipe"
+msgstr "ezin da pipe bat sortu"
+
+#: src/exec.c:319 src/exec_pty.c:944 src/exec_pty.c:1077
+#, c-format
+msgid "select failed"
+msgstr "select-ek huts egin du"
+
+#: src/exec.c:387
+#, c-format
+msgid "unable to restore tty label"
+msgstr ""
+
+#: src/exec_pty.c:136
+#, c-format
+msgid "unable to allocate pty"
+msgstr ""
+
+#: src/exec_pty.c:566
+#, c-format
+msgid "unable to set terminal to raw mode"
+msgstr ""
+
+#: src/exec_pty.c:858
+#, c-format
+msgid "unable to set controlling tty"
+msgstr ""
+
+#: src/exec_pty.c:952
+#, c-format
+msgid "error reading from signal pipe"
+msgstr "errorea seinale hoditik irakurtzean"
+
+#: src/exec_pty.c:971
+#, c-format
+msgid "error reading from pipe"
+msgstr "errorea hoditik irakurtzean"
+
+#: src/exec_pty.c:987
+#, c-format
+msgid "error reading from socketpair"
+msgstr "errorea socketpair-etik irakurtzean"
+
+#: src/exec_pty.c:991
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "espero ez zen erantzun moeta backchannel-ean: %d"
+
+#: src/load_plugins.c:154
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: src/load_plugins.c:160
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:170
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s-(r)en jabeak %d uid-a behar du"
+
+#: src/load_plugins.c:174
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s jabeak bakarrik idazteko moduan behar du"
+
+#: src/load_plugins.c:181
+#, c-format
+msgid "unable to dlopen %s: %s"
+msgstr "ezin da %s-(r)engan dlopen egin: %s"
+
+#: src/load_plugins.c:186
+#, c-format
+msgid "%s: unable to find symbol %s"
+msgstr "%s: ezin da %s sinboloa aurkitu"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "%s: unknown policy type %d"
+msgstr "%s: %d arau moeta ezezaguna"
+
+#: src/load_plugins.c:196
+#, c-format
+msgid "%s: incompatible policy major version %d, expected %d"
+msgstr ""
+
+#: src/load_plugins.c:203
+#, c-format
+msgid "%s: only a single policy plugin may be loaded"
+msgstr ""
+
+#: src/load_plugins.c:221
+#, c-format
+msgid "%s: at least one policy plugin must be specified"
+msgstr ""
+
+#: src/load_plugins.c:226
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr ""
+
+#: src/net_ifs.c:155 src/net_ifs.c:164 src/net_ifs.c:176 src/net_ifs.c:185
+#: src/net_ifs.c:295 src/net_ifs.c:319
+#, c-format
+msgid "load_interfaces: overflow detected"
+msgstr "load_interfaces: overflow-a atzeman da"
+
+#: src/net_ifs.c:224
+#, c-format
+msgid "unable to open socket"
+msgstr "ezin da socket-a ireki"
+
+#: src/parse_args.c:180
+#, c-format
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "-C argumentuak 3 edo zenbaki altuagoa behar du"
+
+#: src/parse_args.c:192
+#, c-format
+msgid "the argument to -D must be between 1 and 9 inclusive"
+msgstr "-D argumentua 1 eta 9 bitartean behar du, biak barne"
+
+#: src/parse_args.c:273
+#, c-format
+msgid "unknown user: %s"
+msgstr "erabiltzaile ezezaguna: %s"
+
+#: src/parse_args.c:332
+#, c-format
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "ez zenituzke `-i' eta `-s' aukerak batera erabili behar"
+
+#: src/parse_args.c:336
+#, c-format
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "ez zenitzuke `-i' eta `-E' aukerak batera erabili behar"
+
+#: src/parse_args.c:346
+#, c-format
+msgid "the `-E' option is not valid in edit mode"
+msgstr "`-E' aukera ez da onartzen edizio moduan"
+
+#: src/parse_args.c:348
+#, c-format
+msgid "you may not specify environment variables in edit mode"
+msgstr "ez zenuke ingurune aldagairik zehaztu beharko edizio moduan"
+
+#: src/parse_args.c:356
+#, c-format
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "`-U' aukera `-l' aukerarekin erabili beharko zenuke soilik"
+
+#: src/parse_args.c:360
+#, c-format
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "`-A' eta `-S' aukerak ez lirateke batera erabili beharko"
+
+#: src/parse_args.c:418 src/sudo.c:398 src/sudo.c:418 src/sudo.c:426
+#: src/sudo.c:436 common/alloc.c:85 common/alloc.c:105 common/alloc.c:123
+#: common/alloc.c:145 common/alloc.c:203 common/alloc.c:217
+#, c-format
+msgid "unable to allocate memory"
+msgstr "ezin da memoria esleitu"
+
+#: src/parse_args.c:431
+#, c-format
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit-ek ez du euskarririk plataforma hontan"
+
+#: src/parse_args.c:502
+#, c-format
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Soilik -e, -h, -i, -K, -l, -s, -v edo -V aukeretako bat definitu beharko litzateke"
+
+#: src/parse_args.c:515
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - editatu fitxategia beste erabiltzaile bat bezala\n"
+"\n"
+
+#: src/parse_args.c:517
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - exekutatu komandu bat beste erabiltzaile bat bezala\n"
+"\n"
+
+#: src/parse_args.c:522
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Aukerak:\n"
+
+#: src/parse_args.c:525
+msgid "use helper program for password prompting\n"
+msgstr ""
+
+#: src/parse_args.c:528
+msgid "use specified BSD authentication type\n"
+msgstr ""
+
+#: src/parse_args.c:530
+msgid "run command in the background\n"
+msgstr ""
+
+#: src/parse_args.c:532
+msgid "close all file descriptors >= fd\n"
+msgstr ""
+
+#: src/parse_args.c:535
+msgid "run command with specified login class\n"
+msgstr ""
+
+#: src/parse_args.c:538
+msgid "preserve user environment when executing command\n"
+msgstr ""
+
+#: src/parse_args.c:540
+msgid "edit files instead of running a command\n"
+msgstr ""
+
+#: src/parse_args.c:542
+msgid "execute command as the specified group\n"
+msgstr ""
+
+#: src/parse_args.c:544
+msgid "set HOME variable to target user's home dir.\n"
+msgstr ""
+
+#: src/parse_args.c:546
+msgid "display help message and exit\n"
+msgstr "laguntza mezua erakutsi eta irten\n"
+
+#: src/parse_args.c:548
+msgid "run a login shell as target user\n"
+msgstr "abiarazi login shell bat helburua den erabiltzaile moduan\n"
+
+#: src/parse_args.c:550
+msgid "remove timestamp file completely\n"
+msgstr "ezabatu guztiz data-zigilu fitxategia\n"
+
+#: src/parse_args.c:552
+msgid "invalidate timestamp file\n"
+msgstr "baliogabetu data-zigilu fitxategia\n"
+
+#: src/parse_args.c:554
+msgid "list user's available commands\n"
+msgstr "zerrendatu erabiltzaileak eskuragarri dituen komandoak\n"
+
+#: src/parse_args.c:556
+msgid "non-interactive mode, will not prompt user\n"
+msgstr ""
+
+#: src/parse_args.c:558
+msgid "preserve group vector instead of setting to target's\n"
+msgstr ""
+
+#: src/parse_args.c:560
+msgid "use specified password prompt\n"
+msgstr ""
+
+#: src/parse_args.c:563 src/parse_args.c:571
+msgid "create SELinux security context with specified role\n"
+msgstr ""
+
+#: src/parse_args.c:566
+msgid "read password from standard input\n"
+msgstr ""
+
+#: src/parse_args.c:568
+msgid "run a shell as target user\n"
+msgstr ""
+
+#: src/parse_args.c:574
+msgid "when listing, list specified user's privileges\n"
+msgstr ""
+
+#: src/parse_args.c:576
+msgid "run command (or edit file) as specified user\n"
+msgstr ""
+
+#: src/parse_args.c:578
+msgid "display version information and exit\n"
+msgstr ""
+
+#: src/parse_args.c:580
+msgid "update user's timestamp without running a command\n"
+msgstr ""
+
+#: src/parse_args.c:582
+msgid "stop processing command line arguments\n"
+msgstr ""
+
+#: src/selinux.c:75
+#, c-format
+msgid "unable to open audit system"
+msgstr ""
+
+#: src/selinux.c:85
+#, c-format
+msgid "unable to send audit message"
+msgstr ""
+
+#: src/selinux.c:112
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "ezin da %s-(r)engan fgetfilecon egin"
+
+#: src/selinux.c:117
+#, c-format
+msgid "%s changed labels"
+msgstr ""
+
+#: src/selinux.c:122
+#, c-format
+msgid "unable to restore context for %s"
+msgstr ""
+
+#: src/selinux.c:161
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr ""
+
+#: src/selinux.c:170
+#, c-format
+msgid "unable to get current tty context, not relabeling tty"
+msgstr ""
+
+#: src/selinux.c:177
+#, c-format
+msgid "unable to get new tty context, not relabeling tty"
+msgstr ""
+
+#: src/selinux.c:184
+#, c-format
+msgid "unable to set new tty context"
+msgstr ""
+
+#: src/selinux.c:194 src/selinux.c:207 src/sudo.c:330
+#, c-format
+msgid "unable to open %s"
+msgstr ""
+
+#: src/selinux.c:249
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr ""
+
+#: src/selinux.c:255
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr ""
+
+#: src/selinux.c:273
+#, c-format
+msgid "failed to set new role %s"
+msgstr ""
+
+#: src/selinux.c:277
+#, c-format
+msgid "failed to set new type %s"
+msgstr ""
+
+#: src/selinux.c:286
+#, c-format
+msgid "%s is not a valid context"
+msgstr ""
+
+#: src/selinux.c:320
+#, c-format
+msgid "failed to get old_context"
+msgstr ""
+
+#: src/selinux.c:326
+#, c-format
+msgid "unable to determine enforcing mode."
+msgstr ""
+
+#: src/selinux.c:338
+#, c-format
+msgid "unable to setup tty context for %s"
+msgstr ""
+
+#: src/selinux.c:367
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr ""
+
+#: src/selinux.c:374
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr ""
+
+#: src/sesh.c:48
+msgid "requires at least one argument"
+msgstr "gutxienez argumentu bat behar du"
+
+#: src/sesh.c:64
+#, c-format
+msgid "unable to execute %s"
+msgstr "ezin da %s exekutatu"
+
+#: src/sudo.c:192
+#, c-format
+msgid "must be setuid root"
+msgstr "root setuid-a behar du"
+
+#: src/sudo.c:210
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "%s sudo bertsioa\n"
+
+#: src/sudo.c:212
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Konfigurazio aukerak: %s\n"
+
+#: src/sudo.c:217
+#, c-format
+msgid "fatal error, unable to load plugins"
+msgstr "errore larria, ezin dira gehigarriak gehitu"
+
+#: src/sudo.c:225
+#, c-format
+msgid "unable to initialize policy plugin"
+msgstr ""
+
+#: src/sudo.c:280
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "errorea %s I/O plugina abiaraztean"
+
+#: src/sudo.c:307
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr ""
+
+#: src/sudo.c:356
+#, c-format
+msgid "unable to get group vector"
+msgstr ""
+
+#: src/sudo.c:394
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr ""
+
+#: src/sudo.c:734
+#, c-format
+msgid "resource control limit has been reached"
+msgstr ""
+
+#: src/sudo.c:737
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr ""
+
+#: src/sudo.c:741
+#, c-format
+msgid "the invoking task is final"
+msgstr ""
+
+#: src/sudo.c:744
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "ezin izan da \"%s\" proiektura batu"
+
+#: src/sudo.c:749
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr ""
+
+#: src/sudo.c:753
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr ""
+
+#: src/sudo.c:757
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr ""
+
+#: src/sudo.c:763
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "setproject-ek huts egin du \"%s\" proiektuarentzat"
+
+#: src/sudo.c:765
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr ""
+
+#: src/sudo.c:791
+#, c-format
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr ""
+
+#: src/sudo.c:895
+#, c-format
+msgid "unknown login class %s"
+msgstr ""
+
+#: src/sudo.c:902 src/sudo.c:905
+#, c-format
+msgid "unable to set user context"
+msgstr ""
+
+#: src/sudo.c:916
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr ""
+
+#: src/sudo.c:921
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr ""
+
+#: src/sudo.c:929 src/sudo.c:935
+#, c-format
+msgid "unable to set supplementary group IDs"
+msgstr ""
+
+#: src/sudo.c:943
+#, c-format
+msgid "unable to set process priority"
+msgstr ""
+
+#: src/sudo.c:951
+#, c-format
+msgid "unable to change root to %s"
+msgstr ""
+
+#: src/sudo.c:961 src/sudo.c:967 src/sudo.c:973
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr ""
+
+#: src/sudo.c:987
+#, c-format
+msgid "unable to change directory to %s"
+msgstr ""
+
+#: src/sudo.c:1078
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr ""
+
+#: src/sudo.c:1118
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr ""
+
+#: src/sudo.c:1129
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr ""
+
+#: src/sudo.c:1140
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr ""
+
+#: src/sudo_edit.c:108
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "ezin da uid-a root-era aldatu (%u)"
+
+#: src/sudo_edit.c:140
+#, c-format
+msgid "plugin error: missing file list for sudoedit"
+msgstr ""
+
+#: src/sudo_edit.c:172 src/sudo_edit.c:280
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: ez da fitxategi normala"
+
+#: src/sudo_edit.c:206 src/sudo_edit.c:316
+#, c-format
+msgid "%s: short write"
+msgstr ""
+
+#: src/sudo_edit.c:281
+#, c-format
+msgid "%s left unmodified"
+msgstr ""
+
+#: src/sudo_edit.c:294
+#, c-format
+msgid "%s unchanged"
+msgstr "%s aldatugabea"
+
+#: src/sudo_edit.c:306 src/sudo_edit.c:327
+#, c-format
+msgid "unable to write to %s"
+msgstr "ezin da %s-(e)ra idatzi"
+
+#: src/sudo_edit.c:307 src/sudo_edit.c:325 src/sudo_edit.c:328
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr ""
+
+#: src/sudo_edit.c:324
+#, c-format
+msgid "unable to read temporary file"
+msgstr "ezin da aldi baterako fitxategia irakurri"
+
+#: src/tgetpass.c:95
+#, c-format
+msgid "no tty present and no askpass program specified"
+msgstr "ez dago tty-rik eta askpass aplikazioa zehaztu gabe"
+
+#: src/tgetpass.c:104
+#, c-format
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "ez da askpass aplikaziorik zehaztu, saiatu SUDO_ASKPASS ezartzen"
+
+#: src/tgetpass.c:234
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "ezin da %u gid-a ezarri"
+
+#: src/tgetpass.c:238
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "ezin da %u uid-a ezarri"
+
+#: src/tgetpass.c:243
+#, c-format
+msgid "unable to run %s"
+msgstr "ezin da %s exekutatu"
+
+#: src/utmp.c:263
+#, c-format
+msgid "unable to save stdin"
+msgstr "ezin da stdin-era gorde"
+
+#: src/utmp.c:265
+#, c-format
+msgid "unable to dup2 stdin"
+msgstr "ezin da stdin-era dup2 egin"
+
+#: src/utmp.c:268
+#, c-format
+msgid "unable to restore stdin"
+msgstr "ezin da stdin-era leheneratu"
+
+#: common/aix.c:144
+#, c-format
+msgid "unable to open userdb"
+msgstr "ezin da userdb-a ireki"
+
+#: common/aix.c:147
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "ezin da \"%s\" erregistrora aldatu %s-(r)entzat"
+
+#: common/aix.c:161
+#, c-format
+msgid "unable to restore registry"
+msgstr "ezin da erregistroa leheneratu"
+
+#: common/alloc.c:82
+#, c-format
+msgid "internal error, tried to emalloc(0)"
+msgstr "barne errorea, emalloc(0) egiteko saiakera egon da"
+
+#: common/alloc.c:99
+#, c-format
+msgid "internal error, tried to emalloc2(0)"
+msgstr "barne errorea, emalloc2(0) egiteko saiakera egon da"
+
+#: common/alloc.c:101
+#, c-format
+msgid "internal error, emalloc2() overflow"
+msgstr "barne errorea, emalloc2() overflow-a"
+
+#: common/alloc.c:119
+#, c-format
+msgid "internal error, tried to erealloc(0)"
+msgstr "barne errorea, erealloc(0) egiteko saiakera egon da"
+
+#: common/alloc.c:138
+#, c-format
+msgid "internal error, tried to erealloc3(0)"
+msgstr "barne errorea, erealloc3(0) egiteko saiakera egon da"
+
+#: common/alloc.c:140
+#, c-format
+msgid "internal error, erealloc3() overflow"
+msgstr "barne errorea, erealloc3(0) overflow-a"
+
+#: compat/strsignal.c:47
+msgid "Unknown signal"
+msgstr "Seinale ezezaguna"
diff --git a/po/fi.mo b/po/fi.mo
new file mode 100644
index 0000000..ee8602b
--- /dev/null
+++ b/po/fi.mo
Binary files differ
diff --git a/po/fi.po b/po/fi.po
new file mode 100644
index 0000000..8b19fd6
--- /dev/null
+++ b/po/fi.po
@@ -0,0 +1,962 @@
+# Finnish messages for sudo.
+# This file is put in the public domain.
+# This file is distributed under the same license as the sudo package.
+# Jorma Karvonen <karvonen.jorma@gmail.com>, 2011-2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.21b2\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2017-08-03 10:04-0600\n"
+"PO-Revision-Date: 2017-08-19 20:33+0300\n"
+"Last-Translator: Jorma Karvonen <karvonen.jorma@gmail.com>\n"
+"Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
+"Language: fi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Poedit 2.0.3\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:172
+msgid "unable to open userdb"
+msgstr "userdb-käyttäjätietokannan avaaminen epäonnistui"
+
+#: lib/util/aix.c:227
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "vaihtaminen registeröitymiseen \"%s\" käyttäjälle %s epäonnistui"
+
+#: lib/util/aix.c:252
+msgid "unable to restore registry"
+msgstr "rekisteröitymisen palauttaminen epäonnistui"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:186 lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349
+#: lib/util/sudo_conf.c:553 src/conversation.c:75 src/exec_common.c:107
+#: src/exec_common.c:123 src/exec_common.c:132 src/exec_monitor.c:167
+#: src/exec_nopty.c:462 src/exec_pty.c:667 src/exec_pty.c:676
+#: src/exec_pty.c:738 src/exec_pty.c:867 src/load_plugins.c:52
+#: src/load_plugins.c:65 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:198 src/parse_args.c:273 src/parse_args.c:540
+#: src/parse_args.c:562 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:115 src/sudo.c:389 src/sudo.c:416 src/sudo.c:481 src/sudo.c:603
+#: src/sudo.c:663 src/sudo.c:673 src/sudo.c:693 src/sudo.c:712 src/sudo.c:721
+#: src/sudo.c:730 src/sudo.c:747 src/sudo.c:788 src/sudo.c:798 src/sudo.c:818
+#: src/sudo.c:1058 src/sudo.c:1079 src/sudo.c:1253 src/sudo.c:1351
+#: src/sudo_edit.c:148 src/sudo_edit.c:771 src/sudo_edit.c:868
+#: src/sudo_edit.c:982 src/sudo_edit.c:1002
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/sudo_conf.c:187
+#: lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349 lib/util/sudo_conf.c:553
+#: src/conversation.c:76 src/exec_common.c:107 src/exec_common.c:124
+#: src/exec_common.c:133 src/exec_pty.c:667 src/exec_pty.c:676
+#: src/exec_pty.c:738 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:199 src/parse_args.c:273 src/parse_args.c:540
+#: src/parse_args.c:562 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:115 src/sudo.c:389 src/sudo.c:416 src/sudo.c:481 src/sudo.c:603
+#: src/sudo.c:818 src/sudo.c:1058 src/sudo.c:1079 src/sudo.c:1253
+#: src/sudo.c:1351 src/sudo_edit.c:148 src/sudo_edit.c:771 src/sudo_edit.c:868
+#: src/sudo_edit.c:982 src/sudo_edit.c:1002
+msgid "unable to allocate memory"
+msgstr "muistin varaaminen epäonnistui"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "Tuntematon signaali"
+
+#: lib/util/strtoid.c:77 lib/util/strtoid.c:124 lib/util/strtoid.c:152
+#: lib/util/strtomode.c:49 lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "virheellinen arvo"
+
+#: lib/util/strtoid.c:84 lib/util/strtoid.c:131 lib/util/strtoid.c:159
+#: lib/util/strtomode.c:55 lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "arvo on liian suuri"
+
+#: lib/util/strtoid.c:86 lib/util/strtoid.c:137 lib/util/strtomode.c:55
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "arvo on liian pieni"
+
+#: lib/util/sudo_conf.c:205
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "virheellinen Path-muuttuja-arvo \"%s\" tiedostossa %s, rivi %u"
+
+#: lib/util/sudo_conf.c:371 lib/util/sudo_conf.c:424
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "virheellinen arvo kohteelle %s \"%s\" tiedostossa %s, rivi %u"
+
+#: lib/util/sudo_conf.c:392
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "tukematon ryhmälähde \"%s\" tiedostossa %s, rivi %u"
+
+#: lib/util/sudo_conf.c:408
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "virheellinen ryhmien \"%s\" enimmäismäärä tiedostossa %s, rivi %u"
+
+#: lib/util/sudo_conf.c:569
+#, c-format
+msgid "unable to stat %s"
+msgstr "käskyn stat %s suorittaminen epäonnistui"
+
+#: lib/util/sudo_conf.c:572
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s ei ole tavallinen tiedosto"
+
+# ensimmäinen parametri on path
+#: lib/util/sudo_conf.c:575
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "polun %s omistaja on %u, pitäisi olla %u"
+
+#: lib/util/sudo_conf.c:579
+#, c-format
+msgid "%s is world writable"
+msgstr "%s on yleiskirjoitettava"
+
+#: lib/util/sudo_conf.c:582
+#, c-format
+msgid "%s is group writable"
+msgstr "%s on ryhmäkirjoitettava"
+
+#: lib/util/sudo_conf.c:592 src/selinux.c:208 src/selinux.c:225 src/sudo.c:357
+#, c-format
+msgid "unable to open %s"
+msgstr "kohteen %s avaaminen epäonnistui"
+
+#: src/exec.c:160
+#, c-format
+msgid "unknown login class %s"
+msgstr "tuntematon kirjautumisluokka %s"
+
+#: src/exec.c:173
+msgid "unable to set user context"
+msgstr "käyttäjäasiayhteyden asettaminen epäonnistui"
+
+#: src/exec.c:189
+msgid "unable to set process priority"
+msgstr "prosessiprioriteetin asettaminen epäonnistui"
+
+#: src/exec.c:197
+#, c-format
+msgid "unable to change root to %s"
+msgstr "root-käyttäjän vaihtaminen käyttäjäksi %s epäonnistui"
+
+#: src/exec.c:210 src/exec.c:216 src/exec.c:223
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "ei kyetä vaihtamaan suoritettavaksi uid-käyttäjätunnisteeksi (%u, %u)"
+
+# parametrina on CWD- eli Change Working Directory- komennolla palautettava hakemisto
+#: src/exec.c:241
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "ei kyetä vaihtamaan hakemistoksi %s"
+
+#: src/exec.c:337 src/exec_monitor.c:526 src/exec_monitor.c:528
+#: src/exec_nopty.c:520 src/exec_pty.c:472 src/exec_pty.c:1184
+#: src/exec_pty.c:1186 src/signal.c:139 src/signal.c:153
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "käsittelijän asettaminen signaalille %d epäonnistui"
+
+# Solaris privileges, remove PRIV_PROC_EXEC post-execve.
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "kohteen PRIV_PROC_EXEC poistaminen kohteesta PRIV_LIMIT epäonnistui"
+
+#: src/exec_monitor.c:326
+msgid "error reading from socketpair"
+msgstr "virhe luettaessa vastakeparista"
+
+#: src/exec_monitor.c:338
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "odottamaton vastaustyyppi paluukanavalla: %d"
+
+#: src/exec_monitor.c:423 src/exec_monitor.c:431 src/exec_monitor.c:439
+#: src/exec_monitor.c:446 src/exec_monitor.c:453 src/exec_monitor.c:460
+#: src/exec_monitor.c:467 src/exec_monitor.c:474 src/exec_monitor.c:481
+#: src/exec_monitor.c:488 src/exec_nopty.c:215 src/exec_nopty.c:224
+#: src/exec_nopty.c:231 src/exec_nopty.c:238 src/exec_nopty.c:245
+#: src/exec_nopty.c:252 src/exec_nopty.c:259 src/exec_nopty.c:266
+#: src/exec_nopty.c:273 src/exec_nopty.c:280 src/exec_nopty.c:287
+#: src/exec_nopty.c:294 src/exec_nopty.c:302 src/exec_pty.c:563
+#: src/exec_pty.c:568 src/exec_pty.c:635 src/exec_pty.c:642 src/exec_pty.c:743
+#: src/exec_pty.c:1029 src/exec_pty.c:1038 src/exec_pty.c:1045
+#: src/exec_pty.c:1052 src/exec_pty.c:1059 src/exec_pty.c:1066
+#: src/exec_pty.c:1073 src/exec_pty.c:1080 src/exec_pty.c:1087
+#: src/exec_pty.c:1094 src/exec_pty.c:1101 src/exec_pty.c:1446
+#: src/exec_pty.c:1456 src/exec_pty.c:1501 src/exec_pty.c:1508
+#: src/exec_pty.c:1533
+msgid "unable to add event to queue"
+msgstr "tapahtuman lisääminen jonoon epäonnistui"
+
+# Istunnolla voi olla ohjaava tty. Istunnon yksi prosessiryhmä voi olla edustaprosessiryhmä ja toimia siten ohjaavana tty:nä, joka vastaanottaa tty-syötteen ja -signaalit.
+#: src/exec_monitor.c:540
+msgid "unable to set controlling tty"
+msgstr "ohjaavan tty:n asettaminen epäonnistui"
+
+#: src/exec_monitor.c:548 src/exec_nopty.c:359 src/exec_pty.c:1261
+#: src/exec_pty.c:1280 src/exec_pty.c:1298 src/tgetpass.c:246
+msgid "unable to create pipe"
+msgstr "putken luominen epäonnistui"
+
+#: src/exec_monitor.c:553 src/exec_nopty.c:377 src/exec_pty.c:1335
+#: src/tgetpass.c:250
+msgid "unable to fork"
+msgstr "fork-kutsu epäonnistui"
+
+#: src/exec_monitor.c:639 src/exec_nopty.c:430
+msgid "unable to restore tty label"
+msgstr "tty-nimiön palauttaminen epäonnistui"
+
+#: src/exec_nopty.c:353 src/exec_pty.c:1193
+msgid "policy plugin failed session initialization"
+msgstr "menettelytapalisäosa epäonnistui istunnon alustamisessa"
+
+#: src/exec_nopty.c:419 src/exec_pty.c:1404
+msgid "error in event loop"
+msgstr "virhe tapahtumasilmukassa"
+
+#: src/exec_nopty.c:528 src/exec_pty.c:504 src/signal.c:101
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "käsittelijän palauttaminen signaalille %d epäonnistui"
+
+#: src/exec_pty.c:143
+msgid "unable to allocate pty"
+msgstr "pty:n varaaminen epäonnistui"
+
+#: src/exec_pty.c:1173
+msgid "unable to create sockets"
+msgstr "vastakkeiden luominen epäonnistui"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "virhe tiedostossa %s, rivi %d alustettaessa lisäosaa \"%s\""
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+# ensimmäinen parametri on path
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "polun %s omistajan on oltava uid %d"
+
+# parametri on path
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "polun %s on oltava vain omistajan kirjoitettava"
+
+#: src/load_plugins.c:172
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "kohteen %s lataaminen epäonnistui: %s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "symbolin \"%s\" löytäminen kohteesta %s epäonnistui"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "tuntematon menettelytapatyyppi %d löytyi kohteesta %s"
+
+#: src/load_plugins.c:193
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "yhteensopimaton lisäosan major-versio %d (odotettiin %d) löytyi kohteesta %s"
+
+#: src/load_plugins.c:202
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "ohitetaan menettelytapalisäosa \"%s\" tiedostossa %s, rivi %d"
+
+#: src/load_plugins.c:204
+msgid "only a single policy plugin may be specified"
+msgstr "vain yksi menettelytapalisäosa voidaan määritellä"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "ohitetaan menettelytapalisäosan \"%s\" kaksoiskappale tiedostossa %s, rivi %d"
+
+#: src/load_plugins.c:228
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "ohitetaan siirräntälisäosan \"%s\" kaksoiskappale tiedostossa %s, rivi %d"
+
+#: src/load_plugins.c:331
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "menettelytapalisäosa %s ei sisällä check_policy-metodia"
+
+#: src/net_ifs.c:173 src/net_ifs.c:190 src/net_ifs.c:335 src/sudo.c:476
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "sisäinen virhe, %s-ylivuoto"
+
+#: src/parse_args.c:219
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "virheellinen ympäristömuuttujanimi: %s"
+
+#: src/parse_args.c:313
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "valitsimen -C argumentin on oltava vähintään 3"
+
+#: src/parse_args.c:480
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "sekä valitsimen ”-i” että valitsimen ”-s” määritteleminen ei ole sallittua"
+
+#: src/parse_args.c:484
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "sekä valitsimen ”-i” että valitsimen ”-E” määritteleminen ei ole sallittua"
+
+#: src/parse_args.c:494
+msgid "the `-E' option is not valid in edit mode"
+msgstr "valitsin ”-E” ei ole kelvollinen muokkaustilassa"
+
+#: src/parse_args.c:496
+msgid "you may not specify environment variables in edit mode"
+msgstr "ympäristömuuttujien määritteleminen muokkaustilassa ei ole sallittua"
+
+#: src/parse_args.c:504
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "valitsinta ”-U” voidaan käyttää vain valitsimen ”-l” kanssa"
+
+#: src/parse_args.c:508
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "valitsimia ”-A” ja ”-S” ei voi käyttää yhdessä"
+
+#: src/parse_args.c:584
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit ei ole tuettu tällä alustalla"
+
+#: src/parse_args.c:657
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Vain yksi valitsimista -e, -h, -i, -K, -l, -s, -v tai -V voidaan määritellä"
+
+#: src/parse_args.c:671
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - muokkaa tiedostoja toisena käyttäjänä\n"
+"\n"
+
+#: src/parse_args.c:673
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - suorita komentoja toisena käyttäjänä\n"
+"\n"
+
+#: src/parse_args.c:678
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Valitsimet:\n"
+
+#: src/parse_args.c:680
+msgid "use a helper program for password prompting"
+msgstr "käytä apuohjelmaa salasanakyselyyn"
+
+#: src/parse_args.c:683
+msgid "use specified BSD authentication type"
+msgstr "käytä määriteltyä BSD-todennustyyppiä"
+
+#: src/parse_args.c:686
+msgid "run command in the background"
+msgstr "suorita komento taustalla"
+
+#: src/parse_args.c:688
+msgid "close all file descriptors >= num"
+msgstr "sulje kaikki tiedostokuvaajat >= num"
+
+#: src/parse_args.c:691
+msgid "run command with the specified BSD login class"
+msgstr "suorita komento määritellyllä BSD-kirjautumisluokalla"
+
+#: src/parse_args.c:694
+msgid "preserve user environment when running command"
+msgstr "säilytä käyttäjäympäristö komentoa suoritettaessa"
+
+#: src/parse_args.c:696
+msgid "preserve specific environment variables"
+msgstr "säilytä maaritellyt ympäristömuuttujat"
+
+#: src/parse_args.c:698
+msgid "edit files instead of running a command"
+msgstr "muokkaa tiedostoja komennon suorittamisen sijasta"
+
+# tämä viittaa runas_group-määritelyyn
+#: src/parse_args.c:700
+msgid "run command as the specified group name or ID"
+msgstr "suorita komento määriteltynä ryhmänimenä tai tunnisteena"
+
+#: src/parse_args.c:702
+msgid "set HOME variable to target user's home dir"
+msgstr "aseta HOME-muuttuja osoittamaan kohdekäyttäjän kotihakemistoon"
+
+#: src/parse_args.c:704
+msgid "display help message and exit"
+msgstr "näytä opasteviesti ja poistu"
+
+#: src/parse_args.c:706
+msgid "run command on host (if supported by plugin)"
+msgstr "suorita komento verkkokoneessa (jos lisäosa tukee)"
+
+#: src/parse_args.c:708
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "suorita kirjautumiskomentoikkuna kohdekäyttäjänä; komento voidaan myös määritellä"
+
+#: src/parse_args.c:710
+msgid "remove timestamp file completely"
+msgstr "poista aikaleimatiedosto kokonaan"
+
+#: src/parse_args.c:712
+msgid "invalidate timestamp file"
+msgstr "mitätöi aikaleimatiedosto"
+
+#: src/parse_args.c:714
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "luettele käyttäjä käyttöoikeudet ja tarkista määritelty komento; käytä kahdesti pitemmällä muodolla"
+
+#: src/parse_args.c:716
+msgid "non-interactive mode, no prompts are used"
+msgstr "vuorovaikutteeton tila, ei kysy käyttäjältä"
+
+#: src/parse_args.c:718
+msgid "preserve group vector instead of setting to target's"
+msgstr "säilytä ryhmävektori kohteen vektorin asettamisen sijasta"
+
+#: src/parse_args.c:720
+msgid "use the specified password prompt"
+msgstr "käytä määriteltyä salasanakehotetta"
+
+#: src/parse_args.c:723
+msgid "create SELinux security context with specified role"
+msgstr "luo SELinux-turva-asiayhteys määritellyllä roolilla"
+
+#: src/parse_args.c:726
+msgid "read password from standard input"
+msgstr "lue salasana vakiosyötteestä"
+
+#: src/parse_args.c:728
+msgid "run shell as the target user; a command may also be specified"
+msgstr "suorita komentotulkki kohdekäyttäjänä; myös komento voidaan määritellä"
+
+#: src/parse_args.c:731
+msgid "create SELinux security context with specified type"
+msgstr "luo SELinux-turva-asiayhteys määritellyllä roolilla"
+
+#: src/parse_args.c:734
+msgid "terminate command after the specified time limit"
+msgstr "päätä komento määrätyn aikarajan jälkeen"
+
+#: src/parse_args.c:736
+msgid "in list mode, display privileges for user"
+msgstr "luettelotilassa, näytä käyttöoikeudet käyttäjälle"
+
+#: src/parse_args.c:738
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "suorita komento (tai muokkaa tiedostoa) määriteltynä käyttäjänimenä tai tunnisteena"
+
+#: src/parse_args.c:740
+msgid "display version information and exit"
+msgstr "näytä versiotiedot ja poistu"
+
+#: src/parse_args.c:742
+msgid "update user's timestamp without running a command"
+msgstr "päivitä käyttäjän aikaleima suorittamatta komentoa"
+
+#: src/parse_args.c:744
+msgid "stop processing command line arguments"
+msgstr "lopeta komentoriviargumenttien käsittely"
+
+#: src/selinux.c:78
+msgid "unable to open audit system"
+msgstr "audit-järjestelmän avaaminen epäonnistui"
+
+#: src/selinux.c:88
+msgid "unable to send audit message"
+msgstr "audit-viestin lähettäminen epäonnistui"
+
+#: src/selinux.c:116
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "funktion fgetfilecon %s kutsuminen epäonnistui"
+
+#: src/selinux.c:121
+#, c-format
+msgid "%s changed labels"
+msgstr "%s muutti nimiöitä"
+
+#: src/selinux.c:126
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "asiayhteyden palauttaminen kohteelle %s epäonnistui"
+
+#: src/selinux.c:167
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "kohteen %s avaaminen epäonnistui, ei nimiöidä uudelleen tty:tä"
+
+#: src/selinux.c:171 src/selinux.c:212 src/selinux.c:229
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s ei ole merkkilaite, ei nimiöidä uudelleen tty:tä"
+
+#: src/selinux.c:180
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "nykyisen tty-asiayhteyden hakeminen epäonnistui, ei nimiöidä uudelleen tty:tä"
+
+#: src/selinux.c:187
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "tuntematon turvaluokka \"chr_file\", ei nimiöidä uudelleen tty:tä"
+
+#: src/selinux.c:192
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "uuden tty-asiayhteyden hakeminen epäonnistui, ei nimiöidä uudelleen tty:tä"
+
+#: src/selinux.c:199
+msgid "unable to set new tty context"
+msgstr "uuden tty-asiayhteyden asettaminen epäonnistui"
+
+#: src/selinux.c:273
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "tyypille %s on määriteltävä rooli"
+
+#: src/selinux.c:279
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "oletustyypin hakeminen roolille %s epäonnistui"
+
+#: src/selinux.c:297
+#, c-format
+msgid "failed to set new role %s"
+msgstr "uuden roolin %s asettaminen epäonnistui"
+
+#: src/selinux.c:301
+#, c-format
+msgid "failed to set new type %s"
+msgstr "uuden tyypin %s asettaminen epäonnistui"
+
+#: src/selinux.c:313
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s ei ole kelvollinen asiayhteys"
+
+#: src/selinux.c:348
+msgid "failed to get old_context"
+msgstr "kohteen old_context hakeminen epäonnistui"
+
+#: src/selinux.c:354
+msgid "unable to determine enforcing mode."
+msgstr "vahvistustilan määritteleminen epäonnistui."
+
+#: src/selinux.c:371
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "ei kyetä asettamaan tty-asiayhteydeksi %s"
+
+#: src/selinux.c:410
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "ei kyetä asettamaan suoritusasiayhteydeksi %s"
+
+#: src/selinux.c:417
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "ei kyetä asettamaan avaimenluontiasiayhteydeksi %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "vaatii vähintään yhden argumentin"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "virheellinen tiedostokuvaajanumero: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "salasanakyselyn %s suorittaminen komentorivi-ikkunassa epäonnistui"
+
+#: src/sesh.c:125 src/sudo.c:1117
+#, c-format
+msgid "unable to execute %s"
+msgstr "kohteen %s suorittaminen epäonnistui"
+
+#: src/signal.c:83
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "käsittelijän tallentaminen signaalille %d epäonnistui"
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "resurssivalvontaraja saavutettu"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "käyttäjä \"%s\" ei ole hankkeen \"%s\" jäsen"
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr "kutsuttu tehtävä on final-tyyppinen"
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "hankkeeseen \"%s\" liittyminen epäonnistui"
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "hankkeelle \"%s\" ei ole oletusyhteydet hyväksyvää resurssivarantoa"
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "hankkeelle \"%s\" ei ole määriteltyä resurssivarantoa"
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "hankkeelle \"%s\" ei voitu sitoa oletusresurssivarantoa"
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "funktio setproject hankkeelle \"%s\" epäonnistui"
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "varoitus, hankkeen \"%s\" resurssiohjausosoitus epäonnistui"
+
+#: src/sudo.c:198
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo-versio %s\n"
+
+#: src/sudo.c:200
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Asetusvalitsimet: %s\n"
+
+#: src/sudo.c:208
+msgid "fatal error, unable to load plugins"
+msgstr "vakava virhe, lisäosien lataaminen epäonnistui"
+
+#: src/sudo.c:216
+msgid "unable to initialize policy plugin"
+msgstr "menettelytapalisäosan alustaminen epäonnistui"
+
+#: src/sudo.c:260
+msgid "plugin did not return a command to execute"
+msgstr "lisäosa ei palauta suoritettavaa komentoa"
+
+#: src/sudo.c:276
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "virhe alustettaessa siirräntälisäosaa %s"
+
+#: src/sudo.c:299
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "odottamaton sudo-tila 0x%x"
+
+#: src/sudo.c:461
+msgid "unable to get group vector"
+msgstr "ei kyetä hakemaan ryhmävektoria"
+
+#: src/sudo.c:523
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "tuntematon uid-käyttäjätunniste %u: kuka olet?"
+
+#: src/sudo.c:579
+msgid "unable to determine tty"
+msgstr "tty:n määritteleminen epäonnistui"
+
+# ensimmäinen parametri on path
+#: src/sudo.c:867
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "polun %s omistajan on oltava uid %d ja setuid-bitin on oltava asetettu"
+
+#: src/sudo.c:870
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "todellinen käyttäjätunniste ei ole %d, onko %s asetettu tiedostojärjestelmässä, jossa on ’nosuid’-valitsin vai onko tämä NFS-tiedostojärjestelmä ilman root-käyttöoikeuksia?"
+
+#: src/sudo.c:876
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "todellinen käyttäjätunniste ei ole %d, onko sudo asennettu setuid root -käyttöoikeuksilla?"
+
+#: src/sudo.c:929
+msgid "unable to set supplementary group IDs"
+msgstr "lisäryhmätunnisteiden asettaminen epäonnistui"
+
+# tämän ymmärrän niin, että käyttöjärjestelmäydin luo tiedoston ja antaa tälle tavallaan tilapäisen effective gid-tunnisteen, joka vaihdetaan suorittamisen yhteydessä prosessin omistajan suoritettavaksi ryhmätunnisteeksi.
+#: src/sudo.c:936
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "voimassaolevan gid-ryhmätunnisteen asettaminen suoritettavaksi gid-ryhmätunnisteeksi %u epäonnistui"
+
+#: src/sudo.c:942
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "gid-ryhmätunnisteen asettaminen suoritettavaksi gid-ryhmätunnisteeksi %u epäonnistui"
+
+#: src/sudo.c:999
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "lapsiprosessin odottamaton päättymisehto: %d"
+
+#: src/sudo.c:1145
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "menettelytapalisäosa %s ei sisällä ”check_policy”-metodia"
+
+#: src/sudo.c:1163
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "menettelytapalisäosa %s ei tue luettelointikäyttöoikeuksia"
+
+#: src/sudo.c:1180
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "menettelytapalisäosa %s ei tue valitsinta -v"
+
+#: src/sudo.c:1195
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "menettelytapalisäosa %s ei tue valitsimia -k/-K"
+
+#: src/sudo_edit.c:178 src/sudo_edit.c:267
+msgid "unable to restore current working directory"
+msgstr "nykyisen työhakemiston palauttaminen epäonnistui"
+
+#: src/sudo_edit.c:574 src/sudo_edit.c:686
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: ei ole tavallinen tiedosto"
+
+#: src/sudo_edit.c:581
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: symbolisten linkkien muokkaus ei ole sallittua"
+
+#: src/sudo_edit.c:584
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: tiedostojen muokkaus kirjoitettavassa hakemistossa ei ole sallittua"
+
+#: src/sudo_edit.c:617 src/sudo_edit.c:724
+#, c-format
+msgid "%s: short write"
+msgstr "%s: lyhyt kirjoitus"
+
+#: src/sudo_edit.c:687
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s jätetty muokkaamattomaksi"
+
+#: src/sudo_edit.c:700 src/sudo_edit.c:885
+#, c-format
+msgid "%s unchanged"
+msgstr "%s muuttamaton"
+
+#: src/sudo_edit.c:713 src/sudo_edit.c:735
+#, c-format
+msgid "unable to write to %s"
+msgstr "kohteeseen %s kirjoittaminen epäonnistui"
+
+#: src/sudo_edit.c:714 src/sudo_edit.c:733 src/sudo_edit.c:736
+#: src/sudo_edit.c:910 src/sudo_edit.c:914
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "muokkausistunnon sisältö jätetty kohteessa %s"
+
+#: src/sudo_edit.c:732
+msgid "unable to read temporary file"
+msgstr "tilapäisen tiedoston lukeminen epäonnistui"
+
+#: src/sudo_edit.c:815
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: sisäinen virhe: polkujen pariton määrä"
+
+#: src/sudo_edit.c:817
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: tilapäisten tiedostojen luominen epäonnistui"
+
+#: src/sudo_edit.c:819 src/sudo_edit.c:917
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: tuntematon virhe %d"
+
+#: src/sudo_edit.c:909
+msgid "unable to copy temporary files back to their original location"
+msgstr "tilapäisten tiedostojen kopioiminen takaisin niiden alkuperäiseen sijaintiin epäonnistui"
+
+#: src/sudo_edit.c:913
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "joidenkin tilapäisten tiedostojen kopioiminen takaisin niiden alkuperäiseen sijaintiin epäonnistui"
+
+#: src/sudo_edit.c:958
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "uid-käyttäjätunnisteen vaihtaminen root-tunnisteeksi (%u) epäonnistui"
+
+#: src/sudo_edit.c:975
+msgid "plugin error: missing file list for sudoedit"
+msgstr "lisäosavirhe: puuttuu sudoedit-tiedostoluettelo"
+
+#: src/sudo_edit.c:1016 src/sudo_edit.c:1029
+msgid "unable to read the clock"
+msgstr "kellon lukeminen epäonnistui"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr "ei tty:tä käytettävissä eikä salasanan kyselyohjelmaa määriteltynä"
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "salasanan kyselyohjelma ei ole määritelty, yritä asettaa SUDO_ASKPASS"
+
+#: src/tgetpass.c:261
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "ei kyetä asettamaan gid-ryhmätunnisteeksi %u"
+
+#: src/tgetpass.c:265
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "ei kyetä asettamaan uid-käyttäjätunnisteeksi %u"
+
+#: src/tgetpass.c:270
+#, c-format
+msgid "unable to run %s"
+msgstr "salasanakyselyn %s suorittaminen epäonnistui"
+
+#: src/utmp.c:268
+msgid "unable to save stdin"
+msgstr "vakiosyötteeseen tallentaminen epäonnistui"
+
+#: src/utmp.c:270
+msgid "unable to dup2 stdin"
+msgstr "funktion dup2 kutsuminen vakiosyötteellä epäonnistui"
+
+#: src/utmp.c:273
+msgid "unable to restore stdin"
+msgstr "vakiosyötteen palauttaminen epäonnistui"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "virhe luettaessa signaaliputkesta"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "virhe luettaessa putkesta"
+
+#~ msgid "internal error, tried allocate zero bytes"
+#~ msgstr "sisäinen virhe, yritettiin varata nolla tavua"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "pääteikkunan asentaminen raakatilaan epäonnistui"
+
+#~ msgid "unable to open socket"
+#~ msgstr "vastakkeen avaaminen epäonnistui"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "sisäinen virhe, yritettiin suorittaa emalloc2(0)"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "sisäinen virhe, yritettiin suorittaa ecalloc(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "sisäinen virhe, yritettiin suorittaa erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "sisäinen virhe, yritettiin suorittaa erealloc3(0)"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "sisäinen virhe, yritettiin suorittaa erecalloc(0)"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: ylivuoto havaittu"
+
+#~ msgid "value out of range"
+#~ msgstr "arvo lukualueen ulkopuolella"
+
+#~ msgid "select failed"
+#~ msgstr "select-funktio epäonnistui"
+
+#~ msgid "list user's available commands\n"
+#~ msgstr "luettele käyttäjän käytettävissä olevat komennot\n"
+
+#~ msgid "run a shell as target user\n"
+#~ msgstr "suorita komentotulkki kohdekäyttäjänä\n"
+
+#~ msgid "when listing, list specified user's privileges\n"
+#~ msgstr "luetteloitaessa luettele määritellyn käyttäjän käyttöoikeudet\n"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "internal error, emalloc2() overflow"
+#~ msgstr "sisäinen virhe, emalloc2() -ylivuoto"
+
+#~ msgid "internal error, erealloc3() overflow"
+#~ msgstr "sisäinen virhe, erealloc3() -ylivuoto"
+
+#~ msgid "%s: at least one policy plugin must be specified"
+#~ msgstr "%s: vähintään yksi menettelytapalisäosa on määriteltävä"
+
+#~ msgid "must be setuid root"
+#~ msgstr "on oltava setuid root"
+
+#~ msgid "the argument to -D must be between 1 and 9 inclusive"
+#~ msgstr "valitsimen -D argumentin on oltava alueella 1 - 9"
diff --git a/po/fr.mo b/po/fr.mo
new file mode 100644
index 0000000..4cbea63
--- /dev/null
+++ b/po/fr.mo
Binary files differ
diff --git a/po/fr.po b/po/fr.po
new file mode 100644
index 0000000..2eeedd0
--- /dev/null
+++ b/po/fr.po
@@ -0,0 +1,978 @@
+# Messages français pour sudo.
+# Copyright (C) 2018 Free Software Foundation, Inc.
+# This file is put in the public domain.
+# Todd C. Miller <Todd.Miller@courtesan.com>, 2011-2013
+# Frédéric Marchal <fmarchal@perso.be>, 2018
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-30 17:35+0100\n"
+"Last-Translator: Frédéric Marchal <fmarchal@perso.be>\n"
+"Language-Team: French <traduc@traduc.org>\n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n >= 2);\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "impossible d'ouvrir la base de données utilisateurs"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "impossible de basculer vers le registre « %s » pour %s"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "impossible de rétablir le registre"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "impossible d'allouer la mémoire"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "Signal inconnu"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "valeur incorrecte"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "valeur trop grande"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "valeur trop petite"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "valeur de chemin « %s » incorrecte dans %s, ligne %u"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "valeur « %2$s » incorrecte pour %1$s dans %3$s, ligne %4$u"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "source de groupe « %s » non supportée dans %s, ligne %u"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "groupes max « %s » incorrects dans %s, ligne %u"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "impossible d'évaluer par stat() %s"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s n'est pas un fichier régulier"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s est la propriété du uid %u alors que ça devrait être %u"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "%s peut être écrit par tout le monde"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "%s peut être écrit par le groupe"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "impossible d'ouvrir %s"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "classe de login %s inconnue"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "impossible de changer le contexte utilisateur"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "impossible de changer la priorité du processus"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "impossible de changer root en %s"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "impossible de changer vers runas uid (%u, %u)"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "impossible de changer le répertoire vers %s"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "impossible de spécifier le gestionnaire pour le signal %d"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "impossible de supprimer PRIV_PROC_EXEC de PRIV_LIMIT"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "erreur de lecture sur la paire de sockets"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "réponse inattendue sur le backchannel : %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "impossible d'ajouter l'événement à la queue"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "impossible de choisir le tty de contrôle"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "impossible de créer le tube"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "impossible de recevoir un message du parent"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "erreur de fork"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "impossible d'exécuter %s"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "impossible de rétablir l'étiquette du tty"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "le greffon de règles a échoué lors de l'initialisation de la session"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "erreur dans la boucle des événements"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "impossible de rétablir le gestionnaire pour le signal %d"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "impossible d'allouer le pty"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "impossible de créer des sockets"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "impossible d'envoyer le message au processus de monitoring"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "erreur dans %s, ligne %d lors du chargement du greffon « %s »"
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s doit être la propriété du uid %d"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "seul le propriétaire doit pouvoir écrire dans %s"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "impossible de charger %s : %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "impossible de trouver le symbole « %s » dans %s"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "type de règle %d inconnu dans %s"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "greffon à la version majeure %d incompatible (%d attendu) trouvé dans %s"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "ignore le greffon de règles « %s » dans %s, ligne %d"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "un seul greffon de règles peut être spécifié"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "ignore le greffon de règles en double « %s » dans %s, ligne %d"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "ignore le greffon E/S en double « %s » dans %s, ligne %d"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "le greffon de règles %s ne contient pas de méthode check_policy"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "erreur interne, débordement %s"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "nom de variable d'environnement invalide: %s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "l'argument à -C doit être un nombre plus grand ou égal à 3"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "vous ne pouvez pas spécifier les options « -i » et « -s » en même temps"
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "vous ne pouvez pas spécifier les options « -i » et « -E » en même temps"
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "l'option « -E » n'est pas valable en mode édition"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "vous ne pouvez pas spécifier de variable d'environnement en mode édition"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "l'option « -U » ne peut être utilisée qu'avec l'option « -l »"
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "les options « -A » et « -S » ne peuvent pas être utilisées ensemble"
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit n'est pas pris en charge sur cette plate-forme"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Seule une des options -e, -h, -i, -K, -l, -s, -v ou -V peut être spécifiée"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s – édite les fichiers en tant qu'un autre utilisateur\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s – exécute une commande en tant qu'un autre utilisateur\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Options:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "utiliser un programme adjoint pour demander le mot de passe"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "utiliser le type d'authentification BSD spécifié"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "exécuter la commande en arrière-plan"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "fermer tous les descripteurs de fichiers >= n°"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "exécuter la commande avec la classe de login BSD"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "préserver l'environnement de l'utilisateur en exécutant la commande"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "préserver les variables d'environnement spécifiques"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "éditer les fichiers au lieu d'exécuter une commande"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "exécuter la commande en tant que le nom ou ID de groupe spécifié"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "assigner à la variable HOME le répertoire personnel de l'utilisateur cible"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "afficher le message d'aide et terminer"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "exécuter la commande sur l'hôte (si supporté par le greffon)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "exécuter le shell de login comme l'utilisateur cible. Une commande peut aussi être spécifiée"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "supprime complètement le fichier d'horodatage"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "invalide le fichier d'horodatage"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "afficher les privilèges de l'utilisateur ou vérifie une commande spécifique. Utilisez deux fois pour une forme plus longue"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "mode non interactif, aucune invite utilisée"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "préserve le vecteur des groupes au lieu de le changer en celui de la cible"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "utiliser l'invite de mot de passe spécifié"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "créer le contexte de sécurité SELinux avec le rôle spécifié"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "lire le mot de passe depuis l'entrée standard"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "exécuter le shell en tant que l'utilisateur cible. Une commande peut aussi être spécifiée"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "créer le contexte de sécurité SELinux avec le type spécifié"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "terminer la commande après la limite de temps spécifiée"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "en mode liste, afficher les privilèges de l'utilisateur"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "exécuter la commande (ou éditer le fichier) sous le nom d'utilisateur ou le ID spécifié"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "afficher les informations de version et terminer"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "mettre à jour l'horodatage de l'utilisateur sans exécuter de commande"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "arrêter de traiter les arguments en ligne de commande"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "impossible d'ouvrir le système d'audit"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "impossible d'envoyer le message d'audit"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "impossible d'exécuter fgetfilecon %s"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s à changé des étiquettes"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "impossible de rétablir le contexte de %s"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "impossible d'ouvrir %s, le tty n'est pas ré-étiqueté"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s n'est pas un périphérique caractères, le tty n'est pas ré-étiqueté"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "impossible d'obtenir le contexte actuel du tty, le tty n'est pas ré-étiqueté"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "classe de sécurité « chr_file » inconnue, le tty n'est pas ré-étiqueté"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "impossible d'obtenir le nouveau contexte du tty, le tty n'est pas ré-étiqueté"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "impossible de changer le nouveau contexte du tty"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "vous devez spécifier un rôle pour le type %s"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "impossible d'obtenir le type par défaut pour le rôle %s"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "échec lors du changement du nouveau rôle %s"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "échec lors du changement du nouveau type %s"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s n'est pas un contexte valide"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "échec de l'obtention de old_context"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "impossible de déterminer le mode de contrainte"
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "impossible de changer le contexte du tty en %s"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "impossible de changer le contexte exec en %s"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "impossible de changer le contexte de création de clé en %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "exige au moins un argument"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "numéro de descripteur de fichier invalide: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "impossible d'exécuter %s comme un shell de login"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "impossible de sauvegarder le gestionnaire du signal %d"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "la limite de contrôle de la ressource a été atteinte"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "l'utilisateur « %s » n'est pas un membre du projet « %s »"
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "la tâche appelante est « final »"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "impossible de joindre le projet « %s »"
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "aucun pool de ressources acceptant les liaisons par défaut existe pour le projet « %s »"
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "le pool de ressources spécifié n'existe pas pour le projet « %s »"
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "impossible de se lier au pool de ressources par défaut du projet « %s »"
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "setproject a échoué pour le projet « %s »"
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "attention, l'assignement du contrôle de ressources a échoue pour le projet « %s »"
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo version %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Options de configuration : %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "erreur fatale, impossible de charger les greffons"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "impossible d'initialiser le greffon de règles"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "le greffon n'a pas retourné une commande à exécuter"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "erreur à l'initialisation du greffon E/S %s"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "mode sudo 0x%x inattendu"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "vous n'existez pas dans la base de données %s"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "impossible de déterminer le tty"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s doit être la propriété du uid %d et avoir le bit setuid mis"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "le uid effectif n'est pas %d. Est-ce que %s est sur un système de fichiers avec l'option « nosuid » ou un système de fichiers NFS sans privilèges root ?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "le uid effectif n'est pas %d. Est-ce que sudo est installé setuid root ?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "impossible d'attribuer les ID de groupe supplémentaires"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "impossible de changer le gid effectif à runas gid %u"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "impossible de changer le gid à runas gid %u"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "condition de fin de l'enfant inconnue: %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "le greffon de règles %s n'a pas de méthode « check_policy »"
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "le greffon de règles %s ne supporte pas les privilèges de listage"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "le greffon de règles %s ne supporte pas l'option -v"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "le greffon de règles %s ne supporte pas les options -k/-K"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "aucun répertoire temporaire est disponible en écriture"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "impossible de rétablir le répertoire de travail actuel"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: pas un fichier régulier"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: l'édition de liens symboliques n'est pas permise"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: l'édition de fichiers dans un répertoire accessible en écriture n'est pas permis"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s: écriture trop courte"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s laissé tel quel"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "%s non modifié"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "impossible d'écrire dans %s"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "contenu de la session d'édition laissé dans %s"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "impossible de lire le fichier temporaire"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: erreur interne: nombre impaire de chemins"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: impossible de créer des fichiers temporaires"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: erreur %d inconnue"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "impossible de copier les fichiers temporaires à leurs emplacements d'origine"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "impossible de copier quelques fichiers temporaires à leurs emplacements d'origine"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "impossible de changer le uid en root (%u)"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "erreur de greffon : liste de fichiers manquantes pour sudoedit"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "impossible de lire l'horloge"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "délai d'attente dépassé durant la lecture du mot de passe"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "aucun mot de passe fourni"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "impossible de lire le mot de passe"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "pas de tty présent et pas de programme askpass spécifié"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "pas de programme askpass spécifié, essayez avec SUDO_ASKPASS"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "impossible de changer le gid en %u"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "impossible de changer le uid en %u"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "impossible d'exécuter %s"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "impossible de sauvegarder stdin"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "impossible d'exécuter dup2 sur stdin"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "impossible de rétablir stdin"
+
+#~ msgid "unable to get group vector"
+#~ msgstr "impossible d'obtenir le vecteur de groupes"
+
+#~ msgid "unknown uid %u: who are you?"
+#~ msgstr "uid %u inconnu : qui êtes-vous ?"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "erreur lors de la lecture du tube signal"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "erreur de lecture sur le tube"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "impossible de mettre le terminal en mode brut"
+
+#~ msgid "internal error, tried allocate zero bytes"
+#~ msgstr "erreur interne, a tenté d'allouer zéro octets"
+
+#~ msgid "unable to open socket"
+#~ msgstr "impossible d'ouvrir la socket"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "erreur interne, emalloc2(0) a été tenté"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "erreur interne, ecalloc(0) a été tenté"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "erreur interne, erealloc(0) a été tenté"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "erreur interne, erealloc3(0) a été tenté"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "erreur interne, erecalloc(0) a été tenté"
+
+#~ msgid "value out of range"
+#~ msgstr "valeur hors limites"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "select failed"
+#~ msgstr "select a échoué"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: débordement détecté"
diff --git a/po/fur.mo b/po/fur.mo
new file mode 100644
index 0000000..d91a19c
--- /dev/null
+++ b/po/fur.mo
Binary files differ
diff --git a/po/fur.po b/po/fur.po
new file mode 100644
index 0000000..8ceb326
--- /dev/null
+++ b/po/fur.po
@@ -0,0 +1,873 @@
+# Friulian translations for sudo package
+# This file is put in the public domain.
+# Fabio Tomat <f.t.public@gmail.com>, 2017
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo-1.8.20b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2017-03-09 11:58-0700\n"
+"PO-Revision-Date: 2017-06-24 14:55+0200\n"
+"Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n"
+"Language-Team: Friulian <f.t.public@gmail.com>\n"
+"Language: fur\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.12\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:172
+msgid "unable to open userdb"
+msgstr "impussibil vierzi userdb"
+
+#: lib/util/aix.c:227
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "impussibil passâ al regjistri \"%s\" par %s"
+
+#: lib/util/aix.c:252
+msgid "unable to restore registry"
+msgstr "impussibil ripristinâ il regjistri"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:184 lib/util/sudo_conf.c:270 lib/util/sudo_conf.c:347
+#: lib/util/sudo_conf.c:545 src/conversation.c:75 src/exec_common.c:107
+#: src/exec_common.c:123 src/exec_common.c:132 src/exec_monitor.c:214
+#: src/exec_nopty.c:326 src/exec_pty.c:623 src/exec_pty.c:631
+#: src/exec_pty.c:868 src/load_plugins.c:52 src/load_plugins.c:65
+#: src/load_plugins.c:215 src/load_plugins.c:238 src/load_plugins.c:303
+#: src/load_plugins.c:318 src/parse_args.c:183 src/parse_args.c:205
+#: src/parse_args.c:376 src/parse_args.c:472 src/parse_args.c:494
+#: src/preserve_fds.c:47 src/preserve_fds.c:130 src/selinux.c:83
+#: src/selinux.c:292 src/selinux.c:415 src/selinux.c:424 src/sesh.c:115
+#: src/sudo.c:398 src/sudo.c:423 src/sudo.c:488 src/sudo.c:610 src/sudo.c:670
+#: src/sudo.c:680 src/sudo.c:700 src/sudo.c:719 src/sudo.c:728 src/sudo.c:737
+#: src/sudo.c:754 src/sudo.c:795 src/sudo.c:805 src/sudo.c:825 src/sudo.c:1246
+#: src/sudo.c:1267 src/sudo.c:1441 src/sudo.c:1535 src/sudo_edit.c:151
+#: src/sudo_edit.c:775 src/sudo_edit.c:872 src/sudo_edit.c:985
+#: src/sudo_edit.c:1005
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/sudo_conf.c:185
+#: lib/util/sudo_conf.c:270 lib/util/sudo_conf.c:347 lib/util/sudo_conf.c:545
+#: src/conversation.c:76 src/exec_common.c:107 src/exec_common.c:124
+#: src/exec_common.c:133 src/exec_pty.c:623 src/exec_pty.c:631
+#: src/exec_pty.c:868 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:183
+#: src/parse_args.c:205 src/parse_args.c:376 src/parse_args.c:472
+#: src/parse_args.c:494 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:83 src/selinux.c:292 src/selinux.c:415 src/selinux.c:424
+#: src/sesh.c:115 src/sudo.c:398 src/sudo.c:423 src/sudo.c:488 src/sudo.c:610
+#: src/sudo.c:825 src/sudo.c:1246 src/sudo.c:1267 src/sudo.c:1441
+#: src/sudo.c:1535 src/sudo_edit.c:151 src/sudo_edit.c:775 src/sudo_edit.c:872
+#: src/sudo_edit.c:985 src/sudo_edit.c:1005
+msgid "unable to allocate memory"
+msgstr "impussibil assegnâ memorie"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "Segnâl no cognossût"
+
+#: lib/util/strtoid.c:77 lib/util/strtoid.c:124 lib/util/strtoid.c:152
+#: lib/util/strtomode.c:49 lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "valôr no valit"
+
+#: lib/util/strtoid.c:84 lib/util/strtoid.c:131 lib/util/strtoid.c:159
+#: lib/util/strtomode.c:55 lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "valôr masse grant"
+
+#: lib/util/strtoid.c:86 lib/util/strtoid.c:137 lib/util/strtomode.c:55
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "valôr masse piçul"
+
+#: lib/util/sudo_conf.c:203
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "il valôr percors \"%s\" no valit in %s, rie %u"
+
+#: lib/util/sudo_conf.c:369 lib/util/sudo_conf.c:422
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "valôr no valit par %s \"%s\" in %s, rie %u"
+
+#: lib/util/sudo_conf.c:390
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "sorzint di grup \"%s\" no supuartade in %s, rie %u"
+
+#: lib/util/sudo_conf.c:406
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "grups massims \"%s\" no valits in %s, rie %u"
+
+#: lib/util/sudo_conf.c:561
+#, c-format
+msgid "unable to stat %s"
+msgstr "impussibil eseguî stat su %s"
+
+#: lib/util/sudo_conf.c:564
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s nol è un file regolâr"
+
+#: lib/util/sudo_conf.c:567
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s al è dal uid %u, al varès di jessi di %u"
+
+#: lib/util/sudo_conf.c:571
+#, c-format
+msgid "%s is world writable"
+msgstr "ducj a puedin scrivi su %s"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "%s is group writable"
+msgstr "il grup al pues scrivi su %s"
+
+#: lib/util/sudo_conf.c:584 src/selinux.c:201 src/selinux.c:213 src/sudo.c:366
+#, c-format
+msgid "unable to open %s"
+msgstr "impussibil vierzi %s"
+
+#: src/exec.c:189 src/exec_monitor.c:504 src/exec_monitor.c:506
+#: src/exec_monitor.c:511 src/exec_monitor.c:513 src/exec_monitor.c:527
+#: src/exec_monitor.c:538 src/exec_monitor.c:540 src/exec_monitor.c:542
+#: src/exec_monitor.c:544 src/exec_monitor.c:546 src/exec_monitor.c:548
+#: src/exec_monitor.c:550 src/exec_nopty.c:191 src/exec_nopty.c:193
+#: src/exec_nopty.c:195 src/exec_nopty.c:197 src/exec_nopty.c:199
+#: src/exec_nopty.c:201 src/exec_nopty.c:203 src/exec_nopty.c:205
+#: src/exec_nopty.c:208 src/exec_nopty.c:222 src/exec_nopty.c:224
+#: src/exec_nopty.c:226 src/exec_nopty.c:384 src/exec_pty.c:427
+#: src/exec_pty.c:661 src/exec_pty.c:1196 src/exec_pty.c:1198
+#: src/exec_pty.c:1200 src/exec_pty.c:1202 src/exec_pty.c:1204
+#: src/exec_pty.c:1206 src/exec_pty.c:1208 src/exec_pty.c:1211
+#: src/exec_pty.c:1219 src/exec_pty.c:1221 src/exec_pty.c:1223
+#: src/exec_pty.c:1231 src/exec_pty.c:1233 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "impussibil stabilî il gjestôr pal segnâl %d"
+
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "impussibil gjavâ PRIV_PROC_EXEC dal PRIV_LIMIT"
+
+#: src/exec_monitor.c:277 src/exec_nopty.c:455 src/exec_pty.c:1028
+msgid "error reading from signal pipe"
+msgstr "erôr tal lei dal condot (pipe) dal segnâl"
+
+#: src/exec_monitor.c:363
+msgid "error reading from socketpair"
+msgstr "erôr tal lei dal socketpair"
+
+#: src/exec_monitor.c:372
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "gjenar di rispueste inspietade sul backchannel: %d"
+
+#: src/exec_monitor.c:450 src/exec_monitor.c:458 src/exec_monitor.c:466
+#: src/exec_nopty.c:130 src/exec_nopty.c:138 src/exec_pty.c:516
+#: src/exec_pty.c:521 src/exec_pty.c:591 src/exec_pty.c:598 src/exec_pty.c:873
+#: src/exec_pty.c:1129 src/exec_pty.c:1137 src/exec_pty.c:1322
+#: src/exec_pty.c:1332 src/exec_pty.c:1377 src/exec_pty.c:1384
+#: src/exec_pty.c:1409
+msgid "unable to add event to queue"
+msgstr "impussibil zontâ l'event ae code"
+
+#: src/exec_monitor.c:496 src/exec_monitor.c:570 src/exec_nopty.c:161
+#: src/exec_pty.c:705 src/exec_pty.c:714 src/exec_pty.c:722 src/signal.c:129
+#: src/tgetpass.c:246
+msgid "unable to create pipe"
+msgstr "impussibil creâ il condot (pipe)"
+
+#: src/exec_monitor.c:562
+msgid "unable to set controlling tty"
+msgstr "impussibil stabilî il tty di control"
+
+#: src/exec_monitor.c:573 src/exec_nopty.c:240 src/exec_pty.c:756
+#: src/tgetpass.c:250
+msgid "unable to fork"
+msgstr "impussibil inglovâ (fâ il fork)"
+
+#: src/exec_monitor.c:654 src/exec_nopty.c:292
+msgid "unable to restore tty label"
+msgstr "impussibil ripristinâ la etichete tty"
+
+#: src/exec_nopty.c:233 src/exec_pty.c:1240
+msgid "policy plugin failed session initialization"
+msgstr "il plugin di politche nol è rivât a inizializâ la session"
+
+#: src/exec_nopty.c:281 src/exec_pty.c:1278
+msgid "error in event loop"
+msgstr "erôr tal cicli dal event"
+
+#: src/exec_nopty.c:392 src/exec_pty.c:459 src/signal.c:87
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "impussibil ripristinâ il gjestôr pal segnâl %d"
+
+#: src/exec_pty.c:133
+msgid "unable to allocate pty"
+msgstr "impussibil assegnâ pty"
+
+#: src/exec_pty.c:1179
+msgid "unable to create sockets"
+msgstr "impussibil creâ sockets"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "erôr in %s, rie %d intant che si cjariave il plugin \"%s\""
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s al scugne jessi di proprietât dal uid %d"
+
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s al scugne jessi scrivibil dome dal proprietari"
+
+#: src/load_plugins.c:172
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "impussibil cjariâ %s: %s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "impussibil cjatâ il simbul \"%s\" in %s"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "gjenar di politiche %d no cognossude, cjatade in %s"
+
+#: src/load_plugins.c:193
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "numar principâl di version dal plugin %d no compatibil (si spietave %d) cjatât in %s"
+
+#: src/load_plugins.c:202
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "si ignore il plugin di politiche \"%s\" in %s, rie %d"
+
+#: src/load_plugins.c:204
+msgid "only a single policy plugin may be specified"
+msgstr "dome un singul plugin di politiche al podarès jessi specificât"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "si ignore il plugin di politiche duplicât \"%s\" in %s, rie %d"
+
+#: src/load_plugins.c:228
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "si ignore il plugin I/O duplicât \"%s\" in %s, rie %d"
+
+#: src/load_plugins.c:331
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "il plugin di politiche %s nol inclût un metodi check_policy"
+
+#: src/net_ifs.c:173 src/net_ifs.c:190 src/net_ifs.c:335 src/sudo.c:483
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "erôr interni, %s overflow (stranfât)"
+
+#: src/parse_args.c:242
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "l'argoment di -C al scugne jessi un numar plui grant o compagn a 3"
+
+#: src/parse_args.c:412
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "no si podarès specificâ dutis dôs lis opzions `-i' e `-s'"
+
+#: src/parse_args.c:416
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "no si podarès specificâ dutis dôs lis opzions `-i' e `-E'"
+
+#: src/parse_args.c:426
+msgid "the `-E' option is not valid in edit mode"
+msgstr "la opzion `-E' no je valide in modalitât di modifiche"
+
+#: src/parse_args.c:428
+msgid "you may not specify environment variables in edit mode"
+msgstr "no si podarès specificâ lis variabilis di ambient inte modalitât di modifiche"
+
+#: src/parse_args.c:436
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "la opzion `-U' e podarès jessi doprade dome cun la opzion `-l'"
+
+#: src/parse_args.c:440
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "lis opzions `-A' e `-S' no podaressin jessi dopradis adun"
+
+#: src/parse_args.c:516
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit nol è supuartât su cheste plateforme"
+
+#: src/parse_args.c:589
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Dome une des opzions -e, -h, -i, -K, -l, -s, -v o -V e podarès jessi specificade"
+
+#: src/parse_args.c:603
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - modifiche i file come altri utent\n"
+"\n"
+
+#: src/parse_args.c:605
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - eseguìs un comant come altri utent\n"
+"\n"
+
+#: src/parse_args.c:610
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opzions:\n"
+
+#: src/parse_args.c:612
+msgid "use a helper program for password prompting"
+msgstr "Dopre un program di jutori par domandâ la password"
+
+#: src/parse_args.c:615
+msgid "use specified BSD authentication type"
+msgstr "dopre il gjenar di autenticazion BSD specificât"
+
+#: src/parse_args.c:618
+msgid "run command in the background"
+msgstr "eseguìs il comant in background"
+
+#: src/parse_args.c:620
+msgid "close all file descriptors >= num"
+msgstr "siere ducj i descritôrs di file >= num"
+
+#: src/parse_args.c:623
+msgid "run command with the specified BSD login class"
+msgstr "eseguìs il comant cun la classe di acès BSD specificade"
+
+#: src/parse_args.c:626
+msgid "preserve user environment when running command"
+msgstr "preserve l'ambient utent cuant che si eseguìs un comant"
+
+#: src/parse_args.c:628
+msgid "edit files instead of running a command"
+msgstr "modifiche i file invezit di eseguî un comant"
+
+#: src/parse_args.c:630
+msgid "run command as the specified group name or ID"
+msgstr "eseguìs il comant come il ID o il non dal grup specificât"
+
+#: src/parse_args.c:632
+msgid "set HOME variable to target user's home dir"
+msgstr "stabilìs la variabile HOME ae cartele home dal utent di destinazion"
+
+#: src/parse_args.c:634
+msgid "display help message and exit"
+msgstr "mostre il messaç di jutori e jes"
+
+#: src/parse_args.c:636
+msgid "run command on host (if supported by plugin)"
+msgstr "eseguìs il comant sul host (se supuartât dal plugin)"
+
+#: src/parse_args.c:638
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "eseguìs une shell di acès come utent di destinazion; si podarès ancje specificâ un comant"
+
+#: src/parse_args.c:640
+msgid "remove timestamp file completely"
+msgstr ""
+
+#: src/parse_args.c:642
+msgid "invalidate timestamp file"
+msgstr ""
+
+#: src/parse_args.c:644
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "liste i privileçs dal utent o verifiche un comant specific; doprâ dôs voltis pal formât plui lunc"
+
+#: src/parse_args.c:646
+msgid "non-interactive mode, no prompts are used"
+msgstr "modalitât no interative, nissune richieste e ven presentade"
+
+#: src/parse_args.c:648
+msgid "preserve group vector instead of setting to target's"
+msgstr "preserve il vetôr dal grup invezit di metilu a chel de destinazion"
+
+#: src/parse_args.c:650
+msgid "use the specified password prompt"
+msgstr "dopre la richieste de password specificade"
+
+#: src/parse_args.c:653
+msgid "create SELinux security context with specified role"
+msgstr "cree il contest di sigurece SELinux cul rûl specificât"
+
+#: src/parse_args.c:656
+msgid "read password from standard input"
+msgstr "lei la passwrod dal standard input"
+
+#: src/parse_args.c:658
+msgid "run shell as the target user; a command may also be specified"
+msgstr "eseguìs la shell come l'utent di destinazion; si podarès ancje specificâ un comant"
+
+#: src/parse_args.c:661
+msgid "create SELinux security context with specified type"
+msgstr "cree il contest di sigurece SELinux cul gjenar specificât"
+
+#: src/parse_args.c:664
+msgid "terminate command after the specified time limit"
+msgstr "termine il comant dopo il limit di timp specificât"
+
+#: src/parse_args.c:666
+msgid "in list mode, display privileges for user"
+msgstr "in modalitât liste, mostre i privileçs dal utent"
+
+#: src/parse_args.c:668
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "eseguìs il comant (o modifiche il file) come non utent o ID specificât"
+
+#: src/parse_args.c:670
+msgid "display version information and exit"
+msgstr "mostre informazions di version e jes"
+
+#: src/parse_args.c:672
+msgid "update user's timestamp without running a command"
+msgstr ""
+
+#: src/parse_args.c:674
+msgid "stop processing command line arguments"
+msgstr "ferme la elaborazion dai argoments a rie di comant"
+
+#: src/selinux.c:77
+msgid "unable to open audit system"
+msgstr "impussibil vierzi il sisteme di audit"
+
+#: src/selinux.c:87
+msgid "unable to send audit message"
+msgstr "impussibil inviâ il messaç di audit"
+
+#: src/selinux.c:115
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "impussibil eseguî fgetfilecon %s"
+
+#: src/selinux.c:120
+#, c-format
+msgid "%s changed labels"
+msgstr "%s al à modificâts lis etichetis"
+
+#: src/selinux.c:125
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "impussibil ripristinâ il contest par %s"
+
+#: src/selinux.c:165
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "impussibil vierzi %s, no si torne a etichetâ tty"
+
+#: src/selinux.c:173
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "impussibil otignî il contest tty atuâl, no si torne a etichetâ tty"
+
+#: src/selinux.c:180
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "classe di sigurece \"chr_file\" no cognossude, no si torne a etichetâ tty"
+
+#: src/selinux.c:185
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "impussibil otignî il gnûf contest tty, no si torne a etichetâ tty"
+
+#: src/selinux.c:192
+msgid "unable to set new tty context"
+msgstr "impussibil stabilî un gnûf contest tty"
+
+#: src/selinux.c:256
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "si scugne specificâ un rûl pal gjenar %s"
+
+#: src/selinux.c:262
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "impussibil otignî il gjenar predefinît pal rûl %s"
+
+#: src/selinux.c:280
+#, c-format
+msgid "failed to set new role %s"
+msgstr "no si è rivâts a stabilî il gnûf rûl %s"
+
+#: src/selinux.c:284
+#, c-format
+msgid "failed to set new type %s"
+msgstr "no si è rivâts a stabilî il gnûf gjenar %s"
+
+#: src/selinux.c:296
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s nol è un contest valit"
+
+#: src/selinux.c:331
+msgid "failed to get old_context"
+msgstr "no si è rivâts a otignî old_context"
+
+#: src/selinux.c:337
+msgid "unable to determine enforcing mode."
+msgstr ""
+
+#: src/selinux.c:354
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "impussibil meti il contest di tty a %s"
+
+#: src/selinux.c:393
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "impussibil meti il contest di exec a %s"
+
+#: src/selinux.c:400
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "impussibil meti il contest de creazion de clâf a %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "al domande almancul un argoment"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "numar descritôr file no valit: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "impussibil eseguî %s come une shell di acès"
+
+#: src/sesh.c:125 src/sudo.c:1305
+#, c-format
+msgid "unable to execute %s"
+msgstr "impussibil eseguî %s"
+
+#: src/signal.c:69
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "impussibil salvâ il gjestôr pal segnâl %d"
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "si è rivâts al limit di control de risorse"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "l'utent \"%s\" nol è un membri dal progjet \"%s\""
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr ""
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "impussibil unîsi al progjet \"%s\""
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "nissun font di risorsis pal progjet \"%s\" che al aceti i vincui predefinîts"
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "il font di risorsis specificât nol esist pal progjet \"%s\""
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "impussibil vincolâ al font di risorsis predefinît pal progjet \"%s\""
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "setproject al à falît pal progjet \"%s\""
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "avertiment, faliment de assegnazion dal control de risorse pal progjet \"%s\""
+
+#: src/sudo.c:212
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Version di sudo: %s\n"
+
+#: src/sudo.c:214
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Opzions di configurazion: %s\n"
+
+#: src/sudo.c:222
+msgid "fatal error, unable to load plugins"
+msgstr "erôr fatâl, impussibil cjariâ i plugin"
+
+#: src/sudo.c:230
+msgid "unable to initialize policy plugin"
+msgstr "impussibil inizializâ il plugin de politiche"
+
+#: src/sudo.c:274
+msgid "plugin did not return a command to execute"
+msgstr "il plugin nol à tornât un comant di eseguî"
+
+#: src/sudo.c:290
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "erôr tal inizializâ il plugin I/O %s"
+
+#: src/sudo.c:316
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "modalitât 0x%x di sudo inspietade"
+
+#: src/sudo.c:468
+msgid "unable to get group vector"
+msgstr "impussibil otignî il vetôr di grup"
+
+#: src/sudo.c:530
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "uid %u no cognossût: cui sêstu?"
+
+#: src/sudo.c:586
+msgid "unable to determine tty"
+msgstr "impussibil determinâ tty"
+
+#: src/sudo.c:874
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s al scugne jessi di proprietât dal uid %d e vê stabilît il bit setuid"
+
+#: src/sudo.c:877
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "il uid efetîf nol è %d, %s isal suntun filesystem cun stabilide la opzion 'nosuid' o un filesystem NFS cence privileçs di root?"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "il uid efetîf nol è %d, sudo isal instalât cun setuid root?"
+
+#: src/sudo.c:964
+msgid "unable to set supplementary group IDs"
+msgstr "impussibil stabilî il ID di grup suplementâr"
+
+#: src/sudo.c:971
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "impussibil stabilî il gid efetîf par eseguî come gid %u"
+
+#: src/sudo.c:977
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "impussibil stabilî il gid par eseguî come gid %u"
+
+#: src/sudo.c:1048
+#, c-format
+msgid "unknown login class %s"
+msgstr "classe di acès %s no cognossude"
+
+#: src/sudo.c:1061
+msgid "unable to set user context"
+msgstr "impussibil stabilî il contest utent"
+
+#: src/sudo.c:1077
+msgid "unable to set process priority"
+msgstr "impussibil stabilî la prioritât dal procès"
+
+#: src/sudo.c:1085
+#, c-format
+msgid "unable to change root to %s"
+msgstr "impussibil cambiâ root a %s"
+
+#: src/sudo.c:1098 src/sudo.c:1104 src/sudo.c:1111
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "impussibil passâ a un diviers uid (%u, %u)"
+
+#: src/sudo.c:1129
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "impussibil passâ ae cartele a %s"
+
+#: src/sudo.c:1187
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "condizion di jessude dal fi inspietade: %d"
+
+#: src/sudo.c:1333
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "il plugin di politiche %s al mancje dal metodi `check_policy'"
+
+#: src/sudo.c:1351
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "il plugin di politiche %s nol supuarte il listâ dai privileçs"
+
+#: src/sudo.c:1368
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "il plugin di politiche %s nol supuarte la opzion -v"
+
+#: src/sudo.c:1383
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "il plugin di politiche %s nol supuarte lis opzions -k/-K"
+
+#: src/sudo_edit.c:181 src/sudo_edit.c:270
+msgid "unable to restore current working directory"
+msgstr "impussibil ripristinâ la cartele di lavôr atuâl"
+
+#: src/sudo_edit.c:577 src/sudo_edit.c:689
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: nol è un file regolâr."
+
+#: src/sudo_edit.c:584
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: la modifiche dai colegaments simbolics no je permetude"
+
+#: src/sudo_edit.c:587
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: la modifiche dai file intune cartele cun acès in scriture no je permetude"
+
+#: src/sudo_edit.c:620 src/sudo_edit.c:728
+#, c-format
+msgid "%s: short write"
+msgstr "%s: scriture curte"
+
+#: src/sudo_edit.c:690
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s lassât no modificât"
+
+#: src/sudo_edit.c:703 src/sudo_edit.c:889
+#, c-format
+msgid "%s unchanged"
+msgstr "%s no modificât"
+
+#: src/sudo_edit.c:717 src/sudo_edit.c:739
+#, c-format
+msgid "unable to write to %s"
+msgstr "impussibil scrivi su %s"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:737 src/sudo_edit.c:740
+#: src/sudo_edit.c:914 src/sudo_edit.c:918
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "contignûts de session di modifiche lassâts in %s"
+
+#: src/sudo_edit.c:736
+msgid "unable to read temporary file"
+msgstr "impussibil lei il file temporani"
+
+#: src/sudo_edit.c:819
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: erôr interni: strani numar di percors"
+
+#: src/sudo_edit.c:821
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: impussibil creâ file temporanis"
+
+#: src/sudo_edit.c:823 src/sudo_edit.c:921
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: erôr %d no cognossût"
+
+#: src/sudo_edit.c:913
+msgid "unable to copy temporary files back to their original location"
+msgstr "impussibil tornâ a copiâ i file temporanis te lôr posizion origjinarie"
+
+#: src/sudo_edit.c:917
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "impussibil tornâ a copiâ cualchidun dai file temporanis te lôr posizion origjinarie"
+
+#: src/sudo_edit.c:961
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "impussibil cambiâ il uid a root (%u)"
+
+#: src/sudo_edit.c:978
+msgid "plugin error: missing file list for sudoedit"
+msgstr "erôr di plugin: e mancje la liste file par sudoedit"
+
+#: src/sudo_edit.c:1019 src/sudo_edit.c:1032
+msgid "unable to read the clock"
+msgstr "impussibil lei l'orloi"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr "nissun tty presint e nissun program specificât pe richieste password"
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "nissun program pe richieste password specificât, cîr di stabilî SUDO_ASKPASS"
+
+#: src/tgetpass.c:261
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "impussibil stabilî il gid a %u"
+
+#: src/tgetpass.c:265
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "impussibil stabilî il uid a %u"
+
+#: src/tgetpass.c:270
+#, c-format
+msgid "unable to run %s"
+msgstr "impussibil eseguî %s"
+
+#: src/utmp.c:268
+msgid "unable to save stdin"
+msgstr "impussibil salvâ stdin"
+
+#: src/utmp.c:270
+msgid "unable to dup2 stdin"
+msgstr "impussibil esguî dup2 su stdin"
+
+#: src/utmp.c:273
+msgid "unable to restore stdin"
+msgstr "impussibil ripristinâ stdin"
diff --git a/po/gl.mo b/po/gl.mo
new file mode 100644
index 0000000..ace3418
--- /dev/null
+++ b/po/gl.mo
Binary files differ
diff --git a/po/gl.po b/po/gl.po
new file mode 100644
index 0000000..f84eb0e
--- /dev/null
+++ b/po/gl.po
@@ -0,0 +1,898 @@
+# Galician translations for sudo package.
+# This file is put in the public domain.
+# Fran Dieguez <frandieguez@gnome.org>, 2012.
+# Francisco Diéguez <frandieguez@ubuntu.com>, 2012.
+# Leandro Regueiro <leandro.regueiro@gmail.com>, 2012-2015.
+# Proxecto Trasno - Adaptación do software libre á lingua galega: Se desexas
+# colaborar connosco, podes atopar máis información en <http://www.trasno.net>
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.15b1\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2015-09-10 14:28-0600\n"
+"PO-Revision-Date: 2015-09-15 10:41+0100\n"
+"Last-Translator: Leandro Regueiro <leandro.regueiro@gmail.com>\n"
+"Language-Team: Galician <proxecto@trasno.net>\n"
+"Language: gl\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.5.4\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:155
+msgid "unable to open userdb"
+msgstr "non foi posíbel abrir userdb"
+
+#: lib/util/aix.c:160
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "non foi posíbel ir ao rexistro «%s» para %s"
+
+#: lib/util/aix.c:185
+msgid "unable to restore registry"
+msgstr "non foi posíbel restaurar o rexistro"
+
+#: lib/util/aix.c:204 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:185 lib/util/sudo_conf.c:265 lib/util/sudo_conf.c:342
+#: lib/util/sudo_conf.c:544 src/conversation.c:72 src/exec.c:864
+#: src/exec_common.c:96 src/exec_common.c:108 src/exec_common.c:115
+#: src/exec_pty.c:684 src/exec_pty.c:692 src/load_plugins.c:52
+#: src/load_plugins.c:65 src/load_plugins.c:208 src/load_plugins.c:231
+#: src/load_plugins.c:296 src/load_plugins.c:311 src/parse_args.c:180
+#: src/parse_args.c:202 src/parse_args.c:370 src/parse_args.c:466
+#: src/parse_args.c:485 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:291 src/selinux.c:414 src/sesh.c:102
+#: src/sudo.c:182 src/sudo.c:359 src/sudo.c:378 src/sudo.c:442 src/sudo.c:596
+#: src/sudo.c:615 src/sudo.c:642 src/sudo.c:651 src/sudo.c:660 src/sudo.c:677
+#: src/sudo.c:729 src/sudo.c:739 src/sudo.c:763 src/sudo.c:1146
+#: src/sudo.c:1148 src/sudo.c:1154 src/sudo.c:1162 src/sudo_edit.c:150
+#: src/sudo_edit.c:425 src/sudo_edit.c:522 src/sudo_edit.c:634
+#: src/sudo_edit.c:654
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:204 lib/util/gidlist.c:64 lib/util/sudo_conf.c:185
+#: lib/util/sudo_conf.c:265 lib/util/sudo_conf.c:342 lib/util/sudo_conf.c:544
+#: src/conversation.c:73 src/exec.c:864 src/exec_common.c:96
+#: src/exec_common.c:108 src/exec_common.c:115 src/exec_pty.c:684
+#: src/exec_pty.c:692 src/load_plugins.c:208 src/load_plugins.c:231
+#: src/load_plugins.c:296 src/load_plugins.c:311 src/parse_args.c:180
+#: src/parse_args.c:202 src/parse_args.c:370 src/parse_args.c:466
+#: src/parse_args.c:485 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:291 src/selinux.c:414 src/sesh.c:102
+#: src/sudo.c:182 src/sudo.c:359 src/sudo.c:378 src/sudo.c:442 src/sudo.c:763
+#: src/sudo.c:1146 src/sudo.c:1148 src/sudo.c:1154 src/sudo.c:1162
+#: src/sudo_edit.c:150 src/sudo_edit.c:425 src/sudo_edit.c:522
+#: src/sudo_edit.c:634 src/sudo_edit.c:654
+msgid "unable to allocate memory"
+msgstr "non foi posíbel asignar memoria"
+
+#: lib/util/strsignal.c:50
+msgid "Unknown signal"
+msgstr "Sinal descoñecido"
+
+#: lib/util/strtoid.c:76 lib/util/strtoid.c:104 lib/util/strtomode.c:48
+#: lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "valor non válido"
+
+#: lib/util/strtoid.c:83 lib/util/strtoid.c:111 lib/util/strtomode.c:54
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "valor demasiado grande"
+
+#: lib/util/strtoid.c:89 lib/util/strtomode.c:54 lib/util/strtonum.c:61
+#: lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "valor demasiado pequeno"
+
+#: lib/util/sudo_conf.c:198
+#, c-format
+msgid "invalid Path value `%s' in %s, line %u"
+msgstr ""
+
+#: lib/util/sudo_conf.c:364 lib/util/sudo_conf.c:417
+#, c-format
+msgid "invalid value for %s `%s' in %s, line %u"
+msgstr "valor non válido para %s `%s' en %s, liña %u"
+
+#: lib/util/sudo_conf.c:385
+#, c-format
+msgid "unsupported group source `%s' in %s, line %u"
+msgstr ""
+
+#: lib/util/sudo_conf.c:401
+#, c-format
+msgid "invalid max groups `%s' in %s, line %u"
+msgstr ""
+
+#: lib/util/sudo_conf.c:560
+#, c-format
+msgid "unable to stat %s"
+msgstr "non foi posíbel executar stat en %s"
+
+#: lib/util/sudo_conf.c:563
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s non é un ficheiro normal"
+
+#: lib/util/sudo_conf.c:566
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s é propiedade de uid %u, pero debería ser %u"
+
+#: lib/util/sudo_conf.c:570
+#, c-format
+msgid "%s is world writable"
+msgstr "%s é escribíbel por todo o mundo"
+
+#: lib/util/sudo_conf.c:573
+#, c-format
+msgid "%s is group writable"
+msgstr "%s é escribíbel polo grupo"
+
+#: lib/util/sudo_conf.c:583 src/selinux.c:199 src/selinux.c:212 src/sudo.c:328
+#, c-format
+msgid "unable to open %s"
+msgstr "non foi posíbel abrir %s"
+
+#: src/exec.c:114 src/exec.c:116 src/exec.c:121 src/exec.c:409 src/exec.c:411
+#: src/exec.c:413 src/exec.c:415 src/exec.c:417 src/exec.c:420 src/exec.c:437
+#: src/exec.c:439 src/exec.c:441 src/exec.c:596 src/exec.c:791
+#: src/exec_pty.c:466 src/exec_pty.c:722 src/exec_pty.c:792 src/exec_pty.c:794
+#: src/exec_pty.c:806 src/exec_pty.c:808 src/exec_pty.c:1285
+#: src/exec_pty.c:1287 src/exec_pty.c:1292 src/exec_pty.c:1294
+#: src/exec_pty.c:1308 src/exec_pty.c:1319 src/exec_pty.c:1321
+#: src/exec_pty.c:1323 src/exec_pty.c:1325 src/exec_pty.c:1327
+#: src/exec_pty.c:1329 src/exec_pty.c:1331 src/signal.c:147
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "non foi posíbel definir o manexador para o sinal %d"
+
+#: src/exec.c:126 src/exec_pty.c:838 src/exec_pty.c:1369 src/tgetpass.c:265
+msgid "unable to fork"
+msgstr "non é posíbel realizar fork"
+
+#: src/exec.c:304 src/exec.c:312 src/exec.c:869 src/exec_pty.c:604
+#: src/exec_pty.c:611 src/exec_pty.c:654 src/exec_pty.c:659 src/exec_pty.c:942
+#: src/exec_pty.c:952 src/exec_pty.c:997 src/exec_pty.c:1004
+#: src/exec_pty.c:1434 src/exec_pty.c:1441 src/exec_pty.c:1448
+msgid "unable to add event to queue"
+msgstr "non foi posíbel engadir o evento á cola"
+
+#: src/exec.c:392
+msgid "unable to create sockets"
+msgstr "non foi posíbel crear sockets"
+
+#: src/exec.c:448
+msgid "policy plugin failed session initialization"
+msgstr "produciuse un erro durante a inicialización de sesión do engadido de política"
+
+#: src/exec.c:493
+msgid "error in event loop"
+msgstr "erro no bucle de eventos"
+
+#: src/exec.c:511
+msgid "unable to restore tty label"
+msgstr "non foi posíbel restaurar a etiqueta tty"
+
+#: src/exec.c:604 src/exec_pty.c:498 src/signal.c:86
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "non foi posíbel restaurar o manexador para o sinal %d"
+
+#: src/exec.c:722 src/exec_pty.c:1176
+msgid "error reading from signal pipe"
+msgstr "produciuse un erro ao ler desde a tubería do sinal"
+
+#: src/exec_common.c:64
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "non foi posíbel retirar PRIV_PROC_EXEC desde PRIV_LIMIT"
+
+#: src/exec_pty.c:188
+msgid "unable to allocate pty"
+msgstr "non foi posíbel asignar pty"
+
+#: src/exec_pty.c:766 src/exec_pty.c:775 src/exec_pty.c:783
+#: src/exec_pty.c:1277 src/exec_pty.c:1366 src/signal.c:128 src/tgetpass.c:261
+msgid "unable to create pipe"
+msgstr "non foi psosíbel crear tubería"
+
+#: src/exec_pty.c:1209
+msgid "error reading from pipe"
+msgstr "produciuse un erro ao ler da tubería"
+
+#: src/exec_pty.c:1234
+msgid "error reading from socketpair"
+msgstr "produciuse un erro ao ler de socketpair"
+
+#: src/exec_pty.c:1243
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "tipo de resposta inesperada en canles alternos %d"
+
+#: src/exec_pty.c:1345
+msgid "unable to set controlling tty"
+msgstr "non foi posíebl estabelecer o controlador tty"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:80
+#: src/load_plugins.c:110 src/load_plugins.c:116 src/load_plugins.c:122
+#: src/load_plugins.c:163 src/load_plugins.c:171 src/load_plugins.c:178
+#: src/load_plugins.c:184
+#, c-format
+msgid "error in %s, line %d while loading plugin `%s'"
+msgstr "produciuse un erro en %s, liña %d ao cargar o engadido «%s»"
+
+#: src/load_plugins.c:82
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:118
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s debe ser propiedade do uid %d"
+
+#: src/load_plugins.c:124
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s só debe ter permisos de escritura polo propietario"
+
+#: src/load_plugins.c:165
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "non foi posíbel cargar %s: %s"
+
+#: src/load_plugins.c:173
+#, c-format
+msgid "unable to find symbol `%s' in %s"
+msgstr " non foi posíbel atopar o símbolo «%s» en %s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "tipo de política descoñecida %d atopado en %s"
+
+#: src/load_plugins.c:186
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "versión principal %d do engadido incompatíbel (agardábase %d) atopouse en %s"
+
+#: src/load_plugins.c:195
+#, c-format
+msgid "ignoring policy plugin `%s' in %s, line %d"
+msgstr ""
+
+#: src/load_plugins.c:197
+msgid "only a single policy plugin may be specified"
+msgstr "só se pode especificar unha política de engadido"
+
+#: src/load_plugins.c:200
+#, c-format
+msgid "ignoring duplicate policy plugin `%s' in %s, line %d"
+msgstr ""
+
+#: src/load_plugins.c:221
+#, c-format
+msgid "ignoring duplicate I/O plugin `%s' in %s, line %d"
+msgstr ""
+
+#: src/load_plugins.c:324
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "a política do engadido %s non inclúe un método check_policy"
+
+#: src/net_ifs.c:173 src/net_ifs.c:190 src/net_ifs.c:335 src/sudo.c:437
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "erro interno, desbordamento en %s"
+
+#: src/parse_args.c:239
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "o agumento -C debe ser un número maior ou igual a 3"
+
+#: src/parse_args.c:406
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "non se deben especificar as opcións «-i» e «-s» simultáneamente"
+
+#: src/parse_args.c:410
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "non se deben especificar as opcións «-i» e «-E» simultáneamente"
+
+#: src/parse_args.c:420
+msgid "the `-E' option is not valid in edit mode"
+msgstr "a opción «-E» non é válida no modo edición"
+
+#: src/parse_args.c:422
+msgid "you may not specify environment variables in edit mode"
+msgstr "non se deben especificar variábeis de ambiente no modo edición"
+
+#: src/parse_args.c:430
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "a opción «-U» só se pode usar coa opción «-l»"
+
+#: src/parse_args.c:434
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "as opcións «-A» e «-S» non se poden empregar conxuntamente"
+
+#: src/parse_args.c:504
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit non se admite nesta plataforma"
+
+#: src/parse_args.c:577
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Só pode especificar unha das opcións -e, -h, -i, -K, -l, -s, -v ou -V"
+
+#: src/parse_args.c:591
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - edita ficheiros como outro usuario\n"
+"\n"
+
+#: src/parse_args.c:593
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - executa unha orde como outro usuario\n"
+"\n"
+
+#: src/parse_args.c:598
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opcións:\n"
+
+#: src/parse_args.c:600
+msgid "use a helper program for password prompting"
+msgstr "usar un programa auxiliar para a solicitude de contrasinal"
+
+#: src/parse_args.c:603
+msgid "use specified BSD authentication type"
+msgstr "usar tipo de autenticación especificado en BSD"
+
+#: src/parse_args.c:606
+msgid "run command in the background"
+msgstr "executa unha orde en segundo plano"
+
+#: src/parse_args.c:608
+msgid "close all file descriptors >= num"
+msgstr "pecha todos os descritores de ficheiro >= num"
+
+#: src/parse_args.c:611
+msgid "run command with the specified BSD login class"
+msgstr "executa unha orde coa clase de inicio de sesión especificada"
+
+#: src/parse_args.c:614
+msgid "preserve user environment when running command"
+msgstr "conserva o ambiente de usuario ao executar unha orde"
+
+#: src/parse_args.c:616
+msgid "edit files instead of running a command"
+msgstr "edita ficheiros no lugar de executar unha orde"
+
+#: src/parse_args.c:618
+msgid "run command as the specified group name or ID"
+msgstr "executa unha orde como o nome ou ID de grupo especificado"
+
+#: src/parse_args.c:620
+msgid "set HOME variable to target user's home dir"
+msgstr "define a variábel HOME como o cartafol de inicio do usuario"
+
+#: src/parse_args.c:622
+msgid "display help message and exit"
+msgstr "mostra esta mensaxe de axuda e sae"
+
+#: src/parse_args.c:624
+msgid "run command on host (if supported by plugin)"
+msgstr ""
+
+#: src/parse_args.c:626
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "executar un intérprete de ordes de inicio como o usuario destino; tamén se pode especificar unha orde"
+
+#: src/parse_args.c:628
+msgid "remove timestamp file completely"
+msgstr "retira completamente un ficheiro de marca de tempo"
+
+#: src/parse_args.c:630
+msgid "invalidate timestamp file"
+msgstr "invalidar o ficheiro de marca de tempo"
+
+#: src/parse_args.c:632
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "listar os privilexios do usuario ou comprobar unha orde específica; usar dúas veces para un formato máis longo"
+
+#: src/parse_args.c:634
+msgid "non-interactive mode, no prompts are used"
+msgstr "modo non interactivo, non se preguntará ao usuario"
+
+#: src/parse_args.c:636
+#, fuzzy
+msgid "preserve group vector instead of setting to target's"
+msgstr "conserva o vector de grupos en vez de definilo ao obxectivo"
+
+#: src/parse_args.c:638
+msgid "use the specified password prompt"
+msgstr "usa o contrasinal especificado"
+
+#: src/parse_args.c:641
+msgid "create SELinux security context with specified role"
+msgstr "crea un contexto de seguranza SELinux co rol especificado"
+
+#: src/parse_args.c:644
+msgid "read password from standard input"
+msgstr "le o contrasinal desde a entrada estándar"
+
+#: src/parse_args.c:646
+msgid "run shell as the target user; a command may also be specified"
+msgstr "executar o intérprete de ordes como o usuario destino; tamén se pode especificar unha orde"
+
+#: src/parse_args.c:649
+msgid "create SELinux security context with specified type"
+msgstr "crea un contexto de seguranza SELinux co tipo especificado"
+
+#: src/parse_args.c:652
+msgid "in list mode, display privileges for user"
+msgstr "en modo lista, mostrar os privilexios do usuario"
+
+#: src/parse_args.c:654
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "executa unha orde (ou edita un ficheiro) como o nome ou ID de usuario especificado"
+
+#: src/parse_args.c:656
+msgid "display version information and exit"
+msgstr "mostra a información da versión e sae"
+
+#: src/parse_args.c:658
+msgid "update user's timestamp without running a command"
+msgstr "actualiza a marca de tempo do usuario sen executar ningunha orde"
+
+#: src/parse_args.c:660
+msgid "stop processing command line arguments"
+msgstr "detén o proceso de argumentos da liña de ordes"
+
+#: src/selinux.c:78
+msgid "unable to open audit system"
+msgstr "non foi posíbel abrir o sistema de auditoría"
+
+#: src/selinux.c:88
+msgid "unable to send audit message"
+msgstr "non foi posíbel enviar a mensaxe de auditoría"
+
+#: src/selinux.c:116
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "non foi posíbel executar fgetfilecon %s"
+
+#: src/selinux.c:121
+#, c-format
+msgid "%s changed labels"
+msgstr "%s etiquetas cambiadas"
+
+#: src/selinux.c:126
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "non foi posíbel restaurar o contexto para %s"
+
+#: src/selinux.c:166
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "non foi posíbel abrir %s, non volver a etiquetar tty"
+
+#: src/selinux.c:175
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "non foi posíbel obter o contexto actual de tty, non se volve etiquetar tty"
+
+#: src/selinux.c:182
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "non foi posíbel obter o novo contexto tty, non volver a etiquetar tty"
+
+#: src/selinux.c:189
+msgid "unable to set new tty context"
+msgstr "non foi posíbel estabelecer o novo contexto tty"
+
+#: src/selinux.c:255
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "débese especificar unha regra por tipo %s"
+
+#: src/selinux.c:261
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "non foi posíbel obter o tipo de regra predeterminada %s"
+
+#: src/selinux.c:279
+#, c-format
+msgid "failed to set new role %s"
+msgstr "produciuse un erro ao definir a nova regra %s"
+
+#: src/selinux.c:283
+#, c-format
+msgid "failed to set new type %s"
+msgstr "produciuse un erro ao definir o novo tipo %s"
+
+#: src/selinux.c:295
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s non é un contexto válido"
+
+#: src/selinux.c:330
+msgid "failed to get old_context"
+msgstr "produciuse un erro ao obter old_context"
+
+#: src/selinux.c:336
+msgid "unable to determine enforcing mode."
+msgstr "non foi posíbel determinar o método de forzado"
+
+#: src/selinux.c:353
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "non foi posíbel definir o contexto tty para %s"
+
+#: src/selinux.c:392
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "non foi posíbel o contexto de execución a %s"
+
+#: src/selinux.c:399
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "non foi posíbel estabelecer a chave de creación de contexto a %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "require cando menos un argumento"
+
+#: src/sesh.c:107
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "non foi posíbel executar %s como shell de inicio de sesión"
+
+#: src/sesh.c:112 src/sudo.c:1217
+#, c-format
+msgid "unable to execute %s"
+msgstr "non é posíbel executar %s"
+
+#: src/signal.c:68
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "non foi posíbel gardar o manexador para o sinal %d"
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "acadouse o límite de control de recursos"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "o usuario «%s» non é membro do grupo «%s»"
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr "a tarefa que invoca é definitiva"
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "non é posíbel unirse ao proxecto «%s»"
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "non hai fondo de recursos aceptando as asignacións existentes par ao proxecto «%s»"
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "o fondo de recursos especificado non existe para o proxecto «%s»"
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "non é posíbel ligar ao fondo de recursos predeterminado para o proxecto «%s»"
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "configuración do proxecto fallada «%s»"
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "aviso, o control de asignación de recuros fallou para o proxecto «%s»"
+
+#: src/sudo.c:193
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo versión %s\n"
+
+#: src/sudo.c:195
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Opcións de configuración: %s\n"
+
+#: src/sudo.c:203
+msgid "fatal error, unable to load plugins"
+msgstr "erro fatal, non foi posíbel cargar os engadidos"
+
+#: src/sudo.c:211
+msgid "unable to initialize policy plugin"
+msgstr "non foi posíbel inicializar a normativa do engadido"
+
+#: src/sudo.c:267
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "erro ao inicializar os engadidos de E/S %s"
+
+#: src/sudo.c:293
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "modo sudo 0x%x non agardado"
+
+#: src/sudo.c:422
+msgid "unable to get group vector"
+msgstr "non é posíbel obter o vector de grupo"
+
+#: src/sudo.c:485
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "uid descoñecido %u: quen é vostede?"
+
+#: src/sudo.c:812
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s debe ser propiedade do uid %d e debe ter definido o bit setuid"
+
+#: src/sudo.c:815
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "o uid efectivo non é %d, é %s nun sistema de ficheiros coa opción «nosuid» definida ou nun sistema de ficheiros NFS sen privilexios de root?"
+
+#: src/sudo.c:821
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "o uid efectivo non é %d, está sudo instalado con setuid de root?"
+
+#: src/sudo.c:952
+#, c-format
+msgid "unknown login class %s"
+msgstr "clase de inicio de sesión descoñecida %s"
+
+#: src/sudo.c:965
+msgid "unable to set user context"
+msgstr "non foi posíbel estabelecer o contexto do usuario"
+
+#: src/sudo.c:979
+msgid "unable to set supplementary group IDs"
+msgstr "non foi posíbel estabelecer o grupo suplementario de IDs"
+
+#: src/sudo.c:986
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "non foi posíbel estabelcer o gid efectivo para executar como gid %u"
+
+#: src/sudo.c:992
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "non foi posíbel estabelcer o gid para executar como gid %u"
+
+#: src/sudo.c:999
+msgid "unable to set process priority"
+msgstr "non foi posíbel estabelecer a prioridade de proceso"
+
+#: src/sudo.c:1007
+#, c-format
+msgid "unable to change root to %s"
+msgstr "non foi posíbel cambiar de root a %s"
+
+#: src/sudo.c:1020 src/sudo.c:1026 src/sudo.c:1033
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "non foi posíbel cambiar as runas uid (%u, %u)"
+
+#: src/sudo.c:1051
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "non foi posíbel cambiar ao cartafol %s"
+
+#: src/sudo.c:1112
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "terminación de condición filla non agardada: %d"
+
+#: src/sudo.c:1245
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "a política do engadido %s non inclúe ningún método «check_policy»"
+
+#: src/sudo.c:1263
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "a política do engadido %s non admite listar os privilexios"
+
+#: src/sudo.c:1280
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "a política do engadido %s non admite a opción -v"
+
+#: src/sudo.c:1295
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "a normativa do engadido %s non admite as opcións -k/-K"
+
+#: src/sudo_edit.c:238 src/sudo_edit.c:339
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: non é un ficheiro regular"
+
+#: src/sudo_edit.c:245
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: a edición de ligazóns simbólicas non está permitida"
+
+#: src/sudo_edit.c:276 src/sudo_edit.c:378
+#, c-format
+msgid "%s: short write"
+msgstr "%s: escritura curta"
+
+#: src/sudo_edit.c:340
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s sen modificar"
+
+#: src/sudo_edit.c:353 src/sudo_edit.c:539
+#, c-format
+msgid "%s unchanged"
+msgstr "%s sen cambios"
+
+#: src/sudo_edit.c:367 src/sudo_edit.c:389
+#, c-format
+msgid "unable to write to %s"
+msgstr "non foi posíbel escribir en %s"
+
+#: src/sudo_edit.c:368 src/sudo_edit.c:387 src/sudo_edit.c:390
+#: src/sudo_edit.c:564 src/sudo_edit.c:568
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "os contidos de edición de sesión déixanse en %s"
+
+#: src/sudo_edit.c:386
+msgid "unable to read temporary file"
+msgstr "non é posíbel ler o ficheiro temporal"
+
+#: src/sudo_edit.c:469
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: erro interno: número impar de rutas"
+
+#: src/sudo_edit.c:471
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: non é posíbel crear ficheiros temporais"
+
+#: src/sudo_edit.c:473 src/sudo_edit.c:571
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: erro descoñecido %d"
+
+#: src/sudo_edit.c:563
+msgid "unable to copy temporary files back to their original location"
+msgstr "non foi posíbel copiar os ficheiros temporais de volta á súa localización orixinal"
+
+#: src/sudo_edit.c:567
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "non foi posíbel copiar algúns ficheiros temporais de volta á súa localización orixinal"
+
+#: src/sudo_edit.c:610
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "non foi posíbel cambiar uid a root (%u)"
+
+#: src/sudo_edit.c:627
+msgid "plugin error: missing file list for sudoedit"
+msgstr "erro do engadido: falta a lista de ficheiros para sudoedit"
+
+#: src/sudo_edit.c:668 src/sudo_edit.c:681
+msgid "unable to read the clock"
+msgstr "non foi posíbel ler o reloxo"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr "sen tty presente e non se especificou un programa askpass"
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "non hai programa askpass especificado, tente estabelecer SUDO_ASKPASS"
+
+#: src/tgetpass.c:276
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "non foi posíbel estabelecer o gid a %u"
+
+#: src/tgetpass.c:280
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "non foi posíbel estabelecer o uid a %u"
+
+#: src/tgetpass.c:285
+#, c-format
+msgid "unable to run %s"
+msgstr "non foi posíbel executar %s"
+
+#: src/utmp.c:266
+msgid "unable to save stdin"
+msgstr "non foi posíbel gardar stdin"
+
+#: src/utmp.c:268
+msgid "unable to dup2 stdin"
+msgstr "non foi posíbel facer dup2 stdin"
+
+#: src/utmp.c:271
+msgid "unable to restore stdin"
+msgstr "non foi posíbel restaurar stdin"
+
+#~ msgid "internal error, tried to emalloc(0)"
+#~ msgstr "erro interno: tentou emalloc(0)"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "erro interno: tentou emalloc2(0)"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "erro interno, tentou ecalloc(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "erro interno, tentou erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "erro interno, tentou erealloc3(0)"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "erro interno, tentou erealloc(0)"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "non foi posíbel estabelcer a terminal en modo directo"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: desbordamento detectado"
+
+#~ msgid "unable to open socket"
+#~ msgstr "non foi posíbel abrir o socket"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "select failed"
+#~ msgstr "selección fallada"
+
+#~ msgid "list user's available commands\n"
+#~ msgstr "lista de ordes do usuario dispoñíbeis\n"
+
+#~ msgid "run a shell as target user\n"
+#~ msgstr "executa un intérprete de ordes como un determinado usuario\n"
+
+#~ msgid "when listing, list specified user's privileges\n"
+#~ msgstr "cando está na lista, mostra os privilexios do usuario especificado\n"
+
+#~ msgid "%s: at least one policy plugin must be specified"
+#~ msgstr "%s: debe ser especificada cando menos unha política de engadido"
+
+#~ msgid "must be setuid root"
+#~ msgstr "debe ser setuid root"
+
+#~ msgid "internal error, erealloc3() overflow"
+#~ msgstr "erro interno: desbordamento de erealloc3(0)"
diff --git a/po/hr.mo b/po/hr.mo
new file mode 100644
index 0000000..1eb7d30
--- /dev/null
+++ b/po/hr.mo
Binary files differ
diff --git a/po/hr.po b/po/hr.po
new file mode 100644
index 0000000..f6cf50f
--- /dev/null
+++ b/po/hr.po
@@ -0,0 +1,1001 @@
+# Translation of sudo to Croatian.
+# This file is put in the public domain.
+# Tomislav Krznar <tomislav.krznar@gmail.com>, 2012, 2013.
+# Božidar Putanec <bozidarp@yahoo.com>, 2016, 2017, 2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo-1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-30 12:53-0700\n"
+"Last-Translator: Božidar Putanec <bozidarp@yahoo.com>\n"
+"Language-Team: Croatian <lokalizacija@linux.hr>\n"
+"Language: hr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Generator: Poedit 2.2\n"
+"X-Poedit-Basepath: sources/sudo-1.8.26b1\n"
+"X-Poedit-SearchPath-0: .\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "nije moguće otvoriti userdb (korisnička baza podataka)"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "nije moguće prebaciti se u registar „%s“ za %s"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "nije moguće obnoviti registar"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "nije moguće dodijeliti memoriju"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "Nepoznati signal"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "nevaljana vrijednost"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "veličina je prevelika"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "veličina je premala"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "nevaljana Path vrijednost „%s“ u %s, redak %u"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "nevaljana vrijednost za %s „%s“ u %s, redak %u"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "nepodržani izvor grupe „%s“ u %s, redak %u"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "nevaljani maksimalni broj grupa „%s“ u %s, redak %u"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "nije moguće dobiti status od %s"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s nije obična datoteka"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "vlasnik %s je UID %u, a trebao bi biti %u"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "%s može svatko mijenjati/pisati"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "%s može svaki član grupe mijenjati/pisati"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "nije moguće otvoriti %s"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "nepoznata prijavnička klasa %s"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "nije moguće uspostaviti korisnički kontekst"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "nije moguće uspostaviti prioritet procesa"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "nije moguće promijeniti root na %s"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "nije moguće promijeniti na runas UID (%u, %u)"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "nije moguće promijeniti direktorij na %s"
+
+# Handler, an asynchronous callback (computer programming) subroutine in computing
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "nije moguće postaviti rukovatelja za signal %d"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "nije moguće ukloniti PRIV_PROC_EXEC iz PRIV_LIMIT"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "greška čitanja iz para utičnica"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "neočekivana vrsta odgovora na povratnom kanalu: %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "nije moguće dodati događaj u red čekanja"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "nije moguće uspostaviti upravljački TTY"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "nije moguće napraviti cijev"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "nije moguće primiti poruku od pretka (roditelja)"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "nije moguće kreirati potomka (dijete)"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "nije moguće izvršiti %s"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "nije moguće obnoviti TTY etiketu"
+
+# initialization > inicirati > dati/davati inicijativu, pobudu; pokrenuti/pokretati, započeti/započinjati
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "plugin s pravilima nije uspio pokrenuti inicijalizaciju sesije"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "greška u petlji događaja"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "nije moguće obnoviti rukovatelja za signal %d"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "nije moguće dodijeliti PTY"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "nije moguće napraviti utičnice"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "nije moguće poslati poruku za praćenje procesa"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "greška u %s, redak %d pri učitavanju plugina „%s“"
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "vlasnik %s mora biti UID %d"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s za pisanje mora biti dostupan samo vlasniku"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "nije moguće učitati %s: %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "nije moguće pronaći simbol „%s“ u %s"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "nepoznata vrsta pravila %d pronađena u %s"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "nekompatibilni plugin inačica %d (očekivana %d) pronađen u %s"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "ignorira se plugin s pravilima „%s“ u %s, redak %d"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "smije se navesti samo jedan plugin s pravilima"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "ignorira se duplikat plugina s pravilima „%s“ u %s, redak %d"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "ignorira se duplikat U/I plugina „%s“ u %s, redak %d"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "plugin s pravilima %s ne sadrži metodu check_policy"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "**interna greška**, %s prelijevanje"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "nevaljano ime varijable okoline: %s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "argument za -C mora biti broj veći ili jednak 3"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "ne smijete navesti opcije „-i“ i „-s“ zajedno"
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "ne smijete navesti opcije „-i“ i -„E“ zajedno"
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "opcija „-E“ nije valjana kad se redigira (in edit mode)"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "ne smijete specificirati varijable okoline kad se redigira (in edit mode)"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "opciju „-U“ može se koristiti samo s „-l“ opcijom"
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "ne smiju se zajedno koristiti „-A“ i „-S“ opcije"
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit nije podržan na ovoj platformi"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Smije se navesti samo jedna od opcija -e, -h, -i, -K, -l, -s, -v i -V"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - redigira datoteku kao neki drugi korisnik\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - izvrši naredbu kao neki drugi korisnik\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opcije:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "zahtjev za lozinku koristi pomoćni program"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "rabi navedenu BSD autentifikaciju"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "pokrene naredbu u pozadini"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "zatvara sve deskriptore datoteka >= num"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "pokrene naredbu s navedenom BSD klasom prijave"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "sačuva okolinu korisnika pri izvršenju naredbe"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "sačuva specifične varijable okoline"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "redigira datoteke umjesto pokretanja naredbe"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "izvrši naredbu kao navedeno group ime ili ID"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "var HOME postavi na osobni direktorij korisnika"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "pokaže ovu pomoć i iziđe"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "pokrene naredbu na host računalu (ako to plugin podržava)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "pokrene prijavnu ljusku kao ciljani korisnik; može se navesti i naredba"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "sasvim ukloni datoteku s vremenskim oznakama"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "poništi datoteku s vremenskim oznakama"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "privilegije korisnika ili test specifične naredbe; rabite -ll za duži popis"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "ne-interaktivni mȏd; bez prompta"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "sačuva grupni vektor umjesto postavljanja na ciljanu grupu"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "koristi navedeni prompt za unos lozinke"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "stvori SELinux sigurnosni kontekst s navedenom role ulogom"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "čita lozinku iz standardnog ulaza"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "pokrene ljusku kao ciljani korisnik; može se navesti i naredba"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "stvori SELinux sigurnosni kontekst s navedenom type ulogom"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "naredba završi nakon navedenoga timeout vremena"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "izlista popis privilegija user korisnika"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "pokreni naredbu (ili redigira datoteku) kao navedeni user korisnik"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "informira o inačici ovog programa i iziđe"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "obnovi vremensku oznaku korisnika bez pokretanja naredbe"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "prestane s obradom argumenata na naredbenom retku"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "nije moguće otvoriti revizijski sustav"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "nije moguće poslati revizijsku poruku"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "neuspješna fgetfilecon() %s"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s je promijenio etikete"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "nije moguće obnoviti kontekst za %s"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "nije moguće otvoriti %s, oznaka TTY se ne mijenja"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s nije znakovni uređaj (c-device), oznaka TTY se me mijenja"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "nije moguće dobiti trenutačni TTY kontekst, oznaka TTY se me mijenja"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "nepoznata sigurnosna klasa „chr_file“, oznaka TTY se me mijenja"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "nije moguće dobiti novi TTY kontekst, oznaka TTY se me mijenja"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "nije moguće uspostaviti novi TTY kontekst"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "morate navesti ulogu za vrstu %s"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "nije moguće dobiti zadanu vrstu za ulogu %s"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "nije uspjelo postaviti novu ulogu %s"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "nije uspjelo postaviti novu vrstu %s"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s nije valjani kontekst"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "nije uspjelo dobiti old_context"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "nije moguće odrediti način provedbe."
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "nije moguće postaviti TTY kontekst za %s"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "nije moguće postaviti exec kontekst na %s"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "nije moguće postaviti kontekst stvaranja ključa na %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "zahtijeva barem jedan argument"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "nevaljani broj deskriptora datoteke: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "nije moguće pokrenuti %s kao prijavnu ljusku"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "nije moguće sačuvati rukovatelja za signal %d"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "dosegnuta je granica upravljanja resursima"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "korisnik „%s“ nije član projekta „%s“"
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "pozvani zadatak je zadnji -- svršetak"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "nije bilo moguće pridružiti se projektu „%s“"
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "ne postoji skup resursa koji prihvaća zadane poveznice za projekt „%s“"
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "ne postoji navedeni skup resursa za projekt „%s“"
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "nije bilo moguće povezati se na zadani skup resursa za projekt „%s“"
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "neuspješna setproject() za projekt „%s“"
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "upozorenje: nije uspjelo dodijeliti upravljanje resursima projekta „%s“"
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo inačica %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Konfiguracijske opcije: %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "kobna greška, nije moguće učitati plugine"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "nije moguće inicijalizirati plugin s pravilima"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "plugin nije uzvratio naredbu za izvršiti"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "greška pri inicijalizaciji U/I plugina %s"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "neočekivani sudo mȏd 0x%x"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "vas nema u %s bazi podataka"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "nije moguće odrediti TTY"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "vlasnik %s mora biti UID %d i mora imati postavljeni setuid bit"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "efektivni UID nije %d; je li %s na datotečnom sustavu s postavljenom opcijom „nosuid“ ili NFS datotečnom sustavu bez root privilegija?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "efektivni UID nije %d; je li sudo instaliran sa setuid root?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "nije moguće postaviti ID dodatnih grupa"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "nije moguće postaviti efektivni GID na runas GID %u"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "nije moguće postaviti GID na runas GID %u"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "neočekivano stanje završetka potomka (dijete-procesa) : %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "plugin s pravilima %s nema metodu „check_policy“"
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "plugin s pravilima %s ne podržava ispis ovlasti"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "plugin s pravilima %s ne podržava opciju -v"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "plugin s pravilima %s ne podržava -k/-K opcije"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "nije pronađen privremeni direktorij u koji je moguće pisati"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "nije moguće obnoviti trenutačni radni direktorij"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: nije obična datoteka"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: simboličke veze nije dopušteno redigirati"
+
+# writable> zapisiv, upisiv, u kojem je dopušteno pisati
+# http://hjp.znanje.hr/ > upisiv > koji se može upisati, koji ispunjava uvjete upisa
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: datoteke nije dopušteno redigirati u direktoriju koji dopušta pisanje"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s: nepotpuni zapis"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s nije izmijenjeno"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "%s nije promijenjeno"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "nije moguće pisati u %s"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "sadržaj sesije redigiranja je ostavljen u %s"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "nije moguće čitati privremenu datoteku"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: interna greška: neparni broj staza"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: nije moguće čitati privremenu datoteku"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: nepoznata greška: %d"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "nije moguće kopirati privremene datoteke u njihovu originalnu lokaciju"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "nije moguće kopirati neke od privremenih datoteka u njihovu originalnu lokaciju"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "nije moguće promijeniti UID na root (%u)"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "greška plugina: nedostaje popis datoteka za sudoedit"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "nije moguće očitati vrijeme (clock)"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "vrijeme za čitanje lozinke je isteklo"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "nema lozinke (nije unesena)"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "nije moguće pročitati lozinku"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "nema TTY i nije specificiran askpass program"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "nije specificiran askpass program, pokušajte postaviti SUDO_ASKPASS"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "nije moguće postaviti GID na %u"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "nije moguće postaviti UID na %u"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "nije moguće pokrenuti %s"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "nije moguće sačuvati stdin"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "dup2 nije moguće primijeniti na stdin"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "nije moguće obnoviti stdin"
+
+#~ msgid "unable to get group vector"
+#~ msgstr "nije moguće dobiti grupni vektor"
+
+#~ msgid "unknown uid %u: who are you?"
+#~ msgstr "nepoznat UID %u: tko ste vi?"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "greška čitanja iz signalne cijevi"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "greška čitanja iz cjevovoda"
+
+#~ msgid "internal error, tried to emalloc(0)"
+#~ msgstr "interna greška, pokušao sam emalloc(0)"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "interna greška, pokušao sam emalloc2(0)"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "interna greška, pokušao sam ecalloc(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "interna greška, pokušao sam erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "interna greška, pokušao sam erealloc3(0)"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "interna greška, pokušao sam erecalloc(0)"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "select failed"
+#~ msgstr "odabir nije uspio"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "ne mogu postaviti terminal u sirovi način"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: otkriven preljev"
+
+#~ msgid "unable to open socket"
+#~ msgstr "ne mogu otvoriti utičnicu"
+
+#~ msgid "list user's available commands\n"
+#~ msgstr "ispiši dostupne korisničke naredbe\n"
+
+#~ msgid "run a shell as target user\n"
+#~ msgstr "pokreni ljusku kao odredišni korisnik\n"
+
+#~ msgid "when listing, list specified user's privileges\n"
+#~ msgstr "pri ispisu, ispiši navedene korisničke ovlasti\n"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "internal error, emalloc2() overflow"
+#~ msgstr "interna greška, emalloc2() preljev"
+
+#~ msgid "internal error, erealloc3() overflow"
+#~ msgstr "interna greška, erealloc3() preljev"
+
+#~ msgid "%s: at least one policy plugin must be specified"
+#~ msgstr "%s: mora biti naveden barem jedan priključak police"
diff --git a/po/hu.mo b/po/hu.mo
new file mode 100644
index 0000000..2553155
--- /dev/null
+++ b/po/hu.mo
Binary files differ
diff --git a/po/hu.po b/po/hu.po
new file mode 100644
index 0000000..4a66835
--- /dev/null
+++ b/po/hu.po
@@ -0,0 +1,883 @@
+# Hungarian translation for sudo.
+# Copyright (C) 2016, 2017, 2018 Free Software Foundation, Inc.
+# This file is distributed under the same license as the sudo package.
+#
+# Gabor Kelemen <kelemeng@gnome.hu>, 2016.
+# Balázs Úr <urbalazs@gmail.com>, 2017, 2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.21b2\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2017-08-03 10:04-0600\n"
+"PO-Revision-Date: 2018-01-20 13:53+0100\n"
+"Last-Translator: Balázs Úr <urbalazs@gmail.com>\n"
+"Language-Team: Hungarian <translation-team-hu@lists.sourceforge.net>\n"
+"Language: hu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2016-01-03 00:40+0000\n"
+"X-Generator: Lokalize 1.2\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:172
+msgid "unable to open userdb"
+msgstr "userdb megnyitása sikertelen"
+
+#: lib/util/aix.c:227
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "a(z) „%s” regisztrációs adatbázisra váltás sikertelen ennél: %s"
+
+#: lib/util/aix.c:252
+msgid "unable to restore registry"
+msgstr "a rendszerleíró visszaállítása sikertelen"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:186 lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349
+#: lib/util/sudo_conf.c:553 src/conversation.c:75 src/exec_common.c:107
+#: src/exec_common.c:123 src/exec_common.c:132 src/exec_monitor.c:167
+#: src/exec_nopty.c:462 src/exec_pty.c:667 src/exec_pty.c:676
+#: src/exec_pty.c:738 src/exec_pty.c:867 src/load_plugins.c:52
+#: src/load_plugins.c:65 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:198 src/parse_args.c:273 src/parse_args.c:540
+#: src/parse_args.c:562 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:115 src/sudo.c:389 src/sudo.c:416 src/sudo.c:481 src/sudo.c:603
+#: src/sudo.c:663 src/sudo.c:673 src/sudo.c:693 src/sudo.c:712 src/sudo.c:721
+#: src/sudo.c:730 src/sudo.c:747 src/sudo.c:788 src/sudo.c:798 src/sudo.c:818
+#: src/sudo.c:1058 src/sudo.c:1079 src/sudo.c:1253 src/sudo.c:1351
+#: src/sudo_edit.c:148 src/sudo_edit.c:771 src/sudo_edit.c:868
+#: src/sudo_edit.c:982 src/sudo_edit.c:1002
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/sudo_conf.c:187
+#: lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349 lib/util/sudo_conf.c:553
+#: src/conversation.c:76 src/exec_common.c:107 src/exec_common.c:124
+#: src/exec_common.c:133 src/exec_pty.c:667 src/exec_pty.c:676
+#: src/exec_pty.c:738 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:199 src/parse_args.c:273 src/parse_args.c:540
+#: src/parse_args.c:562 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:115 src/sudo.c:389 src/sudo.c:416 src/sudo.c:481 src/sudo.c:603
+#: src/sudo.c:818 src/sudo.c:1058 src/sudo.c:1079 src/sudo.c:1253
+#: src/sudo.c:1351 src/sudo_edit.c:148 src/sudo_edit.c:771 src/sudo_edit.c:868
+#: src/sudo_edit.c:982 src/sudo_edit.c:1002
+msgid "unable to allocate memory"
+msgstr "a memóriafoglalás sikertelen"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "Ismeretlen szignál"
+
+#: lib/util/strtoid.c:77 lib/util/strtoid.c:124 lib/util/strtoid.c:152
+#: lib/util/strtomode.c:49 lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "érvénytelen érték"
+
+#: lib/util/strtoid.c:84 lib/util/strtoid.c:131 lib/util/strtoid.c:159
+#: lib/util/strtomode.c:55 lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "túl magas érték"
+
+#: lib/util/strtoid.c:86 lib/util/strtoid.c:137 lib/util/strtomode.c:55
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "túl alacsony érték"
+
+#: lib/util/sudo_conf.c:205
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "érvénytelen „%s” útvonal érték a(z) %s, %u. sorában"
+
+#: lib/util/sudo_conf.c:371 lib/util/sudo_conf.c:424
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "a(z) %s értéke („%s”) érvénytelen a(z) %s, %u. sorában"
+
+#: lib/util/sudo_conf.c:392
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "nem támogatott „%s” csoportforrás a(z) %s, %u. sorában"
+
+#: lib/util/sudo_conf.c:408
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "érvénytelen legnagyobb csoportok („%s”) a(z) %s, %u. sorában"
+
+#: lib/util/sudo_conf.c:569
+#, c-format
+msgid "unable to stat %s"
+msgstr "%s nem érhető el"
+
+#: lib/util/sudo_conf.c:572
+#, c-format
+msgid "%s is not a regular file"
+msgstr "a(z) %s nem szabályos fájl"
+
+#: lib/util/sudo_conf.c:575
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s a(z) %u uid tulajdona, ennek kellene lennie: %u"
+
+#: lib/util/sudo_conf.c:579
+#, c-format
+msgid "%s is world writable"
+msgstr "%s bárki számára írható"
+
+#: lib/util/sudo_conf.c:582
+#, c-format
+msgid "%s is group writable"
+msgstr "%s a csoport számára írható"
+
+#: lib/util/sudo_conf.c:592 src/selinux.c:208 src/selinux.c:225 src/sudo.c:357
+#, c-format
+msgid "unable to open %s"
+msgstr "%s nem nyitható meg"
+
+#: src/exec.c:160
+#, c-format
+msgid "unknown login class %s"
+msgstr "ismeretlen %s logikai osztály"
+
+#: src/exec.c:173
+msgid "unable to set user context"
+msgstr "a felhasználói környezet beállítása sikertelen"
+
+#: src/exec.c:189
+msgid "unable to set process priority"
+msgstr "a folyamat prioritásának beállítása sikertelen"
+
+#: src/exec.c:197
+#, c-format
+msgid "unable to change root to %s"
+msgstr "a gyökér megváltoztatása sikertelen erre: %s"
+
+#: src/exec.c:210 src/exec.c:216 src/exec.c:223
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "a runas uid értékre (%u, %u) váltás sikertelen"
+
+#: src/exec.c:241
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "a könyvtárváltás sikertelen erre: %s"
+
+#: src/exec.c:337 src/exec_monitor.c:526 src/exec_monitor.c:528
+#: src/exec_nopty.c:520 src/exec_pty.c:472 src/exec_pty.c:1184
+#: src/exec_pty.c:1186 src/signal.c:139 src/signal.c:153
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "%d szignál kezelőjének beállítása sikertelen"
+
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "a PRIV_PROC_EXEC eltávolítása sikertelen a PRIV_LIMIT-ből"
+
+#: src/exec_monitor.c:326
+msgid "error reading from socketpair"
+msgstr "hiba a foglalatpárból való olvasáskor"
+
+#: src/exec_monitor.c:338
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "váratlan választípus a visszcsatornán: %d"
+
+#: src/exec_monitor.c:423 src/exec_monitor.c:431 src/exec_monitor.c:439
+#: src/exec_monitor.c:446 src/exec_monitor.c:453 src/exec_monitor.c:460
+#: src/exec_monitor.c:467 src/exec_monitor.c:474 src/exec_monitor.c:481
+#: src/exec_monitor.c:488 src/exec_nopty.c:215 src/exec_nopty.c:224
+#: src/exec_nopty.c:231 src/exec_nopty.c:238 src/exec_nopty.c:245
+#: src/exec_nopty.c:252 src/exec_nopty.c:259 src/exec_nopty.c:266
+#: src/exec_nopty.c:273 src/exec_nopty.c:280 src/exec_nopty.c:287
+#: src/exec_nopty.c:294 src/exec_nopty.c:302 src/exec_pty.c:563
+#: src/exec_pty.c:568 src/exec_pty.c:635 src/exec_pty.c:642 src/exec_pty.c:743
+#: src/exec_pty.c:1029 src/exec_pty.c:1038 src/exec_pty.c:1045
+#: src/exec_pty.c:1052 src/exec_pty.c:1059 src/exec_pty.c:1066
+#: src/exec_pty.c:1073 src/exec_pty.c:1080 src/exec_pty.c:1087
+#: src/exec_pty.c:1094 src/exec_pty.c:1101 src/exec_pty.c:1446
+#: src/exec_pty.c:1456 src/exec_pty.c:1501 src/exec_pty.c:1508
+#: src/exec_pty.c:1533
+msgid "unable to add event to queue"
+msgstr "az esemény hozzáadása a sorhoz sikertelen"
+
+#: src/exec_monitor.c:540
+msgid "unable to set controlling tty"
+msgstr "a vezérlő tty beállítása sikertelen"
+
+#: src/exec_monitor.c:548 src/exec_nopty.c:359 src/exec_pty.c:1261
+#: src/exec_pty.c:1280 src/exec_pty.c:1298 src/tgetpass.c:246
+msgid "unable to create pipe"
+msgstr "adatcsatorna létrehozása sikertelen"
+
+#: src/exec_monitor.c:553 src/exec_nopty.c:377 src/exec_pty.c:1335
+#: src/tgetpass.c:250
+msgid "unable to fork"
+msgstr "az elágaztatás sikertelen"
+
+#: src/exec_monitor.c:639 src/exec_nopty.c:430
+msgid "unable to restore tty label"
+msgstr "a tty címke visszaállítása sikertelen"
+
+#: src/exec_nopty.c:353 src/exec_pty.c:1193
+msgid "policy plugin failed session initialization"
+msgstr "a házirendbővítménynek nem sikerült a munkamenet előkészítése"
+
+#: src/exec_nopty.c:419 src/exec_pty.c:1404
+msgid "error in event loop"
+msgstr "hiba az eseményhurokban"
+
+#: src/exec_nopty.c:528 src/exec_pty.c:504 src/signal.c:101
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "%d szignál kezelőjének visszaállítása sikertelen"
+
+#: src/exec_pty.c:143
+msgid "unable to allocate pty"
+msgstr "a pty lefoglalása sikertelen"
+
+#: src/exec_pty.c:1173
+msgid "unable to create sockets"
+msgstr "a foglalatok létrehozása sikertelen"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "hiba a(z) %s, %d. sorában a(z) „%s” bővítmény betöltése közben"
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s a(z) %d uid tulajdona kell legyen"
+
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s csak a tulajdonos által írható lehet"
+
+#: src/load_plugins.c:172
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "a(z) %s nem tölthető be: %s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "a(z) „%s” szimbólum nem található ebben: %s"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "ismeretlen %d házirendtípus található ebben: %s"
+
+#: src/load_plugins.c:193
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "összeférhetetlen %d bővítmény főverzió (várt: %d) található ebben: %s"
+
+#: src/load_plugins.c:202
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "a(z) „%s” házirendbővítmény mellőzése a(z) %s, %d. sorában"
+
+#: src/load_plugins.c:204
+msgid "only a single policy plugin may be specified"
+msgstr "csak egyetlen házirendbővítmény határozható meg"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "kettőzött „%s” házirendbővítmény mellőzése a(z) %s, %d. sorában"
+
+#: src/load_plugins.c:228
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "kettőzött „%s” I/O bővítmény mellőzése a(z) %s, %d. sorában"
+
+#: src/load_plugins.c:331
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "a(z) %s házirendbővítmény nem tartalmazza a „check_policy” metódust"
+
+#: src/net_ifs.c:173 src/net_ifs.c:190 src/net_ifs.c:335 src/sudo.c:476
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "belső hiba, %s túlcsordul"
+
+#: src/parse_args.c:219
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "érvénytelen környezeti változó név: %s"
+
+#: src/parse_args.c:313
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "a -C kapcsoló argumentuma legyen 3, vagy ennél nagyobb szám"
+
+#: src/parse_args.c:480
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "az „-i” és „-s” kapcsoló egyszerre nem használható"
+
+#: src/parse_args.c:484
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "az „-i” és „-E” kapcsoló egyszerre nem használható"
+
+#: src/parse_args.c:494
+msgid "the `-E' option is not valid in edit mode"
+msgstr "az „-E” kapcsoló nem használható szerkesztő módban"
+
+#: src/parse_args.c:496
+msgid "you may not specify environment variables in edit mode"
+msgstr "nem használhat környezeti változókat szerkesztő módban"
+
+#: src/parse_args.c:504
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "az „-U” kapcsoló csak a „-l” kapcsolóval együtt használható"
+
+#: src/parse_args.c:508
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "az „-A” és „-S” kapcsoló együtt nem használható"
+
+#: src/parse_args.c:584
+msgid "sudoedit is not supported on this platform"
+msgstr "a „sudoedit” nem támogatott ezen a rendszeren"
+
+#: src/parse_args.c:657
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Kizárólag az -e, -h, -i, -K, -l, -s, -v vagy -V kapcsolók egyike használható"
+
+#: src/parse_args.c:671
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - fájlok szerkesztése más felhasználóként\n"
+"\n"
+
+#: src/parse_args.c:673
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - parancs végrehajtása más felhasználóként\n"
+"\n"
+
+#: src/parse_args.c:678
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Kapcsolók:\n"
+
+#: src/parse_args.c:680
+msgid "use a helper program for password prompting"
+msgstr "segédprogram használata a jelszóbekérésre"
+
+#: src/parse_args.c:683
+msgid "use specified BSD authentication type"
+msgstr "megadott BSD hitelesítési típus használata"
+
+#: src/parse_args.c:686
+msgid "run command in the background"
+msgstr "parancs futtatása a háttérben"
+
+#: src/parse_args.c:688
+msgid "close all file descriptors >= num"
+msgstr "minden fájlleíró lezárása, ami >= num"
+
+#: src/parse_args.c:691
+msgid "run command with the specified BSD login class"
+msgstr "parancs futtatása a megadott BSD bejelentkezési osztállyal"
+
+#: src/parse_args.c:694
+msgid "preserve user environment when running command"
+msgstr "felhasználói környezet megőrzése parancsfuttatáskor"
+
+#: src/parse_args.c:696
+msgid "preserve specific environment variables"
+msgstr "bizonyos környezeti változók megőrzése"
+
+#: src/parse_args.c:698
+msgid "edit files instead of running a command"
+msgstr "fájlok szerkesztése parancs futtatása helyett"
+
+#: src/parse_args.c:700
+msgid "run command as the specified group name or ID"
+msgstr "parancs futtatása megadott csoportnévként vagy -azonosítóként"
+
+#: src/parse_args.c:702
+msgid "set HOME variable to target user's home dir"
+msgstr "a HOME változó beállítása a célfelhasználó saját könyvtárára"
+
+#: src/parse_args.c:704
+msgid "display help message and exit"
+msgstr "súgóüzenet megjelenítése és kilépés"
+
+#: src/parse_args.c:706
+msgid "run command on host (if supported by plugin)"
+msgstr "parancs futtatása a gépen (ha a bővítmény támogatja)"
+
+#: src/parse_args.c:708
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "bejelentkezési parancsértelmező futtatása a célfelhasználóként; egy parancs is megadható"
+
+#: src/parse_args.c:710
+msgid "remove timestamp file completely"
+msgstr "időbélyeg fájl teljes eltávolítása"
+
+#: src/parse_args.c:712
+msgid "invalidate timestamp file"
+msgstr "időbélyeg fájl érvénytelenítése"
+
+#: src/parse_args.c:714
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "felhasználó jogosultságainak felsorolása, vagy adott parancs ellenőrzése, kétszer megadva hosszabb formátumban"
+
+#: src/parse_args.c:716
+msgid "non-interactive mode, no prompts are used"
+msgstr "nem interaktív mód, kérdések nélkül"
+
+#: src/parse_args.c:718
+msgid "preserve group vector instead of setting to target's"
+msgstr "csoportvektor megőrzése a céléra beállítás helyett"
+
+#: src/parse_args.c:720
+msgid "use the specified password prompt"
+msgstr "a megadott jelszóbekérés használata"
+
+#: src/parse_args.c:723
+msgid "create SELinux security context with specified role"
+msgstr "SELinux biztonsági környezet létrehozása a megadott szereppel"
+
+#: src/parse_args.c:726
+msgid "read password from standard input"
+msgstr "jelszó olvasása a szabványos bemenetről"
+
+#: src/parse_args.c:728
+msgid "run shell as the target user; a command may also be specified"
+msgstr "parancsértelmező futtatása a célfelhasználóként; egy parancs is megadható"
+
+#: src/parse_args.c:731
+msgid "create SELinux security context with specified type"
+msgstr "SELinux biztonsági környezet létrehozása a megadott típussal"
+
+#: src/parse_args.c:734
+msgid "terminate command after the specified time limit"
+msgstr "parancs megszakítása a megadott időkorlát után"
+
+#: src/parse_args.c:736
+msgid "in list mode, display privileges for user"
+msgstr "lista módban a felhasználó jogosultságainak megjelenítése"
+
+#: src/parse_args.c:738
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "parancs futtatása (vagy fájl szerkesztése) a megadott nevű vagy azonosítójú felhasználóként"
+
+#: src/parse_args.c:740
+msgid "display version information and exit"
+msgstr "verzióinformáció kiírása és kilépés"
+
+#: src/parse_args.c:742
+msgid "update user's timestamp without running a command"
+msgstr "felhasználó időbélyegének frissítése parancs futtatása nélkül"
+
+#: src/parse_args.c:744
+msgid "stop processing command line arguments"
+msgstr "parancssori argumentumok feldolgozásának befejezése"
+
+#: src/selinux.c:78
+msgid "unable to open audit system"
+msgstr "a felülvizsgálati rendszer megnyitása sikertelen"
+
+#: src/selinux.c:88
+msgid "unable to send audit message"
+msgstr "a felülvizsgálati üzenet küldése sikertelen"
+
+#: src/selinux.c:116
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "az fgetfilecon %s futtatása sikertelen"
+
+#: src/selinux.c:121
+#, c-format
+msgid "%s changed labels"
+msgstr "%s megváltoztatta a címkéket"
+
+#: src/selinux.c:126
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "%s környezetének visszaállítása sikertelen"
+
+#: src/selinux.c:167
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "%s nem nyitható meg, a tty nem címkézhető újra"
+
+#: src/selinux.c:171 src/selinux.c:212 src/selinux.c:229
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "a(z) %s nem karakteres eszköz, a tty nem címkézhető újra"
+
+#: src/selinux.c:180
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "a jelenlegi tty környezet lekérése sikertelen, a tty nem címkézhető újra"
+
+#: src/selinux.c:187
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "ismeretlen „chr_file” biztonsági osztály, a tty nem címkézhető újra"
+
+#: src/selinux.c:192
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "az új tty környezet lekérése sikertelen, a tty nem címkézhető újra"
+
+#: src/selinux.c:199
+msgid "unable to set new tty context"
+msgstr "az új tty környezet beállítása sikertelen"
+
+#: src/selinux.c:273
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "meg kell adnia egy szerepet a(z) %s típushoz"
+
+#: src/selinux.c:279
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "az alapértelmezett típus lekérése sikertelen a(z) %s szerepnél"
+
+#: src/selinux.c:297
+#, c-format
+msgid "failed to set new role %s"
+msgstr "%s új szerep beállítása nem sikerült"
+
+#: src/selinux.c:301
+#, c-format
+msgid "failed to set new type %s"
+msgstr "%s új típus beállítása nem sikerült"
+
+#: src/selinux.c:313
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s nem érvényes környezet"
+
+#: src/selinux.c:348
+msgid "failed to get old_context"
+msgstr "az old_context lekérése nem sikerült"
+
+#: src/selinux.c:354
+msgid "unable to determine enforcing mode."
+msgstr "a kényszerítő mód meghatározása sikertelen."
+
+#: src/selinux.c:371
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "a tty környezet beállítása sikertelen erre: %s"
+
+#: src/selinux.c:410
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "a végrehajtási környezet beállítása sikertelen erre: %s"
+
+#: src/selinux.c:417
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "a kulcslétrehozási környezet beállítása sikertelen erre: %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "legalább egy argumentum szükséges"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "érvénytelen fájlleíró szám: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "%s futtatása bejelentkezési parancsértelmezőként sikertelen"
+
+#: src/sesh.c:125 src/sudo.c:1117
+#, c-format
+msgid "unable to execute %s"
+msgstr "%s nem hajtható végre"
+
+#: src/signal.c:83
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "%d szignál kezelőjének mentése sikertelen"
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "az erőforrás-vezérlési korlát elérve"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "„%s” felhasználó nem tagja ennek a projektnek: „%s”"
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr "a meghívó feladat végső"
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "nem sikerült a(z) „%s” projekthez csatlakozás"
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "nem létezik alapértelmezett kötéseket elfogadó erőforrás-tároló a(z) „%s” projektnél"
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "a megadott erőforrás-tároló nem létezik a(z) „%s” projektnél"
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "nem sikerült hozzákötni az alapértelmezett erőforrás-tárolóhoz a(z) „%s” projektnél"
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "a projekt beállítása nem sikerült a(z) „%s” projektnél"
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "figyelmeztetés: az erőforrás-vezérlés hozzárendelése nem sikerült a(z) „%s” projektnél"
+
+#: src/sudo.c:198
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo %s verzió\n"
+
+#: src/sudo.c:200
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Configure kapcsolói: %s\n"
+
+#: src/sudo.c:208
+msgid "fatal error, unable to load plugins"
+msgstr "végzetes hiba: a bővítmények betöltése sikertelen"
+
+#: src/sudo.c:216
+msgid "unable to initialize policy plugin"
+msgstr "a házirendbővítmény előkészítése sikertelen"
+
+#: src/sudo.c:260
+msgid "plugin did not return a command to execute"
+msgstr "a bővítmény nem tért vissza végrehajtandó paranccsal"
+
+#: src/sudo.c:276
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "hiba a(z) %s I/O bővítmény előkészítésekor"
+
+#: src/sudo.c:299
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "váratatlan 0x%x sudo mód"
+
+#: src/sudo.c:461
+msgid "unable to get group vector"
+msgstr "a csoportvektor lekérése sikertelen"
+
+#: src/sudo.c:523
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "ismeretlen %u uid: kicsoda Ön?"
+
+#: src/sudo.c:579
+msgid "unable to determine tty"
+msgstr "a tty meghatározása sikertelen"
+
+#: src/sudo.c:867
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s a(z) %d uid tulajdona kell legyen, és a setuid bitnek beállítva kell lennie"
+
+#: src/sudo.c:870
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "a tényleges uid nem %d, a(z) %s a „nosuid” kapcsolóval beállított fájlrendszeren vagy rendszergazda jogosultságok nélküli NFS fájlrendszeren van?"
+
+#: src/sudo.c:876
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "a tényleges uid nem %d, a sudo telepítette a setuid gyökeret?"
+
+#: src/sudo.c:929
+msgid "unable to set supplementary group IDs"
+msgstr "a kiegészítő csoportazonosítók beállítása sikertelen"
+
+#: src/sudo.c:936
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "a tényleges gid beállítása a runas gid %u értékre sikertelen"
+
+#: src/sudo.c:942
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "a gid beállítása a runas gid %u értékre sikertelen"
+
+#: src/sudo.c:999
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "váratlan gyermekmegszakítási feltétel: %d"
+
+#: src/sudo.c:1145
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "a(z) %s házirendbővítményből hiányzik a „check_policy” metódus"
+
+#: src/sudo.c:1163
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "a(z) %s házirendbővítmény nem támogatja a jogosultságok felsorolását"
+
+#: src/sudo.c:1180
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "a(z) %s házirendbővítmény nem támogatja a -v kapcsolót"
+
+#: src/sudo.c:1195
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "a(z) %s házirendbővítmény nem támogatja a -k/-K kapcsolókat"
+
+#: src/sudo_edit.c:178 src/sudo_edit.c:267
+msgid "unable to restore current working directory"
+msgstr "az aktuális munkakönyvtár visszaállítása sikertelen"
+
+#: src/sudo_edit.c:574 src/sudo_edit.c:686
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: nem szabályos fájl"
+
+#: src/sudo_edit.c:581
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: szimbolikus linkek szerkesztése nem engedélyezett"
+
+#: src/sudo_edit.c:584
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: fájlok szerkesztése egy írható könyvtárban nem engedélyezett"
+
+#: src/sudo_edit.c:617 src/sudo_edit.c:724
+#, c-format
+msgid "%s: short write"
+msgstr "%s: rövid írás"
+
+#: src/sudo_edit.c:687
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s módosítatlanul hagyva"
+
+#: src/sudo_edit.c:700 src/sudo_edit.c:885
+#, c-format
+msgid "%s unchanged"
+msgstr "%s változatlan"
+
+#: src/sudo_edit.c:713 src/sudo_edit.c:735
+#, c-format
+msgid "unable to write to %s"
+msgstr "az írás sikertelen ebbe: %s"
+
+#: src/sudo_edit.c:714 src/sudo_edit.c:733 src/sudo_edit.c:736
+#: src/sudo_edit.c:910 src/sudo_edit.c:914
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "a szerkesztési munkamenet tartalma ebben maradt: %s"
+
+#: src/sudo_edit.c:732
+msgid "unable to read temporary file"
+msgstr "az átmeneti fájl olvasása sikertelen"
+
+#: src/sudo_edit.c:815
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: belső hiba: útvonalak páratlan száma"
+
+#: src/sudo_edit.c:817
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: átmeneti fájlok létrehozása sikertelen"
+
+#: src/sudo_edit.c:819 src/sudo_edit.c:917
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: ismeretlen hiba: %d"
+
+#: src/sudo_edit.c:909
+msgid "unable to copy temporary files back to their original location"
+msgstr "az átmeneti fájlok visszamásolása az eredeti helyükre sikertelen"
+
+#: src/sudo_edit.c:913
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "néhány átmeneti fájl visszamásolása az eredeti helyükre sikertelen"
+
+#: src/sudo_edit.c:958
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "az uid megváltoztatása rendszergazdára (%u) sikertelen"
+
+#: src/sudo_edit.c:975
+msgid "plugin error: missing file list for sudoedit"
+msgstr "bővítményhiba: hiányzó fájllista a sudoedit programnál"
+
+#: src/sudo_edit.c:1016 src/sudo_edit.c:1029
+msgid "unable to read the clock"
+msgstr "az óra olvasása sikertelen"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr "nincs tty jelen, és nincs askpass program megadva"
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "nincs askpass program megadva, SUDO_ASKPASS beállításának kísérlete"
+
+#: src/tgetpass.c:261
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "a gid beállítása %u értékre sikertelen"
+
+#: src/tgetpass.c:265
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "az uid beállítása %u értékre sikertelen"
+
+#: src/tgetpass.c:270
+#, c-format
+msgid "unable to run %s"
+msgstr "%s futtatása sikertelen"
+
+#: src/utmp.c:268
+msgid "unable to save stdin"
+msgstr "a szabványos bemenet mentése sikertelen"
+
+#: src/utmp.c:270
+msgid "unable to dup2 stdin"
+msgstr "a szabványos bemenet dup2 futtatása sikertelen"
+
+#: src/utmp.c:273
+msgid "unable to restore stdin"
+msgstr "a szabványos bemenet visszaállítása sikertelen"
diff --git a/po/it.mo b/po/it.mo
new file mode 100644
index 0000000..68993a3
--- /dev/null
+++ b/po/it.mo
Binary files differ
diff --git a/po/it.po b/po/it.po
new file mode 100644
index 0000000..f54cbd0
--- /dev/null
+++ b/po/it.po
@@ -0,0 +1,939 @@
+# Italian translations for sudo package
+# This file is put in the public domain.
+# Milo Casagrande <milo@milo.name>, 2011, 2012, 2013, 2014, 2015, 2016, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo-1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-31 11:15+0100\n"
+"Last-Translator: Milo Casagrande <milo@milo.name>\n"
+"Language-Team: Italian <tp@lists.linux.it>\n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Generator: Poedit 2.1.1\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "impossibile aprire lo userdb"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "impossibile passare al registro \"%s\" per %s"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "impossibile ripristinare il registro"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "impossibile allocare memoria"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "Segnale sconosciuto"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "valore non valido"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "valore troppo grande"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "valore troppo piccolo"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "valore percorso \"%s\" non valido in %s, riga %u"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "valore %s \"%s\" non valido in %s, riga %u"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "gruppo sorgente \"%s\" non supportato in %s, riga %u"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "gruppi massimi \"%s\" non validi in %s, riga %u"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "impossibile eseguire stat su %s"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s non è un file regolare"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s è di proprietà dello uid %u, dovrebbe essere di %u"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "%s è scrivibile da tutti"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "%s è scrivibile dal gruppo"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "impossibile aprire %s"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "classe di accesso %s sconosciuta"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "impossibile impostare il contesto utente"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "impossibile impostare la priorità del processo"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "impossibile modificare root a %s"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "impossibile passare a un diverso uid (%u, %u)"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "impossibile passare alla root %s"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "impossibile impostare il gestore per il segnale %d"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "impossibile rimuovere PRIV_PROC_EXEC da PRIV_LIMIT"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "errore nel leggere dal socketpair"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "tipologia di risposta inattesa sul backchannel: %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "impossibile aggiungere l'evento alla coda"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "impossibile impostare il tty di controllo"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "impossibile creare una pipe"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "impossibile ricevere il messaggio dal genitore"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "impossibile eseguire fork"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "impossibile eseguire %s"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "impossibile ripristinare l'etichetta tty"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "inizializzazione della sessione non riuscita da parte del plugin della politica"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "errore nel ciclo dell'evento"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "impossibile ripristinare il gestore per il segnale %d"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "impossibile allocare pty"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "impossibile creare socket"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "impossibile inviare il messaggio per controllare il processo"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "errore in %s, riga %d, durante il caricamento del plugin \"%s\""
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s deve essere di proprietà dello uid %d"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s deve essere scrivibile solo dal proprietario"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "impossibile caricare %s: %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "impossibile trovare il simbolo \"%s\" in %s"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "politica di tipo %d sconosciuta trovata in %s"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "numero principale di versione del plugin %d non compatibile (atteso %d) trovato in %s"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "viene ignorato il plugin di politica \"%s\" in %s, riga %d"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "solo un plugin di politica può essere specificato"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "viene ignorato il plugin di politica duplicato \"%s\" in %s, riga %d"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "viene ignorato il plugin di I/O duplicato \"%s\" in %s, riga %d"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "il plugin di politica %s non include un metodo check_policy"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "errore interno, overflow di %s"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "nome della variabile d'ambiente non valido: %s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "l'argomento di -C deve essere un numero maggiore o uguale a 3"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "non è possibile specificare entrambe le opzioni \"-i\" e \"-s\""
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "non è possibile specificare entrambe le opzioni \"-i\" ed \"-E\""
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "l'opzione \"-E\" non è valida in modalità di modifica"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "non è possibile specificare variabili d'ambiente in modalità di modifica"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "l'opzione \"-U\" può essere usata solo con l'opzione \"-l\""
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "non è possibile usare assieme le opzioni \"-A\" e \"-S\""
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit non è supportato su questa piattaforma"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Solo una delle opzioni -e, -h, -i, -K, -l, -s, -v o -V può essere specificata"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - modifica file come un altro utente\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - esegue un comando come un altro utente\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opzioni:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "Utilizza un programma d'aiuto per richiedere la password"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "Utilizza la tipologia di autenticazione BSD specificata"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "Esegue il comando in background"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "Chiude tutti i descrittori di file >= num"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "Esegue il comando con la classe di accesso BSD specificata"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "Mantiene l'ambiente dell'utente quando viene eseguito il comando"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "Mantiene delle variabile d'ambiente specifiche"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "Modifica i file invece di eseguire un comando"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "Esegue il comando come il gruppo o l'ID specificato"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "Imposta la variabile HOME alla directory dell'utente finale"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "Visualizza il messaggio di aiuto ed esce"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "Esegue il comando sull'host (se supportato dal plugin)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "Esegue una shell di login come l'utente finale; può essere specificato un comando"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "Rimuove completamente il file temporale"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "Invalida il file temporale"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "Elenca i privilegi dell'utente o verifica un comando specifico; usare due volte per il formato più lungo"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "Modalità non interattiva, non richiede nulla all'utente"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "Mantiene il vettore di gruppo invece di impostarlo a quello dell'obiettivo"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "Utilizza la richiesta della password specificata"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "Crea il contesto di sicurezza SELinux con il ruolo specificato"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "Legge la password dallo standard input"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "Esegue la shell come l'utente finale; può essere specificato un comando"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "Crea il contesto di sicurezza SELinux con il tipo specificato"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "Termina il comando allo trascorrere del limite temporale specificato"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "In modalità elenco, visualizza i privilegi dell'utente"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "Esegue un comando (o modifica un file) come il nome utente o l'ID specificato"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "Visualizza le informazioni sulla versione ed esce"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "Aggiorna il timestamp dell'utente senza eseguire un comando"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "Ferma l'elaborazione degli argomenti a riga di comando"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "impossibile aprire il sistema di audit"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "impossibile inviare il messaggio di audit"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "impossibile eseguire fgetfilecon %s"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s ha modificato le etichette"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "impossibile ripristinare il contesto per %s"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "impossibile aprire %s, tty non viene ri-etichettato"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s non è un dispositivo a caratteri, tty non viene ri-etichettato"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "impossibile ottenere il contesto tty attuale, tty non viene ri-etichettato"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "classe di sicurezza \"chr_file\" sconosciuta, tty non viene ri-etichettato"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "impossibile ottenere il nuovo contesto tty, tty non viene ri-etichettato"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "impossibile impostare il nuovo contesto tty"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "è necessario specificare un ruolo per la tipologia %s"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "impossibile ottenere la tipologia predefinita per il ruolo %s"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "impossibile impostare il nuovo ruolo %s"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "impossibile impostare la nuova tipologia %s"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s non è un contesto valido"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "recupero del vecchio contesto non riuscito"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "impossibile determinare la modalità di rispetto."
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "impossibile impostare il contesto tty a %s"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "impossibile impostare il contesto exec a %s"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "impossibile impostare il contesto di creazione della chiave a %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "richiede almeno un argomento"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "numero descrittore file non valido: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "impossibile eseguire %s come shell di login"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "impossibile salvare il gestore per il segnale %d"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "raggiunto il limite di controllo delle risorse"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "l'utente \"%s\" non fa parte del progetto \"%s\""
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "il task chiamante è definitivo"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "impossibile unirsi al progetto \"%s\""
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "non esiste alcun pool di risorse per il progetto \"%s\" che accetti binding predefiniti"
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "il pool di risorse specificato non esiste per il progetto \"%s\""
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "impossibile unirsi al pool di risorse predefinito per il progetto \"%s\""
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "setproject per il progetto \"%s\" non riuscita"
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "attenzione, assegnazione della risorsa di controllo per il progetto \"%s\" non riuscita"
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Versione di sudo: %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Opzioni di configurazione: %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "errore irreversibile, impossibile caricare i plugin"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "impossibile inizializzare il plugin delle politiche"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "il plug-in non ha restituito un comando da eseguire"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "errore nell'inizializzare il plugin di I/O %s"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "modalità 0x%x di sudo non attesa"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "l'utente attuale non esiste nel database %s"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "impossibile impostare il tty"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s deve essere di proprietà dello uid %d e avere il bit setuid impostato"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "lo uid effettivo non è %d. %s si trova su un file system con l'opzione \"nosuid\" impostata o su un file system NFS senza privilegi di root?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "lo uid effettivo non è %d. Il programma sudo è installato con setuid root?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "impossibile impostare ID di gruppo supplementari"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "impossibile impostare il gid effettivo per eseguire come %u"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "impossibile impostare il gid per eseguire come gid %u"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "condizione di uscita del figlio inattesa: %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "il plugin di politica %s non include un metodo \"check_policy\""
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "il plugin di politica %s non supporta l'elencazione dei privilegi"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "il plugin di politica %s non supporta l'opzione -v"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "il plugin di politica %s non supporta le opzioni -k/-K"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "nessuna directory temporanea scrivibile trovata"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "impossibile ripristinare la directory di lavoro attuale"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: non è un file regolare"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: la modifica di collegamenti simbolici non è consentita"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: la modifica di file in una directory con accesso in scrittura non è consentita"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s: scrittura breve"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s lasciato non modificato"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "%s non modificato"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "impossibile scrivere su %s"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "contenuto della sessione di modifica lasciato in %s"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "impossibile leggere il file temporaneo"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: errore interno: strano numero numero di percorsi"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: impossibile creare file temporanei"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: errore %d sconosciuto"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "impossibile copiare i file temporanei nella loro posizione originale"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "impossibile copiare alcuni dei file temporanei nella loro posizione originale"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "impossibile modificare lo uid a root (%u)"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "errore di plugin: elenco file mancante per sudoedit"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "impossibile leggere l'orologio"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "tempo esaurito durante la lettura della password"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "nessuna password fornita"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "impossibile leggere la password"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "nessun tty presente e nessun programma di richiesta password specificato"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "nessun programma di richiesta password specificato, impostare SUDO_ASKPASS"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "impossibile impostare il gid a %u"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "impossibile impostare lo uid a %u"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "impossibile eseguire %s"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "impossibile salvare lo stdin"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "impossibile eseguire dup2 sullo stdin"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "impossibile ripristinare lo stdin"
+
+#~ msgid "unable to get group vector"
+#~ msgstr "impossibile ottenere il vettore di gruppo"
+
+# (ndt) mah... andrebbe resa meglio...
+#~ msgid "unknown uid %u: who are you?"
+#~ msgstr "uid %u sconosciuto: utente sconosciuto."
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "errore nel leggere dalla pipe di segnale"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "errore nel leggere dalla pipe"
diff --git a/po/ja.mo b/po/ja.mo
new file mode 100644
index 0000000..55f8c79
--- /dev/null
+++ b/po/ja.mo
Binary files differ
diff --git a/po/ja.po b/po/ja.po
new file mode 100644
index 0000000..c652148
--- /dev/null
+++ b/po/ja.po
@@ -0,0 +1,996 @@
+# Japanese messages for sudo
+# This file is put in the public domain.
+# Yasuaki Taniguchi <yasuakit@gmail.com>, 2011.
+# Takeshi Hamasaki <hmatrjp@users.sourceforge.jp>, 2012, 2015, 2016, 2017, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-12-09 19:26+0900\n"
+"Last-Translator: Takeshi Hamasaki <hmatrjp@users.sourceforge.jp>\n"
+"Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Poedit 2.1.1\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "ユーザーデータベースを開くことができません"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "%s 用のレジストリー \"%s\" へ切り替えることができません"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "レジストリーを復元できません"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "メモリ割り当てを行えませんでした"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "不明なシグナルです"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "無効な値"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "値が大き過ぎます"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "値が小さ過ぎます"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "無効な Path の値 \"%s\" が %s の %u 行目 にあります"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "無効な %s の値 \"%s\" が %s の %u 行目 にあります"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "サポートしていないグループソース \"%s\" が %s の %u 行目で指定されています"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "無効な最大グループの値 \"%s\" が %s の %u 行目 にあります"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "%s の状態取得 (stat) ができません"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s は通常ファイルではありません"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s はユーザーID %u によって所有されています。これは %u であるべきです"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "%s は誰でも書き込み可能です"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "%s はグループのメンバーによる書き込みが可能です"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "%s を開けません"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "不明なログインクラス %s です"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "ユーザーコンテキストを設定できません"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "プロセス優先度を設定できません"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "root を %s へ変更できません"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "実行時のユーザーID (uid) (%u, %u) へ変更できません"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "ディレクトリーを %s に変更できません"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "シグナル %d のハンドラを設定できません"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "PRIV_LIMIT から PRIV_PROC_EXEC を取り除くことができません"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "ソケットペアからの読み込み中にエラーが発生しました"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "バックチャンネルに関する予期しないリプレイタイプです: %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "キューにイベントを追加できません"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "tty の制御設定ができません"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "パイプを作成できません"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "親からのメッセージを受け取ることができません"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "fork できません"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "%s を実行できません"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "tty ラベルを復旧できません"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "ポリシープラグインがセッションの初期化に失敗しました"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "イベントループでエラーが発生しました"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "シグナル %d のハンドラを復元できません"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "pty を割り当てられません"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "ソケットを作成できません"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "監視プロセスへメッセージを送ることができません"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "%s, %d 行目 プラグイン \"%s\" をロード中にエラーが発生しました"
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s の所有者は uid %d でなければいけません"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s は所有者のみ書き込み可能で無ければいけません"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "%s をロードできません: %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "シンボル \"%s\" が %s に見つかりません"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "不明なポリシータイプ %d が %s で見つかりました"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "互換性の無いポリシーメジャーバージョン %d (予期されるのは %d)が %s で見つかりました"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "ポリシープラグイン \"%s\" を無視します。%s の %d 行目"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "1つのポリシープラグインのみ指定できます"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "重複しているポリシープラグイン \"%s\" を無視します。%s の %d 行目"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "重複している I/O プラグイン \"%s\" を無視します。%s の %d 行目"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "ポリシープラグイン %s には check_policy メソッドが含まれていません"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "内部エラー、 %s がオーバーフローしました"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "無効な環境変数名です: %s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "-C の引数は 3 以上の数値でなければいけません"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "`-i' と `-s' オプションを同時に指定することはできません"
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "`-i' と `-E' オプションを同時に指定することはできません"
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "`-E' オプションは編集モードでは無効です"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "編集モードでは環境変数を指定できません"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "`-U' オプションは `-l' オプションのみと同時に指定できます"
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "`-A' と `-S' オプションは同時に指定することはできません"
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit はこのプラットフォームではサポートされていません"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "-e, -h, -i, -K, -l, -s, -v または -V のうち一つのみ指定できます"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - 別のユーザーとしてファイルを編集します\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - 別のユーザーとしてコマンドを実行します\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"オプション:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "パスワード要求のために補助プログラムを使用する"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "指定した BSD 認証タイプを使用する"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "コマンドをバックグラウンドで実行する"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "num 以上のすべてのファイル記述子を閉じる"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "指定した BSD ログインクラスでコマンドを実行する"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "コマンドを実行する時にユーザーの環境変数を維持する"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "指定の環境変数を維持する"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "コマンドを実行するのではなくファイルを編集する"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "指定したグループ名またはグループIDでコマンドを実行する"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "HOME 変数を変更先となるユーザーのホームディレクトリに設定する"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "このヘルプを表示して終了する"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "host でコマンドを実行する(プラグインがサポートしている場合)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "変更先のユーザーとしてログインシェルを実行する; コマンドを指定することもできます"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "タイムスタンプファイルを完全に削除する"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "無効なタイムスタンプファイルです"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "ユーザーの権限を一覧表示するまたは指定したコマンドについて確認する ;長い表示にするには2回指定すること"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "非対話モードで実行し、ユーザーに入力を求めない"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "グループベクトルを保護する (変更先のユーザーのものに設定しない)"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "指定したパスワードプロンプトを使用する"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "指定した役割で SELinux セキュリティーコンテキストを作成する"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "標準入力からパスワードを読み込む"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "変更先のユーザーとしてシェルを実行する; コマンドを指定することもできます"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "指定したタイプで SELinux セキュリティーコンテキストを作成する"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "指定した制限時間でコマンドの実行を中止する"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "リストモードで、ユーザーの権限を表示する"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "指定したユーザー名またはユーザーIDでコマンドを実行する (またはファイルを編集する)"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "バージョン情報を表示して終了する"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "コマンドを実行せずにユーザーのタイムスタンプを更新する"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "コマンドライン引数の処理を終了する"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "監査システムを開くことができません"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "監査メッセージを送ることができません"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "fgetfilecon %s を行うことができません"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s はラベルを変更しました"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "%s 用のコンテキストを復元することができません"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "%s を開くことができません。tty の再ラベル付けを行いません"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s はキャラクターデバイスではありません、tty の再ラベル付けを行いません"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "現在の tty コンテキストを取得できません。tty の再ラベル付けを行いません"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "\"chr_file\" は未知のセキュリティクラスです。tty の再ラベル付けを行いません"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "新しい tty コンテキストを取得できません。tty の再ラベル付けを行いません"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "新しい tty コンテキストを設定できません"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "タイプ %s 用の役割を指定しなければいけません"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "役割 %s 用のデフォルトのタイプを取得できません"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "新しい役割 %s の設定に失敗しました"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "新しいタイプ %s の設定に失敗しました"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s は有効なコンテキストではありません"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "古いコンテキスト (old_context) の取得に失敗しました"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "強制モードを決定することができません。"
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "新しい tty コンテキストを %s に設定できません"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "実行コンテキストを %s に設定できません"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "キー作成コンテキストを %s へ設定できません"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "最低でも一つ以上おの引数が必要です"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "無効なファイル記述子の番号: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "%s をログインシェルとして実行できません"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "シグナル %d のハンドラを保存できません"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "資源制御の制限の最大値に達しました"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "ユーザー \"%s\" はプロジェクト \"%s\" のメンバーではありません"
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "起動しているタスクは最後 (final) です"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "プロジェクト \"%s\" に参加できません"
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "プロジェクト \"%s\" 用にはデフォルト割り当てとして受け付けられる資源プールがありません"
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "プロジェクト \"%s\" 用として指定した資源プールは存在しません"
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "プロジェクト \"%s\" 用にデフォルト資源プールを割り当てられませんでした"
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "プロジェクト\"%s\" への setproject に失敗しました"
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "警告、プロジェクト \"%s\" への資源制御割り当てに失敗しました"
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo バージョン %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "configure オプション: %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "致命的エラー、プラグインをロードできません"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "ポリシープラグインを初期化できません"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "プラグインが実行するべきコマンドを返しませんでした"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "I/O プラグイン %s を初期化中にエラーが発生しました"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "予期しない sudo のモード 0x%x です"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "あなたは %s データベースに存在しません"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "tty を特定できません"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s は所有者が uid %d である必要があり、かつ setuid が設定されている必要があります"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "実効 uid が %d ではありません、%s は 'nosuid' が設定されたファイルシステムにあるか、root 権限のないNFSファイルシステムにあるのでは?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "実効 uid が %d ではありません、sudo は setuid root を設定してインストールされていますか?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "追加のグループIDを設定できません"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "実行時のグループID (gid) %u を実効グループIDに設定できません"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "実行時のグループID (gid) %u をグループIDに設定できません"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "予期しない子プロセスの終了コードです: %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "ポリシープラグイン %s には check_policy メソッドが含まれていません"
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "ポリシープラグイン %s は権限の一覧表示をサポートしていません"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "ポリシープラグイン %s は -v オプションをサポートしません"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "ポリシープラグイン %s は -k/-K オプションをサポートしません"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "書き込み可能な一時ディレクトリが見つかりません"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "カレントディレクトリを復元できません"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: 通常ファイルではありません"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: シンボリックリンクの編集は許可されていません"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: 書き込み可能なディレクトリ内のファイルの編集は許可されていません"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s: 短い書き込みです"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s を修正しないままにします"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "%s を変更しません"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "%s へ書き込むことができません"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "編集セッションの内容が %s 内に残っています"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "一時ファイルを読み込むことができません"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: 内部エラー: パスの数がおかしいです"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: 一時ファイルを作成することができません"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: 不明なエラー %d"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "一時ファイルを元の場所に戻すことができません"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "一時ファイルのいくつかを元の場所に戻すことができません"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "ユーザーID (uid) を root (%u) に変更できません"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "プラグインエラー: sudoedit 用のファイル一覧がありません"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "時刻を読み込むことができません"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "パスワードの読み込みがタイムしました"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "パスワードが与えられませんでした"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "パスワードを読み込むことができません"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "端末 (tty) が存在せず、パスワードを尋ねる (askpass) プログラムが指定されていません"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "パスワードを尋ねる (askpass) プログラムが指定されていません。 SUDO_ASKPASS を設定し、やり直してください"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "グループIDを %u に設定できません"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "ユーザーIDを %u に設定できません"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "%s を実行できません"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "標準入力を保存できません"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "標準入力へ dup2 を実行できません"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "標準入力を復元できません"
+
+#~ msgid "unable to get group vector"
+#~ msgstr "グループベクトルを取得できません"
+
+#~ msgid "unknown uid %u: who are you?"
+#~ msgstr "不明なユーザーID %u です: 誰ですか?"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "シグナルパイプからの読み込み中にエラーが発生しました"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "パイプからの読み込み中にエラーが発生しました"
+
+#~ msgid "internal error, tried allocate zero bytes"
+#~ msgstr "内部エラー、0バイトの確保を試みました"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "端末を raw モードに設定できません"
+
+#~ msgid "unable to open socket"
+#~ msgstr "ソケットを開くことができません"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "内部エラー、 emalloc2(0) を試みました"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "内部エラー、ecalloc(0) を試みました"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "内部エラー、 erealloc(0) を試みました"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "内部エラー、 erealloc3(0) を試みました"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "内部エラー、 erecalloc(0) を試みました"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "select failed"
+#~ msgstr "select に失敗しました"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: オーバーフローが検出されました"
+
+#~ msgid "list user's available commands\n"
+#~ msgstr "ユーザーが使用可能なコマンドを一覧表示する\n"
+
+#~ msgid "run a shell as target user\n"
+#~ msgstr "変更先のユーザーとしてシェルを実行する\n"
+
+#~ msgid "when listing, list specified user's privileges\n"
+#~ msgstr "一覧表示する時に、指定したユーザーの権限を一覧表示する\n"
+
+#~ msgid "internal error, emalloc2() overflow"
+#~ msgstr "内部エラー、 emalloc2() がオーバーフローしました"
+
+#~ msgid "internal error, erealloc3() overflow"
+#~ msgstr "内部エラー、 erealloc3() がオーバーフローしました"
+
+#~ msgid "%s: at least one policy plugin must be specified"
+#~ msgstr "%s: 最低でも一つ以上のポリシープラグインを指定しなければいけません"
+
+#~ msgid "must be setuid root"
+#~ msgstr "setuid root されていなければいけません"
+
+#~ msgid "the argument to -D must be between 1 and 9 inclusive"
+#~ msgstr "-D の引数は 1 から 9 の間でなければいけません"
diff --git a/po/ko.mo b/po/ko.mo
new file mode 100644
index 0000000..3027288
--- /dev/null
+++ b/po/ko.mo
Binary files differ
diff --git a/po/ko.po b/po/ko.po
new file mode 100644
index 0000000..f655e49
--- /dev/null
+++ b/po/ko.po
@@ -0,0 +1,877 @@
+# Korean translation for sudo
+# This file is distributed under the same license as the sudo package.
+# Todd C. Miller <Todd.Miller@courtesan.com>, 2011-2015
+# Seong-ho Cho <darkcircle.0426@gmail.com>, 2016, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.20b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2017-03-09 11:58-0700\n"
+"PO-Revision-Date: 2017-06-06 17:21+0900\n"
+"Last-Translator: Seong-ho Cho <darkcircle.0426@gmail.com>\n"
+"Language-Team: Korean <translation-team-ko@googlegroups.com>\n"
+"Language: ko\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Poedit 1.8.7\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:172
+msgid "unable to open userdb"
+msgstr "사용자 DB를 열 수 없습니다"
+
+#: lib/util/aix.c:227
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "%2$s의 \"%1$s\" 레지스트리로 전환할 수 없습니다"
+
+#: lib/util/aix.c:252
+msgid "unable to restore registry"
+msgstr "레지스트리를 복원할 수 없습니다"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:184 lib/util/sudo_conf.c:270 lib/util/sudo_conf.c:347
+#: lib/util/sudo_conf.c:545 src/conversation.c:75 src/exec_common.c:107
+#: src/exec_common.c:123 src/exec_common.c:132 src/exec_monitor.c:214
+#: src/exec_nopty.c:326 src/exec_pty.c:623 src/exec_pty.c:631
+#: src/exec_pty.c:868 src/load_plugins.c:52 src/load_plugins.c:65
+#: src/load_plugins.c:215 src/load_plugins.c:238 src/load_plugins.c:303
+#: src/load_plugins.c:318 src/parse_args.c:183 src/parse_args.c:205
+#: src/parse_args.c:376 src/parse_args.c:472 src/parse_args.c:494
+#: src/preserve_fds.c:47 src/preserve_fds.c:130 src/selinux.c:83
+#: src/selinux.c:292 src/selinux.c:415 src/selinux.c:424 src/sesh.c:115
+#: src/sudo.c:398 src/sudo.c:423 src/sudo.c:488 src/sudo.c:610 src/sudo.c:670
+#: src/sudo.c:680 src/sudo.c:700 src/sudo.c:719 src/sudo.c:728 src/sudo.c:737
+#: src/sudo.c:754 src/sudo.c:795 src/sudo.c:805 src/sudo.c:825 src/sudo.c:1246
+#: src/sudo.c:1267 src/sudo.c:1441 src/sudo.c:1535 src/sudo_edit.c:151
+#: src/sudo_edit.c:775 src/sudo_edit.c:872 src/sudo_edit.c:985
+#: src/sudo_edit.c:1005
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/sudo_conf.c:185
+#: lib/util/sudo_conf.c:270 lib/util/sudo_conf.c:347 lib/util/sudo_conf.c:545
+#: src/conversation.c:76 src/exec_common.c:107 src/exec_common.c:124
+#: src/exec_common.c:133 src/exec_pty.c:623 src/exec_pty.c:631
+#: src/exec_pty.c:868 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:183
+#: src/parse_args.c:205 src/parse_args.c:376 src/parse_args.c:472
+#: src/parse_args.c:494 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:83 src/selinux.c:292 src/selinux.c:415 src/selinux.c:424
+#: src/sesh.c:115 src/sudo.c:398 src/sudo.c:423 src/sudo.c:488 src/sudo.c:610
+#: src/sudo.c:825 src/sudo.c:1246 src/sudo.c:1267 src/sudo.c:1441
+#: src/sudo.c:1535 src/sudo_edit.c:151 src/sudo_edit.c:775 src/sudo_edit.c:872
+#: src/sudo_edit.c:985 src/sudo_edit.c:1005
+msgid "unable to allocate memory"
+msgstr "메모리를 할당할 수 없습니다"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "알 수 없는 시그널"
+
+#: lib/util/strtoid.c:77 lib/util/strtoid.c:124 lib/util/strtoid.c:152
+#: lib/util/strtomode.c:49 lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "잘못된 값"
+
+#: lib/util/strtoid.c:84 lib/util/strtoid.c:131 lib/util/strtoid.c:159
+#: lib/util/strtomode.c:55 lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "값이 너무 큽니다"
+
+#: lib/util/strtoid.c:86 lib/util/strtoid.c:137 lib/util/strtomode.c:55
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "값이 너무 작습니다"
+
+#: lib/util/sudo_conf.c:203
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "%2$s의 %3$u번째 줄에 잘못된 경로 값 \"%1$s\""
+
+#: lib/util/sudo_conf.c:369 lib/util/sudo_conf.c:422
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "%3$s의 %4$u번째 줄에 %1$s의 잘못된 값 \"%2$s\""
+
+#: lib/util/sudo_conf.c:390
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "%2$s의 %3$u번째 줄에 지원하지 않는 그룹 원본 \"%1$s\""
+
+#: lib/util/sudo_conf.c:406
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "%2$s의 %3$u번째 줄에 잘못된 최대 그룹 값 \"%1$s\""
+
+#: lib/util/sudo_conf.c:561
+#, c-format
+msgid "unable to stat %s"
+msgstr "%s의 상태를 가져올 수 없습니다"
+
+#: lib/util/sudo_conf.c:564
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s은(는) 일반 파일이 아닙니다"
+
+#: lib/util/sudo_conf.c:567
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s은(는) %u uid에서 소유하고 있지만 %u uid가 소유해야 합니다"
+
+#: lib/util/sudo_conf.c:571
+#, c-format
+msgid "%s is world writable"
+msgstr "%s에 모두가 기록할 수 있습니다"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "%s is group writable"
+msgstr "%s에 그룹 구성원이 기록할 수 있습니다"
+
+#: lib/util/sudo_conf.c:584 src/selinux.c:201 src/selinux.c:213 src/sudo.c:366
+#, c-format
+msgid "unable to open %s"
+msgstr "%s을(를) 열 수 없습니다"
+
+#: src/exec.c:189 src/exec_monitor.c:504 src/exec_monitor.c:506
+#: src/exec_monitor.c:511 src/exec_monitor.c:513 src/exec_monitor.c:527
+#: src/exec_monitor.c:538 src/exec_monitor.c:540 src/exec_monitor.c:542
+#: src/exec_monitor.c:544 src/exec_monitor.c:546 src/exec_monitor.c:548
+#: src/exec_monitor.c:550 src/exec_nopty.c:191 src/exec_nopty.c:193
+#: src/exec_nopty.c:195 src/exec_nopty.c:197 src/exec_nopty.c:199
+#: src/exec_nopty.c:201 src/exec_nopty.c:203 src/exec_nopty.c:205
+#: src/exec_nopty.c:208 src/exec_nopty.c:222 src/exec_nopty.c:224
+#: src/exec_nopty.c:226 src/exec_nopty.c:384 src/exec_pty.c:427
+#: src/exec_pty.c:661 src/exec_pty.c:1196 src/exec_pty.c:1198
+#: src/exec_pty.c:1200 src/exec_pty.c:1202 src/exec_pty.c:1204
+#: src/exec_pty.c:1206 src/exec_pty.c:1208 src/exec_pty.c:1211
+#: src/exec_pty.c:1219 src/exec_pty.c:1221 src/exec_pty.c:1223
+#: src/exec_pty.c:1231 src/exec_pty.c:1233 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "%d 시그널의 핸들러를 설정할 수 없습니다"
+
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "PRIV_LIMIT에서 PRIV_PROC_EXEC를 제거할 수 없습니다"
+
+#: src/exec_monitor.c:277 src/exec_nopty.c:455 src/exec_pty.c:1028
+msgid "error reading from signal pipe"
+msgstr "시그널 파이프 읽기 오류"
+
+#: src/exec_monitor.c:363
+msgid "error reading from socketpair"
+msgstr "소켓쌍 읽기 오류"
+
+#: src/exec_monitor.c:372
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "백 채널에 잘못된 응답 형식: %d"
+
+#: src/exec_monitor.c:450 src/exec_monitor.c:458 src/exec_monitor.c:466
+#: src/exec_nopty.c:130 src/exec_nopty.c:138 src/exec_pty.c:516
+#: src/exec_pty.c:521 src/exec_pty.c:591 src/exec_pty.c:598 src/exec_pty.c:873
+#: src/exec_pty.c:1129 src/exec_pty.c:1137 src/exec_pty.c:1322
+#: src/exec_pty.c:1332 src/exec_pty.c:1377 src/exec_pty.c:1384
+#: src/exec_pty.c:1409
+msgid "unable to add event to queue"
+msgstr "큐에 이벤트를 추가할 수 없습니다"
+
+#: src/exec_monitor.c:496 src/exec_monitor.c:570 src/exec_nopty.c:161
+#: src/exec_pty.c:705 src/exec_pty.c:714 src/exec_pty.c:722 src/signal.c:129
+#: src/tgetpass.c:246
+msgid "unable to create pipe"
+msgstr "파이프를 만들 수 없습니다"
+
+#: src/exec_monitor.c:562
+msgid "unable to set controlling tty"
+msgstr "처리 tty를 설정할 수 없습니다"
+
+#: src/exec_monitor.c:573 src/exec_nopty.c:240 src/exec_pty.c:756
+#: src/tgetpass.c:250
+msgid "unable to fork"
+msgstr "포킹할 수 없습니다"
+
+#: src/exec_monitor.c:654 src/exec_nopty.c:292
+msgid "unable to restore tty label"
+msgstr "tty 레이블을 복원할 수 없습니다"
+
+#: src/exec_nopty.c:233 src/exec_pty.c:1240
+msgid "policy plugin failed session initialization"
+msgstr "정책 플러그인에서 세션 초기화에 실패했습니다"
+
+#: src/exec_nopty.c:281 src/exec_pty.c:1278
+msgid "error in event loop"
+msgstr "이벤트 루프에 오류"
+
+#: src/exec_nopty.c:392 src/exec_pty.c:459 src/signal.c:87
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "%d 시그널의 핸들러를 복원할 수 없습니다"
+
+#: src/exec_pty.c:133
+msgid "unable to allocate pty"
+msgstr "pty를 할당할 수 없습니다"
+
+#: src/exec_pty.c:1179
+msgid "unable to create sockets"
+msgstr "소켓을 만들 수 없습니다"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "%s의 %d번째 줄에서 \"%s\" 플러그인을 불러오는 중 오류"
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s은(는) uid %d에서 소유해야 합니다"
+
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s은(는) 소유자만 기록할 수 있어야 합니다"
+
+#: src/load_plugins.c:172
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "%s을(를) 불러올 수 없습니다: %s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "%2$s에서 \"%1$s\" 심볼을 찾을 수 없습니다"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "%2$s에서 알 수 없는 정책 유형 %1$d이(가) 있습니다"
+
+#: src/load_plugins.c:193
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "%3$s에 주 버전이(%2$d을(를) 기대했지만) %1$d인 비호환 플러그인이 있습니다"
+
+#: src/load_plugins.c:202
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "%2$s의 %3$d번째 줄에서 \"%1$s\" 정책 플러그인 무시"
+
+#: src/load_plugins.c:204
+msgid "only a single policy plugin may be specified"
+msgstr "단일 정책 플러그인을 지정하십시오"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "%2$s의 %3$d번째 줄에서 \"%1$s\" 중복 정책 플러그인 무시"
+
+#: src/load_plugins.c:228
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "%2$s의 %3$d번째 줄에서 \"%1$s\" 중복 입출력 플러그인 무시"
+
+#: src/load_plugins.c:331
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "%s 정책 플러그인에 check_policy 메서드가 없습니다"
+
+#: src/net_ifs.c:173 src/net_ifs.c:190 src/net_ifs.c:335 src/sudo.c:483
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "내부 오류. %s 오버플로우."
+
+#: src/parse_args.c:242
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "-C의 인자 값은 3보다 크거나 같아야 합니다"
+
+#: src/parse_args.c:412
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "`-i' 및 `-s' 옵션을 함께 지정할 수 없습니다"
+
+#: src/parse_args.c:416
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "`-i' 및 `-E' 옵션을 함께 지정할 수 없습니다"
+
+#: src/parse_args.c:426
+msgid "the `-E' option is not valid in edit mode"
+msgstr "`-E' 옵션은 편집 모드에서 유효하지 않습니다"
+
+#: src/parse_args.c:428
+msgid "you may not specify environment variables in edit mode"
+msgstr "편집 모드에서 환경 변수를 지정할 수 없습니다"
+
+#: src/parse_args.c:436
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "`-U' 옵션은 `-l' 옵션만 함께 사용할 수 있습니다"
+
+#: src/parse_args.c:440
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "`-A' 및 `-S' 옵션을 함께 사용할 수 없습니다"
+
+#: src/parse_args.c:516
+msgid "sudoedit is not supported on this platform"
+msgstr "이 플랫폼에서 sudoedit를 지원하지 않습니다"
+
+#: src/parse_args.c:589
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "-e, -h, -i, -K, -l, -s, -v, -V 옵션 중 하나를 지정해야 합니다"
+
+#: src/parse_args.c:603
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - 다른 사용자 권한으로 파일을 편집합니다\n"
+"\n"
+
+#: src/parse_args.c:605
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - 다른 사용자 권한으로 명령을 실행합니다\n"
+"\n"
+
+#: src/parse_args.c:610
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"옵션:\n"
+
+#: src/parse_args.c:612
+msgid "use a helper program for password prompting"
+msgstr "암호 질문에 보조 프로그램 활용"
+
+#: src/parse_args.c:615
+msgid "use specified BSD authentication type"
+msgstr "지정 BSD 인증 형식 활용"
+
+#: src/parse_args.c:618
+msgid "run command in the background"
+msgstr "백그라운드에서 명령 실행"
+
+#: src/parse_args.c:620
+msgid "close all file descriptors >= num"
+msgstr "num 보다 크거나 같은 모든 파일 서술자를 닫습니다"
+
+#: src/parse_args.c:623
+msgid "run command with the specified BSD login class"
+msgstr "지정 BSD 로그인 클래스로 명령을 실행합니다"
+
+#: src/parse_args.c:626
+msgid "preserve user environment when running command"
+msgstr "명령을 실행할 때 사용자 환경을 유지합니다"
+
+#: src/parse_args.c:628
+msgid "edit files instead of running a command"
+msgstr "명령을 실행하는 대신 파일을 편집합니다"
+
+#: src/parse_args.c:630
+msgid "run command as the specified group name or ID"
+msgstr "지정 그룹 이름 또는 ID로 명령을 실행합니다"
+
+#: src/parse_args.c:632
+msgid "set HOME variable to target user's home dir"
+msgstr "대상 사용자의 내 폴더에 HOME 변수를 지정합니다"
+
+#: src/parse_args.c:634
+msgid "display help message and exit"
+msgstr "도움말을 보여주고 빠져나갑니다"
+
+#: src/parse_args.c:636
+msgid "run command on host (if supported by plugin)"
+msgstr "(플러그인에서 지원한다면)호스트에서 명령을 실행합니다"
+
+#: src/parse_args.c:638
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "대상 사용자 자격으로 셸에 로그인합니다. 명령도 지정할 수 있습니다."
+
+#: src/parse_args.c:640
+msgid "remove timestamp file completely"
+msgstr "타임스탬프 파일을 완전히 제거합니다"
+
+#: src/parse_args.c:642
+msgid "invalidate timestamp file"
+msgstr "타임스탬프 파일을 초기화합니다"
+
+#: src/parse_args.c:644
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "사용자 권한을 보여주거나 지정 명령을 확인합니다. 긴 형식으로 보려면 옵션을 두 번 사용하십시오"
+
+#: src/parse_args.c:646
+msgid "non-interactive mode, no prompts are used"
+msgstr "비대화형 모드. 프롬프트를 사용하지 않습니다"
+
+#: src/parse_args.c:648
+msgid "preserve group vector instead of setting to target's"
+msgstr "대상을 설정하는 대신 그룹 벡터를 유지합니다"
+
+#: src/parse_args.c:650
+msgid "use the specified password prompt"
+msgstr "지정 암호 프롬프트를 활용합니다"
+
+#: src/parse_args.c:653
+msgid "create SELinux security context with specified role"
+msgstr "지정 역할을 지닌 SELinux 보안 컨텍스트를 만듭니다"
+
+#: src/parse_args.c:656
+msgid "read password from standard input"
+msgstr "표준 입력으로 암호를 입력 받습니다"
+
+#: src/parse_args.c:658
+msgid "run shell as the target user; a command may also be specified"
+msgstr "셸을 대상 사용자 명의로 실행합니다. 명령도 지정합니다."
+
+#: src/parse_args.c:661
+msgid "create SELinux security context with specified type"
+msgstr "지정 유형의 SELinux 보안 컨텍스트를 만듭니다"
+
+#: src/parse_args.c:664
+msgid "terminate command after the specified time limit"
+msgstr "지정 제한 시간 이후로 명령 실행을 멈춥니다"
+
+#: src/parse_args.c:666
+msgid "in list mode, display privileges for user"
+msgstr "목록 모드에서 사용자 권한을 보여줍니다"
+
+#: src/parse_args.c:668
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "지정한 사용자 이름 또는 ID로 명령을 실행(또는 파일 편집)"
+
+#: src/parse_args.c:670
+msgid "display version information and exit"
+msgstr "버전 정보를 보여주고 나갑니다"
+
+#: src/parse_args.c:672
+msgid "update user's timestamp without running a command"
+msgstr "명령을 실행하지 않고 사용자 타임스탬프를 업데이트합니다"
+
+#: src/parse_args.c:674
+msgid "stop processing command line arguments"
+msgstr "명령행 인자 처리를 멈춥니다"
+
+#: src/selinux.c:77
+msgid "unable to open audit system"
+msgstr "감사 시스템을 열 수 없습니다"
+
+#: src/selinux.c:87
+msgid "unable to send audit message"
+msgstr "감사 메시지를 보낼 수 없습니다."
+
+#: src/selinux.c:115
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "%s에 fgetfilecon을 실행할 수 없습니다."
+
+#: src/selinux.c:120
+#, c-format
+msgid "%s changed labels"
+msgstr "%s에서 레이블을 바꾸었습니다"
+
+#: src/selinux.c:125
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "%s의 컨텍스트를 복원할 수 없습니다"
+
+#: src/selinux.c:165
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "%s을(를) 열 수 없어 tty의 레이블을 다시 지정하지 않습니다"
+
+#: src/selinux.c:173
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "현재 tty 컨텍스트를 가져올 수 없어 tty의 레이블을 다시 지정하지 않습니다"
+
+#: src/selinux.c:180
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "\"chr_file\"의 보안 등급을 알 수 없어, tty의 레이블을 다시 지정하지 않습니다"
+
+#: src/selinux.c:185
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "새 tty 컨텍스트를 가져올 수 없습니다."
+
+#: src/selinux.c:192
+msgid "unable to set new tty context"
+msgstr "새 tty 컨텍스트를 설정할 수 없습니다"
+
+#: src/selinux.c:256
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "%s 유형의 역할을 지정해야 합니다"
+
+#: src/selinux.c:262
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "%s 역할의 기본 유형을 가져올 수 없습니다"
+
+#: src/selinux.c:280
+#, c-format
+msgid "failed to set new role %s"
+msgstr "새 %s 역할 설정에 실패했습니다."
+
+#: src/selinux.c:284
+#, c-format
+msgid "failed to set new type %s"
+msgstr "새 %s 유형 설정에 실패했습니다"
+
+#: src/selinux.c:296
+#, c-format
+msgid "%s is not a valid context"
+msgstr "올바르지 않은 %s 컨텍스트 입니다"
+
+#: src/selinux.c:331
+msgid "failed to get old_context"
+msgstr "old_context를 가져오기에 실패했습니다"
+
+#: src/selinux.c:337
+msgid "unable to determine enforcing mode."
+msgstr "강제 모드로 지정할 수 없습니다."
+
+#: src/selinux.c:354
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "tty 컨텍스트를 %s(으)로 설정할 수 없습니다"
+
+#: src/selinux.c:393
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "exec 컨텍스트를 %s(으)로 설정할 수 없습니다"
+
+#: src/selinux.c:400
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "키 생성 컨텍스트를 %s(으)로 설정할 수 없습니다"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "최소한 하나의 인자가 필요합니다"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "잘못된 파일 서술자 번호: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "%s(을)를 로그인 쉘로 실행할 수 없습니다"
+
+#: src/sesh.c:125 src/sudo.c:1305
+#, c-format
+msgid "unable to execute %s"
+msgstr "%s을(를) 실행할 수 없습니다"
+
+#: src/signal.c:69
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "%d 시그널의 핸들러를 저장할 수 없습니다"
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "자원 처리 한계에 도달했습니다"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "\"%s\" 사용자는 \"%s\" 프로젝트의 구성원이 아닙니다"
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr "실행 작업이 마지막입니다"
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "\"%s\" 프로젝트에 참여할 수 없습니다"
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "어떤 자원 풀에서도 \"%s\" 프로젝트에 있는 기본 바인딩을 수용하지 않습니다"
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "\"%s\" 프로젝트에 지정한 자원 풀이 없습니다"
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "\"%s\" 프로젝트에 기본 자원 풀을 바인딩할 수 없습니다"
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "\"%s\" 프로젝트에서 setproject에 실패했습니다"
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "경고! \"%s\" 프로젝트에 자원 처리 할당에 실패했습니다"
+
+#: src/sudo.c:212
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "sudo 버전 %s\n"
+
+#: src/sudo.c:214
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "설정 옵션: %s\n"
+
+#: src/sudo.c:222
+msgid "fatal error, unable to load plugins"
+msgstr "치명적인 오류. 플러그인을 불러올 수 없습니다"
+
+#: src/sudo.c:230
+msgid "unable to initialize policy plugin"
+msgstr "정책 플러그인을 초기화할 수 없습니다"
+
+#: src/sudo.c:274
+msgid "plugin did not return a command to execute"
+msgstr "플러그인에서 실행할 명령을 반환하지 않았습니다"
+
+#: src/sudo.c:290
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "%s 입출력 플러그인 초기화 오류"
+
+#: src/sudo.c:316
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "예상치 못한 sudo 모드 0x%x"
+
+#: src/sudo.c:468
+msgid "unable to get group vector"
+msgstr "그룹 벡터를 가져올 수 없습니다"
+
+#: src/sudo.c:530
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "알 수 없는 %u: 누구일까요?"
+
+#: src/sudo.c:586
+msgid "unable to determine tty"
+msgstr "tty를 지정할 수 없습니다"
+
+#: src/sudo.c:874
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s은(는) %d uid를 소유해야 하며 setuid 비트를 설정해야 합니다"
+
+#: src/sudo.c:877
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "%d은(는) 유효한 uid가 아닙니다. %s은(는) 'nosuid' 옵션을 설정한 파일 시스템이거나 루트 권한이 없는 NFS 파일 시스템입니까?"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "%d은(는) 유효한 uid가 아닙니다. sudo에 setuid root를 설치했습니까?"
+
+#: src/sudo.c:964
+msgid "unable to set supplementary group IDs"
+msgstr "추가 그룹 ID를 설정할 수 없습니다"
+
+#: src/sudo.c:971
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "유효한 gid를 %u 실행 gid로 설정할 수 없습니다"
+
+#: src/sudo.c:977
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "gid를 실행 gid %u(으)로 설정할 수 없습니다"
+
+#: src/sudo.c:1048
+#, c-format
+msgid "unknown login class %s"
+msgstr "알 수 없는 로그인 클래스 %s"
+
+#: src/sudo.c:1061
+msgid "unable to set user context"
+msgstr "사용자 컨텍스트를 설정할 수 없습니다."
+
+#: src/sudo.c:1077
+msgid "unable to set process priority"
+msgstr "프로세스 우선순위를 설정할 수 없습니다"
+
+#: src/sudo.c:1085
+#, c-format
+msgid "unable to change root to %s"
+msgstr "루트를 %s(으)로 바꿀 수 없습니다"
+
+#: src/sudo.c:1098 src/sudo.c:1104 src/sudo.c:1111
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "실행 uid로 바꿀 수 없습니다 (%u, %u)"
+
+#: src/sudo.c:1129
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "%s 디렉터리로 바꿀 수 없습니다"
+
+#: src/sudo.c:1187
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "예상치 못한 하위 프로세스 중단 상태: %d"
+
+#: src/sudo.c:1333
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "%s 정책 플러그인에 `check_policy' 메서드가 빠졌습니다"
+
+#: src/sudo.c:1351
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "%s 정책 플러그인에서 권한 조회를 지원하지 않습니다"
+
+#: src/sudo.c:1368
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "%s 정책 플러그인에서 -v 옵션을 지원하지 않습니다"
+
+#: src/sudo.c:1383
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "%s 정책 플러그인에서 -k/-K 옵션을 지원하지 않습니다"
+
+#: src/sudo_edit.c:181 src/sudo_edit.c:270
+msgid "unable to restore current working directory"
+msgstr "현재 작업 디렉터리를 복원할 수 없습니다"
+
+#: src/sudo_edit.c:577 src/sudo_edit.c:689
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: 일반 파일 아님"
+
+#: src/sudo_edit.c:584
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: 심볼릭 링크 편집을 허용하지 않습니다"
+
+#: src/sudo_edit.c:587
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: 기록 가능한 디렉터리에서 파일 편집을 허용하지 않습니다"
+
+#: src/sudo_edit.c:620 src/sudo_edit.c:728
+#, c-format
+msgid "%s: short write"
+msgstr "%s: 기록 내용이 짧습니다"
+
+#: src/sudo_edit.c:690
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s 수정하지 않은 상태로 남음"
+
+#: src/sudo_edit.c:703 src/sudo_edit.c:889
+#, c-format
+msgid "%s unchanged"
+msgstr "%s 바꾸지 않음"
+
+#: src/sudo_edit.c:717 src/sudo_edit.c:739
+#, c-format
+msgid "unable to write to %s"
+msgstr "%s에 기록할 수 없습니다"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:737 src/sudo_edit.c:740
+#: src/sudo_edit.c:914 src/sudo_edit.c:918
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "%s에 편집 세션 내용 남음"
+
+#: src/sudo_edit.c:736
+msgid "unable to read temporary file"
+msgstr "임시 파일을 읽을 수 없습니다"
+
+#: src/sudo_edit.c:819
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: 내부 오류: 경로에 잘못된 파일"
+
+#: src/sudo_edit.c:821
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: 임시 파일을 만들 수 없습니다"
+
+#: src/sudo_edit.c:823 src/sudo_edit.c:921
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: 잘못된 오류 %d"
+
+#: src/sudo_edit.c:913
+msgid "unable to copy temporary files back to their original location"
+msgstr "원위치에 임시 파일을 복사할 수 없습니다"
+
+#: src/sudo_edit.c:917
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "원 위치에 임시 파일 일부를 복사할 수 없습니다"
+
+#: src/sudo_edit.c:961
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "uid를 루트로 바꿀 수 없습니다(%u)"
+
+#: src/sudo_edit.c:978
+msgid "plugin error: missing file list for sudoedit"
+msgstr "플러그인 오류: sudoedit에 파일 목록이 빠짐"
+
+#: src/sudo_edit.c:1019 src/sudo_edit.c:1032
+msgid "unable to read the clock"
+msgstr "클록을 읽을 수 없습니다"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr "존재하는 tty가 없으며 askpass 프로그램을 지정하지 않았습니다"
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "askpass 프로그램을 지정하지 않았습니다. SUDO_ASKPASS를 설정해보십시오"
+
+#: src/tgetpass.c:261
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "gid를 %u(으)로 설정할 수 없습니다"
+
+#: src/tgetpass.c:265
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "uid를 %u(으)로 설정할 수 없습니다"
+
+#: src/tgetpass.c:270
+#, c-format
+msgid "unable to run %s"
+msgstr "%s을(를) 실행할 수 없습니다"
+
+#: src/utmp.c:268
+msgid "unable to save stdin"
+msgstr "표준 입력을 저장할 수 없습니다"
+
+#: src/utmp.c:270
+msgid "unable to dup2 stdin"
+msgstr "표준 입력을 dup2 처리할 수 없습니다"
+
+#: src/utmp.c:273
+msgid "unable to restore stdin"
+msgstr "표준 입력을 복원할 수 없습니다"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "파이프 읽기 오류"
diff --git a/po/nb.mo b/po/nb.mo
new file mode 100644
index 0000000..7cab20a
--- /dev/null
+++ b/po/nb.mo
Binary files differ
diff --git a/po/nb.po b/po/nb.po
new file mode 100644
index 0000000..ce6036f
--- /dev/null
+++ b/po/nb.po
@@ -0,0 +1,973 @@
+# Norwegian bokmål translation of sudo.
+# This file is distributed under the same license as the sudo package.
+# Copyright (C) 2017 Free Software Foundation, Inc.
+# Todd C. Miller <Todd.Miller@courtesan.com>, 2011-2013.
+# Åka Sikrom <a4@hush.com>, 2014-2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo-1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-30 08:46+0100\n"
+"Last-Translator: Åka Sikrom <a4@hush.com>\n"
+"Language-Team: Norwegian Bokmaal <i18n-nb@lister.ping.uio.no>\n"
+"Language: nb\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"X-Generator: Poedit 1.8.7.1\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "klarte ikke å åpne brukerdatabase"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "klarte ikke å skifte til registeret «%s» for %s"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "klarte ikke å gjenopprette register"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "klarte ikke å tildele minne"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "Ukjent signal"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "ugyldig verdi"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "verdien er for stor"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "verdien er for liten"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "«%s» er en ugyldig Path-verdi i %s, linje %u"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "«%2$s» er en ugyldig verdi for %1$s i %3$s, linje %4$u"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "gruppekilden «%s» (i %s, linje %u) støttes ikke"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "«%s» er et ugyldig maskimalt antall grupper i %s, linje %u"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "klarte ikke å lage statistikk av %s"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "«%s» er ikke en vanlig fil"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "«%s» eies av uid %u, som skulle vært %u"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "«%s» kan overskrives av alle"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "«%s» kan overskrives av eiergruppa"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "klarte ikke å åpne %s"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "innloggingsklassen «%s» er ukjent"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "klarte ikke å velge brukerkontekst"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "klarte ikke å velge prosessprioritet"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "klarte ikke å endre rot til «%s»"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "klarte ikke å endre til runas uid (%u, %u)"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "klarte ikke å endre mappe til «%s»"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "klarte ikke å velge håndtering av signal %d"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "klarte ikke å fjerne PRIV_PROC_EXEC fra PRIV_LIMIT"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "feil under lesing fra sokkelpar"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "uforventet responstype i bak-kanalen: %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "klarte ikke å legge hendelse i kø"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "klarte ikke å velge styrende tty"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "klarte ikke å lage datarør"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "klarte ikke å motta melding fra forelder"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "klarte ikke å lage kopi av prosess"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "klarte ikke å kjøre «%s»"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "klarte ikke å gjenopprette tty-etikett"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "regeltillegg klarte ikke å starte økt"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "feil i hendelsesløkke"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "klarte ikke å gjenopprette håndtering av signal %d"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "klarte ikke å tildele pty"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "klarte ikke å lage sokkel"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "klarte ikke å sende melding til overvåkningsprosess"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "feil i «%s» linje %d under innlasting av tillegg «%s»"
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "«%s» må eies av uid %d"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "«%s» kan ikke være overskrivbar for andre enn eier"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "klarte ikke å laste inn «%s». %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "fant ikke symbol «%s» i %s"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "regeltypen «%d», som ble funnet i «%s», er ukjent"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "ukompatibel versjon av programtillegg %d (forventet %d) ble funnet i «%s»"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "regeltillegg «%s» i «%s» linje %d blir ignorert"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "du kan bare velge ett regeltillegg"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "duplikattillegg «%s» i «%s» linje %d blir ignorert"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "duplikattillegg «%s» for inn- og utdata i «%s» line %d blir ignorert"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "regeltillegget «%s» inneholder ikke en «check_policy»-metode"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "intern feil: %s er full"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "%s er et ugyldig miljøvariabel-navn"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "«-C» må brukes med et tallargument med en verdi på minst 3"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "du kan ikke velge både «-i» og «-s»"
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "du kan ikke velge både «-i» og «-E»"
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "valget «-E» er ugyldig i redigeringsmodus"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "du kan ikke velge miljøvariabler i redigeringsmodus"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "valget «-U» kan ikke brukes uten «-l»"
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "valgene «-A» og «-S» kan ikke brukes samtidig"
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit støttes ikke på denne plattformen"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Du kan bare velge ett av valgene -e, -h, -i, -K, -l, -s, -v eller -V"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - rediger filer som om du var en annen bruker\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - kjør en kommando som om du var en annen bruker\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Valg:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "bruk et hjelpeprogram for å oppgi passord"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "bruk valgt BSD-autentiseringsmetode"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "kjør kommando i bakgrunnen"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "lukk alle fildeskriptorer >= num"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "kjør kommando med valgt BSD-innloggingsklasse"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "behold gjeldende brukermiljø når kommandoen kjøres"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "behold bestemte miljøvariabler"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "rediger filer i stedet for å kjøre en kommando"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "kjør kommando som om du var en del av valgt gruppe (-navn eller -ID)"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "bruk valgt brukers hjemmemappe som HOME-miljøvariabel"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "vis hjelpetekst og avslutt"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "kjør kommando på verten (hvis programtillegget støtter det)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "kjør innloggingsskall som om du var den valgte brukeren (du kan også oppgi en kommando her)"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "fjern tidsstempel-fil skikkelig"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "gjør tidsstempel-fil ugyldig"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "vis brukerens privilegier, eller sjekk om det fungerer å kjøre en bestemt kommando (bruk to ganger for å se et lengre format)"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "stillemodus (ingen ledetekst vises)"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "behold gruppevektor, i stedet for å bruke den som gjelder for målet"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "bruk valgt passord-ledetekst"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "lag SELinux-sikkerhetskontekst med valgt rolle"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "les passord fra standard inndata"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "kjør skall som valgt bruker (du kan også oppgi en kommando her)"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "lag SELinux-sikkerhetskontekst med valgt type"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "avslutt kommando etter valgt tidsfrist"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "vis brukerprivilegier (i listemodus)"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "kjør kommando (eller rediger fil) som valgt brukernavn eller bruker-ID"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "vis programversjon og avslutt"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "oppdater brukerens tidsstempel uten å kjøre en kommando"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "slutt å behandle kommandolinje-argumenter"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "klarte ikke å åpne revisjonssystemet"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "klarte ikke å sende revisjonsmelding"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "klarte ikke å utføre fgetfilecon %s"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s endret etiketter"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "klarte ikke å gjenopprette kontekst for «%s»"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "klarte ikke å åpne «%s». tty får ikke ny etikett"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s er ikke en tegnenhet. tty får ikke ny etikett"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "klarte ikke å hente gjeldende tty-kontekst. tty får ikke ny etikett"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "«chr_file» er ugyldig sikkerhetsklasse. tty får ikke ny etikett"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "klrate ikke å hente ny tty-kontekst. tty får ikke ny etikett"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "klarte ikke å velge ny tty-kontekst"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "du må velge en rolle for typen «%s»"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "klarte ikke å hente standardtype for rollen «%s»"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "klarte ikke å velge den nye rollen «%s»"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "klarte ikke å velge den nye typen «%s»"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "«%s» er en ugyldig kontekst"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "klarte ikke å hente «old_context»"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "klarte ikke å finne håndhevelsesmodus."
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "klarte ikke å velge «%s» som tty-kontekst"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "klarte ikke å velge «%s» som kjørekontekst"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "klarte ikke å velge «%s» som nøkkelkontekst"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "krever at du bruker minst ett argument"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "ugyldig fildeskriptor-tall: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "klarte ikke å kjøre %s som et innloggingsskall"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "klarte ikke å lagre håndtering av signal %d"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "kontrollgrensen for ressurser er nådd"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "brukeren «%s» er ikke medlem av prosjektet «%s»"
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "den kallende oppgaven er endelig"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "klarte ikke å bli med i prosjektet «%s»"
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "det er ingen ressursgrunnlag som godtar standardtildelinger for prosjektet «%s»"
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "fant ikke valgt ressursgrunnlag for prosjetet «%s»"
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "klarte ikke å tildele standard ressursgrunnlag for prosjektet «%s»"
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "klarte ikke å utføre «setproject» på «%s»"
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "advarsel: noe gikk galt ved tildeling av ressurskontroll for prosjektet «%s»"
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo versjon %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Velg innstillinger: %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "kritisk feil: klarte ikke å laste inn tilleggsprogrammer"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "klarte ikke å starte opp regeltillegg"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "tillegget sendte ikke en kjørbar kommando"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "feil under klargjøring av inn-/utdatatillegget «%s»"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "uforventet sudo-modus 0x%x"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "du finnes ikke i databasen %s"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "fant ikke gjeldende tty"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "«%s» må eies av uid %d, og setuid-biten må være valgt"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "effektiv uid er ikke %d. Er «%s» på et filsystem hvor «nosuid» er valgt, eller på et NFS-filsystem uten rot-rettigheter?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "effektiv uid er ikke %d. Er sudo installert med «setuid root»?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "klarte ikke å velge ekstra grruppe-id-er"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "klarte ikke å velge «runas gid %u» som effektiv gid"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "klarte ikke å velge «runas gid %u» som gid"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "uforventet årsak for avslutning av underprosess: %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "regeltillegget «%s» mangler «check_policy»-metoden"
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "regeltillegget «%s» støtter ikke listetillatelser"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "regeltillegget «%s» støtter ikke valget «-v»"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "regeltillegget «%s» støtter ikke valgene «-k» og «-K»"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "fant ingen midlertidig mappe med skrivetillatelse"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "klarte ikke å gjenopprette gjeldende arbeidsmappe"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "«%s» er ikke en vanlig fil"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: redigering av symbolske lenker tillates ikke"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: redigering av filer i en mappe med skrivetilgang tillates ikke"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "«%s» har kort skriving"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "«%s» ble uendret"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "«%s» er uendret"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "klarte ikke å skrive til «%s»"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "innhold fra redigeringsøkt ligger igjen i «%s»"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "klarte ikke å lese midlertidig fil"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: intern feil: for høyt antall stier"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: klarte ikke å lage midlertidige filer"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: ukjent feil (%d)"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "klarte ikke å kopiere midlertidige filer tilbake til opprinnelig plassering"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "klarte ikke å kopiere enkelte midlertidige filer tilbake til opprinnelig plassering"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "klarte ikke å endre uid til root (%u)"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "feil med tillegg: sudoedit mangler filliste"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "klarte ikke å lese klokka"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "tidsavbrudd under lesing av passord"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "du skrev ikke inn passord"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "klarte ikke å lese passord"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "ingen tty er tilgjengelig, og intet program for passord-etterspørsel er valgt"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "intet program for passord-etterspørsel er valgt. Prøv å velge «SUDO_ASKPASS»"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "klarte ikke å velge %u som gid"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "klarte ikke å velge %u som uid"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "klarte ikke å kjøre «%s»"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "klarte ikke å lagre standard innkanal"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "klarte ikke å utføre «dup2 stdin»"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "klarte ikke å gjenopprette standard innkanal"
+
+#~ msgid "unable to get group vector"
+#~ msgstr "klarte ikke å hente gruppevektor"
+
+#~ msgid "unknown uid %u: who are you?"
+#~ msgstr "UID %u er ukjent. Hvem er du?"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "feil under lesing fra signalrør"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "feil under lesing fra datarør"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "klarte ikke å sette terminal i råmodus"
+
+#~ msgid "internal error, tried allocate zero bytes"
+#~ msgstr "intern feil: prøvde å tildele tomme byte"
+
+#~ msgid "unable to open socket"
+#~ msgstr "klarte ikke å åpne sokkelen"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "intern feil: prøvde emalloc2(0)"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "intern feil: prøvde ecalloc(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "intern feil: prøvde erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "intern feil: prøvde erealloc3(0)"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "intern feil: prøvde erecalloc(0)"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: overbelastet"
diff --git a/po/nl.mo b/po/nl.mo
new file mode 100644
index 0000000..dfb19ea
--- /dev/null
+++ b/po/nl.mo
Binary files differ
diff --git a/po/nl.po b/po/nl.po
new file mode 100644
index 0000000..9f816df
--- /dev/null
+++ b/po/nl.po
@@ -0,0 +1,856 @@
+# Dutch translation for sudo.
+# Copyright (C) 2013 P. Hamming
+# This file is distributed under the same license as the sudo package.
+# P. Hamming <peterhamming@gmail.com>, 2013
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.12b1\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2014-10-27 12:35-0600\n"
+"PO-Revision-Date: 2015-01-14 02:50+0100\n"
+"Last-Translator: P. Hamming <peterhamming@gmail.com>\n"
+"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
+"Language: nl\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: lib/util/aix.c:92 lib/util/aix.c:151
+msgid "unable to open userdb"
+msgstr "kan userdb niet openen"
+
+#: lib/util/aix.c:156
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "kan niet wijzigen naar register \"%s\" voor %s"
+
+#: lib/util/aix.c:175
+msgid "unable to restore registry"
+msgstr "kan register niet herstellen"
+
+#: lib/util/alloc.c:68 lib/util/alloc.c:85 lib/util/alloc.c:106
+#: lib/util/alloc.c:128 lib/util/alloc.c:147 lib/util/alloc.c:170
+msgid "internal error, tried allocate zero bytes"
+msgstr "interne fout, heb geprobeerd om zero bytes te alloceren"
+
+#: lib/util/alloc.c:87 lib/util/alloc.c:109 lib/util/alloc.c:149
+#: lib/util/alloc.c:172 src/net_ifs.c:174 src/net_ifs.c:191 src/net_ifs.c:325
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "interne fout, %s overloop"
+
+#: lib/util/gidlist.c:78 src/load_plugins.c:61 src/load_plugins.c:74
+#: src/sudo.c:572 src/sudo.c:591 src/sudo.c:618 src/sudo.c:627 src/sudo.c:636
+#: src/sudo.c:653 src/sudo.c:700 src/sudo.c:710
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/strsignal.c:50
+msgid "Unknown signal"
+msgstr "Onbekend signaal"
+
+#: lib/util/strtoid.c:83 lib/util/strtoid.c:111 lib/util/strtomode.c:55
+#: lib/util/strtonum.c:65 lib/util/strtonum.c:183
+msgid "invalid value"
+msgstr "ongeldige waarde"
+
+#: lib/util/strtoid.c:90 lib/util/strtoid.c:118 lib/util/strtomode.c:61
+#: lib/util/strtonum.c:68 lib/util/strtonum.c:195
+msgid "value too large"
+msgstr "waarde te groot"
+
+#: lib/util/strtoid.c:96 lib/util/strtomode.c:61 lib/util/strtonum.c:68
+#: lib/util/strtonum.c:189
+msgid "value too small"
+msgstr "waarde te klein"
+
+#: lib/util/sudo_conf.c:181
+#, c-format
+msgid "invalid Path value `%s' in %s, line %u"
+msgstr "ongeldige lokatie '%s' in %s, regel %u"
+
+#: lib/util/sudo_conf.c:335 lib/util/sudo_conf.c:388
+#, c-format
+msgid "invalid value for %s `%s' in %s, line %u"
+msgstr "ongeldige waarde voor %s '%s' in %s, regel %u"
+
+#: lib/util/sudo_conf.c:356
+#, c-format
+msgid "unsupported group source `%s' in %s, line %u"
+msgstr "niet-ondersteunde brongroup '%s' in %s, regel %u"
+
+#: lib/util/sudo_conf.c:372
+#, c-format
+msgid "invalid max groups `%s' in %s, line %u"
+msgstr "ongeldig maximaal aantal groepen '%s' in %s, regel %u"
+
+#: lib/util/sudo_conf.c:522
+#, c-format
+msgid "unable to stat %s"
+msgstr "kan status niet opvragen van %s"
+
+#: lib/util/sudo_conf.c:525
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s geen regulier bestand"
+
+#: lib/util/sudo_conf.c:528
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s is eigendom van %u, moet gebruikersnummer %u zijn"
+
+#: lib/util/sudo_conf.c:532
+#, c-format
+msgid "%s is world writable"
+msgstr "%s kan door iedereen worden geschreven"
+
+#: lib/util/sudo_conf.c:535
+#, c-format
+msgid "%s is group writable"
+msgstr "%s kan door groep worden geschreven"
+
+#: lib/util/sudo_conf.c:545 src/selinux.c:196 src/selinux.c:209 src/sudo.c:341
+#, c-format
+msgid "unable to open %s"
+msgstr "kan %s niet openen"
+
+#: src/exec.c:123 src/exec.c:128 src/exec.c:423 src/exec.c:425 src/exec.c:427
+#: src/exec.c:429 src/exec.c:431 src/exec.c:433 src/exec.c:436 src/exec.c:453
+#: src/exec.c:455 src/exec.c:457 src/exec.c:605 src/exec.c:800
+#: src/exec_pty.c:480 src/exec_pty.c:736 src/exec_pty.c:806 src/exec_pty.c:808
+#: src/exec_pty.c:820 src/exec_pty.c:1308 src/exec_pty.c:1310
+#: src/exec_pty.c:1315 src/exec_pty.c:1317 src/exec_pty.c:1331
+#: src/exec_pty.c:1342 src/exec_pty.c:1344 src/exec_pty.c:1346
+#: src/exec_pty.c:1348 src/exec_pty.c:1350 src/exec_pty.c:1352
+#: src/exec_pty.c:1354 src/signal.c:156
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "instellen van handler voor signal %d is niet mogelijk"
+
+#: src/exec.c:135 src/exec_pty.c:845
+msgid "policy plugin failed session initialization"
+msgstr "beleidsplugin kon sessie niet initialiseren"
+
+#: src/exec.c:140 src/exec_pty.c:861 src/exec_pty.c:1392 src/tgetpass.c:221
+msgid "unable to fork"
+msgstr "kan geen nieuw proces starten"
+
+#: src/exec.c:318 src/exec.c:326 src/exec.c:877 src/exec_pty.c:604
+#: src/exec_pty.c:609 src/exec_pty.c:667 src/exec_pty.c:674 src/exec_pty.c:965
+#: src/exec_pty.c:975 src/exec_pty.c:1020 src/exec_pty.c:1027
+#: src/exec_pty.c:1457 src/exec_pty.c:1464 src/exec_pty.c:1471
+msgid "unable to add event to queue"
+msgstr "kan event niet toevoegen aan de wachtrij"
+
+#: src/exec.c:406
+msgid "unable to create sockets"
+msgstr "kan geen sockets maken"
+
+#: src/exec.c:502
+msgid "error in event loop"
+msgstr "fout in eventloop"
+
+#: src/exec.c:520
+msgid "unable to restore tty label"
+msgstr "kan terminallabel niet herstellen"
+
+#: src/exec.c:613 src/exec_pty.c:514 src/signal.c:95
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "kan handler voor signal %d niet herstellen"
+
+#: src/exec.c:731 src/exec_pty.c:1199
+msgid "error reading from signal pipe"
+msgstr "fout met het lezen van signaalpijp"
+
+#: src/exec_common.c:73
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "kan PRIV_PROC_EXEC niet verwijderen van PRIV_LIMIT"
+
+#: src/exec_pty.c:200
+msgid "unable to allocate pty"
+msgstr "kan geen virtuele terminal reserveren"
+
+#: src/exec_pty.c:780 src/exec_pty.c:789 src/exec_pty.c:797
+#: src/exec_pty.c:1300 src/exec_pty.c:1389 src/signal.c:137 src/tgetpass.c:218
+msgid "unable to create pipe"
+msgstr "kan geen pijp maken"
+
+#: src/exec_pty.c:836
+msgid "unable to set terminal to raw mode"
+msgstr "kan de terminal niet op de raw-modus instellen"
+
+#: src/exec_pty.c:1232
+msgid "error reading from pipe"
+msgstr "fout met lezen van pijp"
+
+#: src/exec_pty.c:1257
+msgid "error reading from socketpair"
+msgstr "fout met lezen van socketpaar"
+
+#: src/exec_pty.c:1266
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "onverwachte soort beantwoording van het achterkanaal: %d"
+
+#: src/exec_pty.c:1368
+msgid "unable to set controlling tty"
+msgstr "kan geen controlerende terminal instellen"
+
+#: src/load_plugins.c:59 src/load_plugins.c:72 src/load_plugins.c:89
+#: src/load_plugins.c:142 src/load_plugins.c:148 src/load_plugins.c:154
+#: src/load_plugins.c:195 src/load_plugins.c:202 src/load_plugins.c:209
+#: src/load_plugins.c:215
+#, c-format
+msgid "error in %s, line %d while loading plugin `%s'"
+msgstr "fout in %s, regel %d bij het initialiseren-I/O plug-in %s"
+
+#: src/load_plugins.c:91
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:150
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "eigenaar van %s moet uid %d zijn"
+
+#: src/load_plugins.c:156
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s mag alleen schrijfbaar zijn voor de eigenaar"
+
+#: src/load_plugins.c:197
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "kan %s niet laden: %s"
+
+#: src/load_plugins.c:204
+#, c-format
+msgid "unable to find symbol `%s' in %s"
+msgstr "kan symbool %s niet vinden in %s"
+
+#: src/load_plugins.c:211
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "onbekende beleidssoort %d gevonden in %s"
+
+#: src/load_plugins.c:217
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "niet-compatibel hoofdbeleidsversie %d, (verwachtte %d) gevonden in %s voor plugins"
+
+#: src/load_plugins.c:226
+#, c-format
+msgid "ignoring policy plugin `%s' in %s, line %d"
+msgstr "beleidsplugin '%s' in %s, regel %d wordt genegeerd"
+
+#: src/load_plugins.c:228
+msgid "only a single policy plugin may be specified"
+msgstr "slechts een beleidsplug-in mag geladen worden"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate policy plugin `%s' in %s, line %d"
+msgstr "dubbele beleidsplugin '%s' in %s, regel %d wordt genegeerd"
+
+#: src/load_plugins.c:249
+#, c-format
+msgid "ignoring duplicate I/O plugin `%s' in %s, line %d"
+msgstr "dubbele I/O-plugin '%s' in %s, regel %d wordt genegeerd"
+
+#: src/load_plugins.c:338
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "beleidsplug-in %s heeft geen check_policy methode"
+
+#: src/net_ifs.c:236
+msgid "unable to open socket"
+msgstr "kan geen socket openen"
+
+#: src/parse_args.c:241
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "het argument van -C moet een getal zijn dat groter dan of gelijk aan 3 is"
+
+#: src/parse_args.c:403
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "u mag de opties '-i' en '-s' niet tegelijk opgeven"
+
+#: src/parse_args.c:407
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "u mag de opties '-i' en '-E' niet tegelijk opgeven"
+
+#: src/parse_args.c:417
+msgid "the `-E' option is not valid in edit mode"
+msgstr "optie '-E' is niet geldig in bewerkingsmodus"
+
+#: src/parse_args.c:419
+msgid "you may not specify environment variables in edit mode"
+msgstr "u mag geen omgevingsvariabelen opgeven in de bewerkingsmodus"
+
+#: src/parse_args.c:427
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "optie '-U' mag alleen worden gebruikt samen met optie '-l'"
+
+#: src/parse_args.c:431
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "de opties '-A' en '-S' mogen niet tegelijk worden gebruikt"
+
+#: src/parse_args.c:497
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit wordt niet ondersteund op dit platform"
+
+#: src/parse_args.c:570
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Slechts een van de volgende opties mag worden gebruikt: -e, -h, -i, -K, -l, -s, -v of -V"
+
+#: src/parse_args.c:584
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - bewerk bestanden als een andere gebruiker\n"
+"\n"
+
+#: src/parse_args.c:586
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - voer een opdracht uit als een andere gebruiker\n"
+"\n"
+
+#: src/parse_args.c:591
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opties:\n"
+
+#: src/parse_args.c:593
+msgid "use a helper program for password prompting"
+msgstr "gebruik een hulpprogramma voor het vragen van wachtwoord"
+
+#: src/parse_args.c:596
+msgid "use specified BSD authentication type"
+msgstr "gebruik opgegeven BSD-verificatietype"
+
+#: src/parse_args.c:599
+msgid "run command in the background"
+msgstr "voer opdracht op de achtergrond uit"
+
+#: src/parse_args.c:601
+msgid "close all file descriptors >= num"
+msgstr "sluit alle file descriptors >= num"
+
+#: src/parse_args.c:604
+msgid "run command with the specified BSD login class"
+msgstr "voer opdracht uit met gespecificeerde BSD-inlogklasse"
+
+#: src/parse_args.c:607
+msgid "preserve user environment when running command"
+msgstr "behoud gebruikersomgeving bij uitvoeren van opdracht"
+
+#: src/parse_args.c:609
+msgid "edit files instead of running a command"
+msgstr "bewerk bestanden in plaats van uitvoeren van een opdracht"
+
+#: src/parse_args.c:611
+msgid "run command as the specified group name or ID"
+msgstr "voer opdracht uit als de opgegeven groep"
+
+#: src/parse_args.c:613
+msgid "set HOME variable to target user's home dir"
+msgstr "stel HOME variabele in om naar persoonlijke map van gebruiker te verwijzen"
+
+#: src/parse_args.c:615
+msgid "display help message and exit"
+msgstr "hulptekst tonen en stoppen"
+
+#: src/parse_args.c:617
+msgid "run command on host (if supported by plugin)"
+msgstr "voer opdracht uit op computer (enkel als plugin dit ondersteund)"
+
+#: src/parse_args.c:619
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "voer een inlogshell uit als beoogd gebruiker; een opdracht mag ook worden opgegeven"
+
+#: src/parse_args.c:621
+msgid "remove timestamp file completely"
+msgstr "verwijder tijdbestand volledig"
+
+#: src/parse_args.c:623
+msgid "invalidate timestamp file"
+msgstr "maak tijdbestand ongeldig"
+
+#: src/parse_args.c:625
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "geef privileges van gebruiker weer of controleer specifieke opdracht; gebuik twee keer voor uitgebreidere opmaak"
+
+#: src/parse_args.c:627
+msgid "non-interactive mode, no prompts are used"
+msgstr "niet-interactieve modus, geen interactie met gebruiker"
+
+#: src/parse_args.c:629
+msgid "preserve group vector instead of setting to target's"
+msgstr "behoud groepsvector in plaats van die van het doel in te stellen"
+
+#: src/parse_args.c:631
+msgid "use the specified password prompt"
+msgstr "gebruik gespecifeerde wachtwoordvraag"
+
+#: src/parse_args.c:634
+msgid "create SELinux security context with specified role"
+msgstr "maak SELinux beveiligingscontext met gespecificeerde rol aan"
+
+#: src/parse_args.c:637
+msgid "read password from standard input"
+msgstr "lees wachtwoord van standaardinvoer"
+
+#: src/parse_args.c:639
+msgid "run shell as the target user; a command may also be specified"
+msgstr "voer shell uit als doelgebruiker; een opdracht mag ook worden opgegeven"
+
+#: src/parse_args.c:642
+msgid "create SELinux security context with specified type"
+msgstr "maak SELinux beveiligingscontext met gespecificeerde type aan"
+
+#: src/parse_args.c:645
+msgid "in list mode, display privileges for user"
+msgstr "in lijstmodus, geef privileges voor gebruiker weer"
+
+#: src/parse_args.c:647
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "voer opdracht uit (of bewerk bestand) als gespecificeerde gebruiker"
+
+#: src/parse_args.c:649
+msgid "display version information and exit"
+msgstr "versie-informatie tonen en stoppen"
+
+#: src/parse_args.c:651
+msgid "update user's timestamp without running a command"
+msgstr "werk tijd van gebruiker bij zonder opdracht uit te voeren"
+
+#: src/parse_args.c:653
+msgid "stop processing command line arguments"
+msgstr "stop verwerken opdrachtregelargumenten"
+
+#: src/selinux.c:77
+msgid "unable to open audit system"
+msgstr "kan audit-systeem niet openen"
+
+#: src/selinux.c:85
+msgid "unable to send audit message"
+msgstr "kan audit-melding niet verzenden"
+
+#: src/selinux.c:113
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "fgetfilecon %s mislukt"
+
+#: src/selinux.c:118
+#, c-format
+msgid "%s changed labels"
+msgstr "%s gewijzigde labels"
+
+#: src/selinux.c:123
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "kan context voor %s niet herstellen"
+
+#: src/selinux.c:163
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "kan %s niet openen, terminaltitel wordt niet opnieuw ingesteld"
+
+#: src/selinux.c:172
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "kan huidige terminalcontext niet verkrijgen, terminaltitel wordt niet opniew ingesteld"
+
+#: src/selinux.c:179
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "kan geen nieuwe terminalcontext verkrijgen, terminaltitel wordt niet opnieuw ingesteld"
+
+#: src/selinux.c:186
+msgid "unable to set new tty context"
+msgstr "kan nieuwe terminalcontext niet instellen"
+
+#: src/selinux.c:252
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "u moet een rol kiezen voor type %s"
+
+#: src/selinux.c:258
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "kan standaard-type niet verkrijgen voor rol %s"
+
+#: src/selinux.c:276
+#, c-format
+msgid "failed to set new role %s"
+msgstr "instellen van nieuwe rol %s mislukt"
+
+#: src/selinux.c:280
+#, c-format
+msgid "failed to set new type %s"
+msgstr "instellen van nieuw type %s mislukt"
+
+#: src/selinux.c:289
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s is geen geldige context"
+
+#: src/selinux.c:324
+msgid "failed to get old_context"
+msgstr "verkrijgen old_context mislukt"
+
+#: src/selinux.c:330
+msgid "unable to determine enforcing mode."
+msgstr "kan afdwingende modus niet vinden."
+
+#: src/selinux.c:347
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "kan terminalcontext niet instellen voor %s"
+
+#: src/selinux.c:386
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "kan uitvoeringscontext niet instellen op %s"
+
+#: src/selinux.c:393
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "kan context voor aanmaak van sleutels niet instellen op %s"
+
+#: src/sesh.c:80
+msgid "requires at least one argument"
+msgstr "tenminste één argument vereist"
+
+#: src/sesh.c:109
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "kan %s niet uitvoeren als een loginshell"
+
+#: src/sesh.c:114 src/sudo.c:1186
+#, c-format
+msgid "unable to execute %s"
+msgstr "kan %s niet uitvoeren"
+
+#: src/signal.c:77
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "kan handler niet opslaan naar signaal %d"
+
+#: src/solaris.c:88
+msgid "resource control limit has been reached"
+msgstr "hulpbroncontrolelimiet is bereikt"
+
+#: src/solaris.c:91
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "gebruiker \"%s\" is geen lid van project \"%s\""
+
+#: src/solaris.c:95
+msgid "the invoking task is final"
+msgstr "de aanroepende taak is klaar"
+
+#: src/solaris.c:98
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "kan project \"%s\" niet samenvoegen"
+
+#: src/solaris.c:103
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "er bestaat geen hulpbronnengroep voor project \"%s\" die de standaardbindingen accepteert"
+
+#: src/solaris.c:107
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "er bestaat geen hulpbronnengroep voor project \"%s\" die de standaardbindingen accepteert"
+
+#: src/solaris.c:111
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "kan niet verbinden met standaard hulpbronnen voor project \"%s\""
+
+#: src/solaris.c:117
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "setproject mislukt voor project \"%s\""
+
+#: src/solaris.c:119
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "waarschuwing, hulpbrontoewijzingscontrole mislukt voor project \"%s\""
+
+#: src/sudo.c:209
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo versie %s\n"
+
+#: src/sudo.c:211
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Configuratieopties: %s\n"
+
+#: src/sudo.c:216
+msgid "fatal error, unable to load plugins"
+msgstr "fatale fout, kan geen plug-ins laden"
+
+#: src/sudo.c:224
+msgid "unable to initialize policy plugin"
+msgstr "kan beleidsplug-in niet instellen"
+
+#: src/sudo.c:280
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "fout bij initialiseren-I/O plug-in %s"
+
+#: src/sudo.c:306
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "onverwachte sudo modus 0x%x"
+
+#: src/sudo.c:426
+msgid "unable to get group vector"
+msgstr "kan groepsvector niet verkrijgen"
+
+#: src/sudo.c:478
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "onbekende uid %u: wie bent u?"
+
+#: src/sudo.c:785
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "eigenaar van %s moet gebruikersnummer %d zijn en de setuid bit ingesteld"
+
+#: src/sudo.c:788
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "gebruikt gebruikersnummer is niet %d, is %s op een bestandssysteem met de 'nosuid' optie ingesteld of een NFS bestandssysteem zonder rootrechten?"
+
+#: src/sudo.c:794
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "gebruikt gebruikersnummer is niet %d, is sudo geinstalleerd met setuid root?"
+
+#: src/sudo.c:923
+#, c-format
+msgid "unknown login class %s"
+msgstr "onbekende inlog-klasse %s"
+
+#: src/sudo.c:936
+msgid "unable to set user context"
+msgstr "kan gebruikerscontext niet instellen"
+
+#: src/sudo.c:950
+msgid "unable to set supplementary group IDs"
+msgstr "kan aanvullende groeps-ID's niet instellen"
+
+#: src/sudo.c:957
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "kan effectieve gid niet instellen op runas-gid %u"
+
+#: src/sudo.c:963
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "kan gid niet instellen op runas-gid %u"
+
+#: src/sudo.c:970
+msgid "unable to set process priority"
+msgstr "kan taakprioriteit niet instellen"
+
+#: src/sudo.c:978
+#, c-format
+msgid "unable to change root to %s"
+msgstr "kan root niet wijzigen naar %s"
+
+#: src/sudo.c:991 src/sudo.c:997 src/sudo.c:1003
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "kan niet wijzigen naar runas uid (%u, %u)"
+
+#: src/sudo.c:1021
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "kan map niet wijzigen naar %s"
+
+#: src/sudo.c:1082
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "onverwachte dochter-afsluitvoorwaarde: %d"
+
+#: src/sudo.c:1214
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "beleidsplug-in %s heeft geen check_policy methode"
+
+#: src/sudo.c:1232
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "beleidsplug-in %s ondersteunt niet het tonen van privileges"
+
+#: src/sudo.c:1249
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "beleidsplug-in %s ondersteunt niet de -v optie"
+
+#: src/sudo.c:1264
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "beleidsplug-in %s ondersteunt niet de -k/-K opties"
+
+#: src/sudo_edit.c:203 src/sudo_edit.c:294
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: geen regulier bestand"
+
+#: src/sudo_edit.c:230 src/sudo_edit.c:332
+#, c-format
+msgid "%s: short write"
+msgstr "%s: te weinig geschreven"
+
+#: src/sudo_edit.c:295
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s ongewijzigd gelaten"
+
+#: src/sudo_edit.c:308 src/sudo_edit.c:483
+#, c-format
+msgid "%s unchanged"
+msgstr "%s ongewijzigd"
+
+#: src/sudo_edit.c:321 src/sudo_edit.c:343
+#, c-format
+msgid "unable to write to %s"
+msgstr "kan niet schrijven naar %s"
+
+#: src/sudo_edit.c:322 src/sudo_edit.c:341 src/sudo_edit.c:344
+#: src/sudo_edit.c:508 src/sudo_edit.c:512
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "inhoud van bewerkingssessie achtergelaten in %s"
+
+#: src/sudo_edit.c:340
+msgid "unable to read temporary file"
+msgstr "kan tijdelijk bestand niet lezen"
+
+#: src/sudo_edit.c:417
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: interne fout: oneven aantal paden"
+
+#: src/sudo_edit.c:419
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: kan geen tijdelijke bestanden aanmaken "
+
+#: src/sudo_edit.c:421 src/sudo_edit.c:515
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: onbekende fout %d"
+
+#: src/sudo_edit.c:507
+msgid "unable to copy temporary files back to their original location"
+msgstr "kan tijdelijke bestanden niet terugzetten naar de oorsprongelijke lokatie"
+
+#: src/sudo_edit.c:511
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "kan sommige tijdelijke bestanden niet terugzetten naar de oorsprongelijke lokatie"
+
+#: src/sudo_edit.c:554
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "kan uid niet wijzigen naar root (%u)"
+
+#: src/sudo_edit.c:571
+msgid "plugin error: missing file list for sudoedit"
+msgstr "plug-infout: missende bestandslijst voor sudoedit"
+
+#: src/tgetpass.c:90
+msgid "no tty present and no askpass program specified"
+msgstr "geen terminal aanwezig en geen wachtwoordvraag(askpass)-programma opgegeven"
+
+#: src/tgetpass.c:99
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "geen wachtwoordvraag(askpass)-programma opgegeven, probeer SUDO_ASKPASS in te stellen"
+
+#: src/tgetpass.c:232
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "kan gid niet instellen op %u"
+
+#: src/tgetpass.c:236
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "kan uid niet instellen op %u"
+
+#: src/tgetpass.c:241
+#, c-format
+msgid "unable to run %s"
+msgstr "kan %s niet uitvoeren"
+
+#: src/utmp.c:278
+msgid "unable to save stdin"
+msgstr "kan niet opslaan naar stdin"
+
+#: src/utmp.c:280
+msgid "unable to dup2 stdin"
+msgstr "kan dup2 niet uitvoeren op standaardinvoer"
+
+#: src/utmp.c:283
+msgid "unable to restore stdin"
+msgstr "kan stdin niet herstellen"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "interne fout, probeerde emalloc2(0)"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "interne fout, probeerde ecalloc(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "interne fout, probeerde erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "interne fout, probeerde erealloc3(0)"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "interne fout, probeerde erecalloc(0)"
+
+#~ msgid "value out of range"
+#~ msgstr "waarde buiten bereik"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "select failed"
+#~ msgstr "selecteren mislukt"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: overloop gevonden"
+
+#~ msgid "unable to allocate memory"
+#~ msgstr "kan geen geheugen reserveren"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "list user's available commands\n"
+#~ msgstr "geef voor gebruiker beschikbare opdrachten weer\n"
+
+#~ msgid "run a shell as target user\n"
+#~ msgstr "voer een shell uit als doel-gebruiker\n"
+
+#~ msgid "when listing, list specified user's privileges\n"
+#~ msgstr "bij listing, toon privileges van gespecificeerde gebruiker\n"
diff --git a/po/nn.mo b/po/nn.mo
new file mode 100644
index 0000000..d17effd
--- /dev/null
+++ b/po/nn.mo
Binary files differ
diff --git a/po/nn.po b/po/nn.po
new file mode 100644
index 0000000..14a8045
--- /dev/null
+++ b/po/nn.po
@@ -0,0 +1,934 @@
+# Norwegian Nynorsk translation of sudo.
+# This file is distributed under the same license as the sudo package.
+#
+# Karl Ove Hufthammer <karl@huftis.org>, 2016.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.18b4\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2016-08-31 05:48-0600\n"
+"PO-Revision-Date: 2016-09-04 19:09+0100\n"
+"Last-Translator: Karl Ove Hufthammer <karl@huftis.org>\n"
+"Language-Team: Norwegian Nynorsk <i18n-nn@lister.ping.uio.no>\n"
+"Language: nn\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Lokalize 2.0\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:172
+msgid "unable to open userdb"
+msgstr "klarte ikkje opna brukardatabase"
+
+#: lib/util/aix.c:227
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "klarte ikkje byta til registeret «%s» for %s"
+
+#: lib/util/aix.c:252
+msgid "unable to restore registry"
+msgstr "klarte ikkje gjenoppretta register"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:207 lib/util/sudo_conf.c:290 lib/util/sudo_conf.c:367
+#: lib/util/sudo_conf.c:569 src/conversation.c:75 src/exec.c:868
+#: src/exec_common.c:107 src/exec_common.c:123 src/exec_common.c:132
+#: src/exec_pty.c:692 src/exec_pty.c:700 src/exec_pty.c:1163
+#: src/load_plugins.c:52 src/load_plugins.c:65 src/load_plugins.c:215
+#: src/load_plugins.c:238 src/load_plugins.c:303 src/load_plugins.c:318
+#: src/parse_args.c:180 src/parse_args.c:202 src/parse_args.c:370
+#: src/parse_args.c:466 src/parse_args.c:485 src/preserve_fds.c:47
+#: src/preserve_fds.c:130 src/selinux.c:83 src/selinux.c:292 src/selinux.c:415
+#: src/selinux.c:424 src/sesh.c:115 src/sudo.c:399 src/sudo.c:418
+#: src/sudo.c:482 src/sudo.c:600 src/sudo.c:660 src/sudo.c:670 src/sudo.c:690
+#: src/sudo.c:709 src/sudo.c:718 src/sudo.c:727 src/sudo.c:744 src/sudo.c:785
+#: src/sudo.c:795 src/sudo.c:815 src/sudo.c:1236 src/sudo.c:1257
+#: src/sudo.c:1431 src/sudo.c:1525 src/sudo_edit.c:151 src/sudo_edit.c:773
+#: src/sudo_edit.c:870 src/sudo_edit.c:983 src/sudo_edit.c:1003
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/sudo_conf.c:208
+#: lib/util/sudo_conf.c:290 lib/util/sudo_conf.c:367 lib/util/sudo_conf.c:569
+#: src/conversation.c:76 src/exec.c:868 src/exec_common.c:107
+#: src/exec_common.c:124 src/exec_common.c:133 src/exec_pty.c:692
+#: src/exec_pty.c:700 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:180
+#: src/parse_args.c:202 src/parse_args.c:370 src/parse_args.c:466
+#: src/parse_args.c:485 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:83 src/selinux.c:292 src/selinux.c:415 src/selinux.c:424
+#: src/sesh.c:115 src/sudo.c:399 src/sudo.c:418 src/sudo.c:482 src/sudo.c:600
+#: src/sudo.c:815 src/sudo.c:1236 src/sudo.c:1257 src/sudo.c:1431
+#: src/sudo.c:1525 src/sudo_edit.c:151 src/sudo_edit.c:773 src/sudo_edit.c:870
+#: src/sudo_edit.c:983 src/sudo_edit.c:1003
+msgid "unable to allocate memory"
+msgstr "klarte ikkje tildela minne"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "Ukjent signal"
+
+#: lib/util/strtoid.c:76 lib/util/strtoid.c:104 lib/util/strtomode.c:48
+#: lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "ugyldig verdi"
+
+#: lib/util/strtoid.c:83 lib/util/strtoid.c:111 lib/util/strtomode.c:54
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "verdien er for stor"
+
+#: lib/util/strtoid.c:89 lib/util/strtomode.c:54 lib/util/strtonum.c:61
+#: lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "verdien er for liten"
+
+#: lib/util/sudo_conf.c:223
+#, fuzzy, c-format
+msgid "invalid Path value `%s' in %s, line %u"
+msgstr "«%s» er ein ugyldig Path-verdi i %s, linje %u"
+
+#: lib/util/sudo_conf.c:389 lib/util/sudo_conf.c:442
+#, fuzzy, c-format
+msgid "invalid value for %s `%s' in %s, line %u"
+msgstr "«%2$s» er ein ugyldig verdi for %1$s i %3$s, linje %4$u"
+
+#: lib/util/sudo_conf.c:410
+#, c-format
+msgid "unsupported group source `%s' in %s, line %u"
+msgstr "gruppekjelda «%s» (i %s, linje %u) er ikkje støtta"
+
+#: lib/util/sudo_conf.c:426
+#, fuzzy, c-format
+msgid "invalid max groups `%s' in %s, line %u"
+msgstr "«%s» er eit ugyldig maskimalt mengd grupper i %s, linje %u"
+
+#: lib/util/sudo_conf.c:585
+#, fuzzy, c-format
+msgid "unable to stat %s"
+msgstr "klarte ikkje laga statistikk av %s"
+
+#: lib/util/sudo_conf.c:588
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s er ikkje ei vanleg fil"
+
+#: lib/util/sudo_conf.c:591
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "«%s» er eigd av uid %u, som skulle vore %u"
+
+#: lib/util/sudo_conf.c:595
+#, c-format
+msgid "%s is world writable"
+msgstr "%s er skrivbar for alle"
+
+#: lib/util/sudo_conf.c:598
+#, c-format
+msgid "%s is group writable"
+msgstr "%s er skrivbar for eigargruppa"
+
+#: lib/util/sudo_conf.c:608 src/selinux.c:201 src/selinux.c:213 src/sudo.c:368
+#, c-format
+msgid "unable to open %s"
+msgstr "klarte ikkje opna %s"
+
+#: src/exec.c:115 src/exec.c:117 src/exec.c:122 src/exec.c:408 src/exec.c:410
+#: src/exec.c:412 src/exec.c:414 src/exec.c:416 src/exec.c:418 src/exec.c:421
+#: src/exec.c:437 src/exec.c:439 src/exec.c:600 src/exec.c:795
+#: src/exec_pty.c:464 src/exec_pty.c:730 src/exec_pty.c:800 src/exec_pty.c:802
+#: src/exec_pty.c:814 src/exec_pty.c:816 src/exec_pty.c:1346
+#: src/exec_pty.c:1348 src/exec_pty.c:1353 src/exec_pty.c:1355
+#: src/exec_pty.c:1369 src/exec_pty.c:1380 src/exec_pty.c:1382
+#: src/exec_pty.c:1384 src/exec_pty.c:1386 src/exec_pty.c:1388
+#: src/exec_pty.c:1390 src/exec_pty.c:1392 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "klarte ikkje velja handtering av signal %d"
+
+#: src/exec.c:127 src/exec_pty.c:846 src/exec_pty.c:1430 src/tgetpass.c:259
+#, fuzzy
+msgid "unable to fork"
+msgstr "klarte ikkje laga kopi av prosess"
+
+#: src/exec.c:303 src/exec.c:311 src/exec.c:873 src/exec_pty.c:585
+#: src/exec_pty.c:590 src/exec_pty.c:660 src/exec_pty.c:667 src/exec_pty.c:954
+#: src/exec_pty.c:964 src/exec_pty.c:1009 src/exec_pty.c:1016
+#: src/exec_pty.c:1041 src/exec_pty.c:1495 src/exec_pty.c:1502
+#: src/exec_pty.c:1509
+msgid "unable to add event to queue"
+msgstr "klarte ikkje leggja hending i kø"
+
+#: src/exec.c:391
+msgid "unable to create sockets"
+msgstr "klarte ikkje laga socket-ar"
+
+#: src/exec.c:446
+#, fuzzy
+msgid "policy plugin failed session initialization"
+msgstr "regeltillegg klarte ikkje starta økt"
+
+#: src/exec.c:491
+msgid "error in event loop"
+msgstr "feil i hendingslykkje"
+
+#: src/exec.c:509
+msgid "unable to restore tty label"
+msgstr "klarte ikkje gjenoppretta tty-etikett"
+
+#: src/exec.c:608 src/exec_pty.c:496 src/signal.c:87
+#, fuzzy, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "klarte ikkje retta opp igjen handtering av signal %d"
+
+#: src/exec.c:726 src/exec_pty.c:1235
+msgid "error reading from signal pipe"
+msgstr "feil ved lesing frå signalrøyr"
+
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "klarte ikkje fjerna PRIV_PROC_EXEC frå PRIV_LIMIT"
+
+#: src/exec_pty.c:188
+msgid "unable to allocate pty"
+msgstr "klarte ikkje tildela pty"
+
+#: src/exec_pty.c:774 src/exec_pty.c:783 src/exec_pty.c:791
+#: src/exec_pty.c:1338 src/exec_pty.c:1427 src/signal.c:129 src/tgetpass.c:255
+msgid "unable to create pipe"
+msgstr "klarte ikkje laga datarøyr"
+
+#: src/exec_pty.c:1268
+msgid "error reading from pipe"
+msgstr "feil ved lesing frå datarøyr"
+
+#: src/exec_pty.c:1295
+msgid "error reading from socketpair"
+msgstr "feil ved lesing frå socketpar"
+
+#: src/exec_pty.c:1304
+#, fuzzy, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "uventa responstype i bak-kanalen: %d"
+
+#: src/exec_pty.c:1406
+msgid "unable to set controlling tty"
+msgstr "klarte ikkje velja styrande tty"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin `%s'"
+msgstr "feil i %s, linje %d ved lasting av tillegget «%s»"
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s må eigast av uid %d"
+
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s kan ikkje vera skrivbar for andre enn eigar"
+
+#: src/load_plugins.c:172
+#, fuzzy, c-format
+msgid "unable to load %s: %s"
+msgstr "klarte ikkje lasta inn «%s». %s"
+
+#: src/load_plugins.c:180
+#, fuzzy, c-format
+msgid "unable to find symbol `%s' in %s"
+msgstr "fann ikkje symbolet «%s» i %s"
+
+#: src/load_plugins.c:187
+#, fuzzy, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "regeltypen «%d», som vart funne i «%s», er ukjent"
+
+#: src/load_plugins.c:193
+#, fuzzy, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "ukompatibel versjon av programtillegg %d (forventa %d) vart funnen i «%s»"
+
+#: src/load_plugins.c:202
+#, fuzzy, c-format
+msgid "ignoring policy plugin `%s' in %s, line %d"
+msgstr "regeltillegg «%s» i «%s» linje %d vert ignorert"
+
+#: src/load_plugins.c:204
+#, fuzzy
+msgid "only a single policy plugin may be specified"
+msgstr "du kan berre velja eitt regeltillegg"
+
+#: src/load_plugins.c:207
+#, fuzzy, c-format
+msgid "ignoring duplicate policy plugin `%s' in %s, line %d"
+msgstr "duplikattillegget «%s» i «%s» linje %d vert ignorert"
+
+#: src/load_plugins.c:228
+#, fuzzy, c-format
+msgid "ignoring duplicate I/O plugin `%s' in %s, line %d"
+msgstr "duplikattillegget «%s» for inn- og utdata i «%s» line %d vert ignorert"
+
+#: src/load_plugins.c:331
+#, fuzzy, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "regeltillegget «%s» inneheld ikkje ein «check_policy»-metode"
+
+#: src/net_ifs.c:173 src/net_ifs.c:190 src/net_ifs.c:335 src/sudo.c:477
+#, fuzzy, c-format
+msgid "internal error, %s overflow"
+msgstr "intern feil: %s er full"
+
+#: src/parse_args.c:239
+#, fuzzy
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "«-C» må brukast med eit talargument med ein verdi på minst 3"
+
+#: src/parse_args.c:406
+#, fuzzy
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "du kan ikkje velja både «-i» og «-s»"
+
+#: src/parse_args.c:410
+#, fuzzy
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "du kan ikkje velja både «-i» og «-E»"
+
+#: src/parse_args.c:420
+#, fuzzy
+msgid "the `-E' option is not valid in edit mode"
+msgstr "valet «-E» er ugyldig i redigeringsmodus"
+
+#: src/parse_args.c:422
+#, fuzzy
+msgid "you may not specify environment variables in edit mode"
+msgstr "du kan ikkje velja miljøvariablar i redigeringsmodus"
+
+#: src/parse_args.c:430
+#, fuzzy
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "valet «-U» kan ikkje brukast utan «-l»"
+
+#: src/parse_args.c:434
+#, fuzzy
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "vala «-A» og «-S» kan ikkje verta samstundes brukt"
+
+#: src/parse_args.c:504
+#, fuzzy
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit vert ikkje støtta på denne plattforma"
+
+#: src/parse_args.c:577
+#, fuzzy
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Du kan berre velja eitt av vala -e, -h, -i, -K, -l, -s, -v eller -V"
+
+#: src/parse_args.c:591
+#, fuzzy, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - rediger filer som om du var ein annan nytter\n"
+"\n"
+
+#: src/parse_args.c:593
+#, fuzzy, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - køyr ein kommando som om du var ein annan nytter\n"
+"\n"
+
+#: src/parse_args.c:598
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Val:\n"
+
+#: src/parse_args.c:600
+#, fuzzy
+msgid "use a helper program for password prompting"
+msgstr "nytte eit hjelpeprogram for å oppgje passord"
+
+#: src/parse_args.c:603
+#, fuzzy
+msgid "use specified BSD authentication type"
+msgstr "nytte valt BSD-autentiseringsmetode"
+
+#: src/parse_args.c:606
+#, fuzzy
+msgid "run command in the background"
+msgstr "køyr kommando i bakgrunnen"
+
+#: src/parse_args.c:608
+#, fuzzy
+msgid "close all file descriptors >= num"
+msgstr "lukk alle fildeskriptorer >= num"
+
+#: src/parse_args.c:611
+#, fuzzy
+msgid "run command with the specified BSD login class"
+msgstr "køyr kommando med valt BSD-innloggingsklasse"
+
+#: src/parse_args.c:614
+#, fuzzy
+msgid "preserve user environment when running command"
+msgstr "hald på gjeldande brukarmiljø når kommandoen vert køyrt"
+
+#: src/parse_args.c:616
+#, fuzzy
+msgid "edit files instead of running a command"
+msgstr "rediger filer i staden for å køyra ein kommando"
+
+#: src/parse_args.c:618
+#, fuzzy
+msgid "run command as the specified group name or ID"
+msgstr "køyr kommando som om du var ein del av vald gruppe (-namn eller -ID)"
+
+#: src/parse_args.c:620
+#, fuzzy
+msgid "set HOME variable to target user's home dir"
+msgstr "nytte vald nytter sine hjemmemappe som HOME-miljøvariabel"
+
+#: src/parse_args.c:622
+#, fuzzy
+msgid "display help message and exit"
+msgstr "vis hjelpetekst og avslutt"
+
+#: src/parse_args.c:624
+#, fuzzy
+msgid "run command on host (if supported by plugin)"
+msgstr "køyr kommando på verten (viss programtillegget støttar det)"
+
+#: src/parse_args.c:626
+#, fuzzy
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "køyr innloggingsskall som om du var den valde brukaren (du kan òg oppgje ein kommando her)"
+
+#: src/parse_args.c:628
+#, fuzzy
+msgid "remove timestamp file completely"
+msgstr "fjern tidsstempel-fil skikkeleg"
+
+#: src/parse_args.c:630
+#, fuzzy
+msgid "invalidate timestamp file"
+msgstr "gjer tidsstempel-fil ugyldig"
+
+#: src/parse_args.c:632
+#, fuzzy
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "privilegia til vise brukaren, eller sjekk om det fungerer å køyra ein bestemd kommando (nytte to gonger for å sjå eit lengre format)"
+
+#: src/parse_args.c:634
+#, fuzzy
+msgid "non-interactive mode, no prompts are used"
+msgstr "stillemodus (ingen ledetekst vert vist)"
+
+#: src/parse_args.c:636
+#, fuzzy
+msgid "preserve group vector instead of setting to target's"
+msgstr "hald på gruppevektor, i staden for å bruka han som gjeld for målet"
+
+#: src/parse_args.c:638
+#, fuzzy
+msgid "use the specified password prompt"
+msgstr "nytte valt passord-ledetekst"
+
+#: src/parse_args.c:641
+#, fuzzy
+msgid "create SELinux security context with specified role"
+msgstr "lag SELinux-tryggleikskontekst med vald rolle"
+
+#: src/parse_args.c:644
+#, fuzzy
+msgid "read password from standard input"
+msgstr "les passord frå standard inndata"
+
+#: src/parse_args.c:646
+#, fuzzy
+msgid "run shell as the target user; a command may also be specified"
+msgstr "køyr skal som vald brukar (du kan òg oppgje ein kommando her)"
+
+#: src/parse_args.c:649
+#, fuzzy
+msgid "create SELinux security context with specified type"
+msgstr "lag SELinux-tryggleikskontekst med vald type"
+
+#: src/parse_args.c:652
+#, fuzzy
+msgid "in list mode, display privileges for user"
+msgstr "vis brukarprivilegium (i listemodus)"
+
+#: src/parse_args.c:654
+#, fuzzy
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "køyr kommando (eller rediger fil) som valt brukarnamn eller nytter-ID"
+
+#: src/parse_args.c:656
+#, fuzzy
+msgid "display version information and exit"
+msgstr "vis programversjon og avslutt"
+
+#: src/parse_args.c:658
+#, fuzzy
+msgid "update user's timestamp without running a command"
+msgstr "oppdater brukaren sin tidsstempel utan å køyra ein kommando"
+
+#: src/parse_args.c:660
+#, fuzzy
+msgid "stop processing command line arguments"
+msgstr "slutt å handsama kommandolinje-argument"
+
+#: src/selinux.c:77
+#, fuzzy
+msgid "unable to open audit system"
+msgstr "klarte ikkje opna revisjonssystemet"
+
+#: src/selinux.c:87
+#, fuzzy
+msgid "unable to send audit message"
+msgstr "klarte ikkje senda revisjonsmelding"
+
+#: src/selinux.c:115
+#, fuzzy, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "klarte ikkje utføra fgetfilecon %s"
+
+#: src/selinux.c:120
+#, fuzzy, c-format
+msgid "%s changed labels"
+msgstr "%s endra etikettar"
+
+#: src/selinux.c:125
+#, fuzzy, c-format
+msgid "unable to restore context for %s"
+msgstr "klarte ikkje retta opp igjen kontekst for «%s»"
+
+#: src/selinux.c:165
+#, fuzzy, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "klarte ikkje opna «%s». tty får ikkje ny etikett"
+
+#: src/selinux.c:173
+#, fuzzy
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "klarte ikkje henta gjeldande tty-kontekst. tty får ikkje ny etikett"
+
+#: src/selinux.c:180
+#, fuzzy
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "«chr_file» er ugyldig tryggleiksklasse. tty får ikkje ny etikett"
+
+#: src/selinux.c:185
+#, fuzzy
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "klrate ikkje henta ny tty-kontekst. tty får ikkje ny etikett"
+
+#: src/selinux.c:192
+#, fuzzy
+msgid "unable to set new tty context"
+msgstr "klarte ikkje velja ny tty-kontekst"
+
+#: src/selinux.c:256
+#, fuzzy, c-format
+msgid "you must specify a role for type %s"
+msgstr "du må velja ei rolle for typen «%s»"
+
+#: src/selinux.c:262
+#, fuzzy, c-format
+msgid "unable to get default type for role %s"
+msgstr "klarte ikkje henta standardtype for rollen «%s»"
+
+#: src/selinux.c:280
+#, fuzzy, c-format
+msgid "failed to set new role %s"
+msgstr "klarte ikkje velja den nye rollen «%s»"
+
+#: src/selinux.c:284
+#, fuzzy, c-format
+msgid "failed to set new type %s"
+msgstr "klarte ikkje velja den nye typen «%s»"
+
+#: src/selinux.c:296
+#, fuzzy, c-format
+msgid "%s is not a valid context"
+msgstr "«%s» er ein ugyldig kontekst"
+
+#: src/selinux.c:331
+#, fuzzy
+msgid "failed to get old_context"
+msgstr "klarte ikkje henta «old_context»"
+
+#: src/selinux.c:337
+#, fuzzy
+msgid "unable to determine enforcing mode."
+msgstr "klarte ikkje finna håndhevelsesmodus."
+
+#: src/selinux.c:354
+#, fuzzy, c-format
+msgid "unable to set tty context to %s"
+msgstr "klarte ikkje velja «%s» som tty-kontekst"
+
+#: src/selinux.c:393
+#, fuzzy, c-format
+msgid "unable to set exec context to %s"
+msgstr "klarte ikkje velja «%s» som kjørekontekst"
+
+#: src/selinux.c:400
+#, fuzzy, c-format
+msgid "unable to set key creation context to %s"
+msgstr "klarte ikkje velja «%s» som nøkkelkontekst"
+
+#: src/sesh.c:77
+#, fuzzy
+msgid "requires at least one argument"
+msgstr "krev at du brukar minst eitt argument"
+
+#: src/sesh.c:106
+#, fuzzy, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "ugyldig fildeskriptor-tal: %s"
+
+#: src/sesh.c:120
+#, fuzzy, c-format
+msgid "unable to run %s as a login shell"
+msgstr "klarte ikkje køyra %s som eit innloggingsskall"
+
+#: src/sesh.c:125 src/sudo.c:1295
+#, fuzzy, c-format
+msgid "unable to execute %s"
+msgstr "klarte ikkje køyra «%s»"
+
+#: src/signal.c:69
+#, fuzzy, c-format
+msgid "unable to save handler for signal %d"
+msgstr "klarte ikkje lagra handtering av signal %d"
+
+#: src/solaris.c:76
+#, fuzzy
+msgid "resource control limit has been reached"
+msgstr "kontrollgrensa for ressursar er nådd"
+
+#: src/solaris.c:79
+#, fuzzy, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "brukaren «%s» er ikkje medlem av prosjektet «%s»"
+
+#: src/solaris.c:83
+#, fuzzy
+msgid "the invoking task is final"
+msgstr "den kallande oppgåva er endeleg"
+
+#: src/solaris.c:86
+#, fuzzy, c-format
+msgid "could not join project \"%s\""
+msgstr "klarte ikkje verta med i prosjektet «%s»"
+
+#: src/solaris.c:91
+#, fuzzy, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "det er ingen ressursgrunnlag som godtek standardtildelinger for prosjektet «%s»"
+
+#: src/solaris.c:95
+#, fuzzy, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "fann ikkje valt ressursgrunnlag for prosjetet «%s»"
+
+#: src/solaris.c:99
+#, fuzzy, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "klarte ikkje tildela standard ressursgrunnlag for prosjektet «%s»"
+
+#: src/solaris.c:105
+#, fuzzy, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "klarte ikkje utføra «setproject» på «%s»"
+
+#: src/solaris.c:107
+#, fuzzy, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "åtvaring: noko gjekk gale ved tildeling av ressurskontroll for prosjektet «%s»"
+
+#: src/sudo.c:215
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo versjon %s\n"
+
+#: src/sudo.c:217
+#, fuzzy, c-format
+msgid "Configure options: %s\n"
+msgstr "Vel innstillingar: %s\n"
+
+#: src/sudo.c:225
+#, fuzzy
+msgid "fatal error, unable to load plugins"
+msgstr "kritisk feil: klarte ikkje lasta inn tilleggsprogram"
+
+#: src/sudo.c:233
+#, fuzzy
+msgid "unable to initialize policy plugin"
+msgstr "klarte ikkje starta opp regeltillegg"
+
+#: src/sudo.c:277
+#, fuzzy
+msgid "plugin did not return a command to execute"
+msgstr "tillegget sende ikkje ein kjørbar kommando"
+
+#: src/sudo.c:293
+#, fuzzy, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "feil under klargjøring av inn-/utdatatillegget «%s»"
+
+#: src/sudo.c:319
+#, fuzzy, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "uforventet sudo-modus 0x%x"
+
+#: src/sudo.c:462
+#, fuzzy
+msgid "unable to get group vector"
+msgstr "klarte ikkje henta gruppevektor"
+
+#: src/sudo.c:523
+#, fuzzy, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "UID %u er ukjend. Kven er du?"
+
+#: src/sudo.c:574
+msgid "unable to determine tty"
+msgstr ""
+
+#: src/sudo.c:864
+#, fuzzy, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "«%s» må eigast av uid %d, og setuid-biten må veljast"
+
+#: src/sudo.c:867
+#, fuzzy, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "effektiv uid er ikkje %d. Er «%s» på eit filsystem der «nosuid» er valt, eller på eit NFS-filsystem utan rot-rettar?"
+
+#: src/sudo.c:873
+#, fuzzy, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "effektiv uid er ikkje %d. Er sudo installert med «setuid root»?"
+
+#: src/sudo.c:954
+#, fuzzy
+msgid "unable to set supplementary group IDs"
+msgstr "klarte ikkje velja ekstra grruppe-id-er"
+
+#: src/sudo.c:961
+#, fuzzy, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "klarte ikkje velja «runa si gjev %u» som effektiv gjev"
+
+#: src/sudo.c:967
+#, fuzzy, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "klarte ikkje velja «runa si gjev %u» som gjev"
+
+#: src/sudo.c:1038
+#, fuzzy, c-format
+msgid "unknown login class %s"
+msgstr "innloggingsklassen «%s» er ukjend"
+
+#: src/sudo.c:1051
+#, fuzzy
+msgid "unable to set user context"
+msgstr "klarte ikkje velja brukarkontekst"
+
+#: src/sudo.c:1067
+#, fuzzy
+msgid "unable to set process priority"
+msgstr "klarte ikkje velja prosessprioritet"
+
+#: src/sudo.c:1075
+#, fuzzy, c-format
+msgid "unable to change root to %s"
+msgstr "klarte ikkje endra rot til «%s»"
+
+#: src/sudo.c:1088 src/sudo.c:1094 src/sudo.c:1101
+#, fuzzy, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "klarte ikkje endra til runa sine uid (%u, %u)"
+
+#: src/sudo.c:1119
+#, fuzzy, c-format
+msgid "unable to change directory to %s"
+msgstr "klarte ikkje endra mappe til «%s»"
+
+#: src/sudo.c:1177
+#, fuzzy, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "uforventet årsak for avslutning av underprosess: %d"
+
+#: src/sudo.c:1323
+#, fuzzy, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "regeltillegget «%s» manglar «check_policy»-metoden"
+
+#: src/sudo.c:1341
+#, fuzzy, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "regeltillegget «%s» støttar ikkje listeløyve"
+
+#: src/sudo.c:1358
+#, fuzzy, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "regeltillegget «%s» støttar ikkje valet «-v»"
+
+#: src/sudo.c:1373
+#, fuzzy, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "regeltillegget «%s» støttar ikkje vala «-k» og «-K»"
+
+#: src/sudo_edit.c:181 src/sudo_edit.c:270
+#, fuzzy
+msgid "unable to restore current working directory"
+msgstr "klarte ikkje retta opp igjen gjeldande arbeidsmappe"
+
+#: src/sudo_edit.c:576 src/sudo_edit.c:687
+#, fuzzy, c-format
+msgid "%s: not a regular file"
+msgstr "«%s» er ikkje ei vanleg fil"
+
+#: src/sudo_edit.c:583
+#, fuzzy, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: redigering av symbolske lenkjer vert ikkje tillate"
+
+#: src/sudo_edit.c:586
+#, fuzzy, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: redigering av filer i ei mappe med skrivetilgang vert ikkje tillate"
+
+#: src/sudo_edit.c:619 src/sudo_edit.c:726
+#, fuzzy, c-format
+msgid "%s: short write"
+msgstr "«%s» har kort skriving"
+
+#: src/sudo_edit.c:688
+#, fuzzy, c-format
+msgid "%s left unmodified"
+msgstr "«%s» vart uendra"
+
+#: src/sudo_edit.c:701 src/sudo_edit.c:887
+#, fuzzy, c-format
+msgid "%s unchanged"
+msgstr "«%s» er uendra"
+
+#: src/sudo_edit.c:715 src/sudo_edit.c:737
+#, fuzzy, c-format
+msgid "unable to write to %s"
+msgstr "klarte ikkje skriva til «%s»"
+
+#: src/sudo_edit.c:716 src/sudo_edit.c:735 src/sudo_edit.c:738
+#: src/sudo_edit.c:912 src/sudo_edit.c:916
+#, fuzzy, c-format
+msgid "contents of edit session left in %s"
+msgstr "innhald frå redigeringsøkt ligg igjen i «%s»"
+
+#: src/sudo_edit.c:734
+#, fuzzy
+msgid "unable to read temporary file"
+msgstr "klarte ikkje lesa mellombels fil"
+
+#: src/sudo_edit.c:817
+#, fuzzy
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: intern feil: for høgt mengd stiar"
+
+#: src/sudo_edit.c:819
+#, fuzzy
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: klarte ikkje laga mellombelse filer"
+
+#: src/sudo_edit.c:821 src/sudo_edit.c:919
+#, fuzzy, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: ukjend feil (%d)"
+
+#: src/sudo_edit.c:911
+#, fuzzy
+msgid "unable to copy temporary files back to their original location"
+msgstr "klarte ikkje kopiera mellombelse filer tilbake til opphavleg plassering"
+
+#: src/sudo_edit.c:915
+#, fuzzy
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "klarte ikkje kopiera enkelte mellombelse filer tilbake til opphavleg plassering"
+
+#: src/sudo_edit.c:959
+#, fuzzy, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "klarte ikkje endra uid til root (%u)"
+
+#: src/sudo_edit.c:976
+#, fuzzy
+msgid "plugin error: missing file list for sudoedit"
+msgstr "feil med tillegg: sudoedit manglar filliste"
+
+#: src/sudo_edit.c:1017 src/sudo_edit.c:1030
+#, fuzzy
+msgid "unable to read the clock"
+msgstr "klarte ikkje lesa klokka"
+
+#: src/tgetpass.c:107
+#, fuzzy
+msgid "no tty present and no askpass program specified"
+msgstr "ingen tty er tilgjengeleg, og inkje program for passord-etterspurnad er vald"
+
+#: src/tgetpass.c:116
+#, fuzzy
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "inkje program for passord-etterspurnad er vald. Prøv å velja «SUDO_ASKPASS»"
+
+#: src/tgetpass.c:270
+#, fuzzy, c-format
+msgid "unable to set gid to %u"
+msgstr "klarte ikkje velja %u som gjev"
+
+#: src/tgetpass.c:274
+#, fuzzy, c-format
+msgid "unable to set uid to %u"
+msgstr "klarte ikkje velja %u som uid"
+
+#: src/tgetpass.c:279
+#, fuzzy, c-format
+msgid "unable to run %s"
+msgstr "klarte ikkje køyra «%s»"
+
+#: src/utmp.c:268
+#, fuzzy
+msgid "unable to save stdin"
+msgstr "klarte ikkje lagra standard innkanal"
+
+#: src/utmp.c:270
+#, fuzzy
+msgid "unable to dup2 stdin"
+msgstr "klarte ikkje utføra «dup2 stdin»"
+
+#: src/utmp.c:273
+#, fuzzy
+msgid "unable to restore stdin"
+msgstr "klarte ikkje retta opp igjen standard innkanal"
diff --git a/po/pl.mo b/po/pl.mo
new file mode 100644
index 0000000..8fde088
--- /dev/null
+++ b/po/pl.mo
Binary files differ
diff --git a/po/pl.po b/po/pl.po
new file mode 100644
index 0000000..f3535ec
--- /dev/null
+++ b/po/pl.po
@@ -0,0 +1,924 @@
+# Polish translation for sudo.
+# This file is put in the public domain.
+# Jakub Bogusz <qboosh@pld-linux.org>, 2011-2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-29 21:07+0100\n"
+"Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
+"Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "nie udało się otworzyć userdb"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "nie udało się przełączyć na rejestr \"%s\" dla %s"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "nie udało się odtworzyć rejestru"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "nie udało się przydzielić pamięci"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "Nieznany sygnał"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "błędna wartość"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "wartość zbyt duża"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "wartość zbyt mała"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "błędna wartość Path \"%s\" w %s, w linii %u"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "błędna wartość opcji %s \"%s\" w %s, w linii %u"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "nieobsługiwane źródło grup \"%s\" w %s, w linii %u"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "błędna maksymalna liczba grup \"%s\" w %s, w linii %u"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "nie udało się wykonać stat na %s"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s nie jest zwykłym plikiem"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "właścicielem %s jest uid %u, powinien być %u"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "%s jest zapisywalny dla świata"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "%s jest zapisywalny dla grupy"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "nie udało się otworzyć %s"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "nieznana klasa logowania %s"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "nie udało się ustawić kontekstu użytkownika"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "nie udało się ustawić priorytetu procesu"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "nie udało się zmienić katalogu głównego na %s"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "nie udało się zmienić uid-ów, aby działać jako (%u, %u)"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "nie udało się zmienić katalogu na %s"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "nie udało się ustawić procedury obsługi dla sygnału %d"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "nie udało się usunąć PRIV_PROC_EXEC z PRIV_LIMIT"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "błąd odczytu z pary gniazd"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "nieoczekiwany typ odpowiedzi z kanału zwrotnego: %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "nie udało się dodać zdarzenia do kolejki"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "nie udało się ustawić sterującego tty"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "nie udało się utworzyć potoku"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "nie udało się odebrać komunikatu od rodzica"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "nie udało się wykonać fork"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "nie udało się wykonać %s"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "nie udało się przywrócić etykiety tty"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "nie udało się zainicjować sesji przez wtyczkę polityki"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "błąd w pętli zdarzeń"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "nie udało się przywrócić procedury obsługi dla sygnału %d"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "nie udało się przydzielić pty"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "nie udało się utworzyć gniazd"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "nie udało się wysłać komunikatu do procesu monitorującego"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "błąd w %s, w linii %d podczas wczytywania wtyczki \"%s\""
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "właścicielem %s musi być uid %d"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "prawo zapisu do %s może mieć tylko właściciel"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "nie udało się załadować %s: %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "nie udało się odnaleźć symbolu \"%s\" w %s"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "nieznany typ polityki %d napotkany w %s"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "niezgodna główna wersja polityki %d (zamiast oczekiwanej %d) napotkana w %s"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "zignorowano wtyczkę polityki \"%s\" w %s, w linii %d"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "może być podana tylko jedna wtyczka polityki"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "zignotowano powtórzoną wtyczkę polityki \"%s\" w %s, w linii %d"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "zignotowano powtórzoną wtyczkę we/wy \"%s\" w %s, w linii %d"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "wtyczka polityki %s nie zawiera metody check_policy"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "błąd wewnętrzny, przepełnienie %s"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "błędna nazwa zmiennej środowiskowej: %s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "argument opcji -C musi być większy lub równy 3"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "nie można podać jednocześnie opcji `-i' oraz `-s'"
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "nie można podać jednocześnie opcji `-i' oraz `-E'"
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "opcja `-E' nie jest poprawna w trybie edycji"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "w trybie edycji nie można przekazywać zmiennych środowiskowych"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "opcji `-U' można używać tylko wraz z opcją `-l'"
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "opcji `-A' oraz `-S' nie można używać jednocześnie"
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit nie jest obsługiwane na tej platformie"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Można podać tylko jedną z opcji -e, -h, -i, -K, -l, -s, -v lub -V"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - modyfikowanie plików jako inny użytkownik\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - wykonywanie poleceń jako inny użytkownik\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opcje:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "użycie programu pomocniczego do pytań o hasło"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "użycie podanego rodzaju uwierzytelnienia BSD"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "uruchomienie polecenia w tle"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "zamknięcie wszystkich deskryptorów >= fd"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "uruchomienie polecenia z podaną klasą logowania BSD"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "zachowanie środowiska użytkownika przy uruchamianiu polecenia"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "zachowanie określonych zmiennych środowiskowych"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "modyfikowanie plików zamiast uruchomienia polecenia"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "wywołanie polecenia jako określona grupa lub ID"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "ustawienie zmiennej HOME na katalog domowy użytkownika docelowego"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "wyświetlenie opisu i zakończenie"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "uruchomienie polecenia na hoście (jeśli obsługiwane przez wtyczkę)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "uruchomienie powłoki logowania jako użytkownik docelowy; można także podać polecenie"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "całkowite usunięcie pliku znacznika czasu"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "unieważnienie pliku znacznika czasu"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "wypisanie uprawnień użytkownika lub sprawdzenie określonego polecenia; dwukrotne użycie to dłuższy format"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "tryb nieinteraktywny, bez pytań"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "zachowanie wektora grup zamiast ustawiania docelowych"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "użycie podanego pytania o hasło"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "utworzenie kontekstu bezpieczeństwa SELinuksa z podaną rolą"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "odczyt hasła ze standardowego wejścia"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "uruchomienie powłoki jako użytkownik docelowy; można także podać polecenie"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "utworzenie kontekstu bezpieczeństwa SELinuksa z podanym typem"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "zakończenie polecenia po zadanym limicie czasu"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "w trybie listy - wyświetlenie uprawnień użytkownika"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "uruchomienie polecenia (lub modyfikowanie pliku) jako podany użytkownik lub ID"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "wyświetlenie informacji o wersji i zakończenie"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "uaktualnienie znacznika czasu użytkownika bez uruchamiania polecenia"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "zakończenie przetwarzania argumentów linii poleceń"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "nie udało się otworzyć systemu audytu"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "nie udało się wysłać komunikatu audytowego"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "nie udało się wykonać fgetfilecon %s"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "zmienionych etykiet: %s"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "nie udało się przywrócić kontekstu %s"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "nie udało się otworzyć %s, bez zmiany etykiety tty"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s nie jest urządzeniem znakowym, bez ponownego etykietowania tty"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "nie udało się uzyskać bieżącego kontekstu tty, bez zmiany etykiety tty"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "nieznana klasa bezpieczeństwa \"chr_file\", bez ponownego etykietowania tty"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "nie udało się uzyskać nowego kontekstu tty, bez zmiany etykiety tty"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "nie udało się ustawić nowego kontekstu tty"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "trzeba podać rolę dla typu %s"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "nie udało się uzyskać domyślnego typu dla roli %s"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "nie udało się ustawić nowej roli %s"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "nie udało się ustawić nowego typu %s"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s nie jest poprawnym kontekstem"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "nie udało się uzyskać starego kontekstu"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "nie udało się określić trybu wymuszenia."
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "nie udało się ustawić kontekstu tty na %s"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "nie udało się ustawić kontekstu wykonywania na %s"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "nie udało się ustawić kontekstu tworzenia klucza na %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "wymagany jest przynajmniej jeden argument"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "błędny numer deskryptora pliku: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "nie udało się uruchomić %s jako powłoki logowania"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "nie udało się zapisać procedury obsługi dla sygnału %d"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "osiągnięto limit kontroli zasobów"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "użytkownik \"%s\" nie jest członkiem projektu \"%s\""
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "zadanie uruchamiające jest ostatnim"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "nie udało się dołączyć do projektu \"%s\""
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "nie istnieje pula zasobów akceptująca domyślne przypisania dla projektu \"%s\""
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "podana pula zasobów nie istnieje w projekcie \"%s\""
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "nie można przypisać do domyślnej puli zasobów w projekcie \"%s\""
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "setproject dla projektu \"%s\" nie powiodło się"
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "uwaga: przypisanie kontroli zasobów dla projektu \"%s\" nie powiodło się"
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo wersja %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Opcje konfiguracji: %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "błąd krytyczny, nie udało się załadować wtyczek"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "nie udało się zainicjować wtyczki polityki"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "wtyczka nie zwróciła polecenia do wykonania"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "błąd inicjalizacji wtyczki we/wy %s"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "nieoczekiwany tryb sudo 0x%x"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "nie istniejesz w bazie danych %s"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "nie udało się określić tty"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s musi mieć uid %d jako właściciela oraz ustawiony bit setuid"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "efektywny uid nie wynosi %d, czy %s jest na systemie plików z opcją 'nosuid' albo systemie plików NFS bez uprawnień roota?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "efektywny uid nie wynosi %d, czy sudo jest zainstalowane z setuid root?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "nie udało się ustawić ID dodatkowych grup"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "nie udało się ustawić efektywnego gid-a w celu działania jako gid %u"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "nie udało się ustawić gid-a w celu działania jako gid %u"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "nieoczekiwane zakończenie procesu potomnego: %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "wtyczka polityki %s nie zawiera metody `check_policy'"
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "wtyczka polityki %s nie obsługuje wypisywania uprawnień"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "wtyczka polityki %s nie obsługuje opcji -v"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "wtyczka polityki %s nie obsługuje opcji -k/-K"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "nie znaleziono katalogu tymczasowego z prawem zapisu"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "nie udało się odtworzyć bieżącego kartalogu roboczego"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: nie jest zwykłym plikiem"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: edycja dowiązań symbolicznych nie jest dozwolona"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: edycja plików w katalogu zapisywalnym nie jest dozwolona"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s: skrócony zapis"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "pozostawiono bez zmian: %s"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "nie zmieniono: %s"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "nie udało się zapisać do %s"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "zawartość sesji edycji pozostawiono w %s"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "nie udało się odczytać pliku tymczasowego"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: błąd wewnętrzny: nieparzysta liczba ścieżek"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: nie udało się utworzyć plików tymczasowych"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: nieznany błąd %d"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "nie udało się skopiować plików tymczasowych z powrotem w ich oryginalne miejsce"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "nie udało się skopiować części plików tymczasowych z powrotem w ich oryginalne miejsce"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "nie udało się zmienić uid-a na roota (%u)"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "błąd wtyczki: brak listy plików dla sudoedit"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "nie udało się odczytać zegara"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "przekroczony limit czasu przy czytaniu hasła"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "nie podano hasła"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "nie udało się odczytać hasła"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "brak tty i nie podano programu pytającego o hasło"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "nie podano programu pytającego o hasło, proszę spróbować ustawić SUDO_ASKPASS"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "nie udało się ustawić gid-a na %u"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "nie udało się ustawić uid-a na %u"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "nie udało się uruchomić %s"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "nie udało się zapisać standardowego wejścia"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "nie udało się wykonać dup2 na standardowym wejściu"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "nie udało się przywrócić standardowego wejścia"
diff --git a/po/pt.mo b/po/pt.mo
new file mode 100644
index 0000000..c12773d
--- /dev/null
+++ b/po/pt.mo
Binary files differ
diff --git a/po/pt.po b/po/pt.po
new file mode 100644
index 0000000..93d1dc0
--- /dev/null
+++ b/po/pt.po
@@ -0,0 +1,933 @@
+# Portuguese (Portugal) translations for the sudo package
+# This file is distributed under the same license as the sudo package.
+# Todd C. Miller <Todd.Miller@sudo.ws>, 2011-2016
+# Pedro Albuquerque <palbuquerque73@gmail.com>, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo-1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-30 06:58+0100\n"
+"Last-Translator: Pedro Albuquerque <palbuquerque73@gmail.com>\n"
+"Language-Team: Portuguese <translation-team-pt@lists.sourceforge.net>\n"
+"Language: pt\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Virtaal 0.7.1\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "impossível abrir userdb"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "impossível mudar para o registo \"%s\" para %s"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "impossível restaurar o registo"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "impossível alocar memória"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "Sinal desconhecido"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "valor inválido"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "valor muito grande"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "valor muito pequeno"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "valor de caminho inválido \"%s\" em %s, linha %u"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "valor inválido %s \"%s\" em %s, linha %u"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "fonte de grupo não suportada \"%s\" em %s, linna %u"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "máximo de grupos inválido \"%s\" em %s, linha %u"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "impossível obter informações de %s"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s não é um ficheiro normal"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s é propriedade de uid %u, deveria ser %u"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "%s é escrito universalmente"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "%s é escrito pelo grupo"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "impossível abrir %s"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "classe de sessão %s desconhecida"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "impossível definir contexto de utilizador"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "impossível processar prioridade"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "impossível alterar root para %s"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "impossível alterar para runas uid (%u, %u)"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "impossível alterar pasta para %s"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "impossível definir gestor para sinal %d"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "impossível remover PRIV_PROC_EXEC de PRIV_LIMIT"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "erro ao ler de socketpair"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "tipo de resposta inesperada no canal secundário: %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "impossível adicionar evento à fila"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "impossível definir tty de controlo"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "impossível criar túnel"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "impossível receber mensagem de pai"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "impossível bifurcar"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "impossível executar %s"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "impossível restaurar rótulo tty"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "a extensão de política falhou a inicialização de sessão"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "erro em ciclo de evento"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "impossível restaurar gestor para o sinal %d"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "impossível alocar pty"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "impossível criar sockets"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "impossível enviar mensagem para monitorizar processo"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "erro em %s, linha %d ao carregar a extensão \"%s\""
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s tem de ser propriedade de uid %d"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s só pode ter permissão de escrita para o dono"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "impossível carregar %s: %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "impossível encontrar símbolo \"%s\" em %s"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "tipo de política %d desconhecida encontrada em %s"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "versão principal de extensão %d incompatível (esperada %d) encontrada em %s"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "a ignorar extensão de política \"%s\" em %s, linha %d"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "só pode especificar um tipo de extensão de política"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "a ignorar extensão de política duplicada \"%s\" em %s, linha %d"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "a ignorar extensão E/S duplicada \"%s\" em %s, linha %d"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "extensão de política %s não inclui um método check_policy"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "erro interno, transporte %s"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "nome de variável de ambiente inválido: %s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "o argumento para -C tem de ser um número maior ou igual a 3"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "não pode especificar ambas as opções \"-i\" e \"-s\""
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "não pode especificar ambas as opções \"-i\" e \"-E\""
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "a opção \"-E\" não é válida em modo de edição"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "não pode especificar variáveis de ambiente em modo de edição"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "a opção \"-U\" só pode ser usada com a opção \"-l\""
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "não pode especificar ambas as opções \"-A\" e \"-S\""
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit não é suportado nesta plataforma"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Só uma das opções -e, -h, -i, -K, -l, -s, -v ou -V pode ser especificada"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - edita ficheiros como outro utilizador\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - executa um comando como outro utilizador\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opções:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "usa um programa de ajuda para pedir a senha"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "usa um tipo de autenticação BSD especificado"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "executa o comando em 2º plano"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "fecha todos os descritores de ficheiros >= num"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "executa o comando com a classe de sessão BSD especificada"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "preserva o ambiente de utilizador ao executar o comando"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "preserva variáveis de ambiente específicas"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "edita ficheiros em vez de executar um comando"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "executa o comando como nome de grupo ou ID especificados"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "define a variável HOME para a pasta home do utilizador alvo"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "mostra a ajuda e sai"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "executa o comando no anfitrião (se suportado pela extensão)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "executa a shell de sessão como utilizador alvo; também pode especificar um comando"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "remove completamente o ficheiro de datação"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "invalida o ficheiro de datação"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "lista privilégios do utilizador ou verifica um comando específico; use duas vezes para formato mais longo"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "modo não-interactivo, não usa prompts"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "preserva vector de grupo em vez de o definir para o do alvo"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "usa o pedido de senha especificado"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "cria contexto de segurnaça SELinux com o papel especificado"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "lê a senha da entrada padrão"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "executa a shell como utilizador alvo; também pode especificar um comando"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "cria contexto de segurnaça SELinux com o tipo especificado"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "termina o comando após o tempo limite especificado"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "em modo Lista, mostra os privilégios do utilizador"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "executa o comando (ou edita o ficheiro) como nome ou ID de utilizador especificados"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "mostra informação da versão e sai"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "actualiza datação do utilizador sem executar um comando"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "pára o processamento de argumentos da linha de comandos"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "impossível abrir o sistema de auditoria"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "impossível enviar mensagem de auditoria"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "impossível fgetfilecon %s"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s rótulos alterados"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "impossível restaurar contexto para %s"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "impossível abrir %s, sem re-rotular tty"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s não é um dispositivo carácter, sem re-rotular tty"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "impossível obter contexto tty actual, sem re-rotular tty"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "classe de segurança \"chr_file\" desconhecida, sem re-rotular tty"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "impossível obter novo contexto tty, sem re-rotular tty"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "impossível definir novo contexto tty"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "tem de especificar um papel para o tipo %s"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "impossível obter o tipo predefinido para o papel %s"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "falha ao definir novo papel %s"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "falha ao definir novo tipo %s"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s não é um contexto válido"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "falha ao obter old_context"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "impossível determinar modo de imposição."
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "impossível definir contexto tty para %s"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "impossível definir contexto exec para %s"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "impossível definir contexto de criação de chave para %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "requer pelo menos um argumento"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "número de descritor de ficheiro inválido: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "impossível executar %s como shell de sessão"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "impossível gravar gestor para o sinal %d"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "atingido o limite de controlo de recursos"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "o utilizador \"%s\" não é membro do projecto \"%s\""
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "a tarefa chamadora é final"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "impossível participar no projecto \"%s\""
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "não existe nenhum conjunto de recursos que aceite associações predefinidas para o projeto \"%s\""
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "o conjunto de recursos especificado não existe para o projecto \"%s\""
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "impossível associar ao conjunto de recursos predefinido do projecto \"%s\""
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "falha setproject para o projecto \"%s\""
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "aviso: falha na atribuição de controlo de recursos para o projecto \"%s\""
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo versão %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Opções de configuração: %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "erro fatal, impossível carregar extensões"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "impossível inicializar a extensão de política"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "a extensão não devolveu um comando a executar"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "erro ao inicializar a extensão E/S %s"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "modo sudo 0x%x inesperado"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "utilizador não existente na base de dados %s"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "impossível determinar tty"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s tem ser propriedade de uid %d e ter o bit setuid definido"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "a uid efectiva não é %d, é %s num sistema de ficheiros com a opção 'nosuid' definida ou um sistema de ficheiros NFS sem privilégios root?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "a uid efectiva não é %d, tem sudo instalado com setuid root?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "impossível definir IDs de grupo suplementares"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "impossível definir gid efectiva para gid runas %u"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "impossível definir gid para gid runas %u"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "condição de terminação de filho inesperada: %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "a extensão de política %s tem o método \"check_policy\" em falta"
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "a extensão de política %s não suporta privilégios de listagem"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "a extensão de política %s não suporta a opção -v"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "a extensão de política %s não suporta as opções -k/-K"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "sem pasta temporária onde possa escrever"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "impossível restaurar pasta de trabalho actual"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s não é um ficheiro normal"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: não é permitido editar ligações simbólicas"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: não é permitido editar ficheiros numa pasta onde se pode escrever"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s: escrita curta"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s deixado sem alterações"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "%s não alterado"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "impossível escrever em %s"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "conteúdo da sessão de edição deixados em %s"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "impossível ler ficheiro temporário"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: erro interno: número de caminhos ímpar"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: impossível criar ficheiros temporários"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: erro %d desconhecido"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "impossível copiar ficheiros temporários de volta à localização original"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "impossível copiar alguns ficheiros temporários de volta à localização original"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "impossível alterar uid para root (%u)"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "erro de extensão: lista de ficheiros para sudoedit em falta"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "impossível ler o relógio"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "tempo expirado ao ler senha"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "não foi fornecida uma senha"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "impossível ler senha"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "sem tty presente e sem programa askpass especificado"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "sem programa askpass especificado, tente definir SUDO_ASKPASS"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "impossível definir gid para %u"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "impossível definir uid para %u"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "impossível executar %s"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "impossível gravar stdin"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "impossível dup2 stdin"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "impossível restaurar stdin"
+
+#~ msgid "unable to get group vector"
+#~ msgstr "impossível obter vector de grupo"
+
+#~ msgid "unknown uid %u: who are you?"
+#~ msgstr "uid %u desconhecida: quem é?"
diff --git a/po/pt_BR.mo b/po/pt_BR.mo
new file mode 100644
index 0000000..385bc48
--- /dev/null
+++ b/po/pt_BR.mo
Binary files differ
diff --git a/po/pt_BR.po b/po/pt_BR.po
new file mode 100644
index 0000000..b10db17
--- /dev/null
+++ b/po/pt_BR.po
@@ -0,0 +1,988 @@
+# Brazilian Portuguese translation for sudo.
+# Traduções em português brasileiro para o pacote sudo.
+# This file is distributed under the same license as the sudo package.
+# Copyright (C) 2018 Free Software Foundation, Inc.
+# Rafael Fontenelle <rafaelff@gnome.org>, 2013-2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-29 16:10-0200\n"
+"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
+"Language-Team: Brazilian Portuguese <ldpbr-translation@lists.sourceforge.net>\n"
+"Language: pt_BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Generator: Virtaal 1.0.0-beta1\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "não foi possível abrir o userdb"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "não foi possível alterar para registro \"%s\" para %s"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "não foi possível restaurar registro"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "não foi possível alocar memória"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "Sinal desconhecido"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "valor inválido"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "valor grande demais"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "valor pequeno demais"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "Path inválido com valor \"%s\" em %s, linha %u"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "Valor inválido para %s \"%s\" em %s, linha %u"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "fonte de grupo sem suporte \"%s\" em %s, linha %u"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "máximo de grupos inválido \"%s\" em %s, linha %u"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "não foi possível obter o estado de %s"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s não é um arquivo comum"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s tem como dono o uid %u, deveria ser %u"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "%s é gravável globalmente"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "%s é gravável pelo grupo"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "não foi possível abrir %s"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "classe de login desconhecida %s"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "não foi possível definir contexto de usuário"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "não foi possível definir prioridade do processo"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "não foi possível alterar a raiz para %s"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "não foi possível alterar para uid de \"runas\" (%u, %u)"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "não foi possível alterar diretório para %s"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "não foi possível definir manipulador para sinal %d"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "não foi possível remover PRIV_PROC_EXEC de PRIV_LIMIT"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "erro ao ler do par de soquetes"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "tipo de resposta inesperada no canal de retorno: %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "não foi possível adicionar um evento à fila"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "não foi possível definir tty de controle"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "não foi possível criar um encadeamento (pipe)"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "não foi possível receber mensagem de pai"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "não foi possível fazer fork"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "não foi possível executar %s"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "não foi possível restaurar rótulo de tty"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "plug-in de política falhou ao inicializar da sessão"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "erro em loop de evento"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "não foi possível restaurar manipulador para sinal %d"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "não foi possível alocar pty"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "não foi possível criar soquetes"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "não foi possível enviar mensagem para monitorar processo"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "erro em %s, linha %d ao carregar plug-in \"%s\""
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s deve ter como dono o uid %d"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s deve ser gravável apenas pelo dono"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "não foi possível carregar %s: %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "não foi possível localizar símbolo \"%s\" em %s"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "tipo de política %d desconhecida localizada em %s"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "versão maior %d do plug-in incompatível (esperava %d) localizada em %s"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "ignorando plug-in de política \"%s\" em %s, linha %d"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "apenas um plug-in de política pode ser especificado"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "ignorando plug-in de política duplicada \"%s\" em %s, linha %d"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "ignorando plug-in de E/S \"%s\" duplicado em %s, linha %d"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "plug-in de política %s não inclui um método de check_policy"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "erro interno, estouro de pilha de %s"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "nome de variável de ambiente inválida: %s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "o argumento do -C deve ser um número maior ou igual a 3"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "você não pode especificar as opções \"-i\" e \"-s\" ao mesmo tempo"
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "você não pode especificar as opções \"-i\" e \"-E\" ao mesmo tempo"
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "a opção \"-E\" não é válida no modo de edição"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "você não pode especificar variáveis de ambiente no modo de edição"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "a opção \"-U\" pode ser usada apenas com a opção \"-l\""
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "as opções \"-A\" e \"-S\" não podem ser usadas ao mesmo tempo"
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "não há suporte a sudoedit nesta plataforma"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Apenas uma das opções -e, -h, -i, -K, -l, -s, -v ou -V pode ser especificada"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - edita arquivos como outro usuário\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - executa um comando como outro usuário\n"
+"\n"
+
+# Deixei minúsculo para seguir o padrão das demais linhas do "sudo -h"
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"opções:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "usa um programa auxiliar para pedir senha"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "usa o tipo de autenticação BSD especificado"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "executa um comando em plano de fundo"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "fecha todos os descritores, de arquivos, >= num"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "executa um comando com uma classe de login especificada"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "preserva um ambiente de usuário ao executar um comando"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "preserva variáveis de ambiente específicas"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "edita arquivos em vez de executar um comando"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "executa um comando como o ID ou nome de grupo especificado"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "define a variável HOME para a pasta pessoal do usuário alvo"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "exibe uma mensagem de ajuda e sai"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "executa o comando na máquina (se houver suporte pelo plug-in)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "executa um shell de login como usuário alvo; um comando também pode ser especificado"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "remove arquivo de marca de tempo completamente"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "invalida arquivo de marca de tempo"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "lista os privilégios do usuário ou verifica um comando específico; use duas vezes para um formato maior"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "modo não interativo, não pergunta para o usuário"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "preserva vetor de grupos ao invés de definir para o do alvo"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "usa a senha especificada"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "cria um contexto de segurança SELinux com o papel especificado"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "lê a senha da entrada padrão"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "executa o shell como o usuário alvo; um comando também pode ser especificado"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "cria um contexto de segurança SELinux com o tipo especificado"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "termina o comando após o tempo limite especificado"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "no modo lista, exibe os privilégios por usuário"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "executa um comando (ou edita um arquivo) como o nome ou ID do usuário especificado"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "exibe as informações de versão e sai"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "atualiza a marca de tempo do usuário sem executar um comando"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "interrompe processamento de argumentos de linha de comando"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "não foi possível abrir o sistema de auditoria"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "não foi possível enviar mensagem de auditoria"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "não foi possível fazer fgetfilecon de %s"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s mudou de rótulo"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "não foi possível restaurar contexto de %s"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "não foi possível abrir %s, não re-rotulando o tty"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s não é um dispositivo de caractere, não re-rotulando o tty"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "não foi possível obter contexto de tty atual, não re-rotulando o tty"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "classe de segurança \"chr_file\" desconhecida, não re-rotulando o tty"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "não foi possível obter novo contexto de tty, não re-rotulando o tty"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "não foi possível definir um novo contexto de tty"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "você deve especificar um papel para o tipo %s"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "não foi possível obter tipo padrão para o papel %s"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "falha ao definir novo papel %s"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "falha ao definir novo tipo %s"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s não é um contexto válido"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "falha ao obter old_context"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "não foi possível determinar modo de aplicação."
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "não foi possível definir contexto de tty de %s"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "não foi possível definir contexto de exec de %s"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "não foi possível definir contexto de criação de chave para %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "requer ao menos um argumento"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "número de descritor de arquivos inválido: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "não foi possível executar %s como shell de login"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "não foi possível salvar manipulador para sinal %d"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "limite de controle de recurso foi atingido"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "usuário \"%s\" não é um membro do projeto \"%s\""
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "a tarefa de chamada é final"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "não foi possível participar do projeto \"%s\""
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "nenhuma pool de recursos aceitando vinculações padrões existe para o projeto \"%s\""
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "pool de recursos especificados não existe para o projeto \"%s\""
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "não foi possível vincular ao pool de recursos padrão para o projeto \"%s\""
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "setproject falhou para o projeto \"%s\""
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "aviso, atribuição de controle de recursos falhou para o projeto \"%s\""
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo versão %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Opções de configuração: %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "erro fatal, não foi possível carregar os plug-ins"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "não foi possível inicializar plug-in de política"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "o plug-in não retornou um comando para ser executado"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "erro ao inicializar o plug-in de E/S %s"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "modo de sudo inesperado 0x%x"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "você não existe no banco de dados %s"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "não foi possível determinar o tty"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s deve ter como dono o uid %d e tem definido o bit setuid"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "uid efetivo não é %d, é %s em um sistema de arquivos com a opção \"nosuid\" defina ou um sistema de arquivos NFS sem privilégios de root?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "uid efetivo não é %d, sudo está instalado em uma raiz com setuid?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "não foi possível definir IDs de grupo suplementares"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "não foi possível definir gid efetivo para executar como gid %u"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "não foi possível definir gid para executar como gid %u"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "condição inesperada de término de filho: %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "plug-in de política %s é sem o método \"check_policy\""
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "plug-in de política %s não tem suporte a listagem de privilégios"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "plug-in de política %s não tem suporte à opção -v"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "plug-in de política %s não tem suporte às opções -k/-K"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "nenhum diretório temporário gravável encontrado"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "não foi possível restaurar o diretório de trabalho atual"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: não é um arquivo comum"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: edição de links simbólicos não é permitida"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: edição de arquivos em um diretório gravável não é permitida"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s: escrita curta"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s não foi modificado"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "%s sem alteração"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "não foi possível gravar em %s"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "conteúdo da sessão de edição deixado em %s"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "não foi possível ler arquivo temporário"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: erro interno: número ímpar de caminhos"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: não foi possível criar arquivos temporários"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: erro desconhecido: %d"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "não foi possível copiar arquivos temporários de volta para sua localização original"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "não foi possível copiar alguns dos arquivos temporários de volta para sua localização original"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "não foi possível alterar uid de root (%u)"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "erro no plug-in: faltando lista de arquivo para sudoedit"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "não foi possível ler o relógio"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "tempo limite esgotado lendo senha"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "nenhuma senha foi fornecida"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "não foi possível ler a senha"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "nenhum tty presente e nenhum programa de askpass especificado"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "nenhum programa de askpass especificado, tente definir SUDO_ASKPASS"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "não foi possível definir gid para %u"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "não foi possível definir uid para %u"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "não foi possível executar %s"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "não foi possível salvar a entrada padrão"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "não foi possível realizar dup2 da entrada padrão"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "não foi possível restaurar a entrada padrão"
+
+#~ msgid "unable to get group vector"
+#~ msgstr "não foi possível obter vetor de grupos"
+
+#~ msgid "unknown uid %u: who are you?"
+#~ msgstr "uid desconhecido %u: quem é você?"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "erro ao ler do sinal de encadeamento (pipe)"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "erro ao ler de encadeamento (pipe)"
+
+#~ msgid "internal error, tried allocate zero bytes"
+#~ msgstr "erro interno, tentou alocar zero bytes"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "não foi possível definir o terminal para modo raw"
+
+#~ msgid "unable to open socket"
+#~ msgstr "não foi possível abrir soquete"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "erro interno, tentou fazer emalloc2(0)"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "erro interno, tentou fazer ecalloc(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "erro interno, tentou fazer erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "erro interno, tentou fazer erealloc3(0)"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "erro interno, tentou fazer erecalloc(0)"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: estouro de pilha detectado"
+
+#~ msgid "value out of range"
+#~ msgstr "valor fora de faixa"
+
+#~ msgid "select failed"
+#~ msgstr "seleção falhou"
+
+#~ msgid "list user's available commands\n"
+#~ msgstr "lista comandos disponíveis do usuário\n"
+
+#~ msgid "run a shell as target user\n"
+#~ msgstr "executa um shell como usuário alvo\n"
+
+#~ msgid "when listing, list specified user's privileges\n"
+#~ msgstr "ao listar, lista os privilégios do usuário especificado\n"
diff --git a/po/ru.mo b/po/ru.mo
new file mode 100644
index 0000000..5b7e646
--- /dev/null
+++ b/po/ru.mo
Binary files differ
diff --git a/po/ru.po b/po/ru.po
new file mode 100644
index 0000000..b0784ca
--- /dev/null
+++ b/po/ru.po
@@ -0,0 +1,923 @@
+# Transation of sudo messages to Russian.
+# This file is put in the public domain.
+# This file is distributed under the same license as the sudo package.
+#
+# Pavel Maryanov <acid@jack.kiev.ua>, 2011.
+# Yuri Kozlov <yuray@komyakino.ru>, 2011, 2012, 2013, 2014, 2016.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.16b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2016-02-19 15:48-0700\n"
+"PO-Revision-Date: 2016-02-28 11:05+0200\n"
+"Last-Translator: Pavel Maryanov <acid@jack.kiev.ua>\n"
+"Language-Team: Russian <gnu@d07.ru>\n"
+"Language: ru\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.6\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:164
+msgid "unable to open userdb"
+msgstr "не удаётся открыть userdb"
+
+#: lib/util/aix.c:219
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "не удаётся переключиться на реестр «%s» для %s"
+
+#: lib/util/aix.c:244
+msgid "unable to restore registry"
+msgstr "не удаётся восстановить реестр"
+
+#: lib/util/aix.c:267 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:207 lib/util/sudo_conf.c:290 lib/util/sudo_conf.c:367
+#: lib/util/sudo_conf.c:569 src/conversation.c:75 src/exec.c:863
+#: src/exec_common.c:107 src/exec_common.c:123 src/exec_common.c:132
+#: src/exec_pty.c:684 src/exec_pty.c:692 src/load_plugins.c:52
+#: src/load_plugins.c:65 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:180
+#: src/parse_args.c:202 src/parse_args.c:370 src/parse_args.c:466
+#: src/parse_args.c:485 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:291 src/selinux.c:416 src/selinux.c:425
+#: src/sesh.c:115 src/sudo.c:201 src/sudo.c:398 src/sudo.c:417 src/sudo.c:481
+#: src/sudo.c:655 src/sudo.c:665 src/sudo.c:685 src/sudo.c:704 src/sudo.c:713
+#: src/sudo.c:722 src/sudo.c:739 src/sudo.c:780 src/sudo.c:790 src/sudo.c:810
+#: src/sudo.c:1215 src/sudo.c:1236 src/sudo.c:1398 src/sudo.c:1492
+#: src/sudo_edit.c:151 src/sudo_edit.c:716 src/sudo_edit.c:813
+#: src/sudo_edit.c:925 src/sudo_edit.c:945
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:267 lib/util/gidlist.c:64 lib/util/sudo_conf.c:208
+#: lib/util/sudo_conf.c:290 lib/util/sudo_conf.c:367 lib/util/sudo_conf.c:569
+#: src/conversation.c:76 src/exec.c:863 src/exec_common.c:107
+#: src/exec_common.c:124 src/exec_common.c:133 src/exec_pty.c:684
+#: src/exec_pty.c:692 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:180
+#: src/parse_args.c:202 src/parse_args.c:370 src/parse_args.c:466
+#: src/parse_args.c:485 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:291 src/selinux.c:416 src/selinux.c:425
+#: src/sesh.c:115 src/sudo.c:201 src/sudo.c:398 src/sudo.c:417 src/sudo.c:481
+#: src/sudo.c:810 src/sudo.c:1215 src/sudo.c:1236 src/sudo.c:1398
+#: src/sudo.c:1492 src/sudo_edit.c:151 src/sudo_edit.c:716 src/sudo_edit.c:813
+#: src/sudo_edit.c:925 src/sudo_edit.c:945
+msgid "unable to allocate memory"
+msgstr "не удаётся выделить память"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "Неизвестный сигнал"
+
+#: lib/util/strtoid.c:76 lib/util/strtoid.c:104 lib/util/strtomode.c:48
+#: lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "недопустимое значение"
+
+#: lib/util/strtoid.c:83 lib/util/strtoid.c:111 lib/util/strtomode.c:54
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "значение слишком велико"
+
+#: lib/util/strtoid.c:89 lib/util/strtomode.c:54 lib/util/strtonum.c:61
+#: lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "значение слишком мало"
+
+#: lib/util/sudo_conf.c:223
+#, c-format
+msgid "invalid Path value `%s' in %s, line %u"
+msgstr "некорректное значение Path «%s» в %s, строка %u"
+
+#: lib/util/sudo_conf.c:389 lib/util/sudo_conf.c:442
+#, c-format
+msgid "invalid value for %s `%s' in %s, line %u"
+msgstr "некорректное значение для %s «%s» в %s, строка %u"
+
+#: lib/util/sudo_conf.c:410
+#, c-format
+msgid "unsupported group source `%s' in %s, line %u"
+msgstr "неподдерживаемый групповой источник «%s» в %s, строка %u"
+
+#: lib/util/sudo_conf.c:426
+#, c-format
+msgid "invalid max groups `%s' in %s, line %u"
+msgstr "некорректное максимальное значение для групп «%s» в %s, строка %u"
+
+#: lib/util/sudo_conf.c:585
+#, c-format
+msgid "unable to stat %s"
+msgstr "не удалось выполнить вызов stat %s"
+
+#: lib/util/sudo_conf.c:588
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s не является обычным файлом"
+
+#: lib/util/sudo_conf.c:591
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s принадлежит пользователю с uid %u, а должен принадлежать пользователю с uid %u"
+
+#: lib/util/sudo_conf.c:595
+#, c-format
+msgid "%s is world writable"
+msgstr "доступ на запись в %s разрешена всем"
+
+#: lib/util/sudo_conf.c:598
+#, c-format
+msgid "%s is group writable"
+msgstr "доступ на запись в %s разрешена группе"
+
+#: lib/util/sudo_conf.c:608 src/selinux.c:199 src/selinux.c:212 src/sudo.c:367
+#, c-format
+msgid "unable to open %s"
+msgstr "не удаётся открыть %s"
+
+#: src/exec.c:114 src/exec.c:116 src/exec.c:121 src/exec.c:409 src/exec.c:411
+#: src/exec.c:413 src/exec.c:415 src/exec.c:417 src/exec.c:419 src/exec.c:422
+#: src/exec.c:438 src/exec.c:440 src/exec.c:595 src/exec.c:790
+#: src/exec_pty.c:466 src/exec_pty.c:722 src/exec_pty.c:792 src/exec_pty.c:794
+#: src/exec_pty.c:806 src/exec_pty.c:808 src/exec_pty.c:1289
+#: src/exec_pty.c:1291 src/exec_pty.c:1296 src/exec_pty.c:1298
+#: src/exec_pty.c:1312 src/exec_pty.c:1323 src/exec_pty.c:1325
+#: src/exec_pty.c:1327 src/exec_pty.c:1329 src/exec_pty.c:1331
+#: src/exec_pty.c:1333 src/exec_pty.c:1335 src/signal.c:147
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "не удаётся установить обработчик сигнала %d"
+
+#: src/exec.c:126 src/exec_pty.c:838 src/exec_pty.c:1373 src/tgetpass.c:265
+msgid "unable to fork"
+msgstr "не удаётся создать дочерний процесс"
+
+#: src/exec.c:304 src/exec.c:312 src/exec.c:868 src/exec_pty.c:604
+#: src/exec_pty.c:611 src/exec_pty.c:654 src/exec_pty.c:659 src/exec_pty.c:946
+#: src/exec_pty.c:956 src/exec_pty.c:1001 src/exec_pty.c:1008
+#: src/exec_pty.c:1438 src/exec_pty.c:1445 src/exec_pty.c:1452
+msgid "unable to add event to queue"
+msgstr "не удаётся добавить событие в очередь"
+
+#: src/exec.c:392
+msgid "unable to create sockets"
+msgstr "не удаётся создать сокеты"
+
+#: src/exec.c:447
+msgid "policy plugin failed session initialization"
+msgstr "модулю политик не удалось инициализировать сеанс"
+
+#: src/exec.c:492
+msgid "error in event loop"
+msgstr "ошибка в событийном цикле"
+
+#: src/exec.c:510
+msgid "unable to restore tty label"
+msgstr "не удаётся создать восстановить метку tty"
+
+#: src/exec.c:603 src/exec_pty.c:498 src/signal.c:86
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "не удаётся восстановить обработчик сигнала %d"
+
+#: src/exec.c:721 src/exec_pty.c:1180
+msgid "error reading from signal pipe"
+msgstr "ошибка чтения из сигнального канала"
+
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "не удаётся удалить PRIV_PROC_EXEC из PRIV_LIMIT"
+
+#: src/exec_pty.c:188
+msgid "unable to allocate pty"
+msgstr "не удаётся выделить pty"
+
+#: src/exec_pty.c:766 src/exec_pty.c:775 src/exec_pty.c:783
+#: src/exec_pty.c:1281 src/exec_pty.c:1370 src/signal.c:128 src/tgetpass.c:261
+msgid "unable to create pipe"
+msgstr "не удаётся создать канал"
+
+#: src/exec_pty.c:1213
+msgid "error reading from pipe"
+msgstr "ошибка чтения из канала"
+
+#: src/exec_pty.c:1238
+msgid "error reading from socketpair"
+msgstr "ошибка чтения из пары сокетов"
+
+#: src/exec_pty.c:1247
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "неожиданный тип ответа в резервном канале: %d"
+
+#: src/exec_pty.c:1349
+msgid "unable to set controlling tty"
+msgstr "не удаётся установить управляющий tty"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin `%s'"
+msgstr "ошибка в %s, строка %d, при загрузке модуля «%s»"
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s должен принадлежать пользователю с uid %d"
+
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s должен быть доступен на запись только владельцу"
+
+#: src/load_plugins.c:172
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "не удаётся загрузить %s: %s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unable to find symbol `%s' in %s"
+msgstr "не удаётся найти символ «%s» в %s"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "найден неизвестный тип политики %d в %s"
+
+#: src/load_plugins.c:193
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "найдена несовместимая основная версия модуля %d (ожидалась %d) в %s"
+
+#: src/load_plugins.c:202
+#, c-format
+msgid "ignoring policy plugin `%s' in %s, line %d"
+msgstr "игнорируется модуль политики «%s» в %s, строка %d"
+
+#: src/load_plugins.c:204
+msgid "only a single policy plugin may be specified"
+msgstr "может быть задан только один модуль политики"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring duplicate policy plugin `%s' in %s, line %d"
+msgstr "игнорируется повторный модуль политики «%s» в %s, строка %d"
+
+#: src/load_plugins.c:228
+#, c-format
+msgid "ignoring duplicate I/O plugin `%s' in %s, line %d"
+msgstr "игнорируется повторный модуль ввода-вывода «%s» в %s, строка %d"
+
+#: src/load_plugins.c:331
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "модуль политики %s не содержит метод check_policy"
+
+#: src/net_ifs.c:173 src/net_ifs.c:190 src/net_ifs.c:335 src/sudo.c:476
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "внутренняя ошибка, переполнение %s"
+
+#: src/parse_args.c:239
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "аргумент для -C должен быть числом, которое больше или равно 3"
+
+#: src/parse_args.c:406
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "параметры «-i» и «-s» являются взаимоисключающими"
+
+#: src/parse_args.c:410
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "параметры «-i» и «-E» являются взаимоисключающими"
+
+#: src/parse_args.c:420
+msgid "the `-E' option is not valid in edit mode"
+msgstr "параметр «-E» не действует в режиме редактирования"
+
+#: src/parse_args.c:422
+msgid "you may not specify environment variables in edit mode"
+msgstr "переменные окружения нельзя определять в режиме редактирования"
+
+#: src/parse_args.c:430
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "параметр «-U» можно использовать только с параметром «-l»"
+
+#: src/parse_args.c:434
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "параметры «-A» и «-S» являются взаимоисключающими"
+
+#: src/parse_args.c:504
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit не поддерживается на этой платформе"
+
+#: src/parse_args.c:577
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Можно указать только параметры -e, -h, -i, -K, -l, -s, -v или -V"
+
+#: src/parse_args.c:591
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s — редактирование файлов от имени другого пользователя\n"
+"\n"
+
+#: src/parse_args.c:593
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s — выполнение команд от имени другого пользователя\n"
+"\n"
+
+#: src/parse_args.c:598
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Параметры:\n"
+
+#: src/parse_args.c:600
+msgid "use a helper program for password prompting"
+msgstr "использовать вспомогательную программу для ввода пароля"
+
+#: src/parse_args.c:603
+msgid "use specified BSD authentication type"
+msgstr "использовать указанный тип проверки подлинности BSD"
+
+#: src/parse_args.c:606
+msgid "run command in the background"
+msgstr "выполнить команду в фоновом режиме"
+
+#: src/parse_args.c:608
+msgid "close all file descriptors >= num"
+msgstr "закрыть все дескрипторы файлов >= num"
+
+#: src/parse_args.c:611
+msgid "run command with the specified BSD login class"
+msgstr "выполнить команду с указанным классом входа BSD в систему"
+
+#: src/parse_args.c:614
+msgid "preserve user environment when running command"
+msgstr "сохранить пользовательское окружение при выполнении команды"
+
+#: src/parse_args.c:616
+msgid "edit files instead of running a command"
+msgstr "редактировать файлы вместо выполнения команды"
+
+#: src/parse_args.c:618
+msgid "run command as the specified group name or ID"
+msgstr "выполнить команду от имени или ID указанной группы"
+
+#: src/parse_args.c:620
+msgid "set HOME variable to target user's home dir"
+msgstr "установить для переменной HOME домашний каталог указанного пользователя"
+
+#: src/parse_args.c:622
+msgid "display help message and exit"
+msgstr "показать справку и выйти"
+
+#: src/parse_args.c:624
+msgid "run command on host (if supported by plugin)"
+msgstr "выполнить команду на узле (если поддерживается модулем)"
+
+#: src/parse_args.c:626
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "запустить оболочку входа в систему от имени указанного пользователя; также можно задать команду"
+
+#: src/parse_args.c:628
+msgid "remove timestamp file completely"
+msgstr "полностью удалить файл timestamp"
+
+#: src/parse_args.c:630
+msgid "invalidate timestamp file"
+msgstr "объявить недействительным файл timestamp"
+
+#: src/parse_args.c:632
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "показать список прав пользователя или проверить заданную команду; в длинном формате используется дважды"
+
+#: src/parse_args.c:634
+msgid "non-interactive mode, no prompts are used"
+msgstr "автономный режим без не вывода запросов пользователю"
+
+#: src/parse_args.c:636
+msgid "preserve group vector instead of setting to target's"
+msgstr "сохранить вектор группы вместо установки целевой группы"
+
+#: src/parse_args.c:638
+msgid "use the specified password prompt"
+msgstr "использовать указанный запрос пароля"
+
+#: src/parse_args.c:641
+msgid "create SELinux security context with specified role"
+msgstr "создать контекст безопасности SELinux с указанной ролью"
+
+#: src/parse_args.c:644
+msgid "read password from standard input"
+msgstr "читать пароль из стандартного ввода"
+
+#: src/parse_args.c:646
+msgid "run shell as the target user; a command may also be specified"
+msgstr "запустить оболочку от имени указанного пользователя; также можно задать команду"
+
+#: src/parse_args.c:649
+msgid "create SELinux security context with specified type"
+msgstr "создать контекст безопасности SELinux указанного типа"
+
+#: src/parse_args.c:652
+msgid "in list mode, display privileges for user"
+msgstr "в режиме списка показывать права пользователя"
+
+#: src/parse_args.c:654
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "выполнить команду (или редактировать файл) от имени или ID указанного пользователя"
+
+#: src/parse_args.c:656
+msgid "display version information and exit"
+msgstr "показать сведения о версии и выйти"
+
+#: src/parse_args.c:658
+msgid "update user's timestamp without running a command"
+msgstr "обновить временную метку пользователя без выполнения команды"
+
+#: src/parse_args.c:660
+msgid "stop processing command line arguments"
+msgstr "прекратить обработку аргументов командной строки"
+
+#: src/selinux.c:78
+msgid "unable to open audit system"
+msgstr "не удаётся открыть систему аудита"
+
+#: src/selinux.c:88
+msgid "unable to send audit message"
+msgstr "не удаётся отправить сообщение аудита"
+
+#: src/selinux.c:116
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "не удаётся выполнить fgetfilecon %s"
+
+#: src/selinux.c:121
+#, c-format
+msgid "%s changed labels"
+msgstr "изменено меток: %s"
+
+#: src/selinux.c:126
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "не удаётся восстановить контекст для %s"
+
+#: src/selinux.c:166
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "не удаётся открыть %s, tty без возможности переименования"
+
+#: src/selinux.c:175
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "не удаётся получить контекст текущего tty, tty без возможности переименования"
+
+#: src/selinux.c:182
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "не удаётся получить контекст tty, tty без возможности переименования"
+
+#: src/selinux.c:189
+msgid "unable to set new tty context"
+msgstr "не удаётся установить новый контекст tty"
+
+#: src/selinux.c:255
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "необходимо указать роль для типа %s"
+
+#: src/selinux.c:261
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "не удаётся получить тип по умолчанию для роли %s"
+
+#: src/selinux.c:279
+#, c-format
+msgid "failed to set new role %s"
+msgstr "не удалось установить новую роль %s"
+
+#: src/selinux.c:283
+#, c-format
+msgid "failed to set new type %s"
+msgstr "не удалось установить новый тип %s"
+
+#: src/selinux.c:295
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s не является допустимым контекстом"
+
+#: src/selinux.c:330
+msgid "failed to get old_context"
+msgstr "не удалось получить old_context"
+
+#: src/selinux.c:336
+msgid "unable to determine enforcing mode."
+msgstr "не удаётся определить принудительный режим"
+
+#: src/selinux.c:353
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "не удаётся задать контекст tty для %s"
+
+#: src/selinux.c:392
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "не удаётся установить для контекста exec значение %s"
+
+#: src/selinux.c:399
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "не удаётся установить для контекста создания ключа значение %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "укажите не менее одного аргумента"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "неверный номер файлового дескриптора: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "не удаётся выполнить %s в качестве регистрационной оболочки"
+
+#: src/sesh.c:125 src/sudo.c:1274
+#, c-format
+msgid "unable to execute %s"
+msgstr "не удаётся выполнить %s"
+
+#: src/signal.c:68
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "не удаётся сохранить обработчик сигнала %d"
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "достигнут лимит управления ресурсами"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "пользователь «%s» не является членом проекта «%s»"
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr "вызывающе задание — последнее"
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "не удалось присоединиться к проекту «%s»"
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "для проекта «%s» не существует пула ресурсов, принимающих привязки по умолчанию"
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "у проекта «%s» нет указанного пула ресурсов"
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "не удаётся подключиться к пулу ресурсов по умолчанию проекта «%s»"
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "setproject завершилась с ошибкой для проекта «%s»"
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "предупреждение: назначение контроля за ресурсами завершилось с ошибкой для проекта «%s»"
+
+#: src/sudo.c:212
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo версия %s\n"
+
+#: src/sudo.c:214
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Параметры настройки: %s\n"
+
+#: src/sudo.c:222
+msgid "fatal error, unable to load plugins"
+msgstr "фатальная ошибка, не удалось загрузить модули"
+
+#: src/sudo.c:230
+msgid "unable to initialize policy plugin"
+msgstr "не удаётся инициализировать модуль политики"
+
+#: src/sudo.c:276
+msgid "plugin did not return a command to execute"
+msgstr "модуль не вернул команду для выполнения"
+
+#: src/sudo.c:292
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "ошибка инициализации модуля ввода-вывода %s"
+
+#: src/sudo.c:318
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "неожиданный режим sudo: 0x%x"
+
+#: src/sudo.c:461
+msgid "unable to get group vector"
+msgstr "не удаётся получить вектор группы"
+
+#: src/sudo.c:522
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "неизвестный uid %u: кто вы?"
+
+#: src/sudo.c:859
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s должен принадлежать пользователю с uid %d и иметь бит setuid"
+
+#: src/sudo.c:862
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "эффективный uid не равен %d, возможно, %s находится в файловой системе, смонтированной с битом «nosuid» или в файловой системе NFS без прав суперпользователя?"
+
+#: src/sudo.c:868
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "эффективный uid не равен %d, программа sudo установлена с битом setuid и принадлежит root?"
+
+#: src/sudo.c:999
+#, c-format
+msgid "unknown login class %s"
+msgstr "неизвестный класс входа %s"
+
+#: src/sudo.c:1012
+msgid "unable to set user context"
+msgstr "не удаётся назначить контекст пользователя"
+
+#: src/sudo.c:1026
+msgid "unable to set supplementary group IDs"
+msgstr "не удаётся назначить дополнительные идентификаторы групп"
+
+#: src/sudo.c:1033
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "не удаётся назначить эффективный gid на runas gid %u"
+
+#: src/sudo.c:1039
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "не удаётся назначить gid на runas gid %u"
+
+#: src/sudo.c:1046
+msgid "unable to set process priority"
+msgstr "не удаётся назначить приоритет процесса"
+
+#: src/sudo.c:1054
+#, c-format
+msgid "unable to change root to %s"
+msgstr "не удаётся изменить root на %s"
+
+#: src/sudo.c:1067 src/sudo.c:1073 src/sudo.c:1080
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "не удаётся изменить на runas uid (%u, %u)"
+
+#: src/sudo.c:1098
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "не удаётся сменить каталог на %s"
+
+#: src/sudo.c:1156
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "неожиданное условие завершения потомка: %d"
+
+#: src/sudo.c:1302
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "модуль политики %s не содержит метод «check_policy»"
+
+#: src/sudo.c:1320
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "модуль политики %s не поддерживает списка прав"
+
+#: src/sudo.c:1337
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "модуль политики %s не поддерживает параметр -v"
+
+#: src/sudo.c:1352
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "модуль политики %s не поддерживает параметры -k/-K"
+
+#: src/sudo_edit.c:181
+msgid "unable to restore current working directory"
+msgstr "не удалось восстановить текущий рабочий каталог"
+
+#: src/sudo_edit.c:526 src/sudo_edit.c:630
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: не обычный файл"
+
+#: src/sudo_edit.c:533
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: изменение символических ссылок не допускается"
+
+#: src/sudo_edit.c:536
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: изменение файлов в каталоге, доступном на запись, не допускается"
+
+#: src/sudo_edit.c:567 src/sudo_edit.c:669
+#, c-format
+msgid "%s: short write"
+msgstr "%s: неполная запись"
+
+#: src/sudo_edit.c:631
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s осталось неизменным"
+
+#: src/sudo_edit.c:644 src/sudo_edit.c:830
+#, c-format
+msgid "%s unchanged"
+msgstr "%s не изменено"
+
+#: src/sudo_edit.c:658 src/sudo_edit.c:680
+#, c-format
+msgid "unable to write to %s"
+msgstr "не удаётся записать в %s"
+
+#: src/sudo_edit.c:659 src/sudo_edit.c:678 src/sudo_edit.c:681
+#: src/sudo_edit.c:855 src/sudo_edit.c:859
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "содержимое сеанса редактирования сохранено в %s"
+
+#: src/sudo_edit.c:677
+msgid "unable to read temporary file"
+msgstr "не удалось прочитать временный файл"
+
+#: src/sudo_edit.c:760
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: внутренняя ошибка: нечётное количество путей"
+
+#: src/sudo_edit.c:762
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: не удалось создать временные файлы"
+
+#: src/sudo_edit.c:764 src/sudo_edit.c:862
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: неизвестная ошибка %d"
+
+#: src/sudo_edit.c:854
+msgid "unable to copy temporary files back to their original location"
+msgstr "не удалось скопировать временные файлы обратно в изначальное положение"
+
+#: src/sudo_edit.c:858
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "не удалось скопировать некоторые из временных файлов обратно в изначальное положение"
+
+#: src/sudo_edit.c:901
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "не удалось изменить uid на root (%u)"
+
+#: src/sudo_edit.c:918
+msgid "plugin error: missing file list for sudoedit"
+msgstr "ошибка модуля: отсутствует список файлов для sudoedit"
+
+#: src/sudo_edit.c:959 src/sudo_edit.c:972
+msgid "unable to read the clock"
+msgstr "не удалось прочитать время"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr "нет tty и не указана программа askpass"
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "не указана программа askpass, попробуйте задать значение в SUDO_ASKPASS"
+
+#: src/tgetpass.c:276
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "не удаётся назначить gid равным %u"
+
+#: src/tgetpass.c:280
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "не удаётся назначить uid равным %u"
+
+#: src/tgetpass.c:285
+#, c-format
+msgid "unable to run %s"
+msgstr "не удаётся выполнить %s"
+
+#: src/utmp.c:266
+msgid "unable to save stdin"
+msgstr "не удаётся сохранить стандартный ввод"
+
+#: src/utmp.c:268
+msgid "unable to dup2 stdin"
+msgstr "не удаётся выполнить dup2 для стандартного ввода"
+
+#: src/utmp.c:271
+msgid "unable to restore stdin"
+msgstr "не удаётся восстановить стандартный ввод"
+
+#~ msgid "internal error, tried allocate zero bytes"
+#~ msgstr "внутренняя ошибка, попытка выделить 0 байт"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "не удаётся перевести терминал в «сырой» режим"
+
+#~ msgid "unable to open socket"
+#~ msgstr "не удаётся открыть сокет"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "внутренняя ошибка, попытка выполнить emalloc2(0)"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "внутренняя ошибка, попытка выполнить ecalloc(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "внутренняя ошибка, попытка выполнить erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "внутренняя ошибка, попытка выполнить erealloc3(0)"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "внутренняя ошибка, попытка выполнить ereсalloc(0)"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: обнаружено переполнение"
+
+#~ msgid "value out of range"
+#~ msgstr "значение за пределами диапазона"
+
+#~ msgid "select failed"
+#~ msgstr "ошибка select"
+
+#~ msgid "list user's available commands\n"
+#~ msgstr "вывести список команд, доступных пользователю\n"
+
+#~ msgid "run a shell as target user\n"
+#~ msgstr "запустить оболочку от имени указанного пользователя\n"
+
+#~ msgid "when listing, list specified user's privileges\n"
+#~ msgstr "при выводе списка показать привилегии пользователя\n"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "internal error, emalloc2() overflow"
+#~ msgstr "внутренняя ошибка, переполнение emalloc2()"
+
+#~ msgid "internal error, erealloc3() overflow"
+#~ msgstr "внутренняя ошибка, переполнение erealloc3()"
+
+#~ msgid "%s: at least one policy plugin must be specified"
+#~ msgstr "%s: необходимо указать не менее одного модуля политики"
+
+#~ msgid "must be setuid root"
+#~ msgstr "требуется setuid пользователя root"
+
+#~ msgid "the argument to -D must be between 1 and 9 inclusive"
+#~ msgstr "аргумент для -D должен быть в диапазоне от 1 до 9 включительно"
diff --git a/po/sk.mo b/po/sk.mo
new file mode 100644
index 0000000..597a3c7
--- /dev/null
+++ b/po/sk.mo
Binary files differ
diff --git a/po/sk.po b/po/sk.po
new file mode 100644
index 0000000..2c00dbb
--- /dev/null
+++ b/po/sk.po
@@ -0,0 +1,858 @@
+# Portable object template file for sudo
+# This file is put in the public domain.
+# Todd C. Miller <Todd.Miller@courtesan.com>, 2011-2015
+# Dušan Kazik <prescott66@gmail.com>, 2015-2016
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.16b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2016-02-19 15:48-0700\n"
+"PO-Revision-Date: 2016-03-20 10:56+0100\n"
+"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
+"Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
+"Language: sk\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.7\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+"X-Poedit-Basepath: .\n"
+"X-Poedit-SearchPath-0: .\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:164
+msgid "unable to open userdb"
+msgstr "nie je možné otvoriť userdb"
+
+#: lib/util/aix.c:219
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "nie je možné prepnúť na register „%s“ pre %s"
+
+#: lib/util/aix.c:244
+msgid "unable to restore registry"
+msgstr "nie je možné obnoviť register"
+
+#: lib/util/aix.c:267 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:207 lib/util/sudo_conf.c:290 lib/util/sudo_conf.c:367
+#: lib/util/sudo_conf.c:569 src/conversation.c:75 src/exec.c:863
+#: src/exec_common.c:107 src/exec_common.c:123 src/exec_common.c:132
+#: src/exec_pty.c:684 src/exec_pty.c:692 src/load_plugins.c:52
+#: src/load_plugins.c:65 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:180
+#: src/parse_args.c:202 src/parse_args.c:370 src/parse_args.c:466
+#: src/parse_args.c:485 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:291 src/selinux.c:416 src/selinux.c:425
+#: src/sesh.c:115 src/sudo.c:201 src/sudo.c:398 src/sudo.c:417 src/sudo.c:481
+#: src/sudo.c:655 src/sudo.c:665 src/sudo.c:685 src/sudo.c:704 src/sudo.c:713
+#: src/sudo.c:722 src/sudo.c:739 src/sudo.c:780 src/sudo.c:790 src/sudo.c:810
+#: src/sudo.c:1215 src/sudo.c:1236 src/sudo.c:1398 src/sudo.c:1492
+#: src/sudo_edit.c:151 src/sudo_edit.c:716 src/sudo_edit.c:813
+#: src/sudo_edit.c:925 src/sudo_edit.c:945
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:267 lib/util/gidlist.c:64 lib/util/sudo_conf.c:208
+#: lib/util/sudo_conf.c:290 lib/util/sudo_conf.c:367 lib/util/sudo_conf.c:569
+#: src/conversation.c:76 src/exec.c:863 src/exec_common.c:107
+#: src/exec_common.c:124 src/exec_common.c:133 src/exec_pty.c:684
+#: src/exec_pty.c:692 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:180
+#: src/parse_args.c:202 src/parse_args.c:370 src/parse_args.c:466
+#: src/parse_args.c:485 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:291 src/selinux.c:416 src/selinux.c:425
+#: src/sesh.c:115 src/sudo.c:201 src/sudo.c:398 src/sudo.c:417 src/sudo.c:481
+#: src/sudo.c:810 src/sudo.c:1215 src/sudo.c:1236 src/sudo.c:1398
+#: src/sudo.c:1492 src/sudo_edit.c:151 src/sudo_edit.c:716 src/sudo_edit.c:813
+#: src/sudo_edit.c:925 src/sudo_edit.c:945
+msgid "unable to allocate memory"
+msgstr "nie je možné alokovať pamäť"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "Neznámy signál"
+
+#: lib/util/strtoid.c:76 lib/util/strtoid.c:104 lib/util/strtomode.c:48
+#: lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "neplatná hodnota"
+
+#: lib/util/strtoid.c:83 lib/util/strtoid.c:111 lib/util/strtomode.c:54
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "hodnota je príliš veľká"
+
+#: lib/util/strtoid.c:89 lib/util/strtomode.c:54 lib/util/strtonum.c:61
+#: lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "hodnota je príliš malá"
+
+#: lib/util/sudo_conf.c:223
+#, c-format
+msgid "invalid Path value `%s' in %s, line %u"
+msgstr "neplatná hodnota pre cestu „%s“ v %s, riadok %u"
+
+#: lib/util/sudo_conf.c:389 lib/util/sudo_conf.c:442
+#, c-format
+msgid "invalid value for %s `%s' in %s, line %u"
+msgstr "neplatná hodnota pre %s „%s“ v %s, riadok %u"
+
+#: lib/util/sudo_conf.c:410
+#, c-format
+msgid "unsupported group source `%s' in %s, line %u"
+msgstr "nepodporovaný zdroj skupiny „%s“ v %s, riadok %u"
+
+#: lib/util/sudo_conf.c:426
+#, c-format
+msgid "invalid max groups `%s' in %s, line %u"
+msgstr ""
+
+#: lib/util/sudo_conf.c:585
+#, c-format
+msgid "unable to stat %s"
+msgstr ""
+
+#: lib/util/sudo_conf.c:588
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s nie je regulárny súbor"
+
+#: lib/util/sudo_conf.c:591
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s je vlastnený identifikátorom uid %u a mal by byť vlastnený %u"
+
+#: lib/util/sudo_conf.c:595
+#, c-format
+msgid "%s is world writable"
+msgstr ""
+
+#: lib/util/sudo_conf.c:598
+#, c-format
+msgid "%s is group writable"
+msgstr ""
+
+#: lib/util/sudo_conf.c:608 src/selinux.c:199 src/selinux.c:212 src/sudo.c:367
+#, c-format
+msgid "unable to open %s"
+msgstr "nie je možné otvoriť %s"
+
+#: src/exec.c:114 src/exec.c:116 src/exec.c:121 src/exec.c:409 src/exec.c:411
+#: src/exec.c:413 src/exec.c:415 src/exec.c:417 src/exec.c:419 src/exec.c:422
+#: src/exec.c:438 src/exec.c:440 src/exec.c:595 src/exec.c:790
+#: src/exec_pty.c:466 src/exec_pty.c:722 src/exec_pty.c:792 src/exec_pty.c:794
+#: src/exec_pty.c:806 src/exec_pty.c:808 src/exec_pty.c:1289
+#: src/exec_pty.c:1291 src/exec_pty.c:1296 src/exec_pty.c:1298
+#: src/exec_pty.c:1312 src/exec_pty.c:1323 src/exec_pty.c:1325
+#: src/exec_pty.c:1327 src/exec_pty.c:1329 src/exec_pty.c:1331
+#: src/exec_pty.c:1333 src/exec_pty.c:1335 src/signal.c:147
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr ""
+
+#: src/exec.c:126 src/exec_pty.c:838 src/exec_pty.c:1373 src/tgetpass.c:265
+msgid "unable to fork"
+msgstr ""
+
+#: src/exec.c:304 src/exec.c:312 src/exec.c:868 src/exec_pty.c:604
+#: src/exec_pty.c:611 src/exec_pty.c:654 src/exec_pty.c:659 src/exec_pty.c:946
+#: src/exec_pty.c:956 src/exec_pty.c:1001 src/exec_pty.c:1008
+#: src/exec_pty.c:1438 src/exec_pty.c:1445 src/exec_pty.c:1452
+msgid "unable to add event to queue"
+msgstr ""
+
+#: src/exec.c:392
+msgid "unable to create sockets"
+msgstr "nie je možné vytvoriť sokety"
+
+#: src/exec.c:447
+msgid "policy plugin failed session initialization"
+msgstr ""
+
+#: src/exec.c:492
+msgid "error in event loop"
+msgstr ""
+
+#: src/exec.c:510
+msgid "unable to restore tty label"
+msgstr "nie je možné obnoviť menovku rozhrania tty"
+
+#: src/exec.c:603 src/exec_pty.c:498 src/signal.c:86
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr ""
+
+#: src/exec.c:721 src/exec_pty.c:1180
+msgid "error reading from signal pipe"
+msgstr "chyba pri čítaní zo zreťazenia signálov"
+
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "nie je možné odstrániť PRIV_PROC_EXEC z PRIV_LIMIT"
+
+#: src/exec_pty.c:188
+msgid "unable to allocate pty"
+msgstr "nie je možné alokovať pty"
+
+#: src/exec_pty.c:766 src/exec_pty.c:775 src/exec_pty.c:783
+#: src/exec_pty.c:1281 src/exec_pty.c:1370 src/signal.c:128 src/tgetpass.c:261
+msgid "unable to create pipe"
+msgstr "nie je možné vytvoriť zreťazenie"
+
+#: src/exec_pty.c:1213
+msgid "error reading from pipe"
+msgstr "chyba pri čítaní zo zreťazenia"
+
+#: src/exec_pty.c:1238
+msgid "error reading from socketpair"
+msgstr ""
+
+#: src/exec_pty.c:1247
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "neočakávaný typ odpovede na zadnom kanále: %d"
+
+#: src/exec_pty.c:1349
+msgid "unable to set controlling tty"
+msgstr "nie je možné nastaviť ovládacie rozhranie tty"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin `%s'"
+msgstr "chyba v %s, riadok%d počas načítania zásuvného modulu „%s“"
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s musí byť vlastnený identifikátorom uid %d"
+
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s musí byť zapisovateľný iba vlastníkom"
+
+#: src/load_plugins.c:172
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "nie je možné načítať %s:%s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unable to find symbol `%s' in %s"
+msgstr "nie je možné nájsť symbol „%s“ v %s"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "našiel sa neplatný typ politiky %d v %s"
+
+#: src/load_plugins.c:193
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "nekompatibilná hlavná verzia zásuvného modulu %d (očakávala sa %d) nájdená v %s"
+
+#: src/load_plugins.c:202
+#, c-format
+msgid "ignoring policy plugin `%s' in %s, line %d"
+msgstr "ignoruje sa zásuvný modul politiky „%s“ v %s, riadok %d"
+
+#: src/load_plugins.c:204
+msgid "only a single policy plugin may be specified"
+msgstr "môže byť určený iba jeden zásuvný modul politiky"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring duplicate policy plugin `%s' in %s, line %d"
+msgstr "ignoruje sa zdvojený zásuvný modul politiky „%s“ v %s, riadok %d"
+
+#: src/load_plugins.c:228
+#, c-format
+msgid "ignoring duplicate I/O plugin `%s' in %s, line %d"
+msgstr "ignoruje sa zdvojený vstupno-výstupný zásuvný modul „%s“ v %s, riadok %d"
+
+#: src/load_plugins.c:331
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "zásuvný modul politiky %s nezahŕňa spôsob check_policy"
+
+#: src/net_ifs.c:173 src/net_ifs.c:190 src/net_ifs.c:335 src/sudo.c:476
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "vnútorná chyba, %s pretečenie"
+
+#: src/parse_args.c:239
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "parameter pre -C musí byť číslo väčšie alebo rovné 3"
+
+#: src/parse_args.c:406
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "nemôžete určiť naraz voľby „-i“ a „-s“"
+
+#: src/parse_args.c:410
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "nemôžete určiť naraz voľby „-i“ a „-E“"
+
+#: src/parse_args.c:420
+msgid "the `-E' option is not valid in edit mode"
+msgstr "voľba „-E“ nie je platná v režime úprav"
+
+#: src/parse_args.c:422
+msgid "you may not specify environment variables in edit mode"
+msgstr "nemôžete určiť premenné prostredia v režim úprav"
+
+#: src/parse_args.c:430
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "voľba „-U“ môže byť použitá iba s voľbou „-l“"
+
+#: src/parse_args.c:434
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "voľby „-A“ a „-S“ nemôžu byť použité zároveň"
+
+#: src/parse_args.c:504
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit nie je podporovaný na tejto platforme"
+
+#: src/parse_args.c:577
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Môže byť určená iba jedna z volieb -e, -h, -i, -K, -l, -s, -v alebo -V"
+
+#: src/parse_args.c:591
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - upravuje súbory ako iný používateľ\n"
+"\n"
+
+#: src/parse_args.c:593
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - vykonáva príkaz ako iný používateľ\n"
+"\n"
+
+#: src/parse_args.c:598
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Voľby:\n"
+
+#: src/parse_args.c:600
+msgid "use a helper program for password prompting"
+msgstr "použije pomocný program na pýtanie hesla "
+
+#: src/parse_args.c:603
+msgid "use specified BSD authentication type"
+msgstr ""
+
+#: src/parse_args.c:606
+msgid "run command in the background"
+msgstr "spustí príkaz na pozadí"
+
+#: src/parse_args.c:608
+msgid "close all file descriptors >= num"
+msgstr "zavrie všetky popisovače súborov >= číslo"
+
+#: src/parse_args.c:611
+msgid "run command with the specified BSD login class"
+msgstr "spustí príkaz s určenou triedou prihlásenia BSD"
+
+#: src/parse_args.c:614
+msgid "preserve user environment when running command"
+msgstr "zachová rozhranie používateľa, keď sa spúšťa príkaz"
+
+#: src/parse_args.c:616
+msgid "edit files instead of running a command"
+msgstr "upraví súbory namiesto spustenia príkazu"
+
+#: src/parse_args.c:618
+msgid "run command as the specified group name or ID"
+msgstr "spustí príkaz ako určený názov skupiny alebo ID"
+
+#: src/parse_args.c:620
+msgid "set HOME variable to target user's home dir"
+msgstr "nastaví premennú HOME do domovského adresára cieľového používateľa"
+
+#: src/parse_args.c:622
+msgid "display help message and exit"
+msgstr "zobrazí správu pomocníka a skončí"
+
+#: src/parse_args.c:624
+msgid "run command on host (if supported by plugin)"
+msgstr "spustí príkaz na hostiteľovi (ak je podporované zásuvným modulom)"
+
+#: src/parse_args.c:626
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "spustí príkazový riadok prihlásenia, príkaz môže byť tiež určený"
+
+#: src/parse_args.c:628
+msgid "remove timestamp file completely"
+msgstr "úplne odstráni súbor časovej značky"
+
+#: src/parse_args.c:630
+msgid "invalidate timestamp file"
+msgstr "urobí súbor časovej značky neplatným"
+
+#: src/parse_args.c:632
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "vypíše právomoci používateľa, alebo skontroluje určený príkaz; použite dvakrát pre dlhší formát"
+
+#: src/parse_args.c:634
+msgid "non-interactive mode, no prompts are used"
+msgstr "neinteraktívny režim, nebudú použité žiadne výzvy"
+
+#: src/parse_args.c:636
+msgid "preserve group vector instead of setting to target's"
+msgstr ""
+
+#: src/parse_args.c:638
+msgid "use the specified password prompt"
+msgstr "použije určenú výzvu na heslo"
+
+#: src/parse_args.c:641
+msgid "create SELinux security context with specified role"
+msgstr "vytvorí bezpečnostný kontext systému SELinux s určenou rolou"
+
+#: src/parse_args.c:644
+msgid "read password from standard input"
+msgstr "bude čítať heslo zo štandardného vstupu"
+
+#: src/parse_args.c:646
+msgid "run shell as the target user; a command may also be specified"
+msgstr ""
+
+#: src/parse_args.c:649
+msgid "create SELinux security context with specified type"
+msgstr "vytvorí bezpečnostný kontext systému SELinux s určeným typom"
+
+#: src/parse_args.c:652
+msgid "in list mode, display privileges for user"
+msgstr "v režime výpisu, zobrazí právomoci používateľa"
+
+#: src/parse_args.c:654
+msgid "run command (or edit file) as specified user name or ID"
+msgstr ""
+
+#: src/parse_args.c:656
+msgid "display version information and exit"
+msgstr "zobrazí informácie o verzii a skončí"
+
+#: src/parse_args.c:658
+msgid "update user's timestamp without running a command"
+msgstr ""
+
+#: src/parse_args.c:660
+msgid "stop processing command line arguments"
+msgstr "zastaví spracovávanie parametrov príkazového riadku"
+
+#: src/selinux.c:78
+msgid "unable to open audit system"
+msgstr "nie je možné otvoriť systém auditu"
+
+#: src/selinux.c:88
+msgid "unable to send audit message"
+msgstr "nie je možné odoslať správu auditu"
+
+#: src/selinux.c:116
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "nie je možné vykonať funkciu fgetfilecon na %s"
+
+#: src/selinux.c:121
+#, c-format
+msgid "%s changed labels"
+msgstr ""
+
+#: src/selinux.c:126
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "nie je možné obnoviť kontext pre %s"
+
+#: src/selinux.c:166
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "nie je možné otvoriť %s, rozhranie tty nebude mať zmenenú menovku"
+
+#: src/selinux.c:175
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "nie je možné získať aktuálny kontext rozhrania tty, rozhranie tty nebude mať zmenenú menovku"
+
+#: src/selinux.c:182
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "nie je možné získať nový kontext tty, rozhranie tty nebude mať zmenenú menovku"
+
+#: src/selinux.c:189
+msgid "unable to set new tty context"
+msgstr "nie je možné nastaviť nový kontext rozhrania tty"
+
+#: src/selinux.c:255
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "musíte určiť typ roly pre %s"
+
+#: src/selinux.c:261
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "nie je možné získať predvolený typ roly %s"
+
+#: src/selinux.c:279
+#, c-format
+msgid "failed to set new role %s"
+msgstr "zlyhalo nastavenie novej roly %s"
+
+#: src/selinux.c:283
+#, c-format
+msgid "failed to set new type %s"
+msgstr "zlyhalo nastavenie nového typu %s"
+
+#: src/selinux.c:295
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s nie je platný kontext"
+
+#: src/selinux.c:330
+msgid "failed to get old_context"
+msgstr "zlyhalo získanie old_context"
+
+#: src/selinux.c:336
+msgid "unable to determine enforcing mode."
+msgstr ""
+
+#: src/selinux.c:353
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "nie je možné nastaviť kontext rozhrania tty na %s"
+
+#: src/selinux.c:392
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "nie je možné nastaviť kontext exec na %s"
+
+#: src/selinux.c:399
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "nie je možné nastaviť kontext tvorby kľúča na %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "vyžaduje aspoň jeden parameter"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "neplatné číslo popisovača súboru: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "nie je možné spustiť %s ako terminál prihlásenia"
+
+#: src/sesh.c:125 src/sudo.c:1274
+#, c-format
+msgid "unable to execute %s"
+msgstr "nie je možné vykonať %s"
+
+#: src/signal.c:68
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr ""
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "bol dosiahnutý limit ovládania prostriedkov"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "používateľ „%s“ nie je členom projektu „%s“"
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr "vyvolávajúca úloha je konečná"
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "nepodarilo sa vstúpiť do projektu „%s“"
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr ""
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr ""
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr ""
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "funkcia setproject zlyhala pre projekt „%s“"
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "upozornenie, zlyhalo priradenie ovládania prostriedkov pre projekt „%s“"
+
+#: src/sudo.c:212
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Verzia programu sudo %s\n"
+
+#: src/sudo.c:214
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Voľby konfigurácie: %s\n"
+
+#: src/sudo.c:222
+msgid "fatal error, unable to load plugins"
+msgstr "závažná chyba, nie je možné načítať zásuvné moduly"
+
+#: src/sudo.c:230
+msgid "unable to initialize policy plugin"
+msgstr "nie je možné inicializovať zásuvný modul politiky"
+
+#: src/sudo.c:276
+msgid "plugin did not return a command to execute"
+msgstr ""
+
+#: src/sudo.c:292
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "chyba pri inicializácii vstupno-výstupného zásuvného modulu %s"
+
+#: src/sudo.c:318
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "neočakávaný režim sudo 0x%x"
+
+#: src/sudo.c:461
+msgid "unable to get group vector"
+msgstr "nie je možné získať vektor skupiny"
+
+#: src/sudo.c:522
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "neznámy identifikátor uid %u: kto ste?"
+
+#: src/sudo.c:859
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s musí byť vlastnený identifikátorom uid %d a musí mať nastavený bit setuid"
+
+#: src/sudo.c:862
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "efektívny identifikátor uid nie je %d, je %s na systéme súborov s nastavenou voľbou „nosuid“, alebo na systéme súborov NFS bez právomocí administrátora?"
+
+#: src/sudo.c:868
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr ""
+
+#: src/sudo.c:999
+#, c-format
+msgid "unknown login class %s"
+msgstr "neznáma trieda prihlásenia %s"
+
+#: src/sudo.c:1012
+msgid "unable to set user context"
+msgstr "nie je možné nastaviť kontext používateľa"
+
+#: src/sudo.c:1026
+msgid "unable to set supplementary group IDs"
+msgstr ""
+
+#: src/sudo.c:1033
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr ""
+
+#: src/sudo.c:1039
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr ""
+
+#: src/sudo.c:1046
+msgid "unable to set process priority"
+msgstr "nie je možné nastaviť prioritu procesu"
+
+#: src/sudo.c:1054
+#, c-format
+msgid "unable to change root to %s"
+msgstr "nie je možné zmeniť administrátora na %s"
+
+#: src/sudo.c:1067 src/sudo.c:1073 src/sudo.c:1080
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr ""
+
+#: src/sudo.c:1098
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "nie je možné zmeniť adresár na %s"
+
+#: src/sudo.c:1156
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "neočakávaná podmienka prerušenia potomka: %d"
+
+#: src/sudo.c:1302
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "zásuvnému modulu politiky %s chýba spôsob „check_policy“"
+
+#: src/sudo.c:1320
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "zásuvný modul politiky %s nepodporuje výpis právomocí"
+
+#: src/sudo.c:1337
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr ""
+
+#: src/sudo.c:1352
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr ""
+
+#: src/sudo_edit.c:181
+msgid "unable to restore current working directory"
+msgstr "nie je možné obnoviť aktuálny pracovný adresár"
+
+#: src/sudo_edit.c:526 src/sudo_edit.c:630
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: nie je regulárny súbor"
+
+#: src/sudo_edit.c:533
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: upravovanie symbolických odkazov nie je dovolené"
+
+#: src/sudo_edit.c:536
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: upravovanie súborov v zapisovateľnom adresári nie je dovolené"
+
+#: src/sudo_edit.c:567 src/sudo_edit.c:669
+#, c-format
+msgid "%s: short write"
+msgstr "%s: krátky zápis"
+
+#: src/sudo_edit.c:631
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s zostal nezmenený"
+
+#: src/sudo_edit.c:644 src/sudo_edit.c:830
+#, c-format
+msgid "%s unchanged"
+msgstr "%s nezmenený"
+
+#: src/sudo_edit.c:658 src/sudo_edit.c:680
+#, c-format
+msgid "unable to write to %s"
+msgstr "nie je možné zapísať do %s"
+
+#: src/sudo_edit.c:659 src/sudo_edit.c:678 src/sudo_edit.c:681
+#: src/sudo_edit.c:855 src/sudo_edit.c:859
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "obsah upravovanej relácie zostal v %s"
+
+#: src/sudo_edit.c:677
+msgid "unable to read temporary file"
+msgstr "nie je možné čítať dočasný súbor"
+
+#: src/sudo_edit.c:760
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: vnútorná chyba: nepárne čísla ciest"
+
+#: src/sudo_edit.c:762
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: nie je možné vytvoriť dočasné súbory"
+
+#: src/sudo_edit.c:764 src/sudo_edit.c:862
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: neznáma chyba %d"
+
+#: src/sudo_edit.c:854
+msgid "unable to copy temporary files back to their original location"
+msgstr "nie je možné skopírovať dočasné súbory späť do ich pôvodného umiestnenia"
+
+#: src/sudo_edit.c:858
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "nie je možné skopírovať niektoré z dočasných súborov späť do ich pôvodného umiestnenia"
+
+#: src/sudo_edit.c:901
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "nie je možné zmeniť identifikátor uid na administrátora (%u)"
+
+#: src/sudo_edit.c:918
+msgid "plugin error: missing file list for sudoedit"
+msgstr "chyba zásuvného modulu: chýba zoznam súborov pre sudoedit"
+
+#: src/sudo_edit.c:959 src/sudo_edit.c:972
+msgid "unable to read the clock"
+msgstr "nie je možné čítať hodiny"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr ""
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr ""
+
+#: src/tgetpass.c:276
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "nie je možné nastaviť identifikátor gid na %u"
+
+#: src/tgetpass.c:280
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "nie je možné nastaviť identifikátor uid na %u"
+
+#: src/tgetpass.c:285
+#, c-format
+msgid "unable to run %s"
+msgstr "nie je možné spustiť %s"
+
+#: src/utmp.c:266
+msgid "unable to save stdin"
+msgstr "nie je možné uložiť štandardný vstup stdin"
+
+#: src/utmp.c:268
+msgid "unable to dup2 stdin"
+msgstr ""
+
+#: src/utmp.c:271
+msgid "unable to restore stdin"
+msgstr "nie je možné obnoviť štandardný vstup stdin"
diff --git a/po/sl.mo b/po/sl.mo
new file mode 100644
index 0000000..b0cc741
--- /dev/null
+++ b/po/sl.mo
Binary files differ
diff --git a/po/sl.po b/po/sl.po
new file mode 100644
index 0000000..ef8df67
--- /dev/null
+++ b/po/sl.po
@@ -0,0 +1,810 @@
+# Slovenian translation of sudo.
+# This file is put in the public domain.
+# This file is distributed under the same license as the sudo package.
+#
+# Damir Jerovšek <damir.jerovsek@gmail.com>, 2012.
+# Klemen Košir <klemen.kosir@gmx.com>, 2012 - 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.7b1\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2013-04-02 10:40-0400\n"
+"PO-Revision-Date: 2013-04-06 09:33+0100\n"
+"Last-Translator: Klemen Košir <klemen913@gmail.com>\n"
+"Language-Team: Slovenian <translation-team-sl@lists.sourceforge.net>\n"
+"Language: sl\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.5.5\n"
+
+#: common/aix.c:150
+#, c-format
+msgid "unable to open userdb"
+msgstr "ni mogoče odpreti userdb"
+
+#: common/aix.c:153
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "ni mogoče preklopiti na vpisnik \"%s\" za %s"
+
+#: common/aix.c:170
+#, c-format
+msgid "unable to restore registry"
+msgstr "ni mogoče obnoviti vpisnika"
+
+#: common/alloc.c:82
+msgid "internal error, tried to emalloc(0)"
+msgstr "notranja napaka, poskus uporabe emalloc(0)"
+
+#: common/alloc.c:99
+msgid "internal error, tried to emalloc2(0)"
+msgstr "notranja napaka, poskus uporabe emalloc2(0)"
+
+#: common/alloc.c:101 common/alloc.c:123 common/alloc.c:163 common/alloc.c:187
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "notranja napaka, prekoračitev funkcije %s"
+
+#: common/alloc.c:120
+msgid "internal error, tried to ecalloc(0)"
+msgstr "notranja napaka med izvajanjem funkcije ecalloc(0)"
+
+#: common/alloc.c:142
+msgid "internal error, tried to erealloc(0)"
+msgstr "notranja napaka, poskus uporabe erealloc(0)"
+
+#: common/alloc.c:161
+msgid "internal error, tried to erealloc3(0)"
+msgstr "notranja napaka, poskus uporabe erealloc3(0)"
+
+#: common/alloc.c:185
+msgid "internal error, tried to erecalloc(0)"
+msgstr "notranja napaka, poskus uporabe erealloc(0)"
+
+#: common/error.c:154
+#, c-format
+msgid "%s: %s: %s\n"
+msgstr "%s: %s: %s\n"
+
+#: common/error.c:157 common/error.c:161
+#, c-format
+msgid "%s: %s\n"
+msgstr "%s: %s\n"
+
+#: common/sudo_conf.c:172
+#, c-format
+msgid "unsupported group source `%s' in %s, line %d"
+msgstr "nepodprt vir skupine %s v datoteki %s v %d. vrstici"
+
+#: common/sudo_conf.c:186
+#, c-format
+msgid "invalid max groups `%s' in %s, line %d"
+msgstr "neveljavna največja skupina %s v datoteki %s v %d. vrstici"
+
+#: common/sudo_conf.c:382
+#, c-format
+msgid "unable to stat %s"
+msgstr "stanja datoteke %s ni mogoče izpisati"
+
+#: common/sudo_conf.c:385
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s ni običajna datoteka"
+
+#: common/sudo_conf.c:388
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s je v lasti uporabnika z ID-jem %u, moral bi biti %u"
+
+#: common/sudo_conf.c:392
+#, c-format
+msgid "%s is world writable"
+msgstr "v datoteko %s lahko zapisujejo vsi uporabniki"
+
+#: common/sudo_conf.c:395
+#, c-format
+msgid "%s is group writable"
+msgstr "%s"
+
+#: common/sudo_conf.c:405 src/selinux.c:196 src/selinux.c:209 src/sudo.c:328
+#, c-format
+msgid "unable to open %s"
+msgstr "ni mogoče odpreti %s"
+
+#: compat/strsignal.c:50
+msgid "Unknown signal"
+msgstr "Neznan signal"
+
+#: src/exec.c:127 src/exec_pty.c:685
+#, c-format
+msgid "policy plugin failed session initialization"
+msgstr "vstavek za pravilnik ni mogel zagnati seje"
+
+#: src/exec.c:132 src/exec_pty.c:701 src/exec_pty.c:1066 src/tgetpass.c:220
+#, c-format
+msgid "unable to fork"
+msgstr "ni mogoče razvejiti"
+
+#: src/exec.c:259
+#, c-format
+msgid "unable to create sockets"
+msgstr "ni mogoče ustvariti vtičev"
+
+#: src/exec.c:347 src/exec_pty.c:1130 src/exec_pty.c:1268
+#, c-format
+msgid "select failed"
+msgstr "izbira je spodletela"
+
+#: src/exec.c:449
+#, c-format
+msgid "unable to restore tty label"
+msgstr "ni mogoče obnoviti oznake tty"
+
+#: src/exec_common.c:70
+#, c-format
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "ni mogoče odstraniti PRIV_PROC_EXEC iz PRIV_LIMIT"
+
+#: src/exec_pty.c:183
+#, c-format
+msgid "unable to allocate pty"
+msgstr "ni mogoče dodeliti pty"
+
+#: src/exec_pty.c:623 src/exec_pty.c:632 src/exec_pty.c:640 src/exec_pty.c:986
+#: src/exec_pty.c:1063 src/signal.c:126 src/tgetpass.c:217
+#, c-format
+msgid "unable to create pipe"
+msgstr "ni mogoče ustvariti cevi"
+
+#: src/exec_pty.c:676
+#, c-format
+msgid "unable to set terminal to raw mode"
+msgstr "ni mogoče postaviti terminala v surov način"
+
+#: src/exec_pty.c:1042
+#, c-format
+msgid "unable to set controlling tty"
+msgstr "ni mogoče nastaviti nadzora tty"
+
+#: src/exec_pty.c:1139
+#, c-format
+msgid "error reading from signal pipe"
+msgstr "napaka med branjem iz cevi signala"
+
+#: src/exec_pty.c:1160
+#, c-format
+msgid "error reading from pipe"
+msgstr "napaka med branjem iz cevovoda"
+
+#: src/exec_pty.c:1176
+#, c-format
+msgid "error reading from socketpair"
+msgstr "napaka med branjem iz para vtičev"
+
+#: src/exec_pty.c:1180
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "nepričakovana vrsta odgovora na ozadnem kanalu: %d"
+
+#: src/load_plugins.c:70 src/load_plugins.c:79 src/load_plugins.c:132
+#: src/load_plugins.c:138 src/load_plugins.c:144 src/load_plugins.c:185
+#: src/load_plugins.c:192 src/load_plugins.c:199 src/load_plugins.c:205
+#, c-format
+msgid "error in %s, line %d while loading plugin `%s'"
+msgstr "v datoteki %s (vrstica %d) je prišlo do napake med nalaganjem vstavka %s"
+
+#: src/load_plugins.c:72
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: src/load_plugins.c:81
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:140
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s mora biti v lasti ID-ja uporabnika %d"
+
+#: src/load_plugins.c:146
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s mora biti zapisljiv samo za lastnika"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unable to dlopen %s: %s"
+msgstr "ni mogoče uporabiti dlopen %s: %s"
+
+#: src/load_plugins.c:194
+#, c-format
+msgid "unable to find symbol `%s' in %s"
+msgstr "ni mogoče najti simbola '%s' v %s"
+
+#: src/load_plugins.c:201
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "neznana vrsta pravilnika %d v %s"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "nezdružljiva različica vstavka %d (pričakovana %d) v %s"
+
+#: src/load_plugins.c:216
+#, c-format
+msgid "ignoring policy plugin `%s' in %s, line %d"
+msgstr "vstavek pravilnika %s v datoteki %s v %d. vrstici bo prezrt"
+
+#: src/load_plugins.c:218
+#, c-format
+msgid "only a single policy plugin may be specified"
+msgstr "naložen je lahko le en vstavek pravilnika"
+
+#: src/load_plugins.c:221
+#, c-format
+msgid "ignoring duplicate policy plugin `%s' in %s, line %d"
+msgstr "podvojeni vstavek pravilnika %s v datoteki %s v %d. vrstici bo prezrt"
+
+#: src/load_plugins.c:236
+#, c-format
+msgid "ignoring duplicate I/O plugin `%s' in %s, line %d"
+msgstr "podvojeni vstavek I/O %s v datoteki %s v %d. vrstici bo prezrt"
+
+#: src/load_plugins.c:313
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "vstavek pravilnika %s ne vključuje načina check_policy"
+
+#: src/net_ifs.c:156 src/net_ifs.c:165 src/net_ifs.c:177 src/net_ifs.c:186
+#: src/net_ifs.c:297 src/net_ifs.c:321
+#, c-format
+msgid "load_interfaces: overflow detected"
+msgstr "load_interfaces: zaznana je bila prekoračitev"
+
+#: src/net_ifs.c:226
+#, c-format
+msgid "unable to open socket"
+msgstr "ni mogoče odpreti vtiča"
+
+#: src/parse_args.c:197
+#, c-format
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "argument k -C mora biti številka, večja kot ali enaka 3"
+
+#: src/parse_args.c:286
+#, c-format
+msgid "unknown user: %s"
+msgstr "neznan uporabnik: %s"
+
+#: src/parse_args.c:345
+#, c-format
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "možnosti `-i' in `-s' ne smeta biti navedeni hkrati"
+
+#: src/parse_args.c:349
+#, c-format
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "možnosti `-i' in `-E' ne smeta biti navedeni hkrati"
+
+#: src/parse_args.c:359
+#, c-format
+msgid "the `-E' option is not valid in edit mode"
+msgstr "možnost `-E' ni veljavna v načinu urejanja"
+
+#: src/parse_args.c:361
+#, c-format
+msgid "you may not specify environment variables in edit mode"
+msgstr "v načinu urejanja se ne sme podati spremenljivk okolja"
+
+#: src/parse_args.c:369
+#, c-format
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "možnost `-U' se lahko uporabi samo z možnostjo `-l'"
+
+#: src/parse_args.c:373
+#, c-format
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "možnosti `-A' in `-S' se ne smeta uporabljati hkrati"
+
+#: src/parse_args.c:456
+#, c-format
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit ni podprt v tem okolju"
+
+#: src/parse_args.c:529
+#, c-format
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Od -e, -h, -i, -K, -l, -s, -v ali -V je lahko navedena samo ena možnost"
+
+#: src/parse_args.c:543
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - urejaj datoteke kot drug uporabnik\n"
+"\n"
+
+#: src/parse_args.c:545
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - izvedi ukaz kot drug uporabnik\n"
+"\n"
+
+#: src/parse_args.c:550
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Možnosti:\n"
+
+#: src/parse_args.c:552
+msgid "use helper program for password prompting\n"
+msgstr "uporabi program pomagalnik za pozive za vnos gesla\n"
+
+#: src/parse_args.c:555
+msgid "use specified BSD authentication type\n"
+msgstr "uporabi navedeno vrsto urejanja BSD\n"
+
+#: src/parse_args.c:558
+msgid "run command in the background\n"
+msgstr "zaženi ukaz v ozadju\n"
+
+#: src/parse_args.c:560
+msgid "close all file descriptors >= fd\n"
+msgstr "zapri vse opisnike datotek >= fd\n"
+
+#: src/parse_args.c:563
+msgid "run command with specified login class\n"
+msgstr "zaženi ukaz z navedenim prijavnim razredom\n"
+
+#: src/parse_args.c:566
+msgid "preserve user environment when executing command\n"
+msgstr "ohrani okolje uporabnika, kadar se izvajajo ukazi\n"
+
+#: src/parse_args.c:568
+msgid "edit files instead of running a command\n"
+msgstr "namesto izvedbe ukaza uredi datoteke\n"
+
+#: src/parse_args.c:570
+msgid "execute command as the specified group\n"
+msgstr "izvedi ukaz kot navedena skupina\n"
+
+#: src/parse_args.c:572
+msgid "set HOME variable to target user's home dir.\n"
+msgstr "nastavi spremenljivko HOME kot cilj v domači mapi uporabnika\n"
+
+#: src/parse_args.c:574
+msgid "display help message and exit\n"
+msgstr "prikaži sporočilo pomoči in končaj\n"
+
+#: src/parse_args.c:576
+msgid "run a login shell as target user\n"
+msgstr "zaženi lupino prijave kot ciljni uporabnik\n"
+
+#: src/parse_args.c:578
+msgid "remove timestamp file completely\n"
+msgstr "popolnoma odstrani datoteko s časovnimi žigi\n"
+
+#: src/parse_args.c:580
+msgid "invalidate timestamp file\n"
+msgstr "razveljavi veljavnost datoteke s časovnimi žigi\n"
+
+#: src/parse_args.c:582
+msgid "list user's available commands\n"
+msgstr "prikaži razpoložljive ukaze uporabnika\n"
+
+#: src/parse_args.c:584
+msgid "non-interactive mode, will not prompt user\n"
+msgstr "nevzajemni način, ne bo poziva uporabnika\n"
+
+#: src/parse_args.c:586
+msgid "preserve group vector instead of setting to target's\n"
+msgstr "ohrani vektor skupine namesto nastavitve tarči\n"
+
+#: src/parse_args.c:588
+msgid "use specified password prompt\n"
+msgstr "uporabi določen poziv za vnos gesla\n"
+
+#: src/parse_args.c:591 src/parse_args.c:599
+msgid "create SELinux security context with specified role\n"
+msgstr "ustvari varnostno vsebino SELinux z določeno vlogo\n"
+
+#: src/parse_args.c:594
+msgid "read password from standard input\n"
+msgstr "preberi geslo s standardnega vnosa\n"
+
+#: src/parse_args.c:596
+msgid "run a shell as target user\n"
+msgstr "zaženi lupino kot ciljni uporabnik\n"
+
+#: src/parse_args.c:602
+msgid "when listing, list specified user's privileges\n"
+msgstr "med naštevanjem prikaži določena dovoljenja uporabnika\n"
+
+#: src/parse_args.c:604
+msgid "run command (or edit file) as specified user\n"
+msgstr "zaženi ukaz (ali uredi datoteko) kot določen uporabnik\n"
+
+#: src/parse_args.c:606
+msgid "display version information and exit\n"
+msgstr "prikaži podrobnosti različice in končaj\n"
+
+#: src/parse_args.c:608
+msgid "update user's timestamp without running a command\n"
+msgstr "posodobi časovni žig uporabnika brez izvajanja ukaza\n"
+
+#: src/parse_args.c:610
+msgid "stop processing command line arguments\n"
+msgstr "zaustavi obdelovanje argumentov ukazne vrstice\n"
+
+#: src/selinux.c:77
+#, c-format
+msgid "unable to open audit system"
+msgstr "ni mogoče odpreti nadzornega sistema"
+
+#: src/selinux.c:85
+#, c-format
+msgid "unable to send audit message"
+msgstr "ni mogoče poslati nadzornega sporočila"
+
+#: src/selinux.c:113
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "ni mogoče uporabiti fgetfilecon %s"
+
+#: src/selinux.c:118
+#, c-format
+msgid "%s changed labels"
+msgstr "%s spremenjenih oznak"
+
+#: src/selinux.c:123
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "ni mogoče obnoviti vsebine za %s"
+
+#: src/selinux.c:163
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "ni mogoče odpreti %s, brez ponovnega označevanja tty"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "ni mogoče pridobiti trenutne vsebine tty, brez ponovnega označevanja tty"
+
+#: src/selinux.c:179
+#, c-format
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "ni mogoče pridobiti nove vsebine tty, brez ponovnega označevanja tty"
+
+#: src/selinux.c:186
+#, c-format
+msgid "unable to set new tty context"
+msgstr "ni mogoče nastaviti nove vsebine tty"
+
+#: src/selinux.c:252
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "podati morate vlogo za vrsto %s"
+
+#: src/selinux.c:258
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "ni mogoče pridobiti privzete vrste za vlogo %s"
+
+#: src/selinux.c:276
+#, c-format
+msgid "failed to set new role %s"
+msgstr "nastavitev nove vloge %s ni uspela"
+
+#: src/selinux.c:280
+#, c-format
+msgid "failed to set new type %s"
+msgstr "nastavitev nove vrste %s ni uspela"
+
+#: src/selinux.c:289
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s ni veljavna vsebina"
+
+#: src/selinux.c:324
+#, c-format
+msgid "failed to get old_context"
+msgstr "pridobitev stare_vsebine je spodletela"
+
+#: src/selinux.c:330
+#, c-format
+msgid "unable to determine enforcing mode."
+msgstr "ni mogoče določiti načina vsiljenja"
+
+#: src/selinux.c:342
+#, c-format
+msgid "unable to setup tty context for %s"
+msgstr "ni mogoče nastaviti vsebine tty za %s"
+
+#: src/selinux.c:381
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "ni mogoče nastavite izvedene vsebine k %s"
+
+#: src/selinux.c:388
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "ni mogoče nastaviti vsebine ustvarjenja ključa k %s"
+
+#: src/sesh.c:57
+#, c-format
+msgid "requires at least one argument"
+msgstr "zahteva vsaj en argument"
+
+#: src/sesh.c:78 src/sudo.c:1126
+#, c-format
+msgid "unable to execute %s"
+msgstr "ni mogoče izvršiti %s"
+
+#: src/solaris.c:88
+#, c-format
+msgid "resource control limit has been reached"
+msgstr "meja omejitve virov je bila dosežena"
+
+#: src/solaris.c:91
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "uporabnik \"%s\" ni član projekta \"%s\""
+
+#: src/solaris.c:95
+#, c-format
+msgid "the invoking task is final"
+msgstr "priklicana naloga je končna"
+
+#: src/solaris.c:98
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "ni mogoče pridružiti projekta \"%s\""
+
+#: src/solaris.c:103
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "nobene zaloge virov, ki sprejemajo privzete vezi, ne obstajajo za projekt \"% s\""
+
+#: src/solaris.c:107
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "določen vir zalog ne obstaja za projekt \"%s\""
+
+#: src/solaris.c:111
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "ni mogoče vezati na privzet vir zalog za projekt \"%s\""
+
+#: src/solaris.c:117
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "setproject je spodletel za projekt \"%s\""
+
+#: src/solaris.c:119
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "opozorilo, naloga nadzora virov je spodletela za projekt \"%s\""
+
+#: src/sudo.c:196
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo različica %s\n"
+
+#: src/sudo.c:198
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Nastavitev možnosti: %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "fatal error, unable to load plugins"
+msgstr "usodna napaka, ni mogoče naložiti vstavka"
+
+#: src/sudo.c:211
+#, c-format
+msgid "unable to initialize policy plugin"
+msgstr "ni mogoče začenjati vstavka pravilnika"
+
+#: src/sudo.c:268
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "napaka med začenjanjem I/O vstavka %s"
+
+#: src/sudo.c:293
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "nepričakovan način sudo 0x%x"
+
+#: src/sudo.c:413
+#, c-format
+msgid "unable to get group vector"
+msgstr "ni mogoče pridobiti vektorja skupine"
+
+#: src/sudo.c:465
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "neznan ID uporabnika %u: kdo ste?"
+
+#: src/sudo.c:802
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s si mora lastiti uporabnik z ID-jem %d and mora imeti nastavljen bit setuid"
+
+#: src/sudo.c:805
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "trenutni ID uporabnika ni %d. Ali je %s na datotečnem sistemu z nastavljeno možnostjo \"nosuid\" ali datotečnem sistemu NFS brez dovoljenj skrbnika?"
+
+#: src/sudo.c:811
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "trenutni uid ni %d. Ali je sudo pravilno nameščen?"
+
+#: src/sudo.c:915
+#, c-format
+msgid "unknown login class %s"
+msgstr "neznan razred prijave %s"
+
+#: src/sudo.c:929 src/sudo.c:932
+#, c-format
+msgid "unable to set user context"
+msgstr "ni mogoče nastaviti vsebine uporabnika"
+
+#: src/sudo.c:944
+#, c-format
+msgid "unable to set supplementary group IDs"
+msgstr "ni mogoče nastaviti dopolnilnih ID-jev skupin"
+
+#: src/sudo.c:951
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "ni mogoče nastaviti učinkovitega ID-ja skupine, da se zažene kot ID skupine %u"
+
+#: src/sudo.c:957
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "ni mogoče nastaviti ID-ja skupine, da se zažene kot ID skupine %u"
+
+#: src/sudo.c:964
+#, c-format
+msgid "unable to set process priority"
+msgstr "ni mogoče nastaviti prednosti opravil"
+
+#: src/sudo.c:972
+#, c-format
+msgid "unable to change root to %s"
+msgstr "ni mogoče spremeniti skrbnika v %s"
+
+#: src/sudo.c:979 src/sudo.c:985 src/sudo.c:991
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "ni mogoče spremeniti ID uporabnika zaženi kot (%u, %u)"
+
+#: src/sudo.c:1005
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "ni mogoče spremeniti mape v %s"
+
+#: src/sudo.c:1089
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "nepričakovan pogoj uničenja podrejenega opravila: %d"
+
+#: src/sudo.c:1146
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "vstavek pravilnika %s ne vključuje načina check_policy"
+
+#: src/sudo.c:1159
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "vstavek pravilnika %s ne podpira navajanja dovoljenj"
+
+#: src/sudo.c:1171
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "vstavek pravilnika %s ne podpira možnosti -v"
+
+#: src/sudo.c:1183
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "vstavek pravilnika %s ne podpira možnosti -k/-K"
+
+#: src/sudo_edit.c:110
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "ni mogoče spremeniti ID-ja uporabnika v skrbnika (%u)"
+
+#: src/sudo_edit.c:142
+#, c-format
+msgid "plugin error: missing file list for sudoedit"
+msgstr "napaka vstavka: manjka seznam datotek za sudoedit"
+
+#: src/sudo_edit.c:170 src/sudo_edit.c:270
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: ni običajna datoteka"
+
+#: src/sudo_edit.c:204 src/sudo_edit.c:306
+#, c-format
+msgid "%s: short write"
+msgstr "%s: kratko pisanje"
+
+#: src/sudo_edit.c:271
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s je ostalo nespremenjeno"
+
+#: src/sudo_edit.c:284
+#, c-format
+msgid "%s unchanged"
+msgstr "%s nespremenjeno"
+
+#: src/sudo_edit.c:296 src/sudo_edit.c:317
+#, c-format
+msgid "unable to write to %s"
+msgstr "ni mogoče pisati v %s"
+
+#: src/sudo_edit.c:297 src/sudo_edit.c:315 src/sudo_edit.c:318
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "vsebina seje urejanja je ostala v %s"
+
+#: src/sudo_edit.c:314
+#, c-format
+msgid "unable to read temporary file"
+msgstr "ni mogoče brati začasne datoteke"
+
+#: src/tgetpass.c:89
+#, c-format
+msgid "no tty present and no askpass program specified"
+msgstr "prisotnega ni nobenega tty in določen ni noben program askpass"
+
+#: src/tgetpass.c:98
+#, c-format
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "določenega ni nobenega programa askpass, poskusite nastaviti SUDO_ASKPASS"
+
+#: src/tgetpass.c:230
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "ni mogoče nastaviti ID skupine v %u"
+
+#: src/tgetpass.c:234
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "ni mogoče nastaviti ID uporabnika v %u"
+
+#: src/tgetpass.c:239
+#, c-format
+msgid "unable to run %s"
+msgstr "ni mogoče zagnati %s"
+
+#: src/utmp.c:278
+#, c-format
+msgid "unable to save stdin"
+msgstr "ni mogoče shraniti stdin"
+
+#: src/utmp.c:280
+#, c-format
+msgid "unable to dup2 stdin"
+msgstr "ni mogoče uporabiti dup2 za stdin"
+
+#: src/utmp.c:283
+#, c-format
+msgid "unable to restore stdin"
+msgstr "ni mogoče obnoviti stdin"
diff --git a/po/sr.mo b/po/sr.mo
new file mode 100644
index 0000000..c32de31
--- /dev/null
+++ b/po/sr.mo
Binary files differ
diff --git a/po/sr.po b/po/sr.po
new file mode 100644
index 0000000..222a9fd
--- /dev/null
+++ b/po/sr.po
@@ -0,0 +1,923 @@
+# Serbian translations for sudo package.
+# This file is put in the public domain.
+# Мирослав Николић <miroslavnikolic@rocketmail.com>, 2011—2017.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo-1.8.21b2\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2017-08-03 10:04-0600\n"
+"PO-Revision-Date: 2017-08-06 14:45+0200\n"
+"Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
+"Language-Team: Serbian <(nothing)>\n"
+"Language: sr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:172
+msgid "unable to open userdb"
+msgstr "не могу да отворим корисничку базу података"
+
+#: lib/util/aix.c:227
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "не могу да се пребацим на регистар „%s“ за %s"
+
+#: lib/util/aix.c:252
+msgid "unable to restore registry"
+msgstr "не могу да повратим регистар"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:186 lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349
+#: lib/util/sudo_conf.c:553 src/conversation.c:75 src/exec_common.c:107
+#: src/exec_common.c:123 src/exec_common.c:132 src/exec_monitor.c:167
+#: src/exec_nopty.c:462 src/exec_pty.c:667 src/exec_pty.c:676
+#: src/exec_pty.c:738 src/exec_pty.c:867 src/load_plugins.c:52
+#: src/load_plugins.c:65 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:198 src/parse_args.c:273 src/parse_args.c:540
+#: src/parse_args.c:562 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:115 src/sudo.c:389 src/sudo.c:416 src/sudo.c:481 src/sudo.c:603
+#: src/sudo.c:663 src/sudo.c:673 src/sudo.c:693 src/sudo.c:712 src/sudo.c:721
+#: src/sudo.c:730 src/sudo.c:747 src/sudo.c:788 src/sudo.c:798 src/sudo.c:818
+#: src/sudo.c:1058 src/sudo.c:1079 src/sudo.c:1253 src/sudo.c:1351
+#: src/sudo_edit.c:148 src/sudo_edit.c:771 src/sudo_edit.c:868
+#: src/sudo_edit.c:982 src/sudo_edit.c:1002
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/sudo_conf.c:187
+#: lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349 lib/util/sudo_conf.c:553
+#: src/conversation.c:76 src/exec_common.c:107 src/exec_common.c:124
+#: src/exec_common.c:133 src/exec_pty.c:667 src/exec_pty.c:676
+#: src/exec_pty.c:738 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:199 src/parse_args.c:273 src/parse_args.c:540
+#: src/parse_args.c:562 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:115 src/sudo.c:389 src/sudo.c:416 src/sudo.c:481 src/sudo.c:603
+#: src/sudo.c:818 src/sudo.c:1058 src/sudo.c:1079 src/sudo.c:1253
+#: src/sudo.c:1351 src/sudo_edit.c:148 src/sudo_edit.c:771 src/sudo_edit.c:868
+#: src/sudo_edit.c:982 src/sudo_edit.c:1002
+msgid "unable to allocate memory"
+msgstr "не могу да доделим меморију"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "Непознати сигнал"
+
+#: lib/util/strtoid.c:77 lib/util/strtoid.c:124 lib/util/strtoid.c:152
+#: lib/util/strtomode.c:49 lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "неисправна вредност"
+
+#: lib/util/strtoid.c:84 lib/util/strtoid.c:131 lib/util/strtoid.c:159
+#: lib/util/strtomode.c:55 lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "вредност је превелика"
+
+#: lib/util/strtoid.c:86 lib/util/strtoid.c:137 lib/util/strtomode.c:55
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "вредност је премала"
+
+#: lib/util/sudo_conf.c:205
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "неисправна вредност путање „%s“ у „%s“, %u. ред"
+
+#: lib/util/sudo_conf.c:371 lib/util/sudo_conf.c:424
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "неисправна вредност за %s „%s“ у „%s“, %u. ред"
+
+#: lib/util/sudo_conf.c:392
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "неподржани извор групе „%s“ у „%s“, %u. ред"
+
+#: lib/util/sudo_conf.c:408
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "неисправне највеће групе „%s“ у „%s“, %u. ред"
+
+#: lib/util/sudo_conf.c:569
+#, c-format
+msgid "unable to stat %s"
+msgstr "не могу да добијем податке о „%s“"
+
+#: lib/util/sudo_conf.c:572
+#, c-format
+msgid "%s is not a regular file"
+msgstr "„%s“ није обична датотека"
+
+#: lib/util/sudo_conf.c:575
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s је у власништву уиб-а %u, а треба бити %u"
+
+#: lib/util/sudo_conf.c:579
+#, c-format
+msgid "%s is world writable"
+msgstr "%s је светски уписив"
+
+#: lib/util/sudo_conf.c:582
+#, c-format
+msgid "%s is group writable"
+msgstr "%s је групно уписив"
+
+#: lib/util/sudo_conf.c:592 src/selinux.c:208 src/selinux.c:225 src/sudo.c:357
+#, c-format
+msgid "unable to open %s"
+msgstr "не могу да отворим %s"
+
+#: src/exec.c:160
+#, c-format
+msgid "unknown login class %s"
+msgstr "непозната класа пријаве %s"
+
+#: src/exec.c:173
+msgid "unable to set user context"
+msgstr "не могу да подесим кориснички контекст"
+
+#: src/exec.c:189
+msgid "unable to set process priority"
+msgstr "не могу да подесим приоритет процеса"
+
+#: src/exec.c:197
+#, c-format
+msgid "unable to change root to %s"
+msgstr "не могу да променим администратора на %s"
+
+#: src/exec.c:210 src/exec.c:216 src/exec.c:223
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "не могу да се пребацим у покрени_као уид (%u, %u)"
+
+#: src/exec.c:241
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "не могу да променим директоријум у %s"
+
+#: src/exec.c:337 src/exec_monitor.c:526 src/exec_monitor.c:528
+#: src/exec_nopty.c:520 src/exec_pty.c:472 src/exec_pty.c:1184
+#: src/exec_pty.c:1186 src/signal.c:139 src/signal.c:153
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "не могу да подесим руковаоца за сигнал „%d“"
+
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "не могу да уклоним PRIV_PROC_EXEC из PRIV_LIMIT"
+
+#: src/exec_monitor.c:326
+msgid "error reading from socketpair"
+msgstr "грешка у читању из пара прикључка"
+
+#: src/exec_monitor.c:338
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "неочекивана врста одговора на повратном каналу: %d"
+
+#: src/exec_monitor.c:423 src/exec_monitor.c:431 src/exec_monitor.c:439
+#: src/exec_monitor.c:446 src/exec_monitor.c:453 src/exec_monitor.c:460
+#: src/exec_monitor.c:467 src/exec_monitor.c:474 src/exec_monitor.c:481
+#: src/exec_monitor.c:488 src/exec_nopty.c:215 src/exec_nopty.c:224
+#: src/exec_nopty.c:231 src/exec_nopty.c:238 src/exec_nopty.c:245
+#: src/exec_nopty.c:252 src/exec_nopty.c:259 src/exec_nopty.c:266
+#: src/exec_nopty.c:273 src/exec_nopty.c:280 src/exec_nopty.c:287
+#: src/exec_nopty.c:294 src/exec_nopty.c:302 src/exec_pty.c:563
+#: src/exec_pty.c:568 src/exec_pty.c:635 src/exec_pty.c:642 src/exec_pty.c:743
+#: src/exec_pty.c:1029 src/exec_pty.c:1038 src/exec_pty.c:1045
+#: src/exec_pty.c:1052 src/exec_pty.c:1059 src/exec_pty.c:1066
+#: src/exec_pty.c:1073 src/exec_pty.c:1080 src/exec_pty.c:1087
+#: src/exec_pty.c:1094 src/exec_pty.c:1101 src/exec_pty.c:1446
+#: src/exec_pty.c:1456 src/exec_pty.c:1501 src/exec_pty.c:1508
+#: src/exec_pty.c:1533
+msgid "unable to add event to queue"
+msgstr "не могу да додам догађај у ред"
+
+#: src/exec_monitor.c:540
+msgid "unable to set controlling tty"
+msgstr "не могу да подесим контролисање tty"
+
+#: src/exec_monitor.c:548 src/exec_nopty.c:359 src/exec_pty.c:1261
+#: src/exec_pty.c:1280 src/exec_pty.c:1298 src/tgetpass.c:246
+msgid "unable to create pipe"
+msgstr "не могу да направим спојку"
+
+#: src/exec_monitor.c:553 src/exec_nopty.c:377 src/exec_pty.c:1335
+#: src/tgetpass.c:250
+msgid "unable to fork"
+msgstr "не могу да поделим"
+
+#: src/exec_monitor.c:639 src/exec_nopty.c:430
+msgid "unable to restore tty label"
+msgstr "не могу да повратим tty натпис"
+
+#: src/exec_nopty.c:353 src/exec_pty.c:1193
+msgid "policy plugin failed session initialization"
+msgstr "није успело покретање сесије прикључка политике"
+
+#: src/exec_nopty.c:419 src/exec_pty.c:1404
+msgid "error in event loop"
+msgstr "грешка у петљи догађаја"
+
+#: src/exec_nopty.c:528 src/exec_pty.c:504 src/signal.c:101
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "не могу да повратим руковаоца за сигнал „%d“"
+
+#: src/exec_pty.c:143
+msgid "unable to allocate pty"
+msgstr "не могу да доделим pty"
+
+#: src/exec_pty.c:1173
+msgid "unable to create sockets"
+msgstr "не могу да направим утичнице"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "грешка у „%s“, %d. ред приликом учитавања прикључка „%s“"
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s мора бити у власништву уида %d"
+
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s мора бити уписив само од стране власника"
+
+#: src/load_plugins.c:172
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "не могу да учитам %s: %s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "не могу да пронађем симбол „%s“ у %s"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "непозната врста сигурности %d је пронађена у %s"
+
+#: src/load_plugins.c:193
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "пронађено је несагласно главно издање прикључка %d (очекивано је %d) у „%s“"
+
+#: src/load_plugins.c:202
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "занемарујем прикључак сигурности „%s“ у %s, %d. ред"
+
+#: src/load_plugins.c:204
+msgid "only a single policy plugin may be specified"
+msgstr "може бити наведен само један прикључак сигурности"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "занемарујем удвостручен прикључак сигурности „%s“ у %s, %d. ред"
+
+#: src/load_plugins.c:228
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "занемарујем удвостручени У/И прикључак „%s“ у %s, %d. ред"
+
+#: src/load_plugins.c:331
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "прикључак сигурности %s не садржи метод провере_сигурности"
+
+#: src/net_ifs.c:173 src/net_ifs.c:190 src/net_ifs.c:335 src/sudo.c:476
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "унутрашња грешка, прекорачење функције „%s“"
+
+#: src/parse_args.c:219
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "неисправан назив променљиве окружења: %s"
+
+#: src/parse_args.c:313
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "аргумент уз -C мора бити број већи или једнак 3"
+
+#: src/parse_args.c:480
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "не можете да наведете обе опције „-i“ и „-s“"
+
+#: src/parse_args.c:484
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "не можете да наведете обе опције „-i“ и „-E“"
+
+#: src/parse_args.c:494
+msgid "the `-E' option is not valid in edit mode"
+msgstr "опција „-E“ није исправна у режиму уређивања"
+
+#: src/parse_args.c:496
+msgid "you may not specify environment variables in edit mode"
+msgstr "не можете да одредите променљиве окружења у режиму уређивања"
+
+#: src/parse_args.c:504
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "опција „-U“ може бити коришћена само са опцијом „-l“"
+
+#: src/parse_args.c:508
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "опције „-A“ и „-S“ не могу бити коришћене заједно"
+
+#: src/parse_args.c:584
+msgid "sudoedit is not supported on this platform"
+msgstr "„sudoedit“ није подржано на овој платформи"
+
+#: src/parse_args.c:657
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Само једна од опција -e, -h, -i, -K, -l, -s, -v или -V може бити наведена"
+
+#: src/parse_args.c:671
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s — уредите датотеке као други корисник\n"
+"\n"
+
+#: src/parse_args.c:673
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s — извршите наредбу као други корисник\n"
+"\n"
+
+#: src/parse_args.c:678
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Опције:\n"
+
+#: src/parse_args.c:680
+msgid "use a helper program for password prompting"
+msgstr "користи програм испомоћи за упит лозинке"
+
+#: src/parse_args.c:683
+msgid "use specified BSD authentication type"
+msgstr "користи наведену врсту БСД потврде идентитета"
+
+#: src/parse_args.c:686
+msgid "run command in the background"
+msgstr "покреће наредбу у позадини"
+
+#: src/parse_args.c:688
+msgid "close all file descriptors >= num"
+msgstr "затвара све описнике датотеке >= fd"
+
+#: src/parse_args.c:691
+msgid "run command with the specified BSD login class"
+msgstr "покреће наредбу са наведеним разредом БСД пријаве"
+
+#: src/parse_args.c:694
+msgid "preserve user environment when running command"
+msgstr "чува корисничко окружење приликом покретања наредбе"
+
+#: src/parse_args.c:696
+msgid "preserve specific environment variables"
+msgstr "чува нарочите променљиве окружења"
+
+#: src/parse_args.c:698
+msgid "edit files instead of running a command"
+msgstr "уређује датотеке уместо да изврши наредбу"
+
+#: src/parse_args.c:700
+msgid "run command as the specified group name or ID"
+msgstr "извршава наредбу као наведени назив групе или ИБ"
+
+#: src/parse_args.c:702
+msgid "set HOME variable to target user's home dir"
+msgstr "подешава променљиву ЛИЧНО у циљну корисничку личну фасциклу"
+
+#: src/parse_args.c:704
+msgid "display help message and exit"
+msgstr "приказује поруку помоћи и излази"
+
+#: src/parse_args.c:706
+msgid "run command on host (if supported by plugin)"
+msgstr "покреће наредбу на домаћину (ако је подржано прикључком)"
+
+#: src/parse_args.c:708
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "покреће љуску пријаве као крајњи корисник; наредба може такође бити наведена"
+
+#: src/parse_args.c:710
+msgid "remove timestamp file completely"
+msgstr "потпуно уклања датотеку записа датума и времена"
+
+#: src/parse_args.c:712
+msgid "invalidate timestamp file"
+msgstr "чини неисправном датотеку датума и времена"
+
+#: src/parse_args.c:714
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "исписује привилегије корисника или проверава посебну наредбу; користи се двапута за дуже записе"
+
+#: src/parse_args.c:716
+msgid "non-interactive mode, no prompts are used"
+msgstr "немеђудејствени режим, не користи упите"
+
+#: src/parse_args.c:718
+msgid "preserve group vector instead of setting to target's"
+msgstr "чува вектор групе уместо да подеси на циљеве"
+
+#: src/parse_args.c:720
+msgid "use the specified password prompt"
+msgstr "користи упит наведене лозинке"
+
+#: src/parse_args.c:723
+msgid "create SELinux security context with specified role"
+msgstr "ствара СЕЛинукс сигурносни контекст са наведеном улогом"
+
+#: src/parse_args.c:726
+msgid "read password from standard input"
+msgstr "чита лозинку са стандардног улаза"
+
+#: src/parse_args.c:728
+msgid "run shell as the target user; a command may also be specified"
+msgstr "покреће љуску као крајњи корисник; наредба такође може бити наведена"
+
+#: src/parse_args.c:731
+msgid "create SELinux security context with specified type"
+msgstr "ствара СЕЛинукс сигурносни контекст са наведеном улогом"
+
+#: src/parse_args.c:734
+msgid "terminate command after the specified time limit"
+msgstr "окончава наредбу након наведеног временског ограничења"
+
+#: src/parse_args.c:736
+msgid "in list mode, display privileges for user"
+msgstr "у режиму списка, приказује привилегије за корисника"
+
+#: src/parse_args.c:738
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "покреће наредбу (или уређује датотеку) као наведени корисник"
+
+#: src/parse_args.c:740
+msgid "display version information and exit"
+msgstr "приказује податке о издању и излази"
+
+#: src/parse_args.c:742
+msgid "update user's timestamp without running a command"
+msgstr "освежава кориснички запис датума и времена без покретања наредбе"
+
+#: src/parse_args.c:744
+msgid "stop processing command line arguments"
+msgstr "зауставља обрађивање аргумената линије наредби"
+
+#: src/selinux.c:78
+msgid "unable to open audit system"
+msgstr "не могу да отворим аудит систем"
+
+#: src/selinux.c:88
+msgid "unable to send audit message"
+msgstr "не могу да пошаљем аудит поруку"
+
+#: src/selinux.c:116
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "не могу да добавим контекст отворене датотеке %s"
+
+#: src/selinux.c:121
+#, c-format
+msgid "%s changed labels"
+msgstr "%s измењена натписа"
+
+#: src/selinux.c:126
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "не могу да повратим контекст за %s"
+
+#: src/selinux.c:167
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "не могу да отворим %s, није тту за поновно натписивање"
+
+#: src/selinux.c:171 src/selinux.c:212 src/selinux.c:229
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "„%s“ није знаковни уређај, није конзола за поновно натписивање"
+
+#: src/selinux.c:180
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "не могу да добавим текући тту контекст, није тту за поновно натписивање"
+
+#: src/selinux.c:187
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "непознат разред безбедности „chr_file“, није тту за поновно натписивање"
+
+#: src/selinux.c:192
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "не могу да добавим нови тту контекст, није тту за поновно натписивање"
+
+#: src/selinux.c:199
+msgid "unable to set new tty context"
+msgstr "не могу да подесим нови тту контекст"
+
+#: src/selinux.c:273
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "морате да наведете улогу за врсту %s"
+
+#: src/selinux.c:279
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "не могу да добавим основну врсту за улогу %s"
+
+#: src/selinux.c:297
+#, c-format
+msgid "failed to set new role %s"
+msgstr "нисам успео да подесим нову улогу %s"
+
+#: src/selinux.c:301
+#, c-format
+msgid "failed to set new type %s"
+msgstr "нисам успео да подесим нову врсту %s"
+
+#: src/selinux.c:313
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s није исправан контекст"
+
+#: src/selinux.c:348
+msgid "failed to get old_context"
+msgstr "нисам успео да добавим стари_контекст"
+
+#: src/selinux.c:354
+msgid "unable to determine enforcing mode."
+msgstr "не могу да одредим режим присиљавања."
+
+#: src/selinux.c:371
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "не могу да подесим тту контекст на %s"
+
+#: src/selinux.c:410
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "не могу да подесим извршни контекст за %s"
+
+#: src/selinux.c:417
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "не могу да подесим контекст стварања кључа за %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "захтева барем један аргумент"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "неисправан број описника датотеке: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "не могу да покренем „%s“ као шкољку пријављивања"
+
+#: src/sesh.c:125 src/sudo.c:1117
+#, c-format
+msgid "unable to execute %s"
+msgstr "не могу да извршим %s"
+
+#: src/signal.c:83
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "не могу да сачувам руковаоца за сигнал „%d“"
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "ограничење контроле ресурса је достигнуто"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "корисник „%s“ није члан пројекта „%s“"
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr "задатак призивања је завршни"
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "не могу да приступим пројекту „%s“"
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "не постоји депо извора који прихвата основне пречице за пројекат „%s“"
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "наведени депо извора не постоји за пројекат „%s“"
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "не могу да се повежем са основним депоом извора за пројекат „%s“"
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "подешавање пројекта није успело за пројекат „%s“"
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "упозорење, није успело додељивање контроле ресурса за пројекат „%s“"
+
+#: src/sudo.c:198
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Судо издање %s\n"
+
+#: src/sudo.c:200
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Опције подешавања: %s\n"
+
+#: src/sudo.c:208
+msgid "fatal error, unable to load plugins"
+msgstr "кобна грешка, не могу да учитам прикључке"
+
+#: src/sudo.c:216
+msgid "unable to initialize policy plugin"
+msgstr "не могу да започнем прикључак сигурности"
+
+#: src/sudo.c:260
+msgid "plugin did not return a command to execute"
+msgstr "прикључак није вратио наредбу за извршавање"
+
+#: src/sudo.c:276
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "грешка приликом покретања У/И прикључка %s"
+
+#: src/sudo.c:299
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "неочекивани судо режим 0x%x"
+
+#: src/sudo.c:461
+msgid "unable to get group vector"
+msgstr "не могу да добавим вектор групе"
+
+#: src/sudo.c:523
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "непознати уид %u: ко сте ви?"
+
+#: src/sudo.c:579
+msgid "unable to determine tty"
+msgstr "не могу да одредим конзолу"
+
+#: src/sudo.c:867
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s мора бити власништвo уида %d и треба да има подешен бит „setuid“"
+
+#: src/sudo.c:870
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "стварни уид није %d, већ %s на систему датотека са подешеном опцијом „nosuid“ или је НФС систем датотека без администраторских привилегија?"
+
+#: src/sudo.c:876
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "стварни уид није %d, већ сетуид администратор инсталиран судоом?"
+
+#: src/sudo.c:929
+msgid "unable to set supplementary group IDs"
+msgstr "не могу да подесим додатне ИБ-ове групе"
+
+#: src/sudo.c:936
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "не могу да подесим ефективан гид да се покрене_као гид %u"
+
+#: src/sudo.c:942
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "не могу да подесим гид да се покрене као гид %u"
+
+#: src/sudo.c:999
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "неочекивани услов завршетка потпроцеса: %d"
+
+#: src/sudo.c:1145
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "прикључак сигурности %s не садржи метод „check_policy“"
+
+#: src/sudo.c:1163
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "прикључак сигурности %s не подржава привилегије исписивања"
+
+#: src/sudo.c:1180
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "прикључак сигурности %s не подржава опцију -v"
+
+#: src/sudo.c:1195
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "прикључак сигурности %s не подржава опције -k/-K"
+
+#: src/sudo_edit.c:178 src/sudo_edit.c:267
+msgid "unable to restore current working directory"
+msgstr "не могу да повратим текући радни директоријум"
+
+#: src/sudo_edit.c:574 src/sudo_edit.c:686
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: није обична датотека"
+
+#: src/sudo_edit.c:581
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: уређивање симболичких веза није допуштено"
+
+#: src/sudo_edit.c:584
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: уређивање датотека у уписивом директоријуму није допуштено"
+
+#: src/sudo_edit.c:617 src/sudo_edit.c:724
+#, c-format
+msgid "%s: short write"
+msgstr "%s: кратак упис"
+
+#: src/sudo_edit.c:687
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s је остао неизмењен"
+
+#: src/sudo_edit.c:700 src/sudo_edit.c:885
+#, c-format
+msgid "%s unchanged"
+msgstr "%s је непромењен"
+
+#: src/sudo_edit.c:713 src/sudo_edit.c:735
+#, c-format
+msgid "unable to write to %s"
+msgstr "не могу да упишем у %s"
+
+#: src/sudo_edit.c:714 src/sudo_edit.c:733 src/sudo_edit.c:736
+#: src/sudo_edit.c:910 src/sudo_edit.c:914
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "садржај сесије уређивања је остао у %s"
+
+#: src/sudo_edit.c:732
+msgid "unable to read temporary file"
+msgstr "не могу да прочитам привремену датотеку"
+
+#: src/sudo_edit.c:815
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: унутрашња грешка: непарн број путања"
+
+#: src/sudo_edit.c:817
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: не могу да направим привремене датотеке"
+
+#: src/sudo_edit.c:819 src/sudo_edit.c:917
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: непозната грешка „%d“"
+
+#: src/sudo_edit.c:909
+msgid "unable to copy temporary files back to their original location"
+msgstr "не могу да умножим привремене датотеке назад на њихова првобитна места"
+
+#: src/sudo_edit.c:913
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "не могу да умножим неке од привремених датотека назад на њихова првобитна места"
+
+#: src/sudo_edit.c:958
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "не могу да променим уид у администратора (%u)"
+
+#: src/sudo_edit.c:975
+msgid "plugin error: missing file list for sudoedit"
+msgstr "грешка прикључка: недостаје датотеа списка за уређивање судоа"
+
+#: src/sudo_edit.c:1016 src/sudo_edit.c:1029
+msgid "unable to read the clock"
+msgstr "не могу да прочитам сат"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr "тту не постоји и није наведен програм за пропуштање"
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "није наведен програм за пропуштање, покушајте да подесите SUDO_ASKPASS"
+
+#: src/tgetpass.c:261
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "не могу да подесим гид у %u"
+
+#: src/tgetpass.c:265
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "не могу да подесим уид у %u"
+
+#: src/tgetpass.c:270
+#, c-format
+msgid "unable to run %s"
+msgstr "не могу да покренем %s"
+
+#: src/utmp.c:268
+msgid "unable to save stdin"
+msgstr "не могу да сачувам стандардни улаз"
+
+#: src/utmp.c:270
+msgid "unable to dup2 stdin"
+msgstr "не могу да дуп2 стандардни улаз"
+
+#: src/utmp.c:273
+msgid "unable to restore stdin"
+msgstr "не могу да повратим стандардни улаз"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "грешка у читању из спојке сигнала"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "грешка у читању из спојке"
+
+#~ msgid "internal error, tried allocate zero bytes"
+#~ msgstr "унутрашња грешка, покушах да доделим нула бајта"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "не могу да подесим терминал у сирови режим"
+
+#~ msgid "unable to open socket"
+#~ msgstr "не могу да отворим утичницу"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "унутрашња грешка, покушах да обавим „emalloc2(0)“"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "унутрашња грешка, покушах „ecalloc(0)“"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "унутрашња грешка, покушах да обавим „erealloc(0)“"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "унутрашња грешка, покушах да обавим „erealloc3(0)“"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "унутрашња грешка, покушах да обавим „erecalloc(0)“"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "учитај_сучеља: откривено је прекорачење"
+
+#~ msgid "value out of range"
+#~ msgstr "вредност је изван опсега"
+
+#~ msgid "select failed"
+#~ msgstr "избор није успео"
diff --git a/po/sudo.pot b/po/sudo.pot
new file mode 100644
index 0000000..70b153b
--- /dev/null
+++ b/po/sudo.pot
@@ -0,0 +1,924 @@
+# Portable object template file for sudo
+# This file is put in the public domain.
+# Todd C. Miller <Todd.Miller@sudo.ws>, 2011-2018
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.26\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr ""
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr ""
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr ""
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:57 src/load_plugins.c:70
+#: src/load_plugins.c:219 src/load_plugins.c:240 src/load_plugins.c:309
+#: src/load_plugins.c:315 src/load_plugins.c:329 src/load_plugins.c:335
+#: src/parse_args.c:182 src/parse_args.c:203 src/parse_args.c:278
+#: src/parse_args.c:565 src/parse_args.c:587 src/preserve_fds.c:52
+#: src/preserve_fds.c:137 src/selinux.c:89 src/selinux.c:314 src/selinux.c:437
+#: src/selinux.c:446 src/sesh.c:115 src/sudo.c:616 src/sudo.c:676
+#: src/sudo.c:686 src/sudo.c:706 src/sudo.c:725 src/sudo.c:734 src/sudo.c:743
+#: src/sudo.c:760 src/sudo.c:801 src/sudo.c:811 src/sudo.c:834 src/sudo.c:1071
+#: src/sudo.c:1092 src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256
+#: src/sudo_edit.c:789 src/sudo_edit.c:886 src/sudo_edit.c:1000
+#: src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr ""
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr ""
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr ""
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr ""
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr ""
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr ""
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr ""
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr ""
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr ""
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr ""
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr ""
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr ""
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr ""
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr ""
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr ""
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr ""
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr ""
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr ""
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr ""
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr ""
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr ""
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr ""
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr ""
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr ""
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr ""
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr ""
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr ""
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr ""
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr ""
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr ""
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr ""
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr ""
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr ""
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr ""
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr ""
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr ""
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr ""
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr ""
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr ""
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr ""
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr ""
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr ""
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr ""
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr ""
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr ""
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr ""
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr ""
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr ""
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr ""
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr ""
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr ""
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr ""
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr ""
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr ""
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr ""
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr ""
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr ""
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr ""
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr ""
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr ""
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr ""
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr ""
+
+#: src/parse_args.c:682
+msgid ""
+"Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr ""
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr ""
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr ""
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr ""
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr ""
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr ""
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr ""
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr ""
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr ""
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr ""
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr ""
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr ""
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr ""
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr ""
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr ""
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr ""
+
+#: src/parse_args.c:739
+msgid ""
+"list user's privileges or check a specific command; use twice for longer "
+"format"
+msgstr ""
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr ""
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr ""
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr ""
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr ""
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr ""
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr ""
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr ""
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr ""
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr ""
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr ""
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr ""
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr ""
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr ""
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr ""
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr ""
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr ""
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr ""
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr ""
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr ""
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr ""
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr ""
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr ""
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr ""
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr ""
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr ""
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr ""
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr ""
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr ""
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr ""
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr ""
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr ""
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr ""
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr ""
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr ""
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr ""
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr ""
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr ""
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr ""
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr ""
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr ""
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr ""
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr ""
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr ""
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr ""
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr ""
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr ""
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr ""
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr ""
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr ""
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr ""
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr ""
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr ""
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr ""
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr ""
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr ""
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr ""
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr ""
+
+#: src/sudo.c:883
+#, c-format
+msgid ""
+"effective uid is not %d, is %s on a file system with the 'nosuid' option set "
+"or an NFS file system without root privileges?"
+msgstr ""
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr ""
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr ""
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr ""
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr ""
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr ""
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr ""
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr ""
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr ""
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr ""
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr ""
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr ""
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr ""
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr ""
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr ""
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr ""
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr ""
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr ""
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr ""
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr ""
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr ""
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr ""
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr ""
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr ""
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr ""
+
+#: src/sudo_edit.c:931
+msgid ""
+"unable to copy some of the temporary files back to their original location"
+msgstr ""
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr ""
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr ""
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr ""
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr ""
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr ""
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr ""
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr ""
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr ""
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr ""
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr ""
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr ""
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr ""
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr ""
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr ""
diff --git a/po/sv.mo b/po/sv.mo
new file mode 100644
index 0000000..2b0088f
--- /dev/null
+++ b/po/sv.mo
Binary files differ
diff --git a/po/sv.po b/po/sv.po
new file mode 100644
index 0000000..129b687
--- /dev/null
+++ b/po/sv.po
@@ -0,0 +1,974 @@
+# Swedish translation for sudo.
+# Copyright © 2012, 2016, 2017, 2018 Free Software Foundation, Inc.
+# This file is put in the public domain.
+# Daniel Nylander <po@danielnylander.se>, 2012.
+# Sebastian Rasmussen <sebras@gmail.com>, 2016, 2017, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-30 02:17+0100\n"
+"Last-Translator: Sebastian Rasmussen <sebras@gmail.com>\n"
+"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
+"Language: sv\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 2.2\n"
+"X-Poedit-Bookmarks: -1,0,-1,-1,-1,-1,-1,-1,-1,-1\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "kunde inte öppna användardatabasen"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "kunde inte växla till registret ”%s” för %s"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "kunde inte återställa registret"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "kunde inte allokera minne"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "Okänd signal"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "ogiltigt värde"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "värde för stort"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "värde för litet"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "ogiltigt Path-värde ”%s” i %s, rad %u"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "ogiltigt värde för %s ”%s” i %s, rad %u"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "gruppkälla ”%s” stöds ej i %s, rad %u"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "ogiltigt största antal grupper ”%s” i %s, rad %u"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "kunde inte ta status på %s"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s är inte en vanlig fil"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s ägs av uid %u, ska vara %u"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "%s är skrivbar för alla"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "%s är skrivbar för gruppen"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "kunde inte öppna %s"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "okänd inloggningsklass %s"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "kunde inte ställa in användarens kontext"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "kunde inte ställa in processprioritet"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "kunde inte ändra rot till %s"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "kunde inte ändra till runas uid (%u, %u)"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "kunde inte ändra katalog till %s"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "kunde inte ställa in hanterare för signal %d"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "kan inte ta bort PRIV_PROC_EXEC från PRIV_LIMIT"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "fel vid läsning från uttagspar"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "oväntad svarstyp i bakkanal: %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "kunde inte lägga till händelse till kö"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "kan inte ställa in kontrollerande tty"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "kunde inte skapa rör"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "kan inte ta emot meddelande från förälder"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "kunde inte grena process"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "kunde inte köra %s"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "kan inte återställa tty-etikett"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "policyinsticksmodul misslyckades att initiera session"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "fel i händelseslinga"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "kunde inte återställa hanterare för signal %d"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "kunde inte allokera pty"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "kunde inte skapa uttag"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "kan inte skicka meddelande till övervakningsprocess"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "fel i %s, rad %d under inläsning av insticksmodul ”%s”"
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s måste ägas av uid %d"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s får endast vara skrivbar av ägaren"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "kunde inte läsa in %s: %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "kunde inte hitta symbol ”%s” i %s"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "okänd policytyp %d hittad i %s"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "inkompatibel huvudversion %d för insticksmodul (%d förväntades) hittad i %s"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "ignorerar policyinsticksmodul ”%s” i %s, rad %d"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "bara en policyinsticksmodul kan anges"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "ignorerar dubblerad policyinsticksmodul ”%s” i %s, rad %d"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "ignorerar dubblerad I/O-insticksmodul ”%s” i %s, rad %d"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "policyinsticksmodul %s inkluderar inte en check_policy-metod"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "internt fel, %s spill"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "ogiltigt namn på miljövariabel: %s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "argumentet till -C måste vara ett tal större än eller lika med 3"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "du får inte ange flaggorna ”-i” och ”-s” samtidigt"
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "du får inte ange flaggorna ”-i” och ”-E” samtidigt"
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "flaggan ”-E” är inte giltig i redigeringsläget"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "du får inte ange miljövariabler i redigeringsläget"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "flaggan ”-U” får bara användas med flaggan ”-l”"
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "flaggorna ”-A” och ”-S” får inte användas tillsammans"
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit stöds inte på denna plattform"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Endast en av flaggorna -e, -h, -i, -K, -l, -s, -v eller -V får anges"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - redigera filer som en annan användare\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - kör ett kommando som en annan användare\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Flaggor:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "använd hjälpprogram för att fråga efter lösenord"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "använd angiven BSD-autentiseringstyp"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "kör kommando i bakgrunden"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "stäng alla fildeskriptorer >= num"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "kör kommando med den angivna BSD-inloggningsklassen"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "bevara användarens miljö när kommandot körs"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "bevara specifika miljövariabler"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "redigera filer istället för att köra ett kommando"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "kör kommando som angivet gruppnamn eller ID"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "ställ in HOME-variabeln till målanvändarens hemkatalog"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "visa hjälpmeddelande och avsluta"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "kör kommando på värd (om det stöds av instick)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "kör ett inloggningsskal som målanvändaren; ett kommando kan också anges"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "ta bort tidsstämpelfil helt"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "ogiltigförklara tidsstämpelfil"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "lista användarens rättigheter eller kontrollera ett specifikt kommando; använd två gånger för längre format"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "icke-interaktivt läge, inga frågor ställs"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "behåll gruppvektor istället för att ställa in den till målets"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "använd angiven lösenordsprompt"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "skapa SELinux-säkerhetskontext med angiven roll"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "läs lösenord från standard in"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "kör skal som målanvändaren; ett kommando kan också anges"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "skapa SELinux-säkerhetskontext med angiven typ"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "avsluta kommando efter den angivna tidsgränsen"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "i listläge, visa rättigheter för användaren"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "kör kommando (eller redigera fil) som angivet användarnamn eller ID"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "visa versionsinformation och avsluta"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "uppdatera användarens tidsstämpel utan att köra ett kommando"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "sluta behandla kommandoradsargument"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "kan inte öppna granskningssystem"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "kan inte skicka granskningsmeddelande"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "kan inte köra fgetfilecon på %s"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s ändrade etiketter"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "kan inte återställa kontext för %s"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "kan inte öppna %s, ometiketterar inte tty"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s är inte en teckenenhet, ometiketterar inte tty"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "kan inte hämta aktuell tty-kontext, ometiketterar inte tty"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "okänd säkerhetsklass ”chr_file”, ometiketterar inte tty"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "kan inte hämta ny tty-kontext, ometiketterar inte tty"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "kan inte ställa in ny tty-kontext"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "du måste ange en roll för typen %s"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "kunde inte få tag på standardtyp för rollen %s"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "misslyckades med att ställa in nya rollen %s"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "misslyckades med att ställa in nya typen %s"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s är inte en giltig kontext"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "misslyckades med att få tag på old_context"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "kan inte fastställa påtvingande läge."
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "kunde inte ställa in tty-kontext till %s"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "kunde inte ställa in körkontext till %s"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "kan inte ställa in kontext för nyckelskapande till %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "kräver minst ett argument"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "ogiltigt fildeskriptornummer: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "kunde inte köra %s som ett inloggningsskal"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "kunde inte spara hanterare för signal %d"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "begränsning för resurskontroll uppnådd"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "användaren ”%s” är inte medlem av projekt ”%s”"
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "den startande uppgiften är den sista"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "kunde inte gå med i projekt ”%s”"
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "ingen resurspool som accepterar standardbindningar existerar för projekt ”%s”"
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "angiven resurspool finns inte för projekt ”%s”"
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "kunde inte binda till standardresurspool för projekt ”%s”"
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "setproject misslyckades för projekt ”%s”"
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "varning, tilldelning av resurskontroll misslyckades för projekt ”%s”"
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo version %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Konfigurationsflaggor: %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "ödesdigert fel, kunde inte läsa in insticksmoduler"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "kan inte initiera policy-instick"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "insticksmodul returnerade ett kommando att exekvera"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "fel vid initiering av I/O-insticksmodul %s"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "oväntat sudo-läge 0x%x"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "du existerar inte i %s-databasen"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "kan inte detektera tty"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s måste ägas av uid %d och ha setuid-biten inställd"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "effektivt uid är inte %d, är %s på ett filsystem med flaggan ”nosuid” inställd eller ett NFS-filsystem utan root-rättigheter?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "effektivt uid är inte %d, har sudo installerats som setuid root?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "kan inte ställa in kompletterande grupp-ID:n"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "kunde inte ställa in effektiv gid till runas gid %u"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "kunde inte ställa in gid för runas gid %u"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "oväntat barnavslutsvillkor: %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "policyinsticksmodul %s saknar metoden ”check_policy”"
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "policyinsticksmodul %s har inte stöd för att lista rättigheter"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "policyinsticksmodul %s har inte stöd för flaggan -v"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "policyinsticksmodul %s har inte stöd för flaggorna -k/-K"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "ingen skrivbar temporärkatalog hittad"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "kunde inte återställa aktuell arbetskatalog"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: inte en vanlig fil"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: att redigera symboliska länkar är inte tillåtet"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: att redigera filer i en skrivbar katalog är inte tillåtet"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s: kort skrivning"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s lämnad oförändrad"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "%s oförändrad"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "kunde inte skriva till %s"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "innehåll av redigeringssession finns kvar i %s"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "kunde inte läsa temporärfil"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: internt fel: udda antal sökvägar"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: kunde inte skapa temporärfiler"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: okänt fel %d"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "kan inte kopiera temporära filer tillbaka till deras originalplats"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "kan inte kopiera vissa av de temporära filerna tillbaka till deras originalplats"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "kunde inte ändra uid till root (%u)"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "insticksfel: fillista för sudoedit saknas"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "kunde inte läsa klockan"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "tidsgräns löpte ut vid lösenordsinläsning"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "ingen lösenord angavs"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "kan inte läsa lösenord"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "ingen tty finns tillgänglig och inget askpass-program angivet"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "inget askpass-program angivet, prova att ställ in SUDO_ASKPASS"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "kunde inte ställa in gid till %u"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "kunde inte ställa in uid till %u"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "kunde inte köra %s"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "kunde inte spara standard in"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "kan inte köra dup2 på standard in"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "kan inte återställa standard in"
+
+#~ msgid "unable to get group vector"
+#~ msgstr "kan inte hämta gruppvektor"
+
+#~ msgid "unknown uid %u: who are you?"
+#~ msgstr "okänt uid %u: vem är du?"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "fel vid läsning från signalrör"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "fel vid läsning från rör"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: stackspill upptäcktes"
+
+#~ msgid "unable to open socket"
+#~ msgstr "kunde inte öppna uttag"
+
+#~ msgid "list user's available commands\n"
+#~ msgstr "lista användarens tillgängliga kommandon\n"
+
+#~ msgid "run a shell as target user\n"
+#~ msgstr "kör ett skal som målanvändaren\n"
+
+#~ msgid "must be setuid root"
+#~ msgstr "måste vara setuid root"
+
+#~ msgid "internal error, tried to emalloc(0)"
+#~ msgstr "internt fel, försökte med emalloc(0)"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "internt fel, försökte med emalloc2(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "internt fel, försökte med erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "internt fel, försökte med erealloc3(0)"
+
+#~ msgid "internal error, erealloc3() overflow"
+#~ msgstr "internt fel, stackspill i erealloc3()"
diff --git a/po/tr.mo b/po/tr.mo
new file mode 100644
index 0000000..e5e7af7
--- /dev/null
+++ b/po/tr.mo
Binary files differ
diff --git a/po/tr.po b/po/tr.po
new file mode 100644
index 0000000..61f6cbe
--- /dev/null
+++ b/po/tr.po
@@ -0,0 +1,988 @@
+# This file is put in the public domain.
+# This file is distributed under the same license as the sudo package.
+# Volkan Gezer <vlkngzr@gmail.com>, 2013, 2015.
+# Mehmet Kececi <mkececi@mehmetkececi.com>, 2016, 2017, 2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-11-04 15:25+0300\n"
+"Last-Translator: Mehmet Kececi <mkececi@mehmetkececi.com>\n"
+"Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"
+"Language: tr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Virtaal 0.7.1\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "userdb açılamıyor"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "\"%s\" kaydına %s için geçiş yapılamıyor"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "kayıt geri yüklenemiyor"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "bellek ayırma başarısız"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "Bilinmeyen sinyal"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "geçersiz değer"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "değer çok büyük"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "değer çok küçük"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "\"%s\" geçersiz yol değeri, %s içinde, satır %u"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "%s \"%s\" için geçersiz değer, %s içinde, satır %u"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "\"%s\" desteklenmeyen grup kaynağı, %s içinde, satır %u"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "`\"%s\" geçersiz azami grubu, %s içinde, satır %u"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "%s durumlanamıyor"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s düzenli bir dosya değil"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s, %u kullanıcı kimliği tarafından sahiplenmiş, %u olmalı"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "%s genel yazılabilir"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "%s grup yazılabilir"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "%s açılamıyor"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "bilinmeyen %s oturum sınıfı"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "kullanıcı bağlamı ayarlama başarısız"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "süreç önceliği ayarlanamıyor"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "kök %s olarak değiştirilemiyor"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "runas uid (%u, %u) olarak değiştirilemiyor"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "%s dizinine değiştirilemiyor"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "sinyal %d için işleyici ayarlanamıyor"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "PRIV_LIMIT'ten PRIV_PROC_EXEC kaldırılamıyor"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "sockerpair'den okuma hatası"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "backchannel'da beklenmeyen yanıt türü: %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "olay kuyruğa eklenemedi"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "tty denetleme ayarlaması başarısız"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "iletişim tüneli oluşturulamıyor"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "ebeveynden mesaj alamıyor"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "çatallanamıyor"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "%s çalıştırılamıyor"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "tty etiketi geri yüklenemiyor"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "oturum başlatma için ilke eklentisi başarısız"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "olay döngüsünde hata"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "sinyal %d için işleyici geri yüklenemiyor"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "pty ayırma başarısız"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "soket oluşturulamıyor"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "süreci izlemek için mesaj gönderilemiyor"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "\"%s\" eklentisi yüklenirken satır %d, %s içerisinde hata"
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s, %d kullanıcı kimliği tarafından sahiplenmeli"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s sadece sahibi tarafından yazılabilir olmalı"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "%s yüklenemedi: %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "%s içerisinde \"%s\" sembolü bulunamıyor"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "bilinmeyen ilke türü %d bulundu: %s içerisinde"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "uyumsuz temel ilke sürümü %d bulundu (beklenen %d) %s içerisinde"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "\"%s\" ilke eklentisi ihmal ediliyor, %s içinde, satır %d"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "sadece tek ilke eklentisi belirtilebilir"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "yinelenmiş \"%s\" ilke eklentisi ihmal ediliyor, %s içinde, satır %d"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "kopyalanmış \"%s\" G/Ç eklentisi ihmal ediliyor, %s içinde, satır %d"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "%s ilke eklentisi, bir check_policy yöntemi içermiyor"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "dahili hata, %s taşması"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "geçersiz çevre değişken adı: %s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "-C argümanı 3 veya daha büyük bir sayı olmalıdır"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "`-i' ve `-s' seçeneklerini aynı anda belirtemezsiniz"
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "`-i' ve `-E' seçeneklerini aynı anda belirtemezsiniz"
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "düzenleme kipinde `-E' seçeneği geçerli değil"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "düzenleme kipinde ortam değişkenlerini belirtemezsiniz"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "`-U' seçeneği sadece `-l' seçeneği ile kullanılabilir"
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "`-A' ve `-S' seçenekleri birlikte kullanılamaz"
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit bu platformda desteklenmiyor"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "-e, -h, -i, -K, -l, -s, -v veya -V seçeneklerinden sadece biri belirtilebilir"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - dosyaları farklı kullanıcı olarak düzenle\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - bir komutu farklı kullanıcı olarak çalıştır\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Seçenekler:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "parola sorgulaması için bir yardımcı program kullan"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "belirtilen BSD kimlik doğrulama türünü kullan"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "arkaalanda komutu çalıştır"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr ">= sayı olan tüm dosya tanımlayıcılarını kapat"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "komutu belirtilen BSD oturum sınıfı ile çalıştır"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "komut çalıştırılırken kullanıcı ortamını koru"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "özel çevre değişkenlerini koru"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "komut çalıştırmak yerine dosyaları düzenleyiniz"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "grup adı veya ID olarak tanımlanan komutu çalıştır"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "HOME değişkenini kullanıcının ev dizinine hedefle"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "yardım mesajını görüntüle ve çık"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "komutunuzu hostta çalıştırın (eğer plugin tarafından destekleniyorsa)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "oturum kabuğunu hedef kullanıcı olarak çalıştır; bir komut da belirtilebilir"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "zaman damgası dosyasını kalıcı olarak kaldır"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "zaman damgası dosyasının geçerliliğini kaldır"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "kullanıcı yetkilerini listele veya özel bir komut denetle; daha uzun biçim için iki kez kullanın"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "etkileşimsiz kip, sorgu yapılmaz"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "hedefe atamak yerine grup vektörünü koru"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "belirtilen parola sorgusunu kullan"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "SELinux güvenlik bağlamını belirtilen rol ile oluştur"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "standart girdiden şifreyi okuyun"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "kabuğu hedef kullanıcı olarak çalıştır; bir komut da belirtilebilir"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "SELinux güvenlik bağlamını belirtilen tür ile oluştur"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "belirtilen süre sonunda komutu sonlandır"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "liste modunda, kullanıcıların ayrıcalıklarını görüntüle"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "belirtilen kullanıcı adı veya ID ile komutu çalıştırın (veya dosyayı düzenleyin)"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "sürüm bilgisini göster ve çık"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "kullanıcı zaman damgasını bir komut çalıştırmadan güncelle"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "komut satırı argümanlarını işlemeyi durdur"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "denetim sistemi açılamıyor"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "denetim iletisi gönderilemiyor"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "fgetfilecon %s yapılamıyor"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s değişmiş etiket"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "%s için bağlam geri yüklenemiyor"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "%s açılamadı, tty yeniden etiketlenemiyor"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s bir karakter aygıtı değildir, tty yeniden etiketlenemiyor"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "geçerli tty bağlamı alınamadı, tty yeniden etiketlenemiyor"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "bilinmeyen güvenlik sınıfı \"chr_file\", tty yeniden etiketlenemiyor"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "yeni tty bağlamı alınamadı, tty yeniden etiketlenemiyor"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "yeni tty bağlamı alınamıyor"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "%s türü için bir görev belirtmelisiniz"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "%s görevi için öntanımlı tür alınamıyor"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "%s yeni görevi atanamadı"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "yeni tür %s atanamadı"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s geçerli bir bağlam değil"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "old_context alınamadı"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "zorlama kipini belirleme başarısız."
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "tty bağlamı %s olarak ayarlanamadı"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "%s için exec bağlamı ayarlanamıyor"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "%s için anahtar oluşturma bağlamı ayarlanamıyor"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "en az bir argüman gerektirir"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "geçersiz dosya tanımlayıcı sayısı: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "bir oturum açma kabuğu gibi %s çalıştırılamıyor"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "%d için işleyici kaydedilemiyor"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "kaynak denetim sınırına ulaşıldı"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "\"%s\", bir \"%s\" projesi üyesi değil"
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "çağırılan görev son"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "\"%s\" projesine katılamadı"
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "\"%s\" projesi için hiçbir kaynak havuzu varsayılan atamaları kabul etmiyor"
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "belirtilen kaynak havuzu \"%s\" projesi için mevcut değil"
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "\"%s\" projesi için öntanımlı kaynak havuzu atanamadı"
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "\"%s\" projesi için setproject başarısız"
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "uyarı, \"%s\" projesi için kaynak denetim ataması başarısız"
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo sürüm %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Yapılandırma seçenekleri: %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "ölümcül hata, eklentiler yüklenemiyor"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "ilke eklentisi başlatılamıyor"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "eklenti çalıştırmak için bir komut döndürmedi"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "G/Ç eklentisi %s başlatılırken hata"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "beklenmeyen 0x%x sudo kipi"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "sen %s veritabanında yoksun"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "tty belirlenemiyor"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s, %d kullanıcı kimliği tarafından sahiplenmeli ve setuid biti ayarlanmış olmalı"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "etkin kullanıcı kimliği %d değil, %s 'nosuid' seçeneği ayarlanmış bir dosya sisteminde veya yetkisiz haklara sahip bir NFS dosya sisteminde mi?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "etkin kullanıcı kimliği %d değil, sudo setuid root ile mi yüklendi?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "ek grup kimlikleri ayarlanamıyor"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "etkin grup kimliği, runas gid %u olarak ayarlanamıyor"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "grup kimliği, runas gid %u olarak ayarlanamıyor"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "beklenmeyen alt sonlandırma şartı: %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "%s ilke eklentisi, bir `check_policy' yöntemi içermiyor"
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "%s ilke eklentisi listeleme yetkilerini desteklemiyor"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "%s ilke eklentisi -v seçeneğini desteklemiyor"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "%s ilke eklentisi -k/-K seçeneklerini desteklemiyor"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "yazılabilir geçici dizin bulunamadı"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "geçerli çalışma klasörü geri yüklenemiyor"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: düzenli bir dosya değil"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: sembolik bağlantı düzenlemesine izin verilmemiştir"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: yazılabilir klasördeki düzenleme dosyalarına izin verilmemiştir"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s: kısa yazım"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s düzenlenmemiş olarak bırakıldı"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "%s değiştirilmemiş"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "%s dosyasına yazılamıyor"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "düzenleme oturumu içerikleri %s içinde bırakıldı"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "geçici dosya okunamıyor"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: iç hata: yolların tek sayısı"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: geçici dosyalar oluşturulamıyor"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: bilinmeyen hata %d"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "geçici dosyalar onların özgün konumlarına kopyalanamıyor"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "bazı geçici dosyalar onların özgün konumlarına kopyalanamıyor"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "kullanıcı kimliği yetkili (%u) olarak değiştirilemiyor"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "eklenti hatası: sudoedit için eksik dosya listesi"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "saat okunamıyor"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "şifre okuma zaman aşımına uğradı"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "şifre sağlanmadı"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "parola okunamıyor"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "tty bulunmuyor ve askpass programı belirtilmemiş"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "askpass programı belirtilmemiş, SUDO_ASKPASS ayarlamayı deneyin"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "grup kimliği %u olarak ayarlanamıyor"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "kullanıcı kimliği %u olarak ayarlanamıyor"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "%s çalıştırılamıyor"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "stdin kaydedilemiyor"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "dup2 stdin yapılamıyor"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "stdin geri yüklenemiyor"
+
+#~ msgid "unable to get group vector"
+#~ msgstr "grup vektörü alınamıyor"
+
+#~ msgid "unknown uid %u: who are you?"
+#~ msgstr "bilinmeyen kullanıcı kimliği %u: kimsiniz?"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "sinyal tünelinden okuma hatası"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "tünelden okuma hatası"
+
+#, fuzzy
+#~| msgid "internal error, tried to emalloc(0)"
+#~ msgid "internal error, tried allocate zero bytes"
+#~ msgstr "dahili hata, emalloc(0) denendi"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "uçbirim ham kipine ayarlanamıyor"
+
+#~ msgid "unable to open socket"
+#~ msgstr "soket açılamıyor"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "dahili hata, emalloc2(0) denendi"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "dahili hata, ecalloc() denendi"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "dahili hata, erealloc() denendi"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "dahili hata, erealloc3() denendi"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "dahili hata, erecalloc() denendi"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "select failed"
+#~ msgstr "seçim başarısız"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: taşma tespit edildi"
+
+#~ msgid "list user's available commands\n"
+#~ msgstr "kullanıcının kullanılabilir komutlarını listele\n"
+
+#~ msgid "run a shell as target user\n"
+#~ msgstr "hedef kullanıcı olarak bir kabuk çalıştır\n"
+
+#~ msgid "when listing, list specified user's privileges\n"
+#~ msgstr "listelerken, belirtilen kullanıcının haklarını listele\n"
+
+#~ msgid ": "
+#~ msgstr ": "
diff --git a/po/uk.mo b/po/uk.mo
new file mode 100644
index 0000000..e59bf93
--- /dev/null
+++ b/po/uk.mo
Binary files differ
diff --git a/po/uk.po b/po/uk.po
new file mode 100644
index 0000000..3406c99
--- /dev/null
+++ b/po/uk.po
@@ -0,0 +1,926 @@
+# Ukrainian translation for sudo.
+# This file is put in the public domain.
+#
+# Yuri Chornoivan <yurchor@ukr.net>, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-10-29 21:00+0200\n"
+"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
+"Language-Team: Ukrainian <translation-team-uk@lists.sourceforge.net>\n"
+"Language: uk\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"X-Generator: Lokalize 2.0\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "не вдалося відкрити userdb"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "не вдалося перемкнутися на регістр «%s» для %s"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "не вдалося відновити регістр"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "не вдалося отримати потрібний об’єм пам’яті"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "Невідомий сигнал"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "некоректне значення"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "надто велике значення"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "надто мале значення"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "некоректне значення Path, «%s», у %s, рядок %u"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "некоректне значення %s, «%s», у %s, рядок %u"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "непідтримуване джерело групи, «%s», у %s, рядок %u"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "некоректна максимальна кількість груп, «%s», у %s, рядок %u"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "не вдалося виконати stat для %s"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s не є звичайним файлом"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s належить uid %u, має належати %u"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "Запис до «%s» можливий для довільного користувача"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "Запис до «%s» може здійснювати будь-який користувач з групи"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "не вдалося відкрити %s"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "невідомий клас входу %s"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "не вдалося встановити контекст користувача"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "не вдалося встановити пріоритет процесу"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "не вдалося змінити root на %s"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "не вдалося змінити uid користувача, від імені якого відбувається виконання (%u, %u)"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "не вдалося змінити каталог на %s"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "не вдалося встановити обробник для сигналу %d"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "не вдалося вилучити PRIV_PROC_EXEC з PRIV_LIMIT"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "помилка під час спроби читання з пари сокетів"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "неочікуваний тип відповіді на зворотному каналі: %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "не вдалося додати подію до черги обробки"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "не вдалося встановити tty для керування"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "не вдалося створити канал"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "не вдалося отримати повідомлення від батьківського процесу"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "не вдалося створити відгалуження"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "не вдалося виконати %s"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "не вдалося відновити позначку tty"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "не вдалося виконати ініціалізацію сеансу через додаток правил"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "помилка у циклі обробки подій"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "не вдалося відновити обробник для сигналу %d"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "не вдалося розмістити pty"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "не вдалося створити сокети"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "не вдалося надіслати повідомлення до процесу аудиту"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "помилка у %s, рядок %d під час спроби завантаження додатка «%s»"
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s має належати користувачеві з uid %d"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s має бути доступним до запису лише для власника"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "не вдалося завантажити %s: %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "не вдалося знайти символ «%s» у %s"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "у %2$s виявлено невідомий тип правил, %1$d"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "несумісна основна версія додатка, %d, (мало бути %d) у %s"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "ігноруємо додаток правил, «%s», у %s, рядок %d"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "можна визначати лише один додаток обробки правил"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "ігноруємо повторний запис додатка правил, «%s», у %s, рядок %d"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "ігноруємо повторний запис додатка введення-виведення, «%s», у %s, рядок %d"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "до додатка правил %s не включено метод check_policy"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "внутрішня помилка, переповнення %s"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "некоректна назва змінної середовища: %s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "аргументом параметра -C mмає бути число не менше за 3"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "не можна одночасно вказувати параметри «-i» і «-s»"
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "не можна одночасно вказувати параметри «-i» і «-E»"
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "не можна використовувати «-E» у режимі редагування"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "не можна вказувати змінні середовища у режимі редагування"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "параметр «-U» можна використовувати лише разом з параметром «-l»"
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "параметри «-A» і «-S» не можна використовувати одночасно"
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "підтримки sudoedit для цієї платформи не передбачено"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Можна використовувати лише такі параметри: -e, -h, -i, -K, -l, -s, -v та -V"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s — редагувати файли від імені іншого користувача\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s — виконати команду від імені іншого користувача\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Параметри:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "використовувати допоміжну програму для запитів щодо пароля"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "використовувати вказаний тип розпізнавання BSD"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "виконати команду у фоновому режимі"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "закрити всі дескриптори файлів >= num"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "виконати команду з вказаним класом доступу BSD"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "зберегти середовище користувача на час виконання команди"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "зберегти вказані змінні середовища"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "редагувати файли замість виконання команди"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "виконати команду від імені групи користувачів, вказаної за назвою або ідентифікатором"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "встановити для змінної HOME значення домашнього каталогу вказаного користувача."
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "показати довідкове повідомлення і завершити роботу"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "виконати команду на комп’ютері (якщо підтримується додатком)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "запустити оболонку для входу до системи від імені вказаного користувача; слід вказати команду запуску"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "повністю вилучити файл часової позначки"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "позбавити чинності файл часової позначки"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "показати список прав доступу користувача або перевірити певну команду; подвоєння параметра призводить до виведення додаткових даних"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "неінтерактивний режим, не просити користувача відповідати на питання"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "зберегти вектор групи, не встановлювати вектор вказаного користувача"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "використовувати вказаний інструмент отримання паролів"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "створити контекст захисту SELinux з вказаною роллю"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "прочитати пароль зі стандартного джерела вхідних даних"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "виконати командну оболонку від імені вказаного користувача; слід також вказати команду"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "створити контекст захисту SELinux вказаного типу"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "перервати виконання команди щойно буде перевищено вказане обмеження за часом"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "у режимі списку, показати права доступу користувача"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "виконати команду (або редагувати файл) від імені користувача, вказаного за іменем або ідентифікатором"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "показати дані щодо версії і завершити роботу"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "оновити штамп часу користувача без виконання команди"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "зупинити обробку аргументів командного рядка"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "не вдалося відкрити систему аудиту"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "не вдалося надіслати повідомлення аудиту"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "не вдалося виконати fgetfilecon %s"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s змінено позначки"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "не вдалося відновити контекст %s"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "не вдалося відкрити %s, не змінюємо позначки tty"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s не є символьним пристроєм, не змінюємо мітки tty"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "не вдалося отримати поточний контекст tty, не змінюємо позначки tty"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "невідомий клас захисту «chr_file», не змінюємо позначки tty"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "не вдалося отримати новий контекст tty, не змінюємо позначки tty"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "не вдалося встановити новий контекст tty"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "вам слід вказати роль для типу %s"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "не вдалося отримати типовий тип для ролі %s"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "не вдалося встановити нову роль %s"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "не вдалося встановити новий тип %s"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s не є коректним контекстом"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "не вдалося отримати old_context"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "не вдалося визначити режим примушення."
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "не вдалося встановити контекст tty у значення %s"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "не вдалося встановити контекст виконання у значення %s"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "не вдалося встановити контекст ключа створення у значення %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "потребує принаймні одного аргументу"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "некоректний номер дескриптора файла: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "%s не можна працювати як оболонка для входу"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "не вдалося зберегти обробник для сигналу %d"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "перевищено обмеження керування ресурсами"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "користувач «%s» не є учасником проекту «%s»"
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "викликане завдання є завершальним"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "не вдалося приєднатися до проекту «%s»"
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "для проекту «%s» не існує сховища ресурсів, яке приймає типові прив’язки"
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "у проекті «%s» не існує вказаного сховища ресурсів"
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "не вдалося виконати прив’язку до типового сховища ресурсів проекту «%s»"
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "помилка під час виконання setproject для проекту «%s»"
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "попередження, помилка призначення керування ресурсами проекту «%s»"
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Версія sudo %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Параметри налаштування: %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "критична помилка, не вдалося завантажити додатки"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "не вдалося ініціалізувати додаток правил"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "додатком не повернуто команди, яку слід виконати"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "помилка під час спроби ініціалізації додатка введення/виведення даних %s"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "неочікуваний режим sudo 0x%x"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "вас немає у базі даних %s"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "не вдалося визначити tty"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s має належати користувачеві з uid %d, крім того, має бути встановлено біт setuid"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "поточним uid не є %d. Можливо %s зберігається у файловій системі зі встановленим параметром «nosuid» або у файловій системі NFS без прав доступу root?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "поточним uid не є %d, sudo встановлено з ідентифікатором користувача root?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "не вдалося встановити ідентифікатори додаткових груп"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "не вдалося встановити ефективний ідентифікатор групи для ідентифікатора групи запуску %u"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "не вдалося встановити ідентифікатор групи для ідентифікатора групи запуску %u"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "неочікувана умова переривання дочірнього процесу: %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "до додатка правил %s не включено метод «check_policy»"
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "у додатку правил %s не передбачено підтримки побудови списку прав доступу"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "у додатку правил %s не передбачено підтримки параметра -v"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "у додатку правил %s не передбачено підтримки параметрів -k/-K"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "не знайдено придатного до запису тимчасового каталогу"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "не вдалося відновити поточний робочий каталог"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: не є звичайним файлом"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: не можна редагувати символічні посилання"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: не можна редагувати файли у непридатному до запису каталозі"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s: короткий запис"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s залишено без змін"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "%s не змінено"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "не вдалося виконати запис до %s"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "дані сеансу редагування залишилися у %s"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "не вдалося виконати читання з файла тимчасових даних"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: внутрішня помилка: непарна кількість шляхів"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: не вдалося створити тимчасові файли"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: невідома помилка %d"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "не вдалося скопіювати тимчасові файли назад до початкового місця зберігання"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "не вдалося скопіювати деякі з тимчасових файлів назад до початкового місця зберігання"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "не вдалося змінити значення uid на значення root (%u)"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "помилка додатка: не вистачає списку файлів для sudoedit"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "не вдалося прочитати час на годиннику"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "перевищено граничний час очікування на пароль"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "пароль не надано"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "не вдалося прочитати пароль"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "не виявлено tty і не вказано програми askpass"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "не вказано програми askpass, спробуйте встановити значення змінної SUDO_ASKPASS"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "не вдалося встановити gid у значення %u"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "не вдалося встановити uid у значення %u"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "не вдалося виконати %s"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "не вдалося зберегти stdin"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "не вдалося виконати dup2 для stdin"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "не вдалося відновити stdin"
diff --git a/po/vi.mo b/po/vi.mo
new file mode 100644
index 0000000..ad32bba
--- /dev/null
+++ b/po/vi.mo
Binary files differ
diff --git a/po/vi.po b/po/vi.po
new file mode 100644
index 0000000..bb726a8
--- /dev/null
+++ b/po/vi.po
@@ -0,0 +1,1006 @@
+# Vietnamese translation for sudo.
+# Bản dịch tiếng Việt dành cho sudo.
+# This file is put in the public domain.
+# Trần Ngọc Quân <vnwildman@gmail.com>, 2012-2014, 2015, 2016, 2017, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-11-01 13:57+0700\n"
+"Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
+"Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
+"Language: vi\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Language-Team-Website: <http://translationproject.org/team/vi.html>\n"
+"X-Generator: Gtranslator 2.91.7\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+"X-Poedit-Language: Vietnamese\n"
+"X-Poedit-Country: VIET NAM\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "không thể mở cơ sở dữ liệu người dùng userdb"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "không thể chuyển đến sổ đăng ký “%s” cho %s"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "không thể phục hồi sổ đăng ký"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "không thể cấp phát bộ nhớ"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "Không hiểu tín hiệu"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "giá trị không hợp lệ"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "giá trị quá lớn"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "giá trị quá nhỏ"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "đường dẫn không hợp lệ “%s” trong %s, dòng %u"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "giá trị không hợp lệ cho %s “%s” trong %s, dòng %u"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "nguồn nhóm không được hỗ trợ “%s” trong %s, dòng %u"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "nhóm tối đa không hợp lệ “%s” trong %s, dòng %u"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "không thể lấy thống kê về %s"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s không phải tập tin thường"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s được sở hữu bởi uid %u, nên là %u"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "%s là ai ghi cũng được"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "%s là nhóm có thể ghi"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "không thể mở “%s”"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "không hiểu lớp đăng nhập %s"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "không thể đặt ngữ cảnh người dùng"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "không thể đặt ưu tiên cho quá trình"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "không thể chuyển đổi thư mục gốc thành %s"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "không thể thay đổi thành chạy như là mã người dùng này (%u, %u)"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "không thể thay đổi thư mục thành %s"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "không thể đặt bộ tiếp hợp cho tín hiệu %d"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "không thể xóa bỏ PRIV_PROC_EXEC từ PRIV_LIMIT"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "gặp lỗi khi đọc từ socketpair"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "kiểu trả về không như mong đợi từ backchannel: %d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "không thể thêm sự kiện vào hàng đợi"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "không thể đặt điều khiển cho tty"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "không tạo được đường ống pipe"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "không thể nhận tin nhắn từ cha mẹ"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "không thể tạo tiến trình con"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "không thể thực thi %s"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "không thể phục hồi nhãn cho tty"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "phần bổ sung chính sách gặp lỗi khi khởi tạo phiên"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "có lỗi trong vòng lặp sự kiện"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "không thể phục hồi bộ tiếp hợp cho tín hiệu %d"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "không thể phân bổ pty"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "không thể tạo các ổ cắm mạng"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "không thể gửi tin đến tiến trình theo dõi"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "lỗi trong %s, dòng %d, trong khi tải phần bổ sung “%s”"
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s phải được sở hữu bởi uid %d"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s phải là những thứ chỉ có thể ghi bởi chủ sở hữu"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "không thể tải %s: %s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "không tìm thấy ký hiệu “%s” trong %s"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "không hiểu kiểu chính sách %d tìm thấy trong %s"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "không tương thích số hiệu phiên bản lớn %d (cần %d) tìm thấy trong %s"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "lờ đi phần bổ sung chính sách “%s” trong %s, dòng %d"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "chỉ được phép chỉ định một phần bổ sung chính sách"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "lờ đi phần bổ sung chính sách bị trùng lặp “%s” trong %s, dòng %d"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "lờ đi phần bổ sung I/O trùng lặp “%s” trong %s, dòng %d"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "phần bổ sung chính sách %s không bao gồm phương thức kiểm tra chính sách"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "lỗi nội bộ, %s bị tràn"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "tên biến môi trường không hợp lệ: %s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "đối số cho -C phải là một số lớn hơn hoặc bằng 3"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "bạn không thể chỉ định đồng thời cả hai tùy chọn “-i” và “-s”"
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "bạn không thể chỉ định cả hai tùy chọn “-i” và “-E”"
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "tùy chọn “-E” không hợp lệ trong chế độ chỉnh sửa"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "bạn có lẽ không được chỉ định biến môi trường trong chế độ soạn thảo"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "tùy chọn “-U” chỉ sử dụng cùng với tùy chọn “-l”"
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "tùy chọn “-A” và “-S” không thể dùng cùng một lúc với nhau"
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit không được hỗ trợ trên nền tảng này"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Chỉ được phép chỉ định một trong số các tùy chọn -e, -h, -i, -K, -l, -s, -v hay -V"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - sửa chữa các tập tin trên danh nghĩa người dùng khác\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - thực hiện câu lệnh trên danh nghĩa người dùng khác\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Tùy chọn:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "sử dụng chương trình trợ giúp cho hỏi đáp mật khẩu"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "sử dụng kiểu xác thực BSD được chỉ ra"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "chạy lệnh ở chế độ nền"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "đóng tất cả các mô tả của tập tin >= số"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "chạy lệnh với một lớp đăng nhập BSD được chỉ ra"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "bảo tồn môi trường người dùng khi thi hành lệnh"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "bảo tôn các biến môi trường chuyên biệt"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "chỉnh sửa các tập tin thay vì chạy lệnh"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "thực hiện câu lệnh với tư cách là tên hay ID của nhóm được chỉ định"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "đặt biến HOME cho thư mục riêng của người dùng đích"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "hiển thị trợ giúp này rồi thoát"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "chạy câu lệnh trên máy chủ (nếu được hỗ trợ bởi phần bổ sung)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "chạy shell đăng nhập như là người dùng đích; có thể đồng thời chỉ định một câu lệnh"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "gỡ bỏ hoàn toàn dấu vết thời gian của tập tin"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "làm mất hiệu lực dấu vết thời gian (timestamp) của tập tin"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "liệt kê đặc quyền của người dùng hay kiểm tra câu lệnh xác định; dùng hai lần cho định dạng dài"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "chế độ không-tương-tác, sẽ không hỏi tên người dùng"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "bảo tồn véc-tơ nhóm thay vì các cài đặt cho đích"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "sử dụng nhắc nhập mật khẩu đã chỉ ra"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "tạo ngữ cảnh an ninh SELinux với vai trò đã chỉ ra"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "đọc mật khẩu từ đầu vào tiêu chuẩn"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "chạy hệ vỏ dưới danh nghĩa người dùng đích; cũng có thể chỉ định thêm câu lệnh"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "tạo ngữ cảnh an ninh SELinux với kiểu đã chỉ ra"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "chấm dứt lệnh sau một thời hạn giới hạn được chỉ định"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "ở chế độ liệt kê, hiển thị đặc quyền cho người dùng"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "chạy lệnh (hay sửa chữa tập tin) trên tư cách của người dùng hay ID đã chỉ ra"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "hiển thị thông tin phiên bản rồi thoát"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "cập nhật dấu vết thời gian (timestamp) của người dùng mà không chạy một lệnh"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "dừng việc xử lý đối số dòng lệnh"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "không thể mở hệ thống audit"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "không thể gửi thông tin audit"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "không thể fgetfilecon %s"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s nhãn đã thay đổi"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "Không thể phục hồi ngữ cảnh cho %s"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "không thể mở %s, không phải là tty dán nhãn lại"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s không phải là một thiết bị ký tự, không phải là tty dán nhãn lại"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "không thể lấy ngữ cảnh tty hiện hành, không phải là tty dán nhãn lại"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "không hiểu lớp an ninh \"chr_file\", không phải là tty dán nhãn lại"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "không thể lấy ngữ cảnh tty mới, không phải là tty dán nhãn lại"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "không thể đặt ngữ cảnh tty mới"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "bạn phải chỉ định một kiểu vai trò cho %s"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "không thể lấy kiểu mặc định cho vai trò %s"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "gặp lỗi khi đặt đặt vai trò mới %s"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "gặp lỗi khi đặt kiểu mới %s"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s không phải là một ngữ cảnh hợp lệ"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "gặp lỗi khi lấy ngữ cảnh cũ"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "không thể xác định rõ chế độ ép buộc."
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "không thể cài đặt ngữ cảnh tty mới cho %s"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "không thể đặt ngữ cảnh bảo thực thi thành %s"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "không thể đặt ngữ cảnh tạo khóa thành %s"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "cần thiết ít nhất một đối số"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "số mô tả của tập tin không hợp lệ: %s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "không thể chạy %s như là hệ vỏ đăng nhập"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "không thể ghi lại bộ tiếp hợp cho tín hiệu %d"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "giới hạn điều khiển tài nguyên đã tới hạn"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "người dùng “%s” không phải là thành viên của dự án “%s”"
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "tác vụ được gọi là cuối cùng"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "không thể gia nhập dự án “%s”"
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "không kho tài nguyên chung nào được thừa nhận ràng buộc đã tồn tại sẵn cho dự án “%s”"
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "nguồn tài nguyên chung được chỉ ra chưa tồn tại cho dự án “%s”"
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "không thể buộc phần tài nguyên chung mặc định cho dự án “%s”"
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "đặt dự án cho dự án “%s” gặp lỗi"
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "cảnh báo, nguồn điều khiển gán gặp lỗi cho dự án “%s”"
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo phiên bản %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Các tùy chọn cấu hình: %s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "lỗi nghiêm trọng, không thể tải các phần bổ sung"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "không thể khởi tạo phần bổ sung chính sách"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "phần bổ sung không trả về một lệnh để thực thi"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "Gặp lỗi khi nạp phần bổ sung I/O %s"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "không mong đợi chế độ sudo 0x%x"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "bạn không tồn tại trong cơ sở dữ liệu %s"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "không thể dò tìm tty"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s phải được sở hữu bởi uid %d và bít setuid phải được đặt"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "uid chịu tác động hiện tại không phải là %d, có phải là %s trên hệ thống tập tin với tùy chọn “nosuid” được đặt, hay một hệ thống tập tin NFS không có đặc quyền của root không?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "uid chịu tác động hiện tại không phải là %d, chương trình sudo có được cài với setuid root không?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "không thể đặt nhóm phụ IDs"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "không thể đặt hiệu ứng gid chạy như là gid %u"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "không thể thay đổi gid thành runas gid %u"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "biểu thức điều kiện con kết thúc không như mong đợi: %d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "phần bổ sung chính sách %s bị thiếu phương thức kiểm tra chính sách “check_policy”"
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "phần bổ sung chính sách %s không hỗ trợ liệt kê đặc quyền"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "phần bổ sung chính sách %s không hỗ trợ tùy chọn -v"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "phần bổ sung chính sách %s không hỗ trợ tùy chọn -k/-K"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "không thể tìm thấy thư mục tạm ghi được nào"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "không thể phục hồi thư mục làm việc hiện tại"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: không phải là tập tin thường"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s: sửa các liên kết mềm là không được phép"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s: sửa các tập tin trong thư mục ghi được là là không được phép"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s: ghi ngắn"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s còn lại chưa thay đổi"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "%s không thay đổi"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "không thể ghi vào %s"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "nội dung của phiên chỉnh sửa chỉ còn %s"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "không thể đọc tập tin tạm thời"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh: lỗi nội tại: số cũ của đường dẫn"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh: không thể tạo tập tin tạm thời"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh: không hiểu lỗi %d"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "không thể chép các tập tin tạm trở lại vị trí gốc của chúng"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "không thể chép một số tập tin tạm trở lại vị trí gốc của chúng"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "không thể thay đổi uid thành root (%u)"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "lỗi phần bổ sung: thiếu danh sách tập tin cho sudoedit"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "không thể đọc khóa"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "quá thời hạn chờ đọc mật khẩu"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "chưa đưa ra mật khẩu"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "không thể đọc mật khẩu"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "không có tty hiện diện và không có chương trình hỏi mật khẩu nào được chỉ ra"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "không có chương trình hỏi mật khẩu nào được chỉ ra, hãy thử đặt SUDO_ASKPASS"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "không thể đặt mã số nhóm thành %u"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "không thể đặt mã số người dùng thành %u"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "không thể chạy %s"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "không thể ghi lại đầu vào tiêu chuẩn"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "không thể dup2 (nhân đôi) đầu vào tiêu chuẩn"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "không thể phục hồi đầu vào tiêu chuẩn"
+
+#~ msgid "unable to get group vector"
+#~ msgstr "không thể lấy véc-tơ nhóm"
+
+#~ msgid "unknown uid %u: who are you?"
+#~ msgstr "không hiểu mã số người dùng %u: bạn là ai?"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "lỗi khi đọc từ đường ống dẫn tín hiệu"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "gặp lỗi khi đọc từ một đường ống dẫn lệnh"
+
+#~ msgid "internal error, tried allocate zero bytes"
+#~ msgstr "lỗi nội bộ, đã phân bổ 0 byte bộ nhớ"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "không thể đặt thiết bị cuối sang chế độ thô"
+
+#~ msgid "unable to open socket"
+#~ msgstr "không mở được socket"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s: %s: %s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s: %s\n"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "lỗi nội bộ, đã dùng erealloc2(0)"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "lỗi nội bộ, đã dùng ecalloc(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "lỗi nội bộ, đã dùng erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "lỗi nội bộ, đã dùng erealloc3(0)"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "lỗi nội bộ, đã dùng erecalloc(0)"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces: đã có chỗ bị tràn"
+
+#~ msgid "value out of range"
+#~ msgstr "giá trị nằm ngoài phạm vi"
+
+#~ msgid "select failed"
+#~ msgstr "lựa chọn gặp lỗi"
+
+#~ msgid "list user's available commands\n"
+#~ msgstr "Danh sách các biến câu lệnh người dùng có thể sử dụng\n"
+
+#~ msgid "run a shell as target user\n"
+#~ msgstr "chạy shell như là người dùng đích\n"
+
+#~ msgid "when listing, list specified user's privileges\n"
+#~ msgstr "khi liệt kê, liệt kê các đặc quyền của người dùng\n"
+
+#~ msgid ": "
+#~ msgstr ": "
+
+#~ msgid "internal error, emalloc2() overflow"
+#~ msgstr "lỗi nội bộ, erealloc2() bị tràn"
+
+#~ msgid "internal error, erealloc3() overflow"
+#~ msgstr "lỗi nội bộ, erealloc3() bị tràn"
+
+#~ msgid "%s: at least one policy plugin must be specified"
+#~ msgstr "%s: phải xác định ít nhất một phần bổ xung chính sách"
+
+#~ msgid "must be setuid root"
+#~ msgstr "phải được đặt setuid của root"
diff --git a/po/zh_CN.mo b/po/zh_CN.mo
new file mode 100644
index 0000000..80f7479
--- /dev/null
+++ b/po/zh_CN.mo
Binary files differ
diff --git a/po/zh_CN.po b/po/zh_CN.po
new file mode 100644
index 0000000..62ecde7
--- /dev/null
+++ b/po/zh_CN.po
@@ -0,0 +1,1003 @@
+# Chinese simplified translation for sudo.
+# sudo 的简体中文翻译。
+# This file is put in the public domain.
+# Wylmer Wang <wantinghard@gmail.com>, 2011, 2012, 2013, 2014, 2015, 2016, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo-1.8.26b1\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-10-29 08:31-0600\n"
+"PO-Revision-Date: 2018-11-05 09:18+0800\n"
+"Last-Translator: Wylmer Wang <wantinghard@gmail.com>\n"
+"Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+
+#: lib/util/aix.c:90 lib/util/aix.c:177
+msgid "unable to open userdb"
+msgstr "无法打开 userdb"
+
+#: lib/util/aix.c:232
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "无法为 %2$s 切换到注册表“%1$s”"
+
+#: lib/util/aix.c:257
+msgid "unable to restore registry"
+msgstr "无法恢复注册表"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/gidlist.c:79
+#: lib/util/sudo_conf.c:191 lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354
+#: lib/util/sudo_conf.c:558 src/conversation.c:82 src/exec_common.c:112
+#: src/exec_common.c:128 src/exec_common.c:137 src/exec_monitor.c:210
+#: src/exec_monitor.c:465 src/exec_monitor.c:471 src/exec_monitor.c:479
+#: src/exec_monitor.c:487 src/exec_monitor.c:494 src/exec_monitor.c:501
+#: src/exec_monitor.c:508 src/exec_monitor.c:515 src/exec_monitor.c:522
+#: src/exec_monitor.c:529 src/exec_monitor.c:536 src/exec_nopty.c:212
+#: src/exec_nopty.c:218 src/exec_nopty.c:227 src/exec_nopty.c:234
+#: src/exec_nopty.c:241 src/exec_nopty.c:248 src/exec_nopty.c:255
+#: src/exec_nopty.c:262 src/exec_nopty.c:269 src/exec_nopty.c:276
+#: src/exec_nopty.c:283 src/exec_nopty.c:290 src/exec_nopty.c:297
+#: src/exec_nopty.c:305 src/exec_nopty.c:467 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:994
+#: src/exec_pty.c:1157 src/exec_pty.c:1163 src/exec_pty.c:1172
+#: src/exec_pty.c:1179 src/exec_pty.c:1186 src/exec_pty.c:1193
+#: src/exec_pty.c:1200 src/exec_pty.c:1207 src/exec_pty.c:1214
+#: src/exec_pty.c:1221 src/exec_pty.c:1228 src/exec_pty.c:1235
+#: src/exec_pty.c:1243 src/exec_pty.c:1661 src/load_plugins.c:57
+#: src/load_plugins.c:70 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:203
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:676 src/sudo.c:686 src/sudo.c:706 src/sudo.c:725
+#: src/sudo.c:734 src/sudo.c:743 src/sudo.c:760 src/sudo.c:801 src/sudo.c:811
+#: src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092 src/sudo.c:1266
+#: src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789 src/sudo_edit.c:886
+#: src/sudo_edit.c:1000 src/sudo_edit.c:1020
+#, c-format
+msgid "%s: %s"
+msgstr "%s:%s"
+
+#: lib/util/aix.c:280 lib/util/gidlist.c:69 lib/util/sudo_conf.c:192
+#: lib/util/sudo_conf.c:277 lib/util/sudo_conf.c:354 lib/util/sudo_conf.c:558
+#: src/conversation.c:83 src/exec_common.c:112 src/exec_common.c:129
+#: src/exec_common.c:138 src/exec_monitor.c:465 src/exec_monitor.c:471
+#: src/exec_monitor.c:479 src/exec_monitor.c:487 src/exec_monitor.c:494
+#: src/exec_monitor.c:501 src/exec_monitor.c:508 src/exec_monitor.c:515
+#: src/exec_monitor.c:522 src/exec_monitor.c:529 src/exec_monitor.c:536
+#: src/exec_nopty.c:212 src/exec_nopty.c:218 src/exec_nopty.c:227
+#: src/exec_nopty.c:234 src/exec_nopty.c:241 src/exec_nopty.c:248
+#: src/exec_nopty.c:255 src/exec_nopty.c:262 src/exec_nopty.c:269
+#: src/exec_nopty.c:276 src/exec_nopty.c:283 src/exec_nopty.c:290
+#: src/exec_nopty.c:297 src/exec_nopty.c:305 src/exec_pty.c:778
+#: src/exec_pty.c:787 src/exec_pty.c:844 src/exec_pty.c:1157
+#: src/exec_pty.c:1163 src/exec_pty.c:1172 src/exec_pty.c:1179
+#: src/exec_pty.c:1186 src/exec_pty.c:1193 src/exec_pty.c:1200
+#: src/exec_pty.c:1207 src/exec_pty.c:1214 src/exec_pty.c:1221
+#: src/exec_pty.c:1228 src/exec_pty.c:1235 src/exec_pty.c:1243
+#: src/exec_pty.c:1661 src/load_plugins.c:219 src/load_plugins.c:240
+#: src/load_plugins.c:309 src/load_plugins.c:315 src/load_plugins.c:329
+#: src/load_plugins.c:335 src/parse_args.c:182 src/parse_args.c:204
+#: src/parse_args.c:278 src/parse_args.c:565 src/parse_args.c:587
+#: src/preserve_fds.c:52 src/preserve_fds.c:137 src/selinux.c:89
+#: src/selinux.c:314 src/selinux.c:437 src/selinux.c:446 src/sesh.c:115
+#: src/sudo.c:616 src/sudo.c:834 src/sudo.c:1071 src/sudo.c:1092
+#: src/sudo.c:1266 src/sudo.c:1382 src/sudo_edit.c:256 src/sudo_edit.c:789
+#: src/sudo_edit.c:886 src/sudo_edit.c:1000 src/sudo_edit.c:1020
+msgid "unable to allocate memory"
+msgstr "无法分配内存"
+
+#: lib/util/strsignal.c:53
+msgid "Unknown signal"
+msgstr "未知信号"
+
+#: lib/util/strtoid.c:82 lib/util/strtoid.c:129 lib/util/strtoid.c:157
+#: lib/util/strtomode.c:54 lib/util/strtonum.c:63 lib/util/strtonum.c:181
+msgid "invalid value"
+msgstr "值无效"
+
+#: lib/util/strtoid.c:89 lib/util/strtoid.c:136 lib/util/strtoid.c:164
+#: lib/util/strtomode.c:60 lib/util/strtonum.c:66 lib/util/strtonum.c:193
+msgid "value too large"
+msgstr "值过大"
+
+#: lib/util/strtoid.c:91 lib/util/strtoid.c:142 lib/util/strtomode.c:60
+#: lib/util/strtonum.c:66 lib/util/strtonum.c:187
+msgid "value too small"
+msgstr "值过小"
+
+#: lib/util/sudo_conf.c:210
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "%2$s 第 %3$u 行的路径值“%1$s”无效"
+
+#: lib/util/sudo_conf.c:376 lib/util/sudo_conf.c:429
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "%3$s 第 %4$u 行的 %1$s 的值“%2$s”无效"
+
+#: lib/util/sudo_conf.c:397
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "不支持 %2$s 第 %3$u 行的组来源“%1$s”"
+
+#: lib/util/sudo_conf.c:413
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "%2$s 第 %3$u 行的最大组数“%1$s”无效"
+
+#: lib/util/sudo_conf.c:574
+#, c-format
+msgid "unable to stat %s"
+msgstr "无法 stat %s"
+
+#: lib/util/sudo_conf.c:577
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s 不是常规文件"
+
+#: lib/util/sudo_conf.c:580
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s 属于用户 ID %u,应为 %u"
+
+#: lib/util/sudo_conf.c:584
+#, c-format
+msgid "%s is world writable"
+msgstr "%s 可被任何人写"
+
+#: lib/util/sudo_conf.c:587
+#, c-format
+msgid "%s is group writable"
+msgstr "%s 可被用户组写"
+
+#: lib/util/sudo_conf.c:597 src/selinux.c:213 src/selinux.c:230 src/sudo.c:360
+#, c-format
+msgid "unable to open %s"
+msgstr "打不开 %s"
+
+#: src/exec.c:165
+#, c-format
+msgid "unknown login class %s"
+msgstr "未知的登录类别 %s"
+
+#: src/exec.c:178
+msgid "unable to set user context"
+msgstr "无法设置用户环境"
+
+#: src/exec.c:194
+msgid "unable to set process priority"
+msgstr "无法设置进程优先级"
+
+#: src/exec.c:202
+#, c-format
+msgid "unable to change root to %s"
+msgstr "无法从 root 切换到 %s"
+
+#: src/exec.c:215 src/exec.c:221 src/exec.c:228
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "无法切换到以用户 ID(%u,%u)运行"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "无法将目录切换到 %s"
+
+#: src/exec.c:345 src/exec_monitor.c:574 src/exec_monitor.c:576
+#: src/exec_nopty.c:525 src/exec_pty.c:522 src/exec_pty.c:1329
+#: src/exec_pty.c:1331 src/signal.c:148 src/signal.c:162
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "无法设置 %d 信号的处理程序"
+
+#: src/exec_common.c:171
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "无法从 PRIV_LIMIT 中移除 PRIV_PROC_EXEC"
+
+#: src/exec_monitor.c:364
+msgid "error reading from socketpair"
+msgstr "从套接字对读取出错"
+
+#: src/exec_monitor.c:381
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "联络通道的回应类型异常:%d"
+
+#: src/exec_monitor.c:473 src/exec_monitor.c:481 src/exec_monitor.c:489
+#: src/exec_monitor.c:496 src/exec_monitor.c:503 src/exec_monitor.c:510
+#: src/exec_monitor.c:517 src/exec_monitor.c:524 src/exec_monitor.c:531
+#: src/exec_monitor.c:538 src/exec_nopty.c:220 src/exec_nopty.c:229
+#: src/exec_nopty.c:236 src/exec_nopty.c:243 src/exec_nopty.c:250
+#: src/exec_nopty.c:257 src/exec_nopty.c:264 src/exec_nopty.c:271
+#: src/exec_nopty.c:278 src/exec_nopty.c:285 src/exec_nopty.c:292
+#: src/exec_nopty.c:299 src/exec_nopty.c:307 src/exec_pty.c:644
+#: src/exec_pty.c:649 src/exec_pty.c:746 src/exec_pty.c:753 src/exec_pty.c:850
+#: src/exec_pty.c:1165 src/exec_pty.c:1174 src/exec_pty.c:1181
+#: src/exec_pty.c:1188 src/exec_pty.c:1195 src/exec_pty.c:1202
+#: src/exec_pty.c:1209 src/exec_pty.c:1216 src/exec_pty.c:1223
+#: src/exec_pty.c:1230 src/exec_pty.c:1237 src/exec_pty.c:1614
+#: src/exec_pty.c:1624 src/exec_pty.c:1669 src/exec_pty.c:1676
+#: src/exec_pty.c:1703
+msgid "unable to add event to queue"
+msgstr "无法将事件添加到队列"
+
+#: src/exec_monitor.c:592
+msgid "unable to set controlling tty"
+msgstr "无法设置控制终端"
+
+#: src/exec_monitor.c:600 src/exec_nopty.c:364 src/exec_pty.c:1408
+#: src/exec_pty.c:1429 src/exec_pty.c:1449 src/tgetpass.c:292
+msgid "unable to create pipe"
+msgstr "无法创建管道"
+
+#: src/exec_monitor.c:608
+msgid "unable to receive message from parent"
+msgstr "无法从父(进程)接收消息"
+
+#: src/exec_monitor.c:614 src/exec_nopty.c:382 src/exec_pty.c:1487
+#: src/tgetpass.c:296
+msgid "unable to fork"
+msgstr "无法执行 fork"
+
+#: src/exec_monitor.c:628 src/sesh.c:125 src/sudo.c:1130
+#, c-format
+msgid "unable to execute %s"
+msgstr "无法执行 %s"
+
+#: src/exec_monitor.c:711 src/exec_nopty.c:435
+msgid "unable to restore tty label"
+msgstr "无法恢复终端标签"
+
+#: src/exec_nopty.c:358 src/exec_pty.c:1338
+msgid "policy plugin failed session initialization"
+msgstr "策略插件会话初始化失败"
+
+#: src/exec_nopty.c:424 src/exec_pty.c:1574
+msgid "error in event loop"
+msgstr "事件循环中有错误"
+
+#: src/exec_nopty.c:533 src/exec_pty.c:557 src/signal.c:110
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "无法恢复 %d 信号的处理程序"
+
+#: src/exec_pty.c:156
+msgid "unable to allocate pty"
+msgstr "无法分配伪终端"
+
+#: src/exec_pty.c:1318
+msgid "unable to create sockets"
+msgstr "无法创建套接字"
+
+#: src/exec_pty.c:1531
+msgid "unable to send message to monitor process"
+msgstr "无法向监视进程发送消息"
+
+#: src/load_plugins.c:55 src/load_plugins.c:68 src/load_plugins.c:90
+#: src/load_plugins.c:120 src/load_plugins.c:128 src/load_plugins.c:134
+#: src/load_plugins.c:175 src/load_plugins.c:183 src/load_plugins.c:190
+#: src/load_plugins.c:196
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "在加载插件“%3$s”时在 %1$s 第 %2$d 行出错"
+
+#: src/load_plugins.c:92
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s:%s"
+
+#: src/load_plugins.c:130
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s 必须属于用户 ID %d(的用户)"
+
+#: src/load_plugins.c:136
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s 必须只对其所有者可写"
+
+#: src/load_plugins.c:177
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "无法加载 %s:%s"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "在 %2$s 中找不到符号“%1$s”"
+
+#: src/load_plugins.c:192
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "%2$s 中的策略类型 %1$d 未知"
+
+#: src/load_plugins.c:198
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "%3$s 中发现不兼容的插件主版本号 %1$d(应为 %2$d)"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "忽略位于 %2$s 第 %3$d 行的策略插件“%1$s”"
+
+#: src/load_plugins.c:209
+msgid "only a single policy plugin may be specified"
+msgstr "只能指定一个策略插件"
+
+#: src/load_plugins.c:212
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "忽略位于 %2$s 第 %3$d 行的重复策略插件“%1$s”"
+
+#: src/load_plugins.c:231
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "忽略位于 %2$s 第 %3$d 行的重复 I/O 插件“%1$s”"
+
+#: src/load_plugins.c:347
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "策略插件 %s 不包含 check_policy 方法"
+
+#: src/net_ifs.c:180 src/net_ifs.c:197 src/net_ifs.c:342 src/sudo.c:470
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "内部错误,%s 溢出"
+
+#: src/parse_args.c:224
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "无效的环境变量名:%s"
+
+#: src/parse_args.c:320
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "-C 选项的参数必须是一个大于等于 3 的数字"
+
+#: src/parse_args.c:505
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "您不能同时指定“-i”和“-s”选项"
+
+#: src/parse_args.c:509
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "您不能同时指定“-i”和“-E”选项"
+
+#: src/parse_args.c:519
+msgid "the `-E' option is not valid in edit mode"
+msgstr "“-E”选项在编辑模式中无效"
+
+#: src/parse_args.c:521
+msgid "you may not specify environment variables in edit mode"
+msgstr "在编辑模式中您不能指定环境变量"
+
+#: src/parse_args.c:529
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "“-U”选项只能与“-l”选项一起使用"
+
+#: src/parse_args.c:533
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "“-A”和“-S”选项不可同时使用"
+
+#: src/parse_args.c:609
+msgid "sudoedit is not supported on this platform"
+msgstr "此平台不支持 sudoedit"
+
+#: src/parse_args.c:682
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "只能指定 -e、-h、-i、-K、-l、-s、-v 或 -V 选项中的一个"
+
+#: src/parse_args.c:696
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - 以其他用户身份编辑文件\n"
+"\n"
+
+#: src/parse_args.c:698
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - 以其他用户身份执行一条命令\n"
+"\n"
+
+#: src/parse_args.c:703
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"选项:\n"
+
+#: src/parse_args.c:705
+msgid "use a helper program for password prompting"
+msgstr "使用助手程序进行密码提示"
+
+#: src/parse_args.c:708
+msgid "use specified BSD authentication type"
+msgstr "使用指定的 BSD 认证类型"
+
+#: src/parse_args.c:711
+msgid "run command in the background"
+msgstr "在后台运行命令"
+
+#: src/parse_args.c:713
+msgid "close all file descriptors >= num"
+msgstr "关闭所有 >= num 的文件描述符"
+
+#: src/parse_args.c:716
+msgid "run command with the specified BSD login class"
+msgstr "以指定的 BSD 登录类别运行命令"
+
+#: src/parse_args.c:719
+msgid "preserve user environment when running command"
+msgstr "在执行命令时保留用户环境"
+
+#: src/parse_args.c:721
+msgid "preserve specific environment variables"
+msgstr "保留特定的环境变量"
+
+#: src/parse_args.c:723
+msgid "edit files instead of running a command"
+msgstr "编辑文件而非执行命令"
+
+#: src/parse_args.c:725
+msgid "run command as the specified group name or ID"
+msgstr "以指定的用户组或 ID 执行命令"
+
+#: src/parse_args.c:727
+msgid "set HOME variable to target user's home dir"
+msgstr "将 HOME 变量设为目标用户的主目录。"
+
+#: src/parse_args.c:729
+msgid "display help message and exit"
+msgstr "显示帮助消息并退出"
+
+#: src/parse_args.c:731
+msgid "run command on host (if supported by plugin)"
+msgstr "在主机上运行命令(如果插件支持)"
+
+#: src/parse_args.c:733
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "以目标用户身份运行一个登录 shell;可同时指定一条命令"
+
+#: src/parse_args.c:735
+msgid "remove timestamp file completely"
+msgstr "完全移除时间戳文件"
+
+#: src/parse_args.c:737
+msgid "invalidate timestamp file"
+msgstr "无效的时间戳文件"
+
+#: src/parse_args.c:739
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "列出用户权限或检查某个特定命令;对于长格式,使用两次"
+
+#: src/parse_args.c:741
+msgid "non-interactive mode, no prompts are used"
+msgstr "非交互模式,不提示"
+
+#: src/parse_args.c:743
+msgid "preserve group vector instead of setting to target's"
+msgstr "保留组向量,而非设置为目标的组向量"
+
+#: src/parse_args.c:745
+msgid "use the specified password prompt"
+msgstr "使用指定的密码提示"
+
+#: src/parse_args.c:748
+msgid "create SELinux security context with specified role"
+msgstr "以指定的角色创建 SELinux 安全环境"
+
+#: src/parse_args.c:751
+msgid "read password from standard input"
+msgstr "从标准输入读取密码"
+
+#: src/parse_args.c:753
+msgid "run shell as the target user; a command may also be specified"
+msgstr "以目标用户运行 shell;可同时指定一条命令"
+
+#: src/parse_args.c:756
+msgid "create SELinux security context with specified type"
+msgstr "以指定的类型创建 SELinux 安全环境"
+
+#: src/parse_args.c:759
+msgid "terminate command after the specified time limit"
+msgstr "在达到指定时间限制后终止命令"
+
+#: src/parse_args.c:761
+msgid "in list mode, display privileges for user"
+msgstr "在列表模式中显示用户的权限"
+
+#: src/parse_args.c:763
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "以指定用户或 ID 运行命令(或编辑文件)"
+
+#: src/parse_args.c:765
+msgid "display version information and exit"
+msgstr "显示版本信息并退出"
+
+#: src/parse_args.c:767
+msgid "update user's timestamp without running a command"
+msgstr "更新用户的时间戳而不执行命令"
+
+#: src/parse_args.c:769
+msgid "stop processing command line arguments"
+msgstr "停止处理命令行参数"
+
+#: src/selinux.c:83
+msgid "unable to open audit system"
+msgstr "无法打开审查系统"
+
+#: src/selinux.c:93
+msgid "unable to send audit message"
+msgstr "无法发送审查消息"
+
+#: src/selinux.c:121
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "无法 fgetfilecon %s"
+
+#: src/selinux.c:126
+#, c-format
+msgid "%s changed labels"
+msgstr "%s 修改了标签"
+
+#: src/selinux.c:131
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "无法恢复 %s 的环境"
+
+#: src/selinux.c:172
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "无法打开 %s,将不重新标记终端"
+
+#: src/selinux.c:176 src/selinux.c:217 src/selinux.c:234
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s 不是字符型设备,将不重新标记终端"
+
+#: src/selinux.c:185
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "无法获取当前终端的环境,将不重新标记终端"
+
+#: src/selinux.c:192
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "未知的安全类“chr_file”,将不重新标记终端"
+
+#: src/selinux.c:197
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "无法获取新终端的环境,将不重新标记终端"
+
+#: src/selinux.c:204
+msgid "unable to set new tty context"
+msgstr "无法设置新终端的环境"
+
+#: src/selinux.c:278
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "您必须为 %s 类型指定一个角色"
+
+#: src/selinux.c:284
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "无法获取 %s 角色的默认类型"
+
+#: src/selinux.c:302
+#, c-format
+msgid "failed to set new role %s"
+msgstr "设置新角色 %s 失败"
+
+#: src/selinux.c:306
+#, c-format
+msgid "failed to set new type %s"
+msgstr "设置新类型 %s 失败"
+
+#: src/selinux.c:318
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s 不是有效的环境"
+
+#: src/selinux.c:353
+msgid "failed to get old_context"
+msgstr "无法获取 old_context"
+
+#: src/selinux.c:359
+msgid "unable to determine enforcing mode."
+msgstr "无法确定强制模式。"
+
+#: src/selinux.c:376
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "无法将终端环境设置为 %s"
+
+#: src/selinux.c:415
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "无法向 %s 设置 exec 环境"
+
+#: src/selinux.c:422
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "无法向 %s 设置键创建环境"
+
+#: src/sesh.c:77
+msgid "requires at least one argument"
+msgstr "要求至少有一个参数"
+
+#: src/sesh.c:106
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "无效的文件描述符数字:%s"
+
+#: src/sesh.c:120
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "无法以登录 shell 执行 %s"
+
+#: src/signal.c:88
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "无法保存 %d 信号的处理程序"
+
+#: src/solaris.c:81
+msgid "resource control limit has been reached"
+msgstr "达到了资源控制限制"
+
+#: src/solaris.c:84
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "用户“%s”不是项目“%s”的成员"
+
+#: src/solaris.c:88
+msgid "the invoking task is final"
+msgstr "调用的任务是最终的(final)"
+
+#: src/solaris.c:91
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "无法加入项目“%s”"
+
+#: src/solaris.c:96
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "不存在对应于项目“%s”的、接受默认绑定的资源池"
+
+#: src/solaris.c:100
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "指定的对应于项目“%s”的资源池不存在"
+
+#: src/solaris.c:104
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "无法为项目“%s”绑定到默认的资源池"
+
+#: src/solaris.c:110
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "对项目“%s”执行 setproject 失败"
+
+#: src/solaris.c:112
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "警告,对项目“%s”的资源控制分配失败"
+
+#: src/sudo.c:201
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo 版本 %s\n"
+
+#: src/sudo.c:203
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "当前选项:%s\n"
+
+#: src/sudo.c:211
+msgid "fatal error, unable to load plugins"
+msgstr "致命错误,无法加载插件"
+
+#: src/sudo.c:219
+msgid "unable to initialize policy plugin"
+msgstr "无法初始化策略插件"
+
+#: src/sudo.c:263
+msgid "plugin did not return a command to execute"
+msgstr "插件未返回能执行的命令"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "初始化 I/O 插件 %s 出错"
+
+#: src/sudo.c:302
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "异常的 sudo 模式 0x%x"
+
+#: src/sudo.c:535
+#, c-format
+msgid "you do not exist in the %s database"
+msgstr "%s 数据库中没有您"
+
+#: src/sudo.c:592
+msgid "unable to determine tty"
+msgstr "无法确定终端"
+
+#: src/sudo.c:880
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s 必须属于用户 ID %d(的用户)并且设置 setuid 位"
+
+#: src/sudo.c:883
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "有效用户 ID 不是 %d,%s 位于一个设置了“nosuid”选项的文件系统或没有 root 权限的 NFS 文件系统中吗?"
+
+#: src/sudo.c:889
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "有效用户 ID 不是 %d,sudo 属于 root 并设置了 setuid 位吗?"
+
+#: src/sudo.c:942
+msgid "unable to set supplementary group IDs"
+msgstr "无法设置补充组 ID"
+
+#: src/sudo.c:949
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "无法设置有效组 ID 来以组 ID %u 运行"
+
+#: src/sudo.c:955
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "无法设置组 ID 来以组 ID %u 运行"
+
+#: src/sudo.c:1012
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "异常的子进程终止条件:%d"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "“check_policy”方法中缺少策略插件 %s"
+
+#: src/sudo.c:1176
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "策略插件 %s 不支持列出权限"
+
+#: src/sudo.c:1193
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "策略插件 %s不支持 -v 选项"
+
+#: src/sudo.c:1208
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "策略插件 %s 不支持 -k/-K 选项"
+
+#: src/sudo_edit.c:219
+msgid "no writable temporary directory found"
+msgstr "未找到可写的临时目录"
+
+#: src/sudo_edit.c:286 src/sudo_edit.c:375
+msgid "unable to restore current working directory"
+msgstr "无法恢复当前工作目录"
+
+#: src/sudo_edit.c:592 src/sudo_edit.c:704
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s:不是常规文件"
+
+#: src/sudo_edit.c:599
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s:不允许编辑符号链接"
+
+#: src/sudo_edit.c:602
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s:不允许编辑可写目录中的文件"
+
+#: src/sudo_edit.c:635 src/sudo_edit.c:742
+#, c-format
+msgid "%s: short write"
+msgstr "%s:截短写入"
+
+#: src/sudo_edit.c:705
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s 并未修改"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:903
+#, c-format
+msgid "%s unchanged"
+msgstr "%s 已更改"
+
+#: src/sudo_edit.c:731 src/sudo_edit.c:753
+#, c-format
+msgid "unable to write to %s"
+msgstr "无法写入 %s"
+
+#: src/sudo_edit.c:732 src/sudo_edit.c:751 src/sudo_edit.c:754
+#: src/sudo_edit.c:928 src/sudo_edit.c:932
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "编辑会话的内容留在了 %s 中"
+
+#: src/sudo_edit.c:750
+msgid "unable to read temporary file"
+msgstr "无法读取临时文件"
+
+#: src/sudo_edit.c:833
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh:内部错误:路径数量异常"
+
+#: src/sudo_edit.c:835
+msgid "sesh: unable to create temporary files"
+msgstr "sesh:无法创建临时文件"
+
+#: src/sudo_edit.c:837 src/sudo_edit.c:935
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh:未知错误 %d"
+
+#: src/sudo_edit.c:927
+msgid "unable to copy temporary files back to their original location"
+msgstr "无法将临时文件复制回其原位置"
+
+#: src/sudo_edit.c:931
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "无法将某些临时文件复制回其原位置"
+
+#: src/sudo_edit.c:976
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "无法将用户 ID 切换到 root(%u)"
+
+#: src/sudo_edit.c:993
+msgid "plugin error: missing file list for sudoedit"
+msgstr "插件错误:缺少 sudoedit 的文件列表"
+
+#: src/sudo_edit.c:1034 src/sudo_edit.c:1047
+msgid "unable to read the clock"
+msgstr "无法读取时钟"
+
+#: src/tgetpass.c:101
+msgid "timed out reading password"
+msgstr "读密码超时"
+
+#: src/tgetpass.c:104
+msgid "no password was provided"
+msgstr "未提供密码"
+
+#: src/tgetpass.c:107
+msgid "unable to read password"
+msgstr "无法读取密码"
+
+#: src/tgetpass.c:141
+msgid "no tty present and no askpass program specified"
+msgstr "没有终端存在,且未指定 askpass 程序"
+
+#: src/tgetpass.c:150
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "没有指定 askpass 程序,尝试设置 SUDO_ASKPASS"
+
+#: src/tgetpass.c:307
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "无法将组 ID 设为 %u"
+
+#: src/tgetpass.c:311
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "无法将用户 ID 设为 %u"
+
+#: src/tgetpass.c:316
+#, c-format
+msgid "unable to run %s"
+msgstr "无法执行 %s"
+
+#: src/utmp.c:271
+msgid "unable to save stdin"
+msgstr "无法保存 stdin"
+
+#: src/utmp.c:273
+msgid "unable to dup2 stdin"
+msgstr "无法 dup2 stdin"
+
+#: src/utmp.c:276
+msgid "unable to restore stdin"
+msgstr "无法恢复 stdin"
+
+#~ msgid "unable to get group vector"
+#~ msgstr "无法获取组向量"
+
+#~ msgid "unknown uid %u: who are you?"
+#~ msgstr "未知的用户 ID %u:您是?"
+
+#~ msgid "error reading from signal pipe"
+#~ msgstr "从单管道读取出错"
+
+#~ msgid "error reading from pipe"
+#~ msgstr "从管道读取出错"
+
+#~ msgid "internal error, tried allocate zero bytes"
+#~ msgstr "内部错误,试图分配 0 个字节"
+
+#~ msgid "unable to set terminal to raw mode"
+#~ msgstr "无法将终端设为原始模式"
+
+#~ msgid "unable to open socket"
+#~ msgstr "无法打开套接字"
+
+#~ msgid "%s: %s: %s\n"
+#~ msgstr "%s:%s:%s\n"
+
+#~ msgid "%s: %s\n"
+#~ msgstr "%s:%s\n"
+
+#~ msgid "internal error, tried to emalloc2(0)"
+#~ msgstr "内部错误,试图 emalloc2(0)"
+
+#~ msgid "internal error, tried to ecalloc(0)"
+#~ msgstr "内部错误,试图 ecalloc(0)"
+
+#~ msgid "internal error, tried to erealloc(0)"
+#~ msgstr "内部错误,试图 erealloc(0)"
+
+#~ msgid "internal error, tried to erealloc3(0)"
+#~ msgstr "内部错误,试图 erealloc3(0)"
+
+#~ msgid "internal error, tried to erecalloc(0)"
+#~ msgstr "内部错误,试图 erecalloc(0)"
+
+#~ msgid "load_interfaces: overflow detected"
+#~ msgstr "load_interfaces:检测到溢出"
+
+#~ msgid "value out of range"
+#~ msgstr "值超出范围"
+
+#~ msgid "select failed"
+#~ msgstr "select 失败"
+
+#~ msgid "list user's available commands\n"
+#~ msgstr "列出用户能执行的命令\n"
+
+#~ msgid "run a shell as target user\n"
+#~ msgstr "以目标用户身份运行 shell\n"
+
+#~ msgid "when listing, list specified user's privileges\n"
+#~ msgstr "在列表时,列出指定用户的权限\n"
+
+#~ msgid ": "
+#~ msgstr ":"
+
+#~ msgid "internal error, emalloc2() overflow"
+#~ msgstr "内部错误,emalloc2() 溢出"
+
+#~ msgid "internal error, erealloc3() overflow"
+#~ msgstr "内部错误,erealloc3() 错误"
+
+#~ msgid "%s: at least one policy plugin must be specified"
+#~ msgstr "%s:至少要指定一个策略插件"
+
+#~ msgid "must be setuid root"
+#~ msgstr "必须为 setuid root"
+
+#~ msgid "the argument to -D must be between 1 and 9 inclusive"
+#~ msgstr "-D 选项的参数必须介于 1 到 9(含 1 和 9)"
diff --git a/po/zh_TW.mo b/po/zh_TW.mo
new file mode 100644
index 0000000..5a627f2
--- /dev/null
+++ b/po/zh_TW.mo
Binary files differ
diff --git a/po/zh_TW.po b/po/zh_TW.po
new file mode 100644
index 0000000..96a850f
--- /dev/null
+++ b/po/zh_TW.po
@@ -0,0 +1,886 @@
+# Chinese(Taiwan) translation for sudo.
+# This file is put in the public domain.
+#
+# 林博仁(Buo-ren, Lin) <Buo.Ren.Lin@gmail.com>, 2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.23b3\n"
+"Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n"
+"POT-Creation-Date: 2018-04-05 06:36-0600\n"
+"PO-Revision-Date: 2018-04-21 23:57+0800\n"
+"Last-Translator: 林博仁 <Buo.Ren.Lin@gmail.com>\n"
+"Language-Team: Chinese (traditional) <zh-l10n@linux.org.tw>\n"
+"Language: zh_TW\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Poedit 1.8.7.1\n"
+"X-Poedit-Basepath: .\n"
+"X-Poedit-SearchPath-0: .\n"
+
+#: lib/util/aix.c:85 lib/util/aix.c:172
+msgid "unable to open userdb"
+msgstr "無法開啟 userdb"
+
+#: lib/util/aix.c:227
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "無法為 %2$s 切換至「%1$s」registry"
+
+#: lib/util/aix.c:252
+msgid "unable to restore registry"
+msgstr "無法還原 registry"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/gidlist.c:74
+#: lib/util/sudo_conf.c:186 lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349
+#: lib/util/sudo_conf.c:553 src/conversation.c:75 src/exec_common.c:107
+#: src/exec_common.c:123 src/exec_common.c:132 src/exec_monitor.c:168
+#: src/exec_nopty.c:462 src/exec_pty.c:735 src/exec_pty.c:744
+#: src/exec_pty.c:815 src/exec_pty.c:942 src/load_plugins.c:52
+#: src/load_plugins.c:65 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:198 src/parse_args.c:273 src/parse_args.c:559
+#: src/parse_args.c:581 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:112 src/sudo.c:386 src/sudo.c:413 src/sudo.c:494 src/sudo.c:632
+#: src/sudo.c:692 src/sudo.c:702 src/sudo.c:722 src/sudo.c:741 src/sudo.c:750
+#: src/sudo.c:759 src/sudo.c:776 src/sudo.c:817 src/sudo.c:827 src/sudo.c:847
+#: src/sudo.c:1087 src/sudo.c:1108 src/sudo.c:1282 src/sudo.c:1380
+#: src/sudo_edit.c:250 src/sudo_edit.c:775 src/sudo_edit.c:872
+#: src/sudo_edit.c:986 src/sudo_edit.c:1006
+#, c-format
+msgid "%s: %s"
+msgstr "%s:%s"
+
+#: lib/util/aix.c:275 lib/util/gidlist.c:64 lib/util/sudo_conf.c:187
+#: lib/util/sudo_conf.c:272 lib/util/sudo_conf.c:349 lib/util/sudo_conf.c:553
+#: src/conversation.c:76 src/exec_common.c:107 src/exec_common.c:124
+#: src/exec_common.c:133 src/exec_pty.c:735 src/exec_pty.c:744
+#: src/exec_pty.c:815 src/load_plugins.c:215 src/load_plugins.c:238
+#: src/load_plugins.c:303 src/load_plugins.c:318 src/parse_args.c:177
+#: src/parse_args.c:199 src/parse_args.c:273 src/parse_args.c:559
+#: src/parse_args.c:581 src/preserve_fds.c:47 src/preserve_fds.c:130
+#: src/selinux.c:84 src/selinux.c:309 src/selinux.c:432 src/selinux.c:441
+#: src/sesh.c:112 src/sudo.c:386 src/sudo.c:413 src/sudo.c:494 src/sudo.c:632
+#: src/sudo.c:847 src/sudo.c:1087 src/sudo.c:1108 src/sudo.c:1282
+#: src/sudo.c:1380 src/sudo_edit.c:250 src/sudo_edit.c:775 src/sudo_edit.c:872
+#: src/sudo_edit.c:986 src/sudo_edit.c:1006
+msgid "unable to allocate memory"
+msgstr "無法配置記憶體"
+
+#: lib/util/strsignal.c:48
+msgid "Unknown signal"
+msgstr "未知的訊號"
+
+#: lib/util/strtoid.c:77 lib/util/strtoid.c:124 lib/util/strtoid.c:152
+#: lib/util/strtomode.c:49 lib/util/strtonum.c:58 lib/util/strtonum.c:176
+msgid "invalid value"
+msgstr "無效的數值"
+
+#: lib/util/strtoid.c:84 lib/util/strtoid.c:131 lib/util/strtoid.c:159
+#: lib/util/strtomode.c:55 lib/util/strtonum.c:61 lib/util/strtonum.c:188
+msgid "value too large"
+msgstr "數值太大了"
+
+#: lib/util/strtoid.c:86 lib/util/strtoid.c:137 lib/util/strtomode.c:55
+#: lib/util/strtonum.c:61 lib/util/strtonum.c:182
+msgid "value too small"
+msgstr "數值太小了"
+
+#: lib/util/sudo_conf.c:205
+#, c-format
+msgid "invalid Path value \"%s\" in %s, line %u"
+msgstr "於 %2$s 第 %3$u 行發現無效的 Path 值「%1$s」"
+
+#: lib/util/sudo_conf.c:371 lib/util/sudo_conf.c:424
+#, c-format
+msgid "invalid value for %s \"%s\" in %s, line %u"
+msgstr "於 %3$s 中第 %4$u 行發現用於 %1$s 的「%2$s」無效數值"
+
+#: lib/util/sudo_conf.c:392
+#, c-format
+msgid "unsupported group source \"%s\" in %s, line %u"
+msgstr "於「%2$s」第 %3$u 行發現不支援的「%1$s」 group source"
+
+#: lib/util/sudo_conf.c:408
+#, c-format
+msgid "invalid max groups \"%s\" in %s, line %u"
+msgstr "於 %2$s 第 %3$u 行發現無效的「%1$s」最大群組(max groups)"
+
+#: lib/util/sudo_conf.c:569
+#, c-format
+msgid "unable to stat %s"
+msgstr "無法取得 %s 檔案的資訊"
+
+#: lib/util/sudo_conf.c:572
+#, c-format
+msgid "%s is not a regular file"
+msgstr "%s 不是一個一般檔案"
+
+#: lib/util/sudo_conf.c:575
+#, c-format
+msgid "%s is owned by uid %u, should be %u"
+msgstr "%s 不應由 %u 使用者識別碼所擁有,應為 %u"
+
+#: lib/util/sudo_conf.c:579
+#, c-format
+msgid "%s is world writable"
+msgstr "%s 是全世界可寫的"
+
+#: lib/util/sudo_conf.c:582
+#, c-format
+msgid "%s is group writable"
+msgstr "%s 是群組可寫的"
+
+#: lib/util/sudo_conf.c:592 src/selinux.c:208 src/selinux.c:225 src/sudo.c:354
+#, c-format
+msgid "unable to open %s"
+msgstr "無法開啟 %s"
+
+#: src/exec.c:160
+#, c-format
+msgid "unknown login class %s"
+msgstr "未知的 %s 登入類別"
+
+#: src/exec.c:173
+msgid "unable to set user context"
+msgstr "無法設定使用者情境"
+
+#: src/exec.c:189
+msgid "unable to set process priority"
+msgstr "無法設定進程優先層級"
+
+#: src/exec.c:197
+#, c-format
+msgid "unable to change root to %s"
+msgstr "無法切換根目錄(chroot)至 %s"
+
+#: src/exec.c:210 src/exec.c:216 src/exec.c:223
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "無法變更至 runas uid (%u, %u)"
+
+#: src/exec.c:241
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "無法變更目錄至 %s"
+
+#: src/exec.c:340 src/exec_monitor.c:528 src/exec_monitor.c:530
+#: src/exec_nopty.c:520 src/exec_pty.c:483 src/exec_pty.c:1258
+#: src/exec_pty.c:1260 src/signal.c:143 src/signal.c:157
+#, c-format
+msgid "unable to set handler for signal %d"
+msgstr "無法設定用於 %d 訊號的處理程式"
+
+#: src/exec_common.c:166
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "無法自 PRIV_LIMIT 移除 PRIV_PROC_EXEC"
+
+#: src/exec_monitor.c:322
+msgid "error reading from socketpair"
+msgstr "自 socketpair 讀取資料時發生錯誤"
+
+#: src/exec_monitor.c:334
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "未預期的 backchannel 回應類型:%d"
+
+#: src/exec_monitor.c:425 src/exec_monitor.c:433 src/exec_monitor.c:441
+#: src/exec_monitor.c:448 src/exec_monitor.c:455 src/exec_monitor.c:462
+#: src/exec_monitor.c:469 src/exec_monitor.c:476 src/exec_monitor.c:483
+#: src/exec_monitor.c:490 src/exec_nopty.c:215 src/exec_nopty.c:224
+#: src/exec_nopty.c:231 src/exec_nopty.c:238 src/exec_nopty.c:245
+#: src/exec_nopty.c:252 src/exec_nopty.c:259 src/exec_nopty.c:266
+#: src/exec_nopty.c:273 src/exec_nopty.c:280 src/exec_nopty.c:287
+#: src/exec_nopty.c:294 src/exec_nopty.c:302 src/exec_pty.c:601
+#: src/exec_pty.c:606 src/exec_pty.c:703 src/exec_pty.c:710 src/exec_pty.c:820
+#: src/exec_pty.c:1099 src/exec_pty.c:1108 src/exec_pty.c:1115
+#: src/exec_pty.c:1122 src/exec_pty.c:1129 src/exec_pty.c:1136
+#: src/exec_pty.c:1143 src/exec_pty.c:1150 src/exec_pty.c:1157
+#: src/exec_pty.c:1164 src/exec_pty.c:1171 src/exec_pty.c:1527
+#: src/exec_pty.c:1537 src/exec_pty.c:1582 src/exec_pty.c:1589
+#: src/exec_pty.c:1616
+msgid "unable to add event to queue"
+msgstr "無法新增事件至隊列中"
+
+#: src/exec_monitor.c:542
+msgid "unable to set controlling tty"
+msgstr "無法設定 controlling tty"
+
+#: src/exec_monitor.c:550 src/exec_nopty.c:359 src/exec_pty.c:1337
+#: src/exec_pty.c:1358 src/exec_pty.c:1378 src/tgetpass.c:254
+msgid "unable to create pipe"
+msgstr "無法建立管線檔案"
+
+#: src/exec_monitor.c:555 src/exec_nopty.c:377 src/exec_pty.c:1416
+#: src/tgetpass.c:258
+msgid "unable to fork"
+msgstr "無法叉分(fork)出新進程(process)"
+
+#: src/exec_monitor.c:567 src/sesh.c:122 src/sudo.c:1146
+#, c-format
+msgid "unable to execute %s"
+msgstr "無法執行 %s"
+
+#: src/exec_monitor.c:650 src/exec_nopty.c:430
+msgid "unable to restore tty label"
+msgstr "無法還原 tty label"
+
+#: src/exec_nopty.c:353 src/exec_pty.c:1267
+msgid "policy plugin failed session initialization"
+msgstr "政策可插入元件 session 初始化失敗"
+
+#: src/exec_nopty.c:419 src/exec_pty.c:1485
+msgid "error in event loop"
+msgstr "在事件處理迴圈(event loop)中發生錯誤"
+
+#: src/exec_nopty.c:528 src/exec_pty.c:515 src/signal.c:105
+#, c-format
+msgid "unable to restore handler for signal %d"
+msgstr "無法還原用於%d訊號的處理程序"
+
+#: src/exec_pty.c:150
+msgid "unable to allocate pty"
+msgstr "無法配置 pty"
+
+#: src/exec_pty.c:1247
+msgid "unable to create sockets"
+msgstr "無法建立 socket 檔案"
+
+#: src/load_plugins.c:50 src/load_plugins.c:63 src/load_plugins.c:85
+#: src/load_plugins.c:115 src/load_plugins.c:123 src/load_plugins.c:129
+#: src/load_plugins.c:170 src/load_plugins.c:178 src/load_plugins.c:185
+#: src/load_plugins.c:191
+#, c-format
+msgid "error in %s, line %d while loading plugin \"%s\""
+msgstr "載入「%3$s」可插入元件時於「%1$s」第 %2$d 行發生錯誤"
+
+#: src/load_plugins.c:87
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s:%s"
+
+#: src/load_plugins.c:125
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s 必須由 %d 識別碼的使用者所擁有"
+
+#: src/load_plugins.c:131
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s 必須只能被其擁有者可寫"
+
+#: src/load_plugins.c:172
+#, c-format
+msgid "unable to load %s: %s"
+msgstr "無法載入 %s:%s"
+
+#: src/load_plugins.c:180
+#, c-format
+msgid "unable to find symbol \"%s\" in %s"
+msgstr "無法在 %s 中找到「%s」符號"
+
+#: src/load_plugins.c:187
+#, c-format
+msgid "unknown policy type %d found in %s"
+msgstr "在 %2$s 發現未知的 %1$d sudo 政策分類"
+
+#: src/load_plugins.c:193
+#, c-format
+msgid "incompatible plugin major version %d (expected %d) found in %s"
+msgstr "在 %3$s 中發現不相容的可插入元件主版本號 %1$d(預期要 %2$d)"
+
+#: src/load_plugins.c:202
+#, c-format
+msgid "ignoring policy plugin \"%s\" in %s, line %d"
+msgstr "無視 %2$s 中第 %3$d 行的「%1$s」Sudo 政策可插入元件"
+
+#: src/load_plugins.c:204
+msgid "only a single policy plugin may be specified"
+msgstr "只可以指定一個 Sudo 政策可插入元件"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "ignoring duplicate policy plugin \"%s\" in %s, line %d"
+msgstr "無視 %2$s 中 %3$d 行的重複「%1$s」 Sudo 政策可插入元件"
+
+#: src/load_plugins.c:228
+#, c-format
+msgid "ignoring duplicate I/O plugin \"%s\" in %s, line %d"
+msgstr "無視 %2$s 中第 %3$d 行的「%1$s」重複 I/O 可插入元件"
+
+#: src/load_plugins.c:331
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "%s 政策可插入元件沒有提供一個 check_policy 方法"
+
+#: src/net_ifs.c:172 src/net_ifs.c:189 src/net_ifs.c:334 src/sudo.c:489
+#, c-format
+msgid "internal error, %s overflow"
+msgstr "內部錯誤,%s 溢出(overflow)"
+
+#: src/parse_args.c:219
+#, c-format
+msgid "invalid environment variable name: %s"
+msgstr "無效的環境變數名:%s"
+
+#: src/parse_args.c:315
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "-C 命令列選項的引述必須是個大於等於3的數字"
+
+#: src/parse_args.c:499
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "你不能同時指定 -i 跟 -s 命令列選項"
+
+#: src/parse_args.c:503
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "你不能同時指定 -i 跟 -E 命令列選項"
+
+#: src/parse_args.c:513
+msgid "the `-E' option is not valid in edit mode"
+msgstr "-E 命令列選項在編輯模式中無效"
+
+#: src/parse_args.c:515
+msgid "you may not specify environment variables in edit mode"
+msgstr "你不能在編輯模式中指定環境變數"
+
+#: src/parse_args.c:523
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "-U 命令列選項只能跟 -l 選項一起使用"
+
+#: src/parse_args.c:527
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "-A 跟 -S 命令列選項不能同時被使用"
+
+#: src/parse_args.c:603
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit 在此平台上不被支援"
+
+#: src/parse_args.c:676
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "只有 -e、-h、-i、-K、-l、-s、-v 或是 -V 中的其中一個命令列選項可以被指定"
+
+#: src/parse_args.c:690
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - 以另一個使用者的身份編輯檔案\n"
+"\n"
+
+#: src/parse_args.c:692
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - 以另一個使用者的身份執行一個命令\n"
+"\n"
+
+#: src/parse_args.c:697
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"命令列選項:\n"
+
+#: src/parse_args.c:699
+msgid "use a helper program for password prompting"
+msgstr "使用助手程式來進行密碼提問"
+
+#: src/parse_args.c:702
+msgid "use specified BSD authentication type"
+msgstr "使用指定的 BSD 身份驗證類型"
+
+#: src/parse_args.c:705
+msgid "run command in the background"
+msgstr "在背景中執行命令"
+
+#: src/parse_args.c:707
+msgid "close all file descriptors >= num"
+msgstr "關閉所有 >= num 的檔案描述元(file descriptor)"
+
+#: src/parse_args.c:710
+msgid "run command with the specified BSD login class"
+msgstr "以指定的 BSD 登入類別(login class)執行命令"
+
+#: src/parse_args.c:713
+msgid "preserve user environment when running command"
+msgstr "在執行命令時保留使用者的環境"
+
+#: src/parse_args.c:715
+msgid "preserve specific environment variables"
+msgstr "保留指定的環境變數"
+
+#: src/parse_args.c:717
+msgid "edit files instead of running a command"
+msgstr "編輯檔案而非執行命令"
+
+#: src/parse_args.c:719
+msgid "run command as the specified group name or ID"
+msgstr "以指定的群組名稱或識別碼執行命令"
+
+#: src/parse_args.c:721
+msgid "set HOME variable to target user's home dir"
+msgstr "設定 HOME 環境變數為目標使用者的家目錄"
+
+#: src/parse_args.c:723
+msgid "display help message and exit"
+msgstr "顯示幫助訊息並離開"
+
+#: src/parse_args.c:725
+msgid "run command on host (if supported by plugin)"
+msgstr "在指定的主機上執行命令(如果被可插入元件支援的話)"
+
+#: src/parse_args.c:727
+msgid "run login shell as the target user; a command may also be specified"
+msgstr "以目標使用者的身份執行登入殼程式(login shell);亦可同時指定一個命令"
+
+#: src/parse_args.c:729
+msgid "remove timestamp file completely"
+msgstr "完全地移除時間戳記檔案"
+
+#: src/parse_args.c:731
+msgid "invalidate timestamp file"
+msgstr "使時戳檔案無效化"
+
+#: src/parse_args.c:733
+msgid "list user's privileges or check a specific command; use twice for longer format"
+msgstr "列出使用者的權限或是檢查一個特定的命令;指定兩次以用更長的格式輸出"
+
+#: src/parse_args.c:735
+msgid "non-interactive mode, no prompts are used"
+msgstr "非互動式模式,不使用任何提示文字"
+
+#: src/parse_args.c:737
+msgid "preserve group vector instead of setting to target's"
+msgstr "保留 group vector 而非設定為目標的"
+
+#: src/parse_args.c:739
+msgid "use the specified password prompt"
+msgstr "使用指定的密碼提示文字"
+
+#: src/parse_args.c:742
+msgid "create SELinux security context with specified role"
+msgstr "使用指定的角色(role)建立 SELinux 安全情境(security context)"
+
+#: src/parse_args.c:745
+msgid "read password from standard input"
+msgstr "自標準輸入裝置讀取密碼"
+
+#: src/parse_args.c:747
+msgid "run shell as the target user; a command may also be specified"
+msgstr "以目標使用者的身份執行殼程式(shell);一個命令亦可同時被指定"
+
+#: src/parse_args.c:750
+msgid "create SELinux security context with specified type"
+msgstr "使用指定的類別(type)建立 SELinux 安全情境(security context)"
+
+#: src/parse_args.c:753
+msgid "terminate command after the specified time limit"
+msgstr "在指定的時間限制後中止命令"
+
+#: src/parse_args.c:755
+msgid "in list mode, display privileges for user"
+msgstr "在清單模式中,顯示使用者的權限"
+
+#: src/parse_args.c:757
+msgid "run command (or edit file) as specified user name or ID"
+msgstr "以指定的使用者名稱或識別碼的身份執行命令(或編輯檔案)"
+
+#: src/parse_args.c:759
+msgid "display version information and exit"
+msgstr "顯示軟體版本資訊並離開"
+
+#: src/parse_args.c:761
+msgid "update user's timestamp without running a command"
+msgstr "更新使用者時間戳記而不執行命令"
+
+#: src/parse_args.c:763
+msgid "stop processing command line arguments"
+msgstr "停止處理命令列引數"
+
+#: src/selinux.c:78
+msgid "unable to open audit system"
+msgstr "無法開啟監控系統"
+
+#: src/selinux.c:88
+msgid "unable to send audit message"
+msgstr "無法傳送 audit message"
+
+#: src/selinux.c:116
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "無法對 %s 進行 fgetfilecon"
+
+#: src/selinux.c:121
+#, c-format
+msgid "%s changed labels"
+msgstr "%s 個變更的標籤(changed labels)"
+
+#: src/selinux.c:126
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "無法還原「%s」的 SELinux 情境(context)"
+
+#: src/selinux.c:167
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "無法開啟 %s,將不對 tty 進行 relabeling"
+
+#: src/selinux.c:171 src/selinux.c:212 src/selinux.c:229
+#, c-format
+msgid "%s is not a character device, not relabeling tty"
+msgstr "%s 不是一個字元裝置,將不會進行 tty relabeling"
+
+#: src/selinux.c:180
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "無法取得當前的 tty context,將不會進行 tty 的 relabeling"
+
+#: src/selinux.c:187
+msgid "unknown security class \"chr_file\", not relabeling tty"
+msgstr "未知的安全類別「chr_file」,不進行 tty relabeling"
+
+#: src/selinux.c:192
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "無法取得新的 tty context,將不會對 tty 進行 relabeling"
+
+#: src/selinux.c:199
+msgid "unable to set new tty context"
+msgstr "無法設定新的 tty 情境"
+
+#: src/selinux.c:273
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "你必須為 %s 類別指定一個角色(role)"
+
+#: src/selinux.c:279
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "無法取得 %s 角色(role)的預設分類"
+
+#: src/selinux.c:297
+#, c-format
+msgid "failed to set new role %s"
+msgstr "無法設定新的角色 %s "
+
+#: src/selinux.c:301
+#, c-format
+msgid "failed to set new type %s"
+msgstr "無法設定新的類別 %s "
+
+#: src/selinux.c:313
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s 不是一個有效的 SELinux 情境"
+
+#: src/selinux.c:348
+msgid "failed to get old_context"
+msgstr "無法取得 old_context"
+
+#: src/selinux.c:354
+msgid "unable to determine enforcing mode."
+msgstr "無法判斷 SELinux 行使模式。"
+
+#: src/selinux.c:371
+#, c-format
+msgid "unable to set tty context to %s"
+msgstr "無法設定 tty 情境為 %s"
+
+#: src/selinux.c:410
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "無法設定執行情境為 %s"
+
+#: src/selinux.c:417
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "無法設定 key creation context 為 %s"
+
+#: src/sesh.c:74
+msgid "requires at least one argument"
+msgstr "至少需要至少一個命令列引數"
+
+#: src/sesh.c:103
+#, c-format
+msgid "invalid file descriptor number: %s"
+msgstr "無效的檔案描述元:%s"
+
+#: src/sesh.c:117
+#, c-format
+msgid "unable to run %s as a login shell"
+msgstr "無法以登入殼程式(shell)執行 %s"
+
+#: src/signal.c:83
+#, c-format
+msgid "unable to save handler for signal %d"
+msgstr "無法保存用於 %d 訊號的處理程式"
+
+#: src/solaris.c:76
+msgid "resource control limit has been reached"
+msgstr "資源控制限制已經"
+
+#: src/solaris.c:79
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "「%s」使用者不是「%s」project的成員"
+
+#: src/solaris.c:83
+msgid "the invoking task is final"
+msgstr "觸發的工作(task)是 final 的"
+
+#: src/solaris.c:86
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "無法加入「%s」專案(project)"
+
+#: src/solaris.c:91
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "沒有存在接受預設繫結(default bindings)的資源池可以用在「%s」專案(project)上"
+
+#: src/solaris.c:95
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "「%s」專案(project)中並不存在指定的資源池"
+
+#: src/solaris.c:99
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "無法為「%s」專案(project)連結到預設的資源池"
+
+#: src/solaris.c:105
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "「%s」專案(project) setproject 失敗"
+
+#: src/solaris.c:107
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "警告:「%s」project 的 resource control assignment 失敗了"
+
+#: src/sudo.c:195
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo 第 %s 版\n"
+
+#: src/sudo.c:197
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "軟體設定選項: %s\n"
+
+#: src/sudo.c:205
+msgid "fatal error, unable to load plugins"
+msgstr "致命錯誤,無法載入可插入元件"
+
+#: src/sudo.c:213
+msgid "unable to initialize policy plugin"
+msgstr "無法初始化 Sudo 政策可插入元件"
+
+#: src/sudo.c:257
+msgid "plugin did not return a command to execute"
+msgstr "可插入元件沒有回傳要執行的命令"
+
+#: src/sudo.c:273
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "初始化「%s」I/O 可插入元件時發生錯誤"
+
+#: src/sudo.c:296
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "未預期的 0x%x sudo 模式"
+
+#: src/sudo.c:474
+msgid "unable to get group vector"
+msgstr "無法取得 group vector"
+
+#: src/sudo.c:552
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "未知的 %u 使用者識別碼:你是哪位啊?"
+
+#: src/sudo.c:608
+msgid "unable to determine tty"
+msgstr "無法判斷 tty"
+
+#: src/sudo.c:896
+#, c-format
+msgid "%s must be owned by uid %d and have the setuid bit set"
+msgstr "%s 必須由 %d 識別碼的使用者所擁有,且必須被設定 setuid 位元"
+
+#: src/sudo.c:899
+#, c-format
+msgid "effective uid is not %d, is %s on a file system with the 'nosuid' option set or an NFS file system without root privileges?"
+msgstr "有效使用者識別碼不是 %d,「%s」是在設定了「nosuid」掛載選項的檔案系統中或是在沒有 root 權限的 NFS 檔案系統中嗎?"
+
+#: src/sudo.c:905
+#, c-format
+msgid "effective uid is not %d, is sudo installed setuid root?"
+msgstr "有效使用者識別碼不是 %d,Sudo是被安裝為 setuid root 嗎?"
+
+#: src/sudo.c:958
+msgid "unable to set supplementary group IDs"
+msgstr "無法設定 supplementary group ids"
+
+#: src/sudo.c:965
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "無法設定有效群組識別碼為 %u runas gid"
+
+#: src/sudo.c:971
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "無法設定群組識別碼為 %u runas gid"
+
+#: src/sudo.c:1028
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "未預期之子進程中止狀況:%d"
+
+#: src/sudo.c:1174
+#, c-format
+msgid "policy plugin %s is missing the `check_policy' method"
+msgstr "%s 政策可插入元件缺少 check_policy 方法"
+
+#: src/sudo.c:1192
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "%s 政策可插入元件不支援列出權限"
+
+#: src/sudo.c:1209
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "%s 政策可插入元件不支援 -v 命令列選項"
+
+#: src/sudo.c:1224
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "%s 政策可插入元件不支援 -k/-K 命令列選項"
+
+#: src/sudo_edit.c:213
+msgid "no writable temporary directory found"
+msgstr "沒有找到可寫的暫存目錄"
+
+#: src/sudo_edit.c:280 src/sudo_edit.c:369
+msgid "unable to restore current working directory"
+msgstr "無法還原當前工作目錄"
+
+#: src/sudo_edit.c:578 src/sudo_edit.c:690
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s:不是個一般檔案"
+
+#: src/sudo_edit.c:585
+#, c-format
+msgid "%s: editing symbolic links is not permitted"
+msgstr "%s:編輯象徵性連結(symbolic link)是不被允許的"
+
+#: src/sudo_edit.c:588
+#, c-format
+msgid "%s: editing files in a writable directory is not permitted"
+msgstr "%s:在可寫的目錄中編輯檔案是不被允許的"
+
+#: src/sudo_edit.c:621 src/sudo_edit.c:728
+#, c-format
+msgid "%s: short write"
+msgstr "%s:過短的寫入"
+
+#: src/sudo_edit.c:691
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s 保持未更動的狀態"
+
+#: src/sudo_edit.c:704 src/sudo_edit.c:889
+#, c-format
+msgid "%s unchanged"
+msgstr "%s 未更動"
+
+#: src/sudo_edit.c:717 src/sudo_edit.c:739
+#, c-format
+msgid "unable to write to %s"
+msgstr "無法寫入「%s」"
+
+#: src/sudo_edit.c:718 src/sudo_edit.c:737 src/sudo_edit.c:740
+#: src/sudo_edit.c:914 src/sudo_edit.c:918
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "編輯階段的內容被留在 %s"
+
+#: src/sudo_edit.c:736
+msgid "unable to read temporary file"
+msgstr "無法讀取暫存檔案"
+
+#: src/sudo_edit.c:819
+msgid "sesh: internal error: odd number of paths"
+msgstr "sesh:內部錯誤:只有奇數個路徑"
+
+#: src/sudo_edit.c:821
+msgid "sesh: unable to create temporary files"
+msgstr "sesh:無法建立暫存檔案"
+
+#: src/sudo_edit.c:823 src/sudo_edit.c:921
+#, c-format
+msgid "sesh: unknown error %d"
+msgstr "sesh:未知 %d 號錯誤"
+
+#: src/sudo_edit.c:913
+msgid "unable to copy temporary files back to their original location"
+msgstr "無法複製暫時檔案回到它們原本的位置"
+
+#: src/sudo_edit.c:917
+msgid "unable to copy some of the temporary files back to their original location"
+msgstr "無法複製部份暫時檔案回到它們原本的位置"
+
+#: src/sudo_edit.c:962
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "無法將使用者識別碼變更為 root (%u)"
+
+#: src/sudo_edit.c:979
+msgid "plugin error: missing file list for sudoedit"
+msgstr "可插入元件錯誤:缺少可用於 sudoedit 的檔案清單"
+
+#: src/sudo_edit.c:1020 src/sudo_edit.c:1033
+msgid "unable to read the clock"
+msgstr "無法讀取時間"
+
+#: src/tgetpass.c:107
+msgid "no tty present and no askpass program specified"
+msgstr "沒有 tty 存在且沒有指定 askpass 程式"
+
+#: src/tgetpass.c:116
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "沒有指定 askpass 程式,嘗試設定 SUDO_ASKPASS 環境變數"
+
+#: src/tgetpass.c:269
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "無法設定群組識別碼為 %u"
+
+#: src/tgetpass.c:273
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "無法設定使用者識別碼為 %u"
+
+#: src/tgetpass.c:278
+#, c-format
+msgid "unable to run %s"
+msgstr "無法執行 %s"
+
+#: src/utmp.c:266
+msgid "unable to save stdin"
+msgstr "無法保存標準輸入裝置(stdin)"
+
+#: src/utmp.c:268
+msgid "unable to dup2 stdin"
+msgstr "無法對標準輸入裝置進行 dup2 操作"
+
+#: src/utmp.c:271
+msgid "unable to restore stdin"
+msgstr "無法還原標準輸入裝置(stdin)"
diff --git a/pp b/pp
new file mode 100755
index 0000000..7b54dfa
--- /dev/null
+++ b/pp
@@ -0,0 +1,8415 @@
+#!/bin/sh
+# Copyright 2018 One Identity, LLC. ALL RIGHTS RESERVED
+pp_revision="20180220"
+ # Copyright 2018 One Identity, LLC. ALL RIGHTS RESERVED.
+ #
+ # Redistribution and use in source and binary forms, with or without
+ # modification, are permitted provided that the following conditions
+ # are met:
+ #
+ # 1. Redistributions of source code must retain the above copyright
+ # notice, this list of conditions and the following disclaimer.
+ # 2. Redistributions in binary form must reproduce the above copyright
+ # notice, this list of conditions and the following disclaimer in the
+ # documentation and/or other materials provided with the distribution.
+ # 3. Neither the name of One Identity, LLC. nor the names of its
+ # contributors may be used to endorse or promote products derived from
+ # this software without specific prior written permission.
+ #
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ # Please see <http://rc.quest.com/topics/polypkg/> for more information
+
+pp_version="1.0.0.$pp_revision"
+pp_copyright="Copyright 2018, One Identity, LLC. ALL RIGHTS RESERVED."
+
+pp_opt_debug=false
+pp_opt_destdir="$DESTDIR"
+pp_opt_install_script=
+pp_opt_list=false
+pp_opt_no_clean=false
+pp_opt_no_package=false
+pp_opt_only_front=false
+pp_opt_platform=
+pp_opt_probe=false
+pp_opt_strip=false
+pp_opt_save_unstripped=false
+pp_opt_vas_platforms=false
+pp_opt_wrkdir="`pwd`/pp.work.$$"
+pp_opt_verbose=false
+pp_opt_version=false
+pp_opt_input="-"
+pp_opt_init_vars=""
+pp_opt_eval=
+
+test -n "$PP_NO_CLEAN" && pp_opt_no_clean=true
+test -n "$PP_DEBUG" && pp_opt_debug=true
+test -n "$PP_VERBOSE" && pp_opt_verbose=true
+
+pp_main_cleanup () {
+ pp_debug "main_cleanup"
+ pp_remove_later_now
+ if $pp_opt_no_clean || test x"$pp_platform" = x"unknown"; then
+ : no cleanup
+ else
+ pp_backend_${pp_platform}_cleanup
+ $pp_errors && pp_die "Errors during cleanup"
+ if test -d "$pp_wrkdir"; then
+ if $pp_opt_debug; then
+ pp_debug "not removing $pp_wrkdir"
+ else
+ pp_verbose rm -rf "$pp_wrkdir"
+ fi
+ fi
+ fi
+}
+
+pp_parseopts () {
+ typeset a n _var _val
+ while test $# -gt 0; do
+
+ # convert -[dilpv] to --long-options
+ case "$1" in
+ --?*=?*) n=`echo "$1" | sed -ne 's/^--\([^=]*\)=.*/\1/p'`
+ a=`echo "$1" | sed -ne 's/^--[^=]*=\(.*\)/\1/p'`
+ shift
+ set -- "--$n" "$a" "$@";;
+ --?*) : ;;
+
+ -d) shift; set -- "--debug" "$@";;
+ -d*) a=`echo "$1" | sed -ne 's/^-.//'`
+ shift; set -- "--debug" "$@";;
+
+ -i) shift; set -- "--install-script" "$@";;
+ -i*) a=`echo "$1" | sed -ne 's/^-.//'`
+ shift; set -- "--install-script" "$a" "$@";;
+
+ -l) shift; set -- "--list" "$@";;
+ -l*) a=`echo "$1" | sed -ne 's/^-.//'`
+ shift; set -- "--list" "$@";;
+
+ -p) shift; set -- "--platform" "$@";;
+ -p*) a=`echo "$1" | sed -ne 's/^-.//'`
+ shift; set -- "--platform" "$a" "$@";;
+
+ -v) shift; set -- "--verbose" "$@";;
+ -v*) a=`echo "$1" | sed -ne 's/^-.//'`
+ shift; set -- "--verbose" "$@";;
+
+ -\?) shift; set -- "--help" "$@";;
+ -\?*) a=`echo "$1" | sed -ne 's/^-.//'`
+ shift; set -- "--help" "$@";;
+ esac
+
+ case "$1" in
+ --destdir|--eval|--install-script|--platform|--wrkdir)
+ test $# -ge 2 || pp_error "missing argument to $1";;
+ esac
+
+ case "$1" in
+ --) shift;break;;
+ --debug) pp_opt_debug=true; shift;;
+ --destdir) pp_opt_destdir="$2"; shift;shift;;
+ --eval) pp_opt_eval="$2"; shift;shift;; # undoc
+ --install-script) pp_opt_install_script="$2"; shift;shift;;
+ --list) pp_opt_list=true; shift;;
+ --no-clean) pp_opt_no_clean=true; shift;;
+ --no-package) pp_opt_no_package=true; shift;;
+ --only-front) pp_opt_only_front=true; shift;;
+ --platform) pp_opt_platform="$2"; shift;shift;;
+ --probe) pp_opt_probe=true; shift;;
+ --strip) pp_opt_strip=true; shift;;
+ --save-unstripped) pp_opt_save_unstripped=true; shift;;
+ --wrkdir) pp_opt_wrkdir="$2"; shift;shift;;
+ --vas-platforms) pp_opt_vas_platforms=true; shift;;
+ --verbose) pp_opt_verbose=true; shift;;
+ --version) pp_opt_version=true; shift;;
+ --help) pp_errors=true; shift;;
+ -) break;;
+ -*) pp_error "unknown option $1"; shift;;
+ *) break;;
+ esac
+
+ done
+
+ pp_opt_input=-
+ if test $# -gt 0; then
+ pp_opt_input="$1"
+ shift
+ fi
+
+ #-- extra arguments of the form Foo=bar alter *global* vars
+ while test $# -gt 0; do
+ case "$1" in
+ -*) pp_error "unexpected option '$1'"
+ shift;;
+ *=*) _val="${1#*=}"
+ _var=${1%="$_val"}
+ _val=`echo "$_val"|sed -e 's/[$"\\]/\\&/g'`
+ pp_debug "setting $_var = \"$_val\""
+ pp_opt_init_vars="$pp_opt_init_vars$_var=\"$_val\";"
+ shift;;
+ *) pp_error "unexpected argument $1'"
+ shift;;
+ esac
+ done
+
+ test $# -gt 0 &&
+ pp_error "unknown argument $1"
+
+ if $pp_errors; then
+ cat <<. >&2
+polypkg $pp_version $pp_copyright
+usage: $0 [options] [input.pp] [var=value ...]
+ -d --debug -- write copious info to stderr
+ --destdir=path -- file root, defaults to \$DESTDIR
+ -? --help -- display this information
+ -i --install-script=path -- create an install helper script
+ -l --list -- write package filenames to stdout
+ --no-clean -- don't remove temporary files
+ --no-package -- do everything but create packages
+ --only-front -- only perform front-end actions
+ -p --platform=platform -- defaults to local platform
+ --probe -- print local system identifier, then exit
+ --strip -- strip debug symbols from binaries before
+ packaging (modifies files in destdir)
+ --save-unstripped -- save unstripped binaries to
+ \$name-\$version-unstripped.tar.gz
+ --wrkdir=path -- defaults to subdirectory of \$TMPDIR or /tmp
+ -v --verbose -- write info to stderr
+ --version -- display version and quit
+.
+ exit 1
+ fi
+}
+
+pp_drive () {
+ # initialise the front and back ends
+ pp_model_init
+ pp_frontend_init
+ $pp_opt_only_front || pp_backend_init
+
+ # run the front-end to generate the intermediate files
+ # set $pp_input_dir to be the 'include dir' if needed
+ pp_debug "calling frontend on $pp_opt_input"
+ case "$pp_opt_input" in
+ -) pp_input_dir=.
+ test -t 1<&0 &&
+ pp_warn "reading directives from standard input"
+ pp_frontend
+ ;;
+ */*) pp_input_dir=${pp_opt_input%/*}
+ pp_frontend <"$pp_opt_input"
+ ;;
+ *) pp_input_dir=.
+ pp_frontend <"$pp_opt_input"
+ ;;
+ esac
+
+ pp_files_ignore_others
+ pp_service_scan_groups
+
+ # some sanity checks after front-end processing
+ if test x"$pp_platform" != x"null"; then
+ pp_debug "sanity checks"
+ test -n "$pp_components" || pp_error "No components?"
+ pp_check_var_is_defined "name"
+ pp_check_var_is_defined "version"
+ pp_files_check_duplicates
+ pp_files_check_coverage
+ pp_die_if_errors "Errors during sanity checks"
+ fi
+
+ # stop now if we're only running the front
+ $pp_opt_only_front && return
+
+ if test x"$pp_opt_strip" = x"true"; then
+ pp_strip_binaries
+ fi
+
+ # run the back-end to generate the package
+ pp_debug "calling backend"
+ pp_backend
+ pp_die_if_errors "Errors during backend processing"
+
+ # copy the resulting package files to PP_PKGDESTDIR or .
+ for f in `pp_backend_names` -; do
+ test x"$f" = x"-" && continue
+ pp_debug "copying: $f to `pwd`"
+ if pp_verbose cp -r $pp_wrkdir/$f ${PP_PKGDESTDIR:-.}; then
+ echo "${PP_PKGDESTDIR:+$PP_PKGDESTDIR/}$f"
+ else
+ pp_error "$f: missing package"
+ fi
+ done
+ pp_die_if_errors "Errors during package copying"
+}
+
+pp_install_script () {
+ pp_debug "writing install script to $pp_opt_install_script"
+ rm -f $pp_opt_install_script
+ pp_backend_install_script > $pp_opt_install_script
+ pp_die_if_errors "Errors during package install script"
+ chmod +x $pp_opt_install_script
+}
+
+pp_main () {
+ # If PP_DEV_PATH is set, then jump to that script.
+ # (Useful when working on polypkg source that isn't installed)
+ if test -n "$PP_DEV_PATH" -a x"$PP_DEV_PATH" != x"$0"; then
+ pp_warn "switching from $0 to $PP_DEV_PATH ..."
+ exec "$PP_DEV_PATH" "$@" || exit 1
+ fi
+
+ pp_set_expand_converter_or_reexec "$@"
+ pp_parseopts "$@"
+
+ if $pp_opt_version; then
+ #-- print version and exit
+ echo "polypkg $pp_version"
+ exit 0
+ fi
+
+ pp_set_platform
+
+ trap 'pp_main_cleanup' 0
+
+ pp_wrkdir="$pp_opt_wrkdir"
+ pp_debug "pp_wrkdir = $pp_wrkdir"
+ rm -rf "$pp_wrkdir"
+ mkdir -p "$pp_wrkdir"
+
+ pp_destdir="$pp_opt_destdir"
+ pp_debug "pp_destdir = $pp_destdir"
+
+ if $pp_opt_probe; then
+ pp_backend_init
+ pp_backend_probe
+ elif $pp_opt_vas_platforms; then
+ pp_backend_init
+ pp_backend_vas_platforms
+ elif test -n "$pp_opt_eval"; then
+ #-- execute a shell command
+ eval "$pp_opt_eval" || exit
+ else
+ pp_drive
+ if test -n "$pp_opt_install_script"; then
+ pp_install_script
+ fi
+ fi
+
+ exit 0
+}
+
+
+pp_errors=false
+
+if test -n "$TERM" -a -t 1 && (tput op) >/dev/null 2>/dev/null; then
+ pp_col_redfg=`tput setf 4` 2>/dev/null
+ pp_col_bluefg=`tput setf 1` 2>/dev/null
+ pp_col_reset=`tput op` 2>/dev/null
+else
+ pp_col_redfg='['
+ pp_col_bluefg='['
+ pp_col_reset=']'
+fi
+
+pp__warn () {
+ if test x"" = x"$pp_lineno"; then
+ echo "$1 $2" >&2
+ else
+ echo "$1 line $pp_lineno: $2" >&2
+ fi
+}
+
+pp_warn () {
+ pp__warn "pp: ${pp_col_redfg}warning${pp_col_reset}" "$*"
+}
+
+pp_error () {
+ pp__warn "pp: ${pp_col_redfg}error${pp_col_reset}" "$*"
+ pp_errors=true
+}
+
+pp_die () {
+ pp_error "$@"
+ exit 1
+}
+
+pp_die_if_errors () {
+ $pp_errors && pp_die "$@"
+}
+
+pp_debug () {
+ $pp_opt_debug && echo "${pp_col_bluefg}debug${pp_col_reset} $*" >&2
+}
+
+pp_verbose () {
+ $pp_opt_verbose && echo "pp: ${pp_col_bluefg}info${pp_col_reset} $*" >&2
+ "$@";
+}
+
+pp_substitute () {
+ sed -e 's,%(\([^)]*\)),`\1`,g' \
+ -e 's,%{\([^}]*\)},${\1},g' \
+ -e 's,$,,' |
+ tr '' '\012' |
+ sed -e '/^[^]/s/["$`\\]/\\&/g' \
+ -e 's/^//' \
+ -e '1s/^/echo "/' \
+ -e '$s,$,",' \
+ -e 's,,"echo ",g' |
+ tr -d '\012' |
+ tr '' '\012'
+ echo
+}
+
+pp_incr () {
+ eval "$1=\`expr \$$1 + 1\`"
+}
+
+pp_decr () {
+ eval "$1=\`expr \$$1 - 1\`"
+}
+
+pp_check_var_is_defined () {
+ if eval test -z "\"\$$1\""; then
+ pp_error "\$$1: not set"
+ eval "$1=undefined"
+ fi
+}
+
+pp_contains () {
+ case " $1 " in
+ *" $2 "*) return 0;;
+ *) return 1;;
+ esac
+}
+
+pp_contains_all () {
+ typeset _s _c
+ _l="$1"; shift
+ for _w
+ do
+ pp_contains "$_l" "$_w" || return 1
+ done
+ return 0
+}
+
+pp_contains_any () {
+ typeset _s _c
+ _l="$1"; shift
+ for _w
+ do
+ pp_contains "$_l" "$_w" && return 0
+ done
+ return 1
+}
+
+pp_add_to_list () {
+ if eval test -z \"\$$1\"; then
+ eval $1='"$2"'
+ elif eval pp_contains '"$'$1'"' '"$2"'; then
+ : already there
+ else
+ eval $1='"$'$1' $2"'
+ fi
+}
+
+pp_unique () {
+ typeset result element
+ result=
+ for element
+ do
+ pp_add_to_list result $element
+ done
+ echo $result
+}
+
+pp_mode_strip_altaccess () {
+ case "$1" in
+ ??????????[+.])
+ echo `echo "$1" | cut -b -10`;;
+ *)
+ echo "$1";;
+ esac
+}
+
+pp_mode_from_ls () {
+ typeset umode gmode omode smode
+
+ set -- `pp_mode_strip_altaccess "$1"`
+
+ case "$1" in
+ ?--[-X]??????) umode=0;;
+ ?--[xs]??????) umode=1;;
+ ?-w[-X]??????) umode=2;;
+ ?-w[xs]??????) umode=3;;
+ ?r-[-X]??????) umode=4;;
+ ?r-[xs]??????) umode=5;;
+ ?rw[-X]??????) umode=6;;
+ ?rw[xs]??????) umode=7;;
+ *) pp_error "bad user mode $1";;
+ esac
+
+ case "$1" in
+ ????--[-S]???) gmode=0;;
+ ????--[xs]???) gmode=1;;
+ ????-w[-S]???) gmode=2;;
+ ????-w[xs]???) gmode=3;;
+ ????r-[-X]???) gmode=4;;
+ ????r-[xs]???) gmode=5;;
+ ????rw[-X]???) gmode=6;;
+ ????rw[xs]???) gmode=7;;
+ *) pp_error "bad group mode $1";;
+ esac
+
+ case "$1" in
+ ???????--[-T]) omode=0;;
+ ???????--[xt]) omode=1;;
+ ???????-w[-T]) omode=2;;
+ ???????-w[xt]) omode=3;;
+ ???????r-[-T]) omode=4;;
+ ???????r-[xt]) omode=5;;
+ ???????rw[-T]) omode=6;;
+ ???????rw[xt]) omode=7;;
+ *) pp_error "bad other mode $1";;
+ esac
+
+ case "$1" in
+ ???[-x]??[-x]??[-x]) smode=;;
+ ???[-x]??[-x]??[tT]) smode=1;;
+ ???[-x]??[Ss]??[-x]) smode=2;;
+ ???[-x]??[Ss]??[tT]) smode=3;;
+ ???[Ss]??[-x]??[-x]) smode=4;;
+ ???[Ss]??[-x]??[tT]) smode=5;;
+ ???[Ss]??[Ss]??[-x]) smode=6;;
+ ???[Ss]??[Ss]??[tT]) smode=7;;
+ *) pp_error "bad set-id mode $1";;
+ esac
+
+ echo "$smode$umode$gmode$omode"
+}
+
+pp_find_recurse () {
+ pp_debug "find: ${1#$pp_destdir}/"
+ for f in "$1"/.* "$1"/*; do
+ case "$f" in */.|*/..) continue;; esac # should never happen!
+ if test -d "$f" -o -f "$f" -o -h "$f"; then
+ if test -d "$f" -a ! -h "$f"; then
+ echo "${f#$pp_destdir}/"
+ pp_find_recurse "$f"
+ else
+ echo "${f#$pp_destdir}"
+ fi
+ fi
+ done
+}
+
+pp_prepend () {
+ #test -t && pp_warn "pp_prepend: stdin is a tty?"
+ if test -f $1; then
+ pp_debug "prepending to $1"
+ mv $1 $1._prepend
+ cat - $1._prepend >$1
+ rm -f $1._prepend
+ else
+ pp_debug "prepend: creating $1"
+ cat >$1
+ fi
+}
+
+pp_note_file_used() {
+ echo "$1" >> $pp_wrkdir/all.files
+}
+
+pp_create_dir_if_missing () {
+ case "$1" in
+ */) pp_error "pp_create_dir_if_missing: trailing / forbidden";;
+ "") return 0;;
+ *) if test ! -d "$pp_destdir$1"; then
+ pp_debug "fabricating directory $1/"
+ pp_create_dir_if_missing "${1%/*}"
+ mkdir "$pp_destdir$1" &&
+ pp_note_file_used "$1/"
+ pp_remove_later "$1" &&
+ chmod ${2:-755} "$pp_destdir$1"
+ fi;;
+ esac
+}
+
+pp_add_file_if_missing () {
+ typeset dir
+ #-- check that the file isn't already declared in the component
+ if test -s $pp_wrkdir/%files.${2:-run}; then
+ awk "\$6 == \"$1\" {exit 1}" < $pp_wrkdir/%files.${2:-run} || return 1
+ fi
+
+ pp_create_dir_if_missing "${1%/*}"
+ pp_debug "fabricating file $1"
+ echo "f ${3:-755} - - ${4:--} $1" >> $pp_wrkdir/%files.${2:-run}
+ pp_note_file_used "$1"
+ pp_remove_later "$1"
+ return 0
+}
+
+pp_add_transient_file () {
+ test -f "$pp_destdir$1" && pp_die "$pp_destdir$1: exists"
+ pp_create_dir_if_missing "${1%/*}"
+ pp_debug "transient file $1"
+ pp_note_file_used "$1"
+ pp_remove_later "$1"
+}
+
+pp_remove_later () {
+ {
+ echo "$1"
+ test -s $pp_wrkdir/pp_cleanup && cat $pp_wrkdir/pp_cleanup
+ } > $pp_wrkdir/pp_cleanup.new
+ mv $pp_wrkdir/pp_cleanup.new $pp_wrkdir/pp_cleanup
+}
+
+pp_ls_readlink () {
+ if test -h "$1"; then
+ ls -1ld "$1" | sed -ne 's,.* -> ,,p'
+ else
+ echo "$1: not a symbolic link" >&2
+ return 1
+ fi
+}
+
+pp_remove_later_now () {
+ typeset f
+ if test -s $pp_wrkdir/pp_cleanup; then
+ pp_debug "pp_remove_later_now"
+ while read f; do
+ pp_debug "removing $pp_destdir$f"
+ if test -d $pp_destdir$f; then
+ rmdir $pp_destdir$f
+ else
+ rm $pp_destdir$f
+ fi
+ done < $pp_wrkdir/pp_cleanup
+ rm $pp_wrkdir/pp_cleanup
+ fi
+}
+
+pp_readlink() {
+
+pp_debug "&& pp_readlink_fn=$pp_readlink_fn"
+
+ if test -n "$pp_readlink_fn"; then
+pp_debug "&& calling $pp_readlink_fn $*"
+ "$pp_readlink_fn" "$@"
+ else
+ readlink "$@"
+ fi
+}
+
+
+pp_install_script_common () {
+ cat <<-.
+
+ # Automatically generated for
+ # $name $version ($pp_platform)
+ # by PolyPackage $pp_version
+
+ usage () {
+ case "$1" in
+ "list-services")
+ echo "usage: \$0 list-services" ;;
+ "list-components")
+ echo "usage: \$0 list-components" ;;
+ "list-files")
+ echo "usage: \$0 list-files {cpt...|all}" ;;
+ "install")
+ echo "usage: \$0 install {cpt...|all}" ;;
+ "uninstall")
+ echo "usage: \$0 uninstall {cpt...|all}" ;;
+ "start")
+ echo "usage: \$0 start {svc...}" ;;
+ "stop")
+ echo "usage: \$0 stop {svc...}" ;;
+ "print-platform")
+ echo "usage: \$0 print-platform" ;;
+ *)
+ echo "usage: \$0 [-q] command [args]"
+ echo " list-services"
+ echo " list-components"
+ echo " list-files {cpt...|all}"
+ echo " install {cpt...|all}"
+ echo " uninstall {cpt...|all}"
+ echo " start {svc...}"
+ echo " stop {svc...}"
+ echo " print-platform"
+ ;;
+ esac >&2
+ exit 1
+ }
+
+ if test x"\$1" = x"-q"; then
+ shift
+ verbose () { "\$@"; }
+ verbosemsg () { : ; }
+ else
+ verbose () { echo "+ \$*"; "\$@"; }
+ verbosemsg () { echo "\$*"; }
+ fi
+.
+}
+
+
+pp_functions () {
+ typeset func deps allfuncs
+ allfuncs=
+ while test $# -gt 0; do
+ pp_add_to_list allfuncs "$1"
+ deps=`pp_backend_function "$1:depends"`
+ shift
+ set -- `pp_unique "$@" $deps`
+ done
+
+ for func in $allfuncs
+ do
+ pp_debug "generating function code for '$1'"
+ echo ""
+ echo "$func () {"
+ case "$func" in
+ pp_mkgroup|pp_mkuser|pp_havelib) echo <<.;;
+ if test \$# -lt 1; then
+ echo "$func: not enough arguments" >&2
+ return 1
+ fi
+.
+ esac
+ pp_backend_function "$func" || cat <<.
+ echo "$func: not implemented" >&2
+ return 1
+.
+ echo "}"
+ done
+}
+
+pp_function () {
+ pp_functions "$1"
+}
+
+pp_makevar () {
+ #-- convert all non alpha/digits to underscores
+ echo "$*" | tr -c '[a-z][A-Z][0-9]\012' '[_*]'
+}
+
+pp_getpwuid () {
+ awk -F: '$3 == uid { if (!found) print $1; found=1; } END { if (!found) exit 1; }' uid="$1" \
+ < /etc/passwd || pp_error "no local username for uid $1"
+}
+
+pp_getgrgid () {
+ awk -F: '$3 == gid { if (!found) print $1; found=1; } END { if (!found) exit 1; }' gid="$1" \
+ < /etc/group || pp_error "no local group for gid $1"
+}
+
+pp_backend_function_getopt () {
+ cat <<'..'
+pp_getopt () {
+ _pp_optstring="$1"; shift; eval `_pp_getopt "$_pp_optstring"`
+}
+_pp_getopt_meta=s,[\\\\\"\'\`\$\&\;\(\)\{\}\#\%\ \ ],\\\\\&,g
+_pp_protect () {
+ sed "$_pp_getopt_meta" <<. | tr '\012' ' '
+$*
+.
+}
+_pp_protect2 () {
+ sed "s,^..,,$pp_getopt_meta" <<. | tr '\012' ' '
+$*
+.
+}
+_pp_nonl () {
+ tr '\012' ' ' <<.
+$*
+.
+}
+_pp_getopt () {
+ _pp_nonl '_pp_nonl set --; while test $# -gt 0; do case "$1" in "--") shift; break;;'
+ sed 's/\([^: ]:*\)/<@<\1>@>/g;
+ s/<@<\(.\):>@>/"-\1") _pp_nonl -"\1"; _pp_protect "$2"; shift; shift;; "-\1"*) _pp_nonl -"\1"; _pp_protect2 "$1"; shift;;/g;s/<@<\(.\)>@>/ "-\1") _pp_nonl -"\1"; shift;; "-\1"*) _pp_nonl -"\1"; _pp_tmp="$1"; shift; set -- -`_pp_protect2 "$_pp_tmp"` "$@";;/g' <<.
+$1
+.
+ _pp_nonl '-*) echo "$1: unknown option">&2; return 1;; *) break;; esac; done; _pp_nonl --; while test $# -gt 0; do _pp_nonl "$1"; shift; done; echo'
+ echo
+}
+..
+}
+
+pp_copy_unstripped () {
+ typeset filedir realdir
+ filedir="`dirname ${1#$pp_destdir}`"
+ realdir="$pp_wrkdir/unstripped/$filedir"
+
+ mkdir -p "$realdir"
+ # Can't use hardlinks because `strip` modifies the original file in-place
+ cp "$1" "$realdir"
+}
+
+pp_package_stripped_binaries () {
+ (cd "$pp_wrkdir/unstripped" && tar -c .) \
+ | gzip > "$name-dbg-$version.tar.gz"
+ rm -rf "$pp_wrkdir/unstripped"
+}
+
+pp_strip_binaries () {
+ if test x"$pp_opt_save_unstripped" = x"true"; then
+ rm -rf "$pp_wrkdir/unstripped"
+ mkdir "$pp_wrkdir/unstripped"
+ fi
+
+ for f in `find "$pp_destdir" -type f`; do
+ if file "$f" | awk '{print $2}' | grep ^ELF >/dev/null 2>&1; then
+ if test x"$pp_opt_save_unstripped" = x"true"; then
+ if file "$f" | LC_MESSAGES=C grep 'not stripped' >/dev/null 2>&1; then
+ pp_debug "Saving unstripped binary $f"
+ pp_copy_unstripped "$f"
+ else
+ pp_debug "$f is already stripped; not saving a copy"
+ fi
+ fi
+ pp_debug "Stripping unnecessary symbols from $f"
+ strip "$f"
+ fi
+ done
+
+ if test x"$pp_opt_save_unstripped" = x"true"; then
+ pp_package_stripped_binaries
+ fi
+}
+
+pp_if_true=0
+pp_if_false=0
+
+pp_frontend_init () {
+ name=
+ version=
+ summary="no summary"
+ description="No description"
+ copyright="Copyright 2018 One Identity, LLC. ALL RIGHTS RESERVED."
+
+ #-- if the user supplied extra arguments on the command line
+ # then load them now.
+ pp_debug "pp_opt_init_vars=$pp_opt_init_vars"
+ test -n "$pp_opt_init_vars" && eval "$pp_opt_init_vars"
+}
+
+pp_is_qualifier () {
+ typeset ret
+
+ case "$1" in
+ "["*"]") ret=true;;
+ *) ret=false;;
+ esac
+ pp_debug "is_qualifier: $* -> $ret"
+ test $ret = true
+}
+
+pp_eval_qualifier () {
+ typeset ret
+
+ case "$1" in
+ "[!$pp_platform]"| \
+ "[!"*",$pp_platform]"| \
+ "[!$pp_platform,"*"]"| \
+ "[!"*",$pp_platform,"*"]") ret=false;;
+ "[!"*"]") ret=true;;
+ "[$pp_platform]"| \
+ "["*",$pp_platform]"| \
+ "[$pp_platform,"*"]"| \
+ "["*",$pp_platform,"*"]") ret=true;;
+ "["*"]") ret=false;;
+ *) pp_die "pp_eval_qualifier: bad qualifier '$1'"
+ esac
+ pp_debug "eval: $* -> $ret"
+ test true = $ret
+}
+
+pp_frontend_if () {
+ typeset ifcmd ifret
+ ifcmd="$1";
+ shift
+ case "$ifcmd" in
+ %if) if test 0 = $pp_if_false; then
+ case "$*" in
+ true |1) pp_incr pp_if_true;;
+ false|0) pp_incr pp_if_false;;
+ *)
+ ifret=true
+ if pp_is_qualifier "$*"; then
+ pp_eval_qualifier "$*" || ifret=false
+ else
+ eval test "$@" || ifret=false
+ pp_debug "evaluating test $* -> $ifret"
+ fi
+ pp_incr pp_if_$ifret
+ ;;
+ esac
+ else
+ pp_incr pp_if_false
+ fi;;
+ %else) test $# = 0 || pp_warn "ignoring argument to %else"
+ if test $pp_if_false -gt 1; then
+ : no change
+ elif test $pp_if_false = 1; then
+ pp_incr pp_if_true
+ pp_decr pp_if_false
+ elif test $pp_if_true = 0; then
+ pp_die "unmatched %else"
+ else
+ pp_incr pp_if_false
+ pp_decr pp_if_true
+ fi;;
+ %endif) test $# = 0 || pp_warn "ignoring argument to %endif"
+ if test $pp_if_false -gt 0; then
+ pp_decr pp_if_false
+ elif test $pp_if_true -gt 0; then
+ pp_decr pp_if_true
+ else
+ pp_die "unmatched %endif"
+ fi;;
+ *) pp_die "frontend_if: unknown cmd $ifcmd";;
+ esac
+}
+
+
+pp_frontend () {
+ typeset section newsection sed_word sed_ws line cpt svc
+ typeset section_enabled newsection_enabled s sed sed_candidate
+
+ section='%_initial'
+ newsection='%_initial'
+ section_enabled=:
+ newsection_enabled=:
+ sed_word="[a-zA-Z_][a-zA-Z_0-9]*"
+ sed_ws="[ ]"
+
+ #-- not all seds are created equal
+ sed=
+ for sed_candidate in ${PP_SED:-sed} /usr/xpg4/bin/sed; do
+ if echo 'foo' | $sed_candidate -ne '/^\(x\)*foo/p' | grep foo > /dev/null
+ then
+ sed="$sed_candidate"
+ break
+ fi
+ done
+ test -z "$sed" &&
+ pp_die "sed is broken on this system"
+
+ pp_lineno=0
+
+ #-- Note: this sed script should perform similar to pp_eval_qualifier()
+ $sed -e "/^#/s/.*//" \
+ -e "/^\\[!\\($sed_word,\\)*$pp_platform\\(,$sed_word\\)*\\]/s/.*//" \
+ -e "s/^\\[\\($sed_word,\\)*$pp_platform\\(,$sed_word\\)*\\]$sed_ws*//" \
+ -e "s/^\\[!\\($sed_word,\\)*$sed_word\\]$sed_ws*//" \
+ -e "/^\\[\\($sed_word,\\)*$sed_word\\]/s/.*//" \
+ -e "s/^%$sed_ws*/%/" \
+ -e "s/^$sed_ws/%\\\\&/" \
+ > $pp_wrkdir/frontend.tmp
+
+ #-- add an ignore section at the end to force section completion
+ echo '%ignore' >> $pp_wrkdir/frontend.tmp
+ echo >> $pp_wrkdir/frontend.tmp
+
+ exec 0<$pp_wrkdir/frontend.tmp
+ : > $pp_wrkdir/tmp
+ : > $pp_wrkdir/%fixup
+ while read -r line; do
+ #-- Convert leading double-% to single-%, or switch sections
+ pp_incr pp_lineno
+
+ pp_debug "line $pp_lineno: $line"
+ set -f
+ set -- $line
+ set +f
+ #pp_debug "line $pp_lineno: $*"
+
+ case "$line" in %*)
+ case "$1" in
+ %if|%else|%endif)
+ pp_debug "processing if directive $1"
+ pp_frontend_if "$@"
+ continue;;
+ esac
+ test 0 -ne $pp_if_false && continue # ignore lines %if'd out
+
+ case "$1" in
+ %set|%fixup|%ignore)
+ pp_debug "processing new section $1"
+ newsection="$1"; shift
+ newsection_enabled=:
+ if pp_is_qualifier "$1"; then
+ pp_eval_qualifier "$1" || newsection_enabled=false
+ shift
+ fi
+ test $# -eq 0 || pp_warn "ignoring extra arguments: $line"
+ continue;;
+ %pre|%post|%preun|%postup|%preup|%postun|%files|%depend|%check|%conflict)
+ pp_debug "processing new component section $*"
+ s="$1"; shift
+ if test $# -eq 0 || pp_is_qualifier "$1"; then
+ cpt=run
+ else
+ cpt="$1"
+ shift
+ fi
+ newsection="$s.$cpt"
+ newsection_enabled=:
+ if test $# -gt 0 && pp_is_qualifier "$1"; then
+ pp_eval_qualifier "$1" || newsection_enabled=false
+ shift
+ fi
+ test $# -eq 0 ||
+ pp_warn "ignoring extra arguments: $line"
+ case "$cpt" in
+ run|dbg|doc|dev)
+ $newsection_enabled && pp_add_component "$cpt";;
+ x-*) :;; # useful for discarding stuff
+ *) pp_error "unknown component: $1 $cpt";;
+ esac
+ continue;;
+ %pp)
+ newsection="%ignore"; shift
+ if test $# -gt 0; then
+ pp_set_api_version "$1"
+ shift
+ else
+ pp_error "%pp: missing version"
+ fi
+ test $# -gt 0 &&
+ pp_error "%pp: too many arguments"
+ continue;;
+ %service)
+ pp_debug "processing new service section $1 $2"
+ s="$1"; shift
+ if test $# -eq 0 || pp_is_qualifier "$1"; then
+ pp_error "$s: service name required"
+ svc=unknown
+ else
+ svc="$1"; shift
+ fi
+
+ newsection="$s.$svc"
+ newsection_enabled=:
+ if test $# -gt 0 && pp_is_qualifier "$1"; then
+ pp_eval_qualifier "$1" || newsection_enabled=false
+ shift
+ fi
+ test $# -eq 0 ||
+ pp_warn "ignoring extra arguments: $line"
+ $newsection_enabled && pp_add_service "$svc"
+ continue;;
+ %\\*)
+ pp_debug "removing leading %\\"
+ line="${line#??}"
+ pp_debug " result is <$line>"
+ set -f
+ set -- $line
+ set +f
+ ;;
+ %%*)
+ pp_debug "removing leading %"
+ line="${line#%}"
+ set -f
+ set -- $line
+ set +f
+ ;;
+ %*)
+ pp_error "unknown section $1"
+ newsection='%ignore'
+ newsection_enabled=:
+ continue;;
+ esac;;
+ esac
+
+ test 0 != $pp_if_false && continue # ignore lines %if'd out
+
+ pp_debug "section=$section (enabled=$section_enabled) newsection=$newsection (enabled=$newsection_enabled)"
+
+ #-- finish processing a previous section
+ if test x"$newsection" != x""; then
+ $section_enabled && case "$section" in
+ %ignore|%_initial)
+ pp_debug "leaving ignored section $section"
+ : ignore # guaranteed to be the last section
+ ;;
+ %set)
+ pp_debug "leaving $section: sourcing $pp_wrkdir/tmp"
+ $pp_opt_debug && cat $pp_wrkdir/tmp >&2
+ . $pp_wrkdir/tmp
+ : > $pp_wrkdir/tmp
+ ;;
+ %pre.*|%preun.*|%post.*|%postup.*|%preup.*|%postun.*|%depend.*|%check.*|%conflict.*|%service.*|%fixup)
+ pp_debug "leaving $section: substituting $pp_wrkdir/tmp"
+ # cat $pp_wrkdir/tmp >&2 # debugging
+ $pp_opt_debug && pp_substitute < $pp_wrkdir/tmp >&2
+ pp_substitute < $pp_wrkdir/tmp > $pp_wrkdir/tmp.sh
+ . $pp_wrkdir/tmp.sh >> $pp_wrkdir/$section ||
+ pp_error "shell error in $section"
+ rm -f $pp_wrkdir/tmp.sh
+ : > $pp_wrkdir/tmp
+ ;;
+ esac
+ section="$newsection"
+ section_enabled="$newsection_enabled"
+ newsection=
+ fi
+
+ #-- ignore section content that is disabled
+ $section_enabled || continue
+
+ #-- process some lines in-place
+ case "$section" in
+ %_initial)
+ case "$line" in "") continue;; esac # ignore non-section blanks
+ pp_die "Ignoring text before % section introducer";;
+ %set|%pre.*|%preun.*|%post.*|%postup.*|%preup.*|%postun.*|%check.*|%service.*|%fixup)
+ pp_debug "appending line to \$pp_wrkdir/tmp"
+ echo "$line" >> $pp_wrkdir/tmp
+ ;;
+ %files.*)
+ test $# -eq 0 && continue;
+ pp_files_expand "$@" >> $pp_wrkdir/$section
+ ;;
+ %depend.*)
+ pp_debug "Adding explicit dependency $@ to $cpt"
+ echo "$@" >> $pp_wrkdir/%depend.$cpt
+ ;;
+ %conflict.*)
+ pp_debug "Adding explicit conflict $@ to $cpt"
+ echo "$@" >> $pp_wrkdir/%conflict.$cpt
+ ;;
+ esac
+ done
+ exec <&-
+
+ if test $pp_if_true != 0 -o $pp_if_false != 0; then
+ pp_die "missing %endif at end of file"
+ fi
+
+ pp_lineno=
+
+ pp_debug " name = $name"
+ pp_debug " version = $version"
+ pp_debug " summary = $summary"
+ pp_debug " description = $description"
+ pp_debug " copyright = $copyright"
+ pp_debug ""
+ pp_debug "\$pp_components: $pp_components"
+ pp_debug "\$pp_services: $pp_services"
+}
+
+pp_set_api_version() {
+ case "$1" in
+ 1.0) : ;;
+ *) pp_error "This version of polypackage is too old";;
+ esac
+}
+
+pp_platform=
+
+pp_set_platform () {
+ if test -n "$pp_opt_platform"; then
+ pp_contains "$pp_platforms" "$pp_opt_platform" ||
+ pp_die "$pp_opt_platform: unknown platform"
+ pp_platform="$pp_opt_platform"
+ else
+ uname_s=`uname -s 2>/dev/null`
+ pp_platform=
+ for p in $pp_platforms; do
+ pp_debug "probing for platform $p"
+ if eval pp_backend_${p}_detect "$uname_s"; then
+ pp_platform="$p"
+ break;
+ fi
+ done
+ test -z "$pp_platform" &&
+ pp_die "cannot detect platform (supported: $pp_platforms)"
+ fi
+ pp_debug "pp_platform = $pp_platform"
+}
+
+pp_expand_path=
+
+pp_expand_test_usr_bin () {
+ awk '$1 == "/usr" || $2 == "/usr" {usr++}
+ $1 == "/bin" || $2 == "/bin" {bin++}
+ END { if (usr == 1 && bin == 1) exit(0); else exit(1); }'
+}
+
+pp_set_expand_converter_or_reexec () {
+ test -d /usr -a -d /bin ||
+ pp_die "missing /usr or /bin"
+ echo /usr /bin | pp_expand_test_usr_bin || pp_die "pp_expand_test_usr_bin?"
+ if (eval "echo /{usr,bin}" | pp_expand_test_usr_bin) 2>/dev/null; then
+ pp_expand_path=pp_expand_path_brace
+ elif (eval "echo /@(usr|bin)" | pp_expand_test_usr_bin) 2>/dev/null; then
+ pp_expand_path=pp_expand_path_at
+ else
+ test x"$pp_expand_rexec" != x"true" ||
+ pp_die "problem finding shell that can do brace expansion"
+ for shell in ksh ksh93 bash; do
+ if ($shell -c 'echo /{usr,bin}' |
+ pp_expand_test_usr_bin) 2>/dev/null ||
+ ($shell -c 'echo /@(usr|bin)' |
+ pp_expand_test_usr_bin) 2>/dev/null
+ then
+ pp_debug "switching to shell $shell"
+ pp_expand_rexec=true exec $shell "$0" "$@"
+ fi
+ done
+ pp_die "cannot find a shell that does brace expansion"
+ fi
+}
+
+pp_expand_path_brace () {
+ typeset f
+ eval "for f in $1; do echo \"\$f\"; done|sort -u"
+}
+
+pp_expand_path_at () {
+ typeset f
+ eval "for f in `
+ echo "$1" | sed -e 's/{/@(/g' -e 's/}/)/g' -e 's/,/|/g'
+ `; do echo \"\$f\"; done|sort -u"
+}
+
+pp_shlib_suffix='.so*'
+
+pp_model_init () {
+ #@ $pp_components: whitespace-delimited list of components seen in %files
+ pp_components=
+ #@ $pp_services: whitespace-delimited list of %service seen
+ pp_services=
+
+ rm -f $pp_wrkdir/%files.* \
+ $pp_wrkdir/%post.* \
+ $pp_wrkdir/%pre.* \
+ $pp_wrkdir/%preun.* \
+ $pp_wrkdir/%postup.* \
+ $pp_wrkdir/%postun.* \
+ $pp_wrkdir/%service.* \
+ $pp_wrkdir/%set \
+ $pp_wrkdir/%fixup
+}
+
+
+pp_have_component () {
+ pp_contains "$pp_components" "$1"
+}
+
+pp_have_all_components () {
+ pp_contains_all "$pp_components" "$@"
+}
+
+pp_add_component () {
+ pp_add_to_list 'pp_components' "$1"
+}
+
+pp_add_service () {
+ pp_add_to_list 'pp_services' "$1"
+}
+
+pp_service_init_vars () {
+ cmd=
+ pidfile=
+ stop_signal=15 # SIGTERM
+ user=root
+ group=
+ enable=yes # make it so the service starts on boot
+ optional=no # Whether installing this service is optional
+ pp_backend_init_svc_vars
+}
+
+pp_service_check_vars () {
+ test -n "$cmd" ||
+ pp_error "%service $1: cmd not defined"
+ case "$enable" in
+ yes|no) : ;;
+ *) pp_error "%service $1: \$enable must be set to yes or no";;
+ esac
+}
+
+pp_load_service_vars () {
+ pp_service_init_vars
+ . "$pp_wrkdir/%service.$1"
+ pp_service_check_vars "$1"
+}
+
+pp_files_expand () {
+ typeset _p _mode _group _owner _flags _path _optional _has_target _tree
+ typeset _target _file _tgt _m _o _g _f _type _lm _ll _lo _lg _ls _lx
+ typeset _ignore _a
+
+ test $# -eq 0 && return
+
+ pp_debug "pp_files_expand: path is: $1"
+
+ case "$1" in "#"*) return;; esac
+ _p="$1"; shift
+
+ pp_debug "pp_files_expand: other arguments: $*"
+
+ #-- the mode must be an octal number of at least three digits
+ _mode="="
+ _a=`eval echo \"$1\"`
+ case "$_a" in
+ *:*) :;;
+ -|=|[01234567][01234567][01234567]*) _mode="$_a"; shift;;
+ esac
+
+ #-- the owner:group field may have optional parts
+ _a=`eval echo \"$1\"`
+ case "$_a" in
+ *:*) _group=${_a#*:}; _owner=${_a%:*}; shift;;
+ =|-) _group=$_a; _owner=$_a; shift;;
+ *) _group=; _owner=;;
+ esac
+
+ #-- process the flags argument
+ _flags=
+ _target=
+ _optional=false
+ _has_target=false
+ _ignore=false
+ if test $# -gt 0; then
+ _a=`eval echo \"$1\"`
+ case ",$_a," in *,volatile,*) _flags="${_flags}v";; esac
+ case ",$_a," in *,optional,*) _optional=true;; esac
+ case ",$_a," in *,symlink,*) _has_target=true;; esac
+ case ",$_a," in *,ignore-others,*) _flags="${_flags}i";; esac
+ case ",$_a," in *,ignore,*) _ignore=true;; esac
+ shift
+ fi
+
+ #-- process the target argument
+ if $_has_target; then
+ test $# -ne 0 || pp_error "$_p: missing target"
+ _a=`eval echo \"$1\"`
+ _target="$_a"
+ shift
+ fi
+
+ pp_debug "pp_files_expand: $_mode|$_owner:$_group|$_flags|$_target|$*"
+
+ test $# -eq 0 || pp_error "$_p: too many arguments"
+
+ #-- process speciall suffixes
+ tree=
+ case "$_p" in
+ *"/**") _p="${_p%"/**"}"; tree="**";;
+ *".%so") _p="${_p%".%so"}$pp_shlib_suffix";;
+ esac
+
+ #-- expand the path using the shell glob
+ pp_debug "expanding .$_p ... with $pp_expand_path"
+ (cd ${pp_destdir} && $pp_expand_path ".$_p") > $pp_wrkdir/tmp.files.exp
+
+ #-- expand path/** by rewriting the glob output file
+ case "$tree" in
+ "") : ;;
+ "**")
+ pp_debug "expanding /** tree ..."
+ while read _path; do
+ _path="${_path#.}"
+ pp_find_recurse "$pp_destdir${_path%/}"
+ done < $pp_wrkdir/tmp.files.exp |
+ sort -u > $pp_wrkdir/tmp.files.exp2
+ mv $pp_wrkdir/tmp.files.exp2 $pp_wrkdir/tmp.files.exp
+ ;;
+ esac
+
+ while read _path; do
+ _path="${_path#.}"
+ _file="${pp_destdir}${_path}"
+ _tgt=
+ _m="$_mode"
+ _o="${_owner:--}"
+ _g="${_group:--}"
+ _f="$_flags"
+
+ case "$_path" in
+ /*) :;;
+ *) pp_warn "$_path: inserting leading /"
+ _path="/$_path";; # ensure leading /
+ esac
+
+ #-- sanity checks
+ case "$_path" in
+ */../*|*/..) pp_error "$_path: invalid .. in path";;
+ */./*|*/.) pp_warn "$_path: invalid component . in path";;
+ *//*) pp_warn "$_path: redundant / in path";;
+ esac
+
+ #-- set the type based on the real file's type
+ if $_ignore; then
+ _type=f _m=_ _o=_ _g=_
+ elif test -h "$_file"; then
+ case "$_path" in
+ */) pp_warn "$_path (symlink $_file): removing trailing /"
+ _path="${_path%/}"
+ ;;
+ esac
+ _type=s
+ if test x"$_target" != x"=" -a -n "$_target"; then
+ _tgt="$_target"
+pp_debug "symlink target is $_tgt"
+ else
+ _tgt=`pp_readlink "$_file"`;
+ test -z "$_tgt" && pp_error "can't readlink $_file"
+ case "$_tgt" in
+ ${pp_destdir}/*)
+ pp_warn "stripped \$destdir from symlink ($_path)"
+ _tgt="${_tgt#$pp_destdir}";;
+ esac
+ fi
+ _m=777
+ elif test -d "$_file"; then
+ #-- display a warning if the user forgot the trailing /
+ case "$_path" in
+ */) :;;
+ *) pp_warn "$_path (matching $_file): adding trailing /"
+ _path="$_path/";;
+ esac
+ _type=d
+ $_has_target && pp_error "$_file: not a symlink"
+ elif test -f "$_file"; then
+ case "$_path" in
+ */) pp_warn "$_path (matching $_file): removing trailing /"
+ _path="${_path%/}"
+ ;;
+ esac
+ _type=f
+ $_has_target && pp_error "$_file: not a symlink"
+ else
+ $_optional && continue
+ pp_error "$_file: missing"
+ _type=f
+ fi
+
+ #-- convert '=' shortcuts into mode/owner/group from ls
+ case ":$_m:$_o:$_g:" in *:=:*)
+ if LS_OPTIONS=--color=never /bin/ls -ld "$_file" \
+ > $pp_wrkdir/ls.tmp
+ then
+ read _lm _ll _lo _lg _ls _lx < $pp_wrkdir/ls.tmp
+ test x"$_m" = x"=" && _m=`pp_mode_from_ls "$_lm"`
+ test x"$_o" = x"=" && _o="$_lo"
+ test x"$_g" = x"=" && _g="$_lg"
+ else
+ pp_error "cannot read $_file"
+ test x"$_m" = x"=" && _m=-
+ test x"$_o" = x"=" && _o=-
+ test x"$_g" = x"=" && _g=-
+ fi
+ ;;
+ esac
+
+ test -n "$_f" || _f=-
+
+ #-- sanity checks
+ test -n "$_type" || pp_die "_type empty"
+ test -n "$_path" || pp_die "_path empty"
+ test -n "$_m" || pp_die "_m empty"
+ test -n "$_o" || pp_die "_o empty"
+ test -n "$_g" || pp_die "_g empty"
+
+ #-- setuid/gid files must be given an explicit owner/group (or =)
+ case "$_o:$_g:$_m" in
+ -:*:[4657][1357]??|-:*:[4657]?[1357]?|-:*:[4657]??[1357])
+ pp_error "$_path: setuid file ($_m) missing explicit owner";;
+ *:-:[2367][1357]??|*:-:[2367]?[1357]?|*:-:[2367]??[1357])
+ pp_error "$_path: setgid file ($_m) missing explicit group";;
+ esac
+
+ # convert numeric uids into usernames; only works for /etc/passwd
+ case "$_o" in [0-9]*) _o=`pp_getpwuid $_o`;; esac
+ case "$_g" in [0-9]*) _g=`pp_getgrgid $_g`;; esac
+
+ pp_debug "$_type $_m $_o $_g $_f $_path" $_tgt
+ $_ignore || echo "$_type $_m $_o $_g $_f $_path" $_tgt
+ pp_note_file_used "$_path"
+ case "$_f" in *i*) echo "$_path" >> $pp_wrkdir/ign.files;; esac
+ done < $pp_wrkdir/tmp.files.exp
+}
+
+pp_files_check_duplicates () {
+ typeset _path
+ if test -s $pp_wrkdir/all.files; then
+ sort < $pp_wrkdir/all.files | uniq -d > $pp_wrkdir/duplicate.files
+ if test -f $pp_wrkdir/ign.awk; then
+ # Remove ignored files
+ mv $pp_wrkdir/duplicate.files $pp_wrkdir/duplicate.files.ign
+ sed -e 's/^/_ _ _ _ _ /' < $pp_wrkdir/duplicate.files.ign |
+ awk -f $pp_wrkdir/ign.awk |
+ sed -e 's/^_ _ _ _ _ //' > $pp_wrkdir/duplicate.files
+ fi
+ while read _path; do
+ pp_warn "$_path: file declared more than once"
+ done <$pp_wrkdir/duplicate.files
+ fi
+}
+
+pp_files_check_coverage () {
+ pp_find_recurse "$pp_destdir" | sort > $pp_wrkdir/coverage.avail
+ if test -s $pp_wrkdir/all.files; then
+ sort -u < $pp_wrkdir/all.files
+ else
+ :
+ fi > $pp_wrkdir/coverage.used
+ join -v1 $pp_wrkdir/coverage.avail $pp_wrkdir/coverage.used \
+ > $pp_wrkdir/coverage.not-packaged
+ if test -s $pp_wrkdir/coverage.not-packaged; then
+ pp_warn "The following files/directories were found but not packaged:"
+ sed -e 's,^, ,' < $pp_wrkdir/coverage.not-packaged >&2
+ fi
+ join -v2 $pp_wrkdir/coverage.avail $pp_wrkdir/coverage.used \
+ > $pp_wrkdir/coverage.not-avail
+ if test -s $pp_wrkdir/coverage.not-avail; then
+ pp_warn "The following files/directories were named but not found:"
+ sed -e 's,^, ,' < $pp_wrkdir/coverage.not-avail >&2
+ fi
+}
+
+pp_files_ignore_others () {
+ typeset p f
+
+ test -s $pp_wrkdir/ign.files || return
+
+ #-- for each file in ign.files, we remove it from all the
+ # other %files.* lists, except where it has an i flag.
+ # rather than scan each list multiple times, we build
+ # an awk script
+
+ pp_debug "stripping ignore files"
+
+ while read p; do
+ echo '$6 == "'"$p"'" && $5 !~ /i/ { next }'
+ done < $pp_wrkdir/ign.files > $pp_wrkdir/ign.awk
+ echo '{ print }' >> $pp_wrkdir/ign.awk
+
+ $pp_opt_debug && cat $pp_wrkdir/ign.awk
+
+ for f in $pp_wrkdir/%files.*; do
+ mv $f $f.ign
+ awk -f $pp_wrkdir/ign.awk < $f.ign > $f || pp_error "awk"
+ done
+}
+
+pp_service_scan_groups () {
+ typeset svc
+
+ #-- scan for "group" commands, and build a list of groups
+ pp_service_groups=
+ if test -n "$pp_services"; then
+ for svc in $pp_services; do
+ group=
+ . $pp_wrkdir/%service.$svc
+ if test -n "$group"; then
+ pp_contains "$pp_services" "$group" && pp_error \
+ "%service $svc: group name $group in use by a service"
+ pp_add_to_list 'pp_service_groups' "$group"
+ echo "$svc" >> $pp_wrkdir/%svcgrp.$group
+ fi
+ done
+ fi
+}
+
+pp_service_get_svc_group () {
+ (tr '\012' ' ' < $pp_wrkdir/%svcgrp.$1 ; echo) | sed -e 's/ $//'
+}
+
+for _sufx in _init '' _names _cleanup _install_script \
+ _init_svc_vars _function _probe _vas_platforms
+do
+ eval "pp_backend$_sufx () { pp_debug pp_backend$_sufx; pp_backend_\${pp_platform}$_sufx \"\$@\"; }"
+done
+
+
+pp_platforms="$pp_platforms aix"
+
+pp_backend_aix_detect () {
+ test x"$1" = x"AIX"
+}
+
+pp_backend_aix_init () {
+ pp_aix_detect_arch
+ pp_aix_detect_os
+
+ pp_aix_bosboot= # components that need bosboot
+ pp_aix_lang=en_US
+ pp_aix_copyright=
+ pp_aix_start_services_after_install=false
+ pp_aix_init_services_after_install=true
+
+ pp_aix_sudo=sudo # AIX package tools must run as root
+
+ case "$pp_aix_os" in
+ *) pp_readlink_fn=pp_ls_readlink;; # XXX
+ esac
+
+ pp_aix_abis_seen=
+}
+
+pp_aix_detect_arch () {
+ pp_aix_arch_p=`uname -p 2>/dev/null`
+ case "$pp_aix_arch_p" in
+ "") pp_debug "can't get processor type from uname -p"
+ pp_aix_arch_p=powerpc
+ pp_aix_arch=R;; # guess (lsattr -l proc0 ??)
+ powerpc) pp_aix_arch=R;;
+ *) pp_aix_arch_p=intel
+ pp_aix_arch=I;; # XXX? verify
+ esac
+
+ case "`/usr/sbin/lsattr -El proc0 -a type -F value`" in
+ PowerPC_POWER*) pp_aix_arch_std=ppc64;;
+ PowerPC*) pp_aix_arch_std=ppc;;
+ *) pp_aix_arch_std=unknown;;
+ esac
+}
+
+pp_aix_detect_os () {
+ typeset r v
+
+ r=`uname -r`
+ v=`uname -v`
+ pp_aix_os=aix$v$r
+}
+
+pp_aix_version_fix () {
+ typeset v
+ v=`echo $1 | sed 's/[-+]/./' | tr -c -d '[0-9].\012' | awk -F"." '{ printf "%d.%d.%d.%.4s\n", $1, $2, $3, $4 }' | sed 's/[.]*$//g'`
+ if test x"$v" != x"$1"; then
+ pp_warn "stripped version '$1' to '$v'"
+ fi
+ case $v in
+ ""|*..*|.*|*.) pp_error "malformed '$1'"
+ echo "0.0.0.0";;
+ *.*.*.*.*)
+ # 5 components are only valid for fileset updates, not base
+ # filesets (full packages). We trim 5+ components down to 4.
+ pp_warn "version '$1' has too many dots for AIX, truncating"
+ echo "$v" | cut -d. -f1-4;;
+ *.*.*.*) echo "$v";;
+ *.*.*) echo "$v.0";;
+ *.*) echo "$v.0.0";;
+ *) echo "$v.0.0.0";;
+ esac
+}
+
+pp_aix_select () {
+ case "$1" in
+ -user) op="";;
+ -root) op="!";;
+ *) pp_die "pp_aix_select: bad argument";;
+ esac
+ #pp_debug awk '$5 '$op' /^\/(usr|opt)(\/|$)/ { print; }'
+ #awk '$5 '$op' /^\/(usr|opt)(\/|$)/ { print; }'
+ awk $op'($6 ~ /^\/usr\// || $6 ~ /^\/opt\//) { print; }'
+}
+
+pp_aix_copy_root () {
+ typeset t m o g f p st target
+ while read t m o g f p st; do
+ case "$t" in
+ d) pp_create_dir_if_missing "$1${p%/}";;
+ f) pp_add_transient_file "$1$p"
+ pp_verbose ln "$pp_destdir$p" "$pp_destdir$1$p" ||
+ pp_error "can't link $p into $1";;
+ *) pp_warn "pp_aix_copy_root: filetype $t not handled";;
+ esac
+ done
+}
+
+
+pp_aix_size () {
+ typeset prefix t m o g f p st
+
+ prefix="$1"
+ while read t m o g f p st; do
+ case "$t" in f) du -a "$pp_destdir$p";; esac
+ done | sed -e 's!/[^/]*$!!' | sort +1 |
+ awk '{ if ($2 != d)
+ { if (sz) print d,sz;
+ d=$2; sz=0 }
+ sz += $1; }
+ END { if (sz) print d,sz }' |
+ sed -n -e "s!^$pp_destdir!$prefix!p"
+}
+
+pp_aix_list () {
+ awk '{ print "." pfx $6; }' pfx="$1"
+}
+
+pp_aix_make_liblpp () {
+ typeset out dn fl f
+
+ out="$1"; shift
+ dn=`dirname "$2"`
+ fl=
+ for f
+ do
+ case "$f" in "$dn/"*) fl="$fl `basename $f`" ;;
+ *) pp_die "liblpp name $f not in $dn/";; esac
+ done
+ (cd "$dn" && pp_verbose ar -c -g -r "$out" $fl) || pp_error "ar error"
+}
+
+pp_aix_make_script () {
+ rm -f "$1"
+ echo "#!/bin/sh" > "$1"
+ cat >> "$1"
+ echo "exit 0" >> "$1"
+ chmod +x "$1"
+}
+
+pp_aix_inventory () {
+ typeset fileset t m o g f p st type
+
+ fileset="$1"
+ while read t m o g f p st; do
+ case "$p" in *:*) pp_error "path $p contains colon";; esac
+ echo "$p:"
+ case "$t" in
+ f) type=FILE; defm=644 ;;
+ s) type=SYMLINK; defm=777 ;;
+ d) type=DIRECTORY; defm=755 ;;
+ esac
+ echo " type = $type"
+ echo " class = inventory,apply,$fileset"
+ if test x"$m" = x"-"; then m="$defm"; fi
+ if test x"$o" = x"-"; then o="root"; fi
+ if test x"$g" = x"-"; then g="system"; fi
+ echo " owner = $o"
+ echo " group = $g"
+
+ case "$m" in ????)
+ m=`echo $m|sed -e 's/^1/TCB,/' \
+ -e 's/^[23]/TCB,SGID,/' \
+ -e 's/^[45]/TCB,SUID,/' \
+ -e 's/^[67]/TCB,SUID,SGID,/'`;; # vtx bit ignored
+ esac
+ echo " mode = $m"
+ case "$t" in
+ f) if test ! -f "$pp_destdir$p"; then
+ pp_error "$p: missing file"
+ fi
+ case "$flags" in
+ *v*)
+ echo " size = VOLATILE"
+ echo " checksum = VOLATILE"
+ ;;
+ *)
+ if test -r "$pp_destdir$p"; then
+ echo " size = $size"
+ pp_verbose sum -r < "$pp_destdir$p" |
+ sed -e 's/.*/ checksum = "&"/'
+ fi
+ ;;
+ esac;;
+ s)
+ echo " target = $st"
+ ;;
+ esac
+
+ #-- Record ABI types seen
+ case "$t" in
+ f) if test -r "$pp_destdir$p"; then
+ case "`file "$pp_destdir$p"`" in
+ *"executable (RISC System/6000)"*) abi=ppc;;
+ *"64-bit XCOFF executable"*) abi=ppc64;;
+ *) abi=;;
+ esac
+ if test -n "$abi"; then
+ pp_add_to_list pp_aix_abis_seen $abi
+ fi
+ fi;;
+ esac
+
+ done
+}
+
+pp_aix_depend ()
+{
+ if test -s "$1"; then
+ pp_warn "aix dependencies not implemented"
+ fi
+}
+
+pp_aix_add_service () {
+ typeset svc cmd_cmd cmd_arg f
+ svc="$1"
+
+ pp_load_service_vars $svc
+
+ set -- $cmd
+ cmd_cmd="$1"; shift
+ cmd_arg="${pp_aix_mkssys_cmd_args:-$*}";
+
+ case "$stop_signal" in
+ HUP) stop_signal=1;;
+ INT) stop_signal=2;;
+ QUIT) stop_signal=3;;
+ KILL) stop_signal=9;;
+ TERM) stop_signal=15;;
+ USR1) stop_signal=30;;
+ USR2) stop_signal=31;;
+ "")
+ pp_error "%service $svc: stop_signal not set";;
+ [a-zA-Z]*)
+ pp_error "%service $svc: bad stop_signal ($stop_signal)";;
+ esac
+
+ test -z "$pidfile" || pp_error "aix requires empty pidfile (non daemon)"
+
+ pp_add_component run
+ if test "$user" = "root"; then
+ uid=0
+ else
+ uid="\"\`/usr/bin/id -u $user\`\""
+ fi
+
+
+ #-- add command text to create/remove the service
+ cat <<-. >> $pp_wrkdir/%post.$svc
+svc=$svc
+uid=0
+cmd_cmd="$cmd_cmd"
+cmd_arg="$cmd_arg"
+stop_signal=$stop_signal
+force_signal=9
+srcgroup="$pp_aix_mkssys_group"
+instances_allowed=${pp_aix_mkssys_instances_allowed:--Q}
+
+lssrc -s \$svc > /dev/null 2>&1
+if [ \$? -eq 0 ]; then
+ lssrc -s \$svc | grep "active" > /dev/null 2>&1
+ if [ \$? -eq 0 ]; then
+ stopsrc -s \$svc > /dev/null 2>&1
+ fi
+ rmsys -s \$svc > /dev/null 2>&1
+fi
+
+mkssys -s \$svc -u \$uid -p "\$cmd_cmd" \${cmd_arg:+-a "\$cmd_arg"} -S -n \$stop_signal -f 9 ${pp_aix_mkssys_args} \${srcgroup:+-G \$srcgroup} \$instances_allowed
+.
+
+ #-- add code to start the service on reboot
+ ${pp_aix_init_services_after_install} &&
+ cat <<-. >> $pp_wrkdir/%post.$svc
+id=\`echo "\$svc" | cut -c1-14\`
+mkitab "\$id:2:once:/usr/bin/startsrc -s \$svc" > /dev/null 2>&1
+.
+
+ ${pp_aix_start_services_after_install} &&
+ cat <<-. >> $pp_wrkdir/%post.$svc
+startsrc -s \$svc
+.
+
+if [ -f "$pp_wrkdir/%post.run" ];then
+ cat $pp_wrkdir/%post.run >> $pp_wrkdir/%post.$svc
+fi
+mv $pp_wrkdir/%post.$svc $pp_wrkdir/%post.run
+
+
+ ${pp_aix_init_services_after_install} &&
+ pp_prepend $pp_wrkdir/%preun.$svc <<-.
+rmitab `echo "$svc" | cut -c1-14` > /dev/null 2>&1
+.
+ pp_prepend $pp_wrkdir/%preun.$svc <<-.
+stopsrc -s $svc >/dev/null 2>&1
+rmssys -s $svc
+.
+
+if [ -f "$pp_wrkdir/%preun.run" ];then
+ cat $pp_wrkdir/%preun.run >> $pp_wrkdir/%preun.$svc
+fi
+mv $pp_wrkdir/%preun.$svc $pp_wrkdir/%preun.run
+}
+
+pp_backend_aix () {
+ typeset briefex instuser instroot svc cmp outbff
+ typeset user_wrkdir root_wrkdir
+ typeset user_files root_files
+
+ test -n "$pp_destdir" ||
+ pp_error "AIX backend requires the '--destdir' option"
+
+ instuser="/usr/lpp/$name"
+ instroot="$instuser/inst_root"
+ pp_aix_bff_name=${pp_aix_bff_name:-$name}
+
+ # Here is the component mapping:
+ # run -> $pp_aix_bff_name.rte ('Run time environment')
+ # doc -> $pp_aix_bff_name.doc (non-standard)
+ # dev -> $pp_aix_bff_name.adt ('Application developer toolkit')
+ # dbg -> $pp_aix_bff_name.diag ('Diagnostics')
+
+ test `echo "$summary" | wc -c ` -gt 40 && pp_error "\$summary too long"
+
+ user_wrkdir=$pp_wrkdir/u
+ root_wrkdir=$pp_wrkdir/r
+ pp_verbose rm -rf $user_wrkdir $root_wrkdir
+ pp_verbose mkdir -p $user_wrkdir $root_wrkdir
+
+ for svc in $pp_services .; do
+ test . = "$svc" && continue
+ pp_aix_add_service $svc
+ done
+
+ {
+ echo "4 $pp_aix_arch I $name {"
+
+ for cmp in $pp_components; do
+ case "$cmp" in
+ run) ex=rte briefex="runtime";;
+ doc) ex=doc briefex="documentation";;
+ dev) ex=adt briefex="developer toolkit";;
+ dbg) ex=diag briefex="diagnostics";;
+ esac
+
+ user_files=$pp_wrkdir/%files.$cmp.u
+ root_files=$pp_wrkdir/%files.$cmp.r
+
+ pp_aix_select -user < $pp_wrkdir/%files.$cmp > $user_files
+ pp_aix_select -root < $pp_wrkdir/%files.$cmp > $root_files
+
+ # Default to USR only unless there are root files,
+ # or a post/pre/check script associated
+ content=U
+ if test -s $root_files \
+ -o -s $pp_wrkdir/%pre.$cmp \
+ -o -s $pp_wrkdir/%post.$cmp \
+ -o -s $pp_wrkdir/%preun.$cmp \
+ -o -s $pp_wrkdir/%postun.$cmp \
+ -o -s $pp_wrkdir/%check.$cmp
+ then
+ content=B
+ fi
+
+ if $pp_opt_debug; then
+ echo "$cmp USER %files:"
+ cat $user_files
+ echo "$cmp ROOT %files:"
+ cat $root_files
+ fi >&2
+
+ bosboot=N; pp_contains_any "$pp_aix_bosboot" $cmp && bosboot=b
+
+ echo $pp_aix_bff_name.$ex \
+ `[ $pp_aix_version ] && pp_aix_version_fix $pp_aix_version || pp_aix_version_fix "$version"` \
+ 1 $bosboot $content \
+ $pp_aix_lang "$summary $briefex"
+ echo "["
+
+ pp_aix_depend $pp_wrkdir/%depend.$cmp
+
+ echo "%"
+
+ # generate per-directory size information
+ pp_aix_size < $user_files
+ pp_aix_size $instroot < $root_files
+
+ pp_aix_list < $user_files > $user_wrkdir/$pp_aix_bff_name.$ex.al
+ pp_aix_list $instroot < $root_files >> $user_wrkdir/$pp_aix_bff_name.$ex.al
+ pp_aix_list < $root_files > $root_wrkdir/$pp_aix_bff_name.$ex.al
+
+ if $pp_opt_debug; then
+ echo "$cmp USER $pp_aix_bff_name.$ex.al:"
+ cat $user_wrkdir/$pp_aix_bff_name.$ex.al
+ echo "$cmp ROOT $pp_aix_bff_name.$ex.al:"
+ cat $root_wrkdir/$pp_aix_bff_name.$ex.al
+ fi >&2
+
+ pp_aix_inventory $pp_aix_bff_name.$ex < $user_files \
+ > $user_wrkdir/$pp_aix_bff_name.$ex.inventory
+ pp_aix_inventory $pp_aix_bff_name.$ex < $root_files \
+ > $root_wrkdir/$pp_aix_bff_name.$ex.inventory
+
+ if $pp_opt_debug; then
+ pp_debug "$cmp USER $pp_aix_bff_name.$ex.inventory:"
+ cat $user_wrkdir/$pp_aix_bff_name.$ex.inventory
+ pp_debug "$cmp ROOT $pp_aix_bff_name.$ex.inventory:"
+ cat $root_wrkdir/$pp_aix_bff_name.$ex.inventory
+ fi >&2
+
+ if test x"" != x"${pp_aix_copyright:-$copyright}"; then
+ echo "${pp_aix_copyright:-$copyright}" > $user_wrkdir/$pp_aix_bff_name.$ex.copyright
+ echo "${pp_aix_copyright:-$copyright}" > $root_wrkdir/$pp_aix_bff_name.$ex.copyright
+ fi
+
+ #-- assume that post/pre uninstall scripts only make
+ # sense when installed in a root context
+
+ if test -r $pp_wrkdir/%pre.$cmp; then
+ pp_aix_make_script $user_wrkdir/$pp_aix_bff_name.$ex.pre_i \
+ < $pp_wrkdir/%pre.$cmp
+ fi
+
+ if test -r $pp_wrkdir/%post.$cmp; then
+ pp_aix_make_script $root_wrkdir/$pp_aix_bff_name.$ex.post_i \
+ < $pp_wrkdir/%post.$cmp
+ fi
+
+ if test -r $pp_wrkdir/%preun.$cmp; then
+ pp_aix_make_script $root_wrkdir/$pp_aix_bff_name.$ex.unpost_i \
+ < $pp_wrkdir/%preun.$cmp
+ fi
+
+ if test -r $pp_wrkdir/%postun.$cmp; then
+ pp_aix_make_script $root_wrkdir/$pp_aix_bff_name.$ex.unpre_i \
+ < $pp_wrkdir/%postun.$cmp
+ fi
+
+ # remove empty files
+ for f in $user_wrkdir/$pp_aix_bff_name.$ex.* $root_wrkdir/$pp_aix_bff_name.$ex.*; do
+ if test ! -s "$f"; then
+ pp_debug "removing empty $f"
+ rm -f "$f"
+ fi
+ done
+
+ # copy/link the root files so we can do an easy backup later
+ pp_aix_copy_root $instroot < $root_files
+
+ echo "%"
+ echo "]"
+ done
+ echo "}"
+ } > $pp_wrkdir/lpp_name
+
+ if $pp_opt_debug; then
+ echo "/lpp_name :"
+ cat $pp_wrkdir/lpp_name
+ fi >&2
+
+ #-- copy the /lpp_name file to the destdir
+ pp_add_transient_file /lpp_name
+ cp $pp_wrkdir/lpp_name $pp_destdir/lpp_name
+
+ #-- copy the liblpp.a files under destdir for packaging
+ (cd $user_wrkdir && pp_verbose ar -c -g -r liblpp.a $name.*) ||
+ pp_error "ar error"
+ if test -s $user_wrkdir/liblpp.a; then
+ pp_add_transient_file $instuser/liblpp.a
+ pp_verbose cp $user_wrkdir/liblpp.a $pp_destdir$instuser/liblpp.a ||
+ pp_error "cannot create user liblpp.a"
+ fi
+ (cd $root_wrkdir && pp_verbose ar -c -g -r liblpp.a $name.*) ||
+ pp_error "ar error"
+ if test -s $root_wrkdir/liblpp.a; then
+ pp_add_transient_file $instroot/liblpp.a
+ pp_verbose cp $root_wrkdir/liblpp.a $pp_destdir$instroot/liblpp.a ||
+ pp_error "cannot create root liblpp.a"
+ fi
+
+ { echo ./lpp_name
+ test -s $user_wrkdir/liblpp.a && echo .$instuser/liblpp.a
+ test -s $root_wrkdir/liblpp.a && echo .$instroot/liblpp.a
+ cat $user_wrkdir/$name.*.al # includes the relocated root files!
+ } > $pp_wrkdir/bff.list
+
+ if test -n "$pp_aix_abis_seen" -a x"$pp_aix_arch_std" = x"auto"; then
+ case "$pp_aix_abis_seen" in
+ "ppc ppc64"|"ppc64 ppc")
+ pp_aix_arch_std=ppc64
+ ;;
+ ppc|ppc64)
+ pp_aix_arch_std=$pp_aix_abis_seen
+ ;;
+ *" "*)
+ pp_warn "multiple architectures detected: $pp_aix_abis_seen"
+ pp_aix_arch_std=unknown
+ ;;
+ "")
+ pp_warn "no binary executables detected; using noarch"
+ pp_aix_arch_std=noarch
+ ;;
+ *)
+ pp_warn "unknown architecture detected $pp_aix_abis_seen"
+ pp_aix_arch_std=$pp_aix_abis_seen
+ ;;
+ esac
+ fi
+
+ . $pp_wrkdir/%fixup
+
+ outbff=`pp_backend_aix_names`
+ pp_debug "creating: $pp_wrkdir/$outbff"
+ (cd $pp_destdir && pp_verbose /usr/sbin/backup -i -q -p -f -) \
+ < $pp_wrkdir/bff.list \
+ > $pp_wrkdir/$outbff || pp_error "backup failed"
+ if test -n "$pp_aix_sudo" -o -x /usr/sbin/installp; then
+ $pp_aix_sudo /usr/sbin/installp -l -d $pp_wrkdir/$outbff
+ fi
+}
+
+pp_backend_aix_cleanup () {
+ :
+}
+
+pp_backend_aix_names () {
+ echo "$name.`[ $pp_aix_version ] && pp_aix_version_fix $pp_aix_version || pp_aix_version_fix "$version"`.bff"
+}
+
+pp_backend_aix_install_script () {
+ typeset pkgname platform
+ #
+ # The script should take a first argument being the
+ # operation; further arguments refer to components or services
+ #
+ # list-components -- lists components in the pkg
+ # install component... -- installs the components
+ # uninstall component... -- uninstalles the components
+ # list-services -- lists the services in the pkg
+ # start service... -- starts the name service
+ # stop service... -- stops the named services
+ # print-platform -- prints the platform group
+ #
+ pkgname="`pp_backend_aix_names`"
+ platform="`pp_backend_aix_probe`" # XXX should be derived from files
+
+ fsets=
+ for cmp in $pp_components; do
+ case "$cmp" in
+ run) ex=rte;;
+ doc) ex=doc;;
+ dev) ex=adt;;
+ dbg) ex=diag;;
+ esac
+ fsets="$fsets $name.$ex"
+ done
+
+ echo '#!/bin/sh'
+ pp_install_script_common
+
+ cat <<-.
+
+ cpt_to_fileset () {
+ test x"\$*" = x"all" &&
+ set -- $pp_components
+ for cpt
+ do
+ case "\$cpt" in
+ run) echo "$name.rte";;
+ doc) echo "$name.doc";;
+ dev) echo "$name.adt";;
+ dbg) echo "$name.diag";;
+ *) usage;;
+ esac
+ done
+ }
+
+ test \$# -eq 0 && usage
+ op="\$1"; shift
+
+ case "\$op" in
+ list-components)
+ test \$# -eq 0 || usage \$op
+ echo "$pp_components"
+ ;;
+ list-services)
+ test \$# -eq 0 || usage \$op
+ echo "$pp_services"
+ ;;
+ list-files)
+ test \$# -ge 1 || usage \$op
+ echo \${PP_PKGDESTDIR:-.}/$pkgname
+ ;;
+ install)
+ test \$# -ge 1 || usage \$op
+ verbose /usr/sbin/installp -acX -V0 -F \
+ -d \${PP_PKGDESTDIR:-.}/$pkgname \
+ \`cpt_to_fileset "\$@"\`
+ ;;
+ uninstall)
+ test \$# -ge 1 || usage \$op
+ verbose /usr/sbin/installp -u -e/dev/null \
+ -V0 \`cpt_to_fileset "\$@"\`
+ ;;
+ start|stop)
+ test \$# -ge 1 || usage \$op
+ ec=0
+ for svc
+ do
+ verbose \${op}src -s \$svc || ec=1
+ done
+ exit \$ec
+ ;;
+ print-platform)
+ echo "$platform"
+ ;;
+ *)
+ usage;;
+ esac
+.
+}
+
+pp_backend_aix_init_svc_vars () {
+ :
+}
+
+pp_backend_aix_probe () {
+ echo "${pp_aix_os}-${pp_aix_arch_std}"
+}
+
+pp_backend_aix_vas_platforms () {
+ case "${pp_aix_arch_std}" in
+ ppc*) :;;
+ *) pp_die "unknown architecture ${pp_aix_arch_std}";;
+ esac
+ case "${pp_aix_os}" in
+ aix43) echo "aix-43";;
+ aix51) echo "aix-51 aix-43";;
+ aix52) echo "aix-51 aix-43";;
+ aix53) echo "aix-53 aix-51 aix-43";;
+ aix61) echo "aix-53 aix-51 aix-43";;
+ *) pp_die "unknown system ${pp_aix_os}";;
+ esac
+}
+pp_backend_aix_function () {
+ case "$1" in
+ pp_mkgroup) cat <<'.';;
+ /usr/sbin/lsgroup "$1" >/dev/null &&
+ return 0
+ echo "Creating group $1"
+ /usr/bin/mkgroup -A "$1"
+.
+ pp_mkuser:depends) echo pp_mkgroup;;
+ pp_mkuser) cat <<'.';;
+ /usr/sbin/lsuser "$1" >/dev/null &&
+ return 0
+ pp_mkgroup "${2:-$1}" || return 1
+ echo "Creating user $1"
+ /usr/bin/mkuser \
+ login=false \
+ rlogin=false \
+ account_locked=true \
+ home="${3:-/nohome.$1}" \
+ pgrp="${2:-$1}" \
+ "$1"
+.
+ pp_havelib) cat <<'.';;
+ case "$2" in
+ "") pp_tmp_name="lib$1.so";;
+ *.*.*) pp_tmp_name="lib$1.so.$2";;
+ *.*) pp_tmp_name="lib$1.so.$2.0";;
+ *) pp_tmp_name="lib$1.so.$2";;
+ esac
+ for pp_tmp_dir in `echo "/usr/lib:/lib${3:+:$3}" | tr : ' '`; do
+ test -r "$pp_tmp_dir/$pp_tmp_name" -a \
+ -r "$pp_tmp_dir/lib$1.so" && return 0
+ done
+ return 1
+.
+ *) false;;
+ esac
+}
+
+pp_platforms="$pp_platforms sd"
+
+pp_backend_sd_detect () {
+ test x"$1" = x"HP-UX"
+}
+
+pp_backend_sd_init () {
+ pp_sd_sudo=
+ pp_sd_startlevels=2
+ pp_sd_stoplevels=auto
+ pp_sd_config_file=
+ pp_sd_vendor=
+ pp_sd_vendor_tag=Quest
+ pp_sd_default_start=1 # config_file default start value
+
+ pp_readlink_fn=pp_ls_readlink # HPUX has no readlink
+ pp_shlib_suffix='.sl' # .so on most other platforms
+
+ pp_sd_detect_os
+}
+
+pp_sd_detect_os () {
+ typeset revision
+
+ revision=`uname -r`
+ pp_sd_os="${revision#?.}"
+ test -z "$pp_sd_os" &&
+ pp_warn "cannot detect OS version"
+ pp_sd_os_std="hpux`echo $pp_sd_os | tr -d .`"
+
+ case "`uname -m`" in
+ 9000/[678]??) pp_sd_arch_std=hppa;;
+ ia64) pp_sd_arch_std=ia64;;
+ *) pp_sd_arch_std=unknown;;
+ esac
+}
+
+pp_sd_write_files () {
+ typeset t m o g f p st line dm
+ while read t m o g f p st; do
+ line=" file"
+ case "$f" in *v*) line="$line -v";; esac # FIXME for uninstall
+ case ${pp_sd_os} in
+ 10.*)
+ case $t in
+ f) dm=644;;
+ d) p=${p%/}; dm=755;;
+ esac
+ ;;
+ *)
+ case $t in
+ f) dm=644;;
+ d) line="$line -t d"; p=${p%/}; dm=755;;
+ s) line="$line -t s";;
+ esac
+ ;;
+ esac
+
+ test x"$o" = x"-" && o=root
+ test x"$g" = x"-" && g=sys
+ test x"$m" = x"-" && m=$dm
+
+ case $t in
+ s)
+ # swpackage will make unqualified links relative to the
+ # current working (source) directory, not the destination;
+ # we need to qualify them to prevent this.
+ case "$st" in
+ [!/]*) st="`dirname \"$p\"`/$st";;
+ esac
+ echo "$line -o $o -g $g -m $m $st $p"
+ ;;
+ *)
+ echo "$line -o $o -g $g -m $m $pp_destdir$p $p"
+ ;;
+ esac
+
+ done
+}
+
+pp_sd_service_group_script () {
+ typeset grp svcs scriptpath out
+ grp="$1"
+ svcs="$2"
+ scriptpath="/sbin/init.d/$grp"
+ out="$pp_destdir$scriptpath"
+
+ pp_add_file_if_missing $scriptpath run 755 || return 0
+
+ cat <<-. > $out
+ #!/sbin/sh
+ # generated by pp $pp_version
+ svcs="$svcs"
+.
+
+ cat <<-'.' >> $out
+ #-- starts services in order.. stops them all if any break
+ pp_start () {
+ undo=
+ for svc in \$svcs; do
+ /sbin/init.d/\$svc start
+ case \$? in
+ 0|4)
+ undo="\$svc \$undo"
+ ;;
+ *)
+ if test -n "\$undo"; then
+ for svc in \$undo; do
+ /sbin/init.d/\$svc stop
+ done
+ return 1
+ fi
+ ;;
+ esac
+ done
+ return 0
+ }
+
+ #-- stops services in reverse
+ pp_stop () {
+ reverse=
+ for svc in \$svcs; do
+ reverse="\$svc \$reverse"
+ done
+ rc=0
+ for svc in \$reverse; do
+ /sbin/init.d/\$svc stop || rc=\$?
+ done
+ return \$rc
+ }
+
+ case \$1 in
+ start_msg) echo "Starting \$svcs";;
+ stop_msg) echo "Stopping \$svcs";;
+ start) pp_start;;
+ stop) pp_stop;;
+ *) echo "usage: \$0 {start|stop|start_msg|stop_msg}"
+ exit 1;;
+ esac
+.
+}
+
+pp_sd_service_script () {
+ typeset svc config_file config_value scriptpath out
+
+ svc="$1"
+ scriptpath="/sbin/init.d/$svc"
+
+ config_file=${pp_sd_config_file:-/etc/rc.config.d/$svc}
+ sd_config_var=`echo run-$svc | tr '[a-z]-' '[A-Z]_'`
+ sd_config_value=${pp_sd_default_start:-0}
+ pp_load_service_vars "$svc"
+
+ test -n "$user" -a x"$user" != x"root" &&
+ cmd="SHELL=/usr/bin/sh /usr/bin/su $user -c \"exec `echo $cmd | sed -e 's,[$\\\`],\\&,g'`\""
+ if test -z "$pidfile"; then
+ pidfile="/var/run/$svc.pid"
+ cmd="$cmd & echo \$! > \$pidfile"
+ fi
+
+ pp_debug "config file is $config_file"
+
+ pp_add_file_if_missing $scriptpath run 755
+ pp_add_file_if_missing $config_file run 644 v
+
+ cat <<-. >> $pp_destdir$config_file
+
+ # Controls whether the $svc service is started
+ $sd_config_var=$sd_config_value
+.
+
+ if test ! -f $pp_destdir$scriptpath; then
+ cat <<-. > $pp_destdir$scriptpath
+ #!/sbin/sh
+ # generated by pp $pp_version
+
+ svc="$svc"
+ pidfile="$pidfile"
+ config_file="$config_file"
+
+ pp_start () {
+ $cmd
+ }
+
+ pp_disabled () {
+ test \${$sd_config_var:-0} -eq 0
+ }
+
+ pp_stop () {
+ if test ! -s "\$pidfile"; then
+ echo "Unable to stop \$svc (no pid file)"
+ return 1
+ else
+ read pid < "\$pidfile"
+ if kill -0 "\$pid" 2>/dev/null; then
+ if kill -${stop_signal:-TERM} "\$pid"; then
+ rm -f "\$pidfile"
+ return 0
+ else
+ echo "Unable to stop \$svc"
+ return 1
+ fi
+ else
+ rm -f "\$pidfile"
+ return 0
+ fi
+ fi
+ }
+
+ pp_running () {
+ if test -s "\$pidfile"; then
+ read pid < "\$pidfile" 2>/dev/null
+ if test \${pid:-0} -gt 1 && kill -0 "\$pid" 2>/dev/null; then
+ # make sure command name matches
+ c="\`echo $cmd | sed -e 's: .*::' -e 's:^.*/::'\`"
+ pid="\`ps -p \$pid 2>/dev/null | sed -n \"s/^ *\(\$pid\) .*\$c *\$/\1/p\"\`"
+ if test -n "\$pid"; then
+ return 0
+ fi
+ fi
+ fi
+ return 1
+ }
+
+ case \$1 in
+ start_msg) echo "Starting the \$svc service";;
+ stop_msg) echo "Stopping the \$svc service";;
+ start)
+ if test -f "\$config_file"; then
+ . \$config_file
+ fi
+ if pp_disabled; then
+ exit 2
+ elif pp_running; then
+ echo "\$svc already running";
+ exit 0
+ elif pp_start; then
+ echo "\$svc started";
+ # rc(1M) says we should exit 4, but nobody expects it!
+ exit 0
+ else
+ exit 1
+ fi;;
+ stop) if pp_stop; then
+ echo "\$svc stopped";
+ exit 0
+ else
+ exit 1
+ fi;;
+ *) echo "usage: \$0 {start|stop|start_msg|stop_msg}"
+ exit 1;;
+ esac
+.
+ fi
+}
+
+pp_sd_make_service () {
+ typeset level startpriority stoppriority startlevels stoplevels
+ typeset svc svcvar symtype
+
+ svc="$1"
+ svcvar=`pp_makevar $svc`
+
+ case ${pp_sd_os} in
+ 10.*) symtype="file";;
+ *) symtype="file -t s";;
+ esac
+
+ # TODO: Figure out why this check is here
+ #-- don't do anything if the script exists
+ #if test -s "$pp_destdir/sbin/init.d/$svc"; then
+ # pp_error "$pp_destdir/sbin/init.d/$svc exists"
+ # return
+ #fi
+
+ # symlink the script, depending on the priorities chosen
+ eval startpriority='${pp_sd_startpriority_'$svcvar'}'
+ eval stoppriority='${pp_sd_stoppriority_'$svcvar'}'
+ test -z "$startpriority" && startpriority="${pp_sd_startpriority:-50}"
+ test -z "$stoppriority" && stoppriority="${pp_sd_stoppriority:-50}"
+
+ eval startlevels='${pp_sd_startlevels_'$svcvar'}'
+ test -z "$startlevels" && startlevels="$pp_sd_startlevels"
+
+ eval stoplevels='${pp_sd_stoplevels_'$svcvar'}'
+ test -z "$stoplevels" && stoplevels="$pp_sd_stoplevels"
+
+ # create the script and config file
+ pp_sd_service_script $svc
+
+ # fix the priority up
+ case "$startpriority" in
+ ???) :;;
+ ??) startpriority=0$startpriority;;
+ ?) startpriority=00$startpriority;;
+ esac
+ case "$stoppriority" in
+ ???) :;;
+ ??) stoppriority=0$stoppriority;;
+ ?) stoppriority=00$stoppriority;;
+ esac
+
+ if test x"$stoplevels" = x"auto"; then
+ stoplevels=
+ test -z "$startlevels" || for level in $startlevels; do
+ stoplevels="$stoplevels `expr $level - 1`"
+ done
+ fi
+
+ # create the symlinks
+ test -z "$startlevels" || for level in $startlevels; do
+ echo " ${symtype}" \
+ "/sbin/init.d/$svc" \
+ "/sbin/rc$level.d/S$startpriority$svc"
+ done
+ test -z "$stoplevels" || for level in $stoplevels; do
+ echo " ${symtype}" \
+ "/sbin/init.d/$svc" \
+ "/sbin/rc$level.d/K$stoppriority$svc"
+ done
+}
+
+pp_sd_control () {
+ typeset ctrl script
+ typeset cpt
+
+ ctrl="$1"; shift
+ cpt="$1"; shift
+ script="$pp_wrkdir/control.$ctrl.$cpt"
+ cat <<. >$script
+.
+ cat "$@" >> $script
+ echo "exit 0" >> $script
+ /usr/bin/chmod +x $script
+ echo " $ctrl $script"
+}
+
+pp_sd_depend () {
+ typeset _name _vers
+ while read _name _vers; do
+ case "$_name" in ""| "#"*) continue ;; esac
+ echo " prerequisites $_name ${_vers:+r>= $_vers}"
+ done
+}
+
+pp_sd_conflict () {
+ typeset _name _vers
+ while read _name _vers; do
+ case "$_name" in ""| "#"*) continue ;; esac
+ echo " exrequisites $_name ${_vers:+r>= $_vers}"
+ done
+}
+
+pp_backend_sd () {
+ typeset psf cpt svc outfile release swp_flags
+
+ psf=$pp_wrkdir/psf
+ release="?.${pp_sd_os%.[0-9][0-9]}.*"
+
+ echo "depot" > $psf
+ echo "layout_version 1.0" >>$psf
+
+ #-- vendor
+ cat <<. >>$psf
+ vendor
+ tag $pp_sd_vendor_tag
+ title "${pp_sd_vendor:-$vendor}"
+ end
+
+ product
+ tag $name
+ revision $version
+ vendor_tag $pp_sd_vendor_tag
+ is_patch false
+ title "$summary"
+ copyright "$copyright"
+ machine_type *
+ os_name HP-UX
+ os_release $release
+ os_version ?
+ directory /
+ is_locatable false
+.
+ test -n "$description" \
+ && echo $description > $pp_wrkdir/description \
+ && cat <<. >> $psf
+ description < $pp_wrkdir/description
+.
+
+ # make convenience service groups
+ if test -n "$pp_service_groups"; then
+ for grp in $pp_service_groups; do
+ pp_sd_service_group_script \
+ $grp "`pp_service_get_svc_group $grp`"
+ done
+ fi
+
+ for cpt in $pp_components; do
+ cat <<. >>$psf
+ fileset
+ tag ${pp_sd_fileset_tag:-$cpt}
+ title "${summary:-cpt}"
+ revision $version
+.
+ test -s $pp_wrkdir/%depend.$cpt &&
+ pp_sd_depend < $pp_wrkdir/%depend.$cpt >> $psf
+ test -s $pp_wrkdir/%conflict.$cpt &&
+ pp_sd_conflict < $pp_wrkdir/%conflict.$cpt >> $psf
+
+ #-- make sure services are shut down during uninstall
+ if test $cpt = run -a -n "$pp_services"; then
+ for svc in $pp_services; do
+ pp_prepend $pp_wrkdir/%preun.$cpt <<-.
+ /sbin/init.d/$svc stop
+.
+ done
+ fi
+
+ #-- we put the post/preun code into configure/unconfigure
+ # and not postinstall/preremove, because configure/unconfigure
+ # scripts are run on the hosts where the package is installed,
+ # not loaded (a subtle difference).
+ test -s $pp_wrkdir/%pre.$cpt &&
+ pp_sd_control checkinstall $cpt $pp_wrkdir/%pre.$cpt >> $psf
+ test -s $pp_wrkdir/%post.$cpt &&
+ pp_sd_control configure $cpt $pp_wrkdir/%post.$cpt >> $psf
+ test -s $pp_wrkdir/%preun.$cpt &&
+ pp_sd_control unconfigure $cpt $pp_wrkdir/%preun.$cpt >> $psf
+ test -s $pp_wrkdir/%postun.$cpt &&
+ pp_sd_control postremove $cpt $pp_wrkdir/%postun.$cpt >> $psf
+ test -s $pp_wrkdir/%check.$cpt &&
+ pp_sd_control checkinstall $cpt $pp_wrkdir/%check.$cpt >> $psf
+
+ if test $cpt = run -a -n "$pp_services"; then
+ for svc in $pp_services; do
+ #-- service names are 10 chars max on hpux
+ case "$svc" in ???????????*)
+ pp_warn "service name '$svc' is too long for hpux";;
+ esac
+ pp_sd_make_service $svc >> $psf
+ done
+ #pp_sd_make_service_config
+ fi
+
+ pp_sd_write_files < $pp_wrkdir/%files.$cpt >> $psf
+
+ #-- end fileset clause
+ cat <<. >>$psf
+ end
+.
+
+ done
+
+ #-- end product clause
+ cat <<. >>$psf
+ end
+.
+
+ $pp_opt_debug && cat $psf >&2
+
+ test -s $pp_wrkdir/%fixup && . $pp_wrkdir/%fixup
+
+ outfile=`pp_backend_sd_names`
+ case ${pp_sd_os} in
+ 10.*)
+ swp_flags="-x target_type=tape"
+ ;;
+ *)
+ swp_flags="-x media_type=tape"
+ ;;
+ esac
+ if pp_verbose ${pp_sd_sudo} /usr/sbin/swpackage -s $psf $swp_flags \
+ @ $pp_wrkdir/$outfile
+ then
+ pp_verbose ${pp_sd_sudo} /usr/sbin/swlist -l file -s $pp_wrkdir/$outfile
+ else
+ pp_error "swpackage failed"
+ fi
+}
+
+pp_backend_sd_cleanup () {
+ :
+}
+
+pp_backend_sd_names () {
+ echo "$name-$version.$pp_sd_arch_std.depot"
+}
+
+pp_backend_sd_install_script () {
+ typeset pkgname platform
+
+ pkgname=`pp_backend_sd_names`
+ platform="`pp_backend_sd_probe`"
+
+ echo "#!/bin/sh"
+ pp_install_script_common
+ cat <<.
+
+ cpt_to_tags () {
+ test x"\$*" = x"all" && set -- $pp_components
+ for cpt
+ do
+ echo "$name.\$cpt"
+ done
+ }
+
+ test \$# -eq 0 && usage
+ op="\$1"; shift
+
+ case "\$op" in
+ list-components)
+ test \$# -eq 0 || usage \$op
+ echo "$pp_components"
+ ;;
+ list-services)
+ test \$# -eq 0 || usage \$op
+ echo "$pp_services"
+ ;;
+ list-files)
+ test \$# -ge 1 || usage \$op
+ echo \${PP_PKGDESTDIR:-.}/$pkgname
+ ;;
+ install)
+ test \$# -ge 1 || usage \$op
+ verbose /usr/sbin/swinstall -x verbose=0 \
+ -s \${PP_PKGDESTDIR:-\`pwd\`}/$pkgname \
+ \`cpt_to_tags "\$@"\`
+ ;;
+ uninstall)
+ test \$# -ge 1 || usage \$op
+ verbose /usr/sbin/swremove -x verbose=0 \
+ \`cpt_to_tags "\$@"\`
+ ;;
+ start|stop)
+ test \$# -ge 1 || usage \$op
+ ec=0
+ for svc
+ do
+ verbose /sbin/init.d/\$svc \$op
+ [ \$? -eq 4 -o \$? -eq 0 ] || ec=1
+ done
+ exit \$ec
+ ;;
+ print-platform)
+ echo "$platform"
+ ;;
+ *)
+ usage
+ ;;
+ esac
+.
+}
+
+pp_backend_sd_probe () {
+ echo "${pp_sd_os_std}-${pp_sd_arch_std}"
+}
+
+pp_backend_sd_vas_platforms () {
+ case "`pp_backend_sd_probe`" in
+ hpux*-hppa) echo hpux-pa;;
+ hpux*-ia64) echo hpux-ia64 hpux-pa;;
+ *) pp_die "unknown system `pp_backend_sd_probe`";;
+ esac
+}
+
+pp_backend_sd_init_svc_vars () {
+ :
+}
+pp_backend_sd_function () {
+ case "$1" in
+ pp_mkgroup) cat <<'.';;
+ /usr/sbin/groupmod "$1" 2>/dev/null ||
+ /usr/sbin/groupadd "$1"
+.
+ pp_mkuser:depends) echo pp_mkgroup;;
+ pp_mkuser) cat <<'.';;
+ pp_mkgroup "${2:-$1}" || return 1
+ /usr/sbin/useradd \
+ -g "${2:-$1}" \
+ -d "${3:-/nonexistent}" \
+ -s "${4:-/bin/false}" \
+ "$1"
+.
+ pp_havelib) cat <<'.';;
+ for pp_tmp_dir in `echo /usr/lib${3:+:$3} | tr : ' '`; do
+ test -r "$pp_tmp_dir/lib$1${2:+.$2}.sl" && return 0
+ done
+ return 1
+.
+ *) false;;
+ esac
+}
+
+pp_platforms="$pp_platforms solaris"
+
+pp_backend_solaris_detect () {
+ test x"$1" = x"SunOS"
+}
+
+pp_backend_solaris_init () {
+ pp_solaris_category=
+ pp_solaris_istates="s S 1 2 3" # run-states when install is ok
+ pp_solaris_rstates="s S 1 2 3" # run-states when remove is ok
+ pp_solaris_maxinst=
+ pp_solaris_vendor=
+ pp_solaris_pstamp=
+ pp_solaris_copyright=
+ pp_solaris_name=
+ pp_solaris_desc=
+ pp_solaris_package_arch=auto
+
+ pp_solaris_detect_os
+ pp_solaris_detect_arch
+
+ pp_solaris_init_svc
+
+ #-- readlink not reliably available on Solaris
+ pp_readlink_fn=pp_ls_readlink
+}
+
+pp_solaris_detect_os () {
+ typeset osrel
+
+ osrel=`/usr/bin/uname -r`
+ case "$osrel" in
+ 5.[0-6]) pp_solaris_os="sol2${osrel#5.}";;
+ 5.*) pp_solaris_os="sol${osrel#5.}";;
+ esac
+ test -z "$pp_solaris_os" &&
+ pp_warn "can't determine OS suffix from uname -r"
+
+}
+
+pp_solaris_detect_arch () {
+ pp_solaris_arch=`/usr/bin/optisa amd64 sparcv9 i386 sparc`
+ [ -z "$pp_solaris_arch" ] &&
+ pp_error "can't determine processor architecture"
+ case "$pp_solaris_arch" in
+ amd64) pp_solaris_arch_std=x86_64;;
+ i386) pp_solaris_arch_std=i386;;
+ sparcv9) pp_solaris_arch_std=sparc64;;
+ sparc) pp_solaris_arch_std=sparc;;
+ *) pp_solaris_arch_std=unknown;;
+ esac
+}
+
+pp_solaris_is_request_script_necessary () {
+ typeset has_optional_services
+
+ has_optional_services=no
+ for _svc in $pp_services; do
+ pp_load_service_vars $_svc
+ if test "$optional" = "yes"; then
+ has_optional_services=yes
+ fi
+ done
+
+ # If the package has no optional services and only one component, don't
+ # create a request script at all.
+ if test "$has_optional_services" = "no" &&
+ test `echo $pp_components | wc -w` -eq 1; then
+ return 1 # no
+ fi
+
+ return 0 # yes
+}
+
+pp_solaris_request () {
+ typeset _cmp _svc
+
+ #-- The common part of the request script contains the ask() function
+ # and resets the CLASSES list to empty
+ cat <<'.'
+ trap 'exit 3' 15
+ ask () {
+ ans=`ckyorn -d "$1" \
+ -p "Do you want to $2"` \
+ || exit $?
+ case "$ans" in y*|Y*) return 0;; *) return 1;; esac
+ }
+ CLASSES=
+.
+ #-- each of our components adds itself to the CLASSES list
+ for _cmp in $pp_components; do
+ case "$_cmp" in
+ run) :;;
+ doc) echo 'ask y "install the documentation files" &&';;
+ dev) echo 'ask y "install the development files" &&';;
+ dbg) echo 'ask n "install the diagnostic files" &&';;
+ esac
+ echo ' CLASSES="$CLASSES '$_cmp'"'
+ done
+
+ #-- the request script writes the CLASSES var to its output
+ cat <<'.'
+ echo "CLASSES=$CLASSES" > $1
+.
+
+ if test -n "$pp_services"; then
+ echo 'SERVICES='
+ for _svc in $pp_services; do
+ pp_load_service_vars $_svc
+ if test "$enable" = "yes"; then
+ _default_prompt=y
+ else
+ _default_prompt=n
+ fi
+ if test "$optional" = "yes"; then
+ echo 'ask '$_default_prompt' "install '$_svc' service" &&'
+ fi
+ echo ' SERVICES="$SERVICES '$_svc'"'
+ done
+ echo 'echo "SERVICES=$SERVICES" >> $1'
+ fi
+
+}
+
+pp_solaris_procedure () {
+ cat <<.
+
+ #-- $2 for $1 component of $name
+ case " \$CLASSES " in *" $1 "*)
+.
+ cat
+ cat <<.
+ ;; esac
+.
+}
+
+pp_solaris_depend () {
+ typeset _name _vers
+ while read _name _vers; do
+ if test -n "$_name"; then
+ echo "P $_name $_name"
+ test -n "$_vers" && echo " $_vers"
+ fi
+ done
+}
+
+pp_solaris_conflict () {
+ typeset _name _vers
+ while read _name _vers; do
+ if test -n "$_name"; then
+ echo "I $_name $_name"
+ test -n "$_vers" && echo " $_vers"
+ fi
+ done
+}
+
+pp_solaris_space() {
+ echo "$2:$3:$1" >> $pp_wrkdir/space.cumulative
+}
+
+pp_solaris_sum_space () {
+ if test -s $pp_wrkdir/space.cumulative; then
+ sort -t: +2 < $pp_wrkdir/space.cumulative |
+ awk -F: 'NR==1{n=$3}{if($3==n){b+=$1;i+=$2}else{print n" "b" "i;b=$1;i=$2;n=$3}}END{print n" "b" "i}' > $pp_wrkdir/space
+ fi
+}
+
+pp_solaris_proto () {
+ typeset t m o g f p st
+ typeset abi
+
+ while read t m o g f p st; do
+ # Use Solaris default mode, owner and group if all unspecified
+ if test x"$m$o$g" = x"---"; then
+ m="?"; o="?"; g="?"
+ fi
+ test x"$o" = x"-" && o="root"
+ case "$t" in
+ f) test x"$g" = x"-" && g="bin"
+ test x"$m" = x"-" && m=444
+ case "$f" in
+ *v*) echo "v $1 $p=$pp_destdir$p $m $o $g";;
+ *) echo "f $1 $p=$pp_destdir$p $m $o $g";;
+ esac
+ if test -r "$pp_destdir$p"; then
+ #-- Use file to record ABI types seen
+ case "`file "$pp_destdir$p"`" in
+ *"ELF 32"*80386*) abi=i386;;
+ *"ELF 64"*AMD*) abi=x86_64;;
+ *"ELF 32"*SPARC*) abi=sparc;;
+ *"ELF 64"*SPARC*) abi=sparc64;;
+ *) abi=;;
+ esac
+ if test -n "$abi"; then
+ pp_add_to_list pp_solaris_abis_seen $abi
+ fi
+ fi
+ ;;
+ d) test x"$g" = x"-" && g="sys"
+ test x"$m" = x"-" && m=555
+ echo "d $1 $p $m $o $g"
+ ;;
+ s) test x"$g" = x"-" && g="bin"
+ test x"$m" = x"-" && m=777
+ if test x"$m" != x"777" -a x"$m" != x"?"; then
+ pp_warn "$p: invalid mode $m for symlink, should be 777 or -"
+ fi
+ echo "s $1 $p=$st $m $o $g"
+ ;;
+ esac
+ done
+}
+
+pp_backend_solaris () {
+ typeset _cmp _svc _grp
+
+ prototype=$pp_wrkdir/prototype
+ : > $prototype
+
+ pkginfo=$pp_wrkdir/pkginfo
+ : > $pkginfo
+ echo "i pkginfo=$pkginfo" >> $prototype
+
+ case "${pp_solaris_name:-$name}" in
+ [0-9]*)
+ pp_error "Package name '${pp_solaris_name:-$name}'" \
+ "cannot start with a number"
+ ;;
+ ???????????????*)
+ pp_warn "Package name '${pp_solaris_name:-$name}'" \
+ "too long for Solaris 2.6 or 2.7 (max 9 characters)"
+ ;;
+ ??????????*)
+ pp_warn "Package name '${pp_solaris_name:-$name}'" \
+ "too long for 2.7 Solaris (max 9 characters)"
+ ;;
+ esac
+
+ #-- generate the package info file
+ echo "VERSION=$version" >> $pkginfo
+ echo "PKG=${pp_solaris_name:-$name}" >> $pkginfo
+ echo "CLASSES=$pp_components" >> $pkginfo
+ echo "BASEDIR=/" >> $pkginfo
+ echo "NAME=$name $version" >> $pkginfo
+ echo "CATEGORY=${pp_solaris_category:-application}" >> $pkginfo
+
+ desc="${pp_solaris_desc:-$description}"
+ test -n "$desc" &&
+ echo "DESC=$desc" >> $pkginfo
+
+ test -n "$pp_solaris_rstates" &&
+ echo "RSTATES=$pp_solaris_rstates" >> $pkginfo
+ test -n "$pp_solaris_istates" &&
+ echo "ISTATES=$pp_solaris_istates" >> $pkginfo
+ test -n "$pp_solaris_maxinst" &&
+ echo "MAXINST=$pp_solaris_maxinst" >> $pkginfo
+ test -n "${pp_solaris_vendor:-$vendor}" &&
+ echo "VENDOR=${pp_solaris_vendor:-$vendor}" >> $pkginfo
+ test -n "$pp_solaris_pstamp" &&
+ echo "PSTAMP=$pp_solaris_pstamp" >> $pkginfo
+
+ if test -n "${pp_solaris_copyright:-$copyright}"; then
+ echo "${pp_solaris_copyright:-$copyright}" > $pp_wrkdir/copyright
+ echo "i copyright=$pp_wrkdir/copyright" >> $prototype
+ fi
+
+ #-- scripts to run before and after install
+ : > $pp_wrkdir/postinstall
+ : > $pp_wrkdir/preremove
+ : > $pp_wrkdir/postremove
+ for _cmp in $pp_components; do
+ #-- add the preinstall scripts in definition order
+ if test -s $pp_wrkdir/%pre.$_cmp; then
+ pp_solaris_procedure $_cmp preinst < $pp_wrkdir/%pre.$_cmp \
+ >> $pp_wrkdir/preinstall
+ fi
+ #-- add the postinstall scripts in definition order
+ if test -s $pp_wrkdir/%post.$_cmp; then
+ pp_solaris_procedure $_cmp postinst < $pp_wrkdir/%post.$_cmp \
+ >> $pp_wrkdir/postinstall
+ fi
+ #-- add the preremove rules in reverse definition order
+ if test -s $pp_wrkdir/%preun.$_cmp; then
+ pp_solaris_procedure $_cmp preremove < $pp_wrkdir/%preun.$_cmp |
+ pp_prepend $pp_wrkdir/preremove
+ fi
+ #-- add the postremove scripts in definition order
+ if test -s $pp_wrkdir/%postun.$_cmp; then
+ pp_solaris_procedure $_cmp postremove < $pp_wrkdir/%postun.$_cmp \
+ >> $pp_wrkdir/postremove
+ fi
+ #-- Add the check script in definition order
+ if test -s $pp_wrkdir/%check.$_cmp; then
+ pp_solaris_procedure $_cmp checkinstall \
+ < $pp_wrkdir/%check.$_cmp \
+ >> $pp_wrkdir/checkinstall
+ fi
+ #-- All dependencies and conflicts are merged together for Solaris pkgs
+ test -s $pp_wrkdir/%depend.$_cmp &&
+ pp_solaris_depend < $pp_wrkdir/%depend.$_cmp >> $pp_wrkdir/depend
+ test -s $pp_wrkdir/%conflict.$_cmp &&
+ pp_solaris_conflict < $pp_wrkdir/%conflict.$_cmp >> $pp_wrkdir/depend
+ done
+
+
+ if pp_solaris_is_request_script_necessary; then
+ pp_solaris_request > $pp_wrkdir/request
+ fi
+
+ test -n "$pp_services" &&
+ for _svc in $pp_services; do
+ pp_load_service_vars $_svc
+ pp_solaris_smf $_svc
+ pp_solaris_make_service $_svc
+ pp_solaris_install_service $_svc | pp_prepend $pp_wrkdir/postinstall
+ pp_solaris_remove_service $_svc | pp_prepend $pp_wrkdir/preremove
+ pp_solaris_remove_service $_svc | pp_prepend $pp_wrkdir/postremove
+ unset pp_svc_xml_file
+ done
+
+ test -n "$pp_service_groups" &&
+ for _grp in $pp_service_groups; do
+ pp_solaris_make_service_group \
+ $_grp "`pp_service_get_svc_group $_grp`"
+ done
+
+ #-- if installf was used; we need to indicate a termination
+ grep installf $pp_wrkdir/postinstall >/dev/null &&
+ echo 'installf -f $PKGINST' >> $pp_wrkdir/postinstall
+
+ pp_solaris_sum_space
+
+ # NB: pkginfo and copyright are added earlier
+ for f in compver depend space checkinstall \
+ preinstall request postinstall \
+ preremove postremove; do
+ if test -s $pp_wrkdir/$f; then
+ case $f in
+ *install|*remove|request)
+ # turn scripts into a proper shell scripts
+ mv $pp_wrkdir/$f $pp_wrkdir/$f.tmp
+ { echo "#!/bin/sh";
+ echo "# $f script for ${pp_solaris_name:-$name}-$version"
+ cat $pp_wrkdir/$f.tmp
+ echo "exit 0"; } > $pp_wrkdir/$f
+ chmod +x $pp_wrkdir/$f
+ rm -f $pp_wrkdir/$f.tmp
+ ;;
+ esac
+ if $pp_opt_debug; then
+ pp_debug "contents of $f:"
+ cat $pp_wrkdir/$f >&2
+ fi
+ echo "i $f=$pp_wrkdir/$f" >> $prototype
+ fi
+ done
+
+ #-- create the prototype file which lists the files to install
+ # do this as late as possible because files could be added
+ pp_solaris_abis_seen=
+ for _cmp in $pp_components; do
+ pp_solaris_proto $_cmp < $pp_wrkdir/%files.$_cmp
+ done >> $prototype
+
+ if test x"$pp_solaris_package_arch" = x"auto"; then
+ if pp_contains "$pp_solaris_abis_seen" sparc64; then
+ pp_solaris_package_arch_std="sparc64"
+ echo "ARCH=sparcv9" >> $pkginfo
+ elif pp_contains "$pp_solaris_abis_seen" sparc; then
+ pp_solaris_package_arch_std="sparc"
+ echo "ARCH=sparc" >> $pkginfo
+ elif pp_contains "$pp_solaris_abis_seen" x86_64; then
+ pp_solaris_package_arch_std="x86_64"
+ echo "ARCH=amd64" >> $pkginfo
+ elif pp_contains "$pp_solaris_abis_seen" i386; then
+ pp_solaris_package_arch_std="i386"
+ echo "ARCH=i386" >> $pkginfo
+ else
+ pp_warn "No ELF files found: not supplying an ARCH type"
+ pp_solaris_package_arch_std="noarch"
+ fi
+ else
+ pp_solaris_package_arch_std="$pp_solaris_package_arch"
+ echo "ARCH=$pp_solaris_package_arch" >> $pkginfo
+ fi
+
+ mkdir $pp_wrkdir/pkg
+
+ . $pp_wrkdir/%fixup
+
+if $pp_opt_debug; then
+ echo "$pkginfo::"; cat $pkginfo
+ echo "$prototype::"; cat $prototype
+fi >&2
+
+ pkgmk -d $pp_wrkdir/pkg -f $prototype \
+ || { error "pkgmk failed"; return; }
+ pkgtrans -s $pp_wrkdir/pkg \
+ $pp_wrkdir/`pp_backend_solaris_names` \
+ ${pp_solaris_name:-$name} \
+ || { error "pkgtrans failed"; return; }
+}
+
+pp_backend_solaris_cleanup () {
+ :
+}
+
+pp_backend_solaris_names () {
+ echo ${pp_solaris_name:-$name}-$version-${pp_solaris_package_arch_std:-$pp_solaris_arch}.pkg
+}
+
+pp_backend_solaris_install_script () {
+ typeset pkgname platform
+
+ platform="${pp_solaris_os:-solaris}-${pp_solaris_package_arch_std:-$pp_solaris_arch}"
+
+ echo "#! /sbin/sh"
+ pp_install_script_common
+ pkgname=`pp_backend_solaris_names`
+
+ cat <<.
+ tmpnocheck=/tmp/nocheck\$\$
+ tmpresponse=/tmp/response\$\$
+ trap 'rm -f \$tmpnocheck \$tmpresponse' 0
+
+ make_tmpfiles () {
+ cat <<-.. > \$tmpresponse
+ CLASSES=\$*
+ SERVICES=$pp_services
+..
+ cat <<-.. > \$tmpnocheck
+ mail=
+ instance=overwrite
+ partial=nocheck
+ runlevel=nocheck
+ idepend=nocheck
+ rdepend=nocheck
+ space=nocheck
+ setuid=nocheck
+ conflict=nocheck
+ action=nocheck
+ basedir=default
+..
+ }
+
+ test \$# -eq 0 && usage
+ op="\$1"; shift
+
+ case "\$op" in
+ list-components)
+ test \$# -eq 0 || usage \$op
+ echo "$pp_components"
+ ;;
+ list-services)
+ test \$# -eq 0 || usage \$op
+ echo "$pp_services"
+ ;;
+ list-files)
+ test \$# -ge 1 || usage \$op
+ echo \${PP_PKGDESTDIR:-.}/$pkgname
+ ;;
+ install)
+ test \$# -ge 1 || usage \$op
+ make_tmpfiles "\$@"
+ verbose /usr/sbin/pkgadd -n -d \${PP_PKGDESTDIR:-.}/$pkgname \
+ -r \$tmpresponse \
+ -a \$tmpnocheck \
+ ${pp_solaris_name:-$name}
+ ;;
+ uninstall)
+ test \$# -ge 1 || usage \$op
+ make_tmpfiles "\$@"
+ verbose /usr/sbin/pkgrm -n \
+ -a \$tmpnocheck \
+ ${pp_solaris_name:-$name}
+ ;;
+ start|stop)
+ test \$# -ge 1 || usage \$op
+ ec=0
+ for svc
+ do
+ verbose /etc/init.d/\$svc \$op || ec=1
+ done
+ exit \$ec
+ ;;
+ print-platform)
+ echo "$platform"
+ ;;
+ *)
+ usage
+ ;;
+ esac
+.
+}
+
+pp_solaris_dynlib_depend () {
+ xargs ldd 2>/dev/null |
+ sed -e '/^[^ ]*:$/d' -e 's,.*=>[ ]*,,' -e 's,^[ ]*,,' |
+ sort -u |
+ grep -v '^/usr/platform/' | (
+ set -- ""; shift
+ while read p; do
+ set -- "$@" -p "$p"
+ if [ $# -gt 32 ]; then
+ echo "$# is $#" >&2
+ pkgchk -l "$@"
+ set -- ""; shift
+ fi
+ done
+ [ $# -gt 0 ] && pkgchk -l "$@"
+ )|
+ awk '/^Current status:/{p=0} p==1 {print $1} /^Referenced by/ {p=1}' |
+ sort -u |
+ xargs -l32 pkginfo -x |
+ awk 'NR % 2 == 1 { name=$1; } NR%2 == 0 { print name, $2 }'
+}
+
+pp_solaris_add_dynlib_depends () {
+ typeset tmp
+ tmp=$pp_wrkdir/tmp.dynlib
+
+ for _cmp in $pp_components; do
+ awk '{print destdir $6}' destdir="$pp_destdir" \
+ < $pp_wrkdir/%files.$_cmp |
+ pp_solaris_dynlib_depend > $tmp
+ if test -s $tmp; then
+ cat $tmp >> $pp_wrkdir/%depend.$_cmp
+ fi
+ rm -f $tmp
+ done
+}
+
+pp_backend_solaris_probe () {
+ echo "${pp_solaris_os}-${pp_solaris_arch_std}"
+}
+
+pp_backend_solaris_vas_platforms () {
+ case `pp_backend_solaris_probe` in
+ sol10-sparc* | sol9-sparc* | sol8-sparc*)
+ echo solaris8-sparc solaris7-sparc solaris26-sparc;;
+ sol7-sparc*) echo solaris7-sparc solaris26-sparc;;
+ sol26-sparc*) echo solaris26-sparc;;
+ sol8-*86) echo solaris8-x86;;
+ sol10-*86 | sol10-x86_64)
+ echo solaris10-x64 solaris8-x86;;
+ *) pp_die "unknown system `pp_backend_solaris_probe`";;
+ esac
+}
+pp_backend_solaris_function() {
+ case "$1" in
+ pp_mkgroup) cat<<'.';;
+ /usr/sbin/groupmod "$1" 2>/dev/null && return 0
+ /usr/sbin/groupadd "$1"
+.
+ pp_mkuser:depends) echo pp_mkgroup;;
+ pp_mkuser) cat<<'.';;
+ id "$1" >/dev/null 2>/dev/null && return 0
+ pp_mkgroup "${2:-$1}" || return 1
+ /usr/sbin/useradd \
+ -g "${2:-$1}" \
+ -d "${3:-/nonexistent}" \
+ -s "${4:-/bin/false}" \
+ "$1"
+.
+ *) false;;
+ esac
+}
+
+pp_backend_solaris_init_svc_vars () {
+ _smf_category=${pp_solaris_smf_category:-application}
+ _smf_method_envvar_name=${smf_method_envvar_name:-"PP_SMF_SERVICE"}
+ pp_solaris_service_shell=/sbin/sh
+}
+
+pp_solaris_init_svc () {
+ smf_version=1
+ smf_type=service
+ solaris_user=
+ solaris_stop_signal=
+ solaris_sysv_init_start=S70 # invocation order for start scripts
+ solaris_sysv_init_kill=K30 # invocation order for kill scripts
+ solaris_sysv_init_start_states="2" # states to install start link
+ solaris_sysv_init_kill_states="S 0 1" # states to install kill link
+
+ #
+ # To have the service be installed to start automatically,
+ # %service foo
+ # solaris_sysv_init_start_states="S 0 1 2"
+ #
+}
+
+pp_solaris_smf () {
+ typeset f _pp_solaris_service_script svc _pp_solaris_manpage
+
+ pp_solaris_name=${pp_solaris_name:-$name}
+ pp_solaris_manpath=${pp_solaris_manpath:-"/usr/share/man"}
+ pp_solaris_mansect=${pp_solaris_mansect:-1}
+ smf_start_timeout=${smf_start_timeout:-60}
+ smf_stop_timeout=${smf_stop_timeout:-60}
+ smf_restart_timeout=${smf_restart_timeout:-60}
+
+ svc=${pp_solaris_smf_service_name:-$1}
+ _pp_solaris_service_script=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
+ _pp_solaris_manpage=${pp_solaris_manpage:-$svc}
+
+ if [ -z $pp_svc_xml_file ]; then
+ pp_svc_xml_file="/var/svc/manifest/$_smf_category/$svc.xml"
+ echo "## Generating the smf service manifest file for $pp_svc_xml_file"
+ else
+ echo "## SMF service manifest file already defined at $pp_svc_xml_file"
+ if [ -z $pp_solaris_smf_service_name ] || [ -z $pp_solaris_smf_category ] || [ -z $pp_solaris_service_script ] || [ -z $smf_method_envvar_name ]; then
+ pp_error "All required variables are not set.\n"\
+ "When using a custom manifest file all of the following variables must be set:\n"\
+ "pp_solaris_smf_service_name, pp_solaris_smf_category, pp_solaris_service_script and smf_method_envvar_name.\n\n"\
+ "Example:\n"\
+ " \$pp_solaris_smf_category=application\n"\
+ " \$pp_solaris_smf_service_name=pp\n\n"\
+ " <service name='application/pp' type='service' version='1'>\n\n"\
+ "Example:\n"\
+ " \$pp_solaris_service_script=/etc/init.d/pp\n\n"\
+ " <exec_method type='method' name='start' exec='/etc/init.d/pp' />\n\n"\
+ "Example:\n"\
+ " \$smf_method_envvar_name=PP_SMF_SERVICE\n\n"\
+ " <method_environment>\n"\
+ " <envvar name='PP_SMF_SERVICE' value='1'/>\n"\
+ " </method_environment>\n"
+
+ return 1
+ fi
+ return 0
+ fi
+
+ f=$pp_svc_xml_file
+ pp_add_file_if_missing $f ||
+ return 0
+ pp_solaris_add_parent_dirs "$f"
+
+ _pp_solaris_smf_dependencies="
+ <dependency name='pp_local_filesystems'
+ grouping='require_all'
+ restart_on='none'
+ type='service'>
+ <service_fmri value='svc:/system/filesystem/local'/>
+ </dependency>
+
+ <dependency name='pp_single-user'
+ grouping='require_all'
+ restart_on='none'
+ type='service'>
+ <service_fmri value='svc:/milestone/single-user' />
+ </dependency>
+"
+ _pp_solaris_smf_dependencies=${pp_solaris_smf_dependencies:-$_pp_solaris_smf_dependencies}
+
+ cat <<-. >$pp_destdir$f
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
+<!--
+ $copyright
+ Generated by PolyPackage $pp_version
+-->
+
+ <service_bundle type='manifest' name='${pp_solaris_name}:${svc}' >
+ <service name='$_smf_category/$svc'
+ type='$smf_type'
+ version='$smf_version'>
+
+ <create_default_instance enabled='false'/>
+
+ <single_instance />
+
+ $_pp_solaris_smf_dependencies
+
+ $pp_solaris_smf_additional_dependencies
+
+ <method_context>
+ <method_credential user='${solaris_user:-$user}' />
+ <method_environment>
+ <envvar name='$_smf_method_envvar_name' value='1'/>
+ </method_environment>
+ </method_context>
+
+ <exec_method type='method' name='start'
+ exec='$_pp_solaris_service_script start'
+ timeout_seconds='$smf_start_timeout' />
+
+ <exec_method type='method' name='stop'
+ exec='$_pp_solaris_service_script stop'
+ timeout_seconds='$smf_stop_timeout' />
+
+ <exec_method type='method' name='restart'
+ exec='$_pp_solaris_service_script restart'
+ timeout_seconds='$smf_restart_timeout' />
+
+ <template>
+ <common_name>
+ <loctext xml:lang='C'>$description</loctext>
+ </common_name>
+ <documentation>
+ <manpage title='$pp_solaris_manpage' section='$pp_solaris_mansect' manpath='$pp_solaris_manpath'/>
+ </documentation>
+ </template>
+ </service>
+ </service_bundle>
+.
+}
+
+pp_solaris_make_service_group () {
+ typeset group out file svcs svc
+
+ group="$1"
+ svcs="$2"
+ file="/etc/init.d/$group"
+ out="$pp_destdir$file"
+
+ #-- return if the script is supplied already
+ pp_add_file_if_missing "$file" run 755 || return 0
+ pp_solaris_add_parent_dirs "$file"
+
+ echo "#! /sbin/sh" > $out
+ echo "# polypkg service group script for these services:" >> $out
+ echo "svcs=\"$svcs\"" >> $out
+
+ cat <<'.' >>$out
+
+ #-- starts services in order.. stops them all if any break
+ pp_start () {
+ undo=
+ for svc in $svcs; do
+ if /etc/init.d/$svc start; then
+ undo="$svc $undo"
+ else
+ if test -n "$undo"; then
+ for svc in $undo; do
+ /etc/init.d/$svc stop
+ done
+ return 1
+ fi
+ fi
+ done
+ return 0
+ }
+
+ #-- stops services in reverse
+ pp_stop () {
+ reverse=
+ for svc in $svcs; do
+ reverse="$svc $reverse"
+ done
+ rc=0
+ for svc in $reverse; do
+ /etc/init.d/$svc stop || rc=$?
+ done
+ return $rc
+ }
+
+ #-- returns true only if all services return true status
+ pp_status () {
+ rc=0
+ for svc in $svcs; do
+ /etc/init.d/$svc status || rc=$?
+ done
+ return $rc
+ }
+
+ case "$1" in
+ start) pp_start;;
+ stop) pp_stop;;
+ status) pp_status;;
+ restart) pp_stop && pp_start;;
+ *) echo "usage: $0 {start|stop|restart|status}" >&2; exit 1;;
+ esac
+.
+}
+
+pp_solaris_make_service () {
+ typeset file out svc
+
+ svc="${pp_solaris_smf_service_name:-$1}"
+ file=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
+ out="$pp_destdir$file"
+
+ #-- return if we don't need to create the init script
+ pp_add_file_if_missing "$file" run 755 ||
+ return 0
+ pp_solaris_add_parent_dirs "$file"
+
+ echo "#! /sbin/sh" >$out
+ echo "#-- This service init file generated by polypkg" >>$out
+
+ #-- Start SMF integration.
+ if [ -n "$pp_svc_xml_file" ] ; then
+ cat <<_EOF >>$out
+if [ -x /usr/sbin/svcadm ] && [ "x\$1" != "xstatus" ] && [ "t\$$_smf_method_envvar_name" = "t" ] ; then
+ case "\$1" in
+ start)
+ echo "starting $svc"
+ /usr/sbin/svcadm clear svc:/$_smf_category/$svc:default >/dev/null 2>&1
+ /usr/sbin/svcadm enable -s $_smf_category/$svc
+ RESULT=\$?
+ if [ "\$RESULT" -ne 0 ] ; then
+ echo "Error \$RESULT starting $svc" >&2
+ fi
+ ;;
+ stop)
+ echo "stopping $svc"
+ /usr/sbin/svcadm disable -ts $_smf_category/$svc
+ RESULT=0
+ ;;
+ restart)
+ echo "restarting $svc"
+ /usr/sbin/svcadm disable -ts $_smf_category/$svc
+ /usr/sbin/svcadm clear svc:/$_smf_category/$svc:default >/dev/null 2>&1
+ /usr/sbin/svcadm enable -s $_smf_category/$svc
+ RESULT=\$?
+ if [ "\$RESULT" -ne 0 ] ; then
+ echo "Error \$RESULT starting $svc" >&2
+ fi
+ ;;
+ *)
+ echo "Usage: $file {start|stop|restart|status}" >&2
+ RESULT=1
+ esac
+ exit $RESULT
+fi
+_EOF
+ fi
+
+ #-- Construct a start command that builds a pid file as needed
+ # and forks the daemon. Services started by smf may not fork.
+ if test -z "$pidfile"; then
+ # The service does not define a pidfile, so we have to make
+ # our own up. On Solaris systems where there is no /var/run
+ # we must use /tmp to guarantee the pid files are removed after
+ # a system crash.
+ if test -z "$pp_piddir"; then
+ pp_piddir="/var/run"
+ fi
+ cat <<. >>$out
+ pp_isdaemon=0
+ pp_piddirs="${pp_piddir}${pp_piddir+ }/var/run /tmp"
+ for pp_piddir in \$pp_piddirs; do
+ test -d "\$pp_piddir/." && break
+ done
+ pidfile="\$pp_piddir/$svc.pid"
+.
+ else
+ # The service is able to write its own PID file
+ cat <<. >>$out
+ pp_isdaemon=1
+ pidfile="$pidfile"
+.
+ fi
+
+ pp_su=
+ if test "${user:-root}" != "root"; then
+ pp_su="su $user -c exec "
+ fi
+
+ cat <<. >>$out
+ stop_signal="${stop_signal:-TERM}"
+ svc="${svc}"
+
+ # generated command to run $svc as a service
+ pp_exec () {
+ if [ \$pp_isdaemon -ne 1 ]; then
+ if [ "t\$PP_SMF_SERVICE" = "t" ]; then
+ ${pp_su}$cmd &
+ echo \$! > \$pidfile
+ else
+ echo "via exec."
+ echo \$$ > \$pidfile
+ exec ${pp_su}$cmd
+ return 1
+ fi
+ else
+ ${pp_su}$cmd
+ fi
+ }
+.
+
+ #-- write the invariant section of the init script
+ cat <<'.' >>$out
+
+ # returns true if $svc is running
+ pp_running () {
+ if test -s "$pidfile"; then
+ read pid < "$pidfile" 2>/dev/null
+ if test ${pid:-0} -gt 1 && kill -0 "$pid" 2>/dev/null; then
+ # make sure command name matches up to the first 8 chars
+ c="`echo $cmd | sed -e 's: .*::' -e 's:^.*/::' -e 's/^\(........\).*$/\1/'`"
+ pid="`ps -p $pid 2>/dev/null | sed -n \"s/^ *\($pid\) .*$c *$/\1/p\"`"
+ if test -n "$pid"; then
+ return 0
+ fi
+ fi
+ fi
+ return 1
+ }
+
+ # prints a message describing $svc's running state
+ pp_status () {
+ if pp_running; then
+ echo "service $svc is running (pid $pid)"
+ return 0
+ elif test -f "$pidfile"; then
+ echo "service $svc is not running, but pid file exists"
+ return 2
+ else
+ echo "service $svc is not running"
+ return 1
+ fi
+ }
+
+ # starts $svc
+ pp_start () {
+ if pp_running; then
+ echo "service $svc already running" >&2
+ return 0
+ fi
+ echo "starting $svc... \c"
+ if pp_exec; then
+ echo "done."
+ else
+ echo "ERROR."
+ exit 1
+ fi
+ }
+
+ # stops $svc
+ pp_stop () {
+ if pp_running; then
+ echo "stopping $svc... \c"
+ if kill -$stop_signal $pid; then
+ rm -f "$pidfile"
+ echo "done."
+ else
+ echo "ERROR."
+ return 1
+ fi
+ else
+ echo "service $svc already stopped" >&2
+ return 0
+ fi
+ }
+
+ umask 022
+ case "$1" in
+ start) pp_start;;
+ stop) pp_stop;;
+ status) pp_status;;
+ restart) pp_stop && pp_start;;
+ *) echo "usage: $0 {start|stop|restart|status}" >&2; exit 1;;
+ esac
+.
+}
+
+pp_solaris_remove_service () {
+ typeset file svc
+
+ svc="${pp_solaris_smf_service_name:-$1}"
+ file=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
+
+ echo '
+if [ "x${PKG_INSTALL_ROOT}" = 'x' ]; then
+ if [ -x /usr/sbin/svcadm ] ; then
+ /usr/sbin/svcadm disable -s '$svc' 2>/dev/null
+ /usr/sbin/svccfg delete '$svc' 2>/dev/null
+ else
+ '$file' stop >/dev/null 2>/dev/null
+ fi
+fi
+ '
+}
+
+pp_solaris_install_service () {
+ typeset s k l file svc
+
+ svc="${pp_solaris_smf_service_name:-$1}"
+ file=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
+
+ s="${solaris_sysv_init_start}$svc"
+ k="${solaris_sysv_init_kill}$svc"
+
+ echo '
+if [ "x${PKG_INSTALL_ROOT}" != "x" ]; then
+ if [ -x ${PKG_INSTALL_ROOT}/usr/sbin/svcadm ]; then
+ echo "/usr/sbin/svccfg import '$pp_svc_xml_file' 2>/dev/null" >> ${PKG_INSTALL_ROOT}/var/svc/profile/upgrade
+ else'
+ test -n "${solaris_sysv_init_start_states}" &&
+ for state in ${solaris_sysv_init_start_states}; do
+ l="/etc/rc$state.d/$s"
+ echo "echo '$l'"
+ echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
+ pp_solaris_space /etc/rc$state.d 0 1
+ done
+ test -n "${solaris_sysv_init_kill_states}" &&
+ for state in ${solaris_sysv_init_kill_states}; do
+ l="/etc/rc$state.d/$k"
+ echo "echo '$l'"
+ echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
+ pp_solaris_space /etc/rc$state.d 0 1
+ done
+ echo '
+ fi
+else
+ if [ -x /usr/sbin/svcadm ]; then
+ echo "Registering '$svc' with SMF"
+ /usr/sbin/svcadm disable -s '$svc' 2>/dev/null
+ /usr/sbin/svccfg delete '$svc' 2>/dev/null
+ /usr/sbin/svccfg import '$pp_svc_xml_file'
+ else'
+ test -n "${solaris_sysv_init_start_states}" &&
+ for state in ${solaris_sysv_init_start_states}; do
+ l="/etc/rc$state.d/$s"
+ echo "echo '$l'"
+ echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
+ pp_solaris_space /etc/rc$state.d 0 1
+ done
+ test -n "${solaris_sysv_init_kill_states}" &&
+ for state in ${solaris_sysv_init_kill_states}; do
+ l="/etc/rc$state.d/$k"
+ echo "echo '$l'"
+ echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
+ pp_solaris_space /etc/rc$state.d 0 1
+ done
+ echo '
+ fi
+fi'
+}
+
+pp_solaris_add_parent_dirs () {
+ typeset dir
+
+ dir=${1%/*}
+ while test -n "$dir"; do
+ if awk "\$6 == \"$dir/\" {exit 1}" < $pp_wrkdir/%files.run; then
+ echo "d - - - - $dir/" >> $pp_wrkdir/%files.run
+ fi
+ dir=${dir%/*}
+ done
+}
+
+pp_platforms="$pp_platforms deb"
+
+pp_backend_deb_detect () {
+ test -f /etc/debian_version
+}
+
+pp_deb_cmp_full_name () {
+ local prefix
+ prefix="${pp_deb_name:-$name}"
+ case "$1" in
+ run) echo "${prefix}" ;;
+ dbg) echo "${prefix}-${pp_deb_dbg_pkgname}";;
+ dev) echo "${prefix}-${pp_deb_dev_pkgname}";;
+ doc) echo "${prefix}-${pp_deb_doc_pkgname}";;
+ *) pp_error "unknown component '$1'";
+ esac
+}
+
+pp_backend_deb_init () {
+ pp_deb_dpkg_version="2.0"
+ pp_deb_name=
+ pp_deb_version=
+ pp_deb_release=
+ pp_deb_arch=
+ pp_deb_arch_std=
+ pp_deb_maintainer="One Identity, LLC <support@oneidentity.com>"
+ pp_deb_copyright=
+ pp_deb_distro=
+ pp_deb_control_description=
+ pp_deb_summary=
+ pp_deb_description=
+ pp_deb_dbg_pkgname="dbg"
+ pp_deb_dev_pkgname="dev"
+ pp_deb_doc_pkgname="doc"
+ pp_deb_section=contrib # Free software that depends on non-free software
+
+ # Detect the host architecture
+ pp_deb_detect_arch
+
+ # Make sure any programs we require are installed
+ pp_deb_check_required_programs
+}
+
+pp_deb_check_required_programs () {
+ local p needed notfound ok
+ needed= notfound=
+ for prog in dpkg dpkg-deb install md5sum fakeroot
+ do
+ if which $prog 2>/dev/null >/dev/null; then
+ pp_debug "$prog: found"
+ else
+ pp_debug "$prog: not found"
+ case "$prog" in
+ dpkg|dpkg-deb) p=dpkg;;
+ install|md5sum) p=coreutils;;
+ fakeroot) p=fakeroot;;
+ *) pp_die "unexpected dpkg tool $prog";;
+ esac
+ notfound="$notfound $prog"
+ pp_contains "$needed" "$p" || needed="$needed $p"
+ fi
+ done
+ if [ -n "$notfound" ]; then
+ pp_error "cannot find these programs: $notfound"
+ pp_error "please install these packages: $needed"
+ fi
+}
+
+pp_deb_munge_description () {
+ # Insert a leading space on each line, replace blank lines with a
+ #space followed by a full-stop.
+ pp_deb_control_description="`echo ${pp_deb_description:-$description} | \
+ sed 's,^\(.*\)$, \1, ' | sed 's,^[ \t]*$, .,g' | fmt -w 80`"
+}
+
+pp_deb_detect_arch () {
+ pp_deb_arch=`dpkg --print-architecture`
+ pp_deb_arch_std=`uname -m`
+}
+
+pp_deb_sanitize_version() {
+ echo "$@" | tr -d -c '[:alnum:].+-:~'
+}
+
+pp_deb_version_final() {
+ if test -n "$pp_deb_version"; then
+ # Don't sanitize; assume the user is sane (hah!)
+ echo "$pp_deb_version"
+ else
+ pp_deb_sanitize_version "$version"
+ fi
+}
+
+pp_deb_conflict () {
+ local _name _vers _conflicts
+
+ _conflicts="Conflicts:"
+ while read _name _vers; do
+ case "$_name" in ""| "#"*) continue ;; esac
+ _conflicts="$_conflicts $_name"
+ test -n "$_vers" && _conflicts="$_conflicts $_name (>= $vers)"
+ _conflicts="${_conflicts},"
+ done
+ echo "${_conflicts%,}"
+}
+
+pp_deb_make_control() {
+ local cmp="$1"
+ local installed_size
+
+ # compute the installed size
+ installed_size=`pp_deb_files_size < $pp_wrkdir/%files.$cmp`
+
+ package_name=`pp_deb_cmp_full_name "$cmp"`
+ cat <<-.
+ Package: ${package_name}
+ Version: `pp_deb_version_final`-${pp_deb_release:-1}
+ Section: ${pp_deb_section:-contrib}
+ Priority: optional
+ Architecture: ${pp_deb_arch}
+ Maintainer: ${pp_deb_maintainer:-$maintainer}
+ Description: ${pp_deb_summary:-$summary}
+ ${pp_deb_control_description}
+ Installed-Size: ${installed_size}
+.
+ if test -s $pp_wrkdir/%depend."$cmp"; then
+ sed -ne '/^[ ]*$/!s/^[ ]*/Depends: /p' \
+ < $pp_wrkdir/%depend."$cmp"
+ fi
+ if test -s $pp_wrkdir/%conflict."$cmp"; then
+ pp_deb_conflict < $pp_wrkdir/%conflict."$cmp"
+ fi
+}
+
+pp_deb_make_md5sums() {
+ local cmp="$1"; shift
+ local pkg_dir
+
+ pkg_dir=$pp_wrkdir/`pp_deb_cmp_full_name $cmp`
+ (cd $pkg_dir && md5sum "$@") > $pkg_dir/DEBIAN/md5sums ||
+ pp_error "cannot make md5sums"
+}
+
+pp_deb_make_package_maintainer_script() {
+ local output="$1"
+ local source="$2"
+ local desc="$3"
+
+ # See if we need to create this script at all
+ if [ -s "$source" ]
+ then
+
+ # Create header
+ cat <<-. >$output || pp_error "Cannot create $output"
+ #!/bin/sh
+ # $desc
+ # Generated by PolyPackage $pp_version
+
+.
+
+ cat $source >> "$output" || pp_error "Cannot append to $output"
+
+ # Set perms
+ chmod 755 "$output" || pp_error "Cannot chmod $output"
+ fi
+}
+
+pp_deb_handle_services() {
+ local svc
+
+ #-- add service start/stop code
+ if test -n "$pp_services"; then
+ #-- record the uninstall commands in reverse order
+ for svc in $pp_services; do
+ pp_load_service_vars $svc
+
+ # Create init script (unless one exists)
+ pp_deb_service_make_init_script $svc
+
+ #-- append %post code to install the svc
+ test x"yes" = x"$enable" &&
+ cat<<-. >> $pp_wrkdir/%post.run
+ case "\$1" in
+ configure)
+ # Install the service links
+ update-rc.d $svc defaults
+ ;;
+ esac
+.
+
+ #-- prepend %preun code to stop svc
+ cat<<-. | pp_prepend $pp_wrkdir/%preun.run
+ case "\$1" in
+ remove|deconfigure|upgrade)
+ # Stop the $svc service
+ invoke-rc.d $svc stop
+ ;;
+ esac
+.
+
+ #-- prepend %postun code to remove service
+ cat<<-. | pp_prepend $pp_wrkdir/%postun.run
+ case "\$1" in
+ purge)
+ # Remove the service links
+ update-rc.d $svc remove
+ ;;
+ esac
+.
+ done
+ #pp_deb_service_remove_common | pp_prepend $pp_wrkdir/%preun.run
+ fi
+
+}
+pp_deb_fakeroot () {
+ if test -s $pp_wrkdir/fakeroot.save; then
+ fakeroot -i $pp_wrkdir/fakeroot.save -s $pp_wrkdir/fakeroot.save "$@"
+ else
+ fakeroot -s $pp_wrkdir/fakeroot.save "$@"
+ fi
+}
+
+pp_deb_files_size () {
+ local t m o g f p st
+ while read t m o g f p st; do
+ case $t in
+ f|s) du -k "${pp_destdir}$p";;
+ d) echo 4;;
+ esac
+ done | awk '{n+=$1} END {print n}'
+}
+
+pp_deb_make_DEBIAN() {
+ local cmp="${1:-run}"
+ local data cmp_full_name
+ local old_umask
+
+ old_umask=`umask`
+ umask 0022
+ cmp_full_name=`pp_deb_cmp_full_name $cmp`
+ data=$pp_wrkdir/$cmp_full_name
+
+ # Create DEBIAN dir $data/DEBIAN
+ mkdir -p $data/DEBIAN
+
+ # Create control file
+ pp_deb_make_control $cmp > $data/DEBIAN/control
+
+ # Copy in conffiles
+ if test -f $pp_wrkdir/%conffiles.$cmp; then
+ cp $pp_wrkdir/%conffiles.$cmp $data/DEBIAN/conffiles
+ fi
+
+ # Create preinst
+ pp_deb_make_package_maintainer_script "$data/DEBIAN/preinst" \
+ "$pp_wrkdir/%pre.$cmp" "Pre-install script for $cmp_full_name"\
+ || exit $?
+
+ # Create postinst
+ pp_deb_make_package_maintainer_script "$data/DEBIAN/postinst" \
+ "$pp_wrkdir/%post.$cmp" "Post-install script for $cmp_full_name"\
+ || exit $?
+
+ # Create prerm
+ pp_deb_make_package_maintainer_script "$data/DEBIAN/prerm" \
+ "$pp_wrkdir/%preun.$cmp" "Pre-uninstall script for $cmp_full_name"\
+ || exit $?
+
+ # Create postrm
+ pp_deb_make_package_maintainer_script "$data/DEBIAN/postrm" \
+ "$pp_wrkdir/%postun.$cmp" "Post-uninstall script for $cmp_full_name"\
+ || exit $?
+
+ umask $old_umask
+}
+
+pp_deb_make_data() {
+ local _l t m o g f p st data
+ local data share_doc owner group
+ cmp=$1
+ data=$pp_wrkdir/`pp_deb_cmp_full_name $cmp`
+ cat $pp_wrkdir/%files.${cmp} | while read t m o g f p st; do
+ if test x"$m" = x"-"; then
+ case "$t" in
+ d) m=755;;
+ f) m=644;;
+ esac
+ fi
+ test x"$o" = x"-" && o=root
+ test x"$g" = x"-" && g=root
+ case "$t" in
+ f) # Files
+ pp_deb_fakeroot install -D -o $o -g $g -m ${m} $pp_destdir/$p $data/$p;
+ if [ x"$f" = x"v" ]
+ then
+ # File marked as "volatile". Assume this means it's a conffile
+ # TODO: check this as admins like modified conffiles to be left
+ # behind
+ echo "$p" >> $pp_wrkdir/%conffiles.$cmp
+ fi;;
+
+ d) # Directories
+ pp_deb_fakeroot install -m ${m} -o $o -g $g -d $data/$p;;
+
+ s) # Symlinks
+ # Remove leading / from vars
+ rel_p=`echo $p | sed s,^/,,`
+ rel_st=`echo $st | sed s,^/,,`
+ # TODO: we are always doing absolute links here. We should follow
+ # the debian policy of relative links when in the same top-level
+ # directory
+ (cd $data; ln -sf $st $rel_p);;
+ *) pp_error "Unsupported data file type: $t";;
+ esac
+ done
+
+ # If no copyright file is present add one. This is a debian requirement.
+ share_doc="/usr/share/doc/`pp_deb_cmp_full_name $cmp`"
+ if [ ! -f "$data/$share_doc/copyright" ]
+ then
+ echo "${pp_deb_copyright:-$copyright}" > "$pp_wrkdir/copyright"
+ install -D -m 644 "$pp_wrkdir/copyright" "$data/$share_doc/copyright"
+ fi
+
+}
+
+pp_deb_makedeb () {
+ local cmp
+ local package_build_dir
+
+ cmp="$1"
+
+ package_build_dir=$pp_wrkdir/`pp_deb_cmp_full_name $cmp`
+
+ # Create package dir
+ mkdir -p $package_build_dir
+
+ # Copy in data
+ pp_deb_make_data $cmp ||
+ pp_die "Could not make DEBIAN data files for $cmp"
+
+ # Make control files
+ # must be done after copying data so conffiles are found
+ pp_deb_make_DEBIAN $cmp ||
+ pp_die "Could not make DEBIAN control files for $cmp"
+
+ # Create md5sums
+ pp_deb_make_md5sums $cmp `(cd $package_build_dir;
+ find . -name DEBIAN -prune -o -type f -print | sed "s,^\./,,")` ||
+ pp_die "Could not make DEBIAN md5sums for $cmp"
+}
+
+pp_backend_deb () {
+ local debname
+
+ # Munge description for control file inclusion
+ pp_deb_munge_description
+
+ # Handle services
+ pp_deb_handle_services $cmp
+
+ for cmp in $pp_components
+ do
+ debname=`pp_deb_name $cmp`
+ pp_deb_makedeb $cmp
+ done
+
+ . $pp_wrkdir/%fixup
+
+ for cmp in $pp_components
+ do
+ debname=`pp_deb_name $cmp`
+ # Create debian package
+ pp_debug "Building `pp_deb_cmp_full_name $cmp` -> $output"
+ pp_deb_fakeroot dpkg-deb \
+ --build $pp_wrkdir/`pp_deb_cmp_full_name $cmp` \
+ $pp_wrkdir/$debname ||
+ pp_error "failed to create $cmp package"
+ done
+}
+
+pp_backend_deb_cleanup () {
+ # rm -rf $pp_wrkdir
+ :
+}
+
+pp_deb_name () {
+ local cmp="${1:-run}"
+ echo `pp_deb_cmp_full_name $cmp`"_"`pp_deb_version_final`"-${pp_deb_release:-1}_${pp_deb_arch}.deb"
+}
+pp_backend_deb_names () {
+ for cmp in $pp_components
+ do
+ pp_deb_name $cmp
+ done
+}
+
+pp_backend_deb_install_script () {
+ local cmp _cmp_full_name
+
+ echo "#!/bin/sh"
+ pp_install_script_common
+
+ cat <<.
+
+ cmp_to_pkgname () {
+ test x"\$*" = x"all" &&
+ set -- $pp_components
+ for cmp
+ do
+ case \$cmp in
+.
+ for cmp in $pp_components; do
+ echo "$cmp) echo '`pp_deb_cmp_full_name $cmp`';;"
+ done
+ cat <<.
+ *) usage;;
+ esac
+ done
+ }
+
+
+ cmp_to_pathname () {
+ test x"\$*" = x"all" &&
+ set -- $pp_components
+ for cmp
+ do
+ case \$cmp in
+.
+ for cmp in $pp_components; do
+ echo "$cmp) echo \${PP_PKGDESTDIR:-.}/'`pp_deb_name $cmp`';;"
+ done
+ cat <<.
+ *) usage;;
+ esac
+ done
+ }
+
+ test \$# -eq 0 && usage
+ op="\$1"; shift
+ case "\$op" in
+ list-components)
+ test \$# -eq 0 || usage \$op
+ echo $pp_components
+ ;;
+ list-services)
+ test \$# -eq 0 || usage \$op
+ echo $pp_services
+ ;;
+ list-files)
+ test \$# -ge 1 || usage \$op
+ cmp_to_pathname "\$@"
+ ;;
+ install)
+ test \$# -ge 1 || usage \$op
+ dpkg --install \`cmp_to_pathname "\$@"\`
+ ;;
+ uninstall)
+ test \$# -ge 1 || usage \$op
+ dpkg --remove \`cmp_to_pkgname "\$@"\`; :
+ ;;
+ start|stop)
+ test \$# -ge 1 || usage \$op
+ ec=0
+ for svc
+ do
+ /etc/init.d/\$svc \$op || ec=1
+ done
+ exit \$ec
+ ;;
+ print-platform)
+ test \$# -eq 0 || usage \$op
+ echo "linux-${pp_deb_arch}"
+ ;;
+ *)
+ usage
+ ;;
+ esac
+.
+}
+
+pp_backend_deb_probe() {
+ local arch distro release
+
+ pp_deb_detect_arch
+
+ # /etc/debian_version exists on Debian & Ubuntu, so it's no use
+ # to us. Use lsb_release instead.
+
+ case `(lsb_release -is || echo no-lsb) 2>/dev/null` in
+ Debian)
+ distro=deb
+ ;;
+ Ubuntu)
+ distro=ubu
+ ;;
+ no-lsb)
+ echo unknown-$pp_deb_arch_std
+ return 0
+ ;;
+ *)
+ distro=unknown
+ ;;
+ esac
+
+ release=`lsb_release -rs`
+
+ # If release is not numeric, use the codename
+ case $release in
+ *[!.0-9r]*)
+ release=`lsb_release -cs`
+ case $release in
+ buzz)
+ release="11"
+ ;;
+ rex)
+ release="12"
+ ;;
+ bo)
+ release="13"
+ ;;
+ hamm)
+ release="20"
+ ;;
+ slink)
+ release="21"
+ ;;
+ potato)
+ release="22"
+ ;;
+ woody)
+ release="30"
+ ;;
+ sarge)
+ release="31"
+ ;;
+ etch)
+ release="40"
+ ;;
+ lenny)
+ release="50"
+ ;;
+ squeeze)
+ release="60"
+ ;;
+ esac
+ ;;
+ *)
+ # Remove trailing revision number and any dots
+ release=`echo $release | cut -dr -f1 | tr -d .`
+ ;;
+ esac
+
+ echo $distro$release-$pp_deb_arch_std
+}
+
+pp_backend_deb_vas_platforms () {
+ case "$pp_deb_arch_std" in
+ x86_64) echo "linux-x86_64.deb";; # DO NOT add linux-x86.deb here!!
+ *86) echo "linux-x86.deb";;
+ *) pp_die "unknown architecture ${pp_deb_arch_std}";;
+ esac
+}
+pp_backend_deb_init_svc_vars () {
+
+ reload_signal=
+ start_runlevels=${pp_deb_default_start_runlevels-"2 3 4 5"} # == lsb default-start
+ stop_runlevels=${pp_deb_default_stop_runlevels-"0 1 6"} # == lsb default-stop
+ svc_description="${pp_deb_default_svc_description}" # == lsb short descr
+ svc_process=
+
+ lsb_required_start='$local_fs $network'
+ lsb_should_start=
+ lsb_required_stop='$local_fs'
+ lsb_description=
+
+ start_priority=50
+ stop_priority=50 #-- stop_priority = 100 - start_priority
+}
+
+pp_deb_service_make_init_script () {
+ local svc=$1
+ local script=/etc/init.d/$svc
+ local out=$pp_destdir$script
+ local _process _cmd
+
+ pp_add_file_if_missing $script run 755 v || return 0
+
+ #-- start out as an empty shell script
+ cat <<-'.' >$out
+ #!/bin/sh
+.
+
+ #-- determine the process name from $cmd unless $svc_process is given
+ set -- $cmd
+ #_process=${svc_process:-"$1"} --? WTF
+
+ #-- construct a start command that builds a pid file if needed
+ #-- the command name in /proc/[pid]/stat is limited to 15 characters
+ _cmd="$cmd";
+ _cmd_path=`echo $cmd | cut -d" " -f1`
+ _cmd_name=`basename $_cmd_path | cut -c1-15`
+ _cmd_args=`echo $cmd | cut -d" " -f2-`
+ test x"$_cmd_path" != x"$_cmd_args" || _cmd_args=
+
+ #-- generate the LSB init info
+ cat <<-. >>$out
+ ### BEGIN INIT INFO
+ # Provides: ${svc}
+ # Required-Start: ${lsb_required_start}
+ # Should-Start: ${lsb_should_start}
+ # Required-Stop: ${lsb_required_stop}
+ # Default-Start: ${start_runlevels}
+ # Default-Stop: ${stop_runlevels}
+ # Short-Description: ${svc_description:-no description}
+ ### END INIT INFO
+ # Generated by PolyPackage ${pp_version}
+ # ${copyright}
+
+.
+
+ if test x"${svc_description}" = x"${pp_deb_default_svc_description}"; then
+ svc_description=
+ fi
+
+ #-- write service-specific definitions
+ cat <<. >>$out
+NAME="${_cmd_name}"
+DESC="${svc_description:-$svc service}"
+USER="${user}"
+GROUP="${group}"
+PIDFILE="${pidfile}"
+STOP_SIGNAL="${stop_signal}"
+RELOAD_SIGNAL="${reload_signal}"
+CMD="${_cmd}"
+DAEMON="${_cmd_path}"
+DAEMON_ARGS="${_cmd_args}"
+SCRIPTNAME=${script}
+.
+
+ #-- write the generic part of the init script
+ cat <<'.' >>$out
+
+[ -x "$DAEMON" ] || exit 0
+
+[ -r /etc/default/$NAME ] && . /etc/default/$NAME
+
+[ -f /etc/default/rcS ] && . /etc/default/rcS
+
+. /lib/lsb/init-functions
+
+do_start()
+{
+ # Return
+ # 0 if daemon has been started
+ # 1 if daemon was already running
+ # 2 if daemon could not be started
+ if [ -n "$PIDFILE" ]
+ then
+ pidfile_opt="--pidfile $PIDFILE"
+ else
+ pidfile_opt="--make-pidfile --background --pidfile /var/run/$NAME.pid"
+ fi
+ if [ -n "$USER" ]
+ then
+ user_opt="--user $USER"
+ fi
+ if [ -n "$GROUP" ]
+ then
+ group_opt="--group $GROUP"
+ fi
+
+ start-stop-daemon --start --quiet $pidfile_opt $user_opt --exec $DAEMON --test > /dev/null \
+ || return 1
+
+ # Note: there seems to be no way to tell whether the daemon will fork itself or not, so pass
+ # --background for now
+ start-stop-daemon --start --quiet $pidfile_opt $user_opt --exec $DAEMON -- \
+ $DAEMON_ARGS \
+ || return 2
+}
+
+do_stop()
+{
+ # Return
+ # 0 if daemon has been stopped
+ # 1 if daemon was already stopped
+ # 2 if daemon could not be stopped
+ # other if a failure occurred
+ if [ -n "$PIDFILE" ]
+ then
+ pidfile_opt="--pidfile $PIDFILE"
+ else
+ pidfile_opt="--pidfile /var/run/$NAME.pid"
+ fi
+ if [ -n "$USER" ]
+ then
+ user_opt="--user $USER"
+ fi
+ if [ -n $STOP_SIGNAL ]
+ then
+ signal_opt="--signal $STOP_SIGNAL"
+ fi
+ start-stop-daemon --stop --quiet $signal_opt --retry=TERM/30/KILL/5 $pidfile_opt --name $NAME
+ RETVAL="$?"
+ [ "$RETVAL" = 2 ] && return 2
+ # Wait for children to finish too if this is a daemon that forks
+ # and if the daemon is only ever run from this initscript.
+ # If the above conditions are not satisfied then add some other code
+ # that waits for the process to drop all resources that could be
+ # needed by services started subsequently. A last resort is to
+ # sleep for some time.
+ start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
+ [ "$?" = 2 ] && return 2
+ # Many daemons don't delete their pidfiles when they exit.
+ test -z $PIDFILE || rm -f $PIDFILE
+ return "$RETVAL"
+}
+
+do_reload() {
+ #
+ # If the daemon can reload its configuration without
+ # restarting (for example, when it is sent a SIGHUP),
+ # then implement that here.
+ #
+ if [ -n "$PIDFILE" ]
+ then
+ pidfile_opt="--pidfile $PIDFILE"
+ else
+ pidfile_opt="--pidfile /var/run/$NAME.pid"
+ fi
+ if [ -n "$RELOAD_SIGNAL" ]
+ then
+ start-stop-daemon --stop --signal $RELOAD_SIGNAL --quiet $pidfile_opt --name $NAME
+ fi
+ return 0
+}
+
+case "$1" in
+ start)
+ [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
+ do_start
+ case "$?" in
+ 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+ 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+ esac
+ ;;
+ stop)
+ [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
+ do_stop
+ case "$?" in
+ 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+ 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+ esac
+ ;;
+ reload|force-reload)
+ if [ -n "$RELOAD_SIGNAL" ]
+ then
+ log_daemon_msg "Reloading $DESC" "$NAME"
+ do_reload
+ log_end_msg $?
+ else
+ # Do a restart instead
+ "$0" restart
+ fi
+ ;;
+ restart)
+ #
+ # If the "reload" option is implemented then remove the
+ # 'force-reload' alias
+ #
+ log_daemon_msg "Restarting $DESC" "$NAME"
+ do_stop
+ case "$?" in
+ 0|1)
+ do_start
+ case "$?" in
+ 0) log_end_msg 0 ;;
+ 1) log_end_msg 1 ;; # Old process is still running
+ *) log_end_msg 1 ;; # Failed to start
+ esac
+ ;;
+ *)
+ # Failed to stop
+ log_end_msg 1
+ ;;
+ esac
+ ;;
+ *)
+ #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
+ echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
+ exit 3
+ ;;
+esac
+
+:
+.
+ chmod 755 $out
+}
+pp_backend_deb_function() {
+ case "$1" in
+ pp_mkgroup) cat<<'.';;
+ /usr/sbin/groupmod "$1" 2>/dev/null && return 0
+ /usr/sbin/groupadd "$1"
+.
+ pp_mkuser:depends) echo pp_mkgroup;;
+ pp_mkuser) cat<<'.';;
+ pp_tmp_system=
+ id -u "$1" >/dev/null 2>/dev/null && return 0
+ # deb 3.1's useradd changed API in 4.0. Gah!
+ /usr/sbin/useradd --help 2>&1 | /bin/grep -q .--system &&
+ pp_tmp_system=--system
+ pp_mkgroup "${2:-$1}" || return 1
+ /usr/sbin/useradd \
+ -g "${2:-$1}" \
+ -d "${3:-/nonexistent}" \
+ -s "${4:-/bin/false}" \
+ $pp_tmp_system \
+ "$1"
+.
+ pp_havelib) cat<<'.';;
+ for pp_tmp_dir in `echo "/usr/lib:/lib${3:+:$3}" | tr : ' '`; do
+ test -r "$pp_tmp_dir/lib$1.so{$2:+.$2}" && return 0
+ done
+ return 1
+.
+ *) false;;
+ esac
+}
+
+pp_platforms="$pp_platforms kit"
+
+pp_backend_kit_detect () {
+ test x"$1" = x"OSF1"
+}
+
+pp_backend_kit_init () {
+ pp_kit_name=
+ pp_kit_package=
+ pp_kit_desc=
+ pp_kit_version=
+ pp_kit_subset=
+ pp_readlink_fn=pp_ls_readlink
+ pp_kit_startlevels="2 3"
+ pp_kit_stoplevels="0 2 3"
+}
+
+pp_backend_kit () {
+ typeset mi_file k_file svc outfile
+ typeset desc
+
+ pp_backend_kit_names > /dev/null
+
+ if test -z "$pp_kit_desc"; then
+ pp_kit_desc="$description"
+ fi
+
+ mi_file="$pp_wrkdir/$pp_kit_subset.mi"
+ k_file="$pp_wrkdir/$pp_kit_subset.k"
+ scp_file="$pp_wrkdir/$pp_kit_subset.scp"
+
+ desc="${pp_kit_desc:-$description}"
+
+ cat <<-. >> $k_file
+ NAME='$name'
+ CODE=$pp_kit_name
+ VERS=$pp_kit_version
+ MI=$mi_file
+ COMPRESS=0
+ %%
+ $pp_kit_subset . 0 '$desc'
+.
+
+ if test -n "$pp_services"; then
+ for svc in $pp_services; do
+ pp_kit_make_service $svc
+ pp_prepend $pp_wrkdir/%preun.run <<-.
+ /sbin/init.d/$svc stop
+.
+ done
+ fi
+
+ pp_backend_kit_make_mi "$mi_file"
+ pp_backend_kit_make_scp
+ #rm -rf $pp_wrkdir/kit_dest
+ mkdir -p $pp_wrkdir/kit_dest
+ pp_backend_kit_kits $k_file $pp_opt_destdir $pp_wrkdir/kit_dest
+ tar cvf $pp_wrkdir/$pp_kit_subset.tar -C $pp_wrkdir/kit_dest .
+ gzip -c $pp_wrkdir/$pp_kit_subset.tar > $pp_wrkdir/$pp_kit_subset.tar.gz
+ #rm -rf $pp_wrkdir/$pp_kit_subset.tar $pp_wrkdir/scps
+}
+
+pp_backend_kit_make_mi () {
+ # XXX this information should go into the .inv files
+ typeset t m o g f p st line dm
+ while read t m o g f p st; do
+ case $t in
+ f|d)
+ echo "0 .$p $pp_kit_subset"
+ echo " chmod $m $p" >> $pp_wrkdir/%post.run
+ if [ x"$o" = x"-" ] ; then
+ echo " chown root $p" >> $pp_wrkdir/%post.run
+ else
+ echo " chown $o $p" >> $pp_wrkdir/%post.run
+ fi
+ if [ x"$g" = x"-" ] ; then
+ echo " chgrp 0 $p" >> $pp_wrkdir/%post.run
+ else
+ echo " chgrp $g $p" >> $pp_wrkdir/%post.run
+ fi
+ ;;
+ s)
+ echo " ln -s $st $p" >> $pp_wrkdir/%post.run
+ echo " rm -f $p" >> $pp_wrkdir/%preun.run
+ ;;
+ esac
+ done < $pp_wrkdir/%files.run | sort -k3 |uniq > $1
+}
+
+
+pp_backend_kit_make_scp () {
+ scpdir="$pp_wrkdir/scps"
+ mkdir "$scpdir" && touch "$scpdir"/$pp_kit_subset.scp
+ cat <<EOF >"$scpdir"/$pp_kit_subset.scp
+
+ . /usr/share/lib/shell/libscp
+
+ case "\$ACT" in
+ PRE_L)
+ STL_ScpInit
+
+
+
+ ;;
+ POST_L)
+ STL_ScpInit
+ STL_LinkCreate
+EOF
+
+ cat $pp_wrkdir/%post.run >>"$scpdir"/$pp_kit_subset.scp
+ cat >>"$scpdir"/$pp_kit_subset.scp <<EOF
+ ;;
+ PRE_D)
+ STL_ScpInit
+ STL_LinkRemove
+EOF
+ cat $pp_wrkdir/%preun.run >>"$scpdir"/$pp_kit_subset.scp
+ cat >>"$scpdir"/$pp_kit_subset.scp <<EOF
+ ;;
+ POST_D)
+
+ ;;
+ C)
+ STL_ScpInit
+
+ case "\$1" in
+ INSTALL)
+ echo "Installation of the \$_DESC (\$_SUB) subset is complete."
+ ;;
+ DELETE)
+ ;;
+ esac
+
+ ;;
+ V)
+
+ ;;
+ esac
+
+ exit 0
+EOF
+ chmod 744 "$scpdir"/$pp_kit_subset.scp
+}
+
+
+pp_backend_kit_cleanup () {
+ :
+}
+
+pp_backend_kit_names () {
+ if test -z "$pp_kit_name"; then
+ pp_warn "pp_kit_name not specified, using XXX"
+ pp_kit_name=XXX
+ fi
+ case "$pp_kit_name" in
+ ???) : ok;;
+ *) pp_error "\$pp_kit_name $pp_kit_name must be three characters";;
+ esac
+ if test -z "$pp_kit_package"; then
+ pp_warn "pp_kit_package not specified, using YYYY"
+ pp_kit_package=YYYY
+ fi
+ if test -z "$pp_kit_version"; then
+ pp_kit_version=`echo $version|tr -d '.a-zA-Z'`
+ fi
+ case "$pp_kit_version" in
+ [0-9]) pp_kit_version="${pp_kit_version}00";;
+ [0-9][0-9]) pp_kit_version="${pp_kit_version}0";;
+ [0-9][0-9][0-9]) : ok;;
+ *) pp_error "\$pp_kit_version $pp_kit_version must be three digits, ";;
+ esac
+ if test -z "$pp_kit_subset"; then
+ pp_kit_subset="$pp_kit_name$pp_kit_package$pp_kit_version"
+ fi
+ echo "$pp_kit_subset.tar.gz"
+}
+
+pp_backend_kit_install_script () {
+ typeset pkgname platform
+
+ pkgname=`pp_backend_kit_names`
+ platform="`pp_backend_kit_probe`"
+
+ echo "#!/bin/sh"
+ pp_install_script_common
+ cat <<.
+
+ cpt_to_tags () {
+ test x"\$*" = x"all" && set -- $pp_components
+ for cpt
+ do
+ echo "$name.\$cpt"
+ done
+ }
+
+ test \$# -eq 0 && usage
+ op="\$1"; shift
+
+ case "\$op" in
+ list-components)
+ test \$# -eq 0 || usage \$op
+ echo "$pp_components"
+ ;;
+ list-services)
+ test \$# -eq 0 || usage \$op
+ echo "$pp_services"
+ ;;
+ list-files)
+ test \$# -ge 1 || usage \$op
+ echo \${PP_PKGDESTDIR:-.}/$pkgname
+ ;;
+ install)
+ test \$# -ge 1 || usage \$op
+ verbose echo \${PP_PKGDESTDIR:-\`pwd\`}/$pkgname \`cpt_to_tags "\$@"\`
+ #verbose swinstall -x verbose=0 -s \${PP_PKGDESTDIR:-\`pwd\`}/$pkgname \`cpt_to_tags "\$@"\`
+ ;;
+ uninstall)
+ test \$# -ge 1 || usage \$op
+ verbose echo \`cpt_to_tags "\$@"\`
+ #verbose swremove -x verbose=0 \`cpt_to_tags "\$@"\`
+ ;;
+ start|stop)
+ test \$# -ge 1 || usage \$op
+ ec=0
+ for svc
+ do
+ verbose /sbin/init.d/\$svc \$op
+ [ \$? -eq 4 -o \$? -eq 0 ] || ec=1
+ done
+ exit \$ec
+ ;;
+ print-platform)
+ echo "$platform"
+ ;;
+ *)
+ usage
+ ;;
+ esac
+.
+}
+
+pp_backend_kit_function () {
+ case "$1" in
+ pp_mkgroup) cat <<'.';;
+ grep "^$1:" /etc/group >/dev/null ||
+ /usr/sbin/groupadd $1
+.
+ pp_mkuser) cat <<'.';;
+ eval user=\$$#
+ grep "^$user:" /etc/passwd >/dev/null ||
+ /usr/sbin/useradd -s /usr/bin/false "$@"
+.
+ pp_havelib) cat <<'.';;
+ for dir in `echo /usr/lib${3+:$3} | tr : ' '`; do
+ test -r "$dir/lib$1.${2-sl}" && return 0
+ done
+ return 1
+.
+ *) pp_error "unknown function request: $1";;
+ esac
+}
+
+pp_backend_kit_init_svc_vars () {
+ :
+}
+
+pp_backend_kit_probe () {
+ echo tru64-`uname -r | sed 's/V\([0-9]*\)\.\([0-9]*\)/\1\2/'`
+}
+
+pp_kit_service_group_script () {
+ typeset grp svcs scriptpath out
+ grp="$1"
+ svcs="$2"
+ scriptpath="/sbin/init.d/$grp"
+ out="$pp_destdir$scriptpath"
+
+ pp_add_file_if_missing $scriptpath run 755 || return 0
+
+ cat <<-. > $out
+ #!/sbin/sh
+ # generated by pp $pp_version
+ svcs="$svcs"
+.
+
+cat <<-'.' >> $out
+ #-- starts services in order.. stops them all if any break
+ pp_start () {
+ undo=
+ for svc in $svcs; do
+ /sbin/init.d/$svc start
+ case $? in
+ 0|4)
+ undo="$svc $undo"
+ ;;
+ *)
+ if test -n "$undo"; then
+ for svc in $undo; do
+ /sbin/init.d/$svc stop
+ done
+ return 1
+ fi
+ ;;
+ esac
+ done
+ return 0
+ }
+
+ #-- stops services in reverse
+ pp_stop () {
+ reverse=
+ for svc in $svcs; do
+ reverse="$svc $reverse"
+ done
+ rc=0
+ for svc in $reverse; do
+ /sbin/init.d/$svc stop || rc=$?
+ done
+ return $rc
+ }
+
+ case "$1" in
+ start_msg) echo "Starting $svcs";;
+ stop_msg) echo "Stopping $svcs";;
+ start) pp_start;;
+ stop) pp_stop;;
+ *) echo "usage: $0 {start|stop|start_msg|stop_msg}"
+ exit 1;;
+ esac
+.
+}
+
+pp_kit_service_script () {
+ typeset svc scriptpath out
+
+ svc="$1"
+ scriptpath="/sbin/init.d/$svc"
+
+ pp_load_service_vars "$svc"
+
+ test -n "$user" -a x"$user" != x"root" &&
+ cmd="SHELL=/usr/bin/sh /usr/bin/su $user -c \"exec `echo $cmd | sed -e 's,[$\\\`],\\&,g'`\""
+ if test -z "$pidfile"; then
+ pidfile="/var/run/$svc.pid"
+ cmd="$cmd & echo \$! > \$pidfile"
+ fi
+
+ pp_add_file_if_missing $scriptpath run 755
+
+ cat <<-. > $pp_destdir$scriptpath
+ svc="$svc"
+ pidfile="$pidfile"
+
+ pp_start () {
+ $cmd
+ }
+.
+ cat <<-'.' >>$pp_destdir$scriptpath
+ pp_stop () {
+ if test ! -s "$pidfile"; then
+ echo "Unable to stop $svc (no pid file)"
+ return 1
+ else
+ read pid < "$pidfile"
+ if kill -0 "$pid" 2>/dev/null; then
+ if kill -${stop_signal:-TERM} "$pid"; then
+ rm -f "$pidfile"
+ return 0
+ else
+ echo "Unable to stop $svc"
+ return 1
+ fi
+ else
+ rm -f "$pidfile"
+ return 0
+ fi
+ fi
+ }
+
+ pp_running () {
+ if test ! -s "$pidfile"; then
+ return 1
+ else
+ read pid < "$pidfile"
+ kill -0 "$pid" 2>/dev/null
+ fi
+ }
+ case "$1" in
+ start_msg) echo "Starting the $svc service";;
+ stop_msg) echo "Stopping the $svc service";;
+ start)
+ if pp_running; then
+ echo "$svc already running";
+ exit 0
+ elif pp_start; then
+ echo "$svc started";
+ # rc(1M) says we should exit 4, but nobody expects it!
+ exit 0
+ else
+ exit 1
+ fi
+ ;;
+ stop)
+ if pp_stop; then
+ echo "$svc stopped";
+ exit 0
+ else
+ exit 1
+ fi
+ ;;
+ *) echo "usage: $0 {start|stop|start_msg|stop_msg}"
+ exit 1
+ ;;
+ esac
+.
+}
+
+pp_kit_make_service () {
+ typeset level priority startlevels stoplevels
+ typeset svc svcvar
+
+ svc="$1"
+ svcvar=`pp_makevar $svc`
+
+ #-- don't do anything if the script exists
+ if test -s "$pp_destdir/sbin/init.d/$svc"; then
+ pp_error "$pp_destdir/sbin/init.d/$svc exists"
+ return
+ fi
+
+ # symlink the script, depending on the priorities chosen
+ eval priority='${pp_kit_priority_'$svcvar'}'
+ test -z "$priority" && priority="${pp_kit_priority:-50}"
+
+ eval startlevels='${pp_kit_startlevels_'$svcvar'}'
+ test -z "$startlevels" && startlevels="$pp_kit_startlevels"
+
+ eval stoplevels='${pp_kit_stoplevels_'$svcvar'}'
+ test -z "$stoplevels" && stoplevels="$pp_kit_stoplevels"
+
+ # create the script and config file
+ pp_kit_service_script $svc
+
+ # fix the priority up
+ case "$priority" in
+ ???) :;;
+ ??) priority=0$priority;;
+ ?) priority=00$priority;;
+ esac
+
+ if test x"$stoplevels" = x"auto"; then
+ stoplevels=
+ test -z "$startlevels" || for level in $startlevels; do
+ stoplevels="$stoplevels `expr $level - 1`"
+ done
+ fi
+
+ # create the symlinks
+ test -z "$startlevels" || for level in $startlevels; do
+ echo " ln -s /sbin/init.d/$svc /sbin/rc$level.d/S$priority$svc" >>$pp_wrkdir/%post.run
+ echo " rm /sbin/rc$level.d/S$priority$svc" >>$pp_wrkdir/%preun.run
+ done
+ test -z "$stoplevels" || for level in $stoplevels; do
+ echo " ln -s /sbin/init.d/$svc /sbin/rc$level.d/K$priority$svc" >>$pp_wrkdir/%post.run
+ echo " rm -f /sbin/rc$level.d/K$priority$svc" >>$pp_wrkdir/%preun.run
+ done
+}
+
+
+
+
+pp_backend_kit_sizes () {
+ awk '
+ BEGIN { root = usr = var = 0; }
+ {
+ if (substr($9, 1, 1) != "l")
+ if (substr($10, 1, 6) == "./var/")
+ var += $2;
+ else if (substr($10, 1, 10) == "./usr/var/")
+ var += $2
+ else if (substr($10, 1, 6) == "./usr/")
+ usr += $2
+ else
+ root += $2
+ }
+ END { printf "%d\t%d\t%d", root, usr, var }
+ ' "$@"
+}
+
+pp_kit_kits_global () {
+ line=`sed -n '/^%%/q;/^'$2'=/{s/^'$2'=//p;q;}' <"$1"`
+ test -z "$line" && return 1
+ eval "echo $line"
+ :
+}
+
+pp_backend_kit_kits () {
+ typeset KITFILE FROMDIR TODIR
+ typeset SCPDIR
+
+ SCPDIR="$pp_wrkdir/scps"
+
+ PATH="/usr/lbin:/usr/bin:/etc:/usr/ucb:$PATH"; export PATH # XXX
+ #umask 2 # XXX
+
+ test $# -ge 3 || pp_die "pp_backend_kit_kits: too few arguments"
+ KITFILE="$1"; shift
+ FROMDIR="$1"; shift
+ TODIR="$1"; shift
+
+ test -f "$KITFILE" || pp_die "$KITFILE not found"
+ test -d "$FROMDIR" || pp_die "$FROMDIR not found"
+ test -d "$TODIR" || pp_die "$TODIR not found"
+
+ INSTCTRL="$TODIR/instctrl"
+ mkdir -p "$INSTCTRL" || pp_die "cannot create instctrl directory"
+ chmod 775 "$INSTCTRL"
+
+ grep "%%" $KITFILE > /dev/null || pp_die "no %% in $KITFILE"
+
+ typeset NAME CODE VERS MI ROOT COMPRESS
+ typeset S_LIST ALLSUBS
+
+ NAME=`pp_kit_kits_global "$KITFILE" NAME` || pp_die "no NAME in $KITFILE"
+ CODE=`pp_kit_kits_global "$KITFILE" CODE` || pp_die "no CODE in $KITFILE"
+ VERS=`pp_kit_kits_global "$KITFILE" VERS` || pp_die "no VERS in $KITFILE"
+ MI=`pp_kit_kits_global "$KITFILE" MI` || pp_die "no MI in $KITFILE"
+ ROOT=`pp_kit_kits_global "$KITFILE" ROOT`
+ COMPRESS=`pp_kit_kits_global "$KITFILE" COMPRESS`
+
+ test -f "$MI" || pp_die "Inventory file $MI not found"
+
+ case "$ROOT" in
+ *ROOT)
+ test -f "$TODIR/$ROOT" ||
+ pp_die "Root image $ROOT not found in $TODIR" ;;
+ esac
+
+ ALLSUBS=`awk 'insub==1 {print $1} /^%%/ {insub=1}' <"$KITFILE"`
+ test $# -eq 0 && set -- $ALLSUBS
+
+ pp_debug "Creating $# $NAME subsets."
+ pp_debug "ALLSUBS=<$ALLSUBS>"
+
+ if test x"$COMPRESS" = x"1"; then
+ COMPRESS=:
+ else
+ COMPRESS=false
+ fi
+
+ #rm -f *.ctrl Volume*
+
+ for SUB
+ do
+ test -z "$SUB" && pp_die "SUB is empty"
+
+ typeset INV CTRL ROOTSIZE USRSIZE VARSIZE TSSUB
+ #rm -f Volume*
+ case $SUB in
+ .*) :;;
+ *) pp_verbose rm -f "$TODIR/$SUB"* "$INSTCTRL/$SUB"*;;
+ esac
+
+ TSSUB="$pp_wrkdir/ts.$SUB"
+
+ pp_debug "kits: Subset $SUB"
+
+ INV="$SUB.inv"
+ CTRL="$SUB.ctrl"
+ pp_debug "kits: Generating media creation information..."
+
+ # Invcutter takes as input
+ # SUB dir/path
+ # and generates stl_inv(4) files, like this
+ # f 0 00000 0 0 100644 2/11/09 010 f dir/path none SUB
+ grep " $SUB\$" "$MI" |
+ pp_verbose /usr/lbin/invcutter \
+ -v "$VERS" -f "$FROMDIR" > "$INSTCTRL/$INV" ||
+ pp_die "failed to create $INSTCTRL/$INV"
+ chmod 664 "$INSTCTRL/$INV"
+
+ pp_backend_kit_sizes "$INSTCTRL/$INV" > "$pp_wrkdir/kit.sizes"
+ read ROOTSIZE USRSIZE VARSIZE < "$pp_wrkdir/kit.sizes"
+
+ # Prefix each line with $FROMDIR. This will be stripped
+ awk '$1 != "d" {print from $10}' from="$FROMDIR/" \
+ > "$TSSUB" < "$INSTCTRL/$INV" ||
+ pp_die "failed"
+
+ NVOLS=0
+
+ pp_debug "kits: Creating $SUB control file..."
+
+ sed '1,/^%%/d;/^'"$SUB"'/{p;q;}' < "$KITFILE" > "$pp_wrkdir/kit.line"
+ read _SUB _IGNOR DEPS FLAGS DESC < "$pp_wrkdir/kit.line"
+ if test -z "$_SUB"; then
+ pp_warn "No such subset $SUB in $KITFILE"
+ continue
+ fi
+ DEPS=`echo $DEPS | tr '|' ' '`
+ case $FLAGS in
+ FLGEXP*) pp_verbose FLAGS='"${'"$FLAGS"'}"' ;;
+ esac
+ case $DESC in
+ *%*) DESC=`echo $DESC|awk -F% '{printf "%-36s%%%s\n", $1, $2}'`;;
+ esac
+
+ cat > "$INSTCTRL/$CTRL" <<-.
+ NAME='$NAME $SUB'
+ DESC=$DESC
+ ROOTSIZE=$ROOTSIZE
+ USRSIZE=$USRSIZE
+ VARSIZE=$VARSIZE
+ NVOLS=1:$NVOLS
+ MTLOC=1:$TLOC
+ DEPS="$DEPS"
+ FLAGS=$FLAGS
+.
+ chmod 664 "$INSTCTRL/$CTRL"
+
+ pp_debug "kits: Making tar image"
+
+ pp_verbose tar cfPR "$TODIR/$SUB" "$FROMDIR/" "$TSSUB" ||
+ pp_error "problem creating kit file"
+
+ if $COMPRESS; then
+ pp_debug "kits: Compressing"
+ (cd "$TODIR" && compress -f -v "$SUB") ||
+ pp_die "problem compressing $TODIR/$SUB"
+ SPC=`expr $SUB : '\(...\).*'` # first three characters
+ SVC=`expr $SUB : '.*\(...\)'` # last three characters
+ : > "$INSTCTRL/$SPC$SVC.comp"
+ chmod 664 "$INSTCTRL/$SPC$SVC.comp"
+ pp_debug "kits: Padding compressed file to 10kB" # wtf?
+ rm -f "$TODIR/$SUB"
+ pp_verbose \
+ dd if="$TODIR/$SUB.Z" of="$TODIR/$SUB" bs=10k conv=sync ||
+ pp_die "problem moving compressed file"
+ rm -f "$TODIR/$SUB.Z"
+ fi
+ chmod 664 "$TODIR/$SUB"
+
+ if test -f "$SCPDIR/$SUB.scp"; then
+ cp "$SCPDIR/$SUB.scp" "$INSTCTRL/$SUB.scp"
+ chmod 755 "$INSTCTRL/$SUB.scp"
+ else
+ pp_debug "kits: null subset control program for $SUB"
+ : > "$INSTCTRL/$SUB.scp"
+ chmod 744 "$INSTCTRL/$SUB.scp"
+ fi
+
+ pp_debug "kits: Finished creating media image for $SUB"
+ done
+
+ pp_debug "kits: Creating $CODE.image"
+
+ case "$ROOT" in
+ *ROOT) ALLSUBS="$ROOT $ALLSUBS"
+ ;;
+ esac
+
+ (cd "$TODIR" && sum $ALLSUBS) > "$INSTCTRL/$CODE.image"
+ chmod 664 "$INSTTRL/$CODE.image"
+ pp_debug "kits: Creating INSTCTRL"
+ (cd "$INSTCTRL" && tar cpvf - *) > "$TODIR/INSTCTRL"
+ chmod 664 "$TODIR/INSTCTRL"
+ cp "$INSTCTRL/$CODE.image" "$TODIR/$CODE.image"
+ chmod 664 "$TODIR/$CODE.image"
+
+ pp_debug "kits: Media image production complete"
+}
+
+pp_platforms="$pp_platforms rpm"
+
+pp_backend_rpm_detect () {
+ test x"$1" = x"Linux" -a ! -f /etc/debian_version
+}
+
+pp_backend_rpm_init () {
+
+ pp_rpm_version=
+ pp_rpm_summary=
+ pp_rpm_description=
+ pp_rpm_group="Applications/Internet"
+ pp_rpm_license="Unspecified"
+ pp_rpm_vendor=
+ pp_rpm_url=
+ pp_rpm_packager=
+ pp_rpm_provides=
+ pp_rpm_requires=
+ pp_rpm_requires_pre=
+ pp_rpm_requires_post=
+ pp_rpm_requires_preun=
+ pp_rpm_requires_postun=
+ pp_rpm_release=
+ pp_rpm_epoch=
+ pp_rpm_dev_group="Development/Libraries"
+ pp_rpm_dbg_group="Development/Tools"
+ pp_rpm_doc_group="Documentation"
+ pp_rpm_dev_description=
+ pp_rpm_dbg_description=
+ pp_rpm_doc_description=
+ pp_rpm_dev_requires=
+ pp_rpm_dev_requires_pre=
+ pp_rpm_dev_requires_post=
+ pp_rpm_dev_requires_preun=
+ pp_rpm_dev_requires_postun=
+ pp_rpm_dbg_requires=
+ pp_rpm_dbg_requires_pre=
+ pp_rpm_dbg_requires_post=
+ pp_rpm_dbg_requires_preun=
+ pp_rpm_dbg_requires_postun=
+ pp_rpm_doc_requires=
+ pp_rpm_doc_requires_pre=
+ pp_rpm_doc_requires_post=
+ pp_rpm_doc_requires_preun=
+ pp_rpm_doc_requires_postun=
+ pp_rpm_dev_provides=
+ pp_rpm_dbg_provides=
+ pp_rpm_doc_provides=
+
+ pp_rpm_autoprov=
+ pp_rpm_autoreq=
+ pp_rpm_autoreqprov=
+
+ pp_rpm_dbg_pkgname=debug
+ pp_rpm_dev_pkgname=devel
+ pp_rpm_doc_pkgname=doc
+
+ pp_rpm_defattr_uid=root
+ pp_rpm_defattr_gid=root
+
+ pp_rpm_detect_arch
+ pp_rpm_detect_distro
+ pp_rpm_rpmbuild=`pp_rpm_detect_rpmbuild`
+
+ # SLES8 doesn't always come with readlink
+ test -x /usr/bin/readlink -o -x /bin/readlink ||
+ pp_readlink_fn=pp_ls_readlink
+}
+
+pp_rpm_detect_arch () {
+ pp_rpm_arch=auto
+
+ #-- Find the default native architecture that RPM is configured to use
+ cat <<-. >$pp_wrkdir/dummy.spec
+ Name: dummy
+ Version: 1
+ Release: 1
+ Summary: dummy
+ Group: ${pp_rpm_group}
+ License: ${pp_rpm_license}
+ %description
+ dummy
+.
+ $pp_opt_debug && cat $pp_wrkdir/dummy.spec
+ pp_rpm_arch_local=`rpm -q --qf '%{arch}\n' --specfile $pp_wrkdir/dummy.spec`
+ rm $pp_wrkdir/dummy.spec
+
+ #-- Ask the kernel what machine architecture is in use
+ local arch
+ for arch in "`uname -m`" "`uname -p`"; do
+ case "$arch" in
+ i?86)
+ pp_rpm_arch_std=i386
+ break
+ ;;
+ x86_64|ppc|ppc64|ia64|s390|s390x)
+ pp_rpm_arch_std="$arch"
+ break
+ ;;
+ powerpc)
+ # Probably AIX
+ case "`/usr/sbin/lsattr -El proc0 -a type -F value`" in
+ PowerPC_POWER*) pp_rpm_arch_std=ppc64;;
+ *) pp_rpm_arch_std=ppc;;
+ esac
+ break
+ ;;
+ *) pp_rpm_arch_std=unknown
+ ;;
+ esac
+ done
+
+ #-- Later on, when files are processed, we use 'file' to determine
+ # what platform ABIs are used. This is used when pp_rpm_arch == auto
+ pp_rpm_arch_seen=
+}
+
+pp_rpm_detect_distro () {
+ pp_rpm_distro=
+ if test -f /etc/whitebox-release; then
+ pp_rpm_distro=`awk '
+ /^White Box Enterprise Linux release/ { print "wbel" $6; exit; }
+ ' /etc/whitebox-release`
+ elif test -f /etc/mandrakelinux-release; then
+ pp_rpm_distro=`awk '
+ /^Mandrakelinux release/ { print "mand" $3; exit; }
+ ' /etc/mandrake-release`
+ elif test -f /etc/mandrake-release; then
+ pp_rpm_distro=`awk '
+ /^Linux Mandrake release/ { print "mand" $4; exit; }
+ /^Mandrake Linux release/ { print "mand" $4; exit; }
+ ' /etc/mandrake-release`
+ elif test -f /etc/fedora-release; then
+ pp_rpm_distro=`awk '
+ /^Fedora Core release/ { print "fc" $4; exit; }
+ /^Fedora release/ { print "f" $3; exit; }
+ ' /etc/fedora-release`
+ elif test -f /etc/redhat-release; then
+ pp_rpm_distro=`awk '
+ /^Red Hat Enterprise Linux/ { print "rhel" $7; exit; }
+ /^CentOS release/ { print "centos" $3; exit; }
+ /^CentOS Linux release/ { print "centos" $4; exit; }
+ /^Red Hat Linux release/ { print "rh" $5; exit; }
+ ' /etc/redhat-release`
+ elif test -f /etc/SuSE-release; then
+ pp_rpm_distro=`awk '
+ /^SuSE Linux [0-9]/ { print "suse" $3; exit; }
+ /^SUSE LINUX [0-9]/ { print "suse" $3; exit; }
+ /^openSUSE [0-9]/ { print "suse" $2; exit; }
+ /^S[uU]SE Linux Enterprise Server [0-9]/ { print "sles" $5; exit; }
+ /^S[uU]SE LINUX Enterprise Server [0-9]/ { print "sles" $5; exit; }
+ /^SuSE SLES-[0-9]/ { print "sles" substr($2,6); exit; }
+ ' /etc/SuSE-release`
+ elif test -f /etc/pld-release; then
+ pp_rpm_distro=`awk '
+ /^[^ ]* PLD Linux/ { print "pld" $1; exit; }
+ ' /etc/pld-release`
+ elif test X"`uname -s 2>/dev/null`" = X"AIX"; then
+ local r v
+ r=`uname -r`
+ v=`uname -v`
+ pp_rpm_distro="aix$v$r"
+ fi
+ pp_rpm_distro=`echo $pp_rpm_distro | tr -d .`
+ test -z "$pp_rpm_distro" &&
+ pp_warn "unknown distro"
+}
+
+pp_rpm_detect_rpmbuild () {
+ local cmd
+ for cmd in rpmbuild rpm; do
+ if `which $cmd > /dev/null 2>&1`; then
+ echo $cmd
+ return 0
+ fi
+ done
+
+ pp_error "Could not find rpmbuild"
+ # Default to `rpmbuild` in case it magically appears
+ echo rpmbuild
+ return 1
+}
+
+pp_rpm_label () {
+ local label arg
+ label="$1"; shift
+ for arg
+ do
+ test -z "$arg" || echo "$label: $arg"
+ done
+}
+
+pp_rpm_writefiles () {
+ local _l t m o g f p st fo farch
+ while read t m o g f p st; do
+ _l="$p"
+ test $t = d && _l="%dir ${_l%/}/"
+ if test $t = s; then
+ # rpm warns if %attr contains a mode for symlinks
+ m=-
+ elif test x"$m" = x"-"; then
+ case "$t" in
+ d) m=755;;
+ f) m=644;;
+ esac
+ fi
+ test x"$o" = x"-" && o="${pp_rpm_defattr_uid:-root}"
+ test x"$g" = x"-" && g="${pp_rpm_defattr_gid:-root}"
+ _l="%attr($m,$o,$g) $_l"
+
+ if test "$t" = "f" -a x"$pp_rpm_arch" = x"auto"; then
+ fo=`file "${pp_destdir}$p" 2>/dev/null`
+ #NB: The following should match executables and shared objects,
+ #relocatable objects. It will not match .a files however.
+ case "$fo" in
+ *": ELF 32-bit LSB "*", Intel 80386"*)
+ farch=i386;;
+ *": ELF 64-bit LSB "*", AMD x86-64"*|\
+ *": ELF 64-bit LSB "*", x86-64"*)
+ farch=x86_64;;
+ *": ELF 32-bit MSB "*", PowerPC"*)
+ farch=ppc;;
+ *": ELF 64-bit MSB "*", 64-bit PowerPC"*)
+ farch=ppc64;;
+ *": ELF 64-bit LSB "*", IA-64"*)
+ farch=ia64;;
+ *": ELF 32-bit MSB "*", IBM S/390"*)
+ farch=s390;;
+ *": ELF 64-bit MSB "*", IBM S/390"*)
+ farch=s390x;;
+ *"executable (RISC System/6000)"*)
+ farch=ppc;;
+ *"64-bit XCOFF executable"*)
+ farch=ppc64;;
+ *" ELF "*)
+ farch=ELF;;
+ *)
+ farch=noarch;;
+ esac
+ # If file(1) doesn't provide enough info, try readelf(1)
+ if test "$farch" = "ELF"; then
+ fo=`readelf -h "${pp_destdir}$p" | awk '{if ($1 == "Class:") {class=$2} else if ($1 == "Machine:") {machine=$0; sub(/^ *Machine: */, "", machine)}} END {print class " " machine}' 2>/dev/null`
+ case "$fo" in
+ "ELF32 Intel 80386")
+ farch=i386;;
+ "ELF64 "*[xX]"86-64")
+ farch=x86_64;;
+ "ELF32 PowerPC")
+ farch=ppc;;
+ "ELF64 PowerPC"*)
+ farch=ppc64;;
+ "ELF64 IA-64")
+ farch=ia64;;
+ "ELF32 IBM S/390")
+ farch=s390;;
+ "ELF64 IBM S/390")
+ farch=s390x;;
+ *)
+ farch=noarch;;
+ esac
+ fi
+ pp_debug "file: $fo -> $farch"
+ test x"$farch" = x"noarch" || pp_add_to_list pp_rpm_arch_seen $farch
+ fi
+
+ case $f in *v*) _l="%config(noreplace) $_l";; esac
+ echo "$_l"
+ done
+ echo
+}
+
+pp_rpm_subname () {
+ case "$1" in
+ run) : ;;
+ dbg) echo "${2}${pp_rpm_dbg_pkgname}";;
+ dev) echo "${2}${pp_rpm_dev_pkgname}";;
+ doc) echo "${2}${pp_rpm_doc_pkgname}";;
+ *) pp_error "unknown component '$1'";
+ esac
+}
+
+pp_rpm_depend () {
+ local _name _vers
+ while read _name _vers; do
+ case "$_name" in ""| "#"*) continue ;; esac
+ echo "Requires: $_name ${_vers:+>= $_vers}"
+ done
+}
+
+pp_rpm_conflict () {
+ local _name _vers
+ while read _name _vers; do
+ case "$_name" in ""| "#"*) continue ;; esac
+ echo "Conflicts: $_name ${_vers:+>= $_vers}"
+ done
+}
+
+pp_rpm_override_requires () {
+ local orig_find_requires
+
+ if test -z "$pp_rpm_depend_filter_cmd"; then
+ return 0
+ fi
+
+ orig_find_requires=`rpm --eval '%{__find_requires}'`
+ cat << EOF > "$pp_wrkdir/filtered-find-requires"
+$orig_find_requires \$@ | $pp_rpm_depend_filter_cmd
+EOF
+ chmod +x "$pp_wrkdir/filtered-find-requires"
+ echo "%define __find_requires $pp_wrkdir/filtered-find-requires"
+ # Might be necessary for old versions of RPM? Not for 4.4.2.
+ #echo "%define _use_internal_dependency_generator 0"
+}
+
+pp_backend_rpm () {
+ local cmp specfile _summary _group _desc _pkg _subname svc _script
+
+ specfile=$pp_wrkdir/$name.spec
+ : > $specfile
+
+ #-- force existence of a 'run' component
+ pp_add_component run
+ : >> $pp_wrkdir/%files.run
+
+ if test -z "$pp_rpm_arch"; then
+ pp_error "Unknown RPM architecture"
+ return 1
+ fi
+
+ #-- Write the header components of the RPM spec file
+ cat <<-. >>$specfile
+ Name: ${pp_rpm_name:-$name}
+ Version: ${pp_rpm_version:-$version}
+ Release: ${pp_rpm_release:-1}
+ Summary: ${pp_rpm_summary:-$summary}
+ Group: ${pp_rpm_group}
+ License: ${pp_rpm_license}
+.
+ pp_rpm_label "URL" "$pp_rpm_url" >>$specfile
+ pp_rpm_label "Vendor" "${pp_rpm_vendor:-$vendor}" >>$specfile
+ pp_rpm_label "Packager" "$pp_rpm_packager" >>$specfile
+ pp_rpm_label "Provides" "$pp_rpm_provides" >>$specfile
+ pp_rpm_label "Requires(pre)" "$pp_rpm_requires_pre" >>$specfile
+ pp_rpm_label "Requires(post)" "$pp_rpm_requires_post" >>$specfile
+ pp_rpm_label "Requires(preun)" "$pp_rpm_requires_preun" >>$specfile
+ pp_rpm_label "Requires(postun)" "$pp_rpm_requires_postun" >>$specfile
+ pp_rpm_label "AutoProv" "$pp_rpm_autoprov" >>$specfile
+ pp_rpm_label "AutoReq" "$pp_rpm_autoreq" >>$specfile
+ pp_rpm_label "AutoReqProv" "$pp_rpm_autoreqprov" >>$specfile
+
+ test -n "$pp_rpm_serial" && pp_warn "pp_rpm_serial deprecated"
+ if test -n "$pp_rpm_epoch"; then
+ #-- Epoch was introduced in RPM 2.5.6
+ case `$pp_rpm_rpmbuild --version 2>/dev/null` in
+ 1.*|2.[0-5].*|2.5.[0-5])
+ pp_rpm_label "Serial" $pp_rpm_epoch >>$specfile;;
+ *)
+ pp_rpm_label "Epoch" $pp_rpm_epoch >>$specfile;;
+ esac
+ fi
+
+ if test -n "$pp_rpm_requires"; then
+ pp_rpm_label "Requires" "$pp_rpm_requires" >>$specfile
+ elif test -s $pp_wrkdir/%depend.run; then
+ pp_rpm_depend < $pp_wrkdir/%depend.run >> $specfile
+ fi
+ if test -s $pp_wrkdir/%conflict.run; then
+ pp_rpm_conflict < $pp_wrkdir/%conflict.run >> $specfile
+ fi
+
+ pp_rpm_override_requires >> $specfile
+
+ cat <<-. >>$specfile
+
+ %description
+ ${pp_rpm_description:-$description}
+.
+
+ for cmp in $pp_components; do
+ case $cmp in
+ run) continue;;
+ dev) _summary="development tools for $pp_rpm_summary"
+ _group="$pp_rpm_dev_group"
+ _desc="${pp_rpm_dev_description:-Development libraries for $name. $pp_rpm_description.}"
+ ;;
+ doc) _summary="documentation for $pp_rpm_summary"
+ _group="$pp_rpm_doc_group"
+ _desc="${pp_rpm_doc_description:-Documentation for $name. $pp_rpm_description.}"
+ ;;
+ dbg) _summary="diagnostic tools for $pp_rpm_summary"
+ _group="$pp_rpm_dbg_group"
+ _desc="${pp_rpm_dbg_description:-Diagnostic tools for $name.}"
+ ;;
+ esac
+
+ _subname=`pp_rpm_subname $cmp`
+ cat <<-.
+
+ %package $_subname
+ Summary: $name $_summary
+ Group: $_group
+.
+ for _script in pre post preun postun; do
+ eval '_pkg="$pp_rpm_'$cmp'_requires_'$_script'"'
+ if test -n "$_pkg"; then
+ eval pp_rpm_label "Requires($_script)" $_pkg
+ fi
+ done
+ eval '_pkg="$pp_rpm_'$cmp'_requires"'
+ if test -n "$_pkg"; then
+ eval pp_rpm_label Requires ${pp_rpm_name:-$name} $_pkg
+ elif test -s $pp_wrkdir/%depend.$cmp; then
+ pp_rpm_depend < $pp_wrkdir/%depend.$cmp >> $specfile
+ fi
+ if test -s $pp_wrkdir/%conflict.$cmp; then
+ pp_rpm_conflict < $pp_wrkdir/%conflict.$cmp >> $specfile
+ fi
+
+ eval '_pkg="$pp_rpm_'$cmp'_provides"'
+ eval pp_rpm_label Provides $_pkg
+
+ cat <<-.
+
+ %description $_subname
+ $_desc
+.
+ done >>$specfile
+
+ #-- NB: we don't put any %prep, %build or %install RPM sections
+ # into the spec file.
+
+ #-- add service start/stop code
+ if test -n "$pp_services"; then
+ pp_rpm_service_install_common >> $pp_wrkdir/%post.run
+
+ #-- record the uninstall commands in reverse order
+ for svc in $pp_services; do
+ pp_load_service_vars $svc
+
+ pp_rpm_service_make_init_script $svc
+
+ #-- append %post code to install the svc
+ pp_rpm_service_install $svc >> $pp_wrkdir/%post.run
+
+ #-- prepend %preun code to uninstall svc
+ # (use files in case vars are modified)
+ pp_rpm_service_remove $svc | pp_prepend $pp_wrkdir/%preun.run
+ done
+ pp_rpm_service_remove_common | pp_prepend $pp_wrkdir/%preun.run
+ fi
+
+ # make convenience service groups
+ if test -n "$pp_service_groups"; then
+ for grp in $pp_service_groups; do
+ pp_rpm_service_group_make_init_script \
+ $grp "`pp_service_get_svc_group $grp`"
+ done
+ fi
+
+ #-- Write the RPM %file sections
+ # (do this after services, since services adds to %files.run)
+ for cmp in $pp_components; do
+ _subname=`pp_rpm_subname $cmp`
+
+ if test -s $pp_wrkdir/%check.$cmp; then
+ echo ""
+ echo "%pre $_subname"
+ cat $pp_wrkdir/%check.$cmp
+ echo : # causes script to exit true by default
+ fi
+
+ if test -s $pp_wrkdir/%files.$cmp; then
+ echo ""
+ echo "%files $_subname"
+ pp_rpm_writefiles < $pp_wrkdir/%files.$cmp
+ fi
+
+ if test -n "$pp_rpm_ghost"; then
+ for ghost in $pp_rpm_ghost; do
+ echo "%ghost $ghost"
+ done
+ fi
+
+ if test -s $pp_wrkdir/%pre.$cmp; then
+ echo ""
+ echo "%pre $_subname"
+ cat $pp_wrkdir/%pre.$cmp
+ echo : # causes script to exit true
+ fi
+
+ if test -s $pp_wrkdir/%post.$cmp; then
+ echo ""
+ echo "%post $_subname"
+ cat $pp_wrkdir/%post.$cmp
+ echo : # causes script to exit true
+ fi
+
+ if test -s $pp_wrkdir/%preun.$cmp; then
+ echo ""
+ echo "%preun $_subname"
+ cat $pp_wrkdir/%preun.$cmp
+ echo : # causes script to exit true
+ fi
+
+ if test -s $pp_wrkdir/%postun.$cmp; then
+ echo ""
+ echo "%postun $_subname"
+ cat $pp_wrkdir/%postun.$cmp
+ echo : # causes script to exit true
+ fi
+ done >>$specfile
+
+ #-- create a suitable work area for rpmbuild
+ cat <<-. >$pp_wrkdir/.rpmmacros
+ %_topdir $pp_wrkdir
+ # XXX Note escaped %% for use in headerSprintf
+ %_rpmfilename %%{ARCH}/%%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
+ .
+ mkdir $pp_wrkdir/RPMS
+ mkdir $pp_wrkdir/BUILD
+
+ if test x"$pp_rpm_arch" = x"auto"; then
+ #-- Reduce the arch_seen list to exactly one item
+ case "$pp_rpm_arch_seen" in
+ "i386 x86_64"|"x86_64 i386")
+ pp_rpm_arch_seen=x86_64;;
+ *"s390 s390x"* | *"s390x s390"* )
+ pp_rpm_arch_seen=s390x;;
+ *" "*)
+ pp_error "detected multiple targets: $pp_rpm_arch_seen"
+ pp_rpm_arch_seen=unknown;; # not detected
+ "")
+ pp_warn "detected no binaries: using target noarch"
+ pp_rpm_arch_seen=noarch;;
+ *)
+ pp_debug "detected architecture $pp_rpm_arch_seen"
+ esac
+ pp_rpm_arch="$pp_rpm_arch_seen"
+ fi
+
+ . $pp_wrkdir/%fixup
+
+$pp_opt_debug && cat $specfile
+
+ pp_debug "creating: `pp_backend_rpm_names`"
+
+pp_debug "pp_rpm_arch_seen = <${pp_rpm_arch_seen}>"
+pp_debug "pp_rpm_arch = <${pp_rpm_arch}>"
+
+ HOME=$pp_wrkdir \
+ pp_verbose \
+ $pp_rpm_rpmbuild -bb \
+ --buildroot="$pp_destdir/" \
+ --target="${pp_rpm_arch}" \
+ --define='_unpackaged_files_terminate_build 0' \
+ --define='_use_internal_dependency_generator 0' \
+ `$pp_opt_debug && echo --verbose || echo --quiet` \
+ $pp_rpm_rpmbuild_extra_flags \
+ $specfile ||
+ pp_error "Problem creating RPM packages"
+
+ for f in `pp_backend_rpm_names`; do
+ # The package might be in an arch-specific subdir
+ pkgfile=not-found
+ for dir in $pp_wrkdir/RPMS/${pp_rpm_arch} $pp_wrkdir/RPMS; do
+ if test -f $dir/$f; then
+ pkgfile=$dir/$f
+ fi
+ done
+ if test x"$pkgfile" = x"not-found"; then
+ pp_error "Problem predicting RPM filename: $f"
+ else
+ ln $pkgfile $pp_wrkdir/$f
+ fi
+ done
+}
+
+pp_rpm_output_name () {
+ echo "${pp_rpm_name:-$name}`pp_rpm_subname "$1" -`-${pp_rpm_version:-$version}-${pp_rpm_release:-1}.${pp_rpm_arch}.rpm"
+}
+
+pp_backend_rpm_names () {
+ local cmp _subname
+ for cmp in $pp_components; do
+ pp_rpm_output_name $cmp
+ done
+}
+
+pp_backend_rpm_cleanup () {
+ :
+}
+
+pp_rpm_print_requires () {
+ local _subname _name
+
+ echo "CPU:$pp_rpm_arch"
+ ## XXX should be lines of the form (from file/ldd/objdump)
+ # EXEC:/bin/sh
+ # RTLD:libc.so.4:open
+ rpm -q --requires -p $pp_wrkdir/`pp_rpm_output_name $1` |sed -e '/^rpmlib(/d;s/ //g;s/^/RPM:/' | sort -u
+}
+
+pp_backend_rpm_install_script () {
+ local cmp _subname
+
+ echo "#!/bin/sh"
+ pp_install_script_common
+
+ cat <<.
+
+ cmp_to_pkgname () {
+ local oi name
+ if test x"\$1" = x"--only-installed"; then
+ #-- only print if installation detected
+ oi=false
+ shift
+ else
+ oi=true
+ fi
+ test x"\$*" = x"all" &&
+ set -- $pp_components
+ for cmp
+ do
+ case \$cmp in
+.
+ for cmp in $pp_components; do
+ _subname=`pp_rpm_subname $cmp -`
+ echo "$cmp) name=${pp_rpm_name:-$name}${_subname};;"
+ done
+ cat <<.
+ *) usage;;
+ esac
+ if \$oi || rpm -q "\$name" >/dev/null 2>/dev/null; then
+ echo "\$name"
+ fi
+ done
+ }
+
+
+ cmp_to_pathname () {
+ test x"\$*" = x"all" &&
+ set -- $pp_components
+ for cmp
+ do
+ case \$cmp in
+.
+ for cmp in $pp_components; do
+ echo "$cmp) echo \${PP_PKGDESTDIR:-.}/`pp_rpm_output_name $cmp` ;;"
+ done
+ cat <<.
+ *) usage;;
+ esac
+ done
+ }
+
+ print_requires () {
+ test x"\$*" = x"all" &&
+ set -- $pp_components
+ for cmp
+ do
+ case \$cmp in
+.
+ for cmp in $pp_components; do
+ echo "$cmp) cat <<'._end'"
+ pp_rpm_print_requires $cmp
+ echo "._end"; echo ';;'
+ done
+ cat <<.
+ *) usage;;
+ esac
+ done
+ }
+
+ test \$# -eq 0 && usage
+ op="\$1"; shift
+ case "\$op" in
+ list-components)
+ test \$# -eq 0 || usage \$op
+ echo $pp_components
+ ;;
+ list-services)
+ test \$# -eq 0 || usage \$op
+ echo $pp_services
+ ;;
+ list-files)
+ test \$# -ge 1 || usage \$op
+ cmp_to_pathname "\$@"
+ ;;
+ install)
+ test \$# -ge 1 || usage \$op
+ verbose rpm -U --replacepkgs --oldpackage \
+ \`cmp_to_pathname "\$@"\`
+ ;;
+ uninstall)
+ test \$# -ge 1 || usage \$op
+ pkgs=\`cmp_to_pkgname --only-installed "\$@"\`
+ if test -z "\$pkgs"; then
+ verbosemsg "nothing to uninstall"
+ else
+ verbose rpm -e \$pkgs
+ fi
+ ;;
+ start|stop)
+ test \$# -ge 1 || usage \$op
+ ec=0
+ for svc
+ do
+ verbose /etc/init.d/\$svc \$op || ec=1
+ done
+ exit \$ec
+ ;;
+ print-platform)
+ test \$# -eq 0 || usage \$op
+ echo "linux-${pp_rpm_arch}"
+ ;;
+ print-requires)
+ test \$# -ge 1 || usage \$op
+ print_requires "\$@"
+ ;;
+ *)
+ usage
+ ;;
+ esac
+.
+
+}
+
+pp_backend_rpm_probe () {
+ echo "${pp_rpm_distro}-${pp_rpm_arch_std}"
+}
+
+pp_backend_rpm_vas_platforms () {
+ case "$pp_rpm_arch_std" in
+ x86_64) echo "linux-x86_64.rpm linux-x86.rpm";;
+ *86) echo "linux-x86.rpm";;
+ s390) echo "linux-s390";;
+ s390x) echo "linux-s390x";;
+ ppc*) echo "linux-glibc23-ppc64 linux-glibc22-ppc64";;
+ ia64) echo "linux-ia64";;
+ *) pp_die "unknown architecture $pp_rpm_arch_std";;
+ esac
+}
+
+pp_rpm_service_install_common () {
+ cat <<-'.'
+
+ _pp_install_service () {
+ local svc level
+ svc="$1"
+ if [ -x /usr/lib/lsb/install_initd -a ! -r /etc/redhat-release ]
+ then
+ # LSB-style install
+ /usr/lib/lsb/install_initd /etc/init.d/$svc &> /dev/null
+ elif [ -x /sbin/chkconfig ]; then
+ # Red Hat/chkconfig-style install
+ /sbin/chkconfig --add $svc &> /dev/null
+ /sbin/chkconfig $svc off &> /dev/null
+ else
+ : # manual links under /etc/init.d
+ fi
+ }
+
+ _pp_enable_service () {
+ local svc level
+ svc="$1"
+ if [ -x /usr/lib/lsb/install_initd -a ! -r /etc/redhat-release ]
+ then
+ # LSB-style install
+ : # not sure how to enable
+ elif [ -x /sbin/chkconfig ]; then
+ # Red Hat/chkconfig-style install
+ /sbin/chkconfig $svc on &> /dev/null
+ else
+ # manual install
+ set -- `sed -n -e 's/^# Default-Start://p' /etc/init.d/$svc`
+ start_priority=`sed -n -e 's/^# X-Quest-Start-Priority:[[:space:]]*//p' /etc/init.d/$svc`
+ stop_priority=`sed -n -e 's/^# X-Quest-Stop-Priority:[[:space:]]*//p' /etc/init.d/$svc`
+
+ # Provide default start & stop priorities of 20 & 80 in
+ # accordance with Debian update-rc.d defaults
+ if [ -z "$start_priority" ]; then
+ start_priority=20
+ fi
+ if [ -z "$stop_priority" ]; then
+ stop_priority=80
+ fi
+
+ if [ -d "/etc/rc.d" ];then
+ rcdir=/etc/rc.d
+ else
+ rcdir=/etc
+ fi
+
+ for level
+ do ln -sf /etc/init.d/$svc $rcdir/rc$level.d/S$start_priority$svc; done
+ set -- `sed -n -e 's/^# Default-Stop://p' /etc/init.d/$svc`
+ for level
+ do ln -sf /etc/init.d/$svc $rcdir/rc$level.d/K$stop_priority$svc; done
+ fi
+ }
+.
+}
+
+pp_rpm_service_remove_common () {
+ cat <<-'.'
+
+ _pp_remove_service () {
+ local svc
+ svc="$1"
+ /etc/init.d/$svc stop >/dev/null 2>&1
+ if [ -x /usr/lib/lsb/remove_initd -a ! -r /etc/redhat-release ]
+ then
+ /usr/lib/lsb/remove_initd /etc/init.d/$svc &> /dev/null
+ elif [ -x /sbin/chkconfig ]; then
+ /sbin/chkconfig --del $svc &> /dev/null
+ else
+ if [ -d "/etc/rc.d" ];then
+ rcdir=/etc/rc.d
+ else
+ rcdir=/etc
+ fi
+
+ rm -f $rcdir/rc?.d/[SK]??$svc
+ fi
+ }
+.
+}
+
+
+pp_rpm_service_install () {
+ pp_rpm_service_make_init_script $1 >/dev/null ||
+ pp_error "could not create init script for service $1"
+ echo "_pp_install_service $1"
+ test $enable = yes && echo "_pp_enable_service $1"
+}
+
+pp_rpm_service_remove () {
+ cat <<-.
+ if [ "\$1" = "remove" -o "\$1" = "0" ]; then
+ # only remove the service if not upgrade
+ _pp_remove_service $1
+ fi
+.
+}
+
+
+pp_backend_rpm_init_svc_vars () {
+
+ reload_signal=
+ start_runlevels=${pp_rpm_default_start_runlevels-"2 3 4 5"} # == lsb default-start
+ stop_runlevels=${pp_rpm_default_stop_runlevels-"0 1 6"} # == lsb default-stop
+ svc_description="${pp_rpm_default_svc_description}" # == lsb short descr
+ svc_process=
+
+ lsb_required_start='$local_fs $network'
+ lsb_should_start=
+ lsb_required_stop=
+ lsb_description=
+
+ start_priority=50
+ stop_priority=50 #-- stop_priority = 100 - start_priority
+}
+
+pp_rpm_service_group_make_init_script () {
+ local grp=$1
+ local svcs="$2"
+ local script=/etc/init.d/$grp
+ local out=$pp_destdir$script
+
+ pp_add_file_if_missing $script run 755 || return 0
+
+ cat <<-. >>$out
+ #!/bin/sh
+ svcs="$svcs"
+.
+
+ cat <<-'.' >>$out
+
+ #-- prints usage message
+ pp_usage () {
+ echo "usage: $0 {start|stop|status|restart|reload|condrestart|try-restart|force-reload}" >&2
+ return 2
+ }
+
+ #-- starts services in order.. stops them all if any break
+ pp_start () {
+ undo=
+ for svc in $svcs; do
+ if /etc/init.d/$svc start; then
+ undo="$svc $undo"
+ else
+ if test -n "$undo"; then
+ for svc in $undo; do
+ /etc/init.d/$svc stop
+ done
+ return 1
+ fi
+ fi
+ done
+ return 0
+ }
+
+ #-- stops services in reverse
+ pp_stop () {
+ reverse=
+ for svc in $svcs; do
+ reverse="$svc $reverse"
+ done
+ rc=0
+ for svc in $reverse; do
+ /etc/init.d/$svc stop || rc=$?
+ done
+ return $rc
+ }
+
+ #-- returns true only if all services return true status
+ pp_status () {
+ rc=0
+ for svc in $svcs; do
+ /etc/init.d/$svc status || rc=$?
+ done
+ return $rc
+ }
+
+ pp_reload () {
+ rc=0
+ for svc in $svcs; do
+ /etc/init.d/$svc reload || rc=$?
+ done
+ return $rc
+ }
+
+ case "$1" in
+ start) pp_start;;
+ stop) pp_stop;;
+ restart) pp_stop; pp_start;;
+ status) pp_status;;
+ try-restart|condrestart)
+ if pp_status >/dev/null; then
+ pp_restart
+ fi;;
+ reload) pp_reload;;
+ force-reload) if pp_status >/dev/null; then
+ pp_reload
+ else
+ pp_restart
+ fi;;
+ *) pp_usage;;
+ esac
+.
+ chmod 755 $out
+}
+
+pp_rpm_service_make_init_script () {
+ local svc=$1
+ local script=/etc/init.d/$svc
+ local out=$pp_destdir$script
+ local _process _cmd _rpmlevels
+
+ pp_add_file_if_missing $script run 755 || return 0
+
+ #-- start out as an empty shell script
+ cat <<-'.' >$out
+ #!/bin/sh
+.
+
+ #-- determine the process name from $cmd unless $svc_process is given
+ set -- $cmd
+ _process=${svc_process:-"$1"}
+
+ #-- construct a start command that builds a pid file if needed
+ _cmd="$cmd";
+ if test -z "$pidfile"; then
+ pidfile=/var/run/$svc.pid
+ _cmd="$cmd & echo \$! > \$pidfile"
+ fi
+ if test "$user" != "root"; then
+ _cmd="su $user -c exec $_cmd";
+ fi
+
+ #-- generate the Red Hat chkconfig headers
+ _rpmlevels=`echo $start_runlevels | tr -d ' '`
+ cat <<-. >>$out
+ # chkconfig: ${_rpmlevels:--} ${start_priority:-50} ${stop_priority:-50}
+ # description: ${svc_description:-no description}
+ # processname: ${_process}
+ # pidfile: ${pidfile}
+.
+
+ #-- generate the LSB init info
+ cat <<-. >>$out
+ ### BEGIN INIT INFO
+ # Provides: ${svc}
+ # Required-Start: ${lsb_required_start}
+ # Should-Start: ${lsb_should_start}
+ # Required-Stop: ${lsb_required_stop}
+ # Default-Start: ${start_runlevels}
+ # Default-Stop: ${stop_runlevels}
+ # Short-Description: ${svc_description}
+ ### END INIT INFO
+ # Generated by PolyPackage ${pp_version}
+ # ${copyright}
+
+ prog="`echo $cmd | sed -e 's: .*::' -e 's:^.*/::'`"
+
+.
+
+ if test x"${svc_description}" = x"${pp_rpm_default_svc_description}"; then
+ svc_description=
+ fi
+
+ #-- write service-specific definitions
+ cat <<. >>$out
+ #-- definitions specific to service ${svc}
+ svc_name="${svc_description:-$svc service}"
+ user="${user}"
+ pidfile="${pidfile}"
+ stop_signal="${stop_signal}"
+ reload_signal="${reload_signal}"
+ pp_exec_cmd () { $_cmd; }
+.
+
+ #-- write the generic part of the init script
+ cat <<'.' >>$out
+
+ #-- use system message logging, if available
+ if [ -f /lib/lsb/init-functions -a ! -r /etc/redhat-release ]; then
+ . /lib/lsb/init-functions
+ pp_success_msg () { log_success_msg "$@"; }
+ pp_failure_msg () { log_failure_msg "$@"; }
+ pp_warning_msg () { log_warning_msg "$@"; }
+ elif [ -f /etc/init.d/functions ]; then
+ . /etc/init.d/functions
+ pp_success_msg () { echo -n "$*"; success "$@"; echo; }
+ pp_failure_msg () { echo -n "$*"; failure "$@"; echo; }
+ pp_warning_msg () { echo -n "$*"; warning "$@"; echo; }
+ else
+ pp_success_msg () { echo ${1:+"$*:"} OK; }
+ pp_failure_msg () { echo ${1:+"$*:"} FAIL; }
+ pp_warning_msg () { echo ${1:+"$*:"} WARNING; }
+ fi
+
+ #-- prints a status message
+ pp_msg () { echo -n "$*: "; }
+
+ #-- prints usage message
+ pp_usage () {
+ echo "usage: $0 {start|stop|status|restart|reload|condrestart|try-restart|force-reload}" >&2
+ return 2
+ }
+
+ #-- reloads the service, if possible
+ # returns 0=success 1=failure 3=unimplemented
+ pp_reload () {
+ test -n "$reload_signal" || return 3 # unimplemented
+ pp_msg "Reloading ${svc_name}"
+ if pp_signal -${reload_signal}; then
+ pp_success_msg
+ return 0
+ else
+ pp_failure_msg "not running"
+ return 1
+ fi
+ }
+
+ #-- delivers signal $1 to the pidfile
+ # returns 0=success 1=failure
+ pp_signal () {
+ if test -s "$pidfile"; then
+ read pid < "$pidfile" 2>/dev/null
+ kill "$@" "$pid" 2>/dev/null
+ else
+ return 1
+ fi
+ }
+
+ #-- verifies that ${svc_name} is running
+ # returns 0=success 1=failure
+ pp_running () {
+ if test -s "$pidfile"; then
+ read pid < "$pidfile" 2>/dev/null
+ if test ${pid:-0} -gt 1 && kill -0 "$pid" 2>/dev/null; then
+ # make sure name matches
+ pid="`ps -p $pid 2>/dev/null | sed -n \"s/^ *\($pid\) .*$prog *$/\1/p\"`"
+ if test -n "$pid"; then
+ return 0
+ fi
+ fi
+ fi
+ return 1
+ }
+
+ #-- prints information about the service status
+ # returns 0=running 1=crashed 3=stopped
+ pp_status () {
+ pp_msg "Checking for ${svc_name}"
+ if pp_running; then
+ pp_success_msg "running"
+ return 0
+ elif test -s "$pidfile"; then
+ pp_failure_msg "not running (crashed)"
+ return 1
+ else
+ pp_failure_msg "not running"
+ return 3
+ fi
+ }
+
+ #-- starts the service
+ # returns 0=success 1=failure
+ pp_start () {
+ pp_msg "Starting ${svc_name}"
+ if pp_status >/dev/null; then
+ pp_warning_msg "already started"
+ return 0
+ elif pp_exec_cmd; then
+ pp_success_msg
+ return 0
+ else
+ pp_failure_msg "cannot start"
+ return 1
+ fi
+ }
+
+ #-- stops the service
+ # returns 0=success (always)
+ pp_stop () {
+ pp_msg "Stopping ${svc_name}"
+ if pp_signal -${stop_signal}; then
+ pp_success_msg
+ else
+ pp_success_msg "already stopped"
+ fi
+ rm -f "$pidfile"
+ return 0
+ }
+
+ #-- stops and starts the service
+ pp_restart () {
+ pp_stop
+ pp_start
+ }
+
+ case "$1" in
+ start) pp_start;;
+ stop) pp_stop;;
+ restart) pp_restart;;
+ status) pp_status;;
+ try-restart|condrestart)
+ if pp_status >/dev/null; then
+ pp_restart
+ fi;;
+ reload) pp_reload;;
+ force-reload) if pp_status >/dev/null; then
+ pp_reload
+ else
+ pp_restart
+ fi;;
+ *) pp_usage;;
+ esac
+
+.
+ chmod 755 $out
+}
+pp_backend_rpm_function () {
+ case "$1" in
+ pp_mkgroup) cat<<'.';;
+ /usr/sbin/groupadd -f -r "$1"
+.
+ pp_mkuser:depends) echo pp_mkgroup;;
+ pp_mkuser) cat<<'.';;
+ pp_mkgroup "${2:-$1}" || return 1
+ /usr/sbin/useradd \
+ -g "${2:-$1}" \
+ -M -d "${3:-/nonexistent}" \
+ -s "${4:-/bin/false}" \
+ -r "$1"
+.
+ pp_havelib) cat<<'.';;
+ for pp_tmp_dir in `echo "/usr/lib:/lib${3:+:$3}" | tr : ' '`; do
+ test -r "$pp_tmp_dir/lib$1.so{$2:+.$2}" && return 0
+ done
+ return 1
+.
+ *) false;;
+ esac
+}
+
+: NOTES <<.
+
+ # creating a dmg file for publishing on the web
+ hdiutil create -srcfolder /path/foo foo.dmg
+ hdiutil internet-enable -yes /path/foo.dmg
+ # Layout for packages
+ <name>-<cpy>/component/<file>
+ <name>-<cpt>/extras/postinstall
+ <name>-<cpt>/extras/postupgrade
+ # /Developer/usr/bin/packagemaker (man packagemaker)
+
+ Make a bunch of packages, and then build a 'distribution'
+ which is only understood by macos>10.4
+
+ # Message files in the resource path used are
+ Welcome.{rtf,html,rtfd,txt} - limited text shown in Intro
+ ReadMe.{rtf,html,rtfd,txt} - scrollable/printable, after Intro
+ License.{rtf,html,rtfd,txt} - ditto, user must click 'Accept'
+ background.{jpg,tif,gif,pict,eps,pdf} 620x418 background image
+
+ # These scripts looked for in the resource path
+ InstallationCheck $pkgpath $defaultloc $targetvol
+ 0:ok 32:warn 32+x:warn[1] 64:stop 96+x:stop[2]
+ VolumeCheck $volpath
+ 0:ok 32:failure 32+x:failure[3]
+ preflight $pkgpath $targetloc $targetvol [priv]
+ preinstall $pkgpath $targetloc $targetvol [priv]
+ preupgrade $pkgpath $targetloc $targetvol [priv]
+ postinstall $pkgpath $targetloc $targetvol [priv]
+ postupgrade $pkgpath $targetloc $targetvol [priv]
+ postflight $pkgpath $targetloc $targetvol [priv]
+ 0:ok else fail (for all scripts)
+
+ A detailed reason is deduced by finding an index x (16..31)
+ in the file InstallationCheck.strings or VolumeCheck.strings.
+
+ Scripts marked [priv] are executed with root privileges.
+ None of the [priv] scripts are used by metapackages.
+
+ # Default permissions
+ Permissions of existing directories should match those
+ of a clean install of the OS; typically root:admin 0775
+ New directories or files should be 0775 or 0664 with the
+ appropriate user:group.
+ Exceptions:
+ /etc root:admin 0755
+ /var root:admin 0755
+
+ <http://developer.apple.com/documentation/DeveloperTools/Conceptual/SoftwareDistribution4/Concepts/sd_pkg_flags.html>
+ Info.plist = {
+ CFBundleGetInfoString: "1.2.3, One Identity, LLC.",
+ CFBundleIdentifier: "com.quest.rc.openssh",
+ CFBundleShortVersionString: "1.2.3",
+ IFMajorVersion: 1,
+ IFMinorVersion: 2,
+ IFPkgFlagAllowBackRev: false,
+ IFPkgFlagAuthorizationAction: "AdminAuthorization",
+ IFPkgFlagDefaultLocation: "/",
+ IFPkgFlagFollowLinks: true,
+ IFPkgFlagInstallFat: false,
+ IFPkgFlagInstalledSize: <integer>, # this is added by packagemaker
+ IFPkgFlagIsRequired: false,
+ IFPkgFlagOverwritePermissions: false,
+ IFPkgFlagRelocatable: false,
+ IFPkgFlagRestartAction: "NoRestart",
+ IFPkgFlagRootVolumeOnly: false,
+ IFPkgFlagUpdateInstalledLanguages: false,
+ IFPkgFormatVersion= 0.10000000149011612,
+ IFRequirementDicts: [ {
+ Level = "requires",
+ SpecArgument = "/opt/quest/lib/libvas.4.2.0.dylib",
+ SpecType = "file",
+ TestObject = true,
+ TestOperator = "eq", } ]
+ }
+
+ Description.plist = {
+ IFPkgDescriptionDescription = "this is the description text",
+ IFPkgDescriptionTitle = "quest-openssh"
+ }
+
+ # Startup scripts
+ 'launchd' is a kind of combined inetd and rc/init.d system.
+ <http://developer.apple.com/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/DesigningDaemons.html>
+ Create a /Library/LaunchDaemons/$daemonname.plist file
+ Examples found in /System/Library/LaunchDaemons/
+ See manual page launchd.plist(5) for details:
+
+ { Label: "com.quest.rc.foo", # required
+ Program: "/sbin/program",
+ ProgramArguments: [ "/sbin/program", "arg1", "arg2" ], # required
+ RunAtLoad: true,
+ WatchPaths: [ "/etc/crontab" ],
+ QueueDirectories: [ "/var/cron/tabs" ],
+ inetdCompatibility: { Wait: false }, # inetd-only
+ OnDemand: false, # recommended
+ SessionCreate: true,
+ UserName: "nobody",
+ InitGroups: true,
+ Sockets: { # inetd only
+ Listeners: {
+ SockServiceName: "ssh",
+ Bonjour: ["ssh", "sftp-ssh"], } },
+ Disabled: false,
+ StandardErrorPath: "/dev/null",
+ }
+
+
+ How to add a new user
+ dscl . -create /Users/$user
+ dscl . -create /Users/$user UserShell /bin/bash
+ dscl . -create /Users/$user RealName "$user"
+ dscl . -create /Users/$user UniqueID $uid
+ dscl . -create /Users/$user PrimaryGroupID $gid
+ dscl . -create /Users/$user NFSHomeDirectory /Users/$user
+ dscl . -passwd /Users/$user "$passwd"
+ mkdir /Users/$user
+ chown $uid.$gid /Users/$user
+
+.
+
+
+pp_platforms="$pp_platforms macos"
+
+pp_backend_macos_detect () {
+ [ x"$1" = x"Darwin" ]
+}
+
+pp_backend_macos_init () {
+ pp_macos_default_bundle_id_prefix="com.quest.rc."
+ pp_macos_bundle_id=
+ pp_macos_bundle_vendor=
+ pp_macos_bundle_version=
+ pp_macos_bundle_info_string=
+ pp_macos_pkg_type=bundle
+ pp_macos_pkg_license=
+ pp_macos_pkg_readme=
+ pp_macos_pkg_welcome=
+ pp_macos_sudo=sudo
+ pp_macos_installer_plugin=
+ # OS X puts the library version *before* the .dylib extension
+ pp_shlib_suffix='*.dylib'
+}
+
+pp_macos_plist () {
+ typeset in
+ in=""
+ while test $# -gt 0; do
+ case "$1" in
+
+ start-plist) cat <<-.; in=" "; shift ;;
+ <?xml version="1.0" encoding="UTF-8"?>
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+ <plist version="1.0">
+.
+ end-plist) echo "</plist>"; in=; shift;;
+
+ '[') echo "$in<array>"; in="$in "; shift;;
+ ']') echo "$in</array>"; in="${in# }"; shift;;
+ '{') echo "<dict>"; in="$in "; shift;;
+ '}') echo "</dict>"; in="${in# }"; shift;;
+ key) shift; echo "$in<key>$1</key>"; shift;;
+ string) shift;
+ echo "$1" | sed -e 's/&/&amp;/g;s/</\&lt;/g;s/>/\&gt;/g;' \
+ -e 's/^/'"$in"'<string>/;s/$/<\/string>/';
+ shift;;
+ true) echo "$in<true/>"; shift;;
+ false) echo "$in<false/>"; shift;;
+ real) shift; echo "$in<real>$1</real>"; shift;;
+ integer) shift; echo "$in<integer>$1</integer>"; shift;;
+ date) shift; echo "$in<date>$1</date>"; shift;; # ISO 8601 format
+ data) shift; echo "$in<data>$1</data>"; shift;; # base64 encoded
+ *) pp_error "pp_macos_plist: bad argument '$1'"; shift;;
+ esac
+ done
+}
+
+pp_macos_rewrite_cpio () {
+ typeset script
+ script=$pp_wrkdir/cpio-rewrite.pl
+ cat <<-'.' >$script
+ #!/usr/bin/perl
+ #
+ # Filter a cpio file, applying the user/group/mode specified in %files
+ #
+ # A CPIO header block has octal fields at the following offset/lengths:
+ # 0 6 magic
+ # 6 6 dev
+ # 12 6 ino
+ # 18 6 mode
+ # 24 6 uid
+ # 30 6 gid
+ # 36 6 nlink
+ # 42 6 rdev
+ # 48 11 mtime
+ # 59 6 namesize (including NUL terminator)
+ # 65 11 filesize
+ # 76 --
+ #
+ use strict;
+ use warnings;
+ no strict 'subs';
+
+ # set %uid, %gid, %mode based on %files
+ my (%uid, %gid, %mode, %users, %groups);
+ my %type_map = ( d => 0040000, f => 0100000, s => 0120000 );
+ while (<DATA>) {
+ my ($type,$mode,$uid,$gid,$flags,$name) =
+ m/^(.) (\S+) (\S+) (\S+) (\S+) (\S+)/;
+ $mode = $type eq "f" ? "0644" : "0755" if $mode eq "-";
+ $uid = 0 if $uid eq "-";
+ $gid = 0 if $gid eq "-";
+ if ($uid ne "=" and $uid =~ m/\D/) {
+ unless (exists $users{$uid}) {
+ my @pw = getpwnam($uid) or die "bad username '$uid'";
+ $users{$uid} = $pw[2];
+ }
+ $uid = $users{$uid};
+ }
+ if ($gid ne "=" and $gid =~ m/\D/) {
+ unless (exists $groups{$gid}) {
+ my @gr = getgrnam($gid) or die "bad group'$gid'";
+ $groups{$gid} = $gr[2];
+ }
+ $gid = $groups{$gid};
+ }
+ $name =~ s:/$:: if $type eq "d";
+ $name = ".".$name."\0";
+ $uid{$name} = sprintf("%06o",int($uid)) unless $uid eq "=";
+ $gid{$name} = sprintf("%06o",int($gid)) unless $gid eq "=";
+ $mode{$name} = sprintf("%06o",oct($mode)|$type_map{$type}) unless $mode eq "=";
+ }
+ undef %users;
+ undef %groups;
+ # parse the cpio file
+ my $hdrlen = 76;
+ while (read(STDIN, my $header, $hdrlen)) {
+ my ($name, $namesize, $filesize);
+ my $filepad = 0;
+ if ($header =~ m/^07070[12]/) {
+ # SVR4 ASCII format, convert to ODC
+ if ($hdrlen == 76) {
+ # Read in rest of header and update header len for SVR4
+ read(STDIN, $header, 110 - 76, 76);
+ $hdrlen = 110;
+ }
+ my $ino = hex(substr($header, 6, 8)) & 0x3ffff;
+ my $mode = hex(substr($header, 14, 8)) & 0x3ffff;
+ my $uid = hex(substr($header, 22, 8)) & 0x3ffff;
+ my $gid = hex(substr($header, 30, 8)) & 0x3ffff;
+ my $nlink = hex(substr($header, 38, 8)) & 0x3ffff;
+ my $mtime = hex(substr($header, 46, 8)) & 0xffffffff;
+ $filesize = hex(substr($header, 54, 8)) & 0xffffffff;
+ my $dev_maj = hex(substr($header, 62, 8));
+ my $dev_min = hex(substr($header, 70, 8));
+ my $dev = &makedev($dev_maj, $dev_min) & 0x3ffff;
+ my $rdev_maj = hex(substr($header, 78, 8));
+ my $rdev_min = hex(substr($header, 86, 8));
+ my $rdev = &makedev($rdev_maj, $rdev_min) & 0x3ffff;
+ $namesize = hex(substr($header, 94, 8)) & 0x3ffff;
+ read(STDIN, $name, $namesize);
+ # Header + name is padded to a multiple of 4 bytes
+ my $namepad = (($hdrlen + $namesize + 3) & 0xfffffffc) - ($hdrlen + $namesize);
+ read(STDIN, my $padding, $namepad) if ($namepad);
+ # File data is padded to be a multiple of 4 bytes
+ $filepad = (($filesize + 3) & 0xfffffffc) - $filesize;
+
+ my $new_header = sprintf("070707%06o%06o%06o%06o%06o%06o%06o%011o%06o%011o", $dev, $ino, $mode, $uid, $gid, $nlink, $rdev, $mtime, $namesize, $filesize);
+ $header = $new_header;
+ } elsif ($header =~ m/^070707/) {
+ # POSIX Portable ASCII Format
+ $namesize = oct(substr($header, 59, 6));
+ $filesize = oct(substr($header, 65, 11));
+ read(STDIN, $name, $namesize);
+ } else {
+ die "bad magic";
+ }
+ # update uid, gid and mode (already in octal)
+ substr($header, 24, 6) = $uid{$name} if exists $uid{$name};
+ substr($header, 30, 6) = $gid{$name} if exists $gid{$name};
+ substr($header, 18, 6) = $mode{$name} if exists $mode{$name};
+ print($header, $name);
+ # check for trailer at EOF
+ last if $filesize == 0 && $name =~ /^TRAILER!!!\0/;
+ # copy-through the file data
+ while ($filesize > 0) {
+ my $seg = 8192;
+ $seg = $filesize if $filesize < $seg;
+ read(STDIN, my $data, $seg);
+ print $data;
+ $filesize -= $seg;
+ }
+ # If file data is padded, skip it
+ read(STDIN, my $padding, $filepad) if ($filepad);
+ }
+ # pass through any padding at the end (blocksize-dependent)
+ for (;;) {
+ my $numread = read(STDIN, my $data, 8192);
+ last unless $numread;
+ print $data;
+ }
+ exit(0);
+
+ sub makedev {
+ (((($_[0] & 0xff)) << 24) | ($_[1] & 0xffffff));
+ }
+ __DATA__
+.
+ # Append to the script the %files data
+ cat "$@" </dev/null >> $script
+ /usr/bin/perl $script || pp_error "pp_macos_rewrite_cpio error";
+}
+
+pp_macos_files_bom () {
+ typeset _l t m o g f p st owner
+ while read t m o g f p st; do
+ # make sure that $m is padded up to 4 digits long
+ case "$m" in
+ ?) m="000$m";;
+ ??) m="00$m";;
+ ???) m="0$m";;
+ ?????*) pp_error "pp_macos_writebom: mode '$m' too long";;
+ esac
+
+ # convert owner,group into owner/group in octal
+ case $o in -) o=0;; esac
+ case $g in -) g=0;; esac
+ owner=`pp_d2o $o`/`pp_d2o $g`
+
+ case $t in
+ f)
+ test x"$m" = x"000-" && m=0644
+ echo ".$p 10$m $owner `
+ /usr/bin/cksum < "${pp_destdir}$p" |
+ awk '{print $2 " " $1}'`"
+ ;;
+ d)
+ test x"$m" = x"000-" && m=0755
+ echo ".${p%/} 4$m $owner"
+ ;;
+ s)
+ test x"$m" = x"000-" && m=0755
+ rl=`/usr/bin/readlink "${pp_destdir}$p"`
+ #test x"$rl" = x"$st" ||
+ # pp_error "symlink mismatch $rl != $st"
+ echo ".$p 12$m $owner `
+ /usr/bin/readlink -n "${pp_destdir}$p" |
+ /usr/bin/cksum |
+ awk '{print $2 " " $1}'` $st"
+ ;;
+ esac
+ done
+}
+
+pp_macos_bom_fix_parents () {
+ perl -pe '
+ sub dirname { my $d=shift; $d=~s,/[^/]*$,,; $d; }
+ sub chk { my $d=shift;
+ &chk(&dirname($d)) if $d =~ m,/,;
+ unless ($seen{$d}++) {
+ # Make sure we do not override system directories
+ if ($d =~ m:^\./(etc|var)$:) {
+ my $tgt = "private/$1";
+ my ($sum, $len) = split(/\s+/, `/usr/bin/printf "$tgt" | /usr/bin/cksum /dev/stdin`);
+ print "$d\t120755\t0/0\t$len\t$sum\t$tgt\n";
+ } elsif ($d eq "." || $d eq "./Library") {
+ print "$d\t41775\t0/80\n";
+ } elsif ($d eq "./Applications" || $d eq "./Developer") {
+ print "$d\t40775\t0/80\n";
+ } else {
+ print "$d\t40755\t0/0\n";
+ }
+ }
+ }
+ m/^(\S+)\s+(\d+)/;
+ if (oct($2) & 040000) {
+ $seen{$1}++; # directory
+ }
+ &chk(&dirname($1));'
+}
+
+pp_macos_files_size () {
+ typeset _l t m o g f p st owner
+ while read t m o g f p st; do
+ case $t in
+ f) wc -c < "${pp_destdir}$p";;
+ s) echo 4095;;
+ d) ;; # always seems to be zero
+ esac
+ done | awk '{n+=1+int($1/4096)} END {print n*4}'
+}
+
+pp_o2d () {
+ awk 'BEGIN { x=0; '`echo "$1" |
+ sed -e 's/./x=x*8+&;/g'`'print x;}' </dev/null
+}
+pp_d2o () {
+ case "$1" in
+ [0-7]) echo $1;;
+ *) awk 'BEGIN { printf("%o\n", 0+('"$1"'));}' < /dev/null;;
+ esac
+}
+
+pp_macos_mkbom () {
+ #/usr/bin/mkbom -i $1 $2
+ typeset path mode ugid size cksum linkpath
+ typeset bomstage
+
+ # Use mkbom if it understands -i (avoids a copy)
+ if /usr/bin/mkbom -i /dev/null "$2" 2>/dev/null; then
+ rm -f "$2"
+ /usr/bin/mkbom -i "$1" "$2"
+ return
+ fi
+
+ # On 10.4 we have this nonsense.
+ pp_warn "mkbom workaround: copying source files to staging area"
+
+ bomstage=$pp_wrkdir/bom_stage
+ $pp_macos_sudo /bin/mkdir "$bomstage"
+ while IFS=' ' read path mode ugid size cksumi linkpath; do
+ if test -h "$pp_destdir/$path"; then
+ $pp_macos_sudo /bin/ln -s "$linkpath" "$bomstage/$path"
+ else
+ if test -d "$pp_destdir/$path"; then
+ $pp_macos_sudo /bin/mkdir -p "$bomstage/$path"
+ else
+ $pp_macos_sudo /bin/cp "$pp_destdir/$path" "$bomstage/$path"
+ fi
+ $pp_macos_sudo /bin/chmod $mode "$bomstage/$path"
+ $pp_macos_sudo /usr/sbin/chown `echo $ugid| tr / :` "$bomstage/$path"
+ fi
+ done <"$1"
+ (cd $bomstage && $pp_macos_sudo mkbom . $pp_wrkdir/bom_stage.bom) ||
+ pp_error "mkbom failed"
+ $pp_macos_sudo mv $pp_wrkdir/bom_stage.bom "$2"
+}
+
+pp_backend_macos () {
+ : ${pp_macos_bundle_id:=$pp_macos_default_bundle_id_prefix$name}
+ case "$pp_macos_pkg_type" in
+ bundle) pp_backend_macos_bundle;;
+ flat) pp_backend_macos_flat;;
+ *) pp_error "unsupported package type $pp_macos_pkg_type";;
+ esac
+}
+
+pp_backend_macos_bundle () {
+ typeset pkgdir Contents Resources lprojdir svc
+ typeset Info_plist Description_plist
+ typeset bundle_vendor bundle_version size cmp filelists
+
+ mac_version=`sw_vers -productVersion`
+ bundle_vendor=${pp_macos_bundle_vendor:-$vendor}
+
+ if test -z "$pp_macos_bundle_version"; then
+ bundle_version=`echo "$version.0.0.0" | sed -n -e 's/[^0-9.]//g' \
+ -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/p'`
+ else
+ bundle_version="$pp_macos_bundle_version"
+ fi
+ source_version=`echo $version | sed 's/.*\.//'`
+
+ # build the package layout
+ pkgdir=$pp_wrkdir/$name.pkg
+ Contents=$pkgdir/Contents
+ Resources=$Contents/Resources
+ lprojdir=$Resources/en.lproj
+ mkdir $pkgdir $Contents $Resources $lprojdir ||
+ pp_error "Can't make package temporary directories"
+
+ echo "major: 1" > $Resources/package_version
+ echo "minor: 0" >> $Resources/package_version
+ echo "pmkrpkg1" > $Contents/PkgInfo
+ case $mac_version in
+ "10.6"*)
+ xattr -w "com.apple.TextEncoding" "macintosh;0" "$Resources/package_version"
+ xattr -w "com.apple.TextEncoding" "macintosh;0" "$Contents/PkgInfo"
+ ;;
+ esac
+
+ # Copy welcome file/dir for display at package install time.
+ if test -n "$pp_macos_pkg_welcome"; then
+ typeset sfx
+ sfx=`echo "$pp_macos_pkg_welcome"|sed 's/^.*\.\([^\.]*\)$/\1/'`
+ case "$sfx" in
+ rtf|html|rtfd|txt) ;;
+ *) sfx=txt;;
+ esac
+ cp -R ${pp_macos_pkg_welcome} $Resources/Welcome.$sfx
+ fi
+
+ # Copy readme file/dir for display at package install time.
+ if test -n "$pp_macos_pkg_readme"; then
+ typeset sfx
+ sfx=`echo "$pp_macos_pkg_readme"|sed 's/^.*\.\([^\.]*\)$/\1/'`
+ case "$sfx" in
+ rtf|html|rtfd|txt) ;;
+ *) sfx=txt;;
+ esac
+ cp -R ${pp_macos_pkg_readme} $Resources/ReadMe.$sfx
+ fi
+
+ # Copy license file/dir for display at package install time.
+ if test -n "$pp_macos_pkg_license"; then
+ typeset sfx
+ sfx=`echo "$pp_macos_pkg_license"|sed 's/^.*\.\([^\.]*\)$/\1/'`
+ case "$sfx" in
+ rtf|html|rtfd|txt) ;;
+ *) sfx=txt;;
+ esac
+ cp -R ${pp_macos_pkg_license} $Resources/License.$sfx
+ fi
+
+ # Add services (may modify %files)
+ for svc in $pp_services .; do
+ test . = "$svc" && continue
+ pp_macos_add_service $svc
+ done
+
+ # Find file lists (%files.* includes ignore files)
+ for cmp in $pp_components; do
+ test -f $pp_wrkdir/%files.$cmp && filelists="$filelists${filelists:+ }$pp_wrkdir/%files.$cmp"
+ done
+
+ # compute the installed size
+ size=`cat $filelists | pp_macos_files_size`
+
+ #-- Create Info.plist
+ Info_plist=$Contents/Info.plist
+ pp_macos_plist \
+ start-plist \{ \
+ key CFBundleGetInfoString string \
+ "${pp_macos_bundle_info_string:-$version $bundle_vendor}" \
+ key CFBundleIdentifier string \
+ "${pp_macos_bundle_id}" \
+ key CFBundleName string "$name" \
+ key CFBundleShortVersionString string "$bundle_version" \
+ key IFMajorVersion integer 1 \
+ key IFMinorVersion integer 0 \
+ key IFPkgFlagAllowBackRev false \
+ key IFPkgFlagAuthorizationAction string "RootAuthorization" \
+ key IFPkgFlagDefaultLocation string "/" \
+ key IFPkgFlagFollowLinks true \
+ key IFPkgFlagInstallFat true \
+ key IFPkgFlagInstalledSize integer $size \
+ key IFPkgFlagIsRequired false \
+ key IFPkgFlagOverwritePermissions true \
+ key IFPkgFlagRelocatable false \
+ key IFPkgFlagRestartAction string "NoRestart" \
+ key IFPkgFlagRootVolumeOnly true \
+ key IFPkgFlagUpdateInstalledLanguages false \
+ key IFPkgFlagUseUserMask false \
+ key IFPkgFormatVersion real 0.10000000149011612 \
+ key SourceVersion string $source_version \
+ \} end-plist> $Info_plist
+
+ # write en.lproj/Description.plist
+ Description_plist=$lprojdir/Description.plist
+ pp_macos_plist \
+ start-plist \{ \
+ key IFPkgDescriptionDeleteWarning string "" \
+ key IFPkgDescriptionDescription string "$pp_macos_bundle_info_string" \
+ key IFPkgDescriptionTitle string "$name" \
+ key IFPkgDescriptionVersion string "$version" \
+ \} end-plist > $Description_plist
+
+ # write Resources/files
+ awk '{print $6}' $filelists > $Resources/files
+
+ # write package size file
+ printf \
+"NumFiles 0
+InstalledSize $size
+CompressedSize 0
+" > $Resources/$name.sizes
+
+ # write Resources/preinstall
+ for cmp in $pp_components; do
+ if test -s $pp_wrkdir/%pre.$cmp; then
+ if test ! -s $Resources/preinstall; then
+ echo "#!/bin/sh" > $Resources/preinstall
+ chmod +x $Resources/preinstall
+ fi
+ cat $pp_wrkdir/%pre.$cmp >> $Resources/preinstall
+ echo : >> $Resources/preinstall
+ fi
+ done
+
+ # write Resources/postinstall
+ for cmp in $pp_components; do
+ if test -s $pp_wrkdir/%post.$cmp; then
+ if test ! -s $Resources/postinstall; then
+ echo "#!/bin/sh" > $Resources/postinstall
+ chmod +x $Resources/postinstall
+ fi
+ cat $pp_wrkdir/%post.$cmp >> $Resources/postinstall
+ echo : >> $Resources/postinstall
+ fi
+ done
+
+ # write Resources/postupgrade
+ for cmp in $pp_components; do
+ if test -s $pp_wrkdir/%postup.$cmp; then
+ if test ! -s $Resources/postupgrade; then
+ echo "#!/bin/sh" > $Resources/postupgrade
+ chmod +x $Resources/postupgrade
+ fi
+ cat $pp_wrkdir/%postup.$cmp >> $Resources/postupgrade
+ echo : >> $Resources/postupgrade
+ fi
+ done
+
+ # write Resources/preremove
+ for cmp in $pp_components; do
+ if test -s $pp_wrkdir/%preun.$cmp; then
+ if test ! -s $Resources/preremove; then
+ echo "#!/bin/sh" > $Resources/preremove
+ chmod +x $Resources/preremove
+ fi
+ cat $pp_wrkdir/%preun.$cmp >> $Resources/preremove
+ echo : >> $Resources/preremove
+ fi
+ done
+
+ # write Resources/postremove
+ for cmp in $pp_components; do
+ if test -s $pp_wrkdir/%postun.$cmp; then
+ if test ! -s $Resources/postremove; then
+ echo "#!/bin/sh" > $Resources/postremove
+ chmod +x $Resources/postremove
+ fi
+ cat $pp_wrkdir/%postun.$cmp >> $Resources/postremove
+ echo : >> $Resources/postremove
+ fi
+ done
+
+ # write uninstall info
+ echo "version=$version" > $Resources/uninstall
+ if [ -n "$pp_macos_requires" ];then
+ echo "requires=$pp_macos_requires" >> $Resources/uninstall
+ fi
+
+ . $pp_wrkdir/%fixup
+
+ # Create the bill-of-materials (Archive.bom)
+ cat $filelists | pp_macos_files_bom | sort |
+ pp_macos_bom_fix_parents > $pp_wrkdir/tmp.bomls
+
+ pp_macos_mkbom $pp_wrkdir/tmp.bomls $Contents/Archive.bom
+
+ # Create the cpio archive (Archive.pax.gz)
+ (
+ cd $pp_destdir &&
+ awk '{ print "." $6 }' $filelists | sed 's:/$::' | sort | /usr/bin/cpio -o | pp_macos_rewrite_cpio $filelists | gzip -9f -c > $Contents/Archive.pax.gz
+ )
+
+ # Copy installer plugins if any
+ if test -n "$pp_macos_installer_plugin"; then
+ if test ! -f "$pp_macos_installer_plugin/InstallerSections.plist"; then
+ pp_error "Missing InstallerSections.plist file in $pp_macos_installer_plugin"
+ fi
+ mkdir -p $pkgdir/Plugins
+ cp -R "$pp_macos_installer_plugin"/* $pkgdir/Plugins
+ fi
+
+ test -d $pp_wrkdir/bom_stage && $pp_macos_sudo rm -rf $pp_wrkdir/bom_stage
+
+ rm -f ${name}-${version}.dmg
+ hdiutil create -fs HFS+ -srcfolder $pkgdir -volname $name ${name}-${version}.dmg
+}
+
+pp_backend_macos_flat () {
+ typeset pkgdir bundledir Resources lprojdir svc
+ typeset Info_plist Description_plist
+ typeset bundle_vendor bundle_version size numfiles cmp filelists
+
+ mac_version=`sw_vers -productVersion`
+ bundle_vendor=${pp_macos_bundle_vendor:-$vendor}
+
+ if test -z "$pp_macos_bundle_version"; then
+ bundle_version=`echo "$version.0.0.0" | sed -n -e 's/[^0-9.]//g' \
+ -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/p'`
+ else
+ bundle_version="$pp_macos_bundle_version"
+ fi
+ source_version=`echo $version | sed 's/.*\.//'`
+
+ # build the flat package layout
+ pkgdir=$pp_wrkdir/pkg
+ bundledir=$pp_wrkdir/pkg/$name.pkg
+ Resources=$pkgdir/Resources
+ lprojdir=$Resources/en.lproj
+ mkdir $pkgdir $bundledir $Resources $lprojdir ||
+ pp_error "Can't make package temporary directories"
+
+ # Add services (may modify %files)
+ for svc in $pp_services .; do
+ test . = "$svc" && continue
+ pp_macos_add_service $svc
+ done
+
+ # Find file lists (%files.* includes ignore files)
+ for cmp in $pp_components; do
+ test -f $pp_wrkdir/%files.$cmp && filelists="$filelists${filelists:+ }$pp_wrkdir/%files.$cmp"
+ done
+
+ # compute the installed size and number of files/dirs
+ size=`cat $filelists | pp_macos_files_size`
+ numfiles=`cat $filelists | wc -l`
+ numfiles="${numfiles##* }"
+
+ # Write Distribution file
+ cat <<-. >$pkgdir/Distribution
+ <?xml version="1.0" encoding="UTF-8"?>
+ <installer-script minSpecVersion="1.000000" authoringTool="com.quest.rc.PolyPkg" authoringToolVersion="$pp_version" authoringToolBuild="$pp_revision">
+ <title>$name $version</title>
+ <options customize="never" allow-external-scripts="no"/>
+ <domains enable_localSystem="true"/>
+.
+ if test -n "$pp_macos_pkg_welcome"; then
+ cp -R "${pp_macos_pkg_welcome}" $Resources
+ echo " <welcome file=\"${pp_macos_pkg_welcome##*/}\"/>" >>$pkgdir/Distribution
+ fi
+ if test -n "$pp_macos_pkg_readme"; then
+ cp -R "${pp_macos_pkg_readme}" $Resources
+ echo " <readme file=\"${pp_macos_pkg_readme##*/}\"/>" >>$pkgdir/Distribution
+ fi
+ if test -n "$pp_macos_pkg_license"; then
+ cp -R "${pp_macos_pkg_license}" $Resources
+ echo " <license file=\"${pp_macos_pkg_license##*/}\"/>" >>$pkgdir/Distribution
+ fi
+ cat <<-. >>$pkgdir/Distribution
+ <choices-outline>
+ <line choice="choice0"/>
+ </choices-outline>
+ <choice id="choice0" title="$name $version">
+ <pkg-ref id="${pp_macos_bundle_id}"/>
+ </choice>
+ <pkg-ref id="${pp_macos_bundle_id}" installKBytes="$size" version="$version" auth="Root">#$name.pkg</pkg-ref>
+ </installer-script>
+.
+
+ # write scripts archive
+ # XXX - missing preupgrade, preflight, postflight
+ mkdir $pp_wrkdir/scripts
+ for cmp in $pp_components; do
+ if test -s $pp_wrkdir/%pre.$cmp; then
+ if test ! -s $pp_wrkdir/scripts/preinstall; then
+ echo "#!/bin/sh" > $pp_wrkdir/scripts/preinstall
+ chmod +x $pp_wrkdir/scripts/preinstall
+ fi
+ cat $pp_wrkdir/%pre.$cmp >> $pp_wrkdir/scripts/preinstall
+ echo : >> $pp_wrkdir/scripts/preinstall
+ fi
+ if test -s $pp_wrkdir/%post.$cmp; then
+ if test ! -s $pp_wrkdir/scripts/postinstall; then
+ echo "#!/bin/sh" > $pp_wrkdir/scripts/postinstall
+ chmod +x $pp_wrkdir/scripts/postinstall
+ fi
+ cat $pp_wrkdir/%post.$cmp >> $pp_wrkdir/scripts/postinstall
+ echo : >> $pp_wrkdir/scripts/postinstall
+ fi
+ if test -s $pp_wrkdir/%postup.$cmp; then
+ if test ! -s $pp_wrkdir/scripts/postupgrade; then
+ echo "#!/bin/sh" > $pp_wrkdir/scripts/postupgrade
+ chmod +x $pp_wrkdir/scripts/postupgrade
+ fi
+ cat $pp_wrkdir/%postup.$cmp >> $pp_wrkdir/scripts/postupgrade
+ echo : >> $pp_wrkdir/scripts/postupgrade
+ fi
+ # XXX - not supported
+ if test -s $pp_wrkdir/%preun.$cmp; then
+ if test ! -s $pp_wrkdir/scripts/preremove; then
+ echo "#!/bin/sh" > $pp_wrkdir/scripts/preremove
+ chmod +x $pp_wrkdir/scripts/preremove
+ fi
+ cat $pp_wrkdir/%preun.$cmp >> $pp_wrkdir/scripts/preremove
+ echo : >> $pp_wrkdir/scripts/preremove
+ fi
+ # XXX - not supported
+ if test -s $pp_wrkdir/%postun.$cmp; then
+ if test ! -s $pp_wrkdir/scripts/postremove; then
+ echo "#!/bin/sh" > $pp_wrkdir/scripts/postremove
+ chmod +x $pp_wrkdir/scripts/postremove
+ fi
+ cat $pp_wrkdir/%postun.$cmp >> $pp_wrkdir/scripts/postremove
+ echo : >> $pp_wrkdir/scripts/postremove
+ fi
+ done
+ if test "`echo $pp_wrkdir/scripts/*`" != "$pp_wrkdir/scripts/*"; then
+ # write scripts archive, scripts are mode 0755 uid/gid 0/0
+ # resetting the owner and mode is not strictly required
+ (
+ cd $pp_wrkdir/scripts || pp_error "Can't cd to $pp_wrkdir/scripts"
+ rm -f $pp_wrkdir/tmp.files.scripts
+ for s in *; do
+ echo "f 0755 0 0 - ./$s" >>$pp_wrkdir/tmp.files.scripts
+ done
+ find . -type f | /usr/bin/cpio -o | pp_macos_rewrite_cpio $pp_wrkdir/tmp.files.scripts | gzip -9f -c > $bundledir/Scripts
+ )
+ fi
+
+ # Write PackageInfo file
+ cat <<-. >$bundledir/PackageInfo
+ <?xml version="1.0" encoding="UTF-8"?>
+ <pkg-info format-version="2" identifier="${pp_macos_bundle_id}" version="$version" install-location="/" relocatable="false" overwrite-permissions="true" followSymLinks="true" auth="root">
+ <payload installKBytes="$size" numberOfFiles="$numfiles"/>
+.
+ if test -s $bundledir/Scripts; then
+ echo " <scripts>" >>$bundledir/PackageInfo
+ for s in preflight postflight preinstall postinstall preupgrade postupgrade; do
+ if test -s "$pp_wrkdir/scripts/$s"; then
+ echo " <$s file=\"$s\"/>" >>$bundledir/PackageInfo
+ fi
+ done
+ echo " </scripts>" >>$bundledir/PackageInfo
+ fi
+ cat <<-. >>$bundledir/PackageInfo
+ </pkg-info>
+.
+
+ . $pp_wrkdir/%fixup
+
+ # Create the bill-of-materials (Bom)
+ cat $filelists | pp_macos_files_bom | sort |
+ pp_macos_bom_fix_parents > $pp_wrkdir/tmp.bomls
+ pp_macos_mkbom $pp_wrkdir/tmp.bomls $bundledir/Bom
+
+ # Create the cpio payload
+ (
+ cd $pp_destdir || pp_error "Can't cd to $pp_destdir"
+ awk '{ print "." $6 }' $filelists | sed 's:/$::' | sort | /usr/bin/cpio -o | pp_macos_rewrite_cpio $filelists | gzip -9f -c > $bundledir/Payload
+ )
+
+ # Copy installer plugins if any
+ if test -n "$pp_macos_installer_plugin"; then
+ if test ! -f "$pp_macos_installer_plugin/InstallerSections.plist"; then
+ pp_error "Missing InstallerSections.plist file in $pp_macos_installer_plugin"
+ fi
+ mkdir -p $pkgdir/Plugins
+ cp -R "$pp_macos_installer_plugin"/* $pkgdir/Plugins
+ fi
+
+ test -d $pp_wrkdir/bom_stage && $pp_macos_sudo rm -rf $pp_wrkdir/bom_stage
+
+ # Create the flat package with xar (like pkgutil --flatten does)
+ # Note that --distribution is only supported by Mac OS X 10.6 and above
+ xar_flags="--compression=bzip2 --no-compress Scripts --no-compress Payload"
+ case $mac_version in
+ "10.5"*) ;;
+ *) xar_flags="$xar_flags --distribution";;
+ esac
+ (cd $pkgdir && /usr/bin/xar $xar_flags -cf "../$name-$version.pkg" *)
+}
+
+pp_backend_macos_cleanup () {
+ :
+}
+
+pp_backend_macos_names () {
+ case "$pp_macos_pkg_type" in
+ bundle) echo ${name}.pkg;;
+ flat) echo ${name}-${version}.pkg;;
+ *) pp_error "unsupported package type $pp_macos_pkg_type";;
+ esac
+}
+
+pp_backend_macos_install_script () {
+ echo '#!/bin/sh'
+ typeset pkgname platform
+
+ pkgname="`pp_backend_macos_names`"
+ platform="`pp_backend_macos_probe`"
+ pp_install_script_common
+
+ cat <<.
+ test \$# -eq 0 && usage
+ op="\$1"; shift
+
+ case "\$op" in
+ list-components)
+ test \$# -eq 0 || usage \$op
+ echo "$pp_components"
+ ;;
+ list-services)
+ test \$# -eq 0 || usage \$op
+ echo "$pp_services"
+ ;;
+ list-files)
+ test \$# -ge 1 || usage \$op
+ echo \${PP_PKGDESTDIR:-.}/"$pkgname"
+ ;;
+ install)
+ test \$# -ge 1 || usage \$op
+ vol=/Volumes/pp\$\$
+ pkg=\$vol/${name}-${version}.pkg
+ hdiutil attach -readonly -mountpoint \$vol \
+ \${PP_PKGDESTDIR:-.}/"$pkgname"
+ trap "hdiutil detach \$vol" 0
+ installer -pkginfo -pkg \$pkg
+ installer -verbose -pkg \$pkg -target /
+ ;;
+ uninstall)
+ test \$# -ge 1 || usage \$op
+ # XXX
+ echo "Uninstall not implemented" >&2
+ exit 1;;
+ start|stop)
+ test \$# -ge 1 || usage \$op
+ ec=0
+ for svc
+ do
+ # XXX
+ echo "\${op} not implemented" >&2
+ ec=1
+ done
+ exit \$ec
+ ;;
+ print-platform)
+ echo "$platform"
+ ;;
+ *)
+ usage;;
+ esac
+.
+}
+
+pp_backend_macos_init_svc_vars () {
+ pp_macos_start_services_after_install=false
+ pp_macos_service_name=
+ pp_macos_default_service_id_prefix="com.quest.rc."
+ pp_macos_service_id=
+ pp_macos_service_user=
+ pp_macos_service_group=
+ pp_macos_service_initgroups=
+ pp_macos_service_umask=
+ pp_macos_service_cwd=
+ pp_macos_service_nice=
+ pp_macos_svc_plist_file=
+}
+
+pp_macos_launchd_plist () {
+ typeset svc svc_id
+
+ svc="$1"
+ svc_id="$2"
+
+ set -- $cmd
+
+ if [ -n "$pp_macos_svc_plist_file" ]; then
+ echo "## Launchd plist file already defined at $pp_macos_svc_plist_file"
+ return
+ fi
+
+ echo "## Generating the launchd plist file for $svc"
+ pp_macos_svc_plist_file="$pp_wrkdir/$svc.plist"
+ cat <<-. > $pp_macos_svc_plist_file
+ <?xml version="1.0" encoding="UTF-8"?>
+ <!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
+ http://www.apple.com/DTDs/PropertyList-1.0.dtd >
+ <plist version="1.0">
+ <dict>
+ <key>Label</key>
+ <string>$svc_id</string>
+ <key>ProgramArguments</key>
+ <array>
+.
+ while test $# != 0; do
+ printf " <string>$1</string>\n" >> $pp_macos_svc_plist_file
+ shift
+ done
+ cat <<-. >> $pp_macos_svc_plist_file
+ </array>
+ <key>KeepAlive</key>
+ <true/>
+.
+ if test -n "$pp_macos_service_user"; then
+ printf " <key>UserName</key>\n" >> $pp_macos_svc_plist_file
+ printf " <string>$pp_macos_service_user</string>\n" >> $pp_macos_svc_plist_file
+ fi
+ if test -n "$pp_macos_service_group"; then
+ printf " <key>GroupName</key>\n" >> $pp_macos_svc_plist_file
+ printf " <string>$pp_macos_service_group</string>\n" >> $pp_macos_svc_plist_file
+ fi
+ if test -n "$pp_macos_service_initgroups"; then
+ printf " <key>InitGroups</key>\n" >> $pp_macos_svc_plist_file
+ printf " <string>$pp_macos_service_initgroups</string>\n" >> $pp_macos_svc_plist_file
+ fi
+ if test -n "$pp_macos_service_umask"; then
+ printf " <key>Umask</key>\n" >> $pp_macos_svc_plist_file
+ printf " <string>$pp_macos_service_umask</string>\n" >> $pp_macos_svc_plist_file
+ fi
+ if test -n "$pp_macos_service_cwd"; then
+ printf " <key>WorkingDirectory</key>\n" >> $pp_macos_svc_plist_file
+ printf " <string>$pp_macos_service_cwd</string>\n" >> $pp_macos_svc_plist_file
+ fi
+ if test -n "$pp_macos_service_nice"; then
+ printf " <key>Nice</key>\n" >> $pp_macos_svc_plist_file
+ printf " <string>$pp_macos_service_nice</string>\n" >> $pp_macos_svc_plist_file
+ fi
+ cat <<-. >> $pp_macos_svc_plist_file
+ </dict>
+ </plist>
+.
+}
+
+pp_macos_add_service () {
+ typeset svc svc_id plist_file plist_dir
+
+ pp_load_service_vars "$1"
+ svc=${pp_macos_service_name:-$1}
+ svc_id=${pp_macos_service_id:-$pp_macos_default_service_id_prefix$svc}
+
+ #-- create a plist file for svc
+ pp_macos_launchd_plist "$svc" "$svc_id"
+
+ #-- copy the plist file into place and add to %files
+ plist_dir="/Library/LaunchDaemons"
+ plist_file="$plist_dir/$svc_id.plist"
+ mkdir -p "$pp_destdir/$plist_dir"
+ cp "$pp_macos_svc_plist_file" "$pp_destdir/$plist_file"
+ pp_add_file_if_missing "$plist_file"
+
+ #-- add code to start the service on install
+ ${pp_macos_start_services_after_install} && <<-. >> $pp_wrkdir/%post.$svc
+ # start service '$svc' automatically after install
+ launchctl load "$plist_file"
+.
+}
+
+pp_backend_macos_probe () {
+ typeset name vers arch
+ case `sw_vers -productName` in
+ "Mac OS X") name="macos";;
+ *) name="unknown";;
+ esac
+ vers=`sw_vers -productVersion | sed -e 's/^\([^.]*\)\.\([^.]*\).*/\1\2/'`
+ arch=`arch`
+ echo "$name$vers-$arch"
+}
+
+pp_backend_macos_vas_platforms () {
+ echo "osx" # XXX non-really sure what they do.. it should be "macos"
+}
+pp_backend_macos_function () {
+ case "$1" in
+ _pp_macos_search_unused) cat<<'.';;
+ # Find an unused value in the given path
+ # args: path attribute minid [maxid]
+ pp_tmp_val=$3
+ while :; do
+ test $pp_tmp_val -ge ${4:-999999} && return 1
+ /usr/bin/dscl . -search "$1" "$2" $pp_tmp_val |
+ grep . > /dev/null || break
+ pp_tmp_val=`expr $pp_tmp_val + 1`
+ done
+ echo $pp_tmp_val
+.
+ pp_mkgroup:depends) echo _pp_macos_search_unused;;
+ pp_mkgroup) cat<<'.';;
+ set -e
+ /usr/bin/dscl . -read /Groups/"$1" >/dev/null 2>&1 && return
+ pp_tmp_gid=`_pp_macos_search_unused /Groups PrimaryGroupID 100`
+ /usr/bin/dscl . -create /Groups/"$1"
+ /usr/bin/dscl . -create /Groups/"$1" PrimaryGroupID $pp_tmp_gid
+ /usr/bin/dscl . -create /Groups/"$1" RealName "Group $1"
+ /usr/bin/dscl . -create /Groups/"$1" GroupMembership ""
+ /usr/bin/dscl . -create /Groups/"$1" Password '*'
+.
+ pp_mkuser:depends) echo pp_mkgroup _pp_macos_search_unused;;
+ pp_mkuser) cat<<'.';;
+ set -e
+ /usr/bin/dscl . -read /Users/"$1" >/dev/null 2>&1 && return
+ pp_tmp_uid=`_pp_macos_search_unused /Users UniqueID 100`
+ pp_mkgroup "${2:-$1}"
+ pp_tmp_gid=`/usr/bin/dscl . -read /Groups/"${2:-$1}" \
+ PrimaryGroupID | awk '{print $2}'`
+ /usr/bin/dscl . -create /Users/"$1"
+ /usr/bin/dscl . -create /Users/"$1" PrimaryGroupID $pp_tmp_gid
+ /usr/bin/dscl . -create /Users/"$1" NFSHomeDirectory \
+ "${3:-/var/empty}"
+ /usr/bin/dscl . -create /Users/"$1" UserShell \
+ "${4:-/usr/bin/false}"
+ /usr/bin/dscl . -create /Users/"$1" RealName "$1"
+ /usr/bin/dscl . -create /Users/"$1" UniqueID $pp_tmp_uid
+ /usr/bin/dscl . -create /Users/"$1" Password '*'
+.
+ pp_havelib) cat<<'.';;
+ # (use otool -L to find dependent libraries)
+ for pp_tmp_dir in `echo "${3:+$3:}/usr/local/lib:/lib:/usr/lib" |
+ tr : ' '`; do
+ test -r "$pp_tmp_dir/lib$1{$2:+.$2}.dylib" && return 0
+ done
+ return 1
+.
+ *) false;;
+ esac
+}
+
+pp_platforms="$pp_platforms inst"
+
+pp_backend_inst_detect () {
+ case "$1" in
+ IRIX*) return 0;;
+ *) return 1;;
+ esac
+}
+
+pp_backend_inst_init () {
+ pp_readlink_fn=pp_ls_readlink
+}
+
+pp_backend_inst_create_idb()
+{
+ typeset t m o g f p st
+
+ while read t m o g f p st; do
+ if test x"$o" = x"-"; then
+ o="root"
+ fi
+ if test x"$g" = x"-"; then
+ g="sys"
+ fi
+ case "$t" in
+ f) test x"$m" = x"-" && m=444
+ echo "f 0$m $o $g $p $p $name.sw.base"
+ ;;
+ d) test x"$m" = x"-" && m=555
+ echo "d 0$m $o $g $p $p $name.sw.base"
+ ;;
+ s) test x"$m" = x"-" && m=777
+ test x"$m" = x"777" ||
+ pp_warn "$p: invalid mode $m for symlink, should be 777 or -"
+ echo "l 0$m $o $g $p $p $name.sw.base symval($st)"
+ ;;
+ esac
+ done
+}
+
+pp_backend_inst_create_spec()
+{
+ echo "product $name"
+ echo " id \"${summary}. Version: ${version}\""
+ echo " image sw"
+ echo " id \"Software\""
+ echo " version $version"
+ echo " order 9999"
+ echo " subsys base"
+ echo " id \"Base Software\""
+ echo " replaces self"
+ echo " exp $name.sw.base"
+ echo " endsubsys"
+ echo " endimage"
+ echo "endproduct"
+}
+
+pp_backend_inst () {
+ curdir=`pwd`
+
+ cd "$pp_opt_wrkdir"
+
+ # initialize
+ pp_inst_tardist=tardist
+ pp_inst_spec=${name}.spec
+ pp_inst_idb=${name}.idb
+
+ rm -rf $pp_inst_tardist $pp_inst_spec $pp_inst_idb
+ mkdir -p $pp_inst_tardist
+
+ # Create idb file
+ (for _cmp in $pp_components; do
+ cat %files.$_cmp | sort +4u -6 | pp_backend_inst_create_idb
+ done) >> $pp_inst_idb
+
+ pp_backend_inst_create_spec >> $pp_inst_spec
+
+ # Generate tardist
+ gendist -verbose -all -root / -source $pp_opt_destdir -idb $pp_inst_idb -spec $pp_inst_spec -dist $pp_inst_tardist $name
+ tar -cvf `pp_backend_inst_names` $pp_inst_tardist
+
+ cd "$curdir"
+}
+
+pp_backend_inst_cleanup () {
+ :
+}
+
+pp_backend_inst_names () {
+ echo ${name}-${version}.tardist
+}
+
+pp_backend_inst_install_script () {
+ :
+}
+
+pp_backend_inst_function () {
+ echo false
+}
+
+pp_backend_inst_init_svc_vars () {
+ :
+}
+
+pp_backend_inst_probe () {
+ cpu=`hinv|sed -n '/^CPU/{s/000 /k /;s/^CPU: //;s/ Process.*//;s/^MIPS //;p;q;}'|tr A-Z a-z`
+ echo irix`uname -r`-$cpu
+}
+
+pp_backend_inst_vas_platforms () {
+ echo "irix-65"
+}
+
+pp_platforms="$pp_platforms null"
+
+pp_backend_null_detect () {
+ ! :
+}
+
+pp_backend_null_init () {
+ :
+}
+
+
+pp_backend_null () {
+ :
+}
+
+pp_backend_null_cleanup () {
+ :
+}
+
+pp_backend_null_names () {
+ :
+}
+
+pp_backend_null_install_script () {
+ :
+}
+
+pp_backend_null_function () {
+ echo false
+}
+
+pp_backend_null_init_svc_vars () {
+ :
+}
+
+pp_backend_null_probe () {
+ echo unknown-unknown
+}
+
+pp_backend_null_vas_platforms () {
+:
+}
+
+pp_platforms="$pp_platforms bsd"
+
+pp_bsd_munge_text () {
+ # Insert a leading space on each line, replace blank lines with a
+ #space followed by a full-stop.
+ test -z "$1" && pp_die "pp_bsd_munge_text requires a parameter"
+ echo ${1} | sed "s,^\(.*\)$, \1, " | sed "s,^[ \t]*$, .,g"
+}
+
+pp_backend_bsd_detect () {
+ test x"$1" = x"FreeBSD"
+}
+
+pp_backend_bsd_init () {
+
+ # Get the OS revision
+ pp_bsd_detect_os
+
+ # Get the arch (i386/amd64)
+ pp_bsd_detect_arch
+
+ pp_bsd_name=
+ pp_bsd_version=
+ pp_bsd_origin=
+ pp_bsd_comment=
+ pp_bsd_arch=
+ pp_bsd_www=
+ pp_bsd_maintainer=
+ pp_bsd_prefix="/usr/local"
+ pp_bsd_desc=
+ pp_bsd_message=
+
+ # pp_bsd_category must be in array format comma seperated
+ # pp_bsd_category=[security,network]
+ pp_bsd_category=
+
+ # pp_bsd_licenselogic can be one of the following: single, and, or unset
+ pp_bsd_licenselogic=
+
+ # pp_bsd_licenses must be in array format comma seperated
+ # pp_bsd_licenses=[GPLv2,MIT]
+ pp_bsd_licenses=
+
+ # pp_bsd_annotations. These can be any key: value pair
+ # key must be seperated by a :
+ # keyvalue pairs must be comma seperated
+ # pp_bsd_annotations="repo_type: binary, somekey: somevalue"
+ # since all packages created by PolyPackage will be of type binary
+ # let's just set it now.
+ pp_bsd_annotations="repo_type: binary"
+
+ pp_bsd_dbg_pkgname="debug"
+ pp_bsd_dev_pkgname="devel"
+ pp_bsd_doc_pkgname="doc"
+
+ # Make sure any programs we require are installed
+ pp_bsd_check_required_programs
+
+}
+
+pp_bsd_cmp_full_name () {
+ typeset prefix
+ prefix="${pp_bsd_name:-$name}"
+ case "$1" in
+ run) echo "${prefix}" ;;
+ dbg) echo "${prefix}-${pp_bsd_dbg_pkgname}";;
+ dev) echo "${prefix}-${pp_bsd_dev_pkgname}";;
+ doc) echo "${prefix}-${pp_bsd_doc_pkgname}";;
+ *) pp_error "unknown component '$1'";
+ esac
+}
+
+pp_bsd_check_required_programs () {
+ local p needed notfound ok
+ needed= notfound=
+
+ # list of programs FreeBSD needs in order to create a binary package
+ for prog in ${pp_bsd_required_programs:-"pkg"}
+ do
+ if which $prog 2>&1 > /dev/null; then
+ pp_debug "$prog: found"
+ else
+ pp_debug "$prog: not found"
+ case "$prog" in
+ pkg) p=pkg;;
+ *) pp_die "Unexpected pkg tool $prog";;
+ esac
+ notfound="$notfound $prod"
+ pp_contains "$needed" "$p" || needed="$needed $p"
+ fi
+ done
+ if [ -n "$notfound" ]; then
+ pp_error "cannot find these programs: $notfound"
+ pp_error "please install these packages: $needed"
+ fi
+}
+
+pp_bsd_detect_os () {
+ typeset revision
+
+ pp_bsd_os=`uname -s`
+ revision=`uname -r`
+ pp_bsd_os_rev=`echo $revision | awk -F '-' '{print $1}'`
+}
+
+pp_bsd_detect_arch() {
+ pp_bsd_platform="`uname -m`"
+ case $pp_bsd_platform in
+ amd64) pp_bsd_platform_std=x86_64;;
+ i386) pp_bsd_platform_std=i386;;
+ *) pp_bsd_platform_std=unknown;;
+ esac
+}
+
+pp_bsd_label () {
+ local label arg
+ label="$1"; shift
+ for arg
+ do
+ test -z "$arg" || echo "$label: $arg"
+ done
+}
+
+pp_bsd_make_annotations () {
+
+ test -z $1 && pp_die "pp_bsd_make_annotations requires a parameter"
+ manifest=$1
+
+ # Add annotations. These can be any key: value pair
+ # key must be seperated by a :
+ # key:value pairs must be comma seperated.
+ if test -n "$pp_bsd_annotations"; then
+ pp_debug "Processing annotations:"
+ pp_bsd_label "annotations" "{" >> $manifest
+
+ SAVEIFS=$IFS
+ IFS=,
+ for annotate in $pp_bsd_annotations; do
+ # Remove any spaces at the start of the line
+ annotate=`echo $annotate | sed 's/^ *//'`
+ pp_debug " $annotate"
+ echo " $annotate" >> $manifest
+ done
+ IFS=$SAVEIFS
+ echo "}" >> $manifest
+ fi
+}
+
+pp_bsd_make_depends() {
+ typeset package origin version
+ cmp=$1
+ manifest=$2
+
+ if test -s $pp_wrkdir/%depend.${cmp}; then
+ echo "deps: {" >> $manifest
+ cat $pp_wrkdir/%depend.${cmp} | while read package origin version; do
+ if test x != x$package; then
+ pp_debug "Processing dependency: $package"
+ if test x != x$origin -a x != x$version; then
+ pp_debug " $package: {origin: \"$origin\", version: \"$version\"}"
+ echo " $package: {origin: \"$origin\", version: \"$version\"}" >> $manifest
+ else
+ pp_warn "Dependency $package is missing origin or version or both"
+ fi
+ fi
+ done
+ echo "}" >> $manifest
+ fi
+}
+
+pp_bsd_make_messages () {
+ test -z $1 && pp_die "pp_bsd_make_messages requires a parameter"
+ manifest=$1
+
+ pp_debug "Processing messsages"
+
+ # Empty messages: [ ] is OK in the manifest
+ pp_bsd_label "messages" "[" >> $manifest
+ # Look for a single message in the variable pp_bsd_message
+ if test -n "$pp_bsd_message"; then
+ echo " { message: \"`pp_bsd_munge_text "$pp_bsd_message"`\" }," >> $manifest
+ fi
+ local a=1
+ # Look for messages in the variables pp_bsd_message_[1..n]
+ var="pp_bsd_messages_1"
+ while [ -n "${!var}" ]; do
+ echo " { message: \"`pp_bsd_munge_text "${!var}"`\" }," >> $manifest
+ a=`expr $a + 1`
+ var="pp_bsd_messages_$a"
+ done
+ echo "]" >> $manifest
+}
+
+pp_bsd_make_manifest() {
+ local cmp manifest
+
+ cmp="$1"
+ manifest="$2"
+
+ package_name=`pp_bsd_cmp_full_name $cmp`
+
+ # Required for pkg +MANIFEST
+ cat <<-. >> $manifest
+ name: "${package_name}"
+ version: "${pp_bsd_version:-$version}"
+ origin: "${pp_bsd_origin}"
+ www: "${pp_bsd_www}"
+ desc: "`pp_bsd_munge_text "${pp_bsd_desc:-$description}"`"
+ comment: "${pp_bsd_comment:-$summary}"
+ maintainer: "${pp_bsd_maintainer}"
+ prefix: "${pp_bsd_prefix}"
+.
+
+ # Optional, so if they are not included in the pkg-product.pp file then do not create the label
+ pp_bsd_label "categories" "${pp_bsd_categories}" >> $manifest
+ pp_bsd_label "arch" "${pp_bsd_arch}" >> $manifest
+ pp_bsd_label "licenselogic" "${pp_bsd_licenselogic}" >> $manifest
+ pp_bsd_label "licenses" "${pp_bsd_licenses}" >> $manifest
+
+ pp_bsd_make_annotations $manifest
+ pp_bsd_make_depends $cmp $manifest
+
+ pp_bsd_make_messages $manifest
+}
+
+pp_bsd_fakeroot () {
+ if test -s $pp_wrkdir/fakeroot.save; then
+ fakeroot -i $pp_wrkdir/fakeroot.save -s $pp_wrkdir/fakeroot.save "$@"
+ else
+ fakeroot -s $pp_wrkdir/fakeroot.save "$@"
+ fi
+}
+
+pp_bsd_make_data() {
+ # t = file type
+ # m = file mode
+ # o = file owner
+ # g = file group
+ # f = ?
+ # p = file path
+ # st = file link
+ #
+ # EXAMPLE: f 755 root httpd v /usr/bin/hello goodbye
+ # -> /usr/bin/hello: {uname: root, gname: httpd, perm: 755 } goodbye
+ typeset _l t m o g f p st datadir
+ cmp=$1
+ datadir=$pp_wrkdir/`pp_bsd_cmp_full_name $cmp`
+ local path
+
+ outfilelist="$pp_wrkdir/files.list.$cmp"
+ outdirslist="$pp_wrkdir/dirs.list.$cmp"
+
+ pp_debug "Processing $pp_wrkdir/%file.${cmp}"
+
+ echo "files: {" > $outfilelist
+ echo "directories: {" > $outdirslist
+
+ cat $pp_wrkdir/%files.${cmp} | while read t m o g f p st; do
+ test x"$o" = x"-" && o="${pp_bsd_defattr_uid:-root}"
+ test x"$g" = x"-" && g="${pp_bsd_defattr_gid:-wheel}"
+ path=$pp_bsd_prefix$p
+ case "$t" in
+ f) # Files
+ # For now just skip the file if it is volatile, we will need to remove it in the pre uninstall script
+ if [ x"$f" != x"v" ]; then
+ # If the directory doesn't exist where we are going to copy this file, then create it first
+ if [ ! -d `dirname "$datadir$path"` ]; then
+ pp_debug "creating directory `dirname "$datadir$path"`"
+ mkdir -p `dirname "$datadir$path"`
+ fi
+
+ pp_debug "install -D $datadir -o $o -g $g -h sha256 -m ${m} -v $pp_destdir$p $datadir$path";
+ pp_bsd_fakeroot install -D $datadir -o $o -g $g -h sha256 -m ${m} -v $pp_destdir$p $datadir$path;
+ echo " \"$path\": \"-\", \"$path\": {uname: $o, gname: $g, perm: ${m}}" >> $outfilelist;
+ else
+ pp_warn "file $f was marked as volatile, skipping"
+ fi;
+ ;;
+ d) # Directories
+ pp_debug "install -D $datadir -o $o -g $g -m ${m} -d -v $datadir$path";
+ pp_bsd_fakeroot install -D $datadir -o $o -g $g -m ${m} -d -v $datadir$path;
+ echo " \"$path\": \"-\", \"$path\": {uname: $o, gname: $g, perm: ${m}}" >> $outdirslist;
+ ;;
+ s) # Symlinks
+ pp_debug "Found symlink: $datadir$path";
+ # Remove leading /
+ rel_p=`echo $p | sed s,^/,,`
+ (cd $datadir$pp_bsd_prefix; ln -sf $st $rel_p);
+ # Do we care if the file doesn't exist? Just symnlink it regardless and throw a warning? This will be important in the case
+ # where we depend on other packages to be installed and will be using the libs from that package.
+ if [ ! -e "$datadir$path" ]; then
+ pp_warn "$datadir$path does not exist"
+ fi
+ echo " \"$path\": \"$st\"" >> $outfilelist;
+ ;;
+ *) pp_error "Unsupported data file type: %t";;
+ esac
+ done
+
+ echo "}" >> $outfilelist
+ echo "}" >> $outdirslist
+ cat $outfilelist >> $manifest
+ cat $outdirslist >> $manifest
+
+ pp_debug "Finished processing $pp_wrkdir/%file.${cmp}"
+}
+
+pp_bsd_makebsd() {
+ typeset cmp
+ typeset package_build_dir
+ local manifest postinstall preinstall preuninstall postuninstall preupgrade postupgrade
+
+ cmp="$1"
+
+ if test -z "$pp_bsd_platform"; then
+ pp_error "Unknown BSD architecture"
+ return 1
+ fi
+
+ _subname=`pp_bsd_cmp_full_name $cmp`
+ package_build_dir=$pp_wrkdir/$_subname
+
+ manifest="$package_build_dir/+MANIFEST"
+ postinstall="$package_build_dir/+POST_INSTALL"
+ preinstall="$package_build_dir/+PRE_INSTALL"
+ preuninstall="$package_build_dir/+PRE_DEINSTALL"
+ postuninstall="$package_build_dir/+POST_DEINSTALL"
+ preupgrade="$package_build_dir/+PRE_UPGRADE"
+ postupgrade="$package_build_dir/+POST_UPGRADE"
+
+ # Create package dir
+ mkdir -p $package_build_dir
+
+ pp_bsd_make_manifest $cmp $manifest
+ pp_bsd_make_data $cmp
+
+ pp_debug "Processing pre/post install scripts"
+
+ if test -s $pp_wrkdir/%pre.$cmp; then
+ pp_debug "Found %pre.$cmp"
+ {
+ cat "$pp_wrkdir/%pre.$cmp"
+ } > $preinstall
+ pp_debug "Created $preinstall"
+ fi
+
+ if test -s $pp_wrkdir/%post.$cmp; then
+ pp_debug "Found %post.$cmp"
+ {
+ echo "# Post install script for "
+ cat "$pp_wrkdir/%post.$cmp"
+ } > $postinstall
+ pp_debug "Created $postinstall"
+ fi
+
+ pp_debug "Processing pre/post uninstall scripts"
+
+ if test -s $pp_wrkdir/%preun.$cmp; then
+ pp_debug "Found %preun.$cmp"
+ {
+ echo "# Pre uninstall script for ${pp_bsd_name:-$name}"
+ cat "$pp_wrkdir/%preun.$cmp"
+ } > $preuninstall
+ pp_debug "Created pkg $preuninstall"
+ fi
+
+ if test -s $pp_wrkdir/%postun.$cmp; then
+ pp_debug "Found %postun.$cmp"
+ {
+ echo "# Post uninstall script for ${pp_bsd_name:-$name}"
+ cat "$pp_wrkdir/%postun.$cmp"
+ } > $postuninstall
+ pp_debug "Created $postuninstall"
+ fi
+
+ if test -s $pp_wrkdir/%preup.$cmp; then
+ pp_debug "Found %preup.$cmp"
+ {
+ echo "# Pre upgrade script for ${pp_bsd_name:-$name}"
+ cat "$pp_wrkdir/%preup.$cmp"
+ } > $preupgrade
+ pp_debug "Created pkg $preupgrade"
+ fi
+
+ if test -s $pp_wrkdir/%postup.$cmp; then
+ pp_debug "Found %postup.$cmp"
+ {
+ echo "# Post upgrade script for ${pp_bsd_name:-$name}"
+ cat "$pp_wrkdir/%postup.$cmp"
+ } > $postupgrade
+ pp_debug "Created $postupgrade"
+ fi
+}
+
+pp_backend_bsd() {
+ #get-files-dir-entries
+ #create-manifest
+ #create-preuninstall
+ #create-postinstall
+ #create-package
+ #
+
+ for cmp in $pp_components
+ do
+ _subname=`pp_bsd_cmp_full_name $cmp`
+ pp_debug "Generating packaging specific files for $_subname"
+ pp_bsd_makebsd $cmp
+ done
+
+ # call this to fixup any files before creating the actual packages
+ . $pp_wrkdir/%fixup
+
+ for cmp in $pp_components
+ do
+ _subname=`pp_bsd_cmp_full_name $cmp`
+ package_build_dir=$pp_wrkdir/$_subname
+ # Build the actual packages now
+ pp_debug "Building FreeBSD $_subname"
+ pp_debug "Running package create command: pkg create -m $package_build_dir -r $pp_wrkdir/`pp_bsd_cmp_full_name $cmp` -o $pp_wrkdir"
+ pp_bsd_fakeroot pkg create -m $package_build_dir -r $pp_wrkdir/`pp_bsd_cmp_full_name $cmp` -o $pp_wrkdir -v
+ done
+
+}
+
+pp_bsd_name () {
+ typeset cmp="${1:-run}"
+ echo `pp_bsd_cmp_full_name $cmp`"-${pp_bsd_version:-$version}.txz"
+}
+
+pp_backend_bsd_names () {
+ for cmp in $pp_components; do
+ echo `pp_bsd_cmp_full_name $cmp`"-${pp_bsd_version:-$version}.txz"
+ done
+}
+
+pp_backend_bsd_cleanup () {
+ :
+}
+
+pp_backend_bsd_probe () {
+ echo "${pp_bsd_os}-${pp_bsd_platform_std}"
+ echo "${pp_bsd_os}${pp_bsd_os_rev}-${pp_bsd_platform_std}"
+}
+
+
+pp_backend_bsd_vas_platforms() {
+ case "${pp_bsd_platform_std}" in
+ x86_64) echo "FreeBSD-x86_64.txz FreeBSD-i386.txz";;
+ i386) echo "FreeBSD-i386.txz";;
+ *) pp_die "unknown architecture $pp_bsd_platform_std";;
+ esac
+}
+
+
+pp_backend_bsd_install_script () {
+ typeset cmp _cmp_full_name
+
+ echo "#!/bin/sh"
+ pp_install_script_common
+
+ cat <<.
+
+ cmp_to_pkgname () {
+ test x"\$*" = x"all" && set -- $pp_components
+ for cmp
+ do
+ case \$cmp in
+.
+ for cmp in $pp_components; do
+ echo " $cmp) echo '`pp_bsd_cmp_full_name $cmp`';;"
+ done
+
+ cat <<.
+ *) usage;;
+ esac
+ done
+ }
+
+ cmp_to_pathname () {
+ test x"\$*" = x"all" &&
+ set -- $pp_components
+ for cmp
+ do
+ case \$cmp in
+.
+ for cmp in $pp_components; do
+ echo " $cmp) echo \${PP_PKGDESTDIR:-.}/'`pp_bsd_name $cmp`';;"
+ done
+
+ cat <<.
+ *) usage;;
+ esac
+ done
+ }
+
+ test \$# -eq 0 && usage
+ op="\$1"; shift
+ case "\$op" in
+ list-components)
+ test \$# -eq 0 || usage \$op
+ echo $pp_components
+ ;;
+ list-services)
+ test \$# -eq 0 || usage \$op
+ echo $pp_services
+ ;;
+ list-files)
+ test \$# -ge 1 || usage \$op
+ cmp_to_pathname "\$@"
+ ;;
+ install)
+ test \$# -ge 1 || usage \$op
+ pkg add \`cmp_to_pathname "\$@"\`
+ ;;
+ uninstall)
+ test \$# -ge 1 || usage \$op
+ pkg remove \`cmp_to_pkgname "\$@"\`; :
+ ;;
+ start|stop)
+ test \$# -ge 1 || usage \$op
+ ec=0
+ for svc
+ do
+ /etc/rc.d/\$svc \$op || ec=1
+ done
+ exit \$ec
+ ;;
+ print-platform)
+ test \$# -eq 0 || usage \$op
+ echo "${pp_bsd_os}-${pp_bsd_platform}"
+ echo '`pp_backend_bsd_probe`'
+ ;;
+ *)
+ usage
+ ;;
+ esac
+.
+}
+pp_backend_bsd_function() {
+ case "$1" in
+ pp_mkgroup) cat<<'.';;
+ /usr/sbin/pw group show "$1" 2>/dev/null && return 0
+ /usr/sbin/pw group add "$1"
+.
+ pp_mkuser:depends) echo pp_mkgroup;;
+ pp_mkuser) cat<<'.';;
+ #Check if user exists
+ /usr/sbin/pw user show "$1" 2>/dev/null && return 0
+ pp_mkgroup "${2:-$1}" || return 1
+ echo "Creating user $1"
+ /usr/sbin/pw user add \
+ -n "$1" \
+ -d "${3:-/nonexistent}" \
+ -g "${2:-$1}" \
+ -s "${4:-/bin/false}"
+.
+ pp_havelib) cat<<'.';;
+ for pp_tmp_dir in `echo "/usr/local/lib:/usr/lib:/lib${3:+:$3}" | tr : ' '`; do
+ test -r "$pp_tmp_dir/lib$1.so{$2:+.$2}" && return 0
+ done
+ return 1
+.
+ *) false;;
+ esac
+}
+
+
+quest_require_vas () {
+ typeset v d
+
+ if test $# -ne 1; then
+ return
+ fi
+ set -- `echo "$1" | tr . ' '` 0 0 0
+
+ for d
+ do
+ echo $d | grep '^[0-9][0-9]*$' > /dev/null ||
+ pp_error "quest_require_vas: Bad version component $d"
+ done
+
+ test $# -lt 4 &&
+ pp_error "quest_require_vas: missing version number"
+
+ case "$1.$2.$3.$4" in
+ *.0.0.0) v=$1;;
+ *.*.0.0) v=$1.$2;;
+ *.*.*.0) v=$1.$2.$3;;
+ *) v=$1.$2.$3.$4;;
+ esac
+
+ cat <<.
+ if test -x /opt/quest/bin/vastool &&
+ /opt/quest/bin/vastool -v |
+ awk 'NR == 1 {print \$4}' |
+ awk -F. '{ if (\$1<$1 || \$1==$1 && ( \
+ \$2<$2 || \$2==$2 && ( \
+ \$3<$3 || \$2==$3 && ( \
+ \$4<$4 )))) exit(1); }'
+ then
+ exit 0
+ else
+ echo "Requires VAS $v or later"
+ exit 1
+ fi
+.
+}
+pp_main ${1+"$@"}
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..099193c
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,718 @@
+#
+# Copyright (c) 2010-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# @configure_input@
+#
+
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+devdir = @devdir@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+incdir = $(top_srcdir)/include
+rundir = @rundir@
+cross_compiling = @CROSS_COMPILING@
+
+# Compiler & tools to use
+CC = @CC@
+LIBTOOL = @LIBTOOL@
+SED = @SED@
+
+# Our install program supports extra flags...
+INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
+INSTALL_OWNER = -o $(install_uid) -g $(install_gid)
+INSTALL_BACKUP = @INSTALL_BACKUP@
+
+# Libraries
+LT_LIBS = $(top_builddir)/lib/util/libsudo_util.la
+LIBS = @LIBS@ @SUDO_LIBS@ @GETGROUPS_LIB@ @NET_LIBS@ $(LT_LIBS)
+
+# C preprocessor defines
+CPPDEFS = -D_PATH_SUDO_CONF=\"$(sysconfdir)/sudo.conf\" \
+ -DLOCALEDIR=\"$(localedir)\"
+
+# C preprocessor flags
+CPPFLAGS = -I$(incdir) -I$(top_builddir) -I. -I$(srcdir) -I$(top_srcdir) \
+ $(CPPDEFS) @CPPFLAGS@
+
+# Usually -O and/or -g
+CFLAGS = @CFLAGS@
+
+# Flags to pass to the link stage
+LDFLAGS = @LDFLAGS@
+SUDO_LDFLAGS = $(LDFLAGS) @SUDO_LDFLAGS@
+LT_LDFLAGS = @LT_LDFLAGS@
+
+# Flags to pass to libtool
+LTFLAGS = --tag=disable-static
+
+# Address sanitizer flags
+ASAN_CFLAGS = @ASAN_CFLAGS@
+ASAN_LDFLAGS = @ASAN_LDFLAGS@
+
+# PIE flags
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+
+# Stack smashing protection flags
+SSP_CFLAGS = @SSP_CFLAGS@
+SSP_LDFLAGS = @SSP_LDFLAGS@
+
+# cppcheck options, usually set in the top-level Makefile
+CPPCHECK_OPTS = -q --force --enable=warning,performance,portability --suppress=constStatement --error-exitcode=1 --inline-suppr -Dva_copy=va_copy -U__cplusplus -UQUAD_MAX -UQUAD_MIN -UUQUAD_MAX -U_POSIX_HOST_NAME_MAX -U_POSIX_PATH_MAX -U__NBBY -DNSIG=64
+
+# splint options, usually set in the top-level Makefile
+SPLINT_OPTS = -D__restrict= -checks
+
+# PVS-studio options
+PVS_CFG = $(top_srcdir)/PVS-Studio.cfg
+PVS_IGNORE = 'V707,V011,V002,V536'
+PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE)
+
+# Where to install things...
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+noexecfile = @NOEXECFILE@
+noexecdir = @NOEXECDIR@
+tmpfiles_d = @TMPFILES_D@
+
+# User and group ids the installed files should be "owned" by
+install_uid = 0
+install_gid = 0
+
+# File mode to use for shared libraries
+shlib_mode = @SHLIB_MODE@
+
+# Optional init script and rc.d link
+INIT_DIR=@INIT_DIR@
+INIT_SCRIPT=@INIT_SCRIPT@
+RC_LINK=@RC_LINK@
+
+TEST_PROGS = check_ttyname @CHECK_NOEXEC@
+TEST_LIBS = @LIBS@ $(LT_LIBS)
+TEST_LDFLAGS = @LDFLAGS@
+
+#### End of system configuration section. ####
+
+SHELL = @SHELL@
+
+PROGS = @PROGS@
+
+OBJS = conversation.o env_hooks.o exec.o exec_common.o exec_monitor.o \
+ exec_nopty.o exec_pty.o get_pty.o hooks.o net_ifs.o load_plugins.o \
+ parse_args.o preserve_fds.o signal.o sudo.o sudo_edit.o \
+ tcsetpgrp_nobg.o tgetpass.o ttyname.o utmp.o @SUDO_OBJS@
+
+IOBJS = $(OBJS:.o=.i) sesh.i
+
+POBJS = $(IOBJS:.i=.plog)
+
+SESH_OBJS = sesh.o exec_common.o
+
+CHECK_NOEXEC_OBJS = check_noexec.o exec_common.o
+
+CHECK_TTYNAME_OBJS = check_ttyname.o ttyname.o
+
+LIBOBJDIR = $(top_builddir)/@ac_config_libobj_dir@/
+
+VERSION = @PACKAGE_VERSION@
+
+all: $(PROGS)
+
+Makefile: $(srcdir)/Makefile.in
+ cd $(top_builddir) && ./config.status --file src/Makefile
+
+./sudo_usage.h: $(srcdir)/sudo_usage.h.in
+ cd $(top_builddir) && ./config.status --file src/sudo_usage.h
+
+.SUFFIXES: .c .h .i .lo .o .plog
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $<
+
+.c.lo:
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $<
+
+.c.i:
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+
+.i.plog:
+ ifile=$<; rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $${ifile%i}c --i-file $< --output-file $@
+
+sudo: $(OBJS) $(LT_LIBS) @STATIC_SUDOERS@
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(OBJS) $(SUDO_LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS) @STATIC_SUDOERS@
+
+# We can't use -module here since you cannot preload a module on Darwin
+libsudo_noexec.la: sudo_noexec.lo
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LDFLAGS) $(LT_LDFLAGS) $(SSP_LDFLAGS) @LIBDL@ -o $@ sudo_noexec.lo -avoid-version -rpath $(noexecdir) -shrext .so
+
+# Some hackery is required to install this as sudo_noexec, not libsudo_noexec
+sudo_noexec.la: libsudo_noexec.la
+ sed 's/libsudo_noexec/sudo_noexec/g' libsudo_noexec.la > sudo_noexec.la
+ if test -f .libs/libsudo_noexec.lai; then sed 's/libsudo_noexec/sudo_noexec/g' .libs/libsudo_noexec.lai > .libs/sudo_noexec.lai; fi
+ cp -p .libs/libsudo_noexec.so .libs/sudo_noexec.so
+
+sesh: $(SESH_OBJS) $(LT_LIBS)
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(SESH_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
+
+check_noexec: $(CHECK_NOEXEC_OBJS) $(top_builddir)/lib/util/libsudo_util.la sudo_noexec.la
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_NOEXEC_OBJS) $(TEST_LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LIBS)
+
+check_ttyname: $(CHECK_TTYNAME_OBJS) $(top_builddir)/lib/util/libsudo_util.la
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_TTYNAME_OBJS) $(TEST_LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LIBS)
+
+pre-install:
+
+install: install-binaries install-rc @INSTALL_NOEXEC@
+
+install-dirs:
+ # We only create the rc.d dir when installing to the actual system dir
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(bindir) \
+ $(DESTDIR)$(libexecdir)/sudo $(DESTDIR)$(noexecdir)
+ if test -n "$(INIT_SCRIPT)"; then \
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(INIT_DIR); \
+ if test -z "$(DESTDIR)"; then \
+ $(SHELL) $(top_srcdir)/mkinstalldirs \
+ `echo $(RC_LINK) | $(SED) 's,/[^/]*$$,,'`; \
+ fi; \
+ elif test -n "$(tmpfiles_d)"; then \
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(tmpfiles_d); \
+ fi
+
+install-rc: install-dirs
+ # We only create the rc.d link when installing to the actual system dir
+ if [ -n "$(INIT_SCRIPT)" ]; then \
+ $(INSTALL) $(INSTALL_OWNER) -m 0755 $(top_builddir)/init.d/$(INIT_SCRIPT) $(DESTDIR)$(INIT_DIR)/sudo; \
+ if test -z "$(DESTDIR)"; then \
+ rm -f $(RC_LINK); \
+ ln -s $(INIT_DIR)/sudo $(RC_LINK); \
+ fi; \
+ elif test -n "$(tmpfiles_d)"; then \
+ $(INSTALL) $(INSTALL_OWNER) -m 0644 $(top_builddir)/init.d/sudo.conf $(DESTDIR)$(tmpfiles_d)/sudo.conf; \
+ fi
+
+install-binaries: install-dirs $(PROGS)
+ INSTALL_BACKUP='$(INSTALL_BACKUP)' $(LIBTOOL) $(LTFLAGS) --mode=install $(INSTALL) $(INSTALL_OWNER) -m 04755 sudo $(DESTDIR)$(bindir)/sudo
+ rm -f $(DESTDIR)$(bindir)/sudoedit
+ ln -s sudo $(DESTDIR)$(bindir)/sudoedit
+ if [ -f sesh ]; then \
+ INSTALL_BACKUP='$(INSTALL_BACKUP)' $(LIBTOOL) $(LTFLAGS) --mode=install $(INSTALL) $(INSTALL_OWNER) -m 0755 sesh $(DESTDIR)$(libexecdir)/sudo/sesh; \
+ fi
+
+install-doc:
+
+install-includes:
+
+install-noexec: install-dirs sudo_noexec.la
+ INSTALL_BACKUP='$(INSTALL_BACKUP)' $(LIBTOOL) $(LTFLAGS) --mode=install $(INSTALL) $(INSTALL_OWNER) -m $(shlib_mode) sudo_noexec.la $(DESTDIR)$(noexecdir)
+
+install-plugin:
+
+uninstall:
+ -$(LIBTOOL) $(LTFLAGS) --mode=uninstall rm -f $(DESTDIR)$(noexecdir)/sudo_noexec.la
+ -rm -f $(DESTDIR)$(bindir)/sudo \
+ $(DESTDIR)$(bindir)/sudoedit \
+ $(DESTDIR)$(libexecdir)/sudo/sesh \
+ $(DESTDIR)/usr/lib/tmpfiles.d/sudo.conf
+ -test -z "$(INSTALL_BACKUP)" || \
+ rm -f $(DESTDIR)$(bindir)/sudo$(INSTALL_BACKUP) \
+ $(DESTDIR)$(libexecdir)/sudo/sesh$(INSTALL_BACKUP) \
+ $(DESTDIR)$(noexecdir)/sudo_noexec.so$(INSTALL_BACKUP)
+ -test -z "$(INIT_SCRIPT)" || \
+ rm -f $(DESTDIR)$(RC_LINK) $(DESTDIR)$(INIT_DIR)/sudo
+
+splint:
+ splint $(SPLINT_OPTS) -I$(incdir) -I$(top_builddir) -I. -I$(srcdir) -I$(top_srcdir) $(srcdir)/*.c
+
+cppcheck:
+ cppcheck $(CPPCHECK_OPTS) -I$(incdir) -I$(top_builddir) -I. -I$(srcdir) -I$(top_srcdir) $(srcdir)/*.c
+
+pvs-log-files: $(POBJS)
+
+pvs-studio: $(POBJS)
+ plog-converter $(PVS_LOG_OPTS) $(POBJS)
+
+check: $(TEST_PROGS)
+ @if test X"$(cross_compiling)" != X"yes"; then \
+ ./check_ttyname; \
+ if test X"@CHECK_NOEXEC@" != X""; then \
+ ./check_noexec .libs/$(noexecfile); \
+ fi; \
+ fi
+
+clean:
+ -$(LIBTOOL) $(LTFLAGS) --mode=clean rm -f $(PROGS) $(TEST_PROGS) \
+ *.lo *.o *.la *.a *.i *.plog stamp-* core *.core core.* nohup.out
+
+mostlyclean: clean
+
+distclean: clean
+ -rm -rf Makefile .libs sudo_usage.h
+
+clobber: distclean
+
+realclean: distclean
+ rm -f TAGS tags
+
+cleandir: realclean
+
+# *Not* auto-generated to avoid building with ASAN
+sudo_noexec.lo: $(srcdir)/sudo_noexec.c $(incdir)/sudo_compat.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sudo_noexec.c
+
+# Autogenerated dependencies, do not modify
+check_noexec.o: $(srcdir)/regress/noexec/check_noexec.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(srcdir)/sudo_exec.h $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/noexec/check_noexec.c
+check_noexec.i: $(srcdir)/regress/noexec/check_noexec.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
+ $(srcdir)/sudo_exec.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_noexec.plog: check_noexec.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/noexec/check_noexec.c --i-file $< --output-file $@
+check_ttyname.o: $(srcdir)/regress/ttyname/check_ttyname.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/ttyname/check_ttyname.c
+check_ttyname.i: $(srcdir)/regress/ttyname/check_ttyname.c \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+check_ttyname.plog: check_ttyname.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/ttyname/check_ttyname.c --i-file $< --output-file $@
+conversation.o: $(srcdir)/conversation.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/conversation.c
+conversation.i: $(srcdir)/conversation.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+conversation.plog: conversation.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/conversation.c --i-file $< --output-file $@
+env_hooks.o: $(srcdir)/env_hooks.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_dso.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/env_hooks.c
+env_hooks.i: $(srcdir)/env_hooks.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_dso.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+env_hooks.plog: env_hooks.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/env_hooks.c --i-file $< --output-file $@
+exec.o: $(srcdir)/exec.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/sudo.h $(srcdir)/sudo_exec.h $(srcdir)/sudo_plugin_int.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/exec.c
+exec.i: $(srcdir)/exec.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/sudo.h $(srcdir)/sudo_exec.h $(srcdir)/sudo_plugin_int.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+exec.plog: exec.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/exec.c --i-file $< --output-file $@
+exec_common.o: $(srcdir)/exec_common.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/exec_common.c
+exec_common.i: $(srcdir)/exec_common.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+exec_common.plog: exec_common.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/exec_common.c --i-file $< --output-file $@
+exec_monitor.o: $(srcdir)/exec_monitor.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/exec_monitor.c
+exec_monitor.i: $(srcdir)/exec_monitor.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+exec_monitor.plog: exec_monitor.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/exec_monitor.c --i-file $< --output-file $@
+exec_nopty.o: $(srcdir)/exec_nopty.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/exec_nopty.c
+exec_nopty.i: $(srcdir)/exec_nopty.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+exec_nopty.plog: exec_nopty.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/exec_nopty.c --i-file $< --output-file $@
+exec_pty.o: $(srcdir)/exec_pty.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/exec_pty.c
+exec_pty.i: $(srcdir)/exec_pty.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+exec_pty.plog: exec_pty.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/exec_pty.c --i-file $< --output-file $@
+get_pty.o: $(srcdir)/get_pty.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/get_pty.c
+get_pty.i: $(srcdir)/get_pty.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+get_pty.plog: get_pty.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/get_pty.c --i-file $< --output-file $@
+hooks.o: $(srcdir)/hooks.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/hooks.c
+hooks.i: $(srcdir)/hooks.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+hooks.plog: hooks.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/hooks.c --i-file $< --output-file $@
+load_plugins.o: $(srcdir)/load_plugins.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_dso.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/load_plugins.c
+load_plugins.i: $(srcdir)/load_plugins.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_dso.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+load_plugins.plog: load_plugins.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/load_plugins.c --i-file $< --output-file $@
+net_ifs.o: $(srcdir)/net_ifs.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/net_ifs.c
+net_ifs.i: $(srcdir)/net_ifs.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+net_ifs.plog: net_ifs.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/net_ifs.c --i-file $< --output-file $@
+openbsd.o: $(srcdir)/openbsd.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/openbsd.c
+openbsd.i: $(srcdir)/openbsd.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+openbsd.plog: openbsd.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/openbsd.c --i-file $< --output-file $@
+parse_args.o: $(srcdir)/parse_args.c $(incdir)/compat/getopt.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_lbuf.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h ./sudo_usage.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/parse_args.c
+parse_args.i: $(srcdir)/parse_args.c $(incdir)/compat/getopt.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_lbuf.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h ./sudo_usage.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+parse_args.plog: parse_args.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/parse_args.c --i-file $< --output-file $@
+preload.o: $(srcdir)/preload.c $(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
+ $(incdir)/sudo_plugin.h $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/preload.c
+preload.i: $(srcdir)/preload.c $(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
+ $(incdir)/sudo_plugin.h $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+preload.plog: preload.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/preload.c --i-file $< --output-file $@
+preserve_fds.o: $(srcdir)/preserve_fds.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/preserve_fds.c
+preserve_fds.i: $(srcdir)/preserve_fds.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+preserve_fds.plog: preserve_fds.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/preserve_fds.c --i-file $< --output-file $@
+selinux.o: $(srcdir)/selinux.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/selinux.c
+selinux.i: $(srcdir)/selinux.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+selinux.plog: selinux.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/selinux.c --i-file $< --output-file $@
+sesh.o: $(srcdir)/sesh.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo_exec.h \
+ $(top_builddir)/config.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sesh.c
+sesh.i: $(srcdir)/sesh.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo_exec.h \
+ $(top_builddir)/config.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sesh.plog: sesh.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sesh.c --i-file $< --output-file $@
+signal.o: $(srcdir)/signal.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(srcdir)/sudo_exec.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/signal.c
+signal.i: $(srcdir)/signal.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(srcdir)/sudo_exec.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+signal.plog: signal.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/signal.c --i-file $< --output-file $@
+solaris.o: $(srcdir)/solaris.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_dso.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/solaris.c
+solaris.i: $(srcdir)/solaris.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_dso.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+solaris.plog: solaris.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/solaris.c --i-file $< --output-file $@
+sudo.o: $(srcdir)/sudo.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h ./sudo_usage.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sudo.c
+sudo.i: $(srcdir)/sudo.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h ./sudo_usage.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sudo.plog: sudo.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudo.c --i-file $< --output-file $@
+sudo_edit.o: $(srcdir)/sudo_edit.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sudo_edit.c
+sudo_edit.i: $(srcdir)/sudo_edit.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+sudo_edit.plog: sudo_edit.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudo_edit.c --i-file $< --output-file $@
+tcsetpgrp_nobg.o: $(srcdir)/tcsetpgrp_nobg.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/tcsetpgrp_nobg.c
+tcsetpgrp_nobg.i: $(srcdir)/tcsetpgrp_nobg.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+tcsetpgrp_nobg.plog: tcsetpgrp_nobg.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/tcsetpgrp_nobg.c --i-file $< --output-file $@
+tgetpass.o: $(srcdir)/tgetpass.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/tgetpass.c
+tgetpass.i: $(srcdir)/tgetpass.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+tgetpass.plog: tgetpass.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/tgetpass.c --i-file $< --output-file $@
+ttyname.o: $(srcdir)/ttyname.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/ttyname.c
+ttyname.i: $(srcdir)/ttyname.c $(incdir)/compat/stdbool.h \
+ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
+ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
+ $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+ttyname.plog: ttyname.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/ttyname.c --i-file $< --output-file $@
+utmp.o: $(srcdir)/utmp.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/sudo.h $(srcdir)/sudo_exec.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/utmp.c
+utmp.i: $(srcdir)/utmp.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/sudo.h $(srcdir)/sudo_exec.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(CC) -E -o $@ $(CPPFLAGS) $<
+utmp.plog: utmp.i
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/utmp.c --i-file $< --output-file $@
diff --git a/src/conversation.c b/src/conversation.c
new file mode 100644
index 0000000..fccb3d6
--- /dev/null
+++ b/src/conversation.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 1999-2005, 2007-2012 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "sudo.h"
+#include "sudo_plugin.h"
+#include "sudo_plugin_int.h"
+
+extern int tgetpass_flags; /* XXX */
+
+/*
+ * Sudo conversation function.
+ */
+int
+sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],
+ struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
+{
+ char *pass;
+ int fd, n;
+ const int conv_debug_instance = sudo_debug_get_active_instance();
+
+ sudo_debug_set_active_instance(sudo_debug_instance);
+
+ for (n = 0; n < num_msgs; n++) {
+ const struct sudo_conv_message *msg = &msgs[n];
+ int flags = tgetpass_flags;
+ FILE *fp = stdout;
+
+ switch (msg->msg_type & 0xff) {
+ case SUDO_CONV_PROMPT_ECHO_ON:
+ SET(flags, TGP_ECHO);
+ goto read_pass;
+ case SUDO_CONV_PROMPT_MASK:
+ SET(flags, TGP_MASK);
+ /* FALLTHROUGH */
+ case SUDO_CONV_PROMPT_ECHO_OFF:
+ if (ISSET(msg->msg_type, SUDO_CONV_PROMPT_ECHO_OK))
+ SET(flags, TGP_NOECHO_TRY);
+ read_pass:
+ /* Read the password unless interrupted. */
+ pass = tgetpass(msg->msg, msg->timeout, flags, callback);
+ if (pass == NULL)
+ goto err;
+ replies[n].reply = strdup(pass);
+ if (replies[n].reply == NULL) {
+ sudo_fatalx_nodebug(U_("%s: %s"), "sudo_conversation",
+ U_("unable to allocate memory"));
+ }
+ memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
+ break;
+ case SUDO_CONV_ERROR_MSG:
+ fp = stderr;
+ /* FALLTHROUGH */
+ case SUDO_CONV_INFO_MSG:
+ if (msg->msg != NULL) {
+ if (ISSET(msg->msg_type, SUDO_CONV_PREFER_TTY)) {
+ /* Try writing to /dev/tty first. */
+ if ((fd = open(_PATH_TTY, O_WRONLY)) != -1) {
+ ssize_t nwritten =
+ write(fd, msg->msg, strlen(msg->msg));
+ close(fd);
+ if (nwritten != -1)
+ break;
+ }
+ }
+ if (fputs(msg->msg, fp) == EOF)
+ goto err;
+ }
+ break;
+ default:
+ goto err;
+ }
+ }
+
+ sudo_debug_set_active_instance(conv_debug_instance);
+ return 0;
+
+err:
+ /* Zero and free allocated memory and return an error. */
+ if (replies != 0) {
+ do {
+ struct sudo_conv_reply *repl = &replies[n];
+ if (repl->reply == NULL)
+ continue;
+ memset_s(repl->reply, SUDO_CONV_REPL_MAX, 0, strlen(repl->reply));
+ free(repl->reply);
+ repl->reply = NULL;
+ } while (n--);
+ }
+
+ sudo_debug_set_active_instance(conv_debug_instance);
+ return -1;
+}
+
+int
+sudo_conversation_1_7(int num_msgs, const struct sudo_conv_message msgs[],
+ struct sudo_conv_reply replies[])
+{
+ return sudo_conversation(num_msgs, msgs, replies, NULL);
+}
+
+int
+sudo_conversation_printf(int msg_type, const char *fmt, ...)
+{
+ va_list ap;
+ int len;
+ const int conv_debug_instance = sudo_debug_get_active_instance();
+
+ sudo_debug_set_active_instance(sudo_debug_instance);
+
+ switch (msg_type) {
+ case SUDO_CONV_INFO_MSG:
+ va_start(ap, fmt);
+ len = vfprintf(stdout, fmt, ap);
+ va_end(ap);
+ break;
+ case SUDO_CONV_ERROR_MSG:
+ va_start(ap, fmt);
+ len = vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ break;
+ default:
+ len = -1;
+ errno = EINVAL;
+ break;
+ }
+
+ sudo_debug_set_active_instance(conv_debug_instance);
+ return len;
+}
diff --git a/src/env_hooks.c b/src/env_hooks.c
new file mode 100644
index 0000000..8a0b26c
--- /dev/null
+++ b/src/env_hooks.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2010, 2012-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <errno.h>
+
+#include "sudo.h"
+#include "sudo_plugin.h"
+#include "sudo_dso.h"
+
+extern char **environ; /* global environment pointer */
+static char **priv_environ; /* private environment pointer */
+
+/*
+ * NOTE: we don't use dlsym() to find the libc getenv()
+ * since this may allocate memory on some systems (glibc)
+ * which leads to a hang if malloc() calls getenv (jemalloc).
+ */
+char *
+getenv_unhooked(const char *name)
+{
+ char **ep, *val = NULL;
+ size_t namelen = 0;
+
+ /* For BSD compatibility, treat '=' in name like end of string. */
+ while (name[namelen] != '\0' && name[namelen] != '=')
+ namelen++;
+ for (ep = environ; *ep != NULL; ep++) {
+ if (strncmp(*ep, name, namelen) == 0 && (*ep)[namelen] == '=') {
+ val = *ep + namelen + 1;
+ break;
+ }
+ }
+ return val;
+}
+
+__dso_public char *
+getenv(const char *name)
+{
+ char *val = NULL;
+
+ switch (process_hooks_getenv(name, &val)) {
+ case SUDO_HOOK_RET_STOP:
+ return val;
+ case SUDO_HOOK_RET_ERROR:
+ return NULL;
+ default:
+ return getenv_unhooked(name);
+ }
+}
+
+static int
+rpl_putenv(PUTENV_CONST char *string)
+{
+ char **ep;
+ size_t len;
+ bool found = false;
+
+ /* Look for existing entry. */
+ len = (strchr(string, '=') - string) + 1;
+ for (ep = environ; *ep != NULL; ep++) {
+ if (strncmp(string, *ep, len) == 0) {
+ *ep = (char *)string;
+ found = true;
+ break;
+ }
+ }
+ /* Prune out duplicate variables. */
+ if (found) {
+ while (*ep != NULL) {
+ if (strncmp(string, *ep, len) == 0) {
+ char **cur = ep;
+ while ((*cur = *(cur + 1)) != NULL)
+ cur++;
+ } else {
+ ep++;
+ }
+ }
+ }
+
+ /* Append at the end if not already found. */
+ if (!found) {
+ size_t env_len = (size_t)(ep - environ);
+ char **envp = reallocarray(priv_environ, env_len + 2, sizeof(char *));
+ if (envp == NULL)
+ return -1;
+ if (environ != priv_environ)
+ memcpy(envp, environ, env_len * sizeof(char *));
+ envp[env_len++] = (char *)string;
+ envp[env_len] = NULL;
+ priv_environ = environ = envp;
+ }
+ return 0;
+}
+
+typedef int (*sudo_fn_putenv_t)(PUTENV_CONST char *);
+
+static int
+putenv_unhooked(PUTENV_CONST char *string)
+{
+ sudo_fn_putenv_t fn;
+
+ fn = (sudo_fn_putenv_t)sudo_dso_findsym(SUDO_DSO_NEXT, "putenv");
+ if (fn != NULL)
+ return fn(string);
+ return rpl_putenv(string);
+}
+
+__dso_public int
+putenv(PUTENV_CONST char *string)
+{
+ switch (process_hooks_putenv((char *)string)) {
+ case SUDO_HOOK_RET_STOP:
+ return 0;
+ case SUDO_HOOK_RET_ERROR:
+ return -1;
+ default:
+ return putenv_unhooked(string);
+ }
+}
+
+static int
+rpl_setenv(const char *var, const char *val, int overwrite)
+{
+ char *envstr, *dst;
+ const char *src;
+ size_t esize;
+
+ if (!var || *var == '\0') {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * POSIX says a var name with '=' is an error but BSD
+ * just ignores the '=' and anything after it.
+ */
+ for (src = var; *src != '\0' && *src != '='; src++)
+ continue;
+ esize = (size_t)(src - var) + 2;
+ if (val) {
+ esize += strlen(val); /* glibc treats a NULL val as "" */
+ }
+
+ /* Allocate and fill in envstr. */
+ if ((envstr = malloc(esize)) == NULL)
+ return -1;
+ for (src = var, dst = envstr; *src != '\0' && *src != '=';)
+ *dst++ = *src++;
+ *dst++ = '=';
+ if (val) {
+ for (src = val; *src != '\0';)
+ *dst++ = *src++;
+ }
+ *dst = '\0';
+
+ if (!overwrite && getenv(var) != NULL) {
+ free(envstr);
+ return 0;
+ }
+ if (rpl_putenv(envstr) == -1) {
+ free(envstr);
+ return -1;
+ }
+ return 0;
+}
+
+typedef int (*sudo_fn_setenv_t)(const char *, const char *, int);
+
+static int
+setenv_unhooked(const char *var, const char *val, int overwrite)
+{
+ sudo_fn_setenv_t fn;
+
+ fn = (sudo_fn_setenv_t)sudo_dso_findsym(SUDO_DSO_NEXT, "setenv");
+ if (fn != NULL)
+ return fn(var, val, overwrite);
+ return rpl_setenv(var, val, overwrite);
+}
+
+__dso_public int
+setenv(const char *var, const char *val, int overwrite)
+{
+ switch (process_hooks_setenv(var, val, overwrite)) {
+ case SUDO_HOOK_RET_STOP:
+ return 0;
+ case SUDO_HOOK_RET_ERROR:
+ return -1;
+ default:
+ return setenv_unhooked(var, val, overwrite);
+ }
+}
+
+static int
+rpl_unsetenv(const char *var)
+{
+ char **ep = environ;
+ size_t len;
+
+ if (var == NULL || *var == '\0' || strchr(var, '=') != NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ len = strlen(var);
+ while (*ep != NULL) {
+ if (strncmp(var, *ep, len) == 0 && (*ep)[len] == '=') {
+ /* Found it; shift remainder + NULL over by one. */
+ char **cur = ep;
+ while ((*cur = *(cur + 1)) != NULL)
+ cur++;
+ /* Keep going, could be multiple instances of the var. */
+ } else {
+ ep++;
+ }
+ }
+ return 0;
+}
+
+#ifdef UNSETENV_VOID
+typedef void (*sudo_fn_unsetenv_t)(const char *);
+#else
+typedef int (*sudo_fn_unsetenv_t)(const char *);
+#endif
+
+static int
+unsetenv_unhooked(const char *var)
+{
+ int ret = 0;
+ sudo_fn_unsetenv_t fn;
+
+ fn = (sudo_fn_unsetenv_t)sudo_dso_findsym(SUDO_DSO_NEXT, "unsetenv");
+ if (fn != NULL) {
+# ifdef UNSETENV_VOID
+ fn(var);
+# else
+ ret = fn(var);
+# endif
+ } else {
+ ret = rpl_unsetenv(var);
+ }
+ return ret;
+}
+
+#ifdef UNSETENV_VOID
+__dso_public void
+#else
+__dso_public int
+#endif
+unsetenv(const char *var)
+{
+ int ret;
+
+ switch (process_hooks_unsetenv(var)) {
+ case SUDO_HOOK_RET_STOP:
+ ret = 0;
+ break;
+ case SUDO_HOOK_RET_ERROR:
+ ret = -1;
+ break;
+ default:
+ ret = unsetenv_unhooked(var);
+ break;
+ }
+#ifndef UNSETENV_VOID
+ return ret;
+#endif
+}
diff --git a/src/exec.c b/src/exec.c
new file mode 100644
index 0000000..28d847d
--- /dev/null
+++ b/src/exec.c
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 2009-2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <signal.h>
+#ifdef HAVE_LOGIN_CAP_H
+# include <login_cap.h>
+# ifndef LOGIN_SETENV
+# define LOGIN_SETENV 0
+# endif
+#endif
+#ifdef HAVE_PROJECT_H
+# include <project.h>
+# include <sys/task.h>
+#endif
+
+#include "sudo.h"
+#include "sudo_exec.h"
+#include "sudo_event.h"
+#include "sudo_plugin.h"
+#include "sudo_plugin_int.h"
+
+#ifdef __linux__
+static struct rlimit nproclimit;
+#endif
+
+/*
+ * Unlimit the number of processes since Linux's setuid() will
+ * apply resource limits when changing uid and return EAGAIN if
+ * nproc would be exceeded by the uid switch.
+ */
+static void
+unlimit_nproc(void)
+{
+#ifdef __linux__
+ struct rlimit rl;
+ debug_decl(unlimit_nproc, SUDO_DEBUG_UTIL)
+
+ if (getrlimit(RLIMIT_NPROC, &nproclimit) != 0)
+ sudo_warn("getrlimit");
+ rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
+ if (setrlimit(RLIMIT_NPROC, &rl) != 0) {
+ rl.rlim_cur = rl.rlim_max = nproclimit.rlim_max;
+ if (setrlimit(RLIMIT_NPROC, &rl) != 0)
+ sudo_warn("setrlimit");
+ }
+ debug_return;
+#endif /* __linux__ */
+}
+
+/*
+ * Restore saved value of RLIMIT_NPROC.
+ */
+static void
+restore_nproc(void)
+{
+#ifdef __linux__
+ debug_decl(restore_nproc, SUDO_DEBUG_UTIL)
+
+ if (setrlimit(RLIMIT_NPROC, &nproclimit) != 0)
+ sudo_warn("setrlimit");
+
+ debug_return;
+#endif /* __linux__ */
+}
+
+/*
+ * Setup the execution environment immediately prior to the call to execve().
+ * Group setup is performed by policy_init_session(), called earlier.
+ * Returns true on success and false on failure.
+ */
+static bool
+exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
+{
+ bool ret = false;
+ debug_decl(exec_setup, SUDO_DEBUG_EXEC)
+
+#ifdef HAVE_SELINUX
+ if (ISSET(details->flags, CD_RBAC_ENABLED)) {
+ if (selinux_setup(details->selinux_role, details->selinux_type,
+ ptyname ? ptyname : user_details.tty, ptyfd) == -1)
+ goto done;
+ }
+#endif
+
+ /* Restore coredumpsize resource limit before running. */
+ if (sudo_conf_disable_coredump())
+ disable_coredump(true);
+
+ if (details->pw != NULL) {
+#ifdef HAVE_PROJECT_H
+ set_project(details->pw);
+#endif
+#ifdef HAVE_PRIV_SET
+ if (details->privs != NULL) {
+ if (setppriv(PRIV_SET, PRIV_INHERITABLE, details->privs) != 0) {
+ sudo_warn("unable to set privileges");
+ goto done;
+ }
+ }
+ if (details->limitprivs != NULL) {
+ if (setppriv(PRIV_SET, PRIV_LIMIT, details->limitprivs) != 0) {
+ sudo_warn("unable to set limit privileges");
+ goto done;
+ }
+ } else if (details->privs != NULL) {
+ if (setppriv(PRIV_SET, PRIV_LIMIT, details->privs) != 0) {
+ sudo_warn("unable to set limit privileges");
+ goto done;
+ }
+ }
+#endif /* HAVE_PRIV_SET */
+
+#ifdef HAVE_GETUSERATTR
+ if (aix_prep_user(details->pw->pw_name, ptyname ? ptyname : user_details.tty) != 0) {
+ /* error message displayed by aix_prep_user */
+ goto done;
+ }
+#endif
+#ifdef HAVE_LOGIN_CAP_H
+ if (details->login_class) {
+ int flags;
+ login_cap_t *lc;
+
+ /*
+ * We only use setusercontext() to set the nice value and rlimits
+ * unless this is a login shell (sudo -i).
+ */
+ lc = login_getclass((char *)details->login_class);
+ if (!lc) {
+ sudo_warnx(U_("unknown login class %s"), details->login_class);
+ errno = ENOENT;
+ goto done;
+ }
+ if (ISSET(details->flags, CD_LOGIN_SHELL)) {
+ /* Set everything except user, group and login name. */
+ flags = LOGIN_SETALL;
+ CLR(flags, LOGIN_SETGROUP|LOGIN_SETLOGIN|LOGIN_SETUSER|LOGIN_SETENV|LOGIN_SETPATH);
+ CLR(details->flags, CD_SET_UMASK); /* LOGIN_UMASK instead */
+ } else {
+ flags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY;
+ }
+ if (setusercontext(lc, details->pw, details->pw->pw_uid, flags)) {
+ sudo_warn(U_("unable to set user context"));
+ if (details->pw->pw_uid != ROOT_UID)
+ goto done;
+ }
+ }
+#endif /* HAVE_LOGIN_CAP_H */
+ }
+
+ if (ISSET(details->flags, CD_SET_GROUPS)) {
+ /* set_user_groups() prints error message on failure. */
+ if (!set_user_groups(details))
+ goto done;
+ }
+
+ if (ISSET(details->flags, CD_SET_PRIORITY)) {
+ if (setpriority(PRIO_PROCESS, 0, details->priority) != 0) {
+ sudo_warn(U_("unable to set process priority"));
+ goto done;
+ }
+ }
+ if (ISSET(details->flags, CD_SET_UMASK))
+ (void) umask(details->umask);
+ if (details->chroot) {
+ if (chroot(details->chroot) != 0 || chdir("/") != 0) {
+ sudo_warn(U_("unable to change root to %s"), details->chroot);
+ goto done;
+ }
+ }
+
+ /*
+ * Unlimit the number of processes since Linux's setuid() will
+ * return EAGAIN if RLIMIT_NPROC would be exceeded by the uid switch.
+ */
+ unlimit_nproc();
+
+#if defined(HAVE_SETRESUID)
+ if (setresuid(details->uid, details->euid, details->euid) != 0) {
+ sudo_warn(U_("unable to change to runas uid (%u, %u)"),
+ (unsigned int)details->uid, (unsigned int)details->euid);
+ goto done;
+ }
+#elif defined(HAVE_SETREUID)
+ if (setreuid(details->uid, details->euid) != 0) {
+ sudo_warn(U_("unable to change to runas uid (%u, %u)"),
+ (unsigned int)details->uid, (unsigned int)details->euid);
+ goto done;
+ }
+#else
+ /* Cannot support real user ID that is different from effective user ID. */
+ if (setuid(details->euid) != 0) {
+ sudo_warn(U_("unable to change to runas uid (%u, %u)"),
+ (unsigned int)details->euid, (unsigned int)details->euid);
+ goto done;
+ }
+#endif /* !HAVE_SETRESUID && !HAVE_SETREUID */
+
+ /* Restore previous value of RLIMIT_NPROC. */
+ restore_nproc();
+
+ /*
+ * Only change cwd if we have chroot()ed or the policy modules
+ * specifies a different cwd. Must be done after uid change.
+ */
+ if (details->cwd != NULL) {
+ if (details->chroot || user_details.cwd == NULL ||
+ strcmp(details->cwd, user_details.cwd) != 0) {
+ /* Note: cwd is relative to the new root, if any. */
+ if (chdir(details->cwd) != 0) {
+ sudo_warn(U_("unable to change directory to %s"), details->cwd);
+ goto done;
+ }
+ }
+ }
+
+ ret = true;
+
+done:
+ debug_return_bool(ret);
+}
+
+/*
+ * Setup the execution environment and execute the command.
+ * If SELinux is enabled, run the command via sesh, otherwise
+ * execute it directly.
+ * If the exec fails, cstat is filled in with the value of errno.
+ */
+void
+exec_cmnd(struct command_details *details, int errfd)
+{
+ debug_decl(exec_cmnd, SUDO_DEBUG_EXEC)
+
+ restore_signals();
+ if (exec_setup(details, NULL, -1) == true) {
+ /* headed for execve() */
+ if (details->closefrom >= 0) {
+ int fd, maxfd;
+ unsigned char *debug_fds;
+
+ /* Preserve debug fds and error pipe as needed. */
+ maxfd = sudo_debug_get_fds(&debug_fds);
+ for (fd = 0; fd <= maxfd; fd++) {
+ if (sudo_isset(debug_fds, fd))
+ add_preserved_fd(&details->preserved_fds, fd);
+ }
+ if (errfd != -1)
+ add_preserved_fd(&details->preserved_fds, errfd);
+
+ /* Close all fds except those explicitly preserved. */
+ closefrom_except(details->closefrom, &details->preserved_fds);
+ }
+#ifdef HAVE_SELINUX
+ if (ISSET(details->flags, CD_RBAC_ENABLED)) {
+ selinux_execve(details->execfd, details->command, details->argv,
+ details->envp, ISSET(details->flags, CD_NOEXEC));
+ } else
+#endif
+ {
+ sudo_execve(details->execfd, details->command, details->argv,
+ details->envp, ISSET(details->flags, CD_NOEXEC));
+ }
+ }
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to exec %s: %s",
+ details->command, strerror(errno));
+ debug_return;
+}
+
+/*
+ * Check for caught signals sent to sudo before command execution.
+ * Also suspends the process if SIGTSTP was caught.
+ * Returns true if we should terminate, else false.
+ */
+bool
+sudo_terminated(struct command_status *cstat)
+{
+ int signo;
+ bool sigtstp = false;
+ debug_decl(sudo_terminated, SUDO_DEBUG_EXEC)
+
+ for (signo = 0; signo < NSIG; signo++) {
+ if (signal_pending(signo)) {
+ switch (signo) {
+ case SIGCHLD:
+ /* Ignore. */
+ break;
+ case SIGTSTP:
+ /* Suspend below if not terminated. */
+ sigtstp = true;
+ break;
+ default:
+ /* Terminal signal, do not exec command. */
+ cstat->type = CMD_WSTATUS;
+ cstat->val = signo + 128;
+ debug_return_bool(true);
+ break;
+ }
+ }
+ }
+ if (sigtstp) {
+ struct sigaction sa;
+ sigset_t set, oset;
+
+ /* Send SIGTSTP to ourselves, unblocking it if needed. */
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = SIG_DFL;
+ if (sudo_sigaction(SIGTSTP, &sa, NULL) != 0)
+ sudo_warn(U_("unable to set handler for signal %d"), SIGTSTP);
+ sigemptyset(&set);
+ sigaddset(&set, SIGTSTP);
+ sigprocmask(SIG_UNBLOCK, &set, &oset);
+ if (kill(getpid(), SIGTSTP) != 0)
+ sudo_warn("kill(%d, SIGTSTP)", (int)getpid());
+ sigprocmask(SIG_SETMASK, &oset, NULL);
+ /* No need to restore old SIGTSTP handler. */
+ }
+ debug_return_bool(false);
+}
+
+#if SUDO_API_VERSION != SUDO_API_MKVERSION(1, 13)
+# error "Update sudo_needs_pty() after changing the plugin API"
+#endif
+static bool
+sudo_needs_pty(struct command_details *details)
+{
+ struct plugin_container *plugin;
+
+ if (ISSET(details->flags, CD_USE_PTY))
+ return true;
+
+ TAILQ_FOREACH(plugin, &io_plugins, entries) {
+ if (plugin->u.io->log_ttyin != NULL ||
+ plugin->u.io->log_ttyout != NULL ||
+ plugin->u.io->log_stdin != NULL ||
+ plugin->u.io->log_stdout != NULL ||
+ plugin->u.io->log_stderr != NULL ||
+ plugin->u.io->change_winsize != NULL ||
+ plugin->u.io->log_suspend != NULL)
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Execute a command, potentially in a pty with I/O loggging, and
+ * wait for it to finish.
+ * This is a little bit tricky due to how POSIX job control works and
+ * we fact that we have two different controlling terminals to deal with.
+ */
+int
+sudo_execute(struct command_details *details, struct command_status *cstat)
+{
+ debug_decl(sudo_execute, SUDO_DEBUG_EXEC)
+
+ /* If running in background mode, fork and exit. */
+ if (ISSET(details->flags, CD_BACKGROUND)) {
+ switch (sudo_debug_fork()) {
+ case -1:
+ cstat->type = CMD_ERRNO;
+ cstat->val = errno;
+ debug_return_int(-1);
+ case 0:
+ /* child continues without controlling terminal */
+ (void)setpgid(0, 0);
+ break;
+ default:
+ /* parent exits (but does not flush buffers) */
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__,
+ sudo_debug_subsys, 0);
+ _exit(0);
+ }
+ }
+
+ /*
+ * Run the command in a new pty if there is an I/O plugin or the policy
+ * has requested a pty. If /dev/tty is unavailable and no I/O plugin
+ * is configured, this returns false and we run the command without a pty.
+ */
+ if (sudo_needs_pty(details)) {
+ if (exec_pty(details, cstat))
+ goto done;
+ }
+
+ /*
+ * If we are not running the command in a pty, we were not invoked
+ * as sudoedit, there is no command timeout and there is no close
+ * function, just exec directly. Only returns on error.
+ */
+ if (!ISSET(details->flags, CD_SET_TIMEOUT|CD_SUDOEDIT) &&
+ policy_plugin.u.policy->close == NULL) {
+ if (!sudo_terminated(cstat)) {
+ exec_cmnd(details, -1);
+ cstat->type = CMD_ERRNO;
+ cstat->val = errno;
+ }
+ goto done;
+ }
+
+ /*
+ * Run the command in the existing tty (if any) and wait for it to finish.
+ */
+ exec_nopty(details, cstat);
+
+done:
+ /* The caller will run any plugin close functions. */
+ debug_return_int(cstat->type == CMD_ERRNO ? -1 : 0);
+}
+
+/*
+ * Kill command with increasing urgency.
+ */
+void
+terminate_command(pid_t pid, bool use_pgrp)
+{
+ debug_decl(terminate_command, SUDO_DEBUG_EXEC);
+
+ /* Avoid killing more than a single process or process group. */
+ if (pid <= 0)
+ debug_return;
+
+ /*
+ * Note that SIGCHLD will interrupt the sleep()
+ */
+ if (use_pgrp) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "killpg %d SIGHUP", (int)pid);
+ killpg(pid, SIGHUP);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "killpg %d SIGTERM", (int)pid);
+ killpg(pid, SIGTERM);
+ sleep(2);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "killpg %d SIGKILL", (int)pid);
+ killpg(pid, SIGKILL);
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "kill %d SIGHUP", (int)pid);
+ kill(pid, SIGHUP);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "kill %d SIGTERM", (int)pid);
+ kill(pid, SIGTERM);
+ sleep(2);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "kill %d SIGKILL", (int)pid);
+ kill(pid, SIGKILL);
+ }
+
+ debug_return;
+}
diff --git a/src/exec_common.c b/src/exec_common.c
new file mode 100644
index 0000000..53abdbf
--- /dev/null
+++ b/src/exec_common.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2009-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#ifdef HAVE_PRIV_SET
+# include <priv.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "sudo.h"
+#include "sudo_exec.h"
+
+#ifdef RTLD_PRELOAD_VAR
+/*
+ * Add a DSO file to LD_PRELOAD or the system equivalent.
+ */
+static char **
+preload_dso(char *envp[], const char *dso_file)
+{
+ char *preload = NULL;
+ int env_len;
+ int preload_idx = -1;
+ bool present = false;
+# ifdef RTLD_PRELOAD_ENABLE_VAR
+ bool enabled = false;
+# else
+ const bool enabled = true;
+# endif
+ debug_decl(preload_dso, SUDO_DEBUG_UTIL)
+
+ /*
+ * Preload a DSO file. For a list of LD_PRELOAD-alikes, see
+ * http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
+ * XXX - need to support 32-bit and 64-bit variants
+ */
+
+ /* Count entries in envp, looking for LD_PRELOAD as we go. */
+ for (env_len = 0; envp[env_len] != NULL; env_len++) {
+ if (preload_idx == -1 && strncmp(envp[env_len], RTLD_PRELOAD_VAR "=",
+ sizeof(RTLD_PRELOAD_VAR)) == 0) {
+ const char *cp = envp[env_len] + sizeof(RTLD_PRELOAD_VAR);
+ const char *end = cp + strlen(cp);
+ const char *ep;
+ const size_t dso_len = strlen(dso_file);
+
+ /* Check to see if dso_file is already present. */
+ for (cp = sudo_strsplit(cp, end, RTLD_PRELOAD_DELIM, &ep);
+ cp != NULL; cp = sudo_strsplit(NULL, end, RTLD_PRELOAD_DELIM,
+ &ep)) {
+ if ((size_t)(ep - cp) == dso_len) {
+ if (memcmp(cp, dso_file, dso_len) == 0) {
+ /* already present */
+ present = true;
+ break;
+ }
+ }
+ }
+
+ /* Save index of existing LD_PRELOAD variable. */
+ preload_idx = env_len;
+ continue;
+ }
+# ifdef RTLD_PRELOAD_ENABLE_VAR
+ if (strncmp(envp[env_len], RTLD_PRELOAD_ENABLE_VAR "=", sizeof(RTLD_PRELOAD_ENABLE_VAR)) == 0) {
+ enabled = true;
+ continue;
+ }
+# endif
+ }
+
+ /*
+ * Make a new copy of envp as needed.
+ * It would be nice to realloc the old envp[] but we don't know
+ * whether it was dynamically allocated. [TODO: plugin API]
+ */
+ if (preload_idx == -1 || !enabled) {
+ const int env_size = env_len + 1 + (preload_idx == -1) + enabled;
+
+ char **nenvp = reallocarray(NULL, env_size, sizeof(*envp));
+ if (nenvp == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ memcpy(nenvp, envp, env_len * sizeof(*envp));
+ nenvp[env_len] = NULL;
+ envp = nenvp;
+ }
+
+ /* Prepend our LD_PRELOAD to existing value or add new entry at the end. */
+ if (!present) {
+ if (preload_idx == -1) {
+# ifdef RTLD_PRELOAD_DEFAULT
+ asprintf(&preload, "%s=%s%s%s", RTLD_PRELOAD_VAR, dso_file,
+ RTLD_PRELOAD_DELIM, RTLD_PRELOAD_DEFAULT);
+# else
+ preload = sudo_new_key_val(RTLD_PRELOAD_VAR, dso_file);
+# endif
+ if (preload == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ envp[env_len++] = preload;
+ envp[env_len] = NULL;
+ } else {
+ int len = asprintf(&preload, "%s=%s%s%s", RTLD_PRELOAD_VAR,
+ dso_file, RTLD_PRELOAD_DELIM, envp[preload_idx]);
+ if (len == -1) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ envp[preload_idx] = preload;
+ }
+ }
+# ifdef RTLD_PRELOAD_ENABLE_VAR
+ if (!enabled) {
+ envp[env_len++] = RTLD_PRELOAD_ENABLE_VAR "=";
+ envp[env_len] = NULL;
+ }
+# endif
+
+ debug_return_ptr(envp);
+}
+#endif /* RTLD_PRELOAD_VAR */
+
+/*
+ * Disable execution of child processes in the command we are about
+ * to run. On systems with privilege sets, we can remove the exec
+ * privilege. On other systems we use LD_PRELOAD and the like.
+ */
+char **
+disable_execute(char *envp[], const char *dso)
+{
+ debug_decl(disable_execute, SUDO_DEBUG_UTIL)
+
+#ifdef HAVE_PRIV_SET
+ /* Solaris privileges, remove PRIV_PROC_EXEC post-execve. */
+ (void)priv_set(PRIV_ON, PRIV_INHERITABLE, "PRIV_FILE_DAC_READ", NULL);
+ (void)priv_set(PRIV_ON, PRIV_INHERITABLE, "PRIV_FILE_DAC_WRITE", NULL);
+ (void)priv_set(PRIV_ON, PRIV_INHERITABLE, "PRIV_FILE_DAC_SEARCH", NULL);
+ if (priv_set(PRIV_OFF, PRIV_LIMIT, "PRIV_PROC_EXEC", NULL) == 0)
+ debug_return_ptr(envp);
+ sudo_warn(U_("unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"));
+#endif /* HAVE_PRIV_SET */
+
+#ifdef RTLD_PRELOAD_VAR
+ if (dso != NULL)
+ envp = preload_dso(envp, dso);
+#endif /* RTLD_PRELOAD_VAR */
+
+ debug_return_ptr(envp);
+}
+
+/*
+ * Like execve(2) but falls back to running through /bin/sh
+ * ala execvp(3) if we get ENOEXEC.
+ */
+int
+sudo_execve(int fd, const char *path, char *const argv[], char *envp[], bool noexec)
+{
+ debug_decl(sudo_execve, SUDO_DEBUG_UTIL)
+
+ sudo_debug_execve(SUDO_DEBUG_INFO, path, argv, envp);
+
+ /* Modify the environment as needed to disable further execve(). */
+ if (noexec)
+ envp = disable_execute(envp, sudo_conf_noexec_path());
+
+#ifdef HAVE_FEXECVE
+ if (fd != -1)
+ fexecve(fd, argv, envp);
+ else
+#endif
+ execve(path, argv, envp);
+ if (fd == -1 && errno == ENOEXEC) {
+ int argc;
+ char **nargv;
+
+ for (argc = 0; argv[argc] != NULL; argc++)
+ continue;
+ nargv = reallocarray(NULL, argc + 2, sizeof(char *));
+ if (nargv != NULL) {
+ nargv[0] = "sh";
+ nargv[1] = (char *)path;
+ memcpy(nargv + 2, argv + 1, argc * sizeof(char *));
+ execve(_PATH_SUDO_BSHELL, nargv, envp);
+ free(nargv);
+ }
+ }
+ debug_return_int(-1);
+}
diff --git a/src/exec_monitor.c b/src/exec_monitor.c
new file mode 100644
index 0000000..4a81b5d
--- /dev/null
+++ b/src/exec_monitor.c
@@ -0,0 +1,719 @@
+/*
+ * Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <termios.h>
+
+#include "sudo.h"
+#include "sudo_event.h"
+#include "sudo_exec.h"
+#include "sudo_plugin.h"
+#include "sudo_plugin_int.h"
+
+struct monitor_closure {
+ pid_t cmnd_pid;
+ pid_t cmnd_pgrp;
+ pid_t mon_pgrp;
+ int backchannel;
+ struct command_status *cstat;
+ struct sudo_event_base *evbase;
+ struct sudo_event *errpipe_event;
+ struct sudo_event *backchannel_event;
+ struct sudo_event *sigint_event;
+ struct sudo_event *sigquit_event;
+ struct sudo_event *sigtstp_event;
+ struct sudo_event *sigterm_event;
+ struct sudo_event *sighup_event;
+ struct sudo_event *sigusr1_event;
+ struct sudo_event *sigusr2_event;
+ struct sudo_event *sigchld_event;
+};
+
+static bool tty_initialized;
+
+/*
+ * Deliver a signal to the running command.
+ * The signal was either forwarded to us by the parent sudo process
+ * or was received by the monitor itself.
+ *
+ * There are two "special" signals, SIGCONT_FG and SIGCONT_BG that
+ * also specify whether the command should have the controlling tty.
+ */
+static void
+deliver_signal(struct monitor_closure *mc, int signo, bool from_parent)
+{
+ char signame[SIG2STR_MAX];
+ debug_decl(deliver_signal, SUDO_DEBUG_EXEC);
+
+ /* Avoid killing more than a single process or process group. */
+ if (mc->cmnd_pid <= 0)
+ debug_return;
+
+ if (signo == SIGCONT_FG)
+ strlcpy(signame, "CONT_FG", sizeof(signame));
+ else if (signo == SIGCONT_BG)
+ strlcpy(signame, "CONT_BG", sizeof(signame));
+ else if (sig2str(signo, signame) == -1)
+ snprintf(signame, sizeof(signame), "%d", signo);
+
+ /* Handle signal from parent or monitor. */
+ sudo_debug_printf(SUDO_DEBUG_INFO, "received SIG%s%s",
+ signame, from_parent ? " from parent" : "");
+ switch (signo) {
+ case SIGALRM:
+ terminate_command(mc->cmnd_pid, true);
+ break;
+ case SIGCONT_FG:
+ /* Continue in foreground, grant it controlling tty. */
+ if (tcsetpgrp(io_fds[SFD_SLAVE], mc->cmnd_pgrp) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to set foreground pgrp to %d (command)",
+ __func__, (int)mc->cmnd_pgrp);
+ }
+ /* Lazily initialize the pty if needed. */
+ if (!tty_initialized) {
+ if (sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE]))
+ tty_initialized = true;
+ }
+ killpg(mc->cmnd_pid, SIGCONT);
+ break;
+ case SIGCONT_BG:
+ /* Continue in background, I take controlling tty. */
+ if (tcsetpgrp(io_fds[SFD_SLAVE], mc->mon_pgrp) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to set foreground pgrp to %d (monitor)",
+ __func__, (int)mc->mon_pgrp);
+ }
+ killpg(mc->cmnd_pid, SIGCONT);
+ break;
+ case SIGKILL:
+ _exit(1); /* XXX */
+ /* NOTREACHED */
+ default:
+ /* Relay signal to command. */
+ killpg(mc->cmnd_pid, signo);
+ break;
+ }
+ debug_return;
+}
+
+/*
+ * Unpack rows and cols from a CMD_TTYWINCH value, set the new window
+ * size on the pty slave and inform the command of the change.
+ */
+static void
+handle_winch(struct monitor_closure *mc, unsigned int wsize_packed)
+{
+ struct winsize wsize, owsize;
+ debug_decl(handle_winch, SUDO_DEBUG_EXEC);
+
+ /* Rows and colums are stored as two shorts packed into a single int. */
+ wsize.ws_row = wsize_packed & 0xffff;
+ wsize.ws_col = (wsize_packed >> 16) & 0xffff;
+
+ if (ioctl(io_fds[SFD_SLAVE], TIOCGWINSZ, &owsize) == 0 &&
+ (wsize.ws_row != owsize.ws_row || wsize.ws_col != owsize.ws_col)) {
+
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "window size change %dx%d -> %dx%d",
+ owsize.ws_col, owsize.ws_row, wsize.ws_col, wsize.ws_row);
+
+ (void)ioctl(io_fds[SFD_SLAVE], TIOCSWINSZ, &wsize);
+ deliver_signal(mc, SIGWINCH, true);
+ }
+
+ debug_return;
+}
+
+/*
+ * Send status to parent over socketpair.
+ * Return value is the same as send(2).
+ */
+static int
+send_status(int fd, struct command_status *cstat)
+{
+ int n = -1;
+ debug_decl(send_status, SUDO_DEBUG_EXEC);
+
+ if (cstat->type != CMD_INVALID) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "sending status message to parent: [%d, %d]",
+ cstat->type, cstat->val);
+ n = send(fd, cstat, sizeof(*cstat), 0);
+ if (n != sizeof(*cstat)) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to send status to parent", __func__);
+ }
+ cstat->type = CMD_INVALID; /* prevent re-sending */
+ }
+ debug_return_int(n);
+}
+
+/*
+ * Wait for command status after receiving SIGCHLD.
+ * If the command was stopped, the status is send back to the parent.
+ * Otherwise, cstat is filled in but not sent.
+ */
+static void
+mon_handle_sigchld(struct monitor_closure *mc)
+{
+ char signame[SIG2STR_MAX];
+ int status;
+ pid_t pid;
+ debug_decl(mon_handle_sigchld, SUDO_DEBUG_EXEC);
+
+ /* Read command status. */
+ do {
+ pid = waitpid(mc->cmnd_pid, &status, WUNTRACED|WCONTINUED|WNOHANG);
+ } while (pid == -1 && errno == EINTR);
+ switch (pid) {
+ case 0:
+ errno = ECHILD;
+ /* FALLTHROUGH */
+ case -1:
+ sudo_warn(U_("%s: %s"), __func__, "waitpid");
+ debug_return;
+ }
+
+ if (WIFCONTINUED(status)) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) resumed",
+ __func__, (int)mc->cmnd_pid);
+ } else if (WIFSTOPPED(status)) {
+ if (sig2str(WSTOPSIG(status), signame) == -1)
+ snprintf(signame, sizeof(signame), "%d", WSTOPSIG(status));
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) stopped, SIG%s",
+ __func__, (int)mc->cmnd_pid, signame);
+ } else if (WIFSIGNALED(status)) {
+ if (sig2str(WTERMSIG(status), signame) == -1)
+ snprintf(signame, sizeof(signame), "%d", WTERMSIG(status));
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) killed, SIG%s",
+ __func__, (int)mc->cmnd_pid, signame);
+ mc->cmnd_pid = -1;
+ } else if (WIFEXITED(status)) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) exited: %d",
+ __func__, (int)mc->cmnd_pid, WEXITSTATUS(status));
+ mc->cmnd_pid = -1;
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_WARN,
+ "%s: unexpected wait status %d for command (%d)",
+ __func__, status, (int)mc->cmnd_pid);
+ }
+
+ /* Don't overwrite execve() failure with child exit status. */
+ if (mc->cstat->type == CMD_INVALID) {
+ /*
+ * Store wait status in cstat and forward to parent if stopped.
+ * Parent does not expect SIGCONT so don't bother sending it.
+ */
+ if (!WIFCONTINUED(status)) {
+ mc->cstat->type = CMD_WSTATUS;
+ mc->cstat->val = status;
+ if (WIFSTOPPED(status)) {
+ /* Save the foreground pgid so we can restore it later. */
+ pid = tcgetpgrp(io_fds[SFD_SLAVE]);
+ if (pid != mc->mon_pgrp)
+ mc->cmnd_pgrp = pid;
+ send_status(mc->backchannel, mc->cstat);
+ }
+ }
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_WARN,
+ "%s: not overwriting command status %d,%d with %d,%d",
+ __func__, mc->cstat->type, mc->cstat->val, CMD_WSTATUS, status);
+ }
+
+ debug_return;
+}
+
+static void
+mon_signal_cb(int signo, int what, void *v)
+{
+ struct sudo_ev_siginfo_container *sc = v;
+ struct monitor_closure *mc = sc->closure;
+ debug_decl(mon_signal_cb, SUDO_DEBUG_EXEC);
+
+ /*
+ * Handle SIGCHLD specially and deliver other signals
+ * directly to the command.
+ */
+ if (signo == SIGCHLD) {
+ mon_handle_sigchld(mc);
+ if (mc->cmnd_pid == -1) {
+ /* Command exited or was killed, exit event loop. */
+ sudo_ev_loopexit(mc->evbase);
+ }
+ } else {
+ /*
+ * If the signal came from the process group of the command we ran,
+ * do not forward it as we don't want the child to indirectly kill
+ * itself. This can happen with, e.g., BSD-derived versions of
+ * reboot that call kill(-1, SIGTERM) to kill all other processes.
+ */
+ if (USER_SIGNALED(sc->siginfo) && sc->siginfo->si_pid != 0) {
+ pid_t si_pgrp = getpgid(sc->siginfo->si_pid);
+ if (si_pgrp != -1) {
+ if (si_pgrp == mc->cmnd_pgrp)
+ debug_return;
+ } else if (sc->siginfo->si_pid == mc->cmnd_pid) {
+ debug_return;
+ }
+ }
+ deliver_signal(mc, signo, false);
+ }
+ debug_return;
+}
+
+/* Note: this is basically the same as errpipe_cb() in exec_nopty.c */
+static void
+mon_errpipe_cb(int fd, int what, void *v)
+{
+ struct monitor_closure *mc = v;
+ ssize_t nread;
+ int errval;
+ debug_decl(mon_errpipe_cb, SUDO_DEBUG_EXEC);
+
+ /*
+ * Read errno from child or EOF when command is executed.
+ * Note that the error pipe is *blocking*.
+ */
+ nread = read(fd, &errval, sizeof(errval));
+ switch (nread) {
+ case -1:
+ if (errno != EAGAIN && errno != EINTR) {
+ if (mc->cstat->val == CMD_INVALID) {
+ /* XXX - need a way to distinguish non-exec error. */
+ mc->cstat->type = CMD_ERRNO;
+ mc->cstat->val = errno;
+ }
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: failed to read error pipe", __func__);
+ sudo_ev_loopbreak(mc->evbase);
+ }
+ break;
+ default:
+ if (nread == 0) {
+ /* The error pipe closes when the command is executed. */
+ sudo_debug_printf(SUDO_DEBUG_INFO, "EOF on error pipe");
+ } else {
+ /* Errno value when child is unable to execute command. */
+ sudo_debug_printf(SUDO_DEBUG_INFO, "errno from child: %s",
+ strerror(errval));
+ mc->cstat->type = CMD_ERRNO;
+ mc->cstat->val = errval;
+ }
+ sudo_ev_del(mc->evbase, mc->errpipe_event);
+ close(fd);
+ break;
+ }
+ debug_return;
+}
+
+static void
+mon_backchannel_cb(int fd, int what, void *v)
+{
+ struct monitor_closure *mc = v;
+ struct command_status cstmp;
+ ssize_t n;
+ debug_decl(mon_backchannel_cb, SUDO_DEBUG_EXEC);
+
+ /*
+ * Read command from backchannel, should be a signal.
+ * Note that the backchannel is a *blocking* socket.
+ */
+ n = recv(fd, &cstmp, sizeof(cstmp), MSG_WAITALL);
+ if (n != sizeof(cstmp)) {
+ if (n == -1) {
+ if (errno == EINTR || errno == EAGAIN)
+ debug_return;
+ sudo_warn(U_("error reading from socketpair"));
+ } else {
+ /* short read or EOF, parent process died? */
+ }
+ /* XXX - need a way to distinguish non-exec error. */
+ mc->cstat->type = CMD_ERRNO;
+ mc->cstat->val = n ? EIO : ECONNRESET;
+ sudo_ev_loopbreak(mc->evbase);
+ } else {
+ switch (cstmp.type) {
+ case CMD_TTYWINCH:
+ handle_winch(mc, cstmp.val);
+ break;
+ case CMD_SIGNO:
+ deliver_signal(mc, cstmp.val, true);
+ break;
+ default:
+ sudo_warnx(U_("unexpected reply type on backchannel: %d"), cstmp.type);
+ break;
+ }
+ }
+ debug_return;
+}
+
+/*
+ * Sets up std{in,out,err} and executes the actual command.
+ * Returns only if execve() fails.
+ */
+static void
+exec_cmnd_pty(struct command_details *details, bool foreground, int errfd)
+{
+ volatile pid_t self = getpid();
+ debug_decl(exec_cmnd_pty, SUDO_DEBUG_EXEC);
+
+ /* Register cleanup function */
+ sudo_fatal_callback_register(pty_cleanup);
+
+ /* Set command process group here too to avoid a race. */
+ setpgid(0, self);
+
+ /* Wire up standard fds, note that stdout/stderr may be pipes. */
+ if (io_fds[SFD_STDIN] != STDIN_FILENO) {
+ if (dup2(io_fds[SFD_STDIN], STDIN_FILENO) == -1)
+ sudo_fatal("dup2");
+ if (io_fds[SFD_STDIN] != io_fds[SFD_SLAVE])
+ close(io_fds[SFD_STDIN]);
+ }
+ if (io_fds[SFD_STDOUT] != STDOUT_FILENO) {
+ if (dup2(io_fds[SFD_STDOUT], STDOUT_FILENO) == -1)
+ sudo_fatal("dup2");
+ if (io_fds[SFD_STDOUT] != io_fds[SFD_SLAVE])
+ close(io_fds[SFD_STDOUT]);
+ }
+ if (io_fds[SFD_STDERR] != STDERR_FILENO) {
+ if (dup2(io_fds[SFD_STDERR], STDERR_FILENO) == -1)
+ sudo_fatal("dup2");
+ if (io_fds[SFD_STDERR] != io_fds[SFD_SLAVE])
+ close(io_fds[SFD_STDERR]);
+ }
+
+ /* Wait for parent to grant us the tty if we are foreground. */
+ if (foreground && !ISSET(details->flags, CD_EXEC_BG)) {
+ struct timespec ts = { 0, 1000 }; /* 1us */
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: waiting for controlling tty",
+ __func__);
+ while (tcgetpgrp(io_fds[SFD_SLAVE]) != self)
+ nanosleep(&ts, NULL);
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: got controlling tty",
+ __func__);
+ }
+
+ /* Done with the pty slave, don't leak it. */
+ if (io_fds[SFD_SLAVE] != -1)
+ close(io_fds[SFD_SLAVE]);
+
+ /* Execute command; only returns on error. */
+ sudo_debug_printf(SUDO_DEBUG_INFO, "executing %s in the %s",
+ details->command, foreground ? "foreground" : "background");
+ exec_cmnd(details, errfd);
+
+ debug_return;
+}
+
+/*
+ * Fill in the monitor closure and setup initial events.
+ * Allocates read events for the signal pipe, error pipe and backchannel.
+ */
+static void
+fill_exec_closure_monitor(struct monitor_closure *mc,
+ struct command_status *cstat, int errfd, int backchannel)
+{
+ debug_decl(fill_exec_closure_monitor, SUDO_DEBUG_EXEC);
+
+ /* Fill in the non-event part of the closure. */
+ mc->cstat = cstat;
+ mc->backchannel = backchannel;
+ mc->mon_pgrp = getpgrp();
+
+ /* Setup event base and events. */
+ mc->evbase = sudo_ev_base_alloc();
+ if (mc->evbase == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+ /* Event for command status via errfd. */
+ mc->errpipe_event = sudo_ev_alloc(errfd,
+ SUDO_EV_READ|SUDO_EV_PERSIST, mon_errpipe_cb, mc);
+ if (mc->errpipe_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(mc->evbase, mc->errpipe_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ /* Event for forwarded signals via backchannel. */
+ mc->backchannel_event = sudo_ev_alloc(backchannel,
+ SUDO_EV_READ|SUDO_EV_PERSIST, mon_backchannel_cb, mc);
+ if (mc->backchannel_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(mc->evbase, mc->backchannel_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ /* Events for local signals. */
+ mc->sigint_event = sudo_ev_alloc(SIGINT,
+ SUDO_EV_SIGINFO, mon_signal_cb, mc);
+ if (mc->sigint_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(mc->evbase, mc->sigint_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ mc->sigquit_event = sudo_ev_alloc(SIGQUIT,
+ SUDO_EV_SIGINFO, mon_signal_cb, mc);
+ if (mc->sigquit_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(mc->evbase, mc->sigquit_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ mc->sigtstp_event = sudo_ev_alloc(SIGTSTP,
+ SUDO_EV_SIGINFO, mon_signal_cb, mc);
+ if (mc->sigtstp_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(mc->evbase, mc->sigtstp_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ mc->sigterm_event = sudo_ev_alloc(SIGTERM,
+ SUDO_EV_SIGINFO, mon_signal_cb, mc);
+ if (mc->sigterm_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(mc->evbase, mc->sigterm_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ mc->sighup_event = sudo_ev_alloc(SIGHUP,
+ SUDO_EV_SIGINFO, mon_signal_cb, mc);
+ if (mc->sighup_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(mc->evbase, mc->sighup_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ mc->sigusr1_event = sudo_ev_alloc(SIGUSR1,
+ SUDO_EV_SIGINFO, mon_signal_cb, mc);
+ if (mc->sigusr1_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(mc->evbase, mc->sigusr1_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ mc->sigusr2_event = sudo_ev_alloc(SIGUSR2,
+ SUDO_EV_SIGINFO, mon_signal_cb, mc);
+ if (mc->sigusr2_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(mc->evbase, mc->sigusr2_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ mc->sigchld_event = sudo_ev_alloc(SIGCHLD,
+ SUDO_EV_SIGINFO, mon_signal_cb, mc);
+ if (mc->sigchld_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(mc->evbase, mc->sigchld_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ /* Clear the default event base. */
+ sudo_ev_base_setdef(NULL);
+
+ debug_return;
+}
+
+/*
+ * Monitor process that creates a new session with the controlling tty,
+ * resets signal handlers and forks a child to call exec_cmnd_pty().
+ * Waits for status changes from the command and relays them to the
+ * parent and relays signals from the parent to the command.
+ * Must be called with signals blocked and the old signal mask in oset.
+ * Returns an error if fork(2) fails, else calls _exit(2).
+ */
+int
+exec_monitor(struct command_details *details, sigset_t *oset,
+ bool foreground, int backchannel)
+{
+ struct monitor_closure mc = { 0 };
+ struct command_status cstat;
+ struct sigaction sa;
+ int errpipe[2];
+ debug_decl(exec_monitor, SUDO_DEBUG_EXEC);
+
+ /* The pty master is not used by the monitor. */
+ if (io_fds[SFD_MASTER] != -1)
+ close(io_fds[SFD_MASTER]);
+
+ /* Ignore any SIGTTIN or SIGTTOU we receive (shouldn't be possible). */
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = SIG_IGN;
+ if (sudo_sigaction(SIGTTIN, &sa, NULL) != 0)
+ sudo_warn(U_("unable to set handler for signal %d"), SIGTTIN);
+ if (sudo_sigaction(SIGTTOU, &sa, NULL) != 0)
+ sudo_warn(U_("unable to set handler for signal %d"), SIGTTOU);
+
+ /* If we are starting in the foreground, the pty was already initialized. */
+ if (foreground)
+ tty_initialized = true;
+
+ /*
+ * Start a new session with the parent as the session leader
+ * and the slave pty as the controlling terminal.
+ * This allows us to be notified when the command has been suspended.
+ */
+ if (setsid() == -1) {
+ sudo_warn("setsid");
+ goto bad;
+ }
+ if (pty_make_controlling() == -1) {
+ sudo_warn(U_("unable to set controlling tty"));
+ goto bad;
+ }
+
+ /*
+ * We use a pipe to get errno if execve(2) fails in the child.
+ */
+ if (pipe2(errpipe, O_CLOEXEC) != 0)
+ sudo_fatal(U_("unable to create pipe"));
+
+ /*
+ * Before forking, wait for the main sudo process to tell us to go.
+ * Avoids race conditions when the command exits quickly.
+ */
+ while (recv(backchannel, &cstat, sizeof(cstat), MSG_WAITALL) == -1) {
+ if (errno != EINTR && errno != EAGAIN)
+ sudo_fatal(U_("unable to receive message from parent"));
+ }
+
+ mc.cmnd_pid = sudo_debug_fork();
+ switch (mc.cmnd_pid) {
+ case -1:
+ sudo_warn(U_("unable to fork"));
+ goto bad;
+ case 0:
+ /* child */
+ sigprocmask(SIG_SETMASK, oset, NULL);
+ close(backchannel);
+ close(errpipe[0]);
+ if (io_fds[SFD_USERTTY] != -1)
+ close(io_fds[SFD_USERTTY]);
+ restore_signals();
+
+ /* setup tty and exec command */
+ exec_cmnd_pty(details, foreground, errpipe[1]);
+ if (write(errpipe[1], &errno, sizeof(int)) == -1)
+ sudo_warn(U_("unable to execute %s"), details->command);
+ _exit(1);
+ }
+ close(errpipe[1]);
+
+ /* No longer need execfd. */
+ if (details->execfd != -1) {
+ close(details->execfd);
+ details->execfd = -1;
+ }
+
+ /* Send the command's pid to main sudo process. */
+ cstat.type = CMD_PID;
+ cstat.val = mc.cmnd_pid;
+ send_status(backchannel, &cstat);
+
+ /*
+ * Create new event base and register read events for the
+ * signal pipe, error pipe, and backchannel.
+ */
+ fill_exec_closure_monitor(&mc, &cstat, errpipe[0], backchannel);
+
+ /* Restore signal mask now that signal handlers are setup. */
+ sigprocmask(SIG_SETMASK, oset, NULL);
+
+ /* If any of stdin/stdout/stderr are pipes, close them in parent. */
+ if (io_fds[SFD_STDIN] != io_fds[SFD_SLAVE])
+ close(io_fds[SFD_STDIN]);
+ if (io_fds[SFD_STDOUT] != io_fds[SFD_SLAVE])
+ close(io_fds[SFD_STDOUT]);
+ if (io_fds[SFD_STDERR] != io_fds[SFD_SLAVE])
+ close(io_fds[SFD_STDERR]);
+
+ /* Put command in its own process group. */
+ mc.cmnd_pgrp = mc.cmnd_pid;
+ setpgid(mc.cmnd_pid, mc.cmnd_pgrp);
+
+ /* Make the command the foreground process for the pty slave. */
+ if (foreground && !ISSET(details->flags, CD_EXEC_BG)) {
+ if (tcsetpgrp(io_fds[SFD_SLAVE], mc.cmnd_pgrp) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to set foreground pgrp to %d (command)",
+ __func__, (int)mc.cmnd_pgrp);
+ }
+ }
+
+ /*
+ * Wait for errno on pipe, signal on backchannel or for SIGCHLD.
+ * The event loop ends when the child is no longer running and
+ * the error pipe is closed.
+ */
+ cstat.type = CMD_INVALID;
+ cstat.val = 0;
+ (void) sudo_ev_dispatch(mc.evbase);
+ if (mc.cmnd_pid != -1) {
+ pid_t pid;
+
+ /* Command still running, did the parent die? */
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "Command still running after event loop exit, terminating");
+ terminate_command(mc.cmnd_pid, true);
+ do {
+ pid = waitpid(mc.cmnd_pid, NULL, 0);
+ } while (pid == -1 && errno == EINTR);
+ /* XXX - update cstat with wait status? */
+ }
+
+ /*
+ * Take the controlling tty. This prevents processes spawned by the
+ * command from receiving SIGHUP when the session leader (us) exits.
+ */
+ if (tcsetpgrp(io_fds[SFD_SLAVE], mc.mon_pgrp) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to set foreground pgrp to %d (monitor)",
+ __func__, (int)mc.mon_pgrp);
+ }
+
+ /* Send parent status. */
+ send_status(backchannel, &cstat);
+
+#ifdef HAVE_SELINUX
+ if (ISSET(details->flags, CD_RBAC_ENABLED)) {
+ if (selinux_restore_tty() != 0)
+ sudo_warnx(U_("unable to restore tty label"));
+ }
+#endif
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, 1);
+ _exit(1);
+
+bad:
+ debug_return_int(-1);
+}
diff --git a/src/exec_nopty.c b/src/exec_nopty.c
new file mode 100644
index 0000000..0df79f0
--- /dev/null
+++ b/src/exec_nopty.c
@@ -0,0 +1,573 @@
+/*
+ * Copyright (c) 2009-2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "sudo.h"
+#include "sudo_exec.h"
+#include "sudo_event.h"
+#include "sudo_plugin.h"
+#include "sudo_plugin_int.h"
+
+struct exec_closure_nopty {
+ pid_t cmnd_pid;
+ pid_t ppgrp;
+ struct command_status *cstat;
+ struct command_details *details;
+ struct sudo_event_base *evbase;
+ struct sudo_event *errpipe_event;
+ struct sudo_event *sigint_event;
+ struct sudo_event *sigquit_event;
+ struct sudo_event *sigtstp_event;
+ struct sudo_event *sigterm_event;
+ struct sudo_event *sighup_event;
+ struct sudo_event *sigalrm_event;
+ struct sudo_event *sigpipe_event;
+ struct sudo_event *sigusr1_event;
+ struct sudo_event *sigusr2_event;
+ struct sudo_event *sigchld_event;
+ struct sudo_event *sigcont_event;
+ struct sudo_event *siginfo_event;
+};
+
+static void handle_sigchld_nopty(struct exec_closure_nopty *ec);
+
+/* Note: this is basically the same as mon_errpipe_cb() in exec_monitor.c */
+static void
+errpipe_cb(int fd, int what, void *v)
+{
+ struct exec_closure_nopty *ec = v;
+ ssize_t nread;
+ int errval;
+ debug_decl(errpipe_cb, SUDO_DEBUG_EXEC);
+
+ /*
+ * Read errno from child or EOF when command is executed.
+ * Note that the error pipe is *blocking*.
+ */
+ nread = read(fd, &errval, sizeof(errval));
+ switch (nread) {
+ case -1:
+ if (errno != EAGAIN && errno != EINTR) {
+ if (ec->cstat->val == CMD_INVALID) {
+ /* XXX - need a way to distinguish non-exec error. */
+ ec->cstat->type = CMD_ERRNO;
+ ec->cstat->val = errno;
+ }
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: failed to read error pipe", __func__);
+ sudo_ev_loopbreak(ec->evbase);
+ }
+ break;
+ default:
+ if (nread == 0) {
+ /* The error pipe closes when the command is executed. */
+ sudo_debug_printf(SUDO_DEBUG_INFO, "EOF on error pipe");
+ } else {
+ /* Errno value when child is unable to execute command. */
+ sudo_debug_printf(SUDO_DEBUG_INFO, "errno from child: %s",
+ strerror(errval));
+ ec->cstat->type = CMD_ERRNO;
+ ec->cstat->val = errval;
+ }
+ sudo_ev_del(ec->evbase, ec->errpipe_event);
+ close(fd);
+ break;
+ }
+ debug_return;
+}
+
+/* Signal callback */
+static void
+signal_cb_nopty(int signo, int what, void *v)
+{
+ struct sudo_ev_siginfo_container *sc = v;
+ struct exec_closure_nopty *ec = sc->closure;
+ char signame[SIG2STR_MAX];
+ debug_decl(signal_cb_nopty, SUDO_DEBUG_EXEC)
+
+ if (ec->cmnd_pid == -1)
+ debug_return;
+
+ if (sig2str(signo, signame) == -1)
+ snprintf(signame, sizeof(signame), "%d", signo);
+ sudo_debug_printf(SUDO_DEBUG_DIAG,
+ "%s: evbase %p, command: %d, signo %s(%d), cstat %p",
+ __func__, ec->evbase, (int)ec->cmnd_pid, signame, signo, ec->cstat);
+
+ switch (signo) {
+ case SIGCHLD:
+ handle_sigchld_nopty(ec);
+ if (ec->cmnd_pid == -1) {
+ /* Command exited or was killed, exit event loop. */
+ sudo_ev_loopexit(ec->evbase);
+ }
+ debug_return;
+#ifdef SIGINFO
+ case SIGINFO:
+#endif
+ case SIGINT:
+ case SIGQUIT:
+ case SIGTSTP:
+ /*
+ * Only forward user-generated signals not sent by a process in
+ * the command's own process group. Signals sent by the kernel
+ * may include SIGTSTP when the user presses ^Z. Curses programs
+ * often trap ^Z and send SIGTSTP to their own pgrp, so we don't
+ * want to send an extra SIGTSTP.
+ */
+ if (!USER_SIGNALED(sc->siginfo))
+ debug_return;
+ if (sc->siginfo->si_pid != 0) {
+ pid_t si_pgrp = getpgid(sc->siginfo->si_pid);
+ if (si_pgrp != -1) {
+ if (si_pgrp == ec->ppgrp || si_pgrp == ec->cmnd_pid)
+ debug_return;
+ } else if (sc->siginfo->si_pid == ec->cmnd_pid) {
+ debug_return;
+ }
+ }
+ break;
+ default:
+ /*
+ * Do not forward signals sent by a process in the command's process
+ * group, as we don't want the command to indirectly kill itself.
+ * For example, this can happen with some versions of reboot that
+ * call kill(-1, SIGTERM) to kill all other processes.
+ */
+ if (USER_SIGNALED(sc->siginfo) && sc->siginfo->si_pid != 0) {
+ pid_t si_pgrp = getpgid(sc->siginfo->si_pid);
+ if (si_pgrp != -1) {
+ if (si_pgrp == ec->ppgrp || si_pgrp == ec->cmnd_pid)
+ debug_return;
+ } else if (sc->siginfo->si_pid == ec->cmnd_pid) {
+ debug_return;
+ }
+ }
+ break;
+ }
+
+ /* Send signal to command. */
+ if (signo == SIGALRM) {
+ terminate_command(ec->cmnd_pid, false);
+ } else if (kill(ec->cmnd_pid, signo) != 0) {
+ sudo_warn("kill(%d, SIG%s)", (int)ec->cmnd_pid, signame);
+ }
+
+ debug_return;
+}
+
+
+/*
+ * Fill in the exec closure and setup initial exec events.
+ * Allocates events for the signal pipe and error pipe.
+ */
+static void
+fill_exec_closure_nopty(struct exec_closure_nopty *ec,
+ struct command_status *cstat, struct command_details *details, int errfd)
+{
+ debug_decl(fill_exec_closure_nopty, SUDO_DEBUG_EXEC)
+
+ /* Fill in the non-event part of the closure. */
+ ec->ppgrp = getpgrp();
+ ec->cstat = cstat;
+ ec->details = details;
+
+ /* Setup event base and events. */
+ ec->evbase = sudo_ev_base_alloc();
+ if (ec->evbase == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+ /* Event for command status via errfd. */
+ ec->errpipe_event = sudo_ev_alloc(errfd,
+ SUDO_EV_READ|SUDO_EV_PERSIST, errpipe_cb, ec);
+ if (ec->errpipe_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->errpipe_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ sudo_debug_printf(SUDO_DEBUG_INFO, "error pipe fd %d\n", errfd);
+
+ /* Events for local signals. */
+ ec->sigint_event = sudo_ev_alloc(SIGINT,
+ SUDO_EV_SIGINFO, signal_cb_nopty, ec);
+ if (ec->sigint_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigint_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigquit_event = sudo_ev_alloc(SIGQUIT,
+ SUDO_EV_SIGINFO, signal_cb_nopty, ec);
+ if (ec->sigquit_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigquit_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigtstp_event = sudo_ev_alloc(SIGTSTP,
+ SUDO_EV_SIGINFO, signal_cb_nopty, ec);
+ if (ec->sigtstp_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigtstp_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigterm_event = sudo_ev_alloc(SIGTERM,
+ SUDO_EV_SIGINFO, signal_cb_nopty, ec);
+ if (ec->sigterm_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigterm_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sighup_event = sudo_ev_alloc(SIGHUP,
+ SUDO_EV_SIGINFO, signal_cb_nopty, ec);
+ if (ec->sighup_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sighup_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigalrm_event = sudo_ev_alloc(SIGALRM,
+ SUDO_EV_SIGINFO, signal_cb_nopty, ec);
+ if (ec->sigalrm_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigalrm_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigpipe_event = sudo_ev_alloc(SIGPIPE,
+ SUDO_EV_SIGINFO, signal_cb_nopty, ec);
+ if (ec->sigpipe_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigpipe_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigusr1_event = sudo_ev_alloc(SIGUSR1,
+ SUDO_EV_SIGINFO, signal_cb_nopty, ec);
+ if (ec->sigusr1_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigusr1_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigusr2_event = sudo_ev_alloc(SIGUSR2,
+ SUDO_EV_SIGINFO, signal_cb_nopty, ec);
+ if (ec->sigusr2_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigusr2_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigchld_event = sudo_ev_alloc(SIGCHLD,
+ SUDO_EV_SIGINFO, signal_cb_nopty, ec);
+ if (ec->sigchld_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigchld_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigcont_event = sudo_ev_alloc(SIGCONT,
+ SUDO_EV_SIGINFO, signal_cb_nopty, ec);
+ if (ec->sigcont_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigcont_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+#ifdef SIGINFO
+ ec->siginfo_event = sudo_ev_alloc(SIGINFO,
+ SUDO_EV_SIGINFO, signal_cb_nopty, ec);
+ if (ec->siginfo_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->siginfo_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+#endif
+
+ /* Set the default event base. */
+ sudo_ev_base_setdef(ec->evbase);
+
+ debug_return;
+}
+
+/*
+ * Free the dynamically-allocated contents of the exec closure.
+ */
+static void
+free_exec_closure_nopty(struct exec_closure_nopty *ec)
+{
+ debug_decl(free_exec_closure_nopty, SUDO_DEBUG_EXEC)
+
+ sudo_ev_base_free(ec->evbase);
+ sudo_ev_free(ec->errpipe_event);
+ sudo_ev_free(ec->sigint_event);
+ sudo_ev_free(ec->sigquit_event);
+ sudo_ev_free(ec->sigtstp_event);
+ sudo_ev_free(ec->sigterm_event);
+ sudo_ev_free(ec->sighup_event);
+ sudo_ev_free(ec->sigalrm_event);
+ sudo_ev_free(ec->sigpipe_event);
+ sudo_ev_free(ec->sigusr1_event);
+ sudo_ev_free(ec->sigusr2_event);
+ sudo_ev_free(ec->sigchld_event);
+ sudo_ev_free(ec->sigcont_event);
+ sudo_ev_free(ec->siginfo_event);
+
+ debug_return;
+}
+
+/*
+ * Execute a command and wait for it to finish.
+ */
+void
+exec_nopty(struct command_details *details, struct command_status *cstat)
+{
+ struct exec_closure_nopty ec = { 0 };
+ sigset_t set, oset;
+ int errpipe[2];
+ debug_decl(exec_nopty, SUDO_DEBUG_EXEC)
+
+ /*
+ * The policy plugin's session init must be run before we fork
+ * or certain pam modules won't be able to track their state.
+ */
+ if (policy_init_session(details) != true)
+ sudo_fatalx(U_("policy plugin failed session initialization"));
+
+ /*
+ * We use a pipe to get errno if execve(2) fails in the child.
+ */
+ if (pipe2(errpipe, O_CLOEXEC) != 0)
+ sudo_fatal(U_("unable to create pipe"));
+
+ /*
+ * Block signals until we have our handlers setup in the parent so
+ * we don't miss SIGCHLD if the command exits immediately.
+ */
+ sigfillset(&set);
+ sigprocmask(SIG_BLOCK, &set, &oset);
+
+ /* Check for early termination or suspend signals before we fork. */
+ if (sudo_terminated(cstat)) {
+ sigprocmask(SIG_SETMASK, &oset, NULL);
+ debug_return;
+ }
+
+ ec.cmnd_pid = sudo_debug_fork();
+ switch (ec.cmnd_pid) {
+ case -1:
+ sudo_fatal(U_("unable to fork"));
+ break;
+ case 0:
+ /* child */
+ sigprocmask(SIG_SETMASK, &oset, NULL);
+ close(errpipe[0]);
+ exec_cmnd(details, errpipe[1]);
+ while (write(errpipe[1], &errno, sizeof(int)) == -1) {
+ if (errno != EINTR)
+ break;
+ }
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, 1);
+ _exit(1);
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO, "executed %s, pid %d", details->command,
+ (int)ec.cmnd_pid);
+ close(errpipe[1]);
+
+ /* No longer need execfd. */
+ if (details->execfd != -1) {
+ close(details->execfd);
+ details->execfd = -1;
+ }
+
+ /* Set command timeout if specified. */
+ if (ISSET(details->flags, CD_SET_TIMEOUT))
+ alarm(details->timeout);
+
+ /*
+ * Fill in exec closure, allocate event base, signal events and
+ * the error pipe event.
+ */
+ fill_exec_closure_nopty(&ec, cstat, details, errpipe[0]);
+
+ /* Restore signal mask now that signal handlers are setup. */
+ sigprocmask(SIG_SETMASK, &oset, NULL);
+
+ /*
+ * Non-pty event loop.
+ * Wait for command to exit, handles signals and the error pipe.
+ */
+ if (sudo_ev_dispatch(ec.evbase) == -1)
+ sudo_warn(U_("error in event loop"));
+ if (sudo_ev_got_break(ec.evbase)) {
+ /* error from callback */
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "event loop exited prematurely");
+ /* kill command */
+ terminate_command(ec.cmnd_pid, true);
+ }
+
+#ifdef HAVE_SELINUX
+ if (ISSET(details->flags, CD_RBAC_ENABLED)) {
+ if (selinux_restore_tty() != 0)
+ sudo_warnx(U_("unable to restore tty label"));
+ }
+#endif
+
+ /* Free things up. */
+ free_exec_closure_nopty(&ec);
+ debug_return;
+}
+
+/*
+ * Wait for command status after receiving SIGCHLD.
+ * If the command exits, fill in cstat and stop the event loop.
+ * If the command stops, save the tty pgrp, suspend sudo, then restore
+ * the tty pgrp when sudo resumes.
+ */
+static void
+handle_sigchld_nopty(struct exec_closure_nopty *ec)
+{
+ pid_t pid;
+ int status;
+ char signame[SIG2STR_MAX];
+ debug_decl(handle_sigchld_nopty, SUDO_DEBUG_EXEC)
+
+ /* Read command status. */
+ do {
+ pid = waitpid(ec->cmnd_pid, &status, WUNTRACED|WNOHANG);
+ } while (pid == -1 && errno == EINTR);
+ switch (pid) {
+ case 0:
+ /* waitpid() will return 0 for SIGCONT, which we don't care about */
+ debug_return;
+ case -1:
+ sudo_warn(U_("%s: %s"), __func__, "waitpid");
+ debug_return;
+ }
+
+ if (WIFSTOPPED(status)) {
+ /*
+ * Save the controlling terminal's process group so we can restore it
+ * after we resume, if needed. Most well-behaved shells change the
+ * pgrp back to its original value before suspending so we must
+ * not try to restore in that case, lest we race with the command upon
+ * resume, potentially stopping sudo with SIGTTOU while the command
+ * continues to run.
+ */
+ struct sigaction sa, osa;
+ pid_t saved_pgrp = -1;
+ int fd, signo = WSTOPSIG(status);
+
+ if (sig2str(signo, signame) == -1)
+ snprintf(signame, sizeof(signame), "%d", signo);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) stopped, SIG%s",
+ __func__, (int)ec->cmnd_pid, signame);
+
+ fd = open(_PATH_TTY, O_RDWR);
+ if (fd != -1) {
+ saved_pgrp = tcgetpgrp(fd);
+ if (saved_pgrp == -1) {
+ close(fd);
+ fd = -1;
+ }
+ }
+ if (saved_pgrp != -1) {
+ /*
+ * Command was stopped trying to access the controlling terminal.
+ * If the command has a different pgrp and we own the controlling
+ * terminal, give it to the command's pgrp and let it continue.
+ */
+ if (signo == SIGTTOU || signo == SIGTTIN) {
+ if (saved_pgrp == ec->ppgrp) {
+ pid_t cmnd_pgrp = getpgid(ec->cmnd_pid);
+ if (cmnd_pgrp != ec->ppgrp) {
+ if (tcsetpgrp_nobg(fd, cmnd_pgrp) == 0) {
+ if (killpg(cmnd_pgrp, SIGCONT) != 0) {
+ sudo_warn("kill(%d, SIGCONT)",
+ (int)cmnd_pgrp);
+ }
+ close(fd);
+ goto done;
+ }
+ }
+ }
+ }
+ }
+ if (signo == SIGTSTP) {
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = SIG_DFL;
+ if (sudo_sigaction(SIGTSTP, &sa, &osa) != 0) {
+ sudo_warn(U_("unable to set handler for signal %d"),
+ SIGTSTP);
+ }
+ }
+ if (kill(getpid(), signo) != 0)
+ sudo_warn("kill(%d, SIG%s)", (int)getpid(), signame);
+ if (signo == SIGTSTP) {
+ if (sudo_sigaction(SIGTSTP, &osa, NULL) != 0) {
+ sudo_warn(U_("unable to restore handler for signal %d"),
+ SIGTSTP);
+ }
+ }
+ if (saved_pgrp != -1) {
+ /*
+ * On resume, restore foreground process group, if different.
+ * Otherwise, we cannot resume some shells (pdksh).
+ *
+ * It is possible that we are no longer the foreground process so
+ * use tcsetpgrp_nobg() to prevent sudo from receiving SIGTTOU.
+ */
+ if (saved_pgrp != ec->ppgrp)
+ tcsetpgrp_nobg(fd, saved_pgrp);
+ close(fd);
+ }
+ } else {
+ /* Command has exited or been killed, we are done. */
+ if (WIFSIGNALED(status)) {
+ if (sig2str(WTERMSIG(status), signame) == -1)
+ snprintf(signame, sizeof(signame), "%d", WTERMSIG(status));
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) killed, SIG%s",
+ __func__, (int)ec->cmnd_pid, signame);
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) exited: %d",
+ __func__, (int)ec->cmnd_pid, WEXITSTATUS(status));
+ }
+ /* Don't overwrite execve() failure with command exit status. */
+ if (ec->cstat->type == CMD_INVALID) {
+ ec->cstat->type = CMD_WSTATUS;
+ ec->cstat->val = status;
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_WARN,
+ "%s: not overwriting command status %d,%d with %d,%d",
+ __func__, ec->cstat->type, ec->cstat->val, CMD_WSTATUS, status);
+ }
+ ec->cmnd_pid = -1;
+ }
+done:
+ debug_return;
+}
diff --git a/src/exec_pty.c b/src/exec_pty.c
new file mode 100644
index 0000000..c1ccd4b
--- /dev/null
+++ b/src/exec_pty.c
@@ -0,0 +1,1813 @@
+/*
+ * Copyright (c) 2009-2019 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <termios.h> /* for struct winsize on HP-UX */
+
+#include "sudo.h"
+#include "sudo_event.h"
+#include "sudo_exec.h"
+#include "sudo_plugin.h"
+#include "sudo_plugin_int.h"
+
+/* Evaluates to true if the event has /dev/tty as its fd. */
+#define USERTTY_EVENT(_ev) (sudo_ev_get_fd((_ev)) == io_fds[SFD_USERTTY])
+
+#define TERM_COOKED 0
+#define TERM_RAW 1
+
+/* Tail queue of messages to send to the monitor. */
+struct monitor_message {
+ TAILQ_ENTRY(monitor_message) entries;
+ struct command_status cstat;
+};
+TAILQ_HEAD(monitor_message_list, monitor_message);
+
+struct exec_closure_pty {
+ pid_t monitor_pid;
+ pid_t cmnd_pid;
+ pid_t ppgrp;
+ short rows;
+ short cols;
+ struct command_status *cstat;
+ struct command_details *details;
+ struct sudo_event_base *evbase;
+ struct sudo_event *backchannel_event;
+ struct sudo_event *fwdchannel_event;
+ struct sudo_event *sigint_event;
+ struct sudo_event *sigquit_event;
+ struct sudo_event *sigtstp_event;
+ struct sudo_event *sigterm_event;
+ struct sudo_event *sighup_event;
+ struct sudo_event *sigalrm_event;
+ struct sudo_event *sigusr1_event;
+ struct sudo_event *sigusr2_event;
+ struct sudo_event *sigchld_event;
+ struct sudo_event *sigwinch_event;
+ struct monitor_message_list monitor_messages;
+};
+
+/*
+ * I/O buffer with associated read/write events and a logging action.
+ * Used to, e.g. pass data from the pty to the user's terminal
+ * and any I/O logging plugins.
+ */
+struct io_buffer;
+typedef bool (*sudo_io_action_t)(const char *, unsigned int, struct io_buffer *);
+struct io_buffer {
+ SLIST_ENTRY(io_buffer) entries;
+ struct exec_closure_pty *ec;
+ struct sudo_event *revent;
+ struct sudo_event *wevent;
+ sudo_io_action_t action;
+ int len; /* buffer length (how much produced) */
+ int off; /* write position (how much already consumed) */
+ char buf[64 * 1024];
+};
+SLIST_HEAD(io_buffer_list, io_buffer);
+
+static char slavename[PATH_MAX];
+int io_fds[6] = { -1, -1, -1, -1, -1, -1};
+static bool foreground, pipeline;
+static int ttymode = TERM_COOKED;
+static sigset_t ttyblock;
+static struct io_buffer_list iobufs;
+static const char *utmp_user;
+
+static void del_io_events(bool nonblocking);
+static void sync_ttysize(struct exec_closure_pty *ec);
+static int safe_close(int fd);
+static void ev_free_by_fd(struct sudo_event_base *evbase, int fd);
+static void check_foreground(struct exec_closure_pty *ec);
+static void add_io_events(struct sudo_event_base *evbase);
+static void schedule_signal(struct exec_closure_pty *ec, int signo);
+
+/*
+ * Cleanup hook for sudo_fatal()/sudo_fatalx()
+ */
+void
+pty_cleanup(void)
+{
+ debug_decl(cleanup, SUDO_DEBUG_EXEC);
+
+ if (io_fds[SFD_USERTTY] != -1)
+ sudo_term_restore(io_fds[SFD_USERTTY], false);
+ if (utmp_user != NULL)
+ utmp_logout(slavename, 0);
+
+ debug_return;
+}
+
+/*
+ * Allocate a pty if /dev/tty is a tty.
+ * Fills in io_fds[SFD_USERTTY], io_fds[SFD_MASTER], io_fds[SFD_SLAVE]
+ * and slavename globals.
+ */
+static bool
+pty_setup(struct command_details *details, const char *tty)
+{
+ debug_decl(pty_setup, SUDO_DEBUG_EXEC);
+
+ io_fds[SFD_USERTTY] = open(_PATH_TTY, O_RDWR);
+ if (io_fds[SFD_USERTTY] == -1) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: no %s, not allocating a pty",
+ __func__, _PATH_TTY);
+ debug_return_bool(false);
+ }
+
+ if (!get_pty(&io_fds[SFD_MASTER], &io_fds[SFD_SLAVE],
+ slavename, sizeof(slavename), details->euid))
+ sudo_fatal(U_("unable to allocate pty"));
+
+ /* Add entry to utmp/utmpx? */
+ if (ISSET(details->flags, CD_SET_UTMP)) {
+ utmp_user =
+ details->utmp_user ? details->utmp_user : user_details.username;
+ utmp_login(tty, slavename, io_fds[SFD_SLAVE], utmp_user);
+ }
+
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: %s fd %d, pty master fd %d, pty slave fd %d",
+ __func__, _PATH_TTY, io_fds[SFD_USERTTY], io_fds[SFD_MASTER],
+ io_fds[SFD_SLAVE]);
+
+ debug_return_bool(true);
+}
+
+/*
+ * Make the tty slave the controlling tty.
+ * This is only used by the monitor but slavename[] is static.
+ */
+int
+pty_make_controlling(void)
+{
+ if (io_fds[SFD_SLAVE] != -1) {
+#ifdef TIOCSCTTY
+ if (ioctl(io_fds[SFD_SLAVE], TIOCSCTTY, NULL) != 0)
+ return -1;
+#else
+ /* Set controlling tty by reopening slave. */
+ int fd = open(slavename, O_RDWR);
+ if (fd == -1)
+ return -1;
+ close(fd);
+#endif
+ }
+ return 0;
+}
+
+/* Call I/O plugin tty input log method. */
+static bool
+log_ttyin(const char *buf, unsigned int n, struct io_buffer *iob)
+{
+ struct plugin_container *plugin;
+ sigset_t omask;
+ bool ret = true;
+ debug_decl(log_ttyin, SUDO_DEBUG_EXEC);
+
+ sigprocmask(SIG_BLOCK, &ttyblock, &omask);
+ TAILQ_FOREACH(plugin, &io_plugins, entries) {
+ if (plugin->u.io->log_ttyin) {
+ int rc;
+
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ rc = plugin->u.io->log_ttyin(buf, n);
+ if (rc <= 0) {
+ if (rc < 0) {
+ /* Error: disable plugin's I/O function. */
+ plugin->u.io->log_ttyin = NULL;
+ }
+ ret = false;
+ break;
+ }
+ }
+ }
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+
+ debug_return_bool(ret);
+}
+
+/* Call I/O plugin stdin log method. */
+static bool
+log_stdin(const char *buf, unsigned int n, struct io_buffer *iob)
+{
+ struct plugin_container *plugin;
+ sigset_t omask;
+ bool ret = true;
+ debug_decl(log_stdin, SUDO_DEBUG_EXEC);
+
+ sigprocmask(SIG_BLOCK, &ttyblock, &omask);
+ TAILQ_FOREACH(plugin, &io_plugins, entries) {
+ if (plugin->u.io->log_stdin) {
+ int rc;
+
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ rc = plugin->u.io->log_stdin(buf, n);
+ if (rc <= 0) {
+ if (rc < 0) {
+ /* Error: disable plugin's I/O function. */
+ plugin->u.io->log_stdin = NULL;
+ }
+ ret = false;
+ break;
+ }
+ }
+ }
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+
+ debug_return_bool(ret);
+}
+
+/* Call I/O plugin tty output log method. */
+static bool
+log_ttyout(const char *buf, unsigned int n, struct io_buffer *iob)
+{
+ struct plugin_container *plugin;
+ sigset_t omask;
+ bool ret = true;
+ debug_decl(log_ttyout, SUDO_DEBUG_EXEC);
+
+ sigprocmask(SIG_BLOCK, &ttyblock, &omask);
+ TAILQ_FOREACH(plugin, &io_plugins, entries) {
+ if (plugin->u.io->log_ttyout) {
+ int rc;
+
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ rc = plugin->u.io->log_ttyout(buf, n);
+ if (rc <= 0) {
+ if (rc < 0) {
+ /* Error: disable plugin's I/O function. */
+ plugin->u.io->log_ttyout = NULL;
+ }
+ ret = false;
+ break;
+ }
+ }
+ }
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ if (!ret) {
+ /*
+ * I/O plugin rejected the output, delete the write event
+ * (user's tty) so we do not display the rejected output.
+ */
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: deleting and freeing devtty wevent %p", __func__, iob->wevent);
+ sudo_ev_free(iob->wevent);
+ iob->wevent = NULL;
+ iob->off = iob->len = 0;
+ }
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+
+ debug_return_bool(ret);
+}
+
+/* Call I/O plugin stdout log method. */
+static bool
+log_stdout(const char *buf, unsigned int n, struct io_buffer *iob)
+{
+ struct plugin_container *plugin;
+ sigset_t omask;
+ bool ret = true;
+ debug_decl(log_stdout, SUDO_DEBUG_EXEC);
+
+ sigprocmask(SIG_BLOCK, &ttyblock, &omask);
+ TAILQ_FOREACH(plugin, &io_plugins, entries) {
+ if (plugin->u.io->log_stdout) {
+ int rc;
+
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ rc = plugin->u.io->log_stdout(buf, n);
+ if (rc <= 0) {
+ if (rc < 0) {
+ /* Error: disable plugin's I/O function. */
+ plugin->u.io->log_stdout = NULL;
+ }
+ ret = false;
+ break;
+ }
+ }
+ }
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ if (!ret) {
+ /*
+ * I/O plugin rejected the output, delete the write event
+ * (user's stdout) so we do not display the rejected output.
+ */
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: deleting and freeing stdout wevent %p", __func__, iob->wevent);
+ sudo_ev_free(iob->wevent);
+ iob->wevent = NULL;
+ iob->off = iob->len = 0;
+ }
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+
+ debug_return_bool(ret);
+}
+
+/* Call I/O plugin stderr log method. */
+static bool
+log_stderr(const char *buf, unsigned int n, struct io_buffer *iob)
+{
+ struct plugin_container *plugin;
+ sigset_t omask;
+ bool ret = true;
+ debug_decl(log_stderr, SUDO_DEBUG_EXEC);
+
+ sigprocmask(SIG_BLOCK, &ttyblock, &omask);
+ TAILQ_FOREACH(plugin, &io_plugins, entries) {
+ if (plugin->u.io->log_stderr) {
+ int rc;
+
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ rc = plugin->u.io->log_stderr(buf, n);
+ if (rc <= 0) {
+ if (rc < 0) {
+ /* Error: disable plugin's I/O function. */
+ plugin->u.io->log_stderr = NULL;
+ }
+ ret = false;
+ break;
+ }
+ }
+ }
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ if (!ret) {
+ /*
+ * I/O plugin rejected the output, delete the write event
+ * (user's stderr) so we do not display the rejected output.
+ */
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: deleting and freeing stderr wevent %p", __func__, iob->wevent);
+ sudo_ev_free(iob->wevent);
+ iob->wevent = NULL;
+ iob->off = iob->len = 0;
+ }
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+
+ debug_return_bool(ret);
+}
+
+/* Call I/O plugin suspend log method. */
+static void
+log_suspend(int signo)
+{
+ struct plugin_container *plugin;
+ sigset_t omask;
+ debug_decl(log_suspend, SUDO_DEBUG_EXEC);
+
+ sigprocmask(SIG_BLOCK, &ttyblock, &omask);
+ TAILQ_FOREACH(plugin, &io_plugins, entries) {
+ if (plugin->u.io->version < SUDO_API_MKVERSION(1, 13))
+ continue;
+ if (plugin->u.io->log_suspend) {
+ int rc;
+
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ rc = plugin->u.io->log_suspend(signo);
+ if (rc <= 0) {
+ if (rc < 0) {
+ /* Error: disable plugin's I/O function. */
+ plugin->u.io->log_suspend = NULL;
+ }
+ break;
+ }
+ }
+ }
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+
+ debug_return;
+}
+
+/* Call I/O plugin window change log method. */
+static void
+log_winchange(unsigned int rows, unsigned int cols)
+{
+ struct plugin_container *plugin;
+ sigset_t omask;
+ debug_decl(log_winchange, SUDO_DEBUG_EXEC);
+
+ sigprocmask(SIG_BLOCK, &ttyblock, &omask);
+ TAILQ_FOREACH(plugin, &io_plugins, entries) {
+ if (plugin->u.io->version < SUDO_API_MKVERSION(1, 12))
+ continue;
+ if (plugin->u.io->change_winsize) {
+ int rc;
+
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ rc = plugin->u.io->change_winsize(rows, cols);
+ if (rc <= 0) {
+ if (rc < 0) {
+ /* Error: disable plugin's I/O function. */
+ plugin->u.io->change_winsize = NULL;
+ }
+ break;
+ }
+ }
+ }
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+
+ debug_return;
+}
+
+/*
+ * Check whether we are running in the foregroup.
+ * Updates the foreground global and does lazy init of the
+ * the pty slave as needed.
+ */
+static void
+check_foreground(struct exec_closure_pty *ec)
+{
+ debug_decl(check_foreground, SUDO_DEBUG_EXEC);
+
+ if (io_fds[SFD_USERTTY] != -1) {
+ foreground = tcgetpgrp(io_fds[SFD_USERTTY]) == ec->ppgrp;
+
+ /* Also check for window size changes. */
+ sync_ttysize(ec);
+ }
+
+ debug_return;
+}
+
+/*
+ * Suspend sudo if the underlying command is suspended.
+ * Returns SIGCONT_FG if the command should be resumed in the
+ * foreground or SIGCONT_BG if it is a background process.
+ */
+static int
+suspend_sudo(struct exec_closure_pty *ec, int signo)
+{
+ char signame[SIG2STR_MAX];
+ struct sigaction sa, osa;
+ int ret = 0;
+ debug_decl(suspend_sudo, SUDO_DEBUG_EXEC);
+
+ switch (signo) {
+ case SIGTTOU:
+ case SIGTTIN:
+ /*
+ * If sudo is already the foreground process, just resume the command
+ * in the foreground. If not, we'll suspend sudo and resume later.
+ */
+ if (!foreground)
+ check_foreground(ec);
+ if (foreground) {
+ if (ttymode != TERM_RAW) {
+ if (sudo_term_raw(io_fds[SFD_USERTTY], 0))
+ ttymode = TERM_RAW;
+ }
+ ret = SIGCONT_FG; /* resume command in foreground */
+ break;
+ }
+ /* FALLTHROUGH */
+ case SIGSTOP:
+ case SIGTSTP:
+ /* Flush any remaining output and deschedule I/O events. */
+ del_io_events(true);
+
+ /* Restore original tty mode before suspending. */
+ if (ttymode != TERM_COOKED)
+ sudo_term_restore(io_fds[SFD_USERTTY], false);
+
+ /* Log the suspend event. */
+ log_suspend(signo);
+
+ if (sig2str(signo, signame) == -1)
+ snprintf(signame, sizeof(signame), "%d", signo);
+
+ /* Suspend self and continue command when we resume. */
+ if (signo != SIGSTOP) {
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = SIG_DFL;
+ if (sudo_sigaction(signo, &sa, &osa) != 0)
+ sudo_warn(U_("unable to set handler for signal %d"), signo);
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO, "kill parent SIG%s", signame);
+ if (killpg(ec->ppgrp, signo) != 0)
+ sudo_warn("killpg(%d, SIG%s)", (int)ec->ppgrp, signame);
+
+ /* Log the resume event. */
+ log_suspend(SIGCONT);
+
+ /* Check foreground/background status on resume. */
+ check_foreground(ec);
+
+ /*
+ * We always resume the command in the foreground if sudo itself
+ * is the foreground process. This helps work around poorly behaved
+ * programs that catch SIGTTOU/SIGTTIN but suspend themselves with
+ * SIGSTOP. At worst, sudo will go into the background but upon
+ * resume the command will be runnable. Otherwise, we can get into
+ * a situation where the command will immediately suspend itself.
+ */
+ sudo_debug_printf(SUDO_DEBUG_INFO, "parent is in %s, ttymode %d -> %d",
+ foreground ? "foreground" : "background", ttymode,
+ foreground ? TERM_RAW : TERM_COOKED);
+
+ if (foreground) {
+ /* Foreground process, set tty to raw mode. */
+ if (sudo_term_raw(io_fds[SFD_USERTTY], 0))
+ ttymode = TERM_RAW;
+ } else {
+ /* Background process, no access to tty. */
+ ttymode = TERM_COOKED;
+ }
+
+ if (signo != SIGSTOP) {
+ if (sudo_sigaction(signo, &osa, NULL) != 0)
+ sudo_warn(U_("unable to restore handler for signal %d"), signo);
+ }
+
+ ret = ttymode == TERM_RAW ? SIGCONT_FG : SIGCONT_BG;
+ break;
+ }
+
+ debug_return_int(ret);
+}
+
+/*
+ * SIGTTIN signal handler for read_callback that just sets a flag.
+ */
+static volatile sig_atomic_t got_sigttin;
+
+static void
+sigttin(int signo)
+{
+ got_sigttin = 1;
+}
+
+/*
+ * Read an iobuf that is ready.
+ */
+static void
+read_callback(int fd, int what, void *v)
+{
+ struct io_buffer *iob = v;
+ struct sudo_event_base *evbase = sudo_ev_get_base(iob->revent);
+ struct sigaction sa, osa;
+ int saved_errno;
+ ssize_t n;
+ debug_decl(read_callback, SUDO_DEBUG_EXEC);
+
+ /*
+ * We ignore SIGTTIN by default but we need to handle it when reading
+ * from the terminal. A signal event won't work here because the
+ * read() would be restarted, preventing the callback from running.
+ */
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = sigttin;
+ got_sigttin = 0;
+ sigaction(SIGTTIN, &sa, &osa);
+ n = read(fd, iob->buf + iob->len, sizeof(iob->buf) - iob->len);
+ saved_errno = errno;
+ sigaction(SIGTTIN, &osa, NULL);
+ errno = saved_errno;
+
+ switch (n) {
+ case -1:
+ if (got_sigttin) {
+ /* Schedule SIGTTIN to be forwared to the command. */
+ schedule_signal(iob->ec, SIGTTIN);
+ }
+ if (errno == EAGAIN || errno == EINTR)
+ break;
+ /* treat read error as fatal and close the fd */
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "error reading fd %d: %s", fd, strerror(errno));
+ /* FALLTHROUGH */
+ case 0:
+ /* got EOF or pty has gone away */
+ if (n == 0) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "read EOF from fd %d", fd);
+ }
+ safe_close(fd);
+ ev_free_by_fd(evbase, fd);
+ /* If writer already consumed the buffer, close it too. */
+ if (iob->wevent != NULL && iob->off == iob->len) {
+ safe_close(sudo_ev_get_fd(iob->wevent));
+ ev_free_by_fd(evbase, sudo_ev_get_fd(iob->wevent));
+ iob->off = iob->len = 0;
+ }
+ break;
+ default:
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "read %zd bytes from fd %d", n, fd);
+ if (!iob->action(iob->buf + iob->len, n, iob)) {
+ terminate_command(iob->ec->cmnd_pid, true);
+ iob->ec->cmnd_pid = -1;
+ }
+ iob->len += n;
+ /* Enable writer now that there is data in the buffer. */
+ if (iob->wevent != NULL) {
+ if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ }
+ /* Re-enable reader if buffer is not full. */
+ if (iob->len != sizeof(iob->buf)) {
+ if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ }
+ break;
+ }
+}
+
+/*
+ * SIGTTOU signal handler for write_callback that just sets a flag.
+ */
+static volatile sig_atomic_t got_sigttou;
+
+static void
+sigttou(int signo)
+{
+ got_sigttou = 1;
+}
+
+/*
+ * Write an iobuf that is ready.
+ */
+static void
+write_callback(int fd, int what, void *v)
+{
+ struct io_buffer *iob = v;
+ struct sudo_event_base *evbase = sudo_ev_get_base(iob->wevent);
+ struct sigaction sa, osa;
+ int saved_errno;
+ ssize_t n;
+ debug_decl(write_callback, SUDO_DEBUG_EXEC);
+
+ /*
+ * We ignore SIGTTOU by default but we need to handle it when writing
+ * to the terminal. A signal event won't work here because the
+ * write() would be restarted, preventing the callback from running.
+ */
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = sigttou;
+ got_sigttou = 0;
+ sigaction(SIGTTOU, &sa, &osa);
+ n = write(fd, iob->buf + iob->off, iob->len - iob->off);
+ saved_errno = errno;
+ sigaction(SIGTTOU, &osa, NULL);
+ errno = saved_errno;
+
+ if (n == -1) {
+ switch (errno) {
+ case EPIPE:
+ case ENXIO:
+ case EIO:
+ case EBADF:
+ /* other end of pipe closed or pty revoked */
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "unable to write %d bytes to fd %d",
+ iob->len - iob->off, fd);
+ /* Close reader if there is one. */
+ if (iob->revent != NULL) {
+ safe_close(sudo_ev_get_fd(iob->revent));
+ ev_free_by_fd(evbase, sudo_ev_get_fd(iob->revent));
+ }
+ safe_close(fd);
+ ev_free_by_fd(evbase, fd);
+ break;
+ case EINTR:
+ if (got_sigttou) {
+ /* Schedule SIGTTOU to be forwared to the command. */
+ schedule_signal(iob->ec, SIGTTOU);
+ }
+ /* FALLTHROUGH */
+ case EAGAIN:
+ /* not an error */
+ break;
+ default:
+ /* XXX - need a way to distinguish non-exec error. */
+ iob->ec->cstat->type = CMD_ERRNO;
+ iob->ec->cstat->val = errno;
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "error writing fd %d: %s", fd, strerror(errno));
+ sudo_ev_loopbreak(evbase);
+ break;
+ }
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "wrote %zd bytes to fd %d", n, fd);
+ iob->off += n;
+ /* Reset buffer if fully consumed. */
+ if (iob->off == iob->len) {
+ iob->off = iob->len = 0;
+ /* Forward the EOF from reader to writer. */
+ if (iob->revent == NULL) {
+ safe_close(fd);
+ ev_free_by_fd(evbase, fd);
+ }
+ }
+ /* Re-enable writer if buffer is not empty. */
+ if (iob->len > iob->off) {
+ if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ }
+ /* Enable reader if buffer is not full. */
+ if (iob->revent != NULL &&
+ (ttymode == TERM_RAW || !USERTTY_EVENT(iob->revent))) {
+ if (iob->len != sizeof(iob->buf)) {
+ if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ }
+ }
+ }
+}
+
+static void
+io_buf_new(int rfd, int wfd,
+ bool (*action)(const char *, unsigned int, struct io_buffer *),
+ struct exec_closure_pty *ec, struct io_buffer_list *head)
+{
+ int n;
+ struct io_buffer *iob;
+ debug_decl(io_buf_new, SUDO_DEBUG_EXEC);
+
+ /* Set non-blocking mode. */
+ n = fcntl(rfd, F_GETFL, 0);
+ if (n != -1 && !ISSET(n, O_NONBLOCK))
+ (void) fcntl(rfd, F_SETFL, n | O_NONBLOCK);
+ n = fcntl(wfd, F_GETFL, 0);
+ if (n != -1 && !ISSET(n, O_NONBLOCK))
+ (void) fcntl(wfd, F_SETFL, n | O_NONBLOCK);
+
+ /* Allocate and add to head of list. */
+ if ((iob = malloc(sizeof(*iob))) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ iob->ec = ec;
+ iob->revent = sudo_ev_alloc(rfd, SUDO_EV_READ, read_callback, iob);
+ iob->wevent = sudo_ev_alloc(wfd, SUDO_EV_WRITE, write_callback, iob);
+ iob->len = 0;
+ iob->off = 0;
+ iob->action = action;
+ iob->buf[0] = '\0';
+ if (iob->revent == NULL || iob->wevent == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ SLIST_INSERT_HEAD(head, iob, entries);
+
+ debug_return;
+}
+
+/*
+ * We already closed the slave pty so reads from the master will not block.
+ */
+static void
+pty_finish(struct command_status *cstat)
+{
+ struct io_buffer *iob;
+ int n;
+ debug_decl(pty_finish, SUDO_DEBUG_EXEC);
+
+ /* Flush any remaining output (the plugin already got it). */
+ if (io_fds[SFD_USERTTY] != -1) {
+ n = fcntl(io_fds[SFD_USERTTY], F_GETFL, 0);
+ if (n != -1 && ISSET(n, O_NONBLOCK)) {
+ CLR(n, O_NONBLOCK);
+ (void) fcntl(io_fds[SFD_USERTTY], F_SETFL, n);
+ }
+ }
+ del_io_events(false);
+
+ /* Free I/O buffers. */
+ while ((iob = SLIST_FIRST(&iobufs)) != NULL) {
+ SLIST_REMOVE_HEAD(&iobufs, entries);
+ if (iob->revent != NULL)
+ sudo_ev_free(iob->revent);
+ if (iob->wevent != NULL)
+ sudo_ev_free(iob->wevent);
+ free(iob);
+ }
+
+ /* Restore terminal settings. */
+ if (io_fds[SFD_USERTTY] != -1)
+ sudo_term_restore(io_fds[SFD_USERTTY], false);
+
+ /* Update utmp */
+ if (utmp_user != NULL)
+ utmp_logout(slavename, cstat->type == CMD_WSTATUS ? cstat->val : 0);
+
+ debug_return;
+}
+
+/*
+ * Send command status to the monitor (signal or window size change).
+ */
+static void
+send_command_status(struct exec_closure_pty *ec, int type, int val)
+{
+ struct monitor_message *msg;
+ debug_decl(send_command, SUDO_DEBUG_EXEC)
+
+ if ((msg = calloc(1, sizeof(*msg))) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ msg->cstat.type = type;
+ msg->cstat.val = val;
+ TAILQ_INSERT_TAIL(&ec->monitor_messages, msg, entries);
+
+ if (sudo_ev_add(ec->evbase, ec->fwdchannel_event, NULL, true) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ /* Restart event loop to send the command immediately. */
+ sudo_ev_loopcontinue(ec->evbase);
+
+ debug_return;
+}
+
+/*
+ * Schedule a signal to be forwarded.
+ */
+static void
+schedule_signal(struct exec_closure_pty *ec, int signo)
+{
+ char signame[SIG2STR_MAX];
+ debug_decl(schedule_signal, SUDO_DEBUG_EXEC)
+
+ if (signo == SIGCONT_FG)
+ strlcpy(signame, "CONT_FG", sizeof(signame));
+ else if (signo == SIGCONT_BG)
+ strlcpy(signame, "CONT_BG", sizeof(signame));
+ else if (sig2str(signo, signame) == -1)
+ snprintf(signame, sizeof(signame), "%d", signo);
+ sudo_debug_printf(SUDO_DEBUG_DIAG, "scheduled SIG%s for command", signame);
+
+ send_command_status(ec, CMD_SIGNO, signo);
+
+ debug_return;
+}
+
+static void
+backchannel_cb(int fd, int what, void *v)
+{
+ struct exec_closure_pty *ec = v;
+ struct command_status cstat;
+ ssize_t nread;
+ debug_decl(backchannel_cb, SUDO_DEBUG_EXEC)
+
+ /*
+ * Read command status from the monitor.
+ * Note that the backchannel is a *blocking* socket.
+ */
+ nread = recv(fd, &cstat, sizeof(cstat), MSG_WAITALL);
+ switch (nread) {
+ case -1:
+ switch (errno) {
+ case EINTR:
+ case EAGAIN:
+ /* Nothing ready. */
+ break;
+ default:
+ if (ec->cstat->val == CMD_INVALID) {
+ ec->cstat->type = CMD_ERRNO;
+ ec->cstat->val = errno;
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "%s: failed to read command status: %s",
+ __func__, strerror(errno));
+ sudo_ev_loopbreak(ec->evbase);
+ }
+ break;
+ }
+ break;
+ case 0:
+ /* EOF, monitor exited or was killed. */
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "EOF on backchannel, monitor dead?");
+ if (ec->cstat->type == CMD_INVALID) {
+ /* XXX - need new CMD_ type for monitor errors. */
+ ec->cstat->type = CMD_ERRNO;
+ ec->cstat->val = ECONNRESET;
+ }
+ sudo_ev_loopexit(ec->evbase);
+ break;
+ case sizeof(cstat):
+ /* Check command status. */
+ switch (cstat.type) {
+ case CMD_PID:
+ ec->cmnd_pid = cstat.val;
+ sudo_debug_printf(SUDO_DEBUG_INFO, "executed %s, pid %d",
+ ec->details->command, (int)ec->cmnd_pid);
+ break;
+ case CMD_WSTATUS:
+ if (WIFSTOPPED(cstat.val)) {
+ int signo;
+
+ /* Suspend parent and tell monitor how to resume on return. */
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "command stopped, suspending parent");
+ signo = suspend_sudo(ec, WSTOPSIG(cstat.val));
+ schedule_signal(ec, signo);
+ /* Re-enable I/O events */
+ add_io_events(ec->evbase);
+ } else {
+ /* Command exited or was killed, either way we are done. */
+ sudo_debug_printf(SUDO_DEBUG_INFO, "command exited or was killed");
+ sudo_ev_loopexit(ec->evbase);
+ }
+ *ec->cstat = cstat;
+ break;
+ case CMD_ERRNO:
+ /* Monitor was unable to execute command or broken pipe. */
+ sudo_debug_printf(SUDO_DEBUG_INFO, "errno from monitor: %s",
+ strerror(cstat.val));
+ sudo_ev_loopbreak(ec->evbase);
+ *ec->cstat = cstat;
+ break;
+ }
+ /* Keep reading command status messages until EAGAIN or EOF. */
+ break;
+ default:
+ /* Short read, should not happen. */
+ if (ec->cstat->val == CMD_INVALID) {
+ ec->cstat->type = CMD_ERRNO;
+ ec->cstat->val = EIO;
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "%s: failed to read command status: short read", __func__);
+ sudo_ev_loopbreak(ec->evbase);
+ }
+ break;
+ }
+ debug_return;
+}
+
+/*
+ * Handle changes to the monitors's status (SIGCHLD).
+ */
+static void
+handle_sigchld_pty(struct exec_closure_pty *ec)
+{
+ int n, status;
+ pid_t pid;
+ debug_decl(handle_sigchld_pty, SUDO_DEBUG_EXEC)
+
+ /*
+ * Monitor process was signaled; wait for it as needed.
+ */
+ do {
+ pid = waitpid(ec->monitor_pid, &status, WUNTRACED|WNOHANG);
+ } while (pid == -1 && errno == EINTR);
+ switch (pid) {
+ case 0:
+ errno = ECHILD;
+ /* FALLTHROUGH */
+ case -1:
+ sudo_warn(U_("%s: %s"), __func__, "waitpid");
+ debug_return;
+ }
+
+ /*
+ * If the monitor dies we get notified via backchannel_cb().
+ * If it was stopped, we should stop too (the command keeps
+ * running in its pty) and continue it when we come back.
+ */
+ if (WIFSTOPPED(status)) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "monitor stopped, suspending sudo");
+ n = suspend_sudo(ec, WSTOPSIG(status));
+ kill(pid, SIGCONT);
+ schedule_signal(ec, n);
+ /* Re-enable I/O events */
+ add_io_events(ec->evbase);
+ } else if (WIFSIGNALED(status)) {
+ char signame[SIG2STR_MAX];
+ if (sig2str(WTERMSIG(status), signame) == -1)
+ snprintf(signame, sizeof(signame), "%d", WTERMSIG(status));
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: monitor (%d) killed, SIG%s",
+ __func__, (int)ec->monitor_pid, signame);
+ ec->monitor_pid = -1;
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: monitor exited, status %d", __func__, WEXITSTATUS(status));
+ ec->monitor_pid = -1;
+ }
+ debug_return;
+}
+
+/* Signal callback */
+static void
+signal_cb_pty(int signo, int what, void *v)
+{
+ struct sudo_ev_siginfo_container *sc = v;
+ struct exec_closure_pty *ec = sc->closure;
+ char signame[SIG2STR_MAX];
+ debug_decl(signal_cb_pty, SUDO_DEBUG_EXEC)
+
+ if (ec->monitor_pid == -1)
+ debug_return;
+
+ if (sig2str(signo, signame) == -1)
+ snprintf(signame, sizeof(signame), "%d", signo);
+ sudo_debug_printf(SUDO_DEBUG_DIAG,
+ "%s: evbase %p, monitor: %d, signo %s(%d), cstat %p", __func__,
+ ec->evbase, (int)ec->monitor_pid, signame, signo, ec->cstat);
+
+ switch (signo) {
+ case SIGCHLD:
+ handle_sigchld_pty(ec);
+ break;
+ case SIGWINCH:
+ sync_ttysize(ec);
+ break;
+ default:
+ /*
+ * Do not forward signals sent by a process in the command's process
+ * group, as we don't want the command to indirectly kill itself.
+ * For example, this can happen with some versions of reboot that
+ * call kill(-1, SIGTERM) to kill all other processes.
+ */
+ if (USER_SIGNALED(sc->siginfo) && sc->siginfo->si_pid != 0) {
+ pid_t si_pgrp = getpgid(sc->siginfo->si_pid);
+ if (si_pgrp != -1) {
+ if (si_pgrp == ec->ppgrp || si_pgrp == ec->cmnd_pid)
+ debug_return;
+ } else if (sc->siginfo->si_pid == ec->cmnd_pid) {
+ debug_return;
+ }
+ }
+ /* Schedule signal to be forwared to the command. */
+ schedule_signal(ec, signo);
+ break;
+ }
+
+ debug_return;
+}
+
+/*
+ * Forward signals in monitor_messages to the monitor so it can
+ * deliver them to the command.
+ */
+static void
+fwdchannel_cb(int sock, int what, void *v)
+{
+ struct exec_closure_pty *ec = v;
+ char signame[SIG2STR_MAX];
+ struct monitor_message *msg;
+ ssize_t nsent;
+ debug_decl(fwdchannel_cb, SUDO_DEBUG_EXEC)
+
+ while ((msg = TAILQ_FIRST(&ec->monitor_messages)) != NULL) {
+ switch (msg->cstat.type) {
+ case CMD_SIGNO:
+ if (msg->cstat.val == SIGCONT_FG)
+ strlcpy(signame, "CONT_FG", sizeof(signame));
+ else if (msg->cstat.val == SIGCONT_BG)
+ strlcpy(signame, "CONT_BG", sizeof(signame));
+ else if (sig2str(msg->cstat.val, signame) == -1)
+ snprintf(signame, sizeof(signame), "%d", msg->cstat.val);
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "sending SIG%s to monitor over backchannel", signame);
+ break;
+ case CMD_TTYWINCH:
+ sudo_debug_printf(SUDO_DEBUG_INFO, "sending window size change "
+ "to monitor over backchannelL %d x %d",
+ msg->cstat.val & 0xffff, (msg->cstat.val >> 16) & 0xffff);
+ break;
+ default:
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "sending cstat type %d, value %d to monitor over backchannel",
+ msg->cstat.type, msg->cstat.val);
+ break;
+ }
+ TAILQ_REMOVE(&ec->monitor_messages, msg, entries);
+ nsent = send(sock, &msg->cstat, sizeof(msg->cstat), 0);
+ if (nsent != sizeof(msg->cstat)) {
+ if (errno == EPIPE) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "broken pipe writing to monitor over backchannel");
+ /* Other end of socket gone, empty out monitor_messages. */
+ free(msg);
+ while ((msg = TAILQ_FIRST(&ec->monitor_messages)) != NULL) {
+ TAILQ_REMOVE(&ec->monitor_messages, msg, entries);
+ free(msg);
+ }
+ /* XXX - need new CMD_ type for monitor errors. */
+ ec->cstat->type = CMD_ERRNO;
+ ec->cstat->val = errno;
+ sudo_ev_loopbreak(ec->evbase);
+ }
+ break;
+ }
+ free(msg);
+ }
+}
+
+/*
+ * Fill in the exec closure and setup initial exec events.
+ * Allocates events for the signal pipe and backchannel.
+ * Forwarded signals on the backchannel are enabled on demand.
+ */
+static void
+fill_exec_closure_pty(struct exec_closure_pty *ec, struct command_status *cstat,
+ struct command_details *details, pid_t ppgrp, int backchannel)
+{
+ debug_decl(fill_exec_closure_pty, SUDO_DEBUG_EXEC)
+
+ /* Fill in the non-event part of the closure. */
+ ec->cmnd_pid = -1;
+ ec->ppgrp = ppgrp;
+ ec->cstat = cstat;
+ ec->details = details;
+ ec->rows = user_details.ts_rows;
+ ec->cols = user_details.ts_cols;
+ TAILQ_INIT(&ec->monitor_messages);
+
+ /* Setup event base and events. */
+ ec->evbase = sudo_ev_base_alloc();
+ if (ec->evbase == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+ /* Event for command status via backchannel. */
+ ec->backchannel_event = sudo_ev_alloc(backchannel,
+ SUDO_EV_READ|SUDO_EV_PERSIST, backchannel_cb, ec);
+ if (ec->backchannel_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->backchannel_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ sudo_debug_printf(SUDO_DEBUG_INFO, "backchannel fd %d\n", backchannel);
+
+ /* Events for local signals. */
+ ec->sigint_event = sudo_ev_alloc(SIGINT,
+ SUDO_EV_SIGINFO, signal_cb_pty, ec);
+ if (ec->sigint_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigint_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigquit_event = sudo_ev_alloc(SIGQUIT,
+ SUDO_EV_SIGINFO, signal_cb_pty, ec);
+ if (ec->sigquit_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigquit_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigtstp_event = sudo_ev_alloc(SIGTSTP,
+ SUDO_EV_SIGINFO, signal_cb_pty, ec);
+ if (ec->sigtstp_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigtstp_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigterm_event = sudo_ev_alloc(SIGTERM,
+ SUDO_EV_SIGINFO, signal_cb_pty, ec);
+ if (ec->sigterm_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigterm_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sighup_event = sudo_ev_alloc(SIGHUP,
+ SUDO_EV_SIGINFO, signal_cb_pty, ec);
+ if (ec->sighup_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sighup_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigalrm_event = sudo_ev_alloc(SIGALRM,
+ SUDO_EV_SIGINFO, signal_cb_pty, ec);
+ if (ec->sigalrm_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigalrm_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigusr1_event = sudo_ev_alloc(SIGUSR1,
+ SUDO_EV_SIGINFO, signal_cb_pty, ec);
+ if (ec->sigusr1_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigusr1_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigusr2_event = sudo_ev_alloc(SIGUSR2,
+ SUDO_EV_SIGINFO, signal_cb_pty, ec);
+ if (ec->sigusr2_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigusr2_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigchld_event = sudo_ev_alloc(SIGCHLD,
+ SUDO_EV_SIGINFO, signal_cb_pty, ec);
+ if (ec->sigchld_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigchld_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ ec->sigwinch_event = sudo_ev_alloc(SIGWINCH,
+ SUDO_EV_SIGINFO, signal_cb_pty, ec);
+ if (ec->sigwinch_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (sudo_ev_add(ec->evbase, ec->sigwinch_event, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+
+ /* The signal forwarding event gets added on demand. */
+ ec->fwdchannel_event = sudo_ev_alloc(backchannel,
+ SUDO_EV_WRITE, fwdchannel_cb, ec);
+ if (ec->fwdchannel_event == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+ /* Set the default event base. */
+ sudo_ev_base_setdef(ec->evbase);
+
+ debug_return;
+}
+
+/*
+ * Free the dynamically-allocated contents of the exec closure.
+ */
+static void
+free_exec_closure_pty(struct exec_closure_pty *ec)
+{
+ struct monitor_message *msg;
+ debug_decl(free_exec_closure_pty, SUDO_DEBUG_EXEC)
+
+ sudo_ev_base_free(ec->evbase);
+ sudo_ev_free(ec->backchannel_event);
+ sudo_ev_free(ec->fwdchannel_event);
+ sudo_ev_free(ec->sigint_event);
+ sudo_ev_free(ec->sigquit_event);
+ sudo_ev_free(ec->sigtstp_event);
+ sudo_ev_free(ec->sigterm_event);
+ sudo_ev_free(ec->sighup_event);
+ sudo_ev_free(ec->sigalrm_event);
+ sudo_ev_free(ec->sigusr1_event);
+ sudo_ev_free(ec->sigusr2_event);
+ sudo_ev_free(ec->sigchld_event);
+ sudo_ev_free(ec->sigwinch_event);
+
+ while ((msg = TAILQ_FIRST(&ec->monitor_messages)) != NULL) {
+ TAILQ_REMOVE(&ec->monitor_messages, msg, entries);
+ free(msg);
+ }
+
+ debug_return;
+}
+
+/*
+ * Execute a command in a pty, potentially with I/O loggging, and
+ * wait for it to finish.
+ * This is a little bit tricky due to how POSIX job control works and
+ * we fact that we have two different controlling terminals to deal with.
+ */
+bool
+exec_pty(struct command_details *details, struct command_status *cstat)
+{
+ int io_pipe[3][2] = { { -1, -1 }, { -1, -1 }, { -1, -1 } };
+ bool interpose[3] = { false, false, false };
+ struct exec_closure_pty ec = { 0 };
+ struct plugin_container *plugin;
+ sigset_t set, oset;
+ struct sigaction sa;
+ struct stat sb;
+ pid_t ppgrp;
+ int sv[2];
+ debug_decl(exec_pty, SUDO_DEBUG_EXEC)
+
+ /*
+ * Allocate a pty.
+ */
+ if (!pty_setup(details, user_details.tty)) {
+ if (TAILQ_EMPTY(&io_plugins)) {
+ /* Not logging I/O and didn't allocate a pty. */
+ debug_return_bool(false);
+ }
+ }
+
+ /*
+ * We communicate with the monitor over a bi-directional pair of sockets.
+ * Parent sends signal info to monitor and monitor sends back wait status.
+ */
+ if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1)
+ sudo_fatal(U_("unable to create sockets"));
+
+ /*
+ * We don't want to receive SIGTTIN/SIGTTOU.
+ * XXX - this affects tcsetattr() and tcsetpgrp() too.
+ */
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = SIG_IGN;
+ if (sudo_sigaction(SIGTTIN, &sa, NULL) != 0)
+ sudo_warn(U_("unable to set handler for signal %d"), SIGTTIN);
+ if (sudo_sigaction(SIGTTOU, &sa, NULL) != 0)
+ sudo_warn(U_("unable to set handler for signal %d"), SIGTTOU);
+
+ /*
+ * The policy plugin's session init must be run before we fork
+ * or certain pam modules won't be able to track their state.
+ */
+ if (policy_init_session(details) != true)
+ sudo_fatalx(U_("policy plugin failed session initialization"));
+
+ /*
+ * Child will run the command in the pty, parent will pass data
+ * to and from pty.
+ */
+
+ /* So we can block tty-generated signals */
+ sigemptyset(&ttyblock);
+ sigaddset(&ttyblock, SIGINT);
+ sigaddset(&ttyblock, SIGQUIT);
+ sigaddset(&ttyblock, SIGTSTP);
+ sigaddset(&ttyblock, SIGTTIN);
+ sigaddset(&ttyblock, SIGTTOU);
+
+ ppgrp = getpgrp(); /* parent's pgrp, so child can signal us */
+
+ /* Determine whether any of std{in,out,err} should be logged. */
+ TAILQ_FOREACH(plugin, &io_plugins, entries) {
+ if (plugin->u.io->log_stdin)
+ interpose[STDIN_FILENO] = true;
+ if (plugin->u.io->log_stdout)
+ interpose[STDOUT_FILENO] = true;
+ if (plugin->u.io->log_stderr)
+ interpose[STDERR_FILENO] = true;
+ }
+
+ /*
+ * Setup stdin/stdout/stderr for command, to be duped after forking.
+ * In background mode there is no stdin.
+ */
+ if (!ISSET(details->flags, CD_BACKGROUND))
+ io_fds[SFD_STDIN] = io_fds[SFD_SLAVE];
+ io_fds[SFD_STDOUT] = io_fds[SFD_SLAVE];
+ io_fds[SFD_STDERR] = io_fds[SFD_SLAVE];
+
+ if (io_fds[SFD_USERTTY] != -1) {
+ /* Read from /dev/tty, write to pty master */
+ if (!ISSET(details->flags, CD_BACKGROUND)) {
+ io_buf_new(io_fds[SFD_USERTTY], io_fds[SFD_MASTER],
+ log_ttyin, &ec, &iobufs);
+ }
+
+ /* Read from pty master, write to /dev/tty */
+ io_buf_new(io_fds[SFD_MASTER], io_fds[SFD_USERTTY],
+ log_ttyout, &ec, &iobufs);
+
+ /* Are we the foreground process? */
+ foreground = tcgetpgrp(io_fds[SFD_USERTTY]) == ppgrp;
+ }
+
+ /*
+ * If stdin, stdout or stderr is not a tty and logging is enabled,
+ * use a pipe to interpose ourselves instead of using the pty fd.
+ */
+ if (io_fds[SFD_STDIN] == -1 || !isatty(STDIN_FILENO)) {
+ if (!interpose[STDIN_FILENO]) {
+ /* Not logging stdin, do not interpose. */
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "stdin not a tty, not logging");
+ if (fstat(STDIN_FILENO, &sb) == 0 && S_ISFIFO(sb.st_mode))
+ pipeline = true;
+ io_fds[SFD_STDIN] = dup(STDIN_FILENO);
+ if (io_fds[SFD_STDIN] == -1)
+ sudo_fatal("dup");
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "stdin not a tty, creating a pipe");
+ pipeline = true;
+ if (pipe(io_pipe[STDIN_FILENO]) != 0)
+ sudo_fatal(U_("unable to create pipe"));
+ io_buf_new(STDIN_FILENO, io_pipe[STDIN_FILENO][1],
+ log_stdin, &ec, &iobufs);
+ io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0];
+ }
+ }
+ if (io_fds[SFD_STDOUT] == -1 || !isatty(STDOUT_FILENO)) {
+ if (!interpose[STDOUT_FILENO]) {
+ /* Not logging stdout, do not interpose. */
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "stdout not a tty, not logging");
+ if (fstat(STDOUT_FILENO, &sb) == 0 && S_ISFIFO(sb.st_mode))
+ pipeline = true;
+ io_fds[SFD_STDOUT] = dup(STDOUT_FILENO);
+ if (io_fds[SFD_STDOUT] == -1)
+ sudo_fatal("dup");
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "stdout not a tty, creating a pipe");
+ pipeline = true;
+ if (pipe(io_pipe[STDOUT_FILENO]) != 0)
+ sudo_fatal(U_("unable to create pipe"));
+ io_buf_new(io_pipe[STDOUT_FILENO][0], STDOUT_FILENO,
+ log_stdout, &ec, &iobufs);
+ io_fds[SFD_STDOUT] = io_pipe[STDOUT_FILENO][1];
+ }
+ }
+ if (io_fds[SFD_STDERR] == -1 || !isatty(STDERR_FILENO)) {
+ if (!interpose[STDERR_FILENO]) {
+ /* Not logging stderr, do not interpose. */
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "stderr not a tty, not logging");
+ if (fstat(STDERR_FILENO, &sb) == 0 && S_ISFIFO(sb.st_mode))
+ pipeline = true;
+ io_fds[SFD_STDERR] = dup(STDERR_FILENO);
+ if (io_fds[SFD_STDERR] == -1)
+ sudo_fatal("dup");
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "stderr not a tty, creating a pipe");
+ if (pipe(io_pipe[STDERR_FILENO]) != 0)
+ sudo_fatal(U_("unable to create pipe"));
+ io_buf_new(io_pipe[STDERR_FILENO][0], STDERR_FILENO,
+ log_stderr, &ec, &iobufs);
+ io_fds[SFD_STDERR] = io_pipe[STDERR_FILENO][1];
+ }
+ }
+
+ if (foreground) {
+ /* Copy terminal attrs from user tty -> pty slave. */
+ if (!sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE])) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to copy terminal settings to pty", __func__);
+ foreground = false;
+ } else {
+ /* Start in raw mode unless part of a pipeline or backgrounded. */
+ if (!pipeline && !ISSET(details->flags, CD_EXEC_BG)) {
+ if (sudo_term_raw(io_fds[SFD_USERTTY], 0))
+ ttymode = TERM_RAW;
+ }
+ }
+ }
+
+ /*
+ * Block signals until we have our handlers setup in the parent so
+ * we don't miss SIGCHLD if the command exits immediately.
+ */
+ sigfillset(&set);
+ sigprocmask(SIG_BLOCK, &set, &oset);
+
+ /* Check for early termination or suspend signals before we fork. */
+ if (sudo_terminated(cstat)) {
+ sigprocmask(SIG_SETMASK, &oset, NULL);
+ debug_return_int(true);
+ }
+
+ ec.monitor_pid = sudo_debug_fork();
+ switch (ec.monitor_pid) {
+ case -1:
+ sudo_fatal(U_("unable to fork"));
+ break;
+ case 0:
+ /* child */
+ close(sv[0]);
+ (void)fcntl(sv[1], F_SETFD, FD_CLOEXEC);
+ /* Close the other end of the stdin/stdout/stderr pipes and exec. */
+ if (io_pipe[STDIN_FILENO][1] != -1)
+ close(io_pipe[STDIN_FILENO][1]);
+ if (io_pipe[STDOUT_FILENO][0] != -1)
+ close(io_pipe[STDOUT_FILENO][0]);
+ if (io_pipe[STDERR_FILENO][0] != -1)
+ close(io_pipe[STDERR_FILENO][0]);
+ /*
+ * If stdin/stdout is not a tty, start command in the background
+ * since it might be part of a pipeline that reads from /dev/tty.
+ * In this case, we rely on the command receiving SIGTTOU or SIGTTIN
+ * when it needs access to the controlling tty.
+ */
+ exec_monitor(details, &oset, foreground && !pipeline, sv[1]);
+ cstat->type = CMD_ERRNO;
+ cstat->val = errno;
+ if (send(sv[1], cstat, sizeof(*cstat), 0) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to send status to parent", __func__);
+ }
+ _exit(1);
+ }
+
+ /*
+ * We close the pty slave so only the monitor and command have a
+ * reference to it. This ensures that we can don't block reading
+ * from the master when the command and monitor have exited.
+ */
+ if (io_fds[SFD_SLAVE] != -1) {
+ close(io_fds[SFD_SLAVE]);
+ io_fds[SFD_SLAVE] = -1;
+ }
+
+ /* Tell the monitor to continue now that the slave is closed. */
+ cstat->type = CMD_SIGNO;
+ cstat->val = 0;
+ while (send(sv[0], cstat, sizeof(*cstat), 0) == -1) {
+ if (errno != EINTR && errno != EAGAIN)
+ sudo_fatal(U_("unable to send message to monitor process"));
+ }
+
+ /* Close the other end of the stdin/stdout/stderr pipes and socketpair. */
+ if (io_pipe[STDIN_FILENO][0] != -1)
+ close(io_pipe[STDIN_FILENO][0]);
+ if (io_pipe[STDOUT_FILENO][1] != -1)
+ close(io_pipe[STDOUT_FILENO][1]);
+ if (io_pipe[STDERR_FILENO][1] != -1)
+ close(io_pipe[STDERR_FILENO][1]);
+ close(sv[1]);
+
+ /* No longer need execfd. */
+ if (details->execfd != -1) {
+ close(details->execfd);
+ details->execfd = -1;
+ }
+
+ /* Set command timeout if specified. */
+ if (ISSET(details->flags, CD_SET_TIMEOUT))
+ alarm(details->timeout);
+
+ /*
+ * Fill in exec closure, allocate event base, signal events and
+ * the backchannel event.
+ */
+ fill_exec_closure_pty(&ec, cstat, details, ppgrp, sv[0]);
+
+ /* Restore signal mask now that signal handlers are setup. */
+ sigprocmask(SIG_SETMASK, &oset, NULL);
+
+ /*
+ * I/O logging must be in the C locale for floating point numbers
+ * to be logged consistently.
+ */
+ setlocale(LC_ALL, "C");
+
+ /*
+ * In the event loop we pass input from user tty to master
+ * and pass output from master to stdout and IO plugin.
+ */
+ add_io_events(ec.evbase);
+ if (sudo_ev_dispatch(ec.evbase) == -1)
+ sudo_warn(U_("error in event loop"));
+ if (sudo_ev_got_break(ec.evbase)) {
+ /* error from callback or monitor died */
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "event loop exited prematurely");
+ /* XXX - may need to terminate command if cmnd_pid != -1 */
+ }
+
+ /* Flush any remaining output, free I/O bufs and events, do logout. */
+ pty_finish(cstat);
+
+ /* Free things up. */
+ free_exec_closure_pty(&ec);
+
+ debug_return_bool(true);
+}
+
+/*
+ * Schedule I/O events before starting the main event loop or
+ * resuming from suspend.
+ */
+static void
+add_io_events(struct sudo_event_base *evbase)
+{
+ struct io_buffer *iob;
+ debug_decl(add_io_events, SUDO_DEBUG_EXEC);
+
+ /*
+ * Schedule all readers as long as the buffer is not full.
+ * Schedule writers that contain buffered data.
+ * Normally, write buffers are added on demand when data is read.
+ */
+ SLIST_FOREACH(iob, &iobufs, entries) {
+ /* Don't read from /dev/tty if we are not in the foreground. */
+ if (iob->revent != NULL &&
+ (ttymode == TERM_RAW || !USERTTY_EVENT(iob->revent))) {
+ if (iob->len != sizeof(iob->buf)) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "added I/O revent %p, fd %d, events %d",
+ iob->revent, iob->revent->fd, iob->revent->events);
+ if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ }
+ }
+ if (iob->wevent != NULL) {
+ /* Enable writer if buffer is not empty. */
+ if (iob->len > iob->off) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "added I/O wevent %p, fd %d, events %d",
+ iob->wevent, iob->wevent->fd, iob->wevent->events);
+ if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ }
+ }
+ }
+ debug_return;
+}
+
+/*
+ * Flush any output buffered in iobufs or readable from fds other
+ * than /dev/tty. Removes I/O events from the event base when done.
+ */
+static void
+del_io_events(bool nonblocking)
+{
+ struct io_buffer *iob;
+ struct sudo_event_base *evbase;
+ debug_decl(del_io_events, SUDO_DEBUG_EXEC);
+
+ /* Remove iobufs from existing event base. */
+ SLIST_FOREACH(iob, &iobufs, entries) {
+ if (iob->revent != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "deleted I/O revent %p, fd %d, events %d",
+ iob->revent, iob->revent->fd, iob->revent->events);
+ sudo_ev_del(NULL, iob->revent);
+ }
+ if (iob->wevent != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "deleted I/O wevent %p, fd %d, events %d",
+ iob->wevent, iob->wevent->fd, iob->wevent->events);
+ sudo_ev_del(NULL, iob->wevent);
+ }
+ }
+
+ /* Create temporary event base for flushing. */
+ evbase = sudo_ev_base_alloc();
+ if (evbase == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+ /* Avoid reading from /dev/tty, just flush existing data. */
+ SLIST_FOREACH(iob, &iobufs, entries) {
+ /* Don't read from /dev/tty while flushing. */
+ if (iob->revent != NULL && !USERTTY_EVENT(iob->revent)) {
+ if (iob->len != sizeof(iob->buf)) {
+ if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ }
+ }
+ /* Flush any write buffers with data in them. */
+ if (iob->wevent != NULL) {
+ if (iob->len > iob->off) {
+ if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ }
+ }
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: flushing remaining I/O buffers (nonblocking)", __func__);
+ (void) sudo_ev_loop(evbase, SUDO_EVLOOP_NONBLOCK);
+
+ /*
+ * If not in non-blocking mode, make sure we flush write buffers.
+ * We don't want to read from the pty or stdin since that might block
+ * and the command is no longer running anyway.
+ */
+ if (!nonblocking) {
+ /* Clear out iobufs from event base. */
+ SLIST_FOREACH(iob, &iobufs, entries) {
+ if (iob->revent != NULL && !USERTTY_EVENT(iob->revent))
+ sudo_ev_del(evbase, iob->revent);
+ if (iob->wevent != NULL)
+ sudo_ev_del(evbase, iob->wevent);
+ }
+
+ SLIST_FOREACH(iob, &iobufs, entries) {
+ /* Flush any write buffers with data in them. */
+ if (iob->wevent != NULL) {
+ if (iob->len > iob->off) {
+ if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1)
+ sudo_fatal(U_("unable to add event to queue"));
+ }
+ }
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: flushing remaining write buffers (blocking)", __func__);
+ (void) sudo_ev_dispatch(evbase);
+
+ /* We should now have flushed all write buffers. */
+ SLIST_FOREACH(iob, &iobufs, entries) {
+ if (iob->wevent != NULL) {
+ if (iob->len > iob->off) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR,
+ "unflushed data: wevent %p, fd %d, events %d",
+ iob->wevent, iob->wevent->fd, iob->wevent->events);
+ }
+ }
+ }
+ }
+
+ /* Free temporary event base, removing its events. */
+ sudo_ev_base_free(evbase);
+
+ debug_return;
+}
+
+/*
+ * Check for tty size changes.
+ * Passes the new window size to the I/O plugin and to the monitor.
+ */
+static void
+sync_ttysize(struct exec_closure_pty *ec)
+{
+ struct winsize wsize;
+ debug_decl(sync_ttysize, SUDO_DEBUG_EXEC);
+
+ if (ioctl(io_fds[SFD_USERTTY], TIOCGWINSZ, &wsize) == 0) {
+ if (wsize.ws_row != ec->rows || wsize.ws_col != ec->cols) {
+ const unsigned int wsize_packed = (wsize.ws_row & 0xffff) |
+ ((wsize.ws_col & 0xffff) << 16);
+
+ /* Log window change event. */
+ log_winchange(wsize.ws_row, wsize.ws_col);
+
+ /* Send window change event to monitor process. */
+ send_command_status(ec, CMD_TTYWINCH, wsize_packed);
+
+ /* Update rows/cols. */
+ ec->rows = wsize.ws_row;
+ ec->cols = wsize.ws_col;
+ }
+ }
+
+ debug_return;
+}
+
+/*
+ * Remove and free any events associated with the specified
+ * file descriptor present in the I/O buffers list.
+ */
+static void
+ev_free_by_fd(struct sudo_event_base *evbase, int fd)
+{
+ struct io_buffer *iob;
+ debug_decl(ev_free_by_fd, SUDO_DEBUG_EXEC);
+
+ /* Deschedule any users of the fd and free up the events. */
+ SLIST_FOREACH(iob, &iobufs, entries) {
+ if (iob->revent != NULL) {
+ if (sudo_ev_get_fd(iob->revent) == fd) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: deleting and freeing revent %p with fd %d",
+ __func__, iob->revent, fd);
+ sudo_ev_free(iob->revent);
+ iob->revent = NULL;
+ }
+ }
+ if (iob->wevent != NULL) {
+ if (sudo_ev_get_fd(iob->wevent) == fd) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: deleting and freeing wevent %p with fd %d",
+ __func__, iob->wevent, fd);
+ sudo_ev_free(iob->wevent);
+ iob->wevent = NULL;
+ }
+ }
+ }
+ debug_return;
+}
+
+/*
+ * Only close the fd if it is not /dev/tty or std{in,out,err}.
+ * Return value is the same as close(2).
+ */
+static int
+safe_close(int fd)
+{
+ debug_decl(safe_close, SUDO_DEBUG_EXEC);
+
+ /* Avoid closing /dev/tty or std{in,out,err}. */
+ if (fd < 3 || fd == io_fds[SFD_USERTTY]) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: not closing fd %d (%s)", __func__, fd, _PATH_TTY);
+ errno = EINVAL;
+ debug_return_int(-1);
+ }
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: closing fd %d", __func__, fd);
+ debug_return_int(close(fd));
+}
diff --git a/src/get_pty.c b/src/get_pty.c
new file mode 100644
index 0000000..3e1a26a
--- /dev/null
+++ b/src/get_pty.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2009-2012, 2014-2016
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#ifdef HAVE_SYS_STROPTS_H
+#include <sys/stropts.h>
+#endif /* HAVE_SYS_STROPTS_H */
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <pwd.h>
+
+#if defined(HAVE_LIBUTIL_H)
+# include <libutil.h>
+#elif defined(HAVE_UTIL_H)
+# include <util.h>
+#endif
+#ifdef HAVE_PTY_H
+# include <pty.h>
+#endif
+
+#include "sudo.h"
+
+#if defined(HAVE_OPENPTY)
+bool
+get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
+{
+ struct group *gr;
+ gid_t ttygid = -1;
+ bool ret = false;
+ debug_decl(get_pty, SUDO_DEBUG_PTY)
+
+ if ((gr = getgrnam("tty")) != NULL)
+ ttygid = gr->gr_gid;
+
+ if (openpty(master, slave, name, NULL, NULL) == 0) {
+ if (chown(name, ttyuid, ttygid) == 0)
+ ret = true;
+ }
+
+ debug_return_bool(ret);
+}
+
+#elif defined(HAVE__GETPTY)
+bool
+get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
+{
+ char *line;
+ bool ret = false;
+ debug_decl(get_pty, SUDO_DEBUG_PTY)
+
+ /* IRIX-style dynamic ptys (may fork) */
+ line = _getpty(master, O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP, 0);
+ if (line != NULL) {
+ *slave = open(line, O_RDWR|O_NOCTTY, 0);
+ if (*slave != -1) {
+ (void) chown(line, ttyuid, -1);
+ strlcpy(name, line, namesz);
+ ret = true;
+ } else {
+ close(*master);
+ *master = -1;
+ }
+ }
+ debug_return_bool(ret);
+}
+#elif defined(HAVE_GRANTPT)
+# ifndef HAVE_POSIX_OPENPT
+static int
+posix_openpt(int oflag)
+{
+ int fd;
+
+# ifdef _AIX
+ fd = open(_PATH_DEV "ptc", oflag);
+# else
+ fd = open(_PATH_DEV "ptmx", oflag);
+# endif
+ return fd;
+}
+# endif /* HAVE_POSIX_OPENPT */
+
+bool
+get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
+{
+ char *line;
+ bool ret = false;
+ debug_decl(get_pty, SUDO_DEBUG_PTY)
+
+ *master = posix_openpt(O_RDWR|O_NOCTTY);
+ if (*master != -1) {
+ (void) grantpt(*master); /* may fork */
+ if (unlockpt(*master) != 0) {
+ close(*master);
+ goto done;
+ }
+ line = ptsname(*master);
+ if (line == NULL) {
+ close(*master);
+ goto done;
+ }
+ *slave = open(line, O_RDWR|O_NOCTTY, 0);
+ if (*slave == -1) {
+ close(*master);
+ goto done;
+ }
+# if defined(I_PUSH) && !defined(_AIX)
+ ioctl(*slave, I_PUSH, "ptem"); /* pseudo tty emulation module */
+ ioctl(*slave, I_PUSH, "ldterm"); /* line discipline module */
+# endif
+ (void) chown(line, ttyuid, -1);
+ strlcpy(name, line, namesz);
+ ret = true;
+ }
+done:
+ debug_return_bool(ret);
+}
+
+#else /* Old-style BSD ptys */
+
+static char line[] = _PATH_DEV "ptyXX";
+
+bool
+get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
+{
+ char *bank, *cp;
+ struct group *gr;
+ gid_t ttygid = -1;
+ bool ret = false;
+ debug_decl(get_pty, SUDO_DEBUG_PTY)
+
+ if ((gr = getgrnam("tty")) != NULL)
+ ttygid = gr->gr_gid;
+
+ for (bank = "pqrs"; *bank != '\0'; bank++) {
+ line[sizeof(_PATH_DEV "ptyX") - 2] = *bank;
+ for (cp = "0123456789abcdef"; *cp != '\0'; cp++) {
+ line[sizeof(_PATH_DEV "ptyXX") - 2] = *cp;
+ *master = open(line, O_RDWR|O_NOCTTY, 0);
+ if (*master == -1) {
+ if (errno == ENOENT)
+ goto done; /* out of ptys */
+ continue; /* already in use */
+ }
+ line[sizeof(_PATH_DEV "p") - 2] = 't';
+ (void) chown(line, ttyuid, ttygid);
+ (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
+# ifdef HAVE_REVOKE
+ (void) revoke(line);
+# endif
+ *slave = open(line, O_RDWR|O_NOCTTY, 0);
+ if (*slave != -1) {
+ strlcpy(name, line, namesz);
+ ret = true; /* success */
+ goto done;
+ }
+ (void) close(*master);
+ }
+ }
+done:
+ debug_return_bool(ret);
+}
+#endif /* HAVE_OPENPTY */
diff --git a/src/hooks.c b/src/hooks.c
new file mode 100644
index 0000000..1216980
--- /dev/null
+++ b/src/hooks.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2012-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+
+#include "sudo.h"
+#include "sudo_plugin.h"
+#include "sudo_plugin_int.h"
+
+/* Singly linked hook list. */
+struct sudo_hook_entry {
+ SLIST_ENTRY(sudo_hook_entry) entries;
+ union {
+ sudo_hook_fn_t generic_fn;
+ sudo_hook_fn_setenv_t setenv_fn;
+ sudo_hook_fn_unsetenv_t unsetenv_fn;
+ sudo_hook_fn_getenv_t getenv_fn;
+ sudo_hook_fn_putenv_t putenv_fn;
+ } u;
+ void *closure;
+};
+SLIST_HEAD(sudo_hook_list, sudo_hook_entry);
+
+/* Each hook type gets own hook list. */
+static struct sudo_hook_list sudo_hook_setenv_list =
+ SLIST_HEAD_INITIALIZER(sudo_hook_setenv_list);
+static struct sudo_hook_list sudo_hook_unsetenv_list =
+ SLIST_HEAD_INITIALIZER(sudo_hook_unsetenv_list);
+static struct sudo_hook_list sudo_hook_getenv_list =
+ SLIST_HEAD_INITIALIZER(sudo_hook_getenv_list);
+static struct sudo_hook_list sudo_hook_putenv_list =
+ SLIST_HEAD_INITIALIZER(sudo_hook_putenv_list);
+
+/* NOTE: must not anything that might call setenv() */
+int
+process_hooks_setenv(const char *name, const char *value, int overwrite)
+{
+ struct sudo_hook_entry *hook;
+ int rc = SUDO_HOOK_RET_NEXT;
+
+ /* First process the hooks. */
+ SLIST_FOREACH(hook, &sudo_hook_setenv_list, entries) {
+ rc = hook->u.setenv_fn(name, value, overwrite, hook->closure);
+ if (rc == SUDO_HOOK_RET_STOP || rc == SUDO_HOOK_RET_ERROR)
+ break;
+ }
+ return rc;
+}
+
+/* NOTE: must not anything that might call putenv() */
+int
+process_hooks_putenv(char *string)
+{
+ struct sudo_hook_entry *hook;
+ int rc = SUDO_HOOK_RET_NEXT;
+
+ /* First process the hooks. */
+ SLIST_FOREACH(hook, &sudo_hook_putenv_list, entries) {
+ rc = hook->u.putenv_fn(string, hook->closure);
+ if (rc == SUDO_HOOK_RET_STOP || rc == SUDO_HOOK_RET_ERROR)
+ break;
+ }
+ return rc;
+}
+
+/* NOTE: must not anything that might call getenv() */
+int
+process_hooks_getenv(const char *name, char **value)
+{
+ struct sudo_hook_entry *hook;
+ char *val = NULL;
+ int rc = SUDO_HOOK_RET_NEXT;
+
+ /* First process the hooks. */
+ SLIST_FOREACH(hook, &sudo_hook_getenv_list, entries) {
+ rc = hook->u.getenv_fn(name, &val, hook->closure);
+ if (rc == SUDO_HOOK_RET_STOP || rc == SUDO_HOOK_RET_ERROR)
+ break;
+ }
+ if (val != NULL)
+ *value = val;
+ return rc;
+}
+
+/* NOTE: must not anything that might call unsetenv() */
+int
+process_hooks_unsetenv(const char *name)
+{
+ struct sudo_hook_entry *hook;
+ int rc = SUDO_HOOK_RET_NEXT;
+
+ /* First process the hooks. */
+ SLIST_FOREACH(hook, &sudo_hook_unsetenv_list, entries) {
+ rc = hook->u.unsetenv_fn(name, hook->closure);
+ if (rc == SUDO_HOOK_RET_STOP || rc == SUDO_HOOK_RET_ERROR)
+ break;
+ }
+ return rc;
+}
+
+/* Hook registration internals. */
+static int
+register_hook_internal(struct sudo_hook_list *head,
+ int (*hook_fn)(), void *closure)
+{
+ struct sudo_hook_entry *hook;
+ debug_decl(register_hook_internal, SUDO_DEBUG_HOOKS)
+
+ if ((hook = calloc(1, sizeof(*hook))) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_int(-1);
+ }
+ hook->u.generic_fn = hook_fn;
+ hook->closure = closure;
+ SLIST_INSERT_HEAD(head, hook, entries);
+
+ debug_return_int(0);
+}
+
+/* Register the specified hook. */
+int
+register_hook(struct sudo_hook *hook)
+{
+ int ret;
+ debug_decl(register_hook, SUDO_DEBUG_HOOKS)
+
+ if (SUDO_API_VERSION_GET_MAJOR(hook->hook_version) != SUDO_HOOK_VERSION_MAJOR) {
+ /* Major versions must match. */
+ errno = EINVAL;
+ ret = -1;
+ } else {
+ switch (hook->hook_type) {
+ case SUDO_HOOK_GETENV:
+ ret = register_hook_internal(&sudo_hook_getenv_list,
+ hook->hook_fn, hook->closure);
+ break;
+ case SUDO_HOOK_PUTENV:
+ ret = register_hook_internal(&sudo_hook_putenv_list,
+ hook->hook_fn, hook->closure);
+ break;
+ case SUDO_HOOK_SETENV:
+ ret = register_hook_internal(&sudo_hook_setenv_list,
+ hook->hook_fn, hook->closure);
+ break;
+ case SUDO_HOOK_UNSETENV:
+ ret = register_hook_internal(&sudo_hook_unsetenv_list,
+ hook->hook_fn, hook->closure);
+ break;
+ default:
+ /* XXX - use define for unknown value */
+ errno = ENOTSUP;
+ ret = 1;
+ break;
+ }
+ }
+
+ debug_return_int(ret);
+}
+
+/* Hook deregistration internals. */
+static void
+deregister_hook_internal(struct sudo_hook_list *head,
+ int (*hook_fn)(), void *closure)
+{
+ struct sudo_hook_entry *hook, *prev = NULL;
+ debug_decl(deregister_hook_internal, SUDO_DEBUG_HOOKS)
+
+ SLIST_FOREACH(hook, head, entries) {
+ if (hook->u.generic_fn == hook_fn && hook->closure == closure) {
+ /* Remove from list and free. */
+ if (prev == NULL)
+ SLIST_REMOVE_HEAD(head, entries);
+ else
+ SLIST_REMOVE_AFTER(prev, entries);
+ free(hook);
+ break;
+ }
+ prev = hook;
+ }
+
+ debug_return;
+}
+
+/* Deregister the specified hook. */
+int
+deregister_hook(struct sudo_hook *hook)
+{
+ int ret = 0;
+ debug_decl(deregister_hook, SUDO_DEBUG_HOOKS)
+
+ if (SUDO_API_VERSION_GET_MAJOR(hook->hook_version) != SUDO_HOOK_VERSION_MAJOR) {
+ /* Major versions must match. */
+ ret = -1;
+ } else {
+ switch (hook->hook_type) {
+ case SUDO_HOOK_GETENV:
+ deregister_hook_internal(&sudo_hook_getenv_list, hook->hook_fn,
+ hook->closure);
+ break;
+ case SUDO_HOOK_PUTENV:
+ deregister_hook_internal(&sudo_hook_putenv_list, hook->hook_fn,
+ hook->closure);
+ break;
+ case SUDO_HOOK_SETENV:
+ deregister_hook_internal(&sudo_hook_setenv_list, hook->hook_fn,
+ hook->closure);
+ break;
+ case SUDO_HOOK_UNSETENV:
+ deregister_hook_internal(&sudo_hook_unsetenv_list, hook->hook_fn,
+ hook->closure);
+ break;
+ default:
+ /* XXX - use define for unknown value */
+ ret = 1;
+ break;
+ }
+ }
+
+ debug_return_int(ret);
+}
diff --git a/src/load_plugins.c b/src/load_plugins.c
new file mode 100644
index 0000000..8cac77b
--- /dev/null
+++ b/src/load_plugins.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+
+#include "sudo.h"
+#include "sudo_plugin.h"
+#include "sudo_plugin_int.h"
+#include "sudo_dso.h"
+
+/* We always use the same name for the sudoers plugin, regardless of the OS */
+#define SUDOERS_PLUGIN "sudoers.so"
+
+#ifdef ENABLE_SUDO_PLUGIN_API
+static int
+sudo_stat_plugin(struct plugin_info *info, char *fullpath,
+ size_t pathsize, struct stat *sb)
+{
+ int status = -1;
+ debug_decl(sudo_stat_plugin, SUDO_DEBUG_PLUGIN)
+
+ if (info->path[0] == '/') {
+ if (strlcpy(fullpath, info->path, pathsize) >= pathsize) {
+ sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
+ _PATH_SUDO_CONF, info->lineno, info->symbol_name);
+ sudo_warnx(U_("%s: %s"), info->path, strerror(ENAMETOOLONG));
+ goto done;
+ }
+ status = stat(fullpath, sb);
+ } else {
+ int len;
+
+#ifdef STATIC_SUDOERS_PLUGIN
+ /* Check static symbols. */
+ if (strcmp(info->path, SUDOERS_PLUGIN) == 0) {
+ if (strlcpy(fullpath, info->path, pathsize) >= pathsize) {
+ sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
+ _PATH_SUDO_CONF, info->lineno, info->symbol_name);
+ sudo_warnx(U_("%s: %s"), info->path, strerror(ENAMETOOLONG));
+ goto done;
+ }
+ /* Plugin is static, fake up struct stat. */
+ memset(sb, 0, sizeof(*sb));
+ sb->st_uid = ROOT_UID;
+ sb->st_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
+ status = 0;
+ goto done;
+ }
+#endif /* STATIC_SUDOERS_PLUGIN */
+
+ if (sudo_conf_plugin_dir_path() == NULL) {
+ errno = ENOENT;
+ goto done;
+ }
+
+ len = snprintf(fullpath, pathsize, "%s%s", sudo_conf_plugin_dir_path(),
+ info->path);
+ if (len <= 0 || (size_t)len >= pathsize) {
+ sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
+ _PATH_SUDO_CONF, info->lineno, info->symbol_name);
+ sudo_warnx(U_("%s%s: %s"), sudo_conf_plugin_dir_path(), info->path,
+ strerror(ENAMETOOLONG));
+ goto done;
+ }
+ /* Try parent dir for compatibility with old plugindir default. */
+ if ((status = stat(fullpath, sb)) != 0) {
+ char *cp = strrchr(fullpath, '/');
+ if (cp > fullpath + 4 && cp[-5] == '/' && cp[-4] == 's' &&
+ cp[-3] == 'u' && cp[-2] == 'd' && cp[-1] == 'o') {
+ int serrno = errno;
+ strlcpy(cp - 4, info->path, pathsize - (cp - 4 - fullpath));
+ if ((status = stat(fullpath, sb)) != 0)
+ errno = serrno;
+ }
+ }
+ }
+done:
+ debug_return_int(status);
+}
+
+static bool
+sudo_check_plugin(struct plugin_info *info, char *fullpath, size_t pathsize)
+{
+ struct stat sb;
+ bool ret = false;
+ debug_decl(sudo_check_plugin, SUDO_DEBUG_PLUGIN)
+
+ if (sudo_stat_plugin(info, fullpath, pathsize, &sb) != 0) {
+ sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
+ _PATH_SUDO_CONF, info->lineno, info->symbol_name);
+ sudo_warn("%s%s",
+ sudo_conf_plugin_dir_path() ? sudo_conf_plugin_dir_path() : "",
+ info->path);
+ goto done;
+ }
+ if (sb.st_uid != ROOT_UID) {
+ sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
+ _PATH_SUDO_CONF, info->lineno, info->symbol_name);
+ sudo_warnx(U_("%s must be owned by uid %d"), fullpath, ROOT_UID);
+ goto done;
+ }
+ if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
+ sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
+ _PATH_SUDO_CONF, info->lineno, info->symbol_name);
+ sudo_warnx(U_("%s must be only be writable by owner"), fullpath);
+ goto done;
+ }
+ ret = true;
+
+done:
+ debug_return_bool(ret);
+}
+#else
+static bool
+sudo_check_plugin(struct plugin_info *info, char *fullpath, size_t pathsize)
+{
+ debug_decl(sudo_check_plugin, SUDO_DEBUG_PLUGIN)
+ (void)strlcpy(fullpath, info->path, pathsize);
+ debug_return_bool(true);
+}
+#endif /* ENABLE_SUDO_PLUGIN_API */
+
+/*
+ * Load the plugin specified by "info".
+ */
+static bool
+sudo_load_plugin(struct plugin_container *policy_plugin,
+ struct plugin_container_list *io_plugins, struct plugin_info *info)
+{
+ struct plugin_container *container = NULL;
+ struct generic_plugin *plugin;
+ char path[PATH_MAX];
+ void *handle = NULL;
+ debug_decl(sudo_load_plugin, SUDO_DEBUG_PLUGIN)
+
+ /* Sanity check plugin and fill in path */
+ if (!sudo_check_plugin(info, path, sizeof(path)))
+ goto bad;
+
+ /* Open plugin and map in symbol */
+ handle = sudo_dso_load(path, SUDO_DSO_LAZY|SUDO_DSO_GLOBAL);
+ if (!handle) {
+ const char *errstr = sudo_dso_strerror();
+ sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
+ _PATH_SUDO_CONF, info->lineno, info->symbol_name);
+ sudo_warnx(U_("unable to load %s: %s"), path,
+ errstr ? errstr : "unknown error");
+ goto bad;
+ }
+ plugin = sudo_dso_findsym(handle, info->symbol_name);
+ if (!plugin) {
+ sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
+ _PATH_SUDO_CONF, info->lineno, info->symbol_name);
+ sudo_warnx(U_("unable to find symbol \"%s\" in %s"), info->symbol_name, path);
+ goto bad;
+ }
+
+ if (plugin->type != SUDO_POLICY_PLUGIN && plugin->type != SUDO_IO_PLUGIN) {
+ sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
+ _PATH_SUDO_CONF, info->lineno, info->symbol_name);
+ sudo_warnx(U_("unknown policy type %d found in %s"), plugin->type, path);
+ goto bad;
+ }
+ if (SUDO_API_VERSION_GET_MAJOR(plugin->version) != SUDO_API_VERSION_MAJOR) {
+ sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
+ _PATH_SUDO_CONF, info->lineno, info->symbol_name);
+ sudo_warnx(U_("incompatible plugin major version %d (expected %d) found in %s"),
+ SUDO_API_VERSION_GET_MAJOR(plugin->version),
+ SUDO_API_VERSION_MAJOR, path);
+ goto bad;
+ }
+ if (plugin->type == SUDO_POLICY_PLUGIN) {
+ if (policy_plugin->handle != NULL) {
+ /* Ignore duplicate entries. */
+ if (strcmp(policy_plugin->name, info->symbol_name) != 0) {
+ sudo_warnx(U_("ignoring policy plugin \"%s\" in %s, line %d"),
+ info->symbol_name, _PATH_SUDO_CONF, info->lineno);
+ sudo_warnx(U_("only a single policy plugin may be specified"));
+ goto bad;
+ }
+ sudo_warnx(U_("ignoring duplicate policy plugin \"%s\" in %s, line %d"),
+ info->symbol_name, _PATH_SUDO_CONF, info->lineno);
+ goto bad;
+ }
+ policy_plugin->handle = handle;
+ policy_plugin->path = strdup(path);
+ if (policy_plugin->path == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto bad;
+ }
+ policy_plugin->name = info->symbol_name;
+ policy_plugin->options = info->options;
+ policy_plugin->debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
+ policy_plugin->u.generic = plugin;
+ policy_plugin->debug_files = sudo_conf_debug_files(path);
+ } else if (plugin->type == SUDO_IO_PLUGIN) {
+ /* Check for duplicate entries. */
+ TAILQ_FOREACH(container, io_plugins, entries) {
+ if (strcmp(container->name, info->symbol_name) == 0) {
+ sudo_warnx(U_("ignoring duplicate I/O plugin \"%s\" in %s, line %d"),
+ info->symbol_name, _PATH_SUDO_CONF, info->lineno);
+ sudo_dso_unload(handle);
+ handle = NULL;
+ break;
+ }
+ }
+ container = calloc(1, sizeof(*container));
+ if (container == NULL || (container->path = strdup(path)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto bad;
+ }
+ container->handle = handle;
+ container->name = info->symbol_name;
+ container->options = info->options;
+ container->debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
+ container->u.generic = plugin;
+ container->debug_files = sudo_conf_debug_files(path);
+ TAILQ_INSERT_TAIL(io_plugins, container, entries);
+ }
+
+ /* Zero out info strings that we now own (see above). */
+ info->symbol_name = NULL;
+ info->options = NULL;
+
+ debug_return_bool(true);
+bad:
+ free(container);
+ if (handle != NULL)
+ sudo_dso_unload(handle);
+ debug_return_bool(false);
+}
+
+static void
+free_plugin_info(struct plugin_info *info)
+{
+ free(info->path);
+ free(info->symbol_name);
+ if (info->options != NULL) {
+ int i = 0;
+ while (info->options[i] != NULL)
+ free(info->options[i++]);
+ free(info->options);
+ }
+ free(info);
+}
+
+/*
+ * Load the plugins listed in sudo.conf.
+ */
+bool
+sudo_load_plugins(struct plugin_container *policy_plugin,
+ struct plugin_container_list *io_plugins)
+{
+ struct plugin_container *container;
+ struct plugin_info_list *plugins;
+ struct plugin_info *info, *next;
+ bool ret = false;
+ debug_decl(sudo_load_plugins, SUDO_DEBUG_PLUGIN)
+
+ /* Walk the plugin list from sudo.conf, if any and free it. */
+ plugins = sudo_conf_plugins();
+ TAILQ_FOREACH_SAFE(info, plugins, entries, next) {
+ ret = sudo_load_plugin(policy_plugin, io_plugins, info);
+ if (!ret)
+ goto done;
+ free_plugin_info(info);
+ }
+ TAILQ_INIT(plugins);
+
+ /*
+ * If no policy plugin, fall back to the default (sudoers).
+ * If there is also no I/O log plugin, use sudoers for that too.
+ */
+ if (policy_plugin->handle == NULL) {
+ /* Default policy plugin */
+ info = calloc(1, sizeof(*info));
+ if (info == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ info->symbol_name = strdup("sudoers_policy");
+ info->path = strdup(SUDOERS_PLUGIN);
+ if (info->symbol_name == NULL || info->path == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ free_plugin_info(info);
+ goto done;
+ }
+ /* info->options = NULL; */
+ ret = sudo_load_plugin(policy_plugin, io_plugins, info);
+ free_plugin_info(info);
+ if (!ret)
+ goto done;
+
+ /* Default I/O plugin */
+ if (TAILQ_EMPTY(io_plugins)) {
+ info = calloc(1, sizeof(*info));
+ if (info == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
+ }
+ info->symbol_name = strdup("sudoers_io");
+ info->path = strdup(SUDOERS_PLUGIN);
+ if (info->symbol_name == NULL || info->path == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ free_plugin_info(info);
+ goto done;
+ }
+ /* info->options = NULL; */
+ ret = sudo_load_plugin(policy_plugin, io_plugins, info);
+ free_plugin_info(info);
+ if (!ret)
+ goto done;
+ }
+ }
+ if (policy_plugin->u.policy->check_policy == NULL) {
+ sudo_warnx(U_("policy plugin %s does not include a check_policy method"),
+ policy_plugin->name);
+ ret = false;
+ goto done;
+ }
+
+ /* Install hooks (XXX - later). */
+ sudo_debug_set_active_instance(SUDO_DEBUG_INSTANCE_INITIALIZER);
+ if (policy_plugin->u.policy->version >= SUDO_API_MKVERSION(1, 2)) {
+ if (policy_plugin->u.policy->register_hooks != NULL)
+ policy_plugin->u.policy->register_hooks(SUDO_HOOK_VERSION, register_hook);
+ }
+ TAILQ_FOREACH(container, io_plugins, entries) {
+ if (container->u.io->version >= SUDO_API_MKVERSION(1, 2)) {
+ if (container->u.io->register_hooks != NULL)
+ container->u.io->register_hooks(SUDO_HOOK_VERSION, register_hook);
+ }
+ }
+ sudo_debug_set_active_instance(sudo_debug_instance);
+
+done:
+ debug_return_bool(ret);
+}
diff --git a/src/net_ifs.c b/src/net_ifs.c
new file mode 100644
index 0000000..f95cf4d
--- /dev/null
+++ b/src/net_ifs.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2015, 2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+/*
+ * Suppress a warning w/ gcc on Digital UN*X.
+ * The system headers should really do this....
+ */
+#if defined(__osf__) && !defined(__cplusplus)
+struct mbuf;
+struct rtentry;
+#endif
+
+/* Avoid a compilation problem with gcc and machine/sys/getppdp.h */
+#define _MACHINE_SYS_GETPPDP_INCLUDED
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#if defined(HAVE_SYS_SOCKIO_H) && !defined(SIOCGIFCONF)
+# include <sys/sockio.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+#include <unistd.h>
+#include <netdb.h>
+#include <errno.h>
+#ifdef _ISC
+# include <sys/stream.h>
+# include <sys/sioctl.h>
+# include <sys/stropts.h>
+# define STRSET(cmd, param, len) {strioctl.ic_cmd=(cmd);\
+ strioctl.ic_dp=(param);\
+ strioctl.ic_timout=0;\
+ strioctl.ic_len=(len);}
+#endif /* _ISC */
+#ifdef _MIPS
+# include <net/soioctl.h>
+#endif /* _MIPS */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#ifdef NEED_RESOLV_H
+# include <arpa/nameser.h>
+# include <resolv.h>
+#endif /* NEED_RESOLV_H */
+#include <net/if.h>
+#ifdef HAVE_GETIFADDRS
+# include <ifaddrs.h>
+#endif
+
+#define SUDO_NET_IFS_C /* to expose sudo_inet_ntop in sudo_compat.h */
+
+#define DEFAULT_TEXT_DOMAIN "sudo"
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_conf.h"
+#include "sudo_debug.h"
+
+/* Minix apparently lacks IFF_LOOPBACK */
+#ifndef IFF_LOOPBACK
+# define IFF_LOOPBACK 0
+#endif
+
+#ifndef INET_ADDRSTRLEN
+# define INET_ADDRSTRLEN 16
+#endif
+#ifndef INET6_ADDRSTRLEN
+# define INET6_ADDRSTRLEN 46
+#endif
+
+#ifdef HAVE_GETIFADDRS
+
+/*
+ * Fill in the interfaces string with the machine's ip addresses and netmasks
+ * and return the number of interfaces found. Returns -1 on error.
+ */
+int
+get_net_ifs(char **addrinfo)
+{
+ struct ifaddrs *ifa, *ifaddrs;
+ struct sockaddr_in *sin;
+#ifdef HAVE_STRUCT_IN6_ADDR
+ struct sockaddr_in6 *sin6;
+ char addrstr[INET6_ADDRSTRLEN], maskstr[INET6_ADDRSTRLEN];
+#else
+ char addrstr[INET_ADDRSTRLEN], maskstr[INET_ADDRSTRLEN];
+#endif
+ int ailen, len, num_interfaces = 0;
+ char *cp;
+ debug_decl(get_net_ifs, SUDO_DEBUG_NETIF)
+
+ if (!sudo_conf_probe_interfaces())
+ debug_return_int(0);
+
+ if (getifaddrs(&ifaddrs) == -1)
+ debug_return_int(-1);
+
+ /* Allocate space for the interfaces info string. */
+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa -> ifa_next) {
+ /* Skip interfaces marked "down" and "loopback". */
+ if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL ||
+ !ISSET(ifa->ifa_flags, IFF_UP) || ISSET(ifa->ifa_flags, IFF_LOOPBACK))
+ continue;
+
+ switch (ifa->ifa_addr->sa_family) {
+ case AF_INET:
+#ifdef HAVE_STRUCT_IN6_ADDR
+ case AF_INET6:
+#endif
+ num_interfaces++;
+ break;
+ }
+ }
+ if (num_interfaces == 0)
+ debug_return_int(0);
+ ailen = num_interfaces * 2 * INET6_ADDRSTRLEN;
+ if ((cp = malloc(ailen)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_int(-1);
+ }
+ *addrinfo = cp;
+
+ /* Store the IP addr/netmask pairs. */
+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa -> ifa_next) {
+ /* Skip interfaces marked "down" and "loopback". */
+ if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL ||
+ !ISSET(ifa->ifa_flags, IFF_UP) || ISSET(ifa->ifa_flags, IFF_LOOPBACK))
+ continue;
+
+ switch (ifa->ifa_addr->sa_family) {
+ case AF_INET:
+ sin = (struct sockaddr_in *)ifa->ifa_addr;
+ if (inet_ntop(AF_INET, &sin->sin_addr, addrstr, sizeof(addrstr)) == NULL)
+ continue;
+ sin = (struct sockaddr_in *)ifa->ifa_netmask;
+ if (inet_ntop(AF_INET, &sin->sin_addr, maskstr, sizeof(maskstr)) == NULL)
+ continue;
+
+ len = snprintf(cp, ailen - (*addrinfo - cp),
+ "%s%s/%s", cp == *addrinfo ? "" : " ", addrstr, maskstr);
+ if (len <= 0 || len >= ailen - (*addrinfo - cp)) {
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ goto done;
+ }
+ cp += len;
+ break;
+#ifdef HAVE_STRUCT_IN6_ADDR
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
+ if (inet_ntop(AF_INET6, &sin6->sin6_addr, addrstr, sizeof(addrstr)) == NULL)
+ continue;
+ sin6 = (struct sockaddr_in6 *)ifa->ifa_netmask;
+ if (inet_ntop(AF_INET6, &sin6->sin6_addr, maskstr, sizeof(maskstr)) == NULL)
+ continue;
+
+ len = snprintf(cp, ailen - (*addrinfo - cp),
+ "%s%s/%s", cp == *addrinfo ? "" : " ", addrstr, maskstr);
+ if (len <= 0 || len >= ailen - (*addrinfo - cp)) {
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ goto done;
+ }
+ cp += len;
+ break;
+#endif /* HAVE_STRUCT_IN6_ADDR */
+ }
+ }
+
+done:
+#ifdef HAVE_FREEIFADDRS
+ freeifaddrs(ifaddrs);
+#else
+ free(ifaddrs);
+#endif
+ debug_return_int(num_interfaces);
+}
+
+#elif defined(SIOCGIFCONF) && !defined(STUB_LOAD_INTERFACES)
+
+/*
+ * Fill in the interfaces string with the machine's ip addresses and netmasks
+ * and return the number of interfaces found. Returns -1 on error.
+ */
+int
+get_net_ifs(char **addrinfo)
+{
+ char ifr_tmpbuf[sizeof(struct ifreq)];
+ struct ifreq *ifr, *ifr_tmp = (struct ifreq *)ifr_tmpbuf;
+ struct ifconf *ifconf;
+ struct sockaddr_in *sin;
+ int ailen, i, len, n, sock, num_interfaces = 0;
+ size_t buflen = sizeof(struct ifconf) + BUFSIZ;
+ char *cp, *previfname = "", *ifconf_buf = NULL;
+ char addrstr[INET_ADDRSTRLEN], maskstr[INET_ADDRSTRLEN];
+#ifdef _ISC
+ struct strioctl strioctl;
+#endif /* _ISC */
+ debug_decl(get_net_ifs, SUDO_DEBUG_NETIF)
+
+ if (!sudo_conf_probe_interfaces())
+ debug_return_int(0);
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock < 0)
+ debug_return_int(-1);
+
+ /*
+ * Get interface configuration or return.
+ */
+ for (;;) {
+ if ((ifconf_buf = malloc(buflen)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ num_interfaces = -1;
+ goto done;
+ }
+ ifconf = (struct ifconf *) ifconf_buf;
+ ifconf->ifc_len = buflen - sizeof(struct ifconf);
+ ifconf->ifc_buf = (caddr_t) (ifconf_buf + sizeof(struct ifconf));
+
+#ifdef _ISC
+ STRSET(SIOCGIFCONF, (caddr_t) ifconf, buflen);
+ if (ioctl(sock, I_STR, (caddr_t) &strioctl) < 0)
+#else
+ /* Note that some kernels return EINVAL if the buffer is too small */
+ if (ioctl(sock, SIOCGIFCONF, (caddr_t) ifconf) < 0 && errno != EINVAL)
+#endif /* _ISC */
+ goto done;
+
+ /* Break out of loop if we have a big enough buffer. */
+ if (ifconf->ifc_len + sizeof(struct ifreq) < buflen)
+ break;
+ buflen += BUFSIZ;
+ free(ifconf_buf);
+ }
+
+ /* Allocate space for the maximum number of interfaces that could exist. */
+ if ((n = ifconf->ifc_len / sizeof(struct ifreq)) == 0)
+ goto done;
+ ailen = n * 2 * INET6_ADDRSTRLEN;
+ if ((cp = malloc(ailen)) == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ num_interfaces = -1;
+ goto done;
+ }
+ *addrinfo = cp;
+
+ /* For each interface, store the ip address and netmask. */
+ for (i = 0; i < ifconf->ifc_len; ) {
+ /* Get a pointer to the current interface. */
+ ifr = (struct ifreq *) &ifconf->ifc_buf[i];
+
+ /* Set i to the subscript of the next interface. */
+ i += sizeof(struct ifreq);
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr))
+ i += ifr->ifr_addr.sa_len - sizeof(struct sockaddr);
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
+
+ /* Skip duplicates and interfaces with NULL addresses. */
+ sin = (struct sockaddr_in *) &ifr->ifr_addr;
+ if (sin->sin_addr.s_addr == 0 ||
+ strncmp(previfname, ifr->ifr_name, sizeof(ifr->ifr_name) - 1) == 0)
+ continue;
+
+ if (ifr->ifr_addr.sa_family != AF_INET)
+ continue;
+
+#ifdef SIOCGIFFLAGS
+ memset(ifr_tmp, 0, sizeof(*ifr_tmp));
+ strncpy(ifr_tmp->ifr_name, ifr->ifr_name, sizeof(ifr_tmp->ifr_name) - 1);
+ if (ioctl(sock, SIOCGIFFLAGS, (caddr_t) ifr_tmp) < 0)
+#endif
+ memcpy(ifr_tmp, ifr, sizeof(*ifr_tmp));
+
+ /* Skip interfaces marked "down" and "loopback". */
+ if (!ISSET(ifr_tmp->ifr_flags, IFF_UP) ||
+ ISSET(ifr_tmp->ifr_flags, IFF_LOOPBACK))
+ continue;
+
+ /* Get the netmask. */
+ memset(ifr_tmp, 0, sizeof(*ifr_tmp));
+ strncpy(ifr_tmp->ifr_name, ifr->ifr_name, sizeof(ifr_tmp->ifr_name) - 1);
+ sin = (struct sockaddr_in *) &ifr_tmp->ifr_addr;
+#ifdef _ISC
+ STRSET(SIOCGIFNETMASK, (caddr_t) ifr_tmp, sizeof(*ifr_tmp));
+ if (ioctl(sock, I_STR, (caddr_t) &strioctl) < 0)
+#else
+ if (ioctl(sock, SIOCGIFNETMASK, (caddr_t) ifr_tmp) < 0)
+#endif /* _ISC */
+ sin->sin_addr.s_addr = htonl(IN_CLASSC_NET);
+
+ /* Convert the addr and mask to string form. */
+ sin = (struct sockaddr_in *) &ifr->ifr_addr;
+ if (inet_ntop(AF_INET, &sin->sin_addr, addrstr, sizeof(addrstr)) == NULL)
+ continue;
+ sin = (struct sockaddr_in *) &ifr_tmp->ifr_addr;
+ if (inet_ntop(AF_INET, &sin->sin_addr, maskstr, sizeof(maskstr)) == NULL)
+ continue;
+
+ len = snprintf(cp, ailen - (*addrinfo - cp),
+ "%s%s/%s", cp == *addrinfo ? "" : " ", addrstr, maskstr);
+ if (len <= 0 || len >= ailen - (*addrinfo - cp)) {
+ sudo_warnx(U_("internal error, %s overflow"), __func__);
+ goto done;
+ }
+ cp += len;
+
+ /* Stash the name of the interface we saved. */
+ previfname = ifr->ifr_name;
+ num_interfaces++;
+ }
+
+done:
+ free(ifconf_buf);
+ (void) close(sock);
+
+ debug_return_int(num_interfaces);
+}
+
+#else /* !SIOCGIFCONF || STUB_LOAD_INTERFACES */
+
+/*
+ * Stub function for those without SIOCGIFCONF or getifaddrs()
+ */
+int
+get_net_ifs(char **addrinfo)
+{
+ debug_decl(get_net_ifs, SUDO_DEBUG_NETIF)
+ debug_return_int(0);
+}
+
+#endif /* SIOCGIFCONF && !STUB_LOAD_INTERFACES */
diff --git a/src/openbsd.c b/src/openbsd.c
new file mode 100644
index 0000000..fd0e2f3
--- /dev/null
+++ b/src/openbsd.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+
+#include "sudo.h"
+
+int
+os_init(int argc, char *argv[], char *envp[])
+{
+#ifdef SUDO_DEVEL
+ extern char *malloc_options;
+ malloc_options = "S";
+#endif
+ return os_init_common(argc, argv, envp);
+}
diff --git a/src/parse_args.c b/src/parse_args.c
new file mode 100644
index 0000000..d9bbe06
--- /dev/null
+++ b/src/parse_args.c
@@ -0,0 +1,774 @@
+/*
+ * Copyright (c) 1993-1996, 1998-2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <ctype.h>
+#include <grp.h>
+#include <pwd.h>
+
+#include <sudo_usage.h>
+#include "sudo.h"
+#include "sudo_lbuf.h"
+
+#ifdef HAVE_GETOPT_LONG
+# include <getopt.h>
+# else
+# include "compat/getopt.h"
+#endif /* HAVE_GETOPT_LONG */
+
+int tgetpass_flags;
+
+/*
+ * Local functions.
+ */
+static void help(void) __attribute__((__noreturn__));
+static void usage_excl(int);
+
+/*
+ * Mapping of command line flags to name/value settings.
+ */
+static struct sudo_settings sudo_settings[] = {
+#define ARG_BSDAUTH_TYPE 0
+ { "bsdauth_type" },
+#define ARG_LOGIN_CLASS 1
+ { "login_class" },
+#define ARG_PRESERVE_ENVIRONMENT 2
+ { "preserve_environment" },
+#define ARG_RUNAS_GROUP 3
+ { "runas_group" },
+#define ARG_SET_HOME 4
+ { "set_home" },
+#define ARG_USER_SHELL 5
+ { "run_shell" },
+#define ARG_LOGIN_SHELL 6
+ { "login_shell" },
+#define ARG_IGNORE_TICKET 7
+ { "ignore_ticket" },
+#define ARG_PROMPT 8
+ { "prompt" },
+#define ARG_SELINUX_ROLE 9
+ { "selinux_role" },
+#define ARG_SELINUX_TYPE 10
+ { "selinux_type" },
+#define ARG_RUNAS_USER 11
+ { "runas_user" },
+#define ARG_PROGNAME 12
+ { "progname" },
+#define ARG_IMPLIED_SHELL 13
+ { "implied_shell" },
+#define ARG_PRESERVE_GROUPS 14
+ { "preserve_groups" },
+#define ARG_NONINTERACTIVE 15
+ { "noninteractive" },
+#define ARG_SUDOEDIT 16
+ { "sudoedit" },
+#define ARG_CLOSEFROM 17
+ { "closefrom" },
+#define ARG_NET_ADDRS 18
+ { "network_addrs" },
+#define ARG_MAX_GROUPS 19
+ { "max_groups" },
+#define ARG_PLUGIN_DIR 20
+ { "plugin_dir" },
+#define ARG_REMOTE_HOST 21
+ { "remote_host" },
+#define ARG_TIMEOUT 22
+ { "timeout" },
+#define NUM_SETTINGS 23
+ { NULL }
+};
+
+struct environment {
+ char **envp; /* pointer to the new environment */
+ size_t env_size; /* size of new_environ in char **'s */
+ size_t env_len; /* number of slots used, not counting NULL */
+};
+
+/*
+ * Default flags allowed when running a command.
+ */
+#define DEFAULT_VALID_FLAGS (MODE_BACKGROUND|MODE_PRESERVE_ENV|MODE_RESET_HOME|MODE_LOGIN_SHELL|MODE_NONINTERACTIVE|MODE_SHELL)
+
+/* Option number for the --host long option due to ambiguity of the -h flag. */
+#define OPT_HOSTNAME 256
+
+/*
+ * Available command line options, both short and long.
+ * Note that we must disable arg permutation to support setting environment
+ * variables and to better support the optional arg of the -h flag.
+ */
+static const char short_opts[] = "+Aa:bC:c:D:Eeg:Hh::iKklnPp:r:SsT:t:U:u:Vv";
+static struct option long_opts[] = {
+ { "askpass", no_argument, NULL, 'A' },
+ { "auth-type", required_argument, NULL, 'a' },
+ { "background", no_argument, NULL, 'b' },
+ { "close-from", required_argument, NULL, 'C' },
+ { "login-class", required_argument, NULL, 'c' },
+ { "preserve-env", optional_argument, NULL, 'E' },
+ { "edit", no_argument, NULL, 'e' },
+ { "group", required_argument, NULL, 'g' },
+ { "set-home", no_argument, NULL, 'H' },
+ { "help", no_argument, NULL, 'h' },
+ { "host", required_argument, NULL, OPT_HOSTNAME },
+ { "login", no_argument, NULL, 'i' },
+ { "remove-timestamp", no_argument, NULL, 'K' },
+ { "reset-timestamp", no_argument, NULL, 'k' },
+ { "list", no_argument, NULL, 'l' },
+ { "non-interactive", no_argument, NULL, 'n' },
+ { "preserve-groups", no_argument, NULL, 'P' },
+ { "prompt", required_argument, NULL, 'p' },
+ { "role", required_argument, NULL, 'r' },
+ { "stdin", no_argument, NULL, 'S' },
+ { "shell", no_argument, NULL, 's' },
+ { "type", required_argument, NULL, 't' },
+ { "command-timeout",required_argument, NULL, 'T' },
+ { "other-user", required_argument, NULL, 'U' },
+ { "user", required_argument, NULL, 'u' },
+ { "version", no_argument, NULL, 'V' },
+ { "validate", no_argument, NULL, 'v' },
+ { NULL, no_argument, NULL, '\0' },
+};
+
+/*
+ * Insert a key=value pair into the specified environment.
+ */
+static void
+env_insert(struct environment *e, char *pair)
+{
+ debug_decl(env_insert, SUDO_DEBUG_ARGS)
+
+ /* Make sure we have at least two slots free (one for NULL). */
+ if (e->env_len + 1 >= e->env_size) {
+ char **tmp;
+
+ if (e->env_size == 0)
+ e->env_size = 16;
+ tmp = reallocarray(e->envp, e->env_size, 2 * sizeof(char *));
+ if (tmp == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ e->envp = tmp;
+ e->env_size *= 2;
+ }
+ e->envp[e->env_len++] = pair;
+ e->envp[e->env_len] = NULL;
+
+ debug_return;
+}
+
+/*
+ * Format as var=val and insert into the specified environment.
+ */
+static void
+env_set(struct environment *e, char *var, char *val)
+{
+ char *pair;
+ debug_decl(env_set, SUDO_DEBUG_ARGS)
+
+ pair = sudo_new_key_val(var, val);
+ if (pair == NULL) {
+ sudo_fatalx(U_("%s: %s"),
+ __func__, U_("unable to allocate memory"));
+ }
+ env_insert(e, pair);
+
+ debug_return;
+}
+
+/*
+ * Parse a comma-separated list of env vars and add to the
+ * specified environment.
+ */
+static void
+parse_env_list(struct environment *e, char *list)
+{
+ char *cp, *last, *val;
+ debug_decl(parse_env_list, SUDO_DEBUG_ARGS)
+
+ for ((cp = strtok_r(list, ",", &last)); cp != NULL;
+ (cp = strtok_r(NULL, ",", &last))) {
+ if (strchr(cp, '=') != NULL) {
+ sudo_warnx(U_("invalid environment variable name: %s"), cp);
+ usage(1);
+ }
+ if ((val = getenv(cp)) != NULL)
+ env_set(e, cp, val);
+ }
+ debug_return;
+}
+
+/*
+ * Command line argument parsing.
+ * Sets nargc and nargv which corresponds to the argc/argv we'll use
+ * for the command to be run (if we are running one).
+ */
+int
+parse_args(int argc, char **argv, int *nargc, char ***nargv,
+ struct sudo_settings **settingsp, char ***env_addp)
+{
+ struct environment extra_env;
+ int mode = 0; /* what mode is sudo to be run in? */
+ int flags = 0; /* mode flags */
+ int valid_flags = DEFAULT_VALID_FLAGS;
+ int ch, i;
+ char *cp;
+ const char *runas_user = NULL;
+ const char *runas_group = NULL;
+ const char *progname;
+ int proglen;
+ debug_decl(parse_args, SUDO_DEBUG_ARGS)
+
+ /* Is someone trying something funny? */
+ if (argc <= 0)
+ usage(1);
+
+ /* Pass progname to plugin so it can call initprogname() */
+ progname = getprogname();
+ sudo_settings[ARG_PROGNAME].value = progname;
+
+ /* First, check to see if we were invoked as "sudoedit". */
+ proglen = strlen(progname);
+ if (proglen > 4 && strcmp(progname + proglen - 4, "edit") == 0) {
+ progname = "sudoedit";
+ mode = MODE_EDIT;
+ sudo_settings[ARG_SUDOEDIT].value = "true";
+ }
+
+ /* Load local IP addresses and masks. */
+ if (get_net_ifs(&cp) > 0)
+ sudo_settings[ARG_NET_ADDRS].value = cp;
+
+ /* Set max_groups from sudo.conf. */
+ i = sudo_conf_max_groups();
+ if (i != -1) {
+ if (asprintf(&cp, "%d", i) == -1)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ sudo_settings[ARG_MAX_GROUPS].value = cp;
+ }
+
+ /* Returns true if the last option string was "-h" */
+#define got_host_flag (optind > 1 && argv[optind - 1][0] == '-' && \
+ argv[optind - 1][1] == 'h' && argv[optind - 1][2] == '\0')
+
+ /* Returns true if the last option string was "--" */
+#define got_end_of_args (optind > 1 && argv[optind - 1][0] == '-' && \
+ argv[optind - 1][1] == '-' && argv[optind - 1][2] == '\0')
+
+ /* Returns true if next option is an environment variable */
+#define is_envar (optind < argc && argv[optind][0] != '/' && \
+ strchr(argv[optind], '=') != NULL)
+
+ /* Space for environment variables is lazy allocated. */
+ memset(&extra_env, 0, sizeof(extra_env));
+
+ /* XXX - should fill in settings at the end to avoid dupes */
+ for (;;) {
+ /*
+ * Some trickiness is required to allow environment variables
+ * to be interspersed with command line options.
+ */
+ if ((ch = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
+ switch (ch) {
+ case 'A':
+ SET(tgetpass_flags, TGP_ASKPASS);
+ break;
+#ifdef HAVE_BSD_AUTH_H
+ case 'a':
+ if (*optarg == '\0')
+ usage(1);
+ sudo_settings[ARG_BSDAUTH_TYPE].value = optarg;
+ break;
+#endif
+ case 'b':
+ SET(flags, MODE_BACKGROUND);
+ break;
+ case 'C':
+ if (strtonum(optarg, 3, INT_MAX, NULL) == 0) {
+ sudo_warnx(U_("the argument to -C must be a number greater than or equal to 3"));
+ usage(1);
+ }
+ sudo_settings[ARG_CLOSEFROM].value = optarg;
+ break;
+#ifdef HAVE_LOGIN_CAP_H
+ case 'c':
+ if (*optarg == '\0')
+ usage(1);
+ sudo_settings[ARG_LOGIN_CLASS].value = optarg;
+ break;
+#endif
+ case 'D':
+ /* Ignored for backwards compatibility. */
+ break;
+ case 'E':
+ /*
+ * Optional argument is a comma-separated list of
+ * environment variables to preserve.
+ * If not present, preserve everything.
+ */
+ if (optarg == NULL) {
+ sudo_settings[ARG_PRESERVE_ENVIRONMENT].value = "true";
+ SET(flags, MODE_PRESERVE_ENV);
+ } else {
+ parse_env_list(&extra_env, optarg);
+ }
+ break;
+ case 'e':
+ if (mode && mode != MODE_EDIT)
+ usage_excl(1);
+ mode = MODE_EDIT;
+ sudo_settings[ARG_SUDOEDIT].value = "true";
+ valid_flags = MODE_NONINTERACTIVE;
+ break;
+ case 'g':
+ if (*optarg == '\0')
+ usage(1);
+ runas_group = optarg;
+ sudo_settings[ARG_RUNAS_GROUP].value = optarg;
+ break;
+ case 'H':
+ sudo_settings[ARG_SET_HOME].value = "true";
+ break;
+ case 'h':
+ if (optarg == NULL) {
+ /*
+ * Optional args support -hhostname, not -h hostname.
+ * If we see a non-option after the -h flag, treat as
+ * remote host and bump optind to skip over it.
+ */
+ if (got_host_flag && !is_envar &&
+ argv[optind] != NULL && argv[optind][0] != '-') {
+ sudo_settings[ARG_REMOTE_HOST].value = argv[optind++];
+ continue;
+ }
+ if (mode && mode != MODE_HELP) {
+ if (strcmp(progname, "sudoedit") != 0)
+ usage_excl(1);
+ }
+ mode = MODE_HELP;
+ valid_flags = 0;
+ break;
+ }
+ /* FALLTHROUGH */
+ case OPT_HOSTNAME:
+ if (*optarg == '\0')
+ usage(1);
+ sudo_settings[ARG_REMOTE_HOST].value = optarg;
+ break;
+ case 'i':
+ sudo_settings[ARG_LOGIN_SHELL].value = "true";
+ SET(flags, MODE_LOGIN_SHELL);
+ break;
+ case 'k':
+ sudo_settings[ARG_IGNORE_TICKET].value = "true";
+ break;
+ case 'K':
+ sudo_settings[ARG_IGNORE_TICKET].value = "true";
+ if (mode && mode != MODE_KILL)
+ usage_excl(1);
+ mode = MODE_KILL;
+ valid_flags = 0;
+ break;
+ case 'l':
+ if (mode) {
+ if (mode == MODE_LIST)
+ SET(flags, MODE_LONG_LIST);
+ else
+ usage_excl(1);
+ }
+ mode = MODE_LIST;
+ valid_flags = MODE_NONINTERACTIVE|MODE_LONG_LIST;
+ break;
+ case 'n':
+ SET(flags, MODE_NONINTERACTIVE);
+ sudo_settings[ARG_NONINTERACTIVE].value = "true";
+ break;
+ case 'P':
+ sudo_settings[ARG_PRESERVE_GROUPS].value = "true";
+ break;
+ case 'p':
+ /* An empty prompt is allowed. */
+ sudo_settings[ARG_PROMPT].value = optarg;
+ break;
+#ifdef HAVE_SELINUX
+ case 'r':
+ if (*optarg == '\0')
+ usage(1);
+ sudo_settings[ARG_SELINUX_ROLE].value = optarg;
+ break;
+ case 't':
+ if (*optarg == '\0')
+ usage(1);
+ sudo_settings[ARG_SELINUX_TYPE].value = optarg;
+ break;
+#endif
+ case 'T':
+ /* Plugin determines whether empty timeout is allowed. */
+ sudo_settings[ARG_TIMEOUT].value = optarg;
+ break;
+ case 'S':
+ SET(tgetpass_flags, TGP_STDIN);
+ break;
+ case 's':
+ sudo_settings[ARG_USER_SHELL].value = "true";
+ SET(flags, MODE_SHELL);
+ break;
+ case 'U':
+ if (*optarg == '\0')
+ usage(1);
+ list_user = optarg;
+ break;
+ case 'u':
+ if (*optarg == '\0')
+ usage(1);
+ runas_user = optarg;
+ sudo_settings[ARG_RUNAS_USER].value = optarg;
+ break;
+ case 'v':
+ if (mode && mode != MODE_VALIDATE)
+ usage_excl(1);
+ mode = MODE_VALIDATE;
+ valid_flags = MODE_NONINTERACTIVE;
+ break;
+ case 'V':
+ if (mode && mode != MODE_VERSION)
+ usage_excl(1);
+ mode = MODE_VERSION;
+ valid_flags = 0;
+ break;
+ default:
+ usage(1);
+ }
+ } else if (!got_end_of_args && is_envar) {
+ /* Insert key=value pair, crank optind and resume getopt. */
+ env_insert(&extra_env, argv[optind]);
+ optind++;
+ } else {
+ /* Not an option or an environment variable -- we're done. */
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (!mode) {
+ /* Defer -k mode setting until we know whether it is a flag or not */
+ if (sudo_settings[ARG_IGNORE_TICKET].value != NULL) {
+ if (argc == 0 && !(flags & (MODE_SHELL|MODE_LOGIN_SHELL))) {
+ mode = MODE_INVALIDATE; /* -k by itself */
+ sudo_settings[ARG_IGNORE_TICKET].value = NULL;
+ valid_flags = 0;
+ }
+ }
+ if (!mode)
+ mode = MODE_RUN; /* running a command */
+ }
+
+ if (argc > 0 && mode == MODE_LIST)
+ mode = MODE_CHECK;
+
+ if (ISSET(flags, MODE_LOGIN_SHELL)) {
+ if (ISSET(flags, MODE_SHELL)) {
+ sudo_warnx(U_("you may not specify both the `-i' and `-s' options"));
+ usage(1);
+ }
+ if (ISSET(flags, MODE_PRESERVE_ENV)) {
+ sudo_warnx(U_("you may not specify both the `-i' and `-E' options"));
+ usage(1);
+ }
+ SET(flags, MODE_SHELL);
+ }
+ if ((flags & valid_flags) != flags)
+ usage(1);
+ if (mode == MODE_EDIT &&
+ (ISSET(flags, MODE_PRESERVE_ENV) || extra_env.env_len != 0)) {
+ if (ISSET(mode, MODE_PRESERVE_ENV))
+ sudo_warnx(U_("the `-E' option is not valid in edit mode"));
+ if (extra_env.env_len != 0)
+ sudo_warnx(U_("you may not specify environment variables in edit mode"));
+ usage(1);
+ }
+ if ((runas_user != NULL || runas_group != NULL) &&
+ !ISSET(mode, MODE_EDIT | MODE_RUN | MODE_CHECK | MODE_VALIDATE)) {
+ usage(1);
+ }
+ if (list_user != NULL && mode != MODE_LIST && mode != MODE_CHECK) {
+ sudo_warnx(U_("the `-U' option may only be used with the `-l' option"));
+ usage(1);
+ }
+ if (ISSET(tgetpass_flags, TGP_STDIN) && ISSET(tgetpass_flags, TGP_ASKPASS)) {
+ sudo_warnx(U_("the `-A' and `-S' options may not be used together"));
+ usage(1);
+ }
+ if ((argc == 0 && mode == MODE_EDIT) ||
+ (argc > 0 && !ISSET(mode, MODE_RUN | MODE_EDIT | MODE_CHECK)))
+ usage(1);
+ if (argc == 0 && mode == MODE_RUN && !ISSET(flags, MODE_SHELL)) {
+ SET(flags, (MODE_IMPLIED_SHELL | MODE_SHELL));
+ sudo_settings[ARG_IMPLIED_SHELL].value = "true";
+ }
+#ifdef ENABLE_SUDO_PLUGIN_API
+ sudo_settings[ARG_PLUGIN_DIR].value = sudo_conf_plugin_dir_path();
+#endif
+
+ if (mode == MODE_HELP)
+ help();
+
+ /*
+ * For shell mode we need to rewrite argv
+ */
+ if (ISSET(mode, MODE_RUN) && ISSET(flags, MODE_SHELL)) {
+ char **av, *cmnd = NULL;
+ int ac = 1;
+
+ if (argc != 0) {
+ /* shell -c "command" */
+ char *src, *dst;
+ size_t cmnd_size = (size_t) (argv[argc - 1] - argv[0]) +
+ strlen(argv[argc - 1]) + 1;
+
+ cmnd = dst = reallocarray(NULL, cmnd_size, 2);
+ if (cmnd == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (!gc_add(GC_PTR, cmnd))
+ exit(1);
+
+ for (av = argv; *av != NULL; av++) {
+ for (src = *av; *src != '\0'; src++) {
+ /* quote potential meta characters */
+ if (!isalnum((unsigned char)*src) && *src != '_' && *src != '-' && *src != '$')
+ *dst++ = '\\';
+ *dst++ = *src;
+ }
+ *dst++ = ' ';
+ }
+ if (cmnd != dst)
+ dst--; /* replace last space with a NUL */
+ *dst = '\0';
+
+ ac += 2; /* -c cmnd */
+ }
+
+ av = reallocarray(NULL, ac + 1, sizeof(char *));
+ if (av == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ if (!gc_add(GC_PTR, av))
+ exit(1);
+
+ av[0] = (char *)user_details.shell; /* plugin may override shell */
+ if (cmnd != NULL) {
+ av[1] = "-c";
+ av[2] = cmnd;
+ }
+ av[ac] = NULL;
+
+ argv = av;
+ argc = ac;
+ }
+
+ if (mode == MODE_EDIT) {
+#if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
+ /* Must have the command in argv[0]. */
+ argc++;
+ argv--;
+ argv[0] = "sudoedit";
+#else
+ sudo_fatalx(U_("sudoedit is not supported on this platform"));
+#endif
+ }
+
+ *settingsp = sudo_settings;
+ *env_addp = extra_env.envp;
+ *nargc = argc;
+ *nargv = argv;
+ debug_return_int(mode | flags);
+}
+
+static int
+usage_err(const char *buf)
+{
+ return fputs(buf, stderr);
+}
+
+static int
+usage_out(const char *buf)
+{
+ return fputs(buf, stdout);
+}
+
+/*
+ * Give usage message and exit.
+ * The actual usage strings are in sudo_usage.h for configure substitution.
+ */
+void
+usage(int fatal)
+{
+ struct sudo_lbuf lbuf;
+ char *uvec[6];
+ int i, ulen;
+
+ /*
+ * Use usage vectors appropriate to the progname.
+ */
+ if (strcmp(getprogname(), "sudoedit") == 0) {
+ uvec[0] = SUDO_USAGE5 + 3;
+ uvec[1] = NULL;
+ } else {
+ uvec[0] = SUDO_USAGE1;
+ uvec[1] = SUDO_USAGE2;
+ uvec[2] = SUDO_USAGE3;
+ uvec[3] = SUDO_USAGE4;
+ uvec[4] = SUDO_USAGE5;
+ uvec[5] = NULL;
+ }
+
+ /*
+ * Print usage and wrap lines as needed, depending on the
+ * tty width.
+ */
+ ulen = (int)strlen(getprogname()) + 8;
+ sudo_lbuf_init(&lbuf, fatal ? usage_err : usage_out, ulen, NULL,
+ user_details.ts_cols);
+ for (i = 0; uvec[i] != NULL; i++) {
+ sudo_lbuf_append(&lbuf, "usage: %s%s", getprogname(), uvec[i]);
+ sudo_lbuf_print(&lbuf);
+ }
+ sudo_lbuf_destroy(&lbuf);
+ if (fatal)
+ exit(1);
+}
+
+/*
+ * Tell which options are mutually exclusive and exit.
+ */
+static void
+usage_excl(int fatal)
+{
+ debug_decl(usage_excl, SUDO_DEBUG_ARGS)
+
+ sudo_warnx(U_("Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"));
+ usage(fatal);
+}
+
+static void
+help(void)
+{
+ struct sudo_lbuf lbuf;
+ const int indent = 32;
+ const char *pname = getprogname();
+ debug_decl(help, SUDO_DEBUG_ARGS)
+
+ sudo_lbuf_init(&lbuf, usage_out, indent, NULL, user_details.ts_cols);
+ if (strcmp(pname, "sudoedit") == 0)
+ sudo_lbuf_append(&lbuf, _("%s - edit files as another user\n\n"), pname);
+ else
+ sudo_lbuf_append(&lbuf, _("%s - execute a command as another user\n\n"), pname);
+ sudo_lbuf_print(&lbuf);
+
+ usage(0);
+
+ sudo_lbuf_append(&lbuf, _("\nOptions:\n"));
+ sudo_lbuf_append(&lbuf, " -A, --askpass %s\n",
+ _("use a helper program for password prompting"));
+#ifdef HAVE_BSD_AUTH_H
+ sudo_lbuf_append(&lbuf, " -a, --auth-type=type %s\n",
+ _("use specified BSD authentication type"));
+#endif
+ sudo_lbuf_append(&lbuf, " -b, --background %s\n",
+ _("run command in the background"));
+ sudo_lbuf_append(&lbuf, " -C, --close-from=num %s\n",
+ _("close all file descriptors >= num"));
+#ifdef HAVE_LOGIN_CAP_H
+ sudo_lbuf_append(&lbuf, " -c, --login-class=class %s\n",
+ _("run command with the specified BSD login class"));
+#endif
+ sudo_lbuf_append(&lbuf, " -E, --preserve-env %s\n",
+ _("preserve user environment when running command"));
+ sudo_lbuf_append(&lbuf, " --preserve-env=list %s\n",
+ _("preserve specific environment variables"));
+ sudo_lbuf_append(&lbuf, " -e, --edit %s\n",
+ _("edit files instead of running a command"));
+ sudo_lbuf_append(&lbuf, " -g, --group=group %s\n",
+ _("run command as the specified group name or ID"));
+ sudo_lbuf_append(&lbuf, " -H, --set-home %s\n",
+ _("set HOME variable to target user's home dir"));
+ sudo_lbuf_append(&lbuf, " -h, --help %s\n",
+ _("display help message and exit"));
+ sudo_lbuf_append(&lbuf, " -h, --host=host %s\n",
+ _("run command on host (if supported by plugin)"));
+ sudo_lbuf_append(&lbuf, " -i, --login %s\n",
+ _("run login shell as the target user; a command may also be specified"));
+ sudo_lbuf_append(&lbuf, " -K, --remove-timestamp %s\n",
+ _("remove timestamp file completely"));
+ sudo_lbuf_append(&lbuf, " -k, --reset-timestamp %s\n",
+ _("invalidate timestamp file"));
+ sudo_lbuf_append(&lbuf, " -l, --list %s\n",
+ _("list user's privileges or check a specific command; use twice for longer format"));
+ sudo_lbuf_append(&lbuf, " -n, --non-interactive %s\n",
+ _("non-interactive mode, no prompts are used"));
+ sudo_lbuf_append(&lbuf, " -P, --preserve-groups %s\n",
+ _("preserve group vector instead of setting to target's"));
+ sudo_lbuf_append(&lbuf, " -p, --prompt=prompt %s\n",
+ _("use the specified password prompt"));
+#ifdef HAVE_SELINUX
+ sudo_lbuf_append(&lbuf, " -r, --role=role %s\n",
+ _("create SELinux security context with specified role"));
+#endif
+ sudo_lbuf_append(&lbuf, " -S, --stdin %s\n",
+ _("read password from standard input"));
+ sudo_lbuf_append(&lbuf, " -s, --shell %s\n",
+ _("run shell as the target user; a command may also be specified"));
+#ifdef HAVE_SELINUX
+ sudo_lbuf_append(&lbuf, " -t, --type=type %s\n",
+ _("create SELinux security context with specified type"));
+#endif
+ sudo_lbuf_append(&lbuf, " -T, --command-timeout=timeout %s\n",
+ _("terminate command after the specified time limit"));
+ sudo_lbuf_append(&lbuf, " -U, --other-user=user %s\n",
+ _("in list mode, display privileges for user"));
+ sudo_lbuf_append(&lbuf, " -u, --user=user %s\n",
+ _("run command (or edit file) as specified user name or ID"));
+ sudo_lbuf_append(&lbuf, " -V, --version %s\n",
+ _("display version information and exit"));
+ sudo_lbuf_append(&lbuf, " -v, --validate %s\n",
+ _("update user's timestamp without running a command"));
+ sudo_lbuf_append(&lbuf, " -- %s\n",
+ _("stop processing command line arguments"));
+ sudo_lbuf_print(&lbuf);
+ sudo_lbuf_destroy(&lbuf);
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, 0);
+ exit(0);
+}
diff --git a/src/preload.c b/src/preload.c
new file mode 100644
index 0000000..e9f83ee
--- /dev/null
+++ b/src/preload.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2010, 2011, 2013 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#ifdef HAVE_GSS_KRB5_CCACHE_NAME
+# if defined(HAVE_GSSAPI_GSSAPI_KRB5_H)
+# include <gssapi/gssapi.h>
+# include <gssapi/gssapi_krb5.h>
+# elif defined(HAVE_GSSAPI_GSSAPI_H)
+# include <gssapi/gssapi.h>
+# else
+# include <gssapi.h>
+# endif
+#endif
+
+#include "sudo_plugin.h"
+#include "sudo_compat.h"
+#include "sudo_dso.h"
+
+#ifdef STATIC_SUDOERS_PLUGIN
+
+extern struct policy_plugin sudoers_policy;
+extern struct io_plugin sudoers_io;
+
+static struct sudo_preload_symbol sudo_rtld_default_symbols[] = {
+# ifdef HAVE_GSS_KRB5_CCACHE_NAME
+ { "gss_krb5_ccache_name", (void *)&gss_krb5_ccache_name},
+# endif
+ { (const char *)0, (void *)0 }
+};
+
+/* XXX - can we autogenerate these? */
+static struct sudo_preload_symbol sudo_sudoers_plugin_symbols[] = {
+ { "sudoers_policy", (void *)&sudoers_policy},
+ { "sudoers_io", (void *)&sudoers_io},
+ { (const char *)0, (void *)0 }
+};
+
+/*
+ * Statically compiled symbols indexed by handle.
+ */
+static struct sudo_preload_table sudo_preload_table[] = {
+ { (char *)0, SUDO_DSO_DEFAULT, sudo_rtld_default_symbols },
+ { "sudoers.so", &sudo_sudoers_plugin_symbols, sudo_sudoers_plugin_symbols },
+ { (char *)0, (void *)0, (struct sudo_preload_symbol *)0 }
+};
+
+void
+preload_static_symbols(void)
+{
+ sudo_dso_preload_table(sudo_preload_table);
+}
+
+#endif /* STATIC_SUDOERS_PLUGIN */
diff --git a/src/preserve_fds.c b/src/preserve_fds.c
new file mode 100644
index 0000000..1de01ad
--- /dev/null
+++ b/src/preserve_fds.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2013-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+
+#include "sudo.h"
+
+/*
+ * Add an fd to preserve.
+ */
+int
+add_preserved_fd(struct preserved_fd_list *pfds, int fd)
+{
+ struct preserved_fd *pfd, *pfd_new;
+ debug_decl(add_preserved_fd, SUDO_DEBUG_UTIL)
+
+ pfd_new = malloc(sizeof(*pfd));
+ if (pfd_new == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ pfd_new->lowfd = fd;
+ pfd_new->highfd = fd;
+ pfd_new->flags = fcntl(fd, F_GETFD);
+ if (pfd_new->flags == -1) {
+ free(pfd_new);
+ debug_return_int(-1);
+ }
+
+ TAILQ_FOREACH(pfd, pfds, entries) {
+ if (fd == pfd->highfd) {
+ /* already preserved */
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "fd %d already preserved", fd);
+ free(pfd_new);
+ pfd_new = NULL;
+ break;
+ }
+ if (fd < pfd->highfd) {
+ TAILQ_INSERT_BEFORE(pfd, pfd_new, entries);
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "preserving fd %d", fd);
+ pfd_new = NULL;
+ break;
+ }
+ }
+ if (pfd_new != NULL) {
+ TAILQ_INSERT_TAIL(pfds, pfd_new, entries);
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "preserving fd %d", fd);
+ }
+
+ debug_return_int(0);
+}
+
+/*
+ * Close all descriptors, startfd and higher except those listed
+ * in pfds.
+ */
+void
+closefrom_except(int startfd, struct preserved_fd_list *pfds)
+{
+ int fd, lastfd = -1;
+ struct preserved_fd *pfd, *pfd_next;
+ unsigned char *fdbits;
+ debug_decl(closefrom_except, SUDO_DEBUG_UTIL)
+
+ /* First, relocate preserved fds to be as contiguous as possible. */
+ TAILQ_FOREACH_REVERSE_SAFE(pfd, pfds, preserved_fd_list, entries, pfd_next) {
+ if (pfd->highfd < startfd)
+ continue;
+ fd = dup(pfd->highfd);
+ if (fd == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "dup %d", pfd->highfd);
+ if (errno == EBADF) {
+ TAILQ_REMOVE(pfds, pfd, entries);
+ continue;
+ }
+ /* NOTE: still need to adjust lastfd below with unchanged lowfd. */
+ } else if (fd < pfd->highfd) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "dup %d -> %d", pfd->highfd, pfd->lowfd);
+ sudo_debug_update_fd(pfd->highfd, pfd->lowfd);
+ pfd->lowfd = fd;
+ fd = pfd->highfd;
+ }
+ if (fd != -1)
+ (void) close(fd);
+
+ if (pfd->lowfd > lastfd)
+ lastfd = pfd->lowfd; /* highest (relocated) preserved fd */
+ }
+
+ if (lastfd == -1) {
+ /* No fds to preserve. */
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "closefrom(%d)", startfd);
+ closefrom(startfd);
+ debug_return;
+ }
+
+ /* Create bitmap of preserved (relocated) fds. */
+ fdbits = calloc((lastfd + NBBY) / NBBY, 1);
+ if (fdbits == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ TAILQ_FOREACH(pfd, pfds, entries) {
+ sudo_setbit(fdbits, pfd->lowfd);
+ }
+
+ /*
+ * Close any unpreserved fds [startfd,lastfd]
+ */
+ for (fd = startfd; fd <= lastfd; fd++) {
+ if (!sudo_isset(fdbits, fd)) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "closing fd %d", fd);
+#ifdef __APPLE__
+ /* Avoid potential libdispatch crash when we close its fds. */
+ (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
+#else
+ (void) close(fd);
+#endif
+ }
+ }
+ free(fdbits);
+
+ /* Let closefrom() do the rest for us. */
+ if (lastfd + 1 > startfd)
+ startfd = lastfd + 1;
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "closefrom(%d)", startfd);
+ closefrom(startfd);
+
+ /* Restore preserved fds and set flags. */
+ TAILQ_FOREACH_REVERSE(pfd, pfds, preserved_fd_list, entries) {
+ if (pfd->lowfd != pfd->highfd) {
+ if (dup2(pfd->lowfd, pfd->highfd) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "dup2(%d, %d): %s", pfd->lowfd, pfd->highfd,
+ strerror(errno));
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "dup2(%d, %d)", pfd->lowfd, pfd->highfd);
+ }
+ if (fcntl(pfd->highfd, F_SETFD, pfd->flags) == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "fcntl(%d, F_SETFD, %d): %s", pfd->highfd,
+ pfd->flags, strerror(errno));
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
+ "fcntl(%d, F_SETFD, %d)", pfd->highfd, pfd->flags);
+ }
+ sudo_debug_update_fd(pfd->lowfd, pfd->highfd);
+ (void) close(pfd->lowfd);
+ pfd->lowfd = pfd->highfd;
+ }
+ }
+ debug_return;
+}
+
+/*
+ * Parse a comma-separated list of fds and add them to preserved_fds.
+ */
+void
+parse_preserved_fds(struct preserved_fd_list *pfds, const char *fdstr)
+{
+ const char *cp = fdstr;
+ long lval;
+ char *ep;
+ debug_decl(parse_preserved_fds, SUDO_DEBUG_UTIL)
+
+ do {
+ errno = 0;
+ lval = strtol(cp, &ep, 10);
+ if (ep == cp || (*ep != ',' && *ep != '\0')) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to parse fd string %s", cp);
+ break;
+ }
+ if ((errno == ERANGE && lval == LONG_MAX) || lval < 0 || lval > INT_MAX) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "range error parsing fd string %s", cp);
+ } else {
+ add_preserved_fd(pfds, (int)lval);
+ }
+ cp = ep + 1;
+ } while (*ep != '\0');
+
+ debug_return;
+}
diff --git a/src/regress/noexec/check_noexec.c b/src/regress/noexec/check_noexec.c
new file mode 100644
index 0000000..e83f420
--- /dev/null
+++ b/src/regress/noexec/check_noexec.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_WORDEXP_H
+# include <wordexp.h>
+#endif
+#include <signal.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_util.h"
+#include "sudo_exec.h"
+
+__dso_public int main(int argc, char *argv[], char *envp[]);
+
+static bool
+report_status(int status, const char *what)
+{
+ bool ret = false;
+
+ /* system() returns -1 for exec failure. */
+ if (status == -1) {
+ printf("%s: OK (%s)\n", getprogname(), what);
+ return true;
+ }
+
+ /* check exit value, expecting 127 for failure */
+ if (WIFEXITED(status)) {
+ int exitval = WEXITSTATUS(status);
+ if (exitval == 127) {
+ printf("%s: OK (%s)\n", getprogname(), what);
+ ret = true;
+ } else {
+ printf("%s: FAIL (%s) [%d]\n", getprogname(), what, exitval);
+ }
+ } else if (WIFSIGNALED(status)) {
+ printf("%s: FAIL (%s) [signal %d]\n", getprogname(), what,
+ WTERMSIG(status));
+ } else {
+ /* should not happen */
+ printf("%s: FAIL (%s) [status %d]\n", getprogname(), what, status);
+ }
+
+ return ret;
+}
+
+static int
+try_execl(void)
+{
+ pid_t child, pid;
+ int status;
+
+ child = fork();
+ switch (child) {
+ case -1:
+ sudo_fatal_nodebug("fork");
+ case 0:
+ /* child */
+ /* Try to exec /bin/true, else exit with value 127. */
+ execl("/bin/true", "true", (char *)0);
+ _exit(127);
+ default:
+ /* parent */
+ do {
+ pid = waitpid(child, &status, 0);
+ } while (pid == -1 && errno == EINTR);
+ if (pid == -1)
+ sudo_fatal_nodebug("waitpid");
+
+ if (report_status(status, "execl"))
+ return 0;
+ return 1;
+ }
+}
+
+static int
+try_system(void)
+{
+ int status;
+
+ /* Try to run /bin/true, system() returns 127 on exec failure. */
+ status = system("/bin/true > /dev/null 2>&1");
+
+ if (report_status(status, "system"))
+ return 0;
+ return 1;
+}
+
+#ifdef HAVE_WORDEXP_H
+static int
+try_wordexp(void)
+{
+ wordexp_t we;
+ int rc, ret = 1;
+
+ /*
+ * sudo_noexec.so prevents command substitution via the WRDE_NOCMD flag
+ * where possible.
+ */
+ rc = wordexp("$(/bin/echo foo)", &we, 0);
+ switch (rc) {
+ case -1:
+ /* sudo's wordexp() wrapper returns -1 if RTLD_NEXT is not supported. */
+ case 127:
+ /* Solaris 10 wordexp() returns 127 for execve() failure. */
+#ifdef WRDE_ERRNO
+ case WRDE_ERRNO:
+ /* Solaris 11 wordexp() returns WRDE_ERRNO for execve() failure. */
+#endif
+ printf("%s: OK (wordexp) [%d]\n", getprogname(), rc);
+ ret = 0;
+ break;
+ case WRDE_SYNTAX:
+ /* FreeBSD returns WRDE_SYNTAX if it can't write to the shell process */
+ printf("%s: OK (wordexp) [WRDE_SYNTAX]\n", getprogname());
+ ret = 0;
+ break;
+ case WRDE_CMDSUB:
+ printf("%s: OK (wordexp) [WRDE_CMDSUB]\n", getprogname());
+ ret = 0;
+ break;
+ case 0:
+ /*
+ * On HP-UX 11.00 we don't seem to be able to add WRDE_NOCMD
+ * but the execve() wrapper prevents the command substitution.
+ */
+ if (we.we_wordc == 0) {
+ printf("%s: OK (wordexp) [%d]\n", getprogname(), rc);
+ wordfree(&we);
+ ret = 0;
+ break;
+ }
+ wordfree(&we);
+ /* FALLTHROUGH */
+ default:
+ printf("%s: FAIL (wordexp) [%d]\n", getprogname(), rc);
+ break;
+ }
+ return ret;
+}
+#endif
+
+int
+main(int argc, char *argv[], char *envp[])
+{
+ int errors = 0;
+
+ initprogname(argc > 0 ? argv[0] : "check_noexec");
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s regress | /path/to/sudo_noexec.so\n", getprogname());
+ exit(1);
+ }
+
+ /* Disable execution for post-exec and re-exec ourself. */
+ if (strcmp(argv[1], "rexec") != 0) {
+ const char *noexec = argv[1];
+ argv[1] = "rexec";
+ execve(argv[0], argv, disable_execute(envp, noexec));
+ sudo_fatalx_nodebug("execve");
+ }
+
+ errors += try_execl();
+ errors += try_system();
+#ifdef HAVE_WORDEXP_H
+ errors += try_wordexp();
+#endif
+
+ return errors;
+}
diff --git a/src/regress/ttyname/check_ttyname.c b/src/regress/ttyname/check_ttyname.c
new file mode 100644
index 0000000..1609cd0
--- /dev/null
+++ b/src/regress/ttyname/check_ttyname.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_util.h"
+#include "sudo_debug.h"
+
+__dso_public int main(int argc, char *argv[]);
+
+int sudo_debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
+extern char *get_process_ttyname(char *name, size_t namelen);
+
+int
+main(int argc, char *argv[])
+{
+ char *tty_libc = NULL, *tty_sudo = NULL;
+ char pathbuf[PATH_MAX];
+ int ret = 1;
+
+ initprogname(argc > 0 ? argv[0] : "check_ttyname");
+
+ /* Lookup tty name using kernel info if possible. */
+ if (get_process_ttyname(pathbuf, sizeof(pathbuf)) != NULL)
+ tty_sudo = pathbuf;
+
+#if defined(HAVE_KINFO_PROC2_NETBSD) || \
+ defined(HAVE_KINFO_PROC_OPENBSD) || \
+ defined(HAVE_KINFO_PROC_FREEBSD) || \
+ defined(HAVE_KINFO_PROC_44BSD) || \
+ defined(HAVE__TTYNAME_DEV) || defined(HAVE_STRUCT_PSINFO_PR_TTYDEV) || \
+ defined(HAVE_PSTAT_GETPROC) || defined(__linux__)
+
+ /* Lookup tty name attached to stdin via libc. */
+ tty_libc = ttyname(STDIN_FILENO);
+#endif
+
+ /* Compare libc and kernel ttys. */
+ if (tty_libc != NULL && tty_sudo != NULL) {
+ if (strcmp(tty_libc, tty_sudo) == 0)
+ ret = 0;
+ } else if (tty_libc == NULL && tty_sudo == NULL) {
+ ret = 0;
+ }
+
+ if (ret == 0) {
+ printf("%s: OK (%s)\n", getprogname(), tty_sudo ? tty_sudo : "none");
+ } else if (tty_libc == NULL) {
+ printf("%s: SKIP (%s)\n", getprogname(), tty_sudo ? tty_sudo : "none");
+ ret = 0;
+ } else {
+ printf("%s: FAIL %s (sudo) vs. %s (libc)\n", getprogname(),
+ tty_sudo ? tty_sudo : "none", tty_libc ? tty_libc : "none");
+ }
+
+ return ret;
+}
diff --git a/src/selinux.c b/src/selinux.c
new file mode 100644
index 0000000..ed36d89
--- /dev/null
+++ b/src/selinux.c
@@ -0,0 +1,460 @@
+/*
+ * Copyright (c) 2009-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ * Copyright (c) 2008 Dan Walsh <dwalsh@redhat.com>
+ *
+ * Borrowed heavily from newrole source code
+ * Authors:
+ * Anthony Colatrella
+ * Tim Fraser
+ * Steve Grubb <sgrubb@redhat.com>
+ * Darrel Goeddel <DGoeddel@trustedcs.com>
+ * Michael Thompson <mcthomps@us.ibm.com>
+ * Dan Walsh <dwalsh@redhat.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#ifdef HAVE_SELINUX
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include <selinux/selinux.h> /* for is_selinux_enabled() */
+#include <selinux/context.h> /* for context-mangling functions */
+#include <selinux/get_default_type.h>
+#include <selinux/get_context_list.h>
+
+#ifdef HAVE_LINUX_AUDIT
+# include <libaudit.h>
+#endif
+
+#include "sudo.h"
+#include "sudo_exec.h"
+
+static struct selinux_state {
+ security_context_t old_context;
+ security_context_t new_context;
+ security_context_t tty_context;
+ security_context_t new_tty_context;
+ const char *ttyn;
+ int ttyfd;
+ int enforcing;
+} se_state;
+
+#ifdef HAVE_LINUX_AUDIT
+static int
+audit_role_change(const security_context_t old_context,
+ const security_context_t new_context, const char *ttyn, int result)
+{
+ int au_fd, rc = -1;
+ char *message;
+ debug_decl(audit_role_change, SUDO_DEBUG_SELINUX)
+
+ au_fd = audit_open();
+ if (au_fd == -1) {
+ /* Kernel may not have audit support. */
+ if (errno != EINVAL && errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT
+)
+ sudo_fatal(U_("unable to open audit system"));
+ } else {
+ /* audit role change using the same format as newrole(1) */
+ rc = asprintf(&message, "newrole: old-context=%s new-context=%s",
+ old_context, new_context);
+ if (rc == -1)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ rc = audit_log_user_message(au_fd, AUDIT_USER_ROLE_CHANGE,
+ message, NULL, NULL, ttyn, result);
+ if (rc <= 0)
+ sudo_warn(U_("unable to send audit message"));
+ free(message);
+ close(au_fd);
+ }
+
+ debug_return_int(rc);
+}
+#endif
+
+/*
+ * This function attempts to revert the relabeling done to the tty.
+ * fd - referencing the opened ttyn
+ * ttyn - name of tty to restore
+ *
+ * Returns zero on success, non-zero otherwise
+ */
+int
+selinux_restore_tty(void)
+{
+ int retval = 0;
+ security_context_t chk_tty_context = NULL;
+ debug_decl(selinux_restore_tty, SUDO_DEBUG_SELINUX)
+
+ if (se_state.ttyfd == -1 || se_state.new_tty_context == NULL)
+ goto skip_relabel;
+
+ /* Verify that the tty still has the context set by sudo. */
+ if ((retval = fgetfilecon(se_state.ttyfd, &chk_tty_context)) < 0) {
+ sudo_warn(U_("unable to fgetfilecon %s"), se_state.ttyn);
+ goto skip_relabel;
+ }
+
+ if ((retval = strcmp(chk_tty_context, se_state.new_tty_context))) {
+ sudo_warnx(U_("%s changed labels"), se_state.ttyn);
+ goto skip_relabel;
+ }
+
+ if ((retval = fsetfilecon(se_state.ttyfd, se_state.tty_context)) < 0)
+ sudo_warn(U_("unable to restore context for %s"), se_state.ttyn);
+
+skip_relabel:
+ if (se_state.ttyfd != -1) {
+ close(se_state.ttyfd);
+ se_state.ttyfd = -1;
+ }
+ if (chk_tty_context != NULL) {
+ freecon(chk_tty_context);
+ chk_tty_context = NULL;
+ }
+ debug_return_int(retval);
+}
+
+/*
+ * This function attempts to relabel the tty. If this function fails, then
+ * the contexts are free'd and -1 is returned. On success, 0 is returned
+ * and tty_context and new_tty_context are set.
+ *
+ * This function will not fail if it can not relabel the tty when selinux is
+ * in permissive mode.
+ */
+static int
+relabel_tty(const char *ttyn, int ptyfd)
+{
+ security_context_t tty_con = NULL;
+ security_context_t new_tty_con = NULL;
+ struct stat sb;
+ int fd;
+ debug_decl(relabel_tty, SUDO_DEBUG_SELINUX)
+
+ se_state.ttyfd = ptyfd;
+
+ /* It is perfectly legal to have no tty. */
+ if (ptyfd == -1 && ttyn == NULL)
+ debug_return_int(0);
+
+ /* If sudo is not allocating a pty for the command, open current tty. */
+ if (ptyfd == -1) {
+ se_state.ttyfd = open(ttyn, O_RDWR|O_NOCTTY|O_NONBLOCK);
+ if (se_state.ttyfd == -1 || fstat(se_state.ttyfd, &sb) == -1) {
+ sudo_warn(U_("unable to open %s, not relabeling tty"), ttyn);
+ goto bad;
+ }
+ if (!S_ISCHR(sb.st_mode)) {
+ sudo_warn(U_("%s is not a character device, not relabeling tty"),
+ ttyn);
+ goto bad;
+ }
+ (void)fcntl(se_state.ttyfd, F_SETFL,
+ fcntl(se_state.ttyfd, F_GETFL, 0) & ~O_NONBLOCK);
+ }
+
+ if (fgetfilecon(se_state.ttyfd, &tty_con) < 0) {
+ sudo_warn(U_("unable to get current tty context, not relabeling tty"));
+ goto bad;
+ }
+
+ if (tty_con) {
+ security_class_t tclass = string_to_security_class("chr_file");
+ if (tclass == 0) {
+ sudo_warn(U_("unknown security class \"chr_file\", not relabeling tty"));
+ goto bad;
+ }
+ if (security_compute_relabel(se_state.new_context, tty_con,
+ tclass, &new_tty_con) < 0) {
+ sudo_warn(U_("unable to get new tty context, not relabeling tty"));
+ goto bad;
+ }
+ }
+
+ if (new_tty_con != NULL) {
+ if (fsetfilecon(se_state.ttyfd, new_tty_con) < 0) {
+ sudo_warn(U_("unable to set new tty context"));
+ goto bad;
+ }
+ }
+
+ if (ptyfd != -1) {
+ /* Reopen pty that was relabeled, std{in,out,err} are reset later. */
+ se_state.ttyfd = open(ttyn, O_RDWR|O_NOCTTY, 0);
+ if (se_state.ttyfd == -1 || fstat(se_state.ttyfd, &sb) == -1) {
+ sudo_warn(U_("unable to open %s"), ttyn);
+ goto bad;
+ }
+ if (!S_ISCHR(sb.st_mode)) {
+ sudo_warn(U_("%s is not a character device, not relabeling tty"),
+ ttyn);
+ goto bad;
+ }
+ if (dup2(se_state.ttyfd, ptyfd) == -1) {
+ sudo_warn("dup2");
+ goto bad;
+ }
+ } else {
+ /* Re-open tty to get new label and reset std{in,out,err} */
+ close(se_state.ttyfd);
+ se_state.ttyfd = open(ttyn, O_RDWR|O_NOCTTY|O_NONBLOCK);
+ if (se_state.ttyfd == -1 || fstat(se_state.ttyfd, &sb) == -1) {
+ sudo_warn(U_("unable to open %s"), ttyn);
+ goto bad;
+ }
+ if (!S_ISCHR(sb.st_mode)) {
+ sudo_warn(U_("%s is not a character device, not relabeling tty"),
+ ttyn);
+ goto bad;
+ }
+ (void)fcntl(se_state.ttyfd, F_SETFL,
+ fcntl(se_state.ttyfd, F_GETFL, 0) & ~O_NONBLOCK);
+ for (fd = STDIN_FILENO; fd <= STDERR_FILENO; fd++) {
+ if (isatty(fd) && dup2(se_state.ttyfd, fd) == -1) {
+ sudo_warn("dup2");
+ goto bad;
+ }
+ }
+ }
+ /* Retain se_state.ttyfd so we can restore label when command finishes. */
+ (void)fcntl(se_state.ttyfd, F_SETFD, FD_CLOEXEC);
+
+ se_state.ttyn = ttyn;
+ se_state.tty_context = tty_con;
+ se_state.new_tty_context = new_tty_con;
+ debug_return_int(0);
+
+bad:
+ if (se_state.ttyfd != -1 && se_state.ttyfd != ptyfd) {
+ close(se_state.ttyfd);
+ se_state.ttyfd = -1;
+ }
+ freecon(tty_con);
+ debug_return_int(se_state.enforcing ? -1 : 0);
+}
+
+/*
+ * Returns a new security context based on the old context and the
+ * specified role and type.
+ */
+security_context_t
+get_exec_context(security_context_t old_context, const char *role, const char *type)
+{
+ security_context_t new_context = NULL;
+ context_t context = NULL;
+ char *typebuf = NULL;
+ debug_decl(get_exec_context, SUDO_DEBUG_SELINUX)
+
+ /* We must have a role, the type is optional (we can use the default). */
+ if (!role) {
+ sudo_warnx(U_("you must specify a role for type %s"), type);
+ errno = EINVAL;
+ goto bad;
+ }
+ if (!type) {
+ if (get_default_type(role, &typebuf)) {
+ sudo_warnx(U_("unable to get default type for role %s"), role);
+ errno = EINVAL;
+ goto bad;
+ }
+ type = typebuf;
+ }
+
+ /*
+ * Expand old_context into a context_t so that we extract and modify
+ * its components easily.
+ */
+ context = context_new(old_context);
+
+ /*
+ * Replace the role and type in "context" with the role and
+ * type we will be running the command as.
+ */
+ if (context_role_set(context, role)) {
+ sudo_warn(U_("failed to set new role %s"), role);
+ goto bad;
+ }
+ if (context_type_set(context, type)) {
+ sudo_warn(U_("failed to set new type %s"), type);
+ goto bad;
+ }
+
+ /*
+ * Convert "context" back into a string and verify it.
+ */
+ if ((new_context = strdup(context_str(context))) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto bad;
+ }
+ if (security_check_context(new_context) < 0) {
+ sudo_warnx(U_("%s is not a valid context"), new_context);
+ errno = EINVAL;
+ goto bad;
+ }
+
+#ifdef DEBUG
+ sudo_warnx("Your new context is %s", new_context);
+#endif
+
+ context_free(context);
+ debug_return_ptr(new_context);
+
+bad:
+ free(typebuf);
+ context_free(context);
+ freecon(new_context);
+ debug_return_ptr(NULL);
+}
+
+/*
+ * Set the exec and tty contexts in preparation for fork/exec.
+ * Must run as root, before the uid change.
+ * If ptyfd is not -1, it indicates we are running
+ * in a pty and do not need to reset std{in,out,err}.
+ * Returns 0 on success and -1 on failure.
+ */
+int
+selinux_setup(const char *role, const char *type, const char *ttyn,
+ int ptyfd)
+{
+ int ret = -1;
+ debug_decl(selinux_setup, SUDO_DEBUG_SELINUX)
+
+ /* Store the caller's SID in old_context. */
+ if (getprevcon(&se_state.old_context)) {
+ sudo_warn(U_("failed to get old_context"));
+ goto done;
+ }
+
+ se_state.enforcing = security_getenforce();
+ if (se_state.enforcing < 0) {
+ sudo_warn(U_("unable to determine enforcing mode."));
+ goto done;
+ }
+
+#ifdef DEBUG
+ sudo_warnx("your old context was %s", se_state.old_context);
+#endif
+ se_state.new_context = get_exec_context(se_state.old_context, role, type);
+ if (!se_state.new_context) {
+#ifdef HAVE_LINUX_AUDIT
+ audit_role_change(se_state.old_context, "?",
+ se_state.ttyn, 0);
+#endif
+ goto done;
+ }
+
+ if (relabel_tty(ttyn, ptyfd) < 0) {
+ sudo_warn(U_("unable to set tty context to %s"), se_state.new_context);
+ goto done;
+ }
+
+#ifdef DEBUG
+ if (se_state.ttyfd != -1) {
+ sudo_warnx("your old tty context is %s", se_state.tty_context);
+ sudo_warnx("your new tty context is %s", se_state.new_tty_context);
+ }
+#endif
+
+#ifdef HAVE_LINUX_AUDIT
+ audit_role_change(se_state.old_context, se_state.new_context,
+ se_state.ttyn, 1);
+#endif
+
+ ret = 0;
+
+done:
+ debug_return_int(ret);
+}
+
+void
+selinux_execve(int fd, const char *path, char *const argv[], char *envp[],
+ bool noexec)
+{
+ char **nargv;
+ const char *sesh;
+ int argc, nargc, serrno;
+ debug_decl(selinux_execve, SUDO_DEBUG_SELINUX)
+
+ sesh = sudo_conf_sesh_path();
+ if (sesh == NULL) {
+ sudo_warnx("internal error: sesh path not set");
+ errno = EINVAL;
+ debug_return;
+ }
+
+ if (setexeccon(se_state.new_context)) {
+ sudo_warn(U_("unable to set exec context to %s"), se_state.new_context);
+ if (se_state.enforcing)
+ debug_return;
+ }
+
+#ifdef HAVE_SETKEYCREATECON
+ if (setkeycreatecon(se_state.new_context)) {
+ sudo_warn(U_("unable to set key creation context to %s"), se_state.new_context);
+ if (se_state.enforcing)
+ debug_return;
+ }
+#endif /* HAVE_SETKEYCREATECON */
+
+ /*
+ * Build new argv with sesh as argv[0].
+ * If argv[0] ends in -noexec, sesh will disable execute
+ * for the command it runs.
+ */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ continue;
+ nargv = reallocarray(NULL, argc + 3, sizeof(char *));
+ if (nargv == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return;
+ }
+ if (noexec)
+ nargv[0] = *argv[0] == '-' ? "-sesh-noexec" : "sesh-noexec";
+ else
+ nargv[0] = *argv[0] == '-' ? "-sesh" : "sesh";
+ nargc = 1;
+ if (fd != -1 && asprintf(&nargv[nargc++], "--execfd=%d", fd) == -1) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return;
+ }
+ nargv[nargc++] = (char *)path;
+ memcpy(&nargv[nargc], &argv[1], argc * sizeof(char *)); /* copies NULL */
+
+ /* sesh will handle noexec for us. */
+ sudo_execve(-1, sesh, nargv, envp, false);
+ serrno = errno;
+ free(nargv);
+ errno = serrno;
+ debug_return;
+}
+
+#endif /* HAVE_SELINUX */
diff --git a/src/sesh.c b/src/sesh.c
new file mode 100644
index 0000000..873748e
--- /dev/null
+++ b/src/sesh.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2008, 2010-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <time.h>
+#include <unistd.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_conf.h"
+#include "sudo_debug.h"
+#include "sudo_exec.h"
+#include "sudo_plugin.h"
+#include "sudo_util.h"
+
+__dso_public int main(int argc, char *argv[], char *envp[]);
+
+static int sesh_sudoedit(int argc, char *argv[]);
+
+/*
+ * Exit codes defined in sudo_exec.h:
+ * SESH_SUCCESS (0) ... successful operation
+ * SESH_ERR_FAILURE (1) ... unspecified error
+ * SESH_ERR_INVALID (30) ... invalid -e arg value
+ * SESH_ERR_BAD_PATHS (31) ... odd number of paths
+ * SESH_ERR_NO_FILES (32) ... copy error, no files copied
+ * SESH_ERR_SOME_FILES (33) ... copy error, no files copied
+ */
+int
+main(int argc, char *argv[], char *envp[])
+{
+ int ret;
+ debug_decl(main, SUDO_DEBUG_MAIN)
+
+ initprogname(argc > 0 ? argv[0] : "sesh");
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE_NAME, LOCALEDIR);
+ textdomain(PACKAGE_NAME);
+
+ if (argc < 2)
+ sudo_fatalx(U_("requires at least one argument"));
+
+ /* Read sudo.conf and initialize the debug subsystem. */
+ if (sudo_conf_read(NULL, SUDO_CONF_DEBUG) == -1)
+ exit(EXIT_FAILURE);
+ sudo_debug_register(getprogname(), NULL, NULL,
+ sudo_conf_debug_files(getprogname()));
+
+ if (strcmp(argv[1], "-e") == 0) {
+ ret = sesh_sudoedit(argc, argv);
+ } else {
+ bool login_shell, noexec = false;
+ char *cp, *cmnd;
+ int fd = -1;
+
+ /* If the first char of argv[0] is '-', we are running a login shell. */
+ login_shell = argv[0][0] == '-';
+
+ /* If argv[0] ends in -noexec, pass the flag to sudo_execve() */
+ if ((cp = strrchr(argv[0], '-')) != NULL && cp != argv[0])
+ noexec = strcmp(cp, "-noexec") == 0;
+
+ /* If argv[1] is --execfd=%d, extract the fd to exec with. */
+ if (strncmp(argv[1], "--execfd=", 9) == 0) {
+ const char *errstr;
+
+ cp = argv[1] + 9;
+ fd = strtonum(cp, 0, INT_MAX, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx(U_("invalid file descriptor number: %s"), cp);
+ argv++;
+ argc--;
+ }
+
+ /* Shift argv and make a copy of the command to execute. */
+ argv++;
+ argc--;
+ if ((cmnd = strdup(argv[0])) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+ /* If invoked as a login shell, modify argv[0] accordingly. */
+ if (login_shell) {
+ if ((cp = strrchr(argv[0], '/')) == NULL)
+ sudo_fatal(U_("unable to run %s as a login shell"), argv[0]);
+ *cp = '-';
+ argv[0] = cp;
+ }
+ sudo_execve(fd, cmnd, argv, envp, noexec);
+ sudo_warn(U_("unable to execute %s"), cmnd);
+ ret = SESH_ERR_FAILURE;
+ }
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, ret);
+ _exit(ret);
+}
+
+static int
+sesh_sudoedit(int argc, char *argv[])
+{
+ int i, oflags_dst, post, ret = SESH_ERR_FAILURE;
+ int fd_src = -1, fd_dst = -1, follow = 0;
+ ssize_t nread, nwritten;
+ struct stat sb;
+ struct timespec times[2];
+ char buf[BUFSIZ];
+ debug_decl(sesh_sudoedit, SUDO_DEBUG_EDIT)
+
+ /* Check for -h flag (don't follow links). */
+ if (strcmp(argv[2], "-h") == 0) {
+ argv++;
+ argc--;
+ follow = O_NOFOLLOW;
+ }
+
+ if (argc < 3)
+ debug_return_int(SESH_ERR_FAILURE);
+
+ /*
+ * We need to know whether we are performing the copy operation
+ * before or after the editing. Without this we would not know
+ * which files are temporary and which are the originals.
+ * post = 0 ... before
+ * post = 1 ... after
+ */
+ if (strcmp(argv[2], "0") == 0)
+ post = 0;
+ else if (strcmp(argv[2], "1") == 0)
+ post = 1;
+ else /* invalid value */
+ debug_return_int(SESH_ERR_INVALID);
+
+ /* Align argv & argc to the beggining of the file list. */
+ argv += 3;
+ argc -= 3;
+
+ /* no files specified, nothing to do */
+ if (argc == 0)
+ debug_return_int(SESH_SUCCESS);
+ /* odd number of paths specified */
+ if (argc & 1)
+ debug_return_int(SESH_ERR_BAD_PATHS);
+
+ /*
+ * Use O_EXCL if we are not in the post editing stage
+ * so that it's ensured that the temporary files are
+ * created by us and that we are not opening any symlinks.
+ */
+ oflags_dst = O_WRONLY|O_TRUNC|O_CREAT|(post ? follow : O_EXCL);
+ for (i = 0; i < argc - 1; i += 2) {
+ const char *path_src = argv[i];
+ const char *path_dst = argv[i + 1];
+ /*
+ * Try to open the source file for reading. If it
+ * doesn't exist, that's OK, we'll create an empty
+ * destination file.
+ */
+ if ((fd_src = open(path_src, O_RDONLY|follow, S_IRUSR|S_IWUSR)) < 0) {
+ if (errno != ENOENT) {
+ sudo_warn("%s", path_src);
+ if (post) {
+ ret = SESH_ERR_SOME_FILES;
+ goto nocleanup;
+ } else
+ goto cleanup_0;
+ }
+ }
+
+ if ((fd_dst = open(path_dst, oflags_dst, post ?
+ (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) : (S_IRUSR|S_IWUSR))) < 0) {
+ /* error - cleanup */
+ sudo_warn("%s", path_dst);
+ if (post) {
+ ret = SESH_ERR_SOME_FILES;
+ goto nocleanup;
+ } else
+ goto cleanup_0;
+ }
+
+ if (fd_src != -1) {
+ while ((nread = read(fd_src, buf, sizeof(buf))) > 0) {
+ if ((nwritten = write(fd_dst, buf, nread)) != nread) {
+ sudo_warn("%s", path_src);
+ if (post) {
+ ret = SESH_ERR_SOME_FILES;
+ goto nocleanup;
+ } else
+ goto cleanup_0;
+ }
+ }
+ }
+
+ if (!post) {
+ if (fd_src == -1 || fstat(fd_src, &sb) != 0)
+ memset(&sb, 0, sizeof(sb));
+ /* Make mtime on temp file match src. */
+ mtim_get(&sb, times[0]);
+ times[1].tv_sec = times[0].tv_sec;
+ times[1].tv_nsec = times[0].tv_nsec;
+ if (futimens(fd_dst, times) == -1) {
+ if (utimensat(AT_FDCWD, path_dst, times, 0) == -1)
+ sudo_warn("%s", path_dst);
+ }
+ }
+ close(fd_dst);
+ fd_dst = -1;
+ if (fd_src != -1) {
+ close(fd_src);
+ fd_src = -1;
+ }
+ }
+
+ ret = SESH_SUCCESS;
+ if (post) {
+ /* Remove temporary files (post=1) */
+ for (i = 0; i < argc - 1; i += 2)
+ unlink(argv[i]);
+ }
+nocleanup:
+ if (fd_dst != -1)
+ close(fd_dst);
+ if (fd_src != -1)
+ close(fd_src);
+ return(ret);
+cleanup_0:
+ /* Remove temporary files (post=0) */
+ for (i = 0; i < argc - 1; i += 2)
+ unlink(argv[i + 1]);
+ if (fd_dst != -1)
+ close(fd_dst);
+ if (fd_src != -1)
+ close(fd_src);
+ return(SESH_ERR_NO_FILES);
+}
diff --git a/src/signal.c b/src/signal.c
new file mode 100644
index 0000000..5c60225
--- /dev/null
+++ b/src/signal.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2009-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "sudo.h"
+#include "sudo_exec.h"
+
+static struct signal_state {
+ int signo;
+ int restore;
+ struct sigaction sa;
+} saved_signals[] = {
+ { SIGALRM }, /* SAVED_SIGALRM */
+ { SIGCHLD }, /* SAVED_SIGCHLD */
+ { SIGCONT }, /* SAVED_SIGCONT */
+ { SIGHUP }, /* SAVED_SIGHUP */
+ { SIGINT }, /* SAVED_SIGINT */
+ { SIGPIPE }, /* SAVED_SIGPIPE */
+ { SIGQUIT }, /* SAVED_SIGQUIT */
+ { SIGTERM }, /* SAVED_SIGTERM */
+ { SIGTSTP }, /* SAVED_SIGTSTP */
+ { SIGTTIN }, /* SAVED_SIGTTIN */
+ { SIGTTOU }, /* SAVED_SIGTTOU */
+ { SIGUSR1 }, /* SAVED_SIGUSR1 */
+ { SIGUSR2 }, /* SAVED_SIGUSR2 */
+ { -1 }
+};
+
+static sig_atomic_t pending_signals[NSIG];
+
+static void
+sudo_handler(int signo)
+{
+ /* Mark signal as pending. */
+ pending_signals[signo] = 1;
+}
+
+bool
+signal_pending(int signo)
+{
+ return pending_signals[signo] == 1;
+}
+
+/*
+ * Save signal handler state so it can be restored before exec.
+ */
+void
+save_signals(void)
+{
+ struct signal_state *ss;
+ debug_decl(save_signals, SUDO_DEBUG_MAIN)
+
+ for (ss = saved_signals; ss->signo != -1; ss++) {
+ if (sigaction(ss->signo, NULL, &ss->sa) != 0)
+ sudo_warn(U_("unable to save handler for signal %d"), ss->signo);
+ }
+
+ debug_return;
+}
+
+/*
+ * Restore signal handlers to initial state for exec.
+ */
+void
+restore_signals(void)
+{
+ struct signal_state *ss;
+ debug_decl(restore_signals, SUDO_DEBUG_MAIN)
+
+ for (ss = saved_signals; ss->signo != -1; ss++) {
+ if (ss->restore) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "restoring handler for signal %d: %s", ss->signo,
+ ss->sa.sa_handler == SIG_IGN ? "SIG_IGN" :
+ ss->sa.sa_handler == SIG_DFL ? "SIG_DFL" : "???");
+ if (sigaction(ss->signo, &ss->sa, NULL) != 0) {
+ sudo_warn(U_("unable to restore handler for signal %d"),
+ ss->signo);
+ }
+ }
+ }
+
+ debug_return;
+}
+
+/*
+ * Trap tty-generated (and other) signals so we can't be killed before
+ * calling the policy close function. The signal pipe will be drained
+ * in sudo_execute() before running the command and new handlers will
+ * be installed in the parent.
+ */
+void
+init_signals(void)
+{
+ struct sigaction sa;
+ struct signal_state *ss;
+ debug_decl(init_signals, SUDO_DEBUG_MAIN)
+
+ memset(&sa, 0, sizeof(sa));
+ sigfillset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = sudo_handler;
+
+ for (ss = saved_signals; ss->signo > 0; ss++) {
+ switch (ss->signo) {
+ case SIGCONT:
+ case SIGPIPE:
+ case SIGTTIN:
+ case SIGTTOU:
+ /* Don't install these until exec time. */
+ break;
+ default:
+ if (ss->sa.sa_handler != SIG_IGN) {
+ if (sigaction(ss->signo, &sa, NULL) != 0) {
+ sudo_warn(U_("unable to set handler for signal %d"),
+ ss->signo);
+ }
+ }
+ break;
+ }
+ }
+ /* Ignore SIGPIPE until exec. */
+ if (saved_signals[SAVED_SIGPIPE].sa.sa_handler != SIG_IGN) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "will restore signal %d on exec", SIGPIPE);
+ saved_signals[SAVED_SIGPIPE].restore = true;
+ sa.sa_handler = SIG_IGN;
+ if (sigaction(SIGPIPE, &sa, NULL) != 0)
+ sudo_warn(U_("unable to set handler for signal %d"), SIGPIPE);
+ }
+
+ debug_return;
+}
+
+/*
+ * Like sigaction() but sets restore flag in saved_signals[]
+ * if needed.
+ */
+int
+sudo_sigaction(int signo, struct sigaction *sa, struct sigaction *osa)
+{
+ struct signal_state *ss;
+ int ret;
+ debug_decl(sudo_sigaction, SUDO_DEBUG_MAIN)
+
+ for (ss = saved_signals; ss->signo > 0; ss++) {
+ if (ss->signo == signo) {
+ /* If signal was or now is ignored, restore old handler on exec. */
+ if (ss->sa.sa_handler == SIG_IGN || sa->sa_handler == SIG_IGN) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "will restore signal %d on exec", signo);
+ ss->restore = true;
+ }
+ break;
+ }
+ }
+ ret = sigaction(signo, sa, osa);
+
+ debug_return_int(ret);
+}
diff --git a/src/solaris.c b/src/solaris.c
new file mode 100644
index 0000000..8e2fcee
--- /dev/null
+++ b/src/solaris.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2009-2015 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#ifdef HAVE_PROJECT_H
+# include <project.h>
+# include <sys/task.h>
+#endif
+#include <errno.h>
+#include <pwd.h>
+
+#include "sudo.h"
+#include "sudo_dso.h"
+
+int
+os_init(int argc, char *argv[], char *envp[])
+{
+ /*
+ * Solaris 11 is unable to load the per-locale shared objects
+ * without this. We must keep the handle open for it to work.
+ * This bug was fixed in Solaris 11 Update 1.
+ */
+ void *handle = sudo_dso_load("/usr/lib/locale/common/methods_unicode.so.3",
+ SUDO_DSO_LAZY|SUDO_DSO_GLOBAL);
+ (void)&handle;
+
+ return os_init_common(argc, argv, envp);
+}
+
+#ifdef HAVE_PROJECT_H
+void
+set_project(struct passwd *pw)
+{
+ struct project proj;
+ char buf[PROJECT_BUFSZ];
+ int errval;
+ debug_decl(set_project, SUDO_DEBUG_UTIL)
+
+ /*
+ * Collect the default project for the user and settaskid
+ */
+ setprojent();
+ if (getdefaultproj(pw->pw_name, &proj, buf, sizeof(buf)) != NULL) {
+ errval = setproject(proj.pj_name, pw->pw_name, TASK_NORMAL);
+ switch(errval) {
+ case 0:
+ break;
+ case SETPROJ_ERR_TASK:
+ switch (errno) {
+ case EAGAIN:
+ sudo_warnx(U_("resource control limit has been reached"));
+ break;
+ case ESRCH:
+ sudo_warnx(U_("user \"%s\" is not a member of project \"%s\""),
+ pw->pw_name, proj.pj_name);
+ break;
+ case EACCES:
+ sudo_warnx(U_("the invoking task is final"));
+ break;
+ default:
+ sudo_warnx(U_("could not join project \"%s\""), proj.pj_name);
+ }
+ case SETPROJ_ERR_POOL:
+ switch (errno) {
+ case EACCES:
+ sudo_warnx(U_("no resource pool accepting default bindings "
+ "exists for project \"%s\""), proj.pj_name);
+ break;
+ case ESRCH:
+ sudo_warnx(U_("specified resource pool does not exist for "
+ "project \"%s\""), proj.pj_name);
+ break;
+ default:
+ sudo_warnx(U_("could not bind to default resource pool for "
+ "project \"%s\""), proj.pj_name);
+ }
+ break;
+ default:
+ if (errval <= 0) {
+ sudo_warnx(U_("setproject failed for project \"%s\""), proj.pj_name);
+ } else {
+ sudo_warnx(U_("warning, resource control assignment failed for "
+ "project \"%s\""), proj.pj_name);
+ }
+ }
+ } else {
+ sudo_warn("getdefaultproj");
+ }
+ endprojent();
+ debug_return;
+}
+#endif /* HAVE_PROJECT_H */
diff --git a/src/sudo.c b/src/sudo.c
new file mode 100644
index 0000000..c81f946
--- /dev/null
+++ b/src/sudo.c
@@ -0,0 +1,1450 @@
+/*
+ * Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#ifdef __TANDEM
+# include <floss.h>
+#endif
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/resource.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <grp.h>
+#include <pwd.h>
+#include <time.h>
+#ifdef HAVE_SELINUX
+# include <selinux/selinux.h> /* for is_selinux_enabled() */
+#endif
+#ifdef HAVE_SETAUTHDB
+# include <usersec.h>
+#endif /* HAVE_SETAUTHDB */
+#if defined(HAVE_GETPRPWNAM) && defined(HAVE_SET_AUTH_PARAMETERS)
+# ifdef __hpux
+# undef MAXINT
+# include <hpsecurity.h>
+# else
+# include <sys/security.h>
+# endif /* __hpux */
+# include <prot.h>
+#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */
+#ifdef __linux__
+# include <sys/prctl.h>
+#endif
+
+#include <sudo_usage.h>
+#include "sudo.h"
+#include "sudo_plugin.h"
+#include "sudo_plugin_int.h"
+
+/*
+ * Local variables
+ */
+struct plugin_container policy_plugin;
+struct plugin_container_list io_plugins = TAILQ_HEAD_INITIALIZER(io_plugins);
+struct user_details user_details;
+const char *list_user; /* extern for parse_args.c */
+int sudo_debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
+static struct command_details command_details;
+static int sudo_mode;
+
+struct sudo_gc_entry {
+ SLIST_ENTRY(sudo_gc_entry) entries;
+ enum sudo_gc_types type;
+ union {
+ char **vec;
+ void *ptr;
+ } u;
+};
+SLIST_HEAD(sudo_gc_list, sudo_gc_entry);
+#ifdef NO_LEAKS
+static struct sudo_gc_list sudo_gc_list = SLIST_HEAD_INITIALIZER(sudo_gc_list);
+#endif
+
+/*
+ * Local functions
+ */
+static void fix_fds(void);
+static void sudo_check_suid(const char *path);
+static char **get_user_info(struct user_details *);
+static void command_info_to_details(char * const info[],
+ struct command_details *details);
+static void gc_init(void);
+
+/* Policy plugin convenience functions. */
+static int policy_open(struct plugin_container *plugin,
+ struct sudo_settings *settings,
+ char * const user_info[], char * const user_env[]);
+static void policy_close(struct plugin_container *plugin, int exit_status,
+ int error);
+static int policy_show_version(struct plugin_container *plugin, int verbose);
+static int policy_check(struct plugin_container *plugin, int argc,
+ char * const argv[], char *env_add[], char **command_info[],
+ char **argv_out[], char **user_env_out[]);
+static int policy_list(struct plugin_container *plugin, int argc,
+ char * const argv[], int verbose, const char *list_user);
+static int policy_validate(struct plugin_container *plugin);
+static void policy_invalidate(struct plugin_container *plugin, int remove);
+
+/* I/O log plugin convenience functions. */
+static int iolog_open(struct plugin_container *plugin,
+ struct sudo_settings *settings, char * const user_info[],
+ char * const command_details[], int argc, char * const argv[],
+ char * const user_env[]);
+static void iolog_close(struct plugin_container *plugin, int exit_status,
+ int error);
+static int iolog_show_version(struct plugin_container *plugin, int verbose);
+static void iolog_unlink(struct plugin_container *plugin);
+static void free_plugin_container(struct plugin_container *plugin, bool ioplugin);
+
+__dso_public int main(int argc, char *argv[], char *envp[]);
+
+int
+main(int argc, char *argv[], char *envp[])
+{
+ int nargc, ok, status = 0;
+ char **nargv, **env_add;
+ char **user_info, **command_info, **argv_out, **user_env_out;
+ struct sudo_settings *settings;
+ struct plugin_container *plugin, *next;
+ sigset_t mask;
+ debug_decl_vars(main, SUDO_DEBUG_MAIN)
+
+ /* Make sure fds 0-2 are open and do OS-specific initialization. */
+ fix_fds();
+ os_init(argc, argv, envp);
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE_NAME, LOCALEDIR);
+ textdomain(PACKAGE_NAME);
+
+ (void) tzset();
+
+ /* Must be done before we do any password lookups */
+#if defined(HAVE_GETPRPWNAM) && defined(HAVE_SET_AUTH_PARAMETERS)
+ (void) set_auth_parameters(argc, argv);
+# ifdef HAVE_INITPRIVS
+ initprivs();
+# endif
+#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */
+
+ /* Initialize the debug subsystem. */
+ if (sudo_conf_read(NULL, SUDO_CONF_DEBUG) == -1)
+ exit(EXIT_FAILURE);
+ sudo_debug_instance = sudo_debug_register(getprogname(),
+ NULL, NULL, sudo_conf_debug_files(getprogname()));
+ if (sudo_debug_instance == SUDO_DEBUG_INSTANCE_ERROR)
+ exit(EXIT_FAILURE);
+
+ /* Make sure we are setuid root. */
+ sudo_check_suid(argc > 0 ? argv[0] : "sudo");
+
+ /* Save original signal state and setup default signal handlers. */
+ save_signals();
+ init_signals();
+
+ /* Reset signal mask to the default value (unblock). */
+ (void) sigemptyset(&mask);
+ (void) sigprocmask(SIG_SETMASK, &mask, NULL);
+
+ /* Parse the rest of sudo.conf. */
+ sudo_conf_read(NULL, SUDO_CONF_ALL & ~SUDO_CONF_DEBUG);
+
+ /* Fill in user_info with user name, uid, cwd, etc. */
+ if ((user_info = get_user_info(&user_details)) == NULL)
+ exit(EXIT_FAILURE); /* get_user_info printed error message */
+
+ /* Disable core dumps if not enabled in sudo.conf. */
+ if (sudo_conf_disable_coredump())
+ disable_coredump(false);
+
+ /* Parse command line arguments. */
+ sudo_mode = parse_args(argc, argv, &nargc, &nargv, &settings, &env_add);
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "sudo_mode %d", sudo_mode);
+
+ /* Print sudo version early, in case of plugin init failure. */
+ if (ISSET(sudo_mode, MODE_VERSION)) {
+ printf(_("Sudo version %s\n"), PACKAGE_VERSION);
+ if (user_details.uid == ROOT_UID)
+ (void) printf(_("Configure options: %s\n"), CONFIGURE_ARGS);
+ }
+
+ /* Use conversation function for sudo_(warn|fatal)x? for plugins. */
+ sudo_warn_set_conversation(sudo_conversation);
+
+ /* Load plugins. */
+ if (!sudo_load_plugins(&policy_plugin, &io_plugins))
+ sudo_fatalx(U_("fatal error, unable to load plugins"));
+
+ /* Open policy plugin. */
+ ok = policy_open(&policy_plugin, settings, user_info, envp);
+ if (ok != 1) {
+ if (ok == -2)
+ usage(1);
+ else
+ sudo_fatalx(U_("unable to initialize policy plugin"));
+ }
+
+ switch (sudo_mode & MODE_MASK) {
+ case MODE_VERSION:
+ policy_show_version(&policy_plugin, !user_details.uid);
+ TAILQ_FOREACH(plugin, &io_plugins, entries) {
+ ok = iolog_open(plugin, settings, user_info, NULL,
+ nargc, nargv, envp);
+ if (ok != -1)
+ iolog_show_version(plugin, !user_details.uid);
+ }
+ break;
+ case MODE_VALIDATE:
+ case MODE_VALIDATE|MODE_INVALIDATE:
+ ok = policy_validate(&policy_plugin);
+ exit(ok != 1);
+ case MODE_KILL:
+ case MODE_INVALIDATE:
+ policy_invalidate(&policy_plugin, sudo_mode == MODE_KILL);
+ exit(0);
+ break;
+ case MODE_CHECK:
+ case MODE_CHECK|MODE_INVALIDATE:
+ case MODE_LIST:
+ case MODE_LIST|MODE_INVALIDATE:
+ ok = policy_list(&policy_plugin, nargc, nargv,
+ ISSET(sudo_mode, MODE_LONG_LIST), list_user);
+ exit(ok != 1);
+ case MODE_EDIT:
+ case MODE_RUN:
+ ok = policy_check(&policy_plugin, nargc, nargv, env_add,
+ &command_info, &argv_out, &user_env_out);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "policy plugin returns %d", ok);
+ if (ok != 1) {
+ if (ok == -2)
+ usage(1);
+ exit(EXIT_FAILURE); /* plugin printed error message */
+ }
+ /* Reset nargv/nargc based on argv_out. */
+ /* XXX - leaks old nargv in shell mode */
+ for (nargv = argv_out, nargc = 0; nargv[nargc] != NULL; nargc++)
+ continue;
+ if (nargc == 0)
+ sudo_fatalx(U_("plugin did not return a command to execute"));
+ /* Open I/O plugins once policy plugin succeeds. */
+ TAILQ_FOREACH_SAFE(plugin, &io_plugins, entries, next) {
+ ok = iolog_open(plugin, settings, user_info,
+ command_info, nargc, nargv, user_env_out);
+ switch (ok) {
+ case 1:
+ break;
+ case 0:
+ /* I/O plugin asked to be disabled, remove and free. */
+ iolog_unlink(plugin);
+ break;
+ case -2:
+ usage(1);
+ break;
+ default:
+ sudo_fatalx(U_("error initializing I/O plugin %s"),
+ plugin->name);
+ }
+ }
+ /* Setup command details and run command/edit. */
+ command_info_to_details(command_info, &command_details);
+ command_details.argv = argv_out;
+ command_details.envp = user_env_out;
+ if (ISSET(sudo_mode, MODE_LOGIN_SHELL))
+ SET(command_details.flags, CD_LOGIN_SHELL);
+ if (ISSET(sudo_mode, MODE_BACKGROUND))
+ SET(command_details.flags, CD_BACKGROUND);
+ /* Become full root (not just setuid) so user cannot kill us. */
+ if (setuid(ROOT_UID) == -1)
+ sudo_warn("setuid(%d)", ROOT_UID);
+ if (ISSET(command_details.flags, CD_SUDOEDIT)) {
+ status = sudo_edit(&command_details);
+ } else {
+ status = run_command(&command_details);
+ }
+ /* The close method was called by sudo_edit/run_command. */
+ break;
+ default:
+ sudo_fatalx(U_("unexpected sudo mode 0x%x"), sudo_mode);
+ }
+
+ /*
+ * If the command was terminated by a signal, sudo needs to terminated
+ * the same way. Otherwise, the shell may ignore a keyboard-generated
+ * signal. However, we want to avoid having sudo dump core itself.
+ */
+ if (WIFSIGNALED(status)) {
+ struct sigaction sa;
+
+ if (WCOREDUMP(status))
+ disable_coredump(false);
+
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = SIG_DFL;
+ sigaction(WTERMSIG(status), &sa, NULL);
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys,
+ WTERMSIG(status) | 128);
+ kill(getpid(), WTERMSIG(status));
+ }
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys,
+ WEXITSTATUS(status));
+ exit(WEXITSTATUS(status));
+}
+
+int
+os_init_common(int argc, char *argv[], char *envp[])
+{
+ initprogname(argc > 0 ? argv[0] : "sudo");
+#ifdef STATIC_SUDOERS_PLUGIN
+ preload_static_symbols();
+#endif
+ gc_init();
+ return 0;
+}
+
+/*
+ * Ensure that stdin, stdout and stderr are open; set to /dev/null if not.
+ * Some operating systems do this automatically in the kernel or libc.
+ */
+static void
+fix_fds(void)
+{
+ int miss[3], devnull = -1;
+ debug_decl(fix_fds, SUDO_DEBUG_UTIL)
+
+ /*
+ * stdin, stdout and stderr must be open; set them to /dev/null
+ * if they are closed.
+ */
+ miss[STDIN_FILENO] = fcntl(STDIN_FILENO, F_GETFL, 0) == -1;
+ miss[STDOUT_FILENO] = fcntl(STDOUT_FILENO, F_GETFL, 0) == -1;
+ miss[STDERR_FILENO] = fcntl(STDERR_FILENO, F_GETFL, 0) == -1;
+ if (miss[STDIN_FILENO] || miss[STDOUT_FILENO] || miss[STDERR_FILENO]) {
+ devnull = open(_PATH_DEVNULL, O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ if (devnull == -1)
+ sudo_fatal(U_("unable to open %s"), _PATH_DEVNULL);
+ if (miss[STDIN_FILENO] && dup2(devnull, STDIN_FILENO) == -1)
+ sudo_fatal("dup2");
+ if (miss[STDOUT_FILENO] && dup2(devnull, STDOUT_FILENO) == -1)
+ sudo_fatal("dup2");
+ if (miss[STDERR_FILENO] && dup2(devnull, STDERR_FILENO) == -1)
+ sudo_fatal("dup2");
+ if (devnull > STDERR_FILENO)
+ close(devnull);
+ }
+ debug_return;
+}
+
+/*
+ * Allocate space for groups and fill in using sudo_getgrouplist2()
+ * for when we cannot (or don't want to) use getgroups().
+ * Returns 0 on success and -1 on failure.
+ */
+static int
+fill_group_list(struct user_details *ud)
+{
+ int ret = -1;
+ debug_decl(fill_group_list, SUDO_DEBUG_UTIL)
+
+ /*
+ * If user specified a max number of groups, use it, otherwise let
+ * sudo_getgrouplist2() allocate the group vector.
+ */
+ ud->ngroups = sudo_conf_max_groups();
+ if (ud->ngroups > 0) {
+ ud->groups = reallocarray(NULL, ud->ngroups, sizeof(GETGROUPS_T));
+ if (ud->groups != NULL) {
+ /* No error on insufficient space if user specified max_groups. */
+ (void)sudo_getgrouplist2(ud->username, ud->gid, &ud->groups,
+ &ud->ngroups);
+ ret = 0;
+ }
+ } else {
+ ud->groups = NULL;
+ ret = sudo_getgrouplist2(ud->username, ud->gid, &ud->groups,
+ &ud->ngroups);
+ }
+ if (ret == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: %s: unable to get groups via sudo_getgrouplist2()",
+ __func__, ud->username);
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: %s: got %d groups via sudo_getgrouplist2()",
+ __func__, ud->username, ud->ngroups);
+ }
+ debug_return_int(ret);
+}
+
+static char *
+get_user_groups(struct user_details *ud)
+{
+ char *cp, *gid_list = NULL;
+ size_t glsize;
+ int i, len, group_source;
+ debug_decl(get_user_groups, SUDO_DEBUG_UTIL)
+
+ ud->groups = NULL;
+ group_source = sudo_conf_group_source();
+ if (group_source != GROUP_SOURCE_DYNAMIC) {
+ int maxgroups = (int)sysconf(_SC_NGROUPS_MAX);
+ if (maxgroups < 0)
+ maxgroups = NGROUPS_MAX;
+
+ if ((ud->ngroups = getgroups(0, NULL)) > 0) {
+ /* Use groups from kernel if not too many or source is static. */
+ if (ud->ngroups < maxgroups || group_source == GROUP_SOURCE_STATIC) {
+ ud->groups = reallocarray(NULL, ud->ngroups, sizeof(GETGROUPS_T));
+ if (ud->groups == NULL)
+ goto done;
+ if (getgroups(ud->ngroups, ud->groups) < 0) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: %s: unable to get %d groups via getgroups()",
+ __func__, ud->username, ud->ngroups);
+ free(ud->groups);
+ ud->groups = NULL;
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: %s: got %d groups via getgroups()",
+ __func__, ud->username, ud->ngroups);
+ }
+ }
+ }
+ }
+ if (ud->groups == NULL) {
+ /*
+ * Query group database if kernel list is too small or disabled.
+ * Typically, this is because NFS can only support up to 16 groups.
+ */
+ if (fill_group_list(ud) == -1)
+ goto done;
+ }
+
+ /*
+ * Format group list as a comma-separated string of gids.
+ */
+ glsize = sizeof("groups=") - 1 + (ud->ngroups * (MAX_UID_T_LEN + 1));
+ if ((gid_list = malloc(glsize)) == NULL)
+ goto done;
+ memcpy(gid_list, "groups=", sizeof("groups=") - 1);
+ cp = gid_list + sizeof("groups=") - 1;
+ for (i = 0; i < ud->ngroups; i++) {
+ len = snprintf(cp, glsize - (cp - gid_list), "%s%u",
+ i ? "," : "", (unsigned int)ud->groups[i]);
+ if (len <= 0 || (size_t)len >= glsize - (cp - gid_list))
+ sudo_fatalx(U_("internal error, %s overflow"), __func__);
+ cp += len;
+ }
+done:
+ debug_return_str(gid_list);
+}
+
+/*
+ * Return user information as an array of name=value pairs.
+ * and fill in struct user_details (which shares the same strings).
+ */
+static char **
+get_user_info(struct user_details *ud)
+{
+ char *cp, **user_info, path[PATH_MAX];
+ unsigned int i = 0;
+ mode_t mask;
+ struct passwd *pw;
+ int fd;
+ debug_decl(get_user_info, SUDO_DEBUG_UTIL)
+
+ /*
+ * On BSD systems you can set a hint to keep the password and
+ * group databases open instead of having to open and close
+ * them all the time. Since sudo does a lot of password and
+ * group lookups, keeping the file open can speed things up.
+ */
+#ifdef HAVE_SETPASSENT
+ setpassent(1);
+#endif /* HAVE_SETPASSENT */
+#ifdef HAVE_SETGROUPENT
+ setgroupent(1);
+#endif /* HAVE_SETGROUPENT */
+
+ memset(ud, 0, sizeof(*ud));
+
+ /* XXX - bound check number of entries */
+ user_info = reallocarray(NULL, 32, sizeof(char *));
+ if (user_info == NULL)
+ goto oom;
+
+ ud->pid = getpid();
+ ud->ppid = getppid();
+ ud->pgid = getpgid(0);
+ ud->tcpgid = -1;
+ fd = open(_PATH_TTY, O_RDWR);
+ if (fd != -1) {
+ ud->tcpgid = tcgetpgrp(fd);
+ close(fd);
+ }
+ ud->sid = getsid(0);
+
+ ud->uid = getuid();
+ ud->euid = geteuid();
+ ud->gid = getgid();
+ ud->egid = getegid();
+
+#ifdef HAVE_SETAUTHDB
+ aix_setauthdb(IDtouser(ud->uid), NULL);
+#endif
+ pw = getpwuid(ud->uid);
+#ifdef HAVE_SETAUTHDB
+ aix_restoreauthdb();
+#endif
+ if (pw == NULL)
+ sudo_fatalx(U_("you do not exist in the %s database"), "passwd");
+
+ user_info[i] = sudo_new_key_val("user", pw->pw_name);
+ if (user_info[i] == NULL)
+ goto oom;
+ ud->username = user_info[i] + sizeof("user=") - 1;
+
+ /* Stash user's shell for use with the -s flag; don't pass to plugin. */
+ if ((ud->shell = getenv("SHELL")) == NULL || ud->shell[0] == '\0') {
+ ud->shell = pw->pw_shell[0] ? pw->pw_shell : _PATH_SUDO_BSHELL;
+ }
+ if ((ud->shell = strdup(ud->shell)) == NULL)
+ goto oom;
+
+ if (asprintf(&user_info[++i], "pid=%d", (int)ud->pid) == -1)
+ goto oom;
+ if (asprintf(&user_info[++i], "ppid=%d", (int)ud->ppid) == -1)
+ goto oom;
+ if (asprintf(&user_info[++i], "pgid=%d", (int)ud->pgid) == -1)
+ goto oom;
+ if (asprintf(&user_info[++i], "tcpgid=%d", (int)ud->tcpgid) == -1)
+ goto oom;
+ if (asprintf(&user_info[++i], "sid=%d", (int)ud->sid) == -1)
+ goto oom;
+ if (asprintf(&user_info[++i], "uid=%u", (unsigned int)ud->uid) == -1)
+ goto oom;
+ if (asprintf(&user_info[++i], "euid=%u", (unsigned int)ud->euid) == -1)
+ goto oom;
+ if (asprintf(&user_info[++i], "gid=%u", (unsigned int)ud->gid) == -1)
+ goto oom;
+ if (asprintf(&user_info[++i], "egid=%u", (unsigned int)ud->egid) == -1)
+ goto oom;
+
+ if ((cp = get_user_groups(ud)) == NULL)
+ goto oom;
+ user_info[++i] = cp;
+
+ mask = umask(0);
+ umask(mask);
+ if (asprintf(&user_info[++i], "umask=0%o", (unsigned int)mask) == -1)
+ goto oom;
+
+ if (getcwd(path, sizeof(path)) != NULL) {
+ user_info[++i] = sudo_new_key_val("cwd", path);
+ if (user_info[i] == NULL)
+ goto oom;
+ ud->cwd = user_info[i] + sizeof("cwd=") - 1;
+ }
+
+ if (get_process_ttyname(path, sizeof(path)) != NULL) {
+ user_info[++i] = sudo_new_key_val("tty", path);
+ if (user_info[i] == NULL)
+ goto oom;
+ ud->tty = user_info[i] + sizeof("tty=") - 1;
+ } else {
+ /* tty may not always be present */
+ if (errno != ENOENT)
+ sudo_warn(U_("unable to determine tty"));
+ }
+
+ cp = sudo_gethostname();
+ user_info[++i] = sudo_new_key_val("host", cp ? cp : "localhost");
+ free(cp);
+ if (user_info[i] == NULL)
+ goto oom;
+ ud->host = user_info[i] + sizeof("host=") - 1;
+
+ sudo_get_ttysize(&ud->ts_rows, &ud->ts_cols);
+ if (asprintf(&user_info[++i], "lines=%d", ud->ts_rows) == -1)
+ goto oom;
+ if (asprintf(&user_info[++i], "cols=%d", ud->ts_cols) == -1)
+ goto oom;
+
+ user_info[++i] = NULL;
+
+ /* Add to list of vectors to be garbage collected at exit. */
+ if (!gc_add(GC_VECTOR, user_info))
+ goto bad;
+
+ debug_return_ptr(user_info);
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+bad:
+ while (i--)
+ free(user_info[i]);
+ free(user_info);
+ debug_return_ptr(NULL);
+}
+
+/*
+ * Convert a command_info array into a command_details structure.
+ */
+static void
+command_info_to_details(char * const info[], struct command_details *details)
+{
+ int i;
+ id_t id;
+ char *cp;
+ const char *errstr;
+ debug_decl(command_info_to_details, SUDO_DEBUG_PCOMM)
+
+ memset(details, 0, sizeof(*details));
+ details->closefrom = -1;
+ details->execfd = -1;
+ details->flags = CD_SUDOEDIT_CHECKDIR | CD_SET_GROUPS;
+ TAILQ_INIT(&details->preserved_fds);
+
+#define SET_STRING(s, n) \
+ if (strncmp(s, info[i], sizeof(s) - 1) == 0 && info[i][sizeof(s) - 1]) { \
+ details->n = info[i] + sizeof(s) - 1; \
+ break; \
+ }
+#define SET_FLAG(s, n) \
+ if (strncmp(s, info[i], sizeof(s) - 1) == 0) { \
+ switch (sudo_strtobool(info[i] + sizeof(s) - 1)) { \
+ case true: \
+ SET(details->flags, n); \
+ break; \
+ case false: \
+ CLR(details->flags, n); \
+ break; \
+ default: \
+ sudo_debug_printf(SUDO_DEBUG_ERROR, \
+ "invalid boolean value for %s", info[i]); \
+ break; \
+ } \
+ break; \
+ }
+
+ sudo_debug_printf(SUDO_DEBUG_INFO, "command info from plugin:");
+ for (i = 0; info[i] != NULL; i++) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, " %d: %s", i, info[i]);
+ switch (info[i][0]) {
+ case 'c':
+ SET_STRING("chroot=", chroot)
+ SET_STRING("command=", command)
+ SET_STRING("cwd=", cwd)
+ if (strncmp("closefrom=", info[i], sizeof("closefrom=") - 1) == 0) {
+ cp = info[i] + sizeof("closefrom=") - 1;
+ details->closefrom = strtonum(cp, 0, INT_MAX, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
+ break;
+ }
+ break;
+ case 'e':
+ SET_FLAG("exec_background=", CD_EXEC_BG)
+ if (strncmp("execfd=", info[i], sizeof("execfd=") - 1) == 0) {
+ cp = info[i] + sizeof("execfd=") - 1;
+ details->execfd = strtonum(cp, 0, INT_MAX, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
+#ifdef HAVE_FEXECVE
+ /* Must keep fd open during exec. */
+ add_preserved_fd(&details->preserved_fds, details->execfd);
+#else
+ /* Plugin thinks we support fexecve() but we don't. */
+ (void)fcntl(details->execfd, F_SETFD, FD_CLOEXEC);
+ details->execfd = -1;
+#endif
+ break;
+ }
+ break;
+ case 'l':
+ SET_STRING("login_class=", login_class)
+ break;
+ case 'n':
+ if (strncmp("nice=", info[i], sizeof("nice=") - 1) == 0) {
+ cp = info[i] + sizeof("nice=") - 1;
+ details->priority = strtonum(cp, INT_MIN, INT_MAX, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
+ SET(details->flags, CD_SET_PRIORITY);
+ break;
+ }
+ SET_FLAG("noexec=", CD_NOEXEC)
+ break;
+ case 'p':
+ SET_FLAG("preserve_groups=", CD_PRESERVE_GROUPS)
+ if (strncmp("preserve_fds=", info[i], sizeof("preserve_fds=") - 1) == 0) {
+ parse_preserved_fds(&details->preserved_fds,
+ info[i] + sizeof("preserve_fds=") - 1);
+ break;
+ }
+ break;
+ case 'r':
+ if (strncmp("runas_egid=", info[i], sizeof("runas_egid=") - 1) == 0) {
+ cp = info[i] + sizeof("runas_egid=") - 1;
+ id = sudo_strtoid(cp, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
+ details->egid = (gid_t)id;
+ SET(details->flags, CD_SET_EGID);
+ break;
+ }
+ if (strncmp("runas_euid=", info[i], sizeof("runas_euid=") - 1) == 0) {
+ cp = info[i] + sizeof("runas_euid=") - 1;
+ id = sudo_strtoid(cp, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
+ details->euid = (uid_t)id;
+ SET(details->flags, CD_SET_EUID);
+ break;
+ }
+ if (strncmp("runas_gid=", info[i], sizeof("runas_gid=") - 1) == 0) {
+ cp = info[i] + sizeof("runas_gid=") - 1;
+ id = sudo_strtoid(cp, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
+ details->gid = (gid_t)id;
+ SET(details->flags, CD_SET_GID);
+ break;
+ }
+ if (strncmp("runas_groups=", info[i], sizeof("runas_groups=") - 1) == 0) {
+ cp = info[i] + sizeof("runas_groups=") - 1;
+ details->ngroups = sudo_parse_gids(cp, NULL, &details->groups);
+ /* sudo_parse_gids() will print a warning on error. */
+ if (details->ngroups == -1)
+ exit(EXIT_FAILURE); /* XXX */
+ break;
+ }
+ if (strncmp("runas_uid=", info[i], sizeof("runas_uid=") - 1) == 0) {
+ cp = info[i] + sizeof("runas_uid=") - 1;
+ id = sudo_strtoid(cp, NULL, NULL, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
+ details->uid = (uid_t)id;
+ SET(details->flags, CD_SET_UID);
+ break;
+ }
+#ifdef HAVE_PRIV_SET
+ if (strncmp("runas_privs=", info[i], sizeof("runas_privs=") - 1) == 0) {
+ const char *endp;
+ cp = info[i] + sizeof("runas_privs=") - 1;
+ if (*cp != '\0') {
+ details->privs = priv_str_to_set(cp, ",", &endp);
+ if (details->privs == NULL)
+ sudo_warn("invalid runas_privs %s", endp);
+ }
+ break;
+ }
+ if (strncmp("runas_limitprivs=", info[i], sizeof("runas_limitprivs=") - 1) == 0) {
+ const char *endp;
+ cp = info[i] + sizeof("runas_limitprivs=") - 1;
+ if (*cp != '\0') {
+ details->limitprivs = priv_str_to_set(cp, ",", &endp);
+ if (details->limitprivs == NULL)
+ sudo_warn("invalid runas_limitprivs %s", endp);
+ }
+ break;
+ }
+#endif /* HAVE_PRIV_SET */
+ break;
+ case 's':
+ SET_STRING("selinux_role=", selinux_role)
+ SET_STRING("selinux_type=", selinux_type)
+ SET_FLAG("set_utmp=", CD_SET_UTMP)
+ SET_FLAG("sudoedit=", CD_SUDOEDIT)
+ SET_FLAG("sudoedit_checkdir=", CD_SUDOEDIT_CHECKDIR)
+ SET_FLAG("sudoedit_follow=", CD_SUDOEDIT_FOLLOW)
+ break;
+ case 't':
+ if (strncmp("timeout=", info[i], sizeof("timeout=") - 1) == 0) {
+ cp = info[i] + sizeof("timeout=") - 1;
+ details->timeout = strtonum(cp, 0, INT_MAX, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
+ SET(details->flags, CD_SET_TIMEOUT);
+ break;
+ }
+ break;
+ case 'u':
+ if (strncmp("umask=", info[i], sizeof("umask=") - 1) == 0) {
+ cp = info[i] + sizeof("umask=") - 1;
+ details->umask = sudo_strtomode(cp, &errstr);
+ if (errstr != NULL)
+ sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
+ SET(details->flags, CD_SET_UMASK);
+ break;
+ }
+ SET_FLAG("use_pty=", CD_USE_PTY)
+ SET_STRING("utmp_user=", utmp_user)
+ break;
+ }
+ }
+
+ if (!ISSET(details->flags, CD_SET_EUID))
+ details->euid = details->uid;
+ if (!ISSET(details->flags, CD_SET_EGID))
+ details->egid = details->gid;
+
+#ifdef HAVE_SETAUTHDB
+ aix_setauthdb(IDtouser(details->euid), NULL);
+#endif
+ details->pw = getpwuid(details->euid);
+#ifdef HAVE_SETAUTHDB
+ aix_restoreauthdb();
+#endif
+ if (details->pw != NULL && (details->pw = pw_dup(details->pw)) == NULL)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+#ifdef HAVE_SELINUX
+ if (details->selinux_role != NULL && is_selinux_enabled() > 0)
+ SET(details->flags, CD_RBAC_ENABLED);
+#endif
+ debug_return;
+}
+
+static void
+sudo_check_suid(const char *sudo)
+{
+ char pathbuf[PATH_MAX];
+ struct stat sb;
+ bool qualified;
+ debug_decl(sudo_check_suid, SUDO_DEBUG_PCOMM)
+
+ if (geteuid() != ROOT_UID) {
+ /* Search for sudo binary in PATH if not fully qualified. */
+ qualified = strchr(sudo, '/') != NULL;
+ if (!qualified) {
+ char *path = getenv_unhooked("PATH");
+ if (path != NULL) {
+ const char *cp, *ep;
+ const char *pathend = path + strlen(path);
+
+ for (cp = sudo_strsplit(path, pathend, ":", &ep); cp != NULL;
+ cp = sudo_strsplit(NULL, pathend, ":", &ep)) {
+
+ int len = snprintf(pathbuf, sizeof(pathbuf), "%.*s/%s",
+ (int)(ep - cp), cp, sudo);
+ if (len <= 0 || (size_t)len >= sizeof(pathbuf))
+ continue;
+ if (access(pathbuf, X_OK) == 0) {
+ sudo = pathbuf;
+ qualified = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (qualified && stat(sudo, &sb) == 0) {
+ /* Try to determine why sudo was not running as root. */
+ if (sb.st_uid != ROOT_UID || !ISSET(sb.st_mode, S_ISUID)) {
+ sudo_fatalx(
+ U_("%s must be owned by uid %d and have the setuid bit set"),
+ sudo, ROOT_UID);
+ } else {
+ sudo_fatalx(U_("effective uid is not %d, is %s on a file system "
+ "with the 'nosuid' option set or an NFS file system without"
+ " root privileges?"), ROOT_UID, sudo);
+ }
+ } else {
+ sudo_fatalx(
+ U_("effective uid is not %d, is sudo installed setuid root?"),
+ ROOT_UID);
+ }
+ }
+ debug_return;
+}
+
+/*
+ * Disable core dumps to avoid dropping a core with user password in it.
+ * Called with restore set to true before executing the command.
+ * Not all operating systems disable core dumps for setuid processes.
+ */
+void
+disable_coredump(bool restore)
+{
+ struct rlimit rl;
+ static struct rlimit corelimit;
+#ifdef __linux__
+ static int dumpflag;
+#endif
+ debug_decl(disable_coredump, SUDO_DEBUG_UTIL)
+
+ if (restore) {
+ (void) setrlimit(RLIMIT_CORE, &corelimit);
+#ifdef __linux__
+ (void) prctl(PR_SET_DUMPABLE, dumpflag, 0, 0, 0);
+#endif /* __linux__ */
+ debug_return;
+ }
+
+ (void) getrlimit(RLIMIT_CORE, &corelimit);
+ rl.rlim_cur = 0;
+ rl.rlim_max = 0;
+ (void) setrlimit(RLIMIT_CORE, &rl);
+#ifdef __linux__
+ /* On Linux, also set PR_SET_DUMPABLE to zero (reset by execve). */
+ if ((dumpflag = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) == -1)
+ dumpflag = 0;
+ (void) prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
+#endif /* __linux__ */
+
+ debug_return;
+}
+
+bool
+set_user_groups(struct command_details *details)
+{
+ bool ret = false;
+ debug_decl(set_user_groups, SUDO_DEBUG_EXEC)
+
+ if (!ISSET(details->flags, CD_PRESERVE_GROUPS)) {
+ if (details->ngroups >= 0) {
+ if (sudo_setgroups(details->ngroups, details->groups) < 0) {
+ sudo_warn(U_("unable to set supplementary group IDs"));
+ goto done;
+ }
+ }
+ }
+#ifdef HAVE_SETEUID
+ if (ISSET(details->flags, CD_SET_EGID) && setegid(details->egid)) {
+ sudo_warn(U_("unable to set effective gid to runas gid %u"),
+ (unsigned int)details->egid);
+ goto done;
+ }
+#endif
+ if (ISSET(details->flags, CD_SET_GID) && setgid(details->gid)) {
+ sudo_warn(U_("unable to set gid to runas gid %u"),
+ (unsigned int)details->gid);
+ goto done;
+ }
+ ret = true;
+
+done:
+ CLR(details->flags, CD_SET_GROUPS);
+ debug_return_bool(ret);
+}
+
+/*
+ * Run the command and wait for it to complete.
+ * Returns wait status suitable for use with the wait(2) macros.
+ */
+int
+run_command(struct command_details *details)
+{
+ struct plugin_container *plugin;
+ struct command_status cstat;
+ int status = W_EXITCODE(1, 0);
+ debug_decl(run_command, SUDO_DEBUG_EXEC)
+
+ cstat.type = CMD_INVALID;
+ cstat.val = 0;
+
+ sudo_execute(details, &cstat);
+
+ switch (cstat.type) {
+ case CMD_ERRNO:
+ /* exec_setup() or execve() returned an error. */
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "calling policy close with errno %d", cstat.val);
+ policy_close(&policy_plugin, 0, cstat.val);
+ TAILQ_FOREACH(plugin, &io_plugins, entries) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "calling I/O close with errno %d", cstat.val);
+ iolog_close(plugin, 0, cstat.val);
+ }
+ break;
+ case CMD_WSTATUS:
+ /* Command ran, exited or was killed. */
+ status = cstat.val;
+#ifdef HAVE_SELINUX
+ if (ISSET(details->flags, CD_SUDOEDIT_COPY))
+ break;
+#endif
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "calling policy close with wait status %d", status);
+ policy_close(&policy_plugin, status, 0);
+ TAILQ_FOREACH(plugin, &io_plugins, entries) {
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
+ "calling I/O close with wait status %d", status);
+ iolog_close(plugin, status, 0);
+ }
+ break;
+ default:
+ sudo_warnx(U_("unexpected child termination condition: %d"), cstat.type);
+ break;
+ }
+ debug_return_int(status);
+}
+
+/*
+ * Format struct sudo_settings as name=value pairs for the plugin
+ * to consume. Returns a NULL-terminated plugin-style array of pairs.
+ */
+static char **
+format_plugin_settings(struct plugin_container *plugin,
+ struct sudo_settings *sudo_settings)
+{
+ size_t plugin_settings_size;
+ struct sudo_debug_file *debug_file;
+ struct sudo_settings *setting;
+ char **plugin_settings;
+ unsigned int i = 0;
+ debug_decl(format_plugin_settings, SUDO_DEBUG_PCOMM)
+
+ /* Determine sudo_settings array size (including plugin_path and NULL) */
+ plugin_settings_size = 2;
+ for (setting = sudo_settings; setting->name != NULL; setting++)
+ plugin_settings_size++;
+ if (plugin->debug_files != NULL) {
+ TAILQ_FOREACH(debug_file, plugin->debug_files, entries)
+ plugin_settings_size++;
+ }
+
+ /* Allocate and fill in. */
+ plugin_settings = reallocarray(NULL, plugin_settings_size, sizeof(char *));
+ if (plugin_settings == NULL)
+ goto bad;
+ plugin_settings[i] = sudo_new_key_val("plugin_path", plugin->path);
+ if (plugin_settings[i] == NULL)
+ goto bad;
+ for (setting = sudo_settings; setting->name != NULL; setting++) {
+ if (setting->value != NULL) {
+ sudo_debug_printf(SUDO_DEBUG_INFO, "settings: %s=%s",
+ setting->name, setting->value);
+ plugin_settings[++i] =
+ sudo_new_key_val(setting->name, setting->value);
+ if (plugin_settings[i] == NULL)
+ goto bad;
+ }
+ }
+ if (plugin->debug_files != NULL) {
+ TAILQ_FOREACH(debug_file, plugin->debug_files, entries) {
+ /* XXX - quote filename? */
+ if (asprintf(&plugin_settings[++i], "debug_flags=%s %s",
+ debug_file->debug_file, debug_file->debug_flags) == -1)
+ goto bad;
+ }
+ }
+ plugin_settings[++i] = NULL;
+
+ /* Add to list of vectors to be garbage collected at exit. */
+ if (!gc_add(GC_VECTOR, plugin_settings))
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+
+ debug_return_ptr(plugin_settings);
+bad:
+ while (i--)
+ free(plugin_settings[i]);
+ free(plugin_settings);
+ debug_return_ptr(NULL);
+}
+
+static int
+policy_open(struct plugin_container *plugin, struct sudo_settings *settings,
+ char * const user_info[], char * const user_env[])
+{
+ char **plugin_settings;
+ int ret;
+ debug_decl(policy_open, SUDO_DEBUG_PCOMM)
+
+ /* Convert struct sudo_settings to plugin_settings[] */
+ plugin_settings = format_plugin_settings(plugin, settings);
+ if (plugin_settings == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+
+ /*
+ * Backwards compatibility for older API versions
+ */
+ sudo_debug_set_active_instance(SUDO_DEBUG_INSTANCE_INITIALIZER);
+ switch (plugin->u.generic->version) {
+ case SUDO_API_MKVERSION(1, 0):
+ case SUDO_API_MKVERSION(1, 1):
+ ret = plugin->u.policy_1_0->open(plugin->u.io_1_0->version,
+ sudo_conversation_1_7, sudo_conversation_printf, plugin_settings,
+ user_info, user_env);
+ break;
+ default:
+ ret = plugin->u.policy->open(SUDO_API_VERSION, sudo_conversation,
+ sudo_conversation_printf, plugin_settings, user_info, user_env,
+ plugin->options);
+ }
+
+ /* Stash plugin debug instance ID if set in open() function. */
+ plugin->debug_instance = sudo_debug_get_active_instance();
+ sudo_debug_set_active_instance(sudo_debug_instance);
+
+ debug_return_int(ret);
+}
+
+static void
+policy_close(struct plugin_container *plugin, int exit_status, int error_code)
+{
+ debug_decl(policy_close, SUDO_DEBUG_PCOMM)
+ if (plugin->u.policy->close != NULL) {
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ plugin->u.policy->close(exit_status, error_code);
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ } else if (error_code) {
+ errno = error_code;
+ sudo_warn(U_("unable to execute %s"), command_details.command);
+ }
+ debug_return;
+}
+
+static int
+policy_show_version(struct plugin_container *plugin, int verbose)
+{
+ int ret;
+ debug_decl(policy_show_version, SUDO_DEBUG_PCOMM)
+
+ if (plugin->u.policy->show_version == NULL)
+ debug_return_int(true);
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ ret = plugin->u.policy->show_version(verbose);
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ debug_return_int(ret);
+}
+
+static int
+policy_check(struct plugin_container *plugin, int argc, char * const argv[],
+ char *env_add[], char **command_info[], char **argv_out[],
+ char **user_env_out[])
+{
+ int ret;
+ debug_decl(policy_check, SUDO_DEBUG_PCOMM)
+
+ if (plugin->u.policy->check_policy == NULL) {
+ sudo_fatalx(U_("policy plugin %s is missing the `check_policy' method"),
+ plugin->name);
+ }
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ ret = plugin->u.policy->check_policy(argc, argv, env_add, command_info,
+ argv_out, user_env_out);
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ debug_return_int(ret);
+}
+
+static int
+policy_list(struct plugin_container *plugin, int argc, char * const argv[],
+ int verbose, const char *list_user)
+{
+ int ret;
+ debug_decl(policy_list, SUDO_DEBUG_PCOMM)
+
+ if (plugin->u.policy->list == NULL) {
+ sudo_warnx(U_("policy plugin %s does not support listing privileges"),
+ plugin->name);
+ debug_return_int(false);
+ }
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ ret = plugin->u.policy->list(argc, argv, verbose, list_user);
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ debug_return_int(ret);
+}
+
+static int
+policy_validate(struct plugin_container *plugin)
+{
+ int ret;
+ debug_decl(policy_validate, SUDO_DEBUG_PCOMM)
+
+ if (plugin->u.policy->validate == NULL) {
+ sudo_warnx(U_("policy plugin %s does not support the -v option"),
+ plugin->name);
+ debug_return_int(false);
+ }
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ ret = plugin->u.policy->validate();
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ debug_return_int(ret);
+}
+
+static void
+policy_invalidate(struct plugin_container *plugin, int remove)
+{
+ debug_decl(policy_invalidate, SUDO_DEBUG_PCOMM)
+ if (plugin->u.policy->invalidate == NULL) {
+ sudo_fatalx(U_("policy plugin %s does not support the -k/-K options"),
+ plugin->name);
+ }
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ plugin->u.policy->invalidate(remove);
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ debug_return;
+}
+
+int
+policy_init_session(struct command_details *details)
+{
+ int ret = true;
+ debug_decl(policy_init_session, SUDO_DEBUG_PCOMM)
+
+ /*
+ * We set groups, including supplementary group vector,
+ * as part of the session setup. This allows for dynamic
+ * groups to be set via pam_group(8) in pam_setcred(3).
+ */
+ if (ISSET(details->flags, CD_SET_GROUPS)) {
+ /* set_user_groups() prints error message on failure. */
+ if (!set_user_groups(details))
+ goto done;
+ }
+
+ if (policy_plugin.u.policy->init_session) {
+ /*
+ * Backwards compatibility for older API versions
+ */
+ sudo_debug_set_active_instance(policy_plugin.debug_instance);
+ switch (policy_plugin.u.generic->version) {
+ case SUDO_API_MKVERSION(1, 0):
+ case SUDO_API_MKVERSION(1, 1):
+ ret = policy_plugin.u.policy_1_0->init_session(details->pw);
+ break;
+ default:
+ ret = policy_plugin.u.policy->init_session(details->pw,
+ &details->envp);
+ }
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ }
+done:
+ debug_return_int(ret);
+}
+
+static int
+iolog_open(struct plugin_container *plugin, struct sudo_settings *settings,
+ char * const user_info[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[])
+{
+ char **plugin_settings;
+ int ret;
+ debug_decl(iolog_open, SUDO_DEBUG_PCOMM)
+
+ /* Convert struct sudo_settings to plugin_settings[] */
+ plugin_settings = format_plugin_settings(plugin, settings);
+ if (plugin_settings == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+
+ /*
+ * Backwards compatibility for older API versions
+ */
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ switch (plugin->u.generic->version) {
+ case SUDO_API_MKVERSION(1, 0):
+ ret = plugin->u.io_1_0->open(plugin->u.io_1_0->version,
+ sudo_conversation_1_7, sudo_conversation_printf, plugin_settings,
+ user_info, argc, argv, user_env);
+ break;
+ case SUDO_API_MKVERSION(1, 1):
+ ret = plugin->u.io_1_1->open(plugin->u.io_1_1->version,
+ sudo_conversation_1_7, sudo_conversation_printf, plugin_settings,
+ user_info, command_info, argc, argv, user_env);
+ break;
+ default:
+ ret = plugin->u.io->open(SUDO_API_VERSION, sudo_conversation,
+ sudo_conversation_printf, plugin_settings, user_info, command_info,
+ argc, argv, user_env, plugin->options);
+ }
+
+ /* Stash plugin debug instance ID if set in open() function. */
+ plugin->debug_instance = sudo_debug_get_active_instance();
+ sudo_debug_set_active_instance(sudo_debug_instance);
+
+ debug_return_int(ret);
+}
+
+static void
+iolog_close(struct plugin_container *plugin, int exit_status, int error_code)
+{
+ debug_decl(iolog_close, SUDO_DEBUG_PCOMM)
+
+ if (plugin->u.io->close != NULL) {
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ plugin->u.io->close(exit_status, error_code);
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ }
+ debug_return;
+}
+
+static int
+iolog_show_version(struct plugin_container *plugin, int verbose)
+{
+ int ret;
+ debug_decl(iolog_show_version, SUDO_DEBUG_PCOMM)
+
+ if (plugin->u.io->show_version == NULL)
+ debug_return_int(true);
+
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ ret = plugin->u.io->show_version(verbose);
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ debug_return_int(ret);
+}
+
+/*
+ * Remove the specified I/O logging plugin from the io_plugins list.
+ * Deregisters any hooks before unlinking, then frees the container.
+ */
+static void
+iolog_unlink(struct plugin_container *plugin)
+{
+ debug_decl(iolog_unlink, SUDO_DEBUG_PCOMM)
+
+ /* Deregister hooks, if any. */
+ if (plugin->u.io->version >= SUDO_API_MKVERSION(1, 2)) {
+ if (plugin->u.io->deregister_hooks != NULL) {
+ sudo_debug_set_active_instance(plugin->debug_instance);
+ plugin->u.io->deregister_hooks(SUDO_HOOK_VERSION,
+ deregister_hook);
+ sudo_debug_set_active_instance(sudo_debug_instance);
+ }
+ }
+ /* Remove from io_plugins list and free. */
+ TAILQ_REMOVE(&io_plugins, plugin, entries);
+ free_plugin_container(plugin, true);
+
+ debug_return;
+}
+
+static void
+free_plugin_container(struct plugin_container *plugin, bool ioplugin)
+{
+ debug_decl(free_plugin_container, SUDO_DEBUG_PLUGIN)
+
+ free(plugin->path);
+ free(plugin->name);
+ if (plugin->options != NULL) {
+ int i = 0;
+ while (plugin->options[i] != NULL)
+ free(plugin->options[i++]);
+ free(plugin->options);
+ }
+ if (ioplugin)
+ free(plugin);
+
+ debug_return;
+}
+
+bool
+gc_add(enum sudo_gc_types type, void *v)
+{
+#ifdef NO_LEAKS
+ struct sudo_gc_entry *gc;
+ debug_decl(gc_add, SUDO_DEBUG_MAIN)
+
+ if (v == NULL)
+ debug_return_bool(false);
+
+ gc = calloc(1, sizeof(*gc));
+ if (gc == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
+ switch (type) {
+ case GC_PTR:
+ gc->u.ptr = v;
+ break;
+ case GC_VECTOR:
+ gc->u.vec = v;
+ break;
+ default:
+ free(gc);
+ sudo_warnx("unexpected garbage type %d", type);
+ debug_return_bool(false);
+ }
+ gc->type = type;
+ SLIST_INSERT_HEAD(&sudo_gc_list, gc, entries);
+ debug_return_bool(true);
+#else
+ return true;
+#endif /* NO_LEAKS */
+}
+
+#ifdef NO_LEAKS
+static void
+gc_run(void)
+{
+ struct plugin_container *plugin;
+ struct sudo_gc_entry *gc;
+ char **cur;
+ debug_decl(gc_run, SUDO_DEBUG_MAIN)
+
+ /* Collect garbage. */
+ while ((gc = SLIST_FIRST(&sudo_gc_list))) {
+ SLIST_REMOVE_HEAD(&sudo_gc_list, entries);
+ switch (gc->type) {
+ case GC_PTR:
+ free(gc->u.ptr);
+ free(gc);
+ break;
+ case GC_VECTOR:
+ for (cur = gc->u.vec; *cur != NULL; cur++)
+ free(*cur);
+ free(gc->u.vec);
+ free(gc);
+ break;
+ default:
+ sudo_warnx("unexpected garbage type %d", gc->type);
+ }
+ }
+
+ /* Free plugin structs. */
+ free_plugin_container(&policy_plugin, false);
+ while ((plugin = TAILQ_FIRST(&io_plugins))) {
+ TAILQ_REMOVE(&io_plugins, plugin, entries);
+ free_plugin_container(plugin, true);
+ }
+
+ debug_return;
+}
+#endif /* NO_LEAKS */
+
+static void
+gc_init(void)
+{
+#ifdef NO_LEAKS
+ atexit(gc_run);
+#endif
+}
diff --git a/src/sudo.h b/src/sudo.h
new file mode 100644
index 0000000..1d8e672
--- /dev/null
+++ b/src/sudo.h
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 1993-1996, 1998-2005, 2007-2016
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#ifndef SUDO_SUDO_H
+#define SUDO_SUDO_H
+
+#include <limits.h>
+#include <pathnames.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
+
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
+
+#include "sudo_compat.h"
+#include "sudo_fatal.h"
+#include "sudo_conf.h"
+#include "sudo_debug.h"
+#include "sudo_util.h"
+
+#ifdef HAVE_PRIV_SET
+# include <priv.h>
+#endif
+
+#ifdef __TANDEM
+# define ROOT_UID 65535
+#else
+# define ROOT_UID 0
+#endif
+
+/*
+ * Various modes sudo can be in (based on arguments) in hex
+ */
+#define MODE_RUN 0x00000001
+#define MODE_EDIT 0x00000002
+#define MODE_VALIDATE 0x00000004
+#define MODE_INVALIDATE 0x00000008
+#define MODE_KILL 0x00000010
+#define MODE_VERSION 0x00000020
+#define MODE_HELP 0x00000040
+#define MODE_LIST 0x00000080
+#define MODE_CHECK 0x00000100
+#define MODE_MASK 0x0000ffff
+
+/* Mode flags */
+/* XXX - prune this */
+#define MODE_BACKGROUND 0x00010000
+#define MODE_SHELL 0x00020000
+#define MODE_LOGIN_SHELL 0x00040000
+#define MODE_IMPLIED_SHELL 0x00080000
+#define MODE_RESET_HOME 0x00100000
+#define MODE_PRESERVE_GROUPS 0x00200000
+#define MODE_PRESERVE_ENV 0x00400000
+#define MODE_NONINTERACTIVE 0x00800000
+#define MODE_LONG_LIST 0x01000000
+
+/*
+ * Flags for tgetpass()
+ */
+#define TGP_NOECHO 0x00 /* turn echo off reading pw (default) */
+#define TGP_ECHO 0x01 /* leave echo on when reading passwd */
+#define TGP_STDIN 0x02 /* read from stdin, not /dev/tty */
+#define TGP_ASKPASS 0x04 /* read from askpass helper program */
+#define TGP_MASK 0x08 /* mask user input when reading */
+#define TGP_NOECHO_TRY 0x10 /* turn off echo if possible */
+
+/* name/value pairs for command line settings. */
+struct sudo_settings {
+ const char *name;
+ const char *value;
+};
+
+struct user_details {
+ pid_t pid;
+ pid_t ppid;
+ pid_t pgid;
+ pid_t tcpgid;
+ pid_t sid;
+ uid_t uid;
+ uid_t euid;
+ uid_t gid;
+ uid_t egid;
+ const char *username;
+ const char *cwd;
+ const char *tty;
+ const char *host;
+ const char *shell;
+ GETGROUPS_T *groups;
+ int ngroups;
+ int ts_rows;
+ int ts_cols;
+};
+
+#define CD_SET_UID 0x00001
+#define CD_SET_EUID 0x00002
+#define CD_SET_GID 0x00004
+#define CD_SET_EGID 0x00008
+#define CD_PRESERVE_GROUPS 0x00010
+#define CD_NOEXEC 0x00020
+#define CD_SET_PRIORITY 0x00040
+#define CD_SET_UMASK 0x00080
+#define CD_SET_TIMEOUT 0x00100
+#define CD_SUDOEDIT 0x00200
+#define CD_BACKGROUND 0x00400
+#define CD_RBAC_ENABLED 0x00800
+#define CD_USE_PTY 0x01000
+#define CD_SET_UTMP 0x02000
+#define CD_EXEC_BG 0x04000
+#define CD_SUDOEDIT_COPY 0x08000
+#define CD_SUDOEDIT_FOLLOW 0x10000
+#define CD_SUDOEDIT_CHECKDIR 0x20000
+#define CD_SET_GROUPS 0x40000
+#define CD_LOGIN_SHELL 0x80000
+
+struct preserved_fd {
+ TAILQ_ENTRY(preserved_fd) entries;
+ int lowfd;
+ int highfd;
+ int flags;
+};
+TAILQ_HEAD(preserved_fd_list, preserved_fd);
+
+struct command_details {
+ uid_t uid;
+ uid_t euid;
+ gid_t gid;
+ gid_t egid;
+ mode_t umask;
+ int priority;
+ int timeout;
+ int ngroups;
+ int closefrom;
+ int flags;
+ int execfd;
+ struct preserved_fd_list preserved_fds;
+ struct passwd *pw;
+ GETGROUPS_T *groups;
+ const char *command;
+ const char *cwd;
+ const char *login_class;
+ const char *chroot;
+ const char *selinux_role;
+ const char *selinux_type;
+ const char *utmp_user;
+ char **argv;
+ char **envp;
+#ifdef HAVE_PRIV_SET
+ priv_set_t *privs;
+ priv_set_t *limitprivs;
+#endif
+};
+
+/* Status passed between parent and child via socketpair */
+struct command_status {
+#define CMD_INVALID 0
+#define CMD_ERRNO 1
+#define CMD_WSTATUS 2
+#define CMD_SIGNO 3
+#define CMD_PID 4
+#define CMD_TTYWINCH 5
+ int type;
+ int val;
+};
+
+/* Garbage collector data types. */
+enum sudo_gc_types {
+ GC_UNKNOWN,
+ GC_VECTOR,
+ GC_PTR
+};
+
+/* For fatal() and fatalx() (XXX - needed?) */
+void cleanup(int);
+
+/* tgetpass.c */
+char *tgetpass(const char *prompt, int timeout, int flags,
+ struct sudo_conv_callback *callback);
+
+/* exec.c */
+int sudo_execute(struct command_details *details, struct command_status *cstat);
+
+/* parse_args.c */
+int parse_args(int argc, char **argv, int *nargc, char ***nargv,
+ struct sudo_settings **settingsp, char ***env_addp);
+extern int tgetpass_flags;
+
+/* get_pty.c */
+bool get_pty(int *master, int *slave, char *name, size_t namesz, uid_t uid);
+
+/* sudo.c */
+int policy_init_session(struct command_details *details);
+int run_command(struct command_details *details);
+int os_init_common(int argc, char *argv[], char *envp[]);
+bool gc_add(enum sudo_gc_types type, void *v);
+void disable_coredump(bool restore);
+bool set_user_groups(struct command_details *details);
+extern const char *list_user;
+extern struct user_details user_details;
+extern int sudo_debug_instance;
+
+/* sudo_edit.c */
+int sudo_edit(struct command_details *details);
+
+/* parse_args.c */
+void usage(int);
+
+/* openbsd.c */
+int os_init_openbsd(int argc, char *argv[], char *envp[]);
+
+/* selinux.c */
+int selinux_restore_tty(void);
+int selinux_setup(const char *role, const char *type, const char *ttyn,
+ int ttyfd);
+void selinux_execve(int fd, const char *path, char *const argv[],
+ char *envp[], bool noexec);
+
+/* solaris.c */
+void set_project(struct passwd *);
+int os_init_solaris(int argc, char *argv[], char *envp[]);
+
+/* hooks.c */
+/* XXX - move to sudo_plugin_int.h? */
+struct sudo_hook;
+int register_hook(struct sudo_hook *hook);
+int deregister_hook(struct sudo_hook *hook);
+int process_hooks_getenv(const char *name, char **val);
+int process_hooks_setenv(const char *name, const char *value, int overwrite);
+int process_hooks_putenv(char *string);
+int process_hooks_unsetenv(const char *name);
+
+/* env_hooks.c */
+char *getenv_unhooked(const char *name);
+
+/* interfaces.c */
+int get_net_ifs(char **addrinfo);
+
+/* ttyname.c */
+char *get_process_ttyname(char *name, size_t namelen);
+
+/* signal.c */
+struct sigaction;
+int sudo_sigaction(int signo, struct sigaction *sa, struct sigaction *osa);
+void init_signals(void);
+void restore_signals(void);
+void save_signals(void);
+bool signal_pending(int signo);
+
+/* preload.c */
+void preload_static_symbols(void);
+
+/* preserve_fds.c */
+int add_preserved_fd(struct preserved_fd_list *pfds, int fd);
+void closefrom_except(int startfd, struct preserved_fd_list *pfds);
+void parse_preserved_fds(struct preserved_fd_list *pfds, const char *fdstr);
+
+/* setpgrp_nobg.c */
+int tcsetpgrp_nobg(int fd, pid_t pgrp_id);
+
+#endif /* SUDO_SUDO_H */
diff --git a/src/sudo_edit.c b/src/sudo_edit.c
new file mode 100644
index 0000000..44b4fb3
--- /dev/null
+++ b/src/sudo_edit.c
@@ -0,0 +1,1101 @@
+/*
+ * Copyright (c) 2004-2008, 2010-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <time.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <grp.h>
+#include <pwd.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "sudo.h"
+#include "sudo_exec.h"
+
+#if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
+
+/*
+ * Editor temporary file name along with original name, mtime and size.
+ */
+struct tempfile {
+ char *tfile;
+ char *ofile;
+ off_t osize;
+ struct timespec omtim;
+};
+
+static char edit_tmpdir[MAX(sizeof(_PATH_VARTMP), sizeof(_PATH_TMP))];
+
+static void
+switch_user(uid_t euid, gid_t egid, int ngroups, GETGROUPS_T *groups)
+{
+ int serrno = errno;
+ debug_decl(switch_user, SUDO_DEBUG_EDIT)
+
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "set uid:gid to %u:%u(%u)", (unsigned int)euid, (unsigned int)egid,
+ ngroups ? (unsigned int)groups[0] : (unsigned int)egid);
+
+ /* When restoring root, change euid first; otherwise change it last. */
+ if (euid == ROOT_UID) {
+ if (seteuid(ROOT_UID) != 0)
+ sudo_fatal("seteuid(ROOT_UID)");
+ }
+ if (setegid(egid) != 0)
+ sudo_fatal("setegid(%d)", (int)egid);
+ if (ngroups != -1) {
+ if (sudo_setgroups(ngroups, groups) != 0)
+ sudo_fatal("setgroups");
+ }
+ if (euid != ROOT_UID) {
+ if (seteuid(euid) != 0)
+ sudo_fatal("seteuid(%u)", (unsigned int)euid);
+ }
+ errno = serrno;
+
+ debug_return;
+}
+
+#ifdef HAVE_FACCESSAT
+/*
+ * Returns true if the open directory fd is writable by the user.
+ */
+static int
+dir_is_writable(int dfd, struct user_details *ud, struct command_details *cd)
+{
+ debug_decl(dir_is_writable, SUDO_DEBUG_EDIT)
+ int rc;
+
+ /* Change uid/gid/groups to invoking user, usually needs root perms. */
+ if (cd->euid != ROOT_UID) {
+ if (seteuid(ROOT_UID) != 0)
+ sudo_fatal("seteuid(ROOT_UID)");
+ }
+ switch_user(ud->uid, ud->gid, ud->ngroups, ud->groups);
+
+ /* Access checks are done using the euid/egid and group vector. */
+ rc = faccessat(dfd, ".", W_OK, AT_EACCESS);
+
+ /* Change uid/gid/groups back to target user, may need root perms. */
+ if (ud->uid != ROOT_UID) {
+ if (seteuid(ROOT_UID) != 0)
+ sudo_fatal("seteuid(ROOT_UID)");
+ }
+ switch_user(cd->euid, cd->egid, cd->ngroups, cd->groups);
+
+ if (rc == 0)
+ debug_return_int(true);
+ if (errno == EACCES)
+ debug_return_int(false);
+ debug_return_int(-1);
+}
+#else
+static bool
+group_matches(gid_t target, gid_t gid, int ngroups, GETGROUPS_T *groups)
+{
+ int i;
+ debug_decl(group_matches, SUDO_DEBUG_EDIT)
+
+ if (target == gid) {
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "user gid %u matches directory gid %u", (unsigned int)gid,
+ (unsigned int)target);
+ debug_return_bool(true);
+ }
+ for (i = 0; i < ngroups; i++) {
+ if (target == groups[i]) {
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "user gid %u matches directory gid %u", (unsigned int)gid,
+ (unsigned int)target);
+ debug_return_bool(true);
+ }
+ }
+ debug_return_bool(false);
+}
+
+/*
+ * Returns true if the open directory fd is writable by the user.
+ */
+static int
+dir_is_writable(int dfd, struct user_details *ud, struct command_details *cd)
+{
+ struct stat sb;
+ debug_decl(dir_is_writable, SUDO_DEBUG_EDIT)
+
+ if (fstat(dfd, &sb) == -1)
+ debug_return_int(-1);
+
+ /* If the user owns the dir we always consider it writable. */
+ if (sb.st_uid == ud->uid) {
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "user uid %u matches directory uid %u", (unsigned int)ud->uid,
+ (unsigned int)sb.st_uid);
+ debug_return_int(true);
+ }
+
+ /* Other writable? */
+ if (ISSET(sb.st_mode, S_IWOTH)) {
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "directory is writable by other");
+ debug_return_int(true);
+ }
+
+ /* Group writable? */
+ if (ISSET(sb.st_mode, S_IWGRP)) {
+ if (group_matches(sb.st_gid, ud->gid, ud->ngroups, ud->groups)) {
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "directory is writable by one of the user's groups");
+ debug_return_int(true);
+ }
+ }
+
+ errno = EACCES;
+ debug_return_int(false);
+}
+#endif /* HAVE_FACCESSAT */
+
+/*
+ * Find our temporary directory, one of /var/tmp, /usr/tmp, or /tmp
+ * Returns true on success, else false;
+ */
+static bool
+set_tmpdir(struct command_details *command_details)
+{
+ const char *tdir = NULL;
+ const char *tmpdirs[] = {
+ _PATH_VARTMP,
+#ifdef _PATH_USRTMP
+ _PATH_USRTMP,
+#endif
+ _PATH_TMP
+ };
+ unsigned int i;
+ size_t len;
+ int dfd;
+ debug_decl(set_tmpdir, SUDO_DEBUG_EDIT)
+
+ for (i = 0; tdir == NULL && i < nitems(tmpdirs); i++) {
+ if ((dfd = open(tmpdirs[i], O_RDONLY)) != -1) {
+ if (dir_is_writable(dfd, &user_details, command_details) == true)
+ tdir = tmpdirs[i];
+ close(dfd);
+ }
+ }
+ if (tdir == NULL)
+ sudo_fatalx(U_("no writable temporary directory found"));
+
+ len = strlcpy(edit_tmpdir, tdir, sizeof(edit_tmpdir));
+ if (len >= sizeof(edit_tmpdir)) {
+ errno = ENAMETOOLONG;
+ sudo_warn("%s", tdir);
+ debug_return_bool(false);
+ }
+ while (len > 0 && edit_tmpdir[--len] == '/')
+ edit_tmpdir[len] = '\0';
+ debug_return_bool(true);
+}
+
+/*
+ * Construct a temporary file name for file and return an
+ * open file descriptor. The temporary file name is stored
+ * in tfile which the caller is responsible for freeing.
+ */
+static int
+sudo_edit_mktemp(const char *ofile, char **tfile)
+{
+ const char *cp, *suff;
+ int len, tfd;
+ debug_decl(sudo_edit_mktemp, SUDO_DEBUG_EDIT)
+
+ if ((cp = strrchr(ofile, '/')) != NULL)
+ cp++;
+ else
+ cp = ofile;
+ suff = strrchr(cp, '.');
+ if (suff != NULL) {
+ len = asprintf(tfile, "%s/%.*sXXXXXXXX%s", edit_tmpdir,
+ (int)(size_t)(suff - cp), cp, suff);
+ } else {
+ len = asprintf(tfile, "%s/%s.XXXXXXXX", edit_tmpdir, cp);
+ }
+ if (len == -1)
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ tfd = mkstemps(*tfile, suff ? strlen(suff) : 0);
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "%s -> %s, fd %d", ofile, *tfile, tfd);
+ debug_return_int(tfd);
+}
+
+#ifndef HAVE_OPENAT
+static int
+sudo_openat(int dfd, const char *path, int flags, mode_t mode)
+{
+ int fd, odfd;
+ debug_decl(sudo_openat, SUDO_DEBUG_EDIT)
+
+ if (dfd == AT_FDCWD)
+ debug_return_int(open(path, flags, mode));
+
+ /* Save cwd */
+ if ((odfd = open(".", O_RDONLY)) == -1)
+ debug_return_int(-1);
+
+ if (fchdir(dfd) == -1) {
+ close(odfd);
+ debug_return_int(-1);
+ }
+
+ fd = open(path, flags, mode);
+
+ /* Restore cwd */
+ if (fchdir(odfd) == -1)
+ sudo_fatal(U_("unable to restore current working directory"));
+ close(odfd);
+
+ debug_return_int(fd);
+}
+#define openat sudo_openat
+#endif /* HAVE_OPENAT */
+
+#ifdef O_NOFOLLOW
+static int
+sudo_edit_openat_nofollow(int dfd, char *path, int oflags, mode_t mode)
+{
+ debug_decl(sudo_edit_openat_nofollow, SUDO_DEBUG_EDIT)
+
+ debug_return_int(openat(dfd, path, oflags|O_NOFOLLOW, mode));
+}
+#else
+/*
+ * Returns true if fd and path don't match or path is a symlink.
+ * Used on older systems without O_NOFOLLOW.
+ */
+static bool
+sudo_edit_is_symlink(int fd, char *path)
+{
+ struct stat sb1, sb2;
+ debug_decl(sudo_edit_is_symlink, SUDO_DEBUG_EDIT)
+
+ /*
+ * Treat [fl]stat() failure like there was a symlink.
+ */
+ if (fstat(fd, &sb1) == -1 || lstat(path, &sb2) == -1)
+ debug_return_bool(true);
+
+ /*
+ * Make sure we did not open a link and that what we opened
+ * matches what is currently on the file system.
+ */
+ if (S_ISLNK(sb2.st_mode) ||
+ sb1.st_dev != sb2.st_dev || sb1.st_ino != sb2.st_ino) {
+ debug_return_bool(true);
+ }
+
+ debug_return_bool(false);
+}
+
+static int
+sudo_edit_openat_nofollow(int dfd, char *path, int oflags, mode_t mode)
+{
+ int fd = -1, odfd = -1;
+ struct stat sb;
+ debug_decl(sudo_edit_openat_nofollow, SUDO_DEBUG_EDIT)
+
+ /* Save cwd and chdir to dfd */
+ if ((odfd = open(".", O_RDONLY)) == -1)
+ debug_return_int(-1);
+ if (fchdir(dfd) == -1) {
+ close(odfd);
+ debug_return_int(-1);
+ }
+
+ /*
+ * Check if path is a symlink. This is racey but we detect whether
+ * we lost the race in sudo_edit_is_symlink() after the open.
+ */
+ if (lstat(path, &sb) == -1 && errno != ENOENT)
+ goto done;
+ if (S_ISLNK(sb.st_mode)) {
+ errno = ELOOP;
+ goto done;
+ }
+
+ fd = open(path, oflags, mode);
+ if (fd == -1)
+ goto done;
+
+ /*
+ * Post-open symlink check. This will leave a zero-length file if
+ * O_CREAT was specified but it is too dangerous to try and remove it.
+ */
+ if (sudo_edit_is_symlink(fd, path)) {
+ close(fd);
+ fd = -1;
+ errno = ELOOP;
+ }
+
+done:
+ /* Restore cwd */
+ if (odfd != -1) {
+ if (fchdir(odfd) == -1)
+ sudo_fatal(U_("unable to restore current working directory"));
+ close(odfd);
+ }
+
+ debug_return_int(fd);
+}
+#endif /* O_NOFOLLOW */
+
+/*
+ * Directory open flags for use with openat(2).
+ * Use O_SEARCH/O_PATH and/or O_DIRECTORY where possible.
+ */
+#if defined(O_SEARCH)
+# if defined(O_DIRECTORY)
+# define DIR_OPEN_FLAGS (O_SEARCH|O_DIRECTORY)
+# else
+# define DIR_OPEN_FLAGS (O_SEARCH)
+# endif
+#elif defined(O_PATH)
+# if defined(O_DIRECTORY)
+# define DIR_OPEN_FLAGS (O_PATH|O_DIRECTORY)
+# else
+# define DIR_OPEN_FLAGS (O_PATH)
+# endif
+#elif defined(O_DIRECTORY)
+# define DIR_OPEN_FLAGS (O_RDONLY|O_DIRECTORY)
+#else
+# define DIR_OPEN_FLAGS (O_RDONLY|O_NONBLOCK)
+#endif
+
+static int
+sudo_edit_open_nonwritable(char *path, int oflags, mode_t mode,
+ struct command_details *command_details)
+{
+ const int dflags = DIR_OPEN_FLAGS;
+ int dfd, fd, is_writable;
+ debug_decl(sudo_edit_open_nonwritable, SUDO_DEBUG_EDIT)
+
+ if (path[0] == '/') {
+ dfd = open("/", dflags);
+ path++;
+ } else {
+ dfd = open(".", dflags);
+ if (path[0] == '.' && path[1] == '/')
+ path += 2;
+ }
+ if (dfd == -1)
+ debug_return_int(-1);
+
+ for (;;) {
+ char *slash;
+ int subdfd;
+
+ /*
+ * Look up one component at a time, avoiding symbolic links in
+ * writable directories.
+ */
+ is_writable = dir_is_writable(dfd, &user_details, command_details);
+ if (is_writable == -1) {
+ close(dfd);
+ debug_return_int(-1);
+ }
+
+ while (path[0] == '/')
+ path++;
+ slash = strchr(path, '/');
+ if (slash == NULL)
+ break;
+ *slash = '\0';
+ if (is_writable)
+ subdfd = sudo_edit_openat_nofollow(dfd, path, dflags, 0);
+ else
+ subdfd = openat(dfd, path, dflags, 0);
+ *slash = '/'; /* restore path */
+ close(dfd);
+ if (subdfd == -1)
+ debug_return_int(-1);
+ path = slash + 1;
+ dfd = subdfd;
+ }
+
+ if (is_writable) {
+ close(dfd);
+ errno = EISDIR;
+ debug_return_int(-1);
+ }
+
+ /*
+ * For "sudoedit /" we will receive ENOENT from openat() and sudoedit
+ * will try to create a file with an empty name. We treat an empty
+ * path as the cwd so sudoedit can give a sensible error message.
+ */
+ fd = openat(dfd, *path ? path : ".", oflags, mode);
+ close(dfd);
+ debug_return_int(fd);
+}
+
+#ifdef O_NOFOLLOW
+static int
+sudo_edit_open(char *path, int oflags, mode_t mode,
+ struct command_details *command_details)
+{
+ const int sflags = command_details ? command_details->flags : 0;
+ int fd;
+ debug_decl(sudo_edit_open, SUDO_DEBUG_EDIT)
+
+ if (!ISSET(sflags, CD_SUDOEDIT_FOLLOW))
+ oflags |= O_NOFOLLOW;
+ if (ISSET(sflags, CD_SUDOEDIT_CHECKDIR) && user_details.uid != ROOT_UID) {
+ fd = sudo_edit_open_nonwritable(path, oflags|O_NONBLOCK, mode,
+ command_details);
+ } else {
+ fd = open(path, oflags|O_NONBLOCK, mode);
+ }
+ if (fd != -1 && !ISSET(oflags, O_NONBLOCK))
+ (void) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+ debug_return_int(fd);
+}
+#else
+static int
+sudo_edit_open(char *path, int oflags, mode_t mode,
+ struct command_details *command_details)
+{
+ const int sflags = command_details ? command_details->flags : 0;
+ struct stat sb;
+ int fd;
+ debug_decl(sudo_edit_open, SUDO_DEBUG_EDIT)
+
+ /*
+ * Check if path is a symlink. This is racey but we detect whether
+ * we lost the race in sudo_edit_is_symlink() after the file is opened.
+ */
+ if (!ISSET(sflags, CD_SUDOEDIT_FOLLOW)) {
+ if (lstat(path, &sb) == -1 && errno != ENOENT)
+ debug_return_int(-1);
+ if (S_ISLNK(sb.st_mode)) {
+ errno = ELOOP;
+ debug_return_int(-1);
+ }
+ }
+
+ if (ISSET(sflags, CD_SUDOEDIT_CHECKDIR) && user_details.uid != ROOT_UID) {
+ fd = sudo_edit_open_nonwritable(path, oflags|O_NONBLOCK, mode,
+ command_details);
+ } else {
+ fd = open(path, oflags|O_NONBLOCK, mode);
+ }
+ if (fd == -1)
+ debug_return_int(-1);
+ if (!ISSET(oflags, O_NONBLOCK))
+ (void) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+
+ /*
+ * Post-open symlink check. This will leave a zero-length file if
+ * O_CREAT was specified but it is too dangerous to try and remove it.
+ */
+ if (!ISSET(sflags, CD_SUDOEDIT_FOLLOW) && sudo_edit_is_symlink(fd, path)) {
+ close(fd);
+ fd = -1;
+ errno = ELOOP;
+ }
+
+ debug_return_int(fd);
+}
+#endif /* O_NOFOLLOW */
+
+/*
+ * Create temporary copies of files[] and store the temporary path name
+ * along with the original name, size and mtime in tf.
+ * Returns the number of files copied (which may be less than nfiles)
+ * or -1 if a fatal error occurred.
+ */
+static int
+sudo_edit_create_tfiles(struct command_details *command_details,
+ struct tempfile *tf, char *files[], int nfiles)
+{
+ int i, j, tfd, ofd, rc;
+ char buf[BUFSIZ];
+ ssize_t nwritten, nread;
+ struct timespec times[2];
+ struct stat sb;
+ debug_decl(sudo_edit_create_tfiles, SUDO_DEBUG_EDIT)
+
+ /*
+ * For each file specified by the user, make a temporary version
+ * and copy the contents of the original to it.
+ */
+ for (i = 0, j = 0; i < nfiles; i++) {
+ rc = -1;
+ switch_user(command_details->euid, command_details->egid,
+ command_details->ngroups, command_details->groups);
+ ofd = sudo_edit_open(files[i], O_RDONLY,
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, command_details);
+ if (ofd != -1 || errno == ENOENT) {
+ if (ofd == -1) {
+ /* New file, verify parent dir exists unless in cwd. */
+ char *slash = strrchr(files[i], '/');
+ if (slash != NULL && slash != files[i]) {
+ int serrno = errno;
+ *slash = '\0';
+ if (stat(files[i], &sb) == 0 && S_ISDIR(sb.st_mode)) {
+ memset(&sb, 0, sizeof(sb));
+ rc = 0;
+ }
+ *slash = '/';
+ errno = serrno;
+ } else {
+ memset(&sb, 0, sizeof(sb));
+ rc = 0;
+ }
+ } else {
+ rc = fstat(ofd, &sb);
+ }
+ }
+ switch_user(ROOT_UID, user_details.egid,
+ user_details.ngroups, user_details.groups);
+ if (ofd != -1 && !S_ISREG(sb.st_mode)) {
+ sudo_warnx(U_("%s: not a regular file"), files[i]);
+ close(ofd);
+ continue;
+ }
+ if (rc == -1) {
+ /* open() or fstat() error. */
+ if (ofd == -1 && errno == ELOOP) {
+ sudo_warnx(U_("%s: editing symbolic links is not permitted"),
+ files[i]);
+ } else if (ofd == -1 && errno == EISDIR) {
+ sudo_warnx(U_("%s: editing files in a writable directory is not permitted"),
+ files[i]);
+ } else {
+ sudo_warn("%s", files[i]);
+ }
+ if (ofd != -1)
+ close(ofd);
+ continue;
+ }
+ tf[j].ofile = files[i];
+ tf[j].osize = sb.st_size;
+ mtim_get(&sb, tf[j].omtim);
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "seteuid(%u)", (unsigned int)user_details.uid);
+ if (seteuid(user_details.uid) != 0)
+ sudo_fatal("seteuid(%u)", (unsigned int)user_details.uid);
+ tfd = sudo_edit_mktemp(tf[j].ofile, &tf[j].tfile);
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "seteuid(%u)", ROOT_UID);
+ if (seteuid(ROOT_UID) != 0)
+ sudo_fatal("seteuid(ROOT_UID)");
+ if (tfd == -1) {
+ sudo_warn("mkstemps");
+ if (ofd != -1)
+ close(ofd);
+ debug_return_int(-1);
+ }
+ if (ofd != -1) {
+ while ((nread = read(ofd, buf, sizeof(buf))) > 0) {
+ if ((nwritten = write(tfd, buf, nread)) != nread) {
+ if (nwritten == -1)
+ sudo_warn("%s", tf[j].tfile);
+ else
+ sudo_warnx(U_("%s: short write"), tf[j].tfile);
+ break;
+ }
+ }
+ if (nread != 0) {
+ if (nread < 0)
+ sudo_warn("%s", files[i]);
+ close(ofd);
+ close(tfd);
+ debug_return_int(-1);
+ }
+ close(ofd);
+ }
+ /*
+ * We always update the stashed mtime because the time
+ * resolution of the filesystem the temporary file is on may
+ * not match that of the filesystem where the file to be edited
+ * resides. It is OK if futimens() fails since we only use the
+ * info to determine whether or not a file has been modified.
+ */
+ times[0].tv_sec = times[1].tv_sec = tf[j].omtim.tv_sec;
+ times[0].tv_nsec = times[1].tv_nsec = tf[j].omtim.tv_nsec;
+ if (futimens(tfd, times) == -1) {
+ if (utimensat(AT_FDCWD, tf[j].tfile, times, 0) == -1)
+ sudo_warn("%s", tf[j].tfile);
+ }
+ rc = fstat(tfd, &sb);
+ if (!rc)
+ mtim_get(&sb, tf[j].omtim);
+ close(tfd);
+ j++;
+ }
+ debug_return_int(j);
+}
+
+/*
+ * Copy the temporary files specified in tf to the originals.
+ * Returns the number of copy errors or 0 if completely successful.
+ */
+static int
+sudo_edit_copy_tfiles(struct command_details *command_details,
+ struct tempfile *tf, int nfiles, struct timespec *times)
+{
+ int i, tfd, ofd, rc, errors = 0;
+ char buf[BUFSIZ];
+ ssize_t nwritten, nread;
+ struct timespec ts;
+ struct stat sb;
+ debug_decl(sudo_edit_copy_tfiles, SUDO_DEBUG_EDIT)
+
+ /* Copy contents of temp files to real ones. */
+ for (i = 0; i < nfiles; i++) {
+ rc = -1;
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "seteuid(%u)", (unsigned int)user_details.uid);
+ if (seteuid(user_details.uid) != 0)
+ sudo_fatal("seteuid(%u)", (unsigned int)user_details.uid);
+ tfd = sudo_edit_open(tf[i].tfile, O_RDONLY,
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, NULL);
+ if (tfd != -1)
+ rc = fstat(tfd, &sb);
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "seteuid(%u)", ROOT_UID);
+ if (seteuid(ROOT_UID) != 0)
+ sudo_fatal("seteuid(ROOT_UID)");
+ if (rc || !S_ISREG(sb.st_mode)) {
+ if (rc)
+ sudo_warn("%s", tf[i].tfile);
+ else
+ sudo_warnx(U_("%s: not a regular file"), tf[i].tfile);
+ sudo_warnx(U_("%s left unmodified"), tf[i].ofile);
+ if (tfd != -1)
+ close(tfd);
+ errors++;
+ continue;
+ }
+ mtim_get(&sb, ts);
+ if (tf[i].osize == sb.st_size && sudo_timespeccmp(&tf[i].omtim, &ts, ==)) {
+ /*
+ * If mtime and size match but the user spent no measurable
+ * time in the editor we can't tell if the file was changed.
+ */
+ if (sudo_timespeccmp(&times[0], &times[1], !=)) {
+ sudo_warnx(U_("%s unchanged"), tf[i].ofile);
+ unlink(tf[i].tfile);
+ close(tfd);
+ continue;
+ }
+ }
+ switch_user(command_details->euid, command_details->egid,
+ command_details->ngroups, command_details->groups);
+ ofd = sudo_edit_open(tf[i].ofile, O_WRONLY|O_TRUNC|O_CREAT,
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, command_details);
+ switch_user(ROOT_UID, user_details.egid,
+ user_details.ngroups, user_details.groups);
+ if (ofd == -1) {
+ sudo_warn(U_("unable to write to %s"), tf[i].ofile);
+ sudo_warnx(U_("contents of edit session left in %s"), tf[i].tfile);
+ close(tfd);
+ errors++;
+ continue;
+ }
+ while ((nread = read(tfd, buf, sizeof(buf))) > 0) {
+ if ((nwritten = write(ofd, buf, nread)) != nread) {
+ if (nwritten == -1)
+ sudo_warn("%s", tf[i].ofile);
+ else
+ sudo_warnx(U_("%s: short write"), tf[i].ofile);
+ break;
+ }
+ }
+ if (nread == 0) {
+ /* success, got EOF */
+ unlink(tf[i].tfile);
+ } else if (nread < 0) {
+ sudo_warn(U_("unable to read temporary file"));
+ sudo_warnx(U_("contents of edit session left in %s"), tf[i].tfile);
+ } else {
+ sudo_warn(U_("unable to write to %s"), tf[i].ofile);
+ sudo_warnx(U_("contents of edit session left in %s"), tf[i].tfile);
+ }
+ close(ofd);
+ close(tfd);
+ }
+ debug_return_int(errors);
+}
+
+#ifdef HAVE_SELINUX
+static int
+selinux_edit_create_tfiles(struct command_details *command_details,
+ struct tempfile *tf, char *files[], int nfiles)
+{
+ char **sesh_args, **sesh_ap;
+ int i, rc, sesh_nargs;
+ struct stat sb;
+ struct command_details saved_command_details;
+ debug_decl(selinux_edit_create_tfiles, SUDO_DEBUG_EDIT)
+
+ /* Prepare selinux stuff (setexeccon) */
+ if (selinux_setup(command_details->selinux_role,
+ command_details->selinux_type, NULL, -1) != 0)
+ debug_return_int(-1);
+
+ if (nfiles < 1)
+ debug_return_int(0);
+
+ /* Construct common args for sesh */
+ memcpy(&saved_command_details, command_details, sizeof(struct command_details));
+ command_details->command = _PATH_SUDO_SESH;
+ command_details->flags |= CD_SUDOEDIT_COPY;
+
+ sesh_nargs = 4 + (nfiles * 2) + 1;
+ sesh_args = sesh_ap = reallocarray(NULL, sesh_nargs, sizeof(char *));
+ if (sesh_args == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+ *sesh_ap++ = "sesh";
+ *sesh_ap++ = "-e";
+ if (!ISSET(command_details->flags, CD_SUDOEDIT_FOLLOW))
+ *sesh_ap++ = "-h";
+ *sesh_ap++ = "0";
+
+ for (i = 0; i < nfiles; i++) {
+ char *tfile, *ofile = files[i];
+ int tfd;
+ *sesh_ap++ = ofile;
+ tf[i].ofile = ofile;
+ if (stat(ofile, &sb) == -1)
+ memset(&sb, 0, sizeof(sb)); /* new file */
+ tf[i].osize = sb.st_size;
+ mtim_get(&sb, tf[i].omtim);
+ /*
+ * The temp file must be created by the sesh helper,
+ * which uses O_EXCL | O_NOFOLLOW to make this safe.
+ */
+ tfd = sudo_edit_mktemp(ofile, &tfile);
+ if (tfd == -1) {
+ sudo_warn("mkstemps");
+ free(tfile);
+ free(sesh_args);
+ debug_return_int(-1);
+ }
+ /* Helper will re-create temp file with proper security context. */
+ close(tfd);
+ unlink(tfile);
+ *sesh_ap++ = tfile;
+ tf[i].tfile = tfile;
+ }
+ *sesh_ap = NULL;
+
+ /* Run sesh -e [-h] 0 <o1> <t1> ... <on> <tn> */
+ command_details->argv = sesh_args;
+ rc = run_command(command_details);
+ switch (rc) {
+ case SESH_SUCCESS:
+ break;
+ case SESH_ERR_BAD_PATHS:
+ sudo_fatalx(U_("sesh: internal error: odd number of paths"));
+ case SESH_ERR_NO_FILES:
+ sudo_fatalx(U_("sesh: unable to create temporary files"));
+ default:
+ sudo_fatalx(U_("sesh: unknown error %d"), rc);
+ }
+
+ /* Restore saved command_details. */
+ command_details->command = saved_command_details.command;
+ command_details->flags = saved_command_details.flags;
+ command_details->argv = saved_command_details.argv;
+
+ /* Chown to user's UID so they can edit the temporary files. */
+ for (i = 0; i < nfiles; i++) {
+ if (chown(tf[i].tfile, user_details.uid, user_details.gid) != 0) {
+ sudo_warn("unable to chown(%s) to %d:%d for editing",
+ tf[i].tfile, user_details.uid, user_details.gid);
+ }
+ }
+
+ /* Contents of tf will be freed by caller. */
+ free(sesh_args);
+
+ return (nfiles);
+}
+
+static int
+selinux_edit_copy_tfiles(struct command_details *command_details,
+ struct tempfile *tf, int nfiles, struct timespec *times)
+{
+ char **sesh_args, **sesh_ap;
+ int i, rc, sesh_nargs, ret = 1;
+ struct command_details saved_command_details;
+ struct timespec ts;
+ struct stat sb;
+ debug_decl(selinux_edit_copy_tfiles, SUDO_DEBUG_EDIT)
+
+ /* Prepare selinux stuff (setexeccon) */
+ if (selinux_setup(command_details->selinux_role,
+ command_details->selinux_type, NULL, -1) != 0)
+ debug_return_int(1);
+
+ if (nfiles < 1)
+ debug_return_int(0);
+
+ /* Construct common args for sesh */
+ memcpy(&saved_command_details, command_details, sizeof(struct command_details));
+ command_details->command = _PATH_SUDO_SESH;
+ command_details->flags |= CD_SUDOEDIT_COPY;
+
+ sesh_nargs = 3 + (nfiles * 2) + 1;
+ sesh_args = sesh_ap = reallocarray(NULL, sesh_nargs, sizeof(char *));
+ if (sesh_args == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_int(-1);
+ }
+ *sesh_ap++ = "sesh";
+ *sesh_ap++ = "-e";
+ *sesh_ap++ = "1";
+
+ /* Construct args for sesh -e 1 */
+ for (i = 0; i < nfiles; i++) {
+ if (stat(tf[i].tfile, &sb) == 0) {
+ mtim_get(&sb, ts);
+ if (tf[i].osize == sb.st_size && sudo_timespeccmp(&tf[i].omtim, &ts, ==)) {
+ /*
+ * If mtime and size match but the user spent no measurable
+ * time in the editor we can't tell if the file was changed.
+ */
+ if (sudo_timespeccmp(&times[0], &times[1], !=)) {
+ sudo_warnx(U_("%s unchanged"), tf[i].ofile);
+ unlink(tf[i].tfile);
+ continue;
+ }
+ }
+ }
+ *sesh_ap++ = tf[i].tfile;
+ *sesh_ap++ = tf[i].ofile;
+ if (chown(tf[i].tfile, command_details->uid, command_details->gid) != 0) {
+ sudo_warn("unable to chown(%s) back to %d:%d", tf[i].tfile,
+ command_details->uid, command_details->gid);
+ }
+ }
+ *sesh_ap = NULL;
+
+ if (sesh_ap - sesh_args > 3) {
+ /* Run sesh -e 1 <t1> <o1> ... <tn> <on> */
+ command_details->argv = sesh_args;
+ rc = run_command(command_details);
+ switch (rc) {
+ case SESH_SUCCESS:
+ ret = 0;
+ break;
+ case SESH_ERR_NO_FILES:
+ sudo_warnx(U_("unable to copy temporary files back to their original location"));
+ sudo_warnx(U_("contents of edit session left in %s"), edit_tmpdir);
+ break;
+ case SESH_ERR_SOME_FILES:
+ sudo_warnx(U_("unable to copy some of the temporary files back to their original location"));
+ sudo_warnx(U_("contents of edit session left in %s"), edit_tmpdir);
+ break;
+ default:
+ sudo_warnx(U_("sesh: unknown error %d"), rc);
+ break;
+ }
+ }
+ free(sesh_args);
+
+ /* Restore saved command_details. */
+ command_details->command = saved_command_details.command;
+ command_details->flags = saved_command_details.flags;
+ command_details->argv = saved_command_details.argv;
+
+ debug_return_int(ret);
+}
+#endif /* HAVE_SELINUX */
+
+/*
+ * Wrapper to allow users to edit privileged files with their own uid.
+ * Returns the wait status of the command on success and a wait status
+ * of 1 on failure.
+ */
+int
+sudo_edit(struct command_details *command_details)
+{
+ struct command_details saved_command_details;
+ char **nargv = NULL, **ap, **files = NULL;
+ int errors, i, ac, nargc, rc;
+ int editor_argc = 0, nfiles = 0;
+ struct timespec times[2];
+ struct tempfile *tf = NULL;
+ debug_decl(sudo_edit, SUDO_DEBUG_EDIT)
+
+ if (!set_tmpdir(command_details))
+ goto cleanup;
+
+ /*
+ * Set real, effective and saved uids to root.
+ * We will change the euid as needed below.
+ */
+ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
+ "setuid(%u)", ROOT_UID);
+ if (setuid(ROOT_UID) != 0) {
+ sudo_warn(U_("unable to change uid to root (%u)"), ROOT_UID);
+ goto cleanup;
+ }
+
+ /*
+ * The user's editor must be separated from the files to be
+ * edited by a "--" option.
+ */
+ for (ap = command_details->argv; *ap != NULL; ap++) {
+ if (files)
+ nfiles++;
+ else if (strcmp(*ap, "--") == 0)
+ files = ap + 1;
+ else
+ editor_argc++;
+ }
+ if (nfiles == 0) {
+ sudo_warnx(U_("plugin error: missing file list for sudoedit"));
+ goto cleanup;
+ }
+
+ /* Copy editor files to temporaries. */
+ tf = calloc(nfiles, sizeof(*tf));
+ if (tf == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto cleanup;
+ }
+#ifdef HAVE_SELINUX
+ if (ISSET(command_details->flags, CD_RBAC_ENABLED))
+ nfiles = selinux_edit_create_tfiles(command_details, tf, files, nfiles);
+ else
+#endif
+ nfiles = sudo_edit_create_tfiles(command_details, tf, files, nfiles);
+ if (nfiles <= 0)
+ goto cleanup;
+
+ /*
+ * Allocate space for the new argument vector and fill it in.
+ * We concatenate the editor with its args and the file list
+ * to create a new argv.
+ */
+ nargc = editor_argc + nfiles;
+ nargv = reallocarray(NULL, nargc + 1, sizeof(char *));
+ if (nargv == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto cleanup;
+ }
+ for (ac = 0; ac < editor_argc; ac++)
+ nargv[ac] = command_details->argv[ac];
+ for (i = 0; i < nfiles && ac < nargc; )
+ nargv[ac++] = tf[i++].tfile;
+ nargv[ac] = NULL;
+
+ /*
+ * Run the editor with the invoking user's creds,
+ * keeping track of the time spent in the editor.
+ */
+ if (sudo_gettime_real(&times[0]) == -1) {
+ sudo_warn(U_("unable to read the clock"));
+ goto cleanup;
+ }
+ memcpy(&saved_command_details, command_details, sizeof(struct command_details));
+ command_details->uid = user_details.uid;
+ command_details->euid = user_details.uid;
+ command_details->gid = user_details.gid;
+ command_details->egid = user_details.gid;
+ command_details->ngroups = user_details.ngroups;
+ command_details->groups = user_details.groups;
+ command_details->argv = nargv;
+ rc = run_command(command_details);
+ if (sudo_gettime_real(&times[1]) == -1) {
+ sudo_warn(U_("unable to read the clock"));
+ goto cleanup;
+ }
+
+ /* Restore saved command_details. */
+ command_details->uid = saved_command_details.uid;
+ command_details->euid = saved_command_details.euid;
+ command_details->gid = saved_command_details.gid;
+ command_details->egid = saved_command_details.egid;
+ command_details->ngroups = saved_command_details.ngroups;
+ command_details->groups = saved_command_details.groups;
+ command_details->argv = saved_command_details.argv;
+
+ /* Copy contents of temp files to real ones. */
+#ifdef HAVE_SELINUX
+ if (ISSET(command_details->flags, CD_RBAC_ENABLED))
+ errors = selinux_edit_copy_tfiles(command_details, tf, nfiles, times);
+ else
+#endif
+ errors = sudo_edit_copy_tfiles(command_details, tf, nfiles, times);
+ if (errors)
+ goto cleanup;
+
+ for (i = 0; i < nfiles; i++)
+ free(tf[i].tfile);
+ free(tf);
+ free(nargv);
+ debug_return_int(rc);
+
+cleanup:
+ /* Clean up temp files and return. */
+ if (tf != NULL) {
+ for (i = 0; i < nfiles; i++) {
+ if (tf[i].tfile != NULL)
+ unlink(tf[i].tfile);
+ }
+ }
+ free(tf);
+ free(nargv);
+ debug_return_int(W_EXITCODE(1, 0));
+}
+
+#else /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
+
+/*
+ * Must have the ability to change the effective uid to use sudoedit.
+ */
+int
+sudo_edit(struct command_details *command_details)
+{
+ debug_decl(sudo_edit, SUDO_DEBUG_EDIT)
+ debug_return_int(W_EXITCODE(1, 0));
+}
+
+#endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
diff --git a/src/sudo_exec.h b/src/sudo_exec.h
new file mode 100644
index 0000000..c8c7941
--- /dev/null
+++ b/src/sudo_exec.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2010-2016 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_EXEC_H
+#define SUDO_EXEC_H
+
+/*
+ * Older systems may not support MSG_WAITALL but it shouldn't really be needed.
+ */
+#ifndef MSG_WAITALL
+# define MSG_WAITALL 0
+#endif
+
+/*
+ * Some older systems support siginfo but predate SI_USER.
+ */
+#ifdef SI_USER
+# define USER_SIGNALED(_info) ((_info) != NULL && (_info)->si_code == SI_USER)
+#else
+# define USER_SIGNALED(_info) ((_info) != NULL && (_info)->si_code <= 0)
+#endif
+
+/*
+ * Indices into io_fds[] when running a command in a pty.
+ */
+#define SFD_STDIN 0
+#define SFD_STDOUT 1
+#define SFD_STDERR 2
+#define SFD_MASTER 3
+#define SFD_SLAVE 4
+#define SFD_USERTTY 5
+
+/*
+ * Special values to indicate whether continuing in foreground or background.
+ */
+#define SIGCONT_FG -2
+#define SIGCONT_BG -3
+
+/*
+ * Positions in saved_signals[]
+ */
+#define SAVED_SIGALRM 0
+#define SAVED_SIGCHLD 1
+#define SAVED_SIGCONT 2
+#define SAVED_SIGHUP 3
+#define SAVED_SIGINT 4
+#define SAVED_SIGPIPE 5
+#define SAVED_SIGQUIT 6
+#define SAVED_SIGTERM 7
+#define SAVED_SIGTSTP 8
+#define SAVED_SIGTTIN 9
+#define SAVED_SIGTTOU 10
+#define SAVED_SIGUSR1 11
+#define SAVED_SIGUSR2 12
+
+/*
+ * Error codes for sesh
+ */
+#define SESH_SUCCESS 0 /* successful operation */
+#define SESH_ERR_FAILURE 1 /* unspecified error */
+#define SESH_ERR_INVALID 30 /* invalid -e arg value */
+#define SESH_ERR_BAD_PATHS 31 /* odd number of paths */
+#define SESH_ERR_NO_FILES 32 /* copy error, no files copied */
+#define SESH_ERR_SOME_FILES 33 /* copy error, some files copied */
+
+/*
+ * Symbols shared between exec.c, exec_nopty.c, exec_pty.c and exec_monitor.c
+ */
+struct command_details;
+struct command_status;
+
+/* exec.c */
+void exec_cmnd(struct command_details *details, int errfd);
+void terminate_command(pid_t pid, bool use_pgrp);
+bool sudo_terminated(struct command_status *cstat);
+
+/* exec_common.c */
+int sudo_execve(int fd, const char *path, char *const argv[], char *envp[], bool noexec);
+char **disable_execute(char *envp[], const char *dso);
+
+/* exec_nopty.c */
+void exec_nopty(struct command_details *details, struct command_status *cstat);
+
+/* exec_pty.c */
+bool exec_pty(struct command_details *details, struct command_status *cstat);
+void pty_cleanup(void);
+int pty_make_controlling(void);
+extern int io_fds[6];
+
+/* exec_monitor.c */
+int exec_monitor(struct command_details *details, sigset_t *omask, bool foreground, int backchannel);
+
+/* utmp.c */
+bool utmp_login(const char *from_line, const char *to_line, int ttyfd,
+ const char *user);
+bool utmp_logout(const char *line, int status);
+
+#endif /* SUDO_EXEC_H */
diff --git a/src/sudo_noexec.c b/src/sudo_noexec.c
new file mode 100644
index 0000000..c103d5f
--- /dev/null
+++ b/src/sudo_noexec.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2004-2005, 2010-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#if defined(HAVE_DECL_SECCOMP_SET_MODE_FILTER) && HAVE_DECL_SECCOMP_SET_MODE_FILTER
+# include <sys/prctl.h>
+# include <asm/unistd.h>
+# include <linux/filter.h>
+# include <linux/seccomp.h>
+#endif
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#ifdef HAVE_SPAWN_H
+#include <spawn.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_WORDEXP_H
+#include <wordexp.h>
+#endif
+#if defined(HAVE_SHL_LOAD)
+# include <dl.h>
+#elif defined(HAVE_DLOPEN)
+# include <dlfcn.h>
+#endif
+
+#include "sudo_compat.h"
+#include "pathnames.h"
+
+#ifdef HAVE___INTERPOSE
+/*
+ * Mac OS X 10.4 and above has support for library symbol interposition.
+ * There is a good explanation of this in the Mac OS X Internals book.
+ */
+typedef struct interpose_s {
+ void *new_func;
+ void *orig_func;
+} interpose_t;
+
+# define FN_NAME(fn) dummy_ ## fn
+# define INTERPOSE(fn) \
+ __attribute__((__used__)) static const interpose_t interpose_ ## fn \
+ __attribute__((__section__("__DATA,__interpose"))) = \
+ { (void *)dummy_ ## fn, (void *)fn };
+#else
+# define FN_NAME(fn) fn
+# define INTERPOSE(fn)
+#endif
+
+/*
+ * Dummy versions of the exec(3) family of syscalls. It is not enough to
+ * just dummy out execve(2) since many C libraries do not call the public
+ * execve(2) interface. Note that it is still possible to access the real
+ * syscalls via the syscall(2) interface, but that is rarely done.
+ */
+
+#define DUMMY_BODY \
+{ \
+ errno = EACCES; \
+ return -1; \
+}
+
+#define DUMMY1(fn, t1) \
+__dso_public int \
+FN_NAME(fn)(t1 a1) \
+DUMMY_BODY \
+INTERPOSE(fn)
+
+#define DUMMY2(fn, t1, t2) \
+__dso_public int \
+FN_NAME(fn)(t1 a1, t2 a2) \
+DUMMY_BODY \
+INTERPOSE(fn)
+
+#define DUMMY3(fn, t1, t2, t3) \
+__dso_public int \
+FN_NAME(fn)(t1 a1, t2 a2, t3 a3) \
+DUMMY_BODY \
+INTERPOSE(fn)
+
+#define DUMMY6(fn, t1, t2, t3, t4, t5, t6) \
+__dso_public int \
+FN_NAME(fn)(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \
+DUMMY_BODY \
+INTERPOSE(fn)
+
+#define DUMMY_VA(fn, t1, t2) \
+__dso_public int \
+FN_NAME(fn)(t1 a1, t2 a2, ...) \
+DUMMY_BODY \
+INTERPOSE(fn)
+
+/*
+ * Standard exec(3) family of functions.
+ */
+DUMMY_VA(execl, const char *, const char *)
+DUMMY_VA(execle, const char *, const char *)
+DUMMY_VA(execlp, const char *, const char *)
+DUMMY2(execv, const char *, char * const *)
+DUMMY2(execvp, const char *, char * const *)
+DUMMY3(execve, const char *, char * const *, char * const *)
+
+/*
+ * Non-standard exec(3) functions and corresponding private versions.
+ */
+#ifdef HAVE_EXECVP
+DUMMY3(execvP, const char *, const char *, char * const *)
+#endif
+#ifdef HAVE_EXECVPE
+DUMMY3(execvpe, const char *, char * const *, char * const *)
+#endif
+#ifdef HAVE_EXECT
+DUMMY3(exect, const char *, char * const *, char * const *)
+#endif
+
+/*
+ * Not all systems support fexecve(2), posix_spawn(2) and posix_spawnp(2).
+ */
+#ifdef HAVE_FEXECVE
+DUMMY3(fexecve, int , char * const *, char * const *)
+#endif
+#ifdef HAVE_POSIX_SPAWN
+DUMMY6(posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
+#endif
+#ifdef HAVE_POSIX_SPAWNP
+DUMMY6(posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
+#endif
+
+/*
+ * system(3) and popen(3).
+ * We can't use a wrapper for popen since it returns FILE *, not int.
+ */
+DUMMY1(system, const char *)
+
+__dso_public FILE *
+FN_NAME(popen)(const char *c, const char *t)
+{
+ errno = EACCES;
+ return NULL;
+}
+INTERPOSE(popen)
+
+#if defined(HAVE_WORDEXP) && (defined(RTLD_NEXT) || defined(HAVE_SHL_LOAD) || defined(HAVE___INTERPOSE))
+/*
+ * We can't use a wrapper for wordexp(3) since we still want to call
+ * the real wordexp(3) but with WRDE_NOCMD added to the flags argument.
+ */
+typedef int (*sudo_fn_wordexp_t)(const char *, wordexp_t *, int);
+
+__dso_public int
+FN_NAME(wordexp)(const char *words, wordexp_t *we, int flags)
+{
+#if defined(HAVE___INTERPOSE)
+ return wordexp(words, we, flags | WRDE_NOCMD);
+#else
+# if defined(HAVE_DLOPEN)
+ void *fn = dlsym(RTLD_NEXT, "wordexp");
+# elif defined(HAVE_SHL_LOAD)
+ const char *name, *myname = _PATH_SUDO_NOEXEC;
+ struct shl_descriptor *desc;
+ void *fn = NULL;
+ int idx = 0;
+
+ name = strrchr(myname, '/');
+ if (name != NULL)
+ myname = name + 1;
+
+ /* Search for wordexp() but skip this shared object. */
+ while (shl_get(idx++, &desc) == 0) {
+ name = strrchr(desc->filename, '/');
+ if (name == NULL)
+ name = desc->filename;
+ else
+ name++;
+ if (strcmp(name, myname) == 0)
+ continue;
+ if (shl_findsym(&desc->handle, "wordexp", TYPE_PROCEDURE, &fn) == 0)
+ break;
+ }
+# else
+ void *fn = NULL;
+# endif
+ if (fn == NULL) {
+ errno = EACCES;
+ return -1;
+ }
+ return ((sudo_fn_wordexp_t)fn)(words, we, flags | WRDE_NOCMD);
+#endif /* HAVE___INTERPOSE */
+}
+INTERPOSE(wordexp)
+#endif /* HAVE_WORDEXP && (RTLD_NEXT || HAVE_SHL_LOAD || HAVE___INTERPOSE) */
+
+/*
+ * On Linux we can use a seccomp() filter to disable exec.
+ */
+#if defined(HAVE_DECL_SECCOMP_SET_MODE_FILTER) && HAVE_DECL_SECCOMP_SET_MODE_FILTER
+
+/* Older systems may not support execveat(2). */
+#ifndef __NR_execveat
+# define __NR_execveat -1
+#endif
+
+static void noexec_ctor(void) __attribute__((constructor));
+
+static void
+noexec_ctor(void)
+{
+ struct sock_filter exec_filter[] = {
+ /* Load syscall number into the accumulator */
+ BPF_STMT(BPF_LD | BPF_ABS, offsetof(struct seccomp_data, nr)),
+ /* Jump to deny for execve/execveat */
+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execve, 2, 0),
+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execveat, 1, 0),
+ /* Allow non-matching syscalls */
+ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+ /* Deny execve/execveat syscall */
+ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (EACCES & SECCOMP_RET_DATA))
+ };
+ const struct sock_fprog exec_fprog = {
+ nitems(exec_filter),
+ exec_filter
+ };
+
+ /*
+ * SECCOMP_MODE_FILTER will fail unless the process has
+ * CAP_SYS_ADMIN or the no_new_privs bit is set.
+ */
+ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == 0)
+ (void)prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &exec_fprog);
+}
+#endif /* HAVE_DECL_SECCOMP_SET_MODE_FILTER */
diff --git a/src/sudo_plugin_int.h b/src/sudo_plugin_int.h
new file mode 100644
index 0000000..c5fce34
--- /dev/null
+++ b/src/sudo_plugin_int.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2010-2014 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_PLUGIN_INT_H
+#define SUDO_PLUGIN_INT_H
+
+/*
+ * All plugin structures start with a type and a version.
+ */
+struct generic_plugin {
+ unsigned int type;
+ unsigned int version;
+ /* the rest depends on the type... */
+};
+
+typedef int (*sudo_conv_1_7_t)(int num_msgs,
+ const struct sudo_conv_message msgs[], struct sudo_conv_reply replies[]);
+
+/*
+ * Backwards-compatible structures for API bumps.
+ */
+struct policy_plugin_1_0 {
+ unsigned int type;
+ unsigned int version;
+ int (*open)(unsigned int version, sudo_conv_1_7_t conversation,
+ sudo_printf_t sudo_printf, char * const settings[],
+ char * const user_info[], char * const user_env[]);
+ void (*close)(int exit_status, int error); /* wait status or error */
+ int (*show_version)(int verbose);
+ int (*check_policy)(int argc, char * const argv[],
+ char *env_add[], char **command_info[],
+ char **argv_out[], char **user_env_out[]);
+ int (*list)(int argc, char * const argv[], int verbose,
+ const char *list_user);
+ int (*validate)(void);
+ void (*invalidate)(int remove);
+ int (*init_session)(struct passwd *pwd);
+};
+struct io_plugin_1_0 {
+ unsigned int type;
+ unsigned int version;
+ int (*open)(unsigned int version, sudo_conv_1_7_t conversation,
+ sudo_printf_t sudo_printf, char * const settings[],
+ char * const user_info[], int argc, char * const argv[],
+ char * const user_env[]);
+ void (*close)(int exit_status, int error);
+ int (*show_version)(int verbose);
+ int (*log_ttyin)(const char *buf, unsigned int len);
+ int (*log_ttyout)(const char *buf, unsigned int len);
+ int (*log_stdin)(const char *buf, unsigned int len);
+ int (*log_stdout)(const char *buf, unsigned int len);
+ int (*log_stderr)(const char *buf, unsigned int len);
+};
+struct io_plugin_1_1 {
+ unsigned int type;
+ unsigned int version;
+ int (*open)(unsigned int version, sudo_conv_1_7_t conversation,
+ sudo_printf_t sudo_printf, char * const settings[],
+ char * const user_info[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[]);
+ void (*close)(int exit_status, int error); /* wait status or error */
+ int (*show_version)(int verbose);
+ int (*log_ttyin)(const char *buf, unsigned int len);
+ int (*log_ttyout)(const char *buf, unsigned int len);
+ int (*log_stdin)(const char *buf, unsigned int len);
+ int (*log_stdout)(const char *buf, unsigned int len);
+ int (*log_stderr)(const char *buf, unsigned int len);
+};
+
+/*
+ * Sudo plugin internals.
+ */
+struct plugin_container {
+ TAILQ_ENTRY(plugin_container) entries;
+ struct sudo_conf_debug_file_list *debug_files;
+ char *name;
+ char *path;
+ char **options;
+ void *handle;
+ int debug_instance;
+ union {
+ struct generic_plugin *generic;
+ struct policy_plugin *policy;
+ struct policy_plugin_1_0 *policy_1_0;
+ struct io_plugin *io;
+ struct io_plugin_1_0 *io_1_0;
+ struct io_plugin_1_1 *io_1_1;
+ } u;
+};
+TAILQ_HEAD(plugin_container_list, plugin_container);
+
+extern struct plugin_container policy_plugin;
+extern struct plugin_container_list io_plugins;
+
+int sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],
+ struct sudo_conv_reply replies[], struct sudo_conv_callback *callback);
+int sudo_conversation_1_7(int num_msgs, const struct sudo_conv_message msgs[],
+ struct sudo_conv_reply replies[]);
+int sudo_conversation_printf(int msg_type, const char *fmt, ...);
+
+bool sudo_load_plugins(struct plugin_container *policy_plugin,
+ struct plugin_container_list *io_plugins);
+
+#endif /* SUDO_PLUGIN_INT_H */
diff --git a/src/sudo_usage.h.in b/src/sudo_usage.h.in
new file mode 100644
index 0000000..95ae893
--- /dev/null
+++ b/src/sudo_usage.h.in
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2007-2010, 2013, 2015, 2017
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDO_USAGE_H
+#define SUDO_USAGE_H
+
+/*
+ * Usage strings for sudo. These are here because we
+ * need to be able to substitute values from configure.
+ */
+#define SUDO_USAGE1 " -h | -K | -k | -V"
+#define SUDO_USAGE2 " -v [-AknS] @BSDAUTH_USAGE@[-g group] [-h host] [-p prompt] [-u user]"
+#define SUDO_USAGE3 " -l [-AknS] @BSDAUTH_USAGE@[-g group] [-h host] [-p prompt] [-U user] [-u user] [command]"
+#define SUDO_USAGE4 " [-AbEHknPS] @BSDAUTH_USAGE@@SELINUX_USAGE@[-C num] @LOGINCAP_USAGE@[-g group] [-h host] [-p prompt] [-T timeout] [-u user] [VAR=value] [-i|-s] [<command>]"
+#define SUDO_USAGE5 " -e [-AknS] @BSDAUTH_USAGE@@SELINUX_USAGE@[-C num] @LOGINCAP_USAGE@[-g group] [-h host] [-p prompt] [-T timeout] [-u user] file ..."
+
+/*
+ * Configure script arguments used to build sudo.
+ */
+#define CONFIGURE_ARGS "@CONFIGURE_ARGS@"
+
+#endif /* SUDO_USAGE_H */
diff --git a/src/tcsetpgrp_nobg.c b/src/tcsetpgrp_nobg.c
new file mode 100644
index 0000000..03e95c8
--- /dev/null
+++ b/src/tcsetpgrp_nobg.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+
+#include "sudo.h"
+
+static volatile sig_atomic_t got_sigttou;
+
+/*
+ * SIGTTOU signal handler for tcsetpgrp_nobg() that just sets a flag.
+ */
+static void
+sigttou(int signo)
+{
+ got_sigttou = 1;
+}
+
+/*
+ * Like tcsetpgrp() but restarts on EINTR _except_ for SIGTTOU.
+ * Returns 0 on success or -1 on failure, setting errno.
+ * Sets got_sigttou on failure if interrupted by SIGTTOU.
+ */
+int
+tcsetpgrp_nobg(int fd, pid_t pgrp_id)
+{
+ struct sigaction sa, osa;
+ int rc;
+
+ /*
+ * If we receive SIGTTOU from tcsetpgrp() it means we are
+ * not in the foreground process group.
+ * This avoid a TOCTOU race compared to using tcgetpgrp().
+ */
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0; /* do not restart syscalls */
+ sa.sa_handler = sigttou;
+ got_sigttou = 0;
+ (void)sigaction(SIGTTOU, &sa, &osa);
+ do {
+ rc = tcsetpgrp(fd, pgrp_id);
+ } while (rc != 0 && errno == EINTR && !got_sigttou);
+ (void)sigaction(SIGTTOU, &osa, NULL);
+
+ return rc;
+}
diff --git a/src/tgetpass.c b/src/tgetpass.c
new file mode 100644
index 0000000..76b0c8b
--- /dev/null
+++ b/src/tgetpass.c
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#ifdef __TANDEM
+# include <floss.h>
+#endif
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <pwd.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+
+#include "sudo.h"
+#include "sudo_plugin.h"
+
+enum tgetpass_errval {
+ TGP_ERRVAL_NOERROR,
+ TGP_ERRVAL_TIMEOUT,
+ TGP_ERRVAL_NOPASSWORD,
+ TGP_ERRVAL_READERROR
+};
+
+static volatile sig_atomic_t signo[NSIG];
+
+static bool tty_present(void);
+static void tgetpass_handler(int);
+static char *getln(int, char *, size_t, int, enum tgetpass_errval *);
+static char *sudo_askpass(const char *, const char *);
+
+static int
+suspend(int signo, struct sudo_conv_callback *callback)
+{
+ int ret = 0;
+ debug_decl(suspend, SUDO_DEBUG_CONV)
+
+ if (callback != NULL && SUDO_API_VERSION_GET_MAJOR(callback->version) != SUDO_CONV_CALLBACK_VERSION_MAJOR) {
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
+ "callback major version mismatch, expected %u, got %u",
+ SUDO_CONV_CALLBACK_VERSION_MAJOR,
+ SUDO_API_VERSION_GET_MAJOR(callback->version));
+ callback = NULL;
+ }
+
+ if (callback != NULL && callback->on_suspend != NULL) {
+ if (callback->on_suspend(signo, callback->closure) == -1)
+ ret = -1;
+ }
+ kill(getpid(), signo);
+ if (callback != NULL && callback->on_resume != NULL) {
+ if (callback->on_resume(signo, callback->closure) == -1)
+ ret = -1;
+ }
+ debug_return_int(ret);
+}
+
+static void
+tgetpass_display_error(enum tgetpass_errval errval)
+{
+ debug_decl(tgetpass_display_error, SUDO_DEBUG_CONV)
+
+ switch (errval) {
+ case TGP_ERRVAL_NOERROR:
+ break;
+ case TGP_ERRVAL_TIMEOUT:
+ sudo_warnx(U_("timed out reading password"));
+ break;
+ case TGP_ERRVAL_NOPASSWORD:
+ sudo_warnx(U_("no password was provided"));
+ break;
+ case TGP_ERRVAL_READERROR:
+ sudo_warn(U_("unable to read password"));
+ break;
+ }
+ debug_return;
+}
+
+/*
+ * Like getpass(3) but with timeout and echo flags.
+ */
+char *
+tgetpass(const char *prompt, int timeout, int flags,
+ struct sudo_conv_callback *callback)
+{
+ struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
+ struct sigaction savetstp, savettin, savettou;
+ char *pass;
+ static const char *askpass;
+ static char buf[SUDO_CONV_REPL_MAX + 1];
+ int i, input, output, save_errno, neednl = 0, need_restart;
+ enum tgetpass_errval errval;
+ debug_decl(tgetpass, SUDO_DEBUG_CONV)
+
+ (void) fflush(stdout);
+
+ if (askpass == NULL) {
+ askpass = getenv_unhooked("SUDO_ASKPASS");
+ if (askpass == NULL || *askpass == '\0')
+ askpass = sudo_conf_askpass_path();
+ }
+
+ /* If no tty present and we need to disable echo, try askpass. */
+ if (!ISSET(flags, TGP_STDIN|TGP_ECHO|TGP_ASKPASS|TGP_NOECHO_TRY) &&
+ !tty_present()) {
+ if (askpass == NULL || getenv_unhooked("DISPLAY") == NULL) {
+ sudo_warnx(U_("no tty present and no askpass program specified"));
+ debug_return_str(NULL);
+ }
+ SET(flags, TGP_ASKPASS);
+ }
+
+ /* If using a helper program to get the password, run it instead. */
+ if (ISSET(flags, TGP_ASKPASS)) {
+ if (askpass == NULL || *askpass == '\0')
+ sudo_fatalx(U_("no askpass program specified, try setting SUDO_ASKPASS"));
+ debug_return_str_masked(sudo_askpass(askpass, prompt));
+ }
+
+restart:
+ for (i = 0; i < NSIG; i++)
+ signo[i] = 0;
+ pass = NULL;
+ save_errno = 0;
+ need_restart = 0;
+ /* Open /dev/tty for reading/writing if possible else use stdin/stderr. */
+ if (ISSET(flags, TGP_STDIN) ||
+ (input = output = open(_PATH_TTY, O_RDWR)) == -1) {
+ input = STDIN_FILENO;
+ output = STDERR_FILENO;
+ }
+
+ /*
+ * If we are using a tty but are not the foreground pgrp this will
+ * return EINTR. We send ourself SIGTTOU bracketed by callbacks.
+ */
+ if (!ISSET(flags, TGP_ECHO)) {
+ for (;;) {
+ if (ISSET(flags, TGP_MASK))
+ neednl = sudo_term_cbreak(input);
+ else
+ neednl = sudo_term_noecho(input);
+ if (neednl || errno != EINTR)
+ break;
+ /* Received SIGTTOU, suspend the process. */
+ if (suspend(SIGTTOU, callback) == -1) {
+ if (input != STDIN_FILENO)
+ (void) close(input);
+ debug_return_ptr(NULL);
+ }
+ }
+ }
+
+ /*
+ * Catch signals that would otherwise cause the user to end
+ * up with echo turned off in the shell.
+ */
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0; /* don't restart system calls */
+ sa.sa_handler = tgetpass_handler;
+ (void) sigaction(SIGALRM, &sa, &savealrm);
+ (void) sigaction(SIGINT, &sa, &saveint);
+ (void) sigaction(SIGHUP, &sa, &savehup);
+ (void) sigaction(SIGQUIT, &sa, &savequit);
+ (void) sigaction(SIGTERM, &sa, &saveterm);
+ (void) sigaction(SIGTSTP, &sa, &savetstp);
+ (void) sigaction(SIGTTIN, &sa, &savettin);
+ (void) sigaction(SIGTTOU, &sa, &savettou);
+
+ if (prompt) {
+ if (write(output, prompt, strlen(prompt)) == -1)
+ goto restore;
+ }
+
+ if (timeout > 0)
+ alarm(timeout);
+ pass = getln(input, buf, sizeof(buf), ISSET(flags, TGP_MASK), &errval);
+ alarm(0);
+ save_errno = errno;
+
+ if (neednl || pass == NULL) {
+ if (write(output, "\n", 1) == -1)
+ goto restore;
+ }
+ tgetpass_display_error(errval);
+
+restore:
+ /* Restore old signal handlers. */
+ (void) sigaction(SIGALRM, &savealrm, NULL);
+ (void) sigaction(SIGINT, &saveint, NULL);
+ (void) sigaction(SIGHUP, &savehup, NULL);
+ (void) sigaction(SIGQUIT, &savequit, NULL);
+ (void) sigaction(SIGTERM, &saveterm, NULL);
+ (void) sigaction(SIGTSTP, &savetstp, NULL);
+ (void) sigaction(SIGTTIN, &savettin, NULL);
+ (void) sigaction(SIGTTOU, &savettou, NULL);
+
+ /* Restore old tty settings. */
+ if (!ISSET(flags, TGP_ECHO)) {
+ /* Restore old tty settings if possible. */
+ (void) sudo_term_restore(input, true);
+ }
+ if (input != STDIN_FILENO)
+ (void) close(input);
+
+ /*
+ * If we were interrupted by a signal, resend it to ourselves
+ * now that we have restored the signal handlers.
+ */
+ for (i = 0; i < NSIG; i++) {
+ if (signo[i]) {
+ switch (i) {
+ case SIGALRM:
+ break;
+ case SIGTSTP:
+ case SIGTTIN:
+ case SIGTTOU:
+ if (suspend(i, callback) == 0)
+ need_restart = 1;
+ break;
+ default:
+ kill(getpid(), i);
+ break;
+ }
+ }
+ }
+ if (need_restart)
+ goto restart;
+
+ if (save_errno)
+ errno = save_errno;
+
+ debug_return_str_masked(pass);
+}
+
+/*
+ * Fork a child and exec sudo-askpass to get the password from the user.
+ */
+static char *
+sudo_askpass(const char *askpass, const char *prompt)
+{
+ static char buf[SUDO_CONV_REPL_MAX + 1], *pass;
+ struct sigaction sa, savechld;
+ enum tgetpass_errval errval;
+ int pfd[2], status;
+ pid_t child;
+ debug_decl(sudo_askpass, SUDO_DEBUG_CONV)
+
+ /* Set SIGCHLD handler to default since we call waitpid() below. */
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = SIG_DFL;
+ (void) sigaction(SIGCHLD, &sa, &savechld);
+
+ if (pipe(pfd) == -1)
+ sudo_fatal(U_("unable to create pipe"));
+
+ child = sudo_debug_fork();
+ if (child == -1)
+ sudo_fatal(U_("unable to fork"));
+
+ if (child == 0) {
+ /* child, point stdout to output side of the pipe and exec askpass */
+ if (dup2(pfd[1], STDOUT_FILENO) == -1) {
+ sudo_warn("dup2");
+ _exit(255);
+ }
+ if (setuid(ROOT_UID) == -1)
+ sudo_warn("setuid(%d)", ROOT_UID);
+ if (setgid(user_details.gid)) {
+ sudo_warn(U_("unable to set gid to %u"), (unsigned int)user_details.gid);
+ _exit(255);
+ }
+ if (setuid(user_details.uid)) {
+ sudo_warn(U_("unable to set uid to %u"), (unsigned int)user_details.uid);
+ _exit(255);
+ }
+ closefrom(STDERR_FILENO + 1);
+ execl(askpass, askpass, prompt, (char *)NULL);
+ sudo_warn(U_("unable to run %s"), askpass);
+ _exit(255);
+ }
+
+ /* Get response from child (askpass). */
+ (void) close(pfd[1]);
+ pass = getln(pfd[0], buf, sizeof(buf), 0, &errval);
+ (void) close(pfd[0]);
+
+ tgetpass_display_error(errval);
+
+ /* Wait for child to exit. */
+ for (;;) {
+ pid_t rv = waitpid(child, &status, 0);
+ if (rv == -1 && errno != EINTR)
+ break;
+ if (rv != -1 && !WIFSTOPPED(status))
+ break;
+ }
+
+ if (pass == NULL)
+ errno = EINTR; /* make cancel button simulate ^C */
+
+ /* Restore saved SIGCHLD handler. */
+ (void) sigaction(SIGCHLD, &savechld, NULL);
+
+ debug_return_str_masked(pass);
+}
+
+extern int sudo_term_eof, sudo_term_erase, sudo_term_kill;
+
+static char *
+getln(int fd, char *buf, size_t bufsiz, int feedback,
+ enum tgetpass_errval *errval)
+{
+ size_t left = bufsiz;
+ ssize_t nr = -1;
+ char *cp = buf;
+ char c = '\0';
+ debug_decl(getln, SUDO_DEBUG_CONV)
+
+ *errval = TGP_ERRVAL_NOERROR;
+
+ if (left == 0) {
+ *errval = TGP_ERRVAL_READERROR;
+ errno = EINVAL;
+ debug_return_str(NULL); /* sanity */
+ }
+
+ while (--left) {
+ nr = read(fd, &c, 1);
+ if (nr != 1 || c == '\n' || c == '\r')
+ break;
+ if (feedback) {
+ if (c == sudo_term_eof) {
+ nr = 0;
+ break;
+ } else if (c == sudo_term_kill) {
+ while (cp > buf) {
+ if (write(fd, "\b \b", 3) == -1)
+ break;
+ --cp;
+ }
+ left = bufsiz;
+ continue;
+ } else if (c == sudo_term_erase) {
+ if (cp > buf) {
+ if (write(fd, "\b \b", 3) == -1)
+ break;
+ --cp;
+ left++;
+ }
+ continue;
+ }
+ ignore_result(write(fd, "*", 1));
+ }
+ *cp++ = c;
+ }
+ *cp = '\0';
+ if (feedback) {
+ /* erase stars */
+ while (cp > buf) {
+ if (write(fd, "\b \b", 3) == -1)
+ break;
+ --cp;
+ }
+ }
+
+ switch (nr) {
+ case -1:
+ /* Read error */
+ if (errno == EINTR) {
+ if (signo[SIGALRM] == 1)
+ *errval = TGP_ERRVAL_TIMEOUT;
+ } else {
+ *errval = TGP_ERRVAL_READERROR;
+ }
+ debug_return_str(NULL);
+ case 0:
+ /* EOF is only an error if no bytes were read. */
+ if (left == bufsiz - 1) {
+ *errval = TGP_ERRVAL_NOPASSWORD;
+ debug_return_str(NULL);
+ }
+ /* FALLTHROUGH */
+ default:
+ debug_return_str_masked(buf);
+ }
+}
+
+static void
+tgetpass_handler(int s)
+{
+ signo[s] = 1;
+}
+
+static bool
+tty_present(void)
+{
+#if defined(HAVE_KINFO_PROC2_NETBSD) || defined(HAVE_KINFO_PROC_OPENBSD) || defined(HAVE_KINFO_PROC_FREEBSD) || defined(HAVE_KINFO_PROC_44BSD) || defined(HAVE_STRUCT_PSINFO_PR_TTYDEV) || defined(HAVE_PSTAT_GETPROC) || defined(__linux__)
+ debug_decl(tty_present, SUDO_DEBUG_UTIL)
+ debug_return_bool(user_details.tty != NULL);
+#else
+ int fd;
+ debug_decl(tty_present, SUDO_DEBUG_UTIL)
+
+ if ((fd = open(_PATH_TTY, O_RDWR)) != -1)
+ close(fd);
+ debug_return_bool(fd != -1);
+#endif
+}
diff --git a/src/ttyname.c b/src/ttyname.c
new file mode 100644
index 0000000..580bafd
--- /dev/null
+++ b/src/ttyname.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2012-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+/* Large files not supported by procfs.h on Solaris. */
+#if defined(HAVE_STRUCT_PSINFO_PR_TTYDEV)
+# undef _FILE_OFFSET_BITS
+# undef _LARGE_FILES
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#if defined(MAJOR_IN_MKDEV)
+# include <sys/mkdev.h>
+#elif defined(MAJOR_IN_SYSMACROS)
+# include <sys/sysmacros.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <dirent.h>
+#if defined(HAVE_KINFO_PROC2_NETBSD) || defined (HAVE_KINFO_PROC_OPENBSD) || defined(HAVE_KINFO_PROC_44BSD)
+# include <sys/sysctl.h>
+#elif defined(HAVE_KINFO_PROC_FREEBSD)
+# include <sys/sysctl.h>
+# include <sys/user.h>
+#endif
+#if defined(HAVE_PROCFS_H)
+# include <procfs.h>
+#elif defined(HAVE_SYS_PROCFS_H)
+# include <sys/procfs.h>
+#endif
+#ifdef HAVE_PSTAT_GETPROC
+# include <sys/pstat.h>
+#endif
+
+#include "sudo.h"
+
+/*
+ * How to access the tty device number in struct kinfo_proc.
+ */
+#if defined(HAVE_KINFO_PROC2_NETBSD)
+# define SUDO_KERN_PROC KERN_PROC2
+# define sudo_kinfo_proc kinfo_proc2
+# define sudo_kp_tdev p_tdev
+# define sudo_kp_namelen 6
+#elif defined(HAVE_KINFO_PROC_OPENBSD)
+# define SUDO_KERN_PROC KERN_PROC
+# define sudo_kinfo_proc kinfo_proc
+# define sudo_kp_tdev p_tdev
+# define sudo_kp_namelen 6
+#elif defined(HAVE_KINFO_PROC_FREEBSD)
+# define SUDO_KERN_PROC KERN_PROC
+# define sudo_kinfo_proc kinfo_proc
+# define sudo_kp_tdev ki_tdev
+# define sudo_kp_namelen 4
+#elif defined(HAVE_KINFO_PROC_44BSD)
+# define SUDO_KERN_PROC KERN_PROC
+# define sudo_kinfo_proc kinfo_proc
+# define sudo_kp_tdev kp_eproc.e_tdev
+# define sudo_kp_namelen 4
+#endif
+
+#if defined(sudo_kp_tdev)
+/*
+ * Store the name of the tty to which the process is attached in name.
+ * Returns name on success and NULL on failure, setting errno.
+ */
+char *
+get_process_ttyname(char *name, size_t namelen)
+{
+ struct sudo_kinfo_proc *ki_proc = NULL;
+ size_t size = sizeof(*ki_proc);
+ int mib[6], rc, serrno = errno;
+ char *ret = NULL;
+ debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL)
+
+ /*
+ * Lookup controlling tty for this process via sysctl.
+ * This will work even if std{in,out,err} are redirected.
+ */
+ mib[0] = CTL_KERN;
+ mib[1] = SUDO_KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = (int)getpid();
+ mib[4] = sizeof(*ki_proc);
+ mib[5] = 1;
+ do {
+ struct sudo_kinfo_proc *kp;
+
+ size += size / 10;
+ if ((kp = realloc(ki_proc, size)) == NULL) {
+ rc = -1;
+ break; /* really out of memory. */
+ }
+ ki_proc = kp;
+ rc = sysctl(mib, sudo_kp_namelen, ki_proc, &size, NULL, 0);
+ } while (rc == -1 && errno == ENOMEM);
+ errno = ENOENT;
+ if (rc != -1) {
+ if ((dev_t)ki_proc->sudo_kp_tdev != (dev_t)-1) {
+ errno = serrno;
+ ret = sudo_ttyname_dev(ki_proc->sudo_kp_tdev, name, namelen);
+ if (ret == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "unable to map device number %u to name",
+ ki_proc->sudo_kp_tdev);
+ }
+ }
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "unable to resolve tty via KERN_PROC");
+ }
+ free(ki_proc);
+
+ debug_return_str(ret);
+}
+#elif defined(HAVE_STRUCT_PSINFO_PR_TTYDEV)
+/*
+ * Store the name of the tty to which the process is attached in name.
+ * Returns name on success and NULL on failure, setting errno.
+ */
+char *
+get_process_ttyname(char *name, size_t namelen)
+{
+ char path[PATH_MAX], *ret = NULL;
+ struct psinfo psinfo;
+ ssize_t nread;
+ int fd, serrno = errno;
+ debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL)
+
+ /* Try to determine the tty from pr_ttydev in /proc/pid/psinfo. */
+ snprintf(path, sizeof(path), "/proc/%u/psinfo", (unsigned int)getpid());
+ if ((fd = open(path, O_RDONLY, 0)) != -1) {
+ nread = read(fd, &psinfo, sizeof(psinfo));
+ close(fd);
+ if (nread == (ssize_t)sizeof(psinfo)) {
+ dev_t rdev = (dev_t)psinfo.pr_ttydev;
+#if defined(_AIX) && defined(DEVNO64)
+ if ((psinfo.pr_ttydev & DEVNO64) && sizeof(dev_t) == 4)
+ rdev = makedev(major64(psinfo.pr_ttydev), minor64(psinfo.pr_ttydev));
+#endif
+ if (rdev != (dev_t)-1) {
+ errno = serrno;
+ ret = sudo_ttyname_dev(rdev, name, namelen);
+ goto done;
+ }
+ }
+ }
+ errno = ENOENT;
+
+done:
+ if (ret == NULL)
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "unable to resolve tty via %s", path);
+
+ debug_return_str(ret);
+}
+#elif defined(__linux__)
+/*
+ * Store the name of the tty to which the process is attached in name.
+ * Returns name on success and NULL on failure, setting errno.
+ */
+char *
+get_process_ttyname(char *name, size_t namelen)
+{
+ const char path[] = "/proc/self/stat";
+ char *cp, buf[1024];
+ char *ret = NULL;
+ int serrno = errno;
+ ssize_t nread;
+ int fd;
+ debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL)
+
+ /*
+ * Try to determine the tty from tty_nr in /proc/self/stat.
+ * Ignore /proc/self/stat if it contains embedded NUL bytes.
+ */
+ if ((fd = open(path, O_RDONLY | O_NOFOLLOW)) != -1) {
+ cp = buf;
+ while ((nread = read(fd, cp, buf + sizeof(buf) - cp)) != 0) {
+ if (nread == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ break;
+ }
+ cp += nread;
+ if (cp >= buf + sizeof(buf))
+ break;
+ }
+ if (nread == 0 && memchr(buf, '\0', cp - buf) == NULL) {
+ /*
+ * Field 7 is the tty dev (0 if no tty).
+ * Since the process name at field 2 "(comm)" may include
+ * whitespace (including newlines), start at the last ')' found.
+ */
+ *cp = '\0';
+ cp = strrchr(buf, ')');
+ if (cp != NULL) {
+ char *ep = cp;
+ const char *errstr;
+ int field = 1;
+
+ while (*++ep != '\0') {
+ if (*ep == ' ') {
+ *ep = '\0';
+ if (++field == 7) {
+ int tty_nr = strtonum(cp, INT_MIN, INT_MAX, &errstr);
+ if (errstr) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "%s: tty device %s: %s", path, cp, errstr);
+ }
+ if (tty_nr != 0) {
+ /*
+ * Avoid sign extension when assigning tdev.
+ * tty_nr in /proc/self/stat is printed as a
+ * signed int but the actual device number is an
+ * unsigned int and dev_t is unsigned long long.
+ */
+ dev_t tdev = (unsigned int)tty_nr;
+ errno = serrno;
+ ret = sudo_ttyname_dev(tdev, name, namelen);
+ goto done;
+ }
+ break;
+ }
+ cp = ep + 1;
+ }
+ }
+ }
+ }
+ }
+ errno = ENOENT;
+
+done:
+ if (fd != -1)
+ close(fd);
+ if (ret == NULL)
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "unable to resolve tty via %s", path);
+
+ debug_return_str(ret);
+}
+#elif defined(HAVE_PSTAT_GETPROC)
+/*
+ * Store the name of the tty to which the process is attached in name.
+ * Returns name on success and NULL on failure, setting errno.
+ */
+char *
+get_process_ttyname(char *name, size_t namelen)
+{
+ struct pst_status pstat;
+ char *ret = NULL;
+ int rc, serrno = errno;
+ debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL)
+
+ /*
+ * Determine the tty from psdev in struct pst_status.
+ * We may get EOVERFLOW if the whole thing doesn't fit but that is OK.
+ */
+ rc = pstat_getproc(&pstat, sizeof(pstat), (size_t)0, (int)getpid());
+ if (rc != -1 || errno == EOVERFLOW) {
+ if (pstat.pst_term.psd_major != -1 && pstat.pst_term.psd_minor != -1) {
+ errno = serrno;
+ ret = sudo_ttyname_dev(makedev(pstat.pst_term.psd_major,
+ pstat.pst_term.psd_minor), name, namelen);
+ goto done;
+ }
+ }
+ errno = ENOENT;
+
+done:
+ if (ret == NULL)
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "unable to resolve tty via pstat");
+
+ debug_return_str(ret);
+}
+#else
+/*
+ * Store the name of the tty to which the process is attached in name.
+ * Returns name on success and NULL on failure, setting errno.
+ */
+char *
+get_process_ttyname(char *name, size_t namelen)
+{
+ char *tty;
+ debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL)
+
+ if ((tty = ttyname(STDIN_FILENO)) == NULL) {
+ if ((tty = ttyname(STDOUT_FILENO)) == NULL)
+ tty = ttyname(STDERR_FILENO);
+ }
+ if (tty != NULL) {
+ if (strlcpy(name, tty, namelen) < namelen)
+ debug_return_str(name);
+ errno = ERANGE;
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "unable to store tty from ttyname");
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ "unable to resolve tty via ttyname");
+ errno = ENOENT;
+ }
+
+ debug_return_str(NULL);
+}
+#endif
diff --git a/src/utmp.c b/src/utmp.c
new file mode 100644
index 0000000..b371bbf
--- /dev/null
+++ b/src/utmp.c
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2011-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <unistd.h>
+#include <time.h>
+#if defined(HAVE_UTMPS_H)
+# include <utmps.h>
+#elif defined(HAVE_UTMPX_H)
+# include <utmpx.h>
+#else
+# include <utmp.h>
+#endif /* HAVE_UTMPS_H */
+#ifdef HAVE_GETTTYENT
+# include <ttyent.h>
+#endif
+#include <fcntl.h>
+#include <signal.h>
+
+#include "sudo.h"
+#include "sudo_exec.h"
+
+/*
+ * Simplify handling of different utmp types.
+ */
+#if defined(HAVE_GETUTSID)
+# define sudo_getutline(u) GETUTSLINE(u)
+# define sudo_pututline(u) PUTUTSLINE(u)
+# define sudo_setutent() SETUTSENT()
+# define sudo_endutent() ENDUTSENT()
+#elif defined(HAVE_GETUTXID)
+# define sudo_getutline(u) getutxline(u)
+# define sudo_pututline(u) pututxline(u)
+# define sudo_setutent() setutxent()
+# define sudo_endutent() endutxent()
+#elif defined(HAVE_GETUTID)
+# define sudo_getutline(u) getutline(u)
+# define sudo_pututline(u) pututline(u)
+# define sudo_setutent() setutent()
+# define sudo_endutent() endutent()
+#endif
+
+#if defined(HAVE_GETUTSID)
+typedef struct utmps sudo_utmp_t;
+#elif defined(HAVE_GETUTXID)
+typedef struct utmpx sudo_utmp_t;
+#else
+typedef struct utmp sudo_utmp_t;
+/* Older systems have ut_name, not ut_user */
+# if !defined(HAVE_STRUCT_UTMP_UT_USER) && !defined(ut_user)
+# define ut_user ut_name
+# endif
+#endif
+
+/* HP-UX has __e_termination and __e_exit, others may lack the __ */
+#if defined(HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION)
+# undef __e_termination
+# define __e_termination e_termination
+# undef __e_exit
+# define __e_exit e_exit
+#endif
+
+#if defined(HAVE_GETUTSID) || defined(HAVE_GETUTXID) || defined(HAVE_GETUTID)
+/*
+ * Create ut_id from the new ut_line and the old ut_id.
+ */
+static void
+utmp_setid(sudo_utmp_t *old, sudo_utmp_t *new)
+{
+ const char *line = new->ut_line;
+ size_t idlen;
+ debug_decl(utmp_setid, SUDO_DEBUG_UTMP)
+
+ /* Skip over "tty" in the id if old entry did too. */
+ if (old != NULL) {
+ /* cppcheck-suppress uninitdata */
+ if (strncmp(line, "tty", 3) == 0) {
+ idlen = MIN(sizeof(old->ut_id), 3);
+ if (strncmp(old->ut_id, "tty", idlen) != 0)
+ line += 3;
+ }
+ }
+
+ /* Store as much as will fit, skipping parts of the beginning as needed. */
+ /* cppcheck-suppress uninitdata */
+ idlen = strlen(line);
+ if (idlen > sizeof(new->ut_id)) {
+ line += idlen - sizeof(new->ut_id);
+ idlen = sizeof(new->ut_id);
+ }
+ strncpy(new->ut_id, line, idlen);
+
+ debug_return;
+}
+#endif /* HAVE_GETUTSID || HAVE_GETUTXID || HAVE_GETUTID */
+
+/*
+ * Store time in utmp structure.
+ */
+static void
+utmp_settime(sudo_utmp_t *ut)
+{
+ struct timeval tv;
+ debug_decl(utmp_settime, SUDO_DEBUG_UTMP)
+
+ if (gettimeofday(&tv, NULL) == 0) {
+#if defined(HAVE_STRUCT_UTMP_UT_TV)
+ ut->ut_tv.tv_sec = tv.tv_sec;
+ ut->ut_tv.tv_usec = tv.tv_usec;
+#else
+ ut->ut_time = tv.tv_sec;
+#endif
+ }
+
+ debug_return;
+}
+
+/*
+ * Fill in a utmp entry, using an old entry as a template if there is one.
+ */
+static void
+utmp_fill(const char *line, const char *user, sudo_utmp_t *ut_old,
+ sudo_utmp_t *ut_new)
+{
+ debug_decl(utmp_file, SUDO_DEBUG_UTMP)
+
+ if (ut_old == NULL) {
+ memset(ut_new, 0, sizeof(*ut_new));
+ if (user == NULL) {
+ strncpy(ut_new->ut_user, user_details.username,
+ sizeof(ut_new->ut_user));
+ }
+ } else if (ut_old != ut_new) {
+ memcpy(ut_new, ut_old, sizeof(*ut_new));
+ }
+ if (user != NULL)
+ strncpy(ut_new->ut_user, user, sizeof(ut_new->ut_user));
+ strncpy(ut_new->ut_line, line, sizeof(ut_new->ut_line));
+#if defined(HAVE_STRUCT_UTMP_UT_ID)
+ utmp_setid(ut_old, ut_new);
+#endif
+#if defined(HAVE_STRUCT_UTMP_UT_PID)
+ ut_new->ut_pid = getpid();
+#endif
+ utmp_settime(ut_new);
+#if defined(HAVE_STRUCT_UTMP_UT_TYPE)
+ ut_new->ut_type = USER_PROCESS;
+#endif
+ debug_return;
+}
+
+/*
+ * There are two basic utmp file types:
+ *
+ * POSIX: sequential access with new entries appended to the end.
+ * Manipulated via {get,put}[sx]?utent()
+ *
+ * Legacy: sparse file indexed by ttyslot() * sizeof(struct utmp)
+ */
+#if defined(HAVE_GETUTSID) || defined(HAVE_GETUTXID) || defined(HAVE_GETUTID)
+bool
+utmp_login(const char *from_line, const char *to_line, int ttyfd,
+ const char *user)
+{
+ sudo_utmp_t utbuf, *ut_old = NULL;
+ bool ret = false;
+ debug_decl(utmp_login, SUDO_DEBUG_UTMP)
+
+ /* Strip off /dev/ prefix from line as needed. */
+ if (strncmp(to_line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+ to_line += sizeof(_PATH_DEV) - 1;
+ sudo_setutent();
+ if (from_line != NULL) {
+ if (strncmp(from_line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+ from_line += sizeof(_PATH_DEV) - 1;
+
+ /* Lookup old line. */
+ memset(&utbuf, 0, sizeof(utbuf));
+ strncpy(utbuf.ut_line, from_line, sizeof(utbuf.ut_line));
+ ut_old = sudo_getutline(&utbuf);
+ }
+ utmp_fill(to_line, user, ut_old, &utbuf);
+ if (sudo_pututline(&utbuf) != NULL)
+ ret = true;
+ sudo_endutent();
+
+ debug_return_bool(ret);
+}
+
+bool
+utmp_logout(const char *line, int status)
+{
+ bool ret = false;
+ sudo_utmp_t *ut, utbuf;
+ debug_decl(utmp_logout, SUDO_DEBUG_UTMP)
+
+ /* Strip off /dev/ prefix from line as needed. */
+ if (strncmp(line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+ line += sizeof(_PATH_DEV) - 1;
+
+ memset(&utbuf, 0, sizeof(utbuf));
+ strncpy(utbuf.ut_line, line, sizeof(utbuf.ut_line));
+ if ((ut = sudo_getutline(&utbuf)) != NULL) {
+ memset(ut->ut_user, 0, sizeof(ut->ut_user));
+# if defined(HAVE_STRUCT_UTMP_UT_TYPE)
+ ut->ut_type = DEAD_PROCESS;
+# endif
+# if defined(HAVE_STRUCT_UTMP_UT_EXIT)
+ ut->ut_exit.__e_termination = WIFSIGNALED(status) ? WTERMSIG(status) : 0;
+ ut->ut_exit.__e_exit = WIFEXITED(status) ? WEXITSTATUS(status) : 0;
+# endif
+ utmp_settime(ut);
+ if (sudo_pututline(ut) != NULL)
+ ret = true;
+ }
+ debug_return_bool(ret);
+}
+
+#else /* !HAVE_GETUTSID && !HAVE_GETUTXID && !HAVE_GETUTID */
+
+/*
+ * Find the slot for the specified line (tty name and file descriptor).
+ * Returns a slot suitable for seeking into utmp on success or <= 0 on error.
+ * If getttyent() is available we can use that to compute the slot.
+ */
+# ifdef HAVE_GETTTYENT
+static int
+utmp_slot(const char *line, int ttyfd)
+{
+ int slot = 1;
+ struct ttyent *tty;
+ debug_decl(utmp_slot, SUDO_DEBUG_UTMP)
+
+ setttyent();
+ while ((tty = getttyent()) != NULL) {
+ if (strcmp(line, tty->ty_name) == 0)
+ break;
+ slot++;
+ }
+ endttyent();
+ debug_return_int(tty ? slot : 0);
+}
+# else
+static int
+utmp_slot(const char *line, int ttyfd)
+{
+ int sfd, slot;
+ debug_decl(utmp_slot, SUDO_DEBUG_UTMP)
+
+ /*
+ * Temporarily point stdin to the tty since ttyslot()
+ * doesn't take an argument.
+ */
+ if ((sfd = dup(STDIN_FILENO)) == -1)
+ sudo_fatal(U_("unable to save stdin"));
+ if (dup2(ttyfd, STDIN_FILENO) == -1)
+ sudo_fatal(U_("unable to dup2 stdin"));
+ slot = ttyslot();
+ if (dup2(sfd, STDIN_FILENO) == -1)
+ sudo_fatal(U_("unable to restore stdin"));
+ close(sfd);
+
+ debug_return_int(slot);
+}
+# endif /* HAVE_GETTTYENT */
+
+bool
+utmp_login(const char *from_line, const char *to_line, int ttyfd,
+ const char *user)
+{
+ sudo_utmp_t utbuf, *ut_old = NULL;
+ bool ret = false;
+ int slot;
+ FILE *fp;
+ debug_decl(utmp_login, SUDO_DEBUG_UTMP)
+
+ /* Strip off /dev/ prefix from line as needed. */
+ if (strncmp(to_line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+ to_line += sizeof(_PATH_DEV) - 1;
+
+ /* Find slot for new entry. */
+ slot = utmp_slot(to_line, ttyfd);
+ if (slot <= 0)
+ goto done;
+
+ if ((fp = fopen(_PATH_UTMP, "r+")) == NULL)
+ goto done;
+
+ if (from_line != NULL) {
+ if (strncmp(from_line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+ from_line += sizeof(_PATH_DEV) - 1;
+
+ /* Lookup old line. */
+ while (fread(&utbuf, sizeof(utbuf), 1, fp) == 1) {
+# ifdef HAVE_STRUCT_UTMP_UT_ID
+ if (utbuf.ut_type != LOGIN_PROCESS && utbuf.ut_type != USER_PROCESS)
+ continue;
+# endif
+ if (utbuf.ut_user[0] &&
+ !strncmp(utbuf.ut_line, from_line, sizeof(utbuf.ut_line))) {
+ ut_old = &utbuf;
+ break;
+ }
+ }
+ }
+ utmp_fill(to_line, user, ut_old, &utbuf);
+# ifdef HAVE_FSEEKO
+ if (fseeko(fp, slot * (off_t)sizeof(utbuf), SEEK_SET) == 0) {
+# else
+ if (fseek(fp, slot * (long)sizeof(utbuf), SEEK_SET) == 0) {
+# endif
+ if (fwrite(&utbuf, sizeof(utbuf), 1, fp) == 1)
+ ret = true;
+ }
+ fclose(fp);
+
+done:
+ debug_return_bool(ret);
+}
+
+bool
+utmp_logout(const char *line, int status)
+{
+ sudo_utmp_t utbuf;
+ bool ret = false;
+ FILE *fp;
+ debug_decl(utmp_logout, SUDO_DEBUG_UTMP)
+
+ if ((fp = fopen(_PATH_UTMP, "r+")) == NULL)
+ debug_return_int(ret);
+
+ /* Strip off /dev/ prefix from line as needed. */
+ if (strncmp(line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+ line += sizeof(_PATH_DEV) - 1;
+
+ while (fread(&utbuf, sizeof(utbuf), 1, fp) == 1) {
+ if (!strncmp(utbuf.ut_line, line, sizeof(utbuf.ut_line))) {
+ memset(utbuf.ut_user, 0, sizeof(utbuf.ut_user));
+# if defined(HAVE_STRUCT_UTMP_UT_TYPE)
+ utbuf.ut_type = DEAD_PROCESS;
+# endif
+ utmp_settime(&utbuf);
+ /* Back up and overwrite record. */
+# ifdef HAVE_FSEEKO
+ if (fseeko(fp, (off_t)0 - (off_t)sizeof(utbuf), SEEK_CUR) == 0) {
+# else
+ if (fseek(fp, 0L - (long)sizeof(utbuf), SEEK_CUR) == 0) {
+# endif
+ if (fwrite(&utbuf, sizeof(utbuf), 1, fp) == 1)
+ ret = true;
+ }
+ break;
+ }
+ }
+ fclose(fp);
+
+ debug_return_bool(ret);
+}
+#endif /* HAVE_GETUTSID || HAVE_GETUTXID || HAVE_GETUTID */
diff --git a/sudo.pp b/sudo.pp
new file mode 100644
index 0000000..166c560
--- /dev/null
+++ b/sudo.pp
@@ -0,0 +1,531 @@
+%set
+ if test -n "$flavor"; then
+ name="sudo-$flavor"
+ pp_kit_package="sudo_$flavor"
+ else
+ name="sudo"
+ pp_kit_package="sudo"
+ fi
+ summary="Provide limited super-user privileges to specific users"
+ description="Sudo is a program designed to allow a sysadmin to give \
+limited root privileges to users and log root activity. \
+The basic philosophy is to give as few privileges as possible but \
+still allow people to get their work done."
+ vendor="Todd C. Miller"
+ copyright="(c) 1993-1996,1998-2016 Todd C. Miller"
+ sudoedit_man=`echo ${pp_destdir}$mandir/*/sudoedit.*|sed "s:^${pp_destdir}::"`
+ sudoedit_man_target=`basename $sudoedit_man | sed 's/edit//'`
+
+%if [aix]
+ # AIX package summary is limited to 40 characters
+ summary="Configurable super-user privileges"
+
+ # Convert to 4 part version for AIX, including patch level
+ pp_aix_version=`echo $version|sed -e 's/^\([0-9]*\.[0-9]*\.[0-9]*\)p\([0-9]*\)$/\1.\2/' -e 's/^\([0-9]*\.[0-9]*\.[0-9]*\)[^0-9\.].*$/\1/' -e 's/^\([0-9]*\.[0-9]*\.[0-9]*\)$/\1.0/'`
+%endif
+
+%if [kit]
+ # Strip off patchlevel for kit which only supports xyz versions
+ pp_kit_version="`echo $version|sed -e 's/\.//g' -e 's/[^0-9][^0-9]*[0-9][0-9]*$//'`"
+ pp_kit_name="TCM"
+%endif
+
+%if [sd]
+ pp_sd_vendor_tag="TCM"
+%endif
+
+%if [solaris]
+ pp_solaris_name="TCM${name}"
+ pp_solaris_pstamp=`/usr/bin/date "+%B %d, %Y"`
+%endif
+
+%if [macos]
+ # System Integrity Protection on macOS won't allow us to write
+ # directly to /etc or /var. We must install in /private instead.
+ case "$sudoersdir" in
+ /etc|/etc/*)
+ mkdir -p ${pp_destdir}/private
+ chmod 755 ${pp_destdir}/private
+ if test -d ${pp_destdir}/etc; then
+ mv ${pp_destdir}/etc ${pp_destdir}/private/etc
+ fi
+ sudoersdir="/private${sudoersdir}"
+ ;;
+ esac
+ case "$vardir" in
+ /var|/var/*)
+ mkdir -p ${pp_destdir}/private
+ chmod 755 ${pp_destdir}/private
+ if test -d ${pp_destdir}/var; then
+ mv ${pp_destdir}/var ${pp_destdir}/private/var
+ fi
+ vardir="/private${vardir}"
+ ;;
+ esac
+ case "$rundir" in
+ /var|/var/*)
+ mkdir -p ${pp_destdir}/private
+ chmod 755 ${pp_destdir}/private
+ if test -d ${pp_destdir}/var; then
+ mv ${pp_destdir}/var ${pp_destdir}/private/var
+ fi
+ rundir="/private${rundir}"
+ ;;
+ esac
+%endif
+
+%if [rpm,deb]
+ # Convert patch level into release and remove from version
+ pp_rpm_release="`expr \( $version : '.*p\([0-9][0-9]*\)$' \| 0 \) + 1`"
+ pp_rpm_version="`expr \( $version : '\(.*\)p[0-9][0-9]*$' \| $version \)`"
+ pp_rpm_license="BSD"
+ pp_rpm_url="https://www.sudo.ws"
+ pp_rpm_group="Applications/System"
+ pp_rpm_packager="Todd C. Miller <Todd.Miller@sudo.ws>"
+ if test -n "$linux_audit"; then
+ pp_rpm_requires="audit-libs >= $linux_audit"
+ fi
+ # The package manager will handle an existing sudoers file
+ rm -f ${pp_destdir}$sudoersdir/sudoers.dist
+%else
+ # For all but RPM and Debian we copy sudoers in a post-install script.
+ rm -f ${pp_destdir}$sudoersdir/sudoers
+%endif
+
+%if [deb]
+ pp_deb_maintainer="$pp_rpm_packager"
+ pp_deb_release="$pp_rpm_release"
+ pp_deb_version="$pp_rpm_version"
+ pp_deb_section=admin
+ install -D -m 644 ${pp_destdir}$docdir/LICENSE ${pp_wrkdir}/${name}/usr/share/doc/${name}/copyright
+ install -D -m 644 ${pp_destdir}$docdir/ChangeLog ${pp_wrkdir}/${name}/usr/share/doc/${name}/changelog
+ gzip -9f ${pp_wrkdir}/${name}/usr/share/doc/${name}/changelog
+ printf "$name ($pp_deb_version-$pp_deb_release) admin; urgency=low\n\n * see upstream changelog\n\n -- $pp_deb_maintainer `date '+%a, %d %b %Y %T %z'`\n" > ${pp_wrkdir}/${name}/usr/share/doc/${name}/changelog.Debian
+ chmod 644 ${pp_wrkdir}/${name}/usr/share/doc/${name}/changelog.Debian
+ gzip -9f ${pp_wrkdir}/${name}/usr/share/doc/${name}/changelog.Debian
+ # Create lintian override file
+ mkdir -p ${pp_wrkdir}/${name}/usr/share/lintian/overrides
+ cat >${pp_wrkdir}/${name}/usr/share/lintian/overrides/${name} <<-EOF
+ # The sudo binary must be setuid root
+ $name: setuid-binary usr/bin/sudo 4755 root/root
+ # Sudo configuration and data dirs must not be world-readable
+ $name: non-standard-file-perm etc/sudoers 0440 != 0644
+ $name: non-standard-dir-perm etc/sudoers.d/ 0750 != 0755
+ $name: non-standard-dir-perm var/lib/sudo/ 0700 != 0755
+ # Sudo ships with debugging symbols
+ $name: unstripped-binary-or-object
+ EOF
+ chmod 644 ${pp_wrkdir}/${name}/usr/share/lintian/overrides/${name}
+%endif
+
+%if [rpm]
+ # Add distro info to release
+ osrelease=`echo "$pp_rpm_distro" | sed -e 's/^[^0-9]*\([0-9]\{1,2\}\).*/\1/'`
+ case "$pp_rpm_distro" in
+ centos*|rhel*|f[0-9]*)
+ pp_rpm_release="$pp_rpm_release.el${osrelease%%[0-9]}"
+ ;;
+ sles*)
+ pp_rpm_release="$pp_rpm_release.sles$osrelease"
+ ;;
+ esac
+
+ # Uncomment some Defaults in sudoers
+ # Note that the order must match that of sudoers.
+ case "$pp_rpm_distro" in
+ centos*|rhel*|f[0-9]*)
+ chmod u+w ${pp_destdir}${sudoersdir}/sudoers
+ /bin/ed - ${pp_destdir}${sudoersdir}/sudoers <<-'EOF'
+ /Locale settings/+1,s/^# //
+ /Desktop path settings/+1,s/^# //
+ /allow members of group wheel to execute any command/+1,s/^# //
+ w
+ q
+ EOF
+ chmod u-w ${pp_destdir}${sudoersdir}/sudoers
+ ;;
+ sles*)
+ chmod u+w ${pp_destdir}${sudoersdir}/sudoers
+ /bin/ed - ${pp_destdir}${sudoersdir}/sudoers <<-'EOF'
+ /Locale settings/+1,s/^# //
+ /ConsoleKit session/+1,s/^# //
+ /allow any user to run sudo if they know the password/+2,s/^# //
+ /allow any user to run sudo if they know the password/+3,s/^# //
+ w
+ q
+ EOF
+ chmod u-w ${pp_destdir}${sudoersdir}/sudoers
+ ;;
+ esac
+
+ # For RedHat the doc dir is expected to include version and release
+ case "$pp_rpm_distro" in
+ centos*|rhel*|f[0-9]*)
+ rhel_docdir="${docdir}-${pp_rpm_version}-${pp_rpm_release}"
+ if test "`dirname ${exampledir}`" = "${docdir}"; then
+ exampledir="${rhel_docdir}/`basename ${exampledir}`"
+ fi
+ mv "${pp_destdir}/${docdir}" "${pp_destdir}/${rhel_docdir}"
+ docdir="${rhel_docdir}"
+ ;;
+ esac
+
+ # Choose the correct PAM file by distro, must be tab indented for "<<-"
+ case "$pp_rpm_distro" in
+ centos*|rhel*)
+ mkdir -p ${pp_destdir}/etc/pam.d
+ if test $osrelease -lt 50; then
+ cat > ${pp_destdir}/etc/pam.d/sudo <<-EOF
+ #%PAM-1.0
+ auth required pam_stack.so service=system-auth
+ account required pam_stack.so service=system-auth
+ password required pam_stack.so service=system-auth
+ session required pam_limits.so
+ EOF
+ else
+ cat > ${pp_destdir}/etc/pam.d/sudo <<-EOF
+ #%PAM-1.0
+ auth include system-auth
+ account include system-auth
+ password include system-auth
+ session optional pam_keyinit.so revoke
+ session required pam_limits.so
+ EOF
+ cat > ${pp_destdir}/etc/pam.d/sudo-i <<-EOF
+ #%PAM-1.0
+ auth include sudo
+ account include sudo
+ password include sudo
+ session optional pam_keyinit.so force revoke
+ session required pam_limits.so
+ EOF
+ fi
+ ;;
+ f[0-9]*)
+ # XXX - share with rhel
+ mkdir -p ${pp_destdir}/etc/pam.d
+ cat > ${pp_destdir}/etc/pam.d/sudo <<-EOF
+ #%PAM-1.0
+ auth include system-auth
+ account include system-auth
+ password include system-auth
+ session optional pam_keyinit.so revoke
+ session required pam_limits.so
+ EOF
+ cat > ${pp_destdir}/etc/pam.d/sudo-i <<-EOF
+ #%PAM-1.0
+ auth include sudo
+ account include sudo
+ password include sudo
+ session optional pam_keyinit.so force revoke
+ session required pam_limits.so
+ EOF
+ ;;
+ sles*)
+ mkdir -p ${pp_destdir}/etc/pam.d
+ if test $osrelease -lt 10; then
+ cat > ${pp_destdir}/etc/pam.d/sudo <<-EOF
+ #%PAM-1.0
+ auth required pam_unix2.so
+ session required pam_limits.so
+ EOF
+ else
+ cat > ${pp_destdir}/etc/pam.d/sudo <<-EOF
+ #%PAM-1.0
+ auth include common-auth
+ account include common-account
+ password include common-password
+ session include common-session
+ # session optional pam_xauth.so
+ EOF
+ fi
+ ;;
+ esac
+%endif
+
+%if [deb]
+ # Uncomment some Defaults and the %sudo rule in sudoers
+ # Note that the order must match that of sudoers and be tab-indented.
+ chmod u+w ${pp_destdir}${sudoersdir}/sudoers
+ /bin/ed - ${pp_destdir}${sudoersdir}/sudoers <<-'EOF'
+ /Locale settings/+1,s/^# //
+ /X11 resource/+1,s/^# //
+ /^# \%sudo/,s/^# //
+ /^# Defaults secure_path/,s/^# //
+ /^# Defaults mail_badpass/,s/^# //
+ w
+ q
+ EOF
+ chmod u-w ${pp_destdir}${sudoersdir}/sudoers
+ mkdir -p ${pp_destdir}/etc/pam.d
+ cat > ${pp_destdir}/etc/pam.d/sudo <<-EOF
+ #%PAM-1.0
+
+ @include common-auth
+ @include common-account
+
+ session required pam_permit.so
+ session required pam_limits.so
+ EOF
+%endif
+
+%if [macos]
+ pp_macos_pkg_type=flat
+ pp_macos_bundle_id=ws.sudo.pkg.sudo
+ pp_macos_pkg_license=${pp_destdir}$docdir/LICENSE
+ pp_macos_pkg_readme=${pp_wrkdir}/ReadMe.txt
+ perl -pe 'last if (/^What/i && $seen++)' ${pp_destdir}$docdir/NEWS > ${pp_wrkdir}/ReadMe.txt
+%endif
+
+%if X"$aix_freeware" = X"true"
+ # Create links from /opt/freeware/{bin,sbin} -> /usr/{bin.sbin}
+ mkdir -p ${pp_destdir}/usr/bin ${pp_destdir}/usr/sbin
+ ln -s -f ${bindir}/cvtsudoers ${pp_destdir}/usr/bin
+ ln -s -f ${bindir}/sudo ${pp_destdir}/usr/bin
+ ln -s -f ${bindir}/sudoedit ${pp_destdir}/usr/bin
+ ln -s -f ${bindir}/sudoreplay ${pp_destdir}/usr/bin
+ ln -s -f ${sbindir}/visudo ${pp_destdir}/usr/sbin
+%endif
+
+ # Package parent directories when not installing under /usr
+ if test "${prefix}" != "/usr"; then
+ extradirs=`echo ${pp_destdir}/${mandir}/[mc]* | sed "s#${pp_destdir}/##g"`
+ extradirs="$extradirs `dirname $docdir` `dirname $rundir` `dirname $vardir`"
+ test "`dirname $exampledir`" != "$docdir" && extradirs="$extradirs `dirname $exampledir`"
+ test -d ${pp_destdir}${localedir} && extradirs="$extradirs $localedir"
+ for dir in $bindir $sbindir $libexecdir $includedir $extradirs; do
+ while test "$dir" != "/"; do
+ parentdirs="${parentdirs}${parentdirs+ }$dir/"
+ dir=`dirname $dir`
+ done
+ done
+ parentdirs=`echo $parentdirs | tr " " "\n" | sort -u`
+ fi
+
+%depend [deb]
+ libc6, libpam0g, libpam-modules, zlib1g, libselinux1
+
+%fixup [deb]
+ # Add Conflicts, Replaces headers and add libldap depedency as needed.
+ DEPENDS="%{linux_audit}"
+ if test -z "%{flavor}"; then
+ echo "Conflicts: sudo-ldap" >> %{pp_wrkdir}/%{name}/DEBIAN/control
+ echo "Replaces: sudo-ldap" >> %{pp_wrkdir}/%{name}/DEBIAN/control
+ elif test "%{flavor}" = "ldap"; then
+ echo "Conflicts: sudo" >> %{pp_wrkdir}/%{name}/DEBIAN/control
+ echo "Replaces: sudo" >> %{pp_wrkdir}/%{name}/DEBIAN/control
+ echo "Provides: sudo" >> %{pp_wrkdir}/%{name}/DEBIAN/control
+ DEPENDS="${DEPENDS}, libldap-2.4-2"
+ fi
+ cp -p %{pp_wrkdir}/%{name}/DEBIAN/control %{pp_wrkdir}/%{name}/DEBIAN/control.$$
+ sed "s/^\(Depends:.*\) *$/\1, ${DEPENDS}/" %{pp_wrkdir}/%{name}/DEBIAN/control.$$ > %{pp_wrkdir}/%{name}/DEBIAN/control
+ rm -f %{pp_wrkdir}/%{name}/DEBIAN/control.$$
+ echo "Homepage: https://www.sudo.ws" >> %{pp_wrkdir}/%{name}/DEBIAN/control
+ echo "Bugs: https://bugzilla.sudo.ws" >> %{pp_wrkdir}/%{name}/DEBIAN/control
+
+%files
+%if X"$parentdirs" != X""
+ $parentdirs -
+%endif
+ $bindir/cvtsudoers 0755 root:
+ $bindir/sudo 4755 root:
+ $bindir/sudoedit 0755 root: symlink sudo
+ $bindir/sudoreplay 0755
+ $sbindir/visudo 0755
+ $includedir/sudo_plugin.h 0644
+ $libexecdir/sudo/ 0755
+ $libexecdir/sudo/sesh 0755 optional,ignore-others
+ $libexecdir/sudo/* $shlib_mode optional
+ $sudoersdir/sudoers.d/ 0750 $sudoers_uid:$sudoers_gid
+ $rundir/ 0711 root:
+ $vardir/ 0711 root: ignore-others
+ $vardir/lectured/ 0700 root:
+ $docdir/ 0755
+%if [deb]
+ $docdir/LICENSE ignore,ignore-others
+ $docdir/ChangeLog ignore,ignore-others
+%endif
+ $exampledir/ 0755 ignore-others
+ $exampledir/* 0644 ignore-others
+ $docdir/** 0644
+ $localedir/*/ - optional
+ $localedir/*/LC_MESSAGES/ - optional
+ $localedir/*/LC_MESSAGES/* 0644 optional
+ /etc/pam.d/* 0644 volatile,optional
+%if [rpm,deb]
+ $sudoersdir/sudoers $sudoers_mode $sudoers_uid:$sudoers_gid volatile
+%else
+ $sudoersdir/sudoers.dist $sudoers_mode $sudoers_uid:$sudoers_gid
+%endif
+%if X"$aix_freeware" = X"true"
+ # Links for binaries from /opt/freeware to /usr
+ /usr/bin/cvtsudoers 0755 root: symlink $bindir/cvtsudoers
+ /usr/bin/sudo 0755 root: symlink $bindir/sudo
+ /usr/bin/sudoedit 0755 root: symlink $bindir/sudoedit
+ /usr/bin/sudoreplay 0755 root: symlink $bindir/sudoreplay
+ /usr/sbin/visudo 0755 root: symlink $sbindir/visudo
+%endif
+%if [rpm]
+ /etc/rc.d/init.d/sudo 0755 root: optional
+%endif
+%if [aix]
+ /etc/rc.d/ ignore
+ /etc/rc.d/rc2.d/ ignore
+ /etc/rc.d/rc2.d/** ignore
+ /etc/rc.d/init.d/ ignore
+ /etc/rc.d/init.d/sudo 0755 root:
+%endif
+%if [sd]
+ /sbin/ ignore
+ /sbin/rc2.d/ ignore
+ /sbin/rc2.d/** ignore
+ /sbin/init.d/ ignore
+ /sbin/init.d/sudo 0755 root:
+%endif
+
+%files [!aix]
+ $mandir/man*/* 0644
+ $sudoedit_man 0644 symlink,ignore-others $sudoedit_man_target
+
+%files [aix]
+ # Some versions use catpages, some use manpages.
+ $mandir/cat*/* 0644 optional
+ $mandir/man*/* 0644 optional
+ $sudoedit_man 0644 symlink,ignore-others $sudoedit_man_target
+
+%pre [aix]
+ if rpm -q %{name} >/dev/null 2>&1; then
+ echo "Another version of sudo is currently installed via rpm." 2>&1
+ echo "Please either uninstall the rpm version of sudo by running \"rpm -e sudo\"" 2>&1
+ echo "or upgrade the existing version of sudo using the .rpm packagae instead" 2>&1
+ echo "instead of the .bff package." 2>&1
+ echo "" 2>&1
+ echo "Note that you may need to pass rpm the --oldpackage flag when upgrading" 2>&1
+ echo "the AIX Toolbox version of sudo to the latest sudo rpm from sudo.ws." 2>&1
+ echo "" 2>&1
+ exit 1
+ fi
+
+%post [!rpm,deb]
+ # Don't overwrite an existing sudoers file
+%if [solaris]
+ sudoersdir=${PKG_INSTALL_ROOT}%{sudoersdir}
+%else
+ sudoersdir=%{sudoersdir}
+%endif
+ if test ! -r $sudoersdir/sudoers; then
+ cp $sudoersdir/sudoers.dist $sudoersdir/sudoers
+ chmod %{sudoers_mode} $sudoersdir/sudoers
+ chown %{sudoers_uid} $sudoersdir/sudoers
+ chgrp %{sudoers_gid} $sudoersdir/sudoers
+ fi
+
+%post [deb]
+ set -e
+
+ # dpkg-deb does not maintain the mode on the sudoers file, and
+ # installs it 0640 when sudo requires 0440
+ chmod %{sudoers_mode} %{sudoersdir}/sudoers
+
+ # create symlink to ease transition to new path for ldap config
+ # if old config file exists and new one doesn't
+ if test X"%{flavor}" = X"ldap" -a \
+ -r /etc/ldap/ldap.conf -a ! -r /etc/sudo-ldap.conf; then
+ ln -s /etc/ldap/ldap.conf /etc/sudo-ldap.conf
+ fi
+
+ # Debian uses a sudo group in its default sudoers file
+ perl -e '
+ exit 0 if getgrnam("sudo");
+ $gid = 27; # default debian sudo gid
+ setgrent();
+ while (getgrgid($gid)) { $gid++; }
+ if ($gid != 27) {
+ print "On Debian we normally use gid 27 for \"sudo\".\n";
+ $gname = getgrgid(27);
+ print "However, on your system gid 27 is group \"$gname\".\n\n";
+ print "Would you like me to stop configuring sudo so that you can change this? [n] ";
+ $ans = <STDIN>;
+ if ($ans =~ /^[yY]/) {
+ print "\"dpkg --pending --configure\" will restart the configuration.\n\n";
+ exit 1;
+ }
+ }
+ print "Creating group \"sudo\" with gid = $gid\n";
+ system("groupadd -g $gid sudo");
+ exit 0;
+ '
+
+%post [rpm]
+ case "%{pp_rpm_distro}" in
+ aix*)
+ # Create /etc/rc.d/rc2.d/S90sudo link if possible
+ if [ -d /etc/rc.d/rc2.d ]; then
+ rm -f /etc/rc.d/rc2.d/S90sudo
+ ln -s /etc/rc.d/init.d/sudo /etc/rc.d/rc2.d/S90sudo
+ fi
+ ;;
+ esac
+
+%post [rpm,deb]
+ # Create /usr/lib/tmpfiles.d/sudo.conf if systemd is configured.
+ if [ -f /usr/lib/tmpfiles.d/systemd.conf ]; then
+ cat > /usr/lib/tmpfiles.d/sudo.conf <<-EOF
+ # Create an empty sudo time stamp directory on OSes using systemd.
+ # Sudo will create the directory itself but this can cause problems
+ # on systems that have SELinux enabled since the directories will be
+ # created with the user's security context.
+ d %{rundir} 0711 root root
+ D %{rundir}/ts 0700 root root
+ EOF
+ fi
+
+%post [aix]
+ # Create /etc/rc.d/rc2.d/S90sudo link if /etc/rc.d exists
+ if [ -d /etc/rc.d ]; then
+ rm -f /etc/rc.d/rc2.d/S90sudo
+ ln -s /etc/rc.d/init.d/sudo /etc/rc.d/rc2.d/S90sudo
+ fi
+
+%post [sd]
+ # Create /sbin/rc2.d/S900sudo link
+ rm -f /sbin/rc2.d/S900sudo
+ ln -s /sbin/init.d/sudo /sbin/rc2.d/S900sudo
+
+%preun
+ # Remove the time stamp dir and its contents
+ # We currently leave the lecture status files installed
+ rm -rf %{rundir}/ts
+%if [deb]
+ set -e
+
+ # Remove the /etc/ldap/ldap.conf -> /etc/sudo-ldap.conf symlink if
+ # it matches what we created in the postinstall script.
+ if test X"%{flavor}" = X"ldap" -a \
+ X"`readlink /etc/sudo-ldap.conf 2>/dev/null`" = X"/etc/ldap/ldap.conf"; then
+ rm -f /etc/sudo-ldap.conf
+ fi
+
+ # Remove systemd tmpfile config
+ rm -f /usr/lib/tmpfiles.d/sudo.conf
+%endif
+%if [rpm]
+ case "%{pp_rpm_distro}" in
+ aix*)
+ # Remove /etc/rc.d/rc2.d/S90sudo link
+ rm -f /etc/rc.d/rc2.d/S90sudo
+ ;;
+ *)
+ # Remove systemd tmpfile config
+ rm -f /usr/lib/tmpfiles.d/sudo.conf
+ ;;
+ esac
+%endif
+%if [aix]
+ # Remove /etc/rc.d/rc2.d/S90sudo link
+ rm -f /etc/rc.d/rc2.d/S90sudo
+%endif
+%if [sd]
+ # Remove /sbin/rc2.d/S900sudo link
+ rm -f /sbin/rc2.d/S900sudo
+%endif